authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-03 12:43:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-03 12:56:35-04:00
logffab950e0cce8b1be2755e070d0684d817138f15
tree67b9e76445bdb6294d2a3c8c848635098737a47e
parent63ebd9d12e48765514777418e12f55576ff63509
signaturelock-open Commit is signed but in an unrecognized format.

update embedded LLD to 9.0.0rc1


1556 files changed, 49295 insertions(+), 31778 deletions(-)

CMakeLists.txt+4-1
......@@ -88,6 +88,7 @@ else()
8888 set(EMBEDDED_LLD_LIB_SOURCES
8989 "${CMAKE_SOURCE_DIR}/deps/lld/Common/Args.cpp"
9090 "${CMAKE_SOURCE_DIR}/deps/lld/Common/ErrorHandler.cpp"
91 "${CMAKE_SOURCE_DIR}/deps/lld/Common/Filesystem.cpp"
9192 "${CMAKE_SOURCE_DIR}/deps/lld/Common/Memory.cpp"
9293 "${CMAKE_SOURCE_DIR}/deps/lld/Common/Reproduce.cpp"
9394 "${CMAKE_SOURCE_DIR}/deps/lld/Common/Strings.cpp"
......@@ -148,7 +149,6 @@ else()
148149 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Driver.cpp"
149150 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DriverUtils.cpp"
150151 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/EhFrame.cpp"
151 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Filesystem.cpp"
152152 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ICF.cpp"
153153 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputFiles.cpp"
154154 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputSection.cpp"
......@@ -171,6 +171,7 @@ else()
171171 set(EMBEDDED_LLD_COFF_SOURCES
172172 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Chunks.cpp"
173173 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/DLL.cpp"
174 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/DebugTypes.cpp"
174175 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Driver.cpp"
175176 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/DriverUtils.cpp"
176177 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/ICF.cpp"
......@@ -194,8 +195,10 @@ else()
194195 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/LTO.cpp"
195196 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/MarkLive.cpp"
196197 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/OutputSections.cpp"
198 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/Relocations.cpp"
197199 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/SymbolTable.cpp"
198200 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/Symbols.cpp"
201 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/SyntheticSections.cpp"
199202 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/Writer.cpp"
200203 "${CMAKE_SOURCE_DIR}/deps/lld/wasm/WriterUtils.cpp"
201204 )
deps/lld-prebuilt/COFF/Options.inc+41-10
......@@ -13,9 +13,8 @@
1313#define COMMA ,
1414PREFIX(prefix_0, {nullptr})
1515PREFIX(prefix_2, {"--" COMMA nullptr})
16PREFIX(prefix_3, {"/" COMMA "-" COMMA nullptr})
17PREFIX(prefix_1, {"/" COMMA "-" COMMA "-?" COMMA nullptr})
18PREFIX(prefix_4, {"/?" COMMA "-?" COMMA nullptr})
16PREFIX(prefix_1, {"/" COMMA "-" COMMA "/?" COMMA "-?" COMMA nullptr})
17PREFIX(prefix_3, {"/??" COMMA "-??" COMMA "/?" COMMA "-?" COMMA nullptr})
1918#undef COMMA
2019#endif // PREFIX
2120
......@@ -61,13 +60,17 @@ OPTION(prefix_1, "debugtype:", debugtype, Joined, INVALID, INVALID, nullptr, 0,
6160 "Debug Info Options", nullptr, nullptr)
6261OPTION(prefix_1, "debug", debug, Flag, INVALID, INVALID, nullptr, 0, 0,
6362 "Embed a symbol table in the image", nullptr, nullptr)
64OPTION(prefix_3, "def:", deffile, Joined, INVALID, INVALID, nullptr, 0, 0,
63OPTION(prefix_1, "def:", deffile, Joined, INVALID, INVALID, nullptr, 0, 0,
6564 "Use module-definition file", nullptr, nullptr)
6665OPTION(prefix_1, "defaultlib:", defaultlib, Joined, INVALID, INVALID, nullptr, 0, 0,
6766 "Add the library to the list of input files", nullptr, nullptr)
6867OPTION(prefix_1, "delay:", delay, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
6968OPTION(prefix_1, "delayload:", delayload, Joined, INVALID, INVALID, nullptr, 0, 0,
7069 "Delay loaded DLL name", nullptr, nullptr)
70OPTION(prefix_1, "demangle:no", demangle_no, Flag, INVALID, INVALID, nullptr, 0, 0,
71 "Do not demangle symbols in output", nullptr, nullptr)
72OPTION(prefix_1, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
73 "Demangle symbols in output (default)", nullptr, nullptr)
7174OPTION(prefix_1, "disallowlib:", disallowlib, Joined, INVALID, nodefaultlib, nullptr, 0, 0, nullptr, nullptr, nullptr)
7275OPTION(prefix_1, "dll", dll, Flag, INVALID, INVALID, nullptr, 0, 0,
7376 "Create a DLL", nullptr, nullptr)
......@@ -83,22 +86,29 @@ OPTION(prefix_1, "entry:", entry, Joined, INVALID, INVALID, nullptr, 0, 0,
8386OPTION(prefix_1, "errorlimit:", errorlimit, Joined, INVALID, INVALID, nullptr, 0, 0,
8487 "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr)
8588OPTION(prefix_1, "errorreport:", errorreport, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
89OPTION(prefix_1, "exclude-all-symbols", exclude_all_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
8690OPTION(prefix_1, "export-all-symbols", export_all_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
8791OPTION(prefix_1, "export:", export, Joined, INVALID, INVALID, nullptr, 0, 0,
8892 "Export a function", nullptr, nullptr)
8993OPTION(prefix_1, "failifmismatch:", failifmismatch, Joined, INVALID, INVALID, nullptr, 0, 0,
9094 "", nullptr, nullptr)
9195OPTION(prefix_1, "fastfail", fastfail, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
96OPTION(prefix_1, "filealign:", filealign, Joined, INVALID, INVALID, nullptr, 0, 0,
97 "Section alignment in the output file", nullptr, nullptr)
9298OPTION(prefix_1, "fixed:no", fixed_no, Flag, INVALID, INVALID, nullptr, 0, 0,
9399 "Enable base relocations (default)", nullptr, nullptr)
94100OPTION(prefix_1, "fixed", fixed, Flag, INVALID, INVALID, nullptr, 0, 0,
95101 "Disable base relocations", nullptr, nullptr)
102OPTION(prefix_1, "force:multipleres", force_multipleres, Flag, INVALID, INVALID, nullptr, 0, 0,
103 "Allow multiply defined resources when creating executables", nullptr, nullptr)
96104OPTION(prefix_1, "force:multiple", force_multiple, Flag, INVALID, INVALID, nullptr, 0, 0,
97105 "Allow multiply defined symbols when creating executables", nullptr, nullptr)
98106OPTION(prefix_1, "force:unresolved", force_unresolved, Flag, INVALID, INVALID, nullptr, 0, 0,
99107 "Allow undefined symbols when creating executables", nullptr, nullptr)
100108OPTION(prefix_1, "force", force, Flag, INVALID, INVALID, nullptr, 0, 0,
101109 "Allow undefined and multiply defined symbols when creating executables", nullptr, nullptr)
110OPTION(prefix_1, "functionpadmin:", functionpadmin_opt, Joined, INVALID, INVALID, nullptr, 0, 0,
111 "Prepares an image for hotpatching", nullptr, nullptr)
102112OPTION(prefix_1, "functionpadmin", functionpadmin, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
103113OPTION(prefix_1, "guard:", guard, Joined, INVALID, INVALID, nullptr, 0, 0,
104114 "Control flow guard", nullptr, nullptr)
......@@ -116,8 +126,10 @@ OPTION(prefix_1, "ignore:", ignore, Joined, INVALID, INVALID, nullptr, 0, 0,
116126OPTION(prefix_1, "ignoreidl", ignoreidl, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
117127OPTION(prefix_1, "implib:", implib, Joined, INVALID, INVALID, nullptr, 0, 0,
118128 "Import library name", nullptr, nullptr)
119OPTION(prefix_3, "include:", incl, Joined, INVALID, INVALID, nullptr, 0, 0,
129OPTION(prefix_1, "include:", incl, Joined, INVALID, INVALID, nullptr, 0, 0,
120130 "Force symbol to be added to symbol table as undefined one", nullptr, nullptr)
131OPTION(prefix_1, "includeoptional:", include_optional, Joined, INVALID, INVALID, nullptr, 0, 0,
132 "Add symbol as undefined, but allow it to remain undefined", nullptr, nullptr)
121133OPTION(prefix_1, "incremental:no", incremental_no, Flag, INVALID, INVALID, nullptr, 0, 0,
122134 "Overwrite import library even if contents are unchanged", nullptr, nullptr)
123135OPTION(prefix_1, "incremental", incremental, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -141,7 +153,7 @@ OPTION(prefix_1, "lldltocache:", lldltocache, Joined, INVALID, INVALID, nullptr,
141153 "Path to ThinLTO cached object file directory", nullptr, nullptr)
142154OPTION(prefix_1, "lldltocachepolicy:", lldltocachepolicy, Joined, INVALID, INVALID, nullptr, 0, 0,
143155 "Pruning policy for the ThinLTO cache", nullptr, nullptr)
144OPTION(prefix_3, "lldmap:", lldmap_file, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
156OPTION(prefix_1, "lldmap:", lldmap_file, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
145157OPTION(prefix_1, "lldmap", lldmap, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
146158OPTION(prefix_1, "lldmingw", lldmingw, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
147159OPTION(prefix_1, "lldsavetemps", lldsavetemps, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -186,7 +198,7 @@ OPTION(prefix_1, "order:", order, Joined, INVALID, INVALID, nullptr, 0, 0,
186198 "Put functions in order", nullptr, nullptr)
187199OPTION(prefix_1, "out:", out, Joined, INVALID, INVALID, nullptr, 0, 0,
188200 "Path to file to write output", nullptr, nullptr)
189OPTION(prefix_3, "output-def:", output_def, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
201OPTION(prefix_1, "output-def:", output_def, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
190202OPTION(prefix_1, "pdb:", pdb, Joined, INVALID, INVALID, nullptr, 0, 0,
191203 "PDB file path", nullptr, nullptr)
192204OPTION(prefix_1, "pdbaltpath:", pdbaltpath, Joined, INVALID, INVALID, nullptr, 0, 0,
......@@ -208,8 +220,27 @@ OPTION(prefix_1, "stub:", stub, Joined, INVALID, INVALID, nullptr, 0, 0,
208220 "Specify DOS stub file", nullptr, nullptr)
209221OPTION(prefix_1, "subsystem:", subsystem, Joined, INVALID, INVALID, nullptr, 0, 0,
210222 "Specify subsystem", nullptr, nullptr)
211OPTION(prefix_1, "swaprun:cd", swaprun_cd, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
212OPTION(prefix_1, "swaprun:net", swaprun_net, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
223OPTION(prefix_1, "summary", summary, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
224OPTION(prefix_1, "swaprun:cd", swaprun_cd, Flag, INVALID, swaprun, "cd\0", 0, 0,
225 "Make loader run output binary from swap instead of from CD", nullptr, nullptr)
226OPTION(prefix_1, "swaprun:net", swaprun_net, Flag, INVALID, swaprun, "net\0", 0, 0,
227 "Make loader run output binary from swap instead of from network", nullptr, nullptr)
228OPTION(prefix_1, "swaprun:", swaprun, Joined, INVALID, INVALID, nullptr, 0, 0,
229 "Comma-separated list of 'cd' or 'net'", nullptr, nullptr)
230OPTION(prefix_1, "thinlto-emit-imports-files", thinlto_emit_imports_files, Flag, INVALID, INVALID, nullptr, 0, 0,
231 "Emit .imports files with -thinlto-index-only", nullptr, nullptr)
232OPTION(prefix_1, "thinlto-index-only:", thinlto_index_only_arg, Joined, INVALID, INVALID, nullptr, 0, 0,
233 "-thinlto-index-only and also write native module names to file", nullptr, nullptr)
234OPTION(prefix_1, "thinlto-index-only", thinlto_index_only, Flag, INVALID, INVALID, nullptr, 0, 0,
235 "Instead of linking, emit ThinLTO index files", nullptr, nullptr)
236OPTION(prefix_1, "thinlto-object-suffix-replace:", thinlto_object_suffix_replace, Joined, INVALID, INVALID, nullptr, 0, 0,
237 "'old;new' replace old suffix with new suffix in ThinLTO index", nullptr, nullptr)
238OPTION(prefix_1, "thinlto-prefix-replace:", thinlto_prefix_replace, Joined, INVALID, INVALID, nullptr, 0, 0,
239 "'old;new' replace old prefix with new prefix in ThinLTO outputs", nullptr, nullptr)
240OPTION(prefix_1, "threads:no", threads_no, Flag, INVALID, INVALID, nullptr, 0, 0,
241 "Do not run the linker multi-threaded", nullptr, nullptr)
242OPTION(prefix_1, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,
243 "Run the linker multi-threaded (default)", nullptr, nullptr)
213244OPTION(prefix_1, "throwingnew", throwingnew, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
214245OPTION(prefix_1, "timestamp:", timestamp, Joined, INVALID, INVALID, nullptr, 0, 0,
215246 "Specify the PE header timestamp", nullptr, nullptr)
......@@ -233,7 +264,7 @@ OPTION(prefix_1, "WX:no", WX_no, Flag, INVALID, INVALID, nullptr, 0, 0,
233264 "Don't treat warnings as errors", nullptr, nullptr)
234265OPTION(prefix_1, "WX", WX, Flag, INVALID, INVALID, nullptr, 0, 0,
235266 "Treat warnings as errors", nullptr, nullptr)
236OPTION(prefix_4, "", help_q, Flag, INVALID, help, nullptr, 0, 0, nullptr, nullptr, nullptr)
267OPTION(prefix_3, "", help_q, Flag, INVALID, help, nullptr, 0, 0, nullptr, nullptr, nullptr)
237268#endif // OPTION
238269
239270#ifdef OPTTABLE_ARG_INIT
deps/lld-prebuilt/ELF/Options.inc+91-51
......@@ -29,13 +29,14 @@ PREFIX(prefix_2, {"--" COMMA "-" COMMA nullptr})
2929
3030OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
3131OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
32OPTION(prefix_1, "(", anonymous_30, Flag, INVALID, start_group, nullptr, 0, 0,
32OPTION(prefix_1, "(", anonymous_31, Flag, INVALID, start_group, nullptr, 0, 0,
3333 "Alias for --start-group", nullptr, nullptr)
3434OPTION(prefix_1, ")", anonymous_12, Flag, INVALID, end_group, nullptr, 0, 0,
3535 "Alias for --end-group", nullptr, nullptr)
3636OPTION(prefix_2, "allow-multiple-definition", allow_multiple_definition, Flag, INVALID, INVALID, nullptr, 0, 0,
3737 "Allow multiple definitions", nullptr, nullptr)
38OPTION(prefix_2, "allow-shlib-undefined", anonymous_47, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
38OPTION(prefix_2, "allow-shlib-undefined", allow_shlib_undefined, Flag, INVALID, INVALID, nullptr, 0, 0,
39 "Allow unresolved references in shared libraries (default when linking a shared library)", nullptr, nullptr)
3940OPTION(prefix_2, "apply-dynamic-relocs", apply_dynamic_relocs, Flag, INVALID, INVALID, nullptr, 0, 0,
4041 "Apply link-time values for dynamic relocations", nullptr, nullptr)
4142OPTION(prefix_2, "as-needed", as_needed, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -45,7 +46,7 @@ OPTION(prefix_2, "auxiliary=", auxiliary_eq, Joined, INVALID, auxiliary, nullptr
4546OPTION(prefix_2, "auxiliary", auxiliary, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
4647OPTION(prefix_2, "Bdynamic", Bdynamic, Flag, INVALID, INVALID, nullptr, 0, 0,
4748 "Link against shared libraries (default)", nullptr, nullptr)
48OPTION(prefix_2, "Bshareable", anonymous_28, Flag, INVALID, shared, nullptr, 0, 0,
49OPTION(prefix_2, "Bshareable", anonymous_29, Flag, INVALID, shared, nullptr, 0, 0,
4950 "Alias for --shared", nullptr, nullptr)
5051OPTION(prefix_2, "Bstatic", Bstatic, Flag, INVALID, INVALID, nullptr, 0, 0,
5152 "Do not link against shared libraries", nullptr, nullptr)
......@@ -87,7 +88,9 @@ OPTION(prefix_2, "defsym=", defsym_eq, Joined, INVALID, defsym, nullptr, 0, 0,
8788OPTION(prefix_2, "defsym", defsym, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<symbol>=<value>", nullptr)
8889OPTION(prefix_2, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
8990 "Demangle symbol names (default)", nullptr, nullptr)
90OPTION(prefix_2, "detect-odr-violations", anonymous_48, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
91OPTION(prefix_2, "dependent-libraries", dependent_libraries, Flag, INVALID, INVALID, nullptr, 0, 0,
92 "Process dependent library specifiers from input files (default)", nullptr, nullptr)
93OPTION(prefix_2, "detect-odr-violations", anonymous_50, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
9194OPTION(prefix_2, "disable-new-dtags", disable_new_dtags, Flag, INVALID, INVALID, nullptr, 0, 0,
9295 "Disable new dynamic tags", nullptr, nullptr)
9396OPTION(prefix_2, "disable-verify", disable_verify, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
......@@ -111,10 +114,10 @@ OPTION(prefix_2, "dy", anonymous_2, Flag, INVALID, Bdynamic, nullptr, 0, 0,
111114 "Alias for --Bdynamic", nullptr, nullptr)
112115OPTION(prefix_1, "d", anonymous_6, Flag, INVALID, define_common, nullptr, 0, 0,
113116 "Alias for --define-common", nullptr, nullptr)
114OPTION(prefix_2, "EB", anonymous_65, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
117OPTION(prefix_2, "EB", anonymous_69, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
115118OPTION(prefix_2, "eh-frame-hdr", eh_frame_hdr, Flag, INVALID, INVALID, nullptr, 0, 0,
116119 "Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header", nullptr, nullptr)
117OPTION(prefix_2, "EL", anonymous_66, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
120OPTION(prefix_2, "EL", anonymous_70, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
118121OPTION(prefix_2, "emit-relocs", emit_relocs, Flag, INVALID, INVALID, nullptr, 0, 0,
119122 "Generate relocations in output", nullptr, nullptr)
120123OPTION(prefix_2, "enable-new-dtags", enable_new_dtags, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -155,6 +158,8 @@ OPTION(prefix_2, "fini=", fini_eq, Joined, INVALID, fini, nullptr, 0, 0,
155158OPTION(prefix_2, "fini", fini, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<symbol>", nullptr)
156159OPTION(prefix_2, "fix-cortex-a53-843419", fix_cortex_a53_843419, Flag, INVALID, INVALID, nullptr, 0, 0,
157160 "Apply fixes for AArch64 Cortex-A53 erratum 843419", nullptr, nullptr)
161OPTION(prefix_2, "force-bti", force_bti, Flag, INVALID, INVALID, nullptr, 0, 0,
162 "Force enable AArch64 BTI in PLT, warn if Input ELF file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property", nullptr, nullptr)
158163OPTION(prefix_2, "format=", format_eq, Joined, INVALID, format, nullptr, 0, 0,
159164 "Change the input format of the inputs following this option", "[default,elf,binary]", nullptr)
160165OPTION(prefix_2, "format", format, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[default,elf,binary]", nullptr)
......@@ -168,14 +173,14 @@ OPTION(prefix_2, "gdb-index", gdb_index, Flag, INVALID, INVALID, nullptr, 0, 0,
168173 "Generate .gdb_index section", nullptr, nullptr)
169174OPTION(prefix_2, "gnu-unique", gnu_unique, Flag, INVALID, INVALID, nullptr, 0, 0,
170175 "Enable STB_GNU_UNIQUE symbol binding (default)", nullptr, nullptr)
171OPTION(prefix_1, "G", anonymous_67, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
172OPTION(prefix_1, "g", anonymous_49, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
176OPTION(prefix_1, "G", anonymous_71, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
177OPTION(prefix_1, "g", anonymous_51, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
173178OPTION(prefix_2, "hash-style=", hash_style_eq, Joined, INVALID, hash_style, nullptr, 0, 0,
174179 "Specify hash style (sysv, gnu or both)", nullptr, nullptr)
175180OPTION(prefix_2, "hash-style", hash_style, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
176181OPTION(prefix_2, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0,
177182 "Print option help", nullptr, nullptr)
178OPTION(prefix_1, "h", anonymous_29, JoinedOrSeparate, INVALID, soname, nullptr, 0, 0,
183OPTION(prefix_1, "h", anonymous_30, JoinedOrSeparate, INVALID, soname, nullptr, 0, 0,
179184 "Alias for --soname", nullptr, nullptr)
180185OPTION(prefix_2, "icf=all", icf_all, Flag, INVALID, INVALID, nullptr, 0, 0,
181186 "Enable identical code folding", nullptr, nullptr)
......@@ -205,9 +210,13 @@ OPTION(prefix_2, "library-path", library_path, Separate, INVALID, INVALID, nullp
205210OPTION(prefix_2, "library=", library_eq, Joined, INVALID, library, nullptr, 0, 0,
206211 "Root name of library to use", "<libName>", nullptr)
207212OPTION(prefix_2, "library", library, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<libName>", nullptr)
208OPTION(prefix_2, "long-plt", anonymous_50, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
213OPTION(prefix_2, "long-plt", anonymous_52, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
209214OPTION(prefix_2, "lto-aa-pipeline=", lto_aa_pipeline, Joined, INVALID, INVALID, nullptr, 0, 0,
210215 "AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes", nullptr, nullptr)
216OPTION(prefix_2, "lto-cs-profile-file=", lto_cs_profile_file, Joined, INVALID, INVALID, nullptr, 0, 0,
217 "Context sensitive profile file path", nullptr, nullptr)
218OPTION(prefix_2, "lto-cs-profile-generate", lto_cs_profile_generate, Flag, INVALID, INVALID, nullptr, 0, 0,
219 "Perform context senstive PGO instrumentation", nullptr, nullptr)
211220OPTION(prefix_2, "lto-debug-pass-manager", lto_debug_pass_manager, Flag, INVALID, INVALID, nullptr, 0, 0,
212221 "Debug new pass manager", nullptr, nullptr)
213222OPTION(prefix_2, "lto-new-pass-manager", lto_new_pass_manager, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -235,14 +244,17 @@ OPTION(prefix_2, "mips-got-size", mips_got_size, Separate, INVALID, INVALID, nul
235244OPTION(prefix_2, "mllvm=", mllvm_eq, Joined, INVALID, mllvm, nullptr, 0, 0,
236245 "Additional arguments to forward to LLVM's option processing", nullptr, nullptr)
237246OPTION(prefix_2, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
238OPTION(prefix_1, "M", anonymous_24, Flag, INVALID, print_map, nullptr, 0, 0,
247OPTION(prefix_1, "M", anonymous_25, Flag, INVALID, print_map, nullptr, 0, 0,
239248 "Alias for --print-map", nullptr, nullptr)
240249OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
241250 "Set target emulation", nullptr, nullptr)
242OPTION(prefix_2, "no-add-needed", anonymous_51, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
251OPTION(prefix_2, "nmagic", nmagic, Flag, INVALID, INVALID, nullptr, 0, 0,
252 "Do not page align sections, link against static libraries.", "<magic>", nullptr)
253OPTION(prefix_2, "no-add-needed", anonymous_53, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
243254OPTION(prefix_2, "no-allow-multiple-definition", no_allow_multiple_definition, Flag, INVALID, INVALID, nullptr, 0, 0,
244255 "Do not allow multiple definitions (default)", nullptr, nullptr)
245OPTION(prefix_2, "no-allow-shlib-undefined", anonymous_52, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
256OPTION(prefix_2, "no-allow-shlib-undefined", no_allow_shlib_undefined, Flag, INVALID, INVALID, nullptr, 0, 0,
257 "Do not allow unresolved references in shared libraries (default when linking an executable)", nullptr, nullptr)
246258OPTION(prefix_2, "no-apply-dynamic-relocs", no_apply_dynamic_relocs, Flag, INVALID, INVALID, nullptr, 0, 0,
247259 "Do not apply link-time values for dynamic relocations (default)", nullptr, nullptr)
248260OPTION(prefix_2, "no-as-needed", no_as_needed, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -253,14 +265,16 @@ OPTION(prefix_2, "no-check-sections", no_check_sections, Flag, INVALID, INVALID,
253265 "Do not check section addresses for overlaps", nullptr, nullptr)
254266OPTION(prefix_2, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
255267 "Do not use colors in diagnostics", nullptr, nullptr)
256OPTION(prefix_2, "no-copy-dt-needed-entries", anonymous_53, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
268OPTION(prefix_2, "no-copy-dt-needed-entries", anonymous_54, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
257269OPTION(prefix_2, "no-cref", no_cref, Flag, INVALID, INVALID, nullptr, 0, 0,
258270 "Do not output cross reference table", nullptr, nullptr)
259OPTION(prefix_2, "no-ctors-in-init-array", anonymous_54, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
271OPTION(prefix_2, "no-ctors-in-init-array", anonymous_55, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
260272OPTION(prefix_2, "no-define-common", no_define_common, Flag, INVALID, INVALID, nullptr, 0, 0,
261273 "Do not assign space to common symbols", nullptr, nullptr)
262274OPTION(prefix_2, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
263275 "Do not demangle symbol names", nullptr, nullptr)
276OPTION(prefix_2, "no-dependent-libraries", no_dependent_libraries, Flag, INVALID, INVALID, nullptr, 0, 0,
277 "Ignore dependent library specifiers from input files", nullptr, nullptr)
264278OPTION(prefix_2, "no-dynamic-linker", no_dynamic_linker, Flag, INVALID, INVALID, nullptr, 0, 0,
265279 "Inhibit output of .interp section", nullptr, nullptr)
266280OPTION(prefix_2, "no-eh-frame-hdr", no_eh_frame_hdr, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -277,16 +291,19 @@ OPTION(prefix_2, "no-gdb-index", no_gdb_index, Flag, INVALID, INVALID, nullptr,
277291 "Do not generate .gdb_index section (default)", nullptr, nullptr)
278292OPTION(prefix_2, "no-gnu-unique", no_gnu_unique, Flag, INVALID, INVALID, nullptr, 0, 0,
279293 "Disable STB_GNU_UNIQUE symbol binding", nullptr, nullptr)
280OPTION(prefix_2, "no-keep-memory", anonymous_55, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
294OPTION(prefix_2, "no-keep-memory", anonymous_56, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
281295OPTION(prefix_2, "no-merge-exidx-entries", no_merge_exidx_entries, Flag, INVALID, INVALID, nullptr, 0, 0,
282296 "Disable merging .ARM.exidx entries", nullptr, nullptr)
283OPTION(prefix_2, "no-mmap-output-file", anonymous_56, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
297OPTION(prefix_2, "no-mmap-output-file", anonymous_57, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
298OPTION(prefix_2, "no-nmagic", no_nmagic, Flag, INVALID, INVALID, nullptr, 0, 0,
299 "Page align sections (default)", "<magic>", nullptr)
284300OPTION(prefix_2, "no-omagic", no_omagic, Flag, INVALID, INVALID, nullptr, 0, 0,
285 "Do not set the text data sections to be writable", "<magic>", nullptr)
301 "Do not set the text data sections to be writable, page align sections (default)", "<magic>", nullptr)
286302OPTION(prefix_2, "no-pic-executable", anonymous_19, Flag, INVALID, no_pie, nullptr, 0, 0,
287303 "Alias for --no-pie", nullptr, nullptr)
288304OPTION(prefix_2, "no-pie", no_pie, Flag, INVALID, INVALID, nullptr, 0, 0,
289305 "Do not create a position independent executable (default)", nullptr, nullptr)
306OPTION(prefix_2, "no-pipeline-knowledge", anonymous_58, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
290307OPTION(prefix_2, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
291308 "Do not list removed unused sections (default)", nullptr, nullptr)
292309OPTION(prefix_2, "no-print-icf-sections", no_print_icf_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -309,7 +326,7 @@ OPTION(prefix_2, "no-warn-common", no_warn_common, Flag, INVALID, INVALID, nullp
309326 "Do not warn about duplicate common symbols (default)", nullptr, nullptr)
310327OPTION(prefix_2, "no-warn-ifunc-textrel", no_warn_ifunc_textrel, Flag, INVALID, INVALID, nullptr, 0, 0,
311328 "Do not warn about using ifunc symbols with text relocations (default)", nullptr, nullptr)
312OPTION(prefix_2, "no-warn-mismatch", anonymous_57, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
329OPTION(prefix_2, "no-warn-mismatch", anonymous_59, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
313330OPTION(prefix_2, "no-warn-symbol-ordering", no_warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0,
314331 "Do not warn about problems with the symbol ordering file", nullptr, nullptr)
315332OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -320,31 +337,39 @@ OPTION(prefix_2, "non_shared", anonymous_4, Flag, INVALID, Bstatic, nullptr, 0,
320337 "Alias for --Bstatic", nullptr, nullptr)
321338OPTION(prefix_2, "nostdlib", nostdlib, Flag, INVALID, INVALID, nullptr, 0, 0,
322339 "Only search directories specified on the command line", nullptr, nullptr)
323OPTION(prefix_1, "N", anonymous_20, Flag, INVALID, omagic, nullptr, 0, 0,
340OPTION(prefix_1, "N", anonymous_21, Flag, INVALID, omagic, nullptr, 0, 0,
324341 "Alias for --omagic", nullptr, nullptr)
342OPTION(prefix_1, "n", anonymous_20, Flag, INVALID, nmagic, nullptr, 0, 0,
343 "Alias for --nmagic", nullptr, nullptr)
325344OPTION(prefix_3, "oformat", oformat, Separate, INVALID, INVALID, nullptr, 0, 0,
326345 "Specify the binary format for the output object file", "<format>", nullptr)
327346OPTION(prefix_3, "omagic", omagic, Flag, INVALID, INVALID, nullptr, 0, 0,
328 "Set the text and data sections to be readable and writable", "<magic>", nullptr)
347 "Set the text and data sections to be readable and writable, do not page align sections, link against static libraries", "<magic>", nullptr)
329348OPTION(prefix_3, "opt-remarks-filename", opt_remarks_filename, Separate, INVALID, INVALID, nullptr, 0, 0,
330349 "YAML output file for optimization remarks", nullptr, nullptr)
350OPTION(prefix_3, "opt-remarks-format", opt_remarks_format, Separate, INVALID, INVALID, nullptr, 0, 0,
351 "The format used for serializing remarks (default: YAML)", nullptr, nullptr)
352OPTION(prefix_3, "opt-remarks-passes", opt_remarks_passes, Separate, INVALID, INVALID, nullptr, 0, 0,
353 "Regex for the passes that need to be serialized to the output file", nullptr, nullptr)
331354OPTION(prefix_3, "opt-remarks-with-hotness", opt_remarks_with_hotness, Flag, INVALID, INVALID, nullptr, 0, 0,
332355 "Include hotness information in the optimization remarks file", nullptr, nullptr)
333356OPTION(prefix_2, "orphan-handling=", orphan_handling_eq, Joined, INVALID, orphan_handling, nullptr, 0, 0,
334357 "Control how orphan sections are handled when linker script used", nullptr, nullptr)
335358OPTION(prefix_2, "orphan-handling", orphan_handling, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
336OPTION(prefix_3, "output=", anonymous_21, Joined, INVALID, o, nullptr, 0, 0,
359OPTION(prefix_3, "output=", anonymous_22, Joined, INVALID, o, nullptr, 0, 0,
337360 "Alias for -o", nullptr, nullptr)
338OPTION(prefix_3, "output", anonymous_22, Separate, INVALID, o, nullptr, 0, 0,
361OPTION(prefix_3, "output", anonymous_23, Separate, INVALID, o, nullptr, 0, 0,
339362 "Alias for -o", nullptr, nullptr)
340363OPTION(prefix_1, "O", O, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
341364 "Optimize output file size", nullptr, nullptr)
342365OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
343366 "Path to file to write output", "<path>", nullptr)
367OPTION(prefix_2, "pac-plt", pac_plt, Flag, INVALID, INVALID, nullptr, 0, 0,
368 "AArch64 only, use pointer authentication in PLT", nullptr, nullptr)
344369OPTION(prefix_2, "pack-dyn-relocs=", pack_dyn_relocs_eq, Joined, INVALID, pack_dyn_relocs, nullptr, 0, 0,
345370 "Pack dynamic relocations in the given format", "[none,android,relr,android+relr]", nullptr)
346371OPTION(prefix_2, "pack-dyn-relocs", pack_dyn_relocs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[none,android,relr,android+relr]", nullptr)
347OPTION(prefix_2, "pic-executable", anonymous_23, Flag, INVALID, pie, nullptr, 0, 0,
372OPTION(prefix_2, "pic-executable", anonymous_24, Flag, INVALID, pie, nullptr, 0, 0,
348373 "Alias for --pie", nullptr, nullptr)
349374OPTION(prefix_2, "pic-veneer", pic_veneer, Flag, INVALID, INVALID, nullptr, 0, 0,
350375 "Always generate position independent thunks (veneers)", nullptr, nullptr)
......@@ -353,26 +378,30 @@ OPTION(prefix_2, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0,
353378OPTION(prefix_2, "plugin-opt=-fresolution=", plugin_opt_fresolution_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
354379OPTION(prefix_2, "plugin-opt=-pass-through=", plugin_opt_pass_through_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
355380OPTION(prefix_2, "plugin-opt=/", plugin_opt_slash, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
356OPTION(prefix_2, "plugin-opt=debug-pass-manager", anonymous_40, Flag, INVALID, lto_debug_pass_manager, nullptr, 0, 0,
381OPTION(prefix_2, "plugin-opt=cs-profile-generate", anonymous_46, Flag, INVALID, lto_cs_profile_generate, nullptr, 0, 0,
382 "Alias for -lto-cs-profile-generate", nullptr, nullptr)
383OPTION(prefix_2, "plugin-opt=cs-profile-path=", anonymous_47, Joined, INVALID, lto_cs_profile_file, nullptr, 0, 0,
384 "Alias for -lto-cs-profile-file", nullptr, nullptr)
385OPTION(prefix_2, "plugin-opt=debug-pass-manager", anonymous_41, Flag, INVALID, lto_debug_pass_manager, nullptr, 0, 0,
357386 "Alias for -lto-debug-pass-manager", nullptr, nullptr)
358OPTION(prefix_2, "plugin-opt=disable-verify", anonymous_41, Flag, INVALID, disable_verify, nullptr, 0, 0,
387OPTION(prefix_2, "plugin-opt=disable-verify", anonymous_42, Flag, INVALID, disable_verify, nullptr, 0, 0,
359388 "Alias for -disable-verify", nullptr, nullptr)
360389OPTION(prefix_2, "plugin-opt=dwo_dir=", plugin_opt_dwo_dir_eq, Joined, INVALID, INVALID, nullptr, 0, 0,
361390 "Directory to store .dwo files when LTO and debug fission are used", nullptr, nullptr)
362391OPTION(prefix_2, "plugin-opt=emit-llvm", plugin_opt_emit_llvm, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
363OPTION(prefix_2, "plugin-opt=jobs=", anonymous_42, Joined, INVALID, thinlto_jobs, nullptr, 0, 0,
392OPTION(prefix_2, "plugin-opt=jobs=", anonymous_43, Joined, INVALID, thinlto_jobs, nullptr, 0, 0,
364393 "Alias for -thinlto-jobs", nullptr, nullptr)
365OPTION(prefix_2, "plugin-opt=lto-partitions=", anonymous_43, Joined, INVALID, lto_partitions, nullptr, 0, 0,
394OPTION(prefix_2, "plugin-opt=lto-partitions=", anonymous_44, Joined, INVALID, lto_partitions, nullptr, 0, 0,
366395 "Alias for -lto-partitions", nullptr, nullptr)
367396OPTION(prefix_2, "plugin-opt=mcpu=", plugin_opt_mcpu_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
368OPTION(prefix_2, "plugin-opt=new-pass-manager", anonymous_44, Flag, INVALID, lto_new_pass_manager, nullptr, 0, 0,
397OPTION(prefix_2, "plugin-opt=new-pass-manager", anonymous_45, Flag, INVALID, lto_new_pass_manager, nullptr, 0, 0,
369398 "Alias for -lto-new-pass-manager", nullptr, nullptr)
370399OPTION(prefix_2, "plugin-opt=obj-path=", plugin_opt_obj_path_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
371OPTION(prefix_2, "plugin-opt=O", anonymous_39, Joined, INVALID, lto_O, nullptr, 0, 0,
400OPTION(prefix_2, "plugin-opt=O", anonymous_40, Joined, INVALID, lto_O, nullptr, 0, 0,
372401 "Alias for -lto-O", nullptr, nullptr)
373OPTION(prefix_2, "plugin-opt=sample-profile=", anonymous_45, Joined, INVALID, lto_sample_profile, nullptr, 0, 0,
402OPTION(prefix_2, "plugin-opt=sample-profile=", anonymous_48, Joined, INVALID, lto_sample_profile, nullptr, 0, 0,
374403 "Alias for -lto-sample-profile", nullptr, nullptr)
375OPTION(prefix_2, "plugin-opt=save-temps", anonymous_46, Flag, INVALID, save_temps, nullptr, 0, 0,
404OPTION(prefix_2, "plugin-opt=save-temps", anonymous_49, Flag, INVALID, save_temps, nullptr, 0, 0,
376405 "Alias for -save-temps", nullptr, nullptr)
377406OPTION(prefix_2, "plugin-opt=thinlto-emit-imports-files", plugin_opt_thinlto_emit_imports_files, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
378407OPTION(prefix_2, "plugin-opt=thinlto-index-only=", plugin_opt_thinlto_index_only_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
......@@ -394,9 +423,13 @@ OPTION(prefix_2, "print-icf-sections", print_icf_sections, Flag, INVALID, INVALI
394423 "List identical folded sections", nullptr, nullptr)
395424OPTION(prefix_2, "print-map", print_map, Flag, INVALID, INVALID, nullptr, 0, 0,
396425 "Print a link map to the standard output", nullptr, nullptr)
426OPTION(prefix_2, "print-symbol-order=", print_symbol_order_eq, Joined, INVALID, print_symbol_order, nullptr, 0, 0,
427 "Print a symbol order specified by --call-graph-ordering-file into the speficied file", nullptr, nullptr)
428OPTION(prefix_2, "print-symbol-order", print_symbol_order, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
397429OPTION(prefix_2, "push-state", push_state, Flag, INVALID, INVALID, nullptr, 0, 0,
398430 "Save the current state of -as-needed, -static and -whole-archive", nullptr, nullptr)
399OPTION(prefix_2, "Qy", anonymous_68, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
431OPTION(prefix_1, "p", anonymous_60, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
432OPTION(prefix_2, "Qy", anonymous_72, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
400433OPTION(prefix_1, "q", anonymous_11, Flag, INVALID, emit_relocs, nullptr, 0, 0,
401434 "Alias for --emit-relocs", nullptr, nullptr)
402435OPTION(prefix_2, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -404,20 +437,21 @@ OPTION(prefix_2, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0,
404437OPTION(prefix_2, "reproduce=", reproduce_eq, Joined, INVALID, reproduce, nullptr, 0, 0,
405438 "Dump linker invocation and input files for debugging", nullptr, nullptr)
406439OPTION(prefix_2, "reproduce", reproduce, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
440OPTION(prefix_2, "require-cet", require_cet, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
407441OPTION(prefix_2, "retain-symbols-file=", retain_symbols_file_eq, Joined, INVALID, retain_symbols_file, nullptr, 0, 0,
408442 "Retain only the symbols listed in the file", "<file>", nullptr)
409443OPTION(prefix_2, "retain-symbols-file", retain_symbols_file, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<file>", nullptr)
410OPTION(prefix_2, "rpath-link=", anonymous_59, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
411OPTION(prefix_2, "rpath-link", anonymous_58, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
444OPTION(prefix_2, "rpath-link=", anonymous_62, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
445OPTION(prefix_2, "rpath-link", anonymous_61, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
412446OPTION(prefix_2, "rpath=", rpath_eq, Joined, INVALID, rpath, nullptr, 0, 0,
413447 "Add a DT_RUNPATH to the output", nullptr, nullptr)
414448OPTION(prefix_2, "rpath", rpath, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
415449OPTION(prefix_2, "rsp-quoting=", rsp_quoting_eq, Joined, INVALID, rsp_quoting, nullptr, 0, 0,
416450 "Quoting style for response files", "[posix,windows]", nullptr)
417451OPTION(prefix_2, "rsp-quoting", rsp_quoting, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[posix,windows]", nullptr)
418OPTION(prefix_1, "R", anonymous_26, JoinedOrSeparate, INVALID, rpath, nullptr, 0, 0,
452OPTION(prefix_1, "R", anonymous_27, JoinedOrSeparate, INVALID, rpath, nullptr, 0, 0,
419453 "Alias for --rpath", nullptr, nullptr)
420OPTION(prefix_1, "r", anonymous_25, Flag, INVALID, relocatable, nullptr, 0, 0,
454OPTION(prefix_1, "r", anonymous_26, Flag, INVALID, relocatable, nullptr, 0, 0,
421455 "Alias for --relocatable", nullptr, nullptr)
422456OPTION(prefix_2, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
423457OPTION(prefix_2, "script=", script_eq, Joined, INVALID, script, nullptr, 0, 0,
......@@ -426,12 +460,13 @@ OPTION(prefix_2, "script", script, Separate, INVALID, INVALID, nullptr, 0, 0, nu
426460OPTION(prefix_2, "section-start=", section_start_eq, Joined, INVALID, section_start, nullptr, 0, 0,
427461 "Set address of section", "<address>", nullptr)
428462OPTION(prefix_2, "section-start", section_start, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<address>", nullptr)
463OPTION(prefix_2, "secure-plt", anonymous_63, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
429464OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0,
430465 "Build a shared object", nullptr, nullptr)
431466OPTION(prefix_2, "soname=", soname_eq, Joined, INVALID, soname, nullptr, 0, 0,
432467 "Set DT_SONAME", nullptr, nullptr)
433468OPTION(prefix_2, "soname", soname, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
434OPTION(prefix_2, "sort-common", anonymous_60, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
469OPTION(prefix_2, "sort-common", anonymous_64, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
435470OPTION(prefix_2, "sort-section=", sort_section_eq, Joined, INVALID, sort_section, nullptr, 0, 0,
436471 "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr)
437472OPTION(prefix_2, "sort-section", sort_section, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
......@@ -444,7 +479,7 @@ OPTION(prefix_2, "start-lib", start_lib, Flag, INVALID, INVALID, nullptr, 0, 0,
444479 "Start a grouping of objects that should be treated as if they were together in an archive", nullptr, nullptr)
445480OPTION(prefix_2, "static", anonymous_5, Flag, INVALID, Bstatic, nullptr, 0, 0,
446481 "Alias for --Bstatic", nullptr, nullptr)
447OPTION(prefix_2, "stats", anonymous_61, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
482OPTION(prefix_2, "stats", anonymous_65, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
448483OPTION(prefix_2, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0,
449484 "Strip all symbols", nullptr, nullptr)
450485OPTION(prefix_2, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -455,9 +490,9 @@ OPTION(prefix_2, "symbol-ordering-file", symbol_ordering_file, Separate, INVALID
455490OPTION(prefix_2, "sysroot=", sysroot_eq, Joined, INVALID, sysroot, nullptr, 0, 0,
456491 "Set the system root", nullptr, nullptr)
457492OPTION(prefix_2, "sysroot", sysroot, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
458OPTION(prefix_1, "S", anonymous_32, Flag, INVALID, strip_debug, nullptr, 0, 0,
493OPTION(prefix_1, "S", anonymous_33, Flag, INVALID, strip_debug, nullptr, 0, 0,
459494 "Alias for --strip-debug", nullptr, nullptr)
460OPTION(prefix_1, "s", anonymous_31, Flag, INVALID, strip_all, nullptr, 0, 0,
495OPTION(prefix_1, "s", anonymous_32, Flag, INVALID, strip_all, nullptr, 0, 0,
461496 "Alias for --strip-all", nullptr, nullptr)
462497OPTION(prefix_2, "target1-abs", target1_abs, Flag, INVALID, INVALID, nullptr, 0, 0,
463498 "Interpret R_ARM_TARGET1 as R_ARM_ABS32 (default)", nullptr, nullptr)
......@@ -488,17 +523,20 @@ OPTION(prefix_2, "trace-symbol=", trace_symbol_eq, Joined, INVALID, trace_symbol
488523OPTION(prefix_2, "trace-symbol", trace_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
489524OPTION(prefix_2, "trace", trace, Flag, INVALID, INVALID, nullptr, 0, 0,
490525 "Print the names of the input files", nullptr, nullptr)
491OPTION(prefix_4, "Ttext-segment=", anonymous_36, Joined, INVALID, Ttext, nullptr, 0, 0,
526OPTION(prefix_4, "Ttext-segment=", anonymous_37, Joined, INVALID, Ttext, nullptr, 0, 0,
492527 "Alias for --Ttext", nullptr, nullptr)
493OPTION(prefix_4, "Ttext-segment", anonymous_35, Separate, INVALID, Ttext, nullptr, 0, 0,
528OPTION(prefix_4, "Ttext-segment", anonymous_36, Separate, INVALID, Ttext, nullptr, 0, 0,
494529 "Alias for --Ttext", nullptr, nullptr)
495530OPTION(prefix_2, "Ttext=", Ttext_eq, Joined, INVALID, Ttext, nullptr, 0, 0,
496531 "Same as --section-start with .text as the sectionname", nullptr, nullptr)
497532OPTION(prefix_2, "Ttext", Ttext, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
498OPTION(prefix_1, "T", anonymous_27, JoinedOrSeparate, INVALID, script, nullptr, 0, 0,
533OPTION(prefix_1, "T", anonymous_28, JoinedOrSeparate, INVALID, script, nullptr, 0, 0,
499534 "Alias for --script", nullptr, nullptr)
500OPTION(prefix_1, "t", anonymous_33, Flag, INVALID, trace, nullptr, 0, 0,
535OPTION(prefix_1, "t", anonymous_34, Flag, INVALID, trace, nullptr, 0, 0,
501536 "Alias for --trace", nullptr, nullptr)
537OPTION(prefix_2, "undefined-glob=", undefined_glob_eq, Joined, INVALID, undefined_glob, nullptr, 0, 0,
538 "Force undefined symbol during linking", "<pattern>", nullptr)
539OPTION(prefix_2, "undefined-glob", undefined_glob, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<pattern>", nullptr)
502540OPTION(prefix_2, "undefined-version", undefined_version, Flag, INVALID, INVALID, nullptr, 0, 0,
503541 "Allow unused version in version script (default)", nullptr, nullptr)
504542OPTION(prefix_2, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0,
......@@ -509,7 +547,7 @@ OPTION(prefix_2, "unresolved-symbols=", unresolved_symbols_eq, Joined, INVALID,
509547OPTION(prefix_2, "unresolved-symbols", unresolved_symbols, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
510548OPTION(prefix_2, "use-android-relr-tags", use_android_relr_tags, Flag, INVALID, INVALID, nullptr, 0, 0,
511549 "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*", nullptr, nullptr)
512OPTION(prefix_1, "u", anonymous_37, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0,
550OPTION(prefix_1, "u", anonymous_38, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0,
513551 "Alias for --undefined", nullptr, nullptr)
514552OPTION(prefix_2, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0,
515553 "Verbose mode", nullptr, nullptr)
......@@ -518,7 +556,9 @@ OPTION(prefix_2, "version-script=", version_script_eq, Joined, INVALID, version_
518556OPTION(prefix_2, "version-script", version_script, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
519557OPTION(prefix_2, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0,
520558 "Display the version number and exit", nullptr, nullptr)
521OPTION(prefix_1, "V", anonymous_38, Flag, INVALID, version, nullptr, 0, 0,
559OPTION(prefix_2, "vs-diagnostics", visual_studio_diagnostics_format, Flag, INVALID, INVALID, nullptr, 0, 0,
560 "Format diagnostics for Visual Studio compatiblity", nullptr, nullptr)
561OPTION(prefix_1, "V", anonymous_39, Flag, INVALID, version, nullptr, 0, 0,
522562 "Alias for --version", nullptr, nullptr)
523563OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0,
524564 "Display the version number", nullptr, nullptr)
......@@ -526,11 +566,11 @@ OPTION(prefix_2, "warn-backrefs", warn_backrefs, Flag, INVALID, INVALID, nullptr
526566 "Warn about backward symbol references to fetch archive members", nullptr, nullptr)
527567OPTION(prefix_2, "warn-common", warn_common, Flag, INVALID, INVALID, nullptr, 0, 0,
528568 "Warn about duplicate common symbols", nullptr, nullptr)
529OPTION(prefix_2, "warn-execstack", anonymous_62, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
569OPTION(prefix_2, "warn-execstack", anonymous_66, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
530570OPTION(prefix_2, "warn-ifunc-textrel", warn_ifunc_textrel, Flag, INVALID, INVALID, nullptr, 0, 0,
531571 "Warn about using ifunc symbols with text relocations", nullptr, nullptr)
532OPTION(prefix_2, "warn-once", anonymous_63, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
533OPTION(prefix_2, "warn-shared-textrel", anonymous_64, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
572OPTION(prefix_2, "warn-once", anonymous_67, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
573OPTION(prefix_2, "warn-shared-textrel", anonymous_68, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
534574OPTION(prefix_2, "warn-symbol-ordering", warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0,
535575 "Warn about problems with the symbol ordering file (default)", nullptr, nullptr)
536576OPTION(prefix_2, "warn-unresolved-symbols", warn_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -544,7 +584,7 @@ OPTION(prefix_1, "X", anonymous_10, Flag, INVALID, discard_locals, nullptr, 0, 0
544584 "Alias for --discard-locals", nullptr, nullptr)
545585OPTION(prefix_1, "x", anonymous_9, Flag, INVALID, discard_all, nullptr, 0, 0,
546586 "Alias for --discard-all", nullptr, nullptr)
547OPTION(prefix_1, "y", anonymous_34, JoinedOrSeparate, INVALID, trace_symbol, nullptr, 0, 0,
587OPTION(prefix_1, "y", anonymous_35, JoinedOrSeparate, INVALID, trace_symbol, nullptr, 0, 0,
548588 "Alias for --trace-symbol", nullptr, nullptr)
549589OPTION(prefix_1, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
550590 "Linker option extensions", "<option>", nullptr)
deps/lld-prebuilt/MinGW/Options.inc+50-26
......@@ -30,31 +30,39 @@ OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullp
3030OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
3131OPTION(prefix_1, "###", _HASH_HASH_HASH, Flag, INVALID, INVALID, nullptr, 0, 0,
3232 "Print (but do not run) the commands to run for this compilation", nullptr, nullptr)
33OPTION(prefix_2, "appcontainer", appcontainer, Flag, INVALID, INVALID, nullptr, 0, 0,
34 "Set the appcontainer flag in the executable", nullptr, nullptr)
3335OPTION(prefix_2, "Bdynamic", Bdynamic, Flag, INVALID, INVALID, nullptr, 0, 0,
3436 "Link against shared libraries", nullptr, nullptr)
3537OPTION(prefix_2, "Bstatic", Bstatic, Flag, INVALID, INVALID, nullptr, 0, 0,
3638 "Do not link against shared libraries", nullptr, nullptr)
37OPTION(prefix_2, "build-id", build_id, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
38OPTION(prefix_2, "disable-auto-image-base", disable_auto_image_base, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
39OPTION(prefix_2, "build-id", anonymous_1, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
40OPTION(prefix_2, "disable-auto-image-base", anonymous_2, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
3941OPTION(prefix_2, "dynamicbase", dynamicbase, Flag, INVALID, INVALID, nullptr, 0, 0,
4042 "Enable ASLR", nullptr, nullptr)
41OPTION(prefix_2, "enable-auto-image-base", enable_auto_image_base, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
42OPTION(prefix_2, "enable-auto-import", enable_auto_import, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
43OPTION(prefix_2, "end-group", end_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
43OPTION(prefix_2, "enable-auto-image-base", anonymous_3, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
44OPTION(prefix_2, "enable-auto-import", anonymous_4, Flag, INVALID, INVALID, nullptr, 0, 0,
45 "Ignored; listed for libtool compatibility", nullptr, nullptr)
46OPTION(prefix_2, "end-group", anonymous_5, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
4447OPTION(prefix_2, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0,
4548 "Name of entry point symbol", "<entry>", nullptr)
49OPTION(prefix_2, "exclude-all-symbols", exclude_all_symbols, Flag, INVALID, INVALID, nullptr, 0, 0,
50 "Don't automatically export any symbols", nullptr, nullptr)
4651OPTION(prefix_2, "export-all-symbols", export_all_symbols, Flag, INVALID, INVALID, nullptr, 0, 0,
4752 "Export all symbols even if a def file or dllexport attributes are used", nullptr, nullptr)
4853OPTION(prefix_1, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
49OPTION(prefix_3, "full-shutdown", full_shutdown, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
54OPTION(prefix_3, "full-shutdown", anonymous_6, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
5055OPTION(prefix_2, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
5156 "Remove unused sections", nullptr, nullptr)
52OPTION(prefix_2, "high-entropy-va", high_entropy_va, Flag, INVALID, INVALID, nullptr, 0, 0,
53 "Enable 64-bit ASLR", nullptr, nullptr)
57OPTION(prefix_2, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0,
58 "Print option help", nullptr, nullptr)
59OPTION(prefix_2, "high-entropy-va", anonymous_7, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
5460OPTION(prefix_2, "icf=", icf, Joined, INVALID, INVALID, nullptr, 0, 0,
5561 "Identical code folding", nullptr, nullptr)
5662OPTION(prefix_2, "image-base", image_base, Separate, INVALID, INVALID, nullptr, 0, 0,
5763 "Base address of the program", nullptr, nullptr)
64OPTION(prefix_2, "insert-timestamp", insert_timestamp, Flag, INVALID, INVALID, nullptr, 0, 0,
65 "Include PE header timestamp", nullptr, nullptr)
5866OPTION(prefix_2, "kill-at", kill_at, Flag, INVALID, INVALID, nullptr, 0, 0,
5967 "Remove @n from exported symbols", nullptr, nullptr)
6068OPTION(prefix_3, "large-address-aware", large_address_aware, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -63,56 +71,72 @@ OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
6371 "Add a directory to the library search path", "<dir>", nullptr)
6472OPTION(prefix_1, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
6573 "Root name of library to use", "<libName>", nullptr)
66OPTION(prefix_2, "major-image-version", major_image_version, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
74OPTION(prefix_2, "major-image-version", anonymous_8, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
75OPTION(prefix_3, "major-os-version=", major_os_version_eq, Joined, INVALID, major_os_version, nullptr, 0, 0, nullptr, nullptr, nullptr)
76OPTION(prefix_3, "major-os-version", major_os_version, Separate, INVALID, INVALID, nullptr, 0, 0,
77 "Set the OS and subsystem major version", nullptr, nullptr)
78OPTION(prefix_3, "major-subsystem-version=", major_subsystem_version_eq, Joined, INVALID, major_subsystem_version, nullptr, 0, 0, nullptr, nullptr, nullptr)
79OPTION(prefix_3, "major-subsystem-version", major_subsystem_version, Separate, INVALID, INVALID, nullptr, 0, 0,
80 "Set the OS and subsystem major version", nullptr, nullptr)
6781OPTION(prefix_2, "Map=", map_eq, Joined, INVALID, map, nullptr, 0, 0, nullptr, nullptr, nullptr)
6882OPTION(prefix_2, "Map", map, Separate, INVALID, INVALID, nullptr, 0, 0,
6983 "Output a linker map", nullptr, nullptr)
70OPTION(prefix_2, "minor-image-version", minor_image_version, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
84OPTION(prefix_2, "minor-image-version", anonymous_9, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
85OPTION(prefix_3, "minor-os-version=", minor_os_version_eq, Joined, INVALID, minor_os_version, nullptr, 0, 0, nullptr, nullptr, nullptr)
86OPTION(prefix_3, "minor-os-version", minor_os_version, Separate, INVALID, INVALID, nullptr, 0, 0,
87 "Set the OS and subsystem minor version", nullptr, nullptr)
88OPTION(prefix_3, "minor-subsystem-version=", minor_subsystem_version_eq, Joined, INVALID, minor_subsystem_version, nullptr, 0, 0, nullptr, nullptr, nullptr)
89OPTION(prefix_3, "minor-subsystem-version", minor_subsystem_version, Separate, INVALID, INVALID, nullptr, 0, 0,
90 "Set the OS and subsystem minor version", nullptr, nullptr)
7191OPTION(prefix_2, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
7292OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
7393 "Set target emulation", nullptr, nullptr)
7494OPTION(prefix_2, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
7595 "Don't remove unused sections", nullptr, nullptr)
76OPTION(prefix_2, "no-seh", no_seh, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
96OPTION(prefix_2, "no-insert-timestamp", no_insert_timestamp, Flag, INVALID, INVALID, nullptr, 0, 0,
97 "Don't include PE header timestamp", nullptr, nullptr)
98OPTION(prefix_2, "no-seh", anonymous_10, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
7799OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0,
78100 "No longer include all object files for following archives", nullptr, nullptr)
79OPTION(prefix_2, "nxcompat", nxcompat, Flag, INVALID, INVALID, nullptr, 0, 0,
80 "Enable data execution prevention", nullptr, nullptr)
101OPTION(prefix_2, "nxcompat", anonymous_11, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
81102OPTION(prefix_3, "out-implib=", out_implib_eq, Joined, INVALID, out_implib, nullptr, 0, 0, nullptr, nullptr, nullptr)
82103OPTION(prefix_3, "out-implib", out_implib, Separate, INVALID, INVALID, nullptr, 0, 0,
83104 "Import library name", nullptr, nullptr)
84105OPTION(prefix_2, "output-def", output_def, Separate, INVALID, INVALID, nullptr, 0, 0,
85106 "Output def file", nullptr, nullptr)
86OPTION(prefix_1, "O", O, Joined, INVALID, INVALID, nullptr, 0, 0,
87 "Optimize output file size", nullptr, nullptr)
107OPTION(prefix_1, "O", anonymous_0, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
88108OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
89109 "Path to file to write output", "<path>", nullptr)
110OPTION(prefix_2, "pdb=", pdb_eq, Joined, INVALID, pdb, nullptr, 0, 0, nullptr, nullptr, nullptr)
90111OPTION(prefix_2, "pdb", pdb, Separate, INVALID, INVALID, nullptr, 0, 0,
91 "Specify output PDB debug information file", nullptr, nullptr)
92OPTION(prefix_2, "pic-executable", pic_executable, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
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)
112 "Output PDB debug info file, chosen implicitly if the argument is empty", nullptr, nullptr)
113OPTION(prefix_2, "pic-executable", anonymous_12, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
114OPTION(prefix_2, "plugin-opt=", anonymous_16, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
115OPTION(prefix_2, "plugin-opt", anonymous_15, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
116OPTION(prefix_2, "plugin=", anonymous_14, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
117OPTION(prefix_2, "plugin", anonymous_13, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
97118OPTION(prefix_2, "require-defined=", require_defined_eq, Joined, INVALID, require_defined, nullptr, 0, 0, nullptr, nullptr, nullptr)
98119OPTION(prefix_2, "require-defined", require_defined, Separate, INVALID, INVALID, nullptr, 0, 0,
99120 "Force symbol to be added to symbol table as an undefined one", nullptr, nullptr)
100121OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0,
101122 "Build a shared object", nullptr, nullptr)
102123OPTION(prefix_2, "stack", stack, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
103OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
124OPTION(prefix_2, "start-group", anonymous_18, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
104125OPTION(prefix_2, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0,
105126 "Omit all symbol information from the output binary", nullptr, nullptr)
106127OPTION(prefix_2, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0,
107128 "Omit all debug information, but keep symbol information", nullptr, nullptr)
129OPTION(prefix_2, "subsystem=", subs_eq, Joined, INVALID, subs, nullptr, 0, 0, nullptr, nullptr, nullptr)
108130OPTION(prefix_2, "subsystem", subs, Separate, INVALID, INVALID, nullptr, 0, 0,
109131 "Specify subsystem", nullptr, nullptr)
110OPTION(prefix_2, "sysroot", sysroot, Joined, INVALID, INVALID, nullptr, 0, 0,
111 "Sysroot", nullptr, nullptr)
132OPTION(prefix_2, "sysroot", anonymous_17, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
112133OPTION(prefix_1, "S", alias_strip_S, Flag, INVALID, strip_debug, nullptr, 0, 0, nullptr, nullptr, nullptr)
113134OPTION(prefix_1, "s", alias_strip_s, Flag, INVALID, strip_all, nullptr, 0, 0, nullptr, nullptr, nullptr)
114OPTION(prefix_2, "tsaware", tsaware, Flag, INVALID, INVALID, nullptr, 0, 0,
115 "Create Terminal Server aware executable", nullptr, nullptr)
135OPTION(prefix_2, "tsaware", anonymous_19, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
136OPTION(prefix_2, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
137OPTION(prefix_2, "undefined", undefined_long, Separate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
138OPTION(prefix_2, "u", undefined, Separate, INVALID, INVALID, nullptr, 0, 0,
139 "Include symbol in the link, if available", nullptr, nullptr)
116140OPTION(prefix_2, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0,
117141 "Verbose mode", nullptr, nullptr)
118142OPTION(prefix_2, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0,
deps/lld-prebuilt/lld/Common/Version.inc+3-3
......@@ -1,6 +1,6 @@
1#define LLD_VERSION 8.0.0
2#define LLD_VERSION_STRING "8.0.0"
3#define LLD_VERSION_MAJOR 8
1#define LLD_VERSION 9.0.0
2#define LLD_VERSION_STRING "9.0.0"
3#define LLD_VERSION_MAJOR 9
44#define LLD_VERSION_MINOR 0
55#define LLD_REVISION_STRING ""
66#define LLD_REPOSITORY_STRING ""
deps/lld-prebuilt/wasm/Options.inc+28-1
......@@ -27,11 +27,15 @@ PREFIX(prefix_1, {"--" COMMA "-" COMMA nullptr})
2727
2828OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
2929OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
30OPTION(prefix_1, "active-segments", active_segments, Flag, INVALID, INVALID, nullptr, 0, 0,
31 "Force segments to be active (default with unshared memory)", nullptr, nullptr)
3032OPTION(prefix_1, "allow-undefined-file=", allow_undefined_file, Joined, INVALID, INVALID, nullptr, 0, 0,
3133 "Allow symbols listed in <file> to be undefined in linked binary", nullptr, nullptr)
3234OPTION(prefix_2, "allow-undefined-file", allow_undefined_file_s, Separate, INVALID, allow_undefined_file, nullptr, 0, 0, nullptr, nullptr, nullptr)
3335OPTION(prefix_1, "allow-undefined", allow_undefined, Flag, INVALID, INVALID, nullptr, 0, 0,
3436 "Allow undefined symbols in linked binary", nullptr, nullptr)
37OPTION(prefix_1, "check-features", check_features, Flag, INVALID, INVALID, nullptr, 0, 0,
38 "Check feature compatibility of linked objects (default)", nullptr, nullptr)
3539OPTION(prefix_1, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, INVALID, nullptr, 0, 0,
3640 "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr)
3741OPTION(prefix_1, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -41,6 +45,8 @@ OPTION(prefix_1, "compress-relocations", compress_relocations, Flag, INVALID, IN
4145OPTION(prefix_1, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
4246 "Demangle symbol names", nullptr, nullptr)
4347OPTION(prefix_1, "disable-verify", disable_verify, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
48OPTION(prefix_1, "emit-relocs", emit_relocs, Flag, INVALID, INVALID, nullptr, 0, 0,
49 "Generate relocations in output", nullptr, nullptr)
4450OPTION(prefix_1, "entry=", anonymous_1, Joined, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
4551OPTION(prefix_1, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0,
4652 "Name of entry point symbol", "<entry>", nullptr)
......@@ -60,6 +66,8 @@ OPTION(prefix_2, "E", anonymous_2, Flag, INVALID, export_dynamic, nullptr, 0, 0,
6066OPTION(prefix_2, "e", anonymous_0, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
6167OPTION(prefix_1, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0,
6268 "Treat warnings as errors", nullptr, nullptr)
69OPTION(prefix_1, "features=", features, CommaJoined, INVALID, INVALID, nullptr, 0, 0,
70 "Comma-separated used features, inferred from input objects by default.", nullptr, nullptr)
6371OPTION(prefix_1, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
6472 "Enable garbage collection of unused sections", nullptr, nullptr)
6573OPTION(prefix_1, "global-base=", global_base, Joined, INVALID, INVALID, nullptr, 0, 0,
......@@ -88,6 +96,8 @@ OPTION(prefix_1, "merge-data-segments", merge_data_segments, Flag, INVALID, INVA
8896OPTION(prefix_1, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0,
8997 "Options to pass to LLVM", nullptr, nullptr)
9098OPTION(prefix_2, "m", anonymous_4, Flag, INVALID, max_memory, nullptr, 0, 0, nullptr, nullptr, nullptr)
99OPTION(prefix_1, "no-check-features", no_check_features, Flag, INVALID, INVALID, nullptr, 0, 0,
100 "Ignore feature compatibility of linked objects", nullptr, nullptr)
91101OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
92102 "Do not use colors in diagnostics", nullptr, nullptr)
93103OPTION(prefix_1, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -113,12 +123,17 @@ OPTION(prefix_2, "O", O, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
113123 "Optimize output file size", nullptr, nullptr)
114124OPTION(prefix_2, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
115125 "Path to file to write output", "<path>", nullptr)
126OPTION(prefix_1, "passive-segments", passive_segments, Flag, INVALID, INVALID, nullptr, 0, 0,
127 "Force segments to be passive (default with shared memory)", nullptr, nullptr)
116128OPTION(prefix_1, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0,
117129 "Create a position independent executable", nullptr, nullptr)
118130OPTION(prefix_1, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
119131 "List removed unused sections", nullptr, nullptr)
120132OPTION(prefix_1, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0,
121133 "Create relocatable object file", nullptr, nullptr)
134OPTION(prefix_1, "reproduce=", reproduce_eq, Joined, INVALID, reproduce, nullptr, 0, 0,
135 "Dump linker invocation and input files for debugging", nullptr, nullptr)
136OPTION(prefix_1, "reproduce", reproduce, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
122137OPTION(prefix_2, "r", anonymous_5, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr)
123138OPTION(prefix_1, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
124139OPTION(prefix_1, "shared-memory", shared_memory, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -144,10 +159,17 @@ OPTION(prefix_1, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullpt
144159 "Number of ThinLTO jobs", nullptr, nullptr)
145160OPTION(prefix_1, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,
146161 "Run the linker multi-threaded", nullptr, nullptr)
162OPTION(prefix_1, "trace-symbol=", trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0,
163 "Trace references to symbols", nullptr, nullptr)
164OPTION(prefix_1, "trace-symbol", trace_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
165OPTION(prefix_1, "trace", trace, Flag, INVALID, INVALID, nullptr, 0, 0,
166 "Print the names of the input files", nullptr, nullptr)
167OPTION(prefix_2, "t", anonymous_8, Flag, INVALID, trace, nullptr, 0, 0,
168 "Alias for --trace", nullptr, nullptr)
147169OPTION(prefix_1, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0,
148170 "Force undefined symbol during linking", nullptr, nullptr)
149171OPTION(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)
172OPTION(prefix_2, "u", anonymous_10, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
151173OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0,
152174 "Verbose mode", nullptr, nullptr)
153175OPTION(prefix_1, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0,
......@@ -156,6 +178,11 @@ OPTION(prefix_2, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0,
156178 "Display the version number", nullptr, nullptr)
157179OPTION(prefix_1, "whole-archive", whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0,
158180 "Force load of all members in a static library", nullptr, nullptr)
181OPTION(prefix_1, "wrap=", wrap_eq, Joined, INVALID, wrap, nullptr, 0, 0,
182 "Use wrapper functions for symbol", "<symbol>=<symbol>", nullptr)
183OPTION(prefix_1, "wrap", wrap, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<symbol>=<symbol>", nullptr)
184OPTION(prefix_2, "y", anonymous_9, JoinedOrSeparate, INVALID, trace_symbol, nullptr, 0, 0,
185 "Alias for --trace-symbol", nullptr, nullptr)
159186OPTION(prefix_2, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
160187 "Linker option extensions", "<option>", nullptr)
161188#endif // OPTION
deps/lld/COFF/CMakeLists.txt+1
......@@ -8,6 +8,7 @@ endif()
88
99add_lld_library(lldCOFF
1010 Chunks.cpp
11 DebugTypes.cpp
1112 DLL.cpp
1213 Driver.cpp
1314 DriverUtils.cpp
deps/lld/COFF/Chunks.cpp+444-405
......@@ -1,9 +1,8 @@
11//===- Chunks.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -30,203 +29,201 @@ using llvm::support::ulittle32_t;
3029namespace lld {
3130namespace coff {
3231
33SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)
34 : Chunk(SectionKind), Repl(this), Header(H), File(F),
35 Relocs(File->getCOFFObj()->getRelocations(Header)) {
36 // Initialize SectionName.
37 File->getCOFFObj()->getSectionName(Header, SectionName);
32SectionChunk::SectionChunk(ObjFile *f, const coff_section *h)
33 : Chunk(SectionKind), file(f), header(h), repl(this) {
34 // Initialize relocs.
35 setRelocs(file->getCOFFObj()->getRelocations(header));
36
37 // Initialize sectionName.
38 StringRef sectionName;
39 if (Expected<StringRef> e = file->getCOFFObj()->getSectionName(header))
40 sectionName = *e;
41 sectionNameData = sectionName.data();
42 sectionNameSize = sectionName.size();
43
44 setAlignment(header->getAlignment());
3845
39 Alignment = Header->getAlignment();
46 hasData = !(header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
4047
4148 // If linker GC is disabled, every chunk starts out alive. If linker GC is
4249 // enabled, treat non-comdat sections as roots. Generally optimized object
4350 // files will be built with -ffunction-sections or /Gy, so most things worth
4451 // stripping will be in a comdat.
45 Live = !Config->DoGC || !isCOMDAT();
52 live = !config->doGC || !isCOMDAT();
4653}
4754
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}
55// SectionChunk is one of the most frequently allocated classes, so it is
56// important to keep it as compact as possible. As of this writing, the number
57// below is the size of this class on x64 platforms.
58static_assert(sizeof(SectionChunk) <= 88, "SectionChunk grew unexpectedly");
6359
64static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
65static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
66static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
67static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); }
68static void or32(uint8_t *P, uint32_t V) { write32le(P, read32le(P) | V); }
60static void add16(uint8_t *p, int16_t v) { write16le(p, read16le(p) + v); }
61static void add32(uint8_t *p, int32_t v) { write32le(p, read32le(p) + v); }
62static void add64(uint8_t *p, int64_t v) { write64le(p, read64le(p) + v); }
63static void or16(uint8_t *p, uint16_t v) { write16le(p, read16le(p) | v); }
64static void or32(uint8_t *p, uint32_t v) { write32le(p, read32le(p) | v); }
6965
7066// Verify that given sections are appropriate targets for SECREL
7167// relocations. This check is relaxed because unfortunately debug
7268// sections have section-relative relocations against absolute symbols.
73static bool checkSecRel(const SectionChunk *Sec, OutputSection *OS) {
74 if (OS)
69static bool checkSecRel(const SectionChunk *sec, OutputSection *os) {
70 if (os)
7571 return true;
76 if (Sec->isCodeView())
72 if (sec->isCodeView())
7773 return false;
7874 error("SECREL relocation cannot be applied to absolute symbols");
7975 return false;
8076}
8177
82static void applySecRel(const SectionChunk *Sec, uint8_t *Off,
83 OutputSection *OS, uint64_t S) {
84 if (!checkSecRel(Sec, OS))
78static void applySecRel(const SectionChunk *sec, uint8_t *off,
79 OutputSection *os, uint64_t s) {
80 if (!checkSecRel(sec, os))
8581 return;
86 uint64_t SecRel = S - OS->getRVA();
87 if (SecRel > UINT32_MAX) {
88 error("overflow in SECREL relocation in section: " + Sec->getSectionName());
82 uint64_t secRel = s - os->getRVA();
83 if (secRel > UINT32_MAX) {
84 error("overflow in SECREL relocation in section: " + sec->getSectionName());
8985 return;
9086 }
91 add32(Off, SecRel);
87 add32(off, secRel);
9288}
9389
94static void applySecIdx(uint8_t *Off, OutputSection *OS) {
90static void applySecIdx(uint8_t *off, OutputSection *os) {
9591 // Absolute symbol doesn't have section index, but section index relocation
9692 // against absolute symbol should be resolved to one plus the last output
9793 // section index. This is required for compatibility with MSVC.
98 if (OS)
99 add16(Off, OS->SectionIndex);
94 if (os)
95 add16(off, os->sectionIndex);
10096 else
101 add16(Off, DefinedAbsolute::NumOutputSections + 1);
102}
103
104void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS,
105 uint64_t S, uint64_t P) const {
106 switch (Type) {
107 case IMAGE_REL_AMD64_ADDR32: add32(Off, S + Config->ImageBase); break;
108 case IMAGE_REL_AMD64_ADDR64: add64(Off, S + Config->ImageBase); break;
109 case IMAGE_REL_AMD64_ADDR32NB: add32(Off, S); break;
110 case IMAGE_REL_AMD64_REL32: add32(Off, S - P - 4); break;
111 case IMAGE_REL_AMD64_REL32_1: add32(Off, S - P - 5); break;
112 case IMAGE_REL_AMD64_REL32_2: add32(Off, S - P - 6); break;
113 case IMAGE_REL_AMD64_REL32_3: add32(Off, S - P - 7); break;
114 case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break;
115 case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break;
116 case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break;
117 case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break;
97 add16(off, DefinedAbsolute::numOutputSections + 1);
98}
99
100void SectionChunk::applyRelX64(uint8_t *off, uint16_t type, OutputSection *os,
101 uint64_t s, uint64_t p) const {
102 switch (type) {
103 case IMAGE_REL_AMD64_ADDR32: add32(off, s + config->imageBase); break;
104 case IMAGE_REL_AMD64_ADDR64: add64(off, s + config->imageBase); break;
105 case IMAGE_REL_AMD64_ADDR32NB: add32(off, s); break;
106 case IMAGE_REL_AMD64_REL32: add32(off, s - p - 4); break;
107 case IMAGE_REL_AMD64_REL32_1: add32(off, s - p - 5); break;
108 case IMAGE_REL_AMD64_REL32_2: add32(off, s - p - 6); break;
109 case IMAGE_REL_AMD64_REL32_3: add32(off, s - p - 7); break;
110 case IMAGE_REL_AMD64_REL32_4: add32(off, s - p - 8); break;
111 case IMAGE_REL_AMD64_REL32_5: add32(off, s - p - 9); break;
112 case IMAGE_REL_AMD64_SECTION: applySecIdx(off, os); break;
113 case IMAGE_REL_AMD64_SECREL: applySecRel(this, off, os, s); break;
118114 default:
119 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
120 toString(File));
115 error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " +
116 toString(file));
121117 }
122118}
123119
124void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS,
125 uint64_t S, uint64_t P) const {
126 switch (Type) {
120void SectionChunk::applyRelX86(uint8_t *off, uint16_t type, OutputSection *os,
121 uint64_t s, uint64_t p) const {
122 switch (type) {
127123 case IMAGE_REL_I386_ABSOLUTE: break;
128 case IMAGE_REL_I386_DIR32: add32(Off, S + Config->ImageBase); break;
129 case IMAGE_REL_I386_DIR32NB: add32(Off, S); break;
130 case IMAGE_REL_I386_REL32: add32(Off, S - P - 4); break;
131 case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break;
132 case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break;
124 case IMAGE_REL_I386_DIR32: add32(off, s + config->imageBase); break;
125 case IMAGE_REL_I386_DIR32NB: add32(off, s); break;
126 case IMAGE_REL_I386_REL32: add32(off, s - p - 4); break;
127 case IMAGE_REL_I386_SECTION: applySecIdx(off, os); break;
128 case IMAGE_REL_I386_SECREL: applySecRel(this, off, os, s); break;
133129 default:
134 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
135 toString(File));
130 error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " +
131 toString(file));
136132 }
137133}
138134
139static void applyMOV(uint8_t *Off, uint16_t V) {
140 write16le(Off, (read16le(Off) & 0xfbf0) | ((V & 0x800) >> 1) | ((V >> 12) & 0xf));
141 write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
135static void applyMOV(uint8_t *off, uint16_t v) {
136 write16le(off, (read16le(off) & 0xfbf0) | ((v & 0x800) >> 1) | ((v >> 12) & 0xf));
137 write16le(off + 2, (read16le(off + 2) & 0x8f00) | ((v & 0x700) << 4) | (v & 0xff));
142138}
143139
144static uint16_t readMOV(uint8_t *Off, bool MOVT) {
145 uint16_t Op1 = read16le(Off);
146 if ((Op1 & 0xfbf0) != (MOVT ? 0xf2c0 : 0xf240))
147 error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
140static uint16_t readMOV(uint8_t *off, bool movt) {
141 uint16_t op1 = read16le(off);
142 if ((op1 & 0xfbf0) != (movt ? 0xf2c0 : 0xf240))
143 error("unexpected instruction in " + Twine(movt ? "MOVT" : "MOVW") +
148144 " instruction in MOV32T relocation");
149 uint16_t Op2 = read16le(Off + 2);
150 if ((Op2 & 0x8000) != 0)
151 error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
145 uint16_t op2 = read16le(off + 2);
146 if ((op2 & 0x8000) != 0)
147 error("unexpected instruction in " + Twine(movt ? "MOVT" : "MOVW") +
152148 " instruction in MOV32T relocation");
153 return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |
154 ((Op1 & 0x000f) << 12);
149 return (op2 & 0x00ff) | ((op2 >> 4) & 0x0700) | ((op1 << 1) & 0x0800) |
150 ((op1 & 0x000f) << 12);
155151}
156152
157void applyMOV32T(uint8_t *Off, uint32_t V) {
158 uint16_t ImmW = readMOV(Off, false); // read MOVW operand
159 uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand
160 uint32_t Imm = ImmW | (ImmT << 16);
161 V += Imm; // add the immediate offset
162 applyMOV(Off, V); // set MOVW operand
163 applyMOV(Off + 4, V >> 16); // set MOVT operand
153void applyMOV32T(uint8_t *off, uint32_t v) {
154 uint16_t immW = readMOV(off, false); // read MOVW operand
155 uint16_t immT = readMOV(off + 4, true); // read MOVT operand
156 uint32_t imm = immW | (immT << 16);
157 v += imm; // add the immediate offset
158 applyMOV(off, v); // set MOVW operand
159 applyMOV(off + 4, v >> 16); // set MOVT operand
164160}
165161
166static void applyBranch20T(uint8_t *Off, int32_t V) {
167 if (!isInt<21>(V))
162static void applyBranch20T(uint8_t *off, int32_t v) {
163 if (!isInt<21>(v))
168164 error("relocation out of range");
169 uint32_t S = V < 0 ? 1 : 0;
170 uint32_t J1 = (V >> 19) & 1;
171 uint32_t J2 = (V >> 18) & 1;
172 or16(Off, (S << 10) | ((V >> 12) & 0x3f));
173 or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
165 uint32_t s = v < 0 ? 1 : 0;
166 uint32_t j1 = (v >> 19) & 1;
167 uint32_t j2 = (v >> 18) & 1;
168 or16(off, (s << 10) | ((v >> 12) & 0x3f));
169 or16(off + 2, (j1 << 13) | (j2 << 11) | ((v >> 1) & 0x7ff));
174170}
175171
176void applyBranch24T(uint8_t *Off, int32_t V) {
177 if (!isInt<25>(V))
172void applyBranch24T(uint8_t *off, int32_t v) {
173 if (!isInt<25>(v))
178174 error("relocation out of range");
179 uint32_t S = V < 0 ? 1 : 0;
180 uint32_t J1 = ((~V >> 23) & 1) ^ S;
181 uint32_t J2 = ((~V >> 22) & 1) ^ S;
182 or16(Off, (S << 10) | ((V >> 12) & 0x3ff));
175 uint32_t s = v < 0 ? 1 : 0;
176 uint32_t j1 = ((~v >> 23) & 1) ^ s;
177 uint32_t j2 = ((~v >> 22) & 1) ^ s;
178 or16(off, (s << 10) | ((v >> 12) & 0x3ff));
183179 // Clear out the J1 and J2 bits which may be set.
184 write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
180 write16le(off + 2, (read16le(off + 2) & 0xd000) | (j1 << 13) | (j2 << 11) | ((v >> 1) & 0x7ff));
185181}
186182
187void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
188 uint64_t S, uint64_t P) const {
183void SectionChunk::applyRelARM(uint8_t *off, uint16_t type, OutputSection *os,
184 uint64_t s, uint64_t p) const {
189185 // Pointer to thumb code must have the LSB set.
190 uint64_t SX = S;
191 if (OS && (OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE))
192 SX |= 1;
193 switch (Type) {
194 case IMAGE_REL_ARM_ADDR32: add32(Off, SX + Config->ImageBase); break;
195 case IMAGE_REL_ARM_ADDR32NB: add32(Off, SX); break;
196 case IMAGE_REL_ARM_MOV32T: applyMOV32T(Off, SX + Config->ImageBase); break;
197 case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, SX - P - 4); break;
198 case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, SX - P - 4); break;
199 case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, SX - P - 4); break;
200 case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break;
201 case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break;
186 uint64_t sx = s;
187 if (os && (os->header.Characteristics & IMAGE_SCN_MEM_EXECUTE))
188 sx |= 1;
189 switch (type) {
190 case IMAGE_REL_ARM_ADDR32: add32(off, sx + config->imageBase); break;
191 case IMAGE_REL_ARM_ADDR32NB: add32(off, sx); break;
192 case IMAGE_REL_ARM_MOV32T: applyMOV32T(off, sx + config->imageBase); break;
193 case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(off, sx - p - 4); break;
194 case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(off, sx - p - 4); break;
195 case IMAGE_REL_ARM_BLX23T: applyBranch24T(off, sx - p - 4); break;
196 case IMAGE_REL_ARM_SECTION: applySecIdx(off, os); break;
197 case IMAGE_REL_ARM_SECREL: applySecRel(this, off, os, s); break;
198 case IMAGE_REL_ARM_REL32: add32(off, sx - p - 4); break;
202199 default:
203 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
204 toString(File));
200 error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " +
201 toString(file));
205202 }
206203}
207204
208205// Interpret the existing immediate value as a byte offset to the
209206// target symbol, then update the instruction with the immediate as
210207// the page offset from the current instruction to the target.
211void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
212 uint32_t Orig = read32le(Off);
213 uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);
214 S += Imm;
215 Imm = (S >> Shift) - (P >> Shift);
216 uint32_t ImmLo = (Imm & 0x3) << 29;
217 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
218 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
219 write32le(Off, (Orig & ~Mask) | ImmLo | ImmHi);
208void applyArm64Addr(uint8_t *off, uint64_t s, uint64_t p, int shift) {
209 uint32_t orig = read32le(off);
210 uint64_t imm = ((orig >> 29) & 0x3) | ((orig >> 3) & 0x1FFFFC);
211 s += imm;
212 imm = (s >> shift) - (p >> shift);
213 uint32_t immLo = (imm & 0x3) << 29;
214 uint32_t immHi = (imm & 0x1FFFFC) << 3;
215 uint64_t mask = (0x3 << 29) | (0x1FFFFC << 3);
216 write32le(off, (orig & ~mask) | immLo | immHi);
220217}
221218
222219// Update the immediate field in a AARCH64 ldr, str, and add instruction.
223220// Optionally limit the range of the written immediate by one or more bits
224// (RangeLimit).
225void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
226 uint32_t Orig = read32le(Off);
227 Imm += (Orig >> 10) & 0xFFF;
228 Orig &= ~(0xFFF << 10);
229 write32le(Off, Orig | ((Imm & (0xFFF >> RangeLimit)) << 10));
221// (rangeLimit).
222void applyArm64Imm(uint8_t *off, uint64_t imm, uint32_t rangeLimit) {
223 uint32_t orig = read32le(off);
224 imm += (orig >> 10) & 0xFFF;
225 orig &= ~(0xFFF << 10);
226 write32le(off, orig | ((imm & (0xFFF >> rangeLimit)) << 10));
230227}
231228
232229// Add the 12 bit page offset to the existing immediate.
......@@ -237,171 +234,178 @@ void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
237234// Even if larger loads/stores have a larger range, limit the
238235// effective offset to 12 bit, since it is intended to be a
239236// page offset.
240static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) {
241 uint32_t Orig = read32le(Off);
242 uint32_t Size = Orig >> 30;
237static void applyArm64Ldr(uint8_t *off, uint64_t imm) {
238 uint32_t orig = read32le(off);
239 uint32_t size = orig >> 30;
243240 // 0x04000000 indicates SIMD/FP registers
244241 // 0x00800000 indicates 128 bit
245 if ((Orig & 0x4800000) == 0x4800000)
246 Size += 4;
247 if ((Imm & ((1 << Size) - 1)) != 0)
242 if ((orig & 0x4800000) == 0x4800000)
243 size += 4;
244 if ((imm & ((1 << size) - 1)) != 0)
248245 error("misaligned ldr/str offset");
249 applyArm64Imm(Off, Imm >> Size, Size);
246 applyArm64Imm(off, imm >> size, size);
250247}
251248
252static void applySecRelLow12A(const SectionChunk *Sec, uint8_t *Off,
253 OutputSection *OS, uint64_t S) {
254 if (checkSecRel(Sec, OS))
255 applyArm64Imm(Off, (S - OS->getRVA()) & 0xfff, 0);
249static void applySecRelLow12A(const SectionChunk *sec, uint8_t *off,
250 OutputSection *os, uint64_t s) {
251 if (checkSecRel(sec, os))
252 applyArm64Imm(off, (s - os->getRVA()) & 0xfff, 0);
256253}
257254
258static void applySecRelHigh12A(const SectionChunk *Sec, uint8_t *Off,
259 OutputSection *OS, uint64_t S) {
260 if (!checkSecRel(Sec, OS))
255static void applySecRelHigh12A(const SectionChunk *sec, uint8_t *off,
256 OutputSection *os, uint64_t s) {
257 if (!checkSecRel(sec, os))
261258 return;
262 uint64_t SecRel = (S - OS->getRVA()) >> 12;
263 if (0xfff < SecRel) {
259 uint64_t secRel = (s - os->getRVA()) >> 12;
260 if (0xfff < secRel) {
264261 error("overflow in SECREL_HIGH12A relocation in section: " +
265 Sec->getSectionName());
262 sec->getSectionName());
266263 return;
267264 }
268 applyArm64Imm(Off, SecRel & 0xfff, 0);
265 applyArm64Imm(off, secRel & 0xfff, 0);
269266}
270267
271static void applySecRelLdr(const SectionChunk *Sec, uint8_t *Off,
272 OutputSection *OS, uint64_t S) {
273 if (checkSecRel(Sec, OS))
274 applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);
268static void applySecRelLdr(const SectionChunk *sec, uint8_t *off,
269 OutputSection *os, uint64_t s) {
270 if (checkSecRel(sec, os))
271 applyArm64Ldr(off, (s - os->getRVA()) & 0xfff);
275272}
276273
277void applyArm64Branch26(uint8_t *Off, int64_t V) {
278 if (!isInt<28>(V))
274void applyArm64Branch26(uint8_t *off, int64_t v) {
275 if (!isInt<28>(v))
279276 error("relocation out of range");
280 or32(Off, (V & 0x0FFFFFFC) >> 2);
277 or32(off, (v & 0x0FFFFFFC) >> 2);
281278}
282279
283static void applyArm64Branch19(uint8_t *Off, int64_t V) {
284 if (!isInt<21>(V))
280static void applyArm64Branch19(uint8_t *off, int64_t v) {
281 if (!isInt<21>(v))
285282 error("relocation out of range");
286 or32(Off, (V & 0x001FFFFC) << 3);
283 or32(off, (v & 0x001FFFFC) << 3);
287284}
288285
289static void applyArm64Branch14(uint8_t *Off, int64_t V) {
290 if (!isInt<16>(V))
286static void applyArm64Branch14(uint8_t *off, int64_t v) {
287 if (!isInt<16>(v))
291288 error("relocation out of range");
292 or32(Off, (V & 0x0000FFFC) << 3);
293}
294
295void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS,
296 uint64_t S, uint64_t P) const {
297 switch (Type) {
298 case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P, 12); break;
299 case IMAGE_REL_ARM64_REL21: applyArm64Addr(Off, S, P, 0); break;
300 case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff, 0); break;
301 case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break;
302 case IMAGE_REL_ARM64_BRANCH26: applyArm64Branch26(Off, S - P); break;
303 case IMAGE_REL_ARM64_BRANCH19: applyArm64Branch19(Off, S - P); break;
304 case IMAGE_REL_ARM64_BRANCH14: applyArm64Branch14(Off, S - P); break;
305 case IMAGE_REL_ARM64_ADDR32: add32(Off, S + Config->ImageBase); break;
306 case IMAGE_REL_ARM64_ADDR32NB: add32(Off, S); break;
307 case IMAGE_REL_ARM64_ADDR64: add64(Off, S + Config->ImageBase); break;
308 case IMAGE_REL_ARM64_SECREL: applySecRel(this, Off, OS, S); break;
309 case IMAGE_REL_ARM64_SECREL_LOW12A: applySecRelLow12A(this, Off, OS, S); break;
310 case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, Off, OS, S); break;
311 case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break;
312 case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break;
289 or32(off, (v & 0x0000FFFC) << 3);
290}
291
292void SectionChunk::applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os,
293 uint64_t s, uint64_t p) const {
294 switch (type) {
295 case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(off, s, p, 12); break;
296 case IMAGE_REL_ARM64_REL21: applyArm64Addr(off, s, p, 0); break;
297 case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(off, s & 0xfff, 0); break;
298 case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(off, s & 0xfff); break;
299 case IMAGE_REL_ARM64_BRANCH26: applyArm64Branch26(off, s - p); break;
300 case IMAGE_REL_ARM64_BRANCH19: applyArm64Branch19(off, s - p); break;
301 case IMAGE_REL_ARM64_BRANCH14: applyArm64Branch14(off, s - p); break;
302 case IMAGE_REL_ARM64_ADDR32: add32(off, s + config->imageBase); break;
303 case IMAGE_REL_ARM64_ADDR32NB: add32(off, s); break;
304 case IMAGE_REL_ARM64_ADDR64: add64(off, s + config->imageBase); break;
305 case IMAGE_REL_ARM64_SECREL: applySecRel(this, off, os, s); break;
306 case IMAGE_REL_ARM64_SECREL_LOW12A: applySecRelLow12A(this, off, os, s); break;
307 case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, off, os, s); break;
308 case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, off, os, s); break;
309 case IMAGE_REL_ARM64_SECTION: applySecIdx(off, os); break;
310 case IMAGE_REL_ARM64_REL32: add32(off, s - p - 4); break;
313311 default:
314 error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
315 toString(File));
312 error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " +
313 toString(file));
316314 }
317315}
318316
319static void maybeReportRelocationToDiscarded(const SectionChunk *FromChunk,
320 Defined *Sym,
321 const coff_relocation &Rel) {
317static void maybeReportRelocationToDiscarded(const SectionChunk *fromChunk,
318 Defined *sym,
319 const coff_relocation &rel) {
322320 // Don't report these errors when the relocation comes from a debug info
323321 // section or in mingw mode. MinGW mode object files (built by GCC) can
324322 // have leftover sections with relocations against discarded comdat
325323 // sections. Such sections are left as is, with relocations untouched.
326 if (FromChunk->isCodeView() || FromChunk->isDWARF() || Config->MinGW)
324 if (fromChunk->isCodeView() || fromChunk->isDWARF() || config->mingw)
327325 return;
328326
329327 // Get the name of the symbol. If it's null, it was discarded early, so we
330328 // have to go back to the object file.
331 ObjFile *File = FromChunk->File;
332 StringRef Name;
333 if (Sym) {
334 Name = Sym->getName();
329 ObjFile *file = fromChunk->file;
330 StringRef name;
331 if (sym) {
332 name = sym->getName();
335333 } else {
336 COFFSymbolRef COFFSym =
337 check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
338 File->getCOFFObj()->getSymbolName(COFFSym, Name);
334 COFFSymbolRef coffSym =
335 check(file->getCOFFObj()->getSymbol(rel.SymbolTableIndex));
336 file->getCOFFObj()->getSymbolName(coffSym, name);
339337 }
340338
341 error("relocation against symbol in discarded section: " + Name +
342 getSymbolLocations(File, Rel.SymbolTableIndex));
339 std::vector<std::string> symbolLocations =
340 getSymbolLocations(file, rel.SymbolTableIndex);
341
342 std::string out;
343 llvm::raw_string_ostream os(out);
344 os << "relocation against symbol in discarded section: " + name;
345 for (const std::string &s : symbolLocations)
346 os << s;
347 error(os.str());
343348}
344349
345void SectionChunk::writeTo(uint8_t *Buf) const {
346 if (!hasData())
350void SectionChunk::writeTo(uint8_t *buf) const {
351 if (!hasData)
347352 return;
348353 // Copy section contents from source object file to output file.
349 ArrayRef<uint8_t> A = getContents();
350 if (!A.empty())
351 memcpy(Buf + OutputSectionOff, A.data(), A.size());
354 ArrayRef<uint8_t> a = getContents();
355 if (!a.empty())
356 memcpy(buf, a.data(), a.size());
352357
353358 // Apply relocations.
354 size_t InputSize = getSize();
355 for (size_t I = 0, E = Relocs.size(); I < E; I++) {
356 const coff_relocation &Rel = Relocs[I];
359 size_t inputSize = getSize();
360 for (size_t i = 0, e = relocsSize; i < e; i++) {
361 const coff_relocation &rel = relocsData[i];
357362
358363 // Check for an invalid relocation offset. This check isn't perfect, because
359364 // we don't have the relocation size, which is only known after checking the
360365 // machine and relocation type. As a result, a relocation may overwrite the
361366 // beginning of the following input section.
362 if (Rel.VirtualAddress >= InputSize) {
367 if (rel.VirtualAddress >= inputSize) {
363368 error("relocation points beyond the end of its parent section");
364369 continue;
365370 }
366371
367 uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
372 uint8_t *off = buf + rel.VirtualAddress;
368373
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]);
374 auto *sym =
375 dyn_cast_or_null<Defined>(file->getSymbol(rel.SymbolTableIndex));
372376
373377 // Get the output section of the symbol for this relocation. The output
374378 // section is needed to compute SECREL and SECTION relocations used in debug
375379 // info.
376 Chunk *C = Sym ? Sym->getChunk() : nullptr;
377 OutputSection *OS = C ? C->getOutputSection() : nullptr;
380 Chunk *c = sym ? sym->getChunk() : nullptr;
381 OutputSection *os = c ? c->getOutputSection() : nullptr;
378382
379383 // Skip the relocation if it refers to a discarded section, and diagnose it
380384 // as an error if appropriate. If a symbol was discarded early, it may be
381385 // null. If it was discarded late, the output section will be null, unless
382386 // it was an absolute or synthetic symbol.
383 if (!Sym ||
384 (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym))) {
385 maybeReportRelocationToDiscarded(this, Sym, Rel);
387 if (!sym ||
388 (!os && !isa<DefinedAbsolute>(sym) && !isa<DefinedSynthetic>(sym))) {
389 maybeReportRelocationToDiscarded(this, sym, rel);
386390 continue;
387391 }
388392
389 uint64_t S = Sym->getRVA();
393 uint64_t s = sym->getRVA();
390394
391395 // Compute the RVA of the relocation for relative relocations.
392 uint64_t P = RVA + Rel.VirtualAddress;
393 switch (Config->Machine) {
396 uint64_t p = rva + rel.VirtualAddress;
397 switch (config->machine) {
394398 case AMD64:
395 applyRelX64(Off, Rel.Type, OS, S, P);
399 applyRelX64(off, rel.Type, os, s, p);
396400 break;
397401 case I386:
398 applyRelX86(Off, Rel.Type, OS, S, P);
402 applyRelX86(off, rel.Type, os, s, p);
399403 break;
400404 case ARMNT:
401 applyRelARM(Off, Rel.Type, OS, S, P);
405 applyRelARM(off, rel.Type, os, s, p);
402406 break;
403407 case ARM64:
404 applyRelARM64(Off, Rel.Type, OS, S, P);
408 applyRelARM64(off, rel.Type, os, s, p);
405409 break;
406410 default:
407411 llvm_unreachable("unknown machine type");
......@@ -409,28 +413,32 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
409413 }
410414}
411415
412void SectionChunk::addAssociative(SectionChunk *Child) {
413 AssocChildren.push_back(Child);
416void SectionChunk::addAssociative(SectionChunk *child) {
417 // Insert this child at the head of the list.
418 assert(child->assocChildren == nullptr &&
419 "associated sections cannot have their own associated children");
420 child->assocChildren = assocChildren;
421 assocChildren = child;
414422}
415423
416static uint8_t getBaserelType(const coff_relocation &Rel) {
417 switch (Config->Machine) {
424static uint8_t getBaserelType(const coff_relocation &rel) {
425 switch (config->machine) {
418426 case AMD64:
419 if (Rel.Type == IMAGE_REL_AMD64_ADDR64)
427 if (rel.Type == IMAGE_REL_AMD64_ADDR64)
420428 return IMAGE_REL_BASED_DIR64;
421429 return IMAGE_REL_BASED_ABSOLUTE;
422430 case I386:
423 if (Rel.Type == IMAGE_REL_I386_DIR32)
431 if (rel.Type == IMAGE_REL_I386_DIR32)
424432 return IMAGE_REL_BASED_HIGHLOW;
425433 return IMAGE_REL_BASED_ABSOLUTE;
426434 case ARMNT:
427 if (Rel.Type == IMAGE_REL_ARM_ADDR32)
435 if (rel.Type == IMAGE_REL_ARM_ADDR32)
428436 return IMAGE_REL_BASED_HIGHLOW;
429 if (Rel.Type == IMAGE_REL_ARM_MOV32T)
437 if (rel.Type == IMAGE_REL_ARM_MOV32T)
430438 return IMAGE_REL_BASED_ARM_MOV32T;
431439 return IMAGE_REL_BASED_ABSOLUTE;
432440 case ARM64:
433 if (Rel.Type == IMAGE_REL_ARM64_ADDR64)
441 if (rel.Type == IMAGE_REL_ARM64_ADDR64)
434442 return IMAGE_REL_BASED_DIR64;
435443 return IMAGE_REL_BASED_ABSOLUTE;
436444 default:
......@@ -442,18 +450,16 @@ static uint8_t getBaserelType(const coff_relocation &Rel) {
442450// Collect all locations that contain absolute addresses, which need to be
443451// fixed by the loader if load-time relocation is needed.
444452// Only called when base relocation is enabled.
445void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
446 for (size_t I = 0, E = Relocs.size(); I < E; I++) {
447 const coff_relocation &Rel = Relocs[I];
448 uint8_t Ty = getBaserelType(Rel);
449 if (Ty == IMAGE_REL_BASED_ABSOLUTE)
453void SectionChunk::getBaserels(std::vector<Baserel> *res) {
454 for (size_t i = 0, e = relocsSize; i < e; i++) {
455 const coff_relocation &rel = relocsData[i];
456 uint8_t ty = getBaserelType(rel);
457 if (ty == IMAGE_REL_BASED_ABSOLUTE)
450458 continue;
451 // Use the potentially remapped Symbol instead of the one that the
452 // relocation points to.
453 Symbol *Target = RelocTargets[I];
454 if (!Target || isa<DefinedAbsolute>(Target))
459 Symbol *target = file->getSymbol(rel.SymbolTableIndex);
460 if (!target || isa<DefinedAbsolute>(target))
455461 continue;
456 Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
462 res->emplace_back(rva + rel.VirtualAddress, ty);
457463 }
458464}
459465
......@@ -464,7 +470,7 @@ void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
464470// another DLL) This returns the size the relocation is supposed to update,
465471// in bits, or 0 if the relocation cannot be handled as a runtime pseudo
466472// relocation.
467static int getRuntimePseudoRelocSize(uint16_t Type) {
473static int getRuntimePseudoRelocSize(uint16_t type) {
468474 // Relocations that either contain an absolute address, or a plain
469475 // relative offset, since the runtime pseudo reloc implementation
470476 // adds 8/16/32/64 bit values to a memory address.
......@@ -490,9 +496,9 @@ static int getRuntimePseudoRelocSize(uint16_t Type) {
490496 // the image, or temporarily changed at runtime with VirtualProtect.
491497 // Since this only operates on direct address values, it doesn't work for
492498 // ARM/ARM64 relocations, other than the plain ADDR32/ADDR64 relocations.
493 switch (Config->Machine) {
499 switch (config->machine) {
494500 case AMD64:
495 switch (Type) {
501 switch (type) {
496502 case IMAGE_REL_AMD64_ADDR64:
497503 return 64;
498504 case IMAGE_REL_AMD64_ADDR32:
......@@ -507,7 +513,7 @@ static int getRuntimePseudoRelocSize(uint16_t Type) {
507513 return 0;
508514 }
509515 case I386:
510 switch (Type) {
516 switch (type) {
511517 case IMAGE_REL_I386_DIR32:
512518 case IMAGE_REL_I386_REL32:
513519 return 32;
......@@ -515,14 +521,14 @@ static int getRuntimePseudoRelocSize(uint16_t Type) {
515521 return 0;
516522 }
517523 case ARMNT:
518 switch (Type) {
524 switch (type) {
519525 case IMAGE_REL_ARM_ADDR32:
520526 return 32;
521527 default:
522528 return 0;
523529 }
524530 case ARM64:
525 switch (Type) {
531 switch (type) {
526532 case IMAGE_REL_ARM64_ADDR64:
527533 return 64;
528534 case IMAGE_REL_ARM64_ADDR32:
......@@ -541,75 +547,106 @@ static int getRuntimePseudoRelocSize(uint16_t Type) {
541547// to a module local variable, which turned out to actually need to be
542548// imported from another DLL).
543549void 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)
550 std::vector<RuntimePseudoReloc> &res) {
551 for (const coff_relocation &rel : getRelocs()) {
552 auto *target =
553 dyn_cast_or_null<Defined>(file->getSymbol(rel.SymbolTableIndex));
554 if (!target || !target->isRuntimePseudoReloc)
549555 continue;
550 int SizeInBits = getRuntimePseudoRelocSize(Rel.Type);
551 if (SizeInBits == 0) {
552 error("unable to automatically import from " + Target->getName() +
556 int sizeInBits = getRuntimePseudoRelocSize(rel.Type);
557 if (sizeInBits == 0) {
558 error("unable to automatically import from " + target->getName() +
553559 " with relocation type " +
554 File->getCOFFObj()->getRelocationTypeName(Rel.Type) + " in " +
555 toString(File));
560 file->getCOFFObj()->getRelocationTypeName(rel.Type) + " in " +
561 toString(file));
556562 continue;
557563 }
558 // SizeInBits is used to initialize the Flags field; currently no
564 // sizeInBits is used to initialize the Flags field; currently no
559565 // other flags are defined.
560 Res.emplace_back(
561 RuntimePseudoReloc(Target, this, Rel.VirtualAddress, SizeInBits));
566 res.emplace_back(
567 RuntimePseudoReloc(target, this, rel.VirtualAddress, sizeInBits));
562568 }
563569}
564570
565bool SectionChunk::hasData() const {
566 return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
567}
568
569uint32_t SectionChunk::getOutputCharacteristics() const {
570 return Header->Characteristics & (PermMask | TypeMask);
571}
572
573571bool SectionChunk::isCOMDAT() const {
574 return Header->Characteristics & IMAGE_SCN_LNK_COMDAT;
572 return header->Characteristics & IMAGE_SCN_LNK_COMDAT;
575573}
576574
577575void SectionChunk::printDiscardedMessage() const {
578576 // Removed by dead-stripping. If it's removed by ICF, ICF already
579577 // printed out the name, so don't repeat that here.
580 if (Sym && this == Repl)
581 message("Discarded " + Sym->getName());
578 if (sym && this == repl)
579 message("Discarded " + sym->getName());
582580}
583581
584StringRef SectionChunk::getDebugName() {
585 if (Sym)
586 return Sym->getName();
582StringRef SectionChunk::getDebugName() const {
583 if (sym)
584 return sym->getName();
587585 return "";
588586}
589587
590588ArrayRef<uint8_t> SectionChunk::getContents() const {
591 ArrayRef<uint8_t> A;
592 File->getCOFFObj()->getSectionContents(Header, A);
593 return A;
589 ArrayRef<uint8_t> a;
590 cantFail(file->getCOFFObj()->getSectionContents(header, a));
591 return a;
594592}
595593
596void SectionChunk::replace(SectionChunk *Other) {
597 Alignment = std::max(Alignment, Other->Alignment);
598 Other->Repl = Repl;
599 Other->Live = false;
594ArrayRef<uint8_t> SectionChunk::consumeDebugMagic() {
595 assert(isCodeView());
596 return consumeDebugMagic(getContents(), getSectionName());
597}
598
599ArrayRef<uint8_t> SectionChunk::consumeDebugMagic(ArrayRef<uint8_t> data,
600 StringRef sectionName) {
601 if (data.empty())
602 return {};
603
604 // First 4 bytes are section magic.
605 if (data.size() < 4)
606 fatal("the section is too short: " + sectionName);
607
608 if (!sectionName.startswith(".debug$"))
609 fatal("invalid section: " + sectionName);
610
611 uint32_t magic = support::endian::read32le(data.data());
612 uint32_t expectedMagic = sectionName == ".debug$H"
613 ? DEBUG_HASHES_SECTION_MAGIC
614 : DEBUG_SECTION_MAGIC;
615 if (magic != expectedMagic) {
616 warn("ignoring section " + sectionName + " with unrecognized magic 0x" +
617 utohexstr(magic));
618 return {};
619 }
620 return data.slice(4);
621}
622
623SectionChunk *SectionChunk::findByName(ArrayRef<SectionChunk *> sections,
624 StringRef name) {
625 for (SectionChunk *c : sections)
626 if (c->getSectionName() == name)
627 return c;
628 return nullptr;
629}
630
631void SectionChunk::replace(SectionChunk *other) {
632 p2Align = std::max(p2Align, other->p2Align);
633 other->repl = repl;
634 other->live = false;
600635}
601636
602637uint32_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;
638 DataRefImpl r;
639 r.p = reinterpret_cast<uintptr_t>(header);
640 SectionRef s(r, file->getCOFFObj());
641 return s.getIndex() + 1;
607642}
608643
609CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
610 // Common symbols are aligned on natural boundaries up to 32 bytes.
644CommonChunk::CommonChunk(const COFFSymbolRef s) : sym(s) {
645 // The value of a common symbol is its size. Align all common symbols smaller
646 // than 32 bytes naturally, i.e. round the size up to the next power of two.
611647 // This is what MSVC link.exe does.
612 Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
648 setAlignment(std::min(32U, uint32_t(PowerOf2Ceil(sym.getValue()))));
649 hasData = false;
613650}
614651
615652uint32_t CommonChunk::getOutputCharacteristics() const {
......@@ -617,139 +654,139 @@ uint32_t CommonChunk::getOutputCharacteristics() const {
617654 IMAGE_SCN_MEM_WRITE;
618655}
619656
620void StringChunk::writeTo(uint8_t *Buf) const {
621 memcpy(Buf + OutputSectionOff, Str.data(), Str.size());
622 Buf[OutputSectionOff + Str.size()] = '\0';
657void StringChunk::writeTo(uint8_t *buf) const {
658 memcpy(buf, str.data(), str.size());
659 buf[str.size()] = '\0';
623660}
624661
625ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
662ImportThunkChunkX64::ImportThunkChunkX64(Defined *s) : ImportThunkChunk(s) {
626663 // Intel Optimization Manual says that all branch targets
627664 // should be 16-byte aligned. MSVC linker does this too.
628 Alignment = 16;
665 setAlignment(16);
629666}
630667
631void ImportThunkChunkX64::writeTo(uint8_t *Buf) const {
632 memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
668void ImportThunkChunkX64::writeTo(uint8_t *buf) const {
669 memcpy(buf, importThunkX86, sizeof(importThunkX86));
633670 // The first two bytes is a JMP instruction. Fill its operand.
634 write32le(Buf + OutputSectionOff + 2, ImpSymbol->getRVA() - RVA - getSize());
671 write32le(buf + 2, impSymbol->getRVA() - rva - getSize());
635672}
636673
637void ImportThunkChunkX86::getBaserels(std::vector<Baserel> *Res) {
638 Res->emplace_back(getRVA() + 2);
674void ImportThunkChunkX86::getBaserels(std::vector<Baserel> *res) {
675 res->emplace_back(getRVA() + 2);
639676}
640677
641void ImportThunkChunkX86::writeTo(uint8_t *Buf) const {
642 memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
678void ImportThunkChunkX86::writeTo(uint8_t *buf) const {
679 memcpy(buf, importThunkX86, sizeof(importThunkX86));
643680 // The first two bytes is a JMP instruction. Fill its operand.
644 write32le(Buf + OutputSectionOff + 2,
645 ImpSymbol->getRVA() + Config->ImageBase);
681 write32le(buf + 2,
682 impSymbol->getRVA() + config->imageBase);
646683}
647684
648void ImportThunkChunkARM::getBaserels(std::vector<Baserel> *Res) {
649 Res->emplace_back(getRVA(), IMAGE_REL_BASED_ARM_MOV32T);
685void ImportThunkChunkARM::getBaserels(std::vector<Baserel> *res) {
686 res->emplace_back(getRVA(), IMAGE_REL_BASED_ARM_MOV32T);
650687}
651688
652void ImportThunkChunkARM::writeTo(uint8_t *Buf) const {
653 memcpy(Buf + OutputSectionOff, ImportThunkARM, sizeof(ImportThunkARM));
689void ImportThunkChunkARM::writeTo(uint8_t *buf) const {
690 memcpy(buf, importThunkARM, sizeof(importThunkARM));
654691 // Fix mov.w and mov.t operands.
655 applyMOV32T(Buf + OutputSectionOff, ImpSymbol->getRVA() + Config->ImageBase);
692 applyMOV32T(buf, impSymbol->getRVA() + config->imageBase);
656693}
657694
658void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {
659 int64_t Off = ImpSymbol->getRVA() & 0xfff;
660 memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64));
661 applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA, 12);
662 applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
695void ImportThunkChunkARM64::writeTo(uint8_t *buf) const {
696 int64_t off = impSymbol->getRVA() & 0xfff;
697 memcpy(buf, importThunkARM64, sizeof(importThunkARM64));
698 applyArm64Addr(buf, impSymbol->getRVA(), rva, 12);
699 applyArm64Ldr(buf + 4, off);
663700}
664701
665702// A Thumb2, PIC, non-interworking range extension thunk.
666const uint8_t ArmThunk[] = {
703const uint8_t armThunk[] = {
667704 0x40, 0xf2, 0x00, 0x0c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
668705 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)
669706 0xe7, 0x44, // L1: add pc, ip
670707};
671708
672709size_t RangeExtensionThunkARM::getSize() const {
673 assert(Config->Machine == ARMNT);
674 return sizeof(ArmThunk);
710 assert(config->machine == ARMNT);
711 return sizeof(armThunk);
675712}
676713
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));
714void RangeExtensionThunkARM::writeTo(uint8_t *buf) const {
715 assert(config->machine == ARMNT);
716 uint64_t offset = target->getRVA() - rva - 12;
717 memcpy(buf, armThunk, sizeof(armThunk));
718 applyMOV32T(buf, uint32_t(offset));
682719}
683720
684721// A position independent ARM64 adrp+add thunk, with a maximum range of
685722// +/- 4 GB, which is enough for any PE-COFF.
686const uint8_t Arm64Thunk[] = {
723const uint8_t arm64Thunk[] = {
687724 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest
688725 0x10, 0x02, 0x00, 0x91, // add x16, x16, :lo12:Dest
689726 0x00, 0x02, 0x1f, 0xd6, // br x16
690727};
691728
692729size_t RangeExtensionThunkARM64::getSize() const {
693 assert(Config->Machine == ARM64);
694 return sizeof(Arm64Thunk);
730 assert(config->machine == ARM64);
731 return sizeof(arm64Thunk);
695732}
696733
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);
734void RangeExtensionThunkARM64::writeTo(uint8_t *buf) const {
735 assert(config->machine == ARM64);
736 memcpy(buf, arm64Thunk, sizeof(arm64Thunk));
737 applyArm64Addr(buf + 0, target->getRVA(), rva, 12);
738 applyArm64Imm(buf + 4, target->getRVA() & 0xfff, 0);
702739}
703740
704void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
705 Res->emplace_back(getRVA());
741void LocalImportChunk::getBaserels(std::vector<Baserel> *res) {
742 res->emplace_back(getRVA());
706743}
707744
708size_t LocalImportChunk::getSize() const { return Config->Wordsize; }
745size_t LocalImportChunk::getSize() const { return config->wordsize; }
709746
710void LocalImportChunk::writeTo(uint8_t *Buf) const {
711 if (Config->is64()) {
712 write64le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
747void LocalImportChunk::writeTo(uint8_t *buf) const {
748 if (config->is64()) {
749 write64le(buf, sym->getRVA() + config->imageBase);
713750 } else {
714 write32le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
751 write32le(buf, sym->getRVA() + config->imageBase);
715752 }
716753}
717754
718void RVATableChunk::writeTo(uint8_t *Buf) const {
719 ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
720 size_t Cnt = 0;
721 for (const ChunkAndOffset &CO : Syms)
722 Begin[Cnt++] = CO.InputChunk->getRVA() + CO.Offset;
723 std::sort(Begin, Begin + Cnt);
724 assert(std::unique(Begin, Begin + Cnt) == Begin + Cnt &&
755void RVATableChunk::writeTo(uint8_t *buf) const {
756 ulittle32_t *begin = reinterpret_cast<ulittle32_t *>(buf);
757 size_t cnt = 0;
758 for (const ChunkAndOffset &co : syms)
759 begin[cnt++] = co.inputChunk->getRVA() + co.offset;
760 std::sort(begin, begin + cnt);
761 assert(std::unique(begin, begin + cnt) == begin + cnt &&
725762 "RVA tables should be de-duplicated");
726763}
727764
728765// MinGW specific, for the "automatic import of variables from DLLs" feature.
729766size_t PseudoRelocTableChunk::getSize() const {
730 if (Relocs.empty())
767 if (relocs.empty())
731768 return 0;
732 return 12 + 12 * Relocs.size();
769 return 12 + 12 * relocs.size();
733770}
734771
735772// MinGW specific.
736void PseudoRelocTableChunk::writeTo(uint8_t *Buf) const {
737 if (Relocs.empty())
773void PseudoRelocTableChunk::writeTo(uint8_t *buf) const {
774 if (relocs.empty())
738775 return;
739776
740 ulittle32_t *Table = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
777 ulittle32_t *table = reinterpret_cast<ulittle32_t *>(buf);
741778 // This is the list header, to signal the runtime pseudo relocation v2
742779 // 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;
780 table[0] = 0;
781 table[1] = 0;
782 table[2] = 1;
783
784 size_t idx = 3;
785 for (const RuntimePseudoReloc &rpr : relocs) {
786 table[idx + 0] = rpr.sym->getRVA();
787 table[idx + 1] = rpr.target->getRVA() + rpr.targetOffset;
788 table[idx + 2] = rpr.flags;
789 idx += 3;
753790 }
754791}
755792
......@@ -792,26 +829,26 @@ void PseudoRelocTableChunk::writeTo(uint8_t *Buf) const {
792829//
793830// Usually we have a lot of relocations for each page, so the number of
794831// bytes for one .reloc entry is close to 2 bytes on average.
795BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) {
832BaserelChunk::BaserelChunk(uint32_t page, Baserel *begin, Baserel *end) {
796833 // Block header consists of 4 byte page RVA and 4 byte block size.
797834 // Each entry is 2 byte. Last entry may be padding.
798 Data.resize(alignTo((End - Begin) * 2 + 8, 4));
799 uint8_t *P = Data.data();
800 write32le(P, Page);
801 write32le(P + 4, Data.size());
802 P += 8;
803 for (Baserel *I = Begin; I != End; ++I) {
804 write16le(P, (I->Type << 12) | (I->RVA - Page));
805 P += 2;
835 data.resize(alignTo((end - begin) * 2 + 8, 4));
836 uint8_t *p = data.data();
837 write32le(p, page);
838 write32le(p + 4, data.size());
839 p += 8;
840 for (Baserel *i = begin; i != end; ++i) {
841 write16le(p, (i->type << 12) | (i->rva - page));
842 p += 2;
806843 }
807844}
808845
809void BaserelChunk::writeTo(uint8_t *Buf) const {
810 memcpy(Buf + OutputSectionOff, Data.data(), Data.size());
846void BaserelChunk::writeTo(uint8_t *buf) const {
847 memcpy(buf, data.data(), data.size());
811848}
812849
813850uint8_t Baserel::getDefaultType() {
814 switch (Config->Machine) {
851 switch (config->machine) {
815852 case AMD64:
816853 case ARM64:
817854 return IMAGE_REL_BASED_DIR64;
......@@ -823,36 +860,38 @@ uint8_t Baserel::getDefaultType() {
823860 }
824861}
825862
826std::map<uint32_t, MergeChunk *> MergeChunk::Instances;
863MergeChunk *MergeChunk::instances[Log2MaxSectionAlignment + 1] = {};
827864
828MergeChunk::MergeChunk(uint32_t Alignment)
829 : Builder(StringTableBuilder::RAW, Alignment) {
830 this->Alignment = Alignment;
865MergeChunk::MergeChunk(uint32_t alignment)
866 : builder(StringTableBuilder::RAW, alignment) {
867 setAlignment(alignment);
831868}
832869
833void MergeChunk::addSection(SectionChunk *C) {
834 auto *&MC = Instances[C->Alignment];
835 if (!MC)
836 MC = make<MergeChunk>(C->Alignment);
837 MC->Sections.push_back(C);
870void MergeChunk::addSection(SectionChunk *c) {
871 assert(isPowerOf2_32(c->getAlignment()));
872 uint8_t p2Align = llvm::Log2_32(c->getAlignment());
873 assert(p2Align < array_lengthof(instances));
874 auto *&mc = instances[p2Align];
875 if (!mc)
876 mc = make<MergeChunk>(c->getAlignment());
877 mc->sections.push_back(c);
838878}
839879
840880void MergeChunk::finalizeContents() {
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 }
881 assert(!finalized && "should only finalize once");
882 for (SectionChunk *c : sections)
883 if (c->live)
884 builder.add(toStringRef(c->getContents()));
885 builder.finalize();
886 finalized = true;
887}
848888
849 for (SectionChunk *C : Sections) {
850 if (!C->Live)
889void MergeChunk::assignSubsectionRVAs() {
890 for (SectionChunk *c : sections) {
891 if (!c->live)
851892 continue;
852 size_t Off = Builder.getOffset(toStringRef(C->getContents()));
853 C->setOutputSection(Out);
854 C->setRVA(RVA + Off);
855 C->OutputSectionOff = OutputSectionOff + Off;
893 size_t off = builder.getOffset(toStringRef(c->getContents()));
894 c->setRVA(rva + off);
856895 }
857896}
858897
......@@ -861,21 +900,21 @@ uint32_t MergeChunk::getOutputCharacteristics() const {
861900}
862901
863902size_t MergeChunk::getSize() const {
864 return Builder.getSize();
903 return builder.getSize();
865904}
866905
867void MergeChunk::writeTo(uint8_t *Buf) const {
868 Builder.write(Buf + OutputSectionOff);
906void MergeChunk::writeTo(uint8_t *buf) const {
907 builder.write(buf);
869908}
870909
871910// MinGW specific.
872size_t AbsolutePointerChunk::getSize() const { return Config->Wordsize; }
911size_t AbsolutePointerChunk::getSize() const { return config->wordsize; }
873912
874void AbsolutePointerChunk::writeTo(uint8_t *Buf) const {
875 if (Config->is64()) {
876 write64le(Buf + OutputSectionOff, Value);
913void AbsolutePointerChunk::writeTo(uint8_t *buf) const {
914 if (config->is64()) {
915 write64le(buf, value);
877916 } else {
878 write32le(Buf + OutputSectionOff, Value);
917 write32le(buf, value);
879918 }
880919}
881920
deps/lld/COFF/Chunks.h+368-209
......@@ -1,9 +1,8 @@
11//===- Chunks.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -14,6 +13,7 @@
1413#include "InputFiles.h"
1514#include "lld/Common/LLVM.h"
1615#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/PointerIntPair.h"
1717#include "llvm/ADT/iterator.h"
1818#include "llvm/ADT/iterator_range.h"
1919#include "llvm/MC/StringTableBuilder.h"
......@@ -40,10 +40,13 @@ class RuntimePseudoReloc;
4040class Symbol;
4141
4242// Mask for permissions (discardable, writable, readable, executable, etc).
43const uint32_t PermMask = 0xFE000000;
43const uint32_t permMask = 0xFE000000;
4444
4545// Mask for section types (code, data, bss).
46const uint32_t TypeMask = 0x000000E0;
46const uint32_t typeMask = 0x000000E0;
47
48// The log base 2 of the largest section alignment, which is log2(8192), or 13.
49enum : unsigned { Log2MaxSectionAlignment = 13 };
4750
4851// A Chunk represents a chunk of data that will occupy space in the
4952// output (if the resolver chose that). It may or may not be backed by
......@@ -51,81 +54,126 @@ const uint32_t TypeMask = 0x000000E0;
5154// doesn't even have actual data (if common or bss).
5255class Chunk {
5356public:
54 enum Kind { SectionKind, OtherKind };
55 Kind kind() const { return ChunkKind; }
56 virtual ~Chunk() = default;
57 enum Kind : uint8_t { SectionKind, OtherKind, ImportThunkKind };
58 Kind kind() const { return chunkKind; }
5759
5860 // Returns the size of this chunk (even if this is a common or BSS.)
59 virtual size_t getSize() const = 0;
61 size_t getSize() const;
62
63 // Returns chunk alignment in power of two form. Value values are powers of
64 // two from 1 to 8192.
65 uint32_t getAlignment() const { return 1U << p2Align; }
66
67 // Update the chunk section alignment measured in bytes. Internally alignment
68 // is stored in log2.
69 void setAlignment(uint32_t align) {
70 // Treat zero byte alignment as 1 byte alignment.
71 align = align ? align : 1;
72 assert(llvm::isPowerOf2_32(align) && "alignment is not a power of 2");
73 p2Align = llvm::Log2_32(align);
74 assert(p2Align <= Log2MaxSectionAlignment &&
75 "impossible requested alignment");
76 }
6077
6178 // Write this chunk to a mmap'ed file, assuming Buf is pointing to
6279 // beginning of the file. Because this function may use RVA values
6380 // of other chunks for relocations, you need to set them properly
6481 // before calling this function.
65 virtual void writeTo(uint8_t *Buf) const {}
82 void writeTo(uint8_t *buf) const;
83
84 // The writer sets and uses the addresses. In practice, PE images cannot be
85 // larger than 2GB. Chunks are always laid as part of the image, so Chunk RVAs
86 // can be stored with 32 bits.
87 uint32_t getRVA() const { return rva; }
88 void setRVA(uint64_t v) {
89 rva = (uint32_t)v;
90 assert(rva == v && "RVA truncated");
91 }
6692
67 // Called by the writer once before assigning addresses and writing
68 // the output.
69 virtual void readRelocTargets() {}
93 // Returns readable/writable/executable bits.
94 uint32_t getOutputCharacteristics() const;
7095
71 // Called if restarting thunk addition.
72 virtual void resetRelocTargets() {}
96 // Returns the section name if this is a section chunk.
97 // It is illegal to call this function on non-section chunks.
98 StringRef getSectionName() const;
7399
74 // Called by the writer after an RVA is assigned, but before calling
75 // getSize().
76 virtual void finalizeContents() {}
100 // An output section has pointers to chunks in the section, and each
101 // chunk has a back pointer to an output section.
102 void setOutputSectionIdx(uint16_t o) { osidx = o; }
103 uint16_t getOutputSectionIdx() const { return osidx; }
104 OutputSection *getOutputSection() const;
77105
78 // The writer sets and uses the addresses.
79 uint64_t getRVA() const { return RVA; }
80 void setRVA(uint64_t V) { RVA = V; }
106 // Windows-specific.
107 // Collect all locations that contain absolute addresses for base relocations.
108 void getBaserels(std::vector<Baserel> *res);
81109
110 // Returns a human-readable name of this chunk. Chunks are unnamed chunks of
111 // bytes, so this is used only for logging or debugging.
112 StringRef getDebugName() const;
113
114 // Return true if this file has the hotpatch flag set to true in the
115 // S_COMPILE3 record in codeview debug info. Also returns true for some thunks
116 // synthesized by the linker.
117 bool isHotPatchable() const;
118
119protected:
120 Chunk(Kind k = OtherKind) : chunkKind(k), hasData(true), p2Align(0) {}
121
122 const Kind chunkKind;
123
124public:
82125 // Returns true if this has non-zero data. BSS chunks return
83126 // false. If false is returned, the space occupied by this chunk
84 // will be filled with zeros.
85 virtual bool hasData() const { return true; }
127 // will be filled with zeros. Corresponds to the
128 // IMAGE_SCN_CNT_UNINITIALIZED_DATA section characteristic bit.
129 uint8_t hasData : 1;
130
131public:
132 // The alignment of this chunk, stored in log2 form. The writer uses the
133 // value.
134 uint8_t p2Align : 7;
135
136 // The output section index for this chunk. The first valid section number is
137 // one.
138 uint16_t osidx = 0;
139
140 // The RVA of this chunk in the output. The writer sets a value.
141 uint32_t rva = 0;
142};
143
144class NonSectionChunk : public Chunk {
145public:
146 virtual ~NonSectionChunk() = default;
147
148 // Returns the size of this chunk (even if this is a common or BSS.)
149 virtual size_t getSize() const = 0;
86150
87 // Returns readable/writable/executable bits.
88151 virtual uint32_t getOutputCharacteristics() const { return 0; }
89152
153 // Write this chunk to a mmap'ed file, assuming Buf is pointing to
154 // beginning of the file. Because this function may use RVA values
155 // of other chunks for relocations, you need to set them properly
156 // before calling this function.
157 virtual void writeTo(uint8_t *buf) const {}
158
90159 // Returns the section name if this is a section chunk.
91160 // It is illegal to call this function on non-section chunks.
92161 virtual StringRef getSectionName() const {
93162 llvm_unreachable("unimplemented getSectionName");
94163 }
95164
96 // An output section has pointers to chunks in the section, and each
97 // chunk has a back pointer to an output section.
98 void setOutputSection(OutputSection *O) { Out = O; }
99 OutputSection *getOutputSection() const { return Out; }
100
101165 // Windows-specific.
102166 // Collect all locations that contain absolute addresses for base relocations.
103 virtual void getBaserels(std::vector<Baserel> *Res) {}
167 virtual void getBaserels(std::vector<Baserel> *res) {}
104168
105169 // Returns a human-readable name of this chunk. Chunks are unnamed chunks of
106170 // bytes, so this is used only for logging or debugging.
107 virtual StringRef getDebugName() { return ""; }
171 virtual StringRef getDebugName() const { return ""; }
108172
109 // The alignment of this chunk. The writer uses the value.
110 uint32_t Alignment = 1;
173 static bool classof(const Chunk *c) { return c->kind() != SectionKind; }
111174
112175protected:
113 Chunk(Kind K = OtherKind) : ChunkKind(K) {}
114 const Kind ChunkKind;
115
116 // The RVA of this chunk in the output. The writer sets a value.
117 uint64_t RVA = 0;
118
119 // The output section for this chunk.
120 OutputSection *Out = nullptr;
121
122public:
123 // The offset from beginning of the output section. The writer sets a value.
124 uint64_t OutputSectionOff = 0;
125
126 // Whether this section needs to be kept distinct from other sections during
127 // ICF. This is set by the driver using address-significance tables.
128 bool KeepUnique = false;
176 NonSectionChunk(Kind k = OtherKind) : Chunk(k) {}
129177};
130178
131179// A chunk corresponding a section of an input file.
......@@ -139,39 +187,41 @@ public:
139187 std::random_access_iterator_tag, Symbol *> {
140188 friend SectionChunk;
141189
142 ObjFile *File;
190 ObjFile *file;
143191
144 symbol_iterator(ObjFile *File, const coff_relocation *I)
145 : symbol_iterator::iterator_adaptor_base(I), File(File) {}
192 symbol_iterator(ObjFile *file, const coff_relocation *i)
193 : symbol_iterator::iterator_adaptor_base(i), file(file) {}
146194
147195 public:
148196 symbol_iterator() = default;
149197
150 Symbol *operator*() const { return File->getSymbol(I->SymbolTableIndex); }
198 Symbol *operator*() const { return file->getSymbol(I->SymbolTableIndex); }
151199 };
152200
153 SectionChunk(ObjFile *File, const coff_section *Header);
154 static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
155 void readRelocTargets() override;
156 void resetRelocTargets() override;
157 size_t getSize() const override { return Header->SizeOfRawData; }
201 SectionChunk(ObjFile *file, const coff_section *header);
202 static bool classof(const Chunk *c) { return c->kind() == SectionKind; }
203 size_t getSize() const { return header->SizeOfRawData; }
158204 ArrayRef<uint8_t> getContents() const;
159 void writeTo(uint8_t *Buf) const override;
160 bool hasData() const override;
161 uint32_t getOutputCharacteristics() const override;
162 StringRef getSectionName() const override { return SectionName; }
163 void getBaserels(std::vector<Baserel> *Res) override;
205 void writeTo(uint8_t *buf) const;
206
207 uint32_t getOutputCharacteristics() const {
208 return header->Characteristics & (permMask | typeMask);
209 }
210 StringRef getSectionName() const {
211 return StringRef(sectionNameData, sectionNameSize);
212 }
213 void getBaserels(std::vector<Baserel> *res);
164214 bool isCOMDAT() const;
165 void applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
166 uint64_t P) const;
167 void applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
168 uint64_t P) const;
169 void applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
170 uint64_t P) const;
171 void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
172 uint64_t P) const;
215 void applyRelX64(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s,
216 uint64_t p) const;
217 void applyRelX86(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s,
218 uint64_t p) const;
219 void applyRelARM(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s,
220 uint64_t p) const;
221 void applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s,
222 uint64_t p) const;
173223
174 void getRuntimePseudoRelocs(std::vector<RuntimePseudoReloc> &Res);
224 void getRuntimePseudoRelocs(std::vector<RuntimePseudoReloc> &res);
175225
176226 // Called if the garbage collector decides to not include this chunk
177227 // in a final output. It's supposed to print out a log message to stdout.
......@@ -179,69 +229,169 @@ public:
179229
180230 // Adds COMDAT associative sections to this COMDAT section. A chunk
181231 // and its children are treated as a group by the garbage collector.
182 void addAssociative(SectionChunk *Child);
232 void addAssociative(SectionChunk *child);
183233
184 StringRef getDebugName() override;
234 StringRef getDebugName() const;
185235
186236 // True if this is a codeview debug info chunk. These will not be laid out in
187237 // the image. Instead they will end up in the PDB, if one is requested.
188238 bool isCodeView() const {
189 return SectionName == ".debug" || SectionName.startswith(".debug$");
239 return getSectionName() == ".debug" || getSectionName().startswith(".debug$");
190240 }
191241
192242 // True if this is a DWARF debug info or exception handling chunk.
193243 bool isDWARF() const {
194 return SectionName.startswith(".debug_") || SectionName == ".eh_frame";
244 return getSectionName().startswith(".debug_") || getSectionName() == ".eh_frame";
195245 }
196246
197247 // Allow iteration over the bodies of this chunk's relocated symbols.
198248 llvm::iterator_range<symbol_iterator> symbols() const {
199 return llvm::make_range(symbol_iterator(File, Relocs.begin()),
200 symbol_iterator(File, Relocs.end()));
249 return llvm::make_range(symbol_iterator(file, relocsData),
250 symbol_iterator(file, relocsData + relocsSize));
251 }
252
253 ArrayRef<coff_relocation> getRelocs() const {
254 return llvm::makeArrayRef(relocsData, relocsSize);
201255 }
202256
257 // Reloc setter used by ARM range extension thunk insertion.
258 void setRelocs(ArrayRef<coff_relocation> newRelocs) {
259 relocsData = newRelocs.data();
260 relocsSize = newRelocs.size();
261 assert(relocsSize == newRelocs.size() && "reloc size truncation");
262 }
263
264 // Single linked list iterator for associated comdat children.
265 class AssociatedIterator
266 : public llvm::iterator_facade_base<
267 AssociatedIterator, std::forward_iterator_tag, SectionChunk> {
268 public:
269 AssociatedIterator() = default;
270 AssociatedIterator(SectionChunk *head) : cur(head) {}
271 AssociatedIterator &operator=(const AssociatedIterator &r) {
272 cur = r.cur;
273 return *this;
274 }
275 bool operator==(const AssociatedIterator &r) const { return cur == r.cur; }
276 const SectionChunk &operator*() const { return *cur; }
277 SectionChunk &operator*() { return *cur; }
278 AssociatedIterator &operator++() {
279 cur = cur->assocChildren;
280 return *this;
281 }
282
283 private:
284 SectionChunk *cur = nullptr;
285 };
286
203287 // Allow iteration over the associated child chunks for this section.
204 ArrayRef<SectionChunk *> children() const { return AssocChildren; }
288 llvm::iterator_range<AssociatedIterator> children() const {
289 return llvm::make_range(AssociatedIterator(assocChildren),
290 AssociatedIterator(nullptr));
291 }
205292
206293 // The section ID this chunk belongs to in its Obj.
207294 uint32_t getSectionNumber() const;
208295
209 // A pointer pointing to a replacement for this chunk.
210 // Initially it points to "this" object. If this chunk is merged
211 // with other chunk by ICF, it points to another chunk,
212 // and this chunk is considered as dead.
213 SectionChunk *Repl;
296 ArrayRef<uint8_t> consumeDebugMagic();
214297
215 // The CRC of the contents as described in the COFF spec 4.5.5.
216 // Auxiliary Format 5: Section Definitions. Used for ICF.
217 uint32_t Checksum = 0;
298 static ArrayRef<uint8_t> consumeDebugMagic(ArrayRef<uint8_t> data,
299 StringRef sectionName);
218300
219 const coff_section *Header;
301 static SectionChunk *findByName(ArrayRef<SectionChunk *> sections,
302 StringRef name);
220303
221304 // The file that this chunk was created from.
222 ObjFile *File;
305 ObjFile *file;
306
307 // Pointer to the COFF section header in the input file.
308 const coff_section *header;
223309
224310 // The COMDAT leader symbol if this is a COMDAT chunk.
225 DefinedRegular *Sym = nullptr;
311 DefinedRegular *sym = nullptr;
226312
227 ArrayRef<coff_relocation> Relocs;
313 // The CRC of the contents as described in the COFF spec 4.5.5.
314 // Auxiliary Format 5: Section Definitions. Used for ICF.
315 uint32_t checksum = 0;
228316
229317 // Used by the garbage collector.
230 bool Live;
318 bool live;
319
320 // Whether this section needs to be kept distinct from other sections during
321 // ICF. This is set by the driver using address-significance tables.
322 bool keepUnique = false;
231323
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;
324 // The COMDAT selection if this is a COMDAT chunk.
325 llvm::COFF::COMDATType selection = (llvm::COFF::COMDATType)0;
326
327 // A pointer pointing to a replacement for this chunk.
328 // Initially it points to "this" object. If this chunk is merged
329 // with other chunk by ICF, it points to another chunk,
330 // and this chunk is considered as dead.
331 SectionChunk *repl;
235332
236333private:
237 StringRef SectionName;
238 std::vector<SectionChunk *> AssocChildren;
334 SectionChunk *assocChildren = nullptr;
239335
240336 // Used for ICF (Identical COMDAT Folding)
241 void replace(SectionChunk *Other);
242 uint32_t Class[2] = {0, 0};
337 void replace(SectionChunk *other);
338 uint32_t eqClass[2] = {0, 0};
339
340 // Relocations for this section. Size is stored below.
341 const coff_relocation *relocsData;
342
343 // Section name string. Size is stored below.
344 const char *sectionNameData;
345
346 uint32_t relocsSize = 0;
347 uint32_t sectionNameSize = 0;
243348};
244349
350// Inline methods to implement faux-virtual dispatch for SectionChunk.
351
352inline size_t Chunk::getSize() const {
353 if (isa<SectionChunk>(this))
354 return static_cast<const SectionChunk *>(this)->getSize();
355 else
356 return static_cast<const NonSectionChunk *>(this)->getSize();
357}
358
359inline uint32_t Chunk::getOutputCharacteristics() const {
360 if (isa<SectionChunk>(this))
361 return static_cast<const SectionChunk *>(this)->getOutputCharacteristics();
362 else
363 return static_cast<const NonSectionChunk *>(this)
364 ->getOutputCharacteristics();
365}
366
367inline void Chunk::writeTo(uint8_t *buf) const {
368 if (isa<SectionChunk>(this))
369 static_cast<const SectionChunk *>(this)->writeTo(buf);
370 else
371 static_cast<const NonSectionChunk *>(this)->writeTo(buf);
372}
373
374inline StringRef Chunk::getSectionName() const {
375 if (isa<SectionChunk>(this))
376 return static_cast<const SectionChunk *>(this)->getSectionName();
377 else
378 return static_cast<const NonSectionChunk *>(this)->getSectionName();
379}
380
381inline void Chunk::getBaserels(std::vector<Baserel> *res) {
382 if (isa<SectionChunk>(this))
383 static_cast<SectionChunk *>(this)->getBaserels(res);
384 else
385 static_cast<NonSectionChunk *>(this)->getBaserels(res);
386}
387
388inline StringRef Chunk::getDebugName() const {
389 if (isa<SectionChunk>(this))
390 return static_cast<const SectionChunk *>(this)->getDebugName();
391 else
392 return static_cast<const NonSectionChunk *>(this)->getDebugName();
393}
394
245395// This class is used to implement an lld-specific feature (not implemented in
246396// MSVC) that minimizes the output size by finding string literals sharing tail
247397// parts and merging them.
......@@ -251,60 +401,60 @@ private:
251401// The MergeChunk then tail merges the strings using the StringTableBuilder
252402// class and assigns RVAs and section offsets to each of the member chunks based
253403// on the offsets assigned by the StringTableBuilder.
254class MergeChunk : public Chunk {
404class MergeChunk : public NonSectionChunk {
255405public:
256 MergeChunk(uint32_t Alignment);
257 static void addSection(SectionChunk *C);
258 void finalizeContents() override;
406 MergeChunk(uint32_t alignment);
407 static void addSection(SectionChunk *c);
408 void finalizeContents();
409 void assignSubsectionRVAs();
259410
260411 uint32_t getOutputCharacteristics() const override;
261412 StringRef getSectionName() const override { return ".rdata"; }
262413 size_t getSize() const override;
263 void writeTo(uint8_t *Buf) const override;
414 void writeTo(uint8_t *buf) const override;
264415
265 static std::map<uint32_t, MergeChunk *> Instances;
266 std::vector<SectionChunk *> Sections;
416 static MergeChunk *instances[Log2MaxSectionAlignment + 1];
417 std::vector<SectionChunk *> sections;
267418
268419private:
269 llvm::StringTableBuilder Builder;
270 bool Finalized = false;
420 llvm::StringTableBuilder builder;
421 bool finalized = false;
271422};
272423
273424// A chunk for common symbols. Common chunks don't have actual data.
274class CommonChunk : public Chunk {
425class CommonChunk : public NonSectionChunk {
275426public:
276 CommonChunk(const COFFSymbolRef Sym);
277 size_t getSize() const override { return Sym.getValue(); }
278 bool hasData() const override { return false; }
427 CommonChunk(const COFFSymbolRef sym);
428 size_t getSize() const override { return sym.getValue(); }
279429 uint32_t getOutputCharacteristics() const override;
280430 StringRef getSectionName() const override { return ".bss"; }
281431
282432private:
283 const COFFSymbolRef Sym;
433 const COFFSymbolRef sym;
284434};
285435
286436// A chunk for linker-created strings.
287class StringChunk : public Chunk {
437class StringChunk : public NonSectionChunk {
288438public:
289 explicit StringChunk(StringRef S) : Str(S) {}
290 size_t getSize() const override { return Str.size() + 1; }
291 void writeTo(uint8_t *Buf) const override;
439 explicit StringChunk(StringRef s) : str(s) {}
440 size_t getSize() const override { return str.size() + 1; }
441 void writeTo(uint8_t *buf) const override;
292442
293443private:
294 StringRef Str;
444 StringRef str;
295445};
296446
297static const uint8_t ImportThunkX86[] = {
447static const uint8_t importThunkX86[] = {
298448 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP *0x0
299449};
300450
301static const uint8_t ImportThunkARM[] = {
451static const uint8_t importThunkARM[] = {
302452 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0
303453 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0
304454 0xdc, 0xf8, 0x00, 0xf0, // ldr.w pc, [ip]
305455};
306456
307static const uint8_t ImportThunkARM64[] = {
457static const uint8_t importThunkARM64[] = {
308458 0x10, 0x00, 0x00, 0x90, // adrp x16, #0
309459 0x10, 0x02, 0x40, 0xf9, // ldr x16, [x16]
310460 0x00, 0x02, 0x1f, 0xd6, // br x16
......@@ -313,87 +463,85 @@ static const uint8_t ImportThunkARM64[] = {
313463// Windows-specific.
314464// A chunk for DLL import jump table entry. In a final output, its
315465// contents will be a JMP instruction to some __imp_ symbol.
316class ImportThunkChunkX64 : public Chunk {
466class ImportThunkChunk : public NonSectionChunk {
317467public:
318 explicit ImportThunkChunkX64(Defined *S);
319 size_t getSize() const override { return sizeof(ImportThunkX86); }
320 void writeTo(uint8_t *Buf) const override;
468 ImportThunkChunk(Defined *s)
469 : NonSectionChunk(ImportThunkKind), impSymbol(s) {}
470 static bool classof(const Chunk *c) { return c->kind() == ImportThunkKind; }
321471
322private:
323 Defined *ImpSymbol;
472protected:
473 Defined *impSymbol;
324474};
325475
326class ImportThunkChunkX86 : public Chunk {
476class ImportThunkChunkX64 : public ImportThunkChunk {
327477public:
328 explicit ImportThunkChunkX86(Defined *S) : ImpSymbol(S) {}
329 size_t getSize() const override { return sizeof(ImportThunkX86); }
330 void getBaserels(std::vector<Baserel> *Res) override;
331 void writeTo(uint8_t *Buf) const override;
332
333private:
334 Defined *ImpSymbol;
478 explicit ImportThunkChunkX64(Defined *s);
479 size_t getSize() const override { return sizeof(importThunkX86); }
480 void writeTo(uint8_t *buf) const override;
335481};
336482
337class ImportThunkChunkARM : public Chunk {
483class ImportThunkChunkX86 : public ImportThunkChunk {
338484public:
339 explicit ImportThunkChunkARM(Defined *S) : ImpSymbol(S) {}
340 size_t getSize() const override { return sizeof(ImportThunkARM); }
341 void getBaserels(std::vector<Baserel> *Res) override;
342 void writeTo(uint8_t *Buf) const override;
343
344private:
345 Defined *ImpSymbol;
485 explicit ImportThunkChunkX86(Defined *s) : ImportThunkChunk(s) {}
486 size_t getSize() const override { return sizeof(importThunkX86); }
487 void getBaserels(std::vector<Baserel> *res) override;
488 void writeTo(uint8_t *buf) const override;
346489};
347490
348class ImportThunkChunkARM64 : public Chunk {
491class ImportThunkChunkARM : public ImportThunkChunk {
349492public:
350 explicit ImportThunkChunkARM64(Defined *S) : ImpSymbol(S) {}
351 size_t getSize() const override { return sizeof(ImportThunkARM64); }
352 void writeTo(uint8_t *Buf) const override;
493 explicit ImportThunkChunkARM(Defined *s) : ImportThunkChunk(s) {}
494 size_t getSize() const override { return sizeof(importThunkARM); }
495 void getBaserels(std::vector<Baserel> *res) override;
496 void writeTo(uint8_t *buf) const override;
497};
353498
354private:
355 Defined *ImpSymbol;
499class ImportThunkChunkARM64 : public ImportThunkChunk {
500public:
501 explicit ImportThunkChunkARM64(Defined *s) : ImportThunkChunk(s) {}
502 size_t getSize() const override { return sizeof(importThunkARM64); }
503 void writeTo(uint8_t *buf) const override;
356504};
357505
358class RangeExtensionThunkARM : public Chunk {
506class RangeExtensionThunkARM : public NonSectionChunk {
359507public:
360 explicit RangeExtensionThunkARM(Defined *T) : Target(T) {}
508 explicit RangeExtensionThunkARM(Defined *t) : target(t) {}
361509 size_t getSize() const override;
362 void writeTo(uint8_t *Buf) const override;
510 void writeTo(uint8_t *buf) const override;
363511
364 Defined *Target;
512 Defined *target;
365513};
366514
367class RangeExtensionThunkARM64 : public Chunk {
515class RangeExtensionThunkARM64 : public NonSectionChunk {
368516public:
369 explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {}
517 explicit RangeExtensionThunkARM64(Defined *t) : target(t) {}
370518 size_t getSize() const override;
371 void writeTo(uint8_t *Buf) const override;
519 void writeTo(uint8_t *buf) const override;
372520
373 Defined *Target;
521 Defined *target;
374522};
375523
376524// Windows-specific.
377525// See comments for DefinedLocalImport class.
378class LocalImportChunk : public Chunk {
526class LocalImportChunk : public NonSectionChunk {
379527public:
380 explicit LocalImportChunk(Defined *S) : Sym(S) {
381 Alignment = Config->Wordsize;
528 explicit LocalImportChunk(Defined *s) : sym(s) {
529 setAlignment(config->wordsize);
382530 }
383531 size_t getSize() const override;
384 void getBaserels(std::vector<Baserel> *Res) override;
385 void writeTo(uint8_t *Buf) const override;
532 void getBaserels(std::vector<Baserel> *res) override;
533 void writeTo(uint8_t *buf) const override;
386534
387535private:
388 Defined *Sym;
536 Defined *sym;
389537};
390538
391539// Duplicate RVAs are not allowed in RVA tables, so unique symbols by chunk and
392540// offset into the chunk. Order does not matter as the RVA table will be sorted
393541// later.
394542struct ChunkAndOffset {
395 Chunk *InputChunk;
396 uint32_t Offset;
543 Chunk *inputChunk;
544 uint32_t offset;
397545
398546 struct DenseMapInfo {
399547 static ChunkAndOffset getEmptyKey() {
......@@ -402,12 +550,12 @@ struct ChunkAndOffset {
402550 static ChunkAndOffset getTombstoneKey() {
403551 return {llvm::DenseMapInfo<Chunk *>::getTombstoneKey(), 0};
404552 }
405 static unsigned getHashValue(const ChunkAndOffset &CO) {
553 static unsigned getHashValue(const ChunkAndOffset &co) {
406554 return llvm::DenseMapInfo<std::pair<Chunk *, uint32_t>>::getHashValue(
407 {CO.InputChunk, CO.Offset});
555 {co.inputChunk, co.offset});
408556 }
409 static bool isEqual(const ChunkAndOffset &LHS, const ChunkAndOffset &RHS) {
410 return LHS.InputChunk == RHS.InputChunk && LHS.Offset == RHS.Offset;
557 static bool isEqual(const ChunkAndOffset &lhs, const ChunkAndOffset &rhs) {
558 return lhs.inputChunk == rhs.inputChunk && lhs.offset == rhs.offset;
411559 }
412560 };
413561};
......@@ -415,48 +563,48 @@ struct ChunkAndOffset {
415563using SymbolRVASet = llvm::DenseSet<ChunkAndOffset>;
416564
417565// Table which contains symbol RVAs. Used for /safeseh and /guard:cf.
418class RVATableChunk : public Chunk {
566class RVATableChunk : public NonSectionChunk {
419567public:
420 explicit RVATableChunk(SymbolRVASet S) : Syms(std::move(S)) {}
421 size_t getSize() const override { return Syms.size() * 4; }
422 void writeTo(uint8_t *Buf) const override;
568 explicit RVATableChunk(SymbolRVASet s) : syms(std::move(s)) {}
569 size_t getSize() const override { return syms.size() * 4; }
570 void writeTo(uint8_t *buf) const override;
423571
424572private:
425 SymbolRVASet Syms;
573 SymbolRVASet syms;
426574};
427575
428576// Windows-specific.
429577// This class represents a block in .reloc section.
430578// See the PE/COFF spec 5.6 for details.
431class BaserelChunk : public Chunk {
579class BaserelChunk : public NonSectionChunk {
432580public:
433 BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End);
434 size_t getSize() const override { return Data.size(); }
435 void writeTo(uint8_t *Buf) const override;
581 BaserelChunk(uint32_t page, Baserel *begin, Baserel *end);
582 size_t getSize() const override { return data.size(); }
583 void writeTo(uint8_t *buf) const override;
436584
437585private:
438 std::vector<uint8_t> Data;
586 std::vector<uint8_t> data;
439587};
440588
441589class Baserel {
442590public:
443 Baserel(uint32_t V, uint8_t Ty) : RVA(V), Type(Ty) {}
444 explicit Baserel(uint32_t V) : Baserel(V, getDefaultType()) {}
591 Baserel(uint32_t v, uint8_t ty) : rva(v), type(ty) {}
592 explicit Baserel(uint32_t v) : Baserel(v, getDefaultType()) {}
445593 uint8_t getDefaultType();
446594
447 uint32_t RVA;
448 uint8_t Type;
595 uint32_t rva;
596 uint8_t type;
449597};
450598
451599// This is a placeholder Chunk, to allow attaching a DefinedSynthetic to a
452600// specific place in a section, without any data. This is used for the MinGW
453601// specific symbol __RUNTIME_PSEUDO_RELOC_LIST_END__, even though the concept
454602// of an empty chunk isn't MinGW specific.
455class EmptyChunk : public Chunk {
603class EmptyChunk : public NonSectionChunk {
456604public:
457605 EmptyChunk() {}
458606 size_t getSize() const override { return 0; }
459 void writeTo(uint8_t *Buf) const override {}
607 void writeTo(uint8_t *buf) const override {}
460608};
461609
462610// MinGW specific, for the "automatic import of variables from DLLs" feature.
......@@ -465,17 +613,17 @@ public:
465613// the reference didn't use the dllimport attribute. The MinGW runtime will
466614// process this table after loading, before handling control over to user
467615// code.
468class PseudoRelocTableChunk : public Chunk {
616class PseudoRelocTableChunk : public NonSectionChunk {
469617public:
470 PseudoRelocTableChunk(std::vector<RuntimePseudoReloc> &Relocs)
471 : Relocs(std::move(Relocs)) {
472 Alignment = 4;
618 PseudoRelocTableChunk(std::vector<RuntimePseudoReloc> &relocs)
619 : relocs(std::move(relocs)) {
620 setAlignment(4);
473621 }
474622 size_t getSize() const override;
475 void writeTo(uint8_t *Buf) const override;
623 void writeTo(uint8_t *buf) const override;
476624
477625private:
478 std::vector<RuntimePseudoReloc> Relocs;
626 std::vector<RuntimePseudoReloc> relocs;
479627};
480628
481629// MinGW specific; information about one individual location in the image
......@@ -483,37 +631,48 @@ private:
483631// one individual element in the PseudoRelocTableChunk table.
484632class RuntimePseudoReloc {
485633public:
486 RuntimePseudoReloc(Defined *Sym, SectionChunk *Target, uint32_t TargetOffset,
487 int Flags)
488 : Sym(Sym), Target(Target), TargetOffset(TargetOffset), Flags(Flags) {}
634 RuntimePseudoReloc(Defined *sym, SectionChunk *target, uint32_t targetOffset,
635 int flags)
636 : sym(sym), target(target), targetOffset(targetOffset), flags(flags) {}
489637
490 Defined *Sym;
491 SectionChunk *Target;
492 uint32_t TargetOffset;
638 Defined *sym;
639 SectionChunk *target;
640 uint32_t targetOffset;
493641 // The Flags field contains the size of the relocation, in bits. No other
494642 // flags are currently defined.
495 int Flags;
643 int flags;
496644};
497645
498646// MinGW specific. A Chunk that contains one pointer-sized absolute value.
499class AbsolutePointerChunk : public Chunk {
647class AbsolutePointerChunk : public NonSectionChunk {
500648public:
501 AbsolutePointerChunk(uint64_t Value) : Value(Value) {
502 Alignment = getSize();
649 AbsolutePointerChunk(uint64_t value) : value(value) {
650 setAlignment(getSize());
503651 }
504652 size_t getSize() const override;
505 void writeTo(uint8_t *Buf) const override;
653 void writeTo(uint8_t *buf) const override;
506654
507655private:
508 uint64_t Value;
656 uint64_t value;
509657};
510658
511void applyMOV32T(uint8_t *Off, uint32_t V);
512void applyBranch24T(uint8_t *Off, int32_t V);
659// Return true if this file has the hotpatch flag set to true in the S_COMPILE3
660// record in codeview debug info. Also returns true for some thunks synthesized
661// by the linker.
662inline bool Chunk::isHotPatchable() const {
663 if (auto *sc = dyn_cast<SectionChunk>(this))
664 return sc->file->hotPatchable;
665 else if (isa<ImportThunkChunk>(this))
666 return true;
667 return false;
668}
669
670void applyMOV32T(uint8_t *off, uint32_t v);
671void applyBranch24T(uint8_t *off, int32_t v);
513672
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);
673void applyArm64Addr(uint8_t *off, uint64_t s, uint64_t p, int shift);
674void applyArm64Imm(uint8_t *off, uint64_t imm, uint32_t rangeLimit);
675void applyArm64Branch26(uint8_t *off, int64_t v);
517676
518677} // namespace coff
519678} // namespace lld
deps/lld/COFF/Config.h+130-111
......@@ -1,9 +1,8 @@
11//===- Config.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -29,6 +28,7 @@ class DefinedAbsolute;
2928class DefinedRelative;
3029class StringChunk;
3130class Symbol;
31class InputFile;
3232
3333// Short aliases.
3434static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
......@@ -38,30 +38,30 @@ static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
3838
3939// Represents an /export option.
4040struct Export {
41 StringRef Name; // N in /export:N or /export:E=N
42 StringRef ExtName; // E in /export:E=N
43 Symbol *Sym = nullptr;
44 uint16_t Ordinal = 0;
45 bool Noname = false;
46 bool Data = false;
47 bool Private = false;
48 bool Constant = false;
41 StringRef name; // N in /export:N or /export:E=N
42 StringRef extName; // E in /export:E=N
43 Symbol *sym = nullptr;
44 uint16_t ordinal = 0;
45 bool noname = false;
46 bool data = false;
47 bool isPrivate = false;
48 bool constant = false;
4949
5050 // If an export is a form of /export:foo=dllname.bar, that means
5151 // that foo should be exported as an alias to bar in the DLL.
52 // ForwardTo is set to "dllname.bar" part. Usually empty.
53 StringRef ForwardTo;
54 StringChunk *ForwardChunk = nullptr;
52 // forwardTo is set to "dllname.bar" part. Usually empty.
53 StringRef forwardTo;
54 StringChunk *forwardChunk = nullptr;
5555
5656 // True if this /export option was in .drectves section.
57 bool Directives = false;
58 StringRef SymbolName;
59 StringRef ExportName; // Name in DLL
60
61 bool operator==(const Export &E) {
62 return (Name == E.Name && ExtName == E.ExtName &&
63 Ordinal == E.Ordinal && Noname == E.Noname &&
64 Data == E.Data && Private == E.Private);
57 bool directives = false;
58 StringRef symbolName;
59 StringRef exportName; // Name in DLL
60
61 bool operator==(const Export &e) {
62 return (name == e.name && extName == e.extName &&
63 ordinal == e.ordinal && noname == e.noname &&
64 data == e.data && isPrivate == e.isPrivate);
6565 }
6666};
6767
......@@ -81,130 +81,149 @@ enum class GuardCFLevel {
8181// Global configuration.
8282struct Configuration {
8383 enum ManifestKind { SideBySide, Embed, No };
84 bool is64() { return Machine == AMD64 || Machine == ARM64; }
85
86 llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
87 size_t Wordsize;
88 bool Verbose = false;
89 WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
90 Symbol *Entry = nullptr;
91 bool NoEntry = false;
92 std::string OutputFile;
93 std::string ImportName;
94 bool DoGC = true;
95 bool DoICF = true;
96 bool TailMerge;
97 bool Relocatable = true;
98 bool ForceMultiple = false;
99 bool ForceUnresolved = false;
100 bool Debug = false;
101 bool DebugDwarf = false;
102 bool DebugGHashes = false;
103 bool DebugSymtab = false;
104 bool ShowTiming = false;
105 unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
106 std::vector<std::string> NatvisFiles;
107 llvm::SmallString<128> PDBAltPath;
108 llvm::SmallString<128> PDBPath;
109 llvm::SmallString<128> PDBSourcePath;
110 std::vector<llvm::StringRef> Argv;
84 bool is64() { return machine == AMD64 || machine == ARM64; }
85
86 llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
87 size_t wordsize;
88 bool verbose = false;
89 WindowsSubsystem subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
90 Symbol *entry = nullptr;
91 bool noEntry = false;
92 std::string outputFile;
93 std::string importName;
94 bool demangle = true;
95 bool doGC = true;
96 bool doICF = true;
97 bool tailMerge;
98 bool relocatable = true;
99 bool forceMultiple = false;
100 bool forceMultipleRes = false;
101 bool forceUnresolved = false;
102 bool debug = false;
103 bool debugDwarf = false;
104 bool debugGHashes = false;
105 bool debugSymtab = false;
106 bool showTiming = false;
107 bool showSummary = false;
108 unsigned debugTypes = static_cast<unsigned>(DebugType::None);
109 std::vector<std::string> natvisFiles;
110 llvm::SmallString<128> pdbAltPath;
111 llvm::SmallString<128> pdbPath;
112 llvm::SmallString<128> pdbSourcePath;
113 std::vector<llvm::StringRef> argv;
111114
112115 // Symbols in this set are considered as live by the garbage collector.
113 std::vector<Symbol *> GCRoot;
116 std::vector<Symbol *> gcroot;
114117
115 std::set<StringRef> NoDefaultLibs;
116 bool NoDefaultLibAll = false;
118 std::set<std::string> noDefaultLibs;
119 bool noDefaultLibAll = false;
117120
118121 // True if we are creating a DLL.
119 bool DLL = false;
120 StringRef Implib;
121 std::vector<Export> Exports;
122 std::set<std::string> DelayLoads;
123 std::map<std::string, int> DLLOrder;
124 Symbol *DelayLoadHelper = nullptr;
122 bool dll = false;
123 StringRef implib;
124 std::vector<Export> exports;
125 std::set<std::string> delayLoads;
126 std::map<std::string, int> dllOrder;
127 Symbol *delayLoadHelper = nullptr;
125128
126 bool SaveTemps = false;
129 bool saveTemps = false;
127130
128131 // /guard:cf
129 GuardCFLevel GuardCF = GuardCFLevel::Off;
132 GuardCFLevel guardCF = GuardCFLevel::Off;
130133
131134 // Used for SafeSEH.
132 Symbol *SEHTable = nullptr;
133 Symbol *SEHCount = nullptr;
135 bool safeSEH = false;
136 Symbol *sehTable = nullptr;
137 Symbol *sehCount = nullptr;
134138
135139 // Used for /opt:lldlto=N
136 unsigned LTOO = 2;
140 unsigned ltoo = 2;
137141
138142 // Used for /opt:lldltojobs=N
139 unsigned ThinLTOJobs = 0;
143 unsigned thinLTOJobs = 0;
140144 // Used for /opt:lldltopartitions=N
141 unsigned LTOPartitions = 1;
145 unsigned ltoPartitions = 1;
142146
143147 // Used for /opt:lldltocache=path
144 StringRef LTOCache;
148 StringRef ltoCache;
145149 // Used for /opt:lldltocachepolicy=policy
146 llvm::CachePruningPolicy LTOCachePolicy;
150 llvm::CachePruningPolicy ltoCachePolicy;
147151
148152 // Used for /merge:from=to (e.g. /merge:.rdata=.text)
149 std::map<StringRef, StringRef> Merge;
153 std::map<StringRef, StringRef> merge;
150154
151155 // Used for /section=.name,{DEKPRSW} to set section attributes.
152 std::map<StringRef, uint32_t> Section;
156 std::map<StringRef, uint32_t> section;
153157
154158 // Options for manifest files.
155 ManifestKind Manifest = No;
156 int ManifestID = 1;
157 StringRef ManifestDependency;
158 bool ManifestUAC = true;
159 std::vector<std::string> ManifestInput;
160 StringRef ManifestLevel = "'asInvoker'";
161 StringRef ManifestUIAccess = "'false'";
162 StringRef ManifestFile;
159 ManifestKind manifest = No;
160 int manifestID = 1;
161 StringRef manifestDependency;
162 bool manifestUAC = true;
163 std::vector<std::string> manifestInput;
164 StringRef manifestLevel = "'asInvoker'";
165 StringRef manifestUIAccess = "'false'";
166 StringRef manifestFile;
163167
164168 // Used for /aligncomm.
165 std::map<std::string, int> AlignComm;
169 std::map<std::string, int> alignComm;
166170
167171 // Used for /failifmismatch.
168 std::map<StringRef, StringRef> MustMatch;
172 std::map<StringRef, std::pair<StringRef, InputFile *>> mustMatch;
169173
170174 // Used for /alternatename.
171 std::map<StringRef, StringRef> AlternateNames;
175 std::map<StringRef, StringRef> alternateNames;
172176
173177 // Used for /order.
174 llvm::StringMap<int> Order;
178 llvm::StringMap<int> order;
175179
176180 // Used for /lldmap.
177 std::string MapFile;
178
179 uint64_t ImageBase = -1;
180 uint64_t StackReserve = 1024 * 1024;
181 uint64_t StackCommit = 4096;
182 uint64_t HeapReserve = 1024 * 1024;
183 uint64_t HeapCommit = 4096;
184 uint32_t MajorImageVersion = 0;
185 uint32_t MinorImageVersion = 0;
186 uint32_t MajorOSVersion = 6;
187 uint32_t MinorOSVersion = 0;
188 uint32_t Timestamp = 0;
189 bool DynamicBase = true;
190 bool AllowBind = true;
191 bool NxCompat = true;
192 bool AllowIsolation = true;
193 bool TerminalServerAware = true;
194 bool LargeAddressAware = false;
195 bool HighEntropyVA = false;
196 bool AppContainer = false;
197 bool MinGW = false;
198 bool WarnMissingOrderSymbol = true;
199 bool WarnLocallyDefinedImported = true;
200 bool WarnDebugInfoUnusable = true;
201 bool Incremental = true;
202 bool IntegrityCheck = false;
203 bool KillAt = false;
204 bool Repro = false;
181 std::string mapFile;
182
183 // Used for /thinlto-index-only:
184 llvm::StringRef thinLTOIndexOnlyArg;
185
186 // Used for /thinlto-object-prefix-replace:
187 std::pair<llvm::StringRef, llvm::StringRef> thinLTOPrefixReplace;
188
189 // Used for /thinlto-object-suffix-replace:
190 std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
191
192 uint64_t imageBase = -1;
193 uint64_t fileAlign = 512;
194 uint64_t stackReserve = 1024 * 1024;
195 uint64_t stackCommit = 4096;
196 uint64_t heapReserve = 1024 * 1024;
197 uint64_t heapCommit = 4096;
198 uint32_t majorImageVersion = 0;
199 uint32_t minorImageVersion = 0;
200 uint32_t majorOSVersion = 6;
201 uint32_t minorOSVersion = 0;
202 uint32_t timestamp = 0;
203 uint32_t functionPadMin = 0;
204 bool dynamicBase = true;
205 bool allowBind = true;
206 bool nxCompat = true;
207 bool allowIsolation = true;
208 bool terminalServerAware = true;
209 bool largeAddressAware = false;
210 bool highEntropyVA = false;
211 bool appContainer = false;
212 bool mingw = false;
213 bool warnMissingOrderSymbol = true;
214 bool warnLocallyDefinedImported = true;
215 bool warnDebugInfoUnusable = true;
216 bool incremental = true;
217 bool integrityCheck = false;
218 bool killAt = false;
219 bool repro = false;
220 bool swaprunCD = false;
221 bool swaprunNet = false;
222 bool thinLTOEmitImportsFiles;
223 bool thinLTOIndexOnly;
205224};
206225
207extern Configuration *Config;
226extern Configuration *config;
208227
209228} // namespace coff
210229} // namespace lld
deps/lld/COFF/DLL.cpp+399-308
......@@ -1,9 +1,8 @@
11//===- DLL.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -36,161 +35,167 @@ namespace {
3635// Import table
3736
3837// A chunk for the import descriptor table.
39class HintNameChunk : public Chunk {
38class HintNameChunk : public NonSectionChunk {
4039public:
41 HintNameChunk(StringRef N, uint16_t H) : Name(N), Hint(H) {}
40 HintNameChunk(StringRef n, uint16_t h) : name(n), hint(h) {}
4241
4342 size_t getSize() const override {
4443 // Starts with 2 byte Hint field, followed by a null-terminated string,
4544 // ends with 0 or 1 byte padding.
46 return alignTo(Name.size() + 3, 2);
45 return alignTo(name.size() + 3, 2);
4746 }
4847
49 void writeTo(uint8_t *Buf) const override {
50 memset(Buf + OutputSectionOff, 0, getSize());
51 write16le(Buf + OutputSectionOff, Hint);
52 memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
48 void writeTo(uint8_t *buf) const override {
49 memset(buf, 0, getSize());
50 write16le(buf, hint);
51 memcpy(buf + 2, name.data(), name.size());
5352 }
5453
5554private:
56 StringRef Name;
57 uint16_t Hint;
55 StringRef name;
56 uint16_t hint;
5857};
5958
6059// A chunk for the import descriptor table.
61class LookupChunk : public Chunk {
60class LookupChunk : public NonSectionChunk {
6261public:
63 explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = Config->Wordsize; }
64 size_t getSize() const override { return Config->Wordsize; }
62 explicit LookupChunk(Chunk *c) : hintName(c) {
63 setAlignment(config->wordsize);
64 }
65 size_t getSize() const override { return config->wordsize; }
6566
66 void writeTo(uint8_t *Buf) const override {
67 if (Config->is64())
68 write64le(Buf + OutputSectionOff, HintName->getRVA());
67 void writeTo(uint8_t *buf) const override {
68 if (config->is64())
69 write64le(buf, hintName->getRVA());
6970 else
70 write32le(Buf + OutputSectionOff, HintName->getRVA());
71 write32le(buf, hintName->getRVA());
7172 }
7273
73 Chunk *HintName;
74 Chunk *hintName;
7475};
7576
7677// A chunk for the import descriptor table.
7778// This chunk represent import-by-ordinal symbols.
7879// See Microsoft PE/COFF spec 7.1. Import Header for details.
79class OrdinalOnlyChunk : public Chunk {
80class OrdinalOnlyChunk : public NonSectionChunk {
8081public:
81 explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {
82 Alignment = Config->Wordsize;
82 explicit OrdinalOnlyChunk(uint16_t v) : ordinal(v) {
83 setAlignment(config->wordsize);
8384 }
84 size_t getSize() const override { return Config->Wordsize; }
85 size_t getSize() const override { return config->wordsize; }
8586
86 void writeTo(uint8_t *Buf) const override {
87 void writeTo(uint8_t *buf) const override {
8788 // An import-by-ordinal slot has MSB 1 to indicate that
8889 // this is import-by-ordinal (and not import-by-name).
89 if (Config->is64()) {
90 write64le(Buf + OutputSectionOff, (1ULL << 63) | Ordinal);
90 if (config->is64()) {
91 write64le(buf, (1ULL << 63) | ordinal);
9192 } else {
92 write32le(Buf + OutputSectionOff, (1ULL << 31) | Ordinal);
93 write32le(buf, (1ULL << 31) | ordinal);
9394 }
9495 }
9596
96 uint16_t Ordinal;
97 uint16_t ordinal;
9798};
9899
99100// A chunk for the import descriptor table.
100class ImportDirectoryChunk : public Chunk {
101class ImportDirectoryChunk : public NonSectionChunk {
101102public:
102 explicit ImportDirectoryChunk(Chunk *N) : DLLName(N) {}
103 explicit ImportDirectoryChunk(Chunk *n) : dllName(n) {}
103104 size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
104105
105 void writeTo(uint8_t *Buf) const override {
106 memset(Buf + OutputSectionOff, 0, getSize());
106 void writeTo(uint8_t *buf) const override {
107 memset(buf, 0, getSize());
107108
108 auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
109 E->ImportLookupTableRVA = LookupTab->getRVA();
110 E->NameRVA = DLLName->getRVA();
111 E->ImportAddressTableRVA = AddressTab->getRVA();
109 auto *e = (coff_import_directory_table_entry *)(buf);
110 e->ImportLookupTableRVA = lookupTab->getRVA();
111 e->NameRVA = dllName->getRVA();
112 e->ImportAddressTableRVA = addressTab->getRVA();
112113 }
113114
114 Chunk *DLLName;
115 Chunk *LookupTab;
116 Chunk *AddressTab;
115 Chunk *dllName;
116 Chunk *lookupTab;
117 Chunk *addressTab;
117118};
118119
119120// A chunk representing null terminator in the import table.
120121// Contents of this chunk is always null bytes.
121class NullChunk : public Chunk {
122class NullChunk : public NonSectionChunk {
122123public:
123 explicit NullChunk(size_t N) : Size(N) {}
124 bool hasData() const override { return false; }
125 size_t getSize() const override { return Size; }
124 explicit NullChunk(size_t n) : size(n) { hasData = false; }
125 size_t getSize() const override { return size; }
126126
127 void writeTo(uint8_t *Buf) const override {
128 memset(Buf + OutputSectionOff, 0, Size);
127 void writeTo(uint8_t *buf) const override {
128 memset(buf, 0, size);
129129 }
130130
131131private:
132 size_t Size;
132 size_t size;
133133};
134134
135135static std::vector<std::vector<DefinedImportData *>>
136binImports(const std::vector<DefinedImportData *> &Imports) {
136binImports(const std::vector<DefinedImportData *> &imports) {
137137 // Group DLL-imported symbols by DLL name because that's how
138138 // symbols are layed out in the import descriptor table.
139 auto Less = [](const std::string &A, const std::string &B) {
140 return Config->DLLOrder[A] < Config->DLLOrder[B];
139 auto less = [](const std::string &a, const std::string &b) {
140 return config->dllOrder[a] < config->dllOrder[b];
141141 };
142142 std::map<std::string, std::vector<DefinedImportData *>,
143 bool(*)(const std::string &, const std::string &)> M(Less);
144 for (DefinedImportData *Sym : Imports)
145 M[Sym->getDLLName().lower()].push_back(Sym);
143 bool(*)(const std::string &, const std::string &)> m(less);
144 for (DefinedImportData *sym : imports)
145 m[sym->getDLLName().lower()].push_back(sym);
146146
147 std::vector<std::vector<DefinedImportData *>> V;
148 for (auto &KV : M) {
147 std::vector<std::vector<DefinedImportData *>> v;
148 for (auto &kv : m) {
149149 // Sort symbols by name for each group.
150 std::vector<DefinedImportData *> &Syms = KV.second;
151 std::sort(Syms.begin(), Syms.end(),
152 [](DefinedImportData *A, DefinedImportData *B) {
153 return A->getName() < B->getName();
150 std::vector<DefinedImportData *> &syms = kv.second;
151 std::sort(syms.begin(), syms.end(),
152 [](DefinedImportData *a, DefinedImportData *b) {
153 return a->getName() < b->getName();
154154 });
155 V.push_back(std::move(Syms));
155 v.push_back(std::move(syms));
156156 }
157 return V;
157 return v;
158158}
159159
160160// Export table
161161// See Microsoft PE/COFF spec 4.3 for details.
162162
163163// A chunk for the delay import descriptor table etnry.
164class DelayDirectoryChunk : public Chunk {
164class DelayDirectoryChunk : public NonSectionChunk {
165165public:
166 explicit DelayDirectoryChunk(Chunk *N) : DLLName(N) {}
166 explicit DelayDirectoryChunk(Chunk *n) : dllName(n) {}
167167
168168 size_t getSize() const override {
169169 return sizeof(delay_import_directory_table_entry);
170170 }
171171
172 void writeTo(uint8_t *Buf) const override {
173 memset(Buf + OutputSectionOff, 0, getSize());
172 void writeTo(uint8_t *buf) const override {
173 memset(buf, 0, getSize());
174174
175 auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
176 E->Attributes = 1;
177 E->Name = DLLName->getRVA();
178 E->ModuleHandle = ModuleHandle->getRVA();
179 E->DelayImportAddressTable = AddressTab->getRVA();
180 E->DelayImportNameTable = NameTab->getRVA();
175 auto *e = (delay_import_directory_table_entry *)(buf);
176 e->Attributes = 1;
177 e->Name = dllName->getRVA();
178 e->ModuleHandle = moduleHandle->getRVA();
179 e->DelayImportAddressTable = addressTab->getRVA();
180 e->DelayImportNameTable = nameTab->getRVA();
181181 }
182182
183 Chunk *DLLName;
184 Chunk *ModuleHandle;
185 Chunk *AddressTab;
186 Chunk *NameTab;
183 Chunk *dllName;
184 Chunk *moduleHandle;
185 Chunk *addressTab;
186 Chunk *nameTab;
187187};
188188
189189// Initial contents for delay-loaded functions.
190190// This code calls __delayLoadHelper2 function to resolve a symbol
191191// and then overwrites its jump table slot with the result
192192// for subsequent function calls.
193static const uint8_t ThunkX64[] = {
193static const uint8_t thunkX64[] = {
194 0x48, 0x8D, 0x05, 0, 0, 0, 0, // lea rax, [__imp_<FUNCNAME>]
195 0xE9, 0, 0, 0, 0, // jmp __tailMerge_<lib>
196};
197
198static const uint8_t tailMergeX64[] = {
194199 0x51, // push rcx
195200 0x52, // push rdx
196201 0x41, 0x50, // push r8
......@@ -200,7 +205,7 @@ static const uint8_t ThunkX64[] = {
200205 0x66, 0x0F, 0x7F, 0x4C, 0x24, 0x10, // movdqa xmmword ptr [rsp+10h], xmm1
201206 0x66, 0x0F, 0x7F, 0x54, 0x24, 0x20, // movdqa xmmword ptr [rsp+20h], xmm2
202207 0x66, 0x0F, 0x7F, 0x5C, 0x24, 0x30, // movdqa xmmword ptr [rsp+30h], xmm3
203 0x48, 0x8D, 0x15, 0, 0, 0, 0, // lea rdx, [__imp_<FUNCNAME>]
208 0x48, 0x8B, 0xD0, // mov rdx, rax
204209 0x48, 0x8D, 0x0D, 0, 0, 0, 0, // lea rcx, [___DELAY_IMPORT_...]
205210 0xE8, 0, 0, 0, 0, // call __delayLoadHelper2
206211 0x66, 0x0F, 0x6F, 0x04, 0x24, // movdqa xmm0, xmmword ptr [rsp]
......@@ -215,10 +220,15 @@ static const uint8_t ThunkX64[] = {
215220 0xFF, 0xE0, // jmp rax
216221};
217222
218static const uint8_t ThunkX86[] = {
223static const uint8_t thunkX86[] = {
224 0xB8, 0, 0, 0, 0, // mov eax, offset ___imp__<FUNCNAME>
225 0xE9, 0, 0, 0, 0, // jmp __tailMerge_<lib>
226};
227
228static const uint8_t tailMergeX86[] = {
219229 0x51, // push ecx
220230 0x52, // push edx
221 0x68, 0, 0, 0, 0, // push offset ___imp__<FUNCNAME>
231 0x50, // push eax
222232 0x68, 0, 0, 0, 0, // push offset ___DELAY_IMPORT_DESCRIPTOR_<DLLNAME>_dll
223233 0xE8, 0, 0, 0, 0, // call ___delayLoadHelper2@8
224234 0x5A, // pop edx
......@@ -226,9 +236,13 @@ static const uint8_t ThunkX86[] = {
226236 0xFF, 0xE0, // jmp eax
227237};
228238
229static const uint8_t ThunkARM[] = {
239static const uint8_t thunkARM[] = {
230240 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0 __imp_<FUNCNAME>
231241 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0 __imp_<FUNCNAME>
242 0x00, 0xf0, 0x00, 0xb8, // b.w __tailMerge_<lib>
243};
244
245static const uint8_t tailMergeARM[] = {
232246 0x2d, 0xe9, 0x0f, 0x48, // push.w {r0, r1, r2, r3, r11, lr}
233247 0x0d, 0xf2, 0x10, 0x0b, // addw r11, sp, #16
234248 0x2d, 0xed, 0x10, 0x0b, // vpush {d0, d1, d2, d3, d4, d5, d6, d7}
......@@ -242,9 +256,13 @@ static const uint8_t ThunkARM[] = {
242256 0x60, 0x47, // bx ip
243257};
244258
245static const uint8_t ThunkARM64[] = {
259static const uint8_t thunkARM64[] = {
246260 0x11, 0x00, 0x00, 0x90, // adrp x17, #0 __imp_<FUNCNAME>
247261 0x31, 0x02, 0x00, 0x91, // add x17, x17, #0 :lo12:__imp_<FUNCNAME>
262 0x00, 0x00, 0x00, 0x14, // b __tailMerge_<lib>
263};
264
265static const uint8_t tailMergeARM64[] = {
248266 0xfd, 0x7b, 0xb3, 0xa9, // stp x29, x30, [sp, #-208]!
249267 0xfd, 0x03, 0x00, 0x91, // mov x29, sp
250268 0xe0, 0x07, 0x01, 0xa9, // stp x0, x1, [sp, #16]
......@@ -273,372 +291,445 @@ static const uint8_t ThunkARM64[] = {
273291};
274292
275293// A chunk for the delay import thunk.
276class ThunkChunkX64 : public Chunk {
294class ThunkChunkX64 : public NonSectionChunk {
295public:
296 ThunkChunkX64(Defined *i, Chunk *tm) : imp(i), tailMerge(tm) {}
297
298 size_t getSize() const override { return sizeof(thunkX64); }
299
300 void writeTo(uint8_t *buf) const override {
301 memcpy(buf, thunkX64, sizeof(thunkX64));
302 write32le(buf + 3, imp->getRVA() - rva - 7);
303 write32le(buf + 8, tailMerge->getRVA() - rva - 12);
304 }
305
306 Defined *imp = nullptr;
307 Chunk *tailMerge = nullptr;
308};
309
310class TailMergeChunkX64 : public NonSectionChunk {
311public:
312 TailMergeChunkX64(Chunk *d, Defined *h) : desc(d), helper(h) {}
313
314 size_t getSize() const override { return sizeof(tailMergeX64); }
315
316 void writeTo(uint8_t *buf) const override {
317 memcpy(buf, tailMergeX64, sizeof(tailMergeX64));
318 write32le(buf + 39, desc->getRVA() - rva - 43);
319 write32le(buf + 44, helper->getRVA() - rva - 48);
320 }
321
322 Chunk *desc = nullptr;
323 Defined *helper = nullptr;
324};
325
326class ThunkChunkX86 : public NonSectionChunk {
277327public:
278 ThunkChunkX64(Defined *I, Chunk *D, Defined *H)
279 : Imp(I), Desc(D), Helper(H) {}
328 ThunkChunkX86(Defined *i, Chunk *tm) : imp(i), tailMerge(tm) {}
280329
281 size_t getSize() const override { return sizeof(ThunkX64); }
330 size_t getSize() const override { return sizeof(thunkX86); }
282331
283 void writeTo(uint8_t *Buf) const override {
284 memcpy(Buf + OutputSectionOff, ThunkX64, sizeof(ThunkX64));
285 write32le(Buf + OutputSectionOff + 36, Imp->getRVA() - RVA - 40);
286 write32le(Buf + OutputSectionOff + 43, Desc->getRVA() - RVA - 47);
287 write32le(Buf + OutputSectionOff + 48, Helper->getRVA() - RVA - 52);
332 void writeTo(uint8_t *buf) const override {
333 memcpy(buf, thunkX86, sizeof(thunkX86));
334 write32le(buf + 1, imp->getRVA() + config->imageBase);
335 write32le(buf + 6, tailMerge->getRVA() - rva - 10);
288336 }
289337
290 Defined *Imp = nullptr;
291 Chunk *Desc = nullptr;
292 Defined *Helper = nullptr;
338 void getBaserels(std::vector<Baserel> *res) override {
339 res->emplace_back(rva + 1);
340 }
341
342 Defined *imp = nullptr;
343 Chunk *tailMerge = nullptr;
293344};
294345
295class ThunkChunkX86 : public Chunk {
346class TailMergeChunkX86 : public NonSectionChunk {
296347public:
297 ThunkChunkX86(Defined *I, Chunk *D, Defined *H)
298 : Imp(I), Desc(D), Helper(H) {}
348 TailMergeChunkX86(Chunk *d, Defined *h) : desc(d), helper(h) {}
299349
300 size_t getSize() const override { return sizeof(ThunkX86); }
350 size_t getSize() const override { return sizeof(tailMergeX86); }
301351
302 void writeTo(uint8_t *Buf) const override {
303 memcpy(Buf + OutputSectionOff, ThunkX86, sizeof(ThunkX86));
304 write32le(Buf + OutputSectionOff + 3, Imp->getRVA() + Config->ImageBase);
305 write32le(Buf + OutputSectionOff + 8, Desc->getRVA() + Config->ImageBase);
306 write32le(Buf + OutputSectionOff + 13, Helper->getRVA() - RVA - 17);
352 void writeTo(uint8_t *buf) const override {
353 memcpy(buf, tailMergeX86, sizeof(tailMergeX86));
354 write32le(buf + 4, desc->getRVA() + config->imageBase);
355 write32le(buf + 9, helper->getRVA() - rva - 13);
307356 }
308357
309 void getBaserels(std::vector<Baserel> *Res) override {
310 Res->emplace_back(RVA + 3);
311 Res->emplace_back(RVA + 8);
358 void getBaserels(std::vector<Baserel> *res) override {
359 res->emplace_back(rva + 4);
312360 }
313361
314 Defined *Imp = nullptr;
315 Chunk *Desc = nullptr;
316 Defined *Helper = nullptr;
362 Chunk *desc = nullptr;
363 Defined *helper = nullptr;
317364};
318365
319class ThunkChunkARM : public Chunk {
366class ThunkChunkARM : public NonSectionChunk {
320367public:
321 ThunkChunkARM(Defined *I, Chunk *D, Defined *H)
322 : Imp(I), Desc(D), Helper(H) {}
368 ThunkChunkARM(Defined *i, Chunk *tm) : imp(i), tailMerge(tm) {}
323369
324 size_t getSize() const override { return sizeof(ThunkARM); }
370 size_t getSize() const override { return sizeof(thunkARM); }
325371
326 void writeTo(uint8_t *Buf) const override {
327 memcpy(Buf + OutputSectionOff, ThunkARM, sizeof(ThunkARM));
328 applyMOV32T(Buf + OutputSectionOff + 0, Imp->getRVA() + Config->ImageBase);
329 applyMOV32T(Buf + OutputSectionOff + 22, Desc->getRVA() + Config->ImageBase);
330 applyBranch24T(Buf + OutputSectionOff + 30, Helper->getRVA() - RVA - 34);
372 void writeTo(uint8_t *buf) const override {
373 memcpy(buf, thunkARM, sizeof(thunkARM));
374 applyMOV32T(buf + 0, imp->getRVA() + config->imageBase);
375 applyBranch24T(buf + 8, tailMerge->getRVA() - rva - 12);
331376 }
332377
333 void getBaserels(std::vector<Baserel> *Res) override {
334 Res->emplace_back(RVA + 0, IMAGE_REL_BASED_ARM_MOV32T);
335 Res->emplace_back(RVA + 22, IMAGE_REL_BASED_ARM_MOV32T);
378 void getBaserels(std::vector<Baserel> *res) override {
379 res->emplace_back(rva + 0, IMAGE_REL_BASED_ARM_MOV32T);
336380 }
337381
338 Defined *Imp = nullptr;
339 Chunk *Desc = nullptr;
340 Defined *Helper = nullptr;
382 Defined *imp = nullptr;
383 Chunk *tailMerge = nullptr;
341384};
342385
343class ThunkChunkARM64 : public Chunk {
386class TailMergeChunkARM : public NonSectionChunk {
344387public:
345 ThunkChunkARM64(Defined *I, Chunk *D, Defined *H)
346 : Imp(I), Desc(D), Helper(H) {}
388 TailMergeChunkARM(Chunk *d, Defined *h) : desc(d), helper(h) {}
389
390 size_t getSize() const override { return sizeof(tailMergeARM); }
347391
348 size_t getSize() const override { return sizeof(ThunkARM64); }
392 void writeTo(uint8_t *buf) const override {
393 memcpy(buf, tailMergeARM, sizeof(tailMergeARM));
394 applyMOV32T(buf + 14, desc->getRVA() + config->imageBase);
395 applyBranch24T(buf + 22, helper->getRVA() - rva - 26);
396 }
349397
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);
398 void getBaserels(std::vector<Baserel> *res) override {
399 res->emplace_back(rva + 14, IMAGE_REL_BASED_ARM_MOV32T);
358400 }
359401
360 Defined *Imp = nullptr;
361 Chunk *Desc = nullptr;
362 Defined *Helper = nullptr;
402 Chunk *desc = nullptr;
403 Defined *helper = nullptr;
404};
405
406class ThunkChunkARM64 : public NonSectionChunk {
407public:
408 ThunkChunkARM64(Defined *i, Chunk *tm) : imp(i), tailMerge(tm) {}
409
410 size_t getSize() const override { return sizeof(thunkARM64); }
411
412 void writeTo(uint8_t *buf) const override {
413 memcpy(buf, thunkARM64, sizeof(thunkARM64));
414 applyArm64Addr(buf + 0, imp->getRVA(), rva + 0, 12);
415 applyArm64Imm(buf + 4, imp->getRVA() & 0xfff, 0);
416 applyArm64Branch26(buf + 8, tailMerge->getRVA() - rva - 8);
417 }
418
419 Defined *imp = nullptr;
420 Chunk *tailMerge = nullptr;
421};
422
423class TailMergeChunkARM64 : public NonSectionChunk {
424public:
425 TailMergeChunkARM64(Chunk *d, Defined *h) : desc(d), helper(h) {}
426
427 size_t getSize() const override { return sizeof(tailMergeARM64); }
428
429 void writeTo(uint8_t *buf) const override {
430 memcpy(buf, tailMergeARM64, sizeof(tailMergeARM64));
431 applyArm64Addr(buf + 44, desc->getRVA(), rva + 44, 12);
432 applyArm64Imm(buf + 48, desc->getRVA() & 0xfff, 0);
433 applyArm64Branch26(buf + 52, helper->getRVA() - rva - 52);
434 }
435
436 Chunk *desc = nullptr;
437 Defined *helper = nullptr;
363438};
364439
365440// A chunk for the import descriptor table.
366class DelayAddressChunk : public Chunk {
441class DelayAddressChunk : public NonSectionChunk {
367442public:
368 explicit DelayAddressChunk(Chunk *C) : Thunk(C) {
369 Alignment = Config->Wordsize;
443 explicit DelayAddressChunk(Chunk *c) : thunk(c) {
444 setAlignment(config->wordsize);
370445 }
371 size_t getSize() const override { return Config->Wordsize; }
446 size_t getSize() const override { return config->wordsize; }
372447
373 void writeTo(uint8_t *Buf) const override {
374 if (Config->is64()) {
375 write64le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase);
448 void writeTo(uint8_t *buf) const override {
449 if (config->is64()) {
450 write64le(buf, thunk->getRVA() + config->imageBase);
376451 } else {
377 uint32_t Bit = 0;
452 uint32_t bit = 0;
378453 // Pointer to thumb code must have the LSB set, so adjust it.
379 if (Config->Machine == ARMNT)
380 Bit = 1;
381 write32le(Buf + OutputSectionOff, (Thunk->getRVA() + Config->ImageBase) | Bit);
454 if (config->machine == ARMNT)
455 bit = 1;
456 write32le(buf, (thunk->getRVA() + config->imageBase) | bit);
382457 }
383458 }
384459
385 void getBaserels(std::vector<Baserel> *Res) override {
386 Res->emplace_back(RVA);
460 void getBaserels(std::vector<Baserel> *res) override {
461 res->emplace_back(rva);
387462 }
388463
389 Chunk *Thunk;
464 Chunk *thunk;
390465};
391466
392467// Export table
393468// Read Microsoft PE/COFF spec 5.3 for details.
394469
395470// A chunk for the export descriptor table.
396class ExportDirectoryChunk : public Chunk {
471class ExportDirectoryChunk : public NonSectionChunk {
397472public:
398 ExportDirectoryChunk(int I, int J, Chunk *D, Chunk *A, Chunk *N, Chunk *O)
399 : MaxOrdinal(I), NameTabSize(J), DLLName(D), AddressTab(A), NameTab(N),
400 OrdinalTab(O) {}
473 ExportDirectoryChunk(int i, int j, Chunk *d, Chunk *a, Chunk *n, Chunk *o)
474 : maxOrdinal(i), nameTabSize(j), dllName(d), addressTab(a), nameTab(n),
475 ordinalTab(o) {}
401476
402477 size_t getSize() const override {
403478 return sizeof(export_directory_table_entry);
404479 }
405480
406 void writeTo(uint8_t *Buf) const override {
407 memset(Buf + OutputSectionOff, 0, getSize());
408
409 auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
410 E->NameRVA = DLLName->getRVA();
411 E->OrdinalBase = 0;
412 E->AddressTableEntries = MaxOrdinal + 1;
413 E->NumberOfNamePointers = NameTabSize;
414 E->ExportAddressTableRVA = AddressTab->getRVA();
415 E->NamePointerRVA = NameTab->getRVA();
416 E->OrdinalTableRVA = OrdinalTab->getRVA();
481 void writeTo(uint8_t *buf) const override {
482 memset(buf, 0, getSize());
483
484 auto *e = (export_directory_table_entry *)(buf);
485 e->NameRVA = dllName->getRVA();
486 e->OrdinalBase = 0;
487 e->AddressTableEntries = maxOrdinal + 1;
488 e->NumberOfNamePointers = nameTabSize;
489 e->ExportAddressTableRVA = addressTab->getRVA();
490 e->NamePointerRVA = nameTab->getRVA();
491 e->OrdinalTableRVA = ordinalTab->getRVA();
417492 }
418493
419 uint16_t MaxOrdinal;
420 uint16_t NameTabSize;
421 Chunk *DLLName;
422 Chunk *AddressTab;
423 Chunk *NameTab;
424 Chunk *OrdinalTab;
494 uint16_t maxOrdinal;
495 uint16_t nameTabSize;
496 Chunk *dllName;
497 Chunk *addressTab;
498 Chunk *nameTab;
499 Chunk *ordinalTab;
425500};
426501
427class AddressTableChunk : public Chunk {
502class AddressTableChunk : public NonSectionChunk {
428503public:
429 explicit AddressTableChunk(size_t MaxOrdinal) : Size(MaxOrdinal + 1) {}
430 size_t getSize() const override { return Size * 4; }
504 explicit AddressTableChunk(size_t maxOrdinal) : size(maxOrdinal + 1) {}
505 size_t getSize() const override { return size * 4; }
431506
432 void writeTo(uint8_t *Buf) const override {
433 memset(Buf + OutputSectionOff, 0, getSize());
507 void writeTo(uint8_t *buf) const override {
508 memset(buf, 0, getSize());
434509
435 for (const Export &E : Config->Exports) {
436 uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
437 uint32_t Bit = 0;
510 for (const Export &e : config->exports) {
511 uint8_t *p = buf + e.ordinal * 4;
512 uint32_t bit = 0;
438513 // Pointer to thumb code must have the LSB set, so adjust it.
439 if (Config->Machine == ARMNT && !E.Data)
440 Bit = 1;
441 if (E.ForwardChunk) {
442 write32le(P, E.ForwardChunk->getRVA() | Bit);
514 if (config->machine == ARMNT && !e.data)
515 bit = 1;
516 if (e.forwardChunk) {
517 write32le(p, e.forwardChunk->getRVA() | bit);
443518 } else {
444 write32le(P, cast<Defined>(E.Sym)->getRVA() | Bit);
519 write32le(p, cast<Defined>(e.sym)->getRVA() | bit);
445520 }
446521 }
447522 }
448523
449524private:
450 size_t Size;
525 size_t size;
451526};
452527
453class NamePointersChunk : public Chunk {
528class NamePointersChunk : public NonSectionChunk {
454529public:
455 explicit NamePointersChunk(std::vector<Chunk *> &V) : Chunks(V) {}
456 size_t getSize() const override { return Chunks.size() * 4; }
457
458 void writeTo(uint8_t *Buf) const override {
459 uint8_t *P = Buf + OutputSectionOff;
460 for (Chunk *C : Chunks) {
461 write32le(P, C->getRVA());
462 P += 4;
530 explicit NamePointersChunk(std::vector<Chunk *> &v) : chunks(v) {}
531 size_t getSize() const override { return chunks.size() * 4; }
532
533 void writeTo(uint8_t *buf) const override {
534 for (Chunk *c : chunks) {
535 write32le(buf, c->getRVA());
536 buf += 4;
463537 }
464538 }
465539
466540private:
467 std::vector<Chunk *> Chunks;
541 std::vector<Chunk *> chunks;
468542};
469543
470class ExportOrdinalChunk : public Chunk {
544class ExportOrdinalChunk : public NonSectionChunk {
471545public:
472 explicit ExportOrdinalChunk(size_t I) : Size(I) {}
473 size_t getSize() const override { return Size * 2; }
546 explicit ExportOrdinalChunk(size_t i) : size(i) {}
547 size_t getSize() const override { return size * 2; }
474548
475 void writeTo(uint8_t *Buf) const override {
476 uint8_t *P = Buf + OutputSectionOff;
477 for (Export &E : Config->Exports) {
478 if (E.Noname)
549 void writeTo(uint8_t *buf) const override {
550 for (Export &e : config->exports) {
551 if (e.noname)
479552 continue;
480 write16le(P, E.Ordinal);
481 P += 2;
553 write16le(buf, e.ordinal);
554 buf += 2;
482555 }
483556 }
484557
485558private:
486 size_t Size;
559 size_t size;
487560};
488561
489562} // anonymous namespace
490563
491564void IdataContents::create() {
492 std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
565 std::vector<std::vector<DefinedImportData *>> v = binImports(imports);
493566
494567 // Create .idata contents for each DLL.
495 for (std::vector<DefinedImportData *> &Syms : V) {
568 for (std::vector<DefinedImportData *> &syms : v) {
496569 // Create lookup and address tables. If they have external names,
497 // we need to create HintName chunks to store the names.
570 // we need to create hintName chunks to store the names.
498571 // If they don't (if they are import-by-ordinals), we store only
499572 // ordinal values to the table.
500 size_t Base = Lookups.size();
501 for (DefinedImportData *S : Syms) {
502 uint16_t Ord = S->getOrdinal();
503 if (S->getExternalName().empty()) {
504 Lookups.push_back(make<OrdinalOnlyChunk>(Ord));
505 Addresses.push_back(make<OrdinalOnlyChunk>(Ord));
573 size_t base = lookups.size();
574 for (DefinedImportData *s : syms) {
575 uint16_t ord = s->getOrdinal();
576 if (s->getExternalName().empty()) {
577 lookups.push_back(make<OrdinalOnlyChunk>(ord));
578 addresses.push_back(make<OrdinalOnlyChunk>(ord));
506579 continue;
507580 }
508 auto *C = make<HintNameChunk>(S->getExternalName(), Ord);
509 Lookups.push_back(make<LookupChunk>(C));
510 Addresses.push_back(make<LookupChunk>(C));
511 Hints.push_back(C);
581 auto *c = make<HintNameChunk>(s->getExternalName(), ord);
582 lookups.push_back(make<LookupChunk>(c));
583 addresses.push_back(make<LookupChunk>(c));
584 hints.push_back(c);
512585 }
513586 // Terminate with null values.
514 Lookups.push_back(make<NullChunk>(Config->Wordsize));
515 Addresses.push_back(make<NullChunk>(Config->Wordsize));
587 lookups.push_back(make<NullChunk>(config->wordsize));
588 addresses.push_back(make<NullChunk>(config->wordsize));
516589
517 for (int I = 0, E = Syms.size(); I < E; ++I)
518 Syms[I]->setLocation(Addresses[Base + I]);
590 for (int i = 0, e = syms.size(); i < e; ++i)
591 syms[i]->setLocation(addresses[base + i]);
519592
520593 // Create the import table header.
521 DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
522 auto *Dir = make<ImportDirectoryChunk>(DLLNames.back());
523 Dir->LookupTab = Lookups[Base];
524 Dir->AddressTab = Addresses[Base];
525 Dirs.push_back(Dir);
594 dllNames.push_back(make<StringChunk>(syms[0]->getDLLName()));
595 auto *dir = make<ImportDirectoryChunk>(dllNames.back());
596 dir->lookupTab = lookups[base];
597 dir->addressTab = addresses[base];
598 dirs.push_back(dir);
526599 }
527600 // Add null terminator.
528 Dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry)));
601 dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry)));
529602}
530603
531604std::vector<Chunk *> DelayLoadContents::getChunks() {
532 std::vector<Chunk *> V;
533 V.insert(V.end(), Dirs.begin(), Dirs.end());
534 V.insert(V.end(), Names.begin(), Names.end());
535 V.insert(V.end(), HintNames.begin(), HintNames.end());
536 V.insert(V.end(), DLLNames.begin(), DLLNames.end());
537 return V;
605 std::vector<Chunk *> v;
606 v.insert(v.end(), dirs.begin(), dirs.end());
607 v.insert(v.end(), names.begin(), names.end());
608 v.insert(v.end(), hintNames.begin(), hintNames.end());
609 v.insert(v.end(), dllNames.begin(), dllNames.end());
610 return v;
538611}
539612
540613std::vector<Chunk *> DelayLoadContents::getDataChunks() {
541 std::vector<Chunk *> V;
542 V.insert(V.end(), ModuleHandles.begin(), ModuleHandles.end());
543 V.insert(V.end(), Addresses.begin(), Addresses.end());
544 return V;
614 std::vector<Chunk *> v;
615 v.insert(v.end(), moduleHandles.begin(), moduleHandles.end());
616 v.insert(v.end(), addresses.begin(), addresses.end());
617 return v;
545618}
546619
547620uint64_t DelayLoadContents::getDirSize() {
548 return Dirs.size() * sizeof(delay_import_directory_table_entry);
621 return dirs.size() * sizeof(delay_import_directory_table_entry);
549622}
550623
551void DelayLoadContents::create(Defined *H) {
552 Helper = H;
553 std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
624void DelayLoadContents::create(Defined *h) {
625 helper = h;
626 std::vector<std::vector<DefinedImportData *>> v = binImports(imports);
554627
555628 // Create .didat contents for each DLL.
556 for (std::vector<DefinedImportData *> &Syms : V) {
629 for (std::vector<DefinedImportData *> &syms : v) {
557630 // Create the delay import table header.
558 DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
559 auto *Dir = make<DelayDirectoryChunk>(DLLNames.back());
560
561 size_t Base = Addresses.size();
562 for (DefinedImportData *S : Syms) {
563 Chunk *T = newThunkChunk(S, Dir);
564 auto *A = make<DelayAddressChunk>(T);
565 Addresses.push_back(A);
566 Thunks.push_back(T);
567 StringRef ExtName = S->getExternalName();
568 if (ExtName.empty()) {
569 Names.push_back(make<OrdinalOnlyChunk>(S->getOrdinal()));
631 dllNames.push_back(make<StringChunk>(syms[0]->getDLLName()));
632 auto *dir = make<DelayDirectoryChunk>(dllNames.back());
633
634 size_t base = addresses.size();
635 Chunk *tm = newTailMergeChunk(dir);
636 for (DefinedImportData *s : syms) {
637 Chunk *t = newThunkChunk(s, tm);
638 auto *a = make<DelayAddressChunk>(t);
639 addresses.push_back(a);
640 thunks.push_back(t);
641 StringRef extName = s->getExternalName();
642 if (extName.empty()) {
643 names.push_back(make<OrdinalOnlyChunk>(s->getOrdinal()));
570644 } else {
571 auto *C = make<HintNameChunk>(ExtName, 0);
572 Names.push_back(make<LookupChunk>(C));
573 HintNames.push_back(C);
645 auto *c = make<HintNameChunk>(extName, 0);
646 names.push_back(make<LookupChunk>(c));
647 hintNames.push_back(c);
574648 }
575649 }
650 thunks.push_back(tm);
576651 // Terminate with null values.
577 Addresses.push_back(make<NullChunk>(8));
578 Names.push_back(make<NullChunk>(8));
652 addresses.push_back(make<NullChunk>(8));
653 names.push_back(make<NullChunk>(8));
579654
580 for (int I = 0, E = Syms.size(); I < E; ++I)
581 Syms[I]->setLocation(Addresses[Base + I]);
582 auto *MH = make<NullChunk>(8);
583 MH->Alignment = 8;
584 ModuleHandles.push_back(MH);
655 for (int i = 0, e = syms.size(); i < e; ++i)
656 syms[i]->setLocation(addresses[base + i]);
657 auto *mh = make<NullChunk>(8);
658 mh->setAlignment(8);
659 moduleHandles.push_back(mh);
585660
586661 // Fill the delay import table header fields.
587 Dir->ModuleHandle = MH;
588 Dir->AddressTab = Addresses[Base];
589 Dir->NameTab = Names[Base];
590 Dirs.push_back(Dir);
662 dir->moduleHandle = mh;
663 dir->addressTab = addresses[base];
664 dir->nameTab = names[base];
665 dirs.push_back(dir);
591666 }
592667 // Add null terminator.
593 Dirs.push_back(make<NullChunk>(sizeof(delay_import_directory_table_entry)));
668 dirs.push_back(make<NullChunk>(sizeof(delay_import_directory_table_entry)));
594669}
595670
596Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) {
597 switch (Config->Machine) {
671Chunk *DelayLoadContents::newTailMergeChunk(Chunk *dir) {
672 switch (config->machine) {
598673 case AMD64:
599 return make<ThunkChunkX64>(S, Dir, Helper);
674 return make<TailMergeChunkX64>(dir, helper);
600675 case I386:
601 return make<ThunkChunkX86>(S, Dir, Helper);
676 return make<TailMergeChunkX86>(dir, helper);
602677 case ARMNT:
603 return make<ThunkChunkARM>(S, Dir, Helper);
678 return make<TailMergeChunkARM>(dir, helper);
604679 case ARM64:
605 return make<ThunkChunkARM64>(S, Dir, Helper);
680 return make<TailMergeChunkARM64>(dir, helper);
681 default:
682 llvm_unreachable("unsupported machine type");
683 }
684}
685
686Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *s,
687 Chunk *tailMerge) {
688 switch (config->machine) {
689 case AMD64:
690 return make<ThunkChunkX64>(s, tailMerge);
691 case I386:
692 return make<ThunkChunkX86>(s, tailMerge);
693 case ARMNT:
694 return make<ThunkChunkARM>(s, tailMerge);
695 case ARM64:
696 return make<ThunkChunkARM64>(s, tailMerge);
606697 default:
607698 llvm_unreachable("unsupported machine type");
608699 }
609700}
610701
611702EdataContents::EdataContents() {
612 uint16_t MaxOrdinal = 0;
613 for (Export &E : Config->Exports)
614 MaxOrdinal = std::max(MaxOrdinal, E.Ordinal);
615
616 auto *DLLName = make<StringChunk>(sys::path::filename(Config->OutputFile));
617 auto *AddressTab = make<AddressTableChunk>(MaxOrdinal);
618 std::vector<Chunk *> Names;
619 for (Export &E : Config->Exports)
620 if (!E.Noname)
621 Names.push_back(make<StringChunk>(E.ExportName));
622
623 std::vector<Chunk *> Forwards;
624 for (Export &E : Config->Exports) {
625 if (E.ForwardTo.empty())
703 uint16_t maxOrdinal = 0;
704 for (Export &e : config->exports)
705 maxOrdinal = std::max(maxOrdinal, e.ordinal);
706
707 auto *dllName = make<StringChunk>(sys::path::filename(config->outputFile));
708 auto *addressTab = make<AddressTableChunk>(maxOrdinal);
709 std::vector<Chunk *> names;
710 for (Export &e : config->exports)
711 if (!e.noname)
712 names.push_back(make<StringChunk>(e.exportName));
713
714 std::vector<Chunk *> forwards;
715 for (Export &e : config->exports) {
716 if (e.forwardTo.empty())
626717 continue;
627 E.ForwardChunk = make<StringChunk>(E.ForwardTo);
628 Forwards.push_back(E.ForwardChunk);
629 }
630
631 auto *NameTab = make<NamePointersChunk>(Names);
632 auto *OrdinalTab = make<ExportOrdinalChunk>(Names.size());
633 auto *Dir = make<ExportDirectoryChunk>(MaxOrdinal, Names.size(), DLLName,
634 AddressTab, NameTab, OrdinalTab);
635 Chunks.push_back(Dir);
636 Chunks.push_back(DLLName);
637 Chunks.push_back(AddressTab);
638 Chunks.push_back(NameTab);
639 Chunks.push_back(OrdinalTab);
640 Chunks.insert(Chunks.end(), Names.begin(), Names.end());
641 Chunks.insert(Chunks.end(), Forwards.begin(), Forwards.end());
718 e.forwardChunk = make<StringChunk>(e.forwardTo);
719 forwards.push_back(e.forwardChunk);
720 }
721
722 auto *nameTab = make<NamePointersChunk>(names);
723 auto *ordinalTab = make<ExportOrdinalChunk>(names.size());
724 auto *dir = make<ExportDirectoryChunk>(maxOrdinal, names.size(), dllName,
725 addressTab, nameTab, ordinalTab);
726 chunks.push_back(dir);
727 chunks.push_back(dllName);
728 chunks.push_back(addressTab);
729 chunks.push_back(nameTab);
730 chunks.push_back(ordinalTab);
731 chunks.insert(chunks.end(), names.begin(), names.end());
732 chunks.insert(chunks.end(), forwards.begin(), forwards.end());
642733}
643734
644735} // namespace coff
deps/lld/COFF/DLL.h+30-30
......@@ -1,9 +1,8 @@
11//===- DLL.h ----------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -22,45 +21,46 @@ namespace coff {
2221// call create() to populate the chunk vectors.
2322class IdataContents {
2423public:
25 void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
26 bool empty() { return Imports.empty(); }
24 void add(DefinedImportData *sym) { imports.push_back(sym); }
25 bool empty() { return imports.empty(); }
2726
2827 void create();
2928
30 std::vector<DefinedImportData *> Imports;
31 std::vector<Chunk *> Dirs;
32 std::vector<Chunk *> Lookups;
33 std::vector<Chunk *> Addresses;
34 std::vector<Chunk *> Hints;
35 std::vector<Chunk *> DLLNames;
29 std::vector<DefinedImportData *> imports;
30 std::vector<Chunk *> dirs;
31 std::vector<Chunk *> lookups;
32 std::vector<Chunk *> addresses;
33 std::vector<Chunk *> hints;
34 std::vector<Chunk *> dllNames;
3635};
3736
3837// Windows-specific.
3938// DelayLoadContents creates all chunks for the delay-load DLL import table.
4039class DelayLoadContents {
4140public:
42 void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
43 bool empty() { return Imports.empty(); }
44 void create(Defined *Helper);
41 void add(DefinedImportData *sym) { imports.push_back(sym); }
42 bool empty() { return imports.empty(); }
43 void create(Defined *helper);
4544 std::vector<Chunk *> getChunks();
4645 std::vector<Chunk *> getDataChunks();
47 ArrayRef<Chunk *> getCodeChunks() { return Thunks; }
46 ArrayRef<Chunk *> getCodeChunks() { return thunks; }
4847
49 uint64_t getDirRVA() { return Dirs[0]->getRVA(); }
48 uint64_t getDirRVA() { return dirs[0]->getRVA(); }
5049 uint64_t getDirSize();
5150
5251private:
53 Chunk *newThunkChunk(DefinedImportData *S, Chunk *Dir);
52 Chunk *newThunkChunk(DefinedImportData *s, Chunk *tailMerge);
53 Chunk *newTailMergeChunk(Chunk *dir);
5454
55 Defined *Helper;
56 std::vector<DefinedImportData *> Imports;
57 std::vector<Chunk *> Dirs;
58 std::vector<Chunk *> ModuleHandles;
59 std::vector<Chunk *> Addresses;
60 std::vector<Chunk *> Names;
61 std::vector<Chunk *> HintNames;
62 std::vector<Chunk *> Thunks;
63 std::vector<Chunk *> DLLNames;
55 Defined *helper;
56 std::vector<DefinedImportData *> imports;
57 std::vector<Chunk *> dirs;
58 std::vector<Chunk *> moduleHandles;
59 std::vector<Chunk *> addresses;
60 std::vector<Chunk *> names;
61 std::vector<Chunk *> hintNames;
62 std::vector<Chunk *> thunks;
63 std::vector<Chunk *> dllNames;
6464};
6565
6666// Windows-specific.
......@@ -68,11 +68,11 @@ private:
6868class EdataContents {
6969public:
7070 EdataContents();
71 std::vector<Chunk *> Chunks;
71 std::vector<Chunk *> chunks;
7272
73 uint64_t getRVA() { return Chunks[0]->getRVA(); }
73 uint64_t getRVA() { return chunks[0]->getRVA(); }
7474 uint64_t getSize() {
75 return Chunks.back()->getRVA() + Chunks.back()->getSize() - getRVA();
75 return chunks.back()->getRVA() + chunks.back()->getSize() - getRVA();
7676 }
7777};
7878
deps/lld/COFF/DebugTypes.cpp created+268
......@@ -0,0 +1,268 @@
1//===- DebugTypes.cpp -----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "DebugTypes.h"
10#include "Driver.h"
11#include "InputFiles.h"
12#include "lld/Common/ErrorHandler.h"
13#include "llvm/DebugInfo/CodeView/TypeRecord.h"
14#include "llvm/DebugInfo/PDB/GenericError.h"
15#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
16#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
17#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
18#include "llvm/Support/Path.h"
19
20using namespace lld;
21using namespace lld::coff;
22using namespace llvm;
23using namespace llvm::codeview;
24
25namespace {
26// The TypeServerSource class represents a PDB type server, a file referenced by
27// OBJ files compiled with MSVC /Zi. A single PDB can be shared by several OBJ
28// files, therefore there must be only once instance per OBJ lot. The file path
29// is discovered from the dependent OBJ's debug type stream. The
30// TypeServerSource object is then queued and loaded by the COFF Driver. The
31// debug type stream for such PDB files will be merged first in the final PDB,
32// before any dependent OBJ.
33class TypeServerSource : public TpiSource {
34public:
35 explicit TypeServerSource(MemoryBufferRef m, llvm::pdb::NativeSession *s)
36 : TpiSource(PDB, nullptr), session(s), mb(m) {}
37
38 // Queue a PDB type server for loading in the COFF Driver
39 static void enqueue(const ObjFile *dependentFile,
40 const TypeServer2Record &ts);
41
42 // Create an instance
43 static Expected<TypeServerSource *> getInstance(MemoryBufferRef m);
44
45 // Fetch the PDB instance loaded for a corresponding dependent OBJ.
46 static Expected<TypeServerSource *>
47 findFromFile(const ObjFile *dependentFile);
48
49 static std::map<std::string, std::pair<std::string, TypeServerSource *>>
50 instances;
51
52 // The interface to the PDB (if it was opened successfully)
53 std::unique_ptr<llvm::pdb::NativeSession> session;
54
55private:
56 MemoryBufferRef mb;
57};
58
59// This class represents the debug type stream of an OBJ file that depends on a
60// PDB type server (see TypeServerSource).
61class UseTypeServerSource : public TpiSource {
62public:
63 UseTypeServerSource(const ObjFile *f, const TypeServer2Record *ts)
64 : TpiSource(UsingPDB, f), typeServerDependency(*ts) {}
65
66 // Information about the PDB type server dependency, that needs to be loaded
67 // in before merging this OBJ.
68 TypeServer2Record typeServerDependency;
69};
70
71// This class represents the debug type stream of a Microsoft precompiled
72// headers OBJ (PCH OBJ). This OBJ kind needs to be merged first in the output
73// PDB, before any other OBJs that depend on this. Note that only MSVC generate
74// such files, clang does not.
75class PrecompSource : public TpiSource {
76public:
77 PrecompSource(const ObjFile *f) : TpiSource(PCH, f) {}
78};
79
80// This class represents the debug type stream of an OBJ file that depends on a
81// Microsoft precompiled headers OBJ (see PrecompSource).
82class UsePrecompSource : public TpiSource {
83public:
84 UsePrecompSource(const ObjFile *f, const PrecompRecord *precomp)
85 : TpiSource(UsingPCH, f), precompDependency(*precomp) {}
86
87 // Information about the Precomp OBJ dependency, that needs to be loaded in
88 // before merging this OBJ.
89 PrecompRecord precompDependency;
90};
91} // namespace
92
93static std::vector<std::unique_ptr<TpiSource>> GC;
94
95TpiSource::TpiSource(TpiKind k, const ObjFile *f) : kind(k), file(f) {
96 GC.push_back(std::unique_ptr<TpiSource>(this));
97}
98
99TpiSource *lld::coff::makeTpiSource(const ObjFile *f) {
100 return new TpiSource(TpiSource::Regular, f);
101}
102
103TpiSource *lld::coff::makeUseTypeServerSource(const ObjFile *f,
104 const TypeServer2Record *ts) {
105 TypeServerSource::enqueue(f, *ts);
106 return new UseTypeServerSource(f, ts);
107}
108
109TpiSource *lld::coff::makePrecompSource(const ObjFile *f) {
110 return new PrecompSource(f);
111}
112
113TpiSource *lld::coff::makeUsePrecompSource(const ObjFile *f,
114 const PrecompRecord *precomp) {
115 return new UsePrecompSource(f, precomp);
116}
117
118namespace lld {
119namespace coff {
120template <>
121const PrecompRecord &retrieveDependencyInfo(const TpiSource *source) {
122 assert(source->kind == TpiSource::UsingPCH);
123 return ((const UsePrecompSource *)source)->precompDependency;
124}
125
126template <>
127const TypeServer2Record &retrieveDependencyInfo(const TpiSource *source) {
128 assert(source->kind == TpiSource::UsingPDB);
129 return ((const UseTypeServerSource *)source)->typeServerDependency;
130}
131} // namespace coff
132} // namespace lld
133
134std::map<std::string, std::pair<std::string, TypeServerSource *>>
135 TypeServerSource::instances;
136
137// Make a PDB path assuming the PDB is in the same folder as the OBJ
138static std::string getPdbBaseName(const ObjFile *file, StringRef tSPath) {
139 StringRef localPath =
140 !file->parentName.empty() ? file->parentName : file->getName();
141 SmallString<128> path = sys::path::parent_path(localPath);
142
143 // Currently, type server PDBs are only created by MSVC cl, which only runs
144 // on Windows, so we can assume type server paths are Windows style.
145 sys::path::append(path, sys::path::filename(tSPath, sys::path::Style::windows));
146 return path.str();
147}
148
149// The casing of the PDB path stamped in the OBJ can differ from the actual path
150// on disk. With this, we ensure to always use lowercase as a key for the
151// PDBInputFile::Instances map, at least on Windows.
152static std::string normalizePdbPath(StringRef path) {
153#if defined(_WIN32)
154 return path.lower();
155#else // LINUX
156 return path;
157#endif
158}
159
160// If existing, return the actual PDB path on disk.
161static Optional<std::string> findPdbPath(StringRef pdbPath,
162 const ObjFile *dependentFile) {
163 // Ensure the file exists before anything else. In some cases, if the path
164 // points to a removable device, Driver::enqueuePath() would fail with an
165 // error (EAGAIN, "resource unavailable try again") which we want to skip
166 // silently.
167 if (llvm::sys::fs::exists(pdbPath))
168 return normalizePdbPath(pdbPath);
169 std::string ret = getPdbBaseName(dependentFile, pdbPath);
170 if (llvm::sys::fs::exists(ret))
171 return normalizePdbPath(ret);
172 return None;
173}
174
175// Fetch the PDB instance that was already loaded by the COFF Driver.
176Expected<TypeServerSource *>
177TypeServerSource::findFromFile(const ObjFile *dependentFile) {
178 const TypeServer2Record &ts =
179 retrieveDependencyInfo<TypeServer2Record>(dependentFile->debugTypesObj);
180
181 Optional<std::string> p = findPdbPath(ts.Name, dependentFile);
182 if (!p)
183 return createFileError(ts.Name, errorCodeToError(std::error_code(
184 ENOENT, std::generic_category())));
185
186 auto it = TypeServerSource::instances.find(*p);
187 // The PDB file exists on disk, at this point we expect it to have been
188 // inserted in the map by TypeServerSource::loadPDB()
189 assert(it != TypeServerSource::instances.end());
190
191 std::pair<std::string, TypeServerSource *> &pdb = it->second;
192
193 if (!pdb.second)
194 return createFileError(
195 *p, createStringError(inconvertibleErrorCode(), pdb.first.c_str()));
196
197 pdb::PDBFile &pdbFile = (pdb.second)->session->getPDBFile();
198 pdb::InfoStream &info = cantFail(pdbFile.getPDBInfoStream());
199
200 // Just because a file with a matching name was found doesn't mean it can be
201 // used. The GUID must match between the PDB header and the OBJ
202 // TypeServer2 record. The 'Age' is used by MSVC incremental compilation.
203 if (info.getGuid() != ts.getGuid())
204 return createFileError(
205 ts.Name,
206 make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
207
208 return pdb.second;
209}
210
211// FIXME: Temporary interface until PDBLinker::maybeMergeTypeServerPDB() is
212// moved here.
213Expected<llvm::pdb::NativeSession *>
214lld::coff::findTypeServerSource(const ObjFile *f) {
215 Expected<TypeServerSource *> ts = TypeServerSource::findFromFile(f);
216 if (!ts)
217 return ts.takeError();
218 return ts.get()->session.get();
219}
220
221// Queue a PDB type server for loading in the COFF Driver
222void TypeServerSource::enqueue(const ObjFile *dependentFile,
223 const TypeServer2Record &ts) {
224 // Start by finding where the PDB is located (either the record path or next
225 // to the OBJ file)
226 Optional<std::string> p = findPdbPath(ts.Name, dependentFile);
227 if (!p)
228 return;
229 auto it = TypeServerSource::instances.emplace(
230 *p, std::pair<std::string, TypeServerSource *>{});
231 if (!it.second)
232 return; // another OBJ already scheduled this PDB for load
233
234 driver->enqueuePath(*p, false);
235}
236
237// Create an instance of TypeServerSource or an error string if the PDB couldn't
238// be loaded. The error message will be displayed later, when the referring OBJ
239// will be merged in. NOTE - a PDB load failure is not a link error: some
240// debug info will simply be missing from the final PDB - that is the default
241// accepted behavior.
242void lld::coff::loadTypeServerSource(llvm::MemoryBufferRef m) {
243 std::string path = normalizePdbPath(m.getBufferIdentifier());
244
245 Expected<TypeServerSource *> ts = TypeServerSource::getInstance(m);
246 if (!ts)
247 TypeServerSource::instances[path] = {toString(ts.takeError()), nullptr};
248 else
249 TypeServerSource::instances[path] = {{}, *ts};
250}
251
252Expected<TypeServerSource *> TypeServerSource::getInstance(MemoryBufferRef m) {
253 std::unique_ptr<llvm::pdb::IPDBSession> iSession;
254 Error err = pdb::NativeSession::createFromPdb(
255 MemoryBuffer::getMemBuffer(m, false), iSession);
256 if (err)
257 return std::move(err);
258
259 std::unique_ptr<llvm::pdb::NativeSession> session(
260 static_cast<pdb::NativeSession *>(iSession.release()));
261
262 pdb::PDBFile &pdbFile = session->getPDBFile();
263 Expected<pdb::InfoStream &> info = pdbFile.getPDBInfoStream();
264 // All PDB Files should have an Info stream.
265 if (!info)
266 return info.takeError();
267 return new TypeServerSource(m, session.release());
268}
deps/lld/COFF/DebugTypes.h created+60
......@@ -0,0 +1,60 @@
1//===- DebugTypes.h ---------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLD_COFF_DEBUGTYPES_H
10#define LLD_COFF_DEBUGTYPES_H
11
12#include "llvm/Support/Error.h"
13#include "llvm/Support/MemoryBuffer.h"
14
15namespace llvm {
16namespace codeview {
17class PrecompRecord;
18class TypeServer2Record;
19} // namespace codeview
20namespace pdb {
21class NativeSession;
22}
23} // namespace llvm
24
25namespace lld {
26namespace coff {
27
28class ObjFile;
29
30class TpiSource {
31public:
32 enum TpiKind { Regular, PCH, UsingPCH, PDB, UsingPDB };
33
34 TpiSource(TpiKind k, const ObjFile *f);
35 virtual ~TpiSource() {}
36
37 const TpiKind kind;
38 const ObjFile *file;
39};
40
41TpiSource *makeTpiSource(const ObjFile *f);
42TpiSource *makeUseTypeServerSource(const ObjFile *f,
43 const llvm::codeview::TypeServer2Record *ts);
44TpiSource *makePrecompSource(const ObjFile *f);
45TpiSource *makeUsePrecompSource(const ObjFile *f,
46 const llvm::codeview::PrecompRecord *precomp);
47
48void loadTypeServerSource(llvm::MemoryBufferRef m);
49
50// Temporary interface to get the dependency
51template <typename T> const T &retrieveDependencyInfo(const TpiSource *source);
52
53// Temporary interface until we move PDBLinker::maybeMergeTypeServerPDB here
54llvm::Expected<llvm::pdb::NativeSession *>
55findTypeServerSource(const ObjFile *f);
56
57} // namespace coff
58} // namespace lld
59
60#endif
\ No newline at end of file
deps/lld/COFF/Driver.cpp+1066-856
......@@ -1,14 +1,14 @@
11//===- Driver.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
109#include "Driver.h"
1110#include "Config.h"
11#include "DebugTypes.h"
1212#include "ICF.h"
1313#include "InputFiles.h"
1414#include "MarkLive.h"
......@@ -19,7 +19,9 @@
1919#include "lld/Common/Args.h"
2020#include "lld/Common/Driver.h"
2121#include "lld/Common/ErrorHandler.h"
22#include "lld/Common/Filesystem.h"
2223#include "lld/Common/Memory.h"
24#include "lld/Common/Threads.h"
2325#include "lld/Common/Timer.h"
2426#include "lld/Common/Version.h"
2527#include "llvm/ADT/Optional.h"
......@@ -28,6 +30,7 @@
2830#include "llvm/Object/ArchiveWriter.h"
2931#include "llvm/Object/COFFImportFile.h"
3032#include "llvm/Object/COFFModuleDefinition.h"
33#include "llvm/Object/WindowsMachineFlag.h"
3134#include "llvm/Option/Arg.h"
3235#include "llvm/Option/ArgList.h"
3336#include "llvm/Option/Option.h"
......@@ -51,43 +54,68 @@ using llvm::sys::Process;
5154namespace lld {
5255namespace coff {
5356
54static Timer InputFileTimer("Input File Reading", Timer::root());
57static Timer inputFileTimer("Input File Reading", Timer::root());
5558
56Configuration *Config;
57LinkerDriver *Driver;
59Configuration *config;
60LinkerDriver *driver;
5861
59bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {
60 errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
61 errorHandler().ErrorOS = &Diag;
62 errorHandler().ColorDiagnostics = Diag.has_colors();
63 errorHandler().ErrorLimitExceededMsg =
62bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &diag) {
63 errorHandler().logName = args::getFilenameWithoutExe(args[0]);
64 errorHandler().errorOS = &diag;
65 errorHandler().colorDiagnostics = diag.has_colors();
66 errorHandler().errorLimitExceededMsg =
6467 "too many errors emitted, stopping now"
6568 " (use /errorlimit:0 to see all errors)";
66 errorHandler().ExitEarly = CanExitEarly;
67 Config = make<Configuration>();
69 errorHandler().exitEarly = canExitEarly;
70 config = make<Configuration>();
6871
69 Symtab = make<SymbolTable>();
72 symtab = make<SymbolTable>();
7073
71 Driver = make<LinkerDriver>();
72 Driver->link(Args);
74 driver = make<LinkerDriver>();
75 driver->link(args);
7376
7477 // Call exit() if we can to avoid calling destructors.
75 if (CanExitEarly)
78 if (canExitEarly)
7679 exitLld(errorCount() ? 1 : 0);
7780
7881 freeArena();
79 ObjFile::Instances.clear();
80 ImportFile::Instances.clear();
81 BitcodeFile::Instances.clear();
82 ObjFile::instances.clear();
83 ImportFile::instances.clear();
84 BitcodeFile::instances.clear();
85 memset(MergeChunk::instances, 0, sizeof(MergeChunk::instances));
8286 return !errorCount();
8387}
8488
89// Parse options of the form "old;new".
90static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
91 unsigned id) {
92 auto *arg = args.getLastArg(id);
93 if (!arg)
94 return {"", ""};
95
96 StringRef s = arg->getValue();
97 std::pair<StringRef, StringRef> ret = s.split(';');
98 if (ret.second.empty())
99 error(arg->getSpelling() + " expects 'old;new' format, but got " + s);
100 return ret;
101}
102
85103// Drop directory components and replace extension with ".exe" or ".dll".
86static std::string getOutputPath(StringRef Path) {
87 auto P = Path.find_last_of("\\/");
88 StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1);
89 const char* E = Config->DLL ? ".dll" : ".exe";
90 return (S.substr(0, S.rfind('.')) + E).str();
104static std::string getOutputPath(StringRef path) {
105 auto p = path.find_last_of("\\/");
106 StringRef s = (p == StringRef::npos) ? path : path.substr(p + 1);
107 const char* e = config->dll ? ".dll" : ".exe";
108 return (s.substr(0, s.rfind('.')) + e).str();
109}
110
111// Returns true if S matches /crtend.?\.o$/.
112static bool isCrtend(StringRef s) {
113 if (!s.endswith(".o"))
114 return false;
115 s = s.drop_back(2);
116 if (s.endswith("crtend"))
117 return true;
118 return !s.empty() && s.drop_back().endswith("crtend");
91119}
92120
93121// ErrorOr is not default constructible, so it cannot be used as the type
......@@ -95,347 +123,401 @@ static std::string getOutputPath(StringRef Path) {
95123// FIXME: We could open the file in createFutureForFile and avoid needing to
96124// return an error here, but for the moment that would cost us a file descriptor
97125// (a limited resource on Windows) for the duration that the future is pending.
98typedef std::pair<std::unique_ptr<MemoryBuffer>, std::error_code> MBErrPair;
126using MBErrPair = std::pair<std::unique_ptr<MemoryBuffer>, std::error_code>;
99127
100128// Create a std::future that opens and maps a file using the best strategy for
101129// the host platform.
102static std::future<MBErrPair> createFutureForFile(std::string Path) {
130static std::future<MBErrPair> createFutureForFile(std::string path) {
103131#if _WIN32
104132 // On Windows, file I/O is relatively slow so it is best to do this
105133 // asynchronously.
106 auto Strategy = std::launch::async;
134 auto strategy = std::launch::async;
107135#else
108 auto Strategy = std::launch::deferred;
136 auto strategy = std::launch::deferred;
109137#endif
110 return std::async(Strategy, [=]() {
111 auto MBOrErr = MemoryBuffer::getFile(Path,
138 return std::async(strategy, [=]() {
139 auto mbOrErr = MemoryBuffer::getFile(path,
112140 /*FileSize*/ -1,
113141 /*RequiresNullTerminator*/ false);
114 if (!MBOrErr)
115 return MBErrPair{nullptr, MBOrErr.getError()};
116 return MBErrPair{std::move(*MBOrErr), std::error_code()};
142 if (!mbOrErr)
143 return MBErrPair{nullptr, mbOrErr.getError()};
144 return MBErrPair{std::move(*mbOrErr), std::error_code()};
117145 });
118146}
119147
120148// Symbol names are mangled by prepending "_" on x86.
121static StringRef mangle(StringRef Sym) {
122 assert(Config->Machine != IMAGE_FILE_MACHINE_UNKNOWN);
123 if (Config->Machine == I386)
124 return Saver.save("_" + Sym);
125 return Sym;
149static StringRef mangle(StringRef sym) {
150 assert(config->machine != IMAGE_FILE_MACHINE_UNKNOWN);
151 if (config->machine == I386)
152 return saver.save("_" + sym);
153 return sym;
126154}
127155
128static bool findUnderscoreMangle(StringRef Sym) {
129 StringRef Entry = Symtab->findMangle(mangle(Sym));
130 return !Entry.empty() && !isa<Undefined>(Symtab->find(Entry));
156static bool findUnderscoreMangle(StringRef sym) {
157 Symbol *s = symtab->findMangle(mangle(sym));
158 return s && !isa<Undefined>(s);
131159}
132160
133MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) {
134 MemoryBufferRef MBRef = *MB;
135 make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take ownership
161MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> mb) {
162 MemoryBufferRef mbref = *mb;
163 make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take ownership
136164
137 if (Driver->Tar)
138 Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()),
139 MBRef.getBuffer());
140 return MBRef;
165 if (driver->tar)
166 driver->tar->append(relativeToRoot(mbref.getBufferIdentifier()),
167 mbref.getBuffer());
168 return mbref;
141169}
142170
143void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB,
144 bool WholeArchive) {
145 StringRef Filename = MB->getBufferIdentifier();
171void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
172 bool wholeArchive) {
173 StringRef filename = mb->getBufferIdentifier();
146174
147 MemoryBufferRef MBRef = takeBuffer(std::move(MB));
148 FilePaths.push_back(Filename);
175 MemoryBufferRef mbref = takeBuffer(std::move(mb));
176 filePaths.push_back(filename);
149177
150178 // File type is detected by contents, not by file extension.
151 switch (identify_magic(MBRef.getBuffer())) {
179 switch (identify_magic(mbref.getBuffer())) {
152180 case file_magic::windows_resource:
153 Resources.push_back(MBRef);
181 resources.push_back(mbref);
154182 break;
155183 case file_magic::archive:
156 if (WholeArchive) {
157 std::unique_ptr<Archive> File =
158 CHECK(Archive::create(MBRef), Filename + ": failed to parse archive");
184 if (wholeArchive) {
185 std::unique_ptr<Archive> file =
186 CHECK(Archive::create(mbref), filename + ": failed to parse archive");
159187
160 for (MemoryBufferRef M : getArchiveMembers(File.get()))
161 addArchiveBuffer(M, "<whole-archive>", Filename);
188 for (MemoryBufferRef m : getArchiveMembers(file.get()))
189 addArchiveBuffer(m, "<whole-archive>", filename, 0);
162190 return;
163191 }
164 Symtab->addFile(make<ArchiveFile>(MBRef));
192 symtab->addFile(make<ArchiveFile>(mbref));
165193 break;
166194 case file_magic::bitcode:
167 Symtab->addFile(make<BitcodeFile>(MBRef));
195 symtab->addFile(make<BitcodeFile>(mbref, "", 0));
168196 break;
169197 case file_magic::coff_object:
170198 case file_magic::coff_import_library:
171 Symtab->addFile(make<ObjFile>(MBRef));
199 symtab->addFile(make<ObjFile>(mbref));
200 break;
201 case file_magic::pdb:
202 loadTypeServerSource(mbref);
172203 break;
173204 case file_magic::coff_cl_gl_object:
174 error(Filename + ": is not a native COFF file. Recompile without /GL");
205 error(filename + ": is not a native COFF file. Recompile without /GL");
175206 break;
176207 case file_magic::pecoff_executable:
177 if (Filename.endswith_lower(".dll")) {
178 error(Filename + ": bad file type. Did you specify a DLL instead of an "
208 if (filename.endswith_lower(".dll")) {
209 error(filename + ": bad file type. Did you specify a DLL instead of an "
179210 "import library?");
180211 break;
181212 }
182213 LLVM_FALLTHROUGH;
183214 default:
184 error(MBRef.getBufferIdentifier() + ": unknown file type");
215 error(mbref.getBufferIdentifier() + ": unknown file type");
185216 break;
186217 }
187218}
188219
189void LinkerDriver::enqueuePath(StringRef Path, bool WholeArchive) {
190 auto Future =
191 std::make_shared<std::future<MBErrPair>>(createFutureForFile(Path));
192 std::string PathStr = Path;
220void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive) {
221 auto future =
222 std::make_shared<std::future<MBErrPair>>(createFutureForFile(path));
223 std::string pathStr = path;
193224 enqueueTask([=]() {
194 auto MBOrErr = Future->get();
195 if (MBOrErr.second)
196 error("could not open " + PathStr + ": " + MBOrErr.second.message());
197 else
198 Driver->addBuffer(std::move(MBOrErr.first), WholeArchive);
225 auto mbOrErr = future->get();
226 if (mbOrErr.second) {
227 std::string msg =
228 "could not open '" + pathStr + "': " + mbOrErr.second.message();
229 // Check if the filename is a typo for an option flag. OptTable thinks
230 // that all args that are not known options and that start with / are
231 // filenames, but e.g. `/nodefaultlibs` is more likely a typo for
232 // the option `/nodefaultlib` than a reference to a file in the root
233 // directory.
234 std::string nearest;
235 if (COFFOptTable().findNearest(pathStr, nearest) > 1)
236 error(msg);
237 else
238 error(msg + "; did you mean '" + nearest + "'");
239 } else
240 driver->addBuffer(std::move(mbOrErr.first), wholeArchive);
199241 });
200242}
201243
202void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName,
203 StringRef ParentName) {
204 file_magic Magic = identify_magic(MB.getBuffer());
205 if (Magic == file_magic::coff_import_library) {
206 Symtab->addFile(make<ImportFile>(MB));
244void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
245 StringRef parentName,
246 uint64_t offsetInArchive) {
247 file_magic magic = identify_magic(mb.getBuffer());
248 if (magic == file_magic::coff_import_library) {
249 InputFile *imp = make<ImportFile>(mb);
250 imp->parentName = parentName;
251 symtab->addFile(imp);
207252 return;
208253 }
209254
210 InputFile *Obj;
211 if (Magic == file_magic::coff_object) {
212 Obj = make<ObjFile>(MB);
213 } else if (Magic == file_magic::bitcode) {
214 Obj = make<BitcodeFile>(MB);
255 InputFile *obj;
256 if (magic == file_magic::coff_object) {
257 obj = make<ObjFile>(mb);
258 } else if (magic == file_magic::bitcode) {
259 obj = make<BitcodeFile>(mb, parentName, offsetInArchive);
215260 } else {
216 error("unknown file type: " + MB.getBufferIdentifier());
261 error("unknown file type: " + mb.getBufferIdentifier());
217262 return;
218263 }
219264
220 Obj->ParentName = ParentName;
221 Symtab->addFile(Obj);
222 log("Loaded " + toString(Obj) + " for " + SymName);
265 obj->parentName = parentName;
266 symtab->addFile(obj);
267 log("Loaded " + toString(obj) + " for " + symName);
223268}
224269
225void LinkerDriver::enqueueArchiveMember(const Archive::Child &C,
226 StringRef SymName,
227 StringRef ParentName) {
228 if (!C.getParent()->isThin()) {
229 MemoryBufferRef MB = CHECK(
230 C.getMemoryBufferRef(),
231 "could not get the buffer for the member defining symbol " + SymName);
232 enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); });
270void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
271 StringRef symName,
272 StringRef parentName) {
273
274 auto reportBufferError = [=](Error &&e,
275 StringRef childName) {
276 fatal("could not get the buffer for the member defining symbol " +
277 symName + ": " + parentName + "(" + childName + "): " +
278 toString(std::move(e)));
279 };
280
281 if (!c.getParent()->isThin()) {
282 uint64_t offsetInArchive = c.getChildOffset();
283 Expected<MemoryBufferRef> mbOrErr = c.getMemoryBufferRef();
284 if (!mbOrErr)
285 reportBufferError(mbOrErr.takeError(), check(c.getFullName()));
286 MemoryBufferRef mb = mbOrErr.get();
287 enqueueTask([=]() {
288 driver->addArchiveBuffer(mb, symName, parentName, offsetInArchive);
289 });
233290 return;
234291 }
235292
236 auto Future = std::make_shared<std::future<MBErrPair>>(createFutureForFile(
237 CHECK(C.getFullName(),
238 "could not get the filename for the member defining symbol " +
239 SymName)));
293 std::string childName = CHECK(
294 c.getFullName(),
295 "could not get the filename for the member defining symbol " +
296 symName);
297 auto future = std::make_shared<std::future<MBErrPair>>(
298 createFutureForFile(childName));
240299 enqueueTask([=]() {
241 auto MBOrErr = Future->get();
242 if (MBOrErr.second)
243 fatal("could not get the buffer for the member defining " + SymName +
244 ": " + MBOrErr.second.message());
245 Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName,
246 ParentName);
300 auto mbOrErr = future->get();
301 if (mbOrErr.second)
302 reportBufferError(errorCodeToError(mbOrErr.second), childName);
303 driver->addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)), symName,
304 parentName, /* OffsetInArchive */ 0);
247305 });
248306}
249307
250static bool isDecorated(StringRef Sym) {
251 return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") ||
252 (!Config->MinGW && Sym.contains('@'));
308static bool isDecorated(StringRef sym) {
309 return sym.startswith("@") || sym.contains("@@") || sym.startswith("?") ||
310 (!config->mingw && sym.contains('@'));
253311}
254312
255313// Parses .drectve section contents and returns a list of files
256314// specified by /defaultlib.
257void LinkerDriver::parseDirectives(StringRef S) {
258 ArgParser Parser;
315void LinkerDriver::parseDirectives(InputFile *file) {
316 StringRef s = file->getDirectives();
317 if (s.empty())
318 return;
319
320 log("Directives: " + toString(file) + ": " + s);
321
322 ArgParser parser;
259323 // .drectve is always tokenized using Windows shell rules.
260324 // /EXPORT: option can appear too many times, processing in fastpath.
261 opt::InputArgList Args;
262 std::vector<StringRef> Exports;
263 std::tie(Args, Exports) = Parser.parseDirectives(S);
325 opt::InputArgList args;
326 std::vector<StringRef> exports;
327 std::tie(args, exports) = parser.parseDirectives(s);
264328
265 for (StringRef E : Exports) {
329 for (StringRef e : exports) {
266330 // If a common header file contains dllexported function
267331 // declarations, many object files may end up with having the
268332 // same /EXPORT options. In order to save cost of parsing them,
269333 // we dedup them first.
270 if (!DirectivesExports.insert(E).second)
334 if (!directivesExports.insert(e).second)
271335 continue;
272336
273 Export Exp = parseExport(E);
274 if (Config->Machine == I386 && Config->MinGW) {
275 if (!isDecorated(Exp.Name))
276 Exp.Name = Saver.save("_" + Exp.Name);
277 if (!Exp.ExtName.empty() && !isDecorated(Exp.ExtName))
278 Exp.ExtName = Saver.save("_" + Exp.ExtName);
337 Export exp = parseExport(e);
338 if (config->machine == I386 && config->mingw) {
339 if (!isDecorated(exp.name))
340 exp.name = saver.save("_" + exp.name);
341 if (!exp.extName.empty() && !isDecorated(exp.extName))
342 exp.extName = saver.save("_" + exp.extName);
279343 }
280 Exp.Directives = true;
281 Config->Exports.push_back(Exp);
344 exp.directives = true;
345 config->exports.push_back(exp);
282346 }
283347
284 for (auto *Arg : Args) {
285 switch (Arg->getOption().getUnaliasedOption().getID()) {
348 for (auto *arg : args) {
349 switch (arg->getOption().getID()) {
286350 case OPT_aligncomm:
287 parseAligncomm(Arg->getValue());
351 parseAligncomm(arg->getValue());
288352 break;
289353 case OPT_alternatename:
290 parseAlternateName(Arg->getValue());
354 parseAlternateName(arg->getValue());
291355 break;
292356 case OPT_defaultlib:
293 if (Optional<StringRef> Path = findLib(Arg->getValue()))
294 enqueuePath(*Path, false);
357 if (Optional<StringRef> path = findLib(arg->getValue()))
358 enqueuePath(*path, false);
295359 break;
296360 case OPT_entry:
297 Config->Entry = addUndefined(mangle(Arg->getValue()));
361 config->entry = addUndefined(mangle(arg->getValue()));
298362 break;
299363 case OPT_failifmismatch:
300 checkFailIfMismatch(Arg->getValue());
364 checkFailIfMismatch(arg->getValue(), file);
301365 break;
302366 case OPT_incl:
303 addUndefined(Arg->getValue());
367 addUndefined(arg->getValue());
304368 break;
305369 case OPT_merge:
306 parseMerge(Arg->getValue());
370 parseMerge(arg->getValue());
307371 break;
308372 case OPT_nodefaultlib:
309 Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()));
373 config->noDefaultLibs.insert(doFindLib(arg->getValue()).lower());
310374 break;
311375 case OPT_section:
312 parseSection(Arg->getValue());
376 parseSection(arg->getValue());
313377 break;
314378 case OPT_subsystem:
315 parseSubsystem(Arg->getValue(), &Config->Subsystem,
316 &Config->MajorOSVersion, &Config->MinorOSVersion);
379 parseSubsystem(arg->getValue(), &config->subsystem,
380 &config->majorOSVersion, &config->minorOSVersion);
317381 break;
382 // Only add flags here that link.exe accepts in
383 // `#pragma comment(linker, "/flag")`-generated sections.
318384 case OPT_editandcontinue:
319 case OPT_fastfail:
320385 case OPT_guardsym:
321 case OPT_natvis:
322386 case OPT_throwingnew:
323387 break;
324388 default:
325 error(Arg->getSpelling() + " is not allowed in .drectve");
389 error(arg->getSpelling() + " is not allowed in .drectve");
326390 }
327391 }
328392}
329393
330394// Find file from search paths. You can omit ".obj", this function takes
331395// care of that. Note that the returned path is not guaranteed to exist.
332StringRef LinkerDriver::doFindFile(StringRef Filename) {
333 bool HasPathSep = (Filename.find_first_of("/\\") != StringRef::npos);
334 if (HasPathSep)
335 return Filename;
336 bool HasExt = Filename.contains('.');
337 for (StringRef Dir : SearchPaths) {
338 SmallString<128> Path = Dir;
339 sys::path::append(Path, Filename);
340 if (sys::fs::exists(Path.str()))
341 return Saver.save(Path.str());
342 if (!HasExt) {
343 Path.append(".obj");
344 if (sys::fs::exists(Path.str()))
345 return Saver.save(Path.str());
396StringRef LinkerDriver::doFindFile(StringRef filename) {
397 bool hasPathSep = (filename.find_first_of("/\\") != StringRef::npos);
398 if (hasPathSep)
399 return filename;
400 bool hasExt = filename.contains('.');
401 for (StringRef dir : searchPaths) {
402 SmallString<128> path = dir;
403 sys::path::append(path, filename);
404 if (sys::fs::exists(path.str()))
405 return saver.save(path.str());
406 if (!hasExt) {
407 path.append(".obj");
408 if (sys::fs::exists(path.str()))
409 return saver.save(path.str());
346410 }
347411 }
348 return Filename;
412 return filename;
349413}
350414
351static Optional<sys::fs::UniqueID> getUniqueID(StringRef Path) {
352 sys::fs::UniqueID Ret;
353 if (sys::fs::getUniqueID(Path, Ret))
415static Optional<sys::fs::UniqueID> getUniqueID(StringRef path) {
416 sys::fs::UniqueID ret;
417 if (sys::fs::getUniqueID(path, ret))
354418 return None;
355 return Ret;
419 return ret;
356420}
357421
358422// Resolves a file path. This never returns the same path
359423// (in that case, it returns None).
360Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {
361 StringRef Path = doFindFile(Filename);
424Optional<StringRef> LinkerDriver::findFile(StringRef filename) {
425 StringRef path = doFindFile(filename);
362426
363 if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) {
364 bool Seen = !VisitedFiles.insert(*ID).second;
365 if (Seen)
427 if (Optional<sys::fs::UniqueID> id = getUniqueID(path)) {
428 bool seen = !visitedFiles.insert(*id).second;
429 if (seen)
366430 return None;
367431 }
368432
369 if (Path.endswith_lower(".lib"))
370 VisitedLibs.insert(sys::path::filename(Path));
371 return Path;
433 if (path.endswith_lower(".lib"))
434 visitedLibs.insert(sys::path::filename(path));
435 return path;
372436}
373437
374438// MinGW specific. If an embedded directive specified to link to
375439// 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);
440StringRef LinkerDriver::doFindLibMinGW(StringRef filename) {
441 if (filename.contains('/') || filename.contains('\\'))
442 return filename;
443
444 SmallString<128> s = filename;
445 sys::path::replace_extension(s, ".a");
446 StringRef libName = saver.save("lib" + s.str());
447 return doFindFile(libName);
384448}
385449
386450// Find library file from search path.
387StringRef LinkerDriver::doFindLib(StringRef Filename) {
451StringRef LinkerDriver::doFindLib(StringRef filename) {
388452 // Add ".lib" to Filename if that has no file extension.
389 bool HasExt = Filename.contains('.');
390 if (!HasExt)
391 Filename = Saver.save(Filename + ".lib");
392 StringRef Ret = doFindFile(Filename);
453 bool hasExt = filename.contains('.');
454 if (!hasExt)
455 filename = saver.save(filename + ".lib");
456 StringRef ret = doFindFile(filename);
393457 // For MinGW, if the find above didn't turn up anything, try
394458 // looking for a MinGW formatted library name.
395 if (Config->MinGW && Ret == Filename)
396 return doFindLibMinGW(Filename);
397 return Ret;
459 if (config->mingw && ret == filename)
460 return doFindLibMinGW(filename);
461 return ret;
398462}
399463
400464// Resolves a library path. /nodefaultlib options are taken into
401465// consideration. This never returns the same path (in that case,
402466// it returns None).
403Optional<StringRef> LinkerDriver::findLib(StringRef Filename) {
404 if (Config->NoDefaultLibAll)
467Optional<StringRef> LinkerDriver::findLib(StringRef filename) {
468 if (config->noDefaultLibAll)
405469 return None;
406 if (!VisitedLibs.insert(Filename.lower()).second)
470 if (!visitedLibs.insert(filename.lower()).second)
407471 return None;
408472
409 StringRef Path = doFindLib(Filename);
410 if (Config->NoDefaultLibs.count(Path))
473 StringRef path = doFindLib(filename);
474 if (config->noDefaultLibs.count(path.lower()))
411475 return None;
412476
413 if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path))
414 if (!VisitedFiles.insert(*ID).second)
477 if (Optional<sys::fs::UniqueID> id = getUniqueID(path))
478 if (!visitedFiles.insert(*id).second)
415479 return None;
416 return Path;
480 return path;
417481}
418482
419483// Parses LIB environment which contains a list of search paths.
420484void LinkerDriver::addLibSearchPaths() {
421 Optional<std::string> EnvOpt = Process::GetEnv("LIB");
422 if (!EnvOpt.hasValue())
485 Optional<std::string> envOpt = Process::GetEnv("LIB");
486 if (!envOpt.hasValue())
423487 return;
424 StringRef Env = Saver.save(*EnvOpt);
425 while (!Env.empty()) {
426 StringRef Path;
427 std::tie(Path, Env) = Env.split(';');
428 SearchPaths.push_back(Path);
488 StringRef env = saver.save(*envOpt);
489 while (!env.empty()) {
490 StringRef path;
491 std::tie(path, env) = env.split(';');
492 searchPaths.push_back(path);
429493 }
430494}
431495
432Symbol *LinkerDriver::addUndefined(StringRef Name) {
433 Symbol *B = Symtab->addUndefined(Name);
434 if (!B->IsGCRoot) {
435 B->IsGCRoot = true;
436 Config->GCRoot.push_back(B);
496Symbol *LinkerDriver::addUndefined(StringRef name) {
497 Symbol *b = symtab->addUndefined(name);
498 if (!b->isGCRoot) {
499 b->isGCRoot = true;
500 config->gcroot.push_back(b);
437501 }
438 return B;
502 return b;
503}
504
505StringRef LinkerDriver::mangleMaybe(Symbol *s) {
506 // If the plain symbol name has already been resolved, do nothing.
507 Undefined *unmangled = dyn_cast<Undefined>(s);
508 if (!unmangled)
509 return "";
510
511 // Otherwise, see if a similar, mangled symbol exists in the symbol table.
512 Symbol *mangled = symtab->findMangle(unmangled->getName());
513 if (!mangled)
514 return "";
515
516 // If we find a similar mangled symbol, make this an alias to it and return
517 // its name.
518 log(unmangled->getName() + " aliased to " + mangled->getName());
519 unmangled->weakAlias = symtab->addUndefined(mangled->getName());
520 return mangled->getName();
439521}
440522
441523// Windows specific -- find default entry point name.
......@@ -444,15 +526,15 @@ Symbol *LinkerDriver::addUndefined(StringRef Name) {
444526// each of which corresponds to a user-defined "main" function. This function
445527// infers an entry point from a user-defined "main" function.
446528StringRef LinkerDriver::findDefaultEntry() {
447 assert(Config->Subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&
529 assert(config->subsystem != IMAGE_SUBSYSTEM_UNKNOWN &&
448530 "must handle /subsystem before calling this");
449531
450 if (Config->MinGW)
451 return mangle(Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI
532 if (config->mingw)
533 return mangle(config->subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI
452534 ? "WinMainCRTStartup"
453535 : "mainCRTStartup");
454536
455 if (Config->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
537 if (config->subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
456538 if (findUnderscoreMangle("wWinMain")) {
457539 if (!findUnderscoreMangle("WinMain"))
458540 return mangle("wWinMainCRTStartup");
......@@ -469,44 +551,44 @@ StringRef LinkerDriver::findDefaultEntry() {
469551}
470552
471553WindowsSubsystem LinkerDriver::inferSubsystem() {
472 if (Config->DLL)
554 if (config->dll)
473555 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
474 if (Config->MinGW)
556 if (config->mingw)
475557 return IMAGE_SUBSYSTEM_WINDOWS_CUI;
476558 // Note that link.exe infers the subsystem from the presence of these
477559 // functions even if /entry: or /nodefaultlib are passed which causes them
478560 // 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") +
561 bool haveMain = findUnderscoreMangle("main");
562 bool haveWMain = findUnderscoreMangle("wmain");
563 bool haveWinMain = findUnderscoreMangle("WinMain");
564 bool haveWWinMain = findUnderscoreMangle("wWinMain");
565 if (haveMain || haveWMain) {
566 if (haveWinMain || haveWWinMain) {
567 warn(std::string("found ") + (haveMain ? "main" : "wmain") + " and " +
568 (haveWinMain ? "WinMain" : "wWinMain") +
487569 "; defaulting to /subsystem:console");
488570 }
489571 return IMAGE_SUBSYSTEM_WINDOWS_CUI;
490572 }
491 if (HaveWinMain || HaveWWinMain)
573 if (haveWinMain || haveWWinMain)
492574 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
493575 return IMAGE_SUBSYSTEM_UNKNOWN;
494576}
495577
496578static uint64_t getDefaultImageBase() {
497 if (Config->is64())
498 return Config->DLL ? 0x180000000 : 0x140000000;
499 return Config->DLL ? 0x10000000 : 0x400000;
579 if (config->is64())
580 return config->dll ? 0x180000000 : 0x140000000;
581 return config->dll ? 0x10000000 : 0x400000;
500582}
501583
502static std::string createResponseFile(const opt::InputArgList &Args,
503 ArrayRef<StringRef> FilePaths,
504 ArrayRef<StringRef> SearchPaths) {
505 SmallString<0> Data;
506 raw_svector_ostream OS(Data);
584static std::string createResponseFile(const opt::InputArgList &args,
585 ArrayRef<StringRef> filePaths,
586 ArrayRef<StringRef> searchPaths) {
587 SmallString<0> data;
588 raw_svector_ostream os(data);
507589
508 for (auto *Arg : Args) {
509 switch (Arg->getOption().getID()) {
590 for (auto *arg : args) {
591 switch (arg->getOption().getID()) {
510592 case OPT_linkrepro:
511593 case OPT_INPUT:
512594 case OPT_defaultlib:
......@@ -518,32 +600,37 @@ static std::string createResponseFile(const opt::InputArgList &Args,
518600 case OPT_manifestinput:
519601 case OPT_manifestuac:
520602 break;
603 case OPT_implib:
604 case OPT_pdb:
605 case OPT_out:
606 os << arg->getSpelling() << sys::path::filename(arg->getValue()) << "\n";
607 break;
521608 default:
522 OS << toString(*Arg) << "\n";
609 os << toString(*arg) << "\n";
523610 }
524611 }
525612
526 for (StringRef Path : SearchPaths) {
527 std::string RelPath = relativeToRoot(Path);
528 OS << "/libpath:" << quote(RelPath) << "\n";
613 for (StringRef path : searchPaths) {
614 std::string relPath = relativeToRoot(path);
615 os << "/libpath:" << quote(relPath) << "\n";
529616 }
530617
531 for (StringRef Path : FilePaths)
532 OS << quote(relativeToRoot(Path)) << "\n";
618 for (StringRef path : filePaths)
619 os << quote(relativeToRoot(path)) << "\n";
533620
534 return Data.str();
621 return data.str();
535622}
536623
537624enum class DebugKind { Unknown, None, Full, FastLink, GHash, Dwarf, Symtab };
538625
539static DebugKind parseDebugKind(const opt::InputArgList &Args) {
540 auto *A = Args.getLastArg(OPT_debug, OPT_debug_opt);
541 if (!A)
626static DebugKind parseDebugKind(const opt::InputArgList &args) {
627 auto *a = args.getLastArg(OPT_debug, OPT_debug_opt);
628 if (!a)
542629 return DebugKind::None;
543 if (A->getNumValues() == 0)
630 if (a->getNumValues() == 0)
544631 return DebugKind::Full;
545632
546 DebugKind Debug = StringSwitch<DebugKind>(A->getValue())
633 DebugKind debug = StringSwitch<DebugKind>(a->getValue())
547634 .CaseLower("none", DebugKind::None)
548635 .CaseLower("full", DebugKind::Full)
549636 .CaseLower("fastlink", DebugKind::FastLink)
......@@ -553,67 +640,68 @@ static DebugKind parseDebugKind(const opt::InputArgList &Args) {
553640 .CaseLower("symtab", DebugKind::Symtab)
554641 .Default(DebugKind::Unknown);
555642
556 if (Debug == DebugKind::FastLink) {
643 if (debug == DebugKind::FastLink) {
557644 warn("/debug:fastlink unsupported; using /debug:full");
558645 return DebugKind::Full;
559646 }
560 if (Debug == DebugKind::Unknown) {
561 error("/debug: unknown option: " + Twine(A->getValue()));
647 if (debug == DebugKind::Unknown) {
648 error("/debug: unknown option: " + Twine(a->getValue()));
562649 return DebugKind::None;
563650 }
564 return Debug;
651 return debug;
565652}
566653
567static unsigned parseDebugTypes(const opt::InputArgList &Args) {
568 unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
654static unsigned parseDebugTypes(const opt::InputArgList &args) {
655 unsigned debugTypes = static_cast<unsigned>(DebugType::None);
569656
570 if (auto *A = Args.getLastArg(OPT_debugtype)) {
571 SmallVector<StringRef, 3> Types;
572 A->getSpelling().split(Types, ',', /*KeepEmpty=*/false);
657 if (auto *a = args.getLastArg(OPT_debugtype)) {
658 SmallVector<StringRef, 3> types;
659 StringRef(a->getValue())
660 .split(types, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
573661
574 for (StringRef Type : Types) {
575 unsigned V = StringSwitch<unsigned>(Type.lower())
662 for (StringRef type : types) {
663 unsigned v = StringSwitch<unsigned>(type.lower())
576664 .Case("cv", static_cast<unsigned>(DebugType::CV))
577665 .Case("pdata", static_cast<unsigned>(DebugType::PData))
578666 .Case("fixup", static_cast<unsigned>(DebugType::Fixup))
579667 .Default(0);
580 if (V == 0) {
581 warn("/debugtype: unknown option: " + Twine(A->getValue()));
668 if (v == 0) {
669 warn("/debugtype: unknown option '" + type + "'");
582670 continue;
583671 }
584 DebugTypes |= V;
672 debugTypes |= v;
585673 }
586 return DebugTypes;
674 return debugTypes;
587675 }
588676
589677 // Default debug types
590 DebugTypes = static_cast<unsigned>(DebugType::CV);
591 if (Args.hasArg(OPT_driver))
592 DebugTypes |= static_cast<unsigned>(DebugType::PData);
593 if (Args.hasArg(OPT_profile))
594 DebugTypes |= static_cast<unsigned>(DebugType::Fixup);
678 debugTypes = static_cast<unsigned>(DebugType::CV);
679 if (args.hasArg(OPT_driver))
680 debugTypes |= static_cast<unsigned>(DebugType::PData);
681 if (args.hasArg(OPT_profile))
682 debugTypes |= static_cast<unsigned>(DebugType::Fixup);
595683
596 return DebugTypes;
684 return debugTypes;
597685}
598686
599static std::string getMapFile(const opt::InputArgList &Args) {
600 auto *Arg = Args.getLastArg(OPT_lldmap, OPT_lldmap_file);
601 if (!Arg)
687static std::string getMapFile(const opt::InputArgList &args) {
688 auto *arg = args.getLastArg(OPT_lldmap, OPT_lldmap_file);
689 if (!arg)
602690 return "";
603 if (Arg->getOption().getID() == OPT_lldmap_file)
604 return Arg->getValue();
691 if (arg->getOption().getID() == OPT_lldmap_file)
692 return arg->getValue();
605693
606 assert(Arg->getOption().getID() == OPT_lldmap);
607 StringRef OutFile = Config->OutputFile;
608 return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
694 assert(arg->getOption().getID() == OPT_lldmap);
695 StringRef outFile = config->outputFile;
696 return (outFile.substr(0, outFile.rfind('.')) + ".map").str();
609697}
610698
611699static std::string getImplibPath() {
612 if (!Config->Implib.empty())
613 return Config->Implib;
614 SmallString<128> Out = StringRef(Config->OutputFile);
615 sys::path::replace_extension(Out, ".lib");
616 return Out.str();
700 if (!config->implib.empty())
701 return config->implib;
702 SmallString<128> out = StringRef(config->outputFile);
703 sys::path::replace_extension(out, ".lib");
704 return out.str();
617705}
618706
619707//
......@@ -624,289 +712,346 @@ static std::string getImplibPath() {
624712// LINK | {value} | {value}.{.dll/.exe} | {output name}
625713// LIB | {value} | {value}.dll | {output name}.dll
626714//
627static std::string getImportName(bool AsLib) {
628 SmallString<128> Out;
715static std::string getImportName(bool asLib) {
716 SmallString<128> out;
629717
630 if (Config->ImportName.empty()) {
631 Out.assign(sys::path::filename(Config->OutputFile));
632 if (AsLib)
633 sys::path::replace_extension(Out, ".dll");
718 if (config->importName.empty()) {
719 out.assign(sys::path::filename(config->outputFile));
720 if (asLib)
721 sys::path::replace_extension(out, ".dll");
634722 } else {
635 Out.assign(Config->ImportName);
636 if (!sys::path::has_extension(Out))
637 sys::path::replace_extension(Out,
638 (Config->DLL || AsLib) ? ".dll" : ".exe");
723 out.assign(config->importName);
724 if (!sys::path::has_extension(out))
725 sys::path::replace_extension(out,
726 (config->dll || asLib) ? ".dll" : ".exe");
639727 }
640728
641 return Out.str();
729 return out.str();
642730}
643731
644static void createImportLibrary(bool AsLib) {
645 std::vector<COFFShortExport> Exports;
646 for (Export &E1 : Config->Exports) {
647 COFFShortExport E2;
648 E2.Name = E1.Name;
649 E2.SymbolName = E1.SymbolName;
650 E2.ExtName = E1.ExtName;
651 E2.Ordinal = E1.Ordinal;
652 E2.Noname = E1.Noname;
653 E2.Data = E1.Data;
654 E2.Private = E1.Private;
655 E2.Constant = E1.Constant;
656 Exports.push_back(E2);
657 }
658
659 auto HandleError = [](Error &&E) {
660 handleAllErrors(std::move(E),
661 [](ErrorInfoBase &EIB) { error(EIB.message()); });
732static void createImportLibrary(bool asLib) {
733 std::vector<COFFShortExport> exports;
734 for (Export &e1 : config->exports) {
735 COFFShortExport e2;
736 e2.Name = e1.name;
737 e2.SymbolName = e1.symbolName;
738 e2.ExtName = e1.extName;
739 e2.Ordinal = e1.ordinal;
740 e2.Noname = e1.noname;
741 e2.Data = e1.data;
742 e2.Private = e1.isPrivate;
743 e2.Constant = e1.constant;
744 exports.push_back(e2);
745 }
746
747 auto handleError = [](Error &&e) {
748 handleAllErrors(std::move(e),
749 [](ErrorInfoBase &eib) { error(eib.message()); });
662750 };
663 std::string LibName = getImportName(AsLib);
664 std::string Path = getImplibPath();
751 std::string libName = getImportName(asLib);
752 std::string path = getImplibPath();
665753
666 if (!Config->Incremental) {
667 HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine,
668 Config->MinGW));
754 if (!config->incremental) {
755 handleError(writeImportLibrary(libName, path, exports, config->machine,
756 config->mingw));
669757 return;
670758 }
671759
672760 // If the import library already exists, replace it only if the contents
673761 // have changed.
674 ErrorOr<std::unique_ptr<MemoryBuffer>> OldBuf = MemoryBuffer::getFile(
675 Path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false);
676 if (!OldBuf) {
677 HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine,
678 Config->MinGW));
762 ErrorOr<std::unique_ptr<MemoryBuffer>> oldBuf = MemoryBuffer::getFile(
763 path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false);
764 if (!oldBuf) {
765 handleError(writeImportLibrary(libName, path, exports, config->machine,
766 config->mingw));
679767 return;
680768 }
681769
682 SmallString<128> TmpName;
683 if (std::error_code EC =
684 sys::fs::createUniqueFile(Path + ".tmp-%%%%%%%%.lib", TmpName))
685 fatal("cannot create temporary file for import library " + Path + ": " +
686 EC.message());
770 SmallString<128> tmpName;
771 if (std::error_code ec =
772 sys::fs::createUniqueFile(path + ".tmp-%%%%%%%%.lib", tmpName))
773 fatal("cannot create temporary file for import library " + path + ": " +
774 ec.message());
687775
688 if (Error E = writeImportLibrary(LibName, TmpName, Exports, Config->Machine,
689 Config->MinGW)) {
690 HandleError(std::move(E));
776 if (Error e = writeImportLibrary(libName, tmpName, exports, config->machine,
777 config->mingw)) {
778 handleError(std::move(e));
691779 return;
692780 }
693781
694 std::unique_ptr<MemoryBuffer> NewBuf = check(MemoryBuffer::getFile(
695 TmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false));
696 if ((*OldBuf)->getBuffer() != NewBuf->getBuffer()) {
697 OldBuf->reset();
698 HandleError(errorCodeToError(sys::fs::rename(TmpName, Path)));
782 std::unique_ptr<MemoryBuffer> newBuf = check(MemoryBuffer::getFile(
783 tmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false));
784 if ((*oldBuf)->getBuffer() != newBuf->getBuffer()) {
785 oldBuf->reset();
786 handleError(errorCodeToError(sys::fs::rename(tmpName, path)));
699787 } else {
700 sys::fs::remove(TmpName);
788 sys::fs::remove(tmpName);
701789 }
702790}
703791
704static void parseModuleDefs(StringRef Path) {
705 std::unique_ptr<MemoryBuffer> MB = CHECK(
706 MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
707 COFFModuleDefinition M = check(parseCOFFModuleDefinition(
708 MB->getMemBufferRef(), Config->Machine, Config->MinGW));
709
710 if (Config->OutputFile.empty())
711 Config->OutputFile = Saver.save(M.OutputFile);
712 Config->ImportName = Saver.save(M.ImportName);
713 if (M.ImageBase)
714 Config->ImageBase = M.ImageBase;
715 if (M.StackReserve)
716 Config->StackReserve = M.StackReserve;
717 if (M.StackCommit)
718 Config->StackCommit = M.StackCommit;
719 if (M.HeapReserve)
720 Config->HeapReserve = M.HeapReserve;
721 if (M.HeapCommit)
722 Config->HeapCommit = M.HeapCommit;
723 if (M.MajorImageVersion)
724 Config->MajorImageVersion = M.MajorImageVersion;
725 if (M.MinorImageVersion)
726 Config->MinorImageVersion = M.MinorImageVersion;
727 if (M.MajorOSVersion)
728 Config->MajorOSVersion = M.MajorOSVersion;
729 if (M.MinorOSVersion)
730 Config->MinorOSVersion = M.MinorOSVersion;
731
732 for (COFFShortExport E1 : M.Exports) {
733 Export E2;
792static void parseModuleDefs(StringRef path) {
793 std::unique_ptr<MemoryBuffer> mb = CHECK(
794 MemoryBuffer::getFile(path, -1, false, true), "could not open " + path);
795 COFFModuleDefinition m = check(parseCOFFModuleDefinition(
796 mb->getMemBufferRef(), config->machine, config->mingw));
797
798 if (config->outputFile.empty())
799 config->outputFile = saver.save(m.OutputFile);
800 config->importName = saver.save(m.ImportName);
801 if (m.ImageBase)
802 config->imageBase = m.ImageBase;
803 if (m.StackReserve)
804 config->stackReserve = m.StackReserve;
805 if (m.StackCommit)
806 config->stackCommit = m.StackCommit;
807 if (m.HeapReserve)
808 config->heapReserve = m.HeapReserve;
809 if (m.HeapCommit)
810 config->heapCommit = m.HeapCommit;
811 if (m.MajorImageVersion)
812 config->majorImageVersion = m.MajorImageVersion;
813 if (m.MinorImageVersion)
814 config->minorImageVersion = m.MinorImageVersion;
815 if (m.MajorOSVersion)
816 config->majorOSVersion = m.MajorOSVersion;
817 if (m.MinorOSVersion)
818 config->minorOSVersion = m.MinorOSVersion;
819
820 for (COFFShortExport e1 : m.Exports) {
821 Export e2;
734822 // In simple cases, only Name is set. Renamed exports are parsed
735823 // and set as "ExtName = Name". If Name has the form "OtherDll.Func",
736824 // it shouldn't be a normal exported function but a forward to another
737825 // DLL instead. This is supported by both MS and GNU linkers.
738 if (E1.ExtName != E1.Name && StringRef(E1.Name).contains('.')) {
739 E2.Name = Saver.save(E1.ExtName);
740 E2.ForwardTo = Saver.save(E1.Name);
741 Config->Exports.push_back(E2);
826 if (e1.ExtName != e1.Name && StringRef(e1.Name).contains('.')) {
827 e2.name = saver.save(e1.ExtName);
828 e2.forwardTo = saver.save(e1.Name);
829 config->exports.push_back(e2);
742830 continue;
743831 }
744 E2.Name = Saver.save(E1.Name);
745 E2.ExtName = Saver.save(E1.ExtName);
746 E2.Ordinal = E1.Ordinal;
747 E2.Noname = E1.Noname;
748 E2.Data = E1.Data;
749 E2.Private = E1.Private;
750 E2.Constant = E1.Constant;
751 Config->Exports.push_back(E2);
832 e2.name = saver.save(e1.Name);
833 e2.extName = saver.save(e1.ExtName);
834 e2.ordinal = e1.Ordinal;
835 e2.noname = e1.Noname;
836 e2.data = e1.Data;
837 e2.isPrivate = e1.Private;
838 e2.constant = e1.Constant;
839 config->exports.push_back(e2);
752840 }
753841}
754842
755void LinkerDriver::enqueueTask(std::function<void()> Task) {
756 TaskQueue.push_back(std::move(Task));
843void LinkerDriver::enqueueTask(std::function<void()> task) {
844 taskQueue.push_back(std::move(task));
757845}
758846
759847bool LinkerDriver::run() {
760 ScopedTimer T(InputFileTimer);
848 ScopedTimer t(inputFileTimer);
761849
762 bool DidWork = !TaskQueue.empty();
763 while (!TaskQueue.empty()) {
764 TaskQueue.front()();
765 TaskQueue.pop_front();
850 bool didWork = !taskQueue.empty();
851 while (!taskQueue.empty()) {
852 taskQueue.front()();
853 taskQueue.pop_front();
766854 }
767 return DidWork;
855 return didWork;
768856}
769857
770858// Parse an /order file. If an option is given, the linker places
771859// COMDAT sections in the same order as their names appear in the
772860// given file.
773static void parseOrderFile(StringRef Arg) {
861static void parseOrderFile(StringRef arg) {
774862 // For some reason, the MSVC linker requires a filename to be
775863 // preceded by "@".
776 if (!Arg.startswith("@")) {
864 if (!arg.startswith("@")) {
777865 error("malformed /order option: '@' missing");
778866 return;
779867 }
780868
781869 // Get a list of all comdat sections for error checking.
782 DenseSet<StringRef> Set;
783 for (Chunk *C : Symtab->getChunks())
784 if (auto *Sec = dyn_cast<SectionChunk>(C))
785 if (Sec->Sym)
786 Set.insert(Sec->Sym->getName());
870 DenseSet<StringRef> set;
871 for (Chunk *c : symtab->getChunks())
872 if (auto *sec = dyn_cast<SectionChunk>(c))
873 if (sec->sym)
874 set.insert(sec->sym->getName());
787875
788876 // Open a file.
789 StringRef Path = Arg.substr(1);
790 std::unique_ptr<MemoryBuffer> MB = CHECK(
791 MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
877 StringRef path = arg.substr(1);
878 std::unique_ptr<MemoryBuffer> mb = CHECK(
879 MemoryBuffer::getFile(path, -1, false, true), "could not open " + path);
792880
793881 // Parse a file. An order file contains one symbol per line.
794882 // All symbols that were not present in a given order file are
795883 // considered to have the lowest priority 0 and are placed at
796884 // end of an output section.
797 for (std::string S : args::getLines(MB->getMemBufferRef())) {
798 if (Config->Machine == I386 && !isDecorated(S))
799 S = "_" + S;
885 for (std::string s : args::getLines(mb->getMemBufferRef())) {
886 if (config->machine == I386 && !isDecorated(s))
887 s = "_" + s;
800888
801 if (Set.count(S) == 0) {
802 if (Config->WarnMissingOrderSymbol)
803 warn("/order:" + Arg + ": missing symbol: " + S + " [LNK4037]");
889 if (set.count(s) == 0) {
890 if (config->warnMissingOrderSymbol)
891 warn("/order:" + arg + ": missing symbol: " + s + " [LNK4037]");
804892 }
805893 else
806 Config->Order[S] = INT_MIN + Config->Order.size();
894 config->order[s] = INT_MIN + config->order.size();
807895 }
808896}
809897
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;
898static void markAddrsig(Symbol *s) {
899 if (auto *d = dyn_cast_or_null<Defined>(s))
900 if (SectionChunk *c = dyn_cast_or_null<SectionChunk>(d->getChunk()))
901 c->keepUnique = true;
814902}
815903
816904static void findKeepUniqueSections() {
817905 // Exported symbols could be address-significant in other executables or DSOs,
818906 // so we conservatively mark them as address-significant.
819 for (Export &R : Config->Exports)
820 markAddrsig(R.Sym);
907 for (Export &r : config->exports)
908 markAddrsig(r.sym);
821909
822910 // Visit the address-significance table in each object file and mark each
823911 // 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;
912 for (ObjFile *obj : ObjFile::instances) {
913 ArrayRef<Symbol *> syms = obj->getSymbols();
914 if (obj->addrsigSec) {
915 ArrayRef<uint8_t> contents;
916 cantFail(
917 obj->getCOFFObj()->getSectionContents(obj->addrsigSec, contents));
918 const uint8_t *cur = contents.begin();
919 while (cur != contents.end()) {
920 unsigned size;
921 const char *err;
922 uint64_t symIndex = decodeULEB128(cur, &size, contents.end(), &err);
923 if (err)
924 fatal(toString(obj) + ": could not decode addrsig section: " + err);
925 if (symIndex >= syms.size())
926 fatal(toString(obj) + ": invalid symbol index in addrsig section");
927 markAddrsig(syms[symIndex]);
928 cur += size;
840929 }
841930 } else {
842931 // If an object file does not have an address-significance table,
843932 // conservatively mark all of its symbols as address-significant.
844 for (Symbol *S : Syms)
845 markAddrsig(S);
933 for (Symbol *s : syms)
934 markAddrsig(s);
846935 }
847936 }
848937}
849938
850// link.exe replaces each %foo% in AltPath with the contents of environment
939// link.exe replaces each %foo% in altPath with the contents of environment
851940// variable foo, and adds the two magic env vars _PDB (expands to the basename
852941// of pdb's output path) and _EXT (expands to the extension of the output
853942// binary).
854943// lld only supports %_PDB% and %_EXT% and warns on references to all other env
855944// 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 '.'.
945static void parsePDBAltPath(StringRef altPath) {
946 SmallString<128> buf;
947 StringRef pdbBasename =
948 sys::path::filename(config->pdbPath, sys::path::Style::windows);
949 StringRef binaryExtension =
950 sys::path::extension(config->outputFile, sys::path::Style::windows);
951 if (!binaryExtension.empty())
952 binaryExtension = binaryExtension.substr(1); // %_EXT% does not include '.'.
864953
865954 // Invariant:
866 // +--------- Cursor ('a...' might be the empty string).
867 // | +----- FirstMark
868 // | | +- SecondMark
955 // +--------- cursor ('a...' might be the empty string).
956 // | +----- firstMark
957 // | | +- secondMark
869958 // v v v
870959 // 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) {
960 size_t cursor = 0;
961 while (cursor < altPath.size()) {
962 size_t firstMark, secondMark;
963 if ((firstMark = altPath.find('%', cursor)) == StringRef::npos ||
964 (secondMark = altPath.find('%', firstMark + 1)) == StringRef::npos) {
876965 // Didn't find another full fragment, treat rest of string as literal.
877 Buf.append(AltPath.substr(Cursor));
966 buf.append(altPath.substr(cursor));
878967 break;
879968 }
880969
881970 // Found a full fragment. Append text in front of first %, and interpret
882971 // 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);
972 buf.append(altPath.substr(cursor, firstMark - cursor));
973 StringRef var = altPath.substr(firstMark, secondMark - firstMark + 1);
974 if (var.equals_lower("%_pdb%"))
975 buf.append(pdbBasename);
976 else if (var.equals_lower("%_ext%"))
977 buf.append(binaryExtension);
889978 else {
890979 warn("only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping " +
891 Var + " as literal");
892 Buf.append(Var);
980 var + " as literal");
981 buf.append(var);
893982 }
894983
895 Cursor = SecondMark + 1;
984 cursor = secondMark + 1;
896985 }
897986
898 Config->PDBAltPath = Buf;
987 config->pdbAltPath = buf;
899988}
900989
901void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
902 // If the first command line argument is "/lib", link.exe acts like lib.exe.
903 // We call our own implementation of lib.exe that understands bitcode files.
904 if (ArgsArr.size() > 1 && StringRef(ArgsArr[1]).equals_lower("/lib")) {
905 if (llvm::libDriverMain(ArgsArr.slice(1)) != 0)
906 fatal("lib failed");
990/// Check that at most one resource obj file was used.
991/// Call after ObjFile::Instances is complete.
992static void diagnoseMultipleResourceObjFiles() {
993 // The .rsrc$01 section in a resource obj file contains a tree description
994 // of resources. Merging multiple resource obj files would require merging
995 // the trees instead of using usual linker section merging semantics.
996 // Since link.exe disallows linking more than one resource obj file with
997 // LNK4078, mirror that. The normal use of resource files is to give the
998 // linker many .res files, which are then converted to a single resource obj
999 // file internally, so this is not a big restriction in practice.
1000 ObjFile *resourceObjFile = nullptr;
1001 for (ObjFile *f : ObjFile::instances) {
1002 if (!f->isResourceObjFile)
1003 continue;
1004
1005 if (!resourceObjFile) {
1006 resourceObjFile = f;
1007 continue;
1008 }
1009
1010 error(toString(f) +
1011 ": more than one resource obj file not allowed, already got " +
1012 toString(resourceObjFile));
1013 }
1014}
1015
1016// In MinGW, if no symbols are chosen to be exported, then all symbols are
1017// automatically exported by default. This behavior can be forced by the
1018// -export-all-symbols option, so that it happens even when exports are
1019// explicitly specified. The automatic behavior can be disabled using the
1020// -exclude-all-symbols option, so that lld-link behaves like link.exe rather
1021// than MinGW in the case that nothing is explicitly exported.
1022void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
1023 if (!config->dll)
9071024 return;
1025
1026 if (!args.hasArg(OPT_export_all_symbols)) {
1027 if (!config->exports.empty())
1028 return;
1029 if (args.hasArg(OPT_exclude_all_symbols))
1030 return;
9081031 }
9091032
1033 AutoExporter exporter;
1034
1035 for (auto *arg : args.filtered(OPT_wholearchive_file))
1036 if (Optional<StringRef> path = doFindFile(arg->getValue()))
1037 exporter.addWholeArchive(*path);
1038
1039 symtab->forEachSymbol([&](Symbol *s) {
1040 auto *def = dyn_cast<Defined>(s);
1041 if (!exporter.shouldExport(def))
1042 return;
1043
1044 Export e;
1045 e.name = def->getName();
1046 e.sym = def;
1047 if (Chunk *c = def->getChunk())
1048 if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
1049 e.data = true;
1050 config->exports.push_back(e);
1051 });
1052}
1053
1054void LinkerDriver::link(ArrayRef<const char *> argsArr) {
9101055 // Needed for LTO.
9111056 InitializeAllTargetInfos();
9121057 InitializeAllTargets();
......@@ -914,279 +1059,308 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
9141059 InitializeAllAsmParsers();
9151060 InitializeAllAsmPrinters();
9161061
1062 // If the first command line argument is "/lib", link.exe acts like lib.exe.
1063 // We call our own implementation of lib.exe that understands bitcode files.
1064 if (argsArr.size() > 1 && StringRef(argsArr[1]).equals_lower("/lib")) {
1065 if (llvm::libDriverMain(argsArr.slice(1)) != 0)
1066 fatal("lib failed");
1067 return;
1068 }
1069
9171070 // Parse command line options.
918 ArgParser Parser;
919 opt::InputArgList Args = Parser.parseLINK(ArgsArr);
1071 ArgParser parser;
1072 opt::InputArgList args = parser.parseLINK(argsArr);
9201073
9211074 // Parse and evaluate -mllvm options.
922 std::vector<const char *> V;
923 V.push_back("lld-link (LLVM option parsing)");
924 for (auto *Arg : Args.filtered(OPT_mllvm))
925 V.push_back(Arg->getValue());
926 cl::ParseCommandLineOptions(V.size(), V.data());
1075 std::vector<const char *> v;
1076 v.push_back("lld-link (LLVM option parsing)");
1077 for (auto *arg : args.filtered(OPT_mllvm))
1078 v.push_back(arg->getValue());
1079 cl::ParseCommandLineOptions(v.size(), v.data());
9271080
9281081 // Handle /errorlimit early, because error() depends on it.
929 if (auto *Arg = Args.getLastArg(OPT_errorlimit)) {
930 int N = 20;
931 StringRef S = Arg->getValue();
932 if (S.getAsInteger(10, N))
933 error(Arg->getSpelling() + " number expected, but got " + S);
934 errorHandler().ErrorLimit = N;
1082 if (auto *arg = args.getLastArg(OPT_errorlimit)) {
1083 int n = 20;
1084 StringRef s = arg->getValue();
1085 if (s.getAsInteger(10, n))
1086 error(arg->getSpelling() + " number expected, but got " + s);
1087 errorHandler().errorLimit = n;
9351088 }
9361089
9371090 // Handle /help
938 if (Args.hasArg(OPT_help)) {
939 printHelp(ArgsArr[0]);
1091 if (args.hasArg(OPT_help)) {
1092 printHelp(argsArr[0]);
9401093 return;
9411094 }
9421095
943 if (Args.hasArg(OPT_show_timing))
944 Config->ShowTiming = true;
1096 lld::threadsEnabled = args.hasFlag(OPT_threads, OPT_threads_no, true);
1097
1098 if (args.hasArg(OPT_show_timing))
1099 config->showTiming = true;
9451100
946 ScopedTimer T(Timer::root());
1101 config->showSummary = args.hasArg(OPT_summary);
1102
1103 ScopedTimer t(Timer::root());
9471104 // Handle --version, which is an lld extension. This option is a bit odd
9481105 // because it doesn't start with "/", but we deliberately chose "--" to
9491106 // avoid conflict with /version and for compatibility with clang-cl.
950 if (Args.hasArg(OPT_dash_dash_version)) {
1107 if (args.hasArg(OPT_dash_dash_version)) {
9511108 outs() << getLLDVersion() << "\n";
9521109 return;
9531110 }
9541111
9551112 // Handle /lldmingw early, since it can potentially affect how other
9561113 // options are handled.
957 Config->MinGW = Args.hasArg(OPT_lldmingw);
1114 config->mingw = args.hasArg(OPT_lldmingw);
9581115
959 if (auto *Arg = Args.getLastArg(OPT_linkrepro)) {
960 SmallString<64> Path = StringRef(Arg->getValue());
961 sys::path::append(Path, "repro.tar");
1116 if (auto *arg = args.getLastArg(OPT_linkrepro)) {
1117 SmallString<64> path = StringRef(arg->getValue());
1118 sys::path::append(path, "repro.tar");
9621119
963 Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
964 TarWriter::create(Path, "repro");
1120 Expected<std::unique_ptr<TarWriter>> errOrWriter =
1121 TarWriter::create(path, "repro");
9651122
966 if (ErrOrWriter) {
967 Tar = std::move(*ErrOrWriter);
1123 if (errOrWriter) {
1124 tar = std::move(*errOrWriter);
9681125 } else {
969 error("/linkrepro: failed to open " + Path + ": " +
970 toString(ErrOrWriter.takeError()));
1126 error("/linkrepro: failed to open " + path + ": " +
1127 toString(errOrWriter.takeError()));
9711128 }
9721129 }
9731130
974 if (!Args.hasArg(OPT_INPUT)) {
975 if (Args.hasArg(OPT_deffile))
976 Config->NoEntry = true;
1131 if (!args.hasArg(OPT_INPUT)) {
1132 if (args.hasArg(OPT_deffile))
1133 config->noEntry = true;
9771134 else
9781135 fatal("no input files");
9791136 }
9801137
9811138 // Construct search path list.
982 SearchPaths.push_back("");
983 for (auto *Arg : Args.filtered(OPT_libpath))
984 SearchPaths.push_back(Arg->getValue());
1139 searchPaths.push_back("");
1140 for (auto *arg : args.filtered(OPT_libpath))
1141 searchPaths.push_back(arg->getValue());
9851142 addLibSearchPaths();
9861143
9871144 // Handle /ignore
988 for (auto *Arg : Args.filtered(OPT_ignore)) {
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;
1145 for (auto *arg : args.filtered(OPT_ignore)) {
1146 SmallVector<StringRef, 8> vec;
1147 StringRef(arg->getValue()).split(vec, ',');
1148 for (StringRef s : vec) {
1149 if (s == "4037")
1150 config->warnMissingOrderSymbol = false;
1151 else if (s == "4099")
1152 config->warnDebugInfoUnusable = false;
1153 else if (s == "4217")
1154 config->warnLocallyDefinedImported = false;
9981155 // Other warning numbers are ignored.
9991156 }
10001157 }
10011158
10021159 // Handle /out
1003 if (auto *Arg = Args.getLastArg(OPT_out))
1004 Config->OutputFile = Arg->getValue();
1160 if (auto *arg = args.getLastArg(OPT_out))
1161 config->outputFile = arg->getValue();
10051162
10061163 // Handle /verbose
1007 if (Args.hasArg(OPT_verbose))
1008 Config->Verbose = true;
1009 errorHandler().Verbose = Config->Verbose;
1164 if (args.hasArg(OPT_verbose))
1165 config->verbose = true;
1166 errorHandler().verbose = config->verbose;
10101167
10111168 // Handle /force or /force:unresolved
1012 if (Args.hasArg(OPT_force, OPT_force_unresolved))
1013 Config->ForceUnresolved = true;
1169 if (args.hasArg(OPT_force, OPT_force_unresolved))
1170 config->forceUnresolved = true;
10141171
10151172 // Handle /force or /force:multiple
1016 if (Args.hasArg(OPT_force, OPT_force_multiple))
1017 Config->ForceMultiple = true;
1173 if (args.hasArg(OPT_force, OPT_force_multiple))
1174 config->forceMultiple = true;
1175
1176 // Handle /force or /force:multipleres
1177 if (args.hasArg(OPT_force, OPT_force_multipleres))
1178 config->forceMultipleRes = true;
10181179
10191180 // Handle /debug
1020 DebugKind Debug = parseDebugKind(Args);
1021 if (Debug == DebugKind::Full || Debug == DebugKind::Dwarf ||
1022 Debug == DebugKind::GHash) {
1023 Config->Debug = true;
1024 Config->Incremental = true;
1181 DebugKind debug = parseDebugKind(args);
1182 if (debug == DebugKind::Full || debug == DebugKind::Dwarf ||
1183 debug == DebugKind::GHash) {
1184 config->debug = true;
1185 config->incremental = true;
10251186 }
10261187
1188 // Handle /demangle
1189 config->demangle = args.hasFlag(OPT_demangle, OPT_demangle_no);
1190
10271191 // Handle /debugtype
1028 Config->DebugTypes = parseDebugTypes(Args);
1192 config->debugTypes = parseDebugTypes(args);
10291193
10301194 // Handle /pdb
1031 bool ShouldCreatePDB =
1032 (Debug == DebugKind::Full || Debug == DebugKind::GHash);
1033 if (ShouldCreatePDB) {
1034 if (auto *Arg = Args.getLastArg(OPT_pdb))
1035 Config->PDBPath = Arg->getValue();
1036 if (auto *Arg = Args.getLastArg(OPT_pdbaltpath))
1037 Config->PDBAltPath = Arg->getValue();
1038 if (Args.hasArg(OPT_natvis))
1039 Config->NatvisFiles = Args.getAllArgValues(OPT_natvis);
1195 bool shouldCreatePDB =
1196 (debug == DebugKind::Full || debug == DebugKind::GHash);
1197 if (shouldCreatePDB) {
1198 if (auto *arg = args.getLastArg(OPT_pdb))
1199 config->pdbPath = arg->getValue();
1200 if (auto *arg = args.getLastArg(OPT_pdbaltpath))
1201 config->pdbAltPath = arg->getValue();
1202 if (args.hasArg(OPT_natvis))
1203 config->natvisFiles = args.getAllArgValues(OPT_natvis);
10401204
1041 if (auto *Arg = Args.getLastArg(OPT_pdb_source_path))
1042 Config->PDBSourcePath = Arg->getValue();
1205 if (auto *arg = args.getLastArg(OPT_pdb_source_path))
1206 config->pdbSourcePath = arg->getValue();
10431207 }
10441208
10451209 // Handle /noentry
1046 if (Args.hasArg(OPT_noentry)) {
1047 if (Args.hasArg(OPT_dll))
1048 Config->NoEntry = true;
1210 if (args.hasArg(OPT_noentry)) {
1211 if (args.hasArg(OPT_dll))
1212 config->noEntry = true;
10491213 else
10501214 error("/noentry must be specified with /dll");
10511215 }
10521216
10531217 // Handle /dll
1054 if (Args.hasArg(OPT_dll)) {
1055 Config->DLL = true;
1056 Config->ManifestID = 2;
1218 if (args.hasArg(OPT_dll)) {
1219 config->dll = true;
1220 config->manifestID = 2;
10571221 }
10581222
10591223 // Handle /dynamicbase and /fixed. We can't use hasFlag for /dynamicbase
10601224 // because we need to explicitly check whether that option or its inverse was
10611225 // present in the argument list in order to handle /fixed.
1062 auto *DynamicBaseArg = Args.getLastArg(OPT_dynamicbase, OPT_dynamicbase_no);
1063 if (DynamicBaseArg &&
1064 DynamicBaseArg->getOption().getID() == OPT_dynamicbase_no)
1065 Config->DynamicBase = false;
1226 auto *dynamicBaseArg = args.getLastArg(OPT_dynamicbase, OPT_dynamicbase_no);
1227 if (dynamicBaseArg &&
1228 dynamicBaseArg->getOption().getID() == OPT_dynamicbase_no)
1229 config->dynamicBase = false;
10661230
10671231 // MSDN claims "/FIXED:NO is the default setting for a DLL, and /FIXED is the
10681232 // default setting for any other project type.", but link.exe defaults to
10691233 // /FIXED:NO for exe outputs as well. Match behavior, not docs.
1070 bool Fixed = Args.hasFlag(OPT_fixed, OPT_fixed_no, false);
1071 if (Fixed) {
1072 if (DynamicBaseArg &&
1073 DynamicBaseArg->getOption().getID() == OPT_dynamicbase) {
1234 bool fixed = args.hasFlag(OPT_fixed, OPT_fixed_no, false);
1235 if (fixed) {
1236 if (dynamicBaseArg &&
1237 dynamicBaseArg->getOption().getID() == OPT_dynamicbase) {
10741238 error("/fixed must not be specified with /dynamicbase");
10751239 } else {
1076 Config->Relocatable = false;
1077 Config->DynamicBase = false;
1240 config->relocatable = false;
1241 config->dynamicBase = false;
10781242 }
10791243 }
10801244
10811245 // Handle /appcontainer
1082 Config->AppContainer =
1083 Args.hasFlag(OPT_appcontainer, OPT_appcontainer_no, false);
1246 config->appContainer =
1247 args.hasFlag(OPT_appcontainer, OPT_appcontainer_no, false);
10841248
10851249 // Handle /machine
1086 if (auto *Arg = Args.getLastArg(OPT_machine))
1087 Config->Machine = getMachineType(Arg->getValue());
1250 if (auto *arg = args.getLastArg(OPT_machine)) {
1251 config->machine = getMachineType(arg->getValue());
1252 if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN)
1253 fatal(Twine("unknown /machine argument: ") + arg->getValue());
1254 }
10881255
10891256 // Handle /nodefaultlib:<filename>
1090 for (auto *Arg : Args.filtered(OPT_nodefaultlib))
1091 Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()));
1257 for (auto *arg : args.filtered(OPT_nodefaultlib))
1258 config->noDefaultLibs.insert(doFindLib(arg->getValue()).lower());
10921259
10931260 // Handle /nodefaultlib
1094 if (Args.hasArg(OPT_nodefaultlib_all))
1095 Config->NoDefaultLibAll = true;
1261 if (args.hasArg(OPT_nodefaultlib_all))
1262 config->noDefaultLibAll = true;
10961263
10971264 // Handle /base
1098 if (auto *Arg = Args.getLastArg(OPT_base))
1099 parseNumbers(Arg->getValue(), &Config->ImageBase);
1265 if (auto *arg = args.getLastArg(OPT_base))
1266 parseNumbers(arg->getValue(), &config->imageBase);
1267
1268 // Handle /filealign
1269 if (auto *arg = args.getLastArg(OPT_filealign)) {
1270 parseNumbers(arg->getValue(), &config->fileAlign);
1271 if (!isPowerOf2_64(config->fileAlign))
1272 error("/filealign: not a power of two: " + Twine(config->fileAlign));
1273 }
11001274
11011275 // Handle /stack
1102 if (auto *Arg = Args.getLastArg(OPT_stack))
1103 parseNumbers(Arg->getValue(), &Config->StackReserve, &Config->StackCommit);
1276 if (auto *arg = args.getLastArg(OPT_stack))
1277 parseNumbers(arg->getValue(), &config->stackReserve, &config->stackCommit);
11041278
11051279 // Handle /guard:cf
1106 if (auto *Arg = Args.getLastArg(OPT_guard))
1107 parseGuard(Arg->getValue());
1280 if (auto *arg = args.getLastArg(OPT_guard))
1281 parseGuard(arg->getValue());
11081282
11091283 // Handle /heap
1110 if (auto *Arg = Args.getLastArg(OPT_heap))
1111 parseNumbers(Arg->getValue(), &Config->HeapReserve, &Config->HeapCommit);
1284 if (auto *arg = args.getLastArg(OPT_heap))
1285 parseNumbers(arg->getValue(), &config->heapReserve, &config->heapCommit);
11121286
11131287 // Handle /version
1114 if (auto *Arg = Args.getLastArg(OPT_version))
1115 parseVersion(Arg->getValue(), &Config->MajorImageVersion,
1116 &Config->MinorImageVersion);
1288 if (auto *arg = args.getLastArg(OPT_version))
1289 parseVersion(arg->getValue(), &config->majorImageVersion,
1290 &config->minorImageVersion);
11171291
11181292 // Handle /subsystem
1119 if (auto *Arg = Args.getLastArg(OPT_subsystem))
1120 parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion,
1121 &Config->MinorOSVersion);
1293 if (auto *arg = args.getLastArg(OPT_subsystem))
1294 parseSubsystem(arg->getValue(), &config->subsystem, &config->majorOSVersion,
1295 &config->minorOSVersion);
11221296
11231297 // Handle /timestamp
1124 if (llvm::opt::Arg *Arg = Args.getLastArg(OPT_timestamp, OPT_repro)) {
1125 if (Arg->getOption().getID() == OPT_repro) {
1126 Config->Timestamp = 0;
1127 Config->Repro = true;
1298 if (llvm::opt::Arg *arg = args.getLastArg(OPT_timestamp, OPT_repro)) {
1299 if (arg->getOption().getID() == OPT_repro) {
1300 config->timestamp = 0;
1301 config->repro = true;
11281302 } else {
1129 Config->Repro = false;
1130 StringRef Value(Arg->getValue());
1131 if (Value.getAsInteger(0, Config->Timestamp))
1132 fatal(Twine("invalid timestamp: ") + Value +
1303 config->repro = false;
1304 StringRef value(arg->getValue());
1305 if (value.getAsInteger(0, config->timestamp))
1306 fatal(Twine("invalid timestamp: ") + value +
11331307 ". Expected 32-bit integer");
11341308 }
11351309 } else {
1136 Config->Repro = false;
1137 Config->Timestamp = time(nullptr);
1310 config->repro = false;
1311 config->timestamp = time(nullptr);
11381312 }
11391313
11401314 // Handle /alternatename
1141 for (auto *Arg : Args.filtered(OPT_alternatename))
1142 parseAlternateName(Arg->getValue());
1315 for (auto *arg : args.filtered(OPT_alternatename))
1316 parseAlternateName(arg->getValue());
11431317
11441318 // Handle /include
1145 for (auto *Arg : Args.filtered(OPT_incl))
1146 addUndefined(Arg->getValue());
1319 for (auto *arg : args.filtered(OPT_incl))
1320 addUndefined(arg->getValue());
11471321
11481322 // Handle /implib
1149 if (auto *Arg = Args.getLastArg(OPT_implib))
1150 Config->Implib = Arg->getValue();
1323 if (auto *arg = args.getLastArg(OPT_implib))
1324 config->implib = arg->getValue();
11511325
11521326 // Handle /opt.
1153 bool DoGC = Debug == DebugKind::None || Args.hasArg(OPT_profile);
1154 unsigned ICFLevel =
1155 Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on
1156 unsigned TailMerge = 1;
1157 for (auto *Arg : Args.filtered(OPT_opt)) {
1158 std::string Str = StringRef(Arg->getValue()).lower();
1159 SmallVector<StringRef, 1> Vec;
1160 StringRef(Str).split(Vec, ',');
1161 for (StringRef S : Vec) {
1162 if (S == "ref") {
1163 DoGC = true;
1164 } else if (S == "noref") {
1165 DoGC = false;
1166 } else if (S == "icf" || S.startswith("icf=")) {
1167 ICFLevel = 2;
1168 } else if (S == "noicf") {
1169 ICFLevel = 0;
1170 } else if (S == "lldtailmerge") {
1171 TailMerge = 2;
1172 } else if (S == "nolldtailmerge") {
1173 TailMerge = 0;
1174 } else if (S.startswith("lldlto=")) {
1175 StringRef OptLevel = S.substr(7);
1176 if (OptLevel.getAsInteger(10, Config->LTOO) || Config->LTOO > 3)
1177 error("/opt:lldlto: invalid optimization level: " + OptLevel);
1178 } else if (S.startswith("lldltojobs=")) {
1179 StringRef Jobs = S.substr(11);
1180 if (Jobs.getAsInteger(10, Config->ThinLTOJobs) ||
1181 Config->ThinLTOJobs == 0)
1182 error("/opt:lldltojobs: invalid job count: " + Jobs);
1183 } else if (S.startswith("lldltopartitions=")) {
1184 StringRef N = S.substr(17);
1185 if (N.getAsInteger(10, Config->LTOPartitions) ||
1186 Config->LTOPartitions == 0)
1187 error("/opt:lldltopartitions: invalid partition count: " + N);
1188 } else if (S != "lbr" && S != "nolbr")
1189 error("/opt: unknown option: " + S);
1327 bool doGC = debug == DebugKind::None || args.hasArg(OPT_profile);
1328 unsigned icfLevel =
1329 args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on
1330 unsigned tailMerge = 1;
1331 for (auto *arg : args.filtered(OPT_opt)) {
1332 std::string str = StringRef(arg->getValue()).lower();
1333 SmallVector<StringRef, 1> vec;
1334 StringRef(str).split(vec, ',');
1335 for (StringRef s : vec) {
1336 if (s == "ref") {
1337 doGC = true;
1338 } else if (s == "noref") {
1339 doGC = false;
1340 } else if (s == "icf" || s.startswith("icf=")) {
1341 icfLevel = 2;
1342 } else if (s == "noicf") {
1343 icfLevel = 0;
1344 } else if (s == "lldtailmerge") {
1345 tailMerge = 2;
1346 } else if (s == "nolldtailmerge") {
1347 tailMerge = 0;
1348 } else if (s.startswith("lldlto=")) {
1349 StringRef optLevel = s.substr(7);
1350 if (optLevel.getAsInteger(10, config->ltoo) || config->ltoo > 3)
1351 error("/opt:lldlto: invalid optimization level: " + optLevel);
1352 } else if (s.startswith("lldltojobs=")) {
1353 StringRef jobs = s.substr(11);
1354 if (jobs.getAsInteger(10, config->thinLTOJobs) ||
1355 config->thinLTOJobs == 0)
1356 error("/opt:lldltojobs: invalid job count: " + jobs);
1357 } else if (s.startswith("lldltopartitions=")) {
1358 StringRef n = s.substr(17);
1359 if (n.getAsInteger(10, config->ltoPartitions) ||
1360 config->ltoPartitions == 0)
1361 error("/opt:lldltopartitions: invalid partition count: " + n);
1362 } else if (s != "lbr" && s != "nolbr")
1363 error("/opt: unknown option: " + s);
11901364 }
11911365 }
11921366
......@@ -1195,37 +1369,37 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
11951369 // FIXME: LLD only implements "limited" ICF, i.e. it only merges identical
11961370 // code. If the user passes /OPT:ICF explicitly, LLD should merge identical
11971371 // comdat readonly data.
1198 if (ICFLevel == 1 && !DoGC)
1199 ICFLevel = 0;
1200 Config->DoGC = DoGC;
1201 Config->DoICF = ICFLevel > 0;
1202 Config->TailMerge = (TailMerge == 1 && Config->DoICF) || TailMerge == 2;
1372 if (icfLevel == 1 && !doGC)
1373 icfLevel = 0;
1374 config->doGC = doGC;
1375 config->doICF = icfLevel > 0;
1376 config->tailMerge = (tailMerge == 1 && config->doICF) || tailMerge == 2;
12031377
12041378 // Handle /lldsavetemps
1205 if (Args.hasArg(OPT_lldsavetemps))
1206 Config->SaveTemps = true;
1379 if (args.hasArg(OPT_lldsavetemps))
1380 config->saveTemps = true;
12071381
12081382 // Handle /kill-at
1209 if (Args.hasArg(OPT_kill_at))
1210 Config->KillAt = true;
1383 if (args.hasArg(OPT_kill_at))
1384 config->killAt = true;
12111385
12121386 // Handle /lldltocache
1213 if (auto *Arg = Args.getLastArg(OPT_lldltocache))
1214 Config->LTOCache = Arg->getValue();
1387 if (auto *arg = args.getLastArg(OPT_lldltocache))
1388 config->ltoCache = arg->getValue();
12151389
12161390 // Handle /lldsavecachepolicy
1217 if (auto *Arg = Args.getLastArg(OPT_lldltocachepolicy))
1218 Config->LTOCachePolicy = CHECK(
1219 parseCachePruningPolicy(Arg->getValue()),
1220 Twine("/lldltocachepolicy: invalid cache policy: ") + Arg->getValue());
1391 if (auto *arg = args.getLastArg(OPT_lldltocachepolicy))
1392 config->ltoCachePolicy = CHECK(
1393 parseCachePruningPolicy(arg->getValue()),
1394 Twine("/lldltocachepolicy: invalid cache policy: ") + arg->getValue());
12211395
12221396 // Handle /failifmismatch
1223 for (auto *Arg : Args.filtered(OPT_failifmismatch))
1224 checkFailIfMismatch(Arg->getValue());
1397 for (auto *arg : args.filtered(OPT_failifmismatch))
1398 checkFailIfMismatch(arg->getValue(), nullptr);
12251399
12261400 // Handle /merge
1227 for (auto *Arg : Args.filtered(OPT_merge))
1228 parseMerge(Arg->getValue());
1401 for (auto *arg : args.filtered(OPT_merge))
1402 parseMerge(arg->getValue());
12291403
12301404 // Add default section merging rules after user rules. User rules take
12311405 // precedence, but we will emit a warning if there is a conflict.
......@@ -1235,130 +1409,137 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
12351409 parseMerge(".xdata=.rdata");
12361410 parseMerge(".bss=.data");
12371411
1238 if (Config->MinGW) {
1412 if (config->mingw) {
12391413 parseMerge(".ctors=.rdata");
12401414 parseMerge(".dtors=.rdata");
12411415 parseMerge(".CRT=.rdata");
12421416 }
12431417
12441418 // Handle /section
1245 for (auto *Arg : Args.filtered(OPT_section))
1246 parseSection(Arg->getValue());
1419 for (auto *arg : args.filtered(OPT_section))
1420 parseSection(arg->getValue());
12471421
12481422 // Handle /aligncomm
1249 for (auto *Arg : Args.filtered(OPT_aligncomm))
1250 parseAligncomm(Arg->getValue());
1423 for (auto *arg : args.filtered(OPT_aligncomm))
1424 parseAligncomm(arg->getValue());
12511425
12521426 // Handle /manifestdependency. This enables /manifest unless /manifest:no is
12531427 // also passed.
1254 if (auto *Arg = Args.getLastArg(OPT_manifestdependency)) {
1255 Config->ManifestDependency = Arg->getValue();
1256 Config->Manifest = Configuration::SideBySide;
1428 if (auto *arg = args.getLastArg(OPT_manifestdependency)) {
1429 config->manifestDependency = arg->getValue();
1430 config->manifest = Configuration::SideBySide;
12571431 }
12581432
12591433 // Handle /manifest and /manifest:
1260 if (auto *Arg = Args.getLastArg(OPT_manifest, OPT_manifest_colon)) {
1261 if (Arg->getOption().getID() == OPT_manifest)
1262 Config->Manifest = Configuration::SideBySide;
1434 if (auto *arg = args.getLastArg(OPT_manifest, OPT_manifest_colon)) {
1435 if (arg->getOption().getID() == OPT_manifest)
1436 config->manifest = Configuration::SideBySide;
12631437 else
1264 parseManifest(Arg->getValue());
1438 parseManifest(arg->getValue());
12651439 }
12661440
12671441 // Handle /manifestuac
1268 if (auto *Arg = Args.getLastArg(OPT_manifestuac))
1269 parseManifestUAC(Arg->getValue());
1442 if (auto *arg = args.getLastArg(OPT_manifestuac))
1443 parseManifestUAC(arg->getValue());
12701444
12711445 // Handle /manifestfile
1272 if (auto *Arg = Args.getLastArg(OPT_manifestfile))
1273 Config->ManifestFile = Arg->getValue();
1446 if (auto *arg = args.getLastArg(OPT_manifestfile))
1447 config->manifestFile = arg->getValue();
12741448
12751449 // Handle /manifestinput
1276 for (auto *Arg : Args.filtered(OPT_manifestinput))
1277 Config->ManifestInput.push_back(Arg->getValue());
1450 for (auto *arg : args.filtered(OPT_manifestinput))
1451 config->manifestInput.push_back(arg->getValue());
12781452
1279 if (!Config->ManifestInput.empty() &&
1280 Config->Manifest != Configuration::Embed) {
1453 if (!config->manifestInput.empty() &&
1454 config->manifest != Configuration::Embed) {
12811455 fatal("/manifestinput: requires /manifest:embed");
12821456 }
12831457
1458 config->thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files);
1459 config->thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) ||
1460 args.hasArg(OPT_thinlto_index_only_arg);
1461 config->thinLTOIndexOnlyArg =
1462 args.getLastArgValue(OPT_thinlto_index_only_arg);
1463 config->thinLTOPrefixReplace =
1464 getOldNewOptions(args, OPT_thinlto_prefix_replace);
1465 config->thinLTOObjectSuffixReplace =
1466 getOldNewOptions(args, OPT_thinlto_object_suffix_replace);
12841467 // Handle miscellaneous boolean flags.
1285 Config->AllowBind = Args.hasFlag(OPT_allowbind, OPT_allowbind_no, true);
1286 Config->AllowIsolation =
1287 Args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true);
1288 Config->Incremental =
1289 Args.hasFlag(OPT_incremental, OPT_incremental_no,
1290 !Config->DoGC && !Config->DoICF && !Args.hasArg(OPT_order) &&
1291 !Args.hasArg(OPT_profile));
1292 Config->IntegrityCheck =
1293 Args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false);
1294 Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);
1295 Config->TerminalServerAware =
1296 !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
1297 Config->DebugDwarf = Debug == DebugKind::Dwarf;
1298 Config->DebugGHashes = Debug == DebugKind::GHash;
1299 Config->DebugSymtab = Debug == DebugKind::Symtab;
1300
1301 Config->MapFile = getMapFile(Args);
1302
1303 if (Config->Incremental && Args.hasArg(OPT_profile)) {
1468 config->allowBind = args.hasFlag(OPT_allowbind, OPT_allowbind_no, true);
1469 config->allowIsolation =
1470 args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true);
1471 config->incremental =
1472 args.hasFlag(OPT_incremental, OPT_incremental_no,
1473 !config->doGC && !config->doICF && !args.hasArg(OPT_order) &&
1474 !args.hasArg(OPT_profile));
1475 config->integrityCheck =
1476 args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false);
1477 config->nxCompat = args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);
1478 for (auto *arg : args.filtered(OPT_swaprun))
1479 parseSwaprun(arg->getValue());
1480 config->terminalServerAware =
1481 !config->dll && args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
1482 config->debugDwarf = debug == DebugKind::Dwarf;
1483 config->debugGHashes = debug == DebugKind::GHash;
1484 config->debugSymtab = debug == DebugKind::Symtab;
1485
1486 config->mapFile = getMapFile(args);
1487
1488 if (config->incremental && args.hasArg(OPT_profile)) {
13041489 warn("ignoring '/incremental' due to '/profile' specification");
1305 Config->Incremental = false;
1490 config->incremental = false;
13061491 }
13071492
1308 if (Config->Incremental && Args.hasArg(OPT_order)) {
1493 if (config->incremental && args.hasArg(OPT_order)) {
13091494 warn("ignoring '/incremental' due to '/order' specification");
1310 Config->Incremental = false;
1495 config->incremental = false;
13111496 }
13121497
1313 if (Config->Incremental && Config->DoGC) {
1498 if (config->incremental && config->doGC) {
13141499 warn("ignoring '/incremental' because REF is enabled; use '/opt:noref' to "
13151500 "disable");
1316 Config->Incremental = false;
1501 config->incremental = false;
13171502 }
13181503
1319 if (Config->Incremental && Config->DoICF) {
1504 if (config->incremental && config->doICF) {
13201505 warn("ignoring '/incremental' because ICF is enabled; use '/opt:noicf' to "
13211506 "disable");
1322 Config->Incremental = false;
1507 config->incremental = false;
13231508 }
13241509
13251510 if (errorCount())
13261511 return;
13271512
1328 std::set<sys::fs::UniqueID> WholeArchives;
1329 AutoExporter Exporter;
1330 for (auto *Arg : Args.filtered(OPT_wholearchive_file)) {
1331 if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
1332 if (Optional<sys::fs::UniqueID> ID = getUniqueID(*Path))
1333 WholeArchives.insert(*ID);
1334 Exporter.addWholeArchive(*Path);
1335 }
1336 }
1513 std::set<sys::fs::UniqueID> wholeArchives;
1514 for (auto *arg : args.filtered(OPT_wholearchive_file))
1515 if (Optional<StringRef> path = doFindFile(arg->getValue()))
1516 if (Optional<sys::fs::UniqueID> id = getUniqueID(*path))
1517 wholeArchives.insert(*id);
13371518
13381519 // A predicate returning true if a given path is an argument for
13391520 // /wholearchive:, or /wholearchive is enabled globally.
13401521 // This function is a bit tricky because "foo.obj /wholearchive:././foo.obj"
13411522 // needs to be handled as "/wholearchive:foo.obj foo.obj".
1342 auto IsWholeArchive = [&](StringRef Path) -> bool {
1343 if (Args.hasArg(OPT_wholearchive_flag))
1523 auto isWholeArchive = [&](StringRef path) -> bool {
1524 if (args.hasArg(OPT_wholearchive_flag))
13441525 return true;
1345 if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path))
1346 return WholeArchives.count(*ID);
1526 if (Optional<sys::fs::UniqueID> id = getUniqueID(path))
1527 return wholeArchives.count(*id);
13471528 return false;
13481529 };
13491530
13501531 // Create a list of input files. Files can be given as arguments
13511532 // for /defaultlib option.
1352 for (auto *Arg : Args.filtered(OPT_INPUT, OPT_wholearchive_file))
1353 if (Optional<StringRef> Path = findFile(Arg->getValue()))
1354 enqueuePath(*Path, IsWholeArchive(*Path));
1533 for (auto *arg : args.filtered(OPT_INPUT, OPT_wholearchive_file))
1534 if (Optional<StringRef> path = findFile(arg->getValue()))
1535 enqueuePath(*path, isWholeArchive(*path));
13551536
1356 for (auto *Arg : Args.filtered(OPT_defaultlib))
1357 if (Optional<StringRef> Path = findLib(Arg->getValue()))
1358 enqueuePath(*Path, false);
1537 for (auto *arg : args.filtered(OPT_defaultlib))
1538 if (Optional<StringRef> path = findLib(arg->getValue()))
1539 enqueuePath(*path, false);
13591540
13601541 // Windows specific -- Create a resource file containing a manifest file.
1361 if (Config->Manifest == Configuration::Embed)
1542 if (config->manifest == Configuration::Embed)
13621543 addBuffer(createManifestRes(), false);
13631544
13641545 // Read all input files given via the command line.
......@@ -1369,154 +1550,169 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
13691550
13701551 // We should have inferred a machine type by now from the input files, but if
13711552 // not we assume x64.
1372 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
1553 if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) {
13731554 warn("/machine is not specified. x64 is assumed");
1374 Config->Machine = AMD64;
1555 config->machine = AMD64;
13751556 }
1376 Config->Wordsize = Config->is64() ? 8 : 4;
1557 config->wordsize = config->is64() ? 8 : 4;
1558
1559 // Handle /safeseh, x86 only, on by default, except for mingw.
1560 if (config->machine == I386 &&
1561 args.hasFlag(OPT_safeseh, OPT_safeseh_no, !config->mingw))
1562 config->safeSEH = true;
1563
1564 // Handle /functionpadmin
1565 for (auto *arg : args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt))
1566 parseFunctionPadMin(arg, config->machine);
13771567
13781568 // Input files can be Windows resource files (.res files). We use
13791569 // WindowsResource to convert resource files to a regular COFF file,
13801570 // then link the resulting file normally.
1381 if (!Resources.empty())
1382 Symtab->addFile(make<ObjFile>(convertResToCOFF(Resources)));
1571 if (!resources.empty())
1572 symtab->addFile(make<ObjFile>(convertResToCOFF(resources)));
13831573
1384 if (Tar)
1385 Tar->append("response.txt",
1386 createResponseFile(Args, FilePaths,
1387 ArrayRef<StringRef>(SearchPaths).slice(1)));
1574 if (tar)
1575 tar->append("response.txt",
1576 createResponseFile(args, filePaths,
1577 ArrayRef<StringRef>(searchPaths).slice(1)));
13881578
13891579 // Handle /largeaddressaware
1390 Config->LargeAddressAware = Args.hasFlag(
1391 OPT_largeaddressaware, OPT_largeaddressaware_no, Config->is64());
1580 config->largeAddressAware = args.hasFlag(
1581 OPT_largeaddressaware, OPT_largeaddressaware_no, config->is64());
13921582
13931583 // Handle /highentropyva
1394 Config->HighEntropyVA =
1395 Config->is64() &&
1396 Args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true);
1584 config->highEntropyVA =
1585 config->is64() &&
1586 args.hasFlag(OPT_highentropyva, OPT_highentropyva_no, true);
13971587
1398 if (!Config->DynamicBase &&
1399 (Config->Machine == ARMNT || Config->Machine == ARM64))
1588 if (!config->dynamicBase &&
1589 (config->machine == ARMNT || config->machine == ARM64))
14001590 error("/dynamicbase:no is not compatible with " +
1401 machineToStr(Config->Machine));
1591 machineToStr(config->machine));
14021592
14031593 // Handle /export
1404 for (auto *Arg : Args.filtered(OPT_export)) {
1405 Export E = parseExport(Arg->getValue());
1406 if (Config->Machine == I386) {
1407 if (!isDecorated(E.Name))
1408 E.Name = Saver.save("_" + E.Name);
1409 if (!E.ExtName.empty() && !isDecorated(E.ExtName))
1410 E.ExtName = Saver.save("_" + E.ExtName);
1594 for (auto *arg : args.filtered(OPT_export)) {
1595 Export e = parseExport(arg->getValue());
1596 if (config->machine == I386) {
1597 if (!isDecorated(e.name))
1598 e.name = saver.save("_" + e.name);
1599 if (!e.extName.empty() && !isDecorated(e.extName))
1600 e.extName = saver.save("_" + e.extName);
14111601 }
1412 Config->Exports.push_back(E);
1602 config->exports.push_back(e);
14131603 }
14141604
14151605 // Handle /def
1416 if (auto *Arg = Args.getLastArg(OPT_deffile)) {
1606 if (auto *arg = args.getLastArg(OPT_deffile)) {
14171607 // parseModuleDefs mutates Config object.
1418 parseModuleDefs(Arg->getValue());
1608 parseModuleDefs(arg->getValue());
14191609 }
14201610
14211611 // Handle generation of import library from a def file.
1422 if (!Args.hasArg(OPT_INPUT)) {
1612 if (!args.hasArg(OPT_INPUT)) {
14231613 fixupExports();
1424 createImportLibrary(/*AsLib=*/true);
1614 createImportLibrary(/*asLib=*/true);
14251615 return;
14261616 }
14271617
14281618 // Windows specific -- if no /subsystem is given, we need to infer
14291619 // that from entry point name. Must happen before /entry handling,
14301620 // and after the early return when just writing an import library.
1431 if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
1432 Config->Subsystem = inferSubsystem();
1433 if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
1621 if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
1622 config->subsystem = inferSubsystem();
1623 if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
14341624 fatal("subsystem must be defined");
14351625 }
14361626
14371627 // Handle /entry and /dll
1438 if (auto *Arg = Args.getLastArg(OPT_entry)) {
1439 Config->Entry = addUndefined(mangle(Arg->getValue()));
1440 } else if (!Config->Entry && !Config->NoEntry) {
1441 if (Args.hasArg(OPT_dll)) {
1442 StringRef S = (Config->Machine == I386) ? "__DllMainCRTStartup@12"
1628 if (auto *arg = args.getLastArg(OPT_entry)) {
1629 config->entry = addUndefined(mangle(arg->getValue()));
1630 } else if (!config->entry && !config->noEntry) {
1631 if (args.hasArg(OPT_dll)) {
1632 StringRef s = (config->machine == I386) ? "__DllMainCRTStartup@12"
14431633 : "_DllMainCRTStartup";
1444 Config->Entry = addUndefined(S);
1634 config->entry = addUndefined(s);
14451635 } else {
14461636 // Windows specific -- If entry point name is not given, we need to
14471637 // infer that from user-defined entry name.
1448 StringRef S = findDefaultEntry();
1449 if (S.empty())
1638 StringRef s = findDefaultEntry();
1639 if (s.empty())
14501640 fatal("entry point must be defined");
1451 Config->Entry = addUndefined(S);
1452 log("Entry name inferred: " + S);
1641 config->entry = addUndefined(s);
1642 log("Entry name inferred: " + s);
14531643 }
14541644 }
14551645
14561646 // Handle /delayload
1457 for (auto *Arg : Args.filtered(OPT_delayload)) {
1458 Config->DelayLoads.insert(StringRef(Arg->getValue()).lower());
1459 if (Config->Machine == I386) {
1460 Config->DelayLoadHelper = addUndefined("___delayLoadHelper2@8");
1647 for (auto *arg : args.filtered(OPT_delayload)) {
1648 config->delayLoads.insert(StringRef(arg->getValue()).lower());
1649 if (config->machine == I386) {
1650 config->delayLoadHelper = addUndefined("___delayLoadHelper2@8");
14611651 } else {
1462 Config->DelayLoadHelper = addUndefined("__delayLoadHelper2");
1652 config->delayLoadHelper = addUndefined("__delayLoadHelper2");
14631653 }
14641654 }
14651655
14661656 // Set default image name if neither /out or /def set it.
1467 if (Config->OutputFile.empty()) {
1468 Config->OutputFile =
1469 getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue());
1657 if (config->outputFile.empty()) {
1658 config->outputFile =
1659 getOutputPath((*args.filtered(OPT_INPUT).begin())->getValue());
14701660 }
14711661
1472 if (ShouldCreatePDB) {
1662 // Fail early if an output file is not writable.
1663 if (auto e = tryCreateFile(config->outputFile)) {
1664 error("cannot open output file " + config->outputFile + ": " + e.message());
1665 return;
1666 }
1667
1668 if (shouldCreatePDB) {
14731669 // Put the PDB next to the image if no /pdb flag was passed.
1474 if (Config->PDBPath.empty()) {
1475 Config->PDBPath = Config->OutputFile;
1476 sys::path::replace_extension(Config->PDBPath, ".pdb");
1670 if (config->pdbPath.empty()) {
1671 config->pdbPath = config->outputFile;
1672 sys::path::replace_extension(config->pdbPath, ".pdb");
14771673 }
14781674
14791675 // The embedded PDB path should be the absolute path to the PDB if no
14801676 // /pdbaltpath flag was passed.
1481 if (Config->PDBAltPath.empty()) {
1482 Config->PDBAltPath = Config->PDBPath;
1677 if (config->pdbAltPath.empty()) {
1678 config->pdbAltPath = config->pdbPath;
14831679
14841680 // It's important to make the path absolute and remove dots. This path
14851681 // will eventually be written into the PE header, and certain Microsoft
14861682 // tools won't work correctly if these assumptions are not held.
1487 sys::fs::make_absolute(Config->PDBAltPath);
1488 sys::path::remove_dots(Config->PDBAltPath);
1683 sys::fs::make_absolute(config->pdbAltPath);
1684 sys::path::remove_dots(config->pdbAltPath);
14891685 } else {
14901686 // Don't do this earlier, so that Config->OutputFile is ready.
1491 parsePDBAltPath(Config->PDBAltPath);
1687 parsePDBAltPath(config->pdbAltPath);
14921688 }
14931689 }
14941690
14951691 // Set default image base if /base is not given.
1496 if (Config->ImageBase == uint64_t(-1))
1497 Config->ImageBase = getDefaultImageBase();
1498
1499 Symtab->addSynthetic(mangle("__ImageBase"), nullptr);
1500 if (Config->Machine == I386) {
1501 Symtab->addAbsolute("___safe_se_handler_table", 0);
1502 Symtab->addAbsolute("___safe_se_handler_count", 0);
1503 }
1504
1505 Symtab->addAbsolute(mangle("__guard_fids_count"), 0);
1506 Symtab->addAbsolute(mangle("__guard_fids_table"), 0);
1507 Symtab->addAbsolute(mangle("__guard_flags"), 0);
1508 Symtab->addAbsolute(mangle("__guard_iat_count"), 0);
1509 Symtab->addAbsolute(mangle("__guard_iat_table"), 0);
1510 Symtab->addAbsolute(mangle("__guard_longjmp_count"), 0);
1511 Symtab->addAbsolute(mangle("__guard_longjmp_table"), 0);
1692 if (config->imageBase == uint64_t(-1))
1693 config->imageBase = getDefaultImageBase();
1694
1695 symtab->addSynthetic(mangle("__ImageBase"), nullptr);
1696 if (config->machine == I386) {
1697 symtab->addAbsolute("___safe_se_handler_table", 0);
1698 symtab->addAbsolute("___safe_se_handler_count", 0);
1699 }
1700
1701 symtab->addAbsolute(mangle("__guard_fids_count"), 0);
1702 symtab->addAbsolute(mangle("__guard_fids_table"), 0);
1703 symtab->addAbsolute(mangle("__guard_flags"), 0);
1704 symtab->addAbsolute(mangle("__guard_iat_count"), 0);
1705 symtab->addAbsolute(mangle("__guard_iat_table"), 0);
1706 symtab->addAbsolute(mangle("__guard_longjmp_count"), 0);
1707 symtab->addAbsolute(mangle("__guard_longjmp_table"), 0);
15121708 // Needed for MSVC 2017 15.5 CRT.
1513 Symtab->addAbsolute(mangle("__enclave_config"), 0);
1709 symtab->addAbsolute(mangle("__enclave_config"), 0);
15141710
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);
1711 if (config->mingw) {
1712 symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
1713 symtab->addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0);
1714 symtab->addAbsolute(mangle("__CTOR_LIST__"), 0);
1715 symtab->addAbsolute(mangle("__DTOR_LIST__"), 0);
15201716 }
15211717
15221718 // This code may add new undefined symbols to the link, which may enqueue more
......@@ -1525,33 +1721,33 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
15251721 do {
15261722 // Windows specific -- if entry point is not found,
15271723 // search for its mangled names.
1528 if (Config->Entry)
1529 Symtab->mangleMaybe(Config->Entry);
1724 if (config->entry)
1725 mangleMaybe(config->entry);
15301726
15311727 // Windows specific -- Make sure we resolve all dllexported symbols.
1532 for (Export &E : Config->Exports) {
1533 if (!E.ForwardTo.empty())
1728 for (Export &e : config->exports) {
1729 if (!e.forwardTo.empty())
15341730 continue;
1535 E.Sym = addUndefined(E.Name);
1536 if (!E.Directives)
1537 Symtab->mangleMaybe(E.Sym);
1731 e.sym = addUndefined(e.name);
1732 if (!e.directives)
1733 e.symbolName = mangleMaybe(e.sym);
15381734 }
15391735
15401736 // Add weak aliases. Weak aliases is a mechanism to give remaining
15411737 // undefined symbols final chance to be resolved successfully.
1542 for (auto Pair : Config->AlternateNames) {
1543 StringRef From = Pair.first;
1544 StringRef To = Pair.second;
1545 Symbol *Sym = Symtab->find(From);
1546 if (!Sym)
1738 for (auto pair : config->alternateNames) {
1739 StringRef from = pair.first;
1740 StringRef to = pair.second;
1741 Symbol *sym = symtab->find(from);
1742 if (!sym)
15471743 continue;
1548 if (auto *U = dyn_cast<Undefined>(Sym))
1549 if (!U->WeakAlias)
1550 U->WeakAlias = Symtab->addUndefined(To);
1744 if (auto *u = dyn_cast<Undefined>(sym))
1745 if (!u->weakAlias)
1746 u->weakAlias = symtab->addUndefined(to);
15511747 }
15521748
15531749 // Windows specific -- if __load_config_used can be resolved, resolve it.
1554 if (Symtab->findUnderscore("_load_config_used"))
1750 if (symtab->findUnderscore("_load_config_used"))
15551751 addUndefined(mangle("_load_config_used"));
15561752 } while (run());
15571753
......@@ -1559,11 +1755,29 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
15591755 return;
15601756
15611757 // Do LTO by compiling bitcode input files to a set of native COFF files then
1562 // link those files.
1563 Symtab->addCombinedLTOObjects();
1758 // link those files (unless -thinlto-index-only was given, in which case we
1759 // resolve symbols and write indices, but don't generate native code or link).
1760 symtab->addCombinedLTOObjects();
1761
1762 // If -thinlto-index-only is given, we should create only "index
1763 // files" and not object files. Index file creation is already done
1764 // in addCombinedLTOObject, so we are done if that's the case.
1765 if (config->thinLTOIndexOnly)
1766 return;
1767
1768 // If we generated native object files from bitcode files, this resolves
1769 // references to the symbols we use from them.
15641770 run();
15651771
1566 if (Config->MinGW) {
1772 if (args.hasArg(OPT_include_optional)) {
1773 // Handle /includeoptional
1774 for (auto *arg : args.filtered(OPT_include_optional))
1775 if (dyn_cast_or_null<Lazy>(symtab->find(arg->getValue())))
1776 addUndefined(arg->getValue());
1777 while (run());
1778 }
1779
1780 if (config->mingw) {
15671781 // Load any further object files that might be needed for doing automatic
15681782 // imports.
15691783 //
......@@ -1577,95 +1791,91 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
15771791 // normal object file as well (although that won't be used for the
15781792 // actual autoimport later on). If this pass adds new undefined references,
15791793 // we won't iterate further to resolve them.
1580 Symtab->loadMinGWAutomaticImports();
1794 symtab->loadMinGWAutomaticImports();
15811795 run();
15821796 }
15831797
15841798 // Make sure we have resolved all symbols.
1585 Symtab->reportRemainingUndefines();
1799 symtab->reportRemainingUndefines();
15861800 if (errorCount())
15871801 return;
15881802
1589 // Handle /safeseh.
1590 if (Args.hasFlag(OPT_safeseh, OPT_safeseh_no, false)) {
1591 for (ObjFile *File : ObjFile::Instances)
1592 if (!File->hasSafeSEH())
1593 error("/safeseh: " + File->getName() + " is not compatible with SEH");
1594 if (errorCount())
1595 return;
1596 }
1597
1598 // In MinGW, all symbols are automatically exported if no symbols
1599 // are chosen to be exported.
1600 if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) ||
1601 Args.hasArg(OPT_export_all_symbols))) {
1602 Exporter.initSymbolExcludes();
1603
1604 Symtab->forEachSymbol([=](Symbol *S) {
1605 auto *Def = dyn_cast<Defined>(S);
1606 if (!Exporter.shouldExport(Def))
1607 return;
1608 Export E;
1609 E.Name = Def->getName();
1610 E.Sym = Def;
1611 if (Def->getChunk() &&
1612 !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
1613 E.Data = true;
1614 Config->Exports.push_back(E);
1615 });
1803 if (config->mingw) {
1804 // In MinGW, all symbols are automatically exported if no symbols
1805 // are chosen to be exported.
1806 maybeExportMinGWSymbols(args);
1807
1808 // Make sure the crtend.o object is the last object file. This object
1809 // file can contain terminating section chunks that need to be placed
1810 // last. GNU ld processes files and static libraries explicitly in the
1811 // order provided on the command line, while lld will pull in needed
1812 // files from static libraries only after the last object file on the
1813 // command line.
1814 for (auto i = ObjFile::instances.begin(), e = ObjFile::instances.end();
1815 i != e; i++) {
1816 ObjFile *file = *i;
1817 if (isCrtend(file->getName())) {
1818 ObjFile::instances.erase(i);
1819 ObjFile::instances.push_back(file);
1820 break;
1821 }
1822 }
16161823 }
16171824
16181825 // Windows specific -- when we are creating a .dll file, we also
16191826 // need to create a .lib file.
1620 if (!Config->Exports.empty() || Config->DLL) {
1827 if (!config->exports.empty() || config->dll) {
16211828 fixupExports();
1622 createImportLibrary(/*AsLib=*/false);
1829 createImportLibrary(/*asLib=*/false);
16231830 assignExportOrdinals();
16241831 }
16251832
16261833 // Handle /output-def (MinGW specific).
1627 if (auto *Arg = Args.getLastArg(OPT_output_def))
1628 writeDefFile(Arg->getValue());
1834 if (auto *arg = args.getLastArg(OPT_output_def))
1835 writeDefFile(arg->getValue());
16291836
16301837 // Set extra alignment for .comm symbols
1631 for (auto Pair : Config->AlignComm) {
1632 StringRef Name = Pair.first;
1633 uint32_t Alignment = Pair.second;
1838 for (auto pair : config->alignComm) {
1839 StringRef name = pair.first;
1840 uint32_t alignment = pair.second;
16341841
1635 Symbol *Sym = Symtab->find(Name);
1636 if (!Sym) {
1637 warn("/aligncomm symbol " + Name + " not found");
1842 Symbol *sym = symtab->find(name);
1843 if (!sym) {
1844 warn("/aligncomm symbol " + name + " not found");
16381845 continue;
16391846 }
16401847
16411848 // If the symbol isn't common, it must have been replaced with a regular
16421849 // symbol, which will carry its own alignment.
1643 auto *DC = dyn_cast<DefinedCommon>(Sym);
1644 if (!DC)
1850 auto *dc = dyn_cast<DefinedCommon>(sym);
1851 if (!dc)
16451852 continue;
16461853
1647 CommonChunk *C = DC->getChunk();
1648 C->Alignment = std::max(C->Alignment, Alignment);
1854 CommonChunk *c = dc->getChunk();
1855 c->setAlignment(std::max(c->getAlignment(), alignment));
16491856 }
16501857
16511858 // Windows specific -- Create a side-by-side manifest file.
1652 if (Config->Manifest == Configuration::SideBySide)
1859 if (config->manifest == Configuration::SideBySide)
16531860 createSideBySideManifest();
16541861
16551862 // Handle /order. We want to do this at this moment because we
16561863 // need a complete list of comdat sections to warn on nonexistent
16571864 // functions.
1658 if (auto *Arg = Args.getLastArg(OPT_order))
1659 parseOrderFile(Arg->getValue());
1865 if (auto *arg = args.getLastArg(OPT_order))
1866 parseOrderFile(arg->getValue());
16601867
16611868 // Identify unreferenced COMDAT sections.
1662 if (Config->DoGC)
1663 markLive(Symtab->getChunks());
1869 if (config->doGC)
1870 markLive(symtab->getChunks());
1871
1872 // Needs to happen after the last call to addFile().
1873 diagnoseMultipleResourceObjFiles();
16641874
16651875 // Identify identical COMDAT sections to merge them.
1666 if (Config->DoICF) {
1876 if (config->doICF) {
16671877 findKeepUniqueSections();
1668 doICF(Symtab->getChunks());
1878 doICF(symtab->getChunks());
16691879 }
16701880
16711881 // Write the result.
......@@ -1673,7 +1883,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
16731883
16741884 // Stop early so we can print the results.
16751885 Timer::root().stop();
1676 if (Config->ShowTiming)
1886 if (config->showTiming)
16771887 Timer::root().print();
16781888}
16791889
deps/lld/COFF/Driver.h+58-53
......@@ -1,9 +1,8 @@
11//===- Driver.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -31,7 +30,7 @@ namespace lld {
3130namespace coff {
3231
3332class LinkerDriver;
34extern LinkerDriver *Driver;
33extern LinkerDriver *driver;
3534
3635using llvm::COFF::MachineTypes;
3736using llvm::COFF::WindowsSubsystem;
......@@ -45,65 +44,71 @@ public:
4544class ArgParser {
4645public:
4746 // Concatenate LINK environment variable and given arguments and parse them.
48 llvm::opt::InputArgList parseLINK(std::vector<const char *> Args);
47 llvm::opt::InputArgList parseLINK(std::vector<const char *> args);
4948
5049 // Tokenizes a given string and then parses as command line options.
51 llvm::opt::InputArgList parse(StringRef S) { return parse(tokenize(S)); }
50 llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); }
5251
5352 // Tokenizes a given string and then parses as command line options in
5453 // .drectve section. /EXPORT options are returned in second element
5554 // to be processed in fastpath.
5655 std::pair<llvm::opt::InputArgList, std::vector<StringRef>>
57 parseDirectives(StringRef S);
56 parseDirectives(StringRef s);
5857
5958private:
6059 // Parses command line options.
61 llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> Args);
60 llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);
6261
63 std::vector<const char *> tokenize(StringRef S);
62 std::vector<const char *> tokenize(StringRef s);
6463
65 COFFOptTable Table;
64 COFFOptTable table;
6665};
6766
6867class LinkerDriver {
6968public:
70 void link(llvm::ArrayRef<const char *> Args);
69 void link(llvm::ArrayRef<const char *> args);
7170
7271 // Used by the resolver to parse .drectve section contents.
73 void parseDirectives(StringRef S);
72 void parseDirectives(InputFile *file);
7473
7574 // Used by ArchiveFile to enqueue members.
76 void enqueueArchiveMember(const Archive::Child &C, StringRef SymName,
77 StringRef ParentName);
75 void enqueueArchiveMember(const Archive::Child &c, StringRef symName,
76 StringRef parentName);
77
78 MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb);
7879
79 MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
80 void enqueuePath(StringRef path, bool wholeArchive);
8081
8182private:
82 std::unique_ptr<llvm::TarWriter> Tar; // for /linkrepro
83 std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro
8384
8485 // Opens a file. Path has to be resolved already.
85 MemoryBufferRef openFile(StringRef Path);
86 MemoryBufferRef openFile(StringRef path);
8687
8788 // Searches a file from search paths.
88 Optional<StringRef> findFile(StringRef Filename);
89 Optional<StringRef> findLib(StringRef Filename);
90 StringRef doFindFile(StringRef Filename);
91 StringRef doFindLib(StringRef Filename);
92 StringRef doFindLibMinGW(StringRef Filename);
89 Optional<StringRef> findFile(StringRef filename);
90 Optional<StringRef> findLib(StringRef filename);
91 StringRef doFindFile(StringRef filename);
92 StringRef doFindLib(StringRef filename);
93 StringRef doFindLibMinGW(StringRef filename);
9394
9495 // Parses LIB environment which contains a list of search paths.
9596 void addLibSearchPaths();
9697
9798 // Library search path. The first element is always "" (current directory).
98 std::vector<StringRef> SearchPaths;
99 std::vector<StringRef> searchPaths;
100
101 void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args);
99102
100103 // We don't want to add the same file more than once.
101104 // Files are uniquified by their filesystem and file number.
102 std::set<llvm::sys::fs::UniqueID> VisitedFiles;
105 std::set<llvm::sys::fs::UniqueID> visitedFiles;
106
107 std::set<std::string> visitedLibs;
103108
104 std::set<std::string> VisitedLibs;
109 Symbol *addUndefined(StringRef sym);
105110
106 Symbol *addUndefined(StringRef Sym);
111 StringRef mangleMaybe(Symbol *s);
107112
108113 // Windows specific -- "main" is not the only main function in Windows.
109114 // You can choose one from these four -- {w,}{WinMain,main}.
......@@ -115,60 +120,60 @@ private:
115120 StringRef findDefaultEntry();
116121 WindowsSubsystem inferSubsystem();
117122
118 void addBuffer(std::unique_ptr<MemoryBuffer> MB, bool WholeArchive);
119 void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
120 StringRef ParentName);
123 void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive);
124 void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,
125 StringRef parentName, uint64_t offsetInArchive);
121126
122 void enqueuePath(StringRef Path, bool WholeArchive);
123
124 void enqueueTask(std::function<void()> Task);
127 void enqueueTask(std::function<void()> task);
125128 bool run();
126129
127 std::list<std::function<void()>> TaskQueue;
128 std::vector<StringRef> FilePaths;
129 std::vector<MemoryBufferRef> Resources;
130 std::list<std::function<void()>> taskQueue;
131 std::vector<StringRef> filePaths;
132 std::vector<MemoryBufferRef> resources;
130133
131 llvm::StringSet<> DirectivesExports;
134 llvm::StringSet<> directivesExports;
132135};
133136
134137// Functions below this line are defined in DriverUtils.cpp.
135138
136void printHelp(const char *Argv0);
137
138// For /machine option.
139MachineTypes getMachineType(StringRef Arg);
140StringRef machineToStr(MachineTypes MT);
139void printHelp(const char *argv0);
141140
142141// Parses a string in the form of "<integer>[,<integer>]".
143void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size = nullptr);
142void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size = nullptr);
144143
145void parseGuard(StringRef Arg);
144void parseGuard(StringRef arg);
146145
147146// Parses a string in the form of "<integer>[.<integer>]".
148147// Minor's default value is 0.
149void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor);
148void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor);
150149
151150// Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".
152void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major,
153 uint32_t *Minor);
151void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major,
152 uint32_t *minor);
154153
155154void parseAlternateName(StringRef);
156155void parseMerge(StringRef);
157156void parseSection(StringRef);
158157void parseAligncomm(StringRef);
159158
159// Parses a string in the form of "[:<integer>]"
160void parseFunctionPadMin(llvm::opt::Arg *a, llvm::COFF::MachineTypes machine);
161
160162// Parses a string in the form of "EMBED[,=<integer>]|NO".
161void parseManifest(StringRef Arg);
163void parseManifest(StringRef arg);
162164
163165// Parses a string in the form of "level=<string>|uiAccess=<string>"
164void parseManifestUAC(StringRef Arg);
166void parseManifestUAC(StringRef arg);
167
168// Parses a string in the form of "cd|net[,(cd|net)]*"
169void parseSwaprun(StringRef arg);
165170
166171// Create a resource file containing a manifest XML.
167172std::unique_ptr<MemoryBuffer> createManifestRes();
168173void createSideBySideManifest();
169174
170175// Used for dllexported symbols.
171Export parseExport(StringRef Arg);
176Export parseExport(StringRef arg);
172177void fixupExports();
173178void assignExportOrdinals();
174179
......@@ -176,12 +181,12 @@ void assignExportOrdinals();
176181// if value matches previous values for the key.
177182// This feature used in the directive section to reject
178183// incompatible objects.
179void checkFailIfMismatch(StringRef Arg);
184void checkFailIfMismatch(StringRef arg, InputFile *source);
180185
181186// Convert Windows resource files (.res files) to a .obj file.
182MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs);
187MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs);
183188
184void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);
189void runMSVCLinker(std::string rsp, ArrayRef<StringRef> objects);
185190
186191// Create enum with OPT_xxx values for each option in Options.td
187192enum {
deps/lld/COFF/DriverUtils.cpp+495-470
......@@ -1,9 +1,8 @@
11//===- DriverUtils.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -48,104 +47,78 @@ const uint16_t RT_MANIFEST = 24;
4847
4948class Executor {
5049public:
51 explicit Executor(StringRef S) : Prog(Saver.save(S)) {}
52 void add(StringRef S) { Args.push_back(Saver.save(S)); }
53 void add(std::string &S) { Args.push_back(Saver.save(S)); }
54 void add(Twine S) { Args.push_back(Saver.save(S)); }
55 void add(const char *S) { Args.push_back(Saver.save(S)); }
50 explicit Executor(StringRef s) : prog(saver.save(s)) {}
51 void add(StringRef s) { args.push_back(saver.save(s)); }
52 void add(std::string &s) { args.push_back(saver.save(s)); }
53 void add(Twine s) { args.push_back(saver.save(s)); }
54 void add(const char *s) { args.push_back(saver.save(s)); }
5655
5756 void run() {
58 ErrorOr<std::string> ExeOrErr = sys::findProgramByName(Prog);
59 if (auto EC = ExeOrErr.getError())
60 fatal("unable to find " + Prog + " in PATH: " + EC.message());
61 StringRef Exe = Saver.save(*ExeOrErr);
62 Args.insert(Args.begin(), Exe);
57 ErrorOr<std::string> exeOrErr = sys::findProgramByName(prog);
58 if (auto ec = exeOrErr.getError())
59 fatal("unable to find " + prog + " in PATH: " + ec.message());
60 StringRef exe = saver.save(*exeOrErr);
61 args.insert(args.begin(), exe);
6362
64 if (sys::ExecuteAndWait(Args[0], Args) != 0)
63 if (sys::ExecuteAndWait(args[0], args) != 0)
6564 fatal("ExecuteAndWait failed: " +
66 llvm::join(Args.begin(), Args.end(), " "));
65 llvm::join(args.begin(), args.end(), " "));
6766 }
6867
6968private:
70 StringRef Prog;
71 std::vector<StringRef> Args;
69 StringRef prog;
70 std::vector<StringRef> args;
7271};
7372
7473} // anonymous namespace
7574
76// Returns /machine's value.
77MachineTypes getMachineType(StringRef S) {
78 MachineTypes MT = StringSwitch<MachineTypes>(S.lower())
79 .Cases("x64", "amd64", AMD64)
80 .Cases("x86", "i386", I386)
81 .Case("arm", ARMNT)
82 .Case("arm64", ARM64)
83 .Default(IMAGE_FILE_MACHINE_UNKNOWN);
84 if (MT != IMAGE_FILE_MACHINE_UNKNOWN)
85 return MT;
86 fatal("unknown /machine argument: " + S);
87}
88
89StringRef machineToStr(MachineTypes MT) {
90 switch (MT) {
91 case ARMNT:
92 return "arm";
93 case ARM64:
94 return "arm64";
95 case AMD64:
96 return "x64";
97 case I386:
98 return "x86";
99 default:
100 llvm_unreachable("unknown machine type");
101 }
102}
103
10475// Parses a string in the form of "<integer>[,<integer>]".
105void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size) {
106 StringRef S1, S2;
107 std::tie(S1, S2) = Arg.split(',');
108 if (S1.getAsInteger(0, *Addr))
109 fatal("invalid number: " + S1);
110 if (Size && !S2.empty() && S2.getAsInteger(0, *Size))
111 fatal("invalid number: " + S2);
76void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size) {
77 StringRef s1, s2;
78 std::tie(s1, s2) = arg.split(',');
79 if (s1.getAsInteger(0, *addr))
80 fatal("invalid number: " + s1);
81 if (size && !s2.empty() && s2.getAsInteger(0, *size))
82 fatal("invalid number: " + s2);
11283}
11384
11485// Parses a string in the form of "<integer>[.<integer>]".
11586// If second number is not present, Minor is set to 0.
116void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor) {
117 StringRef S1, S2;
118 std::tie(S1, S2) = Arg.split('.');
119 if (S1.getAsInteger(0, *Major))
120 fatal("invalid number: " + S1);
121 *Minor = 0;
122 if (!S2.empty() && S2.getAsInteger(0, *Minor))
123 fatal("invalid number: " + S2);
124}
125
126void parseGuard(StringRef FullArg) {
127 SmallVector<StringRef, 1> SplitArgs;
128 FullArg.split(SplitArgs, ",");
129 for (StringRef Arg : SplitArgs) {
130 if (Arg.equals_lower("no"))
131 Config->GuardCF = GuardCFLevel::Off;
132 else if (Arg.equals_lower("nolongjmp"))
133 Config->GuardCF = GuardCFLevel::NoLongJmp;
134 else if (Arg.equals_lower("cf") || Arg.equals_lower("longjmp"))
135 Config->GuardCF = GuardCFLevel::Full;
87void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor) {
88 StringRef s1, s2;
89 std::tie(s1, s2) = arg.split('.');
90 if (s1.getAsInteger(0, *major))
91 fatal("invalid number: " + s1);
92 *minor = 0;
93 if (!s2.empty() && s2.getAsInteger(0, *minor))
94 fatal("invalid number: " + s2);
95}
96
97void parseGuard(StringRef fullArg) {
98 SmallVector<StringRef, 1> splitArgs;
99 fullArg.split(splitArgs, ",");
100 for (StringRef arg : splitArgs) {
101 if (arg.equals_lower("no"))
102 config->guardCF = GuardCFLevel::Off;
103 else if (arg.equals_lower("nolongjmp"))
104 config->guardCF = GuardCFLevel::NoLongJmp;
105 else if (arg.equals_lower("cf") || arg.equals_lower("longjmp"))
106 config->guardCF = GuardCFLevel::Full;
136107 else
137 fatal("invalid argument to /guard: " + Arg);
108 fatal("invalid argument to /guard: " + arg);
138109 }
139110}
140111
141112// Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".
142void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major,
143 uint32_t *Minor) {
144 StringRef SysStr, Ver;
145 std::tie(SysStr, Ver) = Arg.split(',');
146 *Sys = StringSwitch<WindowsSubsystem>(SysStr.lower())
113void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major,
114 uint32_t *minor) {
115 StringRef sysStr, ver;
116 std::tie(sysStr, ver) = arg.split(',');
117 std::string sysStrLower = sysStr.lower();
118 *sys = StringSwitch<WindowsSubsystem>(sysStrLower)
147119 .Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
148120 .Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI)
121 .Case("default", IMAGE_SUBSYSTEM_UNKNOWN)
149122 .Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION)
150123 .Case("efi_boot_service_driver", IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
151124 .Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM)
......@@ -154,175 +127,217 @@ void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major,
154127 .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI)
155128 .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI)
156129 .Default(IMAGE_SUBSYSTEM_UNKNOWN);
157 if (*Sys == IMAGE_SUBSYSTEM_UNKNOWN)
158 fatal("unknown subsystem: " + SysStr);
159 if (!Ver.empty())
160 parseVersion(Ver, Major, Minor);
130 if (*sys == IMAGE_SUBSYSTEM_UNKNOWN && sysStrLower != "default")
131 fatal("unknown subsystem: " + sysStr);
132 if (!ver.empty())
133 parseVersion(ver, major, minor);
161134}
162135
163136// Parse a string of the form of "<from>=<to>".
164137// Results are directly written to Config.
165void parseAlternateName(StringRef S) {
166 StringRef From, To;
167 std::tie(From, To) = S.split('=');
168 if (From.empty() || To.empty())
169 fatal("/alternatename: invalid argument: " + S);
170 auto It = Config->AlternateNames.find(From);
171 if (It != Config->AlternateNames.end() && It->second != To)
172 fatal("/alternatename: conflicts: " + S);
173 Config->AlternateNames.insert(It, std::make_pair(From, To));
138void parseAlternateName(StringRef s) {
139 StringRef from, to;
140 std::tie(from, to) = s.split('=');
141 if (from.empty() || to.empty())
142 fatal("/alternatename: invalid argument: " + s);
143 auto it = config->alternateNames.find(from);
144 if (it != config->alternateNames.end() && it->second != to)
145 fatal("/alternatename: conflicts: " + s);
146 config->alternateNames.insert(it, std::make_pair(from, to));
174147}
175148
176149// Parse a string of the form of "<from>=<to>".
177150// Results are directly written to Config.
178void parseMerge(StringRef S) {
179 StringRef From, To;
180 std::tie(From, To) = S.split('=');
181 if (From.empty() || To.empty())
182 fatal("/merge: invalid argument: " + S);
183 if (From == ".rsrc" || To == ".rsrc")
151void parseMerge(StringRef s) {
152 StringRef from, to;
153 std::tie(from, to) = s.split('=');
154 if (from.empty() || to.empty())
155 fatal("/merge: invalid argument: " + s);
156 if (from == ".rsrc" || to == ".rsrc")
184157 fatal("/merge: cannot merge '.rsrc' with any section");
185 if (From == ".reloc" || To == ".reloc")
158 if (from == ".reloc" || to == ".reloc")
186159 fatal("/merge: cannot merge '.reloc' with any section");
187 auto Pair = Config->Merge.insert(std::make_pair(From, To));
188 bool Inserted = Pair.second;
189 if (!Inserted) {
190 StringRef Existing = Pair.first->second;
191 if (Existing != To)
192 warn(S + ": already merged into " + Existing);
160 auto pair = config->merge.insert(std::make_pair(from, to));
161 bool inserted = pair.second;
162 if (!inserted) {
163 StringRef existing = pair.first->second;
164 if (existing != to)
165 warn(s + ": already merged into " + existing);
193166 }
194167}
195168
196static uint32_t parseSectionAttributes(StringRef S) {
197 uint32_t Ret = 0;
198 for (char C : S.lower()) {
199 switch (C) {
169static uint32_t parseSectionAttributes(StringRef s) {
170 uint32_t ret = 0;
171 for (char c : s.lower()) {
172 switch (c) {
200173 case 'd':
201 Ret |= IMAGE_SCN_MEM_DISCARDABLE;
174 ret |= IMAGE_SCN_MEM_DISCARDABLE;
202175 break;
203176 case 'e':
204 Ret |= IMAGE_SCN_MEM_EXECUTE;
177 ret |= IMAGE_SCN_MEM_EXECUTE;
205178 break;
206179 case 'k':
207 Ret |= IMAGE_SCN_MEM_NOT_CACHED;
180 ret |= IMAGE_SCN_MEM_NOT_CACHED;
208181 break;
209182 case 'p':
210 Ret |= IMAGE_SCN_MEM_NOT_PAGED;
183 ret |= IMAGE_SCN_MEM_NOT_PAGED;
211184 break;
212185 case 'r':
213 Ret |= IMAGE_SCN_MEM_READ;
186 ret |= IMAGE_SCN_MEM_READ;
214187 break;
215188 case 's':
216 Ret |= IMAGE_SCN_MEM_SHARED;
189 ret |= IMAGE_SCN_MEM_SHARED;
217190 break;
218191 case 'w':
219 Ret |= IMAGE_SCN_MEM_WRITE;
192 ret |= IMAGE_SCN_MEM_WRITE;
220193 break;
221194 default:
222 fatal("/section: invalid argument: " + S);
195 fatal("/section: invalid argument: " + s);
223196 }
224197 }
225 return Ret;
198 return ret;
226199}
227200
228201// Parses /section option argument.
229void parseSection(StringRef S) {
230 StringRef Name, Attrs;
231 std::tie(Name, Attrs) = S.split(',');
232 if (Name.empty() || Attrs.empty())
233 fatal("/section: invalid argument: " + S);
234 Config->Section[Name] = parseSectionAttributes(Attrs);
202void parseSection(StringRef s) {
203 StringRef name, attrs;
204 std::tie(name, attrs) = s.split(',');
205 if (name.empty() || attrs.empty())
206 fatal("/section: invalid argument: " + s);
207 config->section[name] = parseSectionAttributes(attrs);
235208}
236209
237210// Parses /aligncomm option argument.
238void parseAligncomm(StringRef S) {
239 StringRef Name, Align;
240 std::tie(Name, Align) = S.split(',');
241 if (Name.empty() || Align.empty()) {
242 error("/aligncomm: invalid argument: " + S);
211void parseAligncomm(StringRef s) {
212 StringRef name, align;
213 std::tie(name, align) = s.split(',');
214 if (name.empty() || align.empty()) {
215 error("/aligncomm: invalid argument: " + s);
216 return;
217 }
218 int v;
219 if (align.getAsInteger(0, v)) {
220 error("/aligncomm: invalid argument: " + s);
243221 return;
244222 }
245 int V;
246 if (Align.getAsInteger(0, V)) {
247 error("/aligncomm: invalid argument: " + S);
223 config->alignComm[name] = std::max(config->alignComm[name], 1 << v);
224}
225
226// Parses /functionpadmin option argument.
227void parseFunctionPadMin(llvm::opt::Arg *a, llvm::COFF::MachineTypes machine) {
228 StringRef arg = a->getNumValues() ? a->getValue() : "";
229 if (!arg.empty()) {
230 // Optional padding in bytes is given.
231 if (arg.getAsInteger(0, config->functionPadMin))
232 error("/functionpadmin: invalid argument: " + arg);
248233 return;
249234 }
250 Config->AlignComm[Name] = std::max(Config->AlignComm[Name], 1 << V);
235 // No optional argument given.
236 // Set default padding based on machine, similar to link.exe.
237 // There is no default padding for ARM platforms.
238 if (machine == I386) {
239 config->functionPadMin = 5;
240 } else if (machine == AMD64) {
241 config->functionPadMin = 6;
242 } else {
243 error("/functionpadmin: invalid argument for this machine: " + arg);
244 }
251245}
252246
253247// Parses a string in the form of "EMBED[,=<integer>]|NO".
254248// Results are directly written to Config.
255void parseManifest(StringRef Arg) {
256 if (Arg.equals_lower("no")) {
257 Config->Manifest = Configuration::No;
249void parseManifest(StringRef arg) {
250 if (arg.equals_lower("no")) {
251 config->manifest = Configuration::No;
258252 return;
259253 }
260 if (!Arg.startswith_lower("embed"))
261 fatal("invalid option " + Arg);
262 Config->Manifest = Configuration::Embed;
263 Arg = Arg.substr(strlen("embed"));
264 if (Arg.empty())
254 if (!arg.startswith_lower("embed"))
255 fatal("invalid option " + arg);
256 config->manifest = Configuration::Embed;
257 arg = arg.substr(strlen("embed"));
258 if (arg.empty())
265259 return;
266 if (!Arg.startswith_lower(",id="))
267 fatal("invalid option " + Arg);
268 Arg = Arg.substr(strlen(",id="));
269 if (Arg.getAsInteger(0, Config->ManifestID))
270 fatal("invalid option " + Arg);
260 if (!arg.startswith_lower(",id="))
261 fatal("invalid option " + arg);
262 arg = arg.substr(strlen(",id="));
263 if (arg.getAsInteger(0, config->manifestID))
264 fatal("invalid option " + arg);
271265}
272266
273267// Parses a string in the form of "level=<string>|uiAccess=<string>|NO".
274268// Results are directly written to Config.
275void parseManifestUAC(StringRef Arg) {
276 if (Arg.equals_lower("no")) {
277 Config->ManifestUAC = false;
269void parseManifestUAC(StringRef arg) {
270 if (arg.equals_lower("no")) {
271 config->manifestUAC = false;
278272 return;
279273 }
280274 for (;;) {
281 Arg = Arg.ltrim();
282 if (Arg.empty())
275 arg = arg.ltrim();
276 if (arg.empty())
283277 return;
284 if (Arg.startswith_lower("level=")) {
285 Arg = Arg.substr(strlen("level="));
286 std::tie(Config->ManifestLevel, Arg) = Arg.split(" ");
278 if (arg.startswith_lower("level=")) {
279 arg = arg.substr(strlen("level="));
280 std::tie(config->manifestLevel, arg) = arg.split(" ");
287281 continue;
288282 }
289 if (Arg.startswith_lower("uiaccess=")) {
290 Arg = Arg.substr(strlen("uiaccess="));
291 std::tie(Config->ManifestUIAccess, Arg) = Arg.split(" ");
283 if (arg.startswith_lower("uiaccess=")) {
284 arg = arg.substr(strlen("uiaccess="));
285 std::tie(config->manifestUIAccess, arg) = arg.split(" ");
292286 continue;
293287 }
294 fatal("invalid option " + Arg);
288 fatal("invalid option " + arg);
295289 }
296290}
297291
292// Parses a string in the form of "cd|net[,(cd|net)]*"
293// Results are directly written to Config.
294void parseSwaprun(StringRef arg) {
295 do {
296 StringRef swaprun, newArg;
297 std::tie(swaprun, newArg) = arg.split(',');
298 if (swaprun.equals_lower("cd"))
299 config->swaprunCD = true;
300 else if (swaprun.equals_lower("net"))
301 config->swaprunNet = true;
302 else if (swaprun.empty())
303 error("/swaprun: missing argument");
304 else
305 error("/swaprun: invalid argument: " + swaprun);
306 // To catch trailing commas, e.g. `/spawrun:cd,`
307 if (newArg.empty() && arg.endswith(","))
308 error("/swaprun: missing argument");
309 arg = newArg;
310 } while (!arg.empty());
311}
312
298313// An RAII temporary file class that automatically removes a temporary file.
299314namespace {
300315class TemporaryFile {
301316public:
302 TemporaryFile(StringRef Prefix, StringRef Extn, StringRef Contents = "") {
303 SmallString<128> S;
304 if (auto EC = sys::fs::createTemporaryFile("lld-" + Prefix, Extn, S))
305 fatal("cannot create a temporary file: " + EC.message());
306 Path = S.str();
307
308 if (!Contents.empty()) {
309 std::error_code EC;
310 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
311 if (EC)
312 fatal("failed to open " + Path + ": " + EC.message());
313 OS << Contents;
317 TemporaryFile(StringRef prefix, StringRef extn, StringRef contents = "") {
318 SmallString<128> s;
319 if (auto ec = sys::fs::createTemporaryFile("lld-" + prefix, extn, s))
320 fatal("cannot create a temporary file: " + ec.message());
321 path = s.str();
322
323 if (!contents.empty()) {
324 std::error_code ec;
325 raw_fd_ostream os(path, ec, sys::fs::F_None);
326 if (ec)
327 fatal("failed to open " + path + ": " + ec.message());
328 os << contents;
314329 }
315330 }
316331
317 TemporaryFile(TemporaryFile &&Obj) {
318 std::swap(Path, Obj.Path);
332 TemporaryFile(TemporaryFile &&obj) {
333 std::swap(path, obj.path);
319334 }
320335
321336 ~TemporaryFile() {
322 if (Path.empty())
337 if (path.empty())
323338 return;
324 if (sys::fs::remove(Path))
325 fatal("failed to remove " + Path);
339 if (sys::fs::remove(path))
340 fatal("failed to remove " + path);
326341 }
327342
328343 // Returns a memory buffer of this temporary file.
......@@ -330,387 +345,390 @@ public:
330345 // so it is safe to remove the file immediately after this function
331346 // is called (you cannot remove an opened file on Windows.)
332347 std::unique_ptr<MemoryBuffer> getMemoryBuffer() {
333 // IsVolatileSize=true forces MemoryBuffer to not use mmap().
334 return CHECK(MemoryBuffer::getFile(Path, /*FileSize=*/-1,
348 // IsVolatile=true forces MemoryBuffer to not use mmap().
349 return CHECK(MemoryBuffer::getFile(path, /*FileSize=*/-1,
335350 /*RequiresNullTerminator=*/false,
336 /*IsVolatileSize=*/true),
337 "could not open " + Path);
351 /*IsVolatile=*/true),
352 "could not open " + path);
338353 }
339354
340 std::string Path;
355 std::string path;
341356};
342357}
343358
344359static std::string createDefaultXml() {
345 std::string Ret;
346 raw_string_ostream OS(Ret);
360 std::string ret;
361 raw_string_ostream os(ret);
347362
348363 // Emit the XML. Note that we do *not* verify that the XML attributes are
349364 // syntactically correct. This is intentional for link.exe compatibility.
350 OS << "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
365 os << "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
351366 << "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n"
352367 << " manifestVersion=\"1.0\">\n";
353 if (Config->ManifestUAC) {
354 OS << " <trustInfo>\n"
368 if (config->manifestUAC) {
369 os << " <trustInfo>\n"
355370 << " <security>\n"
356371 << " <requestedPrivileges>\n"
357 << " <requestedExecutionLevel level=" << Config->ManifestLevel
358 << " uiAccess=" << Config->ManifestUIAccess << "/>\n"
372 << " <requestedExecutionLevel level=" << config->manifestLevel
373 << " uiAccess=" << config->manifestUIAccess << "/>\n"
359374 << " </requestedPrivileges>\n"
360375 << " </security>\n"
361376 << " </trustInfo>\n";
362377 }
363 if (!Config->ManifestDependency.empty()) {
364 OS << " <dependency>\n"
378 if (!config->manifestDependency.empty()) {
379 os << " <dependency>\n"
365380 << " <dependentAssembly>\n"
366 << " <assemblyIdentity " << Config->ManifestDependency << " />\n"
381 << " <assemblyIdentity " << config->manifestDependency << " />\n"
367382 << " </dependentAssembly>\n"
368383 << " </dependency>\n";
369384 }
370 OS << "</assembly>\n";
371 return OS.str();
385 os << "</assembly>\n";
386 return os.str();
372387}
373388
374static std::string createManifestXmlWithInternalMt(StringRef DefaultXml) {
375 std::unique_ptr<MemoryBuffer> DefaultXmlCopy =
376 MemoryBuffer::getMemBufferCopy(DefaultXml);
389static std::string createManifestXmlWithInternalMt(StringRef defaultXml) {
390 std::unique_ptr<MemoryBuffer> defaultXmlCopy =
391 MemoryBuffer::getMemBufferCopy(defaultXml);
377392
378 windows_manifest::WindowsManifestMerger Merger;
379 if (auto E = Merger.merge(*DefaultXmlCopy.get()))
393 windows_manifest::WindowsManifestMerger merger;
394 if (auto e = merger.merge(*defaultXmlCopy.get()))
380395 fatal("internal manifest tool failed on default xml: " +
381 toString(std::move(E)));
396 toString(std::move(e)));
382397
383 for (StringRef Filename : Config->ManifestInput) {
384 std::unique_ptr<MemoryBuffer> Manifest =
385 check(MemoryBuffer::getFile(Filename));
386 if (auto E = Merger.merge(*Manifest.get()))
387 fatal("internal manifest tool failed on file " + Filename + ": " +
388 toString(std::move(E)));
398 for (StringRef filename : config->manifestInput) {
399 std::unique_ptr<MemoryBuffer> manifest =
400 check(MemoryBuffer::getFile(filename));
401 if (auto e = merger.merge(*manifest.get()))
402 fatal("internal manifest tool failed on file " + filename + ": " +
403 toString(std::move(e)));
389404 }
390405
391 return Merger.getMergedManifest().get()->getBuffer();
406 return merger.getMergedManifest().get()->getBuffer();
392407}
393408
394static std::string createManifestXmlWithExternalMt(StringRef DefaultXml) {
409static std::string createManifestXmlWithExternalMt(StringRef defaultXml) {
395410 // Create the default manifest file as a temporary file.
396411 TemporaryFile Default("defaultxml", "manifest");
397 std::error_code EC;
398 raw_fd_ostream OS(Default.Path, EC, sys::fs::F_Text);
399 if (EC)
400 fatal("failed to open " + Default.Path + ": " + EC.message());
401 OS << DefaultXml;
402 OS.close();
412 std::error_code ec;
413 raw_fd_ostream os(Default.path, ec, sys::fs::F_Text);
414 if (ec)
415 fatal("failed to open " + Default.path + ": " + ec.message());
416 os << defaultXml;
417 os.close();
403418
404419 // Merge user-supplied manifests if they are given. Since libxml2 is not
405420 // enabled, we must shell out to Microsoft's mt.exe tool.
406 TemporaryFile User("user", "manifest");
421 TemporaryFile user("user", "manifest");
407422
408 Executor E("mt.exe");
409 E.add("/manifest");
410 E.add(Default.Path);
411 for (StringRef Filename : Config->ManifestInput) {
412 E.add("/manifest");
413 E.add(Filename);
423 Executor e("mt.exe");
424 e.add("/manifest");
425 e.add(Default.path);
426 for (StringRef filename : config->manifestInput) {
427 e.add("/manifest");
428 e.add(filename);
414429 }
415 E.add("/nologo");
416 E.add("/out:" + StringRef(User.Path));
417 E.run();
430 e.add("/nologo");
431 e.add("/out:" + StringRef(user.path));
432 e.run();
418433
419 return CHECK(MemoryBuffer::getFile(User.Path), "could not open " + User.Path)
434 return CHECK(MemoryBuffer::getFile(user.path), "could not open " + user.path)
420435 .get()
421436 ->getBuffer();
422437}
423438
424439static std::string createManifestXml() {
425 std::string DefaultXml = createDefaultXml();
426 if (Config->ManifestInput.empty())
427 return DefaultXml;
440 std::string defaultXml = createDefaultXml();
441 if (config->manifestInput.empty())
442 return defaultXml;
428443
429444 if (windows_manifest::isAvailable())
430 return createManifestXmlWithInternalMt(DefaultXml);
445 return createManifestXmlWithInternalMt(defaultXml);
431446
432 return createManifestXmlWithExternalMt(DefaultXml);
447 return createManifestXmlWithExternalMt(defaultXml);
433448}
434449
435450static std::unique_ptr<WritableMemoryBuffer>
436createMemoryBufferForManifestRes(size_t ManifestSize) {
437 size_t ResSize = alignTo(
451createMemoryBufferForManifestRes(size_t manifestSize) {
452 size_t resSize = alignTo(
438453 object::WIN_RES_MAGIC_SIZE + object::WIN_RES_NULL_ENTRY_SIZE +
439454 sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) +
440 sizeof(object::WinResHeaderSuffix) + ManifestSize,
455 sizeof(object::WinResHeaderSuffix) + manifestSize,
441456 object::WIN_RES_DATA_ALIGNMENT);
442 return WritableMemoryBuffer::getNewMemBuffer(ResSize, Config->OutputFile +
457 return WritableMemoryBuffer::getNewMemBuffer(resSize, config->outputFile +
443458 ".manifest.res");
444459}
445460
446static void writeResFileHeader(char *&Buf) {
447 memcpy(Buf, COFF::WinResMagic, sizeof(COFF::WinResMagic));
448 Buf += sizeof(COFF::WinResMagic);
449 memset(Buf, 0, object::WIN_RES_NULL_ENTRY_SIZE);
450 Buf += object::WIN_RES_NULL_ENTRY_SIZE;
461static void writeResFileHeader(char *&buf) {
462 memcpy(buf, COFF::WinResMagic, sizeof(COFF::WinResMagic));
463 buf += sizeof(COFF::WinResMagic);
464 memset(buf, 0, object::WIN_RES_NULL_ENTRY_SIZE);
465 buf += object::WIN_RES_NULL_ENTRY_SIZE;
451466}
452467
453static void writeResEntryHeader(char *&Buf, size_t ManifestSize) {
468static void writeResEntryHeader(char *&buf, size_t manifestSize) {
454469 // Write the prefix.
455 auto *Prefix = reinterpret_cast<object::WinResHeaderPrefix *>(Buf);
456 Prefix->DataSize = ManifestSize;
457 Prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) +
470 auto *prefix = reinterpret_cast<object::WinResHeaderPrefix *>(buf);
471 prefix->DataSize = manifestSize;
472 prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) +
458473 sizeof(object::WinResIDs) +
459474 sizeof(object::WinResHeaderSuffix);
460 Buf += sizeof(object::WinResHeaderPrefix);
475 buf += sizeof(object::WinResHeaderPrefix);
461476
462477 // Write the Type/Name IDs.
463 auto *IDs = reinterpret_cast<object::WinResIDs *>(Buf);
464 IDs->setType(RT_MANIFEST);
465 IDs->setName(Config->ManifestID);
466 Buf += sizeof(object::WinResIDs);
478 auto *iDs = reinterpret_cast<object::WinResIDs *>(buf);
479 iDs->setType(RT_MANIFEST);
480 iDs->setName(config->manifestID);
481 buf += sizeof(object::WinResIDs);
467482
468483 // Write the suffix.
469 auto *Suffix = reinterpret_cast<object::WinResHeaderSuffix *>(Buf);
470 Suffix->DataVersion = 0;
471 Suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE;
472 Suffix->Language = SUBLANG_ENGLISH_US;
473 Suffix->Version = 0;
474 Suffix->Characteristics = 0;
475 Buf += sizeof(object::WinResHeaderSuffix);
484 auto *suffix = reinterpret_cast<object::WinResHeaderSuffix *>(buf);
485 suffix->DataVersion = 0;
486 suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE;
487 suffix->Language = SUBLANG_ENGLISH_US;
488 suffix->Version = 0;
489 suffix->Characteristics = 0;
490 buf += sizeof(object::WinResHeaderSuffix);
476491}
477492
478493// Create a resource file containing a manifest XML.
479494std::unique_ptr<MemoryBuffer> createManifestRes() {
480 std::string Manifest = createManifestXml();
495 std::string manifest = createManifestXml();
481496
482 std::unique_ptr<WritableMemoryBuffer> Res =
483 createMemoryBufferForManifestRes(Manifest.size());
497 std::unique_ptr<WritableMemoryBuffer> res =
498 createMemoryBufferForManifestRes(manifest.size());
484499
485 char *Buf = Res->getBufferStart();
486 writeResFileHeader(Buf);
487 writeResEntryHeader(Buf, Manifest.size());
500 char *buf = res->getBufferStart();
501 writeResFileHeader(buf);
502 writeResEntryHeader(buf, manifest.size());
488503
489504 // Copy the manifest data into the .res file.
490 std::copy(Manifest.begin(), Manifest.end(), Buf);
491 return std::move(Res);
505 std::copy(manifest.begin(), manifest.end(), buf);
506 return std::move(res);
492507}
493508
494509void createSideBySideManifest() {
495 std::string Path = Config->ManifestFile;
496 if (Path == "")
497 Path = Config->OutputFile + ".manifest";
498 std::error_code EC;
499 raw_fd_ostream Out(Path, EC, sys::fs::F_Text);
500 if (EC)
501 fatal("failed to create manifest: " + EC.message());
502 Out << createManifestXml();
510 std::string path = config->manifestFile;
511 if (path == "")
512 path = config->outputFile + ".manifest";
513 std::error_code ec;
514 raw_fd_ostream out(path, ec, sys::fs::F_Text);
515 if (ec)
516 fatal("failed to create manifest: " + ec.message());
517 out << createManifestXml();
503518}
504519
505520// Parse a string in the form of
506521// "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]"
507522// or "<name>=<dllname>.<name>".
508523// Used for parsing /export arguments.
509Export parseExport(StringRef Arg) {
510 Export E;
511 StringRef Rest;
512 std::tie(E.Name, Rest) = Arg.split(",");
513 if (E.Name.empty())
524Export parseExport(StringRef arg) {
525 Export e;
526 StringRef rest;
527 std::tie(e.name, rest) = arg.split(",");
528 if (e.name.empty())
514529 goto err;
515530
516 if (E.Name.contains('=')) {
517 StringRef X, Y;
518 std::tie(X, Y) = E.Name.split("=");
531 if (e.name.contains('=')) {
532 StringRef x, y;
533 std::tie(x, y) = e.name.split("=");
519534
520535 // If "<name>=<dllname>.<name>".
521 if (Y.contains(".")) {
522 E.Name = X;
523 E.ForwardTo = Y;
524 return E;
536 if (y.contains(".")) {
537 e.name = x;
538 e.forwardTo = y;
539 return e;
525540 }
526541
527 E.ExtName = X;
528 E.Name = Y;
529 if (E.Name.empty())
542 e.extName = x;
543 e.name = y;
544 if (e.name.empty())
530545 goto err;
531546 }
532547
533548 // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
534 while (!Rest.empty()) {
535 StringRef Tok;
536 std::tie(Tok, Rest) = Rest.split(",");
537 if (Tok.equals_lower("noname")) {
538 if (E.Ordinal == 0)
549 while (!rest.empty()) {
550 StringRef tok;
551 std::tie(tok, rest) = rest.split(",");
552 if (tok.equals_lower("noname")) {
553 if (e.ordinal == 0)
539554 goto err;
540 E.Noname = true;
555 e.noname = true;
541556 continue;
542557 }
543 if (Tok.equals_lower("data")) {
544 E.Data = true;
558 if (tok.equals_lower("data")) {
559 e.data = true;
545560 continue;
546561 }
547 if (Tok.equals_lower("constant")) {
548 E.Constant = true;
562 if (tok.equals_lower("constant")) {
563 e.constant = true;
549564 continue;
550565 }
551 if (Tok.equals_lower("private")) {
552 E.Private = true;
566 if (tok.equals_lower("private")) {
567 e.isPrivate = true;
553568 continue;
554569 }
555 if (Tok.startswith("@")) {
556 int32_t Ord;
557 if (Tok.substr(1).getAsInteger(0, Ord))
570 if (tok.startswith("@")) {
571 int32_t ord;
572 if (tok.substr(1).getAsInteger(0, ord))
558573 goto err;
559 if (Ord <= 0 || 65535 < Ord)
574 if (ord <= 0 || 65535 < ord)
560575 goto err;
561 E.Ordinal = Ord;
576 e.ordinal = ord;
562577 continue;
563578 }
564579 goto err;
565580 }
566 return E;
581 return e;
567582
568583err:
569 fatal("invalid /export: " + Arg);
584 fatal("invalid /export: " + arg);
570585}
571586
572static StringRef undecorate(StringRef Sym) {
573 if (Config->Machine != I386)
574 return Sym;
587static StringRef undecorate(StringRef sym) {
588 if (config->machine != I386)
589 return sym;
575590 // In MSVC mode, a fully decorated stdcall function is exported
576591 // as-is with the leading underscore (with type IMPORT_NAME).
577592 // In MinGW mode, a decorated stdcall function gets the underscore
578593 // removed, just like normal cdecl functions.
579 if (Sym.startswith("_") && Sym.contains('@') && !Config->MinGW)
580 return Sym;
581 return Sym.startswith("_") ? Sym.substr(1) : Sym;
594 if (sym.startswith("_") && sym.contains('@') && !config->mingw)
595 return sym;
596 return sym.startswith("_") ? sym.substr(1) : sym;
582597}
583598
584599// Convert stdcall/fastcall style symbols into unsuffixed symbols,
585600// with or without a leading underscore. (MinGW specific.)
586static StringRef killAt(StringRef Sym, bool Prefix) {
587 if (Sym.empty())
588 return Sym;
601static StringRef killAt(StringRef sym, bool prefix) {
602 if (sym.empty())
603 return sym;
589604 // Strip any trailing stdcall suffix
590 Sym = Sym.substr(0, Sym.find('@', 1));
591 if (!Sym.startswith("@")) {
592 if (Prefix && !Sym.startswith("_"))
593 return Saver.save("_" + Sym);
594 return Sym;
605 sym = sym.substr(0, sym.find('@', 1));
606 if (!sym.startswith("@")) {
607 if (prefix && !sym.startswith("_"))
608 return saver.save("_" + sym);
609 return sym;
595610 }
596611 // For fastcall, remove the leading @ and replace it with an
597612 // underscore, if prefixes are used.
598 Sym = Sym.substr(1);
599 if (Prefix)
600 Sym = Saver.save("_" + Sym);
601 return Sym;
613 sym = sym.substr(1);
614 if (prefix)
615 sym = saver.save("_" + sym);
616 return sym;
602617}
603618
604619// Performs error checking on all /export arguments.
605620// It also sets ordinals.
606621void fixupExports() {
607622 // Symbol ordinals must be unique.
608 std::set<uint16_t> Ords;
609 for (Export &E : Config->Exports) {
610 if (E.Ordinal == 0)
623 std::set<uint16_t> ords;
624 for (Export &e : config->exports) {
625 if (e.ordinal == 0)
611626 continue;
612 if (!Ords.insert(E.Ordinal).second)
613 fatal("duplicate export ordinal: " + E.Name);
614 }
615
616 for (Export &E : Config->Exports) {
617 Symbol *Sym = E.Sym;
618 if (!E.ForwardTo.empty() || !Sym) {
619 E.SymbolName = E.Name;
620 } else {
621 if (auto *U = dyn_cast<Undefined>(Sym))
622 if (U->WeakAlias)
623 Sym = U->WeakAlias;
624 E.SymbolName = Sym->getName();
625 }
627 if (!ords.insert(e.ordinal).second)
628 fatal("duplicate export ordinal: " + e.name);
626629 }
627630
628 for (Export &E : Config->Exports) {
629 if (!E.ForwardTo.empty()) {
630 E.ExportName = undecorate(E.Name);
631 for (Export &e : config->exports) {
632 if (!e.forwardTo.empty()) {
633 e.exportName = undecorate(e.name);
631634 } else {
632 E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName);
635 e.exportName = undecorate(e.extName.empty() ? e.name : e.extName);
633636 }
634637 }
635638
636 if (Config->KillAt && Config->Machine == I386) {
637 for (Export &E : Config->Exports) {
638 E.Name = killAt(E.Name, true);
639 E.ExportName = killAt(E.ExportName, false);
640 E.ExtName = killAt(E.ExtName, true);
641 E.SymbolName = killAt(E.SymbolName, true);
639 if (config->killAt && config->machine == I386) {
640 for (Export &e : config->exports) {
641 e.name = killAt(e.name, true);
642 e.exportName = killAt(e.exportName, false);
643 e.extName = killAt(e.extName, true);
644 e.symbolName = killAt(e.symbolName, true);
642645 }
643646 }
644647
645648 // Uniquefy by name.
646 DenseMap<StringRef, Export *> Map(Config->Exports.size());
647 std::vector<Export> V;
648 for (Export &E : Config->Exports) {
649 auto Pair = Map.insert(std::make_pair(E.ExportName, &E));
650 bool Inserted = Pair.second;
651 if (Inserted) {
652 V.push_back(E);
649 DenseMap<StringRef, Export *> map(config->exports.size());
650 std::vector<Export> v;
651 for (Export &e : config->exports) {
652 auto pair = map.insert(std::make_pair(e.exportName, &e));
653 bool inserted = pair.second;
654 if (inserted) {
655 v.push_back(e);
653656 continue;
654657 }
655 Export *Existing = Pair.first->second;
656 if (E == *Existing || E.Name != Existing->Name)
658 Export *existing = pair.first->second;
659 if (e == *existing || e.name != existing->name)
657660 continue;
658 warn("duplicate /export option: " + E.Name);
661 warn("duplicate /export option: " + e.name);
659662 }
660 Config->Exports = std::move(V);
663 config->exports = std::move(v);
661664
662665 // Sort by name.
663 std::sort(Config->Exports.begin(), Config->Exports.end(),
664 [](const Export &A, const Export &B) {
665 return A.ExportName < B.ExportName;
666 std::sort(config->exports.begin(), config->exports.end(),
667 [](const Export &a, const Export &b) {
668 return a.exportName < b.exportName;
666669 });
667670}
668671
669672void assignExportOrdinals() {
670673 // Assign unique ordinals if default (= 0).
671 uint16_t Max = 0;
672 for (Export &E : Config->Exports)
673 Max = std::max(Max, E.Ordinal);
674 for (Export &E : Config->Exports)
675 if (E.Ordinal == 0)
676 E.Ordinal = ++Max;
674 uint16_t max = 0;
675 for (Export &e : config->exports)
676 max = std::max(max, e.ordinal);
677 for (Export &e : config->exports)
678 if (e.ordinal == 0)
679 e.ordinal = ++max;
677680}
678681
679682// Parses a string in the form of "key=value" and check
680683// if value matches previous values for the same key.
681void checkFailIfMismatch(StringRef Arg) {
682 StringRef K, V;
683 std::tie(K, V) = Arg.split('=');
684 if (K.empty() || V.empty())
685 fatal("/failifmismatch: invalid argument: " + Arg);
686 StringRef Existing = Config->MustMatch[K];
687 if (!Existing.empty() && V != Existing)
688 fatal("/failifmismatch: mismatch detected: " + Existing + " and " + V +
689 " for key " + K);
690 Config->MustMatch[K] = V;
684void checkFailIfMismatch(StringRef arg, InputFile *source) {
685 StringRef k, v;
686 std::tie(k, v) = arg.split('=');
687 if (k.empty() || v.empty())
688 fatal("/failifmismatch: invalid argument: " + arg);
689 std::pair<StringRef, InputFile *> existing = config->mustMatch[k];
690 if (!existing.first.empty() && v != existing.first) {
691 std::string sourceStr = source ? toString(source) : "cmd-line";
692 std::string existingStr =
693 existing.second ? toString(existing.second) : "cmd-line";
694 fatal("/failifmismatch: mismatch detected for '" + k + "':\n>>> " +
695 existingStr + " has value " + existing.first + "\n>>> " + sourceStr +
696 " has value " + v);
697 }
698 config->mustMatch[k] = {v, source};
691699}
692700
693701// Convert Windows resource files (.res files) to a .obj file.
694MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs) {
695 object::WindowsResourceParser Parser;
696
697 for (MemoryBufferRef MB : MBs) {
698 std::unique_ptr<object::Binary> Bin = check(object::createBinary(MB));
699 object::WindowsResource *RF = dyn_cast<object::WindowsResource>(Bin.get());
700 if (!RF)
702// Does what cvtres.exe does, but in-process and cross-platform.
703MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs) {
704 object::WindowsResourceParser parser;
705
706 for (MemoryBufferRef mb : mbs) {
707 std::unique_ptr<object::Binary> bin = check(object::createBinary(mb));
708 object::WindowsResource *rf = dyn_cast<object::WindowsResource>(bin.get());
709 if (!rf)
701710 fatal("cannot compile non-resource file as resource");
702 if (auto EC = Parser.parse(RF))
703 fatal("failed to parse .res file: " + toString(std::move(EC)));
711
712 std::vector<std::string> duplicates;
713 if (auto ec = parser.parse(rf, duplicates))
714 fatal(toString(std::move(ec)));
715
716 for (const auto &dupeDiag : duplicates)
717 if (config->forceMultipleRes)
718 warn(dupeDiag);
719 else
720 error(dupeDiag);
704721 }
705722
706 Expected<std::unique_ptr<MemoryBuffer>> E =
707 llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser);
708 if (!E)
709 fatal("failed to write .res to COFF: " + toString(E.takeError()));
723 Expected<std::unique_ptr<MemoryBuffer>> e =
724 llvm::object::writeWindowsResourceCOFF(config->machine, parser,
725 config->timestamp);
726 if (!e)
727 fatal("failed to write .res to COFF: " + toString(e.takeError()));
710728
711 MemoryBufferRef MBRef = **E;
712 make<std::unique_ptr<MemoryBuffer>>(std::move(*E)); // take ownership
713 return MBRef;
729 MemoryBufferRef mbref = **e;
730 make<std::unique_ptr<MemoryBuffer>>(std::move(*e)); // take ownership
731 return mbref;
714732}
715733
716734// Create OptTable
......@@ -721,7 +739,7 @@ MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs) {
721739#undef PREFIX
722740
723741// Create table mapping all options defined in Options.td
724static const llvm::opt::OptTable::Info InfoTable[] = {
742static const llvm::opt::OptTable::Info infoTable[] = {
725743#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
726744 {X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \
727745 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
......@@ -729,36 +747,36 @@ static const llvm::opt::OptTable::Info InfoTable[] = {
729747#undef OPTION
730748};
731749
732COFFOptTable::COFFOptTable() : OptTable(InfoTable, true) {}
750COFFOptTable::COFFOptTable() : OptTable(infoTable, true) {}
733751
734752// Set color diagnostics according to --color-diagnostics={auto,always,never}
735753// or --no-color-diagnostics flags.
736static void handleColorDiagnostics(opt::InputArgList &Args) {
737 auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
754static void handleColorDiagnostics(opt::InputArgList &args) {
755 auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
738756 OPT_no_color_diagnostics);
739 if (!Arg)
757 if (!arg)
740758 return;
741 if (Arg->getOption().getID() == OPT_color_diagnostics) {
742 errorHandler().ColorDiagnostics = true;
743 } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) {
744 errorHandler().ColorDiagnostics = false;
759 if (arg->getOption().getID() == OPT_color_diagnostics) {
760 errorHandler().colorDiagnostics = true;
761 } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
762 errorHandler().colorDiagnostics = false;
745763 } else {
746 StringRef S = Arg->getValue();
747 if (S == "always")
748 errorHandler().ColorDiagnostics = true;
749 else if (S == "never")
750 errorHandler().ColorDiagnostics = false;
751 else if (S != "auto")
752 error("unknown option: --color-diagnostics=" + S);
753 }
754}
755
756static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
757 if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) {
758 StringRef S = Arg->getValue();
759 if (S != "windows" && S != "posix")
760 error("invalid response file quoting: " + S);
761 if (S == "windows")
764 StringRef s = arg->getValue();
765 if (s == "always")
766 errorHandler().colorDiagnostics = true;
767 else if (s == "never")
768 errorHandler().colorDiagnostics = false;
769 else if (s != "auto")
770 error("unknown option: --color-diagnostics=" + s);
771 }
772}
773
774static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &args) {
775 if (auto *arg = args.getLastArg(OPT_rsp_quoting)) {
776 StringRef s = arg->getValue();
777 if (s != "windows" && s != "posix")
778 error("invalid response file quoting: " + s);
779 if (s == "windows")
762780 return cl::TokenizeWindowsCommandLine;
763781 return cl::TokenizeGNUCommandLine;
764782 }
......@@ -767,104 +785,111 @@ static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
767785}
768786
769787// Parses a given list of options.
770opt::InputArgList ArgParser::parse(ArrayRef<const char *> Argv) {
788opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
771789 // Make InputArgList from string vectors.
772 unsigned MissingIndex;
773 unsigned MissingCount;
790 unsigned missingIndex;
791 unsigned missingCount;
774792
775793 // We need to get the quoting style for response files before parsing all
776794 // options so we parse here before and ignore all the options but
777795 // --rsp-quoting.
778 opt::InputArgList Args = Table.ParseArgs(Argv, MissingIndex, MissingCount);
796 opt::InputArgList args = table.ParseArgs(argv, missingIndex, missingCount);
779797
780798 // Expand response files (arguments in the form of @<filename>)
781799 // and then parse the argument again.
782 SmallVector<const char *, 256> ExpandedArgv(Argv.data(), Argv.data() + Argv.size());
783 cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), ExpandedArgv);
784 Args = Table.ParseArgs(makeArrayRef(ExpandedArgv).drop_front(), MissingIndex,
785 MissingCount);
800 SmallVector<const char *, 256> expandedArgv(argv.data(),
801 argv.data() + argv.size());
802 cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv);
803 args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex,
804 missingCount);
786805
787806 // Print the real command line if response files are expanded.
788 if (Args.hasArg(OPT_verbose) && Argv.size() != ExpandedArgv.size()) {
789 std::string Msg = "Command line:";
790 for (const char *S : ExpandedArgv)
791 Msg += " " + std::string(S);
792 message(Msg);
807 if (args.hasArg(OPT_verbose) && argv.size() != expandedArgv.size()) {
808 std::string msg = "Command line:";
809 for (const char *s : expandedArgv)
810 msg += " " + std::string(s);
811 message(msg);
793812 }
794813
795814 // Save the command line after response file expansion so we can write it to
796815 // the PDB if necessary.
797 Config->Argv = {ExpandedArgv.begin(), ExpandedArgv.end()};
816 config->argv = {expandedArgv.begin(), expandedArgv.end()};
798817
799818 // Handle /WX early since it converts missing argument warnings to errors.
800 errorHandler().FatalWarnings = Args.hasFlag(OPT_WX, OPT_WX_no, false);
819 errorHandler().fatalWarnings = args.hasFlag(OPT_WX, OPT_WX_no, false);
801820
802 if (MissingCount)
803 fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
821 if (missingCount)
822 fatal(Twine(args.getArgString(missingIndex)) + ": missing argument");
804823
805 handleColorDiagnostics(Args);
824 handleColorDiagnostics(args);
806825
807 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
808 warn("ignoring unknown argument: " + Arg->getSpelling());
826 for (auto *arg : args.filtered(OPT_UNKNOWN)) {
827 std::string nearest;
828 if (table.findNearest(arg->getAsString(args), nearest) > 1)
829 warn("ignoring unknown argument '" + arg->getAsString(args) + "'");
830 else
831 warn("ignoring unknown argument '" + arg->getAsString(args) +
832 "', did you mean '" + nearest + "'");
833 }
809834
810 if (Args.hasArg(OPT_lib))
835 if (args.hasArg(OPT_lib))
811836 warn("ignoring /lib since it's not the first argument");
812837
813 return Args;
838 return args;
814839}
815840
816841// Tokenizes and parses a given string as command line in .drective section.
817842// /EXPORT options are processed in fastpath.
818843std::pair<opt::InputArgList, std::vector<StringRef>>
819ArgParser::parseDirectives(StringRef S) {
820 std::vector<StringRef> Exports;
821 SmallVector<const char *, 16> Rest;
844ArgParser::parseDirectives(StringRef s) {
845 std::vector<StringRef> exports;
846 SmallVector<const char *, 16> rest;
822847
823 for (StringRef Tok : tokenize(S)) {
824 if (Tok.startswith_lower("/export:") || Tok.startswith_lower("-export:"))
825 Exports.push_back(Tok.substr(strlen("/export:")));
848 for (StringRef tok : tokenize(s)) {
849 if (tok.startswith_lower("/export:") || tok.startswith_lower("-export:"))
850 exports.push_back(tok.substr(strlen("/export:")));
826851 else
827 Rest.push_back(Tok.data());
852 rest.push_back(tok.data());
828853 }
829854
830855 // Make InputArgList from unparsed string vectors.
831 unsigned MissingIndex;
832 unsigned MissingCount;
856 unsigned missingIndex;
857 unsigned missingCount;
833858
834 opt::InputArgList Args = Table.ParseArgs(Rest, MissingIndex, MissingCount);
859 opt::InputArgList args = table.ParseArgs(rest, missingIndex, missingCount);
835860
836 if (MissingCount)
837 fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
838 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
839 warn("ignoring unknown argument: " + Arg->getSpelling());
840 return {std::move(Args), std::move(Exports)};
861 if (missingCount)
862 fatal(Twine(args.getArgString(missingIndex)) + ": missing argument");
863 for (auto *arg : args.filtered(OPT_UNKNOWN))
864 warn("ignoring unknown argument: " + arg->getAsString(args));
865 return {std::move(args), std::move(exports)};
841866}
842867
843868// link.exe has an interesting feature. If LINK or _LINK_ environment
844869// variables exist, their contents are handled as command line strings.
845870// So you can pass extra arguments using them.
846opt::InputArgList ArgParser::parseLINK(std::vector<const char *> Argv) {
871opt::InputArgList ArgParser::parseLINK(std::vector<const char *> argv) {
847872 // Concatenate LINK env and command line arguments, and then parse them.
848 if (Optional<std::string> S = Process::GetEnv("LINK")) {
849 std::vector<const char *> V = tokenize(*S);
850 Argv.insert(std::next(Argv.begin()), V.begin(), V.end());
873 if (Optional<std::string> s = Process::GetEnv("LINK")) {
874 std::vector<const char *> v = tokenize(*s);
875 argv.insert(std::next(argv.begin()), v.begin(), v.end());
851876 }
852 if (Optional<std::string> S = Process::GetEnv("_LINK_")) {
853 std::vector<const char *> V = tokenize(*S);
854 Argv.insert(std::next(Argv.begin()), V.begin(), V.end());
877 if (Optional<std::string> s = Process::GetEnv("_LINK_")) {
878 std::vector<const char *> v = tokenize(*s);
879 argv.insert(std::next(argv.begin()), v.begin(), v.end());
855880 }
856 return parse(Argv);
881 return parse(argv);
857882}
858883
859std::vector<const char *> ArgParser::tokenize(StringRef S) {
860 SmallVector<const char *, 16> Tokens;
861 cl::TokenizeWindowsCommandLine(S, Saver, Tokens);
862 return std::vector<const char *>(Tokens.begin(), Tokens.end());
884std::vector<const char *> ArgParser::tokenize(StringRef s) {
885 SmallVector<const char *, 16> tokens;
886 cl::TokenizeWindowsCommandLine(s, saver, tokens);
887 return std::vector<const char *>(tokens.begin(), tokens.end());
863888}
864889
865void printHelp(const char *Argv0) {
890void printHelp(const char *argv0) {
866891 COFFOptTable().PrintHelp(outs(),
867 (std::string(Argv0) + " [options] file...").c_str(),
892 (std::string(argv0) + " [options] file...").c_str(),
868893 "LLVM Linker", false);
869894}
870895
deps/lld/COFF/ICF.cpp+139-140
......@@ -1,9 +1,8 @@
11//===- ICF.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -38,33 +37,32 @@ using namespace llvm;
3837namespace lld {
3938namespace coff {
4039
41static Timer ICFTimer("ICF", Timer::root());
40static Timer icfTimer("ICF", Timer::root());
4241
4342class ICF {
4443public:
45 void run(ArrayRef<Chunk *> V);
44 void run(ArrayRef<Chunk *> v);
4645
4746private:
48 void segregate(size_t Begin, size_t End, bool Constant);
47 void segregate(size_t begin, size_t end, bool constant);
4948
50 bool assocEquals(const SectionChunk *A, const SectionChunk *B);
49 bool assocEquals(const SectionChunk *a, const SectionChunk *b);
5150
52 bool equalsConstant(const SectionChunk *A, const SectionChunk *B);
53 bool equalsVariable(const SectionChunk *A, const SectionChunk *B);
51 bool equalsConstant(const SectionChunk *a, const SectionChunk *b);
52 bool equalsVariable(const SectionChunk *a, const SectionChunk *b);
5453
55 uint32_t getHash(SectionChunk *C);
56 bool isEligible(SectionChunk *C);
54 bool isEligible(SectionChunk *c);
5755
58 size_t findBoundary(size_t Begin, size_t End);
56 size_t findBoundary(size_t begin, size_t end);
5957
60 void forEachClassRange(size_t Begin, size_t End,
61 std::function<void(size_t, size_t)> Fn);
58 void forEachClassRange(size_t begin, size_t end,
59 std::function<void(size_t, size_t)> fn);
6260
63 void forEachClass(std::function<void(size_t, size_t)> Fn);
61 void forEachClass(std::function<void(size_t, size_t)> fn);
6462
65 std::vector<SectionChunk *> Chunks;
66 int Cnt = 0;
67 std::atomic<bool> Repeat = {false};
63 std::vector<SectionChunk *> chunks;
64 int cnt = 0;
65 std::atomic<bool> repeat = {false};
6866};
6967
7068// Returns true if section S is subject of ICF.
......@@ -78,143 +76,144 @@ private:
7876// merge read-only sections in a couple of cases where the address of the
7977// section is insignificant to the user program and the behaviour matches that
8078// of the Visual C++ linker.
81bool ICF::isEligible(SectionChunk *C) {
79bool ICF::isEligible(SectionChunk *c) {
8280 // Non-comdat chunks, dead chunks, and writable chunks are not elegible.
83 bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
84 if (!C->isCOMDAT() || !C->Live || Writable)
81 bool writable = c->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
82 if (!c->isCOMDAT() || !c->live || writable)
8583 return false;
8684
8785 // Code sections are eligible.
88 if (C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE)
86 if (c->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE)
8987 return true;
9088
9189 // .pdata and .xdata unwind info sections are eligible.
92 StringRef OutSecName = C->getSectionName().split('$').first;
93 if (OutSecName == ".pdata" || OutSecName == ".xdata")
90 StringRef outSecName = c->getSectionName().split('$').first;
91 if (outSecName == ".pdata" || outSecName == ".xdata")
9492 return true;
9593
9694 // So are vtables.
97 if (C->Sym && C->Sym->getName().startswith("??_7"))
95 if (c->sym && c->sym->getName().startswith("??_7"))
9896 return true;
9997
10098 // Anything else not in an address-significance table is eligible.
101 return !C->KeepUnique;
99 return !c->keepUnique;
102100}
103101
104102// Split an equivalence class into smaller classes.
105void ICF::segregate(size_t Begin, size_t End, bool Constant) {
106 while (Begin < End) {
103void ICF::segregate(size_t begin, size_t end, bool constant) {
104 while (begin < end) {
107105 // Divide [Begin, End) into two. Let Mid be the start index of the
108106 // second group.
109 auto Bound = std::stable_partition(
110 Chunks.begin() + Begin + 1, Chunks.begin() + End, [&](SectionChunk *S) {
111 if (Constant)
112 return equalsConstant(Chunks[Begin], S);
113 return equalsVariable(Chunks[Begin], S);
107 auto bound = std::stable_partition(
108 chunks.begin() + begin + 1, chunks.begin() + end, [&](SectionChunk *s) {
109 if (constant)
110 return equalsConstant(chunks[begin], s);
111 return equalsVariable(chunks[begin], s);
114112 });
115 size_t Mid = Bound - Chunks.begin();
113 size_t mid = bound - chunks.begin();
116114
117115 // Split [Begin, End) into [Begin, Mid) and [Mid, End). We use Mid as an
118116 // equivalence class ID because every group ends with a unique index.
119 for (size_t I = Begin; I < Mid; ++I)
120 Chunks[I]->Class[(Cnt + 1) % 2] = Mid;
117 for (size_t i = begin; i < mid; ++i)
118 chunks[i]->eqClass[(cnt + 1) % 2] = mid;
121119
122120 // If we created a group, we need to iterate the main loop again.
123 if (Mid != End)
124 Repeat = true;
121 if (mid != end)
122 repeat = true;
125123
126 Begin = Mid;
124 begin = mid;
127125 }
128126}
129127
130128// Returns true if two sections' associative children are equal.
131bool ICF::assocEquals(const SectionChunk *A, const SectionChunk *B) {
132 auto ChildClasses = [&](const SectionChunk *SC) {
133 std::vector<uint32_t> Classes;
134 for (const SectionChunk *C : SC->children())
135 if (!C->SectionName.startswith(".debug") &&
136 C->SectionName != ".gfids$y" && C->SectionName != ".gljmp$y")
137 Classes.push_back(C->Class[Cnt % 2]);
138 return Classes;
129bool ICF::assocEquals(const SectionChunk *a, const SectionChunk *b) {
130 auto childClasses = [&](const SectionChunk *sc) {
131 std::vector<uint32_t> classes;
132 for (const SectionChunk &c : sc->children())
133 if (!c.getSectionName().startswith(".debug") &&
134 c.getSectionName() != ".gfids$y" && c.getSectionName() != ".gljmp$y")
135 classes.push_back(c.eqClass[cnt % 2]);
136 return classes;
139137 };
140 return ChildClasses(A) == ChildClasses(B);
138 return childClasses(a) == childClasses(b);
141139}
142140
143141// Compare "non-moving" part of two sections, namely everything
144142// except relocation targets.
145bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) {
146 if (A->Relocs.size() != B->Relocs.size())
143bool ICF::equalsConstant(const SectionChunk *a, const SectionChunk *b) {
144 if (a->relocsSize != b->relocsSize)
147145 return false;
148146
149147 // Compare relocations.
150 auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) {
151 if (R1.Type != R2.Type ||
152 R1.VirtualAddress != R2.VirtualAddress) {
148 auto eq = [&](const coff_relocation &r1, const coff_relocation &r2) {
149 if (r1.Type != r2.Type ||
150 r1.VirtualAddress != r2.VirtualAddress) {
153151 return false;
154152 }
155 Symbol *B1 = A->File->getSymbol(R1.SymbolTableIndex);
156 Symbol *B2 = B->File->getSymbol(R2.SymbolTableIndex);
157 if (B1 == B2)
153 Symbol *b1 = a->file->getSymbol(r1.SymbolTableIndex);
154 Symbol *b2 = b->file->getSymbol(r2.SymbolTableIndex);
155 if (b1 == b2)
158156 return true;
159 if (auto *D1 = dyn_cast<DefinedRegular>(B1))
160 if (auto *D2 = dyn_cast<DefinedRegular>(B2))
161 return D1->getValue() == D2->getValue() &&
162 D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2];
157 if (auto *d1 = dyn_cast<DefinedRegular>(b1))
158 if (auto *d2 = dyn_cast<DefinedRegular>(b2))
159 return d1->getValue() == d2->getValue() &&
160 d1->getChunk()->eqClass[cnt % 2] == d2->getChunk()->eqClass[cnt % 2];
163161 return false;
164162 };
165 if (!std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq))
163 if (!std::equal(a->getRelocs().begin(), a->getRelocs().end(),
164 b->getRelocs().begin(), eq))
166165 return false;
167166
168167 // Compare section attributes and contents.
169 return A->getOutputCharacteristics() == B->getOutputCharacteristics() &&
170 A->SectionName == B->SectionName &&
171 A->Header->SizeOfRawData == B->Header->SizeOfRawData &&
172 A->Checksum == B->Checksum && A->getContents() == B->getContents() &&
173 assocEquals(A, B);
168 return a->getOutputCharacteristics() == b->getOutputCharacteristics() &&
169 a->getSectionName() == b->getSectionName() &&
170 a->header->SizeOfRawData == b->header->SizeOfRawData &&
171 a->checksum == b->checksum && a->getContents() == b->getContents() &&
172 assocEquals(a, b);
174173}
175174
176175// Compare "moving" part of two sections, namely relocation targets.
177bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) {
176bool ICF::equalsVariable(const SectionChunk *a, const SectionChunk *b) {
178177 // Compare relocations.
179 auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) {
180 Symbol *B1 = A->File->getSymbol(R1.SymbolTableIndex);
181 Symbol *B2 = B->File->getSymbol(R2.SymbolTableIndex);
182 if (B1 == B2)
178 auto eq = [&](const coff_relocation &r1, const coff_relocation &r2) {
179 Symbol *b1 = a->file->getSymbol(r1.SymbolTableIndex);
180 Symbol *b2 = b->file->getSymbol(r2.SymbolTableIndex);
181 if (b1 == b2)
183182 return true;
184 if (auto *D1 = dyn_cast<DefinedRegular>(B1))
185 if (auto *D2 = dyn_cast<DefinedRegular>(B2))
186 return D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2];
183 if (auto *d1 = dyn_cast<DefinedRegular>(b1))
184 if (auto *d2 = dyn_cast<DefinedRegular>(b2))
185 return d1->getChunk()->eqClass[cnt % 2] == d2->getChunk()->eqClass[cnt % 2];
187186 return false;
188187 };
189 return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(),
190 Eq) &&
191 assocEquals(A, B);
188 return std::equal(a->getRelocs().begin(), a->getRelocs().end(),
189 b->getRelocs().begin(), eq) &&
190 assocEquals(a, b);
192191}
193192
194193// Find the first Chunk after Begin that has a different class from Begin.
195size_t ICF::findBoundary(size_t Begin, size_t End) {
196 for (size_t I = Begin + 1; I < End; ++I)
197 if (Chunks[Begin]->Class[Cnt % 2] != Chunks[I]->Class[Cnt % 2])
198 return I;
199 return End;
194size_t ICF::findBoundary(size_t begin, size_t end) {
195 for (size_t i = begin + 1; i < end; ++i)
196 if (chunks[begin]->eqClass[cnt % 2] != chunks[i]->eqClass[cnt % 2])
197 return i;
198 return end;
200199}
201200
202void ICF::forEachClassRange(size_t Begin, size_t End,
203 std::function<void(size_t, size_t)> Fn) {
204 while (Begin < End) {
205 size_t Mid = findBoundary(Begin, End);
206 Fn(Begin, Mid);
207 Begin = Mid;
201void ICF::forEachClassRange(size_t begin, size_t end,
202 std::function<void(size_t, size_t)> fn) {
203 while (begin < end) {
204 size_t mid = findBoundary(begin, end);
205 fn(begin, mid);
206 begin = mid;
208207 }
209208}
210209
211210// Call Fn on each class group.
212void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) {
211void ICF::forEachClass(std::function<void(size_t, size_t)> fn) {
213212 // If the number of sections are too small to use threading,
214213 // call Fn sequentially.
215 if (Chunks.size() < 1024) {
216 forEachClassRange(0, Chunks.size(), Fn);
217 ++Cnt;
214 if (chunks.size() < 1024) {
215 forEachClassRange(0, chunks.size(), fn);
216 ++cnt;
218217 return;
219218 }
220219
......@@ -222,97 +221,97 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) {
222221 // The sharding must be completed before any calls to Fn are made
223222 // so that Fn can modify the Chunks in its shard without causing data
224223 // races.
225 const size_t NumShards = 256;
226 size_t Step = Chunks.size() / NumShards;
227 size_t Boundaries[NumShards + 1];
228 Boundaries[0] = 0;
229 Boundaries[NumShards] = Chunks.size();
230 parallelForEachN(1, NumShards, [&](size_t I) {
231 Boundaries[I] = findBoundary((I - 1) * Step, Chunks.size());
224 const size_t numShards = 256;
225 size_t step = chunks.size() / numShards;
226 size_t boundaries[numShards + 1];
227 boundaries[0] = 0;
228 boundaries[numShards] = chunks.size();
229 parallelForEachN(1, numShards, [&](size_t i) {
230 boundaries[i] = findBoundary((i - 1) * step, chunks.size());
232231 });
233 parallelForEachN(1, NumShards + 1, [&](size_t I) {
234 if (Boundaries[I - 1] < Boundaries[I]) {
235 forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);
232 parallelForEachN(1, numShards + 1, [&](size_t i) {
233 if (boundaries[i - 1] < boundaries[i]) {
234 forEachClassRange(boundaries[i - 1], boundaries[i], fn);
236235 }
237236 });
238 ++Cnt;
237 ++cnt;
239238}
240239
241240// Merge identical COMDAT sections.
242241// Two sections are considered the same if their section headers,
243242// contents and relocations are all the same.
244void ICF::run(ArrayRef<Chunk *> Vec) {
245 ScopedTimer T(ICFTimer);
243void ICF::run(ArrayRef<Chunk *> vec) {
244 ScopedTimer t(icfTimer);
246245
247246 // Collect only mergeable sections and group by hash value.
248 uint32_t NextId = 1;
249 for (Chunk *C : Vec) {
250 if (auto *SC = dyn_cast<SectionChunk>(C)) {
251 if (isEligible(SC))
252 Chunks.push_back(SC);
247 uint32_t nextId = 1;
248 for (Chunk *c : vec) {
249 if (auto *sc = dyn_cast<SectionChunk>(c)) {
250 if (isEligible(sc))
251 chunks.push_back(sc);
253252 else
254 SC->Class[0] = NextId++;
253 sc->eqClass[0] = nextId++;
255254 }
256255 }
257256
258257 // Make sure that ICF doesn't merge sections that are being handled by string
259258 // tail merging.
260 for (auto &P : MergeChunk::Instances)
261 for (SectionChunk *SC : P.second->Sections)
262 SC->Class[0] = NextId++;
259 for (MergeChunk *mc : MergeChunk::instances)
260 if (mc)
261 for (SectionChunk *sc : mc->sections)
262 sc->eqClass[0] = nextId++;
263263
264264 // Initially, we use hash values to partition sections.
265 parallelForEach(Chunks, [&](SectionChunk *SC) {
266 SC->Class[0] = xxHash64(SC->getContents());
265 parallelForEach(chunks, [&](SectionChunk *sc) {
266 sc->eqClass[0] = xxHash64(sc->getContents());
267267 });
268268
269269 // Combine the hashes of the sections referenced by each section into its
270270 // 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];
271 for (unsigned cnt = 0; cnt != 2; ++cnt) {
272 parallelForEach(chunks, [&](SectionChunk *sc) {
273 uint32_t hash = sc->eqClass[cnt % 2];
274 for (Symbol *b : sc->symbols())
275 if (auto *sym = dyn_cast_or_null<DefinedRegular>(b))
276 hash += sym->getChunk()->eqClass[cnt % 2];
277277 // Set MSB to 1 to avoid collisions with non-hash classs.
278 SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
278 sc->eqClass[(cnt + 1) % 2] = hash | (1U << 31);
279279 });
280280 }
281281
282282 // From now on, sections in Chunks are ordered so that sections in
283283 // the same group are consecutive in the vector.
284 std::stable_sort(Chunks.begin(), Chunks.end(),
285 [](SectionChunk *A, SectionChunk *B) {
286 return A->Class[0] < B->Class[0];
287 });
284 llvm::stable_sort(chunks, [](const SectionChunk *a, const SectionChunk *b) {
285 return a->eqClass[0] < b->eqClass[0];
286 });
288287
289288 // Compare static contents and assign unique IDs for each static content.
290 forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); });
289 forEachClass([&](size_t begin, size_t end) { segregate(begin, end, true); });
291290
292291 // Split groups by comparing relocations until convergence is obtained.
293292 do {
294 Repeat = false;
293 repeat = false;
295294 forEachClass(
296 [&](size_t Begin, size_t End) { segregate(Begin, End, false); });
297 } while (Repeat);
295 [&](size_t begin, size_t end) { segregate(begin, end, false); });
296 } while (repeat);
298297
299 log("ICF needed " + Twine(Cnt) + " iterations");
298 log("ICF needed " + Twine(cnt) + " iterations");
300299
301300 // Merge sections in the same classs.
302 forEachClass([&](size_t Begin, size_t End) {
303 if (End - Begin == 1)
301 forEachClass([&](size_t begin, size_t end) {
302 if (end - begin == 1)
304303 return;
305304
306 log("Selected " + Chunks[Begin]->getDebugName());
307 for (size_t I = Begin + 1; I < End; ++I) {
308 log(" Removed " + Chunks[I]->getDebugName());
309 Chunks[Begin]->replace(Chunks[I]);
305 log("Selected " + chunks[begin]->getDebugName());
306 for (size_t i = begin + 1; i < end; ++i) {
307 log(" Removed " + chunks[i]->getDebugName());
308 chunks[begin]->replace(chunks[i]);
310309 }
311310 });
312311}
313312
314313// Entry point to ICF.
315void doICF(ArrayRef<Chunk *> Chunks) { ICF().run(Chunks); }
314void doICF(ArrayRef<Chunk *> chunks) { ICF().run(chunks); }
316315
317316} // namespace coff
318317} // namespace lld
deps/lld/COFF/ICF.h+4-5
......@@ -1,9 +1,8 @@
11//===- ICF.h --------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -18,7 +17,7 @@ namespace coff {
1817
1918class Chunk;
2019
21void doICF(ArrayRef<Chunk *> Chunks);
20void doICF(ArrayRef<Chunk *> chunks);
2221
2322} // namespace coff
2423} // namespace lld
deps/lld/COFF/InputFiles.cpp+603-312
......@@ -1,15 +1,15 @@
11//===- InputFiles.cpp -----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
109#include "InputFiles.h"
1110#include "Chunks.h"
1211#include "Config.h"
12#include "DebugTypes.h"
1313#include "Driver.h"
1414#include "SymbolTable.h"
1515#include "Symbols.h"
......@@ -20,6 +20,10 @@
2020#include "llvm/ADT/Triple.h"
2121#include "llvm/ADT/Twine.h"
2222#include "llvm/BinaryFormat/COFF.h"
23#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
24#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
25#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
26#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
2327#include "llvm/Object/Binary.h"
2428#include "llvm/Object/COFF.h"
2529#include "llvm/Support/Casting.h"
......@@ -35,6 +39,7 @@
3539
3640using namespace llvm;
3741using namespace llvm::COFF;
42using namespace llvm::codeview;
3843using namespace llvm::object;
3944using namespace llvm::support::endian;
4045
......@@ -44,80 +49,80 @@ using llvm::support::ulittle32_t;
4449namespace lld {
4550namespace coff {
4651
47std::vector<ObjFile *> ObjFile::Instances;
48std::vector<ImportFile *> ImportFile::Instances;
49std::vector<BitcodeFile *> BitcodeFile::Instances;
52std::vector<ObjFile *> ObjFile::instances;
53std::vector<ImportFile *> ImportFile::instances;
54std::vector<BitcodeFile *> BitcodeFile::instances;
5055
5156/// Checks that Source is compatible with being a weak alias to Target.
5257/// If Source is Undefined and has no weak alias set, makes it a weak
5358/// alias to Target.
54static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F,
55 Symbol *Source, Symbol *Target) {
56 if (auto *U = dyn_cast<Undefined>(Source)) {
57 if (U->WeakAlias && U->WeakAlias != Target) {
59static void checkAndSetWeakAlias(SymbolTable *symtab, InputFile *f,
60 Symbol *source, Symbol *target) {
61 if (auto *u = dyn_cast<Undefined>(source)) {
62 if (u->weakAlias && u->weakAlias != target) {
5863 // Weak aliases as produced by GCC are named in the form
5964 // .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name
6065 // of another symbol emitted near the weak symbol.
6166 // Just use the definition from the first object file that defined
6267 // this weak symbol.
63 if (Config->MinGW)
68 if (config->mingw)
6469 return;
65 Symtab->reportDuplicate(Source, F);
70 symtab->reportDuplicate(source, f);
6671 }
67 U->WeakAlias = Target;
72 u->weakAlias = target;
6873 }
6974}
7075
71ArchiveFile::ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
76ArchiveFile::ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {}
7277
7378void ArchiveFile::parse() {
7479 // Parse a MemoryBufferRef as an archive file.
75 File = CHECK(Archive::create(MB), this);
80 file = CHECK(Archive::create(mb), this);
7681
7782 // Read the symbol table to construct Lazy objects.
78 for (const Archive::Symbol &Sym : File->symbols())
79 Symtab->addLazy(this, Sym);
83 for (const Archive::Symbol &sym : file->symbols())
84 symtab->addLazy(this, sym);
8085}
8186
8287// Returns a buffer pointing to a member file containing a given symbol.
83void ArchiveFile::addMember(const Archive::Symbol *Sym) {
84 const Archive::Child &C =
85 CHECK(Sym->getMember(),
86 "could not get the member for symbol " + Sym->getName());
88void ArchiveFile::addMember(const Archive::Symbol *sym) {
89 const Archive::Child &c =
90 CHECK(sym->getMember(),
91 "could not get the member for symbol " + sym->getName());
8792
8893 // Return an empty buffer if we have already returned the same buffer.
89 if (!Seen.insert(C.getChildOffset()).second)
94 if (!seen.insert(c.getChildOffset()).second)
9095 return;
9196
92 Driver->enqueueArchiveMember(C, Sym->getName(), getName());
97 driver->enqueueArchiveMember(c, sym->getName(), getName());
9398}
9499
95std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) {
96 std::vector<MemoryBufferRef> V;
97 Error Err = Error::success();
98 for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
99 Archive::Child C =
100 CHECK(COrErr,
101 File->getFileName() + ": could not get the child of the archive");
102 MemoryBufferRef MBRef =
103 CHECK(C.getMemoryBufferRef(),
104 File->getFileName() +
100std::vector<MemoryBufferRef> getArchiveMembers(Archive *file) {
101 std::vector<MemoryBufferRef> v;
102 Error err = Error::success();
103 for (const ErrorOr<Archive::Child> &cOrErr : file->children(err)) {
104 Archive::Child c =
105 CHECK(cOrErr,
106 file->getFileName() + ": could not get the child of the archive");
107 MemoryBufferRef mbref =
108 CHECK(c.getMemoryBufferRef(),
109 file->getFileName() +
105110 ": could not get the buffer for a child of the archive");
106 V.push_back(MBRef);
111 v.push_back(mbref);
107112 }
108 if (Err)
109 fatal(File->getFileName() +
110 ": Archive::children failed: " + toString(std::move(Err)));
111 return V;
113 if (err)
114 fatal(file->getFileName() +
115 ": Archive::children failed: " + toString(std::move(err)));
116 return v;
112117}
113118
114119void ObjFile::parse() {
115120 // Parse a memory buffer as a COFF file.
116 std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), this);
121 std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this);
117122
118 if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) {
119 Bin.release();
120 COFFObj.reset(Obj);
123 if (auto *obj = dyn_cast<COFFObjectFile>(bin.get())) {
124 bin.release();
125 coffObj.reset(obj);
121126 } else {
122127 fatal(toString(this) + " is not a COFF file");
123128 }
......@@ -125,6 +130,15 @@ void ObjFile::parse() {
125130 // Read section and symbol tables.
126131 initializeChunks();
127132 initializeSymbols();
133 initializeFlags();
134 initializeDependencies();
135}
136
137const coff_section* ObjFile::getSection(uint32_t i) {
138 const coff_section *sec;
139 if (auto ec = coffObj->getSection(i, sec))
140 fatal("getSection failed: #" + Twine(i) + ": " + ec.message());
141 return sec;
128142}
129143
130144// We set SectionChunk pointers in the SparseChunks vector to this value
......@@ -133,45 +147,42 @@ void ObjFile::parse() {
133147// an associative section definition together with the parent comdat's leader,
134148// we set the pointer to either nullptr (to mark the section as discarded) or a
135149// valid SectionChunk for that section.
136static SectionChunk *const PendingComdat = reinterpret_cast<SectionChunk *>(1);
150static SectionChunk *const pendingComdat = reinterpret_cast<SectionChunk *>(1);
137151
138152void ObjFile::initializeChunks() {
139 uint32_t NumSections = COFFObj->getNumberOfSections();
140 Chunks.reserve(NumSections);
141 SparseChunks.resize(NumSections + 1);
142 for (uint32_t I = 1; I < NumSections + 1; ++I) {
143 const coff_section *Sec;
144 if (auto EC = COFFObj->getSection(I, Sec))
145 fatal("getSection failed: #" + Twine(I) + ": " + EC.message());
146
147 if (Sec->Characteristics & IMAGE_SCN_LNK_COMDAT)
148 SparseChunks[I] = PendingComdat;
153 uint32_t numSections = coffObj->getNumberOfSections();
154 chunks.reserve(numSections);
155 sparseChunks.resize(numSections + 1);
156 for (uint32_t i = 1; i < numSections + 1; ++i) {
157 const coff_section *sec = getSection(i);
158 if (sec->Characteristics & IMAGE_SCN_LNK_COMDAT)
159 sparseChunks[i] = pendingComdat;
149160 else
150 SparseChunks[I] = readSection(I, nullptr, "");
161 sparseChunks[i] = readSection(i, nullptr, "");
151162 }
152163}
153164
154SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
155 const coff_aux_section_definition *Def,
156 StringRef LeaderName) {
157 const coff_section *Sec;
158 if (auto EC = COFFObj->getSection(SectionNumber, Sec))
159 fatal("getSection failed: #" + Twine(SectionNumber) + ": " + EC.message());
160
161 StringRef Name;
162 if (auto EC = COFFObj->getSectionName(Sec, Name))
163 fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " +
164 EC.message());
165
166 if (Name == ".drectve") {
167 ArrayRef<uint8_t> Data;
168 COFFObj->getSectionContents(Sec, Data);
169 Directives = std::string((const char *)Data.data(), Data.size());
165SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
166 const coff_aux_section_definition *def,
167 StringRef leaderName) {
168 const coff_section *sec = getSection(sectionNumber);
169
170 StringRef name;
171 if (Expected<StringRef> e = coffObj->getSectionName(sec))
172 name = *e;
173 else
174 fatal("getSectionName failed: #" + Twine(sectionNumber) + ": " +
175 toString(e.takeError()));
176
177 if (name == ".drectve") {
178 ArrayRef<uint8_t> data;
179 cantFail(coffObj->getSectionContents(sec, data));
180 directives = StringRef((const char *)data.data(), data.size());
170181 return nullptr;
171182 }
172183
173 if (Name == ".llvm_addrsig") {
174 AddrsigSec = Sec;
184 if (name == ".llvm_addrsig") {
185 addrsigSec = sec;
175186 return nullptr;
176187 }
177188
......@@ -186,377 +197,648 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
186197 // and then write it to a separate .pdb file.
187198
188199 // Ignore DWARF debug info unless /debug is given.
189 if (!Config->Debug && Name.startswith(".debug_"))
200 if (!config->debug && name.startswith(".debug_"))
190201 return nullptr;
191202
192 if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
203 if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
193204 return nullptr;
194 auto *C = make<SectionChunk>(this, Sec);
195 if (Def)
196 C->Checksum = Def->CheckSum;
205 auto *c = make<SectionChunk>(this, sec);
206 if (def)
207 c->checksum = def->CheckSum;
208
209 // link.exe uses the presence of .rsrc$01 for LNK4078, so match that.
210 if (name == ".rsrc$01")
211 isResourceObjFile = true;
197212
198213 // CodeView sections are stored to a different vector because they are not
199214 // linked in the regular manner.
200 if (C->isCodeView())
201 DebugChunks.push_back(C);
202 else if (Config->GuardCF != GuardCFLevel::Off && Name == ".gfids$y")
203 GuardFidChunks.push_back(C);
204 else if (Config->GuardCF != GuardCFLevel::Off && Name == ".gljmp$y")
205 GuardLJmpChunks.push_back(C);
206 else if (Name == ".sxdata")
207 SXDataChunks.push_back(C);
208 else if (Config->TailMerge && Sec->NumberOfRelocations == 0 &&
209 Name == ".rdata" && LeaderName.startswith("??_C@"))
215 if (c->isCodeView())
216 debugChunks.push_back(c);
217 else if (name == ".gfids$y")
218 guardFidChunks.push_back(c);
219 else if (name == ".gljmp$y")
220 guardLJmpChunks.push_back(c);
221 else if (name == ".sxdata")
222 sXDataChunks.push_back(c);
223 else if (config->tailMerge && sec->NumberOfRelocations == 0 &&
224 name == ".rdata" && leaderName.startswith("??_C@"))
210225 // COFF sections that look like string literal sections (i.e. no
211226 // relocations, in .rdata, leader symbol name matches the MSVC name mangling
212227 // for string literals) are subject to string tail merging.
213 MergeChunk::addSection(C);
228 MergeChunk::addSection(c);
214229 else
215 Chunks.push_back(C);
230 chunks.push_back(c);
216231
217 return C;
232 return c;
218233}
219234
220235void ObjFile::readAssociativeDefinition(
221 COFFSymbolRef Sym, const coff_aux_section_definition *Def) {
222 readAssociativeDefinition(Sym, Def, Def->getNumber(Sym.isBigObj()));
236 COFFSymbolRef sym, const coff_aux_section_definition *def) {
237 readAssociativeDefinition(sym, def, def->getNumber(sym.isBigObj()));
223238}
224239
225void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym,
226 const coff_aux_section_definition *Def,
227 uint32_t ParentSection) {
228 SectionChunk *Parent = SparseChunks[ParentSection];
240void ObjFile::readAssociativeDefinition(COFFSymbolRef sym,
241 const coff_aux_section_definition *def,
242 uint32_t parentIndex) {
243 SectionChunk *parent = sparseChunks[parentIndex];
244 int32_t sectionNumber = sym.getSectionNumber();
245
246 auto diag = [&]() {
247 StringRef name, parentName;
248 coffObj->getSymbolName(sym, name);
249
250 const coff_section *parentSec = getSection(parentIndex);
251 if (Expected<StringRef> e = coffObj->getSectionName(parentSec))
252 parentName = *e;
253 error(toString(this) + ": associative comdat " + name + " (sec " +
254 Twine(sectionNumber) + ") has invalid reference to section " +
255 parentName + " (sec " + Twine(parentIndex) + ")");
256 };
229257
230 // If the parent is pending, it probably means that its section definition
231 // appears after us in the symbol table. Leave the associated section as
232 // pending; we will handle it during the second pass in initializeSymbols().
233 if (Parent == PendingComdat)
258 if (parent == pendingComdat) {
259 // This can happen if an associative comdat refers to another associative
260 // comdat that appears after it (invalid per COFF spec) or to a section
261 // without any symbols.
262 diag();
234263 return;
264 }
235265
236266 // Check whether the parent is prevailing. If it is, so are we, and we read
237267 // the section; otherwise mark it as discarded.
238 int32_t SectionNumber = Sym.getSectionNumber();
239 if (Parent) {
240 SparseChunks[SectionNumber] = readSection(SectionNumber, Def, "");
241 if (SparseChunks[SectionNumber])
242 Parent->addAssociative(SparseChunks[SectionNumber]);
268 if (parent) {
269 SectionChunk *c = readSection(sectionNumber, def, "");
270 sparseChunks[sectionNumber] = c;
271 if (c) {
272 c->selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE;
273 parent->addAssociative(c);
274 }
243275 } else {
244 SparseChunks[SectionNumber] = nullptr;
276 sparseChunks[sectionNumber] = nullptr;
245277 }
246278}
247279
248280void ObjFile::recordPrevailingSymbolForMingw(
249 COFFSymbolRef Sym, DenseMap<StringRef, uint32_t> &PrevailingSectionMap) {
281 COFFSymbolRef sym, DenseMap<StringRef, uint32_t> &prevailingSectionMap) {
250282 // For comdat symbols in executable sections, where this is the copy
251283 // of the section chunk we actually include instead of discarding it,
252284 // add the symbol to a map to allow using it for implicitly
253285 // associating .[px]data$<func> sections to it.
254 int32_t SectionNumber = Sym.getSectionNumber();
255 SectionChunk *SC = SparseChunks[SectionNumber];
256 if (SC && SC->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) {
257 StringRef Name;
258 COFFObj->getSymbolName(Sym, Name);
259 PrevailingSectionMap[Name] = SectionNumber;
286 int32_t sectionNumber = sym.getSectionNumber();
287 SectionChunk *sc = sparseChunks[sectionNumber];
288 if (sc && sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) {
289 StringRef name;
290 coffObj->getSymbolName(sym, name);
291 if (getMachineType() == I386)
292 name.consume_front("_");
293 prevailingSectionMap[name] = sectionNumber;
260294 }
261295}
262296
263297void ObjFile::maybeAssociateSEHForMingw(
264 COFFSymbolRef Sym, const coff_aux_section_definition *Def,
265 const DenseMap<StringRef, uint32_t> &PrevailingSectionMap) {
266 StringRef Name;
267 COFFObj->getSymbolName(Sym, Name);
268 if (Name.consume_front(".pdata$") || Name.consume_front(".xdata$")) {
269 // For MinGW, treat .[px]data$<func> as implicitly associative to
270 // the symbol <func>.
271 auto ParentSym = PrevailingSectionMap.find(Name);
272 if (ParentSym != PrevailingSectionMap.end())
273 readAssociativeDefinition(Sym, Def, ParentSym->second);
298 COFFSymbolRef sym, const coff_aux_section_definition *def,
299 const DenseMap<StringRef, uint32_t> &prevailingSectionMap) {
300 StringRef name;
301 coffObj->getSymbolName(sym, name);
302 if (name.consume_front(".pdata$") || name.consume_front(".xdata$") ||
303 name.consume_front(".eh_frame$")) {
304 // For MinGW, treat .[px]data$<func> and .eh_frame$<func> as implicitly
305 // associative to the symbol <func>.
306 auto parentSym = prevailingSectionMap.find(name);
307 if (parentSym != prevailingSectionMap.end())
308 readAssociativeDefinition(sym, def, parentSym->second);
274309 }
275310}
276311
277Symbol *ObjFile::createRegular(COFFSymbolRef Sym) {
278 SectionChunk *SC = SparseChunks[Sym.getSectionNumber()];
279 if (Sym.isExternal()) {
280 StringRef Name;
281 COFFObj->getSymbolName(Sym, Name);
282 if (SC)
283 return Symtab->addRegular(this, Name, Sym.getGeneric(), SC);
312Symbol *ObjFile::createRegular(COFFSymbolRef sym) {
313 SectionChunk *sc = sparseChunks[sym.getSectionNumber()];
314 if (sym.isExternal()) {
315 StringRef name;
316 coffObj->getSymbolName(sym, name);
317 if (sc)
318 return symtab->addRegular(this, name, sym.getGeneric(), sc);
284319 // For MinGW symbols named .weak.* that point to a discarded section,
285320 // don't create an Undefined symbol. If nothing ever refers to the symbol,
286321 // everything should be fine. If something actually refers to the symbol
287322 // (e.g. the undefined weak alias), linking will fail due to undefined
288323 // references at the end.
289 if (Config->MinGW && Name.startswith(".weak."))
324 if (config->mingw && name.startswith(".weak."))
290325 return nullptr;
291 return Symtab->addUndefined(Name, this, false);
326 return symtab->addUndefined(name, this, false);
292327 }
293 if (SC)
328 if (sc)
294329 return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
295 /*IsExternal*/ false, Sym.getGeneric(), SC);
330 /*IsExternal*/ false, sym.getGeneric(), sc);
296331 return nullptr;
297332}
298333
299334void ObjFile::initializeSymbols() {
300 uint32_t NumSymbols = COFFObj->getNumberOfSymbols();
301 Symbols.resize(NumSymbols);
302
303 SmallVector<std::pair<Symbol *, uint32_t>, 8> WeakAliases;
304 std::vector<uint32_t> PendingIndexes;
305 PendingIndexes.reserve(NumSymbols);
306
307 DenseMap<StringRef, uint32_t> PrevailingSectionMap;
308 std::vector<const coff_aux_section_definition *> ComdatDefs(
309 COFFObj->getNumberOfSections() + 1);
310
311 for (uint32_t I = 0; I < NumSymbols; ++I) {
312 COFFSymbolRef COFFSym = check(COFFObj->getSymbol(I));
313 bool PrevailingComdat;
314 if (COFFSym.isUndefined()) {
315 Symbols[I] = createUndefined(COFFSym);
316 } else if (COFFSym.isWeakExternal()) {
317 Symbols[I] = createUndefined(COFFSym);
318 uint32_t TagIndex = COFFSym.getAux<coff_aux_weak_external>()->TagIndex;
319 WeakAliases.emplace_back(Symbols[I], TagIndex);
320 } else if (Optional<Symbol *> OptSym =
321 createDefined(COFFSym, ComdatDefs, PrevailingComdat)) {
322 Symbols[I] = *OptSym;
323 if (Config->MinGW && PrevailingComdat)
324 recordPrevailingSymbolForMingw(COFFSym, PrevailingSectionMap);
335 uint32_t numSymbols = coffObj->getNumberOfSymbols();
336 symbols.resize(numSymbols);
337
338 SmallVector<std::pair<Symbol *, uint32_t>, 8> weakAliases;
339 std::vector<uint32_t> pendingIndexes;
340 pendingIndexes.reserve(numSymbols);
341
342 DenseMap<StringRef, uint32_t> prevailingSectionMap;
343 std::vector<const coff_aux_section_definition *> comdatDefs(
344 coffObj->getNumberOfSections() + 1);
345
346 for (uint32_t i = 0; i < numSymbols; ++i) {
347 COFFSymbolRef coffSym = check(coffObj->getSymbol(i));
348 bool prevailingComdat;
349 if (coffSym.isUndefined()) {
350 symbols[i] = createUndefined(coffSym);
351 } else if (coffSym.isWeakExternal()) {
352 symbols[i] = createUndefined(coffSym);
353 uint32_t tagIndex = coffSym.getAux<coff_aux_weak_external>()->TagIndex;
354 weakAliases.emplace_back(symbols[i], tagIndex);
355 } else if (Optional<Symbol *> optSym =
356 createDefined(coffSym, comdatDefs, prevailingComdat)) {
357 symbols[i] = *optSym;
358 if (config->mingw && prevailingComdat)
359 recordPrevailingSymbolForMingw(coffSym, prevailingSectionMap);
325360 } else {
326361 // createDefined() returns None if a symbol belongs to a section that
327362 // was pending at the point when the symbol was read. This can happen in
328363 // two cases:
329364 // 1) section definition symbol for a comdat leader;
330 // 2) symbol belongs to a comdat section associated with a section whose
331 // section definition symbol appears later in the symbol table.
365 // 2) symbol belongs to a comdat section associated with another section.
332366 // In both of these cases, we can expect the section to be resolved by
333367 // the time we finish visiting the remaining symbols in the symbol
334368 // table. So we postpone the handling of this symbol until that time.
335 PendingIndexes.push_back(I);
369 pendingIndexes.push_back(i);
336370 }
337 I += COFFSym.getNumberOfAuxSymbols();
371 i += coffSym.getNumberOfAuxSymbols();
338372 }
339373
340 for (uint32_t I : PendingIndexes) {
341 COFFSymbolRef Sym = check(COFFObj->getSymbol(I));
342 if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
343 if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
344 readAssociativeDefinition(Sym, Def);
345 else if (Config->MinGW)
346 maybeAssociateSEHForMingw(Sym, Def, PrevailingSectionMap);
374 for (uint32_t i : pendingIndexes) {
375 COFFSymbolRef sym = check(coffObj->getSymbol(i));
376 if (const coff_aux_section_definition *def = sym.getSectionDefinition()) {
377 if (def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
378 readAssociativeDefinition(sym, def);
379 else if (config->mingw)
380 maybeAssociateSEHForMingw(sym, def, prevailingSectionMap);
347381 }
348 if (SparseChunks[Sym.getSectionNumber()] == PendingComdat) {
349 StringRef Name;
350 COFFObj->getSymbolName(Sym, Name);
351 log("comdat section " + Name +
382 if (sparseChunks[sym.getSectionNumber()] == pendingComdat) {
383 StringRef name;
384 coffObj->getSymbolName(sym, name);
385 log("comdat section " + name +
352386 " without leader and unassociated, discarding");
353387 continue;
354388 }
355 Symbols[I] = createRegular(Sym);
389 symbols[i] = createRegular(sym);
356390 }
357391
358 for (auto &KV : WeakAliases) {
359 Symbol *Sym = KV.first;
360 uint32_t Idx = KV.second;
361 checkAndSetWeakAlias(Symtab, this, Sym, Symbols[Idx]);
392 for (auto &kv : weakAliases) {
393 Symbol *sym = kv.first;
394 uint32_t idx = kv.second;
395 checkAndSetWeakAlias(symtab, this, sym, symbols[idx]);
362396 }
363397}
364398
365Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) {
366 StringRef Name;
367 COFFObj->getSymbolName(Sym, Name);
368 return Symtab->addUndefined(Name, this, Sym.isWeakExternal());
399Symbol *ObjFile::createUndefined(COFFSymbolRef sym) {
400 StringRef name;
401 coffObj->getSymbolName(sym, name);
402 return symtab->addUndefined(name, this, sym.isWeakExternal());
403}
404
405void ObjFile::handleComdatSelection(COFFSymbolRef sym, COMDATType &selection,
406 bool &prevailing, DefinedRegular *leader) {
407 if (prevailing)
408 return;
409 // There's already an existing comdat for this symbol: `Leader`.
410 // Use the comdats's selection field to determine if the new
411 // symbol in `Sym` should be discarded, produce a duplicate symbol
412 // error, etc.
413
414 SectionChunk *leaderChunk = nullptr;
415 COMDATType leaderSelection = IMAGE_COMDAT_SELECT_ANY;
416
417 if (leader->data) {
418 leaderChunk = leader->getChunk();
419 leaderSelection = leaderChunk->selection;
420 } else {
421 // FIXME: comdats from LTO files don't know their selection; treat them
422 // as "any".
423 selection = leaderSelection;
424 }
425
426 if ((selection == IMAGE_COMDAT_SELECT_ANY &&
427 leaderSelection == IMAGE_COMDAT_SELECT_LARGEST) ||
428 (selection == IMAGE_COMDAT_SELECT_LARGEST &&
429 leaderSelection == IMAGE_COMDAT_SELECT_ANY)) {
430 // cl.exe picks "any" for vftables when building with /GR- and
431 // "largest" when building with /GR. To be able to link object files
432 // compiled with each flag, "any" and "largest" are merged as "largest".
433 leaderSelection = selection = IMAGE_COMDAT_SELECT_LARGEST;
434 }
435
436 // Other than that, comdat selections must match. This is a bit more
437 // strict than link.exe which allows merging "any" and "largest" if "any"
438 // is the first symbol the linker sees, and it allows merging "largest"
439 // with everything (!) if "largest" is the first symbol the linker sees.
440 // Making this symmetric independent of which selection is seen first
441 // seems better though.
442 // (This behavior matches ModuleLinker::getComdatResult().)
443 if (selection != leaderSelection) {
444 log(("conflicting comdat type for " + toString(*leader) + ": " +
445 Twine((int)leaderSelection) + " in " + toString(leader->getFile()) +
446 " and " + Twine((int)selection) + " in " + toString(this))
447 .str());
448 symtab->reportDuplicate(leader, this);
449 return;
450 }
451
452 switch (selection) {
453 case IMAGE_COMDAT_SELECT_NODUPLICATES:
454 symtab->reportDuplicate(leader, this);
455 break;
456
457 case IMAGE_COMDAT_SELECT_ANY:
458 // Nothing to do.
459 break;
460
461 case IMAGE_COMDAT_SELECT_SAME_SIZE:
462 if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData)
463 symtab->reportDuplicate(leader, this);
464 break;
465
466 case IMAGE_COMDAT_SELECT_EXACT_MATCH: {
467 SectionChunk newChunk(this, getSection(sym));
468 // link.exe only compares section contents here and doesn't complain
469 // if the two comdat sections have e.g. different alignment.
470 // Match that.
471 if (leaderChunk->getContents() != newChunk.getContents())
472 symtab->reportDuplicate(leader, this);
473 break;
474 }
475
476 case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
477 // createDefined() is never called for IMAGE_COMDAT_SELECT_ASSOCIATIVE.
478 // (This means lld-link doesn't produce duplicate symbol errors for
479 // associative comdats while link.exe does, but associate comdats
480 // are never extern in practice.)
481 llvm_unreachable("createDefined not called for associative comdats");
482
483 case IMAGE_COMDAT_SELECT_LARGEST:
484 if (leaderChunk->getSize() < getSection(sym)->SizeOfRawData) {
485 // Replace the existing comdat symbol with the new one.
486 StringRef name;
487 coffObj->getSymbolName(sym, name);
488 // FIXME: This is incorrect: With /opt:noref, the previous sections
489 // make it into the final executable as well. Correct handling would
490 // be to undo reading of the whole old section that's being replaced,
491 // or doing one pass that determines what the final largest comdat
492 // is for all IMAGE_COMDAT_SELECT_LARGEST comdats and then reading
493 // only the largest one.
494 replaceSymbol<DefinedRegular>(leader, this, name, /*IsCOMDAT*/ true,
495 /*IsExternal*/ true, sym.getGeneric(),
496 nullptr);
497 prevailing = true;
498 }
499 break;
500
501 case IMAGE_COMDAT_SELECT_NEWEST:
502 llvm_unreachable("should have been rejected earlier");
503 }
369504}
370505
371506Optional<Symbol *> ObjFile::createDefined(
372 COFFSymbolRef Sym,
373 std::vector<const coff_aux_section_definition *> &ComdatDefs,
374 bool &Prevailing) {
375 Prevailing = false;
376 auto GetName = [&]() {
377 StringRef S;
378 COFFObj->getSymbolName(Sym, S);
379 return S;
507 COFFSymbolRef sym,
508 std::vector<const coff_aux_section_definition *> &comdatDefs,
509 bool &prevailing) {
510 prevailing = false;
511 auto getName = [&]() {
512 StringRef s;
513 coffObj->getSymbolName(sym, s);
514 return s;
380515 };
381516
382 if (Sym.isCommon()) {
383 auto *C = make<CommonChunk>(Sym);
384 Chunks.push_back(C);
385 return Symtab->addCommon(this, GetName(), Sym.getValue(), Sym.getGeneric(),
386 C);
517 if (sym.isCommon()) {
518 auto *c = make<CommonChunk>(sym);
519 chunks.push_back(c);
520 return symtab->addCommon(this, getName(), sym.getValue(), sym.getGeneric(),
521 c);
387522 }
388523
389 if (Sym.isAbsolute()) {
390 StringRef Name = GetName();
524 if (sym.isAbsolute()) {
525 StringRef name = getName();
391526
392527 // Skip special symbols.
393 if (Name == "@comp.id")
528 if (name == "@comp.id")
394529 return nullptr;
395 if (Name == "@feat.00") {
396 Feat00Flags = Sym.getValue();
530 if (name == "@feat.00") {
531 feat00Flags = sym.getValue();
397532 return nullptr;
398533 }
399534
400 if (Sym.isExternal())
401 return Symtab->addAbsolute(Name, Sym);
402 return make<DefinedAbsolute>(Name, Sym);
535 if (sym.isExternal())
536 return symtab->addAbsolute(name, sym);
537 return make<DefinedAbsolute>(name, sym);
403538 }
404539
405 int32_t SectionNumber = Sym.getSectionNumber();
406 if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
540 int32_t sectionNumber = sym.getSectionNumber();
541 if (sectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
407542 return nullptr;
408543
409 if (llvm::COFF::isReservedSectionNumber(SectionNumber))
410 fatal(toString(this) + ": " + GetName() +
411 " should not refer to special section " + Twine(SectionNumber));
412
413 if ((uint32_t)SectionNumber >= SparseChunks.size())
414 fatal(toString(this) + ": " + GetName() +
415 " should not refer to non-existent section " + Twine(SectionNumber));
416
417 // Handle comdat leader symbols.
418 if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) {
419 ComdatDefs[SectionNumber] = nullptr;
420 Symbol *Leader;
421 if (Sym.isExternal()) {
422 std::tie(Leader, Prevailing) =
423 Symtab->addComdat(this, GetName(), Sym.getGeneric());
544 if (llvm::COFF::isReservedSectionNumber(sectionNumber))
545 fatal(toString(this) + ": " + getName() +
546 " should not refer to special section " + Twine(sectionNumber));
547
548 if ((uint32_t)sectionNumber >= sparseChunks.size())
549 fatal(toString(this) + ": " + getName() +
550 " should not refer to non-existent section " + Twine(sectionNumber));
551
552 // Comdat handling.
553 // A comdat symbol consists of two symbol table entries.
554 // The first symbol entry has the name of the section (e.g. .text), fixed
555 // values for the other fields, and one auxilliary record.
556 // The second symbol entry has the name of the comdat symbol, called the
557 // "comdat leader".
558 // When this function is called for the first symbol entry of a comdat,
559 // it sets comdatDefs and returns None, and when it's called for the second
560 // symbol entry it reads comdatDefs and then sets it back to nullptr.
561
562 // Handle comdat leader.
563 if (const coff_aux_section_definition *def = comdatDefs[sectionNumber]) {
564 comdatDefs[sectionNumber] = nullptr;
565 DefinedRegular *leader;
566
567 if (sym.isExternal()) {
568 std::tie(leader, prevailing) =
569 symtab->addComdat(this, getName(), sym.getGeneric());
424570 } else {
425 Leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
426 /*IsExternal*/ false, Sym.getGeneric());
427 Prevailing = true;
571 leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
572 /*IsExternal*/ false, sym.getGeneric());
573 prevailing = true;
428574 }
429575
430 if (Prevailing) {
431 SectionChunk *C = readSection(SectionNumber, Def, GetName());
432 SparseChunks[SectionNumber] = C;
433 C->Sym = cast<DefinedRegular>(Leader);
434 cast<DefinedRegular>(Leader)->Data = &C->Repl;
435 } else {
436 SparseChunks[SectionNumber] = nullptr;
576 if (def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES ||
577 // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe
578 // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either.
579 def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) {
580 fatal("unknown comdat type " + std::to_string((int)def->Selection) +
581 " for " + getName() + " in " + toString(this));
437582 }
438 return Leader;
439 }
583 COMDATType selection = (COMDATType)def->Selection;
440584
441 // Read associative section definitions and prepare to handle the comdat
442 // leader symbol by setting the section's ComdatDefs pointer if we encounter a
443 // non-associative comdat.
444 if (SparseChunks[SectionNumber] == PendingComdat) {
445 if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
446 if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
447 readAssociativeDefinition(Sym, Def);
448 else
449 ComdatDefs[SectionNumber] = Def;
585 if (leader->isCOMDAT)
586 handleComdatSelection(sym, selection, prevailing, leader);
587
588 if (prevailing) {
589 SectionChunk *c = readSection(sectionNumber, def, getName());
590 sparseChunks[sectionNumber] = c;
591 c->sym = cast<DefinedRegular>(leader);
592 c->selection = selection;
593 cast<DefinedRegular>(leader)->data = &c->repl;
594 } else {
595 sparseChunks[sectionNumber] = nullptr;
450596 }
597 return leader;
451598 }
452599
453 // readAssociativeDefinition() writes to SparseChunks, so need to check again.
454 if (SparseChunks[SectionNumber] == PendingComdat)
600 // Prepare to handle the comdat leader symbol by setting the section's
601 // ComdatDefs pointer if we encounter a non-associative comdat.
602 if (sparseChunks[sectionNumber] == pendingComdat) {
603 if (const coff_aux_section_definition *def = sym.getSectionDefinition()) {
604 if (def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE)
605 comdatDefs[sectionNumber] = def;
606 }
455607 return None;
608 }
456609
457 return createRegular(Sym);
610 return createRegular(sym);
458611}
459612
460613MachineTypes ObjFile::getMachineType() {
461 if (COFFObj)
462 return static_cast<MachineTypes>(COFFObj->getMachine());
614 if (coffObj)
615 return static_cast<MachineTypes>(coffObj->getMachine());
463616 return IMAGE_FILE_MACHINE_UNKNOWN;
464617}
465618
466StringRef ltrim1(StringRef S, const char *Chars) {
467 if (!S.empty() && strchr(Chars, S[0]))
468 return S.substr(1);
469 return S;
619ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef secName) {
620 if (SectionChunk *sec = SectionChunk::findByName(debugChunks, secName))
621 return sec->consumeDebugMagic();
622 return {};
623}
624
625// OBJ files systematically store critical informations in a .debug$S stream,
626// even if the TU was compiled with no debug info. At least two records are
627// always there. S_OBJNAME stores a 32-bit signature, which is loaded into the
628// PCHSignature member. S_COMPILE3 stores compile-time cmd-line flags. This is
629// currently used to initialize the hotPatchable member.
630void ObjFile::initializeFlags() {
631 ArrayRef<uint8_t> data = getDebugSection(".debug$S");
632 if (data.empty())
633 return;
634
635 DebugSubsectionArray subsections;
636
637 BinaryStreamReader reader(data, support::little);
638 ExitOnError exitOnErr;
639 exitOnErr(reader.readArray(subsections, data.size()));
640
641 for (const DebugSubsectionRecord &ss : subsections) {
642 if (ss.kind() != DebugSubsectionKind::Symbols)
643 continue;
644
645 unsigned offset = 0;
646
647 // Only parse the first two records. We are only looking for S_OBJNAME
648 // and S_COMPILE3, and they usually appear at the beginning of the
649 // stream.
650 for (unsigned i = 0; i < 2; ++i) {
651 Expected<CVSymbol> sym = readSymbolFromStream(ss.getRecordData(), offset);
652 if (!sym) {
653 consumeError(sym.takeError());
654 return;
655 }
656 if (sym->kind() == SymbolKind::S_COMPILE3) {
657 auto cs =
658 cantFail(SymbolDeserializer::deserializeAs<Compile3Sym>(sym.get()));
659 hotPatchable =
660 (cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None;
661 }
662 if (sym->kind() == SymbolKind::S_OBJNAME) {
663 auto objName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(
664 sym.get()));
665 pchSignature = objName.Signature;
666 }
667 offset += sym->length();
668 }
669 }
670}
671
672// Depending on the compilation flags, OBJs can refer to external files,
673// necessary to merge this OBJ into the final PDB. We currently support two
674// types of external files: Precomp/PCH OBJs, when compiling with /Yc and /Yu.
675// And PDB type servers, when compiling with /Zi. This function extracts these
676// dependencies and makes them available as a TpiSource interface (see
677// DebugTypes.h). Both cases only happen with cl.exe: clang-cl produces regular
678// output even with /Yc and /Yu and with /Zi.
679void ObjFile::initializeDependencies() {
680 if (!config->debug)
681 return;
682
683 bool isPCH = false;
684
685 ArrayRef<uint8_t> data = getDebugSection(".debug$P");
686 if (!data.empty())
687 isPCH = true;
688 else
689 data = getDebugSection(".debug$T");
690
691 if (data.empty())
692 return;
693
694 CVTypeArray types;
695 BinaryStreamReader reader(data, support::little);
696 cantFail(reader.readArray(types, reader.getLength()));
697
698 CVTypeArray::Iterator firstType = types.begin();
699 if (firstType == types.end())
700 return;
701
702 debugTypes.emplace(types);
703
704 if (isPCH) {
705 debugTypesObj = makePrecompSource(this);
706 return;
707 }
708
709 if (firstType->kind() == LF_TYPESERVER2) {
710 TypeServer2Record ts = cantFail(
711 TypeDeserializer::deserializeAs<TypeServer2Record>(firstType->data()));
712 debugTypesObj = makeUseTypeServerSource(this, &ts);
713 return;
714 }
715
716 if (firstType->kind() == LF_PRECOMP) {
717 PrecompRecord precomp = cantFail(
718 TypeDeserializer::deserializeAs<PrecompRecord>(firstType->data()));
719 debugTypesObj = makeUsePrecompSource(this, &precomp);
720 return;
721 }
722
723 debugTypesObj = makeTpiSource(this);
724}
725
726StringRef ltrim1(StringRef s, const char *chars) {
727 if (!s.empty() && strchr(chars, s[0]))
728 return s.substr(1);
729 return s;
470730}
471731
472732void ImportFile::parse() {
473 const char *Buf = MB.getBufferStart();
474 const char *End = MB.getBufferEnd();
475 const auto *Hdr = reinterpret_cast<const coff_import_header *>(Buf);
733 const char *buf = mb.getBufferStart();
734 const auto *hdr = reinterpret_cast<const coff_import_header *>(buf);
476735
477736 // Check if the total size is valid.
478 if ((size_t)(End - Buf) != (sizeof(*Hdr) + Hdr->SizeOfData))
737 if (mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)
479738 fatal("broken import library");
480739
481740 // Read names and create an __imp_ symbol.
482 StringRef Name = Saver.save(StringRef(Buf + sizeof(*Hdr)));
483 StringRef ImpName = Saver.save("__imp_" + Name);
484 const char *NameStart = Buf + sizeof(coff_import_header) + Name.size() + 1;
485 DLLName = StringRef(NameStart);
486 StringRef ExtName;
487 switch (Hdr->getNameType()) {
741 StringRef name = saver.save(StringRef(buf + sizeof(*hdr)));
742 StringRef impName = saver.save("__imp_" + name);
743 const char *nameStart = buf + sizeof(coff_import_header) + name.size() + 1;
744 dllName = StringRef(nameStart);
745 StringRef extName;
746 switch (hdr->getNameType()) {
488747 case IMPORT_ORDINAL:
489 ExtName = "";
748 extName = "";
490749 break;
491750 case IMPORT_NAME:
492 ExtName = Name;
751 extName = name;
493752 break;
494753 case IMPORT_NAME_NOPREFIX:
495 ExtName = ltrim1(Name, "?@_");
754 extName = ltrim1(name, "?@_");
496755 break;
497756 case IMPORT_NAME_UNDECORATE:
498 ExtName = ltrim1(Name, "?@_");
499 ExtName = ExtName.substr(0, ExtName.find('@'));
757 extName = ltrim1(name, "?@_");
758 extName = extName.substr(0, extName.find('@'));
500759 break;
501760 }
502761
503 this->Hdr = Hdr;
504 ExternalName = ExtName;
762 this->hdr = hdr;
763 externalName = extName;
505764
506 ImpSym = Symtab->addImportData(ImpName, this);
765 impSym = symtab->addImportData(impName, this);
507766 // If this was a duplicate, we logged an error but may continue;
508 // in this case, ImpSym is nullptr.
509 if (!ImpSym)
767 // in this case, impSym is nullptr.
768 if (!impSym)
510769 return;
511770
512 if (Hdr->getType() == llvm::COFF::IMPORT_CONST)
513 static_cast<void>(Symtab->addImportData(Name, this));
771 if (hdr->getType() == llvm::COFF::IMPORT_CONST)
772 static_cast<void>(symtab->addImportData(name, this));
514773
515774 // If type is function, we need to create a thunk which jump to an
516775 // address pointed by the __imp_ symbol. (This allows you to call
517776 // DLL functions just like regular non-DLL functions.)
518 if (Hdr->getType() == llvm::COFF::IMPORT_CODE)
519 ThunkSym = Symtab->addImportThunk(
520 Name, cast_or_null<DefinedImportData>(ImpSym), Hdr->Machine);
777 if (hdr->getType() == llvm::COFF::IMPORT_CODE)
778 thunkSym = symtab->addImportThunk(
779 name, cast_or_null<DefinedImportData>(impSym), hdr->Machine);
780}
781
782BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
783 uint64_t offsetInArchive)
784 : InputFile(BitcodeKind, mb) {
785 std::string path = mb.getBufferIdentifier().str();
786 if (config->thinLTOIndexOnly)
787 path = replaceThinLTOSuffix(mb.getBufferIdentifier());
788
789 // ThinLTO assumes that all MemoryBufferRefs given to it have a unique
790 // name. If two archives define two members with the same name, this
791 // causes a collision which result in only one of the objects being taken
792 // into consideration at LTO time (which very likely causes undefined
793 // symbols later in the link stage). So we append file offset to make
794 // filename unique.
795 MemoryBufferRef mbref(
796 mb.getBuffer(),
797 saver.save(archiveName + path +
798 (archiveName.empty() ? "" : utostr(offsetInArchive))));
799
800 obj = check(lto::InputFile::create(mbref));
521801}
522802
523803void BitcodeFile::parse() {
524 Obj = check(lto::InputFile::create(MemoryBufferRef(
525 MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
526 std::vector<std::pair<Symbol *, bool>> Comdat(Obj->getComdatTable().size());
527 for (size_t I = 0; I != Obj->getComdatTable().size(); ++I)
528 Comdat[I] = Symtab->addComdat(this, Saver.save(Obj->getComdatTable()[I]));
529 for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) {
530 StringRef SymName = Saver.save(ObjSym.getName());
531 int ComdatIndex = ObjSym.getComdatIndex();
532 Symbol *Sym;
533 if (ObjSym.isUndefined()) {
534 Sym = Symtab->addUndefined(SymName, this, false);
535 } else if (ObjSym.isCommon()) {
536 Sym = Symtab->addCommon(this, SymName, ObjSym.getCommonSize());
537 } else if (ObjSym.isWeak() && ObjSym.isIndirect()) {
804 std::vector<std::pair<Symbol *, bool>> comdat(obj->getComdatTable().size());
805 for (size_t i = 0; i != obj->getComdatTable().size(); ++i)
806 // FIXME: lto::InputFile doesn't keep enough data to do correct comdat
807 // selection handling.
808 comdat[i] = symtab->addComdat(this, saver.save(obj->getComdatTable()[i]));
809 for (const lto::InputFile::Symbol &objSym : obj->symbols()) {
810 StringRef symName = saver.save(objSym.getName());
811 int comdatIndex = objSym.getComdatIndex();
812 Symbol *sym;
813 if (objSym.isUndefined()) {
814 sym = symtab->addUndefined(symName, this, false);
815 } else if (objSym.isCommon()) {
816 sym = symtab->addCommon(this, symName, objSym.getCommonSize());
817 } else if (objSym.isWeak() && objSym.isIndirect()) {
538818 // Weak external.
539 Sym = Symtab->addUndefined(SymName, this, true);
540 std::string Fallback = ObjSym.getCOFFWeakExternalFallback();
541 Symbol *Alias = Symtab->addUndefined(Saver.save(Fallback));
542 checkAndSetWeakAlias(Symtab, this, Sym, Alias);
543 } else if (ComdatIndex != -1) {
544 if (SymName == Obj->getComdatTable()[ComdatIndex])
545 Sym = Comdat[ComdatIndex].first;
546 else if (Comdat[ComdatIndex].second)
547 Sym = Symtab->addRegular(this, SymName);
819 sym = symtab->addUndefined(symName, this, true);
820 std::string fallback = objSym.getCOFFWeakExternalFallback();
821 Symbol *alias = symtab->addUndefined(saver.save(fallback));
822 checkAndSetWeakAlias(symtab, this, sym, alias);
823 } else if (comdatIndex != -1) {
824 if (symName == obj->getComdatTable()[comdatIndex])
825 sym = comdat[comdatIndex].first;
826 else if (comdat[comdatIndex].second)
827 sym = symtab->addRegular(this, symName);
548828 else
549 Sym = Symtab->addUndefined(SymName, this, false);
829 sym = symtab->addUndefined(symName, this, false);
550830 } else {
551 Sym = Symtab->addRegular(this, SymName);
831 sym = symtab->addRegular(this, symName);
552832 }
553 Symbols.push_back(Sym);
833 symbols.push_back(sym);
834 if (objSym.isUsed())
835 config->gcroot.push_back(sym);
554836 }
555 Directives = Obj->getCOFFLinkerOpts();
837 directives = obj->getCOFFLinkerOpts();
556838}
557839
558840MachineTypes BitcodeFile::getMachineType() {
559 switch (Triple(Obj->getTargetTriple()).getArch()) {
841 switch (Triple(obj->getTargetTriple()).getArch()) {
560842 case Triple::x86_64:
561843 return AMD64;
562844 case Triple::x86:
......@@ -569,22 +851,31 @@ MachineTypes BitcodeFile::getMachineType() {
569851 return IMAGE_FILE_MACHINE_UNKNOWN;
570852 }
571853}
854
855std::string replaceThinLTOSuffix(StringRef path) {
856 StringRef suffix = config->thinLTOObjectSuffixReplace.first;
857 StringRef repl = config->thinLTOObjectSuffixReplace.second;
858
859 if (path.consume_back(suffix))
860 return (path + repl).str();
861 return path;
862}
572863} // namespace coff
573864} // namespace lld
574865
575866// Returns the last element of a path, which is supposed to be a filename.
576static StringRef getBasename(StringRef Path) {
577 return sys::path::filename(Path, sys::path::Style::windows);
867static StringRef getBasename(StringRef path) {
868 return sys::path::filename(path, sys::path::Style::windows);
578869}
579870
580871// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".
581std::string lld::toString(const coff::InputFile *File) {
582 if (!File)
872std::string lld::toString(const coff::InputFile *file) {
873 if (!file)
583874 return "<internal>";
584 if (File->ParentName.empty())
585 return File->getName();
875 if (file->parentName.empty() || file->kind() == coff::InputFile::ImportKind)
876 return file->getName();
586877
587 return (getBasename(File->ParentName) + "(" + getBasename(File->getName()) +
878 return (getBasename(file->parentName) + "(" + getBasename(file->getName()) +
588879 ")")
589880 .str();
590881}
deps/lld/COFF/InputFiles.h+125-84
......@@ -1,9 +1,8 @@
11//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -33,7 +32,7 @@ class DbiModuleDescriptorBuilder;
3332namespace lld {
3433namespace coff {
3534
36std::vector<MemoryBufferRef> getArchiveMembers(llvm::object::Archive *File);
35std::vector<MemoryBufferRef> getArchiveMembers(llvm::object::Archive *file);
3736
3837using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
3938using llvm::COFF::MachineTypes;
......@@ -47,20 +46,22 @@ class Chunk;
4746class Defined;
4847class DefinedImportData;
4948class DefinedImportThunk;
49class DefinedRegular;
5050class Lazy;
5151class SectionChunk;
5252class Symbol;
5353class Undefined;
54class TpiSource;
5455
5556// The root class of input files.
5657class InputFile {
5758public:
5859 enum Kind { ArchiveKind, ObjectKind, ImportKind, BitcodeKind };
59 Kind kind() const { return FileKind; }
60 Kind kind() const { return fileKind; }
6061 virtual ~InputFile() {}
6162
6263 // Returns the filename.
63 StringRef getName() const { return MB.getBufferIdentifier(); }
64 StringRef getName() const { return mb.getBufferIdentifier(); }
6465
6566 // Reads a file (the constructor doesn't do that).
6667 virtual void parse() = 0;
......@@ -68,158 +69,195 @@ public:
6869 // Returns the CPU type this file was compiled to.
6970 virtual MachineTypes getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; }
7071
71 MemoryBufferRef MB;
72 MemoryBufferRef mb;
7273
7374 // An archive file name if this file is created from an archive.
74 StringRef ParentName;
75 StringRef parentName;
7576
7677 // Returns .drectve section contents if exist.
77 StringRef getDirectives() { return StringRef(Directives).trim(); }
78 StringRef getDirectives() { return directives; }
7879
7980protected:
80 InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
81 InputFile(Kind k, MemoryBufferRef m) : mb(m), fileKind(k) {}
8182
82 std::string Directives;
83 StringRef directives;
8384
8485private:
85 const Kind FileKind;
86 const Kind fileKind;
8687};
8788
8889// .lib or .a file.
8990class ArchiveFile : public InputFile {
9091public:
91 explicit ArchiveFile(MemoryBufferRef M);
92 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
92 explicit ArchiveFile(MemoryBufferRef m);
93 static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; }
9394 void parse() override;
9495
9596 // Enqueues an archive member load for the given symbol. If we've already
9697 // enqueued a load for the same archive member, this function does nothing,
9798 // which ensures that we don't load the same member more than once.
98 void addMember(const Archive::Symbol *Sym);
99 void addMember(const Archive::Symbol *sym);
99100
100101private:
101 std::unique_ptr<Archive> File;
102 std::string Filename;
103 llvm::DenseSet<uint64_t> Seen;
102 std::unique_ptr<Archive> file;
103 llvm::DenseSet<uint64_t> seen;
104104};
105105
106106// .obj or .o file. This may be a member of an archive file.
107107class ObjFile : public InputFile {
108108public:
109 explicit ObjFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {}
110 static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
109 explicit ObjFile(MemoryBufferRef m) : InputFile(ObjectKind, m) {}
110 static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
111111 void parse() override;
112112 MachineTypes getMachineType() override;
113 ArrayRef<Chunk *> getChunks() { return Chunks; }
114 ArrayRef<SectionChunk *> getDebugChunks() { return DebugChunks; }
115 ArrayRef<SectionChunk *> getSXDataChunks() { return SXDataChunks; }
116 ArrayRef<SectionChunk *> getGuardFidChunks() { return GuardFidChunks; }
117 ArrayRef<SectionChunk *> getGuardLJmpChunks() { return GuardLJmpChunks; }
118 ArrayRef<Symbol *> getSymbols() { return Symbols; }
119
120 // Returns a Symbol object for the SymbolIndex'th symbol in the
113 ArrayRef<Chunk *> getChunks() { return chunks; }
114 ArrayRef<SectionChunk *> getDebugChunks() { return debugChunks; }
115 ArrayRef<SectionChunk *> getSXDataChunks() { return sXDataChunks; }
116 ArrayRef<SectionChunk *> getGuardFidChunks() { return guardFidChunks; }
117 ArrayRef<SectionChunk *> getGuardLJmpChunks() { return guardLJmpChunks; }
118 ArrayRef<Symbol *> getSymbols() { return symbols; }
119
120 ArrayRef<uint8_t> getDebugSection(StringRef secName);
121
122 // Returns a Symbol object for the symbolIndex'th symbol in the
121123 // underlying object file.
122 Symbol *getSymbol(uint32_t SymbolIndex) {
123 return Symbols[SymbolIndex];
124 Symbol *getSymbol(uint32_t symbolIndex) {
125 return symbols[symbolIndex];
124126 }
125127
126128 // Returns the underlying COFF file.
127 COFFObjectFile *getCOFFObj() { return COFFObj.get(); }
129 COFFObjectFile *getCOFFObj() { return coffObj.get(); }
128130
129 // Whether the object was already merged into the final PDB or not
130 bool wasProcessedForPDB() const { return !!ModuleDBI; }
131 // Add a symbol for a range extension thunk. Return the new symbol table
132 // index. This index can be used to modify a relocation.
133 uint32_t addRangeThunkSymbol(Symbol *thunk) {
134 symbols.push_back(thunk);
135 return symbols.size() - 1;
136 }
131137
132 static std::vector<ObjFile *> Instances;
138 static std::vector<ObjFile *> instances;
133139
134140 // Flags in the absolute @feat.00 symbol if it is present. These usually
135141 // indicate if an object was compiled with certain security features enabled
136142 // like stack guard, safeseh, /guard:cf, or other things.
137 uint32_t Feat00Flags = 0;
143 uint32_t feat00Flags = 0;
138144
139145 // True if this object file is compatible with SEH. COFF-specific and
140146 // x86-only. COFF spec 5.10.1. The .sxdata section.
141 bool hasSafeSEH() { return Feat00Flags & 0x1; }
147 bool hasSafeSEH() { return feat00Flags & 0x1; }
142148
143149 // True if this file was compiled with /guard:cf.
144 bool hasGuardCF() { return Feat00Flags & 0x800; }
150 bool hasGuardCF() { return feat00Flags & 0x800; }
145151
146152 // Pointer to the PDB module descriptor builder. Various debug info records
147153 // will reference object files by "module index", which is here. Things like
148154 // source files and section contributions are also recorded here. Will be null
149155 // if we are not producing a PDB.
150 llvm::pdb::DbiModuleDescriptorBuilder *ModuleDBI = nullptr;
156 llvm::pdb::DbiModuleDescriptorBuilder *moduleDBI = nullptr;
151157
152 const coff_section *AddrsigSec = nullptr;
158 const coff_section *addrsigSec = nullptr;
153159
154160 // When using Microsoft precompiled headers, this is the PCH's key.
155161 // The same key is used by both the precompiled object, and objects using the
156162 // precompiled object. Any difference indicates out-of-date objects.
157 llvm::Optional<uint32_t> PCHSignature;
163 llvm::Optional<uint32_t> pchSignature;
164
165 // Whether this is an object file created from .res files.
166 bool isResourceObjFile = false;
167
168 // Whether this file was compiled with /hotpatch.
169 bool hotPatchable = false;
170
171 // Whether the object was already merged into the final PDB.
172 bool mergedIntoPDB = false;
173
174 // If the OBJ has a .debug$T stream, this tells how it will be handled.
175 TpiSource *debugTypesObj = nullptr;
176
177 // The .debug$T stream if there's one.
178 llvm::Optional<llvm::codeview::CVTypeArray> debugTypes;
158179
159180private:
181 const coff_section* getSection(uint32_t i);
182 const coff_section *getSection(COFFSymbolRef sym) {
183 return getSection(sym.getSectionNumber());
184 }
185
160186 void initializeChunks();
161187 void initializeSymbols();
188 void initializeFlags();
189 void initializeDependencies();
162190
163191 SectionChunk *
164 readSection(uint32_t SectionNumber,
165 const llvm::object::coff_aux_section_definition *Def,
166 StringRef LeaderName);
192 readSection(uint32_t sectionNumber,
193 const llvm::object::coff_aux_section_definition *def,
194 StringRef leaderName);
167195
168196 void readAssociativeDefinition(
169 COFFSymbolRef COFFSym,
170 const llvm::object::coff_aux_section_definition *Def);
197 COFFSymbolRef coffSym,
198 const llvm::object::coff_aux_section_definition *def);
171199
172200 void readAssociativeDefinition(
173 COFFSymbolRef COFFSym,
174 const llvm::object::coff_aux_section_definition *Def,
175 uint32_t ParentSection);
201 COFFSymbolRef coffSym,
202 const llvm::object::coff_aux_section_definition *def,
203 uint32_t parentSection);
176204
177205 void recordPrevailingSymbolForMingw(
178 COFFSymbolRef COFFSym,
179 llvm::DenseMap<StringRef, uint32_t> &PrevailingSectionMap);
206 COFFSymbolRef coffSym,
207 llvm::DenseMap<StringRef, uint32_t> &prevailingSectionMap);
180208
181209 void maybeAssociateSEHForMingw(
182 COFFSymbolRef Sym, const llvm::object::coff_aux_section_definition *Def,
183 const llvm::DenseMap<StringRef, uint32_t> &PrevailingSectionMap);
210 COFFSymbolRef sym, const llvm::object::coff_aux_section_definition *def,
211 const llvm::DenseMap<StringRef, uint32_t> &prevailingSectionMap);
212
213 // Given a new symbol Sym with comdat selection Selection, if the new
214 // symbol is not (yet) Prevailing and the existing comdat leader set to
215 // Leader, emits a diagnostic if the new symbol and its selection doesn't
216 // match the existing symbol and its selection. If either old or new
217 // symbol have selection IMAGE_COMDAT_SELECT_LARGEST, Sym might replace
218 // the existing leader. In that case, Prevailing is set to true.
219 void handleComdatSelection(COFFSymbolRef sym,
220 llvm::COFF::COMDATType &selection,
221 bool &prevailing, DefinedRegular *leader);
184222
185223 llvm::Optional<Symbol *>
186 createDefined(COFFSymbolRef Sym,
224 createDefined(COFFSymbolRef sym,
187225 std::vector<const llvm::object::coff_aux_section_definition *>
188 &ComdatDefs,
189 bool &PrevailingComdat);
190 Symbol *createRegular(COFFSymbolRef Sym);
191 Symbol *createUndefined(COFFSymbolRef Sym);
226 &comdatDefs,
227 bool &prevailingComdat);
228 Symbol *createRegular(COFFSymbolRef sym);
229 Symbol *createUndefined(COFFSymbolRef sym);
192230
193 std::unique_ptr<COFFObjectFile> COFFObj;
231 std::unique_ptr<COFFObjectFile> coffObj;
194232
195233 // List of all chunks defined by this file. This includes both section
196234 // chunks and non-section chunks for common symbols.
197 std::vector<Chunk *> Chunks;
235 std::vector<Chunk *> chunks;
198236
199237 // CodeView debug info sections.
200 std::vector<SectionChunk *> DebugChunks;
238 std::vector<SectionChunk *> debugChunks;
201239
202240 // Chunks containing symbol table indices of exception handlers. Only used for
203241 // 32-bit x86.
204 std::vector<SectionChunk *> SXDataChunks;
242 std::vector<SectionChunk *> sXDataChunks;
205243
206244 // Chunks containing symbol table indices of address taken symbols and longjmp
207245 // targets. These are not linked into the final binary when /guard:cf is set.
208 std::vector<SectionChunk *> GuardFidChunks;
209 std::vector<SectionChunk *> GuardLJmpChunks;
246 std::vector<SectionChunk *> guardFidChunks;
247 std::vector<SectionChunk *> guardLJmpChunks;
210248
211249 // This vector contains the same chunks as Chunks, but they are
212250 // indexed such that you can get a SectionChunk by section index.
213251 // Nonexistent section indices are filled with null pointers.
214252 // (Because section number is 1-based, the first slot is always a
215253 // null pointer.)
216 std::vector<SectionChunk *> SparseChunks;
254 std::vector<SectionChunk *> sparseChunks;
217255
218256 // This vector contains a list of all symbols defined or referenced by this
219257 // file. They are indexed such that you can get a Symbol by symbol
220258 // index. Nonexistent indices (which are occupied by auxiliary
221259 // symbols in the real symbol table) are filled with null pointers.
222 std::vector<Symbol *> Symbols;
260 std::vector<Symbol *> symbols;
223261};
224262
225263// This type represents import library members that contain DLL names
......@@ -227,23 +265,23 @@ private:
227265// for details about the format.
228266class ImportFile : public InputFile {
229267public:
230 explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind, M) {}
268 explicit ImportFile(MemoryBufferRef m) : InputFile(ImportKind, m) {}
231269
232 static bool classof(const InputFile *F) { return F->kind() == ImportKind; }
270 static bool classof(const InputFile *f) { return f->kind() == ImportKind; }
233271
234 static std::vector<ImportFile *> Instances;
272 static std::vector<ImportFile *> instances;
235273
236 Symbol *ImpSym = nullptr;
237 Symbol *ThunkSym = nullptr;
238 std::string DLLName;
274 Symbol *impSym = nullptr;
275 Symbol *thunkSym = nullptr;
276 std::string dllName;
239277
240278private:
241279 void parse() override;
242280
243281public:
244 StringRef ExternalName;
245 const coff_import_header *Hdr;
246 Chunk *Location = nullptr;
282 StringRef externalName;
283 const coff_import_header *hdr;
284 Chunk *location = nullptr;
247285
248286 // We want to eliminate dllimported symbols if no one actually refers them.
249287 // These "Live" bits are used to keep track of which import library members
......@@ -253,28 +291,31 @@ public:
253291 // symbols provided by this import library member. We also track whether the
254292 // imported symbol is used separately from whether the thunk is used in order
255293 // to avoid creating unnecessary thunks.
256 bool Live = !Config->DoGC;
257 bool ThunkLive = !Config->DoGC;
294 bool live = !config->doGC;
295 bool thunkLive = !config->doGC;
258296};
259297
260298// Used for LTO.
261299class BitcodeFile : public InputFile {
262300public:
263 explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {}
264 static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
265 ArrayRef<Symbol *> getSymbols() { return Symbols; }
301 BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
302 uint64_t offsetInArchive);
303 static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
304 ArrayRef<Symbol *> getSymbols() { return symbols; }
266305 MachineTypes getMachineType() override;
267 static std::vector<BitcodeFile *> Instances;
268 std::unique_ptr<llvm::lto::InputFile> Obj;
306 static std::vector<BitcodeFile *> instances;
307 std::unique_ptr<llvm::lto::InputFile> obj;
269308
270309private:
271310 void parse() override;
272311
273 std::vector<Symbol *> Symbols;
312 std::vector<Symbol *> symbols;
274313};
314
315std::string replaceThinLTOSuffix(StringRef path);
275316} // namespace coff
276317
277std::string toString(const coff::InputFile *File);
318std::string toString(const coff::InputFile *file);
278319} // namespace lld
279320
280321#endif
deps/lld/COFF/LTO.cpp+121-67
......@@ -1,9 +1,8 @@
11//===- LTO.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -11,6 +10,7 @@
1110#include "Config.h"
1211#include "InputFiles.h"
1312#include "Symbols.h"
13#include "lld/Common/Args.h"
1414#include "lld/Common/ErrorHandler.h"
1515#include "lld/Common/Strings.h"
1616#include "lld/Common/TargetOptionsCommandFlags.h"
......@@ -18,6 +18,7 @@
1818#include "llvm/ADT/SmallString.h"
1919#include "llvm/ADT/StringRef.h"
2020#include "llvm/ADT/Twine.h"
21#include "llvm/Bitcode/BitcodeWriter.h"
2122#include "llvm/IR/DiagnosticPrinter.h"
2223#include "llvm/LTO/Caching.h"
2324#include "llvm/LTO/Config.h"
......@@ -41,112 +42,165 @@ using namespace llvm::object;
4142using namespace lld;
4243using namespace lld::coff;
4344
44static std::unique_ptr<lto::LTO> createLTO() {
45 lto::Config C;
46 C.Options = InitTargetOptionsFromCodeGenFlags();
45// Creates an empty file to and returns a raw_fd_ostream to write to it.
46static std::unique_ptr<raw_fd_ostream> openFile(StringRef file) {
47 std::error_code ec;
48 auto ret =
49 llvm::make_unique<raw_fd_ostream>(file, ec, sys::fs::OpenFlags::F_None);
50 if (ec) {
51 error("cannot open " + file + ": " + ec.message());
52 return nullptr;
53 }
54 return ret;
55}
56
57static std::string getThinLTOOutputFile(StringRef path) {
58 return lto::getThinLTOOutputFile(path,
59 config->thinLTOPrefixReplace.first,
60 config->thinLTOPrefixReplace.second);
61}
62
63static lto::Config createConfig() {
64 lto::Config c;
65 c.Options = initTargetOptionsFromCodeGenFlags();
4766
4867 // Always emit a section per function/datum with LTO. LLVM LTO should get most
4968 // of the benefit of linker GC, but there are still opportunities for ICF.
50 C.Options.FunctionSections = true;
51 C.Options.DataSections = true;
69 c.Options.FunctionSections = true;
70 c.Options.DataSections = true;
5271
5372 // Use static reloc model on 32-bit x86 because it usually results in more
5473 // compact code, and because there are also known code generation bugs when
5574 // using the PIC model (see PR34306).
56 if (Config->Machine == COFF::IMAGE_FILE_MACHINE_I386)
57 C.RelocModel = Reloc::Static;
75 if (config->machine == COFF::IMAGE_FILE_MACHINE_I386)
76 c.RelocModel = Reloc::Static;
5877 else
59 C.RelocModel = Reloc::PIC_;
60 C.DisableVerify = true;
61 C.DiagHandler = diagnosticHandler;
62 C.OptLevel = Config->LTOO;
63 C.CPU = GetCPUStr();
64 C.MAttrs = GetMAttrs();
65
66 if (Config->SaveTemps)
67 checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".",
78 c.RelocModel = Reloc::PIC_;
79 c.DisableVerify = true;
80 c.DiagHandler = diagnosticHandler;
81 c.OptLevel = config->ltoo;
82 c.CPU = getCPUStr();
83 c.MAttrs = getMAttrs();
84 c.CGOptLevel = args::getCGOptLevel(config->ltoo);
85
86 if (config->saveTemps)
87 checkError(c.addSaveTemps(std::string(config->outputFile) + ".",
6888 /*UseInputModulePath*/ true));
69 lto::ThinBackend Backend;
70 if (Config->ThinLTOJobs != 0)
71 Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
72 return llvm::make_unique<lto::LTO>(std::move(C), Backend,
73 Config->LTOPartitions);
89 return c;
7490}
7591
76BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {}
92BitcodeCompiler::BitcodeCompiler() {
93 // Initialize indexFile.
94 if (!config->thinLTOIndexOnlyArg.empty())
95 indexFile = openFile(config->thinLTOIndexOnlyArg);
96
97 // Initialize ltoObj.
98 lto::ThinBackend backend;
99 if (config->thinLTOIndexOnly) {
100 auto OnIndexWrite = [&](StringRef S) { thinIndices.erase(S); };
101 backend = lto::createWriteIndexesThinBackend(
102 config->thinLTOPrefixReplace.first, config->thinLTOPrefixReplace.second,
103 config->thinLTOEmitImportsFiles, indexFile.get(), OnIndexWrite);
104 } else if (config->thinLTOJobs != 0) {
105 backend = lto::createInProcessThinBackend(config->thinLTOJobs);
106 }
107
108 ltoObj = llvm::make_unique<lto::LTO>(createConfig(), backend,
109 config->ltoPartitions);
110}
77111
78112BitcodeCompiler::~BitcodeCompiler() = default;
79113
80static void undefine(Symbol *S) { replaceSymbol<Undefined>(S, S->getName()); }
114static void undefine(Symbol *s) { replaceSymbol<Undefined>(s, s->getName()); }
115
116void BitcodeCompiler::add(BitcodeFile &f) {
117 lto::InputFile &obj = *f.obj;
118 unsigned symNum = 0;
119 std::vector<Symbol *> symBodies = f.getSymbols();
120 std::vector<lto::SymbolResolution> resols(symBodies.size());
81121
82void BitcodeCompiler::add(BitcodeFile &F) {
83 lto::InputFile &Obj = *F.Obj;
84 unsigned SymNum = 0;
85 std::vector<Symbol *> SymBodies = F.getSymbols();
86 std::vector<lto::SymbolResolution> Resols(SymBodies.size());
122 if (config->thinLTOIndexOnly)
123 thinIndices.insert(obj.getName());
87124
88125 // Provide a resolution to the LTO API for each symbol.
89 for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
90 Symbol *Sym = SymBodies[SymNum];
91 lto::SymbolResolution &R = Resols[SymNum];
92 ++SymNum;
126 for (const lto::InputFile::Symbol &objSym : obj.symbols()) {
127 Symbol *sym = symBodies[symNum];
128 lto::SymbolResolution &r = resols[symNum];
129 ++symNum;
93130
94131 // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
95132 // reports two symbols for module ASM defined. Without this check, lld
96133 // flags an undefined in IR with a definition in ASM as prevailing.
97134 // Once IRObjectFile is fixed to report only one symbol this hack can
98135 // be removed.
99 R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F;
100 R.VisibleToRegularObj = Sym->IsUsedInRegularObj;
101 if (R.Prevailing)
102 undefine(Sym);
136 r.Prevailing = !objSym.isUndefined() && sym->getFile() == &f;
137 r.VisibleToRegularObj = sym->isUsedInRegularObj;
138 if (r.Prevailing)
139 undefine(sym);
103140 }
104 checkError(LTOObj->add(std::move(F.Obj), Resols));
141 checkError(ltoObj->add(std::move(f.obj), resols));
105142}
106143
107144// Merge all the bitcode files we have seen, codegen the result
108145// and return the resulting objects.
109146std::vector<StringRef> BitcodeCompiler::compile() {
110 unsigned MaxTasks = LTOObj->getMaxTasks();
111 Buf.resize(MaxTasks);
112 Files.resize(MaxTasks);
147 unsigned maxTasks = ltoObj->getMaxTasks();
148 buf.resize(maxTasks);
149 files.resize(maxTasks);
113150
114151 // The /lldltocache option specifies the path to a directory in which to cache
115152 // native object files for ThinLTO incremental builds. If a path was
116153 // specified, configure LTO to use it as the cache directory.
117 lto::NativeObjectCache Cache;
118 if (!Config->LTOCache.empty())
119 Cache = check(lto::localCache(
120 Config->LTOCache, [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
121 Files[Task] = std::move(MB);
154 lto::NativeObjectCache cache;
155 if (!config->ltoCache.empty())
156 cache = check(lto::localCache(
157 config->ltoCache, [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
158 files[task] = std::move(mb);
122159 }));
123160
124 checkError(LTOObj->run(
125 [&](size_t Task) {
161 checkError(ltoObj->run(
162 [&](size_t task) {
126163 return llvm::make_unique<lto::NativeObjectStream>(
127 llvm::make_unique<raw_svector_ostream>(Buf[Task]));
164 llvm::make_unique<raw_svector_ostream>(buf[task]));
128165 },
129 Cache));
166 cache));
167
168 // Emit empty index files for non-indexed files
169 for (StringRef s : thinIndices) {
170 std::string path = getThinLTOOutputFile(s);
171 openFile(path + ".thinlto.bc");
172 if (config->thinLTOEmitImportsFiles)
173 openFile(path + ".imports");
174 }
175
176 // ThinLTO with index only option is required to generate only the index
177 // files. After that, we exit from linker and ThinLTO backend runs in a
178 // distributed environment.
179 if (config->thinLTOIndexOnly) {
180 if (indexFile)
181 indexFile->close();
182 return {};
183 }
130184
131 if (!Config->LTOCache.empty())
132 pruneCache(Config->LTOCache, Config->LTOCachePolicy);
185 if (!config->ltoCache.empty())
186 pruneCache(config->ltoCache, config->ltoCachePolicy);
133187
134 std::vector<StringRef> Ret;
135 for (unsigned I = 0; I != MaxTasks; ++I) {
136 if (Buf[I].empty())
188 std::vector<StringRef> ret;
189 for (unsigned i = 0; i != maxTasks; ++i) {
190 if (buf[i].empty())
137191 continue;
138 if (Config->SaveTemps) {
139 if (I == 0)
140 saveBuffer(Buf[I], Config->OutputFile + ".lto.obj");
192 if (config->saveTemps) {
193 if (i == 0)
194 saveBuffer(buf[i], config->outputFile + ".lto.obj");
141195 else
142 saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.obj");
196 saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.obj");
143197 }
144 Ret.emplace_back(Buf[I].data(), Buf[I].size());
198 ret.emplace_back(buf[i].data(), buf[i].size());
145199 }
146200
147 for (std::unique_ptr<MemoryBuffer> &File : Files)
148 if (File)
149 Ret.push_back(File->getBuffer());
201 for (std::unique_ptr<MemoryBuffer> &file : files)
202 if (file)
203 ret.push_back(file->getBuffer());
150204
151 return Ret;
205 return ret;
152206}
deps/lld/COFF/LTO.h+11-8
......@@ -1,9 +1,8 @@
11//===- LTO.h ----------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -22,7 +21,9 @@
2221#define LLD_COFF_LTO_H
2322
2423#include "lld/Common/LLVM.h"
24#include "llvm/ADT/DenseSet.h"
2525#include "llvm/ADT/SmallString.h"
26#include "llvm/Support/raw_ostream.h"
2627#include <memory>
2728#include <vector>
2829
......@@ -43,13 +44,15 @@ public:
4344 BitcodeCompiler();
4445 ~BitcodeCompiler();
4546
46 void add(BitcodeFile &F);
47 void add(BitcodeFile &f);
4748 std::vector<StringRef> compile();
4849
4950private:
50 std::unique_ptr<llvm::lto::LTO> LTOObj;
51 std::vector<SmallString<0>> Buf;
52 std::vector<std::unique_ptr<MemoryBuffer>> Files;
51 std::unique_ptr<llvm::lto::LTO> ltoObj;
52 std::vector<SmallString<0>> buf;
53 std::vector<std::unique_ptr<MemoryBuffer>> files;
54 std::unique_ptr<llvm::raw_fd_ostream> indexFile;
55 llvm::DenseSet<StringRef> thinIndices;
5356};
5457}
5558}
deps/lld/COFF/MapFile.cpp+57-58
......@@ -1,9 +1,8 @@
11//===- MapFile.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -24,7 +23,7 @@
2423#include "Symbols.h"
2524#include "Writer.h"
2625#include "lld/Common/ErrorHandler.h"
27#include "llvm/Support/Parallel.h"
26#include "lld/Common/Threads.h"
2827#include "llvm/Support/raw_ostream.h"
2928
3029using namespace llvm;
......@@ -33,93 +32,93 @@ using namespace llvm::object;
3332using namespace lld;
3433using namespace lld::coff;
3534
36typedef DenseMap<const SectionChunk *, SmallVector<DefinedRegular *, 4>>
37 SymbolMapTy;
35using SymbolMapTy =
36 DenseMap<const SectionChunk *, SmallVector<DefinedRegular *, 4>>;
3837
39static const std::string Indent8 = " "; // 8 spaces
40static const std::string Indent16 = " "; // 16 spaces
38static const std::string indent8 = " "; // 8 spaces
39static const std::string indent16 = " "; // 16 spaces
4140
4241// Print out the first three columns of a line.
43static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
44 uint64_t Align) {
45 OS << format("%08llx %08llx %5lld ", Addr, Size, Align);
42static void writeHeader(raw_ostream &os, uint64_t addr, uint64_t size,
43 uint64_t align) {
44 os << format("%08llx %08llx %5lld ", addr, size, align);
4645}
4746
4847// Returns a list of all symbols that we want to print out.
4948static std::vector<DefinedRegular *> getSymbols() {
50 std::vector<DefinedRegular *> V;
51 for (ObjFile *File : ObjFile::Instances)
52 for (Symbol *B : File->getSymbols())
53 if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
54 if (Sym && !Sym->getCOFFSymbol().isSectionDefinition())
55 V.push_back(Sym);
56 return V;
49 std::vector<DefinedRegular *> v;
50 for (ObjFile *file : ObjFile::instances)
51 for (Symbol *b : file->getSymbols())
52 if (auto *sym = dyn_cast_or_null<DefinedRegular>(b))
53 if (sym && !sym->getCOFFSymbol().isSectionDefinition())
54 v.push_back(sym);
55 return v;
5756}
5857
5958// Returns a map from sections to their symbols.
60static SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> Syms) {
61 SymbolMapTy Ret;
62 for (DefinedRegular *S : Syms)
63 Ret[S->getChunk()].push_back(S);
59static SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> syms) {
60 SymbolMapTy ret;
61 for (DefinedRegular *s : syms)
62 ret[s->getChunk()].push_back(s);
6463
6564 // Sort symbols by address.
66 for (auto &It : Ret) {
67 SmallVectorImpl<DefinedRegular *> &V = It.second;
68 std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) {
69 return A->getRVA() < B->getRVA();
65 for (auto &it : ret) {
66 SmallVectorImpl<DefinedRegular *> &v = it.second;
67 std::sort(v.begin(), v.end(), [](DefinedRegular *a, DefinedRegular *b) {
68 return a->getRVA() < b->getRVA();
7069 });
7170 }
72 return Ret;
71 return ret;
7372}
7473
7574// Construct a map from symbols to their stringified representations.
7675static DenseMap<DefinedRegular *, std::string>
77getSymbolStrings(ArrayRef<DefinedRegular *> Syms) {
78 std::vector<std::string> Str(Syms.size());
79 for_each_n(parallel::par, (size_t)0, Syms.size(), [&](size_t I) {
80 raw_string_ostream OS(Str[I]);
81 writeHeader(OS, Syms[I]->getRVA(), 0, 0);
82 OS << Indent16 << toString(*Syms[I]);
76getSymbolStrings(ArrayRef<DefinedRegular *> syms) {
77 std::vector<std::string> str(syms.size());
78 parallelForEachN((size_t)0, syms.size(), [&](size_t i) {
79 raw_string_ostream os(str[i]);
80 writeHeader(os, syms[i]->getRVA(), 0, 0);
81 os << indent16 << toString(*syms[i]);
8382 });
8483
85 DenseMap<DefinedRegular *, std::string> Ret;
86 for (size_t I = 0, E = Syms.size(); I < E; ++I)
87 Ret[Syms[I]] = std::move(Str[I]);
88 return Ret;
84 DenseMap<DefinedRegular *, std::string> ret;
85 for (size_t i = 0, e = syms.size(); i < e; ++i)
86 ret[syms[i]] = std::move(str[i]);
87 return ret;
8988}
9089
91void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) {
92 if (Config->MapFile.empty())
90void coff::writeMapFile(ArrayRef<OutputSection *> outputSections) {
91 if (config->mapFile.empty())
9392 return;
9493
95 std::error_code EC;
96 raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
97 if (EC)
98 fatal("cannot open " + Config->MapFile + ": " + EC.message());
94 std::error_code ec;
95 raw_fd_ostream os(config->mapFile, ec, sys::fs::F_None);
96 if (ec)
97 fatal("cannot open " + config->mapFile + ": " + ec.message());
9998
10099 // Collect symbol info that we want to print out.
101 std::vector<DefinedRegular *> Syms = getSymbols();
102 SymbolMapTy SectionSyms = getSectionSyms(Syms);
103 DenseMap<DefinedRegular *, std::string> SymStr = getSymbolStrings(Syms);
100 std::vector<DefinedRegular *> syms = getSymbols();
101 SymbolMapTy sectionSyms = getSectionSyms(syms);
102 DenseMap<DefinedRegular *, std::string> symStr = getSymbolStrings(syms);
104103
105104 // Print out the header line.
106 OS << "Address Size Align Out In Symbol\n";
105 os << "Address Size Align Out In Symbol\n";
107106
108107 // Print out file contents.
109 for (OutputSection *Sec : OutputSections) {
110 writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize);
111 OS << Sec->Name << '\n';
108 for (OutputSection *sec : outputSections) {
109 writeHeader(os, sec->getRVA(), sec->getVirtualSize(), /*align=*/pageSize);
110 os << sec->name << '\n';
112111
113 for (Chunk *C : Sec->Chunks) {
114 auto *SC = dyn_cast<SectionChunk>(C);
115 if (!SC)
112 for (Chunk *c : sec->chunks) {
113 auto *sc = dyn_cast<SectionChunk>(c);
114 if (!sc)
116115 continue;
117116
118 writeHeader(OS, SC->getRVA(), SC->getSize(), SC->Alignment);
119 OS << Indent8 << SC->File->getName() << ":(" << SC->getSectionName()
117 writeHeader(os, sc->getRVA(), sc->getSize(), sc->getAlignment());
118 os << indent8 << sc->file->getName() << ":(" << sc->getSectionName()
120119 << ")\n";
121 for (DefinedRegular *Sym : SectionSyms[SC])
122 OS << SymStr[Sym] << '\n';
120 for (DefinedRegular *sym : sectionSyms[sc])
121 os << symStr[sym] << '\n';
123122 }
124123 }
125124}
deps/lld/COFF/MapFile.h+4-5
......@@ -1,9 +1,8 @@
11//===- MapFile.h ------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -15,7 +14,7 @@
1514namespace lld {
1615namespace coff {
1716class OutputSection;
18void writeMapFile(llvm::ArrayRef<OutputSection *> OutputSections);
17void writeMapFile(llvm::ArrayRef<OutputSection *> outputSections);
1918}
2019}
2120
deps/lld/COFF/MarkLive.cpp+32-33
......@@ -1,9 +1,8 @@
11//===- MarkLive.cpp -------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -16,57 +15,57 @@
1615namespace lld {
1716namespace coff {
1817
19static Timer GCTimer("GC", Timer::root());
18static Timer gctimer("GC", Timer::root());
2019
2120// Set live bit on for each reachable chunk. Unmarked (unreachable)
2221// COMDAT chunks will be ignored by Writer, so they will be excluded
2322// from the final output.
24void markLive(ArrayRef<Chunk *> Chunks) {
25 ScopedTimer T(GCTimer);
23void markLive(ArrayRef<Chunk *> chunks) {
24 ScopedTimer t(gctimer);
2625
2726 // We build up a worklist of sections which have been marked as live. We only
2827 // push into the worklist when we discover an unmarked section, and we mark
2928 // as we push, so sections never appear twice in the list.
30 SmallVector<SectionChunk *, 256> Worklist;
29 SmallVector<SectionChunk *, 256> worklist;
3130
3231 // COMDAT section chunks are dead by default. Add non-COMDAT chunks.
33 for (Chunk *C : Chunks)
34 if (auto *SC = dyn_cast<SectionChunk>(C))
35 if (SC->Live)
36 Worklist.push_back(SC);
32 for (Chunk *c : chunks)
33 if (auto *sc = dyn_cast<SectionChunk>(c))
34 if (sc->live)
35 worklist.push_back(sc);
3736
38 auto Enqueue = [&](SectionChunk *C) {
39 if (C->Live)
37 auto enqueue = [&](SectionChunk *c) {
38 if (c->live)
4039 return;
41 C->Live = true;
42 Worklist.push_back(C);
40 c->live = true;
41 worklist.push_back(c);
4342 };
4443
45 auto AddSym = [&](Symbol *B) {
46 if (auto *Sym = dyn_cast<DefinedRegular>(B))
47 Enqueue(Sym->getChunk());
48 else if (auto *Sym = dyn_cast<DefinedImportData>(B))
49 Sym->File->Live = true;
50 else if (auto *Sym = dyn_cast<DefinedImportThunk>(B))
51 Sym->WrappedSym->File->Live = Sym->WrappedSym->File->ThunkLive = true;
44 auto addSym = [&](Symbol *b) {
45 if (auto *sym = dyn_cast<DefinedRegular>(b))
46 enqueue(sym->getChunk());
47 else if (auto *sym = dyn_cast<DefinedImportData>(b))
48 sym->file->live = true;
49 else if (auto *sym = dyn_cast<DefinedImportThunk>(b))
50 sym->wrappedSym->file->live = sym->wrappedSym->file->thunkLive = true;
5251 };
5352
5453 // Add GC root chunks.
55 for (Symbol *B : Config->GCRoot)
56 AddSym(B);
54 for (Symbol *b : config->gcroot)
55 addSym(b);
5756
58 while (!Worklist.empty()) {
59 SectionChunk *SC = Worklist.pop_back_val();
60 assert(SC->Live && "We mark as live when pushing onto the worklist!");
57 while (!worklist.empty()) {
58 SectionChunk *sc = worklist.pop_back_val();
59 assert(sc->live && "We mark as live when pushing onto the worklist!");
6160
6261 // Mark all symbols listed in the relocation table for this section.
63 for (Symbol *B : SC->symbols())
64 if (B)
65 AddSym(B);
62 for (Symbol *b : sc->symbols())
63 if (b)
64 addSym(b);
6665
6766 // Mark associative sections if any.
68 for (SectionChunk *C : SC->children())
69 Enqueue(C);
67 for (SectionChunk &c : sc->children())
68 enqueue(&c);
7069 }
7170}
7271
deps/lld/COFF/MarkLive.h+6-5
......@@ -1,9 +1,8 @@
11//===- MarkLive.h -----------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -16,7 +15,9 @@
1615namespace lld {
1716namespace coff {
1817
19void markLive(ArrayRef<Chunk *> Chunks);
18class Chunk;
19
20void markLive(ArrayRef<Chunk *> chunks);
2021
2122} // namespace coff
2223} // namespace lld
deps/lld/COFF/MinGW.cpp+75-85
......@@ -1,9 +1,8 @@
11//===- MinGW.cpp ----------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -19,8 +18,35 @@ using namespace lld::coff;
1918using namespace llvm;
2019using namespace llvm::COFF;
2120
22void AutoExporter::initSymbolExcludes() {
23 ExcludeSymbolPrefixes = {
21AutoExporter::AutoExporter() {
22 excludeLibs = {
23 "libgcc",
24 "libgcc_s",
25 "libstdc++",
26 "libmingw32",
27 "libmingwex",
28 "libg2c",
29 "libsupc++",
30 "libobjc",
31 "libgcj",
32 "libclang_rt.builtins",
33 "libclang_rt.builtins-aarch64",
34 "libclang_rt.builtins-arm",
35 "libclang_rt.builtins-i386",
36 "libclang_rt.builtins-x86_64",
37 "libc++",
38 "libc++abi",
39 "libunwind",
40 "libmsvcrt",
41 "libucrtbase",
42 };
43
44 excludeObjects = {
45 "crt0.o", "crt1.o", "crt1u.o", "crt2.o", "crt2u.o", "dllcrt1.o",
46 "dllcrt2.o", "gcrt0.o", "gcrt1.o", "gcrt2.o", "crtbegin.o", "crtend.o",
47 };
48
49 excludeSymbolPrefixes = {
2450 // Import symbols
2551 "__imp_",
2652 "__IMPORT_DESCRIPTOR_",
......@@ -32,12 +58,14 @@ void AutoExporter::initSymbolExcludes() {
3258 // Artifical symbols such as .refptr
3359 ".",
3460 };
35 ExcludeSymbolSuffixes = {
61
62 excludeSymbolSuffixes = {
3663 "_iname",
3764 "_NULL_THUNK_DATA",
3865 };
39 if (Config->Machine == I386) {
40 ExcludeSymbols = {
66
67 if (config->machine == I386) {
68 excludeSymbols = {
4169 "__NULL_IMPORT_DESCRIPTOR",
4270 "__pei386_runtime_relocator",
4371 "_do_pseudo_reloc",
......@@ -52,9 +80,9 @@ void AutoExporter::initSymbolExcludes() {
5280 "_DllEntryPoint@12",
5381 "_DllMainCRTStartup@12",
5482 };
55 ExcludeSymbolPrefixes.insert("__head_");
83 excludeSymbolPrefixes.insert("__head_");
5684 } else {
57 ExcludeSymbols = {
85 excludeSymbols = {
5886 "__NULL_IMPORT_DESCRIPTOR",
5987 "_pei386_runtime_relocator",
6088 "do_pseudo_reloc",
......@@ -69,108 +97,70 @@ void AutoExporter::initSymbolExcludes() {
6997 "DllEntryPoint",
7098 "DllMainCRTStartup",
7199 };
72 ExcludeSymbolPrefixes.insert("_head_");
100 excludeSymbolPrefixes.insert("_head_");
73101 }
74102}
75103
76AutoExporter::AutoExporter() {
77 ExcludeLibs = {
78 "libgcc",
79 "libgcc_s",
80 "libstdc++",
81 "libmingw32",
82 "libmingwex",
83 "libg2c",
84 "libsupc++",
85 "libobjc",
86 "libgcj",
87 "libclang_rt.builtins",
88 "libclang_rt.builtins-aarch64",
89 "libclang_rt.builtins-arm",
90 "libclang_rt.builtins-i386",
91 "libclang_rt.builtins-x86_64",
92 "libc++",
93 "libc++abi",
94 "libunwind",
95 "libmsvcrt",
96 "libucrtbase",
97 };
98 ExcludeObjects = {
99 "crt0.o",
100 "crt1.o",
101 "crt1u.o",
102 "crt2.o",
103 "crt2u.o",
104 "dllcrt1.o",
105 "dllcrt2.o",
106 "gcrt0.o",
107 "gcrt1.o",
108 "gcrt2.o",
109 "crtbegin.o",
110 "crtend.o",
111 };
112}
113
114void AutoExporter::addWholeArchive(StringRef Path) {
115 StringRef LibName = sys::path::filename(Path);
104void AutoExporter::addWholeArchive(StringRef path) {
105 StringRef libName = sys::path::filename(path);
116106 // Drop the file extension, to match the processing below.
117 LibName = LibName.substr(0, LibName.rfind('.'));
118 ExcludeLibs.erase(LibName);
107 libName = libName.substr(0, libName.rfind('.'));
108 excludeLibs.erase(libName);
119109}
120110
121bool AutoExporter::shouldExport(Defined *Sym) const {
122 if (!Sym || !Sym->isLive() || !Sym->getChunk())
111bool AutoExporter::shouldExport(Defined *sym) const {
112 if (!sym || !sym->isLive() || !sym->getChunk())
123113 return false;
124114
125115 // Only allow the symbol kinds that make sense to export; in particular,
126116 // disallow import symbols.
127 if (!isa<DefinedRegular>(Sym) && !isa<DefinedCommon>(Sym))
117 if (!isa<DefinedRegular>(sym) && !isa<DefinedCommon>(sym))
128118 return false;
129 if (ExcludeSymbols.count(Sym->getName()))
119 if (excludeSymbols.count(sym->getName()))
130120 return false;
131121
132 for (StringRef Prefix : ExcludeSymbolPrefixes.keys())
133 if (Sym->getName().startswith(Prefix))
122 for (StringRef prefix : excludeSymbolPrefixes.keys())
123 if (sym->getName().startswith(prefix))
134124 return false;
135 for (StringRef Suffix : ExcludeSymbolSuffixes.keys())
136 if (Sym->getName().endswith(Suffix))
125 for (StringRef suffix : excludeSymbolSuffixes.keys())
126 if (sym->getName().endswith(suffix))
137127 return false;
138128
139129 // If a corresponding __imp_ symbol exists and is defined, don't export it.
140 if (Symtab->find(("__imp_" + Sym->getName()).str()))
130 if (symtab->find(("__imp_" + sym->getName()).str()))
141131 return false;
142132
143133 // Check that file is non-null before dereferencing it, symbols not
144134 // originating in regular object files probably shouldn't be exported.
145 if (!Sym->getFile())
135 if (!sym->getFile())
146136 return false;
147137
148 StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
138 StringRef libName = sys::path::filename(sym->getFile()->parentName);
149139
150140 // Drop the file extension.
151 LibName = LibName.substr(0, LibName.rfind('.'));
152 if (!LibName.empty())
153 return !ExcludeLibs.count(LibName);
141 libName = libName.substr(0, libName.rfind('.'));
142 if (!libName.empty())
143 return !excludeLibs.count(libName);
154144
155 StringRef FileName = sys::path::filename(Sym->getFile()->getName());
156 return !ExcludeObjects.count(FileName);
145 StringRef fileName = sys::path::filename(sym->getFile()->getName());
146 return !excludeObjects.count(fileName);
157147}
158148
159void coff::writeDefFile(StringRef Name) {
160 std::error_code EC;
161 raw_fd_ostream OS(Name, EC, sys::fs::F_None);
162 if (EC)
163 fatal("cannot open " + Name + ": " + EC.message());
164
165 OS << "EXPORTS\n";
166 for (Export &E : Config->Exports) {
167 OS << " " << E.ExportName << " "
168 << "@" << E.Ordinal;
169 if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) {
170 if (Def && Def->getChunk() &&
171 !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
172 OS << " DATA";
149void coff::writeDefFile(StringRef name) {
150 std::error_code ec;
151 raw_fd_ostream os(name, ec, sys::fs::F_None);
152 if (ec)
153 fatal("cannot open " + name + ": " + ec.message());
154
155 os << "EXPORTS\n";
156 for (Export &e : config->exports) {
157 os << " " << e.exportName << " "
158 << "@" << e.ordinal;
159 if (auto *def = dyn_cast_or_null<Defined>(e.sym)) {
160 if (def && def->getChunk() &&
161 !(def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
162 os << " DATA";
173163 }
174 OS << "\n";
164 os << "\n";
175165 }
176166}
deps/lld/COFF/MinGW.h+11-14
......@@ -1,9 +1,8 @@
11//===- MinGW.h --------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -23,20 +22,18 @@ class AutoExporter {
2322public:
2423 AutoExporter();
2524
26 void initSymbolExcludes();
27
28 void addWholeArchive(StringRef Path);
25 void addWholeArchive(StringRef path);
2926
30 llvm::StringSet<> ExcludeSymbols;
31 llvm::StringSet<> ExcludeSymbolPrefixes;
32 llvm::StringSet<> ExcludeSymbolSuffixes;
33 llvm::StringSet<> ExcludeLibs;
34 llvm::StringSet<> ExcludeObjects;
27 llvm::StringSet<> excludeSymbols;
28 llvm::StringSet<> excludeSymbolPrefixes;
29 llvm::StringSet<> excludeSymbolSuffixes;
30 llvm::StringSet<> excludeLibs;
31 llvm::StringSet<> excludeObjects;
3532
36 bool shouldExport(Defined *Sym) const;
33 bool shouldExport(Defined *sym) const;
3734};
3835
39void writeDefFile(StringRef Name);
36void writeDefFile(StringRef name);
4037
4138} // namespace coff
4239} // namespace lld
deps/lld/COFF/Options.td+48-17
......@@ -3,11 +3,11 @@ include "llvm/Option/OptParser.td"
33// link.exe accepts options starting with either a dash or a slash.
44
55// Flag that takes no arguments.
6class F<string name> : Flag<["/", "-", "-?"], name>;
6class F<string name> : Flag<["/", "-", "/?", "-?"], name>;
77
88// Flag that takes one argument after ":".
99class P<string name, string help> :
10 Joined<["/", "-", "-?"], name#":">, HelpText<help>;
10 Joined<["/", "-", "/?", "-?"], name#":">, HelpText<help>;
1111
1212// Boolean flag which can be suffixed by ":no". Using it unsuffixed turns the
1313// flag on and using it suffixed by ":no" turns it off.
......@@ -32,6 +32,9 @@ def errorlimit : P<"errorlimit",
3232def export : P<"export", "Export a function">;
3333// No help text because /failifmismatch is not intended to be used by the user.
3434def failifmismatch : P<"failifmismatch", "">;
35def filealign : P<"filealign", "Section alignment in the output file">;
36def functionpadmin : F<"functionpadmin">;
37def functionpadmin_opt : P<"functionpadmin", "Prepares an image for hotpatching">;
3538def guard : P<"guard", "Control flow guard">;
3639def heap : P<"heap", "Size of the heap">;
3740def ignore : P<"ignore", "Specify warning codes to ignore">;
......@@ -64,7 +67,8 @@ def timestamp : P<"timestamp", "Specify the PE header timestamp">;
6467def version : P<"version", "Specify a version number in the PE header">;
6568def wholearchive_file : P<"wholearchive", "Include all object files from this archive">;
6669
67def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>;
70def disallowlib : Joined<["/", "-", "/?", "-?"], "disallowlib:">,
71 Alias<nodefaultlib>;
6872
6973def manifest : F<"manifest">, HelpText<"Create .manifest file">;
7074def manifest_colon : P<
......@@ -82,11 +86,11 @@ def manifestinput : P<
8286// We cannot use multiclass P because class name "incl" is different
8387// from its command line option name. We do this because "include" is
8488// a reserved keyword in tablegen.
85def incl : Joined<["/", "-"], "include:">,
89def incl : Joined<["/", "-", "/?", "-?"], "include:">,
8690 HelpText<"Force symbol to be added to symbol table as undefined one">;
8791
8892// "def" is also a keyword.
89def deffile : Joined<["/", "-"], "def:">,
93def deffile : Joined<["/", "-", "/?", "-?"], "def:">,
9094 HelpText<"Use module-definition file">;
9195
9296def debug : F<"debug">, HelpText<"Embed a symbol table in the image">;
......@@ -101,8 +105,12 @@ def noentry : F<"noentry">,
101105def profile : F<"profile">;
102106def repro : F<"Brepro">,
103107 HelpText<"Use a hash of the executable as the PE header timestamp">;
104def swaprun_cd : F<"swaprun:cd">;
105def swaprun_net : F<"swaprun:net">;
108def swaprun : P<"swaprun",
109 "Comma-separated list of 'cd' or 'net'">;
110def swaprun_cd : F<"swaprun:cd">, Alias<swaprun>, AliasArgs<["cd"]>,
111 HelpText<"Make loader run output binary from swap instead of from CD">;
112def swaprun_net : F<"swaprun:net">, Alias<swaprun>, AliasArgs<["net"]>,
113 HelpText<"Make loader run output binary from swap instead of from network">;
106114def verbose : F<"verbose">;
107115def wholearchive_flag : F<"wholearchive">;
108116
......@@ -112,6 +120,8 @@ def force_unresolved : F<"force:unresolved">,
112120 HelpText<"Allow undefined symbols when creating executables">;
113121def force_multiple : F<"force:multiple">,
114122 HelpText<"Allow multiply defined symbols when creating executables">;
123def force_multipleres : F<"force:multipleres">,
124 HelpText<"Allow multiply defined resources when creating executables">;
115125defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">;
116126
117127defm allowbind : B<"allowbind", "Enable DLL binding (default)",
......@@ -147,37 +157,58 @@ defm tsaware : B<"tsaware",
147157 "Create non-Terminal Server aware executable">;
148158
149159def help : F<"help">;
150def help_q : Flag<["/?", "-?"], "">, Alias<help>;
160
161// /?? and -?? must be before /? and -? to not confuse lib/Options.
162def help_q : Flag<["/??", "-??", "/?", "-?"], "">, Alias<help>;
151163
152164// LLD extensions
165def exclude_all_symbols : F<"exclude-all-symbols">;
153166def export_all_symbols : F<"export-all-symbols">;
167defm demangle : B<"demangle",
168 "Demangle symbols in output (default)",
169 "Do not demangle symbols in output">;
170def include_optional : Joined<["/", "-", "/?", "-?"], "includeoptional:">,
171 HelpText<"Add symbol as undefined, but allow it to remain undefined">;
154172def kill_at : F<"kill-at">;
155173def lldmingw : F<"lldmingw">;
156def output_def : Joined<["/", "-"], "output-def:">;
174def output_def : Joined<["/", "-", "/?", "-?"], "output-def:">;
157175def pdb_source_path : P<"pdbsourcepath",
158176 "Base path used to make relative source file path absolute in PDB">;
159177def rsp_quoting : Joined<["--"], "rsp-quoting=">,
160178 HelpText<"Quoting style for response files, 'windows' (default) or 'posix'">;
179def thinlto_emit_imports_files :
180 F<"thinlto-emit-imports-files">,
181 HelpText<"Emit .imports files with -thinlto-index-only">;
182def thinlto_index_only :
183 F<"thinlto-index-only">,
184 HelpText<"Instead of linking, emit ThinLTO index files">;
185def thinlto_index_only_arg : P<
186 "thinlto-index-only",
187 "-thinlto-index-only and also write native module names to file">;
188def thinlto_object_suffix_replace : P<
189 "thinlto-object-suffix-replace",
190 "'old;new' replace old suffix with new suffix in ThinLTO index">;
191def thinlto_prefix_replace: P<
192 "thinlto-prefix-replace",
193 "'old;new' replace old prefix with new prefix in ThinLTO outputs">;
161194def dash_dash_version : Flag<["--"], "version">,
162195 HelpText<"Print version information">;
196defm threads: B<"threads",
197 "Run the linker multi-threaded (default)",
198 "Do not run the linker multi-threaded">;
163199
164200// Flags for debugging
165201def lldmap : F<"lldmap">;
166def lldmap_file : Joined<["/", "-"], "lldmap:">;
202def lldmap_file : Joined<["/", "-", "/?", "-?"], "lldmap:">;
167203def show_timing : F<"time">;
204def summary : F<"summary">;
168205
169206//==============================================================================
170207// The flags below do nothing. They are defined only for link.exe compatibility.
171208//==============================================================================
172209
173class QF<string name> : Joined<["/", "-", "-?"], name#":">;
210class QF<string name> : Joined<["/", "-", "/?", "-?"], name#":">;
174211
175multiclass QB<string name> {
176 def "" : F<name>;
177 def _no : F<name#":no">;
178}
179
180def functionpadmin : F<"functionpadmin">;
181212def ignoreidl : F<"ignoreidl">;
182213def nologo : F<"nologo">;
183214def throwingnew : F<"throwingnew">;
deps/lld/COFF/PDB.cpp+1046-981
......@@ -1,21 +1,23 @@
11//===- PDB.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
109#include "PDB.h"
1110#include "Chunks.h"
1211#include "Config.h"
12#include "DebugTypes.h"
1313#include "Driver.h"
1414#include "SymbolTable.h"
1515#include "Symbols.h"
16#include "TypeMerger.h"
1617#include "Writer.h"
1718#include "lld/Common/ErrorHandler.h"
1819#include "lld/Common/Timer.h"
20#include "lld/Common/Threads.h"
1921#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
2022#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
2123#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
......@@ -53,7 +55,6 @@
5355#include "llvm/Support/Errc.h"
5456#include "llvm/Support/FormatVariadic.h"
5557#include "llvm/Support/JamCRC.h"
56#include "llvm/Support/Parallel.h"
5758#include "llvm/Support/Path.h"
5859#include "llvm/Support/ScopedPrinter.h"
5960#include <memory>
......@@ -65,44 +66,34 @@ using namespace llvm::codeview;
6566
6667using llvm::object::coff_section;
6768
68static ExitOnError ExitOnErr;
69static ExitOnError exitOnErr;
6970
70static Timer TotalPdbLinkTimer("PDB Emission (Cumulative)", Timer::root());
71static Timer totalPdbLinkTimer("PDB Emission (Cumulative)", Timer::root());
7172
72static Timer AddObjectsTimer("Add Objects", TotalPdbLinkTimer);
73static Timer TypeMergingTimer("Type Merging", AddObjectsTimer);
74static Timer SymbolMergingTimer("Symbol Merging", AddObjectsTimer);
75static Timer GlobalsLayoutTimer("Globals Stream Layout", TotalPdbLinkTimer);
76static Timer TpiStreamLayoutTimer("TPI Stream Layout", TotalPdbLinkTimer);
77static Timer DiskCommitTimer("Commit to Disk", TotalPdbLinkTimer);
73static Timer addObjectsTimer("Add Objects", totalPdbLinkTimer);
74static Timer typeMergingTimer("Type Merging", addObjectsTimer);
75static Timer symbolMergingTimer("Symbol Merging", addObjectsTimer);
76static Timer globalsLayoutTimer("Globals Stream Layout", totalPdbLinkTimer);
77static Timer tpiStreamLayoutTimer("TPI Stream Layout", totalPdbLinkTimer);
78static Timer diskCommitTimer("Commit to Disk", totalPdbLinkTimer);
7879
7980namespace {
80/// Map from type index and item index in a type server PDB to the
81/// corresponding index in the destination PDB.
82struct CVIndexMap {
83 SmallVector<TypeIndex, 0> TPIMap;
84 SmallVector<TypeIndex, 0> IPIMap;
85 bool IsTypeServerMap = false;
86 bool IsPrecompiledTypeMap = false;
87};
88
8981class DebugSHandler;
9082
9183class PDBLinker {
9284 friend DebugSHandler;
9385
9486public:
95 PDBLinker(SymbolTable *Symtab)
96 : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc),
97 IDTable(Alloc), GlobalTypeTable(Alloc), GlobalIDTable(Alloc) {
87 PDBLinker(SymbolTable *symtab)
88 : alloc(), symtab(symtab), builder(alloc), tMerger(alloc) {
9889 // This isn't strictly necessary, but link.exe usually puts an empty string
9990 // as the first "valid" string in the string table, so we do the same in
10091 // order to maintain as much byte-for-byte compatibility as possible.
101 PDBStrTab.insert("");
92 pdbStrTab.insert("");
10293 }
10394
10495 /// Emit the basic PDB structure: initial streams, headers, etc.
105 void initialize(llvm::codeview::DebugInfo *BuildId);
96 void initialize(llvm::codeview::DebugInfo *buildId);
10697
10798 /// Add natvis files specified on the command line.
10899 void addNatvisFiles();
......@@ -110,10 +101,13 @@ public:
110101 /// Link CodeView from each object file in the symbol table into the PDB.
111102 void addObjectsToPDB();
112103
104 /// Link info for each import file in the symbol table into the PDB.
105 void addImportFilesToPDB(ArrayRef<OutputSection *> outputSections);
106
113107 /// Link CodeView from a single object file into the target (output) PDB.
114108 /// When a precompiled headers object is linked, its TPI map might be provided
115109 /// externally.
116 void addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap = nullptr);
110 void addObjFile(ObjFile *file, CVIndexMap *externIndexMap = nullptr);
117111
118112 /// Produce a mapping from the type and item indices used in the object
119113 /// file to those in the destination PDB.
......@@ -125,20 +119,17 @@ public:
125119 ///
126120 /// If the object does not use a type server PDB (compiled with /Z7), we merge
127121 /// all the type and item records from the .debug$S stream and fill in the
128 /// caller-provided ObjectIndexMap.
129 Expected<const CVIndexMap &> mergeDebugT(ObjFile *File,
130 CVIndexMap *ObjectIndexMap);
122 /// caller-provided objectIndexMap.
123 Expected<const CVIndexMap &> mergeDebugT(ObjFile *file,
124 CVIndexMap *objectIndexMap);
131125
132126 /// Reads and makes available a PDB.
133 Expected<const CVIndexMap &> maybeMergeTypeServerPDB(ObjFile *File,
134 const CVType &FirstType);
127 Expected<const CVIndexMap &> maybeMergeTypeServerPDB(ObjFile *file);
135128
136129 /// Merges a precompiled headers TPI map into the current TPI map. The
137130 /// precompiled headers object will also be loaded and remapped in the
138131 /// process.
139 Expected<const CVIndexMap &>
140 mergeInPrecompHeaderObj(ObjFile *File, const CVType &FirstType,
141 CVIndexMap *ObjectIndexMap);
132 Error mergeInPrecompHeaderObj(ObjFile *file, CVIndexMap *objectIndexMap);
142133
143134 /// Reads and makes available a precompiled headers object.
144135 ///
......@@ -149,109 +140,87 @@ public:
149140 ///
150141 /// If the precompiled headers object was already loaded, this function will
151142 /// simply return its (remapped) TPI map.
152 Expected<const CVIndexMap &> aquirePrecompObj(ObjFile *File,
153 PrecompRecord Precomp);
143 Expected<const CVIndexMap &> aquirePrecompObj(ObjFile *file);
154144
155145 /// Adds a precompiled headers object signature -> TPI mapping.
156146 std::pair<CVIndexMap &, bool /*already there*/>
157 registerPrecompiledHeaders(uint32_t Signature);
147 registerPrecompiledHeaders(uint32_t signature);
158148
159 void mergeSymbolRecords(ObjFile *File, const CVIndexMap &IndexMap,
160 std::vector<ulittle32_t *> &StringTableRefs,
161 BinaryStreamRef SymData);
149 void mergeSymbolRecords(ObjFile *file, const CVIndexMap &indexMap,
150 std::vector<ulittle32_t *> &stringTableRefs,
151 BinaryStreamRef symData);
162152
163153 /// Add the section map and section contributions to the PDB.
164 void addSections(ArrayRef<OutputSection *> OutputSections,
165 ArrayRef<uint8_t> SectionTable);
166
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 }
154 void addSections(ArrayRef<OutputSection *> outputSections,
155 ArrayRef<uint8_t> sectionTable);
180156
181157 /// Write the PDB to disk and store the Guid generated for it in *Guid.
182 void commit(codeview::GUID *Guid);
183
184private:
185 BumpPtrAllocator Alloc;
186
187 SymbolTable *Symtab;
158 void commit(codeview::GUID *guid);
188159
189 pdb::PDBFileBuilder Builder;
160 // Print statistics regarding the final PDB
161 void printStats();
190162
191 /// Type records that will go into the PDB TPI stream.
192 MergingTypeTableBuilder TypeTable;
163private:
164 BumpPtrAllocator alloc;
193165
194 /// Item records that will go into the PDB IPI stream.
195 MergingTypeTableBuilder IDTable;
166 SymbolTable *symtab;
196167
197 /// Type records that will go into the PDB TPI stream (for /DEBUG:GHASH)
198 GlobalTypeTableBuilder GlobalTypeTable;
168 pdb::PDBFileBuilder builder;
199169
200 /// Item records that will go into the PDB IPI stream (for /DEBUG:GHASH)
201 GlobalTypeTableBuilder GlobalIDTable;
170 TypeMerger tMerger;
202171
203172 /// PDBs use a single global string table for filenames in the file checksum
204173 /// table.
205 DebugStringTableSubsection PDBStrTab;
206
207 llvm::SmallString<128> NativePath;
174 DebugStringTableSubsection pdbStrTab;
208175
209 /// A list of other PDBs which are loaded during the linking process and which
210 /// we need to keep around since the linking operation may reference pointers
211 /// inside of these PDBs.
212 llvm::SmallVector<std::unique_ptr<pdb::NativeSession>, 2> LoadedPDBs;
176 llvm::SmallString<128> nativePath;
213177
214 std::vector<pdb::SecMapEntry> SectionMap;
178 std::vector<pdb::SecMapEntry> sectionMap;
215179
216180 /// Type index mappings of type server PDBs that we've loaded so far.
217 std::map<codeview::GUID, CVIndexMap> TypeServerIndexMappings;
181 std::map<codeview::GUID, CVIndexMap> typeServerIndexMappings;
218182
219183 /// Type index mappings of precompiled objects type map that we've loaded so
220184 /// far.
221 std::map<uint32_t, CVIndexMap> PrecompTypeIndexMappings;
185 std::map<uint32_t, CVIndexMap> precompTypeIndexMappings;
222186
223 /// List of TypeServer PDBs which cannot be loaded.
224 /// Cached to prevent repeated load attempts.
225 std::map<codeview::GUID, std::string> MissingTypeServerPDBs;
187 // For statistics
188 uint64_t globalSymbols = 0;
189 uint64_t moduleSymbols = 0;
190 uint64_t publicSymbols = 0;
226191};
227192
228193class DebugSHandler {
229 PDBLinker &Linker;
194 PDBLinker &linker;
230195
231196 /// The object file whose .debug$S sections we're processing.
232 ObjFile &File;
197 ObjFile &file;
233198
234199 /// The result of merging type indices.
235 const CVIndexMap &IndexMap;
200 const CVIndexMap &indexMap;
236201
237202 /// The DEBUG_S_STRINGTABLE subsection. These strings are referred to by
238203 /// index from other records in the .debug$S section. All of these strings
239204 /// need to be added to the global PDB string table, and all references to
240205 /// these strings need to have their indices re-written to refer to the
241206 /// global PDB string table.
242 DebugStringTableSubsectionRef CVStrTab;
207 DebugStringTableSubsectionRef cVStrTab;
243208
244209 /// The DEBUG_S_FILECHKSMS subsection. As above, these are referred to
245210 /// by other records in the .debug$S section and need to be merged into the
246211 /// PDB.
247 DebugChecksumsSubsectionRef Checksums;
212 DebugChecksumsSubsectionRef checksums;
213
214 /// The DEBUG_S_INLINEELINES subsection. There can be only one of these per
215 /// object file.
216 DebugInlineeLinesSubsectionRef inlineeLines;
248217
249218 /// The DEBUG_S_FRAMEDATA subsection(s). There can be more than one of
250219 /// these and they need not appear in any specific order. However, they
251220 /// contain string table references which need to be re-written, so we
252221 /// collect them all here and re-write them after all subsections have been
253222 /// discovered and processed.
254 std::vector<DebugFrameDataSubsectionRef> NewFpoFrames;
223 std::vector<DebugFrameDataSubsectionRef> newFpoFrames;
255224
256225 /// Pointers to raw memory that we determine have string table references
257226 /// that need to be re-written. We first process all .debug$S subsections
......@@ -259,13 +228,17 @@ class DebugSHandler {
259228 /// up this list as we go. At the end, we use the string table (which must
260229 /// have been discovered by now else it is an error) to re-write these
261230 /// references.
262 std::vector<ulittle32_t *> StringTableReferences;
231 std::vector<ulittle32_t *> stringTableReferences;
263232
264233public:
265 DebugSHandler(PDBLinker &Linker, ObjFile &File, const CVIndexMap &IndexMap)
266 : Linker(Linker), File(File), IndexMap(IndexMap) {}
234 DebugSHandler(PDBLinker &linker, ObjFile &file, const CVIndexMap &indexMap)
235 : linker(linker), file(file), indexMap(indexMap) {}
236
237 void handleDebugS(lld::coff::SectionChunk &debugS);
238
239 std::shared_ptr<DebugInlineeLinesSubsection>
240 mergeInlineeLines(DebugChecksumsSubsection *newChecksums);
267241
268 void handleDebugS(lld::coff::SectionChunk &DebugS);
269242 void finish();
270243};
271244}
......@@ -273,7 +246,7 @@ public:
273246// Visual Studio's debugger requires absolute paths in various places in the
274247// PDB to work without additional configuration:
275248// https://docs.microsoft.com/en-us/visualstudio/debugger/debug-source-files-common-properties-solution-property-pages-dialog-box
276static void pdbMakeAbsolute(SmallVectorImpl<char> &FileName) {
249static void pdbMakeAbsolute(SmallVectorImpl<char> &fileName) {
277250 // The default behavior is to produce paths that are valid within the context
278251 // of the machine that you perform the link on. If the linker is running on
279252 // a POSIX system, we will output absolute POSIX paths. If the linker is
......@@ -281,16 +254,16 @@ static void pdbMakeAbsolute(SmallVectorImpl<char> &FileName) {
281254 // user desires any other kind of behavior, they should explicitly pass
282255 // /pdbsourcepath, in which case we will treat the exact string the user
283256 // 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))
257 if (sys::path::is_absolute(fileName, sys::path::Style::windows) ||
258 sys::path::is_absolute(fileName, sys::path::Style::posix))
286259 return;
287260
288261 // It's not absolute in any path syntax. Relative paths necessarily refer to
289262 // the local file system, so we can make it native without ending up with a
290263 // nonsensical path.
291 if (Config->PDBSourcePath.empty()) {
292 sys::path::native(FileName);
293 sys::fs::make_absolute(FileName);
264 if (config->pdbSourcePath.empty()) {
265 sys::path::native(fileName);
266 sys::fs::make_absolute(fileName);
294267 return;
295268 }
296269
......@@ -298,397 +271,239 @@ static void pdbMakeAbsolute(SmallVectorImpl<char> &FileName) {
298271 // Since PDB's are more of a Windows thing, we make this conservative and only
299272 // decide that it's a unix path if we're fairly certain. Specifically, if
300273 // it starts with a forward slash.
301 SmallString<128> AbsoluteFileName = Config->PDBSourcePath;
302 sys::path::Style GuessedStyle = AbsoluteFileName.startswith("/")
274 SmallString<128> absoluteFileName = config->pdbSourcePath;
275 sys::path::Style guessedStyle = absoluteFileName.startswith("/")
303276 ? sys::path::Style::posix
304277 : 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);
278 sys::path::append(absoluteFileName, guessedStyle, fileName);
279 sys::path::native(absoluteFileName, guessedStyle);
280 sys::path::remove_dots(absoluteFileName, true, guessedStyle);
308281
309 FileName = std::move(AbsoluteFileName);
310}
311
312static SectionChunk *findByName(ArrayRef<SectionChunk *> Sections,
313 StringRef Name) {
314 for (SectionChunk *C : Sections)
315 if (C->getSectionName() == Name)
316 return C;
317 return nullptr;
318}
319
320static ArrayRef<uint8_t> consumeDebugMagic(ArrayRef<uint8_t> Data,
321 StringRef SecName) {
322 // First 4 bytes are section magic.
323 if (Data.size() < 4)
324 fatal(SecName + " too short");
325 if (support::endian::read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
326 fatal(SecName + " has an invalid magic");
327 return Data.slice(4);
328}
329
330static ArrayRef<uint8_t> getDebugSection(ObjFile *File, StringRef SecName) {
331 if (SectionChunk *Sec = findByName(File->getDebugChunks(), SecName))
332 return consumeDebugMagic(Sec->getContents(), SecName);
333 return {};
282 fileName = std::move(absoluteFileName);
334283}
335284
336285// A COFF .debug$H section is currently a clang extension. This function checks
337286// if a .debug$H section is in a format that we expect / understand, so that we
338287// can ignore any sections which are coincidentally also named .debug$H but do
339288// not contain a format we recognize.
340static bool canUseDebugH(ArrayRef<uint8_t> DebugH) {
341 if (DebugH.size() < sizeof(object::debug_h_header))
289static bool canUseDebugH(ArrayRef<uint8_t> debugH) {
290 if (debugH.size() < sizeof(object::debug_h_header))
342291 return false;
343 auto *Header =
344 reinterpret_cast<const object::debug_h_header *>(DebugH.data());
345 DebugH = DebugH.drop_front(sizeof(object::debug_h_header));
346 return Header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC &&
347 Header->Version == 0 &&
348 Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1_8) &&
349 (DebugH.size() % 8 == 0);
292 auto *header =
293 reinterpret_cast<const object::debug_h_header *>(debugH.data());
294 debugH = debugH.drop_front(sizeof(object::debug_h_header));
295 return header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC &&
296 header->Version == 0 &&
297 header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1_8) &&
298 (debugH.size() % 8 == 0);
350299}
351300
352static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *File) {
353 SectionChunk *Sec = findByName(File->getDebugChunks(), ".debug$H");
354 if (!Sec)
301static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *file) {
302 SectionChunk *sec =
303 SectionChunk::findByName(file->getDebugChunks(), ".debug$H");
304 if (!sec)
355305 return llvm::None;
356 ArrayRef<uint8_t> Contents = Sec->getContents();
357 if (!canUseDebugH(Contents))
306 ArrayRef<uint8_t> contents = sec->getContents();
307 if (!canUseDebugH(contents))
358308 return None;
359 return Contents;
309 return contents;
360310}
361311
362312static ArrayRef<GloballyHashedType>
363getHashesFromDebugH(ArrayRef<uint8_t> DebugH) {
364 assert(canUseDebugH(DebugH));
313getHashesFromDebugH(ArrayRef<uint8_t> debugH) {
314 assert(canUseDebugH(debugH));
365315
366 DebugH = DebugH.drop_front(sizeof(object::debug_h_header));
367 uint32_t Count = DebugH.size() / sizeof(GloballyHashedType);
368 return {reinterpret_cast<const GloballyHashedType *>(DebugH.data()), Count};
316 debugH = debugH.drop_front(sizeof(object::debug_h_header));
317 uint32_t count = debugH.size() / sizeof(GloballyHashedType);
318 return {reinterpret_cast<const GloballyHashedType *>(debugH.data()), count};
369319}
370320
371static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
372 TypeCollection &TypeTable) {
321static void addTypeInfo(pdb::TpiStreamBuilder &tpiBuilder,
322 TypeCollection &typeTable) {
373323 // Start the TPI or IPI stream header.
374 TpiBuilder.setVersionHeader(pdb::PdbTpiV80);
324 tpiBuilder.setVersionHeader(pdb::PdbTpiV80);
375325
376326 // Flatten the in memory type table and hash each type.
377 TypeTable.ForEachRecord([&](TypeIndex TI, const CVType &Type) {
378 auto Hash = pdb::hashTypeRecord(Type);
379 if (auto E = Hash.takeError())
327 typeTable.ForEachRecord([&](TypeIndex ti, const CVType &type) {
328 auto hash = pdb::hashTypeRecord(type);
329 if (auto e = hash.takeError())
380330 fatal("type hashing error");
381 TpiBuilder.addTypeRecord(Type.RecordData, *Hash);
331 tpiBuilder.addTypeRecord(type.RecordData, *hash);
382332 });
383333}
384334
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;
417}
418
419335Expected<const CVIndexMap &>
420PDBLinker::mergeDebugT(ObjFile *File, CVIndexMap *ObjectIndexMap) {
421 ScopedTimer T(TypeMergingTimer);
336PDBLinker::mergeDebugT(ObjFile *file, CVIndexMap *objectIndexMap) {
337 ScopedTimer t(typeMergingTimer);
422338
423 bool IsPrecompiledHeader = false;
424
425 ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
426 if (Data.empty()) {
427 // Try again, Microsoft precompiled headers use .debug$P instead of
428 // .debug$T
429 Data = getDebugSection(File, ".debug$P");
430 IsPrecompiledHeader = true;
431 }
432 if (Data.empty())
433 return *ObjectIndexMap; // no debug info
339 if (!file->debugTypesObj)
340 return *objectIndexMap; // no Types stream
434341
435342 // Precompiled headers objects need to save the index map for further
436343 // reference by other objects which use the precompiled headers.
437 if (IsPrecompiledHeader) {
438 uint32_t PCHSignature = extractPCHSignature(File);
439 if (PCHSignature == 0)
344 if (file->debugTypesObj->kind == TpiSource::PCH) {
345 uint32_t pchSignature = file->pchSignature.getValueOr(0);
346 if (pchSignature == 0)
440347 fatal("No signature found for the precompiled headers OBJ (" +
441 File->getName() + ")");
348 file->getName() + ")");
442349
443350 // When a precompiled headers object comes first on the command-line, we
444351 // update the mapping here. Otherwise, if an object referencing the
445352 // precompiled headers object comes first, the mapping is created in
446353 // aquirePrecompObj(), thus we would skip this block.
447 if (!ObjectIndexMap->IsPrecompiledTypeMap) {
448 auto R = registerPrecompiledHeaders(PCHSignature);
449 if (R.second)
354 if (!objectIndexMap->isPrecompiledTypeMap) {
355 auto r = registerPrecompiledHeaders(pchSignature);
356 if (r.second)
450357 fatal(
451358 "A precompiled headers OBJ with the same signature was already "
452359 "provided! (" +
453 File->getName() + ")");
360 file->getName() + ")");
454361
455 ObjectIndexMap = &R.first;
362 objectIndexMap = &r.first;
456363 }
457364 }
458365
459 BinaryByteStream Stream(Data, support::little);
460 CVTypeArray Types;
461 BinaryStreamReader Reader(Stream);
462 if (auto EC = Reader.readArray(Types, Reader.getLength()))
463 fatal("Reader::readArray failed: " + toString(std::move(EC)));
464
465 auto FirstType = Types.begin();
466 if (FirstType == Types.end())
467 return *ObjectIndexMap;
468
469 if (FirstType->kind() == LF_TYPESERVER2) {
366 if (file->debugTypesObj->kind == TpiSource::UsingPDB) {
470367 // Look through type servers. If we've already seen this type server,
471368 // don't merge any type information.
472 return maybeMergeTypeServerPDB(File, *FirstType);
473 } else if (FirstType->kind() == LF_PRECOMP) {
369 return maybeMergeTypeServerPDB(file);
370 }
371
372 CVTypeArray &types = *file->debugTypes;
373
374 if (file->debugTypesObj->kind == TpiSource::UsingPCH) {
474375 // This object was compiled with /Yu, so process the corresponding
475376 // precompiled headers object (/Yc) first. Some type indices in the current
476377 // object are referencing data in the precompiled headers object, so we need
477378 // 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()));
379 Error e = mergeInPrecompHeaderObj(file, objectIndexMap);
380 if (e)
381 return std::move(e);
382
383 // Drop LF_PRECOMP record from the input stream, as it has been replaced
384 // with the precompiled headers Type stream in the mergeInPrecompHeaderObj()
385 // call above. Note that we can't just call Types.drop_front(), as we
386 // explicitly want to rebase the stream.
387 CVTypeArray::Iterator firstType = types.begin();
388 types.setUnderlyingStream(
389 types.getUnderlyingStream().drop_front(firstType->RecordData.size()));
488390 }
489391
490392 // Fill in the temporary, caller-provided ObjectIndexMap.
491 if (Config->DebugGHashes) {
492 ArrayRef<GloballyHashedType> Hashes;
493 std::vector<GloballyHashedType> OwnedHashes;
494 if (Optional<ArrayRef<uint8_t>> DebugH = getDebugH(File))
495 Hashes = getHashesFromDebugH(*DebugH);
393 if (config->debugGHashes) {
394 ArrayRef<GloballyHashedType> hashes;
395 std::vector<GloballyHashedType> ownedHashes;
396 if (Optional<ArrayRef<uint8_t>> debugH = getDebugH(file))
397 hashes = getHashesFromDebugH(*debugH);
496398 else {
497 OwnedHashes = GloballyHashedType::hashTypes(Types);
498 Hashes = OwnedHashes;
399 ownedHashes = GloballyHashedType::hashTypes(types);
400 hashes = ownedHashes;
499401 }
500402
501 if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable,
502 ObjectIndexMap->TPIMap, Types, Hashes,
503 File->PCHSignature))
403 if (auto err = mergeTypeAndIdRecords(
404 tMerger.globalIDTable, tMerger.globalTypeTable,
405 objectIndexMap->tpiMap, types, hashes, file->pchSignature))
504406 fatal("codeview::mergeTypeAndIdRecords failed: " +
505 toString(std::move(Err)));
407 toString(std::move(err)));
506408 } else {
507 if (auto Err =
508 mergeTypeAndIdRecords(IDTable, TypeTable, ObjectIndexMap->TPIMap,
509 Types, File->PCHSignature))
409 if (auto err = mergeTypeAndIdRecords(tMerger.iDTable, tMerger.typeTable,
410 objectIndexMap->tpiMap, types,
411 file->pchSignature))
510412 fatal("codeview::mergeTypeAndIdRecords failed: " +
511 toString(std::move(Err)));
413 toString(std::move(err)));
512414 }
513 return *ObjectIndexMap;
415 return *objectIndexMap;
514416}
515417
516static Expected<std::unique_ptr<pdb::NativeSession>>
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
524 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(
525 TSPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
526 if (!MBOrErr)
527 return errorCodeToError(MBOrErr.getError());
528
529 std::unique_ptr<pdb::IPDBSession> ThisSession;
530 if (auto EC = pdb::NativeSession::createFromPdb(
531 MemoryBuffer::getMemBuffer(Driver->takeBuffer(std::move(*MBOrErr)),
532 /*RequiresNullTerminator=*/false),
533 ThisSession))
534 return std::move(EC);
535
536 std::unique_ptr<pdb::NativeSession> NS(
537 static_cast<pdb::NativeSession *>(ThisSession.release()));
538 pdb::PDBFile &File = NS->getPDBFile();
539 auto ExpectedInfo = File.getPDBInfoStream();
540 // All PDB Files should have an Info stream.
541 if (!ExpectedInfo)
542 return ExpectedInfo.takeError();
543
544 // Just because a file with a matching name was found and it was an actual
545 // PDB file doesn't mean it matches. For it to match the InfoStream's GUID
546 // must match the GUID specified in the TypeServer2 record.
547 if (ExpectedInfo->getGuid() != GuidFromObj)
548 return make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date);
549
550 return std::move(NS);
551}
418Expected<const CVIndexMap &> PDBLinker::maybeMergeTypeServerPDB(ObjFile *file) {
419 Expected<llvm::pdb::NativeSession *> pdbSession = findTypeServerSource(file);
420 if (!pdbSession)
421 return pdbSession.takeError();
552422
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();
561 StringRef TSPath = TS.getName();
562
563 // First, check if the PDB has previously failed to load.
564 auto PrevErr = MissingTypeServerPDBs.find(TSId);
565 if (PrevErr != MissingTypeServerPDBs.end())
566 return createFileError(
567 TSPath,
568 make_error<StringError>(PrevErr->second, inconvertibleErrorCode()));
423 pdb::PDBFile &pdbFile = pdbSession.get()->getPDBFile();
424 pdb::InfoStream &info = cantFail(pdbFile.getPDBInfoStream());
569425
570 // Second, check if we already loaded a PDB with this GUID. Return the type
571 // index mapping if we have it.
572 auto Insertion = TypeServerIndexMappings.insert({TSId, CVIndexMap()});
573 CVIndexMap &IndexMap = Insertion.first->second;
574 if (!Insertion.second)
575 return IndexMap;
426 auto it = typeServerIndexMappings.emplace(info.getGuid(), CVIndexMap());
427 CVIndexMap &indexMap = it.first->second;
428 if (!it.second)
429 return indexMap; // already merged
576430
577431 // Mark this map as a type server map.
578 IndexMap.IsTypeServerMap = true;
579
580 // Check for a PDB at:
581 // 1. The given file path
582 // 2. Next to the object file or archive file
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
605 if (auto E = ExpectedSession.takeError()) {
606 TypeServerIndexMappings.erase(TSId);
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));
432 indexMap.isTypeServerMap = true;
433
434 Expected<pdb::TpiStream &> expectedTpi = pdbFile.getPDBTpiStream();
435 if (auto e = expectedTpi.takeError())
436 fatal("Type server does not have TPI stream: " + toString(std::move(e)));
437 pdb::TpiStream *maybeIpi = nullptr;
438 if (pdbFile.hasPDBIpiStream()) {
439 Expected<pdb::TpiStream &> expectedIpi = pdbFile.getPDBIpiStream();
440 if (auto e = expectedIpi.takeError())
441 fatal("Error getting type server IPI stream: " + toString(std::move(e)));
442 maybeIpi = &*expectedIpi;
616443 }
617444
618 pdb::NativeSession *Session = ExpectedSession->get();
619
620 // Keep a strong reference to this PDB, so that it's safe to hold pointers
621 // into the file.
622 LoadedPDBs.push_back(std::move(*ExpectedSession));
623
624 auto ExpectedTpi = Session->getPDBFile().getPDBTpiStream();
625 if (auto E = ExpectedTpi.takeError())
626 fatal("Type server does not have TPI stream: " + toString(std::move(E)));
627 auto ExpectedIpi = Session->getPDBFile().getPDBIpiStream();
628 if (auto E = ExpectedIpi.takeError())
629 fatal("Type server does not have TPI stream: " + toString(std::move(E)));
630
631 if (Config->DebugGHashes) {
445 if (config->debugGHashes) {
632446 // PDBs do not actually store global hashes, so when merging a type server
633447 // PDB we have to synthesize global hashes. To do this, we first synthesize
634448 // global hashes for the TPI stream, since it is independent, then we
635449 // synthesize hashes for the IPI stream, using the hashes for the TPI stream
636450 // as inputs.
637 auto TpiHashes = GloballyHashedType::hashTypes(ExpectedTpi->typeArray());
638 auto IpiHashes =
639 GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes);
640
641 Optional<uint32_t> EndPrecomp;
451 auto tpiHashes = GloballyHashedType::hashTypes(expectedTpi->typeArray());
452 Optional<uint32_t> endPrecomp;
642453 // Merge TPI first, because the IPI stream will reference type indices.
643 if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap,
644 ExpectedTpi->typeArray(), TpiHashes, EndPrecomp))
645 fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));
454 if (auto err =
455 mergeTypeRecords(tMerger.globalTypeTable, indexMap.tpiMap,
456 expectedTpi->typeArray(), tpiHashes, endPrecomp))
457 fatal("codeview::mergeTypeRecords failed: " + toString(std::move(err)));
646458
647459 // Merge IPI.
648 if (auto Err =
649 mergeIdRecords(GlobalIDTable, IndexMap.TPIMap, IndexMap.IPIMap,
650 ExpectedIpi->typeArray(), IpiHashes))
651 fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
460 if (maybeIpi) {
461 auto ipiHashes =
462 GloballyHashedType::hashIds(maybeIpi->typeArray(), tpiHashes);
463 if (auto err =
464 mergeIdRecords(tMerger.globalIDTable, indexMap.tpiMap,
465 indexMap.ipiMap, maybeIpi->typeArray(), ipiHashes))
466 fatal("codeview::mergeIdRecords failed: " + toString(std::move(err)));
467 }
652468 } else {
653469 // Merge TPI first, because the IPI stream will reference type indices.
654 if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap,
655 ExpectedTpi->typeArray()))
656 fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err)));
470 if (auto err = mergeTypeRecords(tMerger.typeTable, indexMap.tpiMap,
471 expectedTpi->typeArray()))
472 fatal("codeview::mergeTypeRecords failed: " + toString(std::move(err)));
657473
658474 // Merge IPI.
659 if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap,
660 ExpectedIpi->typeArray()))
661 fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err)));
475 if (maybeIpi) {
476 if (auto err = mergeIdRecords(tMerger.iDTable, indexMap.tpiMap,
477 indexMap.ipiMap, maybeIpi->typeArray()))
478 fatal("codeview::mergeIdRecords failed: " + toString(std::move(err)));
479 }
662480 }
663481
664 return IndexMap;
482 return indexMap;
665483}
666484
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)));
485Error PDBLinker::mergeInPrecompHeaderObj(ObjFile *file,
486 CVIndexMap *objectIndexMap) {
487 const PrecompRecord &precomp =
488 retrieveDependencyInfo<PrecompRecord>(file->debugTypesObj);
674489
675 auto E = aquirePrecompObj(File, Precomp);
676 if (!E)
677 return E.takeError();
490 Expected<const CVIndexMap &> e = aquirePrecompObj(file);
491 if (!e)
492 return e.takeError();
678493
679 const CVIndexMap &PrecompIndexMap = *E;
680 assert(PrecompIndexMap.IsPrecompiledTypeMap);
494 const CVIndexMap &precompIndexMap = *e;
495 assert(precompIndexMap.isPrecompiledTypeMap);
681496
682 if (PrecompIndexMap.TPIMap.empty())
683 return PrecompIndexMap;
497 if (precompIndexMap.tpiMap.empty())
498 return Error::success();
684499
685 assert(Precomp.getStartTypeIndex() == TypeIndex::FirstNonSimpleIndex);
686 assert(Precomp.getTypesCount() <= PrecompIndexMap.TPIMap.size());
500 assert(precomp.getStartTypeIndex() == TypeIndex::FirstNonSimpleIndex);
501 assert(precomp.getTypesCount() <= precompIndexMap.tpiMap.size());
687502 // 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;
503 objectIndexMap->tpiMap.append(precompIndexMap.tpiMap.begin(),
504 precompIndexMap.tpiMap.begin() +
505 precomp.getTypesCount());
506 return Error::success();
692507}
693508
694509static bool equals_path(StringRef path1, StringRef path2) {
......@@ -700,101 +515,103 @@ static bool equals_path(StringRef path1, StringRef path2) {
700515}
701516
702517// Find by name an OBJ provided on the command line
703static ObjFile *findObjByName(StringRef FileNameOnly) {
704 SmallString<128> CurrentPath;
518static ObjFile *findObjByName(StringRef fileNameOnly) {
519 SmallString<128> currentPath;
705520
706 for (ObjFile *F : ObjFile::Instances) {
707 StringRef CurrentFileName = sys::path::filename(F->getName());
521 for (ObjFile *f : ObjFile::instances) {
522 StringRef currentFileName = sys::path::filename(f->getName());
708523
709524 // Compare based solely on the file name (link.exe behavior)
710 if (equals_path(CurrentFileName, FileNameOnly))
711 return F;
525 if (equals_path(currentFileName, fileNameOnly))
526 return f;
712527 }
713528 return nullptr;
714529}
715530
716531std::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};
532PDBLinker::registerPrecompiledHeaders(uint32_t signature) {
533 auto insertion = precompTypeIndexMappings.insert({signature, CVIndexMap()});
534 CVIndexMap &indexMap = insertion.first->second;
535 if (!insertion.second)
536 return {indexMap, true};
722537 // Mark this map as a precompiled types map.
723 IndexMap.IsPrecompiledTypeMap = true;
724 return {IndexMap, false};
538 indexMap.isPrecompiledTypeMap = true;
539 return {indexMap, false};
725540}
726541
727Expected<const CVIndexMap &>
728PDBLinker::aquirePrecompObj(ObjFile *File, PrecompRecord Precomp) {
542Expected<const CVIndexMap &> PDBLinker::aquirePrecompObj(ObjFile *file) {
543 const PrecompRecord &precomp =
544 retrieveDependencyInfo<PrecompRecord>(file->debugTypesObj);
545
729546 // First, check if we already loaded the precompiled headers object with this
730547 // 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;
548 auto r = registerPrecompiledHeaders(precomp.getSignature());
549 if (r.second)
550 return r.first;
734551
735 CVIndexMap &IndexMap = R.first;
552 CVIndexMap &indexMap = r.first;
736553
737554 // Cross-compile warning: given that Clang doesn't generate LF_PRECOMP
738555 // records, we assume the OBJ comes from a Windows build of cl.exe. Thusly,
739556 // 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);
557 SmallString<128> precompFileName = sys::path::filename(
558 precomp.getPrecompFilePath(), sys::path::Style::windows);
742559
743560 // link.exe requires that a precompiled headers object must always be provided
744561 // on the command-line, even if that's not necessary.
745 auto PrecompFile = findObjByName(PrecompFileName);
746 if (!PrecompFile)
562 auto precompFile = findObjByName(precompFileName);
563 if (!precompFile)
747564 return createFileError(
748 PrecompFileName.str(),
565 precompFileName.str(),
749566 make_error<pdb::PDBError>(pdb::pdb_error_code::external_cmdline_ref));
750567
751 addObjFile(PrecompFile, &IndexMap);
568 addObjFile(precompFile, &indexMap);
752569
753 if (!PrecompFile->PCHSignature)
754 fatal(PrecompFile->getName() + " is not a precompiled headers object");
570 if (!precompFile->pchSignature)
571 fatal(precompFile->getName() + " is not a precompiled headers object");
755572
756 if (Precomp.getSignature() != PrecompFile->PCHSignature.getValueOr(0))
573 if (precomp.getSignature() != precompFile->pchSignature.getValueOr(0))
757574 return createFileError(
758 Precomp.getPrecompFilePath().str(),
575 precomp.getPrecompFilePath().str(),
759576 make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
760577
761 return IndexMap;
578 return indexMap;
762579}
763580
764static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
765 if (TI.isSimple())
581static bool remapTypeIndex(TypeIndex &ti, ArrayRef<TypeIndex> typeIndexMap) {
582 if (ti.isSimple())
766583 return true;
767 if (TI.toArrayIndex() >= TypeIndexMap.size())
584 if (ti.toArrayIndex() >= typeIndexMap.size())
768585 return false;
769 TI = TypeIndexMap[TI.toArrayIndex()];
586 ti = typeIndexMap[ti.toArrayIndex()];
770587 return true;
771588}
772589
773static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind,
774 MutableArrayRef<uint8_t> RecordBytes,
775 const CVIndexMap &IndexMap,
776 ArrayRef<TiReference> TypeRefs) {
777 MutableArrayRef<uint8_t> Contents =
778 RecordBytes.drop_front(sizeof(RecordPrefix));
779 for (const TiReference &Ref : TypeRefs) {
780 unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
781 if (Contents.size() < Ref.Offset + ByteSize)
590static void remapTypesInSymbolRecord(ObjFile *file, SymbolKind symKind,
591 MutableArrayRef<uint8_t> recordBytes,
592 const CVIndexMap &indexMap,
593 ArrayRef<TiReference> typeRefs) {
594 MutableArrayRef<uint8_t> contents =
595 recordBytes.drop_front(sizeof(RecordPrefix));
596 for (const TiReference &ref : typeRefs) {
597 unsigned byteSize = ref.Count * sizeof(TypeIndex);
598 if (contents.size() < ref.Offset + byteSize)
782599 fatal("symbol record too short");
783600
784601 // This can be an item index or a type index. Choose the appropriate map.
785 ArrayRef<TypeIndex> TypeOrItemMap = IndexMap.TPIMap;
786 bool IsItemIndex = Ref.Kind == TiRefKind::IndexRef;
787 if (IsItemIndex && IndexMap.IsTypeServerMap)
788 TypeOrItemMap = IndexMap.IPIMap;
789
790 MutableArrayRef<TypeIndex> TIs(
791 reinterpret_cast<TypeIndex *>(Contents.data() + Ref.Offset), Ref.Count);
792 for (TypeIndex &TI : TIs) {
793 if (!remapTypeIndex(TI, TypeOrItemMap)) {
794 log("ignoring symbol record of kind 0x" + utohexstr(SymKind) + " in " +
795 File->getName() + " with bad " + (IsItemIndex ? "item" : "type") +
796 " index 0x" + utohexstr(TI.getIndex()));
797 TI = TypeIndex(SimpleTypeKind::NotTranslated);
602 ArrayRef<TypeIndex> typeOrItemMap = indexMap.tpiMap;
603 bool isItemIndex = ref.Kind == TiRefKind::IndexRef;
604 if (isItemIndex && indexMap.isTypeServerMap)
605 typeOrItemMap = indexMap.ipiMap;
606
607 MutableArrayRef<TypeIndex> tIs(
608 reinterpret_cast<TypeIndex *>(contents.data() + ref.Offset), ref.Count);
609 for (TypeIndex &ti : tIs) {
610 if (!remapTypeIndex(ti, typeOrItemMap)) {
611 log("ignoring symbol record of kind 0x" + utohexstr(symKind) + " in " +
612 file->getName() + " with bad " + (isItemIndex ? "item" : "type") +
613 " index 0x" + utohexstr(ti.getIndex()));
614 ti = TypeIndex(SimpleTypeKind::NotTranslated);
798615 continue;
799616 }
800617 }
......@@ -802,26 +619,26 @@ static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind,
802619}
803620
804621static void
805recordStringTableReferenceAtOffset(MutableArrayRef<uint8_t> Contents,
806 uint32_t Offset,
807 std::vector<ulittle32_t *> &StrTableRefs) {
808 Contents =
809 Contents.drop_front(Offset).take_front(sizeof(support::ulittle32_t));
810 ulittle32_t *Index = reinterpret_cast<ulittle32_t *>(Contents.data());
811 StrTableRefs.push_back(Index);
622recordStringTableReferenceAtOffset(MutableArrayRef<uint8_t> contents,
623 uint32_t offset,
624 std::vector<ulittle32_t *> &strTableRefs) {
625 contents =
626 contents.drop_front(offset).take_front(sizeof(support::ulittle32_t));
627 ulittle32_t *index = reinterpret_cast<ulittle32_t *>(contents.data());
628 strTableRefs.push_back(index);
812629}
813630
814631static void
815recordStringTableReferences(SymbolKind Kind, MutableArrayRef<uint8_t> Contents,
816 std::vector<ulittle32_t *> &StrTableRefs) {
632recordStringTableReferences(SymbolKind kind, MutableArrayRef<uint8_t> contents,
633 std::vector<ulittle32_t *> &strTableRefs) {
817634 // For now we only handle S_FILESTATIC, but we may need the same logic for
818635 // S_DEFRANGE and S_DEFRANGE_SUBFIELD. However, I cannot seem to generate any
819636 // PDBs that contain these types of records, so because of the uncertainty
820637 // they are omitted here until we can prove that it's necessary.
821 switch (Kind) {
638 switch (kind) {
822639 case SymbolKind::S_FILESTATIC:
823640 // FileStaticSym::ModFileOffset
824 recordStringTableReferenceAtOffset(Contents, 8, StrTableRefs);
641 recordStringTableReferenceAtOffset(contents, 8, strTableRefs);
825642 break;
826643 case SymbolKind::S_DEFRANGE:
827644 case SymbolKind::S_DEFRANGE_SUBFIELD:
......@@ -833,21 +650,21 @@ recordStringTableReferences(SymbolKind Kind, MutableArrayRef<uint8_t> Contents,
833650 }
834651}
835652
836static SymbolKind symbolKind(ArrayRef<uint8_t> RecordData) {
837 const RecordPrefix *Prefix =
838 reinterpret_cast<const RecordPrefix *>(RecordData.data());
839 return static_cast<SymbolKind>(uint16_t(Prefix->RecordKind));
653static SymbolKind symbolKind(ArrayRef<uint8_t> recordData) {
654 const RecordPrefix *prefix =
655 reinterpret_cast<const RecordPrefix *>(recordData.data());
656 return static_cast<SymbolKind>(uint16_t(prefix->RecordKind));
840657}
841658
842659/// MSVC translates S_PROC_ID_END to S_END, and S_[LG]PROC32_ID to S_[LG]PROC32
843static void translateIdSymbols(MutableArrayRef<uint8_t> &RecordData,
844 TypeCollection &IDTable) {
845 RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(RecordData.data());
660static void translateIdSymbols(MutableArrayRef<uint8_t> &recordData,
661 TypeCollection &iDTable) {
662 RecordPrefix *prefix = reinterpret_cast<RecordPrefix *>(recordData.data());
846663
847 SymbolKind Kind = symbolKind(RecordData);
664 SymbolKind kind = symbolKind(recordData);
848665
849 if (Kind == SymbolKind::S_PROC_ID_END) {
850 Prefix->RecordKind = SymbolKind::S_END;
666 if (kind == SymbolKind::S_PROC_ID_END) {
667 prefix->RecordKind = SymbolKind::S_END;
851668 return;
852669 }
853670
......@@ -856,89 +673,89 @@ static void translateIdSymbols(MutableArrayRef<uint8_t> &RecordData,
856673 // to the PDB file's ID stream index space, but we need to convert this to a
857674 // symbol that refers to the type stream index space. So we remap again from
858675 // ID index space to type index space.
859 if (Kind == SymbolKind::S_GPROC32_ID || Kind == SymbolKind::S_LPROC32_ID) {
860 SmallVector<TiReference, 1> Refs;
861 auto Content = RecordData.drop_front(sizeof(RecordPrefix));
862 CVSymbol Sym(Kind, RecordData);
863 discoverTypeIndicesInSymbol(Sym, Refs);
864 assert(Refs.size() == 1);
865 assert(Refs.front().Count == 1);
866
867 TypeIndex *TI =
868 reinterpret_cast<TypeIndex *>(Content.data() + Refs[0].Offset);
869 // `TI` is the index of a FuncIdRecord or MemberFuncIdRecord which lives in
676 if (kind == SymbolKind::S_GPROC32_ID || kind == SymbolKind::S_LPROC32_ID) {
677 SmallVector<TiReference, 1> refs;
678 auto content = recordData.drop_front(sizeof(RecordPrefix));
679 CVSymbol sym(recordData);
680 discoverTypeIndicesInSymbol(sym, refs);
681 assert(refs.size() == 1);
682 assert(refs.front().Count == 1);
683
684 TypeIndex *ti =
685 reinterpret_cast<TypeIndex *>(content.data() + refs[0].Offset);
686 // `ti` is the index of a FuncIdRecord or MemberFuncIdRecord which lives in
870687 // the IPI stream, whose `FunctionType` member refers to the TPI stream.
871688 // Note that LF_FUNC_ID and LF_MEMFUNC_ID have the same record layout, and
872689 // in both cases we just need the second type index.
873 if (!TI->isSimple() && !TI->isNoneType()) {
874 CVType FuncIdData = IDTable.getType(*TI);
875 SmallVector<TypeIndex, 2> Indices;
876 discoverTypeIndices(FuncIdData, Indices);
877 assert(Indices.size() == 2);
878 *TI = Indices[1];
690 if (!ti->isSimple() && !ti->isNoneType()) {
691 CVType funcIdData = iDTable.getType(*ti);
692 SmallVector<TypeIndex, 2> indices;
693 discoverTypeIndices(funcIdData, indices);
694 assert(indices.size() == 2);
695 *ti = indices[1];
879696 }
880697
881 Kind = (Kind == SymbolKind::S_GPROC32_ID) ? SymbolKind::S_GPROC32
698 kind = (kind == SymbolKind::S_GPROC32_ID) ? SymbolKind::S_GPROC32
882699 : SymbolKind::S_LPROC32;
883 Prefix->RecordKind = uint16_t(Kind);
700 prefix->RecordKind = uint16_t(kind);
884701 }
885702}
886703
887704/// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned.
888705/// The object file may not be aligned.
889706static MutableArrayRef<uint8_t>
890copyAndAlignSymbol(const CVSymbol &Sym, MutableArrayRef<uint8_t> &AlignedMem) {
891 size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));
892 assert(Size >= 4 && "record too short");
893 assert(Size <= MaxRecordLength && "record too long");
894 assert(AlignedMem.size() >= Size && "didn't preallocate enough");
707copyAndAlignSymbol(const CVSymbol &sym, MutableArrayRef<uint8_t> &alignedMem) {
708 size_t size = alignTo(sym.length(), alignOf(CodeViewContainer::Pdb));
709 assert(size >= 4 && "record too short");
710 assert(size <= MaxRecordLength && "record too long");
711 assert(alignedMem.size() >= size && "didn't preallocate enough");
895712
896713 // Copy the symbol record and zero out any padding bytes.
897 MutableArrayRef<uint8_t> NewData = AlignedMem.take_front(Size);
898 AlignedMem = AlignedMem.drop_front(Size);
899 memcpy(NewData.data(), Sym.data().data(), Sym.length());
900 memset(NewData.data() + Sym.length(), 0, Size - Sym.length());
714 MutableArrayRef<uint8_t> newData = alignedMem.take_front(size);
715 alignedMem = alignedMem.drop_front(size);
716 memcpy(newData.data(), sym.data().data(), sym.length());
717 memset(newData.data() + sym.length(), 0, size - sym.length());
901718
902719 // Update the record prefix length. It should point to the beginning of the
903720 // next record.
904 auto *Prefix = reinterpret_cast<RecordPrefix *>(NewData.data());
905 Prefix->RecordLen = Size - 2;
906 return NewData;
721 auto *prefix = reinterpret_cast<RecordPrefix *>(newData.data());
722 prefix->RecordLen = size - 2;
723 return newData;
907724}
908725
909726struct ScopeRecord {
910 ulittle32_t PtrParent;
911 ulittle32_t PtrEnd;
727 ulittle32_t ptrParent;
728 ulittle32_t ptrEnd;
912729};
913730
914731struct SymbolScope {
915 ScopeRecord *OpeningRecord;
916 uint32_t ScopeOffset;
732 ScopeRecord *openingRecord;
733 uint32_t scopeOffset;
917734};
918735
919static void scopeStackOpen(SmallVectorImpl<SymbolScope> &Stack,
920 uint32_t CurOffset, CVSymbol &Sym) {
921 assert(symbolOpensScope(Sym.kind()));
922 SymbolScope S;
923 S.ScopeOffset = CurOffset;
924 S.OpeningRecord = const_cast<ScopeRecord *>(
925 reinterpret_cast<const ScopeRecord *>(Sym.content().data()));
926 S.OpeningRecord->PtrParent = Stack.empty() ? 0 : Stack.back().ScopeOffset;
927 Stack.push_back(S);
736static void scopeStackOpen(SmallVectorImpl<SymbolScope> &stack,
737 uint32_t curOffset, CVSymbol &sym) {
738 assert(symbolOpensScope(sym.kind()));
739 SymbolScope s;
740 s.scopeOffset = curOffset;
741 s.openingRecord = const_cast<ScopeRecord *>(
742 reinterpret_cast<const ScopeRecord *>(sym.content().data()));
743 s.openingRecord->ptrParent = stack.empty() ? 0 : stack.back().scopeOffset;
744 stack.push_back(s);
928745}
929746
930static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack,
931 uint32_t CurOffset, ObjFile *File) {
932 if (Stack.empty()) {
933 warn("symbol scopes are not balanced in " + File->getName());
747static void scopeStackClose(SmallVectorImpl<SymbolScope> &stack,
748 uint32_t curOffset, InputFile *file) {
749 if (stack.empty()) {
750 warn("symbol scopes are not balanced in " + file->getName());
934751 return;
935752 }
936 SymbolScope S = Stack.pop_back_val();
937 S.OpeningRecord->PtrEnd = CurOffset;
753 SymbolScope s = stack.pop_back_val();
754 s.openingRecord->ptrEnd = curOffset;
938755}
939756
940static bool symbolGoesInModuleStream(const CVSymbol &Sym, bool IsGlobalScope) {
941 switch (Sym.kind()) {
757static bool symbolGoesInModuleStream(const CVSymbol &sym, bool isGlobalScope) {
758 switch (sym.kind()) {
942759 case SymbolKind::S_GDATA32:
943760 case SymbolKind::S_CONSTANT:
944761 // We really should not be seeing S_PROCREF and S_LPROCREF in the first place
......@@ -950,7 +767,7 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym, bool IsGlobalScope) {
950767 return false;
951768 // S_UDT records go in the module stream if it is not a global S_UDT.
952769 case SymbolKind::S_UDT:
953 return !IsGlobalScope;
770 return !isGlobalScope;
954771 // S_GDATA32 does not go in the module stream, but S_LDATA32 does.
955772 case SymbolKind::S_LDATA32:
956773 default:
......@@ -958,8 +775,8 @@ static bool symbolGoesInModuleStream(const CVSymbol &Sym, bool IsGlobalScope) {
958775 }
959776}
960777
961static bool symbolGoesInGlobalsStream(const CVSymbol &Sym, bool IsGlobalScope) {
962 switch (Sym.kind()) {
778static bool symbolGoesInGlobalsStream(const CVSymbol &sym, bool isGlobalScope) {
779 switch (sym.kind()) {
963780 case SymbolKind::S_CONSTANT:
964781 case SymbolKind::S_GDATA32:
965782 // S_LDATA32 goes in both the module stream and the globals stream.
......@@ -974,36 +791,36 @@ static bool symbolGoesInGlobalsStream(const CVSymbol &Sym, bool IsGlobalScope) {
974791 return true;
975792 // S_UDT records go in the globals stream if it is a global S_UDT.
976793 case SymbolKind::S_UDT:
977 return IsGlobalScope;
794 return isGlobalScope;
978795 default:
979796 return false;
980797 }
981798}
982799
983static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, uint16_t ModIndex,
984 unsigned SymOffset, const CVSymbol &Sym) {
985 switch (Sym.kind()) {
800static void addGlobalSymbol(pdb::GSIStreamBuilder &builder, uint16_t modIndex,
801 unsigned symOffset, const CVSymbol &sym) {
802 switch (sym.kind()) {
986803 case SymbolKind::S_CONSTANT:
987804 case SymbolKind::S_UDT:
988805 case SymbolKind::S_GDATA32:
989806 case SymbolKind::S_LDATA32:
990807 case SymbolKind::S_PROCREF:
991808 case SymbolKind::S_LPROCREF:
992 Builder.addGlobalSymbol(Sym);
809 builder.addGlobalSymbol(sym);
993810 break;
994811 case SymbolKind::S_GPROC32:
995812 case SymbolKind::S_LPROC32: {
996 SymbolRecordKind K = SymbolRecordKind::ProcRefSym;
997 if (Sym.kind() == SymbolKind::S_LPROC32)
998 K = SymbolRecordKind::LocalProcRef;
999 ProcRefSym PS(K);
1000 PS.Module = ModIndex;
813 SymbolRecordKind k = SymbolRecordKind::ProcRefSym;
814 if (sym.kind() == SymbolKind::S_LPROC32)
815 k = SymbolRecordKind::LocalProcRef;
816 ProcRefSym ps(k);
817 ps.Module = modIndex;
1001818 // For some reason, MSVC seems to add one to this value.
1002 ++PS.Module;
1003 PS.Name = getSymbolName(Sym);
1004 PS.SumName = 0;
1005 PS.SymOffset = SymOffset;
1006 Builder.addGlobalSymbol(PS);
819 ++ps.Module;
820 ps.Name = getSymbolName(sym);
821 ps.SumName = 0;
822 ps.SymOffset = symOffset;
823 builder.addGlobalSymbol(ps);
1007824 break;
1008825 }
1009826 default:
......@@ -1011,229 +828,304 @@ static void addGlobalSymbol(pdb::GSIStreamBuilder &Builder, uint16_t ModIndex,
1011828 }
1012829}
1013830
1014void PDBLinker::mergeSymbolRecords(ObjFile *File, const CVIndexMap &IndexMap,
1015 std::vector<ulittle32_t *> &StringTableRefs,
1016 BinaryStreamRef SymData) {
1017 ArrayRef<uint8_t> SymsBuffer;
1018 cantFail(SymData.readBytes(0, SymData.getLength(), SymsBuffer));
1019 SmallVector<SymbolScope, 4> Scopes;
831void PDBLinker::mergeSymbolRecords(ObjFile *file, const CVIndexMap &indexMap,
832 std::vector<ulittle32_t *> &stringTableRefs,
833 BinaryStreamRef symData) {
834 ArrayRef<uint8_t> symsBuffer;
835 cantFail(symData.readBytes(0, symData.getLength(), symsBuffer));
836 SmallVector<SymbolScope, 4> scopes;
1020837
1021838 // Iterate every symbol to check if any need to be realigned, and if so, how
1022839 // much space we need to allocate for them.
1023 bool NeedsRealignment = false;
1024 unsigned TotalRealignedSize = 0;
1025 auto EC = forEachCodeViewRecord<CVSymbol>(
1026 SymsBuffer, [&](CVSymbol Sym) -> llvm::Error {
1027 unsigned RealignedSize =
1028 alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));
1029 NeedsRealignment |= RealignedSize != Sym.length();
1030 TotalRealignedSize += RealignedSize;
840 bool needsRealignment = false;
841 unsigned totalRealignedSize = 0;
842 auto ec = forEachCodeViewRecord<CVSymbol>(
843 symsBuffer, [&](CVSymbol sym) -> llvm::Error {
844 unsigned realignedSize =
845 alignTo(sym.length(), alignOf(CodeViewContainer::Pdb));
846 needsRealignment |= realignedSize != sym.length();
847 totalRealignedSize += realignedSize;
1031848 return Error::success();
1032849 });
1033850
1034851 // If any of the symbol record lengths was corrupt, ignore them all, warn
1035852 // about it, and move on.
1036 if (EC) {
1037 warn("corrupt symbol records in " + File->getName());
1038 consumeError(std::move(EC));
853 if (ec) {
854 warn("corrupt symbol records in " + file->getName());
855 consumeError(std::move(ec));
1039856 return;
1040857 }
1041858
1042859 // If any symbol needed realignment, allocate enough contiguous memory for
1043860 // them all. Typically symbol subsections are small enough that this will not
1044861 // 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);
862 MutableArrayRef<uint8_t> alignedSymbolMem;
863 if (needsRealignment) {
864 void *alignedData =
865 alloc.Allocate(totalRealignedSize, alignOf(CodeViewContainer::Pdb));
866 alignedSymbolMem = makeMutableArrayRef(
867 reinterpret_cast<uint8_t *>(alignedData), totalRealignedSize);
1051868 }
1052869
1053870 // Iterate again, this time doing the real work.
1054 unsigned CurSymOffset = File->ModuleDBI->getNextSymbolOffset();
1055 ArrayRef<uint8_t> BulkSymbols;
871 unsigned curSymOffset = file->moduleDBI->getNextSymbolOffset();
872 ArrayRef<uint8_t> bulkSymbols;
1056873 cantFail(forEachCodeViewRecord<CVSymbol>(
1057 SymsBuffer, [&](CVSymbol Sym) -> llvm::Error {
874 symsBuffer, [&](CVSymbol sym) -> llvm::Error {
1058875 // Align the record if required.
1059 MutableArrayRef<uint8_t> RecordBytes;
1060 if (NeedsRealignment) {
1061 RecordBytes = copyAndAlignSymbol(Sym, AlignedSymbolMem);
1062 Sym = CVSymbol(Sym.kind(), RecordBytes);
876 MutableArrayRef<uint8_t> recordBytes;
877 if (needsRealignment) {
878 recordBytes = copyAndAlignSymbol(sym, alignedSymbolMem);
879 sym = CVSymbol(recordBytes);
1063880 } else {
1064881 // Otherwise, we can actually mutate the symbol directly, since we
1065882 // copied it to apply relocations.
1066 RecordBytes = makeMutableArrayRef(
1067 const_cast<uint8_t *>(Sym.data().data()), Sym.length());
883 recordBytes = makeMutableArrayRef(
884 const_cast<uint8_t *>(sym.data().data()), sym.length());
1068885 }
1069886
1070887 // Discover type index references in the record. Skip it if we don't
1071888 // know where they are.
1072 SmallVector<TiReference, 32> TypeRefs;
1073 if (!discoverTypeIndicesInSymbol(Sym, TypeRefs)) {
889 SmallVector<TiReference, 32> typeRefs;
890 if (!discoverTypeIndicesInSymbol(sym, typeRefs)) {
1074891 log("ignoring unknown symbol record with kind 0x" +
1075 utohexstr(Sym.kind()));
892 utohexstr(sym.kind()));
1076893 return Error::success();
1077894 }
1078895
1079896 // Re-map all the type index references.
1080 remapTypesInSymbolRecord(File, Sym.kind(), RecordBytes, IndexMap,
1081 TypeRefs);
897 remapTypesInSymbolRecord(file, sym.kind(), recordBytes, indexMap,
898 typeRefs);
1082899
1083900 // An object file may have S_xxx_ID symbols, but these get converted to
1084901 // "real" symbols in a PDB.
1085 translateIdSymbols(RecordBytes, getIDTable());
1086 Sym = CVSymbol(symbolKind(RecordBytes), RecordBytes);
902 translateIdSymbols(recordBytes, tMerger.getIDTable());
903 sym = CVSymbol(recordBytes);
1087904
1088905 // If this record refers to an offset in the object file's string table,
1089906 // add that item to the global PDB string table and re-write the index.
1090 recordStringTableReferences(Sym.kind(), RecordBytes, StringTableRefs);
907 recordStringTableReferences(sym.kind(), recordBytes, stringTableRefs);
1091908
1092909 // Fill in "Parent" and "End" fields by maintaining a stack of scopes.
1093 if (symbolOpensScope(Sym.kind()))
1094 scopeStackOpen(Scopes, CurSymOffset, Sym);
1095 else if (symbolEndsScope(Sym.kind()))
1096 scopeStackClose(Scopes, CurSymOffset, File);
910 if (symbolOpensScope(sym.kind()))
911 scopeStackOpen(scopes, curSymOffset, sym);
912 else if (symbolEndsScope(sym.kind()))
913 scopeStackClose(scopes, curSymOffset, file);
1097914
1098915 // Add the symbol to the globals stream if necessary. Do this before
1099916 // adding the symbol to the module since we may need to get the next
1100917 // symbol offset, and writing to the module's symbol stream will update
1101918 // that offset.
1102 if (symbolGoesInGlobalsStream(Sym, Scopes.empty()))
1103 addGlobalSymbol(Builder.getGsiBuilder(),
1104 File->ModuleDBI->getModuleIndex(), CurSymOffset, Sym);
919 if (symbolGoesInGlobalsStream(sym, scopes.empty())) {
920 addGlobalSymbol(builder.getGsiBuilder(),
921 file->moduleDBI->getModuleIndex(), curSymOffset, sym);
922 ++globalSymbols;
923 }
1105924
1106 if (symbolGoesInModuleStream(Sym, Scopes.empty())) {
925 if (symbolGoesInModuleStream(sym, scopes.empty())) {
1107926 // Add symbols to the module in bulk. If this symbol is contiguous
1108927 // with the previous run of symbols to add, combine the ranges. If
1109928 // 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());
929 if (sym.data().data() == bulkSymbols.end()) {
930 bulkSymbols = makeArrayRef(bulkSymbols.data(),
931 bulkSymbols.size() + sym.length());
1113932 } else {
1114 File->ModuleDBI->addSymbolsInBulk(BulkSymbols);
1115 BulkSymbols = RecordBytes;
933 file->moduleDBI->addSymbolsInBulk(bulkSymbols);
934 bulkSymbols = recordBytes;
1116935 }
1117 CurSymOffset += Sym.length();
936 curSymOffset += sym.length();
937 ++moduleSymbols;
1118938 }
1119939 return Error::success();
1120940 }));
1121941
1122942 // Add any remaining symbols we've accumulated.
1123 File->ModuleDBI->addSymbolsInBulk(BulkSymbols);
943 file->moduleDBI->addSymbolsInBulk(bulkSymbols);
1124944}
1125945
1126946// Allocate memory for a .debug$S / .debug$F section and relocate it.
1127static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
1128 SectionChunk &DebugChunk) {
1129 uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk.getSize());
1130 assert(DebugChunk.OutputSectionOff == 0 &&
947static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &alloc,
948 SectionChunk &debugChunk) {
949 uint8_t *buffer = alloc.Allocate<uint8_t>(debugChunk.getSize());
950 assert(debugChunk.getOutputSectionIdx() == 0 &&
1131951 "debug sections should not be in output sections");
1132 DebugChunk.readRelocTargets();
1133 DebugChunk.writeTo(Buffer);
1134 return makeArrayRef(Buffer, DebugChunk.getSize());
952 debugChunk.writeTo(buffer);
953 return makeArrayRef(buffer, debugChunk.getSize());
1135954}
1136955
1137static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
1138 OutputSection *OS = C->getOutputSection();
1139 pdb::SectionContrib SC;
1140 memset(&SC, 0, sizeof(SC));
1141 SC.ISect = OS->SectionIndex;
1142 SC.Off = C->getRVA() - OS->getRVA();
1143 SC.Size = C->getSize();
1144 if (auto *SecChunk = dyn_cast<SectionChunk>(C)) {
1145 SC.Characteristics = SecChunk->Header->Characteristics;
1146 SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex();
1147 ArrayRef<uint8_t> Contents = SecChunk->getContents();
1148 JamCRC CRC(0);
1149 ArrayRef<char> CharContents = makeArrayRef(
1150 reinterpret_cast<const char *>(Contents.data()), Contents.size());
1151 CRC.update(CharContents);
1152 SC.DataCrc = CRC.getCRC();
956static pdb::SectionContrib createSectionContrib(const Chunk *c, uint32_t modi) {
957 OutputSection *os = c ? c->getOutputSection() : nullptr;
958 pdb::SectionContrib sc;
959 memset(&sc, 0, sizeof(sc));
960 sc.ISect = os ? os->sectionIndex : llvm::pdb::kInvalidStreamIndex;
961 sc.Off = c && os ? c->getRVA() - os->getRVA() : 0;
962 sc.Size = c ? c->getSize() : -1;
963 if (auto *secChunk = dyn_cast_or_null<SectionChunk>(c)) {
964 sc.Characteristics = secChunk->header->Characteristics;
965 sc.Imod = secChunk->file->moduleDBI->getModuleIndex();
966 ArrayRef<uint8_t> contents = secChunk->getContents();
967 JamCRC crc(0);
968 ArrayRef<char> charContents = makeArrayRef(
969 reinterpret_cast<const char *>(contents.data()), contents.size());
970 crc.update(charContents);
971 sc.DataCrc = crc.getCRC();
1153972 } else {
1154 SC.Characteristics = OS->Header.Characteristics;
1155 // FIXME: When we start creating DBI for import libraries, use those here.
1156 SC.Imod = Modi;
973 sc.Characteristics = os ? os->header.Characteristics : 0;
974 sc.Imod = modi;
1157975 }
1158 SC.RelocCrc = 0; // FIXME
976 sc.RelocCrc = 0; // FIXME
1159977
1160 return SC;
978 return sc;
1161979}
1162980
1163981static uint32_t
1164translateStringTableIndex(uint32_t ObjIndex,
1165 const DebugStringTableSubsectionRef &ObjStrTable,
1166 DebugStringTableSubsection &PdbStrTable) {
1167 auto ExpectedString = ObjStrTable.getString(ObjIndex);
1168 if (!ExpectedString) {
982translateStringTableIndex(uint32_t objIndex,
983 const DebugStringTableSubsectionRef &objStrTable,
984 DebugStringTableSubsection &pdbStrTable) {
985 auto expectedString = objStrTable.getString(objIndex);
986 if (!expectedString) {
1169987 warn("Invalid string table reference");
1170 consumeError(ExpectedString.takeError());
988 consumeError(expectedString.takeError());
1171989 return 0;
1172990 }
1173991
1174 return PdbStrTable.insert(*ExpectedString);
992 return pdbStrTable.insert(*expectedString);
1175993}
1176994
1177void DebugSHandler::handleDebugS(lld::coff::SectionChunk &DebugS) {
1178 DebugSubsectionArray Subsections;
995void DebugSHandler::handleDebugS(lld::coff::SectionChunk &debugS) {
996 DebugSubsectionArray subsections;
997
998 ArrayRef<uint8_t> relocatedDebugContents = SectionChunk::consumeDebugMagic(
999 relocateDebugChunk(linker.alloc, debugS), debugS.getSectionName());
11791000
1180 ArrayRef<uint8_t> RelocatedDebugContents = consumeDebugMagic(
1181 relocateDebugChunk(Linker.Alloc, DebugS), DebugS.getSectionName());
1001 BinaryStreamReader reader(relocatedDebugContents, support::little);
1002 exitOnErr(reader.readArray(subsections, relocatedDebugContents.size()));
11821003
1183 BinaryStreamReader Reader(RelocatedDebugContents, support::little);
1184 ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
1004 for (const DebugSubsectionRecord &ss : subsections) {
1005 // Ignore subsections with the 'ignore' bit. Some versions of the Visual C++
1006 // runtime have subsections with this bit set.
1007 if (uint32_t(ss.kind()) & codeview::SubsectionIgnoreFlag)
1008 continue;
11851009
1186 for (const DebugSubsectionRecord &SS : Subsections) {
1187 switch (SS.kind()) {
1010 switch (ss.kind()) {
11881011 case DebugSubsectionKind::StringTable: {
1189 assert(!CVStrTab.valid() &&
1012 assert(!cVStrTab.valid() &&
11901013 "Encountered multiple string table subsections!");
1191 ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
1014 exitOnErr(cVStrTab.initialize(ss.getRecordData()));
11921015 break;
11931016 }
11941017 case DebugSubsectionKind::FileChecksums:
1195 assert(!Checksums.valid() &&
1018 assert(!checksums.valid() &&
11961019 "Encountered multiple checksum subsections!");
1197 ExitOnErr(Checksums.initialize(SS.getRecordData()));
1020 exitOnErr(checksums.initialize(ss.getRecordData()));
11981021 break;
11991022 case DebugSubsectionKind::Lines:
12001023 // We can add the relocated line table directly to the PDB without
12011024 // modification because the file checksum offsets will stay the same.
1202 File.ModuleDBI->addDebugSubsection(SS);
1025 file.moduleDBI->addDebugSubsection(ss);
1026 break;
1027 case DebugSubsectionKind::InlineeLines:
1028 assert(!inlineeLines.valid() &&
1029 "Encountered multiple inlinee lines subsections!");
1030 exitOnErr(inlineeLines.initialize(ss.getRecordData()));
12031031 break;
12041032 case DebugSubsectionKind::FrameData: {
12051033 // We need to re-write string table indices here, so save off all
12061034 // frame data subsections until we've processed the entire list of
12071035 // 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));
1036 DebugFrameDataSubsectionRef fds;
1037 exitOnErr(fds.initialize(ss.getRecordData()));
1038 newFpoFrames.push_back(std::move(fds));
12111039 break;
12121040 }
12131041 case DebugSubsectionKind::Symbols: {
1214 Linker.mergeSymbolRecords(&File, IndexMap, StringTableReferences,
1215 SS.getRecordData());
1042 linker.mergeSymbolRecords(&file, indexMap, stringTableReferences,
1043 ss.getRecordData());
12161044 break;
12171045 }
1046
1047 case DebugSubsectionKind::CrossScopeImports:
1048 case DebugSubsectionKind::CrossScopeExports:
1049 // These appear to relate to cross-module optimization, so we might use
1050 // these for ThinLTO.
1051 break;
1052
1053 case DebugSubsectionKind::ILLines:
1054 case DebugSubsectionKind::FuncMDTokenMap:
1055 case DebugSubsectionKind::TypeMDTokenMap:
1056 case DebugSubsectionKind::MergedAssemblyInput:
1057 // These appear to relate to .Net assembly info.
1058 break;
1059
1060 case DebugSubsectionKind::CoffSymbolRVA:
1061 // Unclear what this is for.
1062 break;
1063
12181064 default:
1219 // FIXME: Process the rest of the subsections.
1065 warn("ignoring unknown debug$S subsection kind 0x" +
1066 utohexstr(uint32_t(ss.kind())) + " in file " + toString(&file));
12201067 break;
12211068 }
12221069 }
12231070}
12241071
1072static Expected<StringRef>
1073getFileName(const DebugStringTableSubsectionRef &strings,
1074 const DebugChecksumsSubsectionRef &checksums, uint32_t fileID) {
1075 auto iter = checksums.getArray().at(fileID);
1076 if (iter == checksums.getArray().end())
1077 return make_error<CodeViewError>(cv_error_code::no_records);
1078 uint32_t offset = iter->FileNameOffset;
1079 return strings.getString(offset);
1080}
1081
1082std::shared_ptr<DebugInlineeLinesSubsection>
1083DebugSHandler::mergeInlineeLines(DebugChecksumsSubsection *newChecksums) {
1084 auto newInlineeLines = std::make_shared<DebugInlineeLinesSubsection>(
1085 *newChecksums, inlineeLines.hasExtraFiles());
1086
1087 for (const InlineeSourceLine &line : inlineeLines) {
1088 TypeIndex inlinee = line.Header->Inlinee;
1089 uint32_t fileID = line.Header->FileID;
1090 uint32_t sourceLine = line.Header->SourceLineNum;
1091
1092 ArrayRef<TypeIndex> typeOrItemMap =
1093 indexMap.isTypeServerMap ? indexMap.ipiMap : indexMap.tpiMap;
1094 if (!remapTypeIndex(inlinee, typeOrItemMap)) {
1095 log("ignoring inlinee line record in " + file.getName() +
1096 " with bad inlinee index 0x" + utohexstr(inlinee.getIndex()));
1097 continue;
1098 }
1099
1100 SmallString<128> filename =
1101 exitOnErr(getFileName(cVStrTab, checksums, fileID));
1102 pdbMakeAbsolute(filename);
1103 newInlineeLines->addInlineSite(inlinee, filename, sourceLine);
1104
1105 if (inlineeLines.hasExtraFiles()) {
1106 for (uint32_t extraFileId : line.ExtraFiles) {
1107 filename = exitOnErr(getFileName(cVStrTab, checksums, extraFileId));
1108 pdbMakeAbsolute(filename);
1109 newInlineeLines->addExtraFile(filename);
1110 }
1111 }
1112 }
1113
1114 return newInlineeLines;
1115}
1116
12251117void DebugSHandler::finish() {
1226 pdb::DbiStreamBuilder &DbiBuilder = Linker.Builder.getDbiBuilder();
1118 pdb::DbiStreamBuilder &dbiBuilder = linker.builder.getDbiBuilder();
12271119
12281120 // We should have seen all debug subsections across the entire object file now
12291121 // which means that if a StringTable subsection and Checksums subsection were
12301122 // present, now is the time to handle them.
1231 if (!CVStrTab.valid()) {
1232 if (Checksums.valid())
1123 if (!cVStrTab.valid()) {
1124 if (checksums.valid())
12331125 fatal(".debug$S sections with a checksums subsection must also contain a "
12341126 "string table subsection");
12351127
1236 if (!StringTableReferences.empty())
1128 if (!stringTableReferences.empty())
12371129 warn("No StringTable subsection was encountered, but there are string "
12381130 "table references");
12391131 return;
......@@ -1241,186 +1133,231 @@ void DebugSHandler::finish() {
12411133
12421134 // Rewrite string table indices in the Fpo Data and symbol records to refer to
12431135 // 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);
1136 for (DebugFrameDataSubsectionRef &fds : newFpoFrames) {
1137 const ulittle32_t *reloc = fds.getRelocPtr();
1138 for (codeview::FrameData fd : fds) {
1139 fd.RvaStart += *reloc;
1140 fd.FrameFunc =
1141 translateStringTableIndex(fd.FrameFunc, cVStrTab, linker.pdbStrTab);
1142 dbiBuilder.addNewFpoData(fd);
12511143 }
12521144 }
12531145
1254 for (ulittle32_t *Ref : StringTableReferences)
1255 *Ref = translateStringTableIndex(*Ref, CVStrTab, Linker.PDBStrTab);
1146 for (ulittle32_t *ref : stringTableReferences)
1147 *ref = translateStringTableIndex(*ref, cVStrTab, linker.pdbStrTab);
12561148
12571149 // Make a new file checksum table that refers to offsets in the PDB-wide
12581150 // string table. Generally the string table subsection appears after the
12591151 // checksum table, so we have to do this after looping over all the
12601152 // 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);
1153 auto newChecksums = make_unique<DebugChecksumsSubsection>(linker.pdbStrTab);
1154 for (FileChecksumEntry &fc : checksums) {
1155 SmallString<128> filename =
1156 exitOnErr(cVStrTab.getString(fc.FileNameOffset));
1157 pdbMakeAbsolute(filename);
1158 exitOnErr(dbiBuilder.addModuleSourceFile(*file.moduleDBI, filename));
1159 newChecksums->addChecksum(filename, fc.Kind, fc.Checksum);
12691160 }
1270 File.ModuleDBI->addDebugSubsection(std::move(NewChecksums));
1161
1162 // Rewrite inlinee item indices if present.
1163 if (inlineeLines.valid())
1164 file.moduleDBI->addDebugSubsection(mergeInlineeLines(newChecksums.get()));
1165
1166 file.moduleDBI->addDebugSubsection(std::move(newChecksums));
12711167}
12721168
1273void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) {
1274 if (File->wasProcessedForPDB())
1169void PDBLinker::addObjFile(ObjFile *file, CVIndexMap *externIndexMap) {
1170 if (file->mergedIntoPDB)
12751171 return;
1276 // Add a module descriptor for every object file. We need to put an absolute
1277 // path to the object into the PDB. If this is a plain object, we make its
1278 // path absolute. If it's an object in an archive, we make the archive path
1279 // absolute.
1280 bool InArchive = !File->ParentName.empty();
1281 SmallString<128> Path = InArchive ? File->ParentName : File->getName();
1282 pdbMakeAbsolute(Path);
1283 StringRef Name = InArchive ? File->getName() : StringRef(Path);
1284
1285 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
1286 File->ModuleDBI = &ExitOnErr(DbiBuilder.addModuleInfo(Name));
1287 File->ModuleDBI->setObjFileName(Path);
1288
1289 auto Chunks = File->getChunks();
1290 uint32_t Modi = File->ModuleDBI->getModuleIndex();
1291 for (Chunk *C : Chunks) {
1292 auto *SecChunk = dyn_cast<SectionChunk>(C);
1293 if (!SecChunk || !SecChunk->Live)
1294 continue;
1295 pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi);
1296 File->ModuleDBI->setFirstSectionContrib(SC);
1297 break;
1298 }
1172 file->mergedIntoPDB = true;
12991173
13001174 // Before we can process symbol substreams from .debug$S, we need to process
13011175 // type information, file checksums, and the string table. Add type info to
13021176 // the PDB first, so that we can get the map from object file type and item
13031177 // indices to PDB type and item indices.
1304 CVIndexMap ObjectIndexMap;
1305 auto IndexMapResult =
1306 mergeDebugT(File, ExternIndexMap ? ExternIndexMap : &ObjectIndexMap);
1178 CVIndexMap objectIndexMap;
1179 auto indexMapResult =
1180 mergeDebugT(file, externIndexMap ? externIndexMap : &objectIndexMap);
13071181
13081182 // If the .debug$T sections fail to merge, assume there is no debug info.
1309 if (!IndexMapResult) {
1310 if (!Config->WarnDebugInfoUnusable) {
1311 consumeError(IndexMapResult.takeError());
1183 if (!indexMapResult) {
1184 if (!config->warnDebugInfoUnusable) {
1185 consumeError(indexMapResult.takeError());
13121186 return;
13131187 }
1314 StringRef FileName = sys::path::filename(Path);
1315 warn("Cannot use debug info for '" + FileName + "' [LNK4099]\n" +
1188 warn("Cannot use debug info for '" + toString(file) + "' [LNK4099]\n" +
13161189 ">>> failed to load reference " +
1317 StringRef(toString(IndexMapResult.takeError())));
1190 StringRef(toString(indexMapResult.takeError())));
13181191 return;
13191192 }
13201193
1321 ScopedTimer T(SymbolMergingTimer);
1194 ScopedTimer t(symbolMergingTimer);
13221195
1323 DebugSHandler DSH(*this, *File, *IndexMapResult);
1196 pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();
1197 DebugSHandler dsh(*this, *file, *indexMapResult);
13241198 // Now do all live .debug$S and .debug$F sections.
1325 for (SectionChunk *DebugChunk : File->getDebugChunks()) {
1326 if (!DebugChunk->Live || DebugChunk->getSize() == 0)
1199 for (SectionChunk *debugChunk : file->getDebugChunks()) {
1200 if (!debugChunk->live || debugChunk->getSize() == 0)
13271201 continue;
13281202
1329 if (DebugChunk->getSectionName() == ".debug$S") {
1330 DSH.handleDebugS(*DebugChunk);
1203 if (debugChunk->getSectionName() == ".debug$S") {
1204 dsh.handleDebugS(*debugChunk);
13311205 continue;
13321206 }
13331207
1334 if (DebugChunk->getSectionName() == ".debug$F") {
1335 ArrayRef<uint8_t> RelocatedDebugContents =
1336 relocateDebugChunk(Alloc, *DebugChunk);
1208 if (debugChunk->getSectionName() == ".debug$F") {
1209 ArrayRef<uint8_t> relocatedDebugContents =
1210 relocateDebugChunk(alloc, *debugChunk);
13371211
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));
1212 FixedStreamArray<object::FpoData> fpoRecords;
1213 BinaryStreamReader reader(relocatedDebugContents, support::little);
1214 uint32_t count = relocatedDebugContents.size() / sizeof(object::FpoData);
1215 exitOnErr(reader.readArray(fpoRecords, count));
13421216
13431217 // These are already relocated and don't refer to the string table, so we
13441218 // can just copy it.
1345 for (const object::FpoData &FD : FpoRecords)
1346 DbiBuilder.addOldFpoData(FD);
1219 for (const object::FpoData &fd : fpoRecords)
1220 dbiBuilder.addOldFpoData(fd);
13471221 continue;
13481222 }
13491223 }
13501224
13511225 // Do any post-processing now that all .debug$S sections have been processed.
1352 DSH.finish();
1226 dsh.finish();
13531227}
13541228
1355static PublicSym32 createPublic(Defined *Def) {
1356 PublicSym32 Pub(SymbolKind::S_PUB32);
1357 Pub.Name = Def->getName();
1358 if (auto *D = dyn_cast<DefinedCOFF>(Def)) {
1359 if (D->getCOFFSymbol().isFunctionDefinition())
1360 Pub.Flags = PublicSymFlags::Function;
1361 } else if (isa<DefinedImportThunk>(Def)) {
1362 Pub.Flags = PublicSymFlags::Function;
1229// Add a module descriptor for every object file. We need to put an absolute
1230// path to the object into the PDB. If this is a plain object, we make its
1231// path absolute. If it's an object in an archive, we make the archive path
1232// absolute.
1233static void createModuleDBI(pdb::PDBFileBuilder &builder) {
1234 pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();
1235 SmallString<128> objName;
1236
1237 for (ObjFile *file : ObjFile::instances) {
1238
1239 bool inArchive = !file->parentName.empty();
1240 objName = inArchive ? file->parentName : file->getName();
1241 pdbMakeAbsolute(objName);
1242 StringRef modName = inArchive ? file->getName() : StringRef(objName);
1243
1244 file->moduleDBI = &exitOnErr(dbiBuilder.addModuleInfo(modName));
1245 file->moduleDBI->setObjFileName(objName);
1246
1247 ArrayRef<Chunk *> chunks = file->getChunks();
1248 uint32_t modi = file->moduleDBI->getModuleIndex();
1249
1250 for (Chunk *c : chunks) {
1251 auto *secChunk = dyn_cast<SectionChunk>(c);
1252 if (!secChunk || !secChunk->live)
1253 continue;
1254 pdb::SectionContrib sc = createSectionContrib(secChunk, modi);
1255 file->moduleDBI->setFirstSectionContrib(sc);
1256 break;
1257 }
13631258 }
1259}
13641260
1365 OutputSection *OS = Def->getChunk()->getOutputSection();
1366 assert(OS && "all publics should be in final image");
1367 Pub.Offset = Def->getRVA() - OS->getRVA();
1368 Pub.Segment = OS->SectionIndex;
1369 return Pub;
1261static PublicSym32 createPublic(Defined *def) {
1262 PublicSym32 pub(SymbolKind::S_PUB32);
1263 pub.Name = def->getName();
1264 if (auto *d = dyn_cast<DefinedCOFF>(def)) {
1265 if (d->getCOFFSymbol().isFunctionDefinition())
1266 pub.Flags = PublicSymFlags::Function;
1267 } else if (isa<DefinedImportThunk>(def)) {
1268 pub.Flags = PublicSymFlags::Function;
1269 }
1270
1271 OutputSection *os = def->getChunk()->getOutputSection();
1272 assert(os && "all publics should be in final image");
1273 pub.Offset = def->getRVA() - os->getRVA();
1274 pub.Segment = os->sectionIndex;
1275 return pub;
13701276}
13711277
13721278// Add all object files to the PDB. Merge .debug$T sections into IpiData and
13731279// TpiData.
13741280void PDBLinker::addObjectsToPDB() {
1375 ScopedTimer T1(AddObjectsTimer);
1376 for (ObjFile *File : ObjFile::Instances)
1377 addObjFile(File);
1281 ScopedTimer t1(addObjectsTimer);
1282
1283 createModuleDBI(builder);
13781284
1379 Builder.getStringTableBuilder().setStrings(PDBStrTab);
1380 T1.stop();
1285 for (ObjFile *file : ObjFile::instances)
1286 addObjFile(file);
1287
1288 builder.getStringTableBuilder().setStrings(pdbStrTab);
1289 t1.stop();
13811290
13821291 // Construct TPI and IPI stream contents.
1383 ScopedTimer T2(TpiStreamLayoutTimer);
1384 addTypeInfo(Builder.getTpiBuilder(), getTypeTable());
1385 addTypeInfo(Builder.getIpiBuilder(), getIDTable());
1386 T2.stop();
1292 ScopedTimer t2(tpiStreamLayoutTimer);
1293 addTypeInfo(builder.getTpiBuilder(), tMerger.getTypeTable());
1294 addTypeInfo(builder.getIpiBuilder(), tMerger.getIDTable());
1295 t2.stop();
13871296
1388 ScopedTimer T3(GlobalsLayoutTimer);
1297 ScopedTimer t3(globalsLayoutTimer);
13891298 // Compute the public and global symbols.
1390 auto &GsiBuilder = Builder.getGsiBuilder();
1391 std::vector<PublicSym32> Publics;
1392 Symtab->forEachSymbol([&Publics](Symbol *S) {
1299 auto &gsiBuilder = builder.getGsiBuilder();
1300 std::vector<PublicSym32> publics;
1301 symtab->forEachSymbol([&publics](Symbol *s) {
13931302 // Only emit defined, live symbols that have a chunk.
1394 auto *Def = dyn_cast<Defined>(S);
1395 if (Def && Def->isLive() && Def->getChunk())
1396 Publics.push_back(createPublic(Def));
1303 auto *def = dyn_cast<Defined>(s);
1304 if (def && def->isLive() && def->getChunk())
1305 publics.push_back(createPublic(def));
13971306 });
13981307
1399 if (!Publics.empty()) {
1308 if (!publics.empty()) {
1309 publicSymbols = publics.size();
14001310 // Sort the public symbols and add them to the stream.
1401 sort(parallel::par, Publics.begin(), Publics.end(),
1402 [](const PublicSym32 &L, const PublicSym32 &R) {
1403 return L.Name < R.Name;
1404 });
1405 for (const PublicSym32 &Pub : Publics)
1406 GsiBuilder.addPublicSymbol(Pub);
1311 parallelSort(publics, [](const PublicSym32 &l, const PublicSym32 &r) {
1312 return l.Name < r.Name;
1313 });
1314 for (const PublicSym32 &pub : publics)
1315 gsiBuilder.addPublicSymbol(pub);
14071316 }
14081317}
14091318
1319void PDBLinker::printStats() {
1320 if (!config->showSummary)
1321 return;
1322
1323 SmallString<256> buffer;
1324 raw_svector_ostream stream(buffer);
1325
1326 stream << center_justify("Summary", 80) << '\n'
1327 << std::string(80, '-') << '\n';
1328
1329 auto print = [&](uint64_t v, StringRef s) {
1330 stream << format_decimal(v, 15) << " " << s << '\n';
1331 };
1332
1333 print(ObjFile::instances.size(),
1334 "Input OBJ files (expanded from all cmd-line inputs)");
1335 print(typeServerIndexMappings.size(), "PDB type server dependencies");
1336 print(precompTypeIndexMappings.size(), "Precomp OBJ dependencies");
1337 print(tMerger.getTypeTable().size() + tMerger.getIDTable().size(),
1338 "Merged TPI records");
1339 print(pdbStrTab.size(), "Output PDB strings");
1340 print(globalSymbols, "Global symbol records");
1341 print(moduleSymbols, "Module symbol records");
1342 print(publicSymbols, "Public symbol records");
1343
1344 message(buffer);
1345}
1346
14101347void PDBLinker::addNatvisFiles() {
1411 for (StringRef File : Config->NatvisFiles) {
1412 ErrorOr<std::unique_ptr<MemoryBuffer>> DataOrErr =
1413 MemoryBuffer::getFile(File);
1414 if (!DataOrErr) {
1415 warn("Cannot open input file: " + File);
1348 for (StringRef file : config->natvisFiles) {
1349 ErrorOr<std::unique_ptr<MemoryBuffer>> dataOrErr =
1350 MemoryBuffer::getFile(file);
1351 if (!dataOrErr) {
1352 warn("Cannot open input file: " + file);
14161353 continue;
14171354 }
1418 Builder.addInjectedSource(File, std::move(*DataOrErr));
1355 builder.addInjectedSource(file, std::move(*dataOrErr));
14191356 }
14201357}
14211358
1422static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) {
1423 switch (Machine) {
1359static codeview::CPUType toCodeViewMachine(COFF::MachineTypes machine) {
1360 switch (machine) {
14241361 case COFF::IMAGE_FILE_MACHINE_AMD64:
14251362 return codeview::CPUType::X64;
14261363 case COFF::IMAGE_FILE_MACHINE_ARM:
......@@ -1439,201 +1376,329 @@ static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) {
14391376// Mimic MSVC which surrounds arguments containing whitespace with quotes.
14401377// Double double-quotes are handled, so that the resulting string can be
14411378// 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, "\"\""));
1379static std::string quote(ArrayRef<StringRef> args) {
1380 std::string r;
1381 r.reserve(256);
1382 for (StringRef a : args) {
1383 if (!r.empty())
1384 r.push_back(' ');
1385 bool hasWS = a.find(' ') != StringRef::npos;
1386 bool hasQ = a.find('"') != StringRef::npos;
1387 if (hasWS || hasQ)
1388 r.push_back('"');
1389 if (hasQ) {
1390 SmallVector<StringRef, 4> s;
1391 a.split(s, '"');
1392 r.append(join(s, "\"\""));
14561393 } else {
1457 R.append(A);
1394 r.append(a);
14581395 }
1459 if (HasWS || HasQ)
1460 R.push_back('"');
1396 if (hasWS || hasQ)
1397 r.push_back('"');
14611398 }
1462 return R;
1399 return r;
14631400}
14641401
1465static void addCommonLinkerModuleSymbols(StringRef Path,
1466 pdb::DbiModuleDescriptorBuilder &Mod,
1467 BumpPtrAllocator &Allocator) {
1468 ObjNameSym ONS(SymbolRecordKind::ObjNameSym);
1469 Compile3Sym CS(SymbolRecordKind::Compile3Sym);
1470 EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym);
1471
1472 ONS.Name = "* Linker *";
1473 ONS.Signature = 0;
1474
1475 CS.Machine = toCodeViewMachine(Config->Machine);
1402static void fillLinkerVerRecord(Compile3Sym &cs) {
1403 cs.Machine = toCodeViewMachine(config->machine);
14761404 // Interestingly, if we set the string to 0.0.0.0, then when trying to view
14771405 // local variables WinDbg emits an error that private symbols are not present.
14781406 // By setting this to a valid MSVC linker version string, local variables are
14791407 // displayed properly. As such, even though it is not representative of
14801408 // LLVM's version information, we need this for compatibility.
1481 CS.Flags = CompileSym3Flags::None;
1482 CS.VersionBackendBuild = 25019;
1483 CS.VersionBackendMajor = 14;
1484 CS.VersionBackendMinor = 10;
1485 CS.VersionBackendQFE = 0;
1409 cs.Flags = CompileSym3Flags::None;
1410 cs.VersionBackendBuild = 25019;
1411 cs.VersionBackendMajor = 14;
1412 cs.VersionBackendMinor = 10;
1413 cs.VersionBackendQFE = 0;
14861414
14871415 // MSVC also sets the frontend to 0.0.0.0 since this is specifically for the
14881416 // linker module (which is by definition a backend), so we don't need to do
14891417 // anything here. Also, it seems we can use "LLVM Linker" for the linker name
14901418 // without any problems. Only the backend version has to be hardcoded to a
14911419 // magic number.
1492 CS.VersionFrontendBuild = 0;
1493 CS.VersionFrontendMajor = 0;
1494 CS.VersionFrontendMinor = 0;
1495 CS.VersionFrontendQFE = 0;
1496 CS.Version = "LLVM Linker";
1497 CS.setLanguage(SourceLanguage::Link);
1498
1499 ArrayRef<StringRef> Args = makeArrayRef(Config->Argv).drop_front();
1500 std::string ArgStr = quote(Args);
1501 EBS.Fields.push_back("cwd");
1420 cs.VersionFrontendBuild = 0;
1421 cs.VersionFrontendMajor = 0;
1422 cs.VersionFrontendMinor = 0;
1423 cs.VersionFrontendQFE = 0;
1424 cs.Version = "LLVM Linker";
1425 cs.setLanguage(SourceLanguage::Link);
1426}
1427
1428static void addCommonLinkerModuleSymbols(StringRef path,
1429 pdb::DbiModuleDescriptorBuilder &mod,
1430 BumpPtrAllocator &allocator) {
1431 ObjNameSym ons(SymbolRecordKind::ObjNameSym);
1432 EnvBlockSym ebs(SymbolRecordKind::EnvBlockSym);
1433 Compile3Sym cs(SymbolRecordKind::Compile3Sym);
1434 fillLinkerVerRecord(cs);
1435
1436 ons.Name = "* Linker *";
1437 ons.Signature = 0;
1438
1439 ArrayRef<StringRef> args = makeArrayRef(config->argv).drop_front();
1440 std::string argStr = quote(args);
1441 ebs.Fields.push_back("cwd");
15021442 SmallString<64> cwd;
1503 if (Config->PDBSourcePath.empty())
1443 if (config->pdbSourcePath.empty())
15041444 sys::fs::current_path(cwd);
15051445 else
1506 cwd = Config->PDBSourcePath;
1507 EBS.Fields.push_back(cwd);
1508 EBS.Fields.push_back("exe");
1509 SmallString<64> exe = Config->Argv[0];
1446 cwd = config->pdbSourcePath;
1447 ebs.Fields.push_back(cwd);
1448 ebs.Fields.push_back("exe");
1449 SmallString<64> exe = config->argv[0];
15101450 pdbMakeAbsolute(exe);
1511 EBS.Fields.push_back(exe);
1512 EBS.Fields.push_back("pdb");
1513 EBS.Fields.push_back(Path);
1514 EBS.Fields.push_back("cmd");
1515 EBS.Fields.push_back(ArgStr);
1516 Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1517 ONS, Allocator, CodeViewContainer::Pdb));
1518 Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1519 CS, Allocator, CodeViewContainer::Pdb));
1520 Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1521 EBS, Allocator, CodeViewContainer::Pdb));
1451 ebs.Fields.push_back(exe);
1452 ebs.Fields.push_back("pdb");
1453 ebs.Fields.push_back(path);
1454 ebs.Fields.push_back("cmd");
1455 ebs.Fields.push_back(argStr);
1456 mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1457 ons, allocator, CodeViewContainer::Pdb));
1458 mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1459 cs, allocator, CodeViewContainer::Pdb));
1460 mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1461 ebs, allocator, CodeViewContainer::Pdb));
1462}
1463
1464static void addLinkerModuleCoffGroup(PartialSection *sec,
1465 pdb::DbiModuleDescriptorBuilder &mod,
1466 OutputSection &os,
1467 BumpPtrAllocator &allocator) {
1468 // If there's a section, there's at least one chunk
1469 assert(!sec->chunks.empty());
1470 const Chunk *firstChunk = *sec->chunks.begin();
1471 const Chunk *lastChunk = *sec->chunks.rbegin();
1472
1473 // Emit COFF group
1474 CoffGroupSym cgs(SymbolRecordKind::CoffGroupSym);
1475 cgs.Name = sec->name;
1476 cgs.Segment = os.sectionIndex;
1477 cgs.Offset = firstChunk->getRVA() - os.getRVA();
1478 cgs.Size = lastChunk->getRVA() + lastChunk->getSize() - firstChunk->getRVA();
1479 cgs.Characteristics = sec->characteristics;
1480
1481 // Somehow .idata sections & sections groups in the debug symbol stream have
1482 // the "write" flag set. However the section header for the corresponding
1483 // .idata section doesn't have it.
1484 if (cgs.Name.startswith(".idata"))
1485 cgs.Characteristics |= llvm::COFF::IMAGE_SCN_MEM_WRITE;
1486
1487 mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1488 cgs, allocator, CodeViewContainer::Pdb));
1489}
1490
1491static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &mod,
1492 OutputSection &os,
1493 BumpPtrAllocator &allocator) {
1494 SectionSym sym(SymbolRecordKind::SectionSym);
1495 sym.Alignment = 12; // 2^12 = 4KB
1496 sym.Characteristics = os.header.Characteristics;
1497 sym.Length = os.getVirtualSize();
1498 sym.Name = os.name;
1499 sym.Rva = os.getRVA();
1500 sym.SectionNumber = os.sectionIndex;
1501 mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1502 sym, allocator, CodeViewContainer::Pdb));
1503
1504 // Skip COFF groups in MinGW because it adds a significant footprint to the
1505 // PDB, due to each function being in its own section
1506 if (config->mingw)
1507 return;
1508
1509 // Output COFF groups for individual chunks of this section.
1510 for (PartialSection *sec : os.contribSections) {
1511 addLinkerModuleCoffGroup(sec, mod, os, allocator);
1512 }
15221513}
15231514
1524static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod,
1525 OutputSection &OS,
1526 BumpPtrAllocator &Allocator) {
1527 SectionSym Sym(SymbolRecordKind::SectionSym);
1528 Sym.Alignment = 12; // 2^12 = 4KB
1529 Sym.Characteristics = OS.Header.Characteristics;
1530 Sym.Length = OS.getVirtualSize();
1531 Sym.Name = OS.Name;
1532 Sym.Rva = OS.getRVA();
1533 Sym.SectionNumber = OS.SectionIndex;
1534 Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1535 Sym, Allocator, CodeViewContainer::Pdb));
1515// Add all import files as modules to the PDB.
1516void PDBLinker::addImportFilesToPDB(ArrayRef<OutputSection *> outputSections) {
1517 if (ImportFile::instances.empty())
1518 return;
1519
1520 std::map<std::string, llvm::pdb::DbiModuleDescriptorBuilder *> dllToModuleDbi;
1521
1522 for (ImportFile *file : ImportFile::instances) {
1523 if (!file->live)
1524 continue;
1525
1526 if (!file->thunkSym)
1527 continue;
1528
1529 if (!file->thunkLive)
1530 continue;
1531
1532 std::string dll = StringRef(file->dllName).lower();
1533 llvm::pdb::DbiModuleDescriptorBuilder *&mod = dllToModuleDbi[dll];
1534 if (!mod) {
1535 pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();
1536 SmallString<128> libPath = file->parentName;
1537 pdbMakeAbsolute(libPath);
1538 sys::path::native(libPath);
1539
1540 // Name modules similar to MSVC's link.exe.
1541 // The first module is the simple dll filename
1542 llvm::pdb::DbiModuleDescriptorBuilder &firstMod =
1543 exitOnErr(dbiBuilder.addModuleInfo(file->dllName));
1544 firstMod.setObjFileName(libPath);
1545 pdb::SectionContrib sc =
1546 createSectionContrib(nullptr, llvm::pdb::kInvalidStreamIndex);
1547 firstMod.setFirstSectionContrib(sc);
1548
1549 // The second module is where the import stream goes.
1550 mod = &exitOnErr(dbiBuilder.addModuleInfo("Import:" + file->dllName));
1551 mod->setObjFileName(libPath);
1552 }
1553
1554 DefinedImportThunk *thunk = cast<DefinedImportThunk>(file->thunkSym);
1555 Chunk *thunkChunk = thunk->getChunk();
1556 OutputSection *thunkOS = thunkChunk->getOutputSection();
1557
1558 ObjNameSym ons(SymbolRecordKind::ObjNameSym);
1559 Compile3Sym cs(SymbolRecordKind::Compile3Sym);
1560 Thunk32Sym ts(SymbolRecordKind::Thunk32Sym);
1561 ScopeEndSym es(SymbolRecordKind::ScopeEndSym);
1562
1563 ons.Name = file->dllName;
1564 ons.Signature = 0;
1565
1566 fillLinkerVerRecord(cs);
1567
1568 ts.Name = thunk->getName();
1569 ts.Parent = 0;
1570 ts.End = 0;
1571 ts.Next = 0;
1572 ts.Thunk = ThunkOrdinal::Standard;
1573 ts.Length = thunkChunk->getSize();
1574 ts.Segment = thunkOS->sectionIndex;
1575 ts.Offset = thunkChunk->getRVA() - thunkOS->getRVA();
1576
1577 mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1578 ons, alloc, CodeViewContainer::Pdb));
1579 mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(
1580 cs, alloc, CodeViewContainer::Pdb));
1581
1582 SmallVector<SymbolScope, 4> scopes;
1583 CVSymbol newSym = codeview::SymbolSerializer::writeOneSymbol(
1584 ts, alloc, CodeViewContainer::Pdb);
1585 scopeStackOpen(scopes, mod->getNextSymbolOffset(), newSym);
1586
1587 mod->addSymbol(newSym);
1588
1589 newSym = codeview::SymbolSerializer::writeOneSymbol(es, alloc,
1590 CodeViewContainer::Pdb);
1591 scopeStackClose(scopes, mod->getNextSymbolOffset(), file);
1592
1593 mod->addSymbol(newSym);
1594
1595 pdb::SectionContrib sc =
1596 createSectionContrib(thunk->getChunk(), mod->getModuleIndex());
1597 mod->setFirstSectionContrib(sc);
1598 }
15361599}
15371600
15381601// Creates a PDB file.
1539void coff::createPDB(SymbolTable *Symtab,
1540 ArrayRef<OutputSection *> OutputSections,
1541 ArrayRef<uint8_t> SectionTable,
1542 llvm::codeview::DebugInfo *BuildId) {
1543 ScopedTimer T1(TotalPdbLinkTimer);
1544 PDBLinker PDB(Symtab);
1545
1546 PDB.initialize(BuildId);
1547 PDB.addObjectsToPDB();
1548 PDB.addSections(OutputSections, SectionTable);
1549 PDB.addNatvisFiles();
1550
1551 ScopedTimer T2(DiskCommitTimer);
1552 codeview::GUID Guid;
1553 PDB.commit(&Guid);
1554 memcpy(&BuildId->PDB70.Signature, &Guid, 16);
1602void coff::createPDB(SymbolTable *symtab,
1603 ArrayRef<OutputSection *> outputSections,
1604 ArrayRef<uint8_t> sectionTable,
1605 llvm::codeview::DebugInfo *buildId) {
1606 ScopedTimer t1(totalPdbLinkTimer);
1607 PDBLinker pdb(symtab);
1608
1609 pdb.initialize(buildId);
1610 pdb.addObjectsToPDB();
1611 pdb.addImportFilesToPDB(outputSections);
1612 pdb.addSections(outputSections, sectionTable);
1613 pdb.addNatvisFiles();
1614
1615 ScopedTimer t2(diskCommitTimer);
1616 codeview::GUID guid;
1617 pdb.commit(&guid);
1618 memcpy(&buildId->PDB70.Signature, &guid, 16);
1619
1620 t2.stop();
1621 t1.stop();
1622 pdb.printStats();
15551623}
15561624
1557void PDBLinker::initialize(llvm::codeview::DebugInfo *BuildId) {
1558 ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
1625void PDBLinker::initialize(llvm::codeview::DebugInfo *buildId) {
1626 exitOnErr(builder.initialize(4096)); // 4096 is blocksize
15591627
1560 BuildId->Signature.CVSignature = OMF::Signature::PDB70;
1628 buildId->Signature.CVSignature = OMF::Signature::PDB70;
15611629 // 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;
1630 memset(buildId->PDB70.Signature, 0, 16);
1631 buildId->PDB70.Age = 1;
15641632
15651633 // Create streams in MSF for predefined streams, namely
15661634 // PDB, TPI, DBI and IPI.
1567 for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I)
1568 ExitOnErr(Builder.getMsfBuilder().addStream(0));
1635 for (int i = 0; i < (int)pdb::kSpecialStreamCount; ++i)
1636 exitOnErr(builder.getMsfBuilder().addStream(0));
15691637
15701638 // Add an Info stream.
1571 auto &InfoBuilder = Builder.getInfoBuilder();
1572 InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
1573 InfoBuilder.setHashPDBContentsToGUID(true);
1639 auto &infoBuilder = builder.getInfoBuilder();
1640 infoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
1641 infoBuilder.setHashPDBContentsToGUID(true);
15741642
15751643 // Add an empty DBI stream.
1576 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
1577 DbiBuilder.setAge(BuildId->PDB70.Age);
1578 DbiBuilder.setVersionHeader(pdb::PdbDbiV70);
1579 DbiBuilder.setMachineType(Config->Machine);
1644 pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();
1645 dbiBuilder.setAge(buildId->PDB70.Age);
1646 dbiBuilder.setVersionHeader(pdb::PdbDbiV70);
1647 dbiBuilder.setMachineType(config->machine);
15801648 // Technically we are not link.exe 14.11, but there are known cases where
15811649 // debugging tools on Windows expect Microsoft-specific version numbers or
15821650 // they fail to work at all. Since we know we produce PDBs that are
15831651 // compatible with LINK 14.11, we set that version number here.
1584 DbiBuilder.setBuildNumber(14, 11);
1652 dbiBuilder.setBuildNumber(14, 11);
15851653}
15861654
1587void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
1588 ArrayRef<uint8_t> SectionTable) {
1655void PDBLinker::addSections(ArrayRef<OutputSection *> outputSections,
1656 ArrayRef<uint8_t> sectionTable) {
15891657 // It's not entirely clear what this is, but the * Linker * module uses it.
1590 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
1591 NativePath = Config->PDBPath;
1592 pdbMakeAbsolute(NativePath);
1593 uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);
1594 auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *"));
1595 LinkerModule.setPdbFilePathNI(PdbFilePathNI);
1596 addCommonLinkerModuleSymbols(NativePath, LinkerModule, Alloc);
1658 pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();
1659 nativePath = config->pdbPath;
1660 pdbMakeAbsolute(nativePath);
1661 uint32_t pdbFilePathNI = dbiBuilder.addECName(nativePath);
1662 auto &linkerModule = exitOnErr(dbiBuilder.addModuleInfo("* Linker *"));
1663 linkerModule.setPdbFilePathNI(pdbFilePathNI);
1664 addCommonLinkerModuleSymbols(nativePath, linkerModule, alloc);
15971665
15981666 // Add section contributions. They must be ordered by ascending RVA.
1599 for (OutputSection *OS : OutputSections) {
1600 addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
1601 for (Chunk *C : OS->Chunks) {
1602 pdb::SectionContrib SC =
1603 createSectionContrib(C, LinkerModule.getModuleIndex());
1604 Builder.getDbiBuilder().addSectionContrib(SC);
1667 for (OutputSection *os : outputSections) {
1668 addLinkerModuleSectionSymbol(linkerModule, *os, alloc);
1669 for (Chunk *c : os->chunks) {
1670 pdb::SectionContrib sc =
1671 createSectionContrib(c, linkerModule.getModuleIndex());
1672 builder.getDbiBuilder().addSectionContrib(sc);
16051673 }
16061674 }
16071675
1676 // The * Linker * first section contrib is only used along with /INCREMENTAL,
1677 // to provide trampolines thunks for incremental function patching. Set this
1678 // as "unused" because LLD doesn't support /INCREMENTAL link.
1679 pdb::SectionContrib sc =
1680 createSectionContrib(nullptr, llvm::pdb::kInvalidStreamIndex);
1681 linkerModule.setFirstSectionContrib(sc);
1682
16081683 // Add Section Map stream.
1609 ArrayRef<object::coff_section> Sections = {
1610 (const object::coff_section *)SectionTable.data(),
1611 SectionTable.size() / sizeof(object::coff_section)};
1612 SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections);
1613 DbiBuilder.setSectionMap(SectionMap);
1684 ArrayRef<object::coff_section> sections = {
1685 (const object::coff_section *)sectionTable.data(),
1686 sectionTable.size() / sizeof(object::coff_section)};
1687 sectionMap = pdb::DbiStreamBuilder::createSectionMap(sections);
1688 dbiBuilder.setSectionMap(sectionMap);
16141689
16151690 // Add COFF section header stream.
1616 ExitOnErr(
1617 DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));
1691 exitOnErr(
1692 dbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, sectionTable));
16181693}
16191694
1620void PDBLinker::commit(codeview::GUID *Guid) {
1695void PDBLinker::commit(codeview::GUID *guid) {
16211696 // Write to a file.
1622 ExitOnErr(Builder.commit(Config->PDBPath, Guid));
1623}
1624
1625static Expected<StringRef>
1626getFileName(const DebugStringTableSubsectionRef &Strings,
1627 const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) {
1628 auto Iter = Checksums.getArray().at(FileID);
1629 if (Iter == Checksums.getArray().end())
1630 return make_error<CodeViewError>(cv_error_code::no_records);
1631 uint32_t Offset = Iter->FileNameOffset;
1632 return Strings.getString(Offset);
1697 exitOnErr(builder.commit(config->pdbPath, guid));
16331698}
16341699
16351700static uint32_t getSecrelReloc() {
1636 switch (Config->Machine) {
1701 switch (config->machine) {
16371702 case AMD64:
16381703 return COFF::IMAGE_REL_AMD64_SECREL;
16391704 case I386:
......@@ -1652,78 +1717,78 @@ static uint32_t getSecrelReloc() {
16521717// that are used to interpret the line table, and the offset of Addr in the line
16531718// table are stored in the output arguments. Returns whether a line table was
16541719// found.
1655static bool findLineTable(const SectionChunk *C, uint32_t Addr,
1656 DebugStringTableSubsectionRef &CVStrTab,
1657 DebugChecksumsSubsectionRef &Checksums,
1658 DebugLinesSubsectionRef &Lines,
1659 uint32_t &OffsetInLinetable) {
1660 ExitOnError ExitOnErr;
1661 uint32_t SecrelReloc = getSecrelReloc();
1662
1663 for (SectionChunk *DbgC : C->File->getDebugChunks()) {
1664 if (DbgC->getSectionName() != ".debug$S")
1720static bool findLineTable(const SectionChunk *c, uint32_t addr,
1721 DebugStringTableSubsectionRef &cVStrTab,
1722 DebugChecksumsSubsectionRef &checksums,
1723 DebugLinesSubsectionRef &lines,
1724 uint32_t &offsetInLinetable) {
1725 ExitOnError exitOnErr;
1726 uint32_t secrelReloc = getSecrelReloc();
1727
1728 for (SectionChunk *dbgC : c->file->getDebugChunks()) {
1729 if (dbgC->getSectionName() != ".debug$S")
16651730 continue;
16661731
1667 // Build a mapping of SECREL relocations in DbgC that refer to C.
1668 DenseMap<uint32_t, uint32_t> Secrels;
1669 for (const coff_relocation &R : DbgC->Relocs) {
1670 if (R.Type != SecrelReloc)
1732 // Build a mapping of SECREL relocations in dbgC that refer to `c`.
1733 DenseMap<uint32_t, uint32_t> secrels;
1734 for (const coff_relocation &r : dbgC->getRelocs()) {
1735 if (r.Type != secrelReloc)
16711736 continue;
16721737
1673 if (auto *S = dyn_cast_or_null<DefinedRegular>(
1674 C->File->getSymbols()[R.SymbolTableIndex]))
1675 if (S->getChunk() == C)
1676 Secrels[R.VirtualAddress] = S->getValue();
1738 if (auto *s = dyn_cast_or_null<DefinedRegular>(
1739 c->file->getSymbols()[r.SymbolTableIndex]))
1740 if (s->getChunk() == c)
1741 secrels[r.VirtualAddress] = s->getValue();
16771742 }
16781743
1679 ArrayRef<uint8_t> Contents =
1680 consumeDebugMagic(DbgC->getContents(), ".debug$S");
1681 DebugSubsectionArray Subsections;
1682 BinaryStreamReader Reader(Contents, support::little);
1683 ExitOnErr(Reader.readArray(Subsections, Contents.size()));
1744 ArrayRef<uint8_t> contents =
1745 SectionChunk::consumeDebugMagic(dbgC->getContents(), ".debug$S");
1746 DebugSubsectionArray subsections;
1747 BinaryStreamReader reader(contents, support::little);
1748 exitOnErr(reader.readArray(subsections, contents.size()));
16841749
1685 for (const DebugSubsectionRecord &SS : Subsections) {
1686 switch (SS.kind()) {
1750 for (const DebugSubsectionRecord &ss : subsections) {
1751 switch (ss.kind()) {
16871752 case DebugSubsectionKind::StringTable: {
1688 assert(!CVStrTab.valid() &&
1753 assert(!cVStrTab.valid() &&
16891754 "Encountered multiple string table subsections!");
1690 ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
1755 exitOnErr(cVStrTab.initialize(ss.getRecordData()));
16911756 break;
16921757 }
16931758 case DebugSubsectionKind::FileChecksums:
1694 assert(!Checksums.valid() &&
1759 assert(!checksums.valid() &&
16951760 "Encountered multiple checksum subsections!");
1696 ExitOnErr(Checksums.initialize(SS.getRecordData()));
1761 exitOnErr(checksums.initialize(ss.getRecordData()));
16971762 break;
16981763 case DebugSubsectionKind::Lines: {
1699 ArrayRef<uint8_t> Bytes;
1700 auto Ref = SS.getRecordData();
1701 ExitOnErr(Ref.readLongestContiguousChunk(0, Bytes));
1702 size_t OffsetInDbgC = Bytes.data() - DbgC->getContents().data();
1764 ArrayRef<uint8_t> bytes;
1765 auto ref = ss.getRecordData();
1766 exitOnErr(ref.readLongestContiguousChunk(0, bytes));
1767 size_t offsetInDbgC = bytes.data() - dbgC->getContents().data();
17031768
17041769 // Check whether this line table refers to C.
1705 auto I = Secrels.find(OffsetInDbgC);
1706 if (I == Secrels.end())
1770 auto i = secrels.find(offsetInDbgC);
1771 if (i == secrels.end())
17071772 break;
17081773
17091774 // Check whether this line table covers Addr in C.
1710 DebugLinesSubsectionRef LinesTmp;
1711 ExitOnErr(LinesTmp.initialize(BinaryStreamReader(Ref)));
1712 uint32_t OffsetInC = I->second + LinesTmp.header()->RelocOffset;
1713 if (Addr < OffsetInC || Addr >= OffsetInC + LinesTmp.header()->CodeSize)
1775 DebugLinesSubsectionRef linesTmp;
1776 exitOnErr(linesTmp.initialize(BinaryStreamReader(ref)));
1777 uint32_t offsetInC = i->second + linesTmp.header()->RelocOffset;
1778 if (addr < offsetInC || addr >= offsetInC + linesTmp.header()->CodeSize)
17141779 break;
17151780
1716 assert(!Lines.header() &&
1781 assert(!lines.header() &&
17171782 "Encountered multiple line tables for function!");
1718 ExitOnErr(Lines.initialize(BinaryStreamReader(Ref)));
1719 OffsetInLinetable = Addr - OffsetInC;
1783 exitOnErr(lines.initialize(BinaryStreamReader(ref)));
1784 offsetInLinetable = addr - offsetInC;
17201785 break;
17211786 }
17221787 default:
17231788 break;
17241789 }
17251790
1726 if (CVStrTab.valid() && Checksums.valid() && Lines.header())
1791 if (cVStrTab.valid() && checksums.valid() && lines.header())
17271792 return true;
17281793 }
17291794 }
......@@ -1734,38 +1799,38 @@ static bool findLineTable(const SectionChunk *C, uint32_t Addr,
17341799// Use CodeView line tables to resolve a file and line number for the given
17351800// offset into the given chunk and return them, or {"", 0} if a line table was
17361801// not found.
1737std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *C,
1738 uint32_t Addr) {
1739 ExitOnError ExitOnErr;
1802std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *c,
1803 uint32_t addr) {
1804 ExitOnError exitOnErr;
17401805
1741 DebugStringTableSubsectionRef CVStrTab;
1742 DebugChecksumsSubsectionRef Checksums;
1743 DebugLinesSubsectionRef Lines;
1744 uint32_t OffsetInLinetable;
1806 DebugStringTableSubsectionRef cVStrTab;
1807 DebugChecksumsSubsectionRef checksums;
1808 DebugLinesSubsectionRef lines;
1809 uint32_t offsetInLinetable;
17451810
1746 if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable))
1811 if (!findLineTable(c, addr, cVStrTab, checksums, lines, offsetInLinetable))
17471812 return {"", 0};
17481813
1749 Optional<uint32_t> NameIndex;
1750 Optional<uint32_t> LineNumber;
1751 for (LineColumnEntry &Entry : Lines) {
1752 for (const LineNumberEntry &LN : Entry.LineNumbers) {
1753 LineInfo LI(LN.Flags);
1754 if (LN.Offset > OffsetInLinetable) {
1755 if (!NameIndex) {
1756 NameIndex = Entry.NameIndex;
1757 LineNumber = LI.getStartLine();
1814 Optional<uint32_t> nameIndex;
1815 Optional<uint32_t> lineNumber;
1816 for (LineColumnEntry &entry : lines) {
1817 for (const LineNumberEntry &ln : entry.LineNumbers) {
1818 LineInfo li(ln.Flags);
1819 if (ln.Offset > offsetInLinetable) {
1820 if (!nameIndex) {
1821 nameIndex = entry.NameIndex;
1822 lineNumber = li.getStartLine();
17581823 }
1759 StringRef Filename =
1760 ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
1761 return {Filename, *LineNumber};
1824 StringRef filename =
1825 exitOnErr(getFileName(cVStrTab, checksums, *nameIndex));
1826 return {filename, *lineNumber};
17621827 }
1763 NameIndex = Entry.NameIndex;
1764 LineNumber = LI.getStartLine();
1828 nameIndex = entry.NameIndex;
1829 lineNumber = li.getStartLine();
17651830 }
17661831 }
1767 if (!NameIndex)
1832 if (!nameIndex)
17681833 return {"", 0};
1769 StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, *NameIndex));
1770 return {Filename, *LineNumber};
1834 StringRef filename = exitOnErr(getFileName(cVStrTab, checksums, *nameIndex));
1835 return {filename, *lineNumber};
17711836}
deps/lld/COFF/PDB.h+9-10
......@@ -1,9 +1,8 @@
11//===- PDB.h ----------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -25,13 +24,13 @@ class OutputSection;
2524class SectionChunk;
2625class SymbolTable;
2726
28void createPDB(SymbolTable *Symtab,
29 llvm::ArrayRef<OutputSection *> OutputSections,
30 llvm::ArrayRef<uint8_t> SectionTable,
31 llvm::codeview::DebugInfo *BuildId);
27void createPDB(SymbolTable *symtab,
28 llvm::ArrayRef<OutputSection *> outputSections,
29 llvm::ArrayRef<uint8_t> sectionTable,
30 llvm::codeview::DebugInfo *buildId);
3231
33std::pair<llvm::StringRef, uint32_t> getFileLine(const SectionChunk *C,
34 uint32_t Addr);
32std::pair<llvm::StringRef, uint32_t> getFileLine(const SectionChunk *c,
33 uint32_t addr);
3534}
3635}
3736
deps/lld/COFF/SymbolTable.cpp+392-337
......@@ -1,9 +1,8 @@
11//===- SymbolTable.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -17,6 +16,7 @@
1716#include "lld/Common/Memory.h"
1817#include "lld/Common/Timer.h"
1918#include "llvm/IR/LLVMContext.h"
19#include "llvm/Object/WindowsMachineFlag.h"
2020#include "llvm/Support/Debug.h"
2121#include "llvm/Support/raw_ostream.h"
2222#include <utility>
......@@ -26,521 +26,576 @@ using namespace llvm;
2626namespace lld {
2727namespace coff {
2828
29static Timer LTOTimer("LTO", Timer::root());
29static Timer ltoTimer("LTO", Timer::root());
3030
31SymbolTable *Symtab;
31SymbolTable *symtab;
3232
33void SymbolTable::addFile(InputFile *File) {
34 log("Reading " + toString(File));
35 File->parse();
33void SymbolTable::addFile(InputFile *file) {
34 log("Reading " + toString(file));
35 file->parse();
3636
37 MachineTypes MT = File->getMachineType();
38 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
39 Config->Machine = MT;
40 } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) {
41 error(toString(File) + ": machine type " + machineToStr(MT) +
42 " conflicts with " + machineToStr(Config->Machine));
37 MachineTypes mt = file->getMachineType();
38 if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) {
39 config->machine = mt;
40 } else if (mt != IMAGE_FILE_MACHINE_UNKNOWN && config->machine != mt) {
41 error(toString(file) + ": machine type " + machineToStr(mt) +
42 " conflicts with " + machineToStr(config->machine));
4343 return;
4444 }
4545
46 if (auto *F = dyn_cast<ObjFile>(File)) {
47 ObjFile::Instances.push_back(F);
48 } else if (auto *F = dyn_cast<BitcodeFile>(File)) {
49 BitcodeFile::Instances.push_back(F);
50 } else if (auto *F = dyn_cast<ImportFile>(File)) {
51 ImportFile::Instances.push_back(F);
46 if (auto *f = dyn_cast<ObjFile>(file)) {
47 ObjFile::instances.push_back(f);
48 } else if (auto *f = dyn_cast<BitcodeFile>(file)) {
49 BitcodeFile::instances.push_back(f);
50 } else if (auto *f = dyn_cast<ImportFile>(file)) {
51 ImportFile::instances.push_back(f);
5252 }
5353
54 StringRef S = File->getDirectives();
55 if (S.empty())
56 return;
57
58 log("Directives: " + toString(File) + ": " + S);
59 Driver->parseDirectives(S);
54 driver->parseDirectives(file);
6055}
6156
62static void errorOrWarn(const Twine &S) {
63 if (Config->ForceUnresolved)
64 warn(S);
57static void errorOrWarn(const Twine &s) {
58 if (config->forceUnresolved)
59 warn(s);
6560 else
66 error(S);
61 error(s);
6762}
6863
6964// Returns the symbol in SC whose value is <= Addr that is closest to Addr.
7065// This is generally the global variable or function whose definition contains
7166// Addr.
72static Symbol *getSymbol(SectionChunk *SC, uint32_t Addr) {
73 DefinedRegular *Candidate = nullptr;
67static Symbol *getSymbol(SectionChunk *sc, uint32_t addr) {
68 DefinedRegular *candidate = nullptr;
7469
75 for (Symbol *S : SC->File->getSymbols()) {
76 auto *D = dyn_cast_or_null<DefinedRegular>(S);
77 if (!D || D->getChunk() != SC || D->getValue() > Addr ||
78 (Candidate && D->getValue() < Candidate->getValue()))
70 for (Symbol *s : sc->file->getSymbols()) {
71 auto *d = dyn_cast_or_null<DefinedRegular>(s);
72 if (!d || !d->data || d->getChunk() != sc || d->getValue() > addr ||
73 (candidate && d->getValue() < candidate->getValue()))
7974 continue;
8075
81 Candidate = D;
76 candidate = d;
8277 }
8378
84 return Candidate;
79 return candidate;
8580}
8681
87std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
82// Given a file and the index of a symbol in that file, returns a description
83// of all references to that symbol from that file. If no debug information is
84// available, returns just the name of the file, else one string per actual
85// reference as described in the debug info.
86std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
8887 struct Location {
89 Symbol *Sym;
90 std::pair<StringRef, uint32_t> FileLine;
88 Symbol *sym;
89 std::pair<StringRef, uint32_t> fileLine;
9190 };
92 std::vector<Location> Locations;
91 std::vector<Location> locations;
9392
94 for (Chunk *C : File->getChunks()) {
95 auto *SC = dyn_cast<SectionChunk>(C);
96 if (!SC)
93 for (Chunk *c : file->getChunks()) {
94 auto *sc = dyn_cast<SectionChunk>(c);
95 if (!sc)
9796 continue;
98 for (const coff_relocation &R : SC->Relocs) {
99 if (R.SymbolTableIndex != SymIndex)
97 for (const coff_relocation &r : sc->getRelocs()) {
98 if (r.SymbolTableIndex != symIndex)
10099 continue;
101 std::pair<StringRef, uint32_t> FileLine =
102 getFileLine(SC, R.VirtualAddress);
103 Symbol *Sym = getSymbol(SC, R.VirtualAddress);
104 if (!FileLine.first.empty() || Sym)
105 Locations.push_back({Sym, FileLine});
100 std::pair<StringRef, uint32_t> fileLine =
101 getFileLine(sc, r.VirtualAddress);
102 Symbol *sym = getSymbol(sc, r.VirtualAddress);
103 if (!fileLine.first.empty() || sym)
104 locations.push_back({sym, fileLine});
106105 }
107106 }
108107
109 if (Locations.empty())
110 return "\n>>> referenced by " + toString(File);
108 if (locations.empty())
109 return std::vector<std::string>({"\n>>> referenced by " + toString(file)});
111110
112 std::string Out;
113 llvm::raw_string_ostream OS(Out);
114 for (Location Loc : Locations) {
115 OS << "\n>>> referenced by ";
116 if (!Loc.FileLine.first.empty())
117 OS << Loc.FileLine.first << ":" << Loc.FileLine.second
111 std::vector<std::string> symbolLocations(locations.size());
112 size_t i = 0;
113 for (Location loc : locations) {
114 llvm::raw_string_ostream os(symbolLocations[i++]);
115 os << "\n>>> referenced by ";
116 if (!loc.fileLine.first.empty())
117 os << loc.fileLine.first << ":" << loc.fileLine.second
118118 << "\n>>> ";
119 OS << toString(File);
120 if (Loc.Sym)
121 OS << ":(" << toString(*Loc.Sym) << ')';
119 os << toString(file);
120 if (loc.sym)
121 os << ":(" << toString(*loc.sym) << ')';
122 }
123 return symbolLocations;
124}
125
126// For an undefined symbol, stores all files referencing it and the index of
127// the undefined symbol in each file.
128struct UndefinedDiag {
129 Symbol *sym;
130 struct File {
131 ObjFile *oFile;
132 uint64_t symIndex;
133 };
134 std::vector<File> files;
135};
136
137static void reportUndefinedSymbol(const UndefinedDiag &undefDiag) {
138 std::string out;
139 llvm::raw_string_ostream os(out);
140 os << "undefined symbol: " << toString(*undefDiag.sym);
141
142 const size_t maxUndefReferences = 10;
143 size_t i = 0, numRefs = 0;
144 for (const UndefinedDiag::File &ref : undefDiag.files) {
145 std::vector<std::string> symbolLocations =
146 getSymbolLocations(ref.oFile, ref.symIndex);
147 numRefs += symbolLocations.size();
148 for (const std::string &s : symbolLocations) {
149 if (i >= maxUndefReferences)
150 break;
151 os << s;
152 i++;
153 }
122154 }
123 return OS.str();
155 if (i < numRefs)
156 os << "\n>>> referenced " << numRefs - i << " more times";
157 errorOrWarn(os.str());
124158}
125159
126160void SymbolTable::loadMinGWAutomaticImports() {
127 for (auto &I : SymMap) {
128 Symbol *Sym = I.second;
129 auto *Undef = dyn_cast<Undefined>(Sym);
130 if (!Undef)
161 for (auto &i : symMap) {
162 Symbol *sym = i.second;
163 auto *undef = dyn_cast<Undefined>(sym);
164 if (!undef)
131165 continue;
132 if (!Sym->IsUsedInRegularObj)
166 if (!sym->isUsedInRegularObj)
133167 continue;
134168
135 StringRef Name = Undef->getName();
169 StringRef name = undef->getName();
136170
137 if (Name.startswith("__imp_"))
171 if (name.startswith("__imp_"))
138172 continue;
139173 // If we have an undefined symbol, but we have a Lazy representing a
140174 // 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)
175 Lazy *l = dyn_cast_or_null<Lazy>(find(("__imp_" + name).str()));
176 if (!l || l->pendingArchiveLoad)
143177 continue;
144178
145 log("Loading lazy " + L->getName() + " from " + L->File->getName() +
179 log("Loading lazy " + l->getName() + " from " + l->file->getName() +
146180 " for automatic import");
147 L->PendingArchiveLoad = true;
148 L->File->addMember(&L->Sym);
181 l->pendingArchiveLoad = true;
182 l->file->addMember(&l->sym);
149183 }
150184}
151185
152bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) {
153 if (Name.startswith("__imp_"))
186bool SymbolTable::handleMinGWAutomaticImport(Symbol *sym, StringRef name) {
187 if (name.startswith("__imp_"))
154188 return false;
155 Defined *Imp = dyn_cast_or_null<Defined>(find(("__imp_" + Name).str()));
156 if (!Imp)
189 Defined *imp = dyn_cast_or_null<Defined>(find(("__imp_" + name).str()));
190 if (!imp)
157191 return false;
158192
159193 // Replace the reference directly to a variable with a reference
160194 // to the import address table instead. This obviously isn't right,
161 // but we mark the symbol as IsRuntimePseudoReloc, and a later pass
195 // but we mark the symbol as isRuntimePseudoReloc, and a later pass
162196 // will add runtime pseudo relocations for every relocation against
163197 // this Symbol. The runtime pseudo relocation framework expects the
164198 // 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);
199 size_t impSize = 0;
200 if (isa<DefinedImportData>(imp)) {
201 log("Automatically importing " + name + " from " +
202 cast<DefinedImportData>(imp)->getDLLName());
203 impSize = sizeof(DefinedImportData);
204 } else if (isa<DefinedRegular>(imp)) {
205 log("Automatically importing " + name + " from " +
206 toString(cast<DefinedRegular>(imp)->file));
207 impSize = sizeof(DefinedRegular);
174208 } else {
175 warn("unable to automatically import " + Name + " from " + Imp->getName() +
176 " from " + toString(cast<DefinedRegular>(Imp)->File) +
209 warn("unable to automatically import " + name + " from " + imp->getName() +
210 " from " + toString(cast<DefinedRegular>(imp)->file) +
177211 "; unexpected symbol type");
178212 return false;
179213 }
180 Sym->replaceKeepingName(Imp, ImpSize);
181 Sym->IsRuntimePseudoReloc = true;
214 sym->replaceKeepingName(imp, impSize);
215 sym->isRuntimePseudoReloc = true;
182216
183217 // There may exist symbols named .refptr.<name> which only consist
184218 // of a single pointer to <name>. If it turns out <name> is
185219 // automatically imported, we don't need to keep the .refptr.<name>
186220 // pointer at all, but redirect all accesses to it to the IAT entry
187221 // 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);
222 DefinedRegular *refptr =
223 dyn_cast_or_null<DefinedRegular>(find((".refptr." + name).str()));
224 if (refptr && refptr->getChunk()->getSize() == config->wordsize) {
225 SectionChunk *sc = dyn_cast_or_null<SectionChunk>(refptr->getChunk());
226 if (sc && sc->getRelocs().size() == 1 && *sc->symbols().begin() == sym) {
227 log("Replacing .refptr." + name + " with " + imp->getName());
228 refptr->getChunk()->live = false;
229 refptr->replaceKeepingName(imp, impSize);
196230 }
197231 }
198232 return true;
199233}
200234
201235void SymbolTable::reportRemainingUndefines() {
202 SmallPtrSet<Symbol *, 8> Undefs;
203 DenseMap<Symbol *, Symbol *> LocalImports;
236 SmallPtrSet<Symbol *, 8> undefs;
237 DenseMap<Symbol *, Symbol *> localImports;
204238
205 for (auto &I : SymMap) {
206 Symbol *Sym = I.second;
207 auto *Undef = dyn_cast<Undefined>(Sym);
208 if (!Undef)
239 for (auto &i : symMap) {
240 Symbol *sym = i.second;
241 auto *undef = dyn_cast<Undefined>(sym);
242 if (!undef)
209243 continue;
210 if (!Sym->IsUsedInRegularObj)
244 if (!sym->isUsedInRegularObj)
211245 continue;
212246
213 StringRef Name = Undef->getName();
247 StringRef name = undef->getName();
214248
215249 // A weak alias may have been resolved, so check for that.
216 if (Defined *D = Undef->getWeakAlias()) {
250 if (Defined *d = undef->getWeakAlias()) {
217251 // We want to replace Sym with D. However, we can't just blindly
218252 // copy sizeof(SymbolUnion) bytes from D to Sym because D may be an
219253 // internal symbol, and internal symbols are stored as "unparented"
220254 // Symbols. For that reason we need to check which type of symbol we
221255 // are dealing with and copy the correct number of bytes.
222 if (isa<DefinedRegular>(D))
223 memcpy(Sym, D, sizeof(DefinedRegular));
224 else if (isa<DefinedAbsolute>(D))
225 memcpy(Sym, D, sizeof(DefinedAbsolute));
256 if (isa<DefinedRegular>(d))
257 memcpy(sym, d, sizeof(DefinedRegular));
258 else if (isa<DefinedAbsolute>(d))
259 memcpy(sym, d, sizeof(DefinedAbsolute));
226260 else
227 memcpy(Sym, D, sizeof(SymbolUnion));
261 memcpy(sym, d, sizeof(SymbolUnion));
228262 continue;
229263 }
230264
231265 // If we can resolve a symbol by removing __imp_ prefix, do that.
232266 // This odd rule is for compatibility with MSVC linker.
233 if (Name.startswith("__imp_")) {
234 Symbol *Imp = find(Name.substr(strlen("__imp_")));
235 if (Imp && isa<Defined>(Imp)) {
236 auto *D = cast<Defined>(Imp);
237 replaceSymbol<DefinedLocalImport>(Sym, Name, D);
238 LocalImportChunks.push_back(cast<DefinedLocalImport>(Sym)->getChunk());
239 LocalImports[Sym] = D;
267 if (name.startswith("__imp_")) {
268 Symbol *imp = find(name.substr(strlen("__imp_")));
269 if (imp && isa<Defined>(imp)) {
270 auto *d = cast<Defined>(imp);
271 replaceSymbol<DefinedLocalImport>(sym, name, d);
272 localImportChunks.push_back(cast<DefinedLocalImport>(sym)->getChunk());
273 localImports[sym] = d;
240274 continue;
241275 }
242276 }
243277
244278 // We don't want to report missing Microsoft precompiled headers symbols.
245279 // A proper message will be emitted instead in PDBLinker::aquirePrecompObj
246 if (Name.contains("_PchSym_"))
280 if (name.contains("_PchSym_"))
247281 continue;
248282
249 if (Config->MinGW && handleMinGWAutomaticImport(Sym, Name))
283 if (config->mingw && handleMinGWAutomaticImport(sym, name))
250284 continue;
251285
252286 // Remaining undefined symbols are not fatal if /force is specified.
253287 // They are replaced with dummy defined symbols.
254 if (Config->ForceUnresolved)
255 replaceSymbol<DefinedAbsolute>(Sym, Name, 0);
256 Undefs.insert(Sym);
288 if (config->forceUnresolved)
289 replaceSymbol<DefinedAbsolute>(sym, name, 0);
290 undefs.insert(sym);
257291 }
258292
259 if (Undefs.empty() && LocalImports.empty())
293 if (undefs.empty() && localImports.empty())
260294 return;
261295
262 for (Symbol *B : Config->GCRoot) {
263 if (Undefs.count(B))
264 errorOrWarn("<root>: undefined symbol: " + toString(*B));
265 if (Config->WarnLocallyDefinedImported)
266 if (Symbol *Imp = LocalImports.lookup(B))
267 warn("<root>: locally defined symbol imported: " + toString(*Imp) +
268 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
296 for (Symbol *b : config->gcroot) {
297 if (undefs.count(b))
298 errorOrWarn("<root>: undefined symbol: " + toString(*b));
299 if (config->warnLocallyDefinedImported)
300 if (Symbol *imp = localImports.lookup(b))
301 warn("<root>: locally defined symbol imported: " + toString(*imp) +
302 " (defined in " + toString(imp->getFile()) + ") [LNK4217]");
269303 }
270304
271 for (ObjFile *File : ObjFile::Instances) {
272 size_t SymIndex = (size_t)-1;
273 for (Symbol *Sym : File->getSymbols()) {
274 ++SymIndex;
275 if (!Sym)
305 std::vector<UndefinedDiag> undefDiags;
306 DenseMap<Symbol *, int> firstDiag;
307
308 for (ObjFile *file : ObjFile::instances) {
309 size_t symIndex = (size_t)-1;
310 for (Symbol *sym : file->getSymbols()) {
311 ++symIndex;
312 if (!sym)
276313 continue;
277 if (Undefs.count(Sym))
278 errorOrWarn("undefined symbol: " + toString(*Sym) +
279 getSymbolLocations(File, SymIndex));
280 if (Config->WarnLocallyDefinedImported)
281 if (Symbol *Imp = LocalImports.lookup(Sym))
282 warn(toString(File) +
283 ": locally defined symbol imported: " + toString(*Imp) +
284 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
314 if (undefs.count(sym)) {
315 auto it = firstDiag.find(sym);
316 if (it == firstDiag.end()) {
317 firstDiag[sym] = undefDiags.size();
318 undefDiags.push_back({sym, {{file, symIndex}}});
319 } else {
320 undefDiags[it->second].files.push_back({file, symIndex});
321 }
322 }
323 if (config->warnLocallyDefinedImported)
324 if (Symbol *imp = localImports.lookup(sym))
325 warn(toString(file) +
326 ": locally defined symbol imported: " + toString(*imp) +
327 " (defined in " + toString(imp->getFile()) + ") [LNK4217]");
285328 }
286329 }
330
331 for (const UndefinedDiag& undefDiag : undefDiags)
332 reportUndefinedSymbol(undefDiag);
287333}
288334
289std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
290 bool Inserted = false;
291 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
292 if (!Sym) {
293 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
294 Sym->IsUsedInRegularObj = false;
295 Sym->PendingArchiveLoad = false;
296 Inserted = true;
335std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) {
336 bool inserted = false;
337 Symbol *&sym = symMap[CachedHashStringRef(name)];
338 if (!sym) {
339 sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
340 sym->isUsedInRegularObj = false;
341 sym->pendingArchiveLoad = false;
342 inserted = true;
297343 }
298 return {Sym, Inserted};
344 return {sym, inserted};
299345}
300346
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;
347std::pair<Symbol *, bool> SymbolTable::insert(StringRef name, InputFile *file) {
348 std::pair<Symbol *, bool> result = insert(name);
349 if (!file || !isa<BitcodeFile>(file))
350 result.first->isUsedInRegularObj = true;
351 return result;
306352}
307353
308Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
309 bool IsWeakAlias) {
310 Symbol *S;
311 bool WasInserted;
312 std::tie(S, WasInserted) = insert(Name, F);
313 if (WasInserted || (isa<Lazy>(S) && IsWeakAlias)) {
314 replaceSymbol<Undefined>(S, Name);
315 return S;
354Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f,
355 bool isWeakAlias) {
356 Symbol *s;
357 bool wasInserted;
358 std::tie(s, wasInserted) = insert(name, f);
359 if (wasInserted || (isa<Lazy>(s) && isWeakAlias)) {
360 replaceSymbol<Undefined>(s, name);
361 return s;
316362 }
317 if (auto *L = dyn_cast<Lazy>(S)) {
318 if (!S->PendingArchiveLoad) {
319 S->PendingArchiveLoad = true;
320 L->File->addMember(&L->Sym);
363 if (auto *l = dyn_cast<Lazy>(s)) {
364 if (!s->pendingArchiveLoad) {
365 s->pendingArchiveLoad = true;
366 l->file->addMember(&l->sym);
321367 }
322368 }
323 return S;
369 return s;
324370}
325371
326void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
327 StringRef Name = Sym.getName();
328 Symbol *S;
329 bool WasInserted;
330 std::tie(S, WasInserted) = insert(Name);
331 if (WasInserted) {
332 replaceSymbol<Lazy>(S, F, Sym);
372void SymbolTable::addLazy(ArchiveFile *f, const Archive::Symbol sym) {
373 StringRef name = sym.getName();
374 Symbol *s;
375 bool wasInserted;
376 std::tie(s, wasInserted) = insert(name);
377 if (wasInserted) {
378 replaceSymbol<Lazy>(s, f, sym);
333379 return;
334380 }
335 auto *U = dyn_cast<Undefined>(S);
336 if (!U || U->WeakAlias || S->PendingArchiveLoad)
381 auto *u = dyn_cast<Undefined>(s);
382 if (!u || u->weakAlias || s->pendingArchiveLoad)
337383 return;
338 S->PendingArchiveLoad = true;
339 F->addMember(&Sym);
384 s->pendingArchiveLoad = true;
385 f->addMember(&sym);
340386}
341387
342void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
343 std::string Msg = "duplicate symbol: " + toString(*Existing) + " in " +
344 toString(Existing->getFile()) + " and in " +
345 toString(NewFile);
388void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) {
389 std::string msg = "duplicate symbol: " + toString(*existing) + " in " +
390 toString(existing->getFile()) + " and in " +
391 toString(newFile);
346392
347 if (Config->ForceMultiple)
348 warn(Msg);
393 if (config->forceMultiple)
394 warn(msg);
349395 else
350 error(Msg);
396 error(msg);
351397}
352398
353Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
354 Symbol *S;
355 bool WasInserted;
356 std::tie(S, WasInserted) = insert(N, nullptr);
357 S->IsUsedInRegularObj = true;
358 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
359 replaceSymbol<DefinedAbsolute>(S, N, Sym);
360 else if (!isa<DefinedCOFF>(S))
361 reportDuplicate(S, nullptr);
362 return S;
399Symbol *SymbolTable::addAbsolute(StringRef n, COFFSymbolRef sym) {
400 Symbol *s;
401 bool wasInserted;
402 std::tie(s, wasInserted) = insert(n, nullptr);
403 s->isUsedInRegularObj = true;
404 if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
405 replaceSymbol<DefinedAbsolute>(s, n, sym);
406 else if (!isa<DefinedCOFF>(s))
407 reportDuplicate(s, nullptr);
408 return s;
363409}
364410
365Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
366 Symbol *S;
367 bool WasInserted;
368 std::tie(S, WasInserted) = insert(N, nullptr);
369 S->IsUsedInRegularObj = true;
370 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
371 replaceSymbol<DefinedAbsolute>(S, N, VA);
372 else if (!isa<DefinedCOFF>(S))
373 reportDuplicate(S, nullptr);
374 return S;
411Symbol *SymbolTable::addAbsolute(StringRef n, uint64_t va) {
412 Symbol *s;
413 bool wasInserted;
414 std::tie(s, wasInserted) = insert(n, nullptr);
415 s->isUsedInRegularObj = true;
416 if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
417 replaceSymbol<DefinedAbsolute>(s, n, va);
418 else if (!isa<DefinedCOFF>(s))
419 reportDuplicate(s, nullptr);
420 return s;
375421}
376422
377Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
378 Symbol *S;
379 bool WasInserted;
380 std::tie(S, WasInserted) = insert(N, nullptr);
381 S->IsUsedInRegularObj = true;
382 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
383 replaceSymbol<DefinedSynthetic>(S, N, C);
384 else if (!isa<DefinedCOFF>(S))
385 reportDuplicate(S, nullptr);
386 return S;
423Symbol *SymbolTable::addSynthetic(StringRef n, Chunk *c) {
424 Symbol *s;
425 bool wasInserted;
426 std::tie(s, wasInserted) = insert(n, nullptr);
427 s->isUsedInRegularObj = true;
428 if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s))
429 replaceSymbol<DefinedSynthetic>(s, n, c);
430 else if (!isa<DefinedCOFF>(s))
431 reportDuplicate(s, nullptr);
432 return s;
387433}
388434
389Symbol *SymbolTable::addRegular(InputFile *F, StringRef N,
390 const coff_symbol_generic *Sym,
391 SectionChunk *C) {
392 Symbol *S;
393 bool WasInserted;
394 std::tie(S, WasInserted) = insert(N, F);
395 if (WasInserted || !isa<DefinedRegular>(S))
396 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false,
397 /*IsExternal*/ true, Sym, C);
435Symbol *SymbolTable::addRegular(InputFile *f, StringRef n,
436 const coff_symbol_generic *sym,
437 SectionChunk *c) {
438 Symbol *s;
439 bool wasInserted;
440 std::tie(s, wasInserted) = insert(n, f);
441 if (wasInserted || !isa<DefinedRegular>(s))
442 replaceSymbol<DefinedRegular>(s, f, n, /*IsCOMDAT*/ false,
443 /*IsExternal*/ true, sym, c);
398444 else
399 reportDuplicate(S, F);
400 return S;
445 reportDuplicate(s, f);
446 return s;
401447}
402448
403std::pair<Symbol *, bool>
404SymbolTable::addComdat(InputFile *F, StringRef N,
405 const coff_symbol_generic *Sym) {
406 Symbol *S;
407 bool WasInserted;
408 std::tie(S, WasInserted) = insert(N, F);
409 if (WasInserted || !isa<DefinedRegular>(S)) {
410 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true,
411 /*IsExternal*/ true, Sym, nullptr);
412 return {S, true};
449std::pair<DefinedRegular *, bool>
450SymbolTable::addComdat(InputFile *f, StringRef n,
451 const coff_symbol_generic *sym) {
452 Symbol *s;
453 bool wasInserted;
454 std::tie(s, wasInserted) = insert(n, f);
455 if (wasInserted || !isa<DefinedRegular>(s)) {
456 replaceSymbol<DefinedRegular>(s, f, n, /*IsCOMDAT*/ true,
457 /*IsExternal*/ true, sym, nullptr);
458 return {cast<DefinedRegular>(s), true};
413459 }
414 if (!cast<DefinedRegular>(S)->isCOMDAT())
415 reportDuplicate(S, F);
416 return {S, false};
460 auto *existingSymbol = cast<DefinedRegular>(s);
461 if (!existingSymbol->isCOMDAT)
462 reportDuplicate(s, f);
463 return {existingSymbol, false};
417464}
418465
419Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
420 const coff_symbol_generic *Sym, CommonChunk *C) {
421 Symbol *S;
422 bool WasInserted;
423 std::tie(S, WasInserted) = insert(N, F);
424 if (WasInserted || !isa<DefinedCOFF>(S))
425 replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);
426 else if (auto *DC = dyn_cast<DefinedCommon>(S))
427 if (Size > DC->getSize())
428 replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);
429 return S;
466Symbol *SymbolTable::addCommon(InputFile *f, StringRef n, uint64_t size,
467 const coff_symbol_generic *sym, CommonChunk *c) {
468 Symbol *s;
469 bool wasInserted;
470 std::tie(s, wasInserted) = insert(n, f);
471 if (wasInserted || !isa<DefinedCOFF>(s))
472 replaceSymbol<DefinedCommon>(s, f, n, size, sym, c);
473 else if (auto *dc = dyn_cast<DefinedCommon>(s))
474 if (size > dc->getSize())
475 replaceSymbol<DefinedCommon>(s, f, n, size, sym, c);
476 return s;
430477}
431478
432Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) {
433 Symbol *S;
434 bool WasInserted;
435 std::tie(S, WasInserted) = insert(N, nullptr);
436 S->IsUsedInRegularObj = true;
437 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {
438 replaceSymbol<DefinedImportData>(S, N, F);
439 return S;
479Symbol *SymbolTable::addImportData(StringRef n, ImportFile *f) {
480 Symbol *s;
481 bool wasInserted;
482 std::tie(s, wasInserted) = insert(n, nullptr);
483 s->isUsedInRegularObj = true;
484 if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s)) {
485 replaceSymbol<DefinedImportData>(s, n, f);
486 return s;
440487 }
441488
442 reportDuplicate(S, F);
489 reportDuplicate(s, f);
443490 return nullptr;
444491}
445492
446Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID,
447 uint16_t Machine) {
448 Symbol *S;
449 bool WasInserted;
450 std::tie(S, WasInserted) = insert(Name, nullptr);
451 S->IsUsedInRegularObj = true;
452 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {
453 replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine);
454 return S;
493Symbol *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id,
494 uint16_t machine) {
495 Symbol *s;
496 bool wasInserted;
497 std::tie(s, wasInserted) = insert(name, nullptr);
498 s->isUsedInRegularObj = true;
499 if (wasInserted || isa<Undefined>(s) || isa<Lazy>(s)) {
500 replaceSymbol<DefinedImportThunk>(s, name, id, machine);
501 return s;
455502 }
456503
457 reportDuplicate(S, ID->File);
504 reportDuplicate(s, id->file);
458505 return nullptr;
459506}
460507
461508std::vector<Chunk *> SymbolTable::getChunks() {
462 std::vector<Chunk *> Res;
463 for (ObjFile *File : ObjFile::Instances) {
464 ArrayRef<Chunk *> V = File->getChunks();
465 Res.insert(Res.end(), V.begin(), V.end());
509 std::vector<Chunk *> res;
510 for (ObjFile *file : ObjFile::instances) {
511 ArrayRef<Chunk *> v = file->getChunks();
512 res.insert(res.end(), v.begin(), v.end());
466513 }
467 return Res;
514 return res;
468515}
469516
470Symbol *SymbolTable::find(StringRef Name) {
471 return SymMap.lookup(CachedHashStringRef(Name));
517Symbol *SymbolTable::find(StringRef name) {
518 return symMap.lookup(CachedHashStringRef(name));
472519}
473520
474Symbol *SymbolTable::findUnderscore(StringRef Name) {
475 if (Config->Machine == I386)
476 return find(("_" + Name).str());
477 return find(Name);
521Symbol *SymbolTable::findUnderscore(StringRef name) {
522 if (config->machine == I386)
523 return find(("_" + name).str());
524 return find(name);
478525}
479526
480StringRef SymbolTable::findByPrefix(StringRef Prefix) {
481 for (auto Pair : SymMap) {
482 StringRef Name = Pair.first.val();
483 if (Name.startswith(Prefix))
484 return Name;
527// Return all symbols that start with Prefix, possibly ignoring the first
528// character of Prefix or the first character symbol.
529std::vector<Symbol *> SymbolTable::getSymsWithPrefix(StringRef prefix) {
530 std::vector<Symbol *> syms;
531 for (auto pair : symMap) {
532 StringRef name = pair.first.val();
533 if (name.startswith(prefix) || name.startswith(prefix.drop_front()) ||
534 name.drop_front().startswith(prefix) ||
535 name.drop_front().startswith(prefix.drop_front())) {
536 syms.push_back(pair.second);
537 }
485538 }
486 return "";
539 return syms;
487540}
488541
489StringRef SymbolTable::findMangle(StringRef Name) {
490 if (Symbol *Sym = find(Name))
491 if (!isa<Undefined>(Sym))
492 return Name;
493 if (Config->Machine != I386)
494 return findByPrefix(("?" + Name + "@@Y").str());
495 if (!Name.startswith("_"))
496 return "";
542Symbol *SymbolTable::findMangle(StringRef name) {
543 if (Symbol *sym = find(name))
544 if (!isa<Undefined>(sym))
545 return sym;
546
547 // Efficient fuzzy string lookup is impossible with a hash table, so iterate
548 // the symbol table once and collect all possibly matching symbols into this
549 // vector. Then compare each possibly matching symbol with each possible
550 // mangling.
551 std::vector<Symbol *> syms = getSymsWithPrefix(name);
552 auto findByPrefix = [&syms](const Twine &t) -> Symbol * {
553 std::string prefix = t.str();
554 for (auto *s : syms)
555 if (s->getName().startswith(prefix))
556 return s;
557 return nullptr;
558 };
559
560 // For non-x86, just look for C++ functions.
561 if (config->machine != I386)
562 return findByPrefix("?" + name + "@@Y");
563
564 if (!name.startswith("_"))
565 return nullptr;
497566 // Search for x86 stdcall function.
498 StringRef S = findByPrefix((Name + "@").str());
499 if (!S.empty())
500 return S;
567 if (Symbol *s = findByPrefix(name + "@"))
568 return s;
501569 // Search for x86 fastcall function.
502 S = findByPrefix(("@" + Name.substr(1) + "@").str());
503 if (!S.empty())
504 return S;
570 if (Symbol *s = findByPrefix("@" + name.substr(1) + "@"))
571 return s;
505572 // Search for x86 vectorcall function.
506 S = findByPrefix((Name.substr(1) + "@@").str());
507 if (!S.empty())
508 return S;
573 if (Symbol *s = findByPrefix(name.substr(1) + "@@"))
574 return s;
509575 // Search for x86 C++ non-member function.
510 return findByPrefix(("?" + Name.substr(1) + "@@Y").str());
511}
512
513void SymbolTable::mangleMaybe(Symbol *B) {
514 auto *U = dyn_cast<Undefined>(B);
515 if (!U || U->WeakAlias)
516 return;
517 StringRef Alias = findMangle(U->getName());
518 if (!Alias.empty()) {
519 log(U->getName() + " aliased to " + Alias);
520 U->WeakAlias = addUndefined(Alias);
521 }
576 return findByPrefix("?" + name.substr(1) + "@@Y");
522577}
523578
524Symbol *SymbolTable::addUndefined(StringRef Name) {
525 return addUndefined(Name, nullptr, false);
579Symbol *SymbolTable::addUndefined(StringRef name) {
580 return addUndefined(name, nullptr, false);
526581}
527582
528583std::vector<StringRef> SymbolTable::compileBitcodeFiles() {
529 LTO.reset(new BitcodeCompiler);
530 for (BitcodeFile *F : BitcodeFile::Instances)
531 LTO->add(*F);
532 return LTO->compile();
584 lto.reset(new BitcodeCompiler);
585 for (BitcodeFile *f : BitcodeFile::instances)
586 lto->add(*f);
587 return lto->compile();
533588}
534589
535590void SymbolTable::addCombinedLTOObjects() {
536 if (BitcodeFile::Instances.empty())
591 if (BitcodeFile::instances.empty())
537592 return;
538593
539 ScopedTimer T(LTOTimer);
540 for (StringRef Object : compileBitcodeFiles()) {
541 auto *Obj = make<ObjFile>(MemoryBufferRef(Object, "lto.tmp"));
542 Obj->parse();
543 ObjFile::Instances.push_back(Obj);
594 ScopedTimer t(ltoTimer);
595 for (StringRef object : compileBitcodeFiles()) {
596 auto *obj = make<ObjFile>(MemoryBufferRef(object, "lto.tmp"));
597 obj->parse();
598 ObjFile::instances.push_back(obj);
544599 }
545600}
546601
deps/lld/COFF/SymbolTable.h+44-44
......@@ -1,9 +1,8 @@
11//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -28,6 +27,7 @@ class Chunk;
2827class CommonChunk;
2928class Defined;
3029class DefinedAbsolute;
30class DefinedRegular;
3131class DefinedRelative;
3232class Lazy;
3333class SectionChunk;
......@@ -47,7 +47,7 @@ class Symbol;
4747// There is one add* function per symbol type.
4848class SymbolTable {
4949public:
50 void addFile(InputFile *File);
50 void addFile(InputFile *file);
5151
5252 // Try to resolve any undefined symbols and update the symbol table
5353 // accordingly, then print an error message for any remaining undefined
......@@ -55,21 +55,20 @@ public:
5555 void reportRemainingUndefines();
5656
5757 void loadMinGWAutomaticImports();
58 bool handleMinGWAutomaticImport(Symbol *Sym, StringRef Name);
58 bool handleMinGWAutomaticImport(Symbol *sym, StringRef name);
5959
6060 // Returns a list of chunks of selected symbols.
6161 std::vector<Chunk *> getChunks();
6262
6363 // Returns a symbol for a given name. Returns a nullptr if not found.
64 Symbol *find(StringRef Name);
65 Symbol *findUnderscore(StringRef Name);
64 Symbol *find(StringRef name);
65 Symbol *findUnderscore(StringRef name);
6666
6767 // Occasionally we have to resolve an undefined symbol to its
6868 // mangled symbol. This function tries to find a mangled name
6969 // for U from the symbol table, and if found, set the symbol as
7070 // a weak alias for U.
71 void mangleMaybe(Symbol *B);
72 StringRef findMangle(StringRef Name);
71 Symbol *findMangle(StringRef name);
7372
7473 // Build a set of COFF objects representing the combined contents of
7574 // BitcodeFiles and add them to the symbol table. Called after all files are
......@@ -78,52 +77,53 @@ public:
7877 std::vector<StringRef> compileBitcodeFiles();
7978
8079 // Creates an Undefined symbol for a given name.
81 Symbol *addUndefined(StringRef Name);
82
83 Symbol *addSynthetic(StringRef N, Chunk *C);
84 Symbol *addAbsolute(StringRef N, uint64_t VA);
85
86 Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias);
87 void addLazy(ArchiveFile *F, const Archive::Symbol Sym);
88 Symbol *addAbsolute(StringRef N, COFFSymbolRef S);
89 Symbol *addRegular(InputFile *F, StringRef N,
90 const llvm::object::coff_symbol_generic *S = nullptr,
91 SectionChunk *C = nullptr);
92 std::pair<Symbol *, bool>
93 addComdat(InputFile *F, StringRef N,
94 const llvm::object::coff_symbol_generic *S = nullptr);
95 Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size,
96 const llvm::object::coff_symbol_generic *S = nullptr,
97 CommonChunk *C = nullptr);
98 Symbol *addImportData(StringRef N, ImportFile *F);
99 Symbol *addImportThunk(StringRef Name, DefinedImportData *S,
100 uint16_t Machine);
101
102 void reportDuplicate(Symbol *Existing, InputFile *NewFile);
80 Symbol *addUndefined(StringRef name);
81
82 Symbol *addSynthetic(StringRef n, Chunk *c);
83 Symbol *addAbsolute(StringRef n, uint64_t va);
84
85 Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias);
86 void addLazy(ArchiveFile *f, const Archive::Symbol sym);
87 Symbol *addAbsolute(StringRef n, COFFSymbolRef s);
88 Symbol *addRegular(InputFile *f, StringRef n,
89 const llvm::object::coff_symbol_generic *s = nullptr,
90 SectionChunk *c = nullptr);
91 std::pair<DefinedRegular *, bool>
92 addComdat(InputFile *f, StringRef n,
93 const llvm::object::coff_symbol_generic *s = nullptr);
94 Symbol *addCommon(InputFile *f, StringRef n, uint64_t size,
95 const llvm::object::coff_symbol_generic *s = nullptr,
96 CommonChunk *c = nullptr);
97 Symbol *addImportData(StringRef n, ImportFile *f);
98 Symbol *addImportThunk(StringRef name, DefinedImportData *s,
99 uint16_t machine);
100
101 void reportDuplicate(Symbol *existing, InputFile *newFile);
103102
104103 // A list of chunks which to be added to .rdata.
105 std::vector<Chunk *> LocalImportChunks;
104 std::vector<Chunk *> localImportChunks;
106105
107106 // Iterates symbols in non-determinstic hash table order.
108 template <typename T> void forEachSymbol(T Callback) {
109 for (auto &Pair : SymMap)
110 Callback(Pair.second);
107 template <typename T> void forEachSymbol(T callback) {
108 for (auto &pair : symMap)
109 callback(pair.second);
111110 }
112111
113112private:
114113 /// Inserts symbol if not already present.
115 std::pair<Symbol *, bool> insert(StringRef Name);
116 /// Same as insert(Name), but also sets IsUsedInRegularObj.
117 std::pair<Symbol *, bool> insert(StringRef Name, InputFile *F);
118 StringRef findByPrefix(StringRef Prefix);
114 std::pair<Symbol *, bool> insert(StringRef name);
115 /// Same as insert(Name), but also sets isUsedInRegularObj.
116 std::pair<Symbol *, bool> insert(StringRef name, InputFile *f);
117
118 std::vector<Symbol *> getSymsWithPrefix(StringRef prefix);
119119
120 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
121 std::unique_ptr<BitcodeCompiler> LTO;
120 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> symMap;
121 std::unique_ptr<BitcodeCompiler> lto;
122122};
123123
124extern SymbolTable *Symtab;
124extern SymbolTable *symtab;
125125
126std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex);
126std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex);
127127
128128} // namespace coff
129129} // namespace lld
deps/lld/COFF/Symbols.cpp+58-48
......@@ -1,9 +1,8 @@
11//===- Symbols.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -19,11 +18,17 @@
1918using namespace llvm;
2019using namespace llvm::object;
2120
21using namespace lld::coff;
22
23static_assert(sizeof(SymbolUnion) <= 48,
24 "symbols should be optimized for memory usage");
25
2226// Returns a symbol name for an error message.
23std::string lld::toString(coff::Symbol &B) {
24 if (Optional<std::string> S = lld::demangleMSVC(B.getName()))
25 return ("\"" + *S + "\" (" + B.getName() + ")").str();
26 return B.getName();
27std::string lld::toString(coff::Symbol &b) {
28 if (config->demangle)
29 if (Optional<std::string> s = lld::demangleMSVC(b.getName()))
30 return *s;
31 return b.getName();
2732}
2833
2934namespace lld {
......@@ -37,70 +42,75 @@ StringRef Symbol::getName() {
3742 // name. Object files contain lots of non-external symbols, and creating
3843 // StringRefs for them (which involves lots of strlen() on the string table)
3944 // is a waste of time.
40 if (Name.empty()) {
41 auto *D = cast<DefinedCOFF>(this);
42 cast<ObjFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name);
45 if (nameData == nullptr) {
46 auto *d = cast<DefinedCOFF>(this);
47 StringRef nameStr;
48 cast<ObjFile>(d->file)->getCOFFObj()->getSymbolName(d->sym, nameStr);
49 nameData = nameStr.data();
50 nameSize = nameStr.size();
51 assert(nameSize == nameStr.size() && "name length truncated");
4352 }
44 return Name;
53 return StringRef(nameData, nameSize);
4554}
4655
4756InputFile *Symbol::getFile() {
48 if (auto *Sym = dyn_cast<DefinedCOFF>(this))
49 return Sym->File;
50 if (auto *Sym = dyn_cast<Lazy>(this))
51 return Sym->File;
57 if (auto *sym = dyn_cast<DefinedCOFF>(this))
58 return sym->file;
59 if (auto *sym = dyn_cast<Lazy>(this))
60 return sym->file;
5261 return nullptr;
5362}
5463
5564bool Symbol::isLive() const {
56 if (auto *R = dyn_cast<DefinedRegular>(this))
57 return R->getChunk()->Live;
58 if (auto *Imp = dyn_cast<DefinedImportData>(this))
59 return Imp->File->Live;
60 if (auto *Imp = dyn_cast<DefinedImportThunk>(this))
61 return Imp->WrappedSym->File->ThunkLive;
65 if (auto *r = dyn_cast<DefinedRegular>(this))
66 return r->getChunk()->live;
67 if (auto *imp = dyn_cast<DefinedImportData>(this))
68 return imp->file->live;
69 if (auto *imp = dyn_cast<DefinedImportThunk>(this))
70 return imp->wrappedSym->file->thunkLive;
6271 // Assume any other kind of symbol is live.
6372 return true;
6473}
6574
6675// MinGW specific.
67void Symbol::replaceKeepingName(Symbol *Other, size_t Size) {
68 StringRef OrigName = Name;
69 memcpy(this, Other, Size);
70 Name = OrigName;
76void Symbol::replaceKeepingName(Symbol *other, size_t size) {
77 StringRef origName = getName();
78 memcpy(this, other, size);
79 nameData = origName.data();
80 nameSize = origName.size();
7181}
7282
7383COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
74 size_t SymSize = cast<ObjFile>(File)->getCOFFObj()->getSymbolTableEntrySize();
75 if (SymSize == sizeof(coff_symbol16))
76 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym));
77 assert(SymSize == sizeof(coff_symbol32));
78 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
84 size_t symSize = cast<ObjFile>(file)->getCOFFObj()->getSymbolTableEntrySize();
85 if (symSize == sizeof(coff_symbol16))
86 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(sym));
87 assert(symSize == sizeof(coff_symbol32));
88 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(sym));
7989}
8090
81uint16_t DefinedAbsolute::NumOutputSections;
91uint16_t DefinedAbsolute::numOutputSections;
8292
83static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) {
84 if (Machine == AMD64)
85 return make<ImportThunkChunkX64>(S);
86 if (Machine == I386)
87 return make<ImportThunkChunkX86>(S);
88 if (Machine == ARM64)
89 return make<ImportThunkChunkARM64>(S);
90 assert(Machine == ARMNT);
91 return make<ImportThunkChunkARM>(S);
93static Chunk *makeImportThunk(DefinedImportData *s, uint16_t machine) {
94 if (machine == AMD64)
95 return make<ImportThunkChunkX64>(s);
96 if (machine == I386)
97 return make<ImportThunkChunkX86>(s);
98 if (machine == ARM64)
99 return make<ImportThunkChunkARM64>(s);
100 assert(machine == ARMNT);
101 return make<ImportThunkChunkARM>(s);
92102}
93103
94DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
95 uint16_t Machine)
96 : Defined(DefinedImportThunkKind, Name), WrappedSym(S),
97 Data(makeImportThunk(S, Machine)) {}
104DefinedImportThunk::DefinedImportThunk(StringRef name, DefinedImportData *s,
105 uint16_t machine)
106 : Defined(DefinedImportThunkKind, name), wrappedSym(s),
107 data(makeImportThunk(s, machine)) {}
98108
99109Defined *Undefined::getWeakAlias() {
100110 // A weak alias may be a weak alias to another symbol, so check recursively.
101 for (Symbol *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias)
102 if (auto *D = dyn_cast<Defined>(A))
103 return D;
111 for (Symbol *a = weakAlias; a; a = cast<Undefined>(a)->weakAlias)
112 if (auto *d = dyn_cast<Defined>(a))
113 return d;
104114 return nullptr;
105115}
106116} // namespace coff
deps/lld/COFF/Symbols.h+121-122
......@@ -1,9 +1,8 @@
11//===- Symbols.h ------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -58,15 +57,12 @@ public:
5857 LastDefinedKind = DefinedSyntheticKind,
5958 };
6059
61 Kind kind() const { return static_cast<Kind>(SymbolKind); }
62
63 // Returns true if this is an external symbol.
64 bool isExternal() { return IsExternal; }
60 Kind kind() const { return static_cast<Kind>(symbolKind); }
6561
6662 // Returns the symbol name.
6763 StringRef getName();
6864
69 void replaceKeepingName(Symbol *Other, size_t Size);
65 void replaceKeepingName(Symbol *other, size_t size);
7066
7167 // Returns the file from which this symbol was created.
7268 InputFile *getFile();
......@@ -77,46 +73,50 @@ public:
7773
7874protected:
7975 friend SymbolTable;
80 explicit Symbol(Kind K, StringRef N = "")
81 : SymbolKind(K), IsExternal(true), IsCOMDAT(false),
82 WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),
83 IsRuntimePseudoReloc(false), Name(N) {}
76 explicit Symbol(Kind k, StringRef n = "")
77 : symbolKind(k), isExternal(true), isCOMDAT(false),
78 writtenToSymtab(false), pendingArchiveLoad(false), isGCRoot(false),
79 isRuntimePseudoReloc(false), nameSize(n.size()),
80 nameData(n.empty() ? nullptr : n.data()) {}
8481
85 const unsigned SymbolKind : 8;
86 unsigned IsExternal : 1;
82 const unsigned symbolKind : 8;
83 unsigned isExternal : 1;
8784
85public:
8886 // This bit is used by the \c DefinedRegular subclass.
89 unsigned IsCOMDAT : 1;
87 unsigned isCOMDAT : 1;
9088
91public:
9289 // This bit is used by Writer::createSymbolAndStringTable() to prevent
9390 // symbols from being written to the symbol table more than once.
94 unsigned WrittenToSymtab : 1;
91 unsigned writtenToSymtab : 1;
9592
9693 // True if this symbol was referenced by a regular (non-bitcode) object.
97 unsigned IsUsedInRegularObj : 1;
94 unsigned isUsedInRegularObj : 1;
9895
9996 // True if we've seen both a lazy and an undefined symbol with this symbol
10097 // name, which means that we have enqueued an archive member load and should
10198 // not load any more archive members to resolve the same symbol.
102 unsigned PendingArchiveLoad : 1;
99 unsigned pendingArchiveLoad : 1;
103100
104101 /// True if we've already added this symbol to the list of GC roots.
105 unsigned IsGCRoot : 1;
102 unsigned isGCRoot : 1;
106103
107 unsigned IsRuntimePseudoReloc : 1;
104 unsigned isRuntimePseudoReloc : 1;
108105
109106protected:
110 StringRef Name;
107 // Symbol name length. Assume symbol lengths fit in a 32-bit integer.
108 uint32_t nameSize;
109
110 const char *nameData;
111111};
112112
113113// The base class for any defined symbols, including absolute symbols,
114114// etc.
115115class Defined : public Symbol {
116116public:
117 Defined(Kind K, StringRef N) : Symbol(K, N) {}
117 Defined(Kind k, StringRef n) : Symbol(k, n) {}
118118
119 static bool classof(const Symbol *S) { return S->kind() <= LastDefinedKind; }
119 static bool classof(const Symbol *s) { return s->kind() <= LastDefinedKind; }
120120
121121 // Returns the RVA (relative virtual address) of this symbol. The
122122 // writer sets and uses RVAs.
......@@ -130,120 +130,119 @@ public:
130130// Symbols defined via a COFF object file or bitcode file. For COFF files, this
131131// stores a coff_symbol_generic*, and names of internal symbols are lazily
132132// loaded through that. For bitcode files, Sym is nullptr and the name is stored
133// as a StringRef.
133// as a decomposed StringRef.
134134class DefinedCOFF : public Defined {
135135 friend Symbol;
136136
137137public:
138 DefinedCOFF(Kind K, InputFile *F, StringRef N, const coff_symbol_generic *S)
139 : Defined(K, N), File(F), Sym(S) {}
138 DefinedCOFF(Kind k, InputFile *f, StringRef n, const coff_symbol_generic *s)
139 : Defined(k, n), file(f), sym(s) {}
140140
141 static bool classof(const Symbol *S) {
142 return S->kind() <= LastDefinedCOFFKind;
141 static bool classof(const Symbol *s) {
142 return s->kind() <= LastDefinedCOFFKind;
143143 }
144144
145 InputFile *getFile() { return File; }
145 InputFile *getFile() { return file; }
146146
147147 COFFSymbolRef getCOFFSymbol();
148148
149 InputFile *File;
149 InputFile *file;
150150
151151protected:
152 const coff_symbol_generic *Sym;
152 const coff_symbol_generic *sym;
153153};
154154
155155// Regular defined symbols read from object file symbol tables.
156156class DefinedRegular : public DefinedCOFF {
157157public:
158 DefinedRegular(InputFile *F, StringRef N, bool IsCOMDAT,
159 bool IsExternal = false,
160 const coff_symbol_generic *S = nullptr,
161 SectionChunk *C = nullptr)
162 : DefinedCOFF(DefinedRegularKind, F, N, S), Data(C ? &C->Repl : nullptr) {
163 this->IsExternal = IsExternal;
164 this->IsCOMDAT = IsCOMDAT;
158 DefinedRegular(InputFile *f, StringRef n, bool isCOMDAT,
159 bool isExternal = false,
160 const coff_symbol_generic *s = nullptr,
161 SectionChunk *c = nullptr)
162 : DefinedCOFF(DefinedRegularKind, f, n, s), data(c ? &c->repl : nullptr) {
163 this->isExternal = isExternal;
164 this->isCOMDAT = isCOMDAT;
165165 }
166166
167 static bool classof(const Symbol *S) {
168 return S->kind() == DefinedRegularKind;
167 static bool classof(const Symbol *s) {
168 return s->kind() == DefinedRegularKind;
169169 }
170170
171 uint64_t getRVA() const { return (*Data)->getRVA() + Sym->Value; }
172 bool isCOMDAT() const { return IsCOMDAT; }
173 SectionChunk *getChunk() const { return *Data; }
174 uint32_t getValue() const { return Sym->Value; }
171 uint64_t getRVA() const { return (*data)->getRVA() + sym->Value; }
172 SectionChunk *getChunk() const { return *data; }
173 uint32_t getValue() const { return sym->Value; }
175174
176 SectionChunk **Data;
175 SectionChunk **data;
177176};
178177
179178class DefinedCommon : public DefinedCOFF {
180179public:
181 DefinedCommon(InputFile *F, StringRef N, uint64_t Size,
182 const coff_symbol_generic *S = nullptr,
183 CommonChunk *C = nullptr)
184 : DefinedCOFF(DefinedCommonKind, F, N, S), Data(C), Size(Size) {
185 this->IsExternal = true;
180 DefinedCommon(InputFile *f, StringRef n, uint64_t size,
181 const coff_symbol_generic *s = nullptr,
182 CommonChunk *c = nullptr)
183 : DefinedCOFF(DefinedCommonKind, f, n, s), data(c), size(size) {
184 this->isExternal = true;
186185 }
187186
188 static bool classof(const Symbol *S) {
189 return S->kind() == DefinedCommonKind;
187 static bool classof(const Symbol *s) {
188 return s->kind() == DefinedCommonKind;
190189 }
191190
192 uint64_t getRVA() { return Data->getRVA(); }
193 CommonChunk *getChunk() { return Data; }
191 uint64_t getRVA() { return data->getRVA(); }
192 CommonChunk *getChunk() { return data; }
194193
195194private:
196195 friend SymbolTable;
197 uint64_t getSize() const { return Size; }
198 CommonChunk *Data;
199 uint64_t Size;
196 uint64_t getSize() const { return size; }
197 CommonChunk *data;
198 uint64_t size;
200199};
201200
202201// Absolute symbols.
203202class DefinedAbsolute : public Defined {
204203public:
205 DefinedAbsolute(StringRef N, COFFSymbolRef S)
206 : Defined(DefinedAbsoluteKind, N), VA(S.getValue()) {
207 IsExternal = S.isExternal();
204 DefinedAbsolute(StringRef n, COFFSymbolRef s)
205 : Defined(DefinedAbsoluteKind, n), va(s.getValue()) {
206 isExternal = s.isExternal();
208207 }
209208
210 DefinedAbsolute(StringRef N, uint64_t V)
211 : Defined(DefinedAbsoluteKind, N), VA(V) {}
209 DefinedAbsolute(StringRef n, uint64_t v)
210 : Defined(DefinedAbsoluteKind, n), va(v) {}
212211
213 static bool classof(const Symbol *S) {
214 return S->kind() == DefinedAbsoluteKind;
212 static bool classof(const Symbol *s) {
213 return s->kind() == DefinedAbsoluteKind;
215214 }
216215
217 uint64_t getRVA() { return VA - Config->ImageBase; }
218 void setVA(uint64_t V) { VA = V; }
216 uint64_t getRVA() { return va - config->imageBase; }
217 void setVA(uint64_t v) { va = v; }
219218
220219 // Section index relocations against absolute symbols resolve to
221220 // this 16 bit number, and it is the largest valid section index
222221 // plus one. This variable keeps it.
223 static uint16_t NumOutputSections;
222 static uint16_t numOutputSections;
224223
225224private:
226 uint64_t VA;
225 uint64_t va;
227226};
228227
229228// This symbol is used for linker-synthesized symbols like __ImageBase and
230229// __safe_se_handler_table.
231230class DefinedSynthetic : public Defined {
232231public:
233 explicit DefinedSynthetic(StringRef Name, Chunk *C)
234 : Defined(DefinedSyntheticKind, Name), C(C) {}
232 explicit DefinedSynthetic(StringRef name, Chunk *c)
233 : Defined(DefinedSyntheticKind, name), c(c) {}
235234
236 static bool classof(const Symbol *S) {
237 return S->kind() == DefinedSyntheticKind;
235 static bool classof(const Symbol *s) {
236 return s->kind() == DefinedSyntheticKind;
238237 }
239238
240239 // A null chunk indicates that this is __ImageBase. Otherwise, this is some
241240 // other synthesized chunk, like SEHTableChunk.
242 uint32_t getRVA() { return C ? C->getRVA() : 0; }
243 Chunk *getChunk() { return C; }
241 uint32_t getRVA() { return c ? c->getRVA() : 0; }
242 Chunk *getChunk() { return c; }
244243
245244private:
246 Chunk *C;
245 Chunk *c;
247246};
248247
249248// This class represents a symbol defined in an archive file. It is
......@@ -253,32 +252,32 @@ private:
253252// the same name, it will ask the Lazy to load a file.
254253class Lazy : public Symbol {
255254public:
256 Lazy(ArchiveFile *F, const Archive::Symbol S)
257 : Symbol(LazyKind, S.getName()), File(F), Sym(S) {}
255 Lazy(ArchiveFile *f, const Archive::Symbol s)
256 : Symbol(LazyKind, s.getName()), file(f), sym(s) {}
258257
259 static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
258 static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
260259
261 ArchiveFile *File;
260 ArchiveFile *file;
262261
263262private:
264263 friend SymbolTable;
265264
266265private:
267 const Archive::Symbol Sym;
266 const Archive::Symbol sym;
268267};
269268
270269// Undefined symbols.
271270class Undefined : public Symbol {
272271public:
273 explicit Undefined(StringRef N) : Symbol(UndefinedKind, N) {}
272 explicit Undefined(StringRef n) : Symbol(UndefinedKind, n) {}
274273
275 static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; }
274 static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; }
276275
277276 // An undefined symbol can have a fallback symbol which gives an
278277 // undefined symbol a second chance if it would remain undefined.
279278 // If it remains undefined, it'll be replaced with whatever the
280279 // Alias pointer points to.
281 Symbol *WeakAlias = nullptr;
280 Symbol *weakAlias = nullptr;
282281
283282 // If this symbol is external weak, try to resolve it to a defined
284283 // symbol by searching the chain of fallback symbols. Returns the symbol if
......@@ -294,23 +293,23 @@ public:
294293// table in an output. The former has "__imp_" prefix.
295294class DefinedImportData : public Defined {
296295public:
297 DefinedImportData(StringRef N, ImportFile *F)
298 : Defined(DefinedImportDataKind, N), File(F) {
296 DefinedImportData(StringRef n, ImportFile *f)
297 : Defined(DefinedImportDataKind, n), file(f) {
299298 }
300299
301 static bool classof(const Symbol *S) {
302 return S->kind() == DefinedImportDataKind;
300 static bool classof(const Symbol *s) {
301 return s->kind() == DefinedImportDataKind;
303302 }
304303
305 uint64_t getRVA() { return File->Location->getRVA(); }
306 Chunk *getChunk() { return File->Location; }
307 void setLocation(Chunk *AddressTable) { File->Location = AddressTable; }
304 uint64_t getRVA() { return file->location->getRVA(); }
305 Chunk *getChunk() { return file->location; }
306 void setLocation(Chunk *addressTable) { file->location = addressTable; }
308307
309 StringRef getDLLName() { return File->DLLName; }
310 StringRef getExternalName() { return File->ExternalName; }
311 uint16_t getOrdinal() { return File->Hdr->OrdinalHint; }
308 StringRef getDLLName() { return file->dllName; }
309 StringRef getExternalName() { return file->externalName; }
310 uint16_t getOrdinal() { return file->hdr->OrdinalHint; }
312311
313 ImportFile *File;
312 ImportFile *file;
314313};
315314
316315// This class represents a symbol for a jump table entry which jumps
......@@ -320,19 +319,19 @@ public:
320319// a regular name. A function pointer is given as a DefinedImportData.
321320class DefinedImportThunk : public Defined {
322321public:
323 DefinedImportThunk(StringRef Name, DefinedImportData *S, uint16_t Machine);
322 DefinedImportThunk(StringRef name, DefinedImportData *s, uint16_t machine);
324323
325 static bool classof(const Symbol *S) {
326 return S->kind() == DefinedImportThunkKind;
324 static bool classof(const Symbol *s) {
325 return s->kind() == DefinedImportThunkKind;
327326 }
328327
329 uint64_t getRVA() { return Data->getRVA(); }
330 Chunk *getChunk() { return Data; }
328 uint64_t getRVA() { return data->getRVA(); }
329 Chunk *getChunk() { return data; }
331330
332 DefinedImportData *WrappedSym;
331 DefinedImportData *wrappedSym;
333332
334333private:
335 Chunk *Data;
334 Chunk *data;
336335};
337336
338337// If you have a symbol "foo" in your object file, a symbol name
......@@ -342,18 +341,18 @@ private:
342341// This is here just for compatibility with MSVC.
343342class DefinedLocalImport : public Defined {
344343public:
345 DefinedLocalImport(StringRef N, Defined *S)
346 : Defined(DefinedLocalImportKind, N), Data(make<LocalImportChunk>(S)) {}
344 DefinedLocalImport(StringRef n, Defined *s)
345 : Defined(DefinedLocalImportKind, n), data(make<LocalImportChunk>(s)) {}
347346
348 static bool classof(const Symbol *S) {
349 return S->kind() == DefinedLocalImportKind;
347 static bool classof(const Symbol *s) {
348 return s->kind() == DefinedLocalImportKind;
350349 }
351350
352 uint64_t getRVA() { return Data->getRVA(); }
353 Chunk *getChunk() { return Data; }
351 uint64_t getRVA() { return data->getRVA(); }
352 Chunk *getChunk() { return data; }
354353
355354private:
356 LocalImportChunk *Data;
355 LocalImportChunk *data;
357356};
358357
359358inline uint64_t Defined::getRVA() {
......@@ -406,19 +405,19 @@ inline Chunk *Defined::getChunk() {
406405// object. We allocate memory using this class and instantiate a symbol
407406// using the placement new.
408407union SymbolUnion {
409 alignas(DefinedRegular) char A[sizeof(DefinedRegular)];
410 alignas(DefinedCommon) char B[sizeof(DefinedCommon)];
411 alignas(DefinedAbsolute) char C[sizeof(DefinedAbsolute)];
412 alignas(DefinedSynthetic) char D[sizeof(DefinedSynthetic)];
413 alignas(Lazy) char E[sizeof(Lazy)];
414 alignas(Undefined) char F[sizeof(Undefined)];
415 alignas(DefinedImportData) char G[sizeof(DefinedImportData)];
416 alignas(DefinedImportThunk) char H[sizeof(DefinedImportThunk)];
417 alignas(DefinedLocalImport) char I[sizeof(DefinedLocalImport)];
408 alignas(DefinedRegular) char a[sizeof(DefinedRegular)];
409 alignas(DefinedCommon) char b[sizeof(DefinedCommon)];
410 alignas(DefinedAbsolute) char c[sizeof(DefinedAbsolute)];
411 alignas(DefinedSynthetic) char d[sizeof(DefinedSynthetic)];
412 alignas(Lazy) char e[sizeof(Lazy)];
413 alignas(Undefined) char f[sizeof(Undefined)];
414 alignas(DefinedImportData) char g[sizeof(DefinedImportData)];
415 alignas(DefinedImportThunk) char h[sizeof(DefinedImportThunk)];
416 alignas(DefinedLocalImport) char i[sizeof(DefinedLocalImport)];
418417};
419418
420419template <typename T, typename... ArgT>
421void replaceSymbol(Symbol *S, ArgT &&... Arg) {
420void replaceSymbol(Symbol *s, ArgT &&... arg) {
422421 static_assert(std::is_trivially_destructible<T>(),
423422 "Symbol types must be trivially destructible");
424423 static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
......@@ -426,11 +425,11 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {
426425 "SymbolUnion not aligned enough");
427426 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428427 "Not a Symbol");
429 new (S) T(std::forward<ArgT>(Arg)...);
428 new (s) T(std::forward<ArgT>(arg)...);
430429}
431430} // namespace coff
432431
433std::string toString(coff::Symbol &B);
432std::string toString(coff::Symbol &b);
434433} // namespace lld
435434
436435#endif
deps/lld/COFF/TypeMerger.h created+65
......@@ -0,0 +1,65 @@
1//===- TypeMerger.h ---------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLD_COFF_TYPEMERGER_H
10#define LLD_COFF_TYPEMERGER_H
11
12#include "Config.h"
13#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
14#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
15#include "llvm/Support/Allocator.h"
16
17namespace lld {
18namespace coff {
19
20class TypeMerger {
21public:
22 TypeMerger(llvm::BumpPtrAllocator &alloc)
23 : typeTable(alloc), iDTable(alloc), globalTypeTable(alloc),
24 globalIDTable(alloc) {}
25
26 /// Get the type table or the global type table if /DEBUG:GHASH is enabled.
27 inline llvm::codeview::TypeCollection &getTypeTable() {
28 if (config->debugGHashes)
29 return globalTypeTable;
30 return typeTable;
31 }
32
33 /// Get the ID table or the global ID table if /DEBUG:GHASH is enabled.
34 inline llvm::codeview::TypeCollection &getIDTable() {
35 if (config->debugGHashes)
36 return globalIDTable;
37 return iDTable;
38 }
39
40 /// Type records that will go into the PDB TPI stream.
41 llvm::codeview::MergingTypeTableBuilder typeTable;
42
43 /// Item records that will go into the PDB IPI stream.
44 llvm::codeview::MergingTypeTableBuilder iDTable;
45
46 /// Type records that will go into the PDB TPI stream (for /DEBUG:GHASH)
47 llvm::codeview::GlobalTypeTableBuilder globalTypeTable;
48
49 /// Item records that will go into the PDB IPI stream (for /DEBUG:GHASH)
50 llvm::codeview::GlobalTypeTableBuilder globalIDTable;
51};
52
53/// Map from type index and item index in a type server PDB to the
54/// corresponding index in the destination PDB.
55struct CVIndexMap {
56 llvm::SmallVector<llvm::codeview::TypeIndex, 0> tpiMap;
57 llvm::SmallVector<llvm::codeview::TypeIndex, 0> ipiMap;
58 bool isTypeServerMap = false;
59 bool isPrecompiledTypeMap = false;
60};
61
62} // namespace coff
63} // namespace lld
64
65#endif
\ No newline at end of file
deps/lld/COFF/Writer.cpp+1111-936
......@@ -1,9 +1,8 @@
11//===- Writer.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -17,6 +16,7 @@
1716#include "Symbols.h"
1817#include "lld/Common/ErrorHandler.h"
1918#include "lld/Common/Memory.h"
19#include "lld/Common/Threads.h"
2020#include "lld/Common/Timer.h"
2121#include "llvm/ADT/DenseMap.h"
2222#include "llvm/ADT/STLExtras.h"
......@@ -63,104 +63,129 @@ align 8, db 0
6363$ nasm -fbin /tmp/DOSProgram.asm -o /tmp/DOSProgram.bin
6464$ xxd -i /tmp/DOSProgram.bin
6565*/
66static unsigned char DOSProgram[] = {
66static unsigned char dosProgram[] = {
6767 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c,
6868 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
6969 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65,
7070 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
7171 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x24, 0x00, 0x00
7272};
73static_assert(sizeof(DOSProgram) % 8 == 0,
73static_assert(sizeof(dosProgram) % 8 == 0,
7474 "DOSProgram size must be multiple of 8");
7575
76static const int SectorSize = 512;
77static const int DOSStubSize = sizeof(dos_header) + sizeof(DOSProgram);
78static_assert(DOSStubSize % 8 == 0, "DOSStub size must be multiple of 8");
76static const int dosStubSize = sizeof(dos_header) + sizeof(dosProgram);
77static_assert(dosStubSize % 8 == 0, "DOSStub size must be multiple of 8");
78
79static const int numberOfDataDirectory = 16;
7980
80static const int NumberOfDataDirectory = 16;
81// Global vector of all output sections. After output sections are finalized,
82// this can be indexed by Chunk::getOutputSection.
83static std::vector<OutputSection *> outputSections;
84
85OutputSection *Chunk::getOutputSection() const {
86 return osidx == 0 ? nullptr : outputSections[osidx - 1];
87}
8188
8289namespace {
8390
84class DebugDirectoryChunk : public Chunk {
91class DebugDirectoryChunk : public NonSectionChunk {
8592public:
86 DebugDirectoryChunk(const std::vector<Chunk *> &R, bool WriteRepro)
87 : Records(R), WriteRepro(WriteRepro) {}
93 DebugDirectoryChunk(const std::vector<Chunk *> &r, bool writeRepro)
94 : records(r), writeRepro(writeRepro) {}
8895
8996 size_t getSize() const override {
90 return (Records.size() + int(WriteRepro)) * sizeof(debug_directory);
97 return (records.size() + int(writeRepro)) * sizeof(debug_directory);
9198 }
9299
93 void writeTo(uint8_t *B) const override {
94 auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
100 void writeTo(uint8_t *b) const override {
101 auto *d = reinterpret_cast<debug_directory *>(b);
95102
96 for (const Chunk *Record : Records) {
97 OutputSection *OS = Record->getOutputSection();
98 uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA());
99 fillEntry(D, COFF::IMAGE_DEBUG_TYPE_CODEVIEW, Record->getSize(),
100 Record->getRVA(), Offs);
101 ++D;
103 for (const Chunk *record : records) {
104 OutputSection *os = record->getOutputSection();
105 uint64_t offs = os->getFileOff() + (record->getRVA() - os->getRVA());
106 fillEntry(d, COFF::IMAGE_DEBUG_TYPE_CODEVIEW, record->getSize(),
107 record->getRVA(), offs);
108 ++d;
102109 }
103110
104 if (WriteRepro) {
111 if (writeRepro) {
105112 // FIXME: The COFF spec allows either a 0-sized entry to just say
106113 // "the timestamp field is really a hash", or a 4-byte size field
107114 // followed by that many bytes containing a longer hash (with the
108115 // lowest 4 bytes usually being the timestamp in little-endian order).
109116 // Consider storing the full 8 bytes computed by xxHash64 here.
110 fillEntry(D, COFF::IMAGE_DEBUG_TYPE_REPRO, 0, 0, 0);
117 fillEntry(d, COFF::IMAGE_DEBUG_TYPE_REPRO, 0, 0, 0);
111118 }
112119 }
113120
114 void setTimeDateStamp(uint32_t TimeDateStamp) {
115 for (support::ulittle32_t *TDS : TimeDateStamps)
116 *TDS = TimeDateStamp;
121 void setTimeDateStamp(uint32_t timeDateStamp) {
122 for (support::ulittle32_t *tds : timeDateStamps)
123 *tds = timeDateStamp;
117124 }
118125
119126private:
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
134 mutable std::vector<support::ulittle32_t *> TimeDateStamps;
135 const std::vector<Chunk *> &Records;
136 bool WriteRepro;
127 void fillEntry(debug_directory *d, COFF::DebugType debugType, size_t size,
128 uint64_t rva, uint64_t offs) const {
129 d->Characteristics = 0;
130 d->TimeDateStamp = 0;
131 d->MajorVersion = 0;
132 d->MinorVersion = 0;
133 d->Type = debugType;
134 d->SizeOfData = size;
135 d->AddressOfRawData = rva;
136 d->PointerToRawData = offs;
137
138 timeDateStamps.push_back(&d->TimeDateStamp);
139 }
140
141 mutable std::vector<support::ulittle32_t *> timeDateStamps;
142 const std::vector<Chunk *> &records;
143 bool writeRepro;
137144};
138145
139class CVDebugRecordChunk : public Chunk {
146class CVDebugRecordChunk : public NonSectionChunk {
140147public:
141148 size_t getSize() const override {
142 return sizeof(codeview::DebugInfo) + Config->PDBAltPath.size() + 1;
149 return sizeof(codeview::DebugInfo) + config->pdbAltPath.size() + 1;
143150 }
144151
145 void writeTo(uint8_t *B) const override {
152 void writeTo(uint8_t *b) const override {
146153 // Save off the DebugInfo entry to backfill the file signature (build id)
147154 // in Writer::writeBuildId
148 BuildId = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff);
155 buildId = reinterpret_cast<codeview::DebugInfo *>(b);
149156
150157 // variable sized field (PDB Path)
151 char *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*BuildId));
152 if (!Config->PDBAltPath.empty())
153 memcpy(P, Config->PDBAltPath.data(), Config->PDBAltPath.size());
154 P[Config->PDBAltPath.size()] = '\0';
158 char *p = reinterpret_cast<char *>(b + sizeof(*buildId));
159 if (!config->pdbAltPath.empty())
160 memcpy(p, config->pdbAltPath.data(), config->pdbAltPath.size());
161 p[config->pdbAltPath.size()] = '\0';
155162 }
156163
157 mutable codeview::DebugInfo *BuildId = nullptr;
164 mutable codeview::DebugInfo *buildId = nullptr;
165};
166
167// PartialSection represents a group of chunks that contribute to an
168// OutputSection. Collating a collection of PartialSections of same name and
169// characteristics constitutes the OutputSection.
170class PartialSectionKey {
171public:
172 StringRef name;
173 unsigned characteristics;
174
175 bool operator<(const PartialSectionKey &other) const {
176 int c = name.compare(other.name);
177 if (c == 1)
178 return false;
179 if (c == 0)
180 return characteristics < other.characteristics;
181 return true;
182 }
158183};
159184
160185// The writer writes a SymbolTable result to a file.
161186class Writer {
162187public:
163 Writer() : Buffer(errorHandler().OutputBuffer) {}
188 Writer() : buffer(errorHandler().outputBuffer) {}
164189 void run();
165190
166191private:
......@@ -168,78 +193,81 @@ private:
168193 void createMiscChunks();
169194 void createImportTables();
170195 void appendImportThunks();
171 void locateImportTables(
172 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> &Map);
196 void locateImportTables();
173197 void createExportTable();
174198 void mergeSections();
175 void readRelocTargets();
176199 void removeUnusedSections();
177200 void assignAddresses();
178201 void finalizeAddresses();
179202 void removeEmptySections();
203 void assignOutputSectionIndices();
180204 void createSymbolAndStringTable();
181 void openFile(StringRef OutputPath);
205 void openFile(StringRef outputPath);
182206 template <typename PEHeaderTy> void writeHeader();
183207 void createSEHTable();
184208 void createRuntimePseudoRelocs();
185209 void insertCtorDtorSymbols();
186210 void createGuardCFTables();
187 void markSymbolsForRVATable(ObjFile *File,
188 ArrayRef<SectionChunk *> SymIdxChunks,
189 SymbolRVASet &TableSymbols);
190 void maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym,
191 StringRef CountSym);
211 void markSymbolsForRVATable(ObjFile *file,
212 ArrayRef<SectionChunk *> symIdxChunks,
213 SymbolRVASet &tableSymbols);
214 void maybeAddRVATable(SymbolRVASet tableSymbols, StringRef tableSym,
215 StringRef countSym);
192216 void setSectionPermissions();
193217 void writeSections();
194218 void writeBuildId();
195219 void sortExceptionTable();
196 void sortCRTSectionChunks(std::vector<Chunk *> &Chunks);
220 void sortCRTSectionChunks(std::vector<Chunk *> &chunks);
221 void addSyntheticIdata();
222 void fixPartialSectionChars(StringRef name, uint32_t chars);
223 bool fixGnuImportChunks();
224 PartialSection *createPartialSection(StringRef name, uint32_t outChars);
225 PartialSection *findPartialSection(StringRef name, uint32_t outChars);
197226
198 llvm::Optional<coff_symbol16> createSymbol(Defined *D);
199 size_t addEntryToStringTable(StringRef Str);
227 llvm::Optional<coff_symbol16> createSymbol(Defined *d);
228 size_t addEntryToStringTable(StringRef str);
200229
201 OutputSection *findSection(StringRef Name);
230 OutputSection *findSection(StringRef name);
202231 void addBaserels();
203 void addBaserelBlocks(std::vector<Baserel> &V);
232 void addBaserelBlocks(std::vector<Baserel> &v);
204233
205234 uint32_t getSizeOfInitializedData();
206 std::map<StringRef, std::vector<DefinedImportData *>> binImports();
207
208 std::unique_ptr<FileOutputBuffer> &Buffer;
209 std::vector<OutputSection *> OutputSections;
210 std::vector<char> Strtab;
211 std::vector<llvm::object::coff_symbol16> OutputSymtab;
212 IdataContents Idata;
213 Chunk *ImportTableStart = nullptr;
214 uint64_t ImportTableSize = 0;
215 Chunk *IATStart = nullptr;
216 uint64_t IATSize = 0;
217 DelayLoadContents DelayIdata;
218 EdataContents Edata;
219 bool SetNoSEHCharacteristic = false;
220
221 DebugDirectoryChunk *DebugDirectory = nullptr;
222 std::vector<Chunk *> DebugRecords;
223 CVDebugRecordChunk *BuildId = nullptr;
224 ArrayRef<uint8_t> SectionTable;
225
226 uint64_t FileSize;
227 uint32_t PointerToSymbolTable = 0;
228 uint64_t SizeOfImage;
229 uint64_t SizeOfHeaders;
230
231 OutputSection *TextSec;
232 OutputSection *RdataSec;
233 OutputSection *BuildidSec;
234 OutputSection *DataSec;
235 OutputSection *PdataSec;
236 OutputSection *IdataSec;
237 OutputSection *EdataSec;
238 OutputSection *DidatSec;
239 OutputSection *RsrcSec;
240 OutputSection *RelocSec;
241 OutputSection *CtorsSec;
242 OutputSection *DtorsSec;
235
236 std::unique_ptr<FileOutputBuffer> &buffer;
237 std::map<PartialSectionKey, PartialSection *> partialSections;
238 std::vector<char> strtab;
239 std::vector<llvm::object::coff_symbol16> outputSymtab;
240 IdataContents idata;
241 Chunk *importTableStart = nullptr;
242 uint64_t importTableSize = 0;
243 Chunk *iatStart = nullptr;
244 uint64_t iatSize = 0;
245 DelayLoadContents delayIdata;
246 EdataContents edata;
247 bool setNoSEHCharacteristic = false;
248
249 DebugDirectoryChunk *debugDirectory = nullptr;
250 std::vector<Chunk *> debugRecords;
251 CVDebugRecordChunk *buildId = nullptr;
252 ArrayRef<uint8_t> sectionTable;
253
254 uint64_t fileSize;
255 uint32_t pointerToSymbolTable = 0;
256 uint64_t sizeOfImage;
257 uint64_t sizeOfHeaders;
258
259 OutputSection *textSec;
260 OutputSection *rdataSec;
261 OutputSection *buildidSec;
262 OutputSection *dataSec;
263 OutputSection *pdataSec;
264 OutputSection *idataSec;
265 OutputSection *edataSec;
266 OutputSection *didatSec;
267 OutputSection *rsrcSec;
268 OutputSection *relocSec;
269 OutputSection *ctorsSec;
270 OutputSection *dtorsSec;
243271
244272 // The first and last .pdata sections in the output file.
245273 //
......@@ -250,82 +278,85 @@ private:
250278 // are entirely linker-generated we can keep track of their locations using
251279 // the chunks that the linker creates. All .pdata chunks come from input
252280 // files, so we need to keep track of them separately.
253 Chunk *FirstPdata = nullptr;
254 Chunk *LastPdata;
281 Chunk *firstPdata = nullptr;
282 Chunk *lastPdata;
255283};
256284} // anonymous namespace
257285
258286namespace lld {
259287namespace coff {
260288
261static Timer CodeLayoutTimer("Code Layout", Timer::root());
262static Timer DiskCommitTimer("Commit Output File", Timer::root());
289static Timer codeLayoutTimer("Code Layout", Timer::root());
290static Timer diskCommitTimer("Commit Output File", Timer::root());
263291
264292void writeResult() { Writer().run(); }
265293
266void OutputSection::addChunk(Chunk *C) {
267 Chunks.push_back(C);
268 C->setOutputSection(this);
294void OutputSection::addChunk(Chunk *c) {
295 chunks.push_back(c);
269296}
270297
271void OutputSection::insertChunkAtStart(Chunk *C) {
272 Chunks.insert(Chunks.begin(), C);
273 C->setOutputSection(this);
298void OutputSection::insertChunkAtStart(Chunk *c) {
299 chunks.insert(chunks.begin(), c);
274300}
275301
276void OutputSection::setPermissions(uint32_t C) {
277 Header.Characteristics &= ~PermMask;
278 Header.Characteristics |= C;
302void OutputSection::setPermissions(uint32_t c) {
303 header.Characteristics &= ~permMask;
304 header.Characteristics |= c;
279305}
280306
281void OutputSection::merge(OutputSection *Other) {
282 for (Chunk *C : Other->Chunks)
283 C->setOutputSection(this);
284 Chunks.insert(Chunks.end(), Other->Chunks.begin(), Other->Chunks.end());
285 Other->Chunks.clear();
307void OutputSection::merge(OutputSection *other) {
308 chunks.insert(chunks.end(), other->chunks.begin(), other->chunks.end());
309 other->chunks.clear();
310 contribSections.insert(contribSections.end(), other->contribSections.begin(),
311 other->contribSections.end());
312 other->contribSections.clear();
286313}
287314
288315// Write the section header to a given buffer.
289void OutputSection::writeHeaderTo(uint8_t *Buf) {
290 auto *Hdr = reinterpret_cast<coff_section *>(Buf);
291 *Hdr = Header;
292 if (StringTableOff) {
316void OutputSection::writeHeaderTo(uint8_t *buf) {
317 auto *hdr = reinterpret_cast<coff_section *>(buf);
318 *hdr = header;
319 if (stringTableOff) {
293320 // If name is too long, write offset into the string table as a name.
294 sprintf(Hdr->Name, "/%d", StringTableOff);
321 sprintf(hdr->Name, "/%d", stringTableOff);
295322 } else {
296 assert(!Config->Debug || Name.size() <= COFF::NameSize ||
297 (Hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0);
298 strncpy(Hdr->Name, Name.data(),
299 std::min(Name.size(), (size_t)COFF::NameSize));
323 assert(!config->debug || name.size() <= COFF::NameSize ||
324 (hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0);
325 strncpy(hdr->Name, name.data(),
326 std::min(name.size(), (size_t)COFF::NameSize));
300327 }
301328}
302329
330void OutputSection::addContributingPartialSection(PartialSection *sec) {
331 contribSections.push_back(sec);
332}
333
303334} // namespace coff
304335} // namespace lld
305336
306337// 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) {
338// of type relType at address P.
339static bool isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin) {
340 if (config->machine == ARMNT) {
341 int64_t diff = AbsoluteDifference(s, p + 4) + margin;
342 switch (relType) {
312343 case IMAGE_REL_ARM_BRANCH20T:
313 return isInt<21>(Diff);
344 return isInt<21>(diff);
314345 case IMAGE_REL_ARM_BRANCH24T:
315346 case IMAGE_REL_ARM_BLX23T:
316 return isInt<25>(Diff);
347 return isInt<25>(diff);
317348 default:
318349 return true;
319350 }
320 } else if (Config->Machine == ARM64) {
321 int64_t Diff = AbsoluteDifference(S, P) + Margin;
322 switch (RelType) {
351 } else if (config->machine == ARM64) {
352 int64_t diff = AbsoluteDifference(s, p) + margin;
353 switch (relType) {
323354 case IMAGE_REL_ARM64_BRANCH26:
324 return isInt<28>(Diff);
355 return isInt<28>(diff);
325356 case IMAGE_REL_ARM64_BRANCH19:
326 return isInt<21>(Diff);
357 return isInt<21>(diff);
327358 case IMAGE_REL_ARM64_BRANCH14:
328 return isInt<16>(Diff);
359 return isInt<16>(diff);
329360 default:
330361 return true;
331362 }
......@@ -337,25 +368,25 @@ static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) {
337368// Return the last thunk for the given target if it is in range,
338369// or create a new one.
339370static 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) {
371getThunk(DenseMap<uint64_t, Defined *> &lastThunks, Defined *target, uint64_t p,
372 uint16_t type, int margin) {
373 Defined *&lastThunk = lastThunks[target->getRVA()];
374 if (lastThunk && isInRange(type, lastThunk->getRVA(), p, margin))
375 return {lastThunk, false};
376 Chunk *c;
377 switch (config->machine) {
347378 case ARMNT:
348 C = make<RangeExtensionThunkARM>(Target);
379 c = make<RangeExtensionThunkARM>(target);
349380 break;
350381 case ARM64:
351 C = make<RangeExtensionThunkARM64>(Target);
382 c = make<RangeExtensionThunkARM64>(target);
352383 break;
353384 default:
354385 llvm_unreachable("Unexpected architecture");
355386 }
356 Defined *D = make<DefinedSynthetic>("", C);
357 LastThunk = D;
358 return {D, true};
387 Defined *d = make<DefinedSynthetic>("", c);
388 lastThunk = d;
389 return {d, true};
359390}
360391
361392// This checks all relocations, and for any relocation which isn't in range
......@@ -369,82 +400,124 @@ getThunk(DenseMap<uint64_t, Defined *> &LastThunks, Defined *Target, uint64_t P,
369400// After adding thunks, we verify that all relocations are in range (with
370401// no extra margin requirements). If this failed, we restart (throwing away
371402// 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;
403static bool createThunks(OutputSection *os, int margin) {
404 bool addressesChanged = false;
405 DenseMap<uint64_t, Defined *> lastThunks;
406 DenseMap<std::pair<ObjFile *, Defined *>, uint32_t> thunkSymtabIndices;
407 size_t thunksSize = 0;
376408 // Recheck Chunks.size() each iteration, since we can insert more
377409 // 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)
410 for (size_t i = 0; i != os->chunks.size(); ++i) {
411 SectionChunk *sc = dyn_cast_or_null<SectionChunk>(os->chunks[i]);
412 if (!sc)
381413 continue;
382 size_t ThunkInsertionSpot = I + 1;
414 size_t thunkInsertionSpot = i + 1;
383415
384416 // Try to get a good enough estimate of where new thunks will be placed.
385417 // Offset this by the size of the new thunks added so far, to make the
386418 // 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];
419 size_t thunkInsertionRVA = sc->getRVA() + sc->getSize() + thunksSize;
420 ObjFile *file = sc->file;
421 std::vector<std::pair<uint32_t, uint32_t>> relocReplacements;
422 ArrayRef<coff_relocation> originalRelocs =
423 file->getCOFFObj()->getRelocations(sc->header);
424 for (size_t j = 0, e = originalRelocs.size(); j < e; ++j) {
425 const coff_relocation &rel = originalRelocs[j];
426 Symbol *relocTarget = file->getSymbol(rel.SymbolTableIndex);
391427
392428 // The estimate of the source address P should be pretty accurate,
393429 // 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
430 // offset by thunksSize or not (or by some of thunksSize but not all of
395431 // it), giving us some uncertainty once we have added one thunk.
396 uint64_t P = SC->getRVA() + Rel.VirtualAddress + ThunksSize;
432 uint64_t p = sc->getRVA() + rel.VirtualAddress + thunksSize;
397433
398 Defined *Sym = dyn_cast_or_null<Defined>(RelocTarget);
399 if (!Sym)
434 Defined *sym = dyn_cast_or_null<Defined>(relocTarget);
435 if (!sym)
400436 continue;
401437
402 uint64_t S = Sym->getRVA();
438 uint64_t s = sym->getRVA();
403439
404 if (isInRange(Rel.Type, S, P, Margin))
440 if (isInRange(rel.Type, s, p, margin))
405441 continue;
406442
407443 // If the target isn't in range, hook it up to an existing or new
408444 // 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;
445 Defined *thunk;
446 bool wasNew;
447 std::tie(thunk, wasNew) = getThunk(lastThunks, sym, p, rel.Type, margin);
448 if (wasNew) {
449 Chunk *thunkChunk = thunk->getChunk();
450 thunkChunk->setRVA(
451 thunkInsertionRVA); // Estimate of where it will be located.
452 os->chunks.insert(os->chunks.begin() + thunkInsertionSpot, thunkChunk);
453 thunkInsertionSpot++;
454 thunksSize += thunkChunk->getSize();
455 thunkInsertionRVA += thunkChunk->getSize();
456 addressesChanged = true;
457 }
458
459 // To redirect the relocation, add a symbol to the parent object file's
460 // symbol table, and replace the relocation symbol table index with the
461 // new index.
462 auto insertion = thunkSymtabIndices.insert({{file, thunk}, ~0U});
463 uint32_t &thunkSymbolIndex = insertion.first->second;
464 if (insertion.second)
465 thunkSymbolIndex = file->addRangeThunkSymbol(thunk);
466 relocReplacements.push_back({j, thunkSymbolIndex});
467 }
468
469 // Get a writable copy of this section's relocations so they can be
470 // modified. If the relocations point into the object file, allocate new
471 // memory. Otherwise, this must be previously allocated memory that can be
472 // modified in place.
473 ArrayRef<coff_relocation> curRelocs = sc->getRelocs();
474 MutableArrayRef<coff_relocation> newRelocs;
475 if (originalRelocs.data() == curRelocs.data()) {
476 newRelocs = makeMutableArrayRef(
477 bAlloc.Allocate<coff_relocation>(originalRelocs.size()),
478 originalRelocs.size());
479 } else {
480 newRelocs = makeMutableArrayRef(
481 const_cast<coff_relocation *>(curRelocs.data()), curRelocs.size());
482 }
483
484 // Copy each relocation, but replace the symbol table indices which need
485 // thunks.
486 auto nextReplacement = relocReplacements.begin();
487 auto endReplacement = relocReplacements.end();
488 for (size_t i = 0, e = originalRelocs.size(); i != e; ++i) {
489 newRelocs[i] = originalRelocs[i];
490 if (nextReplacement != endReplacement && nextReplacement->first == i) {
491 newRelocs[i].SymbolTableIndex = nextReplacement->second;
492 ++nextReplacement;
422493 }
423 RelocTarget = Thunk;
424494 }
495
496 sc->setRelocs(newRelocs);
425497 }
426 return AddressesChanged;
498 return addressesChanged;
427499}
428500
429501// 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)
502static bool verifyRanges(const std::vector<Chunk *> chunks) {
503 for (Chunk *c : chunks) {
504 SectionChunk *sc = dyn_cast_or_null<SectionChunk>(c);
505 if (!sc)
434506 continue;
435507
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];
508 ArrayRef<coff_relocation> relocs = sc->getRelocs();
509 for (size_t j = 0, e = relocs.size(); j < e; ++j) {
510 const coff_relocation &rel = relocs[j];
511 Symbol *relocTarget = sc->file->getSymbol(rel.SymbolTableIndex);
439512
440 Defined *Sym = dyn_cast_or_null<Defined>(RelocTarget);
441 if (!Sym)
513 Defined *sym = dyn_cast_or_null<Defined>(relocTarget);
514 if (!sym)
442515 continue;
443516
444 uint64_t P = SC->getRVA() + Rel.VirtualAddress;
445 uint64_t S = Sym->getRVA();
517 uint64_t p = sc->getRVA() + rel.VirtualAddress;
518 uint64_t s = sym->getRVA();
446519
447 if (!isInRange(Rel.Type, S, P, 0))
520 if (!isInRange(rel.Type, s, p, 0))
448521 return false;
449522 }
450523 }
......@@ -454,71 +527,68 @@ static bool verifyRanges(const std::vector<Chunk *> Chunks) {
454527// Assign addresses and add thunks if necessary.
455528void Writer::finalizeAddresses() {
456529 assignAddresses();
457 if (Config->Machine != ARMNT && Config->Machine != ARM64)
530 if (config->machine != ARMNT && config->machine != ARM64)
458531 return;
459532
460 size_t OrigNumChunks = 0;
461 for (OutputSection *Sec : OutputSections) {
462 Sec->OrigChunks = Sec->Chunks;
463 OrigNumChunks += Sec->Chunks.size();
533 size_t origNumChunks = 0;
534 for (OutputSection *sec : outputSections) {
535 sec->origChunks = sec->chunks;
536 origNumChunks += sec->chunks.size();
464537 }
465538
466 int Pass = 0;
467 int Margin = 1024 * 100;
539 int pass = 0;
540 int margin = 1024 * 100;
468541 while (true) {
469542 // First check whether we need thunks at all, or if the previous pass of
470543 // 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;
544 bool rangesOk = true;
545 size_t numChunks = 0;
546 for (OutputSection *sec : outputSections) {
547 if (!verifyRanges(sec->chunks)) {
548 rangesOk = false;
476549 break;
477550 }
478 NumChunks += Sec->Chunks.size();
551 numChunks += sec->chunks.size();
479552 }
480 if (RangesOk) {
481 if (Pass > 0)
482 log("Added " + Twine(NumChunks - OrigNumChunks) + " thunks with " +
483 "margin " + Twine(Margin) + " in " + Twine(Pass) + " passes");
553 if (rangesOk) {
554 if (pass > 0)
555 log("Added " + Twine(numChunks - origNumChunks) + " thunks with " +
556 "margin " + Twine(margin) + " in " + Twine(pass) + " passes");
484557 return;
485558 }
486559
487 if (Pass >= 10)
488 fatal("adding thunks hasn't converged after " + Twine(Pass) + " passes");
560 if (pass >= 10)
561 fatal("adding thunks hasn't converged after " + Twine(pass) + " passes");
489562
490 if (Pass > 0) {
563 if (pass > 0) {
491564 // If the previous pass didn't work out, reset everything back to the
492565 // original conditions before retrying with a wider margin. This should
493566 // 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;
567 for (OutputSection *sec : outputSections)
568 sec->chunks = sec->origChunks;
569 margin *= 2;
500570 }
501571
502572 // Try adding thunks everywhere where it is needed, with a margin
503573 // 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);
574 bool addressesChanged = false;
575 for (OutputSection *sec : outputSections)
576 addressesChanged |= createThunks(sec, margin);
507577 // If the verification above thought we needed thunks, we should have
508578 // added some.
509 assert(AddressesChanged);
579 assert(addressesChanged);
510580
511581 // Recalculate the layout for the whole image (and verify the ranges at
512582 // the start of the next round).
513583 assignAddresses();
514584
515 Pass++;
585 pass++;
516586 }
517587}
518588
519589// The main function of the writer.
520590void Writer::run() {
521 ScopedTimer T1(CodeLayoutTimer);
591 ScopedTimer t1(codeLayoutTimer);
522592
523593 createImportTables();
524594 createSections();
......@@ -526,19 +596,19 @@ void Writer::run() {
526596 appendImportThunks();
527597 createExportTable();
528598 mergeSections();
529 readRelocTargets();
530599 removeUnusedSections();
531600 finalizeAddresses();
532601 removeEmptySections();
602 assignOutputSectionIndices();
533603 setSectionPermissions();
534604 createSymbolAndStringTable();
535605
536 if (FileSize > UINT32_MAX)
537 fatal("image size (" + Twine(FileSize) + ") " +
606 if (fileSize > UINT32_MAX)
607 fatal("image size (" + Twine(fileSize) + ") " +
538608 "exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")");
539609
540 openFile(Config->OutputFile);
541 if (Config->is64()) {
610 openFile(config->outputFile);
611 if (config->is64()) {
542612 writeHeader<pe32plus_header>();
543613 } else {
544614 writeHeader<pe32_header>();
......@@ -546,42 +616,59 @@ void Writer::run() {
546616 writeSections();
547617 sortExceptionTable();
548618
549 T1.stop();
619 t1.stop();
550620
551 if (!Config->PDBPath.empty() && Config->Debug) {
552 assert(BuildId);
553 createPDB(Symtab, OutputSections, SectionTable, BuildId->BuildId);
621 if (!config->pdbPath.empty() && config->debug) {
622 assert(buildId);
623 createPDB(symtab, outputSections, sectionTable, buildId->buildId);
554624 }
555625 writeBuildId();
556626
557 writeMapFile(OutputSections);
627 writeMapFile(outputSections);
558628
559 ScopedTimer T2(DiskCommitTimer);
560 if (auto E = Buffer->commit())
561 fatal("failed to write the output file: " + toString(std::move(E)));
629 ScopedTimer t2(diskCommitTimer);
630 if (auto e = buffer->commit())
631 fatal("failed to write the output file: " + toString(std::move(e)));
562632}
563633
564static StringRef getOutputSectionName(StringRef Name) {
565 StringRef S = Name.split('$').first;
634static StringRef getOutputSectionName(StringRef name) {
635 StringRef s = name.split('$').first;
566636
567637 // Treat a later period as a separator for MinGW, for sections like
568638 // ".ctors.01234".
569 return S.substr(0, S.find('.', 1));
639 return s.substr(0, s.find('.', 1));
570640}
571641
572642// For /order.
573static void sortBySectionOrder(std::vector<Chunk *> &Chunks) {
574 auto GetPriority = [](const Chunk *C) {
575 if (auto *Sec = dyn_cast<SectionChunk>(C))
576 if (Sec->Sym)
577 return Config->Order.lookup(Sec->Sym->getName());
643static void sortBySectionOrder(std::vector<Chunk *> &chunks) {
644 auto getPriority = [](const Chunk *c) {
645 if (auto *sec = dyn_cast<SectionChunk>(c))
646 if (sec->sym)
647 return config->order.lookup(sec->sym->getName());
578648 return 0;
579649 };
580650
581 std::stable_sort(Chunks.begin(), Chunks.end(),
582 [=](const Chunk *A, const Chunk *B) {
583 return GetPriority(A) < GetPriority(B);
584 });
651 llvm::stable_sort(chunks, [=](const Chunk *a, const Chunk *b) {
652 return getPriority(a) < getPriority(b);
653 });
654}
655
656// Change the characteristics of existing PartialSections that belong to the
657// section Name to Chars.
658void Writer::fixPartialSectionChars(StringRef name, uint32_t chars) {
659 for (auto it : partialSections) {
660 PartialSection *pSec = it.second;
661 StringRef curName = pSec->name;
662 if (!curName.consume_front(name) ||
663 (!curName.empty() && !curName.startswith("$")))
664 continue;
665 if (pSec->characteristics == chars)
666 continue;
667 PartialSection *destSec = createPartialSection(pSec->name, chars);
668 destSec->chunks.insert(destSec->chunks.end(), pSec->chunks.begin(),
669 pSec->chunks.end());
670 pSec->chunks.clear();
671 }
585672}
586673
587674// Sort concrete section chunks from GNU import libraries.
......@@ -594,249 +681,269 @@ static void sortBySectionOrder(std::vector<Chunk *> &Chunks) {
594681// be formed correctly, the section chunks within each .idata$* section need
595682// to be grouped by library, and sorted alphabetically within each library
596683// (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;
684bool Writer::fixGnuImportChunks() {
685 uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
600686
601687 // Make sure all .idata$* section chunks are mapped as RDATA in order to
602688 // 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 }
689 fixPartialSectionChars(".idata", rdata);
615690
616 bool HasIdata = false;
691 bool hasIdata = false;
617692 // Sort all .idata$* chunks, grouping chunks from the same library,
618693 // 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"))
694 for (auto it : partialSections) {
695 PartialSection *pSec = it.second;
696 if (!pSec->name.startswith(".idata"))
622697 continue;
623698
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) {
699 if (!pSec->chunks.empty())
700 hasIdata = true;
701 llvm::stable_sort(pSec->chunks, [&](Chunk *s, Chunk *t) {
702 SectionChunk *sc1 = dyn_cast_or_null<SectionChunk>(s);
703 SectionChunk *sc2 = dyn_cast_or_null<SectionChunk>(t);
704 if (!sc1 || !sc2) {
631705 // if SC1, order them ascending. If SC2 or both null,
632706 // S is not less than T.
633 return SC1 != nullptr;
707 return sc1 != nullptr;
634708 }
635709 // Make a string with "libraryname/objectfile" for sorting, achieving
636710 // both grouping by library and sorting of objects within a library,
637711 // 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;
712 std::string key1 =
713 (sc1->file->parentName + "/" + sc1->file->getName()).str();
714 std::string key2 =
715 (sc2->file->parentName + "/" + sc2->file->getName()).str();
716 return key1 < key2;
643717 });
644718 }
645 return HasIdata;
719 return hasIdata;
646720}
647721
648722// Add generated idata chunks, for imported symbols and DLLs, and a
649723// 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();
724void Writer::addSyntheticIdata() {
725 uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
726 idata.create();
655727
656728 // Add the .idata content in the right section groups, to allow
657729 // chunks from other linked in object files to be grouped together.
658730 // 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());
731 auto add = [&](StringRef n, std::vector<Chunk *> &v) {
732 PartialSection *pSec = createPartialSection(n, rdata);
733 pSec->chunks.insert(pSec->chunks.end(), v.begin(), v.end());
662734 };
663735
664736 // The loader assumes a specific order of data.
665737 // 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);
738 add(".idata$2", idata.dirs);
739 add(".idata$4", idata.lookups);
740 add(".idata$5", idata.addresses);
741 add(".idata$6", idata.hints);
742 add(".idata$7", idata.dllNames);
671743}
672744
673745// Locate the first Chunk and size of the import directory list and the
674746// 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();
747void Writer::locateImportTables() {
748 uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
749
750 if (PartialSection *importDirs = findPartialSection(".idata$2", rdata)) {
751 if (!importDirs->chunks.empty())
752 importTableStart = importDirs->chunks.front();
753 for (Chunk *c : importDirs->chunks)
754 importTableSize += c->getSize();
755 }
756
757 if (PartialSection *importAddresses = findPartialSection(".idata$5", rdata)) {
758 if (!importAddresses->chunks.empty())
759 iatStart = importAddresses->chunks.front();
760 for (Chunk *c : importAddresses->chunks)
761 iatSize += c->getSize();
762 }
763}
764
765// Return whether a SectionChunk's suffix (the dollar and any trailing
766// suffix) should be removed and sorted into the main suffixless
767// PartialSection.
768static bool shouldStripSectionSuffix(SectionChunk *sc, StringRef name) {
769 // On MinGW, comdat groups are formed by putting the comdat group name
770 // after the '$' in the section name. For .eh_frame$<symbol>, that must
771 // still be sorted before the .eh_frame trailer from crtend.o, thus just
772 // strip the section name trailer. For other sections, such as
773 // .tls$$<symbol> (where non-comdat .tls symbols are otherwise stored in
774 // ".tls$"), they must be strictly sorted after .tls. And for the
775 // hypothetical case of comdat .CRT$XCU, we definitely need to keep the
776 // suffix for sorting. Thus, to play it safe, only strip the suffix for
777 // the standard sections.
778 if (!config->mingw)
779 return false;
780 if (!sc || !sc->isCOMDAT())
781 return false;
782 return name.startswith(".text$") || name.startswith(".data$") ||
783 name.startswith(".rdata$") || name.startswith(".pdata$") ||
784 name.startswith(".xdata$") || name.startswith(".eh_frame$");
689785}
690786
691787// Create output section objects and add them to OutputSections.
692788void Writer::createSections() {
693789 // First, create the builtin sections.
694 const uint32_t DATA = IMAGE_SCN_CNT_INITIALIZED_DATA;
695 const uint32_t BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA;
696 const uint32_t CODE = IMAGE_SCN_CNT_CODE;
697 const uint32_t DISCARDABLE = IMAGE_SCN_MEM_DISCARDABLE;
698 const uint32_t R = IMAGE_SCN_MEM_READ;
699 const uint32_t W = IMAGE_SCN_MEM_WRITE;
700 const uint32_t X = IMAGE_SCN_MEM_EXECUTE;
701
702 SmallDenseMap<std::pair<StringRef, uint32_t>, OutputSection *> Sections;
703 auto CreateSection = [&](StringRef Name, uint32_t OutChars) {
704 OutputSection *&Sec = Sections[{Name, OutChars}];
705 if (!Sec) {
706 Sec = make<OutputSection>(Name, OutChars);
707 OutputSections.push_back(Sec);
790 const uint32_t data = IMAGE_SCN_CNT_INITIALIZED_DATA;
791 const uint32_t bss = IMAGE_SCN_CNT_UNINITIALIZED_DATA;
792 const uint32_t code = IMAGE_SCN_CNT_CODE;
793 const uint32_t discardable = IMAGE_SCN_MEM_DISCARDABLE;
794 const uint32_t r = IMAGE_SCN_MEM_READ;
795 const uint32_t w = IMAGE_SCN_MEM_WRITE;
796 const uint32_t x = IMAGE_SCN_MEM_EXECUTE;
797
798 SmallDenseMap<std::pair<StringRef, uint32_t>, OutputSection *> sections;
799 auto createSection = [&](StringRef name, uint32_t outChars) {
800 OutputSection *&sec = sections[{name, outChars}];
801 if (!sec) {
802 sec = make<OutputSection>(name, outChars);
803 outputSections.push_back(sec);
708804 }
709 return Sec;
805 return sec;
710806 };
711807
712808 // Try to match the section order used by link.exe.
713 TextSec = CreateSection(".text", CODE | R | X);
714 CreateSection(".bss", BSS | R | W);
715 RdataSec = CreateSection(".rdata", DATA | R);
716 BuildidSec = CreateSection(".buildid", DATA | R);
717 DataSec = CreateSection(".data", DATA | R | W);
718 PdataSec = CreateSection(".pdata", DATA | R);
719 IdataSec = CreateSection(".idata", DATA | R);
720 EdataSec = CreateSection(".edata", DATA | R);
721 DidatSec = CreateSection(".didat", DATA | R);
722 RsrcSec = CreateSection(".rsrc", DATA | R);
723 RelocSec = CreateSection(".reloc", DATA | DISCARDABLE | R);
724 CtorsSec = CreateSection(".ctors", DATA | R | W);
725 DtorsSec = CreateSection(".dtors", DATA | R | W);
809 textSec = createSection(".text", code | r | x);
810 createSection(".bss", bss | r | w);
811 rdataSec = createSection(".rdata", data | r);
812 buildidSec = createSection(".buildid", data | r);
813 dataSec = createSection(".data", data | r | w);
814 pdataSec = createSection(".pdata", data | r);
815 idataSec = createSection(".idata", data | r);
816 edataSec = createSection(".edata", data | r);
817 didatSec = createSection(".didat", data | r);
818 rsrcSec = createSection(".rsrc", data | r);
819 relocSec = createSection(".reloc", data | discardable | r);
820 ctorsSec = createSection(".ctors", data | r | w);
821 dtorsSec = createSection(".dtors", data | r | w);
726822
727823 // Then bin chunks by name and output characteristics.
728 std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> Map;
729 for (Chunk *C : Symtab->getChunks()) {
730 auto *SC = dyn_cast<SectionChunk>(C);
731 if (SC && !SC->Live) {
732 if (Config->Verbose)
733 SC->printDiscardedMessage();
824 for (Chunk *c : symtab->getChunks()) {
825 auto *sc = dyn_cast<SectionChunk>(c);
826 if (sc && !sc->live) {
827 if (config->verbose)
828 sc->printDiscardedMessage();
734829 continue;
735830 }
736 Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C);
831 StringRef name = c->getSectionName();
832 if (shouldStripSectionSuffix(sc, name))
833 name = name.split('$').first;
834 PartialSection *pSec = createPartialSection(name,
835 c->getOutputCharacteristics());
836 pSec->chunks.push_back(c);
737837 }
738838
839 fixPartialSectionChars(".rsrc", data | r);
739840 // Even in non MinGW cases, we might need to link against GNU import
740841 // libraries.
741 bool HasIdata = fixGnuImportChunks(Map);
742 if (!Idata.empty())
743 HasIdata = true;
842 bool hasIdata = fixGnuImportChunks();
843 if (!idata.empty())
844 hasIdata = true;
744845
745 if (HasIdata)
746 addSyntheticIdata(Idata, Map);
846 if (hasIdata)
847 addSyntheticIdata();
747848
748849 // Process an /order option.
749 if (!Config->Order.empty())
750 for (auto &Pair : Map)
751 sortBySectionOrder(Pair.second);
850 if (!config->order.empty())
851 for (auto it : partialSections)
852 sortBySectionOrder(it.second->chunks);
752853
753 if (HasIdata)
754 locateImportTables(Map);
854 if (hasIdata)
855 locateImportTables();
755856
756857 // Then create an OutputSection for each section.
757858 // '$' and all following characters in input section names are
758859 // discarded when determining output section. So, .text$foo
759860 // contributes to .text, for example. See PE/COFF spec 3.2.
760 for (auto &Pair : Map) {
761 StringRef Name = getOutputSectionName(Pair.first.first);
762 uint32_t OutChars = Pair.first.second;
861 for (auto it : partialSections) {
862 PartialSection *pSec = it.second;
863 StringRef name = getOutputSectionName(pSec->name);
864 uint32_t outChars = pSec->characteristics;
763865
764 if (Name == ".CRT") {
866 if (name == ".CRT") {
765867 // In link.exe, there is a special case for the I386 target where .CRT
766868 // sections are treated as if they have output characteristics DATA | R if
767869 // their characteristics are DATA | R | W. This implements the same
768870 // special case for all architectures.
769 OutChars = DATA | R;
871 outChars = data | r;
770872
771 log("Processing section " + Pair.first.first + " -> " + Name);
873 log("Processing section " + pSec->name + " -> " + name);
772874
773 sortCRTSectionChunks(Pair.second);
875 sortCRTSectionChunks(pSec->chunks);
774876 }
775877
776 OutputSection *Sec = CreateSection(Name, OutChars);
777 std::vector<Chunk *> &Chunks = Pair.second;
778 for (Chunk *C : Chunks)
779 Sec->addChunk(C);
878 OutputSection *sec = createSection(name, outChars);
879 for (Chunk *c : pSec->chunks)
880 sec->addChunk(c);
881
882 sec->addContributingPartialSection(pSec);
780883 }
781884
782885 // Finally, move some output sections to the end.
783 auto SectionOrder = [&](OutputSection *S) {
784 // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because
785 // the loader cannot handle holes. Stripping can remove other discardable ones
786 // than .reloc, which is first of them (created early).
787 if (S->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
886 auto sectionOrder = [&](const OutputSection *s) {
887 // Move DISCARDABLE (or non-memory-mapped) sections to the end of file
888 // because the loader cannot handle holes. Stripping can remove other
889 // discardable ones than .reloc, which is first of them (created early).
890 if (s->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
788891 return 2;
789892 // .rsrc should come at the end of the non-discardable sections because its
790893 // size may change by the Win32 UpdateResources() function, causing
791894 // subsequent sections to move (see https://crbug.com/827082).
792 if (S == RsrcSec)
895 if (s == rsrcSec)
793896 return 1;
794897 return 0;
795898 };
796 std::stable_sort(OutputSections.begin(), OutputSections.end(),
797 [&](OutputSection *S, OutputSection *T) {
798 return SectionOrder(S) < SectionOrder(T);
799 });
899 llvm::stable_sort(outputSections,
900 [&](const OutputSection *s, const OutputSection *t) {
901 return sectionOrder(s) < sectionOrder(t);
902 });
800903}
801904
802905void Writer::createMiscChunks() {
803 for (auto &P : MergeChunk::Instances)
804 RdataSec->addChunk(P.second);
906 for (MergeChunk *p : MergeChunk::instances) {
907 if (p) {
908 p->finalizeContents();
909 rdataSec->addChunk(p);
910 }
911 }
805912
806913 // Create thunks for locally-dllimported symbols.
807 if (!Symtab->LocalImportChunks.empty()) {
808 for (Chunk *C : Symtab->LocalImportChunks)
809 RdataSec->addChunk(C);
914 if (!symtab->localImportChunks.empty()) {
915 for (Chunk *c : symtab->localImportChunks)
916 rdataSec->addChunk(c);
810917 }
811918
812919 // Create Debug Information Chunks
813 OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;
814 if (Config->Debug || Config->Repro) {
815 DebugDirectory = make<DebugDirectoryChunk>(DebugRecords, Config->Repro);
816 DebugInfoSec->addChunk(DebugDirectory);
920 OutputSection *debugInfoSec = config->mingw ? buildidSec : rdataSec;
921 if (config->debug || config->repro) {
922 debugDirectory = make<DebugDirectoryChunk>(debugRecords, config->repro);
923 debugInfoSec->addChunk(debugDirectory);
817924 }
818925
819 if (Config->Debug) {
926 if (config->debug) {
820927 // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We
821928 // output a PDB no matter what, and this chunk provides the only means of
822929 // allowing a debugger to match a PDB and an executable. So we need it even
823930 // if we're ultimately not going to write CodeView data to the PDB.
824 BuildId = make<CVDebugRecordChunk>();
825 DebugRecords.push_back(BuildId);
931 buildId = make<CVDebugRecordChunk>();
932 debugRecords.push_back(buildId);
826933
827 for (Chunk *C : DebugRecords)
828 DebugInfoSec->addChunk(C);
934 for (Chunk *c : debugRecords)
935 debugInfoSec->addChunk(c);
829936 }
830937
831938 // Create SEH table. x86-only.
832 if (Config->Machine == I386)
939 if (config->safeSEH)
833940 createSEHTable();
834941
835942 // Create /guard:cf tables if requested.
836 if (Config->GuardCF != GuardCFLevel::Off)
943 if (config->guardCF != GuardCFLevel::Off)
837944 createGuardCFTables();
838945
839 if (Config->MinGW) {
946 if (config->mingw) {
840947 createRuntimePseudoRelocs();
841948
842949 insertCtorDtorSymbols();
......@@ -851,106 +958,123 @@ void Writer::createImportTables() {
851958 // Initialize DLLOrder so that import entries are ordered in
852959 // the same order as in the command line. (That affects DLL
853960 // initialization order, and this ordering is MSVC-compatible.)
854 for (ImportFile *File : ImportFile::Instances) {
855 if (!File->Live)
961 for (ImportFile *file : ImportFile::instances) {
962 if (!file->live)
856963 continue;
857964
858 std::string DLL = StringRef(File->DLLName).lower();
859 if (Config->DLLOrder.count(DLL) == 0)
860 Config->DLLOrder[DLL] = Config->DLLOrder.size();
861
862 if (File->ImpSym && !isa<DefinedImportData>(File->ImpSym))
863 fatal(toString(*File->ImpSym) + " was replaced");
864 DefinedImportData *ImpSym = cast_or_null<DefinedImportData>(File->ImpSym);
865 if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) {
866 if (!File->ThunkSym)
867 fatal("cannot delay-load " + toString(File) +
868 " due to import of data: " + toString(*ImpSym));
869 DelayIdata.add(ImpSym);
965 std::string dll = StringRef(file->dllName).lower();
966 if (config->dllOrder.count(dll) == 0)
967 config->dllOrder[dll] = config->dllOrder.size();
968
969 if (file->impSym && !isa<DefinedImportData>(file->impSym))
970 fatal(toString(*file->impSym) + " was replaced");
971 DefinedImportData *impSym = cast_or_null<DefinedImportData>(file->impSym);
972 if (config->delayLoads.count(StringRef(file->dllName).lower())) {
973 if (!file->thunkSym)
974 fatal("cannot delay-load " + toString(file) +
975 " due to import of data: " + toString(*impSym));
976 delayIdata.add(impSym);
870977 } else {
871 Idata.add(ImpSym);
978 idata.add(impSym);
872979 }
873980 }
874981}
875982
876983void Writer::appendImportThunks() {
877 if (ImportFile::Instances.empty())
984 if (ImportFile::instances.empty())
878985 return;
879986
880 for (ImportFile *File : ImportFile::Instances) {
881 if (!File->Live)
987 for (ImportFile *file : ImportFile::instances) {
988 if (!file->live)
882989 continue;
883990
884 if (!File->ThunkSym)
991 if (!file->thunkSym)
885992 continue;
886993
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());
994 if (!isa<DefinedImportThunk>(file->thunkSym))
995 fatal(toString(*file->thunkSym) + " was replaced");
996 DefinedImportThunk *thunk = cast<DefinedImportThunk>(file->thunkSym);
997 if (file->thunkLive)
998 textSec->addChunk(thunk->getChunk());
892999 }
8931000
894 if (!DelayIdata.empty()) {
895 Defined *Helper = cast<Defined>(Config->DelayLoadHelper);
896 DelayIdata.create(Helper);
897 for (Chunk *C : DelayIdata.getChunks())
898 DidatSec->addChunk(C);
899 for (Chunk *C : DelayIdata.getDataChunks())
900 DataSec->addChunk(C);
901 for (Chunk *C : DelayIdata.getCodeChunks())
902 TextSec->addChunk(C);
1001 if (!delayIdata.empty()) {
1002 Defined *helper = cast<Defined>(config->delayLoadHelper);
1003 delayIdata.create(helper);
1004 for (Chunk *c : delayIdata.getChunks())
1005 didatSec->addChunk(c);
1006 for (Chunk *c : delayIdata.getDataChunks())
1007 dataSec->addChunk(c);
1008 for (Chunk *c : delayIdata.getCodeChunks())
1009 textSec->addChunk(c);
9031010 }
9041011}
9051012
9061013void Writer::createExportTable() {
907 if (Config->Exports.empty())
1014 if (config->exports.empty())
9081015 return;
909 for (Chunk *C : Edata.Chunks)
910 EdataSec->addChunk(C);
1016 for (Chunk *c : edata.chunks)
1017 edataSec->addChunk(c);
9111018}
9121019
9131020void Writer::removeUnusedSections() {
9141021 // Remove sections that we can be sure won't get content, to avoid
9151022 // allocating space for their section headers.
916 auto IsUnused = [this](OutputSection *S) {
917 if (S == RelocSec)
1023 auto isUnused = [this](OutputSection *s) {
1024 if (s == relocSec)
9181025 return false; // This section is populated later.
9191026 // MergeChunks have zero size at this point, as their size is finalized
9201027 // later. Only remove sections that have no Chunks at all.
921 return S->Chunks.empty();
1028 return s->chunks.empty();
9221029 };
923 OutputSections.erase(
924 std::remove_if(OutputSections.begin(), OutputSections.end(), IsUnused),
925 OutputSections.end());
1030 outputSections.erase(
1031 std::remove_if(outputSections.begin(), outputSections.end(), isUnused),
1032 outputSections.end());
9261033}
9271034
9281035// The Windows loader doesn't seem to like empty sections,
9291036// so we remove them if any.
9301037void Writer::removeEmptySections() {
931 auto IsEmpty = [](OutputSection *S) { return S->getVirtualSize() == 0; };
932 OutputSections.erase(
933 std::remove_if(OutputSections.begin(), OutputSections.end(), IsEmpty),
934 OutputSections.end());
935 uint32_t Idx = 1;
936 for (OutputSection *Sec : OutputSections)
937 Sec->SectionIndex = Idx++;
1038 auto isEmpty = [](OutputSection *s) { return s->getVirtualSize() == 0; };
1039 outputSections.erase(
1040 std::remove_if(outputSections.begin(), outputSections.end(), isEmpty),
1041 outputSections.end());
9381042}
9391043
940size_t Writer::addEntryToStringTable(StringRef Str) {
941 assert(Str.size() > COFF::NameSize);
942 size_t OffsetOfEntry = Strtab.size() + 4; // +4 for the size field
943 Strtab.insert(Strtab.end(), Str.begin(), Str.end());
944 Strtab.push_back('\0');
945 return OffsetOfEntry;
1044void Writer::assignOutputSectionIndices() {
1045 // Assign final output section indices, and assign each chunk to its output
1046 // section.
1047 uint32_t idx = 1;
1048 for (OutputSection *os : outputSections) {
1049 os->sectionIndex = idx;
1050 for (Chunk *c : os->chunks)
1051 c->setOutputSectionIdx(idx);
1052 ++idx;
1053 }
1054
1055 // Merge chunks are containers of chunks, so assign those an output section
1056 // too.
1057 for (MergeChunk *mc : MergeChunk::instances)
1058 if (mc)
1059 for (SectionChunk *sc : mc->sections)
1060 if (sc && sc->live)
1061 sc->setOutputSectionIdx(mc->getOutputSectionIdx());
9461062}
9471063
948Optional<coff_symbol16> Writer::createSymbol(Defined *Def) {
949 coff_symbol16 Sym;
950 switch (Def->kind()) {
1064size_t Writer::addEntryToStringTable(StringRef str) {
1065 assert(str.size() > COFF::NameSize);
1066 size_t offsetOfEntry = strtab.size() + 4; // +4 for the size field
1067 strtab.insert(strtab.end(), str.begin(), str.end());
1068 strtab.push_back('\0');
1069 return offsetOfEntry;
1070}
1071
1072Optional<coff_symbol16> Writer::createSymbol(Defined *def) {
1073 coff_symbol16 sym;
1074 switch (def->kind()) {
9511075 case Symbol::DefinedAbsoluteKind:
952 Sym.Value = Def->getRVA();
953 Sym.SectionNumber = IMAGE_SYM_ABSOLUTE;
1076 sym.Value = def->getRVA();
1077 sym.SectionNumber = IMAGE_SYM_ABSOLUTE;
9541078 break;
9551079 case Symbol::DefinedSyntheticKind:
9561080 // Relative symbols are unrepresentable in a COFF symbol table.
......@@ -958,38 +1082,38 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) {
9581082 default: {
9591083 // Don't write symbols that won't be written to the output to the symbol
9601084 // table.
961 Chunk *C = Def->getChunk();
962 if (!C)
1085 Chunk *c = def->getChunk();
1086 if (!c)
9631087 return None;
964 OutputSection *OS = C->getOutputSection();
965 if (!OS)
1088 OutputSection *os = c->getOutputSection();
1089 if (!os)
9661090 return None;
9671091
968 Sym.Value = Def->getRVA() - OS->getRVA();
969 Sym.SectionNumber = OS->SectionIndex;
1092 sym.Value = def->getRVA() - os->getRVA();
1093 sym.SectionNumber = os->sectionIndex;
9701094 break;
9711095 }
9721096 }
9731097
974 StringRef Name = Def->getName();
975 if (Name.size() > COFF::NameSize) {
976 Sym.Name.Offset.Zeroes = 0;
977 Sym.Name.Offset.Offset = addEntryToStringTable(Name);
1098 StringRef name = def->getName();
1099 if (name.size() > COFF::NameSize) {
1100 sym.Name.Offset.Zeroes = 0;
1101 sym.Name.Offset.Offset = addEntryToStringTable(name);
9781102 } else {
979 memset(Sym.Name.ShortName, 0, COFF::NameSize);
980 memcpy(Sym.Name.ShortName, Name.data(), Name.size());
1103 memset(sym.Name.ShortName, 0, COFF::NameSize);
1104 memcpy(sym.Name.ShortName, name.data(), name.size());
9811105 }
9821106
983 if (auto *D = dyn_cast<DefinedCOFF>(Def)) {
984 COFFSymbolRef Ref = D->getCOFFSymbol();
985 Sym.Type = Ref.getType();
986 Sym.StorageClass = Ref.getStorageClass();
1107 if (auto *d = dyn_cast<DefinedCOFF>(def)) {
1108 COFFSymbolRef ref = d->getCOFFSymbol();
1109 sym.Type = ref.getType();
1110 sym.StorageClass = ref.getStorageClass();
9871111 } else {
988 Sym.Type = IMAGE_SYM_TYPE_NULL;
989 Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL;
1112 sym.Type = IMAGE_SYM_TYPE_NULL;
1113 sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL;
9901114 }
991 Sym.NumberOfAuxSymbols = 0;
992 return Sym;
1115 sym.NumberOfAuxSymbols = 0;
1116 return sym;
9931117}
9941118
9951119void Writer::createSymbolAndStringTable() {
......@@ -1001,113 +1125,120 @@ void Writer::createSymbolAndStringTable() {
10011125 // solution where discardable sections have long names preserved and
10021126 // non-discardable sections have their names truncated, to ensure that any
10031127 // section which is mapped at runtime also has its name mapped at runtime.
1004 for (OutputSection *Sec : OutputSections) {
1005 if (Sec->Name.size() <= COFF::NameSize)
1128 for (OutputSection *sec : outputSections) {
1129 if (sec->name.size() <= COFF::NameSize)
10061130 continue;
1007 if ((Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0)
1131 if ((sec->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0)
10081132 continue;
1009 Sec->setStringTableOff(addEntryToStringTable(Sec->Name));
1133 sec->setStringTableOff(addEntryToStringTable(sec->name));
10101134 }
10111135
1012 if (Config->DebugDwarf || Config->DebugSymtab) {
1013 for (ObjFile *File : ObjFile::Instances) {
1014 for (Symbol *B : File->getSymbols()) {
1015 auto *D = dyn_cast_or_null<Defined>(B);
1016 if (!D || D->WrittenToSymtab)
1136 if (config->debugDwarf || config->debugSymtab) {
1137 for (ObjFile *file : ObjFile::instances) {
1138 for (Symbol *b : file->getSymbols()) {
1139 auto *d = dyn_cast_or_null<Defined>(b);
1140 if (!d || d->writtenToSymtab)
10171141 continue;
1018 D->WrittenToSymtab = true;
1142 d->writtenToSymtab = true;
10191143
1020 if (Optional<coff_symbol16> Sym = createSymbol(D))
1021 OutputSymtab.push_back(*Sym);
1144 if (Optional<coff_symbol16> sym = createSymbol(d))
1145 outputSymtab.push_back(*sym);
10221146 }
10231147 }
10241148 }
10251149
1026 if (OutputSymtab.empty() && Strtab.empty())
1150 if (outputSymtab.empty() && strtab.empty())
10271151 return;
10281152
10291153 // We position the symbol table to be adjacent to the end of the last section.
1030 uint64_t FileOff = FileSize;
1031 PointerToSymbolTable = FileOff;
1032 FileOff += OutputSymtab.size() * sizeof(coff_symbol16);
1033 FileOff += 4 + Strtab.size();
1034 FileSize = alignTo(FileOff, SectorSize);
1154 uint64_t fileOff = fileSize;
1155 pointerToSymbolTable = fileOff;
1156 fileOff += outputSymtab.size() * sizeof(coff_symbol16);
1157 fileOff += 4 + strtab.size();
1158 fileSize = alignTo(fileOff, config->fileAlign);
10351159}
10361160
10371161void Writer::mergeSections() {
1038 if (!PdataSec->Chunks.empty()) {
1039 FirstPdata = PdataSec->Chunks.front();
1040 LastPdata = PdataSec->Chunks.back();
1162 if (!pdataSec->chunks.empty()) {
1163 firstPdata = pdataSec->chunks.front();
1164 lastPdata = pdataSec->chunks.back();
10411165 }
10421166
1043 for (auto &P : Config->Merge) {
1044 StringRef ToName = P.second;
1045 if (P.first == ToName)
1167 for (auto &p : config->merge) {
1168 StringRef toName = p.second;
1169 if (p.first == toName)
10461170 continue;
1047 StringSet<> Names;
1171 StringSet<> names;
10481172 while (1) {
1049 if (!Names.insert(ToName).second)
1050 fatal("/merge: cycle found for section '" + P.first + "'");
1051 auto I = Config->Merge.find(ToName);
1052 if (I == Config->Merge.end())
1173 if (!names.insert(toName).second)
1174 fatal("/merge: cycle found for section '" + p.first + "'");
1175 auto i = config->merge.find(toName);
1176 if (i == config->merge.end())
10531177 break;
1054 ToName = I->second;
1178 toName = i->second;
10551179 }
1056 OutputSection *From = findSection(P.first);
1057 OutputSection *To = findSection(ToName);
1058 if (!From)
1180 OutputSection *from = findSection(p.first);
1181 OutputSection *to = findSection(toName);
1182 if (!from)
10591183 continue;
1060 if (!To) {
1061 From->Name = ToName;
1184 if (!to) {
1185 from->name = toName;
10621186 continue;
10631187 }
1064 To->merge(From);
1188 to->merge(from);
10651189 }
10661190}
10671191
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
10751192// Visits all sections to assign incremental, non-overlapping RVAs and
10761193// file offsets.
10771194void Writer::assignAddresses() {
1078 SizeOfHeaders = DOSStubSize + sizeof(PEMagic) + sizeof(coff_file_header) +
1079 sizeof(data_directory) * NumberOfDataDirectory +
1080 sizeof(coff_section) * OutputSections.size();
1081 SizeOfHeaders +=
1082 Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
1083 SizeOfHeaders = alignTo(SizeOfHeaders, SectorSize);
1084 uint64_t RVA = PageSize; // The first page is kept unmapped.
1085 FileSize = SizeOfHeaders;
1086
1087 for (OutputSection *Sec : OutputSections) {
1088 if (Sec == RelocSec)
1195 sizeOfHeaders = dosStubSize + sizeof(PEMagic) + sizeof(coff_file_header) +
1196 sizeof(data_directory) * numberOfDataDirectory +
1197 sizeof(coff_section) * outputSections.size();
1198 sizeOfHeaders +=
1199 config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
1200 sizeOfHeaders = alignTo(sizeOfHeaders, config->fileAlign);
1201 uint64_t rva = pageSize; // The first page is kept unmapped.
1202 fileSize = sizeOfHeaders;
1203
1204 for (OutputSection *sec : outputSections) {
1205 if (sec == relocSec)
10891206 addBaserels();
1090 uint64_t RawSize = 0, VirtualSize = 0;
1091 Sec->Header.VirtualAddress = RVA;
1092 for (Chunk *C : Sec->Chunks) {
1093 VirtualSize = alignTo(VirtualSize, C->Alignment);
1094 C->setRVA(RVA + VirtualSize);
1095 C->OutputSectionOff = VirtualSize;
1096 C->finalizeContents();
1097 VirtualSize += C->getSize();
1098 if (C->hasData())
1099 RawSize = alignTo(VirtualSize, SectorSize);
1207 uint64_t rawSize = 0, virtualSize = 0;
1208 sec->header.VirtualAddress = rva;
1209
1210 // If /FUNCTIONPADMIN is used, functions are padded in order to create a
1211 // hotpatchable image.
1212 const bool isCodeSection =
1213 (sec->header.Characteristics & IMAGE_SCN_CNT_CODE) &&
1214 (sec->header.Characteristics & IMAGE_SCN_MEM_READ) &&
1215 (sec->header.Characteristics & IMAGE_SCN_MEM_EXECUTE);
1216 uint32_t padding = isCodeSection ? config->functionPadMin : 0;
1217
1218 for (Chunk *c : sec->chunks) {
1219 if (padding && c->isHotPatchable())
1220 virtualSize += padding;
1221 virtualSize = alignTo(virtualSize, c->getAlignment());
1222 c->setRVA(rva + virtualSize);
1223 virtualSize += c->getSize();
1224 if (c->hasData)
1225 rawSize = alignTo(virtualSize, config->fileAlign);
11001226 }
1101 if (VirtualSize > UINT32_MAX)
1102 error("section larger than 4 GiB: " + Sec->Name);
1103 Sec->Header.VirtualSize = VirtualSize;
1104 Sec->Header.SizeOfRawData = RawSize;
1105 if (RawSize != 0)
1106 Sec->Header.PointerToRawData = FileSize;
1107 RVA += alignTo(VirtualSize, PageSize);
1108 FileSize += alignTo(RawSize, SectorSize);
1109 }
1110 SizeOfImage = alignTo(RVA, PageSize);
1227 if (virtualSize > UINT32_MAX)
1228 error("section larger than 4 GiB: " + sec->name);
1229 sec->header.VirtualSize = virtualSize;
1230 sec->header.SizeOfRawData = rawSize;
1231 if (rawSize != 0)
1232 sec->header.PointerToRawData = fileSize;
1233 rva += alignTo(virtualSize, pageSize);
1234 fileSize += alignTo(rawSize, config->fileAlign);
1235 }
1236 sizeOfImage = alignTo(rva, pageSize);
1237
1238 // Assign addresses to sections in MergeChunks.
1239 for (MergeChunk *mc : MergeChunk::instances)
1240 if (mc)
1241 mc->assignSubsectionRVAs();
11111242}
11121243
11131244template <typename PEHeaderTy> void Writer::writeHeader() {
......@@ -1116,275 +1247,299 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
11161247 // under DOS, that program gets run (usually to just print an error message).
11171248 // When run under Windows, the loader looks at AddressOfNewExeHeader and uses
11181249 // the PE header instead.
1119 uint8_t *Buf = Buffer->getBufferStart();
1120 auto *DOS = reinterpret_cast<dos_header *>(Buf);
1121 Buf += sizeof(dos_header);
1122 DOS->Magic[0] = 'M';
1123 DOS->Magic[1] = 'Z';
1124 DOS->UsedBytesInTheLastPage = DOSStubSize % 512;
1125 DOS->FileSizeInPages = divideCeil(DOSStubSize, 512);
1126 DOS->HeaderSizeInParagraphs = sizeof(dos_header) / 16;
1127
1128 DOS->AddressOfRelocationTable = sizeof(dos_header);
1129 DOS->AddressOfNewExeHeader = DOSStubSize;
1250 uint8_t *buf = buffer->getBufferStart();
1251 auto *dos = reinterpret_cast<dos_header *>(buf);
1252 buf += sizeof(dos_header);
1253 dos->Magic[0] = 'M';
1254 dos->Magic[1] = 'Z';
1255 dos->UsedBytesInTheLastPage = dosStubSize % 512;
1256 dos->FileSizeInPages = divideCeil(dosStubSize, 512);
1257 dos->HeaderSizeInParagraphs = sizeof(dos_header) / 16;
1258
1259 dos->AddressOfRelocationTable = sizeof(dos_header);
1260 dos->AddressOfNewExeHeader = dosStubSize;
11301261
11311262 // Write DOS program.
1132 memcpy(Buf, DOSProgram, sizeof(DOSProgram));
1133 Buf += sizeof(DOSProgram);
1263 memcpy(buf, dosProgram, sizeof(dosProgram));
1264 buf += sizeof(dosProgram);
11341265
11351266 // Write PE magic
1136 memcpy(Buf, PEMagic, sizeof(PEMagic));
1137 Buf += sizeof(PEMagic);
1267 memcpy(buf, PEMagic, sizeof(PEMagic));
1268 buf += sizeof(PEMagic);
11381269
11391270 // Write COFF header
1140 auto *COFF = reinterpret_cast<coff_file_header *>(Buf);
1141 Buf += sizeof(*COFF);
1142 COFF->Machine = Config->Machine;
1143 COFF->NumberOfSections = OutputSections.size();
1144 COFF->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
1145 if (Config->LargeAddressAware)
1146 COFF->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
1147 if (!Config->is64())
1148 COFF->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
1149 if (Config->DLL)
1150 COFF->Characteristics |= IMAGE_FILE_DLL;
1151 if (!Config->Relocatable)
1152 COFF->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
1153 COFF->SizeOfOptionalHeader =
1154 sizeof(PEHeaderTy) + sizeof(data_directory) * NumberOfDataDirectory;
1271 auto *coff = reinterpret_cast<coff_file_header *>(buf);
1272 buf += sizeof(*coff);
1273 coff->Machine = config->machine;
1274 coff->NumberOfSections = outputSections.size();
1275 coff->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
1276 if (config->largeAddressAware)
1277 coff->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
1278 if (!config->is64())
1279 coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
1280 if (config->dll)
1281 coff->Characteristics |= IMAGE_FILE_DLL;
1282 if (!config->relocatable)
1283 coff->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
1284 if (config->swaprunCD)
1285 coff->Characteristics |= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP;
1286 if (config->swaprunNet)
1287 coff->Characteristics |= IMAGE_FILE_NET_RUN_FROM_SWAP;
1288 coff->SizeOfOptionalHeader =
1289 sizeof(PEHeaderTy) + sizeof(data_directory) * numberOfDataDirectory;
11551290
11561291 // Write PE header
1157 auto *PE = reinterpret_cast<PEHeaderTy *>(Buf);
1158 Buf += sizeof(*PE);
1159 PE->Magic = Config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32;
1292 auto *pe = reinterpret_cast<PEHeaderTy *>(buf);
1293 buf += sizeof(*pe);
1294 pe->Magic = config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32;
11601295
11611296 // If {Major,Minor}LinkerVersion is left at 0.0, then for some
11621297 // reason signing the resulting PE file with Authenticode produces a
11631298 // signature that fails to validate on Windows 7 (but is OK on 10).
11641299 // Set it to 14.0, which is what VS2015 outputs, and which avoids
11651300 // that problem.
1166 PE->MajorLinkerVersion = 14;
1167 PE->MinorLinkerVersion = 0;
1168
1169 PE->ImageBase = Config->ImageBase;
1170 PE->SectionAlignment = PageSize;
1171 PE->FileAlignment = SectorSize;
1172 PE->MajorImageVersion = Config->MajorImageVersion;
1173 PE->MinorImageVersion = Config->MinorImageVersion;
1174 PE->MajorOperatingSystemVersion = Config->MajorOSVersion;
1175 PE->MinorOperatingSystemVersion = Config->MinorOSVersion;
1176 PE->MajorSubsystemVersion = Config->MajorOSVersion;
1177 PE->MinorSubsystemVersion = Config->MinorOSVersion;
1178 PE->Subsystem = Config->Subsystem;
1179 PE->SizeOfImage = SizeOfImage;
1180 PE->SizeOfHeaders = SizeOfHeaders;
1181 if (!Config->NoEntry) {
1182 Defined *Entry = cast<Defined>(Config->Entry);
1183 PE->AddressOfEntryPoint = Entry->getRVA();
1301 pe->MajorLinkerVersion = 14;
1302 pe->MinorLinkerVersion = 0;
1303
1304 pe->ImageBase = config->imageBase;
1305 pe->SectionAlignment = pageSize;
1306 pe->FileAlignment = config->fileAlign;
1307 pe->MajorImageVersion = config->majorImageVersion;
1308 pe->MinorImageVersion = config->minorImageVersion;
1309 pe->MajorOperatingSystemVersion = config->majorOSVersion;
1310 pe->MinorOperatingSystemVersion = config->minorOSVersion;
1311 pe->MajorSubsystemVersion = config->majorOSVersion;
1312 pe->MinorSubsystemVersion = config->minorOSVersion;
1313 pe->Subsystem = config->subsystem;
1314 pe->SizeOfImage = sizeOfImage;
1315 pe->SizeOfHeaders = sizeOfHeaders;
1316 if (!config->noEntry) {
1317 Defined *entry = cast<Defined>(config->entry);
1318 pe->AddressOfEntryPoint = entry->getRVA();
11841319 // Pointer to thumb code must have the LSB set, so adjust it.
1185 if (Config->Machine == ARMNT)
1186 PE->AddressOfEntryPoint |= 1;
1187 }
1188 PE->SizeOfStackReserve = Config->StackReserve;
1189 PE->SizeOfStackCommit = Config->StackCommit;
1190 PE->SizeOfHeapReserve = Config->HeapReserve;
1191 PE->SizeOfHeapCommit = Config->HeapCommit;
1192 if (Config->AppContainer)
1193 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
1194 if (Config->DynamicBase)
1195 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
1196 if (Config->HighEntropyVA)
1197 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
1198 if (!Config->AllowBind)
1199 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND;
1200 if (Config->NxCompat)
1201 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
1202 if (!Config->AllowIsolation)
1203 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION;
1204 if (Config->GuardCF != GuardCFLevel::Off)
1205 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF;
1206 if (Config->IntegrityCheck)
1207 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
1208 if (SetNoSEHCharacteristic)
1209 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;
1210 if (Config->TerminalServerAware)
1211 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
1212 PE->NumberOfRvaAndSize = NumberOfDataDirectory;
1213 if (TextSec->getVirtualSize()) {
1214 PE->BaseOfCode = TextSec->getRVA();
1215 PE->SizeOfCode = TextSec->getRawSize();
1216 }
1217 PE->SizeOfInitializedData = getSizeOfInitializedData();
1320 if (config->machine == ARMNT)
1321 pe->AddressOfEntryPoint |= 1;
1322 }
1323 pe->SizeOfStackReserve = config->stackReserve;
1324 pe->SizeOfStackCommit = config->stackCommit;
1325 pe->SizeOfHeapReserve = config->heapReserve;
1326 pe->SizeOfHeapCommit = config->heapCommit;
1327 if (config->appContainer)
1328 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
1329 if (config->dynamicBase)
1330 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
1331 if (config->highEntropyVA)
1332 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
1333 if (!config->allowBind)
1334 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND;
1335 if (config->nxCompat)
1336 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
1337 if (!config->allowIsolation)
1338 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION;
1339 if (config->guardCF != GuardCFLevel::Off)
1340 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF;
1341 if (config->integrityCheck)
1342 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
1343 if (setNoSEHCharacteristic)
1344 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;
1345 if (config->terminalServerAware)
1346 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
1347 pe->NumberOfRvaAndSize = numberOfDataDirectory;
1348 if (textSec->getVirtualSize()) {
1349 pe->BaseOfCode = textSec->getRVA();
1350 pe->SizeOfCode = textSec->getRawSize();
1351 }
1352 pe->SizeOfInitializedData = getSizeOfInitializedData();
12181353
12191354 // Write data directory
1220 auto *Dir = reinterpret_cast<data_directory *>(Buf);
1221 Buf += sizeof(*Dir) * NumberOfDataDirectory;
1222 if (!Config->Exports.empty()) {
1223 Dir[EXPORT_TABLE].RelativeVirtualAddress = Edata.getRVA();
1224 Dir[EXPORT_TABLE].Size = Edata.getSize();
1225 }
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;
1233 }
1234 if (RsrcSec->getVirtualSize()) {
1235 Dir[RESOURCE_TABLE].RelativeVirtualAddress = RsrcSec->getRVA();
1236 Dir[RESOURCE_TABLE].Size = RsrcSec->getVirtualSize();
1237 }
1238 if (FirstPdata) {
1239 Dir[EXCEPTION_TABLE].RelativeVirtualAddress = FirstPdata->getRVA();
1240 Dir[EXCEPTION_TABLE].Size =
1241 LastPdata->getRVA() + LastPdata->getSize() - FirstPdata->getRVA();
1242 }
1243 if (RelocSec->getVirtualSize()) {
1244 Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = RelocSec->getRVA();
1245 Dir[BASE_RELOCATION_TABLE].Size = RelocSec->getVirtualSize();
1246 }
1247 if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) {
1248 if (Defined *B = dyn_cast<Defined>(Sym)) {
1249 Dir[TLS_TABLE].RelativeVirtualAddress = B->getRVA();
1250 Dir[TLS_TABLE].Size = Config->is64()
1355 auto *dir = reinterpret_cast<data_directory *>(buf);
1356 buf += sizeof(*dir) * numberOfDataDirectory;
1357 if (!config->exports.empty()) {
1358 dir[EXPORT_TABLE].RelativeVirtualAddress = edata.getRVA();
1359 dir[EXPORT_TABLE].Size = edata.getSize();
1360 }
1361 if (importTableStart) {
1362 dir[IMPORT_TABLE].RelativeVirtualAddress = importTableStart->getRVA();
1363 dir[IMPORT_TABLE].Size = importTableSize;
1364 }
1365 if (iatStart) {
1366 dir[IAT].RelativeVirtualAddress = iatStart->getRVA();
1367 dir[IAT].Size = iatSize;
1368 }
1369 if (rsrcSec->getVirtualSize()) {
1370 dir[RESOURCE_TABLE].RelativeVirtualAddress = rsrcSec->getRVA();
1371 dir[RESOURCE_TABLE].Size = rsrcSec->getVirtualSize();
1372 }
1373 if (firstPdata) {
1374 dir[EXCEPTION_TABLE].RelativeVirtualAddress = firstPdata->getRVA();
1375 dir[EXCEPTION_TABLE].Size =
1376 lastPdata->getRVA() + lastPdata->getSize() - firstPdata->getRVA();
1377 }
1378 if (relocSec->getVirtualSize()) {
1379 dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = relocSec->getRVA();
1380 dir[BASE_RELOCATION_TABLE].Size = relocSec->getVirtualSize();
1381 }
1382 if (Symbol *sym = symtab->findUnderscore("_tls_used")) {
1383 if (Defined *b = dyn_cast<Defined>(sym)) {
1384 dir[TLS_TABLE].RelativeVirtualAddress = b->getRVA();
1385 dir[TLS_TABLE].Size = config->is64()
12511386 ? sizeof(object::coff_tls_directory64)
12521387 : sizeof(object::coff_tls_directory32);
12531388 }
12541389 }
1255 if (DebugDirectory) {
1256 Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();
1257 Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();
1390 if (debugDirectory) {
1391 dir[DEBUG_DIRECTORY].RelativeVirtualAddress = debugDirectory->getRVA();
1392 dir[DEBUG_DIRECTORY].Size = debugDirectory->getSize();
12581393 }
1259 if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) {
1260 if (auto *B = dyn_cast<DefinedRegular>(Sym)) {
1261 SectionChunk *SC = B->getChunk();
1262 assert(B->getRVA() >= SC->getRVA());
1263 uint64_t OffsetInChunk = B->getRVA() - SC->getRVA();
1264 if (!SC->hasData() || OffsetInChunk + 4 > SC->getSize())
1394 if (Symbol *sym = symtab->findUnderscore("_load_config_used")) {
1395 if (auto *b = dyn_cast<DefinedRegular>(sym)) {
1396 SectionChunk *sc = b->getChunk();
1397 assert(b->getRVA() >= sc->getRVA());
1398 uint64_t offsetInChunk = b->getRVA() - sc->getRVA();
1399 if (!sc->hasData || offsetInChunk + 4 > sc->getSize())
12651400 fatal("_load_config_used is malformed");
12661401
1267 ArrayRef<uint8_t> SecContents = SC->getContents();
1268 uint32_t LoadConfigSize =
1269 *reinterpret_cast<const ulittle32_t *>(&SecContents[OffsetInChunk]);
1270 if (OffsetInChunk + LoadConfigSize > SC->getSize())
1402 ArrayRef<uint8_t> secContents = sc->getContents();
1403 uint32_t loadConfigSize =
1404 *reinterpret_cast<const ulittle32_t *>(&secContents[offsetInChunk]);
1405 if (offsetInChunk + loadConfigSize > sc->getSize())
12711406 fatal("_load_config_used is too large");
1272 Dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = B->getRVA();
1273 Dir[LOAD_CONFIG_TABLE].Size = LoadConfigSize;
1407 dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = b->getRVA();
1408 dir[LOAD_CONFIG_TABLE].Size = loadConfigSize;
12741409 }
12751410 }
1276 if (!DelayIdata.empty()) {
1277 Dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress =
1278 DelayIdata.getDirRVA();
1279 Dir[DELAY_IMPORT_DESCRIPTOR].Size = DelayIdata.getDirSize();
1411 if (!delayIdata.empty()) {
1412 dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress =
1413 delayIdata.getDirRVA();
1414 dir[DELAY_IMPORT_DESCRIPTOR].Size = delayIdata.getDirSize();
12801415 }
12811416
12821417 // Write section table
1283 for (OutputSection *Sec : OutputSections) {
1284 Sec->writeHeaderTo(Buf);
1285 Buf += sizeof(coff_section);
1418 for (OutputSection *sec : outputSections) {
1419 sec->writeHeaderTo(buf);
1420 buf += sizeof(coff_section);
12861421 }
1287 SectionTable = ArrayRef<uint8_t>(
1288 Buf - OutputSections.size() * sizeof(coff_section), Buf);
1422 sectionTable = ArrayRef<uint8_t>(
1423 buf - outputSections.size() * sizeof(coff_section), buf);
12891424
1290 if (OutputSymtab.empty() && Strtab.empty())
1425 if (outputSymtab.empty() && strtab.empty())
12911426 return;
12921427
1293 COFF->PointerToSymbolTable = PointerToSymbolTable;
1294 uint32_t NumberOfSymbols = OutputSymtab.size();
1295 COFF->NumberOfSymbols = NumberOfSymbols;
1296 auto *SymbolTable = reinterpret_cast<coff_symbol16 *>(
1297 Buffer->getBufferStart() + COFF->PointerToSymbolTable);
1298 for (size_t I = 0; I != NumberOfSymbols; ++I)
1299 SymbolTable[I] = OutputSymtab[I];
1428 coff->PointerToSymbolTable = pointerToSymbolTable;
1429 uint32_t numberOfSymbols = outputSymtab.size();
1430 coff->NumberOfSymbols = numberOfSymbols;
1431 auto *symbolTable = reinterpret_cast<coff_symbol16 *>(
1432 buffer->getBufferStart() + coff->PointerToSymbolTable);
1433 for (size_t i = 0; i != numberOfSymbols; ++i)
1434 symbolTable[i] = outputSymtab[i];
13001435 // Create the string table, it follows immediately after the symbol table.
13011436 // The first 4 bytes is length including itself.
1302 Buf = reinterpret_cast<uint8_t *>(&SymbolTable[NumberOfSymbols]);
1303 write32le(Buf, Strtab.size() + 4);
1304 if (!Strtab.empty())
1305 memcpy(Buf + 4, Strtab.data(), Strtab.size());
1437 buf = reinterpret_cast<uint8_t *>(&symbolTable[numberOfSymbols]);
1438 write32le(buf, strtab.size() + 4);
1439 if (!strtab.empty())
1440 memcpy(buf + 4, strtab.data(), strtab.size());
13061441}
13071442
1308void Writer::openFile(StringRef Path) {
1309 Buffer = CHECK(
1310 FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable),
1311 "failed to open " + Path);
1443void Writer::openFile(StringRef path) {
1444 buffer = CHECK(
1445 FileOutputBuffer::create(path, fileSize, FileOutputBuffer::F_executable),
1446 "failed to open " + path);
13121447}
13131448
13141449void Writer::createSEHTable() {
1315 // Set the no SEH characteristic on x86 binaries unless we find exception
1316 // handlers.
1317 SetNoSEHCharacteristic = true;
1318
1319 SymbolRVASet Handlers;
1320 for (ObjFile *File : ObjFile::Instances) {
1321 // FIXME: We should error here instead of earlier unless /safeseh:no was
1322 // passed.
1323 if (!File->hasSafeSEH())
1324 return;
1325
1326 markSymbolsForRVATable(File, File->getSXDataChunks(), Handlers);
1450 SymbolRVASet handlers;
1451 for (ObjFile *file : ObjFile::instances) {
1452 if (!file->hasSafeSEH())
1453 error("/safeseh: " + file->getName() + " is not compatible with SEH");
1454 markSymbolsForRVATable(file, file->getSXDataChunks(), handlers);
13271455 }
13281456
1329 // Remove the "no SEH" characteristic if all object files were built with
1330 // safeseh, we found some exception handlers, and there is a load config in
1331 // the object.
1332 SetNoSEHCharacteristic =
1333 Handlers.empty() || !Symtab->findUnderscore("_load_config_used");
1457 // Set the "no SEH" characteristic if there really were no handlers, or if
1458 // there is no load config object to point to the table of handlers.
1459 setNoSEHCharacteristic =
1460 handlers.empty() || !symtab->findUnderscore("_load_config_used");
13341461
1335 maybeAddRVATable(std::move(Handlers), "__safe_se_handler_table",
1462 maybeAddRVATable(std::move(handlers), "__safe_se_handler_table",
13361463 "__safe_se_handler_count");
13371464}
13381465
13391466// Add a symbol to an RVA set. Two symbols may have the same RVA, but an RVA set
13401467// cannot contain duplicates. Therefore, the set is uniqued by Chunk and the
13411468// symbol's offset into that Chunk.
1342static void addSymbolToRVASet(SymbolRVASet &RVASet, Defined *S) {
1343 Chunk *C = S->getChunk();
1344 if (auto *SC = dyn_cast<SectionChunk>(C))
1345 C = SC->Repl; // Look through ICF replacement.
1346 uint32_t Off = S->getRVA() - (C ? C->getRVA() : 0);
1347 RVASet.insert({C, Off});
1469static void addSymbolToRVASet(SymbolRVASet &rvaSet, Defined *s) {
1470 Chunk *c = s->getChunk();
1471 if (auto *sc = dyn_cast<SectionChunk>(c))
1472 c = sc->repl; // Look through ICF replacement.
1473 uint32_t off = s->getRVA() - (c ? c->getRVA() : 0);
1474 rvaSet.insert({c, off});
13481475}
13491476
13501477// Given a symbol, add it to the GFIDs table if it is a live, defined, function
13511478// 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)
1479static void maybeAddAddressTakenFunction(SymbolRVASet &addressTakenSyms,
1480 Symbol *s) {
1481 if (!s)
13601482 return;
13611483
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);
1484 switch (s->kind()) {
1485 case Symbol::DefinedLocalImportKind:
1486 case Symbol::DefinedImportDataKind:
1487 // Defines an __imp_ pointer, so it is data, so it is ignored.
1488 break;
1489 case Symbol::DefinedCommonKind:
1490 // Common is always data, so it is ignored.
1491 break;
1492 case Symbol::DefinedAbsoluteKind:
1493 case Symbol::DefinedSyntheticKind:
1494 // Absolute is never code, synthetic generally isn't and usually isn't
1495 // determinable.
1496 break;
1497 case Symbol::LazyKind:
1498 case Symbol::UndefinedKind:
1499 // Undefined symbols resolve to zero, so they don't have an RVA. Lazy
1500 // symbols shouldn't have relocations.
1501 break;
1502
1503 case Symbol::DefinedImportThunkKind:
1504 // Thunks are always code, include them.
1505 addSymbolToRVASet(addressTakenSyms, cast<Defined>(s));
1506 break;
1507
1508 case Symbol::DefinedRegularKind: {
1509 // This is a regular, defined, symbol from a COFF file. Mark the symbol as
1510 // address taken if the symbol type is function and it's in an executable
1511 // section.
1512 auto *d = cast<DefinedRegular>(s);
1513 if (d->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
1514 SectionChunk *sc = dyn_cast<SectionChunk>(d->getChunk());
1515 if (sc && sc->live &&
1516 sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)
1517 addSymbolToRVASet(addressTakenSyms, d);
1518 }
1519 break;
1520 }
1521 }
13671522}
13681523
13691524// Visit all relocations from all section contributions of this object file and
13701525// mark the relocation target as address-taken.
1371static void markSymbolsWithRelocations(ObjFile *File,
1372 SymbolRVASet &UsedSymbols) {
1373 for (Chunk *C : File->getChunks()) {
1526static void markSymbolsWithRelocations(ObjFile *file,
1527 SymbolRVASet &usedSymbols) {
1528 for (Chunk *c : file->getChunks()) {
13741529 // We only care about live section chunks. Common chunks and other chunks
13751530 // don't generally contain relocations.
1376 SectionChunk *SC = dyn_cast<SectionChunk>(C);
1377 if (!SC || !SC->Live)
1531 SectionChunk *sc = dyn_cast<SectionChunk>(c);
1532 if (!sc || !sc->live)
13781533 continue;
13791534
1380 for (const coff_relocation &Reloc : SC->Relocs) {
1381 if (Config->Machine == I386 && Reloc.Type == COFF::IMAGE_REL_I386_REL32)
1535 for (const coff_relocation &reloc : sc->getRelocs()) {
1536 if (config->machine == I386 && reloc.Type == COFF::IMAGE_REL_I386_REL32)
13821537 // Ignore relative relocations on x86. On x86_64 they can't be ignored
13831538 // since they're also used to compute absolute addresses.
13841539 continue;
13851540
1386 Symbol *Ref = SC->File->getSymbol(Reloc.SymbolTableIndex);
1387 maybeAddAddressTakenFunction(UsedSymbols, Ref);
1541 Symbol *ref = sc->file->getSymbol(reloc.SymbolTableIndex);
1542 maybeAddAddressTakenFunction(usedSymbols, ref);
13881543 }
13891544 }
13901545}
......@@ -1393,109 +1548,109 @@ static void markSymbolsWithRelocations(ObjFile *File,
13931548// address-taken functions. It is sorted and uniqued, just like the safe SEH
13941549// table.
13951550void Writer::createGuardCFTables() {
1396 SymbolRVASet AddressTakenSyms;
1397 SymbolRVASet LongJmpTargets;
1398 for (ObjFile *File : ObjFile::Instances) {
1551 SymbolRVASet addressTakenSyms;
1552 SymbolRVASet longJmpTargets;
1553 for (ObjFile *file : ObjFile::instances) {
13991554 // If the object was compiled with /guard:cf, the address taken symbols
14001555 // are in .gfids$y sections, and the longjmp targets are in .gljmp$y
14011556 // sections. If the object was not compiled with /guard:cf, we assume there
14021557 // were no setjmp targets, and that all code symbols with relocations are
14031558 // possibly address-taken.
1404 if (File->hasGuardCF()) {
1405 markSymbolsForRVATable(File, File->getGuardFidChunks(), AddressTakenSyms);
1406 markSymbolsForRVATable(File, File->getGuardLJmpChunks(), LongJmpTargets);
1559 if (file->hasGuardCF()) {
1560 markSymbolsForRVATable(file, file->getGuardFidChunks(), addressTakenSyms);
1561 markSymbolsForRVATable(file, file->getGuardLJmpChunks(), longJmpTargets);
14071562 } else {
1408 markSymbolsWithRelocations(File, AddressTakenSyms);
1563 markSymbolsWithRelocations(file, addressTakenSyms);
14091564 }
14101565 }
14111566
14121567 // Mark the image entry as address-taken.
1413 if (Config->Entry)
1414 maybeAddAddressTakenFunction(AddressTakenSyms, Config->Entry);
1568 if (config->entry)
1569 maybeAddAddressTakenFunction(addressTakenSyms, config->entry);
14151570
14161571 // Mark exported symbols in executable sections as address-taken.
1417 for (Export &E : Config->Exports)
1418 maybeAddAddressTakenFunction(AddressTakenSyms, E.Sym);
1572 for (Export &e : config->exports)
1573 maybeAddAddressTakenFunction(addressTakenSyms, e.sym);
14191574
14201575 // Ensure sections referenced in the gfid table are 16-byte aligned.
1421 for (const ChunkAndOffset &C : AddressTakenSyms)
1422 if (C.InputChunk->Alignment < 16)
1423 C.InputChunk->Alignment = 16;
1576 for (const ChunkAndOffset &c : addressTakenSyms)
1577 if (c.inputChunk->getAlignment() < 16)
1578 c.inputChunk->setAlignment(16);
14241579
1425 maybeAddRVATable(std::move(AddressTakenSyms), "__guard_fids_table",
1580 maybeAddRVATable(std::move(addressTakenSyms), "__guard_fids_table",
14261581 "__guard_fids_count");
14271582
14281583 // Add the longjmp target table unless the user told us not to.
1429 if (Config->GuardCF == GuardCFLevel::Full)
1430 maybeAddRVATable(std::move(LongJmpTargets), "__guard_longjmp_table",
1584 if (config->guardCF == GuardCFLevel::Full)
1585 maybeAddRVATable(std::move(longJmpTargets), "__guard_longjmp_table",
14311586 "__guard_longjmp_count");
14321587
14331588 // Set __guard_flags, which will be used in the load config to indicate that
14341589 // /guard:cf was enabled.
1435 uint32_t GuardFlags = uint32_t(coff_guard_flags::CFInstrumented) |
1590 uint32_t guardFlags = uint32_t(coff_guard_flags::CFInstrumented) |
14361591 uint32_t(coff_guard_flags::HasFidTable);
1437 if (Config->GuardCF == GuardCFLevel::Full)
1438 GuardFlags |= uint32_t(coff_guard_flags::HasLongJmpTable);
1439 Symbol *FlagSym = Symtab->findUnderscore("__guard_flags");
1440 cast<DefinedAbsolute>(FlagSym)->setVA(GuardFlags);
1592 if (config->guardCF == GuardCFLevel::Full)
1593 guardFlags |= uint32_t(coff_guard_flags::HasLongJmpTable);
1594 Symbol *flagSym = symtab->findUnderscore("__guard_flags");
1595 cast<DefinedAbsolute>(flagSym)->setVA(guardFlags);
14411596}
14421597
14431598// Take a list of input sections containing symbol table indices and add those
14441599// symbols to an RVA table. The challenge is that symbol RVAs are not known and
14451600// depend on the table size, so we can't directly build a set of integers.
1446void Writer::markSymbolsForRVATable(ObjFile *File,
1447 ArrayRef<SectionChunk *> SymIdxChunks,
1448 SymbolRVASet &TableSymbols) {
1449 for (SectionChunk *C : SymIdxChunks) {
1601void Writer::markSymbolsForRVATable(ObjFile *file,
1602 ArrayRef<SectionChunk *> symIdxChunks,
1603 SymbolRVASet &tableSymbols) {
1604 for (SectionChunk *c : symIdxChunks) {
14501605 // Skip sections discarded by linker GC. This comes up when a .gfids section
14511606 // is associated with something like a vtable and the vtable is discarded.
14521607 // In this case, the associated gfids section is discarded, and we don't
14531608 // mark the virtual member functions as address-taken by the vtable.
1454 if (!C->Live)
1609 if (!c->live)
14551610 continue;
14561611
14571612 // Validate that the contents look like symbol table indices.
1458 ArrayRef<uint8_t> Data = C->getContents();
1459 if (Data.size() % 4 != 0) {
1460 warn("ignoring " + C->getSectionName() +
1461 " symbol table index section in object " + toString(File));
1613 ArrayRef<uint8_t> data = c->getContents();
1614 if (data.size() % 4 != 0) {
1615 warn("ignoring " + c->getSectionName() +
1616 " symbol table index section in object " + toString(file));
14621617 continue;
14631618 }
14641619
14651620 // Read each symbol table index and check if that symbol was included in the
14661621 // final link. If so, add it to the table symbol set.
1467 ArrayRef<ulittle32_t> SymIndices(
1468 reinterpret_cast<const ulittle32_t *>(Data.data()), Data.size() / 4);
1469 ArrayRef<Symbol *> ObjSymbols = File->getSymbols();
1470 for (uint32_t SymIndex : SymIndices) {
1471 if (SymIndex >= ObjSymbols.size()) {
1622 ArrayRef<ulittle32_t> symIndices(
1623 reinterpret_cast<const ulittle32_t *>(data.data()), data.size() / 4);
1624 ArrayRef<Symbol *> objSymbols = file->getSymbols();
1625 for (uint32_t symIndex : symIndices) {
1626 if (symIndex >= objSymbols.size()) {
14721627 warn("ignoring invalid symbol table index in section " +
1473 C->getSectionName() + " in object " + toString(File));
1628 c->getSectionName() + " in object " + toString(file));
14741629 continue;
14751630 }
1476 if (Symbol *S = ObjSymbols[SymIndex]) {
1477 if (S->isLive())
1478 addSymbolToRVASet(TableSymbols, cast<Defined>(S));
1631 if (Symbol *s = objSymbols[symIndex]) {
1632 if (s->isLive())
1633 addSymbolToRVASet(tableSymbols, cast<Defined>(s));
14791634 }
14801635 }
14811636 }
14821637}
14831638
14841639// Replace the absolute table symbol with a synthetic symbol pointing to
1485// TableChunk so that we can emit base relocations for it and resolve section
1640// tableChunk so that we can emit base relocations for it and resolve section
14861641// relative relocations.
1487void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym,
1488 StringRef CountSym) {
1489 if (TableSymbols.empty())
1642void Writer::maybeAddRVATable(SymbolRVASet tableSymbols, StringRef tableSym,
1643 StringRef countSym) {
1644 if (tableSymbols.empty())
14901645 return;
14911646
1492 RVATableChunk *TableChunk = make<RVATableChunk>(std::move(TableSymbols));
1493 RdataSec->addChunk(TableChunk);
1647 RVATableChunk *tableChunk = make<RVATableChunk>(std::move(tableSymbols));
1648 rdataSec->addChunk(tableChunk);
14941649
1495 Symbol *T = Symtab->findUnderscore(TableSym);
1496 Symbol *C = Symtab->findUnderscore(CountSym);
1497 replaceSymbol<DefinedSynthetic>(T, T->getName(), TableChunk);
1498 cast<DefinedAbsolute>(C)->setVA(TableChunk->getSize() / 4);
1650 Symbol *t = symtab->findUnderscore(tableSym);
1651 Symbol *c = symtab->findUnderscore(countSym);
1652 replaceSymbol<DefinedSynthetic>(t, t->getName(), tableChunk);
1653 cast<DefinedAbsolute>(c)->setVA(tableChunk->getSize() / 4);
14991654}
15001655
15011656// MinGW specific. Gather all relocations that are imported from a DLL even
......@@ -1503,26 +1658,26 @@ void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym,
15031658// uses for fixing them up, and provide the synthetic symbols that the
15041659// runtime uses for finding the table.
15051660void Writer::createRuntimePseudoRelocs() {
1506 std::vector<RuntimePseudoReloc> Rels;
1661 std::vector<RuntimePseudoReloc> rels;
15071662
1508 for (Chunk *C : Symtab->getChunks()) {
1509 auto *SC = dyn_cast<SectionChunk>(C);
1510 if (!SC || !SC->Live)
1663 for (Chunk *c : symtab->getChunks()) {
1664 auto *sc = dyn_cast<SectionChunk>(c);
1665 if (!sc || !sc->live)
15111666 continue;
1512 SC->getRuntimePseudoRelocs(Rels);
1667 sc->getRuntimePseudoRelocs(rels);
15131668 }
15141669
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);
1670 if (!rels.empty())
1671 log("Writing " + Twine(rels.size()) + " runtime pseudo relocations");
1672 PseudoRelocTableChunk *table = make<PseudoRelocTableChunk>(rels);
1673 rdataSec->addChunk(table);
1674 EmptyChunk *endOfList = make<EmptyChunk>();
1675 rdataSec->addChunk(endOfList);
1676
1677 Symbol *headSym = symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST__");
1678 Symbol *endSym = symtab->findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST_END__");
1679 replaceSymbol<DefinedSynthetic>(headSym, headSym->getName(), table);
1680 replaceSymbol<DefinedSynthetic>(endSym, endSym->getName(), endOfList);
15261681}
15271682
15281683// MinGW specific.
......@@ -1531,32 +1686,32 @@ void Writer::createRuntimePseudoRelocs() {
15311686// There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__
15321687// and __DTOR_LIST__ respectively.
15331688void 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);
1689 AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(-1);
1690 AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(0);
1691 AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(-1);
1692 AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(0);
1693 ctorsSec->insertChunkAtStart(ctorListHead);
1694 ctorsSec->addChunk(ctorListEnd);
1695 dtorsSec->insertChunkAtStart(dtorListHead);
1696 dtorsSec->addChunk(dtorListEnd);
1697
1698 Symbol *ctorListSym = symtab->findUnderscore("__CTOR_LIST__");
1699 Symbol *dtorListSym = symtab->findUnderscore("__DTOR_LIST__");
1700 replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
1701 ctorListHead);
1702 replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
1703 dtorListHead);
15491704}
15501705
15511706// Handles /section options to allow users to overwrite
15521707// section attributes.
15531708void Writer::setSectionPermissions() {
1554 for (auto &P : Config->Section) {
1555 StringRef Name = P.first;
1556 uint32_t Perm = P.second;
1557 for (OutputSection *Sec : OutputSections)
1558 if (Sec->Name == Name)
1559 Sec->setPermissions(Perm);
1709 for (auto &p : config->section) {
1710 StringRef name = p.first;
1711 uint32_t perm = p.second;
1712 for (OutputSection *sec : outputSections)
1713 if (sec->name == name)
1714 sec->setPermissions(perm);
15601715 }
15611716}
15621717
......@@ -1564,18 +1719,19 @@ void Writer::setSectionPermissions() {
15641719void Writer::writeSections() {
15651720 // Record the number of sections to apply section index relocations
15661721 // against absolute symbols. See applySecIdx in Chunks.cpp..
1567 DefinedAbsolute::NumOutputSections = OutputSections.size();
1722 DefinedAbsolute::numOutputSections = outputSections.size();
15681723
1569 uint8_t *Buf = Buffer->getBufferStart();
1570 for (OutputSection *Sec : OutputSections) {
1571 uint8_t *SecBuf = Buf + Sec->getFileOff();
1724 uint8_t *buf = buffer->getBufferStart();
1725 for (OutputSection *sec : outputSections) {
1726 uint8_t *secBuf = buf + sec->getFileOff();
15721727 // Fill gaps between functions in .text with INT3 instructions
15731728 // instead of leaving as NUL bytes (which can be interpreted as
15741729 // ADD instructions).
1575 if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE)
1576 memset(SecBuf, 0xCC, Sec->getRawSize());
1577 for_each(parallel::par, Sec->Chunks.begin(), Sec->Chunks.end(),
1578 [&](Chunk *C) { C->writeTo(SecBuf); });
1730 if (sec->header.Characteristics & IMAGE_SCN_CNT_CODE)
1731 memset(secBuf, 0xCC, sec->getRawSize());
1732 parallelForEach(sec->chunks, [&](Chunk *c) {
1733 c->writeTo(secBuf + c->getRVA() - sec->getRVA());
1734 });
15791735 }
15801736}
15811737
......@@ -1586,8 +1742,8 @@ void Writer::writeBuildId() {
15861742 // 2) In all cases, the PE COFF file header also contains a timestamp.
15871743 // For reproducibility, instead of a timestamp we want to use a hash of the
15881744 // PE contents.
1589 if (Config->Debug) {
1590 assert(BuildId && "BuildId is not set!");
1745 if (config->debug) {
1746 assert(buildId && "BuildId is not set!");
15911747 // BuildId->BuildId was filled in when the PDB was written.
15921748 }
15931749
......@@ -1595,62 +1751,65 @@ void Writer::writeBuildId() {
15951751 // "timestamp" in the COFF file header, and the ones in the coff debug
15961752 // directory. Now we can hash the file and write that hash to the various
15971753 // timestamp fields in the file.
1598 StringRef OutputFileData(
1599 reinterpret_cast<const char *>(Buffer->getBufferStart()),
1600 Buffer->getBufferSize());
1754 StringRef outputFileData(
1755 reinterpret_cast<const char *>(buffer->getBufferStart()),
1756 buffer->getBufferSize());
16011757
1602 uint32_t Timestamp = Config->Timestamp;
1603 uint64_t Hash = 0;
1604 bool GenerateSyntheticBuildId =
1605 Config->MinGW && Config->Debug && Config->PDBPath.empty();
1758 uint32_t timestamp = config->timestamp;
1759 uint64_t hash = 0;
1760 bool generateSyntheticBuildId =
1761 config->mingw && config->debug && config->pdbPath.empty();
16061762
1607 if (Config->Repro || GenerateSyntheticBuildId)
1608 Hash = xxHash64(OutputFileData);
1763 if (config->repro || generateSyntheticBuildId)
1764 hash = xxHash64(outputFileData);
16091765
1610 if (Config->Repro)
1611 Timestamp = static_cast<uint32_t>(Hash);
1766 if (config->repro)
1767 timestamp = static_cast<uint32_t>(hash);
16121768
1613 if (GenerateSyntheticBuildId) {
1769 if (generateSyntheticBuildId) {
16141770 // For MinGW builds without a PDB file, we still generate a build id
16151771 // 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);
1772 buildId->buildId->PDB70.CVSignature = OMF::Signature::PDB70;
1773 buildId->buildId->PDB70.Age = 1;
1774 memcpy(buildId->buildId->PDB70.Signature, &hash, 8);
16191775 // 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);
1776 memcpy(&buildId->buildId->PDB70.Signature[8], "LLD PDB.", 8);
16211777 }
16221778
1623 if (DebugDirectory)
1624 DebugDirectory->setTimeDateStamp(Timestamp);
1779 if (debugDirectory)
1780 debugDirectory->setTimeDateStamp(timestamp);
16251781
1626 uint8_t *Buf = Buffer->getBufferStart();
1627 Buf += DOSStubSize + sizeof(PEMagic);
1628 object::coff_file_header *CoffHeader =
1629 reinterpret_cast<coff_file_header *>(Buf);
1630 CoffHeader->TimeDateStamp = Timestamp;
1782 uint8_t *buf = buffer->getBufferStart();
1783 buf += dosStubSize + sizeof(PEMagic);
1784 object::coff_file_header *coffHeader =
1785 reinterpret_cast<coff_file_header *>(buf);
1786 coffHeader->TimeDateStamp = timestamp;
16311787}
16321788
16331789// Sort .pdata section contents according to PE/COFF spec 5.5.
16341790void Writer::sortExceptionTable() {
1635 if (!FirstPdata)
1791 if (!firstPdata)
16361792 return;
16371793 // We assume .pdata contains function table entries only.
1638 auto BufAddr = [&](Chunk *C) {
1639 return Buffer->getBufferStart() + C->getOutputSection()->getFileOff() +
1640 C->getRVA() - C->getOutputSection()->getRVA();
1794 auto bufAddr = [&](Chunk *c) {
1795 OutputSection *os = c->getOutputSection();
1796 return buffer->getBufferStart() + os->getFileOff() + c->getRVA() -
1797 os->getRVA();
16411798 };
1642 uint8_t *Begin = BufAddr(FirstPdata);
1643 uint8_t *End = BufAddr(LastPdata) + LastPdata->getSize();
1644 if (Config->Machine == AMD64) {
1645 struct Entry { ulittle32_t Begin, End, Unwind; };
1646 sort(parallel::par, (Entry *)Begin, (Entry *)End,
1647 [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; });
1799 uint8_t *begin = bufAddr(firstPdata);
1800 uint8_t *end = bufAddr(lastPdata) + lastPdata->getSize();
1801 if (config->machine == AMD64) {
1802 struct Entry { ulittle32_t begin, end, unwind; };
1803 parallelSort(
1804 MutableArrayRef<Entry>((Entry *)begin, (Entry *)end),
1805 [](const Entry &a, const Entry &b) { return a.begin < b.begin; });
16481806 return;
16491807 }
1650 if (Config->Machine == ARMNT || Config->Machine == ARM64) {
1651 struct Entry { ulittle32_t Begin, Unwind; };
1652 sort(parallel::par, (Entry *)Begin, (Entry *)End,
1653 [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; });
1808 if (config->machine == ARMNT || config->machine == ARM64) {
1809 struct Entry { ulittle32_t begin, unwind; };
1810 parallelSort(
1811 MutableArrayRef<Entry>((Entry *)begin, (Entry *)end),
1812 [](const Entry &a, const Entry &b) { return a.begin < b.begin; });
16541813 return;
16551814 }
16561815 errs() << "warning: don't know how to handle .pdata.\n";
......@@ -1670,76 +1829,92 @@ void Writer::sortExceptionTable() {
16701829// pointers in the order that they are listed in the object file (top to
16711830// bottom), otherwise global objects might not be initialized in the
16721831// 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!");
1832void Writer::sortCRTSectionChunks(std::vector<Chunk *> &chunks) {
1833 auto sectionChunkOrder = [](const Chunk *a, const Chunk *b) {
1834 auto sa = dyn_cast<SectionChunk>(a);
1835 auto sb = dyn_cast<SectionChunk>(b);
1836 assert(sa && sb && "Non-section chunks in CRT section!");
16781837
1679 StringRef SAObj = SA->File->MB.getBufferIdentifier();
1680 StringRef SBObj = SB->File->MB.getBufferIdentifier();
1838 StringRef sAObj = sa->file->mb.getBufferIdentifier();
1839 StringRef sBObj = sb->file->mb.getBufferIdentifier();
16811840
1682 return SAObj == SBObj && SA->getSectionNumber() < SB->getSectionNumber();
1841 return sAObj == sBObj && sa->getSectionNumber() < sb->getSectionNumber();
16831842 };
1684 std::stable_sort(Chunks.begin(), Chunks.end(), SectionChunkOrder);
1843 llvm::stable_sort(chunks, sectionChunkOrder);
16851844
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()));
1845 if (config->verbose) {
1846 for (auto &c : chunks) {
1847 auto sc = dyn_cast<SectionChunk>(c);
1848 log(" " + sc->file->mb.getBufferIdentifier().str() +
1849 ", SectionID: " + Twine(sc->getSectionNumber()));
16911850 }
16921851 }
16931852}
16941853
1695OutputSection *Writer::findSection(StringRef Name) {
1696 for (OutputSection *Sec : OutputSections)
1697 if (Sec->Name == Name)
1698 return Sec;
1854OutputSection *Writer::findSection(StringRef name) {
1855 for (OutputSection *sec : outputSections)
1856 if (sec->name == name)
1857 return sec;
16991858 return nullptr;
17001859}
17011860
17021861uint32_t Writer::getSizeOfInitializedData() {
1703 uint32_t Res = 0;
1704 for (OutputSection *S : OutputSections)
1705 if (S->Header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
1706 Res += S->getRawSize();
1707 return Res;
1862 uint32_t res = 0;
1863 for (OutputSection *s : outputSections)
1864 if (s->header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
1865 res += s->getRawSize();
1866 return res;
17081867}
17091868
17101869// Add base relocations to .reloc section.
17111870void Writer::addBaserels() {
1712 if (!Config->Relocatable)
1871 if (!config->relocatable)
17131872 return;
1714 RelocSec->Chunks.clear();
1715 std::vector<Baserel> V;
1716 for (OutputSection *Sec : OutputSections) {
1717 if (Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
1873 relocSec->chunks.clear();
1874 std::vector<Baserel> v;
1875 for (OutputSection *sec : outputSections) {
1876 if (sec->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
17181877 continue;
17191878 // Collect all locations for base relocations.
1720 for (Chunk *C : Sec->Chunks)
1721 C->getBaserels(&V);
1879 for (Chunk *c : sec->chunks)
1880 c->getBaserels(&v);
17221881 // Add the addresses to .reloc section.
1723 if (!V.empty())
1724 addBaserelBlocks(V);
1725 V.clear();
1882 if (!v.empty())
1883 addBaserelBlocks(v);
1884 v.clear();
17261885 }
17271886}
17281887
17291888// Add addresses to .reloc section. Note that addresses are grouped by page.
1730void Writer::addBaserelBlocks(std::vector<Baserel> &V) {
1731 const uint32_t Mask = ~uint32_t(PageSize - 1);
1732 uint32_t Page = V[0].RVA & Mask;
1733 size_t I = 0, J = 1;
1734 for (size_t E = V.size(); J < E; ++J) {
1735 uint32_t P = V[J].RVA & Mask;
1736 if (P == Page)
1889void Writer::addBaserelBlocks(std::vector<Baserel> &v) {
1890 const uint32_t mask = ~uint32_t(pageSize - 1);
1891 uint32_t page = v[0].rva & mask;
1892 size_t i = 0, j = 1;
1893 for (size_t e = v.size(); j < e; ++j) {
1894 uint32_t p = v[j].rva & mask;
1895 if (p == page)
17371896 continue;
1738 RelocSec->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
1739 I = J;
1740 Page = P;
1897 relocSec->addChunk(make<BaserelChunk>(page, &v[i], &v[0] + j));
1898 i = j;
1899 page = p;
17411900 }
1742 if (I == J)
1901 if (i == j)
17431902 return;
1744 RelocSec->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
1903 relocSec->addChunk(make<BaserelChunk>(page, &v[i], &v[0] + j));
1904}
1905
1906PartialSection *Writer::createPartialSection(StringRef name,
1907 uint32_t outChars) {
1908 PartialSection *&pSec = partialSections[{name, outChars}];
1909 if (pSec)
1910 return pSec;
1911 pSec = make<PartialSection>(name, outChars);
1912 return pSec;
1913}
1914
1915PartialSection *Writer::findPartialSection(StringRef name, uint32_t outChars) {
1916 auto it = partialSections.find({name, outChars});
1917 if (it != partialSections.end())
1918 return it->second;
1919 return nullptr;
17451920}
deps/lld/COFF/Writer.h+36-26
......@@ -1,9 +1,8 @@
11//===- Writer.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -19,10 +18,19 @@
1918
2019namespace lld {
2120namespace coff {
22static const int PageSize = 4096;
21static const int pageSize = 4096;
2322
2423void writeResult();
2524
25class PartialSection {
26public:
27 PartialSection(StringRef n, uint32_t chars)
28 : name(n), characteristics(chars) {}
29 StringRef name;
30 unsigned characteristics;
31 std::vector<Chunk *> chunks;
32};
33
2634// OutputSection represents a section in an output file. It's a
2735// container of chunks. OutputSection and Chunk are 1:N relationship.
2836// Chunks cannot belong to more than one OutputSections. The writer
......@@ -30,46 +38,48 @@ void writeResult();
3038// non-overlapping file offsets and RVAs.
3139class OutputSection {
3240public:
33 OutputSection(llvm::StringRef N, uint32_t Chars) : Name(N) {
34 Header.Characteristics = Chars;
41 OutputSection(llvm::StringRef n, uint32_t chars) : name(n) {
42 header.Characteristics = chars;
3543 }
36 void addChunk(Chunk *C);
37 void insertChunkAtStart(Chunk *C);
38 void merge(OutputSection *Other);
39 void addPermissions(uint32_t C);
40 void setPermissions(uint32_t C);
41 uint64_t getRVA() { return Header.VirtualAddress; }
42 uint64_t getFileOff() { return Header.PointerToRawData; }
43 void writeHeaderTo(uint8_t *Buf);
44 void addChunk(Chunk *c);
45 void insertChunkAtStart(Chunk *c);
46 void merge(OutputSection *other);
47 void setPermissions(uint32_t c);
48 uint64_t getRVA() { return header.VirtualAddress; }
49 uint64_t getFileOff() { return header.PointerToRawData; }
50 void writeHeaderTo(uint8_t *buf);
51 void addContributingPartialSection(PartialSection *sec);
4452
4553 // Returns the size of this section in an executable memory image.
4654 // This may be smaller than the raw size (the raw size is multiple
4755 // of disk sector size, so there may be padding at end), or may be
4856 // larger (if that's the case, the loader reserves spaces after end
4957 // of raw data).
50 uint64_t getVirtualSize() { return Header.VirtualSize; }
58 uint64_t getVirtualSize() { return header.VirtualSize; }
5159
5260 // Returns the size of the section in the output file.
53 uint64_t getRawSize() { return Header.SizeOfRawData; }
61 uint64_t getRawSize() { return header.SizeOfRawData; }
5462
5563 // Set offset into the string table storing this section name.
5664 // Used only when the name is longer than 8 bytes.
57 void setStringTableOff(uint32_t V) { StringTableOff = V; }
65 void setStringTableOff(uint32_t v) { stringTableOff = v; }
5866
5967 // N.B. The section index is one based.
60 uint32_t SectionIndex = 0;
68 uint32_t sectionIndex = 0;
69
70 llvm::StringRef name;
71 llvm::object::coff_section header = {};
6172
62 llvm::StringRef Name;
63 llvm::object::coff_section Header = {};
73 std::vector<Chunk *> chunks;
74 std::vector<Chunk *> origChunks;
6475
65 std::vector<Chunk *> Chunks;
66 std::vector<Chunk *> OrigChunks;
76 std::vector<PartialSection *> contribSections;
6777
6878private:
69 uint32_t StringTableOff = 0;
79 uint32_t stringTableOff = 0;
7080};
7181
72}
73}
82} // namespace coff
83} // namespace lld
7484
7585#endif
deps/lld/Common/Args.cpp+48-39
......@@ -1,9 +1,8 @@
11//===- Args.cpp -----------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -18,56 +17,66 @@
1817using namespace llvm;
1918using namespace lld;
2019
21int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) {
22 auto *A = Args.getLastArg(Key);
23 if (!A)
20// TODO(sbc): Remove this once CGOptLevel can be set completely based on bitcode
21// function metadata.
22CodeGenOpt::Level lld::args::getCGOptLevel(int optLevelLTO) {
23 if (optLevelLTO == 3)
24 return CodeGenOpt::Aggressive;
25 assert(optLevelLTO < 3);
26 return CodeGenOpt::Default;
27}
28
29int64_t lld::args::getInteger(opt::InputArgList &args, unsigned key,
30 int64_t Default) {
31 auto *a = args.getLastArg(key);
32 if (!a)
2433 return Default;
2534
26 int V;
27 if (to_integer(A->getValue(), V, 10))
28 return V;
35 int64_t v;
36 if (to_integer(a->getValue(), v, 10))
37 return v;
2938
30 StringRef Spelling = Args.getArgString(A->getIndex());
31 error(Spelling + ": number expected, but got '" + A->getValue() + "'");
39 StringRef spelling = args.getArgString(a->getIndex());
40 error(spelling + ": number expected, but got '" + a->getValue() + "'");
3241 return 0;
3342}
3443
35std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) {
36 std::vector<StringRef> V;
37 for (auto *Arg : Args.filtered(Id))
38 V.push_back(Arg->getValue());
39 return V;
44std::vector<StringRef> lld::args::getStrings(opt::InputArgList &args, int id) {
45 std::vector<StringRef> v;
46 for (auto *arg : args.filtered(id))
47 v.push_back(arg->getValue());
48 return v;
4049}
4150
42uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id,
43 StringRef Key, uint64_t Default) {
44 for (auto *Arg : Args.filtered_reverse(Id)) {
45 std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
46 if (KV.first == Key) {
47 uint64_t Result = Default;
48 if (!to_integer(KV.second, Result))
49 error("invalid " + Key + ": " + KV.second);
50 return Result;
51uint64_t lld::args::getZOptionValue(opt::InputArgList &args, int id,
52 StringRef key, uint64_t Default) {
53 for (auto *arg : args.filtered_reverse(id)) {
54 std::pair<StringRef, StringRef> kv = StringRef(arg->getValue()).split('=');
55 if (kv.first == key) {
56 uint64_t result = Default;
57 if (!to_integer(kv.second, result))
58 error("invalid " + key + ": " + kv.second);
59 return result;
5160 }
5261 }
5362 return Default;
5463}
5564
56std::vector<StringRef> lld::args::getLines(MemoryBufferRef MB) {
57 SmallVector<StringRef, 0> Arr;
58 MB.getBuffer().split(Arr, '\n');
65std::vector<StringRef> lld::args::getLines(MemoryBufferRef mb) {
66 SmallVector<StringRef, 0> arr;
67 mb.getBuffer().split(arr, '\n');
5968
60 std::vector<StringRef> Ret;
61 for (StringRef S : Arr) {
62 S = S.trim();
63 if (!S.empty() && S[0] != '#')
64 Ret.push_back(S);
69 std::vector<StringRef> ret;
70 for (StringRef s : arr) {
71 s = s.trim();
72 if (!s.empty() && s[0] != '#')
73 ret.push_back(s);
6574 }
66 return Ret;
75 return ret;
6776}
6877
69StringRef lld::args::getFilenameWithoutExe(StringRef Path) {
70 if (Path.endswith_lower(".exe"))
71 return sys::path::stem(Path);
72 return sys::path::filename(Path);
78StringRef lld::args::getFilenameWithoutExe(StringRef path) {
79 if (path.endswith_lower(".exe"))
80 return sys::path::stem(path);
81 return sys::path::filename(path);
7382}
deps/lld/Common/CMakeLists.txt+27
......@@ -2,15 +2,42 @@ if(NOT LLD_BUILT_STANDALONE)
22 set(tablegen_deps intrinsics_gen)
33endif()
44
5find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc)
6find_first_existing_vc_file("${LLD_SOURCE_DIR}" lld_vc)
7
8set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc")
9set(generate_vcs_version_script "${LLVM_CMAKE_PATH}/GenerateVersionFromVCS.cmake")
10
11if(lld_vc)
12 set(lld_source_dir ${LLD_SOURCE_DIR})
13endif()
14
15add_custom_command(OUTPUT "${version_inc}"
16 DEPENDS "${lld_vc}" "${generate_vcs_version_script}"
17 COMMAND ${CMAKE_COMMAND} "-DNAMES=LLD"
18 "-DLLD_SOURCE_DIR=${LLD_SOURCE_DIR}"
19 "-DHEADER_FILE=${version_inc}"
20 -P "${generate_vcs_version_script}")
21
22# Mark the generated header as being generated.
23set_source_files_properties("${version_inc}"
24 PROPERTIES GENERATED TRUE
25 HEADER_FILE_ONLY TRUE)
26
27set_property(SOURCE Version.cpp APPEND PROPERTY
28 COMPILE_DEFINITIONS "HAVE_VCS_VERSION_INC")
29
530add_lld_library(lldCommon
631 Args.cpp
732 ErrorHandler.cpp
33 Filesystem.cpp
834 Memory.cpp
935 Reproduce.cpp
1036 Strings.cpp
1137 TargetOptionsCommandFlags.cpp
1238 Threads.cpp
1339 Timer.cpp
40 VCSVersion.inc
1441 Version.cpp
1542
1643 ADDITIONAL_HEADER_DIRS
deps/lld/Common/ErrorHandler.cpp+97-63
......@@ -1,9 +1,8 @@
11//===- ErrorHandler.cpp ---------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -17,6 +16,7 @@
1716#include "llvm/Support/ManagedStatic.h"
1817#include "llvm/Support/raw_ostream.h"
1918#include <mutex>
19#include <regex>
2020
2121#if !defined(_MSC_VER) && !defined(__MINGW32__)
2222#include <unistd.h>
......@@ -27,29 +27,29 @@ using namespace lld;
2727
2828// The functions defined in this file can be called from multiple threads,
2929// but outs() or errs() are not thread-safe. We protect them using a mutex.
30static std::mutex Mu;
30static std::mutex mu;
3131
3232// Prints "\n" or does nothing, depending on Msg contents of
3333// the previous call of this function.
34static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
34static void newline(raw_ostream *errorOS, const Twine &msg) {
3535 // True if the previous error message contained "\n".
3636 // We want to separate multi-line error messages with a newline.
37 static bool Flag;
37 static bool flag;
3838
39 if (Flag)
40 *ErrorOS << "\n";
41 Flag = StringRef(Msg.str()).contains('\n');
39 if (flag)
40 *errorOS << "\n";
41 flag = StringRef(msg.str()).contains('\n');
4242}
4343
4444ErrorHandler &lld::errorHandler() {
45 static ErrorHandler Handler;
46 return Handler;
45 static ErrorHandler handler;
46 return handler;
4747}
4848
49void lld::exitLld(int Val) {
49void lld::exitLld(int val) {
5050 // Delete any temporary file, while keeping the memory mapping open.
51 if (errorHandler().OutputBuffer)
52 errorHandler().OutputBuffer->discard();
51 if (errorHandler().outputBuffer)
52 errorHandler().outputBuffer->discard();
5353
5454 // Dealloc/destroy ManagedStatic variables before calling
5555 // _exit(). In a non-LTO build, this is a nop. In an LTO
......@@ -58,87 +58,121 @@ void lld::exitLld(int Val) {
5858
5959 outs().flush();
6060 errs().flush();
61 _exit(Val);
61 _exit(val);
6262}
6363
64void lld::diagnosticHandler(const DiagnosticInfo &DI) {
65 SmallString<128> S;
66 raw_svector_ostream OS(S);
67 DiagnosticPrinterRawOStream DP(OS);
68 DI.print(DP);
69 switch (DI.getSeverity()) {
64void lld::diagnosticHandler(const DiagnosticInfo &di) {
65 SmallString<128> s;
66 raw_svector_ostream os(s);
67 DiagnosticPrinterRawOStream dp(os);
68 di.print(dp);
69 switch (di.getSeverity()) {
7070 case DS_Error:
71 error(S);
71 error(s);
7272 break;
7373 case DS_Warning:
74 warn(S);
74 warn(s);
7575 break;
7676 case DS_Remark:
7777 case DS_Note:
78 message(S);
78 message(s);
7979 break;
8080 }
8181}
8282
83void lld::checkError(Error E) {
84 handleAllErrors(std::move(E),
85 [&](ErrorInfoBase &EIB) { error(EIB.message()); });
83void lld::checkError(Error e) {
84 handleAllErrors(std::move(e),
85 [&](ErrorInfoBase &eib) { error(eib.message()); });
86}
87
88static std::string getLocation(std::string msg, std::string defaultMsg) {
89 static std::vector<std::regex> Regexes{
90 std::regex(R"(^undefined symbol:.*\n>>> referenced by (\S+):(\d+)\n.*)"),
91 std::regex(R"(^undefined symbol:.*\n>>> referenced by (.*):)"),
92 std::regex(
93 R"(^duplicate symbol: .*\n>>> defined in (\S+)\n>>> defined in.*)"),
94 std::regex(
95 R"(^duplicate symbol: .*\n>>> defined at (\S+):(\d+).*)"),
96 std::regex(
97 R"(.*\n>>> defined in .*\n>>> referenced by (\S+):(\d+))"),
98 std::regex(
99 R"(^undefined (internal|hidden|protected) symbol: .*\n>>> referenced by (\S+):(\d+)\n.*)"),
100 std::regex(R"((\S+):(\d+): unclosed quote)"),
101 };
102
103 std::smatch Match;
104 for (std::regex &Re : Regexes) {
105 if (std::regex_search(msg, Match, Re)) {
106 return Match.size() > 2 ? Match.str(1) + "(" + Match.str(2) + ")"
107 : Match.str(1);
108 }
109 }
110 return defaultMsg;
86111}
87112
88void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
89 *ErrorOS << LogName << ": ";
90 if (ColorDiagnostics) {
91 ErrorOS->changeColor(C, true);
92 *ErrorOS << S;
93 ErrorOS->resetColor();
113void ErrorHandler::printHeader(StringRef s, raw_ostream::Colors c,
114 const Twine &msg) {
115
116 if (vsDiagnostics) {
117 // A Visual Studio-style error message starts with an error location.
118 // If a location cannot be extracted then we default to LogName.
119 *errorOS << getLocation(msg.str(), logName) << ": ";
120 } else {
121 *errorOS << logName << ": ";
122 }
123
124 if (colorDiagnostics) {
125 errorOS->changeColor(c, true);
126 *errorOS << s;
127 errorOS->resetColor();
94128 } else {
95 *ErrorOS << S;
129 *errorOS << s;
96130 }
97131}
98132
99void ErrorHandler::log(const Twine &Msg) {
100 if (Verbose) {
101 std::lock_guard<std::mutex> Lock(Mu);
102 *ErrorOS << LogName << ": " << Msg << "\n";
133void ErrorHandler::log(const Twine &msg) {
134 if (verbose) {
135 std::lock_guard<std::mutex> lock(mu);
136 *errorOS << logName << ": " << msg << "\n";
103137 }
104138}
105139
106void ErrorHandler::message(const Twine &Msg) {
107 std::lock_guard<std::mutex> Lock(Mu);
108 outs() << Msg << "\n";
140void ErrorHandler::message(const Twine &msg) {
141 std::lock_guard<std::mutex> lock(mu);
142 outs() << msg << "\n";
109143 outs().flush();
110144}
111145
112void ErrorHandler::warn(const Twine &Msg) {
113 if (FatalWarnings) {
114 error(Msg);
146void ErrorHandler::warn(const Twine &msg) {
147 if (fatalWarnings) {
148 error(msg);
115149 return;
116150 }
117151
118 std::lock_guard<std::mutex> Lock(Mu);
119 newline(ErrorOS, Msg);
120 print("warning: ", raw_ostream::MAGENTA);
121 *ErrorOS << Msg << "\n";
152 std::lock_guard<std::mutex> lock(mu);
153 newline(errorOS, msg);
154 printHeader("warning: ", raw_ostream::MAGENTA, msg);
155 *errorOS << msg << "\n";
122156}
123157
124void ErrorHandler::error(const Twine &Msg) {
125 std::lock_guard<std::mutex> Lock(Mu);
126 newline(ErrorOS, Msg);
127
128 if (ErrorLimit == 0 || ErrorCount < ErrorLimit) {
129 print("error: ", raw_ostream::RED);
130 *ErrorOS << Msg << "\n";
131 } else if (ErrorCount == ErrorLimit) {
132 print("error: ", raw_ostream::RED);
133 *ErrorOS << ErrorLimitExceededMsg << "\n";
134 if (ExitEarly)
158void ErrorHandler::error(const Twine &msg) {
159 std::lock_guard<std::mutex> lock(mu);
160 newline(errorOS, msg);
161
162 if (errorLimit == 0 || errorCount < errorLimit) {
163 printHeader("error: ", raw_ostream::RED, msg);
164 *errorOS << msg << "\n";
165 } else if (errorCount == errorLimit) {
166 printHeader("error: ", raw_ostream::RED, msg);
167 *errorOS << errorLimitExceededMsg << "\n";
168 if (exitEarly)
135169 exitLld(1);
136170 }
137171
138 ++ErrorCount;
172 ++errorCount;
139173}
140174
141void ErrorHandler::fatal(const Twine &Msg) {
142 error(Msg);
175void ErrorHandler::fatal(const Twine &msg) {
176 error(msg);
143177 exitLld(1);
144178}
deps/lld/Common/Filesystem.cpp created+99
......@@ -0,0 +1,99 @@
1//===- Filesystem.cpp -----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a few utility functions to handle files.
10//
11//===----------------------------------------------------------------------===//
12
13#include "lld/Common/Filesystem.h"
14#include "lld/Common/Threads.h"
15#include "llvm/Config/llvm-config.h"
16#include "llvm/Support/FileOutputBuffer.h"
17#include "llvm/Support/FileSystem.h"
18#if LLVM_ON_UNIX
19#include <unistd.h>
20#endif
21#include <thread>
22
23using namespace llvm;
24using namespace lld;
25
26// Removes a given file asynchronously. This is a performance hack,
27// so remove this when operating systems are improved.
28//
29// On Linux (and probably on other Unix-like systems), unlink(2) is a
30// noticeably slow system call. As of 2016, unlink takes 250
31// milliseconds to remove a 1 GB file on ext4 filesystem on my machine.
32//
33// To create a new result file, we first remove existing file. So, if
34// you repeatedly link a 1 GB program in a regular compile-link-debug
35// cycle, every cycle wastes 250 milliseconds only to remove a file.
36// Since LLD can link a 1 GB binary in about 5 seconds, that waste
37// actually counts.
38//
39// This function spawns a background thread to remove the file.
40// The calling thread returns almost immediately.
41void lld::unlinkAsync(StringRef path) {
42// Removing a file is async on windows.
43#if defined(_WIN32)
44 sys::fs::remove(path);
45#else
46 if (!threadsEnabled || !sys::fs::exists(path) ||
47 !sys::fs::is_regular_file(path))
48 return;
49
50 // We cannot just remove path from a different thread because we are now going
51 // to create path as a new file.
52 // Instead we open the file and unlink it on this thread. The unlink is fast
53 // since the open fd guarantees that it is not removing the last reference.
54 int fd;
55 std::error_code ec = sys::fs::openFileForRead(path, fd);
56 sys::fs::remove(path);
57
58 if (ec)
59 return;
60
61 // close and therefore remove TempPath in background.
62 std::mutex m;
63 std::condition_variable cv;
64 bool started = false;
65 std::thread([&, fd] {
66 {
67 std::lock_guard<std::mutex> l(m);
68 started = true;
69 cv.notify_all();
70 }
71 ::close(fd);
72 }).detach();
73
74 // GLIBC 2.26 and earlier have race condition that crashes an entire process
75 // if the main thread calls exit(2) while other thread is starting up.
76 std::unique_lock<std::mutex> l(m);
77 cv.wait(l, [&] { return started; });
78#endif
79}
80
81// Simulate file creation to see if Path is writable.
82//
83// Determining whether a file is writable or not is amazingly hard,
84// and after all the only reliable way of doing that is to actually
85// create a file. But we don't want to do that in this function
86// because LLD shouldn't update any file if it will end in a failure.
87// We also don't want to reimplement heuristics to determine if a
88// file is writable. So we'll let FileOutputBuffer do the work.
89//
90// FileOutputBuffer doesn't touch a desitnation file until commit()
91// is called. We use that class without calling commit() to predict
92// if the given file is writable.
93std::error_code lld::tryCreateFile(StringRef path) {
94 if (path.empty())
95 return std::error_code();
96 if (path == "-")
97 return std::error_code();
98 return errorToErrorCode(FileOutputBuffer::create(path, 1).takeError());
99}
deps/lld/Common/Memory.cpp+9-10
......@@ -1,9 +1,8 @@
11//===- Memory.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -12,12 +11,12 @@
1211using namespace llvm;
1312using namespace lld;
1413
15BumpPtrAllocator lld::BAlloc;
16StringSaver lld::Saver{BAlloc};
17std::vector<SpecificAllocBase *> lld::SpecificAllocBase::Instances;
14BumpPtrAllocator lld::bAlloc;
15StringSaver lld::saver{bAlloc};
16std::vector<SpecificAllocBase *> lld::SpecificAllocBase::instances;
1817
1918void lld::freeArena() {
20 for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances)
21 Alloc->reset();
22 BAlloc.Reset();
19 for (SpecificAllocBase *alloc : SpecificAllocBase::instances)
20 alloc->reset();
21 bAlloc.Reset();
2322}
deps/lld/Common/Reproduce.cpp+31-36
......@@ -1,9 +1,8 @@
11//===- Reproduce.cpp - Utilities for creating reproducers -----------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -22,45 +21,41 @@ using namespace llvm::sys;
2221// assuming that the current directory is "/home/john/bar".
2322// Returned string is a forward slash separated path even on Windows to avoid
2423// a mess with backslash-as-escape and backslash-as-path-separator.
25std::string lld::relativeToRoot(StringRef Path) {
26 SmallString<128> Abs = Path;
27 if (fs::make_absolute(Abs))
28 return Path;
29 path::remove_dots(Abs, /*remove_dot_dot=*/true);
24std::string lld::relativeToRoot(StringRef path) {
25 SmallString<128> abs = path;
26 if (fs::make_absolute(abs))
27 return path;
28 path::remove_dots(abs, /*remove_dot_dot=*/true);
3029
3130 // This is Windows specific. root_name() returns a drive letter
3231 // (e.g. "c:") or a UNC name (//net). We want to keep it as part
3332 // of the result.
34 SmallString<128> Res;
35 StringRef Root = path::root_name(Abs);
36 if (Root.endswith(":"))
37 Res = Root.drop_back();
38 else if (Root.startswith("//"))
39 Res = Root.substr(2);
40
41 path::append(Res, path::relative_path(Abs));
42 return path::convert_to_slash(Res);
33 SmallString<128> res;
34 StringRef root = path::root_name(abs);
35 if (root.endswith(":"))
36 res = root.drop_back();
37 else if (root.startswith("//"))
38 res = root.substr(2);
39
40 path::append(res, path::relative_path(abs));
41 return path::convert_to_slash(res);
4342}
4443
4544// Quote a given string if it contains a space character.
46std::string lld::quote(StringRef S) {
47 if (S.contains(' '))
48 return ("\"" + S + "\"").str();
49 return S;
50}
51
52std::string lld::rewritePath(StringRef S) {
53 if (fs::exists(S))
54 return relativeToRoot(S);
55 return S;
45std::string lld::quote(StringRef s) {
46 if (s.contains(' '))
47 return ("\"" + s + "\"").str();
48 return s;
5649}
5750
58std::string lld::toString(const opt::Arg &Arg) {
59 std::string K = Arg.getSpelling();
60 if (Arg.getNumValues() == 0)
61 return K;
62 std::string V = quote(Arg.getValue());
63 if (Arg.getOption().getRenderStyle() == opt::Option::RenderJoinedStyle)
64 return K + V;
65 return K + " " + V;
51// Converts an Arg to a string representation suitable for a response file.
52// To show an Arg in a diagnostic, use Arg::getAsString() instead.
53std::string lld::toString(const opt::Arg &arg) {
54 std::string k = arg.getSpelling();
55 if (arg.getNumValues() == 0)
56 return k;
57 std::string v = quote(arg.getValue());
58 if (arg.getOption().getRenderStyle() == opt::Option::RenderJoinedStyle)
59 return k + v;
60 return k + " " + v;
6661}
deps/lld/Common/Strings.cpp+49-50
......@@ -1,9 +1,8 @@
11//===- Strings.cpp -------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -20,85 +19,85 @@ using namespace llvm;
2019using namespace lld;
2120
2221// Returns the demangled C++ symbol name for Name.
23Optional<std::string> lld::demangleItanium(StringRef Name) {
22Optional<std::string> lld::demangleItanium(StringRef name) {
2423 // itaniumDemangle can be used to demangle strings other than symbol
2524 // names which do not necessarily start with "_Z". Name can be
2625 // either a C or C++ symbol. Don't call itaniumDemangle if the name
2726 // does not look like a C++ symbol name to avoid getting unexpected
2827 // result for a C symbol that happens to match a mangled type name.
29 if (!Name.startswith("_Z"))
28 if (!name.startswith("_Z"))
3029 return None;
3130
32 char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr);
33 if (!Buf)
31 char *buf = itaniumDemangle(name.str().c_str(), nullptr, nullptr, nullptr);
32 if (!buf)
3433 return None;
35 std::string S(Buf);
36 free(Buf);
37 return S;
34 std::string s(buf);
35 free(buf);
36 return s;
3837}
3938
40Optional<std::string> lld::demangleMSVC(StringRef Name) {
41 std::string Prefix;
42 if (Name.consume_front("__imp_"))
43 Prefix = "__declspec(dllimport) ";
39Optional<std::string> lld::demangleMSVC(StringRef name) {
40 std::string prefix;
41 if (name.consume_front("__imp_"))
42 prefix = "__declspec(dllimport) ";
4443
4544 // Demangle only C++ names.
46 if (!Name.startswith("?"))
45 if (!name.startswith("?"))
4746 return None;
4847
49 char *Buf = microsoftDemangle(Name.str().c_str(), nullptr, nullptr, nullptr);
50 if (!Buf)
48 char *buf = microsoftDemangle(name.str().c_str(), nullptr, nullptr, nullptr);
49 if (!buf)
5150 return None;
52 std::string S(Buf);
53 free(Buf);
54 return Prefix + S;
51 std::string s(buf);
52 free(buf);
53 return prefix + s;
5554}
5655
57StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) {
58 for (StringRef S : Pat) {
59 Expected<GlobPattern> Pat = GlobPattern::create(S);
60 if (!Pat)
61 error(toString(Pat.takeError()));
56StringMatcher::StringMatcher(ArrayRef<StringRef> pat) {
57 for (StringRef s : pat) {
58 Expected<GlobPattern> pat = GlobPattern::create(s);
59 if (!pat)
60 error(toString(pat.takeError()));
6261 else
63 Patterns.push_back(*Pat);
62 patterns.push_back(*pat);
6463 }
6564}
6665
67bool StringMatcher::match(StringRef S) const {
68 for (const GlobPattern &Pat : Patterns)
69 if (Pat.match(S))
66bool StringMatcher::match(StringRef s) const {
67 for (const GlobPattern &pat : patterns)
68 if (pat.match(s))
7069 return true;
7170 return false;
7271}
7372
7473// Converts a hex string (e.g. "deadbeef") to a vector.
75std::vector<uint8_t> lld::parseHex(StringRef S) {
76 std::vector<uint8_t> Hex;
77 while (!S.empty()) {
78 StringRef B = S.substr(0, 2);
79 S = S.substr(2);
80 uint8_t H;
81 if (!to_integer(B, H, 16)) {
82 error("not a hexadecimal value: " + B);
74std::vector<uint8_t> lld::parseHex(StringRef s) {
75 std::vector<uint8_t> hex;
76 while (!s.empty()) {
77 StringRef b = s.substr(0, 2);
78 s = s.substr(2);
79 uint8_t h;
80 if (!to_integer(b, h, 16)) {
81 error("not a hexadecimal value: " + b);
8382 return {};
8483 }
85 Hex.push_back(H);
84 hex.push_back(h);
8685 }
87 return Hex;
86 return hex;
8887}
8988
9089// Returns true if S is valid as a C language identifier.
91bool lld::isValidCIdentifier(StringRef S) {
92 return !S.empty() && (isAlpha(S[0]) || S[0] == '_') &&
93 std::all_of(S.begin() + 1, S.end(),
94 [](char C) { return C == '_' || isAlnum(C); });
90bool lld::isValidCIdentifier(StringRef s) {
91 return !s.empty() && (isAlpha(s[0]) || s[0] == '_') &&
92 std::all_of(s.begin() + 1, s.end(),
93 [](char c) { return c == '_' || isAlnum(c); });
9594}
9695
9796// Write the contents of the a buffer to a file
98void lld::saveBuffer(StringRef Buffer, const Twine &Path) {
99 std::error_code EC;
100 raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
101 if (EC)
102 error("cannot create " + Path + ": " + EC.message());
103 OS << Buffer;
97void lld::saveBuffer(StringRef buffer, const Twine &path) {
98 std::error_code ec;
99 raw_fd_ostream os(path.str(), ec, sys::fs::OpenFlags::F_None);
100 if (ec)
101 error("cannot create " + path + ": " + ec.message());
102 os << buffer;
104103}
deps/lld/Common/TargetOptionsCommandFlags.cpp+9-9
......@@ -1,9 +1,8 @@
11//===-- TargetOptionsCommandFlags.cpp ---------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -20,16 +19,17 @@
2019#include "llvm/Target/TargetOptions.h"
2120
2221// Define an externally visible version of
23// InitTargetOptionsFromCodeGenFlags, so that its functionality can be
22// initTargetOptionsFromCodeGenFlags, so that its functionality can be
2423// used without having to include llvm/CodeGen/CommandFlags.inc, which
2524// would lead to multiple definitions of the command line flags.
26llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() {
25llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() {
2726 return ::InitTargetOptionsFromCodeGenFlags();
2827}
2928
30llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() {
29llvm::Optional<llvm::CodeModel::Model> lld::getCodeModelFromCMModel() {
3130 return getCodeModel();
3231}
3332
34std::string lld::GetCPUStr() { return ::getCPUStr(); }
35std::vector<std::string> lld::GetMAttrs() { return ::MAttrs; }
33std::string lld::getCPUStr() { return ::getCPUStr(); }
34
35std::vector<std::string> lld::getMAttrs() { return ::MAttrs; }
deps/lld/Common/Threads.cpp+4-5
......@@ -1,12 +1,11 @@
11//===- Threads.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
109#include "lld/Common/Threads.h"
1110
12bool lld::ThreadsEnabled = true;
11bool lld::threadsEnabled = true;
deps/lld/Common/Timer.cpp+30-31
......@@ -1,9 +1,8 @@
11//===- Timer.cpp ----------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -14,43 +13,43 @@
1413using namespace lld;
1514using namespace llvm;
1615
17ScopedTimer::ScopedTimer(Timer &T) : T(&T) { T.start(); }
16ScopedTimer::ScopedTimer(Timer &t) : t(&t) { t.start(); }
1817
1918void ScopedTimer::stop() {
20 if (!T)
19 if (!t)
2120 return;
22 T->stop();
23 T = nullptr;
21 t->stop();
22 t = nullptr;
2423}
2524
2625ScopedTimer::~ScopedTimer() { stop(); }
2726
28Timer::Timer(llvm::StringRef Name) : Name(Name), Parent(nullptr) {}
29Timer::Timer(llvm::StringRef Name, Timer &Parent)
30 : Name(Name), Parent(&Parent) {}
27Timer::Timer(llvm::StringRef name) : name(name), parent(nullptr) {}
28Timer::Timer(llvm::StringRef name, Timer &parent)
29 : name(name), parent(&parent) {}
3130
3231void Timer::start() {
33 if (Parent && Total.count() == 0)
34 Parent->Children.push_back(this);
35 StartTime = std::chrono::high_resolution_clock::now();
32 if (parent && total.count() == 0)
33 parent->children.push_back(this);
34 startTime = std::chrono::high_resolution_clock::now();
3635}
3736
3837void Timer::stop() {
39 Total += (std::chrono::high_resolution_clock::now() - StartTime);
38 total += (std::chrono::high_resolution_clock::now() - startTime);
4039}
4140
4241Timer &Timer::root() {
43 static Timer RootTimer("Total Link Time");
44 return RootTimer;
42 static Timer rootTimer("Total Link Time");
43 return rootTimer;
4544}
4645
4746void Timer::print() {
48 double TotalDuration = static_cast<double>(root().millis());
47 double totalDuration = static_cast<double>(root().millis());
4948
5049 // We want to print the grand total under all the intermediate phases, so we
5150 // print all children first, then print the total under that.
52 for (const auto &Child : Children)
53 Child->print(1, TotalDuration);
51 for (const auto &child : children)
52 child->print(1, totalDuration);
5453
5554 message(std::string(49, '-'));
5655
......@@ -59,22 +58,22 @@ void Timer::print() {
5958
6059double Timer::millis() const {
6160 return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
62 Total)
61 total)
6362 .count();
6463}
6564
66void Timer::print(int Depth, double TotalDuration, bool Recurse) const {
67 double P = 100.0 * millis() / TotalDuration;
65void Timer::print(int depth, double totalDuration, bool recurse) const {
66 double p = 100.0 * millis() / totalDuration;
6867
69 SmallString<32> Str;
70 llvm::raw_svector_ostream Stream(Str);
71 std::string S = std::string(Depth * 2, ' ') + Name + std::string(":");
72 Stream << format("%-30s%5d ms (%5.1f%%)", S.c_str(), (int)millis(), P);
68 SmallString<32> str;
69 llvm::raw_svector_ostream stream(str);
70 std::string s = std::string(depth * 2, ' ') + name + std::string(":");
71 stream << format("%-30s%5d ms (%5.1f%%)", s.c_str(), (int)millis(), p);
7372
74 message(Str);
73 message(str);
7574
76 if (Recurse) {
77 for (const auto &Child : Children)
78 Child->print(Depth + 1, TotalDuration);
75 if (recurse) {
76 for (const auto &child : children)
77 child->print(depth + 1, totalDuration);
7978 }
8079}
deps/lld/Common/Version.cpp+13-29
......@@ -1,9 +1,8 @@
11//===- lib/Common/Version.cpp - LLD Version Number ---------------*- C++-=====//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -13,31 +12,16 @@
1312
1413#include "lld/Common/Version.h"
1514
16using namespace llvm;
17
18// Returns an SVN repository path, which is usually "trunk".
19static std::string getRepositoryPath() {
20 StringRef S = LLD_REPOSITORY_STRING;
21 size_t Pos = S.find("lld/");
22 if (Pos != StringRef::npos)
23 return S.substr(Pos + 4);
24 return S;
25}
26
27// Returns an SVN repository name, e.g., " (trunk 284614)"
28// or an empty string if no repository info is available.
29static std::string getRepository() {
30 std::string Repo = getRepositoryPath();
31 std::string Rev = LLD_REVISION_STRING;
32
33 if (Repo.empty() && Rev.empty())
34 return "";
35 if (!Repo.empty() && !Rev.empty())
36 return " (" + Repo + " " + Rev + ")";
37 return " (" + Repo + Rev + ")";
38}
15#ifdef HAVE_VCS_VERSION_INC
16#include "VCSVersion.inc"
17#endif
3918
40// Returns a version string, e.g., "LLD 4.0 (lld/trunk 284614)".
19// Returns a version string, e.g.:
20// lld 9.0.0 (https://github.com/llvm/llvm-project.git 9efdd7ac5e914d3c9fa1ef)
4121std::string lld::getLLDVersion() {
42 return "LLD " + std::string(LLD_VERSION_STRING) + getRepository();
22#if defined(LLD_REPOSITORY) && defined(LLD_REVISION)
23 return "LLD " LLD_VERSION_STRING " (" LLD_REPOSITORY " " LLD_REVISION ")";
24#else
25 return "LLD " LLD_VERSION_STRING;
26#endif
4327}
deps/lld/ELF/AArch64ErrataFix.cpp+247-248
......@@ -1,9 +1,8 @@
11//===- AArch64ErrataFix.cpp -----------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98// This file implements Section Patching for the purpose of working around
......@@ -57,8 +56,8 @@ using namespace lld::elf;
5756
5857// ADRP
5958// | 1 | immlo (2) | 1 | 0 0 0 0 | immhi (19) | Rd (5) |
60static bool isADRP(uint32_t Instr) {
61 return (Instr & 0x9f000000) == 0x90000000;
59static bool isADRP(uint32_t instr) {
60 return (instr & 0x9f000000) == 0x90000000;
6261}
6362
6463// Load and store bit patterns from ARMv8-A ARM ARM.
......@@ -67,8 +66,8 @@ static bool isADRP(uint32_t Instr) {
6766
6867// All loads and stores have 1 (at bit postion 27), (0 at bit position 25).
6968// | op0 x op1 (2) | 1 op2 0 op3 (2) | x | op4 (5) | xxxx | op5 (2) | x (10) |
70static bool isLoadStoreClass(uint32_t Instr) {
71 return (Instr & 0x0a000000) == 0x08000000;
69static bool isLoadStoreClass(uint32_t instr) {
70 return (instr & 0x0a000000) == 0x08000000;
7271}
7372
7473// LDN/STN multiple no offset
......@@ -83,20 +82,20 @@ static bool isLoadStoreClass(uint32_t Instr) {
8382// opcode == 0110 ST1 3 registers.
8483// opcode == 0111 ST1 1 register.
8584// opcode == 1010 ST1 2 registers.
86static bool isST1MultipleOpcode(uint32_t Instr) {
87 return (Instr & 0x0000f000) == 0x00002000 ||
88 (Instr & 0x0000f000) == 0x00006000 ||
89 (Instr & 0x0000f000) == 0x00007000 ||
90 (Instr & 0x0000f000) == 0x0000a000;
85static bool isST1MultipleOpcode(uint32_t instr) {
86 return (instr & 0x0000f000) == 0x00002000 ||
87 (instr & 0x0000f000) == 0x00006000 ||
88 (instr & 0x0000f000) == 0x00007000 ||
89 (instr & 0x0000f000) == 0x0000a000;
9190}
9291
93static bool isST1Multiple(uint32_t Instr) {
94 return (Instr & 0xbfff0000) == 0x0c000000 && isST1MultipleOpcode(Instr);
92static bool isST1Multiple(uint32_t instr) {
93 return (instr & 0xbfff0000) == 0x0c000000 && isST1MultipleOpcode(instr);
9594}
9695
9796// Writes to Rn (writeback).
98static bool isST1MultiplePost(uint32_t Instr) {
99 return (Instr & 0xbfe00000) == 0x0c800000 && isST1MultipleOpcode(Instr);
97static bool isST1MultiplePost(uint32_t instr) {
98 return (instr & 0xbfe00000) == 0x0c800000 && isST1MultipleOpcode(instr);
10099}
101100
102101// LDN/STN single no offset
......@@ -111,41 +110,41 @@ static bool isST1MultiplePost(uint32_t Instr) {
111110// opcode == 000 ST1 8-bit.
112111// opcode == 010 ST1 16-bit.
113112// opcode == 100 ST1 32 or 64-bit (Size determines which).
114static bool isST1SingleOpcode(uint32_t Instr) {
115 return (Instr & 0x0040e000) == 0x00000000 ||
116 (Instr & 0x0040e000) == 0x00004000 ||
117 (Instr & 0x0040e000) == 0x00008000;
113static bool isST1SingleOpcode(uint32_t instr) {
114 return (instr & 0x0040e000) == 0x00000000 ||
115 (instr & 0x0040e000) == 0x00004000 ||
116 (instr & 0x0040e000) == 0x00008000;
118117}
119118
120static bool isST1Single(uint32_t Instr) {
121 return (Instr & 0xbfff0000) == 0x0d000000 && isST1SingleOpcode(Instr);
119static bool isST1Single(uint32_t instr) {
120 return (instr & 0xbfff0000) == 0x0d000000 && isST1SingleOpcode(instr);
122121}
123122
124123// Writes to Rn (writeback).
125static bool isST1SinglePost(uint32_t Instr) {
126 return (Instr & 0xbfe00000) == 0x0d800000 && isST1SingleOpcode(Instr);
124static bool isST1SinglePost(uint32_t instr) {
125 return (instr & 0xbfe00000) == 0x0d800000 && isST1SingleOpcode(instr);
127126}
128127
129static bool isST1(uint32_t Instr) {
130 return isST1Multiple(Instr) || isST1MultiplePost(Instr) ||
131 isST1Single(Instr) || isST1SinglePost(Instr);
128static bool isST1(uint32_t instr) {
129 return isST1Multiple(instr) || isST1MultiplePost(instr) ||
130 isST1Single(instr) || isST1SinglePost(instr);
132131}
133132
134133// Load/store exclusive
135134// | size (2) 00 | 1000 | o2 L o1 | Rs (5) | o0 | Rt2 (5) | Rn (5) | Rt (5) |
136135// L == 0 for Stores.
137static bool isLoadStoreExclusive(uint32_t Instr) {
138 return (Instr & 0x3f000000) == 0x08000000;
136static bool isLoadStoreExclusive(uint32_t instr) {
137 return (instr & 0x3f000000) == 0x08000000;
139138}
140139
141static bool isLoadExclusive(uint32_t Instr) {
142 return (Instr & 0x3f400000) == 0x08400000;
140static bool isLoadExclusive(uint32_t instr) {
141 return (instr & 0x3f400000) == 0x08400000;
143142}
144143
145144// Load register literal
146145// | opc (2) 01 | 1 V 00 | imm19 | Rt (5) |
147static bool isLoadLiteral(uint32_t Instr) {
148 return (Instr & 0x3b000000) == 0x18000000;
146static bool isLoadLiteral(uint32_t instr) {
147 return (instr & 0x3b000000) == 0x18000000;
149148}
150149
151150// Load/store no-allocate pair
......@@ -153,8 +152,8 @@ static bool isLoadLiteral(uint32_t Instr) {
153152// | opc (2) 10 | 1 V 00 | 0 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
154153// L == 0 for stores.
155154// Never writes to register
156static bool isSTNP(uint32_t Instr) {
157 return (Instr & 0x3bc00000) == 0x28000000;
155static bool isSTNP(uint32_t instr) {
156 return (instr & 0x3bc00000) == 0x28000000;
158157}
159158
160159// Load/store register pair
......@@ -162,69 +161,69 @@ static bool isSTNP(uint32_t Instr) {
162161// | opc (2) 10 | 1 V 00 | 1 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
163162// L == 0 for stores, V == 0 for Scalar, V == 1 for Simd/FP
164163// Writes to Rn.
165static bool isSTPPost(uint32_t Instr) {
166 return (Instr & 0x3bc00000) == 0x28800000;
164static bool isSTPPost(uint32_t instr) {
165 return (instr & 0x3bc00000) == 0x28800000;
167166}
168167
169168// (offset)
170169// | opc (2) 10 | 1 V 01 | 0 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
171static bool isSTPOffset(uint32_t Instr) {
172 return (Instr & 0x3bc00000) == 0x29000000;
170static bool isSTPOffset(uint32_t instr) {
171 return (instr & 0x3bc00000) == 0x29000000;
173172}
174173
175174// (pre-index)
176175// | opc (2) 10 | 1 V 01 | 1 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
177176// Writes to Rn.
178static bool isSTPPre(uint32_t Instr) {
179 return (Instr & 0x3bc00000) == 0x29800000;
177static bool isSTPPre(uint32_t instr) {
178 return (instr & 0x3bc00000) == 0x29800000;
180179}
181180
182static bool isSTP(uint32_t Instr) {
183 return isSTPPost(Instr) || isSTPOffset(Instr) || isSTPPre(Instr);
181static bool isSTP(uint32_t instr) {
182 return isSTPPost(instr) || isSTPOffset(instr) || isSTPPre(instr);
184183}
185184
186185// Load/store register (unscaled immediate)
187186// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 00 | Rn (5) | Rt (5) |
188187// V == 0 for Scalar, V == 1 for Simd/FP.
189static bool isLoadStoreUnscaled(uint32_t Instr) {
190 return (Instr & 0x3b000c00) == 0x38000000;
188static bool isLoadStoreUnscaled(uint32_t instr) {
189 return (instr & 0x3b000c00) == 0x38000000;
191190}
192191
193192// Load/store register (immediate post-indexed)
194193// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 01 | Rn (5) | Rt (5) |
195static bool isLoadStoreImmediatePost(uint32_t Instr) {
196 return (Instr & 0x3b200c00) == 0x38000400;
194static bool isLoadStoreImmediatePost(uint32_t instr) {
195 return (instr & 0x3b200c00) == 0x38000400;
197196}
198197
199198// Load/store register (unprivileged)
200199// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 10 | Rn (5) | Rt (5) |
201static bool isLoadStoreUnpriv(uint32_t Instr) {
202 return (Instr & 0x3b200c00) == 0x38000800;
200static bool isLoadStoreUnpriv(uint32_t instr) {
201 return (instr & 0x3b200c00) == 0x38000800;
203202}
204203
205204// Load/store register (immediate pre-indexed)
206205// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 11 | Rn (5) | Rt (5) |
207static bool isLoadStoreImmediatePre(uint32_t Instr) {
208 return (Instr & 0x3b200c00) == 0x38000c00;
206static bool isLoadStoreImmediatePre(uint32_t instr) {
207 return (instr & 0x3b200c00) == 0x38000c00;
209208}
210209
211210// Load/store register (register offset)
212211// | size (2) 11 | 1 V 00 | opc (2) 1 | Rm (5) | option (3) S | 10 | Rn | Rt |
213static bool isLoadStoreRegisterOff(uint32_t Instr) {
214 return (Instr & 0x3b200c00) == 0x38200800;
212static bool isLoadStoreRegisterOff(uint32_t instr) {
213 return (instr & 0x3b200c00) == 0x38200800;
215214}
216215
217216// Load/store register (unsigned immediate)
218217// | size (2) 11 | 1 V 01 | opc (2) | imm12 | Rn (5) | Rt (5) |
219static bool isLoadStoreRegisterUnsigned(uint32_t Instr) {
220 return (Instr & 0x3b000000) == 0x39000000;
218static bool isLoadStoreRegisterUnsigned(uint32_t instr) {
219 return (instr & 0x3b000000) == 0x39000000;
221220}
222221
223222// Rt is always in bit position 0 - 4.
224static uint32_t getRt(uint32_t Instr) { return (Instr & 0x1f); }
223static uint32_t getRt(uint32_t instr) { return (instr & 0x1f); }
225224
226225// Rn is always in bit position 5 - 9.
227static uint32_t getRn(uint32_t Instr) { return (Instr >> 5) & 0x1f; }
226static uint32_t getRn(uint32_t instr) { return (instr >> 5) & 0x1f; }
228227
229228// C4.1.2 Branches, Exception Generating and System instructions
230229// | op0 (3) 1 | 01 op1 (4) | x (22) |
......@@ -233,41 +232,41 @@ static uint32_t getRn(uint32_t Instr) { return (Instr >> 5) & 0x1f; }
233232// op0 == x00 101 op1 == xxxx Unconditional Branch immediate.
234233// op0 == x01 101 op1 == 0xxx Compare and branch immediate.
235234// op0 == x01 101 op1 == 1xxx Test and branch immediate.
236static bool isBranch(uint32_t Instr) {
237 return ((Instr & 0xfe000000) == 0xd6000000) || // Cond branch.
238 ((Instr & 0xfe000000) == 0x54000000) || // Uncond branch reg.
239 ((Instr & 0x7c000000) == 0x14000000) || // Uncond branch imm.
240 ((Instr & 0x7c000000) == 0x34000000); // Compare and test branch.
235static bool isBranch(uint32_t instr) {
236 return ((instr & 0xfe000000) == 0xd6000000) || // Cond branch.
237 ((instr & 0xfe000000) == 0x54000000) || // Uncond branch reg.
238 ((instr & 0x7c000000) == 0x14000000) || // Uncond branch imm.
239 ((instr & 0x7c000000) == 0x34000000); // Compare and test branch.
241240}
242241
243static bool isV8SingleRegisterNonStructureLoadStore(uint32_t Instr) {
244 return isLoadStoreUnscaled(Instr) || isLoadStoreImmediatePost(Instr) ||
245 isLoadStoreUnpriv(Instr) || isLoadStoreImmediatePre(Instr) ||
246 isLoadStoreRegisterOff(Instr) || isLoadStoreRegisterUnsigned(Instr);
242static bool isV8SingleRegisterNonStructureLoadStore(uint32_t instr) {
243 return isLoadStoreUnscaled(instr) || isLoadStoreImmediatePost(instr) ||
244 isLoadStoreUnpriv(instr) || isLoadStoreImmediatePre(instr) ||
245 isLoadStoreRegisterOff(instr) || isLoadStoreRegisterUnsigned(instr);
247246}
248247
249248// Note that this function refers to v8.0 only and does not include the
250249// additional load and store instructions added for in later revisions of
251250// the architecture such as the Atomic memory operations introduced
252251// in v8.1.
253static bool isV8NonStructureLoad(uint32_t Instr) {
254 if (isLoadExclusive(Instr))
252static bool isV8NonStructureLoad(uint32_t instr) {
253 if (isLoadExclusive(instr))
255254 return true;
256 if (isLoadLiteral(Instr))
255 if (isLoadLiteral(instr))
257256 return true;
258 else if (isV8SingleRegisterNonStructureLoadStore(Instr)) {
257 else if (isV8SingleRegisterNonStructureLoadStore(instr)) {
259258 // For Load and Store single register, Loads are derived from a
260259 // combination of the Size, V and Opc fields.
261 uint32_t Size = (Instr >> 30) & 0xff;
262 uint32_t V = (Instr >> 26) & 0x1;
263 uint32_t Opc = (Instr >> 22) & 0x3;
260 uint32_t size = (instr >> 30) & 0xff;
261 uint32_t v = (instr >> 26) & 0x1;
262 uint32_t opc = (instr >> 22) & 0x3;
264263 // For the load and store instructions that we are decoding.
265264 // Opc == 0 are all stores.
266265 // Opc == 1 with a couple of exceptions are loads. The exceptions are:
267266 // Size == 00 (0), V == 1, Opc == 10 (2) which is a store and
268267 // Size == 11 (3), V == 0, Opc == 10 (2) which is a prefetch.
269 return Opc != 0 && !(Size == 0 && V == 1 && Opc == 2) &&
270 !(Size == 3 && V == 0 && Opc == 2);
268 return opc != 0 && !(size == 0 && v == 1 && opc == 2) &&
269 !(size == 3 && v == 0 && opc == 2);
271270 }
272271 return false;
273272}
......@@ -276,18 +275,18 @@ static bool isV8NonStructureLoad(uint32_t Instr) {
276275// needed for errata 843419.
277276
278277// Instruction with writeback updates the index register after the load/store.
279static bool hasWriteback(uint32_t Instr) {
280 return isLoadStoreImmediatePre(Instr) || isLoadStoreImmediatePost(Instr) ||
281 isSTPPre(Instr) || isSTPPost(Instr) || isST1SinglePost(Instr) ||
282 isST1MultiplePost(Instr);
278static bool hasWriteback(uint32_t instr) {
279 return isLoadStoreImmediatePre(instr) || isLoadStoreImmediatePost(instr) ||
280 isSTPPre(instr) || isSTPPost(instr) || isST1SinglePost(instr) ||
281 isST1MultiplePost(instr);
283282}
284283
285284// For the load and store class of instructions, a load can write to the
286285// destination register, a load and a store can write to the base register when
287286// the instruction has writeback.
288static bool doesLoadStoreWriteToReg(uint32_t Instr, uint32_t Reg) {
289 return (isV8NonStructureLoad(Instr) && getRt(Instr) == Reg) ||
290 (hasWriteback(Instr) && getRn(Instr) == Reg);
287static bool doesLoadStoreWriteToReg(uint32_t instr, uint32_t reg) {
288 return (isV8NonStructureLoad(instr) && getRt(instr) == reg) ||
289 (hasWriteback(instr) && getRn(instr) == reg);
291290}
292291
293292// Scanner for Cortex-A53 errata 843419
......@@ -319,18 +318,18 @@ static bool doesLoadStoreWriteToReg(uint32_t Instr, uint32_t Reg) {
319318// Return true if the Instruction sequence Adrp, Instr2, and Instr4 match
320319// the erratum sequence. The Adrp, Instr2 and Instr4 correspond to 1.), 2.),
321320// and 4.) in the Scanner for Cortex-A53 errata comment above.
322static bool is843419ErratumSequence(uint32_t Instr1, uint32_t Instr2,
323 uint32_t Instr4) {
324 if (!isADRP(Instr1))
321static bool is843419ErratumSequence(uint32_t instr1, uint32_t instr2,
322 uint32_t instr4) {
323 if (!isADRP(instr1))
325324 return false;
326325
327 uint32_t Rn = getRt(Instr1);
328 return isLoadStoreClass(Instr2) &&
329 (isLoadStoreExclusive(Instr2) || isLoadLiteral(Instr2) ||
330 isV8SingleRegisterNonStructureLoadStore(Instr2) || isSTP(Instr2) ||
331 isSTNP(Instr2) || isST1(Instr2)) &&
332 !doesLoadStoreWriteToReg(Instr2, Rn) &&
333 isLoadStoreRegisterUnsigned(Instr4) && getRn(Instr4) == Rn;
326 uint32_t rn = getRt(instr1);
327 return isLoadStoreClass(instr2) &&
328 (isLoadStoreExclusive(instr2) || isLoadLiteral(instr2) ||
329 isV8SingleRegisterNonStructureLoadStore(instr2) || isSTP(instr2) ||
330 isSTNP(instr2) || isST1(instr2)) &&
331 !doesLoadStoreWriteToReg(instr2, rn) &&
332 isLoadStoreRegisterUnsigned(instr4) && getRn(instr4) == rn;
334333}
335334
336335// Scan the instruction sequence starting at Offset Off from the base of
......@@ -339,143 +338,143 @@ static bool is843419ErratumSequence(uint32_t Instr1, uint32_t Instr2,
339338// instructions we've scanned.
340339// Return the offset of the load or store instruction in IS that we want to
341340// patch or 0 if no patch required.
342static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off,
343 uint64_t Limit) {
344 uint64_t ISAddr = IS->getVA(0);
341static uint64_t scanCortexA53Errata843419(InputSection *isec, uint64_t &off,
342 uint64_t limit) {
343 uint64_t isecAddr = isec->getVA(0);
345344
346345 // Advance Off so that (ISAddr + Off) modulo 0x1000 is at least 0xff8.
347 uint64_t InitialPageOff = (ISAddr + Off) & 0xfff;
348 if (InitialPageOff < 0xff8)
349 Off += 0xff8 - InitialPageOff;
346 uint64_t initialPageOff = (isecAddr + off) & 0xfff;
347 if (initialPageOff < 0xff8)
348 off += 0xff8 - initialPageOff;
350349
351 bool OptionalAllowed = Limit - Off > 12;
352 if (Off >= Limit || Limit - Off < 12) {
350 bool optionalAllowed = limit - off > 12;
351 if (off >= limit || limit - off < 12) {
353352 // Need at least 3 4-byte sized instructions to trigger erratum.
354 Off = Limit;
353 off = limit;
355354 return 0;
356355 }
357356
358 uint64_t PatchOff = 0;
359 const uint8_t *Buf = IS->data().begin();
360 const ulittle32_t *InstBuf = reinterpret_cast<const ulittle32_t *>(Buf + Off);
361 uint32_t Instr1 = *InstBuf++;
362 uint32_t Instr2 = *InstBuf++;
363 uint32_t Instr3 = *InstBuf++;
364 if (is843419ErratumSequence(Instr1, Instr2, Instr3)) {
365 PatchOff = Off + 8;
366 } else if (OptionalAllowed && !isBranch(Instr3)) {
367 uint32_t Instr4 = *InstBuf++;
368 if (is843419ErratumSequence(Instr1, Instr2, Instr4))
369 PatchOff = Off + 12;
357 uint64_t patchOff = 0;
358 const uint8_t *buf = isec->data().begin();
359 const ulittle32_t *instBuf = reinterpret_cast<const ulittle32_t *>(buf + off);
360 uint32_t instr1 = *instBuf++;
361 uint32_t instr2 = *instBuf++;
362 uint32_t instr3 = *instBuf++;
363 if (is843419ErratumSequence(instr1, instr2, instr3)) {
364 patchOff = off + 8;
365 } else if (optionalAllowed && !isBranch(instr3)) {
366 uint32_t instr4 = *instBuf++;
367 if (is843419ErratumSequence(instr1, instr2, instr4))
368 patchOff = off + 12;
370369 }
371 if (((ISAddr + Off) & 0xfff) == 0xff8)
372 Off += 4;
370 if (((isecAddr + off) & 0xfff) == 0xff8)
371 off += 4;
373372 else
374 Off += 0xffc;
375 return PatchOff;
373 off += 0xffc;
374 return patchOff;
376375}
377376
378377class lld::elf::Patch843419Section : public SyntheticSection {
379378public:
380 Patch843419Section(InputSection *P, uint64_t Off);
379 Patch843419Section(InputSection *p, uint64_t off);
381380
382 void writeTo(uint8_t *Buf) override;
381 void writeTo(uint8_t *buf) override;
383382
384383 size_t getSize() const override { return 8; }
385384
386385 uint64_t getLDSTAddr() const;
387386
388387 // The Section we are patching.
389 const InputSection *Patchee;
388 const InputSection *patchee;
390389 // The offset of the instruction in the Patchee section we are patching.
391 uint64_t PatcheeOffset;
390 uint64_t patcheeOffset;
392391 // A label for the start of the Patch that we can use as a relocation target.
393 Symbol *PatchSym;
392 Symbol *patchSym;
394393};
395394
396lld::elf::Patch843419Section::Patch843419Section(InputSection *P, uint64_t Off)
395lld::elf::Patch843419Section::Patch843419Section(InputSection *p, uint64_t off)
397396 : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 4,
398397 ".text.patch"),
399 Patchee(P), PatcheeOffset(Off) {
400 this->Parent = P->getParent();
401 PatchSym = addSyntheticLocal(
402 Saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0,
398 patchee(p), patcheeOffset(off) {
399 this->parent = p->getParent();
400 patchSym = addSyntheticLocal(
401 saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0,
403402 getSize(), *this);
404 addSyntheticLocal(Saver.save("$x"), STT_NOTYPE, 0, 0, *this);
403 addSyntheticLocal(saver.save("$x"), STT_NOTYPE, 0, 0, *this);
405404}
406405
407406uint64_t lld::elf::Patch843419Section::getLDSTAddr() const {
408 return Patchee->getVA(PatcheeOffset);
407 return patchee->getVA(patcheeOffset);
409408}
410409
411void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) {
410void lld::elf::Patch843419Section::writeTo(uint8_t *buf) {
412411 // Copy the instruction that we will be replacing with a branch in the
413412 // Patchee Section.
414 write32le(Buf, read32le(Patchee->data().begin() + PatcheeOffset));
413 write32le(buf, read32le(patchee->data().begin() + patcheeOffset));
415414
416415 // Apply any relocation transferred from the original PatcheeSection.
417 // For a SyntheticSection Buf already has OutSecOff added, but relocateAlloc
418 // also adds OutSecOff so we need to subtract to avoid double counting.
419 this->relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + getSize());
416 // For a SyntheticSection Buf already has outSecOff added, but relocateAlloc
417 // also adds outSecOff so we need to subtract to avoid double counting.
418 this->relocateAlloc(buf - outSecOff, buf - outSecOff + getSize());
420419
421420 // Return address is the next instruction after the one we have just copied.
422 uint64_t S = getLDSTAddr() + 4;
423 uint64_t P = PatchSym->getVA() + 4;
424 Target->relocateOne(Buf + 4, R_AARCH64_JUMP26, S - P);
421 uint64_t s = getLDSTAddr() + 4;
422 uint64_t p = patchSym->getVA() + 4;
423 target->relocateOne(buf + 4, R_AARCH64_JUMP26, s - p);
425424}
426425
427426void AArch64Err843419Patcher::init() {
428427 // The AArch64 ABI permits data in executable sections. We must avoid scanning
429428 // this data as if it were instructions to avoid false matches. We use the
430429 // mapping symbols in the InputObjects to identify this data, caching the
431 // results in SectionMap so we don't have to recalculate it each pass.
430 // results in sectionMap so we don't have to recalculate it each pass.
432431
433432 // The ABI Section 4.5.4 Mapping symbols; defines local symbols that describe
434433 // half open intervals [Symbol Value, Next Symbol Value) of code and data
435434 // within sections. If there is no next symbol then the half open interval is
436435 // [Symbol Value, End of section). The type, code or data, is determined by
437436 // the mapping symbol name, $x for code, $d for data.
438 auto IsCodeMapSymbol = [](const Symbol *B) {
439 return B->getName() == "$x" || B->getName().startswith("$x.");
437 auto isCodeMapSymbol = [](const Symbol *b) {
438 return b->getName() == "$x" || b->getName().startswith("$x.");
440439 };
441 auto IsDataMapSymbol = [](const Symbol *B) {
442 return B->getName() == "$d" || B->getName().startswith("$d.");
440 auto isDataMapSymbol = [](const Symbol *b) {
441 return b->getName() == "$d" || b->getName().startswith("$d.");
443442 };
444443
445444 // Collect mapping symbols for every executable InputSection.
446 for (InputFile *File : ObjectFiles) {
447 auto *F = cast<ObjFile<ELF64LE>>(File);
448 for (Symbol *B : F->getLocalSymbols()) {
449 auto *Def = dyn_cast<Defined>(B);
450 if (!Def)
445 for (InputFile *file : objectFiles) {
446 auto *f = cast<ObjFile<ELF64LE>>(file);
447 for (Symbol *b : f->getLocalSymbols()) {
448 auto *def = dyn_cast<Defined>(b);
449 if (!def)
451450 continue;
452 if (!IsCodeMapSymbol(Def) && !IsDataMapSymbol(Def))
451 if (!isCodeMapSymbol(def) && !isDataMapSymbol(def))
453452 continue;
454 if (auto *Sec = dyn_cast_or_null<InputSection>(Def->Section))
455 if (Sec->Flags & SHF_EXECINSTR)
456 SectionMap[Sec].push_back(Def);
453 if (auto *sec = dyn_cast_or_null<InputSection>(def->section))
454 if (sec->flags & SHF_EXECINSTR)
455 sectionMap[sec].push_back(def);
457456 }
458457 }
459458 // For each InputSection make sure the mapping symbols are in sorted in
460459 // ascending order and free from consecutive runs of mapping symbols with
461460 // the same type. For example we must remove the redundant $d.1 from $x.0
462461 // $d.0 $d.1 $x.1.
463 for (auto &KV : SectionMap) {
464 std::vector<const Defined *> &MapSyms = KV.second;
465 if (MapSyms.size() <= 1)
462 for (auto &kv : sectionMap) {
463 std::vector<const Defined *> &mapSyms = kv.second;
464 if (mapSyms.size() <= 1)
466465 continue;
467 std::stable_sort(
468 MapSyms.begin(), MapSyms.end(),
469 [](const Defined *A, const Defined *B) { return A->Value < B->Value; });
470 MapSyms.erase(
471 std::unique(MapSyms.begin(), MapSyms.end(),
472 [=](const Defined *A, const Defined *B) {
473 return (IsCodeMapSymbol(A) && IsCodeMapSymbol(B)) ||
474 (IsDataMapSymbol(A) && IsDataMapSymbol(B));
466 llvm::stable_sort(mapSyms, [](const Defined *a, const Defined *b) {
467 return a->value < b->value;
468 });
469 mapSyms.erase(
470 std::unique(mapSyms.begin(), mapSyms.end(),
471 [=](const Defined *a, const Defined *b) {
472 return (isCodeMapSymbol(a) && isCodeMapSymbol(b)) ||
473 (isDataMapSymbol(a) && isDataMapSymbol(b));
475474 }),
476 MapSyms.end());
475 mapSyms.end());
477476 }
478 Initialized = true;
477 initialized = true;
479478}
480479
481480// Insert the PatchSections we have created back into the
......@@ -484,60 +483,60 @@ void AArch64Err843419Patcher::init() {
484483// executable sections, although we may need to insert them earlier if the
485484// InputSectionDescription is larger than the maximum branch range.
486485void AArch64Err843419Patcher::insertPatches(
487 InputSectionDescription &ISD, std::vector<Patch843419Section *> &Patches) {
488 uint64_t ISLimit;
489 uint64_t PrevISLimit = ISD.Sections.front()->OutSecOff;
490 uint64_t PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
491 uint64_t OutSecAddr = ISD.Sections.front()->getParent()->Addr;
486 InputSectionDescription &isd, std::vector<Patch843419Section *> &patches) {
487 uint64_t isecLimit;
488 uint64_t prevIsecLimit = isd.sections.front()->outSecOff;
489 uint64_t patchUpperBound = prevIsecLimit + target->getThunkSectionSpacing();
490 uint64_t outSecAddr = isd.sections.front()->getParent()->addr;
492491
493 // Set the OutSecOff of patches to the place where we want to insert them.
492 // Set the outSecOff of patches to the place where we want to insert them.
494493 // We use a similar strategy to Thunk placement. Place patches roughly
495494 // every multiple of maximum branch range.
496 auto PatchIt = Patches.begin();
497 auto PatchEnd = Patches.end();
498 for (const InputSection *IS : ISD.Sections) {
499 ISLimit = IS->OutSecOff + IS->getSize();
500 if (ISLimit > PatchUpperBound) {
501 while (PatchIt != PatchEnd) {
502 if ((*PatchIt)->getLDSTAddr() - OutSecAddr >= PrevISLimit)
495 auto patchIt = patches.begin();
496 auto patchEnd = patches.end();
497 for (const InputSection *isec : isd.sections) {
498 isecLimit = isec->outSecOff + isec->getSize();
499 if (isecLimit > patchUpperBound) {
500 while (patchIt != patchEnd) {
501 if ((*patchIt)->getLDSTAddr() - outSecAddr >= prevIsecLimit)
503502 break;
504 (*PatchIt)->OutSecOff = PrevISLimit;
505 ++PatchIt;
503 (*patchIt)->outSecOff = prevIsecLimit;
504 ++patchIt;
506505 }
507 PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
506 patchUpperBound = prevIsecLimit + target->getThunkSectionSpacing();
508507 }
509 PrevISLimit = ISLimit;
508 prevIsecLimit = isecLimit;
510509 }
511 for (; PatchIt != PatchEnd; ++PatchIt) {
512 (*PatchIt)->OutSecOff = ISLimit;
510 for (; patchIt != patchEnd; ++patchIt) {
511 (*patchIt)->outSecOff = isecLimit;
513512 }
514513
515 // merge all patch sections. We use the OutSecOff assigned above to
514 // merge all patch sections. We use the outSecOff assigned above to
516515 // determine the insertion point. This is ok as we only merge into an
517516 // InputSectionDescription once per pass, and at the end of the pass
518 // assignAddresses() will recalculate all the OutSecOff values.
519 std::vector<InputSection *> Tmp;
520 Tmp.reserve(ISD.Sections.size() + Patches.size());
521 auto MergeCmp = [](const InputSection *A, const InputSection *B) {
522 if (A->OutSecOff < B->OutSecOff)
517 // assignAddresses() will recalculate all the outSecOff values.
518 std::vector<InputSection *> tmp;
519 tmp.reserve(isd.sections.size() + patches.size());
520 auto mergeCmp = [](const InputSection *a, const InputSection *b) {
521 if (a->outSecOff < b->outSecOff)
523522 return true;
524 if (A->OutSecOff == B->OutSecOff && isa<Patch843419Section>(A) &&
525 !isa<Patch843419Section>(B))
523 if (a->outSecOff == b->outSecOff && isa<Patch843419Section>(a) &&
524 !isa<Patch843419Section>(b))
526525 return true;
527526 return false;
528527 };
529 std::merge(ISD.Sections.begin(), ISD.Sections.end(), Patches.begin(),
530 Patches.end(), std::back_inserter(Tmp), MergeCmp);
531 ISD.Sections = std::move(Tmp);
528 std::merge(isd.sections.begin(), isd.sections.end(), patches.begin(),
529 patches.end(), std::back_inserter(tmp), mergeCmp);
530 isd.sections = std::move(tmp);
532531}
533532
534// Given an erratum sequence that starts at address AdrpAddr, with an
535// instruction that we need to patch at PatcheeOffset from the start of
533// Given an erratum sequence that starts at address adrpAddr, with an
534// instruction that we need to patch at patcheeOffset from the start of
536535// InputSection IS, create a Patch843419 Section and add it to the
537536// Patches that we need to insert.
538static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
539 InputSection *IS,
540 std::vector<Patch843419Section *> &Patches) {
537static void implementPatch(uint64_t adrpAddr, uint64_t patcheeOffset,
538 InputSection *isec,
539 std::vector<Patch843419Section *> &patches) {
541540 // There may be a relocation at the same offset that we are patching. There
542541 // are four cases that we need to consider.
543542 // Case 1: R_AARCH64_JUMP26 branch relocation. We have already patched this
......@@ -552,29 +551,29 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
552551 // and replace the relocation with a R_AARCH_JUMP26 branch relocation.
553552 // Case 4: No relocation. We must create a new R_AARCH64_JUMP26 branch
554553 // relocation at the offset.
555 auto RelIt = std::find_if(
556 IS->Relocations.begin(), IS->Relocations.end(),
557 [=](const Relocation &R) { return R.Offset == PatcheeOffset; });
558 if (RelIt != IS->Relocations.end() &&
559 (RelIt->Type == R_AARCH64_JUMP26 || RelIt->Expr == R_RELAX_TLS_IE_TO_LE))
554 auto relIt = llvm::find_if(isec->relocations, [=](const Relocation &r) {
555 return r.offset == patcheeOffset;
556 });
557 if (relIt != isec->relocations.end() &&
558 (relIt->type == R_AARCH64_JUMP26 || relIt->expr == R_RELAX_TLS_IE_TO_LE))
560559 return;
561560
562561 log("detected cortex-a53-843419 erratum sequence starting at " +
563 utohexstr(AdrpAddr) + " in unpatched output.");
562 utohexstr(adrpAddr) + " in unpatched output.");
564563
565 auto *PS = make<Patch843419Section>(IS, PatcheeOffset);
566 Patches.push_back(PS);
564 auto *ps = make<Patch843419Section>(isec, patcheeOffset);
565 patches.push_back(ps);
567566
568 auto MakeRelToPatch = [](uint64_t Offset, Symbol *PatchSym) {
569 return Relocation{R_PC, R_AARCH64_JUMP26, Offset, 0, PatchSym};
567 auto makeRelToPatch = [](uint64_t offset, Symbol *patchSym) {
568 return Relocation{R_PC, R_AARCH64_JUMP26, offset, 0, patchSym};
570569 };
571570
572 if (RelIt != IS->Relocations.end()) {
573 PS->Relocations.push_back(
574 {RelIt->Expr, RelIt->Type, 0, RelIt->Addend, RelIt->Sym});
575 *RelIt = MakeRelToPatch(PatcheeOffset, PS->PatchSym);
571 if (relIt != isec->relocations.end()) {
572 ps->relocations.push_back(
573 {relIt->expr, relIt->type, 0, relIt->addend, relIt->sym});
574 *relIt = makeRelToPatch(patcheeOffset, ps->patchSym);
576575 } else
577 IS->Relocations.push_back(MakeRelToPatch(PatcheeOffset, PS->PatchSym));
576 isec->relocations.push_back(makeRelToPatch(patcheeOffset, ps->patchSym));
578577}
579578
580579// Scan all the instructions in InputSectionDescription, for each instance of
......@@ -582,40 +581,40 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset,
582581// Patch843419Sections that need to be applied to ISD.
583582std::vector<Patch843419Section *>
584583AArch64Err843419Patcher::patchInputSectionDescription(
585 InputSectionDescription &ISD) {
586 std::vector<Patch843419Section *> Patches;
587 for (InputSection *IS : ISD.Sections) {
584 InputSectionDescription &isd) {
585 std::vector<Patch843419Section *> patches;
586 for (InputSection *isec : isd.sections) {
588587 // LLD doesn't use the erratum sequence in SyntheticSections.
589 if (isa<SyntheticSection>(IS))
588 if (isa<SyntheticSection>(isec))
590589 continue;
591 // Use SectionMap to make sure we only scan code and not inline data.
590 // Use sectionMap to make sure we only scan code and not inline data.
592591 // We have already sorted MapSyms in ascending order and removed consecutive
593592 // mapping symbols of the same type. Our range of executable instructions to
594 // scan is therefore [CodeSym->Value, DataSym->Value) or [CodeSym->Value,
593 // scan is therefore [codeSym->value, dataSym->value) or [codeSym->value,
595594 // section size).
596 std::vector<const Defined *> &MapSyms = SectionMap[IS];
595 std::vector<const Defined *> &mapSyms = sectionMap[isec];
597596
598 auto CodeSym = llvm::find_if(MapSyms, [&](const Defined *MS) {
599 return MS->getName().startswith("$x");
597 auto codeSym = llvm::find_if(mapSyms, [&](const Defined *ms) {
598 return ms->getName().startswith("$x");
600599 });
601600
602 while (CodeSym != MapSyms.end()) {
603 auto DataSym = std::next(CodeSym);
604 uint64_t Off = (*CodeSym)->Value;
605 uint64_t Limit =
606 (DataSym == MapSyms.end()) ? IS->data().size() : (*DataSym)->Value;
601 while (codeSym != mapSyms.end()) {
602 auto dataSym = std::next(codeSym);
603 uint64_t off = (*codeSym)->value;
604 uint64_t limit =
605 (dataSym == mapSyms.end()) ? isec->data().size() : (*dataSym)->value;
607606
608 while (Off < Limit) {
609 uint64_t StartAddr = IS->getVA(Off);
610 if (uint64_t PatcheeOffset = scanCortexA53Errata843419(IS, Off, Limit))
611 implementPatch(StartAddr, PatcheeOffset, IS, Patches);
607 while (off < limit) {
608 uint64_t startAddr = isec->getVA(off);
609 if (uint64_t patcheeOffset = scanCortexA53Errata843419(isec, off, limit))
610 implementPatch(startAddr, patcheeOffset, isec, patches);
612611 }
613 if (DataSym == MapSyms.end())
612 if (dataSym == mapSyms.end())
614613 break;
615 CodeSym = std::next(DataSym);
614 codeSym = std::next(dataSym);
616615 }
617616 }
618 return Patches;
617 return patches;
619618}
620619
621620// For each InputSectionDescription make one pass over the executable sections
......@@ -631,22 +630,22 @@ AArch64Err843419Patcher::patchInputSectionDescription(
631630// Ouptut and Input Sections may have been changed.
632631// Returns false if no patches were required and no changes were made.
633632bool AArch64Err843419Patcher::createFixes() {
634 if (Initialized == false)
633 if (initialized == false)
635634 init();
636635
637 bool AddressesChanged = false;
638 for (OutputSection *OS : OutputSections) {
639 if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
636 bool addressesChanged = false;
637 for (OutputSection *os : outputSections) {
638 if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR))
640639 continue;
641 for (BaseCommand *BC : OS->SectionCommands)
642 if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
643 std::vector<Patch843419Section *> Patches =
644 patchInputSectionDescription(*ISD);
645 if (!Patches.empty()) {
646 insertPatches(*ISD, Patches);
647 AddressesChanged = true;
640 for (BaseCommand *bc : os->sectionCommands)
641 if (auto *isd = dyn_cast<InputSectionDescription>(bc)) {
642 std::vector<Patch843419Section *> patches =
643 patchInputSectionDescription(*isd);
644 if (!patches.empty()) {
645 insertPatches(*isd, patches);
646 addressesChanged = true;
648647 }
649648 }
650649 }
651 return AddressesChanged;
650 return addressesChanged;
652651}
deps/lld/ELF/AArch64ErrataFix.h+9-10
......@@ -1,9 +1,8 @@
11//===- AArch64ErrataFix.h ---------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -30,19 +29,19 @@ public:
3029
3130private:
3231 std::vector<Patch843419Section *>
33 patchInputSectionDescription(InputSectionDescription &ISD);
32 patchInputSectionDescription(InputSectionDescription &isd);
3433
35 void insertPatches(InputSectionDescription &ISD,
36 std::vector<Patch843419Section *> &Patches);
34 void insertPatches(InputSectionDescription &isd,
35 std::vector<Patch843419Section *> &patches);
3736
3837 void init();
3938
40 // A cache of the mapping symbols defined by the InputSecion sorted in order
39 // A cache of the mapping symbols defined by the InputSection sorted in order
4140 // of ascending value with redundant symbols removed. These describe
4241 // the ranges of code and data in an executable InputSection.
43 std::map<InputSection *, std::vector<const Defined *>> SectionMap;
42 std::map<InputSection *, std::vector<const Defined *>> sectionMap;
4443
45 bool Initialized = false;
44 bool initialized = false;
4645};
4746
4847} // namespace elf
deps/lld/ELF/Arch/AArch64.cpp+308-158
......@@ -1,9 +1,8 @@
11//===- AArch64.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -24,60 +23,59 @@ using namespace lld::elf;
2423// Page(Expr) is the page address of the expression Expr, defined
2524// as (Expr & ~0xFFF). (This applies even if the machine page size
2625// supported by the platform has a different value.)
27uint64_t elf::getAArch64Page(uint64_t Expr) {
28 return Expr & ~static_cast<uint64_t>(0xFFF);
26uint64_t elf::getAArch64Page(uint64_t expr) {
27 return expr & ~static_cast<uint64_t>(0xFFF);
2928}
3029
3130namespace {
32class AArch64 final : public TargetInfo {
31class AArch64 : public TargetInfo {
3332public:
3433 AArch64();
35 RelExpr getRelExpr(RelType Type, const Symbol &S,
36 const uint8_t *Loc) const override;
37 RelType getDynRel(RelType Type) const override;
38 void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
39 void writePltHeader(uint8_t *Buf) const override;
40 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
41 int32_t Index, unsigned RelOff) const override;
42 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
43 uint64_t BranchAddr, const Symbol &S) const override;
34 RelExpr getRelExpr(RelType type, const Symbol &s,
35 const uint8_t *loc) const override;
36 RelType getDynRel(RelType type) const override;
37 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
38 void writePltHeader(uint8_t *buf) const override;
39 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
40 int32_t index, unsigned relOff) const override;
41 bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
42 uint64_t branchAddr, const Symbol &s) const override;
4443 uint32_t getThunkSectionSpacing() const override;
45 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
46 bool usesOnlyLowPageBits(RelType Type) const override;
47 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
48 RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
49 RelExpr Expr) const override;
50 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
51 void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
52 void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
44 bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
45 bool usesOnlyLowPageBits(RelType type) const override;
46 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
47 RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
48 RelExpr expr) const override;
49 void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
50 void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
51 void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
5352};
5453} // namespace
5554
5655AArch64::AArch64() {
57 CopyRel = R_AARCH64_COPY;
58 RelativeRel = R_AARCH64_RELATIVE;
59 IRelativeRel = R_AARCH64_IRELATIVE;
60 GotRel = R_AARCH64_GLOB_DAT;
61 NoneRel = R_AARCH64_NONE;
62 PltRel = R_AARCH64_JUMP_SLOT;
63 TlsDescRel = R_AARCH64_TLSDESC;
64 TlsGotRel = R_AARCH64_TLS_TPREL64;
65 GotEntrySize = 8;
66 GotPltEntrySize = 8;
67 PltEntrySize = 16;
68 PltHeaderSize = 32;
69 DefaultMaxPageSize = 65536;
56 copyRel = R_AARCH64_COPY;
57 relativeRel = R_AARCH64_RELATIVE;
58 iRelativeRel = R_AARCH64_IRELATIVE;
59 gotRel = R_AARCH64_GLOB_DAT;
60 noneRel = R_AARCH64_NONE;
61 pltRel = R_AARCH64_JUMP_SLOT;
62 symbolicRel = R_AARCH64_ABS64;
63 tlsDescRel = R_AARCH64_TLSDESC;
64 tlsGotRel = R_AARCH64_TLS_TPREL64;
65 pltEntrySize = 16;
66 pltHeaderSize = 32;
67 defaultMaxPageSize = 65536;
7068
7169 // Align to the 2 MiB page size (known as a superpage or huge page).
7270 // FreeBSD automatically promotes 2 MiB-aligned allocations.
73 DefaultImageBase = 0x200000;
71 defaultImageBase = 0x200000;
7472
75 NeedsThunks = true;
73 needsThunks = true;
7674}
7775
78RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
79 const uint8_t *Loc) const {
80 switch (Type) {
76RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
77 const uint8_t *loc) const {
78 switch (type) {
8179 case R_AARCH64_TLSDESC_ADR_PAGE21:
8280 return R_AARCH64_TLSDESC_PAGE;
8381 case R_AARCH64_TLSDESC_LD64_LO12:
......@@ -105,6 +103,7 @@ RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
105103 case R_AARCH64_LD_PREL_LO19:
106104 return R_PC;
107105 case R_AARCH64_ADR_PREL_PG_HI21:
106 case R_AARCH64_ADR_PREL_PG_HI21_NC:
108107 return R_AARCH64_PAGE_PC;
109108 case R_AARCH64_LD64_GOT_LO12_NC:
110109 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
......@@ -119,18 +118,18 @@ RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
119118 }
120119}
121120
122RelExpr AArch64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
123 RelExpr Expr) const {
124 if (Expr == R_RELAX_TLS_GD_TO_IE) {
125 if (Type == R_AARCH64_TLSDESC_ADR_PAGE21)
121RelExpr AArch64::adjustRelaxExpr(RelType type, const uint8_t *data,
122 RelExpr expr) const {
123 if (expr == R_RELAX_TLS_GD_TO_IE) {
124 if (type == R_AARCH64_TLSDESC_ADR_PAGE21)
126125 return R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC;
127126 return R_RELAX_TLS_GD_TO_IE_ABS;
128127 }
129 return Expr;
128 return expr;
130129}
131130
132bool AArch64::usesOnlyLowPageBits(RelType Type) const {
133 switch (Type) {
131bool AArch64::usesOnlyLowPageBits(RelType type) const {
132 switch (type) {
134133 default:
135134 return false;
136135 case R_AARCH64_ADD_ABS_LO12_NC:
......@@ -147,18 +146,18 @@ bool AArch64::usesOnlyLowPageBits(RelType Type) const {
147146 }
148147}
149148
150RelType AArch64::getDynRel(RelType Type) const {
151 if (Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64)
152 return Type;
149RelType AArch64::getDynRel(RelType type) const {
150 if (type == R_AARCH64_ABS64)
151 return type;
153152 return R_AARCH64_NONE;
154153}
155154
156void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const {
157 write64le(Buf, In.Plt->getVA());
155void AArch64::writeGotPlt(uint8_t *buf, const Symbol &) const {
156 write64le(buf, in.plt->getVA());
158157}
159158
160void AArch64::writePltHeader(uint8_t *Buf) const {
161 const uint8_t PltData[] = {
159void AArch64::writePltHeader(uint8_t *buf) const {
160 const uint8_t pltData[] = {
162161 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]!
163162 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[2]))
164163 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[2]))]
......@@ -168,42 +167,42 @@ void AArch64::writePltHeader(uint8_t *Buf) const {
168167 0x1f, 0x20, 0x03, 0xd5, // nop
169168 0x1f, 0x20, 0x03, 0xd5 // nop
170169 };
171 memcpy(Buf, PltData, sizeof(PltData));
172
173 uint64_t Got = In.GotPlt->getVA();
174 uint64_t Plt = In.Plt->getVA();
175 relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
176 getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
177 relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
178 relocateOne(Buf + 12, R_AARCH64_ADD_ABS_LO12_NC, Got + 16);
170 memcpy(buf, pltData, sizeof(pltData));
171
172 uint64_t got = in.gotPlt->getVA();
173 uint64_t plt = in.plt->getVA();
174 relocateOne(buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
175 getAArch64Page(got + 16) - getAArch64Page(plt + 4));
176 relocateOne(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16);
177 relocateOne(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16);
179178}
180179
181void AArch64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
182 uint64_t PltEntryAddr, int32_t Index,
183 unsigned RelOff) const {
184 const uint8_t Inst[] = {
180void AArch64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
181 uint64_t pltEntryAddr, int32_t index,
182 unsigned relOff) const {
183 const uint8_t inst[] = {
185184 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
186185 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))]
187186 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[n]))
188187 0x20, 0x02, 0x1f, 0xd6 // br x17
189188 };
190 memcpy(Buf, Inst, sizeof(Inst));
189 memcpy(buf, inst, sizeof(inst));
191190
192 relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
193 getAArch64Page(GotPltEntryAddr) - getAArch64Page(PltEntryAddr));
194 relocateOne(Buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, GotPltEntryAddr);
195 relocateOne(Buf + 8, R_AARCH64_ADD_ABS_LO12_NC, GotPltEntryAddr);
191 relocateOne(buf, R_AARCH64_ADR_PREL_PG_HI21,
192 getAArch64Page(gotPltEntryAddr) - getAArch64Page(pltEntryAddr));
193 relocateOne(buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, gotPltEntryAddr);
194 relocateOne(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr);
196195}
197196
198bool AArch64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
199 uint64_t BranchAddr, const Symbol &S) const {
197bool AArch64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
198 uint64_t branchAddr, const Symbol &s) const {
200199 // ELF for the ARM 64-bit architecture, section Call and Jump relocations
201200 // only permits range extension thunks for R_AARCH64_CALL26 and
202201 // R_AARCH64_JUMP26 relocation types.
203 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
202 if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
204203 return false;
205 uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
206 return !inBranchRange(Type, BranchAddr, Dst);
204 uint64_t dst = (expr == R_PLT_PC) ? s.getPltVA() : s.getVA();
205 return !inBranchRange(type, branchAddr, dst);
207206}
208207
209208uint32_t AArch64::getThunkSectionSpacing() const {
......@@ -213,71 +212,72 @@ uint32_t AArch64::getThunkSectionSpacing() const {
213212 return (128 * 1024 * 1024) - 0x30000;
214213}
215214
216bool AArch64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
217 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
215bool AArch64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
216 if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
218217 return true;
219218 // The AArch64 call and unconditional branch instructions have a range of
220219 // +/- 128 MiB.
221 uint64_t Range = 128 * 1024 * 1024;
222 if (Dst > Src) {
220 uint64_t range = 128 * 1024 * 1024;
221 if (dst > src) {
223222 // Immediate of branch is signed.
224 Range -= 4;
225 return Dst - Src <= Range;
223 range -= 4;
224 return dst - src <= range;
226225 }
227 return Src - Dst <= Range;
226 return src - dst <= range;
228227}
229228
230static void write32AArch64Addr(uint8_t *L, uint64_t Imm) {
231 uint32_t ImmLo = (Imm & 0x3) << 29;
232 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
233 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
234 write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi);
229static void write32AArch64Addr(uint8_t *l, uint64_t imm) {
230 uint32_t immLo = (imm & 0x3) << 29;
231 uint32_t immHi = (imm & 0x1FFFFC) << 3;
232 uint64_t mask = (0x3 << 29) | (0x1FFFFC << 3);
233 write32le(l, (read32le(l) & ~mask) | immLo | immHi);
235234}
236235
237236// Return the bits [Start, End] from Val shifted Start bits.
238237// For instance, getBits(0xF0, 4, 8) returns 0xF.
239static uint64_t getBits(uint64_t Val, int Start, int End) {
240 uint64_t Mask = ((uint64_t)1 << (End + 1 - Start)) - 1;
241 return (Val >> Start) & Mask;
238static uint64_t getBits(uint64_t val, int start, int end) {
239 uint64_t mask = ((uint64_t)1 << (end + 1 - start)) - 1;
240 return (val >> start) & mask;
242241}
243242
244static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
243static void or32le(uint8_t *p, int32_t v) { write32le(p, read32le(p) | v); }
245244
246245// Update the immediate field in a AARCH64 ldr, str, and add instruction.
247static void or32AArch64Imm(uint8_t *L, uint64_t Imm) {
248 or32le(L, (Imm & 0xFFF) << 10);
246static void or32AArch64Imm(uint8_t *l, uint64_t imm) {
247 or32le(l, (imm & 0xFFF) << 10);
249248}
250249
251void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
252 switch (Type) {
250void AArch64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
251 switch (type) {
253252 case R_AARCH64_ABS16:
254253 case R_AARCH64_PREL16:
255 checkIntUInt(Loc, Val, 16, Type);
256 write16le(Loc, Val);
254 checkIntUInt(loc, val, 16, type);
255 write16le(loc, val);
257256 break;
258257 case R_AARCH64_ABS32:
259258 case R_AARCH64_PREL32:
260 checkIntUInt(Loc, Val, 32, Type);
261 write32le(Loc, Val);
259 checkIntUInt(loc, val, 32, type);
260 write32le(loc, val);
262261 break;
263262 case R_AARCH64_ABS64:
264 case R_AARCH64_GLOB_DAT:
265263 case R_AARCH64_PREL64:
266 write64le(Loc, Val);
264 write64le(loc, val);
267265 break;
268266 case R_AARCH64_ADD_ABS_LO12_NC:
269 or32AArch64Imm(Loc, Val);
267 or32AArch64Imm(loc, val);
270268 break;
271269 case R_AARCH64_ADR_GOT_PAGE:
272270 case R_AARCH64_ADR_PREL_PG_HI21:
273271 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
274272 case R_AARCH64_TLSDESC_ADR_PAGE21:
275 checkInt(Loc, Val, 33, Type);
276 write32AArch64Addr(Loc, Val >> 12);
273 checkInt(loc, val, 33, type);
274 LLVM_FALLTHROUGH;
275 case R_AARCH64_ADR_PREL_PG_HI21_NC:
276 write32AArch64Addr(loc, val >> 12);
277277 break;
278278 case R_AARCH64_ADR_PREL_LO21:
279 checkInt(Loc, Val, 21, Type);
280 write32AArch64Addr(Loc, Val);
279 checkInt(loc, val, 21, type);
280 write32AArch64Addr(loc, val);
281281 break;
282282 case R_AARCH64_JUMP26:
283283 // Normally we would just write the bits of the immediate field, however
......@@ -287,75 +287,75 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
287287 // opcode and the immediate (0 001 | 01 imm26) we can do this
288288 // transformation by placing a R_AARCH64_JUMP26 relocation at the offset of
289289 // the instruction we want to patch.
290 write32le(Loc, 0x14000000);
290 write32le(loc, 0x14000000);
291291 LLVM_FALLTHROUGH;
292292 case R_AARCH64_CALL26:
293 checkInt(Loc, Val, 28, Type);
294 or32le(Loc, (Val & 0x0FFFFFFC) >> 2);
293 checkInt(loc, val, 28, type);
294 or32le(loc, (val & 0x0FFFFFFC) >> 2);
295295 break;
296296 case R_AARCH64_CONDBR19:
297297 case R_AARCH64_LD_PREL_LO19:
298 checkAlignment(Loc, Val, 4, Type);
299 checkInt(Loc, Val, 21, Type);
300 or32le(Loc, (Val & 0x1FFFFC) << 3);
298 checkAlignment(loc, val, 4, type);
299 checkInt(loc, val, 21, type);
300 or32le(loc, (val & 0x1FFFFC) << 3);
301301 break;
302302 case R_AARCH64_LDST8_ABS_LO12_NC:
303303 case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
304 or32AArch64Imm(Loc, getBits(Val, 0, 11));
304 or32AArch64Imm(loc, getBits(val, 0, 11));
305305 break;
306306 case R_AARCH64_LDST16_ABS_LO12_NC:
307307 case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
308 checkAlignment(Loc, Val, 2, Type);
309 or32AArch64Imm(Loc, getBits(Val, 1, 11));
308 checkAlignment(loc, val, 2, type);
309 or32AArch64Imm(loc, getBits(val, 1, 11));
310310 break;
311311 case R_AARCH64_LDST32_ABS_LO12_NC:
312312 case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
313 checkAlignment(Loc, Val, 4, Type);
314 or32AArch64Imm(Loc, getBits(Val, 2, 11));
313 checkAlignment(loc, val, 4, type);
314 or32AArch64Imm(loc, getBits(val, 2, 11));
315315 break;
316316 case R_AARCH64_LDST64_ABS_LO12_NC:
317317 case R_AARCH64_LD64_GOT_LO12_NC:
318318 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
319319 case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
320320 case R_AARCH64_TLSDESC_LD64_LO12:
321 checkAlignment(Loc, Val, 8, Type);
322 or32AArch64Imm(Loc, getBits(Val, 3, 11));
321 checkAlignment(loc, val, 8, type);
322 or32AArch64Imm(loc, getBits(val, 3, 11));
323323 break;
324324 case R_AARCH64_LDST128_ABS_LO12_NC:
325325 case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC:
326 checkAlignment(Loc, Val, 16, Type);
327 or32AArch64Imm(Loc, getBits(Val, 4, 11));
326 checkAlignment(loc, val, 16, type);
327 or32AArch64Imm(loc, getBits(val, 4, 11));
328328 break;
329329 case R_AARCH64_MOVW_UABS_G0_NC:
330 or32le(Loc, (Val & 0xFFFF) << 5);
330 or32le(loc, (val & 0xFFFF) << 5);
331331 break;
332332 case R_AARCH64_MOVW_UABS_G1_NC:
333 or32le(Loc, (Val & 0xFFFF0000) >> 11);
333 or32le(loc, (val & 0xFFFF0000) >> 11);
334334 break;
335335 case R_AARCH64_MOVW_UABS_G2_NC:
336 or32le(Loc, (Val & 0xFFFF00000000) >> 27);
336 or32le(loc, (val & 0xFFFF00000000) >> 27);
337337 break;
338338 case R_AARCH64_MOVW_UABS_G3:
339 or32le(Loc, (Val & 0xFFFF000000000000) >> 43);
339 or32le(loc, (val & 0xFFFF000000000000) >> 43);
340340 break;
341341 case R_AARCH64_TSTBR14:
342 checkInt(Loc, Val, 16, Type);
343 or32le(Loc, (Val & 0xFFFC) << 3);
342 checkInt(loc, val, 16, type);
343 or32le(loc, (val & 0xFFFC) << 3);
344344 break;
345345 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
346 checkUInt(Loc, Val, 24, Type);
347 or32AArch64Imm(Loc, Val >> 12);
346 checkUInt(loc, val, 24, type);
347 or32AArch64Imm(loc, val >> 12);
348348 break;
349349 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
350350 case R_AARCH64_TLSDESC_ADD_LO12:
351 or32AArch64Imm(Loc, Val);
351 or32AArch64Imm(loc, val);
352352 break;
353353 default:
354 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
354 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
355355 }
356356}
357357
358void AArch64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
358void AArch64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
359359 // TLSDESC Global-Dynamic relocation are in the form:
360360 // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
361361 // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12]
......@@ -367,25 +367,25 @@ void AArch64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
367367 // movk x0, #0x10
368368 // nop
369369 // nop
370 checkUInt(Loc, Val, 32, Type);
370 checkUInt(loc, val, 32, type);
371371
372 switch (Type) {
372 switch (type) {
373373 case R_AARCH64_TLSDESC_ADD_LO12:
374374 case R_AARCH64_TLSDESC_CALL:
375 write32le(Loc, 0xd503201f); // nop
375 write32le(loc, 0xd503201f); // nop
376376 return;
377377 case R_AARCH64_TLSDESC_ADR_PAGE21:
378 write32le(Loc, 0xd2a00000 | (((Val >> 16) & 0xffff) << 5)); // movz
378 write32le(loc, 0xd2a00000 | (((val >> 16) & 0xffff) << 5)); // movz
379379 return;
380380 case R_AARCH64_TLSDESC_LD64_LO12:
381 write32le(Loc, 0xf2800000 | ((Val & 0xffff) << 5)); // movk
381 write32le(loc, 0xf2800000 | ((val & 0xffff) << 5)); // movk
382382 return;
383383 default:
384384 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
385385 }
386386}
387387
388void AArch64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
388void AArch64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
389389 // TLSDESC Global-Dynamic relocation are in the form:
390390 // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
391391 // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12]
......@@ -398,43 +398,193 @@ void AArch64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
398398 // nop
399399 // nop
400400
401 switch (Type) {
401 switch (type) {
402402 case R_AARCH64_TLSDESC_ADD_LO12:
403403 case R_AARCH64_TLSDESC_CALL:
404 write32le(Loc, 0xd503201f); // nop
404 write32le(loc, 0xd503201f); // nop
405405 break;
406406 case R_AARCH64_TLSDESC_ADR_PAGE21:
407 write32le(Loc, 0x90000000); // adrp
408 relocateOne(Loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, Val);
407 write32le(loc, 0x90000000); // adrp
408 relocateOne(loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, val);
409409 break;
410410 case R_AARCH64_TLSDESC_LD64_LO12:
411 write32le(Loc, 0xf9400000); // ldr
412 relocateOne(Loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, Val);
411 write32le(loc, 0xf9400000); // ldr
412 relocateOne(loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, val);
413413 break;
414414 default:
415415 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
416416 }
417417}
418418
419void AArch64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
420 checkUInt(Loc, Val, 32, Type);
419void AArch64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
420 checkUInt(loc, val, 32, type);
421421
422 if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) {
422 if (type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) {
423423 // Generate MOVZ.
424 uint32_t RegNo = read32le(Loc) & 0x1f;
425 write32le(Loc, (0xd2a00000 | RegNo) | (((Val >> 16) & 0xffff) << 5));
424 uint32_t regNo = read32le(loc) & 0x1f;
425 write32le(loc, (0xd2a00000 | regNo) | (((val >> 16) & 0xffff) << 5));
426426 return;
427427 }
428 if (Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) {
428 if (type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) {
429429 // Generate MOVK.
430 uint32_t RegNo = read32le(Loc) & 0x1f;
431 write32le(Loc, (0xf2800000 | RegNo) | ((Val & 0xffff) << 5));
430 uint32_t regNo = read32le(loc) & 0x1f;
431 write32le(loc, (0xf2800000 | regNo) | ((val & 0xffff) << 5));
432432 return;
433433 }
434434 llvm_unreachable("invalid relocation for TLS IE to LE relaxation");
435435}
436436
437TargetInfo *elf::getAArch64TargetInfo() {
438 static AArch64 Target;
439 return &Target;
437// AArch64 may use security features in variant PLT sequences. These are:
438// Pointer Authentication (PAC), introduced in armv8.3-a and Branch Target
439// Indicator (BTI) introduced in armv8.5-a. The additional instructions used
440// in the variant Plt sequences are encoded in the Hint space so they can be
441// deployed on older architectures, which treat the instructions as a nop.
442// PAC and BTI can be combined leading to the following combinations:
443// writePltHeader
444// writePltHeaderBti (no PAC Header needed)
445// writePlt
446// writePltBti (BTI only)
447// writePltPac (PAC only)
448// writePltBtiPac (BTI and PAC)
449//
450// When PAC is enabled the dynamic loader encrypts the address that it places
451// in the .got.plt using the pacia1716 instruction which encrypts the value in
452// x17 using the modifier in x16. The static linker places autia1716 before the
453// indirect branch to x17 to authenticate the address in x17 with the modifier
454// in x16. This makes it more difficult for an attacker to modify the value in
455// the .got.plt.
456//
457// When BTI is enabled all indirect branches must land on a bti instruction.
458// The static linker must place a bti instruction at the start of any PLT entry
459// that may be the target of an indirect branch. As the PLT entries call the
460// lazy resolver indirectly this must have a bti instruction at start. In
461// general a bti instruction is not needed for a PLT entry as indirect calls
462// are resolved to the function address and not the PLT entry for the function.
463// There are a small number of cases where the PLT address can escape, such as
464// taking the address of a function or ifunc via a non got-generating
465// relocation, and a shared library refers to that symbol.
466//
467// We use the bti c variant of the instruction which permits indirect branches
468// (br) via x16/x17 and indirect function calls (blr) via any register. The ABI
469// guarantees that all indirect branches from code requiring BTI protection
470// will go via x16/x17
471
472namespace {
473class AArch64BtiPac final : public AArch64 {
474public:
475 AArch64BtiPac();
476 void writePltHeader(uint8_t *buf) const override;
477 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
478 int32_t index, unsigned relOff) const override;
479
480private:
481 bool btiHeader; // bti instruction needed in PLT Header
482 bool btiEntry; // bti instruction needed in PLT Entry
483 bool pacEntry; // autia1716 instruction needed in PLT Entry
484};
485} // namespace
486
487AArch64BtiPac::AArch64BtiPac() {
488 btiHeader = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
489 // A BTI (Branch Target Indicator) Plt Entry is only required if the
490 // address of the PLT entry can be taken by the program, which permits an
491 // indirect jump to the PLT entry. This can happen when the address
492 // of the PLT entry for a function is canonicalised due to the address of
493 // the function in an executable being taken by a shared library.
494 // FIXME: There is a potential optimization to omit the BTI if we detect
495 // that the address of the PLT entry isn't taken.
496 btiEntry = btiHeader && !config->shared;
497 pacEntry = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC);
498
499 if (btiEntry || pacEntry)
500 pltEntrySize = 24;
440501}
502
503void AArch64BtiPac::writePltHeader(uint8_t *buf) const {
504 const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c
505 const uint8_t pltData[] = {
506 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]!
507 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[2]))
508 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[2]))]
509 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[2]))
510 0x20, 0x02, 0x1f, 0xd6, // br x17
511 0x1f, 0x20, 0x03, 0xd5, // nop
512 0x1f, 0x20, 0x03, 0xd5 // nop
513 };
514 const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
515
516 uint64_t got = in.gotPlt->getVA();
517 uint64_t plt = in.plt->getVA();
518
519 if (btiHeader) {
520 // PltHeader is called indirectly by plt[N]. Prefix pltData with a BTI C
521 // instruction.
522 memcpy(buf, btiData, sizeof(btiData));
523 buf += sizeof(btiData);
524 plt += sizeof(btiData);
525 }
526 memcpy(buf, pltData, sizeof(pltData));
527
528 relocateOne(buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
529 getAArch64Page(got + 16) - getAArch64Page(plt + 8));
530 relocateOne(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16);
531 relocateOne(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16);
532 if (!btiHeader)
533 // We didn't add the BTI c instruction so round out size with NOP.
534 memcpy(buf + sizeof(pltData), nopData, sizeof(nopData));
535}
536
537void AArch64BtiPac::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
538 uint64_t pltEntryAddr, int32_t index,
539 unsigned relOff) const {
540 // The PLT entry is of the form:
541 // [btiData] addrInst (pacBr | stdBr) [nopData]
542 const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c
543 const uint8_t addrInst[] = {
544 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
545 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))]
546 0x10, 0x02, 0x00, 0x91 // add x16, x16, Offset(&(.plt.got[n]))
547 };
548 const uint8_t pacBr[] = {
549 0x9f, 0x21, 0x03, 0xd5, // autia1716
550 0x20, 0x02, 0x1f, 0xd6 // br x17
551 };
552 const uint8_t stdBr[] = {
553 0x20, 0x02, 0x1f, 0xd6, // br x17
554 0x1f, 0x20, 0x03, 0xd5 // nop
555 };
556 const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
557
558 if (btiEntry) {
559 memcpy(buf, btiData, sizeof(btiData));
560 buf += sizeof(btiData);
561 pltEntryAddr += sizeof(btiData);
562 }
563
564 memcpy(buf, addrInst, sizeof(addrInst));
565 relocateOne(buf, R_AARCH64_ADR_PREL_PG_HI21,
566 getAArch64Page(gotPltEntryAddr) -
567 getAArch64Page(pltEntryAddr));
568 relocateOne(buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, gotPltEntryAddr);
569 relocateOne(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr);
570
571 if (pacEntry)
572 memcpy(buf + sizeof(addrInst), pacBr, sizeof(pacBr));
573 else
574 memcpy(buf + sizeof(addrInst), stdBr, sizeof(stdBr));
575 if (!btiEntry)
576 // We didn't add the BTI c instruction so round out size with NOP.
577 memcpy(buf + sizeof(addrInst) + sizeof(stdBr), nopData, sizeof(nopData));
578}
579
580static TargetInfo *getTargetInfo() {
581 if (config->andFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
582 GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
583 static AArch64BtiPac t;
584 return &t;
585 }
586 static AArch64 t;
587 return &t;
588}
589
590TargetInfo *elf::getAArch64TargetInfo() { return getTargetInfo(); }
deps/lld/ELF/Arch/AMDGPU.cpp+39-31
......@@ -1,9 +1,8 @@
11//===- AMDGPU.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -26,62 +25,63 @@ class AMDGPU final : public TargetInfo {
2625public:
2726 AMDGPU();
2827 uint32_t calcEFlags() const override;
29 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
30 RelExpr getRelExpr(RelType Type, const Symbol &S,
31 const uint8_t *Loc) const override;
28 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
29 RelExpr getRelExpr(RelType type, const Symbol &s,
30 const uint8_t *loc) const override;
31 RelType getDynRel(RelType type) const override;
3232};
3333} // namespace
3434
3535AMDGPU::AMDGPU() {
36 RelativeRel = R_AMDGPU_RELATIVE64;
37 GotRel = R_AMDGPU_ABS64;
38 NoneRel = R_AMDGPU_NONE;
39 GotEntrySize = 8;
36 relativeRel = R_AMDGPU_RELATIVE64;
37 gotRel = R_AMDGPU_ABS64;
38 noneRel = R_AMDGPU_NONE;
39 symbolicRel = R_AMDGPU_ABS64;
4040}
4141
42static uint32_t getEFlags(InputFile *File) {
43 return cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags;
42static uint32_t getEFlags(InputFile *file) {
43 return cast<ObjFile<ELF64LE>>(file)->getObj().getHeader()->e_flags;
4444}
4545
4646uint32_t AMDGPU::calcEFlags() const {
47 assert(!ObjectFiles.empty());
48 uint32_t Ret = getEFlags(ObjectFiles[0]);
47 assert(!objectFiles.empty());
48 uint32_t ret = getEFlags(objectFiles[0]);
4949
5050 // Verify that all input files have the same e_flags.
51 for (InputFile *F : makeArrayRef(ObjectFiles).slice(1)) {
52 if (Ret == getEFlags(F))
51 for (InputFile *f : makeArrayRef(objectFiles).slice(1)) {
52 if (ret == getEFlags(f))
5353 continue;
54 error("incompatible e_flags: " + toString(F));
54 error("incompatible e_flags: " + toString(f));
5555 return 0;
5656 }
57 return Ret;
57 return ret;
5858}
5959
60void AMDGPU::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
61 switch (Type) {
60void AMDGPU::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
61 switch (type) {
6262 case R_AMDGPU_ABS32:
6363 case R_AMDGPU_GOTPCREL:
6464 case R_AMDGPU_GOTPCREL32_LO:
6565 case R_AMDGPU_REL32:
6666 case R_AMDGPU_REL32_LO:
67 write32le(Loc, Val);
67 write32le(loc, val);
6868 break;
6969 case R_AMDGPU_ABS64:
7070 case R_AMDGPU_REL64:
71 write64le(Loc, Val);
71 write64le(loc, val);
7272 break;
7373 case R_AMDGPU_GOTPCREL32_HI:
7474 case R_AMDGPU_REL32_HI:
75 write32le(Loc, Val >> 32);
75 write32le(loc, val >> 32);
7676 break;
7777 default:
78 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
78 llvm_unreachable("unknown relocation");
7979 }
8080}
8181
82RelExpr AMDGPU::getRelExpr(RelType Type, const Symbol &S,
83 const uint8_t *Loc) const {
84 switch (Type) {
82RelExpr AMDGPU::getRelExpr(RelType type, const Symbol &s,
83 const uint8_t *loc) const {
84 switch (type) {
8585 case R_AMDGPU_ABS32:
8686 case R_AMDGPU_ABS64:
8787 return R_ABS;
......@@ -95,11 +95,19 @@ RelExpr AMDGPU::getRelExpr(RelType Type, const Symbol &S,
9595 case R_AMDGPU_GOTPCREL32_HI:
9696 return R_GOT_PC;
9797 default:
98 return R_INVALID;
98 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
99 ") against symbol " + toString(s));
100 return R_NONE;
99101 }
100102}
101103
104RelType AMDGPU::getDynRel(RelType type) const {
105 if (type == R_AMDGPU_ABS64)
106 return type;
107 return R_AMDGPU_NONE;
108}
109
102110TargetInfo *elf::getAMDGPUTargetInfo() {
103 static AMDGPU Target;
104 return &Target;
111 static AMDGPU target;
112 return &target;
105113}
deps/lld/ELF/Arch/ARM.cpp+228-234
......@@ -1,9 +1,8 @@
11//===- ARM.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -27,63 +26,62 @@ class ARM final : public TargetInfo {
2726public:
2827 ARM();
2928 uint32_t calcEFlags() const override;
30 RelExpr getRelExpr(RelType Type, const Symbol &S,
31 const uint8_t *Loc) const override;
32 RelType getDynRel(RelType Type) const override;
33 int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
34 void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
35 void writeIgotPlt(uint8_t *Buf, const Symbol &S) const override;
36 void writePltHeader(uint8_t *Buf) const override;
37 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
38 int32_t Index, unsigned RelOff) const override;
39 void addPltSymbols(InputSection &IS, uint64_t Off) const override;
40 void addPltHeaderSymbols(InputSection &ISD) const override;
41 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
42 uint64_t BranchAddr, const Symbol &S) const override;
29 RelExpr getRelExpr(RelType type, const Symbol &s,
30 const uint8_t *loc) const override;
31 RelType getDynRel(RelType type) const override;
32 int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
33 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
34 void writeIgotPlt(uint8_t *buf, const Symbol &s) const override;
35 void writePltHeader(uint8_t *buf) const override;
36 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
37 int32_t index, unsigned relOff) const override;
38 void addPltSymbols(InputSection &isec, uint64_t off) const override;
39 void addPltHeaderSymbols(InputSection &isd) const override;
40 bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
41 uint64_t branchAddr, const Symbol &s) const override;
4342 uint32_t getThunkSectionSpacing() const override;
44 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
45 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
43 bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
44 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
4645};
4746} // namespace
4847
4948ARM::ARM() {
50 CopyRel = R_ARM_COPY;
51 RelativeRel = R_ARM_RELATIVE;
52 IRelativeRel = R_ARM_IRELATIVE;
53 GotRel = R_ARM_GLOB_DAT;
54 NoneRel = R_ARM_NONE;
55 PltRel = R_ARM_JUMP_SLOT;
56 TlsGotRel = R_ARM_TLS_TPOFF32;
57 TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
58 TlsOffsetRel = R_ARM_TLS_DTPOFF32;
59 GotBaseSymInGotPlt = false;
60 GotEntrySize = 4;
61 GotPltEntrySize = 4;
62 PltEntrySize = 16;
63 PltHeaderSize = 32;
64 TrapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
65 NeedsThunks = true;
49 copyRel = R_ARM_COPY;
50 relativeRel = R_ARM_RELATIVE;
51 iRelativeRel = R_ARM_IRELATIVE;
52 gotRel = R_ARM_GLOB_DAT;
53 noneRel = R_ARM_NONE;
54 pltRel = R_ARM_JUMP_SLOT;
55 symbolicRel = R_ARM_ABS32;
56 tlsGotRel = R_ARM_TLS_TPOFF32;
57 tlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
58 tlsOffsetRel = R_ARM_TLS_DTPOFF32;
59 gotBaseSymInGotPlt = false;
60 pltEntrySize = 16;
61 pltHeaderSize = 32;
62 trapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
63 needsThunks = true;
6664}
6765
6866uint32_t ARM::calcEFlags() const {
6967 // The ABIFloatType is used by loaders to detect the floating point calling
7068 // convention.
71 uint32_t ABIFloatType = 0;
72 if (Config->ARMVFPArgs == ARMVFPArgKind::Base ||
73 Config->ARMVFPArgs == ARMVFPArgKind::Default)
74 ABIFloatType = EF_ARM_ABI_FLOAT_SOFT;
75 else if (Config->ARMVFPArgs == ARMVFPArgKind::VFP)
76 ABIFloatType = EF_ARM_ABI_FLOAT_HARD;
69 uint32_t abiFloatType = 0;
70 if (config->armVFPArgs == ARMVFPArgKind::Base ||
71 config->armVFPArgs == ARMVFPArgKind::Default)
72 abiFloatType = EF_ARM_ABI_FLOAT_SOFT;
73 else if (config->armVFPArgs == ARMVFPArgKind::VFP)
74 abiFloatType = EF_ARM_ABI_FLOAT_HARD;
7775
7876 // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
7977 // but we don't have any firm guarantees of conformance. Linux AArch64
8078 // kernels (as of 2016) require an EABI version to be set.
81 return EF_ARM_EABI_VER5 | ABIFloatType;
79 return EF_ARM_EABI_VER5 | abiFloatType;
8280}
8381
84RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
85 const uint8_t *Loc) const {
86 switch (Type) {
82RelExpr ARM::getRelExpr(RelType type, const Symbol &s,
83 const uint8_t *loc) const {
84 switch (type) {
8785 case R_ARM_THM_JUMP11:
8886 return R_PC;
8987 case R_ARM_CALL:
......@@ -108,11 +106,11 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
108106 case R_ARM_SBREL32:
109107 return R_ARM_SBREL;
110108 case R_ARM_TARGET1:
111 return Config->Target1Rel ? R_PC : R_ABS;
109 return config->target1Rel ? R_PC : R_ABS;
112110 case R_ARM_TARGET2:
113 if (Config->Target2 == Target2Policy::Rel)
111 if (config->target2 == Target2Policy::Rel)
114112 return R_PC;
115 if (Config->Target2 == Target2Policy::Abs)
113 if (config->target2 == Target2Policy::Abs)
116114 return R_ABS;
117115 return R_GOT_PC;
118116 case R_ARM_TLS_GD32:
......@@ -145,25 +143,25 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
145143 }
146144}
147145
148RelType ARM::getDynRel(RelType Type) const {
149 if ((Type == R_ARM_ABS32) || (Type == R_ARM_TARGET1 && !Config->Target1Rel))
146RelType ARM::getDynRel(RelType type) const {
147 if ((type == R_ARM_ABS32) || (type == R_ARM_TARGET1 && !config->target1Rel))
150148 return R_ARM_ABS32;
151149 return R_ARM_NONE;
152150}
153151
154void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {
155 write32le(Buf, In.Plt->getVA());
152void ARM::writeGotPlt(uint8_t *buf, const Symbol &) const {
153 write32le(buf, in.plt->getVA());
156154}
157155
158void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
156void ARM::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
159157 // An ARM entry is the address of the ifunc resolver function.
160 write32le(Buf, S.getVA());
158 write32le(buf, s.getVA());
161159}
162160
163161// Long form PLT Header that does not have any restrictions on the displacement
164162// of the .plt from the .plt.got.
165static void writePltHeaderLong(uint8_t *Buf) {
166 const uint8_t PltData[] = {
163static void writePltHeaderLong(uint8_t *buf) {
164 const uint8_t pltData[] = {
167165 0x04, 0xe0, 0x2d, 0xe5, // str lr, [sp,#-4]!
168166 0x04, 0xe0, 0x9f, 0xe5, // ldr lr, L2
169167 0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
......@@ -172,128 +170,128 @@ static void writePltHeaderLong(uint8_t *Buf) {
172170 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary
173171 0xd4, 0xd4, 0xd4, 0xd4, // Pad to 32-byte boundary
174172 0xd4, 0xd4, 0xd4, 0xd4};
175 memcpy(Buf, PltData, sizeof(PltData));
176 uint64_t GotPlt = In.GotPlt->getVA();
177 uint64_t L1 = In.Plt->getVA() + 8;
178 write32le(Buf + 16, GotPlt - L1 - 8);
173 memcpy(buf, pltData, sizeof(pltData));
174 uint64_t gotPlt = in.gotPlt->getVA();
175 uint64_t l1 = in.plt->getVA() + 8;
176 write32le(buf + 16, gotPlt - l1 - 8);
179177}
180178
181179// The default PLT header requires the .plt.got to be within 128 Mb of the
182180// .plt in the positive direction.
183void ARM::writePltHeader(uint8_t *Buf) const {
181void ARM::writePltHeader(uint8_t *buf) const {
184182 // Use a similar sequence to that in writePlt(), the difference is the calling
185183 // conventions mean we use lr instead of ip. The PLT entry is responsible for
186184 // saving lr on the stack, the dynamic loader is responsible for reloading
187185 // it.
188 const uint32_t PltData[] = {
186 const uint32_t pltData[] = {
189187 0xe52de004, // L1: str lr, [sp,#-4]!
190188 0xe28fe600, // add lr, pc, #0x0NN00000 &(.got.plt - L1 - 4)
191189 0xe28eea00, // add lr, lr, #0x000NN000 &(.got.plt - L1 - 4)
192190 0xe5bef000, // ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
193191 };
194192
195 uint64_t Offset = In.GotPlt->getVA() - In.Plt->getVA() - 4;
196 if (!llvm::isUInt<27>(Offset)) {
193 uint64_t offset = in.gotPlt->getVA() - in.plt->getVA() - 4;
194 if (!llvm::isUInt<27>(offset)) {
197195 // We cannot encode the Offset, use the long form.
198 writePltHeaderLong(Buf);
196 writePltHeaderLong(buf);
199197 return;
200198 }
201 write32le(Buf + 0, PltData[0]);
202 write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff));
203 write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff));
204 write32le(Buf + 12, PltData[3] | (Offset & 0xfff));
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);
199 write32le(buf + 0, pltData[0]);
200 write32le(buf + 4, pltData[1] | ((offset >> 20) & 0xff));
201 write32le(buf + 8, pltData[2] | ((offset >> 12) & 0xff));
202 write32le(buf + 12, pltData[3] | (offset & 0xfff));
203 memcpy(buf + 16, trapInstr.data(), 4); // Pad to 32-byte boundary
204 memcpy(buf + 20, trapInstr.data(), 4);
205 memcpy(buf + 24, trapInstr.data(), 4);
206 memcpy(buf + 28, trapInstr.data(), 4);
209207}
210208
211void ARM::addPltHeaderSymbols(InputSection &IS) const {
212 addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
213 addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
209void ARM::addPltHeaderSymbols(InputSection &isec) const {
210 addSyntheticLocal("$a", STT_NOTYPE, 0, 0, isec);
211 addSyntheticLocal("$d", STT_NOTYPE, 16, 0, isec);
214212}
215213
216214// Long form PLT entries that do not have any restrictions on the displacement
217215// of the .plt from the .plt.got.
218static void writePltLong(uint8_t *Buf, uint64_t GotPltEntryAddr,
219 uint64_t PltEntryAddr, int32_t Index,
220 unsigned RelOff) {
221 const uint8_t PltData[] = {
216static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr,
217 uint64_t pltEntryAddr, int32_t index,
218 unsigned relOff) {
219 const uint8_t pltData[] = {
222220 0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2
223221 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
224222 0x00, 0xf0, 0x9c, 0xe5, // ldr pc, [ip]
225223 0x00, 0x00, 0x00, 0x00, // L2: .word Offset(&(.plt.got) - L1 - 8
226224 };
227 memcpy(Buf, PltData, sizeof(PltData));
228 uint64_t L1 = PltEntryAddr + 4;
229 write32le(Buf + 12, GotPltEntryAddr - L1 - 8);
225 memcpy(buf, pltData, sizeof(pltData));
226 uint64_t l1 = pltEntryAddr + 4;
227 write32le(buf + 12, gotPltEntryAddr - l1 - 8);
230228}
231229
232230// The default PLT entries require the .plt.got to be within 128 Mb of the
233231// .plt in the positive direction.
234void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
235 uint64_t PltEntryAddr, int32_t Index,
236 unsigned RelOff) const {
232void ARM::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
233 uint64_t pltEntryAddr, int32_t index,
234 unsigned relOff) const {
237235 // The PLT entry is similar to the example given in Appendix A of ELF for
238236 // the Arm Architecture. Instead of using the Group Relocations to find the
239237 // optimal rotation for the 8-bit immediate used in the add instructions we
240238 // hard code the most compact rotations for simplicity. This saves a load
241239 // instruction over the long plt sequences.
242 const uint32_t PltData[] = {
240 const uint32_t pltData[] = {
243241 0xe28fc600, // L1: add ip, pc, #0x0NN00000 Offset(&(.plt.got) - L1 - 8
244242 0xe28cca00, // add ip, ip, #0x000NN000 Offset(&(.plt.got) - L1 - 8
245243 0xe5bcf000, // ldr pc, [ip, #0x00000NNN] Offset(&(.plt.got) - L1 - 8
246244 };
247245
248 uint64_t Offset = GotPltEntryAddr - PltEntryAddr - 8;
249 if (!llvm::isUInt<27>(Offset)) {
246 uint64_t offset = gotPltEntryAddr - pltEntryAddr - 8;
247 if (!llvm::isUInt<27>(offset)) {
250248 // We cannot encode the Offset, use the long form.
251 writePltLong(Buf, GotPltEntryAddr, PltEntryAddr, Index, RelOff);
249 writePltLong(buf, gotPltEntryAddr, pltEntryAddr, index, relOff);
252250 return;
253251 }
254 write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff));
255 write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff));
256 write32le(Buf + 8, PltData[2] | (Offset & 0xfff));
257 memcpy(Buf + 12, TrapInstr.data(), 4); // Pad to 16-byte boundary
252 write32le(buf + 0, pltData[0] | ((offset >> 20) & 0xff));
253 write32le(buf + 4, pltData[1] | ((offset >> 12) & 0xff));
254 write32le(buf + 8, pltData[2] | (offset & 0xfff));
255 memcpy(buf + 12, trapInstr.data(), 4); // Pad to 16-byte boundary
258256}
259257
260void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {
261 addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
262 addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
258void ARM::addPltSymbols(InputSection &isec, uint64_t off) const {
259 addSyntheticLocal("$a", STT_NOTYPE, off, 0, isec);
260 addSyntheticLocal("$d", STT_NOTYPE, off + 12, 0, isec);
263261}
264262
265bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
266 uint64_t BranchAddr, const Symbol &S) const {
263bool ARM::needsThunk(RelExpr expr, RelType type, const InputFile *file,
264 uint64_t branchAddr, const Symbol &s) const {
267265 // If S is an undefined weak symbol and does not have a PLT entry then it
268266 // will be resolved as a branch to the next instruction.
269 if (S.isUndefWeak() && !S.isInPlt())
267 if (s.isUndefWeak() && !s.isInPlt())
270268 return false;
271269 // A state change from ARM to Thumb and vice versa must go through an
272270 // interworking thunk if the relocation type is not R_ARM_CALL or
273271 // R_ARM_THM_CALL.
274 switch (Type) {
272 switch (type) {
275273 case R_ARM_PC24:
276274 case R_ARM_PLT32:
277275 case R_ARM_JUMP24:
278276 // Source is ARM, all PLT entries are ARM so no interworking required.
279277 // Otherwise we need to interwork if Symbol has bit 0 set (Thumb).
280 if (Expr == R_PC && ((S.getVA() & 1) == 1))
278 if (expr == R_PC && ((s.getVA() & 1) == 1))
281279 return true;
282280 LLVM_FALLTHROUGH;
283281 case R_ARM_CALL: {
284 uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
285 return !inBranchRange(Type, BranchAddr, Dst);
282 uint64_t dst = (expr == R_PLT_PC) ? s.getPltVA() : s.getVA();
283 return !inBranchRange(type, branchAddr, dst);
286284 }
287285 case R_ARM_THM_JUMP19:
288286 case R_ARM_THM_JUMP24:
289287 // Source is Thumb, all PLT entries are ARM so interworking is required.
290288 // Otherwise we need to interwork if Symbol has bit 0 clear (ARM).
291 if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0))
289 if (expr == R_PLT_PC || ((s.getVA() & 1) == 0))
292290 return true;
293291 LLVM_FALLTHROUGH;
294292 case R_ARM_THM_CALL: {
295 uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
296 return !inBranchRange(Type, BranchAddr, Dst);
293 uint64_t dst = (expr == R_PLT_PC) ? s.getPltVA() : s.getVA();
294 return !inBranchRange(type, branchAddr, dst);
297295 }
298296 }
299297 return false;
......@@ -301,13 +299,13 @@ bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
301299
302300uint32_t ARM::getThunkSectionSpacing() const {
303301 // The placing of pre-created ThunkSections is controlled by the value
304 // ThunkSectionSpacing returned by getThunkSectionSpacing(). The aim is to
302 // thunkSectionSpacing returned by getThunkSectionSpacing(). The aim is to
305303 // place the ThunkSection such that all branches from the InputSections
306304 // prior to the ThunkSection can reach a Thunk placed at the end of the
307305 // ThunkSection. Graphically:
308 // | up to ThunkSectionSpacing .text input sections |
306 // | up to thunkSectionSpacing .text input sections |
309307 // | ThunkSection |
310 // | up to ThunkSectionSpacing .text input sections |
308 // | up to thunkSectionSpacing .text input sections |
311309 // | ThunkSection |
312310
313311 // Pre-created ThunkSections are spaced roughly 16MiB apart on ARMv7. This
......@@ -318,69 +316,68 @@ uint32_t ARM::getThunkSectionSpacing() const {
318316 // Thumb B<cc>.W range +/- 1MiB
319317 // If a branch cannot reach a pre-created ThunkSection a new one will be
320318 // 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
319 // We intentionally use a lower size for thunkSectionSpacing than the maximum
322320 // branch range so the end of the ThunkSection is more likely to be within
323321 // 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
322 // thunkSectionSpacing by is set conservatively to allow us to create 16,384
325323 // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
326324 // one of the Thunks going out of range.
327325
328 // On Arm the ThunkSectionSpacing depends on the range of the Thumb Branch
326 // On Arm the thunkSectionSpacing depends on the range of the Thumb Branch
329327 // range. On earlier Architectures such as ARMv4, ARMv5 and ARMv6 (except
330328 // ARMv6T2) the range is +/- 4MiB.
331329
332 return (Config->ARMJ1J2BranchEncoding) ? 0x1000000 - 0x30000
330 return (config->armJ1J2BranchEncoding) ? 0x1000000 - 0x30000
333331 : 0x400000 - 0x7500;
334332}
335333
336bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
337 uint64_t Range;
338 uint64_t InstrSize;
334bool ARM::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
335 uint64_t range;
336 uint64_t instrSize;
339337
340 switch (Type) {
338 switch (type) {
341339 case R_ARM_PC24:
342340 case R_ARM_PLT32:
343341 case R_ARM_JUMP24:
344342 case R_ARM_CALL:
345 Range = 0x2000000;
346 InstrSize = 4;
343 range = 0x2000000;
344 instrSize = 4;
347345 break;
348346 case R_ARM_THM_JUMP19:
349 Range = 0x100000;
350 InstrSize = 2;
347 range = 0x100000;
348 instrSize = 2;
351349 break;
352350 case R_ARM_THM_JUMP24:
353351 case R_ARM_THM_CALL:
354 Range = Config->ARMJ1J2BranchEncoding ? 0x1000000 : 0x400000;
355 InstrSize = 2;
352 range = config->armJ1J2BranchEncoding ? 0x1000000 : 0x400000;
353 instrSize = 2;
356354 break;
357355 default:
358356 return true;
359357 }
360358 // PC at Src is 2 instructions ahead, immediate of branch is signed
361 if (Src > Dst)
362 Range -= 2 * InstrSize;
359 if (src > dst)
360 range -= 2 * instrSize;
363361 else
364 Range += InstrSize;
362 range += instrSize;
365363
366 if ((Dst & 0x1) == 0)
364 if ((dst & 0x1) == 0)
367365 // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
368366 // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
369367 // destination will be 4 byte aligned.
370 Src &= ~0x3;
368 src &= ~0x3;
371369 else
372370 // Bit 0 == 1 denotes Thumb state, it is not part of the range
373 Dst &= ~0x1;
371 dst &= ~0x1;
374372
375 uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
376 return Distance <= Range;
373 uint64_t distance = (src > dst) ? src - dst : dst - src;
374 return distance <= range;
377375}
378376
379void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
380 switch (Type) {
377void ARM::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
378 switch (type) {
381379 case R_ARM_ABS32:
382380 case R_ARM_BASE_PREL:
383 case R_ARM_GLOB_DAT:
384381 case R_ARM_GOTOFF32:
385382 case R_ARM_GOT_BREL:
386383 case R_ARM_GOT_PREL:
......@@ -396,135 +393,132 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
396393 case R_ARM_TLS_LE32:
397394 case R_ARM_TLS_TPOFF32:
398395 case R_ARM_TLS_DTPOFF32:
399 write32le(Loc, Val);
400 break;
401 case R_ARM_TLS_DTPMOD32:
402 write32le(Loc, 1);
396 write32le(loc, val);
403397 break;
404398 case R_ARM_PREL31:
405 checkInt(Loc, Val, 31, Type);
406 write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));
399 checkInt(loc, val, 31, type);
400 write32le(loc, (read32le(loc) & 0x80000000) | (val & ~0x80000000));
407401 break;
408402 case R_ARM_CALL:
409403 // R_ARM_CALL is used for BL and BLX instructions, depending on the
410404 // value of bit 0 of Val, we must select a BL or BLX instruction
411 if (Val & 1) {
405 if (val & 1) {
412406 // If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
413407 // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
414 checkInt(Loc, Val, 26, Type);
415 write32le(Loc, 0xfa000000 | // opcode
416 ((Val & 2) << 23) | // H
417 ((Val >> 2) & 0x00ffffff)); // imm24
408 checkInt(loc, val, 26, type);
409 write32le(loc, 0xfa000000 | // opcode
410 ((val & 2) << 23) | // H
411 ((val >> 2) & 0x00ffffff)); // imm24
418412 break;
419413 }
420 if ((read32le(Loc) & 0xfe000000) == 0xfa000000)
414 if ((read32le(loc) & 0xfe000000) == 0xfa000000)
421415 // BLX (always unconditional) instruction to an ARM Target, select an
422416 // unconditional BL.
423 write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
417 write32le(loc, 0xeb000000 | (read32le(loc) & 0x00ffffff));
424418 // fall through as BL encoding is shared with B
425419 LLVM_FALLTHROUGH;
426420 case R_ARM_JUMP24:
427421 case R_ARM_PC24:
428422 case R_ARM_PLT32:
429 checkInt(Loc, Val, 26, Type);
430 write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff));
423 checkInt(loc, val, 26, type);
424 write32le(loc, (read32le(loc) & ~0x00ffffff) | ((val >> 2) & 0x00ffffff));
431425 break;
432426 case R_ARM_THM_JUMP11:
433 checkInt(Loc, Val, 12, Type);
434 write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff));
427 checkInt(loc, val, 12, type);
428 write16le(loc, (read32le(loc) & 0xf800) | ((val >> 1) & 0x07ff));
435429 break;
436430 case R_ARM_THM_JUMP19:
437431 // Encoding T3: Val = S:J2:J1:imm6:imm11:0
438 checkInt(Loc, Val, 21, Type);
439 write16le(Loc,
440 (read16le(Loc) & 0xfbc0) | // opcode cond
441 ((Val >> 10) & 0x0400) | // S
442 ((Val >> 12) & 0x003f)); // imm6
443 write16le(Loc + 2,
432 checkInt(loc, val, 21, type);
433 write16le(loc,
434 (read16le(loc) & 0xfbc0) | // opcode cond
435 ((val >> 10) & 0x0400) | // S
436 ((val >> 12) & 0x003f)); // imm6
437 write16le(loc + 2,
444438 0x8000 | // opcode
445 ((Val >> 8) & 0x0800) | // J2
446 ((Val >> 5) & 0x2000) | // J1
447 ((Val >> 1) & 0x07ff)); // imm11
439 ((val >> 8) & 0x0800) | // J2
440 ((val >> 5) & 0x2000) | // J1
441 ((val >> 1) & 0x07ff)); // imm11
448442 break;
449443 case R_ARM_THM_CALL:
450444 // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
451445 // value of bit 0 of Val, we must select a BL or BLX instruction
452 if ((Val & 1) == 0) {
446 if ((val & 1) == 0) {
453447 // Ensure BLX destination is 4-byte aligned. As BLX instruction may
454448 // only be two byte aligned. This must be done before overflow check
455 Val = alignTo(Val, 4);
449 val = alignTo(val, 4);
456450 }
457451 // Bit 12 is 0 for BLX, 1 for BL
458 write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
459 if (!Config->ARMJ1J2BranchEncoding) {
452 write16le(loc + 2, (read16le(loc + 2) & ~0x1000) | (val & 1) << 12);
453 if (!config->armJ1J2BranchEncoding) {
460454 // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
461455 // different encoding rules and range due to J1 and J2 always being 1.
462 checkInt(Loc, Val, 23, Type);
463 write16le(Loc,
456 checkInt(loc, val, 23, type);
457 write16le(loc,
464458 0xf000 | // opcode
465 ((Val >> 12) & 0x07ff)); // imm11
466 write16le(Loc + 2,
467 (read16le(Loc + 2) & 0xd000) | // opcode
459 ((val >> 12) & 0x07ff)); // imm11
460 write16le(loc + 2,
461 (read16le(loc + 2) & 0xd000) | // opcode
468462 0x2800 | // J1 == J2 == 1
469 ((Val >> 1) & 0x07ff)); // imm11
463 ((val >> 1) & 0x07ff)); // imm11
470464 break;
471465 }
472466 // Fall through as rest of encoding is the same as B.W
473467 LLVM_FALLTHROUGH;
474468 case R_ARM_THM_JUMP24:
475469 // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
476 checkInt(Loc, Val, 25, Type);
477 write16le(Loc,
470 checkInt(loc, val, 25, type);
471 write16le(loc,
478472 0xf000 | // opcode
479 ((Val >> 14) & 0x0400) | // S
480 ((Val >> 12) & 0x03ff)); // imm10
481 write16le(Loc + 2,
482 (read16le(Loc + 2) & 0xd000) | // opcode
483 (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1
484 (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2
485 ((Val >> 1) & 0x07ff)); // imm11
473 ((val >> 14) & 0x0400) | // S
474 ((val >> 12) & 0x03ff)); // imm10
475 write16le(loc + 2,
476 (read16le(loc + 2) & 0xd000) | // opcode
477 (((~(val >> 10)) ^ (val >> 11)) & 0x2000) | // J1
478 (((~(val >> 11)) ^ (val >> 13)) & 0x0800) | // J2
479 ((val >> 1) & 0x07ff)); // imm11
486480 break;
487481 case R_ARM_MOVW_ABS_NC:
488482 case R_ARM_MOVW_PREL_NC:
489 write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) |
490 (Val & 0x0fff));
483 write32le(loc, (read32le(loc) & ~0x000f0fff) | ((val & 0xf000) << 4) |
484 (val & 0x0fff));
491485 break;
492486 case R_ARM_MOVT_ABS:
493487 case R_ARM_MOVT_PREL:
494 write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
495 (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
488 write32le(loc, (read32le(loc) & ~0x000f0fff) |
489 (((val >> 16) & 0xf000) << 4) | ((val >> 16) & 0xfff));
496490 break;
497491 case R_ARM_THM_MOVT_ABS:
498492 case R_ARM_THM_MOVT_PREL:
499493 // Encoding T1: A = imm4:i:imm3:imm8
500 write16le(Loc,
494 write16le(loc,
501495 0xf2c0 | // opcode
502 ((Val >> 17) & 0x0400) | // i
503 ((Val >> 28) & 0x000f)); // imm4
504 write16le(Loc + 2,
505 (read16le(Loc + 2) & 0x8f00) | // opcode
506 ((Val >> 12) & 0x7000) | // imm3
507 ((Val >> 16) & 0x00ff)); // imm8
496 ((val >> 17) & 0x0400) | // i
497 ((val >> 28) & 0x000f)); // imm4
498 write16le(loc + 2,
499 (read16le(loc + 2) & 0x8f00) | // opcode
500 ((val >> 12) & 0x7000) | // imm3
501 ((val >> 16) & 0x00ff)); // imm8
508502 break;
509503 case R_ARM_THM_MOVW_ABS_NC:
510504 case R_ARM_THM_MOVW_PREL_NC:
511505 // Encoding T3: A = imm4:i:imm3:imm8
512 write16le(Loc,
506 write16le(loc,
513507 0xf240 | // opcode
514 ((Val >> 1) & 0x0400) | // i
515 ((Val >> 12) & 0x000f)); // imm4
516 write16le(Loc + 2,
517 (read16le(Loc + 2) & 0x8f00) | // opcode
518 ((Val << 4) & 0x7000) | // imm3
519 (Val & 0x00ff)); // imm8
508 ((val >> 1) & 0x0400) | // i
509 ((val >> 12) & 0x000f)); // imm4
510 write16le(loc + 2,
511 (read16le(loc + 2) & 0x8f00) | // opcode
512 ((val << 4) & 0x7000) | // imm3
513 (val & 0x00ff)); // imm8
520514 break;
521515 default:
522 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
516 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
523517 }
524518}
525519
526int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
527 switch (Type) {
520int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
521 switch (type) {
528522 default:
529523 return 0;
530524 case R_ARM_ABS32:
......@@ -540,47 +534,47 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
540534 case R_ARM_TLS_LDO32:
541535 case R_ARM_TLS_IE32:
542536 case R_ARM_TLS_LE32:
543 return SignExtend64<32>(read32le(Buf));
537 return SignExtend64<32>(read32le(buf));
544538 case R_ARM_PREL31:
545 return SignExtend64<31>(read32le(Buf));
539 return SignExtend64<31>(read32le(buf));
546540 case R_ARM_CALL:
547541 case R_ARM_JUMP24:
548542 case R_ARM_PC24:
549543 case R_ARM_PLT32:
550 return SignExtend64<26>(read32le(Buf) << 2);
544 return SignExtend64<26>(read32le(buf) << 2);
551545 case R_ARM_THM_JUMP11:
552 return SignExtend64<12>(read16le(Buf) << 1);
546 return SignExtend64<12>(read16le(buf) << 1);
553547 case R_ARM_THM_JUMP19: {
554548 // Encoding T3: A = S:J2:J1:imm10:imm6:0
555 uint16_t Hi = read16le(Buf);
556 uint16_t Lo = read16le(Buf + 2);
557 return SignExtend64<20>(((Hi & 0x0400) << 10) | // S
558 ((Lo & 0x0800) << 8) | // J2
559 ((Lo & 0x2000) << 5) | // J1
560 ((Hi & 0x003f) << 12) | // imm6
561 ((Lo & 0x07ff) << 1)); // imm11:0
549 uint16_t hi = read16le(buf);
550 uint16_t lo = read16le(buf + 2);
551 return SignExtend64<20>(((hi & 0x0400) << 10) | // S
552 ((lo & 0x0800) << 8) | // J2
553 ((lo & 0x2000) << 5) | // J1
554 ((hi & 0x003f) << 12) | // imm6
555 ((lo & 0x07ff) << 1)); // imm11:0
562556 }
563557 case R_ARM_THM_CALL:
564 if (!Config->ARMJ1J2BranchEncoding) {
558 if (!config->armJ1J2BranchEncoding) {
565559 // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
566560 // 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
561 uint16_t hi = read16le(buf);
562 uint16_t lo = read16le(buf + 2);
563 return SignExtend64<22>(((hi & 0x7ff) << 12) | // imm11
564 ((lo & 0x7ff) << 1)); // imm11:0
571565 break;
572566 }
573567 LLVM_FALLTHROUGH;
574568 case R_ARM_THM_JUMP24: {
575569 // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
576570 // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
577 uint16_t Hi = read16le(Buf);
578 uint16_t Lo = read16le(Buf + 2);
579 return SignExtend64<24>(((Hi & 0x0400) << 14) | // S
580 (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1
581 (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2
582 ((Hi & 0x003ff) << 12) | // imm0
583 ((Lo & 0x007ff) << 1)); // imm11:0
571 uint16_t hi = read16le(buf);
572 uint16_t lo = read16le(buf + 2);
573 return SignExtend64<24>(((hi & 0x0400) << 14) | // S
574 (~((lo ^ (hi << 3)) << 10) & 0x00800000) | // I1
575 (~((lo ^ (hi << 1)) << 11) & 0x00400000) | // I2
576 ((hi & 0x003ff) << 12) | // imm0
577 ((lo & 0x007ff) << 1)); // imm11:0
584578 }
585579 // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
586580 // MOVT is in the range -32768 <= A < 32768
......@@ -588,25 +582,25 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
588582 case R_ARM_MOVT_ABS:
589583 case R_ARM_MOVW_PREL_NC:
590584 case R_ARM_MOVT_PREL: {
591 uint64_t Val = read32le(Buf) & 0x000f0fff;
592 return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff));
585 uint64_t val = read32le(buf) & 0x000f0fff;
586 return SignExtend64<16>(((val & 0x000f0000) >> 4) | (val & 0x00fff));
593587 }
594588 case R_ARM_THM_MOVW_ABS_NC:
595589 case R_ARM_THM_MOVT_ABS:
596590 case R_ARM_THM_MOVW_PREL_NC:
597591 case R_ARM_THM_MOVT_PREL: {
598592 // Encoding T3: A = imm4:i:imm3:imm8
599 uint16_t Hi = read16le(Buf);
600 uint16_t Lo = read16le(Buf + 2);
601 return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4
602 ((Hi & 0x0400) << 1) | // i
603 ((Lo & 0x7000) >> 4) | // imm3
604 (Lo & 0x00ff)); // imm8
593 uint16_t hi = read16le(buf);
594 uint16_t lo = read16le(buf + 2);
595 return SignExtend64<16>(((hi & 0x000f) << 12) | // imm4
596 ((hi & 0x0400) << 1) | // i
597 ((lo & 0x7000) >> 4) | // imm3
598 (lo & 0x00ff)); // imm8
605599 }
606600 }
607601}
608602
609603TargetInfo *elf::getARMTargetInfo() {
610 static ARM Target;
611 return &Target;
604 static ARM target;
605 return &target;
612606}
deps/lld/ELF/Arch/AVR.cpp+18-19
......@@ -1,9 +1,8 @@
11//===- AVR.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -44,34 +43,34 @@ namespace {
4443class AVR final : public TargetInfo {
4544public:
4645 AVR();
47 RelExpr getRelExpr(RelType Type, const Symbol &S,
48 const uint8_t *Loc) const override;
49 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
46 RelExpr getRelExpr(RelType type, const Symbol &s,
47 const uint8_t *loc) const override;
48 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
5049};
5150} // namespace
5251
53AVR::AVR() { NoneRel = R_AVR_NONE; }
52AVR::AVR() { noneRel = R_AVR_NONE; }
5453
55RelExpr AVR::getRelExpr(RelType Type, const Symbol &S,
56 const uint8_t *Loc) const {
54RelExpr AVR::getRelExpr(RelType type, const Symbol &s,
55 const uint8_t *loc) const {
5756 return R_ABS;
5857}
5958
60void AVR::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
61 switch (Type) {
59void AVR::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
60 switch (type) {
6261 case R_AVR_CALL: {
63 uint16_t Hi = Val >> 17;
64 uint16_t Lo = Val >> 1;
65 write16le(Loc, read16le(Loc) | ((Hi >> 1) << 4) | (Hi & 1));
66 write16le(Loc + 2, Lo);
62 uint16_t hi = val >> 17;
63 uint16_t lo = val >> 1;
64 write16le(loc, read16le(loc) | ((hi >> 1) << 4) | (hi & 1));
65 write16le(loc + 2, lo);
6766 break;
6867 }
6968 default:
70 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
69 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
7170 }
7271}
7372
7473TargetInfo *elf::getAVRTargetInfo() {
75 static AVR Target;
76 return &Target;
74 static AVR target;
75 return &target;
7776}
deps/lld/ELF/Arch/Hexagon.cpp+97-98
......@@ -1,9 +1,8 @@
11//===-- Hexagon.cpp -------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -28,65 +27,65 @@ class Hexagon final : public TargetInfo {
2827public:
2928 Hexagon();
3029 uint32_t calcEFlags() const override;
31 RelExpr getRelExpr(RelType Type, const Symbol &S,
32 const uint8_t *Loc) const override;
33 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
34 void writePltHeader(uint8_t *Buf) const override;
35 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
36 int32_t Index, unsigned RelOff) const override;
30 RelExpr getRelExpr(RelType type, const Symbol &s,
31 const uint8_t *loc) const override;
32 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
33 void writePltHeader(uint8_t *buf) const override;
34 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
35 int32_t index, unsigned relOff) const override;
3736};
3837} // namespace
3938
4039Hexagon::Hexagon() {
41 PltRel = R_HEX_JMP_SLOT;
42 RelativeRel = R_HEX_RELATIVE;
43 GotRel = R_HEX_GLOB_DAT;
44 GotEntrySize = 4;
40 pltRel = R_HEX_JMP_SLOT;
41 relativeRel = R_HEX_RELATIVE;
42 gotRel = R_HEX_GLOB_DAT;
43 symbolicRel = R_HEX_32;
44
4545 // The zero'th GOT entry is reserved for the address of _DYNAMIC. The
4646 // next 3 are reserved for the dynamic loader.
47 GotPltHeaderEntriesNum = 4;
48 GotPltEntrySize = 4;
47 gotPltHeaderEntriesNum = 4;
4948
50 PltEntrySize = 16;
51 PltHeaderSize = 32;
49 pltEntrySize = 16;
50 pltHeaderSize = 32;
5251
5352 // Hexagon Linux uses 64K pages by default.
54 DefaultMaxPageSize = 0x10000;
55 NoneRel = R_HEX_NONE;
53 defaultMaxPageSize = 0x10000;
54 noneRel = R_HEX_NONE;
5655}
5756
5857uint32_t Hexagon::calcEFlags() const {
59 assert(!ObjectFiles.empty());
58 assert(!objectFiles.empty());
6059
6160 // The architecture revision must always be equal to or greater than
6261 // 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;
62 uint32_t ret = 0;
63 for (InputFile *f : objectFiles) {
64 uint32_t eflags = cast<ObjFile<ELF32LE>>(f)->getObj().getHeader()->e_flags;
65 if (eflags > ret)
66 ret = eflags;
6867 }
69 return Ret;
68 return ret;
7069}
7170
72static uint32_t applyMask(uint32_t Mask, uint32_t Data) {
73 uint32_t Result = 0;
74 size_t Off = 0;
71static uint32_t applyMask(uint32_t mask, uint32_t data) {
72 uint32_t result = 0;
73 size_t off = 0;
7574
76 for (size_t Bit = 0; Bit != 32; ++Bit) {
77 uint32_t ValBit = (Data >> Off) & 1;
78 uint32_t MaskBit = (Mask >> Bit) & 1;
79 if (MaskBit) {
80 Result |= (ValBit << Bit);
81 ++Off;
75 for (size_t bit = 0; bit != 32; ++bit) {
76 uint32_t valBit = (data >> off) & 1;
77 uint32_t maskBit = (mask >> bit) & 1;
78 if (maskBit) {
79 result |= (valBit << bit);
80 ++off;
8281 }
8382 }
84 return Result;
83 return result;
8584}
8685
87RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
88 const uint8_t *Loc) const {
89 switch (Type) {
86RelExpr Hexagon::getRelExpr(RelType type, const Symbol &s,
87 const uint8_t *loc) const {
88 switch (type) {
9089 case R_HEX_B9_PCREL:
9190 case R_HEX_B9_PCREL_X:
9291 case R_HEX_B13_PCREL:
......@@ -109,16 +108,16 @@ RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
109108 }
110109}
111110
112static uint32_t findMaskR6(uint32_t Insn) {
111static uint32_t findMaskR6(uint32_t insn) {
113112 // There are (arguably too) many relocation masks for the DSP's
114113 // R_HEX_6_X type. The table below is used to select the correct mask
115114 // for the given instruction.
116115 struct InstructionMask {
117 uint32_t CmpMask;
118 uint32_t RelocMask;
116 uint32_t cmpMask;
117 uint32_t relocMask;
119118 };
120119
121 static const InstructionMask R6[] = {
120 static const InstructionMask r6[] = {
122121 {0x38000000, 0x0000201f}, {0x39000000, 0x0000201f},
123122 {0x3e000000, 0x00001f80}, {0x3f000000, 0x00001f80},
124123 {0x40000000, 0x000020f8}, {0x41000000, 0x000007e0},
......@@ -136,124 +135,124 @@ static uint32_t findMaskR6(uint32_t Insn) {
136135 // Duplex forms have a fixed mask and parse bits 15:14 are always
137136 // zero. Non-duplex insns will always have at least one bit set in the
138137 // parse field.
139 if ((0xC000 & Insn) == 0x0)
138 if ((0xC000 & insn) == 0x0)
140139 return 0x03f00000;
141140
142 for (InstructionMask I : R6)
143 if ((0xff000000 & Insn) == I.CmpMask)
144 return I.RelocMask;
141 for (InstructionMask i : r6)
142 if ((0xff000000 & insn) == i.cmpMask)
143 return i.relocMask;
145144
146145 error("unrecognized instruction for R_HEX_6 relocation: 0x" +
147 utohexstr(Insn));
146 utohexstr(insn));
148147 return 0;
149148}
150149
151static uint32_t findMaskR8(uint32_t Insn) {
152 if ((0xff000000 & Insn) == 0xde000000)
150static uint32_t findMaskR8(uint32_t insn) {
151 if ((0xff000000 & insn) == 0xde000000)
153152 return 0x00e020e8;
154 if ((0xff000000 & Insn) == 0x3c000000)
153 if ((0xff000000 & insn) == 0x3c000000)
155154 return 0x0000207f;
156155 return 0x00001fe0;
157156}
158157
159static uint32_t findMaskR11(uint32_t Insn) {
160 if ((0xff000000 & Insn) == 0xa1000000)
158static uint32_t findMaskR11(uint32_t insn) {
159 if ((0xff000000 & insn) == 0xa1000000)
161160 return 0x060020ff;
162161 return 0x06003fe0;
163162}
164163
165static uint32_t findMaskR16(uint32_t Insn) {
166 if ((0xff000000 & Insn) == 0x48000000)
164static uint32_t findMaskR16(uint32_t insn) {
165 if ((0xff000000 & insn) == 0x48000000)
167166 return 0x061f20ff;
168 if ((0xff000000 & Insn) == 0x49000000)
167 if ((0xff000000 & insn) == 0x49000000)
169168 return 0x061f3fe0;
170 if ((0xff000000 & Insn) == 0x78000000)
169 if ((0xff000000 & insn) == 0x78000000)
171170 return 0x00df3fe0;
172 if ((0xff000000 & Insn) == 0xb0000000)
171 if ((0xff000000 & insn) == 0xb0000000)
173172 return 0x0fe03fe0;
174173
175174 error("unrecognized instruction for R_HEX_16_X relocation: 0x" +
176 utohexstr(Insn));
175 utohexstr(insn));
177176 return 0;
178177}
179178
180static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
179static void or32le(uint8_t *p, int32_t v) { write32le(p, read32le(p) | v); }
181180
182void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
183 switch (Type) {
181void Hexagon::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
182 switch (type) {
184183 case R_HEX_NONE:
185184 break;
186185 case R_HEX_6_PCREL_X:
187186 case R_HEX_6_X:
188 or32le(Loc, applyMask(findMaskR6(read32le(Loc)), Val));
187 or32le(loc, applyMask(findMaskR6(read32le(loc)), val));
189188 break;
190189 case R_HEX_8_X:
191 or32le(Loc, applyMask(findMaskR8(read32le(Loc)), Val));
190 or32le(loc, applyMask(findMaskR8(read32le(loc)), val));
192191 break;
193192 case R_HEX_9_X:
194 or32le(Loc, applyMask(0x00003fe0, Val & 0x3f));
193 or32le(loc, applyMask(0x00003fe0, val & 0x3f));
195194 break;
196195 case R_HEX_10_X:
197 or32le(Loc, applyMask(0x00203fe0, Val & 0x3f));
196 or32le(loc, applyMask(0x00203fe0, val & 0x3f));
198197 break;
199198 case R_HEX_11_X:
200199 case R_HEX_GOT_11_X:
201 or32le(Loc, applyMask(findMaskR11(read32le(Loc)), Val & 0x3f));
200 or32le(loc, applyMask(findMaskR11(read32le(loc)), val & 0x3f));
202201 break;
203202 case R_HEX_12_X:
204 or32le(Loc, applyMask(0x000007e0, Val));
203 or32le(loc, applyMask(0x000007e0, val));
205204 break;
206205 case R_HEX_16_X: // These relocs only have 6 effective bits.
207206 case R_HEX_GOT_16_X:
208 or32le(Loc, applyMask(findMaskR16(read32le(Loc)), Val & 0x3f));
207 or32le(loc, applyMask(findMaskR16(read32le(loc)), val & 0x3f));
209208 break;
210209 case R_HEX_32:
211210 case R_HEX_32_PCREL:
212 or32le(Loc, Val);
211 or32le(loc, val);
213212 break;
214213 case R_HEX_32_6_X:
215214 case R_HEX_GOT_32_6_X:
216 or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
215 or32le(loc, applyMask(0x0fff3fff, val >> 6));
217216 break;
218217 case R_HEX_B9_PCREL:
219 or32le(Loc, applyMask(0x003000fe, Val >> 2));
218 or32le(loc, applyMask(0x003000fe, val >> 2));
220219 break;
221220 case R_HEX_B9_PCREL_X:
222 or32le(Loc, applyMask(0x003000fe, Val & 0x3f));
221 or32le(loc, applyMask(0x003000fe, val & 0x3f));
223222 break;
224223 case R_HEX_B13_PCREL:
225 or32le(Loc, applyMask(0x00202ffe, Val >> 2));
224 or32le(loc, applyMask(0x00202ffe, val >> 2));
226225 break;
227226 case R_HEX_B15_PCREL:
228 or32le(Loc, applyMask(0x00df20fe, Val >> 2));
227 or32le(loc, applyMask(0x00df20fe, val >> 2));
229228 break;
230229 case R_HEX_B15_PCREL_X:
231 or32le(Loc, applyMask(0x00df20fe, Val & 0x3f));
230 or32le(loc, applyMask(0x00df20fe, val & 0x3f));
232231 break;
233232 case R_HEX_B22_PCREL:
234233 case R_HEX_PLT_B22_PCREL:
235 or32le(Loc, applyMask(0x1ff3ffe, Val >> 2));
234 or32le(loc, applyMask(0x1ff3ffe, val >> 2));
236235 break;
237236 case R_HEX_B22_PCREL_X:
238 or32le(Loc, applyMask(0x1ff3ffe, Val & 0x3f));
237 or32le(loc, applyMask(0x1ff3ffe, val & 0x3f));
239238 break;
240239 case R_HEX_B32_PCREL_X:
241 or32le(Loc, applyMask(0x0fff3fff, Val >> 6));
240 or32le(loc, applyMask(0x0fff3fff, val >> 6));
242241 break;
243242 case R_HEX_HI16:
244 or32le(Loc, applyMask(0x00c03fff, Val >> 16));
243 or32le(loc, applyMask(0x00c03fff, val >> 16));
245244 break;
246245 case R_HEX_LO16:
247 or32le(Loc, applyMask(0x00c03fff, Val));
246 or32le(loc, applyMask(0x00c03fff, val));
248247 break;
249248 default:
250 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
249 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
251250 break;
252251 }
253252}
254253
255void Hexagon::writePltHeader(uint8_t *Buf) const {
256 const uint8_t PltData[] = {
254void Hexagon::writePltHeader(uint8_t *buf) const {
255 const uint8_t pltData[] = {
257256 0x00, 0x40, 0x00, 0x00, // { immext (#0)
258257 0x1c, 0xc0, 0x49, 0x6a, // r28 = add (pc, ##GOT0@PCREL) } # @GOT0
259258 0x0e, 0x42, 0x9c, 0xe2, // { r14 -= add (r28, #16) # offset of GOTn
......@@ -263,30 +262,30 @@ void Hexagon::writePltHeader(uint8_t *Buf) const {
263262 0x00, 0xc0, 0x9c, 0x52, // jumpr r28 } # call dynamic linker
264263 0x0c, 0xdb, 0x00, 0x54, // trap0(#0xdb) # bring plt0 into 16byte alignment
265264 };
266 memcpy(Buf, PltData, sizeof(PltData));
265 memcpy(buf, pltData, sizeof(pltData));
267266
268267 // 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);
268 uint64_t off = in.gotPlt->getVA() - in.plt->getVA();
269 relocateOne(buf, R_HEX_B32_PCREL_X, off);
270 relocateOne(buf + 4, R_HEX_6_PCREL_X, off);
272271}
273272
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[] = {
273void Hexagon::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
274 uint64_t pltEntryAddr, int32_t index,
275 unsigned relOff) const {
276 const uint8_t inst[] = {
278277 0x00, 0x40, 0x00, 0x00, // { immext (#0)
279278 0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn@PCREL) }
280279 0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14)
281280 0x00, 0xc0, 0x9c, 0x52, // jumpr r28
282281 };
283 memcpy(Buf, Inst, sizeof(Inst));
282 memcpy(buf, inst, sizeof(inst));
284283
285 relocateOne(Buf, R_HEX_B32_PCREL_X, GotPltEntryAddr - PltEntryAddr);
286 relocateOne(Buf + 4, R_HEX_6_PCREL_X, GotPltEntryAddr - PltEntryAddr);
284 relocateOne(buf, R_HEX_B32_PCREL_X, gotPltEntryAddr - pltEntryAddr);
285 relocateOne(buf + 4, R_HEX_6_PCREL_X, gotPltEntryAddr - pltEntryAddr);
287286}
288287
289288TargetInfo *elf::getHexagonTargetInfo() {
290 static Hexagon Target;
291 return &Target;
289 static Hexagon target;
290 return &target;
292291}
deps/lld/ELF/Arch/MSP430.cpp+24-25
......@@ -1,9 +1,8 @@
11//===- MSP430.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -34,20 +33,20 @@ namespace {
3433class MSP430 final : public TargetInfo {
3534public:
3635 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;
36 RelExpr getRelExpr(RelType type, const Symbol &s,
37 const uint8_t *loc) const override;
38 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
4039};
4140} // namespace
4241
4342MSP430::MSP430() {
4443 // mov.b #0, r3
45 TrapInstr = {0x43, 0x43, 0x43, 0x43};
44 trapInstr = {0x43, 0x43, 0x43, 0x43};
4645}
4746
48RelExpr MSP430::getRelExpr(RelType Type, const Symbol &S,
49 const uint8_t *Loc) const {
50 switch (Type) {
47RelExpr MSP430::getRelExpr(RelType type, const Symbol &s,
48 const uint8_t *loc) const {
49 switch (type) {
5150 case R_MSP430_10_PCREL:
5251 case R_MSP430_16_PCREL:
5352 case R_MSP430_16_PCREL_BYTE:
......@@ -60,35 +59,35 @@ RelExpr MSP430::getRelExpr(RelType Type, const Symbol &S,
6059 }
6160}
6261
63void MSP430::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
64 switch (Type) {
62void MSP430::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
63 switch (type) {
6564 case R_MSP430_8:
66 checkIntUInt(Loc, Val, 8, Type);
67 *Loc = Val;
65 checkIntUInt(loc, val, 8, type);
66 *loc = val;
6867 break;
6968 case R_MSP430_16:
7069 case R_MSP430_16_PCREL:
7170 case R_MSP430_16_BYTE:
7271 case R_MSP430_16_PCREL_BYTE:
73 checkIntUInt(Loc, Val, 16, Type);
74 write16le(Loc, Val);
72 checkIntUInt(loc, val, 16, type);
73 write16le(loc, val);
7574 break;
7675 case R_MSP430_32:
77 checkIntUInt(Loc, Val, 32, Type);
78 write32le(Loc, Val);
76 checkIntUInt(loc, val, 32, type);
77 write32le(loc, val);
7978 break;
8079 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));
80 int16_t offset = ((int16_t)val >> 1) - 1;
81 checkInt(loc, offset, 10, type);
82 write16le(loc, (read16le(loc) & 0xFC00) | (offset & 0x3FF));
8483 break;
8584 }
8685 default:
87 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
86 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
8887 }
8988}
9089
9190TargetInfo *elf::getMSP430TargetInfo() {
92 static MSP430 Target;
93 return &Target;
91 static MSP430 target;
92 return &target;
9493}
deps/lld/ELF/Arch/Mips.cpp+336-271
......@@ -1,9 +1,8 @@
11//===- MIPS.cpp -----------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -29,47 +28,47 @@ template <class ELFT> class MIPS final : public TargetInfo {
2928public:
3029 MIPS();
3130 uint32_t calcEFlags() const override;
32 RelExpr getRelExpr(RelType Type, const Symbol &S,
33 const uint8_t *Loc) const override;
34 int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
35 RelType getDynRel(RelType Type) const override;
36 void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
37 void writePltHeader(uint8_t *Buf) const override;
38 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
39 int32_t Index, unsigned RelOff) const override;
40 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
41 uint64_t BranchAddr, const Symbol &S) const override;
42 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
43 bool usesOnlyLowPageBits(RelType Type) const override;
31 RelExpr getRelExpr(RelType type, const Symbol &s,
32 const uint8_t *loc) const override;
33 int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
34 RelType getDynRel(RelType type) const override;
35 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
36 void writePltHeader(uint8_t *buf) const override;
37 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
38 int32_t index, unsigned relOff) const override;
39 bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
40 uint64_t branchAddr, const Symbol &s) const override;
41 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
42 bool usesOnlyLowPageBits(RelType type) const override;
4443};
4544} // namespace
4645
4746template <class ELFT> MIPS<ELFT>::MIPS() {
48 GotPltHeaderEntriesNum = 2;
49 DefaultMaxPageSize = 65536;
50 GotEntrySize = sizeof(typename ELFT::uint);
51 GotPltEntrySize = sizeof(typename ELFT::uint);
52 GotBaseSymInGotPlt = false;
53 PltEntrySize = 16;
54 PltHeaderSize = 32;
55 CopyRel = R_MIPS_COPY;
56 NoneRel = R_MIPS_NONE;
57 PltRel = R_MIPS_JUMP_SLOT;
58 NeedsThunks = true;
47 gotPltHeaderEntriesNum = 2;
48 defaultMaxPageSize = 65536;
49 gotBaseSymInGotPlt = false;
50 pltEntrySize = 16;
51 pltHeaderSize = 32;
52 copyRel = R_MIPS_COPY;
53 noneRel = R_MIPS_NONE;
54 pltRel = R_MIPS_JUMP_SLOT;
55 needsThunks = true;
5956
6057 // Set `sigrie 1` as a trap instruction.
61 write32(TrapInstr.data(), 0x04170001);
58 write32(trapInstr.data(), 0x04170001);
6259
6360 if (ELFT::Is64Bits) {
64 RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
65 TlsGotRel = R_MIPS_TLS_TPREL64;
66 TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
67 TlsOffsetRel = R_MIPS_TLS_DTPREL64;
61 relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62 symbolicRel = R_MIPS_64;
63 tlsGotRel = R_MIPS_TLS_TPREL64;
64 tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
65 tlsOffsetRel = R_MIPS_TLS_DTPREL64;
6866 } else {
69 RelativeRel = R_MIPS_REL32;
70 TlsGotRel = R_MIPS_TLS_TPREL32;
71 TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
72 TlsOffsetRel = R_MIPS_TLS_DTPREL32;
67 relativeRel = R_MIPS_REL32;
68 symbolicRel = R_MIPS_32;
69 tlsGotRel = R_MIPS_TLS_TPREL32;
70 tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
71 tlsOffsetRel = R_MIPS_TLS_DTPREL32;
7372 }
7473}
7574
......@@ -78,13 +77,13 @@ template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
7877}
7978
8079template <class ELFT>
81RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
82 const uint8_t *Loc) const {
80RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
81 const uint8_t *loc) const {
8382 // See comment in the calculateMipsRelChain.
84 if (ELFT::Is64Bits || Config->MipsN32Abi)
85 Type &= 0xff;
83 if (ELFT::Is64Bits || config->mipsN32Abi)
84 type &= 0xff;
8685
87 switch (Type) {
86 switch (type) {
8887 case R_MIPS_JALR:
8988 case R_MICROMIPS_JALR:
9089 return R_HINT;
......@@ -108,9 +107,9 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
108107 // offset between start of function and 'gp' value which by default
109108 // equal to the start of .got section. In that case we consider these
110109 // relocations as relative.
111 if (&S == ElfSym::MipsGpDisp)
110 if (&s == ElfSym::mipsGpDisp)
112111 return R_MIPS_GOT_GP_PC;
113 if (&S == ElfSym::MipsLocalGp)
112 if (&s == ElfSym::mipsLocalGp)
114113 return R_MIPS_GOT_GP;
115114 LLVM_FALLTHROUGH;
116115 case R_MIPS_32:
......@@ -147,7 +146,7 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
147146 return R_PC;
148147 case R_MIPS_GOT16:
149148 case R_MICROMIPS_GOT16:
150 if (S.isLocal())
149 if (s.isLocal())
151150 return R_MIPS_GOT_LOCAL_PAGE;
152151 LLVM_FALLTHROUGH;
153152 case R_MIPS_CALL16:
......@@ -176,209 +175,213 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
176175 case R_MIPS_NONE:
177176 return R_NONE;
178177 default:
179 return R_INVALID;
178 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
179 ") against symbol " + toString(s));
180 return R_NONE;
180181 }
181182}
182183
183template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {
184 if (Type == R_MIPS_32 || Type == R_MIPS_64)
185 return RelativeRel;
184template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType type) const {
185 if (type == symbolicRel)
186 return type;
186187 return R_MIPS_NONE;
187188}
188189
189190template <class ELFT>
190void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
191 uint64_t VA = In.Plt->getVA();
191void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
192 uint64_t va = in.plt->getVA();
192193 if (isMicroMips())
193 VA |= 1;
194 write32<ELFT::TargetEndianness>(Buf, VA);
194 va |= 1;
195 write32<ELFT::TargetEndianness>(buf, va);
195196}
196197
197template <endianness E> static uint32_t readShuffle(const uint8_t *Loc) {
198template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
198199 // The major opcode of a microMIPS instruction needs to appear
199200 // in the first 16-bit word (lowest address) for efficient hardware
200201 // decode so that it knows if the instruction is 16-bit or 32-bit
201202 // as early as possible. To do so, little-endian binaries keep 16-bit
202203 // words in a big-endian order. That is why we have to swap these
203204 // words to get a correct value.
204 uint32_t V = read32<E>(Loc);
205 uint32_t v = read32<E>(loc);
205206 if (E == support::little)
206 return (V << 16) | (V >> 16);
207 return V;
207 return (v << 16) | (v >> 16);
208 return v;
208209}
209210
210211template <endianness E>
211static void writeValue(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
212 uint8_t Shift) {
213 uint32_t Instr = read32<E>(Loc);
214 uint32_t Mask = 0xffffffff >> (32 - BitsSize);
215 uint32_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
216 write32<E>(Loc, Data);
212static void writeValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
213 uint8_t shift) {
214 uint32_t instr = read32<E>(loc);
215 uint32_t mask = 0xffffffff >> (32 - bitsSize);
216 uint32_t data = (instr & ~mask) | ((v >> shift) & mask);
217 write32<E>(loc, data);
217218}
218219
219220template <endianness E>
220static void writeShuffleValue(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
221 uint8_t Shift) {
221static void writeShuffleValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
222 uint8_t shift) {
222223 // See comments in readShuffle for purpose of this code.
223 uint16_t *Words = (uint16_t *)Loc;
224 uint16_t *words = (uint16_t *)loc;
224225 if (E == support::little)
225 std::swap(Words[0], Words[1]);
226 std::swap(words[0], words[1]);
226227
227 writeValue<E>(Loc, V, BitsSize, Shift);
228 writeValue<E>(loc, v, bitsSize, shift);
228229
229230 if (E == support::little)
230 std::swap(Words[0], Words[1]);
231 std::swap(words[0], words[1]);
231232}
232233
233234template <endianness E>
234static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
235 uint8_t Shift) {
236 uint16_t Instr = read16<E>(Loc);
237 uint16_t Mask = 0xffff >> (16 - BitsSize);
238 uint16_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
239 write16<E>(Loc, Data);
235static void writeMicroRelocation16(uint8_t *loc, uint64_t v, uint8_t bitsSize,
236 uint8_t shift) {
237 uint16_t instr = read16<E>(loc);
238 uint16_t mask = 0xffff >> (16 - bitsSize);
239 uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
240 write16<E>(loc, data);
240241}
241242
242template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
243 const endianness E = ELFT::TargetEndianness;
243template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
244 const endianness e = ELFT::TargetEndianness;
244245 if (isMicroMips()) {
245 uint64_t GotPlt = In.GotPlt->getVA();
246 uint64_t Plt = In.Plt->getVA();
246 uint64_t gotPlt = in.gotPlt->getVA();
247 uint64_t plt = in.plt->getVA();
247248 // Overwrite trap instructions written by Writer::writeTrapInstr.
248 memset(Buf, 0, PltHeaderSize);
249
250 write16<E>(Buf, isMipsR6() ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
251 write16<E>(Buf + 4, 0xff23); // lw $25, 0($3)
252 write16<E>(Buf + 8, 0x0535); // subu16 $2, $2, $3
253 write16<E>(Buf + 10, 0x2525); // srl16 $2, $2, 2
254 write16<E>(Buf + 12, 0x3302); // addiu $24, $2, -2
255 write16<E>(Buf + 14, 0xfffe);
256 write16<E>(Buf + 16, 0x0dff); // move $15, $31
249 memset(buf, 0, pltHeaderSize);
250
251 write16<e>(buf, isMipsR6() ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
252 write16<e>(buf + 4, 0xff23); // lw $25, 0($3)
253 write16<e>(buf + 8, 0x0535); // subu16 $2, $2, $3
254 write16<e>(buf + 10, 0x2525); // srl16 $2, $2, 2
255 write16<e>(buf + 12, 0x3302); // addiu $24, $2, -2
256 write16<e>(buf + 14, 0xfffe);
257 write16<e>(buf + 16, 0x0dff); // move $15, $31
257258 if (isMipsR6()) {
258 write16<E>(Buf + 18, 0x0f83); // move $28, $3
259 write16<E>(Buf + 20, 0x472b); // jalrc $25
260 write16<E>(Buf + 22, 0x0c00); // nop
261 relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPlt - Plt);
259 write16<e>(buf + 18, 0x0f83); // move $28, $3
260 write16<e>(buf + 20, 0x472b); // jalrc $25
261 write16<e>(buf + 22, 0x0c00); // nop
262 relocateOne(buf, R_MICROMIPS_PC19_S2, gotPlt - plt);
262263 } else {
263 write16<E>(Buf + 18, 0x45f9); // jalrc $25
264 write16<E>(Buf + 20, 0x0f83); // move $28, $3
265 write16<E>(Buf + 22, 0x0c00); // nop
266 relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPlt - Plt);
264 write16<e>(buf + 18, 0x45f9); // jalrc $25
265 write16<e>(buf + 20, 0x0f83); // move $28, $3
266 write16<e>(buf + 22, 0x0c00); // nop
267 relocateOne(buf, R_MICROMIPS_PC23_S2, gotPlt - plt);
267268 }
268269 return;
269270 }
270271
271 if (Config->MipsN32Abi) {
272 write32<E>(Buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
273 write32<E>(Buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
274 write32<E>(Buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
275 write32<E>(Buf + 12, 0x030ec023); // subu $24, $24, $14
276 write32<E>(Buf + 16, 0x03e07825); // move $15, $31
277 write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2
272 if (config->mipsN32Abi) {
273 write32<e>(buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
274 write32<e>(buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
275 write32<e>(buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
276 write32<e>(buf + 12, 0x030ec023); // subu $24, $24, $14
277 write32<e>(buf + 16, 0x03e07825); // move $15, $31
278 write32<e>(buf + 20, 0x0018c082); // srl $24, $24, 2
278279 } else if (ELFT::Is64Bits) {
279 write32<E>(Buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
280 write32<E>(Buf + 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
281 write32<E>(Buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
282 write32<E>(Buf + 12, 0x030ec023); // subu $24, $24, $14
283 write32<E>(Buf + 16, 0x03e07825); // move $15, $31
284 write32<E>(Buf + 20, 0x0018c0c2); // srl $24, $24, 3
280 write32<e>(buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
281 write32<e>(buf + 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
282 write32<e>(buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
283 write32<e>(buf + 12, 0x030ec023); // subu $24, $24, $14
284 write32<e>(buf + 16, 0x03e07825); // move $15, $31
285 write32<e>(buf + 20, 0x0018c0c2); // srl $24, $24, 3
285286 } else {
286 write32<E>(Buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
287 write32<E>(Buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
288 write32<E>(Buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
289 write32<E>(Buf + 12, 0x031cc023); // subu $24, $24, $28
290 write32<E>(Buf + 16, 0x03e07825); // move $15, $31
291 write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2
287 write32<e>(buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
288 write32<e>(buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
289 write32<e>(buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
290 write32<e>(buf + 12, 0x031cc023); // subu $24, $24, $28
291 write32<e>(buf + 16, 0x03e07825); // move $15, $31
292 write32<e>(buf + 20, 0x0018c082); // srl $24, $24, 2
292293 }
293294
294 uint32_t JalrInst = Config->ZHazardplt ? 0x0320fc09 : 0x0320f809;
295 write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25
296 write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
295 uint32_t jalrInst = config->zHazardplt ? 0x0320fc09 : 0x0320f809;
296 write32<e>(buf + 24, jalrInst); // jalr.hb $25 or jalr $25
297 write32<e>(buf + 28, 0x2718fffe); // subu $24, $24, 2
297298
298 uint64_t GotPlt = In.GotPlt->getVA();
299 writeValue<E>(Buf, GotPlt + 0x8000, 16, 16);
300 writeValue<E>(Buf + 4, GotPlt, 16, 0);
301 writeValue<E>(Buf + 8, GotPlt, 16, 0);
299 uint64_t gotPlt = in.gotPlt->getVA();
300 writeValue<e>(buf, gotPlt + 0x8000, 16, 16);
301 writeValue<e>(buf + 4, gotPlt, 16, 0);
302 writeValue<e>(buf + 8, gotPlt, 16, 0);
302303}
303304
304305template <class ELFT>
305void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
306 uint64_t PltEntryAddr, int32_t Index,
307 unsigned RelOff) const {
308 const endianness E = ELFT::TargetEndianness;
306void MIPS<ELFT>::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
307 uint64_t pltEntryAddr, int32_t index,
308 unsigned relOff) const {
309 const endianness e = ELFT::TargetEndianness;
309310 if (isMicroMips()) {
310311 // Overwrite trap instructions written by Writer::writeTrapInstr.
311 memset(Buf, 0, PltEntrySize);
312 memset(buf, 0, pltEntrySize);
312313
313314 if (isMipsR6()) {
314 write16<E>(Buf, 0x7840); // addiupc $2, (GOTPLT) - .
315 write16<E>(Buf + 4, 0xff22); // lw $25, 0($2)
316 write16<E>(Buf + 8, 0x0f02); // move $24, $2
317 write16<E>(Buf + 10, 0x4723); // jrc $25 / jr16 $25
318 relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPltEntryAddr - PltEntryAddr);
315 write16<e>(buf, 0x7840); // addiupc $2, (GOTPLT) - .
316 write16<e>(buf + 4, 0xff22); // lw $25, 0($2)
317 write16<e>(buf + 8, 0x0f02); // move $24, $2
318 write16<e>(buf + 10, 0x4723); // jrc $25 / jr16 $25
319 relocateOne(buf, R_MICROMIPS_PC19_S2, gotPltEntryAddr - pltEntryAddr);
319320 } else {
320 write16<E>(Buf, 0x7900); // addiupc $2, (GOTPLT) - .
321 write16<E>(Buf + 4, 0xff22); // lw $25, 0($2)
322 write16<E>(Buf + 8, 0x4599); // jrc $25 / jr16 $25
323 write16<E>(Buf + 10, 0x0f02); // move $24, $2
324 relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPltEntryAddr - PltEntryAddr);
321 write16<e>(buf, 0x7900); // addiupc $2, (GOTPLT) - .
322 write16<e>(buf + 4, 0xff22); // lw $25, 0($2)
323 write16<e>(buf + 8, 0x4599); // jrc $25 / jr16 $25
324 write16<e>(buf + 10, 0x0f02); // move $24, $2
325 relocateOne(buf, R_MICROMIPS_PC23_S2, gotPltEntryAddr - pltEntryAddr);
325326 }
326327 return;
327328 }
328329
329 uint32_t JrInst = isMipsR6() ? (Config->ZHazardplt ? 0x03200409 : 0x03200009)
330 : (Config->ZHazardplt ? 0x03200408 : 0x03200008);
331
332 write32<E>(Buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
333 write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15)
334 write32<E>(Buf + 8, JrInst); // jr $25 / jr.hb $25
335 write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry)
336 writeValue<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16);
337 writeValue<E>(Buf + 4, GotPltEntryAddr, 16, 0);
338 writeValue<E>(Buf + 12, GotPltEntryAddr, 16, 0);
330 uint32_t loadInst = ELFT::Is64Bits ? 0xddf90000 : 0x8df90000;
331 uint32_t jrInst = isMipsR6() ? (config->zHazardplt ? 0x03200409 : 0x03200009)
332 : (config->zHazardplt ? 0x03200408 : 0x03200008);
333 uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;
334
335 write32<e>(buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
336 write32<e>(buf + 4, loadInst); // l[wd] $25, %lo(.got.plt entry)($15)
337 write32<e>(buf + 8, jrInst); // jr $25 / jr.hb $25
338 write32<e>(buf + 12, addInst); // [d]addiu $24, $15, %lo(.got.plt entry)
339 writeValue<e>(buf, gotPltEntryAddr + 0x8000, 16, 16);
340 writeValue<e>(buf + 4, gotPltEntryAddr, 16, 0);
341 writeValue<e>(buf + 12, gotPltEntryAddr, 16, 0);
339342}
340343
341344template <class ELFT>
342bool MIPS<ELFT>::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
343 uint64_t BranchAddr, const Symbol &S) const {
345bool MIPS<ELFT>::needsThunk(RelExpr expr, RelType type, const InputFile *file,
346 uint64_t branchAddr, const Symbol &s) const {
344347 // Any MIPS PIC code function is invoked with its address in register $t9.
345348 // So if we have a branch instruction from non-PIC code to the PIC one
346349 // we cannot make the jump directly and need to create a small stubs
347350 // to save the target function address.
348351 // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
349 if (Type != R_MIPS_26 && Type != R_MICROMIPS_26_S1 &&
350 Type != R_MICROMIPS_PC26_S1)
352 if (type != R_MIPS_26 && type != R_MIPS_PC26_S2 &&
353 type != R_MICROMIPS_26_S1 && type != R_MICROMIPS_PC26_S1)
351354 return false;
352 auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
353 if (!F)
355 auto *f = dyn_cast_or_null<ObjFile<ELFT>>(file);
356 if (!f)
354357 return false;
355358 // If current file has PIC code, LA25 stub is not required.
356 if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
359 if (f->getObj().getHeader()->e_flags & EF_MIPS_PIC)
357360 return false;
358 auto *D = dyn_cast<Defined>(&S);
361 auto *d = dyn_cast<Defined>(&s);
359362 // LA25 is required if target file has PIC code
360363 // or target symbol is a PIC symbol.
361 return D && isMipsPIC<ELFT>(D);
364 return d && isMipsPIC<ELFT>(d);
362365}
363366
364367template <class ELFT>
365int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
366 const endianness E = ELFT::TargetEndianness;
367 switch (Type) {
368int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
369 const endianness e = ELFT::TargetEndianness;
370 switch (type) {
368371 case R_MIPS_32:
369372 case R_MIPS_GPREL32:
370373 case R_MIPS_TLS_DTPREL32:
371374 case R_MIPS_TLS_TPREL32:
372 return SignExtend64<32>(read32<E>(Buf));
375 return SignExtend64<32>(read32<e>(buf));
373376 case R_MIPS_26:
374377 // FIXME (simon): If the relocation target symbol is not a PLT entry
375378 // we should use another expression for calculation:
376379 // ((A << 2) | (P & 0xf0000000)) >> 2
377 return SignExtend64<28>(read32<E>(Buf) << 2);
380 return SignExtend64<28>(read32<e>(buf) << 2);
378381 case R_MIPS_GOT16:
379382 case R_MIPS_HI16:
380383 case R_MIPS_PCHI16:
381 return SignExtend64<16>(read32<E>(Buf)) << 16;
384 return SignExtend64<16>(read32<e>(buf)) << 16;
382385 case R_MIPS_GPREL16:
383386 case R_MIPS_LO16:
384387 case R_MIPS_PCLO16:
......@@ -386,54 +389,54 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
386389 case R_MIPS_TLS_DTPREL_LO16:
387390 case R_MIPS_TLS_TPREL_HI16:
388391 case R_MIPS_TLS_TPREL_LO16:
389 return SignExtend64<16>(read32<E>(Buf));
392 return SignExtend64<16>(read32<e>(buf));
390393 case R_MICROMIPS_GOT16:
391394 case R_MICROMIPS_HI16:
392 return SignExtend64<16>(readShuffle<E>(Buf)) << 16;
395 return SignExtend64<16>(readShuffle<e>(buf)) << 16;
393396 case R_MICROMIPS_GPREL16:
394397 case R_MICROMIPS_LO16:
395398 case R_MICROMIPS_TLS_DTPREL_HI16:
396399 case R_MICROMIPS_TLS_DTPREL_LO16:
397400 case R_MICROMIPS_TLS_TPREL_HI16:
398401 case R_MICROMIPS_TLS_TPREL_LO16:
399 return SignExtend64<16>(readShuffle<E>(Buf));
402 return SignExtend64<16>(readShuffle<e>(buf));
400403 case R_MICROMIPS_GPREL7_S2:
401 return SignExtend64<9>(readShuffle<E>(Buf) << 2);
404 return SignExtend64<9>(readShuffle<e>(buf) << 2);
402405 case R_MIPS_PC16:
403 return SignExtend64<18>(read32<E>(Buf) << 2);
406 return SignExtend64<18>(read32<e>(buf) << 2);
404407 case R_MIPS_PC19_S2:
405 return SignExtend64<21>(read32<E>(Buf) << 2);
408 return SignExtend64<21>(read32<e>(buf) << 2);
406409 case R_MIPS_PC21_S2:
407 return SignExtend64<23>(read32<E>(Buf) << 2);
410 return SignExtend64<23>(read32<e>(buf) << 2);
408411 case R_MIPS_PC26_S2:
409 return SignExtend64<28>(read32<E>(Buf) << 2);
412 return SignExtend64<28>(read32<e>(buf) << 2);
410413 case R_MIPS_PC32:
411 return SignExtend64<32>(read32<E>(Buf));
414 return SignExtend64<32>(read32<e>(buf));
412415 case R_MICROMIPS_26_S1:
413 return SignExtend64<27>(readShuffle<E>(Buf) << 1);
416 return SignExtend64<27>(readShuffle<e>(buf) << 1);
414417 case R_MICROMIPS_PC7_S1:
415 return SignExtend64<8>(read16<E>(Buf) << 1);
418 return SignExtend64<8>(read16<e>(buf) << 1);
416419 case R_MICROMIPS_PC10_S1:
417 return SignExtend64<11>(read16<E>(Buf) << 1);
420 return SignExtend64<11>(read16<e>(buf) << 1);
418421 case R_MICROMIPS_PC16_S1:
419 return SignExtend64<17>(readShuffle<E>(Buf) << 1);
422 return SignExtend64<17>(readShuffle<e>(buf) << 1);
420423 case R_MICROMIPS_PC18_S3:
421 return SignExtend64<21>(readShuffle<E>(Buf) << 3);
424 return SignExtend64<21>(readShuffle<e>(buf) << 3);
422425 case R_MICROMIPS_PC19_S2:
423 return SignExtend64<21>(readShuffle<E>(Buf) << 2);
426 return SignExtend64<21>(readShuffle<e>(buf) << 2);
424427 case R_MICROMIPS_PC21_S1:
425 return SignExtend64<22>(readShuffle<E>(Buf) << 1);
428 return SignExtend64<22>(readShuffle<e>(buf) << 1);
426429 case R_MICROMIPS_PC23_S2:
427 return SignExtend64<25>(readShuffle<E>(Buf) << 2);
430 return SignExtend64<25>(readShuffle<e>(buf) << 2);
428431 case R_MICROMIPS_PC26_S1:
429 return SignExtend64<27>(readShuffle<E>(Buf) << 1);
432 return SignExtend64<27>(readShuffle<e>(buf) << 1);
430433 default:
431434 return 0;
432435 }
433436}
434437
435438static std::pair<uint32_t, uint64_t>
436calculateMipsRelChain(uint8_t *Loc, RelType Type, uint64_t Val) {
439calculateMipsRelChain(uint8_t *loc, RelType type, uint64_t val) {
437440 // MIPS N64 ABI packs multiple relocations into the single relocation
438441 // record. In general, all up to three relocations can have arbitrary
439442 // types. In fact, Clang and GCC uses only a few combinations. For now,
......@@ -446,72 +449,134 @@ calculateMipsRelChain(uint8_t *Loc, RelType Type, uint64_t Val) {
446449 // relocations used to modify result of the first one: extend it to
447450 // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
448451 // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
449 RelType Type2 = (Type >> 8) & 0xff;
450 RelType Type3 = (Type >> 16) & 0xff;
451 if (Type2 == R_MIPS_NONE && Type3 == R_MIPS_NONE)
452 return std::make_pair(Type, Val);
453 if (Type2 == R_MIPS_64 && Type3 == R_MIPS_NONE)
454 return std::make_pair(Type2, Val);
455 if (Type2 == R_MIPS_SUB && (Type3 == R_MIPS_HI16 || Type3 == R_MIPS_LO16))
456 return std::make_pair(Type3, -Val);
457 error(getErrorLocation(Loc) + "unsupported relocations combination " +
458 Twine(Type));
459 return std::make_pair(Type & 0xff, Val);
452 RelType type2 = (type >> 8) & 0xff;
453 RelType type3 = (type >> 16) & 0xff;
454 if (type2 == R_MIPS_NONE && type3 == R_MIPS_NONE)
455 return std::make_pair(type, val);
456 if (type2 == R_MIPS_64 && type3 == R_MIPS_NONE)
457 return std::make_pair(type2, val);
458 if (type2 == R_MIPS_SUB && (type3 == R_MIPS_HI16 || type3 == R_MIPS_LO16))
459 return std::make_pair(type3, -val);
460 error(getErrorLocation(loc) + "unsupported relocations combination " +
461 Twine(type));
462 return std::make_pair(type & 0xff, val);
463}
464
465static bool isBranchReloc(RelType type) {
466 return type == R_MIPS_26 || type == R_MIPS_PC26_S2 ||
467 type == R_MIPS_PC21_S2 || type == R_MIPS_PC16;
468}
469
470static bool isMicroBranchReloc(RelType type) {
471 return type == R_MICROMIPS_26_S1 || type == R_MICROMIPS_PC16_S1 ||
472 type == R_MICROMIPS_PC10_S1 || type == R_MICROMIPS_PC7_S1;
460473}
461474
462475template <class ELFT>
463void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
464 const endianness E = ELFT::TargetEndianness;
476static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
477 // Here we need to detect jump/branch from regular MIPS code
478 // to a microMIPS target and vice versa. In that cases jump
479 // instructions need to be replaced by their "cross-mode"
480 // equivalents.
481 const endianness e = ELFT::TargetEndianness;
482 bool isMicroTgt = val & 0x1;
483 bool isCrossJump = (isMicroTgt && isBranchReloc(type)) ||
484 (!isMicroTgt && isMicroBranchReloc(type));
485 if (!isCrossJump)
486 return val;
487
488 switch (type) {
489 case R_MIPS_26: {
490 uint32_t inst = read32<e>(loc) >> 26;
491 if (inst == 0x3 || inst == 0x1d) { // JAL or JALX
492 writeValue<e>(loc, 0x1d << 26, 32, 0);
493 return val;
494 }
495 break;
496 }
497 case R_MICROMIPS_26_S1: {
498 uint32_t inst = readShuffle<e>(loc) >> 26;
499 if (inst == 0x3d || inst == 0x3c) { // JAL32 or JALX32
500 val >>= 1;
501 writeShuffleValue<e>(loc, 0x3c << 26, 32, 0);
502 return val;
503 }
504 break;
505 }
506 case R_MIPS_PC26_S2:
507 case R_MIPS_PC21_S2:
508 case R_MIPS_PC16:
509 case R_MICROMIPS_PC16_S1:
510 case R_MICROMIPS_PC10_S1:
511 case R_MICROMIPS_PC7_S1:
512 // FIXME (simon): Support valid branch relocations.
513 break;
514 default:
515 llvm_unreachable("unexpected jump/branch relocation");
516 }
517
518 error(getErrorLocation(loc) +
519 "unsupported jump/branch instruction between ISA modes referenced by " +
520 toString(type) + " relocation");
521 return val;
522}
523
524template <class ELFT>
525void MIPS<ELFT>::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
526 const endianness e = ELFT::TargetEndianness;
527
528 if (ELFT::Is64Bits || config->mipsN32Abi)
529 std::tie(type, val) = calculateMipsRelChain(loc, type, val);
465530
466 if (ELFT::Is64Bits || Config->MipsN32Abi)
467 std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val);
531 // Detect cross-mode jump/branch and fix instruction.
532 val = fixupCrossModeJump<ELFT>(loc, type, val);
468533
469534 // Thread pointer and DRP offsets from the start of TLS data area.
470535 // https://www.linux-mips.org/wiki/NPTL
471 if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 ||
472 Type == R_MIPS_TLS_DTPREL32 || Type == R_MIPS_TLS_DTPREL64 ||
473 Type == R_MICROMIPS_TLS_DTPREL_HI16 ||
474 Type == R_MICROMIPS_TLS_DTPREL_LO16) {
475 Val -= 0x8000;
476 } else if (Type == R_MIPS_TLS_TPREL_HI16 || Type == R_MIPS_TLS_TPREL_LO16 ||
477 Type == R_MIPS_TLS_TPREL32 || Type == R_MIPS_TLS_TPREL64 ||
478 Type == R_MICROMIPS_TLS_TPREL_HI16 ||
479 Type == R_MICROMIPS_TLS_TPREL_LO16) {
480 Val -= 0x7000;
536 if (type == R_MIPS_TLS_DTPREL_HI16 || type == R_MIPS_TLS_DTPREL_LO16 ||
537 type == R_MIPS_TLS_DTPREL32 || type == R_MIPS_TLS_DTPREL64 ||
538 type == R_MICROMIPS_TLS_DTPREL_HI16 ||
539 type == R_MICROMIPS_TLS_DTPREL_LO16) {
540 val -= 0x8000;
541 } else if (type == R_MIPS_TLS_TPREL_HI16 || type == R_MIPS_TLS_TPREL_LO16 ||
542 type == R_MIPS_TLS_TPREL32 || type == R_MIPS_TLS_TPREL64 ||
543 type == R_MICROMIPS_TLS_TPREL_HI16 ||
544 type == R_MICROMIPS_TLS_TPREL_LO16) {
545 val -= 0x7000;
481546 }
482547
483 switch (Type) {
548 switch (type) {
484549 case R_MIPS_32:
485550 case R_MIPS_GPREL32:
486551 case R_MIPS_TLS_DTPREL32:
487552 case R_MIPS_TLS_TPREL32:
488 write32<E>(Loc, Val);
553 write32<e>(loc, val);
489554 break;
490555 case R_MIPS_64:
491556 case R_MIPS_TLS_DTPREL64:
492557 case R_MIPS_TLS_TPREL64:
493 write64<E>(Loc, Val);
558 write64<e>(loc, val);
494559 break;
495560 case R_MIPS_26:
496 writeValue<E>(Loc, Val, 26, 2);
561 writeValue<e>(loc, val, 26, 2);
497562 break;
498563 case R_MIPS_GOT16:
499564 // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
500565 // is updated addend (not a GOT index). In that case write high 16 bits
501566 // to store a correct addend value.
502 if (Config->Relocatable) {
503 writeValue<E>(Loc, Val + 0x8000, 16, 16);
567 if (config->relocatable) {
568 writeValue<e>(loc, val + 0x8000, 16, 16);
504569 } else {
505 checkInt(Loc, Val, 16, Type);
506 writeValue<E>(Loc, Val, 16, 0);
570 checkInt(loc, val, 16, type);
571 writeValue<e>(loc, val, 16, 0);
507572 }
508573 break;
509574 case R_MICROMIPS_GOT16:
510 if (Config->Relocatable) {
511 writeShuffleValue<E>(Loc, Val + 0x8000, 16, 16);
575 if (config->relocatable) {
576 writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
512577 } else {
513 checkInt(Loc, Val, 16, Type);
514 writeShuffleValue<E>(Loc, Val, 16, 0);
578 checkInt(loc, val, 16, type);
579 writeShuffleValue<e>(loc, val, 16, 0);
515580 }
516581 break;
517582 case R_MIPS_CALL16:
......@@ -521,7 +586,7 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
521586 case R_MIPS_TLS_GD:
522587 case R_MIPS_TLS_GOTTPREL:
523588 case R_MIPS_TLS_LDM:
524 checkInt(Loc, Val, 16, Type);
589 checkInt(loc, val, 16, type);
525590 LLVM_FALLTHROUGH;
526591 case R_MIPS_CALL_LO16:
527592 case R_MIPS_GOT_LO16:
......@@ -530,13 +595,13 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
530595 case R_MIPS_PCLO16:
531596 case R_MIPS_TLS_DTPREL_LO16:
532597 case R_MIPS_TLS_TPREL_LO16:
533 writeValue<E>(Loc, Val, 16, 0);
598 writeValue<e>(loc, val, 16, 0);
534599 break;
535600 case R_MICROMIPS_GPREL16:
536601 case R_MICROMIPS_TLS_GD:
537602 case R_MICROMIPS_TLS_LDM:
538 checkInt(Loc, Val, 16, Type);
539 writeShuffleValue<E>(Loc, Val, 16, 0);
603 checkInt(loc, val, 16, type);
604 writeShuffleValue<e>(loc, val, 16, 0);
540605 break;
541606 case R_MICROMIPS_CALL16:
542607 case R_MICROMIPS_CALL_LO16:
......@@ -544,11 +609,11 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
544609 case R_MICROMIPS_TLS_DTPREL_LO16:
545610 case R_MICROMIPS_TLS_GOTTPREL:
546611 case R_MICROMIPS_TLS_TPREL_LO16:
547 writeShuffleValue<E>(Loc, Val, 16, 0);
612 writeShuffleValue<e>(loc, val, 16, 0);
548613 break;
549614 case R_MICROMIPS_GPREL7_S2:
550 checkInt(Loc, Val, 7, Type);
551 writeShuffleValue<E>(Loc, Val, 7, 2);
615 checkInt(loc, val, 7, type);
616 writeShuffleValue<e>(loc, val, 7, 2);
552617 break;
553618 case R_MIPS_CALL_HI16:
554619 case R_MIPS_GOT_HI16:
......@@ -556,113 +621,113 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
556621 case R_MIPS_PCHI16:
557622 case R_MIPS_TLS_DTPREL_HI16:
558623 case R_MIPS_TLS_TPREL_HI16:
559 writeValue<E>(Loc, Val + 0x8000, 16, 16);
624 writeValue<e>(loc, val + 0x8000, 16, 16);
560625 break;
561626 case R_MICROMIPS_CALL_HI16:
562627 case R_MICROMIPS_GOT_HI16:
563628 case R_MICROMIPS_HI16:
564629 case R_MICROMIPS_TLS_DTPREL_HI16:
565630 case R_MICROMIPS_TLS_TPREL_HI16:
566 writeShuffleValue<E>(Loc, Val + 0x8000, 16, 16);
631 writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
567632 break;
568633 case R_MIPS_HIGHER:
569 writeValue<E>(Loc, Val + 0x80008000, 16, 32);
634 writeValue<e>(loc, val + 0x80008000, 16, 32);
570635 break;
571636 case R_MIPS_HIGHEST:
572 writeValue<E>(Loc, Val + 0x800080008000, 16, 48);
637 writeValue<e>(loc, val + 0x800080008000, 16, 48);
573638 break;
574639 case R_MIPS_JALR:
575640 case R_MICROMIPS_JALR:
576641 // Ignore this optimization relocation for now
577642 break;
578643 case R_MIPS_PC16:
579 checkAlignment(Loc, Val, 4, Type);
580 checkInt(Loc, Val, 18, Type);
581 writeValue<E>(Loc, Val, 16, 2);
644 checkAlignment(loc, val, 4, type);
645 checkInt(loc, val, 18, type);
646 writeValue<e>(loc, val, 16, 2);
582647 break;
583648 case R_MIPS_PC19_S2:
584 checkAlignment(Loc, Val, 4, Type);
585 checkInt(Loc, Val, 21, Type);
586 writeValue<E>(Loc, Val, 19, 2);
649 checkAlignment(loc, val, 4, type);
650 checkInt(loc, val, 21, type);
651 writeValue<e>(loc, val, 19, 2);
587652 break;
588653 case R_MIPS_PC21_S2:
589 checkAlignment(Loc, Val, 4, Type);
590 checkInt(Loc, Val, 23, Type);
591 writeValue<E>(Loc, Val, 21, 2);
654 checkAlignment(loc, val, 4, type);
655 checkInt(loc, val, 23, type);
656 writeValue<e>(loc, val, 21, 2);
592657 break;
593658 case R_MIPS_PC26_S2:
594 checkAlignment(Loc, Val, 4, Type);
595 checkInt(Loc, Val, 28, Type);
596 writeValue<E>(Loc, Val, 26, 2);
659 checkAlignment(loc, val, 4, type);
660 checkInt(loc, val, 28, type);
661 writeValue<e>(loc, val, 26, 2);
597662 break;
598663 case R_MIPS_PC32:
599 writeValue<E>(Loc, Val, 32, 0);
664 writeValue<e>(loc, val, 32, 0);
600665 break;
601666 case R_MICROMIPS_26_S1:
602667 case R_MICROMIPS_PC26_S1:
603 checkInt(Loc, Val, 27, Type);
604 writeShuffleValue<E>(Loc, Val, 26, 1);
668 checkInt(loc, val, 27, type);
669 writeShuffleValue<e>(loc, val, 26, 1);
605670 break;
606671 case R_MICROMIPS_PC7_S1:
607 checkInt(Loc, Val, 8, Type);
608 writeMicroRelocation16<E>(Loc, Val, 7, 1);
672 checkInt(loc, val, 8, type);
673 writeMicroRelocation16<e>(loc, val, 7, 1);
609674 break;
610675 case R_MICROMIPS_PC10_S1:
611 checkInt(Loc, Val, 11, Type);
612 writeMicroRelocation16<E>(Loc, Val, 10, 1);
676 checkInt(loc, val, 11, type);
677 writeMicroRelocation16<e>(loc, val, 10, 1);
613678 break;
614679 case R_MICROMIPS_PC16_S1:
615 checkInt(Loc, Val, 17, Type);
616 writeShuffleValue<E>(Loc, Val, 16, 1);
680 checkInt(loc, val, 17, type);
681 writeShuffleValue<e>(loc, val, 16, 1);
617682 break;
618683 case R_MICROMIPS_PC18_S3:
619 checkInt(Loc, Val, 21, Type);
620 writeShuffleValue<E>(Loc, Val, 18, 3);
684 checkInt(loc, val, 21, type);
685 writeShuffleValue<e>(loc, val, 18, 3);
621686 break;
622687 case R_MICROMIPS_PC19_S2:
623 checkInt(Loc, Val, 21, Type);
624 writeShuffleValue<E>(Loc, Val, 19, 2);
688 checkInt(loc, val, 21, type);
689 writeShuffleValue<e>(loc, val, 19, 2);
625690 break;
626691 case R_MICROMIPS_PC21_S1:
627 checkInt(Loc, Val, 22, Type);
628 writeShuffleValue<E>(Loc, Val, 21, 1);
692 checkInt(loc, val, 22, type);
693 writeShuffleValue<e>(loc, val, 21, 1);
629694 break;
630695 case R_MICROMIPS_PC23_S2:
631 checkInt(Loc, Val, 25, Type);
632 writeShuffleValue<E>(Loc, Val, 23, 2);
696 checkInt(loc, val, 25, type);
697 writeShuffleValue<e>(loc, val, 23, 2);
633698 break;
634699 default:
635 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
700 llvm_unreachable("unknown relocation");
636701 }
637702}
638703
639template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const {
640 return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST ||
641 Type == R_MICROMIPS_LO16;
704template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
705 return type == R_MIPS_LO16 || type == R_MIPS_GOT_OFST ||
706 type == R_MICROMIPS_LO16;
642707}
643708
644709// Return true if the symbol is a PIC function.
645template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) {
646 if (!Sym->isFunc())
710template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
711 if (!sym->isFunc())
647712 return false;
648713
649 if (Sym->StOther & STO_MIPS_PIC)
714 if (sym->stOther & STO_MIPS_PIC)
650715 return true;
651716
652 if (!Sym->Section)
717 if (!sym->section)
653718 return false;
654719
655 ObjFile<ELFT> *File =
656 cast<InputSectionBase>(Sym->Section)->template getFile<ELFT>();
657 if (!File)
720 ObjFile<ELFT> *file =
721 cast<InputSectionBase>(sym->section)->template getFile<ELFT>();
722 if (!file)
658723 return false;
659724
660 return File->getObj().getHeader()->e_flags & EF_MIPS_PIC;
725 return file->getObj().getHeader()->e_flags & EF_MIPS_PIC;
661726}
662727
663728template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
664 static MIPS<ELFT> Target;
665 return &Target;
729 static MIPS<ELFT> target;
730 return &target;
666731}
667732
668733template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
deps/lld/ELF/Arch/MipsArchTree.cpp+119-120
......@@ -1,9 +1,8 @@
11//===- MipsArchTree.cpp --------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===---------------------------------------------------------------------===//
98//
......@@ -29,18 +28,18 @@ using namespace lld::elf;
2928
3029namespace {
3130struct ArchTreeEdge {
32 uint32_t Child;
33 uint32_t Parent;
31 uint32_t child;
32 uint32_t parent;
3433};
3534
3635struct FileFlags {
37 InputFile *File;
38 uint32_t Flags;
36 InputFile *file;
37 uint32_t flags;
3938};
4039} // namespace
4140
42static StringRef getAbiName(uint32_t Flags) {
43 switch (Flags) {
41static StringRef getAbiName(uint32_t flags) {
42 switch (flags) {
4443 case 0:
4544 return "n64";
4645 case EF_MIPS_ABI2:
......@@ -58,76 +57,76 @@ static StringRef getAbiName(uint32_t Flags) {
5857 }
5958}
6059
61static StringRef getNanName(bool IsNan2008) {
62 return IsNan2008 ? "2008" : "legacy";
60static StringRef getNanName(bool isNan2008) {
61 return isNan2008 ? "2008" : "legacy";
6362}
6463
65static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; }
64static StringRef getFpName(bool isFp64) { return isFp64 ? "64" : "32"; }
6665
67static void checkFlags(ArrayRef<FileFlags> Files) {
68 assert(!Files.empty() && "expected non-empty file list");
66static void checkFlags(ArrayRef<FileFlags> files) {
67 assert(!files.empty() && "expected non-empty file list");
6968
70 uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
71 bool Nan = Files[0].Flags & EF_MIPS_NAN2008;
72 bool Fp = Files[0].Flags & EF_MIPS_FP64;
69 uint32_t abi = files[0].flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
70 bool nan = files[0].flags & EF_MIPS_NAN2008;
71 bool fp = files[0].flags & EF_MIPS_FP64;
7372
74 for (const FileFlags &F : Files) {
75 if (Config->Is64 && F.Flags & EF_MIPS_MICROMIPS)
76 error(toString(F.File) + ": microMIPS 64-bit is not supported");
73 for (const FileFlags &f : files) {
74 if (config->is64 && f.flags & EF_MIPS_MICROMIPS)
75 error(toString(f.file) + ": microMIPS 64-bit is not supported");
7776
78 uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
79 if (ABI != ABI2)
80 error(toString(F.File) + ": ABI '" + getAbiName(ABI2) +
81 "' is incompatible with target ABI '" + getAbiName(ABI) + "'");
77 uint32_t abi2 = f.flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
78 if (abi != abi2)
79 error(toString(f.file) + ": ABI '" + getAbiName(abi2) +
80 "' is incompatible with target ABI '" + getAbiName(abi) + "'");
8281
83 bool Nan2 = F.Flags & EF_MIPS_NAN2008;
84 if (Nan != Nan2)
85 error(toString(F.File) + ": -mnan=" + getNanName(Nan2) +
86 " is incompatible with target -mnan=" + getNanName(Nan));
82 bool nan2 = f.flags & EF_MIPS_NAN2008;
83 if (nan != nan2)
84 error(toString(f.file) + ": -mnan=" + getNanName(nan2) +
85 " is incompatible with target -mnan=" + getNanName(nan));
8786
88 bool Fp2 = F.Flags & EF_MIPS_FP64;
89 if (Fp != Fp2)
90 error(toString(F.File) + ": -mfp" + getFpName(Fp2) +
91 " is incompatible with target -mfp" + getFpName(Fp));
87 bool fp2 = f.flags & EF_MIPS_FP64;
88 if (fp != fp2)
89 error(toString(f.file) + ": -mfp" + getFpName(fp2) +
90 " is incompatible with target -mfp" + getFpName(fp));
9291 }
9392}
9493
95static uint32_t getMiscFlags(ArrayRef<FileFlags> Files) {
96 uint32_t Ret = 0;
97 for (const FileFlags &F : Files)
98 Ret |= F.Flags &
94static uint32_t getMiscFlags(ArrayRef<FileFlags> files) {
95 uint32_t ret = 0;
96 for (const FileFlags &f : files)
97 ret |= f.flags &
9998 (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER |
10099 EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE);
101 return Ret;
100 return ret;
102101}
103102
104static uint32_t getPicFlags(ArrayRef<FileFlags> Files) {
103static uint32_t getPicFlags(ArrayRef<FileFlags> files) {
105104 // Check PIC/non-PIC compatibility.
106 bool IsPic = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
107 for (const FileFlags &F : Files.slice(1)) {
108 bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
109 if (IsPic && !IsPic2)
110 warn(toString(F.File) +
105 bool isPic = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
106 for (const FileFlags &f : files.slice(1)) {
107 bool isPic2 = f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
108 if (isPic && !isPic2)
109 warn(toString(f.file) +
111110 ": linking non-abicalls code with abicalls code " +
112 toString(Files[0].File));
113 if (!IsPic && IsPic2)
114 warn(toString(F.File) +
111 toString(files[0].file));
112 if (!isPic && isPic2)
113 warn(toString(f.file) +
115114 ": linking abicalls code with non-abicalls code " +
116 toString(Files[0].File));
115 toString(files[0].file));
117116 }
118117
119118 // Compute the result PIC/non-PIC flag.
120 uint32_t Ret = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
121 for (const FileFlags &F : Files.slice(1))
122 Ret &= F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
119 uint32_t ret = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
120 for (const FileFlags &f : files.slice(1))
121 ret &= f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
123122
124123 // PIC code is inherently CPIC and may not set CPIC flag explicitly.
125 if (Ret & EF_MIPS_PIC)
126 Ret |= EF_MIPS_CPIC;
127 return Ret;
124 if (ret & EF_MIPS_PIC)
125 ret |= EF_MIPS_CPIC;
126 return ret;
128127}
129128
130static ArchTreeEdge ArchTree[] = {
129static ArchTreeEdge archTree[] = {
131130 // MIPS32R6 and MIPS64R6 are not compatible with other extensions
132131 // MIPS64R2 extensions.
133132 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2},
......@@ -167,25 +166,25 @@ static ArchTreeEdge ArchTree[] = {
167166 {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
168167};
169168
170static bool isArchMatched(uint32_t New, uint32_t Res) {
171 if (New == Res)
169static bool isArchMatched(uint32_t New, uint32_t res) {
170 if (New == res)
172171 return true;
173 if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, Res))
172 if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, res))
174173 return true;
175 if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, Res))
174 if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, res))
176175 return true;
177 for (const auto &Edge : ArchTree) {
178 if (Res == Edge.Child) {
179 Res = Edge.Parent;
180 if (Res == New)
176 for (const auto &edge : archTree) {
177 if (res == edge.child) {
178 res = edge.parent;
179 if (res == New)
181180 return true;
182181 }
183182 }
184183 return false;
185184}
186185
187static StringRef getMachName(uint32_t Flags) {
188 switch (Flags & EF_MIPS_MACH) {
186static StringRef getMachName(uint32_t flags) {
187 switch (flags & EF_MIPS_MACH) {
189188 case EF_MIPS_MACH_NONE:
190189 return "";
191190 case EF_MIPS_MACH_3900:
......@@ -229,8 +228,8 @@ static StringRef getMachName(uint32_t Flags) {
229228 }
230229}
231230
232static StringRef getArchName(uint32_t Flags) {
233 switch (Flags & EF_MIPS_ARCH) {
231static StringRef getArchName(uint32_t flags) {
232 switch (flags & EF_MIPS_ARCH) {
234233 case EF_MIPS_ARCH_1:
235234 return "mips1";
236235 case EF_MIPS_ARCH_2:
......@@ -258,12 +257,12 @@ static StringRef getArchName(uint32_t Flags) {
258257 }
259258}
260259
261static std::string getFullArchName(uint32_t Flags) {
262 StringRef Arch = getArchName(Flags);
263 StringRef Mach = getMachName(Flags);
264 if (Mach.empty())
265 return Arch.str();
266 return (Arch + " (" + Mach + ")").str();
260static std::string getFullArchName(uint32_t flags) {
261 StringRef arch = getArchName(flags);
262 StringRef mach = getMachName(flags);
263 if (mach.empty())
264 return arch.str();
265 return (arch + " (" + mach + ")").str();
267266}
268267
269268// There are (arguably too) many MIPS ISAs out there. Their relationships
......@@ -275,55 +274,55 @@ static std::string getFullArchName(uint32_t Flags) {
275274// Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32
276275// are incompatible because nor mips3 is a parent for misp32, nor mips32
277276// is a parent for mips3.
278static uint32_t getArchFlags(ArrayRef<FileFlags> Files) {
279 uint32_t Ret = Files[0].Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
277static uint32_t getArchFlags(ArrayRef<FileFlags> files) {
278 uint32_t ret = files[0].flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
280279
281 for (const FileFlags &F : Files.slice(1)) {
282 uint32_t New = F.Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
280 for (const FileFlags &f : files.slice(1)) {
281 uint32_t New = f.flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
283282
284283 // Check ISA compatibility.
285 if (isArchMatched(New, Ret))
284 if (isArchMatched(New, ret))
286285 continue;
287 if (!isArchMatched(Ret, New)) {
288 error("incompatible target ISA:\n>>> " + toString(Files[0].File) + ": " +
289 getFullArchName(Ret) + "\n>>> " + toString(F.File) + ": " +
286 if (!isArchMatched(ret, New)) {
287 error("incompatible target ISA:\n>>> " + toString(files[0].file) + ": " +
288 getFullArchName(ret) + "\n>>> " + toString(f.file) + ": " +
290289 getFullArchName(New));
291290 return 0;
292291 }
293 Ret = New;
292 ret = New;
294293 }
295 return Ret;
294 return ret;
296295}
297296
298297template <class ELFT> uint32_t elf::calcMipsEFlags() {
299 std::vector<FileFlags> V;
300 for (InputFile *F : ObjectFiles)
301 V.push_back({F, cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
302 if (V.empty())
298 std::vector<FileFlags> v;
299 for (InputFile *f : objectFiles)
300 v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader()->e_flags});
301 if (v.empty())
303302 return 0;
304 checkFlags(V);
305 return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
303 checkFlags(v);
304 return getMiscFlags(v) | getPicFlags(v) | getArchFlags(v);
306305}
307306
308static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) {
309 if (FpA == FpB)
307static int compareMipsFpAbi(uint8_t fpA, uint8_t fpB) {
308 if (fpA == fpB)
310309 return 0;
311 if (FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
310 if (fpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
312311 return 1;
313 if (FpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
314 FpA == Mips::Val_GNU_MIPS_ABI_FP_64)
312 if (fpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
313 fpA == Mips::Val_GNU_MIPS_ABI_FP_64)
315314 return 1;
316 if (FpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
315 if (fpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
317316 return -1;
318 if (FpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
319 FpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
320 FpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
317 if (fpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
318 fpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
319 fpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
321320 return 1;
322321 return -1;
323322}
324323
325static StringRef getMipsFpAbiName(uint8_t FpAbi) {
326 switch (FpAbi) {
324static StringRef getMipsFpAbiName(uint8_t fpAbi) {
325 switch (fpAbi) {
327326 case Mips::Val_GNU_MIPS_ABI_FP_ANY:
328327 return "any";
329328 case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
......@@ -345,43 +344,43 @@ static StringRef getMipsFpAbiName(uint8_t FpAbi) {
345344 }
346345}
347346
348uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
349 StringRef FileName) {
350 if (compareMipsFpAbi(NewFlag, OldFlag) >= 0)
351 return NewFlag;
352 if (compareMipsFpAbi(OldFlag, NewFlag) < 0)
353 error(FileName + ": floating point ABI '" + getMipsFpAbiName(NewFlag) +
347uint8_t elf::getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
348 StringRef fileName) {
349 if (compareMipsFpAbi(newFlag, oldFlag) >= 0)
350 return newFlag;
351 if (compareMipsFpAbi(oldFlag, newFlag) < 0)
352 error(fileName + ": floating point ABI '" + getMipsFpAbiName(newFlag) +
354353 "' is incompatible with target floating point ABI '" +
355 getMipsFpAbiName(OldFlag) + "'");
356 return OldFlag;
354 getMipsFpAbiName(oldFlag) + "'");
355 return oldFlag;
357356}
358357
359template <class ELFT> static bool isN32Abi(const InputFile *F) {
360 if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
361 return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
358template <class ELFT> static bool isN32Abi(const InputFile *f) {
359 if (auto *ef = dyn_cast<ELFFileBase>(f))
360 return ef->template getObj<ELFT>().getHeader()->e_flags & EF_MIPS_ABI2;
362361 return false;
363362}
364363
365bool elf::isMipsN32Abi(const InputFile *F) {
366 switch (Config->EKind) {
364bool elf::isMipsN32Abi(const InputFile *f) {
365 switch (config->ekind) {
367366 case ELF32LEKind:
368 return isN32Abi<ELF32LE>(F);
367 return isN32Abi<ELF32LE>(f);
369368 case ELF32BEKind:
370 return isN32Abi<ELF32BE>(F);
369 return isN32Abi<ELF32BE>(f);
371370 case ELF64LEKind:
372 return isN32Abi<ELF64LE>(F);
371 return isN32Abi<ELF64LE>(f);
373372 case ELF64BEKind:
374 return isN32Abi<ELF64BE>(F);
373 return isN32Abi<ELF64BE>(f);
375374 default:
376375 llvm_unreachable("unknown Config->EKind");
377376 }
378377}
379378
380bool elf::isMicroMips() { return Config->EFlags & EF_MIPS_MICROMIPS; }
379bool elf::isMicroMips() { return config->eflags & EF_MIPS_MICROMIPS; }
381380
382381bool elf::isMipsR6() {
383 uint32_t Arch = Config->EFlags & EF_MIPS_ARCH;
384 return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6;
382 uint32_t arch = config->eflags & EF_MIPS_ARCH;
383 return arch == EF_MIPS_ARCH_32R6 || arch == EF_MIPS_ARCH_64R6;
385384}
386385
387386template uint32_t elf::calcMipsEFlags<ELF32LE>();
deps/lld/ELF/Arch/PPC.cpp+379-28
......@@ -1,13 +1,14 @@
11//===- PPC.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
9#include "OutputSections.h"
1010#include "Symbols.h"
11#include "SyntheticSections.h"
1112#include "Target.h"
1213#include "lld/Common/ErrorHandler.h"
1314#include "llvm/Support/Endian.h"
......@@ -22,60 +23,410 @@ namespace {
2223class PPC final : public TargetInfo {
2324public:
2425 PPC();
25 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
26 RelExpr getRelExpr(RelType Type, const Symbol &S,
27 const uint8_t *Loc) const override;
26 RelExpr getRelExpr(RelType type, const Symbol &s,
27 const uint8_t *loc) const override;
28 RelType getDynRel(RelType type) const override;
29 void writeGotHeader(uint8_t *buf) const override;
30 void writePltHeader(uint8_t *buf) const override {
31 llvm_unreachable("should call writePPC32GlinkSection() instead");
32 }
33 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
34 int32_t index, unsigned relOff) const override {
35 llvm_unreachable("should call writePPC32GlinkSection() instead");
36 }
37 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
38 bool needsThunk(RelExpr expr, RelType relocType, const InputFile *file,
39 uint64_t branchAddr, const Symbol &s) const override;
40 uint32_t getThunkSectionSpacing() const override;
41 bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
42 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
43 RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
44 RelExpr expr) const override;
45 int getTlsGdRelaxSkip(RelType type) const override;
46 void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
47 void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
48 void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
49 void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
2850};
2951} // namespace
3052
53static uint16_t lo(uint32_t v) { return v; }
54static uint16_t ha(uint32_t v) { return (v + 0x8000) >> 16; }
55
56static uint32_t readFromHalf16(const uint8_t *loc) {
57 return read32(config->isLE ? loc : loc - 2);
58}
59
60static void writeFromHalf16(uint8_t *loc, uint32_t insn) {
61 write32(config->isLE ? loc : loc - 2, insn);
62}
63
64void elf::writePPC32GlinkSection(uint8_t *buf, size_t numEntries) {
65 // On PPC Secure PLT ABI, bl foo@plt jumps to a call stub, which loads an
66 // absolute address from a specific .plt slot (usually called .got.plt on
67 // other targets) and jumps there.
68 //
69 // a) With immediate binding (BIND_NOW), the .plt entry is resolved at load
70 // time. The .glink section is not used.
71 // b) With lazy binding, the .plt entry points to a `b PLTresolve`
72 // instruction in .glink, filled in by PPC::writeGotPlt().
73
74 // Write N `b PLTresolve` first.
75 for (size_t i = 0; i != numEntries; ++i)
76 write32(buf + 4 * i, 0x48000000 | 4 * (numEntries - i));
77 buf += 4 * numEntries;
78
79 // Then write PLTresolve(), which has two forms: PIC and non-PIC. PLTresolve()
80 // computes the PLT index (by computing the distance from the landing b to
81 // itself) and calls _dl_runtime_resolve() (in glibc).
82 uint32_t got = in.got->getVA();
83 uint32_t glink = in.plt->getVA(); // VA of .glink
84 const uint8_t *end = buf + 64;
85 if (config->isPic) {
86 uint32_t afterBcl = in.plt->getSize() - target->pltHeaderSize + 12;
87 uint32_t gotBcl = got + 4 - (glink + afterBcl);
88 write32(buf + 0, 0x3d6b0000 | ha(afterBcl)); // addis r11,r11,1f-glink@ha
89 write32(buf + 4, 0x7c0802a6); // mflr r0
90 write32(buf + 8, 0x429f0005); // bcl 20,30,.+4
91 write32(buf + 12, 0x396b0000 | lo(afterBcl)); // 1: addi r11,r11,1b-.glink@l
92 write32(buf + 16, 0x7d8802a6); // mflr r12
93 write32(buf + 20, 0x7c0803a6); // mtlr r0
94 write32(buf + 24, 0x7d6c5850); // sub r11,r11,r12
95 write32(buf + 28, 0x3d8c0000 | ha(gotBcl)); // addis 12,12,GOT+4-1b@ha
96 if (ha(gotBcl) == ha(gotBcl + 4)) {
97 write32(buf + 32, 0x800c0000 | lo(gotBcl)); // lwz r0,r12,GOT+4-1b@l(r12)
98 write32(buf + 36,
99 0x818c0000 | lo(gotBcl + 4)); // lwz r12,r12,GOT+8-1b@l(r12)
100 } else {
101 write32(buf + 32, 0x840c0000 | lo(gotBcl)); // lwzu r0,r12,GOT+4-1b@l(r12)
102 write32(buf + 36, 0x818c0000 | 4); // lwz r12,r12,4(r12)
103 }
104 write32(buf + 40, 0x7c0903a6); // mtctr 0
105 write32(buf + 44, 0x7c0b5a14); // add r0,11,11
106 write32(buf + 48, 0x7d605a14); // add r11,0,11
107 write32(buf + 52, 0x4e800420); // bctr
108 buf += 56;
109 } else {
110 write32(buf + 0, 0x3d800000 | ha(got + 4)); // lis r12,GOT+4@ha
111 write32(buf + 4, 0x3d6b0000 | ha(-glink)); // addis r11,r11,-Glink@ha
112 if (ha(got + 4) == ha(got + 8))
113 write32(buf + 8, 0x800c0000 | lo(got + 4)); // lwz r0,GOT+4@l(r12)
114 else
115 write32(buf + 8, 0x840c0000 | lo(got + 4)); // lwzu r0,GOT+4@l(r12)
116 write32(buf + 12, 0x396b0000 | lo(-glink)); // addi r11,r11,-Glink@l
117 write32(buf + 16, 0x7c0903a6); // mtctr r0
118 write32(buf + 20, 0x7c0b5a14); // add r0,r11,r11
119 if (ha(got + 4) == ha(got + 8))
120 write32(buf + 24, 0x818c0000 | lo(got + 8)); // lwz r12,GOT+8@ha(r12)
121 else
122 write32(buf + 24, 0x818c0000 | 4); // lwz r12,4(r12)
123 write32(buf + 28, 0x7d605a14); // add r11,r0,r11
124 write32(buf + 32, 0x4e800420); // bctr
125 buf += 36;
126 }
127
128 // Pad with nop. They should not be executed.
129 for (; buf < end; buf += 4)
130 write32(buf, 0x60000000);
131}
132
31133PPC::PPC() {
32 NoneRel = R_PPC_NONE;
33 GotBaseSymOff = 0x8000;
34 GotBaseSymInGotPlt = false;
134 gotRel = R_PPC_GLOB_DAT;
135 noneRel = R_PPC_NONE;
136 pltRel = R_PPC_JMP_SLOT;
137 relativeRel = R_PPC_RELATIVE;
138 iRelativeRel = R_PPC_IRELATIVE;
139 symbolicRel = R_PPC_ADDR32;
140 gotBaseSymInGotPlt = false;
141 gotHeaderEntriesNum = 3;
142 gotPltHeaderEntriesNum = 0;
143 pltHeaderSize = 64; // size of PLTresolve in .glink
144 pltEntrySize = 4;
145
146 needsThunks = true;
147
148 tlsModuleIndexRel = R_PPC_DTPMOD32;
149 tlsOffsetRel = R_PPC_DTPREL32;
150 tlsGotRel = R_PPC_TPREL32;
151
152 defaultMaxPageSize = 65536;
153 defaultImageBase = 0x10000000;
154
155 write32(trapInstr.data(), 0x7fe00008);
156}
157
158void PPC::writeGotHeader(uint8_t *buf) const {
159 // _GLOBAL_OFFSET_TABLE_[0] = _DYNAMIC
160 // glibc stores _dl_runtime_resolve in _GLOBAL_OFFSET_TABLE_[1],
161 // link_map in _GLOBAL_OFFSET_TABLE_[2].
162 write32(buf, mainPart->dynamic->getVA());
163}
164
165void PPC::writeGotPlt(uint8_t *buf, const Symbol &s) const {
166 // Address of the symbol resolver stub in .glink .
167 write32(buf, in.plt->getVA() + 4 * s.pltIndex);
168}
169
170bool PPC::needsThunk(RelExpr expr, RelType type, const InputFile *file,
171 uint64_t branchAddr, const Symbol &s) const {
172 if (type != R_PPC_REL24 && type != R_PPC_PLTREL24)
173 return false;
174 if (s.isInPlt())
175 return true;
176 if (s.isUndefWeak())
177 return false;
178 return !(expr == R_PC && PPC::inBranchRange(type, branchAddr, s.getVA()));
35179}
36180
37RelExpr PPC::getRelExpr(RelType Type, const Symbol &S,
38 const uint8_t *Loc) const {
39 switch (Type) {
181uint32_t PPC::getThunkSectionSpacing() const { return 0x2000000; }
182
183bool PPC::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
184 uint64_t offset = dst - src;
185 if (type == R_PPC_REL24 || type == R_PPC_PLTREL24)
186 return isInt<26>(offset);
187 llvm_unreachable("unsupported relocation type used in branch");
188}
189
190RelExpr PPC::getRelExpr(RelType type, const Symbol &s,
191 const uint8_t *loc) const {
192 switch (type) {
193 case R_PPC_DTPREL16:
194 case R_PPC_DTPREL16_HA:
195 case R_PPC_DTPREL16_HI:
196 case R_PPC_DTPREL16_LO:
197 case R_PPC_DTPREL32:
198 return R_DTPREL;
40199 case R_PPC_REL14:
41 case R_PPC_REL24:
42200 case R_PPC_REL32:
201 case R_PPC_LOCAL24PC:
202 case R_PPC_REL16_LO:
203 case R_PPC_REL16_HI:
204 case R_PPC_REL16_HA:
43205 return R_PC;
44 case R_PPC_PLTREL24:
206 case R_PPC_GOT16:
207 return R_GOT_OFF;
208 case R_PPC_REL24:
45209 return R_PLT_PC;
210 case R_PPC_PLTREL24:
211 return R_PPC32_PLTREL;
212 case R_PPC_GOT_TLSGD16:
213 return R_TLSGD_GOT;
214 case R_PPC_GOT_TLSLD16:
215 return R_TLSLD_GOT;
216 case R_PPC_GOT_TPREL16:
217 return R_GOT_OFF;
218 case R_PPC_TLS:
219 return R_TLSIE_HINT;
220 case R_PPC_TLSGD:
221 return R_TLSDESC_CALL;
222 case R_PPC_TLSLD:
223 return R_TLSLD_HINT;
224 case R_PPC_TPREL16:
225 case R_PPC_TPREL16_HA:
226 case R_PPC_TPREL16_LO:
227 case R_PPC_TPREL16_HI:
228 return R_TLS;
46229 default:
47230 return R_ABS;
48231 }
49232}
50233
51void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
52 switch (Type) {
234RelType PPC::getDynRel(RelType type) const {
235 if (type == R_PPC_ADDR32)
236 return type;
237 return R_PPC_NONE;
238}
239
240static std::pair<RelType, uint64_t> fromDTPREL(RelType type, uint64_t val) {
241 uint64_t dtpBiasedVal = val - 0x8000;
242 switch (type) {
243 case R_PPC_DTPREL16:
244 return {R_PPC64_ADDR16, dtpBiasedVal};
245 case R_PPC_DTPREL16_HA:
246 return {R_PPC_ADDR16_HA, dtpBiasedVal};
247 case R_PPC_DTPREL16_HI:
248 return {R_PPC_ADDR16_HI, dtpBiasedVal};
249 case R_PPC_DTPREL16_LO:
250 return {R_PPC_ADDR16_LO, dtpBiasedVal};
251 case R_PPC_DTPREL32:
252 return {R_PPC_ADDR32, dtpBiasedVal};
253 default:
254 return {type, val};
255 }
256}
257
258void PPC::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
259 RelType newType;
260 std::tie(newType, val) = fromDTPREL(type, val);
261 switch (newType) {
262 case R_PPC_ADDR16:
263 checkIntUInt(loc, val, 16, type);
264 write16(loc, val);
265 break;
266 case R_PPC_GOT16:
267 case R_PPC_GOT_TLSGD16:
268 case R_PPC_GOT_TLSLD16:
269 case R_PPC_GOT_TPREL16:
270 case R_PPC_TPREL16:
271 checkInt(loc, val, 16, type);
272 write16(loc, val);
273 break;
53274 case R_PPC_ADDR16_HA:
54 write16be(Loc, (Val + 0x8000) >> 16);
275 case R_PPC_DTPREL16_HA:
276 case R_PPC_GOT_TLSGD16_HA:
277 case R_PPC_GOT_TLSLD16_HA:
278 case R_PPC_GOT_TPREL16_HA:
279 case R_PPC_REL16_HA:
280 case R_PPC_TPREL16_HA:
281 write16(loc, ha(val));
55282 break;
56283 case R_PPC_ADDR16_HI:
57 write16be(Loc, Val >> 16);
284 case R_PPC_DTPREL16_HI:
285 case R_PPC_GOT_TLSGD16_HI:
286 case R_PPC_GOT_TLSLD16_HI:
287 case R_PPC_GOT_TPREL16_HI:
288 case R_PPC_REL16_HI:
289 case R_PPC_TPREL16_HI:
290 write16(loc, val >> 16);
58291 break;
59292 case R_PPC_ADDR16_LO:
60 write16be(Loc, Val);
293 case R_PPC_DTPREL16_LO:
294 case R_PPC_GOT_TLSGD16_LO:
295 case R_PPC_GOT_TLSLD16_LO:
296 case R_PPC_GOT_TPREL16_LO:
297 case R_PPC_REL16_LO:
298 case R_PPC_TPREL16_LO:
299 write16(loc, val);
61300 break;
62301 case R_PPC_ADDR32:
63302 case R_PPC_REL32:
64 write32be(Loc, Val);
303 write32(loc, val);
65304 break;
66 case R_PPC_REL14:
67 write32be(Loc, read32be(Loc) | (Val & 0xFFFC));
305 case R_PPC_REL14: {
306 uint32_t mask = 0x0000FFFC;
307 checkInt(loc, val, 16, type);
308 checkAlignment(loc, val, 4, type);
309 write32(loc, (read32(loc) & ~mask) | (val & mask));
68310 break;
69 case R_PPC_PLTREL24:
311 }
70312 case R_PPC_REL24:
71 write32be(Loc, read32be(Loc) | (Val & 0x3FFFFFC));
313 case R_PPC_LOCAL24PC:
314 case R_PPC_PLTREL24: {
315 uint32_t mask = 0x03FFFFFC;
316 checkInt(loc, val, 26, type);
317 checkAlignment(loc, val, 4, type);
318 write32(loc, (read32(loc) & ~mask) | (val & mask));
72319 break;
320 }
321 default:
322 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
323 }
324}
325
326RelExpr PPC::adjustRelaxExpr(RelType type, const uint8_t *data,
327 RelExpr expr) const {
328 if (expr == R_RELAX_TLS_GD_TO_IE)
329 return R_RELAX_TLS_GD_TO_IE_GOT_OFF;
330 if (expr == R_RELAX_TLS_LD_TO_LE)
331 return R_RELAX_TLS_LD_TO_LE_ABS;
332 return expr;
333}
334
335int PPC::getTlsGdRelaxSkip(RelType type) const {
336 // A __tls_get_addr call instruction is marked with 2 relocations:
337 //
338 // R_PPC_TLSGD / R_PPC_TLSLD: marker relocation
339 // R_PPC_REL24: __tls_get_addr
340 //
341 // After the relaxation we no longer call __tls_get_addr and should skip both
342 // relocations to not create a false dependence on __tls_get_addr being
343 // defined.
344 if (type == R_PPC_TLSGD || type == R_PPC_TLSLD)
345 return 2;
346 return 1;
347}
348
349void PPC::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
350 switch (type) {
351 case R_PPC_GOT_TLSGD16: {
352 // addi rT, rA, x@got@tlsgd --> lwz rT, x@got@tprel(rA)
353 uint32_t insn = readFromHalf16(loc);
354 writeFromHalf16(loc, 0x80000000 | (insn & 0x03ff0000));
355 relocateOne(loc, R_PPC_GOT_TPREL16, val);
356 break;
357 }
358 case R_PPC_TLSGD:
359 // bl __tls_get_addr(x@tldgd) --> add r3, r3, r2
360 write32(loc, 0x7c631214);
361 break;
362 default:
363 llvm_unreachable("unsupported relocation for TLS GD to IE relaxation");
364 }
365}
366
367void PPC::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
368 switch (type) {
369 case R_PPC_GOT_TLSGD16:
370 // addi r3, r31, x@got@tlsgd --> addis r3, r2, x@tprel@ha
371 writeFromHalf16(loc, 0x3c620000 | ha(val));
372 break;
373 case R_PPC_TLSGD:
374 // bl __tls_get_addr(x@tldgd) --> add r3, r3, x@tprel@l
375 write32(loc, 0x38630000 | lo(val));
376 break;
377 default:
378 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
379 }
380}
381
382void PPC::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
383 switch (type) {
384 case R_PPC_GOT_TLSLD16:
385 // addi r3, rA, x@got@tlsgd --> addis r3, r2, 0
386 writeFromHalf16(loc, 0x3c620000);
387 break;
388 case R_PPC_TLSLD:
389 // r3+x@dtprel computes r3+x-0x8000, while we want it to compute r3+x@tprel
390 // = r3+x-0x7000, so add 4096 to r3.
391 // bl __tls_get_addr(x@tlsld) --> addi r3, r3, 4096
392 write32(loc, 0x38631000);
393 break;
394 case R_PPC_DTPREL16:
395 case R_PPC_DTPREL16_HA:
396 case R_PPC_DTPREL16_HI:
397 case R_PPC_DTPREL16_LO:
398 relocateOne(loc, type, val);
399 break;
400 default:
401 llvm_unreachable("unsupported relocation for TLS LD to LE relaxation");
402 }
403}
404
405void PPC::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
406 switch (type) {
407 case R_PPC_GOT_TPREL16: {
408 // lwz rT, x@got@tprel(rA) --> addis rT, r2, x@tprel@ha
409 uint32_t rt = readFromHalf16(loc) & 0x03e00000;
410 writeFromHalf16(loc, 0x3c020000 | rt | ha(val));
411 break;
412 }
413 case R_PPC_TLS: {
414 uint32_t insn = read32(loc);
415 if (insn >> 26 != 31)
416 error("unrecognized instruction for IE to LE R_PPC_TLS");
417 // addi rT, rT, x@tls --> addi rT, rT, x@tprel@l
418 uint32_t dFormOp = getPPCDFormOp((read32(loc) & 0x000007fe) >> 1);
419 if (dFormOp == 0)
420 error("unrecognized instruction for IE to LE R_PPC_TLS");
421 write32(loc, (dFormOp << 26) | (insn & 0x03ff0000) | lo(val));
422 break;
423 }
73424 default:
74 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
425 llvm_unreachable("unsupported relocation for TLS IE to LE relaxation");
75426 }
76427}
77428
78429TargetInfo *elf::getPPCTargetInfo() {
79 static PPC Target;
80 return &Target;
430 static PPC target;
431 return &target;
81432}
deps/lld/ELF/Arch/PPC64.cpp+438-292
......@@ -1,9 +1,8 @@
11//===- PPC64.cpp ----------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -20,8 +19,8 @@ using namespace llvm::ELF;
2019using namespace lld;
2120using namespace lld::elf;
2221
23static uint64_t PPC64TocOffset = 0x8000;
24static uint64_t DynamicThreadPointerOffset = 0x8000;
22static uint64_t ppc64TocOffset = 0x8000;
23static uint64_t dynamicThreadPointerOffset = 0x8000;
2524
2625// The instruction encoding of bits 21-30 from the ISA for the Xform and Dform
2726// instructions that can be used as part of the initial exec TLS sequence.
......@@ -65,16 +64,16 @@ uint64_t elf::getPPC64TocBase() {
6564 // TOC starts where the first of these sections starts. We always create a
6665 // .got when we see a relocation that uses it, so for us the start is always
6766 // the .got.
68 uint64_t TocVA = In.Got->getVA();
67 uint64_t tocVA = in.got->getVA();
6968
7069 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
7170 // thus permitting a full 64 Kbytes segment. Note that the glibc startup
7271 // code (crt1.o) assumes that you can get from the TOC base to the
7372 // start of the .toc section with only a single (signed) 16-bit relocation.
74 return TocVA + PPC64TocOffset;
73 return tocVA + ppc64TocOffset;
7574}
7675
77unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther) {
76unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
7877 // The offset is encoded into the 3 most significant bits of the st_other
7978 // field, with some special values described in section 3.4.1 of the ABI:
8079 // 0 --> Zero offset between the GEP and LEP, and the function does NOT use
......@@ -86,43 +85,134 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther) {
8685 // 2 --> 2^2 = 4 bytes --> 1 instruction.
8786 // 6 --> 2^6 = 64 bytes --> 16 instructions.
8887 // 7 --> Reserved.
89 uint8_t GepToLep = (StOther >> 5) & 7;
90 if (GepToLep < 2)
88 uint8_t gepToLep = (stOther >> 5) & 7;
89 if (gepToLep < 2)
9190 return 0;
9291
9392 // The value encoded in the st_other bits is the
9493 // log-base-2(offset).
95 if (GepToLep < 7)
96 return 1 << GepToLep;
94 if (gepToLep < 7)
95 return 1 << gepToLep;
9796
9897 error("reserved value of 7 in the 3 most-significant-bits of st_other");
9998 return 0;
10099}
101100
101bool elf::isPPC64SmallCodeModelTocReloc(RelType type) {
102 // The only small code model relocations that access the .toc section.
103 return type == R_PPC64_TOC16 || type == R_PPC64_TOC16_DS;
104}
105
106// Find the R_PPC64_ADDR64 in .rela.toc with matching offset.
107template <typename ELFT>
108static std::pair<Defined *, int64_t>
109getRelaTocSymAndAddend(InputSectionBase *tocSec, uint64_t offset) {
110 if (tocSec->numRelocations == 0)
111 return {};
112
113 // .rela.toc contains exclusively R_PPC64_ADDR64 relocations sorted by
114 // r_offset: 0, 8, 16, etc. For a given Offset, Offset / 8 gives us the
115 // relocation index in most cases.
116 //
117 // In rare cases a TOC entry may store a constant that doesn't need an
118 // R_PPC64_ADDR64, the corresponding r_offset is therefore missing. Offset / 8
119 // points to a relocation with larger r_offset. Do a linear probe then.
120 // Constants are extremely uncommon in .toc and the extra number of array
121 // accesses can be seen as a small constant.
122 ArrayRef<typename ELFT::Rela> relas = tocSec->template relas<ELFT>();
123 uint64_t index = std::min<uint64_t>(offset / 8, relas.size() - 1);
124 for (;;) {
125 if (relas[index].r_offset == offset) {
126 Symbol &sym = tocSec->getFile<ELFT>()->getRelocTargetSym(relas[index]);
127 return {dyn_cast<Defined>(&sym), getAddend<ELFT>(relas[index])};
128 }
129 if (relas[index].r_offset < offset || index == 0)
130 break;
131 --index;
132 }
133 return {};
134}
135
136// When accessing a symbol defined in another translation unit, compilers
137// reserve a .toc entry, allocate a local label and generate toc-indirect
138// instuctions:
139//
140// addis 3, 2, .LC0@toc@ha # R_PPC64_TOC16_HA
141// ld 3, .LC0@toc@l(3) # R_PPC64_TOC16_LO_DS, load the address from a .toc entry
142// ld/lwa 3, 0(3) # load the value from the address
143//
144// .section .toc,"aw",@progbits
145// .LC0: .tc var[TC],var
146//
147// If var is defined, non-preemptable and addressable with a 32-bit signed
148// offset from the toc base, the address of var can be computed by adding an
149// offset to the toc base, saving a load.
150//
151// addis 3,2,var@toc@ha # this may be relaxed to a nop,
152// addi 3,3,var@toc@l # then this becomes addi 3,2,var@toc
153// ld/lwa 3, 0(3) # load the value from the address
154//
155// Returns true if the relaxation is performed.
156bool elf::tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
157 uint8_t *bufLoc) {
158 assert(config->tocOptimize);
159 if (rel.addend < 0)
160 return false;
161
162 // If the symbol is not the .toc section, this isn't a toc-indirection.
163 Defined *defSym = dyn_cast<Defined>(rel.sym);
164 if (!defSym || !defSym->isSection() || defSym->section->name != ".toc")
165 return false;
166
167 Defined *d;
168 int64_t addend;
169 auto *tocISB = cast<InputSectionBase>(defSym->section);
170 std::tie(d, addend) =
171 config->isLE ? getRelaTocSymAndAddend<ELF64LE>(tocISB, rel.addend)
172 : getRelaTocSymAndAddend<ELF64BE>(tocISB, rel.addend);
173
174 // Only non-preemptable defined symbols can be relaxed.
175 if (!d || d->isPreemptible)
176 return false;
177
178 // Two instructions can materialize a 32-bit signed offset from the toc base.
179 uint64_t tocRelative = d->getVA(addend) - getPPC64TocBase();
180 if (!isInt<32>(tocRelative))
181 return false;
182
183 // Add PPC64TocOffset that will be subtracted by relocateOne().
184 target->relaxGot(bufLoc, type, tocRelative + ppc64TocOffset);
185 return true;
186}
187
102188namespace {
103189class PPC64 final : public TargetInfo {
104190public:
105191 PPC64();
192 int getTlsGdRelaxSkip(RelType type) const override;
106193 uint32_t calcEFlags() const override;
107 RelExpr getRelExpr(RelType Type, const Symbol &S,
108 const uint8_t *Loc) const override;
109 void writePltHeader(uint8_t *Buf) const override;
110 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
111 int32_t Index, unsigned RelOff) const override;
112 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
113 void writeGotHeader(uint8_t *Buf) const override;
114 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
115 uint64_t BranchAddr, const Symbol &S) const override;
116 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
117 RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
118 RelExpr Expr) const override;
119 void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
120 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
121 void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
122 void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
123
124 bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
125 uint8_t StOther) const override;
194 RelExpr getRelExpr(RelType type, const Symbol &s,
195 const uint8_t *loc) const override;
196 RelType getDynRel(RelType type) const override;
197 void writePltHeader(uint8_t *buf) const override;
198 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
199 int32_t index, unsigned relOff) const override;
200 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
201 void writeGotHeader(uint8_t *buf) const override;
202 bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
203 uint64_t branchAddr, const Symbol &s) const override;
204 uint32_t getThunkSectionSpacing() const override;
205 bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
206 RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
207 RelExpr expr) const override;
208 void relaxGot(uint8_t *loc, RelType type, uint64_t val) const override;
209 void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
210 void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
211 void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
212 void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
213
214 bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
215 uint8_t stOther) const override;
126216};
127217} // namespace
128218
......@@ -130,19 +220,19 @@ public:
130220// #higher(value), #highera(value), #highest(value), and #highesta(value)
131221// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
132222// document.
133static uint16_t lo(uint64_t V) { return V; }
134static uint16_t hi(uint64_t V) { return V >> 16; }
135static uint16_t ha(uint64_t V) { return (V + 0x8000) >> 16; }
136static uint16_t higher(uint64_t V) { return V >> 32; }
137static uint16_t highera(uint64_t V) { return (V + 0x8000) >> 32; }
138static uint16_t highest(uint64_t V) { return V >> 48; }
139static uint16_t highesta(uint64_t V) { return (V + 0x8000) >> 48; }
223static uint16_t lo(uint64_t v) { return v; }
224static uint16_t hi(uint64_t v) { return v >> 16; }
225static uint16_t ha(uint64_t v) { return (v + 0x8000) >> 16; }
226static uint16_t higher(uint64_t v) { return v >> 32; }
227static uint16_t highera(uint64_t v) { return (v + 0x8000) >> 32; }
228static uint16_t highest(uint64_t v) { return v >> 48; }
229static uint16_t highesta(uint64_t v) { return (v + 0x8000) >> 48; }
140230
141231// Extracts the 'PO' field of an instruction encoding.
142static uint8_t getPrimaryOpCode(uint32_t Encoding) { return (Encoding >> 26); }
232static uint8_t getPrimaryOpCode(uint32_t encoding) { return (encoding >> 26); }
143233
144static bool isDQFormInstruction(uint32_t Encoding) {
145 switch (getPrimaryOpCode(Encoding)) {
234static bool isDQFormInstruction(uint32_t encoding) {
235 switch (getPrimaryOpCode(encoding)) {
146236 default:
147237 return false;
148238 case 56:
......@@ -152,12 +242,12 @@ static bool isDQFormInstruction(uint32_t Encoding) {
152242 // There are both DS and DQ instruction forms with this primary opcode.
153243 // Namely `lxv` and `stxv` are the DQ-forms that use it.
154244 // The DS 'XO' bits being set to 01 is restricted to DQ form.
155 return (Encoding & 3) == 0x1;
245 return (encoding & 3) == 0x1;
156246 }
157247}
158248
159static bool isInstructionUpdateForm(uint32_t Encoding) {
160 switch (getPrimaryOpCode(Encoding)) {
249static bool isInstructionUpdateForm(uint32_t encoding) {
250 switch (getPrimaryOpCode(encoding)) {
161251 default:
162252 return false;
163253 case LBZU:
......@@ -176,7 +266,7 @@ static bool isInstructionUpdateForm(uint32_t Encoding) {
176266 // between LD/LDU/LWA
177267 case LD:
178268 case STD:
179 return (Encoding & 3) == 1;
269 return (encoding & 3) == 1;
180270 }
181271}
182272
......@@ -185,40 +275,38 @@ static bool isInstructionUpdateForm(uint32_t Encoding) {
185275// pointer is pointing into the middle of the word we want to extract, and on
186276// little-endian it is pointing to the start of the word. These 2 helpers are to
187277// 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);
278static void writeFromHalf16(uint8_t *loc, uint32_t insn) {
279 write32(config->isLE ? loc : loc - 2, insn);
190280}
191281
192static uint32_t readInstrFromHalf16(const uint8_t *Loc) {
193 return read32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0));
282static uint32_t readFromHalf16(const uint8_t *loc) {
283 return read32(config->isLE ? loc : loc - 2);
194284}
195285
196286PPC64::PPC64() {
197 GotRel = R_PPC64_GLOB_DAT;
198 NoneRel = R_PPC64_NONE;
199 PltRel = R_PPC64_JMP_SLOT;
200 RelativeRel = R_PPC64_RELATIVE;
201 IRelativeRel = R_PPC64_IRELATIVE;
202 GotEntrySize = 8;
203 PltEntrySize = 4;
204 GotPltEntrySize = 8;
205 GotBaseSymInGotPlt = false;
206 GotBaseSymOff = 0x8000;
207 GotHeaderEntriesNum = 1;
208 GotPltHeaderEntriesNum = 2;
209 PltHeaderSize = 60;
210 NeedsThunks = true;
211
212 TlsModuleIndexRel = R_PPC64_DTPMOD64;
213 TlsOffsetRel = R_PPC64_DTPREL64;
214
215 TlsGotRel = R_PPC64_TPREL64;
216
217 NeedsMoreStackNonSplit = false;
287 gotRel = R_PPC64_GLOB_DAT;
288 noneRel = R_PPC64_NONE;
289 pltRel = R_PPC64_JMP_SLOT;
290 relativeRel = R_PPC64_RELATIVE;
291 iRelativeRel = R_PPC64_IRELATIVE;
292 symbolicRel = R_PPC64_ADDR64;
293 pltEntrySize = 4;
294 gotBaseSymInGotPlt = false;
295 gotHeaderEntriesNum = 1;
296 gotPltHeaderEntriesNum = 2;
297 pltHeaderSize = 60;
298 needsThunks = true;
299
300 tlsModuleIndexRel = R_PPC64_DTPMOD64;
301 tlsOffsetRel = R_PPC64_DTPREL64;
302
303 tlsGotRel = R_PPC64_TPREL64;
304
305 needsMoreStackNonSplit = false;
218306
219307 // We need 64K pages (at least under glibc/Linux, the loader won't
220308 // set different permissions on a finer granularity than that).
221 DefaultMaxPageSize = 65536;
309 defaultMaxPageSize = 65536;
222310
223311 // The PPC64 ELF ABI v1 spec, says:
224312 //
......@@ -228,31 +316,66 @@ PPC64::PPC64() {
228316 //
229317 // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers
230318 // use 0x10000000 as the starting address.
231 DefaultImageBase = 0x10000000;
319 defaultImageBase = 0x10000000;
232320
233 write32(TrapInstr.data(), 0x7fe00008);
321 write32(trapInstr.data(), 0x7fe00008);
322}
323
324int PPC64::getTlsGdRelaxSkip(RelType type) const {
325 // A __tls_get_addr call instruction is marked with 2 relocations:
326 //
327 // R_PPC64_TLSGD / R_PPC64_TLSLD: marker relocation
328 // R_PPC64_REL24: __tls_get_addr
329 //
330 // After the relaxation we no longer call __tls_get_addr and should skip both
331 // relocations to not create a false dependence on __tls_get_addr being
332 // defined.
333 if (type == R_PPC64_TLSGD || type == R_PPC64_TLSLD)
334 return 2;
335 return 1;
234336}
235337
236static uint32_t getEFlags(InputFile *File) {
237 if (Config->EKind == ELF64BEKind)
238 return cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags;
239 return cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags;
338static uint32_t getEFlags(InputFile *file) {
339 if (config->ekind == ELF64BEKind)
340 return cast<ObjFile<ELF64BE>>(file)->getObj().getHeader()->e_flags;
341 return cast<ObjFile<ELF64LE>>(file)->getObj().getHeader()->e_flags;
240342}
241343
242344// This file implements v2 ABI. This function makes sure that all
243345// object files have v2 or an unspecified version as an ABI version.
244346uint32_t PPC64::calcEFlags() const {
245 for (InputFile *F : ObjectFiles) {
246 uint32_t Flag = getEFlags(F);
247 if (Flag == 1)
248 error(toString(F) + ": ABI version 1 is not supported");
249 else if (Flag > 2)
250 error(toString(F) + ": unrecognized e_flags: " + Twine(Flag));
347 for (InputFile *f : objectFiles) {
348 uint32_t flag = getEFlags(f);
349 if (flag == 1)
350 error(toString(f) + ": ABI version 1 is not supported");
351 else if (flag > 2)
352 error(toString(f) + ": unrecognized e_flags: " + Twine(flag));
251353 }
252354 return 2;
253355}
254356
255void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
357void PPC64::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
358 switch (type) {
359 case R_PPC64_TOC16_HA:
360 // Convert "addis reg, 2, .LC0@toc@h" to "addis reg, 2, var@toc@h" or "nop".
361 relocateOne(loc, type, val);
362 break;
363 case R_PPC64_TOC16_LO_DS: {
364 // Convert "ld reg, .LC0@toc@l(reg)" to "addi reg, reg, var@toc@l" or
365 // "addi reg, 2, var@toc".
366 uint32_t insn = readFromHalf16(loc);
367 if (getPrimaryOpCode(insn) != LD)
368 error("expected a 'ld' for got-indirect to toc-relative relaxing");
369 writeFromHalf16(loc, (insn & 0x03ffffff) | 0x38000000);
370 relocateOne(loc, R_PPC64_TOC16_LO, val);
371 break;
372 }
373 default:
374 llvm_unreachable("unexpected relocation type");
375 }
376}
377
378void PPC64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
256379 // Reference: 3.7.4.2 of the 64-bit ELF V2 abi supplement.
257380 // The general dynamic code sequence for a global `x` will look like:
258381 // Instruction Relocation Symbol
......@@ -268,30 +391,30 @@ void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
268391 // bl __tls_get_addr(x@tlsgd) into nop
269392 // nop into addi r3, r3, x@tprel@l
270393
271 switch (Type) {
394 switch (type) {
272395 case R_PPC64_GOT_TLSGD16_HA:
273 writeInstrFromHalf16(Loc, 0x60000000); // nop
396 writeFromHalf16(loc, 0x60000000); // nop
274397 break;
275398 case R_PPC64_GOT_TLSGD16:
276399 case R_PPC64_GOT_TLSGD16_LO:
277 writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13
278 relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
400 writeFromHalf16(loc, 0x3c6d0000); // addis r3, r13
401 relocateOne(loc, R_PPC64_TPREL16_HA, val);
279402 break;
280403 case R_PPC64_TLSGD:
281 write32(Loc, 0x60000000); // nop
282 write32(Loc + 4, 0x38630000); // addi r3, r3
404 write32(loc, 0x60000000); // nop
405 write32(loc + 4, 0x38630000); // addi r3, r3
283406 // Since we are relocating a half16 type relocation and Loc + 4 points to
284407 // the start of an instruction we need to advance the buffer by an extra
285408 // 2 bytes on BE.
286 relocateOne(Loc + 4 + (Config->EKind == ELF64BEKind ? 2 : 0),
287 R_PPC64_TPREL16_LO, Val);
409 relocateOne(loc + 4 + (config->ekind == ELF64BEKind ? 2 : 0),
410 R_PPC64_TPREL16_LO, val);
288411 break;
289412 default:
290413 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
291414 }
292415}
293416
294void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
417void PPC64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
295418 // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement.
296419 // The local dynamic code sequence for a global `x` will look like:
297420 // Instruction Relocation Symbol
......@@ -307,16 +430,16 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
307430 // bl __tls_get_addr(x@tlsgd) into nop
308431 // nop into addi r3, r3, 4096
309432
310 switch (Type) {
433 switch (type) {
311434 case R_PPC64_GOT_TLSLD16_HA:
312 writeInstrFromHalf16(Loc, 0x60000000); // nop
435 writeFromHalf16(loc, 0x60000000); // nop
313436 break;
314437 case R_PPC64_GOT_TLSLD16_LO:
315 writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0
438 writeFromHalf16(loc, 0x3c6d0000); // addis r3, r13, 0
316439 break;
317440 case R_PPC64_TLSLD:
318 write32(Loc, 0x60000000); // nop
319 write32(Loc + 4, 0x38631000); // addi r3, r3, 4096
441 write32(loc, 0x60000000); // nop
442 write32(loc + 4, 0x38631000); // addi r3, r3, 4096
320443 break;
321444 case R_PPC64_DTPREL16:
322445 case R_PPC64_DTPREL16_HA:
......@@ -324,19 +447,15 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
324447 case R_PPC64_DTPREL16_DS:
325448 case R_PPC64_DTPREL16_LO:
326449 case R_PPC64_DTPREL16_LO_DS:
327 case R_PPC64_GOT_DTPREL16_HA:
328 case R_PPC64_GOT_DTPREL16_LO_DS:
329 case R_PPC64_GOT_DTPREL16_DS:
330 case R_PPC64_GOT_DTPREL16_HI:
331 relocateOne(Loc, Type, Val);
450 relocateOne(loc, type, val);
332451 break;
333452 default:
334453 llvm_unreachable("unsupported relocation for TLS LD to LE relaxation");
335454 }
336455}
337456
338static unsigned getDFormOp(unsigned SecondaryOp) {
339 switch (SecondaryOp) {
457unsigned elf::getPPCDFormOp(unsigned secondaryOp) {
458 switch (secondaryOp) {
340459 case LBZX:
341460 return LBZ;
342461 case LHZX:
......@@ -356,12 +475,11 @@ static unsigned getDFormOp(unsigned SecondaryOp) {
356475 case ADD:
357476 return ADDI;
358477 default:
359 error("unrecognized instruction for IE to LE R_PPC64_TLS");
360478 return 0;
361479 }
362480}
363481
364void PPC64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
482void PPC64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
365483 // The initial exec code sequence for a global `x` will look like:
366484 // Instruction Relocation Symbol
367485 // addis r9, r2, x@got@tprel@ha R_PPC64_GOT_TPREL16_HA x
......@@ -381,26 +499,28 @@ void PPC64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
381499 // instruction, if we are accessing memory it will use any of the X-form
382500 // indexed load or store instructions.
383501
384 unsigned Offset = (Config->EKind == ELF64BEKind) ? 2 : 0;
385 switch (Type) {
502 unsigned offset = (config->ekind == ELF64BEKind) ? 2 : 0;
503 switch (type) {
386504 case R_PPC64_GOT_TPREL16_HA:
387 write32(Loc - Offset, 0x60000000); // nop
505 write32(loc - offset, 0x60000000); // nop
388506 break;
389507 case R_PPC64_GOT_TPREL16_LO_DS:
390508 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);
509 uint32_t regNo = read32(loc - offset) & 0x03E00000; // bits 6-10
510 write32(loc - offset, 0x3C0D0000 | regNo); // addis RegNo, r13
511 relocateOne(loc, R_PPC64_TPREL16_HA, val);
394512 break;
395513 }
396514 case R_PPC64_TLS: {
397 uint32_t PrimaryOp = getPrimaryOpCode(read32(Loc));
398 if (PrimaryOp != 31)
515 uint32_t primaryOp = getPrimaryOpCode(read32(loc));
516 if (primaryOp != 31)
399517 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);
518 uint32_t secondaryOp = (read32(loc) & 0x000007FE) >> 1; // bits 21-30
519 uint32_t dFormOp = getPPCDFormOp(secondaryOp);
520 if (dFormOp == 0)
521 error("unrecognized instruction for IE to LE R_PPC64_TLS");
522 write32(loc, ((dFormOp << 26) | (read32(loc) & 0x03FFFFFF)));
523 relocateOne(loc + offset, R_PPC64_TPREL16_LO, val);
404524 break;
405525 }
406526 default:
......@@ -409,9 +529,9 @@ void PPC64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
409529 }
410530}
411531
412RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
413 const uint8_t *Loc) const {
414 switch (Type) {
532RelExpr PPC64::getRelExpr(RelType type, const Symbol &s,
533 const uint8_t *loc) const {
534 switch (type) {
415535 case R_PPC64_GOT16:
416536 case R_PPC64_GOT16_DS:
417537 case R_PPC64_GOT16_HA:
......@@ -421,16 +541,17 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
421541 return R_GOT_OFF;
422542 case R_PPC64_TOC16:
423543 case R_PPC64_TOC16_DS:
424 case R_PPC64_TOC16_HA:
425544 case R_PPC64_TOC16_HI:
426545 case R_PPC64_TOC16_LO:
427 case R_PPC64_TOC16_LO_DS:
428546 return R_GOTREL;
547 case R_PPC64_TOC16_HA:
548 case R_PPC64_TOC16_LO_DS:
549 return config->tocOptimize ? R_PPC64_RELAX_TOC : R_GOTREL;
429550 case R_PPC64_TOC:
430 return R_PPC_TOC;
551 return R_PPC64_TOCBASE;
431552 case R_PPC64_REL14:
432553 case R_PPC64_REL24:
433 return R_PPC_CALL_PLT;
554 return R_PPC64_CALL_PLT;
434555 case R_PPC64_REL16_LO:
435556 case R_PPC64_REL16_HA:
436557 case R_PPC64_REL32:
......@@ -478,7 +599,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
478599 case R_PPC64_DTPREL16_LO:
479600 case R_PPC64_DTPREL16_LO_DS:
480601 case R_PPC64_DTPREL64:
481 return R_ABS;
602 return R_DTPREL;
482603 case R_PPC64_TLSGD:
483604 return R_TLSDESC_CALL;
484605 case R_PPC64_TLSLD:
......@@ -490,115 +611,121 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
490611 }
491612}
492613
493void PPC64::writeGotHeader(uint8_t *Buf) const {
494 write64(Buf, getPPC64TocBase());
614RelType PPC64::getDynRel(RelType type) const {
615 if (type == R_PPC64_ADDR64 || type == R_PPC64_TOC)
616 return R_PPC64_ADDR64;
617 return R_PPC64_NONE;
495618}
496619
497void PPC64::writePltHeader(uint8_t *Buf) const {
620void PPC64::writeGotHeader(uint8_t *buf) const {
621 write64(buf, getPPC64TocBase());
622}
623
624void PPC64::writePltHeader(uint8_t *buf) const {
498625 // The generic resolver stub goes first.
499 write32(Buf + 0, 0x7c0802a6); // mflr r0
500 write32(Buf + 4, 0x429f0005); // bcl 20,4*cr7+so,8 <_glink+0x8>
501 write32(Buf + 8, 0x7d6802a6); // mflr r11
502 write32(Buf + 12, 0x7c0803a6); // mtlr r0
503 write32(Buf + 16, 0x7d8b6050); // subf r12, r11, r12
504 write32(Buf + 20, 0x380cffcc); // subi r0,r12,52
505 write32(Buf + 24, 0x7800f082); // srdi r0,r0,62,2
506 write32(Buf + 28, 0xe98b002c); // ld r12,44(r11)
507 write32(Buf + 32, 0x7d6c5a14); // add r11,r12,r11
508 write32(Buf + 36, 0xe98b0000); // ld r12,0(r11)
509 write32(Buf + 40, 0xe96b0008); // ld r11,8(r11)
510 write32(Buf + 44, 0x7d8903a6); // mtctr r12
511 write32(Buf + 48, 0x4e800420); // bctr
626 write32(buf + 0, 0x7c0802a6); // mflr r0
627 write32(buf + 4, 0x429f0005); // bcl 20,4*cr7+so,8 <_glink+0x8>
628 write32(buf + 8, 0x7d6802a6); // mflr r11
629 write32(buf + 12, 0x7c0803a6); // mtlr r0
630 write32(buf + 16, 0x7d8b6050); // subf r12, r11, r12
631 write32(buf + 20, 0x380cffcc); // subi r0,r12,52
632 write32(buf + 24, 0x7800f082); // srdi r0,r0,62,2
633 write32(buf + 28, 0xe98b002c); // ld r12,44(r11)
634 write32(buf + 32, 0x7d6c5a14); // add r11,r12,r11
635 write32(buf + 36, 0xe98b0000); // ld r12,0(r11)
636 write32(buf + 40, 0xe96b0008); // ld r11,8(r11)
637 write32(buf + 44, 0x7d8903a6); // mtctr r12
638 write32(buf + 48, 0x4e800420); // bctr
512639
513640 // The 'bcl' instruction will set the link register to the address of the
514641 // following instruction ('mflr r11'). Here we store the offset from that
515642 // instruction to the first entry in the GotPlt section.
516 int64_t GotPltOffset = In.GotPlt->getVA() - (In.Plt->getVA() + 8);
517 write64(Buf + 52, GotPltOffset);
643 int64_t gotPltOffset = in.gotPlt->getVA() - (in.plt->getVA() + 8);
644 write64(buf + 52, gotPltOffset);
518645}
519646
520void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
521 uint64_t PltEntryAddr, int32_t Index,
522 unsigned RelOff) const {
523 int32_t Offset = PltHeaderSize + Index * PltEntrySize;
647void PPC64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
648 uint64_t pltEntryAddr, int32_t index,
649 unsigned relOff) const {
650 int32_t offset = pltHeaderSize + index * pltEntrySize;
524651 // bl __glink_PLTresolve
525 write32(Buf, 0x48000000 | ((-Offset) & 0x03FFFFFc));
652 write32(buf, 0x48000000 | ((-offset) & 0x03FFFFFc));
526653}
527654
528static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
655static std::pair<RelType, uint64_t> toAddr16Rel(RelType type, uint64_t val) {
529656 // Relocations relative to the toc-base need to be adjusted by the Toc offset.
530 uint64_t TocBiasedVal = Val - PPC64TocOffset;
657 uint64_t tocBiasedVal = val - ppc64TocOffset;
531658 // Relocations relative to dtv[dtpmod] need to be adjusted by the DTP offset.
532 uint64_t DTPBiasedVal = Val - DynamicThreadPointerOffset;
659 uint64_t dtpBiasedVal = val - dynamicThreadPointerOffset;
533660
534 switch (Type) {
661 switch (type) {
535662 // TOC biased relocation.
536663 case R_PPC64_GOT16:
537664 case R_PPC64_GOT_TLSGD16:
538665 case R_PPC64_GOT_TLSLD16:
539666 case R_PPC64_TOC16:
540 return {R_PPC64_ADDR16, TocBiasedVal};
667 return {R_PPC64_ADDR16, tocBiasedVal};
541668 case R_PPC64_GOT16_DS:
542669 case R_PPC64_TOC16_DS:
543670 case R_PPC64_GOT_TPREL16_DS:
544671 case R_PPC64_GOT_DTPREL16_DS:
545 return {R_PPC64_ADDR16_DS, TocBiasedVal};
672 return {R_PPC64_ADDR16_DS, tocBiasedVal};
546673 case R_PPC64_GOT16_HA:
547674 case R_PPC64_GOT_TLSGD16_HA:
548675 case R_PPC64_GOT_TLSLD16_HA:
549676 case R_PPC64_GOT_TPREL16_HA:
550677 case R_PPC64_GOT_DTPREL16_HA:
551678 case R_PPC64_TOC16_HA:
552 return {R_PPC64_ADDR16_HA, TocBiasedVal};
679 return {R_PPC64_ADDR16_HA, tocBiasedVal};
553680 case R_PPC64_GOT16_HI:
554681 case R_PPC64_GOT_TLSGD16_HI:
555682 case R_PPC64_GOT_TLSLD16_HI:
556683 case R_PPC64_GOT_TPREL16_HI:
557684 case R_PPC64_GOT_DTPREL16_HI:
558685 case R_PPC64_TOC16_HI:
559 return {R_PPC64_ADDR16_HI, TocBiasedVal};
686 return {R_PPC64_ADDR16_HI, tocBiasedVal};
560687 case R_PPC64_GOT16_LO:
561688 case R_PPC64_GOT_TLSGD16_LO:
562689 case R_PPC64_GOT_TLSLD16_LO:
563690 case R_PPC64_TOC16_LO:
564 return {R_PPC64_ADDR16_LO, TocBiasedVal};
691 return {R_PPC64_ADDR16_LO, tocBiasedVal};
565692 case R_PPC64_GOT16_LO_DS:
566693 case R_PPC64_TOC16_LO_DS:
567694 case R_PPC64_GOT_TPREL16_LO_DS:
568695 case R_PPC64_GOT_DTPREL16_LO_DS:
569 return {R_PPC64_ADDR16_LO_DS, TocBiasedVal};
696 return {R_PPC64_ADDR16_LO_DS, tocBiasedVal};
570697
571698 // Dynamic Thread pointer biased relocation types.
572699 case R_PPC64_DTPREL16:
573 return {R_PPC64_ADDR16, DTPBiasedVal};
700 return {R_PPC64_ADDR16, dtpBiasedVal};
574701 case R_PPC64_DTPREL16_DS:
575 return {R_PPC64_ADDR16_DS, DTPBiasedVal};
702 return {R_PPC64_ADDR16_DS, dtpBiasedVal};
576703 case R_PPC64_DTPREL16_HA:
577 return {R_PPC64_ADDR16_HA, DTPBiasedVal};
704 return {R_PPC64_ADDR16_HA, dtpBiasedVal};
578705 case R_PPC64_DTPREL16_HI:
579 return {R_PPC64_ADDR16_HI, DTPBiasedVal};
706 return {R_PPC64_ADDR16_HI, dtpBiasedVal};
580707 case R_PPC64_DTPREL16_HIGHER:
581 return {R_PPC64_ADDR16_HIGHER, DTPBiasedVal};
708 return {R_PPC64_ADDR16_HIGHER, dtpBiasedVal};
582709 case R_PPC64_DTPREL16_HIGHERA:
583 return {R_PPC64_ADDR16_HIGHERA, DTPBiasedVal};
710 return {R_PPC64_ADDR16_HIGHERA, dtpBiasedVal};
584711 case R_PPC64_DTPREL16_HIGHEST:
585 return {R_PPC64_ADDR16_HIGHEST, DTPBiasedVal};
712 return {R_PPC64_ADDR16_HIGHEST, dtpBiasedVal};
586713 case R_PPC64_DTPREL16_HIGHESTA:
587 return {R_PPC64_ADDR16_HIGHESTA, DTPBiasedVal};
714 return {R_PPC64_ADDR16_HIGHESTA, dtpBiasedVal};
588715 case R_PPC64_DTPREL16_LO:
589 return {R_PPC64_ADDR16_LO, DTPBiasedVal};
716 return {R_PPC64_ADDR16_LO, dtpBiasedVal};
590717 case R_PPC64_DTPREL16_LO_DS:
591 return {R_PPC64_ADDR16_LO_DS, DTPBiasedVal};
718 return {R_PPC64_ADDR16_LO_DS, dtpBiasedVal};
592719 case R_PPC64_DTPREL64:
593 return {R_PPC64_ADDR64, DTPBiasedVal};
720 return {R_PPC64_ADDR64, dtpBiasedVal};
594721
595722 default:
596 return {Type, Val};
723 return {type, val};
597724 }
598725}
599726
600static bool isTocOptType(RelType Type) {
601 switch (Type) {
727static bool isTocOptType(RelType type) {
728 switch (type) {
602729 case R_PPC64_GOT16_HA:
603730 case R_PPC64_GOT16_LO_DS:
604731 case R_PPC64_TOC16_HA:
......@@ -610,66 +737,69 @@ static bool isTocOptType(RelType Type) {
610737 }
611738}
612739
613void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
740void PPC64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
614741 // We need to save the original relocation type to use in diagnostics, and
615742 // use the original type to determine if we should toc-optimize the
616743 // instructions being relocated.
617 RelType OriginalType = Type;
618 bool ShouldTocOptimize = isTocOptType(Type);
744 RelType originalType = type;
745 bool shouldTocOptimize = isTocOptType(type);
619746 // For dynamic thread pointer relative, toc-relative, and got-indirect
620747 // relocations, proceed in terms of the corresponding ADDR16 relocation type.
621 std::tie(Type, Val) = toAddr16Rel(Type, Val);
748 std::tie(type, val) = toAddr16Rel(type, val);
622749
623 switch (Type) {
750 switch (type) {
624751 case R_PPC64_ADDR14: {
625 checkAlignment(Loc, Val, 4, Type);
752 checkAlignment(loc, val, 4, type);
626753 // Preserve the AA/LK bits in the branch instruction
627 uint8_t AALK = Loc[3];
628 write16(Loc + 2, (AALK & 3) | (Val & 0xfffc));
754 uint8_t aalk = loc[3];
755 write16(loc + 2, (aalk & 3) | (val & 0xfffc));
629756 break;
630757 }
631758 case R_PPC64_ADDR16:
632 case R_PPC64_TPREL16:
633 checkInt(Loc, Val, 16, OriginalType);
634 write16(Loc, Val);
759 checkIntUInt(loc, val, 16, originalType);
760 write16(loc, val);
761 break;
762 case R_PPC64_ADDR32:
763 checkIntUInt(loc, val, 32, originalType);
764 write32(loc, val);
635765 break;
636766 case R_PPC64_ADDR16_DS:
637767 case R_PPC64_TPREL16_DS: {
638 checkInt(Loc, Val, 16, OriginalType);
768 checkInt(loc, val, 16, originalType);
639769 // DQ-form instructions use bits 28-31 as part of the instruction encoding
640770 // 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));
771 uint16_t mask = isDQFormInstruction(readFromHalf16(loc)) ? 0xf : 0x3;
772 checkAlignment(loc, lo(val), mask + 1, originalType);
773 write16(loc, (read16(loc) & mask) | lo(val));
644774 } break;
645775 case R_PPC64_ADDR16_HA:
646776 case R_PPC64_REL16_HA:
647777 case R_PPC64_TPREL16_HA:
648 if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0)
649 writeInstrFromHalf16(Loc, 0x60000000);
778 if (config->tocOptimize && shouldTocOptimize && ha(val) == 0)
779 writeFromHalf16(loc, 0x60000000);
650780 else
651 write16(Loc, ha(Val));
781 write16(loc, ha(val));
652782 break;
653783 case R_PPC64_ADDR16_HI:
654784 case R_PPC64_REL16_HI:
655785 case R_PPC64_TPREL16_HI:
656 write16(Loc, hi(Val));
786 write16(loc, hi(val));
657787 break;
658788 case R_PPC64_ADDR16_HIGHER:
659789 case R_PPC64_TPREL16_HIGHER:
660 write16(Loc, higher(Val));
790 write16(loc, higher(val));
661791 break;
662792 case R_PPC64_ADDR16_HIGHERA:
663793 case R_PPC64_TPREL16_HIGHERA:
664 write16(Loc, highera(Val));
794 write16(loc, highera(val));
665795 break;
666796 case R_PPC64_ADDR16_HIGHEST:
667797 case R_PPC64_TPREL16_HIGHEST:
668 write16(Loc, highest(Val));
798 write16(loc, highest(val));
669799 break;
670800 case R_PPC64_ADDR16_HIGHESTA:
671801 case R_PPC64_TPREL16_HIGHESTA:
672 write16(Loc, highesta(Val));
802 write16(loc, highesta(val));
673803 break;
674804 case R_PPC64_ADDR16_LO:
675805 case R_PPC64_REL16_LO:
......@@ -677,104 +807,119 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
677807 // When the high-adjusted part of a toc relocation evalutes to 0, it is
678808 // changed into a nop. The lo part then needs to be updated to use the
679809 // 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) +
810 if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) {
811 uint32_t insn = readFromHalf16(loc);
812 if (isInstructionUpdateForm(insn))
813 error(getErrorLocation(loc) +
684814 "can't toc-optimize an update instruction: 0x" +
685 utohexstr(Instr));
686 Instr = (Instr & 0xFFE00000) | 0x00020000;
687 writeInstrFromHalf16(Loc, Instr);
815 utohexstr(insn));
816 writeFromHalf16(loc, (insn & 0xffe00000) | 0x00020000 | lo(val));
817 } else {
818 write16(loc, lo(val));
688819 }
689 write16(Loc, lo(Val));
690820 break;
691821 case R_PPC64_ADDR16_LO_DS:
692822 case R_PPC64_TPREL16_LO_DS: {
693823 // DQ-form instructions use bits 28-31 as part of the instruction encoding
694824 // 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) {
825 uint32_t insn = readFromHalf16(loc);
826 uint16_t mask = isDQFormInstruction(insn) ? 0xf : 0x3;
827 checkAlignment(loc, lo(val), mask + 1, originalType);
828 if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) {
699829 // When the high-adjusted part of a toc relocation evalutes to 0, it is
700830 // changed into a nop. The lo part then needs to be updated to use the toc
701831 // pointer register r2, as the base register.
702 if (isInstructionUpdateForm(Inst))
703 error(getErrorLocation(Loc) +
832 if (isInstructionUpdateForm(insn))
833 error(getErrorLocation(loc) +
704834 "Can't toc-optimize an update instruction: 0x" +
705 Twine::utohexstr(Inst));
706 Inst = (Inst & 0xFFE0000F) | 0x00020000;
707 writeInstrFromHalf16(Loc, Inst);
835 Twine::utohexstr(insn));
836 insn &= 0xffe00000 | mask;
837 writeFromHalf16(loc, insn | 0x00020000 | lo(val));
838 } else {
839 write16(loc, (read16(loc) & mask) | lo(val));
708840 }
709 write16(Loc, (read16(Loc) & Mask) | lo(Val));
710841 } break;
711 case R_PPC64_ADDR32:
842 case R_PPC64_TPREL16:
843 checkInt(loc, val, 16, originalType);
844 write16(loc, val);
845 break;
712846 case R_PPC64_REL32:
713 checkInt(Loc, Val, 32, Type);
714 write32(Loc, Val);
847 checkInt(loc, val, 32, type);
848 write32(loc, val);
715849 break;
716850 case R_PPC64_ADDR64:
717851 case R_PPC64_REL64:
718852 case R_PPC64_TOC:
719 write64(Loc, Val);
853 write64(loc, val);
720854 break;
721855 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));
856 uint32_t mask = 0x0000FFFC;
857 checkInt(loc, val, 16, type);
858 checkAlignment(loc, val, 4, type);
859 write32(loc, (read32(loc) & ~mask) | (val & mask));
726860 break;
727861 }
728862 case R_PPC64_REL24: {
729 uint32_t Mask = 0x03FFFFFC;
730 checkInt(Loc, Val, 26, Type);
731 checkAlignment(Loc, Val, 4, Type);
732 write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
863 uint32_t mask = 0x03FFFFFC;
864 checkInt(loc, val, 26, type);
865 checkAlignment(loc, val, 4, type);
866 write32(loc, (read32(loc) & ~mask) | (val & mask));
733867 break;
734868 }
735869 case R_PPC64_DTPREL64:
736 write64(Loc, Val - DynamicThreadPointerOffset);
870 write64(loc, val - dynamicThreadPointerOffset);
737871 break;
738872 default:
739 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
873 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type));
740874 }
741875}
742876
743bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
744 uint64_t BranchAddr, const Symbol &S) const {
745 if (Type != R_PPC64_REL14 && Type != R_PPC64_REL24)
877bool PPC64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
878 uint64_t branchAddr, const Symbol &s) const {
879 if (type != R_PPC64_REL14 && type != R_PPC64_REL24)
746880 return false;
747881
748882 // If a function is in the Plt it needs to be called with a call-stub.
749 if (S.isInPlt())
883 if (s.isInPlt())
750884 return true;
751885
752886 // If a symbol is a weak undefined and we are compiling an executable
753887 // it doesn't need a range-extending thunk since it can't be called.
754 if (S.isUndefWeak() && !Config->Shared)
888 if (s.isUndefWeak() && !config->shared)
755889 return false;
756890
757891 // If the offset exceeds the range of the branch type then it will need
758892 // a range-extending thunk.
759 return !inBranchRange(Type, BranchAddr, S.getVA());
893 // See the comment in getRelocTargetVA() about R_PPC64_CALL.
894 return !inBranchRange(type, branchAddr,
895 s.getVA() +
896 getPPC64GlobalEntryToLocalEntryOffset(s.stOther));
760897}
761898
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);
899uint32_t PPC64::getThunkSectionSpacing() const {
900 // See comment in Arch/ARM.cpp for a more detailed explanation of
901 // getThunkSectionSpacing(). For PPC64 we pick the constant here based on
902 // R_PPC64_REL24, which is used by unconditional branch instructions.
903 // 0x2000000 = (1 << 24-1) * 4
904 return 0x2000000;
905}
906
907bool PPC64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
908 int64_t offset = dst - src;
909 if (type == R_PPC64_REL14)
910 return isInt<16>(offset);
911 if (type == R_PPC64_REL24)
912 return isInt<26>(offset);
768913 llvm_unreachable("unsupported relocation type used in branch");
769914}
770915
771RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
772 RelExpr Expr) const {
773 if (Expr == R_RELAX_TLS_GD_TO_IE)
916RelExpr PPC64::adjustRelaxExpr(RelType type, const uint8_t *data,
917 RelExpr expr) const {
918 if (expr == R_RELAX_TLS_GD_TO_IE)
774919 return R_RELAX_TLS_GD_TO_IE_GOT_OFF;
775 if (Expr == R_RELAX_TLS_LD_TO_LE)
920 if (expr == R_RELAX_TLS_LD_TO_LE)
776921 return R_RELAX_TLS_LD_TO_LE_ABS;
777 return Expr;
922 return expr;
778923}
779924
780925// Reference: 3.7.4.1 of the 64-bit ELF V2 abi supplement.
......@@ -794,24 +939,25 @@ RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
794939// thread pointer.
795940// Since the nop must directly follow the call, the R_PPC64_TLSGD relocation is
796941// used as the relaxation hint for both steps 2 and 3.
797void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
798 switch (Type) {
942void PPC64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
943 switch (type) {
799944 case R_PPC64_GOT_TLSGD16_HA:
800945 // This is relaxed from addis rT, r2, sym@got@tlsgd@ha to
801946 // addis rT, r2, sym@got@tprel@ha.
802 relocateOne(Loc, R_PPC64_GOT_TPREL16_HA, Val);
947 relocateOne(loc, R_PPC64_GOT_TPREL16_HA, val);
803948 return;
949 case R_PPC64_GOT_TLSGD16:
804950 case R_PPC64_GOT_TLSGD16_LO: {
805951 // Relax from addi r3, rA, sym@got@tlsgd@l to
806952 // ld r3, sym@got@tprel@l(rA)
807 uint32_t InputRegister = (readInstrFromHalf16(Loc) & (0x1f << 16));
808 writeInstrFromHalf16(Loc, 0xE8600000 | InputRegister);
809 relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val);
953 uint32_t ra = (readFromHalf16(loc) & (0x1f << 16));
954 writeFromHalf16(loc, 0xe8600000 | ra);
955 relocateOne(loc, R_PPC64_GOT_TPREL16_LO_DS, val);
810956 return;
811957 }
812958 case R_PPC64_TLSGD:
813 write32(Loc, 0x60000000); // bl __tls_get_addr(sym@tlsgd) --> nop
814 write32(Loc + 4, 0x7c636A14); // nop --> add r3, r3, r13
959 write32(loc, 0x60000000); // bl __tls_get_addr(sym@tlsgd) --> nop
960 write32(loc + 4, 0x7c636A14); // nop --> add r3, r3, r13
815961 return;
816962 default:
817963 llvm_unreachable("unsupported relocation for TLS GD to IE relaxation");
......@@ -846,86 +992,86 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
846992// pair by split-stack-size-adjust.
847993// addis r12, r1, ha(-stack-frame size - split-stack-adjust-size)
848994// 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 {
995bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
996 uint8_t stOther) const {
851997 // If the caller has a global entry point adjust the buffer past it. The start
852998 // of the split-stack prologue will be at the local entry point.
853 Loc += getPPC64GlobalEntryToLocalEntryOffset(StOther);
999 loc += getPPC64GlobalEntryToLocalEntryOffset(stOther);
8541000
8551001 // At the very least we expect to see a load of some split-stack data from the
8561002 // tcb, and 2 instructions that calculate the ending stack address this
8571003 // function will require. If there is not enough room for at least 3
8581004 // instructions it can't be a split-stack prologue.
859 if (Loc + 12 >= End)
1005 if (loc + 12 >= end)
8601006 return false;
8611007
8621008 // First instruction must be `ld r0, -0x7000-64(r13)`
863 if (read32(Loc) != 0xe80d8fc0)
1009 if (read32(loc) != 0xe80d8fc0)
8641010 return false;
8651011
866 int16_t HiImm = 0;
867 int16_t LoImm = 0;
1012 int16_t hiImm = 0;
1013 int16_t loImm = 0;
8681014 // First instruction can be either an addis if the frame size is larger then
8691015 // 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;
1016 int32_t firstInstr = read32(loc + 4);
1017 if (getPrimaryOpCode(firstInstr) == 15) {
1018 hiImm = firstInstr & 0xFFFF;
1019 } else if (getPrimaryOpCode(firstInstr) == 14) {
1020 loImm = firstInstr & 0xFFFF;
8751021 } else {
8761022 return false;
8771023 }
8781024
8791025 // Second instruction is either an addi or a nop. If the first instruction was
8801026 // 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) {
1027 uint32_t secondInstr = read32(loc + 8);
1028 if (!loImm && getPrimaryOpCode(secondInstr) == 14) {
1029 loImm = secondInstr & 0xFFFF;
1030 } else if (secondInstr != 0x60000000) {
8851031 return false;
8861032 }
8871033
8881034 // The register operands of the first instruction should be the stack-pointer
8891035 // (r1) as the input (RA) and r12 as the output (RT). If the second
8901036 // 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);
1037 auto checkRegOperands = [](uint32_t instr, uint8_t expectedRT,
1038 uint8_t expectedRA) {
1039 return ((instr & 0x3E00000) >> 21 == expectedRT) &&
1040 ((instr & 0x1F0000) >> 16 == expectedRA);
8951041 };
896 if (!CheckRegOperands(FirstInstr, 12, 1))
1042 if (!checkRegOperands(firstInstr, 12, 1))
8971043 return false;
898 if (SecondInstr != 0x60000000 && !CheckRegOperands(SecondInstr, 12, 12))
1044 if (secondInstr != 0x60000000 && !checkRegOperands(secondInstr, 12, 12))
8991045 return false;
9001046
901 int32_t StackFrameSize = (HiImm * 65536) + LoImm;
1047 int32_t stackFrameSize = (hiImm * 65536) + loImm;
9021048 // Check that the adjusted size doesn't overflow what we can represent with 2
9031049 // instructions.
904 if (StackFrameSize < Config->SplitStackAdjustSize + INT32_MIN) {
905 error(getErrorLocation(Loc) + "split-stack prologue adjustment overflows");
1050 if (stackFrameSize < config->splitStackAdjustSize + INT32_MIN) {
1051 error(getErrorLocation(loc) + "split-stack prologue adjustment overflows");
9061052 return false;
9071053 }
9081054
909 int32_t AdjustedStackFrameSize =
910 StackFrameSize - Config->SplitStackAdjustSize;
1055 int32_t adjustedStackFrameSize =
1056 stackFrameSize - config->splitStackAdjustSize;
9111057
912 LoImm = AdjustedStackFrameSize & 0xFFFF;
913 HiImm = (AdjustedStackFrameSize + 0x8000) >> 16;
914 if (HiImm) {
915 write32(Loc + 4, 0x3D810000 | (uint16_t)HiImm);
1058 loImm = adjustedStackFrameSize & 0xFFFF;
1059 hiImm = (adjustedStackFrameSize + 0x8000) >> 16;
1060 if (hiImm) {
1061 write32(loc + 4, 0x3D810000 | (uint16_t)hiImm);
9161062 // 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);
1063 secondInstr = loImm ? 0x398C0000 | (uint16_t)loImm : 0x60000000;
1064 write32(loc + 8, secondInstr);
9191065 } else {
9201066 // addi r12, r1, imm
921 write32(Loc + 4, (0x39810000) | (uint16_t)LoImm);
922 write32(Loc + 8, 0x60000000);
1067 write32(loc + 4, (0x39810000) | (uint16_t)loImm);
1068 write32(loc + 8, 0x60000000);
9231069 }
9241070
9251071 return true;
9261072}
9271073
9281074TargetInfo *elf::getPPC64TargetInfo() {
929 static PPC64 Target;
930 return &Target;
1075 static PPC64 target;
1076 return &target;
9311077}
deps/lld/ELF/Arch/RISCV.cpp+282-119
......@@ -1,13 +1,13 @@
11//===- RISCV.cpp ----------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
109#include "InputFiles.h"
10#include "SyntheticSections.h"
1111#include "Target.h"
1212
1313using namespace llvm;
......@@ -23,59 +23,207 @@ class RISCV final : public TargetInfo {
2323public:
2424 RISCV();
2525 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;
26 void writeGotHeader(uint8_t *buf) const override;
27 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
28 void writePltHeader(uint8_t *buf) const override;
29 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
30 int32_t index, unsigned relOff) const override;
31 RelType getDynRel(RelType type) const override;
32 RelExpr getRelExpr(RelType type, const Symbol &s,
33 const uint8_t *loc) const override;
34 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
2935};
3036
3137} // end anonymous namespace
3238
33RISCV::RISCV() { NoneRel = R_RISCV_NONE; }
39const uint64_t dtpOffset = 0x800;
40
41enum Op {
42 ADDI = 0x13,
43 AUIPC = 0x17,
44 JALR = 0x67,
45 LD = 0x3003,
46 LW = 0x2003,
47 SRLI = 0x5013,
48 SUB = 0x40000033,
49};
50
51enum Reg {
52 X_RA = 1,
53 X_T0 = 5,
54 X_T1 = 6,
55 X_T2 = 7,
56 X_T3 = 28,
57};
58
59static uint32_t hi20(uint32_t val) { return (val + 0x800) >> 12; }
60static uint32_t lo12(uint32_t val) { return val & 4095; }
61
62static uint32_t itype(uint32_t op, uint32_t rd, uint32_t rs1, uint32_t imm) {
63 return op | (rd << 7) | (rs1 << 15) | (imm << 20);
64}
65static uint32_t rtype(uint32_t op, uint32_t rd, uint32_t rs1, uint32_t rs2) {
66 return op | (rd << 7) | (rs1 << 15) | (rs2 << 20);
67}
68static uint32_t utype(uint32_t op, uint32_t rd, uint32_t imm) {
69 return op | (rd << 7) | (imm << 12);
70}
71
72RISCV::RISCV() {
73 copyRel = R_RISCV_COPY;
74 noneRel = R_RISCV_NONE;
75 pltRel = R_RISCV_JUMP_SLOT;
76 relativeRel = R_RISCV_RELATIVE;
77 if (config->is64) {
78 symbolicRel = R_RISCV_64;
79 tlsModuleIndexRel = R_RISCV_TLS_DTPMOD64;
80 tlsOffsetRel = R_RISCV_TLS_DTPREL64;
81 tlsGotRel = R_RISCV_TLS_TPREL64;
82 } else {
83 symbolicRel = R_RISCV_32;
84 tlsModuleIndexRel = R_RISCV_TLS_DTPMOD32;
85 tlsOffsetRel = R_RISCV_TLS_DTPREL32;
86 tlsGotRel = R_RISCV_TLS_TPREL32;
87 }
88 gotRel = symbolicRel;
89
90 // .got[0] = _DYNAMIC
91 gotBaseSymInGotPlt = false;
92 gotHeaderEntriesNum = 1;
93
94 // .got.plt[0] = _dl_runtime_resolve, .got.plt[1] = link_map
95 gotPltHeaderEntriesNum = 2;
3496
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;
97 pltEntrySize = 16;
98 pltHeaderSize = 32;
99}
100
101static uint32_t getEFlags(InputFile *f) {
102 if (config->is64)
103 return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader()->e_flags;
104 return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader()->e_flags;
39105}
40106
41107uint32_t RISCV::calcEFlags() const {
42 assert(!ObjectFiles.empty());
108 assert(!objectFiles.empty());
43109
44 uint32_t Target = getEFlags(ObjectFiles.front());
110 uint32_t target = getEFlags(objectFiles.front());
45111
46 for (InputFile *F : ObjectFiles) {
47 uint32_t EFlags = getEFlags(F);
48 if (EFlags & EF_RISCV_RVC)
49 Target |= EF_RISCV_RVC;
112 for (InputFile *f : objectFiles) {
113 uint32_t eflags = getEFlags(f);
114 if (eflags & EF_RISCV_RVC)
115 target |= EF_RISCV_RVC;
50116
51 if ((EFlags & EF_RISCV_FLOAT_ABI) != (Target & EF_RISCV_FLOAT_ABI))
52 error(toString(F) +
117 if ((eflags & EF_RISCV_FLOAT_ABI) != (target & EF_RISCV_FLOAT_ABI))
118 error(toString(f) +
53119 ": cannot link object files with different floating-point ABI");
54120
55 if ((EFlags & EF_RISCV_RVE) != (Target & EF_RISCV_RVE))
56 error(toString(F) +
121 if ((eflags & EF_RISCV_RVE) != (target & EF_RISCV_RVE))
122 error(toString(f) +
57123 ": cannot link object files with different EF_RISCV_RVE");
58124 }
59125
60 return Target;
126 return target;
127}
128
129void RISCV::writeGotHeader(uint8_t *buf) const {
130 if (config->is64)
131 write64le(buf, mainPart->dynamic->getVA());
132 else
133 write32le(buf, mainPart->dynamic->getVA());
134}
135
136void RISCV::writeGotPlt(uint8_t *buf, const Symbol &s) const {
137 if (config->is64)
138 write64le(buf, in.plt->getVA());
139 else
140 write32le(buf, in.plt->getVA());
141}
142
143void RISCV::writePltHeader(uint8_t *buf) const {
144 // 1: auipc t2, %pcrel_hi(.got.plt)
145 // sub t1, t1, t3
146 // l[wd] t3, %pcrel_lo(1b)(t2); t3 = _dl_runtime_resolve
147 // addi t1, t1, -pltHeaderSize-12; t1 = &.plt[i] - &.plt[0]
148 // addi t0, t2, %pcrel_lo(1b)
149 // srli t1, t1, (rv64?1:2); t1 = &.got.plt[i] - &.got.plt[0]
150 // l[wd] t0, Wordsize(t0); t0 = link_map
151 // jr t3
152 uint32_t offset = in.gotPlt->getVA() - in.plt->getVA();
153 uint32_t load = config->is64 ? LD : LW;
154 write32le(buf + 0, utype(AUIPC, X_T2, hi20(offset)));
155 write32le(buf + 4, rtype(SUB, X_T1, X_T1, X_T3));
156 write32le(buf + 8, itype(load, X_T3, X_T2, lo12(offset)));
157 write32le(buf + 12, itype(ADDI, X_T1, X_T1, -target->pltHeaderSize - 12));
158 write32le(buf + 16, itype(ADDI, X_T0, X_T2, lo12(offset)));
159 write32le(buf + 20, itype(SRLI, X_T1, X_T1, config->is64 ? 1 : 2));
160 write32le(buf + 24, itype(load, X_T0, X_T0, config->wordsize));
161 write32le(buf + 28, itype(JALR, 0, X_T3, 0));
61162}
62163
63RelExpr RISCV::getRelExpr(const RelType Type, const Symbol &S,
64 const uint8_t *Loc) const {
65 switch (Type) {
164void RISCV::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
165 uint64_t pltEntryAddr, int32_t index,
166 unsigned relOff) const {
167 // 1: auipc t3, %pcrel_hi(f@.got.plt)
168 // l[wd] t3, %pcrel_lo(1b)(t3)
169 // jalr t1, t3
170 // nop
171 uint32_t offset = gotPltEntryAddr - pltEntryAddr;
172 write32le(buf + 0, utype(AUIPC, X_T3, hi20(offset)));
173 write32le(buf + 4, itype(config->is64 ? LD : LW, X_T3, X_T3, lo12(offset)));
174 write32le(buf + 8, itype(JALR, X_T1, X_T3, 0));
175 write32le(buf + 12, itype(ADDI, 0, 0, 0));
176}
177
178RelType RISCV::getDynRel(RelType type) const {
179 return type == target->symbolicRel ? type
180 : static_cast<RelType>(R_RISCV_NONE);
181}
182
183RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
184 const uint8_t *loc) const {
185 switch (type) {
186 case R_RISCV_ADD8:
187 case R_RISCV_ADD16:
188 case R_RISCV_ADD32:
189 case R_RISCV_ADD64:
190 case R_RISCV_SET6:
191 case R_RISCV_SET8:
192 case R_RISCV_SET16:
193 case R_RISCV_SET32:
194 case R_RISCV_SUB6:
195 case R_RISCV_SUB8:
196 case R_RISCV_SUB16:
197 case R_RISCV_SUB32:
198 case R_RISCV_SUB64:
199 return R_RISCV_ADD;
66200 case R_RISCV_JAL:
67201 case R_RISCV_BRANCH:
68 case R_RISCV_CALL:
69202 case R_RISCV_PCREL_HI20:
70203 case R_RISCV_RVC_BRANCH:
71204 case R_RISCV_RVC_JUMP:
72205 case R_RISCV_32_PCREL:
73206 return R_PC;
207 case R_RISCV_CALL:
208 case R_RISCV_CALL_PLT:
209 return R_PLT_PC;
210 case R_RISCV_GOT_HI20:
211 return R_GOT_PC;
74212 case R_RISCV_PCREL_LO12_I:
75213 case R_RISCV_PCREL_LO12_S:
76214 return R_RISCV_PC_INDIRECT;
215 case R_RISCV_TLS_GD_HI20:
216 return R_TLSGD_PC;
217 case R_RISCV_TLS_GOT_HI20:
218 config->hasStaticTlsModel = true;
219 return R_GOT_PC;
220 case R_RISCV_TPREL_HI20:
221 case R_RISCV_TPREL_LO12_I:
222 case R_RISCV_TPREL_LO12_S:
223 return R_TLS;
77224 case R_RISCV_RELAX:
78225 case R_RISCV_ALIGN:
226 case R_RISCV_TPREL_ADD:
79227 return R_HINT;
80228 default:
81229 return R_ABS;
......@@ -83,175 +231,190 @@ RelExpr RISCV::getRelExpr(const RelType Type, const Symbol &S,
83231}
84232
85233// 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;
234static uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end) {
235 return (v & ((1ULL << (begin + 1)) - 1)) >> end;
88236}
89237
90void RISCV::relocateOne(uint8_t *Loc, const RelType Type,
91 const uint64_t Val) const {
92 switch (Type) {
238void RISCV::relocateOne(uint8_t *loc, const RelType type,
239 const uint64_t val) const {
240 const unsigned bits = config->wordsize * 8;
241
242 switch (type) {
93243 case R_RISCV_32:
94 write32le(Loc, Val);
244 write32le(loc, val);
95245 return;
96246 case R_RISCV_64:
97 write64le(Loc, Val);
247 write64le(loc, val);
98248 return;
99249
100250 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);
251 checkInt(loc, static_cast<int64_t>(val) >> 1, 8, type);
252 checkAlignment(loc, val, 2, type);
253 uint16_t insn = read16le(loc) & 0xE383;
254 uint16_t imm8 = extractBits(val, 8, 8) << 12;
255 uint16_t imm4_3 = extractBits(val, 4, 3) << 10;
256 uint16_t imm7_6 = extractBits(val, 7, 6) << 5;
257 uint16_t imm2_1 = extractBits(val, 2, 1) << 3;
258 uint16_t imm5 = extractBits(val, 5, 5) << 2;
259 insn |= imm8 | imm4_3 | imm7_6 | imm2_1 | imm5;
260
261 write16le(loc, insn);
112262 return;
113263 }
114264
115265 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);
266 checkInt(loc, static_cast<int64_t>(val) >> 1, 11, type);
267 checkAlignment(loc, val, 2, type);
268 uint16_t insn = read16le(loc) & 0xE003;
269 uint16_t imm11 = extractBits(val, 11, 11) << 12;
270 uint16_t imm4 = extractBits(val, 4, 4) << 11;
271 uint16_t imm9_8 = extractBits(val, 9, 8) << 9;
272 uint16_t imm10 = extractBits(val, 10, 10) << 8;
273 uint16_t imm6 = extractBits(val, 6, 6) << 7;
274 uint16_t imm7 = extractBits(val, 7, 7) << 6;
275 uint16_t imm3_1 = extractBits(val, 3, 1) << 3;
276 uint16_t imm5 = extractBits(val, 5, 5) << 2;
277 insn |= imm11 | imm4 | imm9_8 | imm10 | imm6 | imm7 | imm3_1 | imm5;
278
279 write16le(loc, insn);
130280 return;
131281 }
132282
133283 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);
284 int64_t imm = SignExtend64(val + 0x800, bits) >> 12;
285 checkInt(loc, imm, 6, type);
286 if (imm == 0) { // `c.lui rd, 0` is illegal, convert to `c.li rd, 0`
287 write16le(loc, (read16le(loc) & 0x0F83) | 0x4000);
138288 } 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);
289 uint16_t imm17 = extractBits(val + 0x800, 17, 17) << 12;
290 uint16_t imm16_12 = extractBits(val + 0x800, 16, 12) << 2;
291 write16le(loc, (read16le(loc) & 0xEF83) | imm17 | imm16_12);
142292 }
143293 return;
144294 }
145295
146296 case R_RISCV_JAL: {
147 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 20, Type);
148 checkAlignment(Loc, Val, 2, Type);
297 checkInt(loc, static_cast<int64_t>(val) >> 1, 20, type);
298 checkAlignment(loc, val, 2, type);
149299
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;
300 uint32_t insn = read32le(loc) & 0xFFF;
301 uint32_t imm20 = extractBits(val, 20, 20) << 31;
302 uint32_t imm10_1 = extractBits(val, 10, 1) << 21;
303 uint32_t imm11 = extractBits(val, 11, 11) << 20;
304 uint32_t imm19_12 = extractBits(val, 19, 12) << 12;
305 insn |= imm20 | imm10_1 | imm11 | imm19_12;
156306
157 write32le(Loc, Insn);
307 write32le(loc, insn);
158308 return;
159309 }
160310
161311 case R_RISCV_BRANCH: {
162 checkInt(Loc, static_cast<int64_t>(Val) >> 1, 12, Type);
163 checkAlignment(Loc, Val, 2, Type);
312 checkInt(loc, static_cast<int64_t>(val) >> 1, 12, type);
313 checkAlignment(loc, val, 2, type);
164314
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;
315 uint32_t insn = read32le(loc) & 0x1FFF07F;
316 uint32_t imm12 = extractBits(val, 12, 12) << 31;
317 uint32_t imm10_5 = extractBits(val, 10, 5) << 25;
318 uint32_t imm4_1 = extractBits(val, 4, 1) << 8;
319 uint32_t imm11 = extractBits(val, 11, 11) << 7;
320 insn |= imm12 | imm10_5 | imm4_1 | imm11;
171321
172 write32le(Loc, Insn);
322 write32le(loc, insn);
173323 return;
174324 }
175325
176326 // 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);
327 case R_RISCV_CALL:
328 case R_RISCV_CALL_PLT: {
329 int64_t hi = SignExtend64(val + 0x800, bits) >> 12;
330 checkInt(loc, hi, 20, type);
331 if (isInt<20>(hi)) {
332 relocateOne(loc, R_RISCV_PCREL_HI20, val);
333 relocateOne(loc + 4, R_RISCV_PCREL_LO12_I, val);
182334 }
183335 return;
184336 }
185337
338 case R_RISCV_GOT_HI20:
186339 case R_RISCV_PCREL_HI20:
340 case R_RISCV_TLS_GD_HI20:
341 case R_RISCV_TLS_GOT_HI20:
342 case R_RISCV_TPREL_HI20:
187343 case R_RISCV_HI20: {
188 checkInt(Loc, Val, 32, Type);
189 uint32_t Hi = Val + 0x800;
190 write32le(Loc, (read32le(Loc) & 0xFFF) | (Hi & 0xFFFFF000));
344 uint64_t hi = val + 0x800;
345 checkInt(loc, SignExtend64(hi, bits) >> 12, 20, type);
346 write32le(loc, (read32le(loc) & 0xFFF) | (hi & 0xFFFFF000));
191347 return;
192348 }
193349
194350 case R_RISCV_PCREL_LO12_I:
351 case R_RISCV_TPREL_LO12_I:
195352 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));
353 uint64_t hi = (val + 0x800) >> 12;
354 uint64_t lo = val - (hi << 12);
355 write32le(loc, (read32le(loc) & 0xFFFFF) | ((lo & 0xFFF) << 20));
200356 return;
201357 }
202358
203359 case R_RISCV_PCREL_LO12_S:
360 case R_RISCV_TPREL_LO12_S:
204361 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);
362 uint64_t hi = (val + 0x800) >> 12;
363 uint64_t lo = val - (hi << 12);
364 uint32_t imm11_5 = extractBits(lo, 11, 5) << 25;
365 uint32_t imm4_0 = extractBits(lo, 4, 0) << 7;
366 write32le(loc, (read32le(loc) & 0x1FFF07F) | imm11_5 | imm4_0);
211367 return;
212368 }
213369
214370 case R_RISCV_ADD8:
215 *Loc += Val;
371 *loc += val;
216372 return;
217373 case R_RISCV_ADD16:
218 write16le(Loc, read16le(Loc) + Val);
374 write16le(loc, read16le(loc) + val);
219375 return;
220376 case R_RISCV_ADD32:
221 write32le(Loc, read32le(Loc) + Val);
377 write32le(loc, read32le(loc) + val);
222378 return;
223379 case R_RISCV_ADD64:
224 write64le(Loc, read64le(Loc) + Val);
380 write64le(loc, read64le(loc) + val);
225381 return;
226382 case R_RISCV_SUB6:
227 *Loc = (*Loc & 0xc0) | (((*Loc & 0x3f) - Val) & 0x3f);
383 *loc = (*loc & 0xc0) | (((*loc & 0x3f) - val) & 0x3f);
228384 return;
229385 case R_RISCV_SUB8:
230 *Loc -= Val;
386 *loc -= val;
231387 return;
232388 case R_RISCV_SUB16:
233 write16le(Loc, read16le(Loc) - Val);
389 write16le(loc, read16le(loc) - val);
234390 return;
235391 case R_RISCV_SUB32:
236 write32le(Loc, read32le(Loc) - Val);
392 write32le(loc, read32le(loc) - val);
237393 return;
238394 case R_RISCV_SUB64:
239 write64le(Loc, read64le(Loc) - Val);
395 write64le(loc, read64le(loc) - val);
240396 return;
241397 case R_RISCV_SET6:
242 *Loc = (*Loc & 0xc0) | (Val & 0x3f);
398 *loc = (*loc & 0xc0) | (val & 0x3f);
243399 return;
244400 case R_RISCV_SET8:
245 *Loc = Val;
401 *loc = val;
246402 return;
247403 case R_RISCV_SET16:
248 write16le(Loc, Val);
404 write16le(loc, val);
249405 return;
250406 case R_RISCV_SET32:
251407 case R_RISCV_32_PCREL:
252 write32le(Loc, Val);
408 write32le(loc, val);
253409 return;
254410
411 case R_RISCV_TLS_DTPREL32:
412 write32le(loc, val - dtpOffset);
413 break;
414 case R_RISCV_TLS_DTPREL64:
415 write64le(loc, val - dtpOffset);
416 break;
417
255418 case R_RISCV_ALIGN:
256419 case R_RISCV_RELAX:
257420 return; // Ignored (for now)
......@@ -267,13 +430,13 @@ void RISCV::relocateOne(uint8_t *Loc, const RelType Type,
267430 case R_RISCV_GPREL_I:
268431 case R_RISCV_GPREL_S:
269432 default:
270 error(getErrorLocation(Loc) +
271 "unimplemented relocation: " + toString(Type));
433 error(getErrorLocation(loc) +
434 "unimplemented relocation: " + toString(type));
272435 return;
273436 }
274437}
275438
276439TargetInfo *elf::getRISCVTargetInfo() {
277 static RISCV Target;
278 return &Target;
440 static RISCV target;
441 return &target;
279442}
deps/lld/ELF/Arch/SPARCV9.cpp+51-51
......@@ -1,9 +1,8 @@
11//===- SPARCV9.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -24,32 +23,32 @@ namespace {
2423class SPARCV9 final : public TargetInfo {
2524public:
2625 SPARCV9();
27 RelExpr getRelExpr(RelType Type, const Symbol &S,
28 const uint8_t *Loc) const override;
29 void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
30 int32_t Index, unsigned RelOff) const override;
31 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
26 RelExpr getRelExpr(RelType type, const Symbol &s,
27 const uint8_t *loc) const override;
28 void writePlt(uint8_t *buf, uint64_t gotEntryAddr, uint64_t pltEntryAddr,
29 int32_t index, unsigned relOff) const override;
30 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
3231};
3332} // namespace
3433
3534SPARCV9::SPARCV9() {
36 CopyRel = R_SPARC_COPY;
37 GotRel = R_SPARC_GLOB_DAT;
38 NoneRel = R_SPARC_NONE;
39 PltRel = R_SPARC_JMP_SLOT;
40 RelativeRel = R_SPARC_RELATIVE;
41 GotEntrySize = 8;
42 PltEntrySize = 32;
43 PltHeaderSize = 4 * PltEntrySize;
35 copyRel = R_SPARC_COPY;
36 gotRel = R_SPARC_GLOB_DAT;
37 noneRel = R_SPARC_NONE;
38 pltRel = R_SPARC_JMP_SLOT;
39 relativeRel = R_SPARC_RELATIVE;
40 symbolicRel = R_SPARC_64;
41 pltEntrySize = 32;
42 pltHeaderSize = 4 * pltEntrySize;
4443
45 PageSize = 8192;
46 DefaultMaxPageSize = 0x100000;
47 DefaultImageBase = 0x100000;
44 defaultCommonPageSize = 8192;
45 defaultMaxPageSize = 0x100000;
46 defaultImageBase = 0x100000;
4847}
4948
50RelExpr SPARCV9::getRelExpr(RelType Type, const Symbol &S,
51 const uint8_t *Loc) const {
52 switch (Type) {
49RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s,
50 const uint8_t *loc) const {
51 switch (type) {
5352 case R_SPARC_32:
5453 case R_SPARC_UA32:
5554 case R_SPARC_64:
......@@ -69,64 +68,65 @@ RelExpr SPARCV9::getRelExpr(RelType Type, const Symbol &S,
6968 case R_SPARC_NONE:
7069 return R_NONE;
7170 default:
72 return R_INVALID;
71 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
72 ") against symbol " + toString(s));
73 return R_NONE;
7374 }
7475}
7576
76void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
77 switch (Type) {
77void SPARCV9::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
78 switch (type) {
7879 case R_SPARC_32:
7980 case R_SPARC_UA32:
8081 // V-word32
81 checkUInt(Loc, Val, 32, Type);
82 write32be(Loc, Val);
82 checkUInt(loc, val, 32, type);
83 write32be(loc, val);
8384 break;
8485 case R_SPARC_DISP32:
8586 // V-disp32
86 checkInt(Loc, Val, 32, Type);
87 write32be(Loc, Val);
87 checkInt(loc, val, 32, type);
88 write32be(loc, val);
8889 break;
8990 case R_SPARC_WDISP30:
9091 case R_SPARC_WPLT30:
9192 // V-disp30
92 checkInt(Loc, Val, 32, Type);
93 write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff));
93 checkInt(loc, val, 32, type);
94 write32be(loc, (read32be(loc) & ~0x3fffffff) | ((val >> 2) & 0x3fffffff));
9495 break;
9596 case R_SPARC_22:
9697 // V-imm22
97 checkUInt(Loc, Val, 22, Type);
98 write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff));
98 checkUInt(loc, val, 22, type);
99 write32be(loc, (read32be(loc) & ~0x003fffff) | (val & 0x003fffff));
99100 break;
100101 case R_SPARC_GOT22:
101102 case R_SPARC_PC22:
102103 // T-imm22
103 write32be(Loc, (read32be(Loc) & ~0x003fffff) | ((Val >> 10) & 0x003fffff));
104 write32be(loc, (read32be(loc) & ~0x003fffff) | ((val >> 10) & 0x003fffff));
104105 break;
105106 case R_SPARC_WDISP19:
106107 // V-disp19
107 checkInt(Loc, Val, 21, Type);
108 write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff));
108 checkInt(loc, val, 21, type);
109 write32be(loc, (read32be(loc) & ~0x0007ffff) | ((val >> 2) & 0x0007ffff));
109110 break;
110111 case R_SPARC_GOT10:
111112 case R_SPARC_PC10:
112113 // T-simm10
113 write32be(Loc, (read32be(Loc) & ~0x000003ff) | (Val & 0x000003ff));
114 write32be(loc, (read32be(loc) & ~0x000003ff) | (val & 0x000003ff));
114115 break;
115116 case R_SPARC_64:
116117 case R_SPARC_UA64:
117 case R_SPARC_GLOB_DAT:
118118 // V-xword64
119 write64be(Loc, Val);
119 write64be(loc, val);
120120 break;
121121 default:
122 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
122 llvm_unreachable("unknown relocation");
123123 }
124124}
125125
126void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
127 uint64_t PltEntryAddr, int32_t Index,
128 unsigned RelOff) const {
129 const uint8_t PltData[] = {
126void SPARCV9::writePlt(uint8_t *buf, uint64_t gotEntryAddr,
127 uint64_t pltEntryAddr, int32_t index,
128 unsigned relOff) const {
129 const uint8_t pltData[] = {
130130 0x03, 0x00, 0x00, 0x00, // sethi (. - .PLT0), %g1
131131 0x30, 0x68, 0x00, 0x00, // ba,a %xcc, .PLT1
132132 0x01, 0x00, 0x00, 0x00, // nop
......@@ -136,14 +136,14 @@ void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
136136 0x01, 0x00, 0x00, 0x00, // nop
137137 0x01, 0x00, 0x00, 0x00 // nop
138138 };
139 memcpy(Buf, PltData, sizeof(PltData));
139 memcpy(buf, pltData, sizeof(pltData));
140140
141 uint64_t Off = getPltEntryOffset(Index);
142 relocateOne(Buf, R_SPARC_22, Off);
143 relocateOne(Buf + 4, R_SPARC_WDISP19, -(Off + 4 - PltEntrySize));
141 uint64_t off = pltHeaderSize + pltEntrySize * index;
142 relocateOne(buf, R_SPARC_22, off);
143 relocateOne(buf + 4, R_SPARC_WDISP19, -(off + 4 - pltEntrySize));
144144}
145145
146146TargetInfo *elf::getSPARCV9TargetInfo() {
147 static SPARCV9 Target;
148 return &Target;
147 static SPARCV9 target;
148 return &target;
149149}
deps/lld/ELF/Arch/X86.cpp+221-221
......@@ -1,9 +1,8 @@
11//===- X86.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -24,63 +23,73 @@ namespace {
2423class X86 : public TargetInfo {
2524public:
2625 X86();
27 RelExpr getRelExpr(RelType Type, const Symbol &S,
28 const uint8_t *Loc) const override;
29 int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
30 void writeGotPltHeader(uint8_t *Buf) const override;
31 RelType getDynRel(RelType Type) const override;
32 void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
33 void writeIgotPlt(uint8_t *Buf, const Symbol &S) 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;
37 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
38
39 RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
40 RelExpr Expr) const override;
41 void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
42 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
43 void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
44 void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
26 int getTlsGdRelaxSkip(RelType type) const override;
27 RelExpr getRelExpr(RelType type, const Symbol &s,
28 const uint8_t *loc) const override;
29 int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
30 void writeGotPltHeader(uint8_t *buf) const override;
31 RelType getDynRel(RelType type) const override;
32 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
33 void writeIgotPlt(uint8_t *buf, const Symbol &s) 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;
37 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
38
39 RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
40 RelExpr expr) const override;
41 void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
42 void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
43 void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
44 void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
4545};
4646} // namespace
4747
4848X86::X86() {
49 CopyRel = R_386_COPY;
50 GotRel = R_386_GLOB_DAT;
51 NoneRel = R_386_NONE;
52 PltRel = R_386_JUMP_SLOT;
53 IRelativeRel = R_386_IRELATIVE;
54 RelativeRel = R_386_RELATIVE;
55 TlsGotRel = R_386_TLS_TPOFF;
56 TlsModuleIndexRel = R_386_TLS_DTPMOD32;
57 TlsOffsetRel = R_386_TLS_DTPOFF32;
58 GotEntrySize = 4;
59 GotPltEntrySize = 4;
60 PltEntrySize = 16;
61 PltHeaderSize = 16;
62 TlsGdRelaxSkip = 2;
63 TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
49 copyRel = R_386_COPY;
50 gotRel = R_386_GLOB_DAT;
51 noneRel = R_386_NONE;
52 pltRel = R_386_JUMP_SLOT;
53 iRelativeRel = R_386_IRELATIVE;
54 relativeRel = R_386_RELATIVE;
55 symbolicRel = R_386_32;
56 tlsGotRel = R_386_TLS_TPOFF;
57 tlsModuleIndexRel = R_386_TLS_DTPMOD32;
58 tlsOffsetRel = R_386_TLS_DTPOFF32;
59 pltEntrySize = 16;
60 pltHeaderSize = 16;
61 trapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
6462
6563 // Align to the non-PAE large page size (known as a superpage or huge page).
6664 // FreeBSD automatically promotes large, superpage-aligned allocations.
67 DefaultImageBase = 0x400000;
65 defaultImageBase = 0x400000;
6866}
6967
70static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
68int X86::getTlsGdRelaxSkip(RelType type) const {
69 return 2;
70}
7171
72RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
73 const uint8_t *Loc) const {
74 switch (Type) {
72RelExpr X86::getRelExpr(RelType type, const Symbol &s,
73 const uint8_t *loc) const {
74 // There are 4 different TLS variable models with varying degrees of
75 // flexibility and performance. LocalExec and InitialExec models are fast but
76 // less-flexible models. If they are in use, we set DF_STATIC_TLS flag in the
77 // dynamic section to let runtime know about that.
78 if (type == R_386_TLS_LE || type == R_386_TLS_LE_32 || type == R_386_TLS_IE ||
79 type == R_386_TLS_GOTIE)
80 config->hasStaticTlsModel = true;
81
82 switch (type) {
7583 case R_386_8:
7684 case R_386_16:
7785 case R_386_32:
78 case R_386_TLS_LDO_32:
7986 return R_ABS;
87 case R_386_TLS_LDO_32:
88 return R_DTPREL;
8089 case R_386_TLS_GD:
81 return R_TLSGD_GOT_FROM_END;
90 return R_TLSGD_GOTPLT;
8291 case R_386_TLS_LDM:
83 return R_TLSLD_GOT_FROM_END;
92 return R_TLSLD_GOTPLT;
8493 case R_386_PLT32:
8594 return R_PLT_PC;
8695 case R_386_PC8:
......@@ -88,7 +97,7 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
8897 case R_386_PC32:
8998 return R_PC;
9099 case R_386_GOTPC:
91 return R_GOTONLY_PC_FROM_END;
100 return R_GOTPLTONLY_PC;
92101 case R_386_TLS_IE:
93102 return R_GOT;
94103 case R_386_GOT32:
......@@ -108,14 +117,14 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
108117 // load an GOT address to a register, which is usually %ebx.
109118 //
110119 // So, there are two ways to refer to symbol foo's GOT entry: foo@GOT or
111 // foo@GOT(%reg).
120 // foo@GOT(%ebx).
112121 //
113122 // foo@GOT is not usable in PIC. If we are creating a PIC output and if we
114123 // find such relocation, we should report an error. foo@GOT is resolved to
115124 // an *absolute* address of foo's GOT entry, because both GOT address and
116125 // foo's offset are known. In other words, it's G + A.
117126 //
118 // foo@GOT(%reg) needs to be resolved to a *relative* offset from a GOT to
127 // foo@GOT(%ebx) needs to be resolved to a *relative* offset from a GOT to
119128 // foo's GOT entry in the table, because GOT address is not known but foo's
120129 // offset in the table is known. It's G + A - GOT.
121130 //
......@@ -123,16 +132,16 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
123132 // different use cases. In order to distinguish them, we have to read a
124133 // machine instruction.
125134 //
126 // The following code implements it. We assume that Loc[0] is the first
127 // byte of a displacement or an immediate field of a valid machine
135 // The following code implements it. We assume that Loc[0] is the first byte
136 // of a displacement or an immediate field of a valid machine
128137 // instruction. That means a ModRM byte is at Loc[-1]. By taking a look at
129 // the byte, we can determine whether the instruction is register-relative
130 // (i.e. it was generated for foo@GOT(%reg)) or absolute (i.e. foo@GOT).
131 return hasBaseReg(Loc[-1]) ? R_GOT_FROM_END : R_GOT;
138 // the byte, we can determine whether the instruction uses the operand as an
139 // absolute address (R_GOT) or a register-relative address (R_GOTPLT).
140 return (loc[-1] & 0xc7) == 0x5 ? R_GOT : R_GOTPLT;
132141 case R_386_TLS_GOTIE:
133 return R_GOT_FROM_END;
142 return R_GOTPLT;
134143 case R_386_GOTOFF:
135 return R_GOTREL_FROM_END;
144 return R_GOTPLTREL;
136145 case R_386_TLS_LE:
137146 return R_TLS;
138147 case R_386_TLS_LE_32:
......@@ -140,105 +149,102 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
140149 case R_386_NONE:
141150 return R_NONE;
142151 default:
143 return R_INVALID;
152 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
153 ") against symbol " + toString(s));
154 return R_NONE;
144155 }
145156}
146157
147RelExpr X86::adjustRelaxExpr(RelType Type, const uint8_t *Data,
148 RelExpr Expr) const {
149 switch (Expr) {
158RelExpr X86::adjustRelaxExpr(RelType type, const uint8_t *data,
159 RelExpr expr) const {
160 switch (expr) {
150161 default:
151 return Expr;
162 return expr;
152163 case R_RELAX_TLS_GD_TO_IE:
153 return R_RELAX_TLS_GD_TO_IE_END;
164 return R_RELAX_TLS_GD_TO_IE_GOTPLT;
154165 case R_RELAX_TLS_GD_TO_LE:
155166 return R_RELAX_TLS_GD_TO_LE_NEG;
156167 }
157168}
158169
159void X86::writeGotPltHeader(uint8_t *Buf) const {
160 write32le(Buf, In.Dynamic->getVA());
170void X86::writeGotPltHeader(uint8_t *buf) const {
171 write32le(buf, mainPart->dynamic->getVA());
161172}
162173
163void X86::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
174void X86::writeGotPlt(uint8_t *buf, const Symbol &s) const {
164175 // Entries in .got.plt initially points back to the corresponding
165176 // PLT entries with a fixed offset to skip the first instruction.
166 write32le(Buf, S.getPltVA() + 6);
177 write32le(buf, s.getPltVA() + 6);
167178}
168179
169void X86::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
180void X86::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
170181 // An x86 entry is the address of the ifunc resolver function.
171 write32le(Buf, S.getVA());
182 write32le(buf, s.getVA());
172183}
173184
174RelType X86::getDynRel(RelType Type) const {
175 if (Type == R_386_TLS_LE)
185RelType X86::getDynRel(RelType type) const {
186 if (type == R_386_TLS_LE)
176187 return R_386_TLS_TPOFF;
177 if (Type == R_386_TLS_LE_32)
188 if (type == R_386_TLS_LE_32)
178189 return R_386_TLS_TPOFF32;
179 return Type;
190 return type;
180191}
181192
182void X86::writePltHeader(uint8_t *Buf) const {
183 if (Config->Pic) {
184 const uint8_t V[] = {
185 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl GOTPLT+4(%ebx)
186 0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *GOTPLT+8(%ebx)
193void X86::writePltHeader(uint8_t *buf) const {
194 if (config->isPic) {
195 const uint8_t v[] = {
196 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx)
197 0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx)
187198 0x90, 0x90, 0x90, 0x90 // nop
188199 };
189 memcpy(Buf, V, sizeof(V));
190
191 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
192 uint32_t GotPlt = In.GotPlt->getVA() - Ebx;
193 write32le(Buf + 2, GotPlt + 4);
194 write32le(Buf + 8, GotPlt + 8);
200 memcpy(buf, v, sizeof(v));
195201 return;
196202 }
197203
198 const uint8_t PltData[] = {
204 const uint8_t pltData[] = {
199205 0xff, 0x35, 0, 0, 0, 0, // pushl (GOTPLT+4)
200206 0xff, 0x25, 0, 0, 0, 0, // jmp *(GOTPLT+8)
201207 0x90, 0x90, 0x90, 0x90, // nop
202208 };
203 memcpy(Buf, PltData, sizeof(PltData));
204 uint32_t GotPlt = In.GotPlt->getVA();
205 write32le(Buf + 2, GotPlt + 4);
206 write32le(Buf + 8, GotPlt + 8);
209 memcpy(buf, pltData, sizeof(pltData));
210 uint32_t gotPlt = in.gotPlt->getVA();
211 write32le(buf + 2, gotPlt + 4);
212 write32le(buf + 8, gotPlt + 8);
207213}
208214
209void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
210 uint64_t PltEntryAddr, int32_t Index,
211 unsigned RelOff) const {
212 const uint8_t Inst[] = {
213 0xff, 0x00, 0, 0, 0, 0, // jmp *foo_in_GOT or jmp *foo@GOT(%ebx)
214 0x68, 0, 0, 0, 0, // pushl $reloc_offset
215 0xe9, 0, 0, 0, 0, // jmp .PLT0@PC
216 };
217 memcpy(Buf, Inst, sizeof(Inst));
218
219 if (Config->Pic) {
220 // jmp *foo@GOT(%ebx)
221 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
222 Buf[1] = 0xa3;
223 write32le(Buf + 2, GotPltEntryAddr - Ebx);
215void X86::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
216 uint64_t pltEntryAddr, int32_t index,
217 unsigned relOff) const {
218 if (config->isPic) {
219 const uint8_t inst[] = {
220 0xff, 0xa3, 0, 0, 0, 0, // jmp *foo@GOT(%ebx)
221 0x68, 0, 0, 0, 0, // pushl $reloc_offset
222 0xe9, 0, 0, 0, 0, // jmp .PLT0@PC
223 };
224 memcpy(buf, inst, sizeof(inst));
225 write32le(buf + 2, gotPltEntryAddr - in.gotPlt->getVA());
224226 } else {
225 // jmp *foo_in_GOT
226 Buf[1] = 0x25;
227 write32le(Buf + 2, GotPltEntryAddr);
227 const uint8_t inst[] = {
228 0xff, 0x25, 0, 0, 0, 0, // jmp *foo@GOT
229 0x68, 0, 0, 0, 0, // pushl $reloc_offset
230 0xe9, 0, 0, 0, 0, // jmp .PLT0@PC
231 };
232 memcpy(buf, inst, sizeof(inst));
233 write32le(buf + 2, gotPltEntryAddr);
228234 }
229235
230 write32le(Buf + 7, RelOff);
231 write32le(Buf + 12, -getPltEntryOffset(Index) - 16);
236 write32le(buf + 7, relOff);
237 write32le(buf + 12, -pltHeaderSize - pltEntrySize * index - 16);
232238}
233239
234int64_t X86::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
235 switch (Type) {
240int64_t X86::getImplicitAddend(const uint8_t *buf, RelType type) const {
241 switch (type) {
236242 case R_386_8:
237243 case R_386_PC8:
238 return SignExtend64<8>(*Buf);
244 return SignExtend64<8>(*buf);
239245 case R_386_16:
240246 case R_386_PC16:
241 return SignExtend64<16>(read16le(Buf));
247 return SignExtend64<16>(read16le(buf));
242248 case R_386_32:
243249 case R_386_GOT32:
244250 case R_386_GOT32X:
......@@ -248,28 +254,28 @@ int64_t X86::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
248254 case R_386_PLT32:
249255 case R_386_TLS_LDO_32:
250256 case R_386_TLS_LE:
251 return SignExtend64<32>(read32le(Buf));
257 return SignExtend64<32>(read32le(buf));
252258 default:
253259 return 0;
254260 }
255261}
256262
257void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
258 switch (Type) {
263void X86::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
264 switch (type) {
259265 case R_386_8:
260266 // R_386_{PC,}{8,16} are not part of the i386 psABI, but they are
261267 // being used for some 16-bit programs such as boot loaders, so
262268 // we want to support them.
263 checkIntUInt(Loc, Val, 8, Type);
264 *Loc = Val;
269 checkIntUInt(loc, val, 8, type);
270 *loc = val;
265271 break;
266272 case R_386_PC8:
267 checkInt(Loc, Val, 8, Type);
268 *Loc = Val;
273 checkInt(loc, val, 8, type);
274 *loc = val;
269275 break;
270276 case R_386_16:
271 checkIntUInt(Loc, Val, 16, Type);
272 write16le(Loc, Val);
277 checkIntUInt(loc, val, 16, type);
278 write16le(loc, val);
273279 break;
274280 case R_386_PC16:
275281 // R_386_PC16 is normally used with 16 bit code. In that situation
......@@ -282,11 +288,10 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
282288 // current location subtracted from it.
283289 // We just check that Val fits in 17 bits. This misses some cases, but
284290 // should have no false positives.
285 checkInt(Loc, Val, 17, Type);
286 write16le(Loc, Val);
291 checkInt(loc, val, 17, type);
292 write16le(loc, val);
287293 break;
288294 case R_386_32:
289 case R_386_GLOB_DAT:
290295 case R_386_GOT32:
291296 case R_386_GOT32X:
292297 case R_386_GOTOFF:
......@@ -305,86 +310,86 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
305310 case R_386_TLS_LE_32:
306311 case R_386_TLS_TPOFF:
307312 case R_386_TLS_TPOFF32:
308 checkInt(Loc, Val, 32, Type);
309 write32le(Loc, Val);
313 checkInt(loc, val, 32, type);
314 write32le(loc, val);
310315 break;
311316 default:
312 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
317 llvm_unreachable("unknown relocation");
313318 }
314319}
315320
316void X86::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
321void X86::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
317322 // Convert
318323 // leal x@tlsgd(, %ebx, 1),
319324 // call __tls_get_addr@plt
320325 // to
321326 // movl %gs:0,%eax
322327 // subl $x@ntpoff,%eax
323 const uint8_t Inst[] = {
328 const uint8_t inst[] = {
324329 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax
325330 0x81, 0xe8, 0, 0, 0, 0, // subl Val(%ebx), %eax
326331 };
327 memcpy(Loc - 3, Inst, sizeof(Inst));
328 write32le(Loc + 5, Val);
332 memcpy(loc - 3, inst, sizeof(inst));
333 write32le(loc + 5, val);
329334}
330335
331void X86::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
336void X86::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
332337 // Convert
333338 // leal x@tlsgd(, %ebx, 1),
334339 // call __tls_get_addr@plt
335340 // to
336341 // movl %gs:0, %eax
337342 // addl x@gotntpoff(%ebx), %eax
338 const uint8_t Inst[] = {
343 const uint8_t inst[] = {
339344 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax
340345 0x03, 0x83, 0, 0, 0, 0, // addl Val(%ebx), %eax
341346 };
342 memcpy(Loc - 3, Inst, sizeof(Inst));
343 write32le(Loc + 5, Val);
347 memcpy(loc - 3, inst, sizeof(inst));
348 write32le(loc + 5, val);
344349}
345350
346351// In some conditions, relocations can be optimized to avoid using GOT.
347352// This function does that for Initial Exec to Local Exec case.
348void X86::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
353void X86::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
349354 // Ulrich's document section 6.2 says that @gotntpoff can
350355 // be used with MOVL or ADDL instructions.
351356 // @indntpoff is similar to @gotntpoff, but for use in
352357 // position dependent code.
353 uint8_t Reg = (Loc[-1] >> 3) & 7;
358 uint8_t reg = (loc[-1] >> 3) & 7;
354359
355 if (Type == R_386_TLS_IE) {
356 if (Loc[-1] == 0xa1) {
360 if (type == R_386_TLS_IE) {
361 if (loc[-1] == 0xa1) {
357362 // "movl foo@indntpoff,%eax" -> "movl $foo,%eax"
358363 // This case is different from the generic case below because
359364 // this is a 5 byte instruction while below is 6 bytes.
360 Loc[-1] = 0xb8;
361 } else if (Loc[-2] == 0x8b) {
365 loc[-1] = 0xb8;
366 } else if (loc[-2] == 0x8b) {
362367 // "movl foo@indntpoff,%reg" -> "movl $foo,%reg"
363 Loc[-2] = 0xc7;
364 Loc[-1] = 0xc0 | Reg;
368 loc[-2] = 0xc7;
369 loc[-1] = 0xc0 | reg;
365370 } else {
366371 // "addl foo@indntpoff,%reg" -> "addl $foo,%reg"
367 Loc[-2] = 0x81;
368 Loc[-1] = 0xc0 | Reg;
372 loc[-2] = 0x81;
373 loc[-1] = 0xc0 | reg;
369374 }
370375 } else {
371 assert(Type == R_386_TLS_GOTIE);
372 if (Loc[-2] == 0x8b) {
376 assert(type == R_386_TLS_GOTIE);
377 if (loc[-2] == 0x8b) {
373378 // "movl foo@gottpoff(%rip),%reg" -> "movl $foo,%reg"
374 Loc[-2] = 0xc7;
375 Loc[-1] = 0xc0 | Reg;
379 loc[-2] = 0xc7;
380 loc[-1] = 0xc0 | reg;
376381 } else {
377382 // "addl foo@gotntpoff(%rip),%reg" -> "leal foo(%reg),%reg"
378 Loc[-2] = 0x8d;
379 Loc[-1] = 0x80 | (Reg << 3) | Reg;
383 loc[-2] = 0x8d;
384 loc[-1] = 0x80 | (reg << 3) | reg;
380385 }
381386 }
382 write32le(Loc, Val);
387 write32le(loc, val);
383388}
384389
385void X86::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
386 if (Type == R_386_TLS_LDO_32) {
387 write32le(Loc, Val);
390void X86::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
391 if (type == R_386_TLS_LDO_32) {
392 write32le(loc, val);
388393 return;
389394 }
390395
......@@ -395,48 +400,48 @@ void X86::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
395400 // movl %gs:0,%eax
396401 // nop
397402 // leal 0(%esi,1),%esi
398 const uint8_t Inst[] = {
403 const uint8_t inst[] = {
399404 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0,%eax
400405 0x90, // nop
401406 0x8d, 0x74, 0x26, 0x00, // leal 0(%esi,1),%esi
402407 };
403 memcpy(Loc - 2, Inst, sizeof(Inst));
408 memcpy(loc - 2, inst, sizeof(inst));
404409}
405410
406411namespace {
407412class RetpolinePic : public X86 {
408413public:
409414 RetpolinePic();
410 void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
411 void writePltHeader(uint8_t *Buf) const override;
412 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
413 int32_t Index, unsigned RelOff) const override;
415 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
416 void writePltHeader(uint8_t *buf) const override;
417 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
418 int32_t index, unsigned relOff) const override;
414419};
415420
416421class RetpolineNoPic : public X86 {
417422public:
418423 RetpolineNoPic();
419 void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
420 void writePltHeader(uint8_t *Buf) const override;
421 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
422 int32_t Index, unsigned RelOff) const override;
424 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
425 void writePltHeader(uint8_t *buf) const override;
426 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
427 int32_t index, unsigned relOff) const override;
423428};
424429} // namespace
425430
426431RetpolinePic::RetpolinePic() {
427 PltHeaderSize = 48;
428 PltEntrySize = 32;
432 pltHeaderSize = 48;
433 pltEntrySize = 32;
429434}
430435
431void RetpolinePic::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
432 write32le(Buf, S.getPltVA() + 17);
436void RetpolinePic::writeGotPlt(uint8_t *buf, const Symbol &s) const {
437 write32le(buf, s.getPltVA() + 17);
433438}
434439
435void RetpolinePic::writePltHeader(uint8_t *Buf) const {
436 const uint8_t Insn[] = {
437 0xff, 0xb3, 0, 0, 0, 0, // 0: pushl GOTPLT+4(%ebx)
440void RetpolinePic::writePltHeader(uint8_t *buf) const {
441 const uint8_t insn[] = {
442 0xff, 0xb3, 4, 0, 0, 0, // 0: pushl 4(%ebx)
438443 0x50, // 6: pushl %eax
439 0x8b, 0x83, 0, 0, 0, 0, // 7: mov GOTPLT+8(%ebx), %eax
444 0x8b, 0x83, 8, 0, 0, 0, // 7: mov 8(%ebx), %eax
440445 0xe8, 0x0e, 0x00, 0x00, 0x00, // d: call next
441446 0xf3, 0x90, // 12: loop: pause
442447 0x0f, 0xae, 0xe8, // 14: lfence
......@@ -450,18 +455,13 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const {
450455 0xc3, // 2e: ret
451456 0xcc, // 2f: int3; padding
452457 };
453 memcpy(Buf, Insn, sizeof(Insn));
454
455 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
456 uint32_t GotPlt = In.GotPlt->getVA() - Ebx;
457 write32le(Buf + 2, GotPlt + 4);
458 write32le(Buf + 9, GotPlt + 8);
458 memcpy(buf, insn, sizeof(insn));
459459}
460460
461void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
462 uint64_t PltEntryAddr, int32_t Index,
463 unsigned RelOff) const {
464 const uint8_t Insn[] = {
461void RetpolinePic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
462 uint64_t pltEntryAddr, int32_t index,
463 unsigned relOff) const {
464 const uint8_t insn[] = {
465465 0x50, // pushl %eax
466466 0x8b, 0x83, 0, 0, 0, 0, // mov foo@GOT(%ebx), %eax
467467 0xe8, 0, 0, 0, 0, // call plt+0x20
......@@ -470,28 +470,28 @@ void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
470470 0xe9, 0, 0, 0, 0, // jmp plt+0
471471 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // int3; padding
472472 };
473 memcpy(Buf, Insn, sizeof(Insn));
474
475 uint32_t Ebx = In.Got->getVA() + In.Got->getSize();
476 unsigned Off = getPltEntryOffset(Index);
477 write32le(Buf + 3, GotPltEntryAddr - Ebx);
478 write32le(Buf + 8, -Off - 12 + 32);
479 write32le(Buf + 13, -Off - 17 + 18);
480 write32le(Buf + 18, RelOff);
481 write32le(Buf + 23, -Off - 27);
473 memcpy(buf, insn, sizeof(insn));
474
475 uint32_t ebx = in.gotPlt->getVA();
476 unsigned off = pltHeaderSize + pltEntrySize * index;
477 write32le(buf + 3, gotPltEntryAddr - ebx);
478 write32le(buf + 8, -off - 12 + 32);
479 write32le(buf + 13, -off - 17 + 18);
480 write32le(buf + 18, relOff);
481 write32le(buf + 23, -off - 27);
482482}
483483
484484RetpolineNoPic::RetpolineNoPic() {
485 PltHeaderSize = 48;
486 PltEntrySize = 32;
485 pltHeaderSize = 48;
486 pltEntrySize = 32;
487487}
488488
489void RetpolineNoPic::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
490 write32le(Buf, S.getPltVA() + 16);
489void RetpolineNoPic::writeGotPlt(uint8_t *buf, const Symbol &s) const {
490 write32le(buf, s.getPltVA() + 16);
491491}
492492
493void RetpolineNoPic::writePltHeader(uint8_t *Buf) const {
494 const uint8_t Insn[] = {
493void RetpolineNoPic::writePltHeader(uint8_t *buf) const {
494 const uint8_t insn[] = {
495495 0xff, 0x35, 0, 0, 0, 0, // 0: pushl GOTPLT+4
496496 0x50, // 6: pushl %eax
497497 0xa1, 0, 0, 0, 0, // 7: mov GOTPLT+8, %eax
......@@ -509,17 +509,17 @@ void RetpolineNoPic::writePltHeader(uint8_t *Buf) const {
509509 0xc3, // 2e: ret
510510 0xcc, // 2f: int3; padding
511511 };
512 memcpy(Buf, Insn, sizeof(Insn));
512 memcpy(buf, insn, sizeof(insn));
513513
514 uint32_t GotPlt = In.GotPlt->getVA();
515 write32le(Buf + 2, GotPlt + 4);
516 write32le(Buf + 8, GotPlt + 8);
514 uint32_t gotPlt = in.gotPlt->getVA();
515 write32le(buf + 2, gotPlt + 4);
516 write32le(buf + 8, gotPlt + 8);
517517}
518518
519void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
520 uint64_t PltEntryAddr, int32_t Index,
521 unsigned RelOff) const {
522 const uint8_t Insn[] = {
519void RetpolineNoPic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
520 uint64_t pltEntryAddr, int32_t index,
521 unsigned relOff) const {
522 const uint8_t insn[] = {
523523 0x50, // 0: pushl %eax
524524 0xa1, 0, 0, 0, 0, // 1: mov foo_in_GOT, %eax
525525 0xe8, 0, 0, 0, 0, // 6: call plt+0x20
......@@ -529,26 +529,26 @@ void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
529529 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1a: int3; padding
530530 0xcc, // 1f: int3; padding
531531 };
532 memcpy(Buf, Insn, sizeof(Insn));
533
534 unsigned Off = getPltEntryOffset(Index);
535 write32le(Buf + 2, GotPltEntryAddr);
536 write32le(Buf + 7, -Off - 11 + 32);
537 write32le(Buf + 12, -Off - 16 + 17);
538 write32le(Buf + 17, RelOff);
539 write32le(Buf + 22, -Off - 26);
532 memcpy(buf, insn, sizeof(insn));
533
534 unsigned off = pltHeaderSize + pltEntrySize * index;
535 write32le(buf + 2, gotPltEntryAddr);
536 write32le(buf + 7, -off - 11 + 32);
537 write32le(buf + 12, -off - 16 + 17);
538 write32le(buf + 17, relOff);
539 write32le(buf + 22, -off - 26);
540540}
541541
542542TargetInfo *elf::getX86TargetInfo() {
543 if (Config->ZRetpolineplt) {
544 if (Config->Pic) {
545 static RetpolinePic T;
546 return &T;
543 if (config->zRetpolineplt) {
544 if (config->isPic) {
545 static RetpolinePic t;
546 return &t;
547547 }
548 static RetpolineNoPic T;
549 return &T;
548 static RetpolineNoPic t;
549 return &t;
550550 }
551551
552 static X86 T;
553 return &T;
552 static X86 t;
553 return &t;
554554}
deps/lld/ELF/Arch/X86_64.cpp+323-299
......@@ -1,9 +1,8 @@
11//===- X86_64.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -23,71 +22,74 @@ using namespace lld;
2322using namespace lld::elf;
2423
2524namespace {
26template <class ELFT> class X86_64 : public TargetInfo {
25class X86_64 : public TargetInfo {
2726public:
2827 X86_64();
29 RelExpr getRelExpr(RelType Type, const Symbol &S,
30 const uint8_t *Loc) const override;
31 RelType getDynRel(RelType Type) const override;
32 void writeGotPltHeader(uint8_t *Buf) const override;
33 void writeGotPlt(uint8_t *Buf, const Symbol &S) 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;
37 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
38
39 RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
40 RelExpr Expr) const override;
41 void relaxGot(uint8_t *Loc, uint64_t Val) const override;
42 void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
43 void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
44 void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
45 void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
46 bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
47 uint8_t StOther) const override;
48
49private:
50 void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
51 uint8_t ModRm) const;
28 int getTlsGdRelaxSkip(RelType type) const override;
29 RelExpr getRelExpr(RelType type, const Symbol &s,
30 const uint8_t *loc) const override;
31 RelType getDynRel(RelType type) const override;
32 void writeGotPltHeader(uint8_t *buf) const override;
33 void writeGotPlt(uint8_t *buf, const Symbol &s) 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;
37 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
38
39 RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
40 RelExpr expr) const override;
41 void relaxGot(uint8_t *loc, RelType type, uint64_t val) const override;
42 void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
43 void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
44 void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
45 void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
46 bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
47 uint8_t stOther) const override;
5248};
5349} // namespace
5450
55template <class ELFT> X86_64<ELFT>::X86_64() {
56 CopyRel = R_X86_64_COPY;
57 GotRel = R_X86_64_GLOB_DAT;
58 NoneRel = R_X86_64_NONE;
59 PltRel = R_X86_64_JUMP_SLOT;
60 RelativeRel = R_X86_64_RELATIVE;
61 IRelativeRel = R_X86_64_IRELATIVE;
62 TlsGotRel = R_X86_64_TPOFF64;
63 TlsModuleIndexRel = R_X86_64_DTPMOD64;
64 TlsOffsetRel = R_X86_64_DTPOFF64;
65 GotEntrySize = 8;
66 GotPltEntrySize = 8;
67 PltEntrySize = 16;
68 PltHeaderSize = 16;
69 TlsGdRelaxSkip = 2;
70 TrapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
51X86_64::X86_64() {
52 copyRel = R_X86_64_COPY;
53 gotRel = R_X86_64_GLOB_DAT;
54 noneRel = R_X86_64_NONE;
55 pltRel = R_X86_64_JUMP_SLOT;
56 relativeRel = R_X86_64_RELATIVE;
57 iRelativeRel = R_X86_64_IRELATIVE;
58 symbolicRel = R_X86_64_64;
59 tlsDescRel = R_X86_64_TLSDESC;
60 tlsGotRel = R_X86_64_TPOFF64;
61 tlsModuleIndexRel = R_X86_64_DTPMOD64;
62 tlsOffsetRel = R_X86_64_DTPOFF64;
63 pltEntrySize = 16;
64 pltHeaderSize = 16;
65 trapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
7166
7267 // Align to the large page size (known as a superpage or huge page).
7368 // FreeBSD automatically promotes large, superpage-aligned allocations.
74 DefaultImageBase = 0x200000;
69 defaultImageBase = 0x200000;
7570}
7671
77template <class ELFT>
78RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
79 const uint8_t *Loc) const {
80 switch (Type) {
72int X86_64::getTlsGdRelaxSkip(RelType type) const { return 2; }
73
74RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
75 const uint8_t *loc) const {
76 if (type == R_X86_64_GOTTPOFF)
77 config->hasStaticTlsModel = true;
78
79 switch (type) {
8180 case R_X86_64_8:
8281 case R_X86_64_16:
8382 case R_X86_64_32:
8483 case R_X86_64_32S:
8584 case R_X86_64_64:
85 return R_ABS;
8686 case R_X86_64_DTPOFF32:
8787 case R_X86_64_DTPOFF64:
88 return R_ABS;
88 return R_DTPREL;
8989 case R_X86_64_TPOFF32:
9090 return R_TLS;
91 case R_X86_64_TLSDESC_CALL:
92 return R_TLSDESC_CALL;
9193 case R_X86_64_TLSLD:
9294 return R_TLSLD_PC;
9395 case R_X86_64_TLSGD:
......@@ -97,189 +99,222 @@ RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
9799 return R_SIZE;
98100 case R_X86_64_PLT32:
99101 return R_PLT_PC;
102 case R_X86_64_PC8:
103 case R_X86_64_PC16:
100104 case R_X86_64_PC32:
101105 case R_X86_64_PC64:
102106 return R_PC;
103107 case R_X86_64_GOT32:
104108 case R_X86_64_GOT64:
105 return R_GOT_FROM_END;
109 return R_GOTPLT;
110 case R_X86_64_GOTPC32_TLSDESC:
111 return R_TLSDESC_PC;
106112 case R_X86_64_GOTPCREL:
107113 case R_X86_64_GOTPCRELX:
108114 case R_X86_64_REX_GOTPCRELX:
109115 case R_X86_64_GOTTPOFF:
110116 return R_GOT_PC;
111117 case R_X86_64_GOTOFF64:
112 return R_GOTREL_FROM_END;
118 return R_GOTPLTREL;
113119 case R_X86_64_GOTPC32:
114120 case R_X86_64_GOTPC64:
115 return R_GOTONLY_PC_FROM_END;
121 return R_GOTPLTONLY_PC;
116122 case R_X86_64_NONE:
117123 return R_NONE;
118124 default:
119 return R_INVALID;
125 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
126 ") against symbol " + toString(s));
127 return R_NONE;
120128 }
121129}
122130
123template <class ELFT> void X86_64<ELFT>::writeGotPltHeader(uint8_t *Buf) const {
131void X86_64::writeGotPltHeader(uint8_t *buf) const {
124132 // The first entry holds the value of _DYNAMIC. It is not clear why that is
125133 // required, but it is documented in the psabi and the glibc dynamic linker
126134 // seems to use it (note that this is relevant for linking ld.so, not any
127135 // other program).
128 write64le(Buf, In.Dynamic->getVA());
136 write64le(buf, mainPart->dynamic->getVA());
129137}
130138
131template <class ELFT>
132void X86_64<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
139void X86_64::writeGotPlt(uint8_t *buf, const Symbol &s) const {
133140 // See comments in X86::writeGotPlt.
134 write64le(Buf, S.getPltVA() + 6);
141 write64le(buf, s.getPltVA() + 6);
135142}
136143
137template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const {
138 const uint8_t PltData[] = {
144void X86_64::writePltHeader(uint8_t *buf) const {
145 const uint8_t pltData[] = {
139146 0xff, 0x35, 0, 0, 0, 0, // pushq GOTPLT+8(%rip)
140147 0xff, 0x25, 0, 0, 0, 0, // jmp *GOTPLT+16(%rip)
141148 0x0f, 0x1f, 0x40, 0x00, // nop
142149 };
143 memcpy(Buf, PltData, sizeof(PltData));
144 uint64_t GotPlt = In.GotPlt->getVA();
145 uint64_t Plt = In.Plt->getVA();
146 write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8
147 write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16
150 memcpy(buf, pltData, sizeof(pltData));
151 uint64_t gotPlt = in.gotPlt->getVA();
152 uint64_t plt = in.plt->getVA();
153 write32le(buf + 2, gotPlt - plt + 2); // GOTPLT+8
154 write32le(buf + 8, gotPlt - plt + 4); // GOTPLT+16
148155}
149156
150template <class ELFT>
151void X86_64<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
152 uint64_t PltEntryAddr, int32_t Index,
153 unsigned RelOff) const {
154 const uint8_t Inst[] = {
157void X86_64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
158 uint64_t pltEntryAddr, int32_t index,
159 unsigned relOff) const {
160 const uint8_t inst[] = {
155161 0xff, 0x25, 0, 0, 0, 0, // jmpq *got(%rip)
156162 0x68, 0, 0, 0, 0, // pushq <relocation index>
157163 0xe9, 0, 0, 0, 0, // jmpq plt[0]
158164 };
159 memcpy(Buf, Inst, sizeof(Inst));
165 memcpy(buf, inst, sizeof(inst));
160166
161 write32le(Buf + 2, GotPltEntryAddr - PltEntryAddr - 6);
162 write32le(Buf + 7, Index);
163 write32le(Buf + 12, -getPltEntryOffset(Index) - 16);
167 write32le(buf + 2, gotPltEntryAddr - pltEntryAddr - 6);
168 write32le(buf + 7, index);
169 write32le(buf + 12, -pltHeaderSize - pltEntrySize * index - 16);
164170}
165171
166template <class ELFT> RelType X86_64<ELFT>::getDynRel(RelType Type) const {
167 if (Type == R_X86_64_64 || Type == R_X86_64_PC64 || Type == R_X86_64_SIZE32 ||
168 Type == R_X86_64_SIZE64)
169 return Type;
172RelType X86_64::getDynRel(RelType type) const {
173 if (type == R_X86_64_64 || type == R_X86_64_PC64 || type == R_X86_64_SIZE32 ||
174 type == R_X86_64_SIZE64)
175 return type;
170176 return R_X86_64_NONE;
171177}
172178
173template <class ELFT>
174void X86_64<ELFT>::relaxTlsGdToLe(uint8_t *Loc, RelType Type,
175 uint64_t Val) const {
176 // Convert
177 // .byte 0x66
178 // leaq x@tlsgd(%rip), %rdi
179 // .word 0x6666
180 // rex64
181 // call __tls_get_addr@plt
182 // to
183 // mov %fs:0x0,%rax
184 // lea x@tpoff,%rax
185 const uint8_t Inst[] = {
186 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax
187 0x48, 0x8d, 0x80, 0, 0, 0, 0, // lea x@tpoff,%rax
188 };
189 memcpy(Loc - 4, Inst, sizeof(Inst));
190
191 // The original code used a pc relative relocation and so we have to
192 // compensate for the -4 in had in the addend.
193 write32le(Loc + 8, Val + 4);
179void X86_64::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
180 if (type == R_X86_64_TLSGD) {
181 // Convert
182 // .byte 0x66
183 // leaq x@tlsgd(%rip), %rdi
184 // .word 0x6666
185 // rex64
186 // call __tls_get_addr@plt
187 // to the following two instructions.
188 const uint8_t inst[] = {
189 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00,
190 0x00, 0x00, // mov %fs:0x0,%rax
191 0x48, 0x8d, 0x80, 0, 0, 0, 0, // lea x@tpoff,%rax
192 };
193 memcpy(loc - 4, inst, sizeof(inst));
194
195 // The original code used a pc relative relocation and so we have to
196 // compensate for the -4 in had in the addend.
197 write32le(loc + 8, val + 4);
198 } else {
199 // Convert
200 // lea x@tlsgd(%rip), %rax
201 // call *(%rax)
202 // to the following two instructions.
203 assert(type == R_X86_64_GOTPC32_TLSDESC);
204 if (memcmp(loc - 3, "\x48\x8d\x05", 3)) {
205 error(getErrorLocation(loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used "
206 "in callq *x@tlsdesc(%rip), %rax");
207 return;
208 }
209 // movq $x@tpoff(%rip),%rax
210 loc[-2] = 0xc7;
211 loc[-1] = 0xc0;
212 write32le(loc, val + 4);
213 // xchg ax,ax
214 loc[4] = 0x66;
215 loc[5] = 0x90;
216 }
194217}
195218
196template <class ELFT>
197void X86_64<ELFT>::relaxTlsGdToIe(uint8_t *Loc, RelType Type,
198 uint64_t Val) const {
199 // Convert
200 // .byte 0x66
201 // leaq x@tlsgd(%rip), %rdi
202 // .word 0x6666
203 // rex64
204 // call __tls_get_addr@plt
205 // to
206 // mov %fs:0x0,%rax
207 // addq x@tpoff,%rax
208 const uint8_t Inst[] = {
209 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax
210 0x48, 0x03, 0x05, 0, 0, 0, 0, // addq x@tpoff,%rax
211 };
212 memcpy(Loc - 4, Inst, sizeof(Inst));
213
214 // Both code sequences are PC relatives, but since we are moving the constant
215 // forward by 8 bytes we have to subtract the value by 8.
216 write32le(Loc + 8, Val - 8);
219void X86_64::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
220 if (type == R_X86_64_TLSGD) {
221 // Convert
222 // .byte 0x66
223 // leaq x@tlsgd(%rip), %rdi
224 // .word 0x6666
225 // rex64
226 // call __tls_get_addr@plt
227 // to the following two instructions.
228 const uint8_t inst[] = {
229 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00,
230 0x00, 0x00, // mov %fs:0x0,%rax
231 0x48, 0x03, 0x05, 0, 0, 0, 0, // addq x@gottpoff(%rip),%rax
232 };
233 memcpy(loc - 4, inst, sizeof(inst));
234
235 // Both code sequences are PC relatives, but since we are moving the
236 // constant forward by 8 bytes we have to subtract the value by 8.
237 write32le(loc + 8, val - 8);
238 } else {
239 // Convert
240 // lea x@tlsgd(%rip), %rax
241 // call *(%rax)
242 // to the following two instructions.
243 assert(type == R_X86_64_GOTPC32_TLSDESC);
244 if (memcmp(loc - 3, "\x48\x8d\x05", 3)) {
245 error(getErrorLocation(loc - 3) + "R_X86_64_GOTPC32_TLSDESC must be used "
246 "in callq *x@tlsdesc(%rip), %rax");
247 return;
248 }
249 // movq x@gottpoff(%rip),%rax
250 loc[-2] = 0x8b;
251 write32le(loc, val);
252 // xchg ax,ax
253 loc[4] = 0x66;
254 loc[5] = 0x90;
255 }
217256}
218257
219258// In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to
220259// R_X86_64_TPOFF32 so that it does not use GOT.
221template <class ELFT>
222void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, RelType Type,
223 uint64_t Val) const {
224 uint8_t *Inst = Loc - 3;
225 uint8_t Reg = Loc[-1] >> 3;
226 uint8_t *RegSlot = Loc - 1;
260void X86_64::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
261 uint8_t *inst = loc - 3;
262 uint8_t reg = loc[-1] >> 3;
263 uint8_t *regSlot = loc - 1;
227264
228265 // Note that ADD with RSP or R12 is converted to ADD instead of LEA
229266 // because LEA with these registers needs 4 bytes to encode and thus
230267 // wouldn't fit the space.
231268
232 if (memcmp(Inst, "\x48\x03\x25", 3) == 0) {
269 if (memcmp(inst, "\x48\x03\x25", 3) == 0) {
233270 // "addq foo@gottpoff(%rip),%rsp" -> "addq $foo,%rsp"
234 memcpy(Inst, "\x48\x81\xc4", 3);
235 } else if (memcmp(Inst, "\x4c\x03\x25", 3) == 0) {
271 memcpy(inst, "\x48\x81\xc4", 3);
272 } else if (memcmp(inst, "\x4c\x03\x25", 3) == 0) {
236273 // "addq foo@gottpoff(%rip),%r12" -> "addq $foo,%r12"
237 memcpy(Inst, "\x49\x81\xc4", 3);
238 } else if (memcmp(Inst, "\x4c\x03", 2) == 0) {
274 memcpy(inst, "\x49\x81\xc4", 3);
275 } else if (memcmp(inst, "\x4c\x03", 2) == 0) {
239276 // "addq foo@gottpoff(%rip),%r[8-15]" -> "leaq foo(%r[8-15]),%r[8-15]"
240 memcpy(Inst, "\x4d\x8d", 2);
241 *RegSlot = 0x80 | (Reg << 3) | Reg;
242 } else if (memcmp(Inst, "\x48\x03", 2) == 0) {
277 memcpy(inst, "\x4d\x8d", 2);
278 *regSlot = 0x80 | (reg << 3) | reg;
279 } else if (memcmp(inst, "\x48\x03", 2) == 0) {
243280 // "addq foo@gottpoff(%rip),%reg -> "leaq foo(%reg),%reg"
244 memcpy(Inst, "\x48\x8d", 2);
245 *RegSlot = 0x80 | (Reg << 3) | Reg;
246 } else if (memcmp(Inst, "\x4c\x8b", 2) == 0) {
281 memcpy(inst, "\x48\x8d", 2);
282 *regSlot = 0x80 | (reg << 3) | reg;
283 } else if (memcmp(inst, "\x4c\x8b", 2) == 0) {
247284 // "movq foo@gottpoff(%rip),%r[8-15]" -> "movq $foo,%r[8-15]"
248 memcpy(Inst, "\x49\xc7", 2);
249 *RegSlot = 0xc0 | Reg;
250 } else if (memcmp(Inst, "\x48\x8b", 2) == 0) {
285 memcpy(inst, "\x49\xc7", 2);
286 *regSlot = 0xc0 | reg;
287 } else if (memcmp(inst, "\x48\x8b", 2) == 0) {
251288 // "movq foo@gottpoff(%rip),%reg" -> "movq $foo,%reg"
252 memcpy(Inst, "\x48\xc7", 2);
253 *RegSlot = 0xc0 | Reg;
289 memcpy(inst, "\x48\xc7", 2);
290 *regSlot = 0xc0 | reg;
254291 } else {
255 error(getErrorLocation(Loc - 3) +
292 error(getErrorLocation(loc - 3) +
256293 "R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only");
257294 }
258295
259296 // The original code used a PC relative relocation.
260297 // Need to compensate for the -4 it had in the addend.
261 write32le(Loc, Val + 4);
298 write32le(loc, val + 4);
262299}
263300
264template <class ELFT>
265void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
266 uint64_t Val) const {
267 if (Type == R_X86_64_DTPOFF64) {
268 write64le(Loc, Val);
301void X86_64::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
302 if (type == R_X86_64_DTPOFF64) {
303 write64le(loc, val);
269304 return;
270305 }
271 if (Type == R_X86_64_DTPOFF32) {
272 write32le(Loc, Val);
306 if (type == R_X86_64_DTPOFF32) {
307 write32le(loc, val);
273308 return;
274309 }
275310
276 const uint8_t Inst[] = {
311 const uint8_t inst[] = {
277312 0x66, 0x66, // .word 0x6666
278313 0x66, // .byte 0x66
279314 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax
280315 };
281316
282 if (Loc[4] == 0xe8) {
317 if (loc[4] == 0xe8) {
283318 // Convert
284319 // leaq bar@tlsld(%rip), %rdi # 48 8d 3d <Loc>
285320 // callq __tls_get_addr@PLT # e8 <disp32>
......@@ -289,11 +324,11 @@ void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
289324 // .byte 0x66
290325 // mov %fs:0,%rax
291326 // leaq bar@tpoff(%rax), %rcx
292 memcpy(Loc - 3, Inst, sizeof(Inst));
327 memcpy(loc - 3, inst, sizeof(inst));
293328 return;
294329 }
295330
296 if (Loc[4] == 0xff && Loc[5] == 0x15) {
331 if (loc[4] == 0xff && loc[5] == 0x15) {
297332 // Convert
298333 // leaq x@tlsld(%rip),%rdi # 48 8d 3d <Loc>
299334 // call *__tls_get_addr@GOTPCREL(%rip) # ff 15 <disp32>
......@@ -302,34 +337,42 @@ void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
302337 // movq %fs:0,%rax
303338 // See "Table 11.9: LD -> LE Code Transition (LP64)" in
304339 // 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));
340 loc[-3] = 0x66;
341 memcpy(loc - 2, inst, sizeof(inst));
307342 return;
308343 }
309344
310 error(getErrorLocation(Loc - 3) +
345 error(getErrorLocation(loc - 3) +
311346 "expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD");
312347}
313348
314template <class ELFT>
315void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
316 switch (Type) {
349void X86_64::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
350 switch (type) {
317351 case R_X86_64_8:
318 checkUInt(Loc, Val, 8, Type);
319 *Loc = Val;
352 checkIntUInt(loc, val, 8, type);
353 *loc = val;
354 break;
355 case R_X86_64_PC8:
356 checkInt(loc, val, 8, type);
357 *loc = val;
320358 break;
321359 case R_X86_64_16:
322 checkUInt(Loc, Val, 16, Type);
323 write16le(Loc, Val);
360 checkIntUInt(loc, val, 16, type);
361 write16le(loc, val);
362 break;
363 case R_X86_64_PC16:
364 checkInt(loc, val, 16, type);
365 write16le(loc, val);
324366 break;
325367 case R_X86_64_32:
326 checkUInt(Loc, Val, 32, Type);
327 write32le(Loc, Val);
368 checkUInt(loc, val, 32, type);
369 write32le(loc, val);
328370 break;
329371 case R_X86_64_32S:
330372 case R_X86_64_TPOFF32:
331373 case R_X86_64_GOT32:
332374 case R_X86_64_GOTPC32:
375 case R_X86_64_GOTPC32_TLSDESC:
333376 case R_X86_64_GOTPCREL:
334377 case R_X86_64_GOTPCRELX:
335378 case R_X86_64_REX_GOTPCRELX:
......@@ -340,49 +383,47 @@ void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
340383 case R_X86_64_TLSLD:
341384 case R_X86_64_DTPOFF32:
342385 case R_X86_64_SIZE32:
343 checkInt(Loc, Val, 32, Type);
344 write32le(Loc, Val);
386 checkInt(loc, val, 32, type);
387 write32le(loc, val);
345388 break;
346389 case R_X86_64_64:
347390 case R_X86_64_DTPOFF64:
348 case R_X86_64_GLOB_DAT:
349391 case R_X86_64_PC64:
350392 case R_X86_64_SIZE64:
351393 case R_X86_64_GOT64:
352394 case R_X86_64_GOTOFF64:
353395 case R_X86_64_GOTPC64:
354 write64le(Loc, Val);
396 write64le(loc, val);
355397 break;
356398 default:
357 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
399 llvm_unreachable("unknown relocation");
358400 }
359401}
360402
361template <class ELFT>
362RelExpr X86_64<ELFT>::adjustRelaxExpr(RelType Type, const uint8_t *Data,
363 RelExpr RelExpr) const {
364 if (Type != R_X86_64_GOTPCRELX && Type != R_X86_64_REX_GOTPCRELX)
365 return RelExpr;
366 const uint8_t Op = Data[-2];
367 const uint8_t ModRm = Data[-1];
403RelExpr X86_64::adjustRelaxExpr(RelType type, const uint8_t *data,
404 RelExpr relExpr) const {
405 if (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX)
406 return relExpr;
407 const uint8_t op = data[-2];
408 const uint8_t modRm = data[-1];
368409
369410 // FIXME: When PIC is disabled and foo is defined locally in the
370411 // lower 32 bit address space, memory operand in mov can be converted into
371412 // immediate operand. Otherwise, mov must be changed to lea. We support only
372413 // latter relaxation at this moment.
373 if (Op == 0x8b)
414 if (op == 0x8b)
374415 return R_RELAX_GOT_PC;
375416
376417 // Relax call and jmp.
377 if (Op == 0xff && (ModRm == 0x15 || ModRm == 0x25))
418 if (op == 0xff && (modRm == 0x15 || modRm == 0x25))
378419 return R_RELAX_GOT_PC;
379420
380421 // Relaxation of test, adc, add, and, cmp, or, sbb, sub, xor.
381422 // If PIC then no relaxation is available.
382423 // We also don't relax test/binop instructions without REX byte,
383424 // they are 32bit operations and not common to have.
384 assert(Type == R_X86_64_REX_GOTPCRELX);
385 return Config->Pic ? RelExpr : R_RELAX_GOT_PC_NOPIC;
425 assert(type == R_X86_64_REX_GOTPCRELX);
426 return config->isPic ? relExpr : R_RELAX_GOT_PC_NOPIC;
386427}
387428
388429// A subset of relaxations can only be applied for no-PIC. This method
......@@ -390,12 +431,11 @@ RelExpr X86_64<ELFT>::adjustRelaxExpr(RelType Type, const uint8_t *Data,
390431// "Intel 64 and IA-32 Architectures Software Developer's Manual V2"
391432// (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
392433// 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf)
393template <class ELFT>
394void X86_64<ELFT>::relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
395 uint8_t ModRm) const {
396 const uint8_t Rex = Loc[-3];
434static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
435 uint8_t modRm) {
436 const uint8_t rex = loc[-3];
397437 // Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg".
398 if (Op == 0x85) {
438 if (op == 0x85) {
399439 // See "TEST-Logical Compare" (4-428 Vol. 2B),
400440 // TEST r/m64, r64 uses "full" ModR / M byte (no opcode extension).
401441
......@@ -412,11 +452,11 @@ void X86_64<ELFT>::relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
412452 // 0x38 == 00 111 000 binary.
413453 // We transfer reg2 to reg1 here as operand.
414454 // See "2.1.3 ModR/M and SIB Bytes" (Vol. 2A 2-3).
415 Loc[-1] = 0xc0 | (ModRm & 0x38) >> 3; // ModR/M byte.
455 loc[-1] = 0xc0 | (modRm & 0x38) >> 3; // ModR/M byte.
416456
417457 // Change opcode from TEST r/m64, r64 to TEST r/m64, imm32
418458 // See "TEST-Logical Compare" (4-428 Vol. 2B).
419 Loc[-2] = 0xf7;
459 loc[-2] = 0xf7;
420460
421461 // Move R bit to the B bit in REX byte.
422462 // REX byte is encoded as 0100WRXB, where
......@@ -429,8 +469,8 @@ void X86_64<ELFT>::relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
429469 // REX.B This 1-bit value is an extension to the MODRM.rm field or the
430470 // SIB.base field.
431471 // See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A).
432 Loc[-3] = (Rex & ~0x4) | (Rex & 0x4) >> 2;
433 write32le(Loc, Val);
472 loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
473 write32le(loc, val);
434474 return;
435475 }
436476
......@@ -440,7 +480,7 @@ void X86_64<ELFT>::relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
440480 // Convert "binop foo@GOTPCREL(%rip), %reg" to "binop $foo, %reg".
441481 // Logic is close to one for test instruction above, but we also
442482 // write opcode extension here, see below for details.
443 Loc[-1] = 0xc0 | (ModRm & 0x38) >> 3 | (Op & 0x3c); // ModR/M byte.
483 loc[-1] = 0xc0 | (modRm & 0x38) >> 3 | (op & 0x3c); // ModR/M byte.
444484
445485 // Primary opcode is 0x81, opcode extension is one of:
446486 // 000b = ADD, 001b is OR, 010b is ADC, 011b is SBB,
......@@ -449,69 +489,67 @@ void X86_64<ELFT>::relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
449489 // See "3.2 INSTRUCTIONS (A-M)" (Vol. 2A 3-15),
450490 // "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for
451491 // descriptions about each operation.
452 Loc[-2] = 0x81;
453 Loc[-3] = (Rex & ~0x4) | (Rex & 0x4) >> 2;
454 write32le(Loc, Val);
492 loc[-2] = 0x81;
493 loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
494 write32le(loc, val);
455495}
456496
457template <class ELFT>
458void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const {
459 const uint8_t Op = Loc[-2];
460 const uint8_t ModRm = Loc[-1];
497void X86_64::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
498 const uint8_t op = loc[-2];
499 const uint8_t modRm = loc[-1];
461500
462501 // Convert "mov foo@GOTPCREL(%rip),%reg" to "lea foo(%rip),%reg".
463 if (Op == 0x8b) {
464 Loc[-2] = 0x8d;
465 write32le(Loc, Val);
502 if (op == 0x8b) {
503 loc[-2] = 0x8d;
504 write32le(loc, val);
466505 return;
467506 }
468507
469 if (Op != 0xff) {
508 if (op != 0xff) {
470509 // We are relaxing a rip relative to an absolute, so compensate
471510 // for the old -4 addend.
472 assert(!Config->Pic);
473 relaxGotNoPic(Loc, Val + 4, Op, ModRm);
511 assert(!config->isPic);
512 relaxGotNoPic(loc, val + 4, op, modRm);
474513 return;
475514 }
476515
477516 // Convert call/jmp instructions.
478 if (ModRm == 0x15) {
517 if (modRm == 0x15) {
479518 // ABI says we can convert "call *foo@GOTPCREL(%rip)" to "nop; call foo".
480519 // Instead we convert to "addr32 call foo" where addr32 is an instruction
481520 // prefix. That makes result expression to be a single instruction.
482 Loc[-2] = 0x67; // addr32 prefix
483 Loc[-1] = 0xe8; // call
484 write32le(Loc, Val);
521 loc[-2] = 0x67; // addr32 prefix
522 loc[-1] = 0xe8; // call
523 write32le(loc, val);
485524 return;
486525 }
487526
488527 // Convert "jmp *foo@GOTPCREL(%rip)" to "jmp foo; nop".
489528 // jmp doesn't return, so it is fine to use nop here, it is just a stub.
490 assert(ModRm == 0x25);
491 Loc[-2] = 0xe9; // jmp
492 Loc[3] = 0x90; // nop
493 write32le(Loc - 1, Val + 1);
529 assert(modRm == 0x25);
530 loc[-2] = 0xe9; // jmp
531 loc[3] = 0x90; // nop
532 write32le(loc - 1, val + 1);
494533}
495534
496// This anonymous namespace works around a warning bug in
497// old versions of gcc. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
498namespace {
499
500535// A split-stack prologue starts by checking the amount of stack remaining
501536// in one of two ways:
502537// A) Comparing of the stack pointer to a field in the tcb.
503538// B) Or a load of a stack pointer offset with an lea to r10 or r11.
504template <>
505bool X86_64<ELF64LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
506 uint8_t *End,
507 uint8_t StOther) const {
508 if (Loc + 8 >= End)
539bool X86_64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
540 uint8_t stOther) const {
541 if (!config->is64) {
542 error("Target doesn't support split stacks.");
543 return false;
544 }
545
546 if (loc + 8 >= end)
509547 return false;
510548
511549 // Replace "cmp %fs:0x70,%rsp" and subsequent branch
512550 // with "stc, nopl 0x0(%rax,%rax,1)"
513 if (memcmp(Loc, "\x64\x48\x3b\x24\x25", 5) == 0) {
514 memcpy(Loc, "\xf9\x0f\x1f\x84\x00\x00\x00\x00", 8);
551 if (memcmp(loc, "\x64\x48\x3b\x24\x25", 5) == 0) {
552 memcpy(loc, "\xf9\x0f\x1f\x84\x00\x00\x00\x00", 8);
515553 return true;
516554 }
517555
......@@ -519,25 +557,16 @@ bool X86_64<ELF64LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
519557 // be r10 or r11. The lea instruction feeds a subsequent compare which checks
520558 // if there is X available stack space. Making X larger effectively reserves
521559 // 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) {
560 if (memcmp(loc, "\x4c\x8d\x94\x24", 4) == 0 ||
561 memcmp(loc, "\x4c\x8d\x9c\x24", 4) == 0) {
524562 // The offset bytes are encoded four bytes after the start of the
525563 // instruction.
526 write32le(Loc + 4, read32le(Loc + 4) - 0x4000);
564 write32le(loc + 4, read32le(loc + 4) - 0x4000);
527565 return true;
528566 }
529567 return false;
530568}
531569
532template <>
533bool X86_64<ELF32LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
534 uint8_t *End,
535 uint8_t StOther) const {
536 llvm_unreachable("Target doesn't support split stacks.");
537}
538
539} // namespace
540
541570// These nonstandard PLT entries are to migtigate Spectre v2 security
542571// vulnerability. In order to mitigate Spectre v2, we want to avoid indirect
543572// branch instructions such as `jmp *GOTPLT(%rip)`. So, in the following PLT
......@@ -548,37 +577,36 @@ bool X86_64<ELF32LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc,
548577// is specified, all dynamic symbols are resolved at load-time. Thus, when
549578// that option is given, we can omit code for symbol lazy resolution.
550579namespace {
551template <class ELFT> class Retpoline : public X86_64<ELFT> {
580class Retpoline : public X86_64 {
552581public:
553582 Retpoline();
554 void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
555 void writePltHeader(uint8_t *Buf) const override;
556 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
557 int32_t Index, unsigned RelOff) const override;
583 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
584 void writePltHeader(uint8_t *buf) const override;
585 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
586 int32_t index, unsigned relOff) const override;
558587};
559588
560template <class ELFT> class RetpolineZNow : public X86_64<ELFT> {
589class RetpolineZNow : public X86_64 {
561590public:
562591 RetpolineZNow();
563 void writeGotPlt(uint8_t *Buf, const Symbol &S) const override {}
564 void writePltHeader(uint8_t *Buf) const override;
565 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
566 int32_t Index, unsigned RelOff) const override;
592 void writeGotPlt(uint8_t *buf, const Symbol &s) const override {}
593 void writePltHeader(uint8_t *buf) const override;
594 void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
595 int32_t index, unsigned relOff) const override;
567596};
568597} // namespace
569598
570template <class ELFT> Retpoline<ELFT>::Retpoline() {
571 TargetInfo::PltHeaderSize = 48;
572 TargetInfo::PltEntrySize = 32;
599Retpoline::Retpoline() {
600 pltHeaderSize = 48;
601 pltEntrySize = 32;
573602}
574603
575template <class ELFT>
576void Retpoline<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const {
577 write64le(Buf, S.getPltVA() + 17);
604void Retpoline::writeGotPlt(uint8_t *buf, const Symbol &s) const {
605 write64le(buf, s.getPltVA() + 17);
578606}
579607
580template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const {
581 const uint8_t Insn[] = {
608void Retpoline::writePltHeader(uint8_t *buf) const {
609 const uint8_t insn[] = {
582610 0xff, 0x35, 0, 0, 0, 0, // 0: pushq GOTPLT+8(%rip)
583611 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 6: mov GOTPLT+16(%rip), %r11
584612 0xe8, 0x0e, 0x00, 0x00, 0x00, // d: callq next
......@@ -591,19 +619,18 @@ template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const {
591619 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 25: int3; padding
592620 0xcc, 0xcc, 0xcc, 0xcc, // 2c: int3; padding
593621 };
594 memcpy(Buf, Insn, sizeof(Insn));
622 memcpy(buf, insn, sizeof(insn));
595623
596 uint64_t GotPlt = In.GotPlt->getVA();
597 uint64_t Plt = In.Plt->getVA();
598 write32le(Buf + 2, GotPlt - Plt - 6 + 8);
599 write32le(Buf + 9, GotPlt - Plt - 13 + 16);
624 uint64_t gotPlt = in.gotPlt->getVA();
625 uint64_t plt = in.plt->getVA();
626 write32le(buf + 2, gotPlt - plt - 6 + 8);
627 write32le(buf + 9, gotPlt - plt - 13 + 16);
600628}
601629
602template <class ELFT>
603void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
604 uint64_t PltEntryAddr, int32_t Index,
605 unsigned RelOff) const {
606 const uint8_t Insn[] = {
630void Retpoline::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
631 uint64_t pltEntryAddr, int32_t index,
632 unsigned relOff) const {
633 const uint8_t insn[] = {
607634 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0: mov foo@GOTPLT(%rip), %r11
608635 0xe8, 0, 0, 0, 0, // 7: callq plt+0x20
609636 0xe9, 0, 0, 0, 0, // c: jmp plt+0x12
......@@ -611,25 +638,24 @@ void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
611638 0xe9, 0, 0, 0, 0, // 16: jmp plt+0
612639 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1b: int3; padding
613640 };
614 memcpy(Buf, Insn, sizeof(Insn));
641 memcpy(buf, insn, sizeof(insn));
615642
616 uint64_t Off = getPltEntryOffset(Index);
643 uint64_t off = pltHeaderSize + pltEntrySize * index;
617644
618 write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
619 write32le(Buf + 8, -Off - 12 + 32);
620 write32le(Buf + 13, -Off - 17 + 18);
621 write32le(Buf + 18, Index);
622 write32le(Buf + 23, -Off - 27);
645 write32le(buf + 3, gotPltEntryAddr - pltEntryAddr - 7);
646 write32le(buf + 8, -off - 12 + 32);
647 write32le(buf + 13, -off - 17 + 18);
648 write32le(buf + 18, index);
649 write32le(buf + 23, -off - 27);
623650}
624651
625template <class ELFT> RetpolineZNow<ELFT>::RetpolineZNow() {
626 TargetInfo::PltHeaderSize = 32;
627 TargetInfo::PltEntrySize = 16;
652RetpolineZNow::RetpolineZNow() {
653 pltHeaderSize = 32;
654 pltEntrySize = 16;
628655}
629656
630template <class ELFT>
631void RetpolineZNow<ELFT>::writePltHeader(uint8_t *Buf) const {
632 const uint8_t Insn[] = {
657void RetpolineZNow::writePltHeader(uint8_t *buf) const {
658 const uint8_t insn[] = {
633659 0xe8, 0x0b, 0x00, 0x00, 0x00, // 0: call next
634660 0xf3, 0x90, // 5: loop: pause
635661 0x0f, 0xae, 0xe8, // 7: lfence
......@@ -641,37 +667,35 @@ void RetpolineZNow<ELFT>::writePltHeader(uint8_t *Buf) const {
641667 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1a: int3; padding
642668 0xcc, // 1f: int3; padding
643669 };
644 memcpy(Buf, Insn, sizeof(Insn));
670 memcpy(buf, insn, sizeof(insn));
645671}
646672
647template <class ELFT>
648void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
649 uint64_t PltEntryAddr, int32_t Index,
650 unsigned RelOff) const {
651 const uint8_t Insn[] = {
673void RetpolineZNow::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
674 uint64_t pltEntryAddr, int32_t index,
675 unsigned relOff) const {
676 const uint8_t insn[] = {
652677 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // mov foo@GOTPLT(%rip), %r11
653678 0xe9, 0, 0, 0, 0, // jmp plt+0
654679 0xcc, 0xcc, 0xcc, 0xcc, // int3; padding
655680 };
656 memcpy(Buf, Insn, sizeof(Insn));
681 memcpy(buf, insn, sizeof(insn));
657682
658 write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7);
659 write32le(Buf + 8, -getPltEntryOffset(Index) - 12);
683 write32le(buf + 3, gotPltEntryAddr - pltEntryAddr - 7);
684 write32le(buf + 8, -pltHeaderSize - pltEntrySize * index - 12);
660685}
661686
662template <class ELFT> static TargetInfo *getTargetInfo() {
663 if (Config->ZRetpolineplt) {
664 if (Config->ZNow) {
665 static RetpolineZNow<ELFT> T;
666 return &T;
687static TargetInfo *getTargetInfo() {
688 if (config->zRetpolineplt) {
689 if (config->zNow) {
690 static RetpolineZNow t;
691 return &t;
667692 }
668 static Retpoline<ELFT> T;
669 return &T;
693 static Retpoline t;
694 return &t;
670695 }
671696
672 static X86_64<ELFT> T;
673 return &T;
697 static X86_64 t;
698 return &t;
674699}
675700
676TargetInfo *elf::getX32TargetInfo() { return getTargetInfo<ELF32LE>(); }
677TargetInfo *elf::getX86_64TargetInfo() { return getTargetInfo<ELF64LE>(); }
701TargetInfo *elf::getX86_64TargetInfo() { return getTargetInfo(); }
deps/lld/ELF/Bits.h deleted-35
......@@ -1,35 +0,0 @@
1//===- Bits.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_BITS_H
11#define LLD_ELF_BITS_H
12
13#include "Config.h"
14#include "llvm/Support/Endian.h"
15
16namespace lld {
17namespace elf {
18
19inline uint64_t readUint(uint8_t *Buf) {
20 if (Config->Is64)
21 return llvm::support::endian::read64(Buf, Config->Endianness);
22 return llvm::support::endian::read32(Buf, Config->Endianness);
23}
24
25inline void writeUint(uint8_t *Buf, uint64_t Val) {
26 if (Config->Is64)
27 llvm::support::endian::write64(Buf, Val, Config->Endianness);
28 else
29 llvm::support::endian::write32(Buf, Val, Config->Endianness);
30}
31
32} // namespace elf
33} // namespace lld
34
35#endif
deps/lld/ELF/CMakeLists.txt-1
......@@ -27,7 +27,6 @@ add_lld_library(lldELF
2727 Driver.cpp
2828 DriverUtils.cpp
2929 EhFrame.cpp
30 Filesystem.cpp
3130 ICF.cpp
3231 InputFiles.cpp
3332 InputSection.cpp
deps/lld/ELF/CallGraphSort.cpp+102-83
......@@ -1,9 +1,8 @@
11//===- CallGraphSort.cpp --------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
......@@ -52,24 +51,24 @@ using namespace lld::elf;
5251
5352namespace {
5453struct Edge {
55 int From;
56 uint64_t Weight;
54 int from;
55 uint64_t weight;
5756};
5857
5958struct Cluster {
60 Cluster(int Sec, size_t S) : Sections{Sec}, Size(S) {}
59 Cluster(int sec, size_t s) : sections{sec}, size(s) {}
6160
6261 double getDensity() const {
63 if (Size == 0)
62 if (size == 0)
6463 return 0;
65 return double(Weight) / double(Size);
64 return double(weight) / double(size);
6665 }
6766
68 std::vector<int> Sections;
69 size_t Size = 0;
70 uint64_t Weight = 0;
71 uint64_t InitialWeight = 0;
72 Edge BestPred = {-1, 0};
67 std::vector<int> sections;
68 size_t size = 0;
69 uint64_t weight = 0;
70 uint64_t initialWeight = 0;
71 Edge bestPred = {-1, 0};
7372};
7473
7574class CallGraphSort {
......@@ -79,8 +78,8 @@ public:
7978 DenseMap<const InputSectionBase *, int> run();
8079
8180private:
82 std::vector<Cluster> Clusters;
83 std::vector<const InputSectionBase *> Sections;
81 std::vector<Cluster> clusters;
82 std::vector<const InputSectionBase *> sections;
8483
8584 void groupClusters();
8685};
......@@ -93,30 +92,30 @@ constexpr int MAX_DENSITY_DEGRADATION = 8;
9392constexpr uint64_t MAX_CLUSTER_SIZE = 1024 * 1024;
9493} // end anonymous namespace
9594
96typedef std::pair<const InputSectionBase *, const InputSectionBase *>
97 SectionPair;
95using SectionPair =
96 std::pair<const InputSectionBase *, const InputSectionBase *>;
9897
9998// Take the edge list in Config->CallGraphProfile, resolve symbol names to
10099// Symbols, and generate a graph between InputSections with the provided
101100// weights.
102101CallGraphSort::CallGraphSort() {
103 MapVector<SectionPair, uint64_t> &Profile = Config->CallGraphProfile;
104 DenseMap<const InputSectionBase *, int> SecToCluster;
105
106 auto GetOrCreateNode = [&](const InputSectionBase *IS) -> int {
107 auto Res = SecToCluster.insert(std::make_pair(IS, Clusters.size()));
108 if (Res.second) {
109 Sections.push_back(IS);
110 Clusters.emplace_back(Clusters.size(), IS->getSize());
102 MapVector<SectionPair, uint64_t> &profile = config->callGraphProfile;
103 DenseMap<const InputSectionBase *, int> secToCluster;
104
105 auto getOrCreateNode = [&](const InputSectionBase *isec) -> int {
106 auto res = secToCluster.insert(std::make_pair(isec, clusters.size()));
107 if (res.second) {
108 sections.push_back(isec);
109 clusters.emplace_back(clusters.size(), isec->getSize());
111110 }
112 return Res.first->second;
111 return res.first->second;
113112 };
114113
115114 // Create the graph.
116 for (std::pair<SectionPair, uint64_t> &C : Profile) {
117 const auto *FromSB = cast<InputSectionBase>(C.first.first->Repl);
118 const auto *ToSB = cast<InputSectionBase>(C.first.second->Repl);
119 uint64_t Weight = C.second;
115 for (std::pair<SectionPair, uint64_t> &c : profile) {
116 const auto *fromSB = cast<InputSectionBase>(c.first.first->repl);
117 const auto *toSB = cast<InputSectionBase>(c.first.second->repl);
118 uint64_t weight = c.second;
120119
121120 // Ignore edges between input sections belonging to different output
122121 // sections. This is done because otherwise we would end up with clusters
......@@ -124,110 +123,130 @@ CallGraphSort::CallGraphSort() {
124123 // output. This messes with the cluster size and density calculations. We
125124 // would also end up moving input sections in other output sections without
126125 // moving them closer to what calls them.
127 if (FromSB->getOutputSection() != ToSB->getOutputSection())
126 if (fromSB->getOutputSection() != toSB->getOutputSection())
128127 continue;
129128
130 int From = GetOrCreateNode(FromSB);
131 int To = GetOrCreateNode(ToSB);
129 int from = getOrCreateNode(fromSB);
130 int to = getOrCreateNode(toSB);
132131
133 Clusters[To].Weight += Weight;
132 clusters[to].weight += weight;
134133
135 if (From == To)
134 if (from == to)
136135 continue;
137136
138137 // 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;
138 Cluster &toC = clusters[to];
139 if (toC.bestPred.from == -1 || toC.bestPred.weight < weight) {
140 toC.bestPred.from = from;
141 toC.bestPred.weight = weight;
143142 }
144143 }
145 for (Cluster &C : Clusters)
146 C.InitialWeight = C.Weight;
144 for (Cluster &c : clusters)
145 c.initialWeight = c.weight;
147146}
148147
149148// It's bad to merge clusters which would degrade the density too much.
150static bool isNewDensityBad(Cluster &A, Cluster &B) {
151 double NewDensity = double(A.Weight + B.Weight) / double(A.Size + B.Size);
152 return NewDensity < A.getDensity() / MAX_DENSITY_DEGRADATION;
149static bool isNewDensityBad(Cluster &a, Cluster &b) {
150 double newDensity = double(a.weight + b.weight) / double(a.size + b.size);
151 return newDensity < a.getDensity() / MAX_DENSITY_DEGRADATION;
153152}
154153
155static void mergeClusters(Cluster &Into, Cluster &From) {
156 Into.Sections.insert(Into.Sections.end(), From.Sections.begin(),
157 From.Sections.end());
158 Into.Size += From.Size;
159 Into.Weight += From.Weight;
160 From.Sections.clear();
161 From.Size = 0;
162 From.Weight = 0;
154static void mergeClusters(Cluster &into, Cluster &from) {
155 into.sections.insert(into.sections.end(), from.sections.begin(),
156 from.sections.end());
157 into.size += from.size;
158 into.weight += from.weight;
159 from.sections.clear();
160 from.size = 0;
161 from.weight = 0;
163162}
164163
165164// Group InputSections into clusters using the Call-Chain Clustering heuristic
166165// then sort the clusters by density.
167166void CallGraphSort::groupClusters() {
168 std::vector<int> SortedSecs(Clusters.size());
169 std::vector<Cluster *> SecToCluster(Clusters.size());
167 std::vector<int> sortedSecs(clusters.size());
168 std::vector<Cluster *> secToCluster(clusters.size());
170169
171 for (size_t I = 0; I < Clusters.size(); ++I) {
172 SortedSecs[I] = I;
173 SecToCluster[I] = &Clusters[I];
170 for (size_t i = 0; i < clusters.size(); ++i) {
171 sortedSecs[i] = i;
172 secToCluster[i] = &clusters[i];
174173 }
175174
176 std::stable_sort(SortedSecs.begin(), SortedSecs.end(), [&](int A, int B) {
177 return Clusters[B].getDensity() < Clusters[A].getDensity();
175 llvm::stable_sort(sortedSecs, [&](int a, int b) {
176 return clusters[a].getDensity() > clusters[b].getDensity();
178177 });
179178
180 for (int SI : SortedSecs) {
181 // Clusters[SI] is the same as SecToClusters[SI] here because it has not
179 for (int si : sortedSecs) {
180 // clusters[si] is the same as secToClusters[si] here because it has not
182181 // been merged into another cluster yet.
183 Cluster &C = Clusters[SI];
182 Cluster &c = clusters[si];
184183
185184 // Don't consider merging if the edge is unlikely.
186 if (C.BestPred.From == -1 || C.BestPred.Weight * 10 <= C.InitialWeight)
185 if (c.bestPred.from == -1 || c.bestPred.weight * 10 <= c.initialWeight)
187186 continue;
188187
189 Cluster *PredC = SecToCluster[C.BestPred.From];
190 if (PredC == &C)
188 Cluster *predC = secToCluster[c.bestPred.from];
189 if (predC == &c)
191190 continue;
192191
193 if (C.Size + PredC->Size > MAX_CLUSTER_SIZE)
192 if (c.size + predC->size > MAX_CLUSTER_SIZE)
194193 continue;
195194
196 if (isNewDensityBad(*PredC, C))
195 if (isNewDensityBad(*predC, c))
197196 continue;
198197
199198 // NOTE: Consider using a disjoint-set to track section -> cluster mapping
200199 // if this is ever slow.
201 for (int SI : C.Sections)
202 SecToCluster[SI] = PredC;
200 for (int si : c.sections)
201 secToCluster[si] = predC;
203202
204 mergeClusters(*PredC, C);
203 mergeClusters(*predC, c);
205204 }
206205
207206 // Remove empty or dead nodes. Invalidates all cluster indices.
208 llvm::erase_if(Clusters, [](const Cluster &C) {
209 return C.Size == 0 || C.Sections.empty();
207 llvm::erase_if(clusters, [](const Cluster &c) {
208 return c.size == 0 || c.sections.empty();
210209 });
211210
212211 // Sort by density.
213 std::stable_sort(Clusters.begin(), Clusters.end(),
214 [](const Cluster &A, const Cluster &B) {
215 return A.getDensity() > B.getDensity();
216 });
212 llvm::stable_sort(clusters, [](const Cluster &a, const Cluster &b) {
213 return a.getDensity() > b.getDensity();
214 });
217215}
218216
219217DenseMap<const InputSectionBase *, int> CallGraphSort::run() {
220218 groupClusters();
221219
222220 // Generate order.
223 DenseMap<const InputSectionBase *, int> OrderMap;
224 ssize_t CurOrder = 1;
221 DenseMap<const InputSectionBase *, int> orderMap;
222 ssize_t curOrder = 1;
223
224 for (const Cluster &c : clusters)
225 for (int secIndex : c.sections)
226 orderMap[sections[secIndex]] = curOrder++;
227
228 if (!config->printSymbolOrder.empty()) {
229 std::error_code ec;
230 raw_fd_ostream os(config->printSymbolOrder, ec, sys::fs::F_None);
231 if (ec) {
232 error("cannot open " + config->printSymbolOrder + ": " + ec.message());
233 return orderMap;
234 }
225235
226 for (const Cluster &C : Clusters)
227 for (int SecIndex : C.Sections)
228 OrderMap[Sections[SecIndex]] = CurOrder++;
236 // Print the symbols ordered by C3, in the order of increasing curOrder
237 // Instead of sorting all the orderMap, just repeat the loops above.
238 for (const Cluster &c : clusters)
239 for (int secIndex : c.sections)
240 // Search all the symbols in the file of the section
241 // and find out a Defined symbol with name that is within the section.
242 for (Symbol *sym: sections[secIndex]->file->getSymbols())
243 if (!sym->isSection()) // Filter out section-type symbols here.
244 if (auto *d = dyn_cast<Defined>(sym))
245 if (sections[secIndex] == d->section)
246 os << sym->getName() << "\n";
247 }
229248
230 return OrderMap;
249 return orderMap;
231250}
232251
233252// Sort sections by the profile data provided by -callgraph-profile-file
deps/lld/ELF/CallGraphSort.h+3-4
......@@ -1,9 +1,8 @@
11//===- CallGraphSort.h ------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/ELF/Config.h+192-165
......@@ -1,9 +1,8 @@
11//===- Config.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -18,6 +17,7 @@
1817#include "llvm/Support/CachePruning.h"
1918#include "llvm/Support/CodeGen.h"
2019#include "llvm/Support/Endian.h"
20#include <atomic>
2121#include <vector>
2222
2323namespace lld {
......@@ -62,18 +62,17 @@ enum class Target2Policy { Abs, Rel, GotRel };
6262enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
6363
6464struct SymbolVersion {
65 llvm::StringRef Name;
66 bool IsExternCpp;
67 bool HasWildcard;
65 llvm::StringRef name;
66 bool isExternCpp;
67 bool hasWildcard;
6868};
6969
7070// This struct contains symbols version definition that
7171// can be found in version script if it is used for link.
7272struct VersionDefinition {
73 llvm::StringRef Name;
74 uint16_t Id = 0;
75 std::vector<SymbolVersion> Globals;
76 size_t NameOff = 0; // Offset in the string table
73 llvm::StringRef name;
74 uint16_t id = 0;
75 std::vector<SymbolVersion> globals;
7776};
7877
7978// This struct contains the global configuration for the linker.
......@@ -81,163 +80,177 @@ struct VersionDefinition {
8180// and such fields have the same name as the corresponding options.
8281// Most fields are initialized by the driver.
8382struct Configuration {
84 uint8_t OSABI = 0;
85 llvm::CachePruningPolicy ThinLTOCachePolicy;
86 llvm::StringMap<uint64_t> SectionStartMap;
87 llvm::StringRef Chroot;
88 llvm::StringRef DynamicLinker;
89 llvm::StringRef DwoDir;
90 llvm::StringRef Entry;
91 llvm::StringRef Emulation;
92 llvm::StringRef Fini;
93 llvm::StringRef Init;
94 llvm::StringRef LTOAAPipeline;
95 llvm::StringRef LTONewPmPasses;
96 llvm::StringRef LTOObjPath;
97 llvm::StringRef LTOSampleProfile;
98 llvm::StringRef MapFile;
99 llvm::StringRef OutputFile;
100 llvm::StringRef OptRemarksFilename;
101 llvm::StringRef ProgName;
102 llvm::StringRef SoName;
103 llvm::StringRef Sysroot;
104 llvm::StringRef ThinLTOCacheDir;
105 llvm::StringRef ThinLTOIndexOnlyArg;
106 std::pair<llvm::StringRef, llvm::StringRef> ThinLTOObjectSuffixReplace;
107 std::pair<llvm::StringRef, llvm::StringRef> ThinLTOPrefixReplace;
108 std::string Rpath;
109 std::vector<VersionDefinition> VersionDefinitions;
110 std::vector<llvm::StringRef> AuxiliaryList;
111 std::vector<llvm::StringRef> FilterList;
112 std::vector<llvm::StringRef> SearchPaths;
113 std::vector<llvm::StringRef> SymbolOrderingFile;
114 std::vector<llvm::StringRef> Undefined;
115 std::vector<SymbolVersion> DynamicList;
116 std::vector<SymbolVersion> VersionScriptGlobals;
117 std::vector<SymbolVersion> VersionScriptLocals;
118 std::vector<uint8_t> BuildIdVector;
83 uint8_t osabi = 0;
84 uint32_t andFeatures = 0;
85 llvm::CachePruningPolicy thinLTOCachePolicy;
86 llvm::StringMap<uint64_t> sectionStartMap;
87 llvm::StringRef chroot;
88 llvm::StringRef dynamicLinker;
89 llvm::StringRef dwoDir;
90 llvm::StringRef entry;
91 llvm::StringRef emulation;
92 llvm::StringRef fini;
93 llvm::StringRef init;
94 llvm::StringRef ltoAAPipeline;
95 llvm::StringRef ltoCSProfileFile;
96 llvm::StringRef ltoNewPmPasses;
97 llvm::StringRef ltoObjPath;
98 llvm::StringRef ltoSampleProfile;
99 llvm::StringRef mapFile;
100 llvm::StringRef outputFile;
101 llvm::StringRef optRemarksFilename;
102 llvm::StringRef optRemarksPasses;
103 llvm::StringRef optRemarksFormat;
104 llvm::StringRef progName;
105 llvm::StringRef printSymbolOrder;
106 llvm::StringRef soName;
107 llvm::StringRef sysroot;
108 llvm::StringRef thinLTOCacheDir;
109 llvm::StringRef thinLTOIndexOnlyArg;
110 std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
111 std::pair<llvm::StringRef, llvm::StringRef> thinLTOPrefixReplace;
112 std::string rpath;
113 std::vector<VersionDefinition> versionDefinitions;
114 std::vector<llvm::StringRef> auxiliaryList;
115 std::vector<llvm::StringRef> filterList;
116 std::vector<llvm::StringRef> searchPaths;
117 std::vector<llvm::StringRef> symbolOrderingFile;
118 std::vector<llvm::StringRef> undefined;
119 std::vector<SymbolVersion> dynamicList;
120 std::vector<SymbolVersion> versionScriptGlobals;
121 std::vector<SymbolVersion> versionScriptLocals;
122 std::vector<uint8_t> buildIdVector;
119123 llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,
120124 uint64_t>
121 CallGraphProfile;
122 bool AllowMultipleDefinition;
123 bool AndroidPackDynRelocs;
124 bool ARMHasBlx = false;
125 bool ARMHasMovtMovw = false;
126 bool ARMJ1J2BranchEncoding = false;
127 bool AsNeeded = false;
128 bool Bsymbolic;
129 bool BsymbolicFunctions;
130 bool CallGraphProfileSort;
131 bool CheckSections;
132 bool CompressDebugSections;
133 bool Cref;
134 bool DefineCommon;
135 bool Demangle = true;
136 bool DisableVerify;
137 bool EhFrameHdr;
138 bool EmitLLVM;
139 bool EmitRelocs;
140 bool EnableNewDtags;
141 bool ExecuteOnly;
142 bool ExportDynamic;
143 bool FixCortexA53Errata843419;
144 bool FormatBinary = false;
145 bool GcSections;
146 bool GdbIndex;
147 bool GnuHash = false;
148 bool GnuUnique;
149 bool HasDynamicList = false;
150 bool HasDynSymTab;
151 bool IgnoreDataAddressEquality;
152 bool IgnoreFunctionAddressEquality;
153 bool LTODebugPassManager;
154 bool LTONewPassManager;
155 bool MergeArmExidx;
156 bool MipsN32Abi = false;
157 bool NoinhibitExec;
158 bool Nostdlib;
159 bool OFormatBinary;
160 bool Omagic;
161 bool OptRemarksWithHotness;
162 bool PicThunk;
163 bool Pie;
164 bool PrintGcSections;
165 bool PrintIcfSections;
166 bool Relocatable;
167 bool RelrPackDynRelocs;
168 bool SaveTemps;
169 bool SingleRoRx;
170 bool Shared;
171 bool Static = false;
172 bool SysvHash = false;
173 bool Target1Rel;
174 bool Trace;
175 bool ThinLTOEmitImportsFiles;
176 bool ThinLTOIndexOnly;
177 bool TocOptimize;
178 bool UndefinedVersion;
179 bool UseAndroidRelrTags = false;
180 bool WarnBackrefs;
181 bool WarnCommon;
182 bool WarnIfuncTextrel;
183 bool WarnMissingEntry;
184 bool WarnSymbolOrdering;
185 bool WriteAddends;
186 bool ZCombreloc;
187 bool ZCopyreloc;
188 bool ZExecstack;
189 bool ZGlobal;
190 bool ZHazardplt;
191 bool ZInitfirst;
192 bool ZInterpose;
193 bool ZKeepTextSectionPrefix;
194 bool ZNodefaultlib;
195 bool ZNodelete;
196 bool ZNodlopen;
197 bool ZNow;
198 bool ZOrigin;
199 bool ZRelro;
200 bool ZRodynamic;
201 bool ZText;
202 bool ZRetpolineplt;
203 bool ZWxneeded;
204 DiscardPolicy Discard;
205 ICFLevel ICF;
206 OrphanHandlingPolicy OrphanHandling;
207 SortSectionPolicy SortSection;
208 StripPolicy Strip;
209 UnresolvedPolicy UnresolvedSymbols;
210 Target2Policy Target2;
211 ARMVFPArgKind ARMVFPArgs = ARMVFPArgKind::Default;
212 BuildIdKind BuildId = BuildIdKind::None;
213 ELFKind EKind = ELFNoneKind;
214 uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
215 uint16_t EMachine = llvm::ELF::EM_NONE;
216 llvm::Optional<uint64_t> ImageBase;
217 uint64_t MaxPageSize;
218 uint64_t MipsGotSize;
219 uint64_t ZStackSize;
220 unsigned LTOPartitions;
221 unsigned LTOO;
222 unsigned Optimize;
223 unsigned ThinLTOJobs;
224 int32_t SplitStackAdjustSize;
125 callGraphProfile;
126 bool allowMultipleDefinition;
127 bool allowShlibUndefined;
128 bool androidPackDynRelocs;
129 bool armHasBlx = false;
130 bool armHasMovtMovw = false;
131 bool armJ1J2BranchEncoding = false;
132 bool asNeeded = false;
133 bool bsymbolic;
134 bool bsymbolicFunctions;
135 bool callGraphProfileSort;
136 bool checkSections;
137 bool compressDebugSections;
138 bool cref;
139 bool defineCommon;
140 bool demangle = true;
141 bool dependentLibraries;
142 bool disableVerify;
143 bool ehFrameHdr;
144 bool emitLLVM;
145 bool emitRelocs;
146 bool enableNewDtags;
147 bool executeOnly;
148 bool exportDynamic;
149 bool fixCortexA53Errata843419;
150 bool forceBTI;
151 bool formatBinary = false;
152 bool requireCET;
153 bool gcSections;
154 bool gdbIndex;
155 bool gnuHash = false;
156 bool gnuUnique;
157 bool hasDynamicList = false;
158 bool hasDynSymTab;
159 bool ignoreDataAddressEquality;
160 bool ignoreFunctionAddressEquality;
161 bool ltoCSProfileGenerate;
162 bool ltoDebugPassManager;
163 bool ltoNewPassManager;
164 bool mergeArmExidx;
165 bool mipsN32Abi = false;
166 bool nmagic;
167 bool noinhibitExec;
168 bool nostdlib;
169 bool oFormatBinary;
170 bool omagic;
171 bool optRemarksWithHotness;
172 bool pacPlt;
173 bool picThunk;
174 bool pie;
175 bool printGcSections;
176 bool printIcfSections;
177 bool relocatable;
178 bool relrPackDynRelocs;
179 bool saveTemps;
180 bool singleRoRx;
181 bool shared;
182 bool isStatic = false;
183 bool sysvHash = false;
184 bool target1Rel;
185 bool trace;
186 bool thinLTOEmitImportsFiles;
187 bool thinLTOIndexOnly;
188 bool tocOptimize;
189 bool undefinedVersion;
190 bool useAndroidRelrTags = false;
191 bool warnBackrefs;
192 bool warnCommon;
193 bool warnIfuncTextrel;
194 bool warnMissingEntry;
195 bool warnSymbolOrdering;
196 bool writeAddends;
197 bool zCombreloc;
198 bool zCopyreloc;
199 bool zExecstack;
200 bool zGlobal;
201 bool zHazardplt;
202 bool zIfuncNoplt;
203 bool zInitfirst;
204 bool zInterpose;
205 bool zKeepTextSectionPrefix;
206 bool zNodefaultlib;
207 bool zNodelete;
208 bool zNodlopen;
209 bool zNow;
210 bool zOrigin;
211 bool zRelro;
212 bool zRodynamic;
213 bool zText;
214 bool zRetpolineplt;
215 bool zWxneeded;
216 DiscardPolicy discard;
217 ICFLevel icf;
218 OrphanHandlingPolicy orphanHandling;
219 SortSectionPolicy sortSection;
220 StripPolicy strip;
221 UnresolvedPolicy unresolvedSymbols;
222 Target2Policy target2;
223 ARMVFPArgKind armVFPArgs = ARMVFPArgKind::Default;
224 BuildIdKind buildId = BuildIdKind::None;
225 ELFKind ekind = ELFNoneKind;
226 uint16_t defaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
227 uint16_t emachine = llvm::ELF::EM_NONE;
228 llvm::Optional<uint64_t> imageBase;
229 uint64_t commonPageSize;
230 uint64_t maxPageSize;
231 uint64_t mipsGotSize;
232 uint64_t zStackSize;
233 unsigned ltoPartitions;
234 unsigned ltoo;
235 unsigned optimize;
236 unsigned thinLTOJobs;
237 int32_t splitStackAdjustSize;
225238
226239 // The following config options do not directly correspond to any
227240 // particualr command line options.
228241
229242 // True if we need to pass through relocations in input files to the
230243 // output file. Usually false because we consume relocations.
231 bool CopyRelocs;
244 bool copyRelocs;
232245
233246 // True if the target is ELF64. False if ELF32.
234 bool Is64;
247 bool is64;
235248
236249 // True if the target is little-endian. False if big-endian.
237 bool IsLE;
250 bool isLE;
238251
239 // endianness::little if IsLE is true. endianness::big otherwise.
240 llvm::support::endianness Endianness;
252 // endianness::little if isLE is true. endianness::big otherwise.
253 llvm::support::endianness endianness;
241254
242255 // True if the target is the little-endian MIPS64.
243256 //
......@@ -251,10 +264,24 @@ struct Configuration {
251264 // name whatever that means. A fun hypothesis is that "EL" is short for
252265 // little-endian written in the little-endian order, but I don't know
253266 // if that's true.)
254 bool IsMips64EL;
267 bool isMips64EL;
268
269 // True if we need to set the DF_STATIC_TLS flag to an output file,
270 // which works as a hint to the dynamic loader that the file contains
271 // code compiled with the static TLS model. The thread-local variable
272 // compiled with the static TLS model is faster but less flexible, and
273 // it may not be loaded using dlopen().
274 //
275 // We set this flag to true when we see a relocation for the static TLS
276 // model. Once this becomes true, it will never become false.
277 //
278 // Since the flag is updated by multi-threaded code, we use std::atomic.
279 // (Writing to a variable is not considered thread-safe even if the
280 // variable is boolean and we always set the same value from all threads.)
281 std::atomic<bool> hasStaticTlsModel{false};
255282
256283 // Holds set of ELF header flags for the target.
257 uint32_t EFlags = 0;
284 uint32_t eflags = 0;
258285
259286 // The ELF spec defines two types of relocation table entries, RELA and
260287 // REL. RELA is a triplet of (offset, info, addend) while REL is a
......@@ -270,23 +297,23 @@ struct Configuration {
270297 // Each ABI defines its relocation type. IsRela is true if target
271298 // uses RELA. As far as we know, all 64-bit ABIs are using RELA. A
272299 // few 32-bit ABIs are using RELA too.
273 bool IsRela;
300 bool isRela;
274301
275302 // True if we are creating position-independent code.
276 bool Pic;
303 bool isPic;
277304
278305 // 4 for ELF32, 8 for ELF64.
279 int Wordsize;
306 int wordsize;
280307};
281308
282309// The only instance of Configuration struct.
283extern Configuration *Config;
310extern Configuration *config;
284311
285static inline void errorOrWarn(const Twine &Msg) {
286 if (!Config->NoinhibitExec)
287 error(Msg);
312static inline void errorOrWarn(const Twine &msg) {
313 if (!config->noinhibitExec)
314 error(msg);
288315 else
289 warn(Msg);
316 warn(msg);
290317}
291318} // namespace elf
292319} // namespace lld
deps/lld/ELF/DWARF.cpp+76-56
......@@ -1,9 +1,8 @@
11//===- DWARF.cpp ----------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -26,81 +25,102 @@ using namespace llvm::object;
2625using namespace lld;
2726using namespace lld::elf;
2827
29template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *Obj) {
30 for (InputSectionBase *Sec : Obj->getSections()) {
31 if (!Sec)
28template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
29 for (InputSectionBase *sec : obj->getSections()) {
30 if (!sec)
3231 continue;
3332
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)
33 if (LLDDWARFSection *m =
34 StringSwitch<LLDDWARFSection *>(sec->name)
35 .Case(".debug_addr", &addrSection)
36 .Case(".debug_gnu_pubnames", &gnuPubNamesSection)
37 .Case(".debug_gnu_pubtypes", &gnuPubTypesSection)
38 .Case(".debug_info", &infoSection)
39 .Case(".debug_ranges", &rangeSection)
40 .Case(".debug_rnglists", &rngListsSection)
41 .Case(".debug_line", &lineSection)
4342 .Default(nullptr)) {
44 M->Data = toStringRef(Sec->data());
45 M->Sec = Sec;
43 m->Data = toStringRef(sec->data());
44 m->sec = sec;
4645 continue;
4746 }
4847
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());
48 if (sec->name == ".debug_abbrev")
49 abbrevSection = toStringRef(sec->data());
50 else if (sec->name == ".debug_str")
51 strSection = toStringRef(sec->data());
52 else if (sec->name == ".debug_line_str")
53 lineStringSection = toStringRef(sec->data());
5554 }
5655}
5756
57namespace {
58template <class RelTy> struct LLDRelocationResolver {
59 // In the ELF ABIs, S sepresents the value of the symbol in the relocation
60 // entry. For Rela, the addend is stored as part of the relocation entry.
61 static uint64_t resolve(object::RelocationRef ref, uint64_t s,
62 uint64_t /* A */) {
63 return s + ref.getRawDataRefImpl().p;
64 }
65};
66
67template <class ELFT> struct LLDRelocationResolver<Elf_Rel_Impl<ELFT, false>> {
68 // For Rel, the addend A is supplied by the caller.
69 static uint64_t resolve(object::RelocationRef /*Ref*/, uint64_t s,
70 uint64_t a) {
71 return s + a;
72 }
73};
74} // namespace
75
5876// Find if there is a relocation at Pos in Sec. The code is a bit
5977// more complicated than usual because we need to pass a section index
6078// to llvm since it has no idea about InputSection.
6179template <class ELFT>
6280template <class RelTy>
6381Optional<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)
82LLDDwarfObj<ELFT>::findAux(const InputSectionBase &sec, uint64_t pos,
83 ArrayRef<RelTy> rels) const {
84 auto it =
85 partition_point(rels, [=](const RelTy &a) { return a.r_offset < pos; });
86 if (it == rels.end() || it->r_offset != pos)
7087 return None;
71 const RelTy &Rel = *It;
88 const RelTy &rel = *it;
7289
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);
90 const ObjFile<ELFT> *file = sec.getFile<ELFT>();
91 uint32_t symIndex = rel.getSymbol(config->isMips64EL);
92 const typename ELFT::Sym &sym = file->template getELFSyms<ELFT>()[symIndex];
93 uint32_t secIndex = file->getSectionIndex(sym);
7794
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);
95 // An undefined symbol may be a symbol defined in a discarded section. We
96 // shall still resolve it. This is important for --gdb-index: the end address
97 // offset of an entry in .debug_ranges is relocated. If it is not resolved,
98 // its zero value will terminate the decoding of .debug_ranges prematurely.
99 Symbol &s = file->getRelocTargetSym(rel);
100 uint64_t val = 0;
101 if (auto *dr = dyn_cast<Defined>(&s)) {
102 val = dr->value;
88103
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();
104 // FIXME: We should be consistent about always adding the file
105 // offset or not.
106 if (dr->section->flags & ELF::SHF_ALLOC)
107 val += cast<InputSection>(dr->section)->getOffsetInFile();
108 }
93109
94 return RelocAddrEntry{SecIndex, Val};
110 DataRefImpl d;
111 d.p = getAddend<ELFT>(rel);
112 return RelocAddrEntry{secIndex, RelocationRef(d, nullptr),
113 val, Optional<object::RelocationRef>(),
114 0, LLDRelocationResolver<RelTy>::resolve};
95115}
96116
97117template <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>());
118Optional<RelocAddrEntry> LLDDwarfObj<ELFT>::find(const llvm::DWARFSection &s,
119 uint64_t pos) const {
120 auto &sec = static_cast<const LLDDWARFSection &>(s);
121 if (sec.sec->areRelocsRela)
122 return findAux(*sec.sec, pos, sec.sec->template relas<ELFT>());
123 return findAux(*sec.sec, pos, sec.sec->template rels<ELFT>());
104124}
105125
106126template class elf::LLDDwarfObj<ELF32LE>;
deps/lld/ELF/DWARF.h+32-33
......@@ -1,9 +1,8 @@
11//===- DWARF.h -----------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===-------------------------------------------------------------------===//
98
......@@ -21,70 +20,70 @@ namespace elf {
2120class InputSection;
2221
2322struct LLDDWARFSection final : public llvm::DWARFSection {
24 InputSectionBase *Sec = nullptr;
23 InputSectionBase *sec = nullptr;
2524};
2625
2726template <class ELFT> class LLDDwarfObj final : public llvm::DWARFObject {
2827public:
29 explicit LLDDwarfObj(ObjFile<ELFT> *Obj);
28 explicit LLDDwarfObj(ObjFile<ELFT> *obj);
3029
3130 void forEachInfoSections(
32 llvm::function_ref<void(const llvm::DWARFSection &)> F) const override {
33 F(InfoSection);
31 llvm::function_ref<void(const llvm::DWARFSection &)> f) const override {
32 f(infoSection);
3433 }
3534
3635 const llvm::DWARFSection &getRangeSection() const override {
37 return RangeSection;
36 return rangeSection;
3837 }
3938
4039 const llvm::DWARFSection &getRnglistsSection() const override {
41 return RngListsSection;
40 return rngListsSection;
4241 }
4342
4443 const llvm::DWARFSection &getLineSection() const override {
45 return LineSection;
44 return lineSection;
4645 }
4746
4847 const llvm::DWARFSection &getAddrSection() const override {
49 return AddrSection;
48 return addrSection;
5049 }
5150
5251 const llvm::DWARFSection &getGnuPubNamesSection() const override {
53 return GnuPubNamesSection;
52 return gnuPubNamesSection;
5453 }
5554
5655 const llvm::DWARFSection &getGnuPubTypesSection() const override {
57 return GnuPubTypesSection;
56 return gnuPubTypesSection;
5857 }
5958
6059 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; }
60 StringRef getAbbrevSection() const override { return abbrevSection; }
61 StringRef getStringSection() const override { return strSection; }
62 StringRef getLineStringSection() const override { return lineStringSection; }
6463
6564 bool isLittleEndian() const override {
6665 return ELFT::TargetEndianness == llvm::support::little;
6766 }
6867
69 llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec,
70 uint64_t Pos) const override;
68 llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &sec,
69 uint64_t pos) const override;
7170
7271private:
7372 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;
73 llvm::Optional<llvm::RelocAddrEntry> findAux(const InputSectionBase &sec,
74 uint64_t pos,
75 ArrayRef<RelTy> rels) const;
76
77 LLDDWARFSection gnuPubNamesSection;
78 LLDDWARFSection gnuPubTypesSection;
79 LLDDWARFSection infoSection;
80 LLDDWARFSection rangeSection;
81 LLDDWARFSection rngListsSection;
82 LLDDWARFSection lineSection;
83 LLDDWARFSection addrSection;
84 StringRef abbrevSection;
85 StringRef strSection;
86 StringRef lineStringSection;
8887};
8988
9089} // namespace elf
deps/lld/ELF/Driver.cpp+1080-818
......@@ -1,9 +1,8 @@
11//===- Driver.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -25,7 +24,6 @@
2524
2625#include "Driver.h"
2726#include "Config.h"
28#include "Filesystem.h"
2927#include "ICF.h"
3028#include "InputFiles.h"
3129#include "InputSection.h"
......@@ -41,6 +39,7 @@
4139#include "lld/Common/Args.h"
4240#include "lld/Common/Driver.h"
4341#include "lld/Common/ErrorHandler.h"
42#include "lld/Common/Filesystem.h"
4443#include "lld/Common/Memory.h"
4544#include "lld/Common/Strings.h"
4645#include "lld/Common/TargetOptionsCommandFlags.h"
......@@ -51,6 +50,7 @@
5150#include "llvm/ADT/StringSwitch.h"
5251#include "llvm/Support/CommandLine.h"
5352#include "llvm/Support/Compression.h"
53#include "llvm/Support/GlobPattern.h"
5454#include "llvm/Support/LEB128.h"
5555#include "llvm/Support/Path.h"
5656#include "llvm/Support/TarWriter.h"
......@@ -68,44 +68,49 @@ using namespace llvm::support;
6868using namespace lld;
6969using namespace lld::elf;
7070
71Configuration *elf::Config;
72LinkerDriver *elf::Driver;
71Configuration *elf::config;
72LinkerDriver *elf::driver;
7373
74static void setConfigs(opt::InputArgList &Args);
74static void setConfigs(opt::InputArgList &args);
75static void readConfigs(opt::InputArgList &args);
7576
76bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
77 raw_ostream &Error) {
78 errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
79 errorHandler().ErrorLimitExceededMsg =
77bool elf::link(ArrayRef<const char *> args, bool canExitEarly,
78 raw_ostream &error) {
79 errorHandler().logName = args::getFilenameWithoutExe(args[0]);
80 errorHandler().errorLimitExceededMsg =
8081 "too many errors emitted, stopping now (use "
8182 "-error-limit=0 to see all errors)";
82 errorHandler().ErrorOS = &Error;
83 errorHandler().ExitEarly = CanExitEarly;
84 errorHandler().ColorDiagnostics = Error.has_colors();
83 errorHandler().errorOS = &error;
84 errorHandler().exitEarly = canExitEarly;
85 errorHandler().colorDiagnostics = error.has_colors();
86
87 inputSections.clear();
88 outputSections.clear();
89 binaryFiles.clear();
90 bitcodeFiles.clear();
91 objectFiles.clear();
92 sharedFiles.clear();
93
94 config = make<Configuration>();
95 driver = make<LinkerDriver>();
96 script = make<LinkerScript>();
97 symtab = make<SymbolTable>();
8598
86 InputSections.clear();
87 OutputSections.clear();
88 BinaryFiles.clear();
89 BitcodeFiles.clear();
90 ObjectFiles.clear();
91 SharedFiles.clear();
99 tar = nullptr;
100 memset(&in, 0, sizeof(in));
92101
93 Config = make<Configuration>();
94 Driver = make<LinkerDriver>();
95 Script = make<LinkerScript>();
96 Symtab = make<SymbolTable>();
102 partitions = {Partition()};
97103
98 Tar = nullptr;
99 memset(&In, 0, sizeof(In));
104 SharedFile::vernauxNum = 0;
100105
101 Config->ProgName = Args[0];
106 config->progName = args[0];
102107
103 Driver->main(Args);
108 driver->main(args);
104109
105110 // Exit immediately if we don't need to return to the caller.
106111 // This saves time because the overhead of calling destructors
107112 // for all globally-allocated objects is not negligible.
108 if (CanExitEarly)
113 if (canExitEarly)
109114 exitLld(errorCount() ? 1 : 0);
110115
111116 freeArena();
......@@ -113,16 +118,16 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
113118}
114119
115120// Parses a linker -m option.
116static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
117 uint8_t OSABI = 0;
118 StringRef S = Emul;
119 if (S.endswith("_fbsd")) {
120 S = S.drop_back(5);
121 OSABI = ELFOSABI_FREEBSD;
121static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) {
122 uint8_t osabi = 0;
123 StringRef s = emul;
124 if (s.endswith("_fbsd")) {
125 s = s.drop_back(5);
126 osabi = ELFOSABI_FREEBSD;
122127 }
123128
124 std::pair<ELFKind, uint16_t> Ret =
125 StringSwitch<std::pair<ELFKind, uint16_t>>(S)
129 std::pair<ELFKind, uint16_t> ret =
130 StringSwitch<std::pair<ELFKind, uint16_t>>(s)
126131 .Cases("aarch64elf", "aarch64linux", "aarch64_elf64_le_vec",
127132 {ELF64LEKind, EM_AARCH64})
128133 .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM})
......@@ -141,91 +146,101 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
141146 .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU})
142147 .Default({ELFNoneKind, EM_NONE});
143148
144 if (Ret.first == ELFNoneKind)
145 error("unknown emulation: " + Emul);
146 return std::make_tuple(Ret.first, Ret.second, OSABI);
149 if (ret.first == ELFNoneKind)
150 error("unknown emulation: " + emul);
151 return std::make_tuple(ret.first, ret.second, osabi);
147152}
148153
149154// Returns slices of MB by parsing MB as an archive file.
150155// Each slice consists of a member file in the archive.
151156std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers(
152 MemoryBufferRef MB) {
153 std::unique_ptr<Archive> File =
154 CHECK(Archive::create(MB),
155 MB.getBufferIdentifier() + ": failed to parse archive");
156
157 std::vector<std::pair<MemoryBufferRef, uint64_t>> V;
158 Error Err = Error::success();
159 bool AddToTar = File->isThin() && Tar;
160 for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
161 Archive::Child C =
162 CHECK(COrErr, MB.getBufferIdentifier() +
157 MemoryBufferRef mb) {
158 std::unique_ptr<Archive> file =
159 CHECK(Archive::create(mb),
160 mb.getBufferIdentifier() + ": failed to parse archive");
161
162 std::vector<std::pair<MemoryBufferRef, uint64_t>> v;
163 Error err = Error::success();
164 bool addToTar = file->isThin() && tar;
165 for (const ErrorOr<Archive::Child> &cOrErr : file->children(err)) {
166 Archive::Child c =
167 CHECK(cOrErr, mb.getBufferIdentifier() +
163168 ": could not get the child of the archive");
164 MemoryBufferRef MBRef =
165 CHECK(C.getMemoryBufferRef(),
166 MB.getBufferIdentifier() +
169 MemoryBufferRef mbref =
170 CHECK(c.getMemoryBufferRef(),
171 mb.getBufferIdentifier() +
167172 ": could not get the buffer for a child of the archive");
168 if (AddToTar)
169 Tar->append(relativeToRoot(check(C.getFullName())), MBRef.getBuffer());
170 V.push_back(std::make_pair(MBRef, C.getChildOffset()));
173 if (addToTar)
174 tar->append(relativeToRoot(check(c.getFullName())), mbref.getBuffer());
175 v.push_back(std::make_pair(mbref, c.getChildOffset()));
171176 }
172 if (Err)
173 fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +
174 toString(std::move(Err)));
177 if (err)
178 fatal(mb.getBufferIdentifier() + ": Archive::children failed: " +
179 toString(std::move(err)));
175180
176181 // Take ownership of memory buffers created for members of thin archives.
177 for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
178 make<std::unique_ptr<MemoryBuffer>>(std::move(MB));
182 for (std::unique_ptr<MemoryBuffer> &mb : file->takeThinBuffers())
183 make<std::unique_ptr<MemoryBuffer>>(std::move(mb));
179184
180 return V;
185 return v;
181186}
182187
183188// Opens a file and create a file object. Path has to be resolved already.
184void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
189void LinkerDriver::addFile(StringRef path, bool withLOption) {
185190 using namespace sys::fs;
186191
187 Optional<MemoryBufferRef> Buffer = readFile(Path);
188 if (!Buffer.hasValue())
192 Optional<MemoryBufferRef> buffer = readFile(path);
193 if (!buffer.hasValue())
189194 return;
190 MemoryBufferRef MBRef = *Buffer;
195 MemoryBufferRef mbref = *buffer;
191196
192 if (Config->FormatBinary) {
193 Files.push_back(make<BinaryFile>(MBRef));
197 if (config->formatBinary) {
198 files.push_back(make<BinaryFile>(mbref));
194199 return;
195200 }
196201
197 switch (identify_magic(MBRef.getBuffer())) {
202 switch (identify_magic(mbref.getBuffer())) {
198203 case file_magic::unknown:
199 readLinkerScript(MBRef);
204 readLinkerScript(mbref);
200205 return;
201206 case file_magic::archive: {
202207 // Handle -whole-archive.
203 if (InWholeArchive) {
204 for (const auto &P : getArchiveMembers(MBRef))
205 Files.push_back(createObjectFile(P.first, Path, P.second));
208 if (inWholeArchive) {
209 for (const auto &p : getArchiveMembers(mbref))
210 files.push_back(createObjectFile(p.first, path, p.second));
206211 return;
207212 }
208213
209 std::unique_ptr<Archive> File =
210 CHECK(Archive::create(MBRef), Path + ": failed to parse archive");
214 std::unique_ptr<Archive> file =
215 CHECK(Archive::create(mbref), path + ": failed to parse archive");
211216
212217 // If an archive file has no symbol table, it is likely that a user
213218 // is attempting LTO and using a default ar command that doesn't
214219 // understand the LLVM bitcode file. It is a pretty common error, so
215220 // we'll handle it as if it had a symbol table.
216 if (!File->isEmpty() && !File->hasSymbolTable()) {
217 for (const auto &P : getArchiveMembers(MBRef))
218 Files.push_back(make<LazyObjFile>(P.first, Path, P.second));
221 if (!file->isEmpty() && !file->hasSymbolTable()) {
222 // Check if all members are bitcode files. If not, ignore, which is the
223 // default action without the LTO hack described above.
224 for (const std::pair<MemoryBufferRef, uint64_t> &p :
225 getArchiveMembers(mbref))
226 if (identify_magic(p.first.getBuffer()) != file_magic::bitcode) {
227 error(path + ": archive has no index; run ranlib to add one");
228 return;
229 }
230
231 for (const std::pair<MemoryBufferRef, uint64_t> &p :
232 getArchiveMembers(mbref))
233 files.push_back(make<LazyObjFile>(p.first, path, p.second));
219234 return;
220235 }
221236
222237 // Handle the regular case.
223 Files.push_back(make<ArchiveFile>(std::move(File)));
238 files.push_back(make<ArchiveFile>(std::move(file)));
224239 return;
225240 }
226241 case file_magic::elf_shared_object:
227 if (Config->Static || Config->Relocatable) {
228 error("attempted static link of dynamic object " + Path);
242 if (config->isStatic || config->relocatable) {
243 error("attempted static link of dynamic object " + path);
229244 return;
230245 }
231246
......@@ -239,27 +254,27 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
239254 // If a file was specified by -lfoo, the directory part is not
240255 // significant, as a user did not specify it. This behavior is
241256 // compatible with GNU.
242 Files.push_back(
243 createSharedFile(MBRef, WithLOption ? path::filename(Path) : Path));
257 files.push_back(
258 make<SharedFile>(mbref, withLOption ? path::filename(path) : path));
244259 return;
245260 case file_magic::bitcode:
246261 case file_magic::elf_relocatable:
247 if (InLib)
248 Files.push_back(make<LazyObjFile>(MBRef, "", 0));
262 if (inLib)
263 files.push_back(make<LazyObjFile>(mbref, "", 0));
249264 else
250 Files.push_back(createObjectFile(MBRef));
265 files.push_back(createObjectFile(mbref));
251266 break;
252267 default:
253 error(Path + ": unknown file type");
268 error(path + ": unknown file type");
254269 }
255270}
256271
257272// Add a given library by searching it from input search paths.
258void LinkerDriver::addLibrary(StringRef Name) {
259 if (Optional<std::string> Path = searchLibrary(Name))
260 addFile(*Path, /*WithLOption=*/true);
273void LinkerDriver::addLibrary(StringRef name) {
274 if (Optional<std::string> path = searchLibrary(name))
275 addFile(*path, /*withLOption=*/true);
261276 else
262 error("unable to find library -l" + Name);
277 error("unable to find library -l" + name);
263278}
264279
265280// This function is called on startup. We need this for LTO since
......@@ -278,102 +293,117 @@ static void initLLVM() {
278293static void checkOptions() {
279294 // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
280295 // table which is a relatively new feature.
281 if (Config->EMachine == EM_MIPS && Config->GnuHash)
296 if (config->emachine == EM_MIPS && config->gnuHash)
282297 error("the .gnu.hash section is not compatible with the MIPS target");
283298
284 if (Config->FixCortexA53Errata843419 && Config->EMachine != EM_AARCH64)
299 if (config->fixCortexA53Errata843419 && config->emachine != EM_AARCH64)
285300 error("--fix-cortex-a53-843419 is only supported on AArch64 targets");
286301
287 if (Config->TocOptimize && Config->EMachine != EM_PPC64)
302 if (config->tocOptimize && config->emachine != EM_PPC64)
288303 error("--toc-optimize is only supported on the PowerPC64 target");
289304
290 if (Config->Pie && Config->Shared)
305 if (config->pie && config->shared)
291306 error("-shared and -pie may not be used together");
292307
293 if (!Config->Shared && !Config->FilterList.empty())
308 if (!config->shared && !config->filterList.empty())
294309 error("-F may not be used without -shared");
295310
296 if (!Config->Shared && !Config->AuxiliaryList.empty())
311 if (!config->shared && !config->auxiliaryList.empty())
297312 error("-f may not be used without -shared");
298313
299 if (!Config->Relocatable && !Config->DefineCommon)
314 if (!config->relocatable && !config->defineCommon)
300315 error("-no-define-common not supported in non relocatable output");
301316
302 if (Config->Relocatable) {
303 if (Config->Shared)
317 if (config->zText && config->zIfuncNoplt)
318 error("-z text and -z ifunc-noplt may not be used together");
319
320 if (config->relocatable) {
321 if (config->shared)
304322 error("-r and -shared may not be used together");
305 if (Config->GcSections)
323 if (config->gcSections)
306324 error("-r and --gc-sections may not be used together");
307 if (Config->GdbIndex)
325 if (config->gdbIndex)
308326 error("-r and --gdb-index may not be used together");
309 if (Config->ICF != ICFLevel::None)
327 if (config->icf != ICFLevel::None)
310328 error("-r and --icf may not be used together");
311 if (Config->Pie)
329 if (config->pie)
312330 error("-r and -pie may not be used together");
313331 }
314332
315 if (Config->ExecuteOnly) {
316 if (Config->EMachine != EM_AARCH64)
333 if (config->executeOnly) {
334 if (config->emachine != EM_AARCH64)
317335 error("-execute-only is only supported on AArch64 targets");
318336
319 if (Config->SingleRoRx && !Script->HasSectionsCommand)
337 if (config->singleRoRx && !script->hasSectionsCommand)
320338 error("-execute-only and -no-rosegment cannot be used together");
321339 }
340
341 if (config->zRetpolineplt && config->requireCET)
342 error("--require-cet may not be used with -z retpolineplt");
343
344 if (config->emachine != EM_AARCH64) {
345 if (config->pacPlt)
346 error("--pac-plt only supported on AArch64");
347 if (config->forceBTI)
348 error("--force-bti only supported on AArch64");
349 }
322350}
323351
324static const char *getReproduceOption(opt::InputArgList &Args) {
325 if (auto *Arg = Args.getLastArg(OPT_reproduce))
326 return Arg->getValue();
352static const char *getReproduceOption(opt::InputArgList &args) {
353 if (auto *arg = args.getLastArg(OPT_reproduce))
354 return arg->getValue();
327355 return getenv("LLD_REPRODUCE");
328356}
329357
330static bool hasZOption(opt::InputArgList &Args, StringRef Key) {
331 for (auto *Arg : Args.filtered(OPT_z))
332 if (Key == Arg->getValue())
358static bool hasZOption(opt::InputArgList &args, StringRef key) {
359 for (auto *arg : args.filtered(OPT_z))
360 if (key == arg->getValue())
333361 return true;
334362 return false;
335363}
336364
337static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2,
365static bool getZFlag(opt::InputArgList &args, StringRef k1, StringRef k2,
338366 bool Default) {
339 for (auto *Arg : Args.filtered_reverse(OPT_z)) {
340 if (K1 == Arg->getValue())
367 for (auto *arg : args.filtered_reverse(OPT_z)) {
368 if (k1 == arg->getValue())
341369 return true;
342 if (K2 == Arg->getValue())
370 if (k2 == arg->getValue())
343371 return false;
344372 }
345373 return Default;
346374}
347375
348static bool isKnownZFlag(StringRef S) {
349 return S == "combreloc" || S == "copyreloc" || S == "defs" ||
350 S == "execstack" || S == "global" || S == "hazardplt" ||
351 S == "initfirst" || S == "interpose" ||
352 S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||
353 S == "nocombreloc" || S == "nocopyreloc" || S == "nodefaultlib" ||
354 S == "nodelete" || S == "nodlopen" || S == "noexecstack" ||
355 S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||
356 S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||
357 S == "rodynamic" || S == "text" || S == "wxneeded" ||
358 S.startswith("max-page-size=") || S.startswith("stack-size=");
376static bool isKnownZFlag(StringRef s) {
377 return s == "combreloc" || s == "copyreloc" || s == "defs" ||
378 s == "execstack" || s == "global" || s == "hazardplt" ||
379 s == "ifunc-noplt" || s == "initfirst" || s == "interpose" ||
380 s == "keep-text-section-prefix" || s == "lazy" || s == "muldefs" ||
381 s == "nocombreloc" || s == "nocopyreloc" || s == "nodefaultlib" ||
382 s == "nodelete" || s == "nodlopen" || s == "noexecstack" ||
383 s == "nokeep-text-section-prefix" || s == "norelro" || s == "notext" ||
384 s == "now" || s == "origin" || s == "relro" || s == "retpolineplt" ||
385 s == "rodynamic" || s == "text" || s == "wxneeded" ||
386 s.startswith("common-page-size") || s.startswith("max-page-size=") ||
387 s.startswith("stack-size=");
359388}
360389
361390// Report an error for an unknown -z option.
362static void checkZOptions(opt::InputArgList &Args) {
363 for (auto *Arg : Args.filtered(OPT_z))
364 if (!isKnownZFlag(Arg->getValue()))
365 error("unknown -z value: " + StringRef(Arg->getValue()));
391static void checkZOptions(opt::InputArgList &args) {
392 for (auto *arg : args.filtered(OPT_z))
393 if (!isKnownZFlag(arg->getValue()))
394 error("unknown -z value: " + StringRef(arg->getValue()));
366395}
367396
368void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
369 ELFOptTable Parser;
370 opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
397void LinkerDriver::main(ArrayRef<const char *> argsArr) {
398 ELFOptTable parser;
399 opt::InputArgList args = parser.parse(argsArr.slice(1));
371400
372401 // Interpret this flag early because error() depends on them.
373 errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
402 errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20);
403 checkZOptions(args);
374404
375405 // Handle -help
376 if (Args.hasArg(OPT_help)) {
406 if (args.hasArg(OPT_help)) {
377407 printHelp();
378408 return;
379409 }
......@@ -393,213 +423,218 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
393423 // lot of "configure" scripts out there that are generated by old version
394424 // of Libtool. We cannot convince every software developer to migrate to
395425 // the latest version and re-generate scripts. So we have this hack.
396 if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version))
426 if (args.hasArg(OPT_v) || args.hasArg(OPT_version))
397427 message(getLLDVersion() + " (compatible with GNU linkers)");
398428
399 if (const char *Path = getReproduceOption(Args)) {
429 if (const char *path = getReproduceOption(args)) {
400430 // Note that --reproduce is a debug option so you can ignore it
401431 // if you are trying to understand the whole picture of the code.
402 Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
403 TarWriter::create(Path, path::stem(Path));
404 if (ErrOrWriter) {
405 Tar = std::move(*ErrOrWriter);
406 Tar->append("response.txt", createResponseFile(Args));
407 Tar->append("version.txt", getLLDVersion() + "\n");
432 Expected<std::unique_ptr<TarWriter>> errOrWriter =
433 TarWriter::create(path, path::stem(path));
434 if (errOrWriter) {
435 tar = std::move(*errOrWriter);
436 tar->append("response.txt", createResponseFile(args));
437 tar->append("version.txt", getLLDVersion() + "\n");
408438 } else {
409 error("--reproduce: " + toString(ErrOrWriter.takeError()));
439 error("--reproduce: " + toString(errOrWriter.takeError()));
410440 }
411441 }
412442
413 readConfigs(Args);
414 checkZOptions(Args);
443 readConfigs(args);
415444
416445 // The behavior of -v or --version is a bit strange, but this is
417446 // needed for compatibility with GNU linkers.
418 if (Args.hasArg(OPT_v) && !Args.hasArg(OPT_INPUT))
447 if (args.hasArg(OPT_v) && !args.hasArg(OPT_INPUT))
419448 return;
420 if (Args.hasArg(OPT_version))
449 if (args.hasArg(OPT_version))
421450 return;
422451
423452 initLLVM();
424 createFiles(Args);
453 createFiles(args);
425454 if (errorCount())
426455 return;
427456
428457 inferMachineType();
429 setConfigs(Args);
458 setConfigs(args);
430459 checkOptions();
431460 if (errorCount())
432461 return;
433462
434 switch (Config->EKind) {
463 // The Target instance handles target-specific stuff, such as applying
464 // relocations or writing a PLT section. It also contains target-dependent
465 // values such as a default image base address.
466 target = getTarget();
467
468 switch (config->ekind) {
435469 case ELF32LEKind:
436 link<ELF32LE>(Args);
470 link<ELF32LE>(args);
437471 return;
438472 case ELF32BEKind:
439 link<ELF32BE>(Args);
473 link<ELF32BE>(args);
440474 return;
441475 case ELF64LEKind:
442 link<ELF64LE>(Args);
476 link<ELF64LE>(args);
443477 return;
444478 case ELF64BEKind:
445 link<ELF64BE>(Args);
479 link<ELF64BE>(args);
446480 return;
447481 default:
448482 llvm_unreachable("unknown Config->EKind");
449483 }
450484}
451485
452static std::string getRpath(opt::InputArgList &Args) {
453 std::vector<StringRef> V = args::getStrings(Args, OPT_rpath);
454 return llvm::join(V.begin(), V.end(), ":");
486static std::string getRpath(opt::InputArgList &args) {
487 std::vector<StringRef> v = args::getStrings(args, OPT_rpath);
488 return llvm::join(v.begin(), v.end(), ":");
455489}
456490
457491// Determines what we should do if there are remaining unresolved
458492// symbols after the name resolution.
459static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {
460 UnresolvedPolicy ErrorOrWarn = Args.hasFlag(OPT_error_unresolved_symbols,
493static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &args) {
494 UnresolvedPolicy errorOrWarn = args.hasFlag(OPT_error_unresolved_symbols,
461495 OPT_warn_unresolved_symbols, true)
462496 ? UnresolvedPolicy::ReportError
463497 : UnresolvedPolicy::Warn;
464498
465499 // Process the last of -unresolved-symbols, -no-undefined or -z defs.
466 for (auto *Arg : llvm::reverse(Args)) {
467 switch (Arg->getOption().getID()) {
500 for (auto *arg : llvm::reverse(args)) {
501 switch (arg->getOption().getID()) {
468502 case OPT_unresolved_symbols: {
469 StringRef S = Arg->getValue();
470 if (S == "ignore-all" || S == "ignore-in-object-files")
503 StringRef s = arg->getValue();
504 if (s == "ignore-all" || s == "ignore-in-object-files")
471505 return UnresolvedPolicy::Ignore;
472 if (S == "ignore-in-shared-libs" || S == "report-all")
473 return ErrorOrWarn;
474 error("unknown --unresolved-symbols value: " + S);
506 if (s == "ignore-in-shared-libs" || s == "report-all")
507 return errorOrWarn;
508 error("unknown --unresolved-symbols value: " + s);
475509 continue;
476510 }
477511 case OPT_no_undefined:
478 return ErrorOrWarn;
512 return errorOrWarn;
479513 case OPT_z:
480 if (StringRef(Arg->getValue()) == "defs")
481 return ErrorOrWarn;
514 if (StringRef(arg->getValue()) == "defs")
515 return errorOrWarn;
482516 continue;
483517 }
484518 }
485519
486520 // -shared implies -unresolved-symbols=ignore-all because missing
487521 // symbols are likely to be resolved at runtime using other DSOs.
488 if (Config->Shared)
522 if (config->shared)
489523 return UnresolvedPolicy::Ignore;
490 return ErrorOrWarn;
524 return errorOrWarn;
491525}
492526
493static Target2Policy getTarget2(opt::InputArgList &Args) {
494 StringRef S = Args.getLastArgValue(OPT_target2, "got-rel");
495 if (S == "rel")
527static Target2Policy getTarget2(opt::InputArgList &args) {
528 StringRef s = args.getLastArgValue(OPT_target2, "got-rel");
529 if (s == "rel")
496530 return Target2Policy::Rel;
497 if (S == "abs")
531 if (s == "abs")
498532 return Target2Policy::Abs;
499 if (S == "got-rel")
533 if (s == "got-rel")
500534 return Target2Policy::GotRel;
501 error("unknown --target2 option: " + S);
535 error("unknown --target2 option: " + s);
502536 return Target2Policy::GotRel;
503537}
504538
505static bool isOutputFormatBinary(opt::InputArgList &Args) {
506 StringRef S = Args.getLastArgValue(OPT_oformat, "elf");
507 if (S == "binary")
539static bool isOutputFormatBinary(opt::InputArgList &args) {
540 StringRef s = args.getLastArgValue(OPT_oformat, "elf");
541 if (s == "binary")
508542 return true;
509 if (!S.startswith("elf"))
510 error("unknown --oformat value: " + S);
543 if (!s.startswith("elf"))
544 error("unknown --oformat value: " + s);
511545 return false;
512546}
513547
514static DiscardPolicy getDiscard(opt::InputArgList &Args) {
515 if (Args.hasArg(OPT_relocatable))
548static DiscardPolicy getDiscard(opt::InputArgList &args) {
549 if (args.hasArg(OPT_relocatable))
516550 return DiscardPolicy::None;
517551
518 auto *Arg =
519 Args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none);
520 if (!Arg)
552 auto *arg =
553 args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none);
554 if (!arg)
521555 return DiscardPolicy::Default;
522 if (Arg->getOption().getID() == OPT_discard_all)
556 if (arg->getOption().getID() == OPT_discard_all)
523557 return DiscardPolicy::All;
524 if (Arg->getOption().getID() == OPT_discard_locals)
558 if (arg->getOption().getID() == OPT_discard_locals)
525559 return DiscardPolicy::Locals;
526560 return DiscardPolicy::None;
527561}
528562
529static StringRef getDynamicLinker(opt::InputArgList &Args) {
530 auto *Arg = Args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker);
531 if (!Arg || Arg->getOption().getID() == OPT_no_dynamic_linker)
563static StringRef getDynamicLinker(opt::InputArgList &args) {
564 auto *arg = args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker);
565 if (!arg || arg->getOption().getID() == OPT_no_dynamic_linker)
532566 return "";
533 return Arg->getValue();
567 return arg->getValue();
534568}
535569
536static ICFLevel getICF(opt::InputArgList &Args) {
537 auto *Arg = Args.getLastArg(OPT_icf_none, OPT_icf_safe, OPT_icf_all);
538 if (!Arg || Arg->getOption().getID() == OPT_icf_none)
570static ICFLevel getICF(opt::InputArgList &args) {
571 auto *arg = args.getLastArg(OPT_icf_none, OPT_icf_safe, OPT_icf_all);
572 if (!arg || arg->getOption().getID() == OPT_icf_none)
539573 return ICFLevel::None;
540 if (Arg->getOption().getID() == OPT_icf_safe)
574 if (arg->getOption().getID() == OPT_icf_safe)
541575 return ICFLevel::Safe;
542576 return ICFLevel::All;
543577}
544578
545static StripPolicy getStrip(opt::InputArgList &Args) {
546 if (Args.hasArg(OPT_relocatable))
579static StripPolicy getStrip(opt::InputArgList &args) {
580 if (args.hasArg(OPT_relocatable))
547581 return StripPolicy::None;
548582
549 auto *Arg = Args.getLastArg(OPT_strip_all, OPT_strip_debug);
550 if (!Arg)
583 auto *arg = args.getLastArg(OPT_strip_all, OPT_strip_debug);
584 if (!arg)
551585 return StripPolicy::None;
552 if (Arg->getOption().getID() == OPT_strip_all)
586 if (arg->getOption().getID() == OPT_strip_all)
553587 return StripPolicy::All;
554588 return StripPolicy::Debug;
555589}
556590
557static uint64_t parseSectionAddress(StringRef S, const opt::Arg &Arg) {
558 uint64_t VA = 0;
559 if (S.startswith("0x"))
560 S = S.drop_front(2);
561 if (!to_integer(S, VA, 16))
562 error("invalid argument: " + toString(Arg));
563 return VA;
591static uint64_t parseSectionAddress(StringRef s, opt::InputArgList &args,
592 const opt::Arg &arg) {
593 uint64_t va = 0;
594 if (s.startswith("0x"))
595 s = s.drop_front(2);
596 if (!to_integer(s, va, 16))
597 error("invalid argument: " + arg.getAsString(args));
598 return va;
564599}
565600
566static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &Args) {
567 StringMap<uint64_t> Ret;
568 for (auto *Arg : Args.filtered(OPT_section_start)) {
569 StringRef Name;
570 StringRef Addr;
571 std::tie(Name, Addr) = StringRef(Arg->getValue()).split('=');
572 Ret[Name] = parseSectionAddress(Addr, *Arg);
601static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &args) {
602 StringMap<uint64_t> ret;
603 for (auto *arg : args.filtered(OPT_section_start)) {
604 StringRef name;
605 StringRef addr;
606 std::tie(name, addr) = StringRef(arg->getValue()).split('=');
607 ret[name] = parseSectionAddress(addr, args, *arg);
573608 }
574609
575 if (auto *Arg = Args.getLastArg(OPT_Ttext))
576 Ret[".text"] = parseSectionAddress(Arg->getValue(), *Arg);
577 if (auto *Arg = Args.getLastArg(OPT_Tdata))
578 Ret[".data"] = parseSectionAddress(Arg->getValue(), *Arg);
579 if (auto *Arg = Args.getLastArg(OPT_Tbss))
580 Ret[".bss"] = parseSectionAddress(Arg->getValue(), *Arg);
581 return Ret;
610 if (auto *arg = args.getLastArg(OPT_Ttext))
611 ret[".text"] = parseSectionAddress(arg->getValue(), args, *arg);
612 if (auto *arg = args.getLastArg(OPT_Tdata))
613 ret[".data"] = parseSectionAddress(arg->getValue(), args, *arg);
614 if (auto *arg = args.getLastArg(OPT_Tbss))
615 ret[".bss"] = parseSectionAddress(arg->getValue(), args, *arg);
616 return ret;
582617}
583618
584static SortSectionPolicy getSortSection(opt::InputArgList &Args) {
585 StringRef S = Args.getLastArgValue(OPT_sort_section);
586 if (S == "alignment")
619static SortSectionPolicy getSortSection(opt::InputArgList &args) {
620 StringRef s = args.getLastArgValue(OPT_sort_section);
621 if (s == "alignment")
587622 return SortSectionPolicy::Alignment;
588 if (S == "name")
623 if (s == "name")
589624 return SortSectionPolicy::Name;
590 if (!S.empty())
591 error("unknown --sort-section rule: " + S);
625 if (!s.empty())
626 error("unknown --sort-section rule: " + s);
592627 return SortSectionPolicy::Default;
593628}
594629
595static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &Args) {
596 StringRef S = Args.getLastArgValue(OPT_orphan_handling, "place");
597 if (S == "warn")
630static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &args) {
631 StringRef s = args.getLastArgValue(OPT_orphan_handling, "place");
632 if (s == "warn")
598633 return OrphanHandlingPolicy::Warn;
599 if (S == "error")
634 if (s == "error")
600635 return OrphanHandlingPolicy::Error;
601 if (S != "place")
602 error("unknown --orphan-handling mode: " + S);
636 if (s != "place")
637 error("unknown --orphan-handling mode: " + s);
603638 return OrphanHandlingPolicy::Place;
604639}
605640
......@@ -607,388 +642,412 @@ static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &Args) {
607642// synonym for "sha1" because all our hash functions including
608643// -build-id=sha1 are actually tree hashes for performance reasons.
609644static std::pair<BuildIdKind, std::vector<uint8_t>>
610getBuildId(opt::InputArgList &Args) {
611 auto *Arg = Args.getLastArg(OPT_build_id, OPT_build_id_eq);
612 if (!Arg)
645getBuildId(opt::InputArgList &args) {
646 auto *arg = args.getLastArg(OPT_build_id, OPT_build_id_eq);
647 if (!arg)
613648 return {BuildIdKind::None, {}};
614649
615 if (Arg->getOption().getID() == OPT_build_id)
650 if (arg->getOption().getID() == OPT_build_id)
616651 return {BuildIdKind::Fast, {}};
617652
618 StringRef S = Arg->getValue();
619 if (S == "fast")
653 StringRef s = arg->getValue();
654 if (s == "fast")
620655 return {BuildIdKind::Fast, {}};
621 if (S == "md5")
656 if (s == "md5")
622657 return {BuildIdKind::Md5, {}};
623 if (S == "sha1" || S == "tree")
658 if (s == "sha1" || s == "tree")
624659 return {BuildIdKind::Sha1, {}};
625 if (S == "uuid")
660 if (s == "uuid")
626661 return {BuildIdKind::Uuid, {}};
627 if (S.startswith("0x"))
628 return {BuildIdKind::Hexstring, parseHex(S.substr(2))};
662 if (s.startswith("0x"))
663 return {BuildIdKind::Hexstring, parseHex(s.substr(2))};
629664
630 if (S != "none")
631 error("unknown --build-id style: " + S);
665 if (s != "none")
666 error("unknown --build-id style: " + s);
632667 return {BuildIdKind::None, {}};
633668}
634669
635static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &Args) {
636 StringRef S = Args.getLastArgValue(OPT_pack_dyn_relocs, "none");
637 if (S == "android")
670static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &args) {
671 StringRef s = args.getLastArgValue(OPT_pack_dyn_relocs, "none");
672 if (s == "android")
638673 return {true, false};
639 if (S == "relr")
674 if (s == "relr")
640675 return {false, true};
641 if (S == "android+relr")
676 if (s == "android+relr")
642677 return {true, true};
643678
644 if (S != "none")
645 error("unknown -pack-dyn-relocs format: " + S);
679 if (s != "none")
680 error("unknown -pack-dyn-relocs format: " + s);
646681 return {false, false};
647682}
648683
649static void readCallGraph(MemoryBufferRef MB) {
684static void readCallGraph(MemoryBufferRef mb) {
650685 // Build a map from symbol name to section
651 DenseMap<StringRef, Symbol *> Map;
652 for (InputFile *File : ObjectFiles)
653 for (Symbol *Sym : File->getSymbols())
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);
686 DenseMap<StringRef, Symbol *> map;
687 for (InputFile *file : objectFiles)
688 for (Symbol *sym : file->getSymbols())
689 map[sym->getName()] = sym;
690
691 auto findSection = [&](StringRef name) -> InputSectionBase * {
692 Symbol *sym = map.lookup(name);
693 if (!sym) {
694 if (config->warnSymbolOrdering)
695 warn(mb.getBufferIdentifier() + ": no such symbol: " + name);
661696 return nullptr;
662697 }
663 maybeWarnUnorderableSymbol(Sym);
698 maybeWarnUnorderableSymbol(sym);
664699
665 if (Defined *DR = dyn_cast_or_null<Defined>(Sym))
666 return dyn_cast_or_null<InputSectionBase>(DR->Section);
700 if (Defined *dr = dyn_cast_or_null<Defined>(sym))
701 return dyn_cast_or_null<InputSectionBase>(dr->section);
667702 return nullptr;
668703 };
669704
670 for (StringRef Line : args::getLines(MB)) {
671 SmallVector<StringRef, 3> Fields;
672 Line.split(Fields, ' ');
673 uint64_t Count;
705 for (StringRef line : args::getLines(mb)) {
706 SmallVector<StringRef, 3> fields;
707 line.split(fields, ' ');
708 uint64_t count;
674709
675 if (Fields.size() != 3 || !to_integer(Fields[2], Count)) {
676 error(MB.getBufferIdentifier() + ": parse error");
710 if (fields.size() != 3 || !to_integer(fields[2], count)) {
711 error(mb.getBufferIdentifier() + ": parse error");
677712 return;
678713 }
679714
680 if (InputSectionBase *From = FindSection(Fields[0]))
681 if (InputSectionBase *To = FindSection(Fields[1]))
682 Config->CallGraphProfile[std::make_pair(From, To)] += Count;
715 if (InputSectionBase *from = findSection(fields[0]))
716 if (InputSectionBase *to = findSection(fields[1]))
717 config->callGraphProfile[std::make_pair(from, to)] += count;
683718 }
684719}
685720
686721template <class ELFT> static void readCallGraphsFromObjectFiles() {
687 for (auto File : ObjectFiles) {
688 auto *Obj = cast<ObjFile<ELFT>>(File);
722 for (auto file : objectFiles) {
723 auto *obj = cast<ObjFile<ELFT>>(file);
689724
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)
725 for (const Elf_CGProfile_Impl<ELFT> &cgpe : obj->cgProfile) {
726 auto *fromSym = dyn_cast<Defined>(&obj->getSymbol(cgpe.cgp_from));
727 auto *toSym = dyn_cast<Defined>(&obj->getSymbol(cgpe.cgp_to));
728 if (!fromSym || !toSym)
694729 continue;
695730
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;
731 auto *from = dyn_cast_or_null<InputSectionBase>(fromSym->section);
732 auto *to = dyn_cast_or_null<InputSectionBase>(toSym->section);
733 if (from && to)
734 config->callGraphProfile[{from, to}] += cgpe.cgp_weight;
700735 }
701736 }
702737}
703738
704static bool getCompressDebugSections(opt::InputArgList &Args) {
705 StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none");
706 if (S == "none")
739static bool getCompressDebugSections(opt::InputArgList &args) {
740 StringRef s = args.getLastArgValue(OPT_compress_debug_sections, "none");
741 if (s == "none")
707742 return false;
708 if (S != "zlib")
709 error("unknown --compress-debug-sections value: " + S);
743 if (s != "zlib")
744 error("unknown --compress-debug-sections value: " + s);
710745 if (!zlib::isAvailable())
711746 error("--compress-debug-sections: zlib is not available");
712747 return true;
713748}
714749
715static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &Args,
716 unsigned Id) {
717 auto *Arg = Args.getLastArg(Id);
718 if (!Arg)
750static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
751 unsigned id) {
752 auto *arg = args.getLastArg(id);
753 if (!arg)
719754 return {"", ""};
720755
721 StringRef S = Arg->getValue();
722 std::pair<StringRef, StringRef> Ret = S.split(';');
723 if (Ret.second.empty())
724 error(Arg->getSpelling() + " expects 'old;new' format, but got " + S);
725 return Ret;
756 StringRef s = arg->getValue();
757 std::pair<StringRef, StringRef> ret = s.split(';');
758 if (ret.second.empty())
759 error(arg->getSpelling() + " expects 'old;new' format, but got " + s);
760 return ret;
726761}
727762
728763// Parse the symbol ordering file and warn for any duplicate entries.
729static std::vector<StringRef> getSymbolOrderingFile(MemoryBufferRef MB) {
730 SetVector<StringRef> Names;
731 for (StringRef S : args::getLines(MB))
732 if (!Names.insert(S) && Config->WarnSymbolOrdering)
733 warn(MB.getBufferIdentifier() + ": duplicate ordered symbol: " + S);
764static std::vector<StringRef> getSymbolOrderingFile(MemoryBufferRef mb) {
765 SetVector<StringRef> names;
766 for (StringRef s : args::getLines(mb))
767 if (!names.insert(s) && config->warnSymbolOrdering)
768 warn(mb.getBufferIdentifier() + ": duplicate ordered symbol: " + s);
734769
735 return Names.takeVector();
770 return names.takeVector();
736771}
737772
738static void parseClangOption(StringRef Opt, const Twine &Msg) {
739 std::string Err;
740 raw_string_ostream OS(Err);
773static void parseClangOption(StringRef opt, const Twine &msg) {
774 std::string err;
775 raw_string_ostream os(err);
741776
742 const char *Argv[] = {Config->ProgName.data(), Opt.data()};
743 if (cl::ParseCommandLineOptions(2, Argv, "", &OS))
777 const char *argv[] = {config->progName.data(), opt.data()};
778 if (cl::ParseCommandLineOptions(2, argv, "", &os))
744779 return;
745 OS.flush();
746 error(Msg + ": " + StringRef(Err).trim());
780 os.flush();
781 error(msg + ": " + StringRef(err).trim());
747782}
748783
749784// Initializes Config members by the command line options.
750void LinkerDriver::readConfigs(opt::InputArgList &Args) {
751 errorHandler().Verbose = Args.hasArg(OPT_verbose);
752 errorHandler().FatalWarnings =
753 Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
754 ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
755
756 Config->AllowMultipleDefinition =
757 Args.hasFlag(OPT_allow_multiple_definition,
785static void readConfigs(opt::InputArgList &args) {
786 errorHandler().verbose = args.hasArg(OPT_verbose);
787 errorHandler().fatalWarnings =
788 args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
789 errorHandler().vsDiagnostics =
790 args.hasArg(OPT_visual_studio_diagnostics_format, false);
791 threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true);
792
793 config->allowMultipleDefinition =
794 args.hasFlag(OPT_allow_multiple_definition,
758795 OPT_no_allow_multiple_definition, false) ||
759 hasZOption(Args, "muldefs");
760 Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary);
761 Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
762 Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
763 Config->CheckSections =
764 Args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
765 Config->Chroot = Args.getLastArgValue(OPT_chroot);
766 Config->CompressDebugSections = getCompressDebugSections(Args);
767 Config->Cref = Args.hasFlag(OPT_cref, OPT_no_cref, false);
768 Config->DefineCommon = Args.hasFlag(OPT_define_common, OPT_no_define_common,
769 !Args.hasArg(OPT_relocatable));
770 Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
771 Config->DisableVerify = Args.hasArg(OPT_disable_verify);
772 Config->Discard = getDiscard(Args);
773 Config->DwoDir = Args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
774 Config->DynamicLinker = getDynamicLinker(Args);
775 Config->EhFrameHdr =
776 Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
777 Config->EmitLLVM = Args.hasArg(OPT_plugin_opt_emit_llvm, false);
778 Config->EmitRelocs = Args.hasArg(OPT_emit_relocs);
779 Config->CallGraphProfileSort = Args.hasFlag(
796 hasZOption(args, "muldefs");
797 config->allowShlibUndefined =
798 args.hasFlag(OPT_allow_shlib_undefined, OPT_no_allow_shlib_undefined,
799 args.hasArg(OPT_shared));
800 config->auxiliaryList = args::getStrings(args, OPT_auxiliary);
801 config->bsymbolic = args.hasArg(OPT_Bsymbolic);
802 config->bsymbolicFunctions = args.hasArg(OPT_Bsymbolic_functions);
803 config->checkSections =
804 args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
805 config->chroot = args.getLastArgValue(OPT_chroot);
806 config->compressDebugSections = getCompressDebugSections(args);
807 config->cref = args.hasFlag(OPT_cref, OPT_no_cref, false);
808 config->defineCommon = args.hasFlag(OPT_define_common, OPT_no_define_common,
809 !args.hasArg(OPT_relocatable));
810 config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
811 config->dependentLibraries = args.hasFlag(OPT_dependent_libraries, OPT_no_dependent_libraries, true);
812 config->disableVerify = args.hasArg(OPT_disable_verify);
813 config->discard = getDiscard(args);
814 config->dwoDir = args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
815 config->dynamicLinker = getDynamicLinker(args);
816 config->ehFrameHdr =
817 args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false);
818 config->emitLLVM = args.hasArg(OPT_plugin_opt_emit_llvm, false);
819 config->emitRelocs = args.hasArg(OPT_emit_relocs);
820 config->callGraphProfileSort = args.hasFlag(
780821 OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true);
781 Config->EnableNewDtags =
782 Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
783 Config->Entry = Args.getLastArgValue(OPT_entry);
784 Config->ExecuteOnly =
785 Args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
786 Config->ExportDynamic =
787 Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
788 Config->FilterList = args::getStrings(Args, OPT_filter);
789 Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
790 Config->FixCortexA53Errata843419 = Args.hasArg(OPT_fix_cortex_a53_843419);
791 Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
792 Config->GnuUnique = Args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true);
793 Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
794 Config->ICF = getICF(Args);
795 Config->IgnoreDataAddressEquality =
796 Args.hasArg(OPT_ignore_data_address_equality);
797 Config->IgnoreFunctionAddressEquality =
798 Args.hasArg(OPT_ignore_function_address_equality);
799 Config->Init = Args.getLastArgValue(OPT_init, "_init");
800 Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline);
801 Config->LTODebugPassManager = Args.hasArg(OPT_lto_debug_pass_manager);
802 Config->LTONewPassManager = Args.hasArg(OPT_lto_new_pass_manager);
803 Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes);
804 Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
805 Config->LTOObjPath = Args.getLastArgValue(OPT_plugin_opt_obj_path_eq);
806 Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
807 Config->LTOSampleProfile = Args.getLastArgValue(OPT_lto_sample_profile);
808 Config->MapFile = Args.getLastArgValue(OPT_Map);
809 Config->MipsGotSize = args::getInteger(Args, OPT_mips_got_size, 0xfff0);
810 Config->MergeArmExidx =
811 Args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
812 Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec);
813 Config->Nostdlib = Args.hasArg(OPT_nostdlib);
814 Config->OFormatBinary = isOutputFormatBinary(Args);
815 Config->Omagic = Args.hasFlag(OPT_omagic, OPT_no_omagic, false);
816 Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename);
817 Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness);
818 Config->Optimize = args::getInteger(Args, OPT_O, 1);
819 Config->OrphanHandling = getOrphanHandling(Args);
820 Config->OutputFile = Args.getLastArgValue(OPT_o);
821 Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
822 Config->PrintIcfSections =
823 Args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
824 Config->PrintGcSections =
825 Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
826 Config->Rpath = getRpath(Args);
827 Config->Relocatable = Args.hasArg(OPT_relocatable);
828 Config->SaveTemps = Args.hasArg(OPT_save_temps);
829 Config->SearchPaths = args::getStrings(Args, OPT_library_path);
830 Config->SectionStartMap = getSectionStartMap(Args);
831 Config->Shared = Args.hasArg(OPT_shared);
832 Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
833 Config->SoName = Args.getLastArgValue(OPT_soname);
834 Config->SortSection = getSortSection(Args);
835 Config->SplitStackAdjustSize = args::getInteger(Args, OPT_split_stack_adjust_size, 16384);
836 Config->Strip = getStrip(Args);
837 Config->Sysroot = Args.getLastArgValue(OPT_sysroot);
838 Config->Target1Rel = Args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
839 Config->Target2 = getTarget2(Args);
840 Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
841 Config->ThinLTOCachePolicy = CHECK(
842 parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
822 config->enableNewDtags =
823 args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
824 config->entry = args.getLastArgValue(OPT_entry);
825 config->executeOnly =
826 args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
827 config->exportDynamic =
828 args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
829 config->filterList = args::getStrings(args, OPT_filter);
830 config->fini = args.getLastArgValue(OPT_fini, "_fini");
831 config->fixCortexA53Errata843419 = args.hasArg(OPT_fix_cortex_a53_843419);
832 config->forceBTI = args.hasArg(OPT_force_bti);
833 config->requireCET = args.hasArg(OPT_require_cet);
834 config->gcSections = args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
835 config->gnuUnique = args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true);
836 config->gdbIndex = args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
837 config->icf = getICF(args);
838 config->ignoreDataAddressEquality =
839 args.hasArg(OPT_ignore_data_address_equality);
840 config->ignoreFunctionAddressEquality =
841 args.hasArg(OPT_ignore_function_address_equality);
842 config->init = args.getLastArgValue(OPT_init, "_init");
843 config->ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline);
844 config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
845 config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file);
846 config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
847 config->ltoNewPassManager = args.hasArg(OPT_lto_new_pass_manager);
848 config->ltoNewPmPasses = args.getLastArgValue(OPT_lto_newpm_passes);
849 config->ltoo = args::getInteger(args, OPT_lto_O, 2);
850 config->ltoObjPath = args.getLastArgValue(OPT_plugin_opt_obj_path_eq);
851 config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
852 config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
853 config->mapFile = args.getLastArgValue(OPT_Map);
854 config->mipsGotSize = args::getInteger(args, OPT_mips_got_size, 0xfff0);
855 config->mergeArmExidx =
856 args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
857 config->nmagic = args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
858 config->noinhibitExec = args.hasArg(OPT_noinhibit_exec);
859 config->nostdlib = args.hasArg(OPT_nostdlib);
860 config->oFormatBinary = isOutputFormatBinary(args);
861 config->omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
862 config->optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
863 config->optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
864 config->optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
865 config->optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);
866 config->optimize = args::getInteger(args, OPT_O, 1);
867 config->orphanHandling = getOrphanHandling(args);
868 config->outputFile = args.getLastArgValue(OPT_o);
869 config->pacPlt = args.hasArg(OPT_pac_plt);
870 config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
871 config->printIcfSections =
872 args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
873 config->printGcSections =
874 args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
875 config->printSymbolOrder =
876 args.getLastArgValue(OPT_print_symbol_order);
877 config->rpath = getRpath(args);
878 config->relocatable = args.hasArg(OPT_relocatable);
879 config->saveTemps = args.hasArg(OPT_save_temps);
880 config->searchPaths = args::getStrings(args, OPT_library_path);
881 config->sectionStartMap = getSectionStartMap(args);
882 config->shared = args.hasArg(OPT_shared);
883 config->singleRoRx = args.hasArg(OPT_no_rosegment);
884 config->soName = args.getLastArgValue(OPT_soname);
885 config->sortSection = getSortSection(args);
886 config->splitStackAdjustSize = args::getInteger(args, OPT_split_stack_adjust_size, 16384);
887 config->strip = getStrip(args);
888 config->sysroot = args.getLastArgValue(OPT_sysroot);
889 config->target1Rel = args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
890 config->target2 = getTarget2(args);
891 config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
892 config->thinLTOCachePolicy = CHECK(
893 parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
843894 "--thinlto-cache-policy: invalid cache policy");
844 Config->ThinLTOEmitImportsFiles =
845 Args.hasArg(OPT_plugin_opt_thinlto_emit_imports_files);
846 Config->ThinLTOIndexOnly = Args.hasArg(OPT_plugin_opt_thinlto_index_only) ||
847 Args.hasArg(OPT_plugin_opt_thinlto_index_only_eq);
848 Config->ThinLTOIndexOnlyArg =
849 Args.getLastArgValue(OPT_plugin_opt_thinlto_index_only_eq);
850 Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
851 Config->ThinLTOObjectSuffixReplace =
852 getOldNewOptions(Args, OPT_plugin_opt_thinlto_object_suffix_replace_eq);
853 Config->ThinLTOPrefixReplace =
854 getOldNewOptions(Args, OPT_plugin_opt_thinlto_prefix_replace_eq);
855 Config->Trace = Args.hasArg(OPT_trace);
856 Config->Undefined = args::getStrings(Args, OPT_undefined);
857 Config->UndefinedVersion =
858 Args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
859 Config->UseAndroidRelrTags = Args.hasFlag(
895 config->thinLTOEmitImportsFiles =
896 args.hasArg(OPT_plugin_opt_thinlto_emit_imports_files);
897 config->thinLTOIndexOnly = args.hasArg(OPT_plugin_opt_thinlto_index_only) ||
898 args.hasArg(OPT_plugin_opt_thinlto_index_only_eq);
899 config->thinLTOIndexOnlyArg =
900 args.getLastArgValue(OPT_plugin_opt_thinlto_index_only_eq);
901 config->thinLTOJobs = args::getInteger(args, OPT_thinlto_jobs, -1u);
902 config->thinLTOObjectSuffixReplace =
903 getOldNewOptions(args, OPT_plugin_opt_thinlto_object_suffix_replace_eq);
904 config->thinLTOPrefixReplace =
905 getOldNewOptions(args, OPT_plugin_opt_thinlto_prefix_replace_eq);
906 config->trace = args.hasArg(OPT_trace);
907 config->undefined = args::getStrings(args, OPT_undefined);
908 config->undefinedVersion =
909 args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
910 config->useAndroidRelrTags = args.hasFlag(
860911 OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false);
861 Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args);
862 Config->WarnBackrefs =
863 Args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
864 Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
865 Config->WarnIfuncTextrel =
866 Args.hasFlag(OPT_warn_ifunc_textrel, OPT_no_warn_ifunc_textrel, false);
867 Config->WarnSymbolOrdering =
868 Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
869 Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true);
870 Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true);
871 Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false);
872 Config->ZGlobal = hasZOption(Args, "global");
873 Config->ZHazardplt = hasZOption(Args, "hazardplt");
874 Config->ZInitfirst = hasZOption(Args, "initfirst");
875 Config->ZInterpose = hasZOption(Args, "interpose");
876 Config->ZKeepTextSectionPrefix = getZFlag(
877 Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
878 Config->ZNodefaultlib = hasZOption(Args, "nodefaultlib");
879 Config->ZNodelete = hasZOption(Args, "nodelete");
880 Config->ZNodlopen = hasZOption(Args, "nodlopen");
881 Config->ZNow = getZFlag(Args, "now", "lazy", false);
882 Config->ZOrigin = hasZOption(Args, "origin");
883 Config->ZRelro = getZFlag(Args, "relro", "norelro", true);
884 Config->ZRetpolineplt = hasZOption(Args, "retpolineplt");
885 Config->ZRodynamic = hasZOption(Args, "rodynamic");
886 Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0);
887 Config->ZText = getZFlag(Args, "text", "notext", true);
888 Config->ZWxneeded = hasZOption(Args, "wxneeded");
912 config->unresolvedSymbols = getUnresolvedSymbolPolicy(args);
913 config->warnBackrefs =
914 args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
915 config->warnCommon = args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
916 config->warnIfuncTextrel =
917 args.hasFlag(OPT_warn_ifunc_textrel, OPT_no_warn_ifunc_textrel, false);
918 config->warnSymbolOrdering =
919 args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
920 config->zCombreloc = getZFlag(args, "combreloc", "nocombreloc", true);
921 config->zCopyreloc = getZFlag(args, "copyreloc", "nocopyreloc", true);
922 config->zExecstack = getZFlag(args, "execstack", "noexecstack", false);
923 config->zGlobal = hasZOption(args, "global");
924 config->zHazardplt = hasZOption(args, "hazardplt");
925 config->zIfuncNoplt = hasZOption(args, "ifunc-noplt");
926 config->zInitfirst = hasZOption(args, "initfirst");
927 config->zInterpose = hasZOption(args, "interpose");
928 config->zKeepTextSectionPrefix = getZFlag(
929 args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
930 config->zNodefaultlib = hasZOption(args, "nodefaultlib");
931 config->zNodelete = hasZOption(args, "nodelete");
932 config->zNodlopen = hasZOption(args, "nodlopen");
933 config->zNow = getZFlag(args, "now", "lazy", false);
934 config->zOrigin = hasZOption(args, "origin");
935 config->zRelro = getZFlag(args, "relro", "norelro", true);
936 config->zRetpolineplt = hasZOption(args, "retpolineplt");
937 config->zRodynamic = hasZOption(args, "rodynamic");
938 config->zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0);
939 config->zText = getZFlag(args, "text", "notext", true);
940 config->zWxneeded = hasZOption(args, "wxneeded");
889941
890942 // Parse LTO options.
891 if (auto *Arg = Args.getLastArg(OPT_plugin_opt_mcpu_eq))
892 parseClangOption(Saver.save("-mcpu=" + StringRef(Arg->getValue())),
893 Arg->getSpelling());
943 if (auto *arg = args.getLastArg(OPT_plugin_opt_mcpu_eq))
944 parseClangOption(saver.save("-mcpu=" + StringRef(arg->getValue())),
945 arg->getSpelling());
894946
895 for (auto *Arg : Args.filtered(OPT_plugin_opt))
896 parseClangOption(Arg->getValue(), Arg->getSpelling());
947 for (auto *arg : args.filtered(OPT_plugin_opt))
948 parseClangOption(arg->getValue(), arg->getSpelling());
897949
898950 // Parse -mllvm options.
899 for (auto *Arg : Args.filtered(OPT_mllvm))
900 parseClangOption(Arg->getValue(), Arg->getSpelling());
951 for (auto *arg : args.filtered(OPT_mllvm))
952 parseClangOption(arg->getValue(), arg->getSpelling());
901953
902 if (Config->LTOO > 3)
903 error("invalid optimization level for LTO: " + Twine(Config->LTOO));
904 if (Config->LTOPartitions == 0)
954 if (config->ltoo > 3)
955 error("invalid optimization level for LTO: " + Twine(config->ltoo));
956 if (config->ltoPartitions == 0)
905957 error("--lto-partitions: number of threads must be > 0");
906 if (Config->ThinLTOJobs == 0)
958 if (config->thinLTOJobs == 0)
907959 error("--thinlto-jobs: number of threads must be > 0");
908960
909 if (Config->SplitStackAdjustSize < 0)
961 if (config->splitStackAdjustSize < 0)
910962 error("--split-stack-adjust-size: size must be >= 0");
911963
912964 // Parse ELF{32,64}{LE,BE} and CPU type.
913 if (auto *Arg = Args.getLastArg(OPT_m)) {
914 StringRef S = Arg->getValue();
915 std::tie(Config->EKind, Config->EMachine, Config->OSABI) =
916 parseEmulation(S);
917 Config->MipsN32Abi = (S == "elf32btsmipn32" || S == "elf32ltsmipn32");
918 Config->Emulation = S;
965 if (auto *arg = args.getLastArg(OPT_m)) {
966 StringRef s = arg->getValue();
967 std::tie(config->ekind, config->emachine, config->osabi) =
968 parseEmulation(s);
969 config->mipsN32Abi = (s == "elf32btsmipn32" || s == "elf32ltsmipn32");
970 config->emulation = s;
919971 }
920972
921973 // Parse -hash-style={sysv,gnu,both}.
922 if (auto *Arg = Args.getLastArg(OPT_hash_style)) {
923 StringRef S = Arg->getValue();
924 if (S == "sysv")
925 Config->SysvHash = true;
926 else if (S == "gnu")
927 Config->GnuHash = true;
928 else if (S == "both")
929 Config->SysvHash = Config->GnuHash = true;
974 if (auto *arg = args.getLastArg(OPT_hash_style)) {
975 StringRef s = arg->getValue();
976 if (s == "sysv")
977 config->sysvHash = true;
978 else if (s == "gnu")
979 config->gnuHash = true;
980 else if (s == "both")
981 config->sysvHash = config->gnuHash = true;
930982 else
931 error("unknown -hash-style: " + S);
983 error("unknown -hash-style: " + s);
932984 }
933985
934 if (Args.hasArg(OPT_print_map))
935 Config->MapFile = "-";
936
937 // --omagic is an option to create old-fashioned executables in which
938 // .text segments are writable. Today, the option is still in use to
939 // create special-purpose programs such as boot loaders. It doesn't
940 // make sense to create PT_GNU_RELRO for such executables.
941 if (Config->Omagic)
942 Config->ZRelro = false;
943
944 std::tie(Config->BuildId, Config->BuildIdVector) = getBuildId(Args);
945
946 std::tie(Config->AndroidPackDynRelocs, Config->RelrPackDynRelocs) =
947 getPackDynRelocs(Args);
948
949 if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file))
950 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
951 Config->SymbolOrderingFile = getSymbolOrderingFile(*Buffer);
986 if (args.hasArg(OPT_print_map))
987 config->mapFile = "-";
988
989 // Page alignment can be disabled by the -n (--nmagic) and -N (--omagic).
990 // As PT_GNU_RELRO relies on Paging, do not create it when we have disabled
991 // it.
992 if (config->nmagic || config->omagic)
993 config->zRelro = false;
994
995 std::tie(config->buildId, config->buildIdVector) = getBuildId(args);
996
997 std::tie(config->androidPackDynRelocs, config->relrPackDynRelocs) =
998 getPackDynRelocs(args);
999
1000 if (auto *arg = args.getLastArg(OPT_symbol_ordering_file)){
1001 if (args.hasArg(OPT_call_graph_ordering_file))
1002 error("--symbol-ordering-file and --call-graph-order-file "
1003 "may not be used together");
1004 if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue())){
1005 config->symbolOrderingFile = getSymbolOrderingFile(*buffer);
1006 // Also need to disable CallGraphProfileSort to prevent
1007 // LLD order symbols with CGProfile
1008 config->callGraphProfileSort = false;
1009 }
1010 }
9521011
9531012 // If --retain-symbol-file is used, we'll keep only the symbols listed in
9541013 // the file and discard all others.
955 if (auto *Arg = Args.getLastArg(OPT_retain_symbols_file)) {
956 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
957 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
958 for (StringRef S : args::getLines(*Buffer))
959 Config->VersionScriptGlobals.push_back(
960 {S, /*IsExternCpp*/ false, /*HasWildcard*/ false});
1014 if (auto *arg = args.getLastArg(OPT_retain_symbols_file)) {
1015 config->defaultSymbolVersion = VER_NDX_LOCAL;
1016 if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
1017 for (StringRef s : args::getLines(*buffer))
1018 config->versionScriptGlobals.push_back(
1019 {s, /*IsExternCpp*/ false, /*HasWildcard*/ false});
9611020 }
9621021
963 bool HasExportDynamic =
964 Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
1022 bool hasExportDynamic =
1023 args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
9651024
9661025 // Parses -dynamic-list and -export-dynamic-symbol. They make some
9671026 // symbols private. Note that -export-dynamic takes precedence over them
9681027 // as it says all symbols should be exported.
969 if (!HasExportDynamic) {
970 for (auto *Arg : Args.filtered(OPT_dynamic_list))
971 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
972 readDynamicList(*Buffer);
973
974 for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
975 Config->DynamicList.push_back(
976 {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false});
1028 if (!hasExportDynamic) {
1029 for (auto *arg : args.filtered(OPT_dynamic_list))
1030 if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
1031 readDynamicList(*buffer);
1032
1033 for (auto *arg : args.filtered(OPT_export_dynamic_symbol))
1034 config->dynamicList.push_back(
1035 {arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false});
9771036 }
9781037
9791038 // If --export-dynamic-symbol=foo is given and symbol foo is defined in
9801039 // an object file in an archive file, that object file should be pulled
9811040 // out and linked. (It doesn't have to behave like that from technical
9821041 // point of view, but this is needed for compatibility with GNU.)
983 for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
984 Config->Undefined.push_back(Arg->getValue());
1042 for (auto *arg : args.filtered(OPT_export_dynamic_symbol))
1043 config->undefined.push_back(arg->getValue());
9851044
986 for (auto *Arg : Args.filtered(OPT_version_script))
987 if (Optional<std::string> Path = searchScript(Arg->getValue())) {
988 if (Optional<MemoryBufferRef> Buffer = readFile(*Path))
989 readVersionScript(*Buffer);
1045 for (auto *arg : args.filtered(OPT_version_script))
1046 if (Optional<std::string> path = searchScript(arg->getValue())) {
1047 if (Optional<MemoryBufferRef> buffer = readFile(*path))
1048 readVersionScript(*buffer);
9901049 } else {
991 error(Twine("cannot find version script ") + Arg->getValue());
1050 error(Twine("cannot find version script ") + arg->getValue());
9921051 }
9931052}
9941053
......@@ -996,18 +1055,18 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
9961055// command line options, but computed based on other Config values.
9971056// This function initialize such members. See Config.h for the details
9981057// of these values.
999static void setConfigs(opt::InputArgList &Args) {
1000 ELFKind K = Config->EKind;
1001 uint16_t M = Config->EMachine;
1002
1003 Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs);
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);
1008 Config->Pic = Config->Pie || Config->Shared;
1009 Config->PicThunk = Args.hasArg(OPT_pic_veneer, Config->Pic);
1010 Config->Wordsize = Config->Is64 ? 8 : 4;
1058static void setConfigs(opt::InputArgList &args) {
1059 ELFKind k = config->ekind;
1060 uint16_t m = config->emachine;
1061
1062 config->copyRelocs = (config->relocatable || config->emitRelocs);
1063 config->is64 = (k == ELF64LEKind || k == ELF64BEKind);
1064 config->isLE = (k == ELF32LEKind || k == ELF64LEKind);
1065 config->endianness = config->isLE ? endianness::little : endianness::big;
1066 config->isMips64EL = (k == ELF64LEKind && m == EM_MIPS);
1067 config->isPic = config->pie || config->shared;
1068 config->picThunk = args.hasArg(OPT_pic_veneer, config->isPic);
1069 config->wordsize = config->is64 ? 8 : 4;
10111070
10121071 // ELF defines two different ways to store relocation addends as shown below:
10131072 //
......@@ -1022,148 +1081,150 @@ static void setConfigs(opt::InputArgList &Args) {
10221081 // You cannot choose which one, Rel or Rela, you want to use. Instead each
10231082 // ABI defines which one you need to use. The following expression expresses
10241083 // that.
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;
1084 config->isRela = m == EM_AARCH64 || m == EM_AMDGPU || m == EM_HEXAGON ||
1085 m == EM_PPC || m == EM_PPC64 || m == EM_RISCV ||
1086 m == EM_X86_64;
10281087
10291088 // If the output uses REL relocations we must store the dynamic relocation
10301089 // addends to the output sections. We also store addends for RELA relocations
10311090 // if --apply-dynamic-relocs is used.
10321091 // We default to not writing the addends when using RELA relocations since
10331092 // any standard conforming tool can find it in r_addend.
1034 Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs,
1093 config->writeAddends = args.hasFlag(OPT_apply_dynamic_relocs,
10351094 OPT_no_apply_dynamic_relocs, false) ||
1036 !Config->IsRela;
1095 !config->isRela;
10371096
1038 Config->TocOptimize =
1039 Args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, M == EM_PPC64);
1097 config->tocOptimize =
1098 args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, m == EM_PPC64);
10401099}
10411100
10421101// Returns a value of "-format" option.
1043static bool isFormatBinary(StringRef S) {
1044 if (S == "binary")
1102static bool isFormatBinary(StringRef s) {
1103 if (s == "binary")
10451104 return true;
1046 if (S == "elf" || S == "default")
1105 if (s == "elf" || s == "default")
10471106 return false;
1048 error("unknown -format value: " + S +
1107 error("unknown -format value: " + s +
10491108 " (supported formats: elf, default, binary)");
10501109 return false;
10511110}
10521111
1053void LinkerDriver::createFiles(opt::InputArgList &Args) {
1112void LinkerDriver::createFiles(opt::InputArgList &args) {
10541113 // For --{push,pop}-state.
1055 std::vector<std::tuple<bool, bool, bool>> Stack;
1114 std::vector<std::tuple<bool, bool, bool>> stack;
10561115
10571116 // Iterate over argv to process input files and positional arguments.
1058 for (auto *Arg : Args) {
1059 switch (Arg->getOption().getUnaliasedOption().getID()) {
1117 for (auto *arg : args) {
1118 switch (arg->getOption().getID()) {
10601119 case OPT_library:
1061 addLibrary(Arg->getValue());
1120 addLibrary(arg->getValue());
10621121 break;
10631122 case OPT_INPUT:
1064 addFile(Arg->getValue(), /*WithLOption=*/false);
1123 addFile(arg->getValue(), /*withLOption=*/false);
10651124 break;
10661125 case OPT_defsym: {
1067 StringRef From;
1068 StringRef To;
1069 std::tie(From, To) = StringRef(Arg->getValue()).split('=');
1070 if (From.empty() || To.empty())
1071 error("-defsym: syntax error: " + StringRef(Arg->getValue()));
1126 StringRef from;
1127 StringRef to;
1128 std::tie(from, to) = StringRef(arg->getValue()).split('=');
1129 if (from.empty() || to.empty())
1130 error("-defsym: syntax error: " + StringRef(arg->getValue()));
10721131 else
1073 readDefsym(From, MemoryBufferRef(To, "-defsym"));
1132 readDefsym(from, MemoryBufferRef(to, "-defsym"));
10741133 break;
10751134 }
10761135 case OPT_script:
1077 if (Optional<std::string> Path = searchScript(Arg->getValue())) {
1078 if (Optional<MemoryBufferRef> MB = readFile(*Path))
1079 readLinkerScript(*MB);
1136 if (Optional<std::string> path = searchScript(arg->getValue())) {
1137 if (Optional<MemoryBufferRef> mb = readFile(*path))
1138 readLinkerScript(*mb);
10801139 break;
10811140 }
1082 error(Twine("cannot find linker script ") + Arg->getValue());
1141 error(Twine("cannot find linker script ") + arg->getValue());
10831142 break;
10841143 case OPT_as_needed:
1085 Config->AsNeeded = true;
1144 config->asNeeded = true;
10861145 break;
10871146 case OPT_format:
1088 Config->FormatBinary = isFormatBinary(Arg->getValue());
1147 config->formatBinary = isFormatBinary(arg->getValue());
10891148 break;
10901149 case OPT_no_as_needed:
1091 Config->AsNeeded = false;
1150 config->asNeeded = false;
10921151 break;
10931152 case OPT_Bstatic:
1094 Config->Static = true;
1153 case OPT_omagic:
1154 case OPT_nmagic:
1155 config->isStatic = true;
10951156 break;
10961157 case OPT_Bdynamic:
1097 Config->Static = false;
1158 config->isStatic = false;
10981159 break;
10991160 case OPT_whole_archive:
1100 InWholeArchive = true;
1161 inWholeArchive = true;
11011162 break;
11021163 case OPT_no_whole_archive:
1103 InWholeArchive = false;
1164 inWholeArchive = false;
11041165 break;
11051166 case OPT_just_symbols:
1106 if (Optional<MemoryBufferRef> MB = readFile(Arg->getValue())) {
1107 Files.push_back(createObjectFile(*MB));
1108 Files.back()->JustSymbols = true;
1167 if (Optional<MemoryBufferRef> mb = readFile(arg->getValue())) {
1168 files.push_back(createObjectFile(*mb));
1169 files.back()->justSymbols = true;
11091170 }
11101171 break;
11111172 case OPT_start_group:
1112 if (InputFile::IsInGroup)
1173 if (InputFile::isInGroup)
11131174 error("nested --start-group");
1114 InputFile::IsInGroup = true;
1175 InputFile::isInGroup = true;
11151176 break;
11161177 case OPT_end_group:
1117 if (!InputFile::IsInGroup)
1178 if (!InputFile::isInGroup)
11181179 error("stray --end-group");
1119 InputFile::IsInGroup = false;
1120 ++InputFile::NextGroupId;
1180 InputFile::isInGroup = false;
1181 ++InputFile::nextGroupId;
11211182 break;
11221183 case OPT_start_lib:
1123 if (InLib)
1184 if (inLib)
11241185 error("nested --start-lib");
1125 if (InputFile::IsInGroup)
1186 if (InputFile::isInGroup)
11261187 error("may not nest --start-lib in --start-group");
1127 InLib = true;
1128 InputFile::IsInGroup = true;
1188 inLib = true;
1189 InputFile::isInGroup = true;
11291190 break;
11301191 case OPT_end_lib:
1131 if (!InLib)
1192 if (!inLib)
11321193 error("stray --end-lib");
1133 InLib = false;
1134 InputFile::IsInGroup = false;
1135 ++InputFile::NextGroupId;
1194 inLib = false;
1195 InputFile::isInGroup = false;
1196 ++InputFile::nextGroupId;
11361197 break;
11371198 case OPT_push_state:
1138 Stack.emplace_back(Config->AsNeeded, Config->Static, InWholeArchive);
1199 stack.emplace_back(config->asNeeded, config->isStatic, inWholeArchive);
11391200 break;
11401201 case OPT_pop_state:
1141 if (Stack.empty()) {
1202 if (stack.empty()) {
11421203 error("unbalanced --push-state/--pop-state");
11431204 break;
11441205 }
1145 std::tie(Config->AsNeeded, Config->Static, InWholeArchive) = Stack.back();
1146 Stack.pop_back();
1206 std::tie(config->asNeeded, config->isStatic, inWholeArchive) = stack.back();
1207 stack.pop_back();
11471208 break;
11481209 }
11491210 }
11501211
1151 if (Files.empty() && errorCount() == 0)
1212 if (files.empty() && errorCount() == 0)
11521213 error("no input files");
11531214}
11541215
11551216// If -m <machine_type> was not given, infer it from object files.
11561217void LinkerDriver::inferMachineType() {
1157 if (Config->EKind != ELFNoneKind)
1218 if (config->ekind != ELFNoneKind)
11581219 return;
11591220
1160 for (InputFile *F : Files) {
1161 if (F->EKind == ELFNoneKind)
1221 for (InputFile *f : files) {
1222 if (f->ekind == ELFNoneKind)
11621223 continue;
1163 Config->EKind = F->EKind;
1164 Config->EMachine = F->EMachine;
1165 Config->OSABI = F->OSABI;
1166 Config->MipsN32Abi = Config->EMachine == EM_MIPS && isMipsN32Abi(F);
1224 config->ekind = f->ekind;
1225 config->emachine = f->emachine;
1226 config->osabi = f->osabi;
1227 config->mipsN32Abi = config->emachine == EM_MIPS && isMipsN32Abi(f);
11671228 return;
11681229 }
11691230 error("target emulation unknown: -m or at least one .o file required");
......@@ -1171,49 +1232,72 @@ void LinkerDriver::inferMachineType() {
11711232
11721233// Parse -z max-page-size=<value>. The default value is defined by
11731234// each target.
1174static uint64_t getMaxPageSize(opt::InputArgList &Args) {
1175 uint64_t Val = args::getZOptionValue(Args, OPT_z, "max-page-size",
1176 Target->DefaultMaxPageSize);
1177 if (!isPowerOf2_64(Val))
1235static uint64_t getMaxPageSize(opt::InputArgList &args) {
1236 uint64_t val = args::getZOptionValue(args, OPT_z, "max-page-size",
1237 target->defaultMaxPageSize);
1238 if (!isPowerOf2_64(val))
11781239 error("max-page-size: value isn't a power of 2");
1179 return Val;
1240 if (config->nmagic || config->omagic) {
1241 if (val != target->defaultMaxPageSize)
1242 warn("-z max-page-size set, but paging disabled by omagic or nmagic");
1243 return 1;
1244 }
1245 return val;
1246}
1247
1248// Parse -z common-page-size=<value>. The default value is defined by
1249// each target.
1250static uint64_t getCommonPageSize(opt::InputArgList &args) {
1251 uint64_t val = args::getZOptionValue(args, OPT_z, "common-page-size",
1252 target->defaultCommonPageSize);
1253 if (!isPowerOf2_64(val))
1254 error("common-page-size: value isn't a power of 2");
1255 if (config->nmagic || config->omagic) {
1256 if (val != target->defaultCommonPageSize)
1257 warn("-z common-page-size set, but paging disabled by omagic or nmagic");
1258 return 1;
1259 }
1260 // commonPageSize can't be larger than maxPageSize.
1261 if (val > config->maxPageSize)
1262 val = config->maxPageSize;
1263 return val;
11801264}
11811265
11821266// Parses -image-base option.
1183static Optional<uint64_t> getImageBase(opt::InputArgList &Args) {
1184 // Because we are using "Config->MaxPageSize" here, this function has to be
1267static Optional<uint64_t> getImageBase(opt::InputArgList &args) {
1268 // Because we are using "Config->maxPageSize" here, this function has to be
11851269 // called after the variable is initialized.
1186 auto *Arg = Args.getLastArg(OPT_image_base);
1187 if (!Arg)
1270 auto *arg = args.getLastArg(OPT_image_base);
1271 if (!arg)
11881272 return None;
11891273
1190 StringRef S = Arg->getValue();
1191 uint64_t V;
1192 if (!to_integer(S, V)) {
1193 error("-image-base: number expected, but got " + S);
1274 StringRef s = arg->getValue();
1275 uint64_t v;
1276 if (!to_integer(s, v)) {
1277 error("-image-base: number expected, but got " + s);
11941278 return 0;
11951279 }
1196 if ((V % Config->MaxPageSize) != 0)
1197 warn("-image-base: address isn't multiple of page size: " + S);
1198 return V;
1280 if ((v % config->maxPageSize) != 0)
1281 warn("-image-base: address isn't multiple of page size: " + s);
1282 return v;
11991283}
12001284
12011285// Parses `--exclude-libs=lib,lib,...`.
12021286// The library names may be delimited by commas or colons.
1203static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
1204 DenseSet<StringRef> Ret;
1205 for (auto *Arg : Args.filtered(OPT_exclude_libs)) {
1206 StringRef S = Arg->getValue();
1287static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &args) {
1288 DenseSet<StringRef> ret;
1289 for (auto *arg : args.filtered(OPT_exclude_libs)) {
1290 StringRef s = arg->getValue();
12071291 for (;;) {
1208 size_t Pos = S.find_first_of(",:");
1209 if (Pos == StringRef::npos)
1292 size_t pos = s.find_first_of(",:");
1293 if (pos == StringRef::npos)
12101294 break;
1211 Ret.insert(S.substr(0, Pos));
1212 S = S.substr(Pos + 1);
1295 ret.insert(s.substr(0, pos));
1296 s = s.substr(pos + 1);
12131297 }
1214 Ret.insert(S);
1298 ret.insert(s);
12151299 }
1216 return Ret;
1300 return ret;
12171301}
12181302
12191303// Handles the -exclude-libs option. If a static library file is specified
......@@ -1222,139 +1306,247 @@ static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
12221306// A special library name "ALL" means all archive files.
12231307//
12241308// This is not a popular option, but some programs such as bionic libc use it.
1225template <class ELFT>
1226static void excludeLibs(opt::InputArgList &Args) {
1227 DenseSet<StringRef> Libs = getExcludeLibs(Args);
1228 bool All = Libs.count("ALL");
1229
1230 auto Visit = [&](InputFile *File) {
1231 if (!File->ArchiveName.empty())
1232 if (All || Libs.count(path::filename(File->ArchiveName)))
1233 for (Symbol *Sym : File->getSymbols())
1234 if (!Sym->isLocal() && Sym->File == File)
1235 Sym->VersionId = VER_NDX_LOCAL;
1309static void excludeLibs(opt::InputArgList &args) {
1310 DenseSet<StringRef> libs = getExcludeLibs(args);
1311 bool all = libs.count("ALL");
1312
1313 auto visit = [&](InputFile *file) {
1314 if (!file->archiveName.empty())
1315 if (all || libs.count(path::filename(file->archiveName)))
1316 for (Symbol *sym : file->getSymbols())
1317 if (!sym->isLocal() && sym->file == file)
1318 sym->versionId = VER_NDX_LOCAL;
12361319 };
12371320
1238 for (InputFile *File : ObjectFiles)
1239 Visit(File);
1321 for (InputFile *file : objectFiles)
1322 visit(file);
12401323
1241 for (BitcodeFile *File : BitcodeFiles)
1242 Visit(File);
1324 for (BitcodeFile *file : bitcodeFiles)
1325 visit(file);
12431326}
12441327
12451328// Force Sym to be entered in the output. Used for -u or equivalent.
1246template <class ELFT> static void handleUndefined(StringRef Name) {
1247 Symbol *Sym = Symtab->find(Name);
1248 if (!Sym)
1329static void handleUndefined(Symbol *sym) {
1330 // Since a symbol may not be used inside the program, LTO may
1331 // eliminate it. Mark the symbol as "used" to prevent it.
1332 sym->isUsedInRegularObj = true;
1333
1334 if (sym->isLazy())
1335 sym->fetch();
1336}
1337
1338// As an extention to GNU linkers, lld supports a variant of `-u`
1339// which accepts wildcard patterns. All symbols that match a given
1340// pattern are handled as if they were given by `-u`.
1341static void handleUndefinedGlob(StringRef arg) {
1342 Expected<GlobPattern> pat = GlobPattern::create(arg);
1343 if (!pat) {
1344 error("--undefined-glob: " + toString(pat.takeError()));
12491345 return;
1346 }
12501347
1251 // Since symbol S may not be used inside the program, LTO may
1252 // eliminate it. Mark the symbol as "used" to prevent it.
1253 Sym->IsUsedInRegularObj = true;
1348 std::vector<Symbol *> syms;
1349 symtab->forEachSymbol([&](Symbol *sym) {
1350 // Calling Sym->fetch() from here is not safe because it may
1351 // add new symbols to the symbol table, invalidating the
1352 // current iterator. So we just keep a note.
1353 if (pat->match(sym->getName()))
1354 syms.push_back(sym);
1355 });
12541356
1255 if (Sym->isLazy())
1256 Symtab->fetchLazy<ELFT>(Sym);
1357 for (Symbol *sym : syms)
1358 handleUndefined(sym);
12571359}
12581360
1259template <class ELFT> static void handleLibcall(StringRef Name) {
1260 Symbol *Sym = Symtab->find(Name);
1261 if (!Sym || !Sym->isLazy())
1361static void handleLibcall(StringRef name) {
1362 Symbol *sym = symtab->find(name);
1363 if (!sym || !sym->isLazy())
12621364 return;
12631365
1264 MemoryBufferRef MB;
1265 if (auto *LO = dyn_cast<LazyObject>(Sym))
1266 MB = LO->File->MB;
1366 MemoryBufferRef mb;
1367 if (auto *lo = dyn_cast<LazyObject>(sym))
1368 mb = lo->file->mb;
12671369 else
1268 MB = cast<LazyArchive>(Sym)->getMemberBuffer();
1370 mb = cast<LazyArchive>(sym)->getMemberBuffer();
12691371
1270 if (isBitcode(MB))
1271 Symtab->fetchLazy<ELFT>(Sym);
1372 if (isBitcode(mb))
1373 sym->fetch();
1374}
1375
1376// Replaces common symbols with defined symbols reside in .bss sections.
1377// This function is called after all symbol names are resolved. As a
1378// result, the passes after the symbol resolution won't see any
1379// symbols of type CommonSymbol.
1380static void replaceCommonSymbols() {
1381 symtab->forEachSymbol([](Symbol *sym) {
1382 auto *s = dyn_cast<CommonSymbol>(sym);
1383 if (!s)
1384 return;
1385
1386 auto *bss = make<BssSection>("COMMON", s->size, s->alignment);
1387 bss->file = s->file;
1388 bss->markDead();
1389 inputSections.push_back(bss);
1390 s->replace(Defined{s->file, s->getName(), s->binding, s->stOther, s->type,
1391 /*value=*/0, s->size, bss});
1392 });
12721393}
12731394
12741395// If all references to a DSO happen to be weak, the DSO is not added
12751396// to DT_NEEDED. If that happens, we need to eliminate shared symbols
12761397// created from the DSO. Otherwise, they become dangling references
12771398// that point to a non-existent DSO.
1278template <class ELFT> static void demoteSharedSymbols() {
1279 for (Symbol *Sym : Symtab->getSymbols()) {
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 }
1287 }
1288 }
1399static void demoteSharedSymbols() {
1400 symtab->forEachSymbol([](Symbol *sym) {
1401 auto *s = dyn_cast<SharedSymbol>(sym);
1402 if (!s || s->getFile().isNeeded)
1403 return;
1404
1405 bool used = s->used;
1406 s->replace(Undefined{nullptr, s->getName(), STB_WEAK, s->stOther, s->type});
1407 s->used = used;
1408 });
12891409}
12901410
1291// The section referred to by S is considered address-significant. Set the
1292// KeepUnique flag on the section if appropriate.
1293static void markAddrsig(Symbol *S) {
1294 if (auto *D = dyn_cast_or_null<Defined>(S))
1295 if (D->Section)
1411// The section referred to by `s` is considered address-significant. Set the
1412// keepUnique flag on the section if appropriate.
1413static void markAddrsig(Symbol *s) {
1414 if (auto *d = dyn_cast_or_null<Defined>(s))
1415 if (d->section)
12961416 // We don't need to keep text sections unique under --icf=all even if they
12971417 // are address-significant.
1298 if (Config->ICF == ICFLevel::Safe || !(D->Section->Flags & SHF_EXECINSTR))
1299 D->Section->KeepUnique = true;
1418 if (config->icf == ICFLevel::Safe || !(d->section->flags & SHF_EXECINSTR))
1419 d->section->keepUnique = true;
13001420}
13011421
13021422// Record sections that define symbols mentioned in --keep-unique <symbol>
13031423// and symbols referred to by address-significance tables. These sections are
13041424// ineligible for ICF.
13051425template <class ELFT>
1306static void findKeepUniqueSections(opt::InputArgList &Args) {
1307 for (auto *Arg : Args.filtered(OPT_keep_unique)) {
1308 StringRef Name = Arg->getValue();
1309 auto *D = dyn_cast_or_null<Defined>(Symtab->find(Name));
1310 if (!D || !D->Section) {
1311 warn("could not find symbol " + Name + " to keep unique");
1426static void findKeepUniqueSections(opt::InputArgList &args) {
1427 for (auto *arg : args.filtered(OPT_keep_unique)) {
1428 StringRef name = arg->getValue();
1429 auto *d = dyn_cast_or_null<Defined>(symtab->find(name));
1430 if (!d || !d->section) {
1431 warn("could not find symbol " + name + " to keep unique");
13121432 continue;
13131433 }
1314 D->Section->KeepUnique = true;
1434 d->section->keepUnique = true;
13151435 }
13161436
13171437 // --icf=all --ignore-data-address-equality means that we can ignore
13181438 // the dynsym and address-significance tables entirely.
1319 if (Config->ICF == ICFLevel::All && Config->IgnoreDataAddressEquality)
1439 if (config->icf == ICFLevel::All && config->ignoreDataAddressEquality)
13201440 return;
13211441
13221442 // Symbols in the dynsym could be address-significant in other executables
13231443 // or DSOs, so we conservatively mark them as address-significant.
1324 for (Symbol *S : Symtab->getSymbols())
1325 if (S->includeInDynsym())
1326 markAddrsig(S);
1444 symtab->forEachSymbol([&](Symbol *sym) {
1445 if (sym->includeInDynsym())
1446 markAddrsig(sym);
1447 });
13271448
13281449 // Visit the address-significance table in each object file and mark each
13291450 // referenced symbol as address-significant.
1330 for (InputFile *F : ObjectFiles) {
1331 auto *Obj = cast<ObjFile<ELFT>>(F);
1332 ArrayRef<Symbol *> Syms = Obj->getSymbols();
1333 if (Obj->AddrsigSec) {
1334 ArrayRef<uint8_t> Contents =
1335 check(Obj->getObj().getSectionContents(Obj->AddrsigSec));
1336 const uint8_t *Cur = Contents.begin();
1337 while (Cur != Contents.end()) {
1338 unsigned Size;
1339 const char *Err;
1340 uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err);
1341 if (Err)
1342 fatal(toString(F) + ": could not decode addrsig section: " + Err);
1343 markAddrsig(Syms[SymIndex]);
1344 Cur += Size;
1451 for (InputFile *f : objectFiles) {
1452 auto *obj = cast<ObjFile<ELFT>>(f);
1453 ArrayRef<Symbol *> syms = obj->getSymbols();
1454 if (obj->addrsigSec) {
1455 ArrayRef<uint8_t> contents =
1456 check(obj->getObj().getSectionContents(obj->addrsigSec));
1457 const uint8_t *cur = contents.begin();
1458 while (cur != contents.end()) {
1459 unsigned size;
1460 const char *err;
1461 uint64_t symIndex = decodeULEB128(cur, &size, contents.end(), &err);
1462 if (err)
1463 fatal(toString(f) + ": could not decode addrsig section: " + err);
1464 markAddrsig(syms[symIndex]);
1465 cur += size;
13451466 }
13461467 } else {
13471468 // If an object file does not have an address-significance table,
13481469 // conservatively mark all of its symbols as address-significant.
1349 for (Symbol *S : Syms)
1350 markAddrsig(S);
1470 for (Symbol *s : syms)
1471 markAddrsig(s);
1472 }
1473 }
1474}
1475
1476// This function reads a symbol partition specification section. These sections
1477// are used to control which partition a symbol is allocated to. See
1478// https://lld.llvm.org/Partitions.html for more details on partitions.
1479template <typename ELFT>
1480static void readSymbolPartitionSection(InputSectionBase *s) {
1481 // Read the relocation that refers to the partition's entry point symbol.
1482 Symbol *sym;
1483 if (s->areRelocsRela)
1484 sym = &s->getFile<ELFT>()->getRelocTargetSym(s->template relas<ELFT>()[0]);
1485 else
1486 sym = &s->getFile<ELFT>()->getRelocTargetSym(s->template rels<ELFT>()[0]);
1487 if (!isa<Defined>(sym) || !sym->includeInDynsym())
1488 return;
1489
1490 StringRef partName = reinterpret_cast<const char *>(s->data().data());
1491 for (Partition &part : partitions) {
1492 if (part.name == partName) {
1493 sym->partition = part.getNumber();
1494 return;
13511495 }
13521496 }
1497
1498 // Forbid partitions from being used on incompatible targets, and forbid them
1499 // from being used together with various linker features that assume a single
1500 // set of output sections.
1501 if (script->hasSectionsCommand)
1502 error(toString(s->file) +
1503 ": partitions cannot be used with the SECTIONS command");
1504 if (script->hasPhdrsCommands())
1505 error(toString(s->file) +
1506 ": partitions cannot be used with the PHDRS command");
1507 if (!config->sectionStartMap.empty())
1508 error(toString(s->file) + ": partitions cannot be used with "
1509 "--section-start, -Ttext, -Tdata or -Tbss");
1510 if (config->emachine == EM_MIPS)
1511 error(toString(s->file) + ": partitions cannot be used on this target");
1512
1513 // Impose a limit of no more than 254 partitions. This limit comes from the
1514 // sizes of the Partition fields in InputSectionBase and Symbol, as well as
1515 // the amount of space devoted to the partition number in RankFlags.
1516 if (partitions.size() == 254)
1517 fatal("may not have more than 254 partitions");
1518
1519 partitions.emplace_back();
1520 Partition &newPart = partitions.back();
1521 newPart.name = partName;
1522 sym->partition = newPart.getNumber();
13531523}
13541524
1355template <class ELFT> static Symbol *addUndefined(StringRef Name) {
1356 return Symtab->addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, 0, false,
1357 nullptr);
1525static Symbol *addUndefined(StringRef name) {
1526 return symtab->addSymbol(
1527 Undefined{nullptr, name, STB_GLOBAL, STV_DEFAULT, 0});
1528}
1529
1530// This function is where all the optimizations of link-time
1531// optimization takes place. When LTO is in use, some input files are
1532// not in native object file format but in the LLVM bitcode format.
1533// This function compiles bitcode files into a few big native files
1534// using LLVM functions and replaces bitcode symbols with the results.
1535// Because all bitcode files that the program consists of are passed to
1536// the compiler at once, it can do a whole-program optimization.
1537template <class ELFT> void LinkerDriver::compileBitcodeFiles() {
1538 // Compile bitcode files and replace bitcode symbols.
1539 lto.reset(new BitcodeCompiler);
1540 for (BitcodeFile *file : bitcodeFiles)
1541 lto->add(*file);
1542
1543 for (InputFile *file : lto->compile()) {
1544 auto *obj = cast<ObjFile<ELFT>>(file);
1545 obj->parse(/*ignoreComdats=*/true);
1546 for (Symbol *sym : obj->getGlobalSymbols())
1547 sym->parseSymbolVersion();
1548 objectFiles.push_back(file);
1549 }
13581550}
13591551
13601552// The --wrap option is a feature to rename symbols so that you can write
......@@ -1366,9 +1558,9 @@ template <class ELFT> static Symbol *addUndefined(StringRef Name) {
13661558//
13671559// This data structure is instantiated for each -wrap option.
13681560struct WrappedSymbol {
1369 Symbol *Sym;
1370 Symbol *Real;
1371 Symbol *Wrap;
1561 Symbol *sym;
1562 Symbol *real;
1563 Symbol *wrap;
13721564};
13731565
13741566// Handles -wrap option.
......@@ -1376,34 +1568,33 @@ struct WrappedSymbol {
13761568// This function instantiates wrapper symbols. At this point, they seem
13771569// like they are not being used at all, so we explicitly set some flags so
13781570// 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;
1571static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
1572 std::vector<WrappedSymbol> v;
1573 DenseSet<StringRef> seen;
13831574
1384 for (auto *Arg : Args.filtered(OPT_wrap)) {
1385 StringRef Name = Arg->getValue();
1386 if (!Seen.insert(Name).second)
1575 for (auto *arg : args.filtered(OPT_wrap)) {
1576 StringRef name = arg->getValue();
1577 if (!seen.insert(name).second)
13871578 continue;
13881579
1389 Symbol *Sym = Symtab->find(Name);
1390 if (!Sym)
1580 Symbol *sym = symtab->find(name);
1581 if (!sym)
13911582 continue;
13921583
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});
1584 Symbol *real = addUndefined(saver.save("__real_" + name));
1585 Symbol *wrap = addUndefined(saver.save("__wrap_" + name));
1586 v.push_back({sym, real, wrap});
13961587
13971588 // We want to tell LTO not to inline symbols to be overwritten
13981589 // because LTO doesn't know the final symbol contents after renaming.
1399 Real->CanInline = false;
1400 Sym->CanInline = false;
1590 real->canInline = false;
1591 sym->canInline = false;
14011592
14021593 // Tell LTO not to eliminate these symbols.
1403 Sym->IsUsedInRegularObj = true;
1404 Wrap->IsUsedInRegularObj = true;
1594 sym->isUsedInRegularObj = true;
1595 wrap->isUsedInRegularObj = true;
14051596 }
1406 return V;
1597 return v;
14071598}
14081599
14091600// Do renaming for -wrap by updating pointers to symbols.
......@@ -1411,27 +1602,63 @@ static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &Args) {
14111602// When this function is executed, only InputFiles and symbol table
14121603// contain pointers to symbol objects. We visit them to replace pointers,
14131604// 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;
1605static void wrapSymbols(ArrayRef<WrappedSymbol> wrapped) {
1606 DenseMap<Symbol *, Symbol *> map;
1607 for (const WrappedSymbol &w : wrapped) {
1608 map[w.sym] = w.wrap;
1609 map[w.real] = w.sym;
14191610 }
14201611
14211612 // 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;
1613 parallelForEach(objectFiles, [&](InputFile *file) {
1614 MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
1615 for (size_t i = 0, e = syms.size(); i != e; ++i)
1616 if (Symbol *s = map.lookup(syms[i]))
1617 syms[i] = s;
14271618 });
14281619
14291620 // Update pointers in the symbol table.
1430 for (const WrappedSymbol &W : Wrapped)
1431 Symtab->wrap(W.Sym, W.Real, W.Wrap);
1621 for (const WrappedSymbol &w : wrapped)
1622 symtab->wrap(w.sym, w.real, w.wrap);
14321623}
14331624
1434static const char *LibcallRoutineNames[] = {
1625// To enable CET (x86's hardware-assited control flow enforcement), each
1626// source file must be compiled with -fcf-protection. Object files compiled
1627// with the flag contain feature flags indicating that they are compatible
1628// with CET. We enable the feature only when all object files are compatible
1629// with CET.
1630//
1631// This function returns the merged feature flags. If 0, we cannot enable CET.
1632// This is also the case with AARCH64's BTI and PAC which use the similar
1633// GNU_PROPERTY_AARCH64_FEATURE_1_AND mechanism.
1634//
1635// Note that the CET-aware PLT is not implemented yet. We do error
1636// check only.
1637template <class ELFT> static uint32_t getAndFeatures() {
1638 if (config->emachine != EM_386 && config->emachine != EM_X86_64 &&
1639 config->emachine != EM_AARCH64)
1640 return 0;
1641
1642 uint32_t ret = -1;
1643 for (InputFile *f : objectFiles) {
1644 uint32_t features = cast<ObjFile<ELFT>>(f)->andFeatures;
1645 if (config->forceBTI && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
1646 warn(toString(f) + ": --force-bti: file does not have BTI property");
1647 features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
1648 } else if (!features && config->requireCET)
1649 error(toString(f) + ": --require-cet: file is not compatible with CET");
1650 ret &= features;
1651 }
1652
1653 // Force enable pointer authentication Plt, we don't warn in this case as
1654 // this does not require support in the object for correctness.
1655 if (config->pacPlt)
1656 ret |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
1657
1658 return ret;
1659}
1660
1661static const char *libcallRoutineNames[] = {
14351662#define HANDLE_LIBCALL(code, name) name,
14361663#include "llvm/IR/RuntimeLibcalls.def"
14371664#undef HANDLE_LIBCALL
......@@ -1439,53 +1666,48 @@ static const char *LibcallRoutineNames[] = {
14391666
14401667// Do actual linking. Note that when this function is called,
14411668// all linker scripts have already been parsed.
1442template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
1443 Target = getTarget();
1444 InX<ELFT>::VerSym = nullptr;
1445 InX<ELFT>::VerNeed = nullptr;
1446
1447 Config->MaxPageSize = getMaxPageSize(Args);
1448 Config->ImageBase = getImageBase(Args);
1449
1669template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
14501670 // If a -hash-style option was not given, set to a default value,
14511671 // which varies depending on the target.
1452 if (!Args.hasArg(OPT_hash_style)) {
1453 if (Config->EMachine == EM_MIPS)
1454 Config->SysvHash = true;
1672 if (!args.hasArg(OPT_hash_style)) {
1673 if (config->emachine == EM_MIPS)
1674 config->sysvHash = true;
14551675 else
1456 Config->SysvHash = Config->GnuHash = true;
1676 config->sysvHash = config->gnuHash = true;
14571677 }
14581678
14591679 // Default output filename is "a.out" by the Unix tradition.
1460 if (Config->OutputFile.empty())
1461 Config->OutputFile = "a.out";
1680 if (config->outputFile.empty())
1681 config->outputFile = "a.out";
14621682
14631683 // Fail early if the output file or map file is not writable. If a user has a
14641684 // long link, e.g. due to a large LTO link, they do not wish to run it and
14651685 // find that it failed because there was a mistake in their command-line.
1466 if (auto E = tryCreateFile(Config->OutputFile))
1467 error("cannot open output file " + Config->OutputFile + ": " + E.message());
1468 if (auto E = tryCreateFile(Config->MapFile))
1469 error("cannot open map file " + Config->MapFile + ": " + E.message());
1686 if (auto e = tryCreateFile(config->outputFile))
1687 error("cannot open output file " + config->outputFile + ": " + e.message());
1688 if (auto e = tryCreateFile(config->mapFile))
1689 error("cannot open map file " + config->mapFile + ": " + e.message());
14701690 if (errorCount())
14711691 return;
14721692
14731693 // Use default entry point name if no name was given via the command
14741694 // line nor linker scripts. For some reason, MIPS entry point name is
14751695 // different from others.
1476 Config->WarnMissingEntry =
1477 (!Config->Entry.empty() || (!Config->Shared && !Config->Relocatable));
1478 if (Config->Entry.empty() && !Config->Relocatable)
1479 Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";
1696 config->warnMissingEntry =
1697 (!config->entry.empty() || (!config->shared && !config->relocatable));
1698 if (config->entry.empty() && !config->relocatable)
1699 config->entry = (config->emachine == EM_MIPS) ? "__start" : "_start";
14801700
14811701 // Handle --trace-symbol.
1482 for (auto *Arg : Args.filtered(OPT_trace_symbol))
1483 Symtab->trace(Arg->getValue());
1702 for (auto *arg : args.filtered(OPT_trace_symbol))
1703 symtab->insert(arg->getValue())->traced = true;
14841704
14851705 // Add all files to the symbol table. This will add almost all
1486 // symbols that we need to the symbol table.
1487 for (InputFile *F : Files)
1488 Symtab->addFile<ELFT>(F);
1706 // symbols that we need to the symbol table. This process might
1707 // add files to the link, via autolinking, these files are always
1708 // appended to the Files vector.
1709 for (size_t i = 0; i < files.size(); ++i)
1710 parseFile(files[i]);
14891711
14901712 // Now that we have every file, we can decide if we will need a
14911713 // dynamic symbol table.
......@@ -1493,20 +1715,26 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
14931715 // producing a shared library.
14941716 // We also need one if any shared libraries are used and for pie executables
14951717 // (probably because the dynamic linker needs it).
1496 Config->HasDynSymTab =
1497 !SharedFiles.empty() || Config->Pic || Config->ExportDynamic;
1718 config->hasDynSymTab =
1719 !sharedFiles.empty() || config->isPic || config->exportDynamic;
14981720
14991721 // Some symbols (such as __ehdr_start) are defined lazily only when there
15001722 // are undefined symbols for them, so we add these to trigger that logic.
1501 for (StringRef Name : Script->ReferencedSymbols)
1502 addUndefined<ELFT>(Name);
1723 for (StringRef name : script->referencedSymbols)
1724 addUndefined(name);
15031725
15041726 // Handle the `--undefined <sym>` options.
1505 for (StringRef S : Config->Undefined)
1506 handleUndefined<ELFT>(S);
1727 for (StringRef arg : config->undefined)
1728 if (Symbol *sym = symtab->find(arg))
1729 handleUndefined(sym);
15071730
15081731 // If an entry symbol is in a static archive, pull out that file now.
1509 handleUndefined<ELFT>(Config->Entry);
1732 if (Symbol *sym = symtab->find(config->entry))
1733 handleUndefined(sym);
1734
1735 // Handle the `--undefined-glob <pattern>` options.
1736 for (StringRef pat : args::getStrings(args, OPT_undefined_glob))
1737 handleUndefinedGlob(pat);
15101738
15111739 // If any of our inputs are bitcode files, the LTO code generator may create
15121740 // references to certain library functions that might not be explicit in the
......@@ -1525,9 +1753,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
15251753 // to, i.e. if the symbol's definition is in bitcode. Any other required
15261754 // libcall symbols will be added to the link after LTO when we add the LTO
15271755 // object file to the link.
1528 if (!BitcodeFiles.empty())
1529 for (const char *S : LibcallRoutineNames)
1530 handleLibcall<ELFT>(S);
1756 if (!bitcodeFiles.empty())
1757 for (const char *s : libcallRoutineNames)
1758 handleLibcall(s);
15311759
15321760 // Return if there were name resolution errors.
15331761 if (errorCount())
......@@ -1535,27 +1763,27 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
15351763
15361764 // Now when we read all script files, we want to finalize order of linker
15371765 // script commands, which can be not yet final because of INSERT commands.
1538 Script->processInsertCommands();
1766 script->processInsertCommands();
15391767
15401768 // We want to declare linker script's symbols early,
15411769 // so that we can version them.
15421770 // They also might be exported if referenced by DSOs.
1543 Script->declareSymbols();
1771 script->declareSymbols();
15441772
15451773 // Handle the -exclude-libs option.
1546 if (Args.hasArg(OPT_exclude_libs))
1547 excludeLibs<ELFT>(Args);
1774 if (args.hasArg(OPT_exclude_libs))
1775 excludeLibs(args);
15481776
1549 // Create ElfHeader early. We need a dummy section in
1777 // Create elfHeader early. We need a dummy section in
15501778 // addReservedSymbols to mark the created symbols as not absolute.
1551 Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
1552 Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
1779 Out::elfHeader = make<OutputSection>("", 0, SHF_ALLOC);
1780 Out::elfHeader->size = sizeof(typename ELFT::Ehdr);
15531781
15541782 // Create wrapped symbols for -wrap option.
1555 std::vector<WrappedSymbol> Wrapped = addWrappedSymbols<ELFT>(Args);
1783 std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
15561784
15571785 // We need to create some reserved symbols such as _end. Create them.
1558 if (!Config->Relocatable)
1786 if (!config->relocatable)
15591787 addReservedSymbols();
15601788
15611789 // Apply version scripts.
......@@ -1563,84 +1791,118 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
15631791 // For a relocatable output, version scripts don't make sense, and
15641792 // parsing a symbol version string (e.g. dropping "@ver1" from a symbol
15651793 // name "foo@ver1") rather do harm, so we don't call this if -r is given.
1566 if (!Config->Relocatable)
1567 Symtab->scanVersionScript();
1794 if (!config->relocatable)
1795 symtab->scanVersionScript();
15681796
15691797 // Do link-time optimization if given files are LLVM bitcode files.
15701798 // This compiles bitcode files into real object files.
15711799 //
15721800 // With this the symbol table should be complete. After this, no new names
15731801 // except a few linker-synthesized ones will be added to the symbol table.
1574 Symtab->addCombinedLTOObject<ELFT>();
1802 compileBitcodeFiles<ELFT>();
15751803 if (errorCount())
15761804 return;
15771805
15781806 // If -thinlto-index-only is given, we should create only "index
15791807 // files" and not object files. Index file creation is already done
15801808 // in addCombinedLTOObject, so we are done if that's the case.
1581 if (Config->ThinLTOIndexOnly)
1809 if (config->thinLTOIndexOnly)
15821810 return;
15831811
15841812 // Likewise, --plugin-opt=emit-llvm is an option to make LTO create
15851813 // an output file in bitcode and exit, so that you can just get a
15861814 // combined bitcode file.
1587 if (Config->EmitLLVM)
1815 if (config->emitLLVM)
15881816 return;
15891817
15901818 // Apply symbol renames for -wrap.
1591 if (!Wrapped.empty())
1592 wrapSymbols<ELFT>(Wrapped);
1819 if (!wrapped.empty())
1820 wrapSymbols(wrapped);
15931821
15941822 // Now that we have a complete list of input files.
15951823 // Beyond this point, no new files are added.
15961824 // Aggregate all input sections into one place.
1597 for (InputFile *F : ObjectFiles)
1598 for (InputSectionBase *S : F->getSections())
1599 if (S && S != &InputSection::Discarded)
1600 InputSections.push_back(S);
1601 for (BinaryFile *F : BinaryFiles)
1602 for (InputSectionBase *S : F->getSections())
1603 InputSections.push_back(cast<InputSection>(S));
1604
1605 // We do not want to emit debug sections if --strip-all
1606 // or -strip-debug are given.
1607 if (Config->Strip != StripPolicy::None)
1608 llvm::erase_if(InputSections, [](InputSectionBase *S) {
1609 return S->Name.startswith(".debug") || S->Name.startswith(".zdebug");
1610 });
1611
1612 Config->EFlags = Target->calcEFlags();
1613
1614 if (Config->EMachine == EM_ARM) {
1825 for (InputFile *f : objectFiles)
1826 for (InputSectionBase *s : f->getSections())
1827 if (s && s != &InputSection::discarded)
1828 inputSections.push_back(s);
1829 for (BinaryFile *f : binaryFiles)
1830 for (InputSectionBase *s : f->getSections())
1831 inputSections.push_back(cast<InputSection>(s));
1832
1833 llvm::erase_if(inputSections, [](InputSectionBase *s) {
1834 if (s->type == SHT_LLVM_SYMPART) {
1835 readSymbolPartitionSection<ELFT>(s);
1836 return true;
1837 }
1838
1839 // We do not want to emit debug sections if --strip-all
1840 // or -strip-debug are given.
1841 return config->strip != StripPolicy::None &&
1842 (s->name.startswith(".debug") || s->name.startswith(".zdebug"));
1843 });
1844
1845 // Now that the number of partitions is fixed, save a pointer to the main
1846 // partition.
1847 mainPart = &partitions[0];
1848
1849 // Read .note.gnu.property sections from input object files which
1850 // contain a hint to tweak linker's and loader's behaviors.
1851 config->andFeatures = getAndFeatures<ELFT>();
1852
1853 // The Target instance handles target-specific stuff, such as applying
1854 // relocations or writing a PLT section. It also contains target-dependent
1855 // values such as a default image base address.
1856 target = getTarget();
1857
1858 config->eflags = target->calcEFlags();
1859 // maxPageSize (sometimes called abi page size) is the maximum page size that
1860 // the output can be run on. For example if the OS can use 4k or 64k page
1861 // sizes then maxPageSize must be 64k for the output to be useable on both.
1862 // All important alignment decisions must use this value.
1863 config->maxPageSize = getMaxPageSize(args);
1864 // commonPageSize is the most common page size that the output will be run on.
1865 // For example if an OS can use 4k or 64k page sizes and 4k is more common
1866 // than 64k then commonPageSize is set to 4k. commonPageSize can be used for
1867 // optimizations such as DATA_SEGMENT_ALIGN in linker scripts. LLD's use of it
1868 // is limited to writing trap instructions on the last executable segment.
1869 config->commonPageSize = getCommonPageSize(args);
1870
1871 config->imageBase = getImageBase(args);
1872
1873 if (config->emachine == EM_ARM) {
16151874 // FIXME: These warnings can be removed when lld only uses these features
16161875 // when the input objects have been compiled with an architecture that
16171876 // supports them.
1618 if (Config->ARMHasBlx == false)
1877 if (config->armHasBlx == false)
16191878 warn("lld uses blx instruction, no object with architecture supporting "
16201879 "feature detected");
16211880 }
16221881
16231882 // This adds a .comment section containing a version string. We have to add it
16241883 // before mergeSections because the .comment section is a mergeable section.
1625 if (!Config->Relocatable)
1626 InputSections.push_back(createCommentSection());
1884 if (!config->relocatable)
1885 inputSections.push_back(createCommentSection());
1886
1887 // Replace common symbols with regular symbols.
1888 replaceCommonSymbols();
16271889
16281890 // Do size optimizations: garbage collection, merging of SHF_MERGE sections
16291891 // and identical code folding.
16301892 splitSections<ELFT>();
16311893 markLive<ELFT>();
1632 demoteSharedSymbols<ELFT>();
1894 demoteSharedSymbols();
16331895 mergeSections();
1634 if (Config->ICF != ICFLevel::None) {
1635 findKeepUniqueSections<ELFT>(Args);
1896 if (config->icf != ICFLevel::None) {
1897 findKeepUniqueSections<ELFT>(args);
16361898 doIcf<ELFT>();
16371899 }
16381900
16391901 // Read the callgraph now that we know what was gced or icfed
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);
1902 if (config->callGraphProfileSort) {
1903 if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file))
1904 if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
1905 readCallGraph(*buffer);
16441906 readCallGraphsFromObjectFiles<ELFT>();
16451907 }
16461908
deps/lld/ELF/Driver.h+23-19
......@@ -1,15 +1,15 @@
11//===- Driver.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
109#ifndef LLD_ELF_DRIVER_H
1110#define LLD_ELF_DRIVER_H
1211
12#include "LTO.h"
1313#include "SymbolTable.h"
1414#include "lld/Common/LLVM.h"
1515#include "lld/Common/Reproduce.h"
......@@ -22,34 +22,37 @@
2222namespace lld {
2323namespace elf {
2424
25extern class LinkerDriver *Driver;
25extern class LinkerDriver *driver;
2626
2727class LinkerDriver {
2828public:
29 void main(ArrayRef<const char *> Args);
30 void addFile(StringRef Path, bool WithLOption);
31 void addLibrary(StringRef Name);
29 void main(ArrayRef<const char *> args);
30 void addFile(StringRef path, bool withLOption);
31 void addLibrary(StringRef name);
3232
3333private:
34 void readConfigs(llvm::opt::InputArgList &Args);
35 void createFiles(llvm::opt::InputArgList &Args);
34 void createFiles(llvm::opt::InputArgList &args);
3635 void inferMachineType();
37 template <class ELFT> void link(llvm::opt::InputArgList &Args);
36 template <class ELFT> void link(llvm::opt::InputArgList &args);
37 template <class ELFT> void compileBitcodeFiles();
3838
3939 // True if we are in --whole-archive and --no-whole-archive.
40 bool InWholeArchive = false;
40 bool inWholeArchive = false;
4141
4242 // True if we are in --start-lib and --end-lib.
43 bool InLib = false;
43 bool inLib = false;
44
45 // For LTO.
46 std::unique_ptr<BitcodeCompiler> lto;
4447
45 std::vector<InputFile *> Files;
48 std::vector<InputFile *> files;
4649};
4750
4851// Parses command line options.
4952class ELFOptTable : public llvm::opt::OptTable {
5053public:
5154 ELFOptTable();
52 llvm::opt::InputArgList parse(ArrayRef<const char *> Argv);
55 llvm::opt::InputArgList parse(ArrayRef<const char *> argv);
5356};
5457
5558// Create enum with OPT_xxx values for each option in Options.td
......@@ -61,11 +64,12 @@ enum {
6164};
6265
6366void printHelp();
64std::string createResponseFile(const llvm::opt::InputArgList &Args);
67std::string createResponseFile(const llvm::opt::InputArgList &args);
6568
66llvm::Optional<std::string> findFromSearchPaths(StringRef Path);
67llvm::Optional<std::string> searchScript(StringRef Path);
68llvm::Optional<std::string> searchLibrary(StringRef Path);
69llvm::Optional<std::string> findFromSearchPaths(StringRef path);
70llvm::Optional<std::string> searchScript(StringRef path);
71llvm::Optional<std::string> searchLibraryBaseName(StringRef path);
72llvm::Optional<std::string> searchLibrary(StringRef path);
6973
7074} // namespace elf
7175} // namespace lld
deps/lld/ELF/DriverUtils.cpp+105-90
......@@ -1,9 +1,8 @@
11//===- DriverUtils.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -42,7 +41,7 @@ using namespace lld::elf;
4241#undef PREFIX
4342
4443// Create table mapping all options defined in Options.td
45static const opt::OptTable::Info OptInfo[] = {
44static const opt::OptTable::Info optInfo[] = {
4645#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
4746 {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
4847 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
......@@ -50,36 +49,36 @@ static const opt::OptTable::Info OptInfo[] = {
5049#undef OPTION
5150};
5251
53ELFOptTable::ELFOptTable() : OptTable(OptInfo) {}
52ELFOptTable::ELFOptTable() : OptTable(optInfo) {}
5453
5554// Set color diagnostics according to -color-diagnostics={auto,always,never}
5655// or -no-color-diagnostics flags.
57static void handleColorDiagnostics(opt::InputArgList &Args) {
58 auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
56static void handleColorDiagnostics(opt::InputArgList &args) {
57 auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
5958 OPT_no_color_diagnostics);
60 if (!Arg)
59 if (!arg)
6160 return;
62 if (Arg->getOption().getID() == OPT_color_diagnostics) {
63 errorHandler().ColorDiagnostics = true;
64 } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) {
65 errorHandler().ColorDiagnostics = false;
61 if (arg->getOption().getID() == OPT_color_diagnostics) {
62 errorHandler().colorDiagnostics = true;
63 } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
64 errorHandler().colorDiagnostics = false;
6665 } else {
67 StringRef S = Arg->getValue();
68 if (S == "always")
69 errorHandler().ColorDiagnostics = true;
70 else if (S == "never")
71 errorHandler().ColorDiagnostics = false;
72 else if (S != "auto")
73 error("unknown option: --color-diagnostics=" + S);
66 StringRef s = arg->getValue();
67 if (s == "always")
68 errorHandler().colorDiagnostics = true;
69 else if (s == "never")
70 errorHandler().colorDiagnostics = false;
71 else if (s != "auto")
72 error("unknown option: --color-diagnostics=" + s);
7473 }
7574}
7675
77static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
78 if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) {
79 StringRef S = Arg->getValue();
80 if (S != "windows" && S != "posix")
81 error("invalid response file quoting: " + S);
82 if (S == "windows")
76static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &args) {
77 if (auto *arg = args.getLastArg(OPT_rsp_quoting)) {
78 StringRef s = arg->getValue();
79 if (s != "windows" && s != "posix")
80 error("invalid response file quoting: " + s);
81 if (s == "windows")
8382 return cl::TokenizeWindowsCommandLine;
8483 return cl::TokenizeGNUCommandLine;
8584 }
......@@ -97,50 +96,56 @@ static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
9796// `--plugin-opt <foo>` is converted to `--plugin-opt=<foo>`. This is a
9897// bit hacky, but looks like it is still better than handling --plugin-opt
9998// options by hand.
100static void concatLTOPluginOptions(SmallVectorImpl<const char *> &Args) {
101 SmallVector<const char *, 256> V;
102 for (size_t I = 0, E = Args.size(); I != E; ++I) {
103 StringRef S = Args[I];
104 if ((S == "-plugin-opt" || S == "--plugin-opt") && I + 1 != E) {
105 V.push_back(Saver.save(S + "=" + Args[I + 1]).data());
106 ++I;
99static void concatLTOPluginOptions(SmallVectorImpl<const char *> &args) {
100 SmallVector<const char *, 256> v;
101 for (size_t i = 0, e = args.size(); i != e; ++i) {
102 StringRef s = args[i];
103 if ((s == "-plugin-opt" || s == "--plugin-opt") && i + 1 != e) {
104 v.push_back(saver.save(s + "=" + args[i + 1]).data());
105 ++i;
107106 } else {
108 V.push_back(Args[I]);
107 v.push_back(args[i]);
109108 }
110109 }
111 Args = std::move(V);
110 args = std::move(v);
112111}
113112
114113// Parses a given list of options.
115opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) {
114opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> argv) {
116115 // Make InputArgList from string vectors.
117 unsigned MissingIndex;
118 unsigned MissingCount;
119 SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());
116 unsigned missingIndex;
117 unsigned missingCount;
118 SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
120119
121120 // We need to get the quoting style for response files before parsing all
122121 // options so we parse here before and ignore all the options but
123122 // --rsp-quoting.
124 opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
123 opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount);
125124
126125 // Expand response files (arguments in the form of @<filename>)
127126 // and then parse the argument again.
128 cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec);
129 concatLTOPluginOptions(Vec);
130 Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
131
132 handleColorDiagnostics(Args);
133 if (MissingCount)
134 error(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
135
136 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
137 error("unknown argument: " + Arg->getSpelling());
138 return Args;
127 cl::ExpandResponseFiles(saver, getQuotingStyle(args), vec);
128 concatLTOPluginOptions(vec);
129 args = this->ParseArgs(vec, missingIndex, missingCount);
130
131 handleColorDiagnostics(args);
132 if (missingCount)
133 error(Twine(args.getArgString(missingIndex)) + ": missing argument");
134
135 for (auto *arg : args.filtered(OPT_UNKNOWN)) {
136 std::string nearest;
137 if (findNearest(arg->getAsString(args), nearest) > 1)
138 error("unknown argument '" + arg->getAsString(args) + "'");
139 else
140 error("unknown argument '" + arg->getAsString(args) +
141 "', did you mean '" + nearest + "'");
142 }
143 return args;
139144}
140145
141146void elf::printHelp() {
142147 ELFOptTable().PrintHelp(
143 outs(), (Config->ProgName + " [options] file...").str().c_str(), "lld",
148 outs(), (config->progName + " [options] file...").str().c_str(), "lld",
144149 false /*ShowHidden*/, true /*ShowAllAliases*/);
145150 outs() << "\n";
146151
......@@ -149,30 +154,36 @@ void elf::printHelp() {
149154 // in a message for the -help option. If it doesn't match, the scripts
150155 // assume that the linker doesn't support very basic features such as
151156 // shared libraries. Therefore, we need to print out at least "elf".
152 outs() << Config->ProgName << ": supported targets: elf\n";
157 outs() << config->progName << ": supported targets: elf\n";
158}
159
160static std::string rewritePath(StringRef s) {
161 if (fs::exists(s))
162 return relativeToRoot(s);
163 return s;
153164}
154165
155166// Reconstructs command line arguments so that so that you can re-run
156167// the same command with the same inputs. This is for --reproduce.
157std::string elf::createResponseFile(const opt::InputArgList &Args) {
158 SmallString<0> Data;
159 raw_svector_ostream OS(Data);
160 OS << "--chroot .\n";
168std::string elf::createResponseFile(const opt::InputArgList &args) {
169 SmallString<0> data;
170 raw_svector_ostream os(data);
171 os << "--chroot .\n";
161172
162173 // Copy the command line to the output while rewriting paths.
163 for (auto *Arg : Args) {
164 switch (Arg->getOption().getUnaliasedOption().getID()) {
174 for (auto *arg : args) {
175 switch (arg->getOption().getID()) {
165176 case OPT_reproduce:
166177 break;
167178 case OPT_INPUT:
168 OS << quote(rewritePath(Arg->getValue())) << "\n";
179 os << quote(rewritePath(arg->getValue())) << "\n";
169180 break;
170181 case OPT_o:
171182 // If -o path contains directories, "lld @response.txt" will likely
172183 // fail because the archive we are creating doesn't contain empty
173184 // directories for the output path (-o doesn't create directories).
174185 // Strip directories to prevent the issue.
175 OS << "-o " << quote(sys::path::filename(Arg->getValue())) << "\n";
186 os << "-o " << quote(sys::path::filename(arg->getValue())) << "\n";
176187 break;
177188 case OPT_dynamic_list:
178189 case OPT_library_path:
......@@ -181,58 +192,62 @@ std::string elf::createResponseFile(const opt::InputArgList &Args) {
181192 case OPT_symbol_ordering_file:
182193 case OPT_sysroot:
183194 case OPT_version_script:
184 OS << Arg->getSpelling() << " " << quote(rewritePath(Arg->getValue()))
195 os << arg->getSpelling() << " " << quote(rewritePath(arg->getValue()))
185196 << "\n";
186197 break;
187198 default:
188 OS << toString(*Arg) << "\n";
199 os << toString(*arg) << "\n";
189200 }
190201 }
191 return Data.str();
202 return data.str();
192203}
193204
194205// Find a file by concatenating given paths. If a resulting path
195206// starts with "=", the character is replaced with a --sysroot value.
196static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
197 SmallString<128> S;
198 if (Path1.startswith("="))
199 path::append(S, Config->Sysroot, Path1.substr(1), Path2);
207static Optional<std::string> findFile(StringRef path1, const Twine &path2) {
208 SmallString<128> s;
209 if (path1.startswith("="))
210 path::append(s, config->sysroot, path1.substr(1), path2);
200211 else
201 path::append(S, Path1, Path2);
212 path::append(s, path1, path2);
202213
203 if (fs::exists(S))
204 return S.str().str();
214 if (fs::exists(s))
215 return s.str().str();
205216 return None;
206217}
207218
208Optional<std::string> elf::findFromSearchPaths(StringRef Path) {
209 for (StringRef Dir : Config->SearchPaths)
210 if (Optional<std::string> S = findFile(Dir, Path))
211 return S;
219Optional<std::string> elf::findFromSearchPaths(StringRef path) {
220 for (StringRef dir : config->searchPaths)
221 if (Optional<std::string> s = findFile(dir, path))
222 return s;
212223 return None;
213224}
214225
215// This is for -lfoo. We'll look for libfoo.so or libfoo.a from
226// This is for -l<basename>. We'll look for lib<basename>.so or lib<basename>.a from
216227// search paths.
217Optional<std::string> elf::searchLibrary(StringRef Name) {
218 if (Name.startswith(":"))
219 return findFromSearchPaths(Name.substr(1));
220
221 for (StringRef Dir : Config->SearchPaths) {
222 if (!Config->Static)
223 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".so"))
224 return S;
225 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a"))
226 return S;
228Optional<std::string> elf::searchLibraryBaseName(StringRef name) {
229 for (StringRef dir : config->searchPaths) {
230 if (!config->isStatic)
231 if (Optional<std::string> s = findFile(dir, "lib" + name + ".so"))
232 return s;
233 if (Optional<std::string> s = findFile(dir, "lib" + name + ".a"))
234 return s;
227235 }
228236 return None;
229237}
230238
239// This is for -l<namespec>.
240Optional<std::string> elf::searchLibrary(StringRef name) {
241 if (name.startswith(":"))
242 return findFromSearchPaths(name.substr(1));
243 return searchLibraryBaseName (name);
244}
245
231246// If a linker/version script doesn't exist in the current directory, we also
232247// look for the script in the '-L' search paths. This matches the behaviour of
233248// '-T', --version-script=, and linker script INPUT() command in ld.bfd.
234Optional<std::string> elf::searchScript(StringRef Name) {
235 if (fs::exists(Name))
236 return Name.str();
237 return findFromSearchPaths(Name);
249Optional<std::string> elf::searchScript(StringRef name) {
250 if (fs::exists(name))
251 return name.str();
252 return findFromSearchPaths(name);
238253}
deps/lld/ELF/EhFrame.cpp+68-69
......@@ -1,9 +1,8 @@
11//===- EhFrame.cpp -------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -37,72 +36,72 @@ using namespace lld::elf;
3736namespace {
3837class EhReader {
3938public:
40 EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {}
39 EhReader(InputSectionBase *s, ArrayRef<uint8_t> d) : isec(s), d(d) {}
4140 size_t readEhRecordSize();
4241 uint8_t getFdeEncoding();
4342
4443private:
45 template <class P> void failOn(const P *Loc, const Twine &Msg) {
46 fatal("corrupted .eh_frame: " + Msg + "\n>>> defined in " +
47 IS->getObjMsg((const uint8_t *)Loc - IS->data().data()));
44 template <class P> void failOn(const P *loc, const Twine &msg) {
45 fatal("corrupted .eh_frame: " + msg + "\n>>> defined in " +
46 isec->getObjMsg((const uint8_t *)loc - isec->data().data()));
4847 }
4948
5049 uint8_t readByte();
51 void skipBytes(size_t Count);
50 void skipBytes(size_t count);
5251 StringRef readString();
5352 void skipLeb128();
5453 void skipAugP();
5554
56 InputSectionBase *IS;
57 ArrayRef<uint8_t> D;
55 InputSectionBase *isec;
56 ArrayRef<uint8_t> d;
5857};
5958}
6059
61size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
62 return EhReader(S, S->data().slice(Off)).readEhRecordSize();
60size_t elf::readEhRecordSize(InputSectionBase *s, size_t off) {
61 return EhReader(s, s->data().slice(off)).readEhRecordSize();
6362}
6463
6564// .eh_frame section is a sequence of records. Each record starts with
6665// a 4 byte length field. This function reads the length.
6766size_t EhReader::readEhRecordSize() {
68 if (D.size() < 4)
69 failOn(D.data(), "CIE/FDE too small");
67 if (d.size() < 4)
68 failOn(d.data(), "CIE/FDE too small");
7069
7170 // First 4 bytes of CIE/FDE is the size of the record.
7271 // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
7372 // but we do not support that format yet.
74 uint64_t V = read32(D.data());
75 if (V == UINT32_MAX)
76 failOn(D.data(), "CIE/FDE too large");
77 uint64_t Size = V + 4;
78 if (Size > D.size())
79 failOn(D.data(), "CIE/FDE ends past the end of the section");
80 return Size;
73 uint64_t v = read32(d.data());
74 if (v == UINT32_MAX)
75 failOn(d.data(), "CIE/FDE too large");
76 uint64_t size = v + 4;
77 if (size > d.size())
78 failOn(d.data(), "CIE/FDE ends past the end of the section");
79 return size;
8180}
8281
8382// Read a byte and advance D by one byte.
8483uint8_t EhReader::readByte() {
85 if (D.empty())
86 failOn(D.data(), "unexpected end of CIE");
87 uint8_t B = D.front();
88 D = D.slice(1);
89 return B;
84 if (d.empty())
85 failOn(d.data(), "unexpected end of CIE");
86 uint8_t b = d.front();
87 d = d.slice(1);
88 return b;
9089}
9190
92void EhReader::skipBytes(size_t Count) {
93 if (D.size() < Count)
94 failOn(D.data(), "CIE is too small");
95 D = D.slice(Count);
91void EhReader::skipBytes(size_t count) {
92 if (d.size() < count)
93 failOn(d.data(), "CIE is too small");
94 d = d.slice(count);
9695}
9796
9897// Read a null-terminated string.
9998StringRef EhReader::readString() {
100 const uint8_t *End = std::find(D.begin(), D.end(), '\0');
101 if (End == D.end())
102 failOn(D.data(), "corrupted CIE (failed to read string)");
103 StringRef S = toStringRef(D.slice(0, End - D.begin()));
104 D = D.slice(S.size() + 1);
105 return S;
99 const uint8_t *end = llvm::find(d, '\0');
100 if (end == d.end())
101 failOn(d.data(), "corrupted CIE (failed to read string)");
102 StringRef s = toStringRef(d.slice(0, end - d.begin()));
103 d = d.slice(s.size() + 1);
104 return s;
106105}
107106
108107// Skip an integer encoded in the LEB128 format.
......@@ -110,21 +109,21 @@ StringRef EhReader::readString() {
110109// But we need to be at least able to skip it so that we can read
111110// the field that follows a LEB128 number.
112111void EhReader::skipLeb128() {
113 const uint8_t *ErrPos = D.data();
114 while (!D.empty()) {
115 uint8_t Val = D.front();
116 D = D.slice(1);
117 if ((Val & 0x80) == 0)
112 const uint8_t *errPos = d.data();
113 while (!d.empty()) {
114 uint8_t val = d.front();
115 d = d.slice(1);
116 if ((val & 0x80) == 0)
118117 return;
119118 }
120 failOn(ErrPos, "corrupted CIE (failed to read LEB128)");
119 failOn(errPos, "corrupted CIE (failed to read LEB128)");
121120}
122121
123static size_t getAugPSize(unsigned Enc) {
124 switch (Enc & 0x0f) {
122static size_t getAugPSize(unsigned enc) {
123 switch (enc & 0x0f) {
125124 case DW_EH_PE_absptr:
126125 case DW_EH_PE_signed:
127 return Config->Wordsize;
126 return config->wordsize;
128127 case DW_EH_PE_udata2:
129128 case DW_EH_PE_sdata2:
130129 return 2;
......@@ -139,29 +138,29 @@ static size_t getAugPSize(unsigned Enc) {
139138}
140139
141140void EhReader::skipAugP() {
142 uint8_t Enc = readByte();
143 if ((Enc & 0xf0) == DW_EH_PE_aligned)
144 failOn(D.data() - 1, "DW_EH_PE_aligned encoding is not supported");
145 size_t Size = getAugPSize(Enc);
146 if (Size == 0)
147 failOn(D.data() - 1, "unknown FDE encoding");
148 if (Size >= D.size())
149 failOn(D.data() - 1, "corrupted CIE");
150 D = D.slice(Size);
141 uint8_t enc = readByte();
142 if ((enc & 0xf0) == DW_EH_PE_aligned)
143 failOn(d.data() - 1, "DW_EH_PE_aligned encoding is not supported");
144 size_t size = getAugPSize(enc);
145 if (size == 0)
146 failOn(d.data() - 1, "unknown FDE encoding");
147 if (size >= d.size())
148 failOn(d.data() - 1, "corrupted CIE");
149 d = d.slice(size);
151150}
152151
153uint8_t elf::getFdeEncoding(EhSectionPiece *P) {
154 return EhReader(P->Sec, P->data()).getFdeEncoding();
152uint8_t elf::getFdeEncoding(EhSectionPiece *p) {
153 return EhReader(p->sec, p->data()).getFdeEncoding();
155154}
156155
157156uint8_t EhReader::getFdeEncoding() {
158157 skipBytes(8);
159 int Version = readByte();
160 if (Version != 1 && Version != 3)
161 failOn(D.data() - 1,
162 "FDE version 1 or 3 expected, but got " + Twine(Version));
158 int version = readByte();
159 if (version != 1 && version != 3)
160 failOn(d.data() - 1,
161 "FDE version 1 or 3 expected, but got " + Twine(version));
163162
164 StringRef Aug = readString();
163 StringRef aug = readString();
165164
166165 // Skip code and data alignment factors.
167166 skipLeb128();
......@@ -169,7 +168,7 @@ uint8_t EhReader::getFdeEncoding() {
169168
170169 // Skip the return address register. In CIE version 1 this is a single
171170 // byte. In CIE version 3 this is an unsigned LEB128.
172 if (Version == 1)
171 if (version == 1)
173172 readByte();
174173 else
175174 skipLeb128();
......@@ -177,22 +176,22 @@ uint8_t EhReader::getFdeEncoding() {
177176 // We only care about an 'R' value, but other records may precede an 'R'
178177 // record. Unfortunately records are not in TLV (type-length-value) format,
179178 // so we need to teach the linker how to skip records for each type.
180 for (char C : Aug) {
181 if (C == 'R')
179 for (char c : aug) {
180 if (c == 'R')
182181 return readByte();
183 if (C == 'z') {
182 if (c == 'z') {
184183 skipLeb128();
185184 continue;
186185 }
187 if (C == 'P') {
186 if (c == 'P') {
188187 skipAugP();
189188 continue;
190189 }
191 if (C == 'L') {
190 if (c == 'L') {
192191 readByte();
193192 continue;
194193 }
195 failOn(Aug.data(), "unknown .eh_frame augmentation string: " + Aug);
194 failOn(aug.data(), "unknown .eh_frame augmentation string: " + aug);
196195 }
197196 return DW_EH_PE_absptr;
198197}
deps/lld/ELF/EhFrame.h+5-6
......@@ -1,9 +1,8 @@
11//===- EhFrame.h ------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -17,8 +16,8 @@ namespace elf {
1716class InputSectionBase;
1817struct EhSectionPiece;
1918
20size_t readEhRecordSize(InputSectionBase *S, size_t Off);
21uint8_t getFdeEncoding(EhSectionPiece *P);
19size_t readEhRecordSize(InputSectionBase *s, size_t off);
20uint8_t getFdeEncoding(EhSectionPiece *p);
2221} // namespace elf
2322} // namespace lld
2423
deps/lld/ELF/Filesystem.cpp deleted-86
......@@ -1,86 +0,0 @@
1//===- Filesystem.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// This file contains a few utility functions to handle files.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Filesystem.h"
15#include "Config.h"
16#include "lld/Common/Threads.h"
17#include "llvm/Config/llvm-config.h"
18#include "llvm/Support/FileOutputBuffer.h"
19#include "llvm/Support/FileSystem.h"
20#if LLVM_ON_UNIX
21#include <unistd.h>
22#endif
23#include <thread>
24
25using namespace llvm;
26
27using namespace lld;
28using namespace lld::elf;
29
30// Removes a given file asynchronously. This is a performance hack,
31// so remove this when operating systems are improved.
32//
33// On Linux (and probably on other Unix-like systems), unlink(2) is a
34// noticeably slow system call. As of 2016, unlink takes 250
35// milliseconds to remove a 1 GB file on ext4 filesystem on my machine.
36//
37// To create a new result file, we first remove existing file. So, if
38// you repeatedly link a 1 GB program in a regular compile-link-debug
39// cycle, every cycle wastes 250 milliseconds only to remove a file.
40// Since LLD can link a 1 GB binary in about 5 seconds, that waste
41// actually counts.
42//
43// This function spawns a background thread to remove the file.
44// The calling thread returns almost immediately.
45void elf::unlinkAsync(StringRef Path) {
46// Removing a file is async on windows.
47#if defined(_WIN32)
48 sys::fs::remove(Path);
49#else
50 if (!ThreadsEnabled || !sys::fs::exists(Path) ||
51 !sys::fs::is_regular_file(Path))
52 return;
53
54 // We cannot just remove path from a different thread because we are now going
55 // to create path as a new file.
56 // Instead we open the file and unlink it on this thread. The unlink is fast
57 // since the open fd guarantees that it is not removing the last reference.
58 int FD;
59 std::error_code EC = sys::fs::openFileForRead(Path, FD);
60 sys::fs::remove(Path);
61
62 // close and therefore remove TempPath in background.
63 if (!EC)
64 std::thread([=] { ::close(FD); }).detach();
65#endif
66}
67
68// Simulate file creation to see if Path is writable.
69//
70// Determining whether a file is writable or not is amazingly hard,
71// and after all the only reliable way of doing that is to actually
72// create a file. But we don't want to do that in this function
73// because LLD shouldn't update any file if it will end in a failure.
74// We also don't want to reimplement heuristics to determine if a
75// file is writable. So we'll let FileOutputBuffer do the work.
76//
77// FileOutputBuffer doesn't touch a desitnation file until commit()
78// is called. We use that class without calling commit() to predict
79// if the given file is writable.
80std::error_code elf::tryCreateFile(StringRef Path) {
81 if (Path.empty())
82 return std::error_code();
83 if (Path == "-")
84 return std::error_code();
85 return errorToErrorCode(FileOutputBuffer::create(Path, 1).takeError());
86}
deps/lld/ELF/Filesystem.h deleted-23
......@@ -1,23 +0,0 @@
1//===- Filesystem.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_FILESYSTEM_H
11#define LLD_ELF_FILESYSTEM_H
12
13#include "lld/Common/LLVM.h"
14#include <system_error>
15
16namespace lld {
17namespace elf {
18void unlinkAsync(StringRef Path);
19std::error_code tryCreateFile(StringRef Path);
20} // namespace elf
21} // namespace lld
22
23#endif
deps/lld/ELF/ICF.cpp+166-168
......@@ -1,9 +1,8 @@
11//===- ICF.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -99,33 +98,33 @@ public:
9998 void run();
10099
101100private:
102 void segregate(size_t Begin, size_t End, bool Constant);
101 void segregate(size_t begin, size_t end, bool constant);
103102
104103 template <class RelTy>
105 bool constantEq(const InputSection *A, ArrayRef<RelTy> RelsA,
106 const InputSection *B, ArrayRef<RelTy> RelsB);
104 bool constantEq(const InputSection *a, ArrayRef<RelTy> relsA,
105 const InputSection *b, ArrayRef<RelTy> relsB);
107106
108107 template <class RelTy>
109 bool variableEq(const InputSection *A, ArrayRef<RelTy> RelsA,
110 const InputSection *B, ArrayRef<RelTy> RelsB);
108 bool variableEq(const InputSection *a, ArrayRef<RelTy> relsA,
109 const InputSection *b, ArrayRef<RelTy> relsB);
111110
112 bool equalsConstant(const InputSection *A, const InputSection *B);
113 bool equalsVariable(const InputSection *A, const InputSection *B);
111 bool equalsConstant(const InputSection *a, const InputSection *b);
112 bool equalsVariable(const InputSection *a, const InputSection *b);
114113
115 size_t findBoundary(size_t Begin, size_t End);
114 size_t findBoundary(size_t begin, size_t end);
116115
117 void forEachClassRange(size_t Begin, size_t End,
118 llvm::function_ref<void(size_t, size_t)> Fn);
116 void forEachClassRange(size_t begin, size_t end,
117 llvm::function_ref<void(size_t, size_t)> fn);
119118
120 void forEachClass(llvm::function_ref<void(size_t, size_t)> Fn);
119 void forEachClass(llvm::function_ref<void(size_t, size_t)> fn);
121120
122 std::vector<InputSection *> Sections;
121 std::vector<InputSection *> sections;
123122
124123 // We repeat the main loop while `Repeat` is true.
125 std::atomic<bool> Repeat;
124 std::atomic<bool> repeat;
126125
127126 // The main loop counter.
128 int Cnt = 0;
127 int cnt = 0;
129128
130129 // We have two locations for equivalence classes. On the first iteration
131130 // of the main loop, Class[0] has a valid value, and Class[1] contains
......@@ -151,42 +150,42 @@ private:
151150 // because we can safely read the next class without worrying about race
152151 // conditions. Using the same location makes this algorithm converge
153152 // faster because it uses results of the same iteration earlier.
154 int Current = 0;
155 int Next = 0;
153 int current = 0;
154 int next = 0;
156155};
157156}
158157
159158// Returns true if section S is subject of ICF.
160static bool isEligible(InputSection *S) {
161 if (!S->Live || S->KeepUnique || !(S->Flags & SHF_ALLOC))
159static bool isEligible(InputSection *s) {
160 if (!s->isLive() || s->keepUnique || !(s->flags & SHF_ALLOC))
162161 return false;
163162
164163 // Don't merge writable sections. .data.rel.ro sections are marked as writable
165164 // but are semantically read-only.
166 if ((S->Flags & SHF_WRITE) && S->Name != ".data.rel.ro" &&
167 !S->Name.startswith(".data.rel.ro."))
165 if ((s->flags & SHF_WRITE) && s->name != ".data.rel.ro" &&
166 !s->name.startswith(".data.rel.ro."))
168167 return false;
169168
170169 // SHF_LINK_ORDER sections are ICF'd as a unit with their dependent sections,
171170 // so we don't consider them for ICF individually.
172 if (S->Flags & SHF_LINK_ORDER)
171 if (s->flags & SHF_LINK_ORDER)
173172 return false;
174173
175174 // Don't merge synthetic sections as their Data member is not valid and empty.
176175 // The Data member needs to be valid for ICF as it is used by ICF to determine
177176 // the equality of section contents.
178 if (isa<SyntheticSection>(S))
177 if (isa<SyntheticSection>(s))
179178 return false;
180179
181180 // .init and .fini contains instructions that must be executed to initialize
182181 // and finalize the process. They cannot and should not be merged.
183 if (S->Name == ".init" || S->Name == ".fini")
182 if (s->name == ".init" || s->name == ".fini")
184183 return false;
185184
186185 // A user program may enumerate sections named with a C identifier using
187186 // __start_* and __stop_* symbols. We cannot ICF any such sections because
188187 // that could change program semantics.
189 if (isValidCIdentifier(S->Name))
188 if (isValidCIdentifier(s->name))
190189 return false;
191190
192191 return true;
......@@ -194,7 +193,7 @@ static bool isEligible(InputSection *S) {
194193
195194// Split an equivalence class into smaller classes.
196195template <class ELFT>
197void ICF<ELFT>::segregate(size_t Begin, size_t End, bool Constant) {
196void ICF<ELFT>::segregate(size_t begin, size_t end, bool constant) {
198197 // This loop rearranges sections in [Begin, End) so that all sections
199198 // that are equal in terms of equals{Constant,Variable} are contiguous
200199 // in [Begin, End).
......@@ -203,93 +202,93 @@ void ICF<ELFT>::segregate(size_t Begin, size_t End, bool Constant) {
203202 // issue in practice because the number of the distinct sections in
204203 // each range is usually very small.
205204
206 while (Begin < End) {
205 while (begin < end) {
207206 // Divide [Begin, End) into two. Let Mid be the start index of the
208207 // second group.
209 auto Bound =
210 std::stable_partition(Sections.begin() + Begin + 1,
211 Sections.begin() + End, [&](InputSection *S) {
212 if (Constant)
213 return equalsConstant(Sections[Begin], S);
214 return equalsVariable(Sections[Begin], S);
208 auto bound =
209 std::stable_partition(sections.begin() + begin + 1,
210 sections.begin() + end, [&](InputSection *s) {
211 if (constant)
212 return equalsConstant(sections[begin], s);
213 return equalsVariable(sections[begin], s);
215214 });
216 size_t Mid = Bound - Sections.begin();
215 size_t mid = bound - sections.begin();
217216
218217 // Now we split [Begin, End) into [Begin, Mid) and [Mid, End) by
219218 // updating the sections in [Begin, Mid). We use Mid as an equivalence
220219 // class ID because every group ends with a unique index.
221 for (size_t I = Begin; I < Mid; ++I)
222 Sections[I]->Class[Next] = Mid;
220 for (size_t i = begin; i < mid; ++i)
221 sections[i]->eqClass[next] = mid;
223222
224223 // If we created a group, we need to iterate the main loop again.
225 if (Mid != End)
226 Repeat = true;
224 if (mid != end)
225 repeat = true;
227226
228 Begin = Mid;
227 begin = mid;
229228 }
230229}
231230
232231// Compare two lists of relocations.
233232template <class ELFT>
234233template <class RelTy>
235bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
236 const InputSection *SecB, ArrayRef<RelTy> RB) {
237 for (size_t I = 0; I < RA.size(); ++I) {
238 if (RA[I].r_offset != RB[I].r_offset ||
239 RA[I].getType(Config->IsMips64EL) != RB[I].getType(Config->IsMips64EL))
234bool ICF<ELFT>::constantEq(const InputSection *secA, ArrayRef<RelTy> ra,
235 const InputSection *secB, ArrayRef<RelTy> rb) {
236 for (size_t i = 0; i < ra.size(); ++i) {
237 if (ra[i].r_offset != rb[i].r_offset ||
238 ra[i].getType(config->isMips64EL) != rb[i].getType(config->isMips64EL))
240239 return false;
241240
242 uint64_t AddA = getAddend<ELFT>(RA[I]);
243 uint64_t AddB = getAddend<ELFT>(RB[I]);
241 uint64_t addA = getAddend<ELFT>(ra[i]);
242 uint64_t addB = getAddend<ELFT>(rb[i]);
244243
245 Symbol &SA = SecA->template getFile<ELFT>()->getRelocTargetSym(RA[I]);
246 Symbol &SB = SecB->template getFile<ELFT>()->getRelocTargetSym(RB[I]);
247 if (&SA == &SB) {
248 if (AddA == AddB)
244 Symbol &sa = secA->template getFile<ELFT>()->getRelocTargetSym(ra[i]);
245 Symbol &sb = secB->template getFile<ELFT>()->getRelocTargetSym(rb[i]);
246 if (&sa == &sb) {
247 if (addA == addB)
249248 continue;
250249 return false;
251250 }
252251
253 auto *DA = dyn_cast<Defined>(&SA);
254 auto *DB = dyn_cast<Defined>(&SB);
252 auto *da = dyn_cast<Defined>(&sa);
253 auto *db = dyn_cast<Defined>(&sb);
255254
256255 // Placeholder symbols generated by linker scripts look the same now but
257256 // may have different values later.
258 if (!DA || !DB || DA->ScriptDefined || DB->ScriptDefined)
257 if (!da || !db || da->scriptDefined || db->scriptDefined)
259258 return false;
260259
261260 // Relocations referring to absolute symbols are constant-equal if their
262261 // values are equal.
263 if (!DA->Section && !DB->Section && DA->Value + AddA == DB->Value + AddB)
262 if (!da->section && !db->section && da->value + addA == db->value + addB)
264263 continue;
265 if (!DA->Section || !DB->Section)
264 if (!da->section || !db->section)
266265 return false;
267266
268 if (DA->Section->kind() != DB->Section->kind())
267 if (da->section->kind() != db->section->kind())
269268 return false;
270269
271270 // Relocations referring to InputSections are constant-equal if their
272271 // section offsets are equal.
273 if (isa<InputSection>(DA->Section)) {
274 if (DA->Value + AddA == DB->Value + AddB)
272 if (isa<InputSection>(da->section)) {
273 if (da->value + addA == db->value + addB)
275274 continue;
276275 return false;
277276 }
278277
279278 // Relocations referring to MergeInputSections are constant-equal if their
280279 // offsets in the output section are equal.
281 auto *X = dyn_cast<MergeInputSection>(DA->Section);
282 if (!X)
280 auto *x = dyn_cast<MergeInputSection>(da->section);
281 if (!x)
283282 return false;
284 auto *Y = cast<MergeInputSection>(DB->Section);
285 if (X->getParent() != Y->getParent())
283 auto *y = cast<MergeInputSection>(db->section);
284 if (x->getParent() != y->getParent())
286285 return false;
287286
288 uint64_t OffsetA =
289 SA.isSection() ? X->getOffset(AddA) : X->getOffset(DA->Value) + AddA;
290 uint64_t OffsetB =
291 SB.isSection() ? Y->getOffset(AddB) : Y->getOffset(DB->Value) + AddB;
292 if (OffsetA != OffsetB)
287 uint64_t offsetA =
288 sa.isSection() ? x->getOffset(addA) : x->getOffset(da->value) + addA;
289 uint64_t offsetB =
290 sb.isSection() ? y->getOffset(addB) : y->getOffset(db->value) + addB;
291 if (offsetA != offsetB)
293292 return false;
294293 }
295294
......@@ -299,57 +298,57 @@ bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
299298// Compare "non-moving" part of two InputSections, namely everything
300299// except relocation targets.
301300template <class ELFT>
302bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {
303 if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags ||
304 A->getSize() != B->getSize() || A->data() != B->data())
301bool ICF<ELFT>::equalsConstant(const InputSection *a, const InputSection *b) {
302 if (a->numRelocations != b->numRelocations || a->flags != b->flags ||
303 a->getSize() != b->getSize() || a->data() != b->data())
305304 return false;
306305
307306 // If two sections have different output sections, we cannot merge them.
308307 // FIXME: This doesn't do the right thing in the case where there is a linker
309308 // script. We probably need to move output section assignment before ICF to
310309 // get the correct behaviour here.
311 if (getOutputSectionName(A) != getOutputSectionName(B))
310 if (getOutputSectionName(a) != getOutputSectionName(b))
312311 return false;
313312
314 if (A->AreRelocsRela)
315 return constantEq(A, A->template relas<ELFT>(), B,
316 B->template relas<ELFT>());
317 return constantEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
313 if (a->areRelocsRela)
314 return constantEq(a, a->template relas<ELFT>(), b,
315 b->template relas<ELFT>());
316 return constantEq(a, a->template rels<ELFT>(), b, b->template rels<ELFT>());
318317}
319318
320319// Compare two lists of relocations. Returns true if all pairs of
321320// relocations point to the same section in terms of ICF.
322321template <class ELFT>
323322template <class RelTy>
324bool ICF<ELFT>::variableEq(const InputSection *SecA, ArrayRef<RelTy> RA,
325 const InputSection *SecB, ArrayRef<RelTy> RB) {
326 assert(RA.size() == RB.size());
323bool ICF<ELFT>::variableEq(const InputSection *secA, ArrayRef<RelTy> ra,
324 const InputSection *secB, ArrayRef<RelTy> rb) {
325 assert(ra.size() == rb.size());
327326
328 for (size_t I = 0; I < RA.size(); ++I) {
327 for (size_t i = 0; i < ra.size(); ++i) {
329328 // The two sections must be identical.
330 Symbol &SA = SecA->template getFile<ELFT>()->getRelocTargetSym(RA[I]);
331 Symbol &SB = SecB->template getFile<ELFT>()->getRelocTargetSym(RB[I]);
332 if (&SA == &SB)
329 Symbol &sa = secA->template getFile<ELFT>()->getRelocTargetSym(ra[i]);
330 Symbol &sb = secB->template getFile<ELFT>()->getRelocTargetSym(rb[i]);
331 if (&sa == &sb)
333332 continue;
334333
335 auto *DA = cast<Defined>(&SA);
336 auto *DB = cast<Defined>(&SB);
334 auto *da = cast<Defined>(&sa);
335 auto *db = cast<Defined>(&sb);
337336
338337 // We already dealt with absolute and non-InputSection symbols in
339338 // constantEq, and for InputSections we have already checked everything
340339 // except the equivalence class.
341 if (!DA->Section)
340 if (!da->section)
342341 continue;
343 auto *X = dyn_cast<InputSection>(DA->Section);
344 if (!X)
342 auto *x = dyn_cast<InputSection>(da->section);
343 if (!x)
345344 continue;
346 auto *Y = cast<InputSection>(DB->Section);
345 auto *y = cast<InputSection>(db->section);
347346
348347 // Ineligible sections are in the special equivalence class 0.
349348 // They can never be the same in terms of the equivalence class.
350 if (X->Class[Current] == 0)
349 if (x->eqClass[current] == 0)
351350 return false;
352 if (X->Class[Current] != Y->Class[Current])
351 if (x->eqClass[current] != y->eqClass[current])
353352 return false;
354353 };
355354
......@@ -358,19 +357,19 @@ bool ICF<ELFT>::variableEq(const InputSection *SecA, ArrayRef<RelTy> RA,
358357
359358// Compare "moving" part of two InputSections, namely relocation targets.
360359template <class ELFT>
361bool ICF<ELFT>::equalsVariable(const InputSection *A, const InputSection *B) {
362 if (A->AreRelocsRela)
363 return variableEq(A, A->template relas<ELFT>(), B,
364 B->template relas<ELFT>());
365 return variableEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
360bool ICF<ELFT>::equalsVariable(const InputSection *a, const InputSection *b) {
361 if (a->areRelocsRela)
362 return variableEq(a, a->template relas<ELFT>(), b,
363 b->template relas<ELFT>());
364 return variableEq(a, a->template rels<ELFT>(), b, b->template rels<ELFT>());
366365}
367366
368template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) {
369 uint32_t Class = Sections[Begin]->Class[Current];
370 for (size_t I = Begin + 1; I < End; ++I)
371 if (Class != Sections[I]->Class[Current])
372 return I;
373 return End;
367template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t begin, size_t end) {
368 uint32_t eqClass = sections[begin]->eqClass[current];
369 for (size_t i = begin + 1; i < end; ++i)
370 if (eqClass != sections[i]->eqClass[current])
371 return i;
372 return end;
374373}
375374
376375// Sections in the same equivalence class are contiguous in Sections
......@@ -379,126 +378,125 @@ template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) {
379378//
380379// This function calls Fn on every group within [Begin, End).
381380template <class ELFT>
382void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End,
383 llvm::function_ref<void(size_t, size_t)> Fn) {
384 while (Begin < End) {
385 size_t Mid = findBoundary(Begin, End);
386 Fn(Begin, Mid);
387 Begin = Mid;
381void ICF<ELFT>::forEachClassRange(size_t begin, size_t end,
382 llvm::function_ref<void(size_t, size_t)> fn) {
383 while (begin < end) {
384 size_t mid = findBoundary(begin, end);
385 fn(begin, mid);
386 begin = mid;
388387 }
389388}
390389
391390// Call Fn on each equivalence class.
392391template <class ELFT>
393void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> Fn) {
392void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> fn) {
394393 // If threading is disabled or the number of sections are
395394 // too small to use threading, call Fn sequentially.
396 if (!ThreadsEnabled || Sections.size() < 1024) {
397 forEachClassRange(0, Sections.size(), Fn);
398 ++Cnt;
395 if (!threadsEnabled || sections.size() < 1024) {
396 forEachClassRange(0, sections.size(), fn);
397 ++cnt;
399398 return;
400399 }
401400
402 Current = Cnt % 2;
403 Next = (Cnt + 1) % 2;
401 current = cnt % 2;
402 next = (cnt + 1) % 2;
404403
405404 // Shard into non-overlapping intervals, and call Fn in parallel.
406405 // The sharding must be completed before any calls to Fn are made
407406 // so that Fn can modify the Chunks in its shard without causing data
408407 // races.
409 const size_t NumShards = 256;
410 size_t Step = Sections.size() / NumShards;
411 size_t Boundaries[NumShards + 1];
412 Boundaries[0] = 0;
413 Boundaries[NumShards] = Sections.size();
414
415 parallelForEachN(1, NumShards, [&](size_t I) {
416 Boundaries[I] = findBoundary((I - 1) * Step, Sections.size());
408 const size_t numShards = 256;
409 size_t step = sections.size() / numShards;
410 size_t boundaries[numShards + 1];
411 boundaries[0] = 0;
412 boundaries[numShards] = sections.size();
413
414 parallelForEachN(1, numShards, [&](size_t i) {
415 boundaries[i] = findBoundary((i - 1) * step, sections.size());
417416 });
418417
419 parallelForEachN(1, NumShards + 1, [&](size_t I) {
420 if (Boundaries[I - 1] < Boundaries[I])
421 forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);
418 parallelForEachN(1, numShards + 1, [&](size_t i) {
419 if (boundaries[i - 1] < boundaries[i])
420 forEachClassRange(boundaries[i - 1], boundaries[i], fn);
422421 });
423 ++Cnt;
422 ++cnt;
424423}
425424
426425// Combine the hashes of the sections referenced by the given section into its
427426// hash.
428427template <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];
428static void combineRelocHashes(unsigned cnt, InputSection *isec,
429 ArrayRef<RelTy> rels) {
430 uint32_t hash = isec->eqClass[cnt % 2];
431 for (RelTy rel : rels) {
432 Symbol &s = isec->template getFile<ELFT>()->getRelocTargetSym(rel);
433 if (auto *d = dyn_cast<Defined>(&s))
434 if (auto *relSec = dyn_cast_or_null<InputSection>(d->section))
435 hash += relSec->eqClass[cnt % 2];
437436 }
438437 // Set MSB to 1 to avoid collisions with non-hash IDs.
439 IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
438 isec->eqClass[(cnt + 1) % 2] = hash | (1U << 31);
440439}
441440
442static void print(const Twine &S) {
443 if (Config->PrintIcfSections)
444 message(S);
441static void print(const Twine &s) {
442 if (config->printIcfSections)
443 message(s);
445444}
446445
447446// The main function of ICF.
448447template <class ELFT> void ICF<ELFT>::run() {
449448 // Collect sections to merge.
450 for (InputSectionBase *Sec : InputSections)
451 if (auto *S = dyn_cast<InputSection>(Sec))
452 if (isEligible(S))
453 Sections.push_back(S);
449 for (InputSectionBase *sec : inputSections)
450 if (auto *s = dyn_cast<InputSection>(sec))
451 if (isEligible(s))
452 sections.push_back(s);
454453
455454 // Initially, we use hash values to partition sections.
456 parallelForEach(Sections, [&](InputSection *S) {
457 S->Class[0] = xxHash64(S->data());
455 parallelForEach(sections, [&](InputSection *s) {
456 s->eqClass[0] = xxHash64(s->data());
458457 });
459458
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>());
459 for (unsigned cnt = 0; cnt != 2; ++cnt) {
460 parallelForEach(sections, [&](InputSection *s) {
461 if (s->areRelocsRela)
462 combineRelocHashes<ELFT>(cnt, s, s->template relas<ELFT>());
464463 else
465 combineRelocHashes<ELFT>(Cnt, S, S->template rels<ELFT>());
464 combineRelocHashes<ELFT>(cnt, s, s->template rels<ELFT>());
466465 });
467466 }
468467
469468 // From now on, sections in Sections vector are ordered so that sections
470469 // in the same equivalence class are consecutive in the vector.
471 std::stable_sort(Sections.begin(), Sections.end(),
472 [](InputSection *A, InputSection *B) {
473 return A->Class[0] < B->Class[0];
474 });
470 llvm::stable_sort(sections, [](const InputSection *a, const InputSection *b) {
471 return a->eqClass[0] < b->eqClass[0];
472 });
475473
476474 // Compare static contents and assign unique IDs for each static content.
477 forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); });
475 forEachClass([&](size_t begin, size_t end) { segregate(begin, end, true); });
478476
479477 // Split groups by comparing relocations until convergence is obtained.
480478 do {
481 Repeat = false;
479 repeat = false;
482480 forEachClass(
483 [&](size_t Begin, size_t End) { segregate(Begin, End, false); });
484 } while (Repeat);
481 [&](size_t begin, size_t end) { segregate(begin, end, false); });
482 } while (repeat);
485483
486 log("ICF needed " + Twine(Cnt) + " iterations");
484 log("ICF needed " + Twine(cnt) + " iterations");
487485
488486 // Merge sections by the equivalence class.
489 forEachClassRange(0, Sections.size(), [&](size_t Begin, size_t End) {
490 if (End - Begin == 1)
487 forEachClassRange(0, sections.size(), [&](size_t begin, size_t end) {
488 if (end - begin == 1)
491489 return;
492 print("selected section " + toString(Sections[Begin]));
493 for (size_t I = Begin + 1; I < End; ++I) {
494 print(" removing identical section " + toString(Sections[I]));
495 Sections[Begin]->replace(Sections[I]);
490 print("selected section " + toString(sections[begin]));
491 for (size_t i = begin + 1; i < end; ++i) {
492 print(" removing identical section " + toString(sections[i]));
493 sections[begin]->replace(sections[i]);
496494
497495 // At this point we know sections merged are fully identical and hence
498496 // we want to remove duplicate implicit dependencies such as link order
499497 // and relocation sections.
500 for (InputSection *IS : Sections[I]->DependentSections)
501 IS->Live = false;
498 for (InputSection *isec : sections[i]->dependentSections)
499 isec->markDead();
502500 }
503501 });
504502}
deps/lld/ELF/ICF.h+3-4
......@@ -1,9 +1,8 @@
11//===- ICF.h --------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/ELF/InputFiles.cpp+991-691
......@@ -1,13 +1,13 @@
11//===- InputFiles.cpp -----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
109#include "InputFiles.h"
10#include "Driver.h"
1111#include "InputSection.h"
1212#include "LinkerScript.h"
1313#include "SymbolTable.h"
......@@ -25,6 +25,7 @@
2525#include "llvm/Object/ELFObjectFile.h"
2626#include "llvm/Support/ARMAttributeParser.h"
2727#include "llvm/Support/ARMBuildAttributes.h"
28#include "llvm/Support/Endian.h"
2829#include "llvm/Support/Path.h"
2930#include "llvm/Support/TarWriter.h"
3031#include "llvm/Support/raw_ostream.h"
......@@ -34,145 +35,272 @@ using namespace llvm::ELF;
3435using namespace llvm::object;
3536using namespace llvm::sys;
3637using namespace llvm::sys::fs;
38using namespace llvm::support::endian;
3739
3840using namespace lld;
3941using namespace lld::elf;
4042
41bool InputFile::IsInGroup;
42uint32_t InputFile::NextGroupId;
43std::vector<BinaryFile *> elf::BinaryFiles;
44std::vector<BitcodeFile *> elf::BitcodeFiles;
45std::vector<LazyObjFile *> elf::LazyObjFiles;
46std::vector<InputFile *> elf::ObjectFiles;
47std::vector<InputFile *> elf::SharedFiles;
48
49std::unique_ptr<TarWriter> elf::Tar;
43bool InputFile::isInGroup;
44uint32_t InputFile::nextGroupId;
45std::vector<BinaryFile *> elf::binaryFiles;
46std::vector<BitcodeFile *> elf::bitcodeFiles;
47std::vector<LazyObjFile *> elf::lazyObjFiles;
48std::vector<InputFile *> elf::objectFiles;
49std::vector<SharedFile *> elf::sharedFiles;
50
51std::unique_ptr<TarWriter> elf::tar;
52
53static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
54 unsigned char size;
55 unsigned char endian;
56 std::tie(size, endian) = getElfArchType(mb.getBuffer());
57
58 auto report = [&](StringRef msg) {
59 StringRef filename = mb.getBufferIdentifier();
60 if (archiveName.empty())
61 fatal(filename + ": " + msg);
62 else
63 fatal(archiveName + "(" + filename + "): " + msg);
64 };
65
66 if (!mb.getBuffer().startswith(ElfMagic))
67 report("not an ELF file");
68 if (endian != ELFDATA2LSB && endian != ELFDATA2MSB)
69 report("corrupted ELF file: invalid data encoding");
70 if (size != ELFCLASS32 && size != ELFCLASS64)
71 report("corrupted ELF file: invalid file class");
72
73 size_t bufSize = mb.getBuffer().size();
74 if ((size == ELFCLASS32 && bufSize < sizeof(Elf32_Ehdr)) ||
75 (size == ELFCLASS64 && bufSize < sizeof(Elf64_Ehdr)))
76 report("corrupted ELF file: file is too short");
77
78 if (size == ELFCLASS32)
79 return (endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;
80 return (endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
81}
5082
51InputFile::InputFile(Kind K, MemoryBufferRef M)
52 : MB(M), GroupId(NextGroupId), FileKind(K) {
83InputFile::InputFile(Kind k, MemoryBufferRef m)
84 : mb(m), groupId(nextGroupId), fileKind(k) {
5385 // All files within the same --{start,end}-group get the same group ID.
5486 // Otherwise, a new file will get a new group ID.
55 if (!IsInGroup)
56 ++NextGroupId;
87 if (!isInGroup)
88 ++nextGroupId;
5789}
5890
59Optional<MemoryBufferRef> elf::readFile(StringRef Path) {
91Optional<MemoryBufferRef> elf::readFile(StringRef path) {
6092 // The --chroot option changes our virtual root directory.
6193 // This is useful when you are dealing with files created by --reproduce.
62 if (!Config->Chroot.empty() && Path.startswith("/"))
63 Path = Saver.save(Config->Chroot + Path);
94 if (!config->chroot.empty() && path.startswith("/"))
95 path = saver.save(config->chroot + path);
6496
65 log(Path);
97 log(path);
6698
67 auto MBOrErr = MemoryBuffer::getFile(Path, -1, false);
68 if (auto EC = MBOrErr.getError()) {
69 error("cannot open " + Path + ": " + EC.message());
99 auto mbOrErr = MemoryBuffer::getFile(path, -1, false);
100 if (auto ec = mbOrErr.getError()) {
101 error("cannot open " + path + ": " + ec.message());
70102 return None;
71103 }
72104
73 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
74 MemoryBufferRef MBRef = MB->getMemBufferRef();
75 make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
105 std::unique_ptr<MemoryBuffer> &mb = *mbOrErr;
106 MemoryBufferRef mbref = mb->getMemBufferRef();
107 make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take MB ownership
108
109 if (tar)
110 tar->append(relativeToRoot(path), mbref.getBuffer());
111 return mbref;
112}
113
114// All input object files must be for the same architecture
115// (e.g. it does not make sense to link x86 object files with
116// MIPS object files.) This function checks for that error.
117static bool isCompatible(InputFile *file) {
118 if (!file->isElf() && !isa<BitcodeFile>(file))
119 return true;
120
121 if (file->ekind == config->ekind && file->emachine == config->emachine) {
122 if (config->emachine != EM_MIPS)
123 return true;
124 if (isMipsN32Abi(file) == config->mipsN32Abi)
125 return true;
126 }
127
128 if (!config->emulation.empty()) {
129 error(toString(file) + " is incompatible with " + config->emulation);
130 } else {
131 InputFile *existing;
132 if (!objectFiles.empty())
133 existing = objectFiles[0];
134 else if (!sharedFiles.empty())
135 existing = sharedFiles[0];
136 else
137 existing = bitcodeFiles[0];
138
139 error(toString(file) + " is incompatible with " + toString(existing));
140 }
141
142 return false;
143}
144
145template <class ELFT> static void doParseFile(InputFile *file) {
146 if (!isCompatible(file))
147 return;
148
149 // Binary file
150 if (auto *f = dyn_cast<BinaryFile>(file)) {
151 binaryFiles.push_back(f);
152 f->parse();
153 return;
154 }
155
156 // .a file
157 if (auto *f = dyn_cast<ArchiveFile>(file)) {
158 f->parse();
159 return;
160 }
161
162 // Lazy object file
163 if (auto *f = dyn_cast<LazyObjFile>(file)) {
164 lazyObjFiles.push_back(f);
165 f->parse<ELFT>();
166 return;
167 }
168
169 if (config->trace)
170 message(toString(file));
76171
77 if (Tar)
78 Tar->append(relativeToRoot(Path), MBRef.getBuffer());
79 return MBRef;
172 // .so file
173 if (auto *f = dyn_cast<SharedFile>(file)) {
174 f->parse<ELFT>();
175 return;
176 }
177
178 // LLVM bitcode file
179 if (auto *f = dyn_cast<BitcodeFile>(file)) {
180 bitcodeFiles.push_back(f);
181 f->parse<ELFT>();
182 return;
183 }
184
185 // Regular object file
186 objectFiles.push_back(file);
187 cast<ObjFile<ELFT>>(file)->parse();
188}
189
190// Add symbols in File to the symbol table.
191void elf::parseFile(InputFile *file) {
192 switch (config->ekind) {
193 case ELF32LEKind:
194 doParseFile<ELF32LE>(file);
195 return;
196 case ELF32BEKind:
197 doParseFile<ELF32BE>(file);
198 return;
199 case ELF64LEKind:
200 doParseFile<ELF64LE>(file);
201 return;
202 case ELF64BEKind:
203 doParseFile<ELF64BE>(file);
204 return;
205 default:
206 llvm_unreachable("unknown ELFT");
207 }
80208}
81209
82210// Concatenates arguments to construct a string representing an error location.
83static std::string createFileLineMsg(StringRef Path, unsigned Line) {
84 std::string Filename = path::filename(Path);
85 std::string Lineno = ":" + std::to_string(Line);
86 if (Filename == Path)
87 return Filename + Lineno;
88 return Filename + Lineno + " (" + Path.str() + Lineno + ")";
211static std::string createFileLineMsg(StringRef path, unsigned line) {
212 std::string filename = path::filename(path);
213 std::string lineno = ":" + std::to_string(line);
214 if (filename == path)
215 return filename + lineno;
216 return filename + lineno + " (" + path.str() + lineno + ")";
89217}
90218
91219template <class ELFT>
92static std::string getSrcMsgAux(ObjFile<ELFT> &File, const Symbol &Sym,
93 InputSectionBase &Sec, uint64_t Offset) {
220static std::string getSrcMsgAux(ObjFile<ELFT> &file, const Symbol &sym,
221 InputSectionBase &sec, uint64_t offset) {
94222 // In DWARF, functions and variables are stored to different places.
95223 // First, lookup a function for a given offset.
96 if (Optional<DILineInfo> Info = File.getDILineInfo(&Sec, Offset))
97 return createFileLineMsg(Info->FileName, Info->Line);
224 if (Optional<DILineInfo> info = file.getDILineInfo(&sec, offset))
225 return createFileLineMsg(info->FileName, info->Line);
98226
99227 // If it failed, lookup again as a variable.
100 if (Optional<std::pair<std::string, unsigned>> FileLine =
101 File.getVariableLoc(Sym.getName()))
102 return createFileLineMsg(FileLine->first, FileLine->second);
228 if (Optional<std::pair<std::string, unsigned>> fileLine =
229 file.getVariableLoc(sym.getName()))
230 return createFileLineMsg(fileLine->first, fileLine->second);
103231
104 // File.SourceFile contains STT_FILE symbol, and that is a last resort.
105 return File.SourceFile;
232 // File.sourceFile contains STT_FILE symbol, and that is a last resort.
233 return file.sourceFile;
106234}
107235
108std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
109 uint64_t Offset) {
236std::string InputFile::getSrcMsg(const Symbol &sym, InputSectionBase &sec,
237 uint64_t offset) {
110238 if (kind() != ObjKind)
111239 return "";
112 switch (Config->EKind) {
240 switch (config->ekind) {
113241 default:
114242 llvm_unreachable("Invalid kind");
115243 case ELF32LEKind:
116 return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), Sym, Sec, Offset);
244 return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), sym, sec, offset);
117245 case ELF32BEKind:
118 return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), Sym, Sec, Offset);
246 return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), sym, sec, offset);
119247 case ELF64LEKind:
120 return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), Sym, Sec, Offset);
248 return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), sym, sec, offset);
121249 case ELF64BEKind:
122 return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), Sym, Sec, Offset);
250 return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), sym, sec, offset);
123251 }
124252}
125253
126254template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
127 Dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this));
128 for (std::unique_ptr<DWARFUnit> &CU : Dwarf->compile_units()) {
129 auto Report = [](Error Err) {
130 handleAllErrors(std::move(Err),
131 [](ErrorInfoBase &Info) { warn(Info.message()); });
255 dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this));
256 for (std::unique_ptr<DWARFUnit> &cu : dwarf->compile_units()) {
257 auto report = [](Error err) {
258 handleAllErrors(std::move(err),
259 [](ErrorInfoBase &info) { warn(info.message()); });
132260 };
133 Expected<const DWARFDebugLine::LineTable *> ExpectedLT =
134 Dwarf->getLineTableForUnit(CU.get(), Report);
135 const DWARFDebugLine::LineTable *LT = nullptr;
136 if (ExpectedLT)
137 LT = *ExpectedLT;
261 Expected<const DWARFDebugLine::LineTable *> expectedLT =
262 dwarf->getLineTableForUnit(cu.get(), report);
263 const DWARFDebugLine::LineTable *lt = nullptr;
264 if (expectedLT)
265 lt = *expectedLT;
138266 else
139 Report(ExpectedLT.takeError());
140 if (!LT)
267 report(expectedLT.takeError());
268 if (!lt)
141269 continue;
142 LineTables.push_back(LT);
270 lineTables.push_back(lt);
143271
144 // Loop over variable records and insert them to VariableLoc.
145 for (const auto &Entry : CU->dies()) {
146 DWARFDie Die(CU.get(), &Entry);
272 // Loop over variable records and insert them to variableLoc.
273 for (const auto &entry : cu->dies()) {
274 DWARFDie die(cu.get(), &entry);
147275 // Skip all tags that are not variables.
148 if (Die.getTag() != dwarf::DW_TAG_variable)
276 if (die.getTag() != dwarf::DW_TAG_variable)
149277 continue;
150278
151279 // Skip if a local variable because we don't need them for generating
152280 // error messages. In general, only non-local symbols can fail to be
153281 // linked.
154 if (!dwarf::toUnsigned(Die.find(dwarf::DW_AT_external), 0))
282 if (!dwarf::toUnsigned(die.find(dwarf::DW_AT_external), 0))
155283 continue;
156284
157285 // Get the source filename index for the variable.
158 unsigned File = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_file), 0);
159 if (!LT->hasFileAtIndex(File))
286 unsigned file = dwarf::toUnsigned(die.find(dwarf::DW_AT_decl_file), 0);
287 if (!lt->hasFileAtIndex(file))
160288 continue;
161289
162290 // Get the line number on which the variable is declared.
163 unsigned Line = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_line), 0);
291 unsigned line = dwarf::toUnsigned(die.find(dwarf::DW_AT_decl_line), 0);
164292
165 // Here we want to take the variable name to add it into VariableLoc.
293 // Here we want to take the variable name to add it into variableLoc.
166294 // Variable can have regular and linkage name associated. At first, we try
167295 // to get linkage name as it can be different, for example when we have
168296 // two variables in different namespaces of the same object. Use common
169297 // name otherwise, but handle the case when it also absent in case if the
170298 // input object file lacks some debug info.
171 StringRef Name =
172 dwarf::toString(Die.find(dwarf::DW_AT_linkage_name),
173 dwarf::toString(Die.find(dwarf::DW_AT_name), ""));
174 if (!Name.empty())
175 VariableLoc.insert({Name, {LT, File, Line}});
299 StringRef name =
300 dwarf::toString(die.find(dwarf::DW_AT_linkage_name),
301 dwarf::toString(die.find(dwarf::DW_AT_name), ""));
302 if (!name.empty())
303 variableLoc.insert({name, {lt, file, line}});
176304 }
177305 }
178306}
......@@ -181,112 +309,152 @@ template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
181309// object (variable, array, etc) definition.
182310template <class ELFT>
183311Optional<std::pair<std::string, unsigned>>
184ObjFile<ELFT>::getVariableLoc(StringRef Name) {
185 llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); });
312ObjFile<ELFT>::getVariableLoc(StringRef name) {
313 llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });
186314
187315 // Return if we have no debug information about data object.
188 auto It = VariableLoc.find(Name);
189 if (It == VariableLoc.end())
316 auto it = variableLoc.find(name);
317 if (it == variableLoc.end())
190318 return None;
191319
192320 // Take file name string from line table.
193 std::string FileName;
194 if (!It->second.LT->getFileNameByIndex(
195 It->second.File, nullptr,
196 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FileName))
321 std::string fileName;
322 if (!it->second.lt->getFileNameByIndex(
323 it->second.file, {},
324 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, fileName))
197325 return None;
198326
199 return std::make_pair(FileName, It->second.Line);
327 return std::make_pair(fileName, it->second.line);
200328}
201329
202330// Returns source line information for a given offset
203331// using DWARF debug info.
204332template <class ELFT>
205Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *S,
206 uint64_t Offset) {
207 llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); });
333Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s,
334 uint64_t offset) {
335 llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });
336
337 // Detect SectionIndex for specified section.
338 uint64_t sectionIndex = object::SectionedAddress::UndefSection;
339 ArrayRef<InputSectionBase *> sections = s->file->getSections();
340 for (uint64_t curIndex = 0; curIndex < sections.size(); ++curIndex) {
341 if (s == sections[curIndex]) {
342 sectionIndex = curIndex;
343 break;
344 }
345 }
208346
209347 // Use fake address calcuated by adding section file offset and offset in
210348 // section. See comments for ObjectInfo class.
211 DILineInfo Info;
212 for (const llvm::DWARFDebugLine::LineTable *LT : LineTables)
213 if (LT->getFileLineInfoForAddress(
214 S->getOffsetInFile() + Offset, nullptr,
215 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info))
216 return Info;
349 DILineInfo info;
350 for (const llvm::DWARFDebugLine::LineTable *lt : lineTables) {
351 if (lt->getFileLineInfoForAddress(
352 {s->getOffsetInFile() + offset, sectionIndex}, nullptr,
353 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, info))
354 return info;
355 }
217356 return None;
218357}
219358
220359// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
221std::string lld::toString(const InputFile *F) {
222 if (!F)
360std::string lld::toString(const InputFile *f) {
361 if (!f)
223362 return "<internal>";
224363
225 if (F->ToStringCache.empty()) {
226 if (F->ArchiveName.empty())
227 F->ToStringCache = F->getName();
364 if (f->toStringCache.empty()) {
365 if (f->archiveName.empty())
366 f->toStringCache = f->getName();
228367 else
229 F->ToStringCache = (F->ArchiveName + "(" + F->getName() + ")").str();
368 f->toStringCache = (f->archiveName + "(" + f->getName() + ")").str();
230369 }
231 return F->ToStringCache;
370 return f->toStringCache;
232371}
233372
234template <class ELFT>
235ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
236 if (ELFT::TargetEndianness == support::little)
237 EKind = ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
238 else
239 EKind = ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
373ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) {
374 ekind = getELFKind(mb, "");
240375
241 EMachine = getObj().getHeader()->e_machine;
242 OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
376 switch (ekind) {
377 case ELF32LEKind:
378 init<ELF32LE>();
379 break;
380 case ELF32BEKind:
381 init<ELF32BE>();
382 break;
383 case ELF64LEKind:
384 init<ELF64LE>();
385 break;
386 case ELF64BEKind:
387 init<ELF64BE>();
388 break;
389 default:
390 llvm_unreachable("getELFKind");
391 }
243392}
244393
245template <class ELFT>
246typename ELFT::SymRange ELFFileBase<ELFT>::getGlobalELFSyms() {
247 return makeArrayRef(ELFSyms.begin() + FirstGlobal, ELFSyms.end());
394template <typename Elf_Shdr>
395static const Elf_Shdr *findSection(ArrayRef<Elf_Shdr> sections, uint32_t type) {
396 for (const Elf_Shdr &sec : sections)
397 if (sec.sh_type == type)
398 return &sec;
399 return nullptr;
248400}
249401
250template <class ELFT>
251uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
252 return CHECK(getObj().getSectionIndex(&Sym, ELFSyms, SymtabSHNDX), this);
253}
402template <class ELFT> void ELFFileBase::init() {
403 using Elf_Shdr = typename ELFT::Shdr;
404 using Elf_Sym = typename ELFT::Sym;
254405
255template <class ELFT>
256void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections,
257 const Elf_Shdr *Symtab) {
258 FirstGlobal = Symtab->sh_info;
259 ELFSyms = CHECK(getObj().symbols(Symtab), this);
260 if (FirstGlobal == 0 || FirstGlobal > ELFSyms.size())
406 // Initialize trivial attributes.
407 const ELFFile<ELFT> &obj = getObj<ELFT>();
408 emachine = obj.getHeader()->e_machine;
409 osabi = obj.getHeader()->e_ident[llvm::ELF::EI_OSABI];
410 abiVersion = obj.getHeader()->e_ident[llvm::ELF::EI_ABIVERSION];
411
412 ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
413
414 // Find a symbol table.
415 bool isDSO =
416 (identify_magic(mb.getBuffer()) == file_magic::elf_shared_object);
417 const Elf_Shdr *symtabSec =
418 findSection(sections, isDSO ? SHT_DYNSYM : SHT_SYMTAB);
419
420 if (!symtabSec)
421 return;
422
423 // Initialize members corresponding to a symbol table.
424 firstGlobal = symtabSec->sh_info;
425
426 ArrayRef<Elf_Sym> eSyms = CHECK(obj.symbols(symtabSec), this);
427 if (firstGlobal == 0 || firstGlobal > eSyms.size())
261428 fatal(toString(this) + ": invalid sh_info in symbol table");
262429
263 StringTable =
264 CHECK(getObj().getStringTableForSymtab(*Symtab, Sections), this);
430 elfSyms = reinterpret_cast<const void *>(eSyms.data());
431 numELFSyms = eSyms.size();
432 stringTable = CHECK(obj.getStringTableForSymtab(*symtabSec, sections), this);
265433}
266434
267435template <class ELFT>
268ObjFile<ELFT>::ObjFile(MemoryBufferRef M, StringRef ArchiveName)
269 : ELFFileBase<ELFT>(Base::ObjKind, M) {
270 this->ArchiveName = ArchiveName;
436uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &sym) const {
437 return CHECK(
438 this->getObj().getSectionIndex(&sym, getELFSyms<ELFT>(), shndxTable),
439 this);
271440}
272441
273442template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getLocalSymbols() {
274 if (this->Symbols.empty())
443 if (this->symbols.empty())
275444 return {};
276 return makeArrayRef(this->Symbols).slice(1, this->FirstGlobal - 1);
445 return makeArrayRef(this->symbols).slice(1, this->firstGlobal - 1);
277446}
278447
279448template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getGlobalSymbols() {
280 return makeArrayRef(this->Symbols).slice(this->FirstGlobal);
449 return makeArrayRef(this->symbols).slice(this->firstGlobal);
281450}
282451
283template <class ELFT>
284void ObjFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
285 // Read a section table. JustSymbols is usually false.
286 if (this->JustSymbols)
452template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
453 // Read a section table. justSymbols is usually false.
454 if (this->justSymbols)
287455 initializeJustSymbols();
288456 else
289 initializeSections(ComdatGroups);
457 initializeSections(ignoreComdats);
290458
291459 // Read a symbol table.
292460 initializeSymbols();
......@@ -296,17 +464,13 @@ void ObjFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
296464// They are identified and deduplicated by group name. This function
297465// returns a group name.
298466template <class ELFT>
299StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
300 const Elf_Shdr &Sec) {
301 // Group signatures are stored as symbol names in object files.
302 // sh_info contains a symbol index, so we fetch a symbol and read its name.
303 if (this->ELFSyms.empty())
304 this->initSymtab(
305 Sections, CHECK(object::getSection<ELFT>(Sections, Sec.sh_link), this));
306
307 const Elf_Sym *Sym =
308 CHECK(object::getSymbol<ELFT>(this->ELFSyms, Sec.sh_info), this);
309 StringRef Signature = CHECK(Sym->getName(this->StringTable), this);
467StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> sections,
468 const Elf_Shdr &sec) {
469 typename ELFT::SymRange symbols = this->getELFSyms<ELFT>();
470 if (sec.sh_info >= symbols.size())
471 fatal(toString(this) + ": invalid symbol index");
472 const typename ELFT::Sym &sym = symbols[sec.sh_info];
473 StringRef signature = CHECK(sym.getName(this->stringTable), this);
310474
311475 // As a special case, if a symbol is a section symbol and has no name,
312476 // we use a section name as a signature.
......@@ -315,12 +479,12 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
315479 // standard, but GNU gold 1.14 (the newest version as of July 2017) or
316480 // older produce such sections as outputs for the -r option, so we need
317481 // a bug-compatibility.
318 if (Signature.empty() && Sym->getType() == STT_SECTION)
319 return getSectionName(Sec);
320 return Signature;
482 if (signature.empty() && sym.getType() == STT_SECTION)
483 return getSectionName(sec);
484 return signature;
321485}
322486
323template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
487template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &sec) {
324488 // On a regular link we don't merge sections if -O0 (default is -O1). This
325489 // sometimes makes the linker significantly faster, although the output will
326490 // be bigger.
......@@ -333,14 +497,14 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
333497 // SHF_MERGE sections based both on their name and sh_entsize, but that seems
334498 // to be more trouble than it is worth. Instead, we just use the regular (-O1)
335499 // logic for -r.
336 if (Config->Optimize == 0 && !Config->Relocatable)
500 if (config->optimize == 0 && !config->relocatable)
337501 return false;
338502
339503 // A mergeable section with size 0 is useless because they don't have
340504 // any data to merge. A mergeable string section with size 0 can be
341505 // argued as invalid because it doesn't end with a null character.
342506 // We'll avoid a mess by handling them as if they were non-mergeable.
343 if (Sec.sh_size == 0)
507 if (sec.sh_size == 0)
344508 return false;
345509
346510 // Check for sh_entsize. The ELF spec is not clear about the zero
......@@ -348,17 +512,17 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
348512 // the section does not hold a table of fixed-size entries". We know
349513 // that Rust 1.13 produces a string mergeable section with a zero
350514 // sh_entsize. Here we just accept it rather than being picky about it.
351 uint64_t EntSize = Sec.sh_entsize;
352 if (EntSize == 0)
515 uint64_t entSize = sec.sh_entsize;
516 if (entSize == 0)
353517 return false;
354 if (Sec.sh_size % EntSize)
518 if (sec.sh_size % entSize)
355519 fatal(toString(this) +
356520 ": SHF_MERGE section size must be a multiple of sh_entsize");
357521
358 uint64_t Flags = Sec.sh_flags;
359 if (!(Flags & SHF_MERGE))
522 uint64_t flags = sec.sh_flags;
523 if (!(flags & SHF_MERGE))
360524 return false;
361 if (Flags & SHF_WRITE)
525 if (flags & SHF_WRITE)
362526 fatal(toString(this) + ": writable SHF_MERGE section is not supported");
363527
364528 return true;
......@@ -374,126 +538,138 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
374538// When the option is given, we link "just symbols". The section table is
375539// initialized with null pointers.
376540template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
377 ArrayRef<Elf_Shdr> ObjSections = CHECK(this->getObj().sections(), this);
378 this->Sections.resize(ObjSections.size());
541 ArrayRef<Elf_Shdr> sections = CHECK(this->getObj().sections(), this);
542 this->sections.resize(sections.size());
543}
379544
380 for (const Elf_Shdr &Sec : ObjSections) {
381 if (Sec.sh_type != SHT_SYMTAB)
382 continue;
383 this->initSymtab(ObjSections, &Sec);
545// An ELF object file may contain a `.deplibs` section. If it exists, the
546// section contains a list of library specifiers such as `m` for libm. This
547// function resolves a given name by finding the first matching library checking
548// the various ways that a library can be specified to LLD. This ELF extension
549// is a form of autolinking and is called `dependent libraries`. It is currently
550// unique to LLVM and lld.
551static void addDependentLibrary(StringRef specifier, const InputFile *f) {
552 if (!config->dependentLibraries)
384553 return;
385 }
554 if (fs::exists(specifier))
555 driver->addFile(specifier, /*withLOption=*/false);
556 else if (Optional<std::string> s = findFromSearchPaths(specifier))
557 driver->addFile(*s, /*withLOption=*/true);
558 else if (Optional<std::string> s = searchLibraryBaseName(specifier))
559 driver->addFile(*s, /*withLOption=*/true);
560 else
561 error(toString(f) +
562 ": unable to find library from dependent library specifier: " +
563 specifier);
386564}
387565
388566template <class ELFT>
389void ObjFile<ELFT>::initializeSections(
390 DenseSet<CachedHashStringRef> &ComdatGroups) {
391 const ELFFile<ELFT> &Obj = this->getObj();
392
393 ArrayRef<Elf_Shdr> ObjSections = CHECK(Obj.sections(), this);
394 uint64_t Size = ObjSections.size();
395 this->Sections.resize(Size);
396 this->SectionStringTable =
397 CHECK(Obj.getSectionStringTable(ObjSections), this);
398
399 for (size_t I = 0, E = ObjSections.size(); I < E; I++) {
400 if (this->Sections[I] == &InputSection::Discarded)
567void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
568 const ELFFile<ELFT> &obj = this->getObj();
569
570 ArrayRef<Elf_Shdr> objSections = CHECK(obj.sections(), this);
571 uint64_t size = objSections.size();
572 this->sections.resize(size);
573 this->sectionStringTable =
574 CHECK(obj.getSectionStringTable(objSections), this);
575
576 for (size_t i = 0, e = objSections.size(); i < e; i++) {
577 if (this->sections[i] == &InputSection::discarded)
401578 continue;
402 const Elf_Shdr &Sec = ObjSections[I];
579 const Elf_Shdr &sec = objSections[i];
403580
404 if (Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
405 CGProfile = check(
406 this->getObj().template getSectionContentsAsArray<Elf_CGProfile>(
407 &Sec));
581 if (sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
582 cgProfile =
583 check(obj.template getSectionContentsAsArray<Elf_CGProfile>(&sec));
408584
409585 // SHF_EXCLUDE'ed sections are discarded by the linker. However,
410586 // if -r is given, we'll let the final link discard such sections.
411587 // This is compatible with GNU.
412 if ((Sec.sh_flags & SHF_EXCLUDE) && !Config->Relocatable) {
413 if (Sec.sh_type == SHT_LLVM_ADDRSIG) {
588 if ((sec.sh_flags & SHF_EXCLUDE) && !config->relocatable) {
589 if (sec.sh_type == SHT_LLVM_ADDRSIG) {
414590 // We ignore the address-significance table if we know that the object
415591 // file was created by objcopy or ld -r. This is because these tools
416592 // will reorder the symbols in the symbol table, invalidating the data
417593 // in the address-significance table, which refers to symbols by index.
418 if (Sec.sh_link != 0)
419 this->AddrsigSec = &Sec;
420 else if (Config->ICF == ICFLevel::Safe)
594 if (sec.sh_link != 0)
595 this->addrsigSec = &sec;
596 else if (config->icf == ICFLevel::Safe)
421597 warn(toString(this) + ": --icf=safe is incompatible with object "
422598 "files created using objcopy or ld -r");
423599 }
424 this->Sections[I] = &InputSection::Discarded;
600 this->sections[i] = &InputSection::discarded;
425601 continue;
426602 }
427603
428 switch (Sec.sh_type) {
604 switch (sec.sh_type) {
429605 case SHT_GROUP: {
430606 // De-duplicate section groups by their signatures.
431 StringRef Signature = getShtGroupSignature(ObjSections, Sec);
432 this->Sections[I] = &InputSection::Discarded;
607 StringRef signature = getShtGroupSignature(objSections, sec);
608 this->sections[i] = &InputSection::discarded;
433609
434610
435 ArrayRef<Elf_Word> Entries =
436 CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
437 if (Entries.empty())
611 ArrayRef<Elf_Word> entries =
612 CHECK(obj.template getSectionContentsAsArray<Elf_Word>(&sec), this);
613 if (entries.empty())
438614 fatal(toString(this) + ": empty SHT_GROUP");
439615
440616 // The first word of a SHT_GROUP section contains flags. Currently,
441617 // the standard defines only "GRP_COMDAT" flag for the COMDAT group.
442618 // An group with the empty flag doesn't define anything; such sections
443619 // are just skipped.
444 if (Entries[0] == 0)
620 if (entries[0] == 0)
445621 continue;
446622
447 if (Entries[0] != GRP_COMDAT)
623 if (entries[0] != GRP_COMDAT)
448624 fatal(toString(this) + ": unsupported SHT_GROUP format");
449625
450 bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
451 if (IsNew) {
452 if (Config->Relocatable)
453 this->Sections[I] = createInputSection(Sec);
454 continue;
626 bool isNew =
627 ignoreComdats ||
628 symtab->comdatGroups.try_emplace(CachedHashStringRef(signature), this)
629 .second;
630 if (isNew) {
631 if (config->relocatable)
632 this->sections[i] = createInputSection(sec);
633 continue;
455634 }
456635
457
458636 // Otherwise, discard group members.
459 for (uint32_t SecIndex : Entries.slice(1)) {
460 if (SecIndex >= Size)
637 for (uint32_t secIndex : entries.slice(1)) {
638 if (secIndex >= size)
461639 fatal(toString(this) +
462 ": invalid section index in group: " + Twine(SecIndex));
463 this->Sections[SecIndex] = &InputSection::Discarded;
640 ": invalid section index in group: " + Twine(secIndex));
641 this->sections[secIndex] = &InputSection::discarded;
464642 }
465643 break;
466644 }
467 case SHT_SYMTAB:
468 this->initSymtab(ObjSections, &Sec);
469 break;
470645 case SHT_SYMTAB_SHNDX:
471 this->SymtabSHNDX = CHECK(Obj.getSHNDXTable(Sec, ObjSections), this);
646 shndxTable = CHECK(obj.getSHNDXTable(sec, objSections), this);
472647 break;
648 case SHT_SYMTAB:
473649 case SHT_STRTAB:
474650 case SHT_NULL:
475651 break;
476652 default:
477 this->Sections[I] = createInputSection(Sec);
653 this->sections[i] = createInputSection(sec);
478654 }
479655
480656 // .ARM.exidx sections have a reverse dependency on the InputSection they
481657 // have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
482 if (Sec.sh_flags & SHF_LINK_ORDER) {
483 InputSectionBase *LinkSec = nullptr;
484 if (Sec.sh_link < this->Sections.size())
485 LinkSec = this->Sections[Sec.sh_link];
486 if (!LinkSec)
658 if (sec.sh_flags & SHF_LINK_ORDER) {
659 InputSectionBase *linkSec = nullptr;
660 if (sec.sh_link < this->sections.size())
661 linkSec = this->sections[sec.sh_link];
662 if (!linkSec)
487663 fatal(toString(this) +
488 ": invalid sh_link index: " + Twine(Sec.sh_link));
664 ": invalid sh_link index: " + Twine(sec.sh_link));
489665
490 InputSection *IS = cast<InputSection>(this->Sections[I]);
491 LinkSec->DependentSections.push_back(IS);
492 if (!isa<InputSection>(LinkSec))
493 error("a section " + IS->Name +
666 InputSection *isec = cast<InputSection>(this->sections[i]);
667 linkSec->dependentSections.push_back(isec);
668 if (!isa<InputSection>(linkSec))
669 error("a section " + isec->name +
494670 " with SHF_LINK_ORDER should not refer a non-regular "
495671 "section: " +
496 toString(LinkSec));
672 toString(linkSec));
497673 }
498674 }
499675}
......@@ -501,9 +677,9 @@ void ObjFile<ELFT>::initializeSections(
501677// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD
502678// flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how
503679// the input objects have been compiled.
504static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
505 const InputFile *F) {
506 if (!Attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args))
680static void updateARMVFPArgs(const ARMAttributeParser &attributes,
681 const InputFile *f) {
682 if (!attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args))
507683 // If an ABI tag isn't present then it is implicitly given the value of 0
508684 // which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,
509685 // including some in glibc that don't use FP args (and should have value 3)
......@@ -511,31 +687,31 @@ static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
511687 // as a clash.
512688 return;
513689
514 unsigned VFPArgs = Attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
515 ARMVFPArgKind Arg;
516 switch (VFPArgs) {
690 unsigned vfpArgs = attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
691 ARMVFPArgKind arg;
692 switch (vfpArgs) {
517693 case ARMBuildAttrs::BaseAAPCS:
518 Arg = ARMVFPArgKind::Base;
694 arg = ARMVFPArgKind::Base;
519695 break;
520696 case ARMBuildAttrs::HardFPAAPCS:
521 Arg = ARMVFPArgKind::VFP;
697 arg = ARMVFPArgKind::VFP;
522698 break;
523699 case ARMBuildAttrs::ToolChainFPPCS:
524700 // Tool chain specific convention that conforms to neither AAPCS variant.
525 Arg = ARMVFPArgKind::ToolChain;
701 arg = ARMVFPArgKind::ToolChain;
526702 break;
527703 case ARMBuildAttrs::CompatibleFPAAPCS:
528704 // Object compatible with all conventions.
529705 return;
530706 default:
531 error(toString(F) + ": unknown Tag_ABI_VFP_args value: " + Twine(VFPArgs));
707 error(toString(f) + ": unknown Tag_ABI_VFP_args value: " + Twine(vfpArgs));
532708 return;
533709 }
534710 // Follow ld.bfd and error if there is a mix of calling conventions.
535 if (Config->ARMVFPArgs != Arg && Config->ARMVFPArgs != ARMVFPArgKind::Default)
536 error(toString(F) + ": incompatible Tag_ABI_VFP_args");
711 if (config->armVFPArgs != arg && config->armVFPArgs != ARMVFPArgKind::Default)
712 error(toString(f) + ": incompatible Tag_ABI_VFP_args");
537713 else
538 Config->ARMVFPArgs = Arg;
714 config->armVFPArgs = arg;
539715}
540716
541717// The ARM support in lld makes some use of instructions that are not available
......@@ -547,11 +723,11 @@ static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
547723// at compile time. We follow the convention that if at least one input object
548724// is compiled with an architecture that supports these features then lld is
549725// permitted to use them.
550static void updateSupportedARMFeatures(const ARMAttributeParser &Attributes) {
551 if (!Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
726static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) {
727 if (!attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
552728 return;
553 auto Arch = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
554 switch (Arch) {
729 auto arch = attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
730 switch (arch) {
555731 case ARMBuildAttrs::Pre_v4:
556732 case ARMBuildAttrs::v4:
557733 case ARMBuildAttrs::v4T:
......@@ -563,70 +739,156 @@ static void updateSupportedARMFeatures(const ARMAttributeParser &Attributes) {
563739 case ARMBuildAttrs::v6:
564740 case ARMBuildAttrs::v6KZ:
565741 case ARMBuildAttrs::v6K:
566 Config->ARMHasBlx = true;
742 config->armHasBlx = true;
567743 // Architectures used in pre-Cortex processors do not support
568744 // The J1 = 1 J2 = 1 Thumb branch range extension, with the exception
569745 // of Architecture v6T2 (arm1156t2-s and arm1156t2f-s) that do.
570746 break;
571747 default:
572748 // All other Architectures have BLX and extended branch encoding
573 Config->ARMHasBlx = true;
574 Config->ARMJ1J2BranchEncoding = true;
575 if (Arch != ARMBuildAttrs::v6_M && Arch != ARMBuildAttrs::v6S_M)
749 config->armHasBlx = true;
750 config->armJ1J2BranchEncoding = true;
751 if (arch != ARMBuildAttrs::v6_M && arch != ARMBuildAttrs::v6S_M)
576752 // All Architectures used in Cortex processors with the exception
577753 // of v6-M and v6S-M have the MOVT and MOVW instructions.
578 Config->ARMHasMovtMovw = true;
754 config->armHasMovtMovw = true;
579755 break;
580756 }
581757}
582758
759// If a source file is compiled with x86 hardware-assisted call flow control
760// enabled, the generated object file contains feature flags indicating that
761// fact. This function reads the feature flags and returns it.
762//
763// Essentially we want to read a single 32-bit value in this function, but this
764// function is rather complicated because the value is buried deep inside a
765// .note.gnu.property section.
766//
767// The section consists of one or more NOTE records. Each NOTE record consists
768// of zero or more type-length-value fields. We want to find a field of a
769// certain type. It seems a bit too much to just store a 32-bit value, perhaps
770// the ABI is unnecessarily complicated.
771template <class ELFT>
772static uint32_t readAndFeatures(ObjFile<ELFT> *obj, ArrayRef<uint8_t> data) {
773 using Elf_Nhdr = typename ELFT::Nhdr;
774 using Elf_Note = typename ELFT::Note;
775
776 uint32_t featuresSet = 0;
777 while (!data.empty()) {
778 // Read one NOTE record.
779 if (data.size() < sizeof(Elf_Nhdr))
780 fatal(toString(obj) + ": .note.gnu.property: section too short");
781
782 auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
783 if (data.size() < nhdr->getSize())
784 fatal(toString(obj) + ": .note.gnu.property: section too short");
785
786 Elf_Note note(*nhdr);
787 if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") {
788 data = data.slice(nhdr->getSize());
789 continue;
790 }
791
792 uint32_t featureAndType = config->emachine == EM_AARCH64
793 ? GNU_PROPERTY_AARCH64_FEATURE_1_AND
794 : GNU_PROPERTY_X86_FEATURE_1_AND;
795
796 // Read a body of a NOTE record, which consists of type-length-value fields.
797 ArrayRef<uint8_t> desc = note.getDesc();
798 while (!desc.empty()) {
799 if (desc.size() < 8)
800 fatal(toString(obj) + ": .note.gnu.property: section too short");
801
802 uint32_t type = read32le(desc.data());
803 uint32_t size = read32le(desc.data() + 4);
804
805 if (type == featureAndType) {
806 // We found a FEATURE_1_AND field. There may be more than one of these
807 // in a .note.gnu.propery section, for a relocatable object we
808 // accumulate the bits set.
809 featuresSet |= read32le(desc.data() + 8);
810 }
811
812 // On 64-bit, a payload may be followed by a 4-byte padding to make its
813 // size a multiple of 8.
814 if (ELFT::Is64Bits)
815 size = alignTo(size, 8);
816
817 desc = desc.slice(size + 8); // +8 for Type and Size
818 }
819
820 // Go to next NOTE record to look for more FEATURE_1_AND descriptions.
821 data = data.slice(nhdr->getSize());
822 }
823
824 return featuresSet;
825}
826
583827template <class ELFT>
584InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) {
585 uint32_t Idx = Sec.sh_info;
586 if (Idx >= this->Sections.size())
587 fatal(toString(this) + ": invalid relocated section index: " + Twine(Idx));
588 InputSectionBase *Target = this->Sections[Idx];
828InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &sec) {
829 uint32_t idx = sec.sh_info;
830 if (idx >= this->sections.size())
831 fatal(toString(this) + ": invalid relocated section index: " + Twine(idx));
832 InputSectionBase *target = this->sections[idx];
589833
590834 // Strictly speaking, a relocation section must be included in the
591835 // group of the section it relocates. However, LLVM 3.3 and earlier
592836 // would fail to do so, so we gracefully handle that case.
593 if (Target == &InputSection::Discarded)
837 if (target == &InputSection::discarded)
594838 return nullptr;
595839
596 if (!Target)
840 if (!target)
597841 fatal(toString(this) + ": unsupported relocation reference");
598 return Target;
842 return target;
599843}
600844
601845// Create a regular InputSection class that has the same contents
602846// as a given section.
603static InputSection *toRegularSection(MergeInputSection *Sec) {
604 return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment,
605 Sec->data(), Sec->Name);
847static InputSection *toRegularSection(MergeInputSection *sec) {
848 return make<InputSection>(sec->file, sec->flags, sec->type, sec->alignment,
849 sec->data(), sec->name);
606850}
607851
608852template <class ELFT>
609InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
610 StringRef Name = getSectionName(Sec);
853InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &sec) {
854 StringRef name = getSectionName(sec);
611855
612 switch (Sec.sh_type) {
856 switch (sec.sh_type) {
613857 case SHT_ARM_ATTRIBUTES: {
614 if (Config->EMachine != EM_ARM)
858 if (config->emachine != EM_ARM)
615859 break;
616 ARMAttributeParser Attributes;
617 ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
618 Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);
619 updateSupportedARMFeatures(Attributes);
620 updateARMVFPArgs(Attributes, this);
860 ARMAttributeParser attributes;
861 ArrayRef<uint8_t> contents = check(this->getObj().getSectionContents(&sec));
862 attributes.Parse(contents, /*isLittle*/ config->ekind == ELF32LEKind);
863 updateSupportedARMFeatures(attributes);
864 updateARMVFPArgs(attributes, this);
621865
622866 // FIXME: Retain the first attribute section we see. The eglibc ARM
623867 // dynamic loaders require the presence of an attribute section for dlopen
624868 // to work. In a full implementation we would merge all attribute sections.
625 if (In.ARMAttributes == nullptr) {
626 In.ARMAttributes = make<InputSection>(*this, Sec, Name);
627 return In.ARMAttributes;
869 if (in.armAttributes == nullptr) {
870 in.armAttributes = make<InputSection>(*this, sec, name);
871 return in.armAttributes;
872 }
873 return &InputSection::discarded;
874 }
875 case SHT_LLVM_DEPENDENT_LIBRARIES: {
876 if (config->relocatable)
877 break;
878 ArrayRef<char> data =
879 CHECK(this->getObj().template getSectionContentsAsArray<char>(&sec), this);
880 if (!data.empty() && data.back() != '\0') {
881 error(toString(this) +
882 ": corrupted dependent libraries section (unterminated string): " +
883 name);
884 return &InputSection::discarded;
628885 }
629 return &InputSection::Discarded;
886 for (const char *d = data.begin(), *e = data.end(); d < e;) {
887 StringRef s(d);
888 addDependentLibrary(s, this);
889 d += s.size() + 1;
890 }
891 return &InputSection::discarded;
630892 }
631893 case SHT_RELA:
632894 case SHT_REL: {
......@@ -635,25 +897,25 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
635897 // and the group is discarded, even though it's a violation of the
636898 // spec. We handle that situation gracefully by discarding dangling
637899 // relocation sections.
638 InputSectionBase *Target = getRelocTarget(Sec);
639 if (!Target)
900 InputSectionBase *target = getRelocTarget(sec);
901 if (!target)
640902 return nullptr;
641903
642904 // This section contains relocation information.
643905 // If -r is given, we do not interpret or apply relocation
644906 // but just copy relocation sections to output.
645 if (Config->Relocatable) {
646 InputSection *RelocSec = make<InputSection>(*this, Sec, Name);
907 if (config->relocatable) {
908 InputSection *relocSec = make<InputSection>(*this, sec, name);
647909 // We want to add a dependency to target, similar like we do for
648910 // -emit-relocs below. This is useful for the case when linker script
649911 // contains the "/DISCARD/". It is perhaps uncommon to use a script with
650912 // -r, but we faced it in the Linux kernel and have to handle such case
651913 // and not to crash.
652 Target->DependentSections.push_back(RelocSec);
653 return RelocSec;
914 target->dependentSections.push_back(relocSec);
915 return relocSec;
654916 }
655917
656 if (Target->FirstRelocation)
918 if (target->firstRelocation)
657919 fatal(toString(this) +
658920 ": multiple relocation sections to one section are not supported");
659921
......@@ -662,33 +924,33 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
662924 // because applying relocations at end of linking changes section
663925 // contents. So, we simply handle such sections as non-mergeable ones.
664926 // Degrading like this is acceptable because section merging is optional.
665 if (auto *MS = dyn_cast<MergeInputSection>(Target)) {
666 Target = toRegularSection(MS);
667 this->Sections[Sec.sh_info] = Target;
927 if (auto *ms = dyn_cast<MergeInputSection>(target)) {
928 target = toRegularSection(ms);
929 this->sections[sec.sh_info] = target;
668930 }
669931
670 if (Sec.sh_type == SHT_RELA) {
671 ArrayRef<Elf_Rela> Rels = CHECK(this->getObj().relas(&Sec), this);
672 Target->FirstRelocation = Rels.begin();
673 Target->NumRelocations = Rels.size();
674 Target->AreRelocsRela = true;
932 if (sec.sh_type == SHT_RELA) {
933 ArrayRef<Elf_Rela> rels = CHECK(getObj().relas(&sec), this);
934 target->firstRelocation = rels.begin();
935 target->numRelocations = rels.size();
936 target->areRelocsRela = true;
675937 } else {
676 ArrayRef<Elf_Rel> Rels = CHECK(this->getObj().rels(&Sec), this);
677 Target->FirstRelocation = Rels.begin();
678 Target->NumRelocations = Rels.size();
679 Target->AreRelocsRela = false;
938 ArrayRef<Elf_Rel> rels = CHECK(getObj().rels(&sec), this);
939 target->firstRelocation = rels.begin();
940 target->numRelocations = rels.size();
941 target->areRelocsRela = false;
680942 }
681 assert(isUInt<31>(Target->NumRelocations));
943 assert(isUInt<31>(target->numRelocations));
682944
683945 // Relocation sections processed by the linker are usually removed
684946 // from the output, so returning `nullptr` for the normal case.
685947 // However, if -emit-relocs is given, we need to leave them in the output.
686948 // (Some post link analysis tools need this information.)
687 if (Config->EmitRelocs) {
688 InputSection *RelocSec = make<InputSection>(*this, Sec, Name);
949 if (config->emitRelocs) {
950 InputSection *relocSec = make<InputSection>(*this, sec, name);
689951 // We will not emit relocation section if target was discarded.
690 Target->DependentSections.push_back(RelocSec);
691 return RelocSec;
952 target->dependentSections.push_back(relocSec);
953 return relocSec;
692954 }
693955 return nullptr;
694956 }
......@@ -707,28 +969,42 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
707969 // explicitly told to do otherwise (by -z execstack). Because the stack
708970 // executable-ness is controlled solely by command line options,
709971 // .note.GNU-stack sections are simply ignored.
710 if (Name == ".note.GNU-stack")
711 return &InputSection::Discarded;
972 if (name == ".note.GNU-stack")
973 return &InputSection::discarded;
974
975 // Object files that use processor features such as Intel Control-Flow
976 // Enforcement (CET) or AArch64 Branch Target Identification BTI, use a
977 // .note.gnu.property section containing a bitfield of feature bits like the
978 // GNU_PROPERTY_X86_FEATURE_1_IBT flag. Read a bitmap containing the flag.
979 //
980 // Since we merge bitmaps from multiple object files to create a new
981 // .note.gnu.property containing a single AND'ed bitmap, we discard an input
982 // file's .note.gnu.property section.
983 if (name == ".note.gnu.property") {
984 ArrayRef<uint8_t> contents = check(this->getObj().getSectionContents(&sec));
985 this->andFeatures = readAndFeatures(this, contents);
986 return &InputSection::discarded;
987 }
712988
713989 // Split stacks is a feature to support a discontiguous stack,
714990 // commonly used in the programming language Go. For the details,
715991 // see https://gcc.gnu.org/wiki/SplitStacks. An object file compiled
716992 // for split stack will include a .note.GNU-split-stack section.
717 if (Name == ".note.GNU-split-stack") {
718 if (Config->Relocatable) {
993 if (name == ".note.GNU-split-stack") {
994 if (config->relocatable) {
719995 error("cannot mix split-stack and non-split-stack in a relocatable link");
720 return &InputSection::Discarded;
996 return &InputSection::discarded;
721997 }
722 this->SplitStack = true;
723 return &InputSection::Discarded;
998 this->splitStack = true;
999 return &InputSection::discarded;
7241000 }
7251001
7261002 // An object file cmpiled for split stack, but where some of the
7271003 // functions were compiled with the no_split_stack_attribute will
7281004 // include a .note.GNU-no-split-stack section.
729 if (Name == ".note.GNU-no-split-stack") {
730 this->SomeNoSplitStack = true;
731 return &InputSection::Discarded;
1005 if (name == ".note.GNU-no-split-stack") {
1006 this->someNoSplitStack = true;
1007 return &InputSection::discarded;
7321008 }
7331009
7341010 // The linkonce feature is a sort of proto-comdat. Some glibc i386 object
......@@ -736,246 +1012,205 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
7361012 // sections. Drop those sections to avoid duplicate symbol errors.
7371013 // FIXME: This is glibc PR20543, we should remove this hack once that has been
7381014 // fixed for a while.
739 if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" ||
740 Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx")
741 return &InputSection::Discarded;
1015 if (name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" ||
1016 name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx")
1017 return &InputSection::discarded;
7421018
7431019 // If we are creating a new .build-id section, strip existing .build-id
7441020 // sections so that the output won't have more than one .build-id.
7451021 // This is not usually a problem because input object files normally don't
7461022 // have .build-id sections, but you can create such files by
7471023 // "ld.{bfd,gold,lld} -r --build-id", and we want to guard against it.
748 if (Name == ".note.gnu.build-id" && Config->BuildId != BuildIdKind::None)
749 return &InputSection::Discarded;
1024 if (name == ".note.gnu.build-id" && config->buildId != BuildIdKind::None)
1025 return &InputSection::discarded;
7501026
7511027 // The linker merges EH (exception handling) frames and creates a
7521028 // .eh_frame_hdr section for runtime. So we handle them with a special
7531029 // class. For relocatable outputs, they are just passed through.
754 if (Name == ".eh_frame" && !Config->Relocatable)
755 return make<EhInputSection>(*this, Sec, Name);
1030 if (name == ".eh_frame" && !config->relocatable)
1031 return make<EhInputSection>(*this, sec, name);
7561032
757 if (shouldMerge(Sec))
758 return make<MergeInputSection>(*this, Sec, Name);
759 return make<InputSection>(*this, Sec, Name);
1033 if (shouldMerge(sec))
1034 return make<MergeInputSection>(*this, sec, name);
1035 return make<InputSection>(*this, sec, name);
7601036}
7611037
7621038template <class ELFT>
763StringRef ObjFile<ELFT>::getSectionName(const Elf_Shdr &Sec) {
764 return CHECK(this->getObj().getSectionName(&Sec, SectionStringTable), this);
1039StringRef ObjFile<ELFT>::getSectionName(const Elf_Shdr &sec) {
1040 return CHECK(getObj().getSectionName(&sec, sectionStringTable), this);
7651041}
7661042
1043// Initialize this->Symbols. this->Symbols is a parallel array as
1044// its corresponding ELF symbol table.
7671045template <class ELFT> void ObjFile<ELFT>::initializeSymbols() {
768 this->Symbols.reserve(this->ELFSyms.size());
769 for (const Elf_Sym &Sym : this->ELFSyms)
770 this->Symbols.push_back(createSymbol(&Sym));
771}
772
773template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
774 int Binding = Sym->getBinding();
775
776 uint32_t SecIdx = this->getSectionIndex(*Sym);
777 if (SecIdx >= this->Sections.size())
778 fatal(toString(this) + ": invalid section index: " + Twine(SecIdx));
779
780 InputSectionBase *Sec = this->Sections[SecIdx];
781 uint8_t StOther = Sym->st_other;
782 uint8_t Type = Sym->getType();
783 uint64_t Value = Sym->st_value;
784 uint64_t Size = Sym->st_size;
785
786 if (Binding == STB_LOCAL) {
787 if (Sym->getType() == STT_FILE)
788 SourceFile = CHECK(Sym->getName(this->StringTable), this);
1046 ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>();
1047 this->symbols.resize(eSyms.size());
1048
1049 // Our symbol table may have already been partially initialized
1050 // because of LazyObjFile.
1051 for (size_t i = 0, end = eSyms.size(); i != end; ++i)
1052 if (!this->symbols[i] && eSyms[i].getBinding() != STB_LOCAL)
1053 this->symbols[i] =
1054 symtab->insert(CHECK(eSyms[i].getName(this->stringTable), this));
1055
1056 // Fill this->Symbols. A symbol is either local or global.
1057 for (size_t i = 0, end = eSyms.size(); i != end; ++i) {
1058 const Elf_Sym &eSym = eSyms[i];
1059
1060 // Read symbol attributes.
1061 uint32_t secIdx = getSectionIndex(eSym);
1062 if (secIdx >= this->sections.size())
1063 fatal(toString(this) + ": invalid section index: " + Twine(secIdx));
1064
1065 InputSectionBase *sec = this->sections[secIdx];
1066 uint8_t binding = eSym.getBinding();
1067 uint8_t stOther = eSym.st_other;
1068 uint8_t type = eSym.getType();
1069 uint64_t value = eSym.st_value;
1070 uint64_t size = eSym.st_size;
1071 StringRefZ name = this->stringTable.data() + eSym.st_name;
1072
1073 // Handle local symbols. Local symbols are not added to the symbol
1074 // table because they are not visible from other object files. We
1075 // allocate symbol instances and add their pointers to Symbols.
1076 if (binding == STB_LOCAL) {
1077 if (eSym.getType() == STT_FILE)
1078 sourceFile = CHECK(eSym.getName(this->stringTable), this);
1079
1080 if (this->stringTable.size() <= eSym.st_name)
1081 fatal(toString(this) + ": invalid symbol name offset");
1082
1083 if (eSym.st_shndx == SHN_UNDEF)
1084 this->symbols[i] = make<Undefined>(this, name, binding, stOther, type);
1085 else if (sec == &InputSection::discarded)
1086 this->symbols[i] = make<Undefined>(this, name, binding, stOther, type,
1087 /*DiscardedSecIdx=*/secIdx);
1088 else
1089 this->symbols[i] =
1090 make<Defined>(this, name, binding, stOther, type, value, size, sec);
1091 continue;
1092 }
7891093
790 if (this->StringTable.size() <= Sym->st_name)
791 fatal(toString(this) + ": invalid symbol name offset");
1094 // Handle global undefined symbols.
1095 if (eSym.st_shndx == SHN_UNDEF) {
1096 this->symbols[i]->resolve(Undefined{this, name, binding, stOther, type});
1097 continue;
1098 }
7921099
793 StringRefZ Name = this->StringTable.data() + Sym->st_name;
794 if (Sym->st_shndx == SHN_UNDEF)
795 return make<Undefined>(this, Name, Binding, StOther, Type);
1100 // Handle global common symbols.
1101 if (eSym.st_shndx == SHN_COMMON) {
1102 if (value == 0 || value >= UINT32_MAX)
1103 fatal(toString(this) + ": common symbol '" + StringRef(name.data) +
1104 "' has invalid alignment: " + Twine(value));
1105 this->symbols[i]->resolve(
1106 CommonSymbol{this, name, binding, stOther, type, value, size});
1107 continue;
1108 }
7961109
797 return make<Defined>(this, Name, Binding, StOther, Type, Value, Size, Sec);
798 }
1110 // If a defined symbol is in a discarded section, handle it as if it
1111 // were an undefined symbol. Such symbol doesn't comply with the
1112 // standard, but in practice, a .eh_frame often directly refer
1113 // COMDAT member sections, and if a comdat group is discarded, some
1114 // defined symbol in a .eh_frame becomes dangling symbols.
1115 if (sec == &InputSection::discarded) {
1116 this->symbols[i]->resolve(
1117 Undefined{this, name, binding, stOther, type, secIdx});
1118 continue;
1119 }
7991120
800 StringRef Name = CHECK(Sym->getName(this->StringTable), this);
801
802 switch (Sym->st_shndx) {
803 case SHN_UNDEF:
804 return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
805 /*CanOmitFromDynSym=*/false, this);
806 case SHN_COMMON:
807 if (Value == 0 || Value >= UINT32_MAX)
808 fatal(toString(this) + ": common symbol '" + Name +
809 "' has invalid alignment: " + Twine(Value));
810 return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, *this);
811 }
1121 // Handle global defined symbols.
1122 if (binding == STB_GLOBAL || binding == STB_WEAK ||
1123 binding == STB_GNU_UNIQUE) {
1124 this->symbols[i]->resolve(
1125 Defined{this, name, binding, stOther, type, value, size, sec});
1126 continue;
1127 }
8121128
813 switch (Binding) {
814 default:
815 fatal(toString(this) + ": unexpected binding: " + Twine(Binding));
816 case STB_GLOBAL:
817 case STB_WEAK:
818 case STB_GNU_UNIQUE:
819 if (Sec == &InputSection::Discarded)
820 return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
821 /*CanOmitFromDynSym=*/false, this);
822 return Symtab->addDefined(Name, StOther, Type, Value, Size, Binding, Sec,
823 this);
1129 fatal(toString(this) + ": unexpected binding: " + Twine((int)binding));
8241130 }
8251131}
8261132
827ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
828 : InputFile(ArchiveKind, File->getMemoryBufferRef()),
829 File(std::move(File)) {}
1133ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&file)
1134 : InputFile(ArchiveKind, file->getMemoryBufferRef()),
1135 file(std::move(file)) {}
8301136
831template <class ELFT> void ArchiveFile::parse() {
832 for (const Archive::Symbol &Sym : File->symbols())
833 Symtab->addLazyArchive<ELFT>(Sym.getName(), *this, Sym);
1137void ArchiveFile::parse() {
1138 for (const Archive::Symbol &sym : file->symbols())
1139 symtab->addSymbol(LazyArchive{*this, sym});
8341140}
8351141
8361142// Returns a buffer pointing to a member file containing a given symbol.
837InputFile *ArchiveFile::fetch(const Archive::Symbol &Sym) {
838 Archive::Child C =
839 CHECK(Sym.getMember(), toString(this) +
1143void ArchiveFile::fetch(const Archive::Symbol &sym) {
1144 Archive::Child c =
1145 CHECK(sym.getMember(), toString(this) +
8401146 ": could not get the member for symbol " +
841 Sym.getName());
1147 sym.getName());
8421148
843 if (!Seen.insert(C.getChildOffset()).second)
844 return nullptr;
1149 if (!seen.insert(c.getChildOffset()).second)
1150 return;
8451151
846 MemoryBufferRef MB =
847 CHECK(C.getMemoryBufferRef(),
1152 MemoryBufferRef mb =
1153 CHECK(c.getMemoryBufferRef(),
8481154 toString(this) +
8491155 ": could not get the buffer for the member defining symbol " +
850 Sym.getName());
851
852 if (Tar && C.getParent()->isThin())
853 Tar->append(relativeToRoot(CHECK(C.getFullName(), this)), MB.getBuffer());
854
855 InputFile *File = createObjectFile(
856 MB, getName(), C.getParent()->isThin() ? 0 : C.getChildOffset());
857 File->GroupId = GroupId;
858 return File;
859}
860
861template <class ELFT>
862SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
863 : ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName),
864 IsNeeded(!Config->AsNeeded) {}
865
866// Partially parse the shared object file so that we can call
867// getSoName on this object.
868template <class ELFT> void SharedFile<ELFT>::parseSoName() {
869 const Elf_Shdr *DynamicSec = nullptr;
870 const ELFFile<ELFT> Obj = this->getObj();
871 ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
872
873 // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
874 for (const Elf_Shdr &Sec : Sections) {
875 switch (Sec.sh_type) {
876 default:
877 continue;
878 case SHT_DYNSYM:
879 this->initSymtab(Sections, &Sec);
880 break;
881 case SHT_DYNAMIC:
882 DynamicSec = &Sec;
883 break;
884 case SHT_SYMTAB_SHNDX:
885 this->SymtabSHNDX = CHECK(Obj.getSHNDXTable(Sec, Sections), this);
886 break;
887 case SHT_GNU_versym:
888 this->VersymSec = &Sec;
889 break;
890 case SHT_GNU_verdef:
891 this->VerdefSec = &Sec;
892 break;
893 }
894 }
1156 sym.getName());
8951157
896 if (this->VersymSec && this->ELFSyms.empty())
897 error("SHT_GNU_versym should be associated with symbol table");
1158 if (tar && c.getParent()->isThin())
1159 tar->append(relativeToRoot(CHECK(c.getFullName(), this)), mb.getBuffer());
8981160
899 // Search for a DT_SONAME tag to initialize this->SoName.
900 if (!DynamicSec)
901 return;
902 ArrayRef<Elf_Dyn> Arr =
903 CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec), this);
904 for (const Elf_Dyn &Dyn : Arr) {
905 if (Dyn.d_tag == DT_SONAME) {
906 uint64_t Val = Dyn.getVal();
907 if (Val >= this->StringTable.size())
908 fatal(toString(this) + ": invalid DT_SONAME entry");
909 SoName = this->StringTable.data() + Val;
910 return;
911 }
912 }
1161 InputFile *file = createObjectFile(
1162 mb, getName(), c.getParent()->isThin() ? 0 : c.getChildOffset());
1163 file->groupId = groupId;
1164 parseFile(file);
9131165}
9141166
915// Parses ".gnu.version" section which is a parallel array for the symbol table.
916// If a given file doesn't have ".gnu.version" section, returns VER_NDX_GLOBAL.
917template <class ELFT> std::vector<uint32_t> SharedFile<ELFT>::parseVersyms() {
918 size_t Size = this->ELFSyms.size() - this->FirstGlobal;
919 if (!VersymSec)
920 return std::vector<uint32_t>(Size, VER_NDX_GLOBAL);
921
922 const char *Base = this->MB.getBuffer().data();
923 const Elf_Versym *Versym =
924 reinterpret_cast<const Elf_Versym *>(Base + VersymSec->sh_offset) +
925 this->FirstGlobal;
926
927 std::vector<uint32_t> Ret(Size);
928 for (size_t I = 0; I < Size; ++I)
929 Ret[I] = Versym[I].vs_index;
930 return Ret;
931}
1167unsigned SharedFile::vernauxNum;
9321168
933// Parse the version definitions in the object file if present. Returns a vector
934// whose nth element contains a pointer to the Elf_Verdef for version identifier
935// n. Version identifiers that are not definitions map to nullptr.
936template <class ELFT>
937std::vector<const typename ELFT::Verdef *> SharedFile<ELFT>::parseVerdefs() {
938 if (!VerdefSec)
1169// Parse the version definitions in the object file if present, and return a
1170// vector whose nth element contains a pointer to the Elf_Verdef for version
1171// identifier n. Version identifiers that are not definitions map to nullptr.
1172template <typename ELFT>
1173static std::vector<const void *> parseVerdefs(const uint8_t *base,
1174 const typename ELFT::Shdr *sec) {
1175 if (!sec)
9391176 return {};
9401177
9411178 // We cannot determine the largest verdef identifier without inspecting
9421179 // every Elf_Verdef, but both bfd and gold assign verdef identifiers
9431180 // sequentially starting from 1, so we predict that the largest identifier
944 // will be VerdefCount.
945 unsigned VerdefCount = VerdefSec->sh_info;
946 std::vector<const Elf_Verdef *> Verdefs(VerdefCount + 1);
1181 // will be verdefCount.
1182 unsigned verdefCount = sec->sh_info;
1183 std::vector<const void *> verdefs(verdefCount + 1);
9471184
9481185 // Build the Verdefs array by following the chain of Elf_Verdef objects
9491186 // from the start of the .gnu.version_d section.
950 const char *Base = this->MB.getBuffer().data();
951 const char *Verdef = Base + VerdefSec->sh_offset;
952 for (unsigned I = 0; I != VerdefCount; ++I) {
953 auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef);
954 Verdef += CurVerdef->vd_next;
955 unsigned VerdefIndex = CurVerdef->vd_ndx;
956 Verdefs.resize(VerdefIndex + 1);
957 Verdefs[VerdefIndex] = CurVerdef;
1187 const uint8_t *verdef = base + sec->sh_offset;
1188 for (unsigned i = 0; i != verdefCount; ++i) {
1189 auto *curVerdef = reinterpret_cast<const typename ELFT::Verdef *>(verdef);
1190 verdef += curVerdef->vd_next;
1191 unsigned verdefIndex = curVerdef->vd_ndx;
1192 verdefs.resize(verdefIndex + 1);
1193 verdefs[verdefIndex] = curVerdef;
9581194 }
959
960 return Verdefs;
1195 return verdefs;
9611196}
9621197
9631198// We do not usually care about alignments of data in shared object
9641199// files because the loader takes care of it. However, if we promote a
9651200// DSO symbol to point to .bss due to copy relocation, we need to keep
9661201// the original alignment requirements. We infer it in this function.
967template <class ELFT>
968uint32_t SharedFile<ELFT>::getAlignment(ArrayRef<Elf_Shdr> Sections,
969 const Elf_Sym &Sym) {
970 uint64_t Ret = UINT64_MAX;
971 if (Sym.st_value)
972 Ret = 1ULL << countTrailingZeros((uint64_t)Sym.st_value);
973 if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size())
974 Ret = std::min<uint64_t>(Ret, Sections[Sym.st_shndx].sh_addralign);
975 return (Ret > UINT32_MAX) ? 0 : Ret;
1202template <typename ELFT>
1203static uint64_t getAlignment(ArrayRef<typename ELFT::Shdr> sections,
1204 const typename ELFT::Sym &sym) {
1205 uint64_t ret = UINT64_MAX;
1206 if (sym.st_value)
1207 ret = 1ULL << countTrailingZeros((uint64_t)sym.st_value);
1208 if (0 < sym.st_shndx && sym.st_shndx < sections.size())
1209 ret = std::min<uint64_t>(ret, sections[sym.st_shndx].sh_addralign);
1210 return (ret > UINT32_MAX) ? 0 : ret;
9761211}
9771212
978// Fully parse the shared object file. This must be called after parseSoName().
1213// Fully parse the shared object file.
9791214//
9801215// This function parses symbol versions. If a DSO has version information,
9811216// the file has a ".gnu.version_d" section which contains symbol version
......@@ -990,80 +1225,163 @@ uint32_t SharedFile<ELFT>::getAlignment(ArrayRef<Elf_Shdr> Sections,
9901225// The file format for symbol versioning is perhaps a bit more complicated
9911226// than necessary, but you can easily understand the code if you wrap your
9921227// head around the data structure described above.
993template <class ELFT> void SharedFile<ELFT>::parseRest() {
994 Verdefs = parseVerdefs(); // parse .gnu.version_d
995 std::vector<uint32_t> Versyms = parseVersyms(); // parse .gnu.version
996 ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this);
1228template <class ELFT> void SharedFile::parse() {
1229 using Elf_Dyn = typename ELFT::Dyn;
1230 using Elf_Shdr = typename ELFT::Shdr;
1231 using Elf_Sym = typename ELFT::Sym;
1232 using Elf_Verdef = typename ELFT::Verdef;
1233 using Elf_Versym = typename ELFT::Versym;
1234
1235 ArrayRef<Elf_Dyn> dynamicTags;
1236 const ELFFile<ELFT> obj = this->getObj<ELFT>();
1237 ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
1238
1239 const Elf_Shdr *versymSec = nullptr;
1240 const Elf_Shdr *verdefSec = nullptr;
1241
1242 // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
1243 for (const Elf_Shdr &sec : sections) {
1244 switch (sec.sh_type) {
1245 default:
1246 continue;
1247 case SHT_DYNAMIC:
1248 dynamicTags =
1249 CHECK(obj.template getSectionContentsAsArray<Elf_Dyn>(&sec), this);
1250 break;
1251 case SHT_GNU_versym:
1252 versymSec = &sec;
1253 break;
1254 case SHT_GNU_verdef:
1255 verdefSec = &sec;
1256 break;
1257 }
1258 }
1259
1260 if (versymSec && numELFSyms == 0) {
1261 error("SHT_GNU_versym should be associated with symbol table");
1262 return;
1263 }
1264
1265 // Search for a DT_SONAME tag to initialize this->soName.
1266 for (const Elf_Dyn &dyn : dynamicTags) {
1267 if (dyn.d_tag == DT_NEEDED) {
1268 uint64_t val = dyn.getVal();
1269 if (val >= this->stringTable.size())
1270 fatal(toString(this) + ": invalid DT_NEEDED entry");
1271 dtNeeded.push_back(this->stringTable.data() + val);
1272 } else if (dyn.d_tag == DT_SONAME) {
1273 uint64_t val = dyn.getVal();
1274 if (val >= this->stringTable.size())
1275 fatal(toString(this) + ": invalid DT_SONAME entry");
1276 soName = this->stringTable.data() + val;
1277 }
1278 }
1279
1280 // DSOs are uniquified not by filename but by soname.
1281 DenseMap<StringRef, SharedFile *>::iterator it;
1282 bool wasInserted;
1283 std::tie(it, wasInserted) = symtab->soNames.try_emplace(soName, this);
1284
1285 // If a DSO appears more than once on the command line with and without
1286 // --as-needed, --no-as-needed takes precedence over --as-needed because a
1287 // user can add an extra DSO with --no-as-needed to force it to be added to
1288 // the dependency list.
1289 it->second->isNeeded |= isNeeded;
1290 if (!wasInserted)
1291 return;
1292
1293 sharedFiles.push_back(this);
1294
1295 verdefs = parseVerdefs<ELFT>(obj.base(), verdefSec);
1296
1297 // Parse ".gnu.version" section which is a parallel array for the symbol
1298 // table. If a given file doesn't have a ".gnu.version" section, we use
1299 // VER_NDX_GLOBAL.
1300 size_t size = numELFSyms - firstGlobal;
1301 std::vector<uint32_t> versyms(size, VER_NDX_GLOBAL);
1302 if (versymSec) {
1303 ArrayRef<Elf_Versym> versym =
1304 CHECK(obj.template getSectionContentsAsArray<Elf_Versym>(versymSec),
1305 this)
1306 .slice(firstGlobal);
1307 for (size_t i = 0; i < size; ++i)
1308 versyms[i] = versym[i].vs_index;
1309 }
9971310
9981311 // System libraries can have a lot of symbols with versions. Using a
9991312 // fixed buffer for computing the versions name (foo@ver) can save a
10001313 // lot of allocations.
1001 SmallString<0> VersionedNameBuffer;
1314 SmallString<0> versionedNameBuffer;
10021315
10031316 // Add symbols to the symbol table.
1004 ArrayRef<Elf_Sym> Syms = this->getGlobalELFSyms();
1005 for (size_t I = 0; I < Syms.size(); ++I) {
1006 const Elf_Sym &Sym = Syms[I];
1317 ArrayRef<Elf_Sym> syms = this->getGlobalELFSyms<ELFT>();
1318 for (size_t i = 0; i < syms.size(); ++i) {
1319 const Elf_Sym &sym = syms[i];
10071320
10081321 // ELF spec requires that all local symbols precede weak or global
10091322 // symbols in each symbol table, and the index of first non-local symbol
10101323 // is stored to sh_info. If a local symbol appears after some non-local
10111324 // symbol, that's a violation of the spec.
1012 StringRef Name = CHECK(Sym.getName(this->StringTable), this);
1013 if (Sym.getBinding() == STB_LOCAL) {
1014 warn("found local symbol '" + Name +
1325 StringRef name = CHECK(sym.getName(this->stringTable), this);
1326 if (sym.getBinding() == STB_LOCAL) {
1327 warn("found local symbol '" + name +
10151328 "' in global part of symbol table in file " + toString(this));
10161329 continue;
10171330 }
10181331
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;
1332 if (sym.isUndefined()) {
1333 Symbol *s = symtab->addSymbol(
1334 Undefined{this, name, sym.getBinding(), sym.st_other, sym.getType()});
1335 s->exportDynamic = true;
10241336 continue;
10251337 }
10261338
10271339 // MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly
10281340 // assigns VER_NDX_LOCAL to this section global symbol. Here is a
10291341 // workaround for this bug.
1030 uint32_t Idx = Versyms[I] & ~VERSYM_HIDDEN;
1031 if (Config->EMachine == EM_MIPS && Idx == VER_NDX_LOCAL &&
1032 Name == "_gp_disp")
1342 uint32_t idx = versyms[i] & ~VERSYM_HIDDEN;
1343 if (config->emachine == EM_MIPS && idx == VER_NDX_LOCAL &&
1344 name == "_gp_disp")
10331345 continue;
10341346
1035 uint64_t Alignment = getAlignment(Sections, Sym);
1036 if (!(Versyms[I] & VERSYM_HIDDEN))
1037 Symtab->addShared(Name, *this, Sym, Alignment, Idx);
1347 uint32_t alignment = getAlignment<ELFT>(sections, sym);
1348 if (!(versyms[i] & VERSYM_HIDDEN)) {
1349 symtab->addSymbol(SharedSymbol{*this, name, sym.getBinding(),
1350 sym.st_other, sym.getType(), sym.st_value,
1351 sym.st_size, alignment, idx});
1352 }
10381353
10391354 // Also add the symbol with the versioned name to handle undefined symbols
10401355 // with explicit versions.
1041 if (Idx == VER_NDX_GLOBAL)
1356 if (idx == VER_NDX_GLOBAL)
10421357 continue;
10431358
1044 if (Idx >= Verdefs.size() || Idx == VER_NDX_LOCAL) {
1045 error("corrupt input file: version definition index " + Twine(Idx) +
1046 " for symbol " + Name + " is out of bounds\n>>> defined in " +
1359 if (idx >= verdefs.size() || idx == VER_NDX_LOCAL) {
1360 error("corrupt input file: version definition index " + Twine(idx) +
1361 " for symbol " + name + " is out of bounds\n>>> defined in " +
10471362 toString(this));
10481363 continue;
10491364 }
10501365
1051 StringRef VerName =
1052 this->StringTable.data() + Verdefs[Idx]->getAux()->vda_name;
1053 VersionedNameBuffer.clear();
1054 Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer);
1055 Symtab->addShared(Saver.save(Name), *this, Sym, Alignment, Idx);
1366 StringRef verName =
1367 this->stringTable.data() +
1368 reinterpret_cast<const Elf_Verdef *>(verdefs[idx])->getAux()->vda_name;
1369 versionedNameBuffer.clear();
1370 name = (name + "@" + verName).toStringRef(versionedNameBuffer);
1371 symtab->addSymbol(SharedSymbol{*this, saver.save(name), sym.getBinding(),
1372 sym.st_other, sym.getType(), sym.st_value,
1373 sym.st_size, alignment, idx});
10561374 }
10571375}
10581376
1059static ELFKind getBitcodeELFKind(const Triple &T) {
1060 if (T.isLittleEndian())
1061 return T.isArch64Bit() ? ELF64LEKind : ELF32LEKind;
1062 return T.isArch64Bit() ? ELF64BEKind : ELF32BEKind;
1377static ELFKind getBitcodeELFKind(const Triple &t) {
1378 if (t.isLittleEndian())
1379 return t.isArch64Bit() ? ELF64LEKind : ELF32LEKind;
1380 return t.isArch64Bit() ? ELF64BEKind : ELF32BEKind;
10631381}
10641382
1065static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
1066 switch (T.getArch()) {
1383static uint8_t getBitcodeMachineKind(StringRef path, const Triple &t) {
1384 switch (t.getArch()) {
10671385 case Triple::aarch64:
10681386 return EM_AARCH64;
10691387 case Triple::amdgcn:
......@@ -1086,25 +1404,28 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
10861404 case Triple::ppc64:
10871405 case Triple::ppc64le:
10881406 return EM_PPC64;
1407 case Triple::riscv32:
1408 case Triple::riscv64:
1409 return EM_RISCV;
10891410 case Triple::x86:
1090 return T.isOSIAMCU() ? EM_IAMCU : EM_386;
1411 return t.isOSIAMCU() ? EM_IAMCU : EM_386;
10911412 case Triple::x86_64:
10921413 return EM_X86_64;
10931414 default:
1094 error(Path + ": could not infer e_machine from bitcode target triple " +
1095 T.str());
1415 error(path + ": could not infer e_machine from bitcode target triple " +
1416 t.str());
10961417 return EM_NONE;
10971418 }
10981419}
10991420
1100BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
1101 uint64_t OffsetInArchive)
1102 : InputFile(BitcodeKind, MB) {
1103 this->ArchiveName = ArchiveName;
1421BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
1422 uint64_t offsetInArchive)
1423 : InputFile(BitcodeKind, mb) {
1424 this->archiveName = archiveName;
11041425
1105 std::string Path = MB.getBufferIdentifier().str();
1106 if (Config->ThinLTOIndexOnly)
1107 Path = replaceThinLTOSuffix(MB.getBufferIdentifier());
1426 std::string path = mb.getBufferIdentifier().str();
1427 if (config->thinLTOIndexOnly)
1428 path = replaceThinLTOSuffix(mb.getBufferIdentifier());
11081429
11091430 // ThinLTO assumes that all MemoryBufferRefs given to it have a unique
11101431 // name. If two archives define two members with the same name, this
......@@ -1112,20 +1433,21 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
11121433 // into consideration at LTO time (which very likely causes undefined
11131434 // symbols later in the link stage). So we append file offset to make
11141435 // filename unique.
1115 MemoryBufferRef MBRef(
1116 MB.getBuffer(),
1117 Saver.save(ArchiveName + Path +
1118 (ArchiveName.empty() ? "" : utostr(OffsetInArchive))));
1436 StringRef name = archiveName.empty()
1437 ? saver.save(path)
1438 : saver.save(archiveName + "(" + path + " at " +
1439 utostr(offsetInArchive) + ")");
1440 MemoryBufferRef mbref(mb.getBuffer(), name);
11191441
1120 Obj = CHECK(lto::InputFile::create(MBRef), this);
1442 obj = CHECK(lto::InputFile::create(mbref), this);
11211443
1122 Triple T(Obj->getTargetTriple());
1123 EKind = getBitcodeELFKind(T);
1124 EMachine = getBitcodeMachineKind(MB.getBufferIdentifier(), T);
1444 Triple t(obj->getTargetTriple());
1445 ekind = getBitcodeELFKind(t);
1446 emachine = getBitcodeMachineKind(mb.getBufferIdentifier(), t);
11251447}
11261448
1127static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
1128 switch (GvVisibility) {
1449static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
1450 switch (gvVisibility) {
11291451 case GlobalValue::DefaultVisibility:
11301452 return STV_DEFAULT;
11311453 case GlobalValue::HiddenVisibility:
......@@ -1137,209 +1459,187 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
11371459}
11381460
11391461template <class ELFT>
1140static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
1141 const lto::InputFile::Symbol &ObjSym,
1142 BitcodeFile &F) {
1143 StringRef Name = Saver.save(ObjSym.getName());
1144 uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
1145
1146 uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE;
1147 uint8_t Visibility = mapVisibility(ObjSym.getVisibility());
1148 bool CanOmitFromDynSym = ObjSym.canBeOmittedFromSymbolTable();
1149
1150 int C = ObjSym.getComdatIndex();
1151 if (C != -1 && !KeptComdats[C])
1152 return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
1153 CanOmitFromDynSym, &F);
1154
1155 if (ObjSym.isUndefined())
1156 return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type,
1157 CanOmitFromDynSym, &F);
1158
1159 if (ObjSym.isCommon())
1160 return Symtab->addCommon(Name, ObjSym.getCommonSize(),
1161 ObjSym.getCommonAlignment(), Binding, Visibility,
1162 STT_OBJECT, F);
1163
1164 return Symtab->addBitcode(Name, Binding, Visibility, Type, CanOmitFromDynSym,
1165 F);
1166}
1462static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
1463 const lto::InputFile::Symbol &objSym,
1464 BitcodeFile &f) {
1465 StringRef name = saver.save(objSym.getName());
1466 uint8_t binding = objSym.isWeak() ? STB_WEAK : STB_GLOBAL;
1467 uint8_t type = objSym.isTLS() ? STT_TLS : STT_NOTYPE;
1468 uint8_t visibility = mapVisibility(objSym.getVisibility());
1469 bool canOmitFromDynSym = objSym.canBeOmittedFromSymbolTable();
1470
1471 int c = objSym.getComdatIndex();
1472 if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {
1473 Undefined New(&f, name, binding, visibility, type);
1474 if (canOmitFromDynSym)
1475 New.exportDynamic = false;
1476 return symtab->addSymbol(New);
1477 }
11671478
1168template <class ELFT>
1169void BitcodeFile::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
1170 std::vector<bool> KeptComdats;
1171 for (StringRef S : Obj->getComdatTable())
1172 KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second);
1479 if (objSym.isCommon())
1480 return symtab->addSymbol(
1481 CommonSymbol{&f, name, binding, visibility, STT_OBJECT,
1482 objSym.getCommonAlignment(), objSym.getCommonSize()});
11731483
1174 for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
1175 Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, *this));
1484 Defined New(&f, name, binding, visibility, type, 0, 0, nullptr);
1485 if (canOmitFromDynSym)
1486 New.exportDynamic = false;
1487 return symtab->addSymbol(New);
11761488}
11771489
1178static ELFKind getELFKind(MemoryBufferRef MB) {
1179 unsigned char Size;
1180 unsigned char Endian;
1181 std::tie(Size, Endian) = getElfArchType(MB.getBuffer());
1182
1183 if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
1184 fatal(MB.getBufferIdentifier() + ": invalid data encoding");
1185 if (Size != ELFCLASS32 && Size != ELFCLASS64)
1186 fatal(MB.getBufferIdentifier() + ": invalid file class");
1490template <class ELFT> void BitcodeFile::parse() {
1491 std::vector<bool> keptComdats;
1492 for (StringRef s : obj->getComdatTable())
1493 keptComdats.push_back(
1494 symtab->comdatGroups.try_emplace(CachedHashStringRef(s), this).second);
11871495
1188 size_t BufSize = MB.getBuffer().size();
1189 if ((Size == ELFCLASS32 && BufSize < sizeof(Elf32_Ehdr)) ||
1190 (Size == ELFCLASS64 && BufSize < sizeof(Elf64_Ehdr)))
1191 fatal(MB.getBufferIdentifier() + ": file is too short");
1496 for (const lto::InputFile::Symbol &objSym : obj->symbols())
1497 symbols.push_back(createBitcodeSymbol<ELFT>(keptComdats, objSym, *this));
11921498
1193 if (Size == ELFCLASS32)
1194 return (Endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;
1195 return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
1499 for (auto l : obj->getDependentLibraries())
1500 addDependentLibrary(l, this);
11961501}
11971502
11981503void BinaryFile::parse() {
1199 ArrayRef<uint8_t> Data = arrayRefFromStringRef(MB.getBuffer());
1200 auto *Section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
1201 8, Data, ".data");
1202 Sections.push_back(Section);
1504 ArrayRef<uint8_t> data = arrayRefFromStringRef(mb.getBuffer());
1505 auto *section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
1506 8, data, ".data");
1507 sections.push_back(section);
12031508
12041509 // For each input file foo that is embedded to a result as a binary
12051510 // blob, we define _binary_foo_{start,end,size} symbols, so that
12061511 // user programs can access blobs by name. Non-alphanumeric
12071512 // characters in a filename are replaced with underscore.
1208 std::string S = "_binary_" + MB.getBufferIdentifier().str();
1209 for (size_t I = 0; I < S.size(); ++I)
1210 if (!isAlnum(S[I]))
1211 S[I] = '_';
1212
1213 Symtab->addDefined(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT, 0, 0,
1214 STB_GLOBAL, Section, nullptr);
1215 Symtab->addDefined(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
1216 Data.size(), 0, STB_GLOBAL, Section, nullptr);
1217 Symtab->addDefined(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,
1218 Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
1513 std::string s = "_binary_" + mb.getBufferIdentifier().str();
1514 for (size_t i = 0; i < s.size(); ++i)
1515 if (!isAlnum(s[i]))
1516 s[i] = '_';
1517
1518 symtab->addSymbol(Defined{nullptr, saver.save(s + "_start"), STB_GLOBAL,
1519 STV_DEFAULT, STT_OBJECT, 0, 0, section});
1520 symtab->addSymbol(Defined{nullptr, saver.save(s + "_end"), STB_GLOBAL,
1521 STV_DEFAULT, STT_OBJECT, data.size(), 0, section});
1522 symtab->addSymbol(Defined{nullptr, saver.save(s + "_size"), STB_GLOBAL,
1523 STV_DEFAULT, STT_OBJECT, data.size(), 0, nullptr});
12191524}
12201525
1221InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
1222 uint64_t OffsetInArchive) {
1223 if (isBitcode(MB))
1224 return make<BitcodeFile>(MB, ArchiveName, OffsetInArchive);
1526InputFile *elf::createObjectFile(MemoryBufferRef mb, StringRef archiveName,
1527 uint64_t offsetInArchive) {
1528 if (isBitcode(mb))
1529 return make<BitcodeFile>(mb, archiveName, offsetInArchive);
12251530
1226 switch (getELFKind(MB)) {
1531 switch (getELFKind(mb, archiveName)) {
12271532 case ELF32LEKind:
1228 return make<ObjFile<ELF32LE>>(MB, ArchiveName);
1533 return make<ObjFile<ELF32LE>>(mb, archiveName);
12291534 case ELF32BEKind:
1230 return make<ObjFile<ELF32BE>>(MB, ArchiveName);
1535 return make<ObjFile<ELF32BE>>(mb, archiveName);
12311536 case ELF64LEKind:
1232 return make<ObjFile<ELF64LE>>(MB, ArchiveName);
1537 return make<ObjFile<ELF64LE>>(mb, archiveName);
12331538 case ELF64BEKind:
1234 return make<ObjFile<ELF64BE>>(MB, ArchiveName);
1539 return make<ObjFile<ELF64BE>>(mb, archiveName);
12351540 default:
12361541 llvm_unreachable("getELFKind");
12371542 }
12381543}
12391544
1240InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) {
1241 switch (getELFKind(MB)) {
1242 case ELF32LEKind:
1243 return make<SharedFile<ELF32LE>>(MB, DefaultSoName);
1244 case ELF32BEKind:
1245 return make<SharedFile<ELF32BE>>(MB, DefaultSoName);
1246 case ELF64LEKind:
1247 return make<SharedFile<ELF64LE>>(MB, DefaultSoName);
1248 case ELF64BEKind:
1249 return make<SharedFile<ELF64BE>>(MB, DefaultSoName);
1250 default:
1251 llvm_unreachable("getELFKind");
1252 }
1253}
1545void LazyObjFile::fetch() {
1546 if (mb.getBuffer().empty())
1547 return;
12541548
1255MemoryBufferRef LazyObjFile::getBuffer() {
1256 if (AddedToLink)
1257 return MemoryBufferRef();
1258 AddedToLink = true;
1259 return MB;
1260}
1549 InputFile *file = createObjectFile(mb, archiveName, offsetInArchive);
1550 file->groupId = groupId;
12611551
1262InputFile *LazyObjFile::fetch() {
1263 MemoryBufferRef MBRef = getBuffer();
1264 if (MBRef.getBuffer().empty())
1265 return nullptr;
1552 mb = {};
1553
1554 // Copy symbol vector so that the new InputFile doesn't have to
1555 // insert the same defined symbols to the symbol table again.
1556 file->symbols = std::move(symbols);
12661557
1267 InputFile *File = createObjectFile(MBRef, ArchiveName, OffsetInArchive);
1268 File->GroupId = GroupId;
1269 return File;
1558 parseFile(file);
12701559}
12711560
12721561template <class ELFT> void LazyObjFile::parse() {
1562 using Elf_Sym = typename ELFT::Sym;
1563
12731564 // A lazy object file wraps either a bitcode file or an ELF file.
1274 if (isBitcode(this->MB)) {
1275 std::unique_ptr<lto::InputFile> Obj =
1276 CHECK(lto::InputFile::create(this->MB), this);
1277 for (const lto::InputFile::Symbol &Sym : Obj->symbols())
1278 if (!Sym.isUndefined())
1279 Symtab->addLazyObject<ELFT>(Saver.save(Sym.getName()), *this);
1565 if (isBitcode(this->mb)) {
1566 std::unique_ptr<lto::InputFile> obj =
1567 CHECK(lto::InputFile::create(this->mb), this);
1568 for (const lto::InputFile::Symbol &sym : obj->symbols()) {
1569 if (sym.isUndefined())
1570 continue;
1571 symtab->addSymbol(LazyObject{*this, saver.save(sym.getName())});
1572 }
12801573 return;
12811574 }
12821575
1283 if (getELFKind(this->MB) != Config->EKind) {
1284 error("incompatible file: " + this->MB.getBufferIdentifier());
1576 if (getELFKind(this->mb, archiveName) != config->ekind) {
1577 error("incompatible file: " + this->mb.getBufferIdentifier());
12851578 return;
12861579 }
12871580
1288 ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer()));
1289 ArrayRef<typename ELFT::Shdr> Sections = CHECK(Obj.sections(), this);
1581 // Find a symbol table.
1582 ELFFile<ELFT> obj = check(ELFFile<ELFT>::create(mb.getBuffer()));
1583 ArrayRef<typename ELFT::Shdr> sections = CHECK(obj.sections(), this);
12901584
1291 for (const typename ELFT::Shdr &Sec : Sections) {
1292 if (Sec.sh_type != SHT_SYMTAB)
1585 for (const typename ELFT::Shdr &sec : sections) {
1586 if (sec.sh_type != SHT_SYMTAB)
12931587 continue;
12941588
1295 typename ELFT::SymRange Syms = CHECK(Obj.symbols(&Sec), this);
1296 uint32_t FirstGlobal = Sec.sh_info;
1297 StringRef StringTable =
1298 CHECK(Obj.getStringTableForSymtab(Sec, Sections), this);
1589 // A symbol table is found.
1590 ArrayRef<Elf_Sym> eSyms = CHECK(obj.symbols(&sec), this);
1591 uint32_t firstGlobal = sec.sh_info;
1592 StringRef strtab = CHECK(obj.getStringTableForSymtab(sec, sections), this);
1593 this->symbols.resize(eSyms.size());
1594
1595 // Get existing symbols or insert placeholder symbols.
1596 for (size_t i = firstGlobal, end = eSyms.size(); i != end; ++i)
1597 if (eSyms[i].st_shndx != SHN_UNDEF)
1598 this->symbols[i] = symtab->insert(CHECK(eSyms[i].getName(strtab), this));
1599
1600 // Replace existing symbols with LazyObject symbols.
1601 //
1602 // resolve() may trigger this->fetch() if an existing symbol is an
1603 // undefined symbol. If that happens, this LazyObjFile has served
1604 // its purpose, and we can exit from the loop early.
1605 for (Symbol *sym : this->symbols) {
1606 if (!sym)
1607 continue;
1608 sym->resolve(LazyObject{*this, sym->getName()});
12991609
1300 for (const typename ELFT::Sym &Sym : Syms.slice(FirstGlobal))
1301 if (Sym.st_shndx != SHN_UNDEF)
1302 Symtab->addLazyObject<ELFT>(CHECK(Sym.getName(StringTable), this),
1303 *this);
1610 // MemoryBuffer is emptied if this file is instantiated as ObjFile.
1611 if (mb.getBuffer().empty())
1612 return;
1613 }
13041614 return;
13051615 }
13061616}
13071617
1308std::string elf::replaceThinLTOSuffix(StringRef Path) {
1309 StringRef Suffix = Config->ThinLTOObjectSuffixReplace.first;
1310 StringRef Repl = Config->ThinLTOObjectSuffixReplace.second;
1618std::string elf::replaceThinLTOSuffix(StringRef path) {
1619 StringRef suffix = config->thinLTOObjectSuffixReplace.first;
1620 StringRef repl = config->thinLTOObjectSuffixReplace.second;
13111621
1312 if (Path.consume_back(Suffix))
1313 return (Path + Repl).str();
1314 return Path;
1622 if (path.consume_back(suffix))
1623 return (path + repl).str();
1624 return path;
13151625}
13161626
1317template void ArchiveFile::parse<ELF32LE>();
1318template void ArchiveFile::parse<ELF32BE>();
1319template void ArchiveFile::parse<ELF64LE>();
1320template void ArchiveFile::parse<ELF64BE>();
1321
1322template void BitcodeFile::parse<ELF32LE>(DenseSet<CachedHashStringRef> &);
1323template void BitcodeFile::parse<ELF32BE>(DenseSet<CachedHashStringRef> &);
1324template void BitcodeFile::parse<ELF64LE>(DenseSet<CachedHashStringRef> &);
1325template void BitcodeFile::parse<ELF64BE>(DenseSet<CachedHashStringRef> &);
1627template void BitcodeFile::parse<ELF32LE>();
1628template void BitcodeFile::parse<ELF32BE>();
1629template void BitcodeFile::parse<ELF64LE>();
1630template void BitcodeFile::parse<ELF64BE>();
13261631
13271632template void LazyObjFile::parse<ELF32LE>();
13281633template void LazyObjFile::parse<ELF32BE>();
13291634template void LazyObjFile::parse<ELF64LE>();
13301635template void LazyObjFile::parse<ELF64BE>();
13311636
1332template class elf::ELFFileBase<ELF32LE>;
1333template class elf::ELFFileBase<ELF32BE>;
1334template class elf::ELFFileBase<ELF64LE>;
1335template class elf::ELFFileBase<ELF64BE>;
1336
13371637template class elf::ObjFile<ELF32LE>;
13381638template class elf::ObjFile<ELF32BE>;
13391639template class elf::ObjFile<ELF64LE>;
13401640template class elf::ObjFile<ELF64BE>;
13411641
1342template class elf::SharedFile<ELF32LE>;
1343template class elf::SharedFile<ELF32BE>;
1344template class elf::SharedFile<ELF64LE>;
1345template class elf::SharedFile<ELF64BE>;
1642template void SharedFile::parse<ELF32LE>();
1643template void SharedFile::parse<ELF32BE>();
1644template void SharedFile::parse<ELF64LE>();
1645template void SharedFile::parse<ELF64BE>();
deps/lld/ELF/InputFiles.h+190-167
......@@ -1,9 +1,8 @@
11//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -40,7 +39,7 @@ class InputSectionBase;
4039}
4140
4241// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
43std::string toString(const elf::InputFile *F);
42std::string toString(const elf::InputFile *f);
4443
4544namespace elf {
4645
......@@ -50,10 +49,13 @@ class Symbol;
5049
5150// If -reproduce option is given, all input files are written
5251// to this tar archive.
53extern std::unique_ptr<llvm::TarWriter> Tar;
52extern std::unique_ptr<llvm::TarWriter> tar;
5453
5554// Opens a given file.
56llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
55llvm::Optional<MemoryBufferRef> readFile(StringRef path);
56
57// Add symbols in File to the symbol table.
58void parseFile(InputFile *file);
5759
5860// The root class of input files.
5961class InputFile {
......@@ -67,191 +69,230 @@ public:
6769 BinaryKind,
6870 };
6971
70 Kind kind() const { return FileKind; }
72 Kind kind() const { return fileKind; }
7173
7274 bool isElf() const {
73 Kind K = kind();
74 return K == ObjKind || K == SharedKind;
75 Kind k = kind();
76 return k == ObjKind || k == SharedKind;
7577 }
7678
77 StringRef getName() const { return MB.getBufferIdentifier(); }
78 MemoryBufferRef MB;
79 StringRef getName() const { return mb.getBufferIdentifier(); }
80 MemoryBufferRef mb;
7981
8082 // Returns sections. It is a runtime error to call this function
8183 // on files that don't have the notion of sections.
8284 ArrayRef<InputSectionBase *> getSections() const {
83 assert(FileKind == ObjKind || FileKind == BinaryKind);
84 return Sections;
85 assert(fileKind == ObjKind || fileKind == BinaryKind);
86 return sections;
8587 }
8688
8789 // Returns object file symbols. It is a runtime error to call this
8890 // function on files of other types.
8991 ArrayRef<Symbol *> getSymbols() { return getMutableSymbols(); }
9092
91 std::vector<Symbol *> &getMutableSymbols() {
92 assert(FileKind == BinaryKind || FileKind == ObjKind ||
93 FileKind == BitcodeKind);
94 return Symbols;
93 MutableArrayRef<Symbol *> getMutableSymbols() {
94 assert(fileKind == BinaryKind || fileKind == ObjKind ||
95 fileKind == BitcodeKind);
96 return symbols;
9597 }
9698
9799 // Filename of .a which contained this file. If this file was
98100 // not in an archive file, it is the empty string. We use this
99101 // string for creating error messages.
100 std::string ArchiveName;
102 std::string archiveName;
101103
102104 // If this is an architecture-specific file, the following members
103105 // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
104 ELFKind EKind = ELFNoneKind;
105 uint16_t EMachine = llvm::ELF::EM_NONE;
106 uint8_t OSABI = 0;
106 ELFKind ekind = ELFNoneKind;
107 uint16_t emachine = llvm::ELF::EM_NONE;
108 uint8_t osabi = 0;
109 uint8_t abiVersion = 0;
107110
108111 // Cache for toString(). Only toString() should use this member.
109 mutable std::string ToStringCache;
112 mutable std::string toStringCache;
110113
111 std::string getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
112 uint64_t Offset);
114 std::string getSrcMsg(const Symbol &sym, InputSectionBase &sec,
115 uint64_t offset);
113116
114117 // True if this is an argument for --just-symbols. Usually false.
115 bool JustSymbols = false;
116
117 // GroupId is used for --warn-backrefs which is an optional error
118 bool justSymbols = false;
119
120 // outSecOff of .got2 in the current file. This is used by PPC32 -fPIC/-fPIE
121 // to compute offsets in PLT call stubs.
122 uint32_t ppc32Got2OutSecOff = 0;
123
124 // On PPC64 we need to keep track of which files contain small code model
125 // relocations that access the .toc section. To minimize the chance of a
126 // relocation overflow, files that do contain said relocations should have
127 // their .toc sections sorted closer to the .got section than files that do
128 // not contain any small code model relocations. Thats because the toc-pointer
129 // is defined to point at .got + 0x8000 and the instructions used with small
130 // code model relocations support immediates in the range [-0x8000, 0x7FFC],
131 // making the addressable range relative to the toc pointer
132 // [.got, .got + 0xFFFC].
133 bool ppc64SmallCodeModelTocRelocs = false;
134
135 // groupId is used for --warn-backrefs which is an optional error
118136 // checking feature. All files within the same --{start,end}-group or
119137 // --{start,end}-lib get the same group ID. Otherwise, each file gets a new
120138 // group ID. For more info, see checkDependency() in SymbolTable.cpp.
121 uint32_t GroupId;
122 static bool IsInGroup;
123 static uint32_t NextGroupId;
139 uint32_t groupId;
140 static bool isInGroup;
141 static uint32_t nextGroupId;
124142
125143 // Index of MIPS GOT built for this file.
126 llvm::Optional<size_t> MipsGotIndex;
144 llvm::Optional<size_t> mipsGotIndex;
145
146 std::vector<Symbol *> symbols;
127147
128148protected:
129 InputFile(Kind K, MemoryBufferRef M);
130 std::vector<InputSectionBase *> Sections;
131 std::vector<Symbol *> Symbols;
149 InputFile(Kind k, MemoryBufferRef m);
150 std::vector<InputSectionBase *> sections;
132151
133152private:
134 const Kind FileKind;
153 const Kind fileKind;
135154};
136155
137template <typename ELFT> class ELFFileBase : public InputFile {
156class ELFFileBase : public InputFile {
138157public:
139 typedef typename ELFT::Shdr Elf_Shdr;
140 typedef typename ELFT::Sym Elf_Sym;
141 typedef typename ELFT::Word Elf_Word;
142 typedef typename ELFT::SymRange Elf_Sym_Range;
158 ELFFileBase(Kind k, MemoryBufferRef m);
159 static bool classof(const InputFile *f) { return f->isElf(); }
143160
144 ELFFileBase(Kind K, MemoryBufferRef M);
145 static bool classof(const InputFile *F) { return F->isElf(); }
146
147 llvm::object::ELFFile<ELFT> getObj() const {
148 return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
161 template <typename ELFT> llvm::object::ELFFile<ELFT> getObj() const {
162 return check(llvm::object::ELFFile<ELFT>::create(mb.getBuffer()));
149163 }
150164
151 StringRef getStringTable() const { return StringTable; }
152
153 uint32_t getSectionIndex(const Elf_Sym &Sym) const;
165 StringRef getStringTable() const { return stringTable; }
154166
155 Elf_Sym_Range getGlobalELFSyms();
156 Elf_Sym_Range getELFSyms() const { return ELFSyms; }
167 template <typename ELFT> typename ELFT::SymRange getELFSyms() const {
168 return typename ELFT::SymRange(
169 reinterpret_cast<const typename ELFT::Sym *>(elfSyms), numELFSyms);
170 }
171 template <typename ELFT> typename ELFT::SymRange getGlobalELFSyms() const {
172 return getELFSyms<ELFT>().slice(firstGlobal);
173 }
157174
158175protected:
159 ArrayRef<Elf_Sym> ELFSyms;
160 uint32_t FirstGlobal = 0;
161 ArrayRef<Elf_Word> SymtabSHNDX;
162 StringRef StringTable;
163 void initSymtab(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr *Symtab);
176 // Initializes this class's member variables.
177 template <typename ELFT> void init();
178
179 const void *elfSyms = nullptr;
180 size_t numELFSyms = 0;
181 uint32_t firstGlobal = 0;
182 StringRef stringTable;
164183};
165184
166185// .o file.
167template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
168 typedef ELFFileBase<ELFT> Base;
169 typedef typename ELFT::Rel Elf_Rel;
170 typedef typename ELFT::Rela Elf_Rela;
171 typedef typename ELFT::Sym Elf_Sym;
172 typedef typename ELFT::Shdr Elf_Shdr;
173 typedef typename ELFT::Word Elf_Word;
174 typedef typename ELFT::CGProfile Elf_CGProfile;
175
176 StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
177 const Elf_Shdr &Sec);
186template <class ELFT> class ObjFile : public ELFFileBase {
187 using Elf_Rel = typename ELFT::Rel;
188 using Elf_Rela = typename ELFT::Rela;
189 using Elf_Sym = typename ELFT::Sym;
190 using Elf_Shdr = typename ELFT::Shdr;
191 using Elf_Word = typename ELFT::Word;
192 using Elf_CGProfile = typename ELFT::CGProfile;
178193
179194public:
180 static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
195 static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
196
197 llvm::object::ELFFile<ELFT> getObj() const {
198 return this->ELFFileBase::getObj<ELFT>();
199 }
181200
182201 ArrayRef<Symbol *> getLocalSymbols();
183202 ArrayRef<Symbol *> getGlobalSymbols();
184203
185 ObjFile(MemoryBufferRef M, StringRef ArchiveName);
186 void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
204 ObjFile(MemoryBufferRef m, StringRef archiveName) : ELFFileBase(ObjKind, m) {
205 this->archiveName = archiveName;
206 }
207
208 void parse(bool ignoreComdats = false);
187209
188 Symbol &getSymbol(uint32_t SymbolIndex) const {
189 if (SymbolIndex >= this->Symbols.size())
210 StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> sections,
211 const Elf_Shdr &sec);
212
213 Symbol &getSymbol(uint32_t symbolIndex) const {
214 if (symbolIndex >= this->symbols.size())
190215 fatal(toString(this) + ": invalid symbol index");
191 return *this->Symbols[SymbolIndex];
216 return *this->symbols[symbolIndex];
192217 }
193218
194 template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const {
195 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
196 return getSymbol(SymIndex);
219 uint32_t getSectionIndex(const Elf_Sym &sym) const;
220
221 template <typename RelT> Symbol &getRelocTargetSym(const RelT &rel) const {
222 uint32_t symIndex = rel.getSymbol(config->isMips64EL);
223 return getSymbol(symIndex);
197224 }
198225
199226 llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t);
200 llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef Name);
227 llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef name);
201228
202229 // MIPS GP0 value defined by this file. This value represents the gp value
203230 // used to create the relocatable object and required to support
204231 // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
205 uint32_t MipsGp0 = 0;
232 uint32_t mipsGp0 = 0;
233
234 uint32_t andFeatures = 0;
206235
207236 // Name of source file obtained from STT_FILE symbol value,
208237 // or empty string if there is no such symbol in object file
209238 // symbol table.
210 StringRef SourceFile;
239 StringRef sourceFile;
211240
212241 // True if the file defines functions compiled with
213242 // -fsplit-stack. Usually false.
214 bool SplitStack = false;
243 bool splitStack = false;
215244
216245 // True if the file defines functions compiled with -fsplit-stack,
217246 // but had one or more functions with the no_split_stack attribute.
218 bool SomeNoSplitStack = false;
247 bool someNoSplitStack = false;
219248
220249 // Pointer to this input file's .llvm_addrsig section, if it has one.
221 const Elf_Shdr *AddrsigSec = nullptr;
250 const Elf_Shdr *addrsigSec = nullptr;
222251
223252 // SHT_LLVM_CALL_GRAPH_PROFILE table
224 ArrayRef<Elf_CGProfile> CGProfile;
253 ArrayRef<Elf_CGProfile> cgProfile;
225254
226255private:
227 void
228 initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
256 void initializeSections(bool ignoreComdats);
229257 void initializeSymbols();
230258 void initializeJustSymbols();
231259 void initializeDwarf();
232 InputSectionBase *getRelocTarget(const Elf_Shdr &Sec);
233 InputSectionBase *createInputSection(const Elf_Shdr &Sec);
234 StringRef getSectionName(const Elf_Shdr &Sec);
235
236 bool shouldMerge(const Elf_Shdr &Sec);
237 Symbol *createSymbol(const Elf_Sym *Sym);
260 InputSectionBase *getRelocTarget(const Elf_Shdr &sec);
261 InputSectionBase *createInputSection(const Elf_Shdr &sec);
262 StringRef getSectionName(const Elf_Shdr &sec);
263
264 bool shouldMerge(const Elf_Shdr &sec);
265
266 // Each ELF symbol contains a section index which the symbol belongs to.
267 // However, because the number of bits dedicated for that is limited, a
268 // symbol can directly point to a section only when the section index is
269 // equal to or smaller than 65280.
270 //
271 // If an object file contains more than 65280 sections, the file must
272 // contain .symtab_shndx section. The section contains an array of
273 // 32-bit integers whose size is the same as the number of symbols.
274 // Nth symbol's section index is in the Nth entry of .symtab_shndx.
275 //
276 // The following variable contains the contents of .symtab_shndx.
277 // If the section does not exist (which is common), the array is empty.
278 ArrayRef<Elf_Word> shndxTable;
238279
239280 // .shstrtab contents.
240 StringRef SectionStringTable;
281 StringRef sectionStringTable;
241282
242283 // Debugging information to retrieve source file and line for error
243284 // reporting. Linker may find reasonable number of errors in a
244285 // single object file, so we cache debugging information in order to
245286 // parse it only once for each object file we link.
246 std::unique_ptr<llvm::DWARFContext> Dwarf;
247 std::vector<const llvm::DWARFDebugLine::LineTable *> LineTables;
287 std::unique_ptr<llvm::DWARFContext> dwarf;
288 std::vector<const llvm::DWARFDebugLine::LineTable *> lineTables;
248289 struct VarLoc {
249 const llvm::DWARFDebugLine::LineTable *LT;
250 unsigned File;
251 unsigned Line;
290 const llvm::DWARFDebugLine::LineTable *lt;
291 unsigned file;
292 unsigned line;
252293 };
253 llvm::DenseMap<StringRef, VarLoc> VariableLoc;
254 llvm::once_flag InitDwarfLine;
294 llvm::DenseMap<StringRef, VarLoc> variableLoc;
295 llvm::once_flag initDwarfLine;
255296};
256297
257298// LazyObjFile is analogous to ArchiveFile in the sense that
......@@ -263,118 +304,100 @@ private:
263304// archive file semantics.
264305class LazyObjFile : public InputFile {
265306public:
266 LazyObjFile(MemoryBufferRef M, StringRef ArchiveName,
267 uint64_t OffsetInArchive)
268 : InputFile(LazyObjKind, M), OffsetInArchive(OffsetInArchive) {
269 this->ArchiveName = ArchiveName;
307 LazyObjFile(MemoryBufferRef m, StringRef archiveName,
308 uint64_t offsetInArchive)
309 : InputFile(LazyObjKind, m), offsetInArchive(offsetInArchive) {
310 this->archiveName = archiveName;
270311 }
271312
272 static bool classof(const InputFile *F) { return F->kind() == LazyObjKind; }
313 static bool classof(const InputFile *f) { return f->kind() == LazyObjKind; }
273314
274315 template <class ELFT> void parse();
275 MemoryBufferRef getBuffer();
276 InputFile *fetch();
277 bool AddedToLink = false;
316 void fetch();
278317
279318private:
280 uint64_t OffsetInArchive;
319 uint64_t offsetInArchive;
281320};
282321
283322// An ArchiveFile object represents a .a file.
284323class ArchiveFile : public InputFile {
285324public:
286 explicit ArchiveFile(std::unique_ptr<Archive> &&File);
287 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
288 template <class ELFT> void parse();
325 explicit ArchiveFile(std::unique_ptr<Archive> &&file);
326 static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; }
327 void parse();
289328
290329 // Pulls out an object file that contains a definition for Sym and
291330 // returns it. If the same file was instantiated before, this
292 // function returns a nullptr (so we don't instantiate the same file
331 // function does nothing (so we don't instantiate the same file
293332 // more than once.)
294 InputFile *fetch(const Archive::Symbol &Sym);
333 void fetch(const Archive::Symbol &sym);
295334
296335private:
297 std::unique_ptr<Archive> File;
298 llvm::DenseSet<uint64_t> Seen;
336 std::unique_ptr<Archive> file;
337 llvm::DenseSet<uint64_t> seen;
299338};
300339
301340class BitcodeFile : public InputFile {
302341public:
303 BitcodeFile(MemoryBufferRef M, StringRef ArchiveName,
304 uint64_t OffsetInArchive);
305 static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
306 template <class ELFT>
307 void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
308 std::unique_ptr<llvm::lto::InputFile> Obj;
342 BitcodeFile(MemoryBufferRef m, StringRef archiveName,
343 uint64_t offsetInArchive);
344 static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
345 template <class ELFT> void parse();
346 std::unique_ptr<llvm::lto::InputFile> obj;
309347};
310348
311349// .so file.
312template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
313 typedef ELFFileBase<ELFT> Base;
314 typedef typename ELFT::Dyn Elf_Dyn;
315 typedef typename ELFT::Shdr Elf_Shdr;
316 typedef typename ELFT::Sym Elf_Sym;
317 typedef typename ELFT::SymRange Elf_Sym_Range;
318 typedef typename ELFT::Verdef Elf_Verdef;
319 typedef typename ELFT::Versym Elf_Versym;
320
321 const Elf_Shdr *VersymSec = nullptr;
322 const Elf_Shdr *VerdefSec = nullptr;
323
350class SharedFile : public ELFFileBase {
324351public:
325 std::vector<const Elf_Verdef *> Verdefs;
326 std::string SoName;
352 SharedFile(MemoryBufferRef m, StringRef defaultSoName)
353 : ELFFileBase(SharedKind, m), soName(defaultSoName),
354 isNeeded(!config->asNeeded) {}
327355
328 static bool classof(const InputFile *F) {
329 return F->kind() == Base::SharedKind;
330 }
356 // This is actually a vector of Elf_Verdef pointers.
357 std::vector<const void *> verdefs;
331358
332 SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
359 // If the output file needs Elf_Verneed data structures for this file, this is
360 // a vector of Elf_Vernaux version identifiers that map onto the entries in
361 // Verdefs, otherwise it is empty.
362 std::vector<unsigned> vernauxs;
333363
334 void parseSoName();
335 void parseRest();
336 uint32_t getAlignment(ArrayRef<Elf_Shdr> Sections, const Elf_Sym &Sym);
337 std::vector<const Elf_Verdef *> parseVerdefs();
338 std::vector<uint32_t> parseVersyms();
364 static unsigned vernauxNum;
339365
340 struct NeededVer {
341 // The string table offset of the version name in the output file.
342 size_t StrTab;
366 std::vector<StringRef> dtNeeded;
367 std::string soName;
343368
344 // The version identifier for this version name.
345 uint16_t Index;
346 };
369 static bool classof(const InputFile *f) { return f->kind() == SharedKind; }
370
371 template <typename ELFT> void parse();
347372
348 // Mapping from Elf_Verdef data structures to information about Elf_Vernaux
349 // data structures in the output file.
350 std::map<const Elf_Verdef *, NeededVer> VerdefMap;
373 // Used for --no-allow-shlib-undefined.
374 bool allNeededIsKnown;
351375
352376 // Used for --as-needed
353 bool IsNeeded;
377 bool isNeeded;
354378};
355379
356380class BinaryFile : public InputFile {
357381public:
358 explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
359 static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
382 explicit BinaryFile(MemoryBufferRef m) : InputFile(BinaryKind, m) {}
383 static bool classof(const InputFile *f) { return f->kind() == BinaryKind; }
360384 void parse();
361385};
362386
363InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
364 uint64_t OffsetInArchive = 0);
365InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
387InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = "",
388 uint64_t offsetInArchive = 0);
366389
367inline bool isBitcode(MemoryBufferRef MB) {
368 return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;
390inline bool isBitcode(MemoryBufferRef mb) {
391 return identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode;
369392}
370393
371std::string replaceThinLTOSuffix(StringRef Path);
394std::string replaceThinLTOSuffix(StringRef path);
372395
373extern std::vector<BinaryFile *> BinaryFiles;
374extern std::vector<BitcodeFile *> BitcodeFiles;
375extern std::vector<LazyObjFile *> LazyObjFiles;
376extern std::vector<InputFile *> ObjectFiles;
377extern std::vector<InputFile *> SharedFiles;
396extern std::vector<BinaryFile *> binaryFiles;
397extern std::vector<BitcodeFile *> bitcodeFiles;
398extern std::vector<LazyObjFile *> lazyObjFiles;
399extern std::vector<InputFile *> objectFiles;
400extern std::vector<SharedFile *> sharedFiles;
378401
379402} // namespace elf
380403} // namespace lld
deps/lld/ELF/InputSection.cpp+583-530
......@@ -1,9 +1,8 @@
11//===- InputSection.cpp ---------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -41,52 +40,52 @@ using namespace llvm::sys;
4140using namespace lld;
4241using namespace lld::elf;
4342
44std::vector<InputSectionBase *> elf::InputSections;
43std::vector<InputSectionBase *> elf::inputSections;
4544
4645// Returns a string to construct an error message.
47std::string lld::toString(const InputSectionBase *Sec) {
48 return (toString(Sec->File) + ":(" + Sec->Name + ")").str();
46std::string lld::toString(const InputSectionBase *sec) {
47 return (toString(sec->file) + ":(" + sec->name + ")").str();
4948}
5049
5150template <class ELFT>
52static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &File,
53 const typename ELFT::Shdr &Hdr) {
54 if (Hdr.sh_type == SHT_NOBITS)
55 return makeArrayRef<uint8_t>(nullptr, Hdr.sh_size);
56 return check(File.getObj().getSectionContents(&Hdr));
51static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &file,
52 const typename ELFT::Shdr &hdr) {
53 if (hdr.sh_type == SHT_NOBITS)
54 return makeArrayRef<uint8_t>(nullptr, hdr.sh_size);
55 return check(file.getObj().getSectionContents(&hdr));
5756}
5857
59InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
60 uint32_t Type, uint64_t Entsize,
61 uint32_t Link, uint32_t Info,
62 uint32_t Alignment, ArrayRef<uint8_t> Data,
63 StringRef Name, Kind SectionKind)
64 : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
65 Link),
66 File(File), RawData(Data) {
58InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
59 uint32_t type, uint64_t entsize,
60 uint32_t link, uint32_t info,
61 uint32_t alignment, ArrayRef<uint8_t> data,
62 StringRef name, Kind sectionKind)
63 : SectionBase(sectionKind, name, flags, entsize, alignment, type, info,
64 link),
65 file(file), rawData(data) {
6766 // In order to reduce memory allocation, we assume that mergeable
6867 // sections are smaller than 4 GiB, which is not an unreasonable
6968 // assumption as of 2017.
70 if (SectionKind == SectionBase::Merge && RawData.size() > UINT32_MAX)
69 if (sectionKind == SectionBase::Merge && rawData.size() > UINT32_MAX)
7170 error(toString(this) + ": section too large");
7271
73 NumRelocations = 0;
74 AreRelocsRela = false;
72 numRelocations = 0;
73 areRelocsRela = false;
7574
7675 // The ELF spec states that a value of 0 means the section has
7776 // no alignment constraits.
78 uint32_t V = std::max<uint64_t>(Alignment, 1);
79 if (!isPowerOf2_64(V))
80 fatal(toString(File) + ": section sh_addralign is not a power of 2");
81 this->Alignment = V;
77 uint32_t v = std::max<uint32_t>(alignment, 1);
78 if (!isPowerOf2_64(v))
79 fatal(toString(this) + ": sh_addralign is not a power of 2");
80 this->alignment = v;
8281
8382 // In ELF, each section can be compressed by zlib, and if compressed,
8483 // section name may be mangled by appending "z" (e.g. ".zdebug_info").
8584 // If that's the case, demangle section name so that we can handle a
8685 // section as if it weren't compressed.
87 if ((Flags & SHF_COMPRESSED) || Name.startswith(".zdebug")) {
86 if ((flags & SHF_COMPRESSED) || name.startswith(".zdebug")) {
8887 if (!zlib::isAvailable())
89 error(toString(File) + ": contains a compressed section, " +
88 error(toString(file) + ": contains a compressed section, " +
9089 "but zlib is not available");
9190 parseCompressedHeader();
9291 }
......@@ -95,11 +94,11 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
9594// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
9695// SHF_GROUP is a marker that a section belongs to some comdat group.
9796// That flag doesn't make sense in an executable.
98static uint64_t getFlags(uint64_t Flags) {
99 Flags &= ~(uint64_t)SHF_INFO_LINK;
100 if (!Config->Relocatable)
101 Flags &= ~(uint64_t)SHF_GROUP;
102 return Flags;
97static uint64_t getFlags(uint64_t flags) {
98 flags &= ~(uint64_t)SHF_INFO_LINK;
99 if (!config->relocatable)
100 flags &= ~(uint64_t)SHF_GROUP;
101 return flags;
103102}
104103
105104// GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
......@@ -112,205 +111,212 @@ static uint64_t getFlags(uint64_t Flags) {
112111//
113112// This function forces SHT_{INIT,FINI}_ARRAY so that we can handle
114113// incorrect inputs as if they were correct from the beginning.
115static uint64_t getType(uint64_t Type, StringRef Name) {
116 if (Type == SHT_PROGBITS && Name.startswith(".init_array."))
114static uint64_t getType(uint64_t type, StringRef name) {
115 if (type == SHT_PROGBITS && name.startswith(".init_array."))
117116 return SHT_INIT_ARRAY;
118 if (Type == SHT_PROGBITS && Name.startswith(".fini_array."))
117 if (type == SHT_PROGBITS && name.startswith(".fini_array."))
119118 return SHT_FINI_ARRAY;
120 return Type;
119 return type;
121120}
122121
123122template <class ELFT>
124InputSectionBase::InputSectionBase(ObjFile<ELFT> &File,
125 const typename ELFT::Shdr &Hdr,
126 StringRef Name, Kind SectionKind)
127 : InputSectionBase(&File, getFlags(Hdr.sh_flags),
128 getType(Hdr.sh_type, Name), Hdr.sh_entsize, Hdr.sh_link,
129 Hdr.sh_info, Hdr.sh_addralign,
130 getSectionContents(File, Hdr), Name, SectionKind) {
123InputSectionBase::InputSectionBase(ObjFile<ELFT> &file,
124 const typename ELFT::Shdr &hdr,
125 StringRef name, Kind sectionKind)
126 : InputSectionBase(&file, getFlags(hdr.sh_flags),
127 getType(hdr.sh_type, name), hdr.sh_entsize, hdr.sh_link,
128 hdr.sh_info, hdr.sh_addralign,
129 getSectionContents(file, hdr), name, sectionKind) {
131130 // We reject object files having insanely large alignments even though
132131 // they are allowed by the spec. I think 4GB is a reasonable limitation.
133132 // We might want to relax this in the future.
134 if (Hdr.sh_addralign > UINT32_MAX)
135 fatal(toString(&File) + ": section sh_addralign is too large");
133 if (hdr.sh_addralign > UINT32_MAX)
134 fatal(toString(&file) + ": section sh_addralign is too large");
136135}
137136
138137size_t InputSectionBase::getSize() const {
139 if (auto *S = dyn_cast<SyntheticSection>(this))
140 return S->getSize();
141 if (UncompressedSize >= 0)
142 return UncompressedSize;
143 return RawData.size();
138 if (auto *s = dyn_cast<SyntheticSection>(this))
139 return s->getSize();
140 if (uncompressedSize >= 0)
141 return uncompressedSize;
142 return rawData.size();
144143}
145144
146145void InputSectionBase::uncompress() const {
147 size_t Size = UncompressedSize;
148 UncompressedBuf.reset(new char[Size]);
146 size_t size = uncompressedSize;
147 char *uncompressedBuf;
148 {
149 static std::mutex mu;
150 std::lock_guard<std::mutex> lock(mu);
151 uncompressedBuf = bAlloc.Allocate<char>(size);
152 }
149153
150 if (Error E =
151 zlib::uncompress(toStringRef(RawData), UncompressedBuf.get(), Size))
154 if (Error e = zlib::uncompress(toStringRef(rawData), uncompressedBuf, size))
152155 fatal(toString(this) +
153 ": uncompress failed: " + llvm::toString(std::move(E)));
154 RawData = makeArrayRef((uint8_t *)UncompressedBuf.get(), Size);
156 ": uncompress failed: " + llvm::toString(std::move(e)));
157 rawData = makeArrayRef((uint8_t *)uncompressedBuf, size);
158 uncompressedSize = -1;
155159}
156160
157161uint64_t InputSectionBase::getOffsetInFile() const {
158 const uint8_t *FileStart = (const uint8_t *)File->MB.getBufferStart();
159 const uint8_t *SecStart = data().begin();
160 return SecStart - FileStart;
162 const uint8_t *fileStart = (const uint8_t *)file->mb.getBufferStart();
163 const uint8_t *secStart = data().begin();
164 return secStart - fileStart;
161165}
162166
163uint64_t SectionBase::getOffset(uint64_t Offset) const {
167uint64_t SectionBase::getOffset(uint64_t offset) const {
164168 switch (kind()) {
165169 case Output: {
166 auto *OS = cast<OutputSection>(this);
170 auto *os = cast<OutputSection>(this);
167171 // For output sections we treat offset -1 as the end of the section.
168 return Offset == uint64_t(-1) ? OS->Size : Offset;
172 return offset == uint64_t(-1) ? os->size : offset;
169173 }
170174 case Regular:
171175 case Synthetic:
172 return cast<InputSection>(this)->getOffset(Offset);
176 return cast<InputSection>(this)->getOffset(offset);
173177 case EHFrame:
174178 // The file crtbeginT.o has relocations pointing to the start of an empty
175179 // .eh_frame that is known to be the first in the link. It does that to
176180 // identify the start of the output .eh_frame.
177 return Offset;
181 return offset;
178182 case Merge:
179 const MergeInputSection *MS = cast<MergeInputSection>(this);
180 if (InputSection *IS = MS->getParent())
181 return IS->getOffset(MS->getParentOffset(Offset));
182 return MS->getParentOffset(Offset);
183 const MergeInputSection *ms = cast<MergeInputSection>(this);
184 if (InputSection *isec = ms->getParent())
185 return isec->getOffset(ms->getParentOffset(offset));
186 return ms->getParentOffset(offset);
183187 }
184188 llvm_unreachable("invalid section kind");
185189}
186190
187uint64_t SectionBase::getVA(uint64_t Offset) const {
188 const OutputSection *Out = getOutputSection();
189 return (Out ? Out->Addr : 0) + getOffset(Offset);
191uint64_t SectionBase::getVA(uint64_t offset) const {
192 const OutputSection *out = getOutputSection();
193 return (out ? out->addr : 0) + getOffset(offset);
190194}
191195
192196OutputSection *SectionBase::getOutputSection() {
193 InputSection *Sec;
194 if (auto *IS = dyn_cast<InputSection>(this))
195 Sec = IS;
196 else if (auto *MS = dyn_cast<MergeInputSection>(this))
197 Sec = MS->getParent();
198 else if (auto *EH = dyn_cast<EhInputSection>(this))
199 Sec = EH->getParent();
197 InputSection *sec;
198 if (auto *isec = dyn_cast<InputSection>(this))
199 sec = isec;
200 else if (auto *ms = dyn_cast<MergeInputSection>(this))
201 sec = ms->getParent();
202 else if (auto *eh = dyn_cast<EhInputSection>(this))
203 sec = eh->getParent();
200204 else
201205 return cast<OutputSection>(this);
202 return Sec ? Sec->getParent() : nullptr;
206 return sec ? sec->getParent() : nullptr;
203207}
204208
205// When a section is compressed, `RawData` consists with a header followed
209// When a section is compressed, `rawData` consists with a header followed
206210// by zlib-compressed data. This function parses a header to initialize
207// `UncompressedSize` member and remove the header from `RawData`.
211// `uncompressedSize` member and remove the header from `rawData`.
208212void InputSectionBase::parseCompressedHeader() {
209 typedef typename ELF64LE::Chdr Chdr64;
210 typedef typename ELF32LE::Chdr Chdr32;
213 using Chdr64 = typename ELF64LE::Chdr;
214 using Chdr32 = typename ELF32LE::Chdr;
211215
212216 // Old-style header
213 if (Name.startswith(".zdebug")) {
214 if (!toStringRef(RawData).startswith("ZLIB")) {
217 if (name.startswith(".zdebug")) {
218 if (!toStringRef(rawData).startswith("ZLIB")) {
215219 error(toString(this) + ": corrupted compressed section header");
216220 return;
217221 }
218 RawData = RawData.slice(4);
222 rawData = rawData.slice(4);
219223
220 if (RawData.size() < 8) {
224 if (rawData.size() < 8) {
221225 error(toString(this) + ": corrupted compressed section header");
222226 return;
223227 }
224228
225 UncompressedSize = read64be(RawData.data());
226 RawData = RawData.slice(8);
229 uncompressedSize = read64be(rawData.data());
230 rawData = rawData.slice(8);
227231
228232 // Restore the original section name.
229233 // (e.g. ".zdebug_info" -> ".debug_info")
230 Name = Saver.save("." + Name.substr(2));
234 name = saver.save("." + name.substr(2));
231235 return;
232236 }
233237
234 assert(Flags & SHF_COMPRESSED);
235 Flags &= ~(uint64_t)SHF_COMPRESSED;
238 assert(flags & SHF_COMPRESSED);
239 flags &= ~(uint64_t)SHF_COMPRESSED;
236240
237241 // New-style 64-bit header
238 if (Config->Is64) {
239 if (RawData.size() < sizeof(Chdr64)) {
242 if (config->is64) {
243 if (rawData.size() < sizeof(Chdr64)) {
240244 error(toString(this) + ": corrupted compressed section");
241245 return;
242246 }
243247
244 auto *Hdr = reinterpret_cast<const Chdr64 *>(RawData.data());
245 if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
248 auto *hdr = reinterpret_cast<const Chdr64 *>(rawData.data());
249 if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
246250 error(toString(this) + ": unsupported compression type");
247251 return;
248252 }
249253
250 UncompressedSize = Hdr->ch_size;
251 RawData = RawData.slice(sizeof(*Hdr));
254 uncompressedSize = hdr->ch_size;
255 alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
256 rawData = rawData.slice(sizeof(*hdr));
252257 return;
253258 }
254259
255260 // New-style 32-bit header
256 if (RawData.size() < sizeof(Chdr32)) {
261 if (rawData.size() < sizeof(Chdr32)) {
257262 error(toString(this) + ": corrupted compressed section");
258263 return;
259264 }
260265
261 auto *Hdr = reinterpret_cast<const Chdr32 *>(RawData.data());
262 if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
266 auto *hdr = reinterpret_cast<const Chdr32 *>(rawData.data());
267 if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
263268 error(toString(this) + ": unsupported compression type");
264269 return;
265270 }
266271
267 UncompressedSize = Hdr->ch_size;
268 RawData = RawData.slice(sizeof(*Hdr));
272 uncompressedSize = hdr->ch_size;
273 alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
274 rawData = rawData.slice(sizeof(*hdr));
269275}
270276
271277InputSection *InputSectionBase::getLinkOrderDep() const {
272 assert(Link);
273 assert(Flags & SHF_LINK_ORDER);
274 return cast<InputSection>(File->getSections()[Link]);
278 assert(link);
279 assert(flags & SHF_LINK_ORDER);
280 return cast<InputSection>(file->getSections()[link]);
275281}
276282
277283// Find a function symbol that encloses a given location.
278284template <class ELFT>
279Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) {
280 for (Symbol *B : File->getSymbols())
281 if (Defined *D = dyn_cast<Defined>(B))
282 if (D->Section == this && D->Type == STT_FUNC && D->Value <= Offset &&
283 Offset < D->Value + D->Size)
284 return D;
285Defined *InputSectionBase::getEnclosingFunction(uint64_t offset) {
286 for (Symbol *b : file->getSymbols())
287 if (Defined *d = dyn_cast<Defined>(b))
288 if (d->section == this && d->type == STT_FUNC && d->value <= offset &&
289 offset < d->value + d->size)
290 return d;
285291 return nullptr;
286292}
287293
288294// Returns a source location string. Used to construct an error message.
289295template <class ELFT>
290std::string InputSectionBase::getLocation(uint64_t Offset) {
291 std::string SecAndOffset = (Name + "+0x" + utohexstr(Offset)).str();
296std::string InputSectionBase::getLocation(uint64_t offset) {
297 std::string secAndOffset = (name + "+0x" + utohexstr(offset)).str();
292298
293299 // We don't have file for synthetic sections.
294300 if (getFile<ELFT>() == nullptr)
295 return (Config->OutputFile + ":(" + SecAndOffset + ")")
301 return (config->outputFile + ":(" + secAndOffset + ")")
296302 .str();
297303
298304 // First check if we can get desired values from debugging information.
299 if (Optional<DILineInfo> Info = getFile<ELFT>()->getDILineInfo(this, Offset))
300 return Info->FileName + ":" + std::to_string(Info->Line) + ":(" +
301 SecAndOffset + ")";
305 if (Optional<DILineInfo> info = getFile<ELFT>()->getDILineInfo(this, offset))
306 return info->FileName + ":" + std::to_string(info->Line) + ":(" +
307 secAndOffset + ")";
302308
303 // File->SourceFile contains STT_FILE symbol that contains a
309 // File->sourceFile contains STT_FILE symbol that contains a
304310 // source file name. If it's missing, we use an object file name.
305 std::string SrcFile = getFile<ELFT>()->SourceFile;
306 if (SrcFile.empty())
307 SrcFile = toString(File);
311 std::string srcFile = getFile<ELFT>()->sourceFile;
312 if (srcFile.empty())
313 srcFile = toString(file);
308314
309 if (Defined *D = getEnclosingFunction<ELFT>(Offset))
310 return SrcFile + ":(function " + toString(*D) + ": " + SecAndOffset + ")";
315 if (Defined *d = getEnclosingFunction<ELFT>(offset))
316 return srcFile + ":(function " + toString(*d) + ": " + secAndOffset + ")";
311317
312318 // If there's no symbol, print out the offset in the section.
313 return (SrcFile + ":(" + SecAndOffset + ")");
319 return (srcFile + ":(" + secAndOffset + ")");
314320}
315321
316322// This function is intended to be used for constructing an error message.
......@@ -319,8 +325,8 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {
319325// foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
320326//
321327// Returns an empty string if there's no way to get line info.
322std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
323 return File->getSrcMsg(Sym, *this, Offset);
328std::string InputSectionBase::getSrcMsg(const Symbol &sym, uint64_t offset) {
329 return file->getSrcMsg(sym, *this, offset);
324330}
325331
326332// Returns a filename string along with an optional section name. This
......@@ -332,95 +338,96 @@ std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
332338// or
333339//
334340// path/to/foo.o:(function bar) in archive path/to/bar.a
335std::string InputSectionBase::getObjMsg(uint64_t Off) {
336 std::string Filename = File->getName();
341std::string InputSectionBase::getObjMsg(uint64_t off) {
342 std::string filename = file->getName();
337343
338 std::string Archive;
339 if (!File->ArchiveName.empty())
340 Archive = " in archive " + File->ArchiveName;
344 std::string archive;
345 if (!file->archiveName.empty())
346 archive = " in archive " + file->archiveName;
341347
342348 // Find a symbol that encloses a given location.
343 for (Symbol *B : File->getSymbols())
344 if (auto *D = dyn_cast<Defined>(B))
345 if (D->Section == this && D->Value <= Off && Off < D->Value + D->Size)
346 return Filename + ":(" + toString(*D) + ")" + Archive;
349 for (Symbol *b : file->getSymbols())
350 if (auto *d = dyn_cast<Defined>(b))
351 if (d->section == this && d->value <= off && off < d->value + d->size)
352 return filename + ":(" + toString(*d) + ")" + archive;
347353
348354 // If there's no symbol, print out the offset in the section.
349 return (Filename + ":(" + Name + "+0x" + utohexstr(Off) + ")" + Archive)
355 return (filename + ":(" + name + "+0x" + utohexstr(off) + ")" + archive)
350356 .str();
351357}
352358
353InputSection InputSection::Discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
359InputSection InputSection::discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
354360
355InputSection::InputSection(InputFile *F, uint64_t Flags, uint32_t Type,
356 uint32_t Alignment, ArrayRef<uint8_t> Data,
357 StringRef Name, Kind K)
358 : InputSectionBase(F, Flags, Type,
359 /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Alignment, Data,
360 Name, K) {}
361InputSection::InputSection(InputFile *f, uint64_t flags, uint32_t type,
362 uint32_t alignment, ArrayRef<uint8_t> data,
363 StringRef name, Kind k)
364 : InputSectionBase(f, flags, type,
365 /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, alignment, data,
366 name, k) {}
361367
362368template <class ELFT>
363InputSection::InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
364 StringRef Name)
365 : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}
369InputSection::InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
370 StringRef name)
371 : InputSectionBase(f, header, name, InputSectionBase::Regular) {}
366372
367bool InputSection::classof(const SectionBase *S) {
368 return S->kind() == SectionBase::Regular ||
369 S->kind() == SectionBase::Synthetic;
373bool InputSection::classof(const SectionBase *s) {
374 return s->kind() == SectionBase::Regular ||
375 s->kind() == SectionBase::Synthetic;
370376}
371377
372378OutputSection *InputSection::getParent() const {
373 return cast_or_null<OutputSection>(Parent);
379 return cast_or_null<OutputSection>(parent);
374380}
375381
376382// Copy SHT_GROUP section contents. Used only for the -r option.
377template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) {
383template <class ELFT> void InputSection::copyShtGroup(uint8_t *buf) {
378384 // ELFT::Word is the 32-bit integral type in the target endianness.
379 typedef typename ELFT::Word u32;
380 ArrayRef<u32> From = getDataAs<u32>();
381 auto *To = reinterpret_cast<u32 *>(Buf);
385 using u32 = typename ELFT::Word;
386 ArrayRef<u32> from = getDataAs<u32>();
387 auto *to = reinterpret_cast<u32 *>(buf);
382388
383389 // The first entry is not a section number but a flag.
384 *To++ = From[0];
390 *to++ = from[0];
385391
386392 // Adjust section numbers because section numbers in an input object
387393 // files are different in the output.
388 ArrayRef<InputSectionBase *> Sections = File->getSections();
389 for (uint32_t Idx : From.slice(1))
390 *To++ = Sections[Idx]->getOutputSection()->SectionIndex;
394 ArrayRef<InputSectionBase *> sections = file->getSections();
395 for (uint32_t idx : from.slice(1))
396 *to++ = sections[idx]->getOutputSection()->sectionIndex;
391397}
392398
393399InputSectionBase *InputSection::getRelocatedSection() const {
394 if (!File || (Type != SHT_RELA && Type != SHT_REL))
400 if (!file || (type != SHT_RELA && type != SHT_REL))
395401 return nullptr;
396 ArrayRef<InputSectionBase *> Sections = File->getSections();
397 return Sections[Info];
402 ArrayRef<InputSectionBase *> sections = file->getSections();
403 return sections[info];
398404}
399405
400406// This is used for -r and --emit-relocs. We can't use memcpy to copy
401407// relocations because we need to update symbol table offset and section index
402408// for each relocation. So we copy relocations one by one.
403409template <class ELFT, class RelTy>
404void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
405 InputSectionBase *Sec = getRelocatedSection();
410void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
411 InputSectionBase *sec = getRelocatedSection();
406412
407 for (const RelTy &Rel : Rels) {
408 RelType Type = Rel.getType(Config->IsMips64EL);
409 Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
413 for (const RelTy &rel : rels) {
414 RelType type = rel.getType(config->isMips64EL);
415 const ObjFile<ELFT> *file = getFile<ELFT>();
416 Symbol &sym = file->getRelocTargetSym(rel);
410417
411 auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf);
412 Buf += sizeof(RelTy);
418 auto *p = reinterpret_cast<typename ELFT::Rela *>(buf);
419 buf += sizeof(RelTy);
413420
414421 if (RelTy::IsRela)
415 P->r_addend = getAddend<ELFT>(Rel);
422 p->r_addend = getAddend<ELFT>(rel);
416423
417424 // Output section VA is zero for -r, so r_offset is an offset within the
418425 // section, but for --emit-relocs it is an virtual address.
419 P->r_offset = Sec->getVA(Rel.r_offset);
420 P->setSymbolAndType(In.SymTab->getSymbolIndex(&Sym), Type,
421 Config->IsMips64EL);
426 p->r_offset = sec->getVA(rel.r_offset);
427 p->setSymbolAndType(in.symTab->getSymbolIndex(&sym), type,
428 config->isMips64EL);
422429
423 if (Sym.Type == STT_SECTION) {
430 if (sym.type == STT_SECTION) {
424431 // We combine multiple section symbols into only one per
425432 // section. This means we have to update the addend. That is
426433 // trivial for Elf_Rela, but for Elf_Rel we have to write to the
......@@ -429,25 +436,38 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
429436 // .eh_frame is horribly special and can reference discarded sections. To
430437 // avoid having to parse and recreate .eh_frame, we just replace any
431438 // relocation in it pointing to discarded sections with R_*_NONE, which
432 // hopefully creates a frame that is ignored at runtime.
433 auto *D = dyn_cast<Defined>(&Sym);
434 if (!D) {
435 error("STT_SECTION symbol should be defined");
439 // hopefully creates a frame that is ignored at runtime. Also, don't warn
440 // on .gcc_except_table and debug sections.
441 //
442 // See the comment in maybeReportUndefined for PPC64 .toc .
443 auto *d = dyn_cast<Defined>(&sym);
444 if (!d) {
445 if (!sec->name.startswith(".debug") &&
446 !sec->name.startswith(".zdebug") && sec->name != ".eh_frame" &&
447 sec->name != ".gcc_except_table" && sec->name != ".toc") {
448 uint32_t secIdx = cast<Undefined>(sym).discardedSecIdx;
449 Elf_Shdr_Impl<ELFT> sec =
450 CHECK(file->getObj().sections(), file)[secIdx];
451 warn("relocation refers to a discarded section: " +
452 CHECK(file->getObj().getSectionName(&sec), file) +
453 "\n>>> referenced by " + getObjMsg(p->r_offset));
454 }
455 p->setSymbolAndType(0, 0, false);
436456 continue;
437457 }
438 SectionBase *Section = D->Section->Repl;
439 if (!Section->Live) {
440 P->setSymbolAndType(0, 0, false);
458 SectionBase *section = d->section->repl;
459 if (!section->isLive()) {
460 p->setSymbolAndType(0, 0, false);
441461 continue;
442462 }
443463
444 int64_t Addend = getAddend<ELFT>(Rel);
445 const uint8_t *BufLoc = Sec->data().begin() + Rel.r_offset;
464 int64_t addend = getAddend<ELFT>(rel);
465 const uint8_t *bufLoc = sec->data().begin() + rel.r_offset;
446466 if (!RelTy::IsRela)
447 Addend = Target->getImplicitAddend(BufLoc, Type);
467 addend = target->getImplicitAddend(bufLoc, type);
448468
449 if (Config->EMachine == EM_MIPS && Config->Relocatable &&
450 Target->getRelExpr(Type, Sym, BufLoc) == R_MIPS_GOTREL) {
469 if (config->emachine == EM_MIPS && config->relocatable &&
470 target->getRelExpr(type, sym, bufLoc) == R_MIPS_GOTREL) {
451471 // Some MIPS relocations depend on "gp" value. By default,
452472 // this value has 0x7ff0 offset from a .got section. But
453473 // relocatable files produced by a complier or a linker
......@@ -459,13 +479,13 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
459479 // individual "gp" values used by each input object file.
460480 // As a workaround we add the "gp" value to the relocation
461481 // addend and save it back to the file.
462 Addend += Sec->getFile<ELFT>()->MipsGp0;
482 addend += sec->getFile<ELFT>()->mipsGp0;
463483 }
464484
465485 if (RelTy::IsRela)
466 P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr;
467 else if (Config->Relocatable)
468 Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym});
486 p->r_addend = sym.getVA(addend) - section->getOutputSection()->addr;
487 else if (config->relocatable && type != target->noneRel)
488 sec->relocations.push_back({R_ABS, type, rel.r_offset, addend, &sym});
469489 }
470490 }
471491}
......@@ -475,13 +495,13 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
475495// this context is the address of the place P. A further special case is that
476496// branch relocations to an undefined weak reference resolve to the next
477497// instruction.
478static uint32_t getARMUndefinedRelativeWeakVA(RelType Type, uint32_t A,
479 uint32_t P) {
480 switch (Type) {
498static uint32_t getARMUndefinedRelativeWeakVA(RelType type, uint32_t a,
499 uint32_t p) {
500 switch (type) {
481501 // Unresolved branch relocations to weak references resolve to next
482502 // instruction, this will be either 2 or 4 bytes on from P.
483503 case R_ARM_THM_JUMP11:
484 return P + 2 + A;
504 return p + 2 + a;
485505 case R_ARM_CALL:
486506 case R_ARM_JUMP24:
487507 case R_ARM_PC24:
......@@ -489,10 +509,10 @@ static uint32_t getARMUndefinedRelativeWeakVA(RelType Type, uint32_t A,
489509 case R_ARM_PREL31:
490510 case R_ARM_THM_JUMP19:
491511 case R_ARM_THM_JUMP24:
492 return P + 4 + A;
512 return p + 4 + a;
493513 case R_ARM_THM_CALL:
494514 // We don't want an interworking BLX to ARM
495 return P + 5 + A;
515 return p + 5 + a;
496516 // Unresolved non branch pc-relative relocations
497517 // R_ARM_TARGET2 which can be resolved relatively is not present as it never
498518 // targets a weak-reference.
......@@ -501,29 +521,29 @@ static uint32_t getARMUndefinedRelativeWeakVA(RelType Type, uint32_t A,
501521 case R_ARM_REL32:
502522 case R_ARM_THM_MOVW_PREL_NC:
503523 case R_ARM_THM_MOVT_PREL:
504 return P + A;
524 return p + a;
505525 }
506526 llvm_unreachable("ARM pc-relative relocation expected\n");
507527}
508528
509529// The comment above getARMUndefinedRelativeWeakVA applies to this function.
510static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
511 uint64_t P) {
512 switch (Type) {
530static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t type, uint64_t a,
531 uint64_t p) {
532 switch (type) {
513533 // Unresolved branch relocations to weak references resolve to next
514534 // instruction, this is 4 bytes on from P.
515535 case R_AARCH64_CALL26:
516536 case R_AARCH64_CONDBR19:
517537 case R_AARCH64_JUMP26:
518538 case R_AARCH64_TSTBR14:
519 return P + 4 + A;
539 return p + 4 + a;
520540 // Unresolved non branch pc-relative relocations
521541 case R_AARCH64_PREL16:
522542 case R_AARCH64_PREL32:
523543 case R_AARCH64_PREL64:
524544 case R_AARCH64_ADR_PREL_LO21:
525545 case R_AARCH64_LD_PREL_LO19:
526 return P + A;
546 return p + a;
527547 }
528548 llvm_unreachable("AArch64 pc-relative relocation expected\n");
529549}
......@@ -535,11 +555,11 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
535555// The procedure call standard only defines a Read Write Position Independent
536556// RWPI variant so in practice we should expect the static base to be the base
537557// of the RW segment.
538static uint64_t getARMStaticBase(const Symbol &Sym) {
539 OutputSection *OS = Sym.getOutputSection();
540 if (!OS || !OS->PtLoad || !OS->PtLoad->FirstSec)
541 fatal("SBREL relocation to " + Sym.getName() + " without static base");
542 return OS->PtLoad->FirstSec->Addr;
558static uint64_t getARMStaticBase(const Symbol &sym) {
559 OutputSection *os = sym.getOutputSection();
560 if (!os || !os->ptLoad || !os->ptLoad->firstSec)
561 fatal("SBREL relocation to " + sym.getName() + " without static base");
562 return os->ptLoad->firstSec->addr;
543563}
544564
545565// For R_RISCV_PC_INDIRECT (R_RISCV_PCREL_LO12_{I,S}), the symbol actually
......@@ -548,101 +568,115 @@ static uint64_t getARMStaticBase(const Symbol &Sym) {
548568//
549569// This function returns the R_RISCV_PCREL_HI20 relocation from
550570// 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);
571static Relocation *getRISCVPCRelHi20(const Symbol *sym, uint64_t addend) {
572 const Defined *d = cast<Defined>(sym);
573 if (!d->section) {
574 error("R_RISCV_PCREL_LO12 relocation points to an absolute symbol: " +
575 sym->getName());
576 return nullptr;
577 }
578 InputSection *isec = cast<InputSection>(d->section);
554579
555 if (Addend != 0)
580 if (addend != 0)
556581 warn("Non-zero addend in R_RISCV_PCREL_LO12 relocation to " +
557 IS->getObjMsg(D->Value) + " is ignored");
582 isec->getObjMsg(d->value) + " is ignored");
558583
559584 // Relocations are sorted by offset, so we can use std::equal_range to do
560585 // 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) +
586 Relocation r;
587 r.offset = d->value;
588 auto range =
589 std::equal_range(isec->relocations.begin(), isec->relocations.end(), r,
590 [](const Relocation &lhs, const Relocation &rhs) {
591 return lhs.offset < rhs.offset;
592 });
593
594 for (auto it = range.first; it != range.second; ++it)
595 if (it->type == R_RISCV_PCREL_HI20 || it->type == R_RISCV_GOT_HI20 ||
596 it->type == R_RISCV_TLS_GD_HI20 || it->type == R_RISCV_TLS_GOT_HI20)
597 return &*it;
598
599 error("R_RISCV_PCREL_LO12 relocation points to " + isec->getObjMsg(d->value) +
568600 " without an associated R_RISCV_PCREL_HI20 relocation");
569601 return nullptr;
570602}
571603
572604// A TLS symbol's virtual address is relative to the TLS segment. Add a
573605// target-specific adjustment to produce a thread-pointer-relative offset.
574static int64_t getTlsTpOffset() {
575 switch (Config->EMachine) {
606static int64_t getTlsTpOffset(const Symbol &s) {
607 // On targets that support TLSDESC, _TLS_MODULE_BASE_@tpoff = 0.
608 if (&s == ElfSym::tlsModuleBase)
609 return 0;
610
611 switch (config->emachine) {
576612 case EM_ARM:
577613 case EM_AARCH64:
578614 // Variant 1. The thread pointer points to a TCB with a fixed 2-word size,
579615 // followed by a variable amount of alignment padding, followed by the TLS
580616 // 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);
617 return s.getVA(0) + alignTo(config->wordsize * 2, Out::tlsPhdr->p_align);
586618 case EM_386:
587619 case EM_X86_64:
588620 // Variant 2. The TLS segment is located just before the thread pointer.
589 return -Out::TlsPhdr->p_memsz;
621 return s.getVA(0) - alignTo(Out::tlsPhdr->p_memsz, Out::tlsPhdr->p_align);
622 case EM_PPC:
590623 case EM_PPC64:
591624 // The thread pointer points to a fixed offset from the start of the
592625 // executable's TLS segment. An offset of 0x7000 allows a signed 16-bit
593626 // offset to reach 0x1000 of TCB/thread-library data and 0xf000 of the
594627 // program's TLS segment.
595 return -0x7000;
628 return s.getVA(0) - 0x7000;
629 case EM_RISCV:
630 return s.getVA(0);
596631 default:
597632 llvm_unreachable("unhandled Config->EMachine");
598633 }
599634}
600635
601static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
602 uint64_t P, const Symbol &Sym, RelExpr Expr) {
603 switch (Expr) {
604 case R_INVALID:
605 return 0;
636static uint64_t getRelocTargetVA(const InputFile *file, RelType type, int64_t a,
637 uint64_t p, const Symbol &sym, RelExpr expr) {
638 switch (expr) {
606639 case R_ABS:
640 case R_DTPREL:
607641 case R_RELAX_TLS_LD_TO_LE_ABS:
608642 case R_RELAX_GOT_PC_NOPIC:
609 return Sym.getVA(A);
643 case R_RISCV_ADD:
644 return sym.getVA(a);
610645 case R_ADDEND:
611 return A;
646 return a;
612647 case R_ARM_SBREL:
613 return Sym.getVA(A) - getARMStaticBase(Sym);
648 return sym.getVA(a) - getARMStaticBase(sym);
614649 case R_GOT:
615 case R_GOT_PLT:
616650 case R_RELAX_TLS_GD_TO_IE_ABS:
617 return Sym.getGotVA() + A;
651 return sym.getGotVA() + a;
618652 case R_GOTONLY_PC:
619 return In.Got->getVA() + A - P;
620 case R_GOTONLY_PC_FROM_END:
621 return In.Got->getVA() + A - P + In.Got->getSize();
653 return in.got->getVA() + a - p;
654 case R_GOTPLTONLY_PC:
655 return in.gotPlt->getVA() + a - p;
622656 case R_GOTREL:
623 return Sym.getVA(A) - In.Got->getVA();
624 case R_GOTREL_FROM_END:
625 return Sym.getVA(A) - In.Got->getVA() - In.Got->getSize();
626 case R_GOT_FROM_END:
627 case R_RELAX_TLS_GD_TO_IE_END:
628 return Sym.getGotOffset() + A - In.Got->getSize();
657 case R_PPC64_RELAX_TOC:
658 return sym.getVA(a) - in.got->getVA();
659 case R_GOTPLTREL:
660 return sym.getVA(a) - in.gotPlt->getVA();
661 case R_GOTPLT:
662 case R_RELAX_TLS_GD_TO_IE_GOTPLT:
663 return sym.getGotVA() + a - in.gotPlt->getVA();
629664 case R_TLSLD_GOT_OFF:
630665 case R_GOT_OFF:
631666 case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
632 return Sym.getGotOffset() + A;
667 return sym.getGotOffset() + a;
633668 case R_AARCH64_GOT_PAGE_PC:
634 case R_AARCH64_GOT_PAGE_PC_PLT:
635669 case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
636 return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);
670 return getAArch64Page(sym.getGotVA() + a) - getAArch64Page(p);
637671 case R_GOT_PC:
638672 case R_RELAX_TLS_GD_TO_IE:
639 return Sym.getGotVA() + A - P;
673 return sym.getGotVA() + a - p;
640674 case R_HEXAGON_GOT:
641 return Sym.getGotVA() - In.GotPlt->getVA();
675 return sym.getGotVA() - in.gotPlt->getVA();
642676 case R_MIPS_GOTREL:
643 return Sym.getVA(A) - In.MipsGot->getGp(File);
677 return sym.getVA(a) - in.mipsGot->getGp(file);
644678 case R_MIPS_GOT_GP:
645 return In.MipsGot->getGp(File) + A;
679 return in.mipsGot->getGp(file) + a;
646680 case R_MIPS_GOT_GP_PC: {
647681 // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target
648682 // is _gp_disp symbol. In that case we should use the following
......@@ -651,73 +685,76 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
651685 // microMIPS variants of these relocations use slightly different
652686 // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi()
653687 // to correctly handle less-sugnificant bit of the microMIPS symbol.
654 uint64_t V = In.MipsGot->getGp(File) + A - P;
655 if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16)
656 V += 4;
657 if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16)
658 V -= 1;
659 return V;
688 uint64_t v = in.mipsGot->getGp(file) + a - p;
689 if (type == R_MIPS_LO16 || type == R_MICROMIPS_LO16)
690 v += 4;
691 if (type == R_MICROMIPS_LO16 || type == R_MICROMIPS_HI16)
692 v -= 1;
693 return v;
660694 }
661695 case R_MIPS_GOT_LOCAL_PAGE:
662696 // If relocation against MIPS local symbol requires GOT entry, this entry
663697 // should be initialized by 'page address'. This address is high 16-bits
664698 // of sum the symbol's value and the addend.
665 return In.MipsGot->getVA() + In.MipsGot->getPageEntryOffset(File, Sym, A) -
666 In.MipsGot->getGp(File);
699 return in.mipsGot->getVA() + in.mipsGot->getPageEntryOffset(file, sym, a) -
700 in.mipsGot->getGp(file);
667701 case R_MIPS_GOT_OFF:
668702 case R_MIPS_GOT_OFF32:
669703 // In case of MIPS if a GOT relocation has non-zero addend this addend
670704 // should be applied to the GOT entry content not to the GOT entry offset.
671705 // That is why we use separate expression type.
672 return In.MipsGot->getVA() + In.MipsGot->getSymEntryOffset(File, Sym, A) -
673 In.MipsGot->getGp(File);
706 return in.mipsGot->getVA() + in.mipsGot->getSymEntryOffset(file, sym, a) -
707 in.mipsGot->getGp(file);
674708 case R_MIPS_TLSGD:
675 return In.MipsGot->getVA() + In.MipsGot->getGlobalDynOffset(File, Sym) -
676 In.MipsGot->getGp(File);
709 return in.mipsGot->getVA() + in.mipsGot->getGlobalDynOffset(file, sym) -
710 in.mipsGot->getGp(file);
677711 case R_MIPS_TLSLD:
678 return In.MipsGot->getVA() + In.MipsGot->getTlsIndexOffset(File) -
679 In.MipsGot->getGp(File);
712 return in.mipsGot->getVA() + in.mipsGot->getTlsIndexOffset(file) -
713 in.mipsGot->getGp(file);
680714 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);
715 uint64_t val = sym.isUndefWeak() ? p + a : sym.getVA(a);
716 return getAArch64Page(val) - getAArch64Page(p);
687717 }
688718 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);
719 if (const Relocation *hiRel = getRISCVPCRelHi20(&sym, a))
720 return getRelocTargetVA(file, hiRel->type, hiRel->addend, sym.getVA(),
721 *hiRel->sym, hiRel->expr);
692722 return 0;
693723 }
694724 case R_PC: {
695 uint64_t Dest;
696 if (Sym.isUndefWeak()) {
725 uint64_t dest;
726 if (sym.isUndefWeak()) {
697727 // On ARM and AArch64 a branch to an undefined weak resolves to the
698728 // next instruction, otherwise the place.
699 if (Config->EMachine == EM_ARM)
700 Dest = getARMUndefinedRelativeWeakVA(Type, A, P);
701 else if (Config->EMachine == EM_AARCH64)
702 Dest = getAArch64UndefinedRelativeWeakVA(Type, A, P);
729 if (config->emachine == EM_ARM)
730 dest = getARMUndefinedRelativeWeakVA(type, a, p);
731 else if (config->emachine == EM_AARCH64)
732 dest = getAArch64UndefinedRelativeWeakVA(type, a, p);
733 else if (config->emachine == EM_PPC)
734 dest = p;
703735 else
704 Dest = Sym.getVA(A);
736 dest = sym.getVA(a);
705737 } else {
706 Dest = Sym.getVA(A);
738 dest = sym.getVA(a);
707739 }
708 return Dest - P;
740 return dest - p;
709741 }
710742 case R_PLT:
711 return Sym.getPltVA() + A;
743 return sym.getPltVA() + a;
712744 case R_PLT_PC:
713 case R_PPC_CALL_PLT:
714 return Sym.getPltVA() + A - P;
715 case R_PPC_CALL: {
716 uint64_t SymVA = Sym.getVA(A);
745 case R_PPC64_CALL_PLT:
746 return sym.getPltVA() + a - p;
747 case R_PPC32_PLTREL:
748 // R_PPC_PLTREL24 uses the addend (usually 0 or 0x8000) to indicate r30
749 // stores _GLOBAL_OFFSET_TABLE_ or .got2+0x8000. The addend is ignored for
750 // target VA compuation.
751 return sym.getPltVA() - p;
752 case R_PPC64_CALL: {
753 uint64_t symVA = sym.getVA(a);
717754 // If we have an undefined weak symbol, we might get here with a symbol
718755 // address of zero. That could overflow, but the code must be unreachable,
719756 // so don't bother doing anything at all.
720 if (!SymVA)
757 if (!symVA)
721758 return 0;
722759
723760 // PPC64 V2 ABI describes two entry points to a function. The global entry
......@@ -726,46 +763,49 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
726763 // the callee. For local calls the caller and callee share the same
727764 // TOC base and so the TOC pointer initialization code should be skipped by
728765 // branching to the local entry point.
729 return SymVA - P + getPPC64GlobalEntryToLocalEntryOffset(Sym.StOther);
766 return symVA - p + getPPC64GlobalEntryToLocalEntryOffset(sym.stOther);
730767 }
731 case R_PPC_TOC:
732 return getPPC64TocBase() + A;
768 case R_PPC64_TOCBASE:
769 return getPPC64TocBase() + a;
733770 case R_RELAX_GOT_PC:
734 return Sym.getVA(A) - P;
771 return sym.getVA(a) - p;
735772 case R_RELAX_TLS_GD_TO_LE:
736773 case R_RELAX_TLS_IE_TO_LE:
737774 case R_RELAX_TLS_LD_TO_LE:
738775 case R_TLS:
739 // A weak undefined TLS symbol resolves to the base of the TLS
740 // block, i.e. gets a value of zero. If we pass --gc-sections to
741 // lld and .tbss is not referenced, it gets reclaimed and we don't
742 // create a TLS program header. Therefore, we resolve this
743 // statically to zero.
744 if (Sym.isTls() && Sym.isUndefWeak())
745 return 0;
746 return Sym.getVA(A) + getTlsTpOffset();
776 // It is not very clear what to return if the symbol is undefined. With
777 // --noinhibit-exec, even a non-weak undefined reference may reach here.
778 // Just return A, which matches R_ABS, and the behavior of some dynamic
779 // loaders.
780 if (sym.isUndefined())
781 return a;
782 return getTlsTpOffset(sym) + a;
747783 case R_RELAX_TLS_GD_TO_LE_NEG:
748784 case R_NEG_TLS:
749 return Out::TlsPhdr->p_memsz - Sym.getVA(A);
785 if (sym.isUndefined())
786 return a;
787 return -getTlsTpOffset(sym) + a;
750788 case R_SIZE:
751 return Sym.getSize() + A;
789 return sym.getSize() + a;
752790 case R_TLSDESC:
753 return In.Got->getGlobalDynAddr(Sym) + A;
791 return in.got->getGlobalDynAddr(sym) + a;
792 case R_TLSDESC_PC:
793 return in.got->getGlobalDynAddr(sym) + a - p;
754794 case R_AARCH64_TLSDESC_PAGE:
755 return getAArch64Page(In.Got->getGlobalDynAddr(Sym) + A) -
756 getAArch64Page(P);
795 return getAArch64Page(in.got->getGlobalDynAddr(sym) + a) -
796 getAArch64Page(p);
757797 case R_TLSGD_GOT:
758 return In.Got->getGlobalDynOffset(Sym) + A;
759 case R_TLSGD_GOT_FROM_END:
760 return In.Got->getGlobalDynOffset(Sym) + A - In.Got->getSize();
798 return in.got->getGlobalDynOffset(sym) + a;
799 case R_TLSGD_GOTPLT:
800 return in.got->getVA() + in.got->getGlobalDynOffset(sym) + a - in.gotPlt->getVA();
761801 case R_TLSGD_PC:
762 return In.Got->getGlobalDynAddr(Sym) + A - P;
763 case R_TLSLD_GOT_FROM_END:
764 return In.Got->getTlsIndexOff() + A - In.Got->getSize();
802 return in.got->getGlobalDynAddr(sym) + a - p;
803 case R_TLSLD_GOTPLT:
804 return in.got->getVA() + in.got->getTlsIndexOff() + a - in.gotPlt->getVA();
765805 case R_TLSLD_GOT:
766 return In.Got->getTlsIndexOff() + A;
806 return in.got->getTlsIndexOff() + a;
767807 case R_TLSLD_PC:
768 return In.Got->getTlsIndexVA() + A - P;
808 return in.got->getTlsIndexVA() + a - p;
769809 default:
770810 llvm_unreachable("invalid expression");
771811 }
......@@ -779,36 +819,36 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
779819// So, we handle relocations for non-alloc sections directly in this
780820// function as a performance optimization.
781821template <class ELFT, class RelTy>
782void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
783 const unsigned Bits = sizeof(typename ELFT::uint) * 8;
822void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
823 const unsigned bits = sizeof(typename ELFT::uint) * 8;
784824
785 for (const RelTy &Rel : Rels) {
786 RelType Type = Rel.getType(Config->IsMips64EL);
825 for (const RelTy &rel : rels) {
826 RelType type = rel.getType(config->isMips64EL);
787827
788828 // GCC 8.0 or earlier have a bug that they emit R_386_GOTPC relocations
789829 // against _GLOBAL_OFFSET_TABLE_ for .debug_info. The bug has been fixed
790830 // in 2017 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630), but we
791831 // need to keep this bug-compatible code for a while.
792 if (Config->EMachine == EM_386 && Type == R_386_GOTPC)
832 if (config->emachine == EM_386 && type == R_386_GOTPC)
793833 continue;
794834
795 uint64_t Offset = getOffset(Rel.r_offset);
796 uint8_t *BufLoc = Buf + Offset;
797 int64_t Addend = getAddend<ELFT>(Rel);
835 uint64_t offset = getOffset(rel.r_offset);
836 uint8_t *bufLoc = buf + offset;
837 int64_t addend = getAddend<ELFT>(rel);
798838 if (!RelTy::IsRela)
799 Addend += Target->getImplicitAddend(BufLoc, Type);
839 addend += target->getImplicitAddend(bufLoc, type);
800840
801 Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
802 RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc);
803 if (Expr == R_NONE)
841 Symbol &sym = getFile<ELFT>()->getRelocTargetSym(rel);
842 RelExpr expr = target->getRelExpr(type, sym, bufLoc);
843 if (expr == R_NONE)
804844 continue;
805845
806 if (Expr != R_ABS) {
807 std::string Msg = getLocation<ELFT>(Offset) +
808 ": has non-ABS relocation " + toString(Type) +
809 " against symbol '" + toString(Sym) + "'";
810 if (Expr != R_PC) {
811 error(Msg);
846 if (expr != R_ABS && expr != R_DTPREL && expr != R_RISCV_ADD) {
847 std::string msg = getLocation<ELFT>(offset) +
848 ": has non-ABS relocation " + toString(type) +
849 " against symbol '" + toString(sym) + "'";
850 if (expr != R_PC) {
851 error(msg);
812852 return;
813853 }
814854
......@@ -819,16 +859,16 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
819859 // relocations without any errors and relocate them as if they were at
820860 // address 0. For bug-compatibilty, we accept them with warnings. We
821861 // know Steel Bank Common Lisp as of 2018 have this bug.
822 warn(Msg);
823 Target->relocateOne(BufLoc, Type,
824 SignExtend64<Bits>(Sym.getVA(Addend - Offset)));
862 warn(msg);
863 target->relocateOne(bufLoc, type,
864 SignExtend64<bits>(sym.getVA(addend - offset)));
825865 continue;
826866 }
827867
828 if (Sym.isTls() && !Out::TlsPhdr)
829 Target->relocateOne(BufLoc, Type, 0);
868 if (sym.isTls() && !Out::tlsPhdr)
869 target->relocateOne(bufLoc, type, 0);
830870 else
831 Target->relocateOne(BufLoc, Type, SignExtend64<Bits>(Sym.getVA(Addend)));
871 target->relocateOne(bufLoc, type, SignExtend64<bits>(sym.getVA(addend)));
832872 }
833873}
834874
......@@ -837,96 +877,100 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
837877// relocations aimed to update addends. They are handled in relocateAlloc()
838878// for allocatable sections, and this function does the same for
839879// non-allocatable sections, such as sections with debug information.
840static void relocateNonAllocForRelocatable(InputSection *Sec, uint8_t *Buf) {
841 const unsigned Bits = Config->Is64 ? 64 : 32;
880static void relocateNonAllocForRelocatable(InputSection *sec, uint8_t *buf) {
881 const unsigned bits = config->is64 ? 64 : 32;
842882
843 for (const Relocation &Rel : Sec->Relocations) {
883 for (const Relocation &rel : sec->relocations) {
844884 // InputSection::copyRelocations() adds only R_ABS relocations.
845 assert(Rel.Expr == R_ABS);
846 uint8_t *BufLoc = Buf + Rel.Offset + Sec->OutSecOff;
847 uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits);
848 Target->relocateOne(BufLoc, Rel.Type, TargetVA);
885 assert(rel.expr == R_ABS);
886 uint8_t *bufLoc = buf + rel.offset + sec->outSecOff;
887 uint64_t targetVA = SignExtend64(rel.sym->getVA(rel.addend), bits);
888 target->relocateOne(bufLoc, rel.type, targetVA);
849889 }
850890}
851891
852892template <class ELFT>
853void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
854 if (Flags & SHF_EXECINSTR)
855 adjustSplitStackFunctionPrologues<ELFT>(Buf, BufEnd);
893void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
894 if (flags & SHF_EXECINSTR)
895 adjustSplitStackFunctionPrologues<ELFT>(buf, bufEnd);
856896
857 if (Flags & SHF_ALLOC) {
858 relocateAlloc(Buf, BufEnd);
897 if (flags & SHF_ALLOC) {
898 relocateAlloc(buf, bufEnd);
859899 return;
860900 }
861901
862 auto *Sec = cast<InputSection>(this);
863 if (Config->Relocatable)
864 relocateNonAllocForRelocatable(Sec, Buf);
865 else if (Sec->AreRelocsRela)
866 Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>());
902 auto *sec = cast<InputSection>(this);
903 if (config->relocatable)
904 relocateNonAllocForRelocatable(sec, buf);
905 else if (sec->areRelocsRela)
906 sec->relocateNonAlloc<ELFT>(buf, sec->template relas<ELFT>());
867907 else
868 Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>());
908 sec->relocateNonAlloc<ELFT>(buf, sec->template rels<ELFT>());
869909}
870910
871void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
872 assert(Flags & SHF_ALLOC);
873 const unsigned Bits = Config->Wordsize * 8;
911void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
912 assert(flags & SHF_ALLOC);
913 const unsigned bits = config->wordsize * 8;
874914
875 for (const Relocation &Rel : Relocations) {
876 uint64_t Offset = Rel.Offset;
877 if (auto *Sec = dyn_cast<InputSection>(this))
878 Offset += Sec->OutSecOff;
879 uint8_t *BufLoc = Buf + Offset;
880 RelType Type = Rel.Type;
915 for (const Relocation &rel : relocations) {
916 uint64_t offset = rel.offset;
917 if (auto *sec = dyn_cast<InputSection>(this))
918 offset += sec->outSecOff;
919 uint8_t *bufLoc = buf + offset;
920 RelType type = rel.type;
881921
882 uint64_t AddrLoc = getOutputSection()->Addr + Offset;
883 RelExpr Expr = Rel.Expr;
884 uint64_t TargetVA = SignExtend64(
885 getRelocTargetVA(File, Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr),
886 Bits);
922 uint64_t addrLoc = getOutputSection()->addr + offset;
923 RelExpr expr = rel.expr;
924 uint64_t targetVA = SignExtend64(
925 getRelocTargetVA(file, type, rel.addend, addrLoc, *rel.sym, expr),
926 bits);
887927
888 switch (Expr) {
928 switch (expr) {
889929 case R_RELAX_GOT_PC:
890930 case R_RELAX_GOT_PC_NOPIC:
891 Target->relaxGot(BufLoc, TargetVA);
931 target->relaxGot(bufLoc, type, targetVA);
932 break;
933 case R_PPC64_RELAX_TOC:
934 if (!tryRelaxPPC64TocIndirection(type, rel, bufLoc))
935 target->relocateOne(bufLoc, type, targetVA);
892936 break;
893937 case R_RELAX_TLS_IE_TO_LE:
894 Target->relaxTlsIeToLe(BufLoc, Type, TargetVA);
938 target->relaxTlsIeToLe(bufLoc, type, targetVA);
895939 break;
896940 case R_RELAX_TLS_LD_TO_LE:
897941 case R_RELAX_TLS_LD_TO_LE_ABS:
898 Target->relaxTlsLdToLe(BufLoc, Type, TargetVA);
942 target->relaxTlsLdToLe(bufLoc, type, targetVA);
899943 break;
900944 case R_RELAX_TLS_GD_TO_LE:
901945 case R_RELAX_TLS_GD_TO_LE_NEG:
902 Target->relaxTlsGdToLe(BufLoc, Type, TargetVA);
946 target->relaxTlsGdToLe(bufLoc, type, targetVA);
903947 break;
904948 case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
905949 case R_RELAX_TLS_GD_TO_IE:
906950 case R_RELAX_TLS_GD_TO_IE_ABS:
907951 case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
908 case R_RELAX_TLS_GD_TO_IE_END:
909 Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);
952 case R_RELAX_TLS_GD_TO_IE_GOTPLT:
953 target->relaxTlsGdToIe(bufLoc, type, targetVA);
910954 break;
911 case R_PPC_CALL:
955 case R_PPC64_CALL:
912956 // If this is a call to __tls_get_addr, it may be part of a TLS
913957 // sequence that has been relaxed and turned into a nop. In this
914958 // case, we don't want to handle it as a call.
915 if (read32(BufLoc) == 0x60000000) // nop
959 if (read32(bufLoc) == 0x60000000) // nop
916960 break;
917961
918962 // Patch a nop (0x60000000) to a ld.
919 if (Rel.Sym->NeedsTocRestore) {
920 if (BufLoc + 8 > BufEnd || read32(BufLoc + 4) != 0x60000000) {
921 error(getErrorLocation(BufLoc) + "call lacks nop, can't restore toc");
963 if (rel.sym->needsTocRestore) {
964 if (bufLoc + 8 > bufEnd || read32(bufLoc + 4) != 0x60000000) {
965 error(getErrorLocation(bufLoc) + "call lacks nop, can't restore toc");
922966 break;
923967 }
924 write32(BufLoc + 4, 0xe8410018); // ld %r2, 24(%r1)
968 write32(bufLoc + 4, 0xe8410018); // ld %r2, 24(%r1)
925969 }
926 Target->relocateOne(BufLoc, Type, TargetVA);
970 target->relocateOne(bufLoc, type, targetVA);
927971 break;
928972 default:
929 Target->relocateOne(BufLoc, Type, TargetVA);
973 target->relocateOne(bufLoc, type, targetVA);
930974 break;
931975 }
932976 }
......@@ -935,44 +979,44 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
935979// For each function-defining prologue, find any calls to __morestack,
936980// and replace them with calls to __morestack_non_split.
937981static void switchMorestackCallsToMorestackNonSplit(
938 DenseSet<Defined *> &Prologues, std::vector<Relocation *> &MorestackCalls) {
982 DenseSet<Defined *> &prologues, std::vector<Relocation *> &morestackCalls) {
939983
940984 // If the target adjusted a function's prologue, all calls to
941985 // __morestack inside that function should be switched to
942986 // __morestack_non_split.
943 Symbol *MoreStackNonSplit = Symtab->find("__morestack_non_split");
944 if (!MoreStackNonSplit) {
987 Symbol *moreStackNonSplit = symtab->find("__morestack_non_split");
988 if (!moreStackNonSplit) {
945989 error("Mixing split-stack objects requires a definition of "
946990 "__morestack_non_split");
947991 return;
948992 }
949993
950994 // Sort both collections to compare addresses efficiently.
951 llvm::sort(MorestackCalls, [](const Relocation *L, const Relocation *R) {
952 return L->Offset < R->Offset;
995 llvm::sort(morestackCalls, [](const Relocation *l, const Relocation *r) {
996 return l->offset < r->offset;
953997 });
954 std::vector<Defined *> Functions(Prologues.begin(), Prologues.end());
955 llvm::sort(Functions, [](const Defined *L, const Defined *R) {
956 return L->Value < R->Value;
998 std::vector<Defined *> functions(prologues.begin(), prologues.end());
999 llvm::sort(functions, [](const Defined *l, const Defined *r) {
1000 return l->value < r->value;
9571001 });
9581002
959 auto It = MorestackCalls.begin();
960 for (Defined *F : Functions) {
1003 auto it = morestackCalls.begin();
1004 for (Defined *f : functions) {
9611005 // Find the first call to __morestack within the function.
962 while (It != MorestackCalls.end() && (*It)->Offset < F->Value)
963 ++It;
1006 while (it != morestackCalls.end() && (*it)->offset < f->value)
1007 ++it;
9641008 // Adjust all calls inside the function.
965 while (It != MorestackCalls.end() && (*It)->Offset < F->Value + F->Size) {
966 (*It)->Sym = MoreStackNonSplit;
967 ++It;
1009 while (it != morestackCalls.end() && (*it)->offset < f->value + f->size) {
1010 (*it)->sym = moreStackNonSplit;
1011 ++it;
9681012 }
9691013 }
9701014}
9711015
972static bool enclosingPrologueAttempted(uint64_t Offset,
973 const DenseSet<Defined *> &Prologues) {
974 for (Defined *F : Prologues)
975 if (F->Value <= Offset && Offset < F->Value + F->Size)
1016static bool enclosingPrologueAttempted(uint64_t offset,
1017 const DenseSet<Defined *> &prologues) {
1018 for (Defined *f : prologues)
1019 if (f->value <= offset && offset < f->value + f->size)
9761020 return true;
9771021 return false;
9781022}
......@@ -982,30 +1026,30 @@ static bool enclosingPrologueAttempted(uint64_t Offset,
9821026// adjusted to ensure that the called function will have enough stack
9831027// available. Find those functions, and adjust their prologues.
9841028template <class ELFT>
985void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
986 uint8_t *End) {
987 if (!getFile<ELFT>()->SplitStack)
1029void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
1030 uint8_t *end) {
1031 if (!getFile<ELFT>()->splitStack)
9881032 return;
989 DenseSet<Defined *> Prologues;
990 std::vector<Relocation *> MorestackCalls;
1033 DenseSet<Defined *> prologues;
1034 std::vector<Relocation *> morestackCalls;
9911035
992 for (Relocation &Rel : Relocations) {
1036 for (Relocation &rel : relocations) {
9931037 // Local symbols can't possibly be cross-calls, and should have been
9941038 // resolved long before this line.
995 if (Rel.Sym->isLocal())
1039 if (rel.sym->isLocal())
9961040 continue;
9971041
9981042 // Ignore calls into the split-stack api.
999 if (Rel.Sym->getName().startswith("__morestack")) {
1000 if (Rel.Sym->getName().equals("__morestack"))
1001 MorestackCalls.push_back(&Rel);
1043 if (rel.sym->getName().startswith("__morestack")) {
1044 if (rel.sym->getName().equals("__morestack"))
1045 morestackCalls.push_back(&rel);
10021046 continue;
10031047 }
10041048
10051049 // A relocation to non-function isn't relevant. Sometimes
10061050 // __morestack is not marked as a function, so this check comes
10071051 // after the name check.
1008 if (Rel.Sym->Type != STT_FUNC)
1052 if (rel.sym->type != STT_FUNC)
10091053 continue;
10101054
10111055 // If the callee's-file was compiled with split stack, nothing to do. In
......@@ -1013,106 +1057,117 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
10131057 // being produced". So an "undefined" symbol might be provided by a shared
10141058 // library. It is not possible to tell how such symbols were compiled, so be
10151059 // 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)
1060 if (Defined *d = dyn_cast<Defined>(rel.sym))
1061 if (InputSection *isec = cast_or_null<InputSection>(d->section))
1062 if (!isec || !isec->getFile<ELFT>() || isec->getFile<ELFT>()->splitStack)
10191063 continue;
10201064
1021 if (enclosingPrologueAttempted(Rel.Offset, Prologues))
1065 if (enclosingPrologueAttempted(rel.offset, prologues))
10221066 continue;
10231067
1024 if (Defined *F = getEnclosingFunction<ELFT>(Rel.Offset)) {
1025 Prologues.insert(F);
1026 if (Target->adjustPrologueForCrossSplitStack(Buf + getOffset(F->Value),
1027 End, F->StOther))
1068 if (Defined *f = getEnclosingFunction<ELFT>(rel.offset)) {
1069 prologues.insert(f);
1070 if (target->adjustPrologueForCrossSplitStack(buf + getOffset(f->value),
1071 end, f->stOther))
10281072 continue;
1029 if (!getFile<ELFT>()->SomeNoSplitStack)
1030 error(lld::toString(this) + ": " + F->getName() +
1031 " (with -fsplit-stack) calls " + Rel.Sym->getName() +
1073 if (!getFile<ELFT>()->someNoSplitStack)
1074 error(lld::toString(this) + ": " + f->getName() +
1075 " (with -fsplit-stack) calls " + rel.sym->getName() +
10321076 " (without -fsplit-stack), but couldn't adjust its prologue");
10331077 }
10341078 }
10351079
1036 if (Target->NeedsMoreStackNonSplit)
1037 switchMorestackCallsToMorestackNonSplit(Prologues, MorestackCalls);
1080 if (target->needsMoreStackNonSplit)
1081 switchMorestackCallsToMorestackNonSplit(prologues, morestackCalls);
10381082}
10391083
1040template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
1041 if (Type == SHT_NOBITS)
1084template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
1085 if (type == SHT_NOBITS)
10421086 return;
10431087
1044 if (auto *S = dyn_cast<SyntheticSection>(this)) {
1045 S->writeTo(Buf + OutSecOff);
1088 if (auto *s = dyn_cast<SyntheticSection>(this)) {
1089 s->writeTo(buf + outSecOff);
10461090 return;
10471091 }
10481092
10491093 // If -r or --emit-relocs is given, then an InputSection
10501094 // may be a relocation section.
1051 if (Type == SHT_RELA) {
1052 copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rela>());
1095 if (type == SHT_RELA) {
1096 copyRelocations<ELFT>(buf + outSecOff, getDataAs<typename ELFT::Rela>());
10531097 return;
10541098 }
1055 if (Type == SHT_REL) {
1056 copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rel>());
1099 if (type == SHT_REL) {
1100 copyRelocations<ELFT>(buf + outSecOff, getDataAs<typename ELFT::Rel>());
10571101 return;
10581102 }
10591103
10601104 // If -r is given, we may have a SHT_GROUP section.
1061 if (Type == SHT_GROUP) {
1062 copyShtGroup<ELFT>(Buf + OutSecOff);
1105 if (type == SHT_GROUP) {
1106 copyShtGroup<ELFT>(buf + outSecOff);
10631107 return;
10641108 }
10651109
10661110 // If this is a compressed section, uncompress section contents directly
10671111 // 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))
1112 if (uncompressedSize >= 0) {
1113 size_t size = uncompressedSize;
1114 if (Error e = zlib::uncompress(toStringRef(rawData),
1115 (char *)(buf + outSecOff), size))
10721116 fatal(toString(this) +
1073 ": uncompress failed: " + llvm::toString(std::move(E)));
1074 uint8_t *BufEnd = Buf + OutSecOff + Size;
1075 relocate<ELFT>(Buf, BufEnd);
1117 ": uncompress failed: " + llvm::toString(std::move(e)));
1118 uint8_t *bufEnd = buf + outSecOff + size;
1119 relocate<ELFT>(buf, bufEnd);
10761120 return;
10771121 }
10781122
10791123 // Copy section contents from source object file to output file
10801124 // and then apply relocations.
1081 memcpy(Buf + OutSecOff, data().data(), data().size());
1082 uint8_t *BufEnd = Buf + OutSecOff + data().size();
1083 relocate<ELFT>(Buf, BufEnd);
1125 memcpy(buf + outSecOff, data().data(), data().size());
1126 uint8_t *bufEnd = buf + outSecOff + data().size();
1127 relocate<ELFT>(buf, bufEnd);
10841128}
10851129
1086void InputSection::replace(InputSection *Other) {
1087 Alignment = std::max(Alignment, Other->Alignment);
1088 Other->Repl = Repl;
1089 Other->Live = false;
1130void InputSection::replace(InputSection *other) {
1131 alignment = std::max(alignment, other->alignment);
1132
1133 // When a section is replaced with another section that was allocated to
1134 // another partition, the replacement section (and its associated sections)
1135 // need to be placed in the main partition so that both partitions will be
1136 // able to access it.
1137 if (partition != other->partition) {
1138 partition = 1;
1139 for (InputSection *isec : dependentSections)
1140 isec->partition = 1;
1141 }
1142
1143 other->repl = repl;
1144 other->markDead();
10901145}
10911146
10921147template <class ELFT>
1093EhInputSection::EhInputSection(ObjFile<ELFT> &F,
1094 const typename ELFT::Shdr &Header,
1095 StringRef Name)
1096 : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) {}
1148EhInputSection::EhInputSection(ObjFile<ELFT> &f,
1149 const typename ELFT::Shdr &header,
1150 StringRef name)
1151 : InputSectionBase(f, header, name, InputSectionBase::EHFrame) {}
10971152
10981153SyntheticSection *EhInputSection::getParent() const {
1099 return cast_or_null<SyntheticSection>(Parent);
1154 return cast_or_null<SyntheticSection>(parent);
11001155}
11011156
11021157// Returns the index of the first relocation that points to a region between
11031158// Begin and Begin+Size.
11041159template <class IntTy, class RelTy>
1105static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels,
1106 unsigned &RelocI) {
1160static unsigned getReloc(IntTy begin, IntTy size, const ArrayRef<RelTy> &rels,
1161 unsigned &relocI) {
11071162 // Start search from RelocI for fast access. That works because the
11081163 // relocations are sorted in .eh_frame.
1109 for (unsigned N = Rels.size(); RelocI < N; ++RelocI) {
1110 const RelTy &Rel = Rels[RelocI];
1111 if (Rel.r_offset < Begin)
1164 for (unsigned n = rels.size(); relocI < n; ++relocI) {
1165 const RelTy &rel = rels[relocI];
1166 if (rel.r_offset < begin)
11121167 continue;
11131168
1114 if (Rel.r_offset < Begin + Size)
1115 return RelocI;
1169 if (rel.r_offset < begin + size)
1170 return relocI;
11161171 return -1;
11171172 }
11181173 return -1;
......@@ -1121,84 +1176,84 @@ static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels,
11211176// .eh_frame is a sequence of CIE or FDE records.
11221177// This function splits an input section into records and returns them.
11231178template <class ELFT> void EhInputSection::split() {
1124 if (AreRelocsRela)
1179 if (areRelocsRela)
11251180 split<ELFT>(relas<ELFT>());
11261181 else
11271182 split<ELFT>(rels<ELFT>());
11281183}
11291184
11301185template <class ELFT, class RelTy>
1131void EhInputSection::split(ArrayRef<RelTy> Rels) {
1132 unsigned RelI = 0;
1133 for (size_t Off = 0, End = data().size(); Off != End;) {
1134 size_t Size = readEhRecordSize(this, Off);
1135 Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
1186void EhInputSection::split(ArrayRef<RelTy> rels) {
1187 unsigned relI = 0;
1188 for (size_t off = 0, end = data().size(); off != end;) {
1189 size_t size = readEhRecordSize(this, off);
1190 pieces.emplace_back(off, this, size, getReloc(off, size, rels, relI));
11361191 // The empty record is the end marker.
1137 if (Size == 4)
1192 if (size == 4)
11381193 break;
1139 Off += Size;
1194 off += size;
11401195 }
11411196}
11421197
1143static size_t findNull(StringRef S, size_t EntSize) {
1198static size_t findNull(StringRef s, size_t entSize) {
11441199 // Optimize the common case.
1145 if (EntSize == 1)
1146 return S.find(0);
1200 if (entSize == 1)
1201 return s.find(0);
11471202
1148 for (unsigned I = 0, N = S.size(); I != N; I += EntSize) {
1149 const char *B = S.begin() + I;
1150 if (std::all_of(B, B + EntSize, [](char C) { return C == 0; }))
1151 return I;
1203 for (unsigned i = 0, n = s.size(); i != n; i += entSize) {
1204 const char *b = s.begin() + i;
1205 if (std::all_of(b, b + entSize, [](char c) { return c == 0; }))
1206 return i;
11521207 }
11531208 return StringRef::npos;
11541209}
11551210
11561211SyntheticSection *MergeInputSection::getParent() const {
1157 return cast_or_null<SyntheticSection>(Parent);
1212 return cast_or_null<SyntheticSection>(parent);
11581213}
11591214
11601215// Split SHF_STRINGS section. Such section is a sequence of
11611216// null-terminated strings.
1162void MergeInputSection::splitStrings(ArrayRef<uint8_t> Data, size_t EntSize) {
1163 size_t Off = 0;
1164 bool IsAlloc = Flags & SHF_ALLOC;
1165 StringRef S = toStringRef(Data);
1166
1167 while (!S.empty()) {
1168 size_t End = findNull(S, EntSize);
1169 if (End == StringRef::npos)
1217void MergeInputSection::splitStrings(ArrayRef<uint8_t> data, size_t entSize) {
1218 size_t off = 0;
1219 bool isAlloc = flags & SHF_ALLOC;
1220 StringRef s = toStringRef(data);
1221
1222 while (!s.empty()) {
1223 size_t end = findNull(s, entSize);
1224 if (end == StringRef::npos)
11701225 fatal(toString(this) + ": string is not null terminated");
1171 size_t Size = End + EntSize;
1226 size_t size = end + entSize;
11721227
1173 Pieces.emplace_back(Off, xxHash64(S.substr(0, Size)), !IsAlloc);
1174 S = S.substr(Size);
1175 Off += Size;
1228 pieces.emplace_back(off, xxHash64(s.substr(0, size)), !isAlloc);
1229 s = s.substr(size);
1230 off += size;
11761231 }
11771232}
11781233
11791234// Split non-SHF_STRINGS section. Such section is a sequence of
11801235// fixed size records.
1181void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data,
1182 size_t EntSize) {
1183 size_t Size = Data.size();
1184 assert((Size % EntSize) == 0);
1185 bool IsAlloc = Flags & SHF_ALLOC;
1186
1187 for (size_t I = 0; I != Size; I += EntSize)
1188 Pieces.emplace_back(I, xxHash64(Data.slice(I, EntSize)), !IsAlloc);
1236void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> data,
1237 size_t entSize) {
1238 size_t size = data.size();
1239 assert((size % entSize) == 0);
1240 bool isAlloc = flags & SHF_ALLOC;
1241
1242 for (size_t i = 0; i != size; i += entSize)
1243 pieces.emplace_back(i, xxHash64(data.slice(i, entSize)), !isAlloc);
11891244}
11901245
11911246template <class ELFT>
1192MergeInputSection::MergeInputSection(ObjFile<ELFT> &F,
1193 const typename ELFT::Shdr &Header,
1194 StringRef Name)
1195 : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {}
1247MergeInputSection::MergeInputSection(ObjFile<ELFT> &f,
1248 const typename ELFT::Shdr &header,
1249 StringRef name)
1250 : InputSectionBase(f, header, name, InputSectionBase::Merge) {}
11961251
1197MergeInputSection::MergeInputSection(uint64_t Flags, uint32_t Type,
1198 uint64_t Entsize, ArrayRef<uint8_t> Data,
1199 StringRef Name)
1200 : InputSectionBase(nullptr, Flags, Type, Entsize, /*Link*/ 0, /*Info*/ 0,
1201 /*Alignment*/ Entsize, Data, Name, SectionBase::Merge) {}
1252MergeInputSection::MergeInputSection(uint64_t flags, uint32_t type,
1253 uint64_t entsize, ArrayRef<uint8_t> data,
1254 StringRef name)
1255 : InputSectionBase(nullptr, flags, type, entsize, /*Link*/ 0, /*Info*/ 0,
1256 /*Alignment*/ entsize, data, name, SectionBase::Merge) {}
12021257
12031258// This function is called after we obtain a complete list of input sections
12041259// that need to be linked. This is responsible to split section contents
......@@ -1207,37 +1262,35 @@ MergeInputSection::MergeInputSection(uint64_t Flags, uint32_t Type,
12071262// Note that this function is called from parallelForEach. This must be
12081263// thread-safe (i.e. no memory allocation from the pools).
12091264void MergeInputSection::splitIntoPieces() {
1210 assert(Pieces.empty());
1265 assert(pieces.empty());
12111266
1212 if (Flags & SHF_STRINGS)
1213 splitStrings(data(), Entsize);
1267 if (flags & SHF_STRINGS)
1268 splitStrings(data(), entsize);
12141269 else
1215 splitNonStrings(data(), Entsize);
1270 splitNonStrings(data(), entsize);
12161271}
12171272
1218SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {
1219 if (this->data().size() <= Offset)
1273SectionPiece *MergeInputSection::getSectionPiece(uint64_t offset) {
1274 if (this->data().size() <= offset)
12201275 fatal(toString(this) + ": offset is outside the section");
12211276
12221277 // If Offset is not at beginning of a section piece, it is not in the map.
12231278 // 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];
1279 auto it = partition_point(
1280 pieces, [=](SectionPiece p) { return p.inputOff <= offset; });
1281 return &it[-1];
12291282}
12301283
12311284// Returns the offset in an output section for a given input offset.
12321285// Because contents of a mergeable section is not contiguous in output,
12331286// it is not just an addition to a base output offset.
1234uint64_t MergeInputSection::getParentOffset(uint64_t Offset) const {
1287uint64_t MergeInputSection::getParentOffset(uint64_t offset) const {
12351288 // If Offset is not at beginning of a section piece, it is not in the map.
12361289 // In that case we need to search from the original section piece vector.
1237 const SectionPiece &Piece =
1238 *(const_cast<MergeInputSection *>(this)->getSectionPiece (Offset));
1239 uint64_t Addend = Offset - Piece.InputOff;
1240 return Piece.OutputOff + Addend;
1290 const SectionPiece &piece =
1291 *(const_cast<MergeInputSection *>(this)->getSectionPiece (offset));
1292 uint64_t addend = offset - piece.inputOff;
1293 return piece.outputOff + addend;
12411294}
12421295
12431296template InputSection::InputSection(ObjFile<ELF32LE> &, const ELF32LE::Shdr &,
deps/lld/ELF/InputSection.h+143-135
......@@ -1,9 +1,8 @@
11//===- InputSection.h -------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -26,11 +25,14 @@ class Symbol;
2625struct SectionPiece;
2726
2827class Defined;
28struct Partition;
2929class SyntheticSection;
3030class MergeSyntheticSection;
3131template <class ELFT> class ObjFile;
3232class OutputSection;
3333
34extern std::vector<Partition> partitions;
35
3436// This is the base class of all sections that lld handles. Some are sections in
3537// input files, some are sections in the produced output file and some exist
3638// just as a convenience for implementing special ways of combining some
......@@ -39,38 +41,53 @@ class SectionBase {
3941public:
4042 enum Kind { Regular, EHFrame, Merge, Synthetic, Output };
4143
42 Kind kind() const { return (Kind)SectionKind; }
44 Kind kind() const { return (Kind)sectionKind; }
4345
44 StringRef Name;
46 StringRef name;
4547
4648 // This pointer points to the "real" instance of this instance.
4749 // Usually Repl == this. However, if ICF merges two sections,
4850 // Repl pointer of one section points to another section. So,
4951 // if you need to get a pointer to this instance, do not use
5052 // this but instead this->Repl.
51 SectionBase *Repl;
53 SectionBase *repl;
5254
53 unsigned SectionKind : 3;
55 unsigned sectionKind : 3;
5456
55 // The next two bit fields are only used by InputSectionBase, but we
57 // The next three bit fields are only used by InputSectionBase, but we
5658 // put them here so the struct packs better.
5759
58 // The garbage collector sets sections' Live bits.
59 // If GC is disabled, all sections are considered live by default.
60 unsigned Live : 1;
60 // True if this section has already been placed to a linker script
61 // output section. This is needed because, in a linker script, you
62 // can refer to the same section more than once. For example, in
63 // the following linker script,
64 //
65 // .foo : { *(.text) }
66 // .bar : { *(.text) }
67 //
68 // .foo takes all .text sections, and .bar becomes empty. To achieve
69 // this, we need to memorize whether a section has been placed or
70 // not for each input section.
71 unsigned assigned : 1;
6172
62 unsigned Bss : 1;
73 unsigned bss : 1;
6374
6475 // Set for sections that should not be folded by ICF.
65 unsigned KeepUnique : 1;
76 unsigned keepUnique : 1;
77
78 // The 1-indexed partition that this section is assigned to by the garbage
79 // collector, or 0 if this section is dead. Normally there is only one
80 // partition, so this will either be 0 or 1.
81 uint8_t partition;
82 elf::Partition &getPartition() const;
6683
6784 // These corresponds to the fields in Elf_Shdr.
68 uint32_t Alignment;
69 uint64_t Flags;
70 uint64_t Entsize;
71 uint32_t Type;
72 uint32_t Link;
73 uint32_t Info;
85 uint32_t alignment;
86 uint64_t flags;
87 uint64_t entsize;
88 uint32_t type;
89 uint32_t link;
90 uint32_t info;
7491
7592 OutputSection *getOutputSection();
7693 const OutputSection *getOutputSection() const {
......@@ -79,90 +96,81 @@ public:
7996
8097 // Translate an offset in the input section to an offset in the output
8198 // section.
82 uint64_t getOffset(uint64_t Offset) const;
99 uint64_t getOffset(uint64_t offset) const;
83100
84 uint64_t getVA(uint64_t Offset = 0) const;
101 uint64_t getVA(uint64_t offset = 0) const;
102
103 bool isLive() const { return partition != 0; }
104 void markLive() { partition = 1; }
105 void markDead() { partition = 0; }
85106
86107protected:
87 SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
88 uint64_t Entsize, uint64_t Alignment, uint32_t Type,
89 uint32_t Info, uint32_t Link)
90 : Name(Name), Repl(this), SectionKind(SectionKind), Live(false),
91 Bss(false), KeepUnique(false), Alignment(Alignment), Flags(Flags),
92 Entsize(Entsize), Type(Type), Link(Link), Info(Info) {}
108 SectionBase(Kind sectionKind, StringRef name, uint64_t flags,
109 uint64_t entsize, uint64_t alignment, uint32_t type,
110 uint32_t info, uint32_t link)
111 : name(name), repl(this), sectionKind(sectionKind), assigned(false),
112 bss(false), keepUnique(false), partition(0), alignment(alignment),
113 flags(flags), entsize(entsize), type(type), link(link), info(info) {}
93114};
94115
95116// This corresponds to a section of an input file.
96117class InputSectionBase : public SectionBase {
97118public:
98119 template <class ELFT>
99 InputSectionBase(ObjFile<ELFT> &File, const typename ELFT::Shdr &Header,
100 StringRef Name, Kind SectionKind);
120 InputSectionBase(ObjFile<ELFT> &file, const typename ELFT::Shdr &header,
121 StringRef name, Kind sectionKind);
122
123 InputSectionBase(InputFile *file, uint64_t flags, uint32_t type,
124 uint64_t entsize, uint32_t link, uint32_t info,
125 uint32_t alignment, ArrayRef<uint8_t> data, StringRef name,
126 Kind sectionKind);
101127
102 InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type,
103 uint64_t Entsize, uint32_t Link, uint32_t Info,
104 uint32_t Alignment, ArrayRef<uint8_t> Data, StringRef Name,
105 Kind SectionKind);
128 static bool classof(const SectionBase *s) { return s->kind() != Output; }
106129
107 static bool classof(const SectionBase *S) { return S->kind() != Output; }
130 // Relocations that refer to this section.
131 unsigned numRelocations : 31;
132 unsigned areRelocsRela : 1;
133 const void *firstRelocation = nullptr;
108134
109135 // The file which contains this section. Its dynamic type is always
110136 // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as
111137 // its static type.
112 InputFile *File;
138 InputFile *file;
113139
114140 template <class ELFT> ObjFile<ELFT> *getFile() const {
115 return cast_or_null<ObjFile<ELFT>>(File);
141 return cast_or_null<ObjFile<ELFT>>(file);
116142 }
117143
118144 ArrayRef<uint8_t> data() const {
119 if (UncompressedSize >= 0 && !UncompressedBuf)
145 if (uncompressedSize >= 0)
120146 uncompress();
121 return RawData;
147 return rawData;
122148 }
123149
124150 uint64_t getOffsetInFile() const;
125151
126 // True if this section has already been placed to a linker script
127 // output section. This is needed because, in a linker script, you
128 // can refer to the same section more than once. For example, in
129 // the following linker script,
130 //
131 // .foo : { *(.text) }
132 // .bar : { *(.text) }
133 //
134 // .foo takes all .text sections, and .bar becomes empty. To achieve
135 // this, we need to memorize whether a section has been placed or
136 // not for each input section.
137 bool Assigned = false;
138
139152 // Input sections are part of an output section. Special sections
140153 // like .eh_frame and merge sections are first combined into a
141154 // synthetic section that is then added to an output section. In all
142155 // cases this points one level up.
143 SectionBase *Parent = nullptr;
144
145 // Relocations that refer to this section.
146 const void *FirstRelocation = nullptr;
147 unsigned NumRelocations : 31;
148 unsigned AreRelocsRela : 1;
156 SectionBase *parent = nullptr;
149157
150158 template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
151 assert(!AreRelocsRela);
159 assert(!areRelocsRela);
152160 return llvm::makeArrayRef(
153 static_cast<const typename ELFT::Rel *>(FirstRelocation),
154 NumRelocations);
161 static_cast<const typename ELFT::Rel *>(firstRelocation),
162 numRelocations);
155163 }
156164
157165 template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
158 assert(AreRelocsRela);
166 assert(areRelocsRela);
159167 return llvm::makeArrayRef(
160 static_cast<const typename ELFT::Rela *>(FirstRelocation),
161 NumRelocations);
168 static_cast<const typename ELFT::Rela *>(firstRelocation),
169 numRelocations);
162170 }
163171
164172 // InputSections that are dependent on us (reverse dependency for GC)
165 llvm::TinyPtrVector<InputSection *> DependentSections;
173 llvm::TinyPtrVector<InputSection *> dependentSections;
166174
167175 // Returns the size of this section (even if this is a common or BSS.)
168176 size_t getSize() const;
......@@ -172,23 +180,23 @@ public:
172180 // Get the function symbol that encloses this offset from within the
173181 // section.
174182 template <class ELFT>
175 Defined *getEnclosingFunction(uint64_t Offset);
183 Defined *getEnclosingFunction(uint64_t offset);
176184
177185 // Returns a source location string. Used to construct an error message.
178 template <class ELFT> std::string getLocation(uint64_t Offset);
179 std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
180 std::string getObjMsg(uint64_t Offset);
186 template <class ELFT> std::string getLocation(uint64_t offset);
187 std::string getSrcMsg(const Symbol &sym, uint64_t offset);
188 std::string getObjMsg(uint64_t offset);
181189
182190 // Each section knows how to relocate itself. These functions apply
183191 // relocations, assuming that Buf points to this section's copy in
184192 // the mmap'ed output buffer.
185 template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
186 void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);
193 template <class ELFT> void relocate(uint8_t *buf, uint8_t *bufEnd);
194 void relocateAlloc(uint8_t *buf, uint8_t *bufEnd);
187195
188196 // The native ELF reloc data type is not very convenient to handle.
189197 // So we convert ELF reloc records to our own records in Relocations.cpp.
190198 // This vector contains such "cooked" relocations.
191 std::vector<Relocation> Relocations;
199 std::vector<Relocation> relocations;
192200
193201 // A function compiled with -fsplit-stack calling a function
194202 // compiled without -fsplit-stack needs its prologue adjusted. Find
......@@ -196,25 +204,26 @@ public:
196204 // to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more
197205 // information.
198206 template <typename ELFT>
199 void adjustSplitStackFunctionPrologues(uint8_t *Buf, uint8_t *End);
207 void adjustSplitStackFunctionPrologues(uint8_t *buf, uint8_t *end);
200208
201209
202210 template <typename T> llvm::ArrayRef<T> getDataAs() const {
203 size_t S = data().size();
204 assert(S % sizeof(T) == 0);
205 return llvm::makeArrayRef<T>((const T *)data().data(), S / sizeof(T));
211 size_t s = data().size();
212 assert(s % sizeof(T) == 0);
213 return llvm::makeArrayRef<T>((const T *)data().data(), s / sizeof(T));
206214 }
207215
208216protected:
209217 void parseCompressedHeader();
210218 void uncompress() const;
211219
212 mutable ArrayRef<uint8_t> RawData;
220 mutable ArrayRef<uint8_t> rawData;
213221
214 // A pointer that owns uncompressed data if a section is compressed by zlib.
215 // Since the feature is not used often, this is usually a nullptr.
216 mutable std::unique_ptr<char[]> UncompressedBuf;
217 int64_t UncompressedSize = -1;
222 // This field stores the uncompressed size of the compressed data in rawData,
223 // or -1 if rawData is not compressed (either because the section wasn't
224 // compressed in the first place, or because we ended up uncompressing it).
225 // Since the feature is not used often, this is usually -1.
226 mutable int64_t uncompressedSize = -1;
218227};
219228
220229// SectionPiece represents a piece of splittable section contents.
......@@ -222,14 +231,13 @@ protected:
222231// have to be as compact as possible, which is why we don't store the size (can
223232// be found by looking at the next one).
224233struct SectionPiece {
225 SectionPiece(size_t Off, uint32_t Hash, bool Live)
226 : InputOff(Off), Hash(Hash), OutputOff(0),
227 Live(Live || !Config->GcSections) {}
228
229 uint32_t InputOff;
230 uint32_t Hash;
231 int64_t OutputOff : 63;
232 uint64_t Live : 1;
234 SectionPiece(size_t off, uint32_t hash, bool live)
235 : inputOff(off), live(live || !config->gcSections), hash(hash >> 1) {}
236
237 uint32_t inputOff;
238 uint32_t live : 1;
239 uint32_t hash : 31;
240 uint64_t outputOff = 0;
233241};
234242
235243static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
......@@ -238,74 +246,74 @@ static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");
238246class MergeInputSection : public InputSectionBase {
239247public:
240248 template <class ELFT>
241 MergeInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
242 StringRef Name);
243 MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize,
244 ArrayRef<uint8_t> Data, StringRef Name);
249 MergeInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
250 StringRef name);
251 MergeInputSection(uint64_t flags, uint32_t type, uint64_t entsize,
252 ArrayRef<uint8_t> data, StringRef name);
245253
246 static bool classof(const SectionBase *S) { return S->kind() == Merge; }
254 static bool classof(const SectionBase *s) { return s->kind() == Merge; }
247255 void splitIntoPieces();
248256
249257 // Translate an offset in the input section to an offset in the parent
250258 // MergeSyntheticSection.
251 uint64_t getParentOffset(uint64_t Offset) const;
259 uint64_t getParentOffset(uint64_t offset) const;
252260
253261 // Splittable sections are handled as a sequence of data
254262 // rather than a single large blob of data.
255 std::vector<SectionPiece> Pieces;
263 std::vector<SectionPiece> pieces;
256264
257265 // Returns I'th piece's data. This function is very hot when
258266 // string merging is enabled, so we want to inline.
259267 LLVM_ATTRIBUTE_ALWAYS_INLINE
260 llvm::CachedHashStringRef getData(size_t I) const {
261 size_t Begin = Pieces[I].InputOff;
262 size_t End =
263 (Pieces.size() - 1 == I) ? data().size() : Pieces[I + 1].InputOff;
264 return {toStringRef(data().slice(Begin, End - Begin)), Pieces[I].Hash};
268 llvm::CachedHashStringRef getData(size_t i) const {
269 size_t begin = pieces[i].inputOff;
270 size_t end =
271 (pieces.size() - 1 == i) ? data().size() : pieces[i + 1].inputOff;
272 return {toStringRef(data().slice(begin, end - begin)), pieces[i].hash};
265273 }
266274
267275 // Returns the SectionPiece at a given input section offset.
268 SectionPiece *getSectionPiece(uint64_t Offset);
269 const SectionPiece *getSectionPiece(uint64_t Offset) const {
270 return const_cast<MergeInputSection *>(this)->getSectionPiece(Offset);
276 SectionPiece *getSectionPiece(uint64_t offset);
277 const SectionPiece *getSectionPiece(uint64_t offset) const {
278 return const_cast<MergeInputSection *>(this)->getSectionPiece(offset);
271279 }
272280
273281 SyntheticSection *getParent() const;
274282
275283private:
276 void splitStrings(ArrayRef<uint8_t> A, size_t Size);
277 void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
284 void splitStrings(ArrayRef<uint8_t> a, size_t size);
285 void splitNonStrings(ArrayRef<uint8_t> a, size_t size);
278286};
279287
280288struct EhSectionPiece {
281 EhSectionPiece(size_t Off, InputSectionBase *Sec, uint32_t Size,
282 unsigned FirstRelocation)
283 : InputOff(Off), Sec(Sec), Size(Size), FirstRelocation(FirstRelocation) {}
289 EhSectionPiece(size_t off, InputSectionBase *sec, uint32_t size,
290 unsigned firstRelocation)
291 : inputOff(off), sec(sec), size(size), firstRelocation(firstRelocation) {}
284292
285293 ArrayRef<uint8_t> data() {
286 return {Sec->data().data() + this->InputOff, Size};
294 return {sec->data().data() + this->inputOff, size};
287295 }
288296
289 size_t InputOff;
290 ssize_t OutputOff = -1;
291 InputSectionBase *Sec;
292 uint32_t Size;
293 unsigned FirstRelocation;
297 size_t inputOff;
298 ssize_t outputOff = -1;
299 InputSectionBase *sec;
300 uint32_t size;
301 unsigned firstRelocation;
294302};
295303
296304// This corresponds to a .eh_frame section of an input file.
297305class EhInputSection : public InputSectionBase {
298306public:
299307 template <class ELFT>
300 EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
301 StringRef Name);
302 static bool classof(const SectionBase *S) { return S->kind() == EHFrame; }
308 EhInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
309 StringRef name);
310 static bool classof(const SectionBase *s) { return s->kind() == EHFrame; }
303311 template <class ELFT> void split();
304 template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
312 template <class ELFT, class RelTy> void split(ArrayRef<RelTy> rels);
305313
306314 // Splittable sections are handled as a sequence of data
307315 // rather than a single large blob of data.
308 std::vector<EhSectionPiece> Pieces;
316 std::vector<EhSectionPiece> pieces;
309317
310318 SyntheticSection *getParent() const;
311319};
......@@ -316,17 +324,17 @@ public:
316324// .eh_frame. It also includes the synthetic sections themselves.
317325class InputSection : public InputSectionBase {
318326public:
319 InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment,
320 ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
327 InputSection(InputFile *f, uint64_t flags, uint32_t type, uint32_t alignment,
328 ArrayRef<uint8_t> data, StringRef name, Kind k = Regular);
321329 template <class ELFT>
322 InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
323 StringRef Name);
330 InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
331 StringRef name);
324332
325333 // Write this section to a mmap'ed file, assuming Buf is pointing to
326334 // beginning of the output section.
327 template <class ELFT> void writeTo(uint8_t *Buf);
335 template <class ELFT> void writeTo(uint8_t *buf);
328336
329 uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }
337 uint64_t getOffset(uint64_t offset) const { return outSecOff + offset; }
330338
331339 OutputSection *getParent() const;
332340
......@@ -334,32 +342,32 @@ public:
334342 // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
335343 // sections. After assignAddresses is called, it represents the offset from
336344 // the beginning of the output section this section was assigned to.
337 uint64_t OutSecOff = 0;
345 uint64_t outSecOff = 0;
338346
339 static bool classof(const SectionBase *S);
347 static bool classof(const SectionBase *s);
340348
341349 InputSectionBase *getRelocatedSection() const;
342350
343351 template <class ELFT, class RelTy>
344 void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
352 void relocateNonAlloc(uint8_t *buf, llvm::ArrayRef<RelTy> rels);
345353
346354 // Used by ICF.
347 uint32_t Class[2] = {0, 0};
355 uint32_t eqClass[2] = {0, 0};
348356
349357 // Called by ICF to merge two input sections.
350 void replace(InputSection *Other);
358 void replace(InputSection *other);
351359
352 static InputSection Discarded;
360 static InputSection discarded;
353361
354362private:
355363 template <class ELFT, class RelTy>
356 void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
364 void copyRelocations(uint8_t *buf, llvm::ArrayRef<RelTy> rels);
357365
358 template <class ELFT> void copyShtGroup(uint8_t *Buf);
366 template <class ELFT> void copyShtGroup(uint8_t *buf);
359367};
360368
361369// The list of all input sections.
362extern std::vector<InputSectionBase *> InputSections;
370extern std::vector<InputSectionBase *> inputSections;
363371
364372} // namespace elf
365373
deps/lld/ELF/LTO.cpp+167-160
......@@ -1,9 +1,8 @@
11//===- LTO.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -13,6 +12,7 @@
1312#include "LinkerScript.h"
1413#include "SymbolTable.h"
1514#include "Symbols.h"
15#include "lld/Common/Args.h"
1616#include "lld/Common/ErrorHandler.h"
1717#include "lld/Common/TargetOptionsCommandFlags.h"
1818#include "llvm/ADT/STLExtras.h"
......@@ -47,134 +47,135 @@ using namespace lld::elf;
4747
4848// Creates an empty file to store a list of object files for final
4949// linking of distributed ThinLTO.
50static std::unique_ptr<raw_fd_ostream> openFile(StringRef File) {
51 std::error_code EC;
52 auto Ret =
53 llvm::make_unique<raw_fd_ostream>(File, EC, sys::fs::OpenFlags::F_None);
54 if (EC) {
55 error("cannot open " + File + ": " + EC.message());
50static std::unique_ptr<raw_fd_ostream> openFile(StringRef file) {
51 std::error_code ec;
52 auto ret =
53 llvm::make_unique<raw_fd_ostream>(file, ec, sys::fs::OpenFlags::F_None);
54 if (ec) {
55 error("cannot open " + file + ": " + ec.message());
5656 return nullptr;
5757 }
58 return Ret;
58 return ret;
5959}
6060
61static std::string getThinLTOOutputFile(StringRef ModulePath) {
62 return lto::getThinLTOOutputFile(ModulePath,
63 Config->ThinLTOPrefixReplace.first,
64 Config->ThinLTOPrefixReplace.second);
61static std::string getThinLTOOutputFile(StringRef modulePath) {
62 return lto::getThinLTOOutputFile(modulePath,
63 config->thinLTOPrefixReplace.first,
64 config->thinLTOPrefixReplace.second);
6565}
6666
6767static lto::Config createConfig() {
68 lto::Config C;
68 lto::Config c;
6969
7070 // LLD supports the new relocations and address-significance tables.
71 C.Options = InitTargetOptionsFromCodeGenFlags();
72 C.Options.RelaxELFRelocations = true;
73 C.Options.EmitAddrsig = true;
71 c.Options = initTargetOptionsFromCodeGenFlags();
72 c.Options.RelaxELFRelocations = true;
73 c.Options.EmitAddrsig = true;
7474
7575 // Always emit a section per function/datum with LTO.
76 C.Options.FunctionSections = true;
77 C.Options.DataSections = true;
76 c.Options.FunctionSections = true;
77 c.Options.DataSections = true;
7878
79 if (Config->Relocatable)
80 C.RelocModel = None;
81 else if (Config->Pic)
82 C.RelocModel = Reloc::PIC_;
79 if (config->relocatable)
80 c.RelocModel = None;
81 else if (config->isPic)
82 c.RelocModel = Reloc::PIC_;
8383 else
84 C.RelocModel = Reloc::Static;
84 c.RelocModel = Reloc::Static;
8585
86 C.CodeModel = GetCodeModelFromCMModel();
87 C.DisableVerify = Config->DisableVerify;
88 C.DiagHandler = diagnosticHandler;
89 C.OptLevel = Config->LTOO;
90 C.CPU = GetCPUStr();
91 C.MAttrs = GetMAttrs();
86 c.CodeModel = getCodeModelFromCMModel();
87 c.DisableVerify = config->disableVerify;
88 c.DiagHandler = diagnosticHandler;
89 c.OptLevel = config->ltoo;
90 c.CPU = getCPUStr();
91 c.MAttrs = getMAttrs();
92 c.CGOptLevel = args::getCGOptLevel(config->ltoo);
9293
9394 // Set up a custom pipeline if we've been asked to.
94 C.OptPipeline = Config->LTONewPmPasses;
95 C.AAPipeline = Config->LTOAAPipeline;
95 c.OptPipeline = config->ltoNewPmPasses;
96 c.AAPipeline = config->ltoAAPipeline;
9697
9798 // Set up optimization remarks if we've been asked to.
98 C.RemarksFilename = Config->OptRemarksFilename;
99 C.RemarksWithHotness = Config->OptRemarksWithHotness;
100
101 C.SampleProfile = Config->LTOSampleProfile;
102 C.UseNewPM = Config->LTONewPassManager;
103 C.DebugPassManager = Config->LTODebugPassManager;
104 C.DwoDir = Config->DwoDir;
105
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);
99 c.RemarksFilename = config->optRemarksFilename;
100 c.RemarksPasses = config->optRemarksPasses;
101 c.RemarksWithHotness = config->optRemarksWithHotness;
102 c.RemarksFormat = config->optRemarksFormat;
103
104 c.SampleProfile = config->ltoSampleProfile;
105 c.UseNewPM = config->ltoNewPassManager;
106 c.DebugPassManager = config->ltoDebugPassManager;
107 c.DwoDir = config->dwoDir;
108
109 c.CSIRProfile = config->ltoCSProfileFile;
110 c.RunCSIRInstr = config->ltoCSProfileGenerate;
111
112 if (config->emitLLVM) {
113 c.PostInternalizeModuleHook = [](size_t task, const Module &m) {
114 if (std::unique_ptr<raw_fd_ostream> os = openFile(config->outputFile))
115 WriteBitcodeToFile(m, *os, false);
110116 return false;
111117 };
112118 }
113119
114 if (Config->SaveTemps)
115 checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
120 if (config->saveTemps)
121 checkError(c.addSaveTemps(config->outputFile.str() + ".",
116122 /*UseInputModulePath*/ true));
117 return C;
123 return c;
118124}
119125
120126BitcodeCompiler::BitcodeCompiler() {
121 // Initialize IndexFile.
122 if (!Config->ThinLTOIndexOnlyArg.empty())
123 IndexFile = openFile(Config->ThinLTOIndexOnlyArg);
124
125 // Initialize LTOObj.
126 lto::ThinBackend Backend;
127 if (Config->ThinLTOIndexOnly) {
128 auto OnIndexWrite = [&](StringRef S) { ThinIndices.erase(S); };
129 Backend = lto::createWriteIndexesThinBackend(
130 Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,
131 Config->ThinLTOEmitImportsFiles, IndexFile.get(), OnIndexWrite);
132 } else if (Config->ThinLTOJobs != -1U) {
133 Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
127 // Initialize indexFile.
128 if (!config->thinLTOIndexOnlyArg.empty())
129 indexFile = openFile(config->thinLTOIndexOnlyArg);
130
131 // Initialize ltoObj.
132 lto::ThinBackend backend;
133 if (config->thinLTOIndexOnly) {
134 auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };
135 backend = lto::createWriteIndexesThinBackend(
136 config->thinLTOPrefixReplace.first, config->thinLTOPrefixReplace.second,
137 config->thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite);
138 } else if (config->thinLTOJobs != -1U) {
139 backend = lto::createInProcessThinBackend(config->thinLTOJobs);
134140 }
135141
136 LTOObj = llvm::make_unique<lto::LTO>(createConfig(), Backend,
137 Config->LTOPartitions);
142 ltoObj = llvm::make_unique<lto::LTO>(createConfig(), backend,
143 config->ltoPartitions);
138144
139 // Initialize UsedStartStop.
140 for (Symbol *Sym : Symtab->getSymbols()) {
141 StringRef S = Sym->getName();
142 for (StringRef Prefix : {"__start_", "__stop_"})
143 if (S.startswith(Prefix))
144 UsedStartStop.insert(S.substr(Prefix.size()));
145 }
145 // Initialize usedStartStop.
146 symtab->forEachSymbol([&](Symbol *sym) {
147 StringRef s = sym->getName();
148 for (StringRef prefix : {"__start_", "__stop_"})
149 if (s.startswith(prefix))
150 usedStartStop.insert(s.substr(prefix.size()));
151 });
146152}
147153
148154BitcodeCompiler::~BitcodeCompiler() = default;
149155
150static void undefine(Symbol *S) {
151 replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT,
152 S->Type);
153}
154
155void BitcodeCompiler::add(BitcodeFile &F) {
156 lto::InputFile &Obj = *F.Obj;
157 bool IsExec = !Config->Shared && !Config->Relocatable;
156void BitcodeCompiler::add(BitcodeFile &f) {
157 lto::InputFile &obj = *f.obj;
158 bool isExec = !config->shared && !config->relocatable;
158159
159 if (Config->ThinLTOIndexOnly)
160 ThinIndices.insert(Obj.getName());
160 if (config->thinLTOIndexOnly)
161 thinIndices.insert(obj.getName());
161162
162 ArrayRef<Symbol *> Syms = F.getSymbols();
163 ArrayRef<lto::InputFile::Symbol> ObjSyms = Obj.symbols();
164 std::vector<lto::SymbolResolution> Resols(Syms.size());
163 ArrayRef<Symbol *> syms = f.getSymbols();
164 ArrayRef<lto::InputFile::Symbol> objSyms = obj.symbols();
165 std::vector<lto::SymbolResolution> resols(syms.size());
165166
166167 // Provide a resolution to the LTO API for each symbol.
167 for (size_t I = 0, E = Syms.size(); I != E; ++I) {
168 Symbol *Sym = Syms[I];
169 const lto::InputFile::Symbol &ObjSym = ObjSyms[I];
170 lto::SymbolResolution &R = Resols[I];
168 for (size_t i = 0, e = syms.size(); i != e; ++i) {
169 Symbol *sym = syms[i];
170 const lto::InputFile::Symbol &objSym = objSyms[i];
171 lto::SymbolResolution &r = resols[i];
171172
172173 // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
173174 // reports two symbols for module ASM defined. Without this check, lld
174175 // flags an undefined in IR with a definition in ASM as prevailing.
175176 // Once IRObjectFile is fixed to report only one symbol this hack can
176177 // be removed.
177 R.Prevailing = !ObjSym.isUndefined() && Sym->File == &F;
178 r.Prevailing = !objSym.isUndefined() && sym->file == &f;
178179
179180 // We ask LTO to preserve following global symbols:
180181 // 1) All symbols when doing relocatable link, so that them can be used
......@@ -182,115 +183,121 @@ void BitcodeCompiler::add(BitcodeFile &F) {
182183 // 2) Symbols that are used in regular objects.
183184 // 3) C named sections if we have corresponding __start_/__stop_ symbol.
184185 // 4) Symbols that are defined in bitcode files and used for dynamic linking.
185 R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj ||
186 (R.Prevailing && Sym->includeInDynsym()) ||
187 UsedStartStop.count(ObjSym.getSectionName());
188 const auto *DR = dyn_cast<Defined>(Sym);
189 R.FinalDefinitionInLinkageUnit =
190 (IsExec || Sym->Visibility != STV_DEFAULT) && DR &&
186 r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj ||
187 (r.Prevailing && sym->includeInDynsym()) ||
188 usedStartStop.count(objSym.getSectionName());
189 const auto *dr = dyn_cast<Defined>(sym);
190 r.FinalDefinitionInLinkageUnit =
191 (isExec || sym->visibility != STV_DEFAULT) && dr &&
191192 // Skip absolute symbols from ELF objects, otherwise PC-rel relocations
192193 // will be generated by for them, triggering linker errors.
193194 // Symbol section is always null for bitcode symbols, hence the check
194195 // for isElf(). Skip linker script defined symbols as well: they have
195196 // no File defined.
196 !(DR->Section == nullptr && (!Sym->File || Sym->File->isElf()));
197 !(dr->section == nullptr && (!sym->file || sym->file->isElf()));
197198
198 if (R.Prevailing)
199 undefine(Sym);
199 if (r.Prevailing)
200 sym->replace(Undefined{nullptr, sym->getName(), STB_GLOBAL, STV_DEFAULT,
201 sym->type});
200202
201203 // We tell LTO to not apply interprocedural optimization for wrapped
202204 // (with --wrap) symbols because otherwise LTO would inline them while
203205 // their values are still not final.
204 R.LinkerRedefined = !Sym->CanInline;
206 r.LinkerRedefined = !sym->canInline;
205207 }
206 checkError(LTOObj->add(std::move(F.Obj), Resols));
208 checkError(ltoObj->add(std::move(f.obj), resols));
207209}
208210
209static void createEmptyIndex(StringRef ModulePath) {
210 std::string Path = replaceThinLTOSuffix(getThinLTOOutputFile(ModulePath));
211 std::unique_ptr<raw_fd_ostream> OS = openFile(Path + ".thinlto.bc");
212 if (!OS)
213 return;
214
215 ModuleSummaryIndex M(/*HaveGVs*/ false);
216 M.setSkipModuleByDistributedBackend();
217 WriteIndexToFile(M, *OS);
211// If LazyObjFile has not been added to link, emit empty index files.
212// This is needed because this is what GNU gold plugin does and we have a
213// distributed build system that depends on that behavior.
214static void thinLTOCreateEmptyIndexFiles() {
215 for (LazyObjFile *f : lazyObjFiles) {
216 if (!isBitcode(f->mb))
217 continue;
218 std::string path = replaceThinLTOSuffix(getThinLTOOutputFile(f->getName()));
219 std::unique_ptr<raw_fd_ostream> os = openFile(path + ".thinlto.bc");
220 if (!os)
221 continue;
218222
219 if (Config->ThinLTOEmitImportsFiles)
220 openFile(Path + ".imports");
223 ModuleSummaryIndex m(/*HaveGVs*/ false);
224 m.setSkipModuleByDistributedBackend();
225 WriteIndexToFile(m, *os);
226 if (config->thinLTOEmitImportsFiles)
227 openFile(path + ".imports");
228 }
221229}
222230
223231// Merge all the bitcode files we have seen, codegen the result
224232// and return the resulting ObjectFile(s).
225233std::vector<InputFile *> BitcodeCompiler::compile() {
226 unsigned MaxTasks = LTOObj->getMaxTasks();
227 Buf.resize(MaxTasks);
228 Files.resize(MaxTasks);
234 unsigned maxTasks = ltoObj->getMaxTasks();
235 buf.resize(maxTasks);
236 files.resize(maxTasks);
229237
230238 // The --thinlto-cache-dir option specifies the path to a directory in which
231239 // to cache native object files for ThinLTO incremental builds. If a path was
232240 // specified, configure LTO to use it as the cache directory.
233 lto::NativeObjectCache Cache;
234 if (!Config->ThinLTOCacheDir.empty())
235 Cache = check(
236 lto::localCache(Config->ThinLTOCacheDir,
237 [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
238 Files[Task] = std::move(MB);
241 lto::NativeObjectCache cache;
242 if (!config->thinLTOCacheDir.empty())
243 cache = check(
244 lto::localCache(config->thinLTOCacheDir,
245 [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
246 files[task] = std::move(mb);
239247 }));
240248
241 checkError(LTOObj->run(
242 [&](size_t Task) {
243 return llvm::make_unique<lto::NativeObjectStream>(
244 llvm::make_unique<raw_svector_ostream>(Buf[Task]));
245 },
246 Cache));
249 if (!bitcodeFiles.empty())
250 checkError(ltoObj->run(
251 [&](size_t task) {
252 return llvm::make_unique<lto::NativeObjectStream>(
253 llvm::make_unique<raw_svector_ostream>(buf[task]));
254 },
255 cache));
247256
248257 // Emit empty index files for non-indexed files
249 for (StringRef S : ThinIndices) {
250 std::string Path = getThinLTOOutputFile(S);
251 openFile(Path + ".thinlto.bc");
252 if (Config->ThinLTOEmitImportsFiles)
253 openFile(Path + ".imports");
258 for (StringRef s : thinIndices) {
259 std::string path = getThinLTOOutputFile(s);
260 openFile(path + ".thinlto.bc");
261 if (config->thinLTOEmitImportsFiles)
262 openFile(path + ".imports");
254263 }
255264
256 // If LazyObjFile has not been added to link, emit empty index files.
257 // This is needed because this is what GNU gold plugin does and we have a
258 // distributed build system that depends on that behavior.
259 if (Config->ThinLTOIndexOnly) {
260 for (LazyObjFile *F : LazyObjFiles)
261 if (!F->AddedToLink && isBitcode(F->MB))
262 createEmptyIndex(F->getName());
265 if (config->thinLTOIndexOnly) {
266 thinLTOCreateEmptyIndexFiles();
263267
264 if (!Config->LTOObjPath.empty())
265 saveBuffer(Buf[0], Config->LTOObjPath);
268 if (!config->ltoObjPath.empty())
269 saveBuffer(buf[0], config->ltoObjPath);
266270
267271 // ThinLTO with index only option is required to generate only the index
268272 // files. After that, we exit from linker and ThinLTO backend runs in a
269273 // distributed environment.
270 if (IndexFile)
271 IndexFile->close();
274 if (indexFile)
275 indexFile->close();
272276 return {};
273277 }
274278
275 if (!Config->ThinLTOCacheDir.empty())
276 pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
279 if (!config->thinLTOCacheDir.empty())
280 pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy);
277281
278 std::vector<InputFile *> Ret;
279 for (unsigned I = 0; I != MaxTasks; ++I) {
280 if (Buf[I].empty())
281 continue;
282 if (Config->SaveTemps) {
283 if (I == 0)
284 saveBuffer(Buf[I], Config->OutputFile + ".lto.o");
285 else
286 saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o");
287 }
288 InputFile *Obj = createObjectFile(MemoryBufferRef(Buf[I], "lto.tmp"));
289 Ret.push_back(Obj);
282 if (!config->ltoObjPath.empty()) {
283 saveBuffer(buf[0], config->ltoObjPath);
284 for (unsigned i = 1; i != maxTasks; ++i)
285 saveBuffer(buf[i], config->ltoObjPath + Twine(i));
290286 }
291287
292 for (std::unique_ptr<MemoryBuffer> &File : Files)
293 if (File)
294 Ret.push_back(createObjectFile(*File));
295 return Ret;
288 if (config->saveTemps) {
289 saveBuffer(buf[0], config->outputFile + ".lto.o");
290 for (unsigned i = 1; i != maxTasks; ++i)
291 saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o");
292 }
293
294 std::vector<InputFile *> ret;
295 for (unsigned i = 0; i != maxTasks; ++i)
296 if (!buf[i].empty())
297 ret.push_back(createObjectFile(MemoryBufferRef(buf[i], "lto.tmp")));
298
299 for (std::unique_ptr<MemoryBuffer> &file : files)
300 if (file)
301 ret.push_back(createObjectFile(*file));
302 return ret;
296303}
deps/lld/ELF/LTO.h+10-11
......@@ -1,9 +1,8 @@
11//===- LTO.h ----------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -46,16 +45,16 @@ public:
4645 BitcodeCompiler();
4746 ~BitcodeCompiler();
4847
49 void add(BitcodeFile &F);
48 void add(BitcodeFile &f);
5049 std::vector<InputFile *> compile();
5150
5251private:
53 std::unique_ptr<llvm::lto::LTO> LTOObj;
54 std::vector<SmallString<0>> Buf;
55 std::vector<std::unique_ptr<MemoryBuffer>> Files;
56 llvm::DenseSet<StringRef> UsedStartStop;
57 std::unique_ptr<llvm::raw_fd_ostream> IndexFile;
58 llvm::DenseSet<StringRef> ThinIndices;
52 std::unique_ptr<llvm::lto::LTO> ltoObj;
53 std::vector<SmallString<0>> buf;
54 std::vector<std::unique_ptr<MemoryBuffer>> files;
55 llvm::DenseSet<StringRef> usedStartStop;
56 std::unique_ptr<llvm::raw_fd_ostream> indexFile;
57 llvm::DenseSet<StringRef> thinIndices;
5958};
6059} // namespace elf
6160} // namespace lld
deps/lld/ELF/LinkerScript.cpp+516-502
......@@ -1,9 +1,8 @@
11//===- LinkerScript.cpp ---------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -47,26 +46,26 @@ using namespace llvm::support::endian;
4746using namespace lld;
4847using namespace lld::elf;
4948
50LinkerScript *elf::Script;
49LinkerScript *elf::script;
5150
52static uint64_t getOutputSectionVA(SectionBase *InputSec, StringRef Loc) {
53 if (OutputSection *OS = InputSec->getOutputSection())
54 return OS->Addr;
55 error(Loc + ": unable to evaluate expression: input section " +
56 InputSec->Name + " has no output section assigned");
51static uint64_t getOutputSectionVA(SectionBase *inputSec, StringRef loc) {
52 if (OutputSection *os = inputSec->getOutputSection())
53 return os->addr;
54 error(loc + ": unable to evaluate expression: input section " +
55 inputSec->name + " has no output section assigned");
5756 return 0;
5857}
5958
6059uint64_t ExprValue::getValue() const {
61 if (Sec)
62 return alignTo(Sec->getOffset(Val) + getOutputSectionVA(Sec, Loc),
63 Alignment);
64 return alignTo(Val, Alignment);
60 if (sec)
61 return alignTo(sec->getOffset(val) + getOutputSectionVA(sec, loc),
62 alignment);
63 return alignTo(val, alignment);
6564}
6665
6766uint64_t ExprValue::getSecAddr() const {
68 if (Sec)
69 return Sec->getOffset(0) + getOutputSectionVA(Sec, Loc);
67 if (sec)
68 return sec->getOffset(0) + getOutputSectionVA(sec, loc);
7069 return 0;
7170}
7271
......@@ -74,106 +73,100 @@ uint64_t ExprValue::getSectionOffset() const {
7473 // If the alignment is trivial, we don't have to compute the full
7574 // value to know the offset. This allows this function to succeed in
7675 // cases where the output section is not yet known.
77 if (Alignment == 1 && (!Sec || !Sec->getOutputSection()))
78 return Val;
76 if (alignment == 1 && (!sec || !sec->getOutputSection()))
77 return val;
7978 return getValue() - getSecAddr();
8079}
8180
82OutputSection *LinkerScript::createOutputSection(StringRef Name,
83 StringRef Location) {
84 OutputSection *&SecRef = NameToOutputSection[Name];
85 OutputSection *Sec;
86 if (SecRef && SecRef->Location.empty()) {
81OutputSection *LinkerScript::createOutputSection(StringRef name,
82 StringRef location) {
83 OutputSection *&secRef = nameToOutputSection[name];
84 OutputSection *sec;
85 if (secRef && secRef->location.empty()) {
8786 // There was a forward reference.
88 Sec = SecRef;
87 sec = secRef;
8988 } else {
90 Sec = make<OutputSection>(Name, SHT_NOBITS, 0);
91 if (!SecRef)
92 SecRef = Sec;
89 sec = make<OutputSection>(name, SHT_PROGBITS, 0);
90 if (!secRef)
91 secRef = sec;
9392 }
94 Sec->Location = Location;
95 return Sec;
93 sec->location = location;
94 return sec;
9695}
9796
98OutputSection *LinkerScript::getOrCreateOutputSection(StringRef Name) {
99 OutputSection *&CmdRef = NameToOutputSection[Name];
100 if (!CmdRef)
101 CmdRef = make<OutputSection>(Name, SHT_PROGBITS, 0);
102 return CmdRef;
97OutputSection *LinkerScript::getOrCreateOutputSection(StringRef name) {
98 OutputSection *&cmdRef = nameToOutputSection[name];
99 if (!cmdRef)
100 cmdRef = make<OutputSection>(name, SHT_PROGBITS, 0);
101 return cmdRef;
103102}
104103
105104// Expands the memory region by the specified size.
106static void expandMemoryRegion(MemoryRegion *MemRegion, uint64_t Size,
107 StringRef RegionName, StringRef SecName) {
108 MemRegion->CurPos += Size;
109 uint64_t NewSize = MemRegion->CurPos - MemRegion->Origin;
110 if (NewSize > MemRegion->Length)
111 error("section '" + SecName + "' will not fit in region '" + RegionName +
112 "': overflowed by " + Twine(NewSize - MemRegion->Length) + " bytes");
105static void expandMemoryRegion(MemoryRegion *memRegion, uint64_t size,
106 StringRef regionName, StringRef secName) {
107 memRegion->curPos += size;
108 uint64_t newSize = memRegion->curPos - memRegion->origin;
109 if (newSize > memRegion->length)
110 error("section '" + secName + "' will not fit in region '" + regionName +
111 "': overflowed by " + Twine(newSize - memRegion->length) + " bytes");
113112}
114113
115void LinkerScript::expandMemoryRegions(uint64_t Size) {
116 if (Ctx->MemRegion)
117 expandMemoryRegion(Ctx->MemRegion, Size, Ctx->MemRegion->Name,
118 Ctx->OutSec->Name);
119 // Only expand the LMARegion if it is different from MemRegion.
120 if (Ctx->LMARegion && Ctx->MemRegion != Ctx->LMARegion)
121 expandMemoryRegion(Ctx->LMARegion, Size, Ctx->LMARegion->Name,
122 Ctx->OutSec->Name);
114void LinkerScript::expandMemoryRegions(uint64_t size) {
115 if (ctx->memRegion)
116 expandMemoryRegion(ctx->memRegion, size, ctx->memRegion->name,
117 ctx->outSec->name);
118 // Only expand the LMARegion if it is different from memRegion.
119 if (ctx->lmaRegion && ctx->memRegion != ctx->lmaRegion)
120 expandMemoryRegion(ctx->lmaRegion, size, ctx->lmaRegion->name,
121 ctx->outSec->name);
123122}
124123
125void LinkerScript::expandOutputSection(uint64_t Size) {
126 Ctx->OutSec->Size += Size;
127 expandMemoryRegions(Size);
124void LinkerScript::expandOutputSection(uint64_t size) {
125 ctx->outSec->size += size;
126 expandMemoryRegions(size);
128127}
129128
130void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
131 uint64_t Val = E().getValue();
132 if (Val < Dot && InSec)
133 error(Loc + ": unable to move location counter backward for: " +
134 Ctx->OutSec->Name);
129void LinkerScript::setDot(Expr e, const Twine &loc, bool inSec) {
130 uint64_t val = e().getValue();
131 if (val < dot && inSec)
132 error(loc + ": unable to move location counter backward for: " +
133 ctx->outSec->name);
135134
136135 // Update to location counter means update to section size.
137 if (InSec)
138 expandOutputSection(Val - Dot);
139 else
140 expandMemoryRegions(Val - Dot);
136 if (inSec)
137 expandOutputSection(val - dot);
141138
142 Dot = Val;
139 dot = val;
143140}
144141
145142// Used for handling linker symbol assignments, for both finalizing
146143// their values and doing early declarations. Returns true if symbol
147144// should be defined from linker script.
148static bool shouldDefineSym(SymbolAssignment *Cmd) {
149 if (Cmd->Name == ".")
145static bool shouldDefineSym(SymbolAssignment *cmd) {
146 if (cmd->name == ".")
150147 return false;
151148
152 if (!Cmd->Provide)
149 if (!cmd->provide)
153150 return true;
154151
155152 // If a symbol was in PROVIDE(), we need to define it only
156153 // when it is a referenced undefined symbol.
157 Symbol *B = Symtab->find(Cmd->Name);
158 if (B && !B->isDefined())
154 Symbol *b = symtab->find(cmd->name);
155 if (b && !b->isDefined())
159156 return true;
160157 return false;
161158}
162159
163160// This function is called from processSectionCommands,
164161// while we are fixing the output section layout.
165void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
166 if (!shouldDefineSym(Cmd))
162void LinkerScript::addSymbol(SymbolAssignment *cmd) {
163 if (!shouldDefineSym(cmd))
167164 return;
168165
169166 // Define a symbol.
170 Symbol *Sym;
171 uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
172 std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
173 /*CanOmitFromDynSym*/ false,
174 /*File*/ nullptr);
175 ExprValue Value = Cmd->Expression();
176 SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
167 ExprValue value = cmd->expression();
168 SectionBase *sec = value.isAbsolute() ? nullptr : value.sec;
169 uint8_t visibility = cmd->hidden ? STV_HIDDEN : STV_DEFAULT;
177170
178171 // When this function is called, section addresses have not been
179172 // fixed yet. So, we may or may not know the value of the RHS
......@@ -186,68 +179,73 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
186179 // We want to set symbol values early if we can. This allows us to
187180 // use symbols as variables in linker scripts. Doing so allows us to
188181 // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`.
189 uint64_t SymValue = Value.Sec ? 0 : Value.getValue();
182 uint64_t symValue = value.sec ? 0 : value.getValue();
183
184 Defined New(nullptr, cmd->name, STB_GLOBAL, visibility, STT_NOTYPE, symValue,
185 0, sec);
190186
191 replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
192 STT_NOTYPE, SymValue, 0, Sec);
193 Cmd->Sym = cast<Defined>(Sym);
187 Symbol *sym = symtab->insert(cmd->name);
188 sym->mergeProperties(New);
189 sym->replace(New);
190 cmd->sym = cast<Defined>(sym);
194191}
195192
196193// This function is called from LinkerScript::declareSymbols.
197194// It creates a placeholder symbol if needed.
198static void declareSymbol(SymbolAssignment *Cmd) {
199 if (!shouldDefineSym(Cmd))
195static void declareSymbol(SymbolAssignment *cmd) {
196 if (!shouldDefineSym(cmd))
200197 return;
201198
199 uint8_t visibility = cmd->hidden ? STV_HIDDEN : STV_DEFAULT;
200 Defined New(nullptr, cmd->name, STB_GLOBAL, visibility, STT_NOTYPE, 0, 0,
201 nullptr);
202
202203 // We can't calculate final value right now.
203 Symbol *Sym;
204 uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
205 std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, Visibility,
206 /*CanOmitFromDynSym*/ false,
207 /*File*/ nullptr);
208 replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
209 STT_NOTYPE, 0, 0, nullptr);
210 Cmd->Sym = cast<Defined>(Sym);
211 Cmd->Provide = false;
212 Sym->ScriptDefined = true;
204 Symbol *sym = symtab->insert(cmd->name);
205 sym->mergeProperties(New);
206 sym->replace(New);
207
208 cmd->sym = cast<Defined>(sym);
209 cmd->provide = false;
210 sym->scriptDefined = true;
213211}
214212
215213// This method is used to handle INSERT AFTER statement. Here we rebuild
216214// the list of script commands to mix sections inserted into.
217215void LinkerScript::processInsertCommands() {
218 std::vector<BaseCommand *> V;
219 auto Insert = [&](std::vector<BaseCommand *> &From) {
220 V.insert(V.end(), From.begin(), From.end());
221 From.clear();
216 std::vector<BaseCommand *> v;
217 auto insert = [&](std::vector<BaseCommand *> &from) {
218 v.insert(v.end(), from.begin(), from.end());
219 from.clear();
222220 };
223221
224 for (BaseCommand *Base : SectionCommands) {
225 if (auto *OS = dyn_cast<OutputSection>(Base)) {
226 Insert(InsertBeforeCommands[OS->Name]);
227 V.push_back(Base);
228 Insert(InsertAfterCommands[OS->Name]);
222 for (BaseCommand *base : sectionCommands) {
223 if (auto *os = dyn_cast<OutputSection>(base)) {
224 insert(insertBeforeCommands[os->name]);
225 v.push_back(base);
226 insert(insertAfterCommands[os->name]);
229227 continue;
230228 }
231 V.push_back(Base);
229 v.push_back(base);
232230 }
233231
234 for (auto &Cmds : {InsertBeforeCommands, InsertAfterCommands})
235 for (const std::pair<StringRef, std::vector<BaseCommand *>> &P : Cmds)
236 if (!P.second.empty())
237 error("unable to INSERT AFTER/BEFORE " + P.first +
232 for (auto &cmds : {insertBeforeCommands, insertAfterCommands})
233 for (const std::pair<StringRef, std::vector<BaseCommand *>> &p : cmds)
234 if (!p.second.empty())
235 error("unable to INSERT AFTER/BEFORE " + p.first +
238236 ": section not defined");
239237
240 SectionCommands = std::move(V);
238 sectionCommands = std::move(v);
241239}
242240
243241// Symbols defined in script should not be inlined by LTO. At the same time
244242// we don't know their final values until late stages of link. Here we scan
245243// over symbol assignment commands and create placeholder symbols if needed.
246244void LinkerScript::declareSymbols() {
247 assert(!Ctx);
248 for (BaseCommand *Base : SectionCommands) {
249 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
250 declareSymbol(Cmd);
245 assert(!ctx);
246 for (BaseCommand *base : sectionCommands) {
247 if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
248 declareSymbol(cmd);
251249 continue;
252250 }
253251
......@@ -255,75 +253,75 @@ void LinkerScript::declareSymbols() {
255253 // we can't say for sure if it is going to be included or not.
256254 // Skip such sections for now. Improve the checks if we ever
257255 // need symbols from that sections to be declared early.
258 auto *Sec = cast<OutputSection>(Base);
259 if (Sec->Constraint != ConstraintKind::NoConstraint)
256 auto *sec = cast<OutputSection>(base);
257 if (sec->constraint != ConstraintKind::NoConstraint)
260258 continue;
261 for (BaseCommand *Base2 : Sec->SectionCommands)
262 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base2))
263 declareSymbol(Cmd);
259 for (BaseCommand *base2 : sec->sectionCommands)
260 if (auto *cmd = dyn_cast<SymbolAssignment>(base2))
261 declareSymbol(cmd);
264262 }
265263}
266264
267265// This function is called from assignAddresses, while we are
268266// fixing the output section addresses. This function is supposed
269267// to set the final value for a given symbol assignment.
270void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
271 if (Cmd->Name == ".") {
272 setDot(Cmd->Expression, Cmd->Location, InSec);
268void LinkerScript::assignSymbol(SymbolAssignment *cmd, bool inSec) {
269 if (cmd->name == ".") {
270 setDot(cmd->expression, cmd->location, inSec);
273271 return;
274272 }
275273
276 if (!Cmd->Sym)
274 if (!cmd->sym)
277275 return;
278276
279 ExprValue V = Cmd->Expression();
280 if (V.isAbsolute()) {
281 Cmd->Sym->Section = nullptr;
282 Cmd->Sym->Value = V.getValue();
277 ExprValue v = cmd->expression();
278 if (v.isAbsolute()) {
279 cmd->sym->section = nullptr;
280 cmd->sym->value = v.getValue();
283281 } else {
284 Cmd->Sym->Section = V.Sec;
285 Cmd->Sym->Value = V.getSectionOffset();
282 cmd->sym->section = v.sec;
283 cmd->sym->value = v.getSectionOffset();
286284 }
287285}
288286
289static std::string getFilename(InputFile *File) {
290 if (!File)
287static std::string getFilename(InputFile *file) {
288 if (!file)
291289 return "";
292 if (File->ArchiveName.empty())
293 return File->getName();
294 return (File->ArchiveName + "(" + File->getName() + ")").str();
290 if (file->archiveName.empty())
291 return file->getName();
292 return (file->archiveName + "(" + file->getName() + ")").str();
295293}
296294
297bool LinkerScript::shouldKeep(InputSectionBase *S) {
298 if (KeptSections.empty())
295bool LinkerScript::shouldKeep(InputSectionBase *s) {
296 if (keptSections.empty())
299297 return false;
300 std::string Filename = getFilename(S->File);
301 for (InputSectionDescription *ID : KeptSections)
302 if (ID->FilePat.match(Filename))
303 for (SectionPattern &P : ID->SectionPatterns)
304 if (P.SectionPat.match(S->Name))
298 std::string filename = getFilename(s->file);
299 for (InputSectionDescription *id : keptSections)
300 if (id->filePat.match(filename))
301 for (SectionPattern &p : id->sectionPatterns)
302 if (p.sectionPat.match(s->name))
305303 return true;
306304 return false;
307305}
308306
309307// A helper function for the SORT() command.
310308static std::function<bool(InputSectionBase *, InputSectionBase *)>
311getComparator(SortSectionPolicy K) {
312 switch (K) {
309getComparator(SortSectionPolicy k) {
310 switch (k) {
313311 case SortSectionPolicy::Alignment:
314 return [](InputSectionBase *A, InputSectionBase *B) {
312 return [](InputSectionBase *a, InputSectionBase *b) {
315313 // ">" is not a mistake. Sections with larger alignments are placed
316314 // before sections with smaller alignments in order to reduce the
317315 // amount of padding necessary. This is compatible with GNU.
318 return A->Alignment > B->Alignment;
316 return a->alignment > b->alignment;
319317 };
320318 case SortSectionPolicy::Name:
321 return [](InputSectionBase *A, InputSectionBase *B) {
322 return A->Name < B->Name;
319 return [](InputSectionBase *a, InputSectionBase *b) {
320 return a->name < b->name;
323321 };
324322 case SortSectionPolicy::Priority:
325 return [](InputSectionBase *A, InputSectionBase *B) {
326 return getPriority(A->Name) < getPriority(B->Name);
323 return [](InputSectionBase *a, InputSectionBase *b) {
324 return getPriority(a->name) < getPriority(b->name);
327325 };
328326 default:
329327 llvm_unreachable("unknown sort policy");
......@@ -331,22 +329,22 @@ getComparator(SortSectionPolicy K) {
331329}
332330
333331// A helper function for the SORT() command.
334static bool matchConstraints(ArrayRef<InputSection *> Sections,
335 ConstraintKind Kind) {
336 if (Kind == ConstraintKind::NoConstraint)
332static bool matchConstraints(ArrayRef<InputSection *> sections,
333 ConstraintKind kind) {
334 if (kind == ConstraintKind::NoConstraint)
337335 return true;
338336
339 bool IsRW = llvm::any_of(
340 Sections, [](InputSection *Sec) { return Sec->Flags & SHF_WRITE; });
337 bool isRW = llvm::any_of(
338 sections, [](InputSection *sec) { return sec->flags & SHF_WRITE; });
341339
342 return (IsRW && Kind == ConstraintKind::ReadWrite) ||
343 (!IsRW && Kind == ConstraintKind::ReadOnly);
340 return (isRW && kind == ConstraintKind::ReadWrite) ||
341 (!isRW && kind == ConstraintKind::ReadOnly);
344342}
345343
346static void sortSections(MutableArrayRef<InputSection *> Vec,
347 SortSectionPolicy K) {
348 if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
349 std::stable_sort(Vec.begin(), Vec.end(), getComparator(K));
344static void sortSections(MutableArrayRef<InputSection *> vec,
345 SortSectionPolicy k) {
346 if (k != SortSectionPolicy::Default && k != SortSectionPolicy::None)
347 llvm::stable_sort(vec, getComparator(k));
350348}
351349
352350// Sort sections as instructed by SORT-family commands and --sort-section
......@@ -360,29 +358,29 @@ static void sortSections(MutableArrayRef<InputSection *> Vec,
360358// --sort-section is handled as an inner SORT command.
361359// 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
362360// 4. If no SORT command is given, sort according to --sort-section.
363static void sortInputSections(MutableArrayRef<InputSection *> Vec,
364 const SectionPattern &Pat) {
365 if (Pat.SortOuter == SortSectionPolicy::None)
361static void sortInputSections(MutableArrayRef<InputSection *> vec,
362 const SectionPattern &pat) {
363 if (pat.sortOuter == SortSectionPolicy::None)
366364 return;
367365
368 if (Pat.SortInner == SortSectionPolicy::Default)
369 sortSections(Vec, Config->SortSection);
366 if (pat.sortInner == SortSectionPolicy::Default)
367 sortSections(vec, config->sortSection);
370368 else
371 sortSections(Vec, Pat.SortInner);
372 sortSections(Vec, Pat.SortOuter);
369 sortSections(vec, pat.sortInner);
370 sortSections(vec, pat.sortOuter);
373371}
374372
375373// Compute and remember which sections the InputSectionDescription matches.
376374std::vector<InputSection *>
377LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
378 std::vector<InputSection *> Ret;
375LinkerScript::computeInputSections(const InputSectionDescription *cmd) {
376 std::vector<InputSection *> ret;
379377
380378 // Collects all sections that satisfy constraints of Cmd.
381 for (const SectionPattern &Pat : Cmd->SectionPatterns) {
382 size_t SizeBefore = Ret.size();
379 for (const SectionPattern &pat : cmd->sectionPatterns) {
380 size_t sizeBefore = ret.size();
383381
384 for (InputSectionBase *Sec : InputSections) {
385 if (!Sec->Live || Sec->Assigned)
382 for (InputSectionBase *sec : inputSections) {
383 if (!sec->isLive() || sec->assigned)
386384 continue;
387385
388386 // For -emit-relocs we have to ignore entries like
......@@ -390,59 +388,59 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
390388 // which are common because they are in the default bfd script.
391389 // We do not ignore SHT_REL[A] linker-synthesized sections here because
392390 // want to support scripts that do custom layout for them.
393 if (auto *IS = dyn_cast<InputSection>(Sec))
394 if (IS->getRelocatedSection())
391 if (auto *isec = dyn_cast<InputSection>(sec))
392 if (isec->getRelocatedSection())
395393 continue;
396394
397 std::string Filename = getFilename(Sec->File);
398 if (!Cmd->FilePat.match(Filename) ||
399 Pat.ExcludedFilePat.match(Filename) ||
400 !Pat.SectionPat.match(Sec->Name))
395 std::string filename = getFilename(sec->file);
396 if (!cmd->filePat.match(filename) ||
397 pat.excludedFilePat.match(filename) ||
398 !pat.sectionPat.match(sec->name))
401399 continue;
402400
403401 // It is safe to assume that Sec is an InputSection
404402 // because mergeable or EH input sections have already been
405403 // handled and eliminated.
406 Ret.push_back(cast<InputSection>(Sec));
407 Sec->Assigned = true;
404 ret.push_back(cast<InputSection>(sec));
405 sec->assigned = true;
408406 }
409407
410 sortInputSections(MutableArrayRef<InputSection *>(Ret).slice(SizeBefore),
411 Pat);
408 sortInputSections(MutableArrayRef<InputSection *>(ret).slice(sizeBefore),
409 pat);
412410 }
413 return Ret;
411 return ret;
414412}
415413
416void LinkerScript::discard(ArrayRef<InputSection *> V) {
417 for (InputSection *S : V) {
418 if (S == In.ShStrTab || S == In.RelaDyn || S == In.RelrDyn)
419 error("discarding " + S->Name + " section is not allowed");
414void LinkerScript::discard(ArrayRef<InputSection *> v) {
415 for (InputSection *s : v) {
416 if (s == in.shStrTab || s == mainPart->relaDyn || s == mainPart->relrDyn)
417 error("discarding " + s->name + " section is not allowed");
420418
421419 // You can discard .hash and .gnu.hash sections by linker scripts. Since
422420 // they are synthesized sections, we need to handle them differently than
423421 // other regular sections.
424 if (S == In.GnuHashTab)
425 In.GnuHashTab = nullptr;
426 if (S == In.HashTab)
427 In.HashTab = nullptr;
428
429 S->Assigned = false;
430 S->Live = false;
431 discard(S->DependentSections);
422 if (s == mainPart->gnuHashTab)
423 mainPart->gnuHashTab = nullptr;
424 if (s == mainPart->hashTab)
425 mainPart->hashTab = nullptr;
426
427 s->assigned = false;
428 s->markDead();
429 discard(s->dependentSections);
432430 }
433431}
434432
435433std::vector<InputSection *>
436LinkerScript::createInputSectionList(OutputSection &OutCmd) {
437 std::vector<InputSection *> Ret;
434LinkerScript::createInputSectionList(OutputSection &outCmd) {
435 std::vector<InputSection *> ret;
438436
439 for (BaseCommand *Base : OutCmd.SectionCommands) {
440 if (auto *Cmd = dyn_cast<InputSectionDescription>(Base)) {
441 Cmd->Sections = computeInputSections(Cmd);
442 Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
437 for (BaseCommand *base : outCmd.sectionCommands) {
438 if (auto *cmd = dyn_cast<InputSectionDescription>(base)) {
439 cmd->sections = computeInputSections(cmd);
440 ret.insert(ret.end(), cmd->sections.begin(), cmd->sections.end());
443441 }
444442 }
445 return Ret;
443 return ret;
446444}
447445
448446void LinkerScript::processSectionCommands() {
......@@ -455,34 +453,34 @@ void LinkerScript::processSectionCommands() {
455453 // To handle that, create a dummy aether section that fills the void before
456454 // the linker scripts switches to another section. It has an index of one
457455 // which will map to whatever the first actual section is.
458 Aether = make<OutputSection>("", 0, SHF_ALLOC);
459 Aether->SectionIndex = 1;
456 aether = make<OutputSection>("", 0, SHF_ALLOC);
457 aether->sectionIndex = 1;
460458
461459 // Ctx captures the local AddressState and makes it accessible deliberately.
462460 // This is needed as there are some cases where we cannot just
463461 // thread the current state through to a lambda function created by the
464462 // script parser.
465 auto Deleter = make_unique<AddressState>();
466 Ctx = Deleter.get();
467 Ctx->OutSec = Aether;
463 auto deleter = make_unique<AddressState>();
464 ctx = deleter.get();
465 ctx->outSec = aether;
468466
469 size_t I = 0;
467 size_t i = 0;
470468 // Add input sections to output sections.
471 for (BaseCommand *Base : SectionCommands) {
469 for (BaseCommand *base : sectionCommands) {
472470 // Handle symbol assignments outside of any output section.
473 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
474 addSymbol(Cmd);
471 if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
472 addSymbol(cmd);
475473 continue;
476474 }
477475
478 if (auto *Sec = dyn_cast<OutputSection>(Base)) {
479 std::vector<InputSection *> V = createInputSectionList(*Sec);
476 if (auto *sec = dyn_cast<OutputSection>(base)) {
477 std::vector<InputSection *> v = createInputSectionList(*sec);
480478
481479 // The output section name `/DISCARD/' is special.
482480 // Any input section assigned to it is discarded.
483 if (Sec->Name == "/DISCARD/") {
484 discard(V);
485 Sec->SectionCommands.clear();
481 if (sec->name == "/DISCARD/") {
482 discard(v);
483 sec->sectionCommands.clear();
486484 continue;
487485 }
488486
......@@ -493,60 +491,61 @@ void LinkerScript::processSectionCommands() {
493491 //
494492 // Because we'll iterate over SectionCommands many more times, the easy
495493 // way to "make it as if it wasn't present" is to make it empty.
496 if (!matchConstraints(V, Sec->Constraint)) {
497 for (InputSectionBase *S : V)
498 S->Assigned = false;
499 Sec->SectionCommands.clear();
494 if (!matchConstraints(v, sec->constraint)) {
495 for (InputSectionBase *s : v)
496 s->assigned = false;
497 sec->sectionCommands.clear();
500498 continue;
501499 }
502500
503501 // A directive may contain symbol definitions like this:
504502 // ".foo : { ...; bar = .; }". Handle them.
505 for (BaseCommand *Base : Sec->SectionCommands)
506 if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
507 addSymbol(OutCmd);
503 for (BaseCommand *base : sec->sectionCommands)
504 if (auto *outCmd = dyn_cast<SymbolAssignment>(base))
505 addSymbol(outCmd);
508506
509507 // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
510508 // is given, input sections are aligned to that value, whether the
511509 // given value is larger or smaller than the original section alignment.
512 if (Sec->SubalignExpr) {
513 uint32_t Subalign = Sec->SubalignExpr().getValue();
514 for (InputSectionBase *S : V)
515 S->Alignment = Subalign;
510 if (sec->subalignExpr) {
511 uint32_t subalign = sec->subalignExpr().getValue();
512 for (InputSectionBase *s : v)
513 s->alignment = subalign;
516514 }
517515
518516 // Add input sections to an output section.
519 for (InputSection *S : V)
520 Sec->addSection(S);
521
522 Sec->SectionIndex = I++;
523 if (Sec->Noload)
524 Sec->Type = SHT_NOBITS;
525 if (Sec->NonAlloc)
526 Sec->Flags &= ~(uint64_t)SHF_ALLOC;
517 for (InputSection *s : v)
518 sec->addSection(s);
519
520 sec->sectionIndex = i++;
521 if (sec->noload)
522 sec->type = SHT_NOBITS;
523 if (sec->nonAlloc)
524 sec->flags &= ~(uint64_t)SHF_ALLOC;
527525 }
528526 }
529 Ctx = nullptr;
527 ctx = nullptr;
530528}
531529
532static OutputSection *findByName(ArrayRef<BaseCommand *> Vec,
533 StringRef Name) {
534 for (BaseCommand *Base : Vec)
535 if (auto *Sec = dyn_cast<OutputSection>(Base))
536 if (Sec->Name == Name)
537 return Sec;
530static OutputSection *findByName(ArrayRef<BaseCommand *> vec,
531 StringRef name) {
532 for (BaseCommand *base : vec)
533 if (auto *sec = dyn_cast<OutputSection>(base))
534 if (sec->name == name)
535 return sec;
538536 return nullptr;
539537}
540538
541static OutputSection *createSection(InputSectionBase *IS,
542 StringRef OutsecName) {
543 OutputSection *Sec = Script->createOutputSection(OutsecName, "<internal>");
544 Sec->addSection(cast<InputSection>(IS));
545 return Sec;
539static OutputSection *createSection(InputSectionBase *isec,
540 StringRef outsecName) {
541 OutputSection *sec = script->createOutputSection(outsecName, "<internal>");
542 sec->addSection(cast<InputSection>(isec));
543 return sec;
546544}
547545
548static OutputSection *addInputSec(StringMap<OutputSection *> &Map,
549 InputSectionBase *IS, StringRef OutsecName) {
546static OutputSection *
547addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map,
548 InputSectionBase *isec, StringRef outsecName) {
550549 // Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r
551550 // option is given. A section with SHT_GROUP defines a "section group", and
552551 // its members have SHF_GROUP attribute. Usually these flags have already been
......@@ -554,8 +553,8 @@ static OutputSection *addInputSec(StringMap<OutputSection *> &Map,
554553 // However, for the -r option, we want to pass through all section groups
555554 // as-is because adding/removing members or merging them with other groups
556555 // change their semantics.
557 if (IS->Type == SHT_GROUP || (IS->Flags & SHF_GROUP))
558 return createSection(IS, OutsecName);
556 if (isec->type == SHT_GROUP || (isec->flags & SHF_GROUP))
557 return createSection(isec, outsecName);
559558
560559 // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
561560 // relocation sections .rela.foo and .rela.bar for example. Most tools do
......@@ -563,25 +562,25 @@ static OutputSection *addInputSec(StringMap<OutputSection *> &Map,
563562 // should combine these relocation sections into single output.
564563 // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
565564 // other REL[A] sections created by linker itself.
566 if (!isa<SyntheticSection>(IS) &&
567 (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
568 auto *Sec = cast<InputSection>(IS);
569 OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
565 if (!isa<SyntheticSection>(isec) &&
566 (isec->type == SHT_REL || isec->type == SHT_RELA)) {
567 auto *sec = cast<InputSection>(isec);
568 OutputSection *out = sec->getRelocatedSection()->getOutputSection();
570569
571 if (Out->RelocationSection) {
572 Out->RelocationSection->addSection(Sec);
570 if (out->relocationSection) {
571 out->relocationSection->addSection(sec);
573572 return nullptr;
574573 }
575574
576 Out->RelocationSection = createSection(IS, OutsecName);
577 return Out->RelocationSection;
575 out->relocationSection = createSection(isec, outsecName);
576 return out->relocationSection;
578577 }
579578
580579 // When control reaches here, mergeable sections have already been merged into
581580 // synthetic sections. For relocatable case we want to create one output
582581 // section per syntetic section so that they have a valid sh_entsize.
583 if (Config->Relocatable && (IS->Flags & SHF_MERGE))
584 return createSection(IS, OutsecName);
582 if (config->relocatable && (isec->flags & SHF_MERGE))
583 return createSection(isec, outsecName);
585584
586585 // The ELF spec just says
587586 // ----------------------------------------------------------------
......@@ -625,159 +624,161 @@ static OutputSection *addInputSec(StringMap<OutputSection *> &Map,
625624 //
626625 // Given the above issues, we instead merge sections by name and error on
627626 // incompatible types and flags.
628 OutputSection *&Sec = Map[OutsecName];
629 if (Sec) {
630 Sec->addSection(cast<InputSection>(IS));
627 TinyPtrVector<OutputSection *> &v = map[outsecName];
628 for (OutputSection *sec : v) {
629 if (sec->partition != isec->partition)
630 continue;
631 sec->addSection(cast<InputSection>(isec));
631632 return nullptr;
632633 }
633634
634 Sec = createSection(IS, OutsecName);
635 return Sec;
635 OutputSection *sec = createSection(isec, outsecName);
636 v.push_back(sec);
637 return sec;
636638}
637639
638640// Add sections that didn't match any sections command.
639641void LinkerScript::addOrphanSections() {
640 unsigned End = SectionCommands.size();
641 StringMap<OutputSection *> Map;
642 std::vector<OutputSection *> V;
642 StringMap<TinyPtrVector<OutputSection *>> map;
643 std::vector<OutputSection *> v;
643644
644 auto Add = [&](InputSectionBase *S) {
645 if (!S->Live || S->Parent)
645 auto add = [&](InputSectionBase *s) {
646 if (!s->isLive() || s->parent)
646647 return;
647648
648 StringRef Name = getOutputSectionName(S);
649 StringRef name = getOutputSectionName(s);
649650
650 if (Config->OrphanHandling == OrphanHandlingPolicy::Error)
651 error(toString(S) + " is being placed in '" + Name + "'");
652 else if (Config->OrphanHandling == OrphanHandlingPolicy::Warn)
653 warn(toString(S) + " is being placed in '" + Name + "'");
651 if (config->orphanHandling == OrphanHandlingPolicy::Error)
652 error(toString(s) + " is being placed in '" + name + "'");
653 else if (config->orphanHandling == OrphanHandlingPolicy::Warn)
654 warn(toString(s) + " is being placed in '" + name + "'");
654655
655 if (OutputSection *Sec =
656 findByName(makeArrayRef(SectionCommands).slice(0, End), Name)) {
657 Sec->addSection(cast<InputSection>(S));
656 if (OutputSection *sec = findByName(sectionCommands, name)) {
657 sec->addSection(cast<InputSection>(s));
658658 return;
659659 }
660660
661 if (OutputSection *OS = addInputSec(Map, S, Name))
662 V.push_back(OS);
663 assert(S->getOutputSection()->SectionIndex == UINT32_MAX);
661 if (OutputSection *os = addInputSec(map, s, name))
662 v.push_back(os);
663 assert(s->getOutputSection()->sectionIndex == UINT32_MAX);
664664 };
665665
666666 // For futher --emit-reloc handling code we need target output section
667667 // to be created before we create relocation output section, so we want
668668 // to create target sections first. We do not want priority handling
669669 // for synthetic sections because them are special.
670 for (InputSectionBase *IS : InputSections) {
671 if (auto *Sec = dyn_cast<InputSection>(IS))
672 if (InputSectionBase *Rel = Sec->getRelocatedSection())
673 if (auto *RelIS = dyn_cast_or_null<InputSectionBase>(Rel->Parent))
674 Add(RelIS);
675 Add(IS);
670 for (InputSectionBase *isec : inputSections) {
671 if (auto *sec = dyn_cast<InputSection>(isec))
672 if (InputSectionBase *rel = sec->getRelocatedSection())
673 if (auto *relIS = dyn_cast_or_null<InputSectionBase>(rel->parent))
674 add(relIS);
675 add(isec);
676676 }
677677
678678 // If no SECTIONS command was given, we should insert sections commands
679679 // before others, so that we can handle scripts which refers them,
680680 // for example: "foo = ABSOLUTE(ADDR(.text)));".
681681 // When SECTIONS command is present we just add all orphans to the end.
682 if (HasSectionsCommand)
683 SectionCommands.insert(SectionCommands.end(), V.begin(), V.end());
682 if (hasSectionsCommand)
683 sectionCommands.insert(sectionCommands.end(), v.begin(), v.end());
684684 else
685 SectionCommands.insert(SectionCommands.begin(), V.begin(), V.end());
685 sectionCommands.insert(sectionCommands.begin(), v.begin(), v.end());
686686}
687687
688uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) {
689 bool IsTbss =
690 (Ctx->OutSec->Flags & SHF_TLS) && Ctx->OutSec->Type == SHT_NOBITS;
691 uint64_t Start = IsTbss ? Dot + Ctx->ThreadBssOffset : Dot;
692 Start = alignTo(Start, Alignment);
693 uint64_t End = Start + Size;
688uint64_t LinkerScript::advance(uint64_t size, unsigned alignment) {
689 bool isTbss =
690 (ctx->outSec->flags & SHF_TLS) && ctx->outSec->type == SHT_NOBITS;
691 uint64_t start = isTbss ? dot + ctx->threadBssOffset : dot;
692 start = alignTo(start, alignment);
693 uint64_t end = start + size;
694694
695 if (IsTbss)
696 Ctx->ThreadBssOffset = End - Dot;
695 if (isTbss)
696 ctx->threadBssOffset = end - dot;
697697 else
698 Dot = End;
699 return End;
698 dot = end;
699 return end;
700700}
701701
702void LinkerScript::output(InputSection *S) {
703 assert(Ctx->OutSec == S->getParent());
704 uint64_t Before = advance(0, 1);
705 uint64_t Pos = advance(S->getSize(), S->Alignment);
706 S->OutSecOff = Pos - S->getSize() - Ctx->OutSec->Addr;
702void LinkerScript::output(InputSection *s) {
703 assert(ctx->outSec == s->getParent());
704 uint64_t before = advance(0, 1);
705 uint64_t pos = advance(s->getSize(), s->alignment);
706 s->outSecOff = pos - s->getSize() - ctx->outSec->addr;
707707
708708 // Update output section size after adding each section. This is so that
709709 // SIZEOF works correctly in the case below:
710710 // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
711 expandOutputSection(Pos - Before);
711 expandOutputSection(pos - before);
712712}
713713
714void LinkerScript::switchTo(OutputSection *Sec) {
715 Ctx->OutSec = Sec;
714void LinkerScript::switchTo(OutputSection *sec) {
715 ctx->outSec = sec;
716716
717 uint64_t Before = advance(0, 1);
718 Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment);
719 expandMemoryRegions(Ctx->OutSec->Addr - Before);
717 uint64_t before = advance(0, 1);
718 ctx->outSec->addr = advance(0, ctx->outSec->alignment);
719 expandMemoryRegions(ctx->outSec->addr - before);
720720}
721721
722722// This function searches for a memory region to place the given output
723723// section in. If found, a pointer to the appropriate memory region is
724724// returned. Otherwise, a nullptr is returned.
725MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *Sec) {
725MemoryRegion *LinkerScript::findMemoryRegion(OutputSection *sec) {
726726 // If a memory region name was specified in the output section command,
727727 // then try to find that region first.
728 if (!Sec->MemoryRegionName.empty()) {
729 if (MemoryRegion *M = MemoryRegions.lookup(Sec->MemoryRegionName))
730 return M;
731 error("memory region '" + Sec->MemoryRegionName + "' not declared");
728 if (!sec->memoryRegionName.empty()) {
729 if (MemoryRegion *m = memoryRegions.lookup(sec->memoryRegionName))
730 return m;
731 error("memory region '" + sec->memoryRegionName + "' not declared");
732732 return nullptr;
733733 }
734734
735735 // If at least one memory region is defined, all sections must
736736 // belong to some memory region. Otherwise, we don't need to do
737737 // anything for memory regions.
738 if (MemoryRegions.empty())
738 if (memoryRegions.empty())
739739 return nullptr;
740740
741741 // See if a region can be found by matching section flags.
742 for (auto &Pair : MemoryRegions) {
743 MemoryRegion *M = Pair.second;
744 if ((M->Flags & Sec->Flags) && (M->NegFlags & Sec->Flags) == 0)
745 return M;
742 for (auto &pair : memoryRegions) {
743 MemoryRegion *m = pair.second;
744 if ((m->flags & sec->flags) && (m->negFlags & sec->flags) == 0)
745 return m;
746746 }
747747
748748 // Otherwise, no suitable region was found.
749 if (Sec->Flags & SHF_ALLOC)
750 error("no memory region specified for section '" + Sec->Name + "'");
749 if (sec->flags & SHF_ALLOC)
750 error("no memory region specified for section '" + sec->name + "'");
751751 return nullptr;
752752}
753753
754static OutputSection *findFirstSection(PhdrEntry *Load) {
755 for (OutputSection *Sec : OutputSections)
756 if (Sec->PtLoad == Load)
757 return Sec;
754static OutputSection *findFirstSection(PhdrEntry *load) {
755 for (OutputSection *sec : outputSections)
756 if (sec->ptLoad == load)
757 return sec;
758758 return nullptr;
759759}
760760
761761// This function assigns offsets to input sections and an output section
762762// for a single sections command (e.g. ".text { *(.text); }").
763void LinkerScript::assignOffsets(OutputSection *Sec) {
764 if (!(Sec->Flags & SHF_ALLOC))
765 Dot = 0;
766 else if (Sec->AddrExpr)
767 setDot(Sec->AddrExpr, Sec->Location, false);
763void LinkerScript::assignOffsets(OutputSection *sec) {
764 if (!(sec->flags & SHF_ALLOC))
765 dot = 0;
768766
769 Ctx->MemRegion = Sec->MemRegion;
770 Ctx->LMARegion = Sec->LMARegion;
771 if (Ctx->MemRegion)
772 Dot = Ctx->MemRegion->CurPos;
767 ctx->memRegion = sec->memRegion;
768 ctx->lmaRegion = sec->lmaRegion;
769 if (ctx->memRegion)
770 dot = ctx->memRegion->curPos;
773771
774 switchTo(Sec);
772 if ((sec->flags & SHF_ALLOC) && sec->addrExpr)
773 setDot(sec->addrExpr, sec->location, false);
775774
776 if (Sec->LMAExpr)
777 Ctx->LMAOffset = Sec->LMAExpr().getValue() - Dot;
775 switchTo(sec);
778776
779 if (MemoryRegion *MR = Sec->LMARegion)
780 Ctx->LMAOffset = MR->CurPos - Dot;
777 if (sec->lmaExpr)
778 ctx->lmaOffset = sec->lmaExpr().getValue() - dot;
779
780 if (MemoryRegion *mr = sec->lmaRegion)
781 ctx->lmaOffset = mr->curPos - dot;
781782
782783 // If neither AT nor AT> is specified for an allocatable section, the linker
783784 // will set the LMA such that the difference between VMA and LMA for the
......@@ -785,62 +786,71 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
785786 // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
786787 // This, however, should only be done by the first "non-header" section
787788 // in the segment.
788 if (PhdrEntry *L = Ctx->OutSec->PtLoad)
789 if (Sec == findFirstSection(L))
790 L->LMAOffset = Ctx->LMAOffset;
789 if (PhdrEntry *l = ctx->outSec->ptLoad)
790 if (sec == findFirstSection(l))
791 l->lmaOffset = ctx->lmaOffset;
791792
792793 // We can call this method multiple times during the creation of
793794 // thunks and want to start over calculation each time.
794 Sec->Size = 0;
795 sec->size = 0;
795796
796797 // We visited SectionsCommands from processSectionCommands to
797798 // layout sections. Now, we visit SectionsCommands again to fix
798799 // section offsets.
799 for (BaseCommand *Base : Sec->SectionCommands) {
800 for (BaseCommand *base : sec->sectionCommands) {
800801 // This handles the assignments to symbol or to the dot.
801 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
802 Cmd->Addr = Dot;
803 assignSymbol(Cmd, true);
804 Cmd->Size = Dot - Cmd->Addr;
802 if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
803 cmd->addr = dot;
804 assignSymbol(cmd, true);
805 cmd->size = dot - cmd->addr;
805806 continue;
806807 }
807808
808809 // Handle BYTE(), SHORT(), LONG(), or QUAD().
809 if (auto *Cmd = dyn_cast<ByteCommand>(Base)) {
810 Cmd->Offset = Dot - Ctx->OutSec->Addr;
811 Dot += Cmd->Size;
812 expandOutputSection(Cmd->Size);
810 if (auto *cmd = dyn_cast<ByteCommand>(base)) {
811 cmd->offset = dot - ctx->outSec->addr;
812 dot += cmd->size;
813 expandOutputSection(cmd->size);
813814 continue;
814815 }
815816
816817 // Handle a single input section description command.
817818 // It calculates and assigns the offsets for each section and also
818819 // updates the output section size.
819 for (InputSection *Sec : cast<InputSectionDescription>(Base)->Sections)
820 output(Sec);
820 for (InputSection *sec : cast<InputSectionDescription>(base)->sections)
821 output(sec);
821822 }
822823}
823824
824static bool isDiscardable(OutputSection &Sec) {
825static bool isDiscardable(OutputSection &sec) {
826 if (sec.name == "/DISCARD/")
827 return true;
828
825829 // We do not remove empty sections that are explicitly
826830 // assigned to any segment.
827 if (!Sec.Phdrs.empty())
831 if (!sec.phdrs.empty())
828832 return false;
829833
830 // We do not want to remove sections that reference symbols in address and
831 // other expressions. We add script symbols as undefined, and want to ensure
832 // all of them are defined in the output, hence have to keep them.
833 if (Sec.ExpressionsUseSymbols)
834 // We do not want to remove OutputSections with expressions that reference
835 // symbols even if the OutputSection is empty. We want to ensure that the
836 // expressions can be evaluated and report an error if they cannot.
837 if (sec.expressionsUseSymbols)
834838 return false;
835839
836 for (BaseCommand *Base : Sec.SectionCommands) {
837 if (auto Cmd = dyn_cast<SymbolAssignment>(Base))
840 // OutputSections may be referenced by name in ADDR and LOADADDR expressions,
841 // as an empty Section can has a valid VMA and LMA we keep the OutputSection
842 // to maintain the integrity of the other Expression.
843 if (sec.usedInExpression)
844 return false;
845
846 for (BaseCommand *base : sec.sectionCommands) {
847 if (auto cmd = dyn_cast<SymbolAssignment>(base))
838848 // Don't create empty output sections just for unreferenced PROVIDE
839849 // symbols.
840 if (Cmd->Name != "." && !Cmd->Sym)
850 if (cmd->name != "." && !cmd->sym)
841851 continue;
842852
843 if (!isa<InputSectionDescription>(*Base))
853 if (!isa<InputSectionDescription>(*base))
844854 return false;
845855 }
846856 return true;
......@@ -867,33 +877,35 @@ void LinkerScript::adjustSectionsBeforeSorting() {
867877 // The other option is to pick flags that minimize the impact the section
868878 // will have on the rest of the linker. That is why we copy the flags from
869879 // the previous sections. Only a few flags are needed to keep the impact low.
870 uint64_t Flags = SHF_ALLOC;
880 uint64_t flags = SHF_ALLOC;
871881
872 for (BaseCommand *&Cmd : SectionCommands) {
873 auto *Sec = dyn_cast<OutputSection>(Cmd);
874 if (!Sec)
882 for (BaseCommand *&cmd : sectionCommands) {
883 auto *sec = dyn_cast<OutputSection>(cmd);
884 if (!sec)
875885 continue;
876886
877887 // Handle align (e.g. ".foo : ALIGN(16) { ... }").
878 if (Sec->AlignExpr)
879 Sec->Alignment =
880 std::max<uint32_t>(Sec->Alignment, Sec->AlignExpr().getValue());
888 if (sec->alignExpr)
889 sec->alignment =
890 std::max<uint32_t>(sec->alignment, sec->alignExpr().getValue());
881891
882 // A live output section means that some input section was added to it. It
883 // might have been removed (if it was empty synthetic section), but we at
884 // least know the flags.
885 if (Sec->Live)
886 Flags = Sec->Flags;
892 // The input section might have been removed (if it was an empty synthetic
893 // section), but we at least know the flags.
894 if (sec->hasInputSections)
895 flags = sec->flags;
887896
888897 // We do not want to keep any special flags for output section
889898 // in case it is empty.
890 bool IsEmpty = getInputSections(Sec).empty();
891 if (IsEmpty)
892 Sec->Flags = Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR);
893
894 if (IsEmpty && isDiscardable(*Sec)) {
895 Sec->Live = false;
896 Cmd = nullptr;
899 bool isEmpty = getInputSections(sec).empty();
900 if (isEmpty)
901 sec->flags = flags & ((sec->nonAlloc ? 0 : (uint64_t)SHF_ALLOC) |
902 SHF_WRITE | SHF_EXECINSTR);
903
904 if (isEmpty && isDiscardable(*sec)) {
905 sec->markDead();
906 cmd = nullptr;
907 } else if (!sec->isLive()) {
908 sec->markLive();
897909 }
898910 }
899911
......@@ -903,20 +915,20 @@ void LinkerScript::adjustSectionsBeforeSorting() {
903915 // clutter the output.
904916 // We instead remove trivially empty sections. The bfd linker seems even
905917 // more aggressive at removing them.
906 llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { return !Base; });
918 llvm::erase_if(sectionCommands, [&](BaseCommand *base) { return !base; });
907919}
908920
909921void LinkerScript::adjustSectionsAfterSorting() {
910922 // Try and find an appropriate memory region to assign offsets in.
911 for (BaseCommand *Base : SectionCommands) {
912 if (auto *Sec = dyn_cast<OutputSection>(Base)) {
913 if (!Sec->LMARegionName.empty()) {
914 if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName))
915 Sec->LMARegion = M;
923 for (BaseCommand *base : sectionCommands) {
924 if (auto *sec = dyn_cast<OutputSection>(base)) {
925 if (!sec->lmaRegionName.empty()) {
926 if (MemoryRegion *m = memoryRegions.lookup(sec->lmaRegionName))
927 sec->lmaRegion = m;
916928 else
917 error("memory region '" + Sec->LMARegionName + "' not declared");
929 error("memory region '" + sec->lmaRegionName + "' not declared");
918930 }
919 Sec->MemRegion = findMemoryRegion(Sec);
931 sec->memRegion = findMemoryRegion(sec);
920932 }
921933 }
922934
......@@ -926,38 +938,38 @@ void LinkerScript::adjustSectionsAfterSorting() {
926938 // Below is an example of such linker script:
927939 // PHDRS { seg PT_LOAD; }
928940 // SECTIONS { .aaa : { *(.aaa) } }
929 std::vector<StringRef> DefPhdrs;
930 auto FirstPtLoad = llvm::find_if(PhdrsCommands, [](const PhdrsCommand &Cmd) {
931 return Cmd.Type == PT_LOAD;
941 std::vector<StringRef> defPhdrs;
942 auto firstPtLoad = llvm::find_if(phdrsCommands, [](const PhdrsCommand &cmd) {
943 return cmd.type == PT_LOAD;
932944 });
933 if (FirstPtLoad != PhdrsCommands.end())
934 DefPhdrs.push_back(FirstPtLoad->Name);
945 if (firstPtLoad != phdrsCommands.end())
946 defPhdrs.push_back(firstPtLoad->name);
935947
936948 // Walk the commands and propagate the program headers to commands that don't
937949 // explicitly specify them.
938 for (BaseCommand *Base : SectionCommands) {
939 auto *Sec = dyn_cast<OutputSection>(Base);
940 if (!Sec)
950 for (BaseCommand *base : sectionCommands) {
951 auto *sec = dyn_cast<OutputSection>(base);
952 if (!sec)
941953 continue;
942954
943 if (Sec->Phdrs.empty()) {
955 if (sec->phdrs.empty()) {
944956 // To match the bfd linker script behaviour, only propagate program
945957 // headers to sections that are allocated.
946 if (Sec->Flags & SHF_ALLOC)
947 Sec->Phdrs = DefPhdrs;
958 if (sec->flags & SHF_ALLOC)
959 sec->phdrs = defPhdrs;
948960 } else {
949 DefPhdrs = Sec->Phdrs;
961 defPhdrs = sec->phdrs;
950962 }
951963 }
952964}
953965
954static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) {
966static uint64_t computeBase(uint64_t min, bool allocateHeaders) {
955967 // If there is no SECTIONS or if the linkerscript is explicit about program
956968 // headers, do our best to allocate them.
957 if (!Script->HasSectionsCommand || AllocateHeaders)
969 if (!script->hasSectionsCommand || allocateHeaders)
958970 return 0;
959971 // Otherwise only allocate program headers if that would not add a page.
960 return alignDown(Min, Config->MaxPageSize);
972 return alignDown(min, config->maxPageSize);
961973}
962974
963975// Try to find an address for the file and program headers output sections,
......@@ -971,118 +983,120 @@ static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) {
971983//
972984// If there isn't enough space for these sections, we'll remove them from the
973985// PT_LOAD segment, and we'll also remove the PT_PHDR segment.
974void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) {
975 uint64_t Min = std::numeric_limits<uint64_t>::max();
976 for (OutputSection *Sec : OutputSections)
977 if (Sec->Flags & SHF_ALLOC)
978 Min = std::min<uint64_t>(Min, Sec->Addr);
979
980 auto It = llvm::find_if(
981 Phdrs, [](const PhdrEntry *E) { return E->p_type == PT_LOAD; });
982 if (It == Phdrs.end())
986void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &phdrs) {
987 uint64_t min = std::numeric_limits<uint64_t>::max();
988 for (OutputSection *sec : outputSections)
989 if (sec->flags & SHF_ALLOC)
990 min = std::min<uint64_t>(min, sec->addr);
991
992 auto it = llvm::find_if(
993 phdrs, [](const PhdrEntry *e) { return e->p_type == PT_LOAD; });
994 if (it == phdrs.end())
983995 return;
984 PhdrEntry *FirstPTLoad = *It;
996 PhdrEntry *firstPTLoad = *it;
985997
986 bool HasExplicitHeaders =
987 llvm::any_of(PhdrsCommands, [](const PhdrsCommand &Cmd) {
988 return Cmd.HasPhdrs || Cmd.HasFilehdr;
998 bool hasExplicitHeaders =
999 llvm::any_of(phdrsCommands, [](const PhdrsCommand &cmd) {
1000 return cmd.hasPhdrs || cmd.hasFilehdr;
9891001 });
990 uint64_t HeaderSize = getHeaderSize();
991 if (HeaderSize <= Min - computeBase(Min, HasExplicitHeaders)) {
992 Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
993 Out::ElfHeader->Addr = Min;
994 Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
1002 bool paged = !config->omagic && !config->nmagic;
1003 uint64_t headerSize = getHeaderSize();
1004 if ((paged || hasExplicitHeaders) &&
1005 headerSize <= min - computeBase(min, hasExplicitHeaders)) {
1006 min = alignDown(min - headerSize, config->maxPageSize);
1007 Out::elfHeader->addr = min;
1008 Out::programHeaders->addr = min + Out::elfHeader->size;
9951009 return;
9961010 }
9971011
9981012 // Error if we were explicitly asked to allocate headers.
999 if (HasExplicitHeaders)
1013 if (hasExplicitHeaders)
10001014 error("could not allocate headers");
10011015
1002 Out::ElfHeader->PtLoad = nullptr;
1003 Out::ProgramHeaders->PtLoad = nullptr;
1004 FirstPTLoad->FirstSec = findFirstSection(FirstPTLoad);
1016 Out::elfHeader->ptLoad = nullptr;
1017 Out::programHeaders->ptLoad = nullptr;
1018 firstPTLoad->firstSec = findFirstSection(firstPTLoad);
10051019
1006 llvm::erase_if(Phdrs,
1007 [](const PhdrEntry *E) { return E->p_type == PT_PHDR; });
1020 llvm::erase_if(phdrs,
1021 [](const PhdrEntry *e) { return e->p_type == PT_PHDR; });
10081022}
10091023
10101024LinkerScript::AddressState::AddressState() {
1011 for (auto &MRI : Script->MemoryRegions) {
1012 MemoryRegion *MR = MRI.second;
1013 MR->CurPos = MR->Origin;
1025 for (auto &mri : script->memoryRegions) {
1026 MemoryRegion *mr = mri.second;
1027 mr->curPos = mr->origin;
10141028 }
10151029}
10161030
10171031static uint64_t getInitialDot() {
10181032 // By default linker scripts use an initial value of 0 for '.',
10191033 // but prefer -image-base if set.
1020 if (Script->HasSectionsCommand)
1021 return Config->ImageBase ? *Config->ImageBase : 0;
1034 if (script->hasSectionsCommand)
1035 return config->imageBase ? *config->imageBase : 0;
10221036
1023 uint64_t StartAddr = UINT64_MAX;
1024 // The Sections with -T<section> have been sorted in order of ascending
1025 // address. We must lower StartAddr if the lowest -T<section address> as
1037 uint64_t startAddr = UINT64_MAX;
1038 // The sections with -T<section> have been sorted in order of ascending
1039 // address. We must lower startAddr if the lowest -T<section address> as
10261040 // calls to setDot() must be monotonically increasing.
1027 for (auto &KV : Config->SectionStartMap)
1028 StartAddr = std::min(StartAddr, KV.second);
1029 return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize());
1041 for (auto &kv : config->sectionStartMap)
1042 startAddr = std::min(startAddr, kv.second);
1043 return std::min(startAddr, target->getImageBase() + elf::getHeaderSize());
10301044}
10311045
10321046// Here we assign addresses as instructed by linker script SECTIONS
10331047// sub-commands. Doing that allows us to use final VA values, so here
10341048// we also handle rest commands like symbol assignments and ASSERTs.
10351049void LinkerScript::assignAddresses() {
1036 Dot = getInitialDot();
1037
1038 auto Deleter = make_unique<AddressState>();
1039 Ctx = Deleter.get();
1040 ErrorOnMissingSection = true;
1041 switchTo(Aether);
1042
1043 for (BaseCommand *Base : SectionCommands) {
1044 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
1045 Cmd->Addr = Dot;
1046 assignSymbol(Cmd, false);
1047 Cmd->Size = Dot - Cmd->Addr;
1050 dot = getInitialDot();
1051
1052 auto deleter = make_unique<AddressState>();
1053 ctx = deleter.get();
1054 errorOnMissingSection = true;
1055 switchTo(aether);
1056
1057 for (BaseCommand *base : sectionCommands) {
1058 if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
1059 cmd->addr = dot;
1060 assignSymbol(cmd, false);
1061 cmd->size = dot - cmd->addr;
10481062 continue;
10491063 }
1050 assignOffsets(cast<OutputSection>(Base));
1064 assignOffsets(cast<OutputSection>(base));
10511065 }
1052 Ctx = nullptr;
1066 ctx = nullptr;
10531067}
10541068
10551069// Creates program headers as instructed by PHDRS linker script command.
10561070std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
1057 std::vector<PhdrEntry *> Ret;
1071 std::vector<PhdrEntry *> ret;
10581072
10591073 // Process PHDRS and FILEHDR keywords because they are not
10601074 // real output sections and cannot be added in the following loop.
1061 for (const PhdrsCommand &Cmd : PhdrsCommands) {
1062 PhdrEntry *Phdr = make<PhdrEntry>(Cmd.Type, Cmd.Flags ? *Cmd.Flags : PF_R);
1075 for (const PhdrsCommand &cmd : phdrsCommands) {
1076 PhdrEntry *phdr = make<PhdrEntry>(cmd.type, cmd.flags ? *cmd.flags : PF_R);
10631077
1064 if (Cmd.HasFilehdr)
1065 Phdr->add(Out::ElfHeader);
1066 if (Cmd.HasPhdrs)
1067 Phdr->add(Out::ProgramHeaders);
1078 if (cmd.hasFilehdr)
1079 phdr->add(Out::elfHeader);
1080 if (cmd.hasPhdrs)
1081 phdr->add(Out::programHeaders);
10681082
1069 if (Cmd.LMAExpr) {
1070 Phdr->p_paddr = Cmd.LMAExpr().getValue();
1071 Phdr->HasLMA = true;
1083 if (cmd.lmaExpr) {
1084 phdr->p_paddr = cmd.lmaExpr().getValue();
1085 phdr->hasLMA = true;
10721086 }
1073 Ret.push_back(Phdr);
1087 ret.push_back(phdr);
10741088 }
10751089
10761090 // Add output sections to program headers.
1077 for (OutputSection *Sec : OutputSections) {
1091 for (OutputSection *sec : outputSections) {
10781092 // Assign headers specified by linker script
1079 for (size_t Id : getPhdrIndices(Sec)) {
1080 Ret[Id]->add(Sec);
1081 if (!PhdrsCommands[Id].Flags.hasValue())
1082 Ret[Id]->p_flags |= Sec->getPhdrFlags();
1093 for (size_t id : getPhdrIndices(sec)) {
1094 ret[id]->add(sec);
1095 if (!phdrsCommands[id].flags.hasValue())
1096 ret[id]->p_flags |= sec->getPhdrFlags();
10831097 }
10841098 }
1085 return Ret;
1099 return ret;
10861100}
10871101
10881102// Returns true if we should emit an .interp section.
......@@ -1091,54 +1105,54 @@ std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
10911105// no PT_INTERP is there, there's no place to emit an
10921106// .interp, so we don't do that in that case.
10931107bool LinkerScript::needsInterpSection() {
1094 if (PhdrsCommands.empty())
1108 if (phdrsCommands.empty())
10951109 return true;
1096 for (PhdrsCommand &Cmd : PhdrsCommands)
1097 if (Cmd.Type == PT_INTERP)
1110 for (PhdrsCommand &cmd : phdrsCommands)
1111 if (cmd.type == PT_INTERP)
10981112 return true;
10991113 return false;
11001114}
11011115
1102ExprValue LinkerScript::getSymbolValue(StringRef Name, const Twine &Loc) {
1103 if (Name == ".") {
1104 if (Ctx)
1105 return {Ctx->OutSec, false, Dot - Ctx->OutSec->Addr, Loc};
1106 error(Loc + ": unable to get location counter value");
1116ExprValue LinkerScript::getSymbolValue(StringRef name, const Twine &loc) {
1117 if (name == ".") {
1118 if (ctx)
1119 return {ctx->outSec, false, dot - ctx->outSec->addr, loc};
1120 error(loc + ": unable to get location counter value");
11071121 return 0;
11081122 }
11091123
1110 if (Symbol *Sym = Symtab->find(Name)) {
1111 if (auto *DS = dyn_cast<Defined>(Sym))
1112 return {DS->Section, false, DS->Value, Loc};
1113 if (isa<SharedSymbol>(Sym))
1114 if (!ErrorOnMissingSection)
1115 return {nullptr, false, 0, Loc};
1124 if (Symbol *sym = symtab->find(name)) {
1125 if (auto *ds = dyn_cast<Defined>(sym))
1126 return {ds->section, false, ds->value, loc};
1127 if (isa<SharedSymbol>(sym))
1128 if (!errorOnMissingSection)
1129 return {nullptr, false, 0, loc};
11161130 }
11171131
1118 error(Loc + ": symbol not found: " + Name);
1132 error(loc + ": symbol not found: " + name);
11191133 return 0;
11201134}
11211135
11221136// Returns the index of the segment named Name.
1123static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> Vec,
1124 StringRef Name) {
1125 for (size_t I = 0; I < Vec.size(); ++I)
1126 if (Vec[I].Name == Name)
1127 return I;
1137static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> vec,
1138 StringRef name) {
1139 for (size_t i = 0; i < vec.size(); ++i)
1140 if (vec[i].name == name)
1141 return i;
11281142 return None;
11291143}
11301144
11311145// Returns indices of ELF headers containing specific section. Each index is a
11321146// zero based number of ELF header listed within PHDRS {} script block.
1133std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Cmd) {
1134 std::vector<size_t> Ret;
1135
1136 for (StringRef S : Cmd->Phdrs) {
1137 if (Optional<size_t> Idx = getPhdrIndex(PhdrsCommands, S))
1138 Ret.push_back(*Idx);
1139 else if (S != "NONE")
1140 error(Cmd->Location + ": section header '" + S +
1147std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *cmd) {
1148 std::vector<size_t> ret;
1149
1150 for (StringRef s : cmd->phdrs) {
1151 if (Optional<size_t> idx = getPhdrIndex(phdrsCommands, s))
1152 ret.push_back(*idx);
1153 else if (s != "NONE")
1154 error(cmd->location + ": section header '" + s +
11411155 "' is not listed in PHDRS");
11421156 }
1143 return Ret;
1157 return ret;
11441158}
deps/lld/ELF/LinkerScript.h+110-112
......@@ -1,9 +1,8 @@
11//===- LinkerScript.h -------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -32,7 +31,6 @@ namespace elf {
3231class Defined;
3332class InputSection;
3433class InputSectionBase;
35class InputSectionBase;
3634class OutputSection;
3735class SectionBase;
3836class Symbol;
......@@ -40,35 +38,35 @@ class ThunkSection;
4038
4139// This represents an r-value in the linker script.
4240struct ExprValue {
43 ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
44 const Twine &Loc)
45 : Sec(Sec), ForceAbsolute(ForceAbsolute), Val(Val), Loc(Loc.str()) {}
41 ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val,
42 const Twine &loc)
43 : sec(sec), forceAbsolute(forceAbsolute), val(val), loc(loc.str()) {}
4644
47 ExprValue(uint64_t Val) : ExprValue(nullptr, false, Val, "") {}
45 ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {}
4846
49 bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
47 bool isAbsolute() const { return forceAbsolute || sec == nullptr; }
5048 uint64_t getValue() const;
5149 uint64_t getSecAddr() const;
5250 uint64_t getSectionOffset() const;
5351
5452 // If a value is relative to a section, it has a non-null Sec.
55 SectionBase *Sec;
53 SectionBase *sec;
5654
5755 // True if this expression is enclosed in ABSOLUTE().
5856 // This flag affects the return value of getValue().
59 bool ForceAbsolute;
57 bool forceAbsolute;
6058
61 uint64_t Val;
62 uint64_t Alignment = 1;
59 uint64_t val;
60 uint64_t alignment = 1;
6361
6462 // Original source location. Used for error messages.
65 std::string Loc;
63 std::string loc;
6664};
6765
6866// This represents an expression in the linker script.
6967// ScriptParser::readExpr reads an expression and returns an Expr.
7068// Later, we evaluate the expression by calling the function.
71typedef std::function<ExprValue()> Expr;
69using Expr = std::function<ExprValue()>;
7270
7371// This enum is used to implement linker script SECTIONS command.
7472// https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
......@@ -80,42 +78,42 @@ enum SectionsCommandKind {
8078};
8179
8280struct BaseCommand {
83 BaseCommand(int K) : Kind(K) {}
84 int Kind;
81 BaseCommand(int k) : kind(k) {}
82 int kind;
8583};
8684
8785// This represents ". = <expr>" or "<symbol> = <expr>".
8886struct SymbolAssignment : BaseCommand {
89 SymbolAssignment(StringRef Name, Expr E, std::string Loc)
90 : BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc) {}
87 SymbolAssignment(StringRef name, Expr e, std::string loc)
88 : BaseCommand(AssignmentKind), name(name), expression(e), location(loc) {}
9189
92 static bool classof(const BaseCommand *C) {
93 return C->Kind == AssignmentKind;
90 static bool classof(const BaseCommand *c) {
91 return c->kind == AssignmentKind;
9492 }
9593
9694 // The LHS of an expression. Name is either a symbol name or ".".
97 StringRef Name;
98 Defined *Sym = nullptr;
95 StringRef name;
96 Defined *sym = nullptr;
9997
10098 // The RHS of an expression.
101 Expr Expression;
99 Expr expression;
102100
103101 // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
104 bool Provide = false;
105 bool Hidden = false;
102 bool provide = false;
103 bool hidden = false;
106104
107105 // Holds file name and line number for error reporting.
108 std::string Location;
106 std::string location;
109107
110108 // A string representation of this command. We use this for -Map.
111 std::string CommandString;
109 std::string commandString;
112110
113111 // Address of this assignment command.
114 unsigned Addr;
112 unsigned addr;
115113
116114 // Size of this assignment command. This is usually 0, but if
117115 // you move '.' this may be greater than 0.
118 unsigned Size;
116 unsigned size;
119117};
120118
121119// Linker scripts allow additional constraints to be put on ouput sections.
......@@ -128,83 +126,83 @@ enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
128126// target memory. Instances of the struct are created by parsing the
129127// MEMORY command.
130128struct MemoryRegion {
131 MemoryRegion(StringRef Name, uint64_t Origin, uint64_t Length, uint32_t Flags,
132 uint32_t NegFlags)
133 : Name(Name), Origin(Origin), Length(Length), Flags(Flags),
134 NegFlags(NegFlags) {}
135
136 std::string Name;
137 uint64_t Origin;
138 uint64_t Length;
139 uint32_t Flags;
140 uint32_t NegFlags;
141 uint64_t CurPos = 0;
129 MemoryRegion(StringRef name, uint64_t origin, uint64_t length, uint32_t flags,
130 uint32_t negFlags)
131 : name(name), origin(origin), length(length), flags(flags),
132 negFlags(negFlags) {}
133
134 std::string name;
135 uint64_t origin;
136 uint64_t length;
137 uint32_t flags;
138 uint32_t negFlags;
139 uint64_t curPos = 0;
142140};
143141
144142// This struct represents one section match pattern in SECTIONS() command.
145143// It can optionally have negative match pattern for EXCLUDED_FILE command.
146144// Also it may be surrounded with SORT() command, so contains sorting rules.
147145struct SectionPattern {
148 SectionPattern(StringMatcher &&Pat1, StringMatcher &&Pat2)
149 : ExcludedFilePat(Pat1), SectionPat(Pat2),
150 SortOuter(SortSectionPolicy::Default),
151 SortInner(SortSectionPolicy::Default) {}
152
153 StringMatcher ExcludedFilePat;
154 StringMatcher SectionPat;
155 SortSectionPolicy SortOuter;
156 SortSectionPolicy SortInner;
146 SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2)
147 : excludedFilePat(pat1), sectionPat(pat2),
148 sortOuter(SortSectionPolicy::Default),
149 sortInner(SortSectionPolicy::Default) {}
150
151 StringMatcher excludedFilePat;
152 StringMatcher sectionPat;
153 SortSectionPolicy sortOuter;
154 SortSectionPolicy sortInner;
157155};
158156
159157struct InputSectionDescription : BaseCommand {
160 InputSectionDescription(StringRef FilePattern)
161 : BaseCommand(InputSectionKind), FilePat(FilePattern) {}
158 InputSectionDescription(StringRef filePattern)
159 : BaseCommand(InputSectionKind), filePat(filePattern) {}
162160
163 static bool classof(const BaseCommand *C) {
164 return C->Kind == InputSectionKind;
161 static bool classof(const BaseCommand *c) {
162 return c->kind == InputSectionKind;
165163 }
166164
167 StringMatcher FilePat;
165 StringMatcher filePat;
168166
169167 // Input sections that matches at least one of SectionPatterns
170168 // will be associated with this InputSectionDescription.
171 std::vector<SectionPattern> SectionPatterns;
169 std::vector<SectionPattern> sectionPatterns;
172170
173 std::vector<InputSection *> Sections;
171 std::vector<InputSection *> sections;
174172
175173 // Temporary record of synthetic ThunkSection instances and the pass that
176174 // they were created in. This is used to insert newly created ThunkSections
177175 // into Sections at the end of a createThunks() pass.
178 std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections;
176 std::vector<std::pair<ThunkSection *, uint32_t>> thunkSections;
179177};
180178
181179// Represents BYTE(), SHORT(), LONG(), or QUAD().
182180struct ByteCommand : BaseCommand {
183 ByteCommand(Expr E, unsigned Size, std::string CommandString)
184 : BaseCommand(ByteKind), CommandString(CommandString), Expression(E),
185 Size(Size) {}
181 ByteCommand(Expr e, unsigned size, std::string commandString)
182 : BaseCommand(ByteKind), commandString(commandString), expression(e),
183 size(size) {}
186184
187 static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; }
185 static bool classof(const BaseCommand *c) { return c->kind == ByteKind; }
188186
189187 // Keeps string representing the command. Used for -Map" is perhaps better.
190 std::string CommandString;
188 std::string commandString;
191189
192 Expr Expression;
190 Expr expression;
193191
194192 // This is just an offset of this assignment command in the output section.
195 unsigned Offset;
193 unsigned offset;
196194
197195 // Size of this data command.
198 unsigned Size;
196 unsigned size;
199197};
200198
201199struct PhdrsCommand {
202 StringRef Name;
203 unsigned Type = llvm::ELF::PT_NULL;
204 bool HasFilehdr = false;
205 bool HasPhdrs = false;
206 llvm::Optional<unsigned> Flags;
207 Expr LMAExpr = nullptr;
200 StringRef name;
201 unsigned type = llvm::ELF::PT_NULL;
202 bool hasFilehdr = false;
203 bool hasPhdrs = false;
204 llvm::Optional<unsigned> flags;
205 Expr lmaExpr = nullptr;
208206};
209207
210208class LinkerScript final {
......@@ -213,35 +211,35 @@ class LinkerScript final {
213211 // not be used outside of the scope of a call to the above functions.
214212 struct AddressState {
215213 AddressState();
216 uint64_t ThreadBssOffset = 0;
217 OutputSection *OutSec = nullptr;
218 MemoryRegion *MemRegion = nullptr;
219 MemoryRegion *LMARegion = nullptr;
220 uint64_t LMAOffset = 0;
214 uint64_t threadBssOffset = 0;
215 OutputSection *outSec = nullptr;
216 MemoryRegion *memRegion = nullptr;
217 MemoryRegion *lmaRegion = nullptr;
218 uint64_t lmaOffset = 0;
221219 };
222220
223 llvm::DenseMap<StringRef, OutputSection *> NameToOutputSection;
221 llvm::DenseMap<StringRef, OutputSection *> nameToOutputSection;
224222
225 void addSymbol(SymbolAssignment *Cmd);
226 void assignSymbol(SymbolAssignment *Cmd, bool InSec);
227 void setDot(Expr E, const Twine &Loc, bool InSec);
228 void expandOutputSection(uint64_t Size);
229 void expandMemoryRegions(uint64_t Size);
223 void addSymbol(SymbolAssignment *cmd);
224 void assignSymbol(SymbolAssignment *cmd, bool inSec);
225 void setDot(Expr e, const Twine &loc, bool inSec);
226 void expandOutputSection(uint64_t size);
227 void expandMemoryRegions(uint64_t size);
230228
231229 std::vector<InputSection *>
232230 computeInputSections(const InputSectionDescription *);
233231
234 std::vector<InputSection *> createInputSectionList(OutputSection &Cmd);
232 std::vector<InputSection *> createInputSectionList(OutputSection &cmd);
235233
236 std::vector<size_t> getPhdrIndices(OutputSection *Sec);
234 std::vector<size_t> getPhdrIndices(OutputSection *sec);
237235
238 MemoryRegion *findMemoryRegion(OutputSection *Sec);
236 MemoryRegion *findMemoryRegion(OutputSection *sec);
239237
240 void switchTo(OutputSection *Sec);
241 uint64_t advance(uint64_t Size, unsigned Align);
242 void output(InputSection *Sec);
238 void switchTo(OutputSection *sec);
239 uint64_t advance(uint64_t size, unsigned align);
240 void output(InputSection *sec);
243241
244 void assignOffsets(OutputSection *Sec);
242 void assignOffsets(OutputSection *sec);
245243
246244 // Ctx captures the local AddressState and makes it accessible
247245 // deliberately. This is needed as there are some cases where we cannot just
......@@ -249,21 +247,21 @@ class LinkerScript final {
249247 // script parser.
250248 // This should remain a plain pointer as its lifetime is smaller than
251249 // LinkerScript.
252 AddressState *Ctx = nullptr;
250 AddressState *ctx = nullptr;
253251
254 OutputSection *Aether;
252 OutputSection *aether;
255253
256 uint64_t Dot;
254 uint64_t dot;
257255
258256public:
259 OutputSection *createOutputSection(StringRef Name, StringRef Location);
260 OutputSection *getOrCreateOutputSection(StringRef Name);
257 OutputSection *createOutputSection(StringRef name, StringRef location);
258 OutputSection *getOrCreateOutputSection(StringRef name);
261259
262 bool hasPhdrsCommands() { return !PhdrsCommands.empty(); }
263 uint64_t getDot() { return Dot; }
264 void discard(ArrayRef<InputSection *> V);
260 bool hasPhdrsCommands() { return !phdrsCommands.empty(); }
261 uint64_t getDot() { return dot; }
262 void discard(ArrayRef<InputSection *> v);
265263
266 ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
264 ExprValue getSymbolValue(StringRef name, const Twine &loc);
267265
268266 void addOrphanSections();
269267 void adjustSectionsBeforeSorting();
......@@ -272,9 +270,9 @@ public:
272270 std::vector<PhdrEntry *> createPhdrs();
273271 bool needsInterpSection();
274272
275 bool shouldKeep(InputSectionBase *S);
273 bool shouldKeep(InputSectionBase *s);
276274 void assignAddresses();
277 void allocateHeaders(std::vector<PhdrEntry *> &Phdrs);
275 void allocateHeaders(std::vector<PhdrEntry *> &phdrs);
278276 void processSectionCommands();
279277 void declareSymbols();
280278
......@@ -282,31 +280,31 @@ public:
282280 void processInsertCommands();
283281
284282 // SECTIONS command list.
285 std::vector<BaseCommand *> SectionCommands;
283 std::vector<BaseCommand *> sectionCommands;
286284
287285 // PHDRS command list.
288 std::vector<PhdrsCommand> PhdrsCommands;
286 std::vector<PhdrsCommand> phdrsCommands;
289287
290 bool HasSectionsCommand = false;
291 bool ErrorOnMissingSection = false;
288 bool hasSectionsCommand = false;
289 bool errorOnMissingSection = false;
292290
293291 // List of section patterns specified with KEEP commands. They will
294292 // be kept even if they are unused and --gc-sections is specified.
295 std::vector<InputSectionDescription *> KeptSections;
293 std::vector<InputSectionDescription *> keptSections;
296294
297295 // A map from memory region name to a memory region descriptor.
298 llvm::MapVector<llvm::StringRef, MemoryRegion *> MemoryRegions;
296 llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions;
299297
300298 // A list of symbols referenced by the script.
301 std::vector<llvm::StringRef> ReferencedSymbols;
299 std::vector<llvm::StringRef> referencedSymbols;
302300
303301 // Used to implement INSERT [AFTER|BEFORE]. Contains commands that need
304302 // to be inserted into SECTIONS commands list.
305 llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands;
306 llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertBeforeCommands;
303 llvm::DenseMap<StringRef, std::vector<BaseCommand *>> insertAfterCommands;
304 llvm::DenseMap<StringRef, std::vector<BaseCommand *>> insertBeforeCommands;
307305};
308306
309extern LinkerScript *Script;
307extern LinkerScript *script;
310308
311309} // end namespace elf
312310} // end namespace lld
deps/lld/ELF/MapFile.cpp+116-118
......@@ -1,9 +1,8 @@
11//===- MapFile.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -38,69 +37,67 @@ using namespace llvm::object;
3837using namespace lld;
3938using namespace lld::elf;
4039
41typedef DenseMap<const SectionBase *, SmallVector<Defined *, 4>> SymbolMapTy;
40using SymbolMapTy = DenseMap<const SectionBase *, SmallVector<Defined *, 4>>;
4241
43static const std::string Indent8 = " "; // 8 spaces
44static const std::string Indent16 = " "; // 16 spaces
42static const std::string indent8 = " "; // 8 spaces
43static const std::string indent16 = " "; // 16 spaces
4544
4645// Print out the first three columns of a line.
47static void writeHeader(raw_ostream &OS, uint64_t VMA, uint64_t LMA,
48 uint64_t Size, uint64_t Align) {
49 if (Config->Is64)
50 OS << format("%16llx %16llx %8llx %5lld ", VMA, LMA, Size, Align);
46static void writeHeader(raw_ostream &os, uint64_t vma, uint64_t lma,
47 uint64_t size, uint64_t align) {
48 if (config->is64)
49 os << format("%16llx %16llx %8llx %5lld ", vma, lma, size, align);
5150 else
52 OS << format("%8llx %8llx %8llx %5lld ", VMA, LMA, Size, Align);
51 os << format("%8llx %8llx %8llx %5lld ", vma, lma, size, align);
5352}
5453
5554// Returns a list of all symbols that we want to print out.
5655static std::vector<Defined *> getSymbols() {
57 std::vector<Defined *> V;
58 for (InputFile *File : ObjectFiles)
59 for (Symbol *B : File->getSymbols())
60 if (auto *DR = dyn_cast<Defined>(B))
61 if (!DR->isSection() && DR->Section && DR->Section->Live &&
62 (DR->File == File || DR->NeedsPltAddr || DR->Section->Bss))
63 V.push_back(DR);
64 return V;
56 std::vector<Defined *> v;
57 for (InputFile *file : objectFiles)
58 for (Symbol *b : file->getSymbols())
59 if (auto *dr = dyn_cast<Defined>(b))
60 if (!dr->isSection() && dr->section && dr->section->isLive() &&
61 (dr->file == file || dr->needsPltAddr || dr->section->bss))
62 v.push_back(dr);
63 return v;
6564}
6665
6766// Returns a map from sections to their symbols.
68static SymbolMapTy getSectionSyms(ArrayRef<Defined *> Syms) {
69 SymbolMapTy Ret;
70 for (Defined *DR : Syms)
71 Ret[DR->Section].push_back(DR);
67static SymbolMapTy getSectionSyms(ArrayRef<Defined *> syms) {
68 SymbolMapTy ret;
69 for (Defined *dr : syms)
70 ret[dr->section].push_back(dr);
7271
7372 // Sort symbols by address. We want to print out symbols in the
7473 // order in the output file rather than the order they appeared
7574 // in the input files.
76 for (auto &It : Ret) {
77 SmallVectorImpl<Defined *> &V = It.second;
78 std::stable_sort(V.begin(), V.end(), [](Defined *A, Defined *B) {
79 return A->getVA() < B->getVA();
75 for (auto &it : ret)
76 llvm::stable_sort(it.second, [](Defined *a, Defined *b) {
77 return a->getVA() < b->getVA();
8078 });
81 }
82 return Ret;
79 return ret;
8380}
8481
8582// Construct a map from symbols to their stringified representations.
8683// Demangling symbols (which is what toString() does) is slow, so
8784// we do that in batch using parallel-for.
8885static DenseMap<Symbol *, std::string>
89getSymbolStrings(ArrayRef<Defined *> Syms) {
90 std::vector<std::string> Str(Syms.size());
91 parallelForEachN(0, Syms.size(), [&](size_t I) {
92 raw_string_ostream OS(Str[I]);
93 OutputSection *OSec = Syms[I]->getOutputSection();
94 uint64_t VMA = Syms[I]->getVA();
95 uint64_t LMA = OSec ? OSec->getLMA() + VMA - OSec->getVA(0) : 0;
96 writeHeader(OS, VMA, LMA, Syms[I]->getSize(), 1);
97 OS << Indent16 << toString(*Syms[I]);
86getSymbolStrings(ArrayRef<Defined *> syms) {
87 std::vector<std::string> str(syms.size());
88 parallelForEachN(0, syms.size(), [&](size_t i) {
89 raw_string_ostream os(str[i]);
90 OutputSection *osec = syms[i]->getOutputSection();
91 uint64_t vma = syms[i]->getVA();
92 uint64_t lma = osec ? osec->getLMA() + vma - osec->getVA(0) : 0;
93 writeHeader(os, vma, lma, syms[i]->getSize(), 1);
94 os << indent16 << toString(*syms[i]);
9895 });
9996
100 DenseMap<Symbol *, std::string> Ret;
101 for (size_t I = 0, E = Syms.size(); I < E; ++I)
102 Ret[Syms[I]] = std::move(Str[I]);
103 return Ret;
97 DenseMap<Symbol *, std::string> ret;
98 for (size_t i = 0, e = syms.size(); i < e; ++i)
99 ret[syms[i]] = std::move(str[i]);
100 return ret;
104101}
105102
106103// Print .eh_frame contents. Since the section consists of EhSectionPieces,
......@@ -109,114 +106,115 @@ getSymbolStrings(ArrayRef<Defined *> Syms) {
109106// .eh_frame tend to contain a lot of section pieces that are contiguous
110107// both in input file and output file. Such pieces are squashed before
111108// being displayed to make output compact.
112static void printEhFrame(raw_ostream &OS, OutputSection *OSec) {
113 std::vector<EhSectionPiece> Pieces;
109static void printEhFrame(raw_ostream &os, const EhFrameSection *sec) {
110 std::vector<EhSectionPiece> pieces;
114111
115 auto Add = [&](const EhSectionPiece &P) {
112 auto add = [&](const EhSectionPiece &p) {
116113 // If P is adjacent to Last, squash the two.
117 if (!Pieces.empty()) {
118 EhSectionPiece &Last = Pieces.back();
119 if (Last.Sec == P.Sec && Last.InputOff + Last.Size == P.InputOff &&
120 Last.OutputOff + Last.Size == P.OutputOff) {
121 Last.Size += P.Size;
114 if (!pieces.empty()) {
115 EhSectionPiece &last = pieces.back();
116 if (last.sec == p.sec && last.inputOff + last.size == p.inputOff &&
117 last.outputOff + last.size == p.outputOff) {
118 last.size += p.size;
122119 return;
123120 }
124121 }
125 Pieces.push_back(P);
122 pieces.push_back(p);
126123 };
127124
128125 // Gather section pieces.
129 for (const CieRecord *Rec : In.EhFrame->getCieRecords()) {
130 Add(*Rec->Cie);
131 for (const EhSectionPiece *Fde : Rec->Fdes)
132 Add(*Fde);
126 for (const CieRecord *rec : sec->getCieRecords()) {
127 add(*rec->cie);
128 for (const EhSectionPiece *fde : rec->fdes)
129 add(*fde);
133130 }
134131
135132 // Print out section pieces.
136 for (EhSectionPiece &P : Pieces) {
137 writeHeader(OS, OSec->Addr + P.OutputOff, OSec->getLMA() + P.OutputOff,
138 P.Size, 1);
139 OS << Indent8 << toString(P.Sec->File) << ":(" << P.Sec->Name << "+0x"
140 << Twine::utohexstr(P.InputOff) + ")\n";
133 const OutputSection *osec = sec->getOutputSection();
134 for (EhSectionPiece &p : pieces) {
135 writeHeader(os, osec->addr + p.outputOff, osec->getLMA() + p.outputOff,
136 p.size, 1);
137 os << indent8 << toString(p.sec->file) << ":(" << p.sec->name << "+0x"
138 << Twine::utohexstr(p.inputOff) + ")\n";
141139 }
142140}
143141
144142void elf::writeMapFile() {
145 if (Config->MapFile.empty())
143 if (config->mapFile.empty())
146144 return;
147145
148146 // Open a map file for writing.
149 std::error_code EC;
150 raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
151 if (EC) {
152 error("cannot open " + Config->MapFile + ": " + EC.message());
147 std::error_code ec;
148 raw_fd_ostream os(config->mapFile, ec, sys::fs::F_None);
149 if (ec) {
150 error("cannot open " + config->mapFile + ": " + ec.message());
153151 return;
154152 }
155153
156154 // Collect symbol info that we want to print out.
157 std::vector<Defined *> Syms = getSymbols();
158 SymbolMapTy SectionSyms = getSectionSyms(Syms);
159 DenseMap<Symbol *, std::string> SymStr = getSymbolStrings(Syms);
155 std::vector<Defined *> syms = getSymbols();
156 SymbolMapTy sectionSyms = getSectionSyms(syms);
157 DenseMap<Symbol *, std::string> symStr = getSymbolStrings(syms);
160158
161159 // Print out the header line.
162 int W = Config->Is64 ? 16 : 8;
163 OS << right_justify("VMA", W) << ' ' << right_justify("LMA", W)
160 int w = config->is64 ? 16 : 8;
161 os << right_justify("VMA", w) << ' ' << right_justify("LMA", w)
164162 << " Size Align Out In Symbol\n";
165163
166 OutputSection* OSec = nullptr;
167 for (BaseCommand *Base : Script->SectionCommands) {
168 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
169 if (Cmd->Provide && !Cmd->Sym)
164 OutputSection* osec = nullptr;
165 for (BaseCommand *base : script->sectionCommands) {
166 if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
167 if (cmd->provide && !cmd->sym)
170168 continue;
171 uint64_t LMA = OSec ? OSec->getLMA() + Cmd->Addr - OSec->getVA(0) : 0;
172 writeHeader(OS, Cmd->Addr, LMA, Cmd->Size, 1);
173 OS << Cmd->CommandString << '\n';
169 uint64_t lma = osec ? osec->getLMA() + cmd->addr - osec->getVA(0) : 0;
170 writeHeader(os, cmd->addr, lma, cmd->size, 1);
171 os << cmd->commandString << '\n';
174172 continue;
175173 }
176174
177 OSec = cast<OutputSection>(Base);
178 writeHeader(OS, OSec->Addr, OSec->getLMA(), OSec->Size, OSec->Alignment);
179 OS << OSec->Name << '\n';
175 osec = cast<OutputSection>(base);
176 writeHeader(os, osec->addr, osec->getLMA(), osec->size, osec->alignment);
177 os << osec->name << '\n';
180178
181179 // Dump symbols for each input section.
182 for (BaseCommand *Base : OSec->SectionCommands) {
183 if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
184 for (InputSection *IS : ISD->Sections) {
185 if (IS == In.EhFrame) {
186 printEhFrame(OS, OSec);
180 for (BaseCommand *base : osec->sectionCommands) {
181 if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
182 for (InputSection *isec : isd->sections) {
183 if (auto *ehSec = dyn_cast<EhFrameSection>(isec)) {
184 printEhFrame(os, ehSec);
187185 continue;
188186 }
189187
190 writeHeader(OS, IS->getVA(0), OSec->getLMA() + IS->getOffset(0),
191 IS->getSize(), IS->Alignment);
192 OS << Indent8 << toString(IS) << '\n';
193 for (Symbol *Sym : SectionSyms[IS])
194 OS << SymStr[Sym] << '\n';
188 writeHeader(os, isec->getVA(0), osec->getLMA() + isec->getOffset(0),
189 isec->getSize(), isec->alignment);
190 os << indent8 << toString(isec) << '\n';
191 for (Symbol *sym : sectionSyms[isec])
192 os << symStr[sym] << '\n';
195193 }
196194 continue;
197195 }
198196
199 if (auto *Cmd = dyn_cast<ByteCommand>(Base)) {
200 writeHeader(OS, OSec->Addr + Cmd->Offset, OSec->getLMA() + Cmd->Offset,
201 Cmd->Size, 1);
202 OS << Indent8 << Cmd->CommandString << '\n';
197 if (auto *cmd = dyn_cast<ByteCommand>(base)) {
198 writeHeader(os, osec->addr + cmd->offset, osec->getLMA() + cmd->offset,
199 cmd->size, 1);
200 os << indent8 << cmd->commandString << '\n';
203201 continue;
204202 }
205203
206 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
207 if (Cmd->Provide && !Cmd->Sym)
204 if (auto *cmd = dyn_cast<SymbolAssignment>(base)) {
205 if (cmd->provide && !cmd->sym)
208206 continue;
209 writeHeader(OS, Cmd->Addr, OSec->getLMA() + Cmd->Addr - OSec->getVA(0),
210 Cmd->Size, 1);
211 OS << Indent8 << Cmd->CommandString << '\n';
207 writeHeader(os, cmd->addr, osec->getLMA() + cmd->addr - osec->getVA(0),
208 cmd->size, 1);
209 os << indent8 << cmd->commandString << '\n';
212210 continue;
213211 }
214212 }
215213 }
216214}
217215
218static void print(StringRef A, StringRef B) {
219 outs() << left_justify(A, 49) << " " << B << "\n";
216static void print(StringRef a, StringRef b) {
217 outs() << left_justify(a, 49) << " " << b << "\n";
220218}
221219
222220// Output a cross reference table to stdout. This is for --cref.
......@@ -231,18 +229,18 @@ static void print(StringRef A, StringRef B) {
231229// In this case, strlen is defined by libc.so.6 and used by other two
232230// files.
233231void elf::writeCrossReferenceTable() {
234 if (!Config->Cref)
232 if (!config->cref)
235233 return;
236234
237235 // Collect symbols and files.
238 MapVector<Symbol *, SetVector<InputFile *>> Map;
239 for (InputFile *File : ObjectFiles) {
240 for (Symbol *Sym : File->getSymbols()) {
241 if (isa<SharedSymbol>(Sym))
242 Map[Sym].insert(File);
243 if (auto *D = dyn_cast<Defined>(Sym))
244 if (!D->isLocal() && (!D->Section || D->Section->Live))
245 Map[D].insert(File);
236 MapVector<Symbol *, SetVector<InputFile *>> map;
237 for (InputFile *file : objectFiles) {
238 for (Symbol *sym : file->getSymbols()) {
239 if (isa<SharedSymbol>(sym))
240 map[sym].insert(file);
241 if (auto *d = dyn_cast<Defined>(sym))
242 if (!d->isLocal() && (!d->section || d->section->isLive()))
243 map[d].insert(file);
246244 }
247245 }
248246
......@@ -251,13 +249,13 @@ void elf::writeCrossReferenceTable() {
251249 print("Symbol", "File");
252250
253251 // Print out a table.
254 for (auto KV : Map) {
255 Symbol *Sym = KV.first;
256 SetVector<InputFile *> &Files = KV.second;
252 for (auto kv : map) {
253 Symbol *sym = kv.first;
254 SetVector<InputFile *> &files = kv.second;
257255
258 print(toString(*Sym), toString(Sym->File));
259 for (InputFile *File : Files)
260 if (File != Sym->File)
261 print("", toString(File));
256 print(toString(*sym), toString(sym->file));
257 for (InputFile *file : files)
258 if (file != sym->file)
259 print("", toString(file));
262260 }
263261}
deps/lld/ELF/MapFile.h+3-4
......@@ -1,9 +1,8 @@
11//===- MapFile.h ------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/ELF/MarkLive.cpp+217-168
......@@ -1,9 +1,8 @@
11//===- MarkLive.cpp -------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -26,6 +25,7 @@
2625#include "OutputSections.h"
2726#include "SymbolTable.h"
2827#include "Symbols.h"
28#include "SyntheticSections.h"
2929#include "Target.h"
3030#include "lld/Common/Memory.h"
3131#include "lld/Common/Strings.h"
......@@ -42,66 +42,79 @@ using namespace llvm::support::endian;
4242using namespace lld;
4343using namespace lld::elf;
4444
45namespace {
46template <class ELFT> class MarkLive {
47public:
48 MarkLive(unsigned partition) : partition(partition) {}
49
50 void run();
51 void moveToMain();
52
53private:
54 void enqueue(InputSectionBase *sec, uint64_t offset);
55 void markSymbol(Symbol *sym);
56 void mark();
57
58 template <class RelTy>
59 void resolveReloc(InputSectionBase &sec, RelTy &rel, bool isLSDA);
60
61 template <class RelTy>
62 void scanEhFrameSection(EhInputSection &eh, ArrayRef<RelTy> rels);
63
64 // The index of the partition that we are currently processing.
65 unsigned partition;
66
67 // A list of sections to visit.
68 SmallVector<InputSection *, 256> queue;
69
70 // There are normally few input sections whose names are valid C
71 // identifiers, so we just store a std::vector instead of a multimap.
72 DenseMap<StringRef, std::vector<InputSectionBase *>> cNamedSections;
73};
74} // namespace
75
4576template <class ELFT>
46static typename ELFT::uint getAddend(InputSectionBase &Sec,
47 const typename ELFT::Rel &Rel) {
48 return Target->getImplicitAddend(Sec.data().begin() + Rel.r_offset,
49 Rel.getType(Config->IsMips64EL));
77static uint64_t getAddend(InputSectionBase &sec,
78 const typename ELFT::Rel &rel) {
79 return target->getImplicitAddend(sec.data().begin() + rel.r_offset,
80 rel.getType(config->isMips64EL));
5081}
5182
5283template <class ELFT>
53static typename ELFT::uint getAddend(InputSectionBase &Sec,
54 const typename ELFT::Rela &Rel) {
55 return Rel.r_addend;
84static uint64_t getAddend(InputSectionBase &sec,
85 const typename ELFT::Rela &rel) {
86 return rel.r_addend;
5687}
5788
58// There are normally few input sections whose names are valid C
59// identifiers, so we just store a std::vector instead of a multimap.
60static DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections;
61
62template <class ELFT, class RelT>
63static void
64resolveReloc(InputSectionBase &Sec, RelT &Rel,
65 llvm::function_ref<void(InputSectionBase *, uint64_t)> Fn) {
66 Symbol &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
89template <class ELFT>
90template <class RelTy>
91void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel,
92 bool isLSDA) {
93 Symbol &sym = sec.getFile<ELFT>()->getRelocTargetSym(rel);
6794
6895 // If a symbol is referenced in a live section, it is used.
69 B.Used = true;
70 if (auto *SS = dyn_cast<SharedSymbol>(&B))
71 if (!SS->isWeak())
72 SS->getFile<ELFT>().IsNeeded = true;
73
74 if (auto *D = dyn_cast<Defined>(&B)) {
75 auto *RelSec = dyn_cast_or_null<InputSectionBase>(D->Section);
76 if (!RelSec)
96 sym.used = true;
97
98 if (auto *d = dyn_cast<Defined>(&sym)) {
99 auto *relSec = dyn_cast_or_null<InputSectionBase>(d->section);
100 if (!relSec)
77101 return;
78 uint64_t Offset = D->Value;
79 if (D->isSection())
80 Offset += getAddend<ELFT>(Sec, Rel);
81 Fn(RelSec, Offset);
82 return;
83 }
84102
85 if (!B.isDefined())
86 for (InputSectionBase *Sec : CNamedSections.lookup(B.getName()))
87 Fn(Sec, 0);
88}
103 uint64_t offset = d->value;
104 if (d->isSection())
105 offset += getAddend<ELFT>(sec, rel);
89106
90// Calls Fn for each section that Sec refers to via relocations.
91template <class ELFT>
92static void
93forEachSuccessor(InputSection &Sec,
94 llvm::function_ref<void(InputSectionBase *, uint64_t)> Fn) {
95 if (Sec.AreRelocsRela) {
96 for (const typename ELFT::Rela &Rel : Sec.template relas<ELFT>())
97 resolveReloc<ELFT>(Sec, Rel, Fn);
98 } else {
99 for (const typename ELFT::Rel &Rel : Sec.template rels<ELFT>())
100 resolveReloc<ELFT>(Sec, Rel, Fn);
107 if (!isLSDA || !(relSec->flags & SHF_EXECINSTR))
108 enqueue(relSec, offset);
109 return;
101110 }
102111
103 for (InputSectionBase *IS : Sec.DependentSections)
104 Fn(IS, 0);
112 if (auto *ss = dyn_cast<SharedSymbol>(&sym))
113 if (!ss->isWeak())
114 ss->getFile().isNeeded = true;
115
116 for (InputSectionBase *sec : cNamedSections.lookup(sym.getName()))
117 enqueue(sec, 0);
105118}
106119
107120// The .eh_frame section is an unfortunate special case.
......@@ -118,175 +131,203 @@ forEachSuccessor(InputSection &Sec,
118131// A possible improvement would be to fully process .eh_frame in the middle of
119132// the gc pass. With that we would be able to also gc some sections holding
120133// LSDAs and personality functions if we found that they were unused.
121template <class ELFT, class RelTy>
122static void
123scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels,
124 llvm::function_ref<void(InputSectionBase *, uint64_t)> Fn) {
125 const endianness E = ELFT::TargetEndianness;
126
127 for (unsigned I = 0, N = EH.Pieces.size(); I < N; ++I) {
128 EhSectionPiece &Piece = EH.Pieces[I];
129 unsigned FirstRelI = Piece.FirstRelocation;
130 if (FirstRelI == (unsigned)-1)
134template <class ELFT>
135template <class RelTy>
136void MarkLive<ELFT>::scanEhFrameSection(EhInputSection &eh,
137 ArrayRef<RelTy> rels) {
138 for (size_t i = 0, end = eh.pieces.size(); i < end; ++i) {
139 EhSectionPiece &piece = eh.pieces[i];
140 size_t firstRelI = piece.firstRelocation;
141 if (firstRelI == (unsigned)-1)
131142 continue;
132 if (read32<E>(Piece.data().data() + 4) == 0) {
143
144 if (read32<ELFT::TargetEndianness>(piece.data().data() + 4) == 0) {
133145 // This is a CIE, we only need to worry about the first relocation. It is
134146 // known to point to the personality function.
135 resolveReloc<ELFT>(EH, Rels[FirstRelI], Fn);
147 resolveReloc(eh, rels[firstRelI], false);
136148 continue;
137149 }
150
138151 // This is a FDE. The relocations point to the described function or to
139152 // a LSDA. We only need to keep the LSDA alive, so ignore anything that
140153 // points to executable sections.
141 typename ELFT::uint PieceEnd = Piece.InputOff + Piece.Size;
142 for (unsigned I2 = FirstRelI, N2 = Rels.size(); I2 < N2; ++I2) {
143 const RelTy &Rel = Rels[I2];
144 if (Rel.r_offset >= PieceEnd)
145 break;
146 resolveReloc<ELFT>(EH, Rels[I2],
147 [&](InputSectionBase *Sec, uint64_t Offset) {
148 if (Sec && Sec != &InputSection::Discarded &&
149 !(Sec->Flags & SHF_EXECINSTR))
150 Fn(Sec, 0);
151 });
152 }
154 uint64_t pieceEnd = piece.inputOff + piece.size;
155 for (size_t j = firstRelI, end2 = rels.size(); j < end2; ++j)
156 if (rels[j].r_offset < pieceEnd)
157 resolveReloc(eh, rels[j], true);
153158 }
154159}
155160
156template <class ELFT>
157static void
158scanEhFrameSection(EhInputSection &EH,
159 llvm::function_ref<void(InputSectionBase *, uint64_t)> Fn) {
160 if (!EH.NumRelocations)
161 return;
162
163 if (EH.AreRelocsRela)
164 scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Fn);
165 else
166 scanEhFrameSection<ELFT>(EH, EH.template rels<ELFT>(), Fn);
167}
168
169161// Some sections are used directly by the loader, so they should never be
170162// garbage-collected. This function returns true if a given section is such
171163// section.
172template <class ELFT> static bool isReserved(InputSectionBase *Sec) {
173 switch (Sec->Type) {
164static bool isReserved(InputSectionBase *sec) {
165 switch (sec->type) {
174166 case SHT_FINI_ARRAY:
175167 case SHT_INIT_ARRAY:
176168 case SHT_NOTE:
177169 case SHT_PREINIT_ARRAY:
178170 return true;
179171 default:
180 StringRef S = Sec->Name;
181 return S.startswith(".ctors") || S.startswith(".dtors") ||
182 S.startswith(".init") || S.startswith(".fini") ||
183 S.startswith(".jcr");
172 StringRef s = sec->name;
173 return s.startswith(".ctors") || s.startswith(".dtors") ||
174 s.startswith(".init") || s.startswith(".fini") ||
175 s.startswith(".jcr");
184176 }
185177}
186178
187// This is the main function of the garbage collector.
188// Starting from GC-root sections, this function visits all reachable
189// sections to set their "Live" bits.
190template <class ELFT> static void doGcSections() {
191 SmallVector<InputSection *, 256> Q;
192 CNamedSections.clear();
193
194 auto Enqueue = [&](InputSectionBase *Sec, uint64_t Offset) {
195 // Skip over discarded sections. This in theory shouldn't happen, because
196 // the ELF spec doesn't allow a relocation to point to a deduplicated
197 // COMDAT section directly. Unfortunately this happens in practice (e.g.
198 // .eh_frame) so we need to add a check.
199 if (Sec == &InputSection::Discarded)
200 return;
201
179template <class ELFT>
180void MarkLive<ELFT>::enqueue(InputSectionBase *sec, uint64_t offset) {
181 // Skip over discarded sections. This in theory shouldn't happen, because
182 // the ELF spec doesn't allow a relocation to point to a deduplicated
183 // COMDAT section directly. Unfortunately this happens in practice (e.g.
184 // .eh_frame) so we need to add a check.
185 if (sec == &InputSection::discarded)
186 return;
202187
203 // Usually, a whole section is marked as live or dead, but in mergeable
204 // (splittable) sections, each piece of data has independent liveness bit.
205 // So we explicitly tell it which offset is in use.
206 if (auto *MS = dyn_cast<MergeInputSection>(Sec))
207 MS->getSectionPiece(Offset)->Live = true;
188 // Usually, a whole section is marked as live or dead, but in mergeable
189 // (splittable) sections, each piece of data has independent liveness bit.
190 // So we explicitly tell it which offset is in use.
191 if (auto *ms = dyn_cast<MergeInputSection>(sec))
192 ms->getSectionPiece(offset)->live = true;
208193
209 if (Sec->Live)
210 return;
211 Sec->Live = true;
194 // Set Sec->Partition to the meet (i.e. the "minimum") of Partition and
195 // Sec->Partition in the following lattice: 1 < other < 0. If Sec->Partition
196 // doesn't change, we don't need to do anything.
197 if (sec->partition == 1 || sec->partition == partition)
198 return;
199 sec->partition = sec->partition ? 1 : partition;
212200
213 // Add input section to the queue.
214 if (InputSection *S = dyn_cast<InputSection>(Sec))
215 Q.push_back(S);
216 };
201 // Add input section to the queue.
202 if (InputSection *s = dyn_cast<InputSection>(sec))
203 queue.push_back(s);
204}
217205
218 auto MarkSymbol = [&](Symbol *Sym) {
219 if (auto *D = dyn_cast_or_null<Defined>(Sym))
220 if (auto *IS = dyn_cast_or_null<InputSectionBase>(D->Section))
221 Enqueue(IS, D->Value);
222 };
206template <class ELFT> void MarkLive<ELFT>::markSymbol(Symbol *sym) {
207 if (auto *d = dyn_cast_or_null<Defined>(sym))
208 if (auto *isec = dyn_cast_or_null<InputSectionBase>(d->section))
209 enqueue(isec, d->value);
210}
223211
212// This is the main function of the garbage collector.
213// Starting from GC-root sections, this function visits all reachable
214// sections to set their "Live" bits.
215template <class ELFT> void MarkLive<ELFT>::run() {
224216 // Add GC root symbols.
225 MarkSymbol(Symtab->find(Config->Entry));
226 MarkSymbol(Symtab->find(Config->Init));
227 MarkSymbol(Symtab->find(Config->Fini));
228 for (StringRef S : Config->Undefined)
229 MarkSymbol(Symtab->find(S));
230 for (StringRef S : Script->ReferencedSymbols)
231 MarkSymbol(Symtab->find(S));
232217
233218 // Preserve externally-visible symbols if the symbols defined by this
234219 // file can interrupt other ELF file's symbols at runtime.
235 for (Symbol *S : Symtab->getSymbols())
236 if (S->includeInDynsym())
237 MarkSymbol(S);
220 symtab->forEachSymbol([&](Symbol *sym) {
221 if (sym->includeInDynsym() && sym->partition == partition)
222 markSymbol(sym);
223 });
224
225 // If this isn't the main partition, that's all that we need to preserve.
226 if (partition != 1) {
227 mark();
228 return;
229 }
230
231 markSymbol(symtab->find(config->entry));
232 markSymbol(symtab->find(config->init));
233 markSymbol(symtab->find(config->fini));
234 for (StringRef s : config->undefined)
235 markSymbol(symtab->find(s));
236 for (StringRef s : script->referencedSymbols)
237 markSymbol(symtab->find(s));
238238
239239 // Preserve special sections and those which are specified in linker
240240 // script KEEP command.
241 for (InputSectionBase *Sec : InputSections) {
241 for (InputSectionBase *sec : inputSections) {
242242 // Mark .eh_frame sections as live because there are usually no relocations
243243 // that point to .eh_frames. Otherwise, the garbage collector would drop
244244 // all of them. We also want to preserve personality routines and LSDA
245245 // referenced by .eh_frame sections, so we scan them for that here.
246 if (auto *EH = dyn_cast<EhInputSection>(Sec)) {
247 EH->Live = true;
248 scanEhFrameSection<ELFT>(*EH, Enqueue);
246 if (auto *eh = dyn_cast<EhInputSection>(sec)) {
247 eh->markLive();
248 if (!eh->numRelocations)
249 continue;
250
251 if (eh->areRelocsRela)
252 scanEhFrameSection(*eh, eh->template relas<ELFT>());
253 else
254 scanEhFrameSection(*eh, eh->template rels<ELFT>());
249255 }
250256
251 if (Sec->Flags & SHF_LINK_ORDER)
257 if (sec->flags & SHF_LINK_ORDER)
252258 continue;
253259
254 if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec)) {
255 Enqueue(Sec, 0);
256 } else if (isValidCIdentifier(Sec->Name)) {
257 CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);
258 CNamedSections[Saver.save("__stop_" + Sec->Name)].push_back(Sec);
260 if (isReserved(sec) || script->shouldKeep(sec)) {
261 enqueue(sec, 0);
262 } else if (isValidCIdentifier(sec->name)) {
263 cNamedSections[saver.save("__start_" + sec->name)].push_back(sec);
264 cNamedSections[saver.save("__stop_" + sec->name)].push_back(sec);
259265 }
260266 }
261267
268 mark();
269}
270
271template <class ELFT> void MarkLive<ELFT>::mark() {
262272 // Mark all reachable sections.
263 while (!Q.empty())
264 forEachSuccessor<ELFT>(*Q.pop_back_val(), Enqueue);
273 while (!queue.empty()) {
274 InputSectionBase &sec = *queue.pop_back_val();
275
276 if (sec.areRelocsRela) {
277 for (const typename ELFT::Rela &rel : sec.template relas<ELFT>())
278 resolveReloc(sec, rel, false);
279 } else {
280 for (const typename ELFT::Rel &rel : sec.template rels<ELFT>())
281 resolveReloc(sec, rel, false);
282 }
283
284 for (InputSectionBase *isec : sec.dependentSections)
285 enqueue(isec, 0);
286 }
287}
288
289// Move the sections for some symbols to the main partition, specifically ifuncs
290// (because they can result in an IRELATIVE being added to the main partition's
291// GOT, which means that the ifunc must be available when the main partition is
292// loaded) and TLS symbols (because we only know how to correctly process TLS
293// relocations for the main partition).
294template <class ELFT> void MarkLive<ELFT>::moveToMain() {
295 for (InputFile *file : objectFiles)
296 for (Symbol *s : file->getSymbols())
297 if (auto *d = dyn_cast<Defined>(s))
298 if ((d->type == STT_GNU_IFUNC || d->type == STT_TLS) && d->section &&
299 d->section->isLive())
300 markSymbol(s);
301
302 mark();
265303}
266304
267305// Before calling this function, Live bits are off for all
268306// input sections. This function make some or all of them on
269307// so that they are emitted to the output file.
270308template <class ELFT> void elf::markLive() {
271 if (!Config->GcSections) {
272 // If -gc-sections is missing, no sections are removed.
273 for (InputSectionBase *Sec : InputSections)
274 Sec->Live = true;
309 // If -gc-sections is not given, no sections are removed.
310 if (!config->gcSections) {
311 for (InputSectionBase *sec : inputSections)
312 sec->markLive();
275313
276314 // 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;
315 symtab->forEachSymbol([](Symbol *sym) {
316 if (auto *s = dyn_cast<SharedSymbol>(sym))
317 if (s->isUsedInRegularObj && !s->isWeak())
318 s->getFile().isNeeded = true;
319 });
281320 return;
282321 }
283322
323 // Otheriwse, do mark-sweep GC.
324 //
284325 // The -gc-sections option works only for SHF_ALLOC sections
285326 // (sections that are memory-mapped at runtime). So we can
286327 // unconditionally make non-SHF_ALLOC sections alive except
287328 // SHF_LINK_ORDER and SHT_REL/SHT_RELA sections.
288329 //
289 // Usually, SHF_ALLOC sections are not removed even if they are
330 // Usually, non-SHF_ALLOC sections are not removed even if they are
290331 // unreachable through relocations because reachability is not
291332 // a good signal whether they are garbage or not (e.g. there is
292333 // usually no section referring to a .comment section, but we
......@@ -300,22 +341,30 @@ template <class ELFT> void elf::markLive() {
300341 // or -emit-reloc were given. And they are subject of garbage
301342 // collection because, if we remove a text section, we also
302343 // remove its relocation section.
303 for (InputSectionBase *Sec : InputSections) {
304 bool IsAlloc = (Sec->Flags & SHF_ALLOC);
305 bool IsLinkOrder = (Sec->Flags & SHF_LINK_ORDER);
306 bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA);
307 if (!IsAlloc && !IsLinkOrder && !IsRel)
308 Sec->Live = true;
344 for (InputSectionBase *sec : inputSections) {
345 bool isAlloc = (sec->flags & SHF_ALLOC);
346 bool isLinkOrder = (sec->flags & SHF_LINK_ORDER);
347 bool isRel = (sec->type == SHT_REL || sec->type == SHT_RELA);
348
349 if (!isAlloc && !isLinkOrder && !isRel)
350 sec->markLive();
309351 }
310352
311353 // Follow the graph to mark all live sections.
312 doGcSections<ELFT>();
354 for (unsigned curPart = 1; curPart <= partitions.size(); ++curPart)
355 MarkLive<ELFT>(curPart).run();
356
357 // If we have multiple partitions, some sections need to live in the main
358 // partition even if they were allocated to a loadable partition. Move them
359 // there now.
360 if (partitions.size() != 1)
361 MarkLive<ELFT>(1).moveToMain();
313362
314363 // Report garbage-collected sections.
315 if (Config->PrintGcSections)
316 for (InputSectionBase *Sec : InputSections)
317 if (!Sec->Live)
318 message("removing unused section " + toString(Sec));
364 if (config->printGcSections)
365 for (InputSectionBase *sec : inputSections)
366 if (!sec->isLive())
367 message("removing unused section " + toString(sec));
319368}
320369
321370template void elf::markLive<ELF32LE>();
deps/lld/ELF/MarkLive.h+3-4
......@@ -1,9 +1,8 @@
11//===- MarkLive.h -----------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/ELF/Options.td+51-4
......@@ -63,10 +63,18 @@ defm allow_multiple_definition: B<"allow-multiple-definition",
6363 "Allow multiple definitions",
6464 "Do not allow multiple definitions (default)">;
6565
66defm allow_shlib_undefined: B<"allow-shlib-undefined",
67 "Allow unresolved references in shared libraries (default when linking a shared library)",
68 "Do not allow unresolved references in shared libraries (default when linking an executable)">;
69
6670defm apply_dynamic_relocs: B<"apply-dynamic-relocs",
6771 "Apply link-time values for dynamic relocations",
6872 "Do not apply link-time values for dynamic relocations (default)">;
6973
74defm dependent_libraries: B<"dependent-libraries",
75 "Process dependent library specifiers from input files (default)",
76 "Ignore dependent library specifiers from input files">;
77
7078defm as_needed: B<"as-needed",
7179 "Only set DT_NEEDED for shared libraries if used",
7280 "Always set DT_NEEDED for shared libraries (default)">;
......@@ -163,6 +171,13 @@ defm fini: Eq<"fini", "Specify a finalizer function">, MetaVarName<"<symbol>">;
163171def fix_cortex_a53_843419: F<"fix-cortex-a53-843419">,
164172 HelpText<"Apply fixes for AArch64 Cortex-A53 erratum 843419">;
165173
174// This option is intentionally hidden from the user as the implementation
175// is not complete.
176def require_cet: F<"require-cet">;
177
178def force_bti: F<"force-bti">,
179 HelpText<"Force enable AArch64 BTI in PLT, warn if Input ELF file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property">;
180
166181defm format: Eq<"format", "Change the input format of the inputs following this option">,
167182 MetaVarName<"[default,elf,binary]">;
168183
......@@ -214,6 +229,9 @@ defm merge_exidx_entries: B<"merge-exidx-entries",
214229 "Enable merging .ARM.exidx entries (default)",
215230 "Disable merging .ARM.exidx entries">;
216231
232def nmagic: F<"nmagic">, MetaVarName<"<magic>">,
233 HelpText<"Do not page align sections, link against static libraries.">;
234
217235def nostdlib: F<"nostdlib">,
218236 HelpText<"Only search directories specified on the command line">;
219237
......@@ -226,8 +244,11 @@ def no_dynamic_linker: F<"no-dynamic-linker">,
226244def noinhibit_exec: F<"noinhibit-exec">,
227245 HelpText<"Retain the executable output file whenever it is still usable">;
228246
247def no_nmagic: F<"no-nmagic">, MetaVarName<"<magic>">,
248 HelpText<"Page align sections (default)">;
249
229250def no_omagic: F<"no-omagic">, MetaVarName<"<magic>">,
230 HelpText<"Do not set the text data sections to be writable">;
251 HelpText<"Do not set the text data sections to be writable, page align sections (default)">;
231252
232253def no_rosegment: F<"no-rosegment">,
233254 HelpText<"Do not put read-only non-executable sections in their own segment">;
......@@ -242,7 +263,7 @@ def oformat: Separate<["--"], "oformat">, MetaVarName<"<format>">,
242263 HelpText<"Specify the binary format for the output object file">;
243264
244265def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">,
245 HelpText<"Set the text and data sections to be readable and writable">;
266 HelpText<"Set the text and data sections to be readable and writable, do not page align sections, link against static libraries">;
246267
247268defm orphan_handling:
248269 Eq<"orphan-handling", "Control how orphan sections are handled when linker script used">;
......@@ -251,6 +272,9 @@ defm pack_dyn_relocs:
251272 Eq<"pack-dyn-relocs", "Pack dynamic relocations in the given format">,
252273 MetaVarName<"[none,android,relr,android+relr]">;
253274
275def pac_plt: F<"pac-plt">,
276 HelpText<"AArch64 only, use pointer authentication in PLT">;
277
254278defm use_android_relr_tags: B<"use-android-relr-tags",
255279 "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*",
256280 "Use SHT_RELR / DT_RELR* tags (default)">;
......@@ -270,6 +294,9 @@ defm print_icf_sections: B<"print-icf-sections",
270294 "List identical folded sections",
271295 "Do not list identical folded sections (default)">;
272296
297defm print_symbol_order: Eq<"print-symbol-order",
298 "Print a symbol order specified by --call-graph-ordering-file into the speficied file">;
299
273300def pop_state: F<"pop-state">,
274301 HelpText<"Undo the effect of -push-state">;
275302
......@@ -339,6 +366,9 @@ defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;
339366defm undefined: Eq<"undefined", "Force undefined symbol during linking">,
340367 MetaVarName<"<symbol>">;
341368
369defm undefined_glob: Eq<"undefined-glob", "Force undefined symbol during linking">,
370 MetaVarName<"<pattern>">;
371
342372defm unresolved_symbols:
343373 Eq<"unresolved-symbols", "Determine how to handle unresolved symbols">;
344374
......@@ -386,6 +416,9 @@ defm wrap: Eq<"wrap", "Use wrapper functions for symbol">,
386416def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
387417 HelpText<"Linker option extensions">;
388418
419def visual_studio_diagnostics_format : F<"vs-diagnostics">,
420HelpText<"Format diagnostics for Visual Studio compatiblity">;
421
389422// Aliases
390423def: Separate<["-"], "f">, Alias<auxiliary>, HelpText<"Alias for --auxiliary">;
391424def: F<"call_shared">, Alias<Bdynamic>, HelpText<"Alias for --Bdynamic">;
......@@ -407,6 +440,7 @@ def: Separate<["-"], "b">, Alias<format>, HelpText<"Alias for --format">;
407440def: JoinedOrSeparate<["-"], "l">, Alias<library>, HelpText<"Alias for --library">;
408441def: JoinedOrSeparate<["-"], "L">, Alias<library_path>, HelpText<"Alias for --library-path">;
409442def: F<"no-pic-executable">, Alias<no_pie>, HelpText<"Alias for --no-pie">;
443def: Flag<["-"], "n">, Alias<nmagic>, HelpText<"Alias for --nmagic">;
410444def: Flag<["-"], "N">, Alias<omagic>, HelpText<"Alias for --omagic">;
411445def: Joined<["--"], "output=">, Alias<o>, HelpText<"Alias for -o">;
412446def: Separate<["--"], "output">, Alias<o>, HelpText<"Alias for -o">;
......@@ -440,14 +474,22 @@ def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,
440474 HelpText<"Optimization level for LTO">;
441475def lto_partitions: J<"lto-partitions=">,
442476 HelpText<"Number of LTO codegen partitions">;
477def lto_cs_profile_generate: F<"lto-cs-profile-generate">,
478 HelpText<"Perform context senstive PGO instrumentation">;
479def lto_cs_profile_file: J<"lto-cs-profile-file=">,
480 HelpText<"Context sensitive profile file path">;
443481def lto_sample_profile: J<"lto-sample-profile=">,
444482 HelpText<"Sample profile file path">;
445483def disable_verify: F<"disable-verify">;
446484defm mllvm: Eq<"mllvm", "Additional arguments to forward to LLVM's option processing">;
447485def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">,
448486 HelpText<"YAML output file for optimization remarks">;
487def opt_remarks_passes: Separate<["--"], "opt-remarks-passes">,
488 HelpText<"Regex for the passes that need to be serialized to the output file">;
449489def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">,
450490 HelpText<"Include hotness information in the optimization remarks file">;
491def opt_remarks_format: Separate<["--"], "opt-remarks-format">,
492 HelpText<"The format used for serializing remarks (default: YAML)">;
451493defm plugin_opt: Eq<"plugin-opt", "specifies LTO options for compatibility with GNU linkers">;
452494def save_temps: F<"save-temps">;
453495def thinlto_cache_dir: J<"thinlto-cache-dir=">,
......@@ -468,6 +510,10 @@ def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">;
468510def: F<"plugin-opt=new-pass-manager">,
469511 Alias<lto_new_pass_manager>, HelpText<"Alias for -lto-new-pass-manager">;
470512def plugin_opt_obj_path_eq: J<"plugin-opt=obj-path=">;
513def: F<"plugin-opt=cs-profile-generate">,
514 Alias<lto_cs_profile_generate>, HelpText<"Alias for -lto-cs-profile-generate">;
515def: J<"plugin-opt=cs-profile-path=">,
516 Alias<lto_cs_profile_file>, HelpText<"Alias for -lto-cs-profile-file">;
471517def: J<"plugin-opt=sample-profile=">,
472518 Alias<lto_sample_profile>, HelpText<"Alias for -lto-sample-profile">;
473519def: F<"plugin-opt=save-temps">, Alias<save_temps>, HelpText<"Alias for -save-temps">;
......@@ -492,19 +538,20 @@ def plugin_opt_thinlto: J<"plugin-opt=thinlto">;
492538def plugin_opt_slash: J<"plugin-opt=/">;
493539
494540// Options listed below are silently ignored for now for compatibility.
495def: F<"allow-shlib-undefined">;
496541def: F<"detect-odr-violations">;
497542def: Flag<["-"], "g">;
498543def: F<"long-plt">;
499544def: F<"no-add-needed">;
500def: F<"no-allow-shlib-undefined">;
501545def: F<"no-copy-dt-needed-entries">;
502546def: F<"no-ctors-in-init-array">;
503547def: F<"no-keep-memory">;
504548def: F<"no-mmap-output-file">;
549def: F<"no-pipeline-knowledge">;
505550def: F<"no-warn-mismatch">;
551def: Flag<["-"], "p">;
506552def: Separate<["--", "-"], "rpath-link">;
507553def: J<"rpath-link=">;
554def: F<"secure-plt">;
508555def: F<"sort-common">;
509556def: F<"stats">;
510557def: F<"warn-execstack">;
deps/lld/ELF/OutputSections.cpp+213-229
......@@ -1,9 +1,8 @@
11//===- OutputSections.cpp -------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -31,47 +30,46 @@ using namespace llvm::ELF;
3130using namespace lld;
3231using namespace lld::elf;
3332
34uint8_t Out::First;
35PhdrEntry *Out::TlsPhdr;
36OutputSection *Out::ElfHeader;
37OutputSection *Out::ProgramHeaders;
38OutputSection *Out::PreinitArray;
39OutputSection *Out::InitArray;
40OutputSection *Out::FiniArray;
33uint8_t *Out::bufferStart;
34uint8_t Out::first;
35PhdrEntry *Out::tlsPhdr;
36OutputSection *Out::elfHeader;
37OutputSection *Out::programHeaders;
38OutputSection *Out::preinitArray;
39OutputSection *Out::initArray;
40OutputSection *Out::finiArray;
4141
42std::vector<OutputSection *> elf::OutputSections;
42std::vector<OutputSection *> elf::outputSections;
4343
4444uint32_t OutputSection::getPhdrFlags() const {
45 uint32_t Ret = 0;
46 if (Config->EMachine != EM_ARM || !(Flags & SHF_ARM_PURECODE))
47 Ret |= PF_R;
48 if (Flags & SHF_WRITE)
49 Ret |= PF_W;
50 if (Flags & SHF_EXECINSTR)
51 Ret |= PF_X;
52 return Ret;
45 uint32_t ret = 0;
46 if (config->emachine != EM_ARM || !(flags & SHF_ARM_PURECODE))
47 ret |= PF_R;
48 if (flags & SHF_WRITE)
49 ret |= PF_W;
50 if (flags & SHF_EXECINSTR)
51 ret |= PF_X;
52 return ret;
5353}
5454
5555template <class ELFT>
56void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) {
57 Shdr->sh_entsize = Entsize;
58 Shdr->sh_addralign = Alignment;
59 Shdr->sh_type = Type;
60 Shdr->sh_offset = Offset;
61 Shdr->sh_flags = Flags;
62 Shdr->sh_info = Info;
63 Shdr->sh_link = Link;
64 Shdr->sh_addr = Addr;
65 Shdr->sh_size = Size;
66 Shdr->sh_name = ShName;
56void OutputSection::writeHeaderTo(typename ELFT::Shdr *shdr) {
57 shdr->sh_entsize = entsize;
58 shdr->sh_addralign = alignment;
59 shdr->sh_type = type;
60 shdr->sh_offset = offset;
61 shdr->sh_flags = flags;
62 shdr->sh_info = info;
63 shdr->sh_link = link;
64 shdr->sh_addr = addr;
65 shdr->sh_size = size;
66 shdr->sh_name = shName;
6767}
6868
69OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
69OutputSection::OutputSection(StringRef name, uint32_t type, uint64_t flags)
7070 : BaseCommand(OutputSectionKind),
71 SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type,
72 /*Info*/ 0, /*Link*/ 0) {
73 Live = false;
74}
71 SectionBase(Output, name, flags, /*Entsize*/ 0, /*Alignment*/ 1, type,
72 /*Info*/ 0, /*Link*/ 0) {}
7573
7674// We allow sections of types listed below to merged into a
7775// single progbits section. This is typically done by linker
......@@ -79,257 +77,248 @@ OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
7977// to be allocated for nobits sections. Other ones don't require
8078// any special treatment on top of progbits, so there doesn't
8179// seem to be a harm in merging them.
82static bool canMergeToProgbits(unsigned Type) {
83 return Type == SHT_NOBITS || Type == SHT_PROGBITS || Type == SHT_INIT_ARRAY ||
84 Type == SHT_PREINIT_ARRAY || Type == SHT_FINI_ARRAY ||
85 Type == SHT_NOTE;
80static bool canMergeToProgbits(unsigned type) {
81 return type == SHT_NOBITS || type == SHT_PROGBITS || type == SHT_INIT_ARRAY ||
82 type == SHT_PREINIT_ARRAY || type == SHT_FINI_ARRAY ||
83 type == SHT_NOTE;
8684}
8785
88void OutputSection::addSection(InputSection *IS) {
89 if (!Live) {
86void OutputSection::addSection(InputSection *isec) {
87 if (!hasInputSections) {
9088 // If IS is the first section to be added to this section,
91 // initialize Type, Entsize and flags from IS.
92 Live = true;
93 Type = IS->Type;
94 Entsize = IS->Entsize;
95 Flags = IS->Flags;
89 // initialize Partition, Type, Entsize and flags from IS.
90 hasInputSections = true;
91 partition = isec->partition;
92 type = isec->type;
93 entsize = isec->entsize;
94 flags = isec->flags;
9695 } else {
9796 // Otherwise, check if new type or flags are compatible with existing ones.
98 unsigned Mask = SHF_TLS | SHF_LINK_ORDER;
99 if ((Flags & Mask) != (IS->Flags & Mask))
100 error("incompatible section flags for " + Name + "\n>>> " + toString(IS) +
101 ": 0x" + utohexstr(IS->Flags) + "\n>>> output section " + Name +
102 ": 0x" + utohexstr(Flags));
103
104 if (Type != IS->Type) {
105 if (!canMergeToProgbits(Type) || !canMergeToProgbits(IS->Type))
106 error("section type mismatch for " + IS->Name + "\n>>> " +
107 toString(IS) + ": " +
108 getELFSectionTypeName(Config->EMachine, IS->Type) +
109 "\n>>> output section " + Name + ": " +
110 getELFSectionTypeName(Config->EMachine, Type));
111 Type = SHT_PROGBITS;
97 unsigned mask = SHF_TLS | SHF_LINK_ORDER;
98 if ((flags & mask) != (isec->flags & mask))
99 error("incompatible section flags for " + name + "\n>>> " + toString(isec) +
100 ": 0x" + utohexstr(isec->flags) + "\n>>> output section " + name +
101 ": 0x" + utohexstr(flags));
102
103 if (type != isec->type) {
104 if (!canMergeToProgbits(type) || !canMergeToProgbits(isec->type))
105 error("section type mismatch for " + isec->name + "\n>>> " +
106 toString(isec) + ": " +
107 getELFSectionTypeName(config->emachine, isec->type) +
108 "\n>>> output section " + name + ": " +
109 getELFSectionTypeName(config->emachine, type));
110 type = SHT_PROGBITS;
112111 }
113112 }
114113
115 IS->Parent = this;
116 uint64_t AndMask =
117 Config->EMachine == EM_ARM ? (uint64_t)SHF_ARM_PURECODE : 0;
118 uint64_t OrMask = ~AndMask;
119 uint64_t AndFlags = (Flags & IS->Flags) & AndMask;
120 uint64_t OrFlags = (Flags | IS->Flags) & OrMask;
121 Flags = AndFlags | OrFlags;
114 isec->parent = this;
115 uint64_t andMask =
116 config->emachine == EM_ARM ? (uint64_t)SHF_ARM_PURECODE : 0;
117 uint64_t orMask = ~andMask;
118 uint64_t andFlags = (flags & isec->flags) & andMask;
119 uint64_t orFlags = (flags | isec->flags) & orMask;
120 flags = andFlags | orFlags;
122121
123 Alignment = std::max(Alignment, IS->Alignment);
122 alignment = std::max(alignment, isec->alignment);
124123
125124 // If this section contains a table of fixed-size entries, sh_entsize
126125 // holds the element size. If it contains elements of different size we
127126 // set sh_entsize to 0.
128 if (Entsize != IS->Entsize)
129 Entsize = 0;
130
131 if (!IS->Assigned) {
132 IS->Assigned = true;
133 if (SectionCommands.empty() ||
134 !isa<InputSectionDescription>(SectionCommands.back()))
135 SectionCommands.push_back(make<InputSectionDescription>(""));
136 auto *ISD = cast<InputSectionDescription>(SectionCommands.back());
137 ISD->Sections.push_back(IS);
127 if (entsize != isec->entsize)
128 entsize = 0;
129
130 if (!isec->assigned) {
131 isec->assigned = true;
132 if (sectionCommands.empty() ||
133 !isa<InputSectionDescription>(sectionCommands.back()))
134 sectionCommands.push_back(make<InputSectionDescription>(""));
135 auto *isd = cast<InputSectionDescription>(sectionCommands.back());
136 isd->sections.push_back(isec);
138137 }
139138}
140139
141static void sortByOrder(MutableArrayRef<InputSection *> In,
142 llvm::function_ref<int(InputSectionBase *S)> Order) {
143 typedef std::pair<int, InputSection *> Pair;
144 auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
140static void sortByOrder(MutableArrayRef<InputSection *> in,
141 llvm::function_ref<int(InputSectionBase *s)> order) {
142 std::vector<std::pair<int, InputSection *>> v;
143 for (InputSection *s : in)
144 v.push_back({order(s), s});
145 llvm::stable_sort(v, less_first());
145146
146 std::vector<Pair> V;
147 for (InputSection *S : In)
148 V.push_back({Order(S), S});
149 std::stable_sort(V.begin(), V.end(), Comp);
150
151 for (size_t I = 0; I < V.size(); ++I)
152 In[I] = V[I].second;
147 for (size_t i = 0; i < v.size(); ++i)
148 in[i] = v[i].second;
153149}
154150
155151uint64_t elf::getHeaderSize() {
156 if (Config->OFormatBinary)
152 if (config->oFormatBinary)
157153 return 0;
158 return Out::ElfHeader->Size + Out::ProgramHeaders->Size;
154 return Out::elfHeader->size + Out::programHeaders->size;
159155}
160156
161bool OutputSection::classof(const BaseCommand *C) {
162 return C->Kind == OutputSectionKind;
157bool OutputSection::classof(const BaseCommand *c) {
158 return c->kind == OutputSectionKind;
163159}
164160
165void OutputSection::sort(llvm::function_ref<int(InputSectionBase *S)> Order) {
166 assert(Live);
167 for (BaseCommand *B : SectionCommands)
168 if (auto *ISD = dyn_cast<InputSectionDescription>(B))
169 sortByOrder(ISD->Sections, Order);
161void OutputSection::sort(llvm::function_ref<int(InputSectionBase *s)> order) {
162 assert(isLive());
163 for (BaseCommand *b : sectionCommands)
164 if (auto *isd = dyn_cast<InputSectionDescription>(b))
165 sortByOrder(isd->sections, order);
170166}
171167
172168// Fill [Buf, Buf + Size) with Filler.
173169// This is used for linker script "=fillexp" command.
174static void fill(uint8_t *Buf, size_t Size,
175 const std::array<uint8_t, 4> &Filler) {
176 size_t I = 0;
177 for (; I + 4 < Size; I += 4)
178 memcpy(Buf + I, Filler.data(), 4);
179 memcpy(Buf + I, Filler.data(), Size - I);
170static void fill(uint8_t *buf, size_t size,
171 const std::array<uint8_t, 4> &filler) {
172 size_t i = 0;
173 for (; i + 4 < size; i += 4)
174 memcpy(buf + i, filler.data(), 4);
175 memcpy(buf + i, filler.data(), size - i);
180176}
181177
182178// Compress section contents if this section contains debug info.
183179template <class ELFT> void OutputSection::maybeCompress() {
184 typedef typename ELFT::Chdr Elf_Chdr;
180 using Elf_Chdr = typename ELFT::Chdr;
185181
186182 // Compress only DWARF debug sections.
187 if (!Config->CompressDebugSections || (Flags & SHF_ALLOC) ||
188 !Name.startswith(".debug_"))
183 if (!config->compressDebugSections || (flags & SHF_ALLOC) ||
184 !name.startswith(".debug_"))
189185 return;
190186
191187 // Create a section header.
192 ZDebugHeader.resize(sizeof(Elf_Chdr));
193 auto *Hdr = reinterpret_cast<Elf_Chdr *>(ZDebugHeader.data());
194 Hdr->ch_type = ELFCOMPRESS_ZLIB;
195 Hdr->ch_size = Size;
196 Hdr->ch_addralign = Alignment;
188 zDebugHeader.resize(sizeof(Elf_Chdr));
189 auto *hdr = reinterpret_cast<Elf_Chdr *>(zDebugHeader.data());
190 hdr->ch_type = ELFCOMPRESS_ZLIB;
191 hdr->ch_size = size;
192 hdr->ch_addralign = alignment;
197193
198194 // Write section contents to a temporary buffer and compress it.
199 std::vector<uint8_t> Buf(Size);
200 writeTo<ELFT>(Buf.data());
201 if (Error E = zlib::compress(toStringRef(Buf), CompressedData))
202 fatal("compress failed: " + llvm::toString(std::move(E)));
195 std::vector<uint8_t> buf(size);
196 writeTo<ELFT>(buf.data());
197 if (Error e = zlib::compress(toStringRef(buf), compressedData))
198 fatal("compress failed: " + llvm::toString(std::move(e)));
203199
204200 // Update section headers.
205 Size = sizeof(Elf_Chdr) + CompressedData.size();
206 Flags |= SHF_COMPRESSED;
201 size = sizeof(Elf_Chdr) + compressedData.size();
202 flags |= SHF_COMPRESSED;
207203}
208204
209static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
210 if (Size == 1)
211 *Buf = Data;
212 else if (Size == 2)
213 write16(Buf, Data);
214 else if (Size == 4)
215 write32(Buf, Data);
216 else if (Size == 8)
217 write64(Buf, Data);
205static void writeInt(uint8_t *buf, uint64_t data, uint64_t size) {
206 if (size == 1)
207 *buf = data;
208 else if (size == 2)
209 write16(buf, data);
210 else if (size == 4)
211 write32(buf, data);
212 else if (size == 8)
213 write64(buf, data);
218214 else
219215 llvm_unreachable("unsupported Size argument");
220216}
221217
222template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
223 if (Type == SHT_NOBITS)
218template <class ELFT> void OutputSection::writeTo(uint8_t *buf) {
219 if (type == SHT_NOBITS)
224220 return;
225221
226 Loc = Buf;
227
228222 // If -compress-debug-section is specified and if this is a debug seciton,
229223 // we've already compressed section contents. If that's the case,
230224 // just write it down.
231 if (!CompressedData.empty()) {
232 memcpy(Buf, ZDebugHeader.data(), ZDebugHeader.size());
233 memcpy(Buf + ZDebugHeader.size(), CompressedData.data(),
234 CompressedData.size());
225 if (!compressedData.empty()) {
226 memcpy(buf, zDebugHeader.data(), zDebugHeader.size());
227 memcpy(buf + zDebugHeader.size(), compressedData.data(),
228 compressedData.size());
235229 return;
236230 }
237231
238232 // Write leading padding.
239 std::vector<InputSection *> Sections = getInputSections(this);
240 std::array<uint8_t, 4> Filler = getFiller();
241 bool NonZeroFiller = read32(Filler.data()) != 0;
242 if (NonZeroFiller)
243 fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler);
233 std::vector<InputSection *> sections = getInputSections(this);
234 std::array<uint8_t, 4> filler = getFiller();
235 bool nonZeroFiller = read32(filler.data()) != 0;
236 if (nonZeroFiller)
237 fill(buf, sections.empty() ? size : sections[0]->outSecOff, filler);
244238
245 parallelForEachN(0, Sections.size(), [&](size_t I) {
246 InputSection *IS = Sections[I];
247 IS->writeTo<ELFT>(Buf);
239 parallelForEachN(0, sections.size(), [&](size_t i) {
240 InputSection *isec = sections[i];
241 isec->writeTo<ELFT>(buf);
248242
249243 // Fill gaps between sections.
250 if (NonZeroFiller) {
251 uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
252 uint8_t *End;
253 if (I + 1 == Sections.size())
254 End = Buf + Size;
244 if (nonZeroFiller) {
245 uint8_t *start = buf + isec->outSecOff + isec->getSize();
246 uint8_t *end;
247 if (i + 1 == sections.size())
248 end = buf + size;
255249 else
256 End = Buf + Sections[I + 1]->OutSecOff;
257 fill(Start, End - Start, Filler);
250 end = buf + sections[i + 1]->outSecOff;
251 fill(start, end - start, filler);
258252 }
259253 });
260254
261255 // Linker scripts may have BYTE()-family commands with which you
262256 // can write arbitrary bytes to the output. Process them if any.
263 for (BaseCommand *Base : SectionCommands)
264 if (auto *Data = dyn_cast<ByteCommand>(Base))
265 writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
257 for (BaseCommand *base : sectionCommands)
258 if (auto *data = dyn_cast<ByteCommand>(base))
259 writeInt(buf + data->offset, data->expression().getValue(), data->size);
266260}
267261
268template <class ELFT>
269static void finalizeShtGroup(OutputSection *OS,
270 InputSection *Section) {
271 assert(Config->Relocatable);
262static void finalizeShtGroup(OutputSection *os,
263 InputSection *section) {
264 assert(config->relocatable);
272265
273266 // sh_link field for SHT_GROUP sections should contain the section index of
274267 // the symbol table.
275 OS->Link = In.SymTab->getParent()->SectionIndex;
268 os->link = in.symTab->getParent()->sectionIndex;
276269
277270 // sh_info then contain index of an entry in symbol table section which
278271 // provides signature of the section group.
279 ObjFile<ELFT> *Obj = Section->getFile<ELFT>();
280 ArrayRef<Symbol *> Symbols = Obj->getSymbols();
281 OS->Info = In.SymTab->getSymbolIndex(Symbols[Section->Info]);
272 ArrayRef<Symbol *> symbols = section->file->getSymbols();
273 os->info = in.symTab->getSymbolIndex(symbols[section->info]);
282274}
283275
284template <class ELFT> void OutputSection::finalize() {
285 if (Type == SHT_NOBITS)
286 for (BaseCommand *Base : SectionCommands)
287 if (isa<ByteCommand>(Base))
288 Type = SHT_PROGBITS;
289
290 std::vector<InputSection *> V = getInputSections(this);
291 InputSection *First = V.empty() ? nullptr : V[0];
276void OutputSection::finalize() {
277 std::vector<InputSection *> v = getInputSections(this);
278 InputSection *first = v.empty() ? nullptr : v[0];
292279
293 if (Flags & SHF_LINK_ORDER) {
280 if (flags & SHF_LINK_ORDER) {
294281 // We must preserve the link order dependency of sections with the
295282 // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
296283 // need to translate the InputSection sh_link to the OutputSection sh_link,
297284 // all InputSections in the OutputSection have the same dependency.
298 if (auto *D = First->getLinkOrderDep())
299 Link = D->getParent()->SectionIndex;
285 if (auto *ex = dyn_cast<ARMExidxSyntheticSection>(first))
286 link = ex->getLinkOrderDep()->getParent()->sectionIndex;
287 else if (auto *d = first->getLinkOrderDep())
288 link = d->getParent()->sectionIndex;
300289 }
301290
302 if (Type == SHT_GROUP) {
303 finalizeShtGroup<ELFT>(this, First);
291 if (type == SHT_GROUP) {
292 finalizeShtGroup(this, first);
304293 return;
305294 }
306295
307 if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
296 if (!config->copyRelocs || (type != SHT_RELA && type != SHT_REL))
308297 return;
309298
310 if (isa<SyntheticSection>(First))
299 if (isa<SyntheticSection>(first))
311300 return;
312301
313 Link = In.SymTab->getParent()->SectionIndex;
302 link = in.symTab->getParent()->sectionIndex;
314303 // sh_info for SHT_REL[A] sections should contain the section header index of
315304 // the section to which the relocation applies.
316 InputSectionBase *S = First->getRelocatedSection();
317 Info = S->getOutputSection()->SectionIndex;
318 Flags |= SHF_INFO_LINK;
305 InputSectionBase *s = first->getRelocatedSection();
306 info = s->getOutputSection()->sectionIndex;
307 flags |= SHF_INFO_LINK;
319308}
320309
321310// Returns true if S matches /Filename.?\.o$/.
322static bool isCrtBeginEnd(StringRef S, StringRef Filename) {
323 if (!S.endswith(".o"))
311static bool isCrtBeginEnd(StringRef s, StringRef filename) {
312 if (!s.endswith(".o"))
324313 return false;
325 S = S.drop_back(2);
326 if (S.endswith(Filename))
314 s = s.drop_back(2);
315 if (s.endswith(filename))
327316 return true;
328 return !S.empty() && S.drop_back().endswith(Filename);
317 return !s.empty() && s.drop_back().endswith(filename);
329318}
330319
331static bool isCrtbegin(StringRef S) { return isCrtBeginEnd(S, "crtbegin"); }
332static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); }
320static bool isCrtbegin(StringRef s) { return isCrtBeginEnd(s, "crtbegin"); }
321static bool isCrtend(StringRef s) { return isCrtBeginEnd(s, "crtend"); }
333322
334323// .ctors and .dtors are sorted by this priority from highest to lowest.
335324//
......@@ -349,52 +338,52 @@ static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); }
349338// .ctors are duplicate features (and .init_array is newer.) However, there
350339// are too many real-world use cases of .ctors, so we had no choice to
351340// support that with this rather ad-hoc semantics.
352static bool compCtors(const InputSection *A, const InputSection *B) {
353 bool BeginA = isCrtbegin(A->File->getName());
354 bool BeginB = isCrtbegin(B->File->getName());
355 if (BeginA != BeginB)
356 return BeginA;
357 bool EndA = isCrtend(A->File->getName());
358 bool EndB = isCrtend(B->File->getName());
359 if (EndA != EndB)
360 return EndB;
361 StringRef X = A->Name;
362 StringRef Y = B->Name;
363 assert(X.startswith(".ctors") || X.startswith(".dtors"));
364 assert(Y.startswith(".ctors") || Y.startswith(".dtors"));
365 X = X.substr(6);
366 Y = Y.substr(6);
367 return X < Y;
341static bool compCtors(const InputSection *a, const InputSection *b) {
342 bool beginA = isCrtbegin(a->file->getName());
343 bool beginB = isCrtbegin(b->file->getName());
344 if (beginA != beginB)
345 return beginA;
346 bool endA = isCrtend(a->file->getName());
347 bool endB = isCrtend(b->file->getName());
348 if (endA != endB)
349 return endB;
350 StringRef x = a->name;
351 StringRef y = b->name;
352 assert(x.startswith(".ctors") || x.startswith(".dtors"));
353 assert(y.startswith(".ctors") || y.startswith(".dtors"));
354 x = x.substr(6);
355 y = y.substr(6);
356 return x < y;
368357}
369358
370359// Sorts input sections by the special rules for .ctors and .dtors.
371360// Unfortunately, the rules are different from the one for .{init,fini}_array.
372361// Read the comment above.
373362void OutputSection::sortCtorsDtors() {
374 assert(SectionCommands.size() == 1);
375 auto *ISD = cast<InputSectionDescription>(SectionCommands[0]);
376 std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(), compCtors);
363 assert(sectionCommands.size() == 1);
364 auto *isd = cast<InputSectionDescription>(sectionCommands[0]);
365 llvm::stable_sort(isd->sections, compCtors);
377366}
378367
379368// If an input string is in the form of "foo.N" where N is a number,
380369// return N. Otherwise, returns 65536, which is one greater than the
381370// lowest priority.
382int elf::getPriority(StringRef S) {
383 size_t Pos = S.rfind('.');
384 if (Pos == StringRef::npos)
371int elf::getPriority(StringRef s) {
372 size_t pos = s.rfind('.');
373 if (pos == StringRef::npos)
385374 return 65536;
386 int V;
387 if (!to_integer(S.substr(Pos + 1), V, 10))
375 int v;
376 if (!to_integer(s.substr(pos + 1), v, 10))
388377 return 65536;
389 return V;
378 return v;
390379}
391380
392std::vector<InputSection *> elf::getInputSections(OutputSection *OS) {
393 std::vector<InputSection *> Ret;
394 for (BaseCommand *Base : OS->SectionCommands)
395 if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
396 Ret.insert(Ret.end(), ISD->Sections.begin(), ISD->Sections.end());
397 return Ret;
381std::vector<InputSection *> elf::getInputSections(OutputSection *os) {
382 std::vector<InputSection *> ret;
383 for (BaseCommand *base : os->sectionCommands)
384 if (auto *isd = dyn_cast<InputSectionDescription>(base))
385 ret.insert(ret.end(), isd->sections.begin(), isd->sections.end());
386 return ret;
398387}
399388
400389// Sorts input sections by section name suffixes, so that .foo.N comes
......@@ -405,14 +394,14 @@ std::vector<InputSection *> elf::getInputSections(OutputSection *OS) {
405394// For more detail, read the section of the GCC's manual about init_priority.
406395void OutputSection::sortInitFini() {
407396 // Sort sections by priority.
408 sort([](InputSectionBase *S) { return getPriority(S->Name); });
397 sort([](InputSectionBase *s) { return getPriority(s->name); });
409398}
410399
411400std::array<uint8_t, 4> OutputSection::getFiller() {
412 if (Filler)
413 return *Filler;
414 if (Flags & SHF_EXECINSTR)
415 return Target->TrapInstr;
401 if (filler)
402 return *filler;
403 if (flags & SHF_EXECINSTR)
404 return target->trapInstr;
416405 return {0, 0, 0, 0};
417406}
418407
......@@ -430,8 +419,3 @@ template void OutputSection::maybeCompress<ELF32LE>();
430419template void OutputSection::maybeCompress<ELF32BE>();
431420template void OutputSection::maybeCompress<ELF64LE>();
432421template void OutputSection::maybeCompress<ELF64BE>();
433
434template void OutputSection::finalize<ELF32LE>();
435template void OutputSection::finalize<ELF32BE>();
436template void OutputSection::finalize<ELF64LE>();
437template void OutputSection::finalize<ELF64BE>();
deps/lld/ELF/OutputSections.h+58-64
......@@ -1,9 +1,8 @@
11//===- OutputSections.h -----------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -23,17 +22,8 @@ namespace lld {
2322namespace elf {
2423
2524struct PhdrEntry;
26class Symbol;
27struct EhSectionPiece;
28class EhInputSection;
2925class InputSection;
3026class InputSectionBase;
31class MergeInputSection;
32class OutputSection;
33template <class ELFT> class ObjFile;
34template <class ELFT> class SharedFile;
35class SharedSymbol;
36class Defined;
3727
3828// This represents a section in an output file.
3929// It is composed of multiple InputSections.
......@@ -41,19 +31,19 @@ class Defined;
4131// non-overlapping file offsets and VAs.
4232class OutputSection final : public BaseCommand, public SectionBase {
4333public:
44 OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
34 OutputSection(StringRef name, uint32_t type, uint64_t flags);
4535
46 static bool classof(const SectionBase *S) {
47 return S->kind() == SectionBase::Output;
36 static bool classof(const SectionBase *s) {
37 return s->kind() == SectionBase::Output;
4838 }
4939
50 static bool classof(const BaseCommand *C);
40 static bool classof(const BaseCommand *c);
5141
52 uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; }
53 template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
42 uint64_t getLMA() const { return ptLoad ? addr + ptLoad->lmaOffset : addr; }
43 template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *sHdr);
5444
55 uint32_t SectionIndex = UINT32_MAX;
56 unsigned SortRank;
45 uint32_t sectionIndex = UINT32_MAX;
46 unsigned sortRank;
5747
5848 uint32_t getPhdrFlags() const;
5949
......@@ -64,78 +54,82 @@ public:
6454 // section offset we use the following formula: Off = Off_first + VA -
6555 // VA_first, where Off_first and VA_first is file offset and VA of first
6656 // section in PT_LOAD.
67 PhdrEntry *PtLoad = nullptr;
57 PhdrEntry *ptLoad = nullptr;
6858
6959 // Pointer to a relocation section for this section. Usually nullptr because
7060 // we consume relocations, but if --emit-relocs is specified (which is rare),
7161 // it may have a non-null value.
72 OutputSection *RelocationSection = nullptr;
62 OutputSection *relocationSection = nullptr;
7363
7464 // Initially this field is the number of InputSections that have been added to
7565 // the OutputSection so far. Later on, after a call to assignAddresses, it
7666 // corresponds to the Elf_Shdr member.
77 uint64_t Size = 0;
67 uint64_t size = 0;
7868
7969 // The following fields correspond to Elf_Shdr members.
80 uint64_t Offset = 0;
81 uint64_t Addr = 0;
82 uint32_t ShName = 0;
83
84 void addSection(InputSection *IS);
70 uint64_t offset = 0;
71 uint64_t addr = 0;
72 uint32_t shName = 0;
8573
86 // Location in the output buffer.
87 uint8_t *Loc = nullptr;
74 void addSection(InputSection *isec);
8875
8976 // The following members are normally only used in linker scripts.
90 MemoryRegion *MemRegion = nullptr;
91 MemoryRegion *LMARegion = nullptr;
92 Expr AddrExpr;
93 Expr AlignExpr;
94 Expr LMAExpr;
95 Expr SubalignExpr;
96 std::vector<BaseCommand *> SectionCommands;
97 std::vector<StringRef> Phdrs;
98 llvm::Optional<std::array<uint8_t, 4>> Filler;
99 ConstraintKind Constraint = ConstraintKind::NoConstraint;
100 std::string Location;
101 std::string MemoryRegionName;
102 std::string LMARegionName;
103 bool NonAlloc = false;
104 bool Noload = false;
105 bool ExpressionsUseSymbols = false;
106 bool InOverlay = false;
107
108 template <class ELFT> void finalize();
109 template <class ELFT> void writeTo(uint8_t *Buf);
77 MemoryRegion *memRegion = nullptr;
78 MemoryRegion *lmaRegion = nullptr;
79 Expr addrExpr;
80 Expr alignExpr;
81 Expr lmaExpr;
82 Expr subalignExpr;
83 std::vector<BaseCommand *> sectionCommands;
84 std::vector<StringRef> phdrs;
85 llvm::Optional<std::array<uint8_t, 4>> filler;
86 ConstraintKind constraint = ConstraintKind::NoConstraint;
87 std::string location;
88 std::string memoryRegionName;
89 std::string lmaRegionName;
90 bool nonAlloc = false;
91 bool noload = false;
92 bool expressionsUseSymbols = false;
93 bool usedInExpression = false;
94 bool inOverlay = false;
95
96 // Tracks whether the section has ever had an input section added to it, even
97 // if the section was later removed (e.g. because it is a synthetic section
98 // that wasn't needed). This is needed for orphan placement.
99 bool hasInputSections = false;
100
101 void finalize();
102 template <class ELFT> void writeTo(uint8_t *buf);
110103 template <class ELFT> void maybeCompress();
111104
112 void sort(llvm::function_ref<int(InputSectionBase *S)> Order);
105 void sort(llvm::function_ref<int(InputSectionBase *s)> order);
113106 void sortInitFini();
114107 void sortCtorsDtors();
115108
116109private:
117110 // Used for implementation of --compress-debug-sections option.
118 std::vector<uint8_t> ZDebugHeader;
119 llvm::SmallVector<char, 1> CompressedData;
111 std::vector<uint8_t> zDebugHeader;
112 llvm::SmallVector<char, 1> compressedData;
120113
121114 std::array<uint8_t, 4> getFiller();
122115};
123116
124int getPriority(StringRef S);
117int getPriority(StringRef s);
125118
126std::vector<InputSection *> getInputSections(OutputSection* OS);
119std::vector<InputSection *> getInputSections(OutputSection* os);
127120
128121// All output sections that are handled by the linker specially are
129122// globally accessible. Writer initializes them, so don't use them
130123// until Writer is initialized.
131124struct Out {
132 static uint8_t First;
133 static PhdrEntry *TlsPhdr;
134 static OutputSection *ElfHeader;
135 static OutputSection *ProgramHeaders;
136 static OutputSection *PreinitArray;
137 static OutputSection *InitArray;
138 static OutputSection *FiniArray;
125 static uint8_t *bufferStart;
126 static uint8_t first;
127 static PhdrEntry *tlsPhdr;
128 static OutputSection *elfHeader;
129 static OutputSection *programHeaders;
130 static OutputSection *preinitArray;
131 static OutputSection *initArray;
132 static OutputSection *finiArray;
139133};
140134
141135} // namespace elf
......@@ -146,7 +140,7 @@ namespace elf {
146140
147141uint64_t getHeaderSize();
148142
149extern std::vector<OutputSection *> OutputSections;
143extern std::vector<OutputSection *> outputSections;
150144} // namespace elf
151145} // namespace lld
152146
deps/lld/ELF/Relocations.cpp+985-678
......@@ -1,9 +1,8 @@
11//===- Relocations.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -66,11 +65,11 @@ using namespace llvm::support::endian;
6665using namespace lld;
6766using namespace lld::elf;
6867
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;
68static Optional<std::string> getLinkerScriptLocation(const Symbol &sym) {
69 for (BaseCommand *base : script->sectionCommands)
70 if (auto *cmd = dyn_cast<SymbolAssignment>(base))
71 if (cmd->sym == &sym)
72 return cmd->location;
7473 return None;
7574}
7675
......@@ -79,19 +78,51 @@ static Optional<std::string> getLinkerScriptLocation(const Symbol &Sym) {
7978// >>> defined in /home/alice/src/foo.o
8079// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
8180// >>> /home/alice/src/bar.o:(.text+0x1)
82static std::string getLocation(InputSectionBase &S, const Symbol &Sym,
83 uint64_t Off) {
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 ";
91 std::string Src = S.getSrcMsg(Sym, Off);
92 if (!Src.empty())
93 Msg += Src + "\n>>> ";
94 return Msg + S.getObjMsg(Off);
81static std::string getLocation(InputSectionBase &s, const Symbol &sym,
82 uint64_t off) {
83 std::string msg = "\n>>> defined in ";
84 if (sym.file)
85 msg += toString(sym.file);
86 else if (Optional<std::string> loc = getLinkerScriptLocation(sym))
87 msg += *loc;
88
89 msg += "\n>>> referenced by ";
90 std::string src = s.getSrcMsg(sym, off);
91 if (!src.empty())
92 msg += src + "\n>>> ";
93 return msg + s.getObjMsg(off);
94}
95
96namespace {
97// Build a bitmask with one bit set for each RelExpr.
98//
99// Constexpr function arguments can't be used in static asserts, so we
100// use template arguments to build the mask.
101// But function template partial specializations don't exist (needed
102// for base case of the recursion), so we need a dummy struct.
103template <RelExpr... Exprs> struct RelExprMaskBuilder {
104 static inline uint64_t build() { return 0; }
105};
106
107// Specialization for recursive case.
108template <RelExpr Head, RelExpr... Tail>
109struct RelExprMaskBuilder<Head, Tail...> {
110 static inline uint64_t build() {
111 static_assert(0 <= Head && Head < 64,
112 "RelExpr is too large for 64-bit mask!");
113 return (uint64_t(1) << Head) | RelExprMaskBuilder<Tail...>::build();
114 }
115};
116} // namespace
117
118// Return true if `Expr` is one of `Exprs`.
119// There are fewer than 64 RelExpr's, so we can represent any set of
120// RelExpr's as a constant bit mask and test for membership with a
121// couple cheap bitwise operations.
122template <RelExpr... Exprs> bool oneof(RelExpr expr) {
123 assert(0 <= expr && (int)expr < 64 &&
124 "RelExpr is too large for 64-bit mask!");
125 return (uint64_t(1) << expr) & RelExprMaskBuilder<Exprs...>::build();
95126}
96127
97128// This function is similar to the `handleTlsRelocation`. MIPS does not
......@@ -100,204 +131,173 @@ static std::string getLocation(InputSectionBase &S, const Symbol &Sym,
100131// pollute other `handleTlsRelocation` by MIPS `ifs` statements.
101132// Mips has a custom MipsGotSection that handles the writing of GOT entries
102133// without dynamic relocations.
103static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym,
104 InputSectionBase &C, uint64_t Offset,
105 int64_t Addend, RelExpr Expr) {
106 if (Expr == R_MIPS_TLSLD) {
107 In.MipsGot->addTlsIndex(*C.File);
108 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
134static unsigned handleMipsTlsRelocation(RelType type, Symbol &sym,
135 InputSectionBase &c, uint64_t offset,
136 int64_t addend, RelExpr expr) {
137 if (expr == R_MIPS_TLSLD) {
138 in.mipsGot->addTlsIndex(*c.file);
139 c.relocations.push_back({expr, type, offset, addend, &sym});
109140 return 1;
110141 }
111 if (Expr == R_MIPS_TLSGD) {
112 In.MipsGot->addDynTlsEntry(*C.File, Sym);
113 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
142 if (expr == R_MIPS_TLSGD) {
143 in.mipsGot->addDynTlsEntry(*c.file, sym);
144 c.relocations.push_back({expr, type, offset, addend, &sym});
114145 return 1;
115146 }
116147 return 0;
117148}
118149
119// This function is similar to the `handleMipsTlsRelocation`. ARM also does not
120// support any relaxations for TLS relocations. ARM is logically similar to Mips
121// in how it handles TLS, but Mips uses its own custom GOT which handles some
122// of the cases that ARM uses GOT relocations for.
123//
124// We look for TLS global dynamic and local dynamic relocations, these may
125// require the generation of a pair of GOT entries that have associated
126// dynamic relocations. When the results of the dynamic relocations can be
127// resolved at static link time we do so. This is necessary for static linking
128// as there will be no dynamic loader to resolve them at load-time.
150// Notes about General Dynamic and Local Dynamic TLS models below. They may
151// require the generation of a pair of GOT entries that have associated dynamic
152// relocations. The pair of GOT entries created are of the form GOT[e0] Module
153// Index (Used to find pointer to TLS block at run-time) GOT[e1] Offset of
154// symbol in TLS block.
129155//
130// The pair of GOT entries created are of the form
131// GOT[e0] Module Index (Used to find pointer to TLS block at run-time)
132// GOT[e1] Offset of symbol in TLS block
133template <class ELFT>
134static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym,
135 InputSectionBase &C, uint64_t Offset,
136 int64_t Addend, RelExpr Expr) {
137 // The Dynamic TLS Module Index Relocation for a symbol defined in an
138 // executable is always 1. If the target Symbol is not preemptible then
139 // we know the offset into the TLS block at static link time.
140 bool NeedDynId = Sym.IsPreemptible || Config->Shared;
141 bool NeedDynOff = Sym.IsPreemptible;
142
143 auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) {
144 if (Dyn)
145 In.RelaDyn->addReloc(Type, In.Got, Off, Dest);
146 else
147 In.Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest});
148 };
149
150 // Local Dynamic is for access to module local TLS variables, while still
151 // being suitable for being dynamically loaded via dlopen.
152 // GOT[e0] is the module index, with a special value of 0 for the current
153 // module. GOT[e1] is unused. There only needs to be one module index entry.
154 if (Expr == R_TLSLD_PC && In.Got->addTlsIndex()) {
155 AddTlsReloc(In.Got->getTlsIndexOff(), Target->TlsModuleIndexRel,
156 NeedDynId ? nullptr : &Sym, NeedDynId);
157 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
158 return 1;
159 }
160
161 // Global Dynamic is the most general purpose access model. When we know
162 // the module index and offset of symbol in TLS block we can fill these in
163 // using static GOT relocations.
164 if (Expr == R_TLSGD_PC) {
165 if (In.Got->addDynTlsEntry(Sym)) {
166 uint64_t Off = In.Got->getGlobalDynOffset(Sym);
167 AddTlsReloc(Off, Target->TlsModuleIndexRel, &Sym, NeedDynId);
168 AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Sym,
169 NeedDynOff);
170 }
171 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
172 return 1;
173 }
174 return 0;
175}
176
177156// Returns the number of relocations processed.
178157template <class ELFT>
179158static unsigned
180handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C,
181 typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) {
182 if (!Sym.isTls())
159handleTlsRelocation(RelType type, Symbol &sym, InputSectionBase &c,
160 typename ELFT::uint offset, int64_t addend, RelExpr expr) {
161 if (!sym.isTls())
183162 return 0;
184163
185 if (Config->EMachine == EM_ARM)
186 return handleARMTlsRelocation<ELFT>(Type, Sym, C, Offset, Addend, Expr);
187 if (Config->EMachine == EM_MIPS)
188 return handleMipsTlsRelocation(Type, Sym, C, Offset, Addend, Expr);
189
190 if (isRelExprOneOf<R_TLSDESC, R_AARCH64_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) &&
191 Config->Shared) {
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});
164 if (config->emachine == EM_MIPS)
165 return handleMipsTlsRelocation(type, sym, c, offset, addend, expr);
166
167 if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC>(
168 expr) &&
169 config->shared) {
170 if (in.got->addDynTlsEntry(sym)) {
171 uint64_t off = in.got->getGlobalDynOffset(sym);
172 mainPart->relaDyn->addReloc(
173 {target->tlsDescRel, in.got, off, !sym.isPreemptible, &sym, 0});
196174 }
197 if (Expr != R_TLSDESC_CALL)
198 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
175 if (expr != R_TLSDESC_CALL)
176 c.relocations.push_back({expr, type, offset, addend, &sym});
199177 return 1;
200178 }
201179
202 if (isRelExprOneOf<R_TLSLD_GOT, R_TLSLD_GOT_FROM_END, R_TLSLD_PC,
203 R_TLSLD_HINT>(Expr)) {
180 bool canRelax = config->emachine != EM_ARM && config->emachine != EM_RISCV;
181
182 // If we are producing an executable and the symbol is non-preemptable, it
183 // must be defined and the code sequence can be relaxed to use Local-Exec.
184 //
185 // ARM and RISC-V do not support any relaxations for TLS relocations, however,
186 // we can omit the DTPMOD dynamic relocations and resolve them at link time
187 // because them are always 1. This may be necessary for static linking as
188 // DTPMOD may not be expected at load time.
189 bool isLocalInExecutable = !sym.isPreemptible && !config->shared;
190
191 // Local Dynamic is for access to module local TLS variables, while still
192 // being suitable for being dynamically loaded via dlopen. GOT[e0] is the
193 // module index, with a special value of 0 for the current module. GOT[e1] is
194 // unused. There only needs to be one module index entry.
195 if (oneof<R_TLSLD_GOT, R_TLSLD_GOTPLT, R_TLSLD_PC, R_TLSLD_HINT>(
196 expr)) {
204197 // Local-Dynamic relocs can be relaxed to Local-Exec.
205 if (!Config->Shared) {
206 C.Relocations.push_back(
207 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type,
208 Offset, Addend, &Sym});
209 return Target->TlsGdRelaxSkip;
198 if (canRelax && !config->shared) {
199 c.relocations.push_back(
200 {target->adjustRelaxExpr(type, nullptr, R_RELAX_TLS_LD_TO_LE), type,
201 offset, addend, &sym});
202 return target->getTlsGdRelaxSkip(type);
210203 }
211 if (Expr == R_TLSLD_HINT)
204 if (expr == R_TLSLD_HINT)
212205 return 1;
213 if (In.Got->addTlsIndex())
214 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got,
215 In.Got->getTlsIndexOff(), nullptr);
216 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
206 if (in.got->addTlsIndex()) {
207 if (isLocalInExecutable)
208 in.got->relocations.push_back(
209 {R_ADDEND, target->symbolicRel, in.got->getTlsIndexOff(), 1, &sym});
210 else
211 mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, in.got,
212 in.got->getTlsIndexOff(), nullptr);
213 }
214 c.relocations.push_back({expr, type, offset, addend, &sym});
217215 return 1;
218216 }
219217
220218 // Local-Dynamic relocs can be relaxed to Local-Exec.
221 if (Expr == R_ABS && !Config->Shared) {
222 C.Relocations.push_back(
223 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type,
224 Offset, Addend, &Sym});
219 if (expr == R_DTPREL && !config->shared) {
220 c.relocations.push_back(
221 {target->adjustRelaxExpr(type, nullptr, R_RELAX_TLS_LD_TO_LE), type,
222 offset, addend, &sym});
225223 return 1;
226224 }
227225
228226 // Local-Dynamic sequence where offset of tls variable relative to dynamic
229 // thread pointer is stored in the got.
230 if (Expr == R_TLSLD_GOT_OFF) {
231 // Local-Dynamic relocs can be relaxed to local-exec
232 if (!Config->Shared) {
233 C.Relocations.push_back({R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Sym});
234 return 1;
227 // thread pointer is stored in the got. This cannot be relaxed to Local-Exec.
228 if (expr == R_TLSLD_GOT_OFF) {
229 if (!sym.isInGot()) {
230 in.got->addEntry(sym);
231 uint64_t off = sym.getGotOffset();
232 in.got->relocations.push_back(
233 {R_ABS, target->tlsOffsetRel, off, 0, &sym});
235234 }
236 if (!Sym.isInGot()) {
237 In.Got->addEntry(Sym);
238 uint64_t Off = Sym.getGotOffset();
239 In.Got->Relocations.push_back(
240 {R_ABS, Target->TlsOffsetRel, Off, 0, &Sym});
241 }
242 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
235 c.relocations.push_back({expr, type, offset, addend, &sym});
243236 return 1;
244237 }
245238
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)) {
248 if (Config->Shared) {
249 if (In.Got->addDynTlsEntry(Sym)) {
250 uint64_t Off = In.Got->getGlobalDynOffset(Sym);
251 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, In.Got, Off, &Sym);
239 if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
240 R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC>(expr)) {
241 if (!canRelax || config->shared) {
242 if (in.got->addDynTlsEntry(sym)) {
243 uint64_t off = in.got->getGlobalDynOffset(sym);
244
245 if (isLocalInExecutable)
246 // Write one to the GOT slot.
247 in.got->relocations.push_back(
248 {R_ADDEND, target->symbolicRel, off, 1, &sym});
249 else
250 mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, in.got, off, &sym);
252251
253252 // If the symbol is preemptible we need the dynamic linker to write
254253 // the offset too.
255 uint64_t OffsetOff = Off + Config->Wordsize;
256 if (Sym.IsPreemptible)
257 In.RelaDyn->addReloc(Target->TlsOffsetRel, In.Got, OffsetOff, &Sym);
254 uint64_t offsetOff = off + config->wordsize;
255 if (sym.isPreemptible)
256 mainPart->relaDyn->addReloc(target->tlsOffsetRel, in.got, offsetOff,
257 &sym);
258258 else
259 In.Got->Relocations.push_back(
260 {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym});
259 in.got->relocations.push_back(
260 {R_ABS, target->tlsOffsetRel, offsetOff, 0, &sym});
261261 }
262 C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
262 c.relocations.push_back({expr, type, offset, addend, &sym});
263263 return 1;
264264 }
265265
266266 // Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
267267 // depending on the symbol being locally defined or not.
268 if (Sym.IsPreemptible) {
269 C.Relocations.push_back(
270 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
271 Offset, Addend, &Sym});
272 if (!Sym.isInGot()) {
273 In.Got->addEntry(Sym);
274 In.RelaDyn->addReloc(Target->TlsGotRel, In.Got, Sym.getGotOffset(),
275 &Sym);
268 if (sym.isPreemptible) {
269 c.relocations.push_back(
270 {target->adjustRelaxExpr(type, nullptr, R_RELAX_TLS_GD_TO_IE), type,
271 offset, addend, &sym});
272 if (!sym.isInGot()) {
273 in.got->addEntry(sym);
274 mainPart->relaDyn->addReloc(target->tlsGotRel, in.got, sym.getGotOffset(),
275 &sym);
276276 }
277277 } else {
278 C.Relocations.push_back(
279 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
280 Offset, Addend, &Sym});
278 c.relocations.push_back(
279 {target->adjustRelaxExpr(type, nullptr, R_RELAX_TLS_GD_TO_LE), type,
280 offset, addend, &sym});
281281 }
282 return Target->TlsGdRelaxSkip;
282 return target->getTlsGdRelaxSkip(type);
283283 }
284284
285285 // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
286286 // defined.
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) &&
289 !Config->Shared && !Sym.IsPreemptible) {
290 C.Relocations.push_back({R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Sym});
287 if (oneof<R_GOT, R_GOTPLT, R_GOT_PC, R_AARCH64_GOT_PAGE_PC, R_GOT_OFF,
288 R_TLSIE_HINT>(expr) &&
289 canRelax && isLocalInExecutable) {
290 c.relocations.push_back({R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});
291291 return 1;
292292 }
293293
294 if (Expr == R_TLSIE_HINT)
294 if (expr == R_TLSIE_HINT)
295295 return 1;
296296 return 0;
297297}
298298
299static RelType getMipsPairType(RelType Type, bool IsLocal) {
300 switch (Type) {
299static RelType getMipsPairType(RelType type, bool isLocal) {
300 switch (type) {
301301 case R_MIPS_HI16:
302302 return R_MIPS_LO16;
303303 case R_MIPS_GOT16:
......@@ -309,9 +309,9 @@ static RelType getMipsPairType(RelType Type, bool IsLocal) {
309309 // the high 16 bits of the symbol's value. A paired R_MIPS_LO16
310310 // relocations handle low 16 bits of the address. That allows
311311 // to allocate only one GOT entry for every 64 KBytes of local data.
312 return IsLocal ? R_MIPS_LO16 : R_MIPS_NONE;
312 return isLocal ? R_MIPS_LO16 : R_MIPS_NONE;
313313 case R_MICROMIPS_GOT16:
314 return IsLocal ? R_MICROMIPS_LO16 : R_MIPS_NONE;
314 return isLocal ? R_MICROMIPS_LO16 : R_MIPS_NONE;
315315 case R_MIPS_PCHI16:
316316 return R_MIPS_PCLO16;
317317 case R_MICROMIPS_HI16:
......@@ -323,40 +323,38 @@ static RelType getMipsPairType(RelType Type, bool IsLocal) {
323323
324324// True if non-preemptable symbol always has the same value regardless of where
325325// the DSO is loaded.
326static bool isAbsolute(const Symbol &Sym) {
327 if (Sym.isUndefWeak())
326static bool isAbsolute(const Symbol &sym) {
327 if (sym.isUndefWeak())
328328 return true;
329 if (const auto *DR = dyn_cast<Defined>(&Sym))
330 return DR->Section == nullptr; // Absolute symbol.
329 if (const auto *dr = dyn_cast<Defined>(&sym))
330 return dr->section == nullptr; // Absolute symbol.
331331 return false;
332332}
333333
334static bool isAbsoluteValue(const Symbol &Sym) {
335 return isAbsolute(Sym) || Sym.isTls();
334static bool isAbsoluteValue(const Symbol &sym) {
335 return isAbsolute(sym) || sym.isTls();
336336}
337337
338338// Returns true if Expr refers a PLT entry.
339static bool needsPlt(RelExpr 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);
339static bool needsPlt(RelExpr expr) {
340 return oneof<R_PLT_PC, R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PLT>(expr);
342341}
343342
344343// Returns true if Expr refers a GOT entry. Note that this function
345344// returns false for TLS variables even though they need GOT, because
346345// TLS variables uses GOT differently than the regular variables.
347static bool needsGot(RelExpr 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);
346static bool needsGot(RelExpr expr) {
347 return oneof<R_GOT, R_GOT_OFF, R_HEXAGON_GOT, R_MIPS_GOT_LOCAL_PAGE,
348 R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
349 R_GOT_PC, R_GOTPLT>(expr);
352350}
353351
354352// True if this expression is of the form Sym - X, where X is a position in the
355353// file (PC, or GOT for example).
356static bool isRelExpr(RelExpr Expr) {
357 return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL,
358 R_PPC_CALL, R_PPC_CALL_PLT, R_AARCH64_PAGE_PC,
359 R_AARCH64_PLT_PAGE_PC, R_RELAX_GOT_PC>(Expr);
354static bool isRelExpr(RelExpr expr) {
355 return oneof<R_PC, R_GOTREL, R_GOTPLTREL, R_MIPS_GOTREL, R_PPC64_CALL,
356 R_PPC64_RELAX_TOC, R_AARCH64_PAGE_PC, R_RELAX_GOT_PC,
357 R_RISCV_PC_INDIRECT>(expr);
360358}
361359
362360// Returns true if a given relocation can be computed at link-time.
......@@ -368,43 +366,43 @@ static bool isRelExpr(RelExpr Expr) {
368366//
369367// If this function returns false, that means we need to emit a
370368// dynamic relocation so that the relocation will be fixed at load-time.
371static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
372 InputSectionBase &S, uint64_t RelOff) {
369static bool isStaticLinkTimeConstant(RelExpr e, RelType type, const Symbol &sym,
370 InputSectionBase &s, uint64_t relOff) {
373371 // These expressions always compute a constant
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))
372 if (oneof<R_DTPREL, R_GOTPLT, R_GOT_OFF, R_HEXAGON_GOT, R_TLSLD_GOT_OFF,
373 R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF,
374 R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD,
375 R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC,
376 R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC, R_PPC32_PLTREL,
377 R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD, R_TLSDESC_CALL,
378 R_TLSDESC_PC, R_AARCH64_TLSDESC_PAGE, R_HINT, R_TLSLD_HINT,
379 R_TLSIE_HINT>(e))
382380 return true;
383381
384382 // These never do, except if the entire file is position dependent or if
385383 // only the low bits are used.
386 if (E == R_GOT || E == R_GOT_PLT || E == R_PLT || E == R_TLSDESC)
387 return Target->usesOnlyLowPageBits(Type) || !Config->Pic;
384 if (e == R_GOT || e == R_PLT || e == R_TLSDESC)
385 return target->usesOnlyLowPageBits(type) || !config->isPic;
388386
389 if (Sym.IsPreemptible)
387 if (sym.isPreemptible)
390388 return false;
391 if (!Config->Pic)
389 if (!config->isPic)
392390 return true;
393391
394392 // The size of a non preemptible symbol is a constant.
395 if (E == R_SIZE)
393 if (e == R_SIZE)
396394 return true;
397395
398396 // For the target and the relocation, we want to know if they are
399397 // absolute or relative.
400 bool AbsVal = isAbsoluteValue(Sym);
401 bool RelE = isRelExpr(E);
402 if (AbsVal && !RelE)
398 bool absVal = isAbsoluteValue(sym);
399 bool relE = isRelExpr(e);
400 if (absVal && !relE)
403401 return true;
404 if (!AbsVal && RelE)
402 if (!absVal && relE)
405403 return true;
406 if (!AbsVal && !RelE)
407 return Target->usesOnlyLowPageBits(Type);
404 if (!absVal && !relE)
405 return target->usesOnlyLowPageBits(type);
408406
409407 // Relative relocation to an absolute value. This is normally unrepresentable,
410408 // but if the relocation refers to a weak undefined symbol, we allow it to
......@@ -414,59 +412,60 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
414412 // Another special case is MIPS _gp_disp symbol which represents offset
415413 // between start of a function and '_gp' value and defined as absolute just
416414 // to simplify the code.
417 assert(AbsVal && RelE);
418 if (Sym.isUndefWeak())
415 assert(absVal && relE);
416 if (sym.isUndefWeak())
419417 return true;
420418
421 error("relocation " + toString(Type) + " cannot refer to absolute symbol: " +
422 toString(Sym) + getLocation(S, Sym, RelOff));
419 // We set the final symbols values for linker script defined symbols later.
420 // They always can be computed as a link time constant.
421 if (sym.scriptDefined)
422 return true;
423
424 error("relocation " + toString(type) + " cannot refer to absolute symbol: " +
425 toString(sym) + getLocation(s, sym, relOff));
423426 return true;
424427}
425428
426static RelExpr toPlt(RelExpr Expr) {
427 switch (Expr) {
428 case R_PPC_CALL:
429 return R_PPC_CALL_PLT;
429static RelExpr toPlt(RelExpr expr) {
430 switch (expr) {
431 case R_PPC64_CALL:
432 return R_PPC64_CALL_PLT;
430433 case R_PC:
431434 return R_PLT_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;
436435 case R_ABS:
437436 return R_PLT;
438 case R_GOT:
439 return R_GOT_PLT;
440437 default:
441 return Expr;
438 return expr;
442439 }
443440}
444441
445static RelExpr fromPlt(RelExpr Expr) {
442static RelExpr fromPlt(RelExpr expr) {
446443 // We decided not to use a plt. Optimize a reference to the plt to a
447444 // reference to the symbol itself.
448 switch (Expr) {
445 switch (expr) {
449446 case R_PLT_PC:
447 case R_PPC32_PLTREL:
450448 return R_PC;
451 case R_PPC_CALL_PLT:
452 return R_PPC_CALL;
449 case R_PPC64_CALL_PLT:
450 return R_PPC64_CALL;
453451 case R_PLT:
454452 return R_ABS;
455453 default:
456 return Expr;
454 return expr;
457455 }
458456}
459457
460458// Returns true if a given shared symbol is in a read-only segment in a DSO.
461template <class ELFT> static bool isReadOnly(SharedSymbol &SS) {
462 typedef typename ELFT::Phdr Elf_Phdr;
459template <class ELFT> static bool isReadOnly(SharedSymbol &ss) {
460 using Elf_Phdr = typename ELFT::Phdr;
463461
464462 // Determine if the symbol is read-only by scanning the DSO's program headers.
465 const SharedFile<ELFT> &File = SS.getFile<ELFT>();
466 for (const Elf_Phdr &Phdr : check(File.getObj().program_headers()))
467 if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
468 !(Phdr.p_flags & ELF::PF_W) && SS.Value >= Phdr.p_vaddr &&
469 SS.Value < Phdr.p_vaddr + Phdr.p_memsz)
463 const SharedFile &file = ss.getFile();
464 for (const Elf_Phdr &phdr :
465 check(file.template getObj<ELFT>().program_headers()))
466 if ((phdr.p_type == ELF::PT_LOAD || phdr.p_type == ELF::PT_GNU_RELRO) &&
467 !(phdr.p_flags & ELF::PF_W) && ss.value >= phdr.p_vaddr &&
468 ss.value < phdr.p_vaddr + phdr.p_memsz)
470469 return true;
471470 return false;
472471}
......@@ -477,22 +476,22 @@ template <class ELFT> static bool isReadOnly(SharedSymbol &SS) {
477476// them are copied by a copy relocation, all of them need to be copied.
478477// Otherwise, they would refer to different places at runtime.
479478template <class ELFT>
480static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
481 typedef typename ELFT::Sym Elf_Sym;
479static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &ss) {
480 using Elf_Sym = typename ELFT::Sym;
482481
483 SharedFile<ELFT> &File = SS.getFile<ELFT>();
482 SharedFile &file = ss.getFile();
484483
485 SmallSet<SharedSymbol *, 4> Ret;
486 for (const Elf_Sym &S : File.getGlobalELFSyms()) {
487 if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS ||
488 S.getType() == STT_TLS || S.st_value != SS.Value)
484 SmallSet<SharedSymbol *, 4> ret;
485 for (const Elf_Sym &s : file.template getGlobalELFSyms<ELFT>()) {
486 if (s.st_shndx == SHN_UNDEF || s.st_shndx == SHN_ABS ||
487 s.getType() == STT_TLS || s.st_value != ss.value)
489488 continue;
490 StringRef Name = check(S.getName(File.getStringTable()));
491 Symbol *Sym = Symtab->find(Name);
492 if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym))
493 Ret.insert(Alias);
489 StringRef name = check(s.getName(file.getStringTable()));
490 Symbol *sym = symtab->find(name);
491 if (auto *alias = dyn_cast_or_null<SharedSymbol>(sym))
492 ret.insert(alias);
494493 }
495 return Ret;
494 return ret;
496495}
497496
498497// When a symbol is copy relocated or we create a canonical plt entry, it is
......@@ -500,19 +499,21 @@ static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
500499// in .bss and in the case of a canonical plt entry it is in .plt. This function
501500// replaces the existing symbol with a Defined pointing to the appropriate
502501// location.
503static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
504 uint64_t Size) {
505 Symbol Old = Sym;
506 replaceSymbol<Defined>(&Sym, Sym.File, Sym.getName(), Sym.Binding,
507 Sym.StOther, Sym.Type, Value, Size, Sec);
508 Sym.PltIndex = Old.PltIndex;
509 Sym.GotIndex = Old.GotIndex;
510 Sym.VerdefIndex = Old.VerdefIndex;
511 Sym.PPC64BranchltIndex = Old.PPC64BranchltIndex;
512 Sym.IsPreemptible = true;
513 Sym.ExportDynamic = true;
514 Sym.IsUsedInRegularObj = true;
515 Sym.Used = true;
502static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
503 uint64_t size) {
504 Symbol old = sym;
505
506 sym.replace(Defined{sym.file, sym.getName(), sym.binding, sym.stOther,
507 sym.type, value, size, sec});
508
509 sym.pltIndex = old.pltIndex;
510 sym.gotIndex = old.gotIndex;
511 sym.verdefIndex = old.verdefIndex;
512 sym.ppc64BranchltIndex = old.ppc64BranchltIndex;
513 sym.isPreemptible = true;
514 sym.exportDynamic = true;
515 sym.isUsedInRegularObj = true;
516 sym.used = true;
516517}
517518
518519// Reserve space in .bss or .bss.rel.ro for copy relocation.
......@@ -557,29 +558,29 @@ static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
557558// to the variable in .bss. This kind of issue is sometimes very hard to
558559// debug. What's a solution? Instead of exporting a varaible V from a DSO,
559560// define an accessor getV().
560template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
561template <class ELFT> static void addCopyRelSymbol(SharedSymbol &ss) {
561562 // Copy relocation against zero-sized symbol doesn't make sense.
562 uint64_t SymSize = SS.getSize();
563 if (SymSize == 0 || SS.Alignment == 0)
564 fatal("cannot create a copy relocation for symbol " + toString(SS));
563 uint64_t symSize = ss.getSize();
564 if (symSize == 0 || ss.alignment == 0)
565 fatal("cannot create a copy relocation for symbol " + toString(ss));
565566
566567 // See if this symbol is in a read-only segment. If so, preserve the symbol's
567568 // memory protection by reserving space in the .bss.rel.ro section.
568 bool IsReadOnly = isReadOnly<ELFT>(SS);
569 BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss",
570 SymSize, SS.Alignment);
571 if (IsReadOnly)
572 In.BssRelRo->getParent()->addSection(Sec);
569 bool isRO = isReadOnly<ELFT>(ss);
570 BssSection *sec =
571 make<BssSection>(isRO ? ".bss.rel.ro" : ".bss", symSize, ss.alignment);
572 if (isRO)
573 in.bssRelRo->getParent()->addSection(sec);
573574 else
574 In.Bss->getParent()->addSection(Sec);
575 in.bss->getParent()->addSection(sec);
575576
576577 // Look through the DSO's dynamic symbol table for aliases and create a
577578 // dynamic symbol for each one. This causes the copy relocation to correctly
578579 // interpose any aliases.
579 for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS))
580 replaceWithDefined(*Sym, Sec, 0, Sym->Size);
580 for (SharedSymbol *sym : getSymbolsAt<ELFT>(ss))
581 replaceWithDefined(*sym, sec, 0, sym->size);
581582
582 In.RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS);
583 mainPart->relaDyn->addReloc(target->copyRel, sec, 0, &ss);
583584}
584585
585586// MIPS has an odd notion of "paired" relocations to calculate addends.
......@@ -587,34 +588,34 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
587588// R_MIPS_LO16 relocation after that, and an addend is calculated using
588589// the two relocations.
589590template <class ELFT, class RelTy>
590static int64_t computeMipsAddend(const RelTy &Rel, const RelTy *End,
591 InputSectionBase &Sec, RelExpr Expr,
592 bool IsLocal) {
593 if (Expr == R_MIPS_GOTREL && IsLocal)
594 return Sec.getFile<ELFT>()->MipsGp0;
591static int64_t computeMipsAddend(const RelTy &rel, const RelTy *end,
592 InputSectionBase &sec, RelExpr expr,
593 bool isLocal) {
594 if (expr == R_MIPS_GOTREL && isLocal)
595 return sec.getFile<ELFT>()->mipsGp0;
595596
596597 // The ABI says that the paired relocation is used only for REL.
597598 // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
598599 if (RelTy::IsRela)
599600 return 0;
600601
601 RelType Type = Rel.getType(Config->IsMips64EL);
602 uint32_t PairTy = getMipsPairType(Type, IsLocal);
603 if (PairTy == R_MIPS_NONE)
602 RelType type = rel.getType(config->isMips64EL);
603 uint32_t pairTy = getMipsPairType(type, isLocal);
604 if (pairTy == R_MIPS_NONE)
604605 return 0;
605606
606 const uint8_t *Buf = Sec.data().data();
607 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
607 const uint8_t *buf = sec.data().data();
608 uint32_t symIndex = rel.getSymbol(config->isMips64EL);
608609
609610 // To make things worse, paired relocations might not be contiguous in
610611 // the relocation table, so we need to do linear search. *sigh*
611 for (const RelTy *RI = &Rel; RI != End; ++RI)
612 if (RI->getType(Config->IsMips64EL) == PairTy &&
613 RI->getSymbol(Config->IsMips64EL) == SymIndex)
614 return Target->getImplicitAddend(Buf + RI->r_offset, PairTy);
612 for (const RelTy *ri = &rel; ri != end; ++ri)
613 if (ri->getType(config->isMips64EL) == pairTy &&
614 ri->getSymbol(config->isMips64EL) == symIndex)
615 return target->getImplicitAddend(buf + ri->r_offset, pairTy);
615616
616 warn("can't find matching " + toString(PairTy) + " relocation for " +
617 toString(Type));
617 warn("can't find matching " + toString(pairTy) + " relocation for " +
618 toString(type));
618619 return 0;
619620}
620621
......@@ -622,59 +623,174 @@ static int64_t computeMipsAddend(const RelTy &Rel, const RelTy *End,
622623// is in a relocation itself. If it is REL, we need to read it from an
623624// input section.
624625template <class ELFT, class RelTy>
625static int64_t computeAddend(const RelTy &Rel, const RelTy *End,
626 InputSectionBase &Sec, RelExpr Expr,
627 bool IsLocal) {
628 int64_t Addend;
629 RelType Type = Rel.getType(Config->IsMips64EL);
626static int64_t computeAddend(const RelTy &rel, const RelTy *end,
627 InputSectionBase &sec, RelExpr expr,
628 bool isLocal) {
629 int64_t addend;
630 RelType type = rel.getType(config->isMips64EL);
630631
631632 if (RelTy::IsRela) {
632 Addend = getAddend<ELFT>(Rel);
633 addend = getAddend<ELFT>(rel);
633634 } else {
634 const uint8_t *Buf = Sec.data().data();
635 Addend = Target->getImplicitAddend(Buf + Rel.r_offset, Type);
635 const uint8_t *buf = sec.data().data();
636 addend = target->getImplicitAddend(buf + rel.r_offset, type);
636637 }
637638
638 if (Config->EMachine == EM_PPC64 && Config->Pic && Type == R_PPC64_TOC)
639 Addend += getPPC64TocBase();
640 if (Config->EMachine == EM_MIPS)
641 Addend += computeMipsAddend<ELFT>(Rel, End, Sec, Expr, IsLocal);
639 if (config->emachine == EM_PPC64 && config->isPic && type == R_PPC64_TOC)
640 addend += getPPC64TocBase();
641 if (config->emachine == EM_MIPS)
642 addend += computeMipsAddend<ELFT>(rel, end, sec, expr, isLocal);
642643
643 return Addend;
644 return addend;
644645}
645646
646// Report an undefined symbol if necessary.
647// Returns true if this function printed out an error message.
648static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
649 uint64_t Offset) {
650 if (Sym.isLocal() || !Sym.isUndefined() || Sym.isWeak())
651 return false;
647// Custom error message if Sym is defined in a discarded section.
648template <class ELFT>
649static std::string maybeReportDiscarded(Undefined &sym) {
650 auto *file = dyn_cast_or_null<ObjFile<ELFT>>(sym.file);
651 if (!file || !sym.discardedSecIdx ||
652 file->getSections()[sym.discardedSecIdx] != &InputSection::discarded)
653 return "";
654 ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
655 CHECK(file->getObj().sections(), file);
656
657 std::string msg;
658 if (sym.type == ELF::STT_SECTION) {
659 msg = "relocation refers to a discarded section: ";
660 msg += CHECK(
661 file->getObj().getSectionName(&objSections[sym.discardedSecIdx]), file);
662 } else {
663 msg = "relocation refers to a symbol in a discarded section: " +
664 toString(sym);
665 }
666 msg += "\n>>> defined in " + toString(file);
667
668 Elf_Shdr_Impl<ELFT> elfSec = objSections[sym.discardedSecIdx - 1];
669 if (elfSec.sh_type != SHT_GROUP)
670 return msg;
671
672 // If the discarded section is a COMDAT.
673 StringRef signature = file->getShtGroupSignature(objSections, elfSec);
674 if (const InputFile *prevailing =
675 symtab->comdatGroups.lookup(CachedHashStringRef(signature)))
676 msg += "\n>>> section group signature: " + signature.str() +
677 "\n>>> prevailing definition is in " + toString(prevailing);
678 return msg;
679}
652680
653 bool CanBeExternal =
654 Sym.computeBinding() != STB_LOCAL && Sym.Visibility == STV_DEFAULT;
655 if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal)
656 return false;
681// Undefined diagnostics are collected in a vector and emitted once all of
682// them are known, so that some postprocessing on the list of undefined symbols
683// can happen before lld emits diagnostics.
684struct UndefinedDiag {
685 Symbol *sym;
686 struct Loc {
687 InputSectionBase *sec;
688 uint64_t offset;
689 };
690 std::vector<Loc> locs;
691 bool isWarning;
692};
693
694static std::vector<UndefinedDiag> undefs;
695
696template <class ELFT>
697static void reportUndefinedSymbol(const UndefinedDiag &undef) {
698 Symbol &sym = *undef.sym;
699
700 auto visibility = [&]() -> std::string {
701 switch (sym.visibility) {
702 case STV_INTERNAL:
703 return "internal ";
704 case STV_HIDDEN:
705 return "hidden ";
706 case STV_PROTECTED:
707 return "protected ";
708 default:
709 return "";
710 }
711 };
657712
658 std::string Msg =
659 "undefined symbol: " + toString(Sym) + "\n>>> referenced by ";
713 std::string msg = maybeReportDiscarded<ELFT>(cast<Undefined>(sym));
714 if (msg.empty())
715 msg = "undefined " + visibility() + "symbol: " + toString(sym);
716
717 const size_t maxUndefReferences = 10;
718 size_t i = 0;
719 for (UndefinedDiag::Loc l : undef.locs) {
720 if (i >= maxUndefReferences)
721 break;
722 InputSectionBase &sec = *l.sec;
723 uint64_t offset = l.offset;
724
725 msg += "\n>>> referenced by ";
726 std::string src = sec.getSrcMsg(sym, offset);
727 if (!src.empty())
728 msg += src + "\n>>> ";
729 msg += sec.getObjMsg(offset);
730 i++;
731 }
660732
661 std::string Src = Sec.getSrcMsg(Sym, Offset);
662 if (!Src.empty())
663 Msg += Src + "\n>>> ";
664 Msg += Sec.getObjMsg(Offset);
733 if (i < undef.locs.size())
734 msg += ("\n>>> referenced " + Twine(undef.locs.size() - i) + " more times")
735 .str();
665736
666 if (Sym.getName().startswith("_ZTV"))
667 Msg += "\nthe vtable symbol may be undefined because the class is missing "
737 if (sym.getName().startswith("_ZTV"))
738 msg += "\nthe vtable symbol may be undefined because the class is missing "
668739 "its key function (see https://lld.llvm.org/missingkeyfunction)";
669740
670 if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) ||
671 Config->NoinhibitExec) {
672 warn(Msg);
673 return false;
741 if (undef.isWarning)
742 warn(msg);
743 else
744 error(msg);
745}
746
747template <class ELFT> void elf::reportUndefinedSymbols() {
748 // Find the first "undefined symbol" diagnostic for each diagnostic, and
749 // collect all "referenced from" lines at the first diagnostic.
750 DenseMap<Symbol *, UndefinedDiag *> firstRef;
751 for (UndefinedDiag &undef : undefs) {
752 assert(undef.locs.size() == 1);
753 if (UndefinedDiag *canon = firstRef.lookup(undef.sym)) {
754 canon->locs.push_back(undef.locs[0]);
755 undef.locs.clear();
756 } else
757 firstRef[undef.sym] = &undef;
674758 }
675759
676 error(Msg);
677 return true;
760 for (const UndefinedDiag &undef : undefs) {
761 if (!undef.locs.empty())
762 reportUndefinedSymbol<ELFT>(undef);
763 }
764 undefs.clear();
765}
766
767// Report an undefined symbol if necessary.
768// Returns true if the undefined symbol will produce an error message.
769template <class ELFT>
770static bool maybeReportUndefined(Symbol &sym, InputSectionBase &sec,
771 uint64_t offset) {
772 if (!sym.isUndefined() || sym.isWeak())
773 return false;
774
775 bool canBeExternal = !sym.isLocal() && sym.computeBinding() != STB_LOCAL &&
776 sym.visibility == STV_DEFAULT;
777 if (config->unresolvedSymbols == UnresolvedPolicy::Ignore && canBeExternal)
778 return false;
779
780 // clang (as of 2019-06-12) / gcc (as of 8.2.1) PPC64 may emit a .rela.toc
781 // which references a switch table in a discarded .rodata/.text section. The
782 // .toc and the .rela.toc are incorrectly not placed in the comdat. The ELF
783 // spec says references from outside the group to a STB_LOCAL symbol are not
784 // allowed. Work around the bug.
785 if (config->emachine == EM_PPC64 &&
786 cast<Undefined>(sym).discardedSecIdx != 0 && sec.name == ".toc")
787 return false;
788
789 bool isWarning =
790 (config->unresolvedSymbols == UnresolvedPolicy::Warn && canBeExternal) ||
791 config->noinhibitExec;
792 undefs.push_back({&sym, {{&sec, offset}}, isWarning});
793 return !isWarning;
678794}
679795
680796// MIPS N32 ABI treats series of successive relocations with the same offset
......@@ -682,14 +798,14 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec,
682798// packs all relocations into the single relocation record. Here we emulate
683799// this for the N32 ABI. Iterate over relocation with the same offset and put
684800// theirs types into the single bit-set.
685template <class RelTy> static RelType getMipsN32RelType(RelTy *&Rel, RelTy *End) {
686 RelType Type = 0;
687 uint64_t Offset = Rel->r_offset;
688
689 int N = 0;
690 while (Rel != End && Rel->r_offset == Offset)
691 Type |= (Rel++)->getType(Config->IsMips64EL) << (8 * N++);
692 return Type;
801template <class RelTy> static RelType getMipsN32RelType(RelTy *&rel, RelTy *end) {
802 RelType type = 0;
803 uint64_t offset = rel->r_offset;
804
805 int n = 0;
806 while (rel != end && rel->r_offset == offset)
807 type |= (rel++)->getType(config->isMips64EL) << (8 * n++);
808 return type;
693809}
694810
695811// .eh_frame sections are mergeable input sections, so their input
......@@ -706,77 +822,72 @@ template <class RelTy> static RelType getMipsN32RelType(RelTy *&Rel, RelTy *End)
706822namespace {
707823class OffsetGetter {
708824public:
709 explicit OffsetGetter(InputSectionBase &Sec) {
710 if (auto *Eh = dyn_cast<EhInputSection>(&Sec))
711 Pieces = Eh->Pieces;
825 explicit OffsetGetter(InputSectionBase &sec) {
826 if (auto *eh = dyn_cast<EhInputSection>(&sec))
827 pieces = eh->pieces;
712828 }
713829
714830 // Translates offsets in input sections to offsets in output sections.
715831 // Given offset must increase monotonically. We assume that Piece is
716 // sorted by InputOff.
717 uint64_t get(uint64_t Off) {
718 if (Pieces.empty())
719 return Off;
720
721 while (I != Pieces.size() && Pieces[I].InputOff + Pieces[I].Size <= Off)
722 ++I;
723 if (I == Pieces.size())
832 // sorted by inputOff.
833 uint64_t get(uint64_t off) {
834 if (pieces.empty())
835 return off;
836
837 while (i != pieces.size() && pieces[i].inputOff + pieces[i].size <= off)
838 ++i;
839 if (i == pieces.size())
724840 fatal(".eh_frame: relocation is not in any piece");
725841
726842 // Pieces must be contiguous, so there must be no holes in between.
727 assert(Pieces[I].InputOff <= Off && "Relocation not in any piece");
843 assert(pieces[i].inputOff <= off && "Relocation not in any piece");
728844
729845 // Offset -1 means that the piece is dead (i.e. garbage collected).
730 if (Pieces[I].OutputOff == -1)
846 if (pieces[i].outputOff == -1)
731847 return -1;
732 return Pieces[I].OutputOff + Off - Pieces[I].InputOff;
848 return pieces[i].outputOff + off - pieces[i].inputOff;
733849 }
734850
735851private:
736 ArrayRef<EhSectionPiece> Pieces;
737 size_t I = 0;
852 ArrayRef<EhSectionPiece> pieces;
853 size_t i = 0;
738854};
739855} // namespace
740856
741static void addRelativeReloc(InputSectionBase *IS, uint64_t OffsetInSec,
742 Symbol *Sym, int64_t Addend, RelExpr Expr,
743 RelType Type) {
744 // Add a relative relocation. If RelrDyn section is enabled, and the
857static void addRelativeReloc(InputSectionBase *isec, uint64_t offsetInSec,
858 Symbol *sym, int64_t addend, RelExpr expr,
859 RelType type) {
860 Partition &part = isec->getPartition();
861
862 // Add a relative relocation. If relrDyn section is enabled, and the
745863 // relocation offset is guaranteed to be even, add the relocation to
746 // the RelrDyn section, otherwise add it to the RelaDyn section.
747 // RelrDyn sections don't support odd offsets. Also, RelrDyn sections
864 // the relrDyn section, otherwise add it to the relaDyn section.
865 // relrDyn sections don't support odd offsets. Also, relrDyn sections
748866 // don't store the addend values, so we must write it to the relocated
749867 // address.
750 if (In.RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) {
751 IS->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
752 In.RelrDyn->Relocs.push_back({IS, OffsetInSec});
868 if (part.relrDyn && isec->alignment >= 2 && offsetInSec % 2 == 0) {
869 isec->relocations.push_back({expr, type, offsetInSec, addend, sym});
870 part.relrDyn->relocs.push_back({isec, offsetInSec});
753871 return;
754872 }
755 In.RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend, Expr,
756 Type);
873 part.relaDyn->addReloc(target->relativeRel, isec, offsetInSec, sym, addend,
874 expr, type);
757875}
758876
759877template <class ELFT, class GotPltSection>
760static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt,
761 RelocationBaseSection *Rel, RelType Type, Symbol &Sym) {
762 Plt->addEntry<ELFT>(Sym);
763 GotPlt->addEntry(Sym);
764 Rel->addReloc(
765 {Type, GotPlt, Sym.getGotPltOffset(), !Sym.IsPreemptible, &Sym, 0});
878static void addPltEntry(PltSection *plt, GotPltSection *gotPlt,
879 RelocationBaseSection *rel, RelType type, Symbol &sym) {
880 plt->addEntry<ELFT>(sym);
881 gotPlt->addEntry(sym);
882 rel->addReloc(
883 {type, gotPlt, sym.getGotPltOffset(), !sym.isPreemptible, &sym, 0});
766884}
767885
768template <class ELFT> static void addGotEntry(Symbol &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;
886static void addGotEntry(Symbol &sym) {
887 in.got->addEntry(sym);
778888
779 uint64_t Off = Sym.getGotOffset();
889 RelExpr expr = sym.isTls() ? R_TLS : R_ABS;
890 uint64_t off = sym.getGotOffset();
780891
781892 // If a GOT slot value can be calculated at link-time, which is now,
782893 // we can just fill that out.
......@@ -785,42 +896,42 @@ template <class ELFT> static void addGotEntry(Symbol &Sym) {
785896 // add a static relocation to a Relocations vector so that
786897 // InputSection::relocate will do the work for us. We may be able
787898 // to just write a value now, but it is a TODO.)
788 bool IsLinkTimeConstant =
789 !Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym));
790 if (IsLinkTimeConstant) {
791 In.Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym});
899 bool isLinkTimeConstant =
900 !sym.isPreemptible && (!config->isPic || isAbsolute(sym));
901 if (isLinkTimeConstant) {
902 in.got->relocations.push_back({expr, target->symbolicRel, off, 0, &sym});
792903 return;
793904 }
794905
795906 // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that
796907 // the GOT slot will be fixed at load-time.
797 if (!Sym.isTls() && !Sym.IsPreemptible && Config->Pic && !isAbsolute(Sym)) {
798 addRelativeReloc(In.Got, Off, &Sym, 0, R_ABS, Target->GotRel);
908 if (!sym.isTls() && !sym.isPreemptible && config->isPic && !isAbsolute(sym)) {
909 addRelativeReloc(in.got, off, &sym, 0, R_ABS, target->symbolicRel);
799910 return;
800911 }
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);
912 mainPart->relaDyn->addReloc(
913 sym.isTls() ? target->tlsGotRel : target->gotRel, in.got, off, &sym, 0,
914 sym.isPreemptible ? R_ADDEND : R_ABS, target->symbolicRel);
804915}
805916
806917// Return true if we can define a symbol in the executable that
807918// contains the value/function of a symbol defined in a shared
808919// library.
809static bool canDefineSymbolInExecutable(Symbol &Sym) {
920static bool canDefineSymbolInExecutable(Symbol &sym) {
810921 // If the symbol has default visibility the symbol defined in the
811922 // executable will preempt it.
812923 // Note that we want the visibility of the shared symbol itself, not
813924 // the visibility of the symbol in the output file we are producing. That is
814 // why we use Sym.StOther.
815 if ((Sym.StOther & 0x3) == STV_DEFAULT)
925 // why we use Sym.stOther.
926 if ((sym.stOther & 0x3) == STV_DEFAULT)
816927 return true;
817928
818929 // If we are allowed to break address equality of functions, defining
819930 // a plt entry will allow the program to call the function in the
820931 // .so, but the .so and the executable will no agree on the address
821932 // of the function. Similar logic for objects.
822 return ((Sym.isFunc() && Config->IgnoreFunctionAddressEquality) ||
823 (Sym.isObject() && Config->IgnoreDataAddressEquality));
933 return ((sym.isFunc() && config->ignoreFunctionAddressEquality) ||
934 (sym.isObject() && config->ignoreDataAddressEquality));
824935}
825936
826937// The reason we have to do this early scan is as follows
......@@ -837,23 +948,33 @@ static bool canDefineSymbolInExecutable(Symbol &Sym) {
837948// complicates things for the dynamic linker and means we would have to reserve
838949// space for the extra PT_LOAD even if we end up not using it.
839950template <class ELFT, class RelTy>
840static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
841 uint64_t Offset, Symbol &Sym, const RelTy &Rel,
842 int64_t Addend) {
843 if (isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Offset)) {
844 Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
951static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
952 uint64_t offset, Symbol &sym, const RelTy &rel,
953 int64_t addend) {
954 // If the relocation is known to be a link-time constant, we know no dynamic
955 // relocation will be created, pass the control to relocateAlloc() or
956 // relocateNonAlloc() to resolve it.
957 //
958 // The behavior of an undefined weak reference is implementation defined. If
959 // the relocation is to a weak undef, and we are producing an executable, let
960 // relocate{,Non}Alloc() resolve it.
961 if (isStaticLinkTimeConstant(expr, type, sym, sec, offset) ||
962 (!config->shared && sym.isUndefWeak())) {
963 sec.relocations.push_back({expr, type, offset, addend, &sym});
845964 return;
846965 }
847 bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText;
848 if (CanWrite) {
849 // R_GOT refers to a position in the got, even if the symbol is preemptible.
850 bool IsPreemptibleValue = Sym.IsPreemptible && Expr != R_GOT;
851966
852 if (!IsPreemptibleValue) {
853 addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type);
967 bool canWrite = (sec.flags & SHF_WRITE) || !config->zText;
968 if (canWrite) {
969 RelType rel = target->getDynRel(type);
970 if (expr == R_GOT || (rel == target->symbolicRel && !sym.isPreemptible)) {
971 addRelativeReloc(&sec, offset, &sym, addend, expr, type);
854972 return;
855 } else if (RelType Rel = Target->getDynRel(Type)) {
856 In.RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend, R_ADDEND, Type);
973 } else if (rel != 0) {
974 if (config->emachine == EM_MIPS && rel == target->symbolicRel)
975 rel = target->relativeRel;
976 sec.getPartition().relaDyn->addReloc(rel, &sec, offset, &sym, addend,
977 R_ADDEND, type);
857978
858979 // MIPS ABI turns using of GOT and dynamic relocations inside out.
859980 // While regular ABI uses dynamic relocations to fill up GOT entries
......@@ -870,62 +991,62 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
870991 // to the GOT entry and reads the GOT entry when it needs to perform
871992 // a dynamic relocation.
872993 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
873 if (Config->EMachine == EM_MIPS)
874 In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
994 if (config->emachine == EM_MIPS)
995 in.mipsGot->addEntry(*sec.file, sym, addend, expr);
875996 return;
876997 }
877998 }
878999
879 // If the relocation is to a weak undef, and we are producing
880 // executable, give up on it and produce a non preemptible 0.
881 if (!Config->Shared && Sym.isUndefWeak()) {
882 Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
883 return;
884 }
885
886 if (!CanWrite && (Config->Pic && !isRelExpr(Expr))) {
1000 if (!canWrite && (config->isPic && !isRelExpr(expr))) {
8871001 error(
888 "can't create dynamic relocation " + toString(Type) + " against " +
889 (Sym.getName().empty() ? "local symbol" : "symbol: " + toString(Sym)) +
1002 "can't create dynamic relocation " + toString(type) + " against " +
1003 (sym.getName().empty() ? "local symbol" : "symbol: " + toString(sym)) +
8901004 " in readonly segment; recompile object files with -fPIC "
8911005 "or pass '-Wl,-z,notext' to allow text relocations in the output" +
892 getLocation(Sec, Sym, Offset));
1006 getLocation(sec, sym, offset));
8931007 return;
8941008 }
8951009
896 // Copy relocations are only possible if we are creating an executable.
897 if (Config->Shared) {
898 errorOrWarn("relocation " + toString(Type) +
899 " cannot be used against symbol " + toString(Sym) +
900 "; recompile with -fPIC" + getLocation(Sec, Sym, Offset));
1010 // Copy relocations (for STT_OBJECT) and canonical PLT (for STT_FUNC) are only
1011 // possible in an executable.
1012 //
1013 // Among R_ABS relocatoin types, symbolicRel has the same size as the word
1014 // size. Others have fewer bits and may cause runtime overflow in -pie/-shared
1015 // mode. Disallow them.
1016 if (config->shared ||
1017 (config->pie && expr == R_ABS && type != target->symbolicRel)) {
1018 errorOrWarn(
1019 "relocation " + toString(type) + " cannot be used against " +
1020 (sym.getName().empty() ? "local symbol" : "symbol " + toString(sym)) +
1021 "; recompile with -fPIC" + getLocation(sec, sym, offset));
9011022 return;
9021023 }
9031024
9041025 // If the symbol is undefined we already reported any relevant errors.
905 if (Sym.isUndefined())
1026 if (sym.isUndefined())
9061027 return;
9071028
908 if (!canDefineSymbolInExecutable(Sym)) {
909 error("cannot preempt symbol: " + toString(Sym) +
910 getLocation(Sec, Sym, Offset));
1029 if (!canDefineSymbolInExecutable(sym)) {
1030 error("cannot preempt symbol: " + toString(sym) +
1031 getLocation(sec, sym, offset));
9111032 return;
9121033 }
9131034
914 if (Sym.isObject()) {
1035 if (sym.isObject()) {
9151036 // Produce a copy relocation.
916 if (auto *SS = dyn_cast<SharedSymbol>(&Sym)) {
917 if (!Config->ZCopyreloc)
918 error("unresolvable relocation " + toString(Type) +
919 " against symbol '" + toString(*SS) +
1037 if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
1038 if (!config->zCopyreloc)
1039 error("unresolvable relocation " + toString(type) +
1040 " against symbol '" + toString(*ss) +
9201041 "'; recompile with -fPIC or remove '-z nocopyreloc'" +
921 getLocation(Sec, Sym, Offset));
922 addCopyRelSymbol<ELFT>(*SS);
1042 getLocation(sec, sym, offset));
1043 addCopyRelSymbol<ELFT>(*ss);
9231044 }
924 Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
1045 sec.relocations.push_back({expr, type, offset, addend, &sym});
9251046 return;
9261047 }
9271048
928 if (Sym.isFunc()) {
1049 if (sym.isFunc()) {
9291050 // This handles a non PIC program call to function in a shared library. In
9301051 // an ideal world, we could just report an error saying the relocation can
9311052 // overflow at runtime. In the real world with glibc, crt1.o has a
......@@ -953,167 +1074,333 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
9531074 // compiled without -fPIE/-fPIC and doesn't maintain ebx.
9541075 // * If a library definition gets preempted to the executable, it will have
9551076 // the wrong ebx value.
956 if (Config->Pie && Config->EMachine == EM_386)
957 errorOrWarn("symbol '" + toString(Sym) +
1077 if (config->pie && config->emachine == EM_386)
1078 errorOrWarn("symbol '" + toString(sym) +
9581079 "' cannot be preempted; recompile with -fPIE" +
959 getLocation(Sec, Sym, Offset));
960 if (!Sym.isInPlt())
961 addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
962 if (!Sym.isDefined())
963 replaceWithDefined(Sym, In.Plt, getPltEntryOffset(Sym.PltIndex), 0);
964 Sym.NeedsPltAddr = true;
965 Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
1080 getLocation(sec, sym, offset));
1081 if (!sym.isInPlt())
1082 addPltEntry<ELFT>(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
1083 if (!sym.isDefined())
1084 replaceWithDefined(
1085 sym, in.plt,
1086 target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
1087 sym.needsPltAddr = true;
1088 sec.relocations.push_back({expr, type, offset, addend, &sym});
9661089 return;
9671090 }
9681091
969 errorOrWarn("symbol '" + toString(Sym) + "' has no type" +
970 getLocation(Sec, Sym, Offset));
1092 errorOrWarn("symbol '" + toString(sym) + "' has no type" +
1093 getLocation(sec, sym, offset));
9711094}
9721095
1096struct IRelativeReloc {
1097 RelType type;
1098 InputSectionBase *sec;
1099 uint64_t offset;
1100 Symbol *sym;
1101};
1102
1103static std::vector<IRelativeReloc> iRelativeRelocs;
1104
9731105template <class ELFT, class RelTy>
974static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
975 RelTy *End) {
976 const RelTy &Rel = *I;
977 Symbol &Sym = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
978 RelType Type;
1106static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
1107 RelTy *end) {
1108 const RelTy &rel = *i;
1109 uint32_t symIndex = rel.getSymbol(config->isMips64EL);
1110 Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIndex);
1111 RelType type;
9791112
9801113 // Deal with MIPS oddity.
981 if (Config->MipsN32Abi) {
982 Type = getMipsN32RelType(I, End);
1114 if (config->mipsN32Abi) {
1115 type = getMipsN32RelType(i, end);
9831116 } else {
984 Type = Rel.getType(Config->IsMips64EL);
985 ++I;
1117 type = rel.getType(config->isMips64EL);
1118 ++i;
9861119 }
9871120
9881121 // Get an offset in an output section this relocation is applied to.
989 uint64_t Offset = GetOffset.get(Rel.r_offset);
990 if (Offset == uint64_t(-1))
1122 uint64_t offset = getOffset.get(rel.r_offset);
1123 if (offset == uint64_t(-1))
9911124 return;
9921125
993 // Skip if the target symbol is an erroneous undefined symbol.
994 if (maybeReportUndefined(Sym, Sec, Rel.r_offset))
1126 // Error if the target symbol is undefined. Symbol index 0 may be used by
1127 // marker relocations, e.g. R_*_NONE and R_ARM_V4BX. Don't error on them.
1128 if (symIndex != 0 && maybeReportUndefined<ELFT>(sym, sec, rel.r_offset))
9951129 return;
9961130
997 const uint8_t *RelocatedAddr = Sec.data().begin() + Rel.r_offset;
998 RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr);
1131 const uint8_t *relocatedAddr = sec.data().begin() + rel.r_offset;
1132 RelExpr expr = target->getRelExpr(type, sym, relocatedAddr);
9991133
10001134 // Ignore "hint" relocations because they are only markers for relaxation.
1001 if (isRelExprOneOf<R_HINT, R_NONE>(Expr))
1135 if (oneof<R_HINT, R_NONE>(expr))
10021136 return;
10031137
1004 // Strenghten or relax relocations.
1005 //
1006 // GNU ifunc symbols must be accessed via PLT because their addresses
1007 // are determined by runtime.
1138 // We can separate the small code model relocations into 2 categories:
1139 // 1) Those that access the compiler generated .toc sections.
1140 // 2) Those that access the linker allocated got entries.
1141 // lld allocates got entries to symbols on demand. Since we don't try to sort
1142 // the got entries in any way, we don't have to track which objects have
1143 // got-based small code model relocs. The .toc sections get placed after the
1144 // end of the linker allocated .got section and we do sort those so sections
1145 // addressed with small code model relocations come first.
1146 if (config->emachine == EM_PPC64 && isPPC64SmallCodeModelTocReloc(type))
1147 sec.file->ppc64SmallCodeModelTocRelocs = true;
1148
1149 if (sym.isGnuIFunc() && !config->zText && config->warnIfuncTextrel) {
1150 warn("using ifunc symbols when text relocations are allowed may produce "
1151 "a binary that will segfault, if the object file is linked with "
1152 "old version of glibc (glibc 2.28 and earlier). If this applies to "
1153 "you, consider recompiling the object files without -fPIC and "
1154 "without -Wl,-z,notext option. Use -no-warn-ifunc-textrel to "
1155 "turn off this warning." +
1156 getLocation(sec, sym, offset));
1157 }
1158
1159 // Read an addend.
1160 int64_t addend = computeAddend<ELFT>(rel, end, sec, expr, sym.isLocal());
1161
1162 // Relax relocations.
10081163 //
1009 // On the other hand, if we know that a PLT entry will be resolved within
1010 // the same ELF module, we can skip PLT access and directly jump to the
1011 // destination function. For example, if we are linking a main exectuable,
1012 // all dynamic symbols that can be resolved within the executable will
1013 // actually be resolved that way at runtime, because the main exectuable
1014 // is always at the beginning of a search list. We can leverage that fact.
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));
1164 // If we know that a PLT entry will be resolved within the same ELF module, we
1165 // can skip PLT access and directly jump to the destination function. For
1166 // example, if we are linking a main exectuable, all dynamic symbols that can
1167 // be resolved within the executable will actually be resolved that way at
1168 // runtime, because the main exectuable is always at the beginning of a search
1169 // list. We can leverage that fact.
1170 if (!sym.isPreemptible && (!sym.isGnuIFunc() || config->zIfuncNoplt)) {
1171 if (expr == R_GOT_PC && !isAbsoluteValue(sym)) {
1172 expr = target->adjustRelaxExpr(type, relocatedAddr, expr);
1173 } else {
1174 // Addend of R_PPC_PLTREL24 is used to choose call stub type. It should be
1175 // ignored if optimized to R_PC.
1176 if (config->emachine == EM_PPC && expr == R_PPC32_PLTREL)
1177 addend = 0;
1178 expr = fromPlt(expr);
10241179 }
1025 Expr = toPlt(Expr);
1026 } else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym)) {
1027 Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr);
1028 } else if (!Sym.IsPreemptible) {
1029 Expr = fromPlt(Expr);
10301180 }
10311181
1032 // This relocation does not require got entry, but it is relative to got and
1033 // needs it to be created. Here we request for that.
1034 if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,
1035 R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
1036 In.Got->HasGotOffRel = true;
1037
1038 // Read an addend.
1039 int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal());
1182 // If the relocation does not emit a GOT or GOTPLT entry but its computation
1183 // uses their addresses, we need GOT or GOTPLT to be created.
1184 //
1185 // The 4 types that relative GOTPLT are all x86 and x86-64 specific.
1186 if (oneof<R_GOTPLTONLY_PC, R_GOTPLTREL, R_GOTPLT, R_TLSGD_GOTPLT>(expr)) {
1187 in.gotPlt->hasGotPltOffRel = true;
1188 } else if (oneof<R_GOTONLY_PC, R_GOTREL, R_PPC64_TOCBASE, R_PPC64_RELAX_TOC>(
1189 expr)) {
1190 in.got->hasGotOffRel = true;
1191 }
10401192
10411193 // Process some TLS relocations, including relaxing TLS relocations.
10421194 // Note that this function does not handle all TLS relocations.
1043 if (unsigned Processed =
1044 handleTlsRelocation<ELFT>(Type, Sym, Sec, Offset, Addend, Expr)) {
1045 I += (Processed - 1);
1195 if (unsigned processed =
1196 handleTlsRelocation<ELFT>(type, sym, sec, offset, addend, expr)) {
1197 i += (processed - 1);
10461198 return;
10471199 }
10481200
1049 // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
1050 if (needsPlt(Expr) && !Sym.isInPlt()) {
1051 if (Sym.isGnuIFunc() && !Sym.IsPreemptible)
1052 addPltEntry<ELFT>(In.Iplt, In.IgotPlt, In.RelaIplt, Target->IRelativeRel,
1053 Sym);
1054 else
1055 addPltEntry<ELFT>(In.Plt, In.GotPlt, In.RelaPlt, Target->PltRel, Sym);
1201 // We were asked not to generate PLT entries for ifuncs. Instead, pass the
1202 // direct relocation on through.
1203 if (sym.isGnuIFunc() && config->zIfuncNoplt) {
1204 sym.exportDynamic = true;
1205 mainPart->relaDyn->addReloc(type, &sec, offset, &sym, addend, R_ADDEND, type);
1206 return;
10561207 }
10571208
1058 // Create a GOT slot if a relocation needs GOT.
1059 if (needsGot(Expr)) {
1060 if (Config->EMachine == EM_MIPS) {
1061 // MIPS ABI has special rules to process GOT entries and doesn't
1062 // require relocation entries for them. A special case is TLS
1063 // relocations. In that case dynamic loader applies dynamic
1064 // relocations to initialize TLS GOT entries.
1065 // See "Global Offset Table" in Chapter 5 in the following document
1066 // for detailed description:
1067 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1068 In.MipsGot->addEntry(*Sec.File, Sym, Addend, Expr);
1069 } else if (!Sym.isInGot()) {
1070 addGotEntry<ELFT>(Sym);
1209 // Non-preemptible ifuncs require special handling. First, handle the usual
1210 // case where the symbol isn't one of these.
1211 if (!sym.isGnuIFunc() || sym.isPreemptible) {
1212 // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
1213 if (needsPlt(expr) && !sym.isInPlt())
1214 addPltEntry<ELFT>(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
1215
1216 // Create a GOT slot if a relocation needs GOT.
1217 if (needsGot(expr)) {
1218 if (config->emachine == EM_MIPS) {
1219 // MIPS ABI has special rules to process GOT entries and doesn't
1220 // require relocation entries for them. A special case is TLS
1221 // relocations. In that case dynamic loader applies dynamic
1222 // relocations to initialize TLS GOT entries.
1223 // See "Global Offset Table" in Chapter 5 in the following document
1224 // for detailed description:
1225 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1226 in.mipsGot->addEntry(*sec.file, sym, addend, expr);
1227 } else if (!sym.isInGot()) {
1228 addGotEntry(sym);
1229 }
1230 }
1231 } else {
1232 // Handle a reference to a non-preemptible ifunc. These are special in a
1233 // few ways:
1234 //
1235 // - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
1236 // a fixed value. But assuming that all references to the ifunc are
1237 // GOT-generating or PLT-generating, the handling of an ifunc is
1238 // relatively straightforward. We create a PLT entry in Iplt, which is
1239 // usually at the end of .plt, which makes an indirect call using a
1240 // matching GOT entry in igotPlt, which is usually at the end of .got.plt.
1241 // The GOT entry is relocated using an IRELATIVE relocation in relaIplt,
1242 // which is usually at the end of .rela.plt. Unlike most relocations in
1243 // .rela.plt, which may be evaluated lazily without -z now, dynamic
1244 // loaders evaluate IRELATIVE relocs eagerly, which means that for
1245 // IRELATIVE relocs only, GOT-generating relocations can point directly to
1246 // .got.plt without requiring a separate GOT entry.
1247 //
1248 // - Despite the fact that an ifunc does not have a fixed value, compilers
1249 // that are not passed -fPIC will assume that they do, and will emit
1250 // direct (non-GOT-generating, non-PLT-generating) relocations to the
1251 // symbol. This means that if a direct relocation to the symbol is
1252 // seen, the linker must set a value for the symbol, and this value must
1253 // be consistent no matter what type of reference is made to the symbol.
1254 // This can be done by creating a PLT entry for the symbol in the way
1255 // described above and making it canonical, that is, making all references
1256 // point to the PLT entry instead of the resolver. In lld we also store
1257 // the address of the PLT entry in the dynamic symbol table, which means
1258 // that the symbol will also have the same value in other modules.
1259 // Because the value loaded from the GOT needs to be consistent with
1260 // the value computed using a direct relocation, a non-preemptible ifunc
1261 // may end up with two GOT entries, one in .got.plt that points to the
1262 // address returned by the resolver and is used only by the PLT entry,
1263 // and another in .got that points to the PLT entry and is used by
1264 // GOT-generating relocations.
1265 //
1266 // - The fact that these symbols do not have a fixed value makes them an
1267 // exception to the general rule that a statically linked executable does
1268 // not require any form of dynamic relocation. To handle these relocations
1269 // correctly, the IRELATIVE relocations are stored in an array which a
1270 // statically linked executable's startup code must enumerate using the
1271 // linker-defined symbols __rela?_iplt_{start,end}.
1272 //
1273 // - An absolute relocation to a non-preemptible ifunc (such as a global
1274 // variable containing a pointer to the ifunc) needs to be relocated in
1275 // the exact same way as a GOT entry, so we can avoid needing to make the
1276 // PLT entry canonical by translating such relocations into IRELATIVE
1277 // relocations in the relaIplt.
1278 if (!sym.isInPlt()) {
1279 // Create PLT and GOTPLT slots for the symbol.
1280 sym.isInIplt = true;
1281
1282 // Create a copy of the symbol to use as the target of the IRELATIVE
1283 // relocation in the igotPlt. This is in case we make the PLT canonical
1284 // later, which would overwrite the original symbol.
1285 //
1286 // FIXME: Creating a copy of the symbol here is a bit of a hack. All
1287 // that's really needed to create the IRELATIVE is the section and value,
1288 // so ideally we should just need to copy those.
1289 auto *directSym = make<Defined>(cast<Defined>(sym));
1290 addPltEntry<ELFT>(in.iplt, in.igotPlt, in.relaIplt, target->iRelativeRel,
1291 *directSym);
1292 sym.pltIndex = directSym->pltIndex;
1293 }
1294 if (expr == R_ABS && addend == 0 && (sec.flags & SHF_WRITE)) {
1295 // We might be able to represent this as an IRELATIVE. But we don't know
1296 // yet whether some later relocation will make the symbol point to a
1297 // canonical PLT, which would make this either a dynamic RELATIVE (PIC) or
1298 // static (non-PIC) relocation. So we keep a record of the information
1299 // required to process the relocation, and after scanRelocs() has been
1300 // called on all relocations, the relocation is resolved by
1301 // addIRelativeRelocs().
1302 iRelativeRelocs.push_back({type, &sec, offset, &sym});
1303 return;
1304 }
1305 if (needsGot(expr)) {
1306 // Redirect GOT accesses to point to the Igot.
1307 //
1308 // This field is also used to keep track of whether we ever needed a GOT
1309 // entry. If we did and we make the PLT canonical later, we'll need to
1310 // create a GOT entry pointing to the PLT entry for Sym.
1311 sym.gotInIgot = true;
1312 } else if (!needsPlt(expr)) {
1313 // Make the ifunc's PLT entry canonical by changing the value of its
1314 // symbol to redirect all references to point to it.
1315 unsigned entryOffset = sym.pltIndex * target->pltEntrySize;
1316 if (config->zRetpolineplt)
1317 entryOffset += target->pltHeaderSize;
1318
1319 auto &d = cast<Defined>(sym);
1320 d.section = in.iplt;
1321 d.value = entryOffset;
1322 d.size = 0;
1323 // It's important to set the symbol type here so that dynamic loaders
1324 // don't try to call the PLT as if it were an ifunc resolver.
1325 d.type = STT_FUNC;
1326
1327 if (sym.gotInIgot) {
1328 // We previously encountered a GOT generating reference that we
1329 // redirected to the Igot. Now that the PLT entry is canonical we must
1330 // clear the redirection to the Igot and add a GOT entry. As we've
1331 // changed the symbol type to STT_FUNC future GOT generating references
1332 // will naturally use this GOT entry.
1333 //
1334 // We don't need to worry about creating a MIPS GOT here because ifuncs
1335 // aren't a thing on MIPS.
1336 sym.gotInIgot = false;
1337 addGotEntry(sym);
1338 }
10711339 }
10721340 }
10731341
1074 processRelocAux<ELFT>(Sec, Expr, Type, Offset, Sym, Rel, Addend);
1342 processRelocAux<ELFT>(sec, expr, type, offset, sym, rel, addend);
10751343}
10761344
10771345template <class ELFT, class RelTy>
1078static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
1079 OffsetGetter GetOffset(Sec);
1346static void scanRelocs(InputSectionBase &sec, ArrayRef<RelTy> rels) {
1347 OffsetGetter getOffset(sec);
10801348
10811349 // Not all relocations end up in Sec.Relocations, but a lot do.
1082 Sec.Relocations.reserve(Rels.size());
1083
1084 for (auto I = Rels.begin(), End = Rels.end(); I != End;)
1085 scanReloc<ELFT>(Sec, GetOffset, I, End);
1086
1087 // Sort relocations by offset to binary search for R_RISCV_PCREL_HI20
1088 if (Config->EMachine == EM_RISCV)
1089 std::stable_sort(Sec.Relocations.begin(), Sec.Relocations.end(),
1090 RelocationOffsetComparator{});
1350 sec.relocations.reserve(rels.size());
1351
1352 for (auto i = rels.begin(), end = rels.end(); i != end;)
1353 scanReloc<ELFT>(sec, getOffset, i, end);
1354
1355 // Sort relocations by offset for more efficient searching for
1356 // R_RISCV_PCREL_HI20 and R_PPC64_ADDR64.
1357 if (config->emachine == EM_RISCV ||
1358 (config->emachine == EM_PPC64 && sec.name == ".toc"))
1359 llvm::stable_sort(sec.relocations,
1360 [](const Relocation &lhs, const Relocation &rhs) {
1361 return lhs.offset < rhs.offset;
1362 });
10911363}
10921364
1093template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
1094 if (S.AreRelocsRela)
1095 scanRelocs<ELFT>(S, S.relas<ELFT>());
1365template <class ELFT> void elf::scanRelocations(InputSectionBase &s) {
1366 if (s.areRelocsRela)
1367 scanRelocs<ELFT>(s, s.relas<ELFT>());
10961368 else
1097 scanRelocs<ELFT>(S, S.rels<ELFT>());
1369 scanRelocs<ELFT>(s, s.rels<ELFT>());
1370}
1371
1372// Figure out which representation to use for any absolute relocs to
1373// non-preemptible ifuncs that we visited during scanRelocs().
1374void elf::addIRelativeRelocs() {
1375 for (IRelativeReloc &r : iRelativeRelocs) {
1376 if (r.sym->type == STT_GNU_IFUNC)
1377 in.relaIplt->addReloc(
1378 {target->iRelativeRel, r.sec, r.offset, true, r.sym, 0});
1379 else if (config->isPic)
1380 addRelativeReloc(r.sec, r.offset, r.sym, 0, R_ABS, r.type);
1381 else
1382 r.sec->relocations.push_back({R_ABS, r.type, r.offset, 0, r.sym});
1383 }
1384 iRelativeRelocs.clear();
10981385}
10991386
1100static bool mergeCmp(const InputSection *A, const InputSection *B) {
1387static bool mergeCmp(const InputSection *a, const InputSection *b) {
11011388 // std::merge requires a strict weak ordering.
1102 if (A->OutSecOff < B->OutSecOff)
1389 if (a->outSecOff < b->outSecOff)
11031390 return true;
11041391
1105 if (A->OutSecOff == B->OutSecOff) {
1106 auto *TA = dyn_cast<ThunkSection>(A);
1107 auto *TB = dyn_cast<ThunkSection>(B);
1392 if (a->outSecOff == b->outSecOff) {
1393 auto *ta = dyn_cast<ThunkSection>(a);
1394 auto *tb = dyn_cast<ThunkSection>(b);
11081395
11091396 // Check if Thunk is immediately before any specific Target
11101397 // InputSection for example Mips LA25 Thunks.
1111 if (TA && TA->getTargetInputSection() == B)
1398 if (ta && ta->getTargetInputSection() == b)
11121399 return true;
11131400
11141401 // Place Thunk Sections without specific targets before
11151402 // non-Thunk Sections.
1116 if (TA && !TB && !TA->getTargetInputSection())
1403 if (ta && !tb && !ta->getTargetInputSection())
11171404 return true;
11181405 }
11191406
......@@ -1123,14 +1410,14 @@ static bool mergeCmp(const InputSection *A, const InputSection *B) {
11231410// Call Fn on every executable InputSection accessed via the linker script
11241411// InputSectionDescription::Sections.
11251412static 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))
1413 ArrayRef<OutputSection *> outputSections,
1414 llvm::function_ref<void(OutputSection *, InputSectionDescription *)> fn) {
1415 for (OutputSection *os : outputSections) {
1416 if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR))
11301417 continue;
1131 for (BaseCommand *BC : OS->SectionCommands)
1132 if (auto *ISD = dyn_cast<InputSectionDescription>(BC))
1133 Fn(OS, ISD);
1418 for (BaseCommand *bc : os->sectionCommands)
1419 if (auto *isd = dyn_cast<InputSectionDescription>(bc))
1420 fn(os, isd);
11341421 }
11351422}
11361423
......@@ -1225,54 +1512,54 @@ static void forEachInputSectionDescription(
12251512// in the Sections vector, and recalculate the InputSection output section
12261513// offsets.
12271514// This may invalidate any output section offsets stored outside of InputSection
1228void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> OutputSections) {
1515void ThunkCreator::mergeThunks(ArrayRef<OutputSection *> outputSections) {
12291516 forEachInputSectionDescription(
1230 OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
1231 if (ISD->ThunkSections.empty())
1517 outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
1518 if (isd->thunkSections.empty())
12321519 return;
12331520
12341521 // Remove any zero sized precreated Thunks.
1235 llvm::erase_if(ISD->ThunkSections,
1236 [](const std::pair<ThunkSection *, uint32_t> &TS) {
1237 return TS.first->getSize() == 0;
1522 llvm::erase_if(isd->thunkSections,
1523 [](const std::pair<ThunkSection *, uint32_t> &ts) {
1524 return ts.first->getSize() == 0;
12381525 });
12391526
12401527 // ISD->ThunkSections contains all created ThunkSections, including
12411528 // those inserted in previous passes. Extract the Thunks created this
1242 // pass and order them in ascending OutSecOff.
1243 std::vector<ThunkSection *> NewThunks;
1244 for (const std::pair<ThunkSection *, uint32_t> TS : ISD->ThunkSections)
1245 if (TS.second == Pass)
1246 NewThunks.push_back(TS.first);
1247 std::stable_sort(NewThunks.begin(), NewThunks.end(),
1248 [](const ThunkSection *A, const ThunkSection *B) {
1249 return A->OutSecOff < B->OutSecOff;
1250 });
1251
1252 // Merge sorted vectors of Thunks and InputSections by OutSecOff
1253 std::vector<InputSection *> Tmp;
1254 Tmp.reserve(ISD->Sections.size() + NewThunks.size());
1255
1256 std::merge(ISD->Sections.begin(), ISD->Sections.end(),
1257 NewThunks.begin(), NewThunks.end(), std::back_inserter(Tmp),
1529 // pass and order them in ascending outSecOff.
1530 std::vector<ThunkSection *> newThunks;
1531 for (const std::pair<ThunkSection *, uint32_t> ts : isd->thunkSections)
1532 if (ts.second == pass)
1533 newThunks.push_back(ts.first);
1534 llvm::stable_sort(newThunks,
1535 [](const ThunkSection *a, const ThunkSection *b) {
1536 return a->outSecOff < b->outSecOff;
1537 });
1538
1539 // Merge sorted vectors of Thunks and InputSections by outSecOff
1540 std::vector<InputSection *> tmp;
1541 tmp.reserve(isd->sections.size() + newThunks.size());
1542
1543 std::merge(isd->sections.begin(), isd->sections.end(),
1544 newThunks.begin(), newThunks.end(), std::back_inserter(tmp),
12581545 mergeCmp);
12591546
1260 ISD->Sections = std::move(Tmp);
1547 isd->sections = std::move(tmp);
12611548 });
12621549}
12631550
12641551// Find or create a ThunkSection within the InputSectionDescription (ISD) that
12651552// is in range of Src. An ISD maps to a range of InputSections described by a
12661553// linker script section pattern such as { .text .text.* }.
1267ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *OS, InputSection *IS,
1268 InputSectionDescription *ISD,
1269 uint32_t Type, uint64_t Src) {
1270 for (std::pair<ThunkSection *, uint32_t> TP : ISD->ThunkSections) {
1271 ThunkSection *TS = TP.first;
1272 uint64_t TSBase = OS->Addr + TS->OutSecOff;
1273 uint64_t TSLimit = TSBase + TS->getSize();
1274 if (Target->inBranchRange(Type, Src, (Src > TSLimit) ? TSBase : TSLimit))
1275 return TS;
1554ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *os, InputSection *isec,
1555 InputSectionDescription *isd,
1556 uint32_t type, uint64_t src) {
1557 for (std::pair<ThunkSection *, uint32_t> tp : isd->thunkSections) {
1558 ThunkSection *ts = tp.first;
1559 uint64_t tsBase = os->addr + ts->outSecOff;
1560 uint64_t tsLimit = tsBase + ts->getSize();
1561 if (target->inBranchRange(type, src, (src > tsLimit) ? tsBase : tsLimit))
1562 return ts;
12761563 }
12771564
12781565 // No suitable ThunkSection exists. This can happen when there is a branch
......@@ -1280,40 +1567,40 @@ ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *OS, InputSection *IS,
12801567 // many Thunks. Create a new ThunkSection as close to the InputSection as
12811568 // possible. Error if InputSection is so large we cannot place ThunkSection
12821569 // anywhere in Range.
1283 uint64_t ThunkSecOff = IS->OutSecOff;
1284 if (!Target->inBranchRange(Type, Src, OS->Addr + ThunkSecOff)) {
1285 ThunkSecOff = IS->OutSecOff + IS->getSize();
1286 if (!Target->inBranchRange(Type, Src, OS->Addr + ThunkSecOff))
1570 uint64_t thunkSecOff = isec->outSecOff;
1571 if (!target->inBranchRange(type, src, os->addr + thunkSecOff)) {
1572 thunkSecOff = isec->outSecOff + isec->getSize();
1573 if (!target->inBranchRange(type, src, os->addr + thunkSecOff))
12871574 fatal("InputSection too large for range extension thunk " +
1288 IS->getObjMsg(Src - (OS->Addr + IS->OutSecOff)));
1575 isec->getObjMsg(src - (os->addr + isec->outSecOff)));
12891576 }
1290 return addThunkSection(OS, ISD, ThunkSecOff);
1577 return addThunkSection(os, isd, thunkSecOff);
12911578}
12921579
12931580// Add a Thunk that needs to be placed in a ThunkSection that immediately
12941581// precedes its Target.
1295ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
1296 ThunkSection *TS = ThunkedSections.lookup(IS);
1297 if (TS)
1298 return TS;
1582ThunkSection *ThunkCreator::getISThunkSec(InputSection *isec) {
1583 ThunkSection *ts = thunkedSections.lookup(isec);
1584 if (ts)
1585 return ts;
12991586
13001587 // Find InputSectionRange within Target Output Section (TOS) that the
13011588 // InputSection (IS) that we need to precede is in.
1302 OutputSection *TOS = IS->getParent();
1303 for (BaseCommand *BC : TOS->SectionCommands) {
1304 auto *ISD = dyn_cast<InputSectionDescription>(BC);
1305 if (!ISD || ISD->Sections.empty())
1589 OutputSection *tos = isec->getParent();
1590 for (BaseCommand *bc : tos->sectionCommands) {
1591 auto *isd = dyn_cast<InputSectionDescription>(bc);
1592 if (!isd || isd->sections.empty())
13061593 continue;
13071594
1308 InputSection *First = ISD->Sections.front();
1309 InputSection *Last = ISD->Sections.back();
1595 InputSection *first = isd->sections.front();
1596 InputSection *last = isd->sections.back();
13101597
1311 if (IS->OutSecOff < First->OutSecOff || Last->OutSecOff < IS->OutSecOff)
1598 if (isec->outSecOff < first->outSecOff || last->outSecOff < isec->outSecOff)
13121599 continue;
13131600
1314 TS = addThunkSection(TOS, ISD, IS->OutSecOff);
1315 ThunkedSections[IS] = TS;
1316 return TS;
1601 ts = addThunkSection(tos, isd, isec->outSecOff);
1602 thunkedSections[isec] = ts;
1603 return ts;
13171604 }
13181605
13191606 return nullptr;
......@@ -1336,82 +1623,93 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
13361623// distance from a thunk to its target will be sufficiently small to
13371624// allow for the creation of a short thunk.
13381625void ThunkCreator::createInitialThunkSections(
1339 ArrayRef<OutputSection *> OutputSections) {
1340 uint32_t ThunkSectionSpacing = Target->getThunkSectionSpacing();
1626 ArrayRef<OutputSection *> outputSections) {
1627 uint32_t thunkSectionSpacing = target->getThunkSectionSpacing();
13411628
13421629 forEachInputSectionDescription(
1343 OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
1344 if (ISD->Sections.empty())
1630 outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
1631 if (isd->sections.empty())
13451632 return;
13461633
1347 uint32_t ISDBegin = ISD->Sections.front()->OutSecOff;
1348 uint32_t ISDEnd =
1349 ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize();
1350 uint32_t LastThunkLowerBound = -1;
1351 if (ISDEnd - ISDBegin > ThunkSectionSpacing * 2)
1352 LastThunkLowerBound = ISDEnd - ThunkSectionSpacing;
1353
1354 uint32_t ISLimit;
1355 uint32_t PrevISLimit = ISDBegin;
1356 uint32_t ThunkUpperBound = ISDBegin + ThunkSectionSpacing;
1357
1358 for (const InputSection *IS : ISD->Sections) {
1359 ISLimit = IS->OutSecOff + IS->getSize();
1360 if (ISLimit > ThunkUpperBound) {
1361 addThunkSection(OS, ISD, PrevISLimit);
1362 ThunkUpperBound = PrevISLimit + ThunkSectionSpacing;
1634 uint32_t isdBegin = isd->sections.front()->outSecOff;
1635 uint32_t isdEnd =
1636 isd->sections.back()->outSecOff + isd->sections.back()->getSize();
1637 uint32_t lastThunkLowerBound = -1;
1638 if (isdEnd - isdBegin > thunkSectionSpacing * 2)
1639 lastThunkLowerBound = isdEnd - thunkSectionSpacing;
1640
1641 uint32_t isecLimit;
1642 uint32_t prevIsecLimit = isdBegin;
1643 uint32_t thunkUpperBound = isdBegin + thunkSectionSpacing;
1644
1645 for (const InputSection *isec : isd->sections) {
1646 isecLimit = isec->outSecOff + isec->getSize();
1647 if (isecLimit > thunkUpperBound) {
1648 addThunkSection(os, isd, prevIsecLimit);
1649 thunkUpperBound = prevIsecLimit + thunkSectionSpacing;
13631650 }
1364 if (ISLimit > LastThunkLowerBound)
1651 if (isecLimit > lastThunkLowerBound)
13651652 break;
1366 PrevISLimit = ISLimit;
1653 prevIsecLimit = isecLimit;
13671654 }
1368 addThunkSection(OS, ISD, ISLimit);
1655 addThunkSection(os, isd, isecLimit);
13691656 });
13701657}
13711658
1372ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
1373 InputSectionDescription *ISD,
1374 uint64_t Off) {
1375 auto *TS = make<ThunkSection>(OS, Off);
1376 ISD->ThunkSections.push_back({TS, Pass});
1377 return TS;
1659ThunkSection *ThunkCreator::addThunkSection(OutputSection *os,
1660 InputSectionDescription *isd,
1661 uint64_t off) {
1662 auto *ts = make<ThunkSection>(os, off);
1663 ts->partition = os->partition;
1664 isd->thunkSections.push_back({ts, pass});
1665 return ts;
13781666}
13791667
1380std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,
1381 uint64_t Src) {
1382 std::vector<Thunk *> *ThunkVec = nullptr;
1668static bool isThunkSectionCompatible(InputSection *source,
1669 SectionBase *target) {
1670 // We can't reuse thunks in different loadable partitions because they might
1671 // not be loaded. But partition 1 (the main partition) will always be loaded.
1672 if (source->partition != target->partition)
1673 return target->partition == 1;
1674 return true;
1675}
1676
1677std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
1678 Relocation &rel, uint64_t src) {
1679 std::vector<Thunk *> *thunkVec = nullptr;
13831680
13841681 // We use (section, offset) pair to find the thunk position if possible so
13851682 // that we create only one thunk for aliased symbols or ICFed sections.
1386 if (auto *D = dyn_cast<Defined>(&Sym))
1387 if (!D->isInPlt() && D->Section)
1388 ThunkVec = &ThunkedSymbolsBySection[{D->Section->Repl, D->Value}];
1389 if (!ThunkVec)
1390 ThunkVec = &ThunkedSymbols[&Sym];
1683 if (auto *d = dyn_cast<Defined>(rel.sym))
1684 if (!d->isInPlt() && d->section)
1685 thunkVec = &thunkedSymbolsBySection[{d->section->repl, d->value}];
1686 if (!thunkVec)
1687 thunkVec = &thunkedSymbols[rel.sym];
13911688
13921689 // Check existing Thunks for Sym to see if they can be reused
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);
1690 for (Thunk *t : *thunkVec)
1691 if (isThunkSectionCompatible(isec, t->getThunkTargetSym()->section) &&
1692 t->isCompatibleWith(*isec, rel) &&
1693 target->inBranchRange(rel.type, src, t->getThunkTargetSym()->getVA()))
1694 return std::make_pair(t, false);
13971695
13981696 // No existing compatible Thunk in range, create a new one
1399 Thunk *T = addThunk(Type, Sym);
1400 ThunkVec->push_back(T);
1401 return std::make_pair(T, true);
1697 Thunk *t = addThunk(*isec, rel);
1698 thunkVec->push_back(t);
1699 return std::make_pair(t, true);
14021700}
14031701
14041702// Return true if the relocation target is an in range Thunk.
14051703// Return false if the relocation is not to a Thunk. If the relocation target
14061704// was originally to a Thunk, but is no longer in range we revert the
14071705// relocation back to its original non-Thunk target.
1408bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
1409 if (Thunk *T = Thunks.lookup(Rel.Sym)) {
1410 if (Target->inBranchRange(Rel.Type, Src, Rel.Sym->getVA()))
1706bool ThunkCreator::normalizeExistingThunk(Relocation &rel, uint64_t src) {
1707 if (Thunk *t = thunks.lookup(rel.sym)) {
1708 if (target->inBranchRange(rel.type, src, rel.sym->getVA()))
14111709 return true;
1412 Rel.Sym = &T->Destination;
1413 if (Rel.Sym->isInPlt())
1414 Rel.Expr = toPlt(Rel.Expr);
1710 rel.sym = &t->destination;
1711 if (rel.sym->isInPlt())
1712 rel.expr = toPlt(rel.expr);
14151713 }
14161714 return false;
14171715}
......@@ -1441,15 +1739,15 @@ bool ThunkCreator::normalizeExistingThunk(Relocation &Rel, uint64_t Src) {
14411739// made no changes. If the target requires range extension thunks, currently
14421740// ARM, then any future change in offset between caller and callee risks a
14431741// relocation out of range error.
1444bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
1445 bool AddressesChanged = false;
1742bool ThunkCreator::createThunks(ArrayRef<OutputSection *> outputSections) {
1743 bool addressesChanged = false;
14461744
1447 if (Pass == 0 && Target->getThunkSectionSpacing())
1448 createInitialThunkSections(OutputSections);
1745 if (pass == 0 && target->getThunkSectionSpacing())
1746 createInitialThunkSections(outputSections);
14491747
14501748 // With Thunk Size much smaller than branch range we expect to
14511749 // converge quickly; if we get to 10 something has gone wrong.
1452 if (Pass == 10)
1750 if (pass == 10)
14531751 fatal("thunk creation not converged");
14541752
14551753 // Create all the Thunks and insert them into synthetic ThunkSections. The
......@@ -1458,55 +1756,64 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
14581756 // ThunkSections as ThunkSections are not always inserted into the same
14591757 // InputSectionDescription as the caller.
14601758 forEachInputSectionDescription(
1461 OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
1462 for (InputSection *IS : ISD->Sections)
1463 for (Relocation &Rel : IS->Relocations) {
1464 uint64_t Src = IS->getVA(Rel.Offset);
1759 outputSections, [&](OutputSection *os, InputSectionDescription *isd) {
1760 for (InputSection *isec : isd->sections)
1761 for (Relocation &rel : isec->relocations) {
1762 uint64_t src = isec->getVA(rel.offset);
14651763
14661764 // If we are a relocation to an existing Thunk, check if it is
14671765 // still in range. If not then Rel will be altered to point to its
14681766 // original target so another Thunk can be generated.
1469 if (Pass > 0 && normalizeExistingThunk(Rel, Src))
1767 if (pass > 0 && normalizeExistingThunk(rel, src))
14701768 continue;
14711769
1472 if (!Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Src,
1473 *Rel.Sym))
1770 if (!target->needsThunk(rel.expr, rel.type, isec->file, src,
1771 *rel.sym))
14741772 continue;
14751773
1476 Thunk *T;
1477 bool IsNew;
1478 std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src);
1774 Thunk *t;
1775 bool isNew;
1776 std::tie(t, isNew) = getThunk(isec, rel, src);
14791777
1480 if (IsNew) {
1778 if (isNew) {
14811779 // Find or create a ThunkSection for the new Thunk
1482 ThunkSection *TS;
1483 if (auto *TIS = T->getTargetInputSection())
1484 TS = getISThunkSec(TIS);
1780 ThunkSection *ts;
1781 if (auto *tis = t->getTargetInputSection())
1782 ts = getISThunkSec(tis);
14851783 else
1486 TS = getISDThunkSec(OS, IS, ISD, Rel.Type, Src);
1487 TS->addThunk(T);
1488 Thunks[T->getThunkTargetSym()] = T;
1784 ts = getISDThunkSec(os, isec, isd, rel.type, src);
1785 ts->addThunk(t);
1786 thunks[t->getThunkTargetSym()] = t;
14891787 }
14901788
14911789 // Redirect relocation to Thunk, we never go via the PLT to a Thunk
1492 Rel.Sym = T->getThunkTargetSym();
1493 Rel.Expr = fromPlt(Rel.Expr);
1790 rel.sym = t->getThunkTargetSym();
1791 rel.expr = fromPlt(rel.expr);
1792
1793 // The addend of R_PPC_PLTREL24 should be ignored after changing to
1794 // R_PC.
1795 if (config->emachine == EM_PPC && rel.type == R_PPC_PLTREL24)
1796 rel.addend = 0;
14941797 }
14951798
1496 for (auto &P : ISD->ThunkSections)
1497 AddressesChanged |= P.first->assignOffsets();
1799 for (auto &p : isd->thunkSections)
1800 addressesChanged |= p.first->assignOffsets();
14981801 });
14991802
1500 for (auto &P : ThunkedSections)
1501 AddressesChanged |= P.second->assignOffsets();
1803 for (auto &p : thunkedSections)
1804 addressesChanged |= p.second->assignOffsets();
15021805
15031806 // Merge all created synthetic ThunkSections back into OutputSection
1504 mergeThunks(OutputSections);
1505 ++Pass;
1506 return AddressesChanged;
1807 mergeThunks(outputSections);
1808 ++pass;
1809 return addressesChanged;
15071810}
15081811
15091812template void elf::scanRelocations<ELF32LE>(InputSectionBase &);
15101813template void elf::scanRelocations<ELF32BE>(InputSectionBase &);
15111814template void elf::scanRelocations<ELF64LE>(InputSectionBase &);
15121815template void elf::scanRelocations<ELF64BE>(InputSectionBase &);
1816template void elf::reportUndefinedSymbols<ELF32LE>();
1817template void elf::reportUndefinedSymbols<ELF32BE>();
1818template void elf::reportUndefinedSymbols<ELF64LE>();
1819template void elf::reportUndefinedSymbols<ELF64BE>();
deps/lld/ELF/Relocations.h+71-107
......@@ -1,9 +1,8 @@
11//===- Relocations.h -------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -24,136 +23,100 @@ class OutputSection;
2423class SectionBase;
2524
2625// Represents a relocation type, such as R_X86_64_PC32 or R_ARM_THM_CALL.
27typedef uint32_t RelType;
26using RelType = uint32_t;
2827
2928// List of target-independent relocation types. Relocations read
3029// from files are converted to these types so that the main code
3130// doesn't have to know about architecture-specific details.
3231enum RelExpr {
33 R_INVALID,
3432 R_ABS,
3533 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,
45 R_ARM_SBREL,
34 R_DTPREL,
4635 R_GOT,
47 // The expression is used for IFUNC support. Evaluates to GOT entry,
48 // containing redirection to the IPLT.
49 R_GOT_PLT,
50 R_GOTONLY_PC,
51 R_GOTONLY_PC_FROM_END,
52 R_GOTREL,
53 R_GOTREL_FROM_END,
54 R_GOT_FROM_END,
5536 R_GOT_OFF,
5637 R_GOT_PC,
57 R_HEXAGON_GOT,
38 R_GOTONLY_PC,
39 R_GOTPLTONLY_PC,
40 R_GOTPLT,
41 R_GOTPLTREL,
42 R_GOTREL,
5843 R_HINT,
59 R_MIPS_GOTREL,
60 R_MIPS_GOT_GP,
61 R_MIPS_GOT_GP_PC,
62 R_MIPS_GOT_LOCAL_PAGE,
63 R_MIPS_GOT_OFF,
64 R_MIPS_GOT_OFF32,
65 R_MIPS_TLSGD,
66 R_MIPS_TLSLD,
6744 R_NEG_TLS,
6845 R_NONE,
6946 R_PC,
7047 R_PLT,
7148 R_PLT_PC,
72 R_PPC_CALL,
73 R_PPC_CALL_PLT,
74 R_PPC_TOC,
7549 R_RELAX_GOT_PC,
7650 R_RELAX_GOT_PC_NOPIC,
7751 R_RELAX_TLS_GD_TO_IE,
7852 R_RELAX_TLS_GD_TO_IE_ABS,
79 R_RELAX_TLS_GD_TO_IE_END,
8053 R_RELAX_TLS_GD_TO_IE_GOT_OFF,
54 R_RELAX_TLS_GD_TO_IE_GOTPLT,
8155 R_RELAX_TLS_GD_TO_LE,
8256 R_RELAX_TLS_GD_TO_LE_NEG,
8357 R_RELAX_TLS_IE_TO_LE,
8458 R_RELAX_TLS_LD_TO_LE,
8559 R_RELAX_TLS_LD_TO_LE_ABS,
86 R_RISCV_PC_INDIRECT,
8760 R_SIZE,
8861 R_TLS,
8962 R_TLSDESC,
9063 R_TLSDESC_CALL,
64 R_TLSDESC_PC,
9165 R_TLSGD_GOT,
92 R_TLSGD_GOT_FROM_END,
66 R_TLSGD_GOTPLT,
9367 R_TLSGD_PC,
9468 R_TLSIE_HINT,
9569 R_TLSLD_GOT,
96 R_TLSLD_GOT_FROM_END,
70 R_TLSLD_GOTPLT,
9771 R_TLSLD_GOT_OFF,
9872 R_TLSLD_HINT,
9973 R_TLSLD_PC,
100};
10174
102// Build a bitmask with one bit set for each RelExpr.
103//
104// Constexpr function arguments can't be used in static asserts, so we
105// use template arguments to build the mask.
106// But function template partial specializations don't exist (needed
107// for base case of the recursion), so we need a dummy struct.
108template <RelExpr... Exprs> struct RelExprMaskBuilder {
109 static inline uint64_t build() { return 0; }
110};
111
112// Specialization for recursive case.
113template <RelExpr Head, RelExpr... Tail>
114struct RelExprMaskBuilder<Head, Tail...> {
115 static inline uint64_t build() {
116 static_assert(0 <= Head && Head < 64,
117 "RelExpr is too large for 64-bit mask!");
118 return (uint64_t(1) << Head) | RelExprMaskBuilder<Tail...>::build();
119 }
75 // The following is abstract relocation types used for only one target.
76 //
77 // Even though RelExpr is intended to be a target-neutral representation
78 // of a relocation type, there are some relocations whose semantics are
79 // unique to a target. Such relocation are marked with R_<TARGET_NAME>.
80 R_AARCH64_GOT_PAGE_PC,
81 R_AARCH64_PAGE_PC,
82 R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
83 R_AARCH64_TLSDESC_PAGE,
84 R_ARM_SBREL,
85 R_HEXAGON_GOT,
86 R_MIPS_GOTREL,
87 R_MIPS_GOT_GP,
88 R_MIPS_GOT_GP_PC,
89 R_MIPS_GOT_LOCAL_PAGE,
90 R_MIPS_GOT_OFF,
91 R_MIPS_GOT_OFF32,
92 R_MIPS_TLSGD,
93 R_MIPS_TLSLD,
94 R_PPC32_PLTREL,
95 R_PPC64_CALL,
96 R_PPC64_CALL_PLT,
97 R_PPC64_RELAX_TOC,
98 R_PPC64_TOCBASE,
99 R_RISCV_ADD,
100 R_RISCV_PC_INDIRECT,
120101};
121102
122// Return true if `Expr` is one of `Exprs`.
123// There are fewer than 64 RelExpr's, so we can represent any set of
124// RelExpr's as a constant bit mask and test for membership with a
125// couple cheap bitwise operations.
126template <RelExpr... Exprs> bool isRelExprOneOf(RelExpr Expr) {
127 assert(0 <= Expr && (int)Expr < 64 &&
128 "RelExpr is too large for 64-bit mask!");
129 return (uint64_t(1) << Expr) & RelExprMaskBuilder<Exprs...>::build();
130}
131
132103// Architecture-neutral representation of relocation.
133104struct Relocation {
134 RelExpr Expr;
135 RelType Type;
136 uint64_t Offset;
137 int64_t Addend;
138 Symbol *Sym;
105 RelExpr expr;
106 RelType type;
107 uint64_t offset;
108 int64_t addend;
109 Symbol *sym;
139110};
140111
141struct RelocationOffsetComparator {
142 bool operator()(const Relocation &Lhs, const Relocation &Rhs) {
143 return Lhs.Offset < Rhs.Offset;
144 }
112// This function writes undefined symbol diagnostics to an internal buffer.
113// Call reportUndefinedSymbols() after calling scanRelocations() to emit
114// the diagnostics.
115template <class ELFT> void scanRelocations(InputSectionBase &);
145116
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 }
117template <class ELFT> void reportUndefinedSymbols();
150118
151 bool operator()(uint64_t Val, const Relocation &Rel) {
152 return Val < Rel.Offset;
153 }
154};
155
156template <class ELFT> void scanRelocations(InputSectionBase &);
119void addIRelativeRelocs();
157120
158121class ThunkSection;
159122class Thunk;
......@@ -162,56 +125,57 @@ struct InputSectionDescription;
162125class ThunkCreator {
163126public:
164127 // Return true if Thunks have been added to OutputSections
165 bool createThunks(ArrayRef<OutputSection *> OutputSections);
128 bool createThunks(ArrayRef<OutputSection *> outputSections);
166129
167130 // The number of completed passes of createThunks this permits us
168131 // to do one time initialization on Pass 0 and put a limit on the
169132 // number of times it can be called to prevent infinite loops.
170 uint32_t Pass = 0;
133 uint32_t pass = 0;
171134
172135private:
173 void mergeThunks(ArrayRef<OutputSection *> OutputSections);
136 void mergeThunks(ArrayRef<OutputSection *> outputSections);
174137
175 ThunkSection *getISDThunkSec(OutputSection *OS, InputSection *IS,
176 InputSectionDescription *ISD, uint32_t Type,
177 uint64_t Src);
138 ThunkSection *getISDThunkSec(OutputSection *os, InputSection *isec,
139 InputSectionDescription *isd, uint32_t type,
140 uint64_t src);
178141
179 ThunkSection *getISThunkSec(InputSection *IS);
142 ThunkSection *getISThunkSec(InputSection *isec);
180143
181 void createInitialThunkSections(ArrayRef<OutputSection *> OutputSections);
144 void createInitialThunkSections(ArrayRef<OutputSection *> outputSections);
182145
183 std::pair<Thunk *, bool> getThunk(Symbol &Sym, RelType Type, uint64_t Src);
146 std::pair<Thunk *, bool> getThunk(InputSection *isec, Relocation &rel,
147 uint64_t src);
184148
185 ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *,
186 uint64_t Off);
149 ThunkSection *addThunkSection(OutputSection *os, InputSectionDescription *,
150 uint64_t off);
187151
188 bool normalizeExistingThunk(Relocation &Rel, uint64_t Src);
152 bool normalizeExistingThunk(Relocation &rel, uint64_t src);
189153
190154 // Record all the available Thunks for a Symbol
191155 llvm::DenseMap<std::pair<SectionBase *, uint64_t>, std::vector<Thunk *>>
192 ThunkedSymbolsBySection;
193 llvm::DenseMap<Symbol *, std::vector<Thunk *>> ThunkedSymbols;
156 thunkedSymbolsBySection;
157 llvm::DenseMap<Symbol *, std::vector<Thunk *>> thunkedSymbols;
194158
195159 // Find a Thunk from the Thunks symbol definition, we can use this to find
196160 // the Thunk from a relocation to the Thunks symbol definition.
197 llvm::DenseMap<Symbol *, Thunk *> Thunks;
161 llvm::DenseMap<Symbol *, Thunk *> thunks;
198162
199163 // Track InputSections that have an inline ThunkSection placed in front
200164 // an inline ThunkSection may have control fall through to the section below
201165 // so we need to make sure that there is only one of them.
202166 // The Mips LA25 Thunk is an example of an inline ThunkSection.
203 llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections;
167 llvm::DenseMap<InputSection *, ThunkSection *> thunkedSections;
204168};
205169
206170// Return a int64_t to make sure we get the sign extension out of the way as
207171// early as possible.
208172template <class ELFT>
209static inline int64_t getAddend(const typename ELFT::Rel &Rel) {
173static inline int64_t getAddend(const typename ELFT::Rel &rel) {
210174 return 0;
211175}
212176template <class ELFT>
213static inline int64_t getAddend(const typename ELFT::Rela &Rel) {
214 return Rel.r_addend;
177static inline int64_t getAddend(const typename ELFT::Rela &rel) {
178 return rel.r_addend;
215179}
216180} // namespace elf
217181} // namespace lld
deps/lld/ELF/ScriptLexer.cpp+113-111
......@@ -1,9 +1,8 @@
11//===- ScriptLexer.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -42,166 +41,169 @@ using namespace lld::elf;
4241
4342// Returns a whole line containing the current token.
4443StringRef ScriptLexer::getLine() {
45 StringRef S = getCurrentMB().getBuffer();
46 StringRef Tok = Tokens[Pos - 1];
44 StringRef s = getCurrentMB().getBuffer();
45 StringRef tok = tokens[pos - 1];
4746
48 size_t Pos = S.rfind('\n', Tok.data() - S.data());
49 if (Pos != StringRef::npos)
50 S = S.substr(Pos + 1);
51 return S.substr(0, S.find_first_of("\r\n"));
47 size_t pos = s.rfind('\n', tok.data() - s.data());
48 if (pos != StringRef::npos)
49 s = s.substr(pos + 1);
50 return s.substr(0, s.find_first_of("\r\n"));
5251}
5352
5453// Returns 1-based line number of the current token.
5554size_t ScriptLexer::getLineNumber() {
56 StringRef S = getCurrentMB().getBuffer();
57 StringRef Tok = Tokens[Pos - 1];
58 return S.substr(0, Tok.data() - S.data()).count('\n') + 1;
55 StringRef s = getCurrentMB().getBuffer();
56 StringRef tok = tokens[pos - 1];
57 return s.substr(0, tok.data() - s.data()).count('\n') + 1;
5958}
6059
6160// Returns 0-based column number of the current token.
6261size_t ScriptLexer::getColumnNumber() {
63 StringRef Tok = Tokens[Pos - 1];
64 return Tok.data() - getLine().data();
62 StringRef tok = tokens[pos - 1];
63 return tok.data() - getLine().data();
6564}
6665
6766std::string ScriptLexer::getCurrentLocation() {
68 std::string Filename = getCurrentMB().getBufferIdentifier();
69 return (Filename + ":" + Twine(getLineNumber())).str();
67 std::string filename = getCurrentMB().getBufferIdentifier();
68 return (filename + ":" + Twine(getLineNumber())).str();
7069}
7170
72ScriptLexer::ScriptLexer(MemoryBufferRef MB) { tokenize(MB); }
71ScriptLexer::ScriptLexer(MemoryBufferRef mb) { tokenize(mb); }
7372
7473// We don't want to record cascading errors. Keep only the first one.
75void ScriptLexer::setError(const Twine &Msg) {
74void ScriptLexer::setError(const Twine &msg) {
7675 if (errorCount())
7776 return;
7877
79 std::string S = (getCurrentLocation() + ": " + Msg).str();
80 if (Pos)
81 S += "\n>>> " + getLine().str() + "\n>>> " +
78 std::string s = (getCurrentLocation() + ": " + msg).str();
79 if (pos)
80 s += "\n>>> " + getLine().str() + "\n>>> " +
8281 std::string(getColumnNumber(), ' ') + "^";
83 error(S);
82 error(s);
8483}
8584
8685// Split S into linker script tokens.
87void ScriptLexer::tokenize(MemoryBufferRef MB) {
88 std::vector<StringRef> Vec;
89 MBs.push_back(MB);
90 StringRef S = MB.getBuffer();
91 StringRef Begin = S;
86void ScriptLexer::tokenize(MemoryBufferRef mb) {
87 std::vector<StringRef> vec;
88 mbs.push_back(mb);
89 StringRef s = mb.getBuffer();
90 StringRef begin = s;
9291
9392 for (;;) {
94 S = skipSpace(S);
95 if (S.empty())
93 s = skipSpace(s);
94 if (s.empty())
9695 break;
9796
9897 // Quoted token. Note that double-quote characters are parts of a token
9998 // because, in a glob match context, only unquoted tokens are interpreted
10099 // as glob patterns. Double-quoted tokens are literal patterns in that
101100 // context.
102 if (S.startswith("\"")) {
103 size_t E = S.find("\"", 1);
104 if (E == StringRef::npos) {
105 StringRef Filename = MB.getBufferIdentifier();
106 size_t Lineno = Begin.substr(0, S.data() - Begin.data()).count('\n');
107 error(Filename + ":" + Twine(Lineno + 1) + ": unclosed quote");
101 if (s.startswith("\"")) {
102 size_t e = s.find("\"", 1);
103 if (e == StringRef::npos) {
104 StringRef filename = mb.getBufferIdentifier();
105 size_t lineno = begin.substr(0, s.data() - begin.data()).count('\n');
106 error(filename + ":" + Twine(lineno + 1) + ": unclosed quote");
108107 return;
109108 }
110109
111 Vec.push_back(S.take_front(E + 1));
112 S = S.substr(E + 1);
110 vec.push_back(s.take_front(e + 1));
111 s = s.substr(e + 1);
113112 continue;
114113 }
115114
116115 // ">foo" is parsed to ">" and "foo", but ">>" is parsed to ">>".
117116 // "|", "||", "&" and "&&" are different operators.
118 if (S.startswith("<<") || S.startswith("<=") || S.startswith(">>") ||
119 S.startswith(">=") || S.startswith("||") || S.startswith("&&")) {
120 Vec.push_back(S.substr(0, 2));
121 S = S.substr(2);
117 if (s.startswith("<<") || s.startswith("<=") || s.startswith(">>") ||
118 s.startswith(">=") || s.startswith("||") || s.startswith("&&")) {
119 vec.push_back(s.substr(0, 2));
120 s = s.substr(2);
122121 continue;
123122 }
124123
125124 // Unquoted token. This is more relaxed than tokens in C-like language,
126125 // so that you can write "file-name.cpp" as one bare token, for example.
127 size_t Pos = S.find_first_not_of(
126 size_t pos = s.find_first_not_of(
128127 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
129128 "0123456789_.$/\\~=+[]*?-!^:");
130129
131130 // A character that cannot start a word (which is usually a
132131 // punctuation) forms a single character token.
133 if (Pos == 0)
134 Pos = 1;
135 Vec.push_back(S.substr(0, Pos));
136 S = S.substr(Pos);
132 if (pos == 0)
133 pos = 1;
134 vec.push_back(s.substr(0, pos));
135 s = s.substr(pos);
137136 }
138137
139 Tokens.insert(Tokens.begin() + Pos, Vec.begin(), Vec.end());
138 tokens.insert(tokens.begin() + pos, vec.begin(), vec.end());
140139}
141140
142141// Skip leading whitespace characters or comments.
143StringRef ScriptLexer::skipSpace(StringRef S) {
142StringRef ScriptLexer::skipSpace(StringRef s) {
144143 for (;;) {
145 if (S.startswith("/*")) {
146 size_t E = S.find("*/", 2);
147 if (E == StringRef::npos) {
144 if (s.startswith("/*")) {
145 size_t e = s.find("*/", 2);
146 if (e == StringRef::npos) {
148147 error("unclosed comment in a linker script");
149148 return "";
150149 }
151 S = S.substr(E + 2);
150 s = s.substr(e + 2);
152151 continue;
153152 }
154 if (S.startswith("#")) {
155 size_t E = S.find('\n', 1);
156 if (E == StringRef::npos)
157 E = S.size() - 1;
158 S = S.substr(E + 1);
153 if (s.startswith("#")) {
154 size_t e = s.find('\n', 1);
155 if (e == StringRef::npos)
156 e = s.size() - 1;
157 s = s.substr(e + 1);
159158 continue;
160159 }
161 size_t Size = S.size();
162 S = S.ltrim();
163 if (S.size() == Size)
164 return S;
160 size_t size = s.size();
161 s = s.ltrim();
162 if (s.size() == size)
163 return s;
165164 }
166165}
167166
168167// An erroneous token is handled as if it were the last token before EOF.
169bool ScriptLexer::atEOF() { return errorCount() || Tokens.size() == Pos; }
168bool ScriptLexer::atEOF() { return errorCount() || tokens.size() == pos; }
170169
171170// Split a given string as an expression.
172171// This function returns "3", "*" and "5" for "3*5" for example.
173static std::vector<StringRef> tokenizeExpr(StringRef S) {
174 StringRef Ops = "+-*/:!~"; // List of operators
172static std::vector<StringRef> tokenizeExpr(StringRef s) {
173 StringRef ops = "+-*/:!~=<>"; // List of operators
175174
176175 // Quoted strings are literal strings, so we don't want to split it.
177 if (S.startswith("\""))
178 return {S};
176 if (s.startswith("\""))
177 return {s};
179178
180179 // Split S with operators as separators.
181 std::vector<StringRef> Ret;
182 while (!S.empty()) {
183 size_t E = S.find_first_of(Ops);
180 std::vector<StringRef> ret;
181 while (!s.empty()) {
182 size_t e = s.find_first_of(ops);
184183
185184 // No need to split if there is no operator.
186 if (E == StringRef::npos) {
187 Ret.push_back(S);
185 if (e == StringRef::npos) {
186 ret.push_back(s);
188187 break;
189188 }
190189
191190 // Get a token before the opreator.
192 if (E != 0)
193 Ret.push_back(S.substr(0, E));
194
195 // Get the operator as a token. Keep != as one token.
196 if (S.substr(E).startswith("!=")) {
197 Ret.push_back(S.substr(E, 2));
198 S = S.substr(E + 2);
191 if (e != 0)
192 ret.push_back(s.substr(0, e));
193
194 // Get the operator as a token.
195 // Keep !=, ==, >=, <=, << and >> operators as a single tokens.
196 if (s.substr(e).startswith("!=") || s.substr(e).startswith("==") ||
197 s.substr(e).startswith(">=") || s.substr(e).startswith("<=") ||
198 s.substr(e).startswith("<<") || s.substr(e).startswith(">>")) {
199 ret.push_back(s.substr(e, 2));
200 s = s.substr(e + 2);
199201 } else {
200 Ret.push_back(S.substr(E, 1));
201 S = S.substr(E + 1);
202 ret.push_back(s.substr(e, 1));
203 s = s.substr(e + 1);
202204 }
203205 }
204 return Ret;
206 return ret;
205207}
206208
207209// In contexts where expressions are expected, the lexer should apply
......@@ -214,14 +216,14 @@ static std::vector<StringRef> tokenizeExpr(StringRef S) {
214216//
215217// This function may split the current token into multiple tokens.
216218void ScriptLexer::maybeSplitExpr() {
217 if (!InExpr || errorCount() || atEOF())
219 if (!inExpr || errorCount() || atEOF())
218220 return;
219221
220 std::vector<StringRef> V = tokenizeExpr(Tokens[Pos]);
221 if (V.size() == 1)
222 std::vector<StringRef> v = tokenizeExpr(tokens[pos]);
223 if (v.size() == 1)
222224 return;
223 Tokens.erase(Tokens.begin() + Pos);
224 Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
225 tokens.erase(tokens.begin() + pos);
226 tokens.insert(tokens.begin() + pos, v.begin(), v.end());
225227}
226228
227229StringRef ScriptLexer::next() {
......@@ -233,28 +235,28 @@ StringRef ScriptLexer::next() {
233235 setError("unexpected EOF");
234236 return "";
235237 }
236 return Tokens[Pos++];
238 return tokens[pos++];
237239}
238240
239241StringRef ScriptLexer::peek() {
240 StringRef Tok = next();
242 StringRef tok = next();
241243 if (errorCount())
242244 return "";
243 Pos = Pos - 1;
244 return Tok;
245 pos = pos - 1;
246 return tok;
245247}
246248
247249StringRef ScriptLexer::peek2() {
248250 skip();
249 StringRef Tok = next();
251 StringRef tok = next();
250252 if (errorCount())
251253 return "";
252 Pos = Pos - 2;
253 return Tok;
254 pos = pos - 2;
255 return tok;
254256}
255257
256bool ScriptLexer::consume(StringRef Tok) {
257 if (peek() == Tok) {
258bool ScriptLexer::consume(StringRef tok) {
259 if (peek() == tok) {
258260 skip();
259261 return true;
260262 }
......@@ -262,12 +264,12 @@ bool ScriptLexer::consume(StringRef Tok) {
262264}
263265
264266// Consumes Tok followed by ":". Space is allowed between Tok and ":".
265bool ScriptLexer::consumeLabel(StringRef Tok) {
266 if (consume((Tok + ":").str()))
267bool ScriptLexer::consumeLabel(StringRef tok) {
268 if (consume((tok + ":").str()))
267269 return true;
268 if (Tokens.size() >= Pos + 2 && Tokens[Pos] == Tok &&
269 Tokens[Pos + 1] == ":") {
270 Pos += 2;
270 if (tokens.size() >= pos + 2 && tokens[pos] == tok &&
271 tokens[pos + 1] == ":") {
272 pos += 2;
271273 return true;
272274 }
273275 return false;
......@@ -275,24 +277,24 @@ bool ScriptLexer::consumeLabel(StringRef Tok) {
275277
276278void ScriptLexer::skip() { (void)next(); }
277279
278void ScriptLexer::expect(StringRef Expect) {
280void ScriptLexer::expect(StringRef expect) {
279281 if (errorCount())
280282 return;
281 StringRef Tok = next();
282 if (Tok != Expect)
283 setError(Expect + " expected, but got " + Tok);
283 StringRef tok = next();
284 if (tok != expect)
285 setError(expect + " expected, but got " + tok);
284286}
285287
286288// Returns true if S encloses T.
287static bool encloses(StringRef S, StringRef T) {
288 return S.bytes_begin() <= T.bytes_begin() && T.bytes_end() <= S.bytes_end();
289static bool encloses(StringRef s, StringRef t) {
290 return s.bytes_begin() <= t.bytes_begin() && t.bytes_end() <= s.bytes_end();
289291}
290292
291293MemoryBufferRef ScriptLexer::getCurrentMB() {
292294 // Find input buffer containing the current token.
293 assert(!MBs.empty() && Pos > 0);
294 for (MemoryBufferRef MB : MBs)
295 if (encloses(MB.getBuffer(), Tokens[Pos - 1]))
296 return MB;
295 assert(!mbs.empty() && pos > 0);
296 for (MemoryBufferRef mb : mbs)
297 if (encloses(mb.getBuffer(), tokens[pos - 1]))
298 return mb;
297299 llvm_unreachable("getCurrentMB: failed to find a token");
298300}
deps/lld/ELF/ScriptLexer.h+14-15
......@@ -1,9 +1,8 @@
11//===- ScriptLexer.h --------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -21,25 +20,25 @@ namespace elf {
2120
2221class ScriptLexer {
2322public:
24 explicit ScriptLexer(MemoryBufferRef MB);
23 explicit ScriptLexer(MemoryBufferRef mb);
2524
26 void setError(const Twine &Msg);
27 void tokenize(MemoryBufferRef MB);
28 static StringRef skipSpace(StringRef S);
25 void setError(const Twine &msg);
26 void tokenize(MemoryBufferRef mb);
27 static StringRef skipSpace(StringRef s);
2928 bool atEOF();
3029 StringRef next();
3130 StringRef peek();
3231 StringRef peek2();
3332 void skip();
34 bool consume(StringRef Tok);
35 void expect(StringRef Expect);
36 bool consumeLabel(StringRef Tok);
33 bool consume(StringRef tok);
34 void expect(StringRef expect);
35 bool consumeLabel(StringRef tok);
3736 std::string getCurrentLocation();
3837
39 std::vector<MemoryBufferRef> MBs;
40 std::vector<StringRef> Tokens;
41 bool InExpr = false;
42 size_t Pos = 0;
38 std::vector<MemoryBufferRef> mbs;
39 std::vector<StringRef> tokens;
40 bool inExpr = false;
41 size_t pos = 0;
4342
4443private:
4544 void maybeSplitExpr();
deps/lld/ELF/ScriptParser.cpp+633-636
......@@ -1,9 +1,8 @@
11//===- ScriptParser.cpp ---------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -41,22 +40,29 @@ using namespace llvm::support::endian;
4140using namespace lld;
4241using namespace lld::elf;
4342
44static bool isUnderSysroot(StringRef Path);
45
4643namespace {
4744class ScriptParser final : ScriptLexer {
4845public:
49 ScriptParser(MemoryBufferRef MB)
50 : ScriptLexer(MB),
51 IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {}
46 ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) {
47 // Initialize IsUnderSysroot
48 if (config->sysroot == "")
49 return;
50 StringRef path = mb.getBufferIdentifier();
51 for (; !path.empty(); path = sys::path::parent_path(path)) {
52 if (!sys::fs::equivalent(config->sysroot, path))
53 continue;
54 isUnderSysroot = true;
55 return;
56 }
57 }
5258
5359 void readLinkerScript();
5460 void readVersionScript();
5561 void readDynamicList();
56 void readDefsym(StringRef Name);
62 void readDefsym(StringRef name);
5763
5864private:
59 void addFile(StringRef Path);
65 void addFile(StringRef path);
6066
6167 void readAsNeeded();
6268 void readEntry();
......@@ -76,24 +82,23 @@ private:
7682 void readVersion();
7783 void readVersionScriptCommand();
7884
79 SymbolAssignment *readSymbolAssignment(StringRef Name);
80 ByteCommand *readByteCommand(StringRef Tok);
85 SymbolAssignment *readSymbolAssignment(StringRef name);
86 ByteCommand *readByteCommand(StringRef tok);
8187 std::array<uint8_t, 4> readFill();
82 std::array<uint8_t, 4> parseFill(StringRef Tok);
83 bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2);
84 void readSectionAddressType(OutputSection *Cmd);
88 bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2);
89 void readSectionAddressType(OutputSection *cmd);
8590 OutputSection *readOverlaySectionDescription();
86 OutputSection *readOutputSectionDescription(StringRef OutSec);
91 OutputSection *readOutputSectionDescription(StringRef outSec);
8792 std::vector<BaseCommand *> readOverlay();
8893 std::vector<StringRef> readOutputSectionPhdrs();
89 InputSectionDescription *readInputSectionDescription(StringRef Tok);
94 InputSectionDescription *readInputSectionDescription(StringRef tok);
9095 StringMatcher readFilePatterns();
9196 std::vector<SectionPattern> readInputSectionsList();
92 InputSectionDescription *readInputSectionRules(StringRef FilePattern);
97 InputSectionDescription *readInputSectionRules(StringRef filePattern);
9398 unsigned readPhdrType();
9499 SortSectionPolicy readSortKind();
95 SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
96 SymbolAssignment *readAssignment(StringRef Tok);
100 SymbolAssignment *readProvideHidden(bool provide, bool hidden);
101 SymbolAssignment *readAssignment(StringRef tok);
97102 void readSort();
98103 Expr readAssert();
99104 Expr readConstant();
......@@ -102,97 +107,88 @@ private:
102107 uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
103108 std::pair<uint32_t, uint32_t> readMemoryAttributes();
104109
105 Expr combine(StringRef Op, Expr L, Expr R);
110 Expr combine(StringRef op, Expr l, Expr r);
106111 Expr readExpr();
107 Expr readExpr1(Expr Lhs, int MinPrec);
112 Expr readExpr1(Expr lhs, int minPrec);
108113 StringRef readParenLiteral();
109114 Expr readPrimary();
110 Expr readTernary(Expr Cond);
115 Expr readTernary(Expr cond);
111116 Expr readParenExpr();
112117
113118 // For parsing version script.
114119 std::vector<SymbolVersion> readVersionExtern();
115120 void readAnonymousDeclaration();
116 void readVersionDeclaration(StringRef VerStr);
121 void readVersionDeclaration(StringRef verStr);
117122
118123 std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
119124 readSymbols();
120125
121126 // True if a script being read is in a subdirectory specified by -sysroot.
122 bool IsUnderSysroot;
127 bool isUnderSysroot = false;
123128
124129 // A set to detect an INCLUDE() cycle.
125 StringSet<> Seen;
130 StringSet<> seen;
126131};
127132} // namespace
128133
129static StringRef unquote(StringRef S) {
130 if (S.startswith("\""))
131 return S.substr(1, S.size() - 2);
132 return S;
133}
134
135static bool isUnderSysroot(StringRef Path) {
136 if (Config->Sysroot == "")
137 return false;
138 for (; !Path.empty(); Path = sys::path::parent_path(Path))
139 if (sys::fs::equivalent(Config->Sysroot, Path))
140 return true;
141 return false;
134static StringRef unquote(StringRef s) {
135 if (s.startswith("\""))
136 return s.substr(1, s.size() - 2);
137 return s;
142138}
143139
144140// Some operations only support one non absolute value. Move the
145141// absolute one to the right hand side for convenience.
146static void moveAbsRight(ExprValue &A, ExprValue &B) {
147 if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute()))
148 std::swap(A, B);
149 if (!B.isAbsolute())
150 error(A.Loc + ": at least one side of the expression must be absolute");
142static void moveAbsRight(ExprValue &a, ExprValue &b) {
143 if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
144 std::swap(a, b);
145 if (!b.isAbsolute())
146 error(a.loc + ": at least one side of the expression must be absolute");
151147}
152148
153static ExprValue add(ExprValue A, ExprValue B) {
154 moveAbsRight(A, B);
155 return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc};
149static ExprValue add(ExprValue a, ExprValue b) {
150 moveAbsRight(a, b);
151 return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc};
156152}
157153
158static ExprValue sub(ExprValue A, ExprValue B) {
154static ExprValue sub(ExprValue a, ExprValue b) {
159155 // The distance between two symbols in sections is absolute.
160 if (!A.isAbsolute() && !B.isAbsolute())
161 return A.getValue() - B.getValue();
162 return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc};
156 if (!a.isAbsolute() && !b.isAbsolute())
157 return a.getValue() - b.getValue();
158 return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc};
163159}
164160
165static ExprValue bitAnd(ExprValue A, ExprValue B) {
166 moveAbsRight(A, B);
167 return {A.Sec, A.ForceAbsolute,
168 (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc};
161static ExprValue bitAnd(ExprValue a, ExprValue b) {
162 moveAbsRight(a, b);
163 return {a.sec, a.forceAbsolute,
164 (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc};
169165}
170166
171static ExprValue bitOr(ExprValue A, ExprValue B) {
172 moveAbsRight(A, B);
173 return {A.Sec, A.ForceAbsolute,
174 (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc};
167static ExprValue bitOr(ExprValue a, ExprValue b) {
168 moveAbsRight(a, b);
169 return {a.sec, a.forceAbsolute,
170 (a.getValue() | b.getValue()) - a.getSecAddr(), a.loc};
175171}
176172
177173void ScriptParser::readDynamicList() {
178 Config->HasDynamicList = true;
174 config->hasDynamicList = true;
179175 expect("{");
180 std::vector<SymbolVersion> Locals;
181 std::vector<SymbolVersion> Globals;
182 std::tie(Locals, Globals) = readSymbols();
176 std::vector<SymbolVersion> locals;
177 std::vector<SymbolVersion> globals;
178 std::tie(locals, globals) = readSymbols();
183179 expect(";");
184180
185181 if (!atEOF()) {
186182 setError("EOF expected, but got " + next());
187183 return;
188184 }
189 if (!Locals.empty()) {
185 if (!locals.empty()) {
190186 setError("\"local:\" scope not supported in --dynamic-list");
191187 return;
192188 }
193189
194 for (SymbolVersion V : Globals)
195 Config->DynamicList.push_back(V);
190 for (SymbolVersion v : globals)
191 config->dynamicList.push_back(v);
196192}
197193
198194void ScriptParser::readVersionScript() {
......@@ -208,14 +204,14 @@ void ScriptParser::readVersionScriptCommand() {
208204 }
209205
210206 while (!atEOF() && !errorCount() && peek() != "}") {
211 StringRef VerStr = next();
212 if (VerStr == "{") {
207 StringRef verStr = next();
208 if (verStr == "{") {
213209 setError("anonymous version definition is used in "
214210 "combination with other version definitions");
215211 return;
216212 }
217213 expect("{");
218 readVersionDeclaration(VerStr);
214 readVersionDeclaration(verStr);
219215 }
220216}
221217
......@@ -227,135 +223,135 @@ void ScriptParser::readVersion() {
227223
228224void ScriptParser::readLinkerScript() {
229225 while (!atEOF()) {
230 StringRef Tok = next();
231 if (Tok == ";")
226 StringRef tok = next();
227 if (tok == ";")
232228 continue;
233229
234 if (Tok == "ENTRY") {
230 if (tok == "ENTRY") {
235231 readEntry();
236 } else if (Tok == "EXTERN") {
232 } else if (tok == "EXTERN") {
237233 readExtern();
238 } else if (Tok == "GROUP") {
234 } else if (tok == "GROUP") {
239235 readGroup();
240 } else if (Tok == "INCLUDE") {
236 } else if (tok == "INCLUDE") {
241237 readInclude();
242 } else if (Tok == "INPUT") {
238 } else if (tok == "INPUT") {
243239 readInput();
244 } else if (Tok == "MEMORY") {
240 } else if (tok == "MEMORY") {
245241 readMemory();
246 } else if (Tok == "OUTPUT") {
242 } else if (tok == "OUTPUT") {
247243 readOutput();
248 } else if (Tok == "OUTPUT_ARCH") {
244 } else if (tok == "OUTPUT_ARCH") {
249245 readOutputArch();
250 } else if (Tok == "OUTPUT_FORMAT") {
246 } else if (tok == "OUTPUT_FORMAT") {
251247 readOutputFormat();
252 } else if (Tok == "PHDRS") {
248 } else if (tok == "PHDRS") {
253249 readPhdrs();
254 } else if (Tok == "REGION_ALIAS") {
250 } else if (tok == "REGION_ALIAS") {
255251 readRegionAlias();
256 } else if (Tok == "SEARCH_DIR") {
252 } else if (tok == "SEARCH_DIR") {
257253 readSearchDir();
258 } else if (Tok == "SECTIONS") {
254 } else if (tok == "SECTIONS") {
259255 readSections();
260 } else if (Tok == "TARGET") {
256 } else if (tok == "TARGET") {
261257 readTarget();
262 } else if (Tok == "VERSION") {
258 } else if (tok == "VERSION") {
263259 readVersion();
264 } else if (SymbolAssignment *Cmd = readAssignment(Tok)) {
265 Script->SectionCommands.push_back(Cmd);
260 } else if (SymbolAssignment *cmd = readAssignment(tok)) {
261 script->sectionCommands.push_back(cmd);
266262 } else {
267 setError("unknown directive: " + Tok);
263 setError("unknown directive: " + tok);
268264 }
269265 }
270266}
271267
272void ScriptParser::readDefsym(StringRef Name) {
268void ScriptParser::readDefsym(StringRef name) {
273269 if (errorCount())
274270 return;
275 Expr E = readExpr();
271 Expr e = readExpr();
276272 if (!atEOF())
277273 setError("EOF expected, but got " + next());
278 SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation());
279 Script->SectionCommands.push_back(Cmd);
274 SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation());
275 script->sectionCommands.push_back(cmd);
280276}
281277
282void ScriptParser::addFile(StringRef S) {
283 if (IsUnderSysroot && S.startswith("/")) {
284 SmallString<128> PathData;
285 StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
286 if (sys::fs::exists(Path)) {
287 Driver->addFile(Saver.save(Path), /*WithLOption=*/false);
278void ScriptParser::addFile(StringRef s) {
279 if (isUnderSysroot && s.startswith("/")) {
280 SmallString<128> pathData;
281 StringRef path = (config->sysroot + s).toStringRef(pathData);
282 if (sys::fs::exists(path)) {
283 driver->addFile(saver.save(path), /*withLOption=*/false);
288284 return;
289285 }
290286 }
291287
292 if (S.startswith("/")) {
293 Driver->addFile(S, /*WithLOption=*/false);
294 } else if (S.startswith("=")) {
295 if (Config->Sysroot.empty())
296 Driver->addFile(S.substr(1), /*WithLOption=*/false);
288 if (s.startswith("/")) {
289 driver->addFile(s, /*withLOption=*/false);
290 } else if (s.startswith("=")) {
291 if (config->sysroot.empty())
292 driver->addFile(s.substr(1), /*withLOption=*/false);
297293 else
298 Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)),
299 /*WithLOption=*/false);
300 } else if (S.startswith("-l")) {
301 Driver->addLibrary(S.substr(2));
302 } else if (sys::fs::exists(S)) {
303 Driver->addFile(S, /*WithLOption=*/false);
294 driver->addFile(saver.save(config->sysroot + "/" + s.substr(1)),
295 /*withLOption=*/false);
296 } else if (s.startswith("-l")) {
297 driver->addLibrary(s.substr(2));
298 } else if (sys::fs::exists(s)) {
299 driver->addFile(s, /*withLOption=*/false);
304300 } else {
305 if (Optional<std::string> Path = findFromSearchPaths(S))
306 Driver->addFile(Saver.save(*Path), /*WithLOption=*/true);
301 if (Optional<std::string> path = findFromSearchPaths(s))
302 driver->addFile(saver.save(*path), /*withLOption=*/true);
307303 else
308 setError("unable to find " + S);
304 setError("unable to find " + s);
309305 }
310306}
311307
312308void ScriptParser::readAsNeeded() {
313309 expect("(");
314 bool Orig = Config->AsNeeded;
315 Config->AsNeeded = true;
310 bool orig = config->asNeeded;
311 config->asNeeded = true;
316312 while (!errorCount() && !consume(")"))
317313 addFile(unquote(next()));
318 Config->AsNeeded = Orig;
314 config->asNeeded = orig;
319315}
320316
321317void ScriptParser::readEntry() {
322318 // -e <symbol> takes predecence over ENTRY(<symbol>).
323319 expect("(");
324 StringRef Tok = next();
325 if (Config->Entry.empty())
326 Config->Entry = Tok;
320 StringRef tok = next();
321 if (config->entry.empty())
322 config->entry = tok;
327323 expect(")");
328324}
329325
330326void ScriptParser::readExtern() {
331327 expect("(");
332328 while (!errorCount() && !consume(")"))
333 Config->Undefined.push_back(next());
329 config->undefined.push_back(unquote(next()));
334330}
335331
336332void ScriptParser::readGroup() {
337 bool Orig = InputFile::IsInGroup;
338 InputFile::IsInGroup = true;
333 bool orig = InputFile::isInGroup;
334 InputFile::isInGroup = true;
339335 readInput();
340 InputFile::IsInGroup = Orig;
341 if (!Orig)
342 ++InputFile::NextGroupId;
336 InputFile::isInGroup = orig;
337 if (!orig)
338 ++InputFile::nextGroupId;
343339}
344340
345341void ScriptParser::readInclude() {
346 StringRef Tok = unquote(next());
342 StringRef tok = unquote(next());
347343
348 if (!Seen.insert(Tok).second) {
344 if (!seen.insert(tok).second) {
349345 setError("there is a cycle in linker script INCLUDEs");
350346 return;
351347 }
352348
353 if (Optional<std::string> Path = searchScript(Tok)) {
354 if (Optional<MemoryBufferRef> MB = readFile(*Path))
355 tokenize(*MB);
349 if (Optional<std::string> path = searchScript(tok)) {
350 if (Optional<MemoryBufferRef> mb = readFile(*path))
351 tokenize(*mb);
356352 return;
357353 }
358 setError("cannot find linker script " + Tok);
354 setError("cannot find linker script " + tok);
359355}
360356
361357void ScriptParser::readInput() {
......@@ -371,9 +367,9 @@ void ScriptParser::readInput() {
371367void ScriptParser::readOutput() {
372368 // -o <file> takes predecence over OUTPUT(<file>).
373369 expect("(");
374 StringRef Tok = next();
375 if (Config->OutputFile.empty())
376 Config->OutputFile = unquote(Tok);
370 StringRef tok = next();
371 if (config->outputFile.empty())
372 config->outputFile = unquote(tok);
377373 expect(")");
378374}
379375
......@@ -384,8 +380,8 @@ void ScriptParser::readOutputArch() {
384380 skip();
385381}
386382
387static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
388 return StringSwitch<std::pair<ELFKind, uint16_t>>(S)
383static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
384 return StringSwitch<std::pair<ELFKind, uint16_t>>(s)
389385 .Case("elf32-i386", {ELF32LEKind, EM_386})
390386 .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
391387 .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
......@@ -402,6 +398,8 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
402398 .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
403399 .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
404400 .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
401 .Case("elf32-littleriscv", {ELF32LEKind, EM_RISCV})
402 .Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV})
405403 .Default({ELFNoneKind, EM_NONE});
406404}
407405
......@@ -410,16 +408,16 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
410408void ScriptParser::readOutputFormat() {
411409 expect("(");
412410
413 StringRef Name = unquote(next());
414 StringRef S = Name;
415 if (S.consume_back("-freebsd"))
416 Config->OSABI = ELFOSABI_FREEBSD;
411 StringRef name = unquote(next());
412 StringRef s = name;
413 if (s.consume_back("-freebsd"))
414 config->osabi = ELFOSABI_FREEBSD;
417415
418 std::tie(Config->EKind, Config->EMachine) = parseBfdName(S);
419 if (Config->EMachine == EM_NONE)
420 setError("unknown output format name: " + Name);
421 if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips")
422 Config->MipsN32Abi = true;
416 std::tie(config->ekind, config->emachine) = parseBfdName(s);
417 if (config->emachine == EM_NONE)
418 setError("unknown output format name: " + name);
419 if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips")
420 config->mipsN32Abi = true;
423421
424422 if (consume(")"))
425423 return;
......@@ -434,46 +432,46 @@ void ScriptParser::readPhdrs() {
434432 expect("{");
435433
436434 while (!errorCount() && !consume("}")) {
437 PhdrsCommand Cmd;
438 Cmd.Name = next();
439 Cmd.Type = readPhdrType();
435 PhdrsCommand cmd;
436 cmd.name = next();
437 cmd.type = readPhdrType();
440438
441439 while (!errorCount() && !consume(";")) {
442440 if (consume("FILEHDR"))
443 Cmd.HasFilehdr = true;
441 cmd.hasFilehdr = true;
444442 else if (consume("PHDRS"))
445 Cmd.HasPhdrs = true;
443 cmd.hasPhdrs = true;
446444 else if (consume("AT"))
447 Cmd.LMAExpr = readParenExpr();
445 cmd.lmaExpr = readParenExpr();
448446 else if (consume("FLAGS"))
449 Cmd.Flags = readParenExpr()().getValue();
447 cmd.flags = readParenExpr()().getValue();
450448 else
451449 setError("unexpected header attribute: " + next());
452450 }
453451
454 Script->PhdrsCommands.push_back(Cmd);
452 script->phdrsCommands.push_back(cmd);
455453 }
456454}
457455
458456void ScriptParser::readRegionAlias() {
459457 expect("(");
460 StringRef Alias = unquote(next());
458 StringRef alias = unquote(next());
461459 expect(",");
462 StringRef Name = next();
460 StringRef name = next();
463461 expect(")");
464462
465 if (Script->MemoryRegions.count(Alias))
466 setError("redefinition of memory region '" + Alias + "'");
467 if (!Script->MemoryRegions.count(Name))
468 setError("memory region '" + Name + "' is not defined");
469 Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]});
463 if (script->memoryRegions.count(alias))
464 setError("redefinition of memory region '" + alias + "'");
465 if (!script->memoryRegions.count(name))
466 setError("memory region '" + name + "' is not defined");
467 script->memoryRegions.insert({alias, script->memoryRegions[name]});
470468}
471469
472470void ScriptParser::readSearchDir() {
473471 expect("(");
474 StringRef Tok = next();
475 if (!Config->Nostdlib)
476 Config->SearchPaths.push_back(unquote(Tok));
472 StringRef tok = next();
473 if (!config->nostdlib)
474 config->searchPaths.push_back(unquote(tok));
477475 expect(")");
478476}
479477
......@@ -485,83 +483,83 @@ std::vector<BaseCommand *> ScriptParser::readOverlay() {
485483 // VA and LMA expressions are optional, though for simplicity of
486484 // implementation we assume they are not. That is what OVERLAY was designed
487485 // for first of all: to allow sections with overlapping VAs at different LMAs.
488 Expr AddrExpr = readExpr();
486 Expr addrExpr = readExpr();
489487 expect(":");
490488 expect("AT");
491 Expr LMAExpr = readParenExpr();
489 Expr lmaExpr = readParenExpr();
492490 expect("{");
493491
494 std::vector<BaseCommand *> V;
495 OutputSection *Prev = nullptr;
492 std::vector<BaseCommand *> v;
493 OutputSection *prev = nullptr;
496494 while (!errorCount() && !consume("}")) {
497495 // VA is the same for all sections. The LMAs are consecutive in memory
498496 // starting from the base load address specified.
499 OutputSection *OS = readOverlaySectionDescription();
500 OS->AddrExpr = AddrExpr;
501 if (Prev)
502 OS->LMAExpr = [=] { return Prev->getLMA() + Prev->Size; };
497 OutputSection *os = readOverlaySectionDescription();
498 os->addrExpr = addrExpr;
499 if (prev)
500 os->lmaExpr = [=] { return prev->getLMA() + prev->size; };
503501 else
504 OS->LMAExpr = LMAExpr;
505 V.push_back(OS);
506 Prev = OS;
502 os->lmaExpr = lmaExpr;
503 v.push_back(os);
504 prev = os;
507505 }
508506
509507 // According to the specification, at the end of the overlay, the location
510508 // counter should be equal to the overlay base address plus size of the
511509 // largest section seen in the overlay.
512510 // Here we want to create the Dot assignment command to achieve that.
513 Expr MoveDot = [=] {
514 uint64_t Max = 0;
515 for (BaseCommand *Cmd : V)
516 Max = std::max(Max, cast<OutputSection>(Cmd)->Size);
517 return AddrExpr().getValue() + Max;
511 Expr moveDot = [=] {
512 uint64_t max = 0;
513 for (BaseCommand *cmd : v)
514 max = std::max(max, cast<OutputSection>(cmd)->size);
515 return addrExpr().getValue() + max;
518516 };
519 V.push_back(make<SymbolAssignment>(".", MoveDot, getCurrentLocation()));
520 return V;
517 v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation()));
518 return v;
521519}
522520
523521void ScriptParser::readSections() {
524 Script->HasSectionsCommand = true;
522 script->hasSectionsCommand = true;
525523
526524 // -no-rosegment is used to avoid placing read only non-executable sections in
527525 // their own segment. We do the same if SECTIONS command is present in linker
528526 // script. See comment for computeFlags().
529 Config->SingleRoRx = true;
527 config->singleRoRx = true;
530528
531529 expect("{");
532 std::vector<BaseCommand *> V;
530 std::vector<BaseCommand *> v;
533531 while (!errorCount() && !consume("}")) {
534 StringRef Tok = next();
535 if (Tok == "OVERLAY") {
536 for (BaseCommand *Cmd : readOverlay())
537 V.push_back(Cmd);
532 StringRef tok = next();
533 if (tok == "OVERLAY") {
534 for (BaseCommand *cmd : readOverlay())
535 v.push_back(cmd);
538536 continue;
539 } else if (Tok == "INCLUDE") {
537 } else if (tok == "INCLUDE") {
540538 readInclude();
541539 continue;
542540 }
543541
544 if (BaseCommand *Cmd = readAssignment(Tok))
545 V.push_back(Cmd);
542 if (BaseCommand *cmd = readAssignment(tok))
543 v.push_back(cmd);
546544 else
547 V.push_back(readOutputSectionDescription(Tok));
545 v.push_back(readOutputSectionDescription(tok));
548546 }
549547
550548 if (!atEOF() && consume("INSERT")) {
551 std::vector<BaseCommand *> *Dest = nullptr;
549 std::vector<BaseCommand *> *dest = nullptr;
552550 if (consume("AFTER"))
553 Dest = &Script->InsertAfterCommands[next()];
551 dest = &script->insertAfterCommands[next()];
554552 else if (consume("BEFORE"))
555 Dest = &Script->InsertBeforeCommands[next()];
553 dest = &script->insertBeforeCommands[next()];
556554 else
557555 setError("expected AFTER/BEFORE, but got '" + next() + "'");
558 if (Dest)
559 Dest->insert(Dest->end(), V.begin(), V.end());
556 if (dest)
557 dest->insert(dest->end(), v.begin(), v.end());
560558 return;
561559 }
562560
563 Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(),
564 V.end());
561 script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
562 v.end());
565563}
566564
567565void ScriptParser::readTarget() {
......@@ -570,19 +568,19 @@ void ScriptParser::readTarget() {
570568 // for --format. We recognize only /^elf/ and "binary" in the linker
571569 // script as well.
572570 expect("(");
573 StringRef Tok = next();
571 StringRef tok = next();
574572 expect(")");
575573
576 if (Tok.startswith("elf"))
577 Config->FormatBinary = false;
578 else if (Tok == "binary")
579 Config->FormatBinary = true;
574 if (tok.startswith("elf"))
575 config->formatBinary = false;
576 else if (tok == "binary")
577 config->formatBinary = true;
580578 else
581 setError("unknown target: " + Tok);
579 setError("unknown target: " + tok);
582580}
583581
584static int precedence(StringRef Op) {
585 return StringSwitch<int>(Op)
582static int precedence(StringRef op) {
583 return StringSwitch<int>(op)
586584 .Cases("*", "/", "%", 8)
587585 .Cases("+", "-", 7)
588586 .Cases("<<", ">>", 6)
......@@ -595,10 +593,10 @@ static int precedence(StringRef Op) {
595593}
596594
597595StringMatcher ScriptParser::readFilePatterns() {
598 std::vector<StringRef> V;
596 std::vector<StringRef> v;
599597 while (!errorCount() && !consume(")"))
600 V.push_back(next());
601 return StringMatcher(V);
598 v.push_back(next());
599 return StringMatcher(v);
602600}
603601
604602SortSectionPolicy ScriptParser::readSortKind() {
......@@ -627,24 +625,24 @@ SortSectionPolicy ScriptParser::readSortKind() {
627625// The semantics of that is section .foo in any file, section .bar in
628626// any file but a.o, and section .baz in any file but b.o.
629627std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
630 std::vector<SectionPattern> Ret;
628 std::vector<SectionPattern> ret;
631629 while (!errorCount() && peek() != ")") {
632 StringMatcher ExcludeFilePat;
630 StringMatcher excludeFilePat;
633631 if (consume("EXCLUDE_FILE")) {
634632 expect("(");
635 ExcludeFilePat = readFilePatterns();
633 excludeFilePat = readFilePatterns();
636634 }
637635
638 std::vector<StringRef> V;
636 std::vector<StringRef> v;
639637 while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE")
640 V.push_back(next());
638 v.push_back(unquote(next()));
641639
642 if (!V.empty())
643 Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
640 if (!v.empty())
641 ret.push_back({std::move(excludeFilePat), StringMatcher(v)});
644642 else
645643 setError("section pattern is expected");
646644 }
647 return Ret;
645 return ret;
648646}
649647
650648// Reads contents of "SECTIONS" directive. That directive contains a
......@@ -659,52 +657,52 @@ std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
659657//
660658// <section-list> is parsed by readInputSectionsList().
661659InputSectionDescription *
662ScriptParser::readInputSectionRules(StringRef FilePattern) {
663 auto *Cmd = make<InputSectionDescription>(FilePattern);
660ScriptParser::readInputSectionRules(StringRef filePattern) {
661 auto *cmd = make<InputSectionDescription>(filePattern);
664662 expect("(");
665663
666664 while (!errorCount() && !consume(")")) {
667 SortSectionPolicy Outer = readSortKind();
668 SortSectionPolicy Inner = SortSectionPolicy::Default;
669 std::vector<SectionPattern> V;
670 if (Outer != SortSectionPolicy::Default) {
665 SortSectionPolicy outer = readSortKind();
666 SortSectionPolicy inner = SortSectionPolicy::Default;
667 std::vector<SectionPattern> v;
668 if (outer != SortSectionPolicy::Default) {
671669 expect("(");
672 Inner = readSortKind();
673 if (Inner != SortSectionPolicy::Default) {
670 inner = readSortKind();
671 if (inner != SortSectionPolicy::Default) {
674672 expect("(");
675 V = readInputSectionsList();
673 v = readInputSectionsList();
676674 expect(")");
677675 } else {
678 V = readInputSectionsList();
676 v = readInputSectionsList();
679677 }
680678 expect(")");
681679 } else {
682 V = readInputSectionsList();
680 v = readInputSectionsList();
683681 }
684682
685 for (SectionPattern &Pat : V) {
686 Pat.SortInner = Inner;
687 Pat.SortOuter = Outer;
683 for (SectionPattern &pat : v) {
684 pat.sortInner = inner;
685 pat.sortOuter = outer;
688686 }
689687
690 std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
688 std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns));
691689 }
692 return Cmd;
690 return cmd;
693691}
694692
695693InputSectionDescription *
696ScriptParser::readInputSectionDescription(StringRef Tok) {
694ScriptParser::readInputSectionDescription(StringRef tok) {
697695 // Input section wildcard can be surrounded by KEEP.
698696 // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
699 if (Tok == "KEEP") {
697 if (tok == "KEEP") {
700698 expect("(");
701 StringRef FilePattern = next();
702 InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
699 StringRef filePattern = next();
700 InputSectionDescription *cmd = readInputSectionRules(filePattern);
703701 expect(")");
704 Script->KeptSections.push_back(Cmd);
705 return Cmd;
702 script->keptSections.push_back(cmd);
703 return cmd;
706704 }
707 return readInputSectionRules(Tok);
705 return readInputSectionRules(tok);
708706}
709707
710708void ScriptParser::readSort() {
......@@ -715,44 +713,33 @@ void ScriptParser::readSort() {
715713
716714Expr ScriptParser::readAssert() {
717715 expect("(");
718 Expr E = readExpr();
716 Expr e = readExpr();
719717 expect(",");
720 StringRef Msg = unquote(next());
718 StringRef msg = unquote(next());
721719 expect(")");
722720
723721 return [=] {
724 if (!E().getValue())
725 error(Msg);
726 return Script->getDot();
722 if (!e().getValue())
723 error(msg);
724 return script->getDot();
727725 };
728726}
729727
730// Reads a FILL(expr) command. We handle the FILL command as an
731// alias for =fillexp section attribute, which is different from
732// what GNU linkers do.
733// https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
734std::array<uint8_t, 4> ScriptParser::readFill() {
735 expect("(");
736 std::array<uint8_t, 4> V = parseFill(next());
737 expect(")");
738 return V;
739}
740
741728// Tries to read the special directive for an output section definition which
742729// can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)".
743730// Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below.
744bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) {
745 if (Tok1 != "(")
731bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) {
732 if (tok1 != "(")
746733 return false;
747 if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY")
734 if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" && tok2 != "OVERLAY")
748735 return false;
749736
750737 expect("(");
751738 if (consume("NOLOAD")) {
752 Cmd->Noload = true;
739 cmd->noload = true;
753740 } else {
754741 skip(); // This is "COPY", "INFO" or "OVERLAY".
755 Cmd->NonAlloc = true;
742 cmd->nonAlloc = true;
756743 }
757744 expect(")");
758745 return true;
......@@ -769,178 +756,186 @@ bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, Stri
769756//
770757// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
771758// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
772void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
773 if (readSectionDirective(Cmd, peek(), peek2()))
759void ScriptParser::readSectionAddressType(OutputSection *cmd) {
760 if (readSectionDirective(cmd, peek(), peek2()))
774761 return;
775762
776 Cmd->AddrExpr = readExpr();
777 if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2()))
763 cmd->addrExpr = readExpr();
764 if (peek() == "(" && !readSectionDirective(cmd, "(", peek2()))
778765 setError("unknown section directive: " + peek2());
779766}
780767
781static Expr checkAlignment(Expr E, std::string &Loc) {
768static Expr checkAlignment(Expr e, std::string &loc) {
782769 return [=] {
783 uint64_t Alignment = std::max((uint64_t)1, E().getValue());
784 if (!isPowerOf2_64(Alignment)) {
785 error(Loc + ": alignment must be power of 2");
770 uint64_t alignment = std::max((uint64_t)1, e().getValue());
771 if (!isPowerOf2_64(alignment)) {
772 error(loc + ": alignment must be power of 2");
786773 return (uint64_t)1; // Return a dummy value.
787774 }
788 return Alignment;
775 return alignment;
789776 };
790777}
791778
792779OutputSection *ScriptParser::readOverlaySectionDescription() {
793 OutputSection *Cmd =
794 Script->createOutputSection(next(), getCurrentLocation());
795 Cmd->InOverlay = true;
780 OutputSection *cmd =
781 script->createOutputSection(next(), getCurrentLocation());
782 cmd->inOverlay = true;
796783 expect("{");
797784 while (!errorCount() && !consume("}"))
798 Cmd->SectionCommands.push_back(readInputSectionRules(next()));
799 Cmd->Phdrs = readOutputSectionPhdrs();
800 return Cmd;
785 cmd->sectionCommands.push_back(readInputSectionRules(next()));
786 cmd->phdrs = readOutputSectionPhdrs();
787 return cmd;
801788}
802789
803OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
804 OutputSection *Cmd =
805 Script->createOutputSection(OutSec, getCurrentLocation());
790OutputSection *ScriptParser::readOutputSectionDescription(StringRef outSec) {
791 OutputSection *cmd =
792 script->createOutputSection(outSec, getCurrentLocation());
806793
807 size_t SymbolsReferenced = Script->ReferencedSymbols.size();
794 size_t symbolsReferenced = script->referencedSymbols.size();
808795
809796 if (peek() != ":")
810 readSectionAddressType(Cmd);
797 readSectionAddressType(cmd);
811798 expect(":");
812799
813 std::string Location = getCurrentLocation();
800 std::string location = getCurrentLocation();
814801 if (consume("AT"))
815 Cmd->LMAExpr = readParenExpr();
802 cmd->lmaExpr = readParenExpr();
816803 if (consume("ALIGN"))
817 Cmd->AlignExpr = checkAlignment(readParenExpr(), Location);
804 cmd->alignExpr = checkAlignment(readParenExpr(), location);
818805 if (consume("SUBALIGN"))
819 Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location);
806 cmd->subalignExpr = checkAlignment(readParenExpr(), location);
820807
821808 // Parse constraints.
822809 if (consume("ONLY_IF_RO"))
823 Cmd->Constraint = ConstraintKind::ReadOnly;
810 cmd->constraint = ConstraintKind::ReadOnly;
824811 if (consume("ONLY_IF_RW"))
825 Cmd->Constraint = ConstraintKind::ReadWrite;
812 cmd->constraint = ConstraintKind::ReadWrite;
826813 expect("{");
827814
828815 while (!errorCount() && !consume("}")) {
829 StringRef Tok = next();
830 if (Tok == ";") {
816 StringRef tok = next();
817 if (tok == ";") {
831818 // Empty commands are allowed. Do nothing here.
832 } else if (SymbolAssignment *Assign = readAssignment(Tok)) {
833 Cmd->SectionCommands.push_back(Assign);
834 } else if (ByteCommand *Data = readByteCommand(Tok)) {
835 Cmd->SectionCommands.push_back(Data);
836 } else if (Tok == "CONSTRUCTORS") {
819 } else if (SymbolAssignment *assign = readAssignment(tok)) {
820 cmd->sectionCommands.push_back(assign);
821 } else if (ByteCommand *data = readByteCommand(tok)) {
822 cmd->sectionCommands.push_back(data);
823 } else if (tok == "CONSTRUCTORS") {
837824 // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
838825 // by name. This is for very old file formats such as ECOFF/XCOFF.
839826 // For ELF, we should ignore.
840 } else if (Tok == "FILL") {
841 Cmd->Filler = readFill();
842 } else if (Tok == "SORT") {
827 } else if (tok == "FILL") {
828 // We handle the FILL command as an alias for =fillexp section attribute,
829 // which is different from what GNU linkers do.
830 // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
831 expect("(");
832 cmd->filler = readFill();
833 expect(")");
834 } else if (tok == "SORT") {
843835 readSort();
844 } else if (Tok == "INCLUDE") {
836 } else if (tok == "INCLUDE") {
845837 readInclude();
846838 } else if (peek() == "(") {
847 Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));
839 cmd->sectionCommands.push_back(readInputSectionDescription(tok));
848840 } else {
849841 // We have a file name and no input sections description. It is not a
850842 // commonly used syntax, but still acceptable. In that case, all sections
851843 // from the file will be included.
852 auto *ISD = make<InputSectionDescription>(Tok);
853 ISD->SectionPatterns.push_back({{}, StringMatcher({"*"})});
854 Cmd->SectionCommands.push_back(ISD);
844 auto *isd = make<InputSectionDescription>(tok);
845 isd->sectionPatterns.push_back({{}, StringMatcher({"*"})});
846 cmd->sectionCommands.push_back(isd);
855847 }
856848 }
857849
858850 if (consume(">"))
859 Cmd->MemoryRegionName = next();
851 cmd->memoryRegionName = next();
860852
861853 if (consume("AT")) {
862854 expect(">");
863 Cmd->LMARegionName = next();
855 cmd->lmaRegionName = next();
864856 }
865857
866 if (Cmd->LMAExpr && !Cmd->LMARegionName.empty())
858 if (cmd->lmaExpr && !cmd->lmaRegionName.empty())
867859 error("section can't have both LMA and a load region");
868860
869 Cmd->Phdrs = readOutputSectionPhdrs();
861 cmd->phdrs = readOutputSectionPhdrs();
870862
871 if (consume("="))
872 Cmd->Filler = parseFill(next());
873 else if (peek().startswith("="))
874 Cmd->Filler = parseFill(next().drop_front());
863 if (peek() == "=" || peek().startswith("=")) {
864 inExpr = true;
865 consume("=");
866 cmd->filler = readFill();
867 inExpr = false;
868 }
875869
876870 // Consume optional comma following output section command.
877871 consume(",");
878872
879 if (Script->ReferencedSymbols.size() > SymbolsReferenced)
880 Cmd->ExpressionsUseSymbols = true;
881 return Cmd;
873 if (script->referencedSymbols.size() > symbolsReferenced)
874 cmd->expressionsUseSymbols = true;
875 return cmd;
882876}
883877
884// Parses a given string as a octal/decimal/hexadecimal number and
885// returns it as a big-endian number. Used for `=<fillexp>`.
878// Reads a `=<fillexp>` expression and returns its value as a big-endian number.
886879// https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
880// We do not support using symbols in such expressions.
887881//
888882// When reading a hexstring, ld.bfd handles it as a blob of arbitrary
889883// size, while ld.gold always handles it as a 32-bit big-endian number.
890884// We are compatible with ld.gold because it's easier to implement.
891std::array<uint8_t, 4> ScriptParser::parseFill(StringRef Tok) {
892 uint32_t V = 0;
893 if (!to_integer(Tok, V))
894 setError("invalid filler expression: " + Tok);
885std::array<uint8_t, 4> ScriptParser::readFill() {
886 uint64_t value = readExpr()().val;
887 if (value > UINT32_MAX)
888 setError("filler expression result does not fit 32-bit: 0x" +
889 Twine::utohexstr(value));
895890
896 std::array<uint8_t, 4> Buf;
897 write32be(Buf.data(), V);
898 return Buf;
891 std::array<uint8_t, 4> buf;
892 write32be(buf.data(), (uint32_t)value);
893 return buf;
899894}
900895
901SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
896SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
902897 expect("(");
903 SymbolAssignment *Cmd = readSymbolAssignment(next());
904 Cmd->Provide = Provide;
905 Cmd->Hidden = Hidden;
898 SymbolAssignment *cmd = readSymbolAssignment(next());
899 cmd->provide = provide;
900 cmd->hidden = hidden;
906901 expect(")");
907 return Cmd;
902 return cmd;
908903}
909904
910SymbolAssignment *ScriptParser::readAssignment(StringRef Tok) {
905SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
911906 // Assert expression returns Dot, so this is equal to ".=."
912 if (Tok == "ASSERT")
907 if (tok == "ASSERT")
913908 return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
914909
915 size_t OldPos = Pos;
916 SymbolAssignment *Cmd = nullptr;
910 size_t oldPos = pos;
911 SymbolAssignment *cmd = nullptr;
917912 if (peek() == "=" || peek() == "+=")
918 Cmd = readSymbolAssignment(Tok);
919 else if (Tok == "PROVIDE")
920 Cmd = readProvideHidden(true, false);
921 else if (Tok == "HIDDEN")
922 Cmd = readProvideHidden(false, true);
923 else if (Tok == "PROVIDE_HIDDEN")
924 Cmd = readProvideHidden(true, true);
925
926 if (Cmd) {
927 Cmd->CommandString =
928 Tok.str() + " " +
929 llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
913 cmd = readSymbolAssignment(tok);
914 else if (tok == "PROVIDE")
915 cmd = readProvideHidden(true, false);
916 else if (tok == "HIDDEN")
917 cmd = readProvideHidden(false, true);
918 else if (tok == "PROVIDE_HIDDEN")
919 cmd = readProvideHidden(true, true);
920
921 if (cmd) {
922 cmd->commandString =
923 tok.str() + " " +
924 llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
930925 expect(";");
931926 }
932 return Cmd;
927 return cmd;
933928}
934929
935SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) {
936 StringRef Op = next();
937 assert(Op == "=" || Op == "+=");
938 Expr E = readExpr();
939 if (Op == "+=") {
940 std::string Loc = getCurrentLocation();
941 E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); };
930SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
931 StringRef op = next();
932 assert(op == "=" || op == "+=");
933 Expr e = readExpr();
934 if (op == "+=") {
935 std::string loc = getCurrentLocation();
936 e = [=] { return add(script->getSymbolValue(name, loc), e()); };
942937 }
943 return make<SymbolAssignment>(Name, E, getCurrentLocation());
938 return make<SymbolAssignment>(name, e, getCurrentLocation());
944939}
945940
946941// This is an operator-precedence parser to parse a linker
......@@ -948,178 +943,178 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) {
948943Expr ScriptParser::readExpr() {
949944 // Our lexer is context-aware. Set the in-expression bit so that
950945 // they apply different tokenization rules.
951 bool Orig = InExpr;
952 InExpr = true;
953 Expr E = readExpr1(readPrimary(), 0);
954 InExpr = Orig;
955 return E;
956}
957
958Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) {
959 if (Op == "+")
960 return [=] { return add(L(), R()); };
961 if (Op == "-")
962 return [=] { return sub(L(), R()); };
963 if (Op == "*")
964 return [=] { return L().getValue() * R().getValue(); };
965 if (Op == "/") {
966 std::string Loc = getCurrentLocation();
946 bool orig = inExpr;
947 inExpr = true;
948 Expr e = readExpr1(readPrimary(), 0);
949 inExpr = orig;
950 return e;
951}
952
953Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
954 if (op == "+")
955 return [=] { return add(l(), r()); };
956 if (op == "-")
957 return [=] { return sub(l(), r()); };
958 if (op == "*")
959 return [=] { return l().getValue() * r().getValue(); };
960 if (op == "/") {
961 std::string loc = getCurrentLocation();
967962 return [=]() -> uint64_t {
968 if (uint64_t RV = R().getValue())
969 return L().getValue() / RV;
970 error(Loc + ": division by zero");
963 if (uint64_t rv = r().getValue())
964 return l().getValue() / rv;
965 error(loc + ": division by zero");
971966 return 0;
972967 };
973968 }
974 if (Op == "%") {
975 std::string Loc = getCurrentLocation();
969 if (op == "%") {
970 std::string loc = getCurrentLocation();
976971 return [=]() -> uint64_t {
977 if (uint64_t RV = R().getValue())
978 return L().getValue() % RV;
979 error(Loc + ": modulo by zero");
972 if (uint64_t rv = r().getValue())
973 return l().getValue() % rv;
974 error(loc + ": modulo by zero");
980975 return 0;
981976 };
982977 }
983 if (Op == "<<")
984 return [=] { return L().getValue() << R().getValue(); };
985 if (Op == ">>")
986 return [=] { return L().getValue() >> R().getValue(); };
987 if (Op == "<")
988 return [=] { return L().getValue() < R().getValue(); };
989 if (Op == ">")
990 return [=] { return L().getValue() > R().getValue(); };
991 if (Op == ">=")
992 return [=] { return L().getValue() >= R().getValue(); };
993 if (Op == "<=")
994 return [=] { return L().getValue() <= R().getValue(); };
995 if (Op == "==")
996 return [=] { return L().getValue() == R().getValue(); };
997 if (Op == "!=")
998 return [=] { return L().getValue() != R().getValue(); };
999 if (Op == "||")
1000 return [=] { return L().getValue() || R().getValue(); };
1001 if (Op == "&&")
1002 return [=] { return L().getValue() && R().getValue(); };
1003 if (Op == "&")
1004 return [=] { return bitAnd(L(), R()); };
1005 if (Op == "|")
1006 return [=] { return bitOr(L(), R()); };
978 if (op == "<<")
979 return [=] { return l().getValue() << r().getValue(); };
980 if (op == ">>")
981 return [=] { return l().getValue() >> r().getValue(); };
982 if (op == "<")
983 return [=] { return l().getValue() < r().getValue(); };
984 if (op == ">")
985 return [=] { return l().getValue() > r().getValue(); };
986 if (op == ">=")
987 return [=] { return l().getValue() >= r().getValue(); };
988 if (op == "<=")
989 return [=] { return l().getValue() <= r().getValue(); };
990 if (op == "==")
991 return [=] { return l().getValue() == r().getValue(); };
992 if (op == "!=")
993 return [=] { return l().getValue() != r().getValue(); };
994 if (op == "||")
995 return [=] { return l().getValue() || r().getValue(); };
996 if (op == "&&")
997 return [=] { return l().getValue() && r().getValue(); };
998 if (op == "&")
999 return [=] { return bitAnd(l(), r()); };
1000 if (op == "|")
1001 return [=] { return bitOr(l(), r()); };
10071002 llvm_unreachable("invalid operator");
10081003}
10091004
10101005// This is a part of the operator-precedence parser. This function
10111006// assumes that the remaining token stream starts with an operator.
1012Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
1007Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
10131008 while (!atEOF() && !errorCount()) {
10141009 // Read an operator and an expression.
10151010 if (consume("?"))
1016 return readTernary(Lhs);
1017 StringRef Op1 = peek();
1018 if (precedence(Op1) < MinPrec)
1011 return readTernary(lhs);
1012 StringRef op1 = peek();
1013 if (precedence(op1) < minPrec)
10191014 break;
10201015 skip();
1021 Expr Rhs = readPrimary();
1016 Expr rhs = readPrimary();
10221017
10231018 // Evaluate the remaining part of the expression first if the
10241019 // next operator has greater precedence than the previous one.
10251020 // For example, if we have read "+" and "3", and if the next
10261021 // operator is "*", then we'll evaluate 3 * ... part first.
10271022 while (!atEOF()) {
1028 StringRef Op2 = peek();
1029 if (precedence(Op2) <= precedence(Op1))
1023 StringRef op2 = peek();
1024 if (precedence(op2) <= precedence(op1))
10301025 break;
1031 Rhs = readExpr1(Rhs, precedence(Op2));
1026 rhs = readExpr1(rhs, precedence(op2));
10321027 }
10331028
1034 Lhs = combine(Op1, Lhs, Rhs);
1029 lhs = combine(op1, lhs, rhs);
10351030 }
1036 return Lhs;
1031 return lhs;
10371032}
10381033
10391034Expr ScriptParser::getPageSize() {
1040 std::string Location = getCurrentLocation();
1035 std::string location = getCurrentLocation();
10411036 return [=]() -> uint64_t {
1042 if (Target)
1043 return Target->PageSize;
1044 error(Location + ": unable to calculate page size");
1037 if (target)
1038 return config->commonPageSize;
1039 error(location + ": unable to calculate page size");
10451040 return 4096; // Return a dummy value.
10461041 };
10471042}
10481043
10491044Expr ScriptParser::readConstant() {
1050 StringRef S = readParenLiteral();
1051 if (S == "COMMONPAGESIZE")
1045 StringRef s = readParenLiteral();
1046 if (s == "COMMONPAGESIZE")
10521047 return getPageSize();
1053 if (S == "MAXPAGESIZE")
1054 return [] { return Config->MaxPageSize; };
1055 setError("unknown constant: " + S);
1048 if (s == "MAXPAGESIZE")
1049 return [] { return config->maxPageSize; };
1050 setError("unknown constant: " + s);
10561051 return [] { return 0; };
10571052}
10581053
10591054// Parses Tok as an integer. It recognizes hexadecimal (prefixed with
10601055// "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
10611056// have "K" (Ki) or "M" (Mi) suffixes.
1062static Optional<uint64_t> parseInt(StringRef Tok) {
1057static Optional<uint64_t> parseInt(StringRef tok) {
10631058 // Hexadecimal
1064 uint64_t Val;
1065 if (Tok.startswith_lower("0x")) {
1066 if (!to_integer(Tok.substr(2), Val, 16))
1059 uint64_t val;
1060 if (tok.startswith_lower("0x")) {
1061 if (!to_integer(tok.substr(2), val, 16))
10671062 return None;
1068 return Val;
1063 return val;
10691064 }
1070 if (Tok.endswith_lower("H")) {
1071 if (!to_integer(Tok.drop_back(), Val, 16))
1065 if (tok.endswith_lower("H")) {
1066 if (!to_integer(tok.drop_back(), val, 16))
10721067 return None;
1073 return Val;
1068 return val;
10741069 }
10751070
10761071 // Decimal
1077 if (Tok.endswith_lower("K")) {
1078 if (!to_integer(Tok.drop_back(), Val, 10))
1072 if (tok.endswith_lower("K")) {
1073 if (!to_integer(tok.drop_back(), val, 10))
10791074 return None;
1080 return Val * 1024;
1075 return val * 1024;
10811076 }
1082 if (Tok.endswith_lower("M")) {
1083 if (!to_integer(Tok.drop_back(), Val, 10))
1077 if (tok.endswith_lower("M")) {
1078 if (!to_integer(tok.drop_back(), val, 10))
10841079 return None;
1085 return Val * 1024 * 1024;
1080 return val * 1024 * 1024;
10861081 }
1087 if (!to_integer(Tok, Val, 10))
1082 if (!to_integer(tok, val, 10))
10881083 return None;
1089 return Val;
1084 return val;
10901085}
10911086
1092ByteCommand *ScriptParser::readByteCommand(StringRef Tok) {
1093 int Size = StringSwitch<int>(Tok)
1087ByteCommand *ScriptParser::readByteCommand(StringRef tok) {
1088 int size = StringSwitch<int>(tok)
10941089 .Case("BYTE", 1)
10951090 .Case("SHORT", 2)
10961091 .Case("LONG", 4)
10971092 .Case("QUAD", 8)
10981093 .Default(-1);
1099 if (Size == -1)
1094 if (size == -1)
11001095 return nullptr;
11011096
1102 size_t OldPos = Pos;
1103 Expr E = readParenExpr();
1104 std::string CommandString =
1105 Tok.str() + " " +
1106 llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " ");
1107 return make<ByteCommand>(E, Size, CommandString);
1097 size_t oldPos = pos;
1098 Expr e = readParenExpr();
1099 std::string commandString =
1100 tok.str() + " " +
1101 llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
1102 return make<ByteCommand>(e, size, commandString);
11081103}
11091104
11101105StringRef ScriptParser::readParenLiteral() {
11111106 expect("(");
1112 bool Orig = InExpr;
1113 InExpr = false;
1114 StringRef Tok = next();
1115 InExpr = Orig;
1107 bool orig = inExpr;
1108 inExpr = false;
1109 StringRef tok = next();
1110 inExpr = orig;
11161111 expect(")");
1117 return Tok;
1112 return tok;
11181113}
11191114
1120static void checkIfExists(OutputSection *Cmd, StringRef Location) {
1121 if (Cmd->Location.empty() && Script->ErrorOnMissingSection)
1122 error(Location + ": undefined section " + Cmd->Name);
1115static void checkIfExists(OutputSection *cmd, StringRef location) {
1116 if (cmd->location.empty() && script->errorOnMissingSection)
1117 error(location + ": undefined section " + cmd->name);
11231118}
11241119
11251120Expr ScriptParser::readPrimary() {
......@@ -1127,84 +1122,85 @@ Expr ScriptParser::readPrimary() {
11271122 return readParenExpr();
11281123
11291124 if (consume("~")) {
1130 Expr E = readPrimary();
1131 return [=] { return ~E().getValue(); };
1125 Expr e = readPrimary();
1126 return [=] { return ~e().getValue(); };
11321127 }
11331128 if (consume("!")) {
1134 Expr E = readPrimary();
1135 return [=] { return !E().getValue(); };
1129 Expr e = readPrimary();
1130 return [=] { return !e().getValue(); };
11361131 }
11371132 if (consume("-")) {
1138 Expr E = readPrimary();
1139 return [=] { return -E().getValue(); };
1133 Expr e = readPrimary();
1134 return [=] { return -e().getValue(); };
11401135 }
11411136
1142 StringRef Tok = next();
1143 std::string Location = getCurrentLocation();
1137 StringRef tok = next();
1138 std::string location = getCurrentLocation();
11441139
11451140 // Built-in functions are parsed here.
11461141 // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
1147 if (Tok == "ABSOLUTE") {
1148 Expr Inner = readParenExpr();
1142 if (tok == "ABSOLUTE") {
1143 Expr inner = readParenExpr();
11491144 return [=] {
1150 ExprValue I = Inner();
1151 I.ForceAbsolute = true;
1152 return I;
1145 ExprValue i = inner();
1146 i.forceAbsolute = true;
1147 return i;
11531148 };
11541149 }
1155 if (Tok == "ADDR") {
1156 StringRef Name = readParenLiteral();
1157 OutputSection *Sec = Script->getOrCreateOutputSection(Name);
1150 if (tok == "ADDR") {
1151 StringRef name = readParenLiteral();
1152 OutputSection *sec = script->getOrCreateOutputSection(name);
1153 sec->usedInExpression = true;
11581154 return [=]() -> ExprValue {
1159 checkIfExists(Sec, Location);
1160 return {Sec, false, 0, Location};
1155 checkIfExists(sec, location);
1156 return {sec, false, 0, location};
11611157 };
11621158 }
1163 if (Tok == "ALIGN") {
1159 if (tok == "ALIGN") {
11641160 expect("(");
1165 Expr E = readExpr();
1161 Expr e = readExpr();
11661162 if (consume(")")) {
1167 E = checkAlignment(E, Location);
1168 return [=] { return alignTo(Script->getDot(), E().getValue()); };
1163 e = checkAlignment(e, location);
1164 return [=] { return alignTo(script->getDot(), e().getValue()); };
11691165 }
11701166 expect(",");
1171 Expr E2 = checkAlignment(readExpr(), Location);
1167 Expr e2 = checkAlignment(readExpr(), location);
11721168 expect(")");
11731169 return [=] {
1174 ExprValue V = E();
1175 V.Alignment = E2().getValue();
1176 return V;
1170 ExprValue v = e();
1171 v.alignment = e2().getValue();
1172 return v;
11771173 };
11781174 }
1179 if (Tok == "ALIGNOF") {
1180 StringRef Name = readParenLiteral();
1181 OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
1175 if (tok == "ALIGNOF") {
1176 StringRef name = readParenLiteral();
1177 OutputSection *cmd = script->getOrCreateOutputSection(name);
11821178 return [=] {
1183 checkIfExists(Cmd, Location);
1184 return Cmd->Alignment;
1179 checkIfExists(cmd, location);
1180 return cmd->alignment;
11851181 };
11861182 }
1187 if (Tok == "ASSERT")
1183 if (tok == "ASSERT")
11881184 return readAssert();
1189 if (Tok == "CONSTANT")
1185 if (tok == "CONSTANT")
11901186 return readConstant();
1191 if (Tok == "DATA_SEGMENT_ALIGN") {
1187 if (tok == "DATA_SEGMENT_ALIGN") {
11921188 expect("(");
1193 Expr E = readExpr();
1189 Expr e = readExpr();
11941190 expect(",");
11951191 readExpr();
11961192 expect(")");
11971193 return [=] {
1198 return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue()));
1194 return alignTo(script->getDot(), std::max((uint64_t)1, e().getValue()));
11991195 };
12001196 }
1201 if (Tok == "DATA_SEGMENT_END") {
1197 if (tok == "DATA_SEGMENT_END") {
12021198 expect("(");
12031199 expect(".");
12041200 expect(")");
1205 return [] { return Script->getDot(); };
1201 return [] { return script->getDot(); };
12061202 }
1207 if (Tok == "DATA_SEGMENT_RELRO_END") {
1203 if (tok == "DATA_SEGMENT_RELRO_END") {
12081204 // GNU linkers implements more complicated logic to handle
12091205 // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
12101206 // just align to the next page boundary for simplicity.
......@@ -1213,112 +1209,113 @@ Expr ScriptParser::readPrimary() {
12131209 expect(",");
12141210 readExpr();
12151211 expect(")");
1216 Expr E = getPageSize();
1217 return [=] { return alignTo(Script->getDot(), E().getValue()); };
1212 Expr e = getPageSize();
1213 return [=] { return alignTo(script->getDot(), e().getValue()); };
12181214 }
1219 if (Tok == "DEFINED") {
1220 StringRef Name = readParenLiteral();
1221 return [=] { return Symtab->find(Name) ? 1 : 0; };
1215 if (tok == "DEFINED") {
1216 StringRef name = readParenLiteral();
1217 return [=] { return symtab->find(name) ? 1 : 0; };
12221218 }
1223 if (Tok == "LENGTH") {
1224 StringRef Name = readParenLiteral();
1225 if (Script->MemoryRegions.count(Name) == 0) {
1226 setError("memory region not defined: " + Name);
1219 if (tok == "LENGTH") {
1220 StringRef name = readParenLiteral();
1221 if (script->memoryRegions.count(name) == 0) {
1222 setError("memory region not defined: " + name);
12271223 return [] { return 0; };
12281224 }
1229 return [=] { return Script->MemoryRegions[Name]->Length; };
1225 return [=] { return script->memoryRegions[name]->length; };
12301226 }
1231 if (Tok == "LOADADDR") {
1232 StringRef Name = readParenLiteral();
1233 OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
1227 if (tok == "LOADADDR") {
1228 StringRef name = readParenLiteral();
1229 OutputSection *cmd = script->getOrCreateOutputSection(name);
1230 cmd->usedInExpression = true;
12341231 return [=] {
1235 checkIfExists(Cmd, Location);
1236 return Cmd->getLMA();
1232 checkIfExists(cmd, location);
1233 return cmd->getLMA();
12371234 };
12381235 }
1239 if (Tok == "MAX" || Tok == "MIN") {
1236 if (tok == "MAX" || tok == "MIN") {
12401237 expect("(");
1241 Expr A = readExpr();
1238 Expr a = readExpr();
12421239 expect(",");
1243 Expr B = readExpr();
1240 Expr b = readExpr();
12441241 expect(")");
1245 if (Tok == "MIN")
1246 return [=] { return std::min(A().getValue(), B().getValue()); };
1247 return [=] { return std::max(A().getValue(), B().getValue()); };
1242 if (tok == "MIN")
1243 return [=] { return std::min(a().getValue(), b().getValue()); };
1244 return [=] { return std::max(a().getValue(), b().getValue()); };
12481245 }
1249 if (Tok == "ORIGIN") {
1250 StringRef Name = readParenLiteral();
1251 if (Script->MemoryRegions.count(Name) == 0) {
1252 setError("memory region not defined: " + Name);
1246 if (tok == "ORIGIN") {
1247 StringRef name = readParenLiteral();
1248 if (script->memoryRegions.count(name) == 0) {
1249 setError("memory region not defined: " + name);
12531250 return [] { return 0; };
12541251 }
1255 return [=] { return Script->MemoryRegions[Name]->Origin; };
1252 return [=] { return script->memoryRegions[name]->origin; };
12561253 }
1257 if (Tok == "SEGMENT_START") {
1254 if (tok == "SEGMENT_START") {
12581255 expect("(");
12591256 skip();
12601257 expect(",");
1261 Expr E = readExpr();
1258 Expr e = readExpr();
12621259 expect(")");
1263 return [=] { return E(); };
1260 return [=] { return e(); };
12641261 }
1265 if (Tok == "SIZEOF") {
1266 StringRef Name = readParenLiteral();
1267 OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
1262 if (tok == "SIZEOF") {
1263 StringRef name = readParenLiteral();
1264 OutputSection *cmd = script->getOrCreateOutputSection(name);
12681265 // Linker script does not create an output section if its content is empty.
12691266 // We want to allow SIZEOF(.foo) where .foo is a section which happened to
12701267 // be empty.
1271 return [=] { return Cmd->Size; };
1268 return [=] { return cmd->size; };
12721269 }
1273 if (Tok == "SIZEOF_HEADERS")
1270 if (tok == "SIZEOF_HEADERS")
12741271 return [=] { return elf::getHeaderSize(); };
12751272
12761273 // Tok is the dot.
1277 if (Tok == ".")
1278 return [=] { return Script->getSymbolValue(Tok, Location); };
1274 if (tok == ".")
1275 return [=] { return script->getSymbolValue(tok, location); };
12791276
12801277 // Tok is a literal number.
1281 if (Optional<uint64_t> Val = parseInt(Tok))
1282 return [=] { return *Val; };
1278 if (Optional<uint64_t> val = parseInt(tok))
1279 return [=] { return *val; };
12831280
12841281 // Tok is a symbol name.
1285 if (!isValidCIdentifier(Tok))
1286 setError("malformed number: " + Tok);
1287 Script->ReferencedSymbols.push_back(Tok);
1288 return [=] { return Script->getSymbolValue(Tok, Location); };
1282 if (!isValidCIdentifier(tok))
1283 setError("malformed number: " + tok);
1284 script->referencedSymbols.push_back(tok);
1285 return [=] { return script->getSymbolValue(tok, location); };
12891286}
12901287
1291Expr ScriptParser::readTernary(Expr Cond) {
1292 Expr L = readExpr();
1288Expr ScriptParser::readTernary(Expr cond) {
1289 Expr l = readExpr();
12931290 expect(":");
1294 Expr R = readExpr();
1295 return [=] { return Cond().getValue() ? L() : R(); };
1291 Expr r = readExpr();
1292 return [=] { return cond().getValue() ? l() : r(); };
12961293}
12971294
12981295Expr ScriptParser::readParenExpr() {
12991296 expect("(");
1300 Expr E = readExpr();
1297 Expr e = readExpr();
13011298 expect(")");
1302 return E;
1299 return e;
13031300}
13041301
13051302std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1306 std::vector<StringRef> Phdrs;
1303 std::vector<StringRef> phdrs;
13071304 while (!errorCount() && peek().startswith(":")) {
1308 StringRef Tok = next();
1309 Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
1305 StringRef tok = next();
1306 phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
13101307 }
1311 return Phdrs;
1308 return phdrs;
13121309}
13131310
13141311// Read a program header type name. The next token must be a
13151312// name of a program header type or a constant (e.g. "0x3").
13161313unsigned ScriptParser::readPhdrType() {
1317 StringRef Tok = next();
1318 if (Optional<uint64_t> Val = parseInt(Tok))
1319 return *Val;
1314 StringRef tok = next();
1315 if (Optional<uint64_t> val = parseInt(tok))
1316 return *val;
13201317
1321 unsigned Ret = StringSwitch<unsigned>(Tok)
1318 unsigned ret = StringSwitch<unsigned>(tok)
13221319 .Case("PT_NULL", PT_NULL)
13231320 .Case("PT_LOAD", PT_LOAD)
13241321 .Case("PT_DYNAMIC", PT_DYNAMIC)
......@@ -1335,56 +1332,56 @@ unsigned ScriptParser::readPhdrType() {
13351332 .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
13361333 .Default(-1);
13371334
1338 if (Ret == (unsigned)-1) {
1339 setError("invalid program header type: " + Tok);
1335 if (ret == (unsigned)-1) {
1336 setError("invalid program header type: " + tok);
13401337 return PT_NULL;
13411338 }
1342 return Ret;
1339 return ret;
13431340}
13441341
13451342// Reads an anonymous version declaration.
13461343void ScriptParser::readAnonymousDeclaration() {
1347 std::vector<SymbolVersion> Locals;
1348 std::vector<SymbolVersion> Globals;
1349 std::tie(Locals, Globals) = readSymbols();
1344 std::vector<SymbolVersion> locals;
1345 std::vector<SymbolVersion> globals;
1346 std::tie(locals, globals) = readSymbols();
13501347
1351 for (SymbolVersion V : Locals) {
1352 if (V.Name == "*")
1353 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1348 for (SymbolVersion v : locals) {
1349 if (v.name == "*")
1350 config->defaultSymbolVersion = VER_NDX_LOCAL;
13541351 else
1355 Config->VersionScriptLocals.push_back(V);
1352 config->versionScriptLocals.push_back(v);
13561353 }
13571354
1358 for (SymbolVersion V : Globals)
1359 Config->VersionScriptGlobals.push_back(V);
1355 for (SymbolVersion v : globals)
1356 config->versionScriptGlobals.push_back(v);
13601357
13611358 expect(";");
13621359}
13631360
13641361// Reads a non-anonymous version definition,
13651362// e.g. "VerStr { global: foo; bar; local: *; };".
1366void ScriptParser::readVersionDeclaration(StringRef VerStr) {
1363void ScriptParser::readVersionDeclaration(StringRef verStr) {
13671364 // Read a symbol list.
1368 std::vector<SymbolVersion> Locals;
1369 std::vector<SymbolVersion> Globals;
1370 std::tie(Locals, Globals) = readSymbols();
1365 std::vector<SymbolVersion> locals;
1366 std::vector<SymbolVersion> globals;
1367 std::tie(locals, globals) = readSymbols();
13711368
1372 for (SymbolVersion V : Locals) {
1373 if (V.Name == "*")
1374 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1369 for (SymbolVersion v : locals) {
1370 if (v.name == "*")
1371 config->defaultSymbolVersion = VER_NDX_LOCAL;
13751372 else
1376 Config->VersionScriptLocals.push_back(V);
1373 config->versionScriptLocals.push_back(v);
13771374 }
13781375
13791376 // Create a new version definition and add that to the global symbols.
1380 VersionDefinition Ver;
1381 Ver.Name = VerStr;
1382 Ver.Globals = Globals;
1377 VersionDefinition ver;
1378 ver.name = verStr;
1379 ver.globals = globals;
13831380
13841381 // User-defined version number starts from 2 because 0 and 1 are
13851382 // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively.
1386 Ver.Id = Config->VersionDefinitions.size() + 2;
1387 Config->VersionDefinitions.push_back(Ver);
1383 ver.id = config->versionDefinitions.size() + 2;
1384 config->versionDefinitions.push_back(ver);
13881385
13891386 // Each version may have a parent version. For example, "Ver2"
13901387 // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
......@@ -1396,39 +1393,39 @@ void ScriptParser::readVersionDeclaration(StringRef VerStr) {
13961393 expect(";");
13971394}
13981395
1399static bool hasWildcard(StringRef S) {
1400 return S.find_first_of("?*[") != StringRef::npos;
1396static bool hasWildcard(StringRef s) {
1397 return s.find_first_of("?*[") != StringRef::npos;
14011398}
14021399
14031400// Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
14041401std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
14051402ScriptParser::readSymbols() {
1406 std::vector<SymbolVersion> Locals;
1407 std::vector<SymbolVersion> Globals;
1408 std::vector<SymbolVersion> *V = &Globals;
1403 std::vector<SymbolVersion> locals;
1404 std::vector<SymbolVersion> globals;
1405 std::vector<SymbolVersion> *v = &globals;
14091406
14101407 while (!errorCount()) {
14111408 if (consume("}"))
14121409 break;
14131410 if (consumeLabel("local")) {
1414 V = &Locals;
1411 v = &locals;
14151412 continue;
14161413 }
14171414 if (consumeLabel("global")) {
1418 V = &Globals;
1415 v = &globals;
14191416 continue;
14201417 }
14211418
14221419 if (consume("extern")) {
1423 std::vector<SymbolVersion> Ext = readVersionExtern();
1424 V->insert(V->end(), Ext.begin(), Ext.end());
1420 std::vector<SymbolVersion> ext = readVersionExtern();
1421 v->insert(v->end(), ext.begin(), ext.end());
14251422 } else {
1426 StringRef Tok = next();
1427 V->push_back({unquote(Tok), false, hasWildcard(Tok)});
1423 StringRef tok = next();
1424 v->push_back({unquote(tok), false, hasWildcard(tok)});
14281425 }
14291426 expect(";");
14301427 }
1431 return {Locals, Globals};
1428 return {locals, globals};
14321429}
14331430
14341431// Reads an "extern C++" directive, e.g.,
......@@ -1437,30 +1434,30 @@ ScriptParser::readSymbols() {
14371434// The last semicolon is optional. E.g. this is OK:
14381435// "extern "C++" { ns::*; "f(int, double)" };"
14391436std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
1440 StringRef Tok = next();
1441 bool IsCXX = Tok == "\"C++\"";
1442 if (!IsCXX && Tok != "\"C\"")
1437 StringRef tok = next();
1438 bool isCXX = tok == "\"C++\"";
1439 if (!isCXX && tok != "\"C\"")
14431440 setError("Unknown language");
14441441 expect("{");
14451442
1446 std::vector<SymbolVersion> Ret;
1443 std::vector<SymbolVersion> ret;
14471444 while (!errorCount() && peek() != "}") {
1448 StringRef Tok = next();
1449 bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok);
1450 Ret.push_back({unquote(Tok), IsCXX, HasWildcard});
1445 StringRef tok = next();
1446 ret.push_back(
1447 {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)});
14511448 if (consume("}"))
1452 return Ret;
1449 return ret;
14531450 expect(";");
14541451 }
14551452
14561453 expect("}");
1457 return Ret;
1454 return ret;
14581455}
14591456
1460uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
1461 StringRef S3) {
1462 if (!consume(S1) && !consume(S2) && !consume(S3)) {
1463 setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
1457uint64_t ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
1458 StringRef s3) {
1459 if (!consume(s1) && !consume(s2) && !consume(s3)) {
1460 setError("expected one of: " + s1 + ", " + s2 + ", or " + s3);
14641461 return 0;
14651462 }
14661463 expect("=");
......@@ -1474,28 +1471,28 @@ uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
14741471void ScriptParser::readMemory() {
14751472 expect("{");
14761473 while (!errorCount() && !consume("}")) {
1477 StringRef Tok = next();
1478 if (Tok == "INCLUDE") {
1474 StringRef tok = next();
1475 if (tok == "INCLUDE") {
14791476 readInclude();
14801477 continue;
14811478 }
14821479
1483 uint32_t Flags = 0;
1484 uint32_t NegFlags = 0;
1480 uint32_t flags = 0;
1481 uint32_t negFlags = 0;
14851482 if (consume("(")) {
1486 std::tie(Flags, NegFlags) = readMemoryAttributes();
1483 std::tie(flags, negFlags) = readMemoryAttributes();
14871484 expect(")");
14881485 }
14891486 expect(":");
14901487
1491 uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
1488 uint64_t origin = readMemoryAssignment("ORIGIN", "org", "o");
14921489 expect(",");
1493 uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
1490 uint64_t length = readMemoryAssignment("LENGTH", "len", "l");
14941491
14951492 // Add the memory region to the region map.
1496 MemoryRegion *MR = make<MemoryRegion>(Tok, Origin, Length, Flags, NegFlags);
1497 if (!Script->MemoryRegions.insert({Tok, MR}).second)
1498 setError("region '" + Tok + "' already defined");
1493 MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, negFlags);
1494 if (!script->memoryRegions.insert({tok, mr}).second)
1495 setError("region '" + tok + "' already defined");
14991496 }
15001497}
15011498
......@@ -1503,43 +1500,43 @@ void ScriptParser::readMemory() {
15031500// flags when placing output sections in a memory region. These flags
15041501// are only used when an explicit memory region name is not used.
15051502std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
1506 uint32_t Flags = 0;
1507 uint32_t NegFlags = 0;
1508 bool Invert = false;
1509
1510 for (char C : next().lower()) {
1511 uint32_t Flag = 0;
1512 if (C == '!')
1513 Invert = !Invert;
1514 else if (C == 'w')
1515 Flag = SHF_WRITE;
1516 else if (C == 'x')
1517 Flag = SHF_EXECINSTR;
1518 else if (C == 'a')
1519 Flag = SHF_ALLOC;
1520 else if (C != 'r')
1503 uint32_t flags = 0;
1504 uint32_t negFlags = 0;
1505 bool invert = false;
1506
1507 for (char c : next().lower()) {
1508 uint32_t flag = 0;
1509 if (c == '!')
1510 invert = !invert;
1511 else if (c == 'w')
1512 flag = SHF_WRITE;
1513 else if (c == 'x')
1514 flag = SHF_EXECINSTR;
1515 else if (c == 'a')
1516 flag = SHF_ALLOC;
1517 else if (c != 'r')
15211518 setError("invalid memory region attribute");
15221519
1523 if (Invert)
1524 NegFlags |= Flag;
1520 if (invert)
1521 negFlags |= flag;
15251522 else
1526 Flags |= Flag;
1523 flags |= flag;
15271524 }
1528 return {Flags, NegFlags};
1525 return {flags, negFlags};
15291526}
15301527
1531void elf::readLinkerScript(MemoryBufferRef MB) {
1532 ScriptParser(MB).readLinkerScript();
1528void elf::readLinkerScript(MemoryBufferRef mb) {
1529 ScriptParser(mb).readLinkerScript();
15331530}
15341531
1535void elf::readVersionScript(MemoryBufferRef MB) {
1536 ScriptParser(MB).readVersionScript();
1532void elf::readVersionScript(MemoryBufferRef mb) {
1533 ScriptParser(mb).readVersionScript();
15371534}
15381535
1539void elf::readDynamicList(MemoryBufferRef MB) {
1540 ScriptParser(MB).readDynamicList();
1536void elf::readDynamicList(MemoryBufferRef mb) {
1537 ScriptParser(mb).readDynamicList();
15411538}
15421539
1543void elf::readDefsym(StringRef Name, MemoryBufferRef MB) {
1544 ScriptParser(MB).readDefsym(Name);
1540void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
1541 ScriptParser(mb).readDefsym(name);
15451542}
deps/lld/ELF/ScriptParser.h+8-9
......@@ -1,9 +1,8 @@
11//===- ScriptParser.h -------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -17,16 +16,16 @@ namespace lld {
1716namespace elf {
1817
1918// Parses a linker script. Calling this function updates
20// Config and ScriptConfig.
21void readLinkerScript(MemoryBufferRef MB);
19// lld::elf::config and lld::elf::script.
20void readLinkerScript(MemoryBufferRef mb);
2221
2322// Parses a version script.
24void readVersionScript(MemoryBufferRef MB);
23void readVersionScript(MemoryBufferRef mb);
2524
26void readDynamicList(MemoryBufferRef MB);
25void readDynamicList(MemoryBufferRef mb);
2726
2827// Parses the defsym expression.
29void readDefsym(StringRef Name, MemoryBufferRef MB);
28void readDefsym(StringRef name, MemoryBufferRef mb);
3029
3130} // namespace elf
3231} // namespace lld
deps/lld/ELF/SymbolTable.cpp+143-692
......@@ -1,9 +1,8 @@
11//===- SymbolTable.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -31,576 +30,76 @@ using namespace llvm::ELF;
3130using namespace lld;
3231using namespace lld::elf;
3332
34SymbolTable *elf::Symtab;
35
36static InputFile *getFirstElf() {
37 if (!ObjectFiles.empty())
38 return ObjectFiles[0];
39 if (!SharedFiles.empty())
40 return SharedFiles[0];
41 return BitcodeFiles[0];
42}
43
44// All input object files must be for the same architecture
45// (e.g. it does not make sense to link x86 object files with
46// MIPS object files.) This function checks for that error.
47static bool isCompatible(InputFile *F) {
48 if (!F->isElf() && !isa<BitcodeFile>(F))
49 return true;
50
51 if (F->EKind == Config->EKind && F->EMachine == Config->EMachine) {
52 if (Config->EMachine != EM_MIPS)
53 return true;
54 if (isMipsN32Abi(F) == Config->MipsN32Abi)
55 return true;
56 }
57
58 if (!Config->Emulation.empty())
59 error(toString(F) + " is incompatible with " + Config->Emulation);
60 else
61 error(toString(F) + " is incompatible with " + toString(getFirstElf()));
62 return false;
63}
64
65// Add symbols in File to the symbol table.
66template <class ELFT> void SymbolTable::addFile(InputFile *File) {
67 if (!isCompatible(File))
68 return;
69
70 // Binary file
71 if (auto *F = dyn_cast<BinaryFile>(File)) {
72 BinaryFiles.push_back(F);
73 F->parse();
74 return;
75 }
76
77 // .a file
78 if (auto *F = dyn_cast<ArchiveFile>(File)) {
79 F->parse<ELFT>();
80 return;
81 }
82
83 // Lazy object file
84 if (auto *F = dyn_cast<LazyObjFile>(File)) {
85 LazyObjFiles.push_back(F);
86 F->parse<ELFT>();
87 return;
88 }
89
90 if (Config->Trace)
91 message(toString(File));
92
93 // .so file
94 if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
95 // DSOs are uniquified not by filename but by soname.
96 F->parseSoName();
97 if (errorCount())
98 return;
99
100 // If a DSO appears more than once on the command line with and without
101 // --as-needed, --no-as-needed takes precedence over --as-needed because a
102 // user can add an extra DSO with --no-as-needed to force it to be added to
103 // the dependency list.
104 DenseMap<StringRef, InputFile *>::iterator It;
105 bool WasInserted;
106 std::tie(It, WasInserted) = SoNames.try_emplace(F->SoName, F);
107 cast<SharedFile<ELFT>>(It->second)->IsNeeded |= F->IsNeeded;
108 if (!WasInserted)
109 return;
110
111 SharedFiles.push_back(F);
112 F->parseRest();
113 return;
114 }
115
116 // LLVM bitcode file
117 if (auto *F = dyn_cast<BitcodeFile>(File)) {
118 BitcodeFiles.push_back(F);
119 F->parse<ELFT>(ComdatGroups);
120 return;
121 }
122
123 // Regular object file
124 ObjectFiles.push_back(File);
125 cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
126}
127
128// This function is where all the optimizations of link-time
129// optimization happens. When LTO is in use, some input files are
130// not in native object file format but in the LLVM bitcode format.
131// This function compiles bitcode files into a few big native files
132// using LLVM functions and replaces bitcode symbols with the results.
133// Because all bitcode files that the program consists of are passed
134// to the compiler at once, it can do whole-program optimization.
135template <class ELFT> void SymbolTable::addCombinedLTOObject() {
136 if (BitcodeFiles.empty())
137 return;
138
139 // Compile bitcode files and replace bitcode symbols.
140 LTO.reset(new BitcodeCompiler);
141 for (BitcodeFile *F : BitcodeFiles)
142 LTO->add(*F);
143
144 for (InputFile *File : LTO->compile()) {
145 DenseSet<CachedHashStringRef> DummyGroups;
146 auto *Obj = cast<ObjFile<ELFT>>(File);
147 Obj->parse(DummyGroups);
148 for (Symbol *Sym : Obj->getGlobalSymbols())
149 Sym->parseSymbolVersion();
150 ObjectFiles.push_back(File);
151 }
152}
153
154// Set a flag for --trace-symbol so that we can print out a log message
155// if a new symbol with the same name is inserted into the symbol table.
156void SymbolTable::trace(StringRef Name) {
157 SymMap.insert({CachedHashStringRef(Name), -1});
158}
33SymbolTable *elf::symtab;
15934
160void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
35void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
16136 // 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())];
37 int &idx1 = symMap[CachedHashStringRef(sym->getName())];
38 int &idx2 = symMap[CachedHashStringRef(real->getName())];
39 int &idx3 = symMap[CachedHashStringRef(wrap->getName())];
16540
166 Idx2 = Idx1;
167 Idx1 = Idx3;
41 idx2 = idx1;
42 idx1 = idx3;
16843
16944 // Now renaming is complete. No one refers Real symbol. We could leave
17045 // Real as-is, but if Real is written to the symbol table, that may
17146 // 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);
175}
176
177static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
178 if (VA == STV_DEFAULT)
179 return VB;
180 if (VB == STV_DEFAULT)
181 return VA;
182 return std::min(VA, VB);
47 StringRef s = real->getName();
48 memcpy(real, sym, sizeof(SymbolUnion));
49 real->setName(s);
18350}
18451
185// Find an existing symbol or create and insert a new one.
186std::pair<Symbol *, bool> SymbolTable::insertName(StringRef Name) {
52// Find an existing symbol or create a new one.
53Symbol *SymbolTable::insert(StringRef name) {
18754 // <name>@@<version> means the symbol is the default version. In that
18855 // case <name>@@<version> will be used to resolve references to <name>.
18956 //
19057 // Since this is a hot path, the following string search code is
19158 // optimized for speed. StringRef::find(char) is much faster than
19259 // StringRef::find(StringRef).
193 size_t Pos = Name.find('@');
194 if (Pos != StringRef::npos && Pos + 1 < Name.size() && Name[Pos + 1] == '@')
195 Name = Name.take_front(Pos);
196
197 auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
198 int &SymIndex = P.first->second;
199 bool IsNew = P.second;
200 bool Traced = false;
201
202 if (SymIndex == -1) {
203 SymIndex = SymVector.size();
204 IsNew = true;
205 Traced = true;
206 }
207
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};
60 size_t pos = name.find('@');
61 if (pos != StringRef::npos && pos + 1 < name.size() && name[pos + 1] == '@')
62 name = name.take_front(pos);
63
64 auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
65 int &symIndex = p.first->second;
66 bool isNew = p.second;
67
68 if (!isNew)
69 return symVector[symIndex];
70
71 Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
72 symVector.push_back(sym);
73
74 sym->setName(name);
75 sym->symbolKind = Symbol::PlaceholderKind;
76 sym->versionId = config->defaultSymbolVersion;
77 sym->visibility = STV_DEFAULT;
78 sym->isUsedInRegularObj = false;
79 sym->exportDynamic = false;
80 sym->canInline = true;
81 sym->scriptDefined = false;
82 sym->partition = 1;
83 return sym;
22184}
22285
223// Find an existing symbol or create and insert a new one, then apply the given
224// attributes.
225std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name,
226 uint8_t Visibility,
227 bool CanOmitFromDynSym,
228 InputFile *File) {
229 Symbol *S;
230 bool WasInserted;
231 std::tie(S, WasInserted) = insertName(Name);
232
233 // Merge in the new symbol's visibility.
234 S->Visibility = getMinVisibility(S->Visibility, Visibility);
235
236 if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic))
237 S->ExportDynamic = true;
238
239 if (!File || File->kind() == InputFile::ObjKind)
240 S->IsUsedInRegularObj = true;
241
242 return {S, WasInserted};
86Symbol *SymbolTable::addSymbol(const Symbol &New) {
87 Symbol *sym = symtab->insert(New.getName());
88 sym->resolve(New);
89 return sym;
24390}
24491
245static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
246
247template <class ELFT>
248Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
249 uint8_t StOther, uint8_t Type,
250 bool CanOmitFromDynSym, InputFile *File) {
251 Symbol *S;
252 bool WasInserted;
253 uint8_t Visibility = getVisibility(StOther);
254 std::tie(S, WasInserted) = insert(Name, Visibility, CanOmitFromDynSym, File);
255
256 // An undefined symbol with non default visibility must be satisfied
257 // in the same DSO.
258 if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) {
259 replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
260 return S;
261 }
262
263 if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
264 S->Binding = Binding;
265
266 if (S->isLazy()) {
267 // An undefined weak will not fetch archive members. See comment on Lazy in
268 // Symbols.h for the details.
269 if (Binding == STB_WEAK) {
270 S->Type = Type;
271 return S;
272 }
273
274 // Do extra check for --warn-backrefs.
275 //
276 // --warn-backrefs is an option to prevent an undefined reference from
277 // fetching an archive member written earlier in the command line. It can be
278 // used to keep compatibility with GNU linkers to some degree.
279 // I'll explain the feature and why you may find it useful in this comment.
280 //
281 // lld's symbol resolution semantics is more relaxed than traditional Unix
282 // linkers. For example,
283 //
284 // ld.lld foo.a bar.o
285 //
286 // succeeds even if bar.o contains an undefined symbol that has to be
287 // resolved by some object file in foo.a. Traditional Unix linkers don't
288 // allow this kind of backward reference, as they visit each file only once
289 // from left to right in the command line while resolving all undefined
290 // symbols at the moment of visiting.
291 //
292 // In the above case, since there's no undefined symbol when a linker visits
293 // foo.a, no files are pulled out from foo.a, and because the linker forgets
294 // about foo.a after visiting, it can't resolve undefined symbols in bar.o
295 // that could have been resolved otherwise.
296 //
297 // That lld accepts more relaxed form means that (besides it'd make more
298 // sense) you can accidentally write a command line or a build file that
299 // works only with lld, even if you have a plan to distribute it to wider
300 // users who may be using GNU linkers. With --warn-backrefs, you can detect
301 // a library order that doesn't work with other Unix linkers.
302 //
303 // The option is also useful to detect cyclic dependencies between static
304 // archives. Again, lld accepts
305 //
306 // ld.lld foo.a bar.a
307 //
308 // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
309 // handled as an error.
310 //
311 // Here is how the option works. We assign a group ID to each file. A file
312 // with a smaller group ID can pull out object files from an archive file
313 // with an equal or greater group ID. Otherwise, it is a reverse dependency
314 // and an error.
315 //
316 // A file outside --{start,end}-group gets a fresh ID when instantiated. All
317 // files within the same --{start,end}-group get the same group ID. E.g.
318 //
319 // ld.lld A B --start-group C D --end-group E
320 //
321 // A forms group 0. B form group 1. C and D (including their member object
322 // files) form group 2. E forms group 3. I think that you can see how this
323 // group assignment rule simulates the traditional linker's semantics.
324 bool Backref =
325 Config->WarnBackrefs && File && S->File->GroupId < File->GroupId;
326 fetchLazy<ELFT>(S);
327
328 // We don't report backward references to weak symbols as they can be
329 // overridden later.
330 if (Backref && S->Binding != STB_WEAK)
331 warn("backward reference detected: " + Name + " in " + toString(File) +
332 " refers to " + toString(S->File));
333 }
334 return S;
335}
336
337// Using .symver foo,foo@@VER unfortunately creates two symbols: foo and
338// foo@@VER. We want to effectively ignore foo, so give precedence to
339// foo@@VER.
340// FIXME: If users can transition to using
341// .symver foo,foo@@@VER
342// we can delete this hack.
343static int compareVersion(Symbol *S, StringRef Name) {
344 bool A = Name.contains("@@");
345 bool B = S->getName().contains("@@");
346 if (A && !B)
347 return 1;
348 if (!A && B)
349 return -1;
350 return 0;
351}
352
353// We have a new defined symbol with the specified binding. Return 1 if the new
354// symbol should win, -1 if the new symbol should lose, or 0 if both symbols are
355// strong defined symbols.
356static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding,
357 StringRef Name) {
358 if (WasInserted)
359 return 1;
360 if (!S->isDefined())
361 return 1;
362 if (int R = compareVersion(S, Name))
363 return R;
364 if (Binding == STB_WEAK)
365 return -1;
366 if (S->isWeak())
367 return 1;
368 return 0;
369}
370
371// We have a new non-common defined symbol with the specified binding. Return 1
372// if the new symbol should win, -1 if the new symbol should lose, or 0 if there
373// is a conflict. If the new symbol wins, also update the binding.
374static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding,
375 bool IsAbsolute, uint64_t Value,
376 StringRef Name) {
377 if (int Cmp = compareDefined(S, WasInserted, Binding, Name))
378 return Cmp;
379 if (auto *R = dyn_cast<Defined>(S)) {
380 if (R->Section && isa<BssSection>(R->Section)) {
381 // Non-common symbols take precedence over common symbols.
382 if (Config->WarnCommon)
383 warn("common " + S->getName() + " is overridden");
384 return 1;
385 }
386 if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute &&
387 R->Value == Value)
388 return -1;
389 }
390 return 0;
391}
392
393Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
394 uint8_t Binding, uint8_t StOther, uint8_t Type,
395 InputFile &File) {
396 Symbol *S;
397 bool WasInserted;
398 std::tie(S, WasInserted) = insert(N, getVisibility(StOther),
399 /*CanOmitFromDynSym*/ false, &File);
400
401 int Cmp = compareDefined(S, WasInserted, Binding, N);
402 if (Cmp < 0)
403 return S;
404
405 if (Cmp > 0) {
406 auto *Bss = make<BssSection>("COMMON", Size, Alignment);
407 Bss->File = &File;
408 Bss->Live = !Config->GcSections;
409 InputSections.push_back(Bss);
410
411 replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss);
412 return S;
413 }
414
415 auto *D = cast<Defined>(S);
416 auto *Bss = dyn_cast_or_null<BssSection>(D->Section);
417 if (!Bss) {
418 // Non-common symbols take precedence over common symbols.
419 if (Config->WarnCommon)
420 warn("common " + S->getName() + " is overridden");
421 return S;
422 }
423
424 if (Config->WarnCommon)
425 warn("multiple common of " + D->getName());
426
427 Bss->Alignment = std::max(Bss->Alignment, Alignment);
428 if (Size > Bss->Size) {
429 D->File = Bss->File = &File;
430 D->Size = Bss->Size = Size;
431 }
432 return S;
433}
434
435static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
436 InputSectionBase *ErrSec, uint64_t ErrOffset) {
437 if (Config->AllowMultipleDefinition)
438 return;
439
440 Defined *D = cast<Defined>(Sym);
441 if (!D->Section || !ErrSec) {
442 error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
443 toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
444 return;
445 }
446
447 // Construct and print an error message in the form of:
448 //
449 // ld.lld: error: duplicate symbol: foo
450 // >>> defined at bar.c:30
451 // >>> bar.o (/home/alice/src/bar.o)
452 // >>> defined at baz.c:563
453 // >>> baz.o in archive libbaz.a
454 auto *Sec1 = cast<InputSectionBase>(D->Section);
455 std::string Src1 = Sec1->getSrcMsg(*Sym, D->Value);
456 std::string Obj1 = Sec1->getObjMsg(D->Value);
457 std::string Src2 = ErrSec->getSrcMsg(*Sym, ErrOffset);
458 std::string Obj2 = ErrSec->getObjMsg(ErrOffset);
459
460 std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at ";
461 if (!Src1.empty())
462 Msg += Src1 + "\n>>> ";
463 Msg += Obj1 + "\n>>> defined at ";
464 if (!Src2.empty())
465 Msg += Src2 + "\n>>> ";
466 Msg += Obj2;
467 error(Msg);
468}
469
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) {
473 Symbol *S;
474 bool WasInserted;
475 std::tie(S, WasInserted) = insert(Name, getVisibility(StOther),
476 /*CanOmitFromDynSym*/ false, File);
477 int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
478 Value, Name);
479 if (Cmp > 0)
480 replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size,
481 Section);
482 else if (Cmp == 0)
483 reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section),
484 Value);
485 return cast<Defined>(S);
486}
487
488template <typename ELFT>
489void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
490 const typename ELFT::Sym &Sym, uint32_t Alignment,
491 uint32_t VerdefIndex) {
492 // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
493 // as the visibility, which will leave the visibility in the symbol table
494 // unchanged.
495 Symbol *S;
496 bool WasInserted;
497 std::tie(S, WasInserted) = insert(Name, STV_DEFAULT,
498 /*CanOmitFromDynSym*/ true, &File);
499 // Make sure we preempt DSO symbols with default visibility.
500 if (Sym.getVisibility() == STV_DEFAULT)
501 S->ExportDynamic = true;
502
503 // An undefined symbol with non default visibility must be satisfied
504 // in the same DSO.
505 auto Replace = [&](uint8_t Binding) {
506 replaceSymbol<SharedSymbol>(S, File, Name, Binding, Sym.st_other,
507 Sym.getType(), Sym.st_value, Sym.st_size,
508 Alignment, VerdefIndex);
509 };
510
511 if (WasInserted)
512 Replace(Sym.getBinding());
513 else if (S->Visibility == STV_DEFAULT && (S->isUndefined() || S->isLazy()))
514 Replace(S->Binding);
515}
516
517Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
518 uint8_t StOther, uint8_t Type,
519 bool CanOmitFromDynSym, BitcodeFile &F) {
520 Symbol *S;
521 bool WasInserted;
522 std::tie(S, WasInserted) =
523 insert(Name, getVisibility(StOther), CanOmitFromDynSym, &F);
524 int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
525 /*IsAbs*/ false, /*Value*/ 0, Name);
526 if (Cmp > 0)
527 replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);
528 else if (Cmp == 0)
529 reportDuplicate(S, &F, nullptr, 0);
530 return S;
531}
532
533Symbol *SymbolTable::find(StringRef Name) {
534 auto It = SymMap.find(CachedHashStringRef(Name));
535 if (It == SymMap.end())
92Symbol *SymbolTable::find(StringRef name) {
93 auto it = symMap.find(CachedHashStringRef(name));
94 if (it == symMap.end())
53695 return nullptr;
537 if (It->second == -1)
96 Symbol *sym = symVector[it->second];
97 if (sym->isPlaceholder())
53898 return nullptr;
539 return SymVector[It->second];
99 return sym;
540100}
541101
542template <class ELFT>
543void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &File,
544 const object::Archive::Symbol Sym) {
545 Symbol *S;
546 bool WasInserted;
547 std::tie(S, WasInserted) = insertName(Name);
548 if (WasInserted) {
549 replaceSymbol<LazyArchive>(S, File, STT_NOTYPE, Sym);
550 return;
551 }
552 if (!S->isUndefined())
553 return;
554
555 // An undefined weak will not fetch archive members. See comment on Lazy in
556 // Symbols.h for the details.
557 if (S->isWeak()) {
558 replaceSymbol<LazyArchive>(S, File, S->Type, Sym);
559 S->Binding = STB_WEAK;
560 return;
561 }
562
563 if (InputFile *F = File.fetch(Sym))
564 addFile<ELFT>(F);
565}
566
567template <class ELFT>
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;
578
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);
589}
590
591template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
592 if (auto *S = dyn_cast<LazyArchive>(Sym)) {
593 if (InputFile *File = S->fetch())
594 addFile<ELFT>(File);
595 return;
596 }
597
598 auto *S = cast<LazyObject>(Sym);
599 if (InputFile *File = cast<LazyObjFile>(S->File)->fetch())
600 addFile<ELFT>(File);
601}
602
603// Initialize DemangledSyms with a map from demangled symbols to symbol
102// Initialize demangledSyms with a map from demangled symbols to symbol
604103// objects. Used to handle "extern C++" directive in version scripts.
605104//
606105// The map will contain all demangled symbols. That can be very large,
......@@ -614,204 +113,156 @@ template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
614113// So, if "extern C++" feature is used, we need to demangle all known
615114// symbols.
616115StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
617 if (!DemangledSyms) {
618 DemangledSyms.emplace();
619 for (Symbol *Sym : SymVector) {
620 if (!Sym->isDefined())
116 if (!demangledSyms) {
117 demangledSyms.emplace();
118 for (Symbol *sym : symVector) {
119 if (!sym->isDefined() && !sym->isCommon())
621120 continue;
622 if (Optional<std::string> S = demangleItanium(Sym->getName()))
623 (*DemangledSyms)[*S].push_back(Sym);
121 if (Optional<std::string> s = demangleItanium(sym->getName()))
122 (*demangledSyms)[*s].push_back(sym);
624123 else
625 (*DemangledSyms)[Sym->getName()].push_back(Sym);
124 (*demangledSyms)[sym->getName()].push_back(sym);
626125 }
627126 }
628 return *DemangledSyms;
127 return *demangledSyms;
629128}
630129
631std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion Ver) {
632 if (Ver.IsExternCpp)
633 return getDemangledSyms().lookup(Ver.Name);
634 if (Symbol *B = find(Ver.Name))
635 if (B->isDefined())
636 return {B};
130std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion ver) {
131 if (ver.isExternCpp)
132 return getDemangledSyms().lookup(ver.name);
133 if (Symbol *b = find(ver.name))
134 if (b->isDefined() || b->isCommon())
135 return {b};
637136 return {};
638137}
639138
640std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion Ver) {
641 std::vector<Symbol *> Res;
642 StringMatcher M(Ver.Name);
139std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver) {
140 std::vector<Symbol *> res;
141 StringMatcher m(ver.name);
643142
644 if (Ver.IsExternCpp) {
645 for (auto &P : getDemangledSyms())
646 if (M.match(P.first()))
647 Res.insert(Res.end(), P.second.begin(), P.second.end());
648 return Res;
143 if (ver.isExternCpp) {
144 for (auto &p : getDemangledSyms())
145 if (m.match(p.first()))
146 res.insert(res.end(), p.second.begin(), p.second.end());
147 return res;
649148 }
650149
651 for (Symbol *Sym : SymVector)
652 if (Sym->isDefined() && M.match(Sym->getName()))
653 Res.push_back(Sym);
654 return Res;
655}
656
657// If there's only one anonymous version definition in a version
658// script file, the script does not actually define any symbol version,
659// but just specifies symbols visibilities.
660void SymbolTable::handleAnonymousVersion() {
661 for (SymbolVersion &Ver : Config->VersionScriptGlobals)
662 assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
663 for (SymbolVersion &Ver : Config->VersionScriptGlobals)
664 assignWildcardVersion(Ver, VER_NDX_GLOBAL);
665 for (SymbolVersion &Ver : Config->VersionScriptLocals)
666 assignExactVersion(Ver, VER_NDX_LOCAL, "local");
667 for (SymbolVersion &Ver : Config->VersionScriptLocals)
668 assignWildcardVersion(Ver, VER_NDX_LOCAL);
150 for (Symbol *sym : symVector)
151 if ((sym->isDefined() || sym->isCommon()) && m.match(sym->getName()))
152 res.push_back(sym);
153 return res;
669154}
670155
671156// Handles -dynamic-list.
672157void SymbolTable::handleDynamicList() {
673 for (SymbolVersion &Ver : Config->DynamicList) {
674 std::vector<Symbol *> Syms;
675 if (Ver.HasWildcard)
676 Syms = findAllByVersion(Ver);
158 for (SymbolVersion &ver : config->dynamicList) {
159 std::vector<Symbol *> syms;
160 if (ver.hasWildcard)
161 syms = findAllByVersion(ver);
677162 else
678 Syms = findByVersion(Ver);
163 syms = findByVersion(ver);
679164
680 for (Symbol *B : Syms) {
681 if (!Config->Shared)
682 B->ExportDynamic = true;
683 else if (B->includeInDynsym())
684 B->IsPreemptible = true;
165 for (Symbol *b : syms) {
166 if (!config->shared)
167 b->exportDynamic = true;
168 else if (b->includeInDynsym())
169 b->isPreemptible = true;
685170 }
686171 }
687172}
688173
689174// Set symbol versions to symbols. This function handles patterns
690175// containing no wildcard characters.
691void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
692 StringRef VersionName) {
693 if (Ver.HasWildcard)
176void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
177 StringRef versionName) {
178 if (ver.hasWildcard)
694179 return;
695180
696181 // Get a list of symbols which we need to assign the version to.
697 std::vector<Symbol *> Syms = findByVersion(Ver);
698 if (Syms.empty()) {
699 if (!Config->UndefinedVersion)
700 error("version script assignment of '" + VersionName + "' to symbol '" +
701 Ver.Name + "' failed: symbol not defined");
182 std::vector<Symbol *> syms = findByVersion(ver);
183 if (syms.empty()) {
184 if (!config->undefinedVersion)
185 error("version script assignment of '" + versionName + "' to symbol '" +
186 ver.name + "' failed: symbol not defined");
702187 return;
703188 }
704189
190 auto getName = [](uint16_t ver) -> std::string {
191 if (ver == VER_NDX_LOCAL)
192 return "VER_NDX_LOCAL";
193 if (ver == VER_NDX_GLOBAL)
194 return "VER_NDX_GLOBAL";
195 return ("version '" + config->versionDefinitions[ver - 2].name + "'").str();
196 };
197
705198 // Assign the version.
706 for (Symbol *Sym : Syms) {
199 for (Symbol *sym : syms) {
707200 // Skip symbols containing version info because symbol versions
708201 // specified by symbol names take precedence over version scripts.
709202 // See parseSymbolVersion().
710 if (Sym->getName().contains('@'))
203 if (sym->getName().contains('@'))
204 continue;
205
206 if (sym->versionId == config->defaultSymbolVersion)
207 sym->versionId = versionId;
208 if (sym->versionId == versionId)
711209 continue;
712210
713 if (Sym->VersionId != Config->DefaultSymbolVersion &&
714 Sym->VersionId != VersionId)
715 error("duplicate symbol '" + Ver.Name + "' in version script");
716 Sym->VersionId = VersionId;
211 warn("attempt to reassign symbol '" + ver.name + "' of " +
212 getName(sym->versionId) + " to " + getName(versionId));
717213 }
718214}
719215
720void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
721 if (!Ver.HasWildcard)
216void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId) {
217 if (!ver.hasWildcard)
722218 return;
723219
724220 // Exact matching takes precendence over fuzzy matching,
725221 // so we set a version to a symbol only if no version has been assigned
726222 // to the symbol. This behavior is compatible with GNU.
727 for (Symbol *B : findAllByVersion(Ver))
728 if (B->VersionId == Config->DefaultSymbolVersion)
729 B->VersionId = VersionId;
223 for (Symbol *b : findAllByVersion(ver))
224 if (b->versionId == config->defaultSymbolVersion)
225 b->versionId = versionId;
730226}
731227
732// This function processes version scripts by updating VersionId
228// This function processes version scripts by updating the versionId
733229// member of symbols.
230// If there's only one anonymous version definition in a version
231// script file, the script does not actually define any symbol version,
232// but just specifies symbols visibilities.
734233void SymbolTable::scanVersionScript() {
735 // Handle edge cases first.
736 handleAnonymousVersion();
737 handleDynamicList();
738
739 // Now we have version definitions, so we need to set version ids to symbols.
740 // Each version definition has a glob pattern, and all symbols that match
741 // with the pattern get that version.
742
743234 // First, we assign versions to exact matching symbols,
744235 // i.e. version definitions not containing any glob meta-characters.
745 for (VersionDefinition &V : Config->VersionDefinitions)
746 for (SymbolVersion &Ver : V.Globals)
747 assignExactVersion(Ver, V.Id, V.Name);
236 for (SymbolVersion &ver : config->versionScriptGlobals)
237 assignExactVersion(ver, VER_NDX_GLOBAL, "global");
238 for (SymbolVersion &ver : config->versionScriptLocals)
239 assignExactVersion(ver, VER_NDX_LOCAL, "local");
240 for (VersionDefinition &v : config->versionDefinitions)
241 for (SymbolVersion &ver : v.globals)
242 assignExactVersion(ver, v.id, v.name);
748243
749244 // Next, we assign versions to fuzzy matching symbols,
750245 // i.e. version definitions containing glob meta-characters.
246 for (SymbolVersion &ver : config->versionScriptGlobals)
247 assignWildcardVersion(ver, VER_NDX_GLOBAL);
248 for (SymbolVersion &ver : config->versionScriptLocals)
249 assignWildcardVersion(ver, VER_NDX_LOCAL);
250
751251 // Note that because the last match takes precedence over previous matches,
752252 // we iterate over the definitions in the reverse order.
753 for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
754 for (SymbolVersion &Ver : V.Globals)
755 assignWildcardVersion(Ver, V.Id);
253 for (VersionDefinition &v : llvm::reverse(config->versionDefinitions))
254 for (SymbolVersion &ver : v.globals)
255 assignWildcardVersion(ver, v.id);
756256
757257 // Symbol themselves might know their versions because symbols
758258 // can contain versions in the form of <name>@<version>.
759259 // Let them parse and update their names to exclude version suffix.
760 for (Symbol *Sym : SymVector)
761 Sym->parseSymbolVersion();
762}
260 for (Symbol *sym : symVector)
261 sym->parseSymbolVersion();
763262
764template void SymbolTable::addFile<ELF32LE>(InputFile *);
765template void SymbolTable::addFile<ELF32BE>(InputFile *);
766template void SymbolTable::addFile<ELF64LE>(InputFile *);
767template void SymbolTable::addFile<ELF64BE>(InputFile *);
768
769template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t,
770 uint8_t, bool, InputFile *);
771template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t,
772 uint8_t, bool, InputFile *);
773template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, uint8_t, uint8_t,
774 uint8_t, bool, InputFile *);
775template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, uint8_t, uint8_t,
776 uint8_t, bool, InputFile *);
777
778template void SymbolTable::addCombinedLTOObject<ELF32LE>();
779template void SymbolTable::addCombinedLTOObject<ELF32BE>();
780template void SymbolTable::addCombinedLTOObject<ELF64LE>();
781template void SymbolTable::addCombinedLTOObject<ELF64BE>();
782
783template void
784SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile &,
785 const object::Archive::Symbol);
786template void
787SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile &,
788 const object::Archive::Symbol);
789template void
790SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile &,
791 const object::Archive::Symbol);
792template void
793SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile &,
794 const object::Archive::Symbol);
795
796template void SymbolTable::addLazyObject<ELF32LE>(StringRef, LazyObjFile &);
797template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjFile &);
798template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &);
799template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &);
800
801template void SymbolTable::fetchLazy<ELF32LE>(Symbol *);
802template void SymbolTable::fetchLazy<ELF32BE>(Symbol *);
803template void SymbolTable::fetchLazy<ELF64LE>(Symbol *);
804template void SymbolTable::fetchLazy<ELF64BE>(Symbol *);
805
806template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &,
807 const typename ELF32LE::Sym &,
808 uint32_t Alignment, uint32_t);
809template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> &,
810 const typename ELF32BE::Sym &,
811 uint32_t Alignment, uint32_t);
812template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &,
813 const typename ELF64LE::Sym &,
814 uint32_t Alignment, uint32_t);
815template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &,
816 const typename ELF64BE::Sym &,
817 uint32_t Alignment, uint32_t);
263 // isPreemptible is false at this point. To correctly compute the binding of a
264 // Defined (which is used by includeInDynsym()), we need to know if it is
265 // VER_NDX_LOCAL or not. If defaultSymbolVersion is VER_NDX_LOCAL, we should
266 // compute symbol versions before handling --dynamic-list.
267 handleDynamicList();
268}
deps/lld/ELF/SymbolTable.h+32-66
......@@ -1,9 +1,8 @@
11//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -11,15 +10,14 @@
1110#define LLD_ELF_SYMBOL_TABLE_H
1211
1312#include "InputFiles.h"
14#include "LTO.h"
13#include "Symbols.h"
1514#include "lld/Common/Strings.h"
1615#include "llvm/ADT/CachedHashString.h"
1716#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/STLExtras.h"
1818
1919namespace lld {
2020namespace elf {
21class Defined;
22class SectionBase;
2321
2422// SymbolTable is a bucket of all known symbols, including defined,
2523// undefined, or lazy symbols (the last one is symbols in archive
......@@ -35,62 +33,40 @@ class SectionBase;
3533// is one add* function per symbol type.
3634class SymbolTable {
3735public:
38 template <class ELFT> void addFile(InputFile *File);
39 template <class ELFT> void addCombinedLTOObject();
40 void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap);
41
42 ArrayRef<Symbol *> getSymbols() const { return SymVector; }
43
44 template <class ELFT>
45 Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther,
46 uint8_t Type, bool CanOmitFromDynSym, 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);
51
52 template <class ELFT>
53 void addShared(StringRef Name, SharedFile<ELFT> &F,
54 const typename ELFT::Sym &Sym, uint32_t Alignment,
55 uint32_t VerdefIndex);
56
57 template <class ELFT>
58 void addLazyArchive(StringRef Name, ArchiveFile &F,
59 const llvm::object::Archive::Symbol S);
36 void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
6037
61 template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj);
38 void forEachSymbol(llvm::function_ref<void(Symbol *)> fn) {
39 for (Symbol *sym : symVector)
40 if (!sym->isPlaceholder())
41 fn(sym);
42 }
6243
63 Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
64 uint8_t Type, bool CanOmitFromDynSym, BitcodeFile &File);
44 Symbol *insert(StringRef name);
6545
66 Symbol *addCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
67 uint8_t Binding, uint8_t StOther, uint8_t Type,
68 InputFile &File);
69
70 std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Visibility,
71 bool CanOmitFromDynSym, InputFile *File);
72
73 template <class ELFT> void fetchLazy(Symbol *Sym);
46 Symbol *addSymbol(const Symbol &New);
7447
7548 void scanVersionScript();
7649
77 Symbol *find(StringRef Name);
78
79 void trace(StringRef Name);
50 Symbol *find(StringRef name);
8051
8152 void handleDynamicList();
8253
83private:
84 std::pair<Symbol *, bool> insertName(StringRef Name);
54 // Set of .so files to not link the same shared object file more than once.
55 llvm::DenseMap<StringRef, SharedFile *> soNames;
8556
86 std::vector<Symbol *> findByVersion(SymbolVersion Ver);
87 std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
57 // Comdat groups define "link once" sections. If two comdat groups have the
58 // same name, only one of them is linked, and the other is ignored. This map
59 // is used to uniquify them.
60 llvm::DenseMap<llvm::CachedHashStringRef, const InputFile *> comdatGroups;
61
62private:
63 std::vector<Symbol *> findByVersion(SymbolVersion ver);
64 std::vector<Symbol *> findAllByVersion(SymbolVersion ver);
8865
8966 llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
90 void handleAnonymousVersion();
91 void assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
92 StringRef VersionName);
93 void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId);
67 void assignExactVersion(SymbolVersion ver, uint16_t versionId,
68 StringRef versionName);
69 void assignWildcardVersion(SymbolVersion ver, uint16_t versionId);
9470
9571 // The order the global symbols are in is not defined. We can use an arbitrary
9672 // order, but it has to be reproducible. That is true even when cross linking.
......@@ -99,28 +75,18 @@ private:
9975 // but a bit inefficient.
10076 // FIXME: Experiment with passing in a custom hashing or sorting the symbols
10177 // once symbol resolution is finished.
102 llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap;
103 std::vector<Symbol *> SymVector;
104
105 // Comdat groups define "link once" sections. If two comdat groups have the
106 // same name, only one of them is linked, and the other is ignored. This set
107 // is used to uniquify them.
108 llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
109
110 // Set of .so files to not link the same shared object file more than once.
111 llvm::DenseMap<StringRef, InputFile *> SoNames;
78 llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
79 std::vector<Symbol *> symVector;
11280
11381 // A map from demangled symbol names to their symbol objects.
11482 // This mapping is 1:N because two symbols with different versions
11583 // can have the same name. We use this map to handle "extern C++ {}"
11684 // directive in version scripts.
117 llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
118
119 // For LTO.
120 std::unique_ptr<BitcodeCompiler> LTO;
85 llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> demangledSyms;
12186};
12287
123extern SymbolTable *Symtab;
88extern SymbolTable *symtab;
89
12490} // namespace elf
12591} // namespace lld
12692
deps/lld/ELF/Symbols.cpp+489-138
......@@ -1,9 +1,8 @@
11//===- Symbols.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -27,40 +26,36 @@ using namespace llvm::ELF;
2726using namespace lld;
2827using namespace lld::elf;
2928
30Defined *ElfSym::Bss;
31Defined *ElfSym::Etext1;
32Defined *ElfSym::Etext2;
33Defined *ElfSym::Edata1;
34Defined *ElfSym::Edata2;
35Defined *ElfSym::End1;
36Defined *ElfSym::End2;
37Defined *ElfSym::GlobalOffsetTable;
38Defined *ElfSym::MipsGp;
39Defined *ElfSym::MipsGpDisp;
40Defined *ElfSym::MipsLocalGp;
41Defined *ElfSym::RelaIpltStart;
42Defined *ElfSym::RelaIpltEnd;
43
44static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
45 switch (Sym.kind()) {
29Defined *ElfSym::bss;
30Defined *ElfSym::etext1;
31Defined *ElfSym::etext2;
32Defined *ElfSym::edata1;
33Defined *ElfSym::edata2;
34Defined *ElfSym::end1;
35Defined *ElfSym::end2;
36Defined *ElfSym::globalOffsetTable;
37Defined *ElfSym::mipsGp;
38Defined *ElfSym::mipsGpDisp;
39Defined *ElfSym::mipsLocalGp;
40Defined *ElfSym::relaIpltStart;
41Defined *ElfSym::relaIpltEnd;
42Defined *ElfSym::riscvGlobalPointer;
43Defined *ElfSym::tlsModuleBase;
44
45static uint64_t getSymVA(const Symbol &sym, int64_t &addend) {
46 switch (sym.kind()) {
4647 case Symbol::DefinedKind: {
47 auto &D = cast<Defined>(Sym);
48 SectionBase *IS = D.Section;
49
50 // According to the ELF spec reference to a local symbol from outside
51 // the group are not allowed. Unfortunately .eh_frame breaks that rule
52 // and must be treated specially. For now we just replace the symbol with
53 // 0.
54 if (IS == &InputSection::Discarded)
55 return 0;
48 auto &d = cast<Defined>(sym);
49 SectionBase *isec = d.section;
5650
5751 // This is an absolute symbol.
58 if (!IS)
59 return D.Value;
52 if (!isec)
53 return d.value;
6054
61 IS = IS->Repl;
55 assert(isec != &InputSection::discarded);
56 isec = isec->repl;
6257
63 uint64_t Offset = D.Value;
58 uint64_t offset = d.value;
6459
6560 // An object in an SHF_MERGE section might be referenced via a
6661 // section symbol (as a hack for reducing the number of local
......@@ -73,9 +68,9 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
7368 // To make this work, we incorporate the addend into the section
7469 // offset (and zero out the addend for later processing) so that
7570 // we find the right object in the section.
76 if (D.isSection()) {
77 Offset += Addend;
78 Addend = 0;
71 if (d.isSection()) {
72 offset += addend;
73 addend = 0;
7974 }
8075
8176 // In the typical case, this is actually very simple and boils
......@@ -88,83 +83,107 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) {
8883 // If you understand the data structures involved with this next
8984 // line (and how they get built), then you have a pretty good
9085 // understanding of the linker.
91 uint64_t VA = IS->getVA(Offset);
92
93 if (D.isTls() && !Config->Relocatable) {
86 uint64_t va = isec->getVA(offset);
87
88 // MIPS relocatable files can mix regular and microMIPS code.
89 // Linker needs to distinguish such code. To do so microMIPS
90 // symbols has the `STO_MIPS_MICROMIPS` flag in the `st_other`
91 // field. Unfortunately, the `MIPS::relocateOne()` method has
92 // a symbol value only. To pass type of the symbol (regular/microMIPS)
93 // to that routine as well as other places where we write
94 // a symbol value as-is (.dynamic section, `Elf_Ehdr::e_entry`
95 // field etc) do the same trick as compiler uses to mark microMIPS
96 // for CPU - set the less-significant bit.
97 if (config->emachine == EM_MIPS && isMicroMips() &&
98 ((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsPltAddr))
99 va |= 1;
100
101 if (d.isTls() && !config->relocatable) {
94102 // Use the address of the TLS segment's first section rather than the
95103 // segment's address, because segment addresses aren't initialized until
96104 // after sections are finalized. (e.g. Measuring the size of .rela.dyn
97105 // for Android relocation packing requires knowing TLS symbol addresses
98106 // during section finalization.)
99 if (!Out::TlsPhdr || !Out::TlsPhdr->FirstSec)
100 fatal(toString(D.File) +
107 if (!Out::tlsPhdr || !Out::tlsPhdr->firstSec)
108 fatal(toString(d.file) +
101109 " has an STT_TLS symbol but doesn't have an SHF_TLS section");
102 return VA - Out::TlsPhdr->FirstSec->Addr;
110 return va - Out::tlsPhdr->firstSec->addr;
103111 }
104 return VA;
112 return va;
105113 }
106114 case Symbol::SharedKind:
107115 case Symbol::UndefinedKind:
108116 return 0;
109117 case Symbol::LazyArchiveKind:
110118 case Symbol::LazyObjectKind:
111 assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer");
119 assert(sym.isUsedInRegularObj && "lazy symbol reached writer");
112120 return 0;
121 case Symbol::CommonKind:
122 llvm_unreachable("common symbol reached writer");
113123 case Symbol::PlaceholderKind:
114124 llvm_unreachable("placeholder symbol reached writer");
115125 }
116126 llvm_unreachable("invalid symbol kind");
117127}
118128
119uint64_t Symbol::getVA(int64_t Addend) const {
120 uint64_t OutVA = getSymVA(*this, Addend);
121 return OutVA + Addend;
129uint64_t Symbol::getVA(int64_t addend) const {
130 uint64_t outVA = getSymVA(*this, addend);
131 return outVA + addend;
122132}
123133
124uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); }
125
126uint64_t Symbol::getGotOffset() const {
127 return GotIndex * Target->GotEntrySize;
134uint64_t Symbol::getGotVA() const {
135 if (gotInIgot)
136 return in.igotPlt->getVA() + getGotPltOffset();
137 return in.got->getVA() + getGotOffset();
128138}
129139
140uint64_t Symbol::getGotOffset() const { return gotIndex * config->wordsize; }
141
130142uint64_t Symbol::getGotPltVA() const {
131 if (this->IsInIgot)
132 return In.IgotPlt->getVA() + getGotPltOffset();
133 return In.GotPlt->getVA() + getGotPltOffset();
143 if (isInIplt)
144 return in.igotPlt->getVA() + getGotPltOffset();
145 return in.gotPlt->getVA() + getGotPltOffset();
134146}
135147
136148uint64_t Symbol::getGotPltOffset() const {
137 if (IsInIgot)
138 return PltIndex * Target->GotPltEntrySize;
139 return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize;
149 if (isInIplt)
150 return pltIndex * config->wordsize;
151 return (pltIndex + target->gotPltHeaderEntriesNum) * config->wordsize;
140152}
141153
142154uint64_t Symbol::getPPC64LongBranchOffset() const {
143 assert(PPC64BranchltIndex != 0xffff);
144 return PPC64BranchltIndex * Target->GotPltEntrySize;
155 assert(ppc64BranchltIndex != 0xffff);
156 return ppc64BranchltIndex * config->wordsize;
145157}
146158
147159uint64_t Symbol::getPltVA() const {
148 PltSection *Plt = IsInIplt ? In.Iplt : In.Plt;
149 return Plt->getVA() + Plt->HeaderSize + PltIndex * Target->PltEntrySize;
160 PltSection *plt = isInIplt ? in.iplt : in.plt;
161 uint64_t outVA =
162 plt->getVA() + plt->headerSize + pltIndex * target->pltEntrySize;
163 // While linking microMIPS code PLT code are always microMIPS
164 // code. Set the less-significant bit to track that fact.
165 // See detailed comment in the `getSymVA` function.
166 if (config->emachine == EM_MIPS && isMicroMips())
167 outVA |= 1;
168 return outVA;
150169}
151170
152171uint64_t Symbol::getPPC64LongBranchTableVA() const {
153 assert(PPC64BranchltIndex != 0xffff);
154 return In.PPC64LongBranchTarget->getVA() +
155 PPC64BranchltIndex * Target->GotPltEntrySize;
172 assert(ppc64BranchltIndex != 0xffff);
173 return in.ppc64LongBranchTarget->getVA() +
174 ppc64BranchltIndex * config->wordsize;
156175}
157176
158177uint64_t Symbol::getSize() const {
159 if (const auto *DR = dyn_cast<Defined>(this))
160 return DR->Size;
161 return cast<SharedSymbol>(this)->Size;
178 if (const auto *dr = dyn_cast<Defined>(this))
179 return dr->size;
180 return cast<SharedSymbol>(this)->size;
162181}
163182
164183OutputSection *Symbol::getOutputSection() const {
165 if (auto *S = dyn_cast<Defined>(this)) {
166 if (auto *Sec = S->Section)
167 return Sec->Repl->getOutputSection();
184 if (auto *s = dyn_cast<Defined>(this)) {
185 if (auto *sec = s->section)
186 return sec->repl->getOutputSection();
168187 return nullptr;
169188 }
170189 return nullptr;
......@@ -173,16 +192,16 @@ OutputSection *Symbol::getOutputSection() const {
173192// If a symbol name contains '@', the characters after that is
174193// a symbol version name. This function parses that.
175194void Symbol::parseSymbolVersion() {
176 StringRef S = getName();
177 size_t Pos = S.find('@');
178 if (Pos == 0 || Pos == StringRef::npos)
195 StringRef s = getName();
196 size_t pos = s.find('@');
197 if (pos == 0 || pos == StringRef::npos)
179198 return;
180 StringRef Verstr = S.substr(Pos + 1);
181 if (Verstr.empty())
199 StringRef verstr = s.substr(pos + 1);
200 if (verstr.empty())
182201 return;
183202
184203 // Truncate the symbol name so that it doesn't include the version string.
185 NameSize = Pos;
204 nameSize = pos;
186205
187206 // If this is not in this DSO, it is not a definition.
188207 if (!isDefined())
......@@ -190,18 +209,18 @@ void Symbol::parseSymbolVersion() {
190209
191210 // '@@' in a symbol name means the default version.
192211 // It is usually the most recent one.
193 bool IsDefault = (Verstr[0] == '@');
194 if (IsDefault)
195 Verstr = Verstr.substr(1);
212 bool isDefault = (verstr[0] == '@');
213 if (isDefault)
214 verstr = verstr.substr(1);
196215
197 for (VersionDefinition &Ver : Config->VersionDefinitions) {
198 if (Ver.Name != Verstr)
216 for (VersionDefinition &ver : config->versionDefinitions) {
217 if (ver.name != verstr)
199218 continue;
200219
201 if (IsDefault)
202 VersionId = Ver.Id;
220 if (isDefault)
221 versionId = ver.id;
203222 else
204 VersionId = Ver.Id | VERSYM_HIDDEN;
223 versionId = ver.id | VERSYM_HIDDEN;
205224 return;
206225 }
207226
......@@ -211,63 +230,79 @@ void Symbol::parseSymbolVersion() {
211230 // so we do not report error in this case. We also do not error
212231 // if the symbol has a local version as it won't be in the dynamic
213232 // symbol table.
214 if (Config->Shared && VersionId != VER_NDX_LOCAL)
215 error(toString(File) + ": symbol " + S + " has undefined version " +
216 Verstr);
233 if (config->shared && versionId != VER_NDX_LOCAL)
234 error(toString(file) + ": symbol " + s + " has undefined version " +
235 verstr);
217236}
218237
219InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); }
238void Symbol::fetch() const {
239 if (auto *sym = dyn_cast<LazyArchive>(this)) {
240 cast<ArchiveFile>(sym->file)->fetch(sym->sym);
241 return;
242 }
243
244 if (auto *sym = dyn_cast<LazyObject>(this)) {
245 dyn_cast<LazyObjFile>(sym->file)->fetch();
246 return;
247 }
248
249 llvm_unreachable("Symbol::fetch() is called on a non-lazy symbol");
250}
220251
221252MemoryBufferRef LazyArchive::getMemberBuffer() {
222 Archive::Child C = CHECK(
223 Sym.getMember(), "could not get the member for symbol " + Sym.getName());
253 Archive::Child c = CHECK(
254 sym.getMember(), "could not get the member for symbol " + sym.getName());
224255
225 return CHECK(C.getMemoryBufferRef(),
256 return CHECK(c.getMemoryBufferRef(),
226257 "could not get the buffer for the member defining symbol " +
227 Sym.getName());
258 sym.getName());
228259}
229260
230261uint8_t Symbol::computeBinding() const {
231 if (Config->Relocatable)
232 return Binding;
233 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
262 if (config->relocatable)
263 return binding;
264 if (visibility != STV_DEFAULT && visibility != STV_PROTECTED)
234265 return STB_LOCAL;
235 if (VersionId == VER_NDX_LOCAL && isDefined() && !IsPreemptible)
266 if (versionId == VER_NDX_LOCAL && isDefined() && !isPreemptible)
236267 return STB_LOCAL;
237 if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE)
268 if (!config->gnuUnique && binding == STB_GNU_UNIQUE)
238269 return STB_GLOBAL;
239 return Binding;
270 return binding;
240271}
241272
242273bool Symbol::includeInDynsym() const {
243 if (!Config->HasDynSymTab)
274 if (!config->hasDynSymTab)
244275 return false;
245276 if (computeBinding() == STB_LOCAL)
246277 return false;
247 if (!isDefined())
248 return true;
249 return ExportDynamic;
278
279 // If a PIE binary was not linked against any shared libraries, then we can
280 // safely drop weak undef symbols from .dynsym.
281 if (isUndefWeak() && config->pie && sharedFiles.empty())
282 return false;
283
284 return isUndefined() || isShared() || exportDynamic;
250285}
251286
252287// Print out a log message for --trace-symbol.
253void elf::printTraceSymbol(Symbol *Sym) {
254 std::string S;
255 if (Sym->isUndefined())
256 S = ": reference to ";
257 else if (Sym->isLazy())
258 S = ": lazy definition of ";
259 else if (Sym->isShared())
260 S = ": shared definition of ";
261 else if (dyn_cast_or_null<BssSection>(cast<Defined>(Sym)->Section))
262 S = ": common definition of ";
288void elf::printTraceSymbol(const Symbol *sym) {
289 std::string s;
290 if (sym->isUndefined())
291 s = ": reference to ";
292 else if (sym->isLazy())
293 s = ": lazy definition of ";
294 else if (sym->isShared())
295 s = ": shared definition of ";
296 else if (sym->isCommon())
297 s = ": common definition of ";
263298 else
264 S = ": definition of ";
299 s = ": definition of ";
265300
266 message(toString(Sym->File) + S + Sym->getName());
301 message(toString(sym->file) + s + sym->getName());
267302}
268303
269void elf::maybeWarnUnorderableSymbol(const Symbol *Sym) {
270 if (!Config->WarnSymbolOrdering)
304void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {
305 if (!config->warnSymbolOrdering)
271306 return;
272307
273308 // If UnresolvedPolicy::Ignore is used, no "undefined symbol" error/warning
......@@ -275,31 +310,347 @@ void elf::maybeWarnUnorderableSymbol(const Symbol *Sym) {
275310 //
276311 // Note, ld.bfd --symbol-ordering-file= does not warn on undefined symbols,
277312 // but we don't have to be compatible here.
278 if (Sym->isUndefined() &&
279 Config->UnresolvedSymbols == UnresolvedPolicy::Ignore)
313 if (sym->isUndefined() &&
314 config->unresolvedSymbols == UnresolvedPolicy::Ignore)
280315 return;
281316
282 const InputFile *File = Sym->File;
283 auto *D = dyn_cast<Defined>(Sym);
284
285 auto Warn = [&](StringRef S) { warn(toString(File) + S + Sym->getName()); };
286
287 if (Sym->isUndefined())
288 Warn(": unable to order undefined symbol: ");
289 else if (Sym->isShared())
290 Warn(": unable to order shared symbol: ");
291 else if (D && !D->Section)
292 Warn(": unable to order absolute symbol: ");
293 else if (D && isa<OutputSection>(D->Section))
294 Warn(": unable to order synthetic symbol: ");
295 else if (D && !D->Section->Repl->Live)
296 Warn(": unable to order discarded symbol: ");
317 const InputFile *file = sym->file;
318 auto *d = dyn_cast<Defined>(sym);
319
320 auto report = [&](StringRef s) { warn(toString(file) + s + sym->getName()); };
321
322 if (sym->isUndefined())
323 report(": unable to order undefined symbol: ");
324 else if (sym->isShared())
325 report(": unable to order shared symbol: ");
326 else if (d && !d->section)
327 report(": unable to order absolute symbol: ");
328 else if (d && isa<OutputSection>(d->section))
329 report(": unable to order synthetic symbol: ");
330 else if (d && !d->section->repl->isLive())
331 report(": unable to order discarded symbol: ");
297332}
298333
299334// Returns a symbol for an error message.
300std::string lld::toString(const Symbol &B) {
301 if (Config->Demangle)
302 if (Optional<std::string> S = demangleItanium(B.getName()))
303 return *S;
304 return B.getName();
335std::string lld::toString(const Symbol &b) {
336 if (config->demangle)
337 if (Optional<std::string> s = demangleItanium(b.getName()))
338 return *s;
339 return b.getName();
340}
341
342static uint8_t getMinVisibility(uint8_t va, uint8_t vb) {
343 if (va == STV_DEFAULT)
344 return vb;
345 if (vb == STV_DEFAULT)
346 return va;
347 return std::min(va, vb);
348}
349
350// Merge symbol properties.
351//
352// When we have many symbols of the same name, we choose one of them,
353// and that's the result of symbol resolution. However, symbols that
354// were not chosen still affect some symbol properties.
355void Symbol::mergeProperties(const Symbol &other) {
356 if (other.exportDynamic)
357 exportDynamic = true;
358 if (other.isUsedInRegularObj)
359 isUsedInRegularObj = true;
360
361 // DSO symbols do not affect visibility in the output.
362 if (!other.isShared())
363 visibility = getMinVisibility(visibility, other.visibility);
364}
365
366void Symbol::resolve(const Symbol &other) {
367 mergeProperties(other);
368
369 if (isPlaceholder()) {
370 replace(other);
371 return;
372 }
373
374 switch (other.kind()) {
375 case Symbol::UndefinedKind:
376 resolveUndefined(cast<Undefined>(other));
377 break;
378 case Symbol::CommonKind:
379 resolveCommon(cast<CommonSymbol>(other));
380 break;
381 case Symbol::DefinedKind:
382 resolveDefined(cast<Defined>(other));
383 break;
384 case Symbol::LazyArchiveKind:
385 resolveLazy(cast<LazyArchive>(other));
386 break;
387 case Symbol::LazyObjectKind:
388 resolveLazy(cast<LazyObject>(other));
389 break;
390 case Symbol::SharedKind:
391 resolveShared(cast<SharedSymbol>(other));
392 break;
393 case Symbol::PlaceholderKind:
394 llvm_unreachable("bad symbol kind");
395 }
396}
397
398void Symbol::resolveUndefined(const Undefined &other) {
399 // An undefined symbol with non default visibility must be satisfied
400 // in the same DSO.
401 //
402 // If this is a non-weak defined symbol in a discarded section, override the
403 // existing undefined symbol for better error message later.
404 if ((isShared() && other.visibility != STV_DEFAULT) ||
405 (isUndefined() && other.binding != STB_WEAK && other.discardedSecIdx)) {
406 replace(other);
407 return;
408 }
409
410 if (traced)
411 printTraceSymbol(&other);
412
413 if (isLazy()) {
414 // An undefined weak will not fetch archive members. See comment on Lazy in
415 // Symbols.h for the details.
416 if (other.binding == STB_WEAK) {
417 binding = STB_WEAK;
418 type = other.type;
419 return;
420 }
421
422 // Do extra check for --warn-backrefs.
423 //
424 // --warn-backrefs is an option to prevent an undefined reference from
425 // fetching an archive member written earlier in the command line. It can be
426 // used to keep compatibility with GNU linkers to some degree.
427 // I'll explain the feature and why you may find it useful in this comment.
428 //
429 // lld's symbol resolution semantics is more relaxed than traditional Unix
430 // linkers. For example,
431 //
432 // ld.lld foo.a bar.o
433 //
434 // succeeds even if bar.o contains an undefined symbol that has to be
435 // resolved by some object file in foo.a. Traditional Unix linkers don't
436 // allow this kind of backward reference, as they visit each file only once
437 // from left to right in the command line while resolving all undefined
438 // symbols at the moment of visiting.
439 //
440 // In the above case, since there's no undefined symbol when a linker visits
441 // foo.a, no files are pulled out from foo.a, and because the linker forgets
442 // about foo.a after visiting, it can't resolve undefined symbols in bar.o
443 // that could have been resolved otherwise.
444 //
445 // That lld accepts more relaxed form means that (besides it'd make more
446 // sense) you can accidentally write a command line or a build file that
447 // works only with lld, even if you have a plan to distribute it to wider
448 // users who may be using GNU linkers. With --warn-backrefs, you can detect
449 // a library order that doesn't work with other Unix linkers.
450 //
451 // The option is also useful to detect cyclic dependencies between static
452 // archives. Again, lld accepts
453 //
454 // ld.lld foo.a bar.a
455 //
456 // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
457 // handled as an error.
458 //
459 // Here is how the option works. We assign a group ID to each file. A file
460 // with a smaller group ID can pull out object files from an archive file
461 // with an equal or greater group ID. Otherwise, it is a reverse dependency
462 // and an error.
463 //
464 // A file outside --{start,end}-group gets a fresh ID when instantiated. All
465 // files within the same --{start,end}-group get the same group ID. E.g.
466 //
467 // ld.lld A B --start-group C D --end-group E
468 //
469 // A forms group 0. B form group 1. C and D (including their member object
470 // files) form group 2. E forms group 3. I think that you can see how this
471 // group assignment rule simulates the traditional linker's semantics.
472 bool backref = config->warnBackrefs && other.file &&
473 file->groupId < other.file->groupId;
474 fetch();
475
476 // We don't report backward references to weak symbols as they can be
477 // overridden later.
478 if (backref && !isWeak())
479 warn("backward reference detected: " + other.getName() + " in " +
480 toString(other.file) + " refers to " + toString(file));
481 return;
482 }
483
484 // Undefined symbols in a SharedFile do not change the binding.
485 if (dyn_cast_or_null<SharedFile>(other.file))
486 return;
487
488 if (isUndefined()) {
489 // The binding may "upgrade" from weak to non-weak.
490 if (other.binding != STB_WEAK)
491 binding = other.binding;
492 } else if (auto *s = dyn_cast<SharedSymbol>(this)) {
493 // The binding of a SharedSymbol will be weak if there is at least one
494 // reference and all are weak. The binding has one opportunity to change to
495 // weak: if the first reference is weak.
496 if (other.binding != STB_WEAK || !s->referenced)
497 binding = other.binding;
498 s->referenced = true;
499 }
500}
501
502// Using .symver foo,foo@@VER unfortunately creates two symbols: foo and
503// foo@@VER. We want to effectively ignore foo, so give precedence to
504// foo@@VER.
505// FIXME: If users can transition to using
506// .symver foo,foo@@@VER
507// we can delete this hack.
508static int compareVersion(StringRef a, StringRef b) {
509 bool x = a.contains("@@");
510 bool y = b.contains("@@");
511 if (!x && y)
512 return 1;
513 if (x && !y)
514 return -1;
515 return 0;
516}
517
518// Compare two symbols. Return 1 if the new symbol should win, -1 if
519// the new symbol should lose, or 0 if there is a conflict.
520int Symbol::compare(const Symbol *other) const {
521 assert(other->isDefined() || other->isCommon());
522
523 if (!isDefined() && !isCommon())
524 return 1;
525
526 if (int cmp = compareVersion(getName(), other->getName()))
527 return cmp;
528
529 if (other->isWeak())
530 return -1;
531
532 if (isWeak())
533 return 1;
534
535 if (isCommon() && other->isCommon()) {
536 if (config->warnCommon)
537 warn("multiple common of " + getName());
538 return 0;
539 }
540
541 if (isCommon()) {
542 if (config->warnCommon)
543 warn("common " + getName() + " is overridden");
544 return 1;
545 }
546
547 if (other->isCommon()) {
548 if (config->warnCommon)
549 warn("common " + getName() + " is overridden");
550 return -1;
551 }
552
553 auto *oldSym = cast<Defined>(this);
554 auto *newSym = cast<Defined>(other);
555
556 if (other->file && isa<BitcodeFile>(other->file))
557 return 0;
558
559 if (!oldSym->section && !newSym->section && oldSym->value == newSym->value &&
560 newSym->binding == STB_GLOBAL)
561 return -1;
562
563 return 0;
564}
565
566static void reportDuplicate(Symbol *sym, InputFile *newFile,
567 InputSectionBase *errSec, uint64_t errOffset) {
568 if (config->allowMultipleDefinition)
569 return;
570
571 Defined *d = cast<Defined>(sym);
572 if (!d->section || !errSec) {
573 error("duplicate symbol: " + toString(*sym) + "\n>>> defined in " +
574 toString(sym->file) + "\n>>> defined in " + toString(newFile));
575 return;
576 }
577
578 // Construct and print an error message in the form of:
579 //
580 // ld.lld: error: duplicate symbol: foo
581 // >>> defined at bar.c:30
582 // >>> bar.o (/home/alice/src/bar.o)
583 // >>> defined at baz.c:563
584 // >>> baz.o in archive libbaz.a
585 auto *sec1 = cast<InputSectionBase>(d->section);
586 std::string src1 = sec1->getSrcMsg(*sym, d->value);
587 std::string obj1 = sec1->getObjMsg(d->value);
588 std::string src2 = errSec->getSrcMsg(*sym, errOffset);
589 std::string obj2 = errSec->getObjMsg(errOffset);
590
591 std::string msg = "duplicate symbol: " + toString(*sym) + "\n>>> defined at ";
592 if (!src1.empty())
593 msg += src1 + "\n>>> ";
594 msg += obj1 + "\n>>> defined at ";
595 if (!src2.empty())
596 msg += src2 + "\n>>> ";
597 msg += obj2;
598 error(msg);
599}
600
601void Symbol::resolveCommon(const CommonSymbol &other) {
602 int cmp = compare(&other);
603 if (cmp < 0)
604 return;
605
606 if (cmp > 0) {
607 replace(other);
608 return;
609 }
610
611 CommonSymbol *oldSym = cast<CommonSymbol>(this);
612
613 oldSym->alignment = std::max(oldSym->alignment, other.alignment);
614 if (oldSym->size < other.size) {
615 oldSym->file = other.file;
616 oldSym->size = other.size;
617 }
618}
619
620void Symbol::resolveDefined(const Defined &other) {
621 int cmp = compare(&other);
622 if (cmp > 0)
623 replace(other);
624 else if (cmp == 0)
625 reportDuplicate(this, other.file,
626 dyn_cast_or_null<InputSectionBase>(other.section),
627 other.value);
628}
629
630template <class LazyT> void Symbol::resolveLazy(const LazyT &other) {
631 if (!isUndefined())
632 return;
633
634 // An undefined weak will not fetch archive members. See comment on Lazy in
635 // Symbols.h for the details.
636 if (isWeak()) {
637 uint8_t ty = type;
638 replace(other);
639 type = ty;
640 binding = STB_WEAK;
641 return;
642 }
643
644 other.fetch();
645}
646
647void Symbol::resolveShared(const SharedSymbol &other) {
648 if (visibility == STV_DEFAULT && (isUndefined() || isLazy())) {
649 // An undefined symbol with non default visibility must be satisfied
650 // in the same DSO.
651 uint8_t bind = binding;
652 replace(other);
653 binding = bind;
654 cast<SharedSymbol>(this)->referenced = true;
655 }
305656}
deps/lld/ELF/Symbols.h+298-163
......@@ -1,9 +1,8 @@
11//===- Symbols.h ------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -14,6 +13,7 @@
1413#ifndef LLD_ELF_SYMBOLS_H
1514#define LLD_ELF_SYMBOLS_H
1615
16#include "InputFiles.h"
1717#include "InputSection.h"
1818#include "lld/Common/LLVM.h"
1919#include "lld/Common/Strings.h"
......@@ -22,8 +22,14 @@
2222
2323namespace lld {
2424namespace elf {
25class Symbol;
25class CommonSymbol;
26class Defined;
2627class InputFile;
28class LazyArchive;
29class LazyObject;
30class SharedSymbol;
31class Symbol;
32class Undefined;
2733} // namespace elf
2834
2935std::string toString(const elf::Symbol &);
......@@ -31,15 +37,6 @@ std::string toString(const elf::InputFile *);
3137
3238namespace elf {
3339
34class ArchiveFile;
35class BitcodeFile;
36class BssSection;
37class InputFile;
38class LazyObjFile;
39template <class ELFT> class ObjFile;
40class OutputSection;
41template <class ELFT> class SharedFile;
42
4340// This is a StringRef-like container that doesn't run strlen().
4441//
4542// ELF string tables contain a lot of null-terminated strings. Most of them
......@@ -47,11 +44,11 @@ template <class ELFT> class SharedFile;
4744// and the linker doesn't use local symbol names for name resolution. So, we
4845// use this class to represents strings read from string tables.
4946struct StringRefZ {
50 StringRefZ(const char *S) : Data(S), Size(-1) {}
51 StringRefZ(StringRef S) : Data(S.data()), Size(S.size()) {}
47 StringRefZ(const char *s) : data(s), size(-1) {}
48 StringRefZ(StringRef s) : data(s.data()), size(s.size()) {}
5249
53 const char *Data;
54 const uint32_t Size;
50 const char *data;
51 const uint32_t size;
5552};
5653
5754// The base class for real symbol classes.
......@@ -60,85 +57,91 @@ public:
6057 enum Kind {
6158 PlaceholderKind,
6259 DefinedKind,
60 CommonKind,
6361 SharedKind,
6462 UndefinedKind,
6563 LazyArchiveKind,
6664 LazyObjectKind,
6765 };
6866
69 Kind kind() const { return static_cast<Kind>(SymbolKind); }
67 Kind kind() const { return static_cast<Kind>(symbolKind); }
7068
7169 // The file from which this symbol was created.
72 InputFile *File;
70 InputFile *file;
7371
7472protected:
75 const char *NameData;
76 mutable uint32_t NameSize;
73 const char *nameData;
74 mutable uint32_t nameSize;
7775
7876public:
79 uint32_t DynsymIndex = 0;
80 uint32_t GotIndex = -1;
81 uint32_t PltIndex = -1;
77 uint32_t dynsymIndex = 0;
78 uint32_t gotIndex = -1;
79 uint32_t pltIndex = -1;
8280
83 uint32_t GlobalDynIndex = -1;
81 uint32_t globalDynIndex = -1;
8482
8583 // This field is a index to the symbol's version definition.
86 uint32_t VerdefIndex = -1;
84 uint32_t verdefIndex = -1;
8785
8886 // Version definition index.
89 uint16_t VersionId;
87 uint16_t versionId;
9088
9189 // An index into the .branch_lt section on PPC64.
92 uint16_t PPC64BranchltIndex = -1;
90 uint16_t ppc64BranchltIndex = -1;
9391
94 // Symbol binding. This is not overwritten by replaceSymbol to track
92 // Symbol binding. This is not overwritten by replace() to track
9593 // changes during resolution. In particular:
9694 // - An undefined weak is still weak when it resolves to a shared library.
9795 // - An undefined weak will not fetch archive members, but we have to
9896 // remember it is weak.
99 uint8_t Binding;
97 uint8_t binding;
10098
10199 // The following fields have the same meaning as the ELF symbol attributes.
102 uint8_t Type; // symbol type
103 uint8_t StOther; // st_other field value
100 uint8_t type; // symbol type
101 uint8_t stOther; // st_other field value
104102
105 uint8_t SymbolKind;
103 uint8_t symbolKind;
106104
107105 // Symbol visibility. This is the computed minimum visibility of all
108106 // observed non-DSO symbols.
109 unsigned Visibility : 2;
107 unsigned visibility : 2;
110108
111109 // True if the symbol was used for linking and thus need to be added to the
112110 // output file's symbol table. This is true for all symbols except for
113 // unreferenced DSO symbols and bitcode symbols that are unreferenced except
114 // by other bitcode objects.
115 unsigned IsUsedInRegularObj : 1;
111 // unreferenced DSO symbols, lazy (archive) symbols, and bitcode symbols that
112 // are unreferenced except by other bitcode objects.
113 unsigned isUsedInRegularObj : 1;
116114
117115 // If this flag is true and the symbol has protected or default visibility, it
118116 // will appear in .dynsym. This flag is set by interposable DSO symbols in
119117 // executables, by most symbols in DSOs and executables built with
120118 // --export-dynamic, and by dynamic lists.
121 unsigned ExportDynamic : 1;
119 unsigned exportDynamic : 1;
122120
123121 // False if LTO shouldn't inline whatever this symbol points to. If a symbol
124122 // is overwritten after LTO, LTO shouldn't inline the symbol because it
125123 // doesn't know the final contents of the symbol.
126 unsigned CanInline : 1;
124 unsigned canInline : 1;
127125
128126 // True if this symbol is specified by --trace-symbol option.
129 unsigned Traced : 1;
127 unsigned traced : 1;
128
129 inline void replace(const Symbol &New);
130130
131131 bool includeInDynsym() const;
132132 uint8_t computeBinding() const;
133 bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
133 bool isWeak() const { return binding == llvm::ELF::STB_WEAK; }
134
135 bool isUndefined() const { return symbolKind == UndefinedKind; }
136 bool isCommon() const { return symbolKind == CommonKind; }
137 bool isDefined() const { return symbolKind == DefinedKind; }
138 bool isShared() const { return symbolKind == SharedKind; }
139 bool isPlaceholder() const { return symbolKind == PlaceholderKind; }
134140
135 bool isUndefined() const { return SymbolKind == UndefinedKind; }
136 bool isDefined() const { return SymbolKind == DefinedKind; }
137 bool isShared() const { return SymbolKind == SharedKind; }
138 bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; }
141 bool isLocal() const { return binding == llvm::ELF::STB_LOCAL; }
139142
140143 bool isLazy() const {
141 return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
144 return symbolKind == LazyArchiveKind || symbolKind == LazyObjectKind;
142145 }
143146
144147 // True if this is an undefined weak symbol. This only works once
......@@ -149,23 +152,23 @@ public:
149152 }
150153
151154 StringRef getName() const {
152 if (NameSize == (uint32_t)-1)
153 NameSize = strlen(NameData);
154 return {NameData, NameSize};
155 if (nameSize == (uint32_t)-1)
156 nameSize = strlen(nameData);
157 return {nameData, nameSize};
155158 }
156159
157 void setName(StringRef S) {
158 NameData = S.data();
159 NameSize = S.size();
160 void setName(StringRef s) {
161 nameData = s.data();
162 nameSize = s.size();
160163 }
161164
162165 void parseSymbolVersion();
163166
164 bool isInGot() const { return GotIndex != -1U; }
165 bool isInPlt() const { return PltIndex != -1U; }
166 bool isInPPC64Branchlt() const { return PPC64BranchltIndex != 0xffff; }
167 bool isInGot() const { return gotIndex != -1U; }
168 bool isInPlt() const { return pltIndex != -1U; }
169 bool isInPPC64Branchlt() const { return ppc64BranchltIndex != 0xffff; }
167170
168 uint64_t getVA(int64_t Addend = 0) const;
171 uint64_t getVA(int64_t addend = 0) const;
169172
170173 uint64_t getGotOffset() const;
171174 uint64_t getGotVA() const;
......@@ -177,81 +180,164 @@ public:
177180 uint64_t getSize() const;
178181 OutputSection *getOutputSection() const;
179182
183 // The following two functions are used for symbol resolution.
184 //
185 // You are expected to call mergeProperties for all symbols in input
186 // files so that attributes that are attached to names rather than
187 // indivisual symbol (such as visibility) are merged together.
188 //
189 // Every time you read a new symbol from an input, you are supposed
190 // to call resolve() with the new symbol. That function replaces
191 // "this" object as a result of name resolution if the new symbol is
192 // more appropriate to be included in the output.
193 //
194 // For example, if "this" is an undefined symbol and a new symbol is
195 // a defined symbol, "this" is replaced with the new symbol.
196 void mergeProperties(const Symbol &other);
197 void resolve(const Symbol &other);
198
199 // If this is a lazy symbol, fetch an input file and add the symbol
200 // in the file to the symbol table. Calling this function on
201 // non-lazy object causes a runtime error.
202 void fetch() const;
203
204private:
205 static bool isExportDynamic(Kind k, uint8_t visibility) {
206 if (k == SharedKind)
207 return visibility == llvm::ELF::STV_DEFAULT;
208 return config->shared || config->exportDynamic;
209 }
210
211 void resolveUndefined(const Undefined &other);
212 void resolveCommon(const CommonSymbol &other);
213 void resolveDefined(const Defined &other);
214 template <class LazyT> void resolveLazy(const LazyT &other);
215 void resolveShared(const SharedSymbol &other);
216
217 int compare(const Symbol *other) const;
218
219 inline size_t getSymbolSize() const;
220
180221protected:
181 Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding,
182 uint8_t StOther, uint8_t Type)
183 : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
184 Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
185 IsInIplt(false), IsInIgot(false), IsPreemptible(false),
186 Used(!Config->GcSections), NeedsTocRestore(false),
187 ScriptDefined(false) {}
222 Symbol(Kind k, InputFile *file, StringRefZ name, uint8_t binding,
223 uint8_t stOther, uint8_t type)
224 : file(file), nameData(name.data), nameSize(name.size), binding(binding),
225 type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
226 isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
227 exportDynamic(isExportDynamic(k, visibility)), canInline(false),
228 traced(false), needsPltAddr(false), isInIplt(false), gotInIgot(false),
229 isPreemptible(false), used(!config->gcSections), needsTocRestore(false),
230 scriptDefined(false) {}
188231
189232public:
190233 // True the symbol should point to its PLT entry.
191234 // For SharedSymbol only.
192 unsigned NeedsPltAddr : 1;
235 unsigned needsPltAddr : 1;
193236
194 // True if this symbol is in the Iplt sub-section of the Plt.
195 unsigned IsInIplt : 1;
237 // True if this symbol is in the Iplt sub-section of the Plt and the Igot
238 // sub-section of the .got.plt or .got.
239 unsigned isInIplt : 1;
196240
197 // True if this symbol is in the Igot sub-section of the .got.plt or .got.
198 unsigned IsInIgot : 1;
241 // True if this symbol needs a GOT entry and its GOT entry is actually in
242 // Igot. This will be true only for certain non-preemptible ifuncs.
243 unsigned gotInIgot : 1;
199244
200245 // True if this symbol is preemptible at load time.
201 unsigned IsPreemptible : 1;
246 unsigned isPreemptible : 1;
202247
203248 // True if an undefined or shared symbol is used from a live section.
204 unsigned Used : 1;
249 unsigned used : 1;
205250
206251 // True if a call to this symbol needs to be followed by a restore of the
207252 // PPC64 toc pointer.
208 unsigned NeedsTocRestore : 1;
253 unsigned needsTocRestore : 1;
209254
210255 // True if this symbol is defined by a linker script.
211 unsigned ScriptDefined : 1;
212
213 bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
214 bool isTls() const { return Type == llvm::ELF::STT_TLS; }
215 bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
216 bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
217 bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
218 bool isFile() const { return Type == llvm::ELF::STT_FILE; }
256 unsigned scriptDefined : 1;
257
258 // The partition whose dynamic symbol table contains this symbol's definition.
259 uint8_t partition = 1;
260
261 bool isSection() const { return type == llvm::ELF::STT_SECTION; }
262 bool isTls() const { return type == llvm::ELF::STT_TLS; }
263 bool isFunc() const { return type == llvm::ELF::STT_FUNC; }
264 bool isGnuIFunc() const { return type == llvm::ELF::STT_GNU_IFUNC; }
265 bool isObject() const { return type == llvm::ELF::STT_OBJECT; }
266 bool isFile() const { return type == llvm::ELF::STT_FILE; }
219267};
220268
221269// Represents a symbol that is defined in the current output file.
222270class Defined : public Symbol {
223271public:
224 Defined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
225 uint8_t Type, uint64_t Value, uint64_t Size, SectionBase *Section)
226 : Symbol(DefinedKind, File, Name, Binding, StOther, Type), Value(Value),
227 Size(Size), Section(Section) {}
272 Defined(InputFile *file, StringRefZ name, uint8_t binding, uint8_t stOther,
273 uint8_t type, uint64_t value, uint64_t size, SectionBase *section)
274 : Symbol(DefinedKind, file, name, binding, stOther, type), value(value),
275 size(size), section(section) {}
276
277 static bool classof(const Symbol *s) { return s->isDefined(); }
278
279 uint64_t value;
280 uint64_t size;
281 SectionBase *section;
282};
283
284// Represents a common symbol.
285//
286// On Unix, it is traditionally allowed to write variable definitions
287// without initialization expressions (such as "int foo;") to header
288// files. Such definition is called "tentative definition".
289//
290// Using tentative definition is usually considered a bad practice
291// because you should write only declarations (such as "extern int
292// foo;") to header files. Nevertheless, the linker and the compiler
293// have to do something to support bad code by allowing duplicate
294// definitions for this particular case.
295//
296// Common symbols represent variable definitions without initializations.
297// The compiler creates common symbols when it sees varaible definitions
298// without initialization (you can suppress this behavior and let the
299// compiler create a regular defined symbol by -fno-common).
300//
301// The linker allows common symbols to be replaced by regular defined
302// symbols. If there are remaining common symbols after name resolution is
303// complete, they are converted to regular defined symbols in a .bss
304// section. (Therefore, the later passes don't see any CommonSymbols.)
305class CommonSymbol : public Symbol {
306public:
307 CommonSymbol(InputFile *file, StringRefZ name, uint8_t binding,
308 uint8_t stOther, uint8_t type, uint64_t alignment, uint64_t size)
309 : Symbol(CommonKind, file, name, binding, stOther, type),
310 alignment(alignment), size(size) {}
228311
229 static bool classof(const Symbol *S) { return S->isDefined(); }
312 static bool classof(const Symbol *s) { return s->isCommon(); }
230313
231 uint64_t Value;
232 uint64_t Size;
233 SectionBase *Section;
314 uint32_t alignment;
315 uint64_t size;
234316};
235317
236318class Undefined : public Symbol {
237319public:
238 Undefined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
239 uint8_t Type)
240 : Symbol(UndefinedKind, File, Name, Binding, StOther, Type) {}
320 Undefined(InputFile *file, StringRefZ name, uint8_t binding, uint8_t stOther,
321 uint8_t type, uint32_t discardedSecIdx = 0)
322 : Symbol(UndefinedKind, file, name, binding, stOther, type),
323 discardedSecIdx(discardedSecIdx) {}
241324
242 static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; }
325 static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; }
326
327 // The section index if in a discarded section, 0 otherwise.
328 uint32_t discardedSecIdx;
243329};
244330
245331class SharedSymbol : public Symbol {
246332public:
247 static bool classof(const Symbol *S) { return S->kind() == SharedKind; }
248
249 SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding,
250 uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size,
251 uint32_t Alignment, uint32_t VerdefIndex)
252 : Symbol(SharedKind, &File, Name, Binding, StOther, Type),
253 Alignment(Alignment), Value(Value), Size(Size) {
254 this->VerdefIndex = VerdefIndex;
333 static bool classof(const Symbol *s) { return s->kind() == SharedKind; }
334
335 SharedSymbol(InputFile &file, StringRef name, uint8_t binding,
336 uint8_t stOther, uint8_t type, uint64_t value, uint64_t size,
337 uint32_t alignment, uint32_t verdefIndex)
338 : Symbol(SharedKind, &file, name, binding, stOther, type), value(value),
339 size(size), alignment(alignment) {
340 this->verdefIndex = verdefIndex;
255341 // GNU ifunc is a mechanism to allow user-supplied functions to
256342 // resolve PLT slot values at load-time. This is contrary to the
257343 // regular symbol resolution scheme in which symbols are resolved just
......@@ -268,18 +354,20 @@ public:
268354 // For DSO symbols, we always call them through PLT slots anyway.
269355 // So there's no difference between GNU ifunc and regular function
270356 // symbols if they are in DSOs. So we can handle GNU_IFUNC as FUNC.
271 if (this->Type == llvm::ELF::STT_GNU_IFUNC)
272 this->Type = llvm::ELF::STT_FUNC;
357 if (this->type == llvm::ELF::STT_GNU_IFUNC)
358 this->type = llvm::ELF::STT_FUNC;
273359 }
274360
275 template <class ELFT> SharedFile<ELFT> &getFile() const {
276 return *cast<SharedFile<ELFT>>(File);
277 }
361 SharedFile &getFile() const { return *cast<SharedFile>(file); }
278362
279 uint32_t Alignment;
363 uint64_t value; // st_value
364 uint64_t size; // st_size
365 uint32_t alignment;
280366
281 uint64_t Value; // st_value
282 uint64_t Size; // st_size
367 // This is true if there has been at least one undefined reference to the
368 // symbol. The binding may change to STB_WEAK if the first undefined reference
369 // is weak.
370 bool referenced = false;
283371};
284372
285373// LazyArchive and LazyObject represent a symbols that is not yet in the link,
......@@ -298,121 +386,168 @@ public:
298386// symbol.
299387class LazyArchive : public Symbol {
300388public:
301 LazyArchive(InputFile &File, uint8_t Type,
302 const llvm::object::Archive::Symbol S)
303 : Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL,
304 llvm::ELF::STV_DEFAULT, Type),
305 Sym(S) {}
389 LazyArchive(InputFile &file, const llvm::object::Archive::Symbol s)
390 : Symbol(LazyArchiveKind, &file, s.getName(), llvm::ELF::STB_GLOBAL,
391 llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE),
392 sym(s) {}
306393
307 static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
394 static bool classof(const Symbol *s) { return s->kind() == LazyArchiveKind; }
308395
309 InputFile *fetch();
310396 MemoryBufferRef getMemberBuffer();
311397
312private:
313 const llvm::object::Archive::Symbol Sym;
398 const llvm::object::Archive::Symbol sym;
314399};
315400
316401// LazyObject symbols represents symbols in object files between
317402// --start-lib and --end-lib options.
318403class LazyObject : public Symbol {
319404public:
320 LazyObject(InputFile &File, uint8_t Type, StringRef Name)
321 : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL,
322 llvm::ELF::STV_DEFAULT, Type) {}
405 LazyObject(InputFile &file, StringRef name)
406 : Symbol(LazyObjectKind, &file, name, llvm::ELF::STB_GLOBAL,
407 llvm::ELF::STV_DEFAULT, llvm::ELF::STT_NOTYPE) {}
323408
324 static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
409 static bool classof(const Symbol *s) { return s->kind() == LazyObjectKind; }
325410};
326411
327412// Some linker-generated symbols need to be created as
328413// Defined symbols.
329414struct ElfSym {
330415 // __bss_start
331 static Defined *Bss;
416 static Defined *bss;
332417
333418 // etext and _etext
334 static Defined *Etext1;
335 static Defined *Etext2;
419 static Defined *etext1;
420 static Defined *etext2;
336421
337422 // edata and _edata
338 static Defined *Edata1;
339 static Defined *Edata2;
423 static Defined *edata1;
424 static Defined *edata2;
340425
341426 // end and _end
342 static Defined *End1;
343 static Defined *End2;
427 static Defined *end1;
428 static Defined *end2;
344429
345430 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
346431 // be at some offset from the base of the .got section, usually 0 or
347432 // the end of the .got.
348 static Defined *GlobalOffsetTable;
433 static Defined *globalOffsetTable;
349434
350435 // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
351 static Defined *MipsGp;
352 static Defined *MipsGpDisp;
353 static Defined *MipsLocalGp;
436 static Defined *mipsGp;
437 static Defined *mipsGpDisp;
438 static Defined *mipsLocalGp;
354439
355440 // __rel{,a}_iplt_{start,end} symbols.
356 static Defined *RelaIpltStart;
357 static Defined *RelaIpltEnd;
441 static Defined *relaIpltStart;
442 static Defined *relaIpltEnd;
443
444 // __global_pointer$ for RISC-V.
445 static Defined *riscvGlobalPointer;
446
447 // _TLS_MODULE_BASE_ on targets that support TLSDESC.
448 static Defined *tlsModuleBase;
358449};
359450
360451// A buffer class that is large enough to hold any Symbol-derived
361452// object. We allocate memory using this class and instantiate a symbol
362453// using the placement new.
363454union SymbolUnion {
364 alignas(Defined) char A[sizeof(Defined)];
365 alignas(Undefined) char C[sizeof(Undefined)];
366 alignas(SharedSymbol) char D[sizeof(SharedSymbol)];
367 alignas(LazyArchive) char E[sizeof(LazyArchive)];
368 alignas(LazyObject) char F[sizeof(LazyObject)];
455 alignas(Defined) char a[sizeof(Defined)];
456 alignas(CommonSymbol) char b[sizeof(CommonSymbol)];
457 alignas(Undefined) char c[sizeof(Undefined)];
458 alignas(SharedSymbol) char d[sizeof(SharedSymbol)];
459 alignas(LazyArchive) char e[sizeof(LazyArchive)];
460 alignas(LazyObject) char f[sizeof(LazyObject)];
369461};
370462
371void printTraceSymbol(Symbol *Sym);
372
373template <typename T, typename... ArgT>
374void replaceSymbol(Symbol *S, ArgT &&... Arg) {
375 using llvm::ELF::STT_TLS;
463// It is important to keep the size of SymbolUnion small for performance and
464// memory usage reasons. 80 bytes is a soft limit based on the size of Defined
465// on a 64-bit system.
466static_assert(sizeof(SymbolUnion) <= 80, "SymbolUnion too large");
376467
468template <typename T> struct AssertSymbol {
377469 static_assert(std::is_trivially_destructible<T>(),
378470 "Symbol types must be trivially destructible");
379471 static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
380472 static_assert(alignof(T) <= alignof(SymbolUnion),
381473 "SymbolUnion not aligned enough");
382 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
383 "Not a Symbol");
474};
384475
385 Symbol Sym = *S;
476static inline void assertSymbols() {
477 AssertSymbol<Defined>();
478 AssertSymbol<CommonSymbol>();
479 AssertSymbol<Undefined>();
480 AssertSymbol<SharedSymbol>();
481 AssertSymbol<LazyArchive>();
482 AssertSymbol<LazyObject>();
483}
386484
387 new (S) T(std::forward<ArgT>(Arg)...);
485void printTraceSymbol(const Symbol *sym);
486
487size_t Symbol::getSymbolSize() const {
488 switch (kind()) {
489 case CommonKind:
490 return sizeof(CommonSymbol);
491 case DefinedKind:
492 return sizeof(Defined);
493 case LazyArchiveKind:
494 return sizeof(LazyArchive);
495 case LazyObjectKind:
496 return sizeof(LazyObject);
497 case SharedKind:
498 return sizeof(SharedSymbol);
499 case UndefinedKind:
500 return sizeof(Undefined);
501 case PlaceholderKind:
502 return sizeof(Symbol);
503 }
504 llvm_unreachable("unknown symbol kind");
505}
388506
389 S->VersionId = Sym.VersionId;
390 S->Visibility = Sym.Visibility;
391 S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
392 S->ExportDynamic = Sym.ExportDynamic;
393 S->CanInline = Sym.CanInline;
394 S->Traced = Sym.Traced;
395 S->ScriptDefined = Sym.ScriptDefined;
507// replace() replaces "this" object with a given symbol by memcpy'ing
508// it over to "this". This function is called as a result of name
509// resolution, e.g. to replace an undefind symbol with a defined symbol.
510void Symbol::replace(const Symbol &New) {
511 using llvm::ELF::STT_TLS;
396512
397513 // Symbols representing thread-local variables must be referenced by
398514 // TLS-aware relocations, and non-TLS symbols must be reference by
399515 // non-TLS relocations, so there's a clear distinction between TLS
400516 // and non-TLS symbols. It is an error if the same symbol is defined
401517 // 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);
518 if (symbolKind != PlaceholderKind && !isLazy() && !New.isLazy()) {
519 bool tlsMismatch = (type == STT_TLS && New.type != STT_TLS) ||
520 (type != STT_TLS && New.type == STT_TLS);
521 if (tlsMismatch)
522 error("TLS attribute mismatch: " + toString(*this) + "\n>>> defined in " +
523 toString(New.file) + "\n>>> defined in " + toString(file));
524 }
525
526 Symbol old = *this;
527 memcpy(this, &New, New.getSymbolSize());
528
529 versionId = old.versionId;
530 visibility = old.visibility;
531 isUsedInRegularObj = old.isUsedInRegularObj;
532 exportDynamic = old.exportDynamic;
533 canInline = old.canInline;
534 traced = old.traced;
535 isPreemptible = old.isPreemptible;
536 scriptDefined = old.scriptDefined;
537 partition = old.partition;
404538
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));
539 // Symbol length is computed lazily. If we already know a symbol length,
540 // propagate it.
541 if (nameData == old.nameData && nameSize == 0 && old.nameSize != 0)
542 nameSize = old.nameSize;
408543
409544 // Print out a log message if --trace-symbol was specified.
410545 // This is for debugging.
411 if (S->Traced)
412 printTraceSymbol(S);
546 if (traced)
547 printTraceSymbol(this);
413548}
414549
415void maybeWarnUnorderableSymbol(const Symbol *Sym);
550void maybeWarnUnorderableSymbol(const Symbol *sym);
416551} // namespace elf
417552} // namespace lld
418553
deps/lld/ELF/SyntheticSections.cpp+2046-1654
......@@ -1,9 +1,8 @@
11//===- SyntheticSections.cpp ----------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -15,7 +14,6 @@
1514//===----------------------------------------------------------------------===//
1615
1716#include "SyntheticSections.h"
18#include "Bits.h"
1917#include "Config.h"
2018#include "InputFiles.h"
2119#include "LinkerScript.h"
......@@ -38,9 +36,6 @@
3836#include "llvm/Support/Endian.h"
3937#include "llvm/Support/LEB128.h"
4038#include "llvm/Support/MD5.h"
41#include "llvm/Support/RandomNumberGenerator.h"
42#include "llvm/Support/SHA1.h"
43#include "llvm/Support/xxhash.h"
4439#include <cstdlib>
4540#include <thread>
4641
......@@ -57,19 +52,30 @@ using llvm::support::endian::read32le;
5752using llvm::support::endian::write32le;
5853using llvm::support::endian::write64le;
5954
60constexpr size_t MergeNoTailSection::NumShards;
55constexpr size_t MergeNoTailSection::numShards;
56
57static uint64_t readUint(uint8_t *buf) {
58 return config->is64 ? read64(buf) : read32(buf);
59}
60
61static void writeUint(uint8_t *buf, uint64_t val) {
62 if (config->is64)
63 write64(buf, val);
64 else
65 write32(buf, val);
66}
6167
6268// Returns an LLD version string.
6369static ArrayRef<uint8_t> getVersion() {
6470 // Check LLD_VERSION first for ease of testing.
6571 // You can get consistent output by using the environment variable.
6672 // This is only for testing.
67 StringRef S = getenv("LLD_VERSION");
68 if (S.empty())
69 S = Saver.save(Twine("Linker: ") + getLLDVersion());
73 StringRef s = getenv("LLD_VERSION");
74 if (s.empty())
75 s = saver.save(Twine("Linker: ") + getLLDVersion());
7076
7177 // +1 to include the terminating '\0'.
72 return {(const uint8_t *)S.data(), S.size() + 1};
78 return {(const uint8_t *)s.data(), s.size() + 1};
7379}
7480
7581// Creates a .comment section containing LLD version info.
......@@ -83,79 +89,79 @@ MergeInputSection *elf::createCommentSection() {
8389
8490// .MIPS.abiflags section.
8591template <class ELFT>
86MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags)
92MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags flags)
8793 : SyntheticSection(SHF_ALLOC, SHT_MIPS_ABIFLAGS, 8, ".MIPS.abiflags"),
88 Flags(Flags) {
89 this->Entsize = sizeof(Elf_Mips_ABIFlags);
94 flags(flags) {
95 this->entsize = sizeof(Elf_Mips_ABIFlags);
9096}
9197
92template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *Buf) {
93 memcpy(Buf, &Flags, sizeof(Flags));
98template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *buf) {
99 memcpy(buf, &flags, sizeof(flags));
94100}
95101
96102template <class ELFT>
97103MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
98 Elf_Mips_ABIFlags Flags = {};
99 bool Create = false;
104 Elf_Mips_ABIFlags flags = {};
105 bool create = false;
100106
101 for (InputSectionBase *Sec : InputSections) {
102 if (Sec->Type != SHT_MIPS_ABIFLAGS)
107 for (InputSectionBase *sec : inputSections) {
108 if (sec->type != SHT_MIPS_ABIFLAGS)
103109 continue;
104 Sec->Live = false;
105 Create = true;
110 sec->markDead();
111 create = true;
106112
107 std::string Filename = toString(Sec->File);
108 const size_t Size = Sec->data().size();
113 std::string filename = toString(sec->file);
114 const size_t size = sec->data().size();
109115 // Older version of BFD (such as the default FreeBSD linker) concatenate
110116 // .MIPS.abiflags instead of merging. To allow for this case (or potential
111117 // zero padding) we ignore everything after the first Elf_Mips_ABIFlags
112 if (Size < sizeof(Elf_Mips_ABIFlags)) {
113 error(Filename + ": invalid size of .MIPS.abiflags section: got " +
114 Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
118 if (size < sizeof(Elf_Mips_ABIFlags)) {
119 error(filename + ": invalid size of .MIPS.abiflags section: got " +
120 Twine(size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
115121 return nullptr;
116122 }
117 auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->data().data());
118 if (S->version != 0) {
119 error(Filename + ": unexpected .MIPS.abiflags version " +
120 Twine(S->version));
123 auto *s = reinterpret_cast<const Elf_Mips_ABIFlags *>(sec->data().data());
124 if (s->version != 0) {
125 error(filename + ": unexpected .MIPS.abiflags version " +
126 Twine(s->version));
121127 return nullptr;
122128 }
123129
124130 // LLD checks ISA compatibility in calcMipsEFlags(). Here we just
125131 // select the highest number of ISA/Rev/Ext.
126 Flags.isa_level = std::max(Flags.isa_level, S->isa_level);
127 Flags.isa_rev = std::max(Flags.isa_rev, S->isa_rev);
128 Flags.isa_ext = std::max(Flags.isa_ext, S->isa_ext);
129 Flags.gpr_size = std::max(Flags.gpr_size, S->gpr_size);
130 Flags.cpr1_size = std::max(Flags.cpr1_size, S->cpr1_size);
131 Flags.cpr2_size = std::max(Flags.cpr2_size, S->cpr2_size);
132 Flags.ases |= S->ases;
133 Flags.flags1 |= S->flags1;
134 Flags.flags2 |= S->flags2;
135 Flags.fp_abi = elf::getMipsFpAbiFlag(Flags.fp_abi, S->fp_abi, Filename);
132 flags.isa_level = std::max(flags.isa_level, s->isa_level);
133 flags.isa_rev = std::max(flags.isa_rev, s->isa_rev);
134 flags.isa_ext = std::max(flags.isa_ext, s->isa_ext);
135 flags.gpr_size = std::max(flags.gpr_size, s->gpr_size);
136 flags.cpr1_size = std::max(flags.cpr1_size, s->cpr1_size);
137 flags.cpr2_size = std::max(flags.cpr2_size, s->cpr2_size);
138 flags.ases |= s->ases;
139 flags.flags1 |= s->flags1;
140 flags.flags2 |= s->flags2;
141 flags.fp_abi = elf::getMipsFpAbiFlag(flags.fp_abi, s->fp_abi, filename);
136142 };
137143
138 if (Create)
139 return make<MipsAbiFlagsSection<ELFT>>(Flags);
144 if (create)
145 return make<MipsAbiFlagsSection<ELFT>>(flags);
140146 return nullptr;
141147}
142148
143149// .MIPS.options section.
144150template <class ELFT>
145MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo Reginfo)
151MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo reginfo)
146152 : SyntheticSection(SHF_ALLOC, SHT_MIPS_OPTIONS, 8, ".MIPS.options"),
147 Reginfo(Reginfo) {
148 this->Entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
153 reginfo(reginfo) {
154 this->entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
149155}
150156
151template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *Buf) {
152 auto *Options = reinterpret_cast<Elf_Mips_Options *>(Buf);
153 Options->kind = ODK_REGINFO;
154 Options->size = getSize();
157template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *buf) {
158 auto *options = reinterpret_cast<Elf_Mips_Options *>(buf);
159 options->kind = ODK_REGINFO;
160 options->size = getSize();
155161
156 if (!Config->Relocatable)
157 Reginfo.ri_gp_value = In.MipsGot->getGp();
158 memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));
162 if (!config->relocatable)
163 reginfo.ri_gp_value = in.mipsGot->getGp();
164 memcpy(buf + sizeof(Elf_Mips_Options), &reginfo, sizeof(reginfo));
159165}
160166
161167template <class ELFT>
......@@ -164,55 +170,55 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() {
164170 if (!ELFT::Is64Bits)
165171 return nullptr;
166172
167 std::vector<InputSectionBase *> Sections;
168 for (InputSectionBase *Sec : InputSections)
169 if (Sec->Type == SHT_MIPS_OPTIONS)
170 Sections.push_back(Sec);
173 std::vector<InputSectionBase *> sections;
174 for (InputSectionBase *sec : inputSections)
175 if (sec->type == SHT_MIPS_OPTIONS)
176 sections.push_back(sec);
171177
172 if (Sections.empty())
178 if (sections.empty())
173179 return nullptr;
174180
175 Elf_Mips_RegInfo Reginfo = {};
176 for (InputSectionBase *Sec : Sections) {
177 Sec->Live = false;
181 Elf_Mips_RegInfo reginfo = {};
182 for (InputSectionBase *sec : sections) {
183 sec->markDead();
178184
179 std::string Filename = toString(Sec->File);
180 ArrayRef<uint8_t> D = Sec->data();
185 std::string filename = toString(sec->file);
186 ArrayRef<uint8_t> d = sec->data();
181187
182 while (!D.empty()) {
183 if (D.size() < sizeof(Elf_Mips_Options)) {
184 error(Filename + ": invalid size of .MIPS.options section");
188 while (!d.empty()) {
189 if (d.size() < sizeof(Elf_Mips_Options)) {
190 error(filename + ": invalid size of .MIPS.options section");
185191 break;
186192 }
187193
188 auto *Opt = reinterpret_cast<const Elf_Mips_Options *>(D.data());
189 if (Opt->kind == ODK_REGINFO) {
190 Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask;
191 Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value;
194 auto *opt = reinterpret_cast<const Elf_Mips_Options *>(d.data());
195 if (opt->kind == ODK_REGINFO) {
196 reginfo.ri_gprmask |= opt->getRegInfo().ri_gprmask;
197 sec->getFile<ELFT>()->mipsGp0 = opt->getRegInfo().ri_gp_value;
192198 break;
193199 }
194200
195 if (!Opt->size)
196 fatal(Filename + ": zero option descriptor size");
197 D = D.slice(Opt->size);
201 if (!opt->size)
202 fatal(filename + ": zero option descriptor size");
203 d = d.slice(opt->size);
198204 }
199205 };
200206
201 return make<MipsOptionsSection<ELFT>>(Reginfo);
207 return make<MipsOptionsSection<ELFT>>(reginfo);
202208}
203209
204210// MIPS .reginfo section.
205211template <class ELFT>
206MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
212MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo reginfo)
207213 : SyntheticSection(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ".reginfo"),
208 Reginfo(Reginfo) {
209 this->Entsize = sizeof(Elf_Mips_RegInfo);
214 reginfo(reginfo) {
215 this->entsize = sizeof(Elf_Mips_RegInfo);
210216}
211217
212template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
213 if (!Config->Relocatable)
214 Reginfo.ri_gp_value = In.MipsGot->getGp();
215 memcpy(Buf, &Reginfo, sizeof(Reginfo));
218template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *buf) {
219 if (!config->relocatable)
220 reginfo.ri_gp_value = in.mipsGot->getGp();
221 memcpy(buf, &reginfo, sizeof(reginfo));
216222}
217223
218224template <class ELFT>
......@@ -221,53 +227,53 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {
221227 if (ELFT::Is64Bits)
222228 return nullptr;
223229
224 std::vector<InputSectionBase *> Sections;
225 for (InputSectionBase *Sec : InputSections)
226 if (Sec->Type == SHT_MIPS_REGINFO)
227 Sections.push_back(Sec);
230 std::vector<InputSectionBase *> sections;
231 for (InputSectionBase *sec : inputSections)
232 if (sec->type == SHT_MIPS_REGINFO)
233 sections.push_back(sec);
228234
229 if (Sections.empty())
235 if (sections.empty())
230236 return nullptr;
231237
232 Elf_Mips_RegInfo Reginfo = {};
233 for (InputSectionBase *Sec : Sections) {
234 Sec->Live = false;
238 Elf_Mips_RegInfo reginfo = {};
239 for (InputSectionBase *sec : sections) {
240 sec->markDead();
235241
236 if (Sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
237 error(toString(Sec->File) + ": invalid size of .reginfo section");
242 if (sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
243 error(toString(sec->file) + ": invalid size of .reginfo section");
238244 return nullptr;
239245 }
240246
241 auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->data().data());
242 Reginfo.ri_gprmask |= R->ri_gprmask;
243 Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;
247 auto *r = reinterpret_cast<const Elf_Mips_RegInfo *>(sec->data().data());
248 reginfo.ri_gprmask |= r->ri_gprmask;
249 sec->getFile<ELFT>()->mipsGp0 = r->ri_gp_value;
244250 };
245251
246 return make<MipsReginfoSection<ELFT>>(Reginfo);
252 return make<MipsReginfoSection<ELFT>>(reginfo);
247253}
248254
249255InputSection *elf::createInterpSection() {
250256 // StringSaver guarantees that the returned string ends with '\0'.
251 StringRef S = Saver.save(Config->DynamicLinker);
252 ArrayRef<uint8_t> Contents = {(const uint8_t *)S.data(), S.size() + 1};
257 StringRef s = saver.save(config->dynamicLinker);
258 ArrayRef<uint8_t> contents = {(const uint8_t *)s.data(), s.size() + 1};
253259
254 auto *Sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, Contents,
260 auto *sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, contents,
255261 ".interp");
256 Sec->Live = true;
257 return Sec;
262 sec->markLive();
263 return sec;
258264}
259265
260Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
261 uint64_t Size, InputSectionBase &Section) {
262 auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type,
263 Value, Size, &Section);
264 if (In.SymTab)
265 In.SymTab->addSymbol(S);
266 return S;
266Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
267 uint64_t size, InputSectionBase &section) {
268 auto *s = make<Defined>(section.file, name, STB_LOCAL, STV_DEFAULT, type,
269 value, size, &section);
270 if (in.symTab)
271 in.symTab->addSymbol(s);
272 return s;
267273}
268274
269275static size_t getHashSize() {
270 switch (Config->BuildId) {
276 switch (config->buildId) {
271277 case BuildIdKind::Fast:
272278 return 8;
273279 case BuildIdKind::Md5:
......@@ -276,89 +282,67 @@ static size_t getHashSize() {
276282 case BuildIdKind::Sha1:
277283 return 20;
278284 case BuildIdKind::Hexstring:
279 return Config->BuildIdVector.size();
285 return config->buildIdVector.size();
280286 default:
281287 llvm_unreachable("unknown BuildIdKind");
282288 }
283289}
284290
291// This class represents a linker-synthesized .note.gnu.property section.
292//
293// In x86 and AArch64, object files may contain feature flags indicating the
294// features that they have used. The flags are stored in a .note.gnu.property
295// section.
296//
297// lld reads the sections from input files and merges them by computing AND of
298// the flags. The result is written as a new .note.gnu.property section.
299//
300// If the flag is zero (which indicates that the intersection of the feature
301// sets is empty, or some input files didn't have .note.gnu.property sections),
302// we don't create this section.
303GnuPropertySection::GnuPropertySection()
304 : SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE, 4,
305 ".note.gnu.property") {}
306
307void GnuPropertySection::writeTo(uint8_t *buf) {
308 uint32_t featureAndType = config->emachine == EM_AARCH64
309 ? GNU_PROPERTY_AARCH64_FEATURE_1_AND
310 : GNU_PROPERTY_X86_FEATURE_1_AND;
311
312 write32(buf, 4); // Name size
313 write32(buf + 4, config->is64 ? 16 : 12); // Content size
314 write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
315 memcpy(buf + 12, "GNU", 4); // Name string
316 write32(buf + 16, featureAndType); // Feature type
317 write32(buf + 20, 4); // Feature size
318 write32(buf + 24, config->andFeatures); // Feature flags
319 if (config->is64)
320 write32(buf + 28, 0); // Padding
321}
322
323size_t GnuPropertySection::getSize() const { return config->is64 ? 32 : 28; }
324
285325BuildIdSection::BuildIdSection()
286326 : SyntheticSection(SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"),
287 HashSize(getHashSize()) {}
288
289void BuildIdSection::writeTo(uint8_t *Buf) {
290 write32(Buf, 4); // Name size
291 write32(Buf + 4, HashSize); // Content size
292 write32(Buf + 8, NT_GNU_BUILD_ID); // Type
293 memcpy(Buf + 12, "GNU", 4); // Name string
294 HashBuf = Buf + 16;
295}
296
297// Split one uint8 array into small pieces of uint8 arrays.
298static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr,
299 size_t ChunkSize) {
300 std::vector<ArrayRef<uint8_t>> Ret;
301 while (Arr.size() > ChunkSize) {
302 Ret.push_back(Arr.take_front(ChunkSize));
303 Arr = Arr.drop_front(ChunkSize);
304 }
305 if (!Arr.empty())
306 Ret.push_back(Arr);
307 return Ret;
308}
309
310// Computes a hash value of Data using a given hash function.
311// In order to utilize multiple cores, we first split data into 1MB
312// chunks, compute a hash for each chunk, and then compute a hash value
313// of the hash values.
314void BuildIdSection::computeHash(
315 llvm::ArrayRef<uint8_t> Data,
316 std::function<void(uint8_t *Dest, ArrayRef<uint8_t> Arr)> HashFn) {
317 std::vector<ArrayRef<uint8_t>> Chunks = split(Data, 1024 * 1024);
318 std::vector<uint8_t> Hashes(Chunks.size() * HashSize);
319
320 // Compute hash values.
321 parallelForEachN(0, Chunks.size(), [&](size_t I) {
322 HashFn(Hashes.data() + I * HashSize, Chunks[I]);
323 });
327 hashSize(getHashSize()) {}
324328
325 // Write to the final output buffer.
326 HashFn(HashBuf, Hashes);
329void BuildIdSection::writeTo(uint8_t *buf) {
330 write32(buf, 4); // Name size
331 write32(buf + 4, hashSize); // Content size
332 write32(buf + 8, NT_GNU_BUILD_ID); // Type
333 memcpy(buf + 12, "GNU", 4); // Name string
334 hashBuf = buf + 16;
327335}
328336
329BssSection::BssSection(StringRef Name, uint64_t Size, uint32_t Alignment)
330 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Name) {
331 this->Bss = true;
332 this->Size = Size;
337void BuildIdSection::writeBuildId(ArrayRef<uint8_t> buf) {
338 assert(buf.size() == hashSize);
339 memcpy(hashBuf, buf.data(), hashSize);
333340}
334341
335void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) {
336 switch (Config->BuildId) {
337 case BuildIdKind::Fast:
338 computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
339 write64le(Dest, xxHash64(Arr));
340 });
341 break;
342 case BuildIdKind::Md5:
343 computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
344 memcpy(Dest, MD5::hash(Arr).data(), 16);
345 });
346 break;
347 case BuildIdKind::Sha1:
348 computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
349 memcpy(Dest, SHA1::hash(Arr).data(), 20);
350 });
351 break;
352 case BuildIdKind::Uuid:
353 if (auto EC = getRandomBytes(HashBuf, HashSize))
354 error("entropy source failure: " + EC.message());
355 break;
356 case BuildIdKind::Hexstring:
357 memcpy(HashBuf, Config->BuildIdVector.data(), Config->BuildIdVector.size());
358 break;
359 default:
360 llvm_unreachable("unknown BuildIdKind");
361 }
342BssSection::BssSection(StringRef name, uint64_t size, uint32_t alignment)
343 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, alignment, name) {
344 this->bss = true;
345 this->size = size;
362346}
363347
364348EhFrameSection::EhFrameSection()
......@@ -368,47 +352,48 @@ EhFrameSection::EhFrameSection()
368352// CIE records from input object files are uniquified by their contents
369353// and where their relocations point to.
370354template <class ELFT, class RelTy>
371CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, ArrayRef<RelTy> Rels) {
372 Symbol *Personality = nullptr;
373 unsigned FirstRelI = Cie.FirstRelocation;
374 if (FirstRelI != (unsigned)-1)
375 Personality =
376 &Cie.Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]);
355CieRecord *EhFrameSection::addCie(EhSectionPiece &cie, ArrayRef<RelTy> rels) {
356 Symbol *personality = nullptr;
357 unsigned firstRelI = cie.firstRelocation;
358 if (firstRelI != (unsigned)-1)
359 personality =
360 &cie.sec->template getFile<ELFT>()->getRelocTargetSym(rels[firstRelI]);
377361
378362 // Search for an existing CIE by CIE contents/relocation target pair.
379 CieRecord *&Rec = CieMap[{Cie.data(), Personality}];
363 CieRecord *&rec = cieMap[{cie.data(), personality}];
380364
381365 // If not found, create a new one.
382 if (!Rec) {
383 Rec = make<CieRecord>();
384 Rec->Cie = &Cie;
385 CieRecords.push_back(Rec);
366 if (!rec) {
367 rec = make<CieRecord>();
368 rec->cie = &cie;
369 cieRecords.push_back(rec);
386370 }
387 return Rec;
371 return rec;
388372}
389373
390374// There is one FDE per function. Returns true if a given FDE
391375// points to a live function.
392376template <class ELFT, class RelTy>
393bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) {
394 auto *Sec = cast<EhInputSection>(Fde.Sec);
395 unsigned FirstRelI = Fde.FirstRelocation;
377bool EhFrameSection::isFdeLive(EhSectionPiece &fde, ArrayRef<RelTy> rels) {
378 auto *sec = cast<EhInputSection>(fde.sec);
379 unsigned firstRelI = fde.firstRelocation;
396380
397381 // An FDE should point to some function because FDEs are to describe
398382 // functions. That's however not always the case due to an issue of
399383 // ld.gold with -r. ld.gold may discard only functions and leave their
400384 // corresponding FDEs, which results in creating bad .eh_frame sections.
401385 // To deal with that, we ignore such FDEs.
402 if (FirstRelI == (unsigned)-1)
386 if (firstRelI == (unsigned)-1)
403387 return false;
404388
405 const RelTy &Rel = Rels[FirstRelI];
406 Symbol &B = Sec->template getFile<ELFT>()->getRelocTargetSym(Rel);
389 const RelTy &rel = rels[firstRelI];
390 Symbol &b = sec->template getFile<ELFT>()->getRelocTargetSym(rel);
407391
408 // FDEs for garbage-collected or merged-by-ICF sections are dead.
409 if (auto *D = dyn_cast<Defined>(&B))
410 if (SectionBase *Sec = D->Section)
411 return Sec->Live;
392 // FDEs for garbage-collected or merged-by-ICF sections, or sections in
393 // another partition, are dead.
394 if (auto *d = dyn_cast<Defined>(&b))
395 if (SectionBase *sec = d->section)
396 return sec->partition == partition;
412397 return false;
413398}
414399
......@@ -417,73 +402,73 @@ bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) {
417402// a list of FDEs. This function searches an existing CIE or create a new
418403// one and associates FDEs to the CIE.
419404template <class ELFT, class RelTy>
420void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) {
421 OffsetToCie.clear();
422 for (EhSectionPiece &Piece : Sec->Pieces) {
405void EhFrameSection::addSectionAux(EhInputSection *sec, ArrayRef<RelTy> rels) {
406 offsetToCie.clear();
407 for (EhSectionPiece &piece : sec->pieces) {
423408 // The empty record is the end marker.
424 if (Piece.Size == 4)
409 if (piece.size == 4)
425410 return;
426411
427 size_t Offset = Piece.InputOff;
428 uint32_t ID = read32(Piece.data().data() + 4);
429 if (ID == 0) {
430 OffsetToCie[Offset] = addCie<ELFT>(Piece, Rels);
412 size_t offset = piece.inputOff;
413 uint32_t id = read32(piece.data().data() + 4);
414 if (id == 0) {
415 offsetToCie[offset] = addCie<ELFT>(piece, rels);
431416 continue;
432417 }
433418
434 uint32_t CieOffset = Offset + 4 - ID;
435 CieRecord *Rec = OffsetToCie[CieOffset];
436 if (!Rec)
437 fatal(toString(Sec) + ": invalid CIE reference");
419 uint32_t cieOffset = offset + 4 - id;
420 CieRecord *rec = offsetToCie[cieOffset];
421 if (!rec)
422 fatal(toString(sec) + ": invalid CIE reference");
438423
439 if (!isFdeLive<ELFT>(Piece, Rels))
424 if (!isFdeLive<ELFT>(piece, rels))
440425 continue;
441 Rec->Fdes.push_back(&Piece);
442 NumFdes++;
426 rec->fdes.push_back(&piece);
427 numFdes++;
443428 }
444429}
445430
446template <class ELFT> void EhFrameSection::addSection(InputSectionBase *C) {
447 auto *Sec = cast<EhInputSection>(C);
448 Sec->Parent = this;
431template <class ELFT> void EhFrameSection::addSection(InputSectionBase *c) {
432 auto *sec = cast<EhInputSection>(c);
433 sec->parent = this;
449434
450 Alignment = std::max(Alignment, Sec->Alignment);
451 Sections.push_back(Sec);
435 alignment = std::max(alignment, sec->alignment);
436 sections.push_back(sec);
452437
453 for (auto *DS : Sec->DependentSections)
454 DependentSections.push_back(DS);
438 for (auto *ds : sec->dependentSections)
439 dependentSections.push_back(ds);
455440
456 if (Sec->Pieces.empty())
441 if (sec->pieces.empty())
457442 return;
458443
459 if (Sec->AreRelocsRela)
460 addSectionAux<ELFT>(Sec, Sec->template relas<ELFT>());
444 if (sec->areRelocsRela)
445 addSectionAux<ELFT>(sec, sec->template relas<ELFT>());
461446 else
462 addSectionAux<ELFT>(Sec, Sec->template rels<ELFT>());
447 addSectionAux<ELFT>(sec, sec->template rels<ELFT>());
463448}
464449
465static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) {
466 memcpy(Buf, D.data(), D.size());
450static void writeCieFde(uint8_t *buf, ArrayRef<uint8_t> d) {
451 memcpy(buf, d.data(), d.size());
467452
468 size_t Aligned = alignTo(D.size(), Config->Wordsize);
453 size_t aligned = alignTo(d.size(), config->wordsize);
469454
470455 // Zero-clear trailing padding if it exists.
471 memset(Buf + D.size(), 0, Aligned - D.size());
456 memset(buf + d.size(), 0, aligned - d.size());
472457
473458 // Fix the size field. -4 since size does not include the size field itself.
474 write32(Buf, Aligned - 4);
459 write32(buf, aligned - 4);
475460}
476461
477462void EhFrameSection::finalizeContents() {
478 assert(!this->Size); // Not finalized.
479 size_t Off = 0;
480 for (CieRecord *Rec : CieRecords) {
481 Rec->Cie->OutputOff = Off;
482 Off += alignTo(Rec->Cie->Size, Config->Wordsize);
483
484 for (EhSectionPiece *Fde : Rec->Fdes) {
485 Fde->OutputOff = Off;
486 Off += alignTo(Fde->Size, Config->Wordsize);
463 assert(!this->size); // Not finalized.
464 size_t off = 0;
465 for (CieRecord *rec : cieRecords) {
466 rec->cie->outputOff = off;
467 off += alignTo(rec->cie->size, config->wordsize);
468
469 for (EhSectionPiece *fde : rec->fdes) {
470 fde->outputOff = off;
471 off += alignTo(fde->size, config->wordsize);
487472 }
488473 }
489474
......@@ -491,375 +476,374 @@ void EhFrameSection::finalizeContents() {
491476 // Call Frame Information records. glibc unwind-dw2-fde.c
492477 // classify_object_over_fdes expects there is a CIE record length 0 as a
493478 // terminator. Thus we add one unconditionally.
494 Off += 4;
479 off += 4;
495480
496 this->Size = Off;
481 this->size = off;
497482}
498483
499484// Returns data for .eh_frame_hdr. .eh_frame_hdr is a binary search table
500485// to get an FDE from an address to which FDE is applied. This function
501486// returns a list of such pairs.
502487std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {
503 uint8_t *Buf = getParent()->Loc + OutSecOff;
504 std::vector<FdeData> Ret;
505
506 uint64_t VA = In.EhFrameHdr->getVA();
507 for (CieRecord *Rec : CieRecords) {
508 uint8_t Enc = getFdeEncoding(Rec->Cie);
509 for (EhSectionPiece *Fde : Rec->Fdes) {
510 uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
511 uint64_t FdeVA = getParent()->Addr + Fde->OutputOff;
512 if (!isInt<32>(Pc - VA))
513 fatal(toString(Fde->Sec) + ": PC offset is too large: 0x" +
514 Twine::utohexstr(Pc - VA));
515 Ret.push_back({uint32_t(Pc - VA), uint32_t(FdeVA - VA)});
488 uint8_t *buf = Out::bufferStart + getParent()->offset + outSecOff;
489 std::vector<FdeData> ret;
490
491 uint64_t va = getPartition().ehFrameHdr->getVA();
492 for (CieRecord *rec : cieRecords) {
493 uint8_t enc = getFdeEncoding(rec->cie);
494 for (EhSectionPiece *fde : rec->fdes) {
495 uint64_t pc = getFdePc(buf, fde->outputOff, enc);
496 uint64_t fdeVA = getParent()->addr + fde->outputOff;
497 if (!isInt<32>(pc - va))
498 fatal(toString(fde->sec) + ": PC offset is too large: 0x" +
499 Twine::utohexstr(pc - va));
500 ret.push_back({uint32_t(pc - va), uint32_t(fdeVA - va)});
516501 }
517502 }
518503
519504 // Sort the FDE list by their PC and uniqueify. Usually there is only
520505 // one FDE for a PC (i.e. function), but if ICF merges two functions
521506 // into one, there can be more than one FDEs pointing to the address.
522 auto Less = [](const FdeData &A, const FdeData &B) {
523 return A.PcRel < B.PcRel;
507 auto less = [](const FdeData &a, const FdeData &b) {
508 return a.pcRel < b.pcRel;
524509 };
525 std::stable_sort(Ret.begin(), Ret.end(), Less);
526 auto Eq = [](const FdeData &A, const FdeData &B) {
527 return A.PcRel == B.PcRel;
510 llvm::stable_sort(ret, less);
511 auto eq = [](const FdeData &a, const FdeData &b) {
512 return a.pcRel == b.pcRel;
528513 };
529 Ret.erase(std::unique(Ret.begin(), Ret.end(), Eq), Ret.end());
514 ret.erase(std::unique(ret.begin(), ret.end(), eq), ret.end());
530515
531 return Ret;
516 return ret;
532517}
533518
534static uint64_t readFdeAddr(uint8_t *Buf, int Size) {
535 switch (Size) {
519static uint64_t readFdeAddr(uint8_t *buf, int size) {
520 switch (size) {
536521 case DW_EH_PE_udata2:
537 return read16(Buf);
522 return read16(buf);
538523 case DW_EH_PE_sdata2:
539 return (int16_t)read16(Buf);
524 return (int16_t)read16(buf);
540525 case DW_EH_PE_udata4:
541 return read32(Buf);
526 return read32(buf);
542527 case DW_EH_PE_sdata4:
543 return (int32_t)read32(Buf);
528 return (int32_t)read32(buf);
544529 case DW_EH_PE_udata8:
545530 case DW_EH_PE_sdata8:
546 return read64(Buf);
531 return read64(buf);
547532 case DW_EH_PE_absptr:
548 return readUint(Buf);
533 return readUint(buf);
549534 }
550535 fatal("unknown FDE size encoding");
551536}
552537
553538// Returns the VA to which a given FDE (on a mmap'ed buffer) is applied to.
554539// We need it to create .eh_frame_hdr section.
555uint64_t EhFrameSection::getFdePc(uint8_t *Buf, size_t FdeOff,
556 uint8_t Enc) const {
540uint64_t EhFrameSection::getFdePc(uint8_t *buf, size_t fdeOff,
541 uint8_t enc) const {
557542 // The starting address to which this FDE applies is
558543 // stored at FDE + 8 byte.
559 size_t Off = FdeOff + 8;
560 uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0xf);
561 if ((Enc & 0x70) == DW_EH_PE_absptr)
562 return Addr;
563 if ((Enc & 0x70) == DW_EH_PE_pcrel)
564 return Addr + getParent()->Addr + Off;
544 size_t off = fdeOff + 8;
545 uint64_t addr = readFdeAddr(buf + off, enc & 0xf);
546 if ((enc & 0x70) == DW_EH_PE_absptr)
547 return addr;
548 if ((enc & 0x70) == DW_EH_PE_pcrel)
549 return addr + getParent()->addr + off;
565550 fatal("unknown FDE size relative encoding");
566551}
567552
568void EhFrameSection::writeTo(uint8_t *Buf) {
553void EhFrameSection::writeTo(uint8_t *buf) {
569554 // Write CIE and FDE records.
570 for (CieRecord *Rec : CieRecords) {
571 size_t CieOffset = Rec->Cie->OutputOff;
572 writeCieFde(Buf + CieOffset, Rec->Cie->data());
555 for (CieRecord *rec : cieRecords) {
556 size_t cieOffset = rec->cie->outputOff;
557 writeCieFde(buf + cieOffset, rec->cie->data());
573558
574 for (EhSectionPiece *Fde : Rec->Fdes) {
575 size_t Off = Fde->OutputOff;
576 writeCieFde(Buf + Off, Fde->data());
559 for (EhSectionPiece *fde : rec->fdes) {
560 size_t off = fde->outputOff;
561 writeCieFde(buf + off, fde->data());
577562
578563 // FDE's second word should have the offset to an associated CIE.
579564 // Write it.
580 write32(Buf + Off + 4, Off + 4 - CieOffset);
565 write32(buf + off + 4, off + 4 - cieOffset);
581566 }
582567 }
583568
584569 // Apply relocations. .eh_frame section contents are not contiguous
585570 // in the output buffer, but relocateAlloc() still works because
586571 // getOffset() takes care of discontiguous section pieces.
587 for (EhInputSection *S : Sections)
588 S->relocateAlloc(Buf, nullptr);
572 for (EhInputSection *s : sections)
573 s->relocateAlloc(buf, nullptr);
574
575 if (getPartition().ehFrameHdr && getPartition().ehFrameHdr->getParent())
576 getPartition().ehFrameHdr->write();
589577}
590578
591579GotSection::GotSection()
592 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
593 Target->GotEntrySize, ".got") {
594 // PPC64 saves the ElfSym::GlobalOffsetTable .TOC. as the first entry in the
595 // .got. If there are no references to .TOC. in the symbol table,
596 // ElfSym::GlobalOffsetTable will not be defined and we won't need to save
597 // .TOC. in the .got. When it is defined, we increase NumEntries by the number
598 // of entries used to emit ElfSym::GlobalOffsetTable.
599 if (ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt)
600 NumEntries += Target->GotHeaderEntriesNum;
580 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
581 ".got") {
582 // If ElfSym::globalOffsetTable is relative to .got and is referenced,
583 // increase numEntries by the number of entries used to emit
584 // ElfSym::globalOffsetTable.
585 if (ElfSym::globalOffsetTable && !target->gotBaseSymInGotPlt)
586 numEntries += target->gotHeaderEntriesNum;
601587}
602588
603void GotSection::addEntry(Symbol &Sym) {
604 Sym.GotIndex = NumEntries;
605 ++NumEntries;
589void GotSection::addEntry(Symbol &sym) {
590 sym.gotIndex = numEntries;
591 ++numEntries;
606592}
607593
608bool GotSection::addDynTlsEntry(Symbol &Sym) {
609 if (Sym.GlobalDynIndex != -1U)
594bool GotSection::addDynTlsEntry(Symbol &sym) {
595 if (sym.globalDynIndex != -1U)
610596 return false;
611 Sym.GlobalDynIndex = NumEntries;
597 sym.globalDynIndex = numEntries;
612598 // Global Dynamic TLS entries take two GOT slots.
613 NumEntries += 2;
599 numEntries += 2;
614600 return true;
615601}
616602
617603// Reserves TLS entries for a TLS module ID and a TLS block offset.
618604// In total it takes two GOT slots.
619605bool GotSection::addTlsIndex() {
620 if (TlsIndexOff != uint32_t(-1))
606 if (tlsIndexOff != uint32_t(-1))
621607 return false;
622 TlsIndexOff = NumEntries * Config->Wordsize;
623 NumEntries += 2;
608 tlsIndexOff = numEntries * config->wordsize;
609 numEntries += 2;
624610 return true;
625611}
626612
627uint64_t GotSection::getGlobalDynAddr(const Symbol &B) const {
628 return this->getVA() + B.GlobalDynIndex * Config->Wordsize;
613uint64_t GotSection::getGlobalDynAddr(const Symbol &b) const {
614 return this->getVA() + b.globalDynIndex * config->wordsize;
629615}
630616
631uint64_t GotSection::getGlobalDynOffset(const Symbol &B) const {
632 return B.GlobalDynIndex * Config->Wordsize;
617uint64_t GotSection::getGlobalDynOffset(const Symbol &b) const {
618 return b.globalDynIndex * config->wordsize;
633619}
634620
635621void GotSection::finalizeContents() {
636 Size = NumEntries * Config->Wordsize;
622 size = numEntries * config->wordsize;
637623}
638624
639bool GotSection::empty() const {
625bool GotSection::isNeeded() const {
640626 // We need to emit a GOT even if it's empty if there's a relocation that is
641 // relative to GOT(such as GOTOFFREL) or there's a symbol that points to a GOT
642 // (i.e. _GLOBAL_OFFSET_TABLE_) that the target defines relative to the .got.
643 return NumEntries == 0 && !HasGotOffRel &&
644 !(ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt);
627 // relative to GOT(such as GOTOFFREL).
628 return numEntries || hasGotOffRel;
645629}
646630
647void GotSection::writeTo(uint8_t *Buf) {
631void GotSection::writeTo(uint8_t *buf) {
648632 // Buf points to the start of this section's buffer,
649633 // whereas InputSectionBase::relocateAlloc() expects its argument
650634 // to point to the start of the output section.
651 Target->writeGotHeader(Buf);
652 relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + Size);
635 target->writeGotHeader(buf);
636 relocateAlloc(buf - outSecOff, buf - outSecOff + size);
653637}
654638
655static uint64_t getMipsPageAddr(uint64_t Addr) {
656 return (Addr + 0x8000) & ~0xffff;
639static uint64_t getMipsPageAddr(uint64_t addr) {
640 return (addr + 0x8000) & ~0xffff;
657641}
658642
659static uint64_t getMipsPageCount(uint64_t Size) {
660 return (Size + 0xfffe) / 0xffff + 1;
643static uint64_t getMipsPageCount(uint64_t size) {
644 return (size + 0xfffe) / 0xffff + 1;
661645}
662646
663647MipsGotSection::MipsGotSection()
664648 : SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16,
665649 ".got") {}
666650
667void MipsGotSection::addEntry(InputFile &File, Symbol &Sym, int64_t Addend,
668 RelExpr Expr) {
669 FileGot &G = getGot(File);
670 if (Expr == R_MIPS_GOT_LOCAL_PAGE) {
671 if (const OutputSection *OS = Sym.getOutputSection())
672 G.PagesMap.insert({OS, {}});
651void MipsGotSection::addEntry(InputFile &file, Symbol &sym, int64_t addend,
652 RelExpr expr) {
653 FileGot &g = getGot(file);
654 if (expr == R_MIPS_GOT_LOCAL_PAGE) {
655 if (const OutputSection *os = sym.getOutputSection())
656 g.pagesMap.insert({os, {}});
673657 else
674 G.Local16.insert({{nullptr, getMipsPageAddr(Sym.getVA(Addend))}, 0});
675 } else if (Sym.isTls())
676 G.Tls.insert({&Sym, 0});
677 else if (Sym.IsPreemptible && Expr == R_ABS)
678 G.Relocs.insert({&Sym, 0});
679 else if (Sym.IsPreemptible)
680 G.Global.insert({&Sym, 0});
681 else if (Expr == R_MIPS_GOT_OFF32)
682 G.Local32.insert({{&Sym, Addend}, 0});
658 g.local16.insert({{nullptr, getMipsPageAddr(sym.getVA(addend))}, 0});
659 } else if (sym.isTls())
660 g.tls.insert({&sym, 0});
661 else if (sym.isPreemptible && expr == R_ABS)
662 g.relocs.insert({&sym, 0});
663 else if (sym.isPreemptible)
664 g.global.insert({&sym, 0});
665 else if (expr == R_MIPS_GOT_OFF32)
666 g.local32.insert({{&sym, addend}, 0});
683667 else
684 G.Local16.insert({{&Sym, Addend}, 0});
668 g.local16.insert({{&sym, addend}, 0});
685669}
686670
687void MipsGotSection::addDynTlsEntry(InputFile &File, Symbol &Sym) {
688 getGot(File).DynTlsSymbols.insert({&Sym, 0});
671void MipsGotSection::addDynTlsEntry(InputFile &file, Symbol &sym) {
672 getGot(file).dynTlsSymbols.insert({&sym, 0});
689673}
690674
691void MipsGotSection::addTlsIndex(InputFile &File) {
692 getGot(File).DynTlsSymbols.insert({nullptr, 0});
675void MipsGotSection::addTlsIndex(InputFile &file) {
676 getGot(file).dynTlsSymbols.insert({nullptr, 0});
693677}
694678
695679size_t MipsGotSection::FileGot::getEntriesNum() const {
696 return getPageEntriesNum() + Local16.size() + Global.size() + Relocs.size() +
697 Tls.size() + DynTlsSymbols.size() * 2;
680 return getPageEntriesNum() + local16.size() + global.size() + relocs.size() +
681 tls.size() + dynTlsSymbols.size() * 2;
698682}
699683
700684size_t MipsGotSection::FileGot::getPageEntriesNum() const {
701 size_t Num = 0;
702 for (const std::pair<const OutputSection *, FileGot::PageBlock> &P : PagesMap)
703 Num += P.second.Count;
704 return Num;
685 size_t num = 0;
686 for (const std::pair<const OutputSection *, FileGot::PageBlock> &p : pagesMap)
687 num += p.second.count;
688 return num;
705689}
706690
707691size_t MipsGotSection::FileGot::getIndexedEntriesNum() const {
708 size_t Count = getPageEntriesNum() + Local16.size() + Global.size();
692 size_t count = getPageEntriesNum() + local16.size() + global.size();
709693 // If there are relocation-only entries in the GOT, TLS entries
710694 // are allocated after them. TLS entries should be addressable
711695 // by 16-bit index so count both reloc-only and TLS entries.
712 if (!Tls.empty() || !DynTlsSymbols.empty())
713 Count += Relocs.size() + Tls.size() + DynTlsSymbols.size() * 2;
714 return Count;
696 if (!tls.empty() || !dynTlsSymbols.empty())
697 count += relocs.size() + tls.size() + dynTlsSymbols.size() * 2;
698 return count;
715699}
716700
717MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &F) {
718 if (!F.MipsGotIndex.hasValue()) {
719 Gots.emplace_back();
720 Gots.back().File = &F;
721 F.MipsGotIndex = Gots.size() - 1;
701MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &f) {
702 if (!f.mipsGotIndex.hasValue()) {
703 gots.emplace_back();
704 gots.back().file = &f;
705 f.mipsGotIndex = gots.size() - 1;
722706 }
723 return Gots[*F.MipsGotIndex];
707 return gots[*f.mipsGotIndex];
724708}
725709
726uint64_t MipsGotSection::getPageEntryOffset(const InputFile *F,
727 const Symbol &Sym,
728 int64_t Addend) const {
729 const FileGot &G = Gots[*F->MipsGotIndex];
730 uint64_t Index = 0;
731 if (const OutputSection *OutSec = Sym.getOutputSection()) {
732 uint64_t SecAddr = getMipsPageAddr(OutSec->Addr);
733 uint64_t SymAddr = getMipsPageAddr(Sym.getVA(Addend));
734 Index = G.PagesMap.lookup(OutSec).FirstIndex + (SymAddr - SecAddr) / 0xffff;
710uint64_t MipsGotSection::getPageEntryOffset(const InputFile *f,
711 const Symbol &sym,
712 int64_t addend) const {
713 const FileGot &g = gots[*f->mipsGotIndex];
714 uint64_t index = 0;
715 if (const OutputSection *outSec = sym.getOutputSection()) {
716 uint64_t secAddr = getMipsPageAddr(outSec->addr);
717 uint64_t symAddr = getMipsPageAddr(sym.getVA(addend));
718 index = g.pagesMap.lookup(outSec).firstIndex + (symAddr - secAddr) / 0xffff;
735719 } else {
736 Index = G.Local16.lookup({nullptr, getMipsPageAddr(Sym.getVA(Addend))});
720 index = g.local16.lookup({nullptr, getMipsPageAddr(sym.getVA(addend))});
737721 }
738 return Index * Config->Wordsize;
722 return index * config->wordsize;
739723}
740724
741uint64_t MipsGotSection::getSymEntryOffset(const InputFile *F, const Symbol &S,
742 int64_t Addend) const {
743 const FileGot &G = Gots[*F->MipsGotIndex];
744 Symbol *Sym = const_cast<Symbol *>(&S);
745 if (Sym->isTls())
746 return G.Tls.lookup(Sym) * Config->Wordsize;
747 if (Sym->IsPreemptible)
748 return G.Global.lookup(Sym) * Config->Wordsize;
749 return G.Local16.lookup({Sym, Addend}) * Config->Wordsize;
725uint64_t MipsGotSection::getSymEntryOffset(const InputFile *f, const Symbol &s,
726 int64_t addend) const {
727 const FileGot &g = gots[*f->mipsGotIndex];
728 Symbol *sym = const_cast<Symbol *>(&s);
729 if (sym->isTls())
730 return g.tls.lookup(sym) * config->wordsize;
731 if (sym->isPreemptible)
732 return g.global.lookup(sym) * config->wordsize;
733 return g.local16.lookup({sym, addend}) * config->wordsize;
750734}
751735
752uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *F) const {
753 const FileGot &G = Gots[*F->MipsGotIndex];
754 return G.DynTlsSymbols.lookup(nullptr) * Config->Wordsize;
736uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *f) const {
737 const FileGot &g = gots[*f->mipsGotIndex];
738 return g.dynTlsSymbols.lookup(nullptr) * config->wordsize;
755739}
756740
757uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *F,
758 const Symbol &S) const {
759 const FileGot &G = Gots[*F->MipsGotIndex];
760 Symbol *Sym = const_cast<Symbol *>(&S);
761 return G.DynTlsSymbols.lookup(Sym) * Config->Wordsize;
741uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *f,
742 const Symbol &s) const {
743 const FileGot &g = gots[*f->mipsGotIndex];
744 Symbol *sym = const_cast<Symbol *>(&s);
745 return g.dynTlsSymbols.lookup(sym) * config->wordsize;
762746}
763747
764748const Symbol *MipsGotSection::getFirstGlobalEntry() const {
765 if (Gots.empty())
749 if (gots.empty())
766750 return nullptr;
767 const FileGot &PrimGot = Gots.front();
768 if (!PrimGot.Global.empty())
769 return PrimGot.Global.front().first;
770 if (!PrimGot.Relocs.empty())
771 return PrimGot.Relocs.front().first;
751 const FileGot &primGot = gots.front();
752 if (!primGot.global.empty())
753 return primGot.global.front().first;
754 if (!primGot.relocs.empty())
755 return primGot.relocs.front().first;
772756 return nullptr;
773757}
774758
775759unsigned MipsGotSection::getLocalEntriesNum() const {
776 if (Gots.empty())
777 return HeaderEntriesNum;
778 return HeaderEntriesNum + Gots.front().getPageEntriesNum() +
779 Gots.front().Local16.size();
760 if (gots.empty())
761 return headerEntriesNum;
762 return headerEntriesNum + gots.front().getPageEntriesNum() +
763 gots.front().local16.size();
780764}
781765
782bool MipsGotSection::tryMergeGots(FileGot &Dst, FileGot &Src, bool IsPrimary) {
783 FileGot Tmp = Dst;
784 set_union(Tmp.PagesMap, Src.PagesMap);
785 set_union(Tmp.Local16, Src.Local16);
786 set_union(Tmp.Global, Src.Global);
787 set_union(Tmp.Relocs, Src.Relocs);
788 set_union(Tmp.Tls, Src.Tls);
789 set_union(Tmp.DynTlsSymbols, Src.DynTlsSymbols);
766bool MipsGotSection::tryMergeGots(FileGot &dst, FileGot &src, bool isPrimary) {
767 FileGot tmp = dst;
768 set_union(tmp.pagesMap, src.pagesMap);
769 set_union(tmp.local16, src.local16);
770 set_union(tmp.global, src.global);
771 set_union(tmp.relocs, src.relocs);
772 set_union(tmp.tls, src.tls);
773 set_union(tmp.dynTlsSymbols, src.dynTlsSymbols);
790774
791 size_t Count = IsPrimary ? HeaderEntriesNum : 0;
792 Count += Tmp.getIndexedEntriesNum();
775 size_t count = isPrimary ? headerEntriesNum : 0;
776 count += tmp.getIndexedEntriesNum();
793777
794 if (Count * Config->Wordsize > Config->MipsGotSize)
778 if (count * config->wordsize > config->mipsGotSize)
795779 return false;
796780
797 std::swap(Tmp, Dst);
781 std::swap(tmp, dst);
798782 return true;
799783}
800784
801785void MipsGotSection::finalizeContents() { updateAllocSize(); }
802786
803787bool MipsGotSection::updateAllocSize() {
804 Size = HeaderEntriesNum * Config->Wordsize;
805 for (const FileGot &G : Gots)
806 Size += G.getEntriesNum() * Config->Wordsize;
788 size = headerEntriesNum * config->wordsize;
789 for (const FileGot &g : gots)
790 size += g.getEntriesNum() * config->wordsize;
807791 return false;
808792}
809793
810template <class ELFT> void MipsGotSection::build() {
811 if (Gots.empty())
794void MipsGotSection::build() {
795 if (gots.empty())
812796 return;
813797
814 std::vector<FileGot> MergedGots(1);
798 std::vector<FileGot> mergedGots(1);
815799
816800 // For each GOT move non-preemptible symbols from the `Global`
817801 // to `Local16` list. Preemptible symbol might become non-preemptible
818802 // one if, for example, it gets a related copy relocation.
819 for (FileGot &Got : Gots) {
820 for (auto &P: Got.Global)
821 if (!P.first->IsPreemptible)
822 Got.Local16.insert({{P.first, 0}, 0});
823 Got.Global.remove_if([&](const std::pair<Symbol *, size_t> &P) {
824 return !P.first->IsPreemptible;
803 for (FileGot &got : gots) {
804 for (auto &p: got.global)
805 if (!p.first->isPreemptible)
806 got.local16.insert({{p.first, 0}, 0});
807 got.global.remove_if([&](const std::pair<Symbol *, size_t> &p) {
808 return !p.first->isPreemptible;
825809 });
826810 }
827811
828812 // For each GOT remove "reloc-only" entry if there is "global"
829813 // entry for the same symbol. And add local entries which indexed
830814 // using 32-bit value at the end of 16-bit entries.
831 for (FileGot &Got : Gots) {
832 Got.Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) {
833 return Got.Global.count(P.first);
815 for (FileGot &got : gots) {
816 got.relocs.remove_if([&](const std::pair<Symbol *, size_t> &p) {
817 return got.global.count(p.first);
834818 });
835 set_union(Got.Local16, Got.Local32);
836 Got.Local32.clear();
819 set_union(got.local16, got.local32);
820 got.local32.clear();
837821 }
838822
839823 // Evaluate number of "reloc-only" entries in the resulting GOT.
840824 // To do that put all unique "reloc-only" and "global" entries
841825 // from all GOTs to the future primary GOT.
842 FileGot *PrimGot = &MergedGots.front();
843 for (FileGot &Got : Gots) {
844 set_union(PrimGot->Relocs, Got.Global);
845 set_union(PrimGot->Relocs, Got.Relocs);
846 Got.Relocs.clear();
826 FileGot *primGot = &mergedGots.front();
827 for (FileGot &got : gots) {
828 set_union(primGot->relocs, got.global);
829 set_union(primGot->relocs, got.relocs);
830 got.relocs.clear();
847831 }
848832
849833 // Evaluate number of "page" entries in each GOT.
850 for (FileGot &Got : Gots) {
851 for (std::pair<const OutputSection *, FileGot::PageBlock> &P :
852 Got.PagesMap) {
853 const OutputSection *OS = P.first;
854 uint64_t SecSize = 0;
855 for (BaseCommand *Cmd : OS->SectionCommands) {
856 if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
857 for (InputSection *IS : ISD->Sections) {
858 uint64_t Off = alignTo(SecSize, IS->Alignment);
859 SecSize = Off + IS->getSize();
834 for (FileGot &got : gots) {
835 for (std::pair<const OutputSection *, FileGot::PageBlock> &p :
836 got.pagesMap) {
837 const OutputSection *os = p.first;
838 uint64_t secSize = 0;
839 for (BaseCommand *cmd : os->sectionCommands) {
840 if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
841 for (InputSection *isec : isd->sections) {
842 uint64_t off = alignTo(secSize, isec->alignment);
843 secSize = off + isec->getSize();
860844 }
861845 }
862 P.second.Count = getMipsPageCount(SecSize);
846 p.second.count = getMipsPageCount(secSize);
863847 }
864848 }
865849
......@@ -868,149 +852,149 @@ template <class ELFT> void MipsGotSection::build() {
868852 // the primary GOT can be accessed in the most effective way. If it
869853 // is not possible, try to fill the last GOT in the list, and finally
870854 // create a new GOT if both attempts failed.
871 for (FileGot &SrcGot : Gots) {
872 InputFile *File = SrcGot.File;
873 if (tryMergeGots(MergedGots.front(), SrcGot, true)) {
874 File->MipsGotIndex = 0;
855 for (FileGot &srcGot : gots) {
856 InputFile *file = srcGot.file;
857 if (tryMergeGots(mergedGots.front(), srcGot, true)) {
858 file->mipsGotIndex = 0;
875859 } else {
876860 // If this is the first time we failed to merge with the primary GOT,
877861 // MergedGots.back() will also be the primary GOT. We must make sure not
878 // to try to merge again with IsPrimary=false, as otherwise, if the
862 // to try to merge again with isPrimary=false, as otherwise, if the
879863 // inputs are just right, we could allow the primary GOT to become 1 or 2
880 // words too big due to ignoring the header size.
881 if (MergedGots.size() == 1 ||
882 !tryMergeGots(MergedGots.back(), SrcGot, false)) {
883 MergedGots.emplace_back();
884 std::swap(MergedGots.back(), SrcGot);
864 // words bigger due to ignoring the header size.
865 if (mergedGots.size() == 1 ||
866 !tryMergeGots(mergedGots.back(), srcGot, false)) {
867 mergedGots.emplace_back();
868 std::swap(mergedGots.back(), srcGot);
885869 }
886 File->MipsGotIndex = MergedGots.size() - 1;
870 file->mipsGotIndex = mergedGots.size() - 1;
887871 }
888872 }
889 std::swap(Gots, MergedGots);
873 std::swap(gots, mergedGots);
890874
891875 // Reduce number of "reloc-only" entries in the primary GOT
892876 // by substracting "global" entries exist in the primary GOT.
893 PrimGot = &Gots.front();
894 PrimGot->Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) {
895 return PrimGot->Global.count(P.first);
877 primGot = &gots.front();
878 primGot->relocs.remove_if([&](const std::pair<Symbol *, size_t> &p) {
879 return primGot->global.count(p.first);
896880 });
897881
898882 // Calculate indexes for each GOT entry.
899 size_t Index = HeaderEntriesNum;
900 for (FileGot &Got : Gots) {
901 Got.StartIndex = &Got == PrimGot ? 0 : Index;
902 for (std::pair<const OutputSection *, FileGot::PageBlock> &P :
903 Got.PagesMap) {
883 size_t index = headerEntriesNum;
884 for (FileGot &got : gots) {
885 got.startIndex = &got == primGot ? 0 : index;
886 for (std::pair<const OutputSection *, FileGot::PageBlock> &p :
887 got.pagesMap) {
904888 // For each output section referenced by GOT page relocations calculate
905 // and save into PagesMap an upper bound of MIPS GOT entries required
889 // and save into pagesMap an upper bound of MIPS GOT entries required
906890 // to store page addresses of local symbols. We assume the worst case -
907891 // each 64kb page of the output section has at least one GOT relocation
908892 // against it. And take in account the case when the section intersects
909893 // page boundaries.
910 P.second.FirstIndex = Index;
911 Index += P.second.Count;
894 p.second.firstIndex = index;
895 index += p.second.count;
912896 }
913 for (auto &P: Got.Local16)
914 P.second = Index++;
915 for (auto &P: Got.Global)
916 P.second = Index++;
917 for (auto &P: Got.Relocs)
918 P.second = Index++;
919 for (auto &P: Got.Tls)
920 P.second = Index++;
921 for (auto &P: Got.DynTlsSymbols) {
922 P.second = Index;
923 Index += 2;
897 for (auto &p: got.local16)
898 p.second = index++;
899 for (auto &p: got.global)
900 p.second = index++;
901 for (auto &p: got.relocs)
902 p.second = index++;
903 for (auto &p: got.tls)
904 p.second = index++;
905 for (auto &p: got.dynTlsSymbols) {
906 p.second = index;
907 index += 2;
924908 }
925909 }
926910
927 // Update Symbol::GotIndex field to use this
911 // Update Symbol::gotIndex field to use this
928912 // value later in the `sortMipsSymbols` function.
929 for (auto &P : PrimGot->Global)
930 P.first->GotIndex = P.second;
931 for (auto &P : PrimGot->Relocs)
932 P.first->GotIndex = P.second;
913 for (auto &p : primGot->global)
914 p.first->gotIndex = p.second;
915 for (auto &p : primGot->relocs)
916 p.first->gotIndex = p.second;
933917
934918 // Create dynamic relocations.
935 for (FileGot &Got : Gots) {
919 for (FileGot &got : gots) {
936920 // Create dynamic relocations for TLS entries.
937 for (std::pair<Symbol *, size_t> &P : Got.Tls) {
938 Symbol *S = P.first;
939 uint64_t Offset = P.second * Config->Wordsize;
940 if (S->IsPreemptible)
941 In.RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
921 for (std::pair<Symbol *, size_t> &p : got.tls) {
922 Symbol *s = p.first;
923 uint64_t offset = p.second * config->wordsize;
924 if (s->isPreemptible)
925 mainPart->relaDyn->addReloc(target->tlsGotRel, this, offset, s);
942926 }
943 for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) {
944 Symbol *S = P.first;
945 uint64_t Offset = P.second * Config->Wordsize;
946 if (S == nullptr) {
947 if (!Config->Pic)
927 for (std::pair<Symbol *, size_t> &p : got.dynTlsSymbols) {
928 Symbol *s = p.first;
929 uint64_t offset = p.second * config->wordsize;
930 if (s == nullptr) {
931 if (!config->isPic)
948932 continue;
949 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
933 mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, this, offset, s);
950934 } else {
951935 // When building a shared library we still need a dynamic relocation
952936 // for the module index. Therefore only checking for
953 // S->IsPreemptible is not sufficient (this happens e.g. for
937 // S->isPreemptible is not sufficient (this happens e.g. for
954938 // thread-locals that have been marked as local through a linker script)
955 if (!S->IsPreemptible && !Config->Pic)
939 if (!s->isPreemptible && !config->isPic)
956940 continue;
957 In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
941 mainPart->relaDyn->addReloc(target->tlsModuleIndexRel, this, offset, s);
958942 // However, we can skip writing the TLS offset reloc for non-preemptible
959943 // symbols since it is known even in shared libraries
960 if (!S->IsPreemptible)
944 if (!s->isPreemptible)
961945 continue;
962 Offset += Config->Wordsize;
963 In.RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
946 offset += config->wordsize;
947 mainPart->relaDyn->addReloc(target->tlsOffsetRel, this, offset, s);
964948 }
965949 }
966950
967951 // Do not create dynamic relocations for non-TLS
968952 // entries in the primary GOT.
969 if (&Got == PrimGot)
953 if (&got == primGot)
970954 continue;
971955
972956 // Dynamic relocations for "global" entries.
973 for (const std::pair<Symbol *, size_t> &P : Got.Global) {
974 uint64_t Offset = P.second * Config->Wordsize;
975 In.RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first);
957 for (const std::pair<Symbol *, size_t> &p : got.global) {
958 uint64_t offset = p.second * config->wordsize;
959 mainPart->relaDyn->addReloc(target->relativeRel, this, offset, p.first);
976960 }
977 if (!Config->Pic)
961 if (!config->isPic)
978962 continue;
979963 // Dynamic relocations for "local" entries in case of PIC.
980 for (const std::pair<const OutputSection *, FileGot::PageBlock> &L :
981 Got.PagesMap) {
982 size_t PageCount = L.second.Count;
983 for (size_t PI = 0; PI < PageCount; ++PI) {
984 uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize;
985 In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
986 int64_t(PI * 0x10000)});
964 for (const std::pair<const OutputSection *, FileGot::PageBlock> &l :
965 got.pagesMap) {
966 size_t pageCount = l.second.count;
967 for (size_t pi = 0; pi < pageCount; ++pi) {
968 uint64_t offset = (l.second.firstIndex + pi) * config->wordsize;
969 mainPart->relaDyn->addReloc({target->relativeRel, this, offset, l.first,
970 int64_t(pi * 0x10000)});
987971 }
988972 }
989 for (const std::pair<GotEntry, size_t> &P : Got.Local16) {
990 uint64_t Offset = P.second * Config->Wordsize;
991 In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
992 P.first.first, P.first.second});
973 for (const std::pair<GotEntry, size_t> &p : got.local16) {
974 uint64_t offset = p.second * config->wordsize;
975 mainPart->relaDyn->addReloc({target->relativeRel, this, offset, true,
976 p.first.first, p.first.second});
993977 }
994978 }
995979}
996980
997bool MipsGotSection::empty() const {
981bool MipsGotSection::isNeeded() const {
998982 // We add the .got section to the result for dynamic MIPS target because
999983 // its address and properties are mentioned in the .dynamic section.
1000 return Config->Relocatable;
984 return !config->relocatable;
1001985}
1002986
1003uint64_t MipsGotSection::getGp(const InputFile *F) const {
987uint64_t MipsGotSection::getGp(const InputFile *f) const {
1004988 // For files without related GOT or files refer a primary GOT
1005989 // returns "common" _gp value. For secondary GOTs calculate
1006990 // individual _gp values.
1007 if (!F || !F->MipsGotIndex.hasValue() || *F->MipsGotIndex == 0)
1008 return ElfSym::MipsGp->getVA(0);
1009 return getVA() + Gots[*F->MipsGotIndex].StartIndex * Config->Wordsize +
991 if (!f || !f->mipsGotIndex.hasValue() || *f->mipsGotIndex == 0)
992 return ElfSym::mipsGp->getVA(0);
993 return getVA() + gots[*f->mipsGotIndex].startIndex * config->wordsize +
1010994 0x7ff0;
1011995}
1012996
1013void MipsGotSection::writeTo(uint8_t *Buf) {
997void MipsGotSection::writeTo(uint8_t *buf) {
1014998 // Set the MSB of the second GOT slot. This is not required by any
1015999 // MIPS ABI documentation, though.
10161000 //
......@@ -1025,51 +1009,48 @@ void MipsGotSection::writeTo(uint8_t *Buf) {
10251009 // we've been doing this for years, it is probably a safe bet to
10261010 // keep doing this for now. We really need to revisit this to see
10271011 // if we had to do this.
1028 writeUint(Buf + Config->Wordsize, (uint64_t)1 << (Config->Wordsize * 8 - 1));
1029 for (const FileGot &G : Gots) {
1030 auto Write = [&](size_t I, const Symbol *S, int64_t A) {
1031 uint64_t VA = A;
1032 if (S) {
1033 VA = S->getVA(A);
1034 if (S->StOther & STO_MIPS_MICROMIPS)
1035 VA |= 1;
1036 }
1037 writeUint(Buf + I * Config->Wordsize, VA);
1012 writeUint(buf + config->wordsize, (uint64_t)1 << (config->wordsize * 8 - 1));
1013 for (const FileGot &g : gots) {
1014 auto write = [&](size_t i, const Symbol *s, int64_t a) {
1015 uint64_t va = a;
1016 if (s)
1017 va = s->getVA(a);
1018 writeUint(buf + i * config->wordsize, va);
10381019 };
10391020 // Write 'page address' entries to the local part of the GOT.
1040 for (const std::pair<const OutputSection *, FileGot::PageBlock> &L :
1041 G.PagesMap) {
1042 size_t PageCount = L.second.Count;
1043 uint64_t FirstPageAddr = getMipsPageAddr(L.first->Addr);
1044 for (size_t PI = 0; PI < PageCount; ++PI)
1045 Write(L.second.FirstIndex + PI, nullptr, FirstPageAddr + PI * 0x10000);
1021 for (const std::pair<const OutputSection *, FileGot::PageBlock> &l :
1022 g.pagesMap) {
1023 size_t pageCount = l.second.count;
1024 uint64_t firstPageAddr = getMipsPageAddr(l.first->addr);
1025 for (size_t pi = 0; pi < pageCount; ++pi)
1026 write(l.second.firstIndex + pi, nullptr, firstPageAddr + pi * 0x10000);
10461027 }
10471028 // Local, global, TLS, reloc-only entries.
10481029 // If TLS entry has a corresponding dynamic relocations, leave it
10491030 // initialized by zero. Write down adjusted TLS symbol's values otherwise.
10501031 // To calculate the adjustments use offsets for thread-local storage.
10511032 // https://www.linux-mips.org/wiki/NPTL
1052 for (const std::pair<GotEntry, size_t> &P : G.Local16)
1053 Write(P.second, P.first.first, P.first.second);
1033 for (const std::pair<GotEntry, size_t> &p : g.local16)
1034 write(p.second, p.first.first, p.first.second);
10541035 // Write VA to the primary GOT only. For secondary GOTs that
10551036 // will be done by REL32 dynamic relocations.
1056 if (&G == &Gots.front())
1057 for (const std::pair<const Symbol *, size_t> &P : G.Global)
1058 Write(P.second, P.first, 0);
1059 for (const std::pair<Symbol *, size_t> &P : G.Relocs)
1060 Write(P.second, P.first, 0);
1061 for (const std::pair<Symbol *, size_t> &P : G.Tls)
1062 Write(P.second, P.first, P.first->IsPreemptible ? 0 : -0x7000);
1063 for (const std::pair<Symbol *, size_t> &P : G.DynTlsSymbols) {
1064 if (P.first == nullptr && !Config->Pic)
1065 Write(P.second, nullptr, 1);
1066 else if (P.first && !P.first->IsPreemptible) {
1037 if (&g == &gots.front())
1038 for (const std::pair<const Symbol *, size_t> &p : g.global)
1039 write(p.second, p.first, 0);
1040 for (const std::pair<Symbol *, size_t> &p : g.relocs)
1041 write(p.second, p.first, 0);
1042 for (const std::pair<Symbol *, size_t> &p : g.tls)
1043 write(p.second, p.first, p.first->isPreemptible ? 0 : -0x7000);
1044 for (const std::pair<Symbol *, size_t> &p : g.dynTlsSymbols) {
1045 if (p.first == nullptr && !config->isPic)
1046 write(p.second, nullptr, 1);
1047 else if (p.first && !p.first->isPreemptible) {
10671048 // If we are emitting PIC code with relocations we mustn't write
10681049 // anything to the GOT here. When using Elf_Rel relocations the value
10691050 // one will be treated as an addend and will cause crashes at runtime
1070 if (!Config->Pic)
1071 Write(P.second, nullptr, 1);
1072 Write(P.second + 1, P.first, -0x8000);
1051 if (!config->isPic)
1052 write(p.second, nullptr, 1);
1053 write(p.second + 1, p.first, -0x8000);
10731054 }
10741055 }
10751056 }
......@@ -1080,46 +1061,48 @@ void MipsGotSection::writeTo(uint8_t *Buf) {
10801061// section. I don't know why we have a BSS style type for the section but it is
10811062// consitent across both 64-bit PowerPC ABIs as well as the 32-bit PowerPC ABI.
10821063GotPltSection::GotPltSection()
1083 : SyntheticSection(SHF_ALLOC | SHF_WRITE,
1084 Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
1085 Target->GotPltEntrySize,
1086 Config->EMachine == EM_PPC64 ? ".plt" : ".got.plt") {}
1064 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
1065 ".got.plt") {
1066 if (config->emachine == EM_PPC) {
1067 name = ".plt";
1068 } else if (config->emachine == EM_PPC64) {
1069 type = SHT_NOBITS;
1070 name = ".plt";
1071 }
1072}
10871073
1088void GotPltSection::addEntry(Symbol &Sym) {
1089 assert(Sym.PltIndex == Entries.size());
1090 Entries.push_back(&Sym);
1074void GotPltSection::addEntry(Symbol &sym) {
1075 assert(sym.pltIndex == entries.size());
1076 entries.push_back(&sym);
10911077}
10921078
10931079size_t GotPltSection::getSize() const {
1094 return (Target->GotPltHeaderEntriesNum + Entries.size()) *
1095 Target->GotPltEntrySize;
1080 return (target->gotPltHeaderEntriesNum + entries.size()) * config->wordsize;
10961081}
10971082
1098void GotPltSection::writeTo(uint8_t *Buf) {
1099 Target->writeGotPltHeader(Buf);
1100 Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize;
1101 for (const Symbol *B : Entries) {
1102 Target->writeGotPlt(Buf, *B);
1103 Buf += Config->Wordsize;
1083void GotPltSection::writeTo(uint8_t *buf) {
1084 target->writeGotPltHeader(buf);
1085 buf += target->gotPltHeaderEntriesNum * config->wordsize;
1086 for (const Symbol *b : entries) {
1087 target->writeGotPlt(buf, *b);
1088 buf += config->wordsize;
11041089 }
11051090}
11061091
1107bool GotPltSection::empty() const {
1108 // We need to emit a GOT.PLT even if it's empty if there's a symbol that
1109 // references the _GLOBAL_OFFSET_TABLE_ and the Target defines the symbol
1110 // relative to the .got.plt section.
1111 return Entries.empty() &&
1112 !(ElfSym::GlobalOffsetTable && Target->GotBaseSymInGotPlt);
1092bool GotPltSection::isNeeded() const {
1093 // We need to emit GOTPLT even if it's empty if there's a relocation relative
1094 // to it.
1095 return !entries.empty() || hasGotPltOffRel;
11131096}
11141097
11151098static StringRef getIgotPltName() {
11161099 // On ARM the IgotPltSection is part of the GotSection.
1117 if (Config->EMachine == EM_ARM)
1100 if (config->emachine == EM_ARM)
11181101 return ".got";
11191102
11201103 // On PowerPC64 the GotPltSection is renamed to '.plt' so the IgotPltSection
11211104 // needs to be named the same.
1122 if (Config->EMachine == EM_PPC64)
1105 if (config->emachine == EM_PPC64)
11231106 return ".plt";
11241107
11251108 return ".got.plt";
......@@ -1129,130 +1112,110 @@ static StringRef getIgotPltName() {
11291112// with the IgotPltSection.
11301113IgotPltSection::IgotPltSection()
11311114 : SyntheticSection(SHF_ALLOC | SHF_WRITE,
1132 Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
1133 Target->GotPltEntrySize, getIgotPltName()) {}
1115 config->emachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
1116 config->wordsize, getIgotPltName()) {}
11341117
1135void IgotPltSection::addEntry(Symbol &Sym) {
1136 Sym.IsInIgot = true;
1137 assert(Sym.PltIndex == Entries.size());
1138 Entries.push_back(&Sym);
1118void IgotPltSection::addEntry(Symbol &sym) {
1119 assert(sym.pltIndex == entries.size());
1120 entries.push_back(&sym);
11391121}
11401122
11411123size_t IgotPltSection::getSize() const {
1142 return Entries.size() * Target->GotPltEntrySize;
1124 return entries.size() * config->wordsize;
11431125}
11441126
1145void IgotPltSection::writeTo(uint8_t *Buf) {
1146 for (const Symbol *B : Entries) {
1147 Target->writeIgotPlt(Buf, *B);
1148 Buf += Config->Wordsize;
1127void IgotPltSection::writeTo(uint8_t *buf) {
1128 for (const Symbol *b : entries) {
1129 target->writeIgotPlt(buf, *b);
1130 buf += config->wordsize;
11491131 }
11501132}
11511133
1152StringTableSection::StringTableSection(StringRef Name, bool Dynamic)
1153 : SyntheticSection(Dynamic ? (uint64_t)SHF_ALLOC : 0, SHT_STRTAB, 1, Name),
1154 Dynamic(Dynamic) {
1134StringTableSection::StringTableSection(StringRef name, bool dynamic)
1135 : SyntheticSection(dynamic ? (uint64_t)SHF_ALLOC : 0, SHT_STRTAB, 1, name),
1136 dynamic(dynamic) {
11551137 // ELF string tables start with a NUL byte.
11561138 addString("");
11571139}
11581140
1159// Adds a string to the string table. If HashIt is true we hash and check for
1141// Adds a string to the string table. If `hashIt` is true we hash and check for
11601142// duplicates. It is optional because the name of global symbols are already
11611143// uniqued and hashing them again has a big cost for a small value: uniquing
11621144// them with some other string that happens to be the same.
1163unsigned StringTableSection::addString(StringRef S, bool HashIt) {
1164 if (HashIt) {
1165 auto R = StringMap.insert(std::make_pair(S, this->Size));
1166 if (!R.second)
1167 return R.first->second;
1145unsigned StringTableSection::addString(StringRef s, bool hashIt) {
1146 if (hashIt) {
1147 auto r = stringMap.insert(std::make_pair(s, this->size));
1148 if (!r.second)
1149 return r.first->second;
11681150 }
1169 unsigned Ret = this->Size;
1170 this->Size = this->Size + S.size() + 1;
1171 Strings.push_back(S);
1172 return Ret;
1151 unsigned ret = this->size;
1152 this->size = this->size + s.size() + 1;
1153 strings.push_back(s);
1154 return ret;
11731155}
11741156
1175void StringTableSection::writeTo(uint8_t *Buf) {
1176 for (StringRef S : Strings) {
1177 memcpy(Buf, S.data(), S.size());
1178 Buf[S.size()] = '\0';
1179 Buf += S.size() + 1;
1157void StringTableSection::writeTo(uint8_t *buf) {
1158 for (StringRef s : strings) {
1159 memcpy(buf, s.data(), s.size());
1160 buf[s.size()] = '\0';
1161 buf += s.size() + 1;
11801162 }
11811163}
11821164
11831165// Returns the number of version definition entries. Because the first entry
11841166// is for the version definition itself, it is the number of versioned symbols
11851167// plus one. Note that we don't support multiple versions yet.
1186static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
1168static unsigned getVerDefNum() { return config->versionDefinitions.size() + 1; }
11871169
11881170template <class ELFT>
11891171DynamicSection<ELFT>::DynamicSection()
1190 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, Config->Wordsize,
1172 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, config->wordsize,
11911173 ".dynamic") {
1192 this->Entsize = ELFT::Is64Bits ? 16 : 8;
1174 this->entsize = ELFT::Is64Bits ? 16 : 8;
11931175
11941176 // .dynamic section is not writable on MIPS and on Fuchsia OS
11951177 // which passes -z rodynamic.
11961178 // See "Special Section" in Chapter 4 in the following document:
11971179 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1198 if (Config->EMachine == EM_MIPS || Config->ZRodynamic)
1199 this->Flags = SHF_ALLOC;
1200
1201 // Add strings to .dynstr early so that .dynstr's size will be
1202 // fixed early.
1203 for (StringRef S : Config->FilterList)
1204 addInt(DT_FILTER, In.DynStrTab->addString(S));
1205 for (StringRef S : Config->AuxiliaryList)
1206 addInt(DT_AUXILIARY, In.DynStrTab->addString(S));
1207
1208 if (!Config->Rpath.empty())
1209 addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
1210 In.DynStrTab->addString(Config->Rpath));
1211
1212 for (InputFile *File : SharedFiles) {
1213 SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
1214 if (F->IsNeeded)
1215 addInt(DT_NEEDED, In.DynStrTab->addString(F->SoName));
1216 }
1217 if (!Config->SoName.empty())
1218 addInt(DT_SONAME, In.DynStrTab->addString(Config->SoName));
1180 if (config->emachine == EM_MIPS || config->zRodynamic)
1181 this->flags = SHF_ALLOC;
12191182}
12201183
12211184template <class ELFT>
1222void DynamicSection<ELFT>::add(int32_t Tag, std::function<uint64_t()> Fn) {
1223 Entries.push_back({Tag, Fn});
1185void DynamicSection<ELFT>::add(int32_t tag, std::function<uint64_t()> fn) {
1186 entries.push_back({tag, fn});
12241187}
12251188
12261189template <class ELFT>
1227void DynamicSection<ELFT>::addInt(int32_t Tag, uint64_t Val) {
1228 Entries.push_back({Tag, [=] { return Val; }});
1190void DynamicSection<ELFT>::addInt(int32_t tag, uint64_t val) {
1191 entries.push_back({tag, [=] { return val; }});
12291192}
12301193
12311194template <class ELFT>
1232void DynamicSection<ELFT>::addInSec(int32_t Tag, InputSection *Sec) {
1233 Entries.push_back({Tag, [=] { return Sec->getVA(0); }});
1195void DynamicSection<ELFT>::addInSec(int32_t tag, InputSection *sec) {
1196 entries.push_back({tag, [=] { return sec->getVA(0); }});
12341197}
12351198
12361199template <class ELFT>
1237void DynamicSection<ELFT>::addInSecRelative(int32_t Tag, InputSection *Sec) {
1238 size_t TagOffset = Entries.size() * Entsize;
1239 Entries.push_back(
1240 {Tag, [=] { return Sec->getVA(0) - (getVA() + TagOffset); }});
1200void DynamicSection<ELFT>::addInSecRelative(int32_t tag, InputSection *sec) {
1201 size_t tagOffset = entries.size() * entsize;
1202 entries.push_back(
1203 {tag, [=] { return sec->getVA(0) - (getVA() + tagOffset); }});
12411204}
12421205
12431206template <class ELFT>
1244void DynamicSection<ELFT>::addOutSec(int32_t Tag, OutputSection *Sec) {
1245 Entries.push_back({Tag, [=] { return Sec->Addr; }});
1207void DynamicSection<ELFT>::addOutSec(int32_t tag, OutputSection *sec) {
1208 entries.push_back({tag, [=] { return sec->addr; }});
12461209}
12471210
12481211template <class ELFT>
1249void DynamicSection<ELFT>::addSize(int32_t Tag, OutputSection *Sec) {
1250 Entries.push_back({Tag, [=] { return Sec->Size; }});
1212void DynamicSection<ELFT>::addSize(int32_t tag, OutputSection *sec) {
1213 entries.push_back({tag, [=] { return sec->size; }});
12511214}
12521215
12531216template <class ELFT>
1254void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {
1255 Entries.push_back({Tag, [=] { return Sym->getVA(); }});
1217void DynamicSection<ELFT>::addSym(int32_t tag, Symbol *sym) {
1218 entries.push_back({tag, [=] { return sym->getVA(); }});
12561219}
12571220
12581221// A Linker script may assign the RELA relocation sections to the same
......@@ -1260,47 +1223,74 @@ void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {
12601223// Size. Moreover the [DT_JMPREL, DT_JMPREL + DT_PLTRELSZ) is permitted to
12611224// overlap with the [DT_RELA, DT_RELA + DT_RELASZ).
12621225static 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;
1226 size_t size = in.relaPlt->getSize();
1227 if (in.relaIplt->getParent() == in.relaPlt->getParent() &&
1228 in.relaIplt->name == in.relaPlt->name)
1229 size += in.relaIplt->getSize();
1230 return size;
12681231}
12691232
12701233// Add remaining entries to complete .dynamic contents.
12711234template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
1235 elf::Partition &part = getPartition();
1236 bool isMain = part.name.empty();
1237
1238 for (StringRef s : config->filterList)
1239 addInt(DT_FILTER, part.dynStrTab->addString(s));
1240 for (StringRef s : config->auxiliaryList)
1241 addInt(DT_AUXILIARY, part.dynStrTab->addString(s));
1242
1243 if (!config->rpath.empty())
1244 addInt(config->enableNewDtags ? DT_RUNPATH : DT_RPATH,
1245 part.dynStrTab->addString(config->rpath));
1246
1247 for (SharedFile *file : sharedFiles)
1248 if (file->isNeeded)
1249 addInt(DT_NEEDED, part.dynStrTab->addString(file->soName));
1250
1251 if (isMain) {
1252 if (!config->soName.empty())
1253 addInt(DT_SONAME, part.dynStrTab->addString(config->soName));
1254 } else {
1255 if (!config->soName.empty())
1256 addInt(DT_NEEDED, part.dynStrTab->addString(config->soName));
1257 addInt(DT_SONAME, part.dynStrTab->addString(part.name));
1258 }
1259
12721260 // Set DT_FLAGS and DT_FLAGS_1.
1273 uint32_t DtFlags = 0;
1274 uint32_t DtFlags1 = 0;
1275 if (Config->Bsymbolic)
1276 DtFlags |= DF_SYMBOLIC;
1277 if (Config->ZGlobal)
1278 DtFlags1 |= DF_1_GLOBAL;
1279 if (Config->ZInitfirst)
1280 DtFlags1 |= DF_1_INITFIRST;
1281 if (Config->ZInterpose)
1282 DtFlags1 |= DF_1_INTERPOSE;
1283 if (Config->ZNodefaultlib)
1284 DtFlags1 |= DF_1_NODEFLIB;
1285 if (Config->ZNodelete)
1286 DtFlags1 |= DF_1_NODELETE;
1287 if (Config->ZNodlopen)
1288 DtFlags1 |= DF_1_NOOPEN;
1289 if (Config->ZNow) {
1290 DtFlags |= DF_BIND_NOW;
1291 DtFlags1 |= DF_1_NOW;
1292 }
1293 if (Config->ZOrigin) {
1294 DtFlags |= DF_ORIGIN;
1295 DtFlags1 |= DF_1_ORIGIN;
1296 }
1297 if (!Config->ZText)
1298 DtFlags |= DF_TEXTREL;
1299
1300 if (DtFlags)
1301 addInt(DT_FLAGS, DtFlags);
1302 if (DtFlags1)
1303 addInt(DT_FLAGS_1, DtFlags1);
1261 uint32_t dtFlags = 0;
1262 uint32_t dtFlags1 = 0;
1263 if (config->bsymbolic)
1264 dtFlags |= DF_SYMBOLIC;
1265 if (config->zGlobal)
1266 dtFlags1 |= DF_1_GLOBAL;
1267 if (config->zInitfirst)
1268 dtFlags1 |= DF_1_INITFIRST;
1269 if (config->zInterpose)
1270 dtFlags1 |= DF_1_INTERPOSE;
1271 if (config->zNodefaultlib)
1272 dtFlags1 |= DF_1_NODEFLIB;
1273 if (config->zNodelete)
1274 dtFlags1 |= DF_1_NODELETE;
1275 if (config->zNodlopen)
1276 dtFlags1 |= DF_1_NOOPEN;
1277 if (config->zNow) {
1278 dtFlags |= DF_BIND_NOW;
1279 dtFlags1 |= DF_1_NOW;
1280 }
1281 if (config->zOrigin) {
1282 dtFlags |= DF_ORIGIN;
1283 dtFlags1 |= DF_1_ORIGIN;
1284 }
1285 if (!config->zText)
1286 dtFlags |= DF_TEXTREL;
1287 if (config->hasStaticTlsModel)
1288 dtFlags |= DF_STATIC_TLS;
1289
1290 if (dtFlags)
1291 addInt(DT_FLAGS, dtFlags);
1292 if (dtFlags1)
1293 addInt(DT_FLAGS_1, dtFlags1);
13041294
13051295 // DT_DEBUG is a pointer to debug informaion used by debuggers at runtime. We
13061296 // need it for each process, so we don't write it for DSOs. The loader writes
......@@ -1310,268 +1300,287 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
13101300 // systems (currently only Fuchsia OS) provide other means to give the
13111301 // debugger this information. Such systems may choose make .dynamic read-only.
13121302 // If the target is such a system (used -z rodynamic) don't write DT_DEBUG.
1313 if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)
1303 if (!config->shared && !config->relocatable && !config->zRodynamic)
13141304 addInt(DT_DEBUG, 0);
13151305
1316 if (OutputSection *Sec = In.DynStrTab->getParent())
1317 this->Link = Sec->SectionIndex;
1306 if (OutputSection *sec = part.dynStrTab->getParent())
1307 this->link = sec->sectionIndex;
13181308
1319 if (!In.RelaDyn->empty()) {
1320 addInSec(In.RelaDyn->DynamicTag, In.RelaDyn);
1321 addSize(In.RelaDyn->SizeDynamicTag, In.RelaDyn->getParent());
1309 if (part.relaDyn->isNeeded()) {
1310 addInSec(part.relaDyn->dynamicTag, part.relaDyn);
1311 addSize(part.relaDyn->sizeDynamicTag, part.relaDyn->getParent());
13221312
1323 bool IsRela = Config->IsRela;
1324 addInt(IsRela ? DT_RELAENT : DT_RELENT,
1325 IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
1313 bool isRela = config->isRela;
1314 addInt(isRela ? DT_RELAENT : DT_RELENT,
1315 isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
13261316
13271317 // MIPS dynamic loader does not support RELCOUNT tag.
13281318 // The problem is in the tight relation between dynamic
13291319 // relocations and GOT. So do not emit this tag on MIPS.
1330 if (Config->EMachine != EM_MIPS) {
1331 size_t NumRelativeRels = In.RelaDyn->getRelativeRelocCount();
1332 if (Config->ZCombreloc && NumRelativeRels)
1333 addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);
1320 if (config->emachine != EM_MIPS) {
1321 size_t numRelativeRels = part.relaDyn->getRelativeRelocCount();
1322 if (config->zCombreloc && numRelativeRels)
1323 addInt(isRela ? DT_RELACOUNT : DT_RELCOUNT, numRelativeRels);
13341324 }
13351325 }
1336 if (In.RelrDyn && !In.RelrDyn->Relocs.empty()) {
1337 addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
1338 In.RelrDyn);
1339 addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
1340 In.RelrDyn->getParent());
1341 addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
1326 if (part.relrDyn && !part.relrDyn->relocs.empty()) {
1327 addInSec(config->useAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
1328 part.relrDyn);
1329 addSize(config->useAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
1330 part.relrDyn->getParent());
1331 addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
13421332 sizeof(Elf_Relr));
13431333 }
13441334 // .rel[a].plt section usually consists of two parts, containing plt and
13451335 // iplt relocations. It is possible to have only iplt relocations in the
1346 // output. In that case RelaPlt is empty and have zero offset, the same offset
1347 // as RelaIplt have. And we still want to emit proper dynamic tags for that
1348 // case, so here we always use RelaPlt as marker for the begining of
1336 // output. In that case relaPlt is empty and have zero offset, the same offset
1337 // as relaIplt has. And we still want to emit proper dynamic tags for that
1338 // case, so here we always use relaPlt as marker for the begining of
13491339 // .rel[a].plt section.
1350 if (In.RelaPlt->getParent()->Live) {
1351 addInSec(DT_JMPREL, In.RelaPlt);
1352 Entries.push_back({DT_PLTRELSZ, addPltRelSz});
1353 switch (Config->EMachine) {
1340 if (isMain && (in.relaPlt->isNeeded() || in.relaIplt->isNeeded())) {
1341 addInSec(DT_JMPREL, in.relaPlt);
1342 entries.push_back({DT_PLTRELSZ, addPltRelSz});
1343 switch (config->emachine) {
13541344 case EM_MIPS:
1355 addInSec(DT_MIPS_PLTGOT, In.GotPlt);
1345 addInSec(DT_MIPS_PLTGOT, in.gotPlt);
13561346 break;
13571347 case EM_SPARCV9:
1358 addInSec(DT_PLTGOT, In.Plt);
1348 addInSec(DT_PLTGOT, in.plt);
13591349 break;
13601350 default:
1361 addInSec(DT_PLTGOT, In.GotPlt);
1351 addInSec(DT_PLTGOT, in.gotPlt);
13621352 break;
13631353 }
1364 addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL);
1354 addInt(DT_PLTREL, config->isRela ? DT_RELA : DT_REL);
1355 }
1356
1357 if (config->emachine == EM_AARCH64) {
1358 if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
1359 addInt(DT_AARCH64_BTI_PLT, 0);
1360 if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)
1361 addInt(DT_AARCH64_PAC_PLT, 0);
13651362 }
13661363
1367 addInSec(DT_SYMTAB, In.DynSymTab);
1364 addInSec(DT_SYMTAB, part.dynSymTab);
13681365 addInt(DT_SYMENT, sizeof(Elf_Sym));
1369 addInSec(DT_STRTAB, In.DynStrTab);
1370 addInt(DT_STRSZ, In.DynStrTab->getSize());
1371 if (!Config->ZText)
1366 addInSec(DT_STRTAB, part.dynStrTab);
1367 addInt(DT_STRSZ, part.dynStrTab->getSize());
1368 if (!config->zText)
13721369 addInt(DT_TEXTREL, 0);
1373 if (In.GnuHashTab)
1374 addInSec(DT_GNU_HASH, In.GnuHashTab);
1375 if (In.HashTab)
1376 addInSec(DT_HASH, In.HashTab);
1377
1378 if (Out::PreinitArray) {
1379 addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray);
1380 addSize(DT_PREINIT_ARRAYSZ, Out::PreinitArray);
1381 }
1382 if (Out::InitArray) {
1383 addOutSec(DT_INIT_ARRAY, Out::InitArray);
1384 addSize(DT_INIT_ARRAYSZ, Out::InitArray);
1385 }
1386 if (Out::FiniArray) {
1387 addOutSec(DT_FINI_ARRAY, Out::FiniArray);
1388 addSize(DT_FINI_ARRAYSZ, Out::FiniArray);
1389 }
1390
1391 if (Symbol *B = Symtab->find(Config->Init))
1392 if (B->isDefined())
1393 addSym(DT_INIT, B);
1394 if (Symbol *B = Symtab->find(Config->Fini))
1395 if (B->isDefined())
1396 addSym(DT_FINI, B);
1397
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);
1370 if (part.gnuHashTab)
1371 addInSec(DT_GNU_HASH, part.gnuHashTab);
1372 if (part.hashTab)
1373 addInSec(DT_HASH, part.hashTab);
1374
1375 if (isMain) {
1376 if (Out::preinitArray) {
1377 addOutSec(DT_PREINIT_ARRAY, Out::preinitArray);
1378 addSize(DT_PREINIT_ARRAYSZ, Out::preinitArray);
1379 }
1380 if (Out::initArray) {
1381 addOutSec(DT_INIT_ARRAY, Out::initArray);
1382 addSize(DT_INIT_ARRAYSZ, Out::initArray);
1383 }
1384 if (Out::finiArray) {
1385 addOutSec(DT_FINI_ARRAY, Out::finiArray);
1386 addSize(DT_FINI_ARRAYSZ, Out::finiArray);
1387 }
1388
1389 if (Symbol *b = symtab->find(config->init))
1390 if (b->isDefined())
1391 addSym(DT_INIT, b);
1392 if (Symbol *b = symtab->find(config->fini))
1393 if (b->isDefined())
1394 addSym(DT_FINI, b);
1395 }
1396
1397 bool hasVerNeed = SharedFile::vernauxNum != 0;
1398 if (hasVerNeed || part.verDef)
1399 addInSec(DT_VERSYM, part.verSym);
1400 if (part.verDef) {
1401 addInSec(DT_VERDEF, part.verDef);
14031402 addInt(DT_VERDEFNUM, getVerDefNum());
14041403 }
1405 if (HasVerNeed) {
1406 addInSec(DT_VERNEED, InX<ELFT>::VerNeed);
1407 addInt(DT_VERNEEDNUM, InX<ELFT>::VerNeed->getNeedNum());
1404 if (hasVerNeed) {
1405 addInSec(DT_VERNEED, part.verNeed);
1406 unsigned needNum = 0;
1407 for (SharedFile *f : sharedFiles)
1408 if (!f->vernauxs.empty())
1409 ++needNum;
1410 addInt(DT_VERNEEDNUM, needNum);
14081411 }
14091412
1410 if (Config->EMachine == EM_MIPS) {
1413 if (config->emachine == EM_MIPS) {
14111414 addInt(DT_MIPS_RLD_VERSION, 1);
14121415 addInt(DT_MIPS_FLAGS, RHF_NOTPOT);
1413 addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase());
1414 addInt(DT_MIPS_SYMTABNO, In.DynSymTab->getNumSymbols());
1416 addInt(DT_MIPS_BASE_ADDRESS, target->getImageBase());
1417 addInt(DT_MIPS_SYMTABNO, part.dynSymTab->getNumSymbols());
14151418
1416 add(DT_MIPS_LOCAL_GOTNO, [] { return In.MipsGot->getLocalEntriesNum(); });
1419 add(DT_MIPS_LOCAL_GOTNO, [] { return in.mipsGot->getLocalEntriesNum(); });
14171420
1418 if (const Symbol *B = In.MipsGot->getFirstGlobalEntry())
1419 addInt(DT_MIPS_GOTSYM, B->DynsymIndex);
1421 if (const Symbol *b = in.mipsGot->getFirstGlobalEntry())
1422 addInt(DT_MIPS_GOTSYM, b->dynsymIndex);
14201423 else
1421 addInt(DT_MIPS_GOTSYM, In.DynSymTab->getNumSymbols());
1422 addInSec(DT_PLTGOT, In.MipsGot);
1423 if (In.MipsRldMap) {
1424 if (!Config->Pie)
1425 addInSec(DT_MIPS_RLD_MAP, In.MipsRldMap);
1424 addInt(DT_MIPS_GOTSYM, part.dynSymTab->getNumSymbols());
1425 addInSec(DT_PLTGOT, in.mipsGot);
1426 if (in.mipsRldMap) {
1427 if (!config->pie)
1428 addInSec(DT_MIPS_RLD_MAP, in.mipsRldMap);
14261429 // Store the offset to the .rld_map section
14271430 // relative to the address of the tag.
1428 addInSecRelative(DT_MIPS_RLD_MAP_REL, In.MipsRldMap);
1431 addInSecRelative(DT_MIPS_RLD_MAP_REL, in.mipsRldMap);
14291432 }
14301433 }
14311434
1435 // DT_PPC_GOT indicates to glibc Secure PLT is used. If DT_PPC_GOT is absent,
1436 // glibc assumes the old-style BSS PLT layout which we don't support.
1437 if (config->emachine == EM_PPC)
1438 add(DT_PPC_GOT, [] { return in.got->getVA(); });
1439
14321440 // Glink dynamic tag is required by the V2 abi if the plt section isn't empty.
1433 if (Config->EMachine == EM_PPC64 && !In.Plt->empty()) {
1441 if (config->emachine == EM_PPC64 && in.plt->isNeeded()) {
14341442 // The Glink tag points to 32 bytes before the first lazy symbol resolution
14351443 // stub, which starts directly after the header.
1436 Entries.push_back({DT_PPC64_GLINK, [=] {
1437 unsigned Offset = Target->PltHeaderSize - 32;
1438 return In.Plt->getVA(0) + Offset;
1444 entries.push_back({DT_PPC64_GLINK, [=] {
1445 unsigned offset = target->pltHeaderSize - 32;
1446 return in.plt->getVA(0) + offset;
14391447 }});
14401448 }
14411449
14421450 addInt(DT_NULL, 0);
14431451
1444 getParent()->Link = this->Link;
1445 this->Size = Entries.size() * this->Entsize;
1452 getParent()->link = this->link;
1453 this->size = entries.size() * this->entsize;
14461454}
14471455
1448template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
1449 auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
1456template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *buf) {
1457 auto *p = reinterpret_cast<Elf_Dyn *>(buf);
14501458
1451 for (std::pair<int32_t, std::function<uint64_t()>> &KV : Entries) {
1452 P->d_tag = KV.first;
1453 P->d_un.d_val = KV.second();
1454 ++P;
1459 for (std::pair<int32_t, std::function<uint64_t()>> &kv : entries) {
1460 p->d_tag = kv.first;
1461 p->d_un.d_val = kv.second();
1462 ++p;
14551463 }
14561464}
14571465
14581466uint64_t DynamicReloc::getOffset() const {
1459 return InputSec->getVA(OffsetInSec);
1467 return inputSec->getVA(offsetInSec);
14601468}
14611469
14621470int64_t DynamicReloc::computeAddend() const {
1463 if (UseSymVA)
1464 return Sym->getVA(Addend);
1465 if (!OutputSec)
1466 return Addend;
1471 if (useSymVA)
1472 return sym->getVA(addend);
1473 if (!outputSec)
1474 return addend;
14671475 // See the comment in the DynamicReloc ctor.
1468 return getMipsPageAddr(OutputSec->Addr) + Addend;
1476 return getMipsPageAddr(outputSec->addr) + addend;
14691477}
14701478
1471uint32_t DynamicReloc::getSymIndex() const {
1472 if (Sym && !UseSymVA)
1473 return Sym->DynsymIndex;
1479uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const {
1480 if (sym && !useSymVA)
1481 return symTab->getSymbolIndex(sym);
14741482 return 0;
14751483}
14761484
1477RelocationBaseSection::RelocationBaseSection(StringRef Name, uint32_t Type,
1478 int32_t DynamicTag,
1479 int32_t SizeDynamicTag)
1480 : SyntheticSection(SHF_ALLOC, Type, Config->Wordsize, Name),
1481 DynamicTag(DynamicTag), SizeDynamicTag(SizeDynamicTag) {}
1485RelocationBaseSection::RelocationBaseSection(StringRef name, uint32_t type,
1486 int32_t dynamicTag,
1487 int32_t sizeDynamicTag)
1488 : SyntheticSection(SHF_ALLOC, type, config->wordsize, name),
1489 dynamicTag(dynamicTag), sizeDynamicTag(sizeDynamicTag) {}
14821490
1483void RelocationBaseSection::addReloc(RelType DynType, InputSectionBase *IS,
1484 uint64_t OffsetInSec, Symbol *Sym) {
1485 addReloc({DynType, IS, OffsetInSec, false, Sym, 0});
1491void RelocationBaseSection::addReloc(RelType dynType, InputSectionBase *isec,
1492 uint64_t offsetInSec, Symbol *sym) {
1493 addReloc({dynType, isec, offsetInSec, false, sym, 0});
14861494}
14871495
1488void RelocationBaseSection::addReloc(RelType DynType,
1489 InputSectionBase *InputSec,
1490 uint64_t OffsetInSec, Symbol *Sym,
1491 int64_t Addend, RelExpr Expr,
1492 RelType Type) {
1496void RelocationBaseSection::addReloc(RelType dynType,
1497 InputSectionBase *inputSec,
1498 uint64_t offsetInSec, Symbol *sym,
1499 int64_t addend, RelExpr expr,
1500 RelType type) {
14931501 // Write the addends to the relocated address if required. We skip
14941502 // it if the written value would be zero.
1495 if (Config->WriteAddends && (Expr != R_ADDEND || Addend != 0))
1496 InputSec->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
1497 addReloc({DynType, InputSec, OffsetInSec, Expr != R_ADDEND, Sym, Addend});
1503 if (config->writeAddends && (expr != R_ADDEND || addend != 0))
1504 inputSec->relocations.push_back({expr, type, offsetInSec, addend, sym});
1505 addReloc({dynType, inputSec, offsetInSec, expr != R_ADDEND, sym, addend});
14981506}
14991507
1500void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) {
1501 if (Reloc.Type == Target->RelativeRel)
1502 ++NumRelativeRelocs;
1503 Relocs.push_back(Reloc);
1508void RelocationBaseSection::addReloc(const DynamicReloc &reloc) {
1509 if (reloc.type == target->relativeRel)
1510 ++numRelativeRelocs;
1511 relocs.push_back(reloc);
15041512}
15051513
15061514void RelocationBaseSection::finalizeContents() {
1515 SymbolTableBaseSection *symTab = getPartition().dynSymTab;
1516
15071517 // When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE
15081518 // relocations due to IFUNC (e.g. strcpy). sh_link will be set to 0 in that
15091519 // case.
1510 InputSection *SymTab = Config->Relocatable ? In.SymTab : In.DynSymTab;
1511 if (SymTab && SymTab->getParent())
1512 getParent()->Link = SymTab->getParent()->SectionIndex;
1520 if (symTab && symTab->getParent())
1521 getParent()->link = symTab->getParent()->sectionIndex;
15131522 else
1514 getParent()->Link = 0;
1523 getParent()->link = 0;
15151524
1516 if (In.RelaPlt == this)
1517 getParent()->Info = In.GotPlt->getParent()->SectionIndex;
1518 if (In.RelaIplt == this)
1519 getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
1525 if (in.relaPlt == this)
1526 getParent()->info = in.gotPlt->getParent()->sectionIndex;
1527 if (in.relaIplt == this)
1528 getParent()->info = in.igotPlt->getParent()->sectionIndex;
15201529}
15211530
15221531RelrBaseSection::RelrBaseSection()
15231532 : SyntheticSection(SHF_ALLOC,
1524 Config->UseAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
1525 Config->Wordsize, ".relr.dyn") {}
1533 config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
1534 config->wordsize, ".relr.dyn") {}
15261535
15271536template <class ELFT>
1528static void encodeDynamicReloc(typename ELFT::Rela *P,
1529 const DynamicReloc &Rel) {
1530 if (Config->IsRela)
1531 P->r_addend = Rel.computeAddend();
1532 P->r_offset = Rel.getOffset();
1533 P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->IsMips64EL);
1537static void encodeDynamicReloc(SymbolTableBaseSection *symTab,
1538 typename ELFT::Rela *p,
1539 const DynamicReloc &rel) {
1540 if (config->isRela)
1541 p->r_addend = rel.computeAddend();
1542 p->r_offset = rel.getOffset();
1543 p->setSymbolAndType(rel.getSymIndex(symTab), rel.type, config->isMips64EL);
15341544}
15351545
15361546template <class ELFT>
1537RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
1538 : RelocationBaseSection(Name, Config->IsRela ? SHT_RELA : SHT_REL,
1539 Config->IsRela ? DT_RELA : DT_REL,
1540 Config->IsRela ? DT_RELASZ : DT_RELSZ),
1541 Sort(Sort) {
1542 this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
1547RelocationSection<ELFT>::RelocationSection(StringRef name, bool sort)
1548 : RelocationBaseSection(name, config->isRela ? SHT_RELA : SHT_REL,
1549 config->isRela ? DT_RELA : DT_REL,
1550 config->isRela ? DT_RELASZ : DT_RELSZ),
1551 sort(sort) {
1552 this->entsize = config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
15431553}
15441554
1545static bool compRelocations(const DynamicReloc &A, const DynamicReloc &B) {
1546 bool AIsRel = A.Type == Target->RelativeRel;
1547 bool BIsRel = B.Type == Target->RelativeRel;
1548 if (AIsRel != BIsRel)
1549 return AIsRel;
1550 return A.getSymIndex() < B.getSymIndex();
1551}
1555template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
1556 SymbolTableBaseSection *symTab = getPartition().dynSymTab;
15521557
1553template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
1554 if (Sort)
1555 std::stable_sort(Relocs.begin(), Relocs.end(), compRelocations);
1558 // Sort by (!IsRelative,SymIndex,r_offset). DT_REL[A]COUNT requires us to
1559 // place R_*_RELATIVE first. SymIndex is to improve locality, while r_offset
1560 // is to make results easier to read.
1561 if (sort)
1562 llvm::stable_sort(
1563 relocs, [&](const DynamicReloc &a, const DynamicReloc &b) {
1564 return std::make_tuple(a.type != target->relativeRel,
1565 a.getSymIndex(symTab), a.getOffset()) <
1566 std::make_tuple(b.type != target->relativeRel,
1567 b.getSymIndex(symTab), b.getOffset());
1568 });
15561569
1557 for (const DynamicReloc &Rel : Relocs) {
1558 encodeDynamicReloc<ELFT>(reinterpret_cast<Elf_Rela *>(Buf), Rel);
1559 Buf += Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
1570 for (const DynamicReloc &rel : relocs) {
1571 encodeDynamicReloc<ELFT>(symTab, reinterpret_cast<Elf_Rela *>(buf), rel);
1572 buf += config->isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
15601573 }
15611574}
15621575
1563template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
1564 return this->Entsize * Relocs.size();
1565}
1566
15671576template <class ELFT>
15681577AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
1569 StringRef Name)
1578 StringRef name)
15701579 : RelocationBaseSection(
1571 Name, Config->IsRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
1572 Config->IsRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
1573 Config->IsRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
1574 this->Entsize = 1;
1580 name, config->isRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
1581 config->isRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
1582 config->isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
1583 this->entsize = 1;
15751584}
15761585
15771586template <class ELFT>
......@@ -1621,32 +1630,32 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
16211630 // RELOCATION_GROUPED_BY_ADDEND_FLAG is not set) the r_addend delta for
16221631 // this relocation.
16231632
1624 size_t OldSize = RelocData.size();
1633 size_t oldSize = relocData.size();
16251634
1626 RelocData = {'A', 'P', 'S', '2'};
1627 raw_svector_ostream OS(RelocData);
1628 auto Add = [&](int64_t V) { encodeSLEB128(V, OS); };
1635 relocData = {'A', 'P', 'S', '2'};
1636 raw_svector_ostream os(relocData);
1637 auto add = [&](int64_t v) { encodeSLEB128(v, os); };
16291638
16301639 // The format header includes the number of relocations and the initial
16311640 // offset (we set this to zero because the first relocation group will
16321641 // perform the initial adjustment).
1633 Add(Relocs.size());
1634 Add(0);
1642 add(relocs.size());
1643 add(0);
16351644
1636 std::vector<Elf_Rela> Relatives, NonRelatives;
1645 std::vector<Elf_Rela> relatives, nonRelatives;
16371646
1638 for (const DynamicReloc &Rel : Relocs) {
1639 Elf_Rela R;
1640 encodeDynamicReloc<ELFT>(&R, Rel);
1647 for (const DynamicReloc &rel : relocs) {
1648 Elf_Rela r;
1649 encodeDynamicReloc<ELFT>(getPartition().dynSymTab, &r, rel);
16411650
1642 if (R.getType(Config->IsMips64EL) == Target->RelativeRel)
1643 Relatives.push_back(R);
1651 if (r.getType(config->isMips64EL) == target->relativeRel)
1652 relatives.push_back(r);
16441653 else
1645 NonRelatives.push_back(R);
1654 nonRelatives.push_back(r);
16461655 }
16471656
1648 llvm::sort(Relatives, [](const Elf_Rel &A, const Elf_Rel &B) {
1649 return A.r_offset < B.r_offset;
1657 llvm::sort(relatives, [](const Elf_Rel &a, const Elf_Rel &b) {
1658 return a.r_offset < b.r_offset;
16501659 });
16511660
16521661 // Try to find groups of relative relocations which are spaced one word
......@@ -1655,108 +1664,108 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
16551664 // encoding, but each group will cost 7 bytes in addition to the offset from
16561665 // the previous group, so it is only profitable to do this for groups of
16571666 // size 8 or larger.
1658 std::vector<Elf_Rela> UngroupedRelatives;
1659 std::vector<std::vector<Elf_Rela>> RelativeGroups;
1660 for (auto I = Relatives.begin(), E = Relatives.end(); I != E;) {
1661 std::vector<Elf_Rela> Group;
1667 std::vector<Elf_Rela> ungroupedRelatives;
1668 std::vector<std::vector<Elf_Rela>> relativeGroups;
1669 for (auto i = relatives.begin(), e = relatives.end(); i != e;) {
1670 std::vector<Elf_Rela> group;
16621671 do {
1663 Group.push_back(*I++);
1664 } while (I != E && (I - 1)->r_offset + Config->Wordsize == I->r_offset);
1672 group.push_back(*i++);
1673 } while (i != e && (i - 1)->r_offset + config->wordsize == i->r_offset);
16651674
1666 if (Group.size() < 8)
1667 UngroupedRelatives.insert(UngroupedRelatives.end(), Group.begin(),
1668 Group.end());
1675 if (group.size() < 8)
1676 ungroupedRelatives.insert(ungroupedRelatives.end(), group.begin(),
1677 group.end());
16691678 else
1670 RelativeGroups.emplace_back(std::move(Group));
1679 relativeGroups.emplace_back(std::move(group));
16711680 }
16721681
1673 unsigned HasAddendIfRela =
1674 Config->IsRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
1682 unsigned hasAddendIfRela =
1683 config->isRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
16751684
1676 uint64_t Offset = 0;
1677 uint64_t Addend = 0;
1685 uint64_t offset = 0;
1686 uint64_t addend = 0;
16781687
16791688 // Emit the run-length encoding for the groups of adjacent relative
16801689 // relocations. Each group is represented using two groups in the packed
16811690 // format. The first is used to set the current offset to the start of the
16821691 // group (and also encodes the first relocation), and the second encodes the
16831692 // remaining relocations.
1684 for (std::vector<Elf_Rela> &G : RelativeGroups) {
1693 for (std::vector<Elf_Rela> &g : relativeGroups) {
16851694 // The first relocation in the group.
1686 Add(1);
1687 Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
1688 RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
1689 Add(G[0].r_offset - Offset);
1690 Add(Target->RelativeRel);
1691 if (Config->IsRela) {
1692 Add(G[0].r_addend - Addend);
1693 Addend = G[0].r_addend;
1695 add(1);
1696 add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
1697 RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
1698 add(g[0].r_offset - offset);
1699 add(target->relativeRel);
1700 if (config->isRela) {
1701 add(g[0].r_addend - addend);
1702 addend = g[0].r_addend;
16941703 }
16951704
16961705 // The remaining relocations.
1697 Add(G.size() - 1);
1698 Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
1699 RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
1700 Add(Config->Wordsize);
1701 Add(Target->RelativeRel);
1702 if (Config->IsRela) {
1703 for (auto I = G.begin() + 1, E = G.end(); I != E; ++I) {
1704 Add(I->r_addend - Addend);
1705 Addend = I->r_addend;
1706 add(g.size() - 1);
1707 add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
1708 RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
1709 add(config->wordsize);
1710 add(target->relativeRel);
1711 if (config->isRela) {
1712 for (auto i = g.begin() + 1, e = g.end(); i != e; ++i) {
1713 add(i->r_addend - addend);
1714 addend = i->r_addend;
17061715 }
17071716 }
17081717
1709 Offset = G.back().r_offset;
1718 offset = g.back().r_offset;
17101719 }
17111720
17121721 // Now the ungrouped relatives.
1713 if (!UngroupedRelatives.empty()) {
1714 Add(UngroupedRelatives.size());
1715 Add(RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
1716 Add(Target->RelativeRel);
1717 for (Elf_Rela &R : UngroupedRelatives) {
1718 Add(R.r_offset - Offset);
1719 Offset = R.r_offset;
1720 if (Config->IsRela) {
1721 Add(R.r_addend - Addend);
1722 Addend = R.r_addend;
1722 if (!ungroupedRelatives.empty()) {
1723 add(ungroupedRelatives.size());
1724 add(RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
1725 add(target->relativeRel);
1726 for (Elf_Rela &r : ungroupedRelatives) {
1727 add(r.r_offset - offset);
1728 offset = r.r_offset;
1729 if (config->isRela) {
1730 add(r.r_addend - addend);
1731 addend = r.r_addend;
17231732 }
17241733 }
17251734 }
17261735
17271736 // Finally the non-relative relocations.
1728 llvm::sort(NonRelatives, [](const Elf_Rela &A, const Elf_Rela &B) {
1729 return A.r_offset < B.r_offset;
1737 llvm::sort(nonRelatives, [](const Elf_Rela &a, const Elf_Rela &b) {
1738 return a.r_offset < b.r_offset;
17301739 });
1731 if (!NonRelatives.empty()) {
1732 Add(NonRelatives.size());
1733 Add(HasAddendIfRela);
1734 for (Elf_Rela &R : NonRelatives) {
1735 Add(R.r_offset - Offset);
1736 Offset = R.r_offset;
1737 Add(R.r_info);
1738 if (Config->IsRela) {
1739 Add(R.r_addend - Addend);
1740 Addend = R.r_addend;
1740 if (!nonRelatives.empty()) {
1741 add(nonRelatives.size());
1742 add(hasAddendIfRela);
1743 for (Elf_Rela &r : nonRelatives) {
1744 add(r.r_offset - offset);
1745 offset = r.r_offset;
1746 add(r.r_info);
1747 if (config->isRela) {
1748 add(r.r_addend - addend);
1749 addend = r.r_addend;
17411750 }
17421751 }
17431752 }
17441753
17451754 // Don't allow the section to shrink; otherwise the size of the section can
17461755 // oscillate infinitely.
1747 if (RelocData.size() < OldSize)
1748 RelocData.append(OldSize - RelocData.size(), 0);
1756 if (relocData.size() < oldSize)
1757 relocData.append(oldSize - relocData.size(), 0);
17491758
17501759 // Returns whether the section size changed. We need to keep recomputing both
17511760 // section layout and the contents of this section until the size converges
17521761 // because changing this section's size can affect section layout, which in
17531762 // turn can affect the sizes of the LEB-encoded integers stored in this
17541763 // section.
1755 return RelocData.size() != OldSize;
1764 return relocData.size() != oldSize;
17561765}
17571766
17581767template <class ELFT> RelrSection<ELFT>::RelrSection() {
1759 this->Entsize = Config->Wordsize;
1768 this->entsize = config->wordsize;
17601769}
17611770
17621771template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
......@@ -1790,90 +1799,90 @@ template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
17901799 // even means address, odd means bitmap.
17911800 // 2. Just a simple list of addresses is a valid encoding.
17921801
1793 size_t OldSize = RelrRelocs.size();
1794 RelrRelocs.clear();
1802 size_t oldSize = relrRelocs.size();
1803 relrRelocs.clear();
17951804
17961805 // Same as Config->Wordsize but faster because this is a compile-time
17971806 // constant.
1798 const size_t Wordsize = sizeof(typename ELFT::uint);
1807 const size_t wordsize = sizeof(typename ELFT::uint);
17991808
18001809 // Number of bits to use for the relocation offsets bitmap.
18011810 // Must be either 63 or 31.
1802 const size_t NBits = Wordsize * 8 - 1;
1811 const size_t nBits = wordsize * 8 - 1;
18031812
18041813 // Get offsets for all relative relocations and sort them.
1805 std::vector<uint64_t> Offsets;
1806 for (const RelativeReloc &Rel : Relocs)
1807 Offsets.push_back(Rel.getOffset());
1808 llvm::sort(Offsets.begin(), Offsets.end());
1814 std::vector<uint64_t> offsets;
1815 for (const RelativeReloc &rel : relocs)
1816 offsets.push_back(rel.getOffset());
1817 llvm::sort(offsets);
18091818
18101819 // For each leading relocation, find following ones that can be folded
18111820 // as a bitmap and fold them.
1812 for (size_t I = 0, E = Offsets.size(); I < E;) {
1821 for (size_t i = 0, e = offsets.size(); i < e;) {
18131822 // Add a leading relocation.
1814 RelrRelocs.push_back(Elf_Relr(Offsets[I]));
1815 uint64_t Base = Offsets[I] + Wordsize;
1816 ++I;
1823 relrRelocs.push_back(Elf_Relr(offsets[i]));
1824 uint64_t base = offsets[i] + wordsize;
1825 ++i;
18171826
18181827 // Find foldable relocations to construct bitmaps.
1819 while (I < E) {
1820 uint64_t Bitmap = 0;
1828 while (i < e) {
1829 uint64_t bitmap = 0;
18211830
1822 while (I < E) {
1823 uint64_t Delta = Offsets[I] - Base;
1831 while (i < e) {
1832 uint64_t delta = offsets[i] - base;
18241833
18251834 // If it is too far, it cannot be folded.
1826 if (Delta >= NBits * Wordsize)
1835 if (delta >= nBits * wordsize)
18271836 break;
18281837
18291838 // If it is not a multiple of wordsize away, it cannot be folded.
1830 if (Delta % Wordsize)
1839 if (delta % wordsize)
18311840 break;
18321841
18331842 // Fold it.
1834 Bitmap |= 1ULL << (Delta / Wordsize);
1835 ++I;
1843 bitmap |= 1ULL << (delta / wordsize);
1844 ++i;
18361845 }
18371846
1838 if (!Bitmap)
1847 if (!bitmap)
18391848 break;
18401849
1841 RelrRelocs.push_back(Elf_Relr((Bitmap << 1) | 1));
1842 Base += NBits * Wordsize;
1850 relrRelocs.push_back(Elf_Relr((bitmap << 1) | 1));
1851 base += nBits * wordsize;
18431852 }
18441853 }
18451854
1846 return RelrRelocs.size() != OldSize;
1855 return relrRelocs.size() != oldSize;
18471856}
18481857
1849SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec)
1850 : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
1851 StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
1852 Config->Wordsize,
1853 StrTabSec.isDynamic() ? ".dynsym" : ".symtab"),
1854 StrTabSec(StrTabSec) {}
1858SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &strTabSec)
1859 : SyntheticSection(strTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
1860 strTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
1861 config->wordsize,
1862 strTabSec.isDynamic() ? ".dynsym" : ".symtab"),
1863 strTabSec(strTabSec) {}
18551864
18561865// Orders symbols according to their positions in the GOT,
18571866// in compliance with MIPS ABI rules.
18581867// See "Global Offset Table" in Chapter 5 in the following document
18591868// for detailed description:
18601869// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1861static bool sortMipsSymbols(const SymbolTableEntry &L,
1862 const SymbolTableEntry &R) {
1870static bool sortMipsSymbols(const SymbolTableEntry &l,
1871 const SymbolTableEntry &r) {
18631872 // Sort entries related to non-local preemptible symbols by GOT indexes.
18641873 // All other entries go to the beginning of a dynsym in arbitrary order.
1865 if (L.Sym->isInGot() && R.Sym->isInGot())
1866 return L.Sym->GotIndex < R.Sym->GotIndex;
1867 if (!L.Sym->isInGot() && !R.Sym->isInGot())
1874 if (l.sym->isInGot() && r.sym->isInGot())
1875 return l.sym->gotIndex < r.sym->gotIndex;
1876 if (!l.sym->isInGot() && !r.sym->isInGot())
18681877 return false;
1869 return !L.Sym->isInGot();
1878 return !l.sym->isInGot();
18701879}
18711880
18721881void SymbolTableBaseSection::finalizeContents() {
1873 if (OutputSection *Sec = StrTabSec.getParent())
1874 getParent()->Link = Sec->SectionIndex;
1882 if (OutputSection *sec = strTabSec.getParent())
1883 getParent()->link = sec->sectionIndex;
18751884
1876 if (this->Type != SHT_DYNSYM) {
1885 if (this->type != SHT_DYNSYM) {
18771886 sortSymTabSymbols();
18781887 return;
18791888 }
......@@ -1883,18 +1892,22 @@ void SymbolTableBaseSection::finalizeContents() {
18831892
18841893 // Section's Info field has the index of the first non-local symbol.
18851894 // Because the first symbol entry is a null entry, 1 is the first.
1886 getParent()->Info = 1;
1895 getParent()->info = 1;
18871896
1888 if (In.GnuHashTab) {
1897 if (getPartition().gnuHashTab) {
18891898 // NB: It also sorts Symbols to meet the GNU hash table requirements.
1890 In.GnuHashTab->addSymbols(Symbols);
1891 } else if (Config->EMachine == EM_MIPS) {
1892 std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
1899 getPartition().gnuHashTab->addSymbols(symbols);
1900 } else if (config->emachine == EM_MIPS) {
1901 llvm::stable_sort(symbols, sortMipsSymbols);
18931902 }
18941903
1895 size_t I = 0;
1896 for (const SymbolTableEntry &S : Symbols)
1897 S.Sym->DynsymIndex = ++I;
1904 // Only the main partition's dynsym indexes are stored in the symbols
1905 // themselves. All other partitions use a lookup table.
1906 if (this == mainPart->dynSymTab) {
1907 size_t i = 0;
1908 for (const SymbolTableEntry &s : symbols)
1909 s.sym->dynsymIndex = ++i;
1910 }
18981911}
18991912
19001913// The ELF spec requires that all local symbols precede global symbols, so we
......@@ -1906,193 +1919,210 @@ void SymbolTableBaseSection::finalizeContents() {
19061919// coming from.
19071920void SymbolTableBaseSection::sortSymTabSymbols() {
19081921 // Move all local symbols before global symbols.
1909 auto E = std::stable_partition(
1910 Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
1911 return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL;
1922 auto e = std::stable_partition(
1923 symbols.begin(), symbols.end(), [](const SymbolTableEntry &s) {
1924 return s.sym->isLocal() || s.sym->computeBinding() == STB_LOCAL;
19121925 });
1913 size_t NumLocals = E - Symbols.begin();
1914 getParent()->Info = NumLocals + 1;
1926 size_t numLocals = e - symbols.begin();
1927 getParent()->info = numLocals + 1;
19151928
19161929 // We want to group the local symbols by file. For that we rebuild the local
19171930 // part of the symbols vector. We do not need to care about the STT_FILE
19181931 // symbols, they are already naturally placed first in each group. That
19191932 // happens because STT_FILE is always the first symbol in the object and hence
19201933 // precede all other local symbols we add for a file.
1921 MapVector<InputFile *, std::vector<SymbolTableEntry>> Arr;
1922 for (const SymbolTableEntry &S : llvm::make_range(Symbols.begin(), E))
1923 Arr[S.Sym->File].push_back(S);
1934 MapVector<InputFile *, std::vector<SymbolTableEntry>> arr;
1935 for (const SymbolTableEntry &s : llvm::make_range(symbols.begin(), e))
1936 arr[s.sym->file].push_back(s);
19241937
1925 auto I = Symbols.begin();
1926 for (std::pair<InputFile *, std::vector<SymbolTableEntry>> &P : Arr)
1927 for (SymbolTableEntry &Entry : P.second)
1928 *I++ = Entry;
1938 auto i = symbols.begin();
1939 for (std::pair<InputFile *, std::vector<SymbolTableEntry>> &p : arr)
1940 for (SymbolTableEntry &entry : p.second)
1941 *i++ = entry;
19291942}
19301943
1931void SymbolTableBaseSection::addSymbol(Symbol *B) {
1944void SymbolTableBaseSection::addSymbol(Symbol *b) {
19321945 // Adding a local symbol to a .dynsym is a bug.
1933 assert(this->Type != SHT_DYNSYM || !B->isLocal());
1946 assert(this->type != SHT_DYNSYM || !b->isLocal());
19341947
1935 bool HashIt = B->isLocal();
1936 Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)});
1948 bool hashIt = b->isLocal();
1949 symbols.push_back({b, strTabSec.addString(b->getName(), hashIt)});
19371950}
19381951
1939size_t SymbolTableBaseSection::getSymbolIndex(Symbol *Sym) {
1940 // Initializes symbol lookup tables lazily. This is used only
1941 // for -r or -emit-relocs.
1942 llvm::call_once(OnceFlag, [&] {
1943 SymbolIndexMap.reserve(Symbols.size());
1944 size_t I = 0;
1945 for (const SymbolTableEntry &E : Symbols) {
1946 if (E.Sym->Type == STT_SECTION)
1947 SectionIndexMap[E.Sym->getOutputSection()] = ++I;
1952size_t SymbolTableBaseSection::getSymbolIndex(Symbol *sym) {
1953 if (this == mainPart->dynSymTab)
1954 return sym->dynsymIndex;
1955
1956 // Initializes symbol lookup tables lazily. This is used only for -r,
1957 // -emit-relocs and dynsyms in partitions other than the main one.
1958 llvm::call_once(onceFlag, [&] {
1959 symbolIndexMap.reserve(symbols.size());
1960 size_t i = 0;
1961 for (const SymbolTableEntry &e : symbols) {
1962 if (e.sym->type == STT_SECTION)
1963 sectionIndexMap[e.sym->getOutputSection()] = ++i;
19481964 else
1949 SymbolIndexMap[E.Sym] = ++I;
1965 symbolIndexMap[e.sym] = ++i;
19501966 }
19511967 });
19521968
19531969 // Section symbols are mapped based on their output sections
19541970 // to maintain their semantics.
1955 if (Sym->Type == STT_SECTION)
1956 return SectionIndexMap.lookup(Sym->getOutputSection());
1957 return SymbolIndexMap.lookup(Sym);
1971 if (sym->type == STT_SECTION)
1972 return sectionIndexMap.lookup(sym->getOutputSection());
1973 return symbolIndexMap.lookup(sym);
19581974}
19591975
19601976template <class ELFT>
1961SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec)
1962 : SymbolTableBaseSection(StrTabSec) {
1963 this->Entsize = sizeof(Elf_Sym);
1977SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &strTabSec)
1978 : SymbolTableBaseSection(strTabSec) {
1979 this->entsize = sizeof(Elf_Sym);
19641980}
19651981
1966static BssSection *getCommonSec(Symbol *Sym) {
1967 if (!Config->DefineCommon)
1968 if (auto *D = dyn_cast<Defined>(Sym))
1969 return dyn_cast_or_null<BssSection>(D->Section);
1982static BssSection *getCommonSec(Symbol *sym) {
1983 if (!config->defineCommon)
1984 if (auto *d = dyn_cast<Defined>(sym))
1985 return dyn_cast_or_null<BssSection>(d->section);
19701986 return nullptr;
19711987}
19721988
1973static uint32_t getSymSectionIndex(Symbol *Sym) {
1974 if (getCommonSec(Sym))
1989static uint32_t getSymSectionIndex(Symbol *sym) {
1990 if (getCommonSec(sym))
19751991 return SHN_COMMON;
1976 if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)
1992 if (!isa<Defined>(sym) || sym->needsPltAddr)
19771993 return SHN_UNDEF;
1978 if (const OutputSection *OS = Sym->getOutputSection())
1979 return OS->SectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
1980 : OS->SectionIndex;
1994 if (const OutputSection *os = sym->getOutputSection())
1995 return os->sectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
1996 : os->sectionIndex;
19811997 return SHN_ABS;
19821998}
19831999
19842000// Write the internal symbol table contents to the output symbol table.
1985template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
2001template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
19862002 // The first entry is a null entry as per the ELF spec.
1987 memset(Buf, 0, sizeof(Elf_Sym));
1988 Buf += sizeof(Elf_Sym);
2003 memset(buf, 0, sizeof(Elf_Sym));
2004 buf += sizeof(Elf_Sym);
19892005
1990 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
2006 auto *eSym = reinterpret_cast<Elf_Sym *>(buf);
19912007
1992 for (SymbolTableEntry &Ent : Symbols) {
1993 Symbol *Sym = Ent.Sym;
2008 for (SymbolTableEntry &ent : symbols) {
2009 Symbol *sym = ent.sym;
2010 bool isDefinedHere = type == SHT_SYMTAB || sym->partition == partition;
19942011
19952012 // Set st_info and st_other.
1996 ESym->st_other = 0;
1997 if (Sym->isLocal()) {
1998 ESym->setBindingAndType(STB_LOCAL, Sym->Type);
2013 eSym->st_other = 0;
2014 if (sym->isLocal()) {
2015 eSym->setBindingAndType(STB_LOCAL, sym->type);
19992016 } else {
2000 ESym->setBindingAndType(Sym->computeBinding(), Sym->Type);
2001 ESym->setVisibility(Sym->Visibility);
2017 eSym->setBindingAndType(sym->computeBinding(), sym->type);
2018 eSym->setVisibility(sym->visibility);
20022019 }
20032020
2004 ESym->st_name = Ent.StrTabOffset;
2005 ESym->st_shndx = getSymSectionIndex(Ent.Sym);
2021 // The 3 most significant bits of st_other are used by OpenPOWER ABI.
2022 // See getPPC64GlobalEntryToLocalEntryOffset() for more details.
2023 if (config->emachine == EM_PPC64)
2024 eSym->st_other |= sym->stOther & 0xe0;
2025
2026 eSym->st_name = ent.strTabOffset;
2027 if (isDefinedHere)
2028 eSym->st_shndx = getSymSectionIndex(ent.sym);
2029 else
2030 eSym->st_shndx = 0;
20062031
20072032 // Copy symbol size if it is a defined symbol. st_size is not significant
20082033 // for undefined symbols, so whether copying it or not is up to us if that's
20092034 // the case. We'll leave it as zero because by not setting a value, we can
20102035 // get the exact same outputs for two sets of input files that differ only
20112036 // in undefined symbol size in DSOs.
2012 if (ESym->st_shndx == SHN_UNDEF)
2013 ESym->st_size = 0;
2037 if (eSym->st_shndx == SHN_UNDEF || !isDefinedHere)
2038 eSym->st_size = 0;
20142039 else
2015 ESym->st_size = Sym->getSize();
2040 eSym->st_size = sym->getSize();
20162041
20172042 // st_value is usually an address of a symbol, but that has a
20182043 // special meaining for uninstantiated common symbols (this can
20192044 // occur if -r is given).
2020 if (BssSection *CommonSec = getCommonSec(Ent.Sym))
2021 ESym->st_value = CommonSec->Alignment;
2045 if (BssSection *commonSec = getCommonSec(ent.sym))
2046 eSym->st_value = commonSec->alignment;
2047 else if (isDefinedHere)
2048 eSym->st_value = sym->getVA();
20222049 else
2023 ESym->st_value = Sym->getVA();
2050 eSym->st_value = 0;
20242051
2025 ++ESym;
2052 ++eSym;
20262053 }
20272054
20282055 // On MIPS we need to mark symbol which has a PLT entry and requires
20292056 // pointer equality by STO_MIPS_PLT flag. That is necessary to help
20302057 // dynamic linker distinguish such symbols and MIPS lazy-binding stubs.
20312058 // https://sourceware.org/ml/binutils/2008-07/txt00000.txt
2032 if (Config->EMachine == EM_MIPS) {
2033 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
2059 if (config->emachine == EM_MIPS) {
2060 auto *eSym = reinterpret_cast<Elf_Sym *>(buf);
20342061
2035 for (SymbolTableEntry &Ent : Symbols) {
2036 Symbol *Sym = Ent.Sym;
2037 if (Sym->isInPlt() && Sym->NeedsPltAddr)
2038 ESym->st_other |= STO_MIPS_PLT;
2062 for (SymbolTableEntry &ent : symbols) {
2063 Symbol *sym = ent.sym;
2064 if (sym->isInPlt() && sym->needsPltAddr)
2065 eSym->st_other |= STO_MIPS_PLT;
20392066 if (isMicroMips()) {
2040 // Set STO_MIPS_MICROMIPS flag and less-significant bit for
2041 // a defined microMIPS symbol and symbol should point to its
2042 // PLT entry (in case of microMIPS, PLT entries always contain
2043 // microMIPS code).
2044 if (Sym->isDefined() &&
2045 ((Sym->StOther & STO_MIPS_MICROMIPS) || Sym->NeedsPltAddr)) {
2046 if (StrTabSec.isDynamic())
2047 ESym->st_value |= 1;
2048 ESym->st_other |= STO_MIPS_MICROMIPS;
2067 // We already set the less-significant bit for symbols
2068 // marked by the `STO_MIPS_MICROMIPS` flag and for microMIPS PLT
2069 // records. That allows us to distinguish such symbols in
2070 // the `MIPS<ELFT>::relocateOne()` routine. Now we should
2071 // clear that bit for non-dynamic symbol table, so tools
2072 // like `objdump` will be able to deal with a correct
2073 // symbol position.
2074 if (sym->isDefined() &&
2075 ((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsPltAddr)) {
2076 if (!strTabSec.isDynamic())
2077 eSym->st_value &= ~1;
2078 eSym->st_other |= STO_MIPS_MICROMIPS;
20492079 }
20502080 }
2051 if (Config->Relocatable)
2052 if (auto *D = dyn_cast<Defined>(Sym))
2053 if (isMipsPIC<ELFT>(D))
2054 ESym->st_other |= STO_MIPS_PIC;
2055 ++ESym;
2081 if (config->relocatable)
2082 if (auto *d = dyn_cast<Defined>(sym))
2083 if (isMipsPIC<ELFT>(d))
2084 eSym->st_other |= STO_MIPS_PIC;
2085 ++eSym;
20562086 }
20572087 }
20582088}
20592089
20602090SymtabShndxSection::SymtabShndxSection()
2061 : SyntheticSection(0, SHT_SYMTAB_SHNDX, 4, ".symtab_shndxr") {
2062 this->Entsize = 4;
2091 : SyntheticSection(0, SHT_SYMTAB_SHNDX, 4, ".symtab_shndx") {
2092 this->entsize = 4;
20632093}
20642094
2065void SymtabShndxSection::writeTo(uint8_t *Buf) {
2095void SymtabShndxSection::writeTo(uint8_t *buf) {
20662096 // We write an array of 32 bit values, where each value has 1:1 association
20672097 // with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,
20682098 // we need to write actual index, otherwise, we must write SHN_UNDEF(0).
2069 Buf += 4; // Ignore .symtab[0] entry.
2070 for (const SymbolTableEntry &Entry : In.SymTab->getSymbols()) {
2071 if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)
2072 write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);
2073 Buf += 4;
2099 buf += 4; // Ignore .symtab[0] entry.
2100 for (const SymbolTableEntry &entry : in.symTab->getSymbols()) {
2101 if (getSymSectionIndex(entry.sym) == SHN_XINDEX)
2102 write32(buf, entry.sym->getOutputSection()->sectionIndex);
2103 buf += 4;
20742104 }
20752105}
20762106
2077bool SymtabShndxSection::empty() const {
2107bool SymtabShndxSection::isNeeded() const {
20782108 // SHT_SYMTAB can hold symbols with section indices values up to
20792109 // SHN_LORESERVE. If we need more, we want to use extension SHT_SYMTAB_SHNDX
20802110 // section. Problem is that we reveal the final section indices a bit too
20812111 // late, and we do not know them here. For simplicity, we just always create
2082 // a .symtab_shndxr section when the amount of output sections is huge.
2083 size_t Size = 0;
2084 for (BaseCommand *Base : Script->SectionCommands)
2085 if (isa<OutputSection>(Base))
2086 ++Size;
2087 return Size < SHN_LORESERVE;
2112 // a .symtab_shndx section when the amount of output sections is huge.
2113 size_t size = 0;
2114 for (BaseCommand *base : script->sectionCommands)
2115 if (isa<OutputSection>(base))
2116 ++size;
2117 return size >= SHN_LORESERVE;
20882118}
20892119
20902120void SymtabShndxSection::finalizeContents() {
2091 getParent()->Link = In.SymTab->getParent()->SectionIndex;
2121 getParent()->link = in.symTab->getParent()->sectionIndex;
20922122}
20932123
20942124size_t SymtabShndxSection::getSize() const {
2095 return In.SymTab->getNumSymbols() * 4;
2125 return in.symTab->getNumSymbols() * 4;
20962126}
20972127
20982128// .hash and .gnu.hash sections contain on-disk hash tables that map
......@@ -2127,45 +2157,45 @@ size_t SymtabShndxSection::getSize() const {
21272157// about .gnu.hash, you want to specify -hash-style=gnu. Otherwise, a
21282158// safe bet is to specify -hash-style=both for backward compatibilty.
21292159GnuHashTableSection::GnuHashTableSection()
2130 : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") {
2160 : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, config->wordsize, ".gnu.hash") {
21312161}
21322162
21332163void GnuHashTableSection::finalizeContents() {
2134 if (OutputSection *Sec = In.DynSymTab->getParent())
2135 getParent()->Link = Sec->SectionIndex;
2164 if (OutputSection *sec = getPartition().dynSymTab->getParent())
2165 getParent()->link = sec->sectionIndex;
21362166
21372167 // Computes bloom filter size in word size. We want to allocate 12
21382168 // bits for each symbol. It must be a power of two.
2139 if (Symbols.empty()) {
2140 MaskWords = 1;
2169 if (symbols.empty()) {
2170 maskWords = 1;
21412171 } else {
2142 uint64_t NumBits = Symbols.size() * 12;
2143 MaskWords = NextPowerOf2(NumBits / (Config->Wordsize * 8));
2172 uint64_t numBits = symbols.size() * 12;
2173 maskWords = NextPowerOf2(numBits / (config->wordsize * 8));
21442174 }
21452175
2146 Size = 16; // Header
2147 Size += Config->Wordsize * MaskWords; // Bloom filter
2148 Size += NBuckets * 4; // Hash buckets
2149 Size += Symbols.size() * 4; // Hash values
2176 size = 16; // Header
2177 size += config->wordsize * maskWords; // Bloom filter
2178 size += nBuckets * 4; // Hash buckets
2179 size += symbols.size() * 4; // Hash values
21502180}
21512181
2152void GnuHashTableSection::writeTo(uint8_t *Buf) {
2182void GnuHashTableSection::writeTo(uint8_t *buf) {
21532183 // The output buffer is not guaranteed to be zero-cleared because we pre-
21542184 // fill executable sections with trap instructions. This is a precaution
21552185 // for that case, which happens only when -no-rosegment is given.
2156 memset(Buf, 0, Size);
2186 memset(buf, 0, size);
21572187
21582188 // Write a header.
2159 write32(Buf, NBuckets);
2160 write32(Buf + 4, In.DynSymTab->getNumSymbols() - Symbols.size());
2161 write32(Buf + 8, MaskWords);
2162 write32(Buf + 12, Shift2);
2163 Buf += 16;
2189 write32(buf, nBuckets);
2190 write32(buf + 4, getPartition().dynSymTab->getNumSymbols() - symbols.size());
2191 write32(buf + 8, maskWords);
2192 write32(buf + 12, Shift2);
2193 buf += 16;
21642194
21652195 // Write a bloom filter and a hash table.
2166 writeBloomFilter(Buf);
2167 Buf += Config->Wordsize * MaskWords;
2168 writeHashTable(Buf);
2196 writeBloomFilter(buf);
2197 buf += config->wordsize * maskWords;
2198 writeHashTable(buf);
21692199}
21702200
21712201// This function writes a 2-bit bloom filter. This bloom filter alone
......@@ -2175,57 +2205,58 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) {
21752205//
21762206// [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2),
21772207// p.9, https://www.akkadia.org/drepper/dsohowto.pdf
2178void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
2179 unsigned C = Config->Is64 ? 64 : 32;
2180 for (const Entry &Sym : Symbols) {
2208void GnuHashTableSection::writeBloomFilter(uint8_t *buf) {
2209 unsigned c = config->is64 ? 64 : 32;
2210 for (const Entry &sym : symbols) {
21812211 // When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
21822212 // the word using bits [0:5] and [26:31].
2183 size_t I = (Sym.Hash / C) & (MaskWords - 1);
2184 uint64_t Val = readUint(Buf + I * Config->Wordsize);
2185 Val |= uint64_t(1) << (Sym.Hash % C);
2186 Val |= uint64_t(1) << ((Sym.Hash >> Shift2) % C);
2187 writeUint(Buf + I * Config->Wordsize, Val);
2213 size_t i = (sym.hash / c) & (maskWords - 1);
2214 uint64_t val = readUint(buf + i * config->wordsize);
2215 val |= uint64_t(1) << (sym.hash % c);
2216 val |= uint64_t(1) << ((sym.hash >> Shift2) % c);
2217 writeUint(buf + i * config->wordsize, val);
21882218 }
21892219}
21902220
2191void GnuHashTableSection::writeHashTable(uint8_t *Buf) {
2192 uint32_t *Buckets = reinterpret_cast<uint32_t *>(Buf);
2193 uint32_t OldBucket = -1;
2194 uint32_t *Values = Buckets + NBuckets;
2195 for (auto I = Symbols.begin(), E = Symbols.end(); I != E; ++I) {
2221void GnuHashTableSection::writeHashTable(uint8_t *buf) {
2222 uint32_t *buckets = reinterpret_cast<uint32_t *>(buf);
2223 uint32_t oldBucket = -1;
2224 uint32_t *values = buckets + nBuckets;
2225 for (auto i = symbols.begin(), e = symbols.end(); i != e; ++i) {
21962226 // Write a hash value. It represents a sequence of chains that share the
21972227 // same hash modulo value. The last element of each chain is terminated by
21982228 // LSB 1.
2199 uint32_t Hash = I->Hash;
2200 bool IsLastInChain = (I + 1) == E || I->BucketIdx != (I + 1)->BucketIdx;
2201 Hash = IsLastInChain ? Hash | 1 : Hash & ~1;
2202 write32(Values++, Hash);
2229 uint32_t hash = i->hash;
2230 bool isLastInChain = (i + 1) == e || i->bucketIdx != (i + 1)->bucketIdx;
2231 hash = isLastInChain ? hash | 1 : hash & ~1;
2232 write32(values++, hash);
22032233
2204 if (I->BucketIdx == OldBucket)
2234 if (i->bucketIdx == oldBucket)
22052235 continue;
22062236 // Write a hash bucket. Hash buckets contain indices in the following hash
22072237 // value table.
2208 write32(Buckets + I->BucketIdx, I->Sym->DynsymIndex);
2209 OldBucket = I->BucketIdx;
2238 write32(buckets + i->bucketIdx,
2239 getPartition().dynSymTab->getSymbolIndex(i->sym));
2240 oldBucket = i->bucketIdx;
22102241 }
22112242}
22122243
2213static uint32_t hashGnu(StringRef Name) {
2214 uint32_t H = 5381;
2215 for (uint8_t C : Name)
2216 H = (H << 5) + H + C;
2217 return H;
2244static uint32_t hashGnu(StringRef name) {
2245 uint32_t h = 5381;
2246 for (uint8_t c : name)
2247 h = (h << 5) + h + c;
2248 return h;
22182249}
22192250
22202251// Add symbols to this symbol hash table. Note that this function
22212252// destructively sort a given vector -- which is needed because
22222253// GNU-style hash table places some sorting requirements.
2223void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
2254void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &v) {
22242255 // We cannot use 'auto' for Mid because GCC 6.1 cannot deduce
22252256 // its type correctly.
2226 std::vector<SymbolTableEntry>::iterator Mid =
2227 std::stable_partition(V.begin(), V.end(), [](const SymbolTableEntry &S) {
2228 return !S.Sym->isDefined();
2257 std::vector<SymbolTableEntry>::iterator mid =
2258 std::stable_partition(v.begin(), v.end(), [&](const SymbolTableEntry &s) {
2259 return !s.sym->isDefined() || s.sym->partition != partition;
22292260 });
22302261
22312262 // We chose load factor 4 for the on-disk hash table. For each hash
......@@ -2237,138 +2268,143 @@ void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
22372268 // Android loader as of 2018 doesn't like a .gnu.hash containing such
22382269 // table. If that's the case, we create a hash table with one unused
22392270 // dummy slot.
2240 NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1);
2271 nBuckets = std::max<size_t>((v.end() - mid) / 4, 1);
22412272
2242 if (Mid == V.end())
2273 if (mid == v.end())
22432274 return;
22442275
2245 for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) {
2246 Symbol *B = Ent.Sym;
2247 uint32_t Hash = hashGnu(B->getName());
2248 uint32_t BucketIdx = Hash % NBuckets;
2249 Symbols.push_back({B, Ent.StrTabOffset, Hash, BucketIdx});
2276 for (SymbolTableEntry &ent : llvm::make_range(mid, v.end())) {
2277 Symbol *b = ent.sym;
2278 uint32_t hash = hashGnu(b->getName());
2279 uint32_t bucketIdx = hash % nBuckets;
2280 symbols.push_back({b, ent.strTabOffset, hash, bucketIdx});
22502281 }
22512282
2252 std::stable_sort(
2253 Symbols.begin(), Symbols.end(),
2254 [](const Entry &L, const Entry &R) { return L.BucketIdx < R.BucketIdx; });
2283 llvm::stable_sort(symbols, [](const Entry &l, const Entry &r) {
2284 return l.bucketIdx < r.bucketIdx;
2285 });
22552286
2256 V.erase(Mid, V.end());
2257 for (const Entry &Ent : Symbols)
2258 V.push_back({Ent.Sym, Ent.StrTabOffset});
2287 v.erase(mid, v.end());
2288 for (const Entry &ent : symbols)
2289 v.push_back({ent.sym, ent.strTabOffset});
22592290}
22602291
22612292HashTableSection::HashTableSection()
22622293 : SyntheticSection(SHF_ALLOC, SHT_HASH, 4, ".hash") {
2263 this->Entsize = 4;
2294 this->entsize = 4;
22642295}
22652296
22662297void HashTableSection::finalizeContents() {
2267 if (OutputSection *Sec = In.DynSymTab->getParent())
2268 getParent()->Link = Sec->SectionIndex;
2298 SymbolTableBaseSection *symTab = getPartition().dynSymTab;
22692299
2270 unsigned NumEntries = 2; // nbucket and nchain.
2271 NumEntries += In.DynSymTab->getNumSymbols(); // The chain entries.
2300 if (OutputSection *sec = symTab->getParent())
2301 getParent()->link = sec->sectionIndex;
2302
2303 unsigned numEntries = 2; // nbucket and nchain.
2304 numEntries += symTab->getNumSymbols(); // The chain entries.
22722305
22732306 // Create as many buckets as there are symbols.
2274 NumEntries += In.DynSymTab->getNumSymbols();
2275 this->Size = NumEntries * 4;
2307 numEntries += symTab->getNumSymbols();
2308 this->size = numEntries * 4;
22762309}
22772310
2278void HashTableSection::writeTo(uint8_t *Buf) {
2311void HashTableSection::writeTo(uint8_t *buf) {
2312 SymbolTableBaseSection *symTab = getPartition().dynSymTab;
2313
22792314 // See comment in GnuHashTableSection::writeTo.
2280 memset(Buf, 0, Size);
2315 memset(buf, 0, size);
22812316
2282 unsigned NumSymbols = In.DynSymTab->getNumSymbols();
2317 unsigned numSymbols = symTab->getNumSymbols();
22832318
2284 uint32_t *P = reinterpret_cast<uint32_t *>(Buf);
2285 write32(P++, NumSymbols); // nbucket
2286 write32(P++, NumSymbols); // nchain
2319 uint32_t *p = reinterpret_cast<uint32_t *>(buf);
2320 write32(p++, numSymbols); // nbucket
2321 write32(p++, numSymbols); // nchain
22872322
2288 uint32_t *Buckets = P;
2289 uint32_t *Chains = P + NumSymbols;
2323 uint32_t *buckets = p;
2324 uint32_t *chains = p + numSymbols;
22902325
2291 for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
2292 Symbol *Sym = S.Sym;
2293 StringRef Name = Sym->getName();
2294 unsigned I = Sym->DynsymIndex;
2295 uint32_t Hash = hashSysV(Name) % NumSymbols;
2296 Chains[I] = Buckets[Hash];
2297 write32(Buckets + Hash, I);
2326 for (const SymbolTableEntry &s : symTab->getSymbols()) {
2327 Symbol *sym = s.sym;
2328 StringRef name = sym->getName();
2329 unsigned i = sym->dynsymIndex;
2330 uint32_t hash = hashSysV(name) % numSymbols;
2331 chains[i] = buckets[hash];
2332 write32(buckets + hash, i);
22982333 }
22992334}
23002335
23012336// On PowerPC64 the lazy symbol resolvers go into the `global linkage table`
23022337// in the .glink section, rather then the typical .plt section.
2303PltSection::PltSection(bool IsIplt)
2304 : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
2305 Config->EMachine == EM_PPC64 ? ".glink" : ".plt"),
2306 HeaderSize(!IsIplt || Config->ZRetpolineplt ? Target->PltHeaderSize : 0),
2307 IsIplt(IsIplt) {
2338PltSection::PltSection(bool isIplt)
2339 : SyntheticSection(
2340 SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
2341 (config->emachine == EM_PPC || config->emachine == EM_PPC64)
2342 ? ".glink"
2343 : ".plt"),
2344 headerSize(!isIplt || config->zRetpolineplt ? target->pltHeaderSize : 0),
2345 isIplt(isIplt) {
23082346 // The PLT needs to be writable on SPARC as the dynamic linker will
23092347 // modify the instructions in the PLT entries.
2310 if (Config->EMachine == EM_SPARCV9)
2311 this->Flags |= SHF_WRITE;
2348 if (config->emachine == EM_SPARCV9)
2349 this->flags |= SHF_WRITE;
23122350}
23132351
2314void PltSection::writeTo(uint8_t *Buf) {
2352void PltSection::writeTo(uint8_t *buf) {
2353 if (config->emachine == EM_PPC) {
2354 writePPC32GlinkSection(buf, entries.size());
2355 return;
2356 }
2357
23152358 // At beginning of PLT or retpoline IPLT, we have code to call the dynamic
23162359 // linker to resolve dynsyms at runtime. Write such code.
2317 if (HeaderSize > 0)
2318 Target->writePltHeader(Buf);
2319 size_t Off = HeaderSize;
2320 // The IPlt is immediately after the Plt, account for this in RelOff
2321 unsigned PltOff = getPltRelocOff();
2360 if (headerSize)
2361 target->writePltHeader(buf);
2362 size_t off = headerSize;
2363
2364 RelocationBaseSection *relSec = isIplt ? in.relaIplt : in.relaPlt;
23222365
2323 for (auto &I : Entries) {
2324 const Symbol *B = I.first;
2325 unsigned RelOff = I.second + PltOff;
2326 uint64_t Got = B->getGotPltVA();
2327 uint64_t Plt = this->getVA() + Off;
2328 Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
2329 Off += Target->PltEntrySize;
2366 // The IPlt is immediately after the Plt, account for this in relOff
2367 size_t pltOff = isIplt ? in.plt->getSize() : 0;
2368
2369 for (size_t i = 0, e = entries.size(); i != e; ++i) {
2370 const Symbol *b = entries[i];
2371 unsigned relOff = relSec->entsize * i + pltOff;
2372 uint64_t got = b->getGotPltVA();
2373 uint64_t plt = this->getVA() + off;
2374 target->writePlt(buf + off, got, plt, b->pltIndex, relOff);
2375 off += target->pltEntrySize;
23302376 }
23312377}
23322378
2333template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
2334 Sym.PltIndex = Entries.size();
2335 RelocationBaseSection *PltRelocSection = In.RelaPlt;
2336 if (IsIplt) {
2337 PltRelocSection = In.RelaIplt;
2338 Sym.IsInIplt = true;
2339 }
2340 unsigned RelOff =
2341 static_cast<RelocationSection<ELFT> *>(PltRelocSection)->getRelocOffset();
2342 Entries.push_back(std::make_pair(&Sym, RelOff));
2379template <class ELFT> void PltSection::addEntry(Symbol &sym) {
2380 sym.pltIndex = entries.size();
2381 entries.push_back(&sym);
23432382}
23442383
23452384size_t PltSection::getSize() const {
2346 return HeaderSize + Entries.size() * Target->PltEntrySize;
2385 return headerSize + entries.size() * target->pltEntrySize;
23472386}
23482387
23492388// Some architectures such as additional symbols in the PLT section. For
23502389// example ARM uses mapping symbols to aid disassembly
23512390void PltSection::addSymbols() {
23522391 // The PLT may have symbols defined for the Header, the IPLT has no header
2353 if (!IsIplt)
2354 Target->addPltHeaderSymbols(*this);
2355 size_t Off = HeaderSize;
2356 for (size_t I = 0; I < Entries.size(); ++I) {
2357 Target->addPltSymbols(*this, Off);
2358 Off += Target->PltEntrySize;
2359 }
2360}
2392 if (!isIplt)
2393 target->addPltHeaderSymbols(*this);
23612394
2362unsigned PltSection::getPltRelocOff() const {
2363 return IsIplt ? In.Plt->getSize() : 0;
2395 size_t off = headerSize;
2396 for (size_t i = 0; i < entries.size(); ++i) {
2397 target->addPltSymbols(*this, off);
2398 off += target->pltEntrySize;
2399 }
23642400}
23652401
23662402// The string hash function for .gdb_index.
2367static uint32_t computeGdbHash(StringRef S) {
2368 uint32_t H = 0;
2369 for (uint8_t C : S)
2370 H = H * 67 + toLower(C) - 113;
2371 return H;
2403static uint32_t computeGdbHash(StringRef s) {
2404 uint32_t h = 0;
2405 for (uint8_t c : s)
2406 h = h * 67 + toLower(c) - 113;
2407 return h;
23722408}
23732409
23742410GdbIndexSection::GdbIndexSection()
......@@ -2377,367 +2413,384 @@ GdbIndexSection::GdbIndexSection()
23772413// Returns the desired size of an on-disk hash table for a .gdb_index section.
23782414// There's a tradeoff between size and collision rate. We aim 75% utilization.
23792415size_t GdbIndexSection::computeSymtabSize() const {
2380 return std::max<size_t>(NextPowerOf2(Symbols.size() * 4 / 3), 1024);
2416 return std::max<size_t>(NextPowerOf2(symbols.size() * 4 / 3), 1024);
23812417}
23822418
23832419// Compute the output section size.
23842420void GdbIndexSection::initOutputSize() {
2385 Size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8;
2421 size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8;
23862422
2387 for (GdbChunk &Chunk : Chunks)
2388 Size += Chunk.CompilationUnits.size() * 16 + Chunk.AddressAreas.size() * 20;
2423 for (GdbChunk &chunk : chunks)
2424 size += chunk.compilationUnits.size() * 16 + chunk.addressAreas.size() * 20;
23892425
23902426 // Add the constant pool size if exists.
2391 if (!Symbols.empty()) {
2392 GdbSymbol &Sym = Symbols.back();
2393 Size += Sym.NameOff + Sym.Name.size() + 1;
2427 if (!symbols.empty()) {
2428 GdbSymbol &sym = symbols.back();
2429 size += sym.nameOff + sym.name.size() + 1;
23942430 }
23952431}
23962432
23972433static std::vector<InputSection *> getDebugInfoSections() {
2398 std::vector<InputSection *> Ret;
2399 for (InputSectionBase *S : InputSections)
2400 if (InputSection *IS = dyn_cast<InputSection>(S))
2401 if (IS->Name == ".debug_info")
2402 Ret.push_back(IS);
2403 return Ret;
2434 std::vector<InputSection *> ret;
2435 for (InputSectionBase *s : inputSections)
2436 if (InputSection *isec = dyn_cast<InputSection>(s))
2437 if (isec->name == ".debug_info")
2438 ret.push_back(isec);
2439 return ret;
24042440}
24052441
2406static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &Dwarf) {
2407 std::vector<GdbIndexSection::CuEntry> Ret;
2408 for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units())
2409 Ret.push_back({Cu->getOffset(), Cu->getLength() + 4});
2410 return Ret;
2442static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &dwarf) {
2443 std::vector<GdbIndexSection::CuEntry> ret;
2444 for (std::unique_ptr<DWARFUnit> &cu : dwarf.compile_units())
2445 ret.push_back({cu->getOffset(), cu->getLength() + 4});
2446 return ret;
24112447}
24122448
24132449static std::vector<GdbIndexSection::AddressEntry>
2414readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
2415 std::vector<GdbIndexSection::AddressEntry> Ret;
2416
2417 uint32_t CuIdx = 0;
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()));
2450readAddressAreas(DWARFContext &dwarf, InputSection *sec) {
2451 std::vector<GdbIndexSection::AddressEntry> ret;
2452
2453 uint32_t cuIdx = 0;
2454 for (std::unique_ptr<DWARFUnit> &cu : dwarf.compile_units()) {
2455 Expected<DWARFAddressRangesVector> ranges = cu->collectAddressRanges();
2456 if (!ranges) {
2457 error(toString(sec) + ": " + toString(ranges.takeError()));
24222458 return {};
24232459 }
24242460
2425 ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
2426 for (DWARFAddressRange &R : *Ranges) {
2427 InputSectionBase *S = Sections[R.SectionIndex];
2428 if (!S || S == &InputSection::Discarded || !S->Live)
2461 ArrayRef<InputSectionBase *> sections = sec->file->getSections();
2462 for (DWARFAddressRange &r : *ranges) {
2463 if (r.SectionIndex == -1ULL)
2464 continue;
2465 InputSectionBase *s = sections[r.SectionIndex];
2466 if (!s || s == &InputSection::discarded || !s->isLive())
24292467 continue;
24302468 // Range list with zero size has no effect.
2431 if (R.LowPC == R.HighPC)
2469 if (r.LowPC == r.HighPC)
24322470 continue;
2433 auto *IS = cast<InputSection>(S);
2434 uint64_t Offset = IS->getOffsetInFile();
2435 Ret.push_back({IS, R.LowPC - Offset, R.HighPC - Offset, CuIdx});
2471 auto *isec = cast<InputSection>(s);
2472 uint64_t offset = isec->getOffsetInFile();
2473 ret.push_back({isec, r.LowPC - offset, r.HighPC - offset, cuIdx});
24362474 }
2437 ++CuIdx;
2475 ++cuIdx;
24382476 }
24392477
2440 return Ret;
2478 return ret;
24412479}
24422480
24432481template <class ELFT>
24442482static 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
2483readPubNamesAndTypes(const LLDDwarfObj<ELFT> &obj,
2484 const std::vector<GdbIndexSection::CuEntry> &cUs) {
2485 const DWARFSection &pubNames = obj.getGnuPubNamesSection();
2486 const DWARFSection &pubTypes = obj.getGnuPubTypesSection();
2487
2488 std::vector<GdbIndexSection::NameAttrEntry> ret;
2489 for (const DWARFSection *pub : {&pubNames, &pubTypes}) {
2490 DWARFDebugPubTable table(obj, *pub, config->isLE, true);
2491 for (const DWARFDebugPubTable::Set &set : table.getData()) {
2492 // The value written into the constant pool is kind << 24 | cuIndex. As we
24552493 // don't know how many compilation units precede this object to compute
2456 // CuIndex, we compute (Kind << 24 | CuIndexInThisObject) instead, and add
2494 // cuIndex, we compute (kind << 24 | cuIndexInThisObject) instead, and add
24572495 // 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;
2496 uint32_t i =
2497 lower_bound(cUs, set.Offset,
2498 [](GdbIndexSection::CuEntry cu, uint32_t offset) {
2499 return cu.cuOffset < offset;
24622500 }) -
2463 CUs.begin();
2464 for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
2465 Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)},
2466 (Ent.Descriptor.toBits() << 24) | I});
2501 cUs.begin();
2502 for (const DWARFDebugPubTable::Entry &ent : set.Entries)
2503 ret.push_back({{ent.Name, computeGdbHash(ent.Name)},
2504 (ent.Descriptor.toBits() << 24) | i});
24672505 }
24682506 }
2469 return Ret;
2507 return ret;
24702508}
24712509
24722510// Create a list of symbols from a given list of symbol names and types
24732511// by uniquifying them by name.
24742512static std::vector<GdbIndexSection::GdbSymbol>
2475createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> NameAttrs,
2476 const std::vector<GdbIndexSection::GdbChunk> &Chunks) {
2477 typedef GdbIndexSection::GdbSymbol GdbSymbol;
2478 typedef GdbIndexSection::NameAttrEntry NameAttrEntry;
2513createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> nameAttrs,
2514 const std::vector<GdbIndexSection::GdbChunk> &chunks) {
2515 using GdbSymbol = GdbIndexSection::GdbSymbol;
2516 using NameAttrEntry = GdbIndexSection::NameAttrEntry;
24792517
24802518 // 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();
2519 uint32_t cuIdx = 0;
2520 std::vector<uint32_t> cuIdxs(chunks.size());
2521 for (uint32_t i = 0, e = chunks.size(); i != e; ++i) {
2522 cuIdxs[i] = cuIdx;
2523 cuIdx += chunks[i].compilationUnits.size();
24862524 }
24872525
24882526 // The number of symbols we will handle in this function is of the order
24892527 // of millions for very large executables, so we use multi-threading to
24902528 // speed it up.
2491 size_t NumShards = 32;
2492 size_t Concurrency = 1;
2493 if (ThreadsEnabled)
2494 Concurrency =
2495 std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards);
2529 size_t numShards = 32;
2530 size_t concurrency = 1;
2531 if (threadsEnabled)
2532 concurrency =
2533 std::min<size_t>(PowerOf2Floor(hardware_concurrency()), numShards);
24962534
24972535 // A sharded map to uniquify symbols by name.
2498 std::vector<DenseMap<CachedHashStringRef, size_t>> Map(NumShards);
2499 size_t Shift = 32 - countTrailingZeros(NumShards);
2536 std::vector<DenseMap<CachedHashStringRef, size_t>> map(numShards);
2537 size_t shift = 32 - countTrailingZeros(numShards);
25002538
25012539 // Instantiate GdbSymbols while uniqufying them by name.
2502 std::vector<std::vector<GdbSymbol>> Symbols(NumShards);
2503 parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
2504 uint32_t I = 0;
2505 for (ArrayRef<NameAttrEntry> Entries : NameAttrs) {
2506 for (const NameAttrEntry &Ent : Entries) {
2507 size_t ShardId = Ent.Name.hash() >> Shift;
2508 if ((ShardId & (Concurrency - 1)) != ThreadId)
2540 std::vector<std::vector<GdbSymbol>> symbols(numShards);
2541 parallelForEachN(0, concurrency, [&](size_t threadId) {
2542 uint32_t i = 0;
2543 for (ArrayRef<NameAttrEntry> entries : nameAttrs) {
2544 for (const NameAttrEntry &ent : entries) {
2545 size_t shardId = ent.name.hash() >> shift;
2546 if ((shardId & (concurrency - 1)) != threadId)
25092547 continue;
25102548
2511 uint32_t V = Ent.CuIndexAndAttrs + CuIdxs[I];
2512 size_t &Idx = Map[ShardId][Ent.Name];
2513 if (Idx) {
2514 Symbols[ShardId][Idx - 1].CuVector.push_back(V);
2549 uint32_t v = ent.cuIndexAndAttrs + cuIdxs[i];
2550 size_t &idx = map[shardId][ent.name];
2551 if (idx) {
2552 symbols[shardId][idx - 1].cuVector.push_back(v);
25152553 continue;
25162554 }
25172555
2518 Idx = Symbols[ShardId].size() + 1;
2519 Symbols[ShardId].push_back({Ent.Name, {V}, 0, 0});
2556 idx = symbols[shardId].size() + 1;
2557 symbols[shardId].push_back({ent.name, {v}, 0, 0});
25202558 }
2521 ++I;
2559 ++i;
25222560 }
25232561 });
25242562
2525 size_t NumSymbols = 0;
2526 for (ArrayRef<GdbSymbol> V : Symbols)
2527 NumSymbols += V.size();
2563 size_t numSymbols = 0;
2564 for (ArrayRef<GdbSymbol> v : symbols)
2565 numSymbols += v.size();
25282566
25292567 // The return type is a flattened vector, so we'll copy each vector
25302568 // contents to Ret.
2531 std::vector<GdbSymbol> Ret;
2532 Ret.reserve(NumSymbols);
2533 for (std::vector<GdbSymbol> &Vec : Symbols)
2534 for (GdbSymbol &Sym : Vec)
2535 Ret.push_back(std::move(Sym));
2569 std::vector<GdbSymbol> ret;
2570 ret.reserve(numSymbols);
2571 for (std::vector<GdbSymbol> &vec : symbols)
2572 for (GdbSymbol &sym : vec)
2573 ret.push_back(std::move(sym));
25362574
25372575 // CU vectors and symbol names are adjacent in the output file.
25382576 // We can compute their offsets in the output file now.
2539 size_t Off = 0;
2540 for (GdbSymbol &Sym : Ret) {
2541 Sym.CuVectorOff = Off;
2542 Off += (Sym.CuVector.size() + 1) * 4;
2577 size_t off = 0;
2578 for (GdbSymbol &sym : ret) {
2579 sym.cuVectorOff = off;
2580 off += (sym.cuVector.size() + 1) * 4;
25432581 }
2544 for (GdbSymbol &Sym : Ret) {
2545 Sym.NameOff = Off;
2546 Off += Sym.Name.size() + 1;
2582 for (GdbSymbol &sym : ret) {
2583 sym.nameOff = off;
2584 off += sym.name.size() + 1;
25472585 }
25482586
2549 return Ret;
2587 return ret;
25502588}
25512589
25522590// Returns a newly-created .gdb_index section.
25532591template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
2554 std::vector<InputSection *> Sections = getDebugInfoSections();
2592 std::vector<InputSection *> sections = getDebugInfoSections();
25552593
25562594 // .debug_gnu_pub{names,types} are useless in executables.
25572595 // They are present in input object files solely for creating
25582596 // a .gdb_index. So we can remove them from the output.
2559 for (InputSectionBase *S : InputSections)
2560 if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes")
2561 S->Live = false;
2562
2563 std::vector<GdbChunk> Chunks(Sections.size());
2564 std::vector<std::vector<NameAttrEntry>> NameAttrs(Sections.size());
2565
2566 parallelForEachN(0, Sections.size(), [&](size_t I) {
2567 ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>();
2568 DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(File));
2569
2570 Chunks[I].Sec = Sections[I];
2571 Chunks[I].CompilationUnits = readCuList(Dwarf);
2572 Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]);
2573 NameAttrs[I] = readPubNamesAndTypes<ELFT>(
2574 static_cast<const LLDDwarfObj<ELFT> &>(Dwarf.getDWARFObj()),
2575 Chunks[I].CompilationUnits);
2597 for (InputSectionBase *s : inputSections)
2598 if (s->name == ".debug_gnu_pubnames" || s->name == ".debug_gnu_pubtypes")
2599 s->markDead();
2600
2601 std::vector<GdbChunk> chunks(sections.size());
2602 std::vector<std::vector<NameAttrEntry>> nameAttrs(sections.size());
2603
2604 parallelForEachN(0, sections.size(), [&](size_t i) {
2605 ObjFile<ELFT> *file = sections[i]->getFile<ELFT>();
2606 DWARFContext dwarf(make_unique<LLDDwarfObj<ELFT>>(file));
2607
2608 chunks[i].sec = sections[i];
2609 chunks[i].compilationUnits = readCuList(dwarf);
2610 chunks[i].addressAreas = readAddressAreas(dwarf, sections[i]);
2611 nameAttrs[i] = readPubNamesAndTypes<ELFT>(
2612 static_cast<const LLDDwarfObj<ELFT> &>(dwarf.getDWARFObj()),
2613 chunks[i].compilationUnits);
25762614 });
25772615
2578 auto *Ret = make<GdbIndexSection>();
2579 Ret->Chunks = std::move(Chunks);
2580 Ret->Symbols = createSymbols(NameAttrs, Ret->Chunks);
2581 Ret->initOutputSize();
2582 return Ret;
2616 auto *ret = make<GdbIndexSection>();
2617 ret->chunks = std::move(chunks);
2618 ret->symbols = createSymbols(nameAttrs, ret->chunks);
2619 ret->initOutputSize();
2620 return ret;
25832621}
25842622
2585void GdbIndexSection::writeTo(uint8_t *Buf) {
2623void GdbIndexSection::writeTo(uint8_t *buf) {
25862624 // Write the header.
2587 auto *Hdr = reinterpret_cast<GdbIndexHeader *>(Buf);
2588 uint8_t *Start = Buf;
2589 Hdr->Version = 7;
2590 Buf += sizeof(*Hdr);
2625 auto *hdr = reinterpret_cast<GdbIndexHeader *>(buf);
2626 uint8_t *start = buf;
2627 hdr->version = 7;
2628 buf += sizeof(*hdr);
25912629
25922630 // Write the CU list.
2593 Hdr->CuListOff = Buf - Start;
2594 for (GdbChunk &Chunk : Chunks) {
2595 for (CuEntry &Cu : Chunk.CompilationUnits) {
2596 write64le(Buf, Chunk.Sec->OutSecOff + Cu.CuOffset);
2597 write64le(Buf + 8, Cu.CuLength);
2598 Buf += 16;
2631 hdr->cuListOff = buf - start;
2632 for (GdbChunk &chunk : chunks) {
2633 for (CuEntry &cu : chunk.compilationUnits) {
2634 write64le(buf, chunk.sec->outSecOff + cu.cuOffset);
2635 write64le(buf + 8, cu.cuLength);
2636 buf += 16;
25992637 }
26002638 }
26012639
26022640 // Write the address area.
2603 Hdr->CuTypesOff = Buf - Start;
2604 Hdr->AddressAreaOff = Buf - Start;
2605 uint32_t CuOff = 0;
2606 for (GdbChunk &Chunk : Chunks) {
2607 for (AddressEntry &E : Chunk.AddressAreas) {
2608 uint64_t BaseAddr = E.Section->getVA(0);
2609 write64le(Buf, BaseAddr + E.LowAddress);
2610 write64le(Buf + 8, BaseAddr + E.HighAddress);
2611 write32le(Buf + 16, E.CuIndex + CuOff);
2612 Buf += 20;
2641 hdr->cuTypesOff = buf - start;
2642 hdr->addressAreaOff = buf - start;
2643 uint32_t cuOff = 0;
2644 for (GdbChunk &chunk : chunks) {
2645 for (AddressEntry &e : chunk.addressAreas) {
2646 uint64_t baseAddr = e.section->getVA(0);
2647 write64le(buf, baseAddr + e.lowAddress);
2648 write64le(buf + 8, baseAddr + e.highAddress);
2649 write32le(buf + 16, e.cuIndex + cuOff);
2650 buf += 20;
26132651 }
2614 CuOff += Chunk.CompilationUnits.size();
2652 cuOff += chunk.compilationUnits.size();
26152653 }
26162654
26172655 // Write the on-disk open-addressing hash table containing symbols.
2618 Hdr->SymtabOff = Buf - Start;
2619 size_t SymtabSize = computeSymtabSize();
2620 uint32_t Mask = SymtabSize - 1;
2656 hdr->symtabOff = buf - start;
2657 size_t symtabSize = computeSymtabSize();
2658 uint32_t mask = symtabSize - 1;
26212659
2622 for (GdbSymbol &Sym : Symbols) {
2623 uint32_t H = Sym.Name.hash();
2624 uint32_t I = H & Mask;
2625 uint32_t Step = ((H * 17) & Mask) | 1;
2660 for (GdbSymbol &sym : symbols) {
2661 uint32_t h = sym.name.hash();
2662 uint32_t i = h & mask;
2663 uint32_t step = ((h * 17) & mask) | 1;
26262664
2627 while (read32le(Buf + I * 8))
2628 I = (I + Step) & Mask;
2665 while (read32le(buf + i * 8))
2666 i = (i + step) & mask;
26292667
2630 write32le(Buf + I * 8, Sym.NameOff);
2631 write32le(Buf + I * 8 + 4, Sym.CuVectorOff);
2668 write32le(buf + i * 8, sym.nameOff);
2669 write32le(buf + i * 8 + 4, sym.cuVectorOff);
26322670 }
26332671
2634 Buf += SymtabSize * 8;
2672 buf += symtabSize * 8;
26352673
26362674 // Write the string pool.
2637 Hdr->ConstantPoolOff = Buf - Start;
2638 parallelForEach(Symbols, [&](GdbSymbol &Sym) {
2639 memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size());
2675 hdr->constantPoolOff = buf - start;
2676 parallelForEach(symbols, [&](GdbSymbol &sym) {
2677 memcpy(buf + sym.nameOff, sym.name.data(), sym.name.size());
26402678 });
26412679
26422680 // Write the CU vectors.
2643 for (GdbSymbol &Sym : Symbols) {
2644 write32le(Buf, Sym.CuVector.size());
2645 Buf += 4;
2646 for (uint32_t Val : Sym.CuVector) {
2647 write32le(Buf, Val);
2648 Buf += 4;
2681 for (GdbSymbol &sym : symbols) {
2682 write32le(buf, sym.cuVector.size());
2683 buf += 4;
2684 for (uint32_t val : sym.cuVector) {
2685 write32le(buf, val);
2686 buf += 4;
26492687 }
26502688 }
26512689}
26522690
2653bool GdbIndexSection::empty() const { return Chunks.empty(); }
2691bool GdbIndexSection::isNeeded() const { return !chunks.empty(); }
26542692
26552693EhFrameHeader::EhFrameHeader()
26562694 : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {}
26572695
2696void EhFrameHeader::writeTo(uint8_t *buf) {
2697 // Unlike most sections, the EhFrameHeader section is written while writing
2698 // another section, namely EhFrameSection, which calls the write() function
2699 // below from its writeTo() function. This is necessary because the contents
2700 // of EhFrameHeader depend on the relocated contents of EhFrameSection and we
2701 // don't know which order the sections will be written in.
2702}
2703
26582704// .eh_frame_hdr contains a binary search table of pointers to FDEs.
26592705// Each entry of the search table consists of two values,
26602706// the starting PC from where FDEs covers, and the FDE's address.
26612707// It is sorted by PC.
2662void EhFrameHeader::writeTo(uint8_t *Buf) {
2663 typedef EhFrameSection::FdeData FdeData;
2708void EhFrameHeader::write() {
2709 uint8_t *buf = Out::bufferStart + getParent()->offset + outSecOff;
2710 using FdeData = EhFrameSection::FdeData;
26642711
2665 std::vector<FdeData> Fdes = In.EhFrame->getFdeData();
2712 std::vector<FdeData> fdes = getPartition().ehFrame->getFdeData();
26662713
2667 Buf[0] = 1;
2668 Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
2669 Buf[2] = DW_EH_PE_udata4;
2670 Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
2671 write32(Buf + 4, In.EhFrame->getParent()->Addr - this->getVA() - 4);
2672 write32(Buf + 8, Fdes.size());
2673 Buf += 12;
2714 buf[0] = 1;
2715 buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
2716 buf[2] = DW_EH_PE_udata4;
2717 buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
2718 write32(buf + 4,
2719 getPartition().ehFrame->getParent()->addr - this->getVA() - 4);
2720 write32(buf + 8, fdes.size());
2721 buf += 12;
26742722
2675 for (FdeData &Fde : Fdes) {
2676 write32(Buf, Fde.PcRel);
2677 write32(Buf + 4, Fde.FdeVARel);
2678 Buf += 8;
2723 for (FdeData &fde : fdes) {
2724 write32(buf, fde.pcRel);
2725 write32(buf + 4, fde.fdeVARel);
2726 buf += 8;
26792727 }
26802728}
26812729
26822730size_t EhFrameHeader::getSize() const {
26832731 // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
2684 return 12 + In.EhFrame->NumFdes * 8;
2732 return 12 + getPartition().ehFrame->numFdes * 8;
26852733}
26862734
2687bool EhFrameHeader::empty() const { return In.EhFrame->empty(); }
2735bool EhFrameHeader::isNeeded() const {
2736 return isLive() && getPartition().ehFrame->isNeeded();
2737}
26882738
26892739VersionDefinitionSection::VersionDefinitionSection()
26902740 : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),
26912741 ".gnu.version_d") {}
26922742
2693static StringRef getFileDefName() {
2694 if (!Config->SoName.empty())
2695 return Config->SoName;
2696 return Config->OutputFile;
2743StringRef VersionDefinitionSection::getFileDefName() {
2744 if (!getPartition().name.empty())
2745 return getPartition().name;
2746 if (!config->soName.empty())
2747 return config->soName;
2748 return config->outputFile;
26972749}
26982750
26992751void VersionDefinitionSection::finalizeContents() {
2700 FileDefNameOff = In.DynStrTab->addString(getFileDefName());
2701 for (VersionDefinition &V : Config->VersionDefinitions)
2702 V.NameOff = In.DynStrTab->addString(V.Name);
2752 fileDefNameOff = getPartition().dynStrTab->addString(getFileDefName());
2753 for (VersionDefinition &v : config->versionDefinitions)
2754 verDefNameOffs.push_back(getPartition().dynStrTab->addString(v.name));
27032755
2704 if (OutputSection *Sec = In.DynStrTab->getParent())
2705 getParent()->Link = Sec->SectionIndex;
2756 if (OutputSection *sec = getPartition().dynStrTab->getParent())
2757 getParent()->link = sec->sectionIndex;
27062758
27072759 // sh_info should be set to the number of definitions. This fact is missed in
27082760 // documentation, but confirmed by binutils community:
27092761 // https://sourceware.org/ml/binutils/2014-11/msg00355.html
2710 getParent()->Info = getVerDefNum();
2762 getParent()->info = getVerDefNum();
27112763}
27122764
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;
2765void VersionDefinitionSection::writeOne(uint8_t *buf, uint32_t index,
2766 StringRef name, size_t nameOff) {
2767 uint16_t flags = index == 1 ? VER_FLG_BASE : 0;
27162768
27172769 // 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
2770 write16(buf, 1); // vd_version
2771 write16(buf + 2, flags); // vd_flags
2772 write16(buf + 4, index); // vd_ndx
2773 write16(buf + 6, 1); // vd_cnt
2774 write32(buf + 8, hashSysV(name)); // vd_hash
2775 write32(buf + 12, 20); // vd_aux
2776 write32(buf + 16, 28); // vd_next
27252777
27262778 // Write a veraux.
2727 write32(Buf + 20, NameOff); // vda_name
2728 write32(Buf + 24, 0); // vda_next
2779 write32(buf + 20, nameOff); // vda_name
2780 write32(buf + 24, 0); // vda_next
27292781}
27302782
2731void VersionDefinitionSection::writeTo(uint8_t *Buf) {
2732 writeOne(Buf, 1, getFileDefName(), FileDefNameOff);
2783void VersionDefinitionSection::writeTo(uint8_t *buf) {
2784 writeOne(buf, 1, getFileDefName(), fileDefNameOff);
27332785
2734 for (VersionDefinition &V : Config->VersionDefinitions) {
2735 Buf += EntrySize;
2736 writeOne(Buf, V.Id, V.Name, V.NameOff);
2786 auto nameOffIt = verDefNameOffs.begin();
2787 for (VersionDefinition &v : config->versionDefinitions) {
2788 buf += EntrySize;
2789 writeOne(buf, v.id, v.name, *nameOffIt++);
27372790 }
27382791
27392792 // Need to terminate the last version definition.
2740 write32(Buf + 16, 0); // vd_next
2793 write32(buf + 16, 0); // vd_next
27412794}
27422795
27432796size_t VersionDefinitionSection::getSize() const {
......@@ -2745,160 +2798,161 @@ size_t VersionDefinitionSection::getSize() const {
27452798}
27462799
27472800// .gnu.version is a table where each entry is 2 byte long.
2748template <class ELFT>
2749VersionTableSection<ELFT>::VersionTableSection()
2801VersionTableSection::VersionTableSection()
27502802 : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
27512803 ".gnu.version") {
2752 this->Entsize = 2;
2804 this->entsize = 2;
27532805}
27542806
2755template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
2807void VersionTableSection::finalizeContents() {
27562808 // At the moment of june 2016 GNU docs does not mention that sh_link field
27572809 // should be set, but Sun docs do. Also readelf relies on this field.
2758 getParent()->Link = In.DynSymTab->getParent()->SectionIndex;
2810 getParent()->link = getPartition().dynSymTab->getParent()->sectionIndex;
27592811}
27602812
2761template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {
2762 return (In.DynSymTab->getSymbols().size() + 1) * 2;
2813size_t VersionTableSection::getSize() const {
2814 return (getPartition().dynSymTab->getSymbols().size() + 1) * 2;
27632815}
27642816
2765template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
2766 Buf += 2;
2767 for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
2768 write16(Buf, S.Sym->VersionId);
2769 Buf += 2;
2817void VersionTableSection::writeTo(uint8_t *buf) {
2818 buf += 2;
2819 for (const SymbolTableEntry &s : getPartition().dynSymTab->getSymbols()) {
2820 write16(buf, s.sym->versionId);
2821 buf += 2;
27702822 }
27712823}
27722824
2773template <class ELFT> bool VersionTableSection<ELFT>::empty() const {
2774 return !In.VerDef && InX<ELFT>::VerNeed->empty();
2825bool VersionTableSection::isNeeded() const {
2826 return getPartition().verDef || getPartition().verNeed->isNeeded();
2827}
2828
2829void elf::addVerneed(Symbol *ss) {
2830 auto &file = cast<SharedFile>(*ss->file);
2831 if (ss->verdefIndex == VER_NDX_GLOBAL) {
2832 ss->versionId = VER_NDX_GLOBAL;
2833 return;
2834 }
2835
2836 if (file.vernauxs.empty())
2837 file.vernauxs.resize(file.verdefs.size());
2838
2839 // Select a version identifier for the vernaux data structure, if we haven't
2840 // already allocated one. The verdef identifiers cover the range
2841 // [1..getVerDefNum()]; this causes the vernaux identifiers to start from
2842 // getVerDefNum()+1.
2843 if (file.vernauxs[ss->verdefIndex] == 0)
2844 file.vernauxs[ss->verdefIndex] = ++SharedFile::vernauxNum + getVerDefNum();
2845
2846 ss->versionId = file.vernauxs[ss->verdefIndex];
27752847}
27762848
27772849template <class ELFT>
27782850VersionNeedSection<ELFT>::VersionNeedSection()
27792851 : SyntheticSection(SHF_ALLOC, SHT_GNU_verneed, sizeof(uint32_t),
2780 ".gnu.version_r") {
2781 // Identifiers in verneed section start at 2 because 0 and 1 are reserved
2782 // for VER_NDX_LOCAL and VER_NDX_GLOBAL.
2783 // First identifiers are reserved by verdef section if it exist.
2784 NextIndex = getVerDefNum() + 1;
2785}
2852 ".gnu.version_r") {}
27862853
2787template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
2788 auto &File = cast<SharedFile<ELFT>>(*SS->File);
2789 if (SS->VerdefIndex == VER_NDX_GLOBAL) {
2790 SS->VersionId = VER_NDX_GLOBAL;
2791 return;
2854template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
2855 for (SharedFile *f : sharedFiles) {
2856 if (f->vernauxs.empty())
2857 continue;
2858 verneeds.emplace_back();
2859 Verneed &vn = verneeds.back();
2860 vn.nameStrTab = getPartition().dynStrTab->addString(f->soName);
2861 for (unsigned i = 0; i != f->vernauxs.size(); ++i) {
2862 if (f->vernauxs[i] == 0)
2863 continue;
2864 auto *verdef =
2865 reinterpret_cast<const typename ELFT::Verdef *>(f->verdefs[i]);
2866 vn.vernauxs.push_back(
2867 {verdef->vd_hash, f->vernauxs[i],
2868 getPartition().dynStrTab->addString(f->getStringTable().data() +
2869 verdef->getAux()->vda_name)});
2870 }
27922871 }
27932872
2794 // If we don't already know that we need an Elf_Verneed for this DSO, prepare
2795 // to create one by adding it to our needed list and creating a dynstr entry
2796 // for the soname.
2797 if (File.VerdefMap.empty())
2798 Needed.push_back({&File, In.DynStrTab->addString(File.SoName)});
2799 const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex];
2800 typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver];
2801
2802 // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef,
2803 // prepare to create one by allocating a version identifier and creating a
2804 // dynstr entry for the version name.
2805 if (NV.Index == 0) {
2806 NV.StrTab = In.DynStrTab->addString(File.getStringTable().data() +
2807 Ver->getAux()->vda_name);
2808 NV.Index = NextIndex++;
2809 }
2810 SS->VersionId = NV.Index;
2873 if (OutputSection *sec = getPartition().dynStrTab->getParent())
2874 getParent()->link = sec->sectionIndex;
2875 getParent()->info = verneeds.size();
28112876}
28122877
2813template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
2878template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *buf) {
28142879 // The Elf_Verneeds need to appear first, followed by the Elf_Vernauxs.
2815 auto *Verneed = reinterpret_cast<Elf_Verneed *>(Buf);
2816 auto *Vernaux = reinterpret_cast<Elf_Vernaux *>(Verneed + Needed.size());
2880 auto *verneed = reinterpret_cast<Elf_Verneed *>(buf);
2881 auto *vernaux = reinterpret_cast<Elf_Vernaux *>(verneed + verneeds.size());
28172882
2818 for (std::pair<SharedFile<ELFT> *, size_t> &P : Needed) {
2883 for (auto &vn : verneeds) {
28192884 // Create an Elf_Verneed for this DSO.
2820 Verneed->vn_version = 1;
2821 Verneed->vn_cnt = P.first->VerdefMap.size();
2822 Verneed->vn_file = P.second;
2823 Verneed->vn_aux =
2824 reinterpret_cast<char *>(Vernaux) - reinterpret_cast<char *>(Verneed);
2825 Verneed->vn_next = sizeof(Elf_Verneed);
2826 ++Verneed;
2827
2828 // Create the Elf_Vernauxs for this Elf_Verneed. The loop iterates over
2829 // VerdefMap, which will only contain references to needed version
2830 // definitions. Each Elf_Vernaux is based on the information contained in
2831 // the Elf_Verdef in the source DSO. This loop iterates over a std::map of
2832 // pointers, but is deterministic because the pointers refer to Elf_Verdef
2833 // data structures within a single input file.
2834 for (auto &NV : P.first->VerdefMap) {
2835 Vernaux->vna_hash = NV.first->vd_hash;
2836 Vernaux->vna_flags = 0;
2837 Vernaux->vna_other = NV.second.Index;
2838 Vernaux->vna_name = NV.second.StrTab;
2839 Vernaux->vna_next = sizeof(Elf_Vernaux);
2840 ++Vernaux;
2885 verneed->vn_version = 1;
2886 verneed->vn_cnt = vn.vernauxs.size();
2887 verneed->vn_file = vn.nameStrTab;
2888 verneed->vn_aux =
2889 reinterpret_cast<char *>(vernaux) - reinterpret_cast<char *>(verneed);
2890 verneed->vn_next = sizeof(Elf_Verneed);
2891 ++verneed;
2892
2893 // Create the Elf_Vernauxs for this Elf_Verneed.
2894 for (auto &vna : vn.vernauxs) {
2895 vernaux->vna_hash = vna.hash;
2896 vernaux->vna_flags = 0;
2897 vernaux->vna_other = vna.verneedIndex;
2898 vernaux->vna_name = vna.nameStrTab;
2899 vernaux->vna_next = sizeof(Elf_Vernaux);
2900 ++vernaux;
28412901 }
28422902
2843 Vernaux[-1].vna_next = 0;
2903 vernaux[-1].vna_next = 0;
28442904 }
2845 Verneed[-1].vn_next = 0;
2846}
2847
2848template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
2849 if (OutputSection *Sec = In.DynStrTab->getParent())
2850 getParent()->Link = Sec->SectionIndex;
2851 getParent()->Info = Needed.size();
2905 verneed[-1].vn_next = 0;
28522906}
28532907
28542908template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
2855 unsigned Size = Needed.size() * sizeof(Elf_Verneed);
2856 for (const std::pair<SharedFile<ELFT> *, size_t> &P : Needed)
2857 Size += P.first->VerdefMap.size() * sizeof(Elf_Vernaux);
2858 return Size;
2909 return verneeds.size() * sizeof(Elf_Verneed) +
2910 SharedFile::vernauxNum * sizeof(Elf_Vernaux);
28592911}
28602912
2861template <class ELFT> bool VersionNeedSection<ELFT>::empty() const {
2862 return getNeedNum() == 0;
2913template <class ELFT> bool VersionNeedSection<ELFT>::isNeeded() const {
2914 return SharedFile::vernauxNum != 0;
28632915}
28642916
2865void MergeSyntheticSection::addSection(MergeInputSection *MS) {
2866 MS->Parent = this;
2867 Sections.push_back(MS);
2917void MergeSyntheticSection::addSection(MergeInputSection *ms) {
2918 ms->parent = this;
2919 sections.push_back(ms);
2920 assert(alignment == ms->alignment || !(ms->flags & SHF_STRINGS));
2921 alignment = std::max(alignment, ms->alignment);
28682922}
28692923
2870MergeTailSection::MergeTailSection(StringRef Name, uint32_t Type,
2871 uint64_t Flags, uint32_t Alignment)
2872 : MergeSyntheticSection(Name, Type, Flags, Alignment),
2873 Builder(StringTableBuilder::RAW, Alignment) {}
2924MergeTailSection::MergeTailSection(StringRef name, uint32_t type,
2925 uint64_t flags, uint32_t alignment)
2926 : MergeSyntheticSection(name, type, flags, alignment),
2927 builder(StringTableBuilder::RAW, alignment) {}
28742928
2875size_t MergeTailSection::getSize() const { return Builder.getSize(); }
2929size_t MergeTailSection::getSize() const { return builder.getSize(); }
28762930
2877void MergeTailSection::writeTo(uint8_t *Buf) { Builder.write(Buf); }
2931void MergeTailSection::writeTo(uint8_t *buf) { builder.write(buf); }
28782932
28792933void MergeTailSection::finalizeContents() {
28802934 // Add all string pieces to the string table builder to create section
28812935 // contents.
2882 for (MergeInputSection *Sec : Sections)
2883 for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
2884 if (Sec->Pieces[I].Live)
2885 Builder.add(Sec->getData(I));
2936 for (MergeInputSection *sec : sections)
2937 for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
2938 if (sec->pieces[i].live)
2939 builder.add(sec->getData(i));
28862940
28872941 // Fix the string table content. After this, the contents will never change.
2888 Builder.finalize();
2942 builder.finalize();
28892943
28902944 // finalize() fixed tail-optimized strings, so we can now get
28912945 // offsets of strings. Get an offset for each string and save it
2892 // to a corresponding StringPiece for easy access.
2893 for (MergeInputSection *Sec : Sections)
2894 for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
2895 if (Sec->Pieces[I].Live)
2896 Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I));
2946 // to a corresponding SectionPiece for easy access.
2947 for (MergeInputSection *sec : sections)
2948 for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
2949 if (sec->pieces[i].live)
2950 sec->pieces[i].outputOff = builder.getOffset(sec->getData(i));
28972951}
28982952
2899void MergeNoTailSection::writeTo(uint8_t *Buf) {
2900 for (size_t I = 0; I < NumShards; ++I)
2901 Shards[I].write(Buf + ShardOffsets[I]);
2953void MergeNoTailSection::writeTo(uint8_t *buf) {
2954 for (size_t i = 0; i < numShards; ++i)
2955 shards[i].write(buf + shardOffsets[i]);
29022956}
29032957
29042958// This function is very hot (i.e. it can take several seconds to finish)
......@@ -2911,66 +2965,68 @@ void MergeNoTailSection::writeTo(uint8_t *Buf) {
29112965// We do it in parallel.
29122966void MergeNoTailSection::finalizeContents() {
29132967 // Initializes string table builders.
2914 for (size_t I = 0; I < NumShards; ++I)
2915 Shards.emplace_back(StringTableBuilder::RAW, Alignment);
2968 for (size_t i = 0; i < numShards; ++i)
2969 shards.emplace_back(StringTableBuilder::RAW, alignment);
29162970
29172971 // Concurrency level. Must be a power of 2 to avoid expensive modulo
29182972 // operations in the following tight loop.
2919 size_t Concurrency = 1;
2920 if (ThreadsEnabled)
2921 Concurrency =
2922 std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards);
2973 size_t concurrency = 1;
2974 if (threadsEnabled)
2975 concurrency =
2976 std::min<size_t>(PowerOf2Floor(hardware_concurrency()), numShards);
29232977
29242978 // Add section pieces to the builders.
2925 parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
2926 for (MergeInputSection *Sec : Sections) {
2927 for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
2928 size_t ShardId = getShardId(Sec->Pieces[I].Hash);
2929 if ((ShardId & (Concurrency - 1)) == ThreadId && Sec->Pieces[I].Live)
2930 Sec->Pieces[I].OutputOff = Shards[ShardId].add(Sec->getData(I));
2979 parallelForEachN(0, concurrency, [&](size_t threadId) {
2980 for (MergeInputSection *sec : sections) {
2981 for (size_t i = 0, e = sec->pieces.size(); i != e; ++i) {
2982 if (!sec->pieces[i].live)
2983 continue;
2984 size_t shardId = getShardId(sec->pieces[i].hash);
2985 if ((shardId & (concurrency - 1)) == threadId)
2986 sec->pieces[i].outputOff = shards[shardId].add(sec->getData(i));
29312987 }
29322988 }
29332989 });
29342990
29352991 // Compute an in-section offset for each shard.
2936 size_t Off = 0;
2937 for (size_t I = 0; I < NumShards; ++I) {
2938 Shards[I].finalizeInOrder();
2939 if (Shards[I].getSize() > 0)
2940 Off = alignTo(Off, Alignment);
2941 ShardOffsets[I] = Off;
2942 Off += Shards[I].getSize();
2992 size_t off = 0;
2993 for (size_t i = 0; i < numShards; ++i) {
2994 shards[i].finalizeInOrder();
2995 if (shards[i].getSize() > 0)
2996 off = alignTo(off, alignment);
2997 shardOffsets[i] = off;
2998 off += shards[i].getSize();
29432999 }
2944 Size = Off;
3000 size = off;
29453001
29463002 // So far, section pieces have offsets from beginning of shards, but
29473003 // we want offsets from beginning of the whole section. Fix them.
2948 parallelForEach(Sections, [&](MergeInputSection *Sec) {
2949 for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
2950 if (Sec->Pieces[I].Live)
2951 Sec->Pieces[I].OutputOff +=
2952 ShardOffsets[getShardId(Sec->Pieces[I].Hash)];
3004 parallelForEach(sections, [&](MergeInputSection *sec) {
3005 for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
3006 if (sec->pieces[i].live)
3007 sec->pieces[i].outputOff +=
3008 shardOffsets[getShardId(sec->pieces[i].hash)];
29533009 });
29543010}
29553011
2956static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
2957 uint32_t Type,
2958 uint64_t Flags,
2959 uint32_t Alignment) {
2960 bool ShouldTailMerge = (Flags & SHF_STRINGS) && Config->Optimize >= 2;
2961 if (ShouldTailMerge)
2962 return make<MergeTailSection>(Name, Type, Flags, Alignment);
2963 return make<MergeNoTailSection>(Name, Type, Flags, Alignment);
3012static MergeSyntheticSection *createMergeSynthetic(StringRef name,
3013 uint32_t type,
3014 uint64_t flags,
3015 uint32_t alignment) {
3016 bool shouldTailMerge = (flags & SHF_STRINGS) && config->optimize >= 2;
3017 if (shouldTailMerge)
3018 return make<MergeTailSection>(name, type, flags, alignment);
3019 return make<MergeNoTailSection>(name, type, flags, alignment);
29643020}
29653021
29663022template <class ELFT> void elf::splitSections() {
29673023 // splitIntoPieces needs to be called on each MergeInputSection
29683024 // before calling finalizeContents().
2969 parallelForEach(InputSections, [](InputSectionBase *Sec) {
2970 if (auto *S = dyn_cast<MergeInputSection>(Sec))
2971 S->splitIntoPieces();
2972 else if (auto *Eh = dyn_cast<EhInputSection>(Sec))
2973 Eh->split<ELFT>();
3025 parallelForEach(inputSections, [](InputSectionBase *sec) {
3026 if (auto *s = dyn_cast<MergeInputSection>(sec))
3027 s->splitIntoPieces();
3028 else if (auto *eh = dyn_cast<EhInputSection>(sec))
3029 eh->split<ELFT>();
29743030 });
29753031}
29763032
......@@ -2982,23 +3038,22 @@ template <class ELFT> void elf::splitSections() {
29823038// that it replaces. It then finalizes each synthetic section in order
29833039// to compute an output offset for each piece of each input section.
29843040void elf::mergeSections() {
2985 std::vector<MergeSyntheticSection *> MergeSections;
2986 for (InputSectionBase *&S : InputSections) {
2987 MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
2988 if (!MS)
3041 std::vector<MergeSyntheticSection *> mergeSections;
3042 for (InputSectionBase *&s : inputSections) {
3043 MergeInputSection *ms = dyn_cast<MergeInputSection>(s);
3044 if (!ms)
29893045 continue;
29903046
29913047 // We do not want to handle sections that are not alive, so just remove
29923048 // them instead of trying to merge.
2993 if (!MS->Live) {
2994 S = nullptr;
3049 if (!ms->isLive()) {
3050 s = nullptr;
29953051 continue;
29963052 }
29973053
2998 StringRef OutsecName = getOutputSectionName(MS);
2999 uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize);
3054 StringRef outsecName = getOutputSectionName(ms);
30003055
3001 auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
3056 auto i = llvm::find_if(mergeSections, [=](MergeSyntheticSection *sec) {
30023057 // While we could create a single synthetic section for two different
30033058 // values of Entsize, it is better to take Entsize into consideration.
30043059 //
......@@ -3007,98 +3062,285 @@ void elf::mergeSections() {
30073062 //
30083063 // Using Entsize in here also allows us to propagate it to the synthetic
30093064 // section.
3010 return Sec->Name == OutsecName && Sec->Flags == MS->Flags &&
3011 Sec->Entsize == MS->Entsize && Sec->Alignment == Alignment;
3065 //
3066 // SHF_STRINGS section with different alignments should not be merged.
3067 return sec->name == outsecName && sec->flags == ms->flags &&
3068 sec->entsize == ms->entsize &&
3069 (sec->alignment == ms->alignment || !(sec->flags & SHF_STRINGS));
30123070 });
3013 if (I == MergeSections.end()) {
3014 MergeSyntheticSection *Syn =
3015 createMergeSynthetic(OutsecName, MS->Type, MS->Flags, Alignment);
3016 MergeSections.push_back(Syn);
3017 I = std::prev(MergeSections.end());
3018 S = Syn;
3019 Syn->Entsize = MS->Entsize;
3071 if (i == mergeSections.end()) {
3072 MergeSyntheticSection *syn =
3073 createMergeSynthetic(outsecName, ms->type, ms->flags, ms->alignment);
3074 mergeSections.push_back(syn);
3075 i = std::prev(mergeSections.end());
3076 s = syn;
3077 syn->entsize = ms->entsize;
30203078 } else {
3021 S = nullptr;
3079 s = nullptr;
30223080 }
3023 (*I)->addSection(MS);
3081 (*i)->addSection(ms);
30243082 }
3025 for (auto *MS : MergeSections)
3026 MS->finalizeContents();
3083 for (auto *ms : mergeSections)
3084 ms->finalizeContents();
30273085
3028 std::vector<InputSectionBase *> &V = InputSections;
3029 V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
3086 std::vector<InputSectionBase *> &v = inputSections;
3087 v.erase(std::remove(v.begin(), v.end(), nullptr), v.end());
30303088}
30313089
30323090MipsRldMapSection::MipsRldMapSection()
3033 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
3091 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, config->wordsize,
30343092 ".rld_map") {}
30353093
3036ARMExidxSentinelSection::ARMExidxSentinelSection()
3094ARMExidxSyntheticSection::ARMExidxSyntheticSection()
30373095 : SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX,
3038 Config->Wordsize, ".ARM.exidx") {}
3039
3040// Write a terminating sentinel entry to the end of the .ARM.exidx table.
3041// This section will have been sorted last in the .ARM.exidx table.
3042// This table entry will have the form:
3043// | PREL31 upper bound of code that has exception tables | EXIDX_CANTUNWIND |
3044// The sentinel must have the PREL31 value of an address higher than any
3045// address described by any other table entry.
3046void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
3047 assert(Highest);
3048 uint64_t S = Highest->getVA(Highest->getSize());
3049 uint64_t P = getVA();
3050 Target->relocateOne(Buf, R_ARM_PREL31, S - P);
3051 write32le(Buf + 4, 1);
3052}
3053
3054// The sentinel has to be removed if there are no other .ARM.exidx entries.
3055bool ARMExidxSentinelSection::empty() const {
3056 for (InputSection *IS : getInputSections(getParent()))
3057 if (!isa<ARMExidxSentinelSection>(IS))
3096 config->wordsize, ".ARM.exidx") {}
3097
3098static InputSection *findExidxSection(InputSection *isec) {
3099 for (InputSection *d : isec->dependentSections)
3100 if (d->type == SHT_ARM_EXIDX)
3101 return d;
3102 return nullptr;
3103}
3104
3105bool ARMExidxSyntheticSection::addSection(InputSection *isec) {
3106 if (isec->type == SHT_ARM_EXIDX) {
3107 exidxSections.push_back(isec);
3108 return true;
3109 }
3110
3111 if ((isec->flags & SHF_ALLOC) && (isec->flags & SHF_EXECINSTR) &&
3112 isec->getSize() > 0) {
3113 executableSections.push_back(isec);
3114 if (empty && findExidxSection(isec))
3115 empty = false;
3116 return false;
3117 }
3118
3119 // FIXME: we do not output a relocation section when --emit-relocs is used
3120 // as we do not have relocation sections for linker generated table entries
3121 // and we would have to erase at a late stage relocations from merged entries.
3122 // Given that exception tables are already position independent and a binary
3123 // analyzer could derive the relocations we choose to erase the relocations.
3124 if (config->emitRelocs && isec->type == SHT_REL)
3125 if (InputSectionBase *ex = isec->getRelocatedSection())
3126 if (isa<InputSection>(ex) && ex->type == SHT_ARM_EXIDX)
3127 return true;
3128
3129 return false;
3130}
3131
3132// References to .ARM.Extab Sections have bit 31 clear and are not the
3133// special EXIDX_CANTUNWIND bit-pattern.
3134static bool isExtabRef(uint32_t unwind) {
3135 return (unwind & 0x80000000) == 0 && unwind != 0x1;
3136}
3137
3138// Return true if the .ARM.exidx section Cur can be merged into the .ARM.exidx
3139// section Prev, where Cur follows Prev in the table. This can be done if the
3140// unwinding instructions in Cur are identical to Prev. Linker generated
3141// EXIDX_CANTUNWIND entries are represented by nullptr as they do not have an
3142// InputSection.
3143static bool isDuplicateArmExidxSec(InputSection *prev, InputSection *cur) {
3144
3145 struct ExidxEntry {
3146 ulittle32_t fn;
3147 ulittle32_t unwind;
3148 };
3149 // Get the last table Entry from the previous .ARM.exidx section. If Prev is
3150 // nullptr then it will be a synthesized EXIDX_CANTUNWIND entry.
3151 ExidxEntry prevEntry = {ulittle32_t(0), ulittle32_t(1)};
3152 if (prev)
3153 prevEntry = prev->getDataAs<ExidxEntry>().back();
3154 if (isExtabRef(prevEntry.unwind))
3155 return false;
3156
3157 // We consider the unwind instructions of an .ARM.exidx table entry
3158 // a duplicate if the previous unwind instructions if:
3159 // - Both are the special EXIDX_CANTUNWIND.
3160 // - Both are the same inline unwind instructions.
3161 // We do not attempt to follow and check links into .ARM.extab tables as
3162 // consecutive identical entries are rare and the effort to check that they
3163 // are identical is high.
3164
3165 // If Cur is nullptr then this is synthesized EXIDX_CANTUNWIND entry.
3166 if (cur == nullptr)
3167 return prevEntry.unwind == 1;
3168
3169 for (const ExidxEntry entry : cur->getDataAs<ExidxEntry>())
3170 if (isExtabRef(entry.unwind) || entry.unwind != prevEntry.unwind)
30583171 return false;
3172
3173 // All table entries in this .ARM.exidx Section can be merged into the
3174 // previous Section.
30593175 return true;
30603176}
30613177
3062bool ARMExidxSentinelSection::classof(const SectionBase *D) {
3063 return D->kind() == InputSectionBase::Synthetic && D->Type == SHT_ARM_EXIDX;
3178// The .ARM.exidx table must be sorted in ascending order of the address of the
3179// functions the table describes. Optionally duplicate adjacent table entries
3180// can be removed. At the end of the function the ExecutableSections must be
3181// sorted in ascending order of address, Sentinel is set to the InputSection
3182// with the highest address and any InputSections that have mergeable
3183// .ARM.exidx table entries are removed from it.
3184void ARMExidxSyntheticSection::finalizeContents() {
3185 // Sort the executable sections that may or may not have associated
3186 // .ARM.exidx sections by order of ascending address. This requires the
3187 // relative positions of InputSections to be known.
3188 auto compareByFilePosition = [](const InputSection *a,
3189 const InputSection *b) {
3190 OutputSection *aOut = a->getParent();
3191 OutputSection *bOut = b->getParent();
3192
3193 if (aOut != bOut)
3194 return aOut->sectionIndex < bOut->sectionIndex;
3195 return a->outSecOff < b->outSecOff;
3196 };
3197 llvm::stable_sort(executableSections, compareByFilePosition);
3198 sentinel = executableSections.back();
3199 // Optionally merge adjacent duplicate entries.
3200 if (config->mergeArmExidx) {
3201 std::vector<InputSection *> selectedSections;
3202 selectedSections.reserve(executableSections.size());
3203 selectedSections.push_back(executableSections[0]);
3204 size_t prev = 0;
3205 for (size_t i = 1; i < executableSections.size(); ++i) {
3206 InputSection *ex1 = findExidxSection(executableSections[prev]);
3207 InputSection *ex2 = findExidxSection(executableSections[i]);
3208 if (!isDuplicateArmExidxSec(ex1, ex2)) {
3209 selectedSections.push_back(executableSections[i]);
3210 prev = i;
3211 }
3212 }
3213 executableSections = std::move(selectedSections);
3214 }
3215
3216 size_t offset = 0;
3217 size = 0;
3218 for (InputSection *isec : executableSections) {
3219 if (InputSection *d = findExidxSection(isec)) {
3220 d->outSecOff = offset;
3221 d->parent = getParent();
3222 offset += d->getSize();
3223 } else {
3224 offset += 8;
3225 }
3226 }
3227 // Size includes Sentinel.
3228 size = offset + 8;
3229}
3230
3231InputSection *ARMExidxSyntheticSection::getLinkOrderDep() const {
3232 return executableSections.front();
30643233}
30653234
3066ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
3235// To write the .ARM.exidx table from the ExecutableSections we have three cases
3236// 1.) The InputSection has a .ARM.exidx InputSection in its dependent sections.
3237// We write the .ARM.exidx section contents and apply its relocations.
3238// 2.) The InputSection does not have a dependent .ARM.exidx InputSection. We
3239// must write the contents of an EXIDX_CANTUNWIND directly. We use the
3240// start of the InputSection as the purpose of the linker generated
3241// section is to terminate the address range of the previous entry.
3242// 3.) A trailing EXIDX_CANTUNWIND sentinel section is required at the end of
3243// the table to terminate the address range of the final entry.
3244void ARMExidxSyntheticSection::writeTo(uint8_t *buf) {
3245
3246 const uint8_t cantUnwindData[8] = {0, 0, 0, 0, // PREL31 to target
3247 1, 0, 0, 0}; // EXIDX_CANTUNWIND
3248
3249 uint64_t offset = 0;
3250 for (InputSection *isec : executableSections) {
3251 assert(isec->getParent() != nullptr);
3252 if (InputSection *d = findExidxSection(isec)) {
3253 memcpy(buf + offset, d->data().data(), d->data().size());
3254 d->relocateAlloc(buf, buf + d->getSize());
3255 offset += d->getSize();
3256 } else {
3257 // A Linker generated CANTUNWIND section.
3258 memcpy(buf + offset, cantUnwindData, sizeof(cantUnwindData));
3259 uint64_t s = isec->getVA();
3260 uint64_t p = getVA() + offset;
3261 target->relocateOne(buf + offset, R_ARM_PREL31, s - p);
3262 offset += 8;
3263 }
3264 }
3265 // Write Sentinel.
3266 memcpy(buf + offset, cantUnwindData, sizeof(cantUnwindData));
3267 uint64_t s = sentinel->getVA(sentinel->getSize());
3268 uint64_t p = getVA() + offset;
3269 target->relocateOne(buf + offset, R_ARM_PREL31, s - p);
3270 assert(size == offset + 8);
3271}
3272
3273bool ARMExidxSyntheticSection::classof(const SectionBase *d) {
3274 return d->kind() == InputSectionBase::Synthetic && d->type == SHT_ARM_EXIDX;
3275}
3276
3277ThunkSection::ThunkSection(OutputSection *os, uint64_t off)
30673278 : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
3068 Config->Wordsize, ".text.thunk") {
3069 this->Parent = OS;
3070 this->OutSecOff = Off;
3279 config->wordsize, ".text.thunk") {
3280 this->parent = os;
3281 this->outSecOff = off;
30713282}
30723283
3073void ThunkSection::addThunk(Thunk *T) {
3074 Thunks.push_back(T);
3075 T->addSymbols(*this);
3284void ThunkSection::addThunk(Thunk *t) {
3285 thunks.push_back(t);
3286 t->addSymbols(*this);
30763287}
30773288
3078void ThunkSection::writeTo(uint8_t *Buf) {
3079 for (Thunk *T : Thunks)
3080 T->writeTo(Buf + T->Offset);
3289void ThunkSection::writeTo(uint8_t *buf) {
3290 for (Thunk *t : thunks)
3291 t->writeTo(buf + t->offset);
30813292}
30823293
30833294InputSection *ThunkSection::getTargetInputSection() const {
3084 if (Thunks.empty())
3295 if (thunks.empty())
30853296 return nullptr;
3086 const Thunk *T = Thunks.front();
3087 return T->getTargetInputSection();
3297 const Thunk *t = thunks.front();
3298 return t->getTargetInputSection();
30883299}
30893300
30903301bool ThunkSection::assignOffsets() {
3091 uint64_t Off = 0;
3092 for (Thunk *T : Thunks) {
3093 Off = alignTo(Off, T->Alignment);
3094 T->setOffset(Off);
3095 uint32_t Size = T->size();
3096 T->getThunkTargetSym()->Size = Size;
3097 Off += Size;
3098 }
3099 bool Changed = Off != Size;
3100 Size = Off;
3101 return Changed;
3302 uint64_t off = 0;
3303 for (Thunk *t : thunks) {
3304 off = alignTo(off, t->alignment);
3305 t->setOffset(off);
3306 uint32_t size = t->size();
3307 t->getThunkTargetSym()->size = size;
3308 off += size;
3309 }
3310 bool changed = off != size;
3311 size = off;
3312 return changed;
3313}
3314
3315PPC32Got2Section::PPC32Got2Section()
3316 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 4, ".got2") {}
3317
3318bool PPC32Got2Section::isNeeded() const {
3319 // See the comment below. This is not needed if there is no other
3320 // InputSection.
3321 for (BaseCommand *base : getParent()->sectionCommands)
3322 if (auto *isd = dyn_cast<InputSectionDescription>(base))
3323 for (InputSection *isec : isd->sections)
3324 if (isec != this)
3325 return true;
3326 return false;
3327}
3328
3329void PPC32Got2Section::finalizeContents() {
3330 // PPC32 may create multiple GOT sections for -fPIC/-fPIE, one per file in
3331 // .got2 . This function computes outSecOff of each .got2 to be used in
3332 // PPC32PltCallStub::writeTo(). The purpose of this empty synthetic section is
3333 // to collect input sections named ".got2".
3334 uint32_t offset = 0;
3335 for (BaseCommand *base : getParent()->sectionCommands)
3336 if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
3337 for (InputSection *isec : isd->sections) {
3338 if (isec == this)
3339 continue;
3340 isec->file->ppc32Got2OutSecOff = offset;
3341 offset += (uint32_t)isec->getSize();
3342 }
3343 }
31023344}
31033345
31043346// If linking position-dependent code then the table will store the addresses
......@@ -3107,48 +3349,188 @@ bool ThunkSection::assignOffsets() {
31073349// allocated and filled in by the dynamic linker.
31083350PPC64LongBranchTargetSection::PPC64LongBranchTargetSection()
31093351 : SyntheticSection(SHF_ALLOC | SHF_WRITE,
3110 Config->Pic ? SHT_NOBITS : SHT_PROGBITS, 8,
3352 config->isPic ? SHT_NOBITS : SHT_PROGBITS, 8,
31113353 ".branch_lt") {}
31123354
3113void PPC64LongBranchTargetSection::addEntry(Symbol &Sym) {
3114 assert(Sym.PPC64BranchltIndex == 0xffff);
3115 Sym.PPC64BranchltIndex = Entries.size();
3116 Entries.push_back(&Sym);
3355void PPC64LongBranchTargetSection::addEntry(Symbol &sym) {
3356 assert(sym.ppc64BranchltIndex == 0xffff);
3357 sym.ppc64BranchltIndex = entries.size();
3358 entries.push_back(&sym);
31173359}
31183360
31193361size_t PPC64LongBranchTargetSection::getSize() const {
3120 return Entries.size() * 8;
3362 return entries.size() * 8;
31213363}
31223364
3123void PPC64LongBranchTargetSection::writeTo(uint8_t *Buf) {
3124 assert(Target->GotPltEntrySize == 8);
3365void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) {
31253366 // If linking non-pic we have the final addresses of the targets and they get
31263367 // written to the table directly. For pic the dynamic linker will allocate
31273368 // the section and fill it it.
3128 if (Config->Pic)
3369 if (config->isPic)
31293370 return;
31303371
3131 for (const Symbol *Sym : Entries) {
3132 assert(Sym->getVA());
3372 for (const Symbol *sym : entries) {
3373 assert(sym->getVA());
31333374 // Need calls to branch to the local entry-point since a long-branch
31343375 // must be a local-call.
3135 write64(Buf,
3136 Sym->getVA() + getPPC64GlobalEntryToLocalEntryOffset(Sym->StOther));
3137 Buf += Target->GotPltEntrySize;
3376 write64(buf,
3377 sym->getVA() + getPPC64GlobalEntryToLocalEntryOffset(sym->stOther));
3378 buf += 8;
31383379 }
31393380}
31403381
3141bool PPC64LongBranchTargetSection::empty() const {
3382bool PPC64LongBranchTargetSection::isNeeded() const {
31423383 // `removeUnusedSyntheticSections()` is called before thunk allocation which
31433384 // is too early to determine if this section will be empty or not. We need
31443385 // Finalized to keep the section alive until after thunk creation. Finalized
31453386 // only gets set to true once `finalizeSections()` is called after thunk
31463387 // creation. Becuase of this, if we don't create any long-branch thunks we end
31473388 // up with an empty .branch_lt section in the binary.
3148 return Finalized && Entries.empty();
3389 return !finalized || !entries.empty();
31493390}
31503391
3151InStruct elf::In;
3392RISCVSdataSection::RISCVSdataSection()
3393 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 1, ".sdata") {}
3394
3395bool RISCVSdataSection::isNeeded() const {
3396 if (!ElfSym::riscvGlobalPointer)
3397 return false;
3398
3399 // __global_pointer$ is defined relative to .sdata . If the section does not
3400 // exist, create a dummy one.
3401 for (BaseCommand *base : getParent()->sectionCommands)
3402 if (auto *isd = dyn_cast<InputSectionDescription>(base))
3403 for (InputSection *isec : isd->sections)
3404 if (isec != this)
3405 return false;
3406 return true;
3407}
3408
3409static uint8_t getAbiVersion() {
3410 // MIPS non-PIC executable gets ABI version 1.
3411 if (config->emachine == EM_MIPS) {
3412 if (!config->isPic && !config->relocatable &&
3413 (config->eflags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
3414 return 1;
3415 return 0;
3416 }
3417
3418 if (config->emachine == EM_AMDGPU) {
3419 uint8_t ver = objectFiles[0]->abiVersion;
3420 for (InputFile *file : makeArrayRef(objectFiles).slice(1))
3421 if (file->abiVersion != ver)
3422 error("incompatible ABI version: " + toString(file));
3423 return ver;
3424 }
3425
3426 return 0;
3427}
3428
3429template <typename ELFT> void elf::writeEhdr(uint8_t *buf, Partition &part) {
3430 // For executable segments, the trap instructions are written before writing
3431 // the header. Setting Elf header bytes to zero ensures that any unused bytes
3432 // in header are zero-cleared, instead of having trap instructions.
3433 memset(buf, 0, sizeof(typename ELFT::Ehdr));
3434 memcpy(buf, "\177ELF", 4);
3435
3436 auto *eHdr = reinterpret_cast<typename ELFT::Ehdr *>(buf);
3437 eHdr->e_ident[EI_CLASS] = config->is64 ? ELFCLASS64 : ELFCLASS32;
3438 eHdr->e_ident[EI_DATA] = config->isLE ? ELFDATA2LSB : ELFDATA2MSB;
3439 eHdr->e_ident[EI_VERSION] = EV_CURRENT;
3440 eHdr->e_ident[EI_OSABI] = config->osabi;
3441 eHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
3442 eHdr->e_machine = config->emachine;
3443 eHdr->e_version = EV_CURRENT;
3444 eHdr->e_flags = config->eflags;
3445 eHdr->e_ehsize = sizeof(typename ELFT::Ehdr);
3446 eHdr->e_phnum = part.phdrs.size();
3447 eHdr->e_shentsize = sizeof(typename ELFT::Shdr);
3448
3449 if (!config->relocatable) {
3450 eHdr->e_phoff = sizeof(typename ELFT::Ehdr);
3451 eHdr->e_phentsize = sizeof(typename ELFT::Phdr);
3452 }
3453}
3454
3455template <typename ELFT> void elf::writePhdrs(uint8_t *buf, Partition &part) {
3456 // Write the program header table.
3457 auto *hBuf = reinterpret_cast<typename ELFT::Phdr *>(buf);
3458 for (PhdrEntry *p : part.phdrs) {
3459 hBuf->p_type = p->p_type;
3460 hBuf->p_flags = p->p_flags;
3461 hBuf->p_offset = p->p_offset;
3462 hBuf->p_vaddr = p->p_vaddr;
3463 hBuf->p_paddr = p->p_paddr;
3464 hBuf->p_filesz = p->p_filesz;
3465 hBuf->p_memsz = p->p_memsz;
3466 hBuf->p_align = p->p_align;
3467 ++hBuf;
3468 }
3469}
3470
3471template <typename ELFT>
3472PartitionElfHeaderSection<ELFT>::PartitionElfHeaderSection()
3473 : SyntheticSection(SHF_ALLOC, SHT_LLVM_PART_EHDR, 1, "") {}
3474
3475template <typename ELFT>
3476size_t PartitionElfHeaderSection<ELFT>::getSize() const {
3477 return sizeof(typename ELFT::Ehdr);
3478}
3479
3480template <typename ELFT>
3481void PartitionElfHeaderSection<ELFT>::writeTo(uint8_t *buf) {
3482 writeEhdr<ELFT>(buf, getPartition());
3483
3484 // Loadable partitions are always ET_DYN.
3485 auto *eHdr = reinterpret_cast<typename ELFT::Ehdr *>(buf);
3486 eHdr->e_type = ET_DYN;
3487}
3488
3489template <typename ELFT>
3490PartitionProgramHeadersSection<ELFT>::PartitionProgramHeadersSection()
3491 : SyntheticSection(SHF_ALLOC, SHT_LLVM_PART_PHDR, 1, ".phdrs") {}
3492
3493template <typename ELFT>
3494size_t PartitionProgramHeadersSection<ELFT>::getSize() const {
3495 return sizeof(typename ELFT::Phdr) * getPartition().phdrs.size();
3496}
3497
3498template <typename ELFT>
3499void PartitionProgramHeadersSection<ELFT>::writeTo(uint8_t *buf) {
3500 writePhdrs<ELFT>(buf, getPartition());
3501}
3502
3503PartitionIndexSection::PartitionIndexSection()
3504 : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".rodata") {}
3505
3506size_t PartitionIndexSection::getSize() const {
3507 return 12 * (partitions.size() - 1);
3508}
3509
3510void PartitionIndexSection::finalizeContents() {
3511 for (size_t i = 1; i != partitions.size(); ++i)
3512 partitions[i].nameStrTab = mainPart->dynStrTab->addString(partitions[i].name);
3513}
3514
3515void PartitionIndexSection::writeTo(uint8_t *buf) {
3516 uint64_t va = getVA();
3517 for (size_t i = 1; i != partitions.size(); ++i) {
3518 write32(buf, mainPart->dynStrTab->getVA() + partitions[i].nameStrTab - va);
3519 write32(buf + 4, partitions[i].elfHeader->getVA() - (va + 4));
3520
3521 SyntheticSection *next =
3522 i == partitions.size() - 1 ? in.partEnd : partitions[i + 1].elfHeader;
3523 write32(buf + 8, next->getVA() - partitions[i].elfHeader->getVA());
3524
3525 va += 12;
3526 buf += 12;
3527 }
3528}
3529
3530InStruct elf::in;
3531
3532std::vector<Partition> elf::partitions;
3533Partition *elf::mainPart;
31523534
31533535template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
31543536template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
......@@ -3170,11 +3552,6 @@ template void PltSection::addEntry<ELF32BE>(Symbol &Sym);
31703552template void PltSection::addEntry<ELF64LE>(Symbol &Sym);
31713553template void PltSection::addEntry<ELF64BE>(Symbol &Sym);
31723554
3173template void MipsGotSection::build<ELF32LE>();
3174template void MipsGotSection::build<ELF32BE>();
3175template void MipsGotSection::build<ELF64LE>();
3176template void MipsGotSection::build<ELF64BE>();
3177
31783555template class elf::MipsAbiFlagsSection<ELF32LE>;
31793556template class elf::MipsAbiFlagsSection<ELF32BE>;
31803557template class elf::MipsAbiFlagsSection<ELF64LE>;
......@@ -3215,12 +3592,27 @@ template class elf::SymbolTableSection<ELF32BE>;
32153592template class elf::SymbolTableSection<ELF64LE>;
32163593template class elf::SymbolTableSection<ELF64BE>;
32173594
3218template class elf::VersionTableSection<ELF32LE>;
3219template class elf::VersionTableSection<ELF32BE>;
3220template class elf::VersionTableSection<ELF64LE>;
3221template class elf::VersionTableSection<ELF64BE>;
3222
32233595template class elf::VersionNeedSection<ELF32LE>;
32243596template class elf::VersionNeedSection<ELF32BE>;
32253597template class elf::VersionNeedSection<ELF64LE>;
32263598template class elf::VersionNeedSection<ELF64BE>;
3599
3600template void elf::writeEhdr<ELF32LE>(uint8_t *Buf, Partition &Part);
3601template void elf::writeEhdr<ELF32BE>(uint8_t *Buf, Partition &Part);
3602template void elf::writeEhdr<ELF64LE>(uint8_t *Buf, Partition &Part);
3603template void elf::writeEhdr<ELF64BE>(uint8_t *Buf, Partition &Part);
3604
3605template void elf::writePhdrs<ELF32LE>(uint8_t *Buf, Partition &Part);
3606template void elf::writePhdrs<ELF32BE>(uint8_t *Buf, Partition &Part);
3607template void elf::writePhdrs<ELF64LE>(uint8_t *Buf, Partition &Part);
3608template void elf::writePhdrs<ELF64BE>(uint8_t *Buf, Partition &Part);
3609
3610template class elf::PartitionElfHeaderSection<ELF32LE>;
3611template class elf::PartitionElfHeaderSection<ELF32BE>;
3612template class elf::PartitionElfHeaderSection<ELF64LE>;
3613template class elf::PartitionElfHeaderSection<ELF64BE>;
3614
3615template class elf::PartitionProgramHeadersSection<ELF32LE>;
3616template class elf::PartitionProgramHeadersSection<ELF32BE>;
3617template class elf::PartitionProgramHeadersSection<ELF64LE>;
3618template class elf::PartitionProgramHeadersSection<ELF64BE>;
deps/lld/ELF/SyntheticSections.h+519-374
......@@ -1,9 +1,8 @@
11//===- SyntheticSection.h ---------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -18,8 +17,8 @@
1817//
1918//===----------------------------------------------------------------------===//
2019
21#ifndef LLD_ELF_SYNTHETIC_SECTION_H
22#define LLD_ELF_SYNTHETIC_SECTION_H
20#ifndef LLD_ELF_SYNTHETIC_SECTIONS_H
21#define LLD_ELF_SYNTHETIC_SECTIONS_H
2322
2423#include "DWARF.h"
2524#include "EhFrame.h"
......@@ -32,107 +31,113 @@
3231namespace lld {
3332namespace elf {
3433class Defined;
35class SharedSymbol;
34struct PhdrEntry;
35class SymbolTableBaseSection;
36class VersionNeedBaseSection;
3637
3738class SyntheticSection : public InputSection {
3839public:
39 SyntheticSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
40 StringRef Name)
41 : InputSection(nullptr, Flags, Type, Alignment, {}, Name,
40 SyntheticSection(uint64_t flags, uint32_t type, uint32_t alignment,
41 StringRef name)
42 : InputSection(nullptr, flags, type, alignment, {}, name,
4243 InputSectionBase::Synthetic) {
43 this->Live = true;
44 markLive();
4445 }
4546
4647 virtual ~SyntheticSection() = default;
47 virtual void writeTo(uint8_t *Buf) = 0;
48 virtual void writeTo(uint8_t *buf) = 0;
4849 virtual size_t getSize() const = 0;
4950 virtual void finalizeContents() {}
5051 // If the section has the SHF_ALLOC flag and the size may be changed if
5152 // thunks are added, update the section size.
5253 virtual bool updateAllocSize() { return false; }
53 virtual bool empty() const { return false; }
54 virtual bool isNeeded() const { return true; }
5455
55 static bool classof(const SectionBase *D) {
56 return D->kind() == InputSectionBase::Synthetic;
56 static bool classof(const SectionBase *d) {
57 return d->kind() == InputSectionBase::Synthetic;
5758 }
5859};
5960
6061struct CieRecord {
61 EhSectionPiece *Cie = nullptr;
62 std::vector<EhSectionPiece *> Fdes;
62 EhSectionPiece *cie = nullptr;
63 std::vector<EhSectionPiece *> fdes;
6364};
6465
6566// Section for .eh_frame.
6667class EhFrameSection final : public SyntheticSection {
6768public:
6869 EhFrameSection();
69 void writeTo(uint8_t *Buf) override;
70 void writeTo(uint8_t *buf) override;
7071 void finalizeContents() override;
71 bool empty() const override { return Sections.empty(); }
72 size_t getSize() const override { return Size; }
72 bool isNeeded() const override { return !sections.empty(); }
73 size_t getSize() const override { return size; }
74
75 static bool classof(const SectionBase *d) {
76 return SyntheticSection::classof(d) && d->name == ".eh_frame";
77 }
7378
74 template <class ELFT> void addSection(InputSectionBase *S);
79 template <class ELFT> void addSection(InputSectionBase *s);
7580
76 std::vector<EhInputSection *> Sections;
77 size_t NumFdes = 0;
81 std::vector<EhInputSection *> sections;
82 size_t numFdes = 0;
7883
7984 struct FdeData {
80 uint32_t PcRel;
81 uint32_t FdeVARel;
85 uint32_t pcRel;
86 uint32_t fdeVARel;
8287 };
8388
8489 std::vector<FdeData> getFdeData() const;
85 ArrayRef<CieRecord *> getCieRecords() const { return CieRecords; }
90 ArrayRef<CieRecord *> getCieRecords() const { return cieRecords; }
8691
8792private:
8893 // This is used only when parsing EhInputSection. We keep it here to avoid
8994 // allocating one for each EhInputSection.
90 llvm::DenseMap<size_t, CieRecord *> OffsetToCie;
95 llvm::DenseMap<size_t, CieRecord *> offsetToCie;
9196
92 uint64_t Size = 0;
97 uint64_t size = 0;
9398
9499 template <class ELFT, class RelTy>
95 void addSectionAux(EhInputSection *S, llvm::ArrayRef<RelTy> Rels);
100 void addSectionAux(EhInputSection *s, llvm::ArrayRef<RelTy> rels);
96101
97102 template <class ELFT, class RelTy>
98 CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
103 CieRecord *addCie(EhSectionPiece &piece, ArrayRef<RelTy> rels);
99104
100105 template <class ELFT, class RelTy>
101 bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
106 bool isFdeLive(EhSectionPiece &piece, ArrayRef<RelTy> rels);
102107
103 uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc) const;
108 uint64_t getFdePc(uint8_t *buf, size_t off, uint8_t enc) const;
104109
105 std::vector<CieRecord *> CieRecords;
110 std::vector<CieRecord *> cieRecords;
106111
107112 // CIE records are uniquified by their contents and personality functions.
108 llvm::DenseMap<std::pair<ArrayRef<uint8_t>, Symbol *>, CieRecord *> CieMap;
113 llvm::DenseMap<std::pair<ArrayRef<uint8_t>, Symbol *>, CieRecord *> cieMap;
109114};
110115
111116class GotSection : public SyntheticSection {
112117public:
113118 GotSection();
114 size_t getSize() const override { return Size; }
119 size_t getSize() const override { return size; }
115120 void finalizeContents() override;
116 bool empty() const override;
117 void writeTo(uint8_t *Buf) override;
121 bool isNeeded() const override;
122 void writeTo(uint8_t *buf) override;
118123
119 void addEntry(Symbol &Sym);
120 bool addDynTlsEntry(Symbol &Sym);
124 void addEntry(Symbol &sym);
125 bool addDynTlsEntry(Symbol &sym);
121126 bool addTlsIndex();
122 uint64_t getGlobalDynAddr(const Symbol &B) const;
123 uint64_t getGlobalDynOffset(const Symbol &B) const;
127 uint64_t getGlobalDynAddr(const Symbol &b) const;
128 uint64_t getGlobalDynOffset(const Symbol &b) const;
124129
125 uint64_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; }
126 uint32_t getTlsIndexOff() const { return TlsIndexOff; }
130 uint64_t getTlsIndexVA() { return this->getVA() + tlsIndexOff; }
131 uint32_t getTlsIndexOff() const { return tlsIndexOff; }
127132
128133 // Flag to force GOT to be in output if we have relocations
129134 // that relies on its address.
130 bool HasGotOffRel = false;
135 bool hasGotOffRel = false;
131136
132137protected:
133 size_t NumEntries = 0;
134 uint32_t TlsIndexOff = -1;
135 uint64_t Size = 0;
138 size_t numEntries = 0;
139 uint32_t tlsIndexOff = -1;
140 uint64_t size = 0;
136141};
137142
138143// .note.GNU-stack section.
......@@ -140,27 +145,31 @@ class GnuStackSection : public SyntheticSection {
140145public:
141146 GnuStackSection()
142147 : SyntheticSection(0, llvm::ELF::SHT_PROGBITS, 1, ".note.GNU-stack") {}
143 void writeTo(uint8_t *Buf) override {}
148 void writeTo(uint8_t *buf) override {}
144149 size_t getSize() const override { return 0; }
145150};
146151
152class GnuPropertySection : public SyntheticSection {
153public:
154 GnuPropertySection();
155 void writeTo(uint8_t *buf) override;
156 size_t getSize() const override;
157};
158
147159// .note.gnu.build-id section.
148160class BuildIdSection : public SyntheticSection {
149161 // First 16 bytes are a header.
150 static const unsigned HeaderSize = 16;
162 static const unsigned headerSize = 16;
151163
152164public:
165 const size_t hashSize;
153166 BuildIdSection();
154 void writeTo(uint8_t *Buf) override;
155 size_t getSize() const override { return HeaderSize + HashSize; }
156 void writeBuildId(llvm::ArrayRef<uint8_t> Buf);
167 void writeTo(uint8_t *buf) override;
168 size_t getSize() const override { return headerSize + hashSize; }
169 void writeBuildId(llvm::ArrayRef<uint8_t> buf);
157170
158171private:
159 void computeHash(llvm::ArrayRef<uint8_t> Buf,
160 std::function<void(uint8_t *, ArrayRef<uint8_t>)> Hash);
161
162 size_t HashSize;
163 uint8_t *HashBuf;
172 uint8_t *hashBuf;
164173};
165174
166175// BssSection is used to reserve space for copy relocations and common symbols.
......@@ -169,40 +178,40 @@ private:
169178// respectively.
170179class BssSection final : public SyntheticSection {
171180public:
172 BssSection(StringRef Name, uint64_t Size, uint32_t Alignment);
181 BssSection(StringRef name, uint64_t size, uint32_t alignment);
173182 void writeTo(uint8_t *) override {
174183 llvm_unreachable("unexpected writeTo() call for SHT_NOBITS section");
175184 }
176 bool empty() const override { return getSize() == 0; }
177 size_t getSize() const override { return Size; }
185 bool isNeeded() const override { return size != 0; }
186 size_t getSize() const override { return size; }
178187
179 static bool classof(const SectionBase *S) { return S->Bss; }
180 uint64_t Size;
188 static bool classof(const SectionBase *s) { return s->bss; }
189 uint64_t size;
181190};
182191
183192class MipsGotSection final : public SyntheticSection {
184193public:
185194 MipsGotSection();
186 void writeTo(uint8_t *Buf) override;
187 size_t getSize() const override { return Size; }
195 void writeTo(uint8_t *buf) override;
196 size_t getSize() const override { return size; }
188197 bool updateAllocSize() override;
189198 void finalizeContents() override;
190 bool empty() const override;
199 bool isNeeded() const override;
191200
192201 // Join separate GOTs built for each input file to generate
193202 // primary and optional multiple secondary GOTs.
194 template <class ELFT> void build();
203 void build();
195204
196 void addEntry(InputFile &File, Symbol &Sym, int64_t Addend, RelExpr Expr);
197 void addDynTlsEntry(InputFile &File, Symbol &Sym);
198 void addTlsIndex(InputFile &File);
205 void addEntry(InputFile &file, Symbol &sym, int64_t addend, RelExpr expr);
206 void addDynTlsEntry(InputFile &file, Symbol &sym);
207 void addTlsIndex(InputFile &file);
199208
200 uint64_t getPageEntryOffset(const InputFile *F, const Symbol &S,
201 int64_t Addend) const;
202 uint64_t getSymEntryOffset(const InputFile *F, const Symbol &S,
203 int64_t Addend) const;
204 uint64_t getGlobalDynOffset(const InputFile *F, const Symbol &S) const;
205 uint64_t getTlsIndexOffset(const InputFile *F) const;
209 uint64_t getPageEntryOffset(const InputFile *f, const Symbol &s,
210 int64_t addend) const;
211 uint64_t getSymEntryOffset(const InputFile *f, const Symbol &s,
212 int64_t addend) const;
213 uint64_t getGlobalDynOffset(const InputFile *f, const Symbol &s) const;
214 uint64_t getTlsIndexOffset(const InputFile *f) const;
206215
207216 // Returns the symbol which corresponds to the first entry of the global part
208217 // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic
......@@ -215,7 +224,7 @@ public:
215224 unsigned getLocalEntriesNum() const;
216225
217226 // Return _gp value for primary GOT (nullptr) or particular input file.
218 uint64_t getGp(const InputFile *F = nullptr) const;
227 uint64_t getGp(const InputFile *f = nullptr) const;
219228
220229private:
221230 // MIPS GOT consists of three parts: local, global and tls. Each part
......@@ -305,34 +314,35 @@ private:
305314 // https://dmz-portal.mips.com/wiki/MIPS_Multi_GOT
306315
307316 // Number of "Header" entries.
308 static const unsigned HeaderEntriesNum = 2;
317 static const unsigned headerEntriesNum = 2;
309318
310 uint64_t Size = 0;
319 uint64_t size = 0;
311320
312321 // Symbol and addend.
313 typedef std::pair<Symbol *, int64_t> GotEntry;
322 using GotEntry = std::pair<Symbol *, int64_t>;
314323
315324 struct FileGot {
316 InputFile *File = nullptr;
317 size_t StartIndex = 0;
325 InputFile *file = nullptr;
326 size_t startIndex = 0;
318327
319328 struct PageBlock {
320 size_t FirstIndex = 0;
321 size_t Count = 0;
329 size_t firstIndex;
330 size_t count;
331 PageBlock() : firstIndex(0), count(0) {}
322332 };
323333
324334 // Map output sections referenced by MIPS GOT relocations
325335 // to the description (index/count) "page" entries allocated
326336 // for this section.
327 llvm::SmallMapVector<const OutputSection *, PageBlock, 16> PagesMap;
337 llvm::SmallMapVector<const OutputSection *, PageBlock, 16> pagesMap;
328338 // Maps from Symbol+Addend pair or just Symbol to the GOT entry index.
329 llvm::MapVector<GotEntry, size_t> Local16;
330 llvm::MapVector<GotEntry, size_t> Local32;
331 llvm::MapVector<Symbol *, size_t> Global;
332 llvm::MapVector<Symbol *, size_t> Relocs;
333 llvm::MapVector<Symbol *, size_t> Tls;
339 llvm::MapVector<GotEntry, size_t> local16;
340 llvm::MapVector<GotEntry, size_t> local32;
341 llvm::MapVector<Symbol *, size_t> global;
342 llvm::MapVector<Symbol *, size_t> relocs;
343 llvm::MapVector<Symbol *, size_t> tls;
334344 // Set of symbols referenced by dynamic TLS relocations.
335 llvm::MapVector<Symbol *, size_t> DynTlsSymbols;
345 llvm::MapVector<Symbol *, size_t> dynTlsSymbols;
336346
337347 // Total number of all entries.
338348 size_t getEntriesNum() const;
......@@ -345,27 +355,31 @@ private:
345355 // Container of GOT created for each input file.
346356 // After building a final series of GOTs this container
347357 // holds primary and secondary GOT's.
348 std::vector<FileGot> Gots;
358 std::vector<FileGot> gots;
349359
350360 // Return (and create if necessary) `FileGot`.
351 FileGot &getGot(InputFile &F);
361 FileGot &getGot(InputFile &f);
352362
353363 // Try to merge two GOTs. In case of success the `Dst` contains
354364 // result of merging and the function returns true. In case of
355365 // ovwerflow the `Dst` is unchanged and the function returns false.
356 bool tryMergeGots(FileGot & Dst, FileGot & Src, bool IsPrimary);
366 bool tryMergeGots(FileGot & dst, FileGot & src, bool isPrimary);
357367};
358368
359369class GotPltSection final : public SyntheticSection {
360370public:
361371 GotPltSection();
362 void addEntry(Symbol &Sym);
372 void addEntry(Symbol &sym);
363373 size_t getSize() const override;
364 void writeTo(uint8_t *Buf) override;
365 bool empty() const override;
374 void writeTo(uint8_t *buf) override;
375 bool isNeeded() const override;
376
377 // Flag to force GotPlt to be in output if we have relocations
378 // that relies on its address.
379 bool hasGotPltOffRel = false;
366380
367381private:
368 std::vector<const Symbol *> Entries;
382 std::vector<const Symbol *> entries;
369383};
370384
371385// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc
......@@ -375,167 +389,164 @@ private:
375389class IgotPltSection final : public SyntheticSection {
376390public:
377391 IgotPltSection();
378 void addEntry(Symbol &Sym);
392 void addEntry(Symbol &sym);
379393 size_t getSize() const override;
380 void writeTo(uint8_t *Buf) override;
381 bool empty() const override { return Entries.empty(); }
394 void writeTo(uint8_t *buf) override;
395 bool isNeeded() const override { return !entries.empty(); }
382396
383397private:
384 std::vector<const Symbol *> Entries;
398 std::vector<const Symbol *> entries;
385399};
386400
387401class StringTableSection final : public SyntheticSection {
388402public:
389 StringTableSection(StringRef Name, bool Dynamic);
390 unsigned addString(StringRef S, bool HashIt = true);
391 void writeTo(uint8_t *Buf) override;
392 size_t getSize() const override { return Size; }
393 bool isDynamic() const { return Dynamic; }
403 StringTableSection(StringRef name, bool dynamic);
404 unsigned addString(StringRef s, bool hashIt = true);
405 void writeTo(uint8_t *buf) override;
406 size_t getSize() const override { return size; }
407 bool isDynamic() const { return dynamic; }
394408
395409private:
396 const bool Dynamic;
410 const bool dynamic;
397411
398 uint64_t Size = 0;
412 uint64_t size = 0;
399413
400 llvm::DenseMap<StringRef, unsigned> StringMap;
401 std::vector<StringRef> Strings;
414 llvm::DenseMap<StringRef, unsigned> stringMap;
415 std::vector<StringRef> strings;
402416};
403417
404418class DynamicReloc {
405419public:
406 DynamicReloc(RelType Type, const InputSectionBase *InputSec,
407 uint64_t OffsetInSec, bool UseSymVA, Symbol *Sym, int64_t Addend)
408 : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
409 UseSymVA(UseSymVA), Addend(Addend), OutputSec(nullptr) {}
420 DynamicReloc(RelType type, const InputSectionBase *inputSec,
421 uint64_t offsetInSec, bool useSymVA, Symbol *sym, int64_t addend)
422 : type(type), sym(sym), inputSec(inputSec), offsetInSec(offsetInSec),
423 useSymVA(useSymVA), addend(addend), outputSec(nullptr) {}
410424 // This constructor records dynamic relocation settings used by MIPS
411425 // multi-GOT implementation. It's to relocate addresses of 64kb pages
412426 // lie inside the output section.
413 DynamicReloc(RelType Type, const InputSectionBase *InputSec,
414 uint64_t OffsetInSec, const OutputSection *OutputSec,
415 int64_t Addend)
416 : Type(Type), Sym(nullptr), InputSec(InputSec), OffsetInSec(OffsetInSec),
417 UseSymVA(false), Addend(Addend), OutputSec(OutputSec) {}
427 DynamicReloc(RelType type, const InputSectionBase *inputSec,
428 uint64_t offsetInSec, const OutputSection *outputSec,
429 int64_t addend)
430 : type(type), sym(nullptr), inputSec(inputSec), offsetInSec(offsetInSec),
431 useSymVA(false), addend(addend), outputSec(outputSec) {}
418432
419433 uint64_t getOffset() const;
420 uint32_t getSymIndex() const;
421 const InputSectionBase *getInputSec() const { return InputSec; }
434 uint32_t getSymIndex(SymbolTableBaseSection *symTab) const;
422435
423436 // Computes the addend of the dynamic relocation. Note that this is not the
424 // same as the Addend member variable as it also includes the symbol address
425 // if UseSymVA is true.
437 // same as the addend member variable as it also includes the symbol address
438 // if useSymVA is true.
426439 int64_t computeAddend() const;
427440
428 RelType Type;
441 RelType type;
429442
430private:
431 Symbol *Sym;
432 const InputSectionBase *InputSec = nullptr;
433 uint64_t OffsetInSec;
443 Symbol *sym;
444 const InputSectionBase *inputSec = nullptr;
445 uint64_t offsetInSec;
434446 // If this member is true, the dynamic relocation will not be against the
435447 // symbol but will instead be a relative relocation that simply adds the
436448 // load address. This means we need to write the symbol virtual address
437449 // plus the original addend as the final relocation addend.
438 bool UseSymVA;
439 int64_t Addend;
440 const OutputSection *OutputSec;
450 bool useSymVA;
451 int64_t addend;
452 const OutputSection *outputSec;
441453};
442454
443455template <class ELFT> class DynamicSection final : public SyntheticSection {
444 typedef typename ELFT::Dyn Elf_Dyn;
445 typedef typename ELFT::Rel Elf_Rel;
446 typedef typename ELFT::Rela Elf_Rela;
447 typedef typename ELFT::Relr Elf_Relr;
448 typedef typename ELFT::Shdr Elf_Shdr;
449 typedef typename ELFT::Sym Elf_Sym;
456 using Elf_Dyn = typename ELFT::Dyn;
457 using Elf_Rel = typename ELFT::Rel;
458 using Elf_Rela = typename ELFT::Rela;
459 using Elf_Relr = typename ELFT::Relr;
460 using Elf_Shdr = typename ELFT::Shdr;
461 using Elf_Sym = typename ELFT::Sym;
450462
451463 // finalizeContents() fills this vector with the section contents.
452 std::vector<std::pair<int32_t, std::function<uint64_t()>>> Entries;
464 std::vector<std::pair<int32_t, std::function<uint64_t()>>> entries;
453465
454466public:
455467 DynamicSection();
456468 void finalizeContents() override;
457 void writeTo(uint8_t *Buf) override;
458 size_t getSize() const override { return Size; }
469 void writeTo(uint8_t *buf) override;
470 size_t getSize() const override { return size; }
459471
460472private:
461 void add(int32_t Tag, std::function<uint64_t()> Fn);
462 void addInt(int32_t Tag, uint64_t Val);
463 void addInSec(int32_t Tag, InputSection *Sec);
464 void addInSecRelative(int32_t Tag, InputSection *Sec);
465 void addOutSec(int32_t Tag, OutputSection *Sec);
466 void addSize(int32_t Tag, OutputSection *Sec);
467 void addSym(int32_t Tag, Symbol *Sym);
468
469 uint64_t Size = 0;
473 void add(int32_t tag, std::function<uint64_t()> fn);
474 void addInt(int32_t tag, uint64_t val);
475 void addInSec(int32_t tag, InputSection *sec);
476 void addInSecRelative(int32_t tag, InputSection *sec);
477 void addOutSec(int32_t tag, OutputSection *sec);
478 void addSize(int32_t tag, OutputSection *sec);
479 void addSym(int32_t tag, Symbol *sym);
480
481 uint64_t size = 0;
470482};
471483
472484class RelocationBaseSection : public SyntheticSection {
473485public:
474 RelocationBaseSection(StringRef Name, uint32_t Type, int32_t DynamicTag,
475 int32_t SizeDynamicTag);
476 void addReloc(RelType DynType, InputSectionBase *IS, uint64_t OffsetInSec,
477 Symbol *Sym);
486 RelocationBaseSection(StringRef name, uint32_t type, int32_t dynamicTag,
487 int32_t sizeDynamicTag);
488 void addReloc(RelType dynType, InputSectionBase *isec, uint64_t offsetInSec,
489 Symbol *sym);
478490 // Add a dynamic relocation that might need an addend. This takes care of
479491 // writing the addend to the output section if needed.
480 void addReloc(RelType DynType, InputSectionBase *InputSec,
481 uint64_t OffsetInSec, Symbol *Sym, int64_t Addend, RelExpr Expr,
482 RelType Type);
483 void addReloc(const DynamicReloc &Reloc);
484 bool empty() const override { return Relocs.empty(); }
485 size_t getSize() const override { return Relocs.size() * this->Entsize; }
486 size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
492 void addReloc(RelType dynType, InputSectionBase *inputSec,
493 uint64_t offsetInSec, Symbol *sym, int64_t addend, RelExpr expr,
494 RelType type);
495 void addReloc(const DynamicReloc &reloc);
496 bool isNeeded() const override { return !relocs.empty(); }
497 size_t getSize() const override { return relocs.size() * this->entsize; }
498 size_t getRelativeRelocCount() const { return numRelativeRelocs; }
487499 void finalizeContents() override;
488 int32_t DynamicTag, SizeDynamicTag;
500 int32_t dynamicTag, sizeDynamicTag;
501 std::vector<DynamicReloc> relocs;
489502
490503protected:
491 std::vector<DynamicReloc> Relocs;
492 size_t NumRelativeRelocs = 0;
504 size_t numRelativeRelocs = 0;
493505};
494506
495507template <class ELFT>
496508class RelocationSection final : public RelocationBaseSection {
497 typedef typename ELFT::Rel Elf_Rel;
498 typedef typename ELFT::Rela Elf_Rela;
509 using Elf_Rel = typename ELFT::Rel;
510 using Elf_Rela = typename ELFT::Rela;
499511
500512public:
501 RelocationSection(StringRef Name, bool Sort);
502 unsigned getRelocOffset();
503 void writeTo(uint8_t *Buf) override;
513 RelocationSection(StringRef name, bool sort);
514 void writeTo(uint8_t *buf) override;
504515
505516private:
506 bool Sort;
517 bool sort;
507518};
508519
509520template <class ELFT>
510521class AndroidPackedRelocationSection final : public RelocationBaseSection {
511 typedef typename ELFT::Rel Elf_Rel;
512 typedef typename ELFT::Rela Elf_Rela;
522 using Elf_Rel = typename ELFT::Rel;
523 using Elf_Rela = typename ELFT::Rela;
513524
514525public:
515 AndroidPackedRelocationSection(StringRef Name);
526 AndroidPackedRelocationSection(StringRef name);
516527
517528 bool updateAllocSize() override;
518 size_t getSize() const override { return RelocData.size(); }
519 void writeTo(uint8_t *Buf) override {
520 memcpy(Buf, RelocData.data(), RelocData.size());
529 size_t getSize() const override { return relocData.size(); }
530 void writeTo(uint8_t *buf) override {
531 memcpy(buf, relocData.data(), relocData.size());
521532 }
522533
523534private:
524 SmallVector<char, 0> RelocData;
535 SmallVector<char, 0> relocData;
525536};
526537
527538struct RelativeReloc {
528 uint64_t getOffset() const { return InputSec->getVA(OffsetInSec); }
539 uint64_t getOffset() const { return inputSec->getVA(offsetInSec); }
529540
530 const InputSectionBase *InputSec;
531 uint64_t OffsetInSec;
541 const InputSectionBase *inputSec;
542 uint64_t offsetInSec;
532543};
533544
534545class RelrBaseSection : public SyntheticSection {
535546public:
536547 RelrBaseSection();
537 bool empty() const override { return Relocs.empty(); }
538 std::vector<RelativeReloc> Relocs;
548 bool isNeeded() const override { return !relocs.empty(); }
549 std::vector<RelativeReloc> relocs;
539550};
540551
541552// RelrSection is used to encode offsets for relative relocations.
......@@ -543,65 +554,65 @@ public:
543554// https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
544555// For more details, see the comment in RelrSection::updateAllocSize().
545556template <class ELFT> class RelrSection final : public RelrBaseSection {
546 typedef typename ELFT::Relr Elf_Relr;
557 using Elf_Relr = typename ELFT::Relr;
547558
548559public:
549560 RelrSection();
550561
551562 bool updateAllocSize() override;
552 size_t getSize() const override { return RelrRelocs.size() * this->Entsize; }
553 void writeTo(uint8_t *Buf) override {
554 memcpy(Buf, RelrRelocs.data(), getSize());
563 size_t getSize() const override { return relrRelocs.size() * this->entsize; }
564 void writeTo(uint8_t *buf) override {
565 memcpy(buf, relrRelocs.data(), getSize());
555566 }
556567
557568private:
558 std::vector<Elf_Relr> RelrRelocs;
569 std::vector<Elf_Relr> relrRelocs;
559570};
560571
561572struct SymbolTableEntry {
562 Symbol *Sym;
563 size_t StrTabOffset;
573 Symbol *sym;
574 size_t strTabOffset;
564575};
565576
566577class SymbolTableBaseSection : public SyntheticSection {
567578public:
568 SymbolTableBaseSection(StringTableSection &StrTabSec);
579 SymbolTableBaseSection(StringTableSection &strTabSec);
569580 void finalizeContents() override;
570 size_t getSize() const override { return getNumSymbols() * Entsize; }
571 void addSymbol(Symbol *Sym);
572 unsigned getNumSymbols() const { return Symbols.size() + 1; }
573 size_t getSymbolIndex(Symbol *Sym);
574 ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
581 size_t getSize() const override { return getNumSymbols() * entsize; }
582 void addSymbol(Symbol *sym);
583 unsigned getNumSymbols() const { return symbols.size() + 1; }
584 size_t getSymbolIndex(Symbol *sym);
585 ArrayRef<SymbolTableEntry> getSymbols() const { return symbols; }
575586
576587protected:
577588 void sortSymTabSymbols();
578589
579590 // A vector of symbols and their string table offsets.
580 std::vector<SymbolTableEntry> Symbols;
591 std::vector<SymbolTableEntry> symbols;
581592
582 StringTableSection &StrTabSec;
593 StringTableSection &strTabSec;
583594
584 llvm::once_flag OnceFlag;
585 llvm::DenseMap<Symbol *, size_t> SymbolIndexMap;
586 llvm::DenseMap<OutputSection *, size_t> SectionIndexMap;
595 llvm::once_flag onceFlag;
596 llvm::DenseMap<Symbol *, size_t> symbolIndexMap;
597 llvm::DenseMap<OutputSection *, size_t> sectionIndexMap;
587598};
588599
589600template <class ELFT>
590601class SymbolTableSection final : public SymbolTableBaseSection {
591 typedef typename ELFT::Sym Elf_Sym;
602 using Elf_Sym = typename ELFT::Sym;
592603
593604public:
594 SymbolTableSection(StringTableSection &StrTabSec);
595 void writeTo(uint8_t *Buf) override;
605 SymbolTableSection(StringTableSection &strTabSec);
606 void writeTo(uint8_t *buf) override;
596607};
597608
598609class SymtabShndxSection final : public SyntheticSection {
599610public:
600611 SymtabShndxSection();
601612
602 void writeTo(uint8_t *Buf) override;
613 void writeTo(uint8_t *buf) override;
603614 size_t getSize() const override;
604 bool empty() const override;
615 bool isNeeded() const override;
605616 void finalizeContents() override;
606617};
607618
......@@ -611,42 +622,42 @@ class GnuHashTableSection final : public SyntheticSection {
611622public:
612623 GnuHashTableSection();
613624 void finalizeContents() override;
614 void writeTo(uint8_t *Buf) override;
615 size_t getSize() const override { return Size; }
625 void writeTo(uint8_t *buf) override;
626 size_t getSize() const override { return size; }
616627
617628 // Adds symbols to the hash table.
618629 // Sorts the input to satisfy GNU hash section requirements.
619 void addSymbols(std::vector<SymbolTableEntry> &Symbols);
630 void addSymbols(std::vector<SymbolTableEntry> &symbols);
620631
621632private:
622633 // See the comment in writeBloomFilter.
623634 enum { Shift2 = 26 };
624635
625 void writeBloomFilter(uint8_t *Buf);
626 void writeHashTable(uint8_t *Buf);
636 void writeBloomFilter(uint8_t *buf);
637 void writeHashTable(uint8_t *buf);
627638
628639 struct Entry {
629 Symbol *Sym;
630 size_t StrTabOffset;
631 uint32_t Hash;
632 uint32_t BucketIdx;
640 Symbol *sym;
641 size_t strTabOffset;
642 uint32_t hash;
643 uint32_t bucketIdx;
633644 };
634645
635 std::vector<Entry> Symbols;
636 size_t MaskWords;
637 size_t NBuckets = 0;
638 size_t Size = 0;
646 std::vector<Entry> symbols;
647 size_t maskWords;
648 size_t nBuckets = 0;
649 size_t size = 0;
639650};
640651
641652class HashTableSection final : public SyntheticSection {
642653public:
643654 HashTableSection();
644655 void finalizeContents() override;
645 void writeTo(uint8_t *Buf) override;
646 size_t getSize() const override { return Size; }
656 void writeTo(uint8_t *buf) override;
657 size_t getSize() const override { return size; }
647658
648659private:
649 size_t Size = 0;
660 size_t size = 0;
650661};
651662
652663// The PltSection is used for both the Plt and Iplt. The former usually has a
......@@ -655,67 +666,66 @@ private:
655666// Target->IRelativeRel.
656667class PltSection : public SyntheticSection {
657668public:
658 PltSection(bool IsIplt);
659 void writeTo(uint8_t *Buf) override;
669 PltSection(bool isIplt);
670 void writeTo(uint8_t *buf) override;
660671 size_t getSize() const override;
661 bool empty() const override { return Entries.empty(); }
672 bool isNeeded() const override { return !entries.empty(); }
662673 void addSymbols();
663 template <class ELFT> void addEntry(Symbol &Sym);
674 template <class ELFT> void addEntry(Symbol &sym);
664675
665 size_t HeaderSize;
676 size_t headerSize;
666677
667678private:
668 unsigned getPltRelocOff() const;
669 std::vector<std::pair<const Symbol *, unsigned>> Entries;
670 bool IsIplt;
679 std::vector<const Symbol *> entries;
680 bool isIplt;
671681};
672682
673683class GdbIndexSection final : public SyntheticSection {
674684public:
675685 struct AddressEntry {
676 InputSection *Section;
677 uint64_t LowAddress;
678 uint64_t HighAddress;
679 uint32_t CuIndex;
686 InputSection *section;
687 uint64_t lowAddress;
688 uint64_t highAddress;
689 uint32_t cuIndex;
680690 };
681691
682692 struct CuEntry {
683 uint64_t CuOffset;
684 uint64_t CuLength;
693 uint64_t cuOffset;
694 uint64_t cuLength;
685695 };
686696
687697 struct NameAttrEntry {
688 llvm::CachedHashStringRef Name;
689 uint32_t CuIndexAndAttrs;
698 llvm::CachedHashStringRef name;
699 uint32_t cuIndexAndAttrs;
690700 };
691701
692702 struct GdbChunk {
693 InputSection *Sec;
694 std::vector<AddressEntry> AddressAreas;
695 std::vector<CuEntry> CompilationUnits;
703 InputSection *sec;
704 std::vector<AddressEntry> addressAreas;
705 std::vector<CuEntry> compilationUnits;
696706 };
697707
698708 struct GdbSymbol {
699 llvm::CachedHashStringRef Name;
700 std::vector<uint32_t> CuVector;
701 uint32_t NameOff;
702 uint32_t CuVectorOff;
709 llvm::CachedHashStringRef name;
710 std::vector<uint32_t> cuVector;
711 uint32_t nameOff;
712 uint32_t cuVectorOff;
703713 };
704714
705715 GdbIndexSection();
706716 template <typename ELFT> static GdbIndexSection *create();
707 void writeTo(uint8_t *Buf) override;
708 size_t getSize() const override { return Size; }
709 bool empty() const override;
717 void writeTo(uint8_t *buf) override;
718 size_t getSize() const override { return size; }
719 bool isNeeded() const override;
710720
711721private:
712722 struct GdbIndexHeader {
713 llvm::support::ulittle32_t Version;
714 llvm::support::ulittle32_t CuListOff;
715 llvm::support::ulittle32_t CuTypesOff;
716 llvm::support::ulittle32_t AddressAreaOff;
717 llvm::support::ulittle32_t SymtabOff;
718 llvm::support::ulittle32_t ConstantPoolOff;
723 llvm::support::ulittle32_t version;
724 llvm::support::ulittle32_t cuListOff;
725 llvm::support::ulittle32_t cuTypesOff;
726 llvm::support::ulittle32_t addressAreaOff;
727 llvm::support::ulittle32_t symtabOff;
728 llvm::support::ulittle32_t constantPoolOff;
719729 };
720730
721731 void initOutputSize();
......@@ -723,12 +733,12 @@ private:
723733
724734 // Each chunk contains information gathered from debug sections of a
725735 // single object file.
726 std::vector<GdbChunk> Chunks;
736 std::vector<GdbChunk> chunks;
727737
728738 // A symbol table for this .gdb_index section.
729 std::vector<GdbSymbol> Symbols;
739 std::vector<GdbSymbol> symbols;
730740
731 size_t Size;
741 size_t size;
732742};
733743
734744// --eh-frame-hdr option tells linker to construct a header for all the
......@@ -743,9 +753,10 @@ private:
743753class EhFrameHeader final : public SyntheticSection {
744754public:
745755 EhFrameHeader();
746 void writeTo(uint8_t *Buf) override;
756 void write();
757 void writeTo(uint8_t *buf) override;
747758 size_t getSize() const override;
748 bool empty() const override;
759 bool isNeeded() const override;
749760};
750761
751762// For more information about .gnu.version and .gnu.version_r see:
......@@ -761,13 +772,15 @@ public:
761772 VersionDefinitionSection();
762773 void finalizeContents() override;
763774 size_t getSize() const override;
764 void writeTo(uint8_t *Buf) override;
775 void writeTo(uint8_t *buf) override;
765776
766777private:
767778 enum { EntrySize = 28 };
768 void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
779 void writeOne(uint8_t *buf, uint32_t index, StringRef name, size_t nameOff);
780 StringRef getFileDefName();
769781
770 unsigned FileDefNameOff;
782 unsigned fileDefNameOff;
783 std::vector<unsigned> verDefNameOffs;
771784};
772785
773786// The .gnu.version section specifies the required version of each symbol in the
......@@ -776,14 +789,13 @@ private:
776789// identifier defined in the either .gnu.version_r or .gnu.version_d section.
777790// The values 0 and 1 are reserved. All other values are used for versions in
778791// the own object or in any of the dependencies.
779template <class ELFT>
780792class VersionTableSection final : public SyntheticSection {
781793public:
782794 VersionTableSection();
783795 void finalizeContents() override;
784796 size_t getSize() const override;
785 void writeTo(uint8_t *Buf) override;
786 bool empty() const override;
797 void writeTo(uint8_t *buf) override;
798 bool isNeeded() const override;
787799};
788800
789801// The .gnu.version_r section defines the version identifiers used by
......@@ -791,25 +803,30 @@ public:
791803// Elf_Verneed specifies the version requirements for a single DSO, and contains
792804// a reference to a linked list of Elf_Vernaux data structures which define the
793805// mapping from version identifiers to version names.
794template <class ELFT> class VersionNeedSection final : public SyntheticSection {
795 typedef typename ELFT::Verneed Elf_Verneed;
796 typedef typename ELFT::Vernaux Elf_Vernaux;
806template <class ELFT>
807class VersionNeedSection final : public SyntheticSection {
808 using Elf_Verneed = typename ELFT::Verneed;
809 using Elf_Vernaux = typename ELFT::Vernaux;
810
811 struct Vernaux {
812 uint64_t hash;
813 uint32_t verneedIndex;
814 uint64_t nameStrTab;
815 };
797816
798 // A vector of shared files that need Elf_Verneed data structures and the
799 // string table offsets of their sonames.
800 std::vector<std::pair<SharedFile<ELFT> *, size_t>> Needed;
817 struct Verneed {
818 uint64_t nameStrTab;
819 std::vector<Vernaux> vernauxs;
820 };
801821
802 // The next available version identifier.
803 unsigned NextIndex;
822 std::vector<Verneed> verneeds;
804823
805824public:
806825 VersionNeedSection();
807 void addSymbol(Symbol *Sym);
808826 void finalizeContents() override;
809 void writeTo(uint8_t *Buf) override;
827 void writeTo(uint8_t *buf) override;
810828 size_t getSize() const override;
811 size_t getNeedNum() const { return Needed.size(); }
812 bool empty() const override;
829 bool isNeeded() const override;
813830};
814831
815832// MergeSyntheticSection is a class that allows us to put mergeable sections
......@@ -818,36 +835,36 @@ public:
818835// attached to regular output sections.
819836class MergeSyntheticSection : public SyntheticSection {
820837public:
821 void addSection(MergeInputSection *MS);
822 std::vector<MergeInputSection *> Sections;
838 void addSection(MergeInputSection *ms);
839 std::vector<MergeInputSection *> sections;
823840
824841protected:
825 MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags,
826 uint32_t Alignment)
827 : SyntheticSection(Flags, Type, Alignment, Name) {}
842 MergeSyntheticSection(StringRef name, uint32_t type, uint64_t flags,
843 uint32_t alignment)
844 : SyntheticSection(flags, type, alignment, name) {}
828845};
829846
830847class MergeTailSection final : public MergeSyntheticSection {
831848public:
832 MergeTailSection(StringRef Name, uint32_t Type, uint64_t Flags,
833 uint32_t Alignment);
849 MergeTailSection(StringRef name, uint32_t type, uint64_t flags,
850 uint32_t alignment);
834851
835852 size_t getSize() const override;
836 void writeTo(uint8_t *Buf) override;
853 void writeTo(uint8_t *buf) override;
837854 void finalizeContents() override;
838855
839856private:
840 llvm::StringTableBuilder Builder;
857 llvm::StringTableBuilder builder;
841858};
842859
843860class MergeNoTailSection final : public MergeSyntheticSection {
844861public:
845 MergeNoTailSection(StringRef Name, uint32_t Type, uint64_t Flags,
846 uint32_t Alignment)
847 : MergeSyntheticSection(Name, Type, Flags, Alignment) {}
862 MergeNoTailSection(StringRef name, uint32_t type, uint64_t flags,
863 uint32_t alignment)
864 : MergeSyntheticSection(name, type, flags, alignment) {}
848865
849 size_t getSize() const override { return Size; }
850 void writeTo(uint8_t *Buf) override;
866 size_t getSize() const override { return size; }
867 void writeTo(uint8_t *buf) override;
851868 void finalizeContents() override;
852869
853870private:
......@@ -856,67 +873,68 @@ private:
856873 // because DenseMap also uses lower bits to determine a bucket ID.
857874 // If we use lower bits, it significantly increases the probability of
858875 // hash collisons.
859 size_t getShardId(uint32_t Hash) {
860 return Hash >> (32 - llvm::countTrailingZeros(NumShards));
876 size_t getShardId(uint32_t hash) {
877 assert((hash >> 31) == 0);
878 return hash >> (31 - llvm::countTrailingZeros(numShards));
861879 }
862880
863881 // Section size
864 size_t Size;
882 size_t size;
865883
866884 // String table contents
867 constexpr static size_t NumShards = 32;
868 std::vector<llvm::StringTableBuilder> Shards;
869 size_t ShardOffsets[NumShards];
885 constexpr static size_t numShards = 32;
886 std::vector<llvm::StringTableBuilder> shards;
887 size_t shardOffsets[numShards];
870888};
871889
872890// .MIPS.abiflags section.
873891template <class ELFT>
874892class MipsAbiFlagsSection final : public SyntheticSection {
875 typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
893 using Elf_Mips_ABIFlags = llvm::object::Elf_Mips_ABIFlags<ELFT>;
876894
877895public:
878896 static MipsAbiFlagsSection *create();
879897
880 MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags);
898 MipsAbiFlagsSection(Elf_Mips_ABIFlags flags);
881899 size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
882 void writeTo(uint8_t *Buf) override;
900 void writeTo(uint8_t *buf) override;
883901
884902private:
885 Elf_Mips_ABIFlags Flags;
903 Elf_Mips_ABIFlags flags;
886904};
887905
888906// .MIPS.options section.
889907template <class ELFT> class MipsOptionsSection final : public SyntheticSection {
890 typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
891 typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
908 using Elf_Mips_Options = llvm::object::Elf_Mips_Options<ELFT>;
909 using Elf_Mips_RegInfo = llvm::object::Elf_Mips_RegInfo<ELFT>;
892910
893911public:
894912 static MipsOptionsSection *create();
895913
896 MipsOptionsSection(Elf_Mips_RegInfo Reginfo);
897 void writeTo(uint8_t *Buf) override;
914 MipsOptionsSection(Elf_Mips_RegInfo reginfo);
915 void writeTo(uint8_t *buf) override;
898916
899917 size_t getSize() const override {
900918 return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
901919 }
902920
903921private:
904 Elf_Mips_RegInfo Reginfo;
922 Elf_Mips_RegInfo reginfo;
905923};
906924
907925// MIPS .reginfo section.
908926template <class ELFT> class MipsReginfoSection final : public SyntheticSection {
909 typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
927 using Elf_Mips_RegInfo = llvm::object::Elf_Mips_RegInfo<ELFT>;
910928
911929public:
912930 static MipsReginfoSection *create();
913931
914 MipsReginfoSection(Elf_Mips_RegInfo Reginfo);
932 MipsReginfoSection(Elf_Mips_RegInfo reginfo);
915933 size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
916 void writeTo(uint8_t *Buf) override;
934 void writeTo(uint8_t *buf) override;
917935
918936private:
919 Elf_Mips_RegInfo Reginfo;
937 Elf_Mips_RegInfo reginfo;
920938};
921939
922940// This is a MIPS specific section to hold a space within the data segment
......@@ -926,45 +944,115 @@ private:
926944class MipsRldMapSection : public SyntheticSection {
927945public:
928946 MipsRldMapSection();
929 size_t getSize() const override { return Config->Wordsize; }
930 void writeTo(uint8_t *Buf) override {}
947 size_t getSize() const override { return config->wordsize; }
948 void writeTo(uint8_t *buf) override {}
931949};
932950
933class ARMExidxSentinelSection : public SyntheticSection {
951// Representation of the combined .ARM.Exidx input sections. We process these
952// as a SyntheticSection like .eh_frame as we need to merge duplicate entries
953// and add terminating sentinel entries.
954//
955// The .ARM.exidx input sections after SHF_LINK_ORDER processing is done form
956// a table that the unwinder can derive (Addresses are encoded as offsets from
957// table):
958// | Address of function | Unwind instructions for function |
959// where the unwind instructions are either a small number of unwind or the
960// special EXIDX_CANTUNWIND entry representing no unwinding information.
961// When an exception is thrown from an address A, the unwinder searches the
962// table for the closest table entry with Address of function <= A. This means
963// that for two consecutive table entries:
964// | A1 | U1 |
965// | A2 | U2 |
966// The range of addresses described by U1 is [A1, A2)
967//
968// There are two cases where we need a linker generated table entry to fixup
969// the address ranges in the table
970// Case 1:
971// - A sentinel entry added with an address higher than all
972// executable sections. This was needed to work around libunwind bug pr31091.
973// - After address assignment we need to find the highest addressed executable
974// section and use the limit of that section so that the unwinder never
975// matches it.
976// Case 2:
977// - InputSections without a .ARM.exidx section (usually from Assembly)
978// need a table entry so that they terminate the range of the previously
979// function. This is pr40277.
980//
981// Instead of storing pointers to the .ARM.exidx InputSections from
982// InputObjects, we store pointers to the executable sections that need
983// .ARM.exidx sections. We can then use the dependentSections of these to
984// either find the .ARM.exidx section or know that we need to generate one.
985class ARMExidxSyntheticSection : public SyntheticSection {
934986public:
935 ARMExidxSentinelSection();
936 size_t getSize() const override { return 8; }
937 void writeTo(uint8_t *Buf) override;
938 bool empty() const override;
987 ARMExidxSyntheticSection();
988
989 // Add an input section to the ARMExidxSyntheticSection. Returns whether the
990 // section needs to be removed from the main input section list.
991 bool addSection(InputSection *isec);
939992
940 static bool classof(const SectionBase *D);
993 size_t getSize() const override { return size; }
994 void writeTo(uint8_t *buf) override;
995 bool isNeeded() const override { return !empty; }
996 // Sort and remove duplicate entries.
997 void finalizeContents() override;
998 InputSection *getLinkOrderDep() const;
999
1000 static bool classof(const SectionBase *d);
1001
1002 // Links to the ARMExidxSections so we can transfer the relocations once the
1003 // layout is known.
1004 std::vector<InputSection *> exidxSections;
9411005
942 // The last section referenced by a regular .ARM.exidx section.
943 // It is found and filled in Writer<ELFT>::resolveShfLinkOrder().
944 // The sentinel points at the end of that section.
945 InputSection *Highest = nullptr;
1006private:
1007 size_t size;
1008
1009 // Empty if ExecutableSections contains no dependent .ARM.exidx sections.
1010 bool empty = true;
1011
1012 // Instead of storing pointers to the .ARM.exidx InputSections from
1013 // InputObjects, we store pointers to the executable sections that need
1014 // .ARM.exidx sections. We can then use the dependentSections of these to
1015 // either find the .ARM.exidx section or know that we need to generate one.
1016 std::vector<InputSection *> executableSections;
1017
1018 // The executable InputSection with the highest address to use for the
1019 // sentinel. We store separately from ExecutableSections as merging of
1020 // duplicate entries may mean this InputSection is removed from
1021 // ExecutableSections.
1022 InputSection *sentinel = nullptr;
9461023};
9471024
9481025// A container for one or more linker generated thunks. Instances of these
9491026// thunks including ARM interworking and Mips LA25 PI to non-PI thunks.
9501027class ThunkSection : public SyntheticSection {
9511028public:
952 // ThunkSection in OS, with desired OutSecOff of Off
953 ThunkSection(OutputSection *OS, uint64_t Off);
1029 // ThunkSection in OS, with desired outSecOff of Off
1030 ThunkSection(OutputSection *os, uint64_t off);
9541031
9551032 // Add a newly created Thunk to this container:
9561033 // Thunk is given offset from start of this InputSection
9571034 // Thunk defines a symbol in this InputSection that can be used as target
9581035 // of a relocation
959 void addThunk(Thunk *T);
960 size_t getSize() const override { return Size; }
961 void writeTo(uint8_t *Buf) override;
1036 void addThunk(Thunk *t);
1037 size_t getSize() const override { return size; }
1038 void writeTo(uint8_t *buf) override;
9621039 InputSection *getTargetInputSection() const;
9631040 bool assignOffsets();
9641041
9651042private:
966 std::vector<Thunk *> Thunks;
967 size_t Size = 0;
1043 std::vector<Thunk *> thunks;
1044 size_t size = 0;
1045};
1046
1047// Used to compute outSecOff of .got2 in each object file. This is needed to
1048// synthesize PLT entries for PPC32 Secure PLT ABI.
1049class PPC32Got2Section final : public SyntheticSection {
1050public:
1051 PPC32Got2Section();
1052 size_t getSize() const override { return 0; }
1053 bool isNeeded() const override;
1054 void finalizeContents() override;
1055 void writeTo(uint8_t *buf) override {}
9681056};
9691057
9701058// This section is used to store the addresses of functions that are called
......@@ -975,15 +1063,48 @@ private:
9751063class PPC64LongBranchTargetSection final : public SyntheticSection {
9761064public:
9771065 PPC64LongBranchTargetSection();
978 void addEntry(Symbol &Sym);
1066 void addEntry(Symbol &sym);
9791067 size_t getSize() const override;
980 void writeTo(uint8_t *Buf) override;
981 bool empty() const override;
982 void finalizeContents() override { Finalized = true; }
1068 void writeTo(uint8_t *buf) override;
1069 bool isNeeded() const override;
1070 void finalizeContents() override { finalized = true; }
9831071
9841072private:
985 std::vector<const Symbol *> Entries;
986 bool Finalized = false;
1073 std::vector<const Symbol *> entries;
1074 bool finalized = false;
1075};
1076
1077template <typename ELFT>
1078class PartitionElfHeaderSection : public SyntheticSection {
1079public:
1080 PartitionElfHeaderSection();
1081 size_t getSize() const override;
1082 void writeTo(uint8_t *buf) override;
1083};
1084
1085template <typename ELFT>
1086class PartitionProgramHeadersSection : public SyntheticSection {
1087public:
1088 PartitionProgramHeadersSection();
1089 size_t getSize() const override;
1090 void writeTo(uint8_t *buf) override;
1091};
1092
1093class PartitionIndexSection : public SyntheticSection {
1094public:
1095 PartitionIndexSection();
1096 size_t getSize() const override;
1097 void finalizeContents() override;
1098 void writeTo(uint8_t *buf) override;
1099};
1100
1101// Create a dummy .sdata for __global_pointer$ if .sdata does not exist.
1102class RISCVSdataSection final : public SyntheticSection {
1103public:
1104 RISCVSdataSection();
1105 size_t getSize() const override { return 0; }
1106 bool isNeeded() const override;
1107 void writeTo(uint8_t *buf) override {}
9871108};
9881109
9891110InputSection *createInterpSection();
......@@ -991,52 +1112,76 @@ MergeInputSection *createCommentSection();
9911112template <class ELFT> void splitSections();
9921113void mergeSections();
9931114
994Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
995 uint64_t Size, InputSectionBase &Section);
996
997// Linker generated sections which can be used as inputs.
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;
1115template <typename ELFT> void writeEhdr(uint8_t *buf, Partition &part);
1116template <typename ELFT> void writePhdrs(uint8_t *buf, Partition &part);
1117
1118Defined *addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
1119 uint64_t size, InputSectionBase &section);
1120
1121void addVerneed(Symbol *ss);
1122
1123// Linker generated per-partition sections.
1124struct Partition {
1125 StringRef name;
1126 uint64_t nameStrTab;
1127
1128 SyntheticSection *elfHeader;
1129 SyntheticSection *programHeaders;
1130 std::vector<PhdrEntry *> phdrs;
1131
1132 ARMExidxSyntheticSection *armExidx;
1133 BuildIdSection *buildId;
1134 SyntheticSection *dynamic;
1135 StringTableSection *dynStrTab;
1136 SymbolTableBaseSection *dynSymTab;
1137 EhFrameHeader *ehFrameHdr;
1138 EhFrameSection *ehFrame;
1139 GnuHashTableSection *gnuHashTab;
1140 HashTableSection *hashTab;
1141 RelocationBaseSection *relaDyn;
1142 RelrBaseSection *relrDyn;
1143 VersionDefinitionSection *verDef;
1144 SyntheticSection *verNeed;
1145 VersionTableSection *verSym;
1146
1147 unsigned getNumber() const { return this - &partitions[0] + 1; }
10291148};
10301149
1031extern InStruct In;
1150extern Partition *mainPart;
10321151
1033template <class ELFT> struct InX {
1034 static VersionTableSection<ELFT> *VerSym;
1035 static VersionNeedSection<ELFT> *VerNeed;
1152inline Partition &SectionBase::getPartition() const {
1153 assert(isLive());
1154 return partitions[partition - 1];
1155}
1156
1157// Linker generated sections which can be used as inputs and are not specific to
1158// a partition.
1159struct InStruct {
1160 InputSection *armAttributes;
1161 BssSection *bss;
1162 BssSection *bssRelRo;
1163 GotSection *got;
1164 GotPltSection *gotPlt;
1165 IgotPltSection *igotPlt;
1166 PPC64LongBranchTargetSection *ppc64LongBranchTarget;
1167 MipsGotSection *mipsGot;
1168 MipsRldMapSection *mipsRldMap;
1169 SyntheticSection *partEnd;
1170 SyntheticSection *partIndex;
1171 PltSection *plt;
1172 PltSection *iplt;
1173 PPC32Got2Section *ppc32Got2;
1174 RISCVSdataSection *riscvSdata;
1175 RelocationBaseSection *relaPlt;
1176 RelocationBaseSection *relaIplt;
1177 StringTableSection *shStrTab;
1178 StringTableSection *strTab;
1179 SymbolTableBaseSection *symTab;
1180 SymtabShndxSection *symTabShndx;
10361181};
10371182
1038template <class ELFT> VersionTableSection<ELFT> *InX<ELFT>::VerSym;
1039template <class ELFT> VersionNeedSection<ELFT> *InX<ELFT>::VerNeed;
1183extern InStruct in;
1184
10401185} // namespace elf
10411186} // namespace lld
10421187
deps/lld/ELF/Target.cpp+49-52
......@@ -1,9 +1,8 @@
11//===- Target.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -38,17 +37,17 @@ using namespace llvm::ELF;
3837using namespace lld;
3938using namespace lld::elf;
4039
41TargetInfo *elf::Target;
40const TargetInfo *elf::target;
4241
43std::string lld::toString(RelType Type) {
44 StringRef S = getELFRelocationTypeName(elf::Config->EMachine, Type);
45 if (S == "Unknown")
46 return ("Unknown (" + Twine(Type) + ")").str();
47 return S;
42std::string lld::toString(RelType type) {
43 StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
44 if (s == "Unknown")
45 return ("Unknown (" + Twine(type) + ")").str();
46 return s;
4847}
4948
5049TargetInfo *elf::getTarget() {
51 switch (Config->EMachine) {
50 switch (config->emachine) {
5251 case EM_386:
5352 case EM_IAMCU:
5453 return getX86TargetInfo();
......@@ -63,7 +62,7 @@ TargetInfo *elf::getTarget() {
6362 case EM_HEXAGON:
6463 return getHexagonTargetInfo();
6564 case EM_MIPS:
66 switch (Config->EKind) {
65 switch (config->ekind) {
6766 case ELF32LEKind:
6867 return getMipsTargetInfo<ELF32LE>();
6968 case ELF32BEKind:
......@@ -86,36 +85,34 @@ TargetInfo *elf::getTarget() {
8685 case EM_SPARCV9:
8786 return getSPARCV9TargetInfo();
8887 case EM_X86_64:
89 if (Config->EKind == ELF32LEKind)
90 return getX32TargetInfo();
9188 return getX86_64TargetInfo();
9289 }
9390 llvm_unreachable("unknown target machine");
9491}
9592
96template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *Loc) {
97 for (InputSectionBase *D : InputSections) {
98 auto *IS = cast<InputSection>(D);
99 if (!IS->getParent())
93template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
94 for (InputSectionBase *d : inputSections) {
95 auto *isec = cast<InputSection>(d);
96 if (!isec->getParent())
10097 continue;
10198
102 uint8_t *ISLoc = IS->getParent()->Loc + IS->OutSecOff;
103 if (ISLoc <= Loc && Loc < ISLoc + IS->getSize())
104 return {IS, IS->template getLocation<ELFT>(Loc - ISLoc) + ": "};
99 uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
100 if (isecLoc <= loc && loc < isecLoc + isec->getSize())
101 return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
105102 }
106103 return {};
107104}
108105
109ErrorPlace elf::getErrorPlace(const uint8_t *Loc) {
110 switch (Config->EKind) {
106ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
107 switch (config->ekind) {
111108 case ELF32LEKind:
112 return getErrPlace<ELF32LE>(Loc);
109 return getErrPlace<ELF32LE>(loc);
113110 case ELF32BEKind:
114 return getErrPlace<ELF32BE>(Loc);
111 return getErrPlace<ELF32BE>(loc);
115112 case ELF64LEKind:
116 return getErrPlace<ELF64LE>(Loc);
113 return getErrPlace<ELF64LE>(loc);
117114 case ELF64BEKind:
118 return getErrPlace<ELF64BE>(Loc);
115 return getErrPlace<ELF64BE>(loc);
119116 default:
120117 llvm_unreachable("unknown ELF type");
121118 }
......@@ -123,62 +120,62 @@ ErrorPlace elf::getErrorPlace(const uint8_t *Loc) {
123120
124121TargetInfo::~TargetInfo() {}
125122
126int64_t TargetInfo::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
123int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
127124 return 0;
128125}
129126
130bool TargetInfo::usesOnlyLowPageBits(RelType Type) const { return false; }
127bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
131128
132bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
133 uint64_t BranchAddr, const Symbol &S) const {
129bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
130 uint64_t branchAddr, const Symbol &s) const {
134131 return false;
135132}
136133
137bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
138 uint8_t StOther) const {
134bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
135 uint8_t stOther) const {
139136 llvm_unreachable("Target doesn't support split stacks.");
140137}
141138
142bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
139bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
143140 return true;
144141}
145142
146void TargetInfo::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
147 writeGotPlt(Buf, S);
143void TargetInfo::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
144 writeGotPlt(buf, s);
148145}
149146
150RelExpr TargetInfo::adjustRelaxExpr(RelType Type, const uint8_t *Data,
151 RelExpr Expr) const {
152 return Expr;
147RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data,
148 RelExpr expr) const {
149 return expr;
153150}
154151
155void TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const {
152void TargetInfo::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
156153 llvm_unreachable("Should not have claimed to be relaxable");
157154}
158155
159void TargetInfo::relaxTlsGdToLe(uint8_t *Loc, RelType Type,
160 uint64_t Val) const {
156void TargetInfo::relaxTlsGdToLe(uint8_t *loc, RelType type,
157 uint64_t val) const {
161158 llvm_unreachable("Should not have claimed to be relaxable");
162159}
163160
164void TargetInfo::relaxTlsGdToIe(uint8_t *Loc, RelType Type,
165 uint64_t Val) const {
161void TargetInfo::relaxTlsGdToIe(uint8_t *loc, RelType type,
162 uint64_t val) const {
166163 llvm_unreachable("Should not have claimed to be relaxable");
167164}
168165
169void TargetInfo::relaxTlsIeToLe(uint8_t *Loc, RelType Type,
170 uint64_t Val) const {
166void TargetInfo::relaxTlsIeToLe(uint8_t *loc, RelType type,
167 uint64_t val) const {
171168 llvm_unreachable("Should not have claimed to be relaxable");
172169}
173170
174void TargetInfo::relaxTlsLdToLe(uint8_t *Loc, RelType Type,
175 uint64_t Val) const {
171void TargetInfo::relaxTlsLdToLe(uint8_t *loc, RelType type,
172 uint64_t val) const {
176173 llvm_unreachable("Should not have claimed to be relaxable");
177174}
178175
179uint64_t TargetInfo::getImageBase() {
176uint64_t TargetInfo::getImageBase() const {
180177 // Use -image-base if set. Fall back to the target default if not.
181 if (Config->ImageBase)
182 return *Config->ImageBase;
183 return Config->Pic ? 0 : DefaultImageBase;
178 if (config->imageBase)
179 return *config->imageBase;
180 return config->isPic ? 0 : defaultImageBase;
184181}
deps/lld/ELF/Target.h+117-116
......@@ -1,9 +1,8 @@
11//===- Target.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -17,7 +16,7 @@
1716#include <array>
1817
1918namespace lld {
20std::string toString(elf::RelType Type);
19std::string toString(elf::RelType type);
2120
2221namespace elf {
2322class Defined;
......@@ -27,36 +26,39 @@ class Symbol;
2726class TargetInfo {
2827public:
2928 virtual uint32_t calcEFlags() const { return 0; }
30 virtual RelType getDynRel(RelType Type) const { return Type; }
31 virtual void writeGotPltHeader(uint8_t *Buf) const {}
32 virtual void writeGotHeader(uint8_t *Buf) const {}
33 virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {};
34 virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const;
35 virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const;
29 virtual RelExpr getRelExpr(RelType type, const Symbol &s,
30 const uint8_t *loc) const = 0;
31 virtual RelType getDynRel(RelType type) const { return 0; }
32 virtual void writeGotPltHeader(uint8_t *buf) const {}
33 virtual void writeGotHeader(uint8_t *buf) const {}
34 virtual void writeGotPlt(uint8_t *buf, const Symbol &s) const {};
35 virtual void writeIgotPlt(uint8_t *buf, const Symbol &s) const;
36 virtual int64_t getImplicitAddend(const uint8_t *buf, RelType type) const;
37 virtual int getTlsGdRelaxSkip(RelType type) const { return 1; }
3638
3739 // If lazy binding is supported, the first entry of the PLT has code
3840 // to call the dynamic linker to resolve PLT entries the first time
3941 // they are called. This function writes that code.
40 virtual void writePltHeader(uint8_t *Buf) const {}
42 virtual void writePltHeader(uint8_t *buf) const {}
4143
42 virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
43 uint64_t PltEntryAddr, int32_t Index,
44 unsigned RelOff) const {}
45 virtual void addPltHeaderSymbols(InputSection &IS) const {}
46 virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {}
44 virtual void writePlt(uint8_t *buf, uint64_t gotEntryAddr,
45 uint64_t pltEntryAddr, int32_t index,
46 unsigned relOff) const {}
47 virtual void addPltHeaderSymbols(InputSection &isec) const {}
48 virtual void addPltSymbols(InputSection &isec, uint64_t off) const {}
4749
4850 // Returns true if a relocation only uses the low bits of a value such that
4951 // all those bits are in the same page. For example, if the relocation
5052 // only uses the low 12 bits in a system with 4k pages. If this is true, the
5153 // bits will always have the same value at runtime and we don't have to emit
5254 // a dynamic relocation.
53 virtual bool usesOnlyLowPageBits(RelType Type) const;
55 virtual bool usesOnlyLowPageBits(RelType type) const;
5456
5557 // Decide whether a Thunk is needed for the relocation from File
5658 // targeting S.
57 virtual bool needsThunk(RelExpr Expr, RelType RelocType,
58 const InputFile *File, uint64_t BranchAddr,
59 const Symbol &S) const;
59 virtual bool needsThunk(RelExpr expr, RelType relocType,
60 const InputFile *file, uint64_t branchAddr,
61 const Symbol &s) const;
6062
6163 // On systems with range extensions we place collections of Thunks at
6264 // regular spacings that enable the majority of branches reach the Thunks.
......@@ -68,77 +70,71 @@ public:
6870 // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks.
6971 // The symbols st_other flags are needed on PowerPC64 for determining the
7072 // offset to the split-stack prologue.
71 virtual bool adjustPrologueForCrossSplitStack(uint8_t *Loc, uint8_t *End,
72 uint8_t StOther) const;
73 virtual bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
74 uint8_t stOther) const;
7375
74 // Return true if we can reach Dst from Src with Relocation RelocType
75 virtual bool inBranchRange(RelType Type, uint64_t Src,
76 uint64_t Dst) const;
77 virtual RelExpr getRelExpr(RelType Type, const Symbol &S,
78 const uint8_t *Loc) const = 0;
76 // Return true if we can reach dst from src with RelType type.
77 virtual bool inBranchRange(RelType type, uint64_t src,
78 uint64_t dst) const;
7979
80 virtual void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const = 0;
80 virtual void relocateOne(uint8_t *loc, RelType type, uint64_t val) const = 0;
8181
8282 virtual ~TargetInfo();
8383
84 unsigned TlsGdRelaxSkip = 1;
85 unsigned PageSize = 4096;
86 unsigned DefaultMaxPageSize = 4096;
84 unsigned defaultCommonPageSize = 4096;
85 unsigned defaultMaxPageSize = 4096;
8786
88 uint64_t getImageBase();
87 uint64_t getImageBase() const;
8988
90 // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got or .got.plt section.
91 uint64_t GotBaseSymOff = 0;
9289 // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
93 bool GotBaseSymInGotPlt = true;
94
95 RelType CopyRel;
96 RelType GotRel;
97 RelType NoneRel;
98 RelType PltRel;
99 RelType RelativeRel;
100 RelType IRelativeRel;
101 RelType TlsDescRel;
102 RelType TlsGotRel;
103 RelType TlsModuleIndexRel;
104 RelType TlsOffsetRel;
105 unsigned GotEntrySize = 0;
106 unsigned GotPltEntrySize = 0;
107 unsigned PltEntrySize;
108 unsigned PltHeaderSize;
90 bool gotBaseSymInGotPlt = true;
91
92 RelType copyRel;
93 RelType gotRel;
94 RelType noneRel;
95 RelType pltRel;
96 RelType relativeRel;
97 RelType iRelativeRel;
98 RelType symbolicRel;
99 RelType tlsDescRel;
100 RelType tlsGotRel;
101 RelType tlsModuleIndexRel;
102 RelType tlsOffsetRel;
103 unsigned pltEntrySize;
104 unsigned pltHeaderSize;
109105
110106 // At least on x86_64 positions 1 and 2 are used by the first plt entry
111107 // to support lazy loading.
112 unsigned GotPltHeaderEntriesNum = 3;
108 unsigned gotPltHeaderEntriesNum = 3;
113109
114110 // On PPC ELF V2 abi, the first entry in the .got is the .TOC.
115 unsigned GotHeaderEntriesNum = 0;
111 unsigned gotHeaderEntriesNum = 0;
116112
117 bool NeedsThunks = false;
113 bool needsThunks = false;
118114
119115 // A 4-byte field corresponding to one or more trap instructions, used to pad
120116 // executable OutputSections.
121 std::array<uint8_t, 4> TrapInstr;
117 std::array<uint8_t, 4> trapInstr;
122118
123119 // If a target needs to rewrite calls to __morestack to instead call
124120 // __morestack_non_split when a split-stack enabled caller calls a
125121 // non-split-stack callee this will return true. Otherwise returns false.
126 bool NeedsMoreStackNonSplit = true;
122 bool needsMoreStackNonSplit = true;
127123
128 virtual RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
129 RelExpr Expr) const;
130 virtual void relaxGot(uint8_t *Loc, uint64_t Val) const;
131 virtual void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const;
132 virtual void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
133 virtual void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
134 virtual void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const;
124 virtual RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
125 RelExpr expr) const;
126 virtual void relaxGot(uint8_t *loc, RelType type, uint64_t val) const;
127 virtual void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const;
128 virtual void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const;
129 virtual void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const;
130 virtual void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const;
135131
136132protected:
137133 // On FreeBSD x86_64 the first page cannot be mmaped.
138134 // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64
139135 // installs that is 65536, so the first 15 pages cannot be used.
140136 // Given that, the smallest value that can be used in here is 0x10000.
141 uint64_t DefaultImageBase = 0x10000;
137 uint64_t defaultImageBase = 0x10000;
142138};
143139
144140TargetInfo *getAArch64TargetInfo();
......@@ -151,108 +147,113 @@ TargetInfo *getPPC64TargetInfo();
151147TargetInfo *getPPCTargetInfo();
152148TargetInfo *getRISCVTargetInfo();
153149TargetInfo *getSPARCV9TargetInfo();
154TargetInfo *getX32TargetInfo();
155150TargetInfo *getX86TargetInfo();
156151TargetInfo *getX86_64TargetInfo();
157152template <class ELFT> TargetInfo *getMipsTargetInfo();
158153
159154struct ErrorPlace {
160 InputSectionBase *IS;
161 std::string Loc;
155 InputSectionBase *isec;
156 std::string loc;
162157};
163158
164159// Returns input section and corresponding source string for the given location.
165ErrorPlace getErrorPlace(const uint8_t *Loc);
160ErrorPlace getErrorPlace(const uint8_t *loc);
166161
167static inline std::string getErrorLocation(const uint8_t *Loc) {
168 return getErrorPlace(Loc).Loc;
162static inline std::string getErrorLocation(const uint8_t *loc) {
163 return getErrorPlace(loc).loc;
169164}
170165
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
166void writePPC32GlinkSection(uint8_t *buf, size_t numEntries);
167
168bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel,
169 uint8_t *bufLoc);
170unsigned getPPCDFormOp(unsigned secondaryOp);
171
172// In the PowerPC64 Elf V2 abi a function can have 2 entry points. The first
173// is a global entry point (GEP) which typically is used to initialize the TOC
173174// pointer in general purpose register 2. The second is a local entry
174175// point (LEP) which bypasses the TOC pointer initialization code. The
175176// offset between GEP and LEP is encoded in a function's st_other flags.
176177// This function will return the offset (in bytes) from the global entry-point
177178// to the local entry-point.
178unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther);
179unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther);
180
181// Returns true if a relocation is a small code model relocation that accesses
182// the .toc section.
183bool isPPC64SmallCodeModelTocReloc(RelType type);
179184
180185uint64_t getPPC64TocBase();
181uint64_t getAArch64Page(uint64_t Expr);
186uint64_t getAArch64Page(uint64_t expr);
182187
183extern TargetInfo *Target;
188extern const TargetInfo *target;
184189TargetInfo *getTarget();
185190
186template <class ELFT> bool isMipsPIC(const Defined *Sym);
191template <class ELFT> bool isMipsPIC(const Defined *sym);
187192
188static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V,
189 int64_t Min, uint64_t Max) {
190 ErrorPlace ErrPlace = getErrorPlace(Loc);
191 StringRef Hint;
192 if (ErrPlace.IS && ErrPlace.IS->Name.startswith(".debug"))
193 Hint = "; consider recompiling with -fdebug-types-section to reduce size "
193static inline void reportRangeError(uint8_t *loc, RelType type, const Twine &v,
194 int64_t min, uint64_t max) {
195 ErrorPlace errPlace = getErrorPlace(loc);
196 StringRef hint;
197 if (errPlace.isec && errPlace.isec->name.startswith(".debug"))
198 hint = "; consider recompiling with -fdebug-types-section to reduce size "
194199 "of debug sections";
195200
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);
199}
200
201inline unsigned getPltEntryOffset(unsigned Idx) {
202 return Target->PltHeaderSize + Target->PltEntrySize * Idx;
201 errorOrWarn(errPlace.loc + "relocation " + lld::toString(type) +
202 " out of range: " + v.str() + " is not in [" + Twine(min).str() +
203 ", " + Twine(max).str() + "]" + hint);
203204}
204205
205206// Make sure that V can be represented as an N bit signed integer.
206inline void checkInt(uint8_t *Loc, int64_t V, int N, RelType Type) {
207 if (V != llvm::SignExtend64(V, N))
208 reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N));
207inline void checkInt(uint8_t *loc, int64_t v, int n, RelType type) {
208 if (v != llvm::SignExtend64(v, n))
209 reportRangeError(loc, type, Twine(v), llvm::minIntN(n), llvm::maxIntN(n));
209210}
210211
211212// Make sure that V can be represented as an N bit unsigned integer.
212inline void checkUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
213 if ((V >> N) != 0)
214 reportRangeError(Loc, Type, Twine(V), 0, llvm::maxUIntN(N));
213inline void checkUInt(uint8_t *loc, uint64_t v, int n, RelType type) {
214 if ((v >> n) != 0)
215 reportRangeError(loc, type, Twine(v), 0, llvm::maxUIntN(n));
215216}
216217
217218// Make sure that V can be represented as an N bit signed or unsigned integer.
218inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
219inline void checkIntUInt(uint8_t *loc, uint64_t v, int n, RelType type) {
219220 // For the error message we should cast V to a signed integer so that error
220221 // messages show a small negative value rather than an extremely large one
221 if (V != (uint64_t)llvm::SignExtend64(V, N) && (V >> N) != 0)
222 reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N),
223 llvm::maxIntN(N));
222 if (v != (uint64_t)llvm::SignExtend64(v, n) && (v >> n) != 0)
223 reportRangeError(loc, type, Twine((int64_t)v), llvm::minIntN(n),
224 llvm::maxUIntN(n));
224225}
225226
226inline void checkAlignment(uint8_t *Loc, uint64_t V, int N, RelType Type) {
227 if ((V & (N - 1)) != 0)
228 error(getErrorLocation(Loc) + "improper alignment for relocation " +
229 lld::toString(Type) + ": 0x" + llvm::utohexstr(V) +
230 " is not aligned to " + Twine(N) + " bytes");
227inline void checkAlignment(uint8_t *loc, uint64_t v, int n, RelType type) {
228 if ((v & (n - 1)) != 0)
229 error(getErrorLocation(loc) + "improper alignment for relocation " +
230 lld::toString(type) + ": 0x" + llvm::utohexstr(v) +
231 " is not aligned to " + Twine(n) + " bytes");
231232}
232233
233234// Endianness-aware read/write.
234inline uint16_t read16(const void *P) {
235 return llvm::support::endian::read16(P, Config->Endianness);
235inline uint16_t read16(const void *p) {
236 return llvm::support::endian::read16(p, config->endianness);
236237}
237238
238inline uint32_t read32(const void *P) {
239 return llvm::support::endian::read32(P, Config->Endianness);
239inline uint32_t read32(const void *p) {
240 return llvm::support::endian::read32(p, config->endianness);
240241}
241242
242inline uint64_t read64(const void *P) {
243 return llvm::support::endian::read64(P, Config->Endianness);
243inline uint64_t read64(const void *p) {
244 return llvm::support::endian::read64(p, config->endianness);
244245}
245246
246inline void write16(void *P, uint16_t V) {
247 llvm::support::endian::write16(P, V, Config->Endianness);
247inline void write16(void *p, uint16_t v) {
248 llvm::support::endian::write16(p, v, config->endianness);
248249}
249250
250inline void write32(void *P, uint32_t V) {
251 llvm::support::endian::write32(P, V, Config->Endianness);
251inline void write32(void *p, uint32_t v) {
252 llvm::support::endian::write32(p, v, config->endianness);
252253}
253254
254inline void write64(void *P, uint64_t V) {
255 llvm::support::endian::write64(P, V, Config->Endianness);
255inline void write64(void *p, uint64_t v) {
256 llvm::support::endian::write64(p, v, config->endianness);
256257}
257258} // namespace elf
258259} // namespace lld
deps/lld/ELF/Thunks.cpp+450-359
......@@ -1,9 +1,8 @@
11//===- Thunks.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===---------------------------------------------------------------------===//
98//
......@@ -50,18 +49,18 @@ namespace {
5049// AArch64 long range Thunks
5150class AArch64ABSLongThunk final : public Thunk {
5251public:
53 AArch64ABSLongThunk(Symbol &Dest) : Thunk(Dest) {}
52 AArch64ABSLongThunk(Symbol &dest) : Thunk(dest) {}
5453 uint32_t size() override { return 16; }
55 void writeTo(uint8_t *Buf) override;
56 void addSymbols(ThunkSection &IS) override;
54 void writeTo(uint8_t *buf) override;
55 void addSymbols(ThunkSection &isec) override;
5756};
5857
5958class AArch64ADRPThunk final : public Thunk {
6059public:
61 AArch64ADRPThunk(Symbol &Dest) : Thunk(Dest) {}
60 AArch64ADRPThunk(Symbol &dest) : Thunk(dest) {}
6261 uint32_t size() override { return 12; }
63 void writeTo(uint8_t *Buf) override;
64 void addSymbols(ThunkSection &IS) override;
62 void writeTo(uint8_t *buf) override;
63 void addSymbols(ThunkSection &isec) override;
6564};
6665
6766// Base class for ARM thunks.
......@@ -74,18 +73,19 @@ public:
7473// if the target is in range, otherwise it creates a long thunk.
7574class ARMThunk : public Thunk {
7675public:
77 ARMThunk(Symbol &Dest) : Thunk(Dest) {}
76 ARMThunk(Symbol &dest) : Thunk(dest) {}
7877
79 bool mayUseShortThunk();
80 uint32_t size() override { return mayUseShortThunk() ? 4 : sizeLong(); }
81 void writeTo(uint8_t *Buf) override;
82 bool isCompatibleWith(RelType Type) const override;
78 bool getMayUseShortThunk();
79 uint32_t size() override { return getMayUseShortThunk() ? 4 : sizeLong(); }
80 void writeTo(uint8_t *buf) override;
81 bool isCompatibleWith(const InputSection &isec,
82 const Relocation &rel) const override;
8383
8484 // Returns the size of a long thunk.
8585 virtual uint32_t sizeLong() = 0;
8686
8787 // Writes a long thunk to Buf.
88 virtual void writeLong(uint8_t *Buf) = 0;
88 virtual void writeLong(uint8_t *buf) = 0;
8989
9090private:
9191 // This field tracks whether all previously considered layouts would allow
......@@ -94,7 +94,7 @@ private:
9494 // distance to the target. We do this because transitioning from long to short
9595 // can create layout oscillations in certain corner cases which would prevent
9696 // the layout from converging.
97 bool MayUseShortThunk = true;
97 bool mayUseShortThunk = true;
9898};
9999
100100// Base class for Thumb-2 thunks.
......@@ -103,60 +103,61 @@ private:
103103// which has a range of 16MB.
104104class ThumbThunk : public Thunk {
105105public:
106 ThumbThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; }
106 ThumbThunk(Symbol &dest) : Thunk(dest) { alignment = 2; }
107107
108 bool mayUseShortThunk();
109 uint32_t size() override { return mayUseShortThunk() ? 4 : sizeLong(); }
110 void writeTo(uint8_t *Buf) override;
111 bool isCompatibleWith(RelType Type) const override;
108 bool getMayUseShortThunk();
109 uint32_t size() override { return getMayUseShortThunk() ? 4 : sizeLong(); }
110 void writeTo(uint8_t *buf) override;
111 bool isCompatibleWith(const InputSection &isec,
112 const Relocation &rel) const override;
112113
113114 // Returns the size of a long thunk.
114115 virtual uint32_t sizeLong() = 0;
115116
116117 // Writes a long thunk to Buf.
117 virtual void writeLong(uint8_t *Buf) = 0;
118 virtual void writeLong(uint8_t *buf) = 0;
118119
119120private:
120121 // See comment in ARMThunk above.
121 bool MayUseShortThunk = true;
122 bool mayUseShortThunk = true;
122123};
123124
124125// Specific ARM Thunk implementations. The naming convention is:
125126// Source State, TargetState, Target Requirement, ABS or PI, Range
126127class ARMV7ABSLongThunk final : public ARMThunk {
127128public:
128 ARMV7ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
129 ARMV7ABSLongThunk(Symbol &dest) : ARMThunk(dest) {}
129130
130131 uint32_t sizeLong() override { return 12; }
131 void writeLong(uint8_t *Buf) override;
132 void addSymbols(ThunkSection &IS) override;
132 void writeLong(uint8_t *buf) override;
133 void addSymbols(ThunkSection &isec) override;
133134};
134135
135136class ARMV7PILongThunk final : public ARMThunk {
136137public:
137 ARMV7PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
138 ARMV7PILongThunk(Symbol &dest) : ARMThunk(dest) {}
138139
139140 uint32_t sizeLong() override { return 16; }
140 void writeLong(uint8_t *Buf) override;
141 void addSymbols(ThunkSection &IS) override;
141 void writeLong(uint8_t *buf) override;
142 void addSymbols(ThunkSection &isec) override;
142143};
143144
144145class ThumbV7ABSLongThunk final : public ThumbThunk {
145146public:
146 ThumbV7ABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
147 ThumbV7ABSLongThunk(Symbol &dest) : ThumbThunk(dest) {}
147148
148149 uint32_t sizeLong() override { return 10; }
149 void writeLong(uint8_t *Buf) override;
150 void addSymbols(ThunkSection &IS) override;
150 void writeLong(uint8_t *buf) override;
151 void addSymbols(ThunkSection &isec) override;
151152};
152153
153154class ThumbV7PILongThunk final : public ThumbThunk {
154155public:
155 ThumbV7PILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
156 ThumbV7PILongThunk(Symbol &dest) : ThumbThunk(dest) {}
156157
157158 uint32_t sizeLong() override { return 12; }
158 void writeLong(uint8_t *Buf) override;
159 void addSymbols(ThunkSection &IS) override;
159 void writeLong(uint8_t *buf) override;
160 void addSymbols(ThunkSection &isec) override;
160161};
161162
162163// Implementations of Thunks for older Arm architectures that do not support
......@@ -166,76 +167,96 @@ public:
166167// can result in a thunk
167168class ARMV5ABSLongThunk final : public ARMThunk {
168169public:
169 ARMV5ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
170 ARMV5ABSLongThunk(Symbol &dest) : ARMThunk(dest) {}
170171
171172 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;
173 void writeLong(uint8_t *buf) override;
174 void addSymbols(ThunkSection &isec) override;
175 bool isCompatibleWith(const InputSection &isec,
176 const Relocation &rel) const override;
175177};
176178
177179class ARMV5PILongThunk final : public ARMThunk {
178180public:
179 ARMV5PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
181 ARMV5PILongThunk(Symbol &dest) : ARMThunk(dest) {}
180182
181183 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;
184 void writeLong(uint8_t *buf) override;
185 void addSymbols(ThunkSection &isec) override;
186 bool isCompatibleWith(const InputSection &isec,
187 const Relocation &rel) const override;
185188};
186189
187190// Implementations of Thunks for Arm v6-M. Only Thumb instructions are permitted
188191class ThumbV6MABSLongThunk final : public ThumbThunk {
189192public:
190 ThumbV6MABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
193 ThumbV6MABSLongThunk(Symbol &dest) : ThumbThunk(dest) {}
191194
192195 uint32_t sizeLong() override { return 12; }
193 void writeLong(uint8_t *Buf) override;
194 void addSymbols(ThunkSection &IS) override;
196 void writeLong(uint8_t *buf) override;
197 void addSymbols(ThunkSection &isec) override;
195198};
196199
197200class ThumbV6MPILongThunk final : public ThumbThunk {
198201public:
199 ThumbV6MPILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
202 ThumbV6MPILongThunk(Symbol &dest) : ThumbThunk(dest) {}
200203
201204 uint32_t sizeLong() override { return 16; }
202 void writeLong(uint8_t *Buf) override;
203 void addSymbols(ThunkSection &IS) override;
205 void writeLong(uint8_t *buf) override;
206 void addSymbols(ThunkSection &isec) override;
204207};
205208
206209// MIPS LA25 thunk
207210class MipsThunk final : public Thunk {
208211public:
209 MipsThunk(Symbol &Dest) : Thunk(Dest) {}
212 MipsThunk(Symbol &dest) : Thunk(dest) {}
210213
211214 uint32_t size() override { return 16; }
212 void writeTo(uint8_t *Buf) override;
213 void addSymbols(ThunkSection &IS) override;
215 void writeTo(uint8_t *buf) override;
216 void addSymbols(ThunkSection &isec) override;
214217 InputSection *getTargetInputSection() const override;
215218};
216219
217220// microMIPS R2-R5 LA25 thunk
218221class MicroMipsThunk final : public Thunk {
219222public:
220 MicroMipsThunk(Symbol &Dest) : Thunk(Dest) {}
223 MicroMipsThunk(Symbol &dest) : Thunk(dest) {}
221224
222225 uint32_t size() override { return 14; }
223 void writeTo(uint8_t *Buf) override;
224 void addSymbols(ThunkSection &IS) override;
226 void writeTo(uint8_t *buf) override;
227 void addSymbols(ThunkSection &isec) override;
225228 InputSection *getTargetInputSection() const override;
226229};
227230
228231// microMIPS R6 LA25 thunk
229232class MicroMipsR6Thunk final : public Thunk {
230233public:
231 MicroMipsR6Thunk(Symbol &Dest) : Thunk(Dest) {}
234 MicroMipsR6Thunk(Symbol &dest) : Thunk(dest) {}
232235
233236 uint32_t size() override { return 12; }
234 void writeTo(uint8_t *Buf) override;
235 void addSymbols(ThunkSection &IS) override;
237 void writeTo(uint8_t *buf) override;
238 void addSymbols(ThunkSection &isec) override;
236239 InputSection *getTargetInputSection() const override;
237240};
238241
242class PPC32PltCallStub final : public Thunk {
243public:
244 PPC32PltCallStub(const InputSection &isec, const Relocation &rel, Symbol &dest)
245 : Thunk(dest), addend(rel.type == R_PPC_PLTREL24 ? rel.addend : 0),
246 file(isec.file) {}
247 uint32_t size() override { return 16; }
248 void writeTo(uint8_t *buf) override;
249 void addSymbols(ThunkSection &isec) override;
250 bool isCompatibleWith(const InputSection &isec, const Relocation &rel) const override;
251
252private:
253 // For R_PPC_PLTREL24, this records the addend, which will be used to decide
254 // the offsets in the call stub.
255 uint32_t addend;
256
257 // Records the call site of the call stub.
258 const InputFile *file;
259};
239260
240261// PPC64 Plt call stubs.
241262// Any call site that needs to call through a plt entry needs a call stub in
......@@ -247,10 +268,10 @@ public:
247268// 3) Transfering control to the target function through an indirect branch.
248269class PPC64PltCallStub final : public Thunk {
249270public:
250 PPC64PltCallStub(Symbol &Dest) : Thunk(Dest) {}
271 PPC64PltCallStub(Symbol &dest) : Thunk(dest) {}
251272 uint32_t size() override { return 20; }
252 void writeTo(uint8_t *Buf) override;
253 void addSymbols(ThunkSection &IS) override;
273 void writeTo(uint8_t *buf) override;
274 void addSymbols(ThunkSection &isec) override;
254275};
255276
256277// A bl instruction uses a signed 24 bit offset, with an implicit 4 byte
......@@ -264,74 +285,75 @@ public:
264285class PPC64LongBranchThunk : public Thunk {
265286public:
266287 uint32_t size() override { return 16; }
267 void writeTo(uint8_t *Buf) override;
268 void addSymbols(ThunkSection &IS) override;
288 void writeTo(uint8_t *buf) override;
289 void addSymbols(ThunkSection &isec) override;
269290
270291protected:
271 PPC64LongBranchThunk(Symbol &Dest) : Thunk(Dest) {}
292 PPC64LongBranchThunk(Symbol &dest) : Thunk(dest) {}
272293};
273294
274295class PPC64PILongBranchThunk final : public PPC64LongBranchThunk {
275296public:
276 PPC64PILongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
277 assert(!Dest.IsPreemptible);
278 if (Dest.isInPPC64Branchlt())
297 PPC64PILongBranchThunk(Symbol &dest) : PPC64LongBranchThunk(dest) {
298 assert(!dest.isPreemptible);
299 if (dest.isInPPC64Branchlt())
279300 return;
280301
281 In.PPC64LongBranchTarget->addEntry(Dest);
282 In.RelaDyn->addReloc({Target->RelativeRel, In.PPC64LongBranchTarget,
283 Dest.getPPC64LongBranchOffset(), true, &Dest,
284 getPPC64GlobalEntryToLocalEntryOffset(Dest.StOther)});
302 in.ppc64LongBranchTarget->addEntry(dest);
303 mainPart->relaDyn->addReloc(
304 {target->relativeRel, in.ppc64LongBranchTarget,
305 dest.getPPC64LongBranchOffset(), true, &dest,
306 getPPC64GlobalEntryToLocalEntryOffset(dest.stOther)});
285307 }
286308};
287309
288310class PPC64PDLongBranchThunk final : public PPC64LongBranchThunk {
289311public:
290 PPC64PDLongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
291 if (!Dest.isInPPC64Branchlt())
292 In.PPC64LongBranchTarget->addEntry(Dest);
312 PPC64PDLongBranchThunk(Symbol &dest) : PPC64LongBranchThunk(dest) {
313 if (!dest.isInPPC64Branchlt())
314 in.ppc64LongBranchTarget->addEntry(dest);
293315 }
294316};
295317
296318} // end anonymous namespace
297319
298Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
299 InputSectionBase &Section) {
300 Defined *D = addSyntheticLocal(Name, Type, Value, /*Size=*/0, Section);
301 Syms.push_back(D);
302 return D;
320Defined *Thunk::addSymbol(StringRef name, uint8_t type, uint64_t value,
321 InputSectionBase &section) {
322 Defined *d = addSyntheticLocal(name, type, value, /*size=*/0, section);
323 syms.push_back(d);
324 return d;
303325}
304326
305void Thunk::setOffset(uint64_t NewOffset) {
306 for (Defined *D : Syms)
307 D->Value = D->Value - Offset + NewOffset;
308 Offset = NewOffset;
327void Thunk::setOffset(uint64_t newOffset) {
328 for (Defined *d : syms)
329 d->value = d->value - offset + newOffset;
330 offset = newOffset;
309331}
310332
311333// AArch64 long range Thunks
312334
313static uint64_t getAArch64ThunkDestVA(const Symbol &S) {
314 uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
315 return V;
335static uint64_t getAArch64ThunkDestVA(const Symbol &s) {
336 uint64_t v = s.isInPlt() ? s.getPltVA() : s.getVA();
337 return v;
316338}
317339
318void AArch64ABSLongThunk::writeTo(uint8_t *Buf) {
319 const uint8_t Data[] = {
340void AArch64ABSLongThunk::writeTo(uint8_t *buf) {
341 const uint8_t data[] = {
320342 0x50, 0x00, 0x00, 0x58, // ldr x16, L0
321343 0x00, 0x02, 0x1f, 0xd6, // br x16
322344 0x00, 0x00, 0x00, 0x00, // L0: .xword S
323345 0x00, 0x00, 0x00, 0x00,
324346 };
325 uint64_t S = getAArch64ThunkDestVA(Destination);
326 memcpy(Buf, Data, sizeof(Data));
327 Target->relocateOne(Buf + 8, R_AARCH64_ABS64, S);
347 uint64_t s = getAArch64ThunkDestVA(destination);
348 memcpy(buf, data, sizeof(data));
349 target->relocateOne(buf + 8, R_AARCH64_ABS64, s);
328350}
329351
330void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) {
331 addSymbol(Saver.save("__AArch64AbsLongThunk_" + Destination.getName()),
332 STT_FUNC, 0, IS);
333 addSymbol("$x", STT_NOTYPE, 0, IS);
334 addSymbol("$d", STT_NOTYPE, 8, IS);
352void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) {
353 addSymbol(saver.save("__AArch64AbsLongThunk_" + destination.getName()),
354 STT_FUNC, 0, isec);
355 addSymbol("$x", STT_NOTYPE, 0, isec);
356 addSymbol("$d", STT_NOTYPE, 8, isec);
335357}
336358
337359// This Thunk has a maximum range of 4Gb, this is sufficient for all programs
......@@ -339,259 +361,263 @@ void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) {
339361// clang and gcc do not support the large code model for position independent
340362// code so it is safe to use this for position independent thunks without
341363// worrying about the destination being more than 4Gb away.
342void AArch64ADRPThunk::writeTo(uint8_t *Buf) {
343 const uint8_t Data[] = {
364void AArch64ADRPThunk::writeTo(uint8_t *buf) {
365 const uint8_t data[] = {
344366 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest R_AARCH64_ADR_PREL_PG_HI21(Dest)
345367 0x10, 0x02, 0x00, 0x91, // add x16, x16, R_AARCH64_ADD_ABS_LO12_NC(Dest)
346368 0x00, 0x02, 0x1f, 0xd6, // br x16
347369 };
348 uint64_t S = getAArch64ThunkDestVA(Destination);
349 uint64_t P = getThunkTargetSym()->getVA();
350 memcpy(Buf, Data, sizeof(Data));
351 Target->relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
352 getAArch64Page(S) - getAArch64Page(P));
353 Target->relocateOne(Buf + 4, R_AARCH64_ADD_ABS_LO12_NC, S);
370 uint64_t s = getAArch64ThunkDestVA(destination);
371 uint64_t p = getThunkTargetSym()->getVA();
372 memcpy(buf, data, sizeof(data));
373 target->relocateOne(buf, R_AARCH64_ADR_PREL_PG_HI21,
374 getAArch64Page(s) - getAArch64Page(p));
375 target->relocateOne(buf + 4, R_AARCH64_ADD_ABS_LO12_NC, s);
354376}
355377
356void AArch64ADRPThunk::addSymbols(ThunkSection &IS) {
357 addSymbol(Saver.save("__AArch64ADRPThunk_" + Destination.getName()), STT_FUNC,
358 0, IS);
359 addSymbol("$x", STT_NOTYPE, 0, IS);
378void AArch64ADRPThunk::addSymbols(ThunkSection &isec) {
379 addSymbol(saver.save("__AArch64ADRPThunk_" + destination.getName()), STT_FUNC,
380 0, isec);
381 addSymbol("$x", STT_NOTYPE, 0, isec);
360382}
361383
362384// ARM Target Thunks
363static uint64_t getARMThunkDestVA(const Symbol &S) {
364 uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
365 return SignExtend64<32>(V);
385static uint64_t getARMThunkDestVA(const Symbol &s) {
386 uint64_t v = s.isInPlt() ? s.getPltVA() : s.getVA();
387 return SignExtend64<32>(v);
366388}
367389
368390// This function returns true if the target is not Thumb and is within 2^26, and
369// it has not previously returned false (see comment for MayUseShortThunk).
370bool ARMThunk::mayUseShortThunk() {
371 if (!MayUseShortThunk)
391// it has not previously returned false (see comment for mayUseShortThunk).
392bool ARMThunk::getMayUseShortThunk() {
393 if (!mayUseShortThunk)
372394 return false;
373 uint64_t S = getARMThunkDestVA(Destination);
374 if (S & 1) {
375 MayUseShortThunk = false;
395 uint64_t s = getARMThunkDestVA(destination);
396 if (s & 1) {
397 mayUseShortThunk = false;
376398 return false;
377399 }
378 uint64_t P = getThunkTargetSym()->getVA();
379 int64_t Offset = S - P - 8;
380 MayUseShortThunk = llvm::isInt<26>(Offset);
381 return MayUseShortThunk;
400 uint64_t p = getThunkTargetSym()->getVA();
401 int64_t offset = s - p - 8;
402 mayUseShortThunk = llvm::isInt<26>(offset);
403 return mayUseShortThunk;
382404}
383405
384void ARMThunk::writeTo(uint8_t *Buf) {
385 if (!mayUseShortThunk()) {
386 writeLong(Buf);
406void ARMThunk::writeTo(uint8_t *buf) {
407 if (!getMayUseShortThunk()) {
408 writeLong(buf);
387409 return;
388410 }
389411
390 uint64_t S = getARMThunkDestVA(Destination);
391 uint64_t P = getThunkTargetSym()->getVA();
392 int64_t Offset = S - P - 8;
393 const uint8_t Data[] = {
412 uint64_t s = getARMThunkDestVA(destination);
413 uint64_t p = getThunkTargetSym()->getVA();
414 int64_t offset = s - p - 8;
415 const uint8_t data[] = {
394416 0x00, 0x00, 0x00, 0xea, // b S
395417 };
396 memcpy(Buf, Data, sizeof(Data));
397 Target->relocateOne(Buf, R_ARM_JUMP24, Offset);
418 memcpy(buf, data, sizeof(data));
419 target->relocateOne(buf, R_ARM_JUMP24, offset);
398420}
399421
400bool ARMThunk::isCompatibleWith(RelType Type) const {
422bool ARMThunk::isCompatibleWith(const InputSection &isec,
423 const Relocation &rel) const {
401424 // Thumb branch relocations can't use BLX
402 return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24;
425 return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
403426}
404427
405428// This function returns true if the target is Thumb and is within 2^25, and
406// it has not previously returned false (see comment for MayUseShortThunk).
407bool ThumbThunk::mayUseShortThunk() {
408 if (!MayUseShortThunk)
429// it has not previously returned false (see comment for mayUseShortThunk).
430bool ThumbThunk::getMayUseShortThunk() {
431 if (!mayUseShortThunk)
409432 return false;
410 uint64_t S = getARMThunkDestVA(Destination);
411 if ((S & 1) == 0) {
412 MayUseShortThunk = false;
433 uint64_t s = getARMThunkDestVA(destination);
434 if ((s & 1) == 0) {
435 mayUseShortThunk = false;
413436 return false;
414437 }
415 uint64_t P = getThunkTargetSym()->getVA() & ~1;
416 int64_t Offset = S - P - 4;
417 MayUseShortThunk = llvm::isInt<25>(Offset);
418 return MayUseShortThunk;
438 uint64_t p = getThunkTargetSym()->getVA() & ~1;
439 int64_t offset = s - p - 4;
440 mayUseShortThunk = llvm::isInt<25>(offset);
441 return mayUseShortThunk;
419442}
420443
421void ThumbThunk::writeTo(uint8_t *Buf) {
422 if (!mayUseShortThunk()) {
423 writeLong(Buf);
444void ThumbThunk::writeTo(uint8_t *buf) {
445 if (!getMayUseShortThunk()) {
446 writeLong(buf);
424447 return;
425448 }
426449
427 uint64_t S = getARMThunkDestVA(Destination);
428 uint64_t P = getThunkTargetSym()->getVA();
429 int64_t Offset = S - P - 4;
430 const uint8_t Data[] = {
450 uint64_t s = getARMThunkDestVA(destination);
451 uint64_t p = getThunkTargetSym()->getVA();
452 int64_t offset = s - p - 4;
453 const uint8_t data[] = {
431454 0x00, 0xf0, 0x00, 0xb0, // b.w S
432455 };
433 memcpy(Buf, Data, sizeof(Data));
434 Target->relocateOne(Buf, R_ARM_THM_JUMP24, Offset);
456 memcpy(buf, data, sizeof(data));
457 target->relocateOne(buf, R_ARM_THM_JUMP24, offset);
435458}
436459
437bool ThumbThunk::isCompatibleWith(RelType Type) const {
460bool ThumbThunk::isCompatibleWith(const InputSection &isec,
461 const Relocation &rel) const {
438462 // ARM branch relocations can't use BLX
439 return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32;
463 return rel.type != R_ARM_JUMP24 && rel.type != R_ARM_PC24 && rel.type != R_ARM_PLT32;
440464}
441465
442void ARMV7ABSLongThunk::writeLong(uint8_t *Buf) {
443 const uint8_t Data[] = {
466void ARMV7ABSLongThunk::writeLong(uint8_t *buf) {
467 const uint8_t data[] = {
444468 0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S
445469 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S
446470 0x1c, 0xff, 0x2f, 0xe1, // bx ip
447471 };
448 uint64_t S = getARMThunkDestVA(Destination);
449 memcpy(Buf, Data, sizeof(Data));
450 Target->relocateOne(Buf, R_ARM_MOVW_ABS_NC, S);
451 Target->relocateOne(Buf + 4, R_ARM_MOVT_ABS, S);
472 uint64_t s = getARMThunkDestVA(destination);
473 memcpy(buf, data, sizeof(data));
474 target->relocateOne(buf, R_ARM_MOVW_ABS_NC, s);
475 target->relocateOne(buf + 4, R_ARM_MOVT_ABS, s);
452476}
453477
454void ARMV7ABSLongThunk::addSymbols(ThunkSection &IS) {
455 addSymbol(Saver.save("__ARMv7ABSLongThunk_" + Destination.getName()),
456 STT_FUNC, 0, IS);
457 addSymbol("$a", STT_NOTYPE, 0, IS);
478void ARMV7ABSLongThunk::addSymbols(ThunkSection &isec) {
479 addSymbol(saver.save("__ARMv7ABSLongThunk_" + destination.getName()),
480 STT_FUNC, 0, isec);
481 addSymbol("$a", STT_NOTYPE, 0, isec);
458482}
459483
460void ThumbV7ABSLongThunk::writeLong(uint8_t *Buf) {
461 const uint8_t Data[] = {
484void ThumbV7ABSLongThunk::writeLong(uint8_t *buf) {
485 const uint8_t data[] = {
462486 0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S
463487 0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S
464488 0x60, 0x47, // bx ip
465489 };
466 uint64_t S = getARMThunkDestVA(Destination);
467 memcpy(Buf, Data, sizeof(Data));
468 Target->relocateOne(Buf, R_ARM_THM_MOVW_ABS_NC, S);
469 Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_ABS, S);
490 uint64_t s = getARMThunkDestVA(destination);
491 memcpy(buf, data, sizeof(data));
492 target->relocateOne(buf, R_ARM_THM_MOVW_ABS_NC, s);
493 target->relocateOne(buf + 4, R_ARM_THM_MOVT_ABS, s);
470494}
471495
472void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) {
473 addSymbol(Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()),
474 STT_FUNC, 1, IS);
475 addSymbol("$t", STT_NOTYPE, 0, IS);
496void ThumbV7ABSLongThunk::addSymbols(ThunkSection &isec) {
497 addSymbol(saver.save("__Thumbv7ABSLongThunk_" + destination.getName()),
498 STT_FUNC, 1, isec);
499 addSymbol("$t", STT_NOTYPE, 0, isec);
476500}
477501
478void ARMV7PILongThunk::writeLong(uint8_t *Buf) {
479 const uint8_t Data[] = {
502void ARMV7PILongThunk::writeLong(uint8_t *buf) {
503 const uint8_t data[] = {
480504 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) + 8)
481505 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P) + 8)
482506 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
483507 0x1c, 0xff, 0x2f, 0xe1, // bx ip
484508 };
485 uint64_t S = getARMThunkDestVA(Destination);
486 uint64_t P = getThunkTargetSym()->getVA();
487 int64_t Offset = S - P - 16;
488 memcpy(Buf, Data, sizeof(Data));
489 Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);
490 Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);
509 uint64_t s = getARMThunkDestVA(destination);
510 uint64_t p = getThunkTargetSym()->getVA();
511 int64_t offset = s - p - 16;
512 memcpy(buf, data, sizeof(data));
513 target->relocateOne(buf, R_ARM_MOVW_PREL_NC, offset);
514 target->relocateOne(buf + 4, R_ARM_MOVT_PREL, offset);
491515}
492516
493void ARMV7PILongThunk::addSymbols(ThunkSection &IS) {
494 addSymbol(Saver.save("__ARMV7PILongThunk_" + Destination.getName()), STT_FUNC,
495 0, IS);
496 addSymbol("$a", STT_NOTYPE, 0, IS);
517void ARMV7PILongThunk::addSymbols(ThunkSection &isec) {
518 addSymbol(saver.save("__ARMV7PILongThunk_" + destination.getName()), STT_FUNC,
519 0, isec);
520 addSymbol("$a", STT_NOTYPE, 0, isec);
497521}
498522
499void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {
500 const uint8_t Data[] = {
523void ThumbV7PILongThunk::writeLong(uint8_t *buf) {
524 const uint8_t data[] = {
501525 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
502526 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4)
503527 0xfc, 0x44, // L1: add ip, pc
504528 0x60, 0x47, // bx ip
505529 };
506 uint64_t S = getARMThunkDestVA(Destination);
507 uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
508 int64_t Offset = S - P - 12;
509 memcpy(Buf, Data, sizeof(Data));
510 Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);
511 Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);
530 uint64_t s = getARMThunkDestVA(destination);
531 uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
532 int64_t offset = s - p - 12;
533 memcpy(buf, data, sizeof(data));
534 target->relocateOne(buf, R_ARM_THM_MOVW_PREL_NC, offset);
535 target->relocateOne(buf + 4, R_ARM_THM_MOVT_PREL, offset);
512536}
513537
514void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {
515 addSymbol(Saver.save("__ThumbV7PILongThunk_" + Destination.getName()),
516 STT_FUNC, 1, IS);
517 addSymbol("$t", STT_NOTYPE, 0, IS);
538void ThumbV7PILongThunk::addSymbols(ThunkSection &isec) {
539 addSymbol(saver.save("__ThumbV7PILongThunk_" + destination.getName()),
540 STT_FUNC, 1, isec);
541 addSymbol("$t", STT_NOTYPE, 0, isec);
518542}
519543
520void ARMV5ABSLongThunk::writeLong(uint8_t *Buf) {
521 const uint8_t Data[] = {
544void ARMV5ABSLongThunk::writeLong(uint8_t *buf) {
545 const uint8_t data[] = {
522546 0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc,#-4] ; L1
523547 0x00, 0x00, 0x00, 0x00, // L1: .word S
524548 };
525 memcpy(Buf, Data, sizeof(Data));
526 Target->relocateOne(Buf + 4, R_ARM_ABS32, getARMThunkDestVA(Destination));
549 memcpy(buf, data, sizeof(data));
550 target->relocateOne(buf + 4, R_ARM_ABS32, getARMThunkDestVA(destination));
527551}
528552
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);
553void ARMV5ABSLongThunk::addSymbols(ThunkSection &isec) {
554 addSymbol(saver.save("__ARMv5ABSLongThunk_" + destination.getName()),
555 STT_FUNC, 0, isec);
556 addSymbol("$a", STT_NOTYPE, 0, isec);
557 addSymbol("$d", STT_NOTYPE, 4, isec);
534558}
535559
536bool ARMV5ABSLongThunk::isCompatibleWith(uint32_t RelocType) const {
560bool ARMV5ABSLongThunk::isCompatibleWith(const InputSection &isec,
561 const Relocation &rel) const {
537562 // Thumb branch relocations can't use BLX
538 return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
563 return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
539564}
540565
541void ARMV5PILongThunk::writeLong(uint8_t *Buf) {
542 const uint8_t Data[] = {
566void ARMV5PILongThunk::writeLong(uint8_t *buf) {
567 const uint8_t data[] = {
543568 0x04, 0xc0, 0x9f, 0xe5, // P: ldr ip, [pc,#4] ; L2
544569 0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
545570 0x1c, 0xff, 0x2f, 0xe1, // bx ip
546571 0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
547572 };
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);
573 uint64_t s = getARMThunkDestVA(destination);
574 uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
575 memcpy(buf, data, sizeof(data));
576 target->relocateOne(buf + 12, R_ARM_REL32, s - p - 12);
552577}
553578
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);
579void ARMV5PILongThunk::addSymbols(ThunkSection &isec) {
580 addSymbol(saver.save("__ARMV5PILongThunk_" + destination.getName()), STT_FUNC,
581 0, isec);
582 addSymbol("$a", STT_NOTYPE, 0, isec);
583 addSymbol("$d", STT_NOTYPE, 12, isec);
559584}
560585
561bool ARMV5PILongThunk::isCompatibleWith(uint32_t RelocType) const {
586bool ARMV5PILongThunk::isCompatibleWith(const InputSection &isec,
587 const Relocation &rel) const {
562588 // Thumb branch relocations can't use BLX
563 return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
589 return rel.type != R_ARM_THM_JUMP19 && rel.type != R_ARM_THM_JUMP24;
564590}
565591
566void ThumbV6MABSLongThunk::writeLong(uint8_t *Buf) {
592void ThumbV6MABSLongThunk::writeLong(uint8_t *buf) {
567593 // Most Thumb instructions cannot access the high registers r8 - r15. As the
568594 // only register we can corrupt is r12 we must instead spill a low register
569595 // to the stack to use as a scratch register. We push r1 even though we
570596 // don't need to get some space to use for the return address.
571 const uint8_t Data[] = {
597 const uint8_t data[] = {
572598 0x03, 0xb4, // push {r0, r1} ; Obtain scratch registers
573599 0x01, 0x48, // ldr r0, [pc, #4] ; L1
574600 0x01, 0x90, // str r0, [sp, #4] ; SP + 4 = S
575601 0x01, 0xbd, // pop {r0, pc} ; restore r0 and branch to dest
576602 0x00, 0x00, 0x00, 0x00 // L1: .word S
577603 };
578 uint64_t S = getARMThunkDestVA(Destination);
579 memcpy(Buf, Data, sizeof(Data));
580 Target->relocateOne(Buf + 8, R_ARM_ABS32, S);
604 uint64_t s = getARMThunkDestVA(destination);
605 memcpy(buf, data, sizeof(data));
606 target->relocateOne(buf + 8, R_ARM_ABS32, s);
581607}
582608
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);
609void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) {
610 addSymbol(saver.save("__Thumbv6MABSLongThunk_" + destination.getName()),
611 STT_FUNC, 1, isec);
612 addSymbol("$t", STT_NOTYPE, 0, isec);
613 addSymbol("$d", STT_NOTYPE, 8, isec);
588614}
589615
590void ThumbV6MPILongThunk::writeLong(uint8_t *Buf) {
616void ThumbV6MPILongThunk::writeLong(uint8_t *buf) {
591617 // Most Thumb instructions cannot access the high registers r8 - r15. As the
592618 // only register we can corrupt is ip (r12) we must instead spill a low
593619 // register to the stack to use as a scratch register.
594 const uint8_t Data[] = {
620 const uint8_t data[] = {
595621 0x01, 0xb4, // P: push {r0} ; Obtain scratch register
596622 0x02, 0x48, // ldr r0, [pc, #8] ; L2
597623 0x84, 0x46, // mov ip, r0 ; high to low register
......@@ -600,131 +626,185 @@ void ThumbV6MPILongThunk::writeLong(uint8_t *Buf) {
600626 0xc0, 0x46, // nop ; pad to 4-byte boundary
601627 0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 4)
602628 };
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);
629 uint64_t s = getARMThunkDestVA(destination);
630 uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
631 memcpy(buf, data, sizeof(data));
632 target->relocateOne(buf + 12, R_ARM_REL32, s - p - 12);
607633}
608634
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);
635void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) {
636 addSymbol(saver.save("__Thumbv6MPILongThunk_" + destination.getName()),
637 STT_FUNC, 1, isec);
638 addSymbol("$t", STT_NOTYPE, 0, isec);
639 addSymbol("$d", STT_NOTYPE, 12, isec);
614640}
615641
616642// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
617void MipsThunk::writeTo(uint8_t *Buf) {
618 uint64_t S = Destination.getVA();
619 write32(Buf, 0x3c190000); // lui $25, %hi(func)
620 write32(Buf + 4, 0x08000000 | (S >> 2)); // j func
621 write32(Buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
622 write32(Buf + 12, 0x00000000); // nop
623 Target->relocateOne(Buf, R_MIPS_HI16, S);
624 Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
643void MipsThunk::writeTo(uint8_t *buf) {
644 uint64_t s = destination.getVA();
645 write32(buf, 0x3c190000); // lui $25, %hi(func)
646 write32(buf + 4, 0x08000000 | (s >> 2)); // j func
647 write32(buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
648 write32(buf + 12, 0x00000000); // nop
649 target->relocateOne(buf, R_MIPS_HI16, s);
650 target->relocateOne(buf + 8, R_MIPS_LO16, s);
625651}
626652
627void MipsThunk::addSymbols(ThunkSection &IS) {
628 addSymbol(Saver.save("__LA25Thunk_" + Destination.getName()), STT_FUNC, 0,
629 IS);
653void MipsThunk::addSymbols(ThunkSection &isec) {
654 addSymbol(saver.save("__LA25Thunk_" + destination.getName()), STT_FUNC, 0,
655 isec);
630656}
631657
632658InputSection *MipsThunk::getTargetInputSection() const {
633 auto &DR = cast<Defined>(Destination);
634 return dyn_cast<InputSection>(DR.Section);
659 auto &dr = cast<Defined>(destination);
660 return dyn_cast<InputSection>(dr.section);
635661}
636662
637663// Write microMIPS R2-R5 LA25 thunk code
638664// to call PIC function from the non-PIC one.
639void MicroMipsThunk::writeTo(uint8_t *Buf) {
640 uint64_t S = Destination.getVA() | 1;
641 write16(Buf, 0x41b9); // lui $25, %hi(func)
642 write16(Buf + 4, 0xd400); // j func
643 write16(Buf + 8, 0x3339); // addiu $25, $25, %lo(func)
644 write16(Buf + 12, 0x0c00); // nop
645 Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
646 Target->relocateOne(Buf + 4, R_MICROMIPS_26_S1, S);
647 Target->relocateOne(Buf + 8, R_MICROMIPS_LO16, S);
665void MicroMipsThunk::writeTo(uint8_t *buf) {
666 uint64_t s = destination.getVA();
667 write16(buf, 0x41b9); // lui $25, %hi(func)
668 write16(buf + 4, 0xd400); // j func
669 write16(buf + 8, 0x3339); // addiu $25, $25, %lo(func)
670 write16(buf + 12, 0x0c00); // nop
671 target->relocateOne(buf, R_MICROMIPS_HI16, s);
672 target->relocateOne(buf + 4, R_MICROMIPS_26_S1, s);
673 target->relocateOne(buf + 8, R_MICROMIPS_LO16, s);
648674}
649675
650void MicroMipsThunk::addSymbols(ThunkSection &IS) {
651 Defined *D = addSymbol(
652 Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS);
653 D->StOther |= STO_MIPS_MICROMIPS;
676void MicroMipsThunk::addSymbols(ThunkSection &isec) {
677 Defined *d = addSymbol(
678 saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec);
679 d->stOther |= STO_MIPS_MICROMIPS;
654680}
655681
656682InputSection *MicroMipsThunk::getTargetInputSection() const {
657 auto &DR = cast<Defined>(Destination);
658 return dyn_cast<InputSection>(DR.Section);
683 auto &dr = cast<Defined>(destination);
684 return dyn_cast<InputSection>(dr.section);
659685}
660686
661687// Write microMIPS R6 LA25 thunk code
662688// to call PIC function from the non-PIC one.
663void MicroMipsR6Thunk::writeTo(uint8_t *Buf) {
664 uint64_t S = Destination.getVA() | 1;
665 uint64_t P = getThunkTargetSym()->getVA();
666 write16(Buf, 0x1320); // lui $25, %hi(func)
667 write16(Buf + 4, 0x3339); // addiu $25, $25, %lo(func)
668 write16(Buf + 8, 0x9400); // bc func
669 Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
670 Target->relocateOne(Buf + 4, R_MICROMIPS_LO16, S);
671 Target->relocateOne(Buf + 8, R_MICROMIPS_PC26_S1, S - P - 12);
689void MicroMipsR6Thunk::writeTo(uint8_t *buf) {
690 uint64_t s = destination.getVA();
691 uint64_t p = getThunkTargetSym()->getVA();
692 write16(buf, 0x1320); // lui $25, %hi(func)
693 write16(buf + 4, 0x3339); // addiu $25, $25, %lo(func)
694 write16(buf + 8, 0x9400); // bc func
695 target->relocateOne(buf, R_MICROMIPS_HI16, s);
696 target->relocateOne(buf + 4, R_MICROMIPS_LO16, s);
697 target->relocateOne(buf + 8, R_MICROMIPS_PC26_S1, s - p - 12);
672698}
673699
674void MicroMipsR6Thunk::addSymbols(ThunkSection &IS) {
675 Defined *D = addSymbol(
676 Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS);
677 D->StOther |= STO_MIPS_MICROMIPS;
700void MicroMipsR6Thunk::addSymbols(ThunkSection &isec) {
701 Defined *d = addSymbol(
702 saver.save("__microLA25Thunk_" + destination.getName()), STT_FUNC, 0, isec);
703 d->stOther |= STO_MIPS_MICROMIPS;
678704}
679705
680706InputSection *MicroMipsR6Thunk::getTargetInputSection() const {
681 auto &DR = cast<Defined>(Destination);
682 return dyn_cast<InputSection>(DR.Section);
707 auto &dr = cast<Defined>(destination);
708 return dyn_cast<InputSection>(dr.section);
683709}
684710
685static void writePPCLoadAndBranch(uint8_t *Buf, int64_t Offset) {
686 uint16_t OffHa = (Offset + 0x8000) >> 16;
687 uint16_t OffLo = Offset & 0xffff;
711void PPC32PltCallStub::writeTo(uint8_t *buf) {
712 if (!config->isPic) {
713 uint64_t va = destination.getGotPltVA();
714 write32(buf + 0, 0x3d600000 | (va + 0x8000) >> 16); // lis r11,ha
715 write32(buf + 4, 0x816b0000 | (uint16_t)va); // lwz r11,l(r11)
716 write32(buf + 8, 0x7d6903a6); // mtctr r11
717 write32(buf + 12, 0x4e800420); // bctr
718 return;
719 }
720 uint32_t offset;
721 if (addend >= 0x8000) {
722 // The stub loads an address relative to r30 (.got2+Addend). Addend is
723 // almost always 0x8000. The address of .got2 is different in another object
724 // file, so a stub cannot be shared.
725 offset = destination.getGotPltVA() - (in.ppc32Got2->getParent()->getVA() +
726 file->ppc32Got2OutSecOff + addend);
727 } else {
728 // The stub loads an address relative to _GLOBAL_OFFSET_TABLE_ (which is
729 // currently the address of .got).
730 offset = destination.getGotPltVA() - in.got->getVA();
731 }
732 uint16_t ha = (offset + 0x8000) >> 16, l = (uint16_t)offset;
733 if (ha == 0) {
734 write32(buf + 0, 0x817e0000 | l); // lwz r11,l(r30)
735 write32(buf + 4, 0x7d6903a6); // mtctr r11
736 write32(buf + 8, 0x4e800420); // bctr
737 write32(buf + 12, 0x60000000); // nop
738 } else {
739 write32(buf + 0, 0x3d7e0000 | ha); // addis r11,r30,ha
740 write32(buf + 4, 0x816b0000 | l); // lwz r11,l(r11)
741 write32(buf + 8, 0x7d6903a6); // mtctr r11
742 write32(buf + 12, 0x4e800420); // bctr
743 }
744}
745
746void PPC32PltCallStub::addSymbols(ThunkSection &isec) {
747 std::string buf;
748 raw_string_ostream os(buf);
749 os << format_hex_no_prefix(addend, 8);
750 if (!config->isPic)
751 os << ".plt_call32.";
752 else if (addend >= 0x8000)
753 os << ".got2.plt_pic32.";
754 else
755 os << ".plt_pic32.";
756 os << destination.getName();
757 addSymbol(saver.save(os.str()), STT_FUNC, 0, isec);
758}
759
760bool PPC32PltCallStub::isCompatibleWith(const InputSection &isec,
761 const Relocation &rel) const {
762 return !config->isPic || (isec.file == file && rel.addend == addend);
763}
688764
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
765static void writePPCLoadAndBranch(uint8_t *buf, int64_t offset) {
766 uint16_t offHa = (offset + 0x8000) >> 16;
767 uint16_t offLo = offset & 0xffff;
768
769 write32(buf + 0, 0x3d820000 | offHa); // addis r12, r2, OffHa
770 write32(buf + 4, 0xe98c0000 | offLo); // ld r12, OffLo(r12)
771 write32(buf + 8, 0x7d8903a6); // mtctr r12
772 write32(buf + 12, 0x4e800420); // bctr
693773}
694774
695void PPC64PltCallStub::writeTo(uint8_t *Buf) {
696 int64_t Offset = Destination.getGotPltVA() - getPPC64TocBase();
775void PPC64PltCallStub::writeTo(uint8_t *buf) {
776 int64_t offset = destination.getGotPltVA() - getPPC64TocBase();
697777 // 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);
778 write32(buf + 0, 0xf8410018); // std r2,24(r1)
779 writePPCLoadAndBranch(buf + 4, offset);
700780}
701781
702void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
703 Defined *S = addSymbol(Saver.save("__plt_" + Destination.getName()), STT_FUNC,
704 0, IS);
705 S->NeedsTocRestore = true;
782void PPC64PltCallStub::addSymbols(ThunkSection &isec) {
783 Defined *s = addSymbol(saver.save("__plt_" + destination.getName()), STT_FUNC,
784 0, isec);
785 s->needsTocRestore = true;
706786}
707787
708void PPC64LongBranchThunk::writeTo(uint8_t *Buf) {
709 int64_t Offset = Destination.getPPC64LongBranchTableVA() - getPPC64TocBase();
710 writePPCLoadAndBranch(Buf, Offset);
788void PPC64LongBranchThunk::writeTo(uint8_t *buf) {
789 int64_t offset = destination.getPPC64LongBranchTableVA() - getPPC64TocBase();
790 writePPCLoadAndBranch(buf, offset);
711791}
712792
713void PPC64LongBranchThunk::addSymbols(ThunkSection &IS) {
714 addSymbol(Saver.save("__long_branch_" + Destination.getName()), STT_FUNC, 0,
715 IS);
793void PPC64LongBranchThunk::addSymbols(ThunkSection &isec) {
794 addSymbol(saver.save("__long_branch_" + destination.getName()), STT_FUNC, 0,
795 isec);
716796}
717797
718Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {}
798Thunk::Thunk(Symbol &d) : destination(d), offset(0) {}
719799
720800Thunk::~Thunk() = default;
721801
722static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
723 if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
802static Thunk *addThunkAArch64(RelType type, Symbol &s) {
803 if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
724804 fatal("unrecognized relocation type");
725 if (Config->PicThunk)
726 return make<AArch64ADRPThunk>(S);
727 return make<AArch64ABSLongThunk>(S);
805 if (config->picThunk)
806 return make<AArch64ADRPThunk>(s);
807 return make<AArch64ABSLongThunk>(s);
728808}
729809
730810// Creates a thunk for Thumb-ARM interworking.
......@@ -732,18 +812,18 @@ static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
732812// - MOVT and MOVW instructions cannot be used
733813// - Only Thumb relocation that can generate a Thunk is a BL, this can always
734814// be transformed into a BLX
735static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
736 switch (Reloc) {
815static Thunk *addThunkPreArmv7(RelType reloc, Symbol &s) {
816 switch (reloc) {
737817 case R_ARM_PC24:
738818 case R_ARM_PLT32:
739819 case R_ARM_JUMP24:
740820 case R_ARM_CALL:
741821 case R_ARM_THM_CALL:
742 if (Config->PicThunk)
743 return make<ARMV5PILongThunk>(S);
744 return make<ARMV5ABSLongThunk>(S);
822 if (config->picThunk)
823 return make<ARMV5PILongThunk>(s);
824 return make<ARMV5ABSLongThunk>(s);
745825 }
746 fatal("relocation " + toString(Reloc) + " to " + toString(S) +
826 fatal("relocation " + toString(reloc) + " to " + toString(s) +
747827 " not supported for Armv5 or Armv6 targets");
748828}
749829
......@@ -752,21 +832,21 @@ static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
752832// - MOVT and MOVW instructions cannot be used.
753833// - Only a limited number of instructions can access registers r8 and above
754834// - No interworking support is needed (all Thumb).
755static Thunk *addThunkV6M(RelType Reloc, Symbol &S) {
756 switch (Reloc) {
835static Thunk *addThunkV6M(RelType reloc, Symbol &s) {
836 switch (reloc) {
757837 case R_ARM_THM_JUMP19:
758838 case R_ARM_THM_JUMP24:
759839 case R_ARM_THM_CALL:
760 if (Config->Pic)
761 return make<ThumbV6MPILongThunk>(S);
762 return make<ThumbV6MABSLongThunk>(S);
840 if (config->isPic)
841 return make<ThumbV6MPILongThunk>(s);
842 return make<ThumbV6MABSLongThunk>(s);
763843 }
764 fatal("relocation " + toString(Reloc) + " to " + toString(S) +
844 fatal("relocation " + toString(reloc) + " to " + toString(s) +
765845 " not supported for Armv6-M targets");
766846}
767847
768848// Creates a thunk for Thumb-ARM interworking or branch range extension.
769static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
849static Thunk *addThunkArm(RelType reloc, Symbol &s) {
770850 // Decide which Thunk is needed based on:
771851 // Available instruction set
772852 // - An Arm Thunk can only be used if Arm state is available.
......@@ -783,61 +863,72 @@ static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
783863 // can use in Thunks. The flags below are set by reading the BuildAttributes
784864 // of the input objects. InputFiles.cpp contains the mapping from ARM
785865 // architecture to flag.
786 if (!Config->ARMHasMovtMovw) {
787 if (!Config->ARMJ1J2BranchEncoding)
788 return addThunkPreArmv7(Reloc, S);
789 return addThunkV6M(Reloc, S);
866 if (!config->armHasMovtMovw) {
867 if (!config->armJ1J2BranchEncoding)
868 return addThunkPreArmv7(reloc, s);
869 return addThunkV6M(reloc, s);
790870 }
791871
792 switch (Reloc) {
872 switch (reloc) {
793873 case R_ARM_PC24:
794874 case R_ARM_PLT32:
795875 case R_ARM_JUMP24:
796876 case R_ARM_CALL:
797 if (Config->PicThunk)
798 return make<ARMV7PILongThunk>(S);
799 return make<ARMV7ABSLongThunk>(S);
877 if (config->picThunk)
878 return make<ARMV7PILongThunk>(s);
879 return make<ARMV7ABSLongThunk>(s);
800880 case R_ARM_THM_JUMP19:
801881 case R_ARM_THM_JUMP24:
802882 case R_ARM_THM_CALL:
803 if (Config->PicThunk)
804 return make<ThumbV7PILongThunk>(S);
805 return make<ThumbV7ABSLongThunk>(S);
883 if (config->picThunk)
884 return make<ThumbV7PILongThunk>(s);
885 return make<ThumbV7ABSLongThunk>(s);
806886 }
807887 fatal("unrecognized relocation type");
808888}
809889
810static Thunk *addThunkMips(RelType Type, Symbol &S) {
811 if ((S.StOther & STO_MIPS_MICROMIPS) && isMipsR6())
812 return make<MicroMipsR6Thunk>(S);
813 if (S.StOther & STO_MIPS_MICROMIPS)
814 return make<MicroMipsThunk>(S);
815 return make<MipsThunk>(S);
890static Thunk *addThunkMips(RelType type, Symbol &s) {
891 if ((s.stOther & STO_MIPS_MICROMIPS) && isMipsR6())
892 return make<MicroMipsR6Thunk>(s);
893 if (s.stOther & STO_MIPS_MICROMIPS)
894 return make<MicroMipsThunk>(s);
895 return make<MipsThunk>(s);
896}
897
898static Thunk *addThunkPPC32(const InputSection &isec, const Relocation &rel, Symbol &s) {
899 assert((rel.type == R_PPC_REL24 || rel.type == R_PPC_PLTREL24) &&
900 "unexpected relocation type for thunk");
901 return make<PPC32PltCallStub>(isec, rel, s);
816902}
817903
818static Thunk *addThunkPPC64(RelType Type, Symbol &S) {
819 assert(Type == R_PPC64_REL24 && "unexpected relocation type for thunk");
820 if (S.isInPlt())
821 return make<PPC64PltCallStub>(S);
904static Thunk *addThunkPPC64(RelType type, Symbol &s) {
905 assert(type == R_PPC64_REL24 && "unexpected relocation type for thunk");
906 if (s.isInPlt())
907 return make<PPC64PltCallStub>(s);
822908
823 if (Config->PicThunk)
824 return make<PPC64PILongBranchThunk>(S);
909 if (config->picThunk)
910 return make<PPC64PILongBranchThunk>(s);
825911
826 return make<PPC64PDLongBranchThunk>(S);
912 return make<PPC64PDLongBranchThunk>(s);
827913}
828914
829Thunk *addThunk(RelType Type, Symbol &S) {
830 if (Config->EMachine == EM_AARCH64)
831 return addThunkAArch64(Type, S);
915Thunk *addThunk(const InputSection &isec, Relocation &rel) {
916 Symbol &s = *rel.sym;
917
918 if (config->emachine == EM_AARCH64)
919 return addThunkAArch64(rel.type, s);
920
921 if (config->emachine == EM_ARM)
922 return addThunkArm(rel.type, s);
832923
833 if (Config->EMachine == EM_ARM)
834 return addThunkArm(Type, S);
924 if (config->emachine == EM_MIPS)
925 return addThunkMips(rel.type, s);
835926
836 if (Config->EMachine == EM_MIPS)
837 return addThunkMips(Type, S);
927 if (config->emachine == EM_PPC)
928 return addThunkPPC32(isec, rel, s);
838929
839 if (Config->EMachine == EM_PPC64)
840 return addThunkPPC64(Type, S);
930 if (config->emachine == EM_PPC64)
931 return addThunkPPC64(rel.type, s);
841932
842933 llvm_unreachable("add Thunk only supported for ARM, Mips and PowerPC");
843934}
deps/lld/ELF/Thunks.h+22-20
......@@ -1,9 +1,8 @@
11//===- Thunks.h --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -28,42 +27,45 @@ class ThunkSection;
2827// Thunks are assigned to synthetic ThunkSections
2928class Thunk {
3029public:
31 Thunk(Symbol &Destination);
30 Thunk(Symbol &destination);
3231 virtual ~Thunk();
3332
3433 virtual uint32_t size() = 0;
35 virtual void writeTo(uint8_t *Buf) = 0;
34 virtual void writeTo(uint8_t *buf) = 0;
3635
3736 // All Thunks must define at least one symbol, known as the thunk target
3837 // symbol, so that we can redirect relocations to it. The thunk may define
3938 // additional symbols, but these are never targets for relocations.
40 virtual void addSymbols(ThunkSection &IS) = 0;
39 virtual void addSymbols(ThunkSection &isec) = 0;
4140
42 void setOffset(uint64_t Offset);
43 Defined *addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
44 InputSectionBase &Section);
41 void setOffset(uint64_t offset);
42 Defined *addSymbol(StringRef name, uint8_t type, uint64_t value,
43 InputSectionBase &section);
4544
4645 // Some Thunks must be placed immediately before their Target as they elide
4746 // a branch and fall through to the first Symbol in the Target.
4847 virtual InputSection *getTargetInputSection() const { return nullptr; }
4948
50 // To reuse a Thunk the caller as identified by the Type must be
51 // compatible with it.
52 virtual bool isCompatibleWith(RelType Type) const { return true; }
49 // To reuse a Thunk the InputSection and the relocation must be compatible
50 // with it.
51 virtual bool isCompatibleWith(const InputSection &,
52 const Relocation &) const {
53 return true;
54 }
5355
54 Defined *getThunkTargetSym() const { return Syms[0]; }
56 Defined *getThunkTargetSym() const { return syms[0]; }
5557
5658 // The alignment requirement for this Thunk, defaults to the size of the
5759 // typical code section alignment.
58 Symbol &Destination;
59 llvm::SmallVector<Defined *, 3> Syms;
60 uint64_t Offset = 0;
61 uint32_t Alignment = 4;
60 Symbol &destination;
61 llvm::SmallVector<Defined *, 3> syms;
62 uint64_t offset = 0;
63 uint32_t alignment = 4;
6264};
6365
6466// For a Relocation to symbol S create a Thunk to be added to a synthetic
65// ThunkSection. At present there are implementations for ARM and Mips Thunks.
66Thunk *addThunk(RelType Type, Symbol &S);
67// ThunkSection.
68Thunk *addThunk(const InputSection &isec, Relocation &rel);
6769
6870} // namespace elf
6971} // namespace lld
deps/lld/ELF/Writer.cpp+1415-1253
......@@ -1,9 +1,8 @@
11//===- Writer.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -11,7 +10,6 @@
1110#include "AArch64ErrataFix.h"
1211#include "CallGraphSort.h"
1312#include "Config.h"
14#include "Filesystem.h"
1513#include "LinkerScript.h"
1614#include "MapFile.h"
1715#include "OutputSections.h"
......@@ -20,11 +18,15 @@
2018#include "Symbols.h"
2119#include "SyntheticSections.h"
2220#include "Target.h"
21#include "lld/Common/Filesystem.h"
2322#include "lld/Common/Memory.h"
2423#include "lld/Common/Strings.h"
2524#include "lld/Common/Threads.h"
2625#include "llvm/ADT/StringMap.h"
2726#include "llvm/ADT/StringSwitch.h"
27#include "llvm/Support/RandomNumberGenerator.h"
28#include "llvm/Support/SHA1.h"
29#include "llvm/Support/xxhash.h"
2830#include <climits>
2931
3032using namespace llvm;
......@@ -40,31 +42,32 @@ namespace {
4042// The writer writes a SymbolTable result to a file.
4143template <class ELFT> class Writer {
4244public:
43 Writer() : Buffer(errorHandler().OutputBuffer) {}
44 typedef typename ELFT::Shdr Elf_Shdr;
45 typedef typename ELFT::Ehdr Elf_Ehdr;
46 typedef typename ELFT::Phdr Elf_Phdr;
45 Writer() : buffer(errorHandler().outputBuffer) {}
46 using Elf_Shdr = typename ELFT::Shdr;
47 using Elf_Ehdr = typename ELFT::Ehdr;
48 using Elf_Phdr = typename ELFT::Phdr;
4749
4850 void run();
4951
5052private:
5153 void copyLocalSymbols();
5254 void addSectionSymbols();
53 void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn);
55 void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> fn);
5456 void sortSections();
5557 void resolveShfLinkOrder();
56 void maybeAddThunks();
58 void finalizeAddressDependentContent();
5759 void sortInputSections();
5860 void finalizeSections();
5961 void checkExecuteOnly();
6062 void setReservedSymbolSections();
6163
62 std::vector<PhdrEntry *> createPhdrs();
63 void removeEmptyPTLoad();
64 void addPtArmExid(std::vector<PhdrEntry *> &Phdrs);
64 std::vector<PhdrEntry *> createPhdrs(Partition &part);
65 void removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrEntry);
66 void addPhdrForSection(Partition &part, unsigned shType, unsigned pType,
67 unsigned pFlags);
6568 void assignFileOffsets();
6669 void assignFileOffsetsBinary();
67 void setPhdrs();
70 void setPhdrs(Partition &part);
6871 void checkSections();
6972 void fixSectionAlignments();
7073 void openFile();
......@@ -74,36 +77,34 @@ private:
7477 void writeSectionsBinary();
7578 void writeBuildId();
7679
77 std::unique_ptr<FileOutputBuffer> &Buffer;
80 std::unique_ptr<FileOutputBuffer> &buffer;
7881
7982 void addRelIpltSymbols();
8083 void addStartEndSymbols();
81 void addStartStopSymbols(OutputSection *Sec);
82
83 std::vector<PhdrEntry *> Phdrs;
84 void addStartStopSymbols(OutputSection *sec);
8485
85 uint64_t FileSize;
86 uint64_t SectionHeaderOff;
86 uint64_t fileSize;
87 uint64_t sectionHeaderOff;
8788};
8889} // anonymous namespace
8990
90static bool isSectionPrefix(StringRef Prefix, StringRef Name) {
91 return Name.startswith(Prefix) || Name == Prefix.drop_back();
91static bool isSectionPrefix(StringRef prefix, StringRef name) {
92 return name.startswith(prefix) || name == prefix.drop_back();
9293}
9394
94StringRef elf::getOutputSectionName(const InputSectionBase *S) {
95 if (Config->Relocatable)
96 return S->Name;
95StringRef elf::getOutputSectionName(const InputSectionBase *s) {
96 if (config->relocatable)
97 return s->name;
9798
9899 // This is for --emit-relocs. If .text.foo is emitted as .text.bar, we want
99100 // to emit .rela.text.foo as .rela.text.bar for consistency (this is not
100101 // technically required, but not doing it is odd). This code guarantees that.
101 if (auto *IS = dyn_cast<InputSection>(S)) {
102 if (InputSectionBase *Rel = IS->getRelocatedSection()) {
103 OutputSection *Out = Rel->getOutputSection();
104 if (S->Type == SHT_RELA)
105 return Saver.save(".rela" + Out->Name);
106 return Saver.save(".rel" + Out->Name);
102 if (auto *isec = dyn_cast<InputSection>(s)) {
103 if (InputSectionBase *rel = isec->getRelocatedSection()) {
104 OutputSection *out = rel->getOutputSection();
105 if (s->type == SHT_RELA)
106 return saver.save(".rela" + out->name);
107 return saver.save(".rel" + out->name);
107108 }
108109 }
109110
......@@ -113,97 +114,133 @@ StringRef elf::getOutputSectionName(const InputSectionBase *S) {
113114 // When enabled, this allows identifying the hot code region (.text.hot) in
114115 // the final binary which can be selectively mapped to huge pages or mlocked,
115116 // for instance.
116 if (Config->ZKeepTextSectionPrefix)
117 for (StringRef V :
117 if (config->zKeepTextSectionPrefix)
118 for (StringRef v :
118119 {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."})
119 if (isSectionPrefix(V, S->Name))
120 return V.drop_back();
120 if (isSectionPrefix(v, s->name))
121 return v.drop_back();
121122
122 for (StringRef V :
123 for (StringRef v :
123124 {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
124125 ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
125126 ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."})
126 if (isSectionPrefix(V, S->Name))
127 return V.drop_back();
127 if (isSectionPrefix(v, s->name))
128 return v.drop_back();
128129
129130 // CommonSection is identified as "COMMON" in linker scripts.
130131 // By default, it should go to .bss section.
131 if (S->Name == "COMMON")
132 if (s->name == "COMMON")
132133 return ".bss";
133134
134 return S->Name;
135 return s->name;
135136}
136137
137138static bool needsInterpSection() {
138 return !SharedFiles.empty() && !Config->DynamicLinker.empty() &&
139 Script->needsInterpSection();
139 return !sharedFiles.empty() && !config->dynamicLinker.empty() &&
140 script->needsInterpSection();
140141}
141142
142143template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
143144
144template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() {
145 llvm::erase_if(Phdrs, [&](const PhdrEntry *P) {
146 if (P->p_type != PT_LOAD)
145template <class ELFT>
146void Writer<ELFT>::removeEmptyPTLoad(std::vector<PhdrEntry *> &phdrs) {
147 llvm::erase_if(phdrs, [&](const PhdrEntry *p) {
148 if (p->p_type != PT_LOAD)
147149 return false;
148 if (!P->FirstSec)
150 if (!p->firstSec)
149151 return true;
150 uint64_t Size = P->LastSec->Addr + P->LastSec->Size - P->FirstSec->Addr;
151 return Size == 0;
152 uint64_t size = p->lastSec->addr + p->lastSec->size - p->firstSec->addr;
153 return size == 0;
152154 });
153155}
154156
155template <class ELFT> static void combineEhFrameSections() {
156 for (InputSectionBase *&S : InputSections) {
157 EhInputSection *ES = dyn_cast<EhInputSection>(S);
158 if (!ES || !ES->Live)
157template <class ELFT> static void copySectionsIntoPartitions() {
158 std::vector<InputSectionBase *> newSections;
159 for (unsigned part = 2; part != partitions.size() + 1; ++part) {
160 for (InputSectionBase *s : inputSections) {
161 if (!(s->flags & SHF_ALLOC) || !s->isLive())
162 continue;
163 InputSectionBase *copy;
164 if (s->type == SHT_NOTE)
165 copy = make<InputSection>(cast<InputSection>(*s));
166 else if (auto *es = dyn_cast<EhInputSection>(s))
167 copy = make<EhInputSection>(*es);
168 else
169 continue;
170 copy->partition = part;
171 newSections.push_back(copy);
172 }
173 }
174
175 inputSections.insert(inputSections.end(), newSections.begin(),
176 newSections.end());
177}
178
179template <class ELFT> static void combineEhSections() {
180 for (InputSectionBase *&s : inputSections) {
181 // Ignore dead sections and the partition end marker (.part.end),
182 // whose partition number is out of bounds.
183 if (!s->isLive() || s->partition == 255)
159184 continue;
160185
161 In.EhFrame->addSection<ELFT>(ES);
162 S = nullptr;
186 Partition &part = s->getPartition();
187 if (auto *es = dyn_cast<EhInputSection>(s)) {
188 part.ehFrame->addSection<ELFT>(es);
189 s = nullptr;
190 } else if (s->kind() == SectionBase::Regular && part.armExidx &&
191 part.armExidx->addSection(cast<InputSection>(s))) {
192 s = nullptr;
193 }
163194 }
164195
165 std::vector<InputSectionBase *> &V = InputSections;
166 V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
196 std::vector<InputSectionBase *> &v = inputSections;
197 v.erase(std::remove(v.begin(), v.end(), nullptr), v.end());
167198}
168199
169static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,
170 uint64_t Val, uint8_t StOther = STV_HIDDEN,
171 uint8_t Binding = STB_GLOBAL) {
172 Symbol *S = Symtab->find(Name);
173 if (!S || S->isDefined())
200static Defined *addOptionalRegular(StringRef name, SectionBase *sec,
201 uint64_t val, uint8_t stOther = STV_HIDDEN,
202 uint8_t binding = STB_GLOBAL) {
203 Symbol *s = symtab->find(name);
204 if (!s || s->isDefined())
174205 return nullptr;
175 return Symtab->addDefined(Name, StOther, STT_NOTYPE, Val,
176 /*Size=*/0, Binding, Sec,
177 /*File=*/nullptr);
206
207 s->resolve(Defined{/*file=*/nullptr, name, binding, stOther, STT_NOTYPE, val,
208 /*size=*/0, sec});
209 return cast<Defined>(s);
178210}
179211
180static Defined *addAbsolute(StringRef Name) {
181 return Symtab->addDefined(Name, STV_HIDDEN, STT_NOTYPE, 0, 0, STB_GLOBAL,
182 nullptr, nullptr);
212static Defined *addAbsolute(StringRef name) {
213 Symbol *sym = symtab->addSymbol(Defined{nullptr, name, STB_GLOBAL, STV_HIDDEN,
214 STT_NOTYPE, 0, 0, nullptr});
215 return cast<Defined>(sym);
183216}
184217
185218// The linker is expected to define some symbols depending on
186219// the linking result. This function defines such symbols.
187220void elf::addReservedSymbols() {
188 if (Config->EMachine == EM_MIPS) {
221 if (config->emachine == EM_MIPS) {
189222 // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
190223 // so that it points to an absolute address which by default is relative
191224 // to GOT. Default offset is 0x7ff0.
192225 // See "Global Data Symbols" in Chapter 6 in the following document:
193226 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
194 ElfSym::MipsGp = addAbsolute("_gp");
227 ElfSym::mipsGp = addAbsolute("_gp");
195228
196229 // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
197230 // start of function and 'gp' pointer into GOT.
198 if (Symtab->find("_gp_disp"))
199 ElfSym::MipsGpDisp = addAbsolute("_gp_disp");
231 if (symtab->find("_gp_disp"))
232 ElfSym::mipsGpDisp = addAbsolute("_gp_disp");
200233
201234 // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
202235 // pointer. This symbol is used in the code generated by .cpload pseudo-op
203236 // in case of using -mno-shared option.
204237 // https://sourceware.org/ml/binutils/2004-12/msg00094.html
205 if (Symtab->find("__gnu_local_gp"))
206 ElfSym::MipsLocalGp = addAbsolute("__gnu_local_gp");
238 if (symtab->find("__gnu_local_gp"))
239 ElfSym::mipsLocalGp = addAbsolute("__gnu_local_gp");
240 } else if (config->emachine == EM_PPC) {
241 // glibc *crt1.o has a undefined reference to _SDA_BASE_. Since we don't
242 // support Small Data Area, define it arbitrarily as 0.
243 addOptionalRegular("_SDA_BASE_", nullptr, 0, STV_HIDDEN);
207244 }
208245
209246 // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which
......@@ -214,56 +251,62 @@ void elf::addReservedSymbols() {
214251 // the .got section.
215252 // We do not allow _GLOBAL_OFFSET_TABLE_ to be defined by input objects as the
216253 // 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);
254 StringRef gotSymName =
255 (config->emachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_";
256
257 if (Symbol *s = symtab->find(gotSymName)) {
258 if (s->isDefined()) {
259 error(toString(s->file) + " cannot redefine linker defined symbol '" +
260 gotSymName + "'");
261 return;
262 }
263
264 uint64_t gotOff = 0;
265 if (config->emachine == EM_PPC64)
266 gotOff = 0x8000;
267
268 s->resolve(Defined{/*file=*/nullptr, gotSymName, STB_GLOBAL, STV_HIDDEN,
269 STT_NOTYPE, gotOff, /*size=*/0, Out::elfHeader});
270 ElfSym::globalOffsetTable = cast<Defined>(s);
228271 }
229272
230273 // __ehdr_start is the location of ELF file headers. Note that we define
231274 // this symbol unconditionally even when using a linker script, which
232275 // differs from the behavior implemented by GNU linker which only define
233276 // this symbol if ELF headers are in the memory mapped segment.
234 addOptionalRegular("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN);
277 addOptionalRegular("__ehdr_start", Out::elfHeader, 0, STV_HIDDEN);
235278
236279 // __executable_start is not documented, but the expectation of at
237280 // least the Android libc is that it points to the ELF header.
238 addOptionalRegular("__executable_start", Out::ElfHeader, 0, STV_HIDDEN);
281 addOptionalRegular("__executable_start", Out::elfHeader, 0, STV_HIDDEN);
239282
240283 // __dso_handle symbol is passed to cxa_finalize as a marker to identify
241284 // each DSO. The address of the symbol doesn't matter as long as they are
242285 // different in different DSOs, so we chose the start address of the DSO.
243 addOptionalRegular("__dso_handle", Out::ElfHeader, 0, STV_HIDDEN);
286 addOptionalRegular("__dso_handle", Out::elfHeader, 0, STV_HIDDEN);
244287
245288 // If linker script do layout we do not need to create any standart symbols.
246 if (Script->HasSectionsCommand)
289 if (script->hasSectionsCommand)
247290 return;
248291
249 auto Add = [](StringRef S, int64_t Pos) {
250 return addOptionalRegular(S, Out::ElfHeader, Pos, STV_DEFAULT);
292 auto add = [](StringRef s, int64_t pos) {
293 return addOptionalRegular(s, Out::elfHeader, pos, STV_DEFAULT);
251294 };
252295
253 ElfSym::Bss = Add("__bss_start", 0);
254 ElfSym::End1 = Add("end", -1);
255 ElfSym::End2 = Add("_end", -1);
256 ElfSym::Etext1 = Add("etext", -1);
257 ElfSym::Etext2 = Add("_etext", -1);
258 ElfSym::Edata1 = Add("edata", -1);
259 ElfSym::Edata2 = Add("_edata", -1);
296 ElfSym::bss = add("__bss_start", 0);
297 ElfSym::end1 = add("end", -1);
298 ElfSym::end2 = add("_end", -1);
299 ElfSym::etext1 = add("etext", -1);
300 ElfSym::etext2 = add("_etext", -1);
301 ElfSym::edata1 = add("edata", -1);
302 ElfSym::edata2 = add("_edata", -1);
260303}
261304
262static OutputSection *findSection(StringRef Name) {
263 for (BaseCommand *Base : Script->SectionCommands)
264 if (auto *Sec = dyn_cast<OutputSection>(Base))
265 if (Sec->Name == Name)
266 return Sec;
305static OutputSection *findSection(StringRef name, unsigned partition = 1) {
306 for (BaseCommand *base : script->sectionCommands)
307 if (auto *sec = dyn_cast<OutputSection>(base))
308 if (sec->name == name && sec->partition == partition)
309 return sec;
267310 return nullptr;
268311}
269312
......@@ -271,202 +314,263 @@ static OutputSection *findSection(StringRef Name) {
271314template <class ELFT> static void createSyntheticSections() {
272315 // Initialize all pointers with NULL. This is needed because
273316 // you can call lld::elf::main more than once as a library.
274 memset(&Out::First, 0, sizeof(Out));
317 memset(&Out::first, 0, sizeof(Out));
275318
276 auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
319 auto add = [](InputSectionBase *sec) { inputSections.push_back(sec); };
277320
278 In.DynStrTab = make<StringTableSection>(".dynstr", true);
279 In.Dynamic = make<DynamicSection<ELFT>>();
280 if (Config->AndroidPackDynRelocs) {
281 In.RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
282 Config->IsRela ? ".rela.dyn" : ".rel.dyn");
283 } else {
284 In.RelaDyn = make<RelocationSection<ELFT>>(
285 Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
286 }
287 In.ShStrTab = make<StringTableSection>(".shstrtab", false);
321 in.shStrTab = make<StringTableSection>(".shstrtab", false);
288322
289 Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
290 Out::ProgramHeaders->Alignment = Config->Wordsize;
323 Out::programHeaders = make<OutputSection>("", 0, SHF_ALLOC);
324 Out::programHeaders->alignment = config->wordsize;
291325
292 if (needsInterpSection()) {
293 In.Interp = createInterpSection();
294 Add(In.Interp);
326 if (config->strip != StripPolicy::All) {
327 in.strTab = make<StringTableSection>(".strtab", false);
328 in.symTab = make<SymbolTableSection<ELFT>>(*in.strTab);
329 in.symTabShndx = make<SymtabShndxSection>();
295330 }
296331
297 if (Config->Strip != StripPolicy::All) {
298 In.StrTab = make<StringTableSection>(".strtab", false);
299 In.SymTab = make<SymbolTableSection<ELFT>>(*In.StrTab);
300 In.SymTabShndx = make<SymtabShndxSection>();
301 }
302
303 if (Config->BuildId != BuildIdKind::None) {
304 In.BuildId = make<BuildIdSection>();
305 Add(In.BuildId);
306 }
307
308 In.Bss = make<BssSection>(".bss", 0, 1);
309 Add(In.Bss);
332 in.bss = make<BssSection>(".bss", 0, 1);
333 add(in.bss);
310334
311335 // If there is a SECTIONS command and a .data.rel.ro section name use name
312336 // .data.rel.ro.bss so that we match in the .data.rel.ro output section.
313337 // This makes sure our relro is contiguous.
314 bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro");
315 In.BssRelRo =
316 make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
317 Add(In.BssRelRo);
338 bool hasDataRelRo =
339 script->hasSectionsCommand && findSection(".data.rel.ro", 0);
340 in.bssRelRo =
341 make<BssSection>(hasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
342 add(in.bssRelRo);
318343
319344 // Add MIPS-specific sections.
320 if (Config->EMachine == EM_MIPS) {
321 if (!Config->Shared && Config->HasDynSymTab) {
322 In.MipsRldMap = make<MipsRldMapSection>();
323 Add(In.MipsRldMap);
345 if (config->emachine == EM_MIPS) {
346 if (!config->shared && config->hasDynSymTab) {
347 in.mipsRldMap = make<MipsRldMapSection>();
348 add(in.mipsRldMap);
324349 }
325 if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
326 Add(Sec);
327 if (auto *Sec = MipsOptionsSection<ELFT>::create())
328 Add(Sec);
329 if (auto *Sec = MipsReginfoSection<ELFT>::create())
330 Add(Sec);
350 if (auto *sec = MipsAbiFlagsSection<ELFT>::create())
351 add(sec);
352 if (auto *sec = MipsOptionsSection<ELFT>::create())
353 add(sec);
354 if (auto *sec = MipsReginfoSection<ELFT>::create())
355 add(sec);
331356 }
332357
333 if (Config->HasDynSymTab) {
334 In.DynSymTab = make<SymbolTableSection<ELFT>>(*In.DynStrTab);
335 Add(In.DynSymTab);
358 for (Partition &part : partitions) {
359 auto add = [&](InputSectionBase *sec) {
360 sec->partition = part.getNumber();
361 inputSections.push_back(sec);
362 };
363
364 if (!part.name.empty()) {
365 part.elfHeader = make<PartitionElfHeaderSection<ELFT>>();
366 part.elfHeader->name = part.name;
367 add(part.elfHeader);
336368
337 InX<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
338 Add(InX<ELFT>::VerSym);
369 part.programHeaders = make<PartitionProgramHeadersSection<ELFT>>();
370 add(part.programHeaders);
371 }
339372
340 if (!Config->VersionDefinitions.empty()) {
341 In.VerDef = make<VersionDefinitionSection>();
342 Add(In.VerDef);
373 if (config->buildId != BuildIdKind::None) {
374 part.buildId = make<BuildIdSection>();
375 add(part.buildId);
343376 }
344377
345 InX<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
346 Add(InX<ELFT>::VerNeed);
378 part.dynStrTab = make<StringTableSection>(".dynstr", true);
379 part.dynSymTab = make<SymbolTableSection<ELFT>>(*part.dynStrTab);
380 part.dynamic = make<DynamicSection<ELFT>>();
381 if (config->androidPackDynRelocs) {
382 part.relaDyn = make<AndroidPackedRelocationSection<ELFT>>(
383 config->isRela ? ".rela.dyn" : ".rel.dyn");
384 } else {
385 part.relaDyn = make<RelocationSection<ELFT>>(
386 config->isRela ? ".rela.dyn" : ".rel.dyn", config->zCombreloc);
387 }
388
389 if (needsInterpSection())
390 add(createInterpSection());
391
392 if (config->hasDynSymTab) {
393 part.dynSymTab = make<SymbolTableSection<ELFT>>(*part.dynStrTab);
394 add(part.dynSymTab);
395
396 part.verSym = make<VersionTableSection>();
397 add(part.verSym);
398
399 if (!config->versionDefinitions.empty()) {
400 part.verDef = make<VersionDefinitionSection>();
401 add(part.verDef);
402 }
403
404 part.verNeed = make<VersionNeedSection<ELFT>>();
405 add(part.verNeed);
406
407 if (config->gnuHash) {
408 part.gnuHashTab = make<GnuHashTableSection>();
409 add(part.gnuHashTab);
410 }
411
412 if (config->sysvHash) {
413 part.hashTab = make<HashTableSection>();
414 add(part.hashTab);
415 }
347416
348 if (Config->GnuHash) {
349 In.GnuHashTab = make<GnuHashTableSection>();
350 Add(In.GnuHashTab);
417 add(part.dynamic);
418 add(part.dynStrTab);
419 add(part.relaDyn);
351420 }
352421
353 if (Config->SysvHash) {
354 In.HashTab = make<HashTableSection>();
355 Add(In.HashTab);
422 if (config->relrPackDynRelocs) {
423 part.relrDyn = make<RelrSection<ELFT>>();
424 add(part.relrDyn);
356425 }
357426
358 Add(In.Dynamic);
359 Add(In.DynStrTab);
360 Add(In.RelaDyn);
427 if (!config->relocatable) {
428 if (config->ehFrameHdr) {
429 part.ehFrameHdr = make<EhFrameHeader>();
430 add(part.ehFrameHdr);
431 }
432 part.ehFrame = make<EhFrameSection>();
433 add(part.ehFrame);
434 }
435
436 if (config->emachine == EM_ARM && !config->relocatable) {
437 // The ARMExidxsyntheticsection replaces all the individual .ARM.exidx
438 // InputSections.
439 part.armExidx = make<ARMExidxSyntheticSection>();
440 add(part.armExidx);
441 }
361442 }
362443
363 if (Config->RelrPackDynRelocs) {
364 In.RelrDyn = make<RelrSection<ELFT>>();
365 Add(In.RelrDyn);
444 if (partitions.size() != 1) {
445 // Create the partition end marker. This needs to be in partition number 255
446 // so that it is sorted after all other partitions. It also has other
447 // special handling (see createPhdrs() and combineEhSections()).
448 in.partEnd = make<BssSection>(".part.end", config->maxPageSize, 1);
449 in.partEnd->partition = 255;
450 add(in.partEnd);
451
452 in.partIndex = make<PartitionIndexSection>();
453 addOptionalRegular("__part_index_begin", in.partIndex, 0);
454 addOptionalRegular("__part_index_end", in.partIndex,
455 in.partIndex->getSize());
456 add(in.partIndex);
366457 }
367458
368459 // Add .got. MIPS' .got is so different from the other archs,
369460 // it has its own class.
370 if (Config->EMachine == EM_MIPS) {
371 In.MipsGot = make<MipsGotSection>();
372 Add(In.MipsGot);
461 if (config->emachine == EM_MIPS) {
462 in.mipsGot = make<MipsGotSection>();
463 add(in.mipsGot);
373464 } else {
374 In.Got = make<GotSection>();
375 Add(In.Got);
465 in.got = make<GotSection>();
466 add(in.got);
467 }
468
469 if (config->emachine == EM_PPC) {
470 in.ppc32Got2 = make<PPC32Got2Section>();
471 add(in.ppc32Got2);
376472 }
377473
378 if (Config->EMachine == EM_PPC64) {
379 In.PPC64LongBranchTarget = make<PPC64LongBranchTargetSection>();
380 Add(In.PPC64LongBranchTarget);
474 if (config->emachine == EM_PPC64) {
475 in.ppc64LongBranchTarget = make<PPC64LongBranchTargetSection>();
476 add(in.ppc64LongBranchTarget);
381477 }
382478
383 In.GotPlt = make<GotPltSection>();
384 Add(In.GotPlt);
385 In.IgotPlt = make<IgotPltSection>();
386 Add(In.IgotPlt);
479 if (config->emachine == EM_RISCV) {
480 in.riscvSdata = make<RISCVSdataSection>();
481 add(in.riscvSdata);
482 }
483
484 in.gotPlt = make<GotPltSection>();
485 add(in.gotPlt);
486 in.igotPlt = make<IgotPltSection>();
487 add(in.igotPlt);
387488
388 if (Config->GdbIndex) {
389 In.GdbIndex = GdbIndexSection::create<ELFT>();
390 Add(In.GdbIndex);
489 // _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat
490 // it as a relocation and ensure the referenced section is created.
491 if (ElfSym::globalOffsetTable && config->emachine != EM_MIPS) {
492 if (target->gotBaseSymInGotPlt)
493 in.gotPlt->hasGotPltOffRel = true;
494 else
495 in.got->hasGotOffRel = true;
391496 }
392497
498 if (config->gdbIndex)
499 add(GdbIndexSection::create<ELFT>());
500
393501 // We always need to add rel[a].plt to output if it has entries.
394502 // Even for static linking it can contain R_[*]_IRELATIVE relocations.
395 In.RelaPlt = make<RelocationSection<ELFT>>(
396 Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
397 Add(In.RelaPlt);
503 in.relaPlt = make<RelocationSection<ELFT>>(
504 config->isRela ? ".rela.plt" : ".rel.plt", /*sort=*/false);
505 add(in.relaPlt);
398506
399 // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
507 // The relaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
400508 // that the IRelative relocations are processed last by the dynamic loader.
401509 // We cannot place the iplt section in .rel.dyn when Android relocation
402510 // packing is enabled because that would cause a section type mismatch.
403511 // However, because the Android dynamic loader reads .rel.plt after .rel.dyn,
404512 // we can get the desired behaviour by placing the iplt section in .rel.plt.
405 In.RelaIplt = make<RelocationSection<ELFT>>(
406 (Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)
513 in.relaIplt = make<RelocationSection<ELFT>>(
514 (config->emachine == EM_ARM && !config->androidPackDynRelocs)
407515 ? ".rel.dyn"
408 : In.RelaPlt->Name,
409 false /*Sort*/);
410 Add(In.RelaIplt);
516 : in.relaPlt->name,
517 /*sort=*/false);
518 add(in.relaIplt);
519
520 in.plt = make<PltSection>(false);
521 add(in.plt);
522 in.iplt = make<PltSection>(true);
523 add(in.iplt);
411524
412 In.Plt = make<PltSection>(false);
413 Add(In.Plt);
414 In.Iplt = make<PltSection>(true);
415 Add(In.Iplt);
525 if (config->andFeatures)
526 add(make<GnuPropertySection>());
416527
417528 // .note.GNU-stack is always added when we are creating a re-linkable
418529 // object file. Other linkers are using the presence of this marker
419530 // section to control the executable-ness of the stack area, but that
420531 // is irrelevant these days. Stack area should always be non-executable
421532 // by default. So we emit this section unconditionally.
422 if (Config->Relocatable)
423 Add(make<GnuStackSection>());
424
425 if (!Config->Relocatable) {
426 if (Config->EhFrameHdr) {
427 In.EhFrameHdr = make<EhFrameHeader>();
428 Add(In.EhFrameHdr);
429 }
430 In.EhFrame = make<EhFrameSection>();
431 Add(In.EhFrame);
432 }
433
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);
533 if (config->relocatable)
534 add(make<GnuStackSection>());
441535
442 if (Config->EMachine == EM_ARM && !Config->Relocatable)
443 // Add a sentinel to terminate .ARM.exidx. It helps an unwinder
444 // to find the exact address range of the last entry.
445 Add(make<ARMExidxSentinelSection>());
536 if (in.symTab)
537 add(in.symTab);
538 if (in.symTabShndx)
539 add(in.symTabShndx);
540 add(in.shStrTab);
541 if (in.strTab)
542 add(in.strTab);
446543}
447544
448545// The main function of the writer.
449546template <class ELFT> void Writer<ELFT>::run() {
547 // Make copies of any input sections that need to be copied into each
548 // partition.
549 copySectionsIntoPartitions<ELFT>();
550
450551 // Create linker-synthesized sections such as .got or .plt.
451552 // Such sections are of type input section.
452553 createSyntheticSections<ELFT>();
453554
454 if (!Config->Relocatable)
455 combineEhFrameSections<ELFT>();
555 // Some input sections that are used for exception handling need to be moved
556 // into synthetic sections. Do that now so that they aren't assigned to
557 // output sections in the usual way.
558 if (!config->relocatable)
559 combineEhSections<ELFT>();
456560
457561 // We want to process linker script commands. When SECTIONS command
458562 // is given we let it create sections.
459 Script->processSectionCommands();
563 script->processSectionCommands();
460564
461565 // Linker scripts controls how input sections are assigned to output sections.
462566 // Input sections that were not handled by scripts are called "orphans", and
463567 // they are assigned to output sections by the default rule. Process that.
464 Script->addOrphanSections();
568 script->addOrphanSections();
465569
466 if (Config->Discard != DiscardPolicy::All)
570 if (config->discard != DiscardPolicy::All)
467571 copyLocalSymbols();
468572
469 if (Config->CopyRelocs)
573 if (config->copyRelocs)
470574 addSectionSymbols();
471575
472576 // Now that we have a complete set of output sections. This function
......@@ -478,33 +582,35 @@ template <class ELFT> void Writer<ELFT>::run() {
478582 if (errorCount())
479583 return;
480584
481 Script->assignAddresses();
585 script->assignAddresses();
482586
483587 // If -compressed-debug-sections is specified, we need to compress
484588 // .debug_* sections. Do it right now because it changes the size of
485589 // output sections.
486 for (OutputSection *Sec : OutputSections)
487 Sec->maybeCompress<ELFT>();
590 for (OutputSection *sec : outputSections)
591 sec->maybeCompress<ELFT>();
488592
489 Script->allocateHeaders(Phdrs);
593 script->allocateHeaders(mainPart->phdrs);
490594
491595 // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
492596 // 0 sized region. This has to be done late since only after assignAddresses
493597 // we know the size of the sections.
494 removeEmptyPTLoad();
598 for (Partition &part : partitions)
599 removeEmptyPTLoad(part.phdrs);
495600
496 if (!Config->OFormatBinary)
601 if (!config->oFormatBinary)
497602 assignFileOffsets();
498603 else
499604 assignFileOffsetsBinary();
500605
501 setPhdrs();
606 for (Partition &part : partitions)
607 setPhdrs(part);
502608
503 if (Config->Relocatable)
504 for (OutputSection *Sec : OutputSections)
505 Sec->Addr = 0;
609 if (config->relocatable)
610 for (OutputSection *sec : outputSections)
611 sec->addr = 0;
506612
507 if (Config->CheckSections)
613 if (config->checkSections)
508614 checkSections();
509615
510616 // It does not make sense try to open the file if we have error already.
......@@ -515,7 +621,7 @@ template <class ELFT> void Writer<ELFT>::run() {
515621 if (errorCount())
516622 return;
517623
518 if (!Config->OFormatBinary) {
624 if (!config->oFormatBinary) {
519625 writeTrapInstr();
520626 writeHeader();
521627 writeSections();
......@@ -535,16 +641,20 @@ template <class ELFT> void Writer<ELFT>::run() {
535641 if (errorCount())
536642 return;
537643
538 if (auto E = Buffer->commit())
539 error("failed to write to the output file: " + toString(std::move(E)));
644 if (auto e = buffer->commit())
645 error("failed to write to the output file: " + toString(std::move(e)));
540646}
541647
542static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
543 const Symbol &B) {
544 if (B.isSection())
648static bool shouldKeepInSymtab(const Defined &sym) {
649 if (sym.isSection())
545650 return false;
546651
547 if (Config->Discard == DiscardPolicy::None)
652 if (config->discard == DiscardPolicy::None)
653 return true;
654
655 // If -emit-reloc is given, all symbols including local ones need to be
656 // copied because they may be referenced by relocations.
657 if (config->emitRelocs)
548658 return true;
549659
550660 // In ELF assembly .L symbols are normally discarded by the assembler.
......@@ -552,61 +662,62 @@ static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
552662 // * --discard-locals is used.
553663 // * The symbol is in a SHF_MERGE section, which is normally the reason for
554664 // the assembler keeping the .L symbol.
555 if (!SymName.startswith(".L") && !SymName.empty())
665 StringRef name = sym.getName();
666 bool isLocal = name.startswith(".L") || name.empty();
667 if (!isLocal)
556668 return true;
557669
558 if (Config->Discard == DiscardPolicy::Locals)
670 if (config->discard == DiscardPolicy::Locals)
559671 return false;
560672
561 return !Sec || !(Sec->Flags & SHF_MERGE);
673 SectionBase *sec = sym.section;
674 return !sec || !(sec->flags & SHF_MERGE);
562675}
563676
564static bool includeInSymtab(const Symbol &B) {
565 if (!B.isLocal() && !B.IsUsedInRegularObj)
677static bool includeInSymtab(const Symbol &b) {
678 if (!b.isLocal() && !b.isUsedInRegularObj)
566679 return false;
567680
568 if (auto *D = dyn_cast<Defined>(&B)) {
681 if (auto *d = dyn_cast<Defined>(&b)) {
569682 // Always include absolute symbols.
570 SectionBase *Sec = D->Section;
571 if (!Sec)
683 SectionBase *sec = d->section;
684 if (!sec)
572685 return true;
573 Sec = Sec->Repl;
686 sec = sec->repl;
574687
575688 // Exclude symbols pointing to garbage-collected sections.
576 if (isa<InputSectionBase>(Sec) && !Sec->Live)
689 if (isa<InputSectionBase>(sec) && !sec->isLive())
577690 return false;
578691
579 if (auto *S = dyn_cast<MergeInputSection>(Sec))
580 if (!S->getSectionPiece(D->Value)->Live)
692 if (auto *s = dyn_cast<MergeInputSection>(sec))
693 if (!s->getSectionPiece(d->value)->live)
581694 return false;
582695 return true;
583696 }
584 return B.Used;
697 return b.used;
585698}
586699
587700// Local symbols are not in the linker's symbol table. This function scans
588701// each object file's symbol table to copy local symbols to the output.
589702template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
590 if (!In.SymTab)
703 if (!in.symTab)
591704 return;
592 for (InputFile *File : ObjectFiles) {
593 ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
594 for (Symbol *B : F->getLocalSymbols()) {
595 if (!B->isLocal())
596 fatal(toString(F) +
705 for (InputFile *file : objectFiles) {
706 ObjFile<ELFT> *f = cast<ObjFile<ELFT>>(file);
707 for (Symbol *b : f->getLocalSymbols()) {
708 if (!b->isLocal())
709 fatal(toString(f) +
597710 ": broken object: getLocalSymbols returns a non-local symbol");
598 auto *DR = dyn_cast<Defined>(B);
711 auto *dr = dyn_cast<Defined>(b);
599712
600713 // No reason to keep local undefined symbol in symtab.
601 if (!DR)
714 if (!dr)
602715 continue;
603 if (!includeInSymtab(*B))
716 if (!includeInSymtab(*b))
604717 continue;
605
606 SectionBase *Sec = DR->Section;
607 if (!shouldKeepInSymtab(Sec, B->getName(), *B))
718 if (!shouldKeepInSymtab(*dr))
608719 continue;
609 In.SymTab->addSymbol(B);
720 in.symTab->addSymbol(b);
610721 }
611722 }
612723}
......@@ -616,33 +727,33 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
616727// referring to a section (that happens if the section is a synthetic one), we
617728// don't create a section symbol for that section.
618729template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
619 for (BaseCommand *Base : Script->SectionCommands) {
620 auto *Sec = dyn_cast<OutputSection>(Base);
621 if (!Sec)
730 for (BaseCommand *base : script->sectionCommands) {
731 auto *sec = dyn_cast<OutputSection>(base);
732 if (!sec)
622733 continue;
623 auto I = llvm::find_if(Sec->SectionCommands, [](BaseCommand *Base) {
624 if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
625 return !ISD->Sections.empty();
734 auto i = llvm::find_if(sec->sectionCommands, [](BaseCommand *base) {
735 if (auto *isd = dyn_cast<InputSectionDescription>(base))
736 return !isd->sections.empty();
626737 return false;
627738 });
628 if (I == Sec->SectionCommands.end())
739 if (i == sec->sectionCommands.end())
629740 continue;
630 InputSection *IS = cast<InputSectionDescription>(*I)->Sections[0];
741 InputSection *isec = cast<InputSectionDescription>(*i)->sections[0];
631742
632743 // Relocations are not using REL[A] section symbols.
633 if (IS->Type == SHT_REL || IS->Type == SHT_RELA)
744 if (isec->type == SHT_REL || isec->type == SHT_RELA)
634745 continue;
635746
636747 // Unlike other synthetic sections, mergeable output sections contain data
637748 // copied from input sections, and there may be a relocation pointing to its
638749 // contents if -r or -emit-reloc are given.
639 if (isa<SyntheticSection>(IS) && !(IS->Flags & SHF_MERGE))
750 if (isa<SyntheticSection>(isec) && !(isec->flags & SHF_MERGE))
640751 continue;
641752
642 auto *Sym =
643 make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
644 /*Value=*/0, /*Size=*/0, IS);
645 In.SymTab->addSymbol(Sym);
753 auto *sym =
754 make<Defined>(isec->file, "", STB_LOCAL, /*stOther=*/0, STT_SECTION,
755 /*value=*/0, /*size=*/0, isec);
756 in.symTab->addSymbol(sym);
646757 }
647758}
648759
......@@ -652,25 +763,25 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
652763//
653764// This function returns true if a section needs to be put into a
654765// PT_GNU_RELRO segment.
655static bool isRelroSection(const OutputSection *Sec) {
656 if (!Config->ZRelro)
766static bool isRelroSection(const OutputSection *sec) {
767 if (!config->zRelro)
657768 return false;
658769
659 uint64_t Flags = Sec->Flags;
770 uint64_t flags = sec->flags;
660771
661772 // Non-allocatable or non-writable sections don't need RELRO because
662773 // they are not writable or not even mapped to memory in the first place.
663774 // RELRO is for sections that are essentially read-only but need to
664775 // be writable only at process startup to allow dynamic linker to
665776 // apply relocations.
666 if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
777 if (!(flags & SHF_ALLOC) || !(flags & SHF_WRITE))
667778 return false;
668779
669780 // Once initialized, TLS data segments are used as data templates
670781 // for a thread-local storage. For each new thread, runtime
671782 // allocates memory for a TLS and copy templates there. No thread
672783 // are supposed to use templates directly. Thus, it can be in RELRO.
673 if (Flags & SHF_TLS)
784 if (flags & SHF_TLS)
674785 return true;
675786
676787 // .init_array, .preinit_array and .fini_array contain pointers to
......@@ -679,15 +790,15 @@ static bool isRelroSection(const OutputSection *Sec) {
679790 // to change at runtime. But if you are an attacker, you could do
680791 // interesting things by manipulating pointers in .fini_array, for
681792 // example. So they are put into RELRO.
682 uint32_t Type = Sec->Type;
683 if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||
684 Type == SHT_PREINIT_ARRAY)
793 uint32_t type = sec->type;
794 if (type == SHT_INIT_ARRAY || type == SHT_FINI_ARRAY ||
795 type == SHT_PREINIT_ARRAY)
685796 return true;
686797
687798 // .got contains pointers to external symbols. They are resolved by
688799 // the dynamic linker when a module is loaded into memory, and after
689800 // that they are not expected to change. So, it can be in RELRO.
690 if (In.Got && Sec == In.Got->getParent())
801 if (in.got && sec == in.got->getParent())
691802 return true;
692803
693804 // .toc is a GOT-ish section for PowerPC64. Their contents are accessed
......@@ -695,30 +806,30 @@ static bool isRelroSection(const OutputSection *Sec) {
695806 // for accessing .got as well, .got and .toc need to be close enough in the
696807 // virtual address space. Usually, .toc comes just after .got. Since we place
697808 // .got into RELRO, .toc needs to be placed into RELRO too.
698 if (Sec->Name.equals(".toc"))
809 if (sec->name.equals(".toc"))
699810 return true;
700811
701812 // .got.plt contains pointers to external function symbols. They are
702813 // by default resolved lazily, so we usually cannot put it into RELRO.
703814 // However, if "-z now" is given, the lazy symbol resolution is
704815 // disabled, which enables us to put it into RELRO.
705 if (Sec == In.GotPlt->getParent())
706 return Config->ZNow;
816 if (sec == in.gotPlt->getParent())
817 return config->zNow;
707818
708819 // .dynamic section contains data for the dynamic linker, and
709820 // there's no need to write to it at runtime, so it's better to put
710821 // it into RELRO.
711 if (Sec == In.Dynamic->getParent())
822 if (sec->name == ".dynamic")
712823 return true;
713824
714825 // Sections with some special names are put into RELRO. This is a
715826 // bit unfortunate because section names shouldn't be significant in
716827 // ELF in spirit. But in reality many linker features depend on
717828 // magic section names.
718 StringRef S = Sec->Name;
719 return S == ".data.rel.ro" || S == ".bss.rel.ro" || S == ".ctors" ||
720 S == ".dtors" || S == ".jcr" || S == ".eh_frame" ||
721 S == ".openbsd.randomdata";
829 StringRef s = sec->name;
830 return s == ".data.rel.ro" || s == ".bss.rel.ro" || s == ".ctors" ||
831 s == ".dtors" || s == ".jcr" || s == ".eh_frame" ||
832 s == ".openbsd.randomdata";
722833}
723834
724835// We compute a rank for each section. The rank indicates where the
......@@ -729,16 +840,18 @@ static bool isRelroSection(const OutputSection *Sec) {
729840// * It is easy to check if a give branch was taken.
730841// * It is easy two see how similar two ranks are (see getRankProximity).
731842enum RankFlags {
732 RF_NOT_ADDR_SET = 1 << 18,
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,
843 RF_NOT_ADDR_SET = 1 << 27,
844 RF_NOT_ALLOC = 1 << 26,
845 RF_PARTITION = 1 << 18, // Partition number (8 bits)
846 RF_NOT_PART_EHDR = 1 << 17,
847 RF_NOT_PART_PHDR = 1 << 16,
848 RF_NOT_INTERP = 1 << 15,
849 RF_NOT_NOTE = 1 << 14,
850 RF_WRITE = 1 << 13,
851 RF_EXEC_WRITE = 1 << 12,
852 RF_EXEC = 1 << 11,
853 RF_RODATA = 1 << 10,
854 RF_NOT_RELRO = 1 << 9,
742855 RF_NOT_TLS = 1 << 8,
743856 RF_BSS = 1 << 7,
744857 RF_PPC_NOT_TOCBSS = 1 << 6,
......@@ -750,33 +863,41 @@ enum RankFlags {
750863 RF_MIPS_NOT_GOT = 1 << 0
751864};
752865
753static unsigned getSectionRank(const OutputSection *Sec) {
754 unsigned Rank = 0;
866static unsigned getSectionRank(const OutputSection *sec) {
867 unsigned rank = sec->partition * RF_PARTITION;
755868
756869 // We want to put section specified by -T option first, so we
757870 // can start assigning VA starting from them later.
758 if (Config->SectionStartMap.count(Sec->Name))
759 return Rank;
760 Rank |= RF_NOT_ADDR_SET;
871 if (config->sectionStartMap.count(sec->name))
872 return rank;
873 rank |= RF_NOT_ADDR_SET;
761874
762875 // Allocatable sections go first to reduce the total PT_LOAD size and
763876 // so debug info doesn't change addresses in actual code.
764 if (!(Sec->Flags & SHF_ALLOC))
765 return Rank | RF_NOT_ALLOC;
877 if (!(sec->flags & SHF_ALLOC))
878 return rank | RF_NOT_ALLOC;
879
880 if (sec->type == SHT_LLVM_PART_EHDR)
881 return rank;
882 rank |= RF_NOT_PART_EHDR;
883
884 if (sec->type == SHT_LLVM_PART_PHDR)
885 return rank;
886 rank |= RF_NOT_PART_PHDR;
766887
767888 // Put .interp first because some loaders want to see that section
768889 // on the first page of the executable file when loaded into memory.
769 if (Sec->Name == ".interp")
770 return Rank;
771 Rank |= RF_NOT_INTERP;
890 if (sec->name == ".interp")
891 return rank;
892 rank |= RF_NOT_INTERP;
772893
773894 // Put .note sections (which make up one PT_NOTE) at the beginning so that
774895 // they are likely to be included in a core file even if core file size is
775896 // limited. In particular, we want a .note.gnu.build-id and a .note.tag to be
776897 // included in a core to match core files with executables.
777 if (Sec->Type == SHT_NOTE)
778 return Rank;
779 Rank |= RF_NOT_NOTE;
898 if (sec->type == SHT_NOTE)
899 return rank;
900 rank |= RF_NOT_NOTE;
780901
781902 // Sort sections based on their access permission in the following
782903 // order: R, RX, RWX, RW. This order is based on the following
......@@ -789,116 +910,105 @@ static unsigned getSectionRank(const OutputSection *Sec) {
789910 // between .text and .data.
790911 // * Writable sections come last, such that .bss lands at the very
791912 // end of the last PT_LOAD.
792 bool IsExec = Sec->Flags & SHF_EXECINSTR;
793 bool IsWrite = Sec->Flags & SHF_WRITE;
913 bool isExec = sec->flags & SHF_EXECINSTR;
914 bool isWrite = sec->flags & SHF_WRITE;
794915
795 if (IsExec) {
796 if (IsWrite)
797 Rank |= RF_EXEC_WRITE;
916 if (isExec) {
917 if (isWrite)
918 rank |= RF_EXEC_WRITE;
798919 else
799 Rank |= RF_EXEC;
800 } else if (IsWrite) {
801 Rank |= RF_WRITE;
802 } else if (Sec->Type == SHT_PROGBITS) {
920 rank |= RF_EXEC;
921 } else if (isWrite) {
922 rank |= RF_WRITE;
923 } else if (sec->type == SHT_PROGBITS) {
803924 // Make non-executable and non-writable PROGBITS sections (e.g .rodata
804925 // .eh_frame) closer to .text. They likely contain PC or GOT relative
805926 // relocations and there could be relocation overflow if other huge sections
806927 // (.dynstr .dynsym) were placed in between.
807 Rank |= RF_RODATA;
928 rank |= RF_RODATA;
808929 }
809930
810 // If we got here we know that both A and B are in the same PT_LOAD.
931 // Place RelRo sections first. After considering SHT_NOBITS below, the
932 // ordering is PT_LOAD(PT_GNU_RELRO(.data.rel.ro .bss.rel.ro) | .data .bss),
933 // where | marks where page alignment happens. An alternative ordering is
934 // PT_LOAD(.data | PT_GNU_RELRO( .data.rel.ro .bss.rel.ro) | .bss), but it may
935 // waste more bytes due to 2 alignment places.
936 if (!isRelroSection(sec))
937 rank |= RF_NOT_RELRO;
811938
812 bool IsTls = Sec->Flags & SHF_TLS;
813 bool IsNoBits = Sec->Type == SHT_NOBITS;
814
815 // The first requirement we have is to put (non-TLS) nobits sections last. The
816 // reason is that the only thing the dynamic linker will see about them is a
817 // p_memsz that is larger than p_filesz. Seeing that it zeros the end of the
818 // PT_LOAD, so that has to correspond to the nobits sections.
819 bool IsNonTlsNoBits = IsNoBits && !IsTls;
820 if (IsNonTlsNoBits)
821 Rank |= RF_NON_TLS_BSS;
822
823 // We place nobits RelRo sections before plain r/w ones, and non-nobits RelRo
824 // sections after r/w ones, so that the RelRo sections are contiguous.
825 bool IsRelRo = isRelroSection(Sec);
826 if (IsNonTlsNoBits && !IsRelRo)
827 Rank |= RF_NON_TLS_BSS_RO;
828 if (!IsNonTlsNoBits && IsRelRo)
829 Rank |= RF_NON_TLS_BSS_RO;
939 // If we got here we know that both A and B are in the same PT_LOAD.
830940
831941 // The TLS initialization block needs to be a single contiguous block in a R/W
832942 // PT_LOAD, so stick TLS sections directly before the other RelRo R/W
833 // sections. The TLS NOBITS sections are placed here as they don't take up
834 // virtual address space in the PT_LOAD.
835 if (!IsTls)
836 Rank |= RF_NOT_TLS;
943 // sections. Since p_filesz can be less than p_memsz, place NOBITS sections
944 // after PROGBITS.
945 if (!(sec->flags & SHF_TLS))
946 rank |= RF_NOT_TLS;
837947
838 // Within the TLS initialization block, the non-nobits sections need to appear
839 // first.
840 if (IsNoBits)
841 Rank |= RF_BSS;
948 // Within TLS sections, or within other RelRo sections, or within non-RelRo
949 // sections, place non-NOBITS sections first.
950 if (sec->type == SHT_NOBITS)
951 rank |= RF_BSS;
842952
843953 // Some architectures have additional ordering restrictions for sections
844954 // within the same PT_LOAD.
845 if (Config->EMachine == EM_PPC64) {
955 if (config->emachine == EM_PPC64) {
846956 // PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections
847957 // that we would like to make sure appear is a specific order to maximize
848958 // their coverage by a single signed 16-bit offset from the TOC base
849959 // pointer. Conversely, the special .tocbss section should be first among
850960 // all SHT_NOBITS sections. This will put it next to the loaded special
851961 // PPC64 sections (and, thus, within reach of the TOC base pointer).
852 StringRef Name = Sec->Name;
853 if (Name != ".tocbss")
854 Rank |= RF_PPC_NOT_TOCBSS;
962 StringRef name = sec->name;
963 if (name != ".tocbss")
964 rank |= RF_PPC_NOT_TOCBSS;
855965
856 if (Name == ".toc1")
857 Rank |= RF_PPC_TOCL;
966 if (name == ".toc1")
967 rank |= RF_PPC_TOCL;
858968
859 if (Name == ".toc")
860 Rank |= RF_PPC_TOC;
969 if (name == ".toc")
970 rank |= RF_PPC_TOC;
861971
862 if (Name == ".got")
863 Rank |= RF_PPC_GOT;
972 if (name == ".got")
973 rank |= RF_PPC_GOT;
864974
865 if (Name == ".branch_lt")
866 Rank |= RF_PPC_BRANCH_LT;
975 if (name == ".branch_lt")
976 rank |= RF_PPC_BRANCH_LT;
867977 }
868978
869 if (Config->EMachine == EM_MIPS) {
979 if (config->emachine == EM_MIPS) {
870980 // All sections with SHF_MIPS_GPREL flag should be grouped together
871981 // because data in these sections is addressable with a gp relative address.
872 if (Sec->Flags & SHF_MIPS_GPREL)
873 Rank |= RF_MIPS_GPREL;
982 if (sec->flags & SHF_MIPS_GPREL)
983 rank |= RF_MIPS_GPREL;
874984
875 if (Sec->Name != ".got")
876 Rank |= RF_MIPS_NOT_GOT;
985 if (sec->name != ".got")
986 rank |= RF_MIPS_NOT_GOT;
877987 }
878988
879 return Rank;
989 return rank;
880990}
881991
882static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {
883 const OutputSection *A = cast<OutputSection>(ACmd);
884 const OutputSection *B = cast<OutputSection>(BCmd);
992static bool compareSections(const BaseCommand *aCmd, const BaseCommand *bCmd) {
993 const OutputSection *a = cast<OutputSection>(aCmd);
994 const OutputSection *b = cast<OutputSection>(bCmd);
885995
886 if (A->SortRank != B->SortRank)
887 return A->SortRank < B->SortRank;
996 if (a->sortRank != b->sortRank)
997 return a->sortRank < b->sortRank;
888998
889 if (!(A->SortRank & RF_NOT_ADDR_SET))
890 return Config->SectionStartMap.lookup(A->Name) <
891 Config->SectionStartMap.lookup(B->Name);
999 if (!(a->sortRank & RF_NOT_ADDR_SET))
1000 return config->sectionStartMap.lookup(a->name) <
1001 config->sectionStartMap.lookup(b->name);
8921002 return false;
8931003}
8941004
895void PhdrEntry::add(OutputSection *Sec) {
896 LastSec = Sec;
897 if (!FirstSec)
898 FirstSec = Sec;
899 p_align = std::max(p_align, Sec->Alignment);
1005void PhdrEntry::add(OutputSection *sec) {
1006 lastSec = sec;
1007 if (!firstSec)
1008 firstSec = sec;
1009 p_align = std::max(p_align, sec->alignment);
9001010 if (p_type == PT_LOAD)
901 Sec->PtLoad = this;
1011 sec->ptLoad = this;
9021012}
9031013
9041014// The beginning and the ending of .rel[a].plt section are marked
......@@ -908,35 +1018,40 @@ void PhdrEntry::add(OutputSection *Sec) {
9081018// need these symbols, since IRELATIVE relocs are resolved through GOT
9091019// and PLT. For details, see http://www.airs.com/blog/archives/403.
9101020template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
911 if (Config->Relocatable || needsInterpSection())
1021 if (config->relocatable || needsInterpSection())
9121022 return;
9131023
9141024 // By default, __rela_iplt_{start,end} belong to a dummy section 0
9151025 // because .rela.plt might be empty and thus removed from output.
916 // We'll override Out::ElfHeader with In.RelaIplt later when we are
1026 // We'll override Out::elfHeader with In.relaIplt later when we are
9171027 // 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);
1028 ElfSym::relaIpltStart = addOptionalRegular(
1029 config->isRela ? "__rela_iplt_start" : "__rel_iplt_start",
1030 Out::elfHeader, 0, STV_HIDDEN, STB_WEAK);
9211031
922 ElfSym::RelaIpltEnd = addOptionalRegular(
923 Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end",
924 Out::ElfHeader, 0, STV_HIDDEN, STB_WEAK);
1032 ElfSym::relaIpltEnd = addOptionalRegular(
1033 config->isRela ? "__rela_iplt_end" : "__rel_iplt_end",
1034 Out::elfHeader, 0, STV_HIDDEN, STB_WEAK);
9251035}
9261036
9271037template <class ELFT>
9281038void Writer<ELFT>::forEachRelSec(
929 llvm::function_ref<void(InputSectionBase &)> Fn) {
1039 llvm::function_ref<void(InputSectionBase &)> fn) {
9301040 // Scan all relocations. Each relocation goes through a series
9311041 // of tests to determine if it needs special treatment, such as
9321042 // creating GOT, PLT, copy relocations, etc.
9331043 // Note that relocations for non-alloc sections are directly
9341044 // processed by InputSection::relocateNonAlloc.
935 for (InputSectionBase *IS : InputSections)
936 if (IS->Live && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))
937 Fn(*IS);
938 for (EhInputSection *ES : In.EhFrame->Sections)
939 Fn(*ES);
1045 for (InputSectionBase *isec : inputSections)
1046 if (isec->isLive() && isa<InputSection>(isec) && (isec->flags & SHF_ALLOC))
1047 fn(*isec);
1048 for (Partition &part : partitions) {
1049 for (EhInputSection *es : part.ehFrame->sections)
1050 fn(*es);
1051 if (part.armExidx && part.armExidx->isLive())
1052 for (InputSection *ex : part.armExidx->exidxSections)
1053 fn(*ex);
1054 }
9401055}
9411056
9421057// This function generates assignments for predefined symbols (e.g. _end or
......@@ -945,76 +1060,78 @@ void Writer<ELFT>::forEachRelSec(
9451060// time any references to these symbols are processed and is equivalent to
9461061// defining these symbols explicitly in the linker script.
9471062template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
948 if (ElfSym::GlobalOffsetTable) {
1063 if (ElfSym::globalOffsetTable) {
9491064 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
9501065 // to the start of the .got or .got.plt section.
951 InputSection *GotSection = In.GotPlt;
952 if (!Target->GotBaseSymInGotPlt)
953 GotSection = In.MipsGot ? cast<InputSection>(In.MipsGot)
954 : cast<InputSection>(In.Got);
955 ElfSym::GlobalOffsetTable->Section = GotSection;
1066 InputSection *gotSection = in.gotPlt;
1067 if (!target->gotBaseSymInGotPlt)
1068 gotSection = in.mipsGot ? cast<InputSection>(in.mipsGot)
1069 : cast<InputSection>(in.got);
1070 ElfSym::globalOffsetTable->section = gotSection;
9561071 }
9571072
9581073 // .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();
1074 if (ElfSym::relaIpltStart && in.relaIplt->isNeeded()) {
1075 ElfSym::relaIpltStart->section = in.relaIplt;
1076 ElfSym::relaIpltEnd->section = in.relaIplt;
1077 ElfSym::relaIpltEnd->value = in.relaIplt->getSize();
9631078 }
9641079
965 PhdrEntry *Last = nullptr;
966 PhdrEntry *LastRO = nullptr;
1080 PhdrEntry *last = nullptr;
1081 PhdrEntry *lastRO = nullptr;
9671082
968 for (PhdrEntry *P : Phdrs) {
969 if (P->p_type != PT_LOAD)
970 continue;
971 Last = P;
972 if (!(P->p_flags & PF_W))
973 LastRO = P;
1083 for (Partition &part : partitions) {
1084 for (PhdrEntry *p : part.phdrs) {
1085 if (p->p_type != PT_LOAD)
1086 continue;
1087 last = p;
1088 if (!(p->p_flags & PF_W))
1089 lastRO = p;
1090 }
9741091 }
9751092
976 if (LastRO) {
1093 if (lastRO) {
9771094 // _etext is the first location after the last read-only loadable segment.
978 if (ElfSym::Etext1)
979 ElfSym::Etext1->Section = LastRO->LastSec;
980 if (ElfSym::Etext2)
981 ElfSym::Etext2->Section = LastRO->LastSec;
1095 if (ElfSym::etext1)
1096 ElfSym::etext1->section = lastRO->lastSec;
1097 if (ElfSym::etext2)
1098 ElfSym::etext2->section = lastRO->lastSec;
9821099 }
9831100
984 if (Last) {
1101 if (last) {
9851102 // _edata points to the end of the last mapped initialized section.
986 OutputSection *Edata = nullptr;
987 for (OutputSection *OS : OutputSections) {
988 if (OS->Type != SHT_NOBITS)
989 Edata = OS;
990 if (OS == Last->LastSec)
1103 OutputSection *edata = nullptr;
1104 for (OutputSection *os : outputSections) {
1105 if (os->type != SHT_NOBITS)
1106 edata = os;
1107 if (os == last->lastSec)
9911108 break;
9921109 }
9931110
994 if (ElfSym::Edata1)
995 ElfSym::Edata1->Section = Edata;
996 if (ElfSym::Edata2)
997 ElfSym::Edata2->Section = Edata;
1111 if (ElfSym::edata1)
1112 ElfSym::edata1->section = edata;
1113 if (ElfSym::edata2)
1114 ElfSym::edata2->section = edata;
9981115
9991116 // _end is the first location after the uninitialized data region.
1000 if (ElfSym::End1)
1001 ElfSym::End1->Section = Last->LastSec;
1002 if (ElfSym::End2)
1003 ElfSym::End2->Section = Last->LastSec;
1117 if (ElfSym::end1)
1118 ElfSym::end1->section = last->lastSec;
1119 if (ElfSym::end2)
1120 ElfSym::end2->section = last->lastSec;
10041121 }
10051122
1006 if (ElfSym::Bss)
1007 ElfSym::Bss->Section = findSection(".bss");
1123 if (ElfSym::bss)
1124 ElfSym::bss->section = findSection(".bss");
10081125
10091126 // Setup MIPS _gp_disp/__gnu_local_gp symbols which should
10101127 // be equal to the _gp symbol's value.
1011 if (ElfSym::MipsGp) {
1128 if (ElfSym::mipsGp) {
10121129 // Find GP-relative section with the lowest address
10131130 // and use this address to calculate default _gp value.
1014 for (OutputSection *OS : OutputSections) {
1015 if (OS->Flags & SHF_MIPS_GPREL) {
1016 ElfSym::MipsGp->Section = OS;
1017 ElfSym::MipsGp->Value = 0x7ff0;
1131 for (OutputSection *os : outputSections) {
1132 if (os->flags & SHF_MIPS_GPREL) {
1133 ElfSym::mipsGp->section = os;
1134 ElfSym::mipsGp->value = 0x7ff0;
10181135 break;
10191136 }
10201137 }
......@@ -1025,14 +1142,13 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
10251142// The more branches in getSectionRank that match, the more similar they are.
10261143// Since each branch corresponds to a bit flag, we can just use
10271144// countLeadingZeros.
1028static int getRankProximityAux(OutputSection *A, OutputSection *B) {
1029 return countLeadingZeros(A->SortRank ^ B->SortRank);
1145static int getRankProximityAux(OutputSection *a, OutputSection *b) {
1146 return countLeadingZeros(a->sortRank ^ b->sortRank);
10301147}
10311148
1032static int getRankProximity(OutputSection *A, BaseCommand *B) {
1033 if (auto *Sec = dyn_cast<OutputSection>(B))
1034 return getRankProximityAux(A, Sec);
1035 return -1;
1149static int getRankProximity(OutputSection *a, BaseCommand *b) {
1150 auto *sec = dyn_cast<OutputSection>(b);
1151 return (sec && sec->hasInputSections) ? getRankProximityAux(a, sec) : -1;
10361152}
10371153
10381154// When placing orphan sections, we want to place them after symbol assignments
......@@ -1049,137 +1165,142 @@ static int getRankProximity(OutputSection *A, BaseCommand *B) {
10491165// /* The RW PT_LOAD starts here*/
10501166// rw_sec : { *(rw_sec) }
10511167// would mean that the RW PT_LOAD would become unaligned.
1052static bool shouldSkip(BaseCommand *Cmd) {
1053 if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
1054 return Assign->Name != ".";
1168static bool shouldSkip(BaseCommand *cmd) {
1169 if (auto *assign = dyn_cast<SymbolAssignment>(cmd))
1170 return assign->name != ".";
10551171 return false;
10561172}
10571173
10581174// We want to place orphan sections so that they share as much
10591175// characteristics with their neighbors as possible. For example, if
10601176// both are rw, or both are tls.
1061template <typename ELFT>
10621177static std::vector<BaseCommand *>::iterator
1063findOrphanPos(std::vector<BaseCommand *>::iterator B,
1064 std::vector<BaseCommand *>::iterator E) {
1065 OutputSection *Sec = cast<OutputSection>(*E);
1178findOrphanPos(std::vector<BaseCommand *>::iterator b,
1179 std::vector<BaseCommand *>::iterator e) {
1180 OutputSection *sec = cast<OutputSection>(*e);
10661181
10671182 // Find the first element that has as close a rank as possible.
1068 auto I = std::max_element(B, E, [=](BaseCommand *A, BaseCommand *B) {
1069 return getRankProximity(Sec, A) < getRankProximity(Sec, B);
1183 auto i = std::max_element(b, e, [=](BaseCommand *a, BaseCommand *b) {
1184 return getRankProximity(sec, a) < getRankProximity(sec, b);
10701185 });
1071 if (I == E)
1072 return E;
1186 if (i == e)
1187 return e;
10731188
10741189 // Consider all existing sections with the same proximity.
1075 int Proximity = getRankProximity(Sec, *I);
1076 for (; I != E; ++I) {
1077 auto *CurSec = dyn_cast<OutputSection>(*I);
1078 if (!CurSec)
1190 int proximity = getRankProximity(sec, *i);
1191 for (; i != e; ++i) {
1192 auto *curSec = dyn_cast<OutputSection>(*i);
1193 if (!curSec || !curSec->hasInputSections)
10791194 continue;
1080 if (getRankProximity(Sec, CurSec) != Proximity ||
1081 Sec->SortRank < CurSec->SortRank)
1195 if (getRankProximity(sec, curSec) != proximity ||
1196 sec->sortRank < curSec->sortRank)
10821197 break;
10831198 }
10841199
1085 auto IsOutputSec = [](BaseCommand *Cmd) { return isa<OutputSection>(Cmd); };
1086 auto J = std::find_if(llvm::make_reverse_iterator(I),
1087 llvm::make_reverse_iterator(B), IsOutputSec);
1088 I = J.base();
1200 auto isOutputSecWithInputSections = [](BaseCommand *cmd) {
1201 auto *os = dyn_cast<OutputSection>(cmd);
1202 return os && os->hasInputSections;
1203 };
1204 auto j = std::find_if(llvm::make_reverse_iterator(i),
1205 llvm::make_reverse_iterator(b),
1206 isOutputSecWithInputSections);
1207 i = j.base();
10891208
10901209 // As a special case, if the orphan section is the last section, put
10911210 // it at the very end, past any other commands.
10921211 // This matches bfd's behavior and is convenient when the linker script fully
10931212 // specifies the start of the file, but doesn't care about the end (the non
10941213 // alloc sections for example).
1095 auto NextSec = std::find_if(I, E, IsOutputSec);
1096 if (NextSec == E)
1097 return E;
1214 auto nextSec = std::find_if(i, e, isOutputSecWithInputSections);
1215 if (nextSec == e)
1216 return e;
10981217
1099 while (I != E && shouldSkip(*I))
1100 ++I;
1101 return I;
1218 while (i != e && shouldSkip(*i))
1219 ++i;
1220 return i;
11021221}
11031222
11041223// Builds section order for handling --symbol-ordering-file.
11051224static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
1106 DenseMap<const InputSectionBase *, int> SectionOrder;
1225 DenseMap<const InputSectionBase *, int> sectionOrder;
11071226 // Use the rarely used option -call-graph-ordering-file to sort sections.
1108 if (!Config->CallGraphProfile.empty())
1227 if (!config->callGraphProfile.empty())
11091228 return computeCallGraphProfileOrder();
11101229
1111 if (Config->SymbolOrderingFile.empty())
1112 return SectionOrder;
1230 if (config->symbolOrderingFile.empty())
1231 return sectionOrder;
11131232
11141233 struct SymbolOrderEntry {
1115 int Priority;
1116 bool Present;
1234 int priority;
1235 bool present;
11171236 };
11181237
11191238 // Build a map from symbols to their priorities. Symbols that didn't
11201239 // appear in the symbol ordering file have the lowest priority 0.
11211240 // All explicitly mentioned symbols have negative (higher) priorities.
1122 DenseMap<StringRef, SymbolOrderEntry> SymbolOrder;
1123 int Priority = -Config->SymbolOrderingFile.size();
1124 for (StringRef S : Config->SymbolOrderingFile)
1125 SymbolOrder.insert({S, {Priority++, false}});
1241 DenseMap<StringRef, SymbolOrderEntry> symbolOrder;
1242 int priority = -config->symbolOrderingFile.size();
1243 for (StringRef s : config->symbolOrderingFile)
1244 symbolOrder.insert({s, {priority++, false}});
11261245
11271246 // Build a map from sections to their priorities.
1128 auto AddSym = [&](Symbol &Sym) {
1129 auto It = SymbolOrder.find(Sym.getName());
1130 if (It == SymbolOrder.end())
1247 auto addSym = [&](Symbol &sym) {
1248 auto it = symbolOrder.find(sym.getName());
1249 if (it == symbolOrder.end())
11311250 return;
1132 SymbolOrderEntry &Ent = It->second;
1133 Ent.Present = true;
1251 SymbolOrderEntry &ent = it->second;
1252 ent.present = true;
11341253
1135 maybeWarnUnorderableSymbol(&Sym);
1254 maybeWarnUnorderableSymbol(&sym);
11361255
1137 if (auto *D = dyn_cast<Defined>(&Sym)) {
1138 if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
1139 int &Priority = SectionOrder[cast<InputSectionBase>(Sec->Repl)];
1140 Priority = std::min(Priority, Ent.Priority);
1256 if (auto *d = dyn_cast<Defined>(&sym)) {
1257 if (auto *sec = dyn_cast_or_null<InputSectionBase>(d->section)) {
1258 int &priority = sectionOrder[cast<InputSectionBase>(sec->repl)];
1259 priority = std::min(priority, ent.priority);
11411260 }
11421261 }
11431262 };
11441263
11451264 // We want both global and local symbols. We get the global ones from the
11461265 // symbol table and iterate the object files for the local ones.
1147 for (Symbol *Sym : Symtab->getSymbols())
1148 if (!Sym->isLazy())
1149 AddSym(*Sym);
1150 for (InputFile *File : ObjectFiles)
1151 for (Symbol *Sym : File->getSymbols())
1152 if (Sym->isLocal())
1153 AddSym(*Sym);
1266 symtab->forEachSymbol([&](Symbol *sym) {
1267 if (!sym->isLazy())
1268 addSym(*sym);
1269 });
11541270
1155 if (Config->WarnSymbolOrdering)
1156 for (auto OrderEntry : SymbolOrder)
1157 if (!OrderEntry.second.Present)
1158 warn("symbol ordering file: no such symbol: " + OrderEntry.first);
1271 for (InputFile *file : objectFiles)
1272 for (Symbol *sym : file->getSymbols())
1273 if (sym->isLocal())
1274 addSym(*sym);
11591275
1160 return SectionOrder;
1276 if (config->warnSymbolOrdering)
1277 for (auto orderEntry : symbolOrder)
1278 if (!orderEntry.second.present)
1279 warn("symbol ordering file: no such symbol: " + orderEntry.first);
1280
1281 return sectionOrder;
11611282}
11621283
11631284// Sorts the sections in ISD according to the provided section order.
11641285static void
1165sortISDBySectionOrder(InputSectionDescription *ISD,
1166 const DenseMap<const InputSectionBase *, int> &Order) {
1167 std::vector<InputSection *> UnorderedSections;
1168 std::vector<std::pair<InputSection *, int>> OrderedSections;
1169 uint64_t UnorderedSize = 0;
1170
1171 for (InputSection *IS : ISD->Sections) {
1172 auto I = Order.find(IS);
1173 if (I == Order.end()) {
1174 UnorderedSections.push_back(IS);
1175 UnorderedSize += IS->getSize();
1286sortISDBySectionOrder(InputSectionDescription *isd,
1287 const DenseMap<const InputSectionBase *, int> &order) {
1288 std::vector<InputSection *> unorderedSections;
1289 std::vector<std::pair<InputSection *, int>> orderedSections;
1290 uint64_t unorderedSize = 0;
1291
1292 for (InputSection *isec : isd->sections) {
1293 auto i = order.find(isec);
1294 if (i == order.end()) {
1295 unorderedSections.push_back(isec);
1296 unorderedSize += isec->getSize();
11761297 continue;
11771298 }
1178 OrderedSections.push_back({IS, I->second});
1299 orderedSections.push_back({isec, i->second});
11791300 }
1180 llvm::sort(OrderedSections, [&](std::pair<InputSection *, int> A,
1181 std::pair<InputSection *, int> B) {
1182 return A.second < B.second;
1301 llvm::sort(orderedSections, [&](std::pair<InputSection *, int> a,
1302 std::pair<InputSection *, int> b) {
1303 return a.second < b.second;
11831304 });
11841305
11851306 // Find an insertion point for the ordered section list in the unordered
......@@ -1209,96 +1330,114 @@ sortISDBySectionOrder(InputSectionDescription *ISD,
12091330 // of the second block of cold code can call the hot code without a thunk. So
12101331 // we effectively double the amount of code that could potentially call into
12111332 // the hot code without a thunk.
1212 size_t InsPt = 0;
1213 if (Target->getThunkSectionSpacing() && !OrderedSections.empty()) {
1214 uint64_t UnorderedPos = 0;
1215 for (; InsPt != UnorderedSections.size(); ++InsPt) {
1216 UnorderedPos += UnorderedSections[InsPt]->getSize();
1217 if (UnorderedPos > UnorderedSize / 2)
1333 size_t insPt = 0;
1334 if (target->getThunkSectionSpacing() && !orderedSections.empty()) {
1335 uint64_t unorderedPos = 0;
1336 for (; insPt != unorderedSections.size(); ++insPt) {
1337 unorderedPos += unorderedSections[insPt]->getSize();
1338 if (unorderedPos > unorderedSize / 2)
12181339 break;
12191340 }
12201341 }
12211342
1222 ISD->Sections.clear();
1223 for (InputSection *IS : makeArrayRef(UnorderedSections).slice(0, InsPt))
1224 ISD->Sections.push_back(IS);
1225 for (std::pair<InputSection *, int> P : OrderedSections)
1226 ISD->Sections.push_back(P.first);
1227 for (InputSection *IS : makeArrayRef(UnorderedSections).slice(InsPt))
1228 ISD->Sections.push_back(IS);
1343 isd->sections.clear();
1344 for (InputSection *isec : makeArrayRef(unorderedSections).slice(0, insPt))
1345 isd->sections.push_back(isec);
1346 for (std::pair<InputSection *, int> p : orderedSections)
1347 isd->sections.push_back(p.first);
1348 for (InputSection *isec : makeArrayRef(unorderedSections).slice(insPt))
1349 isd->sections.push_back(isec);
12291350}
12301351
1231static void sortSection(OutputSection *Sec,
1232 const DenseMap<const InputSectionBase *, int> &Order) {
1233 StringRef Name = Sec->Name;
1352static void sortSection(OutputSection *sec,
1353 const DenseMap<const InputSectionBase *, int> &order) {
1354 StringRef name = sec->name;
12341355
12351356 // Sort input sections by section name suffixes for
12361357 // __attribute__((init_priority(N))).
1237 if (Name == ".init_array" || Name == ".fini_array") {
1238 if (!Script->HasSectionsCommand)
1239 Sec->sortInitFini();
1358 if (name == ".init_array" || name == ".fini_array") {
1359 if (!script->hasSectionsCommand)
1360 sec->sortInitFini();
12401361 return;
12411362 }
12421363
12431364 // Sort input sections by the special rule for .ctors and .dtors.
1244 if (Name == ".ctors" || Name == ".dtors") {
1245 if (!Script->HasSectionsCommand)
1246 Sec->sortCtorsDtors();
1365 if (name == ".ctors" || name == ".dtors") {
1366 if (!script->hasSectionsCommand)
1367 sec->sortCtorsDtors();
12471368 return;
12481369 }
12491370
12501371 // Never sort these.
1251 if (Name == ".init" || Name == ".fini")
1372 if (name == ".init" || name == ".fini")
1373 return;
1374
1375 // .toc is allocated just after .got and is accessed using GOT-relative
1376 // relocations. Object files compiled with small code model have an
1377 // addressable range of [.got, .got + 0xFFFC] for GOT-relative relocations.
1378 // To reduce the risk of relocation overflow, .toc contents are sorted so that
1379 // sections having smaller relocation offsets are at beginning of .toc
1380 if (config->emachine == EM_PPC64 && name == ".toc") {
1381 if (script->hasSectionsCommand)
1382 return;
1383 assert(sec->sectionCommands.size() == 1);
1384 auto *isd = cast<InputSectionDescription>(sec->sectionCommands[0]);
1385 llvm::stable_sort(isd->sections,
1386 [](const InputSection *a, const InputSection *b) -> bool {
1387 return a->file->ppc64SmallCodeModelTocRelocs &&
1388 !b->file->ppc64SmallCodeModelTocRelocs;
1389 });
12521390 return;
1391 }
12531392
12541393 // Sort input sections by priority using the list provided
12551394 // by --symbol-ordering-file.
1256 if (!Order.empty())
1257 for (BaseCommand *B : Sec->SectionCommands)
1258 if (auto *ISD = dyn_cast<InputSectionDescription>(B))
1259 sortISDBySectionOrder(ISD, Order);
1395 if (!order.empty())
1396 for (BaseCommand *b : sec->sectionCommands)
1397 if (auto *isd = dyn_cast<InputSectionDescription>(b))
1398 sortISDBySectionOrder(isd, order);
12601399}
12611400
12621401// If no layout was provided by linker script, we want to apply default
12631402// sorting for special input sections. This also handles --symbol-ordering-file.
12641403template <class ELFT> void Writer<ELFT>::sortInputSections() {
12651404 // Build the order once since it is expensive.
1266 DenseMap<const InputSectionBase *, int> Order = buildSectionOrder();
1267 for (BaseCommand *Base : Script->SectionCommands)
1268 if (auto *Sec = dyn_cast<OutputSection>(Base))
1269 sortSection(Sec, Order);
1405 DenseMap<const InputSectionBase *, int> order = buildSectionOrder();
1406 for (BaseCommand *base : script->sectionCommands)
1407 if (auto *sec = dyn_cast<OutputSection>(base))
1408 sortSection(sec, order);
12701409}
12711410
12721411template <class ELFT> void Writer<ELFT>::sortSections() {
1273 Script->adjustSectionsBeforeSorting();
1412 script->adjustSectionsBeforeSorting();
12741413
12751414 // Don't sort if using -r. It is not necessary and we want to preserve the
12761415 // relative order for SHF_LINK_ORDER sections.
1277 if (Config->Relocatable)
1416 if (config->relocatable)
12781417 return;
12791418
12801419 sortInputSections();
12811420
1282 for (BaseCommand *Base : Script->SectionCommands) {
1283 auto *OS = dyn_cast<OutputSection>(Base);
1284 if (!OS)
1421 for (BaseCommand *base : script->sectionCommands) {
1422 auto *os = dyn_cast<OutputSection>(base);
1423 if (!os)
12851424 continue;
1286 OS->SortRank = getSectionRank(OS);
1425 os->sortRank = getSectionRank(os);
12871426
1288 // We want to assign rude approximation values to OutSecOff fields
1427 // We want to assign rude approximation values to outSecOff fields
12891428 // to know the relative order of the input sections. We use it for
12901429 // sorting SHF_LINK_ORDER sections. See resolveShfLinkOrder().
1291 uint64_t I = 0;
1292 for (InputSection *Sec : getInputSections(OS))
1293 Sec->OutSecOff = I++;
1430 uint64_t i = 0;
1431 for (InputSection *sec : getInputSections(os))
1432 sec->outSecOff = i++;
12941433 }
12951434
1296 if (!Script->HasSectionsCommand) {
1435 if (!script->hasSectionsCommand) {
12971436 // We know that all the OutputSections are contiguous in this case.
1298 auto IsSection = [](BaseCommand *Base) { return isa<OutputSection>(Base); };
1437 auto isSection = [](BaseCommand *base) { return isa<OutputSection>(base); };
12991438 std::stable_sort(
1300 llvm::find_if(Script->SectionCommands, IsSection),
1301 llvm::find_if(llvm::reverse(Script->SectionCommands), IsSection).base(),
1439 llvm::find_if(script->sectionCommands, isSection),
1440 llvm::find_if(llvm::reverse(script->sectionCommands), isSection).base(),
13021441 compareSections);
13031442 return;
13041443 }
......@@ -1342,211 +1481,127 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
13421481 // after another commands. For the details, look at shouldSkip
13431482 // function.
13441483
1345 auto I = Script->SectionCommands.begin();
1346 auto E = Script->SectionCommands.end();
1347 auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) {
1348 if (auto *Sec = dyn_cast<OutputSection>(Base))
1349 return Sec->SectionIndex == UINT32_MAX;
1484 auto i = script->sectionCommands.begin();
1485 auto e = script->sectionCommands.end();
1486 auto nonScriptI = std::find_if(i, e, [](BaseCommand *base) {
1487 if (auto *sec = dyn_cast<OutputSection>(base))
1488 return sec->sectionIndex == UINT32_MAX;
13501489 return false;
13511490 });
13521491
13531492 // Sort the orphan sections.
1354 std::stable_sort(NonScriptI, E, compareSections);
1493 std::stable_sort(nonScriptI, e, compareSections);
13551494
13561495 // As a horrible special case, skip the first . assignment if it is before any
13571496 // section. We do this because it is common to set a load address by starting
13581497 // the script with ". = 0xabcd" and the expectation is that every section is
13591498 // after that.
1360 auto FirstSectionOrDotAssignment =
1361 std::find_if(I, E, [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
1362 if (FirstSectionOrDotAssignment != E &&
1363 isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
1364 ++FirstSectionOrDotAssignment;
1365 I = FirstSectionOrDotAssignment;
1499 auto firstSectionOrDotAssignment =
1500 std::find_if(i, e, [](BaseCommand *cmd) { return !shouldSkip(cmd); });
1501 if (firstSectionOrDotAssignment != e &&
1502 isa<SymbolAssignment>(**firstSectionOrDotAssignment))
1503 ++firstSectionOrDotAssignment;
1504 i = firstSectionOrDotAssignment;
13661505
1367 while (NonScriptI != E) {
1368 auto Pos = findOrphanPos<ELFT>(I, NonScriptI);
1369 OutputSection *Orphan = cast<OutputSection>(*NonScriptI);
1506 while (nonScriptI != e) {
1507 auto pos = findOrphanPos(i, nonScriptI);
1508 OutputSection *orphan = cast<OutputSection>(*nonScriptI);
13701509
13711510 // As an optimization, find all sections with the same sort rank
13721511 // and insert them with one rotate.
1373 unsigned Rank = Orphan->SortRank;
1374 auto End = std::find_if(NonScriptI + 1, E, [=](BaseCommand *Cmd) {
1375 return cast<OutputSection>(Cmd)->SortRank != Rank;
1512 unsigned rank = orphan->sortRank;
1513 auto end = std::find_if(nonScriptI + 1, e, [=](BaseCommand *cmd) {
1514 return cast<OutputSection>(cmd)->sortRank != rank;
13761515 });
1377 std::rotate(Pos, NonScriptI, End);
1378 NonScriptI = End;
1516 std::rotate(pos, nonScriptI, end);
1517 nonScriptI = end;
13791518 }
13801519
1381 Script->adjustSectionsAfterSorting();
1520 script->adjustSectionsAfterSorting();
13821521}
13831522
1384static bool compareByFilePosition(InputSection *A, InputSection *B) {
1385 // Synthetic, i. e. a sentinel section, should go last.
1386 if (A->kind() == InputSectionBase::Synthetic ||
1387 B->kind() == InputSectionBase::Synthetic)
1388 return A->kind() != InputSectionBase::Synthetic;
1389
1390 InputSection *LA = A->getLinkOrderDep();
1391 InputSection *LB = B->getLinkOrderDep();
1392 OutputSection *AOut = LA->getParent();
1393 OutputSection *BOut = LB->getParent();
1394
1395 if (AOut != BOut)
1396 return AOut->SectionIndex < BOut->SectionIndex;
1397 return LA->OutSecOff < LB->OutSecOff;
1398}
1399
1400// This function is used by the --merge-exidx-entries to detect duplicate
1401// .ARM.exidx sections. It is Arm only.
1402//
1403// The .ARM.exidx section is of the form:
1404// | PREL31 offset to function | Unwind instructions for function |
1405// where the unwind instructions are either a small number of unwind
1406// instructions inlined into the table entry, the special CANT_UNWIND value of
1407// 0x1 or a PREL31 offset into a .ARM.extab Section that contains unwind
1408// instructions.
1409//
1410// We return true if all the unwind instructions in the .ARM.exidx entries of
1411// Cur can be merged into the last entry of Prev.
1412static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {
1413
1414 // References to .ARM.Extab Sections have bit 31 clear and are not the
1415 // special EXIDX_CANTUNWIND bit-pattern.
1416 auto IsExtabRef = [](uint32_t Unwind) {
1417 return (Unwind & 0x80000000) == 0 && Unwind != 0x1;
1418 };
1419
1420 struct ExidxEntry {
1421 ulittle32_t Fn;
1422 ulittle32_t Unwind;
1423 };
1424
1425 // Get the last table Entry from the previous .ARM.exidx section.
1426 const ExidxEntry &PrevEntry = Prev->getDataAs<ExidxEntry>().back();
1427 if (IsExtabRef(PrevEntry.Unwind))
1428 return false;
1429
1430 // We consider the unwind instructions of an .ARM.exidx table entry
1431 // a duplicate if the previous unwind instructions if:
1432 // - Both are the special EXIDX_CANTUNWIND.
1433 // - Both are the same inline unwind instructions.
1434 // We do not attempt to follow and check links into .ARM.extab tables as
1435 // consecutive identical entries are rare and the effort to check that they
1436 // are identical is high.
1523static bool compareByFilePosition(InputSection *a, InputSection *b) {
1524 InputSection *la = a->getLinkOrderDep();
1525 InputSection *lb = b->getLinkOrderDep();
1526 OutputSection *aOut = la->getParent();
1527 OutputSection *bOut = lb->getParent();
14371528
1438 for (const ExidxEntry Entry : Cur->getDataAs<ExidxEntry>())
1439 if (IsExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind)
1440 return false;
1441
1442 // All table entries in this .ARM.exidx Section can be merged into the
1443 // previous Section.
1444 return true;
1529 if (aOut != bOut)
1530 return aOut->sectionIndex < bOut->sectionIndex;
1531 return la->outSecOff < lb->outSecOff;
14451532}
14461533
14471534template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
1448 for (OutputSection *Sec : OutputSections) {
1449 if (!(Sec->Flags & SHF_LINK_ORDER))
1535 for (OutputSection *sec : outputSections) {
1536 if (!(sec->flags & SHF_LINK_ORDER))
14501537 continue;
14511538
14521539 // Link order may be distributed across several InputSectionDescriptions
14531540 // but sort must consider them all at once.
1454 std::vector<InputSection **> ScriptSections;
1455 std::vector<InputSection *> Sections;
1456 for (BaseCommand *Base : Sec->SectionCommands) {
1457 if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
1458 for (InputSection *&IS : ISD->Sections) {
1459 ScriptSections.push_back(&IS);
1460 Sections.push_back(IS);
1541 std::vector<InputSection **> scriptSections;
1542 std::vector<InputSection *> sections;
1543 for (BaseCommand *base : sec->sectionCommands) {
1544 if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
1545 for (InputSection *&isec : isd->sections) {
1546 scriptSections.push_back(&isec);
1547 sections.push_back(isec);
14611548 }
14621549 }
14631550 }
1464 std::stable_sort(Sections.begin(), Sections.end(), compareByFilePosition);
1465
1466 if (!Config->Relocatable && Config->EMachine == EM_ARM &&
1467 Sec->Type == SHT_ARM_EXIDX) {
1468
1469 if (auto *Sentinel = dyn_cast<ARMExidxSentinelSection>(Sections.back())) {
1470 assert(Sections.size() >= 2 &&
1471 "We should create a sentinel section only if there are "
1472 "alive regular exidx sections.");
14731551
1474 // The last executable section is required to fill the sentinel.
1475 // Remember it here so that we don't have to find it again.
1476 Sentinel->Highest = Sections[Sections.size() - 2]->getLinkOrderDep();
1477 }
1478
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.
1485 if (Config->MergeArmExidx) {
1486 size_t Prev = 0;
1487 // The last one is a sentinel entry which should not be removed.
1488 for (size_t I = 1; I < Sections.size() - 1; ++I) {
1489 if (isDuplicateArmExidxSec(Sections[Prev], Sections[I]))
1490 Sections[I] = nullptr;
1491 else
1492 Prev = I;
1493 }
1494 }
1495 }
1552 // The ARM.exidx section use SHF_LINK_ORDER, but we have consolidated
1553 // this processing inside the ARMExidxsyntheticsection::finalizeContents().
1554 if (!config->relocatable && config->emachine == EM_ARM &&
1555 sec->type == SHT_ARM_EXIDX)
1556 continue;
14961557
1497 for (int I = 0, N = Sections.size(); I < N; ++I)
1498 *ScriptSections[I] = Sections[I];
1558 llvm::stable_sort(sections, compareByFilePosition);
14991559
1500 // Remove the Sections we marked as duplicate earlier.
1501 for (BaseCommand *Base : Sec->SectionCommands)
1502 if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
1503 llvm::erase_if(ISD->Sections, [](InputSection *IS) { return !IS; });
1560 for (int i = 0, n = sections.size(); i < n; ++i)
1561 *scriptSections[i] = sections[i];
15041562 }
15051563}
15061564
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;
1565// We need to generate and finalize the content that depends on the address of
1566// InputSections. As the generation of the content may also alter InputSection
1567// addresses we must converge to a fixed point. We do that here. See the comment
1568// in Writer<ELFT>::finalizeSections().
1569template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
1570 ThunkCreator tc;
1571 AArch64Err843419Patcher a64p;
15191572
1573 // For some targets, like x86, this loop iterates only once.
15201574 for (;;) {
1521 bool Changed = false;
1575 bool changed = false;
15221576
1523 Script->assignAddresses();
1577 script->assignAddresses();
15241578
1525 if (Target->NeedsThunks)
1526 Changed |= TC.createThunks(OutputSections);
1579 if (target->needsThunks)
1580 changed |= tc.createThunks(outputSections);
15271581
1528 if (Config->FixCortexA53Errata843419) {
1529 if (Changed)
1530 Script->assignAddresses();
1531 Changed |= A64P.createFixes();
1582 if (config->fixCortexA53Errata843419) {
1583 if (changed)
1584 script->assignAddresses();
1585 changed |= a64p.createFixes();
15321586 }
15331587
1534 if (In.MipsGot)
1535 In.MipsGot->updateAllocSize();
1536
1537 Changed |= In.RelaDyn->updateAllocSize();
1588 if (in.mipsGot)
1589 in.mipsGot->updateAllocSize();
15381590
1539 if (In.RelrDyn)
1540 Changed |= In.RelrDyn->updateAllocSize();
1591 for (Partition &part : partitions) {
1592 changed |= part.relaDyn->updateAllocSize();
1593 if (part.relrDyn)
1594 changed |= part.relrDyn->updateAllocSize();
1595 }
15411596
1542 if (!Changed)
1597 if (!changed)
15431598 return;
15441599 }
15451600}
15461601
1547static void finalizeSynthetic(SyntheticSection *Sec) {
1548 if (Sec && !Sec->empty() && Sec->getParent())
1549 Sec->finalizeContents();
1602static void finalizeSynthetic(SyntheticSection *sec) {
1603 if (sec && sec->isNeeded() && sec->getParent())
1604 sec->finalizeContents();
15501605}
15511606
15521607// In order to allow users to manipulate linker-synthesized sections,
......@@ -1565,128 +1620,190 @@ static void removeUnusedSyntheticSections() {
15651620 // All input synthetic sections that can be empty are placed after
15661621 // all regular ones. We iterate over them all and exit at first
15671622 // non-synthetic.
1568 for (InputSectionBase *S : llvm::reverse(InputSections)) {
1569 SyntheticSection *SS = dyn_cast<SyntheticSection>(S);
1570 if (!SS)
1623 for (InputSectionBase *s : llvm::reverse(inputSections)) {
1624 SyntheticSection *ss = dyn_cast<SyntheticSection>(s);
1625 if (!ss)
15711626 return;
1572 OutputSection *OS = SS->getParent();
1573 if (!OS || !SS->empty())
1627 OutputSection *os = ss->getParent();
1628 if (!os || ss->isNeeded())
15741629 continue;
15751630
15761631 // If we reach here, then SS is an unused synthetic section and we want to
15771632 // remove it from corresponding input section description of output section.
1578 for (BaseCommand *B : OS->SectionCommands)
1579 if (auto *ISD = dyn_cast<InputSectionDescription>(B))
1580 llvm::erase_if(ISD->Sections,
1581 [=](InputSection *IS) { return IS == SS; });
1633 for (BaseCommand *b : os->sectionCommands)
1634 if (auto *isd = dyn_cast<InputSectionDescription>(b))
1635 llvm::erase_if(isd->sections,
1636 [=](InputSection *isec) { return isec == ss; });
15821637 }
15831638}
15841639
15851640// Returns true if a symbol can be replaced at load-time by a symbol
15861641// with the same name defined in other ELF executable or DSO.
1587static bool computeIsPreemptible(const Symbol &B) {
1588 assert(!B.isLocal());
1642static bool computeIsPreemptible(const Symbol &b) {
1643 assert(!b.isLocal());
15891644
15901645 // Only symbols that appear in dynsym can be preempted.
1591 if (!B.includeInDynsym())
1646 if (!b.includeInDynsym())
15921647 return false;
15931648
15941649 // Only default visibility symbols can be preempted.
1595 if (B.Visibility != STV_DEFAULT)
1650 if (b.visibility != STV_DEFAULT)
15961651 return false;
15971652
15981653 // At this point copy relocations have not been created yet, so any
15991654 // symbol that is not defined locally is preemptible.
1600 if (!B.isDefined())
1655 if (!b.isDefined())
16011656 return true;
16021657
16031658 // If we have a dynamic list it specifies which local symbols are preemptible.
1604 if (Config->HasDynamicList)
1659 if (config->hasDynamicList)
16051660 return false;
16061661
1607 if (!Config->Shared)
1662 if (!config->shared)
16081663 return false;
16091664
16101665 // -Bsymbolic means that definitions are not preempted.
1611 if (Config->Bsymbolic || (Config->BsymbolicFunctions && B.isFunc()))
1666 if (config->bsymbolic || (config->bsymbolicFunctions && b.isFunc()))
16121667 return false;
16131668 return true;
16141669}
16151670
16161671// Create output section objects and add them to OutputSections.
16171672template <class ELFT> void Writer<ELFT>::finalizeSections() {
1618 Out::PreinitArray = findSection(".preinit_array");
1619 Out::InitArray = findSection(".init_array");
1620 Out::FiniArray = findSection(".fini_array");
1673 Out::preinitArray = findSection(".preinit_array");
1674 Out::initArray = findSection(".init_array");
1675 Out::finiArray = findSection(".fini_array");
16211676
16221677 // The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
16231678 // symbols for sections, so that the runtime can get the start and end
16241679 // addresses of each section by section name. Add such symbols.
1625 if (!Config->Relocatable) {
1680 if (!config->relocatable) {
16261681 addStartEndSymbols();
1627 for (BaseCommand *Base : Script->SectionCommands)
1628 if (auto *Sec = dyn_cast<OutputSection>(Base))
1629 addStartStopSymbols(Sec);
1682 for (BaseCommand *base : script->sectionCommands)
1683 if (auto *sec = dyn_cast<OutputSection>(base))
1684 addStartStopSymbols(sec);
16301685 }
16311686
16321687 // Add _DYNAMIC symbol. Unlike GNU gold, our _DYNAMIC symbol has no type.
16331688 // It should be okay as no one seems to care about the type.
16341689 // Even the author of gold doesn't remember why gold behaves that way.
16351690 // https://sourceware.org/ml/binutils/2002-03/msg00360.html
1636 if (In.Dynamic->Parent)
1637 Symtab->addDefined("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,
1638 /*Size=*/0, STB_WEAK, In.Dynamic,
1639 /*File=*/nullptr);
1691 if (mainPart->dynamic->parent)
1692 symtab->addSymbol(Defined{/*file=*/nullptr, "_DYNAMIC", STB_WEAK,
1693 STV_HIDDEN, STT_NOTYPE,
1694 /*value=*/0, /*size=*/0, mainPart->dynamic});
16401695
16411696 // Define __rel[a]_iplt_{start,end} symbols if needed.
16421697 addRelIpltSymbols();
16431698
16441699 // 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);
1700 // This symbol should only be defined in an executable.
1701 if (config->emachine == EM_RISCV && !config->shared)
1702 ElfSym::riscvGlobalPointer =
1703 addOptionalRegular("__global_pointer$", findSection(".sdata"), 0x800,
1704 STV_DEFAULT, STB_GLOBAL);
1705
1706 if (config->emachine == EM_X86_64) {
1707 // On targets that support TLSDESC, _TLS_MODULE_BASE_ is defined in such a
1708 // way that:
1709 //
1710 // 1) Without relaxation: it produces a dynamic TLSDESC relocation that
1711 // computes 0.
1712 // 2) With LD->LE relaxation: _TLS_MODULE_BASE_@tpoff = 0 (lowest address in
1713 // the TLS block).
1714 //
1715 // 2) is special cased in @tpoff computation. To satisfy 1), we define it as
1716 // an absolute symbol of zero. This is different from GNU linkers which
1717 // define _TLS_MODULE_BASE_ relative to the first TLS section.
1718 Symbol *s = symtab->find("_TLS_MODULE_BASE_");
1719 if (s && s->isUndefined()) {
1720 s->resolve(Defined{/*file=*/nullptr, s->getName(), STB_GLOBAL, STV_HIDDEN,
1721 STT_TLS, /*value=*/0, 0,
1722 /*section=*/nullptr});
1723 ElfSym::tlsModuleBase = cast<Defined>(s);
1724 }
1725 }
16481726
16491727 // This responsible for splitting up .eh_frame section into
16501728 // pieces. The relocation scan uses those pieces, so this has to be
16511729 // earlier.
1652 finalizeSynthetic(In.EhFrame);
1730 for (Partition &part : partitions)
1731 finalizeSynthetic(part.ehFrame);
16531732
1654 for (Symbol *S : Symtab->getSymbols())
1655 if (!S->IsPreemptible)
1656 S->IsPreemptible = computeIsPreemptible(*S);
1733 symtab->forEachSymbol([](Symbol *s) {
1734 if (!s->isPreemptible)
1735 s->isPreemptible = computeIsPreemptible(*s);
1736 });
16571737
16581738 // Scan relocations. This must be done after every symbol is declared so that
16591739 // we can correctly decide if a dynamic relocation is needed.
1660 if (!Config->Relocatable)
1740 if (!config->relocatable) {
16611741 forEachRelSec(scanRelocations<ELFT>);
1742 reportUndefinedSymbols<ELFT>();
1743 }
16621744
1663 if (In.Plt && !In.Plt->empty())
1664 In.Plt->addSymbols();
1665 if (In.Iplt && !In.Iplt->empty())
1666 In.Iplt->addSymbols();
1745 addIRelativeRelocs();
1746
1747 if (in.plt && in.plt->isNeeded())
1748 in.plt->addSymbols();
1749 if (in.iplt && in.iplt->isNeeded())
1750 in.iplt->addSymbols();
1751
1752 if (!config->allowShlibUndefined) {
1753 // Error on undefined symbols in a shared object, if all of its DT_NEEDED
1754 // entires are seen. These cases would otherwise lead to runtime errors
1755 // reported by the dynamic linker.
1756 //
1757 // ld.bfd traces all DT_NEEDED to emulate the logic of the dynamic linker to
1758 // catch more cases. That is too much for us. Our approach resembles the one
1759 // used in ld.gold, achieves a good balance to be useful but not too smart.
1760 for (SharedFile *file : sharedFiles)
1761 file->allNeededIsKnown =
1762 llvm::all_of(file->dtNeeded, [&](StringRef needed) {
1763 return symtab->soNames.count(needed);
1764 });
1765
1766 symtab->forEachSymbol([](Symbol *sym) {
1767 if (sym->isUndefined() && !sym->isWeak())
1768 if (auto *f = dyn_cast_or_null<SharedFile>(sym->file))
1769 if (f->allNeededIsKnown)
1770 error(toString(f) + ": undefined reference to " + toString(*sym));
1771 });
1772 }
16671773
16681774 // Now that we have defined all possible global symbols including linker-
16691775 // synthesized ones. Visit all symbols to give the finishing touches.
1670 for (Symbol *Sym : Symtab->getSymbols()) {
1671 if (!includeInSymtab(*Sym))
1672 continue;
1673 if (In.SymTab)
1674 In.SymTab->addSymbol(Sym);
1675
1676 if (Sym->includeInDynsym()) {
1677 In.DynSymTab->addSymbol(Sym);
1678 if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
1679 if (File->IsNeeded && !Sym->isUndefined())
1680 InX<ELFT>::VerNeed->addSymbol(Sym);
1776 symtab->forEachSymbol([](Symbol *sym) {
1777 if (!includeInSymtab(*sym))
1778 return;
1779 if (in.symTab)
1780 in.symTab->addSymbol(sym);
1781
1782 if (sym->includeInDynsym()) {
1783 partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
1784 if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
1785 if (file->isNeeded && !sym->isUndefined())
1786 addVerneed(sym);
16811787 }
1788 });
1789
1790 // We also need to scan the dynamic relocation tables of the other partitions
1791 // and add any referenced symbols to the partition's dynsym.
1792 for (Partition &part : MutableArrayRef<Partition>(partitions).slice(1)) {
1793 DenseSet<Symbol *> syms;
1794 for (const SymbolTableEntry &e : part.dynSymTab->getSymbols())
1795 syms.insert(e.sym);
1796 for (DynamicReloc &reloc : part.relaDyn->relocs)
1797 if (reloc.sym && !reloc.useSymVA && syms.insert(reloc.sym).second)
1798 part.dynSymTab->addSymbol(reloc.sym);
16821799 }
16831800
16841801 // Do not proceed if there was an undefined symbol.
16851802 if (errorCount())
16861803 return;
16871804
1688 if (In.MipsGot)
1689 In.MipsGot->build<ELFT>();
1805 if (in.mipsGot)
1806 in.mipsGot->build();
16901807
16911808 removeUnusedSyntheticSections();
16921809
......@@ -1694,116 +1811,147 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
16941811
16951812 // Now that we have the final list, create a list of all the
16961813 // OutputSections for convenience.
1697 for (BaseCommand *Base : Script->SectionCommands)
1698 if (auto *Sec = dyn_cast<OutputSection>(Base))
1699 OutputSections.push_back(Sec);
1814 for (BaseCommand *base : script->sectionCommands)
1815 if (auto *sec = dyn_cast<OutputSection>(base))
1816 outputSections.push_back(sec);
17001817
17011818 // Prefer command line supplied address over other constraints.
1702 for (OutputSection *Sec : OutputSections) {
1703 auto I = Config->SectionStartMap.find(Sec->Name);
1704 if (I != Config->SectionStartMap.end())
1705 Sec->AddrExpr = [=] { return I->second; };
1819 for (OutputSection *sec : outputSections) {
1820 auto i = config->sectionStartMap.find(sec->name);
1821 if (i != config->sectionStartMap.end())
1822 sec->addrExpr = [=] { return i->second; };
17061823 }
17071824
17081825 // This is a bit of a hack. A value of 0 means undef, so we set it
17091826 // to 1 to make __ehdr_start defined. The section number is not
17101827 // particularly relevant.
1711 Out::ElfHeader->SectionIndex = 1;
1828 Out::elfHeader->sectionIndex = 1;
17121829
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);
1830 for (size_t i = 0, e = outputSections.size(); i != e; ++i) {
1831 OutputSection *sec = outputSections[i];
1832 sec->sectionIndex = i + 1;
1833 sec->shName = in.shStrTab->addString(sec->name);
17171834 }
17181835
17191836 // Binary and relocatable output does not have PHDRS.
17201837 // The headers have to be created before finalize as that can influence the
17211838 // image base and the dynamic section on mips includes the image base.
1722 if (!Config->Relocatable && !Config->OFormatBinary) {
1723 Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
1724 addPtArmExid(Phdrs);
1725 Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
1839 if (!config->relocatable && !config->oFormatBinary) {
1840 for (Partition &part : partitions) {
1841 part.phdrs = script->hasPhdrsCommands() ? script->createPhdrs()
1842 : createPhdrs(part);
1843 if (config->emachine == EM_ARM) {
1844 // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
1845 addPhdrForSection(part, SHT_ARM_EXIDX, PT_ARM_EXIDX, PF_R);
1846 }
1847 if (config->emachine == EM_MIPS) {
1848 // Add separate segments for MIPS-specific sections.
1849 addPhdrForSection(part, SHT_MIPS_REGINFO, PT_MIPS_REGINFO, PF_R);
1850 addPhdrForSection(part, SHT_MIPS_OPTIONS, PT_MIPS_OPTIONS, PF_R);
1851 addPhdrForSection(part, SHT_MIPS_ABIFLAGS, PT_MIPS_ABIFLAGS, PF_R);
1852 }
1853 }
1854 Out::programHeaders->size = sizeof(Elf_Phdr) * mainPart->phdrs.size();
17261855
17271856 // 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;
1857 // Android relocation packing can look up TLS symbol addresses. We only need
1858 // to care about the main partition here because all TLS symbols were moved
1859 // to the main partition (see MarkLive.cpp).
1860 for (PhdrEntry *p : mainPart->phdrs)
1861 if (p->p_type == PT_TLS)
1862 Out::tlsPhdr = p;
17321863 }
17331864
17341865 // Some symbols are defined in term of program headers. Now that we
17351866 // have the headers, we can find out which sections they point to.
17361867 setReservedSymbolSections();
17371868
1869 finalizeSynthetic(in.bss);
1870 finalizeSynthetic(in.bssRelRo);
1871 finalizeSynthetic(in.symTabShndx);
1872 finalizeSynthetic(in.shStrTab);
1873 finalizeSynthetic(in.strTab);
1874 finalizeSynthetic(in.got);
1875 finalizeSynthetic(in.mipsGot);
1876 finalizeSynthetic(in.igotPlt);
1877 finalizeSynthetic(in.gotPlt);
1878 finalizeSynthetic(in.relaIplt);
1879 finalizeSynthetic(in.relaPlt);
1880 finalizeSynthetic(in.plt);
1881 finalizeSynthetic(in.iplt);
1882 finalizeSynthetic(in.ppc32Got2);
1883 finalizeSynthetic(in.riscvSdata);
1884 finalizeSynthetic(in.partIndex);
1885
17381886 // Dynamic section must be the last one in this list and dynamic
1739 // symbol table section (DynSymTab) must be the first one.
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);
1764
1765 if (!Script->HasSectionsCommand && !Config->Relocatable)
1887 // symbol table section (dynSymTab) must be the first one.
1888 for (Partition &part : partitions) {
1889 finalizeSynthetic(part.armExidx);
1890 finalizeSynthetic(part.dynSymTab);
1891 finalizeSynthetic(part.gnuHashTab);
1892 finalizeSynthetic(part.hashTab);
1893 finalizeSynthetic(part.verDef);
1894 finalizeSynthetic(part.relaDyn);
1895 finalizeSynthetic(part.relrDyn);
1896 finalizeSynthetic(part.ehFrameHdr);
1897 finalizeSynthetic(part.verSym);
1898 finalizeSynthetic(part.verNeed);
1899 finalizeSynthetic(part.dynamic);
1900 }
1901
1902 if (!script->hasSectionsCommand && !config->relocatable)
17661903 fixSectionAlignments();
17671904
1768 // After link order processing .ARM.exidx sections can be deduplicated, which
1769 // needs to be resolved before any other address dependent operation.
1905 // SHFLinkOrder processing must be processed after relative section placements are
1906 // known but before addresses are allocated.
17701907 resolveShfLinkOrder();
17711908
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".
1909 // This is used to:
1910 // 1) Create "thunks":
1911 // Jump instructions in many ISAs have small displacements, and therefore
1912 // they cannot jump to arbitrary addresses in memory. For example, RISC-V
1913 // JAL instruction can target only +-1 MiB from PC. It is a linker's
1914 // responsibility to create and insert small pieces of code between
1915 // sections to extend the ranges if jump targets are out of range. Such
1916 // code pieces are called "thunks".
17781917 //
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();
1918 // We add thunks at this stage. We couldn't do this before this point
1919 // because this is the earliest point where we know sizes of sections and
1920 // their layouts (that are needed to determine if jump targets are in
1921 // range).
1922 //
1923 // 2) Update the sections. We need to generate content that depends on the
1924 // address of InputSections. For example, MIPS GOT section content or
1925 // android packed relocations sections content.
1926 //
1927 // 3) Assign the final values for the linker script symbols. Linker scripts
1928 // sometimes using forward symbol declarations. We want to set the correct
1929 // values. They also might change after adding the thunks.
1930 finalizeAddressDependentContent();
17831931
1784 // maybeAddThunks may have added local symbols to the static symbol table.
1785 finalizeSynthetic(In.SymTab);
1786 finalizeSynthetic(In.PPC64LongBranchTarget);
1932 // finalizeAddressDependentContent may have added local symbols to the static symbol table.
1933 finalizeSynthetic(in.symTab);
1934 finalizeSynthetic(in.ppc64LongBranchTarget);
17871935
17881936 // Fill other section headers. The dynamic table is finalized
17891937 // at the end because some tags like RELSZ depend on result
17901938 // of finalizing other sections.
1791 for (OutputSection *Sec : OutputSections)
1792 Sec->finalize<ELFT>();
1939 for (OutputSection *sec : outputSections)
1940 sec->finalize();
17931941}
17941942
17951943// Ensure data sections are not mixed with executable sections when
17961944// -execute-only is used. -execute-only is a feature to make pages executable
17971945// but not readable, and the feature is currently supported only on AArch64.
17981946template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
1799 if (!Config->ExecuteOnly)
1947 if (!config->executeOnly)
18001948 return;
18011949
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) +
1950 for (OutputSection *os : outputSections)
1951 if (os->flags & SHF_EXECINSTR)
1952 for (InputSection *isec : getInputSections(os))
1953 if (!(isec->flags & SHF_EXECINSTR))
1954 error("cannot place " + toString(isec) + " into " + toString(os->name) +
18071955 ": -execute-only does not support intermingling data and code");
18081956}
18091957
......@@ -1828,24 +1976,24 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
18281976 // case, use the image base address as a last resort.
18291977 OutputSection *Default = findSection(".text");
18301978 if (!Default)
1831 Default = Out::ElfHeader;
1979 Default = Out::elfHeader;
18321980
1833 auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) {
1834 if (OS) {
1835 addOptionalRegular(Start, OS, 0);
1836 addOptionalRegular(End, OS, -1);
1981 auto define = [=](StringRef start, StringRef end, OutputSection *os) {
1982 if (os) {
1983 addOptionalRegular(start, os, 0);
1984 addOptionalRegular(end, os, -1);
18371985 } else {
1838 addOptionalRegular(Start, Default, 0);
1839 addOptionalRegular(End, Default, 0);
1986 addOptionalRegular(start, Default, 0);
1987 addOptionalRegular(end, Default, 0);
18401988 }
18411989 };
18421990
1843 Define("__preinit_array_start", "__preinit_array_end", Out::PreinitArray);
1844 Define("__init_array_start", "__init_array_end", Out::InitArray);
1845 Define("__fini_array_start", "__fini_array_end", Out::FiniArray);
1991 define("__preinit_array_start", "__preinit_array_end", Out::preinitArray);
1992 define("__init_array_start", "__init_array_end", Out::initArray);
1993 define("__fini_array_start", "__fini_array_end", Out::finiArray);
18461994
1847 if (OutputSection *Sec = findSection(".ARM.exidx"))
1848 Define("__exidx_start", "__exidx_end", Sec);
1995 if (OutputSection *sec = findSection(".ARM.exidx"))
1996 define("__exidx_start", "__exidx_end", sec);
18491997}
18501998
18511999// If a section name is valid as a C identifier (which is rare because of
......@@ -1854,22 +2002,22 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
18542002// respectively. This is not requested by the ELF standard, but GNU ld and
18552003// gold provide the feature, and used by many programs.
18562004template <class ELFT>
1857void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
1858 StringRef S = Sec->Name;
1859 if (!isValidCIdentifier(S))
2005void Writer<ELFT>::addStartStopSymbols(OutputSection *sec) {
2006 StringRef s = sec->name;
2007 if (!isValidCIdentifier(s))
18602008 return;
1861 addOptionalRegular(Saver.save("__start_" + S), Sec, 0, STV_PROTECTED);
1862 addOptionalRegular(Saver.save("__stop_" + S), Sec, -1, STV_PROTECTED);
2009 addOptionalRegular(saver.save("__start_" + s), sec, 0, STV_PROTECTED);
2010 addOptionalRegular(saver.save("__stop_" + s), sec, -1, STV_PROTECTED);
18632011}
18642012
1865static bool needsPtLoad(OutputSection *Sec) {
1866 if (!(Sec->Flags & SHF_ALLOC) || Sec->Noload)
2013static bool needsPtLoad(OutputSection *sec) {
2014 if (!(sec->flags & SHF_ALLOC) || sec->noload)
18672015 return false;
18682016
18692017 // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
18702018 // responsible for allocating space for them, not the PT_LOAD that
18712019 // contains the TLS initialization image.
1872 if ((Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS)
2020 if ((sec->flags & SHF_TLS) && sec->type == SHT_NOBITS)
18732021 return false;
18742022 return true;
18752023}
......@@ -1878,46 +2026,93 @@ static bool needsPtLoad(OutputSection *Sec) {
18782026// linker scripts are designed for creating two PT_LOADs only, one RX and one
18792027// RW. This means that there is no alignment in the RO to RX transition and we
18802028// cannot create a PT_LOAD there.
1881static uint64_t computeFlags(uint64_t Flags) {
1882 if (Config->Omagic)
2029static uint64_t computeFlags(uint64_t flags) {
2030 if (config->omagic)
18832031 return PF_R | PF_W | PF_X;
1884 if (Config->ExecuteOnly && (Flags & PF_X))
1885 return Flags & ~PF_R;
1886 if (Config->SingleRoRx && !(Flags & PF_W))
1887 return Flags | PF_X;
1888 return Flags;
2032 if (config->executeOnly && (flags & PF_X))
2033 return flags & ~PF_R;
2034 if (config->singleRoRx && !(flags & PF_W))
2035 return flags | PF_X;
2036 return flags;
18892037}
18902038
18912039// Decide which program headers to create and which sections to include in each
18922040// one.
1893template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
1894 std::vector<PhdrEntry *> Ret;
1895 auto AddHdr = [&](unsigned Type, unsigned Flags) -> PhdrEntry * {
1896 Ret.push_back(make<PhdrEntry>(Type, Flags));
1897 return Ret.back();
2041template <class ELFT>
2042std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs(Partition &part) {
2043 std::vector<PhdrEntry *> ret;
2044 auto addHdr = [&](unsigned type, unsigned flags) -> PhdrEntry * {
2045 ret.push_back(make<PhdrEntry>(type, flags));
2046 return ret.back();
18982047 };
18992048
2049 unsigned partNo = part.getNumber();
2050 bool isMain = partNo == 1;
2051
19002052 // The first phdr entry is PT_PHDR which describes the program header itself.
1901 AddHdr(PT_PHDR, PF_R)->add(Out::ProgramHeaders);
2053 if (isMain)
2054 addHdr(PT_PHDR, PF_R)->add(Out::programHeaders);
2055 else
2056 addHdr(PT_PHDR, PF_R)->add(part.programHeaders->getParent());
19022057
19032058 // PT_INTERP must be the second entry if exists.
1904 if (OutputSection *Cmd = findSection(".interp"))
1905 AddHdr(PT_INTERP, Cmd->getPhdrFlags())->add(Cmd);
2059 if (OutputSection *cmd = findSection(".interp", partNo))
2060 addHdr(PT_INTERP, cmd->getPhdrFlags())->add(cmd);
19062061
19072062 // Add the first PT_LOAD segment for regular output sections.
1908 uint64_t Flags = computeFlags(PF_R);
1909 PhdrEntry *Load = AddHdr(PT_LOAD, Flags);
2063 uint64_t flags = computeFlags(PF_R);
2064 PhdrEntry *load = nullptr;
19102065
19112066 // Add the headers. We will remove them if they don't fit.
1912 Load->add(Out::ElfHeader);
1913 Load->add(Out::ProgramHeaders);
2067 // In the other partitions the headers are ordinary sections, so they don't
2068 // need to be added here.
2069 if (isMain) {
2070 load = addHdr(PT_LOAD, flags);
2071 load->add(Out::elfHeader);
2072 load->add(Out::programHeaders);
2073 }
2074
2075 // PT_GNU_RELRO includes all sections that should be marked as
2076 // read-only by dynamic linker after proccessing relocations.
2077 // Current dynamic loaders only support one PT_GNU_RELRO PHDR, give
2078 // an error message if more than one PT_GNU_RELRO PHDR is required.
2079 PhdrEntry *relRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
2080 bool inRelroPhdr = false;
2081 OutputSection *relroEnd = nullptr;
2082 for (OutputSection *sec : outputSections) {
2083 if (sec->partition != partNo || !needsPtLoad(sec))
2084 continue;
2085 if (isRelroSection(sec)) {
2086 inRelroPhdr = true;
2087 if (!relroEnd)
2088 relRo->add(sec);
2089 else
2090 error("section: " + sec->name + " is not contiguous with other relro" +
2091 " sections");
2092 } else if (inRelroPhdr) {
2093 inRelroPhdr = false;
2094 relroEnd = sec;
2095 }
2096 }
19142097
1915 for (OutputSection *Sec : OutputSections) {
1916 if (!(Sec->Flags & SHF_ALLOC))
2098 for (OutputSection *sec : outputSections) {
2099 if (!(sec->flags & SHF_ALLOC))
19172100 break;
1918 if (!needsPtLoad(Sec))
2101 if (!needsPtLoad(sec))
19192102 continue;
19202103
2104 // Normally, sections in partitions other than the current partition are
2105 // ignored. But partition number 255 is a special case: it contains the
2106 // partition end marker (.part.end). It needs to be added to the main
2107 // partition so that a segment is created for it in the main partition,
2108 // which will cause the dynamic loader to reserve space for the other
2109 // partitions.
2110 if (sec->partition != partNo) {
2111 if (isMain && sec->partition == 255)
2112 addHdr(PT_LOAD, computeFlags(sec->getPhdrFlags()))->add(sec);
2113 continue;
2114 }
2115
19212116 // Segments are contiguous memory regions that has the same attributes
19222117 // (e.g. executable or writable). There is one phdr for each segment.
19232118 // Therefore, we need to create a new phdr when the next section has
......@@ -1925,222 +2120,187 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
19252120 // region using AT or AT> linker script command, respectively. At the same
19262121 // time, we don't want to create a separate load segment for the headers,
19272122 // even if the first output section has an AT or AT> attribute.
1928 uint64_t NewFlags = computeFlags(Sec->getPhdrFlags());
1929 if (((Sec->LMAExpr ||
1930 (Sec->LMARegion && (Sec->LMARegion != Load->FirstSec->LMARegion))) &&
1931 Load->LastSec != Out::ProgramHeaders) ||
1932 Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) {
1933
1934 Load = AddHdr(PT_LOAD, NewFlags);
1935 Flags = NewFlags;
2123 uint64_t newFlags = computeFlags(sec->getPhdrFlags());
2124 if (!load ||
2125 ((sec->lmaExpr ||
2126 (sec->lmaRegion && (sec->lmaRegion != load->firstSec->lmaRegion))) &&
2127 load->lastSec != Out::programHeaders) ||
2128 sec->memRegion != load->firstSec->memRegion || flags != newFlags ||
2129 sec == relroEnd) {
2130 load = addHdr(PT_LOAD, newFlags);
2131 flags = newFlags;
19362132 }
19372133
1938 Load->add(Sec);
2134 load->add(sec);
19392135 }
19402136
19412137 // Add a TLS segment if any.
1942 PhdrEntry *TlsHdr = make<PhdrEntry>(PT_TLS, PF_R);
1943 for (OutputSection *Sec : OutputSections)
1944 if (Sec->Flags & SHF_TLS)
1945 TlsHdr->add(Sec);
1946 if (TlsHdr->FirstSec)
1947 Ret.push_back(TlsHdr);
2138 PhdrEntry *tlsHdr = make<PhdrEntry>(PT_TLS, PF_R);
2139 for (OutputSection *sec : outputSections)
2140 if (sec->partition == partNo && sec->flags & SHF_TLS)
2141 tlsHdr->add(sec);
2142 if (tlsHdr->firstSec)
2143 ret.push_back(tlsHdr);
19482144
19492145 // Add an entry for .dynamic.
1950 if (OutputSection *Sec = In.Dynamic->getParent())
1951 AddHdr(PT_DYNAMIC, Sec->getPhdrFlags())->add(Sec);
2146 if (OutputSection *sec = part.dynamic->getParent())
2147 addHdr(PT_DYNAMIC, sec->getPhdrFlags())->add(sec);
19522148
1953 // PT_GNU_RELRO includes all sections that should be marked as
1954 // read-only by dynamic linker after proccessing relocations.
1955 // Current dynamic loaders only support one PT_GNU_RELRO PHDR, give
1956 // an error message if more than one PT_GNU_RELRO PHDR is required.
1957 PhdrEntry *RelRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
1958 bool InRelroPhdr = false;
1959 bool IsRelroFinished = false;
1960 for (OutputSection *Sec : OutputSections) {
1961 if (!needsPtLoad(Sec))
1962 continue;
1963 if (isRelroSection(Sec)) {
1964 InRelroPhdr = true;
1965 if (!IsRelroFinished)
1966 RelRo->add(Sec);
1967 else
1968 error("section: " + Sec->Name + " is not contiguous with other relro" +
1969 " sections");
1970 } else if (InRelroPhdr) {
1971 InRelroPhdr = false;
1972 IsRelroFinished = true;
1973 }
1974 }
1975 if (RelRo->FirstSec)
1976 Ret.push_back(RelRo);
2149 if (relRo->firstSec)
2150 ret.push_back(relRo);
19772151
19782152 // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
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());
2153 if (part.ehFrame->isNeeded() && part.ehFrameHdr &&
2154 part.ehFrame->getParent() && part.ehFrameHdr->getParent())
2155 addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags())
2156 ->add(part.ehFrameHdr->getParent());
19832157
19842158 // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
19852159 // the dynamic linker fill the segment with random data.
1986 if (OutputSection *Cmd = findSection(".openbsd.randomdata"))
1987 AddHdr(PT_OPENBSD_RANDOMIZE, Cmd->getPhdrFlags())->add(Cmd);
2160 if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo))
2161 addHdr(PT_OPENBSD_RANDOMIZE, cmd->getPhdrFlags())->add(cmd);
19882162
19892163 // PT_GNU_STACK is a special section to tell the loader to make the
19902164 // pages for the stack non-executable. If you really want an executable
19912165 // stack, you can pass -z execstack, but that's not recommended for
19922166 // security reasons.
1993 unsigned Perm = PF_R | PF_W;
1994 if (Config->ZExecstack)
1995 Perm |= PF_X;
1996 AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize;
2167 unsigned perm = PF_R | PF_W;
2168 if (config->zExecstack)
2169 perm |= PF_X;
2170 addHdr(PT_GNU_STACK, perm)->p_memsz = config->zStackSize;
19972171
19982172 // PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable
19992173 // is expected to perform W^X violations, such as calling mprotect(2) or
20002174 // mmap(2) with PROT_WRITE | PROT_EXEC, which is prohibited by default on
20012175 // OpenBSD.
2002 if (Config->ZWxneeded)
2003 AddHdr(PT_OPENBSD_WXNEEDED, PF_X);
2004
2005 // Create one PT_NOTE per a group of contiguous .note sections.
2006 PhdrEntry *Note = nullptr;
2007 for (OutputSection *Sec : OutputSections) {
2008 if (Sec->Type == SHT_NOTE && (Sec->Flags & SHF_ALLOC)) {
2009 if (!Note || Sec->LMAExpr)
2010 Note = AddHdr(PT_NOTE, PF_R);
2011 Note->add(Sec);
2176 if (config->zWxneeded)
2177 addHdr(PT_OPENBSD_WXNEEDED, PF_X);
2178
2179 // Create one PT_NOTE per a group of contiguous SHT_NOTE sections with the
2180 // same alignment.
2181 PhdrEntry *note = nullptr;
2182 for (OutputSection *sec : outputSections) {
2183 if (sec->partition != partNo)
2184 continue;
2185 if (sec->type == SHT_NOTE && (sec->flags & SHF_ALLOC)) {
2186 if (!note || sec->lmaExpr || note->lastSec->alignment != sec->alignment)
2187 note = addHdr(PT_NOTE, PF_R);
2188 note->add(sec);
20122189 } else {
2013 Note = nullptr;
2190 note = nullptr;
20142191 }
20152192 }
2016 return Ret;
2193 return ret;
20172194}
20182195
20192196template <class ELFT>
2020void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry *> &Phdrs) {
2021 if (Config->EMachine != EM_ARM)
2022 return;
2023 auto I = llvm::find_if(OutputSections, [](OutputSection *Cmd) {
2024 return Cmd->Type == SHT_ARM_EXIDX;
2197void Writer<ELFT>::addPhdrForSection(Partition &part, unsigned shType,
2198 unsigned pType, unsigned pFlags) {
2199 unsigned partNo = part.getNumber();
2200 auto i = llvm::find_if(outputSections, [=](OutputSection *cmd) {
2201 return cmd->partition == partNo && cmd->type == shType;
20252202 });
2026 if (I == OutputSections.end())
2203 if (i == outputSections.end())
20272204 return;
20282205
2029 // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
2030 PhdrEntry *ARMExidx = make<PhdrEntry>(PT_ARM_EXIDX, PF_R);
2031 ARMExidx->add(*I);
2032 Phdrs.push_back(ARMExidx);
2206 PhdrEntry *entry = make<PhdrEntry>(pType, pFlags);
2207 entry->add(*i);
2208 part.phdrs.push_back(entry);
20332209}
20342210
20352211// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the
20362212// first section after PT_GNU_RELRO have to be page aligned so that the dynamic
20372213// linker can set the permissions.
20382214template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
2039 auto PageAlign = [](OutputSection *Cmd) {
2040 if (Cmd && !Cmd->AddrExpr)
2041 Cmd->AddrExpr = [=] {
2042 return alignTo(Script->getDot(), Config->MaxPageSize);
2215 auto pageAlign = [](OutputSection *cmd) {
2216 if (cmd && !cmd->addrExpr)
2217 cmd->addrExpr = [=] {
2218 return alignTo(script->getDot(), config->maxPageSize);
20432219 };
20442220 };
20452221
2046 for (const PhdrEntry *P : Phdrs)
2047 if (P->p_type == PT_LOAD && P->FirstSec)
2048 PageAlign(P->FirstSec);
2049
2050 for (const PhdrEntry *P : Phdrs) {
2051 if (P->p_type != PT_GNU_RELRO)
2052 continue;
2053
2054 if (P->FirstSec)
2055 PageAlign(P->FirstSec);
2056
2057 // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
2058 // have to align it to a page.
2059 auto End = OutputSections.end();
2060 auto I = std::find(OutputSections.begin(), End, P->LastSec);
2061 if (I == End || (I + 1) == End)
2062 continue;
2063
2064 OutputSection *Cmd = (*(I + 1));
2065 if (needsPtLoad(Cmd))
2066 PageAlign(Cmd);
2222 for (Partition &part : partitions) {
2223 for (const PhdrEntry *p : part.phdrs)
2224 if (p->p_type == PT_LOAD && p->firstSec)
2225 pageAlign(p->firstSec);
20672226 }
20682227}
20692228
20702229// Compute an in-file position for a given section. The file offset must be the
20712230// same with its virtual address modulo the page size, so that the loader can
20722231// load executables without any address adjustment.
2073static uint64_t computeFileOffset(OutputSection *OS, uint64_t Off) {
2232static uint64_t computeFileOffset(OutputSection *os, uint64_t off) {
20742233 // File offsets are not significant for .bss sections. By convention, we keep
20752234 // section offsets monotonically increasing rather than setting to zero.
2076 if (OS->Type == SHT_NOBITS)
2077 return Off;
2235 if (os->type == SHT_NOBITS)
2236 return off;
20782237
20792238 // If the section is not in a PT_LOAD, we just have to align it.
2080 if (!OS->PtLoad)
2081 return alignTo(Off, OS->Alignment);
2239 if (!os->ptLoad)
2240 return alignTo(off, os->alignment);
20822241
20832242 // The first section in a PT_LOAD has to have congruent offset and address
20842243 // 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);
2244 OutputSection *first = os->ptLoad->firstSec;
2245 if (os == first) {
2246 uint64_t alignment = std::max<uint64_t>(os->alignment, config->maxPageSize);
2247 return alignTo(off, alignment, os->addr);
20892248 }
20902249
20912250 // If two sections share the same PT_LOAD the file offset is calculated
20922251 // using this formula: Off2 = Off1 + (VA2 - VA1).
2093 return First->Offset + OS->Addr - First->Addr;
2252 return first->offset + os->addr - first->addr;
20942253}
20952254
20962255// Set an in-file position to a given section and returns the end position of
20972256// the section.
2098static uint64_t setFileOffset(OutputSection *OS, uint64_t Off) {
2099 Off = computeFileOffset(OS, Off);
2100 OS->Offset = Off;
2257static uint64_t setFileOffset(OutputSection *os, uint64_t off) {
2258 off = computeFileOffset(os, off);
2259 os->offset = off;
21012260
2102 if (OS->Type == SHT_NOBITS)
2103 return Off;
2104 return Off + OS->Size;
2261 if (os->type == SHT_NOBITS)
2262 return off;
2263 return off + os->size;
21052264}
21062265
21072266template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
2108 uint64_t Off = 0;
2109 for (OutputSection *Sec : OutputSections)
2110 if (Sec->Flags & SHF_ALLOC)
2111 Off = setFileOffset(Sec, Off);
2112 FileSize = alignTo(Off, Config->Wordsize);
2267 uint64_t off = 0;
2268 for (OutputSection *sec : outputSections)
2269 if (sec->flags & SHF_ALLOC)
2270 off = setFileOffset(sec, off);
2271 fileSize = alignTo(off, config->wordsize);
21132272}
21142273
2115static std::string rangeToString(uint64_t Addr, uint64_t Len) {
2116 return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]";
2274static std::string rangeToString(uint64_t addr, uint64_t len) {
2275 return "[0x" + utohexstr(addr) + ", 0x" + utohexstr(addr + len - 1) + "]";
21172276}
21182277
21192278// Assign file offsets to output sections.
21202279template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
2121 uint64_t Off = 0;
2122 Off = setFileOffset(Out::ElfHeader, Off);
2123 Off = setFileOffset(Out::ProgramHeaders, Off);
2124
2125 PhdrEntry *LastRX = nullptr;
2126 for (PhdrEntry *P : Phdrs)
2127 if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
2128 LastRX = P;
2129
2130 for (OutputSection *Sec : OutputSections) {
2131 Off = setFileOffset(Sec, Off);
2132 if (Script->HasSectionsCommand)
2280 uint64_t off = 0;
2281 off = setFileOffset(Out::elfHeader, off);
2282 off = setFileOffset(Out::programHeaders, off);
2283
2284 PhdrEntry *lastRX = nullptr;
2285 for (Partition &part : partitions)
2286 for (PhdrEntry *p : part.phdrs)
2287 if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
2288 lastRX = p;
2289
2290 for (OutputSection *sec : outputSections) {
2291 off = setFileOffset(sec, off);
2292 if (script->hasSectionsCommand)
21332293 continue;
21342294
21352295 // If this is a last section of the last executable segment and that
21362296 // segment is the last loadable segment, align the offset of the
21372297 // following section to avoid loading non-segments parts of the file.
2138 if (LastRX && LastRX->LastSec == Sec)
2139 Off = alignTo(Off, Target->PageSize);
2298 if (lastRX && lastRX->lastSec == sec)
2299 off = alignTo(off, config->commonPageSize);
21402300 }
21412301
2142 SectionHeaderOff = alignTo(Off, Config->Wordsize);
2143 FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
2302 sectionHeaderOff = alignTo(off, config->wordsize);
2303 fileSize = sectionHeaderOff + (outputSections.size() + 1) * sizeof(Elf_Shdr);
21442304
21452305 // Our logic assumes that sections have rising VA within the same segment.
21462306 // With use of linker scripts it is possible to violate this rule and get file
......@@ -2151,62 +2311,49 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
21512311 // backwards, so we have to allow doing that to support linking them. We
21522312 // perform non-critical checks for overlaps in checkSectionOverlap(), but here
21532313 // we want to prevent file size overflows because it would crash the linker.
2154 for (OutputSection *Sec : OutputSections) {
2155 if (Sec->Type == SHT_NOBITS)
2314 for (OutputSection *sec : outputSections) {
2315 if (sec->type == SHT_NOBITS)
21562316 continue;
2157 if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize))
2158 error("unable to place section " + Sec->Name + " at file offset " +
2159 rangeToString(Sec->Offset, Sec->Size) +
2317 if ((sec->offset > fileSize) || (sec->offset + sec->size > fileSize))
2318 error("unable to place section " + sec->name + " at file offset " +
2319 rangeToString(sec->offset, sec->size) +
21602320 "; check your linker script for overflows");
21612321 }
21622322}
21632323
21642324// Finalize the program headers. We call this function after we assign
21652325// file offsets and VAs to all sections.
2166template <class ELFT> void Writer<ELFT>::setPhdrs() {
2167 for (PhdrEntry *P : Phdrs) {
2168 OutputSection *First = P->FirstSec;
2169 OutputSection *Last = P->LastSec;
2170
2171 if (First) {
2172 P->p_filesz = Last->Offset - First->Offset;
2173 if (Last->Type != SHT_NOBITS)
2174 P->p_filesz += Last->Size;
2175
2176 P->p_memsz = Last->Addr + Last->Size - First->Addr;
2177 P->p_offset = First->Offset;
2178 P->p_vaddr = First->Addr;
2179
2180 if (!P->HasLMA)
2181 P->p_paddr = First->getLMA();
2326template <class ELFT> void Writer<ELFT>::setPhdrs(Partition &part) {
2327 for (PhdrEntry *p : part.phdrs) {
2328 OutputSection *first = p->firstSec;
2329 OutputSection *last = p->lastSec;
2330
2331 if (first) {
2332 p->p_filesz = last->offset - first->offset;
2333 if (last->type != SHT_NOBITS)
2334 p->p_filesz += last->size;
2335
2336 p->p_memsz = last->addr + last->size - first->addr;
2337 p->p_offset = first->offset;
2338 p->p_vaddr = first->addr;
2339
2340 // File offsets in partitions other than the main partition are relative
2341 // to the offset of the ELF headers. Perform that adjustment now.
2342 if (part.elfHeader)
2343 p->p_offset -= part.elfHeader->getParent()->offset;
2344
2345 if (!p->hasLMA)
2346 p->p_paddr = first->getLMA();
21822347 }
21832348
2184 if (P->p_type == PT_LOAD) {
2185 P->p_align = std::max<uint64_t>(P->p_align, Config->MaxPageSize);
2186 } else if (P->p_type == PT_GNU_RELRO) {
2187 P->p_align = 1;
2349 if (p->p_type == PT_LOAD) {
2350 p->p_align = std::max<uint64_t>(p->p_align, config->maxPageSize);
2351 } else if (p->p_type == PT_GNU_RELRO) {
2352 p->p_align = 1;
21882353 // The glibc dynamic loader rounds the size down, so we need to round up
21892354 // to protect the last page. This is a no-op on FreeBSD which always
21902355 // rounds up.
2191 P->p_memsz = alignTo(P->p_memsz, Target->PageSize);
2192 }
2193
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);
2356 p->p_memsz = alignTo(p->p_memsz, config->commonPageSize);
22102357 }
22112358 }
22122359}
......@@ -2214,37 +2361,37 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
22142361// A helper struct for checkSectionOverlap.
22152362namespace {
22162363struct SectionOffset {
2217 OutputSection *Sec;
2218 uint64_t Offset;
2364 OutputSection *sec;
2365 uint64_t offset;
22192366};
22202367} // namespace
22212368
22222369// Check whether sections overlap for a specific address range (file offsets,
22232370// load and virtual adresses).
2224static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,
2225 bool IsVirtualAddr) {
2226 llvm::sort(Sections, [=](const SectionOffset &A, const SectionOffset &B) {
2227 return A.Offset < B.Offset;
2371static void checkOverlap(StringRef name, std::vector<SectionOffset> &sections,
2372 bool isVirtualAddr) {
2373 llvm::sort(sections, [=](const SectionOffset &a, const SectionOffset &b) {
2374 return a.offset < b.offset;
22282375 });
22292376
22302377 // Finding overlap is easy given a vector is sorted by start position.
22312378 // If an element starts before the end of the previous element, they overlap.
2232 for (size_t I = 1, End = Sections.size(); I < End; ++I) {
2233 SectionOffset A = Sections[I - 1];
2234 SectionOffset B = Sections[I];
2235 if (B.Offset >= A.Offset + A.Sec->Size)
2379 for (size_t i = 1, end = sections.size(); i < end; ++i) {
2380 SectionOffset a = sections[i - 1];
2381 SectionOffset b = sections[i];
2382 if (b.offset >= a.offset + a.sec->size)
22362383 continue;
22372384
22382385 // If both sections are in OVERLAY we allow the overlapping of virtual
22392386 // addresses, because it is what OVERLAY was designed for.
2240 if (IsVirtualAddr && A.Sec->InOverlay && B.Sec->InOverlay)
2387 if (isVirtualAddr && a.sec->inOverlay && b.sec->inOverlay)
22412388 continue;
22422389
2243 errorOrWarn("section " + A.Sec->Name + " " + Name +
2244 " range overlaps with " + B.Sec->Name + "\n>>> " + A.Sec->Name +
2245 " range is " + rangeToString(A.Offset, A.Sec->Size) + "\n>>> " +
2246 B.Sec->Name + " range is " +
2247 rangeToString(B.Offset, B.Sec->Size));
2390 errorOrWarn("section " + a.sec->name + " " + name +
2391 " range overlaps with " + b.sec->name + "\n>>> " + a.sec->name +
2392 " range is " + rangeToString(a.offset, a.sec->size) + "\n>>> " +
2393 b.sec->name + " range is " +
2394 rangeToString(b.offset, b.sec->size));
22482395 }
22492396}
22502397
......@@ -2255,11 +2402,11 @@ static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections,
22552402// ranges and the virtual address ranges don't overlap
22562403template <class ELFT> void Writer<ELFT>::checkSections() {
22572404 // First, check that section's VAs fit in available address space for target.
2258 for (OutputSection *OS : OutputSections)
2259 if ((OS->Addr + OS->Size < OS->Addr) ||
2260 (!ELFT::Is64Bits && OS->Addr + OS->Size > UINT32_MAX))
2261 errorOrWarn("section " + OS->Name + " at 0x" + utohexstr(OS->Addr) +
2262 " of size 0x" + utohexstr(OS->Size) +
2405 for (OutputSection *os : outputSections)
2406 if ((os->addr + os->size < os->addr) ||
2407 (!ELFT::Is64Bits && os->addr + os->size > UINT32_MAX))
2408 errorOrWarn("section " + os->name + " at 0x" + utohexstr(os->addr) +
2409 " of size 0x" + utohexstr(os->size) +
22632410 " exceeds available address space");
22642411
22652412 // Check for overlapping file offsets. In this case we need to skip any
......@@ -2267,17 +2414,17 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
22672414 // the file so Sec->Offset + Sec->Size can overlap with others. If --oformat
22682415 // binary is specified only add SHF_ALLOC sections are added to the output
22692416 // file so we skip any non-allocated sections in that case.
2270 std::vector<SectionOffset> FileOffs;
2271 for (OutputSection *Sec : OutputSections)
2272 if (Sec->Size > 0 && Sec->Type != SHT_NOBITS &&
2273 (!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC)))
2274 FileOffs.push_back({Sec, Sec->Offset});
2275 checkOverlap("file", FileOffs, false);
2417 std::vector<SectionOffset> fileOffs;
2418 for (OutputSection *sec : outputSections)
2419 if (sec->size > 0 && sec->type != SHT_NOBITS &&
2420 (!config->oFormatBinary || (sec->flags & SHF_ALLOC)))
2421 fileOffs.push_back({sec, sec->offset});
2422 checkOverlap("file", fileOffs, false);
22762423
22772424 // When linking with -r there is no need to check for overlapping virtual/load
22782425 // addresses since those addresses will only be assigned when the final
22792426 // executable/shared object is created.
2280 if (Config->Relocatable)
2427 if (config->relocatable)
22812428 return;
22822429
22832430 // Checking for overlapping virtual and load addresses only needs to take
......@@ -2285,20 +2432,20 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
22852432 // Furthermore, we also need to skip SHF_TLS sections since these will be
22862433 // mapped to other addresses at runtime and can therefore have overlapping
22872434 // ranges in the file.
2288 std::vector<SectionOffset> VMAs;
2289 for (OutputSection *Sec : OutputSections)
2290 if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
2291 VMAs.push_back({Sec, Sec->Addr});
2292 checkOverlap("virtual address", VMAs, true);
2435 std::vector<SectionOffset> vmas;
2436 for (OutputSection *sec : outputSections)
2437 if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS))
2438 vmas.push_back({sec, sec->addr});
2439 checkOverlap("virtual address", vmas, true);
22932440
22942441 // Finally, check that the load addresses don't overlap. This will usually be
22952442 // the same as the virtual addresses but can be different when using a linker
22962443 // script with AT().
2297 std::vector<SectionOffset> LMAs;
2298 for (OutputSection *Sec : OutputSections)
2299 if (Sec->Size > 0 && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
2300 LMAs.push_back({Sec, Sec->getLMA()});
2301 checkOverlap("load address", LMAs, false);
2444 std::vector<SectionOffset> lmas;
2445 for (OutputSection *sec : outputSections)
2446 if (sec->size > 0 && (sec->flags & SHF_ALLOC) && !(sec->flags & SHF_TLS))
2447 lmas.push_back({sec, sec->getLMA()});
2448 checkOverlap("load address", lmas, false);
23022449}
23032450
23042451// The entry point address is chosen in the following ways.
......@@ -2311,89 +2458,45 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
23112458// 6. the address 0.
23122459static uint64_t getEntryAddr() {
23132460 // Case 1, 2 or 3
2314 if (Symbol *B = Symtab->find(Config->Entry))
2315 return B->getVA();
2461 if (Symbol *b = symtab->find(config->entry))
2462 return b->getVA();
23162463
23172464 // Case 4
2318 uint64_t Addr;
2319 if (to_integer(Config->Entry, Addr))
2320 return Addr;
2465 uint64_t addr;
2466 if (to_integer(config->entry, addr))
2467 return addr;
23212468
23222469 // Case 5
2323 if (OutputSection *Sec = findSection(".text")) {
2324 if (Config->WarnMissingEntry)
2325 warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
2326 utohexstr(Sec->Addr));
2327 return Sec->Addr;
2470 if (OutputSection *sec = findSection(".text")) {
2471 if (config->warnMissingEntry)
2472 warn("cannot find entry symbol " + config->entry + "; defaulting to 0x" +
2473 utohexstr(sec->addr));
2474 return sec->addr;
23282475 }
23292476
23302477 // Case 6
2331 if (Config->WarnMissingEntry)
2332 warn("cannot find entry symbol " + Config->Entry +
2478 if (config->warnMissingEntry)
2479 warn("cannot find entry symbol " + config->entry +
23332480 "; not setting start address");
23342481 return 0;
23352482}
23362483
23372484static uint16_t getELFType() {
2338 if (Config->Pic)
2485 if (config->isPic)
23392486 return ET_DYN;
2340 if (Config->Relocatable)
2487 if (config->relocatable)
23412488 return ET_REL;
23422489 return ET_EXEC;
23432490}
23442491
2345static uint8_t getAbiVersion() {
2346 // MIPS non-PIC executable gets ABI version 1.
2347 if (Config->EMachine == EM_MIPS && getELFType() == ET_EXEC &&
2348 (Config->EFlags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
2349 return 1;
2350 return 0;
2351}
2352
23532492template <class ELFT> void Writer<ELFT>::writeHeader() {
2354 uint8_t *Buf = Buffer->getBufferStart();
2355
2356 // For executable segments, the trap instructions are written before writing
2357 // the header. Setting Elf header bytes to zero ensures that any unused bytes
2358 // in header are zero-cleared, instead of having trap instructions.
2359 memset(Buf, 0, sizeof(Elf_Ehdr));
2360 memcpy(Buf, "\177ELF", 4);
2361
2362 // Write the ELF header.
2363 auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Buf);
2364 EHdr->e_ident[EI_CLASS] = Config->Is64 ? ELFCLASS64 : ELFCLASS32;
2365 EHdr->e_ident[EI_DATA] = Config->IsLE ? ELFDATA2LSB : ELFDATA2MSB;
2366 EHdr->e_ident[EI_VERSION] = EV_CURRENT;
2367 EHdr->e_ident[EI_OSABI] = Config->OSABI;
2368 EHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
2369 EHdr->e_type = getELFType();
2370 EHdr->e_machine = Config->EMachine;
2371 EHdr->e_version = EV_CURRENT;
2372 EHdr->e_entry = getEntryAddr();
2373 EHdr->e_shoff = SectionHeaderOff;
2374 EHdr->e_flags = Config->EFlags;
2375 EHdr->e_ehsize = sizeof(Elf_Ehdr);
2376 EHdr->e_phnum = Phdrs.size();
2377 EHdr->e_shentsize = sizeof(Elf_Shdr);
2378
2379 if (!Config->Relocatable) {
2380 EHdr->e_phoff = sizeof(Elf_Ehdr);
2381 EHdr->e_phentsize = sizeof(Elf_Phdr);
2382 }
2383
2384 // Write the program header table.
2385 auto *HBuf = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
2386 for (PhdrEntry *P : Phdrs) {
2387 HBuf->p_type = P->p_type;
2388 HBuf->p_flags = P->p_flags;
2389 HBuf->p_offset = P->p_offset;
2390 HBuf->p_vaddr = P->p_vaddr;
2391 HBuf->p_paddr = P->p_paddr;
2392 HBuf->p_filesz = P->p_filesz;
2393 HBuf->p_memsz = P->p_memsz;
2394 HBuf->p_align = P->p_align;
2395 ++HBuf;
2396 }
2493 writeEhdr<ELFT>(Out::bufferStart, *mainPart);
2494 writePhdrs<ELFT>(Out::bufferStart + sizeof(Elf_Ehdr), *mainPart);
2495
2496 auto *eHdr = reinterpret_cast<Elf_Ehdr *>(Out::bufferStart);
2497 eHdr->e_type = getELFType();
2498 eHdr->e_entry = getEntryAddr();
2499 eHdr->e_shoff = sectionHeaderOff;
23972500
23982501 // Write the section header table.
23992502 //
......@@ -2404,57 +2507,58 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
24042507 // the value. The sentinel values and fields are:
24052508 // e_shnum = 0, SHdrs[0].sh_size = number of sections.
24062509 // e_shstrndx = SHN_XINDEX, SHdrs[0].sh_link = .shstrtab section index.
2407 auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
2408 size_t Num = OutputSections.size() + 1;
2409 if (Num >= SHN_LORESERVE)
2410 SHdrs->sh_size = Num;
2510 auto *sHdrs = reinterpret_cast<Elf_Shdr *>(Out::bufferStart + eHdr->e_shoff);
2511 size_t num = outputSections.size() + 1;
2512 if (num >= SHN_LORESERVE)
2513 sHdrs->sh_size = num;
24112514 else
2412 EHdr->e_shnum = Num;
2515 eHdr->e_shnum = num;
24132516
2414 uint32_t StrTabIndex = In.ShStrTab->getParent()->SectionIndex;
2415 if (StrTabIndex >= SHN_LORESERVE) {
2416 SHdrs->sh_link = StrTabIndex;
2417 EHdr->e_shstrndx = SHN_XINDEX;
2517 uint32_t strTabIndex = in.shStrTab->getParent()->sectionIndex;
2518 if (strTabIndex >= SHN_LORESERVE) {
2519 sHdrs->sh_link = strTabIndex;
2520 eHdr->e_shstrndx = SHN_XINDEX;
24182521 } else {
2419 EHdr->e_shstrndx = StrTabIndex;
2522 eHdr->e_shstrndx = strTabIndex;
24202523 }
24212524
2422 for (OutputSection *Sec : OutputSections)
2423 Sec->writeHeaderTo<ELFT>(++SHdrs);
2525 for (OutputSection *sec : outputSections)
2526 sec->writeHeaderTo<ELFT>(++sHdrs);
24242527}
24252528
24262529// Open a result file.
24272530template <class ELFT> void Writer<ELFT>::openFile() {
2428 uint64_t MaxSize = Config->Is64 ? INT64_MAX : UINT32_MAX;
2429 if (MaxSize < FileSize) {
2430 error("output file too large: " + Twine(FileSize) + " bytes");
2531 uint64_t maxSize = config->is64 ? INT64_MAX : UINT32_MAX;
2532 if (fileSize != size_t(fileSize) || maxSize < fileSize) {
2533 error("output file too large: " + Twine(fileSize) + " bytes");
24312534 return;
24322535 }
24332536
2434 unlinkAsync(Config->OutputFile);
2435 unsigned Flags = 0;
2436 if (!Config->Relocatable)
2437 Flags = FileOutputBuffer::F_executable;
2438 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
2439 FileOutputBuffer::create(Config->OutputFile, FileSize, Flags);
2537 unlinkAsync(config->outputFile);
2538 unsigned flags = 0;
2539 if (!config->relocatable)
2540 flags = FileOutputBuffer::F_executable;
2541 Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
2542 FileOutputBuffer::create(config->outputFile, fileSize, flags);
24402543
2441 if (!BufferOrErr)
2442 error("failed to open " + Config->OutputFile + ": " +
2443 llvm::toString(BufferOrErr.takeError()));
2444 else
2445 Buffer = std::move(*BufferOrErr);
2544 if (!bufferOrErr) {
2545 error("failed to open " + config->outputFile + ": " +
2546 llvm::toString(bufferOrErr.takeError()));
2547 return;
2548 }
2549 buffer = std::move(*bufferOrErr);
2550 Out::bufferStart = buffer->getBufferStart();
24462551}
24472552
24482553template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
2449 uint8_t *Buf = Buffer->getBufferStart();
2450 for (OutputSection *Sec : OutputSections)
2451 if (Sec->Flags & SHF_ALLOC)
2452 Sec->writeTo<ELFT>(Buf + Sec->Offset);
2554 for (OutputSection *sec : outputSections)
2555 if (sec->flags & SHF_ALLOC)
2556 sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
24532557}
24542558
2455static void fillTrap(uint8_t *I, uint8_t *End) {
2456 for (; I + 4 <= End; I += 4)
2457 memcpy(I, &Target->TrapInstr, 4);
2559static void fillTrap(uint8_t *i, uint8_t *end) {
2560 for (; i + 4 <= end; i += 4)
2561 memcpy(i, &target->trapInstr, 4);
24582562}
24592563
24602564// Fill the last page of executable segments with trap instructions
......@@ -2464,61 +2568,119 @@ static void fillTrap(uint8_t *I, uint8_t *End) {
24642568// We'll leave other pages in segments as-is because the rest will be
24652569// overwritten by output sections.
24662570template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
2467 if (Script->HasSectionsCommand)
2571 if (script->hasSectionsCommand)
24682572 return;
24692573
2470 // Fill the last page.
2471 uint8_t *Buf = Buffer->getBufferStart();
2472 for (PhdrEntry *P : Phdrs)
2473 if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
2474 fillTrap(Buf + alignDown(P->p_offset + P->p_filesz, Target->PageSize),
2475 Buf + alignTo(P->p_offset + P->p_filesz, Target->PageSize));
2476
2477 // Round up the file size of the last segment to the page boundary iff it is
2478 // an executable segment to ensure that other tools don't accidentally
2479 // trim the instruction padding (e.g. when stripping the file).
2480 PhdrEntry *Last = nullptr;
2481 for (PhdrEntry *P : Phdrs)
2482 if (P->p_type == PT_LOAD)
2483 Last = P;
2484
2485 if (Last && (Last->p_flags & PF_X))
2486 Last->p_memsz = Last->p_filesz = alignTo(Last->p_filesz, Target->PageSize);
2574 for (Partition &part : partitions) {
2575 // Fill the last page.
2576 for (PhdrEntry *p : part.phdrs)
2577 if (p->p_type == PT_LOAD && (p->p_flags & PF_X))
2578 fillTrap(Out::bufferStart + alignDown(p->firstSec->offset + p->p_filesz,
2579 config->commonPageSize),
2580 Out::bufferStart + alignTo(p->firstSec->offset + p->p_filesz,
2581 config->commonPageSize));
2582
2583 // Round up the file size of the last segment to the page boundary iff it is
2584 // an executable segment to ensure that other tools don't accidentally
2585 // trim the instruction padding (e.g. when stripping the file).
2586 PhdrEntry *last = nullptr;
2587 for (PhdrEntry *p : part.phdrs)
2588 if (p->p_type == PT_LOAD)
2589 last = p;
2590
2591 if (last && (last->p_flags & PF_X))
2592 last->p_memsz = last->p_filesz =
2593 alignTo(last->p_filesz, config->commonPageSize);
2594 }
24872595}
24882596
24892597// Write section contents to a mmap'ed file.
24902598template <class ELFT> void Writer<ELFT>::writeSections() {
2491 uint8_t *Buf = Buffer->getBufferStart();
2492
2493 OutputSection *EhFrameHdr = nullptr;
2494 if (In.EhFrameHdr && !In.EhFrameHdr->empty())
2495 EhFrameHdr = In.EhFrameHdr->getParent();
2496
24972599 // In -r or -emit-relocs mode, write the relocation sections first as in
24982600 // ELf_Rel targets we might find out that we need to modify the relocated
24992601 // section while doing it.
2500 for (OutputSection *Sec : OutputSections)
2501 if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
2502 Sec->writeTo<ELFT>(Buf + Sec->Offset);
2602 for (OutputSection *sec : outputSections)
2603 if (sec->type == SHT_REL || sec->type == SHT_RELA)
2604 sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
2605
2606 for (OutputSection *sec : outputSections)
2607 if (sec->type != SHT_REL && sec->type != SHT_RELA)
2608 sec->writeTo<ELFT>(Out::bufferStart + sec->offset);
2609}
2610
2611// Split one uint8 array into small pieces of uint8 arrays.
2612static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> arr,
2613 size_t chunkSize) {
2614 std::vector<ArrayRef<uint8_t>> ret;
2615 while (arr.size() > chunkSize) {
2616 ret.push_back(arr.take_front(chunkSize));
2617 arr = arr.drop_front(chunkSize);
2618 }
2619 if (!arr.empty())
2620 ret.push_back(arr);
2621 return ret;
2622}
25032623
2504 for (OutputSection *Sec : OutputSections)
2505 if (Sec != EhFrameHdr && Sec->Type != SHT_REL && Sec->Type != SHT_RELA)
2506 Sec->writeTo<ELFT>(Buf + Sec->Offset);
2624// Computes a hash value of Data using a given hash function.
2625// In order to utilize multiple cores, we first split data into 1MB
2626// chunks, compute a hash for each chunk, and then compute a hash value
2627// of the hash values.
2628static void
2629computeHash(llvm::MutableArrayRef<uint8_t> hashBuf,
2630 llvm::ArrayRef<uint8_t> data,
2631 std::function<void(uint8_t *dest, ArrayRef<uint8_t> arr)> hashFn) {
2632 std::vector<ArrayRef<uint8_t>> chunks = split(data, 1024 * 1024);
2633 std::vector<uint8_t> hashes(chunks.size() * hashBuf.size());
2634
2635 // Compute hash values.
2636 parallelForEachN(0, chunks.size(), [&](size_t i) {
2637 hashFn(hashes.data() + i * hashBuf.size(), chunks[i]);
2638 });
25072639
2508 // The .eh_frame_hdr depends on .eh_frame section contents, therefore
2509 // it should be written after .eh_frame is written.
2510 if (EhFrameHdr)
2511 EhFrameHdr->writeTo<ELFT>(Buf + EhFrameHdr->Offset);
2640 // Write to the final output buffer.
2641 hashFn(hashBuf.data(), hashes);
25122642}
25132643
25142644template <class ELFT> void Writer<ELFT>::writeBuildId() {
2515 if (!In.BuildId || !In.BuildId->getParent())
2645 if (!mainPart->buildId || !mainPart->buildId->getParent())
25162646 return;
25172647
2648 if (config->buildId == BuildIdKind::Hexstring) {
2649 for (Partition &part : partitions)
2650 part.buildId->writeBuildId(config->buildIdVector);
2651 return;
2652 }
2653
25182654 // Compute a hash of all sections of the output file.
2519 uint8_t *Start = Buffer->getBufferStart();
2520 uint8_t *End = Start + FileSize;
2521 In.BuildId->writeBuildId({Start, End});
2655 size_t hashSize = mainPart->buildId->hashSize;
2656 std::vector<uint8_t> buildId(hashSize);
2657 llvm::ArrayRef<uint8_t> buf{Out::bufferStart, size_t(fileSize)};
2658
2659 switch (config->buildId) {
2660 case BuildIdKind::Fast:
2661 computeHash(buildId, buf, [](uint8_t *dest, ArrayRef<uint8_t> arr) {
2662 write64le(dest, xxHash64(arr));
2663 });
2664 break;
2665 case BuildIdKind::Md5:
2666 computeHash(buildId, buf, [&](uint8_t *dest, ArrayRef<uint8_t> arr) {
2667 memcpy(dest, MD5::hash(arr).data(), hashSize);
2668 });
2669 break;
2670 case BuildIdKind::Sha1:
2671 computeHash(buildId, buf, [&](uint8_t *dest, ArrayRef<uint8_t> arr) {
2672 memcpy(dest, SHA1::hash(arr).data(), hashSize);
2673 });
2674 break;
2675 case BuildIdKind::Uuid:
2676 if (auto ec = llvm::getRandomBytes(buildId.data(), hashSize))
2677 error("entropy source failure: " + ec.message());
2678 break;
2679 default:
2680 llvm_unreachable("unknown BuildIdKind");
2681 }
2682 for (Partition &part : partitions)
2683 part.buildId->writeBuildId(buildId);
25222684}
25232685
25242686template void elf::writeResult<ELF32LE>();
deps/lld/ELF/Writer.h+13-16
......@@ -1,9 +1,8 @@
11//===- Writer.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -20,16 +19,14 @@ namespace elf {
2019class InputFile;
2120class OutputSection;
2221class InputSectionBase;
23template <class ELFT> class ObjFile;
24class SymbolTable;
2522template <class ELFT> void writeResult();
2623
2724// This describes a program header entry.
2825// Each contains type, access flags and range of output sections that will be
2926// placed in it.
3027struct PhdrEntry {
31 PhdrEntry(unsigned Type, unsigned Flags) : p_type(Type), p_flags(Flags) {}
32 void add(OutputSection *Sec);
28 PhdrEntry(unsigned type, unsigned flags) : p_type(type), p_flags(flags) {}
29 void add(OutputSection *sec);
3330
3431 uint64_t p_paddr = 0;
3532 uint64_t p_vaddr = 0;
......@@ -40,22 +37,22 @@ struct PhdrEntry {
4037 uint32_t p_type = 0;
4138 uint32_t p_flags = 0;
4239
43 OutputSection *FirstSec = nullptr;
44 OutputSection *LastSec = nullptr;
45 bool HasLMA = false;
40 OutputSection *firstSec = nullptr;
41 OutputSection *lastSec = nullptr;
42 bool hasLMA = false;
4643
47 uint64_t LMAOffset = 0;
44 uint64_t lmaOffset = 0;
4845};
4946
5047void addReservedSymbols();
51llvm::StringRef getOutputSectionName(const InputSectionBase *S);
48llvm::StringRef getOutputSectionName(const InputSectionBase *s);
5249
5350template <class ELFT> uint32_t calcMipsEFlags();
5451
55uint8_t getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
56 llvm::StringRef FileName);
52uint8_t getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag,
53 llvm::StringRef fileName);
5754
58bool isMipsN32Abi(const InputFile *F);
55bool isMipsN32Abi(const InputFile *f);
5956bool isMicroMips();
6057bool isMipsR6();
6158} // namespace elf
deps/lld/LICENSE.TXT+236-20
......@@ -1,5 +1,240 @@
11==============================================================================
2lld License
2The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
3==============================================================================
4
5 Apache License
6 Version 2.0, January 2004
7 http://www.apache.org/licenses/
8
9 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
10
11 1. Definitions.
12
13 "License" shall mean the terms and conditions for use, reproduction,
14 and distribution as defined by Sections 1 through 9 of this document.
15
16 "Licensor" shall mean the copyright owner or entity authorized by
17 the copyright owner that is granting the License.
18
19 "Legal Entity" shall mean the union of the acting entity and all
20 other entities that control, are controlled by, or are under common
21 control with that entity. For the purposes of this definition,
22 "control" means (i) the power, direct or indirect, to cause the
23 direction or management of such entity, whether by contract or
24 otherwise, or (ii) ownership of fifty percent (50%) or more of the
25 outstanding shares, or (iii) beneficial ownership of such entity.
26
27 "You" (or "Your") shall mean an individual or Legal Entity
28 exercising permissions granted by this License.
29
30 "Source" form shall mean the preferred form for making modifications,
31 including but not limited to software source code, documentation
32 source, and configuration files.
33
34 "Object" form shall mean any form resulting from mechanical
35 transformation or translation of a Source form, including but
36 not limited to compiled object code, generated documentation,
37 and conversions to other media types.
38
39 "Work" shall mean the work of authorship, whether in Source or
40 Object form, made available under the License, as indicated by a
41 copyright notice that is included in or attached to the work
42 (an example is provided in the Appendix below).
43
44 "Derivative Works" shall mean any work, whether in Source or Object
45 form, that is based on (or derived from) the Work and for which the
46 editorial revisions, annotations, elaborations, or other modifications
47 represent, as a whole, an original work of authorship. For the purposes
48 of this License, Derivative Works shall not include works that remain
49 separable from, or merely link (or bind by name) to the interfaces of,
50 the Work and Derivative Works thereof.
51
52 "Contribution" shall mean any work of authorship, including
53 the original version of the Work and any modifications or additions
54 to that Work or Derivative Works thereof, that is intentionally
55 submitted to Licensor for inclusion in the Work by the copyright owner
56 or by an individual or Legal Entity authorized to submit on behalf of
57 the copyright owner. For the purposes of this definition, "submitted"
58 means any form of electronic, verbal, or written communication sent
59 to the Licensor or its representatives, including but not limited to
60 communication on electronic mailing lists, source code control systems,
61 and issue tracking systems that are managed by, or on behalf of, the
62 Licensor for the purpose of discussing and improving the Work, but
63 excluding communication that is conspicuously marked or otherwise
64 designated in writing by the copyright owner as "Not a Contribution."
65
66 "Contributor" shall mean Licensor and any individual or Legal Entity
67 on behalf of whom a Contribution has been received by Licensor and
68 subsequently incorporated within the Work.
69
70 2. Grant of Copyright License. Subject to the terms and conditions of
71 this License, each Contributor hereby grants to You a perpetual,
72 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
73 copyright license to reproduce, prepare Derivative Works of,
74 publicly display, publicly perform, sublicense, and distribute the
75 Work and such Derivative Works in Source or Object form.
76
77 3. Grant of Patent License. Subject to the terms and conditions of
78 this License, each Contributor hereby grants to You a perpetual,
79 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
80 (except as stated in this section) patent license to make, have made,
81 use, offer to sell, sell, import, and otherwise transfer the Work,
82 where such license applies only to those patent claims licensable
83 by such Contributor that are necessarily infringed by their
84 Contribution(s) alone or by combination of their Contribution(s)
85 with the Work to which such Contribution(s) was submitted. If You
86 institute patent litigation against any entity (including a
87 cross-claim or counterclaim in a lawsuit) alleging that the Work
88 or a Contribution incorporated within the Work constitutes direct
89 or contributory patent infringement, then any patent licenses
90 granted to You under this License for that Work shall terminate
91 as of the date such litigation is filed.
92
93 4. Redistribution. You may reproduce and distribute copies of the
94 Work or Derivative Works thereof in any medium, with or without
95 modifications, and in Source or Object form, provided that You
96 meet the following conditions:
97
98 (a) You must give any other recipients of the Work or
99 Derivative Works a copy of this License; and
100
101 (b) You must cause any modified files to carry prominent notices
102 stating that You changed the files; and
103
104 (c) You must retain, in the Source form of any Derivative Works
105 that You distribute, all copyright, patent, trademark, and
106 attribution notices from the Source form of the Work,
107 excluding those notices that do not pertain to any part of
108 the Derivative Works; and
109
110 (d) If the Work includes a "NOTICE" text file as part of its
111 distribution, then any Derivative Works that You distribute must
112 include a readable copy of the attribution notices contained
113 within such NOTICE file, excluding those notices that do not
114 pertain to any part of the Derivative Works, in at least one
115 of the following places: within a NOTICE text file distributed
116 as part of the Derivative Works; within the Source form or
117 documentation, if provided along with the Derivative Works; or,
118 within a display generated by the Derivative Works, if and
119 wherever such third-party notices normally appear. The contents
120 of the NOTICE file are for informational purposes only and
121 do not modify the License. You may add Your own attribution
122 notices within Derivative Works that You distribute, alongside
123 or as an addendum to the NOTICE text from the Work, provided
124 that such additional attribution notices cannot be construed
125 as modifying the License.
126
127 You may add Your own copyright statement to Your modifications and
128 may provide additional or different license terms and conditions
129 for use, reproduction, or distribution of Your modifications, or
130 for any such Derivative Works as a whole, provided Your use,
131 reproduction, and distribution of the Work otherwise complies with
132 the conditions stated in this License.
133
134 5. Submission of Contributions. Unless You explicitly state otherwise,
135 any Contribution intentionally submitted for inclusion in the Work
136 by You to the Licensor shall be under the terms and conditions of
137 this License, without any additional terms or conditions.
138 Notwithstanding the above, nothing herein shall supersede or modify
139 the terms of any separate license agreement you may have executed
140 with Licensor regarding such Contributions.
141
142 6. Trademarks. This License does not grant permission to use the trade
143 names, trademarks, service marks, or product names of the Licensor,
144 except as required for reasonable and customary use in describing the
145 origin of the Work and reproducing the content of the NOTICE file.
146
147 7. Disclaimer of Warranty. Unless required by applicable law or
148 agreed to in writing, Licensor provides the Work (and each
149 Contributor provides its Contributions) on an "AS IS" BASIS,
150 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
151 implied, including, without limitation, any warranties or conditions
152 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
153 PARTICULAR PURPOSE. You are solely responsible for determining the
154 appropriateness of using or redistributing the Work and assume any
155 risks associated with Your exercise of permissions under this License.
156
157 8. Limitation of Liability. In no event and under no legal theory,
158 whether in tort (including negligence), contract, or otherwise,
159 unless required by applicable law (such as deliberate and grossly
160 negligent acts) or agreed to in writing, shall any Contributor be
161 liable to You for damages, including any direct, indirect, special,
162 incidental, or consequential damages of any character arising as a
163 result of this License or out of the use or inability to use the
164 Work (including but not limited to damages for loss of goodwill,
165 work stoppage, computer failure or malfunction, or any and all
166 other commercial damages or losses), even if such Contributor
167 has been advised of the possibility of such damages.
168
169 9. Accepting Warranty or Additional Liability. While redistributing
170 the Work or Derivative Works thereof, You may choose to offer,
171 and charge a fee for, acceptance of support, warranty, indemnity,
172 or other liability obligations and/or rights consistent with this
173 License. However, in accepting such obligations, You may act only
174 on Your own behalf and on Your sole responsibility, not on behalf
175 of any other Contributor, and only if You agree to indemnify,
176 defend, and hold each Contributor harmless for any liability
177 incurred by, or claims asserted against, such Contributor by reason
178 of your accepting any such warranty or additional liability.
179
180 END OF TERMS AND CONDITIONS
181
182 APPENDIX: How to apply the Apache License to your work.
183
184 To apply the Apache License to your work, attach the following
185 boilerplate notice, with the fields enclosed by brackets "[]"
186 replaced with your own identifying information. (Don't include
187 the brackets!) The text should be enclosed in the appropriate
188 comment syntax for the file format. We also recommend that a
189 file or class name and description of purpose be included on the
190 same "printed page" as the copyright notice for easier
191 identification within third-party archives.
192
193 Copyright [yyyy] [name of copyright owner]
194
195 Licensed under the Apache License, Version 2.0 (the "License");
196 you may not use this file except in compliance with the License.
197 You may obtain a copy of the License at
198
199 http://www.apache.org/licenses/LICENSE-2.0
200
201 Unless required by applicable law or agreed to in writing, software
202 distributed under the License is distributed on an "AS IS" BASIS,
203 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
204 See the License for the specific language governing permissions and
205 limitations under the License.
206
207
208---- LLVM Exceptions to the Apache 2.0 License ----
209
210As an exception, if, as a result of your compiling your source code, portions
211of this Software are embedded into an Object form of such source code, you
212may redistribute such embedded portions in such Object form without complying
213with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
214
215In addition, if you combine or link compiled forms of this Software with
216software that is licensed under the GPLv2 ("Combined Software") and if a
217court of competent jurisdiction determines that the patent provision (Section
2183), the indemnity provision (Section 9) or other Section of the License
219conflicts with the conditions of the GPLv2, you may retroactively and
220prospectively choose to deem waived or otherwise exclude such Section(s) of
221the License, but only in their entirety and only with respect to the Combined
222Software.
223
224==============================================================================
225Software from third parties included in the LLVM Project:
226==============================================================================
227The LLVM Project contains third party software which is under different license
228terms. All such code will be identified clearly using at least one of two
229mechanisms:
2301) It will be in a separate directory tree with its own `LICENSE.txt` or
231 `LICENSE` file at the top containing the specific license and restrictions
232 which apply to that software, or
2332) It will contain specific license and restriction terms at the top of every
234 file.
235
236==============================================================================
237Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
3238==============================================================================
4239University of Illinois/NCSA
5240Open Source License
......@@ -41,22 +276,3 @@ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41276LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42277OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
43278SOFTWARE.
44
45==============================================================================
46The lld software contains code written by third parties. Such software will
47have its own individual LICENSE.TXT file in the directory in which it appears.
48This file will describe the copyrights, license, and restrictions which apply
49to that code.
50
51The disclaimer of warranty in the University of Illinois Open Source License
52applies to all code in the lld Distribution, and nothing in any of the
53other licenses gives permission to use the names of the LLVM Team or the
54University of Illinois to endorse or promote products derived from this
55Software.
56
57The following pieces of software have additional or alternate copyrights,
58licenses, and/or restrictions:
59
60Program Directory
61------- ---------
62<none yet>
deps/lld/MinGW/Driver.cpp+216-145
......@@ -1,9 +1,8 @@
11//===- MinGW/Driver.cpp ---------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -31,10 +30,13 @@
3130
3231#include "lld/Common/Driver.h"
3332#include "lld/Common/ErrorHandler.h"
33#include "lld/Common/Memory.h"
34#include "lld/Common/Version.h"
3435#include "llvm/ADT/ArrayRef.h"
3536#include "llvm/ADT/Optional.h"
3637#include "llvm/ADT/StringExtras.h"
3738#include "llvm/ADT/StringRef.h"
39#include "llvm/ADT/Triple.h"
3840#include "llvm/Option/Arg.h"
3941#include "llvm/Option/ArgList.h"
4042#include "llvm/Option/Option.h"
......@@ -63,7 +65,7 @@ enum {
6365#undef PREFIX
6466
6567// Create table mapping all options defined in Options.td
66static const opt::OptTable::Info InfoTable[] = {
68static const opt::OptTable::Info infoTable[] = {
6769#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
6870 {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
6971 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
......@@ -74,208 +76,277 @@ static const opt::OptTable::Info InfoTable[] = {
7476namespace {
7577class MinGWOptTable : public opt::OptTable {
7678public:
77 MinGWOptTable() : OptTable(InfoTable, false) {}
78 opt::InputArgList parse(ArrayRef<const char *> Argv);
79 MinGWOptTable() : OptTable(infoTable, false) {}
80 opt::InputArgList parse(ArrayRef<const char *> argv);
7981};
8082} // namespace
8183
82opt::InputArgList MinGWOptTable::parse(ArrayRef<const char *> Argv) {
83 unsigned MissingIndex;
84 unsigned MissingCount;
84static void printHelp(const char *argv0) {
85 MinGWOptTable().PrintHelp(
86 outs(), (std::string(argv0) + " [options] file...").c_str(), "lld",
87 false /*ShowHidden*/, true /*ShowAllAliases*/);
88 outs() << "\n";
89}
8590
86 SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());
87 opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
91static cl::TokenizerCallback getQuotingStyle() {
92 if (Triple(sys::getProcessTriple()).getOS() == Triple::Win32)
93 return cl::TokenizeWindowsCommandLine;
94 return cl::TokenizeGNUCommandLine;
95}
8896
89 if (MissingCount)
90 fatal(StringRef(Args.getArgString(MissingIndex)) + ": missing argument");
91 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
92 fatal("unknown argument: " + Arg->getSpelling());
93 if (!Args.hasArg(OPT_INPUT) && !Args.hasArg(OPT_l))
94 fatal("no input files");
95 return Args;
97opt::InputArgList MinGWOptTable::parse(ArrayRef<const char *> argv) {
98 unsigned missingIndex;
99 unsigned missingCount;
100
101 SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
102 cl::ExpandResponseFiles(saver, getQuotingStyle(), vec);
103 opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount);
104
105 if (missingCount)
106 fatal(StringRef(args.getArgString(missingIndex)) + ": missing argument");
107 for (auto *arg : args.filtered(OPT_UNKNOWN))
108 fatal("unknown argument: " + arg->getAsString(args));
109 return args;
96110}
97111
98112// Find a file by concatenating given paths.
99static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
100 SmallString<128> S;
101 sys::path::append(S, Path1, Path2);
102 if (sys::fs::exists(S))
103 return S.str().str();
113static Optional<std::string> findFile(StringRef path1, const Twine &path2) {
114 SmallString<128> s;
115 sys::path::append(s, path1, path2);
116 if (sys::fs::exists(s))
117 return s.str().str();
104118 return None;
105119}
106120
107121// This is for -lfoo. We'll look for libfoo.dll.a or libfoo.a from search paths.
108122static std::string
109searchLibrary(StringRef Name, ArrayRef<StringRef> SearchPaths, bool BStatic) {
110 if (Name.startswith(":")) {
111 for (StringRef Dir : SearchPaths)
112 if (Optional<std::string> S = findFile(Dir, Name.substr(1)))
113 return *S;
114 fatal("unable to find library -l" + Name);
123searchLibrary(StringRef name, ArrayRef<StringRef> searchPaths, bool bStatic) {
124 if (name.startswith(":")) {
125 for (StringRef dir : searchPaths)
126 if (Optional<std::string> s = findFile(dir, name.substr(1)))
127 return *s;
128 fatal("unable to find library -l" + name);
115129 }
116130
117 for (StringRef Dir : SearchPaths) {
118 if (!BStatic)
119 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".dll.a"))
120 return *S;
121 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a"))
122 return *S;
131 for (StringRef dir : searchPaths) {
132 if (!bStatic)
133 if (Optional<std::string> s = findFile(dir, "lib" + name + ".dll.a"))
134 return *s;
135 if (Optional<std::string> s = findFile(dir, "lib" + name + ".a"))
136 return *s;
123137 }
124 fatal("unable to find library -l" + Name);
138 fatal("unable to find library -l" + name);
125139}
126140
127141// Convert Unix-ish command line arguments to Windows-ish ones and
128142// then call coff::link.
129bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) {
130 MinGWOptTable Parser;
131 opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
143bool mingw::link(ArrayRef<const char *> argsArr, raw_ostream &diag) {
144 MinGWOptTable parser;
145 opt::InputArgList args = parser.parse(argsArr.slice(1));
146
147 if (args.hasArg(OPT_help)) {
148 printHelp(argsArr[0]);
149 return true;
150 }
151
152 // A note about "compatible with GNU linkers" message: this is a hack for
153 // scripts generated by GNU Libtool 2.4.6 (released in February 2014 and
154 // still the newest version in March 2017) or earlier to recognize LLD as
155 // a GNU compatible linker. As long as an output for the -v option
156 // contains "GNU" or "with BFD", they recognize us as GNU-compatible.
157 if (args.hasArg(OPT_v) || args.hasArg(OPT_version))
158 message(getLLDVersion() + " (compatible with GNU linkers)");
159
160 // The behavior of -v or --version is a bit strange, but this is
161 // needed for compatibility with GNU linkers.
162 if (args.hasArg(OPT_v) && !args.hasArg(OPT_INPUT) && !args.hasArg(OPT_l))
163 return true;
164 if (args.hasArg(OPT_version))
165 return true;
132166
133 std::vector<std::string> LinkArgs;
134 auto Add = [&](const Twine &S) { LinkArgs.push_back(S.str()); };
167 if (!args.hasArg(OPT_INPUT) && !args.hasArg(OPT_l))
168 fatal("no input files");
169
170 std::vector<std::string> linkArgs;
171 auto add = [&](const Twine &s) { linkArgs.push_back(s.str()); };
135172
136 Add("lld-link");
137 Add("-lldmingw");
173 add("lld-link");
174 add("-lldmingw");
138175
139 if (auto *A = Args.getLastArg(OPT_entry)) {
140 StringRef S = A->getValue();
141 if (Args.getLastArgValue(OPT_m) == "i386pe" && S.startswith("_"))
142 Add("-entry:" + S.substr(1));
176 if (auto *a = args.getLastArg(OPT_entry)) {
177 StringRef s = a->getValue();
178 if (args.getLastArgValue(OPT_m) == "i386pe" && s.startswith("_"))
179 add("-entry:" + s.substr(1));
143180 else
144 Add("-entry:" + S);
181 add("-entry:" + s);
182 }
183
184 if (args.hasArg(OPT_major_os_version, OPT_minor_os_version,
185 OPT_major_subsystem_version, OPT_minor_subsystem_version)) {
186 auto *majOSVer = args.getLastArg(OPT_major_os_version);
187 auto *minOSVer = args.getLastArg(OPT_minor_os_version);
188 auto *majSubSysVer = args.getLastArg(OPT_major_subsystem_version);
189 auto *minSubSysVer = args.getLastArg(OPT_minor_subsystem_version);
190 if (majOSVer && majSubSysVer &&
191 StringRef(majOSVer->getValue()) != StringRef(majSubSysVer->getValue()))
192 warn("--major-os-version and --major-subsystem-version set to differing "
193 "versions, not supported");
194 if (minOSVer && minSubSysVer &&
195 StringRef(minOSVer->getValue()) != StringRef(minSubSysVer->getValue()))
196 warn("--minor-os-version and --minor-subsystem-version set to differing "
197 "versions, not supported");
198 StringRef subSys = args.getLastArgValue(OPT_subs, "default");
199 StringRef major = majOSVer ? majOSVer->getValue()
200 : majSubSysVer ? majSubSysVer->getValue() : "6";
201 StringRef minor = minOSVer ? minOSVer->getValue()
202 : minSubSysVer ? minSubSysVer->getValue() : "";
203 StringRef sep = minor.empty() ? "" : ".";
204 add("-subsystem:" + subSys + "," + major + sep + minor);
205 } else if (auto *a = args.getLastArg(OPT_subs)) {
206 add("-subsystem:" + StringRef(a->getValue()));
145207 }
146208
147 if (auto *A = Args.getLastArg(OPT_subs))
148 Add("-subsystem:" + StringRef(A->getValue()));
149 if (auto *A = Args.getLastArg(OPT_out_implib))
150 Add("-implib:" + StringRef(A->getValue()));
151 if (auto *A = Args.getLastArg(OPT_stack))
152 Add("-stack:" + StringRef(A->getValue()));
153 if (auto *A = Args.getLastArg(OPT_output_def))
154 Add("-output-def:" + StringRef(A->getValue()));
155 if (auto *A = Args.getLastArg(OPT_image_base))
156 Add("-base:" + StringRef(A->getValue()));
157 if (auto *A = Args.getLastArg(OPT_map))
158 Add("-lldmap:" + StringRef(A->getValue()));
159
160 if (auto *A = Args.getLastArg(OPT_o))
161 Add("-out:" + StringRef(A->getValue()));
162 else if (Args.hasArg(OPT_shared))
163 Add("-out:a.dll");
209 if (auto *a = args.getLastArg(OPT_out_implib))
210 add("-implib:" + StringRef(a->getValue()));
211 if (auto *a = args.getLastArg(OPT_stack))
212 add("-stack:" + StringRef(a->getValue()));
213 if (auto *a = args.getLastArg(OPT_output_def))
214 add("-output-def:" + StringRef(a->getValue()));
215 if (auto *a = args.getLastArg(OPT_image_base))
216 add("-base:" + StringRef(a->getValue()));
217 if (auto *a = args.getLastArg(OPT_map))
218 add("-lldmap:" + StringRef(a->getValue()));
219
220 if (auto *a = args.getLastArg(OPT_o))
221 add("-out:" + StringRef(a->getValue()));
222 else if (args.hasArg(OPT_shared))
223 add("-out:a.dll");
164224 else
165 Add("-out:a.exe");
166
167 if (auto *A = Args.getLastArg(OPT_pdb)) {
168 Add("-debug");
169 Add("-pdb:" + StringRef(A->getValue()));
170 } else if (Args.hasArg(OPT_strip_debug)) {
171 Add("-debug:symtab");
172 } else if (!Args.hasArg(OPT_strip_all)) {
173 Add("-debug:dwarf");
225 add("-out:a.exe");
226
227 if (auto *a = args.getLastArg(OPT_pdb)) {
228 add("-debug");
229 StringRef v = a->getValue();
230 if (!v.empty())
231 add("-pdb:" + v);
232 } else if (args.hasArg(OPT_strip_debug)) {
233 add("-debug:symtab");
234 } else if (!args.hasArg(OPT_strip_all)) {
235 add("-debug:dwarf");
174236 }
175237
176 if (Args.hasArg(OPT_shared))
177 Add("-dll");
178 if (Args.hasArg(OPT_verbose))
179 Add("-verbose");
180 if (Args.hasArg(OPT_export_all_symbols))
181 Add("-export-all-symbols");
182 if (Args.hasArg(OPT_large_address_aware))
183 Add("-largeaddressaware");
184 if (Args.hasArg(OPT_kill_at))
185 Add("-kill-at");
186
187 if (Args.getLastArgValue(OPT_m) != "thumb2pe" &&
188 Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase))
189 Add("-dynamicbase:no");
190
191 if (Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false))
192 Add("-opt:ref");
238 if (args.hasArg(OPT_shared))
239 add("-dll");
240 if (args.hasArg(OPT_verbose))
241 add("-verbose");
242 if (args.hasArg(OPT_exclude_all_symbols))
243 add("-exclude-all-symbols");
244 if (args.hasArg(OPT_export_all_symbols))
245 add("-export-all-symbols");
246 if (args.hasArg(OPT_large_address_aware))
247 add("-largeaddressaware");
248 if (args.hasArg(OPT_kill_at))
249 add("-kill-at");
250 if (args.hasArg(OPT_appcontainer))
251 add("-appcontainer");
252
253 if (args.getLastArgValue(OPT_m) != "thumb2pe" &&
254 args.getLastArgValue(OPT_m) != "arm64pe" && !args.hasArg(OPT_dynamicbase))
255 add("-dynamicbase:no");
256
257 if (args.hasFlag(OPT_no_insert_timestamp, OPT_insert_timestamp, false))
258 add("-timestamp:0");
259
260 if (args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false))
261 add("-opt:ref");
193262 else
194 Add("-opt:noref");
195
196 if (auto *A = Args.getLastArg(OPT_icf)) {
197 StringRef S = A->getValue();
198 if (S == "all")
199 Add("-opt:icf");
200 else if (S == "safe" || S == "none")
201 Add("-opt:noicf");
263 add("-opt:noref");
264
265 if (auto *a = args.getLastArg(OPT_icf)) {
266 StringRef s = a->getValue();
267 if (s == "all")
268 add("-opt:icf");
269 else if (s == "safe" || s == "none")
270 add("-opt:noicf");
202271 else
203 fatal("unknown parameter: --icf=" + S);
272 fatal("unknown parameter: --icf=" + s);
204273 } else {
205 Add("-opt:noicf");
274 add("-opt:noicf");
206275 }
207276
208 if (auto *A = Args.getLastArg(OPT_m)) {
209 StringRef S = A->getValue();
210 if (S == "i386pe")
211 Add("-machine:x86");
212 else if (S == "i386pep")
213 Add("-machine:x64");
214 else if (S == "thumb2pe")
215 Add("-machine:arm");
216 else if (S == "arm64pe")
217 Add("-machine:arm64");
277 if (auto *a = args.getLastArg(OPT_m)) {
278 StringRef s = a->getValue();
279 if (s == "i386pe")
280 add("-machine:x86");
281 else if (s == "i386pep")
282 add("-machine:x64");
283 else if (s == "thumb2pe")
284 add("-machine:arm");
285 else if (s == "arm64pe")
286 add("-machine:arm64");
218287 else
219 fatal("unknown parameter: -m" + S);
288 fatal("unknown parameter: -m" + s);
220289 }
221290
222 for (auto *A : Args.filtered(OPT_mllvm))
223 Add("-mllvm:" + StringRef(A->getValue()));
291 for (auto *a : args.filtered(OPT_mllvm))
292 add("-mllvm:" + StringRef(a->getValue()));
224293
225 for (auto *A : Args.filtered(OPT_Xlink))
226 Add(A->getValue());
294 for (auto *a : args.filtered(OPT_Xlink))
295 add(a->getValue());
227296
228 if (Args.getLastArgValue(OPT_m) == "i386pe")
229 Add("-alternatename:__image_base__=___ImageBase");
297 if (args.getLastArgValue(OPT_m) == "i386pe")
298 add("-alternatename:__image_base__=___ImageBase");
230299 else
231 Add("-alternatename:__image_base__=__ImageBase");
300 add("-alternatename:__image_base__=__ImageBase");
232301
233 for (auto *A : Args.filtered(OPT_require_defined))
234 Add("-include:" + StringRef(A->getValue()));
302 for (auto *a : args.filtered(OPT_require_defined))
303 add("-include:" + StringRef(a->getValue()));
304 for (auto *a : args.filtered(OPT_undefined))
305 add("-includeoptional:" + StringRef(a->getValue()));
235306
236 std::vector<StringRef> SearchPaths;
237 for (auto *A : Args.filtered(OPT_L)) {
238 SearchPaths.push_back(A->getValue());
239 Add("-libpath:" + StringRef(A->getValue()));
307 std::vector<StringRef> searchPaths;
308 for (auto *a : args.filtered(OPT_L)) {
309 searchPaths.push_back(a->getValue());
310 add("-libpath:" + StringRef(a->getValue()));
240311 }
241312
242 StringRef Prefix = "";
243 bool Static = false;
244 for (auto *A : Args) {
245 switch (A->getOption().getUnaliasedOption().getID()) {
313 StringRef prefix = "";
314 bool isStatic = false;
315 for (auto *a : args) {
316 switch (a->getOption().getID()) {
246317 case OPT_INPUT:
247 if (StringRef(A->getValue()).endswith_lower(".def"))
248 Add("-def:" + StringRef(A->getValue()));
318 if (StringRef(a->getValue()).endswith_lower(".def"))
319 add("-def:" + StringRef(a->getValue()));
249320 else
250 Add(Prefix + StringRef(A->getValue()));
321 add(prefix + StringRef(a->getValue()));
251322 break;
252323 case OPT_l:
253 Add(Prefix + searchLibrary(A->getValue(), SearchPaths, Static));
324 add(prefix + searchLibrary(a->getValue(), searchPaths, isStatic));
254325 break;
255326 case OPT_whole_archive:
256 Prefix = "-wholearchive:";
327 prefix = "-wholearchive:";
257328 break;
258329 case OPT_no_whole_archive:
259 Prefix = "";
330 prefix = "";
260331 break;
261332 case OPT_Bstatic:
262 Static = true;
333 isStatic = true;
263334 break;
264335 case OPT_Bdynamic:
265 Static = false;
336 isStatic = false;
266337 break;
267338 }
268339 }
269340
270 if (Args.hasArg(OPT_verbose) || Args.hasArg(OPT__HASH_HASH_HASH))
271 outs() << llvm::join(LinkArgs, " ") << "\n";
341 if (args.hasArg(OPT_verbose) || args.hasArg(OPT__HASH_HASH_HASH))
342 outs() << llvm::join(linkArgs, " ") << "\n";
272343
273 if (Args.hasArg(OPT__HASH_HASH_HASH))
344 if (args.hasArg(OPT__HASH_HASH_HASH))
274345 return true;
275346
276347 // Repack vector of strings to vector of const char pointers for coff::link.
277 std::vector<const char *> Vec;
278 for (const std::string &S : LinkArgs)
279 Vec.push_back(S.c_str());
280 return coff::link(Vec, true);
348 std::vector<const char *> vec;
349 for (const std::string &s : linkArgs)
350 vec.push_back(s.c_str());
351 return coff::link(vec, true);
281352}
deps/lld/MinGW/Options.td+51-23
......@@ -6,20 +6,45 @@ class S<string name>: Separate<["--", "-"], name>;
66
77def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
88 HelpText<"Add a directory to the library search path">;
9def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
10def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">;
911def dynamicbase: F<"dynamicbase">, HelpText<"Enable ASLR">;
1012def entry: S<"entry">, MetaVarName<"<entry>">,
1113 HelpText<"Name of entry point symbol">;
14def exclude_all_symbols: F<"exclude-all-symbols">,
15 HelpText<"Don't automatically export any symbols">;
1216def export_all_symbols: F<"export-all-symbols">,
1317 HelpText<"Export all symbols even if a def file or dllexport attributes are used">;
1418def gc_sections: F<"gc-sections">, HelpText<"Remove unused sections">;
19def help: F<"help">, HelpText<"Print option help">;
1520def icf: J<"icf=">, HelpText<"Identical code folding">;
1621def image_base: S<"image-base">, HelpText<"Base address of the program">;
22def insert_timestamp: F<"insert-timestamp">,
23 HelpText<"Include PE header timestamp">;
1724def kill_at: F<"kill-at">, HelpText<"Remove @n from exported symbols">;
1825def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">,
1926 HelpText<"Root name of library to use">;
2027def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">;
28def major_os_version: Separate<["--"], "major-os-version">,
29 HelpText<"Set the OS and subsystem major version">;
30def major_os_version_eq: Joined<["--"], "major-os-version=">,
31 Alias<major_os_version>;
32def major_subsystem_version: Separate<["--"], "major-subsystem-version">,
33 HelpText<"Set the OS and subsystem major version">;
34def major_subsystem_version_eq: Joined<["--"], "major-subsystem-version=">,
35 Alias<major_subsystem_version>;
2136def map: S<"Map">, HelpText<"Output a linker map">;
2237def map_eq: J<"Map=">, Alias<map>;
38def minor_os_version: Separate<["--"], "minor-os-version">,
39 HelpText<"Set the OS and subsystem minor version">;
40def minor_os_version_eq: Joined<["--"], "minor-os-version=">,
41 Alias<minor_os_version>;
42def minor_subsystem_version: Separate<["--"], "minor-subsystem-version">,
43 HelpText<"Set the OS and subsystem minor version">;
44def minor_subsystem_version_eq: Joined<["--"], "minor-subsystem-version=">,
45 Alias<minor_subsystem_version>;
46def no_insert_timestamp: F<"no-insert-timestamp">,
47 HelpText<"Don't include PE header timestamp">;
2348def no_whole_archive: F<"no-whole-archive">,
2449 HelpText<"No longer include all object files for following archives">;
2550def large_address_aware: Flag<["--"], "large-address-aware">,
......@@ -32,14 +57,21 @@ def out_implib_eq: Joined<["--"], "out-implib=">, Alias<out_implib>;
3257def output_def: S<"output-def">, HelpText<"Output def file">;
3358def shared: F<"shared">, HelpText<"Build a shared object">;
3459def subs: S<"subsystem">, HelpText<"Specify subsystem">;
60def subs_eq: J<"subsystem=">, Alias<subs>;
3561def stack: S<"stack">;
3662def strip_all: F<"strip-all">,
3763 HelpText<"Omit all symbol information from the output binary">;
3864def strip_debug: F<"strip-debug">,
3965 HelpText<"Omit all debug information, but keep symbol information">;
66def undefined: S<"u">,
67 HelpText<"Include symbol in the link, if available">;
68def undefined_long: S<"undefined">, Alias<undefined>;
69def undefined_eq: J<"undefined=">, Alias<undefined>;
4070def whole_archive: F<"whole-archive">,
4171 HelpText<"Include all object files for following archives">;
72def v: Flag<["-"], "v">, HelpText<"Display the version number">;
4273def verbose: F<"verbose">, HelpText<"Verbose mode">;
74def version: F<"version">, HelpText<"Display the version number and exit">;
4375def require_defined: S<"require-defined">,
4476 HelpText<"Force symbol to be added to symbol table as an undefined one">;
4577def require_defined_eq: J<"require-defined=">, Alias<require_defined>;
......@@ -47,40 +79,36 @@ def require_defined_eq: J<"require-defined=">, Alias<require_defined>;
4779// LLD specific options
4880def _HASH_HASH_HASH : Flag<["-"], "###">,
4981 HelpText<"Print (but do not run) the commands to run for this compilation">;
82def appcontainer: F<"appcontainer">, HelpText<"Set the appcontainer flag in the executable">;
5083def mllvm: S<"mllvm">;
51def pdb: S<"pdb">, HelpText<"Specify output PDB debug information file">;
84def pdb: S<"pdb">, HelpText<"Output PDB debug info file, chosen implicitly if the argument is empty">;
85def pdb_eq: J<"pdb=">, Alias<pdb>;
5286def Xlink : J<"Xlink=">, MetaVarName<"<arg>">,
5387 HelpText<"Pass <arg> to the COFF linker">;
5488
55// Currently stubs to avoid errors
56def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
57def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">;
58def O: Joined<["-"], "O">, HelpText<"Optimize output file size">;
59def build_id: F<"build-id">;
60def disable_auto_image_base: F<"disable-auto-image-base">;
61def enable_auto_image_base: F<"enable-auto-image-base">;
62def enable_auto_import: F<"enable-auto-import">;
63def end_group: F<"end-group">;
64def full_shutdown: Flag<["--"], "full-shutdown">;
65def high_entropy_va: F<"high-entropy-va">, HelpText<"Enable 64-bit ASLR">;
66def major_image_version: S<"major-image-version">;
67def minor_image_version: S<"minor-image-version">;
68def no_seh: F<"no-seh">;
69def nxcompat: F<"nxcompat">, HelpText<"Enable data execution prevention">;
70def pic_executable: F<"pic-executable">;
71def sysroot: J<"sysroot">, HelpText<"Sysroot">;
72def start_group: F<"start-group">;
73def tsaware: F<"tsaware">, HelpText<"Create Terminal Server aware executable">;
74def v: Flag<["-"], "v">, HelpText<"Display the version number">;
75def version: F<"version">, HelpText<"Display the version number and exit">;
76
7789// Alias
7890def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
7991def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>;
8092def alias_strip_S: Flag<["-"], "S">, Alias<strip_debug>;
8193
8294// Ignored options
95def: Joined<["-"], "O">;
96def: F<"build-id">;
97def: F<"disable-auto-image-base">;
98def: F<"enable-auto-image-base">;
99def: F<"enable-auto-import">, HelpText<"Ignored; listed for libtool compatibility">;
100def: F<"end-group">;
101def: Flag<["--"], "full-shutdown">;
102def: F<"high-entropy-va">;
103def: S<"major-image-version">;
104def: S<"minor-image-version">;
105def: F<"no-seh">;
106def: F<"nxcompat">;
107def: F<"pic-executable">;
83108def: S<"plugin">;
84109def: J<"plugin=">;
85110def: S<"plugin-opt">;
86111def: J<"plugin-opt=">;
112def: J<"sysroot">;
113def: F<"start-group">;
114def: F<"tsaware">;
deps/lld/docs/NewLLD.rst+8
......@@ -307,3 +307,11 @@ Glossary
307307 On Unix, your program is generally not guaranteed to be safe with ICF,
308308 although large programs happen to work correctly.
309309 LLD works fine with ICF for example.
310
311Other Info
312----------
313
314.. toctree::
315 :maxdepth: 1
316
317 missingkeyfunction
deps/lld/docs/Partitions.rst created+116
......@@ -0,0 +1,116 @@
1Partitions
2==========
3
4.. warning::
5
6 This feature is currently experimental, and its interface is subject
7 to change.
8
9LLD's partitioning feature allows a program (which may be an executable
10or a shared library) to be split into multiple pieces, or partitions. A
11partitioned program consists of a main partition together with a number of
12loadable partitions. The loadable partitions depend on the main partition
13in a similar way to a regular ELF shared object dependency, but unlike a
14shared object, the main partition and the loadable partitions share a virtual
15address space at link time, and each loadable partition is assigned a fixed
16offset from the main partition. This allows the loadable partitions to refer
17to code and data in the main partition directly without the binary size and
18performance overhead of PLTs, GOTs or symbol table entries.
19
20Usage
21-----
22
23A program that uses the partitioning feature must decide which symbols are
24going to be used as the "entry points" for each partition. An entry point
25could, for example, be the equivalent of the partition's ``main`` function, or
26there could be a group of functions that expose the functionality implemented
27by the partition. The intent is that in order to use a loadable partition,
28the program will use ``dlopen``/``dlsym`` or similar functions to dynamically
29load the partition at its assigned address, look up an entry point by name
30and call it. Note, however, that the standard ``dlopen`` function does not
31allow specifying a load address. On Android, the ``android_dlopen_ext``
32function may be used together with the ``ANDROID_DLEXT_RESERVED_ADDRESS``
33flag to load a shared object at a specific address.
34
35Once the entry points have been decided, the translation unit(s)
36containing the entry points should be compiled using the Clang compiler flag
37``-fsymbol-partition=<soname>``, where ``<soname>`` is the intended soname
38of the partition. The resulting object files are passed to the linker in
39the usual way.
40
41The linker will then use these entry points to automatically split the program
42into partitions according to which sections of the program are reachable from
43which entry points, similarly to how ``--gc-sections`` removes unused parts of
44a program. Any sections that are only reachable from a loadable partition's
45entry point are assigned to that partition, while all other sections are
46assigned to the main partition, including sections only reachable from
47loadable partitions.
48
49The following diagram illustrates how sections are assigned to partitions. Each
50section is colored according to its assigned partition.
51
52.. image:: partitions.svg
53
54The result of linking a program that uses partitions is essentially an
55ELF file with all of the partitions concatenated together. This file is
56referred to as a combined output file. To extract a partition from the
57combined output file, the ``llvm-objcopy`` tool should be used together
58with the flag ``--extract-main-partition`` to extract the main partition, or
59``-extract-partition=<soname>`` to extract one of the loadable partitions.
60An example command sequence is shown below:
61
62.. code-block:: shell
63
64 # Compile the main program.
65 clang -ffunction-sections -fdata-sections -c main.c
66
67 # Compile a feature to be placed in a loadable partition.
68 # Note that this is likely to be a separate build step to the main partition.
69 clang -ffunction-sections -fdata-sections -fsymbol-partition=libfeature.so -c feature.c
70
71 # Link the combined output file.
72 clang main.o feature.o -fuse-ld=lld -shared -o libcombined.so -Wl,-soname,libmain.so -Wl,--gc-sections
73
74 # Extract the partitions.
75 llvm-objcopy libcombined.so libmain.so --extract-main-partition
76 llvm-objcopy libcombined.so libfeature.so --extract-partition=libfeature.so
77
78In order to allow a program to discover the names of its loadable partitions
79and the locations of their reserved regions, the linker creates a partition
80index, which is an array of structs with the following definition:
81
82.. code-block:: c
83
84 struct partition_index_entry {
85 int32_t name_offset;
86 int32_t addr_offset;
87 uint32_t size;
88 };
89
90The ``name_offset`` field is a relative pointer to a null-terminated string
91containing the soname of the partition, the ``addr_offset`` field is a
92relative pointer to its load address and the ``size`` field contains the
93size of the region reserved for the partition. To derive an absolute pointer
94from the relative pointer fields in this data structure, the address of the
95field should be added to the value stored in the field.
96
97The program may discover the location of the partition index using the
98linker-defined symbols ``__part_index_begin`` and ``__part_index_end``.
99
100Restrictions
101------------
102
103This feature is currently only supported in the ELF linker.
104
105The partitioning feature may not currently be used together with the
106``SECTIONS`` or ``PHDRS`` linker script features, nor may it be used with the
107``--section-start``, ``-Ttext``, ``-Tdata`` or ``-Tbss`` flags. All of these
108features assume a single set of output sections and/or program headers, which
109makes their semantics ambiguous in the presence of more than one partition.
110
111The partitioning feature may not currently be used on the MIPS architecture
112because it is unclear whether the MIPS multi-GOT ABI is compatible with
113partitions.
114
115The current implementation only supports creating up to 254 partitions due
116to implementation limitations. This limit may be relaxed in the future.
deps/lld/docs/ReleaseNotes.rst+50-79
......@@ -1,19 +1,22 @@
11=======================
2lld 8.0.0 Release Notes
2lld 9.0.0 Release Notes
33=======================
44
55.. contents::
66 :local:
77
8.. warning::
9 These are in-progress notes for the upcoming LLVM 9.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
11lld is a high-performance linker that supports ELF (Unix), COFF (Windows),
12Mach-O (macOS), MinGW and WebAssembly. lld is command-line-compatible with
13GNU linkers and Microsoft link.exe and is significantly faster than the
14system default linkers.
15
16lld 8.0.0 has lots of feature improvements and bug fixes.
16This document contains the release notes for the lld linker, release 9.0.0.
17Here we describe the status of lld, including major improvements
18from the previous release. All lld releases may be downloaded
19from the `LLVM releases web site <https://llvm.org/releases/>`_.
1720
1821Non-comprehensive list of changes in this release
1922=================================================
......@@ -21,101 +24,69 @@ Non-comprehensive list of changes in this release
2124ELF Improvements
2225----------------
2326
24* lld now supports RISC-V. (`r339364
25 <https://reviews.llvm.org/rL339364>`_)
26
27* Default image base address has changed from 65536 to 2 MiB for i386
28 and 4 MiB for AArch64 to make lld-generated executables work better
29 with automatic superpage promotion. FreeBSD can promote contiguous
30 non-superpages to a superpage if they are aligned to the superpage
31 size. (`r342746 <https://reviews.llvm.org/rL342746>`_)
32
33* lld now attempts to place a ``.note`` segment in the first page of a
34 generated file, so that you can find some important information
35 (``.note.gnu.build-id`` in particular) in a core file even if a core
36 file is truncated by ulimit.
37 (`r349524 <https://reviews.llvm.org/rL349524>`_)
38
39* lld now reports an error if ``_GLOBAL_OFFSET_TABLE_`` symbol is
40 defined by an input object file, as the symbol is supposed to be
41 synthesized by the linker.
42 (`r347854 <https://reviews.llvm.org/rL347854>`_)
43
44* lld/Hexagon can now link Linux kernel and musl libc for Qualcomm
45 Hexagon ISA.
46
47* Initial MSP430 ISA support has landed.
27* ld.lld now has typo suggestions for flags:
28 ``$ ld.lld --call-shared`` now prints
29 ``unknown argument '--call-shared', did you mean '--call_shared'``.
4830
49* lld now uses the ``sigrie`` instruction as a trap instruction for
50 MIPS targets.
51
52* lld now creates a TLS segment for AArch64 with a slightly larger
53 alignment requirement, so that the loader makes a few bytes room
54 before each TLS segment at runtime. The aim of this change is to
55 make room to accomodate nonstandard Android TLS slots while keeping
56 the compatibility with the standard AArch64 ABI.
57 (`r350681 <https://reviews.llvm.org/rL350681>`_)
58
59* The following flags have been added: ``--call-graph-profile``,
60 ``--no-call-graph-profile``, ``--warn-ifunc-textrel``,
61 ``-z interpose``, ``-z global``, ``-z nodefaultlib``
31* ...
6232
6333COFF Improvements
6434-----------------
6535
66* PDB GUID is set to hash of PDB contents instead to a random byte
67 sequence for build reproducibility.
36* Like the ELF driver, lld-link now has typo suggestions for flags.
37
38* lld-link now correctly reports duplicate symbol errors for obj files
39 that were compiled with /Gy.
6840
69* ``/pdbsourcepath:`` is now also used to make ``"cwd"``, ``"exe"``, ``"pdb"``
70 in the env block of PDB outputs absolute if they are relative, and to make
71 paths to obj files referenced in PDB outputs absolute if they are relative.
72 Together with the previous item, this makes it possible to generate
73 executables and PDBs that are fully deterministic and independent of the
74 absolute path to the build directory, so that different machines building
75 the same code in different directories can produce exactly the same output.
41* lld-link now correctly reports duplicate symbol errors when several res
42 input files define resources with the same type, name, and language.
43 This can be demoted to a warning using ``/force:multipleres``.
7644
77* The following flags have been added: ``/force:multiple``
45* Having more than two ``/natvis:`` now works correctly; it used to not
46 work for larger binaries before.
7847
79* lld now can link against import libraries produced by GNU tools.
48* Undefined symbols are now printed only in demangled form. Pass
49 ``/demangle:no`` to see raw symbol names instead.
8050
81* lld can create thunks for ARM and ARM64, to allow linking larger images
82 (over 16 MB for ARM and over 128 MB for ARM64)
51* The following flags have been added: ``/functionpadmin``, ``/swaprun:``,
52 ``/threads:no``
8353
8454* Several speed and memory usage improvements.
8555
86* lld now creates debug info for typedefs.
56* Range extension thunks are now created for ARM64, if needed
8757
88* lld can now link obj files produced by ``cl.exe /Z7 /Yc``.
58* lld-link now supports resource object files created by GNU windres and
59 MS cvtres, not only llvm-cvtres
8960
90* lld now understands ``%_PDB%`` and ``%_EXT%`` in ``/pdbaltpath:``.
61* The generated thunks for delayimports now share the majority of code
62 among thunks, significantly reducing the overhead of using delayimport
9163
92* Undefined symbols are now printed in demangled form in addition to raw form.
64* ...
9365
9466MinGW Improvements
9567------------------
9668
97* lld can now automatically import data variables from DLLs without the
98 use of the dllimport attribute.
69* lld now correctly links crtend.o as the last object file, handling
70 terminators for the sections such as .eh_frame properly, fixing
71 DWARF exception handling with libgcc and gcc's crtend.o.
9972
100* lld can now use existing normal MinGW sysroots with import libraries and
101 CRT startup object files for GNU binutils. lld can handle most object
102 files produced by GCC, and thus works as a drop-in replacement for
103 ld.bfd in such environments. (There are known issues with linking crtend.o
104 from GCC in setups with DWARF exceptions though, where object files are
105 linked in a different order than with GNU ld, inserting a DWARF exception
106 table terminator too early.)
73* lld now also handles DWARF unwind info generated by GCC, when linking
74 with libgcc
10775
108* lld now supports COFF embedded directives for linking to nondefault
109 libraries, just like for the normal COFF target.
76* Many more GNU ld options are now supported, which e.g. allows the lld
77 MinGW frontend to be called by GCC
78
79* PDB output can be requested without manually specifying the PDB file
80 name, with the new option ``-pdb=`` with an empty value to the option.
81 (The old existing syntax ``-pdb <filename>`` was more cumbersome to use
82 with an empty parameter value.)
83
84MachO Improvements
85------------------
11086
111* Actually generate a codeview build id signature, even if not creating a PDB.
112 Previously, the ``--build-id`` option did not actually generate a build id
113 unless ``--pdb`` was specified.
87* Item 1.
11488
11589WebAssembly Improvements
11690------------------------
11791
118* Add initial support for creating shared libraries (-shared).
119 Note: The shared library format is still under active development and may
120 undergo significant changes in future versions.
121 See: https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
92* ...
deps/lld/docs/WebAssembly.rst+65-13
......@@ -4,21 +4,17 @@ WebAssembly lld port
44The WebAssembly version of lld takes WebAssembly binaries as inputs and produces
55a WebAssembly binary as its output. For the most part it tries to mimic the
66behaviour of traditional ELF linkers and specifically the ELF lld port. Where
7possible that command line flags and the semantics should be the same.
7possible the command line flags and the semantics should be the same.
88
99
1010Object file format
1111------------------
1212
13The format the input object files that lld expects is specified as part of the
14the WebAssembly tool conventions
15https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md.
16
17This is object format that the llvm will produce when run with the
18``wasm32-unknown-unknown`` target. To build llvm with WebAssembly support
19currently requires enabling the experimental backed using
20``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``.
13The WebAssembly object file format used by LLVM and LLD is specified as part of
14the WebAssembly tool conventions on linking_.
2115
16This is the object format that the llvm will produce when run with the
17``wasm32-unknown-unknown`` target.
2218
2319Usage
2420-----
......@@ -88,10 +84,52 @@ WebAssembly-specific options:
8884By default the function table is neither imported nor exported, but defined
8985for internal use only.
9086
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.
87Behaviour
88---------
89
90In general, where possible, the WebAssembly linker attempts to emulate the
91behaviour of a traditional ELF linker, and in particular the ELF port of lld.
92For more specific details on how this is achieved see the tool conventions on
93linking_.
94
95Function Signatures
96~~~~~~~~~~~~~~~~~~~
97
98One way in which the WebAssembly linker differs from traditional native linkers
99is that function signature checking is strict in WebAssembly. It is a
100validation error for a module to contain a call site that doesn't agree with
101the target signature. Even though this is undefined behaviour in C/C++, it is not
102uncommon to find this in real-world C/C++ programs. For example, a call site in
103one compilation unit which calls a function defined in another compilation
104unit but with too many arguments.
105
106In order not to generate such invalid modules, lld has two modes of handling such
107mismatches: it can simply error-out or it can create stub functions that will
108trap at runtime (functions that contain only an ``unreachable`` instruction)
109and use these stub functions at the otherwise invalid call sites.
110
111The default behaviour is to generate these stub function and to produce
112a warning. The ``--falal-warnings`` flag can be used to disable this behaviour
113and error out if mismatched are found.
114
115Imports and Exports
116~~~~~~~~~~~~~~~~~~~
117
118When building a shared library any symbols marked as ``visibility=default`` will
119be exported. When building an executable, only the entry point and symbols
120flagged as ``WASM_SYMBOL_EXPORTED`` are exported by default. In LLVM the
121``WASM_SYMBOL_EXPORTED`` flag is applied to any symbol in the ``llvm.used`` list
122which corresponds to ``__attribute__((used))`` in C/C++ sources.
123
124In addition, symbols can be exported via the linker command line using
125``--export``.
126
127Finally, just like with native ELF linker the ``--export-dynamic`` flag can be
128used to export symbol in the executable which are marked as
129``visibility=default``.
130
131Garbage Collection
132~~~~~~~~~~~~~~~~~~
95133
96134Since WebAssembly is designed with size in mind the linker defaults to
97135``--gc-sections`` which means that all unused functions and data segments will
......@@ -103,6 +141,18 @@ The symbols which are preserved by default are:
103141- Any symbol which is to be exported.
104142- Any symbol transitively referenced by the above.
105143
144Weak Undefined Functions
145~~~~~~~~~~~~~~~~~~~~~~~~
146
147On native platforms, calls to weak undefined functions end up as calls to the
148null function pointer. With WebAssembly, direct calls must reference a defined
149function (with the correct signature). In order to handle this case the linker
150will generate function a stub containing only the ``unreachable`` instruction
151and use this for any direct references to an undefined weak function.
152
153For example a runtime call to a weak undefined function ``foo`` will up trapping
154on ``unreachable`` inside and linker-generated function called
155``undefined:foo``.
106156
107157Missing features
108158----------------
......@@ -112,3 +162,5 @@ Missing features
112162- No support for creating shared libraries. The spec for shared libraries in
113163 WebAssembly is still in flux:
114164 https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
165
166.. _linking: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.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 = '8'
51version = '9'
5252# The full version, including alpha/beta/rc tags.
53release = '8'
53release = '9'
5454
5555# The language for content autogenerated by Sphinx. Refer to documentation
5656# for a list of supported languages.
deps/lld/docs/getting_started.rst+8-27
......@@ -28,23 +28,15 @@ On Unix-like Systems
2828.. _libc++: http://libcxx.llvm.org/
2929.. _Python 2.4: http://python.org/download/
3030
312. Check out LLVM::
312. Check out LLVM and subprojects (including lld)::
3232
33 $ cd path/to/llvm-project
34 $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
35
363. Check out lld::
37
38 $ cd llvm/tools
39 $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld
40
41 * lld can also be checked out to ``path/to/llvm-project`` and built as an external
42 project.
33 $ git clone https://github.com/llvm/llvm-project.git
4334
44354. Build LLVM and lld::
4536
46 $ cd path/to/llvm-build/llvm (out of source build required)
47 $ cmake -G "Unix Makefiles" path/to/llvm-project/llvm
37 $ cd llvm-project
38 $ mkdir build && cd build
39 $ cmake -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS=lld ../llvm
4840 $ make
4941
5042 * If you want to build with clang and it is not the default compiler or
......@@ -71,23 +63,12 @@ Using Visual Studio
7163.. _Visual Studio 12 (2013) or later: http://www.microsoft.com/visualstudio/11/en-us
7264.. _Python 2.4: http://python.org/download/
7365
74#. Check out LLVM::
75
76 $ cd path/to/llvm-project
77 $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
78
79#. Check out lld::
80
81 $ cd llvm/tools
82 $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld
83
84 * lld can also be checked out to ``path/to/llvm-project`` and built as an external
85 project.
66#. Check out LLVM as above.
8667
8768#. Generate Visual Studio project files::
8869
89 $ cd path/to/llvm-build/llvm (out of source build required)
90 $ cmake -G "Visual Studio 11" path/to/llvm-project/llvm
70 $ cd llvm-project/build (out of source build required)
71 $ cmake -G "Visual Studio 11" -DLLVM_ENABLE_PROJECTS=lld ../llvm
9172
9273#. Build
9374
deps/lld/docs/index.rst+2-1
......@@ -106,7 +106,7 @@ build that tree. You need `cmake` and of course a C++ compiler.
106106
107107.. code-block:: console
108108
109 $ git clone https://github.com/llvm-project/llvm-project-20170507 llvm-project
109 $ git clone https://github.com/llvm/llvm-project llvm-project
110110 $ mkdir build
111111 $ cd build
112112 $ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=lld -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-project/llvm
......@@ -174,4 +174,5 @@ document soon.
174174 WebAssembly
175175 windows_support
176176 missingkeyfunction
177 Partitions
177178 ReleaseNotes
deps/lld/docs/ld.lld.1+109-8
......@@ -1,9 +1,10 @@
1.\" This file is distributed under the University of Illinois Open Source
2.\" License. See LICENSE.TXT for details.
1.\" Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2.\" See https://llvm.org/LICENSE.txt for license information.
3.\" SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
34.\"
45.\" This man page documents only lld's ELF linking support, obtained originally
56.\" from FreeBSD.
6.Dd September 26, 2018
7.Dd May 12, 2019
78.Dt LD.LLD 1
89.Os
910.Sh NAME
......@@ -45,6 +46,9 @@ as a native linker as well as a cross linker.
4546.It Fl -allow-multiple-definition
4647Do not error if a symbol is defined multiple times.
4748The first definition will be used.
49.It Fl -allow-shlib-undefined
50Allow unresolved references in shared libraries.
51This option is enabled by default when linking a shared library.
4852.It Fl -apply-dynamic-relocs
4953Apply link-time values for dynamic relocations.
5054.It Fl -as-needed
......@@ -178,6 +182,8 @@ Set the
178182field to the specified value.
179183.It Fl -fini Ns = Ns Ar symbol
180184Specify a finalizer function.
185.It Fl -force-bti
186Force enable AArch64 BTI instruction in PLT, warn if Input ELF file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property.
181187.It Fl -format Ns = Ns Ar input-format , Fl b Ar input-format
182188Specify the format of the inputs following this option.
183189.Ar input-format
......@@ -213,6 +219,15 @@ Enable identical code folding.
213219Enable safe identical code folding.
214220.It Fl -icf Ns = Ns Cm none
215221Disable identical code folding.
222.It Fl -ignore-data-address-equality
223Ignore address equality of data. C/C++ requires each data to have a unique
224address. This option allows lld to do unsafe optimization that breaks the
225requirement: create copies of read-only data or merge two or more read-only data
226that happen to have the same value.
227.It Fl -ignore-function-address-equality
228Ignore address equality of functions. This option allows non-PIC calls to a
229function with non-default visibility in a shared object. The function may have
230different addresses within the executable and within the shared object.
216231.It Fl -image-base Ns = Ns Ar value
217232Set the base address to
218233.Ar value .
......@@ -241,6 +256,11 @@ Set target emulation.
241256.It Fl -Map Ns = Ns Ar file , Fl M Ar file
242257Print a link map to
243258.Ar file .
259.It Fl -nmagic , Fl n
260Do not page align sections, link against static libraries.
261.It Fl -no-allow-shlib-undefined
262Do not allow unresolved references in shared libraries.
263This option is enabled by default when linking an executable.
244264.It Fl -no-as-needed
245265Always set
246266.Dv DT_NEEDED
......@@ -259,6 +279,12 @@ section.
259279Disable garbage collection of unused sections.
260280.It Fl -no-gnu-unique
261281Disable STB_GNU_UNIQUE symbol binding.
282.It Fl -no-merge-exidx-entries
283Disable merging .ARM.exidx entries.
284.It Fl -no-nmagic
285Page align sections.
286.It Fl -no-omagic
287Do not set the text data sections to be writable, page align sections.
262288.It Fl -no-rosegment
263289Do not put read-only non-executable sections in their own segment.
264290.It Fl -no-threads
......@@ -267,9 +293,11 @@ Do not run the linker multi-threaded.
267293Report version scripts that refer undefined symbols.
268294.It Fl -no-undefined
269295Report unresolved symbols even if the linker is creating a shared library.
296.It Fl -no-warn-symbol-ordering
297Do not warn about problems with the symbol ordering file or call graph profile.
270298.It Fl -no-whole-archive
271299Restores the default behavior of loading archive members.
272.It Fl -no-pie
300.It Fl -no-pie , Fl -no-pic-executable
273301Do not create a position independent executable.
274302.It Fl -noinhibit-exec
275303Retain the executable output file whenever it is still usable.
......@@ -305,15 +333,62 @@ is
305333.Cm binary ,
306334which produces output with no ELF header.
307335.It Fl -omagic , Fl N
308Set the text and data sections to be readable and writable.
336Set the text and data sections to be readable and writable, do not page align sections, link against static libraries.
309337.It Fl -opt-remarks-filename Ar file
310338Write optimization remarks in YAML format to
311339.Ar file .
340.It Fl -opt-remarks-passes Ar pass-regex
341Filter optimization remarks by only allowing the passes matching
342.Ar pass-regex .
312343.It Fl -opt-remarks-with-hotness
313344Include hotness information in the optimization remarks file.
345.It Fl -orphan-handling Ns = Ns Ar mode
346Control how orphan sections are handled. An orphan section is one not
347specifically mentioned in a linker script.
348.Ar mode
349may be:
350.Pp
351.Bl -tag -width 2n -compact
352.It Cm place
353Place orphan sections in suitable output sections.
354.It Cm warn
355Place orphan sections as for
356.Cm place
357and also report a warning.
358.It Cm error
359Place orphan sections as for
360.Cm place
361and also report an error.
362.El
363.Pp
364.Cm place
365is the default.
366.It Fl -pack-dyn-relocs Ns = Ns Ar format
367Pack dynamic relocations in the given format.
368.Ar format
369may be:
370.Pp
371.Bl -tag -width 2n -compact
372.It Cm none
373Don't pack. Dynamic relocations are encoded in SHT_REL(A).
374.It Cm android
375Pack dynamic relocations in SHT_ANDROID_REL(A).
376.It Cm relr
377Pack relative relocations in SHT_RELR, and the rest of dynamic relocations in SHT_REL(A).
378.It Cm android+relr
379Pack relative relocations in SHT_RELR, and the rest of dynamic relocations in SHT_ANDROID_REL(A).
380.El
381.Pp
382.Cm none
383is the default. If
384.Fl -use-android-relr-tags
385is specified, use SHT_ANDROID_RELR instead of SHT_RELR.
386.Pp
387.It Fl -pac-plt
388AArch64 only, use pointer authentication in PLT.
314389.It Fl -pic-veneer
315390Always generate position independent thunks.
316.It Fl -pie
391.It Fl -pie , Fl -pic-executable
317392Create a position independent executable.
318393.It Fl -print-gc-sections
319394List removed unused sections.
......@@ -358,6 +433,8 @@ Set
358433.Dv DT_SONAME
359434to
360435.Ar value .
436.It Fl -sort-common
437This option is ignored for GNU compatibility.
361438.It Fl -sort-section Ns = Ns Ar value
362439Specifies sections sorting rule when linkerscript is used.
363440.It Fl -start-lib
......@@ -427,11 +504,27 @@ Print the names of the input files.
427504Trace references to
428505.Ar symbol .
429506.It Fl -undefined Ns = Ns Ar symbol , Fl u Ar symbol
430Force
507If
431508.Ar symbol
432to be an undefined symbol during linking.
509is not defined after symbol resolution, and there's a static library
510that contains an object file defining the symbol, load the member
511to include the object file in the output file.
512.It Fl -undefined-glob Ns = Ns Ar pattern
513Synonym for
514.Fl -undefined ,
515except that it takes a glob pattern. In a glob pattern,
516.Cm *
517matches zero or more characters,
518.Cm ?
519matches any single character, and
520.Cm [...]
521matches the characters within brackets. All symbols that match
522a given pattern are handled as if they were given as arguments of
523.Fl -undefined .
433524.It Fl -unresolved-symbols Ns = Ns Ar value
434525Determine how to handle unresolved symbols.
526.It Fl -use-android-relr-tags
527Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*.
435528.It Fl v
436529Display the version number and proceed with linking if object files are
437530specified.
......@@ -479,6 +572,14 @@ Sets the
479572.Dv DYNAMIC
480573section.
481574Different loaders can decide how to handle this flag on their own.
575.It Cm ifunc-noplt
576Do not emit PLT entries for ifunc symbols.
577Instead, emit text relocations referencing the resolver.
578This is an experimental optimization and only suitable for standalone
579environments where text relocations do not have the usual drawbacks.
580This option must be combined with the
581.Fl z Li notext
582option.
482583.It Cm initfirst
483584Sets the
484585.Dv DF_1_INITFIRST
deps/lld/docs/missingkeyfunction.rst+16-15
......@@ -4,23 +4,24 @@ Missing Key Function
44If your build failed with a linker error something like this::
55
66 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)
7 the vtable symbol may be undefined because the class is missing its key function
8 (see https://lld.llvm.org/missingkeyfunction)
89
910it'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.
11non-pure, non-inline, virtual function), but you haven't actually defined it.
1112
1213When a class has a key function, the compiler emits the vtable (and some other
1314things as well) only in the translation unit that defines that key function. Thus,
1415if 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
16function calls your missing function, you won't see any undefined reference errors
1617for it, but you will see undefined references to the vtable symbol.
1718
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
19When a class has no non-pure, non-inline, virtual functions, there is no key
20function, and the compiler is forced to emit the vtable in every translation unit
2021that references the class. In this case, it is emitted in a COMDAT section,
2122which allows the linker to eliminate all duplicate copies. This is still
2223wasteful 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.
24ensure there is at least one eligible function that can serve as the key function.
2425
2526Here are the most common mistakes that lead to this error:
2627
......@@ -36,8 +37,8 @@ Say you have a base class declared in a header file::
3637 ...
3738 };
3839
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
40Here, ``~B`` is the first non-pure, non-inline, virtual function, so it is the key
41function. If you forget to define ``B::~B`` in your source file, the compiler will
4142not emit the vtable for ``B``, and you'll get an undefined reference to "vtable
4243for B".
4344
......@@ -47,10 +48,10 @@ the first eligible key function and it's easy to forget to implement them. It's
4748also more likely that you won't have any direct references to the destructor, so
4849you won't see any undefined reference errors that point directly to the problem.
4950
50The solution in this case is to implement the missing method.
51The solution in this case is to implement the missing function.
5152
52Forgetting to declare a virtual method in an abstract class as pure
53-------------------------------------------------------------------
53Forgetting to declare a virtual function in an abstract class as pure
54---------------------------------------------------------------------
5455
5556Say you have an abstract base class declared in a header file::
5657
......@@ -65,18 +66,18 @@ Say you have an abstract base class declared in a header file::
6566 };
6667
6768This 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,
69functions pure. Here, ``A::bar``, being non-pure, is nominated as the key function,
6970and as a result, the vtable for ``A`` is not emitted, because the compiler is
7071waiting for a translation unit that defines ``A::bar``.
7172
7273The solution in this case is to add the missing ``= 0`` to the declaration of
7374``A::bar``.
7475
75Key method is defined, but the linker doesn't see it
76----------------------------------------------------
76Key function is defined, but the linker doesn't see it
77------------------------------------------------------
7778
7879It'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
80object file containing the definition of that function isn't being linked into
8081your application.
8182
8283The solution in this case is to check your dependencies to make sure that
deps/lld/docs/partitions.dot created+22
......@@ -0,0 +1,22 @@
1digraph G {
2 part_main [label="Main partition",shape=plaintext];
3 part1 [label="Loadable partition 1",shape=plaintext];
4 part2 [label="Loadable partition 2",shape=plaintext];
5 main [style=filled,fillcolor=lightblue];
6 f1 [style=filled,fillcolor=lightsalmon];
7 f2 [style=filled,fillcolor=palegreen];
8 f3 [style=filled,fillcolor=lightblue];
9 f4 [style=filled,fillcolor=lightsalmon];
10 f5 [style=filled,fillcolor=lightblue];
11 f6 [style=filled,fillcolor=palegreen];
12 part_main -> main;
13 main -> f3;
14 part1 -> f1;
15 f1 -> f3;
16 f1 -> f4;
17 f1 -> f5;
18 part2 -> f2;
19 f2 -> f3;
20 f2 -> f5;
21 f2 -> f6;
22}
deps/lld/docs/partitions.svg created+110
......@@ -0,0 +1,110 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4<!-- Generated by graphviz version 2.38.0 (20140413.2041)
5 -->
6<!-- Title: G Pages: 1 -->
7<svg width="393pt" height="188pt"
8 viewBox="0.00 0.00 393.00 188.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184)">
10<title>G</title>
11<polygon fill="white" stroke="none" points="-4,4 -4,-184 389,-184 389,4 -4,4"/>
12<!-- part_main -->
13<g id="node1" class="node"><title>part_main</title>
14<text text-anchor="middle" x="47.5" y="-158.3" font-family="Times,serif" font-size="14.00">Main partition</text>
15</g>
16<!-- main -->
17<g id="node4" class="node"><title>main</title>
18<ellipse fill="lightblue" stroke="black" cx="75.5" cy="-90" rx="28.6953" ry="18"/>
19<text text-anchor="middle" x="75.5" y="-86.3" font-family="Times,serif" font-size="14.00">main</text>
20</g>
21<!-- part_main&#45;&gt;main -->
22<g id="edge1" class="edge"><title>part_main&#45;&gt;main</title>
23<path fill="none" stroke="black" d="M54.4214,-143.697C57.6218,-135.696 61.492,-126.02 65.0381,-117.155"/>
24<polygon fill="black" stroke="black" points="68.3868,-118.207 68.8511,-107.622 61.8874,-115.607 68.3868,-118.207"/>
25</g>
26<!-- part1 -->
27<g id="node2" class="node"><title>part1</title>
28<text text-anchor="middle" x="176.5" y="-158.3" font-family="Times,serif" font-size="14.00">Loadable partition 1</text>
29</g>
30<!-- f1 -->
31<g id="node5" class="node"><title>f1</title>
32<ellipse fill="lightsalmon" stroke="black" cx="176.5" cy="-90" rx="27" ry="18"/>
33<text text-anchor="middle" x="176.5" y="-86.3" font-family="Times,serif" font-size="14.00">f1</text>
34</g>
35<!-- part1&#45;&gt;f1 -->
36<g id="edge3" class="edge"><title>part1&#45;&gt;f1</title>
37<path fill="none" stroke="black" d="M176.5,-143.697C176.5,-135.983 176.5,-126.712 176.5,-118.112"/>
38<polygon fill="black" stroke="black" points="180,-118.104 176.5,-108.104 173,-118.104 180,-118.104"/>
39</g>
40<!-- part2 -->
41<g id="node3" class="node"><title>part2</title>
42<text text-anchor="middle" x="321.5" y="-158.3" font-family="Times,serif" font-size="14.00">Loadable partition 2</text>
43</g>
44<!-- f2 -->
45<g id="node6" class="node"><title>f2</title>
46<ellipse fill="palegreen" stroke="black" cx="284.5" cy="-90" rx="27" ry="18"/>
47<text text-anchor="middle" x="284.5" y="-86.3" font-family="Times,serif" font-size="14.00">f2</text>
48</g>
49<!-- part2&#45;&gt;f2 -->
50<g id="edge7" class="edge"><title>part2&#45;&gt;f2</title>
51<path fill="none" stroke="black" d="M312.354,-143.697C307.97,-135.403 302.636,-125.311 297.813,-116.187"/>
52<polygon fill="black" stroke="black" points="300.801,-114.35 293.034,-107.145 294.612,-117.621 300.801,-114.35"/>
53</g>
54<!-- f3 -->
55<g id="node7" class="node"><title>f3</title>
56<ellipse fill="lightblue" stroke="black" cx="104.5" cy="-18" rx="27" ry="18"/>
57<text text-anchor="middle" x="104.5" y="-14.3" font-family="Times,serif" font-size="14.00">f3</text>
58</g>
59<!-- main&#45;&gt;f3 -->
60<g id="edge2" class="edge"><title>main&#45;&gt;f3</title>
61<path fill="none" stroke="black" d="M82.3726,-72.411C85.7675,-64.2164 89.9422,-54.1395 93.7473,-44.9548"/>
62<polygon fill="black" stroke="black" points="97.0828,-46.0481 97.6767,-35.4699 90.6158,-43.3689 97.0828,-46.0481"/>
63</g>
64<!-- f1&#45;&gt;f3 -->
65<g id="edge4" class="edge"><title>f1&#45;&gt;f3</title>
66<path fill="none" stroke="black" d="M161.93,-74.8345C151.75,-64.9376 137.976,-51.5462 126.469,-40.3591"/>
67<polygon fill="black" stroke="black" points="128.905,-37.8461 119.296,-33.3847 124.026,-42.865 128.905,-37.8461"/>
68</g>
69<!-- f4 -->
70<g id="node8" class="node"><title>f4</title>
71<ellipse fill="lightsalmon" stroke="black" cx="176.5" cy="-18" rx="27" ry="18"/>
72<text text-anchor="middle" x="176.5" y="-14.3" font-family="Times,serif" font-size="14.00">f4</text>
73</g>
74<!-- f1&#45;&gt;f4 -->
75<g id="edge5" class="edge"><title>f1&#45;&gt;f4</title>
76<path fill="none" stroke="black" d="M176.5,-71.6966C176.5,-63.9827 176.5,-54.7125 176.5,-46.1124"/>
77<polygon fill="black" stroke="black" points="180,-46.1043 176.5,-36.1043 173,-46.1044 180,-46.1043"/>
78</g>
79<!-- f5 -->
80<g id="node9" class="node"><title>f5</title>
81<ellipse fill="lightblue" stroke="black" cx="248.5" cy="-18" rx="27" ry="18"/>
82<text text-anchor="middle" x="248.5" y="-14.3" font-family="Times,serif" font-size="14.00">f5</text>
83</g>
84<!-- f1&#45;&gt;f5 -->
85<g id="edge6" class="edge"><title>f1&#45;&gt;f5</title>
86<path fill="none" stroke="black" d="M191.07,-74.8345C201.25,-64.9376 215.024,-51.5462 226.531,-40.3591"/>
87<polygon fill="black" stroke="black" points="228.974,-42.865 233.704,-33.3847 224.095,-37.8461 228.974,-42.865"/>
88</g>
89<!-- f2&#45;&gt;f3 -->
90<g id="edge8" class="edge"><title>f2&#45;&gt;f3</title>
91<path fill="none" stroke="black" d="M260.806,-81.0022C232.063,-71.1346 182.266,-53.5073 140.5,-36 138.683,-35.2385 136.825,-34.4358 134.957,-33.6106"/>
92<polygon fill="black" stroke="black" points="136.231,-30.3452 125.68,-29.3829 133.328,-36.7149 136.231,-30.3452"/>
93</g>
94<!-- f2&#45;&gt;f5 -->
95<g id="edge9" class="edge"><title>f2&#45;&gt;f5</title>
96<path fill="none" stroke="black" d="M276.15,-72.7646C271.788,-64.2831 266.353,-53.7144 261.459,-44.1974"/>
97<polygon fill="black" stroke="black" points="264.49,-42.4395 256.804,-35.1473 258.265,-45.6409 264.49,-42.4395"/>
98</g>
99<!-- f6 -->
100<g id="node10" class="node"><title>f6</title>
101<ellipse fill="palegreen" stroke="black" cx="320.5" cy="-18" rx="27" ry="18"/>
102<text text-anchor="middle" x="320.5" y="-14.3" font-family="Times,serif" font-size="14.00">f6</text>
103</g>
104<!-- f2&#45;&gt;f6 -->
105<g id="edge10" class="edge"><title>f2&#45;&gt;f6</title>
106<path fill="none" stroke="black" d="M292.85,-72.7646C297.212,-64.2831 302.647,-53.7144 307.541,-44.1974"/>
107<polygon fill="black" stroke="black" points="310.735,-45.6409 312.196,-35.1473 304.51,-42.4395 310.735,-45.6409"/>
108</g>
109</g>
110</svg>
deps/lld/docs/sphinx_intro.rst+2-2
......@@ -43,8 +43,8 @@ to install it using:
4343 Use your distribution's standard package management tool to install it,
4444 i.e., ``apt-get install easy_install`` or ``yum install easy_install``.
4545
46 Mac OS X
47 All modern Mac OS X systems come with ``easy_install`` as part of the base
46 macOS
47 All modern macOS systems come with ``easy_install`` as part of the base
4848 system.
4949
5050 Windows
deps/lld/include/lld/Common/Args.h+14-9
......@@ -1,9 +1,8 @@
11//===- Args.h ---------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -11,6 +10,7 @@
1110#define LLD_ARGS_H
1211
1312#include "lld/Common/LLVM.h"
13#include "llvm/Support/CodeGen.h"
1414#include "llvm/Support/MemoryBuffer.h"
1515#include <vector>
1616
......@@ -22,15 +22,20 @@ class InputArgList;
2222
2323namespace lld {
2424namespace args {
25int getInteger(llvm::opt::InputArgList &Args, unsigned Key, int Default);
26std::vector<StringRef> getStrings(llvm::opt::InputArgList &Args, int Id);
2725
28uint64_t getZOptionValue(llvm::opt::InputArgList &Args, int Id, StringRef Key,
26llvm::CodeGenOpt::Level getCGOptLevel(int optLevelLTO);
27
28int64_t getInteger(llvm::opt::InputArgList &args, unsigned key,
29 int64_t Default);
30
31std::vector<StringRef> getStrings(llvm::opt::InputArgList &args, int id);
32
33uint64_t getZOptionValue(llvm::opt::InputArgList &args, int id, StringRef key,
2934 uint64_t Default);
3035
31std::vector<StringRef> getLines(MemoryBufferRef MB);
36std::vector<StringRef> getLines(MemoryBufferRef mb);
3237
33StringRef getFilenameWithoutExe(StringRef Path);
38StringRef getFilenameWithoutExe(StringRef path);
3439
3540} // namespace args
3641} // namespace lld
deps/lld/include/lld/Common/Driver.h+13-14
......@@ -1,9 +1,8 @@
11//===- lld/Common/Driver.h - Linker Driver Emulator -----------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -15,28 +14,28 @@
1514
1615namespace lld {
1716namespace coff {
18bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
19 llvm::raw_ostream &Diag = llvm::errs());
17bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
18 llvm::raw_ostream &diag = llvm::errs());
2019}
2120
2221namespace mingw {
23bool link(llvm::ArrayRef<const char *> Args,
24 llvm::raw_ostream &Diag = llvm::errs());
22bool link(llvm::ArrayRef<const char *> args,
23 llvm::raw_ostream &diag = llvm::errs());
2524}
2625
2726namespace elf {
28bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
29 llvm::raw_ostream &Diag = llvm::errs());
27bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
28 llvm::raw_ostream &diag = llvm::errs());
3029}
3130
3231namespace mach_o {
33bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
34 llvm::raw_ostream &Diag = llvm::errs());
32bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
33 llvm::raw_ostream &diag = llvm::errs());
3534}
3635
3736namespace wasm {
38bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
39 llvm::raw_ostream &Diag = llvm::errs());
37bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
38 llvm::raw_ostream &diag = llvm::errs());
4039}
4140}
4241
deps/lld/include/lld/Common/ErrorHandler.h+49-49
......@@ -1,9 +1,8 @@
11//===- ErrorHandler.h -------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -83,74 +82,75 @@ namespace lld {
8382
8483class ErrorHandler {
8584public:
86 uint64_t ErrorCount = 0;
87 uint64_t ErrorLimit = 20;
88 StringRef ErrorLimitExceededMsg = "too many errors emitted, stopping now";
89 StringRef LogName = "lld";
90 llvm::raw_ostream *ErrorOS = &llvm::errs();
91 bool ColorDiagnostics = llvm::errs().has_colors();
92 bool ExitEarly = true;
93 bool FatalWarnings = false;
94 bool Verbose = false;
95
96 void error(const Twine &Msg);
97 LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
98 void log(const Twine &Msg);
99 void message(const Twine &Msg);
100 void warn(const Twine &Msg);
101
102 std::unique_ptr<llvm::FileOutputBuffer> OutputBuffer;
85 uint64_t errorCount = 0;
86 uint64_t errorLimit = 20;
87 StringRef errorLimitExceededMsg = "too many errors emitted, stopping now";
88 StringRef logName = "lld";
89 llvm::raw_ostream *errorOS = &llvm::errs();
90 bool colorDiagnostics = llvm::errs().has_colors();
91 bool exitEarly = true;
92 bool fatalWarnings = false;
93 bool verbose = false;
94 bool vsDiagnostics = false;
95
96 void error(const Twine &msg);
97 LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg);
98 void log(const Twine &msg);
99 void message(const Twine &msg);
100 void warn(const Twine &msg);
101
102 std::unique_ptr<llvm::FileOutputBuffer> outputBuffer;
103103
104104private:
105 void print(StringRef S, raw_ostream::Colors C);
105 void printHeader(StringRef s, raw_ostream::Colors c, const Twine &msg);
106106};
107107
108108/// Returns the default error handler.
109109ErrorHandler &errorHandler();
110110
111inline void error(const Twine &Msg) { errorHandler().error(Msg); }
112inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) {
113 errorHandler().fatal(Msg);
111inline void error(const Twine &msg) { errorHandler().error(msg); }
112inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg) {
113 errorHandler().fatal(msg);
114114}
115inline void log(const Twine &Msg) { errorHandler().log(Msg); }
116inline void message(const Twine &Msg) { errorHandler().message(Msg); }
117inline void warn(const Twine &Msg) { errorHandler().warn(Msg); }
118inline uint64_t errorCount() { return errorHandler().ErrorCount; }
115inline void log(const Twine &msg) { errorHandler().log(msg); }
116inline void message(const Twine &msg) { errorHandler().message(msg); }
117inline void warn(const Twine &msg) { errorHandler().warn(msg); }
118inline uint64_t errorCount() { return errorHandler().errorCount; }
119119
120LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
120LLVM_ATTRIBUTE_NORETURN void exitLld(int val);
121121
122void diagnosticHandler(const llvm::DiagnosticInfo &DI);
123void checkError(Error E);
122void diagnosticHandler(const llvm::DiagnosticInfo &di);
123void checkError(Error e);
124124
125125// check functions are convenient functions to strip errors
126126// from error-or-value objects.
127template <class T> T check(ErrorOr<T> E) {
128 if (auto EC = E.getError())
129 fatal(EC.message());
130 return std::move(*E);
127template <class T> T check(ErrorOr<T> e) {
128 if (auto ec = e.getError())
129 fatal(ec.message());
130 return std::move(*e);
131131}
132132
133template <class T> T check(Expected<T> E) {
134 if (!E)
135 fatal(llvm::toString(E.takeError()));
136 return std::move(*E);
133template <class T> T check(Expected<T> e) {
134 if (!e)
135 fatal(llvm::toString(e.takeError()));
136 return std::move(*e);
137137}
138138
139139template <class T>
140T check2(ErrorOr<T> E, llvm::function_ref<std::string()> Prefix) {
141 if (auto EC = E.getError())
142 fatal(Prefix() + ": " + EC.message());
143 return std::move(*E);
140T check2(ErrorOr<T> e, llvm::function_ref<std::string()> prefix) {
141 if (auto ec = e.getError())
142 fatal(prefix() + ": " + ec.message());
143 return std::move(*e);
144144}
145145
146146template <class T>
147T check2(Expected<T> E, llvm::function_ref<std::string()> Prefix) {
148 if (!E)
149 fatal(Prefix() + ": " + toString(E.takeError()));
150 return std::move(*E);
147T check2(Expected<T> e, llvm::function_ref<std::string()> prefix) {
148 if (!e)
149 fatal(prefix() + ": " + toString(e.takeError()));
150 return std::move(*e);
151151}
152152
153inline std::string toString(const Twine &S) { return S.str(); }
153inline std::string toString(const Twine &s) { return s.str(); }
154154
155155// To evaluate the second argument lazily, we use C macro.
156156#define CHECK(E, S) check2((E), [&] { return toString(S); })
deps/lld/include/lld/Common/Filesystem.h created+20
......@@ -0,0 +1,20 @@
1//===- Filesystem.h ---------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLD_FILESYSTEM_H
10#define LLD_FILESYSTEM_H
11
12#include "lld/Common/LLVM.h"
13#include <system_error>
14
15namespace lld {
16void unlinkAsync(StringRef path);
17std::error_code tryCreateFile(StringRef path);
18} // namespace lld
19
20#endif
deps/lld/include/lld/Common/LLVM.h+5-4
......@@ -1,9 +1,8 @@
11//===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -30,6 +29,7 @@ class Twine;
3029class MemoryBuffer;
3130class MemoryBufferRef;
3231template <typename T> class ArrayRef;
32template <typename T> class MutableArrayRef;
3333template <unsigned InternalLen> class SmallString;
3434template <typename T, unsigned N> class SmallVector;
3535template <typename T> class ErrorOr;
......@@ -63,6 +63,7 @@ using llvm::isa;
6363
6464// ADT's.
6565using llvm::ArrayRef;
66using llvm::MutableArrayRef;
6667using llvm::Error;
6768using llvm::ErrorOr;
6869using llvm::Expected;
deps/lld/include/lld/Common/Memory.h+12-13
......@@ -1,9 +1,8 @@
11//===- Memory.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -29,30 +28,30 @@
2928namespace lld {
3029
3130// Use this arena if your object doesn't have a destructor.
32extern llvm::BumpPtrAllocator BAlloc;
33extern llvm::StringSaver Saver;
31extern llvm::BumpPtrAllocator bAlloc;
32extern llvm::StringSaver saver;
3433
3534void freeArena();
3635
3736// These two classes are hack to keep track of all
3837// SpecificBumpPtrAllocator instances.
3938struct SpecificAllocBase {
40 SpecificAllocBase() { Instances.push_back(this); }
39 SpecificAllocBase() { instances.push_back(this); }
4140 virtual ~SpecificAllocBase() = default;
4241 virtual void reset() = 0;
43 static std::vector<SpecificAllocBase *> Instances;
42 static std::vector<SpecificAllocBase *> instances;
4443};
4544
4645template <class T> struct SpecificAlloc : public SpecificAllocBase {
47 void reset() override { Alloc.DestroyAll(); }
48 llvm::SpecificBumpPtrAllocator<T> Alloc;
46 void reset() override { alloc.DestroyAll(); }
47 llvm::SpecificBumpPtrAllocator<T> alloc;
4948};
5049
5150// Use this arena if your object has a destructor.
5251// Your destructor will be invoked from freeArena().
53template <typename T, typename... U> T *make(U &&... Args) {
54 static SpecificAlloc<T> Alloc;
55 return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...);
52template <typename T, typename... U> T *make(U &&... args) {
53 static SpecificAlloc<T> alloc;
54 return new (alloc.alloc.Allocate()) T(std::forward<U>(args)...);
5655}
5756
5857} // namespace lld
deps/lld/include/lld/Common/Reproduce.h+6-11
......@@ -1,9 +1,8 @@
11//===- Reproduce.h - Utilities for creating reproducers ---------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -23,17 +22,13 @@ namespace lld {
2322// Makes a given pathname an absolute path first, and then remove
2423// beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
2524// assuming that the current directory is "/home/john/bar".
26std::string relativeToRoot(StringRef Path);
25std::string relativeToRoot(StringRef path);
2726
2827// Quote a given string if it contains a space character.
29std::string quote(StringRef S);
30
31// Rewrite the given path if a file exists with that pathname, otherwise
32// returns the original path.
33std::string rewritePath(StringRef S);
28std::string quote(StringRef s);
3429
3530// Returns the string form of the given argument.
36std::string toString(const llvm::opt::Arg &Arg);
31std::string toString(const llvm::opt::Arg &arg);
3732}
3833
3934#endif
deps/lld/include/lld/Common/Strings.h+11-12
......@@ -1,9 +1,8 @@
11//===- Strings.h ------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -20,25 +19,25 @@
2019namespace lld {
2120// Returns a demangled C++ symbol name. If Name is not a mangled
2221// name, it returns Optional::None.
23llvm::Optional<std::string> demangleItanium(llvm::StringRef Name);
24llvm::Optional<std::string> demangleMSVC(llvm::StringRef S);
22llvm::Optional<std::string> demangleItanium(llvm::StringRef name);
23llvm::Optional<std::string> demangleMSVC(llvm::StringRef s);
2524
26std::vector<uint8_t> parseHex(llvm::StringRef S);
27bool isValidCIdentifier(llvm::StringRef S);
25std::vector<uint8_t> parseHex(llvm::StringRef s);
26bool isValidCIdentifier(llvm::StringRef s);
2827
2928// Write the contents of the a buffer to a file
30void saveBuffer(llvm::StringRef Buffer, const llvm::Twine &Path);
29void saveBuffer(llvm::StringRef buffer, const llvm::Twine &path);
3130
3231// This class represents multiple glob patterns.
3332class StringMatcher {
3433public:
3534 StringMatcher() = default;
36 explicit StringMatcher(llvm::ArrayRef<llvm::StringRef> Pat);
35 explicit StringMatcher(llvm::ArrayRef<llvm::StringRef> pat);
3736
38 bool match(llvm::StringRef S) const;
37 bool match(llvm::StringRef s) const;
3938
4039private:
41 std::vector<llvm::GlobPattern> Patterns;
40 std::vector<llvm::GlobPattern> patterns;
4241};
4342
4443} // namespace lld
deps/lld/include/lld/Common/TargetOptionsCommandFlags.h+7-8
......@@ -1,9 +1,8 @@
11//===-- TargetOptionsCommandFlags.h ----------------------------*- C++ -*-===//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -16,8 +15,8 @@
1615#include "llvm/Target/TargetOptions.h"
1716
1817namespace lld {
19llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();
20llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel();
21std::string GetCPUStr();
22std::vector<std::string> GetMAttrs();
18llvm::TargetOptions initTargetOptionsFromCodeGenFlags();
19llvm::Optional<llvm::CodeModel::Model> getCodeModelFromCMModel();
20std::string getCPUStr();
21std::vector<std::string> getMAttrs();
2322}
deps/lld/include/lld/Common/Threads.h+20-14
......@@ -1,9 +1,8 @@
11//===- Threads.h ------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -64,21 +63,28 @@
6463
6564namespace lld {
6665
67extern bool ThreadsEnabled;
66extern bool threadsEnabled;
67
68template <typename R, class FuncTy> void parallelForEach(R &&range, FuncTy fn) {
69 if (threadsEnabled)
70 for_each(llvm::parallel::par, std::begin(range), std::end(range), fn);
71 else
72 for_each(llvm::parallel::seq, std::begin(range), std::end(range), fn);
73}
6874
69template <typename R, class FuncTy> void parallelForEach(R &&Range, FuncTy Fn) {
70 if (ThreadsEnabled)
71 for_each(llvm::parallel::par, std::begin(Range), std::end(Range), Fn);
75inline void parallelForEachN(size_t begin, size_t end,
76 llvm::function_ref<void(size_t)> fn) {
77 if (threadsEnabled)
78 for_each_n(llvm::parallel::par, begin, end, fn);
7279 else
73 for_each(llvm::parallel::seq, std::begin(Range), std::end(Range), Fn);
80 for_each_n(llvm::parallel::seq, begin, end, fn);
7481}
7582
76inline void parallelForEachN(size_t Begin, size_t End,
77 llvm::function_ref<void(size_t)> Fn) {
78 if (ThreadsEnabled)
79 for_each_n(llvm::parallel::par, Begin, End, Fn);
83template <typename R, class FuncTy> void parallelSort(R &&range, FuncTy fn) {
84 if (threadsEnabled)
85 sort(llvm::parallel::par, std::begin(range), std::end(range), fn);
8086 else
81 for_each_n(llvm::parallel::seq, Begin, End, Fn);
87 sort(llvm::parallel::seq, std::begin(range), std::end(range), fn);
8288}
8389
8490} // namespace lld
deps/lld/include/lld/Common/Timer.h+14-15
......@@ -1,9 +1,8 @@
11//===- Timer.h ----------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -22,18 +21,18 @@ namespace lld {
2221class Timer;
2322
2423struct ScopedTimer {
25 explicit ScopedTimer(Timer &T);
24 explicit ScopedTimer(Timer &t);
2625
2726 ~ScopedTimer();
2827
2928 void stop();
3029
31 Timer *T = nullptr;
30 Timer *t = nullptr;
3231};
3332
3433class Timer {
3534public:
36 Timer(llvm::StringRef Name, Timer &Parent);
35 Timer(llvm::StringRef name, Timer &parent);
3736
3837 static Timer &root();
3938
......@@ -44,14 +43,14 @@ public:
4443 double millis() const;
4544
4645private:
47 explicit Timer(llvm::StringRef Name);
48 void print(int Depth, double TotalDuration, bool Recurse = true) const;
49
50 std::chrono::time_point<std::chrono::high_resolution_clock> StartTime;
51 std::chrono::nanoseconds Total;
52 std::vector<Timer *> Children;
53 std::string Name;
54 Timer *Parent;
46 explicit Timer(llvm::StringRef name);
47 void print(int depth, double totalDuration, bool recurse = true) const;
48
49 std::chrono::time_point<std::chrono::high_resolution_clock> startTime;
50 std::chrono::nanoseconds total;
51 std::vector<Timer *> children;
52 std::string name;
53 Timer *parent;
5554};
5655
5756} // namespace lld
deps/lld/include/lld/Common/Version.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/Common/Version.h - LLD Version Number ----------------*- C++ -*-===//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
deps/lld/include/lld/Core/AbsoluteAtom.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/AbsoluteAtom.h - An absolute Atom -----------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/ArchiveLibraryFile.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/ArchiveLibraryFile.h - Models static library ------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Atom.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/Atom.h - A node in linking graph --------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/DefinedAtom.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/DefinedAtom.h - An Atom with content --------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Error.h+3-4
......@@ -1,9 +1,8 @@
11//===- Error.h - system_error extensions for lld ----------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
deps/lld/include/lld/Core/File.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/File.h - A Container of Atoms ---------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Instrumentation.h+3-4
......@@ -1,9 +1,8 @@
11//===- include/Core/Instrumentation.h - Instrumentation API ---------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
deps/lld/include/lld/Core/LinkingContext.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/Core/LinkingContext.h - Linker Target Info Interface -*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Node.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/Core/Node.h - Input file class -----------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
deps/lld/include/lld/Core/Pass.h+3-4
......@@ -1,9 +1,8 @@
11//===------ Core/Pass.h - Base class for linker passes ----------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/PassManager.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/Core/PassManager.h - Manage linker passes ----------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Reader.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/Core/Reader.h - Abstract File Format Reading Interface ---------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Reference.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/References.h - A Reference to Another Atom ----------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Resolver.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/Resolver.h - Resolves Atom References -------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/SharedLibraryAtom.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/SharedLibraryAtom.h - A Shared Library Atom -------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/SharedLibraryFile.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/SharedLibraryFile.h - Models shared libraries as Atoms --------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Simple.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/Core/Simple.h - Simple implementations of Atom and File --------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
deps/lld/include/lld/Core/SymbolTable.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/SymbolTable.h - Main Symbol Table -----------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/UndefinedAtom.h+3-4
......@@ -1,9 +1,8 @@
11//===- Core/UndefinedAtom.h - An Undefined Atom ---------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/Core/Writer.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/Core/Writer.h - Abstract File Format Interface -----------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/ReaderWriter/MachOLinkingContext.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/ReaderWriter/MachOLinkingContext.h -----------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/include/lld/ReaderWriter/YamlContext.h+3-4
......@@ -1,9 +1,8 @@
11//===- lld/ReaderWriter/YamlContext.h - object used in YAML I/O context ---===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Core/DefinedAtom.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- DefinedAtom.cpp ------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Core/Error.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- Error.cpp - system_error extensions for lld --------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Core/File.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- Core/File.cpp - A Container of Atoms -------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Core/LinkingContext.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/Core/LinkingContext.cpp - Linker Context Object Interface ------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Core/Reader.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/Core/Reader.cpp ------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Core/Resolver.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- Core/Resolver.cpp - Resolves Atom References -----------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Core/SymbolTable.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- Core/SymbolTable.cpp - Main Symbol Table ---------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Core/Writer.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/Core/Writer.cpp ------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/Driver/DarwinLdDriver.cpp+15-16
......@@ -1,9 +1,8 @@
11//===- lib/Driver/DarwinLdDriver.cpp --------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
......@@ -334,8 +333,8 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx) {
334333 Twine(unknownArg->getAsString(parsedArgs)));
335334 }
336335
337 errorHandler().Verbose = parsedArgs.hasArg(OPT_v);
338 errorHandler().ErrorLimit = args::getInteger(parsedArgs, OPT_error_limit, 20);
336 errorHandler().verbose = parsedArgs.hasArg(OPT_v);
337 errorHandler().errorLimit = args::getInteger(parsedArgs, OPT_error_limit, 20);
339338
340339 // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static )
341340 llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE;
......@@ -638,7 +637,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx) {
638637
639638 // Now that we've constructed the final set of search paths, print out those
640639 // search paths in verbose mode.
641 if (errorHandler().Verbose) {
640 if (errorHandler().verbose) {
642641 message("Library search paths:");
643642 for (auto path : ctx.searchDirs()) {
644643 message(" " + path);
......@@ -1146,13 +1145,13 @@ static void createFiles(MachOLinkingContext &ctx, bool Implicit) {
11461145/// This is where the link is actually performed.
11471146bool link(llvm::ArrayRef<const char *> args, bool CanExitEarly,
11481147 raw_ostream &Error) {
1149 errorHandler().LogName = args::getFilenameWithoutExe(args[0]);
1150 errorHandler().ErrorLimitExceededMsg =
1148 errorHandler().logName = args::getFilenameWithoutExe(args[0]);
1149 errorHandler().errorLimitExceededMsg =
11511150 "too many errors emitted, stopping now (use "
11521151 "'-error-limit 0' to see all errors)";
1153 errorHandler().ErrorOS = &Error;
1154 errorHandler().ExitEarly = CanExitEarly;
1155 errorHandler().ColorDiagnostics = Error.has_colors();
1152 errorHandler().errorOS = &Error;
1153 errorHandler().exitEarly = CanExitEarly;
1154 errorHandler().colorDiagnostics = Error.has_colors();
11561155
11571156 MachOLinkingContext ctx;
11581157 if (!parse(args, ctx))
......@@ -1197,9 +1196,9 @@ bool link(llvm::ArrayRef<const char *> args, bool CanExitEarly,
11971196 if (auto ec = pm.runOnFile(*merged)) {
11981197 // FIXME: This should be passed to logAllUnhandledErrors but it needs
11991198 // to be passed a Twine instead of a string.
1200 *errorHandler().ErrorOS << "Failed to run passes on file '"
1199 *errorHandler().errorOS << "Failed to run passes on file '"
12011200 << ctx.outputPath() << "': ";
1202 logAllUnhandledErrors(std::move(ec), *errorHandler().ErrorOS,
1201 logAllUnhandledErrors(std::move(ec), *errorHandler().errorOS,
12031202 std::string());
12041203 return false;
12051204 }
......@@ -1211,9 +1210,9 @@ bool link(llvm::ArrayRef<const char *> args, bool CanExitEarly,
12111210 if (auto ec = ctx.writeFile(*merged)) {
12121211 // FIXME: This should be passed to logAllUnhandledErrors but it needs
12131212 // to be passed a Twine instead of a string.
1214 *errorHandler().ErrorOS << "Failed to write file '" << ctx.outputPath()
1213 *errorHandler().errorOS << "Failed to write file '" << ctx.outputPath()
12151214 << "': ";
1216 logAllUnhandledErrors(std::move(ec), *errorHandler().ErrorOS,
1215 logAllUnhandledErrors(std::move(ec), *errorHandler().errorOS,
12171216 std::string());
12181217 return false;
12191218 }
deps/lld/lib/ReaderWriter/FileArchive.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/FileArchive.cpp -----------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ArchHandler.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/FileFormat/MachO/ArchHandler.cpp -------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ArchHandler.h+3-4
......@@ -1,9 +1,8 @@
11//===- lib/FileFormat/MachO/ArchHandler.h ---------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/FileFormat/MachO/ArchHandler_arm.cpp ---------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/FileFormat/MachO/ArchHandler_arm64.cpp -------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/FileFormat/MachO/ArchHandler_x86.cpp ---------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp+4-4
......@@ -1,9 +1,8 @@
11//===- lib/FileFormat/MachO/ArchHandler_x86_64.cpp ------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -622,6 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal(
622621 // Fall into llvm_unreachable().
623622 break;
624623 }
624 llvm_unreachable("invalid x86_64 Reference Kind");
625625}
626626
627627void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,
deps/lld/lib/ReaderWriter/MachO/Atoms.h+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/Atoms.h ---------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp+7-12
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/CompactUnwindPass.cpp -------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
......@@ -388,12 +387,9 @@ private:
388387
389388 // Gather the personality functions now, so that they're in deterministic
390389 // order (derived from the DefinedAtom order).
391 if (unwindEntry.personalityFunction) {
392 auto pFunc = std::find(personalities.begin(), personalities.end(),
393 unwindEntry.personalityFunction);
394 if (pFunc == personalities.end())
395 personalities.push_back(unwindEntry.personalityFunction);
396 }
390 if (unwindEntry.personalityFunction &&
391 !llvm::count(personalities, unwindEntry.personalityFunction))
392 personalities.push_back(unwindEntry.personalityFunction);
397393 }
398394 }
399395
......@@ -552,8 +548,7 @@ private:
552548 }
553549 }
554550
555 auto personality = std::find(personalities.begin(), personalities.end(),
556 entry.personalityFunction);
551 auto personality = llvm::find(personalities, entry.personalityFunction);
557552 uint32_t personalityIdx = personality == personalities.end()
558553 ? 0
559554 : personality - personalities.begin() + 1;
deps/lld/lib/ReaderWriter/MachO/DebugInfo.h+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/ExecutableAtoms.h ---------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/File.h+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/FlatNamespaceFile.h -------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/GOTPass.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/GOTPass.cpp -----------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
deps/lld/lib/ReaderWriter/MachO/LayoutPass.cpp+3-4
......@@ -1,9 +1,8 @@
11//===-- ReaderWriter/MachO/LayoutPass.cpp - Layout atoms ------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/LayoutPass.h+3-4
......@@ -1,9 +1,8 @@
11//===------ lib/ReaderWriter/MachO/LayoutPass.h - Handles Layout of atoms -===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp+8-11
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -768,8 +767,7 @@ void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
768767 bool upward) const {
769768 std::lock_guard<std::mutex> lock(_dylibsMutex);
770769
771 if (std::find(_allDylibs.begin(),
772 _allDylibs.end(), dylib) == _allDylibs.end())
770 if (!llvm::count(_allDylibs, dylib))
773771 _allDylibs.push_back(dylib);
774772 _pathToDylibMap[dylib->installName()] = dylib;
775773 // If path is different than install name, register path too.
......@@ -1016,11 +1014,10 @@ static bool isLibrary(const std::unique_ptr<Node> &elem) {
10161014// new undefines from libraries.
10171015void MachOLinkingContext::finalizeInputFiles() {
10181016 std::vector<std::unique_ptr<Node>> &elements = getNodes();
1019 std::stable_sort(elements.begin(), elements.end(),
1020 [](const std::unique_ptr<Node> &a,
1021 const std::unique_ptr<Node> &b) {
1022 return !isLibrary(a) && isLibrary(b);
1023 });
1017 llvm::stable_sort(elements, [](const std::unique_ptr<Node> &a,
1018 const std::unique_ptr<Node> &b) {
1019 return !isLibrary(a) && isLibrary(b);
1020 });
10241021 size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
10251022 elements.push_back(llvm::make_unique<GroupEnd>(numLibs));
10261023}
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h+5-5
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachONormalizedFile.h -----------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -288,7 +287,8 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb,
288287/// Takes in-memory normalized view and writes a mach-o object file.
289288llvm::Error writeBinary(const NormalizedFile &file, StringRef path);
290289
291size_t headerAndLoadCommandsSize(const NormalizedFile &file);
290size_t headerAndLoadCommandsSize(const NormalizedFile &file,
291 bool includeFunctionStarts);
292292
293293
294294/// Parses a yaml encoded mach-o file to produce an in-memory normalized view.
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp ---------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h ------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp+20-14
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp ---------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -109,7 +108,7 @@ private:
109108class MachOFileLayout {
110109public:
111110 /// All layout computation is done in the constructor.
112 MachOFileLayout(const NormalizedFile &file);
111 MachOFileLayout(const NormalizedFile &file, bool alwaysIncludeFunctionStarts);
113112
114113 /// Returns the final file size as computed in the constructor.
115114 size_t size() const;
......@@ -123,7 +122,8 @@ public:
123122 llvm::Error writeBinary(StringRef path);
124123
125124private:
126 uint32_t loadCommandsSize(uint32_t &count);
125 uint32_t loadCommandsSize(uint32_t &count,
126 bool alwaysIncludeFunctionStarts);
127127 void buildFileOffsets();
128128 void writeMachHeader();
129129 llvm::Error writeLoadCommands();
......@@ -232,8 +232,9 @@ private:
232232 ByteBuffer _exportTrie;
233233};
234234
235size_t headerAndLoadCommandsSize(const NormalizedFile &file) {
236 MachOFileLayout layout(file);
235size_t headerAndLoadCommandsSize(const NormalizedFile &file,
236 bool includeFunctionStarts) {
237 MachOFileLayout layout(file, includeFunctionStarts);
237238 return layout.headerAndLoadCommandsSize();
238239}
239240
......@@ -250,7 +251,8 @@ size_t MachOFileLayout::headerAndLoadCommandsSize() const {
250251 return _endOfLoadCommands;
251252}
252253
253MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
254MachOFileLayout::MachOFileLayout(const NormalizedFile &file,
255 bool alwaysIncludeFunctionStarts)
254256 : _file(file),
255257 _is64(MachOLinkingContext::is64Bit(file.arch)),
256258 _swap(!MachOLinkingContext::isHostEndian(file.arch)),
......@@ -271,7 +273,7 @@ MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
271273 _endOfLoadCommands += sizeof(version_min_command);
272274 _countOfLoadCommands++;
273275 }
274 if (!_file.functionStarts.empty()) {
276 if (!_file.functionStarts.empty() || alwaysIncludeFunctionStarts) {
275277 _endOfLoadCommands += sizeof(linkedit_data_command);
276278 _countOfLoadCommands++;
277279 }
......@@ -326,7 +328,8 @@ MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
326328 } else {
327329 // Final linked images have one load command per segment.
328330 _endOfLoadCommands = _startOfLoadCommands
329 + loadCommandsSize(_countOfLoadCommands);
331 + loadCommandsSize(_countOfLoadCommands,
332 alwaysIncludeFunctionStarts);
330333
331334 // Assign section file offsets.
332335 buildFileOffsets();
......@@ -375,7 +378,8 @@ MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
375378 }
376379}
377380
378uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) {
381uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count,
382 bool alwaysIncludeFunctionStarts) {
379383 uint32_t size = 0;
380384 count = 0;
381385
......@@ -445,7 +449,7 @@ uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) {
445449 }
446450
447451 // Add LC_FUNCTION_STARTS if needed
448 if (!_file.functionStarts.empty()) {
452 if (!_file.functionStarts.empty() || alwaysIncludeFunctionStarts) {
449453 size += sizeof(linkedit_data_command);
450454 ++count;
451455 }
......@@ -1007,6 +1011,7 @@ llvm::Error MachOFileLayout::writeLoadCommands() {
10071011 lc += sizeof(linkedit_data_command);
10081012 }
10091013 }
1014 assert(lc == &_buffer[_endOfLoadCommands]);
10101015 return llvm::Error::success();
10111016}
10121017
......@@ -1018,6 +1023,7 @@ void MachOFileLayout::writeSectionContent() {
10181023 if (s.content.empty())
10191024 continue;
10201025 uint32_t offset = _sectInfo[&s].fileOffset;
1026 assert(offset >= _endOfLoadCommands);
10211027 uint8_t *p = &_buffer[offset];
10221028 memcpy(p, &s.content[0], s.content.size());
10231029 p += s.content.size();
......@@ -1543,7 +1549,7 @@ llvm::Error MachOFileLayout::writeBinary(StringRef path) {
15431549
15441550/// Takes in-memory normalized view and writes a mach-o object file.
15451551llvm::Error writeBinary(const NormalizedFile &file, StringRef path) {
1546 MachOFileLayout layout(file);
1552 MachOFileLayout layout(file, false);
15471553 return layout.writeBinary(path);
15481554}
15491555
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp+5-5
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp ------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -588,7 +587,8 @@ void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
588587
589588void Util::assignAddressesToSections(const NormalizedFile &file) {
590589 // NOTE!: Keep this in sync with organizeSections.
591 size_t hlcSize = headerAndLoadCommandsSize(file);
590 size_t hlcSize = headerAndLoadCommandsSize(file,
591 _ctx.generateFunctionStartsLoadCommand());
592592 uint64_t address = 0;
593593 for (SegmentInfo *seg : _segmentInfos) {
594594 if (seg->name.equals("__PAGEZERO")) {
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp --------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp -----------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/MachOPasses.h+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/MachOPasses.h -------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ObjCPass.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/ObjCPass.cpp -------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
deps/lld/lib/ReaderWriter/MachO/SectCreateFile.h+3-4
......@@ -1,9 +1,8 @@
11//===---- lib/ReaderWriter/MachO/SectCreateFile.h ---------------*- c++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/MachO/ShimPass.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/ShimPass.cpp -------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
deps/lld/lib/ReaderWriter/MachO/StubsPass.cpp+5-7
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/StubsPass.cpp ---------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -271,9 +270,8 @@ public:
271270 mergedFile.addAtom(*helperCacheNLPAtom);
272271
273272 // Add reference to dyld_stub_binder in libSystem.dylib
274 auto I = std::find_if(
275 mergedFile.sharedLibrary().begin(), mergedFile.sharedLibrary().end(),
276 [&](const SharedLibraryAtom *atom) {
273 auto I = llvm::find_if(
274 mergedFile.sharedLibrary(), [&](const SharedLibraryAtom *atom) {
277275 return atom->name().equals(_stubInfo.binderSymbolName);
278276 });
279277 assert(I != mergedFile.sharedLibrary().end() &&
deps/lld/lib/ReaderWriter/MachO/TLVPass.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/TLVPass.cpp -----------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
deps/lld/lib/ReaderWriter/MachO/WriterMachO.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/MachO/WriterMachO.cpp -----------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lib/ReaderWriter/YAML/ReaderWriterYAML.cpp -------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/test/CMakeLists.txt+5-3
......@@ -14,7 +14,9 @@ if(LLD_BUILT_STANDALONE)
1414endif()
1515
1616llvm_canonicalize_cmake_booleans(
17 HAVE_LIBZ)
17 HAVE_LIBZ
18 LLVM_LIBXML2_ENABLED
19 )
1820
1921configure_lit_site_cfg(
2022 ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
......@@ -32,8 +34,8 @@ configure_lit_site_cfg(
3234set(LLD_TEST_DEPS lld)
3335if (NOT LLD_BUILT_STANDALONE)
3436 list(APPEND LLD_TEST_DEPS
35 FileCheck count llc llvm-ar llvm-as llvm-bcanalyzer llvm-config llvm-dis
36 llvm-dwarfdump llvm-lib llvm-mc llvm-nm llvm-objcopy llvm-objdump
37 FileCheck count llc llvm-ar llvm-as llvm-bcanalyzer llvm-config llvm-cvtres
38 llvm-dis llvm-dwarfdump llvm-lib llvm-mc llvm-nm llvm-objcopy llvm-objdump
3739 llvm-pdbutil llvm-readelf llvm-readobj not obj2yaml opt yaml2obj
3840 )
3941endif()
deps/lld/test/COFF/Inputs/combined-resources-2.rc+36-36
......@@ -1,36 +1,36 @@
1#include "windows.h"
2
3LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
4randomdat RCDATA
5{
6 "this is a random bit of data that means nothing\0",
7 0x23a9,
8 0x140e,
9 194292,
10}
11
12LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
13randomdat RCDATA
14{
15 "zhe4 shi4 yi1ge4 sui2ji1 de shu4ju4, zhe4 yi4wei4zhe shen2me\0",
16 0x23a9,
17 0x140e,
18 194292,
19}
20
21LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_LUXEMBOURG
22randomdat RCDATA
23{
24 "Dies ist ein zufälliges Bit von Daten, die nichts bedeutet\0",
25 0x23a9,
26 0x140e,
27 194292,
28}
29
30LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
31myaccelerators ACCELERATORS
32{
33 "^C", 999, VIRTKEY, ALT
34 "D", 1100, VIRTKEY, CONTROL, SHIFT
35 "^R", 444, ASCII, NOINVERT
36}
1#include "windows.h"
2
3LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
4randomdat RCDATA
5{
6 "this is a random bit of data that means nothing\0",
7 0x23a9,
8 0x140e,
9 194292,
10}
11
12LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
13randomdat RCDATA
14{
15 "zhe4 shi4 yi1ge4 sui2ji1 de shu4ju4, zhe4 yi4wei4zhe shen2me\0",
16 0x23a9,
17 0x140e,
18 194292,
19}
20
21LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_LUXEMBOURG
22randomdat RCDATA
23{
24 "Dies ist ein zufälliges Bit von Daten, die nichts bedeutet\0",
25 0x23a9,
26 0x140e,
27 194292,
28}
29
30LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
31myaccelerators ACCELERATORS
32{
33 "^C", 999, VIRTKEY, ALT
34 "D", 1100, VIRTKEY, CONTROL, SHIFT
35 "^R", 444, ASCII, NOINVERT
36}
deps/lld/test/COFF/Inputs/crt-dyn-initializer-order_1.yaml+15-15
......@@ -1,15 +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...
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+19-19
......@@ -1,19 +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...
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/delayimporttables-dll1.yaml created+57
......@@ -0,0 +1,57 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D455322202F4558504F52543A6F6E65202F4558504F52543A74776F20
10 - Name: '.text$mn'
11 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
12 Alignment: 16
13 SectionData: C20000CCCCCCCCCCCCCCCCCCCCCCCCCCC20000CCCCCCCCCCCCCCCCCCCCCCCCCC4C894424188954241048894C240833C0C3
14symbols:
15 - Name: .drectve
16 Value: 0
17 SectionNumber: 1
18 SimpleType: IMAGE_SYM_TYPE_NULL
19 ComplexType: IMAGE_SYM_DTYPE_NULL
20 StorageClass: IMAGE_SYM_CLASS_STATIC
21 SectionDefinition:
22 Length: 71
23 NumberOfRelocations: 0
24 NumberOfLinenumbers: 0
25 CheckSum: 4081356488
26 Number: 0
27 - Name: '.text$mn'
28 Value: 0
29 SectionNumber: 2
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_STATIC
33 SectionDefinition:
34 Length: 49
35 NumberOfRelocations: 0
36 NumberOfLinenumbers: 0
37 CheckSum: 405845281
38 Number: 0
39 - Name: one
40 Value: 0
41 SectionNumber: 2
42 SimpleType: IMAGE_SYM_TYPE_NULL
43 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
44 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
45 - Name: two
46 Value: 16
47 SectionNumber: 2
48 SimpleType: IMAGE_SYM_TYPE_NULL
49 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
50 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
51 - Name: DllMain
52 Value: 32
53 SectionNumber: 2
54 SimpleType: IMAGE_SYM_TYPE_NULL
55 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
56 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
57...
deps/lld/test/COFF/Inputs/delayimporttables-dll2.yaml created+57
......@@ -0,0 +1,57 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D455322202F4558504F52543A6C656674202F4558504F52543A726967687420
10 - Name: '.text$mn'
11 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
12 Alignment: 16
13 SectionData: C20000CCCCCCCCCCCCCCCCCCCCCCCCCCC20000CCCCCCCCCCCCCCCCCCCCCCCCCC4C894424188954241048894C240833C0C3
14symbols:
15 - Name: .drectve
16 Value: 0
17 SectionNumber: 1
18 SimpleType: IMAGE_SYM_TYPE_NULL
19 ComplexType: IMAGE_SYM_DTYPE_NULL
20 StorageClass: IMAGE_SYM_CLASS_STATIC
21 SectionDefinition:
22 Length: 74
23 NumberOfRelocations: 0
24 NumberOfLinenumbers: 0
25 CheckSum: 127731413
26 Number: 0
27 - Name: '.text$mn'
28 Value: 0
29 SectionNumber: 2
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_STATIC
33 SectionDefinition:
34 Length: 49
35 NumberOfRelocations: 0
36 NumberOfLinenumbers: 0
37 CheckSum: 405845281
38 Number: 0
39 - Name: left
40 Value: 0
41 SectionNumber: 2
42 SimpleType: IMAGE_SYM_TYPE_NULL
43 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
44 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
45 - Name: right
46 Value: 16
47 SectionNumber: 2
48 SimpleType: IMAGE_SYM_TYPE_NULL
49 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
50 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
51 - Name: DllMain
52 Value: 32
53 SectionNumber: 2
54 SimpleType: IMAGE_SYM_TYPE_NULL
55 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
56 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
57...
deps/lld/test/COFF/Inputs/eh_frame_terminator-crtend.s created+3
......@@ -0,0 +1,3 @@
1 .section .eh_frame,"dr"
2__FRAME_END__:
3 .byte 3
deps/lld/test/COFF/Inputs/eh_frame_terminator-otherfunc.s created+7
......@@ -0,0 +1,7 @@
1 .text
2 .globl otherfunc
3otherfunc:
4 ret
5
6 .section .eh_frame,"dr"
7 .byte 2
deps/lld/test/COFF/Inputs/failmismatch1.ll created+15
......@@ -0,0 +1,15 @@
1; ModuleID = 'test.cpp'
2
3; Function Attrs: noinline nounwind optnone sspstrong uwtable
4define dso_local i32 @"?f@@YAHXZ"() #0 {
5 ret i32 0
6}
7
8!llvm.linker.options = !{!0}
9!llvm.module.flags = !{!1, !2}
10!llvm.ident = !{!3}
11
12!0 = !{!"/FAILIFMISMATCH:\22TEST=1\22"}
13!1 = !{i32 1, !"wchar_size", i32 2}
14!2 = !{i32 7, !"PIC Level", i32 2}
15!3 = !{!"clang version 7.0.1 (tags/RELEASE_701/final)"}
deps/lld/test/COFF/Inputs/failmismatch2.ll created+20
......@@ -0,0 +1,20 @@
1; ModuleID = 'test2.cpp'
2
3; Function Attrs: noinline norecurse nounwind optnone sspstrong uwtable
4define dso_local i32 @main() #0 {
5 %1 = alloca i32, align 4
6 store i32 0, i32* %1, align 4
7 %2 = call i32 @"?f@@YAHXZ"()
8 ret i32 %2
9}
10
11declare dso_local i32 @"?f@@YAHXZ"() #1
12
13!llvm.linker.options = !{!0}
14!llvm.module.flags = !{!1, !2}
15!llvm.ident = !{!3}
16
17!0 = !{!"/FAILIFMISMATCH:\22TEST=2\22"}
18!1 = !{i32 1, !"wchar_size", i32 2}
19!2 = !{i32 7, !"PIC Level", i32 2}
20!3 = !{!"clang version 7.0.1 (tags/RELEASE_701/final)"}
deps/lld/test/COFF/Inputs/hello32.yaml+6
......@@ -79,4 +79,10 @@ symbols:
7979 SimpleType: IMAGE_SYM_TYPE_NULL
8080 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
8181 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
82 - Name: '@feat.00'
83 Value: 1
84 SectionNumber: -1
85 SimpleType: IMAGE_SYM_TYPE_NULL
86 ComplexType: IMAGE_SYM_DTYPE_NULL
87 StorageClass: IMAGE_SYM_CLASS_STATIC
8288...
deps/lld/test/COFF/Inputs/id.res created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/id.res differ
deps/lld/test/COFF/Inputs/id.res.o created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/id.res.o differ
deps/lld/test/COFF/Inputs/no-ipi-stream-obj.obj.yaml created+13
......@@ -0,0 +1,13 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_I386
4sections:
5 - Name: '.debug$T'
6 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
7 Types:
8 - Kind: LF_TYPESERVER2
9 TypeServer2:
10 Guid: '{01234567-0123-0123-0123-0123456789AB}'
11 Age: 1
12 Name: 'no-ipi-stream-pdb.pdb'
13symbols:
deps/lld/test/COFF/Inputs/no-ipi-stream-pdb.pdb.yaml created+2
......@@ -0,0 +1,2 @@
1PdbStream:
2 Guid: '{01234567-0123-0123-0123-0123456789AB}'
deps/lld/test/COFF/Inputs/pdb-diff.cpp+10-10
......@@ -1,10 +1,10 @@
1// Build with cl:
2// cl.exe /Z7 pdb-diff.cpp /link /debug /pdb:pdb-diff-cl.pdb
3// /nodefaultlib /entry:main
4// Build with lld (after running the above cl command):
5// lld-link.exe /debug /pdb:pdb-diff-lld.pdb /nodefaultlib
6// /entry:main pdb-diff.obj
7
8void *__purecall = 0;
9
10int main() { return 42; }
1// Build with cl:
2// cl.exe /Z7 pdb-diff.cpp /link /debug /pdb:pdb-diff-cl.pdb
3// /nodefaultlib /entry:main
4// Build with lld (after running the above cl command):
5// lld-link.exe /debug /pdb:pdb-diff-lld.pdb /nodefaultlib
6// /entry:main pdb-diff.obj
7
8void *__purecall = 0;
9
10int main() { return 42; }
deps/lld/test/COFF/Inputs/pdb-file-statics-a.yaml+1
......@@ -1280,6 +1280,7 @@ sections:
12801280 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
12811281 Alignment: 4
12821282 SectionData: ''
1283 SizeOfRawData: 4
12831284 - Name: '.text$mn'
12841285 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
12851286 Alignment: 4
deps/lld/test/COFF/Inputs/pdb-file-statics-b.yaml+1
......@@ -1255,6 +1255,7 @@ sections:
12551255 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
12561256 Alignment: 4
12571257 SectionData: ''
1258 SizeOfRawData: 4
12581259 - Name: '.text$mn'
12591260 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
12601261 Alignment: 4
deps/lld/test/COFF/Inputs/pdb-global-constants-a.s created+214
......@@ -0,0 +1,214 @@
1 .text
2 .def @feat.00;
3 .scl 3;
4 .type 0;
5 .endef
6 .globl @feat.00
7.set @feat.00, 0
8 .file "t.cpp"
9 .def main;
10 .scl 2;
11 .type 32;
12 .endef
13 .globl main # -- Begin function main
14 .p2align 4, 0x90
15main: # @main
16.Lfunc_begin0:
17 .cv_func_id 0
18 .cv_file 1 "C:\\src\\testing\\t.cpp" "D28AB0CC784E17E5DF9BBB49CB629C81" 1
19 .cv_loc 0 1 4 0 # t.cpp:4:0
20.seh_proc main
21# %bb.0: # %entry
22 pushq %rax
23 .seh_stackalloc 8
24 .seh_endprologue
25 movl $0, 4(%rsp)
26.Ltmp0:
27 movl $83, %eax
28 popq %rcx
29 retq
30.Ltmp1:
31.Lfunc_end0:
32 .seh_handlerdata
33 .text
34 .seh_endproc
35 # -- End function
36 .section .debug$S,"dr"
37 .p2align 2
38 .long 4 # Debug section magic
39 .long 241
40 .long .Ltmp3-.Ltmp2 # Subsection size
41.Ltmp2:
42 .short .Ltmp5-.Ltmp4 # Record length
43.Ltmp4:
44 .short 4412 # Record kind: S_COMPILE3
45 .long 1 # Flags and language
46 .short 208 # CPUType
47 .short 9 # Frontend version
48 .short 0
49 .short 0
50 .short 0
51 .short 9000 # Backend version
52 .short 0
53 .short 0
54 .short 0
55 .asciz "clang version 9.0.0 (https://github.com/llvm/llvm-project.git ad522e17b285b1f2667163d52da5abf0968ec650)" # Null-terminated compiler version string
56 .p2align 2
57.Ltmp5:
58.Ltmp3:
59 .p2align 2
60 .long 241 # Symbol subsection for main
61 .long .Ltmp7-.Ltmp6 # Subsection size
62.Ltmp6:
63 .short .Ltmp9-.Ltmp8 # Record length
64.Ltmp8:
65 .short 4423 # Record kind: S_GPROC32_ID
66 .long 0 # PtrParent
67 .long 0 # PtrEnd
68 .long 0 # PtrNext
69 .long .Lfunc_end0-main # Code size
70 .long 0 # Offset after prologue
71 .long 0 # Offset before epilogue
72 .long 4098 # Function type index
73 .secrel32 main # Function section relative address
74 .secidx main # Function section index
75 .byte 0 # Flags
76 .asciz "main" # Function name
77 .p2align 2
78.Ltmp9:
79 .short .Ltmp11-.Ltmp10 # Record length
80.Ltmp10:
81 .short 4114 # Record kind: S_FRAMEPROC
82 .long 8 # FrameSize
83 .long 0 # Padding
84 .long 0 # Offset of padding
85 .long 0 # Bytes of callee saved registers
86 .long 0 # Exception handler offset
87 .short 0 # Exception handler section
88 .long 81920 # Flags (defines frame register)
89 .p2align 2
90.Ltmp11:
91 .short 2 # Record length
92 .short 4431 # Record kind: S_PROC_ID_END
93.Ltmp7:
94 .p2align 2
95 .cv_linetable 0, main, .Lfunc_end0
96 .long 241 # Symbol subsection for globals
97 .long .Ltmp13-.Ltmp12 # Subsection size
98.Ltmp12:
99 .short .Ltmp15-.Ltmp14 # Record length
100.Ltmp14:
101 .short 4359 # Record kind: S_CONSTANT
102 .long 4099 # Type
103 .byte 0x29, 0x00 # Value
104 .asciz "Foo" # Name
105 .p2align 2
106.Ltmp15:
107 .short .Ltmp17-.Ltmp16 # Record length
108.Ltmp16:
109 .short 4359 # Record kind: S_CONSTANT
110 .long 4099 # Type
111 .byte 0x2a, 0x00 # Value
112 .asciz "Bar" # Name
113 .p2align 2
114.Ltmp17:
115.Ltmp13:
116 .p2align 2
117 .cv_filechecksums # File index to string table offset subsection
118 .cv_stringtable # String table
119 .long 241
120 .long .Ltmp19-.Ltmp18 # Subsection size
121.Ltmp18:
122 .short .Ltmp21-.Ltmp20 # Record length
123.Ltmp20:
124 .short 4428 # Record kind: S_BUILDINFO
125 .long 4102 # LF_BUILDINFO index
126 .p2align 2
127.Ltmp21:
128.Ltmp19:
129 .p2align 2
130 .section .debug$T,"dr"
131 .p2align 2
132 .long 4 # Debug section magic
133 # ArgList (0x1000) {
134 # TypeLeafKind: LF_ARGLIST (0x1201)
135 # NumArgs: 0
136 # Arguments [
137 # ]
138 # }
139 .byte 0x06, 0x00, 0x01, 0x12
140 .byte 0x00, 0x00, 0x00, 0x00
141 # Procedure (0x1001) {
142 # TypeLeafKind: LF_PROCEDURE (0x1008)
143 # ReturnType: int (0x74)
144 # CallingConvention: NearC (0x0)
145 # FunctionOptions [ (0x0)
146 # ]
147 # NumParameters: 0
148 # ArgListType: () (0x1000)
149 # }
150 .byte 0x0e, 0x00, 0x08, 0x10
151 .byte 0x74, 0x00, 0x00, 0x00
152 .byte 0x00, 0x00, 0x00, 0x00
153 .byte 0x00, 0x10, 0x00, 0x00
154 # FuncId (0x1002) {
155 # TypeLeafKind: LF_FUNC_ID (0x1601)
156 # ParentScope: 0x0
157 # FunctionType: int () (0x1001)
158 # Name: main
159 # }
160 .byte 0x12, 0x00, 0x01, 0x16
161 .byte 0x00, 0x00, 0x00, 0x00
162 .byte 0x01, 0x10, 0x00, 0x00
163 .byte 0x6d, 0x61, 0x69, 0x6e
164 .byte 0x00, 0xf3, 0xf2, 0xf1
165 # Modifier (0x1003) {
166 # TypeLeafKind: LF_MODIFIER (0x1001)
167 # ModifiedType: int (0x74)
168 # Modifiers [ (0x1)
169 # Const (0x1)
170 # ]
171 # }
172 .byte 0x0a, 0x00, 0x01, 0x10
173 .byte 0x74, 0x00, 0x00, 0x00
174 .byte 0x01, 0x00, 0xf2, 0xf1
175 # StringId (0x1004) {
176 # TypeLeafKind: LF_STRING_ID (0x1605)
177 # Id: 0x0
178 # StringData: C:\src\testing
179 # }
180 .byte 0x16, 0x00, 0x05, 0x16
181 .byte 0x00, 0x00, 0x00, 0x00
182 .byte 0x43, 0x3a, 0x5c, 0x73
183 .byte 0x72, 0x63, 0x5c, 0x74
184 .byte 0x65, 0x73, 0x74, 0x69
185 .byte 0x6e, 0x67, 0x00, 0xf1
186 # StringId (0x1005) {
187 # TypeLeafKind: LF_STRING_ID (0x1605)
188 # Id: 0x0
189 # StringData: t.cpp
190 # }
191 .byte 0x0e, 0x00, 0x05, 0x16
192 .byte 0x00, 0x00, 0x00, 0x00
193 .byte 0x74, 0x2e, 0x63, 0x70
194 .byte 0x70, 0x00, 0xf2, 0xf1
195 # BuildInfo (0x1006) {
196 # TypeLeafKind: LF_BUILDINFO (0x1603)
197 # NumArgs: 5
198 # Arguments [
199 # ArgType: C:\src\testing (0x1004)
200 # ArgType: 0x0
201 # ArgType: t.cpp (0x1005)
202 # ArgType: 0x0
203 # ArgType: 0x0
204 # ]
205 # }
206 .byte 0x1a, 0x00, 0x03, 0x16
207 .byte 0x05, 0x00, 0x04, 0x10
208 .byte 0x00, 0x00, 0x00, 0x00
209 .byte 0x00, 0x00, 0x05, 0x10
210 .byte 0x00, 0x00, 0x00, 0x00
211 .byte 0x00, 0x00, 0x00, 0x00
212 .byte 0x00, 0x00, 0xf2, 0xf1
213
214 .addrsig
deps/lld/test/COFF/Inputs/pdb-global-constants-b.s created+204
......@@ -0,0 +1,204 @@
1 .text
2 .def @feat.00;
3 .scl 3;
4 .type 0;
5 .endef
6 .globl @feat.00
7.set @feat.00, 0
8 .file "t2.cpp"
9 .def "?foobar@@YAHXZ";
10 .scl 2;
11 .type 32;
12 .endef
13 .globl "?foobar@@YAHXZ" # -- Begin function ?foobar@@YAHXZ
14 .p2align 4, 0x90
15"?foobar@@YAHXZ": # @"?foobar@@YAHXZ"
16.Lfunc_begin0:
17 .cv_func_id 0
18# %bb.0: # %entry
19 .cv_file 1 "C:\\src\\testing\\t2.cpp" "C9D7AF07363FDE8EC16D73EC30039C5B" 1
20 .cv_loc 0 1 5 0 # t2.cpp:5:0
21 movl $84, %eax
22 retq
23.Ltmp0:
24.Lfunc_end0:
25 # -- End function
26 .section .debug$S,"dr"
27 .p2align 2
28 .long 4 # Debug section magic
29 .long 241
30 .long .Ltmp2-.Ltmp1 # Subsection size
31.Ltmp1:
32 .short .Ltmp4-.Ltmp3 # Record length
33.Ltmp3:
34 .short 4412 # Record kind: S_COMPILE3
35 .long 1 # Flags and language
36 .short 208 # CPUType
37 .short 9 # Frontend version
38 .short 0
39 .short 0
40 .short 0
41 .short 9000 # Backend version
42 .short 0
43 .short 0
44 .short 0
45 .asciz "clang version 9.0.0 (https://github.com/llvm/llvm-project.git ad522e17b285b1f2667163d52da5abf0968ec650)" # Null-terminated compiler version string
46 .p2align 2
47.Ltmp4:
48.Ltmp2:
49 .p2align 2
50 .long 241 # Symbol subsection for foobar
51 .long .Ltmp6-.Ltmp5 # Subsection size
52.Ltmp5:
53 .short .Ltmp8-.Ltmp7 # Record length
54.Ltmp7:
55 .short 4423 # Record kind: S_GPROC32_ID
56 .long 0 # PtrParent
57 .long 0 # PtrEnd
58 .long 0 # PtrNext
59 .long .Lfunc_end0-"?foobar@@YAHXZ" # Code size
60 .long 0 # Offset after prologue
61 .long 0 # Offset before epilogue
62 .long 4098 # Function type index
63 .secrel32 "?foobar@@YAHXZ" # Function section relative address
64 .secidx "?foobar@@YAHXZ" # Function section index
65 .byte 0 # Flags
66 .asciz "foobar" # Function name
67 .p2align 2
68.Ltmp8:
69 .short .Ltmp10-.Ltmp9 # Record length
70.Ltmp9:
71 .short 4114 # Record kind: S_FRAMEPROC
72 .long 0 # FrameSize
73 .long 0 # Padding
74 .long 0 # Offset of padding
75 .long 0 # Bytes of callee saved registers
76 .long 0 # Exception handler offset
77 .short 0 # Exception handler section
78 .long 0 # Flags (defines frame register)
79 .p2align 2
80.Ltmp10:
81 .short 2 # Record length
82 .short 4431 # Record kind: S_PROC_ID_END
83.Ltmp6:
84 .p2align 2
85 .cv_linetable 0, "?foobar@@YAHXZ", .Lfunc_end0
86 .long 241 # Symbol subsection for globals
87 .long .Ltmp12-.Ltmp11 # Subsection size
88.Ltmp11:
89 .short .Ltmp14-.Ltmp13 # Record length
90.Ltmp13:
91 .short 4359 # Record kind: S_CONSTANT
92 .long 4099 # Type
93 .byte 0x2a, 0x00 # Value
94 .asciz "Foo" # Name
95 .p2align 2
96.Ltmp14:
97 .short .Ltmp16-.Ltmp15 # Record length
98.Ltmp15:
99 .short 4359 # Record kind: S_CONSTANT
100 .long 4099 # Type
101 .byte 0x2a, 0x00 # Value
102 .asciz "Bar" # Name
103 .p2align 2
104.Ltmp16:
105.Ltmp12:
106 .p2align 2
107 .cv_filechecksums # File index to string table offset subsection
108 .cv_stringtable # String table
109 .long 241
110 .long .Ltmp18-.Ltmp17 # Subsection size
111.Ltmp17:
112 .short .Ltmp20-.Ltmp19 # Record length
113.Ltmp19:
114 .short 4428 # Record kind: S_BUILDINFO
115 .long 4102 # LF_BUILDINFO index
116 .p2align 2
117.Ltmp20:
118.Ltmp18:
119 .p2align 2
120 .section .debug$T,"dr"
121 .p2align 2
122 .long 4 # Debug section magic
123 # ArgList (0x1000) {
124 # TypeLeafKind: LF_ARGLIST (0x1201)
125 # NumArgs: 0
126 # Arguments [
127 # ]
128 # }
129 .byte 0x06, 0x00, 0x01, 0x12
130 .byte 0x00, 0x00, 0x00, 0x00
131 # Procedure (0x1001) {
132 # TypeLeafKind: LF_PROCEDURE (0x1008)
133 # ReturnType: int (0x74)
134 # CallingConvention: NearC (0x0)
135 # FunctionOptions [ (0x0)
136 # ]
137 # NumParameters: 0
138 # ArgListType: () (0x1000)
139 # }
140 .byte 0x0e, 0x00, 0x08, 0x10
141 .byte 0x74, 0x00, 0x00, 0x00
142 .byte 0x00, 0x00, 0x00, 0x00
143 .byte 0x00, 0x10, 0x00, 0x00
144 # FuncId (0x1002) {
145 # TypeLeafKind: LF_FUNC_ID (0x1601)
146 # ParentScope: 0x0
147 # FunctionType: int () (0x1001)
148 # Name: foobar
149 # }
150 .byte 0x12, 0x00, 0x01, 0x16
151 .byte 0x00, 0x00, 0x00, 0x00
152 .byte 0x01, 0x10, 0x00, 0x00
153 .byte 0x66, 0x6f, 0x6f, 0x62
154 .byte 0x61, 0x72, 0x00, 0xf1
155 # Modifier (0x1003) {
156 # TypeLeafKind: LF_MODIFIER (0x1001)
157 # ModifiedType: int (0x74)
158 # Modifiers [ (0x1)
159 # Const (0x1)
160 # ]
161 # }
162 .byte 0x0a, 0x00, 0x01, 0x10
163 .byte 0x74, 0x00, 0x00, 0x00
164 .byte 0x01, 0x00, 0xf2, 0xf1
165 # StringId (0x1004) {
166 # TypeLeafKind: LF_STRING_ID (0x1605)
167 # Id: 0x0
168 # StringData: C:\src\testing
169 # }
170 .byte 0x16, 0x00, 0x05, 0x16
171 .byte 0x00, 0x00, 0x00, 0x00
172 .byte 0x43, 0x3a, 0x5c, 0x73
173 .byte 0x72, 0x63, 0x5c, 0x74
174 .byte 0x65, 0x73, 0x74, 0x69
175 .byte 0x6e, 0x67, 0x00, 0xf1
176 # StringId (0x1005) {
177 # TypeLeafKind: LF_STRING_ID (0x1605)
178 # Id: 0x0
179 # StringData: t2.cpp
180 # }
181 .byte 0x0e, 0x00, 0x05, 0x16
182 .byte 0x00, 0x00, 0x00, 0x00
183 .byte 0x74, 0x32, 0x2e, 0x63
184 .byte 0x70, 0x70, 0x00, 0xf1
185 # BuildInfo (0x1006) {
186 # TypeLeafKind: LF_BUILDINFO (0x1603)
187 # NumArgs: 5
188 # Arguments [
189 # ArgType: C:\src\testing (0x1004)
190 # ArgType: 0x0
191 # ArgType: t2.cpp (0x1005)
192 # ArgType: 0x0
193 # ArgType: 0x0
194 # ]
195 # }
196 .byte 0x1a, 0x00, 0x03, 0x16
197 .byte 0x05, 0x00, 0x04, 0x10
198 .byte 0x00, 0x00, 0x00, 0x00
199 .byte 0x00, 0x00, 0x05, 0x10
200 .byte 0x00, 0x00, 0x00, 0x00
201 .byte 0x00, 0x00, 0x00, 0x00
202 .byte 0x00, 0x00, 0xf2, 0xf1
203
204 .addrsig
deps/lld/test/COFF/Inputs/pdb-globals.yaml+1-1
......@@ -70,6 +70,7 @@ sections:
7070 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
7171 Alignment: 4
7272 SectionData: ''
73 SizeOfRawData: 4
7374 - Name: .text
7475 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
7576 Alignment: 16
......@@ -263,7 +264,6 @@ sections:
263264 - Name: '.debug$T'
264265 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
265266 Alignment: 4
266 SectionData: 0400000006000112000000000E000810740000000000000000100000160001160000000001100000476C6F62616C46756E6300F10A000210700400000A8000000E0001120200000074000000031000000E0008107400000000000200041000001200011600000000051000006D61696E00F3F2F13200051500008002000000000000000000000000000048656C6C6F506F696E74002E3F415548656C6C6F506F696E74404000F2F1260003120D15030074000000000058000D15030074000000040059000D1503007400000008005A0032000515030000020810000000000000000000000C0048656C6C6F506F696E74002E3F415548656C6C6F506F696E74404000F2F13E00051600000000643A5C7372635C6C6C766D2D6D6F6E6F5C6C6C645C746573745C636F66665C696E707574735C7064622D676C6F62616C732E63707000F2F10E000616091000000A100000060000000A000210071000000A8000001A00091003000000071000000C1000000B000000001000000000000016000216071000000D10000048656C6C6F506F696E7400F11600011600000000011000004C6F63616C46756E6300F2F10A000110740000000100F2F10A000210101000000A800000
267267 Types:
268268 - Kind: LF_ARGLIST
269269 ArgList:
deps/lld/test/COFF/Inputs/pdb-type-server-invalid-path.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: 1
73 Name: 'c:\some_invalid_path_AABB98765\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/pdb_comdat_bar.yaml+1
......@@ -190,6 +190,7 @@ sections:
190190 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
191191 Alignment: 4
192192 SectionData: ''
193 SizeOfRawData: 4
193194 - Name: '.text$mn'
194195 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
195196 Alignment: 16
deps/lld/test/COFF/Inputs/thinlto-empty.ll created+2
......@@ -0,0 +1,2 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc19.0.24215"
deps/lld/test/COFF/Inputs/thinlto.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc19.0.24215"
3
4define void @g() {
5 ret void
6}
deps/lld/test/COFF/Inputs/tlssup.s created+10
......@@ -0,0 +1,10 @@
1 .section .tls,"dw"
2 .byte 0xaa
3
4 .section .tls$ZZZ,"dw"
5 .byte 0xff
6
7 .globl _tls_index
8 .data
9_tls_index:
10 .int 0
deps/lld/test/COFF/Inputs/undefined-symbol-lto-a.ll created+82
......@@ -0,0 +1,82 @@
1; ModuleID = 't.obj'
2source_filename = "t.cpp"
3target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
4target triple = "x86_64-pc-windows-msvc19.21.27702"
5
6%struct.Init = type { %struct.S }
7%struct.S = type { i32 (...)** }
8%rtti.CompleteObjectLocator = type { i32, i32, i32, i32, i32, i32 }
9%rtti.TypeDescriptor7 = type { i8**, i8*, [8 x i8] }
10%rtti.ClassHierarchyDescriptor = type { i32, i32, i32, i32 }
11%rtti.BaseClassDescriptor = type { i32, i32, i32, i32, i32, i32, i32 }
12
13$"??_SS@@6B@" = comdat largest
14
15$"??_R4S@@6B@" = comdat any
16
17$"??_R0?AUS@@@8" = comdat any
18
19$"??_R3S@@8" = comdat any
20
21$"??_R2S@@8" = comdat any
22
23$"??_R1A@?0A@EA@S@@8" = comdat any
24
25@"?d@@3UInit@@A" = dso_local local_unnamed_addr global %struct.Init zeroinitializer, align 8
26@anon.bcb2691509de99310dddb690fcdb4cdc.0 = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"??_R4S@@6B@" to i8*), i8* bitcast (void (%struct.S*)* @"?foo@S@@UEAAXXZ" to i8*)] }, comdat($"??_SS@@6B@"), !type !0
27@"??_R4S@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUS@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3S@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4S@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
28@"??_7type_info@@6B@" = external constant i8*
29@"??_R0?AUS@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUS@@\00" }, comdat
30@__ImageBase = external dso_local constant i8
31@"??_R3S@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2S@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
32@"??_R2S@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@S@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat
33@"??_R1A@?0A@EA@S@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"??_R0?AUS@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3S@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat
34@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_t.cpp, i8* null }]
35
36@"??_SS@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @anon.bcb2691509de99310dddb690fcdb4cdc.0, i32 0, i32 0, i32 1)
37
38declare dso_local void @"?undefined_ref@@YAXXZ"() local_unnamed_addr #0
39
40declare dllimport void @"?foo@S@@UEAAXXZ"(%struct.S*) unnamed_addr #0
41
42; Function Attrs: nounwind sspstrong uwtable
43define internal void @_GLOBAL__sub_I_t.cpp() #1 {
44entry:
45 store i32 (...)** bitcast (i8** @"??_SS@@6B@" to i32 (...)**), i32 (...)*** getelementptr inbounds (%struct.Init, %struct.Init* @"?d@@3UInit@@A", i64 0, i32 0, i32 0), align 8
46 tail call void @"?undefined_ref@@YAXXZ"() #2
47 ret void
48}
49
50attributes #0 = { "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-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
51attributes #1 = { nounwind sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "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"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
52attributes #2 = { nounwind }
53
54!llvm.linker.options = !{!1, !2}
55!llvm.module.flags = !{!3, !4, !5, !6}
56!llvm.ident = !{!7}
57
58!0 = !{i64 8, !"?AUS@@"}
59!1 = !{!"/DEFAULTLIB:libcmt.lib"}
60!2 = !{!"/DEFAULTLIB:oldnames.lib"}
61!3 = !{i32 1, !"wchar_size", i32 2}
62!4 = !{i32 7, !"PIC Level", i32 2}
63!5 = !{i32 1, !"ThinLTO", i32 0}
64!6 = !{i32 1, !"EnableSplitLTOUnit", i32 0}
65!7 = !{!"clang version 9.0.0 (git@github.com:llvm/llvm-project.git 1a285c27fdf6407ceed3398e015d00559f5f533d)"}
66
67^0 = module: (path: "t.obj", hash: (0, 0, 0, 0, 0))
68^1 = gv: (name: "__ImageBase") ; guid = 434928772013489304
69^2 = gv: (name: "??_R2S@@8", summaries: (variable: (module: ^0, flags: (linkage: linkonce_odr, notEligibleToImport: 1, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0), refs: (^1, ^6)))) ; guid = 2160898732728284029
70^3 = gv: (name: "llvm.global_ctors", summaries: (variable: (module: ^0, flags: (linkage: appending, notEligibleToImport: 1, live: 1, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0), refs: (^14)))) ; guid = 2412314959268824392
71^4 = gv: (name: "?foo@S@@UEAAXXZ") ; guid = 6578172636330484861
72^5 = gv: (name: "??_SS@@6B@", summaries: (alias: (module: ^0, flags: (linkage: external, notEligibleToImport: 1, live: 0, dsoLocal: 0, canAutoHide: 0), aliasee: ^10))) ; guid = 8774897714842691026
73^6 = gv: (name: "??_R1A@?0A@EA@S@@8", summaries: (variable: (module: ^0, flags: (linkage: linkonce_odr, notEligibleToImport: 1, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0), refs: (^11, ^1, ^8)))) ; guid = 9397802696236423453
74^7 = gv: (name: "?undefined_ref@@YAXXZ") ; guid = 9774674600202276560
75^8 = gv: (name: "??_R3S@@8", summaries: (variable: (module: ^0, flags: (linkage: linkonce_odr, notEligibleToImport: 1, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0), refs: (^1, ^2)))) ; guid = 10685958509605791599
76^9 = gv: (name: "??_7type_info@@6B@") ; guid = 10826752452437539368
77^10 = gv: (name: "anon.bcb2691509de99310dddb690fcdb4cdc.0", summaries: (variable: (module: ^0, flags: (linkage: private, notEligibleToImport: 1, live: 0, dsoLocal: 1, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0), vTableFuncs: ((virtFunc: ^4, offset: 8)), refs: (^13, ^4)))) ; guid = 11510395461204283992
78^11 = gv: (name: "??_R0?AUS@@@8", summaries: (variable: (module: ^0, flags: (linkage: linkonce_odr, notEligibleToImport: 1, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0), refs: (^9)))) ; guid = 12346607659584231960
79^12 = gv: (name: "?d@@3UInit@@A", summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 1, live: 0, dsoLocal: 1, canAutoHide: 0), varFlags: (readonly: 1, writeonly: 1)))) ; guid = 14563354643524156382
80^13 = gv: (name: "??_R4S@@6B@", summaries: (variable: (module: ^0, flags: (linkage: linkonce_odr, notEligibleToImport: 1, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0), refs: (^13, ^11, ^1, ^8)))) ; guid = 14703528065171087394
81^14 = gv: (name: "_GLOBAL__sub_I_t.cpp", summaries: (function: (module: ^0, flags: (linkage: internal, notEligibleToImport: 1, live: 0, dsoLocal: 1, canAutoHide: 0), insts: 3, calls: ((callee: ^7)), refs: (^12, ^5)))) ; guid = 15085897428757412588
82^15 = typeidCompatibleVTable: (name: "?AUS@@", summary: ((offset: 8, ^10))) ; guid = 13986515119763165370
deps/lld/test/COFF/Inputs/undefined-symbol-lto-b.ll created+29
......@@ -0,0 +1,29 @@
1; ModuleID = 'b.obj'
2source_filename = "b.cpp"
3target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
4target triple = "x86_64-pc-windows-msvc19.21.27702"
5
6%struct.S = type { i32 (...)** }
7
8; Function Attrs: norecurse nounwind readnone sspstrong uwtable
9define dso_local void @"?foo@S@@UEAAXXZ"(%struct.S* nocapture %this) unnamed_addr #0 align 2 {
10entry:
11 ret void
12}
13
14attributes #0 = { norecurse nounwind readnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "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"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
15
16!llvm.linker.options = !{!0, !1}
17!llvm.module.flags = !{!2, !3, !4, !5}
18!llvm.ident = !{!6}
19
20!0 = !{!"/DEFAULTLIB:libcmt.lib"}
21!1 = !{!"/DEFAULTLIB:oldnames.lib"}
22!2 = !{i32 1, !"wchar_size", i32 2}
23!3 = !{i32 7, !"PIC Level", i32 2}
24!4 = !{i32 1, !"ThinLTO", i32 0}
25!5 = !{i32 1, !"EnableSplitLTOUnit", i32 0}
26!6 = !{!"clang version 9.0.0 (git@github.com:llvm/llvm-project.git 1a285c27fdf6407ceed3398e015d00559f5f533d)"}
27
28^0 = module: (path: "b.obj", hash: (0, 0, 0, 0, 0))
29^1 = gv: (name: "?foo@S@@UEAAXXZ", summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 1, live: 0, dsoLocal: 1, canAutoHide: 0), insts: 1, funcFlags: (readNone: 1, readOnly: 0, noRecurse: 1, returnDoesNotAlias: 0, noInline: 0)))) ; guid = 6578172636330484861
deps/lld/test/COFF/allow-unknown-debug-info.test created+26
......@@ -0,0 +1,26 @@
1# RUN: yaml2obj %s > %t.obj
2# RUN: lld-link -safeseh:no /dll /noentry /debug %t.obj 2>&1 | FileCheck %s
3
4# CHECK: ignoring section .debug$S with unrecognized magic 0x1
5
6--- !COFF
7header:
8 Machine: IMAGE_FILE_MACHINE_I386
9 Characteristics: []
10sections:
11 - Name: '.debug$S'
12 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
13 SectionData: 01000000
14symbols:
15 - Name: '.debug$S'
16 Value: 0
17 SectionNumber: 1
18 SimpleType: IMAGE_SYM_TYPE_NULL
19 ComplexType: IMAGE_SYM_DTYPE_NULL
20 StorageClass: IMAGE_SYM_CLASS_STATIC
21 SectionDefinition:
22 Length: 4
23 NumberOfRelocations: 0
24 NumberOfLinenumbers: 0
25 CheckSum: 0
26 Number: 0
deps/lld/test/COFF/arm64-delayimport.yaml+27-26
......@@ -3,35 +3,36 @@
33# RUN: yaml2obj < %s > %t.obj
44# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj %p/Inputs/library-arm64.lib /alternatename:__delayLoadHelper2=main /delayload:library.dll
55# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix DISASM
6# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
6# RUN: llvm-readobj --coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
77
88# DISASM: 140001014: 11 00 00 d0 adrp x17, #8192
99# 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
10# DISASM: 14000101c: 01 00 00 14 b #4 <.text+0x20>
11# DISASM: 140001020: fd 7b b3 a9 stp x29, x30, [sp, #-208]!
12# DISASM: 140001024: fd 03 00 91 mov x29, sp
13# DISASM: 140001028: e0 07 01 a9 stp x0, x1, [sp, #16]
14# DISASM: 14000102c: e2 0f 02 a9 stp x2, x3, [sp, #32]
15# DISASM: 140001030: e4 17 03 a9 stp x4, x5, [sp, #48]
16# DISASM: 140001034: e6 1f 04 a9 stp x6, x7, [sp, #64]
17# DISASM: 140001038: e0 87 02 ad stp q0, q1, [sp, #80]
18# DISASM: 14000103c: e2 8f 03 ad stp q2, q3, [sp, #112]
19# DISASM: 140001040: e4 97 04 ad stp q4, q5, [sp, #144]
20# DISASM: 140001044: e6 9f 05 ad stp q6, q7, [sp, #176]
21# DISASM: 140001048: e1 03 11 aa mov x1, x17
22# DISASM: 14000104c: 00 00 00 b0 adrp x0, #4096
23# DISASM: 140001050: 00 00 00 91 add x0, x0, #0
24# DISASM: 140001054: eb ff ff 97 bl #-84 <.text>
25# DISASM: 140001058: f0 03 00 aa mov x16, x0
26# DISASM: 14000105c: e6 9f 45 ad ldp q6, q7, [sp, #176]
27# DISASM: 140001060: e4 97 44 ad ldp q4, q5, [sp, #144]
28# DISASM: 140001064: e2 8f 43 ad ldp q2, q3, [sp, #112]
29# DISASM: 140001068: e0 87 42 ad ldp q0, q1, [sp, #80]
30# DISASM: 14000106c: e6 1f 44 a9 ldp x6, x7, [sp, #64]
31# DISASM: 140001070: e4 17 43 a9 ldp x4, x5, [sp, #48]
32# DISASM: 140001074: e2 0f 42 a9 ldp x2, x3, [sp, #32]
33# DISASM: 140001078: e0 07 41 a9 ldp x0, x1, [sp, #16]
34# DISASM: 14000107c: fd 7b cd a8 ldp x29, x30, [sp], #208
35# DISASM: 140001080: 00 02 1f d6 br x16
3536
3637# IMPORTS: Format: COFF-ARM64
3738# IMPORTS: Arch: aarch64
deps/lld/test/COFF/arm64-import2.test+3-1
......@@ -4,14 +4,16 @@
44# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE
55# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj %p/Inputs/library-arm64.lib %p/Inputs/library2-arm64.lib
66# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
7# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
7# RUN: llvm-readobj --coff-imports %t.exe | FileCheck %s -check-prefix IMPORTS
88
99# BEFORE: Disassembly of section .text:
10# BEFORE-EMPTY:
1011# BEFORE: 0: 00 00 00 94 bl #0
1112# BEFORE: 4: 00 00 00 94 bl #0
1213# BEFORE: 8: c0 03 5f d6 ret
1314
1415# AFTER: Disassembly of section .text:
16# AFTER-EMPTY:
1517# AFTER: 140001000: 03 00 00 94 bl #12
1618# AFTER: 140001004: 05 00 00 94 bl #20
1719# AFTER: 140001008: c0 03 5f d6 ret
deps/lld/test/COFF/arm64-magic.yaml+1-1
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /entry:mainCRTStartup /subsystem:console %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
44
55# CHECK: Format: COFF-ARM64
66# CHECK: Arch: aarch64
deps/lld/test/COFF/arm64-relocs-imports.test+14-7
......@@ -6,6 +6,7 @@
66# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
77
88# BEFORE: Disassembly of section .text:
9# BEFORE-EMPTY:
910# BEFORE: 0: fe 0f 1f f8 str x30, [sp, #-16]!
1011# BEFORE: 4: 00 00 00 90 adrp x0, #0
1112# BEFORE: 8: 00 08 00 91 add x0, x0, #2
......@@ -45,12 +46,14 @@
4546# BEFORE: 90: 20 1a 09 30 adr x0, #74565
4647# BEFORE: 94: 01 00 00 54 b.ne #0
4748# BEFORE: 98: 00 00 00 36 tbz w0, #0, #0
49# BEFORE: 9c: 01 00 00 00 udf #1
4850
4951# AFTER: Disassembly of section .text:
52# AFTER-EMPTY:
5053# AFTER: 140001000: fe 0f 1f f8 str x30, [sp, #-16]!
5154# AFTER: 140001004: 00 00 00 b0 adrp x0, #4096
5255# AFTER: 140001008: 00 18 00 91 add x0, x0, #6
53# AFTER: 14000100c: 24 00 00 94 bl #144
56# AFTER: 14000100c: 25 00 00 94 bl #148
5457# AFTER: 140001010: 00 21 40 39 ldrb w0, [x8, #8]
5558# AFTER: 140001014: 00 11 40 79 ldrh w0, [x8, #8]
5659# AFTER: 140001018: 00 09 40 b9 ldr w0, [x8, #8]
......@@ -84,11 +87,12 @@
8487# AFTER: 140001088: 00 c4 41 f9 ldr x0, [x0, #904]
8588# AFTER: 14000108c: 03 00 00 00 udf #3
8689# AFTER: 140001090: e0 95 09 30 adr x0, #78525
87# AFTER: 140001094: 41 00 00 54 b.ne #8
88# AFTER: 140001098: 20 00 00 36 tbz w0, #0, #4
89# AFTER: 14000109c: 10 00 00 b0 adrp x16, #4096
90# AFTER: 1400010a0: 10 2a 40 f9 ldr x16, [x16, #80]
91# AFTER: 1400010a4: 00 02 1f d6 br x16
90# AFTER: 140001094: 61 00 00 54 b.ne #12
91# AFTER: 140001098: 40 00 00 36 tbz w0, #0, #8
92# AFTER: 14000109c: 61 ff ff ff <unknown>
93# AFTER: 1400010a0: 10 00 00 b0 adrp x16, #4096
94# AFTER: 1400010a4: 10 2a 40 f9 ldr x16, [x16, #80]
95# AFTER: 1400010a8: 00 02 1f d6 br x16
9296
9397--- !COFF
9498header:
......@@ -98,7 +102,7 @@ sections:
98102 - Name: .text
99103 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
100104 Alignment: 4
101 SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a09300100005400000036
105 SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a0930010000540000003601000000
102106 Relocations:
103107 - VirtualAddress: 4
104108 SymbolName: .Lstr
......@@ -202,6 +206,9 @@ sections:
202206 - VirtualAddress: 152
203207 SymbolName: function
204208 Type: IMAGE_REL_ARM64_BRANCH14
209 - VirtualAddress: 156
210 SymbolName: main
211 Type: IMAGE_REL_ARM64_REL32
205212 - Name: .data
206213 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
207214 Alignment: 4
deps/lld/test/COFF/armnt-blx23t.test+2
......@@ -6,6 +6,7 @@
66# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
77
88# BEFORE: Disassembly of section .text:
9# BEFORE-EMPTY:
910# BEFORE: 0: 70 47 bx lr
1011# BEFORE: 2: 00 bf nop
1112# BEFORE: 4: 2d e9 00 48 push.w {r11, lr}
......@@ -16,6 +17,7 @@
1617# BEFORE: 12: bd e8 00 88 pop.w {r11, pc}
1718
1819# AFTER: Disassembly of section .text:
20# AFTER-EMPTY:
1921# AFTER: 1000: 70 47 bx lr
2022# AFTER: 1002: 00 bf nop
2123# AFTER: 1004: 2d e9 00 48 push.w {r11, lr}
deps/lld/test/COFF/armnt-branch24t.test+2
......@@ -6,12 +6,14 @@
66# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
77
88# BEFORE: Disassembly of section .text:
9# BEFORE-EMPTY:
910# BEFORE: 0: 70 47 bx lr
1011# BEFORE: 2: 00 bf nop
1112# BEFORE: 4: 20 20 movs r0, #32
1213# BEFORE: 6: 00 f0 00 b8 b.w #0
1314
1415# AFTER: Disassembly of section .text:
16# AFTER-EMPTY:
1517# AFTER: .text:
1618# AFTER: 1000: 70 47 bx lr
1719# AFTER: 1002: 00 bf nop
deps/lld/test/COFF/armnt-entry-point.test+1-1
......@@ -1,5 +1,5 @@
11# RUN: yaml2obj < %p/Inputs/armnt-executable.obj.yaml > %t.obj
22# RUN: lld-link /out:%t.exe /entry:mainCRTStartup /subsystem:console %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
44
55CHECK: AddressOfEntryPoint: 0x1001
deps/lld/test/COFF/armnt-imports.test+1-1
......@@ -1,7 +1,7 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /subsystem:console %t.obj \
33# RUN: /entry:mainCRTStartup %p/Inputs/library.lib
4# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s
4# RUN: llvm-readobj --coff-imports %t.exe | FileCheck %s
55
66# CHECK: Import {
77# CHECK: Name: library.dll
deps/lld/test/COFF/armnt-mov32t-exec.test+2
......@@ -6,6 +6,7 @@
66# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
77
88# BEFORE: Disassembly of section .text:
9# BEFORE-EMPTY:
910# BEFORE: 0: 70 47 bx lr
1011# BEFORE: 2: 00 bf nop
1112# BEFORE: 4: 40 f2 00 00 movw r0, #0
......@@ -13,6 +14,7 @@
1314# BEFORE: c: 70 47 bx lr
1415
1516# AFTER: Disassembly of section .text:
17# AFTER-EMPTY:
1618# AFTER: 1000: 70 47 bx lr
1719# AFTER: 1002: 00 bf nop
1820# AFTER: 1004: 41 f2 01 00 movw r0, #4097
deps/lld/test/COFF/armnt-movt32t.test+2
......@@ -6,11 +6,13 @@
66# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
77
88# BEFORE: Disassembly of section .text:
9# BEFORE-EMPTY:
910# BEFORE: 0: 40 f2 00 00 movw r0, #0
1011# BEFORE: 4: c0 f2 00 00 movt r0, #0
1112# BEFORE: 8: 70 47 bx lr
1213
1314# AFTER: Disassembly of section .text:
15# AFTER-EMPTY:
1416# AFTER: 0: 42 f2 00 00 movw r0, #8192
1517# AFTER: 4: c0 f2 40 00 movt r0, #64
1618# AFTER: 8: 70 47 bx lr
deps/lld/test/COFF/armnt-rel32.yaml created+47
......@@ -0,0 +1,47 @@
1# REQUIRES: arm
2
3# RUN: yaml2obj < %s > %t.obj
4# RUN: llvm-objdump -s %t.obj | FileCheck %s -check-prefix BEFORE
5# RUN: lld-link /entry:function /subsystem:console /out:%t.exe %t.obj
6# RUN: llvm-objdump -s %t.exe | FileCheck %s -check-prefix AFTER
7
8# BEFORE: Contents of section .text:
9# BEFORE: 0000 704700bf 01000000 01000000
10
11# AFTER: Contents of section .text:
12# AFTER: 401000 704700bf faffffff f50f0000
13
14--- !COFF
15header:
16 Machine: IMAGE_FILE_MACHINE_ARMNT
17 Characteristics: []
18sections:
19 - Name: .text
20 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
21 Alignment: 4
22 SectionData: 704700BF0100000001000000
23 Relocations:
24 - VirtualAddress: 4
25 SymbolName: function
26 Type: IMAGE_REL_ARM_REL32
27 - VirtualAddress: 8
28 SymbolName: data
29 Type: IMAGE_REL_ARM_REL32
30 - Name: .rdata
31 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
32 Alignment: 1
33 SectionData: 00
34symbols:
35 - Name: function
36 Value: 0
37 SectionNumber: 1
38 SimpleType: IMAGE_SYM_TYPE_NULL
39 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
40 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
41 - Name: data
42 Value: 0
43 SectionNumber: 2
44 SimpleType: IMAGE_SYM_TYPE_NULL
45 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
46 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
47...
deps/lld/test/COFF/associative-comdat-empty.test created+56
......@@ -0,0 +1,56 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck %s
3
4# Tests an associative comdat being associated with an empty section errors.
5# CHECK: lld-link: error: {{.*}}: associative comdat .text$ac1 (sec 1) has invalid reference to section .text$nm (sec 2)
6# CHECK-NOT: lld-link: error:
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_AMD64
11 Characteristics: [ ]
12sections:
13 - Name: '.text$ac1'
14 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
15 Alignment: 1
16 SectionData: '01000000'
17 - Name: '.text$nm'
18 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
19 Alignment: 1
20 SectionData: '01000000'
21symbols:
22 - Name: '.text$ac1'
23 Value: 0
24 SectionNumber: 1
25 SimpleType: IMAGE_SYM_TYPE_NULL
26 ComplexType: IMAGE_SYM_DTYPE_NULL
27 StorageClass: IMAGE_SYM_CLASS_STATIC
28 SectionDefinition:
29 Length: 4
30 NumberOfRelocations: 0
31 NumberOfLinenumbers: 0
32 CheckSum: 3099354981
33 Number: 2
34 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
35 - Name: '.text$nm'
36 Value: 0
37 SectionNumber: 2
38 SimpleType: IMAGE_SYM_TYPE_NULL
39 ComplexType: IMAGE_SYM_DTYPE_NULL
40 StorageClass: IMAGE_SYM_CLASS_STATIC
41 SectionDefinition:
42 Length: 0
43 NumberOfRelocations: 0
44 NumberOfLinenumbers: 0
45 CheckSum: 3099354981
46 Number: 4
47 Selection: IMAGE_COMDAT_SELECT_ANY
48 - Name: assocsym
49 Value: 0
50 SectionNumber: 1
51 SimpleType: IMAGE_SYM_TYPE_NULL
52 ComplexType: IMAGE_SYM_DTYPE_NULL
53 StorageClass: IMAGE_SYM_CLASS_STATIC
54...
55
56
deps/lld/test/COFF/associative-comdat-mingw-i386.s created+37
......@@ -0,0 +1,37 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj
4
5# RUN: lld-link -lldmingw -entry:main %t.obj -out:%t.exe
6# RUN: llvm-objdump -s %t.exe | FileCheck %s
7
8# Check that the .eh_frame comdat was included, even if it had no symbols,
9# due to associativity with the symbol _foo.
10
11# CHECK: Contents of section .eh_fram:
12# CHECK: 403000 42
13
14 .text
15 .def _main;
16 .scl 2;
17 .type 32;
18 .endef
19 .globl _main
20 .p2align 4, 0x90
21_main:
22 call _foo
23 ret
24
25 .section .eh_frame$foo,"dr"
26 .linkonce discard
27 .byte 0x42
28
29 .def _foo;
30 .scl 2;
31 .type 32;
32 .endef
33 .section .text$foo,"xr",discard,foo
34 .globl _foo
35 .p2align 4
36_foo:
37 ret
deps/lld/test/COFF/associative-comdat-mingw.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/associative-comdat-mingw-2.s -filetype=obj -o %t2.obj
55
66# RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.gc.exe -verbose
7# RUN: llvm-readobj -sections %t.gc.exe | FileCheck %s
7# RUN: llvm-readobj --sections %t.gc.exe | FileCheck %s
88
99# CHECK: Sections [
1010# CHECK: Section {
deps/lld/test/COFF/associative-comdat-order.test created+97
......@@ -0,0 +1,97 @@
1# Tests that an associative comdat being associated with another
2# associated comdat later in the file produces an error.
3# RUN: sed -e s/ASSOC1/2/ -e s/ASSOC2/3/ %s | yaml2obj > %t.obj
4# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck --check-prefix=FORWARD %s
5# FORWARD: lld-link: error: {{.*}}: associative comdat .text$ac1 (sec 1) has invalid reference to section .text$ac2 (sec 2)
6# FORWARD-NOT: lld-link: error:
7
8# Tests that an associative comdat being associated with another
9# associated comdat earlier in the file works.
10# RUN: sed -e s/ASSOC1/3/ -e s/ASSOC2/1/ %s | yaml2obj > %t.obj
11
12# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe
13# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=BACKWARD %s
14# BACKWARD: Contents of section .text:
15# BACKWARD: 180001000 01000000 02000000 03000000 ............
16
17# RUN: lld-link /dll /noentry /nodefaultlib %t.obj /out:%t.exe
18# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=BACKWARDDROP %s
19# BACKWARDDROP-NOT: Contents of section .text:
20
21--- !COFF
22header:
23 Machine: IMAGE_FILE_MACHINE_AMD64
24 Characteristics: [ ]
25sections:
26 - Name: '.text$ac1'
27 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
28 Alignment: 1
29 SectionData: '01000000'
30 - Name: '.text$ac2'
31 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
32 Alignment: 1
33 SectionData: '02000000'
34 - Name: '.text$nm'
35 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
36 Alignment: 1
37 SectionData: '03000000'
38symbols:
39 - Name: '.text$ac1'
40 Value: 0
41 SectionNumber: 1
42 SimpleType: IMAGE_SYM_TYPE_NULL
43 ComplexType: IMAGE_SYM_DTYPE_NULL
44 StorageClass: IMAGE_SYM_CLASS_STATIC
45 SectionDefinition:
46 Length: 4
47 NumberOfRelocations: 0
48 NumberOfLinenumbers: 0
49 CheckSum: 3099354981
50 Number: ASSOC1
51 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
52 - Name: '.text$ac2'
53 Value: 0
54 SectionNumber: 2
55 SimpleType: IMAGE_SYM_TYPE_NULL
56 ComplexType: IMAGE_SYM_DTYPE_NULL
57 StorageClass: IMAGE_SYM_CLASS_STATIC
58 SectionDefinition:
59 Length: 4
60 NumberOfRelocations: 0
61 NumberOfLinenumbers: 0
62 CheckSum: 3099354981
63 Number: ASSOC2
64 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
65 - Name: '.text$nm'
66 Value: 0
67 SectionNumber: 3
68 SimpleType: IMAGE_SYM_TYPE_NULL
69 ComplexType: IMAGE_SYM_DTYPE_NULL
70 StorageClass: IMAGE_SYM_CLASS_STATIC
71 SectionDefinition:
72 Length: 4
73 NumberOfRelocations: 0
74 NumberOfLinenumbers: 0
75 CheckSum: 3099354981
76 Number: 4
77 Selection: IMAGE_COMDAT_SELECT_ANY
78 - Name: symbol
79 Value: 0
80 SectionNumber: 3
81 SimpleType: IMAGE_SYM_TYPE_NULL
82 ComplexType: IMAGE_SYM_DTYPE_NULL
83 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
84 - Name: assocsym2
85 Value: 0
86 SectionNumber: 1
87 SimpleType: IMAGE_SYM_TYPE_NULL
88 ComplexType: IMAGE_SYM_DTYPE_NULL
89 StorageClass: IMAGE_SYM_CLASS_STATIC
90 - Name: assocsym
91 Value: 0
92 SectionNumber: 2
93 SimpleType: IMAGE_SYM_TYPE_NULL
94 ComplexType: IMAGE_SYM_DTYPE_NULL
95 StorageClass: IMAGE_SYM_CLASS_STATIC
96...
97
deps/lld/test/COFF/associative-comdat.s+2-2
......@@ -3,10 +3,10 @@
33# RUN: llvm-mc -triple=x86_64-windows-msvc %S/Inputs/associative-comdat-2.s -filetype=obj -o %t2.obj
44
55# RUN: lld-link -entry:main %t1.obj %t2.obj -out:%t.gc.exe
6# RUN: llvm-readobj -sections %t.gc.exe | FileCheck %s
6# RUN: llvm-readobj --sections %t.gc.exe | FileCheck %s
77
88# RUN: lld-link -entry:main %t1.obj %t2.obj -opt:noref -out:%t.nogc.exe
9# RUN: llvm-readobj -sections %t.nogc.exe | FileCheck %s
9# RUN: llvm-readobj --sections %t.nogc.exe | FileCheck %s
1010
1111# CHECK: Sections [
1212# CHECK: Section {
deps/lld/test/COFF/autoimport-arm-data.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: llvm-mc -triple=armv7-windows-gnu %s -filetype=obj -o %t.obj
88# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
99
10# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
10# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
1111# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
1212
1313# IMPORTS: Import {
deps/lld/test/COFF/autoimport-arm64-data.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: llvm-mc -triple=aarch64-windows-gnu %s -filetype=obj -o %t.obj
88# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
99
10# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
10# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
1111# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
1212
1313# IMPORTS: Import {
deps/lld/test/COFF/autoimport-gnu-implib.s+1-1
......@@ -9,7 +9,7 @@
99# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
1010# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-implib.a -verbose
1111
12# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
12# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
1313
1414# IMPORTS: Import {
1515# IMPORTS-NEXT: Name: foo.dll
deps/lld/test/COFF/autoimport-refptr.s+2-1
......@@ -7,7 +7,7 @@
77# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
88# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
99
10# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
10# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
1111# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
1212# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
1313
......@@ -19,6 +19,7 @@
1919# IMPORTS-NEXT: }
2020
2121# DISASM: Disassembly of section .text:
22# DISASM-EMPTY:
2223# DISASM: .text:
2324# Relative offset at 0x1002 pointing at the IAT at 0x2060
2425# DISASM: 140001000: 48 8b 05 59 10 00 00 movq 4185(%rip), %rax
deps/lld/test/COFF/autoimport-x86.s+2-1
......@@ -7,7 +7,7 @@
77# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
88# RUN: lld-link -lldmingw -out:%t.exe -entry:main %t.obj %t-lib.lib -verbose
99
10# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
10# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
1111# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
1212# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=CONTENTS %s
1313
......@@ -19,6 +19,7 @@
1919# IMPORTS-NEXT: }
2020
2121# DISASM: Disassembly of section .text:
22# DISASM-EMPTY:
2223# DISASM: .text:
2324# Relative offset at 0x1002 pointing at the IAT at 0x2080.
2425# DISASM: 140001000: 8b 05 7a 10 00 00 movl 4218(%rip), %eax
deps/lld/test/COFF/base.test+2-2
......@@ -1,7 +1,7 @@
11# RUN: yaml2obj < %s > %t.obj
22
33# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT-HEADER %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=DEFAULT-HEADER %s
55# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DEFAULT-TEXT %s
66
77# DEFAULT-HEADER: ImageBase: 0x140000000
......@@ -9,7 +9,7 @@
99# DEFAULT-TEXT-NEXT: 1000 00000040 01000000
1010
1111# RUN: lld-link /out:%t.exe /entry:main %t.obj /base:0x280000000
12# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BASE-HEADER %s
12# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=BASE-HEADER %s
1313# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=BASE-TEXT %s
1414
1515# BASE-HEADER: ImageBase: 0x280000000
deps/lld/test/COFF/baserel.test+4-4
......@@ -1,10 +1,10 @@
11# RUN: yaml2obj < %s > %t.obj
22#
33# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
4# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck %s -check-prefix=BASEREL
4# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck %s -check-prefix=BASEREL
55#
66# RUN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib
7# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck %s -check-prefix=NOBASEREL
7# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck %s -check-prefix=NOBASEREL
88#
99# BASEREL: BaseReloc [
1010# BASEREL-NEXT: Entry {
......@@ -44,11 +44,11 @@
4444# NOBASEREL-NEXT: ]
4545#
4646# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
47# RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck %s \
47# RUN: llvm-readobj --file-headers --sections %t.exe | FileCheck %s \
4848# RUN: --check-prefix=BASEREL-HEADER
4949#
5050# 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 \
51# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s \
5252# RUN: --check-prefix=NOBASEREL-HEADER
5353#
5454# BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED
deps/lld/test/COFF/color-diagnostics.test created+18
......@@ -0,0 +1,18 @@
1# Windows command prompt doesn't support ANSI escape sequences.
2# REQUIRES: shell
3
4# RUN: not lld-link -xyz --color-diagnostics /nosuchfile 2>&1 \
5# RUN: | FileCheck -check-prefix=COLOR %s
6# RUN: not lld-link -xyz --color-diagnostics=always /nosuchfile 2>&1 \
7# RUN: | FileCheck -check-prefix=COLOR %s
8
9# COLOR: {{lld-link: .\[0;1;35mwarning: .\[0mignoring unknown argument '-xyz'}}
10# COLOR: {{lld-link: .\[0;1;31merror: .\[0mcould not open '/nosuchfile'}}
11
12# RUN: not lld-link /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
13# RUN: not lld-link -color-diagnostics=never /nosuchfile 2>&1 \
14# RUN: | FileCheck -check-prefix=NOCOLOR %s
15# RUN: not lld-link -color-diagnostics=always -no-color-diagnostics \
16# RUN: /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
17
18# NOCOLOR: lld-link: error: could not open '/nosuchfile'
deps/lld/test/COFF/combined-resources.test+1-1
......@@ -8,7 +8,7 @@
88# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res \
99# RUN: %p/Inputs/combined-resources.res %p/Inputs/combined-resources-2.res
1010
11# RUN: llvm-readobj -coff-resources -file-headers -section-data %t.exe | \
11# RUN: llvm-readobj --coff-resources --file-headers --section-data %t.exe | \
1212# RUN: FileCheck %s
1313
1414CHECK: ResourceTableRVA: 0x2000
deps/lld/test/COFF/comdat-selection-associative-largest.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: x86
2
3# Tests handling of several comdats with "largest" selection type that each
4# has an associative comdat.
5
6# Create obj files.
7# RUN: sed -e s/TYPE/.byte/ -e s/SIZE/1/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.1.obj
8# RUN: sed -e s/TYPE/.short/ -e s/SIZE/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.2.obj
9# RUN: sed -e s/TYPE/.long/ -e s/SIZE/4/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.4.obj
10
11 .section .text$ac, "", associative, symbol
12assocsym:
13 .long SIZE
14
15 .section .text$nm, "", largest, symbol
16 .globl symbol
17symbol:
18 TYPE SIZE
19
20# Pass the obj files in different orders and check that only the associative
21# comdat of the largest obj file makes it into the output, independent of
22# the order of the obj files on the command line.
23
24# FIXME: Make these pass when /opt:noref is passed.
25
26# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.1.obj %t.2.obj %t.4.obj /out:%t.exe
27# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL124 %s
28# ALL124: Contents of section .text:
29# ALL124: 180001000 04000000 04000000 ....
30
31# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.4.obj %t.2.obj %t.1.obj /out:%t.exe
32# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL421 %s
33# ALL421: Contents of section .text:
34# ALL421: 180001000 04000000 04000000 ....
35
36# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.2.obj %t.4.obj %t.1.obj /out:%t.exe
37# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=ALL241 %s
38# ALL241: Contents of section .text:
39# ALL241: 180001000 04000000 04000000 ....
40
41# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.2.obj %t.1.obj /out:%t.exe
42# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=JUST21 %s
43# JUST21: Contents of section .text:
44# JUST21: 180001000 02000000 0200 ....
45
deps/lld/test/COFF/comdat-selection.s created+107
......@@ -0,0 +1,107 @@
1# REQUIRES: x86
2
3# Tests handling of the comdat selection type.
4# (Except associative which is tested in associative-comdat.s and
5# comdat-selection-associate-largest.s instead.)
6
7# Create obj files with each selection type.
8# RUN: sed -e s/SEL/discard/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.discard.obj
9# RUN: sed -e s/SEL/discard/ -e s/.long/.short/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.discard.short.2.obj
10# RUN: sed -e s/SEL/one_only/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.one_only.obj
11# RUN: sed -e s/SEL/same_size/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_size.obj
12# RUN: sed -e s/SEL/same_size/ -e s/.long/.short/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_size.short.obj
13# RUN: sed -e s/SEL/same_contents/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.obj
14# RUN: sed -e s/SEL/same_contents/ -e s/.long/.short/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.short.obj
15# RUN: sed -e s/SEL/same_contents/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.same_contents.2.obj
16# RUN: sed -e s/SEL/largest/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.largest.obj
17# RUN: sed -e s/SEL/largest/ -e s/.long/.short/ -e s/1/2/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.largest.short.2.obj
18# RUN: sed -e s/SEL/newest/ %s | llvm-mc -triple x86_64-pc-win32 -filetype=obj -o %t.newest.obj
19
20 .section .text$nm, "", SEL, symbol
21 .globl symbol
22symbol:
23 .long 1
24
25# First, pass each selection type twice. All should link fine except for
26# one_only which should report a duplicate symbol error and newest which
27# link.exe (and hence lld-link) doesn't understand.
28
29# RUN: cp %t.discard.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.discard.obj %t.obj
30# RUN: cp %t.one_only.obj %t.obj && not lld-link /dll /noentry /nodefaultlib %t.one_only.obj %t.obj 2>&1 | FileCheck --check-prefix=ONEONE %s
31# ONEONE: lld-link: error: duplicate symbol: symbol
32# RUN: cp %t.same_size.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.same_size.obj %t.obj
33# RUN: cp %t.same_contents.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.obj
34# RUN: cp %t.largest.obj %t.obj && lld-link /dll /noentry /nodefaultlib %t.largest.obj %t.obj
35# RUN: cp %t.newest.obj %t.obj && not lld-link /dll /noentry /nodefaultlib %t.newest.obj %t.obj 2>&1 | FileCheck --check-prefix=NEWNEW %s
36# NEWNEW: lld-link: error: unknown comdat type 7 for symbol
37
38# /force doesn't affect errors about unknown comdat types.
39# RUN: cp %t.newest.obj %t.obj && not lld-link /force /dll /noentry /nodefaultlib %t.newest.obj %t.obj 2>&1 | FileCheck --check-prefix=NEWNEWFORCE %s
40# NEWNEWFORCE: lld-link: error: unknown comdat type 7 for symbol
41
42# Check that same_size, same_contents, largest do what they're supposed to.
43
44# Check that the "same_size" selection produces an error if passed two symbols
45# with different size.
46# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_size.obj %t.same_size.short.obj 2>&1 | FileCheck --check-prefix=SAMESIZEDUPE %s
47# SAMESIZEDUPE: lld-link: error: duplicate symbol: symbol
48
49# Check that the "same_contents" selection produces an error if passed two
50# symbols with different contents.
51# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_contents.2.obj 2>&1 | FileCheck --check-prefix=SAMECONTENTSDUPE1 %s
52# SAMECONTENTSDUPE1: lld-link: error: duplicate symbol: symbol
53# RUN: not lld-link /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_contents.2.obj 2>&1 | FileCheck --check-prefix=SAMECONTENTSDUPE2 %s
54# SAMECONTENTSDUPE2: lld-link: error: duplicate symbol: symbol
55
56# Check that the "largest" selection picks the larger comdat (independent of
57# the order the .obj files are passed on the commandline).
58# RUN: lld-link /opt:noref /include:symbol /dll /noentry /nodefaultlib %t.largest.obj %t.largest.short.2.obj /out:%t.exe
59# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGEST1 %s
60# LARGEST1: Contents of section .text:
61# LARGEST1: 180001000 01000000 ....
62
63# FIXME: Make this pass when /opt:noref is passed.
64# RUN: lld-link /include:symbol /dll /noentry /nodefaultlib %t.largest.short.2.obj %t.largest.obj /out:%t.exe
65# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGEST2 %s
66# LARGEST2: Contents of section .text:
67# LARGEST2: 180001000 01000000 ....
68
69
70# Test linking the same symbol with different comdat selection types.
71# link.exe generally rejects this, except for "largest" which is allowed to
72# combine with everything (https://bugs.llvm.org/show_bug.cgi?id=40094#c7).
73# lld-link rejects all comdat selection type mismatches. Spot-test just a few
74# combinations.
75
76# RUN: not lld-link /verbose /dll /noentry /nodefaultlib %t.discard.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=DISCARDONE %s
77# DISCARDONE: lld-link: conflicting comdat type for symbol: 2 in
78# DISCARDONE: lld-link: error: duplicate symbol: symbol
79# RUN: lld-link /verbose /force /dll /noentry /nodefaultlib %t.discard.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=DISCARDONEFORCE %s
80# DISCARDONEFORCE: lld-link: conflicting comdat type for symbol: 2 in
81# DISCARDONEFORCE: lld-link: warning: duplicate symbol: symbol
82
83# Make sure the error isn't depending on the order of .obj files.
84# RUN: not lld-link /verbose /dll /noentry /nodefaultlib %t.one_only.obj %t.discard.obj 2>&1 | FileCheck --check-prefix=ONEDISCARD %s
85# ONEDISCARD: lld-link: conflicting comdat type for symbol: 1 in
86# ONEDISCARD: lld-link: error: duplicate symbol: symbol
87
88# RUN: not lld-link /verbose /dll /noentry /nodefaultlib %t.same_contents.obj %t.same_size.obj 2>&1 | FileCheck --check-prefix=CONTENTSSIZE %s
89# CONTENTSSIZE: lld-link: conflicting comdat type for symbol: 4 in
90# CONTENTSSIZE: lld-link: error: duplicate symbol: symbol
91
92# Check that linking one 'discard' and one 'largest' has the effect of
93# 'largest'.
94# RUN: lld-link /dll /noentry /nodefaultlib %t.discard.short.2.obj %t.largest.obj
95# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=DISCARDLARGEST %s
96# DISCARDLARGEST: Contents of section .text:
97# DISCARDLARGEST: 180001000 01000000 ....
98# RUN: lld-link /dll /noentry /nodefaultlib %t.largest.obj %t.discard.short.2.obj
99# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=LARGESTDISCARD %s
100# LARGESTDISCARD: Contents of section .text:
101# LARGESTDISCARD: 180001000 01000000 ....
102
103
104# These cases are accepted by link.exe but not by lld-link.
105# RUN: not lld-link /verbose /dll /noentry /nodefaultlib %t.largest.obj %t.one_only.obj 2>&1 | FileCheck --check-prefix=LARGESTONE %s
106# LARGESTONE: lld-link: conflicting comdat type for symbol: 6 in
107# LARGESTONE: lld-link: error: duplicate symbol: symbol
deps/lld/test/COFF/common-replacement.s+1-1
......@@ -5,7 +5,7 @@
55
66# RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.exe -verbose 2>&1 \
77# RUN: | FileCheck -check-prefix VERBOSE %s
8# RUN: llvm-readobj -s %t.exe | FileCheck -check-prefix SECTIONS %s
8# RUN: llvm-readobj -S %t.exe | FileCheck -check-prefix SECTIONS %s
99
1010# VERBOSE: -aligncomm:"foo",2
1111
deps/lld/test/COFF/common.test+1-1
......@@ -79,7 +79,7 @@ symbols:
7979 ComplexType: IMAGE_SYM_DTYPE_NULL
8080 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
8181 - Name: bssdata16
82 Value: 16
82 Value: 15
8383 SectionNumber: 0
8484 SimpleType: IMAGE_SYM_TYPE_NULL
8585 ComplexType: IMAGE_SYM_DTYPE_NULL
deps/lld/test/COFF/conflict-mangled.test+5-2
......@@ -1,10 +1,13 @@
1# REQUIRES: system-windows
21# RUN: yaml2obj < %s > %t1.obj
32# RUN: yaml2obj < %s > %t2.obj
43# RUN: not lld-link /out:%t.exe %t1.obj %t2.obj >& %t.log
54# RUN: FileCheck %s < %t.log
5# RUN: not lld-link /out:%t.exe /demangle %t1.obj %t2.obj 2>&1 | FileCheck %s
6# RUN: not lld-link /out:%t.exe /demangle:no %t1.obj %t2.obj 2>&1 | FileCheck --check-prefix=NODEMANGLE %s
67
7# CHECK: duplicate symbol: "int __cdecl mangled(void)" (?mangled@@YAHXZ) in {{.+}}1.obj and in {{.+}}2.obj
8# NODEMANGLE: duplicate symbol: ?mangled@@YAHXZ in {{.+}}1.obj and in {{.+}}2.obj
9
10# CHECK: duplicate symbol: int __cdecl mangled(void) in {{.+}}1.obj and in {{.+}}2.obj
811
912--- !COFF
1013header:
deps/lld/test/COFF/constant-export.test+1-1
......@@ -1,7 +1,7 @@
11# RUN: mkdir -p %t
22# RUN: yaml2obj -o %t/constant-export.obj %s
33# RUN: lld-link /machine:x86 /dll /entry:__CFConstantStringClassReference -out:%t/constant-export.dll %t/constant-export.obj
4# RUN: llvm-readobj -coff-exports %t/constant-export.lib | FileCheck %s
4# RUN: llvm-readobj --coff-exports %t/constant-export.lib | FileCheck %s
55
66# CHECK: Type: const
77# CHECK: Name type: noprefix
deps/lld/test/COFF/constant.test+2-2
......@@ -2,5 +2,5 @@ REQUIRES: x86
22RUN: mkdir -p %t
33RUN: llvm-mc -triple i686-unknown-windows-msvc -filetype obj -o %t/import.o %S/Inputs/constant-import.s
44RUN: llc -mtriple i686-unknown-windows-msvc -filetype obj -o %t/export.o %S/Inputs/constant-export.ll
5RUN: lld-link -machine:x86 -dll -out:%t/export.dll %t/export.o -entry:__CFConstantStringClassReference
6RUN: lld-link -machine:x86 -dll -out:%t/import.dll %t/import.o %t/export.lib
5RUN: lld-link -safeseh:no -machine:x86 -dll -out:%t/export.dll %t/export.o -entry:__CFConstantStringClassReference
6RUN: lld-link -safeseh:no -machine:x86 -dll -out:%t/import.dll %t/import.o %t/export.lib
deps/lld/test/COFF/could-not-open.test+1-1
......@@ -1,5 +1,5 @@
11RUN: not lld-link 01 2>&1 | FileCheck %s
22
3CHECK: could not open 01
3CHECK: could not open '01'
44CHECK-NOT: /machine is not specified
55CHECK-NOT: subsystem must be defined
deps/lld/test/COFF/crt-chars.test+1-1
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj %s > %t.obj
22# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj
3# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s
3# RUN: llvm-readobj --sections --section-data %t.dll | FileCheck %s
44
55# CHECK: Name: .CRT
66# CHECK: Characteristics [
deps/lld/test/COFF/crt-dyn-initializer-order.test+100-100
......@@ -1,100 +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...
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/debug-reloc.s+4-4
......@@ -3,10 +3,10 @@
33# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
44
55# RUN: lld-link -lldmingw -debug:dwarf -out:%t.exe -entry:mainfunc -subsystem:console %t.obj
6# RUN: llvm-readobj -sections %t.exe | FileCheck %s -check-prefix SECTIONS
7# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck %s -check-prefix RELOCS
8# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s -check-prefix HEADERS
9# RUN: llvm-readobj -coff-debug-directory %t.exe | FileCheck %s -check-prefix DEBUG
6# RUN: llvm-readobj --sections %t.exe | FileCheck %s -check-prefix SECTIONS
7# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck %s -check-prefix RELOCS
8# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s -check-prefix HEADERS
9# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s -check-prefix DEBUG
1010
1111# SECTIONS: Number: 3
1212# SECTIONS-NEXT: Name: .buildid (2E 62 75 69 6C 64 69 64)
deps/lld/test/COFF/def-export-stdcall.s+7-7
......@@ -1,9 +1,9 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o %t.obj
33# RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall\n fastcall\n vectorcall\n _underscored" > %t.def
4# RUN: lld-link -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib
4# RUN: lld-link -safeseh:no -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib
55# RUN: llvm-readobj %t.lib | FileCheck -check-prefix UNDECORATED-IMPLIB %s
6# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix UNDECORATED-EXPORTS %s
6# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix UNDECORATED-EXPORTS %s
77
88# UNDECORATED-IMPLIB: Name type: noprefix
99# UNDECORATED-IMPLIB-NEXT: __imp___underscored
......@@ -25,9 +25,9 @@
2525
2626
2727# RUN: echo -e "LIBRARY foo\nEXPORTS\n _stdcall@8\n @fastcall@8\n vectorcall@@8" > %t.def
28# RUN: lld-link -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib
28# RUN: lld-link -safeseh:no -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib
2929# RUN: llvm-readobj %t.lib | FileCheck -check-prefix DECORATED-IMPLIB %s
30# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix DECORATED-EXPORTS %s
30# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix DECORATED-EXPORTS %s
3131
3232# DECORATED-IMPLIB: Name type: name
3333# DECORATED-IMPLIB-NEXT: __imp_@fastcall@8
......@@ -48,7 +48,7 @@
4848# RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall@8\n @fastcall@8\n vectorcall@@8" > %t.def
4949# RUN: lld-link -lldmingw -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib
5050# RUN: llvm-readobj %t.lib | FileCheck -check-prefix DECORATED-MINGW-IMPLIB %s
51# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix DECORATED-MINGW-EXPORTS %s
51# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix DECORATED-MINGW-EXPORTS %s
5252
5353# DECORATED-MINGW-IMPLIB: Name type: name
5454# DECORATED-MINGW-IMPLIB-NEXT: __imp_@fastcall@8
......@@ -68,11 +68,11 @@
6868
6969# RUN: lld-link -lldmingw -kill-at -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib
7070# RUN: llvm-readobj %t.lib | FileCheck -check-prefix MINGW-KILL-AT-IMPLIB %s
71# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix MINGW-KILL-AT-EXPORTS %s
71# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix MINGW-KILL-AT-EXPORTS %s
7272
7373# RUN: lld-link -lldmingw -kill-at -entry:dllmain -dll %t.obj -out:%t.dll -implib:%t.lib
7474# RUN: llvm-readobj %t.lib | FileCheck -check-prefix MINGW-KILL-AT-IMPLIB %s
75# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix MINGW-KILL-AT-EXPORTS %s
75# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix MINGW-KILL-AT-EXPORTS %s
7676
7777# MINGW-KILL-AT-IMPLIB: Name type: noprefix
7878# MINGW-KILL-AT-IMPLIB: __imp__fastcall
deps/lld/test/COFF/delayimports-armnt.yaml+5-4
......@@ -3,8 +3,8 @@
33# RUN: lld-link %t.obj %p/Inputs/library.lib /subsystem:console \
44# RUN: /entry:mainCRTStartup /alternatename:__delayLoadHelper2=mainCRTStartup \
55# RUN: /delayload:library.dll /out:%t.exe
6# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
7# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
6# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
7# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
88# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
99
1010# IMPORT: Format: COFF-ARM
......@@ -35,7 +35,7 @@
3535# BASEREL-NEXT: }
3636# BASEREL-NEXT: Entry {
3737# BASEREL-NEXT: Type: ARM_MOV32(T)
38# BASEREL-NEXT: Address: 0x1022
38# BASEREL-NEXT: Address: 0x1026
3939# BASEREL-NEXT: }
4040# BASEREL-NEXT: Entry {
4141# BASEREL-NEXT: Type: ABSOLUTE
......@@ -53,13 +53,14 @@
5353#
5454# DISASM: 40100c: 43 f2 08 0c movw r12, #12296
5555# DISASM-NEXT: c0 f2 40 0c movt r12, #64
56# DISASM-NEXT: 00 f0 00 b8 b.w #0
5657# DISASM-NEXT: 2d e9 0f 48 push.w {r0, r1, r2, r3, r11, lr}
5758# DISASM-NEXT: 0d f2 10 0b addw r11, sp, #16
5859# DISASM-NEXT: 2d ed 10 0b vpush {d0, d1, d2, d3, d4, d5, d6, d7}
5960# DISASM-NEXT: 61 46 mov r1, r12
6061# DISASM-NEXT: 42 f2 00 00 movw r0, #8192
6162# DISASM-NEXT: c0 f2 40 00 movt r0, #64
62# DISASM-NEXT: ff f7 e9 ff bl #-46
63# DISASM-NEXT: ff f7 e7 ff bl #-50
6364# DISASM-NEXT: 84 46 mov r12, r0
6465# DISASM-NEXT: bd ec 10 0b vpop {d0, d1, d2, d3, d4, d5, d6, d7}
6566# DISASM-NEXT: bd e8 0f 48 pop.w {r0, r1, r2, r3, r11, lr}
deps/lld/test/COFF/delayimports.test+4-4
......@@ -1,8 +1,8 @@
11# RUN: lld-link /out:%t.exe /entry:main /subsystem:console \
22# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /delayload:STD64.DLL \
33# RUN: /alternatename:__delayLoadHelper2=main
4# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
5# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
4# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
5# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
66
77IMPORT: DelayImport {
88IMPORT-NEXT: Name: std64.dll
......@@ -18,11 +18,11 @@ IMPORT-NEXT: Address: 0x140001066
1818IMPORT-NEXT: }
1919IMPORT-NEXT: Import {
2020IMPORT-NEXT: Symbol: (50)
21IMPORT-NEXT: Address: 0x1400010BD
21IMPORT-NEXT: Address: 0x140001072
2222IMPORT-NEXT: }
2323IMPORT-NEXT: Import {
2424IMPORT-NEXT: Symbol: MessageBoxA (0)
25IMPORT-NEXT: Address: 0x140001114
25IMPORT-NEXT: Address: 0x14000107E
2626IMPORT-NEXT: }
2727IMPORT-NEXT: }
2828
deps/lld/test/COFF/delayimports32.test+20-22
......@@ -1,10 +1,10 @@
11# REQUIRES: x86
22# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
3# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
3# RUN: lld-link -safeseh:no %t.obj %p/Inputs/std32.lib /subsystem:console \
44# RUN: /entry:main@0 /alternatename:___delayLoadHelper2@8=_main@0 \
55# RUN: /delayload:std32.dll /out:%t.exe
6# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
7# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
6# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
7# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
88# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
99
1010IMPORT: Format: COFF-i386
......@@ -24,7 +24,7 @@ IMPORT-NEXT: Address: 0x401029
2424IMPORT-NEXT: }
2525IMPORT-NEXT: Import {
2626IMPORT-NEXT: Symbol: MessageBoxA (0)
27IMPORT-NEXT: Address: 0x40103E
27IMPORT-NEXT: Address: 0x401033
2828IMPORT-NEXT: }
2929IMPORT-NEXT: }
3030
......@@ -47,19 +47,19 @@ BASEREL-NEXT: Address: 0x1025
4747BASEREL-NEXT: }
4848BASEREL-NEXT: Entry {
4949BASEREL-NEXT: Type: HIGHLOW
50BASEREL-NEXT: Address: 0x102C
50BASEREL-NEXT: Address: 0x102A
5151BASEREL-NEXT: }
5252BASEREL-NEXT: Entry {
5353BASEREL-NEXT: Type: HIGHLOW
54BASEREL-NEXT: Address: 0x1031
54BASEREL-NEXT: Address: 0x1034
5555BASEREL-NEXT: }
5656BASEREL-NEXT: Entry {
5757BASEREL-NEXT: Type: HIGHLOW
5858BASEREL-NEXT: Address: 0x1041
5959BASEREL-NEXT: }
6060BASEREL-NEXT: Entry {
61BASEREL-NEXT: Type: HIGHLOW
62BASEREL-NEXT: Address: 0x1046
61BASEREL-NEXT: Type: ABSOLUTE
62BASEREL-NEXT: Address: 0x1000
6363BASEREL-NEXT: }
6464BASEREL-NEXT: Entry {
6565BASEREL-NEXT: Type: HIGHLOW
......@@ -71,17 +71,15 @@ BASEREL-NEXT: Address: 0x3024
7171BASEREL-NEXT: }
7272BASEREL-NEXT: ]
7373
74DISASM: 102b: 68 20 30 40 00 pushl $4206624
75DISASM-NEXT: 1030: 68 00 20 40 00 pushl $4202496
76DISASM-NEXT: 1035: e8 c6 ff ff ff calll -58 <.text>
77DISASM-NEXT: 103a: 5a popl %edx
78DISASM-NEXT: 103b: 59 popl %ecx
79DISASM-NEXT: 103c: ff e0 jmpl *%eax
80DISASM-NEXT: 103e: 51 pushl %ecx
81DISASM-NEXT: 103f: 52 pushl %edx
82DISASM-NEXT: 1040: 68 24 30 40 00 pushl $4206628
83DISASM-NEXT: 1045: 68 00 20 40 00 pushl $4202496
84DISASM-NEXT: 104a: e8 b1 ff ff ff calll -79 <.text>
85DISASM-NEXT: 104f: 5a popl %edx
86DISASM-NEXT: 1050: 59 popl %ecx
87DISASM-NEXT: 1051: ff e0 jmpl *%eax
74DISASM: 1029: b8 20 30 40 00 movl $4206624, %eax
75DISASM-NEXT: 102e: e9 0a 00 00 00 jmp 10 <.text+0x3d>
76DISASM-NEXT: 1033: b8 24 30 40 00 movl $4206628, %eax
77DISASM-NEXT: 1038: e9 00 00 00 00 jmp 0 <.text+0x3d>
78DISASM-NEXT: 103d: 51 pushl %ecx
79DISASM-NEXT: 103e: 52 pushl %edx
80DISASM-NEXT: 103f: 50 pushl %eax
81DISASM-NEXT: 1040: 68 00 20 40 00 pushl $4202496
82DISASM-NEXT: 1045: e8 b6 ff ff ff calll -74 <.text>
83DISASM-NEXT: 104a: 5a popl %edx
84DISASM-NEXT: 104b: 59 popl %ecx
85DISASM-NEXT: 104c: ff e0 jmpl *%eax
deps/lld/test/COFF/delayimporttables.yaml created+122
......@@ -0,0 +1,122 @@
1# RUN: yaml2obj %p/Inputs/delayimporttables-dll1.yaml > %t1.obj
2# RUN: yaml2obj %p/Inputs/delayimporttables-dll2.yaml > %t2.obj
3# RUN: yaml2obj %s > %t.obj
4# RUN: lld-link /nodefaultlib /entry:DllMain /out:%T/delayimporttables-dll1.dll /dll /implib:%t-dll1.lib %t1.obj
5# RUN: lld-link /nodefaultlib /entry:DllMain /out:%T/delayimporttables-dll2.dll /dll /implib:%t-dll2.lib %t2.obj
6# RUN: lld-link /nodefaultlib /entry:main /out:%t.exe /delayload:delayimporttables-dll1.dll /delayload:delayimporttables-dll2.dll %t.obj %t-dll1.lib %t-dll2.lib
7# RUN: llvm-readobj --coff-imports %t.exe |FileCheck %s
8
9# CHECK: Format: COFF-x86-64
10# CHECK-NEXT: Arch: x86_64
11# CHECK-NEXT: AddressSize: 64bit
12# CHECK-NEXT: DelayImport {
13# CHECK-NEXT: Name: delayimporttables-dll1.dll
14# CHECK-NEXT: Attributes: 0x1
15# CHECK-NEXT: ModuleHandle: 0x3000
16# CHECK-NEXT: ImportAddressTable: 0x3010
17# CHECK-NEXT: ImportNameTable: 0x2060
18# CHECK-NEXT: BoundDelayImportTable: 0x0
19# CHECK-NEXT: UnloadDelayImportTable: 0x0
20# CHECK-NEXT: Import {
21# CHECK-NEXT: Symbol: one (0)
22# CHECK-NEXT: Address: 0x14000104D
23# CHECK-NEXT: }
24# CHECK-NEXT: Import {
25# CHECK-NEXT: Symbol: two (0)
26# CHECK-NEXT: Address: 0x140001059
27# CHECK-NEXT: }
28# CHECK-NEXT: }
29# CHECK-NEXT: DelayImport {
30# CHECK-NEXT: Name: delayimporttables-dll2.dll
31# CHECK-NEXT: Attributes: 0x1
32# CHECK-NEXT: ModuleHandle: 0x3008
33# CHECK-NEXT: ImportAddressTable: 0x3028
34# CHECK-NEXT: ImportNameTable: 0x2078
35# CHECK-NEXT: BoundDelayImportTable: 0x0
36# CHECK-NEXT: UnloadDelayImportTable: 0x0
37# CHECK-NEXT: Import {
38# CHECK-NEXT: Symbol: left (0)
39# CHECK-NEXT: Address: 0x1400010B8
40# CHECK-NEXT: }
41# CHECK-NEXT: Import {
42# CHECK-NEXT: Symbol: right (0)
43# CHECK-NEXT: Address: 0x1400010C4
44# CHECK-NEXT: }
45# CHECK-NEXT: }
46
47--- !COFF
48header:
49 Machine: IMAGE_FILE_MACHINE_AMD64
50 Characteristics: [ ]
51sections:
52 - Name: .drectve
53 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
54 Alignment: 1
55 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
56 - Name: '.text$mn'
57 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
58 Alignment: 16
59 SectionData: 4889542410894C24084883EC28FF1500000000FF1500000000FF1500000000FF150000000033C04883C428C3CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC488954241048894C240833C0C3
60 Relocations:
61 - VirtualAddress: 15
62 SymbolName: __imp_one
63 Type: IMAGE_REL_AMD64_REL32
64 - VirtualAddress: 21
65 SymbolName: __imp_two
66 Type: IMAGE_REL_AMD64_REL32
67 - VirtualAddress: 27
68 SymbolName: __imp_left
69 Type: IMAGE_REL_AMD64_REL32
70 - VirtualAddress: 33
71 SymbolName: __imp_right
72 Type: IMAGE_REL_AMD64_REL32
73symbols:
74 - Name: .drectve
75 Value: 0
76 SectionNumber: 1
77 SimpleType: IMAGE_SYM_TYPE_NULL
78 ComplexType: IMAGE_SYM_DTYPE_NULL
79 StorageClass: IMAGE_SYM_CLASS_STATIC
80 SectionDefinition:
81 Length: 47
82 NumberOfRelocations: 0
83 NumberOfLinenumbers: 0
84 CheckSum: 0
85 Number: 0
86 - Name: __imp_one
87 Value: 0
88 SectionNumber: 0
89 SimpleType: IMAGE_SYM_TYPE_NULL
90 ComplexType: IMAGE_SYM_DTYPE_NULL
91 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
92 - Name: __imp_two
93 Value: 0
94 SectionNumber: 0
95 SimpleType: IMAGE_SYM_TYPE_NULL
96 ComplexType: IMAGE_SYM_DTYPE_NULL
97 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
98 - Name: __imp_left
99 Value: 0
100 SectionNumber: 0
101 SimpleType: IMAGE_SYM_TYPE_NULL
102 ComplexType: IMAGE_SYM_DTYPE_NULL
103 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
104 - Name: __imp_right
105 Value: 0
106 SectionNumber: 0
107 SimpleType: IMAGE_SYM_TYPE_NULL
108 ComplexType: IMAGE_SYM_DTYPE_NULL
109 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
110 - Name: main
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: __delayLoadHelper2
117 Value: 64
118 SectionNumber: 2
119 SimpleType: IMAGE_SYM_TYPE_NULL
120 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
121 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
122...
deps/lld/test/COFF/dll.test+2-2
......@@ -42,10 +42,10 @@ EXPORT-LTO-NEXT: 3 0x1030 exportfn3
4242# RUN: /export:exportfn1 /export:exportfn2
4343# RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj
4444# RUN: lld-link /out:%t2.exe /entry:main %t2.obj %t2.lib
45# RUN: llvm-readobj -coff-imports %t2.exe | FileCheck -check-prefix=IMPORT %s
45# RUN: llvm-readobj --coff-imports %t2.exe | FileCheck -check-prefix=IMPORT %s
4646
4747# RUN: lld-link /out:%t2.lto.exe /entry:main %t2.obj %t.lto.lib
48# RUN: llvm-readobj -coff-imports %t2.lto.exe | FileCheck -check-prefix=IMPORT %s
48# RUN: llvm-readobj --coff-imports %t2.lto.exe | FileCheck -check-prefix=IMPORT %s
4949
5050IMPORT: Symbol: exportfn1
5151IMPORT: Symbol: exportfn2
deps/lld/test/COFF/dllexport.s+2-2
......@@ -1,9 +1,9 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o %t.obj
33
4# RUN: lld-link -entry:dllmain -dll %t.obj -out:%t.dll -implib:%t.lib
4# RUN: lld-link -safeseh:no -entry:dllmain -dll %t.obj -out:%t.dll -implib:%t.lib
55# RUN: llvm-readobj %t.lib | FileCheck -check-prefix DECORATED-IMPLIB %s
6# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix DECORATED-EXPORTS %s
6# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix DECORATED-EXPORTS %s
77
88# DECORATED-IMPLIB: Name type: name
99# DECORATED-IMPLIB-NEXT: __imp_@fastcall@8
deps/lld/test/COFF/dllimport-gc.test+2-2
......@@ -6,11 +6,11 @@
66# RUN: yaml2obj < %s > %t.obj
77
88# RUN: lld-link /out:%t1.exe /entry:main %t.obj %t-oldname.obj %t.lib
9# RUN: llvm-readobj -coff-imports %t1.exe | FileCheck -check-prefix=REF %s
9# RUN: llvm-readobj --coff-imports %t1.exe | FileCheck -check-prefix=REF %s
1010# REF-NOT: Symbol: exportfn1
1111
1212# RUN: lld-link /out:%t2.exe /entry:main %t.obj %t-oldname.obj %t.lib /opt:noref
13# RUN: llvm-readobj -coff-imports %t2.exe | FileCheck -check-prefix=NOREF %s
13# RUN: llvm-readobj --coff-imports %t2.exe | FileCheck -check-prefix=NOREF %s
1414# NOREF: Symbol: exportfn1
1515
1616--- !COFF
deps/lld/test/COFF/driver.test+23-1
......@@ -1,6 +1,6 @@
11# RUN: not lld-link nosuchfile.obj >& %t.log
22# RUN: FileCheck -check-prefix=MISSING %s < %t.log
3MISSING: nosuchfile.obj: {{[Nn]}}o such file or directory
3MISSING: 'nosuchfile.obj': {{[Nn]}}o such file or directory
44
55# RUN: lld-link --version | FileCheck -check-prefix=VERSION %s
66VERSION: {{LLD [0-9]+\.[0-9]+}}
......@@ -15,3 +15,25 @@ LIBHELP: OVERVIEW: LLVM Lib
1515
1616# RUN: not lld-link /WX /lib 2>&1 | FileCheck -check-prefix=LIBBAD %s
1717LIBBAD: ignoring /lib since it's not the first argument
18
19# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
20# RUN: not lld-link /out:/ %t.obj 2>&1 | FileCheck -check-prefix=DIR %s
21DIR: cannot open output file
22
23# RUN: not lld-link -version 2>&1 | FileCheck -check-prefix=SPELLVERSION %s
24SPELLVERSION: ignoring unknown argument '-version', did you mean '--version'
25SPELLVERSION: no input files
26
27# RUN: not lld-link -nodefaultlibs 2>&1 | FileCheck -check-prefix=SPELLNODEFAULTLIB %s
28SPELLNODEFAULTLIB: ignoring unknown argument '-nodefaultlibs', did you mean '-nodefaultlib'
29SPELLNODEFAULTLIB: no input files
30
31# RUN: not lld-link /nodefaultlibs 2>&1 | FileCheck -check-prefix=SPELLNODEFAULTLIB_SLASH %s
32SPELLNODEFAULTLIB_SLASH: could not open '/nodefaultlibs': {{.*}}; did you mean '/nodefaultlib'
33SPELLNODEFAULTLIB_SLASH-NOT: no input files
34
35# Getting flags as typo corrections for normal input files is a side effect
36# of how spell checking for /-style flags is implemented.
37# RUN: not lld-link force 2>&1 | FileCheck -check-prefix=SPELLFORCE %s
38SPELLFORCE: could not open 'force': {{.*}}; did you mean '/force'
39SPELLFORCE-NOT: no input files
deps/lld/test/COFF/eh_frame_suffix_sorting.s created+39
......@@ -0,0 +1,39 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.main.o
4# RUN: llvm-mc -filetype=obj -triple=i686-windows-gnu \
5# RUN: %p/Inputs/eh_frame_terminator-crtend.s -o %t.crtend.o
6
7# RUN: lld-link -lldmingw -entry:main %t.main.o %t.crtend.o -out:%t.exe
8# RUN: llvm-objdump -s %t.exe | FileCheck %s
9
10# Check that the contents of .eh_frame$foo was placed before .eh_frame from
11# crtend.o, even if the former had a section name suffix.
12
13# CHECK: Contents of section .eh_fram:
14# CHECK: 403000 4203
15
16 .text
17 .def _main;
18 .scl 2;
19 .type 32;
20 .endef
21 .globl _main
22 .p2align 4, 0x90
23_main:
24 call _foo
25 ret
26
27 .section .eh_frame$foo,"dr"
28 .linkonce discard
29 .byte 0x42
30
31 .def _foo;
32 .scl 2;
33 .type 32;
34 .endef
35 .section .text$foo,"xr",discard,foo
36 .globl _foo
37 .p2align 4
38_foo:
39 ret
deps/lld/test/COFF/eh_frame_terminator.s created+26
......@@ -0,0 +1,26 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-windows-gnu %s -o %t.main.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-windows-gnu \
4// RUN: %p/Inputs/eh_frame_terminator-otherfunc.s -o %t.otherfunc.o
5// RUN: llvm-mc -filetype=obj -triple=x86_64-windows-gnu \
6// RUN: %p/Inputs/eh_frame_terminator-crtend.s -o %t.crtend.o
7// RUN: rm -f %t.otherfunc.lib
8// RUN: llvm-ar rcs %t.otherfunc.lib %t.otherfunc.o
9// RUN: lld-link -lldmingw %t.main.o %t.otherfunc.lib %t.crtend.o -out:%t.exe
10// RUN: llvm-objdump -s %t.exe | FileCheck %s
11
12 .text
13 .globl main
14main:
15 call otherfunc
16 ret
17
18 .globl mainCRTStartup
19mainCRTStartup:
20 call main
21
22 .section .eh_frame,"dr"
23 .byte 1
24
25// CHECK: Contents of section .eh_fram:
26// CHECK-NEXT: 140003000 010203
deps/lld/test/COFF/entry-drectve.test+1-1
......@@ -1,5 +1,5 @@
11# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /subsystem:console /out:%t.exe %t.obj
2# RUN: lld-link -safeseh:no /subsystem:console /out:%t.exe %t.obj
33
44--- !COFF
55header:
deps/lld/test/COFF/entry-inference-mingw.s+3-3
......@@ -5,9 +5,9 @@
55# RUN: lld-link -lldmingw %t.o -out:%t-cui.exe -subsystem:console 2>&1 | FileCheck -allow-empty -check-prefix=LINK %s
66# RUN: lld-link -lldmingw %t.o -out:%t-gui.exe -subsystem:windows 2>&1 | FileCheck -allow-empty -check-prefix=LINK %s
77
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
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
1111
1212# Check that this doesn't print any warnings.
1313# LINK-NOT: found both wmain and main
deps/lld/test/COFF/entry-inference332.test+2-2
......@@ -1,9 +1,9 @@
11# RUN: sed -e s/ENTRYNAME/_mainCRTStartup/ %s | yaml2obj > %t.obj
2# RUN: lld-link /subsystem:console /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1
2# RUN: lld-link -safeseh:no /subsystem:console /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1
33# RUN: FileCheck %s < %t.log
44
55# RUN: sed -e s/ENTRYNAME/?mainCRTStartup@@YAHXZ/ %s | yaml2obj > %t.obj
6# RUN: lld-link /subsystem:console /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1
6# RUN: lld-link -safeseh:no /subsystem:console /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1
77# RUN: FileCheck %s < %t.log
88
99# CHECK: Entry name inferred: _mainCRTStartup
deps/lld/test/COFF/error-limit.test+10-10
......@@ -1,26 +1,26 @@
11RUN: not lld-link 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 \
22RUN: 21 22 2>&1 | FileCheck -check-prefix=DEFAULT %s
33
4DEFAULT: could not open 01
5DEFAULT: could not open 20
4DEFAULT: could not open '01'
5DEFAULT: could not open '20'
66DEFAULT-NEXT: too many errors emitted, stopping now (use /errorlimit:0 to see all errors)
7DEFAULT-NOT: could not open 21
7DEFAULT-NOT: could not open '21'
88
99RUN: not lld-link /errorlimit:5 01 02 03 04 05 06 07 08 09 10 2>&1 \
1010RUN: | FileCheck -check-prefix=LIMIT5 %s
1111
12LIMIT5: could not open 01
13LIMIT5: could not open 05
12LIMIT5: could not open '01'
13LIMIT5: could not open '05'
1414LIMIT5-NEXT: too many errors emitted, stopping now (use /errorlimit:0 to see all errors)
15LIMIT5-NOT: could not open 06
15LIMIT5-NOT: could not open '06'
1616
1717RUN: not lld-link /errorlimit:0 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \
1818RUN: 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=UNLIMITED %s
1919
20UNLIMITED: could not open 01
21UNLIMITED: could not open 20
22UNLIMITED: could not open 21
23UNLIMITED: could not open 22
20UNLIMITED: could not open '01'
21UNLIMITED: could not open '20'
22UNLIMITED: could not open '21'
23UNLIMITED: could not open '22'
2424UNLIMITED-NOT: too many errors emitted, stopping now (use /errorlimit:0 to see all errors)
2525
2626RUN: not lld-link /errorlimit:XYZ 01 02 03 04 05 06 07 08 09 10 11 12 13 14 \
deps/lld/test/COFF/exclude-all.s created+31
......@@ -0,0 +1,31 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj
4
5# RUN: lld-link -lldmingw -exclude-all-symbols -dll -out:%t.dll -entry:DllMainCRTStartup@12 %t.obj
6# RUN: llvm-readobj --coff-exports %t.dll | FileCheck %s -check-prefix=NO-EXPORTS
7
8# NO-EXPORTS-NOT: Name:
9
10.global _foobar
11.global _DllMainCRTStartup@12
12.global _dataSym
13.text
14_DllMainCRTStartup@12:
15 ret
16_foobar:
17 ret
18.data
19_dataSym:
20 .int 4
21
22# Test specifying -exclude-all-symbols, on an object file that contains
23# dllexport directive for some of the symbols. In this case, the dllexported
24# symbols are still exported.
25
26# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
27#
28# RUN: lld-link -safeseh:no -out:%t.dll -dll %t.obj -lldmingw -exclude-all-symbols -output-def:%t.def
29# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix=DLLEXPORT %s
30
31# DLLEXPORT: Name: exportfn3
deps/lld/test/COFF/export-all.s+5-5
......@@ -3,7 +3,7 @@
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 | grep Name: | 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
99# CHECK: Name:
......@@ -42,8 +42,8 @@ __imp__unexported:
4242
4343# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
4444#
45# RUN: lld-link -out:%t.dll -dll %t.obj -lldmingw -export-all-symbols -output-def:%t.def
46# RUN: llvm-readobj -coff-exports %t.dll | FileCheck -check-prefix=CHECK2 %s
45# RUN: lld-link -safeseh:no -out:%t.dll -dll %t.obj -lldmingw -export-all-symbols -output-def:%t.def
46# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix=CHECK2 %s
4747# RUN: cat %t.def | FileCheck -check-prefix=CHECK2-DEF %s
4848
4949# Note, this will actually export _DllMainCRTStartup as well, since
......@@ -69,7 +69,7 @@ __imp__unexported:
6969# RUN: llvm-ar rcs %T/libs/libmingwex.a %T/libs/mingwfunc.o
7070# RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %T/libs/crtfunc.s
7171# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/crtfunc.s -filetype=obj -o %T/libs/crt2.o
72# RUN: lld-link -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o %T/libs/libmingwex.a -output-def:%t.def
72# RUN: lld-link -safeseh:no -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o %T/libs/libmingwex.a -output-def:%t.def
7373# RUN: echo "EOF" >> %t.def
7474# RUN: cat %t.def | FileCheck -check-prefix=CHECK-EXCLUDE %s
7575
......@@ -80,7 +80,7 @@ __imp__unexported:
8080# Test that libraries included with -wholearchive: are autoexported, even if
8181# they are in a library that otherwise normally would be excluded.
8282
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
83# RUN: lld-link -safeseh:no -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o -wholearchive:%T/libs/libmingwex.a -output-def:%t.def
8484# RUN: echo "EOF" >> %t.def
8585# RUN: cat %t.def | FileCheck -check-prefix=CHECK-WHOLEARCHIVE %s
8686
deps/lld/test/COFF/export-stdcall.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple i686-windows-msvc %s -o %t.obj -filetype=obj
3# RUN: lld-link -safeseh:no %t.obj -out:%t.dll -dll -nodefaultlib -noentry -export:foo_std=bar_std -export:foo_fast=bar_fast
4# RUN: llvm-nm %t.lib | FileCheck %s
5
6# MSVC fudges the lookup of 'bar' to allow it to find the stdcall function
7# _bar_std@8, and then exports _foo_std@8. Same for fastcall and other mangling
8# schemes.
9
10# CHECK: export-stdcall.s.tmp.dll:
11# CHECK: 00000000 T @foo_fast@8
12# CHECK: 00000000 T __imp_@foo_fast@8
13
14# CHECK: export-stdcall.s.tmp.dll:
15# CHECK: 00000000 T __imp__foo_std@8
16# CHECK: 00000000 T _foo_std@8
17
18 .text
19 .def _bar_std@8; .scl 2; .type 32; .endef
20 .globl _bar_std@8
21_bar_std@8:
22 movl 8(%esp), %eax
23 movl 4(%esp), %ecx
24 leal 42(%ecx,%eax), %eax
25 retl $8
26
27 .def @bar_fast@8; .scl 2; .type 32; .endef
28 .globl @bar_fast@8
29@bar_fast@8:
30 leal 42(%ecx,%eax), %eax
31 retl
32
deps/lld/test/COFF/export-weak-alias.s created+33
......@@ -0,0 +1,33 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple x86_64-windows-msvc %s -o %t.obj -filetype=obj
3# RUN: lld-link %t.obj -out:%t.dll -dll -nodefaultlib -noentry
4# RUN: llvm-nm %t.lib | FileCheck %s
5
6# CHECK: export-weak-alias.s.tmp.dll:
7# CHECK: 00000000 T __imp_foo_dll{{$}}
8# CHECK: 00000000 T foo_dll{{$}}
9
10 .text
11 .def @feat.00;
12 .scl 3;
13 .type 0;
14 .endef
15 .globl @feat.00
16.set @feat.00, 0
17 .file "t.c"
18 .def foo_def;
19 .scl 2;
20 .type 32;
21 .endef
22 .globl foo_def # -- Begin function foo_def
23 .p2align 4, 0x90
24foo_def: # @foo_def
25# %bb.0: # %entry
26 movl $42, %eax
27 retq
28 # -- End function
29 .section .drectve,"yn"
30 .ascii " /alternatename:foo=foo_def"
31 .ascii " /export:foo_dll=foo"
32
33 .addrsig
deps/lld/test/COFF/export32.test+10-10
......@@ -1,11 +1,11 @@
11# RUN: yaml2obj < %s > %t.obj
22#
3# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2
3# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2
44# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s
55#
6# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 /merge:.edata=.rdata
6# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 /merge:.edata=.rdata
77# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s
8# RUN: llvm-readobj -file-headers -sections %t.dll | FileCheck -check-prefix=HEADER-MERGE %s
8# RUN: llvm-readobj --file-headers --sections %t.dll | FileCheck -check-prefix=HEADER-MERGE %s
99
1010# CHECK1: Export Table:
1111# CHECK1: DLL name: export32.test.tmp.dll
......@@ -20,7 +20,7 @@
2020# HEADER-MERGE-NEXT: VirtualSize: 0x7E
2121# HEADER-MERGE-NEXT: VirtualAddress: 0x2000
2222
23# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5 \
23# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /export:exportfn1,@5 \
2424# RUN: /export:exportfn2 /export:mangled
2525# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s
2626
......@@ -37,7 +37,7 @@
3737# CHECK2-NEXT: 7 0x1010 exportfn3
3838# CHECK2-NEXT: 8 0x1010 mangled
3939
40# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2
40# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2
4141# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK3 %s
4242
4343# CHECK3: Export Table:
......@@ -51,7 +51,7 @@
5151# CHECK3-NEXT: 5 0x1008
5252# CHECK3-NEXT: 6 0x1010 exportfn2
5353
54# RUN: lld-link /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2
54# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2
5555# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK4 %s
5656
5757# CHECK4: Export Table:
......@@ -64,12 +64,12 @@
6464
6565# RUN: echo "EXPORTS exportfn1 @3" > %t.def
6666# RUN: echo "fn2=exportfn2 @2" >> %t.def
67# RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def
67# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /def:%t.def
6868# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s
6969
7070# RUN: echo "EXPORTS exportfn1 @ 3" > %t.def
7171# RUN: echo "fn2=exportfn2 @ 2" >> %t.def
72# RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def
72# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /def:%t.def
7373# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s
7474
7575# CHECK5: Export Table:
......@@ -81,14 +81,14 @@
8181# CHECK5-NEXT: 3 0x1008 exportfn1
8282# CHECK5-NEXT: 4 0x1010 exportfn3
8383
84# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \
84# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \
8585# RUN: /export:exportfn1 /export:exportfn2,@5 >& %t.log
8686# RUN: FileCheck -check-prefix=CHECK6 %s < %t.log
8787
8888# CHECK6: duplicate /export option: _exportfn2
8989# CHECK6-NOT: duplicate /export option: _exportfn1
9090
91# RUN: lld-link /out:%t.dll /dll %t.obj /export:foo=mangled
91# RUN: lld-link -safeseh:no /out:%t.dll /dll %t.obj /export:foo=mangled
9292# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK7 %s
9393
9494# CHECK7: Export Table:
deps/lld/test/COFF/failifmismatch.test+29-8
......@@ -1,11 +1,32 @@
1# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
2# RUN: %p/Inputs/ret42.obj
1REQUIRES: x86
32
4# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
5# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k2=v1
3RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
4RUN: %p/Inputs/ret42.obj
65
7# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
8# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v1
6RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
7RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k2=v1
98
10# RUN: not lld-link /entry:main /subsystem:console /out:%t.exe \
11# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v2
9RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
10RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v1
11
12RUN: not lld-link /entry:main /subsystem:console /out:%t.exe \
13RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v2 2>&1 | FileCheck %s
14
15RUN: llc < %p/Inputs/failmismatch1.ll -mtriple x86_64-windows-msvc -filetype obj -o %t1.obj
16RUN: llc < %p/Inputs/failmismatch2.ll -mtriple x86_64-windows-msvc -filetype obj -o %t2.obj
17RUN: not lld-link %t1.obj %t2.obj 2>&1 | FileCheck %s -check-prefix OBJ
18
19RUN: llvm-lib %t1.obj /out:%t.lib
20RUN: not lld-link %t.lib %t2.obj 2>&1 | FileCheck %s -check-prefix LIB
21
22CHECK: lld-link: error: /failifmismatch: mismatch detected for 'k1':
23CHECK-NEXT: >>> cmd-line has value v1
24CHECK-NEXT: >>> cmd-line has value v2
25
26OBJ: lld-link: error: /failifmismatch: mismatch detected for 'TEST':
27OBJ-NEXT: >>> {{.*}}failifmismatch.test.tmp1.obj has value 1
28OBJ-NEXT: >>> {{.*}}failifmismatch.test.tmp2.obj has value 2
29
30LIB: lld-link: error: /failifmismatch: mismatch detected for 'TEST':
31LIB-NEXT: >>> {{.*}}failifmismatch.test.tmp2.obj has value 2
32LIB-NEXT: >>> failifmismatch.test.tmp.lib(failifmismatch.test.tmp1.obj) has value 1
deps/lld/test/COFF/filealign.test created+51
......@@ -0,0 +1,51 @@
1# RUN: yaml2obj < %s > %t.obj
2
3# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=DEFAULT-HEADER %s
5
6# DEFAULT-HEADER: FileAlignment: 512
7
8# RUN: lld-link /out:%t.exe /entry:main %t.obj /filealign:4096
9# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=FILEALIGN-HEADER %s
10
11# FILEALIGN-HEADER: FileAlignment: 4096
12
13--- !COFF
14header:
15 Machine: IMAGE_FILE_MACHINE_AMD64
16 Characteristics: []
17sections:
18 - Name: .text
19 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
20 Alignment: 4096
21 SectionData: 0000000000000000
22 Relocations:
23 - VirtualAddress: 0
24 SymbolName: __ImageBase
25 Type: IMAGE_REL_AMD64_ADDR64
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: 8
35 NumberOfRelocations: 1
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 - Name: __ImageBase
46 Value: 0
47 SectionNumber: 0
48 SimpleType: IMAGE_SYM_TYPE_NULL
49 ComplexType: IMAGE_SYM_DTYPE_NULL
50 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
51...
deps/lld/test/COFF/fixed.test+8-8
......@@ -1,22 +1,22 @@
11# REQUIRES: x86
22# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
33#
4# RUN: lld-link %t.obj /fixed %p/Inputs/std32.lib /subsystem:console \
4# RUN: lld-link -safeseh:no %t.obj /fixed %p/Inputs/std32.lib /subsystem:console \
55# RUN: /entry:main@0 /debug /out:%t.fixed.exe
6# RUN: llvm-readobj -file-headers %t.fixed.exe | \
6# RUN: llvm-readobj --file-headers %t.fixed.exe | \
77# RUN: FileCheck -check-prefix=EXEFIXED %s
88#
9# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
9# RUN: lld-link -safeseh:no %t.obj %p/Inputs/std32.lib /subsystem:console \
1010# RUN: /entry:main@0 /debug /out:%t.exe
11# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=EXEREL %s
11# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=EXEREL %s
1212#
1313# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
1414#
15# RUN: lld-link %t.obj /dll /fixed /debug /out:%t.fixed.dll
16# RUN: llvm-readobj -file-headers %t.fixed.dll | FileCheck -check-prefix=DLLFIXED %s
15# RUN: lld-link -safeseh:no %t.obj /dll /fixed /debug /out:%t.fixed.dll
16# RUN: llvm-readobj --file-headers %t.fixed.dll | FileCheck -check-prefix=DLLFIXED %s
1717#
18# RUN: lld-link %t.obj /dll /debug /out:%t.dll
19# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=DLLREL %s
18# RUN: lld-link -safeseh:no %t.obj /dll /debug /out:%t.dll
19# RUN: llvm-readobj --file-headers %t.dll | FileCheck -check-prefix=DLLREL %s
2020
2121EXEFIXED-NOT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
2222DLLFIXED-NOT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
deps/lld/test/COFF/force-multipleres.test created+21
......@@ -0,0 +1,21 @@
1// Check that lld-link rejects duplicate resources, unless
2// /force or /force:multipleres is passed.
3// The input was generated with the following command, using the original Windows
4// rc.exe:
5// > rc /fo id.res /nologo id.rc
6// > rc /fo name.res /nologo name.rc
7
8RUN: rm -rf %t.dir
9RUN: mkdir %t.dir
10RUN: cp %S/Inputs/id.res %t.dir/id1.res
11RUN: cp %S/Inputs/id.res %t.dir/id2.res
12
13RUN: not lld-link /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.res %t.dir/id2.res 2>&1 | \
14RUN: FileCheck -check-prefix=ERR %s
15ERR: error: duplicate resource: type STRINGTABLE (ID 6)/name ID 3/language 1033, in {{.*}}id1.res and in {{.*}}id2.res
16
17RUN: lld-link /force /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.res %t.dir/id2.res 2>&1 | \
18RUN: FileCheck -check-prefix=WARN %s
19RUN: lld-link /force:multipleres /machine:x64 /nodefaultlib /noentry /dll %t.dir/id1.res %t.dir/id2.res 2>&1 | \
20RUN: FileCheck -check-prefix=WARN %s
21WARN: warning: duplicate resource: type STRINGTABLE (ID 6)/name ID 3/language 1033, in {{.*}}id1.res and in {{.*}}id2.res
deps/lld/test/COFF/functionpadmin.test created+147
......@@ -0,0 +1,147 @@
1// ---- precomp-a.obj - x86_64, hotpatch
2RUN: lld-link %S/Inputs/precomp-a.obj /out:%t.exe /nodefaultlib /force
3RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix BASE
4
5RUN: lld-link %S/Inputs/precomp-a.obj /out:%t.exe /nodefaultlib /force /functionpadmin
6RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix PADDED
7
8RUN: lld-link %S/Inputs/precomp-a.obj /out:%t.exe /nodefaultlib /force /functionpadmin:17
9RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix PADDED-MORE
10
11// ---- Many arguments
12RUN: lld-link %S/Inputs/precomp-a.obj /out:%t.exe /nodefaultlib /force /functionpadmin:17 /functionpadmin
13RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix PADDED
14
15RUN: lld-link %S/Inputs/precomp-a.obj /out:%t.exe /nodefaultlib /force /functionpadmin /functionpadmin:17
16RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix PADDED-MORE
17
18RUN: not lld-link %S/Inputs/precomp-a.obj /out:%t.exe /nodefaultlib /force /functionpadmin:zz 2>&1 | FileCheck %s --check-prefix FAIL
19
20// ---- precomp-a.obj, precomp-b.obj - x86_64, hotpatch - Ensure several functions are properly padded
21RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /out:%t.exe /nodefaultlib /force
22RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix MULTI-BASE
23
24RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /out:%t.exe /nodefaultlib /force /functionpadmin
25RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix MULTI-BASE-PADDED
26
27RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /out:%t.exe /nodefaultlib /force /functionpadmin:17
28RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix MULTI-BASE-PADDED-MORE
29
30// ---- pdb-diff.obj - x86, no hotpatch - No padding is applied
31RUN: lld-link %S/Inputs/pdb-diff.obj /out:%t.exe /nodefaultlib /force /functionpadmin
32RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix NO-HOTPATCH
33
34// ---- hello64.obj - MASM, x86_64, no hotpatch - No padding is applied
35RUN: lld-link %S/Inputs/hello64.obj /out:%t.exe /nodefaultlib /force /functionpadmin
36RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix HELLO
37
38// ---- std64.lib - Import library, x86_64 - Ensure thunks are padded
39RUN: lld-link %S/Inputs/std64.lib /entry:ExitProcess /out:%t.exe /nodefaultlib /force /subsystem:console
40RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix THUNKS-NO-PAD
41RUN: llvm-readobj --file-headers %t.exe | FileCheck %s --check-prefix THUNKS-NO-PAD-ENTRY
42
43RUN: lld-link %S/Inputs/std64.lib /entry:ExitProcess /out:%t.exe /nodefaultlib /force /functionpadmin /subsystem:console
44RUN: llvm-objdump -s %t.exe | FileCheck %s --check-prefix THUNKS-PAD
45RUN: llvm-readobj --file-headers %t.exe | FileCheck %s --check-prefix THUNKS-PAD-ENTRY
46
47BASE: Contents of section .text:
48BASE-NEXT: 140001000 4883ec28 b161e8f5 efffbf33 c04883c4 H..(.a.....3.H..
49BASE-NEXT: 140001010 28c3 (.
50BASE-NEXT: Contents of section .rdata:
51BASE-NEXT: 140002000 01040100 04420000 .....B..
52BASE-NEXT: Contents of section .pdata:
53BASE-NEXT: 140003000 00100000 12100000 00200000 ......... ..
54
55PADDED: Contents of section .text:
56PADDED-NEXT: 140001000 cccccccc cccccccc cccccccc cccccccc ................
57PADDED-NEXT: 140001010 4883ec28 b161e8e5 efffbf33 c04883c4 H..(.a.....3.H..
58PADDED-NEXT: 140001020 28c3 (.
59PADDED-NEXT: Contents of section .rdata:
60PADDED-NEXT: 140002000 01040100 04420000 .....B..
61PADDED-NEXT: Contents of section .pdata:
62PADDED-NEXT: 140003000 10100000 22100000 00200000 ....".... ..
63
64PADDED-MORE: Contents of section .text:
65PADDED-MORE-NEXT: 140001000 cccccccc cccccccc cccccccc cccccccc ................
66PADDED-MORE-NEXT: 140001010 cccccccc cccccccc cccccccc cccccccc ................
67PADDED-MORE-NEXT: 140001020 4883ec28 b161e8d5 efffbf33 c04883c4 H..(.a.....3.H..
68PADDED-MORE-NEXT: 140001030 28c3 (.
69PADDED-MORE-NEXT: Contents of section .rdata:
70PADDED-MORE-NEXT: 140002000 01040100 04420000 .....B..
71PADDED-MORE-NEXT: Contents of section .pdata:
72PADDED-MORE-NEXT: 140003000 20100000 32100000 00200000 ...2.... ..
73
74FAIL: lld-link: error: /functionpadmin: invalid argument: zz
75
76MULTI-BASE: Contents of section .text:
77MULTI-BASE-NEXT: 140001000 4883ec28 b161e815 00000033 c04883c4 H..(.a.....3.H..
78MULTI-BASE-NEXT: 140001010 28c3cccc cccccccc cccccccc cccccccc (...............
79MULTI-BASE-NEXT: 140001020 884c2408 0fbe4424 08c3 .L$...D$..
80MULTI-BASE-NEXT: Contents of section .rdata:
81MULTI-BASE-NEXT: 140002000 01040100 04420000 .....B..
82MULTI-BASE-NEXT: Contents of section .pdata:
83MULTI-BASE-NEXT: 140004000 00100000 12100000 00200000 ......... ..
84
85MULTI-BASE-PADDED: Contents of section .text:
86MULTI-BASE-PADDED-NEXT: 140001000 cccccccc cccccccc cccccccc cccccccc ................
87MULTI-BASE-PADDED-NEXT: 140001010 4883ec28 b161e815 00000033 c04883c4 H..(.a.....3.H..
88MULTI-BASE-PADDED-NEXT: 140001020 28c3cccc cccccccc cccccccc cccccccc (...............
89MULTI-BASE-PADDED-NEXT: 140001030 884c2408 0fbe4424 08c3 .L$...D$..
90MULTI-BASE-PADDED-NEXT: Contents of section .rdata:
91MULTI-BASE-PADDED-NEXT: 140002000 01040100 04420000 .....B..
92MULTI-BASE-PADDED-NEXT: Contents of section .pdata:
93MULTI-BASE-PADDED-NEXT: 140004000 10100000 22100000 00200000 ....".... ..
94
95MULTI-BASE-PADDED-MORE: Contents of section .text:
96MULTI-BASE-PADDED-MORE-NEXT: 140001000 cccccccc cccccccc cccccccc cccccccc ................
97MULTI-BASE-PADDED-MORE-NEXT: 140001010 cccccccc cccccccc cccccccc cccccccc ................
98MULTI-BASE-PADDED-MORE-NEXT: 140001020 4883ec28 b161e825 00000033 c04883c4 H..(.a.%...3.H..
99MULTI-BASE-PADDED-MORE-NEXT: 140001030 28c3cccc cccccccc cccccccc cccccccc (...............
100MULTI-BASE-PADDED-MORE-NEXT: 140001040 cccccccc cccccccc cccccccc cccccccc ................
101MULTI-BASE-PADDED-MORE-NEXT: 140001050 884c2408 0fbe4424 08c3 .L$...D$..
102MULTI-BASE-PADDED-MORE-NEXT: Contents of section .rdata:
103MULTI-BASE-PADDED-MORE-NEXT: 140002000 01040100 04420000 .....B..
104MULTI-BASE-PADDED-MORE-NEXT: Contents of section .pdata:
105MULTI-BASE-PADDED-MORE-NEXT: 140004000 20100000 32100000 00200000 ...2.... ..
106
107
108NO-HOTPATCH: Contents of section .text:
109NO-HOTPATCH-NEXT: 401000 558becb8 2a000000 5dc3 U...*...].
110
111HELLO: Contents of section .text:
112HELLO-NEXT: 140001000 4883ec28 48c7c100 00000048 8d15f40f H..(H......H....
113HELLO-NEXT: 140001010 00004c8d 05e70f00 0041b900 000000e8 ..L......A......
114HELLO-NEXT: 140001020 dcefffbf b9000000 00e8d2ef ffbfe8cd ................
115HELLO-NEXT: 140001030 efffbf ...
116HELLO-NEXT: Contents of section .data:
117HELLO-NEXT: 140002000 48656c6c 6f004865 6c6c6f20 576f726c Hello.Hello Worl
118HELLO-NEXT: 140002010 642100 d!.
119
120THUNKS-NO-PAD: Contents of section .text:
121THUNKS-NO-PAD-NEXT: 140001000 ff253210 0000 .%2...
122THUNKS-NO-PAD-NEXT: Contents of section .rdata:
123THUNKS-NO-PAD-NEXT: 140002000 28200000 00000000 00000000 56200000 ( ..........V ..
124THUNKS-NO-PAD-NEXT: 140002010 38200000 00000000 00000000 00000000 8 ..............
125THUNKS-NO-PAD-NEXT: 140002020 00000000 00000000 48200000 00000000 ........H ......
126THUNKS-NO-PAD-NEXT: 140002030 00000000 00000000 48200000 00000000 ........H ......
127THUNKS-NO-PAD-NEXT: 140002040 00000000 00000000 00004578 69745072 ..........ExitPr
128THUNKS-NO-PAD-NEXT: 140002050 6f636573 73007374 6436342e 646c6c00 ocess.std64.dll.
129
130THUNKS-NO-PAD-ENTRY-LABEL: ImageOptionalHeader {
131THUNKS-NO-PAD-ENTRY: AddressOfEntryPoint: 0x1000
132THUNKS-NO-PAD-ENTRY-NEXT: BaseOfCode: 0x1000
133
134THUNKS-PAD: Contents of section .text:
135THUNKS-PAD-NEXT: 140001000 cccccccc cccccccc cccccccc cccccccc ................
136THUNKS-PAD-NEXT: 140001010 ff252210 0000 .%"...
137THUNKS-PAD-NEXT: Contents of section .rdata:
138THUNKS-PAD-NEXT: 140002000 28200000 00000000 00000000 56200000 ( ..........V ..
139THUNKS-PAD-NEXT: 140002010 38200000 00000000 00000000 00000000 8 ..............
140THUNKS-PAD-NEXT: 140002020 00000000 00000000 48200000 00000000 ........H ......
141THUNKS-PAD-NEXT: 140002030 00000000 00000000 48200000 00000000 ........H ......
142THUNKS-PAD-NEXT: 140002040 00000000 00000000 00004578 69745072 ..........ExitPr
143THUNKS-PAD-NEXT: 140002050 6f636573 73007374 6436342e 646c6c00 ocess.std64.dll.
144
145THUNKS-PAD-ENTRY-LABEL: ImageOptionalHeader {
146THUNKS-PAD-ENTRY: AddressOfEntryPoint: 0x1010
147THUNKS-PAD-ENTRY-NEXT: BaseOfCode: 0x1000
deps/lld/test/COFF/gfids-corrupt.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj -opt:noref -guard:nolongjmp -out:%t.exe -entry:main 2>&1 | FileCheck %s --check-prefix=ERRS
4# RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s
4# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s
55
66# ERRS: warning: ignoring .gfids$y symbol table index section in object {{.*}}gfids-corrupt{{.*}}
77# ERRS: warning: ignoring invalid symbol table index in section .gfids$y in object {{.*}}gfids-corrupt{{.*}}
deps/lld/test/COFF/gfids-export.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple x86_64-pc-win32 %s -filetype=obj -o %t.obj
33# 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
4# RUN: llvm-readobj --coff-load-config %t.dll | FileCheck %s --check-prefix=CHECK
55
66# There should be a single entry in the table for the exported symbol.
77#
deps/lld/test/COFF/gfids-fallback.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: grep -B99999 [S]PLITMARKER %s | llvm-mc -triple x86_64-windows-msvc -filetype=obj -o %t1.obj
33# RUN: grep -A99999 [S]PLITMARKER %s | llvm-mc -triple x86_64-windows-msvc -filetype=obj -o %t2.obj
44# RUN: lld-link %t1.obj %t2.obj -guard:nolongjmp -out:%t.exe -entry:main -opt:noref
5# RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s
5# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s
66
77# CHECK: ImageBase: 0x140000000
88# CHECK: LoadConfig [
deps/lld/test/COFF/gfids-gc.s+3-3
......@@ -1,11 +1,11 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj -guard:nolongjmp -out:%t.exe -opt:noref -entry:main
4# RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
4# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
55# RUN: lld-link %t.obj -guard:nolongjmp -out:%t.exe -opt:noref -entry:main -debug:dwarf
6# RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
6# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
77# RUN: lld-link %t.obj -guard:nolongjmp -out:%t.exe -opt:ref -entry:main
8# RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC
8# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC
99
1010# This assembly is meant to mimic what CL emits for this kind of C code when
1111# /Gw (-fdata-sections) is enabled:
deps/lld/test/COFF/gfids-icf.s+11-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj -guard:nolongjmp -out:%t.exe -opt:icf -entry:main
4# RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK
4# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK
55
66# This assembly is meant to mimic what CL emits for this kind of C code:
77# int icf1() { return 42; }
......@@ -35,6 +35,16 @@
3535# CHECK-NEXT: 0x14000{{.*}}
3636# CHECK-NEXT: ]
3737
38# There should be no .gfids section in the output exectuable when we link with
39# -guard:cf or with no -guard:cf/nolongjmp flag.
40# RUN: llvm-readobj --sections %t.exe | FileCheck %s --check-prefix NOGFIDSEC
41# RUN: lld-link %t.obj -out:%t.exe -opt:icf -entry:main
42# RUN: llvm-readobj --sections %t.exe | FileCheck %s --check-prefix NOGFIDSEC
43
44# NOGFIDSEC: Sections [
45# NOGFIDSEC: Section {
46# NOGFIDSEC: Name: .text
47# NOGFIDSEC-NOT: Name: .gfids
3848
3949# Indicate that gfids are present.
4050 .def @feat.00; .scl 3; .type 0; .endef
deps/lld/test/COFF/gfids-relocations32.s+2-2
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# 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
3# RUN: lld-link -safeseh:no %t.obj -guard:cf -out:%t.exe -entry:main
4# RUN: llvm-readobj --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK
55
66# Only f and _main should go in the table.
77# (use /lldmap:map.txt to check their addresses).
deps/lld/test/COFF/gfids-relocations64.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple x86_64-pc-win32 %s -filetype=obj -o %t.obj
33# 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
4# RUN: llvm-readobj --coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK
55
66# f, g, and main go in the table.
77# Including g isn't strictly necessary since it's not an indirect call target,
deps/lld/test/COFF/guard-longjmp.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj -guard:cf -out:%t.exe -entry:main
4# RUN: llvm-readobj -file-headers -coff-load-config %t.exe | FileCheck %s
4# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s
55
66# CHECK: ImageBase: 0x140000000
77# CHECK: LoadConfig [
deps/lld/test/COFF/guardcf-align.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: > %T/guardcf-align-foobar.obj
55# RUN: lld-link -out:%T/guardcf-align.exe -entry:main -guard:cf \
66# RUN: %t.obj %T/guardcf-align-foobar.obj
7# RUN: llvm-readobj -coff-load-config %T/guardcf-align.exe | FileCheck %s
7# RUN: llvm-readobj --coff-load-config %T/guardcf-align.exe | FileCheck %s
88
99# Check that the gfids table contains at least one entry that ends in 0
1010# and no entries that end in something other than 0.
deps/lld/test/COFF/guardcf-lto.ll+1-1
......@@ -9,7 +9,7 @@
99
1010; RUN: llvm-as %s -o %t.bc
1111; RUN: lld-link -entry:main -guard:cf -dll %t.bc %t.lib %t.ldcfg.obj -out:%t.dll
12; RUN: llvm-readobj -coff-load-config %t.dll | FileCheck %s
12; RUN: llvm-readobj --coff-load-config %t.dll | FileCheck %s
1313
1414; There must be *two* entries in the table: DLL entry point, and my_handler.
1515
deps/lld/test/COFF/guardcf-thunk.s created+43
......@@ -0,0 +1,43 @@
1# REQUIRES: x86
2
3# Make a DLL that exports exportfn1.
4# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
5# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /implib:%t.lib
6
7# Make an obj that takes the address of that exported function.
8# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc %s -o %t2.obj
9# RUN: lld-link -entry:main -guard:cf %t2.obj %t.lib -nodefaultlib -out:%t.exe
10# RUN: llvm-readobj --coff-load-config %t.exe | FileCheck %s
11
12# Check that the gfids table contains *exactly* two entries, one for exportfn1
13# and one for main.
14# CHECK: GuardFidTable [
15# CHECK-NEXT: 0x{{[0-9A-Fa-f]+0$}}
16# CHECK-NEXT: 0x{{[0-9A-Fa-f]+0$}}
17# CHECK-NEXT: ]
18
19
20 .def @feat.00;
21 .scl 3;
22 .type 0;
23 .endef
24 .globl @feat.00
25@feat.00 = 0x001
26
27 .section .text,"rx"
28 .def main; .scl 2; .type 32; .endef
29 .global main
30main:
31 leaq exportfn1(%rip), %rax
32 retq
33
34 .section .rdata,"dr"
35.globl _load_config_used
36_load_config_used:
37 .long 256
38 .fill 124, 1, 0
39 .quad __guard_fids_table
40 .quad __guard_fids_count
41 .long __guard_flags
42 .fill 128, 1, 0
43
deps/lld/test/COFF/header-size.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
33// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe
4// RUN: llvm-readobj -sections %t.exe | FileCheck %s
4// RUN: llvm-readobj --sections %t.exe | FileCheck %s
55 .globl main
66main:
77 ret
deps/lld/test/COFF/heap.test+5-5
......@@ -1,25 +1,25 @@
11# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
22
33# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
55
66DEFAULT: SizeOfHeapReserve: 1048576
77DEFAULT: SizeOfHeapCommit: 4096
88
99# RUN: lld-link /out:%t.exe /entry:main /heap:0x3000 %t.obj
10# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
10# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
1111# RUN: echo "HEAPSIZE 12288" > %t.def
1212# RUN: lld-link /out:%t.exe /entry:main /def:%t.def %t.obj
13# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
13# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
1414
1515CHECK1: SizeOfHeapReserve: 12288
1616CHECK1: SizeOfHeapCommit: 4096
1717
1818# RUN: lld-link /out:%t.exe /entry:main /heap:0x5000,0x3000 %t.obj
19# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
19# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
2020# RUN: echo "HEAPSIZE 20480,12288" > %t.def
2121# RUN: lld-link /out:%t.exe /entry:main /def:%t.def %t.obj
22# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
22# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
2323
2424CHECK2: SizeOfHeapReserve: 20480
2525CHECK2: SizeOfHeapCommit: 12288
deps/lld/test/COFF/hello32.test+5-6
......@@ -1,9 +1,9 @@
11# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
2# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
2# RUN: lld-link -safeseh:no %t.obj %p/Inputs/std32.lib /subsystem:console \
33# RUN: /entry:main@0 /out:%t.exe /appcontainer
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
5# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
6# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=HEADER %s
5# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
6# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
77
88HEADER: Format: COFF-i386
99HEADER-NEXT: Arch: i386
......@@ -42,10 +42,9 @@ HEADER-NEXT: MinorSubsystemVersion: 0
4242HEADER-NEXT: SizeOfImage: 20480
4343HEADER-NEXT: SizeOfHeaders: 1024
4444HEADER-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
45HEADER-NEXT: Characteristics [ (0x9540)
45HEADER-NEXT: Characteristics [ (0x9140)
4646HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_APPCONTAINER (0x1000)
4747HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE (0x40)
48HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_NO_SEH (0x400)
4948HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT (0x100)
5049HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE (0x8000)
5150HEADER-NEXT: ]
deps/lld/test/COFF/icf-pdata.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj -dll -noentry -out:%t.dll -merge:.xdata=.xdata
4# RUN: llvm-readobj -sections -coff-exports %t.dll | FileCheck %s
4# RUN: llvm-readobj --sections --coff-exports %t.dll | FileCheck %s
55
66# CHECK: Name: .pdata
77# CHECK-NEXT: VirtualSize: 0x18
deps/lld/test/COFF/icf-xdata.s+2-2
......@@ -2,9 +2,9 @@
22# RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj -dll -noentry -out:%t.dll -merge:.xdata=.xdata 2>&1 \
44# RUN: | FileCheck %s --check-prefix=WARN
5# RUN: llvm-readobj -sections %t.dll | FileCheck %s --check-prefix=XDATA
5# RUN: llvm-readobj --sections %t.dll | FileCheck %s --check-prefix=XDATA
66# RUN: lld-link %t.obj -dll -noentry -out:%t.dll
7# RUN: llvm-readobj -sections %t.dll | FileCheck %s --check-prefix=RDATA
7# RUN: llvm-readobj --sections %t.dll | FileCheck %s --check-prefix=RDATA
88
99# There shouldn't be much xdata, because all three .pdata entries (12 bytes
1010# each) should use the same .xdata unwind info.
deps/lld/test/COFF/imports-gnu-autoexport.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: llvm-ar rcs %t-implib.a %t-dabcdh.o %t-dabcds00000.o %t-dabcdt.o
88# RUN: lld-link -lldmingw -dll -out:%t.dll -entry:main -subsystem:console \
99# 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
10# RUN: llvm-readobj --coff-exports %t.dll | FileCheck -check-prefix=EXPORT %s
1111
1212# Check that only the single normal symbol was exported, none of the symbols
1313# from the import library.
deps/lld/test/COFF/imports-gnu.test+1-1
......@@ -9,7 +9,7 @@
99# Not linking with -lldmingw; one can link to GNU import libs even if not targeting MinGW.
1010# RUN: lld-link -out:%t.exe -entry:main -subsystem:console \
1111# 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
12# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
1313
1414# Check that import entries from both libraries show up.
1515
deps/lld/test/COFF/imports-mangle.test+1-1
......@@ -1,7 +1,7 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /opt:noref /entry:main \
33# RUN: %t.obj %p/Inputs/imports-mangle.lib
4# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s
4# RUN: llvm-readobj --coff-imports %t.exe | FileCheck %s
55
66# CHECK: Import {
77# CHECK: Symbol: sym4 (0)
deps/lld/test/COFF/imports.test+4-3
......@@ -4,14 +4,15 @@
44# RUN: lld-link /out:%t.exe /entry:main /subsystem:console \
55# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib
66# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=TEXT %s
7# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
7# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
88
99# RUN: lld-link /out:%t.exe /entry:main /subsystem:console \
1010# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess
1111# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=TEXT %s
12# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
12# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
1313
1414TEXT: Disassembly of section .text:
15TEXT-EMPTY:
1516TEXT-NEXT: .text:
1617TEXT-NEXT: subq $40, %rsp
1718TEXT-NEXT: movq $0, %rcx
......@@ -37,7 +38,7 @@ IMPORT-NEXT: }
3738
3839# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /merge:.rdata=.text \
3940# 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# RUN: llvm-readobj --coff-imports %t.exe | FileCheck -check-prefix=MERGE %s
4142
4243MERGE: Import {
4344MERGE-NEXT: Name: std64.dll
deps/lld/test/COFF/includeoptional.yaml created+39
......@@ -0,0 +1,39 @@
1# RUN: yaml2obj < %s > %t.main.obj
2# RUN: yaml2obj < %p/Inputs/include1c.yaml > %t.lib.obj
3# RUN: rm -f %t.lib.lib
4# RUN: llvm-ar cru %t.lib.lib %t.lib.obj
5# RUN: lld-link /out:%t.exe /entry:main /includeoptional:bar /includeoptional:actuallymissing %t.main.obj %t.lib.lib /verbose >& %t.log
6# RUN: FileCheck %s < %t.log
7
8# CHECK: includeoptional.yaml.tmp.main.obj
9# CHECK: includeoptional.yaml.tmp.lib.lib
10# CHECK: includeoptional.yaml.tmp.lib.lib(includeoptional.yaml.tmp.lib.obj) for bar
11--- !COFF
12header:
13 Machine: IMAGE_FILE_MACHINE_AMD64
14 Characteristics: []
15sections:
16 - Name: .text
17 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
18 Alignment: 4
19 SectionData: B800000000506800000000680000000050E80000000050E800000000
20symbols:
21 - Name: .text
22 Value: 0
23 SectionNumber: 1
24 SimpleType: IMAGE_SYM_TYPE_NULL
25 ComplexType: IMAGE_SYM_DTYPE_NULL
26 StorageClass: IMAGE_SYM_CLASS_STATIC
27 SectionDefinition:
28 Length: 28
29 NumberOfRelocations: 4
30 NumberOfLinenumbers: 0
31 CheckSum: 0
32 Number: 0
33 - Name: main
34 Value: 0
35 SectionNumber: 1
36 SimpleType: IMAGE_SYM_TYPE_NULL
37 ComplexType: IMAGE_SYM_DTYPE_NULL
38 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
39...
deps/lld/test/COFF/includeoptional2.yaml created+44
......@@ -0,0 +1,44 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: not lld-link /out:%t.exe /entry:main /includeoptional:undeffunc %t.obj /verbose 2>&1 | FileCheck %s
3
4# CHECK: error: undefined symbol: undeffunc
5
6--- !COFF
7header:
8 Machine: IMAGE_FILE_MACHINE_AMD64
9 Characteristics: []
10sections:
11 - Name: .text
12 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
13 Alignment: 4
14 SectionData: B800000000506800000000680000000050E80000000050E800000000
15 Relocations:
16 - VirtualAddress: 17
17 SymbolName: undeffunc
18 Type: IMAGE_REL_AMD64_REL32
19symbols:
20 - Name: .text
21 Value: 0
22 SectionNumber: 1
23 SimpleType: IMAGE_SYM_TYPE_NULL
24 ComplexType: IMAGE_SYM_DTYPE_NULL
25 StorageClass: IMAGE_SYM_CLASS_STATIC
26 SectionDefinition:
27 Length: 28
28 NumberOfRelocations: 1
29 NumberOfLinenumbers: 0
30 CheckSum: 0
31 Number: 0
32 - Name: main
33 Value: 0
34 SectionNumber: 1
35 SimpleType: IMAGE_SYM_TYPE_NULL
36 ComplexType: IMAGE_SYM_DTYPE_NULL
37 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
38 - Name: undeffunc
39 Value: 0
40 SectionNumber: 0
41 SimpleType: IMAGE_SYM_TYPE_NULL
42 ComplexType: IMAGE_SYM_DTYPE_NULL
43 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
44...
deps/lld/test/COFF/invalid-debug-type.test+8-3
......@@ -1,6 +1,11 @@
11# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
22# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3# RUN: lld-link /debug /debugtype:invalid /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
4# RUN: %t1.obj %t2.obj 2>&1 | FileCheck %s
3# RUN: lld-link /debug /debugtype:invalid /pdb:%t.pdb /dll /out:%t.dll \
4# RUN: /entry:main /nodefaultlib %t1.obj %t2.obj 2>&1 | FileCheck %s
5# CHECK: /debugtype: unknown option 'invalid'
56
6# CHECK: /debugtype: unknown option: invalid
\ No newline at end of file
7# RUN: lld-link /debug /debugtype:invalid,foo /pdb:%t.pdb /dll /out:%t.dll \
8# RUN: /entry:main /nodefaultlib %t1.obj %t2.obj 2>&1 | \
9# RUN: FileCheck --check-prefix=TWO %s
10# TWO: /debugtype: unknown option 'invalid'
11# TWO: /debugtype: unknown option 'foo'
deps/lld/test/COFF/largeaddressaware.test+2-2
......@@ -1,7 +1,7 @@
11# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
2# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
2# RUN: lld-link -safeseh:no %t.obj %p/Inputs/std32.lib /subsystem:console \
33# RUN: /entry:main@0 /out:%t.exe /largeaddressaware
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=HEADER %s
55
66HEADER: Format: COFF-i386
77HEADER-NEXT: Arch: i386
deps/lld/test/COFF/lib-module-asm.ll created+22
......@@ -0,0 +1,22 @@
1; REQUIRES: x86
2; PR41803: llvm-link /lib on object with module asm crashes
3; RUN: rm -f %t.lib
4; RUN: llvm-as -o %t.obj %s
5; RUN: lld-link /lib /out:%t.lib %t.obj
6; RUN: llvm-nm -M %t.lib | FileCheck %s
7
8target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
9target triple = "i386-pc-windows-msvc19.11.0"
10
11module asm ".global global_asm_sym"
12module asm "global_asm_sym:"
13module asm "local_asm_sym:"
14module asm ".long undef_asm_sym"
15
16; CHECK: Archive map
17; CHECK-NEXT: global_asm_sym in {{.*}}lib-module-asm.ll.tmp.obj
18
19; CHECK: lib-module-asm.ll.tmp.obj:{{$}}
20; CHECK-NEXT: T global_asm_sym
21; CHECK-NEXT: t local_asm_sym
22; CHECK-NEXT: U undef_asm_sym
deps/lld/test/COFF/line-error.yaml+160-160
......@@ -1,160 +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...
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/linkrepro-pdb.test+14-1
......@@ -4,6 +4,19 @@ RUN: rm -rf %t && mkdir -p %t && cd %t
44RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj
55RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj
66RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb
7RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib -linkrepro:.
7RUN: lld-link a.obj b.obj -entry:main -debug -out:%t.exe -pdb:%t.pdb -nodefaultlib -linkrepro:.
88RUN: tar xOf repro.tar repro/%:t/ts.pdb > repro-ts.pdb
99RUN: diff ts.pdb repro-ts.pdb
10
11RUN: tar xf repro.tar
12RUN: cat repro/response.txt | FileCheck -check-prefix=PDB %s
13
14PDB: -out:linkrepro-pdb.test.tmp.exe
15PDB-NEXT: -pdb:linkrepro-pdb.test.tmp.pdb
16
17RUN: yaml2obj < %p/Inputs/export.yaml > %t1.obj
18RUN: lld-link /out:%t1.dll /dll %t1.obj /implib:%t1.lib /export:exportfn1 /export:exportfn2 /linkrepro:.
19RUN: tar xf repro.tar
20RUN: cat repro/response.txt | FileCheck -check-prefix=IMP %s
21
22IMP: /implib:linkrepro-pdb.test.tmp1.lib
deps/lld/test/COFF/loadcfg.ll+1-1
......@@ -1,7 +1,7 @@
11; REQUIRES: x86
22; RUN: llvm-as -o %t.obj %s
33; RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
4; RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4; RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
55
66; CHECK: LoadConfigTableRVA: 0x2000
77; CHECK: LoadConfigTableSize: 0x70
deps/lld/test/COFF/loadcfg.test+1-1
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
44
55# CHECK: LoadConfigTableRVA: 0x2000
66# CHECK: LoadConfigTableSize: 0x70
deps/lld/test/COFF/loadcfg32.test+2-2
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
2# RUN: lld-link -safeseh:no /out:%t.exe %t.obj /entry:main /subsystem:console
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
44
55# CHECK: LoadConfigTableRVA: 0x2000
66# CHECK: LoadConfigTableSize: 0x40
deps/lld/test/COFF/locally-imported-arm64.test+1-1
......@@ -1,7 +1,7 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /entry:main %t.obj
33# RUN: llvm-objdump -s %t.exe | FileCheck %s
4# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
4# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
55
66# CHECK: Contents of section .text:
77# CHECK-NEXT: 1000 00200000
deps/lld/test/COFF/locally-imported.test+1-1
......@@ -1,7 +1,7 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /entry:main %t.obj 2>&1 | FileCheck -check-prefix=WARN %s
33# RUN: llvm-objdump -s %t.exe | FileCheck %s
4# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
4# RUN: llvm-readobj --coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
55
66# WARN: warning: [[INPUT:.+]]: locally defined symbol imported: main (defined in [[INPUT]])
77
deps/lld/test/COFF/locally-imported32.test+1-1
......@@ -1,5 +1,5 @@
11# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj
2# RUN: lld-link -safeseh:no /out:%t.exe /entry:main %t.obj
33# RUN: llvm-objdump -s %t.exe | FileCheck %s
44
55# CHECK: Contents of section .text:
deps/lld/test/COFF/long-section-name.test+2-2
......@@ -1,8 +1,8 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj -sections %t.exe | FileCheck %s
3# RUN: llvm-readobj --sections %t.exe | FileCheck %s
44# RUN: lld-link /debug /out:%t2.exe /entry:main %t.obj
5# RUN: llvm-readobj -sections %t2.exe | FileCheck %s
5# RUN: llvm-readobj --sections %t2.exe | FileCheck %s
66
77# CHECK: Name: .eh_fram (
88# CHECK: Name: .data_long_section_name
deps/lld/test/COFF/lto-comdat.ll+9-6
......@@ -14,40 +14,42 @@
1414; Check that, when we use an LTO main with LTO objects, we optimize away all
1515; of f1, f2, and comdat.
1616; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat1.lto.obj %T/comdat2.lto.obj
17; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-11 %s
17; RUN: llvm-readobj --file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-11 %s
1818; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-11 %s
1919; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat.lto.lib
20; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-11 %s
20; RUN: llvm-readobj --file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-11 %s
2121; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-11 %s
2222
2323; Check that, when we use a non-LTO main with LTO objects, we pick the comdat
2424; implementation in LTO, elide calls to it from inside LTO, and retain the
2525; call to comdat from main.
2626; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.obj %T/comdat1.lto.obj %T/comdat2.lto.obj
27; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-01 %s
27; RUN: llvm-readobj --file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-01 %s
2828; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-01 %s
2929; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.obj %T/comdat.lto.lib
30; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-01 %s
30; RUN: llvm-readobj --file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-01 %s
3131; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-01 %s
3232
3333; Check that, when we use an LTO main with non-LTO objects, we pick the comdat
3434; implementation in LTO, elide the call to it from inside LTO, and keep the
3535; calls to comdat from the non-LTO objects.
3636; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat1.obj %T/comdat2.obj
37; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-10 %s
37; RUN: llvm-readobj --file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-10 %s
3838; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-10 %s
3939; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat.lib
40; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-10 %s
40; RUN: llvm-readobj --file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-10 %s
4141; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-10 %s
4242
4343; HEADERS-11: AddressOfEntryPoint: 0x1000
4444; TEXT-11: Disassembly of section .text:
45; TEXT-11-EMPTY:
4546; TEXT-11-NEXT: .text:
4647; TEXT-11-NEXT: xorl %eax, %eax
4748; TEXT-11-NEXT: retq
4849
4950; HEADERS-01: AddressOfEntryPoint: 0x1000
5051; TEXT-01: Disassembly of section .text:
52; TEXT-01-EMPTY:
5153; TEXT-01-NEXT: .text:
5254; TEXT-01-NEXT: subq $40, %rsp
5355; TEXT-01-NEXT: callq 23
......@@ -65,6 +67,7 @@
6567
6668; HEADERS-10: AddressOfEntryPoint: 0x1020
6769; TEXT-10: Disassembly of section .text:
70; TEXT-10-EMPTY:
6871; TEXT-10-NEXT: .text:
6972; TEXT-10-NEXT: subq $40, %rsp
7073; TEXT-10-NEXT: callq 55
deps/lld/test/COFF/lto-icf.ll+1-1
......@@ -4,7 +4,7 @@
44
55; RUN: llvm-as %s -o %t.bc
66; RUN: lld-link -opt:icf -dll -noentry %t.bc -out:%t.dll
7; RUN: llvm-readobj -coff-exports %t.dll | FileCheck %s
7; RUN: llvm-readobj --coff-exports %t.dll | FileCheck %s
88
99; CHECK: Export {
1010; CHECK: Export {
deps/lld/test/COFF/lto-lazy-reference.ll+4
......@@ -9,6 +9,10 @@
99target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
1010target triple = "i686-pc-windows-msvc18.0.0"
1111
12; Define fltused, since we don't link against the MS C runtime but are
13; using floats.
14@_fltused = dllexport global i32 0, align 4
15
1216define double @main(double %x) {
1317entry:
1418 ; When compiled, this defines the __real@40800000 symbol, which already has a
deps/lld/test/COFF/lto-new-symbol.ll+4
......@@ -5,6 +5,10 @@
55target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
66target triple = "x86_64-pc-windows-msvc"
77
8; Define fltused, since we don't link against the MS C runtime but are
9; using floats.
10@_fltused = dllexport global i32 0, align 4
11
812define void @foo(<4 x i32>* %p, <4 x float>* %q, i1 %t) nounwind {
913entry:
1014 br label %loop
deps/lld/test/COFF/lto.ll+9-6
......@@ -10,30 +10,31 @@
1010; RUN: llvm-ar cru %T/foo.lib %T/foo.obj
1111
1212; RUN: lld-link /out:%T/main.exe /entry:main /include:f2 /subsystem:console %T/main.lto.obj %T/foo.lto.obj
13; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-11 %s
13; RUN: llvm-readobj --file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-11 %s
1414; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-11 %s
1515; RUN: lld-link /out:%T/main.exe /entry:main /include:f2 /subsystem:console %T/main.lto.obj %T/foo.lto.lib /verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
16; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-11 %s
16; RUN: llvm-readobj --file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-11 %s
1717; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-11 %s
1818
1919; RUN: lld-link /out:%T/main.exe /entry:main /subsystem:console %T/main.obj %T/foo.lto.obj
20; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-01 %s
20; RUN: llvm-readobj --file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-01 %s
2121; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-01 %s
2222; RUN: lld-link /out:%T/main.exe /entry:main /subsystem:console %T/main.obj %T/foo.lto.lib
23; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-01 %s
23; RUN: llvm-readobj --file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-01 %s
2424; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-01 %s
2525
2626; RUN: lld-link /out:%T/main.exe /entry:main /subsystem:console %T/main.lto.obj %T/foo.obj
27; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-10 %s
27; RUN: llvm-readobj --file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-10 %s
2828; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-10 %s
2929; RUN: lld-link /out:%T/main.exe /entry:main /subsystem:console %T/main.lto.obj %T/foo.lib
30; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-10 %s
30; RUN: llvm-readobj --file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-10 %s
3131; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-10 %s
3232
3333; VERBOSE: foo.lto.lib({{.*}}foo.lto.obj)
3434
3535; HEADERS-11: AddressOfEntryPoint: 0x1000
3636; TEXT-11: Disassembly of section .text:
37; TEXT-11-EMPTY:
3738; TEXT-11-NEXT: .text:
3839; TEXT-11-NEXT: xorl %eax, %eax
3940; TEXT-11-NEXT: retq
......@@ -55,6 +56,7 @@
5556
5657; HEADERS-01: AddressOfEntryPoint: 0x1000
5758; TEXT-01: Disassembly of section .text:
59; TEXT-01-EMPTY:
5860; TEXT-01-NEXT: .text:
5961; TEXT-01-NEXT: subq $40, %rsp
6062; TEXT-01-NEXT: callq 23
......@@ -81,6 +83,7 @@
8183
8284; HEADERS-10: AddressOfEntryPoint: 0x1020
8385; TEXT-10: Disassembly of section .text:
86; TEXT-10-EMPTY:
8487; TEXT-10-NEXT: .text:
8588; TEXT-10-NEXT: retq
8689; TEXT-10-NEXT: nop
deps/lld/test/COFF/machine.test+8-8
......@@ -1,18 +1,18 @@
11# RUN: yaml2obj %p/Inputs/machine-x64.yaml > %t.obj
2# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
4# RUN: lld-link /entry:main /subsystem:console /machine:x64 \
2# RUN: lld-link -safeseh:no /entry:main /subsystem:console /out:%t.exe %t.obj
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
4# RUN: lld-link -safeseh:no /entry:main /subsystem:console /machine:x64 \
55# RUN: /out:%t.exe %t.obj
6# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
6# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
77
88AMD64: Machine: IMAGE_FILE_MACHINE_AMD64
99
1010# RUN: yaml2obj %p/Inputs/machine-x86.yaml > %t.obj
11# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj
12# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
13# RUN: lld-link /entry:main /subsystem:console /machine:x86 \
11# RUN: lld-link -safeseh:no /entry:main /subsystem:console /out:%t.exe %t.obj
12# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=I386 %s
13# RUN: lld-link -safeseh:no /entry:main /subsystem:console /machine:x86 \
1414# RUN: /out:%t.exe %t.obj /fixed
15# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
15# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=I386 %s
1616
1717I386: Machine: IMAGE_FILE_MACHINE_I386
1818
deps/lld/test/COFF/manifestinput.test+2-2
......@@ -5,7 +5,7 @@
55# RUN: /manifest:embed \
66# RUN: /manifestuac:"level='requireAdministrator'" \
77# RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj
8# RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \
8# RUN: llvm-readobj --coff-resources --file-headers %t.exe | FileCheck %s \
99# RUN: -check-prefix TEST_EMBED
1010
1111TEST_EMBED: ResourceTableRVA: 0x2000
......@@ -14,7 +14,7 @@ TEST_EMBED-DAG: Resources [
1414TEST_EMBED-NEXT: Total Number of Resources: 1
1515TEST_EMBED-DAG: Number of String Entries: 0
1616TEST_EMBED-NEXT: Number of ID Entries: 1
17TEST_EMBED-NEXT: Type: kRT_MANIFEST (ID 24) [
17TEST_EMBED-NEXT: Type: MANIFEST (ID 24) [
1818TEST_EMBED-NEXT: Table Offset: 0x18
1919TEST_EMBED-NEXT: Number of String Entries: 0
2020TEST_EMBED-NEXT: Number of ID Entries: 1
deps/lld/test/COFF/merge.test+2-2
......@@ -1,11 +1,11 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
33# RUN: /merge:.foo=.abc /merge:.bar=.def %t.obj /debug
4# RUN: llvm-readobj -sections %t.exe | FileCheck %s
4# RUN: llvm-readobj --sections %t.exe | FileCheck %s
55
66# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
77# RUN: /merge:.foo=.bar /merge:.bar=.abc %t.obj /debug
8# RUN: llvm-readobj -sections %t.exe | FileCheck --check-prefix=CHECK2 %s
8# RUN: llvm-readobj --sections %t.exe | FileCheck --check-prefix=CHECK2 %s
99
1010# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \
1111# RUN: /merge:.rsrc=.foo %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RSRC %s
deps/lld/test/COFF/multiple-resource-objs.test created+11
......@@ -0,0 +1,11 @@
1# RUN: llvm-cvtres /out:%t_resource.obj %S/Inputs/resource.res
2# RUN: llvm-cvtres /out:%t_id.obj %S/Inputs/id.res
3# RUN: not lld-link /out:%t.exe /dll /noentry %t_id.obj %t_resource.obj 2>&1 | \
4# RUN: FileCheck --check-prefix=TWOOBJ %s
5
6TWOOBJ: error: {{.*}}_resource.obj: more than one resource obj file not allowed, already got {{.*}}_id.obj
7
8# RUN: not lld-link /out:%t.exe /dll /noentry %S/Inputs/id.res %t_resource.obj 2>&1 | \
9# RUN: FileCheck --check-prefix=OBJRES %s
10
11OBJRES: error: internal .obj file created from .res files: more than one resource obj file not allowed, already got {{.*}}_resource.obj
deps/lld/test/COFF/no-idata.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj
44# RUN: lld-link -out:%t.exe -entry:main -subsystem:console %t.obj
55# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DUMP %s
6# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DIRECTORY %s
6# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=DIRECTORY %s
77
88 .text
99 .global main
deps/lld/test/COFF/no-ipi-stream.test created+4
......@@ -0,0 +1,4 @@
1# RUN: rm -rf %t && mkdir %t
2# RUN: yaml2obj < %p/Inputs/no-ipi-stream-obj.obj.yaml > %t/no-ipi-stream-obj.obj
3# RUN: llvm-pdbutil yaml2pdb %p/Inputs/no-ipi-stream-pdb.pdb.yaml -pdb=%t/no-ipi-stream-pdb.pdb
4# RUN: lld-link -safeseh:no /dll /noentry /debug %t/no-ipi-stream-obj.obj
deps/lld/test/COFF/nodefaultlib.test+9-2
......@@ -19,8 +19,8 @@
1919# RUN: /nodefaultlib:std64.lib >& %t.log || true
2020# RUN: FileCheck -check-prefix=CHECK3 %s < %t.log
2121
22CHECK1: error: could not open hello64.obj: {{[Nn]}}o such file or directory
23CHECK2: error: could not open hello64: {{[Nn]}}o such file or directory
22CHECK1: error: could not open 'hello64.obj': {{[Nn]}}o such file or directory
23CHECK2: error: could not open 'hello64': {{[Nn]}}o such file or directory
2424CHECK3: error: undefined symbol: MessageBoxA
2525CHECK3-NEXT: >>> referenced by {{.*}}hello64.obj:(main)
2626
......@@ -29,3 +29,10 @@ CHECK3-NEXT: >>> referenced by {{.*}}hello64.obj:(main)
2929
3030# RUN: env LIB=%T lld-link /out:%t.exe /entry:main \
3131# RUN: /subsystem:console hello64.obj /defaultlib:std64.lib
32
33MSVC stamps uppercase references in OBJ directives, thus ensure that passing lowercase 'libcmt' and 'oldnames' to /nodefaultlib works.
34# RUN: lld-link %S/Inputs/precomp.obj %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib:libcmt /nodefaultlib:oldnames /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
35# RUN: llvm-pdbutil dump -modules %t.pdb | FileCheck %s -check-prefix UPPERCASE
36
37UPPERCASE-NOT: OLDNAMES
38UPPERCASE-NOT: LIBCMT
deps/lld/test/COFF/noentry.test+2-2
......@@ -1,8 +1,8 @@
11# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
22# RUN: lld-link /out:%t.dll /dll %t.obj
3# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=ENTRY %s
3# RUN: llvm-readobj --file-headers %t.dll | FileCheck -check-prefix=ENTRY %s
44# RUN: lld-link /out:%t.dll /dll /noentry %t.obj
5# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOENTRY %s
5# RUN: llvm-readobj --file-headers %t.dll | FileCheck -check-prefix=NOENTRY %s
66
77ENTRY: AddressOfEntryPoint: 0x1000
88NOENTRY: AddressOfEntryPoint: 0x0
deps/lld/test/COFF/options.test+60-20
......@@ -1,65 +1,105 @@
11# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
22
33# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=BIND %s
55# RUN: lld-link /allowbind /out:%t.exe /entry:main %t.obj
6# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s
6# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=BIND %s
77BIND-NOT: IMAGE_DLL_CHARACTERISTICS_NO_BIND
88
99# RUN: lld-link /allowbind:no /out:%t.exe /entry:main %t.obj
10# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOBIND %s
10# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NOBIND %s
1111NOBIND: IMAGE_DLL_CHARACTERISTICS_NO_BIND
1212
1313# RUN: lld-link /out:%t.exe /entry:main %t.obj
14# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s
14# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=ISO %s
1515# RUN: lld-link /allowisolation /out:%t.exe /entry:main %t.obj
16# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s
16# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=ISO %s
1717ISO-NOT: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION
1818
1919# RUN: lld-link /allowisolation:no /out:%t.exe /entry:main %t.obj
20# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOISO %s
20# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NOISO %s
2121NOISO: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION
2222
2323# RUN: lld-link /out:%t.exe /entry:main %t.obj
24# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s
24# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=ENT %s
2525# RUN: lld-link /out:%t.exe /entry:main /highentropyva %t.obj
26# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s
26# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=ENT %s
2727ENT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
2828
2929# RUN: lld-link /out:%t.exe /highentropyva:no /out:%t.exe /entry:main %t.obj
30# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOENT %s
30# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NOENT %s
3131NOENT-NOT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
3232
3333# RUN: lld-link /out:%t.exe /entry:main /integritycheck %t.obj
34# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=INT %s
34# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=INT %s
3535INT: IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY
3636
3737# RUN: lld-link /out:%t.exe /entry:main %t.obj
38# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOINT %s
38# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NOINT %s
3939# RUN: lld-link /out:%t.exe /integritycheck:no /out:%t.exe /entry:main %t.obj
40# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOINT %s
40# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NOINT %s
4141NOINT-NOT: IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY
4242
4343# RUN: lld-link /out:%t.exe /entry:main %t.obj
44# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
44# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
4545# RUN: lld-link /out:%t.exe /entry:main /nxcompat %t.obj
46# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
46# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
4747NXCOMPAT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
4848
4949# RUN: lld-link /out:%t.exe /nxcompat:no /out:%t.exe /entry:main %t.obj
50# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NONXCOMPAT %s
50# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NONXCOMPAT %s
5151NONXCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
5252
53# RUN: lld-link /out:%t.exe /entry:main /swaprun:CD %t.obj
54# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=SWAPCD %s
55# RUN: lld-link /out:%t.exe /entry:main /swaprun:cd,net %t.obj
56# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=SWAPCD %s
57SWAPCD: IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
58
59# RUN: lld-link /out:%t.exe /entry:main %t.obj
60# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NOSWAPCD %s
61NOSWAPCD-NOT: IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
62
63# RUN: lld-link /out:%t.exe /entry:main /swaprun:NeT %t.obj
64# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=SWAPNET %s
65# RUN: lld-link /out:%t.exe /entry:main /swaprun:net,cd,cd,net %t.obj
66# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=SWAPNET %s
67SWAPNET: IMAGE_FILE_NET_RUN_FROM_SWAP
68
69# RUN: lld-link /out:%t.exe /entry:main %t.obj
70# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NOSWAPNET %s
71NOSWAPNET-NOT: IMAGE_FILE_NET_RUN_FROM_SWAP
72
73# RUN: not lld-link /out:%t.exe /entry:main /swaprun: %t.obj 2>&1 | \
74# RUN: FileCheck -check-prefix=SWAPERR1 %s
75# RUN: not lld-link /out:%t.exe /entry:main /swaprun:cd, %t.obj 2>&1 | \
76# RUN: FileCheck -check-prefix=SWAPERR1 %s
77# RUN: not lld-link /out:%t.exe /entry:main /swaprun:,, %t.obj 2>&1 | \
78# RUN: FileCheck -check-prefix=SWAPERR1 %s
79# RUN: not lld-link /out:%t.exe /entry:main /swaprun:,cd %t.obj 2>&1 | \
80# RUN: FileCheck -check-prefix=SWAPERR1 %s
81SWAPERR1: /swaprun: missing argument
82
83# RUN: not lld-link /out:%t.exe /entry:main /swaprun:foo %t.obj 2>&1 | \
84# RUN: FileCheck -check-prefix=SWAPERR2 %s
85# RUN: not lld-link /out:%t.exe /entry:main /swaprun:cd,foo,net %t.obj 2>&1 | \
86# RUN: FileCheck -check-prefix=SWAPERR2 %s
87SWAPERR2: /swaprun: invalid argument: foo
88
89# RUN: not lld-link /out:%t.exe /entry:main /swaprun:cdfoo,net %t.obj 2>&1 | \
90# RUN: FileCheck -check-prefix=SWAPERR3 %s
91SWAPERR3: /swaprun: invalid argument: cdfoo
92
5393# RUN: lld-link /out:%t.exe /entry:main %t.obj
54# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
94# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
5595# RUN: lld-link /out:%t.exe /entry:main /tsaware %t.obj
56# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
96# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
5797TSAWARE: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE
5898
5999# RUN: lld-link /tsaware:no /out:%t.exe /entry:main %t.obj
60# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOTSAWARE %s
100# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NOTSAWARE %s
61101# RUN: lld-link /dll /out:%t.dll /entry:main %t.obj
62# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOTSAWARE %s
102# RUN: llvm-readobj --file-headers %t.dll | FileCheck -check-prefix=NOTSAWARE %s
63103# RUN: lld-link /tsaware /dll /out:%t.dll /entry:main %t.obj
64# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOTSAWARE %s
104# RUN: llvm-readobj --file-headers %t.dll | FileCheck -check-prefix=NOTSAWARE %s
65105NOTSAWARE-NOT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE
deps/lld/test/COFF/order-i386.test+2-2
......@@ -3,12 +3,12 @@
33# RUN: echo fn1 > %t.order
44# RUN: echo fn2 >> %t.order
55
6# RUN: lld-link -entry:fn1 -subsystem:console -opt:noref %t.obj \
6# RUN: lld-link -safeseh:no -entry:fn1 -subsystem:console -opt:noref %t.obj \
77# RUN: -lldmap:- -out:%t.exe -order:@%t.order | FileCheck %s
88# CHECK: fn1
99# CHECK: fn2
1010
11# RUN: lld-link -entry:fn1 -subsystem:console -opt:noref %t.obj \
11# RUN: lld-link -safeseh:no -entry:fn1 -subsystem:console -opt:noref %t.obj \
1212# RUN: -lldmap:- -out:%t.exe | FileCheck -check-prefix=DEFAULT %s
1313# DEFAULT: fn2
1414# DEFAULT: fn1
deps/lld/test/COFF/output-chars.test+4-4
......@@ -1,12 +1,12 @@
11# RUN: yaml2obj %s > %t.obj
22# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj
3# RUN: llvm-readobj -sections %t.dll | FileCheck %s
3# RUN: llvm-readobj --sections %t.dll | FileCheck %s
44# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj /section:.foo,rwe
5# RUN: llvm-readobj -sections %t.dll | FileCheck --check-prefix=SECTION %s
5# RUN: llvm-readobj --sections %t.dll | FileCheck --check-prefix=SECTION %s
66# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj /merge:.foo=.bar
7# RUN: llvm-readobj -sections -section-data %t.dll | FileCheck --check-prefix=MERGE %s
7# RUN: llvm-readobj --sections --section-data %t.dll | FileCheck --check-prefix=MERGE %s
88# RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj /merge:.foo=.bar /section:.foo,rwe
9# RUN: llvm-readobj -sections %t.dll | FileCheck --check-prefix=MERGE-SECTION %s
9# RUN: llvm-readobj --sections %t.dll | FileCheck --check-prefix=MERGE-SECTION %s
1010
1111# CHECK: Name: .foo
1212# CHECK: Characteristics [
deps/lld/test/COFF/pdb-comdat.test+2-2
......@@ -48,9 +48,9 @@ CHECK-NEXT: module = 2, sum name = 0, offset = 120
4848CHECK-NEXT: 128 | S_PROCREF [size = 20] `foo`
4949CHECK-NEXT: module = 1, sum name = 0, offset = 208
5050CHECK-NEXT: 104 | S_GDATA32 [size = 24] `global`
51CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000
51CHECK-NEXT: type = 0x0074 (int), addr = 0003:0000
5252CHECK-NEXT: 168 | S_GDATA32 [size = 24] `global`
53CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000
53CHECK-NEXT: type = 0x0074 (int), addr = 0003:0000
5454
5555CHECK: Symbols
5656CHECK: ============================================================
deps/lld/test/COFF/pdb-debug-f.s+1-1
......@@ -1,6 +1,6 @@
11# REQUIRES: x86
22# 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
3# RUN: lld-link -safeseh:no /subsystem:console /debug /nodefaultlib /entry:foo /out:%t.exe /pdb:%t.pdb %t.obj
44# RUN: llvm-pdbutil dump -fpo %t.pdb | FileCheck %s
55
66# CHECK: Old FPO Data
deps/lld/test/COFF/pdb-exe-path-dots.test+1-1
......@@ -5,6 +5,6 @@ RUN: mkdir %t
55RUN: mkdir %t/foo
66RUN: lld-link /debug /pdb:%t/foo/./out.pdb /out:%t/out.exe /entry:main /nodefaultlib \
77RUN: %t1.obj %t2.obj
8RUN: llvm-readobj -coff-debug-directory %t/out.exe | FileCheck %s
8RUN: llvm-readobj --coff-debug-directory %t/out.exe | FileCheck %s
99
1010CHECK: PDBFileName: {{.*}}tmp{{/|\\}}foo{{/|\\}}out.pdb
\ No newline at end of file
deps/lld/test/COFF/pdb-global-constants.test created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj %S/Inputs/pdb-global-constants-a.s -o %t-a.obj -triple x86_64-windows-msvc
3# RUN: llvm-mc -filetype=obj %S/Inputs/pdb-global-constants-b.s -o %t-b.obj -triple x86_64-windows-msvc
4# RUN: lld-link -entry:main -nodefaultlib %t-a.obj %t-b.obj -out:%t.exe -pdb:%t.pdb -debug
5# RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s
6
7# Test that lld deduplicates S_CONSTANT records with the same name and value.
8#
9# Compiled from this C code, using
10# clang t.cpp -g -gcodeview -S
11#
12# %t-a.cpp:
13# const int Foo = 41;
14# const int Bar = 42;
15# int main() { return Foo + Bar; }
16#
17# %t-b.cpp:
18# const int Foo = 42;
19# const int Bar = 42;
20# int foobar() { return Foo + Bar; }
21
22CHECK: Global Symbols
23CHECK: 88 | S_CONSTANT [size = 16] `Bar`
24CHECK-NEXT: type = 0x1002 (const int), value = 42
25CHECK-NEXT: 72 | S_CONSTANT [size = 16] `Foo`
26CHECK-NEXT: type = 0x1002 (const int), value = 41
27CHECK-NEXT: 128 | S_CONSTANT [size = 16] `Foo`
28CHECK-NEXT: type = 0x1002 (const int), value = 42
deps/lld/test/COFF/pdb-global-gc.yaml+1
......@@ -23,6 +23,7 @@
2323# CHECK: ============================================================
2424# CHECK-NEXT: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`:
2525# CHECK-NEXT: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`:
26# CHECK-NEXT: Error loading module stream 1. The specified stream could not be loaded. Module stream not present
2627# CHECK-NEXT: Mod 0002 | `* Linker *`:
2728
2829--- !COFF
deps/lld/test/COFF/pdb-globals.test+5
......@@ -2,6 +2,11 @@ RUN: yaml2obj %S/Inputs/pdb-globals.yaml > %t.obj
22RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj
33RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
44
5RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj /threads
6RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
7RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj /threads:no
8RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
9
510# Test that we correctly distribute symbols between the globals and module
611# symbol streams. Specifically:
712# * S_UDT, S_GDATA32, and S_CONSTANT end up in the globals stream, and are
deps/lld/test/COFF/pdb-inlinees-extrafiles.s created+334
......@@ -0,0 +1,334 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj %s -o %t.obj -triple x86_64-windows-msvc
3# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe -pdb:%t.pdb -debug
4# RUN: llvm-pdbutil dump -il %t.pdb | FileCheck %s
5
6# The assembly was hand written to model the following C code. As of this
7# writing, clang does not emit extra files for inlinees, so it had to be hand
8# written.
9
10# // t1.h:
11# ++x;
12# #include "t2.h"
13# ++x;
14
15# // t2.h:
16# ++x;
17# __debugbreak();
18# ++x;
19
20# // t.c:
21# volatile int x;
22# static __forceinline void inlinee_1(void) {
23# ++x;
24# #include "t1.inc"
25# ++x;
26# }
27# int main() {
28# ++x;
29# inlinee_1();
30# ++x;
31# return x;
32# }
33
34# CHECK: Inlinee Lines
35# CHECK: Mod 0000 | `{{.*}}pdb-inlinees-extrafiles.s.tmp.obj`:
36# CHECK-NEXT: Inlinee | Line | Source File
37# CHECK-NEXT: 0x1000 | 7 | C:\src\llvm-project\build\t.c (MD5: A79D837C976E9F0463A474D74E2EE9E7)
38# CHECK-NEXT: C:\src\llvm-project\build\t1.h (MD5: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
39# CHECK-NEXT: C:\src\llvm-project\build\t2.h (MD5: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
40
41 .text
42 .def @feat.00;
43 .scl 3;
44 .type 0;
45 .endef
46 .globl @feat.00
47.set @feat.00, 0
48 .intel_syntax noprefix
49 .file "t.c"
50 .def main;
51 .scl 2;
52 .type 32;
53 .endef
54 .section .text,"xr",one_only,main
55 .globl main # -- Begin function main
56main: # @main
57.Lfunc_begin0:
58 .cv_func_id 0
59# %bb.0: # %entry
60 .cv_file 1 "C:\\src\\llvm-project\\build\\t.c" "A79D837C976E9F0463A474D74E2EE9E7" 1
61 .cv_file 2 "C:\\src\\llvm-project\\build\\t1.h" "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1
62 .cv_file 3 "C:\\src\\llvm-project\\build\\t2.h" "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1
63 .cv_loc 0 1 13 0 # t.c:13:0
64 inc dword ptr [rip + x]
65.Ltmp0:
66 .cv_inline_site_id 1 within 0 inlined_at 1 14 0
67 .cv_loc 1 1 3 0 # t.c:3:0
68 inc dword ptr [rip + x]
69.Ltmp1:
70 .cv_loc 1 2 1 0 # t1.h:1:0
71 inc dword ptr [rip + x]
72 .cv_loc 1 3 1 0 # t2.h:1:0
73 inc dword ptr [rip + x]
74 .cv_loc 1 3 2 0 # t2.h:2:0
75 int3
76 .cv_loc 1 3 3 0 # t2.h:3:0
77 inc dword ptr [rip + x]
78 .cv_loc 1 2 3 0 # t1.h:3:0
79 inc dword ptr [rip + x]
80.Ltmp2:
81 .cv_loc 1 1 5 0 # t.c:5:0
82 inc dword ptr [rip + x]
83.Ltmp3:
84 .cv_loc 0 1 15 0 # t.c:15:0
85 inc dword ptr [rip + x]
86 .cv_loc 0 1 16 0 # t.c:16:0
87 mov eax, dword ptr [rip + x]
88 ret
89.Ltmp4:
90.Lfunc_end0:
91 # -- End function
92 .comm x,4,2 # @x
93 .section .debug$S,"dr"
94 .p2align 2
95 .long 4 # Debug section magic
96 .long 241
97 .long .Ltmp6-.Ltmp5 # Subsection size
98.Ltmp5:
99 .short .Ltmp8-.Ltmp7 # Record length
100.Ltmp7:
101 .short 4412 # Record kind: S_COMPILE3
102 .long 0 # Flags and language
103 .short 208 # CPUType
104 .short 9 # Frontend version
105 .short 0
106 .short 0
107 .short 0
108 .short 9000 # Backend version
109 .short 0
110 .short 0
111 .short 0
112 .asciz "clang version 9.0.0 (git@github.com:llvm/llvm-project.git aa762a56caf3ef2b0b41c501e66d3ef32903a2d0)" # Null-terminated compiler version string
113 .p2align 2
114.Ltmp8:
115.Ltmp6:
116 .p2align 2
117 .long 246 # Inlinee lines subsection
118 .long .Ltmp10-.Ltmp9 # Subsection size
119.Ltmp9:
120 .long 1 # Inlinee lines signature, extra files
121
122 # Inlined function inlinee_1 starts at t.c:7
123 .long 4098 # Type index of inlined function
124 .cv_filechecksumoffset 1 # Offset into filechecksum table
125 .long 7 # Starting line number
126 .long 2
127 .cv_filechecksumoffset 2 # Offset into filechecksum table
128 .cv_filechecksumoffset 3 # Offset into filechecksum table
129
130.Ltmp10:
131 .p2align 2
132 .section .debug$S,"dr",associative,main
133 .p2align 2
134 .long 4 # Debug section magic
135 .long 241 # Symbol subsection for main
136 .long .Ltmp12-.Ltmp11 # Subsection size
137.Ltmp11:
138 .short .Ltmp14-.Ltmp13 # Record length
139.Ltmp13:
140 .short 4423 # Record kind: S_GPROC32_ID
141 .long 0 # PtrParent
142 .long 0 # PtrEnd
143 .long 0 # PtrNext
144 .long .Lfunc_end0-main # Code size
145 .long 0 # Offset after prologue
146 .long 0 # Offset before epilogue
147 .long 4101 # Function type index
148 .secrel32 main # Function section relative address
149 .secidx main # Function section index
150 .byte 0 # Flags
151 .asciz "main" # Function name
152 .p2align 2
153.Ltmp14:
154 .short .Ltmp16-.Ltmp15 # Record length
155.Ltmp15:
156 .short 4114 # Record kind: S_FRAMEPROC
157 .long 0 # FrameSize
158 .long 0 # Padding
159 .long 0 # Offset of padding
160 .long 0 # Bytes of callee saved registers
161 .long 0 # Exception handler offset
162 .short 0 # Exception handler section
163 .long 0 # Flags (defines frame register)
164 .p2align 2
165.Ltmp16:
166 .short .Ltmp18-.Ltmp17 # Record length
167.Ltmp17:
168 .short 4429 # Record kind: S_INLINESITE
169 .long 0 # PtrParent
170 .long 0 # PtrEnd
171 .long 4098 # Inlinee type index
172 .cv_inline_linetable 1 1 7 .Lfunc_begin0 .Lfunc_end0
173 .p2align 2
174.Ltmp18:
175 .short 2 # Record length
176 .short 4430 # Record kind: S_INLINESITE_END
177 .short 2 # Record length
178 .short 4431 # Record kind: S_PROC_ID_END
179.Ltmp12:
180 .p2align 2
181 .cv_linetable 0, main, .Lfunc_end0
182 .section .debug$S,"dr"
183 .long 241 # Symbol subsection for globals
184 .long .Ltmp22-.Ltmp21 # Subsection size
185.Ltmp21:
186 .short .Ltmp24-.Ltmp23 # Record length
187.Ltmp23:
188 .short 4365 # Record kind: S_GDATA32
189 .long 4102 # Type
190 .secrel32 x # DataOffset
191 .secidx x # Segment
192 .asciz "x" # Name
193 .p2align 2
194.Ltmp24:
195.Ltmp22:
196 .p2align 2
197 .cv_filechecksums # File index to string table offset subsection
198 .cv_stringtable # String table
199 .long 241
200 .long .Ltmp26-.Ltmp25 # Subsection size
201.Ltmp25:
202 .short .Ltmp28-.Ltmp27 # Record length
203.Ltmp27:
204 .short 4428 # Record kind: S_BUILDINFO
205 .long 4105 # LF_BUILDINFO index
206 .p2align 2
207.Ltmp28:
208.Ltmp26:
209 .p2align 2
210 .section .debug$T,"dr"
211 .p2align 2
212 .long 4 # Debug section magic
213 # ArgList (0x1000) {
214 # TypeLeafKind: LF_ARGLIST (0x1201)
215 # NumArgs: 0
216 # Arguments [
217 # ]
218 # }
219 .byte 0x06, 0x00, 0x01, 0x12
220 .byte 0x00, 0x00, 0x00, 0x00
221 # Procedure (0x1001) {
222 # TypeLeafKind: LF_PROCEDURE (0x1008)
223 # ReturnType: void (0x3)
224 # CallingConvention: NearC (0x0)
225 # FunctionOptions [ (0x0)
226 # ]
227 # NumParameters: 0
228 # ArgListType: () (0x1000)
229 # }
230 .byte 0x0e, 0x00, 0x08, 0x10
231 .byte 0x03, 0x00, 0x00, 0x00
232 .byte 0x00, 0x00, 0x00, 0x00
233 .byte 0x00, 0x10, 0x00, 0x00
234 # FuncId (0x1002) {
235 # TypeLeafKind: LF_FUNC_ID (0x1601)
236 # ParentScope: 0x0
237 # FunctionType: void () (0x1001)
238 # Name: inlinee_1
239 # }
240 .byte 0x16, 0x00, 0x01, 0x16
241 .byte 0x00, 0x00, 0x00, 0x00
242 .byte 0x01, 0x10, 0x00, 0x00
243 .byte 0x69, 0x6e, 0x6c, 0x69
244 .byte 0x6e, 0x65, 0x65, 0x5f
245 .byte 0x31, 0x00, 0xf2, 0xf1
246 # FuncId (0x1003) {
247 # TypeLeafKind: LF_FUNC_ID (0x1601)
248 # ParentScope: 0x0
249 # FunctionType: void () (0x1001)
250 # Name: inlinee_2
251 # }
252 .byte 0x16, 0x00, 0x01, 0x16
253 .byte 0x00, 0x00, 0x00, 0x00
254 .byte 0x01, 0x10, 0x00, 0x00
255 .byte 0x69, 0x6e, 0x6c, 0x69
256 .byte 0x6e, 0x65, 0x65, 0x5f
257 .byte 0x32, 0x00, 0xf2, 0xf1
258 # Procedure (0x1004) {
259 # TypeLeafKind: LF_PROCEDURE (0x1008)
260 # ReturnType: int (0x74)
261 # CallingConvention: NearC (0x0)
262 # FunctionOptions [ (0x0)
263 # ]
264 # NumParameters: 0
265 # ArgListType: () (0x1000)
266 # }
267 .byte 0x0e, 0x00, 0x08, 0x10
268 .byte 0x74, 0x00, 0x00, 0x00
269 .byte 0x00, 0x00, 0x00, 0x00
270 .byte 0x00, 0x10, 0x00, 0x00
271 # FuncId (0x1005) {
272 # TypeLeafKind: LF_FUNC_ID (0x1601)
273 # ParentScope: 0x0
274 # FunctionType: int () (0x1004)
275 # Name: main
276 # }
277 .byte 0x12, 0x00, 0x01, 0x16
278 .byte 0x00, 0x00, 0x00, 0x00
279 .byte 0x04, 0x10, 0x00, 0x00
280 .byte 0x6d, 0x61, 0x69, 0x6e
281 .byte 0x00, 0xf3, 0xf2, 0xf1
282 # Modifier (0x1006) {
283 # TypeLeafKind: LF_MODIFIER (0x1001)
284 # ModifiedType: int (0x74)
285 # Modifiers [ (0x2)
286 # Volatile (0x2)
287 # ]
288 # }
289 .byte 0x0a, 0x00, 0x01, 0x10
290 .byte 0x74, 0x00, 0x00, 0x00
291 .byte 0x02, 0x00, 0xf2, 0xf1
292 # StringId (0x1007) {
293 # TypeLeafKind: LF_STRING_ID (0x1605)
294 # Id: 0x0
295 # StringData: C:\src\llvm-project\build
296 # }
297 .byte 0x22, 0x00, 0x05, 0x16
298 .byte 0x00, 0x00, 0x00, 0x00
299 .byte 0x43, 0x3a, 0x5c, 0x73
300 .byte 0x72, 0x63, 0x5c, 0x6c
301 .byte 0x6c, 0x76, 0x6d, 0x2d
302 .byte 0x70, 0x72, 0x6f, 0x6a
303 .byte 0x65, 0x63, 0x74, 0x5c
304 .byte 0x62, 0x75, 0x69, 0x6c
305 .byte 0x64, 0x00, 0xf2, 0xf1
306 # StringId (0x1008) {
307 # TypeLeafKind: LF_STRING_ID (0x1605)
308 # Id: 0x0
309 # StringData: t.c
310 # }
311 .byte 0x0a, 0x00, 0x05, 0x16
312 .byte 0x00, 0x00, 0x00, 0x00
313 .byte 0x74, 0x2e, 0x63, 0x00
314 # BuildInfo (0x1009) {
315 # TypeLeafKind: LF_BUILDINFO (0x1603)
316 # NumArgs: 5
317 # Arguments [
318 # ArgType: C:\src\llvm-project\build (0x1007)
319 # ArgType: 0x0
320 # ArgType: t.c (0x1008)
321 # ArgType: 0x0
322 # ArgType: 0x0
323 # ]
324 # }
325 .byte 0x1a, 0x00, 0x03, 0x16
326 .byte 0x05, 0x00, 0x07, 0x10
327 .byte 0x00, 0x00, 0x00, 0x00
328 .byte 0x00, 0x00, 0x08, 0x10
329 .byte 0x00, 0x00, 0x00, 0x00
330 .byte 0x00, 0x00, 0x00, 0x00
331 .byte 0x00, 0x00, 0xf2, 0xf1
332
333 .addrsig
334 .addrsig_sym x
deps/lld/test/COFF/pdb-inlinees.s created+332
......@@ -0,0 +1,332 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj %s -o %t.obj -triple x86_64-windows-msvc
3# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe -pdb:%t.pdb -debug
4# RUN: llvm-pdbutil dump -il %t.pdb | FileCheck %s
5
6# Compiled from this C code, with modifications to test multiple file checksums:
7# volatile int x;
8# static __forceinline void inlinee_2(void) {
9# ++x;
10# __debugbreak();
11# ++x;
12# }
13# static __forceinline void inlinee_1(void) {
14# ++x;
15# inlinee_2();
16# ++x;
17# }
18# int main() {
19# ++x;
20# inlinee_1();
21# ++x;
22# return x;
23# }
24
25# CHECK: Inlinee Lines
26# CHECK: Mod 0000 | `{{.*}}pdb-inlinees.s.tmp.obj`:
27# CHECK-NEXT: Inlinee | Line | Source File
28# CHECK-NEXT: 0x1000 | 7 | C:\src\llvm-project\build\t.c (MD5: A79D837C976E9F0463A474D74E2EE9E7)
29# CHECK-NEXT: 0x1001 | 2 | C:\src\llvm-project\build\file2.h (MD5: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
30
31 .text
32 .def @feat.00;
33 .scl 3;
34 .type 0;
35 .endef
36 .globl @feat.00
37.set @feat.00, 0
38 .intel_syntax noprefix
39 .file "t.c"
40 .def main;
41 .scl 2;
42 .type 32;
43 .endef
44 .section .text,"xr",one_only,main
45 .globl main # -- Begin function main
46main: # @main
47.Lfunc_begin0:
48 .cv_func_id 0
49# %bb.0: # %entry
50 .cv_file 1 "C:\\src\\llvm-project\\build\\t.c" "A79D837C976E9F0463A474D74E2EE9E7" 1
51 .cv_file 2 "C:\\src\\llvm-project\\build\\file2.h" "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1
52 .cv_loc 0 1 13 0 # t.c:13:0
53 inc dword ptr [rip + x]
54.Ltmp0:
55 .cv_inline_site_id 1 within 0 inlined_at 1 14 0
56 .cv_loc 1 1 8 0 # t.c:8:0
57 inc dword ptr [rip + x]
58.Ltmp1:
59 .cv_inline_site_id 2 within 1 inlined_at 1 9 0
60 .cv_loc 2 2 3 0 # file2.h:3:0
61 inc dword ptr [rip + x]
62 .cv_loc 2 2 4 0 # file2.h:4:0
63 int3
64 .cv_loc 2 2 5 0 # file2.h:5:0
65 inc dword ptr [rip + x]
66.Ltmp2:
67 .cv_loc 1 1 10 0 # t.c:10:0
68 inc dword ptr [rip + x]
69.Ltmp3:
70 .cv_loc 0 1 15 0 # t.c:15:0
71 inc dword ptr [rip + x]
72 .cv_loc 0 1 16 0 # t.c:16:0
73 mov eax, dword ptr [rip + x]
74 ret
75.Ltmp4:
76.Lfunc_end0:
77 # -- End function
78 .comm x,4,2 # @x
79 .section .debug$S,"dr"
80 .p2align 2
81 .long 4 # Debug section magic
82 .long 241
83 .long .Ltmp6-.Ltmp5 # Subsection size
84.Ltmp5:
85 .short .Ltmp8-.Ltmp7 # Record length
86.Ltmp7:
87 .short 4412 # Record kind: S_COMPILE3
88 .long 0 # Flags and language
89 .short 208 # CPUType
90 .short 9 # Frontend version
91 .short 0
92 .short 0
93 .short 0
94 .short 9000 # Backend version
95 .short 0
96 .short 0
97 .short 0
98 .asciz "clang version 9.0.0 (git@github.com:llvm/llvm-project.git aa762a56caf3ef2b0b41c501e66d3ef32903a2d0)" # Null-terminated compiler version string
99 .p2align 2
100.Ltmp8:
101.Ltmp6:
102 .p2align 2
103 .long 246 # Inlinee lines subsection
104 .long .Ltmp10-.Ltmp9 # Subsection size
105.Ltmp9:
106 .long 0 # Inlinee lines signature
107
108 # Inlined function inlinee_1 starts at t.c:7
109 .long 4098 # Type index of inlined function
110 .cv_filechecksumoffset 1 # Offset into filechecksum table
111 .long 7 # Starting line number
112
113 # Inlined function inlinee_2 starts at file2.h:2
114 .long 4099 # Type index of inlined function
115 .cv_filechecksumoffset 2 # Offset into filechecksum table
116 .long 2 # Starting line number
117.Ltmp10:
118 .p2align 2
119 .section .debug$S,"dr",associative,main
120 .p2align 2
121 .long 4 # Debug section magic
122 .long 241 # Symbol subsection for main
123 .long .Ltmp12-.Ltmp11 # Subsection size
124.Ltmp11:
125 .short .Ltmp14-.Ltmp13 # Record length
126.Ltmp13:
127 .short 4423 # Record kind: S_GPROC32_ID
128 .long 0 # PtrParent
129 .long 0 # PtrEnd
130 .long 0 # PtrNext
131 .long .Lfunc_end0-main # Code size
132 .long 0 # Offset after prologue
133 .long 0 # Offset before epilogue
134 .long 4101 # Function type index
135 .secrel32 main # Function section relative address
136 .secidx main # Function section index
137 .byte 0 # Flags
138 .asciz "main" # Function name
139 .p2align 2
140.Ltmp14:
141 .short .Ltmp16-.Ltmp15 # Record length
142.Ltmp15:
143 .short 4114 # Record kind: S_FRAMEPROC
144 .long 0 # FrameSize
145 .long 0 # Padding
146 .long 0 # Offset of padding
147 .long 0 # Bytes of callee saved registers
148 .long 0 # Exception handler offset
149 .short 0 # Exception handler section
150 .long 0 # Flags (defines frame register)
151 .p2align 2
152.Ltmp16:
153 .short .Ltmp18-.Ltmp17 # Record length
154.Ltmp17:
155 .short 4429 # Record kind: S_INLINESITE
156 .long 0 # PtrParent
157 .long 0 # PtrEnd
158 .long 4098 # Inlinee type index
159 .cv_inline_linetable 1 1 7 .Lfunc_begin0 .Lfunc_end0
160 .p2align 2
161.Ltmp18:
162 .short .Ltmp20-.Ltmp19 # Record length
163.Ltmp19:
164 .short 4429 # Record kind: S_INLINESITE
165 .long 0 # PtrParent
166 .long 0 # PtrEnd
167 .long 4099 # Inlinee type index
168 .cv_inline_linetable 2 2 2 .Lfunc_begin0 .Lfunc_end0
169 .p2align 2
170.Ltmp20:
171 .short 2 # Record length
172 .short 4430 # Record kind: S_INLINESITE_END
173 .short 2 # Record length
174 .short 4430 # Record kind: S_INLINESITE_END
175 .short 2 # Record length
176 .short 4431 # Record kind: S_PROC_ID_END
177.Ltmp12:
178 .p2align 2
179 .cv_linetable 0, main, .Lfunc_end0
180 .section .debug$S,"dr"
181 .long 241 # Symbol subsection for globals
182 .long .Ltmp22-.Ltmp21 # Subsection size
183.Ltmp21:
184 .short .Ltmp24-.Ltmp23 # Record length
185.Ltmp23:
186 .short 4365 # Record kind: S_GDATA32
187 .long 4102 # Type
188 .secrel32 x # DataOffset
189 .secidx x # Segment
190 .asciz "x" # Name
191 .p2align 2
192.Ltmp24:
193.Ltmp22:
194 .p2align 2
195 .cv_filechecksums # File index to string table offset subsection
196 .cv_stringtable # String table
197 .long 241
198 .long .Ltmp26-.Ltmp25 # Subsection size
199.Ltmp25:
200 .short .Ltmp28-.Ltmp27 # Record length
201.Ltmp27:
202 .short 4428 # Record kind: S_BUILDINFO
203 .long 4105 # LF_BUILDINFO index
204 .p2align 2
205.Ltmp28:
206.Ltmp26:
207 .p2align 2
208 .section .debug$T,"dr"
209 .p2align 2
210 .long 4 # Debug section magic
211 # ArgList (0x1000) {
212 # TypeLeafKind: LF_ARGLIST (0x1201)
213 # NumArgs: 0
214 # Arguments [
215 # ]
216 # }
217 .byte 0x06, 0x00, 0x01, 0x12
218 .byte 0x00, 0x00, 0x00, 0x00
219 # Procedure (0x1001) {
220 # TypeLeafKind: LF_PROCEDURE (0x1008)
221 # ReturnType: void (0x3)
222 # CallingConvention: NearC (0x0)
223 # FunctionOptions [ (0x0)
224 # ]
225 # NumParameters: 0
226 # ArgListType: () (0x1000)
227 # }
228 .byte 0x0e, 0x00, 0x08, 0x10
229 .byte 0x03, 0x00, 0x00, 0x00
230 .byte 0x00, 0x00, 0x00, 0x00
231 .byte 0x00, 0x10, 0x00, 0x00
232 # FuncId (0x1002) {
233 # TypeLeafKind: LF_FUNC_ID (0x1601)
234 # ParentScope: 0x0
235 # FunctionType: void () (0x1001)
236 # Name: inlinee_1
237 # }
238 .byte 0x16, 0x00, 0x01, 0x16
239 .byte 0x00, 0x00, 0x00, 0x00
240 .byte 0x01, 0x10, 0x00, 0x00
241 .byte 0x69, 0x6e, 0x6c, 0x69
242 .byte 0x6e, 0x65, 0x65, 0x5f
243 .byte 0x31, 0x00, 0xf2, 0xf1
244 # FuncId (0x1003) {
245 # TypeLeafKind: LF_FUNC_ID (0x1601)
246 # ParentScope: 0x0
247 # FunctionType: void () (0x1001)
248 # Name: inlinee_2
249 # }
250 .byte 0x16, 0x00, 0x01, 0x16
251 .byte 0x00, 0x00, 0x00, 0x00
252 .byte 0x01, 0x10, 0x00, 0x00
253 .byte 0x69, 0x6e, 0x6c, 0x69
254 .byte 0x6e, 0x65, 0x65, 0x5f
255 .byte 0x32, 0x00, 0xf2, 0xf1
256 # Procedure (0x1004) {
257 # TypeLeafKind: LF_PROCEDURE (0x1008)
258 # ReturnType: int (0x74)
259 # CallingConvention: NearC (0x0)
260 # FunctionOptions [ (0x0)
261 # ]
262 # NumParameters: 0
263 # ArgListType: () (0x1000)
264 # }
265 .byte 0x0e, 0x00, 0x08, 0x10
266 .byte 0x74, 0x00, 0x00, 0x00
267 .byte 0x00, 0x00, 0x00, 0x00
268 .byte 0x00, 0x10, 0x00, 0x00
269 # FuncId (0x1005) {
270 # TypeLeafKind: LF_FUNC_ID (0x1601)
271 # ParentScope: 0x0
272 # FunctionType: int () (0x1004)
273 # Name: main
274 # }
275 .byte 0x12, 0x00, 0x01, 0x16
276 .byte 0x00, 0x00, 0x00, 0x00
277 .byte 0x04, 0x10, 0x00, 0x00
278 .byte 0x6d, 0x61, 0x69, 0x6e
279 .byte 0x00, 0xf3, 0xf2, 0xf1
280 # Modifier (0x1006) {
281 # TypeLeafKind: LF_MODIFIER (0x1001)
282 # ModifiedType: int (0x74)
283 # Modifiers [ (0x2)
284 # Volatile (0x2)
285 # ]
286 # }
287 .byte 0x0a, 0x00, 0x01, 0x10
288 .byte 0x74, 0x00, 0x00, 0x00
289 .byte 0x02, 0x00, 0xf2, 0xf1
290 # StringId (0x1007) {
291 # TypeLeafKind: LF_STRING_ID (0x1605)
292 # Id: 0x0
293 # StringData: C:\src\llvm-project\build
294 # }
295 .byte 0x22, 0x00, 0x05, 0x16
296 .byte 0x00, 0x00, 0x00, 0x00
297 .byte 0x43, 0x3a, 0x5c, 0x73
298 .byte 0x72, 0x63, 0x5c, 0x6c
299 .byte 0x6c, 0x76, 0x6d, 0x2d
300 .byte 0x70, 0x72, 0x6f, 0x6a
301 .byte 0x65, 0x63, 0x74, 0x5c
302 .byte 0x62, 0x75, 0x69, 0x6c
303 .byte 0x64, 0x00, 0xf2, 0xf1
304 # StringId (0x1008) {
305 # TypeLeafKind: LF_STRING_ID (0x1605)
306 # Id: 0x0
307 # StringData: t.c
308 # }
309 .byte 0x0a, 0x00, 0x05, 0x16
310 .byte 0x00, 0x00, 0x00, 0x00
311 .byte 0x74, 0x2e, 0x63, 0x00
312 # BuildInfo (0x1009) {
313 # TypeLeafKind: LF_BUILDINFO (0x1603)
314 # NumArgs: 5
315 # Arguments [
316 # ArgType: C:\src\llvm-project\build (0x1007)
317 # ArgType: 0x0
318 # ArgType: t.c (0x1008)
319 # ArgType: 0x0
320 # ArgType: 0x0
321 # ]
322 # }
323 .byte 0x1a, 0x00, 0x03, 0x16
324 .byte 0x05, 0x00, 0x07, 0x10
325 .byte 0x00, 0x00, 0x00, 0x00
326 .byte 0x00, 0x00, 0x08, 0x10
327 .byte 0x00, 0x00, 0x00, 0x00
328 .byte 0x00, 0x00, 0x00, 0x00
329 .byte 0x00, 0x00, 0xf2, 0xf1
330
331 .addrsig
332 .addrsig_sym x
deps/lld/test/COFF/pdb-lib.s+4-4
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o foo.obj
44# RUN: llc %S/Inputs/bar.ll -filetype=obj -mtriple=i686-windows-msvc -o bar.obj
55# RUN: llvm-lib bar.obj -out:bar.lib
6# RUN: lld-link -debug -pdb:foo.pdb foo.obj bar.lib -out:foo.exe -entry:main
6# RUN: lld-link -safeseh:no -debug -pdb:foo.pdb foo.obj bar.lib -out:foo.exe -entry:main
77# RUN: llvm-pdbutil dump -modules %t/foo.pdb | FileCheck %s
88
99# Make sure that the PDB has module descriptors. foo.obj and bar.lib should be
......@@ -13,15 +13,15 @@
1313# CHECK-NEXT: ============================================================
1414# CHECK-NEXT: Mod 0000 | `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`:
1515# CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`:
16# CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false
16# CHECK-NEXT: debug stream: 65535, # files: 0, has ec info: false
1717# CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
1818# CHECK-NEXT: Mod 0001 | `bar.obj`:
1919# CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`:
20# CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false
20# CHECK-NEXT: debug stream: 65535, # files: 0, has ec info: false
2121# CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
2222# CHECK-NEXT: Mod 0002 | `* Linker *`:
2323# CHECK-NEXT: Obj: ``:
24# CHECK-NEXT: debug stream: 12, # files: 0, has ec info: false
24# CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false
2525# CHECK-NEXT: pdb file ni: 1 `{{.*foo.pdb}}`, src file ni: 0 ``
2626
2727 .def _main;
deps/lld/test/COFF/pdb-publics-import.test+148-5
......@@ -8,7 +8,48 @@ RUN: /export:exportfn1 /export:exportfn2
88RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj
99RUN: lld-link /out:%t2.exe /pdb:%t2.pdb /pdbaltpath:test.pdb \
1010RUN: /debug /entry:main %t2.obj %t1.lib
11RUN: llvm-pdbutil dump %t2.pdb -publics -section-contribs | FileCheck %s
11RUN: llvm-pdbutil dump %t2.pdb -all | FileCheck %s
12
13CHECK: Streams
14CHECK-NEXT: ============================================================
15CHECK-LABEL: Stream 10 ( 256 bytes): [Module "Import:pdb-publics-import.test.tmp1.dll"]
16
17CHECK: Module Stats
18CHECK-NEXT: ============================================================
19CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`:
20CHECK-NEXT: Mod 0 (debug info not present): [{{.*}}pdb-publics-import.test.tmp2.obj]
21CHECK-NEXT: Mod 0001 | `pdb-publics-import.test.tmp1.dll`:
22CHECK-NEXT: Mod 1 (debug info not present): [pdb-publics-import.test.tmp1.dll]
23CHECK-NEXT: Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`:
24CHECK-NEXT: Stream 10, 256 bytes
25
26CHECK: Modules
27CHECK-NEXT: ============================================================
28CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`:
29CHECK-NEXT: SC[.text] | mod = 0, 0001:0000, size = 8, data crc = 0, reloc crc = 0
30CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_EXECUTE |
31CHECK-NEXT: IMAGE_SCN_MEM_READ
32CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp2.obj`:
33CHECK-NEXT: debug stream: 65535, # files: 0, has ec info: false
34CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
35CHECK-NEXT: Mod 0001 | `pdb-publics-import.test.tmp1.dll`:
36CHECK-NEXT: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0
37CHECK-NEXT: none
38CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp1.lib`:
39CHECK-NEXT: debug stream: 65535, # files: 0, has ec info: false
40CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
41CHECK-NEXT: Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`:
42CHECK-NEXT: SC[.text] | mod = 2, 0001:0032, size = 6, data crc = 0, reloc crc = 0
43CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
44CHECK-NEXT: Obj: `{{.*}}pdb-publics-import.test.tmp1.lib`:
45CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false
46CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
47CHECK-NEXT: Mod 0003 | `* Linker *`:
48CHECK-NEXT: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0
49CHECK-NEXT: none
50CHECK-NEXT: Obj: ``:
51CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false
52CHECK-NEXT: pdb file ni: 1 `{{.*}}pdb-publics-import.test.tmp2.pdb`, src file ni: 0 ``
1253
1354CHECK: Public Symbols
1455CHECK-NEXT: ============================================================
......@@ -24,6 +65,86 @@ CHECK-NEXT: flags = none, addr = 0002:0136
2465CHECK-NEXT: 0 | S_PUB32 [size = 32] `__imp_exportfn1`
2566CHECK-NEXT: flags = none, addr = 0002:0128
2667
68CHECK: Symbols
69CHECK-NEXT: ============================================================
70CHECK-NEXT: Mod 0000 | `{{.*}}pdb-publics-import.test.tmp2.obj`:
71CHECK-NEXT: Error loading module stream 0. The specified stream could not be loaded. Module stream not present
72CHECK-NEXT: Mod 0001 | `pdb-publics-import.test.tmp1.dll`:
73CHECK-NEXT: Error loading module stream 1. The specified stream could not be loaded. Module stream not present
74CHECK-NEXT: Mod 0002 | `Import:pdb-publics-import.test.tmp1.dll`:
75CHECK-NEXT: 4 | S_OBJNAME [size = 44] sig=0, `pdb-publics-import.test.tmp1.dll`
76CHECK-NEXT: 48 | S_COMPILE3 [size = 40]
77CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link
78CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0
79CHECK-NEXT: flags = none
80CHECK-NEXT: 88 | S_THUNK32 [size = 36] `exportfn1`
81CHECK-NEXT: parent = 0, end = 124, next = 0
82CHECK-NEXT: kind = thunk, size = 6, addr = 0001:0016
83CHECK-NEXT: 124 | S_END [size = 4]
84CHECK-NEXT: 128 | S_OBJNAME [size = 44] sig=0, `pdb-publics-import.test.tmp1.dll`
85CHECK-NEXT: 172 | S_COMPILE3 [size = 40]
86CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link
87CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0
88CHECK-NEXT: flags = none
89CHECK-NEXT: 212 | S_THUNK32 [size = 36] `exportfn2`
90CHECK-NEXT: parent = 0, end = 248, next = 0
91CHECK-NEXT: kind = thunk, size = 6, addr = 0001:0032
92CHECK-NEXT: 248 | S_END [size = 4]
93CHECK-NEXT: Mod 0003 | `* Linker *`:
94CHECK-NEXT: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *`
95CHECK-NEXT: 24 | S_COMPILE3 [size = 40]
96CHECK-NEXT: machine = intel x86-x64, Ver = LLVM Linker, language = link
97CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0
98CHECK-NEXT: flags = none
99CHECK-NEXT: 64 | S_ENVBLOCK [size = {{[0-9]+}}]
100CHECK: {{[0-9]+}} | S_SECTION [size = 28] `.text`
101CHECK-NEXT: length = 38, alignment = 12, rva = 4096, section # = 1
102CHECK-NEXT: characteristics =
103CHECK-NEXT: code
104CHECK-NEXT: execute permissions
105CHECK-NEXT: read permissions
106CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 24] `.text`
107CHECK-NEXT: length = 8, addr = 0001:0000
108CHECK-NEXT: characteristics =
109CHECK-NEXT: code
110CHECK-NEXT: execute permissions
111CHECK-NEXT: read permissions
112CHECK-NEXT: {{[0-9]+}} | S_SECTION [size = 28] `.rdata`
113CHECK-NEXT: length = 209, alignment = 12, rva = 8192, section # = 2
114CHECK-NEXT: characteristics =
115CHECK-NEXT: initialized data
116CHECK-NEXT: read permissions
117CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$2`
118CHECK-NEXT: length = 40, addr = 0002:0061
119CHECK-NEXT: characteristics =
120CHECK-NEXT: initialized data
121CHECK-NEXT: read permissions
122CHECK-NEXT: write permissions
123CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$4`
124CHECK-NEXT: length = 24, addr = 0002:0104
125CHECK-NEXT: characteristics =
126CHECK-NEXT: initialized data
127CHECK-NEXT: read permissions
128CHECK-NEXT: write permissions
129CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$5`
130CHECK-NEXT: length = 24, addr = 0002:0128
131CHECK-NEXT: characteristics =
132CHECK-NEXT: initialized data
133CHECK-NEXT: read permissions
134CHECK-NEXT: write permissions
135CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$6`
136CHECK-NEXT: length = 24, addr = 0002:0152
137CHECK-NEXT: characteristics =
138CHECK-NEXT: initialized data
139CHECK-NEXT: read permissions
140CHECK-NEXT: write permissions
141CHECK-NEXT: {{[0-9]+}} | S_COFFGROUP [size = 28] `.idata$7`
142CHECK-NEXT: length = 33, addr = 0002:0176
143CHECK-NEXT: characteristics =
144CHECK-NEXT: initialized data
145CHECK-NEXT: read permissions
146CHECK-NEXT: write permissions
147
27148CHECK: Section Contributions
28149CHECK-NEXT: ============================================================
29150 main
......@@ -31,13 +152,35 @@ CHECK-NEXT: SC[.text] | mod = 0, 0001:0000, size = 8, data crc = 0, reloc cr
31152CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_EXECUTE |
32153CHECK-NEXT: IMAGE_SCN_MEM_READ
33154 exportfn1 thunk
34CHECK-NEXT: SC[.text] | mod = 1, 0001:0016, size = 6, data crc = 0, reloc crc = 0
155CHECK-NEXT: SC[.text] | mod = 3, 0001:0016, size = 6, data crc = 0, reloc crc = 0
35156CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
36157 exportfn2 thunk
37CHECK-NEXT: SC[.text] | mod = 1, 0001:0032, size = 6, data crc = 0, reloc crc = 0
158CHECK-NEXT: SC[.text] | mod = 3, 0001:0032, size = 6, data crc = 0, reloc crc = 0
38159CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
39160 .rdata debug directory data chunks
40CHECK-NEXT: SC[.rdata] | mod = 1, 0002:0000, size = 28, data crc = 0, reloc crc = 0
161CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0000, size = 28, data crc = 0, reloc crc = 0
162CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
163CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0028, size = 33, data crc = 0, reloc crc = 0
164CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
165CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0061, size = 20, data crc = 0, reloc crc = 0
166CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
167CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0081, size = 20, data crc = 0, reloc crc = 0
168CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
169CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0104, size = 8, data crc = 0, reloc crc = 0
170CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
171CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0112, size = 8, data crc = 0, reloc crc = 0
172CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
173CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0120, size = 8, data crc = 0, reloc crc = 0
174CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
175CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0128, size = 8, data crc = 0, reloc crc = 0
176CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
177CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0136, size = 8, data crc = 0, reloc crc = 0
178CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
179CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0144, size = 8, data crc = 0, reloc crc = 0
180CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
181CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0152, size = 12, data crc = 0, reloc crc = 0
182CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
183CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0164, size = 12, data crc = 0, reloc crc = 0
41184CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
42CHECK-NEXT: SC[.rdata] | mod = 1, 0002:0028, size = 33, data crc = 0, reloc crc = 0
185CHECK-NEXT: SC[.rdata] | mod = 3, 0002:0176, size = 33, data crc = 0, reloc crc = 0
43186CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
deps/lld/test/COFF/pdb-safeseh.yaml+1-1
......@@ -1,5 +1,5 @@
11# RUN: yaml2obj %s -o %t.obj
2# RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj
2# RUN: lld-link -safeseh:no -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj
33# RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s
44
55# There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in
deps/lld/test/COFF/pdb-tpi-hash-size.test created+10
......@@ -0,0 +1,10 @@
1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3# RUN: rm -f %t.dll %t.pdb
4# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll \
5# RUN: /entry:main /nodefaultlib %t1.obj %t2.obj
6
7# RUN: llvm-pdbutil dump -types -type-extras %t.pdb | FileCheck %s
8
9CHECK: Hash Key Size: 4
10CHECK-NEXT: Num Hash Buckets: 262143
deps/lld/test/COFF/pdb-type-server-invalid-signature.yaml+12-4
......@@ -1,22 +1,30 @@
11
2# Test linking an OBJ with a reference to an out-of-date PDB type server
23# RUN: cd %S/Inputs
34# RUN: yaml2obj %s -o %t.obj
45# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
56# RUN: cd %S
67
7# CHECK: warning: Cannot use debug info for {{.*}}.obj
8# CHECK: warning: Cannot use debug info for '{{.*}}.obj'
89# CHECK-NEXT: The signature does not match; the file(s) might be out of date
910
10# Also test a valid match
11
11# Also test linking an OBJ with a reference to *valid* PDB type server
1212# RUN: cd %S/Inputs
1313# RUN: yaml2obj %S/Inputs/pdb-type-server-valid-signature.yaml -o %t2.obj
1414# 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
1515# RUN: cd %S
1616
17# VALID-SIGNATURE-NOT: warning: Cannot use debug info for {{.*}}.obj
17# VALID-SIGNATURE-NOT: warning: Cannot use debug info for '{{.*}}.obj'
1818# VALID-SIGNATURE-NOT: The signature does not match; the file(s) might be out of date
1919
20# Test an invalid path reference to a PDB type server; as a fallback LLD should try to load the PDB in the same path as the OBJ
21# RUN: yaml2obj %S/Inputs/pdb-type-server-invalid-path.yaml -o %t3.obj
22# RUN: cp %S/Inputs/pdb-diff-cl.pdb %T
23# RUN: lld-link %t3.obj -out:%t3.exe -debug -pdb:%t3.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -check-prefix=INVALID-PATH -allow-empty
24
25# INVALID-PATH-NOT: warning: Cannot use debug info for '{{.*}}3.obj' [LNK4099]
26# INVALID-PATH-NOT: failed to load reference 'c:\some_invalid_path_AABB98765\pdb-diff-cl.pdb': {{[Nn]}}o such file or directory
27
2028--- !COFF
2129header:
2230 Machine: IMAGE_FILE_MACHINE_AMD64
deps/lld/test/COFF/pdb-type-server-simple.test+12-1
......@@ -20,7 +20,7 @@ RUN: rm -rf %t && mkdir -p %t && cd %t
2020RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj
2121RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj
2222RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb
23RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib
23RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib /summary | FileCheck %s -check-prefix SUMMARY
2424RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s
2525
2626
......@@ -95,3 +95,14 @@ CHECK: type = [[FOO_PTR]] (Foo*), register = RSP, offset = 8
9595CHECK: 196 | S_END [size = 4]
9696CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`
9797CHECK-LABEL: Mod 0002 | `* Linker *`:
98
99SUMMARY: Summary
100SUMMARY-NEXT: --------------------------------------------------------------------------------
101SUMMARY-NEXT: 2 Input OBJ files (expanded from all cmd-line inputs)
102SUMMARY-NEXT: 1 PDB type server dependencies
103SUMMARY-NEXT: 0 Precomp OBJ dependencies
104SUMMARY-NEXT: 25 Merged TPI records
105SUMMARY-NEXT: 3 Output PDB strings
106SUMMARY-NEXT: 4 Global symbol records
107SUMMARY-NEXT: 14 Module symbol records
108SUMMARY-NEXT: 2 Public symbol records
\ No newline at end of file
deps/lld/test/COFF/pdb-unknown-subsection.s created+60
......@@ -0,0 +1,60 @@
1# Check that unknown symbol subsections are ignored with a warning, and a PDB
2# is produced anyway.
3
4# REQUIRES: x86
5# RUN: llvm-mc -triple=i386-pc-win32 -filetype=obj -o %t.obj %s
6# RUN: lld-link -safeseh:no -subsystem:console -debug -nodefaultlib -entry:foo -out:%t.exe -pdb:%t.pdb %t.obj 2>&1 | FileCheck %s --check-prefix=WARNING
7# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
8
9# WARNING-NOT: ignoring unknown
10# WARNING: ignoring unknown debug$S subsection kind 0xFF
11# WARNING-NOT: ignoring unknown
12
13# CHECK: Symbols
14# CHECK: 4 | S_COMPILE3 [size = 52]
15# CHECK: machine = intel x86-x64, Ver = clang version SENTINEL, language = c
16
17.text
18_foo:
19ret
20
21.global _foo
22
23.section .debug$S,"dr"
24 .p2align 2
25 .long 4 # Debug section magic
26 .long 0xF1 # Symbol subsection
27 .long .Ltmp6-.Ltmp5 # Subsection size
28.Ltmp5:
29 .short .Ltmp8-.Ltmp7 # Record length
30.Ltmp7:
31 .short 4412 # Record kind: S_COMPILE3
32 .long 0 # Flags and language
33 .short 208 # CPUType
34 .short 9 # Frontend version
35 .short 0
36 .short 0
37 .short 0
38 .short 9000 # Backend version
39 .short 0
40 .short 0
41 .short 0
42 .asciz "clang version SENTINEL" # Null-terminated compiler version string
43 .p2align 2
44.Ltmp8:
45.Ltmp6:
46 .long 0xFF # Unknown subsection kind
47 .long 4 # Subsection size
48 .long 0
49 .long 0x800000F1 # Unknown subsection kind
50 .long 4 # Subsection size
51 .long 0
52 .long 0x800000F2 # Unknown subsection kind
53 .long 4 # Subsection size
54 .long 0
55 .long 0x800000F3 # Unknown subsection kind
56 .long 4 # Subsection size
57 .long 0
58 .long 0x800000F4 # Unknown subsection kind
59 .long 4 # Subsection size
60 .long 0
deps/lld/test/COFF/pdb.test+18-18
......@@ -134,7 +134,7 @@ RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`:
134134RAW-NEXT: debug stream: 12, # files: 1, has ec info: false
135135RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
136136RAW-NEXT: Mod 0002 | `* Linker *`:
137RAW-NEXT: SC[???] | mod = 2, 0000:0000, size = 0, data crc = 0, reloc crc = 0
137RAW-NEXT: SC[???] | mod = 65535, 65535:0000, size = -1, data crc = 0, reloc crc = 0
138138RAW-NEXT: none
139139RAW-NEXT: Obj: ``:
140140RAW-NEXT: debug stream: 13, # files: 0, has ec info: false
......@@ -142,40 +142,40 @@ RAW-NEXT: pdb file ni: 1 `{{.*pdb.test.tmp.pdb}}`, src file ni: 0 `
142142RAW: Types (TPI Stream)
143143RAW-NEXT: ============================================================
144144RAW-NEXT: Showing 5 records
145RAW-NEXT: 0x1000 | LF_ARGLIST [size = 8, hash = 0xEC0]
146RAW-NEXT: 0x1001 | LF_PROCEDURE [size = 16, hash = 0x7BC]
145RAW-NEXT: 0x1000 | LF_ARGLIST [size = 8, hash = 0x32484]
146RAW-NEXT: 0x1001 | LF_PROCEDURE [size = 16, hash = 0x27EE9]
147147RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1000
148148RAW-NEXT: calling conv = cdecl, options = None
149RAW-NEXT: 0x1002 | LF_POINTER [size = 12, hash = 0x884]
149RAW-NEXT: 0x1002 | LF_POINTER [size = 12, hash = 0x39732]
150150RAW-NEXT: referent = 0x1001, mode = pointer, opts = None, kind = ptr64
151RAW-NEXT: 0x1003 | LF_ARGLIST [size = 12, hash = 0x936]
151RAW-NEXT: 0x1003 | LF_ARGLIST [size = 12, hash = 0x1FC10]
152152RAW-NEXT: <no type>: ``
153RAW-NEXT: 0x1004 | LF_PROCEDURE [size = 16, hash = 0x852]
153RAW-NEXT: 0x1004 | LF_PROCEDURE [size = 16, hash = 0x1BD3]
154154RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1003
155155RAW-NEXT: calling conv = cdecl, options = None
156156RAW: Types (IPI Stream)
157157RAW-NEXT: ============================================================
158158RAW-NEXT: Showing 12 records
159RAW-NEXT: 0x1000 | LF_FUNC_ID [size = 20, hash = 0x330]
159RAW-NEXT: 0x1000 | LF_FUNC_ID [size = 20, hash = 0x38E5A]
160160RAW-NEXT: name = main, type = 0x1004, parent scope = <no type>
161RAW-NEXT: 0x1001 | LF_FUNC_ID [size = 16, hash = 0x120]
161RAW-NEXT: 0x1001 | LF_FUNC_ID [size = 16, hash = 0xD08E]
162162RAW-NEXT: name = foo, type = 0x1001, parent scope = <no type>
163RAW-NEXT: 0x1002 | LF_STRING_ID [size = 16, hash = 0x757] ID: <no type>, String: D:\b
164RAW-NEXT: 0x1003 | LF_STRING_ID [size = 36, hash = 0xC3A] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe
165RAW-NEXT: 0x1004 | LF_STRING_ID [size = 260, hash = 0x433] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"
166RAW-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 12, hash = 0x759]
163RAW-NEXT: 0x1002 | LF_STRING_ID [size = 16, hash = 0x3EBD9] ID: <no type>, String: D:\b
164RAW-NEXT: 0x1003 | LF_STRING_ID [size = 36, hash = 0xD327] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe
165RAW-NEXT: 0x1004 | LF_STRING_ID [size = 260, hash = 0x2FA6A] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"
166RAW-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 12, hash = 0x6053]
167167RAW-NEXT: 0x1004: `-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"`
168RAW-NEXT: 0x1006 | LF_STRING_ID [size = 132, hash = 0xF57] ID: 0x1005, String: -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X
169RAW-NEXT: 0x1007 | LF_STRING_ID [size = 24, hash = 0x2D1] ID: <no type>, String: ret42-main.c
170RAW-NEXT: 0x1008 | LF_STRING_ID [size = 24, hash = 0xB8B] ID: <no type>, String: D:\b\vc140.pdb
171RAW-NEXT: 0x1009 | LF_BUILDINFO [size = 28, hash = 0xA8C]
168RAW-NEXT: 0x1006 | LF_STRING_ID [size = 132, hash = 0xCAC7] ID: 0x1005, String: -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X
169RAW-NEXT: 0x1007 | LF_STRING_ID [size = 24, hash = 0x21783] ID: <no type>, String: ret42-main.c
170RAW-NEXT: 0x1008 | LF_STRING_ID [size = 24, hash = 0x1DB87] ID: <no type>, String: D:\b\vc140.pdb
171RAW-NEXT: 0x1009 | LF_BUILDINFO [size = 28, hash = 0x5E91]
172172RAW-NEXT: 0x1002: `D:\b`
173173RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe`
174174RAW-NEXT: 0x1007: `ret42-main.c`
175175RAW-NEXT: 0x1008: `D:\b\vc140.pdb`
176176RAW-NEXT: 0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X`
177RAW-NEXT: 0x100A | LF_STRING_ID [size = 20, hash = 0x39C] ID: <no type>, String: ret42-sub.c
178RAW-NEXT: 0x100B | LF_BUILDINFO [size = 28, hash = 0xAD7]
177RAW-NEXT: 0x100A | LF_STRING_ID [size = 20, hash = 0x7C68] ID: <no type>, String: ret42-sub.c
178RAW-NEXT: 0x100B | LF_BUILDINFO [size = 28, hash = 0x254D2]
179179RAW-NEXT: 0x1002: `D:\b`
180180RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe`
181181RAW-NEXT: 0x100A: `ret42-sub.c`
deps/lld/test/COFF/pdbaltpath.test+9-9
......@@ -1,39 +1,39 @@
11# RUN: yaml2obj %p/Inputs/empty.yaml > %t.obj
22
33# 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
4# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix HELLO %s
55# HELLO: PDBFileName: hello.pdb
66
77# 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
8# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix PDBVAR %s
99# PDBVAR: PDBFileName: pdbaltpath.test.tmp.pdb
1010
1111# 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
12# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix EXTVAR %s
1313# EXTVAR: PDBFileName: fooexe.pdb
1414
1515# 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
16# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix NOCLOSE %s
1717# NOCLOSE: PDBFileName: %_PDB
1818
1919# 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
20# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix NOCLOSE2 %s
2121# NOCLOSE2: PDBFileName: foo%_PDB
2222
2323# 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
24# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix CLOSEONE %s
2525# CLOSEONE: PDBFileName: foopdbaltpath.test.tmp.pdbbar%_EXT
2626
2727# 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
28# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix CLOSETWO %s
2929# CLOSETWO: PDBFileName: foopdbaltpath.test.tmp.pdbbarexe
3030
3131# 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
32# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix CLOSETWO2 %s
3333# CLOSETWO2: PDBFileName: foopdbaltpath.test.tmp.pdbbarexea
3434
3535# 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
36# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck --check-prefix ENVVARS %s
3737# UNKNOWN-WARN: only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping %FoO% as literal
3838# UNKNOWN-WARN: only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping %r% as literal
3939# ENVVARS: PDBFileName: foo%FoO%bar%r%a
deps/lld/test/COFF/precomp-link.test+54-42
......@@ -1,42 +1,54 @@
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
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 /summary | FileCheck %s -check-prefix SUMMARY
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
22SUMMARY: Summary
23SUMMARY-NEXT: --------------------------------------------------------------------------------
24SUMMARY-NEXT: 3 Input OBJ files (expanded from all cmd-line inputs)
25SUMMARY-NEXT: 0 PDB type server dependencies
26SUMMARY-NEXT: 1 Precomp OBJ dependencies
27SUMMARY-NEXT: 1044 Merged TPI records
28SUMMARY-NEXT: 5 Output PDB strings
29SUMMARY-NEXT: 167 Global symbol records
30SUMMARY-NEXT: 20 Module symbol records
31SUMMARY-NEXT: 3 Public symbol records
32
33// precomp.h
34#pragma once
35int Function(char A);
36
37// precomp.cpp
38#include "precomp.h"
39
40// a.cpp
41#include "precomp.h"
42int main(void) {
43 Function('a');
44 return 0;
45}
46
47// b.cpp
48#include "precomp.h"
49int Function(char a) {
50 return (int)a;
51}
52
53// cl.exe precomp.cpp /Z7 /Ycprecomp.h /c
54// cl.exe a.cpp b.cpp /Z7 /Yuprecomp.h /c
deps/lld/test/COFF/reloc-x86.test+1-1
......@@ -1,6 +1,6 @@
11# REQUIRES: x86
22# RUN: yaml2obj < %s > %t.obj
3# RUN: lld-link /out:%t.exe /entry:main /base:0x400000 %t.obj
3# RUN: lld-link -safeseh:no /out:%t.exe /entry:main /base:0x400000 %t.obj
44# RUN: llvm-objdump -d %t.exe | FileCheck %s
55
66# CHECK: .text:
deps/lld/test/COFF/resource-objs.test created+5
......@@ -0,0 +1,5 @@
1# RUN: lld-link /out:%t.exe /dll /noentry %S/Inputs/id.res.o
2# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
3
4CHECK: ResourceTableRVA: 0x1000
5CHECK: ResourceTableSize: 0x80
deps/lld/test/COFF/resource.test+2-2
......@@ -7,7 +7,7 @@
77EXE: {{H.e.l.l.o}}
88
99# Verify the resource tree layout in the final executable.
10# RUN: llvm-readobj -file-headers -coff-resources -section-data %t.exe | \
10# RUN: llvm-readobj --file-headers --coff-resources --section-data %t.exe | \
1111# RUN: FileCheck --check-prefix=RESOURCE_INFO %s
1212
1313RESOURCE_INFO: ResourceTableRVA: 0x2000
......@@ -17,7 +17,7 @@ RESOURCE_INFO-NEXT: Total Number of Resources: 1
1717RESOURCE_INFO-NEXT: Base Table Address: 0x600
1818RESOURCE_INFO-DAG: Number of String Entries: 0
1919RESOURCE_INFO-NEXT: Number of ID Entries: 1
20RESOURCE_INFO-NEXT: Type: kRT_STRING (ID 6) [
20RESOURCE_INFO-NEXT: Type: STRINGTABLE (ID 6) [
2121RESOURCE_INFO-NEXT: Table Offset: 0x18
2222RESOURCE_INFO-NEXT: Number of String Entries: 0
2323RESOURCE_INFO-NEXT: Number of ID Entries: 1
deps/lld/test/COFF/responsefile.test+4-4
......@@ -2,7 +2,7 @@
22
33# RUN: echo /out:%t.exe /entry:main %t.obj > %t.rsp
44# RUN: lld-link @%t.rsp /heap:0x3000
5# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
5# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
66CHECK: SizeOfHeapReserve: 12288
77
88# RUN: not lld-link --rsp-quoting=foobar @%t.rsp 2>&1 | \
......@@ -12,14 +12,14 @@ INVRSP: invalid response file quoting: foobar
1212# RUN: echo "blah\foo" > %t.rsp
1313# RUN: not lld-link @%t.rsp 2>&1 | \
1414# RUN: FileCheck --check-prefix=DEFRSP %s
15DEFRSP: error: could not open blah\foo
15DEFRSP: error: could not open 'blah\foo'
1616
1717# RUN: echo "blah\foo" > %t.rsp
1818# RUN: not lld-link --rsp-quoting=windows @%t.rsp 2>&1 | \
1919# RUN: FileCheck --check-prefix=WINRSP %s
20WINRSP: error: could not open blah\foo
20WINRSP: error: could not open 'blah\foo'
2121
2222# RUN: echo "blah\foo" > %t.rsp
2323# RUN: not lld-link --rsp-quoting=posix @%t.rsp 2>&1 | \
2424# RUN: FileCheck --check-prefix=POSRSP %s
25POSRSP: error: could not open blahfoo
25POSRSP: error: could not open 'blahfoo'
deps/lld/test/COFF/rsds.test+7-7
......@@ -2,29 +2,29 @@
22
33# RUN: rm -f %t.dll %t.pdb
44# RUN: lld-link /debug /pdbaltpath:test.pdb /dll /out:%t.dll /entry:DllMain %t.obj
5# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.1.txt
5# RUN: llvm-readobj --coff-debug-directory %t.dll > %t.1.txt
66# RUN: lld-link /debug /pdbaltpath:test.pdb /dll /out:%t.dll /entry:DllMain %t.obj
7# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.2.txt
7# RUN: llvm-readobj --coff-debug-directory %t.dll > %t.2.txt
88# RUN: cat %t.1.txt %t.2.txt | FileCheck %s
99
1010# RUN: rm -f %t.dll %t.pdb
1111# RUN: lld-link /debug /pdb:%t1.pdb /dll /out:%t.dll /entry:DllMain %t.obj
12# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.3.txt
12# 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
14# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.4.txt
14# RUN: llvm-readobj --coff-debug-directory %t.dll > %t.4.txt
1515# RUN: cat %t.3.txt %t.4.txt | FileCheck --check-prefix TWOPDBS %s
1616
1717# RUN: rm -f %t.dll %t.pdb
1818# 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
19# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix REPRO %s
2020
2121# RUN: rm -f %t.dll %t.pdb
2222# 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
23# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix REPRODEBUG %s
2424
2525# RUN: rm -f %t.dll %t.pdb
2626# 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
27# RUN: llvm-readobj --coff-debug-directory %t.dll | FileCheck --check-prefix MINGW %s
2828
2929# CHECK: File: [[FILE:.*]].dll
3030# CHECK: DebugDirectory [
deps/lld/test/COFF/s_udt.s+442-442
......@@ -27,450 +27,450 @@
2727# CHECK-NEXT: ============================================================
2828# CHECK: {{.*}} | S_GPROC32 [size = 44] `main`
2929# 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
30# CHECK-NEXT: type = `0x1002 (int (int, char**))`, debug start = 0, debug end = 0, flags = none
3131# CHECK-NOT: {{.*}} | S_END
3232# CHECK: {{.*}} | S_UDT [size = 28] `main::LocalTypedef`
3333# 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;
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;
5353# }
5454
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"
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/safeseh-md.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj %S/Inputs/except_handler3.lib -safeseh -out:%t.exe -opt:noref -entry:main
4# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s
4# RUN: llvm-readobj --coff-load-config %t.exe | FileCheck %s
55
66# CHECK: SEHTable [
77# CHECK-NEXT: 0x
deps/lld/test/COFF/safeseh-no.s created+57
......@@ -0,0 +1,57 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
3# RUN: not lld-link %t.obj -safeseh -out:%t.exe -entry:main 2>&1 | FileCheck %s --check-prefix=ERROR
4# safe seh should be on by default.
5# RUN: not lld-link %t.obj -out:%t.exe -entry:main 2>&1 | FileCheck %s --check-prefix=ERROR
6# RUN: lld-link %t.obj -safeseh:no -out:%t.exe -entry:main
7# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s
8# -lldmingw should also turn off safeseh by default.
9# RUN: lld-link %t.obj -lldmingw -out:%t.exe -entry:main
10# RUN: llvm-readobj --file-headers --coff-load-config %t.exe | FileCheck %s
11
12# ERROR: /safeseh: {{.*}}safeseh-no.s.tmp.obj is not compatible with SEH
13
14# CHECK: Characteristics [
15# CHECK-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH
16# CHECK: ]
17# CHECK: LoadConfig [
18# CHECK: Size: 0x48
19# CHECK: SEHandlerTable: 0x0
20# CHECK: SEHandlerCount: 0
21# CHECK: ]
22# CHECK-NOT: SEHTable
23
24
25# Explicitly mark the object as not having safeseh. LLD should error unless
26# -safeseh:no is passed.
27 .def @feat.00; .scl 3; .type 0; .endef
28 .globl @feat.00
29@feat.00 = 0
30
31 .def _main;
32 .scl 2;
33 .type 32;
34 .endef
35 .section .text,"xr",one_only,_main
36 .globl _main
37_main:
38 movl $42, %eax
39 ret
40
41# Add a handler to create an .sxdata section, which -safeseh:no should ignore.
42 .def _my_handler; .scl 3; .type 32;
43 .endef
44 .section .text,"xr",one_only,_my_handler
45_my_handler:
46 ret
47.safeseh _my_handler
48
49
50 .section .rdata,"dr"
51.globl __load_config_used
52__load_config_used:
53 .long 72
54 .fill 60, 1, 0
55 .long ___safe_se_handler_table
56 .long ___safe_se_handler_count
57
deps/lld/test/COFF/safeseh-notable.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj -safeseh -out:%t.exe -entry:main
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
55
66# This object lacks a _load_config_used global, so we set
77# IMAGE_DLL_CHARACTERISTICS_NO_SEH even though there is an exception handler.
deps/lld/test/COFF/safeseh.s+3-3
......@@ -1,11 +1,11 @@
11# REQUIRES: x86
22# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
33# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main
4# RUN: llvm-readobj -coff-basereloc -coff-load-config -file-headers %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
4# RUN: llvm-readobj --coff-basereloc --coff-load-config --file-headers %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
55# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main -debug:dwarf
6# RUN: llvm-readobj -coff-basereloc -coff-load-config -file-headers %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
6# RUN: llvm-readobj --coff-basereloc --coff-load-config --file-headers %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
77# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main
8# RUN: llvm-readobj -coff-basereloc -coff-load-config -file-headers %t.exe | FileCheck %s --check-prefix=CHECK-GC
8# RUN: llvm-readobj --coff-basereloc --coff-load-config --file-headers %t.exe | FileCheck %s --check-prefix=CHECK-GC
99
1010# __safe_se_handler_table needs to be relocated against ImageBase.
1111# check that the relocation is present.
deps/lld/test/COFF/section.test+4-4
......@@ -1,19 +1,19 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
33# RUN: /section:.foo,r %t.obj
4# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=R %s
4# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=R %s
55
66# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
77# RUN: /section:.foo,w %t.obj
8# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=W %s
8# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=W %s
99
1010# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
1111# RUN: /section:.foo,e %t.obj
12# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=E %s
12# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=E %s
1313
1414# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
1515# RUN: /section:.foo,s %t.obj
16# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=S %s
16# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=S %s
1717
1818# R: Characteristics [
1919# R-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
deps/lld/test/COFF/sort-debug.test+5-4
......@@ -1,12 +1,12 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /debug /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj -sections %t.exe | FileCheck %s
3# RUN: llvm-readobj --sections %t.exe | FileCheck %s
44# RUN: lld-link /debug:dwarf /out:%t.exe /entry:main %t.obj
5# RUN: llvm-readobj -sections %t.exe | FileCheck %s
5# RUN: llvm-readobj --sections %t.exe | FileCheck %s
66# RUN: lld-link /out:%t.exe /entry:main %t.obj
7# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=NODEBUG %s
7# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=NODEBUG %s
88# RUN: lld-link /debug:symtab /out:%t.exe /entry:main %t.obj
9# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=NODEBUG %s
9# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=NODEBUG %s
1010
1111# CHECK: Name: .text
1212# CHECK: Name: .reloc
......@@ -45,6 +45,7 @@ sections:
4545 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
4646 Alignment: 4
4747 SectionData: ''
48 SizeOfRawData: 4
4849 - Name: '.debug$S'
4950 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
5051 Alignment: 1
deps/lld/test/COFF/stack.test+5-5
......@@ -1,25 +1,25 @@
11# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
22
33# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
55
66DEFAULT: SizeOfStackReserve: 1048576
77DEFAULT: SizeOfStackCommit: 4096
88
99# RUN: lld-link /out:%t.exe /entry:main %t.obj /stack:0x3000
10# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
10# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
1111# RUN: echo "STACKSIZE 12288" > %t.def
1212# RUN: lld-link /out:%t.exe /entry:main /def:%t.def %t.obj
13# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
13# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
1414
1515CHECK1: SizeOfStackReserve: 12288
1616CHECK1: SizeOfStackCommit: 4096
1717
1818# RUN: lld-link /out:%t.exe /entry:main %t.obj /stack:0x5000,0x3000
19# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
19# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
2020# RUN: echo "STACKSIZE 20480,12288" > %t.def
2121# RUN: lld-link /out:%t.exe /entry:main /def:%t.def %t.obj
22# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
22# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
2323
2424CHECK2: SizeOfStackReserve: 20480
2525CHECK2: SizeOfStackCommit: 12288
deps/lld/test/COFF/strtab-size.s+2-2
......@@ -12,8 +12,8 @@
1212# output SymbolCount: 0 (and dumpbin.exe would error out with "invalid file
1313# or disk full, cannot seek to 0x1602").
1414
15# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
16# CHECK: SymbolCount: 199
15# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
16# CHECK: SymbolCount: 197
1717
1818.global main
1919.text
deps/lld/test/COFF/subsystem-drectve.test+2-2
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /dll /noentry /out:%t.dll %t.obj
3# RUN: llvm-readobj -file-headers %t.dll | FileCheck %s
2# RUN: lld-link -safeseh:no /dll /noentry /out:%t.dll %t.obj
3# RUN: llvm-readobj --file-headers %t.dll | FileCheck %s
44
55# CHECK: MajorOperatingSystemVersion: 42
66# CHECK: MinorOperatingSystemVersion: 43
deps/lld/test/COFF/subsystem-inference-mingw.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.o
33
44# RUN: lld-link -lldmingw %t.o -out:%t.exe
5# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
5# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
66
77# CHECK: AddressOfEntryPoint: 0x1001
88# CHECK: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
deps/lld/test/COFF/subsystem-inference.test+8-4
......@@ -1,18 +1,22 @@
11# RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj
22# RUN: lld-link /out:%t.exe %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MAIN %s
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=MAIN %s
4# RUN: lld-link /out:%t.exe %t.obj /subsystem:default,6.0
5# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=MAIN %s
46
57# RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj
68# RUN: lld-link /out:%t.exe %t.obj
7# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WMAIN %s
9# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=WMAIN %s
810
911# RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj
1012# RUN: lld-link /out:%t.exe %t.obj
11# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WINMAIN %s
13# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=WINMAIN %s
14# RUN: lld-link /out:%t.exe %t.obj /subsystem:default,6.0
15# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=WINMAIN %s
1216
1317# RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj
1418# RUN: lld-link /out:%t.exe %t.obj
15# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WWINMAIN %s
19# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=WWINMAIN %s
1620
1721# MAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
1822# WMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
deps/lld/test/COFF/subsystem-inference2.test+1-1
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj %s > %t.obj
22# 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
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
44
55# WARN: warning: found main and WinMain; defaulting to /subsystem:console
66# CHECK: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
deps/lld/test/COFF/subsystem-inference32.test+8-8
......@@ -1,18 +1,18 @@
11# RUN: sed -e s/ENTRYNAME/_main/ %s | yaml2obj > %t.obj
2# RUN: lld-link /out:%t.exe %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MAIN %s
2# RUN: lld-link -safeseh:no /out:%t.exe %t.obj
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=MAIN %s
44
55# RUN: sed s/ENTRYNAME/_wmain/ %s | yaml2obj > %t.obj
6# RUN: lld-link /out:%t.exe %t.obj
7# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WMAIN %s
6# RUN: lld-link -safeseh:no /out:%t.exe %t.obj
7# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=WMAIN %s
88
99# RUN: sed s/ENTRYNAME/_WinMain@16/ %s | yaml2obj > %t.obj
10# RUN: lld-link /out:%t.exe %t.obj
11# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WINMAIN %s
10# RUN: lld-link -safeseh:no /out:%t.exe %t.obj
11# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=WINMAIN %s
1212
1313# RUN: sed s/ENTRYNAME/_wWinMain@16/ %s | yaml2obj > %t.obj
14# RUN: lld-link /out:%t.exe %t.obj
15# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WWINMAIN %s
14# RUN: lld-link -safeseh:no /out:%t.exe %t.obj
15# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=WWINMAIN %s
1616
1717# MAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
1818# WMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
deps/lld/test/COFF/subsystem.test+11-2
......@@ -1,6 +1,6 @@
11# RUN: lld-link /entry:main /out:%t.exe /subsystem:windows \
22# RUN: %p/Inputs/ret42.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
44
55CHECK1: MajorOperatingSystemVersion: 6
66CHECK1: MinorOperatingSystemVersion: 0
......@@ -10,10 +10,19 @@ CHECK1: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
1010
1111# RUN: lld-link /entry:main /out:%t.exe /subsystem:windows,8.9 \
1212# RUN: %p/Inputs/ret42.obj
13# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
13# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
1414
1515CHECK2: MajorOperatingSystemVersion: 8
1616CHECK2: MinorOperatingSystemVersion: 9
1717CHECK2: MajorSubsystemVersion: 8
1818CHECK2: MinorSubsystemVersion: 9
1919CHECK2: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
20
21# RUN: lld-link /entry:main /out:%t.exe /subsystem:default,8.9 \
22# RUN: %p/Inputs/ret42.obj
23# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK3 %s
24
25CHECK3: MajorOperatingSystemVersion: 8
26CHECK3: MinorOperatingSystemVersion: 9
27CHECK3: MajorSubsystemVersion: 8
28CHECK3: MinorSubsystemVersion: 9
deps/lld/test/COFF/symtab-gc.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: lld-link -dll -entry:f -out:%t.dll -implib:%t.lib %tobject.obj
55# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %tmain.obj %s
66# RUN: lld-link -entry:main -out:%t.exe -opt:ref -debug:dwarf %tmain.obj %t.lib
7# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s
7# RUN: llvm-readobj --coff-imports %t.exe | FileCheck %s
88
99# CHECK-NOT: Symbol: f
1010
deps/lld/test/COFF/symtab.test+4-4
......@@ -1,13 +1,13 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /debug:dwarf /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
3# RUN: llvm-readobj -symbols %t.exe | FileCheck %s
3# RUN: llvm-readobj --symbols %t.exe | FileCheck %s
44# RUN: lld-link /debug:dwarf /opt:noref /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
5# RUN: llvm-readobj -symbols %t.exe | FileCheck %s
5# RUN: llvm-readobj --symbols %t.exe | FileCheck %s
66# RUN: lld-link /debug:symtab /opt:noref /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
7# RUN: llvm-readobj -symbols %t.exe | FileCheck %s
7# RUN: llvm-readobj --symbols %t.exe | FileCheck %s
88
99# RUN: lld-link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
10# RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=NO %s
10# RUN: llvm-readobj --symbols %t.exe | FileCheck -check-prefix=NO %s
1111
1212# CHECK: Symbols [
1313# CHECK-NEXT: Symbol {
deps/lld/test/COFF/thinlto-archivecollision.ll created+29
......@@ -0,0 +1,29 @@
1; REQUIRES: x86
2; RUN: rm -fr %t
3; RUN: mkdir %t %t/a %t/b
4; RUN: opt -thinlto-bc -o %t/main.obj %s
5; RUN: opt -thinlto-bc -o %t/a/bar.obj %S/Inputs/lto-dep.ll
6; RUN: opt -thinlto-bc -o %t/b/bar.obj %S/Inputs/bar.ll
7; RUN: llvm-ar crs %t/libbar.lib %t/a/bar.obj %t/b/bar.obj
8; RUN: lld-link -out:%t/main.exe -entry:main -lldsavetemps \
9; RUN: -subsystem:console %t/main.obj %t/libbar.lib
10; RUN: FileCheck %s < %t/main.exe.resolution.txt
11
12; CHECK: {{/|\\\\thinlto-archivecollision.ll.tmp/main.obj$}}
13; CHECK: {{^-r=.*/|\\\\thinlto-archivecollision.ll.tmp/main.obj,main,px$}}
14; CHECK: {{/|\\\\thinlto-archivecollision.ll.tmp/libbar.libbar.obj[0-9]+$}}
15; CHECK-NEXT: {{^-r=.*/|\\\\thinlto-archivecollision.ll.tmp/libbar.libbar.obj[0-9]+,foo,p$}}
16; CHECK-NEXT: {{/|\\\\thinlto-archivecollision.ll.tmp/libbar.libbar.obj[0-9]+$}}
17; CHECK-NEXT: {{^-r=.*/|\\\\thinlto-archivecollision.ll.tmp/libbar.libbar.obj[0-9]+,bar,p$}}
18
19target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
20target triple = "x86_64-pc-windows-msvc"
21
22declare void @bar()
23declare void @foo()
24
25define i32 @main() {
26 call void @foo()
27 call void @bar()
28 ret i32 0
29}
deps/lld/test/COFF/thinlto-archives.ll+4-4
......@@ -13,10 +13,10 @@
1313
1414; CHECK: {{/thinlto-archives/main.obj$}}
1515; 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$}}
16; CHECK: {{/thinlto-archives/a.libbar.obj[0-9]+$}}
17; CHECK-NEXT: {{^-r=.*/thinlto-archives/a.libbar.obj[0-9]+,foo,p$}}
18; CHECK-NEXT: {{/thinlto-archives/b.libbar.obj[0-9]+$}}
19; CHECK-NEXT: {{^-r=.*/thinlto-archives/b.libbar.obj[0-9]+,bar,p$}}
2020
2121target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2222target triple = "x86_64-pc-windows-msvc"
deps/lld/test/COFF/thinlto-emit-imports.ll created+59
......@@ -0,0 +1,59 @@
1; REQUIRES: x86
2
3; Generate summary sections and test lld handling.
4; RUN: opt -module-summary %s -o %t1.obj
5; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.obj
6
7; Include a file with an empty module summary index, to ensure that the expected
8; output files are created regardless, for a distributed build system.
9; RUN: opt -module-summary %p/Inputs/thinlto-empty.ll -o %t3.obj
10
11; Ensure lld generates imports files if requested for distributed backends.
12; RUN: rm -f %t3.obj.imports %t3.obj.thinlto.bc
13; RUN: lld-link -entry:main -thinlto-index-only \
14; RUN: -thinlto-emit-imports-files %t1.obj %t2.obj %t3.obj -out:%t4.exe
15
16; The imports file for this module contains the bitcode file for
17; Inputs/thinlto.ll
18; RUN: cat %t1.obj.imports | count 1
19; RUN: cat %t1.obj.imports | FileCheck %s --check-prefix=IMPORTS1
20; IMPORTS1: thinlto-emit-imports.ll.tmp2.obj
21
22; The imports file for Input/thinlto.ll is empty as it does not import anything.
23; RUN: cat %t2.obj.imports | count 0
24
25; The imports file for Input/thinlto_empty.ll is empty but should exist.
26; RUN: cat %t3.obj.imports | count 0
27
28; The index file should be created even for the input with an empty summary.
29; RUN: ls %t3.obj.thinlto.bc
30
31; Ensure lld generates error if unable to write to imports file.
32; RUN: rm -f %t3.obj.imports
33; RUN: touch %t3.obj.imports
34; RUN: chmod 400 %t3.obj.imports
35; RUN: not lld-link -entry:main -thinlto-index-only \
36; RUN: -thinlto-emit-imports-files %t1.obj %t2.obj %t3.obj \
37; RUN: -out:%t4.exe 2>&1 | FileCheck %s --check-prefix=ERR
38; ERR: cannot open {{.*}}3.obj.imports: {{P|p}}ermission denied
39
40; Ensure lld doesn't generate import files when thinlto-index-only is not enabled
41; RUN: rm -f %t1.obj.imports
42; RUN: rm -f %t2.obj.imports
43; RUN: rm -f %t3.obj.imports
44; RUN: lld-link -entry:main -thinlto-emit-imports-files \
45; RUN: %t1.obj %t2.obj %t3.obj -out:%t4.exe
46; RUN: not ls %t1.obj.imports
47; RUN: not ls %t2.obj.imports
48; RUN: not ls %t3.obj.imports
49
50target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
51target triple = "x86_64-pc-windows-msvc19.0.24215"
52
53declare void @g(...)
54
55define void @main() {
56entry:
57 call void (...) @g()
58 ret void
59}
deps/lld/test/COFF/thinlto-index-only.ll created+52
......@@ -0,0 +1,52 @@
1; REQUIRES: x86
2
3; Basic ThinLTO tests.
4; RUN: opt -thinlto-bc %s -o %t1.obj
5; RUN: opt -thinlto-bc %p/Inputs/thinlto.ll -o %t2.obj
6; RUN: opt -thinlto-bc %p/Inputs/thinlto-empty.ll -o %t3.obj
7
8; Ensure lld generates an index and not a binary if requested.
9; RUN: rm -f %t4.exe
10; RUN: lld-link -thinlto-index-only -entry:main %t1.obj %t2.obj -out:%t4.exe
11; RUN: llvm-bcanalyzer -dump %t1.obj.thinlto.bc | FileCheck %s --check-prefix=BACKEND1
12; RUN: llvm-bcanalyzer -dump %t2.obj.thinlto.bc | FileCheck %s --check-prefix=BACKEND2
13; RUN: not test -e %t4.exe
14
15; The backend index for this module contains summaries from itself and
16; Inputs/thinlto.ll, as it imports from the latter.
17; BACKEND1: <MODULE_STRTAB_BLOCK
18; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp{{.*}}.obj'
19; BACKEND1: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp{{.*}}.obj'
20; BACKEND1-NOT: <ENTRY
21; BACKEND1: </MODULE_STRTAB_BLOCK
22; BACKEND1: <GLOBALVAL_SUMMARY_BLOCK
23; BACKEND1: <VERSION
24; BACKEND1: <FLAGS
25; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-5300342847281564238|-2624081020897602054}}
26; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-5300342847281564238|-2624081020897602054}}
27; BACKEND1: <COMBINED
28; BACKEND1: <COMBINED
29; BACKEND1: </GLOBALVAL_SUMMARY_BLOCK
30
31; The backend index for Input/thinlto.ll contains summaries from itself only,
32; as it does not import anything.
33; BACKEND2: <MODULE_STRTAB_BLOCK
34; BACKEND2-NEXT: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp2.obj'
35; BACKEND2-NOT: <ENTRY
36; BACKEND2: </MODULE_STRTAB_BLOCK
37; BACKEND2-NEXT: <GLOBALVAL_SUMMARY_BLOCK
38; BACKEND2-NEXT: <VERSION
39; BACKEND2-NEXT: <FLAGS
40; BACKEND2-NEXT: <VALUE_GUID op0=1 op1=-5300342847281564238
41; BACKEND2-NEXT: <COMBINED
42; BACKEND2-NEXT: </GLOBALVAL_SUMMARY_BLOCK
43
44target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
45target triple = "x86_64-pc-windows-msvc19.0.24215"
46
47declare void @g(...)
48
49define void @main() {
50 call void (...) @g()
51 ret void
52}
deps/lld/test/COFF/thinlto-object-suffix-replace.ll created+50
......@@ -0,0 +1,50 @@
1; REQUIRES: x86
2
3; Test to make sure the thinlto-object-suffix-replace option is handled
4; correctly.
5
6; Generate bitcode file with summary, as well as a minimized bitcode without
7; the debug metadata for the thin link.
8; RUN: opt -thinlto-bc %s -thin-link-bitcode-file=%t1.thinlink.bc -o %t1.obj
9
10; First perform the thin link on the normal bitcode file, and save the
11; resulting index.
12; RUN: lld-link -thinlto-index-only -entry:main %t1.obj -out:%t3.exe
13; RUN: cp %t1.obj.thinlto.bc %t1.obj.thinlto.bc.orig
14
15; Next perform the thin link on the minimized bitcode file, and compare dump
16; of the resulting index to the above dump to ensure they are identical.
17; RUN: rm -f %t1.obj.thinlto.bc
18; Make sure it isn't inadvertently using the regular bitcode file.
19; RUN: rm -f %t1.obj
20; RUN: lld-link -entry:main -thinlto-index-only \
21; RUN: -thinlto-object-suffix-replace:".thinlink.bc;.obj" \
22; RUN: %t1.thinlink.bc -out:%t3.exe
23; RUN: diff %t1.obj.thinlto.bc.orig %t1.obj.thinlto.bc
24
25; Ensure lld generates error if suffix replace option not in 'old;new' format.
26; RUN: rm -f %t1.obj.thinlto.bc
27; RUN: not lld-link -entry:main -thinlto-index-only \
28; RUN: -thinlto-object-suffix-replace:"abc:def" %t1.thinlink.bc \
29; RUN: -out:%t3.exe 2>&1 | FileCheck %s --check-prefix=ERR1
30; ERR1: -thinlto-object-suffix-replace: expects 'old;new' format, but got abc:def
31
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: lld-link -entry:main -thinlto-index-only \
36; RUN: -thinlto-object-suffix-replace:".abc;.obj" %t1.thinlink.bc -out:%t3.exe
37; RUN: ls %t1.thinlink.bc.thinlto.bc
38
39target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
40target triple = "x86_64-pc-windows-msvc19.0.24215"
41
42define void @main() {
43entry:
44 ret void
45}
46
47!llvm.dbg.cu = !{}
48
49!1 = !{i32 2, !"Debug Info Version", i32 3}
50!llvm.module.flags = !{!1}
deps/lld/test/COFF/thinlto-prefix-replace.ll created+26
......@@ -0,0 +1,26 @@
1; REQUIRES: x86
2; Check that changing the output path via thinlto-prefix-replace works
3; RUN: mkdir -p %t/oldpath
4; RUN: opt -module-summary %s -o %t/oldpath/t.obj
5
6; Ensure that there is no existing file at the new path, so we properly
7; test the creation of the new file there.
8; RUN: rm -f %t/newpath/t.obj.thinlto.bc
9; RUN: lld-link -entry:main -thinlto-index-only \
10; RUN: -thinlto-prefix-replace:"%t/oldpath/;%t/newpath/" %t/oldpath/t.obj \
11; RUN: -out:%t/t.exe
12; RUN: ls %t/newpath/t.obj.thinlto.bc
13
14; Ensure that lld errors if prefix replace option is not in 'old;new' format.
15; RUN: rm -f %t/newpath/t.obj.thinlto.bc
16; RUN: not lld-link -entry:main -thinlto-index-only \
17; RUN: -thinlto-prefix-replace:"abc:def" %t/oldpath/t.obj \
18; RUN: -out:%t/t.exe 2>&1 | FileCheck --check-prefix=ERR %s
19; ERR: -thinlto-prefix-replace: expects 'old;new' format, but got abc:def
20
21target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
22target triple = "x86_64-pc-windows-msvc19.0.24215"
23
24define void @main() {
25 ret void
26}
deps/lld/test/COFF/timestamp.test+3-3
......@@ -3,9 +3,9 @@ RUN: yaml2obj %p/Inputs/generic.yaml > %t.obj
33RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.1.exe
44RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.2.exe
55RUN: lld-link %t.obj /debug /timestamp:0 /entry:main /nodefaultlib /out:%t.3.exe
6RUN: llvm-readobj -file-headers -coff-debug-directory %t.1.exe | FileCheck %s --check-prefix=HASH
7RUN: llvm-readobj -file-headers -coff-debug-directory %t.2.exe | FileCheck %s --check-prefix=HASH
8RUN: llvm-readobj -file-headers -coff-debug-directory %t.3.exe | FileCheck %s --check-prefix=ZERO
6RUN: llvm-readobj --file-headers --coff-debug-directory %t.1.exe | FileCheck %s --check-prefix=HASH
7RUN: llvm-readobj --file-headers --coff-debug-directory %t.2.exe | FileCheck %s --check-prefix=HASH
8RUN: llvm-readobj --file-headers --coff-debug-directory %t.3.exe | FileCheck %s --check-prefix=ZERO
99
1010HASH: ImageFileHeader {
1111HASH: TimeDateStamp: [[STAMP:.*]]
deps/lld/test/COFF/tls.test+1-1
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj < %s > %t.obj
22# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
44
55# CHECK: TLSTableRVA: 0x1000
66# CHECK: TLSTableSize: 0x28
deps/lld/test/COFF/tls32.test+2-2
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
2# RUN: lld-link -safeseh:no /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
44
55# CHECK: TLSTableRVA: 0x1000
66# CHECK: TLSTableSize: 0x18
deps/lld/test/COFF/tls_suffix_sorting.s created+27
......@@ -0,0 +1,27 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/tlssup.s -filetype=obj -o %t.tlssup.o
4# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.main.o
5
6# RUN: lld-link -lldmingw -entry:main %t.main.o %t.tlssup.o -out:%t.exe
7# RUN: llvm-objdump -s %t.exe | FileCheck %s
8
9# Check that .tls$$foo is sorted after the start marker (aa) and before the
10# end marker (ff).
11
12# CHECK: Contents of section .tls:
13# CHECK: 140004000 aabbff
14
15 .text
16 .globl main
17main:
18 movl _tls_index(%rip), %eax
19 movq %gs:88, %rcx
20 movq (%rcx,%rax,8), %rax
21 movb foo@SECREL32(%rax), %al
22 ret
23
24 .section .tls$$foo,"dw"
25 .linkonce discard
26foo:
27 .byte 0xbb
deps/lld/test/COFF/undefined-symbol-cv.s+3-3
......@@ -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: "int __cdecl foo(void)" (?foo@@YAHXZ)
5# CHECK: error: undefined symbol: int __cdecl foo(void)
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)
1010# CHECK-EMPTY:
11# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ)
11# CHECK-NEXT: error: undefined symbol: int __cdecl bar(void)
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)
1616# CHECK-EMPTY:
17# CHECK-NEXT: error: undefined symbol: "int __cdecl baz(void)" (?baz@@YAHXZ)
17# CHECK-NEXT: error: undefined symbol: int __cdecl baz(void)
1818# CHECK-NEXT: >>> referenced by file1.cpp:5
1919# CHECK-NEXT: >>> {{.*}}.obj:(f2)
2020
deps/lld/test/COFF/undefined-symbol-lto.test created+31
......@@ -0,0 +1,31 @@
1REQUIRES: x86
2
3RUN: rm -rf %t && mkdir -p %t && cd %t
4RUN: llvm-as %S/Inputs/undefined-symbol-lto-a.ll -o t.obj
5RUN: llvm-as %S/Inputs/undefined-symbol-lto-b.ll -o b.obj
6RUN: llvm-lib b.obj -out:b.lib
7RUN: not lld-link -entry:main -nodefaultlib t.obj b.lib -subsystem:console 2>&1 | FileCheck %s
8
9CHECK: undefined symbol: main
10CHECK: undefined symbol: void __cdecl undefined_ref(void)
11CHECK: referenced by
12
13Originally reported as PR42536.
14
15a.ll corresponds to this C++:
16
17struct __declspec(dllimport) S {
18 virtual void foo();
19};
20void undefined_ref();
21struct Init {
22 Init() { undefined_ref(); }
23 S c;
24} d;
25
26b.ll is from this C++:
27
28struct S {
29 virtual void foo();
30};
31void S::foo() {}
deps/lld/test/COFF/undefined-symbol-multi.s created+47
......@@ -0,0 +1,47 @@
1# REQUIRES: x86
2# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
3
4# All references to a single undefined symbol count as a single error -- but
5# at most 10 references are printed.
6# RUN: echo ".globl bar" > %t.moreref.s
7# RUN: echo "bar:" >> %t.moreref.s
8# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
9# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
10# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
11# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
12# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
13# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
14# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
15# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
16# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
17# RUN: echo ' call "?foo@@YAHXZ"' >> %t.moreref.s
18# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t2.obj %t.moreref.s
19# RUN: not lld-link /out:/dev/null %t.obj %t2.obj 2>&1 | FileCheck %s
20
21# CHECK: error: undefined symbol: int __cdecl foo(void)
22# CHECK-NEXT: >>> referenced by {{.*}}tmp.obj:(main)
23# CHECK-NEXT: >>> referenced by {{.*}}tmp.obj:(main)
24# CHECK-NEXT: >>> referenced by {{.*}}tmp2.obj:(bar)
25# CHECK-NEXT: >>> referenced by {{.*}}tmp2.obj:(bar)
26# CHECK-NEXT: >>> referenced by {{.*}}tmp2.obj:(bar)
27# CHECK-NEXT: >>> referenced by {{.*}}tmp2.obj:(bar)
28# CHECK-NEXT: >>> referenced by {{.*}}tmp2.obj:(bar)
29# CHECK-NEXT: >>> referenced by {{.*}}tmp2.obj:(bar)
30# CHECK-NEXT: >>> referenced by {{.*}}tmp2.obj:(bar)
31# CHECK-NEXT: >>> referenced by {{.*}}tmp2.obj:(bar)
32# CHECK-NEXT: >>> referenced 2 more times
33# CHECK-EMPTY:
34# CHECK-NEXT: error: undefined symbol: int __cdecl bar(void)
35# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
36# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1)
37
38 .section .text,"xr",one_only,main
39.globl main
40main:
41 call "?foo@@YAHXZ"
42 call "?foo@@YAHXZ"
43 call "?bar@@YAHXZ"
44
45f1:
46 call "?bar@@YAHXZ"
47.Lfunc_end1:
deps/lld/test/COFF/undefined-symbol.s+9-3
......@@ -1,16 +1,22 @@
11# REQUIRES: x86
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
4# RUN: not lld-link /out:%t.exe /demangle %t.obj 2>&1 | FileCheck %s
5# RUN: not lld-link /out:%t.exe /demangle:no %t.obj 2>&1 | FileCheck --check-prefix=NODEMANGLE %s
46
5# CHECK: error: undefined symbol: "int __cdecl foo(void)" (?foo@@YAHXZ)
7# NODEMANGLE: error: undefined symbol: ?foo@@YAHXZ
8# NODEMANGLE: error: undefined symbol: ?bar@@YAHXZ
9# NODEMANGLE: error: undefined symbol: __imp_?baz@@YAHXZ
10
11# CHECK: error: undefined symbol: int __cdecl foo(void)
612# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
713# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
814# CHECK-EMPTY:
9# CHECK-NEXT: error: undefined symbol: "int __cdecl bar(void)" (?bar@@YAHXZ)
15# CHECK-NEXT: error: undefined symbol: int __cdecl bar(void)
1016# CHECK-NEXT: >>> referenced by {{.*}}.obj:(main)
1117# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1)
1218# CHECK-EMPTY:
13# CHECK-NEXT: error: undefined symbol: "__declspec(dllimport) int __cdecl baz(void)" (__imp_?baz@@YAHXZ)
19# CHECK-NEXT: error: undefined symbol: __declspec(dllimport) int __cdecl baz(void)
1420# CHECK-NEXT: >>> referenced by {{.*}}.obj:(f2)
1521
1622 .section .text,"xr",one_only,main
deps/lld/test/COFF/unwind.test+2-2
......@@ -1,11 +1,11 @@
11# RUN: yaml2obj < %s > %t.obj
22#
33# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=HEADER %s
55# RUN: llvm-objdump -unwind-info %t.exe | FileCheck -check-prefix=UNWIND %s
66#
77# RUN: lld-link /merge:.pdata=.rdata /out:%t.exe /entry:main %t.obj
8# RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck -check-prefix=HEADER-MERGE %s
8# RUN: llvm-readobj --file-headers --sections %t.exe | FileCheck -check-prefix=HEADER-MERGE %s
99#
1010# HEADER: ExceptionTableRVA: 0x3000
1111#
deps/lld/test/COFF/used-lto.ll created+15
......@@ -0,0 +1,15 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t.obj %s
3; RUN: lld-link -dll -debug -opt:ref -noentry -out:%t.dll %t.obj
4; RUN: llvm-pdbutil dump -publics %t.pdb | FileCheck %s
5
6; CHECK: S_PUB32 {{.*}} `foo`
7
8target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
9target triple = "x86_64-pc-windows-msvc"
10
11@llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @foo to i8*)], section "llvm.metadata"
12
13define void @foo() {
14 ret void
15}
deps/lld/test/COFF/version.test+3-3
......@@ -1,19 +1,19 @@
11# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
22
33# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
4# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
55
66DEFAULT: MajorImageVersion: 0
77DEFAULT: MinorImageVersion: 0
88
99# RUN: lld-link /out:%t.exe /entry:main %t.obj /version:11
10# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
10# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
1111
1212CHECK1: MajorImageVersion: 11
1313CHECK1: MinorImageVersion: 0
1414
1515# RUN: lld-link /out:%t.exe /entry:main %t.obj /version:11.22
16# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
16# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
1717
1818CHECK2: MajorImageVersion: 11
1919CHECK2: MinorImageVersion: 22
deps/lld/test/COFF/wx.s+5-5
......@@ -1,15 +1,15 @@
11# REQUIRES: x86
22
33# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
4# RUN: not lld-link /out:%t.exe /entry:main -notarealoption /WX %t.obj 2>&1 | \
4# RUN: not lld-link /out:%t.exe /entry:main -notarealopt=ion /WX %t.obj 2>&1 | \
55# RUN: FileCheck -check-prefix=ERROR %s
6# RUN: not lld-link /out:%t.exe /entry:main -notarealoption /WX:NO /WX %t.obj 2>&1 | \
6# RUN: not lld-link /out:%t.exe /entry:main -notarealopt=ion /WX:NO /WX %t.obj 2>&1 | \
77# RUN: FileCheck -check-prefix=ERROR %s
8# RUN: lld-link /out:%t.exe /entry:main -notarealoption /WX /WX:NO %t.obj 2>&1 | \
8# RUN: lld-link /out:%t.exe /entry:main -notarealopt=ion /WX /WX:NO %t.obj 2>&1 | \
99# RUN: FileCheck -check-prefix=WARNING %s
1010
11# ERROR: error: ignoring unknown argument: -notarealoption
12# WARNING: warning: ignoring unknown argument: -notarealoption
11# ERROR: error: ignoring unknown argument '-notarealopt=ion'
12# WARNING: warning: ignoring unknown argument '-notarealopt=ion'
1313
1414.text
1515.global main
deps/lld/test/ELF/Inputs/aarch64-addrifunc.s created+8
......@@ -0,0 +1,8 @@
1 .text
2 .globl myfunc
3 .globl func1
4 .type func1, %function
5func1:
6 adrp x8, :got: myfunc
7 ldr x8, [x8, :got_lo12: myfunc]
8 ret
deps/lld/test/ELF/Inputs/aarch64-bti1.s created+19
......@@ -0,0 +1,19 @@
1.section ".note.gnu.property", "a"
2.long 4
3.long 0x10
4.long 0x5
5.asciz "GNU"
6
7.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
8.long 4
9.long 1 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI
10.long 0
11
12.text
13.globl func2
14.type func2,@function
15func2:
16 .globl func3
17 .type func3, @function
18 bl func3
19 ret
deps/lld/test/ELF/Inputs/aarch64-btipac1.s created+19
......@@ -0,0 +1,19 @@
1.section ".note.gnu.property", "a"
2.long 4
3.long 0x10
4.long 0x5
5.asciz "GNU"
6
7.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
8.long 4
9.long 3 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC and BTI
10.long 0
11
12.text
13.globl func2
14.type func2,@function
15func2:
16 .globl func3
17 .type func3, @function
18 bl func3
19 ret
deps/lld/test/ELF/Inputs/aarch64-func2.s created+8
......@@ -0,0 +1,8 @@
1.text
2.globl func2
3.type func2,@function
4func2:
5 .globl func3
6 .type func3, @function
7 bl func3
8 ret
deps/lld/test/ELF/Inputs/aarch64-func3-bti.s created+16
......@@ -0,0 +1,16 @@
1.section ".note.gnu.property", "a"
2.long 4
3.long 0x10
4.long 0x5
5.asciz "GNU"
6
7.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
8.long 4
9.long 1 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI
10.long 0
11
12.text
13.globl func3
14.type func3,@function
15func3:
16 ret
deps/lld/test/ELF/Inputs/aarch64-func3-btipac.s created+16
......@@ -0,0 +1,16 @@
1.section ".note.gnu.property", "a"
2.long 4
3.long 0x10
4.long 0x5
5.asciz "GNU"
6
7.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
8.long 4
9.long 3 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC
10.long 0
11
12.text
13.globl func3
14.type func3,@function
15func3:
16 ret
deps/lld/test/ELF/Inputs/aarch64-func3-pac.s created+16
......@@ -0,0 +1,16 @@
1.section ".note.gnu.property", "a"
2.long 4
3.long 0x10
4.long 0x5
5.asciz "GNU"
6
7.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
8.long 4
9.long 2 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC
10.long 0
11
12.text
13.globl func3
14.type func3,@function
15func3:
16 ret
deps/lld/test/ELF/Inputs/aarch64-func3.s created+5
......@@ -0,0 +1,5 @@
1.text
2.globl func3
3.type func3,@function
4func3:
5 ret
deps/lld/test/ELF/Inputs/aarch64-nobti.s created+8
......@@ -0,0 +1,8 @@
1.text
2.globl func2
3.type func2,@function
4func2:
5 .globl func3
6 .type func3, @function
7 bl func3
8 ret
deps/lld/test/ELF/Inputs/aarch64-nopac.s created+8
......@@ -0,0 +1,8 @@
1.text
2.globl func2
3.type func2,@function
4func2:
5 .globl func3
6 .type func3, @function
7 bl func3
8 ret
deps/lld/test/ELF/Inputs/aarch64-pac1.s created+19
......@@ -0,0 +1,19 @@
1.section ".note.gnu.property", "a"
2.long 4
3.long 0x10
4.long 0x5
5.asciz "GNU"
6
7.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
8.long 4
9.long 2 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC
10.long 0
11
12.text
13.globl func2
14.type func2,@function
15func2:
16 .globl func3
17 .type func3, @function
18 bl func3
19 ret
deps/lld/test/ELF/Inputs/bad-reloc-target.test deleted-21
......@@ -1,21 +0,0 @@
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/comdat-discarded-reloc.s+7-5
......@@ -1,6 +1,8 @@
1.section .text.bar1,"aG",@progbits,group,comdat
1.global bar, _start
22
3.section .text.bar2
4.global bar
5bar:
6 .quad .text.bar1
3.section .text.foo,"aG",@progbits,group,comdat
4
5.section .text
6_start:
7 .quad .text.foo
8 .quad bar
deps/lld/test/ELF/Inputs/deplibs-lib_bar.s created+2
......@@ -0,0 +1,2 @@
1 .global bar
2bar:
deps/lld/test/ELF/Inputs/deplibs-lib_foo.s created+2
......@@ -0,0 +1,2 @@
1 .global foo
2foo:
deps/lld/test/ELF/Inputs/dtrace-r.o deleted
Binary files a/deps/lld/test/ELF/Inputs/dtrace-r.o and /dev/null differ
deps/lld/test/ELF/Inputs/dummy-shared.s created+2
......@@ -0,0 +1,2 @@
1.globl bar
2bar:
deps/lld/test/ELF/Inputs/gdb-index-multiple-cu-2.s+1-1
......@@ -31,7 +31,7 @@ _start:
3131 .byte 0
3232.Lcu_end0:
3333
34# .debug_gnu_pubnames has just one set, associated with .Lcu_begin1 (CuIndex: 1)
34# .debug_gnu_pubnames has just one set, associated with .Lcu_begin1 (cuIndex: 1)
3535.section .debug_gnu_pubnames,"",@progbits
3636 .long .LpubNames_end0 - .LpubNames_begin0
3737.LpubNames_begin0:
deps/lld/test/ELF/Inputs/gnu-ifunc-canon-ro-abs.s created+2
......@@ -0,0 +1,2 @@
1.rodata
2.8byte ifunc
deps/lld/test/ELF/Inputs/gnu-ifunc-canon-ro-pcrel.s created+2
......@@ -0,0 +1,2 @@
1.rodata
2.4byte ifunc - .
deps/lld/test/ELF/Inputs/gnu-ifunc-canon-rw-addend.s created+2
......@@ -0,0 +1,2 @@
1.data
2.8byte ifunc + 1
deps/lld/test/ELF/Inputs/i386-cet1.s created+16
......@@ -0,0 +1,16 @@
1.section ".note.gnu.property", "a"
2.align 4
3.long 4
4.long 12
5.long 5
6.asciz "GNU"
7
8.long 0xc0000002
9.long 4
10.long 3
11
12.text
13.globl func2
14.type func2,@function
15func2:
16 ret
deps/lld/test/ELF/Inputs/i386-cet2.s created+20
......@@ -0,0 +1,20 @@
1.section ".note.gnu.property", "a"
2.align 4
3.long 4
4.long 24
5.long 5
6.asciz "GNU"
7
8.long 0xc0000000
9.long 4
10.long 0
11
12.long 0xc0000002
13.long 4
14.long 3
15
16.text
17.globl func2
18.type func2,@function
19func2:
20 ret
deps/lld/test/ELF/Inputs/i386-cet3.s created+5
......@@ -0,0 +1,5 @@
1.text
2.globl func2
3.type func2,@function
4func2:
5 ret
deps/lld/test/ELF/Inputs/i386-cet4.s created+16
......@@ -0,0 +1,16 @@
1.section ".note.gnu.property", "a"
2.align 4
3.long 4
4.long 12
5.long 5
6.asciz "GNU"
7
8.long 0xc0000002
9.long 4
10.long 0xfffffffd
11
12.text
13.globl func2
14.type func2,@function
15func2:
16 ret
deps/lld/test/ELF/Inputs/i386-reloc-16-error.s deleted-3
......@@ -1,3 +0,0 @@
1.globl foo
2.hidden foo
3foo = 65536
deps/lld/test/ELF/Inputs/i386-reloc-16.s deleted-3
......@@ -1,3 +0,0 @@
1.globl foo
2.hidden foo
3foo = 0xffff
deps/lld/test/ELF/Inputs/i386-reloc-8-error.s deleted-3
......@@ -1,3 +0,0 @@
1.globl foo
2.hidden foo
3foo = 256
deps/lld/test/ELF/Inputs/i386-reloc-8.s deleted-3
......@@ -1,3 +0,0 @@
1.globl foo
2.hidden foo
3foo = 0xff
deps/lld/test/ELF/Inputs/i386-static-tls-model1.s created+9
......@@ -0,0 +1,9 @@
1.section ".tdata", "awT", @progbits
2.globl var
3var:
4
5.section .foo, "aw"
6.global _start
7_start:
8 movl $var@tpoff, %edx # R_386_TLS_LE_32
9 movl %gs:0, %ecx
deps/lld/test/ELF/Inputs/i386-static-tls-model2.s created+9
......@@ -0,0 +1,9 @@
1.section ".tdata", "awT", @progbits
2.globl var
3var:
4
5.section .foo, "aw"
6.global _start
7_start:
8 movl %gs:0, %eax
9 addl var@gotntpoff(%ebx), %eax # R_386_TLS_GOTIE
deps/lld/test/ELF/Inputs/i386-static-tls-model3.s created+9
......@@ -0,0 +1,9 @@
1.section ".tdata", "awT", @progbits
2.globl var
3var:
4
5.section .foo, "aw"
6.global _start
7_start:
8 movl %gs:0, %eax
9 addl var@indntpoff, %eax # R_386_TLS_IE
deps/lld/test/ELF/Inputs/i386-static-tls-model4.s created+9
......@@ -0,0 +1,9 @@
1.section ".tdata", "awT", @progbits
2.globl var
3var:
4
5.section .foo, "aw"
6.global _start
7_start:
8 movl %gs:0, %eax
9 leal var@ntpoff(%eax), %eax # R_386_TLS_LE
deps/lld/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input2.s created+23
......@@ -0,0 +1,23 @@
1 .text
2
3 .global set
4 .type set,@function
5set:
6.Lgep:
7 addis 2, 12, .TOC.-.Lgep@ha
8 addi 2, 2, .TOC.-.Lgep@l
9.Llep:
10 .localentry set, .Llep-.Lgep
11 addis 5, 2, .LC0@toc@ha
12 addis 6, 2, .LC1@toc@ha
13 ld 5, .LC0@toc@l(5)
14 ld 6, .LC1@toc@l(6)
15 stw 3, 0(5)
16 stw 4, 0(6)
17 blr
18
19 .section .toc,"aw",@progbits
20.LC0:
21 .tc c[TC],c
22.LC1:
23 .tc d[TC],d
deps/lld/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input3.s created+41
......@@ -0,0 +1,41 @@
1 .text
2 .global getA
3 .type getA,@function
4getA:
5.LgepA:
6 addis 2, 12, .TOC.-.LgepA@ha
7 addi 2, 2, .TOC.-.LgepA@l
8.LlepA:
9 .localentry getA, .LlepA-.LgepA
10 ld 3, .LC0@toc(2)
11 lwa 3, 0(3)
12 blr
13
14 .global getB
15 .type getB,@function
16getB:
17.LgepB:
18 addis 2, 12, .TOC.-.LgepB@ha
19 addi 2, 2, .TOC.-.LgepB@l
20.LlepB:
21 .localentry getB, .LlepB-.LgepB
22 ld 3, .LC1@toc(2)
23 lwa 3, 0(3)
24 blr
25
26 .section .toc,"aw",@progbits
27.LC0:
28 .tc a[TC],a
29.LConst1:
30 .quad 0xa
31.LC1:
32 .tc b[TC],b
33.Lconst2:
34 .quad 0xaabbccddeeff
35
36 .type b,@object
37 .data
38 .global b
39b:
40 .long 22
41 .size b, 4
deps/lld/test/ELF/Inputs/ppc64-sort-small-cm-relocs-input4.s created+18
......@@ -0,0 +1,18 @@
1 .text
2 .global getRodata
3 .type getRodata,@function
4getRodata:
5.Lgep:
6 addis 2, 12, .TOC.-.Lgep@ha
7 addi 2, 2, .TOC.-.Lgep@l
8.Llep:
9 .localentry getRodata, .Llep-.Lgep
10 lwa 3, .LC0@toc(2)
11 blr
12
13 .section .rodata,"aMS",@progbits,8
14 .quad _start
15
16 .section .toc,"aw",@progbits
17.LC0:
18 .tc .rodata[TC], .rodata
deps/lld/test/ELF/Inputs/ppc64-toc-relax-shared.s created+7
......@@ -0,0 +1,7 @@
1.data
2
3.type shared,@object
4.globl shared
5shared:
6 .long 8
7 .size shared, 4
deps/lld/test/ELF/Inputs/ppc64-toc-relax.s created+15
......@@ -0,0 +1,15 @@
1.data
2
3.globl default, hidden
4.hidden hidden
5
6default:
7hidden:
8 .long 0
9
10.space 65532
11
12.globl hidden2
13.hidden hidden2
14hidden2:
15 .long 0
deps/lld/test/ELF/Inputs/print-icf.s+9-9
......@@ -1,9 +1,9 @@
1.section .text.f6, "ax"
2f6:
3 mov $60, %rax
4 mov $42, %rdi
5 syscall
6
7 .section .text.f7, "ax"
8f7:
9 mov $0, %rax
1.section .text.f6, "ax"
2f6:
3 mov $60, %rax
4 mov $42, %rdi
5 syscall
6
7 .section .text.f7, "ax"
8f7:
9 mov $0, %rax
deps/lld/test/ELF/Inputs/shf-info-link.test+2-2
......@@ -17,5 +17,5 @@ Sections:
1717 Symbol: foo
1818 Type: R_X86_64_64
1919Symbols:
20 Global:
21 - Name: foo
20 - Name: foo
21 Binding: STB_GLOBAL
deps/lld/test/ELF/Inputs/vs-diagnostics-duplicate2.s created+31
......@@ -0,0 +1,31 @@
1.global foo, bar
2
3.text
4foo:
5 nop
6
7.file 1 "duplicate2.s"
8.loc 1 20
9bar:
10 nop
11
12.section .debug_abbrev,"",@progbits
13 .byte 1 # Abbreviation Code
14 .byte 17 # DW_TAG_compile_unit
15 .byte 0 # DW_CHILDREN_no
16 .byte 16 # DW_AT_stmt_list
17 .byte 23 # DW_FORM_sec_offset
18 .byte 0 # EOM(1)
19 .byte 0 # EOM(2)
20 .byte 0 # EOM(3)
21
22.section .debug_info,"",@progbits
23 .long .Lend0 - .Lbegin0 # Length of Unit
24.Lbegin0:
25 .short 4 # DWARF version number
26 .long .debug_abbrev # Offset Into Abbrev. Section
27 .byte 8 # Address Size (in bytes)
28 .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
29 .long .debug_line # DW_AT_stmt_list
30.Lend0:
31 .section .debug_line,"",@progbits
deps/lld/test/ELF/Inputs/vs-diagnostics-duplicate3.s created+6
......@@ -0,0 +1,6 @@
1.file "duplicate3.s"
2
3.global baz
4.text
5baz:
6 nop
deps/lld/test/ELF/Inputs/x86-64-cet1.s created+17
......@@ -0,0 +1,17 @@
1.section ".note.gnu.property", "a"
2.align 4
3.long 4
4.long 16
5.long 5
6.asciz "GNU"
7
8.long 0xc0000002
9.long 4
10.long 3
11.long 0
12
13.text
14.globl func2
15.type func2,@function
16func2:
17 ret
deps/lld/test/ELF/Inputs/x86-64-cet2.s created+22
......@@ -0,0 +1,22 @@
1.section ".note.gnu.property", "a"
2.align 4
3.long 4
4.long 32
5.long 5
6.asciz "GNU"
7
8.long 0xc0000000
9.long 4
10.long 0
11.long 0
12
13.long 0xc0000002
14.long 4
15.long 3
16.long 0
17
18.text
19.globl func2
20.type func2,@function
21func2:
22 ret
deps/lld/test/ELF/Inputs/x86-64-cet3.s created+5
......@@ -0,0 +1,5 @@
1.text
2.globl func2
3.type func2,@function
4func2:
5 ret
deps/lld/test/ELF/Inputs/x86-64-cet4.s created+17
......@@ -0,0 +1,17 @@
1.section ".note.gnu.property", "a"
2.align 4
3.long 4
4.long 16
5.long 5
6.asciz "GNU"
7
8.long 0xc0000002
9.long 4
10.long 0xfffffffd
11.long 0
12
13.text
14.globl func2
15.type func2,@function
16func2:
17 ret
deps/lld/test/ELF/Inputs/x86-64-pcrel.s created+8
......@@ -0,0 +1,8 @@
1.globl foo
2foo:
3
4.word _start - foo
5.fill 14,1,0xcc
6
7.byte _start - foo
8.fill 15,1,0xcc
deps/lld/test/ELF/Inputs/x86-64-reloc-16-error.s deleted-3
......@@ -1,3 +0,0 @@
1.globl foo
2.hidden foo
3foo = 65536
deps/lld/test/ELF/Inputs/x86-64-reloc-16.s deleted-3
......@@ -1,3 +0,0 @@
1.globl foo
2.hidden foo
3foo = 0x42
deps/lld/test/ELF/Inputs/x86-64-reloc-8-error.s deleted-3
......@@ -1,3 +0,0 @@
1.globl foo
2.hidden foo
3foo = 256
deps/lld/test/ELF/Inputs/x86-64-reloc-8.s deleted-3
......@@ -1,3 +0,0 @@
1.globl foo
2.hidden foo
3foo = 0x42
deps/lld/test/ELF/aarch64-abs16.s+4-4
......@@ -20,8 +20,8 @@ _start:
2020// S + A = 0x8000
2121// CHECK-NEXT: 210000 ffff0080
2222
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]
23// RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
24// OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 65535]
2525
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]
26// RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
27// OVERFLOW2: relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535]
deps/lld/test/ELF/aarch64-abs32-dyn.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
3# RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s
4
5## Test we don't create R_AARCH64_RELATIVE.
6
7# CHECK: error: relocation R_AARCH64_ABS32 cannot be used against symbol hidden; recompile with -fPIC
8
9.globl hidden
10.hidden hidden
11hidden:
12
13.data
14.long hidden
deps/lld/test/ELF/aarch64-abs32.s+4-4
......@@ -20,8 +20,8 @@ _start:
2020// S + A = 0x80000000
2121// CHECK-NEXT: 210000 ffffffff 00000080
2222
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]
23// RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
24// OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 4294967295]
2525
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]
26// RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
27// OVERFLOW2: relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295]
deps/lld/test/ELF/aarch64-abs64-dyn.s+1-1
......@@ -14,7 +14,7 @@ bar:
1414 .xword bar
1515
1616// RUN: ld.lld -shared -o %t.so %t.o
17// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s
17// RUN: llvm-readobj --symbols --dyn-relocations %t.so | FileCheck %s
1818
1919// CHECK: Dynamic Relocations {
2020// CHECK-NEXT: {{.*}} R_AARCH64_RELATIVE - [[BAR_ADDR:.*]]
deps/lld/test/ELF/aarch64-bti-pac-cli-error.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2# RUN: llvm-mc --triple=x86_64-pc-linux --filetype=obj -o %t.o %s
3# RUN: not ld.lld --pac-plt --force-bti %t.o -o %t 2>&1 | FileCheck %s
4#
5## Check that we error if --pac-plt and --force-bti are used when target is not
6## aarch64
7
8# CHECK: error: --pac-plt only supported on AArch64
9# CHECK-NEXT: error: --force-bti only supported on AArch64
10
11 .globl start
12start: ret
deps/lld/test/ELF/aarch64-call26-thunk.s+1
......@@ -10,6 +10,7 @@ _start:
1010 bl big
1111
1212// CHECK: Disassembly of section .text:
13// CHECK-EMPTY:
1314// CHECK-NEXT: _start:
1415// CHECK-NEXT: 210000: 02 00 00 94 bl #8
1516// CHECK: __AArch64AbsLongThunk_big:
deps/lld/test/ELF/aarch64-condb-reloc.s+14-10
......@@ -5,12 +5,13 @@
55# RUN: llvm-objdump -d %t | FileCheck %s
66# RUN: ld.lld -shared %t1 %t2 -o %t3
77# RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=DSO %s
8# RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
8# RUN: llvm-readobj -S -r %t3 | FileCheck -check-prefix=DSOREL %s
99
1010# 0x11024 - 36 = 0x11000
1111# 0x11028 - 24 = 0x11010
1212# 0x1102c - 16 = 0x1101c
1313# CHECK: Disassembly of section .text:
14# CHECK-EMPTY:
1415# CHECK-NEXT: _foo:
1516# CHECK-NEXT: 210000: {{.*}} nop
1617# CHECK-NEXT: 210004: {{.*}} nop
......@@ -36,8 +37,8 @@
3637#DSOREL-NEXT: SHF_ALLOC
3738#DSOREL-NEXT: SHF_WRITE
3839#DSOREL-NEXT: ]
39#DSOREL-NEXT: Address: 0x20000
40#DSOREL-NEXT: Offset: 0x20000
40#DSOREL-NEXT: Address: 0x30000
41#DSOREL-NEXT: Offset: 0x30000
4142#DSOREL-NEXT: Size: 48
4243#DSOREL-NEXT: Link: 0
4344#DSOREL-NEXT: Info: 0
......@@ -46,13 +47,14 @@
4647#DSOREL-NEXT: }
4748#DSOREL: Relocations [
4849#DSOREL-NEXT: Section ({{.*}}) .rela.plt {
49#DSOREL-NEXT: 0x20018 R_AARCH64_JUMP_SLOT _foo
50#DSOREL-NEXT: 0x20020 R_AARCH64_JUMP_SLOT _bar
51#DSOREL-NEXT: 0x20028 R_AARCH64_JUMP_SLOT _dah
50#DSOREL-NEXT: 0x30018 R_AARCH64_JUMP_SLOT _foo
51#DSOREL-NEXT: 0x30020 R_AARCH64_JUMP_SLOT _bar
52#DSOREL-NEXT: 0x30028 R_AARCH64_JUMP_SLOT _dah
5253#DSOREL-NEXT: }
5354#DSOREL-NEXT:]
5455
5556#DSO: Disassembly of section .text:
57#DSO-EMPTY:
5658#DSO-NEXT: _foo:
5759#DSO-NEXT: 10000: {{.*}} nop
5860#DSO-NEXT: 10004: {{.*}} nop
......@@ -69,10 +71,12 @@
6971#DSO-NEXT: 10024: {{.*}} b.eq #44
7072#DSO-NEXT: 10028: {{.*}} b.eq #56
7173#DSO-NEXT: 1002c: {{.*}} b.eq #68
74#DSO-EMPTY:
7275#DSO-NEXT: Disassembly of section .plt:
76#DSO-EMPTY:
7377#DSO-NEXT: .plt:
7478#DSO-NEXT: 10030: {{.*}} stp x16, x30, [sp, #-16]!
75#DSO-NEXT: 10034: {{.*}} adrp x16, #65536
79#DSO-NEXT: 10034: {{.*}} adrp x16, #131072
7680#DSO-NEXT: 10038: {{.*}} ldr x17, [x16, #16]
7781#DSO-NEXT: 1003c: {{.*}} add x16, x16, #16
7882#DSO-NEXT: 10040: {{.*}} br x17
......@@ -81,19 +85,19 @@
8185#DSO-NEXT: 1004c: {{.*}} nop
8286#DSO-EMPTY:
8387#DSO-NEXT: _foo@plt:
84#DSO-NEXT: 10050: {{.*}} adrp x16, #65536
88#DSO-NEXT: 10050: {{.*}} adrp x16, #131072
8589#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]
8690#DSO-NEXT: 10058: {{.*}} add x16, x16, #24
8791#DSO-NEXT: 1005c: {{.*}} br x17
8892#DSO-EMPTY:
8993#DSO-NEXT: _bar@plt:
90#DSO-NEXT: 10060: {{.*}} adrp x16, #65536
94#DSO-NEXT: 10060: {{.*}} adrp x16, #131072
9195#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]
9296#DSO-NEXT: 10068: {{.*}} add x16, x16, #32
9397#DSO-NEXT: 1006c: {{.*}} br x17
9498#DSO-EMPTY:
9599#DSO-NEXT: _dah@plt:
96#DSO-NEXT: 10070: {{.*}} adrp x16, #65536
100#DSO-NEXT: 10070: {{.*}} adrp x16, #131072
97101#DSO-NEXT: 10074: {{.*}} ldr x17, [x16, #40]
98102#DSO-NEXT: 10078: {{.*}} add x16, x16, #40
99103#DSO-NEXT: 1007c: {{.*}} br x17
deps/lld/test/ELF/aarch64-copy.s+3-2
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/relocation-copy.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -soname fixed-length-string.so -o %t2.so
55// RUN: ld.lld %t.o %t2.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
6// RUN: llvm-readobj -S -r --expand-relocs --symbols %t3 | FileCheck %s
77// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
88// RUN: llvm-objdump -s -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s
99
......@@ -77,6 +77,7 @@ _start:
7777// CHECK: ]
7878
7979// CODE: Disassembly of section .text:
80// CODE-EMPTY:
8081// CODE-NEXT: _start:
8182// S(x) = 0x230000, A = 0, P = 0x210000
8283// S + A - P = 0x20000 = 131072
......@@ -90,4 +91,4 @@ _start:
9091
9192// RODATA: Contents of section .rodata:
9293// S(z) = 0x230014
93// RODATA-NEXT: 2002e0 14002300
94// RODATA-NEXT: 200318 14002300
deps/lld/test/ELF/aarch64-copy2.s deleted-27
......@@ -1,27 +0,0 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
3// RUN: llvm-mc %p/Inputs/aarch64-copy2.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: ld.lld %t.o %t2.so -o %t
6// RUN: llvm-readobj -t %t | FileCheck %s
7
8 .global _start
9_start:
10 adrp x8, foo
11 bl bar
12
13// CHECK: Name: bar
14// CHECK-NEXT: Value: 0x0
15// CHECK-NEXT: Size: 0
16// CHECK-NEXT: Binding: Global
17// CHECK-NEXT: Type: None
18// CHECK-NEXT: Other: 0
19// CHECK-NEXT: Section: Undefined
20
21// CHECK: Name: foo
22// CHECK-NEXT: Value: 0x210030
23// CHECK-NEXT: Size: 0
24// CHECK-NEXT: Binding: Global
25// CHECK-NEXT: Type: Function
26// CHECK-NEXT: Other: 0
27// CHECK-NEXT: Section: Undefined
deps/lld/test/ELF/aarch64-cortex-a53-843419-large.s+3-3
......@@ -42,7 +42,7 @@ t3_ff8_ldr:
4242 ret
4343
4444// CHECK3: t3_ff8_ldr:
45// CHECK3-NEXT: 211ff8: 60 00 04 f0 adrp x0, #134279168
45// CHECK3-NEXT: 211ff8: e0 00 04 f0 adrp x0, #134344704
4646// CHECK3-NEXT: 211ffc: 21 00 40 f9 ldr x1, [x1]
4747// CHECK3-NEXT: 212000: 02 08 80 15 b #100671496
4848// CHECK3-NEXT: 212004: c0 03 5f d6 ret
......@@ -63,7 +63,7 @@ t3_ff8_str:
6363 ret
6464
6565// CHECK4: t3_ff8_str:
66// CHECK4-NEXT: 4213ff8: 60 00 02 b0 adrp x0, #67162112
66// CHECK4-NEXT: 4213ff8: e0 00 02 b0 adrp x0, #67227648
6767// CHECK4-NEXT: 4213ffc: 21 00 40 f9 ldr x1, [x1]
6868// CHECK4-NEXT: 4214000: 04 00 80 14 b #33554448
6969// CHECK4-NEXT: 4214004: c0 03 5f d6 ret
......@@ -102,7 +102,7 @@ t3_ffc_ldr:
102102 ret
103103
104104// CHECK7: t3_ffc_ldr:
105// CHECK7-NEXT: 8211ffc: 60 00 00 f0 adrp x0, #61440
105// CHECK7-NEXT: 8211ffc: e0 00 00 f0 adrp x0, #126976
106106// CHECK7-NEXT: 8212000: 21 00 40 f9 ldr x1, [x1]
107107// CHECK7-NEXT: 8212004: 02 00 00 14 b #8
108108// CHECK7-NEXT: 8212008: c0 03 5f d6 ret
deps/lld/test/ELF/aarch64-cortex-a53-843419-recognize.s+26-26
......@@ -28,7 +28,7 @@
2828
2929// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 211FF8 in unpatched output.
3030// CHECK: t3_ff8_ldr:
31// CHECK-NEXT: 211ff8: e0 01 00 f0 adrp x0, #258048
31// CHECK-NEXT: 211ff8: 60 02 00 f0 adrp x0, #323584
3232// CHECK-NEXT: 211ffc: 21 00 40 f9 ldr x1, [x1]
3333// CHECK-FIX: 212000: 03 c8 00 14 b #204812
3434// CHECK-NOFIX: 212000: 00 00 40 f9 ldr x0, [x0]
......@@ -46,7 +46,7 @@ t3_ff8_ldr:
4646
4747// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 213FF8 in unpatched output.
4848// CHECK: t3_ff8_ldrsimd:
49// CHECK-NEXT: 213ff8: e0 01 00 b0 adrp x0, #249856
49// CHECK-NEXT: 213ff8: 60 02 00 b0 adrp x0, #315392
5050// CHECK-NEXT: 213ffc: 21 00 40 bd ldr s1, [x1]
5151// CHECK-FIX: 214000: 05 c0 00 14 b #196628
5252// CHECK-NOFIX: 214000: 02 04 40 f9 ldr x2, [x0, #8]
......@@ -64,7 +64,7 @@ t3_ff8_ldrsimd:
6464
6565// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 215FFC in unpatched output.
6666// CHECK: t3_ffc_ldrpost:
67// CHECK-NEXT: 215ffc: c0 01 00 f0 adrp x0, #241664
67// CHECK-NEXT: 215ffc: 40 02 00 f0 adrp x0, #307200
6868// CHECK-NEXT: 216000: 21 84 40 bc ldr s1, [x1], #8
6969// CHECK-FIX: 216004: 06 b8 00 14 b #188440
7070// CHECK-NOFIX: 216004: 03 08 40 f9 ldr x3, [x0, #16]
......@@ -82,7 +82,7 @@ t3_ffc_ldrpost:
8282
8383// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 217FF8 in unpatched output.
8484// CHECK: t3_ff8_strpre:
85// CHECK-NEXT: 217ff8: c0 01 00 b0 adrp x0, #233472
85// CHECK-NEXT: 217ff8: 40 02 00 b0 adrp x0, #299008
8686// CHECK-NEXT: 217ffc: 21 8c 00 bc str s1, [x1, #8]!
8787// CHECK-FIX: 218000: 09 b0 00 14 b #180260
8888// CHECK-NOFIX: 218000: 02 00 40 f9 ldr x2, [x0]
......@@ -100,7 +100,7 @@ t3_ff8_strpre:
100100
101101// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 219FFC in unpatched output.
102102// CHECK: t3_ffc_str:
103// CHECK-NEXT: 219ffc: bc 01 00 f0 adrp x28, #225280
103// CHECK-NEXT: 219ffc: 3c 02 00 f0 adrp x28, #290816
104104// CHECK-NEXT: 21a000: 42 00 00 f9 str x2, [x2]
105105// CHECK-FIX: 21a004: 0a a8 00 14 b #172072
106106// CHECK-NOFIX: 21a004: 9c 07 00 f9 str x28, [x28, #8]
......@@ -118,7 +118,7 @@ t3_ffc_str:
118118
119119// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21BFFC in unpatched output.
120120// CHECK: t3_ffc_strsimd:
121// CHECK-NEXT: 21bffc: bc 01 00 b0 adrp x28, #217088
121// CHECK-NEXT: 21bffc: 3c 02 00 b0 adrp x28, #282624
122122// CHECK-NEXT: 21c000: 44 00 00 b9 str w4, [x2]
123123// CHECK-FIX: 21c004: 0c a0 00 14 b #163888
124124// CHECK-NOFIX: 21c004: 84 0b 00 f9 str x4, [x28, #16]
......@@ -136,7 +136,7 @@ t3_ffc_strsimd:
136136
137137// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21DFF8 in unpatched output.
138138// CHECK: t3_ff8_ldrunpriv:
139// CHECK-NEXT: 21dff8: 9d 01 00 f0 adrp x29, #208896
139// CHECK-NEXT: 21dff8: 1d 02 00 f0 adrp x29, #274432
140140// CHECK-NEXT: 21dffc: 41 08 40 38 ldtrb w1, [x2]
141141// CHECK-FIX: 21e000: 0f 98 00 14 b #155708
142142// CHECK-NOFIX: 21e000: bd 03 40 f9 ldr x29, [x29]
......@@ -154,7 +154,7 @@ t3_ff8_ldrunpriv:
154154
155155// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21FFFC in unpatched output.
156156// CHECK: t3_ffc_ldur:
157// CHECK-NEXT: 21fffc: 9d 01 00 b0 adrp x29, #200704
157// CHECK-NEXT: 21fffc: 1d 02 00 b0 adrp x29, #266240
158158// CHECK-NEXT: 220000: 42 40 40 b8 ldur w2, [x2, #4]
159159// CHECK-FIX: 220004: 10 90 00 14 b #147520
160160// CHECK-NOFIX: 220004: bd 07 40 f9 ldr x29, [x29, #8]
......@@ -171,7 +171,7 @@ t3_ffc_ldur:
171171
172172// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 221FFC in unpatched output.
173173// CHECK: t3_ffc_sturh:
174// CHECK-NEXT: 221ffc: 72 01 00 f0 adrp x18, #192512
174// CHECK-NEXT: 221ffc: f2 01 00 f0 adrp x18, #258048
175175// CHECK-NEXT: 222000: 43 40 00 78 sturh w3, [x2, #4]
176176// CHECK-FIX: 222004: 12 88 00 14 b #139336
177177// CHECK-NOFIX: 222004: 41 0a 40 f9 ldr x1, [x18, #16]
......@@ -189,7 +189,7 @@ t3_ffc_sturh:
189189
190190// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 223FF8 in unpatched output.
191191// CHECK: t3_ff8_literal:
192// CHECK-NEXT: 223ff8: 72 01 00 b0 adrp x18, #184320
192// CHECK-NEXT: 223ff8: f2 01 00 b0 adrp x18, #249856
193193// CHECK-NEXT: 223ffc: e3 ff ff 58 ldr x3, #-4
194194// CHECK-FIX: 224000: 15 80 00 14 b #131156
195195// CHECK-NOFIX: 224000: 52 02 40 f9 ldr x18, [x18]
......@@ -207,7 +207,7 @@ t3_ff8_literal:
207207
208208// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 225FFC in unpatched output.
209209// CHECK: t3_ffc_register:
210// CHECK-NEXT: 225ffc: 4f 01 00 f0 adrp x15, #176128
210// CHECK-NEXT: 225ffc: cf 01 00 f0 adrp x15, #241664
211211// CHECK-NEXT: 226000: 43 68 61 f8 ldr x3, [x2, x1]
212212// CHECK-FIX: 226004: 16 78 00 14 b #122968
213213// CHECK-NOFIX: 226004: ea 05 40 f9 ldr x10, [x15, #8]
......@@ -225,7 +225,7 @@ t3_ffc_register:
225225
226226// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 227FF8 in unpatched output.
227227// CHECK: t3_ff8_stp:
228// CHECK-NEXT: 227ff8: 50 01 00 b0 adrp x16, #167936
228// CHECK-NEXT: 227ff8: d0 01 00 b0 adrp x16, #233472
229229// CHECK-NEXT: 227ffc: 61 08 00 a9 stp x1, x2, [x3]
230230// CHECK-FIX: 228000: 19 70 00 14 b #114788
231231// CHECK-NOFIX: 228000: 0d 0a 40 f9 ldr x13, [x16, #16]
......@@ -243,7 +243,7 @@ t3_ff8_stp:
243243
244244// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 229FFC in unpatched output.
245245// CHECK: t3_ffc_stnp:
246// CHECK-NEXT: 229ffc: 27 01 00 f0 adrp x7, #159744
246// CHECK-NEXT: 229ffc: a7 01 00 f0 adrp x7, #225280
247247// CHECK-NEXT: 22a000: 61 08 00 a8 stnp x1, x2, [x3]
248248// CHECK-FIX: 22a004: 1a 68 00 14 b #106600
249249// CHECK-NOFIX: 22a004: e9 00 40 f9 ldr x9, [x7]
......@@ -261,7 +261,7 @@ t3_ffc_stnp:
261261
262262// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22BFFC in unpatched output.
263263// CHECK: t3_ffc_st1singlepost:
264// CHECK-NEXT: 22bffc: 37 01 00 b0 adrp x23, #151552
264// CHECK-NEXT: 22bffc: b7 01 00 b0 adrp x23, #217088
265265// CHECK-NEXT: 22c000: 20 04 82 0d st1 { v0.b }[1], [x1], x2
266266// CHECK-FIX: 22c004: 1c 60 00 14 b #98416
267267// CHECK-NOFIX: 22c004: f6 06 40 f9 ldr x22, [x23, #8]
......@@ -279,7 +279,7 @@ t3_ffc_st1singlepost:
279279
280280// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22DFF8 in unpatched output.
281281// CHECK: t3_ff8_st1multiple:
282// CHECK-NEXT: 22dff8: 17 01 00 f0 adrp x23, #143360
282// CHECK-NEXT: 22dff8: 97 01 00 f0 adrp x23, #208896
283283// CHECK-NEXT: 22dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1]
284284// CHECK-FIX: 22e000: 1f 58 00 14 b #90236
285285// CHECK-NOFIX: 22e000: f8 0a 40 f9 ldr x24, [x23, #16]
......@@ -297,7 +297,7 @@ t3_ff8_st1multiple:
297297
298298// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 22FFF8 in unpatched output.
299299// CHECK: t4_ff8_ldr:
300// CHECK-NEXT: 22fff8: 00 01 00 b0 adrp x0, #135168
300// CHECK-NEXT: 22fff8: 80 01 00 b0 adrp x0, #200704
301301// CHECK-NEXT: 22fffc: 21 00 40 f9 ldr x1, [x1]
302302// CHECK-NEXT: 230000: 42 00 00 8b add x2, x2, x0
303303// CHECK-FIX: 230004: 20 50 00 14 b #82048
......@@ -317,7 +317,7 @@ t4_ff8_ldr:
317317
318318// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 231FFC in unpatched output.
319319// CHECK: t4_ffc_str:
320// CHECK-NEXT: 231ffc: fc 00 00 f0 adrp x28, #126976
320// CHECK-NEXT: 231ffc: 7c 01 00 f0 adrp x28, #192512
321321// CHECK-NEXT: 232000: 42 00 00 f9 str x2, [x2]
322322// CHECK-NEXT: 232004: 20 00 02 cb sub x0, x1, x2
323323// CHECK-FIX: 232008: 21 48 00 14 b #73860
......@@ -337,7 +337,7 @@ t4_ffc_str:
337337
338338// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 233FF8 in unpatched output.
339339// CHECK: t4_ff8_stp:
340// CHECK-NEXT: 233ff8: f0 00 00 b0 adrp x16, #118784
340// CHECK-NEXT: 233ff8: 70 01 00 b0 adrp x16, #184320
341341// CHECK-NEXT: 233ffc: 61 08 00 a9 stp x1, x2, [x3]
342342// CHECK-NEXT: 234000: 03 7e 10 9b mul x3, x16, x16
343343// CHECK-FIX: 234004: 24 40 00 14 b #65680
......@@ -357,7 +357,7 @@ t4_ff8_stp:
357357
358358// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 235FF8 in unpatched output.
359359// CHECK: t4_ff8_stppre:
360// CHECK-NEXT: 235ff8: d0 00 00 f0 adrp x16, #110592
360// CHECK-NEXT: 235ff8: 50 01 00 f0 adrp x16, #176128
361361// CHECK-NEXT: 235ffc: 61 08 81 a9 stp x1, x2, [x3, #16]!
362362// CHECK-NEXT: 236000: 03 7e 10 9b mul x3, x16, x16
363363// CHECK-FIX: 236004: 26 38 00 14 b #57496
......@@ -377,7 +377,7 @@ t4_ff8_stppre:
377377
378378// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 237FF8 in unpatched output.
379379// CHECK: t4_ff8_stppost:
380// CHECK-NEXT: 237ff8: d0 00 00 b0 adrp x16, #102400
380// CHECK-NEXT: 237ff8: 50 01 00 b0 adrp x16, #167936
381381// CHECK-NEXT: 237ffc: 61 08 81 a8 stp x1, x2, [x3], #16
382382// CHECK-NEXT: 238000: 03 7e 10 9b mul x3, x16, x16
383383// CHECK-FIX: 238004: 28 30 00 14 b #49312
......@@ -397,7 +397,7 @@ t4_ff8_stppost:
397397
398398// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 239FFC in unpatched output.
399399// CHECK: t4_ffc_stpsimd:
400// CHECK-NEXT: 239ffc: b0 00 00 f0 adrp x16, #94208
400// CHECK-NEXT: 239ffc: 30 01 00 f0 adrp x16, #159744
401401// CHECK-NEXT: 23a000: 61 08 00 ad stp q1, q2, [x3]
402402// CHECK-NEXT: 23a004: 03 7e 10 9b mul x3, x16, x16
403403// CHECK-FIX: 23a008: 29 28 00 14 b #41124
......@@ -417,7 +417,7 @@ t4_ffc_stpsimd:
417417
418418// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23BFFC in unpatched output.
419419// CHECK: t4_ffc_stnp:
420// CHECK-NEXT: 23bffc: a7 00 00 b0 adrp x7, #86016
420// CHECK-NEXT: 23bffc: 27 01 00 b0 adrp x7, #151552
421421// CHECK-NEXT: 23c000: 61 08 00 a8 stnp x1, x2, [x3]
422422// CHECK-NEXT: 23c004: 1f 20 03 d5 nop
423423// CHECK-FIX: 23c008: 2b 20 00 14 b #32940
......@@ -437,7 +437,7 @@ t4_ffc_stnp:
437437
438438// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23DFFC in unpatched output.
439439// CHECK: t4_ffc_st1:
440// CHECK-NEXT: 23dffc: 98 00 00 f0 adrp x24, #77824
440// CHECK-NEXT: 23dffc: 18 01 00 f0 adrp x24, #143360
441441// CHECK-NEXT: 23e000: 20 80 00 4d st1 { v0.s }[2], [x1]
442442// CHECK-NEXT: 23e004: f6 06 40 f9 ldr x22, [x23, #8]
443443// CHECK-FIX: 23e008: 2d 18 00 14 b #24756
......@@ -457,7 +457,7 @@ t4_ffc_st1:
457457
458458// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23FFF8 in unpatched output.
459459// CHECK: t3_ff8_ldr_once:
460// CHECK-NEXT: 23fff8: 80 00 00 b0 adrp x0, #69632
460// CHECK-NEXT: 23fff8: 00 01 00 b0 adrp x0, #135168
461461// CHECK-NEXT: 23fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2
462462// CHECK-FIX: 240000: 31 10 00 14 b #16580
463463// CHECK-NOFIX: 240000: 01 08 40 f9 ldr x1, [x0, #16]
......@@ -477,7 +477,7 @@ t3_ff8_ldr_once:
477477
478478// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 241FF8 in unpatched output.
479479// CHECK: t3_ff8_ldxr:
480// CHECK-NEXT: 241ff8: 60 00 00 f0 adrp x0, #61440
480// CHECK-NEXT: 241ff8: e0 00 00 f0 adrp x0, #126976
481481// CHECK-NEXT: 241ffc: 03 7c 5f c8 ldxr x3, [x0]
482482// CHECK-FIX: 242000: 33 08 00 14 b #8396
483483// CHECK-NOFIX: 242000: 01 08 40 f9 ldr x1, [x0, #16]
......@@ -497,7 +497,7 @@ t3_ff8_ldxr:
497497
498498// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 243FF8 in unpatched output.
499499// CHECK: t3_ff8_stxr:
500// CHECK-NEXT: 243ff8: 60 00 00 b0 adrp x0, #53248
500// CHECK-NEXT: 243ff8: e0 00 00 b0 adrp x0, #118784
501501// CHECK-NEXT: 243ffc: 03 7c 04 c8 stxr w4, x3, [x0]
502502// CHECK-FIX: 244000: 35 00 00 14 b #212
503503// CHECK-NOFIX: 244000: 01 08 40 f9 ldr x1, [x0, #16]
deps/lld/test/ELF/aarch64-cortex-a53-843419-thunk.s+1-1
......@@ -44,7 +44,7 @@ t3_ff8_ldr:
4444// CHECK-NEXT: 11004: 02 00 00 14 b #8
4545// CHECK-NEXT: 11008: c0 03 5f d6 ret
4646// CHECK: __CortexA53843419_11004:
47// CHECK-NEXT: 1100c: 00 08 40 f9 ldr x0, [x0, #16]
47// CHECK-NEXT: 1100c: 00 04 40 f9 ldr x0, [x0, #8]
4848// CHECK-NEXT: 11010: fe ff ff 17 b #-8
4949
5050 .section .text.04, "ax", %progbits
deps/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s+2-2
......@@ -26,9 +26,9 @@ _start:
2626// CHECK: _start:
2727// CHECK-NEXT: 210ff8: 41 d0 3b d5 mrs x1, TPIDR_EL0
2828// CHECK-NEXT: 210ffc: 00 00 a0 d2 movz x0, #0, lsl #16
29// CHECK-NEXT: 211000: 01 08 80 f2 movk x1, #64
29// CHECK-NEXT: 211000: 01 02 80 f2 movk x1, #16
3030// CHECK-NEXT: 211004: 00 00 a0 d2 movz x0, #0, lsl #16
31// CHECK-NEXT: 211008: 01 08 80 f2 movk x1, #64
31// CHECK-NEXT: 211008: 01 02 80 f2 movk x1, #16
3232// CHECK-NEXT: 21100c: c0 03 5f d6 ret
3333
3434 .type v,@object
deps/lld/test/ELF/aarch64-feature-bti.s created+218
......@@ -0,0 +1,218 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-bti1.s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3.s -o %t2.o
5# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3-bti.s -o %t3.o
6# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func2.s -o %tno.o
7
8## We do not add BTI support when the inputs don't have the .note.gnu.property
9## field.
10
11# RUN: ld.lld %tno.o %t3.o --shared -o %tno.so
12# RUN: llvm-objdump -d -mattr=+bti --no-show-raw-insn %tno.so | FileCheck --check-prefix=NOBTI %s
13# RUN: llvm-readelf -x .got.plt %tno.so | FileCheck --check-prefix SOGOTPLT %s
14# RUN: llvm-readelf --dynamic-table %tno.so | FileCheck --check-prefix NOBTIDYN %s
15
16# NOBTIDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT)
17# NOBTIDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT)
18
19# NOBTI: 0000000000010000 func2:
20# NOBTI-NEXT: 10000: bl #48 <func3@plt>
21# NOBTI-NEXT: 10004: ret
22# NOBTI: Disassembly of section .plt:
23# NOBTI: 0000000000010010 .plt:
24# NOBTI-NEXT: 10010: stp x16, x30, [sp, #-16]!
25# NOBTI-NEXT: 10014: adrp x16, #131072
26# NOBTI-NEXT: 10018: ldr x17, [x16, #16]
27# NOBTI-NEXT: 1001c: add x16, x16, #16
28# NOBTI-NEXT: 10020: br x17
29# NOBTI-NEXT: 10024: nop
30# NOBTI-NEXT: 10028: nop
31# NOBTI-NEXT: 1002c: nop
32# NOBTI: 0000000000010030 func3@plt:
33# NOBTI-NEXT: 10030: adrp x16, #131072
34# NOBTI-NEXT: 10034: ldr x17, [x16, #24]
35# NOBTI-NEXT: 10038: add x16, x16, #24
36# NOBTI-NEXT: 1003c: br x17
37
38## Expect a bti c at the start of plt[0], the plt entries do not need bti c as
39## their address doesn't escape the shared object, so they can't be indirectly
40## called. Expect no other difference.
41
42# RUN: ld.lld %t1.o %t3.o --shared -o %t.so
43# RUN: llvm-readelf -n %t.so | FileCheck --check-prefix BTIPROP %s
44# RUN: llvm-objdump -d -mattr=+bti --no-show-raw-insn %t.so | FileCheck --check-prefix BTISO %s
45# RUN: llvm-readelf -x .got.plt %t.so | FileCheck --check-prefix SOGOTPLT %s
46# RUN: llvm-readelf --dynamic-table %t.so | FileCheck --check-prefix BTIDYN %s
47
48# BTIPROP: Properties: aarch64 feature: BTI
49
50# BTIDYN: 0x0000000070000001 (AARCH64_BTI_PLT)
51# BTIDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT)
52
53# BTISO: 0000000000010000 func2:
54# BTISO-NEXT: 10000: bl #48 <func3@plt>
55# BTISO-NEXT: 10004: ret
56# BTISO: Disassembly of section .plt:
57# BTISO: 0000000000010010 .plt:
58# BTISO-NEXT: 10010: bti c
59# BTISO-NEXT: 10014: stp x16, x30, [sp, #-16]!
60# BTISO-NEXT: 10018: adrp x16, #131072
61# BTISO-NEXT: 1001c: ldr x17, [x16, #16]
62# BTISO-NEXT: 10020: add x16, x16, #16
63# BTISO-NEXT: 10024: br x17
64# BTISO-NEXT: 10028: nop
65# BTISO-NEXT: 1002c: nop
66# BTISO: 0000000000010030 func3@plt:
67# BTISO-NEXT: 10030: adrp x16, #131072
68# BTISO-NEXT: 10034: ldr x17, [x16, #24]
69# BTISO-NEXT: 10038: add x16, x16, #24
70# BTISO-NEXT: 1003c: br x17
71
72## The .got.plt should be identical between the BTI and no BTI DSO PLT.
73# SOGOTPLT: Hex dump of section '.got.plt'
74# SOGOTPLT-NEXT: 0x00030000 00000000 00000000 00000000 00000000
75# SOGOTPLT-NEXT: 0x00030010 00000000 00000000 10000100 00000000
76
77## Build an executable with all relocatable inputs having the BTI
78## .note.gnu.property. We expect a bti c in front of all PLT entries as the
79## address of a PLT entry can escape an executable.
80
81# RUN: ld.lld %t2.o --shared -o %t2.so
82
83# RUN: ld.lld %t.o %t.so %t2.so -o %t.exe
84# RUN: llvm-readelf --dynamic-table -n %t.exe | FileCheck --check-prefix=BTIPROP %s
85# RUN: llvm-objdump -d -mattr=+bti --no-show-raw-insn %t.exe | FileCheck --check-prefix=EXECBTI %s
86
87# EXECBTI: Disassembly of section .text:
88# EXECBTI: 0000000000210000 func1:
89# EXECBTI-NEXT: 210000: bl #48 <func2@plt>
90# EXECBTI-NEXT: 210004: ret
91# EXECBTI: Disassembly of section .plt:
92# EXECBTI: 0000000000210010 .plt:
93# EXECBTI-NEXT: 210010: bti c
94# EXECBTI-NEXT: 210014: stp x16, x30, [sp, #-16]!
95# EXECBTI-NEXT: 210018: adrp x16, #131072
96# EXECBTI-NEXT: 21001c: ldr x17, [x16, #16]
97# EXECBTI-NEXT: 210020: add x16, x16, #16
98# EXECBTI-NEXT: 210024: br x17
99# EXECBTI-NEXT: 210028: nop
100# EXECBTI-NEXT: 21002c: nop
101# EXECBTI: 0000000000210030 func2@plt:
102# EXECBTI-NEXT: 210030: bti c
103# EXECBTI-NEXT: 210034: adrp x16, #131072
104# EXECBTI-NEXT: 210038: ldr x17, [x16, #24]
105# EXECBTI-NEXT: 21003c: add x16, x16, #24
106# EXECBTI-NEXT: 210040: br x17
107# EXECBTI-NEXT: 210044: nop
108
109## We expect the same for PIE, as the address of an ifunc can escape
110# RUN: ld.lld --pie %t.o %t.so %t2.so -o %tpie.exe
111# RUN: llvm-readelf -n %tpie.exe | FileCheck --check-prefix=BTIPROP %s
112# RUN: llvm-readelf --dynamic-table -n %tpie.exe | FileCheck --check-prefix=BTIPROP %s
113# RUN: llvm-objdump -d -mattr=+bti --no-show-raw-insn %tpie.exe | FileCheck --check-prefix=PIE %s
114
115# PIE: Disassembly of section .text:
116# PIE: 0000000000010000 func1:
117# PIE-NEXT: 10000: bl #48 <func2@plt>
118# PIE-NEXT: 10004: ret
119# PIE: Disassembly of section .plt:
120# PIE: 0000000000010010 .plt:
121# PIE-NEXT: 10010: bti c
122# PIE-NEXT: 10014: stp x16, x30, [sp, #-16]!
123# PIE-NEXT: 10018: adrp x16, #131072
124# PIE-NEXT: 1001c: ldr x17, [x16, #16]
125# PIE-NEXT: 10020: add x16, x16, #16
126# PIE-NEXT: 10024: br x17
127# PIE-NEXT: 10028: nop
128# PIE-NEXT: 1002c: nop
129# PIE: 0000000000010030 func2@plt:
130# PIE-NEXT: 10030: bti c
131# PIE-NEXT: 10034: adrp x16, #131072
132# PIE-NEXT: 10038: ldr x17, [x16, #24]
133# PIE-NEXT: 1003c: add x16, x16, #24
134# PIE-NEXT: 10040: br x17
135# PIE-NEXT: 10044: nop
136
137## Build and executable with not all relocatable inputs having the BTI
138## .note.property, expect no bti c and no .note.gnu.property entry
139
140# RUN: ld.lld %t.o %t2.o %t.so -o %tnobti.exe
141# RUN: llvm-readelf --dynamic-table %tnobti.exe | FileCheck --check-prefix NOBTIDYN %s
142# RUN: llvm-objdump -d -mattr=+bti --no-show-raw-insn %tnobti.exe | FileCheck --check-prefix=NOEX %s
143
144# NOEX: Disassembly of section .text:
145# NOEX: 0000000000210000 func1:
146# NOEX-NEXT: 210000: bl #48 <func2@plt>
147# NOEX-NEXT: 210004: ret
148# NOEX: 0000000000210008 func3:
149# NOEX-NEXT: 210008: ret
150# NOEX: Disassembly of section .plt:
151# NOEX: 0000000000210010 .plt:
152# NOEX-NEXT: 210010: stp x16, x30, [sp, #-16]!
153# NOEX-NEXT: 210014: adrp x16, #131072
154# NOEX-NEXT: 210018: ldr x17, [x16, #16]
155# NOEX-NEXT: 21001c: add x16, x16, #16
156# NOEX-NEXT: 210020: br x17
157# NOEX-NEXT: 210024: nop
158# NOEX-NEXT: 210028: nop
159# NOEX-NEXT: 21002c: nop
160# NOEX: 0000000000210030 func2@plt:
161# NOEX-NEXT: 210030: adrp x16, #131072
162# NOEX-NEXT: 210034: ldr x17, [x16, #24]
163# NOEX-NEXT: 210038: add x16, x16, #24
164# NOEX-NEXT: 21003c: br x17
165
166## Force BTI entries with the --force-bti command line option. Expect a warning
167## from the file without the .note.gnu.property.
168
169# RUN: ld.lld %t.o %t2.o --force-bti %t.so -o %tforcebti.exe 2>&1 | FileCheck --check-prefix=FORCE-WARN %s
170
171# FORCE-WARN: aarch64-feature-bti.s.tmp2.o: --force-bti: file does not have BTI property
172
173
174# RUN: llvm-readelf -n %tforcebti.exe | FileCheck --check-prefix=BTIPROP %s
175# RUN: llvm-readelf --dynamic-table %tforcebti.exe | FileCheck --check-prefix BTIDYN %s
176# RUN: llvm-objdump -d -mattr=+bti --no-show-raw-insn %tforcebti.exe | FileCheck --check-prefix=FORCE %s
177
178# FORCE: Disassembly of section .text:
179# FORCE: 0000000000210000 func1:
180# FORCE-NEXT: 210000: bl #48 <func2@plt>
181# FORCE-NEXT: 210004: ret
182# FORCE: 0000000000210008 func3:
183# FORCE-NEXT: 210008: ret
184# FORCE: Disassembly of section .plt:
185# FORCE: 0000000000210010 .plt:
186# FORCE-NEXT: 210010: bti c
187# FORCE-NEXT: 210014: stp x16, x30, [sp, #-16]!
188# FORCE-NEXT: 210018: adrp x16, #131072
189# FORCE-NEXT: 21001c: ldr x17, [x16, #16]
190# FORCE-NEXT: 210020: add x16, x16, #16
191# FORCE-NEXT: 210024: br x17
192# FORCE-NEXT: 210028: nop
193# FORCE-NEXT: 21002c: nop
194# FORCE: 0000000000210030 func2@plt:
195# FORCE-NEXT: 210030: bti c
196# FORCE-NEXT: 210034: adrp x16, #131072
197# FORCE-NEXT: 210038: ldr x17, [x16, #24]
198# FORCE-NEXT: 21003c: add x16, x16, #24
199# FORCE-NEXT: 210040: br x17
200# FORCE-NEXT: 210044: nop
201
202.section ".note.gnu.property", "a"
203.long 4
204.long 0x10
205.long 0x5
206.asciz "GNU"
207
208.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
209.long 4
210.long 1 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI
211.long 0
212
213.text
214.globl _start
215.type func1,%function
216func1:
217 bl func2
218 ret
deps/lld/test/ELF/aarch64-feature-btipac.s created+142
......@@ -0,0 +1,142 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-btipac1.s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3.s -o %t3.o
5# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3-btipac.s -o %t3btipac.o
6
7## Build shared library with all inputs having BTI and PAC, expect PLT
8## entries supporting both PAC and BTI. For a shared library this means:
9## PLT[0] has bti c at start
10## PLT[n] has autia1716 before br x17
11
12# RUN: ld.lld %t1.o %t3btipac.o --shared -o %t.so
13# RUN: llvm-readelf -n %t.so | FileCheck --check-prefix BTIPACPROP %s
14# RUN: llvm-objdump -d -mattr=+v8.5a --no-show-raw-insn %t.so | FileCheck --check-prefix BTIPACSO %s
15# RUN: llvm-readelf --dynamic-table %t.so | FileCheck --check-prefix BTIPACDYN %s
16
17# BTIPACSO: Disassembly of section .text:
18# BTIPACSO: 0000000000010000 func2:
19# BTIPACSO-NEXT: 10000: bl #48 <func3@plt>
20# BTIPACSO-NEXT: 10004: ret
21# BTIPACSO: 0000000000010008 func3:
22# BTIPACSO-NEXT: 10008: ret
23# BTIPACSO: Disassembly of section .plt:
24# BTIPACSO: 0000000000010010 .plt:
25# BTIPACSO-NEXT: 10010: bti c
26# BTIPACSO-NEXT: 10014: stp x16, x30, [sp, #-16]!
27# BTIPACSO-NEXT: 10018: adrp x16, #131072
28# BTIPACSO-NEXT: 1001c: ldr x17, [x16, #16]
29# BTIPACSO-NEXT: 10020: add x16, x16, #16
30# BTIPACSO-NEXT: 10024: br x17
31# BTIPACSO-NEXT: 10028: nop
32# BTIPACSO-NEXT: 1002c: nop
33# BTIPACSO: 0000000000010030 func3@plt:
34# BTIPACSO-NEXT: 10030: adrp x16, #131072
35# BTIPACSO-NEXT: 10034: ldr x17, [x16, #24]
36# BTIPACSO-NEXT: 10038: add x16, x16, #24
37# BTIPACSO-NEXT: 1003c: autia1716
38# BTIPACSO-NEXT: 10040: br x17
39# BTIPACSO-NEXT: 10044: nop
40
41# BTIPACPROP: Properties: aarch64 feature: BTI, PAC
42
43# BTIPACDYN: 0x0000000070000001 (AARCH64_BTI_PLT)
44# BTIPACDYN: 0x0000000070000003 (AARCH64_PAC_PLT)
45
46## Make an executable with both BTI and PAC properties. Expect:
47## PLT[0] bti c as first instruction
48## PLT[n] bti n as first instruction, autia1716 before br x17
49
50# RUN: ld.lld %t.o %t3btipac.o %t.so -o %t.exe
51# RUN: llvm-readelf -n %t.exe | FileCheck --check-prefix=BTIPACPROP %s
52# RUN: llvm-objdump -d -mattr=+v8.5a --no-show-raw-insn %t.exe | FileCheck --check-prefix BTIPACEX %s
53# RUN: llvm-readelf --dynamic-table %t.exe | FileCheck --check-prefix BTIPACDYN %s
54
55# BTIPACEX: Disassembly of section .text:
56# BTIPACEX: 0000000000210000 func1:
57# BTIPACEX-NEXT: 210000: bl #48 <func2@plt>
58# BTIPACEX-NEXT: 210004: ret
59# BTIPACEX-NEXT: 210008: ret
60# BTIPACEX: 000000000021000c func3:
61# BTIPACEX-NEXT: 21000c: ret
62# BTIPACEX: Disassembly of section .plt:
63# BTIPACEX: 0000000000210010 .plt:
64# BTIPACEX-NEXT: 210010: bti c
65# BTIPACEX-NEXT: 210014: stp x16, x30, [sp, #-16]!
66# BTIPACEX-NEXT: 210018: adrp x16, #131072
67# BTIPACEX-NEXT: 21001c: ldr x17, [x16, #16]
68# BTIPACEX-NEXT: 210020: add x16, x16, #16
69# BTIPACEX-NEXT: 210024: br x17
70# BTIPACEX-NEXT: 210028: nop
71# BTIPACEX-NEXT: 21002c: nop
72# BTIPACEX: 0000000000210030 func2@plt:
73# BTIPACEX-NEXT: 210030: bti c
74# BTIPACEX-NEXT: 210034: adrp x16, #131072
75# BTIPACEX-NEXT: 210038: ldr x17, [x16, #24]
76# BTIPACEX-NEXT: 21003c: add x16, x16, #24
77# BTIPACEX-NEXT: 210040: autia1716
78# BTIPACEX-NEXT: 210044: br x17
79
80## Check that combinations of BTI+PAC with 0 properties results in standard PLT
81
82# RUN: ld.lld %t.o %t3.o %t.so -o %t.exe
83# RUN: llvm-objdump -d -mattr=+v8.5a --no-show-raw-insn %t.exe | FileCheck --check-prefix EX %s
84# RUN: llvm-readelf --dynamic-table %t.exe | FileCheck --check-prefix=NODYN %s
85
86# EX: Disassembly of section .text:
87# EX: 0000000000210000 func1:
88# EX-NEXT: 210000: bl #48 <func2@plt>
89# EX-NEXT: 210004: ret
90# EX-NEXT: 210008: ret
91# EX: 000000000021000c func3:
92# EX-NEXT: 21000c: ret
93# EX: Disassembly of section .plt:
94# EX: 0000000000210010 .plt:
95# EX-NEXT: 210010: stp x16, x30, [sp, #-16]!
96# EX-NEXT: 210014: adrp x16, #131072
97# EX-NEXT: 210018: ldr x17, [x16, #16]
98# EX-NEXT: 21001c: add x16, x16, #16
99# EX-NEXT: 210020: br x17
100# EX-NEXT: 210024: nop
101# EX-NEXT: 210028: nop
102# EX-NEXT: 21002c: nop
103# EX: 0000000000210030 func2@plt:
104# EX: 210030: adrp x16, #131072
105# EX-NEXT: 210034: ldr x17, [x16, #24]
106# EX-NEXT: 210038: add x16, x16, #24
107# EX-NEXT: 21003c: br x17
108
109# NODYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT)
110# NODYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT)
111
112## Check that combination of --pac-plt and --force-bti warns for the file that
113## doesn't contain the BTI property, but generates PAC and BTI PLT sequences.
114## The --pac-plt doesn't warn as it is not required for correctness.
115
116# RUN: ld.lld %t.o %t3.o %t.so --pac-plt --force-bti -o %t.exe 2>&1 | FileCheck --check-prefix=FORCE-WARN %s
117
118# FORCE-WARN: aarch64-feature-btipac.s.tmp3.o: --force-bti: file does not have BTI property
119
120# RUN: llvm-readelf -n %t.exe | FileCheck --check-prefix=BTIPACPROP %s
121# RUN: llvm-objdump -d -mattr=+v8.5a --no-show-raw-insn %t.exe | FileCheck --check-prefix BTIPACEX %s
122# RUN: llvm-readelf --dynamic-table %t.exe | FileCheck --check-prefix BTIPACDYN %s
123.section ".note.gnu.property", "a"
124.long 4
125.long 0x10
126.long 0x5
127.asciz "GNU"
128
129.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
130.long 4
131.long 3 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI and PAC
132.long 0
133
134.text
135.globl _start
136.type func1,%function
137func1:
138 bl func2
139 ret
140.globl func3
141.type func3,%function
142 ret
deps/lld/test/ELF/aarch64-feature-pac.s created+129
......@@ -0,0 +1,129 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-pac1.s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3.s -o %t2.o
5# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3-pac.s -o %t3.o
6# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func2.s -o %tno.o
7
8## We do not add PAC support when the inputs don't have the .note.gnu.property
9## field.
10
11# RUN: ld.lld %tno.o %t3.o --shared -o %tno.so
12# RUN: llvm-objdump -d -mattr=+v8.3a --no-show-raw-insn %tno.so | FileCheck --check-prefix=NOPAC %s
13# RUN: llvm-readelf -x .got.plt %tno.so | FileCheck --check-prefix SOGOTPLT %s
14# RUN: llvm-readelf --dynamic-table %tno.so | FileCheck --check-prefix NOPACDYN %s
15
16# NOPAC: 0000000000010000 func2:
17# NOPAC-NEXT: 10000: bl #48 <func3@plt>
18# NOPAC-NEXT: 10004: ret
19# NOPAC: Disassembly of section .plt:
20# NOPAC: 0000000000010010 .plt:
21# NOPAC-NEXT: 10010: stp x16, x30, [sp, #-16]!
22# NOPAC-NEXT: 10014: adrp x16, #131072
23# NOPAC-NEXT: 10018: ldr x17, [x16, #16]
24# NOPAC-NEXT: 1001c: add x16, x16, #16
25# NOPAC-NEXT: 10020: br x17
26# NOPAC-NEXT: 10024: nop
27# NOPAC-NEXT: 10028: nop
28# NOPAC-NEXT: 1002c: nop
29# NOPAC: 0000000000010030 func3@plt:
30# NOPAC-NEXT: 10030: adrp x16, #131072
31# NOPAC-NEXT: 10034: ldr x17, [x16, #24]
32# NOPAC-NEXT: 10038: add x16, x16, #24
33# NOPAC-NEXT: 1003c: br x17
34
35# NOPACDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT)
36# NOPACDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT)
37
38# RUN: ld.lld %t1.o %t3.o --shared -o %t.so
39# RUN: llvm-readelf -n %t.so | FileCheck --check-prefix PACPROP %s
40# RUN: llvm-objdump -d -mattr=+v8.3a --no-show-raw-insn %t.so | FileCheck --check-prefix PACSO %s
41# RUN: llvm-readelf -x .got.plt %t.so | FileCheck --check-prefix SOGOTPLT %s
42# RUN: llvm-readelf --dynamic-table %t.so | FileCheck --check-prefix PACDYN %s
43
44## PAC has no effect on PLT[0], for PLT[N] autia1716 is used to authenticate
45## the address in x17 (context in x16) before branching to it. The dynamic
46## loader is responsible for calling pacia1716 on the entry.
47# PACSO: 0000000000010000 func2:
48# PACSO-NEXT: 10000: bl #48 <func3@plt>
49# PACSO-NEXT: 10004: ret
50# PACSO: Disassembly of section .plt:
51# PACSO: 0000000000010010 .plt:
52# PACSO-NEXT: 10010: stp x16, x30, [sp, #-16]!
53# PACSO-NEXT: 10014: adrp x16, #131072
54# PACSO-NEXT: 10018: ldr x17, [x16, #16]
55# PACSO-NEXT: 1001c: add x16, x16, #16
56# PACSO-NEXT: 10020: br x17
57# PACSO-NEXT: 10024: nop
58# PACSO-NEXT: 10028: nop
59# PACSO-NEXT: 1002c: nop
60# PACSO: 0000000000010030 func3@plt:
61# PACSO-NEXT: 10030: adrp x16, #131072
62# PACSO-NEXT: 10034: ldr x17, [x16, #24]
63# PACSO-NEXT: 10038: add x16, x16, #24
64# PACSO-NEXT: 1003c: autia1716
65# PACSO-NEXT: 10040: br x17
66# PACSO-NEXT: 10044: nop
67
68# The .got.plt should be identical between the PAC and no PAC DSO PLT.
69# SOGOTPLT: Hex dump of section '.got.plt':
70# SOGOTPLT-NEXT: 0x00030000 00000000 00000000 00000000 00000000
71# SOGOTPLT-NEXT: 0x00030010 00000000 00000000 10000100 00000000
72
73# PACPROP: Properties: aarch64 feature: PAC
74
75# PACDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT)
76# PACDYN: 0x0000000070000003 (AARCH64_PAC_PLT)
77
78## Turn on PAC entries with the --pac-plt command line option. There are no
79## warnings in this case as the choice to use PAC in PLT entries is orthogonal
80## to the choice of using PAC in relocatable objects. The presence of the PAC
81## .note.gnu.property is an indication of preference by the relocatable object.
82
83# RUN: ld.lld %t.o %t2.o --pac-plt %t.so -o %tpacplt.exe
84# RUN: llvm-readelf -n %tpacplt.exe | FileCheck --check-prefix=PACPROP %s
85# RUN: llvm-readelf --dynamic-table %tpacplt.exe | FileCheck --check-prefix PACDYN %s
86# RUN: llvm-objdump -d -mattr=+v8.3a --no-show-raw-insn %tpacplt.exe | FileCheck --check-prefix PACPLT %s
87
88# PACPLT: Disassembly of section .text:
89# PACPLT: 0000000000210000 func1:
90# PACPLT-NEXT: 210000: bl #48 <func2@plt>
91# PACPLT-NEXT: 210004: ret
92# PACPLT: 0000000000210008 func3:
93# PACPLT-NEXT: 210008: ret
94# PACPLT: Disassembly of section .plt:
95# PACPLT: 0000000000210010 .plt:
96# PACPLT-NEXT: 210010: stp x16, x30, [sp, #-16]!
97# PACPLT-NEXT: 210014: adrp x16, #131072
98# PACPLT-NEXT: 210018: ldr x17, [x16, #16]
99# PACPLT-NEXT: 21001c: add x16, x16, #16
100# PACPLT-NEXT: 210020: br x17
101# PACPLT-NEXT: 210024: nop
102# PACPLT-NEXT: 210028: nop
103# PACPLT-NEXT: 21002c: nop
104# PACPLT: 0000000000210030 func2@plt:
105# PACPLT-NEXT: 210030: adrp x16, #131072
106# PACPLT-NEXT: 210034: ldr x17, [x16, #24]
107# PACPLT-NEXT: 210038: add x16, x16, #24
108# PACPLT-NEXT: 21003c: autia1716
109# PACPLT-NEXT: 210040: br x17
110# PACPLT-NEXT: 210044: nop
111
112
113.section ".note.gnu.property", "a"
114.long 4
115.long 0x10
116.long 0x5
117.asciz "GNU"
118
119.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
120.long 4
121.long 2 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC
122.long 0
123
124.text
125.globl _start
126.type func1,%function
127func1:
128 bl func2
129 ret
deps/lld/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s+2
......@@ -4,8 +4,10 @@
44// CHECK: relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used against symbol dat; recompile with -fPIC
55// CHECK: >>> defined in {{.*}}.o
66// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
7// CHECK: relocation R_AARCH64_ADR_PREL_PG_HI21_NC cannot be used against symbol dat; recompile with -fPIC
78
89 adrp x0, dat
10 adrp x0, :pg_hi21_nc:dat
911.data
1012.globl dat
1113dat:
deps/lld/test/ELF/aarch64-fpic-got.s+12-4
......@@ -3,14 +3,22 @@
33# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
44# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %p/Inputs/shared.s -o %t-lib.o
55# RUN: ld.lld -shared %t-lib.o -o %t-lib.so
6
67# RUN: ld.lld %t-lib.so %t.o -o %t.exe
7# RUN: llvm-readobj -dyn-relocations %t.exe | FileCheck %s
8# RUN: llvm-readobj -r %t.exe | FileCheck --check-prefix=RELOC %s
9# RUN: llvm-objdump -d --no-show-raw-insn %t.exe | FileCheck --check-prefix=DIS %s
810
911## Checks if got access to dynamic objects is done through a got relative
1012## dynamic relocation and not using plt relative (R_AARCH64_JUMP_SLOT).
11# CHECK: Dynamic Relocations {
12# CHECK-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_GLOB_DAT bar 0x0
13# CHECK-NEXT: }
13# RELOC: .rela.dyn {
14# RELOC-NEXT: 0x2200C0 R_AARCH64_GLOB_DAT bar 0x0
15# RELOC-NEXT: }
16
17## page(0x2200C0) - page(0x210000) = 65536
18## page(0x2200C0) & 0xff8 = 192
19# DIS: _start:
20# DIS-NEXT: 210000: adrp x0, #65536
21# DIS-NEXT: 210004: ldr x0, [x0, #192]
1422
1523.globl _start
1624_start:
deps/lld/test/ELF/aarch64-gnu-ifunc-address-pie.s deleted-44
......@@ -1,44 +0,0 @@
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+9-11
......@@ -1,7 +1,7 @@
11# REQUIRES: aarch64
22# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
33# RUN: ld.lld -shared %t.o -o %tout
4# RUN: llvm-objdump -D %tout | FileCheck %s
4# RUN: llvm-objdump -D --no-show-raw-insn %tout | FileCheck %s
55# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=CHECK-RELOCS
66
77# Test that when we take the address of a preemptible ifunc in a shared object
......@@ -21,20 +21,18 @@ main:
2121 ldr x8, [x8, :got_lo12:myfunc]
2222 ret
2323# 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
24# x8 = 0x20000
25# CHECK-NEXT: 10004: adrp x8, #65536
26# x8 = 0x200a0 = .got entry for myfunc with R_AARCH64_GLOB_DAT
27# CHECK-NEXT: 10008: ldr x8, [x8, #160]
28# CHECK-NEXT: 1000c: ret
2929
3030# CHECK: Disassembly of section .got:
31# CHECK-NEXT: 00000000000300e0 .got:
31# CHECK-EMPTY:
32# CHECK-NEXT: 00000000000200a0 .got:
3233
3334# CHECK-RELOCS: Relocations [
3435# 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
36# CHECK-RELOCS-NEXT: 0x200A0 R_AARCH64_GLOB_DAT myfunc 0x0
3937# CHECK-RELOCS-NEXT: }
4038# CHECK-RELOCS-NEXT: ]
deps/lld/test/ELF/aarch64-gnu-ifunc-nonpreemptable.s created+72
......@@ -0,0 +1,72 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
3
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PDE
6# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=PDE-RELOC
7
8# RUN: ld.lld -pie %t.o -o %t
9# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PIE
10# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=PIE-RELOC
11
12## When compiling with -fno-PIE or -fPIE, if the ifunc is in the same
13## translation unit as the address taker, the compiler knows that ifunc is not
14## defined in a shared library so it can use a non GOT generating relative reference.
15.text
16.globl myfunc
17.type myfunc,@gnu_indirect_function
18myfunc:
19.globl myfunc_resolver
20.type myfunc_resolver,@function
21myfunc_resolver:
22 ret
23
24.text
25.globl main
26.type main,@function
27main:
28 adrp x8, myfunc
29 add x8, x8, :lo12: myfunc
30 ret
31
32## The address of myfunc is the address of the PLT entry for myfunc.
33# PDE: myfunc_resolver:
34# PDE-NEXT: 210000: ret
35# PDE: main:
36# PDE-NEXT: 210004: adrp x8, #0
37# PDE-NEXT: 210008: add x8, x8, #16
38# PDE-NEXT: 21000c: ret
39# PDE-EMPTY:
40# PDE-NEXT: Disassembly of section .plt:
41# PDE-EMPTY:
42# PDE-NEXT: myfunc:
43## page(.got.plt) - page(0x210010) = 65536
44# PDE-NEXT: 210010: adrp x16, #65536
45# PDE-NEXT: 210014: ldr x17, [x16]
46# PDE-NEXT: 210018: add x16, x16, #0
47# PDE-NEXT: 21001c: br x17
48
49## The adrp to myfunc should generate a PLT entry and a GOT entry with an
50## irelative relocation.
51# PDE-RELOC: .rela.plt {
52# PDE-RELOC-NEXT: 0x220000 R_AARCH64_IRELATIVE - 0x210000
53# PDE-RELOC-NEXT: }
54
55# PIE: myfunc_resolver:
56# PIE-NEXT: 10000: ret
57# PIE: main:
58# PIE-NEXT: 10004: adrp x8, #0
59# PIE-NEXT: 10008: add x8, x8, #16
60# PIE-NEXT: 1000c: ret
61# PIE-EMPTY:
62# PIE-NEXT: Disassembly of section .plt:
63# PIE-EMPTY:
64# PIE-NEXT: myfunc:
65# PIE-NEXT: 10010: adrp x16, #131072
66# PIE-NEXT: 10014: ldr x17, [x16]
67# PIE-NEXT: 10018: add x16, x16, #0
68# PIE-NEXT: 1001c: br x17
69
70# PIE-RELOC: .rela.plt {
71# PIE-RELOC-NEXT: 0x30000 R_AARCH64_IRELATIVE - 0x10000
72# PIE-RELOC-NEXT: }
deps/lld/test/ELF/aarch64-gnu-ifunc-nosym.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: aarch64
22// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
33// RUN: ld.lld -static %t.o -o %tout
4// RUN: llvm-readobj -symbols %tout | FileCheck %s
4// RUN: llvm-readobj --symbols %tout | FileCheck %s
55
66// Check that no __rela_iplt_end/__rela_iplt_start
77// appear in symtab if there is no references to them.
deps/lld/test/ELF/aarch64-gnu-ifunc-plt.s+17-14
......@@ -5,24 +5,24 @@
55// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout
66// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
77// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
8// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
8// RUN: llvm-readobj -r --dynamic-table %tout | FileCheck %s
99
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: 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
13// CHECK: 0x230018 R_AARCH64_JUMP_SLOT bar2 0x0
14// CHECK-NEXT: 0x230020 R_AARCH64_JUMP_SLOT zed2 0x0
15// CHECK-NEXT: 0x230028 R_AARCH64_IRELATIVE - 0x210000
16// CHECK-NEXT: 0x230030 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: 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
22// GOTPLT-NEXT: 230000 00000000 00000000 00000000 00000000
23// GOTPLT-NEXT: 230010 00000000 00000000 20002100 00000000
24// GOTPLT-NEXT: 230020 20002100 00000000 20002100 00000000
25// GOTPLT-NEXT: 230030 20002100 00000000
2626
2727// Check that the PLTRELSZ tag includes the IRELATIVE relocations
2828// CHECK: DynamicSection [
......@@ -30,6 +30,7 @@
3030
3131// Check that a PLT header is written and the ifunc entries appear last
3232// DISASM: Disassembly of section .text:
33// DISASM-EMPTY:
3334// DISASM-NEXT: foo:
3435// DISASM-NEXT: 210000: {{.*}} ret
3536// DISASM: bar:
......@@ -39,10 +40,12 @@
3940// DISASM-NEXT: 21000c: {{.*}} bl #100
4041// DISASM-NEXT: 210010: {{.*}} bl #48
4142// DISASM-NEXT: 210014: {{.*}} bl #60
43// DISASM-EMPTY:
4244// DISASM-NEXT: Disassembly of section .plt:
45// DISASM-EMPTY:
4346// DISASM-NEXT: .plt:
4447// DISASM-NEXT: 210020: {{.*}} stp x16, x30, [sp, #-16]!
45// DISASM-NEXT: 210024: {{.*}} adrp x16, #65536
48// DISASM-NEXT: 210024: {{.*}} adrp x16, #131072
4649// DISASM-NEXT: 210028: {{.*}} ldr x17, [x16, #16]
4750// DISASM-NEXT: 21002c: {{.*}} add x16, x16, #16
4851// DISASM-NEXT: 210030: {{.*}} br x17
......@@ -51,21 +54,21 @@
5154// DISASM-NEXT: 21003c: {{.*}} nop
5255// DISASM-EMPTY:
5356// DISASM-NEXT: bar2@plt:
54// DISASM-NEXT: 210040: {{.*}} adrp x16, #65536
57// DISASM-NEXT: 210040: {{.*}} adrp x16, #131072
5558// DISASM-NEXT: 210044: {{.*}} ldr x17, [x16, #24]
5659// DISASM-NEXT: 210048: {{.*}} add x16, x16, #24
5760// DISASM-NEXT: 21004c: {{.*}} br x17
5861// DISASM-EMPTY:
5962// DISASM-NEXT: zed2@plt:
60// DISASM-NEXT: 210050: {{.*}} adrp x16, #65536
63// DISASM-NEXT: 210050: {{.*}} adrp x16, #131072
6164// DISASM-NEXT: 210054: {{.*}} ldr x17, [x16, #32]
6265// DISASM-NEXT: 210058: {{.*}} add x16, x16, #32
6366// DISASM-NEXT: 21005c: {{.*}} br x17
64// DISASM-NEXT: 210060: {{.*}} adrp x16, #65536
67// DISASM-NEXT: 210060: {{.*}} adrp x16, #131072
6568// DISASM-NEXT: 210064: {{.*}} ldr x17, [x16, #40]
6669// DISASM-NEXT: 210068: {{.*}} add x16, x16, #40
6770// DISASM-NEXT: 21006c: {{.*}} br x17
68// DISASM-NEXT: 210070: {{.*}} adrp x16, #65536
71// DISASM-NEXT: 210070: {{.*}} adrp x16, #131072
6972// DISASM-NEXT: 210074: {{.*}} ldr x17, [x16, #48]
7073// DISASM-NEXT: 210078: {{.*}} add x16, x16, #48
7174// DISASM-NEXT: 21007c: {{.*}} br x17
deps/lld/test/ELF/aarch64-gnu-ifunc.s+4-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
33// RUN: ld.lld -static %t.o -o %tout
44// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
5// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
5// RUN: llvm-readobj -r --symbols --sections %tout | FileCheck %s
66
77// CHECK: Sections [
88// CHECK: Section {
......@@ -100,6 +100,7 @@
100100// 392 = 0x188
101101
102102// DISASM: Disassembly of section .text:
103// DISASM-EMPTY:
103104// DISASM-NEXT: foo:
104105// DISASM-NEXT: 210000: c0 03 5f d6 ret
105106// DISASM: bar:
......@@ -109,7 +110,9 @@
109110// DISASM-NEXT: 21000c: 09 00 00 94 bl #36
110111// DISASM-NEXT: 210010: 42 60 05 91 add x2, x2, #344
111112// DISASM-NEXT: 210014: 42 20 06 91 add x2, x2, #392
113// DISASM-EMPTY:
112114// DISASM-NEXT: Disassembly of section .plt:
115// DISASM-EMPTY:
113116// DISASM-NEXT: .plt:
114117// DISASM-NEXT: 210020: 90 00 00 90 adrp x16, #65536
115118// DISASM-NEXT: 210024: 11 02 40 f9 ldr x17, [x16]
deps/lld/test/ELF/aarch64-gnu-ifunc2.s+5-7
......@@ -5,16 +5,18 @@
55# RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC
66
77# CHECK: Disassembly of section .text:
8# CHECK-EMPTY:
89# CHECK-NEXT: myfunc:
910# CHECK-NEXT: 210000:
1011
1112# CHECK: main:
12# adrp x8, 0x230000, 0x230000 == address in .got
13# CHECK-NEXT: 210004: {{.*}} adrp x8, #131072
13# adrp x8, 0x220000, 0x220000 == address in .got.plt
14# CHECK-NEXT: 210004: {{.*}} adrp x8, #65536
1415# CHECK-NEXT: 210008: {{.*}} ldr x8, [x8]
1516# CHECK-NEXT: 21000c: {{.*}} ret
1617
1718# CHECK: Disassembly of section .plt:
19# CHECK-EMPTY:
1820# CHECK-NEXT: .plt:
1921# adrp x16, 0x220000, 0x220000 == address in .got.plt
2022# CHECK-NEXT: 210010: {{.*}} adrp x16, #65536
......@@ -23,14 +25,10 @@
2325# CHECK-NEXT: 21001c: {{.*}} br x17
2426
2527# CHECK: Disassembly of section .got.plt:
28# CHECK-EMPTY:
2629# CHECK-NEXT: .got.plt:
2730# CHECK-NEXT: 220000:
2831
29# CHECK: Disassembly of section .got:
30# CHECK-NEXT: .got:
31# 0x210010 == address in .plt
32# CHECK-NEXT: 230000: 10 00 21 00
33
3432# RELOC: Relocations [
3533# RELOC-NEXT: Section {{.*}} .rela.plt {
3634# RELOC-NEXT: 0x220000 R_AARCH64_IRELATIVE - 0x210000
deps/lld/test/ELF/aarch64-gnu-ifunc3.s deleted-49
......@@ -1,49 +0,0 @@
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-got-reloc.s deleted-30
......@@ -1,30 +0,0 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -s --section-data %t | FileCheck %s
5
6// CHECK: Name: .got
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_WRITE
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address:
13// CHECK-NEXT: Offset:
14// CHECK-NEXT: Size: 8
15// CHECK-NEXT: Link: 0
16// CHECK-NEXT: Info: 0
17// CHECK-NEXT: AddressAlignment: 8
18// CHECK-NEXT: EntrySize: 0
19// CHECK-NEXT: SectionData (
20// CHECK-NEXT: 0000: 00000000 00000000 |........|
21// CHECK-NEXT: )
22
23 .globl _start
24_start:
25 adrp x8, :got:foo
26 ldr x8, [x8, :got_lo12:foo]
27 ldr w0, [x8]
28 ret
29
30 .weak foo
deps/lld/test/ELF/aarch64-got-weak-undef.s created+18
......@@ -0,0 +1,18 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readelf -r %t | FileCheck --check-prefix=RELOC %s
5// RUN: llvm-readelf -x .got %t | FileCheck %s
6
7// RELOC: no relocations
8
9// CHECK: 0x00220000 00000000 00000000
10
11 .globl _start
12_start:
13 adrp x8, :got:foo
14 ldr x8, [x8, :got_lo12:foo]
15 ldr w0, [x8]
16 ret
17
18 .weak foo
deps/lld/test/ELF/aarch64-got.s deleted-18
......@@ -1,18 +0,0 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readobj -s %t | FileCheck %s
5
6# CHECK-NOT: Name: .got
7
8.globl _start
9_start:
10 adrp x0, :gottprel:foo
11
12 .global foo
13 .section .tdata,"awT",%progbits
14 .align 2
15 .type foo, %object
16 .size foo, 4
17foo:
18 .word 5
deps/lld/test/ELF/aarch64-hi21-nc.s created+8
......@@ -0,0 +1,8 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t
4// RUN: llvm-objdump -d %t | FileCheck %s
5
6foo = . + 0x1100000000000000
7// CHECK: adrp x0, #0
8adrp x0, :pg_hi21_nc:foo
deps/lld/test/ELF/aarch64-ifunc-bti.s created+65
......@@ -0,0 +1,65 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %p/Inputs/aarch64-addrifunc.s -o %t1.o
4
5# RUN: ld.lld --shared %t1.o -o %t1.so
6# RUN: ld.lld --pie %t1.so %t.o -o %t
7# RUN: llvm-objdump -d -mattr=+bti -triple=aarch64-linux-gnu %t | FileCheck %s
8
9# When the address of an ifunc is taken using a non-got reference which clang
10# can do, LLD exports a canonical PLT entry that may have its address taken so
11# we must use bti c.
12
13# CHECK: Disassembly of section .plt:
14# CHECK: 0000000000010020 .plt:
15# CHECK-NEXT: 10020: 5f 24 03 d5 bti c
16# CHECK-NEXT: 10024: f0 7b bf a9 stp x16, x30, [sp, #-16]!
17# CHECK-NEXT: 10028: 10 01 00 90 adrp x16, #131072
18# CHECK-NEXT: 1002c: 11 0a 40 f9 ldr x17, [x16, #16]
19# CHECK-NEXT: 10030: 10 42 00 91 add x16, x16, #16
20# CHECK-NEXT: 10034: 20 02 1f d6 br x17
21# CHECK-NEXT: 10038: 1f 20 03 d5 nop
22# CHECK-NEXT: 1003c: 1f 20 03 d5 nop
23# CHECK: 0000000000010040 func1@plt:
24# CHECK-NEXT: 10040: 5f 24 03 d5 bti c
25# CHECK-NEXT: 10044: 10 01 00 90 adrp x16, #131072
26# CHECK-NEXT: 10048: 11 0e 40 f9 ldr x17, [x16, #24]
27# CHECK-NEXT: 1004c: 10 62 00 91 add x16, x16, #24
28# CHECK-NEXT: 10050: 20 02 1f d6 br x17
29# CHECK-NEXT: 10054: 1f 20 03 d5 nop
30# CHECK-NEXT: ...
31# CHECK: 0000000000010060 myfunc:
32# CHECK-NEXT: 10060: 5f 24 03 d5 bti c
33# CHECK-NEXT: 10064: 10 01 00 90 adrp x16, #131072
34# CHECK-NEXT: 10068: 11 12 40 f9 ldr x17, [x16, #32]
35# CHECK-NEXT: 1006c: 10 82 00 91 add x16, x16, #32
36# CHECK-NEXT: 10070: 20 02 1f d6 br x17
37# CHECK-NEXT: 10074: 1f 20 03 d5 nop
38
39.section ".note.gnu.property", "a"
40.long 4
41.long 0x10
42.long 0x5
43.asciz "GNU"
44
45.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
46.long 4
47.long 1 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI
48.long 0
49
50.text
51.globl myfunc
52.type myfunc,@gnu_indirect_function
53myfunc:
54 ret
55
56.globl func1
57
58.text
59.globl _start
60.type _start, %function
61_start:
62 bl func1
63 adrp x8, myfunc
64 add x8, x8, :lo12:myfunc
65 ret
deps/lld/test/ELF/aarch64-jump26-thunk.s+1
......@@ -10,6 +10,7 @@ _start:
1010 b big
1111
1212// CHECK: Disassembly of section .text:
13// CHECK-EMPTY:
1314// CHECK-NEXT: _start:
1415// CHECK-NEXT: 210000: 02 00 00 14 b #8
1516// CHECK: __AArch64AbsLongThunk_big:
deps/lld/test/ELF/aarch64-ldprel-lo19-invalid.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
44# RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s
55
6# CHECK: relocation R_AARCH64_LD_PREL_LO19 out of range: 2065536 is not in [-1048576, 1048575]
6# CHECK: relocation R_AARCH64_LD_PREL_LO19 out of range: 2131072 is not in [-1048576, 1048575]
77
88 ldr x8, patatino
99 .data
deps/lld/test/ELF/aarch64-load-alignment.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
44# RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s
55
6# CHECK: improper alignment for relocation R_AARCH64_LD_PREL_LO19: 0x10005 is not aligned to 4 bytes
6# CHECK: improper alignment for relocation R_AARCH64_LD_PREL_LO19: 0x20005 is not aligned to 4 bytes
77
88 ldr x8, patatino
99 .data
deps/lld/test/ELF/aarch64-nopic-plt.s created+27
......@@ -0,0 +1,27 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
3// RUN: llvm-mc %p/Inputs/aarch64-copy2.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: ld.lld %t.o %t2.so -o %t
6// RUN: llvm-readobj --symbols %t | FileCheck %s
7
8 .global _start
9_start:
10 adrp x8, foo
11 bl bar
12
13// CHECK: Name: bar
14// CHECK-NEXT: Value: 0x0
15// CHECK-NEXT: Size: 0
16// CHECK-NEXT: Binding: Global
17// CHECK-NEXT: Type: None
18// CHECK-NEXT: Other: 0
19// CHECK-NEXT: Section: Undefined
20
21// CHECK: Name: foo
22// CHECK-NEXT: Value: 0x210030
23// CHECK-NEXT: Size: 0
24// CHECK-NEXT: Binding: Global
25// CHECK-NEXT: Type: Function
26// CHECK-NEXT: Other: 0
27// CHECK-NEXT: Section: Undefined
deps/lld/test/ELF/aarch64-prel16.s+2-2
......@@ -25,7 +25,7 @@ _start:
2525// CHECK-NEXT: 201000 ffff0080
2626
2727// 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]
28// OVERFLOW1: relocation R_AARCH64_PREL16 out of range: -32769 is not in [-32768, 65535]
2929
3030// 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]
31// OVERFLOW2: relocation R_AARCH64_PREL16 out of range: 65536 is not in [-32768, 65535]
deps/lld/test/ELF/aarch64-prel32.s+2-2
......@@ -25,7 +25,7 @@ _start:
2525// CHECK-NEXT: 201000 ffffffff 00000080
2626
2727// 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]
28// OVERFLOW1: relocation R_AARCH64_PREL32 out of range: -2147483649 is not in [-2147483648, 4294967295]
2929
3030// 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]
31// OVERFLOW2: relocation R_AARCH64_PREL32 out of range: 4294967296 is not in [-2147483648, 4294967295]
deps/lld/test/ELF/aarch64-property-relocatable.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o
3# RUN: ld.lld -r %t.o -o %t2.o
4# RUN: llvm-readelf -n %t2.o | FileCheck -match-full-lines %s
5
6## Test that .note.gnu.property is passed through -r, and that we can handle
7## more than one FEATURE_AND in the same object file. This is logically the
8## same as if the features were combined in a single FEATURE_AND as the rule
9## states that the bit in the output pr_data field if it is set in all
10.text
11ret
12
13.section ".note.gnu.property", "a"
14.p2align 3
15.long 4
16.long 0x10
17.long 0x5
18.asciz "GNU"
19
20.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
21.long 4
22.long 1 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI
23.long 0
24
25.long 4
26.long 0x10
27.long 0x5
28.asciz "GNU"
29.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND
30.long 4
31.long 2 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC
32.long 0
33
34# CHECK: Owner Data size Description
35# CHECK-NEXT: GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 (property note)
36# CHECK-NEXT: Properties: aarch64 feature: BTI, PAC
deps/lld/test/ELF/aarch64-relocs.s+12
......@@ -12,6 +12,7 @@ msg: .asciz "Hello, world\n"
1212msgend:
1313
1414# CHECK: Disassembly of section .R_AARCH64_ADR_PREL_LO21:
15# CHECK-EMPTY:
1516# CHECK: _start:
1617# CHECK: 0: 21 00 00 10 adr x1, #4
1718# CHECK: msg:
......@@ -29,6 +30,7 @@ mystr:
2930# PAGE(P) = 0x210000
3031#
3132# CHECK: Disassembly of section .R_AARCH64_ADR_PREL_PG_H121:
33# CHECK-EMPTY:
3234# CHECK-NEXT: $x.2:
3335# CHECK-NEXT: 210012: 01 00 00 90 adrp x1, #0
3436
......@@ -43,6 +45,7 @@ mystr:
4345# R << 10 = 0x7c00
4446#
4547# CHECK: Disassembly of section .R_AARCH64_ADD_ABS_LO12_NC:
48# CHECK-EMPTY:
4649# CHECK-NEXT: $x.4:
4750# CHECK-NEXT: 21001b: 00 7c 00 91 add x0, x0, #31
4851
......@@ -56,6 +59,7 @@ foo:
5659# R = ((S + A) & 0xFFF) << 7 = 0x00001400
5760# 0x00001400 | 0xf940177c = 0xf940177c
5861# CHECK: Disassembly of section .R_AARCH64_LDST64_ABS_LO12_NC:
62# CHECK-EMPTY:
5963# CHECK-NEXT: $x.6:
6064# CHECK-NEXT: 210024: 7c 17 40 f9 ldr x28, [x27, #40]
6165
......@@ -65,6 +69,7 @@ sub:
6569 nop
6670
6771# CHECK: Disassembly of section .SUB:
72# CHECK-EMPTY:
6873# CHECK-NEXT: $x.8:
6974# CHECK-NEXT: 21002c: 1f 20 03 d5 nop
7075# CHECK: sub:
......@@ -79,6 +84,7 @@ call26:
7984# (R & 0x0ffffffc) >> 2 = 0x03ffffff
8085# 0x94000000 | 0x03ffffff = 0x97ffffff
8186# CHECK: Disassembly of section .R_AARCH64_CALL26:
87# CHECK-EMPTY:
8288# CHECK-NEXT: call26:
8389# CHECK-NEXT: 210034: ff ff ff 97 bl #-4
8490
......@@ -91,6 +97,7 @@ jump26:
9197# (R & 0x0ffffffc) >> 2 = 0x03fffffe
9298# 0x14000000 | 0x03fffffe = 0x17fffffe
9399# CHECK: Disassembly of section .R_AARCH64_JUMP26:
100# CHECK-EMPTY:
94101# CHECK-NEXT: jump26:
95102# CHECK-NEXT: 210038: fe ff ff 17 b #-8
96103
......@@ -105,6 +112,7 @@ foo32:
105112# R = ((S + A) & 0xFFC) << 8 = 0x00004000
106113# 0x00004000 | 0xbd4000a4 = 0xbd4040a4
107114# CHECK: Disassembly of section .R_AARCH64_LDST32_ABS_LO12_NC:
115# CHECK-EMPTY:
108116# CHECK-NEXT: ldst32:
109117# CHECK-NEXT: 21003c: a4 40 40 bd ldr s4, [x5, #64]
110118
......@@ -119,6 +127,7 @@ foo8:
119127# R = ((S + A) & 0xFFF) << 10 = 0x00012000
120128# 0x00012000 | 0x398001ab = 0x398121ab
121129# CHECK: Disassembly of section .R_AARCH64_LDST8_ABS_LO12_NC:
130# CHECK-EMPTY:
122131# CHECK-NEXT: ldst8:
123132# CHECK-NEXT: 210044: ab 21 81 39 ldrsb x11, [x13, #72]
124133
......@@ -133,6 +142,7 @@ foo128:
133142# R = ((S + A) & 0xFF8) << 6 = 0x00001400
134143# 0x00001400 | 0x3dc00274 = 0x3dc01674
135144# CHECK: Disassembly of section .R_AARCH64_LDST128_ABS_LO12_NC:
145# CHECK-EMPTY:
136146# CHECK: ldst128:
137147# CHECK: 21004c: 74 16 c0 3d ldr q20, [x19, #80]
138148#foo128:
......@@ -151,6 +161,7 @@ foo16:
151161# R = ((S + A) & 0x0FFC) << 9 = 0xb000
152162# 0xb000 | 0x7d400271 = 0x7d40b271
153163# CHECK: Disassembly of section .R_AARCH64_LDST16_ABS_LO12_NC:
164# CHECK-EMPTY:
154165# CHECK-NEXT: ldst16:
155166# CHECK-NEXT: 210054: 71 c2 40 7d ldr h17, [x19, #96]
156167# CHECK-NEXT: 210058: 61 c2 40 79 ldrh w1, [x19, #96]
......@@ -166,6 +177,7 @@ movz1:
166177
167178## 4222124650659840 == (0xF << 48)
168179# CHECK: Disassembly of section .R_AARCH64_MOVW_UABS:
180# CHECK-EMPTY:
169181# CHECK-NEXT: movz1:
170182# CHECK-NEXT: 8c 01 80 f2 movk x12, #12
171183# CHECK-NEXT: ad 01 a0 f2 movk x13, #13, lsl #16
deps/lld/test/ELF/aarch64-relro.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: aarch64
22# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t
33# RUN: ld.lld %t -o %t2
4# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
4# RUN: llvm-readobj -l %t2 | FileCheck %s
55
66# CHECK: Type: PT_GNU_RELRO
77# CHECK-NEXT: Offset:
deps/lld/test/ELF/aarch64-thunk-pi.s+7-6
......@@ -72,11 +72,12 @@ high_target2:
7272// CHECK-NEXT: 10000018: 00 02 1f d6 br x16
7373
7474// CHECK: Disassembly of section .plt:
75// CHECK-EMPTY:
7576// CHECK-NEXT: .plt:
7677// CHECK-NEXT: 10000020: f0 7b bf a9 stp x16, x30, [sp, #-16]!
7778// CHECK-NEXT: 10000024: 10 00 00 90 adrp x16, #0
78// CHECK-NEXT: 10000028: 11 3a 40 f9 ldr x17, [x16, #112]
79// CHECK-NEXT: 1000002c: 10 c2 01 91 add x16, x16, #112
79// CHECK-NEXT: 10000028: 11 92 40 f9 ldr x17, [x16, #288]
80// CHECK-NEXT: 1000002c: 10 82 04 91 add x16, x16, #288
8081// CHECK-NEXT: 10000030: 20 02 1f d6 br x17
8182// CHECK-NEXT: 10000034: 1f 20 03 d5 nop
8283// CHECK-NEXT: 10000038: 1f 20 03 d5 nop
......@@ -84,12 +85,12 @@ high_target2:
8485// CHECK-EMPTY:
8586// CHECK-NEXT: high_target@plt:
8687// CHECK-NEXT: 10000040: 10 00 00 90 adrp x16, #0
87// CHECK-NEXT: 10000044: 11 3e 40 f9 ldr x17, [x16, #120]
88// CHECK-NEXT: 10000048: 10 e2 01 91 add x16, x16, #120
88// CHECK-NEXT: 10000044: 11 96 40 f9 ldr x17, [x16, #296]
89// CHECK-NEXT: 10000048: 10 a2 04 91 add x16, x16, #296
8990// CHECK-NEXT: 1000004c: 20 02 1f d6 br x17
9091// CHECK-EMPTY:
9192// CHECK-NEXT: low_target@plt:
9293// CHECK-NEXT: 10000050: 10 00 00 90 adrp x16, #0
93// CHECK-NEXT: 10000054: 11 42 40 f9 ldr x17, [x16, #128]
94// CHECK-NEXT: 10000058: 10 02 02 91 add x16, x16, #128
94// CHECK-NEXT: 10000054: 11 9a 40 f9 ldr x17, [x16, #304]
95// CHECK-NEXT: 10000058: 10 c2 04 91 add x16, x16, #304
9596// CHECK-NEXT: 1000005c: 20 02 1f d6 br x17
deps/lld/test/ELF/aarch64-thunk-script.s+2
......@@ -26,6 +26,7 @@ high_target:
2626 ret
2727
2828// CHECK: Disassembly of section .text_low:
29// CHECK-EMPTY:
2930// CHECK-NEXT: _start:
3031// CHECK-NEXT: 2000: 02 00 00 94 bl #8
3132// CHECK-NEXT: 2004: c0 03 5f d6 ret
......@@ -36,6 +37,7 @@ high_target:
3637// CHECK-NEXT: 2010: 00 20 00 08 .word 0x08002000
3738// CHECK-NEXT: 2014: 00 00 00 00 .word 0x00000000
3839// CHECK: Disassembly of section .text_high:
40// CHECK-EMPTY:
3941// CHECK-NEXT: high_target:
4042// CHECK-NEXT: 8002000: 00 00 00 96 bl #-134217728
4143// CHECK-NEXT: 8002004: c0 03 5f d6 ret
deps/lld/test/ELF/aarch64-tls-gdie.s+7-7
......@@ -3,8 +3,8 @@
33// RUN: llvm-mc %p/Inputs/aarch64-tls-gdie.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux
44// RUN: ld.lld %t2.o -o %t2.so -shared
55// RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t
6// RUN: llvm-readobj -s %t | FileCheck --check-prefix=SEC %s
7// RUN: llvm-objdump -d %t | FileCheck %s
6// RUN: llvm-readobj -S %t | FileCheck --check-prefix=SEC %s
7// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
88
99 .globl _start
1010_start:
......@@ -27,8 +27,8 @@ _start:
2727// 0x0B0 = 176
2828
2929// CHECK: _start:
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
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+11-10
......@@ -2,20 +2,21 @@
22# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o
33# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o
44# RUN: ld.lld %tmain.o %ttlsie.o -o %tout
5# RUN: llvm-objdump -d %tout | FileCheck %s
6# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
5# RUN: llvm-objdump -d --no-show-raw-insn %tout | FileCheck %s
6# RUN: llvm-readobj -r %tout | FileCheck -check-prefix=RELOC %s
77
8#Local-Dynamic to Local-Exec relax creates no
9#RELOC: Relocations [
10#RELOC-NEXT: ]
8## Local-Dynamic to Local-Exec relax creates no dynamic relocations.
9# RELOC: Relocations [
10# RELOC-NEXT: ]
1111
12# TCB size = 64 and foo is first element from TLS register.
12# TCB size = 0x16 and foo is first element from TLS register.
1313# CHECK: Disassembly of section .text:
14# CHECK-EMPTY:
1415# CHECK: _start:
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
16# CHECK: 210000: movz x0, #0, lsl #16
17# CHECK: 210004: movk x0, #16
18# CHECK: 210008: nop
19# CHECK: 21000c: nop
1920
2021.globl _start
2122_start:
deps/lld/test/ELF/aarch64-tls-ie.s+33-35
......@@ -1,45 +1,43 @@
1// REQUIRES: aarch64
21# REQUIRES: aarch64
32# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tls-ie.s -o %tdso.o
43# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o
54# RUN: ld.lld -shared %tdso.o -o %tdso.so
65# RUN: ld.lld --hash-style=sysv %tmain.o %tdso.so -o %tout
7# RUN: llvm-objdump -d %tout | FileCheck %s
8# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
6# RUN: llvm-objdump -d --no-show-raw-insn %tout | FileCheck %s
7# RUN: llvm-readobj -S -r %tout | FileCheck -check-prefix=RELOC %s
98
10#RELOC: Section {
11#RELOC: Index:
12#RELOC: Name: .got
13#RELOC-NEXT: Type: SHT_PROGBITS
14#RELOC-NEXT: Flags [
15#RELOC-NEXT: SHF_ALLOC
16#RELOC-NEXT: SHF_WRITE
17#RELOC-NEXT: ]
18#RELOC-NEXT: Address: 0x2200B0
19#RELOC-NEXT: Offset: 0x200B0
20#RELOC-NEXT: Size: 16
21#RELOC-NEXT: Link: 0
22#RELOC-NEXT: Info: 0
23#RELOC-NEXT: AddressAlignment: 8
24#RELOC-NEXT: EntrySize: 0
25#RELOC-NEXT: }
26#RELOC: Relocations [
27#RELOC-NEXT: Section ({{.*}}) .rela.dyn {
28#RELOC-NEXT: 0x2200B8 R_AARCH64_TLS_TPREL64 bar 0x0
29#RELOC-NEXT: 0x2200B0 R_AARCH64_TLS_TPREL64 foo 0x0
30#RELOC-NEXT: }
31#RELOC-NEXT:]
9# RELOC: Section {
10# RELOC: Index:
11# RELOC: Name: .got
12# RELOC-NEXT: Type: SHT_PROGBITS
13# RELOC-NEXT: Flags [
14# RELOC-NEXT: SHF_ALLOC
15# RELOC-NEXT: SHF_WRITE
16# RELOC-NEXT: ]
17# RELOC-NEXT: Address: 0x2200B0
18# RELOC-NEXT: Offset: 0x200B0
19# RELOC-NEXT: Size: 16
20# RELOC-NEXT: Link: 0
21# RELOC-NEXT: Info: 0
22# RELOC-NEXT: AddressAlignment: 8
23# RELOC-NEXT: EntrySize: 0
24# RELOC-NEXT: }
25# RELOC: Relocations [
26# RELOC-NEXT: Section ({{.*}}) .rela.dyn {
27# RELOC-NEXT: 0x2200B8 R_AARCH64_TLS_TPREL64 bar 0x0
28# RELOC-NEXT: 0x2200B0 R_AARCH64_TLS_TPREL64 foo 0x0
29# RELOC-NEXT: }
30# RELOC-NEXT:]
3231
33# Page(0x2200B0) - Page(0x210000) = 0x10000 = 65536
34# 0x2200B0 & 0xff8 = 0xB0 = 176
35# Page(0x2200B8) - Page(0x210000) = 0x10000 = 65536
36# 0x2200B8 & 0xff8 = 0xB8 = 184
37#CHECK: Disassembly of section .text:
38#CHECK: _start:
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]
32## Page(0x2200B0) - Page(0x210000) = 0x10000 = 65536
33## 0x2200B0 & 0xff8 = 0xB0 = 176
34## Page(0x2200B8) - Page(0x210000) = 0x10000 = 65536
35## 0x2200B8 & 0xff8 = 0xB8 = 184
36# CHECK: _start:
37# CHECK-NEXT: 210000: adrp x0, #65536
38# CHECK-NEXT: 210004: ldr x0, [x0, #176]
39# CHECK-NEXT: 210008: adrp x0, #65536
40# CHECK-NEXT: 21000c: ldr x0, [x0, #184]
4341
4442.globl _start
4543_start:
deps/lld/test/ELF/aarch64-tls-iele.s+12-7
......@@ -2,20 +2,25 @@
22# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o
33# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o
44# RUN: ld.lld %tmain.o %ttlsie.o -o %tout
5# RUN: llvm-objdump -d %tout | FileCheck %s
6# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
5# RUN: llvm-objdump -d --no-show-raw-insn %tout | FileCheck %s
6# RUN: llvm-readobj -r %tout | FileCheck -check-prefix=RELOC %s
7
8# RUN: ld.lld -pie %tmain.o %ttlsie.o -o %tout
9# RUN: llvm-objdump -d --no-show-raw-insn %tout | FileCheck %s
10# RUN: llvm-readobj -r %tout | FileCheck -check-prefix=RELOC %s
711
812# Initial-Exec to Local-Exec relax creates no dynamic relocations.
913# RELOC: Relocations [
1014# RELOC-NEXT: ]
1115
12# TCB size = 64 and foo is first element from TLS register.
16# TCB size = 0x16 and foo is first element from TLS register.
1317# CHECK: Disassembly of section .text:
18# CHECK-EMPTY:
1419# CHECK: _start:
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
20# CHECK-NEXT: movz x0, #0, lsl #16
21# CHECK-NEXT: movk x0, #20
22# CHECK-NEXT: movz x0, #0, lsl #16
23# CHECK-NEXT: movk x0, #16
1924
2025.section .tdata
2126.align 2
deps/lld/test/ELF/aarch64-tls-le.s+5-5
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o
33# RUN: ld.lld %tmain.o -o %tout
44# RUN: llvm-objdump -d %tout | FileCheck %s
5# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
5# RUN: llvm-readobj -S -r %tout | FileCheck -check-prefix=RELOC %s
66
77#Local-Dynamic to Local-Exec relax creates no
88#RELOC: Relocations [
......@@ -17,12 +17,12 @@ _start:
1717 add x0, x0, :tprel_hi12:v2
1818 add x0, x0, :tprel_lo12_nc:v2
1919
20# TCB size = 64 and foo is first element from TLS register.
20# TCB size = 0x16 and foo is first element from TLS register.
2121#CHECK: Disassembly of section .text:
2222#CHECK: _start:
2323#CHECK: 210000: 40 d0 3b d5 mrs x0, TPIDR_EL0
2424#CHECK: 210004: 00 00 40 91 add x0, x0, #0, lsl #12
25#CHECK: 210008: 00 00 01 91 add x0, x0, #64
25#CHECK: 210008: 00 40 00 91 add x0, x0, #16
2626#CHECK: 21000c: 40 d0 3b d5 mrs x0, TPIDR_EL0
2727#CHECK: 210010: 00 fc 7f 91 add x0, x0, #4095, lsl #12
2828#CHECK: 210014: 00 e0 3f 91 add x0, x0, #4088
......@@ -36,9 +36,9 @@ v1:
3636.word 0
3737.size v1, 4
3838
39# The current offset from the thread pointer is 68. Raise it to just below the
39# The current offset from the thread pointer is 20. Raise it to just below the
4040# 24-bit limit.
41.space (0xfffff8 - 68)
41.space (0xfffff8 - 20)
4242
4343.type v2,@object
4444.globl v2
deps/lld/test/ELF/aarch64-tls-pie.s deleted-28
......@@ -1,28 +0,0 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t1.o
3# RUN: ld.lld -pie %t1.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck %s
5
6# Similar to bug 27174: R_AARCH64_TLSLE_*TPREL* relocations should be
7# eliminated when building a PIE executable, as the static TLS layout is
8# fixed.
9#
10# CHECK: Relocations [
11# CHECK-NEXT: ]
12
13 .globl _start
14_start:
15 # Accessing the variable directly.
16 add x11, x8, :tprel_hi12:i
17 add x11, x11, :tprel_lo12_nc:i
18
19 # Accessing the variable through the GOT.
20 adrp x10, :gottprel:i
21 mrs x8, TPIDR_EL0
22 ldr x10, [x10, :gottprel_lo12:i]
23
24 .section .tbss.i,"awT",@nobits
25 .globl i
26i:
27 .word 0
28 .size i, 4
deps/lld/test/ELF/aarch64-tls-static.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: aarch64
22// RUN: llvm-mc %s -o %t.o -triple aarch64-pc-linux -filetype=obj
33// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4// RUN: llvm-readobj -s %t.so | FileCheck --check-prefix=SEC %s
4// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
55// RUN: llvm-objdump -d %t.so | FileCheck %s
66
77foo:
deps/lld/test/ELF/aarch64-tlsld-ldst.s+27-27
......@@ -1,7 +1,7 @@
11// REQUIRES: aarch64
22// RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj %s -o %t.o
33// RUN: ld.lld %t.o -o %t
4// RUN: llvm-objdump -d %t | FileCheck %s
4// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
55// RUN: llvm-readelf --symbols %t | FileCheck -check-prefix CHECK-SYMS %s
66
77 .text
......@@ -25,28 +25,28 @@ _start: mrs x8, TPIDR_EL0
2525 ldrb w0, [x8, :tprel_lo12_nc:var4]
2626
2727// CHECK: _start:
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]
28// CHECK-NEXT: 210000: mrs x8, TPIDR_EL0
29// 0x0 + c10 = 0xc10 = tcb (16-bytes) + var0
30// CHECK-NEXT: 210004: add x8, x8, #0, lsl #12
31// CHECK-NEXT: 210008: ldr q20, [x8, #3088]
32// 0x1000 + 0x820 = 0x1820 = tcb + var1
33// CHECK-NEXT: 21000c: add x8, x8, #1, lsl #12
34// CHECK-NEXT: 210010: ldr x0, [x8, #2080]
35// 0x2000 + 0x428 = 0x2428 = tcb + var2
36// CHECK-NEXT: 210014: add x8, x8, #2, lsl #12
37// CHECK-NEXT: 210018: ldr w0, [x8, #1064]
38// 0x3000 + 0x2c = 0x302c = tcb + var3
39// CHECK-NEXT: 21001c: add x8, x8, #3, lsl #12
40// CHECK-NEXT: 210020: ldrh w0, [x8, #44]
41// 0x3000 + 0xc2e = 0x32ce = tcb + var4
42// CHECK-NEXT: 210024: add x8, x8, #3, lsl #12
43// CHECK-NEXT: 210028: ldrb w0, [x8, #3118]
4444
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
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
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 64
62 .balign 16
6363 .space 1024 * 3
6464var0:
6565 .quad 0
6666 .quad 0
67 .size var0, 16
67 .size var1, 16
6868 .space 1024 * 3
6969var1:
7070 .quad 0
......@@ -72,14 +72,14 @@ var1:
7272 .space 1024 * 3
7373var2:
7474 .word 0
75 .size var2, 4
75 .size var1, 4
7676
7777 .space 1024 * 3
7878var3:
7979 .hword 0
80 .size var3, 2
80 .size var2, 2
8181 .space 1024 * 3
8282var4:
8383 .byte 0
84 .size var4, 1
84 .size var3, 1
8585 .space 1024 * 3
deps/lld/test/ELF/aarch64-tstbr14-reloc.s+12-8
......@@ -5,13 +5,14 @@
55# RUN: llvm-objdump -d %t | FileCheck %s
66# RUN: ld.lld -shared %t1 %t2 -o %t3
77# RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=DSO %s
8# RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
8# RUN: llvm-readobj -S -r %t3 | FileCheck -check-prefix=DSOREL %s
99
1010# 0x1101c - 28 = 0x20000
1111# 0x11020 - 16 = 0x20010
1212# 0x11024 - 36 = 0x20000
1313# 0x11028 - 24 = 0x20010
1414# CHECK: Disassembly of section .text:
15# CHECK-EMPTY:
1516# CHECK-NEXT: _foo:
1617# CHECK-NEXT: 210000: {{.*}} nop
1718# CHECK-NEXT: 210004: {{.*}} nop
......@@ -35,8 +36,8 @@
3536#DSOREL-NEXT: SHF_ALLOC
3637#DSOREL-NEXT: SHF_WRITE
3738#DSOREL-NEXT: ]
38#DSOREL-NEXT: Address: 0x20000
39#DSOREL-NEXT: Offset: 0x20000
39#DSOREL-NEXT: Address: 0x30000
40#DSOREL-NEXT: Offset: 0x30000
4041#DSOREL-NEXT: Size: 40
4142#DSOREL-NEXT: Link: 0
4243#DSOREL-NEXT: Info: 0
......@@ -45,12 +46,13 @@
4546#DSOREL-NEXT: }
4647#DSOREL: Relocations [
4748#DSOREL-NEXT: Section ({{.*}}) .rela.plt {
48#DSOREL-NEXT: 0x20018 R_AARCH64_JUMP_SLOT _foo
49#DSOREL-NEXT: 0x20020 R_AARCH64_JUMP_SLOT _bar
49#DSOREL-NEXT: 0x30018 R_AARCH64_JUMP_SLOT _foo
50#DSOREL-NEXT: 0x30020 R_AARCH64_JUMP_SLOT _bar
5051#DSOREL-NEXT: }
5152#DSOREL-NEXT:]
5253
5354#DSO: Disassembly of section .text:
55#DSO-EMPTY:
5456#DSO-NEXT: _foo:
5557#DSO-NEXT: 10000: {{.*}} nop
5658#DSO-NEXT: 10004: {{.*}} nop
......@@ -69,10 +71,12 @@
6971#DSO-NEXT: 10020: {{.*}} tbnz w3, #15, #64
7072#DSO-NEXT: 10024: {{.*}} tbz x6, #45, #44
7173#DSO-NEXT: 10028: {{.*}} tbz x6, #45, #56
74#DSO-EMPTY:
7275#DSO-NEXT: Disassembly of section .plt:
76#DSO-EMPTY:
7377#DSO-NEXT: .plt:
7478#DSO-NEXT: 10030: {{.*}} stp x16, x30, [sp, #-16]!
75#DSO-NEXT: 10034: {{.*}} adrp x16, #65536
79#DSO-NEXT: 10034: {{.*}} adrp x16, #131072
7680#DSO-NEXT: 10038: {{.*}} ldr x17, [x16, #16]
7781#DSO-NEXT: 1003c: {{.*}} add x16, x16, #16
7882#DSO-NEXT: 10040: {{.*}} br x17
......@@ -81,13 +85,13 @@
8185#DSO-NEXT: 1004c: {{.*}} nop
8286#DSO-EMPTY:
8387#DSO-NEXT: _foo@plt:
84#DSO-NEXT: 10050: {{.*}} adrp x16, #65536
88#DSO-NEXT: 10050: {{.*}} adrp x16, #131072
8589#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]
8690#DSO-NEXT: 10058: {{.*}} add x16, x16, #24
8791#DSO-NEXT: 1005c: {{.*}} br x17
8892#DSO-EMPTY:
8993#DSO-NEXT: _bar@plt:
90#DSO-NEXT: 10060: {{.*}} adrp x16, #65536
94#DSO-NEXT: 10060: {{.*}} adrp x16, #131072
9195#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]
9296#DSO-NEXT: 10068: {{.*}} add x16, x16, #32
9397#DSO-NEXT: 1006c: {{.*}} br x17
deps/lld/test/ELF/aarch64-undefined-weak.s+1
......@@ -34,6 +34,7 @@ _start:
3434 ldr x8, target
3535
3636// CHECK: Disassembly of section .text:
37// CHECK-EMPTY:
3738// 2162688 = 0x210000
3839// CHECK: 210000: {{.*}} b #4
3940// CHECK-NEXT: 210004: {{.*}} bl #4
deps/lld/test/ELF/abs-hidden.s+1-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/abs-hidden.s -o %t2.o
44// RUN: ld.lld --hash-style=sysv %t.o %t2.o -o %t.so -shared
5// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
5// RUN: llvm-readobj -r -S --section-data %t.so | FileCheck %s
66
77 .quad foo
88 .long foo@gotpcrel
deps/lld/test/ELF/allow-shlib-undefined.s+20-16
......@@ -1,26 +1,30 @@
11# REQUIRES: x86
2# --allow-shlib-undefined and --no-allow-shlib-undefined are fully
3# ignored in linker implementation.
4# --allow-shlib-undefined is set by default
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
54# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
6# RUN: %p/Inputs/allow-shlib-undefined.s -o %t
7# RUN: ld.lld -shared %t -o %t.so
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
5# RUN: %p/Inputs/allow-shlib-undefined.s -o %t1.o
6# RUN: ld.lld -shared %t1.o -o %t.so
7
8# RUN: ld.lld --allow-shlib-undefined %t.o %t.so -o /dev/null
9# RUN: not ld.lld --no-allow-shlib-undefined %t.o %t.so -o /dev/null 2>&1 | FileCheck %s
10# Executable defaults to --no-allow-shlib-undefined
11# RUN: not ld.lld %t.o %t.so -o /dev/null 2>&1 | FileCheck %s
12# -shared defaults to --allow-shlib-undefined
13# RUN: ld.lld -shared %t.o %t.so -o /dev/null
914
10# Executable: should link with DSO containing undefined symbols in any case.
11# RUN: ld.lld %t1 %t.so -o %t2
12# RUN: ld.lld --no-allow-shlib-undefined %t1 %t.so -o %t2
13# RUN: ld.lld --allow-shlib-undefined %t1 %t.so -o %t2
15# RUN: echo | llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %tempty.o
16# RUN: ld.lld -shared %tempty.o -o %tempty.so
17# RUN: ld.lld -shared %t1.o %tempty.so -o %t2.so
18# RUN: ld.lld --no-allow-shlib-undefined %t.o %t2.so -o /dev/null
1419
1520# DSO with undefines:
1621# should link with or without any of these options.
17# RUN: ld.lld -shared %t -o %t.so
18# RUN: ld.lld -shared --allow-shlib-undefined %t -o %t.so
19# RUN: ld.lld -shared --no-allow-shlib-undefined %t -o %t.so
20
21# Executable still should not link when have undefines inside.
22# RUN: not ld.lld %t -o %t.so
22# RUN: ld.lld -shared %t1.o -o /dev/null
23# RUN: ld.lld -shared --allow-shlib-undefined %t1.o -o /dev/null
24# RUN: ld.lld -shared --no-allow-shlib-undefined %t1.o -o /dev/null
2325
2426.globl _start
2527_start:
2628 callq _shared@PLT
29
30# CHECK: undefined reference to _unresolved
deps/lld/test/ELF/amdgpu-abi-version-err.s created+10
......@@ -0,0 +1,10 @@
1# REQUIRES: amdgpu
2# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx900 -filetype=obj %s -o %t-0.o
3# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx900 -mattr=-code-object-v3 -filetype=obj %s -o %t-1.o
4# RUN: not ld.lld -shared %t-0.o %t-1.o -o %t.so 2>&1 | FileCheck %s
5
6# CHECK: ld.lld: error: incompatible ABI version: {{.*}}-1.o
7
8.text
9 s_nop 0x0
10 s_endpgm
deps/lld/test/ELF/amdgpu-abi-version.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: amdgpu
2# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx900 -filetype=obj %s -o %t.o
3# RUN: ld.lld -shared %t.o -o %t.so
4# RUN: llvm-readobj --file-headers %t.so | FileCheck %s
5
6# CHECK: OS/ABI: AMDGPU_HSA (0x40)
7# CHECK: ABIVersion: 1
8
9.text
10 s_nop 0x0
11 s_endpgm
deps/lld/test/ELF/amdgpu-elf-flags.s+1-1
......@@ -2,7 +2,7 @@
22# 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
33# 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
5# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
5# RUN: llvm-readobj --file-headers %t.so | FileCheck %s
66
77# CHECK: Flags [
88# CHECK: EF_AMDGPU_MACH_AMDGCN_GFX803 (0x2A)
deps/lld/test/ELF/amdgpu-globals.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: amdgpu
22# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o
33# RUN: ld.lld -shared %t.o -o %t
4# RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s
4# RUN: llvm-readobj --sections --symbols -l %t | FileCheck %s
55
66.type glob0, @object
77.data
deps/lld/test/ELF/amdgpu-kernels.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: amdgpu
22# 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
4# RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s
4# RUN: llvm-readobj --sections --symbols -l %t | FileCheck %s
55
66.hsa_code_object_version 1,0
77.hsa_code_object_isa 7,0,0,"AMD","AMDGPU"
deps/lld/test/ELF/amdgpu-relocs.s+19-7
......@@ -2,7 +2,8 @@
22# RUN: llvm-mc -filetype=obj -triple=amdgcn--amdhsa -mcpu=fiji %s -o %t.o
33# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so
44# RUN: llvm-readobj -r %t.so | FileCheck %s
5# RUN: llvm-objdump -s %t.so | FileCheck %s --check-prefix=OBJDUMP
5# RUN: llvm-nm %t.so | FileCheck %s --check-prefix=NM
6# RUN: llvm-readelf -x .rodata -x nonalloc %t.so | FileCheck %s --check-prefix=HEX
67
78.text
89
......@@ -48,6 +49,9 @@ kernel0:
4849 .local local_var0
4950 .local local_var1
5051 .local local_var2
52 local_var0:
53 local_var1:
54 local_var2:
5155
5256# R_AMDGPU_ABS32:
5357.section nonalloc, "w", @progbits
......@@ -68,6 +72,7 @@ ptr:
6872 .type temp2, @object
6973 .local temp2
7074 .size temp2, 4
75 temp2:
7176
7277 .type ptr2, @object
7378 .globl ptr2
......@@ -89,7 +94,7 @@ foo:
8994# linker.
9095# CHECK: Relocations [
9196# CHECK: .rela.dyn {
92# CHECK-NEXT: R_AMDGPU_RELATIVE64 - 0x0
97# CHECK-NEXT: R_AMDGPU_RELATIVE64 - 0x3008
9398# CHECK-NEXT: R_AMDGPU_ABS64 common_var0 0x0
9499# CHECK-NEXT: R_AMDGPU_ABS64 common_var1 0x0
95100# CHECK-NEXT: R_AMDGPU_ABS64 common_var2 0x0
......@@ -109,9 +114,16 @@ foo:
109114# CHECK-NEXT: }
110115# CHECK-NEXT: ]
111116
112# OBJDUMP: Contents of section .rodata:
113# OBJDUMP: d0f8ffff ffffffff
117# NM: 0000000000003010 B common_var0
118# NM: 0000000000003410 B common_var1
119# NM: 0000000000003810 B common_var2
120# NM: 0000000000003008 d temp2
114121
115# OBJDUMP: Contents of section nonalloc:
116# OBJDUMP-NEXT: 0000 00000000 04480000 00000000 08440000
117# OBJDUMP-NEXT: 00000000 0c400000
122# temp2 - foo = 0x3008-0x768 = 0x28a0
123# HEX: section '.rodata':
124# HEX-NEXT: 0x00000768 a0280000 00000000
125
126# common_var2+4, common_var1+8, and common_var0+12.
127# HEX: section 'nonalloc':
128# HEX-NEXT: 0x00000000 00000000 14380000 00000000 18340000
129# HEX-NEXT: 0x00000010 00000000 1c300000
deps/lld/test/ELF/archive-fetch.s+8-1
......@@ -9,7 +9,14 @@
99# RUN: llvm-ar rcs %t.a %tfoo.o %tbar.o
1010
1111# 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
12# RUN: ld.lld %t.a %t.o -o %t
13# RUN: llvm-nm %t | FileCheck %s
14
15# RUN: ld.lld -shared %t.o -o %t.so
16# RUN: ld.lld %t.a %t.so -o %t
17# RUN: llvm-nm %t | FileCheck %s
18
19# CHECK: T foo
1320
1421_start:
1522callq foo
deps/lld/test/ELF/archive-no-index.s created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2# Tests error on archive file without a symbol table
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t.o %s
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t.archive.o %S/Inputs/archive.s
5# RUN: rm -f %t.a
6# RUN: llvm-ar crS %t.a %t.archive.o
7
8# RUN: not ld.lld -o /dev/null %t.o %t.a 2>&1 | FileCheck %s
9
10.globl _start
11_start:
12
13# CHECK: error: {{.*}}.a: archive has no index; run ranlib to add one
deps/lld/test/ELF/archive-thin-missing-member.s created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: x86
2
3# RUN: rm -f %t-no-syms.a
4# RUN: rm -f %t-syms.a
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
6# RUN: llvm-ar rcTS %t-no-syms.a %t.o
7# RUN: llvm-ar rcT %t-syms.a %t.o
8# RUN: rm %t.o
9
10# Test error when loading symbols from missing thin archive member.
11# RUN: not ld.lld %t-no-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
12# ERR1: {{.*}}-no-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
13
14# Test error when thin archive has symbol table but member is missing.
15# RUN: not ld.lld -m elf_amd64_fbsd %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
16# ERR2: {{.*}}-syms.a: could not get the buffer for the member defining symbol _start: '{{.*}}.o': {{[Nn]}}o such file or directory
17
18# Test error when thin archive is linked using --whole-archive but member is missing.
19# RUN: not ld.lld --whole-archive %t-syms.a -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR3
20# ERR3: {{.*}}-syms.a: could not get the buffer for a child of the archive: '{{.*}}.o': {{[Nn]}}o such file or directory
21
22.global _start
23_start:
24 nop
deps/lld/test/ELF/arm-abs32-dyn.s+12-3
......@@ -14,12 +14,19 @@ bar:
1414 .word foo
1515 .word bar
1616
17// In PIC mode, if R_ARM_TARGET1 represents R_ARM_ABS32 (the default), an
18// R_ARM_TARGET1 to a non-preemptable symbol also creates an R_ARM_RELATIVE in
19// a writable section.
20 .word bar(target1)
21
1722// RUN: ld.lld -shared -o %t.so %t.o
18// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s
23// RUN: llvm-readobj --symbols --dyn-relocations %t.so | FileCheck %s
24// RUN: llvm-readelf -x .data %t.so | FileCheck --check-prefix=HEX %s
1925
2026// CHECK: Dynamic Relocations {
21// CHECK-NEXT: 0x1004 R_ARM_RELATIVE
22// CHECK-NEXT: 0x1000 R_ARM_ABS32 foo 0x0
27// CHECK-NEXT: 0x2004 R_ARM_RELATIVE
28// CHECK-NEXT: 0x2008 R_ARM_RELATIVE
29// CHECK-NEXT: 0x2000 R_ARM_ABS32 foo 0x0
2330// CHECK-NEXT: }
2431
2532// CHECK: Symbols [
......@@ -30,3 +37,5 @@ bar:
3037// CHECK: Symbol {
3138// CHECK: Name: foo
3239// CHECK-NEXT: Value: 0x1000
40
41// HEX: 0x00002000 00000000 00100000 00100000
deps/lld/test/ELF/arm-attributes.s+3-3
......@@ -3,11 +3,11 @@
33// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2.o
44
55// RUN: ld.lld %t1.o %t2.o -o %t
6// RUN: llvm-readobj -arm-attributes %t | FileCheck %s
6// RUN: llvm-readobj --arm-attributes %t | FileCheck %s
77// RUN: ld.lld %t1.o %t2.o -shared -o %t2
8// RUN: llvm-readobj -arm-attributes %t2 | FileCheck %s
8// RUN: llvm-readobj --arm-attributes %t2 | FileCheck %s
99// RUN: ld.lld %t1.o %t2.o -r -o %t3
10// RUN: llvm-readobj -arm-attributes %t3 | FileCheck %s
10// RUN: llvm-readobj --arm-attributes %t3 | FileCheck %s
1111
1212// Check that we retain only 1 SHT_ARM_ATTRIBUTES section. At present we do not
1313// try and merge or use the contents of SHT_ARM_ATTRIBUTES sections. We just
deps/lld/test/ELF/arm-bl-v6-inrange.s+4
......@@ -28,9 +28,12 @@ _start:
2828thumbfunc:
2929 bx lr
3030// CHECK-THUMB: Disassembly of section .callee1:
31// CHECK-THUMB-EMPTY:
3132// CHECK-THUMB-NEXT: thumbfunc:
3233// CHECK-THUMB-NEXT: 100004: 70 47 bx lr
34// CHECK-THUMB-EMPTY:
3335// CHECK-THUMB-NEXT: Disassembly of section .caller:
36// CHECK-THUMB-EMPTY:
3437// CHECK-THUMB-NEXT: _start:
3538// CHECK-THUMB-NEXT: 500000: 00 f4 00 f8 bl #-4194304
3639// CHECK-THUMB-NEXT: 500004: ff f3 fe ef blx #4194300
......@@ -43,5 +46,6 @@ thumbfunc:
4346armfunc:
4447 bx lr
4548// CHECK-ARM: Disassembly of section .callee2:
49// CHECK-ARM-EMPTY:
4650// CHECK-ARM-NEXT: armfunc:
4751// CHECK-ARM-NEXT: 900004: 1e ff 2f e1 bx lr
deps/lld/test/ELF/arm-bl-v6.s+1
......@@ -26,6 +26,7 @@ _start:
2626 bx lr
2727
2828// CHECK-ARM1: Disassembly of section .text:
29// CHECK-ARM1-EMPTY:
2930// CHECK-ARM1-NEXT: _start:
3031// CHECK-ARM1-NEXT: 11000: 00 00 00 fa blx #0 <thumbfunc>
3132// CHECK-ARM1-NEXT: 11004: 1e ff 2f e1 bx lr
deps/lld/test/ELF/arm-blx.s+5
......@@ -74,16 +74,19 @@ callee_arm_high:
7474 bx lr
7575
7676// CHECK-THUMB: Disassembly of section .callee1:
77// CHECK-THUMB-EMPTY:
7778// CHECK-THUMB-NEXT: callee_low:
7879// CHECK-THUMB-NEXT: b4: 70 47 bx lr
7980// CHECK-THUMB: callee_low2:
8081// CHECK-THUMB-NEXT: b6: 70 47 bx lr
8182
8283// CHECK-ARM: Disassembly of section .callee2:
84// CHECK-ARM-EMPTY:
8385// CHECK-ARM-NEXT: callee_arm_low:
8486// CHECK-ARM-NEXT: 100: 1e ff 2f e1 bx lr
8587
8688// CHECK-ARM: Disassembly of section .caller:
89// CHECK-ARM-EMPTY:
8790// CHECK-ARM-NEXT: _start:
8891// CHECK-ARM-NEXT: 10000: 2b c0 ff fa blx #-65364 <callee_low>
8992// CHECK-ARM-NEXT: 10004: 2a c0 ff fa blx #-65368 <callee_low>
......@@ -104,11 +107,13 @@ callee_arm_high:
104107// CHECK-ARM-NEXT: 10038: 1e ff 2f e1 bx lr
105108
106109// CHECK-THUMB: Disassembly of section .callee3:
110// CHECK-THUMB-EMPTY:
107111// CHECK-THUMB: callee_high:
108112// CHECK-THUMB-NEXT: 10100: 70 47 bx lr
109113// CHECK-THUMB: callee_high2:
110114// CHECK-THUMB-NEXT: 10102: 70 47 bx lr
111115
112116// CHECK-ARM: Disassembly of section .callee4:
117// CHECK-ARM-EMPTY:
113118// CHECK-NEXT-ARM: callee_arm_high:
114119// CHECK-NEXT-ARM: 10200: 1e ff 2f e1 bx lr
deps/lld/test/ELF/arm-branch-rangethunk.s+2
......@@ -19,6 +19,7 @@ _start:
1919 beq too_far3
2020
2121// SHORT: Disassembly of section .text:
22// SHORT-EMPTY:
2223// SHORT-NEXT: _start:
2324// SHORT-NEXT: 20000: 01 00 00 eb bl #4 <__ARMv7ABSLongThunk_too_far1>
2425// SHORT-NEXT: 20004: 01 00 00 ea b #4 <__ARMv7ABSLongThunk_too_far2>
......@@ -31,6 +32,7 @@ _start:
3132// SHORT-NEXT: 20014: fd ff 7f ea b #33554420 <__ARMv7ABSLongThunk_too_far3+0x1fffffc>
3233
3334// LONG: Disassembly of section .text:
35// LONG-EMPTY:
3436// LONG-NEXT: _start:
3537// LONG-NEXT: 20000: 01 00 00 eb bl #4 <__ARMv7ABSLongThunk_too_far1>
3638// LONG-NEXT: 20004: 03 00 00 ea b #12 <__ARMv7ABSLongThunk_too_far2>
deps/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s+1
......@@ -22,6 +22,7 @@ _start:
2222 .space 32 * 1024 * 1024
2323
2424// CHECK: Disassembly of section .text:
25// CHECK-EMPTY:
2526// CHECK-NEXT: _start:
2627// CHECK-NEXT: 11000: 00 00 00 ea b #0 <__ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for>
2728// CHECK-NEXT: 11004: 02 00 00 eb bl #8 <__ARMv7ABSLongThunk_bar2>
deps/lld/test/ELF/arm-branch.s+1
......@@ -38,6 +38,7 @@ callee_high:
3838 bx lr
3939
4040// CHECK: Disassembly of section .caller:
41// CHECK-EMPTY:
4142// CHECK-NEXT: _start:
4243// S(callee_low) = 0xb4 P = 0x10000 A = -8 = -0xff54 = -65364
4344// CHECK-NEXT: 10000: 2b c0 ff eb bl #-65364 <callee_low>
deps/lld/test/ELF/arm-copy.s+3-2
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/relocation-copy-arm.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -soname fixed-length-string.so -o %t2.so
55// RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
6// RUN: llvm-readobj -S -r --expand-relocs --symbols %t3 | FileCheck %s
77// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CODE %s
88// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s
99
......@@ -65,6 +65,7 @@ _start:
6565// CHECK-NEXT: Section: .bss
6666
6767// CODE: Disassembly of section .text:
68// CODE-EMPTY:
6869// CODE-NEXT: _start:
6970// S(y) = 0x13000, A = 0
7071// (S + A) & 0x0000ffff = 0x3000 = #12288
......@@ -78,4 +79,4 @@ _start:
7879
7980// RODATA: Contents of section .rodata:
8081// S(z) = 0x13004
81// RODATA-NEXT: 10190 04300100
82// RODATA-NEXT: 101b0 04300100
deps/lld/test/ELF/arm-data-prel.s+9-13
......@@ -1,12 +1,11 @@
11// REQUIRES: arm
2// RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o %t.o
2// RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj --arm-add-build-attributes -o %t.o
33// RUN: echo "SECTIONS { \
44// RUN: .text : { *(.text) } \
55// RUN: .prel.test : { *(.ARM.exidx) } \
6// RUN: .prel.test.TEST1 : { *(.ARM.exidx.TEST1) } \
76// RUN: .TEST1 : { *(.TEST1) } } " > %t.script
87// RUN: ld.lld --script %t.script %t.o -o %t
9// RUN: llvm-readobj -s -sd %t | FileCheck --check-prefix=CHECK %s
8// RUN: llvm-readobj -S --section-data %t | FileCheck --check-prefix=CHECK %s
109
1110// The R_ARM_PREL31 relocation is used in by the .ARM.exidx exception tables
1211// bit31 of the place denotes whether the field is an inline table entry
......@@ -47,17 +46,14 @@ __aeabi_unwind_cpp_pr0:
4746// The expected value of the exception table is
4847// Word0 0 in bit 31, -4 encoded in 31-bit signed offset
4948// Word1 Inline table entry EHT Inline Personality Routine #0
50// CHECK: Name: .prel.test
51// CHECK: SectionData (
52// CHECK: 0000: FCFFFF7F B0B0B080
53// CHECK: )
54
55// The expected value of the exception table is
56// Word0 0 in bit 31, +8 encoded in 31-bit signed offset
57// Word1 Inline table entry EHT Inline Personality Routine #0
49// Word3 0 in bit 31, +10 encoded in 31-bit signed offset
50// Word4 Inline table entry EHT Inline Personality Routine #0
5851// set vsp = r11
5952// pop r11, r14
60// CHECK: Name: .prel.test.TEST1
53// Word5 Sentinel +18 EXIDX_CANTUNWIND
54
55// CHECK: Name: .prel.test
6156// CHECK: SectionData (
62// CHECK: 0000: 08000000 80849B80
57// CHECK: 0000: FCFFFF7F B0B0B080 10000000 80849B80
58// CHECK: 0010: 18000000 01000000
6359// CHECK: )
deps/lld/test/ELF/arm-data-relocs.s+2
......@@ -12,9 +12,11 @@ _start:
1212// S = 0x100, A = 0x24
1313// S + A = 0x124
1414// CHECK: Disassembly of section .R_ARM_ABS32POS:
15// CHECK-EMPTY:
1516// CHECK: 11000: 24 01 00 00
1617 .section .R_ARM_ABS32NEG, "ax",%progbits
1718 .word foo - 0x24
1819// S = 0x100, A = -0x24
1920// CHECK: Disassembly of section .R_ARM_ABS32NEG:
21// CHECK-EMPTY:
2022// CHECK: 11004: dc 00 00 00
deps/lld/test/ELF/arm-eabi-version.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
33// RUN: ld.lld -static %t.o -o %tout
4// RUN: llvm-readobj -file-headers %tout | FileCheck %s
4// RUN: llvm-readobj --file-headers %tout | FileCheck %s
55 .syntax unified
66 .text
77 .globl _start
deps/lld/test/ELF/arm-exidx-add-missing.s created+66
......@@ -0,0 +1,66 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi --arm-add-build-attributes %s -o %t
3// RUN: ld.lld %t --no-merge-exidx-entries -o %t2
4// RUN: llvm-objdump -s %t2 | FileCheck %s
5// RUN: ld.lld %t -o %t3
6// RUN: llvm-objdump -s %t3 | FileCheck %s -check-prefix=CHECK-MERGE
7
8// The ARM.exidx section is a table of 8-byte entries of the form:
9// | PREL31 Relocation to start of function | Unwinding information |
10// The range of addresses covered by the table entry is terminated by the
11// next table entry. This means that an executable section without a .ARM.exidx
12// section does not terminate the range of addresses. To fix this the linker
13// synthesises an EXIDX_CANTUNWIND entry for each section wihout a .ARM.exidx
14// section.
15
16 .syntax unified
17
18 // Expect inline unwind instructions
19 .section .text.01, "ax", %progbits
20 .global f1
21f1:
22 .fnstart
23 bx lr
24 .save {r7, lr}
25 .setfp r7, sp, #0
26 .fnend
27
28 // Expect no unwind information from assembler. The linker must
29 // synthesise an EXIDX_CANTUNWIND entry to prevent an exception
30 // thrown through f2 from matching against the unwind instructions
31 // for f1.
32 .section .text.02, "ax", %progbits
33 .global f2
34f2:
35 bx lr
36
37
38 // Expect 1 EXIDX_CANTUNWIND entry that can be merged into the linker
39 // generated EXIDX_CANTUNWIND as if the assembler had generated it.
40 .section .text.03, "ax",%progbits
41 .global f3
42f3:
43 .fnstart
44 bx lr
45 .cantunwind
46 .fnend
47
48 // Dummy implementation of personality routines to satisfy reference
49 // from exception tables, linker will generate EXIDX_CANTUNWIND.
50 .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
51 .global __aeabi_unwind_cpp_pr0
52__aeabi_unwind_cpp_pr0:
53 bx lr
54
55// f1, f2
56// CHECK: 100d4 2c0f0000 08849780 280f0000 01000000
57// f3, __aeabi_unwind_cpp_pr0
58// CHECK-NEXT: 100e4 240f0000 01000000 200f0000 01000000
59// sentinel
60// CHECK-NEXT: 100f4 1c0f0000 01000000
61
62// f1, (f2, f3, __aeabi_unwind_cpp_pr0)
63// CHECK-MERGE: 100d4 2c0f0000 08849780 280f0000 01000000
64// sentinel
65// CHECK-MERGE-NEXT: 100e4 2c0f0000 01000000
66
deps/lld/test/ELF/arm-exidx-canunwind.s+14-14
......@@ -1,6 +1,6 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 2>&1
2// RUN: llvm-mc -filetype=obj --arm-add-build-attributes -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2
44// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
55// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s
66// RUN: llvm-readobj --program-headers --sections %t2 | FileCheck -check-prefix=CHECK-PT %s
......@@ -53,6 +53,7 @@ _start:
5353 bx lr
5454
5555// CHECK: Disassembly of section .text:
56// CHECK-EMPTY:
5657// CHECK-NEXT: _start:
5758// CHECK-NEXT: 11000: 01 00 00 eb bl #4 <func1>
5859// CHECK-NEXT: 11004: 01 00 00 eb bl #4 <func2>
......@@ -66,15 +67,14 @@ _start:
6667// CHECK: __aeabi_unwind_cpp_pr0:
6768// CHECK-NEXT: 11018: 1e ff 2f e1 bx lr
6869
69// CHECK-EXIDX: Contents of section .ARM.exidx:
70// 100d4 + f38 = 1100c = func1 (inline unwinding data)
71// 100dc + f34 = 11010 = func2 (100e0 + c = 100ec = .ARM.extab entry)
72// CHECK-EXIDX-NEXT: 100d4 380f0000 08849780 340f0000 0c000000
73// 100e4 + f30 = 11014 = terminate = func2 + sizeof(func2)
74// CHECK-EXIDX-NEXT: 100e4 300f0000 01000000
75// CHECK-EXIDX-NEXT: Contents of section .ARM.extab:
76// 100ec + f28 = 11014 = __gxx_personality_v0
77// CHECK-EXIDX-NEXT: 100ec 280f0000 b0b0b000 00000000
70// 100d4 + f2c = 11000 = main (linker generated cantunwind)
71// 100dc + f30 = 1100c = func1 (inline unwinding data)
72// CHECK-EXIDX: 100d4 2c0f0000 01000000 300f0000 08849780
73// 100e4 + f2c = 11010 = func2 (100e8 + 14 = 100fc = .ARM.extab entry)
74// 100ec + f28 = 11014 = __gcc_personality_v0 (linker generated cantunwind)
75// CHECK-EXIDX-NEXT: 100e4 2c0f0000 14000000 280f0000 01000000
76// 100f4 + f28 = 1101c = sentinel
77// CHECK-EXIDX-NEXT: 100f4 280f0000 01000000
7878
7979// CHECK-PT: Name: .ARM.exidx
8080// CHECK-PT-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
......@@ -84,14 +84,14 @@ _start:
8484// CHECK-PT-NEXT: ]
8585// CHECK-PT-NEXT: Address: 0x100D4
8686// CHECK-PT-NEXT: Offset: 0xD4
87// CHECK-PT-NEXT: Size: 24
87// CHECK-PT-NEXT: Size: 40
8888
8989// CHECK-PT: Type: PT_ARM_EXIDX (0x70000001)
9090// CHECK-PT-NEXT: Offset: 0xD4
9191// CHECK-PT-NEXT: VirtualAddress: 0x100D4
9292// CHECK-PT-NEXT: PhysicalAddress: 0x100D4
93// CHECK-PT-NEXT: FileSize: 24
94// CHECK-PT-NEXT: MemSize: 24
93// CHECK-PT-NEXT: FileSize: 40
94// CHECK-PT-NEXT: MemSize: 40
9595// CHECK-PT-NEXT: Flags [ (0x4)
9696// CHECK-PT-NEXT: PF_R (0x4)
9797// CHECK-PT-NEXT: ]
deps/lld/test/ELF/arm-exidx-dedup.s+14-11
......@@ -1,27 +1,29 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj --arm-add-build-attributes -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t --no-merge-exidx-entries -o %t2
44// RUN: llvm-objdump -s %t2 | FileCheck --check-prefix CHECK-DUPS %s
55// RUN: ld.lld %t -o %t3
66// RUN: llvm-objdump -s %t3 | FileCheck %s
7
78// Test that lld can at least remove duplicate .ARM.exidx sections. A more
89// fine grained implementation will be able to remove duplicate entries within
910// a .ARM.exidx section.
1011
1112// With duplicate entries
1213// CHECK-DUPS: Contents of section .ARM.exidx:
13// CHECK-DUPS-NEXT: 100d4 2c0f0000 01000000 280f0000 01000000
14// CHECK-DUPS-NEXT: 100e4 240f0000 01000000 200f0000 01000000
15// CHECK-DUPS-NEXT: 100f4 1c0f0000 08849780 180f0000 08849780
16// CHECK-DUPS-NEXT: 10104 140f0000 08849780 100f0000 14000000
17// CHECK-DUPS-NEXT: 10114 0c0f0000 18000000 080f0000 01000000
14// CHECK-DUPS-NEXT: 100d4 2c0f0000 01000000 280f0000 01000000
15// CHECK-DUPS-NEXT: 100e4 240f0000 01000000 200f0000 01000000
16// CHECK-DUPS-NEXT: 100f4 1c0f0000 08849780 180f0000 08849780
17// CHECK-DUPS-NEXT: 10104 140f0000 08849780 100f0000 24000000
18// CHECK-DUPS-NEXT: 10114 0c0f0000 28000000 080f0000 01000000
19// CHECK-DUPS-NEXT: 10124 040f0000 01000000 000f0000 01000000
1820// CHECK-DUPS-NEXT: Contents of section .ARM.extab:
1921
2022// After duplicate entry removal
2123// CHECK: Contents of section .ARM.exidx:
22// CHECK-NEXT: 100d4 2c0f0000 01000000 340f0000 08849780
23// CHECK-NEXT: 100e4 380f0000 14000000 340f0000 18000000
24// CHECK-NEXT: 100f4 300f0000 01000000
24// CHECK-NEXT: 100d4 2c0f0000 01000000 340f0000 08849780
25// CHECK-NEXT: 100e4 380f0000 1c000000 340f0000 20000000
26// CHECK-NEXT: 100f4 300f0000 01000000 300f0000 01000000
2527// CHECK-NEXT: Contents of section .ARM.extab:
2628 .syntax unified
2729
......@@ -113,8 +115,9 @@ f8:
113115 .long 0
114116 .fnend
115117
116 // Dummy implementation of personality routines to satisfy reference from
117 // exception tables
118// Dummy implementation of personality routines to satisfy reference from
119// exception tables
120// Expect Linker generated EXIDX_CANTUNWIND tables
118121 .section .text.__gcc_personality_v0, "ax", %progbits
119122 .global __gxx_personality_v0
120123__gxx_personality_v0:
deps/lld/test/ELF/arm-exidx-discard.s+5-2
......@@ -2,12 +2,15 @@
22// RUN: llvm-mc -filetype=obj -triple arm-gnu-linux-eabi -mcpu cortex-a7 -arm-add-build-attributes %s -o %t.o
33// RUN: echo "ENTRY(__entrypoint) SECTIONS { . = 0x10000; .text : { *(.text .text.*) } /DISCARD/ : { *(.ARM.exidx*) *(.gnu.linkonce.armexidx.*) } }" > %t.script
44// RUN: ld.lld -T %t.script %t.o -o %t.elf 2>&1
5// RUN: llvm-readobj -sections %t.elf | FileCheck %s
5// RUN: llvm-readobj --sections %t.elf | FileCheck %s
66
77.globl __entrypoint
88__entrypoint:
9.fnstart
910 bx lr
10
11 .save {r7, lr}
12 .setfp r7, sp, #0
13 .fnend
1114// Check that .ARM.exidx/.gnu.linkonce.armexidx
1215// are correctly removed if they were added.
1316// CHECK-NOT: .ARM.exidx
deps/lld/test/ELF/arm-exidx-emit-relocs.s created+71
......@@ -0,0 +1,71 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj --arm-add-build-attributes -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld --emit-relocs %t -o %t2
4// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
5// RUN: llvm-readelf --relocs %t2 | FileCheck -check-prefix=CHECK-RELOCS %s
6
7// LLD does not support --emit-relocs for .ARM.exidx sections as the relocations
8// from synthetic table entries won't be represented. Given the known use cases
9// of --emit-relocs, relocating kernels, and binary analysis, the former doesn't
10// use exceptions and the latter can derive the relocations from the table if
11// they need them.
12 .syntax unified
13 // Will produce an ARM.exidx entry with inline unwinding instructions
14 .section .text.func1, "ax",%progbits
15 .global func1
16func1:
17 .fnstart
18 bx lr
19 .save {r7, lr}
20 .setfp r7, sp, #0
21 .fnend
22
23 .syntax unified
24 .section .text.func2, "ax",%progbits
25// A function with the same inline unwinding instructions, expect merge.
26 .global func2
27func2:
28 .fnstart
29 bx lr
30 .save {r7, lr}
31 .setfp r7, sp, #0
32 .fnend
33
34 .section .text.25, "ax", %progbits
35 .global func25
36func25:
37 .fnstart
38 bx lr
39 .cantunwind
40 .fnend
41
42 .section .text.26, "ax", %progbits
43 .global func26
44func26:
45 .fnstart
46 bx lr
47 .cantunwind
48 .fnend
49
50 .syntax unified
51 .section .text.func3, "ax",%progbits
52// A function with the same inline unwinding instructions, expect merge.
53 .global func3
54func3:
55 .fnstart
56 bx lr
57 .save {r7, lr}
58 .setfp r7, sp, #0
59 .fnend
60
61 .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
62 .global __aeabi_unwind_cpp_pr0
63__aeabi_unwind_cpp_pr0:
64 bx lr
65
66// CHECK: Contents of section .ARM.exidx:
67// CHECK-NEXT: 100d4 2c0f0000 08849780 2c0f0000 01000000
68// CHECK-NEXT: 100e4 2c0f0000 08849780 280f0000 01000000
69// CHECK-NEXT: 100f4 240f0000 01000000
70
71// CHECK-RELOCS-NOT: Relocation section '.rel.ARM.exidx'
deps/lld/test/ELF/arm-exidx-gc.s+13-11
......@@ -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 -filetype=obj --arm-add-build-attributes -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t --no-merge-exidx-entries -o %t2 --gc-sections 2>&1
44// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
55// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s
......@@ -91,6 +91,7 @@ _start:
9191// routines are kept alive by references from live .ARM.exidx and .ARM.extab
9292// sections
9393// CHECK: Disassembly of section .text:
94// CHECK-EMPTY:
9495// CHECK-NEXT: _start:
9596// CHECK-NEXT: 11000: 01 00 00 eb bl #4 <func1>
9697// CHECK-NEXT: 11004: 01 00 00 eb bl #4 <func2>
......@@ -111,14 +112,15 @@ _start:
111112// CHECK-NOT: __gxx_personality_v1
112113
113114// CHECK-EXIDX: Contents of section .ARM.exidx:
114// 100d4 + f38 = 1100c = func1
115// 100dc + f34 = 11010 = func2 (100e0 + 1c = 100fc = .ARM.extab)
116// CHECK-EXIDX-NEXT: 100d4 380f0000 08849780 340f0000 1c000000
117// 100e4 + f30 = 11014 = __gxx_personality_v0
118// 100ec + f2c = 11018 = __aeabi_unwind_cpp_pr0
119// CHECK-EXIDX-NEXT: 100e4 300f0000 01000000 2c0f0000 01000000
120// 100f4 + f28 = 1101c = __aeabi_unwind_cpp_pr0 + sizeof(__aeabi_unwind_cpp_pr0)
121// CHECK-EXIDX-NEXT: 100f4 280f0000 01000000
115// 100d4 + f2c = 11000
116// 100dc + f30 = 1100c = func1
117// CHECK-EXIDX-NEXT: 100d4 2c0f0000 01000000 300f0000 08849780
118// 100e4 + f2c = 11010 = func2 (100e8 + 1c = 10104 = .ARM.extab)
119// 100ec + f28 = 11014 = __gxx_personality_v0
120// CHECK-EXIDX-NEXT: 100e4 2c0f0000 1c000000 280f0000 01000000
121// 100f4 + f24 = 11018 = __aeabi_unwind_cpp_pr0
122// 100fc + f20 = 1101c = __aeabi_unwind_cpp_pr0 + sizeof(__aeabi_unwind_cpp_pr0)
123// CHECK-EXIDX-NEXT: 100f4 240f0000 01000000 200f0000 01000000
122124// CHECK-EXIDX-NEXT: Contents of section .ARM.extab:
123// 100fc + f18 = 11014 = __gxx_personality_v0
124// CHECK-EXIDX-NEXT: 100fc 180f0000 b0b0b000
125// 10104 + f10 = 11014 = __gxx_personality_v0
126// CHECK-EXIDX-NEXT: 10104 100f0000 b0b0b000
deps/lld/test/ELF/arm-exidx-link.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
33// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -s %t.so | FileCheck %s
4// RUN: llvm-readobj -S %t.so | FileCheck %s
55
66// CHECK: Name: .ARM.exidx
77// CHECK-NEXT: Type: SHT_ARM_EXIDX
deps/lld/test/ELF/arm-exidx-order.s+11
......@@ -54,6 +54,7 @@ f3:
5454// Check default no linker script order.
5555
5656// CHECK: Disassembly of section .text:
57// CHECK-EMPTY:
5758// CHECK: _start:
5859// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
5960// CHECK: f1:
......@@ -67,12 +68,15 @@ f3:
6768// CHECK: func5:
6869// CHECK-NEXT: 11014: 1e ff 2f e1 bx lr
6970// CHECK: Disassembly of section .func1:
71// CHECK-EMPTY:
7072// CHECK-NEXT: func1:
7173// CHECK-NEXT: 11018: 1e ff 2f e1 bx lr
7274// CHECK: Disassembly of section .func2:
75// CHECK-EMPTY:
7376// CHECK-NEXT: func2:
7477// CHECK-NEXT: 1101c: 1e ff 2f e1 bx lr
7578// CHECK: Disassembly of section .func3:
79// CHECK-EMPTY:
7680// CHECK-NEXT: func3:
7781// CHECK-NEXT: 11020: 1e ff 2f e1 bx lr
7882
......@@ -128,6 +132,7 @@ f3:
128132// the .text section but before the orphan sections
129133
130134// CHECK-SCRIPT: Disassembly of section .text:
135// CHECK-SCRIPT-EMPTY:
131136// CHECK-SCRIPT-NEXT: func4:
132137// CHECK-SCRIPT-NEXT: 11000: 1e ff 2f e1 bx lr
133138// CHECK-SCRIPT: func5:
......@@ -140,13 +145,19 @@ f3:
140145// CHECK-SCRIPT-NEXT: 11010: 1e ff 2f e1 bx lr
141146// CHECK-SCRIPT: f3:
142147// CHECK-SCRIPT-NEXT: 11014: 1e ff 2f e1 bx lr
148// CHECK-SCRIPT-EMPTY:
143149// CHECK-SCRIPT-NEXT: Disassembly of section .func1:
150// CHECK-SCRIPT-EMPTY:
144151// CHECK-SCRIPT-NEXT: func1:
145152// CHECK-SCRIPT-NEXT: 11018: 1e ff 2f e1 bx lr
153// CHECK-SCRIPT-EMPTY:
146154// CHECK-SCRIPT-NEXT: Disassembly of section .func2:
155// CHECK-SCRIPT-EMPTY:
147156// CHECK-SCRIPT-NEXT: func2:
148157// CHECK-SCRIPT-NEXT: 1101c: 1e ff 2f e1 bx lr
158// CHECK-SCRIPT-EMPTY:
149159// CHECK-SCRIPT-NEXT: Disassembly of section .func3:
160// CHECK-SCRIPT-EMPTY:
150161// CHECK-SCRIPT-NEXT: func3:
151162// CHECK-SCRIPT-NEXT: 11020: 1e ff 2f e1 bx lr
152163
deps/lld/test/ELF/arm-exidx-output.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld %t -o %t2 2>&1
4// RUN: llvm-readobj -sections %t2 | FileCheck %s
4// RUN: llvm-readobj --sections %t2 | FileCheck %s
55
66// Check that only a single .ARM.exidx output section is created when
77// there are input sections of the form .ARM.exidx.<section-name>. The
deps/lld/test/ELF/arm-exidx-relocatable.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind
44// Check that relocatable link maintains SHF_LINK_ORDER
55// RUN: ld.lld -r %t %tcantunwind -o %t4 2>&1
6// RUN: llvm-readobj -s %t4 | FileCheck %s
6// RUN: llvm-readobj -S %t4 | FileCheck %s
77
88// Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set
99// with the sh_link containing the section index of the executable section
deps/lld/test/ELF/arm-exidx-sentinel-norelocatable.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o %t.o
33// RUN: ld.lld -r %t.o -o %t
4// RUN: llvm-readobj -s %t | FileCheck %s
4// RUN: llvm-readobj -S %t | FileCheck %s
55// Check that when doing a relocatable link we don't add a terminating entry
66// to the .ARM.exidx section
77 .syntax unified
deps/lld/test/ELF/arm-exidx-shared.s+5-5
......@@ -1,8 +1,8 @@
11// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -arm-add-build-attributes -triple=armv7a-none-linux-gnueabi %s -o %t
33// RUN: ld.lld --hash-style=sysv %t --shared -o %t2 2>&1
44// RUN: llvm-readobj --relocations %t2 | FileCheck %s
5// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXTAB %s
5// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck --check-prefix=CHECK-EXTAB-NEXT %s
66
77// Check that the relative R_ARM_PREL31 relocation can access a PLT entry
88// for when the personality routine is referenced from a shared library.
......@@ -38,8 +38,8 @@ __aeabi_unwind_cpp_pr0:
3838
3939// CHECK: Relocations [
4040// CHECK-NEXT: Section {{.*}} .rel.plt {
41// CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0
41// CHECK-NEXT: 0x300C R_ARM_JUMP_SLOT __gxx_personality_v0
4242
4343// CHECK-EXTAB: Contents of section .ARM.extab:
44// 0x0210 + 0x0e20 = 0x1030 = __gxx_personality_v0(PLT)
45// CHECK-EXTAB-NEXT: 0210 200e0000 b0b0b000 00000000
44// 0x0238 + 0xdf8 = 0x1030 = __gxx_personality_v0(PLT)
45// CHECK-EXTAB-NEXT: 0238 f80d0000 b0b0b000 00000000
deps/lld/test/ELF/arm-exidx-synthetic-link.s created+37
......@@ -0,0 +1,37 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -arm-add-build-attributes -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -S %t.so | FileCheck %s
5
6// Test that when all the .ARM.exidx sections are merged into a single
7// synthetic EXIDX_CANTUNWIND entry we can still set the SHF_LINK_ORDER
8// link.
9 .syntax unified
10 .section .text.1, "ax", %progbits
11 .globl f1
12 .type f1, %function
13f1:
14 bx lr
15
16 .section .text.2, "ax", %progbits
17 .globl f2
18 .type f2, %function
19f2:
20 .fnstart
21 bx lr
22 .cantunwind
23 .fnend
24
25// CHECK: Name: .ARM.exidx
26// CHECK-NEXT: Type: SHT_ARM_EXIDX
27// CHECK-NEXT: Flags [
28// CHECK-NEXT: SHF_ALLOC
29// CHECK-NEXT: SHF_LINK_ORDER
30// CHECK-NEXT: ]
31// CHECK-NEXT: Address:
32// CHECK-NEXT: Offset:
33// CHECK-NEXT: Size:
34// CHECK-NEXT: Link: [[INDEX:.*]]
35
36// CHECK: Index: [[INDEX]]
37// CHECK-NEXT: Name: .text
deps/lld/test/ELF/arm-extreme-range-pi-thunk.s+4
......@@ -32,6 +32,7 @@ high:
3232// ARMv7a instructions and relocations.
3333
3434// CHECK: Disassembly of section .text_low:
35// CHECK-EMPTY:
3536// CHECK-NEXT: _start:
3637// CHECK-NEXT: 130: 00 00 00 eb bl #0 <__ARMV7PILongThunk_high>
3738// CHECK-NEXT: 134: 1e ff 2f e1 bx lr
......@@ -44,6 +45,7 @@ high:
4445// CHECK-NEXT: 144: 1c ff 2f e1 bx r12
4546
4647// CHECK: Disassembly of section .text_high:
48// CHECK-EMPTY:
4749// CHECK-NEXT: high:
4850// CHECK-NEXT: f0000000: 00 00 00 eb bl #0 <__ARMV7PILongThunk__start>
4951// CHECK-NEXT: f0000004: 1e ff 2f e1 bx lr
......@@ -57,6 +59,7 @@ high:
5759
5860// Thumbv7a instructions and relocations
5961// CHECK-THUMB: Disassembly of section .text_low:
62// CHECK-THUMB-EMPTY:
6063// CHECK-THUMB-NEXT: _start:
6164// CHECK-THUMB-NEXT: 130: 00 f0 02 f8 bl #4
6265// CHECK-THUMB-NEXT: 134: 70 47 bx lr
......@@ -70,6 +73,7 @@ high:
7073// CHECK-THUMB-NEXT: 142: 60 47 bx r12
7174
7275// CHECK-THUMB: Disassembly of section .text_high:
76// CHECK-THUMB-EMPTY:
7377// CHECK-THUMB-NEXT: high:
7478// CHECK-THUMB-NEXT: f0000000: 00 f0 02 f8 bl #4
7579// CHECK-THUMB-NEXT: f0000004: 70 47 bx lr
deps/lld/test/ELF/arm-force-pi-thunk.s+2
......@@ -31,6 +31,7 @@ low_target2:
3131 bl high_target2
3232
3333// CHECK: Disassembly of section .text_low:
34// CHECK-EMPTY:
3435// CHECK-NEXT: _start:
3536// CHECK-NEXT: 94: 70 47 bx lr
3637// CHECK: low_target:
......@@ -69,6 +70,7 @@ high_target2:
6970 bl low_target2
7071
7172// CHECK: Disassembly of section .text_high:
73// CHECK-EMPTY:
7274// CHECK-NEXT: high_target:
7375// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4
7476// CHECK-NEXT: 2000004: 00 f0 06 f8 bl #12
deps/lld/test/ELF/arm-fpic-got.s+7-6
......@@ -1,8 +1,8 @@
11// REQUIRES: arm
22// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
33// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -s %t | FileCheck %s
5// RUN: llvm-readobj -s -symbols %t | FileCheck -check-prefix=SYMBOLS %s
4// RUN: llvm-readobj -S %t | FileCheck %s
5// RUN: llvm-readobj -S --symbols %t | FileCheck -check-prefix=SYMBOLS %s
66// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s
77
88// Test the R_ARM_GOT_PREL relocation
......@@ -36,7 +36,7 @@ val:
3636// CHECK-NEXT: SHF_ALLOC
3737// CHECK-NEXT: SHF_WRITE
3838// CHECK-NEXT: ]
39// CHECK-NEXT: Address: 0x13000
39// CHECK-NEXT: Address: 0x12000
4040// CHECK-NEXT: Offset:
4141// CHECK-NEXT: Size: 4
4242// CHECK-NEXT: Link:
......@@ -45,7 +45,7 @@ val:
4545// CHECK-NEXT: EntrySize:
4646
4747// SYMBOLS: Name: val
48// SYMBOLS-NEXT: Value: 0x12000
48// SYMBOLS-NEXT: Value: 0x13000
4949// SYMBOLS-NEXT: Size: 4
5050// SYMBOLS-NEXT: Binding: Global
5151// SYMBOLS-NEXT: Type: Object
......@@ -53,11 +53,12 @@ val:
5353// SYMBOLS-NEXT: Section: .data
5454
5555// CODE: Disassembly of section .text:
56// CODE-EMPTY:
5657// CODE-NEXT: _start:
5758// CODE-NEXT: 11000: 08 00 9f e5 ldr r0, [pc, #8]
5859// CODE-NEXT: 11004: 00 00 9f e7 ldr r0, [pc, r0]
5960// CODE-NEXT: 11008: 00 00 90 e5 ldr r0, [r0]
6061// CODE-NEXT: 1100c: 1e ff 2f e1 bx lr
6162// CODE: $d.1:
62// 0x11004 + 0x1ff4 + 8 = 0x13000 = .got
63// CODE-NEXT: 11010: f4 1f 00 00
63// 0x11004 + 0x0ff4 + 8 = 0x12000 = .got
64// CODE-NEXT: 11010: f4 0f 00 00
deps/lld/test/ELF/arm-gnu-ifunc-nosym.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
33// RUN: ld.lld -static %t.o -o %tout
4// RUN: llvm-readobj -symbols %tout | FileCheck %s
4// RUN: llvm-readobj --symbols %tout | FileCheck %s
55
66// Check that no __rel_iplt_end/__rel_iplt_start
77// appear in symtab if there are no references to them.
deps/lld/test/ELF/arm-gnu-ifunc-plt.s+19-16
......@@ -5,30 +5,31 @@
55// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout
66// RUN: llvm-objdump -triple=armv7a-linux-gnueabihf -d %tout | FileCheck %s --check-prefix=DISASM
77// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
8// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
8// RUN: llvm-readobj -r --dynamic-table %tout | FileCheck %s
99
1010// Check that the IRELATIVE relocations are last in the .got
1111// CHECK: Relocations [
1212// CHECK-NEXT: Section (4) .rel.dyn {
13// CHECK-NEXT: 0x13078 R_ARM_GLOB_DAT bar2 0x0
14// CHECK-NEXT: 0x1307C R_ARM_GLOB_DAT zed2 0x0
15// CHECK-NEXT: 0x13080 R_ARM_IRELATIVE - 0x0
16// CHECK-NEXT: 0x13084 R_ARM_IRELATIVE - 0x0
13// CHECK-NEXT: 0x12078 R_ARM_GLOB_DAT bar2 0x0
14// CHECK-NEXT: 0x1207C R_ARM_GLOB_DAT zed2 0x0
15// CHECK-NEXT: 0x12080 R_ARM_IRELATIVE - 0x0
16// CHECK-NEXT: 0x12084 R_ARM_IRELATIVE - 0x0
1717// CHECK-NEXT: }
1818// CHECK-NEXT: Section (5) .rel.plt {
19// CHECK-NEXT: 0x1200C R_ARM_JUMP_SLOT bar2 0x0
20// CHECK-NEXT: 0x12010 R_ARM_JUMP_SLOT zed2 0x0
19// CHECK-NEXT: 0x1300C R_ARM_JUMP_SLOT bar2 0x0
20// CHECK-NEXT: 0x13010 R_ARM_JUMP_SLOT zed2 0x0
2121// CHECK-NEXT: }
2222// CHECK-NEXT: ]
2323
2424// Check that the GOT entries refer back to the ifunc resolver
25// GOTPLT: Contents of section .got.plt:
26// GOTPLT-NEXT: 12000 00000000 00000000 00000000 20100100
27// GOTPLT-NEXT: 12010 20100100
2825// GOTPLT: Contents of section .got:
29// GOTPLT-NEXT: 13078 00000000 00000000 00100100 04100100
26// GOTPLT-NEXT: 12078 00000000 00000000 00100100 04100100
27// GOTPLT: Contents of section .got.plt:
28// GOTPLT-NEXT: 13000 00000000 00000000 00000000 20100100
29// GOTPLT-NEXT: 13010 20100100
3030
3131// DISASM: Disassembly of section .text:
32// DISASM-EMPTY:
3233// DISASM-NEXT: foo:
3334// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr
3435// DISASM: bar:
......@@ -41,11 +42,13 @@
4142// DISASM-NEXT: 11014: 04 00 00 00 .word 0x00000004
4243// DISASM: 11018: 08 00 00 eb bl #32
4344// DISASM-NEXT: 1101c: 0b 00 00 eb bl #44
45// DISASM-EMPTY:
4446// DISASM-NEXT: Disassembly of section .plt:
47// DISASM-EMPTY:
4548// DISASM-NEXT: $a:
4649// DISASM-NEXT: 11020: 04 e0 2d e5 str lr, [sp, #-4]!
4750// DISASM-NEXT: 11024: 00 e6 8f e2 add lr, pc, #0, #12
48// DISASM-NEXT: 11028: 00 ea 8e e2 add lr, lr, #0, #20
51// DISASM-NEXT: 11028: 01 ea 8e e2 add lr, lr, #4096
4952// DISASM-NEXT: 1102c: dc ff be e5 ldr pc, [lr, #4060]!
5053// DISASM: $d:
5154// DISASM-NEXT: 11030: d4 d4 d4 d4 .word 0xd4d4d4d4
......@@ -54,25 +57,25 @@
5457// DISASM-NEXT: 1103c: d4 d4 d4 d4 .word 0xd4d4d4d4
5558// DISASM: $a:
5659// DISASM-NEXT: 11040: 00 c6 8f e2 add r12, pc, #0, #12
57// DISASM-NEXT: 11044: 00 ca 8c e2 add r12, r12, #0, #20
60// DISASM-NEXT: 11044: 01 ca 8c e2 add r12, r12, #4096
5861// DISASM-NEXT: 11048: c4 ff bc e5 ldr pc, [r12, #4036]!
5962// DISASM: $d:
6063// DISASM-NEXT: 1104c: d4 d4 d4 d4 .word 0xd4d4d4d4
6164// DISASM: $a:
6265// DISASM-NEXT: 11050: 00 c6 8f e2 add r12, pc, #0, #12
63// DISASM-NEXT: 11054: 00 ca 8c e2 add r12, r12, #0, #20
66// DISASM-NEXT: 11054: 01 ca 8c e2 add r12, r12, #4096
6467// DISASM-NEXT: 11058: b8 ff bc e5 ldr pc, [r12, #4024]!
6568// DISASM: $d:
6669// DISASM-NEXT: 1105c: d4 d4 d4 d4 .word 0xd4d4d4d4
6770// DISASM: $a:
6871// DISASM-NEXT: 11060: 00 c6 8f e2 add r12, pc, #0, #12
69// DISASM-NEXT: 11064: 02 ca 8c e2 add r12, r12, #8192
72// DISASM-NEXT: 11064: 01 ca 8c e2 add r12, r12, #4096
7073// DISASM-NEXT: 11068: 18 f0 bc e5 ldr pc, [r12, #24]!
7174// DISASM: $d:
7275// DISASM-NEXT: 1106c: d4 d4 d4 d4 .word 0xd4d4d4d4
7376// DISASM: $a:
7477// DISASM-NEXT: 11070: 00 c6 8f e2 add r12, pc, #0, #12
75// DISASM-NEXT: 11074: 02 ca 8c e2 add r12, r12, #8192
78// DISASM-NEXT: 11074: 01 ca 8c e2 add r12, r12, #4096
7679// DISASM-NEXT: 11078: 0c f0 bc e5 ldr pc, [r12, #12]!
7780// DISASM: $d:
7881// DISASM-NEXT: 1107c: d4 d4 d4 d4 .word 0xd4d4d4d4
deps/lld/test/ELF/arm-gnu-ifunc.s+4-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
33// RUN: ld.lld -static %t.o -o %tout
44// RUN: llvm-objdump -triple armv7a-none-linux-gnueabi -d %tout | FileCheck %s --check-prefix=DISASM
5// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
5// RUN: llvm-readobj -r --symbols --sections %tout | FileCheck %s
66 .syntax unified
77 .text
88 .type foo STT_GNU_IFUNC
......@@ -113,6 +113,7 @@ _start:
113113// CHECK-NEXT: }
114114
115115// DISASM: Disassembly of section .text:
116// DISASM-EMPTY:
116117// DISASM-NEXT: foo:
117118// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr
118119// DISASM: bar:
......@@ -126,7 +127,9 @@ _start:
126127// 1 * 65536 + 260 = 0x10104 __rel_iplt_end
127128// DISASM-NEXT: 11018: 04 01 00 e3 movw r0, #260
128129// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1
130// DISASM-EMPTY:
129131// DISASM-NEXT: Disassembly of section .plt:
132// DISASM-EMPTY:
130133// DISASM-NEXT: $a:
131134// DISASM-NEXT: 11020: 00 c6 8f e2 add r12, pc, #0, #12
132135// DISASM-NEXT: 11024: 00 ca 8c e2 add r12, r12, #0, #20
deps/lld/test/ELF/arm-got-relative.s+2-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc -position-independent -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
33// RUN: ld.lld --hash-style=sysv %t.o -shared -o %t
4// RUN: llvm-readobj -s -symbols -dyn-relocations %t | FileCheck %s
4// RUN: llvm-readobj -S --symbols --dyn-relocations %t | FileCheck %s
55// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s
66 .syntax unified
77 .text
......@@ -41,6 +41,7 @@ function:
4141// CHECK-NEXT: Section: .got
4242
4343// CODE: Disassembly of section .text:
44// CODE-EMPTY:
4445// CODE-NEXT: _start:
4546// CODE-NEXT: 1000: 08 30 9f e5 ldr r3, [pc, #8]
4647// CODE-NEXT: 1004: 08 20 9f e5 ldr r2, [pc, #8]
deps/lld/test/ELF/arm-gotoff.s+2-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t.o
33// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -s -r -t %t | FileCheck %s
4// RUN: llvm-readobj -S -r --symbols %t | FileCheck %s
55// RUN: llvm-objdump -triple=armv7a-linux-gnueabi -d %t | FileCheck --check-prefix=DISASM %s
66
77// Test the R_ARM_GOTOFF32 relocation
......@@ -53,6 +53,7 @@
5353// CHECK-NEXT: Section: .bss
5454
5555// DISASM: Disassembly of section .text:
56// DISASM-EMPTY:
5657// DISASM-NEXT :_start:
5758// DISASM-NEXT 11000: 1e ff 2f e1 bx lr
5859// Offset 0 from .got = bar
deps/lld/test/ELF/arm-icf-exidx.s+1
......@@ -23,6 +23,7 @@ __aeabi_unwind_cpp_pr0:
2323 bx lr
2424
2525// CHECK: Disassembly of section .text:
26// CHECK-EMPTY:
2627// CHECK-NEXT: g:
2728// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
2829// CHECK: __aeabi_unwind_cpp_pr0:
deps/lld/test/ELF/arm-mov-relocs.s+2
......@@ -18,6 +18,7 @@ _start:
1818 movw r3, :lower16:label3
1919 movw r4, :lower16:label3 + 4
2020// CHECK: Disassembly of section .R_ARM_MOVW_ABS_NC
21// CHECK-EMPTY:
2122// CHECK: movw r0, #0
2223// CHECK: movw r1, #4
2324// CHECK: movw r2, #12
......@@ -30,6 +31,7 @@ _start:
3031 movt r3, :upper16:label3
3132 movt r4, :upper16:label3 + 4
3233// CHECK: Disassembly of section .R_ARM_MOVT_ABS
34// CHECK-EMPTY:
3335// CHECK: movt r0, #2
3436// CHECK: movt r1, #2
3537// CHECK: movt r2, #2
deps/lld/test/ELF/arm-pie-relative.s+2-2
......@@ -19,7 +19,7 @@ sym:
1919
2020// CHECK: Relocations [
2121// CHECK-NEXT: Section (4) .rel.dyn {
22// CHECK-NEXT: 0x3058 R_ARM_RELATIVE
22// CHECK-NEXT: 0x2058 R_ARM_RELATIVE
2323
2424// GOT: Contents of section .got:
25// GOT-NEXT: 3058 00200000
25// GOT-NEXT: 2058 00300000
deps/lld/test/ELF/arm-plt-reloc.s+29-16
......@@ -5,7 +5,7 @@
55// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t | FileCheck %s
66// RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3
77// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSO %s
8// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
8// RUN: llvm-readobj -S -r %t3 | FileCheck -check-prefix=DSOREL %s
99//
1010// Test PLT entry generation
1111 .syntax unified
......@@ -20,6 +20,7 @@ _start:
2020
2121// Executable, expect no PLT
2222// CHECK: Disassembly of section .text:
23// CHECK-EMPTY:
2324// CHECK-NEXT: func1:
2425// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
2526// CHECK: func2:
......@@ -34,6 +35,7 @@ _start:
3435// Expect PLT entries as symbols can be preempted
3536// The .got.plt and .plt displacement is small so we can use small PLT entries.
3637// DSO: Disassembly of section .text:
38// DSO-EMPTY:
3739// DSO-NEXT: func1:
3840// DSO-NEXT: 1000: 1e ff 2f e1 bx lr
3941// DSO: func2:
......@@ -47,12 +49,14 @@ _start:
4749// DSO-NEXT: 1010: 0e 00 00 eb bl #56
4850// S(0x10160) - P(0x1014) + A(-8) = 0x44 = 68
4951// DSO-NEXT: 1014: 11 00 00 0a beq #68
52// DSO-EMPTY:
5053// DSO-NEXT: Disassembly of section .plt:
54// DSO-EMPTY:
5155// DSO-NEXT: $a:
5256// DSO-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
53// (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfdc) = 0x2008 = .got.plt[3]
57// (0x1024 + 8) + (0 RoR 12) + 4096 + (0xfdc) = 0x3008 = .got.plt[3]
5458// DSO-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12
55// DSO-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20
59// DSO-NEXT: 1028: 01 ea 8e e2 add lr, lr, #4096
5660// DSO-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]!
5761// DSO: $d:
5862// DSO-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4
......@@ -60,23 +64,23 @@ _start:
6064// DSO-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4
6165// DSO-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4
6266// DSO: $a:
63// (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfc4) = 0x200c
67// (0x1040 + 8) + (0 RoR 12) + 4096 + (0xfc4) = 0x300c
6468// DSO-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12
65// DSO-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20
69// DSO-NEXT: 1044: 01 ca 8c e2 add r12, r12, #4096
6670// DSO-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]!
6771// DSO: $d:
6872// DSO-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4
6973// DSO: $a:
70// (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfb8) = 0x2010
74// (0x1050 + 8) + (0 RoR 12) + 4096 + (0xfb8) = 0x3010
7175// DSO-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12
72// DSO-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20
76// DSO-NEXT: 1054: 01 ca 8c e2 add r12, r12, #4096
7377// DSO-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]!
7478// DSO: $d:
7579// DSO-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4
7680// DSO: $a:
77// (0x1060 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfac) = 0x2014
81// (0x1060 + 8) + (0 RoR 12) + 4096 + (0xfac) = 0x3014
7882// DSO-NEXT: 1060: 00 c6 8f e2 add r12, pc, #0, #12
79// DSO-NEXT: 1064: 00 ca 8c e2 add r12, r12, #0, #20
83// DSO-NEXT: 1064: 01 ca 8c e2 add r12, r12, #4096
8084// DSO-NEXT: 1068: ac ff bc e5 ldr pc, [r12, #4012]!
8185// DSO: $d:
8286// DSO-NEXT: 106c: d4 d4 d4 d4 .word 0xd4d4d4d4
......@@ -88,7 +92,7 @@ _start:
8892// DSOREL-NEXT: SHF_ALLOC
8993// DSOREL-NEXT: SHF_WRITE
9094// DSOREL-NEXT: ]
91// DSOREL-NEXT: Address: 0x2000
95// DSOREL-NEXT: Address: 0x3000
9296// DSOREL-NEXT: Offset:
9397// DSOREL-NEXT: Size: 24
9498// DSOREL-NEXT: Link:
......@@ -97,9 +101,9 @@ _start:
97101// DSOREL-NEXT: EntrySize:
98102// DSOREL: Relocations [
99103// DSOREL-NEXT: Section {{.*}} .rel.plt {
100// DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0
101// DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0
102// DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0
104// DSOREL-NEXT: 0x300C R_ARM_JUMP_SLOT func1 0x0
105// DSOREL-NEXT: 0x3010 R_ARM_JUMP_SLOT func2 0x0
106// DSOREL-NEXT: 0x3014 R_ARM_JUMP_SLOT func3 0x0
103107
104108// Test a large separation between the .plt and .got.plt
105109// The .got.plt and .plt displacement is large but still within the range
......@@ -111,9 +115,10 @@ _start:
111115// RUN: }" > %t.script
112116// RUN: ld.lld --hash-style=sysv --script %t.script -shared %t1 %t2 -o %t4
113117// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t4 | FileCheck --check-prefix=CHECKHIGH %s
114// RUN: llvm-readobj -s -r %t4 | FileCheck --check-prefix=DSORELHIGH %s
118// RUN: llvm-readobj -S -r %t4 | FileCheck --check-prefix=DSORELHIGH %s
115119
116120// CHECKHIGH: Disassembly of section .text:
121// CHECKHIGH-EMPTY:
117122// CHECKHIGH-NEXT: func1:
118123// CHECKHIGH-NEXT: 1000: 1e ff 2f e1 bx lr
119124// CHECKHIGH: func2:
......@@ -124,7 +129,9 @@ _start:
124129// CHECKHIGH-NEXT: 100c: 03 04 00 ea b #4108 <$a>
125130// CHECKHIGH-NEXT: 1010: 06 04 00 eb bl #4120 <$a>
126131// CHECKHIGH-NEXT: 1014: 09 04 00 0a beq #4132 <$a>
132// CHECKHIGH-EMPTY:
127133// CHECKHIGH-NEXT: Disassembly of section .plt:
134// CHECKHIGH-EMPTY:
128135// CHECKHIGH-NEXT: $a:
129136// CHECKHIGH-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]!
130137// CHECKHIGH-NEXT: 2004: 10 e6 8f e2 add lr, pc, #16, #12
......@@ -176,9 +183,10 @@ _start:
176183// RUN: }" > %t2.script
177184// RUN: ld.lld --hash-style=sysv --script %t2.script -shared %t1 %t2 -o %t5
178185// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t5 | FileCheck --check-prefix=CHECKLONG %s
179// RUN: llvm-readobj -s -r %t5 | FileCheck --check-prefix=DSORELLONG %s
186// RUN: llvm-readobj -S -r %t5 | FileCheck --check-prefix=DSORELLONG %s
180187
181188// CHECKLONG: Disassembly of section .text:
189// CHECKLONG-EMPTY:
182190// CHECKLONG-NEXT: func1:
183191// CHECKLONG-NEXT: 1000: 1e ff 2f e1 bx lr
184192// CHECKLONG: func2:
......@@ -189,7 +197,9 @@ _start:
189197// CHECKLONG-NEXT: 100c: 03 04 00 ea b #4108 <$a>
190198// CHECKLONG-NEXT: 1010: 06 04 00 eb bl #4120 <$a>
191199// CHECKLONG-NEXT: 1014: 09 04 00 0a beq #4132 <$a>
200// CHECKLONG-EMPTY:
192201// CHECKLONG-NEXT: Disassembly of section .plt:
202// CHECKLONG-EMPTY:
193203// CHECKLONG-NEXT: $a:
194204// CHECKLONG-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]!
195205// CHECKLONG-NEXT: 2004: 04 e0 9f e5 ldr lr, [pc, #4]
......@@ -242,9 +252,10 @@ _start:
242252// RUN: }" > %t3.script
243253// RUN: ld.lld --hash-style=sysv --script %t3.script -shared %t1 %t2 -o %t6
244254// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t6 | FileCheck --check-prefix=CHECKMIX %s
245// RUN: llvm-readobj -s -r %t6 | FileCheck --check-prefix=DSORELMIX %s
255// RUN: llvm-readobj -S -r %t6 | FileCheck --check-prefix=DSORELMIX %s
246256
247257// CHECKMIX: Disassembly of section .text:
258// CHECKMIX-EMPTY:
248259// CHECKMIX-NEXT: func1:
249260// CHECKMIX-NEXT: 1000: 1e ff 2f e1 bx lr
250261// CHECKMIX: func2:
......@@ -255,7 +266,9 @@ _start:
255266// CHECKMIX-NEXT: 100c: 03 04 00 ea b #4108 <$a>
256267// CHECKMIX-NEXT: 1010: 06 04 00 eb bl #4120 <$a>
257268// CHECKMIX-NEXT: 1014: 09 04 00 0a beq #4132 <$a>
269// CHECKMIX-EMPTY:
258270// CHECKMIX-NEXT: Disassembly of section .plt:
271// CHECKMIX-EMPTY:
259272// CHECKMIX-NEXT: $a:
260273// CHECKMIX-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]!
261274// CHECKMIX-NEXT: 2004: 04 e0 9f e5 ldr lr, [pc, #4]
deps/lld/test/ELF/arm-sbrel32.s+1
......@@ -31,6 +31,7 @@ foo3: .space 4
3131foo4: .space 4
3232
3333// CHECK: Disassembly of section .text:
34// CHECK-EMPTY:
3435// CHECK-NEXT: _start:
3536// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
3637// CHECK: 11004: 00 00 00 00 .word 0x00000000
deps/lld/test/ELF/arm-tag-vfp-args.s+7-7
......@@ -7,15 +7,15 @@
77
88// The default for this file is 0 (Base AAPCS)
99// RUN: ld.lld %t.o -o %tdefault
10// RUN: llvm-readobj -file-headers %tdefault | FileCheck -check-prefix=CHECK-BASE %s
10// RUN: llvm-readobj --file-headers %tdefault | FileCheck -check-prefix=CHECK-BASE %s
1111
1212// Expect explicit Base AAPCS.
1313// RUN: ld.lld %t.o %tbase.o -o %tbase
14// RUN: llvm-readobj -file-headers %tbase | FileCheck -check-prefix=CHECK-BASE %s
14// RUN: llvm-readobj --file-headers %tbase | FileCheck -check-prefix=CHECK-BASE %s
1515
1616// Expect explicit Base AAPCS when linking Base and Compatible.
1717// RUN: ld.lld %t.o %tbase.o %tcompat.o -o %tbasecompat
18// RUN: llvm-readobj -file-headers %tbasecompat | FileCheck -check-prefix=CHECK-BASE %s
18// RUN: llvm-readobj --file-headers %tbasecompat | FileCheck -check-prefix=CHECK-BASE %s
1919
2020// CHECK-BASE: Flags [ (0x5000200)
2121// CHECK-BASE-NEXT: 0x200
......@@ -25,11 +25,11 @@
2525
2626// Expect Hard float VFP AAPCS
2727// RUN: ld.lld %t.o %tvfp.o -o %tvfp
28// RUN: llvm-readobj -file-headers %tvfp | FileCheck -check-prefix=CHECK-VFP %s
28// RUN: llvm-readobj --file-headers %tvfp | FileCheck -check-prefix=CHECK-VFP %s
2929
3030// Expect Hard float VFP AAPCS when linking VFP and Compatible
3131// RUN: ld.lld %t.o %tvfp.o %tcompat.o -o %tvfpcompat
32// RUN: llvm-readobj -file-headers %tvfpcompat | FileCheck -check-prefix=CHECK-VFP %s
32// RUN: llvm-readobj --file-headers %tvfpcompat | FileCheck -check-prefix=CHECK-VFP %s
3333
3434// CHECK-VFP: Flags [ (0x5000400)
3535// CHECK-VFP-NEXT: 0x400
......@@ -39,11 +39,11 @@
3939
4040// Expect Toolchain specifc to not use either Base or VFP AAPCS
4141// RUN: ld.lld %t.o %ttoolchain.o -o %ttoolchain
42// RUN: llvm-readobj -file-headers %ttoolchain | FileCheck -check-prefix=CHECK-TOOLCHAIN %s
42// RUN: llvm-readobj --file-headers %ttoolchain | FileCheck -check-prefix=CHECK-TOOLCHAIN %s
4343
4444// Expect Toolchain and Compatible to have same affect as Toolchain.
4545// RUN: ld.lld %t.o %ttoolchain.o %tcompat.o -o %ttoolchaincompat
46// RUN: llvm-readobj -file-headers %ttoolchaincompat | FileCheck -check-prefix=CHECK-TOOLCHAIN %s
46// RUN: llvm-readobj --file-headers %ttoolchaincompat | FileCheck -check-prefix=CHECK-TOOLCHAIN %s
4747
4848// CHECK-TOOLCHAIN: Flags [ (0x5000000)
4949// CHECK-TOOLCHAIN-NEXT: 0x1000000
deps/lld/test/ELF/arm-target1.s+1
......@@ -26,6 +26,7 @@
2626// Force generation of $d.0 as section is not all data
2727 nop
2828// RELATIVE: Disassembly of section .text:
29// RELATIVE-EMPTY:
2930// RELATIVE: $d.0:
3031// RELATIVE: 1000: 04 00 00 00 .word 0x00000004
3132// RELATIVE: SYMBOL TABLE:
deps/lld/test/ELF/arm-thumb-blx.s+5
......@@ -41,14 +41,17 @@ _start:
4141 bx lr
4242
4343// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee1:
44// CHECK-ARM-EMPTY:
4445// CHECK-NEXT-ARM: callee_low:
4546// CHECK-NEXT-ARM: b4: 1e ff 2f e1 bx lr
4647
4748// CHECK-THUMB: Disassembly of section .R_ARM_CALL24_callee2:
49// CHECK-THUMB-EMPTY:
4850// CHECK-NEXT-THUMB: callee_thumb_low:
4951// CHECK-NEXT-THUMB: 100: 70 47 bx lr
5052
5153// CHECK-THUMB: Disassembly of section .caller:
54// CHECK-THUMB-EMPTY:
5255// CHECK-THUMB: _start:
5356// Align(0x10000,4) - 0xff50 (65360) + 4 = 0xb4 = callee_low
5457// CHECK-NEXT-THUMB: 10000: f0 f7 58 e8 blx #-65360
......@@ -77,9 +80,11 @@ _start:
7780
7881
7982// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee3:
83// CHECK-ARM-EMPTY:
8084// CHECK-NEXT-ARM: callee_high:
8185// CHECK-NEXT-ARM: 10100: 1e ff 2f e1 bx lr
8286
8387// CHECK: Disassembly of section .R_ARM_CALL24_callee4:
88// CHECK-EMPTY:
8489// CHECK-NEXT-THUMB:callee_thumb_high:
8590// CHECK-NEXT-THUMB: 10200: 70 47 bx lr
deps/lld/test/ELF/arm-thumb-branch-rangethunk.s+1
......@@ -17,6 +17,7 @@ _start:
1717 beq.w too_far3
1818
1919// CHECK: Disassembly of section .text:
20// CHECK-EMPTY:
2021// CHECK-NEXT: _start:
2122// CHECK-NEXT: 20000: 00 f0 04 f8 bl #8
2223// CHECK-NEXT: 20004: 00 f0 07 b8 b.w #14 <__Thumbv7ABSLongThunk_too_far2>
deps/lld/test/ELF/arm-thumb-branch.s+5
......@@ -40,9 +40,12 @@ callee_high:
4040 bx lr
4141
4242// CHECK: Disassembly of section .callee1:
43// CHECK-EMPTY:
4344// CHECK-NEXT: callee_low:
4445// CHECK-NEXT: b4: 70 47 bx lr
46// CHECK-EMPTY:
4547// CHECK-NEXT: Disassembly of section .caller:
48// CHECK-EMPTY:
4649// CHECK-NEXT: _start:
4750// CHECK-NEXT: 10000: f0 f7 58 f8 bl #-65360
4851// CHECK-NEXT: 10004: f0 f7 56 b8 b.w #-65364
......@@ -55,6 +58,8 @@ callee_high:
5558// CHECK-NEXT: 10020: 3f f3 ff af bgt.w #1048574
5659// CHECK-NEXT: 10024: 70 47 bx lr
5760// CHECK-NEXT: 10026:
61// CHECK-EMPTY:
5862// CHECK-NEXT: Disassembly of section .callee2:
63// CHECK-EMPTY:
5964// CHECK-NEXT: callee_high:
6065// CHECK-NEXT: 10028: 70 47 bx lr
deps/lld/test/ELF/arm-thumb-condbranch-thunk.s+1
......@@ -34,6 +34,7 @@ _start:
3434// Section
3535 bl tfunc33
3636// CHECK1: Disassembly of section .text:
37// CHECK1-EMPTY:
3738// CHECK1-NEXT: tfunc00:
3839// CHECK1-NEXT: 80000: 70 47 bx lr
3940// CHECK1-NEXT: 80002: 7f f3 ff d7 bl #16252926
deps/lld/test/ELF/arm-thumb-interwork-shared.s+5-3
......@@ -15,6 +15,7 @@ sym1:
1515// entry.
1616
1717// CHECK: Disassembly of section .text:
18// CHECK-EMPTY:
1819// CHECK-NEXT: sym1:
1920// CHECK-NEXT: 1000: 00 f0 02 b8 b.w #4 <__ThumbV7PILongThunk_elsewhere>
2021// CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12 <__ThumbV7PILongThunk_weakref>
......@@ -30,10 +31,11 @@ sym1:
3031// CHECK-NEXT: 101e: 60 47 bx r12
3132
3233// PLT: Disassembly of section .plt:
34// PLT-EMPTY:
3335// PLT-NEXT: $a:
3436// PLT-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
3537// PLT-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12
36// PLT-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20
38// PLT-NEXT: 1028: 01 ea 8e e2 add lr, lr, #4096
3739// PLT-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]!
3840// PLT: $d:
3941// PLT-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4
......@@ -42,13 +44,13 @@ sym1:
4244// PLT-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4
4345// PLT: $a:
4446// PLT-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12
45// PLT-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20
47// PLT-NEXT: 1044: 01 ca 8c e2 add r12, r12, #4096
4648// PLT-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]!
4749// PLT: $d:
4850// PLT-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4
4951// PLT: $a:
5052// PLT-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12
51// PLT-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20
53// PLT-NEXT: 1054: 01 ca 8c e2 add r12, r12, #4096
5254// PLT-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]!
5355// PLT: $d:
5456// PLT-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4
deps/lld/test/ELF/arm-thumb-interwork-thunk.s+11-1
......@@ -19,7 +19,7 @@
1919// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-ARM %s
2020// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-PLT-THUMB %s
2121// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-PLT-ARM %s
22// RUN: llvm-readobj -s -r %t4 | FileCheck -check-prefix=CHECK-DSO-REL %s
22// RUN: llvm-readobj -S -r %t4 | FileCheck -check-prefix=CHECK-DSO-REL %s
2323
2424// Test ARM Thumb Interworking
2525// The file is linked and checked 3 times to check the following contexts
......@@ -39,6 +39,7 @@ thumb_callee1:
3939 bx lr
4040
4141// CHECK-THUMB: Disassembly of section .R_ARM_JUMP24_callee_1:
42// CHECK-THUMB-EMPTY:
4243// CHECK-THUMB: thumb_callee1:
4344// CHECK-THUMB: 1000: 70 47 bx
4445 .section .R_ARM_THM_JUMP_callee_low, "ax", %progbits
......@@ -79,6 +80,7 @@ arm_caller:
7980 bne arm_callee3
8081 bx lr
8182// CHECK-ARM-ABS-ARM: Disassembly of section .arm_caller:
83// CHECK-ARM-ABS-ARM-EMPTY:
8284// CHECK-ARM-ABS-ARM-NEXT: arm_caller:
8385// CHECK-ARM-ABS-ARM-NEXT: 1300: 3e ff ff fa blx #-776 <thumb_callee1>
8486// CHECK-ARM-ABS-ARM-NEXT: 1304: 3d ff ff fa blx #-780 <thumb_callee1>
......@@ -107,6 +109,7 @@ arm_caller:
107109// CHECK-ARM-ABS-ARM-NEXT: 1348: 1c ff 2f e1 bx r12
108110
109111// CHECK-PI-ARM: Disassembly of section .arm_caller:
112// CHECK-PI-ARM-EMPTY:
110113// CHECK-PI-ARM-NEXT: arm_caller:
111114// CHECK-PI-ARM-NEXT: 1300: 3e ff ff fa blx #-776 <thumb_callee1>
112115// CHECK-PI-ARM-NEXT: 1304: 3d ff ff fa blx #-780 <thumb_callee1>
......@@ -140,6 +143,7 @@ arm_caller:
140143
141144// All PLT entries are ARM, no need for interworking thunks
142145// CHECK-PI-ARM-PLT: Disassembly of section .arm_caller:
146// CHECK-PI-ARM-PLT-EMPTY:
143147// CHECK-PI-ARM-PLT-NEXT: arm_caller:
144148// 0x17e4 PLT(thumb_callee1)
145149// CHECK-PI-ARM-PLT-NEXT: 1300: 37 01 00 eb bl #1244
......@@ -184,6 +188,7 @@ thumb_caller:
184188 beq.w arm_callee2
185189 bne.w arm_callee3
186190// CHECK-ABS-THUMB: Disassembly of section .thumb_caller:
191// CHECK-ABS-THUMB-EMPTY:
187192// CHECK-ABS-THUMB-NEXT: thumb_caller:
188193// CHECK-ABS-THUMB-NEXT: 1400: ff f7 7e ee blx #-772
189194// CHECK-ABS-THUMB-NEXT: 1404: ff f7 7c ee blx #-776
......@@ -210,6 +215,7 @@ thumb_caller:
210215// CHECK-ABS-THUMB-NEXT: 143c: 60 47 bx r12
211216
212217// CHECK-PI-THUMB: Disassembly of section .thumb_caller:
218// CHECK-PI-THUMB-EMPTY:
213219// CHECK-PI-THUMB-NEXT: thumb_caller:
214220// CHECK-PI-THUMB-NEXT: 1400: ff f7 7e ee blx #-772
215221// CHECK-PI-THUMB-NEXT: 1404: ff f7 7c ee blx #-776
......@@ -239,6 +245,7 @@ thumb_caller:
239245// CHECK-PI-THUMB-NEXT: 1442: 60 47 bx r12
240246
241247// CHECK-PI-THUMB-PLT: Disassembly of section .arm_caller:
248// CHECK-PI-THUMB-PLT-EMPTY:
242249// CHECK-PI-THUMB-PLT-NEXT: thumb_caller:
243250// 0x1400 + 4 + 0x410 = 0x1814 = PLT(arm_callee1)
244251// CHECK-PI-THUMB-PLT-NEXT: 1400: 00 f0 08 ea blx #1040
......@@ -286,6 +293,7 @@ thumb_callee2:
286293thumb_callee3:
287294 bx lr
288295// CHECK-THUMB: Disassembly of section .R_ARM_JUMP24_callee_2:
296// CHECK-THUMB-EMPTY:
289297// CHECK-THUMB-NEXT: thumb_callee2:
290298// CHECK-THUMB-NEXT: 1500: 70 47 bx lr
291299// CHECK-THUMB: thumb_callee3:
......@@ -303,6 +311,7 @@ arm_callee2:
303311arm_callee3:
304312 bx lr
305313// CHECK-ARM: Disassembly of section .R_ARM_THM_JUMP_callee_2:
314// CHECK-ARM-EMPTY:
306315// CHECK-ARM-NEXT: arm_callee2:
307316// CHECK-ARM-NEXT: 1600: 1e ff 2f e1 bx lr
308317// CHECK-ARM: arm_callee3:
......@@ -321,6 +330,7 @@ _start:
321330
322331
323332// CHECK-PI-ARM-PLT: Disassembly of section .plt:
333// CHECK-PI-ARM-PLT-EMPTY:
324334// CHECK-PI-ARM-PLT-NEXT: .plt:
325335// CHECK-PI-ARM-PLT-NEXT: 17b0: 04 e0 2d e5 str lr, [sp, #-4]!
326336// CHECK-PI-ARM-PLT-NEXT: 17b4: 04 e0 9f e5 ldr lr, [pc, #4]
deps/lld/test/ELF/arm-thumb-narrow-branch-check.s+7
......@@ -50,9 +50,12 @@ callee_high:
5050callee_high_far = 0x180d
5151
5252// CHECK: Disassembly of section .R_ARM_PC11_1:
53// CHECK-EMPTY:
5354// CHECK-NEXT: callee_low:
5455// CHECK-NEXT: 1000: 70 47 bx lr
56// CHECK-EMPTY:
5557// CHECK-NEXT: Disassembly of section .caller:
58// CHECK-EMPTY:
5659// CHECK-NEXT: callers:
5760// 1004 - 0x800 (2048) + 4 = 0x808 = callee_low_far
5861// CHECK-NEXT: 1004: 00 e4 b #-2048
......@@ -64,10 +67,14 @@ callee_high_far = 0x180d
6467// CHECK-NEXT: 100a: ff e3 b #2046
6568// CHECK-NEXT: 100c: 70 47 bx lr
6669// CHECK-NEXT: 100e: 00 bf nop
70// CHECK-EMPTY:
6771// CHECK-NEXT: Disassembly of section .R_ARM_PC11_2:
72// CHECK-EMPTY:
6873// CHECK-NEXT: callee_high:
6974// CHECK-NEXT: 1010: 70 47 bx lr
75// CHECK-EMPTY:
7076// CHECK-NEXT: Disassembly of section .text:
77// CHECK-EMPTY:
7178// CHECK-NEXT: _start:
7279// CHECK-NEXT: 1014: ff f7 f6 ff bl #-20
7380// CHECK-NEXT: 1018: 70 47 bx lr
deps/lld/test/ELF/arm-thumb-no-undefined-thunk.s+1
......@@ -17,6 +17,7 @@ _start:
1717 b.w target
1818
1919// CHECK: Disassembly of section .text:
20// CHECK-EMPTY:
2021// CHECK-NEXT: _start:
2122// 69636 = 0x11004 = next instruction
2223// CHECK: 11000: {{.*}} bl #0
deps/lld/test/ELF/arm-thumb-plt-range-thunk-os.s+6-4
......@@ -35,6 +35,7 @@ preemptible:
3535 bl far_nonpreemptible_alias
3636 bx lr
3737// CHECK1: Disassembly of section .text:
38// CHECK1-EMPTY:
3839// CHECK1-NEXT: sym1:
3940// CHECK1-NEXT: 2000000: 00 f0 00 d8 bl #8388608
4041// CHECK1-NEXT: 2000004: 00 f0 04 d8 bl #8388616
......@@ -84,10 +85,11 @@ far_nonpreemptible_alias:
8485// CHECK3: 4000000: 00 f0 16 e8 blx #44
8586
8687// CHECK4: Disassembly of section .plt:
88// CHECK4-EMPTY:
8789// CHECK4-NEXT: $a:
8890// CHECK4-NEXT: 4000010: 04 e0 2d e5 str lr, [sp, #-4]!
8991// CHECK4-NEXT: 4000014: 00 e6 8f e2 add lr, pc, #0, #12
90// CHECK4-NEXT: 4000018: 00 ea 8e e2 add lr, lr, #0, #20
92// CHECK4-NEXT: 4000018: 01 ea 8e e2 add lr, lr, #4096
9193// CHECK4-NEXT: 400001c: ec ff be e5 ldr pc, [lr, #4076]!
9294// CHECK4: $d:
9395// CHECK4-NEXT: 4000020: d4 d4 d4 d4 .word 0xd4d4d4d4
......@@ -96,19 +98,19 @@ far_nonpreemptible_alias:
9698// CHECK4-NEXT: 400002c: d4 d4 d4 d4 .word 0xd4d4d4d4
9799// CHECK4: $a:
98100// CHECK4-NEXT: 4000030: 00 c6 8f e2 add r12, pc, #0, #12
99// CHECK4-NEXT: 4000034: 00 ca 8c e2 add r12, r12, #0, #20
101// CHECK4-NEXT: 4000034: 01 ca 8c e2 add r12, r12, #4096
100102// CHECK4-NEXT: 4000038: d4 ff bc e5 ldr pc, [r12, #4052]!
101103// CHECK4: $d:
102104// CHECK4-NEXT: 400003c: d4 d4 d4 d4 .word 0xd4d4d4d4
103105// CHECK4: $a:
104106// CHECK4-NEXT: 4000040: 00 c6 8f e2 add r12, pc, #0, #12
105// CHECK4-NEXT: 4000044: 00 ca 8c e2 add r12, r12, #0, #20
107// CHECK4-NEXT: 4000044: 01 ca 8c e2 add r12, r12, #4096
106108// CHECK4-NEXT: 4000048: c8 ff bc e5 ldr pc, [r12, #4040]!
107109// CHECK4: $d:
108110// CHECK4-NEXT: 400004c: d4 d4 d4 d4 .word 0xd4d4d4d4
109111// CHECK4: $a:
110112// CHECK4-NEXT: 4000050: 00 c6 8f e2 add r12, pc, #0, #12
111// CHECK4-NEXT: 4000054: 00 ca 8c e2 add r12, r12, #0, #20
113// CHECK4-NEXT: 4000054: 01 ca 8c e2 add r12, r12, #4096
112114// CHECK4-NEXT: 4000058: bc ff bc e5 ldr pc, [r12, #4028]!
113115// CHECK4: $d:
114116// CHECK4-NEXT: 400005c: d4 d4 d4 d4 .word 0xd4d4d4d4
deps/lld/test/ELF/arm-thumb-plt-reloc.s+16-13
......@@ -6,7 +6,7 @@
66// RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3
77// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s
88// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s
9// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
9// RUN: llvm-readobj -S -r %t3 | FileCheck -check-prefix=DSOREL %s
1010//
1111// Test PLT entry generation
1212 .syntax unified
......@@ -24,6 +24,7 @@ _start:
2424
2525// Executable, expect no PLT
2626// CHECK: Disassembly of section .text:
27// CHECK-EMPTY:
2728// CHECK-NEXT: func1:
2829// CHECK-NEXT: 11000: 70 47 bx lr
2930// CHECK: func2:
......@@ -43,6 +44,7 @@ _start:
4344// .text is Thumb and .plt is ARM, llvm-objdump can currently only disassemble
4445// as ARM or Thumb. Work around by disassembling twice.
4546// DSOTHUMB: Disassembly of section .text:
47// DSOTHUMB-EMPTY:
4648// DSOTHUMB-NEXT: func1:
4749// DSOTHUMB-NEXT: 1000: 70 47 bx lr
4850// DSOTHUMB: func2:
......@@ -58,11 +60,12 @@ _start:
5860// 0x1010 + 0x4C + 4 = 0x1060 = PLT func3
5961// DSOTHUMB-NEXT: 1010: 00 f0 26 e8 blx #76
6062// DSOARM: Disassembly of section .plt:
63// DSOARM-EMPTY:
6164// DSOARM-NEXT: $a:
6265// DSOARM-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
63// (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfdc) = 0x2008 = .got.plt[3]
66// (0x1024 + 8) + (0 RoR 12) + 4096 + (0xfdc) = 0x3008 = .got.plt[3]
6467// DSOARM-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12
65// DSOARM-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20
68// DSOARM-NEXT: 1028: 01 ea 8e e2 add lr, lr, #4096
6669// DSOARM-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]!
6770// DSOARM: $d:
6871
......@@ -71,23 +74,23 @@ _start:
7174// DSOARM-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4
7275// DSOARM-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4
7376// DSOARM: $a:
74// (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfc4) = 0x200c
77// (0x1040 + 8) + (0 RoR 12) + 4096 + (0xfc4) = 0x300c
7578// DSOARM-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12
76// DSOARM-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20
79// DSOARM-NEXT: 1044: 01 ca 8c e2 add r12, r12, #4096
7780// DSOARM-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]!
7881// DSOARM: $d:
7982// DSOARM-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4
8083// DSOARM: $a:
81// (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfb8) = 0x2010
84// (0x1050 + 8) + (0 RoR 12) + 4096 + (0xfb8) = 0x3010
8285// DSOARM-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12
83// DSOARM-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20
86// DSOARM-NEXT: 1054: 01 ca 8c e2 add r12, r12, #4096
8487// DSOARM-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]!
8588// DSOARM: $d:
8689// DSOARM-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4
8790// DSOARM: $a:
88// (0x1060 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfac) = 0x2014
91// (0x1060 + 8) + (0 RoR 12) + 4096 + (0xfac) = 0x3014
8992// DSOARM-NEXT: 1060: 00 c6 8f e2 add r12, pc, #0, #12
90// DSOARM-NEXT: 1064: 00 ca 8c e2 add r12, r12, #0, #20
93// DSOARM-NEXT: 1064: 01 ca 8c e2 add r12, r12, #4096
9194// DSOARM-NEXT: 1068: ac ff bc e5 ldr pc, [r12, #4012]!
9295// DSOARM: $d:
9396// DSOARM-NEXT: 106c: d4 d4 d4 d4 .word 0xd4d4d4d4
......@@ -98,7 +101,7 @@ _start:
98101// DSOREL-NEXT: SHF_ALLOC
99102// DSOREL-NEXT: SHF_WRITE
100103// DSOREL-NEXT: ]
101// DSOREL-NEXT: Address: 0x2000
104// DSOREL-NEXT: Address: 0x3000
102105// DSOREL-NEXT: Offset:
103106// DSOREL-NEXT: Size: 24
104107// DSOREL-NEXT: Link:
......@@ -107,6 +110,6 @@ _start:
107110// DSOREL-NEXT: EntrySize:
108111// DSOREL: Relocations [
109112// DSOREL-NEXT: Section (4) .rel.plt {
110// DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0
111// DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0
112// DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0
113// DSOREL-NEXT: 0x300C R_ARM_JUMP_SLOT func1 0x0
114// DSOREL-NEXT: 0x3010 R_ARM_JUMP_SLOT func2 0x0
115// DSOREL-NEXT: 0x3014 R_ARM_JUMP_SLOT func3 0x0
deps/lld/test/ELF/arm-thumb-range-thunk-os.s+1
......@@ -43,6 +43,7 @@ _start:
4343// the first of the pre-created ThunkSections.
4444 bl tfunc16
4545// CHECK1: Disassembly of section .text:
46// CHECK1-EMPTY:
4647// CHECK1-NEXT: _start:
4748// CHECK1-NEXT: 100000: ff f0 fe ff bl #1048572
4849// CHECK1-NEXT: 100004: ff f3 fc d7 bl #16777208
deps/lld/test/ELF/arm-thumb-thunk-empty-pass.s+1
......@@ -17,6 +17,7 @@ foo:
1717 bl _start
1818
1919// CHECK1: Disassembly of section .text:
20// CHECK1-EMPTY:
2021// CHECK1-NEXT: _start:
2122// CHECK1-NEXT: 11000: ff f7 fe ff bl #-4
2223// CHECK1: __Thumbv7ABSLongThunk__start:
deps/lld/test/ELF/arm-thumb-thunk-v6m.s+4
......@@ -31,6 +31,7 @@ far:
3131 bx lr
3232
3333// CHECK: Disassembly of section .text_low:
34// CHECK-EMPTY:
3435// CHECK-NEXT: _start:
3536// CHECK-NEXT: 94: 00 f0 00 f8 bl #0
3637// CHECK: __Thumbv6MABSLongThunk_far:
......@@ -40,10 +41,12 @@ far:
4041// CHECK-NEXT: 9e: 01 bd pop {r0, pc}
4142// CHECK: a0: 01 00 00 02 .word 0x02000001
4243// CHECK: Disassembly of section .text_high:
44// CHECK-EMPTY:
4345// CHECK-NEXT: far:
4446// CHECK-NEXT: 2000000: 70 47 bx lr
4547
4648// CHECK-PI: Disassembly of section .text_low:
49// CHECK-PI-EMPTY:
4750// CHECK-PI-NEXT: _start:
4851// CHECK-PI-NEXT: 130: 00 f0 00 f8 bl #0
4952// CHECK-PI: __Thumbv6MPILongThunk_far:
......@@ -57,5 +60,6 @@ far:
5760// CHECK-PI: 140: c1 fe ff 01 .word 0x01fffec1
5861
5962// CHECK-PI: Disassembly of section .text_high:
63// CHECK-PI-EMPTY:
6064// CHECK-PI-NEXT: far:
6165// CHECK-PI-NEXT: 2000000: 70 47 bx lr
deps/lld/test/ELF/arm-thumb-undefined-weak-narrow.test+14-15
......@@ -4,6 +4,7 @@
44# RUN: llvm-objdump -triple=thumbv7a-linux-gnueabi -d %t | FileCheck %s
55
66# CHECK: Disassembly of section .text:
7# CHECK-EMPTY:
78# CHECK-NEXT:_start:
89# CHECK-NEXT: 11000: ff e7 b #-2
910
......@@ -33,18 +34,16 @@ Sections:
3334 Type: R_ARM_THM_JUMP11
3435
3536Symbols:
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
37 - Type: STT_NOTYPE
38 Name: "$t"
39 Section: .text
40 Value: 0
41 - Type: STT_FUNC
42 Name: _start
43 Value: 1
44 Section: .text
45 Binding: STB_GLOBAL
46 - Type: STT_NOTYPE
47 Name: undefined_weak
48 Value: 0
49 Binding: STB_WEAK
deps/lld/test/ELF/arm-thumb-undefined-weak.s+1
......@@ -28,6 +28,7 @@ _start:
2828 movw r0, :lower16:target - .
2929
3030// CHECK: Disassembly of section .text:
31// CHECK-EMPTY:
3132// 69636 = 0x11004
3233// CHECK: 11000: {{.*}} beq.w #0 <_start+0x4>
3334// CHECK-NEXT: 11004: {{.*}} b.w #0 <_start+0x8>
deps/lld/test/ELF/arm-thunk-largesection.s+1
......@@ -16,6 +16,7 @@ _start:
1616 bx lr
1717 .space 0x1000
1818// CHECK1: Disassembly of section .text:
19// CHECK1-EMPTY:
1920// CHECK1-NEXT:_start:
2021// CHECK1-NEXT: 11000: 70 47 bx lr
2122// CHECK1-EMPTY:
deps/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s+1
......@@ -28,6 +28,7 @@ low_target2:
2828 bl high_target
2929 bl high_target2
3030// CHECK1: Disassembly of section .text_low:
31// CHECK1-EMPTY:
3132// CHECK1-NEXT: _start:
3233// CHECK1-NEXT: 94: 70 47 bx lr
3334// CHECK1: low_target:
deps/lld/test/ELF/arm-thunk-linkerscript-large.s+3
......@@ -53,6 +53,7 @@ _start:
5353 // Expect a range extension thunk in .text OutputSection
5454 bl tfunch31
5555// CHECK1: Disassembly of section .text:
56// CHECK1-EMPTY:
5657// CHECK1-NEXT: _start:
5758// CHECK1-NEXT: 100000: ff f0 fe ff bl #1048572
5859// CHECK1-NEXT: 100004: 00 f0 00 f8 bl #0
......@@ -66,6 +67,7 @@ _start:
6667 // We can reuse existing thunk in .text
6768 bl tfunch31
6869// CHECK2: Disassembly of section .textl:
70// CHECK2-EMPTY:
6971// CHECK2-NEXT: tfuncl00:
7072// CHECK2-NEXT: 200000: 70 47 bx lr
7173// CHECK2-NEXT: 200002: ff f0 ff df bl #9437182
......@@ -122,6 +124,7 @@ _start:
122124 // Shouldn't need a thunk
123125 bl tfuncl31
124126// CHECK5: Disassembly of section .texth:
127// CHECK5-EMPTY:
125128// CHECK5-NEXT: tfunch00:
126129// CHECK5-NEXT: 2200000: 70 47 bx lr
127130// CHECK5-NEXT: 2200002: 00 f7 05 f8 bl #-1048566
deps/lld/test/ELF/arm-thunk-linkerscript-orphan.s+3
......@@ -18,6 +18,7 @@ low_target:
1818 bl high_target
1919 bl orphan_target
2020// CHECK: Disassembly of section .text_low:
21// CHECK-EMPTY:
2122// CHECK-NEXT: _start:
2223// CHECK-NEXT: 100000: 70 47 bx lr
2324// CHECK: low_target:
......@@ -39,6 +40,7 @@ high_target:
3940 bl low_target
4041 bl orphan_target
4142// CHECK: Disassembly of section .text_high:
43// CHECK-EMPTY:
4244// CHECK-NEXT: high_target:
4345// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4
4446// CHECK-NEXT: 2000004: 00 f0 06 f8 bl #12
......@@ -55,6 +57,7 @@ orphan_target:
5557 bl low_target
5658 bl high_target
5759// CHECK: Disassembly of section orphan:
60// CHECK-EMPTY:
5861// CHECK-NEXT: orphan_target:
5962// CHECK-NEXT: 2000014: ff f7 f8 ff bl #-16
6063// CHECK-NEXT: 2000018: ff f7 f2 ff bl #-28
deps/lld/test/ELF/arm-thunk-linkerscript.s+2
......@@ -28,6 +28,7 @@ low_target2:
2828 bl high_target2
2929
3030// CHECK: Disassembly of section .text_low:
31// CHECK-EMPTY:
3132// CHECK-NEXT: _start:
3233// CHECK-NEXT: 94: 70 47 bx lr
3334// CHECK: low_target:
......@@ -62,6 +63,7 @@ high_target2:
6263 bl low_target2
6364
6465// CHECK: Disassembly of section .text_high:
66// CHECK-EMPTY:
6567// CHECK-NEXT: high_target:
6668// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4
6769// CHECK-NEXT: 2000004: 00 f0 05 f8 bl #10
deps/lld/test/ELF/arm-thunk-multipass-plt.s created+95
......@@ -0,0 +1,95 @@
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 --shared 2>&1
4// RUN: llvm-objdump --start-address=7340044 --stop-address=7340048 --triple=armv5-none-linux-gnueabi -d %t2 | FileCheck %s
5// RUN: llvm-objdump --start-address=8388620 --stop-address=8388624 --triple=thumbv5-none-linux-gnueabi -d %t2 | FileCheck %s -check-prefix=CHECK-CALL
6// RUN: llvm-objdump --start-address=13631520 --stop-address=13631584 --triple=armv5-none-linux-gnueabi -d %t2 | FileCheck %s -check-prefix=CHECK-PLT
7// When we create a thunk to a PLT entry the relocation is redirected to the
8// Thunk, changing its expression to a non-PLT equivalent. If the thunk
9// becomes unusable we need to restore the relocation expression to the PLT
10// form so that when we create a new thunk it targets the PLT.
11
12// Test case that checks the case:
13// - Thunk is created on pass 1 to a PLT entry for preemptible
14// - Some other Thunk added in the same pass moves the thunk to
15// preemptible out of range of its caller.
16// - New Thunk is created on pass 2 to PLT entry for preemptible
17
18 .globl preemptible
19 .globl preemptible2
20.section .text.01, "ax", %progbits
21.balign 0x100000
22 .thumb
23 .globl needsplt
24 .type needsplt, %function
25needsplt:
26 bl preemptible
27 .section .text.02, "ax", %progbits
28 .space (1024 * 1024)
29
30 .section .text.03, "ax", %progbits
31 .space (1024 * 1024)
32
33 .section .text.04, "ax", %progbits
34 .space (1024 * 1024)
35
36 .section .text.05, "ax", %progbits
37 .space (1024 * 1024)
38
39 .section .text.06, "ax", %progbits
40 .space (1024 * 1024)
41
42 .section .text.07, "ax", %progbits
43 .space (1024 * 1024)
44// 0x70000c + 8 + 0x60002c = 0xd00040 = preemptible@plt
45// CHECK: 0070000c __ARMV5PILongThunk_preemptible:
46// CHECK-NEXT: 70000c: 0b 00 18 ea b #6291500
47
48 .section .text.08, "ax", %progbits
49 .space (1024 * 1024) - 4
50
51 .section .text.10, "ax", %progbits
52 .balign 2
53 bl preemptible
54 bl preemptible2
55// 0x80000c + 4 - 100004 = 0x70000c = __ARMv5PILongThunk_preemptible
56// CHECK-CALL: 80000c: ff f6 fe ef blx #-1048580
57 .balign 2
58 .globl preemptible
59 .type preemptible, %function
60preemptible:
61 bx lr
62 .globl preemptible2
63 .type preemptible2, %function
64preemptible2:
65 bx lr
66
67
68 .section .text.11, "ax", %progbits
69 .space (5 * 1024 * 1024)
70
71
72// CHECK-PLT: Disassembly of section .plt:
73// CHECK-PLT-EMPTY:
74// CHECK-PLT-NEXT: 00d00020 $a:
75// CHECK-PLT-NEXT: d00020: 04 e0 2d e5 str lr, [sp, #-4]!
76// CHECK-PLT-NEXT: d00024: 00 e6 8f e2 add lr, pc, #0, #12
77// CHECK-PLT-NEXT: d00028: 01 ea 8e e2 add lr, lr, #4096
78// CHECK-PLT-NEXT: d0002c: dc ff be e5 ldr pc, [lr, #4060]!
79// CHECK-PLT: 00d00030 $d:
80// CHECK-PLT-NEXT: d00030: d4 d4 d4 d4 .word 0xd4d4d4d4
81// CHECK-PLT-NEXT: d00034: d4 d4 d4 d4 .word 0xd4d4d4d4
82// CHECK-PLT-NEXT: d00038: d4 d4 d4 d4 .word 0xd4d4d4d4
83// CHECK-PLT-NEXT: d0003c: d4 d4 d4 d4 .word 0xd4d4d4d4
84// CHECK-PLT: 00d00040 $a:
85// CHECK-PLT-NEXT: d00040: 00 c6 8f e2 add r12, pc, #0, #12
86// CHECK-PLT-NEXT: d00044: 01 ca 8c e2 add r12, r12, #4096
87// CHECK-PLT-NEXT: d00048: c4 ff bc e5 ldr pc, [r12, #4036]!
88// CHECK-PLT: 00d0004c $d:
89// CHECK-PLT-NEXT: d0004c: d4 d4 d4 d4 .word 0xd4d4d4d4
90// CHECK-PLT: 00d00050 $a:
91// CHECK-PLT-NEXT: d00050: 00 c6 8f e2 add r12, pc, #0, #12
92// CHECK-PLT-NEXT: d00054: 01 ca 8c e2 add r12, r12, #4096
93// CHECK-PLT-NEXT: d00058: b8 ff bc e5 ldr pc, [r12, #4024]!
94// CHECK-PLT: 00d0005c $d:
95// CHECK-PLT-NEXT: d0005c: d4 d4 d4 d4 .word 0xd4d4d4d4
deps/lld/test/ELF/arm-thunk-re-add.s+4-3
......@@ -99,10 +99,11 @@ callers:
9999// CHECK2-NEXT: 110001c: ff f6 f8 bf b.w #-1048592 <__ThumbV7PILongThunk_imported2>
100100
101101// CHECK3: Disassembly of section .plt:
102// CHECK3-EMPTY:
102103// CHECK3-NEXT: $a:
103104// CHECK3-NEXT: 1100020: 04 e0 2d e5 str lr, [sp, #-4]!
104105// CHECK3-NEXT: 1100024: 00 e6 8f e2 add lr, pc, #0, #12
105// CHECK3-NEXT: 1100028: 00 ea 8e e2 add lr, lr, #0, #20
106// CHECK3-NEXT: 1100028: 01 ea 8e e2 add lr, lr, #4096
106107// CHECK3-NEXT: 110002c: dc ff be e5 ldr pc, [lr, #4060]!
107108// CHECK3: $d:
108109// CHECK3-NEXT: 1100030: d4 d4 d4 d4 .word 0xd4d4d4d4
......@@ -111,13 +112,13 @@ callers:
111112// CHECK3-NEXT: 110003c: d4 d4 d4 d4 .word 0xd4d4d4d4
112113// CHECK3: $a:
113114// CHECK3-NEXT: 1100040: 00 c6 8f e2 add r12, pc, #0, #12
114// CHECK3-NEXT: 1100044: 00 ca 8c e2 add r12, r12, #0, #20
115// CHECK3-NEXT: 1100044: 01 ca 8c e2 add r12, r12, #4096
115116// CHECK3-NEXT: 1100048: c4 ff bc e5 ldr pc, [r12, #4036]!
116117// CHECK3: $d:
117118// CHECK3-NEXT: 110004c: d4 d4 d4 d4 .word 0xd4d4d4d4
118119// CHECK3: $a:
119120// CHECK3-NEXT: 1100050: 00 c6 8f e2 add r12, pc, #0, #12
120// CHECK3-NEXT: 1100054: 00 ca 8c e2 add r12, r12, #0, #20
121// CHECK3-NEXT: 1100054: 01 ca 8c e2 add r12, r12, #4096
121122// CHECK3-NEXT: 1100058: b8 ff bc e5 ldr pc, [r12, #4024]!
122123// CHECK3: $d:
123124// CHECK3-NEXT: 110005c: d4 d4 d4 d4 .word 0xd4d4d4d4
deps/lld/test/ELF/arm-tls-gd32.s+2-3
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
33// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
4// RUN: llvm-readobj -S --dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
55// RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s
66
77// Test the handling of the global-dynamic TLS model. Dynamic Loader finds
......@@ -91,8 +91,7 @@ x:
9191// SEC-NEXT: 0x2058 R_ARM_TLS_DTPOFF32 y
9292
9393
94// CHECK: Disassembly
95// CHECK-NEXT: func:
94// CHECK-LABEL: 00001000 func:
9695// CHECK-NEXT: 1000: 00 f0 20 e3 nop
9796// CHECK-NEXT: 1004: 00 f0 20 e3 nop
9897// CHECK-NEXT: 1008: 00 f0 20 e3 nop
deps/lld/test/ELF/arm-tls-ie32.s+2-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
33// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
4// RUN: llvm-readobj -S --dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
55// RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s
66
77// Test the handling of the initial-exec TLS model. Relative location within
......@@ -83,6 +83,7 @@ x:
8383// SEC: 0x2050 R_ARM_TLS_TPOFF32 y
8484
8585// CHECK: Disassembly of section .text:
86// CHECK-EMPTY:
8687// CHECK-NEXT: func:
8788// CHECK-NEXT: 1000: 00 f0 20 e3 nop
8889// CHECK-NEXT: 1004: 00 f0 20 e3 nop
deps/lld/test/ELF/arm-tls-ldm32.s+3-1
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
33// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
4// RUN: llvm-readobj -S --dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
55// RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s
66
77// Test the handling of the local-dynamic TLS model. Dynamic loader finds
......@@ -56,6 +56,7 @@ x:
5656// SEC-NEXT: 0x204C R_ARM_TLS_DTPMOD32 - 0x0
5757
5858// CHECK: Disassembly of section .text:
59// CHECK-EMPTY:
5960// CHECK-NEXT: _start:
6061// CHECK-NEXT: 1000: 00 f0 20 e3 nop
6162
......@@ -65,6 +66,7 @@ x:
6566// CHECK-NEXT: 100c: 04 00 00 00
6667
6768// CHECK-EXE: Disassembly of section .text:
69// CHECK-EXE-EMPTY:
6870// CHECK-NEXT-EXE: _start:
6971// CHECK-NEXT-EXE: 11000: 00 f0 20 e3 nop
7072
deps/lld/test/ELF/arm-tls-le32.s+8-7
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
33// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -s -dyn-relocations %t | FileCheck --check-prefix=SEC %s
4// RUN: llvm-readobj -S --dyn-relocations %t | FileCheck --check-prefix=SEC %s
55// RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t | FileCheck %s
66
77// Test the handling of the local exec TLS model. TLS can be resolved
......@@ -68,10 +68,11 @@ x:
6868// SEC-NEXT: }
6969
7070// CHECK: Disassembly of section .text:
71// CHECK-EMPTY:
7172// CHECK-NEXT: _start:
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
73// offset of x from Thread pointer = (TcbSize + 0x0 = 0x8)
74// CHECK-NEXT: 11000: 08 00 00 00
75// offset of z from Thread pointer = (TcbSize + 0x8 = 0x10)
76// CHECK-NEXT: 11004: 10 00 00 00
77// offset of y from Thread pointer = (TcbSize + 0x4 = 0xc)
78// CHECK-NEXT: 11008: 0c 00 00 00
deps/lld/test/ELF/arm-tls-norelax-gd-ie.s+4-4
......@@ -3,7 +3,7 @@
33// RUN: ld.lld %t1 --shared -o %t1.so
44// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
55// RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t
6// RUN: llvm-readobj -s -dyn-relocations %t | FileCheck %s
6// RUN: llvm-readobj -S --dyn-relocations %t | FileCheck %s
77
88// This tls global-dynamic sequence is with respect to a preemptible symbol but
99// is in an application so a relaxation to Initial Exec would normally be
......@@ -25,6 +25,6 @@ func:
2525 .Lt0: .word y(TLSGD) + (. - .L0 - 8)
2626
2727// CHECK: Dynamic Relocations {
28// CHECK-NEXT: 0x13078 R_ARM_TLS_DTPMOD32 y
29// CHECK-NEXT: 0x1307C R_ARM_TLS_DTPOFF32 y
30// CHECK-NEXT: 0x1200C R_ARM_JUMP_SLOT __tls_get_addr
28// CHECK-NEXT: 0x12078 R_ARM_TLS_DTPMOD32 y
29// CHECK-NEXT: 0x1207C R_ARM_TLS_DTPOFF32 y
30// CHECK-NEXT: 0x1300C R_ARM_JUMP_SLOT __tls_get_addr
deps/lld/test/ELF/arm-tls-norelax-gd-le.s+1-1
......@@ -33,7 +33,7 @@ x:
3333
3434// CHECK: Contents of section .got:
3535// Module index is always 1 for executable
36// CHECK-NEXT: 13060 01000000 00000000
36// CHECK-NEXT: 12060 01000000 00000000
3737
3838
3939// Without any definition of __tls_get_addr we get an error
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 0x20 from TP, x2 at offset 0x24 from TP. Offsets include TCB size of 0x20
41// CHECK-NEXT: 13064 20000000 24000000
40// x1 at offset 8 from TP, x2 at offset 0xc from TP. Offsets include TCB size of 8
41// CHECK-NEXT: 12064 08000000 0c000000
deps/lld/test/ELF/arm-tls-norelax-ld-le.s+1-1
......@@ -32,4 +32,4 @@ x:
3232 .word 10
3333
3434// CHECK: Contents of section .got:
35// CHECK-NEXT: 13064 01000000 00000000
35// CHECK-NEXT: 12064 01000000 00000000
deps/lld/test/ELF/arm-undefined-weak.s+1
......@@ -28,6 +28,7 @@ _start:
2828 .word target - .
2929
3030// CHECK: Disassembly of section .text:
31// CHECK-EMPTY:
3132// 69636 = 0x11004
3233// CHECK: 11000: {{.*}} b #-4 <_start+0x4>
3334// CHECK-NEXT: 11004: {{.*}} bl #-4 <_start+0x8>
deps/lld/test/ELF/arm-v4bx.test+6-9
......@@ -27,14 +27,11 @@ Sections:
2727 Info: .text
2828 Relocations:
2929 - Offset: 0x0000000000000000
30 Symbol: ''
3130 Type: R_ARM_V4BX
3231Symbols:
33 Global:
34 - Name: _start
35 Section: .text
36 Local:
37 - Name: .text
38 Type: STT_SECTION
39 Section: .text
40DynamicSymbols:
32 - Name: .text
33 Type: STT_SECTION
34 Section: .text
35 - Name: _start
36 Section: .text
37 Binding: STB_GLOBAL
deps/lld/test/ELF/as-needed-weak.s+4-3
......@@ -10,9 +10,10 @@
1010
1111# CHECK-NOT: libfoo
1212
13# CHECK: Symbol table of .hash for image:
14# CHECK-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
15# CHECK-NEXT: 1 1: 0000000000000000 0 FUNC WEAK DEFAULT UND foo
13# CHECK: Symbol table '.dynsym' contains 2 entries:
14# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
15# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
16# CHECK-NEXT: 1: 0000000000000000 0 FUNC WEAK DEFAULT UND foo
1617
1718.globl _start
1819.weak foo
deps/lld/test/ELF/as-needed.s+6-6
......@@ -10,27 +10,27 @@
1010/// Check if --as-needed actually works.
1111
1212// RUN: ld.lld %t.o %t2.so %t3.so %t4.so -o %t2
13// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
13// RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
1414
1515// RUN: ld.lld --as-needed %t.o %t2.so %t3.so %t4.so -o %t2
16// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
16// RUN: llvm-readobj --dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
1717
1818// Test with the .o last
1919// RUN: ld.lld --as-needed %t2.so %t3.so %t4.so %t.o -o %t2
20// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
20// RUN: llvm-readobj --dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
2121
2222// RUN: ld.lld --as-needed %t.o %t2.so --no-as-needed %t3.so %t4.so -o %t2
23// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
23// RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
2424
2525/// GROUP command is the same as listing the files on the command line.
2626
2727// RUN: echo "GROUP(\"%t2.so\" \"%t3.so\" \"%t4.so\")" > %t.script
2828// RUN: ld.lld %t.o %t.script -o %t2
29// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
29// RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
3030
3131// RUN: echo "GROUP(AS_NEEDED(\"%t2.so\" \"%t3.so\" \"%t4.so\"))" > %t.script
3232// RUN: ld.lld %t.o %t.script -o %t2
33// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
33// RUN: llvm-readobj --dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
3434
3535// CHECK: NEEDED Shared library: [shared1]
3636// CHECK: NEEDED Shared library: [shared2]
deps/lld/test/ELF/assignment-archive.s+2-2
......@@ -6,14 +6,14 @@
66
77# RUN: echo "SECTIONS { foo = 1; }" > %t1.script
88# RUN: ld.lld -o %t1.exe --script %t1.script %tar.a %t.o
9# RUN: llvm-readobj -symbols %t1.exe | FileCheck %s
9# RUN: llvm-readobj --symbols %t1.exe | FileCheck %s
1010# CHECK-NOT: bar
1111# CHECK: foo
1212# CHECK-NOT: bar
1313
1414# RUN: echo "SECTIONS { zed = foo; }" > %t2.script
1515# RUN: ld.lld -o %t2.exe --script %t2.script %tar.a %t.o
16# RUN: llvm-readobj -symbols %t2.exe | FileCheck %s --check-prefix=SYMS
16# RUN: llvm-readobj --symbols %t2.exe | FileCheck %s --check-prefix=SYMS
1717# SYMS: bar
1818# SYMS: foo
1919
deps/lld/test/ELF/avoid-empty-program-headers.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -program-headers %tout | FileCheck %s
4// RUN: llvm-readobj -l %tout | FileCheck %s
55
66.global _start
77_start:
deps/lld/test/ELF/bad-reloc-target.test deleted-29
......@@ -1,29 +0,0 @@
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+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: aarch64
22# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t
33# RUN: ld.lld %t -o %t2
4# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
4# RUN: llvm-readobj --file-headers --sections -l --symbols %t2 \
55# RUN: | FileCheck %s
66
77# exits with return code 42 on FreeBSD/AArch64
deps/lld/test/ELF/basic-freebsd.s+1-1
......@@ -3,7 +3,7 @@
33
44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
55# RUN: ld.lld %t -o %t2
6# RUN: llvm-readobj -file-headers %t2 | FileCheck %s
6# RUN: llvm-readobj --file-headers %t2 | FileCheck %s
77
88.globl _start
99_start:
deps/lld/test/ELF/basic-i386.s created+179
......@@ -0,0 +1,179 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readobj --file-headers --sections -l %t | FileCheck %s
5
6# exits with return code 42 on linux
7.globl _start
8_start:
9 mov $1, %eax
10 mov $42, %ebx
11 int $0x80
12
13# CHECK: ElfHeader {
14# CHECK-NEXT: Ident {
15# CHECK-NEXT: Magic: (7F 45 4C 46)
16# CHECK-NEXT: Class: 32-bit (0x1)
17# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
18# CHECK-NEXT: FileVersion: 1
19# CHECK-NEXT: OS/ABI: SystemV (0x0)
20# CHECK-NEXT: ABIVersion: 0
21# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
22# CHECK-NEXT: }
23# CHECK-NEXT: Type: Executable (0x2)
24# CHECK-NEXT: Machine: EM_386 (0x3)
25# CHECK-NEXT: Version: 1
26# CHECK-NEXT: Entry: 0x401000
27# CHECK-NEXT: ProgramHeaderOffset: 0x34
28# CHECK-NEXT: SectionHeaderOffset: 0x205C
29# CHECK-NEXT: Flags [ (0x0)
30# CHECK-NEXT: ]
31# CHECK-NEXT: HeaderSize: 52
32# CHECK-NEXT: ProgramHeaderEntrySize: 32
33# CHECK-NEXT: ProgramHeaderCount: 4
34# CHECK-NEXT: SectionHeaderEntrySize: 40
35# CHECK-NEXT: SectionHeaderCount: 6
36# CHECK-NEXT: StringTableSectionIndex: 4
37# CHECK-NEXT: }
38# CHECK-NEXT: Sections [
39# CHECK-NEXT: Section {
40# CHECK-NEXT: Index: 0
41# CHECK-NEXT: Name: (0)
42# CHECK-NEXT: Type: SHT_NULL (0x0)
43# CHECK-NEXT: Flags [ (0x0)
44# CHECK-NEXT: ]
45# CHECK-NEXT: Address: 0x0
46# CHECK-NEXT: Offset: 0x0
47# CHECK-NEXT: Size: 0
48# CHECK-NEXT: Link: 0
49# CHECK-NEXT: Info: 0
50# CHECK-NEXT: AddressAlignment: 0
51# CHECK-NEXT: EntrySize: 0
52# CHECK-NEXT: }
53# CHECK-NEXT: Section {
54# CHECK-NEXT: Index: 1
55# CHECK-NEXT: Name: .text
56# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
57# CHECK-NEXT: Flags [ (0x6)
58# CHECK-NEXT: SHF_ALLOC (0x2)
59# CHECK-NEXT: SHF_EXECINSTR (0x4)
60# CHECK-NEXT: ]
61# CHECK-NEXT: Address: 0x401000
62# CHECK-NEXT: Offset: 0x1000
63# CHECK-NEXT: Size: 12
64# CHECK-NEXT: Link: 0
65# CHECK-NEXT: Info: 0
66# CHECK-NEXT: AddressAlignment: 4
67# CHECK-NEXT: EntrySize: 0
68# CHECK-NEXT: }
69# CHECK-NEXT: Section {
70# CHECK-NEXT: Index: 2
71# CHECK-NEXT: Name: .comment
72# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
73# CHECK-NEXT: Flags [ (0x30)
74# CHECK-NEXT: SHF_MERGE (0x10)
75# CHECK-NEXT: SHF_STRINGS (0x20)
76# CHECK-NEXT: ]
77# CHECK-NEXT: Address: 0x0
78# CHECK-NEXT: Offset: 0x2000
79# CHECK-NEXT: Size: 8
80# CHECK-NEXT: Link: 0
81# CHECK-NEXT: Info: 0
82# CHECK-NEXT: AddressAlignment: 1
83# CHECK-NEXT: EntrySize: 1
84# CHECK-NEXT: }
85# CHECK-NEXT: Section {
86# CHECK-NEXT: Index: 3
87# CHECK-NEXT: Name: .symtab
88# CHECK-NEXT: Type: SHT_SYMTAB
89# CHECK-NEXT: Flags [
90# CHECK-NEXT: ]
91# CHECK-NEXT: Address: 0x0
92# CHECK-NEXT: Offset: 0x2008
93# CHECK-NEXT: Size: 32
94# CHECK-NEXT: Link: 5
95# CHECK-NEXT: Info: 1
96# CHECK-NEXT: AddressAlignment: 4
97# CHECK-NEXT: EntrySize: 16
98# CHECK-NEXT: }
99# CHECK-NEXT: Section {
100# CHECK-NEXT: Index: 4
101# CHECK-NEXT: Name: .shstrtab
102# CHECK-NEXT: Type: SHT_STRTAB (0x3)
103# CHECK-NEXT: Flags [ (0x0)
104# CHECK-NEXT: ]
105# CHECK-NEXT: Address: 0x0
106# CHECK-NEXT: Offset: 0x2028
107# CHECK-NEXT: Size: 42
108# CHECK-NEXT: Link: 0
109# CHECK-NEXT: Info: 0
110# CHECK-NEXT: AddressAlignment: 1
111# CHECK-NEXT: EntrySize: 0
112# CHECK-NEXT: }
113# CHECK-NEXT: Section {
114# CHECK-NEXT: Index: 5
115# CHECK-NEXT: Name: .strtab
116# CHECK-NEXT: Type: SHT_STRTAB (0x3)
117# CHECK-NEXT: Flags [ (0x0)
118# CHECK-NEXT: ]
119# CHECK-NEXT: Address: 0x0
120# CHECK-NEXT: Offset: 0x2052
121# CHECK-NEXT: Size: 8
122# CHECK-NEXT: Link: 0
123# CHECK-NEXT: Info: 0
124# CHECK-NEXT: AddressAlignment: 1
125# CHECK-NEXT: EntrySize: 0
126# CHECK-NEXT: }
127# CHECK-NEXT: ]
128# CHECK-NEXT: ProgramHeaders [
129# CHECK-NEXT: ProgramHeader {
130# CHECK-NEXT: Type: PT_PHDR (0x6)
131# CHECK-NEXT: Offset: 0x34
132# CHECK-NEXT: VirtualAddress: 0x400034
133# CHECK-NEXT: PhysicalAddress: 0x400034
134# CHECK-NEXT: FileSize: 128
135# CHECK-NEXT: MemSize: 128
136# CHECK-NEXT: Flags [ (0x4)
137# CHECK-NEXT: PF_R (0x4)
138# CHECK-NEXT: ]
139# CHECK-NEXT: Alignment: 4
140# CHECK-NEXT: }
141# CHECK-NEXT: ProgramHeader {
142# CHECK-NEXT: Type: PT_LOAD (0x1)
143# CHECK-NEXT: Offset: 0x0
144# CHECK-NEXT: VirtualAddress: 0x400000
145# CHECK-NEXT: PhysicalAddress: 0x400000
146# CHECK-NEXT: FileSize: 180
147# CHECK-NEXT: MemSize: 180
148# CHECK-NEXT: Flags [
149# CHECK-NEXT: PF_R
150# CHECK-NEXT: ]
151# CHECK-NEXT: Alignment: 4096
152# CHECK-NEXT: }
153# CHECK-NEXT: ProgramHeader {
154# CHECK-NEXT: Type: PT_LOAD (0x1)
155# CHECK-NEXT: Offset: 0x1000
156# CHECK-NEXT: VirtualAddress: 0x401000
157# CHECK-NEXT: PhysicalAddress: 0x401000
158# CHECK-NEXT: FileSize: 4096
159# CHECK-NEXT: MemSize: 4096
160# CHECK-NEXT: Flags [ (0x5)
161# CHECK-NEXT: PF_R (0x4)
162# CHECK-NEXT: PF_X (0x1)
163# CHECK-NEXT: ]
164# CHECK-NEXT: Alignment: 4096
165# CHECK-NEXT: }
166# CHECK-NEXT: ProgramHeader {
167# CHECK-NEXT: Type: PT_GNU_STACK
168# CHECK-NEXT: Offset: 0x0
169# CHECK-NEXT: VirtualAddress: 0x0
170# CHECK-NEXT: PhysicalAddress: 0x0
171# CHECK-NEXT: FileSize: 0
172# CHECK-NEXT: MemSize: 0
173# CHECK-NEXT: Flags [
174# CHECK-NEXT: PF_R
175# CHECK-NEXT: PF_W
176# CHECK-NEXT: ]
177# CHECK-NEXT: Alignment: 0
178# CHECK-NEXT: }
179# CHECK-NEXT: ]
deps/lld/test/ELF/basic-mips.s+47-23
......@@ -1,7 +1,7 @@
11# REQUIRES: mips
22# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t.o
33# RUN: ld.lld %t.o -o %t.exe
4# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t.exe \
4# RUN: llvm-readobj --file-headers --sections -l --symbols %t.exe \
55# RUN: | FileCheck %s
66
77# Exits with return code 1 on Linux.
......@@ -34,7 +34,7 @@ __start:
3434# CHECK-NEXT: ]
3535# CHECK-NEXT: HeaderSize: 52
3636# CHECK-NEXT: ProgramHeaderEntrySize: 32
37# CHECK-NEXT: ProgramHeaderCount: 5
37# CHECK-NEXT: ProgramHeaderCount: 7
3838# CHECK-NEXT: SectionHeaderEntrySize: 40
3939# CHECK-NEXT: SectionHeaderCount: 11
4040# CHECK-NEXT: StringTableSectionIndex: 9
......@@ -61,8 +61,8 @@ __start:
6161# CHECK-NEXT: Flags [ (0x2)
6262# CHECK-NEXT: SHF_ALLOC (0x2)
6363# CHECK-NEXT: ]
64# CHECK-NEXT: Address: 0x100D8
65# CHECK-NEXT: Offset: 0xD8
64# CHECK-NEXT: Address: 0x10118
65# CHECK-NEXT: Offset: 0x118
6666# CHECK-NEXT: Size: 24
6767# CHECK-NEXT: Link: 0
6868# CHECK-NEXT: Info: 0
......@@ -76,8 +76,8 @@ __start:
7676# CHECK-NEXT: Flags [ (0x2)
7777# CHECK-NEXT: SHF_ALLOC (0x2)
7878# CHECK-NEXT: ]
79# CHECK-NEXT: Address: 0x100F0
80# CHECK-NEXT: Offset: 0xF0
79# CHECK-NEXT: Address: 0x10130
80# CHECK-NEXT: Offset: 0x130
8181# CHECK-NEXT: Size: 24
8282# CHECK-NEXT: Link: 0
8383# CHECK-NEXT: Info: 0
......@@ -245,8 +245,8 @@ __start:
245245# CHECK-NEXT: Offset: 0x34
246246# CHECK-NEXT: VirtualAddress: 0x10034
247247# CHECK-NEXT: PhysicalAddress: 0x10034
248# CHECK-NEXT: FileSize: 160
249# CHECK-NEXT: MemSize: 160
248# CHECK-NEXT: FileSize: 224
249# CHECK-NEXT: MemSize: 224
250250# CHECK-NEXT: Flags [ (0x4)
251251# CHECK-NEXT: PF_R (0x4)
252252# CHECK-NEXT: ]
......@@ -257,8 +257,8 @@ __start:
257257# CHECK-NEXT: Offset: 0x0
258258# CHECK-NEXT: VirtualAddress: 0x10000
259259# CHECK-NEXT: PhysicalAddress: 0x10000
260# CHECK-NEXT: FileSize: 264
261# CHECK-NEXT: MemSize: 264
260# CHECK-NEXT: FileSize: 328
261# CHECK-NEXT: MemSize: 328
262262# CHECK-NEXT: Flags [ (0x4)
263263# CHECK-NEXT: PF_R (0x4)
264264# CHECK-NEXT: ]
......@@ -291,16 +291,40 @@ __start:
291291# CHECK-NEXT: Alignment: 65536
292292# CHECK-NEXT: }
293293# CHECK-NEXT: ProgramHeader {
294# CHECK-NEXT: Type: PT_GNU_STACK
295# CHECK-NEXT: Offset: 0x0
296# CHECK-NEXT: VirtualAddress: 0x0
297# CHECK-NEXT: PhysicalAddress: 0x0
298# CHECK-NEXT: FileSize: 0
299# CHECK-NEXT: MemSize: 0
300# CHECK-NEXT: Flags [
301# CHECK-NEXT: PF_R
302# CHECK-NEXT: PF_W
303# CHECK-NEXT: ]
304# CHECK-NEXT: Alignment: 0
305# CHECK-NEXT: }
306# CHECK-NEXT:]
294# CHECK-NEXT: Type: PT_GNU_STACK
295# CHECK-NEXT: Offset: 0x0
296# CHECK-NEXT: VirtualAddress: 0x0
297# CHECK-NEXT: PhysicalAddress: 0x0
298# CHECK-NEXT: FileSize: 0
299# CHECK-NEXT: MemSize: 0
300# CHECK-NEXT: Flags [
301# CHECK-NEXT: PF_R
302# CHECK-NEXT: PF_W
303# CHECK-NEXT: ]
304# CHECK-NEXT: Alignment: 0
305# CHECK-NEXT: }
306# CHECK-NEXT: ProgramHeader {
307# CHECK-NEXT: Type: PT_MIPS_REGINFO
308# CHECK-NEXT: Offset: 0x130
309# CHECK-NEXT: VirtualAddress: 0x10130
310# CHECK-NEXT: PhysicalAddress: 0x10130
311# CHECK-NEXT: FileSize: 24
312# CHECK-NEXT: MemSize: 24
313# CHECK-NEXT: Flags [ (0x4)
314# CHECK-NEXT: PF_R (0x4)
315# CHECK-NEXT: ]
316# CHECK-NEXT: Alignment: 4
317# CHECK-NEXT: }
318# CHECK-NEXT: ProgramHeader {
319# CHECK-NEXT: Type: PT_MIPS_ABIFLAGS
320# CHECK-NEXT: Offset: 0x118
321# CHECK-NEXT: VirtualAddress: 0x10118
322# CHECK-NEXT: PhysicalAddress: 0x10118
323# CHECK-NEXT: FileSize: 24
324# CHECK-NEXT: MemSize: 24
325# CHECK-NEXT: Flags [ (0x4)
326# CHECK-NEXT: PF_R (0x4)
327# CHECK-NEXT: ]
328# CHECK-NEXT: Alignment: 8
329# CHECK-NEXT: }
330# CHECK-NEXT: ]
deps/lld/test/ELF/basic-ppc.s+41-165
......@@ -1,7 +1,7 @@
11# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t
3# RUN: ld.lld --hash-style=sysv -discard-all -shared %t -o %t2
4# RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s
2# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readobj --file-headers --sections --section-data -l %t | FileCheck %s
55
66# exits with return code 42 on FreeBSD
77.text
......@@ -23,20 +23,20 @@
2323// CHECK-NEXT: ABIVersion: 0
2424// CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
2525// CHECK-NEXT: }
26// CHECK-NEXT: Type: SharedObject (0x3)
26// CHECK-NEXT: Type: Executable (0x2)
2727// CHECK-NEXT: Machine: EM_PPC (0x14)
2828// CHECK-NEXT: Version: 1
29// CHECK-NEXT: Entry: 0x1000
29// CHECK-NEXT: Entry: 0x10010000
3030// CHECK-NEXT: ProgramHeaderOffset: 0x34
31// CHECK-NEXT: SectionHeaderOffset: 0x20AC
31// CHECK-NEXT: SectionHeaderOffset: 0x11044
3232// CHECK-NEXT: Flags [ (0x0)
3333// CHECK-NEXT: ]
3434// CHECK-NEXT: HeaderSize: 52
3535// CHECK-NEXT: ProgramHeaderEntrySize: 32
36// CHECK-NEXT: ProgramHeaderCount: 7
36// CHECK-NEXT: ProgramHeaderCount: 4
3737// CHECK-NEXT: SectionHeaderEntrySize: 40
38// CHECK-NEXT: SectionHeaderCount: 10
39// CHECK-NEXT: StringTableSectionIndex: 8
38// CHECK-NEXT: SectionHeaderCount: 6
39// CHECK-NEXT: StringTableSectionIndex: 4
4040// CHECK-NEXT: }
4141// CHECK-NEXT: Sections [
4242// CHECK-NEXT: Section {
......@@ -57,68 +57,14 @@
5757// CHECK-NEXT: }
5858// CHECK-NEXT: Section {
5959// CHECK-NEXT: Index: 1
60// CHECK-NEXT: Name: .dynsym
61// CHECK-NEXT: Type: SHT_DYNSYM (0xB)
62// CHECK-NEXT: Flags [ (0x2)
63// CHECK-NEXT: SHF_ALLOC (0x2)
64// CHECK-NEXT: ]
65// CHECK-NEXT: Address: 0x114
66// CHECK-NEXT: Offset: 0x114
67// CHECK-NEXT: Size: 16
68// CHECK-NEXT: Link: 3
69// CHECK-NEXT: Info: 1
70// CHECK-NEXT: AddressAlignment: 4
71// CHECK-NEXT: EntrySize: 16
72// CHECK-NEXT: SectionData (
73// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
74// CHECK-NEXT: )
75// CHECK-NEXT: }
76// CHECK-NEXT: Section {
77// CHECK-NEXT: Index: 2
78// CHECK-NEXT: Name: .hash
79// CHECK-NEXT: Type: SHT_HASH (0x5)
80// CHECK-NEXT: Flags [ (0x2)
81// CHECK-NEXT: SHF_ALLOC (0x2)
82// CHECK-NEXT: ]
83// CHECK-NEXT: Address: 0x124
84// CHECK-NEXT: Offset: 0x124
85// CHECK-NEXT: Size: 16
86// CHECK-NEXT: Link: 1
87// CHECK-NEXT: Info: 0
88// CHECK-NEXT: AddressAlignment: 4
89// CHECK-NEXT: EntrySize: 4
90// CHECK-NEXT: SectionData (
91// CHECK-NEXT: 0000: 00000001 00000001 00000000 00000000 |................|
92// CHECK-NEXT: )
93// CHECK-NEXT: }
94// CHECK-NEXT: Section {
95// CHECK-NEXT: Index: 3
96// CHECK-NEXT: Name: .dynstr
97// CHECK-NEXT: Type: SHT_STRTAB (0x3)
98// CHECK-NEXT: Flags [ (0x2)
99// CHECK-NEXT: SHF_ALLOC (0x2)
100// CHECK-NEXT: ]
101// CHECK-NEXT: Address: 0x134
102// CHECK-NEXT: Offset: 0x134
103// CHECK-NEXT: Size: 1
104// CHECK-NEXT: Link: 0
105// CHECK-NEXT: Info: 0
106// CHECK-NEXT: AddressAlignment: 1
107// CHECK-NEXT: EntrySize: 0
108// CHECK-NEXT: SectionData (
109// CHECK-NEXT: 0000: 00 |.|
110// CHECK-NEXT: )
111// CHECK-NEXT: }
112// CHECK-NEXT: Section {
113// CHECK-NEXT: Index: 4
11460// CHECK-NEXT: Name: .text
11561// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
11662// CHECK-NEXT: Flags [ (0x6)
11763// CHECK-NEXT: SHF_ALLOC (0x2)
11864// CHECK-NEXT: SHF_EXECINSTR (0x4)
11965// CHECK-NEXT: ]
120// CHECK-NEXT: Address: 0x1000
121// CHECK-NEXT: Offset: 0x1000
66// CHECK-NEXT: Address: 0x10010000
67// CHECK-NEXT: Offset: 0x10000
12268// CHECK-NEXT: Size: 12
12369// CHECK-NEXT: Link: 0
12470// CHECK-NEXT: Info: 0
......@@ -129,28 +75,7 @@
12975// CHECK-NEXT: )
13076// CHECK-NEXT: }
13177// CHECK-NEXT: Section {
132// CHECK-NEXT: Index: 5
133// CHECK-NEXT: Name: .dynamic
134// CHECK-NEXT: Type: SHT_DYNAMIC (0x6)
135// CHECK-NEXT: Flags [ (0x3)
136// CHECK-NEXT: SHF_ALLOC (0x2)
137// CHECK-NEXT: SHF_WRITE (0x1)
138// CHECK-NEXT: ]
139// CHECK-NEXT: Address: 0x2000
140// CHECK-NEXT: Offset: 0x2000
141// CHECK-NEXT: Size: 48
142// CHECK-NEXT: Link: 3
143// CHECK-NEXT: Info: 0
144// CHECK-NEXT: AddressAlignment: 4
145// CHECK-NEXT: EntrySize: 8
146// CHECK-NEXT: SectionData (
147// CHECK-NEXT: 0000: 00000006 00000114 0000000B 00000010
148// CHECK-NEXT: 0010: 00000005 00000134 0000000A 00000001
149// CHECK-NEXT: 0020: 00000004 00000124 00000000 00000000
150// CHECK-NEXT: )
151// CHECK-NEXT: }
152// CHECK-NEXT: Section {
153// CHECK-NEXT: Index: 6
78// CHECK-NEXT: Index: 2
15479// CHECK-NEXT: Name: .comment
15580// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
15681// CHECK-NEXT: Flags [ (0x30)
......@@ -158,70 +83,59 @@
15883// CHECK-NEXT: SHF_STRINGS (0x20)
15984// CHECK-NEXT: ]
16085// CHECK-NEXT: Address: 0x0
161// CHECK-NEXT: Offset: 0x2030
86// CHECK-NEXT: Offset: 0x11000
16287// CHECK-NEXT: Size: 8
16388// CHECK-NEXT: Link: 0
16489// CHECK-NEXT: Info: 0
16590// CHECK-NEXT: AddressAlignment: 1
16691// CHECK-NEXT: EntrySize: 1
167// CHECK-NEXT: SectionData (
168// CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.|
169// CHECK-NEXT: )
170// CHECK-NEXT: }
92// CHECK: }
17193// CHECK-NEXT: Section {
172// CHECK-NEXT: Index: 7
94// CHECK-NEXT: Index: 3
17395// CHECK-NEXT: Name: .symtab
17496// CHECK-NEXT: Type: SHT_SYMTAB (0x2)
17597// CHECK-NEXT: Flags [ (0x0)
17698// CHECK-NEXT: ]
17799// CHECK-NEXT: Address: 0x0
178// CHECK-NEXT: Offset: 0x2038
179// CHECK-NEXT: Size: 32
180// CHECK-NEXT: Link: 9
181// CHECK-NEXT: Info: 2
100// CHECK-NEXT: Offset: 0x11008
101// CHECK-NEXT: Size: 16
102// CHECK-NEXT: Link: 5
103// CHECK-NEXT: Info: 1
182104// CHECK-NEXT: AddressAlignment: 4
183105// CHECK-NEXT: EntrySize: 16
184106// CHECK-NEXT: SectionData (
185107// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
186// CHECK-NEXT: 0010: 00000001 00002000 00000000 00020005 |...... .........|
187108// CHECK-NEXT: )
188109// CHECK-NEXT: }
189110// CHECK-NEXT: Section {
190// CHECK-NEXT: Index: 8
111// CHECK-NEXT: Index: 4
191112// CHECK-NEXT: Name: .shstrtab
192113// CHECK-NEXT: Type: SHT_STRTAB (0x3)
193114// CHECK-NEXT: Flags [ (0x0)
194115// CHECK-NEXT: ]
195116// CHECK-NEXT: Address: 0x0
196// CHECK-NEXT: Offset: 0x2058
197// CHECK-NEXT: Size: 73
117// CHECK-NEXT: Offset: 0x11018
118// CHECK-NEXT: Size: 42
198119// CHECK-NEXT: Link: 0
199120// CHECK-NEXT: Info: 0
200121// CHECK-NEXT: AddressAlignment: 1
201122// CHECK-NEXT: EntrySize: 0
202// CHECK-NEXT: SectionData (
203// CHECK-NEXT: 0000: 002E6479 6E73796D 002E6861 7368002E |..dynsym..hash..|
204// CHECK-NEXT: 0010: 64796E73 7472002E 74657874 002E6479 |dynstr..text..dy|
205// CHECK-NEXT: 0020: 6E616D69 63002E63 6F6D6D65 6E74002E |namic..comment..|
206// CHECK-NEXT: 0030: 73796D74 6162002E 73687374 72746162 |symtab..shstrtab|
207// CHECK-NEXT: 0040: 002E7374 72746162 00 |..strtab.|
208// CHECK-NEXT: )
209// CHECK-NEXT: }
123// CHECK: }
210124// CHECK-NEXT: Section {
211// CHECK-NEXT: Index: 9
125// CHECK-NEXT: Index: 5
212126// CHECK-NEXT: Name: .strtab
213127// CHECK-NEXT: Type: SHT_STRTAB (0x3)
214128// CHECK-NEXT: Flags [ (0x0)
215129// CHECK-NEXT: ]
216130// CHECK-NEXT: Address: 0x0
217// CHECK-NEXT: Offset: 0x20A1
218// CHECK-NEXT: Size: 10
131// CHECK-NEXT: Offset: 0x11042
132// CHECK-NEXT: Size: 1
219133// CHECK-NEXT: Link: 0
220134// CHECK-NEXT: Info: 0
221135// CHECK-NEXT: AddressAlignment: 1
222136// CHECK-NEXT: EntrySize: 0
223137// CHECK-NEXT: SectionData (
224// CHECK-NEXT: 0000: 005F4459 4E414D49 4300 |._DYNAMIC.|
138// CHECK-NEXT: 0000: 00
225139// CHECK-NEXT: )
226140// CHECK-NEXT: }
227141// CHECK-NEXT: ]
......@@ -229,10 +143,10 @@
229143// CHECK-NEXT: ProgramHeader {
230144// CHECK-NEXT: Type: PT_PHDR (0x6)
231145// CHECK-NEXT: Offset: 0x34
232// CHECK-NEXT: VirtualAddress: 0x34
233// CHECK-NEXT: PhysicalAddress: 0x34
234// CHECK-NEXT: FileSize: 224
235// CHECK-NEXT: MemSize: 224
146// CHECK-NEXT: VirtualAddress: 0x10000034
147// CHECK-NEXT: PhysicalAddress: 0x10000034
148// CHECK-NEXT: FileSize: 128
149// CHECK-NEXT: MemSize: 128
236150// CHECK-NEXT: Flags [ (0x4)
237151// CHECK-NEXT: PF_R (0x4)
238152// CHECK-NEXT: ]
......@@ -241,65 +155,27 @@
241155// CHECK-NEXT: ProgramHeader {
242156// CHECK-NEXT: Type: PT_LOAD (0x1)
243157// CHECK-NEXT: Offset: 0x0
244// CHECK-NEXT: VirtualAddress: 0x0
245// CHECK-NEXT: PhysicalAddress: 0x0
246// CHECK-NEXT: FileSize: 309
247// CHECK-NEXT: MemSize: 309
158// CHECK-NEXT: VirtualAddress: 0x10000000
159// CHECK-NEXT: PhysicalAddress: 0x10000000
160// CHECK-NEXT: FileSize: 180
161// CHECK-NEXT: MemSize: 180
248162// CHECK-NEXT: Flags [ (0x4)
249163// CHECK-NEXT: PF_R (0x4)
250164// CHECK-NEXT: ]
251// CHECK-NEXT: Alignment: 4096
165// CHECK-NEXT: Alignment: 65536
252166// CHECK-NEXT: }
253167// CHECK-NEXT: ProgramHeader {
254168// CHECK-NEXT: Type: PT_LOAD (0x1)
255169// CHECK-NEXT: Offset: 0x1000
256// CHECK-NEXT: VirtualAddress: 0x1000
257// CHECK-NEXT: PhysicalAddress: 0x1000
258// CHECK-NEXT: FileSize: 12
259// CHECK-NEXT: MemSize: 12
170// CHECK-NEXT: VirtualAddress: 0x10010000
171// CHECK-NEXT: PhysicalAddress: 0x10010000
172// CHECK-NEXT: FileSize: 4096
173// CHECK-NEXT: MemSize: 4096
260174// CHECK-NEXT: Flags [ (0x5)
261175// CHECK-NEXT: PF_R (0x4)
262176// CHECK-NEXT: PF_X (0x1)
263177// CHECK-NEXT: ]
264// CHECK-NEXT: Alignment: 4096
265// CHECK-NEXT: }
266// CHECK-NEXT: ProgramHeader {
267// CHECK-NEXT: Type: PT_LOAD (0x1)
268// CHECK-NEXT: Offset: 0x2000
269// CHECK-NEXT: VirtualAddress: 0x2000
270// CHECK-NEXT: PhysicalAddress: 0x2000
271// CHECK-NEXT: FileSize: 48
272// CHECK-NEXT: MemSize: 48
273// CHECK-NEXT: Flags [ (0x6)
274// CHECK-NEXT: PF_R (0x4)
275// CHECK-NEXT: PF_W (0x2)
276// CHECK-NEXT: ]
277// CHECK-NEXT: Alignment: 4096
278// CHECK-NEXT: }
279// CHECK-NEXT: ProgramHeader {
280// CHECK-NEXT: Type: PT_DYNAMIC (0x2)
281// CHECK-NEXT: Offset: 0x2000
282// CHECK-NEXT: VirtualAddress: 0x2000
283// CHECK-NEXT: PhysicalAddress: 0x2000
284// CHECK-NEXT: FileSize: 48
285// CHECK-NEXT: MemSize: 48
286// CHECK-NEXT: Flags [ (0x6)
287// CHECK-NEXT: PF_R (0x4)
288// CHECK-NEXT: PF_W (0x2)
289// CHECK-NEXT: ]
290// CHECK-NEXT: Alignment: 4
291// CHECK-NEXT: }
292// CHECK-NEXT: ProgramHeader {
293// CHECK-NEXT: Type: PT_GNU_RELRO (0x6474E552)
294// CHECK-NEXT: Offset: 0x2000
295// CHECK-NEXT: VirtualAddress: 0x2000
296// CHECK-NEXT: PhysicalAddress: 0x2000
297// CHECK-NEXT: FileSize: 48
298// CHECK-NEXT: MemSize: 4096
299// CHECK-NEXT: Flags [ (0x4)
300// CHECK-NEXT: PF_R (0x4)
301// CHECK-NEXT: ]
302// CHECK-NEXT: Alignment: 1
178// CHECK-NEXT: Alignment: 65536
303179// CHECK-NEXT: }
304180// CHECK-NEXT: ProgramHeader {
305181// CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
deps/lld/test/ELF/basic-ppc64.s+48-30
......@@ -1,7 +1,12 @@
11# REQUIRES: ppc
2# # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
3# RUN: ld.lld --hash-style=sysv -discard-all -shared %t -o %t2
4# RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
3# RUN: ld.lld --hash-style=sysv -discard-all -shared %t.o -o %t.so
4# RUN: llvm-readobj --file-headers --sections --section-data -l %t.so | FileCheck --check-prefixes=CHECK,LE %s
5
6# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
7# RUN: ld.lld --hash-style=sysv -discard-all -shared %t.o -o %t.so
8# RUN: llvm-readobj --file-headers --sections --section-data -l %t.so | FileCheck --check-prefixes=CHECK,BE %s
9
510.abiversion 2
611# Exits with return code 55 on linux.
712.text
......@@ -10,14 +15,16 @@
1015 sc
1116
1217// CHECK:Format: ELF64-ppc64
13// CHECK-NEXT:Arch: powerpc64le
14// CHECK-NEXT:AddressSize: 64bit
15// CHECK-NEXT:LoadName:
16// CHECK-NEXT:ElfHeader {
18// LE-NEXT: Arch: powerpc64le
19// BE-NEXT: Arch: powerpc64{{$}}
20// CHECK-NEXT: AddressSize: 64bit
21// CHECK-NEXT: LoadName:
22// CHECK-NEXT: ElfHeader {
1723// CHECK-NEXT: Ident {
1824// CHECK-NEXT: Magic: (7F 45 4C 46)
1925// CHECK-NEXT: Class: 64-bit (0x2)
20// CHECK-NEXT: DataEncoding: LittleEndian (0x1)
26// LE-NEXT: DataEncoding: LittleEndian (0x1)
27// BE-NEXT: DataEncoding: BigEndian (0x2)
2128// CHECK-NEXT: FileVersion: 1
2229// CHECK-NEXT: OS/ABI: SystemV (0x0)
2330// CHECK-NEXT: ABIVersion: 0
......@@ -63,8 +70,8 @@
6370// CHECK-NEXT: Flags [ (0x2)
6471// CHECK-NEXT: SHF_ALLOC (0x2)
6572// CHECK-NEXT: ]
66// CHECK-NEXT: Address: 0x1C8
67// CHECK-NEXT: Offset: 0x1C8
73// CHECK-NEXT: Address: 0x200
74// CHECK-NEXT: Offset: 0x200
6875// CHECK-NEXT: Size: 24
6976// CHECK-NEXT: Link: 3
7077// CHECK-NEXT: Info: 1
......@@ -82,15 +89,16 @@
8289// CHECK-NEXT: Flags [ (0x2)
8390// CHECK-NEXT: SHF_ALLOC (0x2)
8491// CHECK-NEXT: ]
85// CHECK-NEXT: Address: 0x1E0
86// CHECK-NEXT: Offset: 0x1E0
92// CHECK-NEXT: Address: 0x218
93// CHECK-NEXT: Offset: 0x218
8794// CHECK-NEXT: Size: 16
8895// CHECK-NEXT: Link: 1
8996// CHECK-NEXT: Info: 0
9097// CHECK-NEXT: AddressAlignment: 4
9198// CHECK-NEXT: EntrySize: 4
9299// CHECK-NEXT: SectionData (
93// CHECK-NEXT: 0000: 01000000 01000000 00000000 00000000 |................|
100// LE-NEXT: 0000: 01000000 01000000 00000000 00000000
101// BE-NEXT: 0000: 00000001 00000001 00000000 00000000
94102// CHECK-NEXT: )
95103// CHECK-NEXT: }
96104// CHECK-NEXT: Section {
......@@ -100,8 +108,8 @@
100108// CHECK-NEXT: Flags [ (0x2)
101109// CHECK-NEXT: SHF_ALLOC (0x2)
102110// CHECK-NEXT: ]
103// CHECK-NEXT: Address: 0x1F0
104// CHECK-NEXT: Offset: 0x1F0
111// CHECK-NEXT: Address: 0x228
112// CHECK-NEXT: Offset: 0x228
105113// CHECK-NEXT: Size: 1
106114// CHECK-NEXT: Link: 0
107115// CHECK-NEXT: Info: 0
......@@ -127,7 +135,8 @@
127135// CHECK-NEXT: AddressAlignment: 4
128136// CHECK-NEXT: EntrySize: 0
129137// CHECK-NEXT: SectionData (
130// CHECK-NEXT: 0000: 01000038 37006038 02000044 |...87.`8...D|
138// LE-NEXT: 0000: 01000038 37006038 02000044
139// BE-NEXT: 0000: 38000001 38600037 44000002
131140// CHECK-NEXT: )
132141// CHECK-NEXT: }
133142// CHECK-NEXT: Section {
......@@ -146,12 +155,18 @@
146155// CHECK-NEXT: AddressAlignment: 8
147156// CHECK-NEXT: EntrySize: 16
148157// CHECK-NEXT: SectionData (
149// CHECK-NEXT: 0000: 06000000 00000000 C8010000 00000000 |................|
150// CHECK-NEXT: 0010: 0B000000 00000000 18000000 00000000 |................|
151// CHECK-NEXT: 0020: 05000000 00000000 F0010000 00000000 |................|
152// CHECK-NEXT: 0030: 0A000000 00000000 01000000 00000000 |................|
153// CHECK-NEXT: 0040: 04000000 00000000 E0010000 00000000 |................|
154// CHECK-NEXT: 0050: 00000000 00000000 00000000 00000000 |................|
158// LE-NEXT: 0000: 06000000 00000000 00020000 00000000 |
159// LE-NEXT: 0010: 0B000000 00000000 18000000 00000000 |
160// LE-NEXT: 0020: 05000000 00000000 28020000 00000000 |
161// LE-NEXT: 0030: 0A000000 00000000 01000000 00000000 |
162// LE-NEXT: 0040: 04000000 00000000 18020000 00000000 |
163// LE-NEXT: 0050: 00000000 00000000 00000000 00000000 |
164// BE-NEXT: 0000: 00000000 00000006 00000000 00000200 |
165// BE-NEXT: 0010: 00000000 0000000B 00000000 00000018 |
166// BE-NEXT: 0020: 00000000 00000005 00000000 00000228 |
167// BE-NEXT: 0030: 00000000 0000000A 00000000 00000001 |
168// BE-NEXT: 0040: 00000000 00000004 00000000 00000218 |
169// BE-NEXT: 0050: 00000000 00000000 00000000 00000000 |
155170// CHECK-NEXT: )
156171// CHECK-NEXT: }
157172// CHECK-NEXT: Section {
......@@ -203,9 +218,12 @@
203218// CHECK-NEXT: AddressAlignment: 8
204219// CHECK-NEXT: EntrySize: 24
205220// CHECK-NEXT: SectionData (
206// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
207// CHECK-NEXT: 0010: 00000000 00000000 01000000 00020500 |................|
208// CHECK-NEXT: 0020: 00000200 00000000 00000000 00000000 |................|
221// LE-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
222// LE-NEXT: 0010: 00000000 00000000 01000000 00020500 |................|
223// LE-NEXT: 0020: 00000200 00000000 00000000 00000000 |................|
224// BE-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
225// BE-NEXT: 0010: 00000000 00000000 00000001 00020005 |................|
226// BE-NEXT: 0020: 00000000 00020000 00000000 00000000 |................|
209227// CHECK-NEXT: )
210228// CHECK-NEXT: }
211229// CHECK-NEXT: Section {
......@@ -254,8 +272,8 @@
254272// CHECK-NEXT: Offset: 0x40
255273// CHECK-NEXT: VirtualAddress: 0x40
256274// CHECK-NEXT: PhysicalAddress: 0x40
257// CHECK-NEXT: FileSize: 392
258// CHECK-NEXT: MemSize: 392
275// CHECK-NEXT: FileSize: 448
276// CHECK-NEXT: MemSize: 448
259277// CHECK-NEXT: Flags [ (0x4)
260278// CHECK-NEXT: PF_R (0x4)
261279// CHECK-NEXT: ]
......@@ -266,8 +284,8 @@
266284// CHECK-NEXT: Offset: 0x0
267285// CHECK-NEXT: VirtualAddress: 0x0
268286// CHECK-NEXT: PhysicalAddress: 0x0
269// CHECK-NEXT: FileSize: 497
270// CHECK-NEXT: MemSize: 497
287// CHECK-NEXT: FileSize: 553
288// CHECK-NEXT: MemSize: 553
271289// CHECK-NEXT: Flags [ (0x4)
272290// CHECK-NEXT: PF_R (0x4)
273291// CHECK-NEXT: ]
......@@ -292,7 +310,7 @@
292310// CHECK-NEXT: VirtualAddress: 0x20000
293311// CHECK-NEXT: PhysicalAddress: 0x20000
294312// CHECK-NEXT: FileSize: 96
295// CHECK-NEXT: MemSize: 65536
313// CHECK-NEXT: MemSize: 96
296314// CHECK-NEXT: Flags [ (0x6)
297315// CHECK-NEXT: PF_R (0x4)
298316// CHECK-NEXT: PF_W (0x2)
deps/lld/test/ELF/basic-sparcv9.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: sparc
22# RUN: llvm-mc -filetype=obj -triple=sparc64-unknown-openbsd %s -o %t
33# RUN: ld.lld %t -o %t2
4# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
4# RUN: llvm-readobj --file-headers --sections -l --symbols %t2 \
55# RUN: | FileCheck %s
66
77# exits with return code 42 on OpenBSD/sparc64
deps/lld/test/ELF/basic.s+6-3
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44# RUN: ld.lld %t -o %t2
5# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
5# RUN: llvm-readobj --file-headers --sections -l --symbols %t2 \
66# RUN: | FileCheck %s
77# RUN: ld.lld %t -o /dev/null
88
......@@ -204,7 +204,7 @@ _start:
204204# Test for the response file (POSIX quoting style)
205205# RUN: echo " -o %t2" > %t.responsefile
206206# RUN: ld.lld %t --rsp-quoting=posix @%t.responsefile
207# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
207# RUN: llvm-readobj --file-headers --sections -l --symbols %t2 \
208208# RUN: | FileCheck %s
209209
210210# Test for the response file (Windows quoting style)
......@@ -234,7 +234,7 @@ _start:
234234# NO_O_VAL: -o: missing argument
235235
236236# RUN: not ld.lld --foo 2>&1 | FileCheck --check-prefix=UNKNOWN %s
237# UNKNOWN: unknown argument: --foo
237# UNKNOWN: unknown argument '--foo'
238238
239239# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
240240# RUN: not ld.lld %t %t -o %t2 2>&1 | FileCheck --check-prefix=DUP %s
......@@ -252,3 +252,6 @@ _start:
252252# RUN: not ld.lld %t --thinlto-jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s
253253# RUN: not ld.lld %t --plugin-opt=jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s
254254# NOTHREADSTHIN: --thinlto-jobs: number of threads must be > 0
255
256# RUN: not ld.lld %t -z ifunc-noplt -z text 2>&1 | FileCheck --check-prefix=NOIFUNCPLTNOTEXTREL %s
257# NOIFUNCPLTNOTEXTREL: -z text and -z ifunc-noplt may not be used together
deps/lld/test/ELF/basic32.s deleted-179
......@@ -1,179 +0,0 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t
3# RUN: ld.lld %t -o %t2
4# RUN: llvm-readobj -file-headers -sections -program-headers %t2 | FileCheck %s
5
6# exits with return code 42 on linux
7.globl _start
8_start:
9 mov $1, %eax
10 mov $42, %ebx
11 int $0x80
12
13# CHECK: ElfHeader {
14# CHECK-NEXT: Ident {
15# CHECK-NEXT: Magic: (7F 45 4C 46)
16# CHECK-NEXT: Class: 32-bit (0x1)
17# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
18# CHECK-NEXT: FileVersion: 1
19# CHECK-NEXT: OS/ABI: SystemV (0x0)
20# CHECK-NEXT: ABIVersion: 0
21# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
22# CHECK-NEXT: }
23# CHECK-NEXT: Type: Executable (0x2)
24# CHECK-NEXT: Machine: EM_386 (0x3)
25# CHECK-NEXT: Version: 1
26# CHECK-NEXT: Entry: 0x401000
27# CHECK-NEXT: ProgramHeaderOffset: 0x34
28# CHECK-NEXT: SectionHeaderOffset: 0x205C
29# CHECK-NEXT: Flags [ (0x0)
30# CHECK-NEXT: ]
31# CHECK-NEXT: HeaderSize: 52
32# CHECK-NEXT: ProgramHeaderEntrySize: 32
33# CHECK-NEXT: ProgramHeaderCount: 4
34# CHECK-NEXT: SectionHeaderEntrySize: 40
35# CHECK-NEXT: SectionHeaderCount: 6
36# CHECK-NEXT: StringTableSectionIndex: 4
37# CHECK-NEXT: }
38# CHECK-NEXT: Sections [
39# CHECK-NEXT: Section {
40# CHECK-NEXT: Index: 0
41# CHECK-NEXT: Name: (0)
42# CHECK-NEXT: Type: SHT_NULL (0x0)
43# CHECK-NEXT: Flags [ (0x0)
44# CHECK-NEXT: ]
45# CHECK-NEXT: Address: 0x0
46# CHECK-NEXT: Offset: 0x0
47# CHECK-NEXT: Size: 0
48# CHECK-NEXT: Link: 0
49# CHECK-NEXT: Info: 0
50# CHECK-NEXT: AddressAlignment: 0
51# CHECK-NEXT: EntrySize: 0
52# CHECK-NEXT: }
53# CHECK-NEXT: Section {
54# CHECK-NEXT: Index: 1
55# CHECK-NEXT: Name: .text
56# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
57# CHECK-NEXT: Flags [ (0x6)
58# CHECK-NEXT: SHF_ALLOC (0x2)
59# CHECK-NEXT: SHF_EXECINSTR (0x4)
60# CHECK-NEXT: ]
61# CHECK-NEXT: Address: 0x401000
62# CHECK-NEXT: Offset: 0x1000
63# CHECK-NEXT: Size: 12
64# CHECK-NEXT: Link: 0
65# CHECK-NEXT: Info: 0
66# CHECK-NEXT: AddressAlignment: 4
67# CHECK-NEXT: EntrySize: 0
68# CHECK-NEXT: }
69# CHECK-NEXT: Section {
70# CHECK-NEXT: Index: 2
71# CHECK-NEXT: Name: .comment
72# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
73# CHECK-NEXT: Flags [ (0x30)
74# CHECK-NEXT: SHF_MERGE (0x10)
75# CHECK-NEXT: SHF_STRINGS (0x20)
76# CHECK-NEXT: ]
77# CHECK-NEXT: Address: 0x0
78# CHECK-NEXT: Offset: 0x2000
79# CHECK-NEXT: Size: 8
80# CHECK-NEXT: Link: 0
81# CHECK-NEXT: Info: 0
82# CHECK-NEXT: AddressAlignment: 1
83# CHECK-NEXT: EntrySize: 1
84# CHECK-NEXT: }
85# CHECK-NEXT: Section {
86# CHECK-NEXT: Index: 3
87# CHECK-NEXT: Name: .symtab
88# CHECK-NEXT: Type: SHT_SYMTAB
89# CHECK-NEXT: Flags [
90# CHECK-NEXT: ]
91# CHECK-NEXT: Address: 0x0
92# CHECK-NEXT: Offset: 0x2008
93# CHECK-NEXT: Size: 32
94# CHECK-NEXT: Link: 5
95# CHECK-NEXT: Info: 1
96# CHECK-NEXT: AddressAlignment: 4
97# CHECK-NEXT: EntrySize: 16
98# CHECK-NEXT: }
99# CHECK-NEXT: Section {
100# CHECK-NEXT: Index: 4
101# CHECK-NEXT: Name: .shstrtab
102# CHECK-NEXT: Type: SHT_STRTAB (0x3)
103# CHECK-NEXT: Flags [ (0x0)
104# CHECK-NEXT: ]
105# CHECK-NEXT: Address: 0x0
106# CHECK-NEXT: Offset: 0x2028
107# CHECK-NEXT: Size: 42
108# CHECK-NEXT: Link: 0
109# CHECK-NEXT: Info: 0
110# CHECK-NEXT: AddressAlignment: 1
111# CHECK-NEXT: EntrySize: 0
112# CHECK-NEXT: }
113# CHECK-NEXT: Section {
114# CHECK-NEXT: Index: 5
115# CHECK-NEXT: Name: .strtab
116# CHECK-NEXT: Type: SHT_STRTAB (0x3)
117# CHECK-NEXT: Flags [ (0x0)
118# CHECK-NEXT: ]
119# CHECK-NEXT: Address: 0x0
120# CHECK-NEXT: Offset: 0x2052
121# CHECK-NEXT: Size: 8
122# CHECK-NEXT: Link: 0
123# CHECK-NEXT: Info: 0
124# CHECK-NEXT: AddressAlignment: 1
125# CHECK-NEXT: EntrySize: 0
126# CHECK-NEXT: }
127# CHECK-NEXT: ]
128# CHECK-NEXT: ProgramHeaders [
129# CHECK-NEXT: ProgramHeader {
130# CHECK-NEXT: Type: PT_PHDR (0x6)
131# CHECK-NEXT: Offset: 0x34
132# CHECK-NEXT: VirtualAddress: 0x400034
133# CHECK-NEXT: PhysicalAddress: 0x400034
134# CHECK-NEXT: FileSize: 128
135# CHECK-NEXT: MemSize: 128
136# CHECK-NEXT: Flags [ (0x4)
137# CHECK-NEXT: PF_R (0x4)
138# CHECK-NEXT: ]
139# CHECK-NEXT: Alignment: 4
140# CHECK-NEXT: }
141# CHECK-NEXT: ProgramHeader {
142# CHECK-NEXT: Type: PT_LOAD (0x1)
143# CHECK-NEXT: Offset: 0x0
144# CHECK-NEXT: VirtualAddress: 0x400000
145# CHECK-NEXT: PhysicalAddress: 0x400000
146# CHECK-NEXT: FileSize: 180
147# CHECK-NEXT: MemSize: 180
148# CHECK-NEXT: Flags [
149# CHECK-NEXT: PF_R
150# CHECK-NEXT: ]
151# CHECK-NEXT: Alignment: 4096
152# CHECK-NEXT: }
153# CHECK-NEXT: ProgramHeader {
154# CHECK-NEXT: Type: PT_LOAD (0x1)
155# CHECK-NEXT: Offset: 0x1000
156# CHECK-NEXT: VirtualAddress: 0x401000
157# CHECK-NEXT: PhysicalAddress: 0x401000
158# CHECK-NEXT: FileSize: 4096
159# CHECK-NEXT: MemSize: 4096
160# CHECK-NEXT: Flags [ (0x5)
161# CHECK-NEXT: PF_R (0x4)
162# CHECK-NEXT: PF_X (0x1)
163# CHECK-NEXT: ]
164# CHECK-NEXT: Alignment: 4096
165# CHECK-NEXT: }
166# CHECK-NEXT: ProgramHeader {
167# CHECK-NEXT: Type: PT_GNU_STACK
168# CHECK-NEXT: Offset: 0x0
169# CHECK-NEXT: VirtualAddress: 0x0
170# CHECK-NEXT: PhysicalAddress: 0x0
171# CHECK-NEXT: FileSize: 0
172# CHECK-NEXT: MemSize: 0
173# CHECK-NEXT: Flags [
174# CHECK-NEXT: PF_R
175# CHECK-NEXT: PF_W
176# CHECK-NEXT: ]
177# CHECK-NEXT: Alignment: 0
178# CHECK-NEXT: }
179# CHECK-NEXT: ]
deps/lld/test/ELF/basic64be.s deleted-217
......@@ -1,217 +0,0 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
3# RUN: ld.lld -discard-all %t -o %t2
4# RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s
5
6# exits with return code 42 on linux
7.text
8 li 0,1
9 li 3,42
10 sc
11# CHECK: ElfHeader {
12# CHECK-NEXT: Ident {
13# CHECK-NEXT: Magic: (7F 45 4C 46)
14# CHECK-NEXT: Class: 64-bit (0x2)
15# CHECK-NEXT: DataEncoding: BigEndian (0x2)
16# CHECK-NEXT: FileVersion: 1
17# CHECK-NEXT: OS/ABI: SystemV (0x0)
18# CHECK-NEXT: ABIVersion: 0
19# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
20# CHECK-NEXT: }
21# CHECK-NEXT: Type: Executable (0x2)
22# CHECK-NEXT: Machine: EM_PPC64 (0x15)
23# CHECK-NEXT: Version: 1
24# CHECK-NEXT: Entry: 0x10010000
25# CHECK-NEXT: ProgramHeaderOffset: 0x40
26# CHECK-NEXT: SectionHeaderOffset: 0x20058
27# CHECK-NEXT: Flags [ (0x2)
28# CHECK-NEXT: 0x2
29# CHECK-NEXT: ]
30# CHECK-NEXT: HeaderSize: 64
31# CHECK-NEXT: ProgramHeaderEntrySize: 56
32# CHECK-NEXT: ProgramHeaderCount: 4
33# CHECK-NEXT: SectionHeaderEntrySize: 64
34# CHECK-NEXT: SectionHeaderCount: 7
35# CHECK-NEXT: StringTableSectionIndex: 5
36# CHECK-NEXT: }
37# CHECK-NEXT: Sections [
38# CHECK-NEXT: Section {
39# CHECK-NEXT: Index: 0
40# CHECK-NEXT: Name: (0)
41# CHECK-NEXT: Type: SHT_NULL (0x0)
42# CHECK-NEXT: Flags [ (0x0)
43# CHECK-NEXT: ]
44# CHECK-NEXT: Address: 0x0
45# CHECK-NEXT: Offset: 0x0
46# CHECK-NEXT: Size: 0
47# CHECK-NEXT: Link: 0
48# CHECK-NEXT: Info: 0
49# CHECK-NEXT: AddressAlignment: 0
50# CHECK-NEXT: EntrySize: 0
51# CHECK-NEXT: SectionData (
52# CHECK-NEXT: )
53# CHECK-NEXT: }
54# CHECK-NEXT: Section {
55# CHECK-NEXT: Index: 1
56# CHECK-NEXT: Name: .text (1)
57# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
58# CHECK-NEXT: Flags [ (0x6)
59# CHECK-NEXT: SHF_ALLOC (0x2)
60# CHECK-NEXT: SHF_EXECINSTR (0x4)
61# CHECK-NEXT: ]
62# CHECK-NEXT: Address: 0x10010000
63# CHECK-NEXT: Offset: 0x10000
64# CHECK-NEXT: Size: 12
65# CHECK-NEXT: Link: 0
66# CHECK-NEXT: Info: 0
67# CHECK-NEXT: AddressAlignment: 4
68# CHECK-NEXT: EntrySize: 0
69# CHECK-NEXT: SectionData (
70# CHECK-NEXT: 0000: 38000001 3860002A 44000002 |8...8`.*D...|
71# CHECK-NEXT: )
72# CHECK-NEXT: }
73# CHECK-NEXT: Section {
74# CHECK-NEXT: Index: 2
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)
94# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
95# CHECK-NEXT: Flags [ (0x30)
96# CHECK-NEXT: SHF_MERGE (0x10)
97# CHECK-NEXT: SHF_STRINGS (0x20)
98# CHECK-NEXT: ]
99# CHECK-NEXT: Address: 0x0
100# CHECK-NEXT: Offset: 0x20000
101# CHECK-NEXT: Size: 8
102# CHECK-NEXT: Link: 0
103# CHECK-NEXT: Info: 0
104# CHECK-NEXT: AddressAlignment: 1
105# CHECK-NEXT: EntrySize: 1
106# CHECK-NEXT: SectionData (
107# CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.|
108# CHECK-NEXT: )
109# CHECK-NEXT: }
110# CHECK-NEXT: Section {
111# CHECK-NEXT: Index: 4
112# CHECK-NEXT: Name: .symtab (27)
113# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
114# CHECK-NEXT: Flags [ (0x0)
115# CHECK-NEXT: ]
116# CHECK-NEXT: Address: 0x0
117# CHECK-NEXT: Offset: 0x20008
118# CHECK-NEXT: Size: 24
119# CHECK-NEXT: Link: 6
120# CHECK-NEXT: Info: 1
121# CHECK-NEXT: AddressAlignment: 8
122# CHECK-NEXT: EntrySize: 24
123# CHECK-NEXT: SectionData (
124# CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
125# CHECK-NEXT: 0010: 00000000 00000000 |........|
126# CHECK-NEXT: )
127# CHECK-NEXT: }
128# CHECK-NEXT: Section {
129# CHECK-NEXT: Index: 5
130# CHECK-NEXT: Name: .shstrtab (35)
131# CHECK-NEXT: Type: SHT_STRTAB (0x3)
132# CHECK-NEXT: Flags [ (0x0)
133# CHECK-NEXT: ]
134# CHECK-NEXT: Address: 0x0
135# CHECK-NEXT: Offset: 0x20020
136# CHECK-NEXT: Size: 53
137# CHECK-NEXT: Link: 0
138# CHECK-NEXT: Info: 0
139# CHECK-NEXT: AddressAlignment: 1
140# CHECK-NEXT: EntrySize: 0
141# CHECK-NEXT: SectionData (
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.|
146# CHECK-NEXT: )
147# CHECK-NEXT: }
148# CHECK-NEXT: Section {
149# CHECK-NEXT: Index: 6
150# CHECK-NEXT: Name: .strtab (45)
151# CHECK-NEXT: Type: SHT_STRTAB (0x3)
152# CHECK-NEXT: Flags [ (0x0)
153# CHECK-NEXT: ]
154# CHECK-NEXT: Address: 0x0
155# CHECK-NEXT: Offset: 0x20055
156# CHECK-NEXT: Size: 1
157# CHECK-NEXT: Link: 0
158# CHECK-NEXT: Info: 0
159# CHECK-NEXT: AddressAlignment: 1
160# CHECK-NEXT: EntrySize: 0
161# CHECK-NEXT: SectionData (
162# CHECK-NEXT: 0000: 00 |.|
163# CHECK-NEXT: )
164# CHECK-NEXT: }
165# CHECK-NEXT: ]
166# CHECK-NEXT: ProgramHeaders [
167# CHECK-NEXT: ProgramHeader {
168# CHECK-NEXT: Type: PT_PHDR (0x6)
169# CHECK-NEXT: Offset: 0x40
170# CHECK-NEXT: VirtualAddress: 0x10000040
171# CHECK-NEXT: PhysicalAddress: 0x10000040
172# CHECK-NEXT: FileSize: 280
173# CHECK-NEXT: MemSize: 280
174# CHECK-NEXT: Flags [ (0x4)
175# CHECK-NEXT: PF_R (0x4)
176# CHECK-NEXT: ]
177# CHECK-NEXT: Alignment: 8
178# CHECK-NEXT: }
179# CHECK-NEXT: ProgramHeader {
180# CHECK-NEXT: Type: PT_LOAD (0x1)
181# CHECK-NEXT: Offset: 0x0
182# CHECK-NEXT: VirtualAddress: 0x10000000
183# CHECK-NEXT: PhysicalAddress: 0x10000000
184# CHECK-NEXT: FileSize: 344
185# CHECK-NEXT: MemSize: 344
186# CHECK-NEXT: Flags [ (0x4)
187# CHECK-NEXT: PF_R (0x4)
188# CHECK-NEXT: ]
189# CHECK-NEXT: Alignment: 65536
190# CHECK-NEXT: }
191# CHECK-NEXT: ProgramHeader {
192# CHECK-NEXT: Type: PT_LOAD (0x1)
193# CHECK-NEXT: Offset: 0x10000
194# CHECK-NEXT: VirtualAddress: 0x10010000
195# CHECK-NEXT: PhysicalAddress: 0x10010000
196# CHECK-NEXT: FileSize: 4096
197# CHECK-NEXT: MemSize: 4096
198# CHECK-NEXT: Flags [ (0x5)
199# CHECK-NEXT: PF_R (0x4)
200# CHECK-NEXT: PF_X (0x1)
201# CHECK-NEXT: ]
202# CHECK-NEXT: Alignment: 65536
203# CHECK-NEXT: }
204# CHECK-NEXT: ProgramHeader {
205# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
206# CHECK-NEXT: Offset: 0x0
207# CHECK-NEXT: VirtualAddress: 0x0
208# CHECK-NEXT: PhysicalAddress: 0x0
209# CHECK-NEXT: FileSize: 0
210# CHECK-NEXT: MemSize: 0
211# CHECK-NEXT: Flags [ (0x6)
212# CHECK-NEXT: PF_R (0x4)
213# CHECK-NEXT: PF_W (0x2)
214# CHECK-NEXT: ]
215# CHECK-NEXT: Alignment: 0
216# CHECK-NEXT: }
217# CHECK-NEXT: ]
deps/lld/test/ELF/bss-start-common.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-objdump -t -section-headers %t2 | FileCheck %s
55
66# CHECK: Sections:
7# CHECK: Idx Name Size Address Type
7# CHECK: Idx Name Size VMA Type
88# CHECK: 2 .bss 00000004 0000000000201000 BSS
99# CHECK: SYMBOL TABLE:
1010# CHECK: 0000000000201000 .bss 00000000 __bss_start
deps/lld/test/ELF/bss.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %t2
4// RUN: llvm-readobj -sections %t2 | FileCheck %s
4// RUN: llvm-readobj --sections %t2 | FileCheck %s
55
66// Test that bss takes no space on disk.
77
deps/lld/test/ELF/bsymbolic-undef.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: ld.lld -shared -Bsymbolic %t.o -o %t.so
4# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
4# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
55
66# CHECK: DynamicSymbols [
77# CHECK-NEXT: Symbol {
deps/lld/test/ELF/bsymbolic.s+3-3
......@@ -3,9 +3,9 @@
33// RUN: ld.lld -shared %t.o -o %t0.so
44// RUN: ld.lld -shared -Bsymbolic %t.o -o %t1.so
55// RUN: ld.lld -shared -Bsymbolic-functions %t.o -o %t2.so
6// RUN: llvm-readobj -s %t0.so | FileCheck -check-prefix=NOOPTION %s
7// RUN: llvm-readobj -s %t1.so | FileCheck -check-prefix=SYMBOLIC %s
8// RUN: llvm-readobj -s %t2.so | FileCheck -check-prefix=SYMBOLIC %s
6// RUN: llvm-readobj -S %t0.so | FileCheck -check-prefix=NOOPTION %s
7// RUN: llvm-readobj -S %t1.so | FileCheck -check-prefix=SYMBOLIC %s
8// RUN: llvm-readobj -S %t2.so | FileCheck -check-prefix=SYMBOLIC %s
99
1010// NOOPTION: Section {
1111// NOOPTION: Name: .plt
deps/lld/test/ELF/build-id.s+4-4
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44
55# RUN: ld.lld --build-id %t -o %t2
6# RUN: llvm-readobj -s %t2 | FileCheck -check-prefix=ALIGN %s
6# RUN: llvm-readobj -S %t2 | FileCheck -check-prefix=ALIGN %s
77
88# RUN: ld.lld --build-id %t -o %t2 -threads
99# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s
......@@ -65,15 +65,15 @@ _start:
6565# DEFAULT: Contents of section .note.test:
6666# DEFAULT: Contents of section .note.gnu.build-id:
6767# DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU.
68# DEFAULT-NEXT: 894c04e8 fbf5556b
68# DEFAULT-NEXT: 95849665 2621c734
6969
7070# MD5: Contents of section .note.gnu.build-id:
7171# MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.
72# MD5-NEXT: 6a51bbd7 9e8ee3f9 2e02d213 711cfec9
72# MD5-NEXT: 1882c01f 71698eed 229b3994 eb554c80
7373
7474# SHA1: Contents of section .note.gnu.build-id:
7575# SHA1-NEXT: 04000000 14000000 03000000 474e5500 ............GNU.
76# SHA1-NEXT: 9a8618b1 d6fd0e5c eda73dd8 76de5596
76# SHA1-NEXT: 96820adf d90d5470 0a0c32ff a88c4017
7777
7878# UUID: Contents of section .note.gnu.build-id:
7979# UUID-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.
deps/lld/test/ELF/cgprofile-bad-clusters.s+1-1
......@@ -11,7 +11,7 @@
1111# RUN: echo "G H 5" >> %t.call_graph
1212# RUN: echo "H I 4" >> %t.call_graph
1313# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2
14# RUN: llvm-readobj -symbols %t2 | FileCheck %s
14# RUN: llvm-readobj --symbols %t2 | FileCheck %s
1515
1616 .section .text.A,"ax",@progbits
1717 .globl A
deps/lld/test/ELF/cgprofile-icf.s+2-2
......@@ -6,9 +6,9 @@
66# RUN: echo "A C 40" >> %t.call_graph
77# RUN: echo "C D 61" >> %t.call_graph
88# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t.out -icf=all
9# RUN: llvm-readobj -symbols %t.out | FileCheck %s
9# RUN: llvm-readobj --symbols %t.out | FileCheck %s
1010# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2.out
11# RUN: llvm-readobj -symbols %t2.out | FileCheck %s --check-prefix=NOICF
11# RUN: llvm-readobj --symbols %t2.out | FileCheck %s --check-prefix=NOICF
1212
1313 .section .text.D,"ax",@progbits
1414 .globl D
deps/lld/test/ELF/cgprofile-print.s created+37
......@@ -0,0 +1,37 @@
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 --print-symbol-order=%t3
9# RUN: FileCheck %s --input-file %t3
10
11# CHECK: B
12# CHECK-NEXT: C
13# CHECK-NEXT: D
14# CHECK-NEXT: A
15
16.section .text.A,"ax",@progbits
17.globl A
18A:
19 nop
20
21.section .text.B,"ax",@progbits
22.globl B
23B:
24 nop
25
26.section .text.C,"ax",@progbits
27.globl C
28C:
29 nop
30
31.section .text.D,"ax",@progbits
32.globl D
33D:
34 nop
35
36
37
deps/lld/test/ELF/cgprofile-reproduce.s created+42
......@@ -0,0 +1,42 @@
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 --print-symbol-order=%t3
9# RUN: ld.lld -e A %t --symbol-ordering-file %t3 -o %t2
10# RUN: llvm-readobj --symbols %t2 | FileCheck %s
11
12# CHECK: Name: A
13# CHECK-NEXT: Value: 0x201003
14# CHECK: Name: B
15# CHECK-NEXT: Value: 0x201000
16# CHECK: Name: C
17# CHECK-NEXT: Value: 0x201001
18# CHECK: Name: D
19# CHECK-NEXT: Value: 0x201002
20
21.section .text.A,"ax",@progbits
22.globl A
23A:
24 nop
25
26.section .text.B,"ax",@progbits
27.globl B
28B:
29 nop
30
31.section .text.C,"ax",@progbits
32.globl C
33C:
34 nop
35
36.section .text.D,"ax",@progbits
37.globl D
38D:
39 nop
40
41
42
deps/lld/test/ELF/cgprofile-txt.s+2-2
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44# RUN: ld.lld -e A %t -o %t2
5# RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=NOSORT
5# RUN: llvm-readobj --symbols %t2 | FileCheck %s --check-prefix=NOSORT
66
77# RUN: echo "A B 10" > %t.call_graph
88# RUN: echo "A B 10" >> %t.call_graph
......@@ -25,7 +25,7 @@
2525# RUN: echo "TooManyPreds9 TooManyPreds 10" >> %t.call_graph
2626# RUN: echo "TooManyPreds10 TooManyPreds 11" >> %t.call_graph
2727# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2
28# RUN: llvm-readobj -symbols %t2 | FileCheck %s
28# RUN: llvm-readobj --symbols %t2 | FileCheck %s
2929
3030 .section .text.D,"ax",@progbits
3131D:
deps/lld/test/ELF/cgprofile-txt2.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: echo "C D 40" >> %t.call_graph
77# RUN: echo "D B 10" >> %t.call_graph
88# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2
9# RUN: llvm-readobj -symbols %t2 | FileCheck %s
9# RUN: llvm-readobj --symbols %t2 | FileCheck %s
1010
1111# CHECK: Name: A
1212# CHECK-NEXT: Value: 0x201003
deps/lld/test/ELF/color-diagnostics.test+1-1
......@@ -6,7 +6,7 @@
66# RUN: not ld.lld -xyz -color-diagnostics=always /nosuchfile 2>&1 \
77# RUN: | FileCheck -check-prefix=COLOR %s
88
9# COLOR: {{ld.lld: .\[0;1;31merror: .\[0munknown argument: -xyz}}
9# COLOR: {{ld.lld: .\[0;1;31merror: .\[0munknown argument '-xyz'}}
1010# COLOR: {{ld.lld: .\[0;1;31merror: .\[0mcannot open /nosuchfile}}
1111
1212# RUN: not ld.lld -color-diagnostics=foobar 2>&1 | FileCheck -check-prefix=ERR %s
deps/lld/test/ELF/combreloc.s created+48
......@@ -0,0 +1,48 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
4# RUN: echo 'mov aaa@gotpcrel(%rip), %rax' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
5
6# RUN: ld.lld -shared %t.o %t1.o -o %t.so
7# RUN: llvm-readobj -r --dynamic-table %t.so | FileCheck %s
8# RUN: ld.lld -shared %t.o %t1.o -o %t.so -z combreloc
9# RUN: llvm-readobj -r --dynamic-table %t.so | FileCheck %s
10
11# -z combreloc is the default: sort relocations by (!IsRelative,SymIndex,r_offset),
12# and emit DT_RELACOUNT (except on MIPS) to indicate the number of relative
13# relocations.
14
15# CHECK: Relocations [
16# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
17# CHECK-NEXT: 0x3020 R_X86_64_RELATIVE - 0x3028
18# CHECK-NEXT: 0x20B0 R_X86_64_GLOB_DAT aaa 0x0
19# CHECK-NEXT: 0x3000 R_X86_64_64 aaa 0x0
20# CHECK-NEXT: 0x3018 R_X86_64_64 aaa 0x0
21# CHECK-NEXT: 0x3010 R_X86_64_64 bbb 0x0
22# CHECK-NEXT: 0x3008 R_X86_64_64 ccc 0x0
23# CHECK-NEXT: }
24# CHECK: DynamicSection [
25# CHECK: RELACOUNT 1
26
27# RUN: ld.lld -z nocombreloc -shared %t.o %t1.o -o %t.so
28# RUN: llvm-readobj -r --dynamic-table %t.so | FileCheck --check-prefix=NOCOMB %s
29
30# NOCOMB: Relocations [
31# NOCOMB-NEXT: Section ({{.*}}) .rela.dyn {
32# NOCOMB-NEXT: 0x3000 R_X86_64_64 aaa 0x0
33# NOCOMB-NEXT: 0x3008 R_X86_64_64 ccc 0x0
34# NOCOMB-NEXT: 0x3010 R_X86_64_64 bbb 0x0
35# NOCOMB-NEXT: 0x3018 R_X86_64_64 aaa 0x0
36# NOCOMB-NEXT: 0x3020 R_X86_64_RELATIVE - 0x3028
37# NOCOMB-NEXT: 0x20A0 R_X86_64_GLOB_DAT aaa 0x0
38# NOCOMB-NEXT: }
39# NOCOMB: DynamicSection [
40# NOCOMB-NOT: RELACOUNT
41
42.data
43 .quad aaa
44 .quad ccc
45 .quad bbb
46 .quad aaa
47 .quad relative
48relative:
deps/lld/test/ELF/combrelocs.s deleted-95
......@@ -1,95 +0,0 @@
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 %t.out
5# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s
6
7# RUN: ld.lld -shared %t.o -o %t.out -z combreloc
8# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s
9
10# CHECK: Relocations [
11# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
12# CHECK-NEXT: Relocation {
13# CHECK-NEXT: Offset: 0x1000
14# CHECK-NEXT: Type: R_X86_64_64
15# CHECK-NEXT: Symbol: aaa (1)
16# CHECK-NEXT: Addend: 0x0
17# CHECK-NEXT: }
18# CHECK-NEXT: Relocation {
19# CHECK-NEXT: Offset: 0x1018
20# CHECK-NEXT: Type: R_X86_64_64
21# CHECK-NEXT: Symbol: aaa (1)
22# CHECK-NEXT: Addend: 0x0
23# CHECK-NEXT: }
24# CHECK-NEXT: Relocation {
25# CHECK-NEXT: Offset: 0x1010
26# CHECK-NEXT: Type: R_X86_64_64
27# CHECK-NEXT: Symbol: bbb (2)
28# CHECK-NEXT: Addend: 0x0
29# CHECK-NEXT: }
30# CHECK-NEXT: Relocation {
31# CHECK-NEXT: Offset: 0x1008
32# CHECK-NEXT: Type: R_X86_64_64
33# CHECK-NEXT: Symbol: ccc (3)
34# CHECK-NEXT: Addend: 0x0
35# CHECK-NEXT: }
36# CHECK-NEXT: Relocation {
37# CHECK-NEXT: Offset: 0x1020
38# CHECK-NEXT: Type: R_X86_64_64
39# CHECK-NEXT: Symbol: ddd (4)
40# CHECK-NEXT: Addend: 0x0
41# CHECK-NEXT: }
42# CHECK-NEXT: }
43# CHECK-NEXT: ]
44# CHECK: DynamicSection [
45# CHECK-NEXT: Tag
46# CHECK-NOT: RELACOUNT
47
48# RUN: ld.lld -z nocombreloc -shared %t.o -o %t.out
49# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | \
50# RUN: FileCheck --check-prefix=NOCOMB %s
51
52# NOCOMB: Relocations [
53# NOCOMB-NEXT: Section ({{.*}}) .rela.dyn {
54# NOCOMB-NEXT: Relocation {
55# NOCOMB-NEXT: Offset: 0x1000
56# NOCOMB-NEXT: Type: R_X86_64_64
57# NOCOMB-NEXT: Symbol: aaa (1)
58# NOCOMB-NEXT: Addend: 0x0
59# NOCOMB-NEXT: }
60# NOCOMB-NEXT: Relocation {
61# NOCOMB-NEXT: Offset: 0x1008
62# NOCOMB-NEXT: Type: R_X86_64_64
63# NOCOMB-NEXT: Symbol: ccc (3)
64# NOCOMB-NEXT: Addend: 0x0
65# NOCOMB-NEXT: }
66# NOCOMB-NEXT: Relocation {
67# NOCOMB-NEXT: Offset: 0x1010
68# NOCOMB-NEXT: Type: R_X86_64_64
69# NOCOMB-NEXT: Symbol: bbb (2)
70# NOCOMB-NEXT: Addend: 0x0
71# NOCOMB-NEXT: }
72# NOCOMB-NEXT: Relocation {
73# NOCOMB-NEXT: Offset: 0x1018
74# NOCOMB-NEXT: Type: R_X86_64_64
75# NOCOMB-NEXT: Symbol: aaa (1)
76# NOCOMB-NEXT: Addend: 0x0
77# NOCOMB-NEXT: }
78# NOCOMB-NEXT: Relocation {
79# NOCOMB-NEXT: Offset: 0x1020
80# NOCOMB-NEXT: Type: R_X86_64_64
81# NOCOMB-NEXT: Symbol: ddd (4)
82# NOCOMB-NEXT: Addend: 0x0
83# NOCOMB-NEXT: }
84# NOCOMB-NEXT: }
85# NOCOMB-NEXT: ]
86# NOCOMB: DynamicSection [
87# NOCOMB-NEXT: Tag
88# NOCOMB-NOT: RELACOUNT
89
90.data
91 .quad aaa
92 .quad ccc
93 .quad bbb
94 .quad aaa
95 .quad ddd
deps/lld/test/ELF/comdat-discarded-error.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o
3# RUN: echo '.section .text.foo,"axG",@progbits,foo,comdat; .globl foo; foo:' |\
4# RUN: llvm-mc -filetype=obj -triple=x86_64 - -o %t2.o
5# RUN: echo '.section .text.foo,"axG",@progbits,foo,comdat; .globl bar; bar:' |\
6# RUN: llvm-mc -filetype=obj -triple=x86_64 - -o %t3.o
7
8# RUN: not ld.lld %t2.o %t3.o %t1.o -o /dev/null 2>&1 | FileCheck %s
9
10# CHECK: error: relocation refers to a symbol in a discarded section: bar
11# CHECK-NEXT: >>> defined in {{.*}}3.o
12# CHECK-NEXT: >>> section group signature: foo
13# CHECK-NEXT: >>> prevailing definition is in {{.*}}2.o
14# CHECK-NEXT: >>> referenced by {{.*}}1.o:(.text+0x1)
15
16# CHECK: error: relocation refers to a discarded section: .text.foo
17# CHECK-NEXT: >>> defined in {{.*}}1.o
18# CHECK-NEXT: >>> section group signature: foo
19# CHECK-NEXT: >>> prevailing definition is in {{.*}}2.o
20# CHECK-NEXT: >>> referenced by {{.*}}1.o:(.data+0x0)
21
22.globl _start
23_start:
24 jmp bar
25
26.section .text.foo,"axG",@progbits,foo,comdat
27.data
28 .quad .text.foo
deps/lld/test/ELF/comdat-discarded-gdb-index.s created+63
......@@ -0,0 +1,63 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: ld.lld --gdb-index %t.o %t.o -o %t
4
5## .debug_info has a relocation to .text.foo . The second %t.o is discarded.
6## Check we don't error on the relocation.
7# CHECK: .rela.debug_info {
8# CHECK-NEXT: 0xC R_X86_64_64 .text.foo 0x0
9
10.section .text.foo,"axG",@progbits,foo,comdat
11.globl foo
12.Lfunc_begin0:
13foo:
14 ret
15.Lfunc_end0:
16
17.section .debug_abbrev,"",@progbits
18 .byte 1 # Abbreviation Code
19 .byte 17 # DW_TAG_compile_unit
20 .byte 1 # DW_CHILDREN_yes
21 .byte 17 # DW_AT_low_pc
22 .byte 1 # DW_FORM_addr
23 .byte 18 # DW_AT_high_pc
24 .byte 6 # DW_FORM_data4
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 .quad .Lfunc_begin0 # DW_AT_low_pc
47 .long .Lfunc_end0 - .Lfunc_begin0 # DW_AT_high_pc
48 .byte 2 # Abbrev [2] DW_TAG_subprogram
49 .asciz "foo" # DW_AT_name
50 .byte 0
51.Lcu_end0:
52
53.section .debug_gnu_pubnames,"",@progbits
54 .long .LpubNames_end0 - .LpubNames_begin0
55.LpubNames_begin0:
56 .short 2 # Version
57 .long .Lcu_begin0 # CU Offset
58 .long .Lcu_end0 - .Lcu_begin0
59 .long .Ldie0 - .Lcu_begin0
60 .byte 48 # Attributes: FUNCTION, EXTERNAL
61 .asciz "foo" # External Name
62 .long 0
63.LpubNames_end0:
deps/lld/test/ELF/comdat-discarded-ppc64.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
3# RUN: ld.lld %t.o %t.o -o /dev/null
4# RUN: ld.lld -r --fatal-warnings %t.o %t.o -o /dev/null
5
6## clang/gcc PPC64 may emit a .rela.toc which references a switch table in a
7## discarded .rodata/.text section. The .toc and the .rela.toc are incorrectly
8## not placed in the comdat.
9## Don't error "relocation refers to a discarded section".
10
11.section .text.foo,"axG",@progbits,foo,comdat
12.globl foo
13foo:
14.L0:
15
16.section .toc,"aw"
17.quad .L0
deps/lld/test/ELF/comdat-discarded-reloc.s+32-7
......@@ -1,17 +1,42 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat-discarded-reloc.s -o %t2.o
4# RUN: ld.lld -gc-sections %t.o %t2.o -o %t
4# RUN: ld.lld -gc-sections --noinhibit-exec %t2.o %t.o -o /dev/null
5# RUN: ld.lld -r %t2.o %t.o -o %t 2>&1 | FileCheck --check-prefix=WARN %s
6# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
57
68## ELF spec doesn't allow a relocation to point to a deduplicated
79## COMDAT section. Unfortunately this happens in practice (e.g. .eh_frame)
810## Test case checks we do not crash.
911
10.global bar, _start
12# WARN: warning: relocation refers to a discarded section: .text.bar1
13# WARN-NEXT: >>> referenced by {{.*}}.o:(.rela.text.bar2+0x0)
14# WARN-NOT: warning
1115
12.section .text.foo,"aG",@progbits,group,comdat
16# RELOC: .rela.eh_frame {
17# RELOC-NEXT: R_X86_64_NONE
18# RELOC-NEXT: }
19# RELOC-NEXT: .rela.debug_foo {
20# RELOC-NEXT: R_X86_64_NONE
21# RELOC-NEXT: }
22# RELOC-NEXT: .rela.gcc_except_table {
23# RELOC-NEXT: R_X86_64_NONE
24# RELOC-NEXT: }
1325
14.section .text
15_start:
16 .quad .text.foo
17 .quad bar
26.section .text.bar1,"aG",@progbits,group,comdat
27
28## .text.bar1 in this file is discarded. Warn on the relocation.
29.section .text.bar2,"ax"
30.globl bar
31bar:
32 .quad .text.bar1
33
34## Don't warn on .eh_frame, .debug*, .zdebug*, or .gcc_except_table
35.section .eh_frame,"a"
36 .quad .text.bar1
37
38.section .debug_foo
39 .quad .text.bar1
40
41.section .gcc_except_table,"a"
42 .quad .text.bar1
deps/lld/test/ELF/comdat.s+4-4
......@@ -1,9 +1,9 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o
4// RUN: ld.lld -shared %t.o %t.o %t2.o -o %t
4// RUN: ld.lld -shared %t.o %t2.o -o %t
55// RUN: llvm-objdump -d %t | FileCheck %s
6// RUN: llvm-readobj -s -t %t | FileCheck --check-prefix=READ %s
6// RUN: llvm-readobj -S --symbols %t | FileCheck --check-prefix=READ %s
77
88// Check that we don't crash with --gc-section and that we print a list of
99// reclaimed sections on stderr.
......@@ -19,6 +19,7 @@ foo:
1919 nop
2020
2121// CHECK: Disassembly of section .text2:
22// CHECK-EMPTY:
2223// CHECK-NEXT: foo:
2324// CHECK-NEXT: 1000: {{.*}} nop
2425// CHECK-NOT: nop
......@@ -27,11 +28,10 @@ foo:
2728 call foo
2829
2930// CHECK: Disassembly of section bar:
31// CHECK-EMPTY:
3032// CHECK-NEXT: bar:
3133// 0x1000 - 0x1001 - 5 = -6
32// 0 - 0x1006 - 5 = -4107
3334// CHECK-NEXT: 1001: {{.*}} callq -6
34// CHECK-NEXT: 1006: {{.*}} callq -4107
3535
3636 .section .text3,"axG",@progbits,zed,comdat,unique,0
3737
deps/lld/test/ELF/common-gc.s+2-2
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33
44# RUN: ld.lld %t -o %t2
5# RUN: llvm-readobj -sections -symbols %t2 | FileCheck %s --check-prefix=NOGC
5# RUN: llvm-readobj --sections --symbols %t2 | FileCheck %s --check-prefix=NOGC
66
77# NOGC: Name: .bss
88# NOGC-NEXT: Type:
......@@ -18,7 +18,7 @@
1818# NOGC: Name: foo
1919
2020# RUN: ld.lld -gc-sections %t -o %t1
21# RUN: llvm-readobj -sections -symbols %t1 | FileCheck %s --check-prefix=GC
21# RUN: llvm-readobj --sections --symbols %t1 | FileCheck %s --check-prefix=GC
2222
2323# GC: Name: .bss
2424# GC-NEXT: Type:
deps/lld/test/ELF/common-page.s created+223
......@@ -0,0 +1,223 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4
5# exits with return code 42 on linux
6.globl _start
7_start:
8 nop
9
10# Increase max-page-size to 64k while using the default x86_64 common page size
11# of 4k. If the last loadable segment is executable then lld aligns the next
12# section using the common page size.
13
14# RUN: ld.lld -z max-page-size=0x10000 -z common-page-size=0x1000 %t -o %t2
15# RUN: llvm-readobj --sections -l %t2 | FileCheck --check-prefix=CHECK-MAX %s
16
17# CHECK-MAX: Sections [
18# CHECK-MAX-NEXT: Section {
19# CHECK-MAX-NEXT: Index: 0
20# CHECK-MAX-NEXT: Name: (0)
21# CHECK-MAX-NEXT: Type: SHT_NULL (0x0)
22# CHECK-MAX-NEXT: Flags [ (0x0)
23# CHECK-MAX-NEXT: ]
24# CHECK-MAX-NEXT: Address: 0x0
25# CHECK-MAX-NEXT: Offset: 0x0
26# CHECK-MAX-NEXT: Size: 0
27# CHECK-MAX-NEXT: Link: 0
28# CHECK-MAX-NEXT: Info: 0
29# CHECK-MAX-NEXT: AddressAlignment: 0
30# CHECK-MAX-NEXT: EntrySize: 0
31# CHECK-MAX-NEXT: }
32# CHECK-MAX-NEXT: Section {
33# CHECK-MAX-NEXT: Index: 1
34# CHECK-MAX-NEXT: Name: .text (1)
35# CHECK-MAX-NEXT: Type: SHT_PROGBITS (0x1)
36# CHECK-MAX-NEXT: Flags [ (0x6)
37# CHECK-MAX-NEXT: SHF_ALLOC (0x2)
38# CHECK-MAX-NEXT: SHF_EXECINSTR (0x4)
39# CHECK-MAX-NEXT: ]
40# CHECK-MAX-NEXT: Address: 0x210000
41# CHECK-MAX-NEXT: Offset: 0x10000
42# CHECK-MAX-NEXT: Size: 1
43# CHECK-MAX-NEXT: Link: 0
44# CHECK-MAX-NEXT: Info: 0
45# CHECK-MAX-NEXT: AddressAlignment: 4
46# CHECK-MAX-NEXT: EntrySize: 0
47# CHECK-MAX-NEXT: }
48# CHECK-MAX-NEXT: Section {
49# CHECK-MAX-NEXT: Index: 2
50# CHECK-MAX-NEXT: Name: .comment (7)
51# CHECK-MAX-NEXT: Type: SHT_PROGBITS (0x1)
52# CHECK-MAX-NEXT: Flags [ (0x30)
53# CHECK-MAX-NEXT: SHF_MERGE (0x10)
54# CHECK-MAX-NEXT: SHF_STRINGS (0x20)
55# CHECK-MAX-NEXT: ]
56# CHECK-MAX-NEXT: Address: 0x0
57# CHECK-MAX-NEXT: Offset: 0x11000
58# CHECK-MAX-NEXT: Size: 8
59# CHECK-MAX-NEXT: Link: 0
60# CHECK-MAX-NEXT: Info: 0
61# CHECK-MAX-NEXT: AddressAlignment: 1
62# CHECK-MAX-NEXT: EntrySize: 1
63
64# CHECK-MAX: ProgramHeaders [
65# CHECK-MAX-NEXT: ProgramHeader {
66# CHECK-MAX-NEXT: Type: PT_PHDR (0x6)
67# CHECK-MAX-NEXT: Offset: 0x40
68# CHECK-MAX-NEXT: VirtualAddress: 0x200040
69# CHECK-MAX-NEXT: PhysicalAddress: 0x200040
70# CHECK-MAX-NEXT: FileSize: 224
71# CHECK-MAX-NEXT: MemSize: 224
72# CHECK-MAX-NEXT: Flags [ (0x4)
73# CHECK-MAX-NEXT: PF_R (0x4)
74# CHECK-MAX-NEXT: ]
75# CHECK-MAX-NEXT: Alignment: 8
76# CHECK-MAX-NEXT: }
77# CHECK-MAX-NEXT: ProgramHeader {
78# CHECK-MAX-NEXT: Type: PT_LOAD (0x1)
79# CHECK-MAX-NEXT: Offset: 0x0
80# CHECK-MAX-NEXT: VirtualAddress: 0x200000
81# CHECK-MAX-NEXT: PhysicalAddress: 0x200000
82# CHECK-MAX-NEXT: FileSize: 288
83# CHECK-MAX-NEXT: MemSize: 288
84# CHECK-MAX-NEXT: Flags [ (0x4)
85# CHECK-MAX-NEXT: PF_R (0x4)
86# CHECK-MAX-NEXT: ]
87# CHECK-MAX-NEXT: Alignment: 65536
88# CHECK-MAX-NEXT: }
89# CHECK-MAX-NEXT: ProgramHeader {
90# CHECK-MAX-NEXT: Type: PT_LOAD (0x1)
91# CHECK-MAX-NEXT: Offset: 0x10000
92# CHECK-MAX-NEXT: VirtualAddress: 0x210000
93# CHECK-MAX-NEXT: PhysicalAddress: 0x210000
94# CHECK-MAX-NEXT: FileSize: 4096
95# CHECK-MAX-NEXT: MemSize: 4096
96# CHECK-MAX-NEXT: Flags [ (0x5)
97# CHECK-MAX-NEXT: PF_R (0x4)
98# CHECK-MAX-NEXT: PF_X (0x1)
99# CHECK-MAX-NEXT: ]
100# CHECK-MAX-NEXT: Alignment: 65536
101# CHECK-MAX-NEXT: }
102# CHECK-MAX-NEXT: ProgramHeader {
103# CHECK-MAX-NEXT: Type: PT_GNU_STACK (0x6474E551)
104# CHECK-MAX-NEXT: Offset: 0x0
105# CHECK-MAX-NEXT: VirtualAddress: 0x0
106# CHECK-MAX-NEXT: PhysicalAddress: 0x0
107# CHECK-MAX-NEXT: FileSize: 0
108# CHECK-MAX-NEXT: MemSize: 0
109# CHECK-MAX-NEXT: Flags [ (0x6)
110# CHECK-MAX-NEXT: PF_R (0x4)
111# CHECK-MAX-NEXT: PF_W (0x2)
112# CHECK-MAX-NEXT: ]
113# CHECK-MAX-NEXT: Alignment: 0
114
115# Increase common-page-size to max-page-size. Expect to see a larger offset
116# of the first Section after the executable loadable segment due to the higher
117# alignment requirement.
118
119# RUN: ld.lld -z max-page-size=0x10000 -z common-page-size=0x10000 %t -o %t3
120# RUN: llvm-readobj --sections -l %t3 | FileCheck --check-prefix=CHECK-COMMON %s
121
122# Check that we truncate common-page-size to max-page-size
123
124# RUN: ld.lld -z max-page-size=0x10000 -z common-page-size=0x100000 %t -o %t4
125# RUN: llvm-readobj --sections -l %t4 | FileCheck --check-prefix=CHECK-COMMON %s
126
127# CHECK-COMMON: Sections [
128# CHECK-COMMON-NEXT: Section {
129# CHECK-COMMON-NEXT: Index: 0
130# CHECK-COMMON-NEXT: Name: (0)
131# CHECK-COMMON-NEXT: Type: SHT_NULL (0x0)
132# CHECK-COMMON-NEXT: Flags [ (0x0)
133# CHECK-COMMON-NEXT: ]
134# CHECK-COMMON-NEXT: Address: 0x0
135# CHECK-COMMON-NEXT: Offset: 0x0
136# CHECK-COMMON-NEXT: Size: 0
137# CHECK-COMMON-NEXT: Link: 0
138# CHECK-COMMON-NEXT: Info: 0
139# CHECK-COMMON-NEXT: AddressAlignment: 0
140# CHECK-COMMON-NEXT: EntrySize: 0
141# CHECK-COMMON-NEXT: }
142# CHECK-COMMON-NEXT: Section {
143# CHECK-COMMON-NEXT: Index: 1
144# CHECK-COMMON-NEXT: Name: .text (1)
145# CHECK-COMMON-NEXT: Type: SHT_PROGBITS (0x1)
146# CHECK-COMMON-NEXT: Flags [ (0x6)
147# CHECK-COMMON-NEXT: SHF_ALLOC (0x2)
148# CHECK-COMMON-NEXT: SHF_EXECINSTR (0x4)
149# CHECK-COMMON-NEXT: ]
150# CHECK-COMMON-NEXT: Address: 0x210000
151# CHECK-COMMON-NEXT: Offset: 0x10000
152# CHECK-COMMON-NEXT: Size: 1
153# CHECK-COMMON-NEXT: Link: 0
154# CHECK-COMMON-NEXT: Info: 0
155# CHECK-COMMON-NEXT: AddressAlignment: 4
156# CHECK-COMMON-NEXT: EntrySize: 0
157# CHECK-COMMON-NEXT: }
158# CHECK-COMMON-NEXT: Section {
159# CHECK-COMMON-NEXT: Index: 2
160# CHECK-COMMON-NEXT: Name: .comment (7)
161# CHECK-COMMON-NEXT: Type: SHT_PROGBITS (0x1)
162# CHECK-COMMON-NEXT: Flags [ (0x30)
163# CHECK-COMMON-NEXT: SHF_MERGE (0x10)
164# CHECK-COMMON-NEXT: SHF_STRINGS (0x20)
165# CHECK-COMMON-NEXT: ]
166# CHECK-COMMON-NEXT: Address: 0x0
167# CHECK-COMMON-NEXT: Offset: 0x20000
168# CHECK-COMMON-NEXT: Size: 8
169# CHECK-COMMON-NEXT: Link: 0
170# CHECK-COMMON-NEXT: Info: 0
171# CHECK-COMMON-NEXT: AddressAlignment: 1
172# CHECK-COMMON-NEXT: EntrySize: 1
173
174# CHECK-COMMON: ProgramHeaders [
175# CHECK-COMMON-NEXT: ProgramHeader {
176# CHECK-COMMON-NEXT: Type: PT_PHDR (0x6)
177# CHECK-COMMON-NEXT: Offset: 0x40
178# CHECK-COMMON-NEXT: VirtualAddress: 0x200040
179# CHECK-COMMON-NEXT: PhysicalAddress: 0x200040
180# CHECK-COMMON-NEXT: FileSize: 224
181# CHECK-COMMON-NEXT: MemSize: 224
182# CHECK-COMMON-NEXT: Flags [ (0x4)
183# CHECK-COMMON-NEXT: PF_R (0x4)
184# CHECK-COMMON-NEXT: ]
185# CHECK-COMMON-NEXT: Alignment: 8
186# CHECK-COMMON-NEXT: }
187# CHECK-COMMON-NEXT: ProgramHeader {
188# CHECK-COMMON-NEXT: Type: PT_LOAD (0x1)
189# CHECK-COMMON-NEXT: Offset: 0x0
190# CHECK-COMMON-NEXT: VirtualAddress: 0x200000
191# CHECK-COMMON-NEXT: PhysicalAddress: 0x200000
192# CHECK-COMMON-NEXT: FileSize: 288
193# CHECK-COMMON-NEXT: MemSize: 288
194# CHECK-COMMON-NEXT: Flags [ (0x4)
195# CHECK-COMMON-NEXT: PF_R (0x4)
196# CHECK-COMMON-NEXT: ]
197# CHECK-COMMON-NEXT: Alignment: 65536
198# CHECK-COMMON-NEXT: }
199# CHECK-COMMON-NEXT: ProgramHeader {
200# CHECK-COMMON-NEXT: Type: PT_LOAD (0x1)
201# CHECK-COMMON-NEXT: Offset: 0x10000
202# CHECK-COMMON-NEXT: VirtualAddress: 0x210000
203# CHECK-COMMON-NEXT: PhysicalAddress: 0x210000
204# CHECK-COMMON-NEXT: FileSize: 65536
205# CHECK-COMMON-NEXT: MemSize: 65536
206# CHECK-COMMON-NEXT: Flags [ (0x5)
207# CHECK-COMMON-NEXT: PF_R (0x4)
208# CHECK-COMMON-NEXT: PF_X (0x1)
209# CHECK-COMMON-NEXT: ]
210# CHECK-COMMON-NEXT: Alignment: 65536
211# CHECK-COMMON-NEXT: }
212# CHECK-COMMON-NEXT: ProgramHeader {
213# CHECK-COMMON-NEXT: Type: PT_GNU_STACK (0x6474E551)
214# CHECK-COMMON-NEXT: Offset: 0x0
215# CHECK-COMMON-NEXT: VirtualAddress: 0x0
216# CHECK-COMMON-NEXT: PhysicalAddress: 0x0
217# CHECK-COMMON-NEXT: FileSize: 0
218# CHECK-COMMON-NEXT: MemSize: 0
219# CHECK-COMMON-NEXT: Flags [ (0x6)
220# CHECK-COMMON-NEXT: PF_R (0x4)
221# CHECK-COMMON-NEXT: PF_W (0x2)
222# CHECK-COMMON-NEXT: ]
223# CHECK-COMMON-NEXT: Alignment: 0
deps/lld/test/ELF/common.s+1-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2
44// RUN: ld.lld %t %t2 -o %t3
5// RUN: llvm-readobj -t -s %t3 | FileCheck %s
5// RUN: llvm-readobj --symbols -S %t3 | FileCheck %s
66
77// CHECK: Name: .bss
88// CHECK-NEXT: Type: SHT_NOBITS
deps/lld/test/ELF/compress-debug-sections.s+2-2
......@@ -7,7 +7,7 @@
77# ZLIBCONTENT: Contents of section .debug_str:
88# ZLIBCONTENT-NOT: AAAAAAAAA
99
10# RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS
10# RUN: llvm-readobj -S %t1 | FileCheck %s --check-prefix=ZLIBFLAGS
1111# ZLIBFLAGS: Section {
1212# ZLIBFLAGS: Index:
1313# ZLIBFLAGS: Name: .debug_str
......@@ -24,7 +24,7 @@
2424## Test alias.
2525# RUN: ld.lld %t.o -o %t2 --compress-debug-sections zlib
2626# RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=ZLIBCONTENT
27# RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS
27# RUN: llvm-readobj -S %t2 | FileCheck %s --check-prefix=ZLIBFLAGS
2828
2929# RUN: not ld.lld %t.o -o %t1 --compress-debug-sections=zlib-gabi 2>&1 | \
3030# RUN: FileCheck -check-prefix=ERR %s
deps/lld/test/ELF/compressed-debug-conflict.s+1-1
......@@ -1,6 +1,6 @@
11# REQUIRES: x86, zlib
22# RUN: llvm-mc -filetype=obj -triple i686-linux-gnu -compress-debug-sections=zlib %s -o %t.o
3# RUN: llvm-readobj -sections %t.o | FileCheck -check-prefix=OBJ %s
3# RUN: llvm-readobj --sections %t.o | FileCheck -check-prefix=OBJ %s
44# RUN: not ld.lld %t.o %t.o -o /dev/null 2>&1 | FileCheck -check-prefix=ERROR %s
55
66# OBJ: Sections [
deps/lld/test/ELF/compressed-debug-input.s+5-5
......@@ -1,7 +1,7 @@
11# REQUIRES: zlib, x86
22
33# RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: llvm-readobj -sections %t | FileCheck -check-prefix=ZLIB %s
4# RUN: llvm-readobj --sections %t | FileCheck -check-prefix=ZLIB %s
55# ZLIB: Section {
66# ZLIB: Index: 2
77# ZLIB: Name: .debug_str
......@@ -16,12 +16,12 @@
1616# ZLIB-NEXT: Size:
1717# ZLIB-NEXT: Link:
1818# ZLIB-NEXT: Info:
19# ZLIB-NEXT: AddressAlignment: 1
19# ZLIB-NEXT: AddressAlignment: 8
2020# ZLIB-NEXT: EntrySize: 1
2121# ZLIB-NEXT: }
2222
2323# RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
24# RUN: llvm-readobj -sections %t2 | FileCheck -check-prefix=GNU %s
24# RUN: llvm-readobj --sections %t2 | FileCheck -check-prefix=GNU %s
2525# GNU: Section {
2626# GNU: Index: 2
2727# GNU: Name: .zdebug_str
......@@ -40,10 +40,10 @@
4040# GNU-NEXT: }
4141
4242# RUN: ld.lld --hash-style=sysv %t -o %t.so -shared
43# RUN: llvm-readobj -sections -section-data %t.so | FileCheck -check-prefix=DATA %s
43# RUN: llvm-readobj --sections --section-data %t.so | FileCheck -check-prefix=DATA %s
4444
4545# RUN: ld.lld --hash-style=sysv %t2 -o %t2.so -shared
46# RUN: llvm-readobj -sections -section-data %t2.so | FileCheck -check-prefix=DATA %s
46# RUN: llvm-readobj --sections --section-data %t2.so | FileCheck -check-prefix=DATA %s
4747
4848# DATA: Section {
4949# DATA: Index: 6
deps/lld/test/ELF/compressed-input-alignment.test created+67
......@@ -0,0 +1,67 @@
1# REQUIRES: zlib, x86
2
3# RUN: yaml2obj -docnum=1 %s -o %t.o
4# RUN: ld.lld %t.o %t.o -o %t2
5# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s
6
7# RUN: yaml2obj -docnum=2 %s -o %t.o
8# RUN: ld.lld %t.o %t.o -o %t2
9# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s
10
11# CHECK: Name: .debug_info
12# CHECK-NEXT: Type: SHT_PROGBITS
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: ]
15# CHECK-NEXT: Address: 0x0
16# CHECK-NEXT: Offset: 0xE8
17# CHECK-NEXT: Size: 108
18# CHECK-NEXT: Link: 0
19# CHECK-NEXT: Info: 0
20# CHECK-NEXT: AddressAlignment: 1
21# CHECK-NEXT: EntrySize: 0
22# CHECK-NEXT: SectionData (
23# CHECK-NEXT: 0000: {{.*}} |ABCDEFGHIJKLMNOP|
24# CHECK-NEXT: 0010: {{.*}} |QRSTUVWXYZ.ABCDE|
25# CHECK-NEXT: 0020: {{.*}} |FGHIJKLMNOPQRSTU|
26# CHECK-NEXT: 0030: {{.*}} |VWXYZ.ABCDEFGHIJ|
27# CHECK-NEXT: 0040: {{.*}} |KLMNOPQRSTUVWXYZ|
28# CHECK-NEXT: 0050: {{.*}} |.ABCDEFGHIJKLMNO|
29# CHECK-NEXT: 0060: {{.*}} |PQRSTUVWXYZ.|
30# CHECK-NEXT: )
31# CHECK-NEXT: }
32
33## YAML below is produced from the following code. AddressAlign of .debug_info is 8,
34## while compressed header has ch_addralign = 1. LLD had a bug and did not use the
35## value of ch_addralign at all. We produced broken section content.
36##
37## .section .debug_info,"",@progbits
38## .string "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
39## .string "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
40
41--- !ELF
42FileHeader:
43 Class: ELFCLASS64
44 Data: ELFDATA2LSB
45 Type: ET_REL
46 Machine: EM_X86_64
47Sections:
48 - Name: .debug_info
49 Type: SHT_PROGBITS
50 Flags: [ SHF_COMPRESSED ]
51 AddressAlign: 0x0000000000000008
52 Content: 010000000000000036000000000000000100000000000000789C73747276717573F7F0F4F2F6F1F5F30F080C0A0E090D0B8F888C6270C42D0500ADA00FBF
53
54## YAML below is the same as above, with a single change: ch_addralign field of the compressed
55## header was set to 0. This is allowed by the standard, we have to support it.
56--- !ELF
57FileHeader:
58 Class: ELFCLASS64
59 Data: ELFDATA2LSB
60 Type: ET_REL
61 Machine: EM_X86_64
62Sections:
63 - Name: .debug_info
64 Type: SHT_PROGBITS
65 Flags: [ SHF_COMPRESSED ]
66 AddressAlign: 0x0000000000000008
67 Content: 010000000000000036000000000000000000000000000000789C73747276717573F7F0F4F2F6F1F5F30F080C0A0E090D0B8F888C6270C42D0500ADA00FBF
deps/lld/test/ELF/copy-rel-pie.s+7-6
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
44// RUN: ld.lld %t2.o -o %t2.so -shared
55// RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t.exe -pie
6// RUN: llvm-readobj -s -r %t.exe | FileCheck %s
6// RUN: llvm-readobj -S -r %t.exe | FileCheck %s
77// RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASM %s
88
99.global _start
......@@ -27,21 +27,22 @@ _start:
2727// CHECK-NEXT: SHF_ALLOC
2828// CHECK-NEXT: SHF_WRITE
2929// CHECK-NEXT: ]
30// CHECK-NEXT: Address: 0x4000
30// CHECK-NEXT: Address: 0x3020
3131
3232// CHECK: Relocations [
3333// CHECK-NEXT: Section (4) .rela.dyn {
34// CHECK-NEXT: 0x4000 R_X86_64_COPY foo 0x0
34// CHECK-NEXT: 0x3020 R_X86_64_COPY foo 0x0
3535// CHECK-NEXT: }
3636// CHECK-NEXT: Section (5) .rela.plt {
37// CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT bar 0x0
37// CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT bar 0x0
3838// CHECK-NEXT: }
3939// CHECK-NEXT: ]
4040
4141// (0x1010 + 0x10) - 0x1005 = 27
42// 0x4000 - 0x100a = 12278
42// 0x3020 - 0x100a = 8214
4343
4444// DISASM: Disassembly of section .text:
45// DISASM-EMPTY:
4546// DISASM-NEXT: _start:
4647// DISASM-NEXT: 1000: e8 1b 00 00 00 callq 27
47// DISASM-NEXT: 1005: e8 f6 2f 00 00 callq 12278 <foo>
48// DISASM-NEXT: 1005: e8 16 20 00 00 callq 8214 <foo>
deps/lld/test/ELF/copy-rel-version.s+1-1
......@@ -4,7 +4,7 @@
44// RUN: echo "v1 {}; v2 {};" > %t.ver
55// RUN: ld.lld %t1.o -shared -soname t1.so --version-script=%t.ver -o %t1.so
66// RUN: ld.lld %t.o %t1.so -o %t
7// RUN: llvm-readobj -t %t | FileCheck %s
7// RUN: llvm-readobj --symbols %t | FileCheck %s
88
99.global _start
1010_start:
deps/lld/test/ELF/copy-relocation-zero-abs-addr.s+2-2
......@@ -3,8 +3,8 @@
33// RUN: ld.lld -shared -o %t2.so %t.o
44// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t3.o
55// RUN: ld.lld %t2.so %t3.o -o %t4
6// RUN: llvm-readobj -symbols %t2.so | FileCheck -check-prefix=ABSADDR %s
7// RUN: llvm-readobj -s -r --expand-relocs %t4 | FileCheck %s
6// RUN: llvm-readobj --symbols %t2.so | FileCheck -check-prefix=ABSADDR %s
7// RUN: llvm-readobj -S -r --expand-relocs %t4 | FileCheck %s
88
99// This tests that symbols with absolute addresses are properly
1010// handled. Normal DSO symbols are handled as usual.
deps/lld/test/ELF/debug-gnu-pubnames.s+2-2
......@@ -2,12 +2,12 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33
44# RUN: ld.lld %t.o -o %t1.exe
5# RUN: llvm-readobj -sections %t1.exe | FileCheck %s
5# RUN: llvm-readobj --sections %t1.exe | FileCheck %s
66# CHECK: .debug_gnu_pubnames
77# CHECK: .debug_gnu_pubtypes
88
99# RUN: ld.lld -gdb-index %t.o -o %t2.exe
10# RUN: llvm-readobj -sections %t2.exe | FileCheck %s --check-prefix=GDB
10# RUN: llvm-readobj --sections %t2.exe | FileCheck %s --check-prefix=GDB
1111# GDB-NOT: .debug_gnu_pubnames
1212# GDB-NOT: .debug_gnu_pubtypes
1313
deps/lld/test/ELF/debug-line-obj.s created+175
......@@ -0,0 +1,175 @@
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# When compiling with -ffunction-sections, .debug_line may contain descriptions
6# of locations from the different text sections. Until relocated such
7# descriptions might contain overlapping offsets. Check LLD is able to report
8# the error locations correctly in this case.
9
10# CHECK: error: undefined symbol: foo()
11# CHECK-NEXT: >>> referenced by test.cpp:2
12# CHECK-NEXT: >>> {{.*}}.o:(bar())
13# CHECK-NEXT: >>> referenced by test.cpp:3
14# CHECK-NEXT: >>> {{.*}}.o:(baz())
15
16# The code below is the reduced version of the output
17# from the following invocation and source:
18#
19# // test.cpp:
20# int foo();
21# int bar() { return foo(); }
22# int baz() { return foo(); }
23#
24# clang -gdwarf-5 -ffunction-sections test.cpp -o test.s -S
25
26.text
27.file "test.cpp"
28.section .text._Z3barv,"ax",@progbits
29.globl _Z3barv
30.type _Z3barv,@function
31_Z3barv:
32.Lfunc_begin0:
33 .file 0 "/path" "test.cpp" md5 0x9ff11a8404ab4d032ee2dd4f5f8c4140
34 .loc 0 2 0 # test.cpp:2:0
35 .loc 0 2 20 prologue_end # test.cpp:2:20
36 callq _Z3foov
37 .loc 0 2 13 is_stmt 0 # test.cpp:2:13
38.Lfunc_end0:
39.size _Z3barv, .Lfunc_end0-_Z3barv
40 # -- End function
41.section .text._Z3bazv,"ax",@progbits
42.globl _Z3bazv # -- Begin function _Z3bazv
43 .type _Z3bazv,@function
44_Z3bazv: # @_Z3bazv
45.Lfunc_begin1:
46 .loc 0 3 0 is_stmt 1 # test.cpp:3:0
47 .loc 0 3 20 prologue_end # test.cpp:3:20
48 callq _Z3foov
49 .loc 0 3 13 is_stmt 0 # test.cpp:3:13
50.Lfunc_end1:
51 .size _Z3bazv, .Lfunc_end1-_Z3bazv
52
53.section .debug_str,"MS",@progbits,1
54.Linfo_string0:
55 .asciz "stub"
56
57.section .debug_str_offsets,"",@progbits
58 .long 8
59 .short 5
60 .short 0
61.Lstr_offsets_base0:
62 .long .Linfo_string0
63
64.section .debug_abbrev,"",@progbits
65 .byte 1 # Abbreviation Code
66 .byte 17 # DW_TAG_compile_unit
67 .byte 1 # DW_CHILDREN_yes
68 .byte 37 # DW_AT_producer
69 .byte 37 # DW_FORM_strx1
70 .byte 19 # DW_AT_language
71 .byte 5 # DW_FORM_data2
72 .byte 3 # DW_AT_name
73 .byte 37 # DW_FORM_strx1
74 .byte 114 # DW_AT_str_offsets_base
75 .byte 23 # DW_FORM_sec_offset
76 .byte 16 # DW_AT_stmt_list
77 .byte 23 # DW_FORM_sec_offset
78 .byte 27 # DW_AT_comp_dir
79 .byte 37 # DW_FORM_strx1
80 .byte 115 # DW_AT_addr_base
81 .byte 23 # DW_FORM_sec_offset
82 .byte 17 # DW_AT_low_pc
83 .byte 1 # DW_FORM_addr
84 .byte 85 # DW_AT_ranges
85 .byte 35 # DW_FORM_rnglistx
86 .byte 116 # DW_AT_rnglists_base
87 .byte 23 # DW_FORM_sec_offset
88 .byte 0 # EOM(1)
89 .byte 0 # EOM(2)
90 .byte 2 # Abbreviation Code
91 .byte 46 # DW_TAG_subprogram
92 .byte 0 # DW_CHILDREN_no
93 .byte 17 # DW_AT_low_pc
94 .byte 27 # DW_FORM_addrx
95 .byte 18 # DW_AT_high_pc
96 .byte 6 # DW_FORM_data4
97 .byte 64 # DW_AT_frame_base
98 .byte 24 # DW_FORM_exprloc
99 .byte 110 # DW_AT_linkage_name
100 .byte 37 # DW_FORM_strx1
101 .byte 3 # DW_AT_name
102 .byte 37 # DW_FORM_strx1
103 .byte 58 # DW_AT_decl_file
104 .byte 11 # DW_FORM_data1
105 .byte 59 # DW_AT_decl_line
106 .byte 11 # DW_FORM_data1
107 .byte 73 # DW_AT_type
108 .byte 19 # DW_FORM_ref4
109 .byte 63 # DW_AT_external
110 .byte 25 # DW_FORM_flag_present
111 .byte 0 # EOM(1)
112 .byte 0 # EOM(2)
113 .byte 3 # Abbreviation Code
114 .byte 36 # DW_TAG_base_type
115 .byte 0 # DW_CHILDREN_no
116 .byte 3 # DW_AT_name
117 .byte 37 # DW_FORM_strx1
118 .byte 62 # DW_AT_encoding
119 .byte 11 # DW_FORM_data1
120 .byte 11 # DW_AT_byte_size
121 .byte 11 # DW_FORM_data1
122 .byte 0 # EOM(1)
123 .byte 0 # EOM(2)
124 .byte 0 # EOM(3)
125
126.section .debug_info,"",@progbits
127.Lcu_begin0:
128 .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
129.Ldebug_info_start0:
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 .byte 1 # Abbrev [1] 0xc:0x44 DW_TAG_compile_unit
135 .byte 0 # DW_AT_producer
136 .short 4 # DW_AT_language
137 .byte 0 # DW_AT_name
138 .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
139 .long .Lline_table_start0 # DW_AT_stmt_list
140 .byte 2 # DW_AT_comp_dir
141 .long 0 # DW_AT_addr_base
142 .quad 0 # DW_AT_low_pc
143 .byte 0 # DW_AT_ranges
144 .long 0 # DW_AT_rnglists_base
145 .byte 2 # Abbrev [2] 0x2b:0x10 DW_TAG_subprogram
146 .byte 0 # DW_AT_low_pc
147 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
148 .byte 1 # DW_AT_frame_base
149 .byte 86
150 .byte 3 # DW_AT_linkage_name
151 .byte 0 # DW_AT_name
152 .byte 1 # DW_AT_decl_file
153 .byte 2 # DW_AT_decl_line
154 .long 75 # DW_AT_type
155 # DW_AT_external
156 .byte 2 # Abbrev [2] 0x3b:0x10 DW_TAG_subprogram
157 .byte 1 # DW_AT_low_pc
158 .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
159 .byte 1 # DW_AT_frame_base
160 .byte 86
161 .byte 6 # DW_AT_linkage_name
162 .byte 0 # DW_AT_name
163 .byte 1 # DW_AT_decl_file
164 .byte 3 # DW_AT_decl_line
165 .long 75 # DW_AT_type
166 # DW_AT_external
167 .byte 3 # Abbrev [3] 0x4b:0x4 DW_TAG_base_type
168 .byte 0 # DW_AT_name
169 .byte 5 # DW_AT_encoding
170 .byte 4 # DW_AT_byte_size
171 .byte 0 # End Of Children Mark
172.Ldebug_info_end0:
173
174.section .debug_line,"",@progbits
175.Lline_table_start0:
deps/lld/test/ELF/debug-line-str.s+1-2
......@@ -27,8 +27,7 @@
2727main:
2828.Lfunc_begin0:
2929 .file 0 "/home/path" "test.cpp" md5 0x8ed32099ab837bd13543fd3e8102739f
30 .file 1 "test.cpp" md5 0x8ed32099ab837bd13543fd3e8102739f
31 .loc 1 3 10 prologue_end
30 .loc 0 3 10 prologue_end
3231 jmp _Z3foov
3332.Lfunc_end0:
3433
deps/lld/test/ELF/debug-relocation-none.test+5-4
......@@ -52,7 +52,8 @@ Sections:
5252 Content: '0111001017000000'
5353
5454Symbols:
55 Global:
56 - Name: _start
57 Section: .text
58 - Name: bar
55 - Name: _start
56 Section: .text
57 Binding: STB_GLOBAL
58 - Name: bar
59 Binding: STB_GLOBAL
deps/lld/test/ELF/defsym-reserved-syms.s+2-2
......@@ -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 -o %t %t.o --defsym=foo2=etext
4# RUN: llvm-readobj -t -s %t | FileCheck %s
4# RUN: llvm-readobj --symbols -S %t | FileCheck %s
55
66## Check 'foo2' value is equal to value of 'etext'.
77# CHECK: Symbol {
......@@ -14,7 +14,7 @@
1414## Check 'foo2' value set correctly when using
1515## reserved symbol 'etext' in expression.
1616# RUN: ld.lld -o %t %t.o --defsym=foo2=etext+2
17# RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=EXPR
17# RUN: llvm-readobj --symbols -S %t | FileCheck %s --check-prefix=EXPR
1818# EXPR: Symbol {
1919# EXPR: Name: foo2
2020# EXPR-NEXT: Value: 0x201007
deps/lld/test/ELF/defsym.s+5-4
......@@ -1,12 +1,12 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: ld.lld -o %t %t.o --defsym=foo2=foo1
4# RUN: llvm-readobj -t -s %t | FileCheck %s
4# RUN: llvm-readobj --symbols -S %t | FileCheck %s
55# RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s --check-prefix=USE
66
77## Check that we accept --defsym foo2=foo1 form.
88# RUN: ld.lld -o %t2 %t.o --defsym foo2=foo1
9# RUN: llvm-readobj -t -s %t2 | FileCheck %s
9# RUN: llvm-readobj --symbols -S %t2 | FileCheck %s
1010# RUN: llvm-objdump -d -print-imm-hex %t2 | FileCheck %s --check-prefix=USE
1111
1212## Check we are reporting the error correctly and don't crash
......@@ -36,11 +36,12 @@
3636
3737## Check we can use foo2 and it that it is an alias for foo1.
3838# USE: Disassembly of section .text:
39# USE-EMPTY:
3940# USE-NEXT: _start:
4041# USE-NEXT: movl $0x123, %edx
4142
4243# RUN: ld.lld -o %t %t.o --defsym=foo2=1
43# RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=ABS
44# RUN: llvm-readobj --symbols -S %t | FileCheck %s --check-prefix=ABS
4445
4546# ABS: Symbol {
4647# ABS: Name: foo2
......@@ -53,7 +54,7 @@
5354# ABS-NEXT: }
5455
5556# RUN: ld.lld -o %t %t.o --defsym=foo2=foo1+5
56# RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=EXPR
57# RUN: llvm-readobj --symbols -S %t | FileCheck %s --check-prefix=EXPR
5758
5859# EXPR: Symbol {
5960# EXPR: Name: foo1
deps/lld/test/ELF/deplibs-colon-prefix.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/deplibs-lib_foo.s -o %tfoo.o
5# RUN: rm -rf %t.dir
6# RUN: mkdir -p %t.dir
7# RUN: llvm-ar rc %t.dir/foo.a %tfoo.o
8# RUN: not ld.lld %t.o -o /dev/null -L %t.dir 2>&1 | FileCheck %s -DOBJ=%t.o
9# CHECK: error: [[OBJ]]: unable to find library from dependent library specifier: :foo.a
10
11 .global _start
12_start:
13 call foo
14 .section ".deplibs","MS",@llvm_dependent_libraries,1
15 .asciz ":foo.a"
deps/lld/test/ELF/deplibs-corrupt.s created+8
......@@ -0,0 +1,8 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: not ld.lld %t.o -o /dev/null -L %t.dir 2>&1 | FileCheck %s -DOBJ=%t.o
5# CHECK: error: [[OBJ]]: corrupted dependent libraries section (unterminated string): .deplibs
6
7.section ".deplibs","MS",@llvm_dependent_libraries,1
8 .ascii ":foo.a"
deps/lld/test/ELF/deplibs.s created+56
......@@ -0,0 +1,56 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/deplibs-lib_foo.s -o %tfoo.o
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/deplibs-lib_bar.s -o %tbar.o
6# RUN: rm -rf %t.dir %t.cwd
7# RUN: mkdir -p %t.dir
8
9# error if dependent libraries cannot be found
10# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s -DOBJ=%t.o --check-prefix MISSING
11# MISSING: error: [[OBJ]]: unable to find library from dependent library specifier: foo.a
12# MISSING-NEXT: error: [[OBJ]]: unable to find library from dependent library specifier: bar
13
14# can ignore dependent libraries
15# RUN: not ld.lld %t.o -o /dev/null --no-dependent-libraries 2>&1 | FileCheck %s --check-prefix IGNORE
16# IGNORE: error: undefined symbol: foo
17# IGNORE: error: undefined symbol: bar
18
19# -r links preserve dependent libraries
20# RUN: ld.lld %t.o %t.o -r -o %t-r.o
21# RUN: not ld.lld %t-r.o -o /dev/null 2>&1 | sort | FileCheck %s -DOBJ=%t-r.o --check-prefixes MINUSR
22# MINUSR: error: [[OBJ]]: unable to find library from dependent library specifier: bar
23# MINUSR-NEXT: error: [[OBJ]]: unable to find library from dependent library specifier: foo.a
24# MINUSR-NOT: unable to find library from dependent library specifier
25
26# static archives located relative to library search paths
27# RUN: llvm-ar rc %t.dir/foo.a %tfoo.o
28# RUN: llvm-ar rc %t.dir/libbar.a %tbar.o
29# RUN: ld.lld %t.o -o /dev/null -L %t.dir
30
31# shared objects located relative to library search paths
32# RUN: rm %t.dir/libbar.a
33# RUN: ld.lld -shared -o %t.dir/libbar.so %tbar.o
34# RUN: ld.lld -Bdynamic %t.o -o /dev/null -L %t.dir
35
36# dependent libraries searched for symbols after libraries on the command line
37# RUN: mkdir -p %t.cwd
38# RUN: cd %t.cwd
39# RUN: cp %t.dir/foo.a %t.cwd/libcmdline.a
40# RUN: ld.lld %t.o libcmdline.a -o /dev/null -L %t.dir --trace 2>&1 | FileCheck %s -DOBJ=%t.o -DSO=%t.dir --check-prefix CMDLINE --implicit-check-not foo.a
41# CMDLINE: [[OBJ]]
42# CMDLINE-NEXT: {{^libcmdline\.a}}
43# CMDLINE-NEXT: [[SO]]{{[\\/]}}libbar.so
44
45# libraries can be found from specifiers as if the specifiers were listed on on the command-line.
46# RUN: cp %t.dir/foo.a %t.cwd/foo.a
47# RUN: ld.lld %t.o -o /dev/null -L %t.dir --trace 2>&1 | FileCheck %s -DOBJ=%t.o -DSO=%t.dir --check-prefix ASIFCMDLINE --implicit-check-not foo.a
48# ASIFCMDLINE: [[OBJ]]
49# ASIFCMDLINE-NEXT: {{^foo\.a}}
50# ASIFCMDLINE-NEXT: [[SO]]{{[\\/]}}libbar.so
51
52 call foo
53 call bar
54.section ".deplibs","MS",@llvm_dependent_libraries,1
55 .asciz "foo.a"
56 .asciz "bar"
deps/lld/test/ELF/discard-locals.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t
33// RUN: ld.lld -discard-locals %t -o %t2
4// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
4// RUN: llvm-readobj -S --section-data --symbols %t2 | FileCheck %s
55
66.global _start
77_start:
deps/lld/test/ELF/discard-merge-locals.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33// RUN: ld.lld %t -o %t2 -shared
4// RUN: llvm-readobj -t %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55
66 leaq .L.str(%rip), %rdi
77
deps/lld/test/ELF/discard-merge-unnamed.s+1-1
......@@ -1,5 +1,5 @@
11// RUN: ld.lld %p/Inputs/discard-merge-unnamed.o -o %t2 -shared
2// RUN: llvm-readobj -t %t2 | FileCheck %s
2// RUN: llvm-readobj --symbols %t2 | FileCheck %s
33
44// Test that the unnamed symbol is SHF_MERGE is omitted.
55
deps/lld/test/ELF/discard-none.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t
33// RUN: ld.lld -discard-none -shared %t -o %t2
4// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
4// RUN: llvm-readobj -S --section-data --symbols %t2 | FileCheck %s
55
66.text
77.Lmyvar:
deps/lld/test/ELF/driver.test+7-3
......@@ -1,10 +1,10 @@
11# REQUIRES: x86
22
3# RUN: not ld.lld --unknown1 --unknown2 -m foo /no/such/file -lnosuchlib \
3# RUN: not ld.lld --unknown1 --unkn=own2 -m foo /no/such/file -lnosuchlib \
44# RUN: 2>&1 | FileCheck -check-prefix=UNKNOWN %s
55
6# UNKNOWN: unknown argument: --unknown1
7# UNKNOWN: unknown argument: --unknown2
6# UNKNOWN: unknown argument '--unknown1'
7# UNKNOWN: unknown argument '--unkn=own2'
88# UNKNOWN: unknown emulation: foo
99# UNKNOWN: cannot open /no/such/file
1010# UNKNOWN: unable to find library -lnosuchlib
......@@ -22,6 +22,9 @@
2222# RUN: not ld.lld -v xyz 2>&1 | FileCheck -check-prefix=VERSION %s
2323# VERSION: LLD {{.*}} (compatible with GNU linkers)
2424
25# RUN: not ld.lld --versin 2>&1 | FileCheck -check-prefix=SPELLVERSION %s
26# SPELLVERSION: unknown argument '--versin', did you mean '--version'
27
2528## Attempt to link DSO with -r
2629# RUN: ld.lld -shared %t -o %t.so
2730# RUN: not ld.lld -r %t.so %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR %s
......@@ -60,6 +63,7 @@
6063# ERR9: cannot open output file utput=/no/such/file
6164
6265# RUN: not ld.lld %t -z foo 2>&1 | FileCheck -check-prefix=ERR10 %s
66# RUN: not ld.lld %t -z foo --version 2>&1 | FileCheck -check-prefix=ERR10 %s
6367# ERR10: unknown -z value: foo
6468
6569## Check we report "unknown -z value" error even with -v.
deps/lld/test/ELF/dso-undef-size.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: ld.lld -shared %t1.o -o %t1.so
44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
55# RUN: ld.lld -shared %t2.o %t1.so -o %t2.so
6# RUN: llvm-readobj -symbols -dyn-symbols %t2.so
6# RUN: llvm-readobj --symbols --dyn-syms %t2.so
77
88# CHECK: Symbols [
99# CHECK-NEXT: Symbol {
deps/lld/test/ELF/dso_handle.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
44# RUN: ld.lld -shared %t.o -o %t
5# RUN: llvm-readobj -symbols %t | FileCheck %s
5# RUN: llvm-readobj --symbols %t | FileCheck %s
66# CHECK: Name: __dso_handle
77# CHECK-NEXT: Value: 0x0
88# CHECK-NEXT: Size: 0
deps/lld/test/ELF/dt_flags.s+3-3
......@@ -5,13 +5,13 @@
55
66# RUN: ld.lld -z global -z initfirst -z interpose -z now -z nodefaultlib \
77# RUN: -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1
8# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s
8# RUN: llvm-readobj --dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s
99
1010# RUN: ld.lld %t %t.so -o %t2
11# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
11# RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
1212
1313# RUN: ld.lld -z lazy %t %t.so -o %t2
14# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
14# RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
1515
1616# FLAGS: DynamicSection [
1717# FLAGS: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW
deps/lld/test/ELF/dt_tags.s+2-2
......@@ -3,8 +3,8 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
44# RUN: ld.lld -shared %t -o %t.so
55# RUN: ld.lld %t %t.so -o %t.exe
6# RUN: llvm-readobj -dynamic-table %t.so | FileCheck -check-prefix=DSO %s
7# RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=EXE %s
6# RUN: llvm-readobj --dynamic-table %t.so | FileCheck -check-prefix=DSO %s
7# RUN: llvm-readobj --dynamic-table %t.exe | FileCheck -check-prefix=EXE %s
88
99# EXE: DynamicSection [
1010# EXE: 0x0000000000000015 DEBUG 0x0
deps/lld/test/ELF/dtrace-r.test deleted-8
......@@ -1,8 +0,0 @@
1RUN: ld.lld -r -o %t.o %p/Inputs/dtrace-r.o
2RUN: llvm-readobj -r %t.o | FileCheck %s
3
4CHECK: Relocations [
5CHECK-NEXT: Section ({{.*}}) .rela.text {
6CHECK-NEXT: 0x0 R_X86_64_NONE - 0x0
7CHECK-NEXT: }
8CHECK-NEXT: ]
deps/lld/test/ELF/dynamic-got-rela.s+3-3
......@@ -1,11 +1,11 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: ld.lld %t.o -o %t.so -shared --apply-dynamic-relocs
4// RUN: llvm-readobj -r -s -l -section-data %t.so | FileCheck -check-prefix CHECK -check-prefix APPLYDYNREL %s
4// RUN: llvm-readobj -r -S -l --section-data %t.so | FileCheck -check-prefix CHECK -check-prefix APPLYDYNREL %s
55// RUN: ld.lld %t.o -o %t2.so -shared
6// RUN: llvm-readobj -r -s -l -section-data %t2.so | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
6// RUN: llvm-readobj -r -S -l --section-data %t2.so | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
77// RUN: ld.lld %t.o -o %t2.so -shared --no-apply-dynamic-relocs
8// RUN: llvm-readobj -r -s -l -section-data %t2.so | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
8// RUN: llvm-readobj -r -S -l --section-data %t2.so | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
99
1010// APPLYDYNREL: Name: .got
1111// APPLYDYNREL-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/dynamic-got.s+23-23
......@@ -1,24 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
33// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -l -section-data -r %t.so | FileCheck %s
5
6// CHECK: Name: .got.plt
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_WRITE
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address:
13// CHECK-NEXT: Offset:
14// CHECK-NEXT: Size:
15// CHECK-NEXT: Link:
16// CHECK-NEXT: Info:
17// CHECK-NEXT: AddressAlignment:
18// CHECK-NEXT: EntrySize:
19// CHECK-NEXT: SectionData (
20// CHECK-NEXT: 0000: 00300000 00000000 00000000
21// CHECK-NEXT: )
4// RUN: llvm-readobj -S -l --section-data -r %t.so | FileCheck %s
225
236// CHECK: Name: .got
247// CHECK-NEXT: Type: SHT_PROGBITS
......@@ -34,19 +17,36 @@
3417// CHECK-NEXT: AddressAlignment:
3518// CHECK-NEXT: EntrySize:
3619// CHECK-NEXT: SectionData (
37// CHECK-NEXT: 0000: 00300000
20// CHECK-NEXT: 0000: 00200000
3821// CHECK-NEXT: )
3922
23// CHECK: Name: .got.plt
24// CHECK-NEXT: Type: SHT_PROGBITS
25// CHECK-NEXT: Flags [
26// CHECK-NEXT: SHF_ALLOC
27// CHECK-NEXT: SHF_WRITE
28// CHECK-NEXT: ]
29// CHECK-NEXT: Address:
30// CHECK-NEXT: Offset:
31// CHECK-NEXT: Size:
32// CHECK-NEXT: Link:
33// CHECK-NEXT: Info:
34// CHECK-NEXT: AddressAlignment:
35// CHECK-NEXT: EntrySize:
36// CHECK-NEXT: SectionData (
37// CHECK-NEXT: 0000: 00200000 00000000 00000000
38// CHECK-NEXT: )
39
4040// CHECK: Relocations [
4141// CHECK-NEXT: Section ({{.*}}) .rel.dyn {
42// CHECK-NEXT: 0x3050 R_386_RELATIVE - 0x0
42// CHECK-NEXT: 0x2050 R_386_RELATIVE - 0x0
4343// CHECK-NEXT: }
4444// CHECK-NEXT: ]
4545
4646// CHECK: Type: PT_DYNAMIC
47// CHECK-NEXT: Offset: 0x3000
48// CHECK-NEXT: VirtualAddress: 0x3000
49// CHECK-NEXT: PhysicalAddress: 0x3000
47// CHECK-NEXT: Offset: 0x2000
48// CHECK-NEXT: VirtualAddress: 0x2000
49// CHECK-NEXT: PhysicalAddress: 0x2000
5050
5151 calll .L0$pb
5252.L0$pb:
deps/lld/test/ELF/dynamic-list-preempt-replace-symbol.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
4# RUN: echo '{ common; };' > %t.list
5# RUN: ld.lld --dynamic-list %t.list -shared %t.o -o %t.so
6
7# RUN: llvm-readobj -r %t.so | FileCheck %s
8
9# CHECK: R_X86_64_GLOB_DAT common 0x0
10
11movq common@gotpcrel(%rip), %rax
12
13.type common,@object
14.comm common,4,4
deps/lld/test/ELF/dynamic-list-preempt.s+7-2
......@@ -5,11 +5,16 @@
55# RUN: echo "{ global: foo; bar; local: *; };" > %t.vers
66# RUN: ld.lld --hash-style=sysv -fatal-warnings -dynamic-list %t.list -version-script %t.vers -shared %t.o -o %t.so
77# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOCS %s
8# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=DYNSYMS %s
8# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=DYNSYMS %s
9
10# RUN: echo "V1 { global: foo; bar; local: *; };" > %t.vers
11# RUN: ld.lld --hash-style=sysv -fatal-warnings -dynamic-list %t.list -version-script %t.vers -shared %t.o -o %t.so
12# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOCS %s
13# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=DYNSYMS %s
914
1015# RELOCS: Relocations [
1116# RELOCS-NEXT: Section ({{.*}}) .rela.plt {
12# RELOCS-NEXT: R_X86_64_JUMP_SLOT foo 0x0
17# RELOCS-NEXT: R_X86_64_JUMP_SLOT foo{{.*}} 0x0
1318# RELOCS-NEXT: R_X86_64_JUMP_SLOT ext 0x0
1419# RELOCS-NEXT: }
1520# RELOCS-NEXT: ]
deps/lld/test/ELF/dynamic-list-weak-archive.s+1-1
......@@ -10,7 +10,7 @@
1010
1111# CHECK: Relocations [
1212# CHECK-NEXT: Section ({{.*}}) .rela.plt {
13# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo
13# CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT foo
1414# CHECK-NEXT: }
1515# CHECK-NEXT: ]
1616
deps/lld/test/ELF/dynamic-list-wildcard.s+1-1
......@@ -4,7 +4,7 @@
44
55# RUN: echo "{ foo1*; };" > %t.list
66# RUN: ld.lld --hash-style=sysv -pie --dynamic-list %t.list %t -o %t.exe
7# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
7# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck %s
88
99# CHECK: DynamicSymbols [
1010# CHECK-NEXT: Symbol {
deps/lld/test/ELF/dynamic-list.s+8-8
......@@ -7,19 +7,19 @@
77## Check exporting only one symbol.
88# RUN: echo "{ foo1; };" > %t.list
99# RUN: ld.lld --hash-style=sysv --dynamic-list %t.list %t %t2.so -o %t.exe
10# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
10# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck %s
1111
1212## And now using quoted strings (the output is the same since it does
1313## use any wildcard character).
1414# RUN: echo "{ \"foo1\"; };" > %t.list
1515# RUN: ld.lld --hash-style=sysv --dynamic-list %t.list %t %t2.so -o %t.exe
16# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
16# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck %s
1717
1818## And now using --export-dynamic-symbol.
1919# RUN: ld.lld --hash-style=sysv --export-dynamic-symbol foo1 %t %t2.so -o %t.exe
20# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
20# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck %s
2121# RUN: ld.lld --hash-style=sysv --export-dynamic-symbol=foo1 %t %t2.so -o %t.exe
22# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
22# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck %s
2323
2424# CHECK: DynamicSymbols [
2525# CHECK-NEXT: Symbol {
......@@ -46,11 +46,11 @@
4646## Now export all the foo1, foo2, and foo31 symbols
4747# RUN: echo "{ foo1; foo2; foo31; };" > %t.list
4848# RUN: ld.lld --hash-style=sysv --dynamic-list %t.list %t %t2.so -o %t.exe
49# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s
49# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck -check-prefix=CHECK2 %s
5050# RUN: echo "{ foo1; foo2; };" > %t1.list
5151# RUN: echo "{ foo31; };" > %t2.list
5252# RUN: ld.lld --hash-style=sysv --dynamic-list %t1.list --dynamic-list %t2.list %t %t2.so -o %t.exe
53# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s
53# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck -check-prefix=CHECK2 %s
5454
5555# CHECK2: DynamicSymbols [
5656# CHECK2-NEXT: Symbol {
......@@ -96,11 +96,11 @@
9696## incomplete dynamic-list still exports everything.
9797# RUN: echo "{ foo2; };" > %t.list
9898# RUN: ld.lld --hash-style=sysv --dynamic-list %t.list --export-dynamic %t %t2.so -o %t.exe
99# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK3 %s
99# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck -check-prefix=CHECK3 %s
100100
101101## The same with --export-dynamic-symbol.
102102# RUN: ld.lld --hash-style=sysv --export-dynamic-symbol=foo2 --export-dynamic %t %t2.so -o %t.exe
103# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK3 %s
103# RUN: llvm-readobj --dyn-syms %t.exe | FileCheck -check-prefix=CHECK3 %s
104104
105105# CHECK3: DynamicSymbols [
106106# CHECK3-NEXT: Symbol {
deps/lld/test/ELF/dynamic-no-rosegment.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 -shared --no-rosegment -z rodynamic -o %t %t.o
4# RUN: llvm-readobj -dynamic-table -s %t | FileCheck %s
4# RUN: llvm-readobj --dynamic-table -S %t | FileCheck %s
55
66# CHECK: DynamicSection [ (7 entries)
77# CHECK-NEXT: Tag Type Name/Value
deps/lld/test/ELF/dynamic-reloc-index.s+1-1
......@@ -9,7 +9,7 @@
99
1010// CHECK: Relocations [
1111// CHECK-NEXT: Section ({{.*}}) .rela.plt {
12// CHECK-NEXT: 0x202018 R_X86_64_JUMP_SLOT bar 0x0
12// CHECK-NEXT: 0x203018 R_X86_64_JUMP_SLOT bar 0x0
1313// CHECK-NEXT: }
1414// CHECK-NEXT: ]
1515
deps/lld/test/ELF/dynamic-reloc.s+3-3
......@@ -4,7 +4,7 @@
44// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc.s -o %t3.o
55// RUN: ld.lld -shared %t2.o -o %t2.so
66// RUN: ld.lld --hash-style=sysv %t.o %t3.o %t2.so -o %t
7// RUN: llvm-readobj -dynamic-table -r --expand-relocs -s %t | FileCheck %s
7// RUN: llvm-readobj --dynamic-table -r --expand-relocs -S %t | FileCheck %s
88
99// CHECK: Index: 1
1010// CHECK-NEXT: Name: .dynsym
......@@ -18,7 +18,7 @@
1818// CHECK-NEXT: Offset:
1919// CHECK-NEXT: Size: [[RELASIZE:.*]]
2020// CHECK-NEXT: Link: 1
21// CHECK-NEXT: Info: 7
21// CHECK-NEXT: Info: 8
2222// CHECK-NEXT: AddressAlignment: 8
2323// CHECK-NEXT: EntrySize: 24
2424
......@@ -33,7 +33,7 @@
3333// CHECK: Relocations [
3434// CHECK-NEXT: Section ({{.*}}) .rela.plt {
3535// CHECK-NEXT: Relocation {
36// CHECK-NEXT: Offset: 0x202018
36// CHECK-NEXT: Offset: 0x203018
3737// CHECK-NEXT: Type: R_X86_64_JUMP_SLOT
3838// CHECK-NEXT: Symbol: bar
3939// CHECK-NEXT: Addend: 0x0
deps/lld/test/ELF/dynamic.s+2-2
......@@ -4,7 +4,7 @@
44## Check that _DYNAMIC symbol is created when creating dynamic output,
55## and has hidden visibility and address equal to .dynamic section.
66# RUN: ld.lld -shared %t.o -o %t.so
7# RUN: llvm-readobj -sections -symbols %t.so | FileCheck %s
7# RUN: llvm-readobj --sections --symbols %t.so | FileCheck %s
88# CHECK: Section {
99# CHECK: Index: 5
1010# CHECK: Name: .dynamic
......@@ -35,7 +35,7 @@
3535# CHECK-NEXT: }
3636
3737# RUN: ld.lld %t.o -o %t2
38# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=NODYN %s
38# RUN: llvm-readobj --sections --symbols %t2 | FileCheck -check-prefix=NODYN %s
3939# NODYN: Symbols [
4040# NODYN-NOT: Name: _DYNAMIC
4141# NODYN: ]
deps/lld/test/ELF/dynsym-no-rosegment.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 -shared --no-rosegment -o %t %t.o
4# RUN: llvm-readobj -dyn-symbols -s %t | FileCheck %s
4# RUN: llvm-readobj --dyn-syms -S %t | FileCheck %s
55
66# CHECK: DynamicSymbols [
77# CHECK-NEXT: Symbol {
deps/lld/test/ELF/dynsym-pie.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33# RUN: ld.lld -pie %t -o %t.out
4# RUN: llvm-readobj -t -dyn-symbols %t.out | FileCheck %s
4# RUN: llvm-readobj --symbols --dyn-syms %t.out | FileCheck %s
55
66# CHECK: Symbols [
77# CHECK: Symbol {
deps/lld/test/ELF/edata-etext.s+1-1
......@@ -12,7 +12,7 @@
1212## 3) Address of _end is different from _edata because of 2.
1313## 4) Addresses of _edata == edata, _end == end and _etext == etext.
1414# CHECK: Sections:
15# CHECK-NEXT: Idx Name Size Address Type
15# CHECK-NEXT: Idx Name Size VMA Type
1616# CHECK-NEXT: 0 00000000 0000000000000000
1717# CHECK-NEXT: 1 .text 00000001 0000000000201000 TEXT
1818# CHECK-NEXT: 2 .data 00000002 0000000000202000 DATA
deps/lld/test/ELF/eh-align-cie.s+2-2
......@@ -9,7 +9,7 @@
99bar:
1010
1111// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
12// RUN: llvm-readobj -s -section-data %t.o | FileCheck --check-prefix=OBJ %s
12// RUN: llvm-readobj -S --section-data %t.o | FileCheck --check-prefix=OBJ %s
1313
1414// Check the size of the CIE (0x18 + 4) an FDE (0x10 + 4)
1515// OBJ: Name: .eh_frame
......@@ -32,7 +32,7 @@ bar:
3232
3333
3434// RUN: ld.lld --hash-style=sysv %t.o -o %t -shared
35// RUN: llvm-readobj -s -section-data %t | FileCheck %s
35// RUN: llvm-readobj -S --section-data %t | FileCheck %s
3636
3737// Check that the size of the CIE was changed to (0x1C + 4) and the FDE one was
3838// changed to (0x14 + 4)
deps/lld/test/ELF/eh-frame-begin-end.s+1-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=amd64-unknown-openbsd %s -o %t.o
33// RUN: llvm-mc -filetype=obj -triple=amd64-unknown-openbsd %p/Inputs/eh-frame-end.s -o %t2.o
44// RUN: ld.lld %t.o %t2.o -o %t
5// RUN: llvm-readobj -sections %t | FileCheck %s
5// RUN: llvm-readobj --sections %t | FileCheck %s
66
77// CHECK: Name: .eh_frame
88// CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/eh-frame-gc.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 -shared --gc-sections %t.o -o %t
4# RUN: llvm-readobj -s %t | FileCheck %s
4# RUN: llvm-readobj -S %t | FileCheck %s
55
66## Check that section containing personality is
77## not garbage collected.
deps/lld/test/ELF/eh-frame-gc2.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 --gc-sections %t.o -o %t
4// RUN: llvm-readobj -s %t | FileCheck %s
4// RUN: llvm-readobj -S %t | FileCheck %s
55
66// Test that the we don't gc the personality function.
77// CHECK: Name: .foobar
deps/lld/test/ELF/eh-frame-hdr-abs-fde.s+9-9
......@@ -1,23 +1,23 @@
1# REQUIRES: mips
1# REQUIRES: x86
22# Check reading PC values of FDEs and writing lookup table in the .eh_frame_hdr
33# if CIE augmentation string has 'L' token and PC values are encoded using
44# absolute (not relative) format.
55
6# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
6# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s -o %t.o
77# RUN: ld.lld --eh-frame-hdr %t.o -o %t
88# RUN: llvm-objdump -s -dwarf=frames %t | FileCheck %s
99
1010# CHECK: Contents of section .eh_frame_hdr:
11# CHECK-NEXT: 10128 011b033b 00000010 00000001 0000fed8
12# ^-- 0x20000 - 0x10138
13# .text - .eh_frame_hdr
14# CHECK-NEXT: 10138 0000002c
11# CHECK-NEXT: 200190 011b033b 14000000 01000000 700e0000
12# ^-- 0x201000 - 0x200190
13# .text - .eh_frame_hdr
14# CHECK-NEXT: 2001a0 30000000
1515# CHECK: Contents of section .text:
16# CHECK-NEXT: 20000 00000000
16# CHECK-NEXT: 201000 90
1717
1818# CHECK: Augmentation: "zLR"
19# CHECK: Augmentation data: 00 0B
20# ^-- DW_EH_PE_udata4 | DW_EH_PE_signed
19# CHECK: Augmentation data: 00 1B
20# ^-- DW_EH_PE_pcrel | DW_EH_PE_udata4 | DW_EH_PE_signed
2121
2222 .text
2323 .globl __start
deps/lld/test/ELF/eh-frame-hdr-augmentation.s+2-2
......@@ -11,7 +11,7 @@
1111// CHECK-NEXT: Code alignment factor: 1
1212// CHECK-NEXT: Data alignment factor: -8
1313// CHECK-NEXT: Return address column: 16
14// CHECK-NEXT: Personality Address: 00000dad
14// CHECK-NEXT: Personality Address: 0000000000000dad
1515// CHECK-NEXT: Augmentation data:
1616
1717// CHECK: DW_CFA_def_cfa: reg7 +8
......@@ -20,7 +20,7 @@
2020// CHECK-NEXT: DW_CFA_nop:
2121
2222// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000d98...00000d98
23// CHECK-NEXT: LSDA Address: 00000d8f
23// CHECK-NEXT: LSDA Address: 0000000000000d8f
2424// CHECK-NEXT: DW_CFA_nop:
2525// CHECK-NEXT: DW_CFA_nop:
2626// CHECK-NEXT: DW_CFA_nop:
deps/lld/test/ELF/eh-frame-hdr-icf-fde.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
77# RUN: ld.lld %t -o %t2 --icf=all --eh-frame-hdr
88# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=OBJ
9# RUN: llvm-readobj -s -section-data %t2 | FileCheck %s
9# RUN: llvm-readobj -S --section-data %t2 | FileCheck %s
1010
1111# OBJ: Relocations [
1212# OBJ-NEXT: Section {{.*}} .rela.eh_frame {
deps/lld/test/ELF/eh-frame-hdr-no-out2.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 --eh-frame-hdr %t.o -o %t
4// RUN: llvm-readobj -s -program-headers %t | FileCheck %s --check-prefix=NOHDR
4// RUN: llvm-readobj -S -l %t | FileCheck %s --check-prefix=NOHDR
55
66.section foo,"ax",@progbits
77 nop
deps/lld/test/ELF/eh-frame-hdr.s+17-12
......@@ -2,15 +2,15 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33
44// RUN: ld.lld %t.o -o %t
5// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t \
5// RUN: llvm-readobj --file-headers -S --section-data -l --symbols %t \
66// RUN: | FileCheck %s --check-prefix=NOHDR
77
88// RUN: ld.lld -eh-frame-hdr -no-eh-frame-hdr %t.o -o %t
9// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t \
9// RUN: llvm-readobj --file-headers -S --section-data -l --symbols %t \
1010// RUN: | FileCheck %s --check-prefix=NOHDR
1111
1212// RUN: ld.lld --eh-frame-hdr %t.o -o %t
13// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t \
13// RUN: llvm-readobj --file-headers -S --section-data -l --symbols %t \
1414// RUN: | FileCheck %s --check-prefix=HDR
1515// RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=HDRDISASM
1616
......@@ -38,15 +38,20 @@ _start:
3838// NOHDR: ProgramHeaders [
3939// NOHDR-NOT: PT_GNU_EH_FRAME
4040
41//HDRDISASM: Disassembly of section foo:
42//HDRDISASM-NEXT: foo:
43//HDRDISASM-NEXT: 201000: 90 nop
44//HDRDISASM-NEXT: Disassembly of section bar:
45//HDRDISASM-NEXT: bar:
46//HDRDISASM-NEXT: 201001: 90 nop
47//HDRDISASM-NEXT: Disassembly of section dah:
48//HDRDISASM-NEXT: dah:
49//HDRDISASM-NEXT: 201002: 90 nop
41// HDRDISASM: Disassembly of section foo:
42// HDRDISASM-EMPTY:
43// HDRDISASM-NEXT: foo:
44// HDRDISASM-NEXT: 201000: 90 nop
45// HDRDISASM-EMPTY:
46// HDRDISASM-NEXT: Disassembly of section bar:
47// HDRDISASM-EMPTY:
48// HDRDISASM-NEXT: bar:
49// HDRDISASM-NEXT: 201001: 90 nop
50// HDRDISASM-EMPTY:
51// HDRDISASM-NEXT: Disassembly of section dah:
52// HDRDISASM-EMPTY:
53// HDRDISASM-NEXT: dah:
54// HDRDISASM-NEXT: 201002: 90 nop
5055
5156// HDR: Section {
5257// HDR: Index:
deps/lld/test/ELF/eh-frame-marker.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: ld.lld --eh-frame-hdr %t.o -o %t.so -shared
4// RUN: llvm-readobj -t -s %t.so | FileCheck %s
4// RUN: llvm-readobj --symbols -S %t.so | FileCheck %s
55// We used to crash on this.
66
77// CHECK: Name: .eh_frame_hdr
deps/lld/test/ELF/eh-frame-merge.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 --hash-style=sysv %t.o %t.o -o %t -shared
4// RUN: llvm-readobj -s -section-data %t | FileCheck %s
4// RUN: llvm-readobj -S --section-data %t | FileCheck %s
55
66 .section foo,"ax",@progbits
77 .cfi_startproc
deps/lld/test/ELF/eh-frame-negative-pcrel-sdata2.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
77# RUN: echo "SECTIONS { .text : { *(.text) } .eh_frame : { *(.eh_frame) } }" > %t.script
88# RUN: ld.lld --eh-frame-hdr --script %t.script --section-start .text=0x1000 %t.o -o %t
9# RUN: llvm-readobj -s -section-data %t | FileCheck %s
9# RUN: llvm-readobj -S --section-data %t | FileCheck %s
1010
1111# CHECK: Section {
1212# CHECK: Index:
deps/lld/test/ELF/eh-frame-negative-pcrel-sdata4.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
77# RUN: echo "SECTIONS { .text : { *(.text) } .eh_frame : { *(.eh_frame) } }" > %t.script
88# RUN: ld.lld --eh-frame-hdr --script %t.script --section-start .text=0x1000 %t.o -o %t
9# RUN: llvm-readobj -s -section-data %t | FileCheck %s
9# RUN: llvm-readobj -S --section-data %t | FileCheck %s
1010
1111# CHECK: Section {
1212# CHECK: Index:
deps/lld/test/ELF/eh-frame-negative-pcrel-sdata8.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
77# RUN: echo "SECTIONS { .text : { *(.text) } .eh_frame : { *(.eh_frame) } }" > %t.script
88# RUN: ld.lld --eh-frame-hdr --script %t.script --section-start .text=0x1000 %t.o -o %t
9# RUN: llvm-readobj -s -section-data %t | FileCheck %s
9# RUN: llvm-readobj -S --section-data %t | FileCheck %s
1010
1111# CHECK: Section {
1212# CHECK: Index:
deps/lld/test/ELF/eh-frame-padding-no-rosegment.s+3-3
......@@ -12,7 +12,7 @@ bar:
1212// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
1313
1414// Check the size of the CIE (0x18 + 4) and FDE (0x10 + 4)
15// RUN: llvm-readobj -s -section-data %t.o | FileCheck --check-prefix=OBJ %s
15// RUN: llvm-readobj -S --section-data %t.o | FileCheck --check-prefix=OBJ %s
1616
1717// OBJ: Name: .eh_frame
1818// OBJ-NEXT: Type:
......@@ -35,14 +35,14 @@ bar:
3535// RUN: ld.lld --hash-style=sysv %t.o -no-rosegment -o %t -shared
3636
3737// Check that .eh_frame is in the same segment as .text
38// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=PHDR %s
38// RUN: llvm-readelf -l %t | FileCheck --check-prefix=PHDR %s
3939
4040// PHDR: Segment Sections
4141// PHDR: .eh_frame {{.*}}.text
4242
4343// Check that the CIE and FDE are padded with 0x00 and not 0xCC when the
4444// .eh_frame section is placed in the executable segment
45// RUN: llvm-readobj -s -section-data %t | FileCheck %s
45// RUN: llvm-readobj -S --section-data %t | FileCheck %s
4646
4747// CHECK: Name: .eh_frame
4848// CHECK-NEXT: Type:
deps/lld/test/ELF/eh-frame-type.test+1-1
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj %s -o %t.o
22# RUN: ld.lld %t.o -o %t -shared
3# RUN: llvm-readobj -s %t | FileCheck %s
3# RUN: llvm-readobj -S %t | FileCheck %s
44
55# CHECK: Name: .eh_frame
66# CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/eh-frame-value-format7.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
44# RUN: ld.lld --eh-frame-hdr --section-start .text=0x1000 %t.o -o %t
5# RUN: llvm-readobj -s -section-data %t | FileCheck %s
5# RUN: llvm-readobj -S --section-data %t | FileCheck %s
66
77## Check we are able to handle DW_EH_PE_udata2 encoding.
88
deps/lld/test/ELF/eh-frame-value-format8.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
44# RUN: ld.lld --eh-frame-hdr --section-start .text=0x1000 %t.o -o %t
5# RUN: llvm-readobj -s -section-data %t | FileCheck %s
5# RUN: llvm-readobj -S --section-data %t | FileCheck %s
66
77## Check we are able to handle DW_EH_PE_absptr encoding.
88
deps/lld/test/ELF/ehdr_start.s+2-2
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
44# RUN: ld.lld %t.o -o %t
5# RUN: llvm-readobj -symbols %t | FileCheck %s
5# RUN: llvm-readobj --symbols %t | FileCheck %s
66# CHECK: Name: __ehdr_start (1)
77# CHECK-NEXT: Value: 0x200000
88# CHECK-NEXT: Size: 0
......@@ -30,7 +30,7 @@ _start:
3030 .quad __executable_start
3131
3232# RUN: ld.lld -r %t.o -o %t.r
33# RUN: llvm-readobj -symbols %t.r | FileCheck %s --check-prefix=RELOCATABLE
33# RUN: llvm-readobj --symbols %t.r | FileCheck %s --check-prefix=RELOCATABLE
3434
3535# RELOCATABLE: Name: __ehdr_start (1)
3636# RELOCATABLE-NEXT: Value: 0x0
deps/lld/test/ELF/ehframe-relocation.s+2-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/ehframe-relocation.s -o %t2.o
44// RUN: ld.lld %t.o %t2.o -o %t
5// RUN: llvm-readobj -s %t | FileCheck %s
5// RUN: llvm-readobj -S %t | FileCheck %s
66// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
77
88// CHECK: Name: .eh_frame
......@@ -18,6 +18,7 @@
1818// 0x200120 = 2097440
1919// 0x200120 + 5 = 2097445
2020// DISASM: Disassembly of section .text:
21// DISASM-EMPTY:
2122// DISASM-NEXT: _start:
2223// DISASM-NEXT: 201000: {{.*}} movq 2097440, %rax
2324// DISASM-NEXT: 201008: {{.*}} movq 2097445, %rax
deps/lld/test/ELF/elf-header.s+2-2
......@@ -1,10 +1,10 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: ld.lld %t.o -o %t1
4# RUN: llvm-readobj -file-headers %t1 | FileCheck %s
4# RUN: llvm-readobj --file-headers %t1 | FileCheck %s
55
66# RUN: ld.lld %t.o -no-rosegment -o %t2
7# RUN: llvm-readobj -file-headers %t2 | FileCheck %s
7# RUN: llvm-readobj --file-headers %t2 | FileCheck %s
88
99# CHECK: ElfHeader {
1010# CHECK-NEXT: Ident {
deps/lld/test/ELF/emit-relocs-merge.s+4-4
......@@ -5,12 +5,12 @@
55
66# CHECK: Relocations [
77# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
8# CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0
9# CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0
8# CHECK-NEXT: 0x2000 R_X86_64_64 zed 0x0
9# CHECK-NEXT: 0x2008 R_X86_64_64 zed 0x0
1010# CHECK-NEXT: }
1111# CHECK-NEXT: Section ({{.*}}) .rela.data {
12# CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0
13# CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0
12# CHECK-NEXT: 0x2000 R_X86_64_64 zed 0x0
13# CHECK-NEXT: 0x2008 R_X86_64_64 zed 0x0
1414# CHECK-NEXT: }
1515# CHECK-NEXT: ]
1616
deps/lld/test/ELF/emit-relocs-mergeable-i386.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t1
33# RUN: ld.lld --emit-relocs %t1 -o %t2
4# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s
4# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s
55
66## Check lf we produce proper relocations when doing merging of SHF_MERGE sections.
77
deps/lld/test/ELF/emit-relocs-mergeable.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
33# RUN: ld.lld --emit-relocs %t1 -o %t2
4# RUN: llvm-readobj -sections -section-data -r %t2 | FileCheck %s
4# RUN: llvm-readobj --sections --section-data -r %t2 | FileCheck %s
55
66## Check if we produce proper relocations when doing merging of SHF_MERGE sections.
77
deps/lld/test/ELF/emit-relocs-mergeable2.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: ld.lld --emit-relocs %t.o -o %t.exe
4# RUN: llvm-readelf --relocations %t.exe | FileCheck %s
5
6# CHECK: 0000000000201004 000000010000000b R_X86_64_32S 0000000000200120 .Lfoo + 8
7
8.globl _start
9_start:
10 movq .Lfoo+8, %rax
11.section .rodata.cst16,"aM",@progbits,16
12.Lfoo:
13 .quad 0
14 .quad 0
deps/lld/test/ELF/emit-relocs-shared.s+2-2
......@@ -8,9 +8,9 @@
88
99# CHECK: Relocations [
1010# CHECK-NEXT: Section {{.*}} .rela.dyn {
11# CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0
11# CHECK-NEXT: 0x2000 R_X86_64_64 foo 0x0
1212# CHECK-NEXT: }
1313# CHECK-NEXT: Section {{.*}} .rela.data {
14# CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0
14# CHECK-NEXT: 0x2000 R_X86_64_64 foo 0x0
1515# CHECK-NEXT: }
1616# CHECK-NEXT: ]
deps/lld/test/ELF/emit-relocs.s+3-3
......@@ -1,15 +1,15 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
33# RUN: ld.lld --emit-relocs %t1.o -o %t
4# RUN: llvm-readobj -t -r -s %t | FileCheck %s
4# RUN: llvm-readobj --symbols -r -S %t | FileCheck %s
55
66## Check single dash form.
77# RUN: ld.lld -emit-relocs %t1.o -o %t1
8# RUN: llvm-readobj -t -r -s %t1 | FileCheck %s
8# RUN: llvm-readobj --symbols -r -S %t1 | FileCheck %s
99
1010## Check alias.
1111# RUN: ld.lld -q %t1.o -o %t2
12# RUN: llvm-readobj -t -r -s %t2 | FileCheck %s
12# RUN: llvm-readobj --symbols -r -S %t2 | FileCheck %s
1313
1414# CHECK: Section {
1515# CHECK: Index: 2
deps/lld/test/ELF/empty-pack-dyn-relocs.s+1-1
......@@ -2,7 +2,7 @@
22
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
44// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.o -o %t
5// RUN: llvm-readobj -sections %t | FileCheck %s
5// RUN: llvm-readobj --sections %t | FileCheck %s
66
77.global _start
88_start:
deps/lld/test/ELF/empty-pt-load.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 -o %t.so -shared
4// RUN: llvm-readobj -l --elf-output-style=GNU %t.so | FileCheck %s
4// RUN: llvm-readelf -l %t.so | FileCheck %s
55
66// Test that we don't create an empty executable PT_LOAD.
77
deps/lld/test/ELF/empty-ver.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: cd %t.dir
44// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
55// RUN: ld.lld %t.o -o t.so -shared -version-script %p/Inputs/empty-ver.ver
6// RUN: llvm-readobj -s -section-data -version-info t.so | FileCheck %s
6// RUN: llvm-readobj -S --section-data --version-info t.so | FileCheck %s
77
88// CHECK: Name: .dynstr
99// CHECK-NEXT: Type: SHT_STRTAB
deps/lld/test/ELF/empty-ver2.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: cd %t.dir
44# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
55# RUN: ld.lld %t.o -o t.so -shared -version-script %p/Inputs/empty-ver.ver
6# RUN: llvm-readobj -version-info t.so | FileCheck %s
6# RUN: llvm-readobj --version-info t.so | FileCheck %s
77
88# CHECK: Symbols [
99# CHECK-NEXT: Symbol {
deps/lld/test/ELF/emulation-aarch64.s+6-6
......@@ -1,16 +1,16 @@
11# REQUIRES: aarch64
22# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64
33# RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64
4# RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s
4# RUN: llvm-readobj --file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s
55# RUN: ld.lld -m aarch64elf %taarch64 -o %t3aarch64
6# RUN: llvm-readobj -file-headers %t3aarch64 | FileCheck --check-prefix=AARCH64 %s
6# RUN: llvm-readobj --file-headers %t3aarch64 | FileCheck --check-prefix=AARCH64 %s
77# RUN: ld.lld -m aarch64_elf64_le_vec %taarch64 -o %t4aarch64
8# RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
8# RUN: llvm-readobj --file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
99# RUN: ld.lld %taarch64 -o %t5aarch64
10# RUN: llvm-readobj -file-headers %t5aarch64 | FileCheck --check-prefix=AARCH64 %s
10# RUN: llvm-readobj --file-headers %t5aarch64 | FileCheck --check-prefix=AARCH64 %s
1111# RUN: echo 'OUTPUT_FORMAT(elf64-littleaarch64)' > %t4aarch64.script
1212# RUN: ld.lld %t4aarch64.script %taarch64 -o %t4aarch64
13# RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
13# RUN: llvm-readobj --file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s
1414# AARCH64: ElfHeader {
1515# AARCH64-NEXT: Ident {
1616# AARCH64-NEXT: Magic: (7F 45 4C 46)
......@@ -33,7 +33,7 @@
3333# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %taarch64fbsd
3434# RUN: echo 'OUTPUT_FORMAT(elf64-aarch64-freebsd)' > %taarch64fbsd.script
3535# RUN: ld.lld %taarch64fbsd.script %taarch64fbsd -o %t2aarch64fbsd
36# RUN: llvm-readobj -file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s
36# RUN: llvm-readobj --file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s
3737# AARCH64-FBSD: ElfHeader {
3838# AARCH64-FBSD-NEXT: Ident {
3939# AARCH64-FBSD-NEXT: Magic: (7F 45 4C 46)
deps/lld/test/ELF/emulation-arm.s+4-4
......@@ -1,14 +1,14 @@
11# REQUIRES: arm
22# RUN: llvm-mc -filetype=obj -triple=armv7-unknown-linux %s -o %tarm
33# RUN: ld.lld -m armelf %tarm -o %t2arm
4# RUN: llvm-readobj -file-headers %t2arm | FileCheck --check-prefix=ARM %s
4# RUN: llvm-readobj --file-headers %t2arm | FileCheck --check-prefix=ARM %s
55# RUN: ld.lld -m armelf_linux_eabi %tarm -o %t3arm
6# RUN: llvm-readobj -file-headers %t3arm | FileCheck --check-prefix=ARM %s
6# RUN: llvm-readobj --file-headers %t3arm | FileCheck --check-prefix=ARM %s
77# RUN: ld.lld %tarm -o %t4arm
8# RUN: llvm-readobj -file-headers %t4arm | FileCheck --check-prefix=ARM %s
8# RUN: llvm-readobj --file-headers %t4arm | FileCheck --check-prefix=ARM %s
99# RUN: echo 'OUTPUT_FORMAT(elf32-littlearm)' > %t5arm.script
1010# RUN: ld.lld %t5arm.script %tarm -o %t5arm
11# RUN: llvm-readobj -file-headers %t5arm | FileCheck --check-prefix=ARM %s
11# RUN: llvm-readobj --file-headers %t5arm | FileCheck --check-prefix=ARM %s
1212# ARM: ElfHeader {
1313# ARM-NEXT: Ident {
1414# ARM-NEXT: Magic: (7F 45 4C 46)
deps/lld/test/ELF/emulation-mips.s+21-21
......@@ -1,15 +1,15 @@
11# REQUIRES: mips
22# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %tmips
33# RUN: ld.lld -m elf32btsmip -e _start %tmips -o %t2mips
4# RUN: llvm-readobj -file-headers %t2mips | FileCheck --check-prefix=MIPS %s
4# RUN: llvm-readobj --file-headers %t2mips | FileCheck --check-prefix=MIPS %s
55# RUN: ld.lld %tmips -e _start -o %t3mips
6# RUN: llvm-readobj -file-headers %t3mips | FileCheck --check-prefix=MIPS %s
6# RUN: llvm-readobj --file-headers %t3mips | FileCheck --check-prefix=MIPS %s
77# RUN: echo 'OUTPUT_FORMAT(elf32-tradbigmips)' > %tmips.script
88# RUN: ld.lld %tmips.script -e _start %tmips -o %t4mips
9# RUN: llvm-readobj -file-headers %t4mips | FileCheck --check-prefix=MIPS %s
9# RUN: llvm-readobj --file-headers %t4mips | FileCheck --check-prefix=MIPS %s
1010# RUN: echo 'OUTPUT_FORMAT(elf32-bigmips)' > %tmips2.script
1111# RUN: ld.lld %tmips2.script -e _start %tmips -o %t5mips
12# RUN: llvm-readobj -file-headers %t5mips | FileCheck --check-prefix=MIPS %s
12# RUN: llvm-readobj --file-headers %t5mips | FileCheck --check-prefix=MIPS %s
1313# MIPS: ElfHeader {
1414# MIPS-NEXT: Ident {
1515# MIPS-NEXT: Magic: (7F 45 4C 46)
......@@ -34,14 +34,14 @@
3434
3535# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %tmipsel
3636# RUN: ld.lld -m elf32ltsmip -e _start %tmipsel -o %t2mipsel
37# RUN: llvm-readobj -file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
37# RUN: llvm-readobj --file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
3838# RUN: ld.lld -melf32ltsmip -e _start %tmipsel -o %t2mipsel
39# RUN: llvm-readobj -file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
39# RUN: llvm-readobj --file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
4040# RUN: ld.lld %tmipsel -e _start -o %t3mipsel
41# RUN: llvm-readobj -file-headers %t3mipsel | FileCheck --check-prefix=MIPSEL %s
41# RUN: llvm-readobj --file-headers %t3mipsel | FileCheck --check-prefix=MIPSEL %s
4242# RUN: echo 'OUTPUT_FORMAT(elf32-tradlittlemips)' > %tmipsel.script
4343# RUN: ld.lld %tmipsel.script -e _start %tmipsel -o %t4mipsel
44# RUN: llvm-readobj -file-headers %t4mipsel | FileCheck --check-prefix=MIPSEL %s
44# RUN: llvm-readobj --file-headers %t4mipsel | FileCheck --check-prefix=MIPSEL %s
4545# MIPSEL: ElfHeader {
4646# MIPSEL-NEXT: Ident {
4747# MIPSEL-NEXT: Magic: (7F 45 4C 46)
......@@ -66,12 +66,12 @@
6666
6767# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux-gnuabin32 %s -o %tmipsn32
6868# RUN: ld.lld -m elf32btsmipn32 -e _start %tmipsn32 -o %t2mipsn32
69# RUN: llvm-readobj -file-headers %t2mipsn32 | FileCheck --check-prefix=MIPSN32 %s
69# RUN: llvm-readobj --file-headers %t2mipsn32 | FileCheck --check-prefix=MIPSN32 %s
7070# RUN: ld.lld %tmipsn32 -e _start -o %t3mipsn32
71# RUN: llvm-readobj -file-headers %t3mipsn32 | FileCheck --check-prefix=MIPSN32 %s
71# RUN: llvm-readobj --file-headers %t3mipsn32 | FileCheck --check-prefix=MIPSN32 %s
7272# RUN: echo 'OUTPUT_FORMAT(elf32-ntradbigmips)' > %tmipsn32.script
7373# RUN: ld.lld %tmipsn32.script -e _start %tmipsn32 -o %t4mipsn32
74# RUN: llvm-readobj -file-headers %t4mipsn32 | FileCheck --check-prefix=MIPSN32 %s
74# RUN: llvm-readobj --file-headers %t4mipsn32 | FileCheck --check-prefix=MIPSN32 %s
7575# MIPSN32: ElfHeader {
7676# MIPSN32-NEXT: Ident {
7777# MIPSN32-NEXT: Magic: (7F 45 4C 46)
......@@ -96,14 +96,14 @@
9696
9797# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux-gnuabin32 %s -o %tmipsn32el
9898# RUN: ld.lld -m elf32ltsmipn32 -e _start %tmipsn32el -o %t2mipsn32el
99# RUN: llvm-readobj -file-headers %t2mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
99# RUN: llvm-readobj --file-headers %t2mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
100100# RUN: ld.lld -melf32ltsmipn32 -e _start %tmipsn32el -o %t2mipsn32el
101# RUN: llvm-readobj -file-headers %t2mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
101# RUN: llvm-readobj --file-headers %t2mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
102102# RUN: ld.lld %tmipsn32el -e _start -o %t3mipsn32el
103# RUN: llvm-readobj -file-headers %t3mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
103# RUN: llvm-readobj --file-headers %t3mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
104104# RUN: echo 'OUTPUT_FORMAT(elf32-ntradlittlemips)' > %tmipsn32el.script
105105# RUN: ld.lld %tmipsn32el.script -e _start %tmipsn32el -o %t4mipsn32el
106# RUN: llvm-readobj -file-headers %t4mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
106# RUN: llvm-readobj --file-headers %t4mipsn32el | FileCheck --check-prefix=MIPSN32EL %s
107107# MIPSN32EL: ElfHeader {
108108# MIPSN32EL-NEXT: Ident {
109109# MIPSN32EL-NEXT: Magic: (7F 45 4C 46)
......@@ -129,12 +129,12 @@
129129# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -position-independent \
130130# RUN: %s -o %tmips64
131131# RUN: ld.lld -m elf64btsmip -e _start %tmips64 -o %t2mips64
132# RUN: llvm-readobj -file-headers %t2mips64 | FileCheck --check-prefix=MIPS64 %s
132# RUN: llvm-readobj --file-headers %t2mips64 | FileCheck --check-prefix=MIPS64 %s
133133# RUN: ld.lld %tmips64 -e _start -o %t3mips64
134# RUN: llvm-readobj -file-headers %t3mips64 | FileCheck --check-prefix=MIPS64 %s
134# RUN: llvm-readobj --file-headers %t3mips64 | FileCheck --check-prefix=MIPS64 %s
135135# RUN: echo 'OUTPUT_FORMAT(elf64-tradbigmips)' > %tmips64.script
136136# RUN: ld.lld %tmips64.script -e _start %tmips64 -o %t4mips64
137# RUN: llvm-readobj -file-headers %t4mips64 | FileCheck --check-prefix=MIPS64 %s
137# RUN: llvm-readobj --file-headers %t4mips64 | FileCheck --check-prefix=MIPS64 %s
138138# MIPS64: ElfHeader {
139139# MIPS64-NEXT: Ident {
140140# MIPS64-NEXT: Magic: (7F 45 4C 46)
......@@ -160,12 +160,12 @@
160160# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux \
161161# RUN: -position-independent %s -o %tmips64el
162162# RUN: ld.lld -m elf64ltsmip -e _start %tmips64el -o %t2mips64el
163# RUN: llvm-readobj -file-headers %t2mips64el | FileCheck --check-prefix=MIPS64EL %s
163# RUN: llvm-readobj --file-headers %t2mips64el | FileCheck --check-prefix=MIPS64EL %s
164164# RUN: ld.lld %tmips64el -e _start -o %t3mips64el
165# RUN: llvm-readobj -file-headers %t3mips64el | FileCheck --check-prefix=MIPS64EL %s
165# RUN: llvm-readobj --file-headers %t3mips64el | FileCheck --check-prefix=MIPS64EL %s
166166# RUN: echo 'OUTPUT_FORMAT(elf64-tradlittlemips)' > %tmips64el.script
167167# RUN: ld.lld %tmips64el.script -e _start %tmips64el -o %t4mips64el
168# RUN: llvm-readobj -file-headers %t4mips64el | FileCheck --check-prefix=MIPS64EL %s
168# RUN: llvm-readobj --file-headers %t4mips64el | FileCheck --check-prefix=MIPS64EL %s
169169# MIPS64EL: ElfHeader {
170170# MIPS64EL-NEXT: Ident {
171171# MIPS64EL-NEXT: Magic: (7F 45 4C 46)
deps/lld/test/ELF/emulation-ppc.s+11-11
......@@ -1,12 +1,12 @@
11# REQUIRES: ppc
22# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %tppc64
33# RUN: ld.lld -m elf64ppc %tppc64 -o %t2ppc64
4# RUN: llvm-readobj -file-headers %t2ppc64 | FileCheck --check-prefix=PPC64 %s
4# RUN: llvm-readobj --file-headers %t2ppc64 | FileCheck --check-prefix=PPC64 %s
55# RUN: ld.lld %tppc64 -o %t3ppc64
6# RUN: llvm-readobj -file-headers %t3ppc64 | FileCheck --check-prefix=PPC64 %s
6# RUN: llvm-readobj --file-headers %t3ppc64 | FileCheck --check-prefix=PPC64 %s
77# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc)' > %tppc64.script
88# RUN: ld.lld %tppc64.script %tppc64 -o %t4ppc64
9# RUN: llvm-readobj -file-headers %t4ppc64 | FileCheck --check-prefix=PPC64 %s
9# RUN: llvm-readobj --file-headers %t4ppc64 | FileCheck --check-prefix=PPC64 %s
1010
1111# PPC64: ElfHeader {
1212# PPC64-NEXT: Ident {
......@@ -38,7 +38,7 @@
3838# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd
3939# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script
4040# RUN: ld.lld %tppc64fbsd.script %tppc64fbsd -o %t2ppc64fbsd
41# RUN: llvm-readobj -file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s
41# RUN: llvm-readobj --file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s
4242
4343# PPC64-FBSD: ElfHeader {
4444# PPC64-FBSD-NEXT: Ident {
......@@ -69,12 +69,12 @@
6969
7070# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le
7171# RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le
72# RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s
72# RUN: llvm-readobj --file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s
7373# RUN: ld.lld %tppc64le -o %t3ppc64le
74# RUN: llvm-readobj -file-headers %t3ppc64le | FileCheck --check-prefix=PPC64LE %s
74# RUN: llvm-readobj --file-headers %t3ppc64le | FileCheck --check-prefix=PPC64LE %s
7575# RUN: echo 'OUTPUT_FORMAT(elf64-powerpcle)' > %tppc64le.script
7676# RUN: ld.lld %tppc64le.script %tppc64le -o %t4ppc64le
77# RUN: llvm-readobj -file-headers %t4ppc64le | FileCheck --check-prefix=PPC64LE %s
77# RUN: llvm-readobj --file-headers %t4ppc64le | FileCheck --check-prefix=PPC64LE %s
7878
7979# PPC64LE: ElfHeader {
8080# PPC64LE-NEXT: Ident {
......@@ -105,14 +105,14 @@
105105
106106# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-linux %s -o %tppc32
107107# RUN: ld.lld -m elf32ppc %tppc32 -o %t2ppc32
108# RUN: llvm-readobj -file-headers %t2ppc32 | FileCheck --check-prefix=PPC32 %s
108# RUN: llvm-readobj --file-headers %t2ppc32 | FileCheck --check-prefix=PPC32 %s
109109# RUN: ld.lld %tppc32 -o %t3ppc32
110# RUN: llvm-readobj -file-headers %t3ppc32 | FileCheck --check-prefix=PPC32 %s
110# RUN: llvm-readobj --file-headers %t3ppc32 | FileCheck --check-prefix=PPC32 %s
111111# RUN: echo 'OUTPUT_FORMAT(elf32-powerpc)' > %tppc32.script
112112# RUN: ld.lld %tppc32.script %tppc32 -o %t4ppc32
113# RUN: llvm-readobj -file-headers %t4ppc32 | FileCheck --check-prefix=PPC32 %s
113# RUN: llvm-readobj --file-headers %t4ppc32 | FileCheck --check-prefix=PPC32 %s
114114# RUN: ld.lld -m elf32ppclinux %tppc32 -o %t5ppc32
115# RUN: llvm-readobj -file-headers %t5ppc32 | FileCheck --check-prefix=PPC32 %s
115# RUN: llvm-readobj --file-headers %t5ppc32 | FileCheck --check-prefix=PPC32 %s
116116
117117# PPC32: ElfHeader {
118118# PPC32-NEXT: Ident {
deps/lld/test/ELF/emulation-riscv.s created+74
......@@ -0,0 +1,74 @@
1# REQUIRES: riscv
2
3# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.o
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-readobj --file-headers %t | FileCheck --check-prefix=RV32 %s
6# RUN: ld.lld -m elf32lriscv %t.o -o %t
7# RUN: llvm-readobj --file-headers %t | FileCheck --check-prefix=RV32 %s
8# RUN: echo 'OUTPUT_FORMAT(elf32-littleriscv)' > %t.script
9# RUN: ld.lld %t.script %t.o -o %t
10# RUN: llvm-readobj --file-headers %t | FileCheck --check-prefix=RV32 %s
11
12# RV32: ElfHeader {
13# RV32-NEXT: Ident {
14# RV32-NEXT: Magic: (7F 45 4C 46)
15# RV32-NEXT: Class: 32-bit (0x1)
16# RV32-NEXT: DataEncoding: LittleEndian (0x1)
17# RV32-NEXT: FileVersion: 1
18# RV32-NEXT: OS/ABI: SystemV (0x0)
19# RV32-NEXT: ABIVersion: 0
20# RV32-NEXT: Unused: (00 00 00 00 00 00 00)
21# RV32-NEXT: }
22# RV32-NEXT: Type: Executable (0x2)
23# RV32-NEXT: Machine: EM_RISCV (0xF3)
24# RV32-NEXT: Version: 1
25# RV32-NEXT: Entry:
26# RV32-NEXT: ProgramHeaderOffset: 0x34
27# RV32-NEXT: SectionHeaderOffset:
28# RV32-NEXT: Flags [ (0x0)
29# RV32-NEXT: ]
30# RV32-NEXT: HeaderSize: 52
31# RV32-NEXT: ProgramHeaderEntrySize: 32
32# RV32-NEXT: ProgramHeaderCount:
33# RV32-NEXT: SectionHeaderEntrySize: 40
34# RV32-NEXT: SectionHeaderCount:
35# RV32-NEXT: StringTableSectionIndex:
36# RV32-NEXT: }
37
38# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
39# RUN: ld.lld %t.o -o %t
40# RUN: llvm-readobj --file-headers %t | FileCheck --check-prefix=RV64 %s
41# RUN: ld.lld -m elf64lriscv %t.o -o %t
42# RUN: llvm-readobj --file-headers %t | FileCheck --check-prefix=RV64 %s
43# RUN: echo 'OUTPUT_FORMAT(elf64-littleriscv)' > %t.script
44# RUN: ld.lld %t.script %t.o -o %t
45# RUN: llvm-readobj --file-headers %t | FileCheck --check-prefix=RV64 %s
46
47# RV64: ElfHeader {
48# RV64-NEXT: Ident {
49# RV64-NEXT: Magic: (7F 45 4C 46)
50# RV64-NEXT: Class: 64-bit (0x2)
51# RV64-NEXT: DataEncoding: LittleEndian (0x1)
52# RV64-NEXT: FileVersion: 1
53# RV64-NEXT: OS/ABI: SystemV (0x0)
54# RV64-NEXT: ABIVersion: 0
55# RV64-NEXT: Unused: (00 00 00 00 00 00 00)
56# RV64-NEXT: }
57# RV64-NEXT: Type: Executable (0x2)
58# RV64-NEXT: Machine: EM_RISCV (0xF3)
59# RV64-NEXT: Version: 1
60# RV64-NEXT: Entry:
61# RV64-NEXT: ProgramHeaderOffset: 0x40
62# RV64-NEXT: SectionHeaderOffset:
63# RV64-NEXT: Flags [ (0x0)
64# RV64-NEXT: ]
65# RV64-NEXT: HeaderSize: 64
66# RV64-NEXT: ProgramHeaderEntrySize: 56
67# RV64-NEXT: ProgramHeaderCount:
68# RV64-NEXT: SectionHeaderEntrySize: 64
69# RV64-NEXT: SectionHeaderCount:
70# RV64-NEXT: StringTableSectionIndex:
71# RV64-NEXT: }
72
73.globl _start
74_start:
deps/lld/test/ELF/emulation-x86.s+19-19
......@@ -1,15 +1,15 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %tx64
33# RUN: ld.lld -m elf_amd64_fbsd %tx64 -o %t2x64
4# RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=AMD64 %s
4# RUN: llvm-readobj --file-headers %t2x64 | FileCheck --check-prefix=AMD64 %s
55# RUN: ld.lld %tx64 -o %t3x64
6# RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=AMD64 %s
6# RUN: llvm-readobj --file-headers %t3x64 | FileCheck --check-prefix=AMD64 %s
77# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv
88# 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
9# RUN: llvm-readobj --file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s
1010# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64-freebsd)' > %t4x64.script
1111# RUN: ld.lld %t4x64.script %tx64 -o %t4x64
12# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s
12# RUN: llvm-readobj --file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s
1313# AMD64: ElfHeader {
1414# AMD64-NEXT: Ident {
1515# AMD64-NEXT: Magic: (7F 45 4C 46)
......@@ -38,13 +38,13 @@
3838
3939# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tx64
4040# RUN: ld.lld -m elf_x86_64 %tx64 -o %t2x64
41# RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=X86-64 %s
41# RUN: llvm-readobj --file-headers %t2x64 | FileCheck --check-prefix=X86-64 %s
4242# RUN: ld.lld %tx64 -o %t3x64
43# RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=X86-64 %s
43# RUN: llvm-readobj --file-headers %t3x64 | FileCheck --check-prefix=X86-64 %s
4444# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64)' > %t4x64.script
4545# RUN: ld.lld %t4x64.script %tx64 -o %t4x64
4646# RUN: ld.lld %tx64 -o %t4x64 %t4x64.script
47# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=X86-64 %s
47# RUN: llvm-readobj --file-headers %t4x64 | FileCheck --check-prefix=X86-64 %s
4848# X86-64: ElfHeader {
4949# X86-64-NEXT: Ident {
5050# X86-64-NEXT: Magic: (7F 45 4C 46)
......@@ -73,12 +73,12 @@
7373
7474# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnux32 %s -o %tx32
7575# RUN: ld.lld -m elf32_x86_64 %tx32 -o %t2x32
76# RUN: llvm-readobj -file-headers %t2x32 | FileCheck --check-prefix=X32 %s
76# RUN: llvm-readobj --file-headers %t2x32 | FileCheck --check-prefix=X32 %s
7777# RUN: ld.lld %tx32 -o %t3x32
78# RUN: llvm-readobj -file-headers %t3x32 | FileCheck --check-prefix=X32 %s
78# RUN: llvm-readobj --file-headers %t3x32 | FileCheck --check-prefix=X32 %s
7979# RUN: echo 'OUTPUT_FORMAT(elf32-x86-64)' > %t4x32.script
8080# RUN: ld.lld %t4x32.script %tx32 -o %t4x32
81# RUN: llvm-readobj -file-headers %t4x32 | FileCheck --check-prefix=X32 %s
81# RUN: llvm-readobj --file-headers %t4x32 | FileCheck --check-prefix=X32 %s
8282# X32: ElfHeader {
8383# X32-NEXT: Ident {
8484# X32-NEXT: Magic: (7F 45 4C 46)
......@@ -107,12 +107,12 @@
107107
108108# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tx86
109109# RUN: ld.lld -m elf_i386 %tx86 -o %t2x86
110# RUN: llvm-readobj -file-headers %t2x86 | FileCheck --check-prefix=X86 %s
110# RUN: llvm-readobj --file-headers %t2x86 | FileCheck --check-prefix=X86 %s
111111# RUN: ld.lld %tx86 -o %t3x86
112# RUN: llvm-readobj -file-headers %t3x86 | FileCheck --check-prefix=X86 %s
112# RUN: llvm-readobj --file-headers %t3x86 | FileCheck --check-prefix=X86 %s
113113# RUN: echo 'OUTPUT_FORMAT(elf32-i386)' > %t4x86.script
114114# RUN: ld.lld %t4x86.script %tx86 -o %t4x86
115# RUN: llvm-readobj -file-headers %t4x86 | FileCheck --check-prefix=X86 %s
115# RUN: llvm-readobj --file-headers %t4x86 | FileCheck --check-prefix=X86 %s
116116# X86: ElfHeader {
117117# X86-NEXT: Ident {
118118# X86-NEXT: Magic: (7F 45 4C 46)
......@@ -141,12 +141,12 @@
141141
142142# RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd
143143# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86fbsd
144# RUN: llvm-readobj -file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s
144# RUN: llvm-readobj --file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s
145145# RUN: ld.lld %tx86fbsd -o %t3x86fbsd
146# RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
146# RUN: llvm-readobj --file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
147147# RUN: echo 'OUTPUT_FORMAT(elf32-i386-freebsd)' > %t4x86fbsd.script
148148# RUN: ld.lld %t4x86fbsd.script %tx86fbsd -o %t4x86fbsd
149# RUN: llvm-readobj -file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s
149# RUN: llvm-readobj --file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s
150150# X86FBSD: ElfHeader {
151151# X86FBSD-NEXT: Ident {
152152# X86FBSD-NEXT: Magic: (7F 45 4C 46)
......@@ -175,12 +175,12 @@
175175
176176# RUN: llvm-mc -filetype=obj -triple=i586-intel-elfiamcu %s -o %tiamcu
177177# RUN: ld.lld -m elf_iamcu %tiamcu -o %t2iamcu
178# RUN: llvm-readobj -file-headers %t2iamcu | FileCheck --check-prefix=IAMCU %s
178# RUN: llvm-readobj --file-headers %t2iamcu | FileCheck --check-prefix=IAMCU %s
179179# RUN: ld.lld %tiamcu -o %t3iamcu
180# RUN: llvm-readobj -file-headers %t3iamcu | FileCheck --check-prefix=IAMCU %s
180# RUN: llvm-readobj --file-headers %t3iamcu | FileCheck --check-prefix=IAMCU %s
181181# RUN: echo 'OUTPUT_FORMAT(elf32-iamcu)' > %t4iamcu.script
182182# RUN: ld.lld %t4iamcu.script %tiamcu -o %t4iamcu
183# RUN: llvm-readobj -file-headers %t4iamcu | FileCheck --check-prefix=IAMCU %s
183# RUN: llvm-readobj --file-headers %t4iamcu | FileCheck --check-prefix=IAMCU %s
184184# IAMCU: ElfHeader {
185185# IAMCU-NEXT: Ident {
186186# IAMCU-NEXT: Magic: (7F 45 4C 46)
deps/lld/test/ELF/end-update.s+1-1
......@@ -3,7 +3,7 @@
33
44// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
55// RUN: ld.lld %t.o -o %t
6// RUN: llvm-readobj -sections -symbols %t | FileCheck %s
6// RUN: llvm-readobj --sections --symbols %t | FileCheck %s
77
88// CHECK: Sections [
99// CHECK: Name: .bss
deps/lld/test/ELF/end.s+1-1
......@@ -5,7 +5,7 @@
55
66// By default, the .bss section is the latest section of the data segment.
77// RUN: ld.lld %t.o -o %t
8// RUN: llvm-readobj -sections -symbols %t | FileCheck %s --check-prefix=DEFAULT
8// RUN: llvm-readobj --sections --symbols %t | FileCheck %s --check-prefix=DEFAULT
99
1010// DEFAULT: Sections [
1111// DEFAULT: Name: .bss
deps/lld/test/ELF/entry.s+7-7
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
33
44# RUN: ld.lld -e foobar %t1 -o %t2 2>&1 | FileCheck -check-prefix=WARN1 %s
5# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=TEXT %s
5# RUN: llvm-readobj --file-headers %t2 | FileCheck -check-prefix=TEXT %s
66
77# WARN1: warning: cannot find entry symbol foobar; defaulting to 0x201000
88# TEXT: Entry: 0x201000
......@@ -19,7 +19,7 @@
1919# RUN: echo .data > %t.s
2020# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -n %t.s -o %t3
2121# RUN: ld.lld %t3 -o %t4 2>&1 | FileCheck -check-prefix=WARN4 %s
22# RUN: llvm-readobj -file-headers %t4 | FileCheck -check-prefix=NOENTRY %s
22# RUN: llvm-readobj --file-headers %t4 | FileCheck -check-prefix=NOENTRY %s
2323
2424# WARN4: cannot find entry symbol _start; not setting start address
2525# NOENTRY: Entry: 0x0
......@@ -28,23 +28,23 @@
2828# WARN5-NOT: warning: cannot find entry symbol
2929
3030# RUN: ld.lld %t1 -o %t2 -e entry
31# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=SYM %s
31# RUN: llvm-readobj --file-headers %t2 | FileCheck -check-prefix=SYM %s
3232# SYM: Entry: 0x201008
3333
3434# RUN: ld.lld %t1 --fatal-warnings -shared -o %t2 -e entry
35# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DSO %s
35# RUN: llvm-readobj --file-headers %t2 | FileCheck -check-prefix=DSO %s
3636# DSO: Entry: 0x1008
3737
3838# RUN: ld.lld %t1 -o %t2 --entry=4096
39# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DEC %s
39# RUN: llvm-readobj --file-headers %t2 | FileCheck -check-prefix=DEC %s
4040# DEC: Entry: 0x1000
4141
4242# RUN: ld.lld %t1 -o %t2 --entry 0xcafe
43# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=HEX %s
43# RUN: llvm-readobj --file-headers %t2 | FileCheck -check-prefix=HEX %s
4444# HEX: Entry: 0xCAFE
4545
4646# RUN: ld.lld %t1 -o %t2 -e 0777
47# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s
47# RUN: llvm-readobj --file-headers %t2 | FileCheck -check-prefix=OCT %s
4848# OCT: Entry: 0x1FF
4949
5050.globl entry
deps/lld/test/ELF/exclude-discarded-error.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
4
5# CHECK: error: relocation refers to a symbol in a discarded section: foo
6# CHECK-NEXT: >>> defined in {{.*}}.o
7# CHECK-NEXT: >>> referenced by {{.*}}.o:(.text+0x1)
8
9.globl _start
10_start:
11 jmp foo
12
13.section .foo,"ae"
14.globl foo
15foo:
deps/lld/test/ELF/exclude-discarded-error2.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: echo '.section .foo,"ae"; .weak foo; foo:' | \
4# RUN: llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
5# RUN: not ld.lld %t.o %t1.o -o /dev/null 2>&1 | FileCheck %s
6
7# Because foo defined in %t1.o is weak, it does not override global undefined
8# in %t.o
9# CHECK-NOT: discarded section
10# CHECK: undefined symbol: foo
11
12.globl _start
13_start:
14 jmp foo
deps/lld/test/ELF/exclude-libs.s+8-8
......@@ -9,28 +9,28 @@
99// RUN: llvm-ar rcs %t.dir/exc.a %t2.o %t3.o
1010
1111// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe
12// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
12// RUN: llvm-readobj --dyn-syms %t.exe | FileCheck --check-prefix=DEFAULT %s
1313
1414// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=foo,bar
15// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
15// RUN: llvm-readobj --dyn-syms %t.exe | FileCheck --check-prefix=DEFAULT %s
1616
1717// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a
18// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
18// RUN: llvm-readobj --dyn-syms %t.exe | FileCheck --check-prefix=EXCLUDE %s
1919
2020// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo:bar:exc.a
21// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
21// RUN: llvm-readobj --dyn-syms %t.exe | FileCheck --check-prefix=EXCLUDE %s
2222
2323// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL
24// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
24// RUN: llvm-readobj --dyn-syms %t.exe | FileCheck --check-prefix=EXCLUDE %s
2525
2626// RUN: ld.lld -shared %t.o %t2.o %t3.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL
27// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
27// RUN: llvm-readobj --dyn-syms %t.exe | FileCheck --check-prefix=DEFAULT %s
2828
2929// RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a
30// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
30// RUN: llvm-readobj --dyn-syms %t.exe | FileCheck --check-prefix=EXCLUDE %s
3131
3232// RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL
33// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
33// RUN: llvm-readobj --dyn-syms %t.exe | FileCheck --check-prefix=EXCLUDE %s
3434
3535// DEFAULT: Name: fn
3636// DEFAULT: Name: fn2
deps/lld/test/ELF/executable-undefined-ignoreall.s+1-1
......@@ -5,7 +5,7 @@
55
66# CHECK: Relocations [
77# CHECK-NEXT: Section ({{.*}}) .rela.plt {
8# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo 0x0
8# CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT foo 0x0
99# CHECK-NEXT: }
1010# CHECK-NEXT: ]
1111
deps/lld/test/ELF/executable-undefined-protected-ignoreall.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: not ld.lld %t -o /dev/null --unresolved-symbols=ignore-all -pie 2>&1 | FileCheck %s
4# CHECK: error: undefined symbol: foo
4# CHECK: error: undefined protected symbol: foo
55
66.protected foo
77_start:
deps/lld/test/ELF/fill-trap-ppc.s+2-2
......@@ -2,12 +2,12 @@
22
33# RUN: llvm-mc -filetype=obj -triple=powerpc64le-linux %s -o %t.o
44# RUN: ld.lld %t.o -o %t.ppc64le
5# RUN: llvm-readobj -program-headers %t.ppc64le | FileCheck %s
5# RUN: llvm-readobj -l %t.ppc64le | FileCheck %s
66# RUN: od -Ax -t x1 -N16 -j0x10ff0 %t.ppc64le | FileCheck %s -check-prefix=LE
77
88# RUN: llvm-mc -filetype=obj -triple=powerpc64-linux %s -o %t.o
99# RUN: ld.lld %t.o -o %t.ppc64
10# RUN: llvm-readobj -program-headers %t.ppc64 | FileCheck %s
10# RUN: llvm-readobj -l %t.ppc64 | FileCheck %s
1111# RUN: od -Ax -t x1 -N16 -j0x10ff0 %t.ppc64 | FileCheck %s -check-prefix=BE
1212
1313# CHECK: ProgramHeader {
deps/lld/test/ELF/fill-trap.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44# RUN: ld.lld %t -o %t2
5# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
5# RUN: llvm-readobj -l %t2 | FileCheck %s
66# RUN: od -Ax -x -N16 -j0x1ff0 %t2 | FileCheck %s -check-prefix=FILL
77
88# CHECK: ProgramHeader {
deps/lld/test/ELF/format-binary-non-ascii.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t£.o
33
44# RUN: ld.lld -o %t.elf %t£.o --format=binary %t£.o
5# RUN: llvm-readobj -symbols %t.elf | FileCheck %s
5# RUN: llvm-readobj --symbols %t.elf | FileCheck %s
66
77# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp_{{[_]+}}o_start
88# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp_{{[_]+}}o_end
deps/lld/test/ELF/gc-debuginfo-tls.s+2-2
......@@ -2,8 +2,8 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: ld.lld %t.o --gc-sections -shared -o %t1
44# RUN: ld.lld %t.o -shared -o %t2
5# RUN: llvm-readobj -symbols %t1 | FileCheck %s --check-prefix=GC
6# RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=NOGC
5# RUN: llvm-readobj --symbols %t1 | FileCheck %s --check-prefix=GC
6# RUN: llvm-readobj --symbols %t2 | FileCheck %s --check-prefix=NOGC
77
88# NOGC: Symbol {
99# NOGC: Name: patatino
deps/lld/test/ELF/gc-merge-local-sym.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: ld.lld %t.o -o %t.so -shared -O3 --gc-sections
4// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data --symbols %t.so | FileCheck %s
55
66// CHECK: Name: .rodata
77// CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/gc-sections-alloc.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44# RUN: ld.lld %t -o %t2 --gc-sections -shared
5# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s
5# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s
66
77# Non alloca section .bar should not keep section .foo alive.
88
deps/lld/test/ELF/gc-sections-eh.s+2-2
......@@ -3,11 +3,11 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44
55# RUN: ld.lld %t -o %t2 --gc-sections
6# RUN: llvm-readobj -t %t2 | FileCheck %s
6# RUN: llvm-readobj --symbols %t2 | FileCheck %s
77# RUN: llvm-objdump --dwarf=frames %t2 | FileCheck --check-prefix=EH %s
88
99# RUN: ld.lld %t -o %t3
10# RUN: llvm-readobj -t %t3 | FileCheck --check-prefix=NOGC %s
10# RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=NOGC %s
1111# RUN: llvm-objdump --dwarf=frames %t3 | FileCheck --check-prefix=EHNOGC %s
1212
1313# CHECK-NOT: foo
deps/lld/test/ELF/gc-sections-implicit-addend.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t.o
44# RUN: ld.lld %t.o -o %t --gc-sections
5# RUN: llvm-readobj -s %t | FileCheck %s
5# RUN: llvm-readobj -S %t | FileCheck %s
66# RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
77
88# CHECK: Name: .foo
deps/lld/test/ELF/gc-sections-keep-shared-start.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44# RUN: ld.lld -shared --gc-sections -o %t1 %t
5# RUN: llvm-readobj --elf-output-style=GNU --file-headers --symbols %t1
5# RUN: llvm-readelf --file-headers --symbols %t1
66# | FileCheck %s
77# CHECK: Entry point address: 0x1000
88# CHECK: 0000000000001000 0 FUNC LOCAL HIDDEN 4 _start
deps/lld/test/ELF/gc-sections-linker-defined-symbol.s+1-1
......@@ -10,7 +10,7 @@
1010# CHECK-NEXT: Binding: Global
1111# CHECK-NEXT: Type: None
1212# CHECK-NEXT: Other:
13# CHECK-NEXT: Section: .dynamic
13# CHECK-NEXT: Section: .data
1414
1515 .data
1616 .globl g
deps/lld/test/ELF/gc-sections-local-sym.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %t2 -shared --gc-sections
4// RUN: llvm-readobj -t -s -section-data %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols -S --section-data %t2 | FileCheck %s
55
66.global foo
77foo:
deps/lld/test/ELF/gc-sections-lsda.s+1-1
......@@ -7,7 +7,7 @@
77// precise and gc the entire contents of this file, but test that at least
88// we are consistent: if we keep .abc, we have to keep .foo
99
10// RUN: llvm-readobj -s %t | FileCheck %s
10// RUN: llvm-readobj -S %t | FileCheck %s
1111// CHECK: Name: .abc
1212// CHECK: Name: .foo
1313
deps/lld/test/ELF/gc-sections-merge-addend.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: ld.lld %t.o -o %t.so -shared --gc-sections
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
55
66
77// CHECK: Name: .rodata
deps/lld/test/ELF/gc-sections-merge-implicit-addend.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux
33// RUN: ld.lld %t.o -o %t.so -shared --gc-sections
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
55
66
77// CHECK: Name: .rodata
deps/lld/test/ELF/gc-sections-merge.s+2-2
......@@ -2,8 +2,8 @@
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
33// RUN: ld.lld %t.o -o %t.so -shared
44// RUN: ld.lld %t.o -o %t.gc.so -shared --gc-sections
5// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
6// RUN: llvm-readobj -s -section-data %t.gc.so | FileCheck --check-prefix=GC %s
5// RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
6// RUN: llvm-readobj -S --section-data %t.gc.so | FileCheck --check-prefix=GC %s
77
88
99// CHECK: Name: .rodata
deps/lld/test/ELF/gc-sections-metadata-startstop.s+1-1
......@@ -11,7 +11,7 @@
1111# CHECK-NOT: yy
1212
1313# CHECK: SYMBOL TABLE:
14# CHECK: xx 00000000 __start_xx
14# CHECK: xx 00000000 .protected __start_xx
1515# CHECK: w *UND* 00000000 __start_yy
1616
1717.weak __start_xx
deps/lld/test/ELF/gc-sections-non-alloc-to-merge.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
44# RUN: ld.lld %t.o -o %t --gc-sections
5# RUN: llvm-readobj -s --elf-output-style=GNU %t | FileCheck %s
5# RUN: llvm-readelf -S %t | FileCheck %s
66
77# CHECK: .merge1 PROGBITS {{[0-9a-z]*}} {{[0-9a-z]*}} 000004
88
deps/lld/test/ELF/gc-sections-protected.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: ld.lld %t.o -o %t.so -shared --gc-sections
4// RUN: llvm-readobj -s %t.so | FileCheck %s
4// RUN: llvm-readobj -S %t.so | FileCheck %s
55
66// CHECK: Name: .text
77// CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/gc-sections-synthetic.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: ld.lld %t1 -shared -o %t.so
77# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
88# RUN: ld.lld %t2 %t.so -build-id -dynamic-linker /foo/bar -o %t.out
9# RUN: llvm-readobj -sections %t.out | FileCheck %s
9# RUN: llvm-readobj --sections %t.out | FileCheck %s
1010
1111# CHECK: Name: .interp
1212# CHECK: Name: .note.gnu.build-id
deps/lld/test/ELF/gc-sections-undefined.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: ld.lld %t -o %t1 --gc-sections --undefined=foo
4# RUN: llvm-readobj -t %t1 | FileCheck %s
4# RUN: llvm-readobj --symbols %t1 | FileCheck %s
55
66# CHECK: foo
77
deps/lld/test/ELF/gc-sections-weak.s+1-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gc-sections-weak.s -o %t2.o
44// RUN: ld.lld %t.o %t2.o -o %t.so -shared --gc-sections
5// RUN: llvm-readobj -s %t.so | FileCheck %s
5// RUN: llvm-readobj -S %t.so | FileCheck %s
66
77.global foo
88foo:
deps/lld/test/ELF/gc-sections.s+3-3
......@@ -2,11 +2,11 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44# RUN: ld.lld %t -o %t2
5# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=NOGC %s
5# RUN: llvm-readobj --sections --symbols %t2 | FileCheck -check-prefix=NOGC %s
66# RUN: ld.lld --gc-sections %t -o %t2
7# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=GC1 %s
7# RUN: llvm-readobj --sections --symbols %t2 | FileCheck -check-prefix=GC1 %s
88# RUN: ld.lld --export-dynamic --gc-sections %t -o %t2
9# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=GC2 %s
9# RUN: llvm-readobj --sections --symbols %t2 | FileCheck -check-prefix=GC2 %s
1010
1111# NOGC: Name: .eh_frame
1212# NOGC: Name: .text
deps/lld/test/ELF/gdb-index-invalid-section-index.yaml created+140
......@@ -0,0 +1,140 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld --gdb-index %t.o -o /dev/null
3
4## We used to crash if a DWARFAddressRange has invalid SectionIndex (-1).
5## Such DWARFAddressRange can be produced by clang -c -gdwarf-5 -gmlt before r360678.
6
7--- !ELF
8FileHeader:
9 Class: ELFCLASS64
10 Data: ELFDATA2LSB
11 Type: ET_REL
12 Machine: EM_X86_64
13Sections:
14 - Name: .text
15 Type: SHT_PROGBITS
16 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
17 AddressAlign: 0x0000000000000010
18 Content: 31C0C3
19 - Name: .debug_str_offsets
20 Type: SHT_PROGBITS
21 AddressAlign: 0x0000000000000001
22 Content: '1000000005000000000000000000000000000000'
23 - Name: .rela.debug_str_offsets
24 Type: SHT_RELA
25 Link: .symtab
26 AddressAlign: 0x0000000000000008
27 EntSize: 0x0000000000000018
28 Info: .debug_str_offsets
29 Relocations:
30 - Offset: 0x0000000000000008
31 Symbol: .debug_str
32 Type: R_X86_64_32
33 - Offset: 0x000000000000000C
34 Symbol: .debug_str
35 Type: R_X86_64_32
36 Addend: 1
37 - Offset: 0x0000000000000010
38 Symbol: .debug_str
39 Type: R_X86_64_32
40 Addend: 6
41 - Name: .debug_str
42 Type: SHT_PROGBITS
43 Flags: [ SHF_MERGE, SHF_STRINGS ]
44 AddressAlign: 0x0000000000000001
45 EntSize: 0x0000000000000001
46 Content: 00612E6363002F746D7000
47 - Name: .debug_abbrev
48 Type: SHT_PROGBITS
49 AddressAlign: 0x0000000000000001
50 Content: 011100252513050325721710171B25111B1206000000
51 - Name: .debug_info
52 Type: SHT_PROGBITS
53 AddressAlign: 0x0000000000000001
54 Content: 1B000000050001080000000001000400010000000000000000020003000000
55 - Name: .rela.debug_info
56 Type: SHT_RELA
57 Link: .symtab
58 AddressAlign: 0x0000000000000008
59 EntSize: 0x0000000000000018
60 Info: .debug_info
61 Relocations:
62 - Offset: 0x0000000000000008
63 Symbol: .debug_abbrev
64 Type: R_X86_64_32
65 - Offset: 0x0000000000000011
66 Symbol: .debug_str_offsets
67 Type: R_X86_64_32
68 Addend: 8
69 - Offset: 0x0000000000000015
70 Symbol: .debug_line
71 Type: R_X86_64_32
72 - Name: .debug_addr
73 Type: SHT_PROGBITS
74 AddressAlign: 0x0000000000000001
75 Content: 0C000000050008000000000000000000
76 - Name: .rela.debug_addr
77 Type: SHT_RELA
78 Link: .symtab
79 AddressAlign: 0x0000000000000008
80 EntSize: 0x0000000000000018
81 Info: .debug_addr
82 Relocations:
83 - Offset: 0x0000000000000008
84 Symbol: .text
85 Type: R_X86_64_64
86 - Name: .debug_line
87 Type: SHT_PROGBITS
88 AddressAlign: 0x0000000000000001
89 Content: 2D0000000500080025000000010101FB0E0D00010101010000000100000101011F010000000002011F020F010000000000
90 - Name: .rela.debug_line
91 Type: SHT_RELA
92 Link: .symtab
93 AddressAlign: 0x0000000000000008
94 EntSize: 0x0000000000000018
95 Info: .debug_line
96 Relocations:
97 - Offset: 0x0000000000000022
98 Symbol: .debug_line_str
99 Type: R_X86_64_32
100 - Offset: 0x000000000000002C
101 Symbol: .debug_line_str
102 Type: R_X86_64_32
103 Addend: 5
104 - Name: .debug_line_str
105 Type: SHT_PROGBITS
106 Flags: [ SHF_MERGE, SHF_STRINGS ]
107 AddressAlign: 0x0000000000000001
108 EntSize: 0x0000000000000001
109 Content: 2F746D7000612E636300
110Symbols:
111 - Name: a.ll
112 Type: STT_FILE
113 Index: SHN_ABS
114 - Name: .text
115 Type: STT_SECTION
116 Section: .text
117 - Name: .debug_str_offsets
118 Type: STT_SECTION
119 Section: .debug_str_offsets
120 - Name: .debug_str
121 Type: STT_SECTION
122 Section: .debug_str
123 - Name: .debug_abbrev
124 Type: STT_SECTION
125 Section: .debug_abbrev
126 - Name: .debug_info
127 Type: STT_SECTION
128 Section: .debug_info
129 - Name: .debug_line
130 Type: STT_SECTION
131 Section: .debug_line
132 - Name: .debug_line_str
133 Type: STT_SECTION
134 Section: .debug_line_str
135 - Name: foo
136 Type: STT_FUNC
137 Section: .text
138 Binding: STB_GLOBAL
139 Size: 0x0000000000000003
140...
deps/lld/test/ELF/gdb-index-multiple-cu-2.s+2-2
......@@ -4,8 +4,8 @@
44# RUN: ld.lld --gdb-index %t.o %t1.o -o %t
55# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
66
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
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
99# CHECK: Constant pool
1010# CHECK-NEXT: 0(0x0): 0x30000002
1111
deps/lld/test/ELF/gdb-index-multiple-cu.s+6-6
......@@ -3,10 +3,10 @@
33# RUN: ld.lld --gdb-index %t.o -o %t
44# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
55
6# CuIndexAndAttrs of _start:
7# Attributes << 24 | CuIndex = 48 << 24 | 0 = 0x30000000
8# CuIndexAndAttrs of foo:
9# Attributes << 24 | CuIndex = 48 << 24 | 1 = 0x30000001
6# cuIndexAndAttrs of _start:
7# attributes << 24 | cuIndex = 48 << 24 | 0 = 0x30000000
8# cuIndexAndAttrs of foo:
9# attributes << 24 | cuIndex = 48 << 24 | 1 = 0x30000001
1010# CHECK: Symbol table
1111# CHECK-DAG: String name: _start, CU vector index: 0
1212# CHECK-DAG: String name: foo, CU vector index: 1
......@@ -63,7 +63,7 @@ foo:
6363# Swap sets to test the case where pubnames are in a
6464# different order than the CUs they refer to.
6565.section .debug_gnu_pubnames,"",@progbits
66 # CuIndex: 1
66 # cuIndex: 1
6767 .long .LpubNames_end1 - .LpubNames_begin1
6868.LpubNames_begin1:
6969 .short 2 # Version
......@@ -75,7 +75,7 @@ foo:
7575 .long 0
7676.LpubNames_end1:
7777
78 # CuIndex: 0
78 # cuIndex: 0
7979 .long .LpubNames_end0 - .LpubNames_begin0
8080.LpubNames_begin0:
8181 .short 2 # Version
deps/lld/test/ELF/gdb-index-ranges-discarded.s created+51
......@@ -0,0 +1,51 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: ld.lld --gdb-index -e main %t.o -o %t
4# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
5
6# CHECK: .gdb_index contents:
7# CHECK: Address area offset = 0x28, has 1 entries:
8# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
9
10## .debug_ranges contains 2 entries. .Lfunc_end0 is defined in the discarded
11## .text.foo. Test we resolve it to a non-zero value, otherwise the address area
12## of .gdb_index will not included [.Lfunc_begin1, .Lfunc_end1).
13
14.section .text.foo,"aex",@progbits
15.Lfunc_begin0:
16 ret
17.Lfunc_end0:
18
19.section .text.bar,"ax",@progbits
20.Lfunc_begin1:
21 ret
22.Lfunc_end1:
23
24.section .debug_abbrev,"",@progbits
25 .byte 1 # Abbreviation Code
26 .byte 17 # DW_TAG_compile_unit
27 .byte 0 # DW_CHILDREN_no
28 .byte 85 # DW_AT_ranges
29 .byte 23 # DW_FORM_sec_offset
30 .byte 0 # EOM(1)
31 .byte 0 # EOM(2)
32 .byte 0
33
34.section .debug_info,"",@progbits
35.Lcu_begin0:
36 .long .Lcu_end0 - .Lcu_begin0 - 4
37 .short 4 # DWARF version number
38 .long 0 # Offset Into Abbrev. Section
39 .byte 8 # Address Size
40.Ldie0:
41 .byte 1 # Abbrev [1] DW_TAG_compile_unit
42 .long 0 # DW_AT_ranges
43.Lcu_end0:
44
45.section .debug_ranges,"",@progbits
46 .quad .Lfunc_begin0
47 .quad .Lfunc_end0
48 .quad .Lfunc_begin1
49 .quad .Lfunc_end1
50 .quad 0
51 .quad 0
deps/lld/test/ELF/gdb-index.s+2-1
......@@ -16,6 +16,7 @@
1616# RUN: llvm-readelf -sections %t | FileCheck %s --check-prefix=SECTION
1717
1818# DISASM: Disassembly of section .text:
19# DISASM-EMPTY:
1920# DISASM: entrypoint:
2021# DISASM-CHECK: 201000: 90 nop
2122# DISASM-CHECK: 201001: cc int3
......@@ -48,7 +49,7 @@
4849# SECTION-NOT: debug_gnu_pubnames
4950
5051# RUN: ld.lld --gdb-index --no-gdb-index %t1.o %t2.o -o %t2
51# RUN: llvm-readobj -sections %t2 | FileCheck -check-prefix=NOGDB %s
52# RUN: llvm-readobj --sections %t2 | FileCheck -check-prefix=NOGDB %s
5253# NOGDB-NOT: Name: .gdb_index
5354
5455## The following section contents are created by this using gcc 7.1.0:
deps/lld/test/ELF/global-offset-table-position-aarch64.s+2-2
......@@ -1,7 +1,7 @@
11// REQUIRES: aarch64
22// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
33// RUN: ld.lld --hash-style=sysv -shared %t -o %t2
4// RUN: llvm-readobj -t %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55.globl a
66.type a,@object
77.comm a,4,4
......@@ -20,7 +20,7 @@ _start:
2020.long _GLOBAL_OFFSET_TABLE_ - .
2121
2222// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11)
23// CHECK-NEXT: Value: 0x20008
23// CHECK-NEXT: Value: 0x30008
2424// CHECK-NEXT: Size: 0
2525// CHECK-NEXT: Binding: Local (0x0)
2626// CHECK-NEXT: Type: None (0x0)
deps/lld/test/ELF/global-offset-table-position-arm.s+2-2
......@@ -1,7 +1,7 @@
11// REQUIRES: arm
22// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t
33// RUN: ld.lld --hash-style=sysv -shared %t -o %t2
4// RUN: llvm-readobj -t %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55
66// The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
77.globl a
......@@ -25,7 +25,7 @@ _start:
2525.data
2626
2727// CHECK: Name: _GLOBAL_OFFSET_TABLE_
28// CHECK-NEXT: Value: 0x3068
28// CHECK-NEXT: Value: 0x2068
2929// CHECK-NEXT: Size: 0
3030// CHECK-NEXT: Binding: Local
3131// CHECK-NEXT: Type: None
deps/lld/test/ELF/global-offset-table-position-i386.s+2-2
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
33// RUN: ld.lld --hash-style=sysv -shared %t -o %t2
4// RUN: llvm-readobj -t %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55
66// The X86 _GLOBAL_OFFSET_TABLE_ is defined at the start of the .got.plt
77// section.
......@@ -22,7 +22,7 @@ addl $_GLOBAL_OFFSET_TABLE_, %eax
2222calll f@PLT
2323
2424// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1)
25// CHECK-NEXT: Value: 0x2000
25// CHECK-NEXT: Value: 0x3000
2626// CHECK-NEXT: Size: 0
2727// CHECK-NEXT: Binding: Local (0x0)
2828// CHECK-NEXT: Type: None (0x0)
deps/lld/test/ELF/global-offset-table-position-mips.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: mips
22// RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t
33// RUN: ld.lld -shared %t -o %t2
4// RUN: llvm-readobj -t %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55
66// The Mips _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
77
deps/lld/test/ELF/global-offset-table-position.s+2-2
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33// RUN: ld.lld --hash-style=sysv -shared %t -o %t2
4// RUN: llvm-readobj -t %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55
66// The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the start of the .got.plt
77// section.
......@@ -22,7 +22,7 @@ callq f@PLT
2222.long _GLOBAL_OFFSET_TABLE_ - .
2323
2424// CHECK: Name: _GLOBAL_OFFSET_TABLE_
25// CHECK-NEXT: Value: 0x2008
25// CHECK-NEXT: Value: 0x3008
2626// CHECK-NEXT: Size: 0
2727// CHECK-NEXT: Binding: Local
2828// CHECK-NEXT: Type: None (0x0)
deps/lld/test/ELF/global_offset_table_shared.s+2-2
......@@ -1,11 +1,11 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33// RUN: ld.lld --hash-style=sysv -shared %t -o %t2
4// RUN: llvm-readobj -t %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55.long _GLOBAL_OFFSET_TABLE_ - .
66
77// CHECK: Name: _GLOBAL_OFFSET_TABLE_
8// CHECK-NEXT: Value: 0x2000
8// CHECK-NEXT: Value: 0x3000
99// CHECK-NEXT: Size: 0
1010// CHECK-NEXT: Binding: Local
1111// CHECK-NEXT: Type: None
deps/lld/test/ELF/gnu-hash-table-rwsegment.s+1-1
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
44# RUN: ld.lld -shared -hash-style=gnu --no-rosegment -o %t.so %t.o
5# RUN: llvm-readobj -gnu-hash-table %t.so | FileCheck %s
5# RUN: llvm-readobj --gnu-hash-table %t.so | FileCheck %s
66
77# CHECK: GnuHashTable {
88# CHECK-NEXT: Num Buckets: 1
deps/lld/test/ELF/gnu-hash-table.s+5-5
......@@ -36,15 +36,15 @@
3636# RUN: ld.lld -shared --hash-style both -o %t-ppc64le.so %t-ppc64le.o %t2-ppc64le.a %t3-ppc64le.so
3737# RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o %t2-ppc64.a %t3-ppc64.so
3838
39# RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \
39# RUN: llvm-readobj --dyn-syms --gnu-hash-table %te-i386.so \
4040# RUN: | FileCheck %s -check-prefix=EMPTY
41# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-i386.so \
41# RUN: llvm-readobj --sections --dyn-syms --gnu-hash-table %t-i386.so \
4242# RUN: | FileCheck %s -check-prefix=I386
43# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-x86_64.so \
43# RUN: llvm-readobj --sections --dyn-syms --gnu-hash-table %t-x86_64.so \
4444# RUN: | FileCheck %s -check-prefix=X86_64
45# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64le.so \
45# RUN: llvm-readobj --sections --dyn-syms --gnu-hash-table %t-ppc64le.so \
4646# RUN: | FileCheck %s -check-prefix=PPC64
47# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64.so \
47# RUN: llvm-readobj --sections --dyn-syms --gnu-hash-table %t-ppc64.so \
4848# RUN: | FileCheck %s -check-prefix=PPC64
4949
5050# EMPTY: DynamicSymbols [
deps/lld/test/ELF/gnu-ifunc-canon.s created+92
......@@ -0,0 +1,92 @@
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 %S/Inputs/gnu-ifunc-canon-ro-pcrel.s -o %t-ro-pcrel.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-canon-ro-abs.s -o %t-ro-abs.o
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-canon-rw-addend.s -o %t-rw-addend.o
6// RUN: ld.lld %t.o -o %t1
7// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=IREL2 %s
8// RUN: ld.lld %t.o %t-ro-pcrel.o -o %t2
9// RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=IREL1 %s
10// RUN: ld.lld %t.o %t-ro-abs.o -o %t3
11// RUN: llvm-readobj -r %t3 | FileCheck --check-prefix=IREL1 %s
12// RUN: ld.lld %t.o %t-rw-addend.o -o %t4
13// RUN: llvm-readobj -r %t4 | FileCheck --check-prefix=IREL1 %s
14// RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=DUMP %s
15// RUN: ld.lld %t.o %t-rw-addend.o -o %t4a -z retpolineplt
16// RUN: llvm-readobj -r %t4a | FileCheck --check-prefix=IREL1 %s
17// RUN: llvm-objdump -s %t4a | FileCheck --check-prefix=DUMP2 %s
18// RUN: ld.lld %t-ro-pcrel.o %t.o -o %t5
19// RUN: llvm-readobj -r %t5 | FileCheck --check-prefix=IREL1 %s
20// RUN: ld.lld %t-ro-abs.o %t.o -o %t6
21// RUN: llvm-readobj -r %t6 | FileCheck --check-prefix=IREL1 %s
22// RUN: ld.lld %t-rw-addend.o %t.o -o %t7
23// RUN: llvm-readobj -r %t7 | FileCheck --check-prefix=IREL1 %s
24// RUN: ld.lld %t.o -o %t8 -pie
25// RUN: llvm-readobj -r %t8 | FileCheck --check-prefix=IREL2 %s
26// RUN: ld.lld %t.o %t-ro-pcrel.o -o %t9 -pie
27// RUN: llvm-readobj -r %t9 | FileCheck --check-prefix=IREL1-REL2 %s
28// RUN: ld.lld %t.o %t-rw-addend.o -o %t10 -pie
29// RUN: llvm-readobj -r %t10 | FileCheck --check-prefix=IREL1-REL3 %s
30// RUN: ld.lld %t-ro-pcrel.o %t.o -o %t11 -pie
31// RUN: llvm-readobj -r %t11 | FileCheck --check-prefix=IREL1-REL2 %s
32// RUN: ld.lld %t-rw-addend.o %t.o -o %t12 -pie
33// RUN: llvm-readobj -r %t12 | FileCheck --check-prefix=IREL1-REL3 %s
34
35// Two relocs, one for the GOT and the other for .data.
36// IREL2-NOT: R_X86_64_
37// IREL2: .rela.plt
38// IREL2-NEXT: R_X86_64_IRELATIVE
39// IREL2-NEXT: R_X86_64_IRELATIVE
40// IREL2-NOT: R_X86_64_
41
42// One reloc for the canonical PLT.
43// IREL1-NOT: R_X86_64_
44// IREL1: .rela.plt
45// IREL1-NEXT: R_X86_64_IRELATIVE
46// IREL1-NOT: R_X86_64_
47
48// One reloc for the canonical PLT and two RELATIVE relocations pointing to it,
49// one in the GOT and one in .data.
50// IREL1-REL2-NOT: R_X86_64_
51// IREL1-REL2: .rela.dyn
52// IREL1-REL2-NEXT: R_X86_64_RELATIVE
53// IREL1-REL2-NEXT: R_X86_64_RELATIVE
54// IREL1-REL2: .rela.plt
55// IREL1-REL2-NEXT: R_X86_64_IRELATIVE
56// IREL1-REL2-NOT: R_X86_64_
57
58// One reloc for the canonical PLT and three RELATIVE relocations pointing to it,
59// one in the GOT and two in .data.
60// IREL1-REL3-NOT: R_X86_64_
61// IREL1-REL3: .rela.dyn
62// IREL1-REL3-NEXT: R_X86_64_RELATIVE
63// IREL1-REL3-NEXT: R_X86_64_RELATIVE
64// IREL1-REL3-NEXT: R_X86_64_RELATIVE
65// IREL1-REL3: .rela.plt
66// IREL1-REL3-NEXT: R_X86_64_IRELATIVE
67// IREL1-REL3-NOT: R_X86_64_
68
69// Make sure the static relocations look right, both with and without headers.
70// DUMP: Contents of section .plt:
71// DUMP-NEXT: 201010
72// DUMP: Contents of section .got:
73// DUMP-NEXT: 202000 10102000 00000000
74// DUMP: Contents of section .data:
75// DUMP-NEXT: 203000 10102000 00000000 11102000 00000000
76
77// DUMP2: Contents of section .plt:
78// DUMP2-NEXT: 201010
79// DUMP2: Contents of section .got:
80// DUMP2-NEXT: 202000 40102000 00000000
81// DUMP2: Contents of section .data:
82// DUMP2-NEXT: 203000 40102000 00000000 41102000 00000000
83
84lea ifunc@gotpcrel(%rip), %rbx
85
86.type ifunc STT_GNU_IFUNC
87.globl ifunc
88ifunc:
89ret
90
91.data
92.8byte ifunc
deps/lld/test/ELF/gnu-ifunc-dso.s+2-2
......@@ -3,10 +3,10 @@
33# RUN: ld.lld -shared %t1.o -o %t.so
44# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
55# RUN: ld.lld -shared %t2.o %t.so -o %t
6# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
6# RUN: llvm-readobj --dyn-relocations %t | FileCheck %s
77
88# CHECK: Dynamic Relocations {
9# CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0
9# CHECK-NEXT: 0x2000 R_X86_64_64 foo 0x0
1010# CHECK-NEXT: }
1111
1212.data
deps/lld/test/ELF/gnu-ifunc-dyntags.s+6-6
......@@ -2,14 +2,14 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: ld.lld -pie %t.o -o %tout
44# RUN: llvm-objdump -section-headers %tout | FileCheck %s
5# RUN: llvm-readobj -dynamic-table -r %tout | FileCheck %s --check-prefix=TAGS
5# RUN: llvm-readobj --dynamic-table -r %tout | FileCheck %s --check-prefix=TAGS
66
77## Check we produce DT_PLTREL/DT_JMPREL/DT_PLTGOT and DT_PLTRELSZ tags
88## when there are no other relocations except R_*_IRELATIVE.
99
10# CHECK: Name Size Address
11# CHECK: .rela.plt 00000030 0000000000000210
12# CHECK: .got.plt 00000010 0000000000002000
10# CHECK: Name Size VMA
11# CHECK: .rela.plt 00000030 0000000000000248
12# CHECK: .got.plt 00000010 0000000000003000
1313
1414# TAGS: Relocations [
1515# TAGS-NEXT: Section {{.*}} .rela.plt {
......@@ -19,9 +19,9 @@
1919# TAGS-NEXT: ]
2020
2121# TAGS: Tag Type Name/Value
22# TAGS: 0x0000000000000017 JMPREL 0x210
22# TAGS: 0x0000000000000017 JMPREL 0x248
2323# TAGS: 0x0000000000000002 PLTRELSZ 48
24# TAGS: 0x0000000000000003 PLTGOT 0x2000
24# TAGS: 0x0000000000000003 PLTGOT 0x3000
2525# TAGS: 0x0000000000000014 PLTREL RELA
2626
2727.text
deps/lld/test/ELF/gnu-ifunc-gotpcrel.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: ld.lld -shared %t2.o -o %t2.so
44# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
55# RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t
6# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
6# RUN: llvm-readobj --dyn-relocations %t | FileCheck %s
77
88# CHECK: Dynamic Relocations {
99# CHECK-NEXT: 0x2020B0 R_X86_64_GLOB_DAT foo 0x0
deps/lld/test/ELF/gnu-ifunc-i386.s+34-6
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
33// RUN: ld.lld -static %t.o -o %tout
44// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
5// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
5// RUN: llvm-readobj -r --symbols --sections %tout | FileCheck %s
66
77// CHECK: Sections [
88// CHECK: Section {
......@@ -70,39 +70,61 @@
7070// CHECK-NEXT: }
7171// CHECK-NEXT: Symbol {
7272// CHECK-NEXT: Name: bar
73// CHECK-NEXT: Value: 0x401030
74// CHECK-NEXT: Size: 0
75// CHECK-NEXT: Binding: Global
76// CHECK-NEXT: Type: Function
77// CHECK-NEXT: Other: 0
78// CHECK-NEXT: Section: .plt
79// CHECK-NEXT: }
80// CHECK-NEXT: Symbol {
81// CHECK-NEXT: Name: bar_resolver
7382// CHECK-NEXT: Value: 0x401001
7483// CHECK-NEXT: Size: 0
7584// CHECK-NEXT: Binding: Global
76// CHECK-NEXT: Type: GNU_IFunc
85// CHECK-NEXT: Type: Function
7786// CHECK-NEXT: Other: 0
7887// CHECK-NEXT: Section: .text
7988// CHECK-NEXT: }
8089// CHECK-NEXT: Symbol {
8190// CHECK-NEXT: Name: foo
91// CHECK-NEXT: Value: 0x401020
92// CHECK-NEXT: Size: 0
93// CHECK-NEXT: Binding: Global
94// CHECK-NEXT: Type: Function
95// CHECK-NEXT: Other: 0
96// CHECK-NEXT: Section: .plt
97// CHECK-NEXT: }
98// CHECK-NEXT: Symbol {
99// CHECK-NEXT: Name: foo_resolver
82100// CHECK-NEXT: Value: 0x401000
83101// CHECK-NEXT: Size: 0
84102// CHECK-NEXT: Binding: Global
85// CHECK-NEXT: Type: GNU_IFunc
103// CHECK-NEXT: Type: Function
86104// CHECK-NEXT: Other: 0
87105// CHECK-NEXT: Section: .text
88106// CHECK-NEXT: }
89107// CHECK-NEXT:]
90108
91109// DISASM: Disassembly of section .text:
92// DISASM-NEXT: foo:
110// DISASM-EMPTY:
111// DISASM-NEXT: foo_resolver:
93112// DISASM-NEXT: 401000: c3 retl
94// DISASM: bar:
113// DISASM: bar_resolver:
95114// DISASM-NEXT: 401001: c3 retl
96115// DISASM: _start:
97116// DISASM-NEXT: 401002: e8 19 00 00 00 calll 25
98117// DISASM-NEXT: 401007: e8 24 00 00 00 calll 36
99118// DISASM-NEXT: 40100c: ba d4 00 40 00 movl $4194516, %edx
100119// DISASM-NEXT: 401011: ba e4 00 40 00 movl $4194532, %edx
120// DISASM-EMPTY:
101121// DISASM-NEXT: Disassembly of section .plt:
102// DISASM-NEXT: .plt:
122// DISASM-EMPTY:
123// DISASM-NEXT: foo:
103124// DISASM-NEXT: 401020: ff 25 00 20 40 00 jmpl *4202496
104125// DISASM-NEXT: 401026: 68 10 00 00 00 pushl $16
105126// DISASM-NEXT: 40102b: e9 e0 ff ff ff jmp -32 <_start+0xe>
127// DISASM: bar:
106128// DISASM-NEXT: 401030: ff 25 04 20 40 00 jmpl *4202500
107129// DISASM-NEXT: 401036: 68 18 00 00 00 pushl $24
108130// DISASM-NEXT: 40103b: e9 d0 ff ff ff jmp -48 <_start+0xe>
......@@ -111,11 +133,17 @@
111133.type foo STT_GNU_IFUNC
112134.globl foo
113135foo:
136.type foo_resolver STT_FUNC
137.globl foo_resolver
138foo_resolver:
114139 ret
115140
116141.type bar STT_GNU_IFUNC
117142.globl bar
118143bar:
144.type bar_resolver STT_FUNC
145.globl bar_resolver
146bar_resolver:
119147 ret
120148
121149.globl _start
deps/lld/test/ELF/gnu-ifunc-noplt-i386.s created+71
......@@ -0,0 +1,71 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-freebsd %S/Inputs/shared2-x86-64.s -o %t1.o
3// RUN: ld.lld %t1.o --shared -o %t.so
4// RUN: llvm-mc -filetype=obj -triple=i686-pc-freebsd %s -o %t.o
5// RUN: ld.lld -z ifunc-noplt -z notext --hash-style=sysv %t.so %t.o -o %tout
6// RUN: llvm-objdump -d --no-show-raw-insn %tout | FileCheck %s --check-prefix=DISASM
7// RUN: llvm-readobj -r --dynamic-table %tout | FileCheck %s
8
9// Check that we emitted relocations for the ifunc calls
10// CHECK: Relocations [
11// CHECK-NEXT: Section (4) .rel.dyn {
12// CHECK-NEXT: 0x401008 R_386_PLT32 bar
13// CHECK-NEXT: 0x401003 R_386_PLT32 foo
14// CHECK-NEXT: }
15// CHECK-NEXT: Section (5) .rel.plt {
16// CHECK-NEXT: 0x40300C R_386_JUMP_SLOT bar2
17// CHECK-NEXT: 0x403010 R_386_JUMP_SLOT zed2
18// CHECK-NEXT: }
19
20// Check that ifunc call sites still require relocation
21// DISASM: Disassembly of section .text:
22// DISASM-EMPTY:
23// DISASM-NEXT: 00401000 foo:
24// DISASM-NEXT: 401000: retl
25// DISASM-EMPTY:
26// DISASM-NEXT: 00401001 bar:
27// DISASM-NEXT: 401001: retl
28// DISASM-EMPTY:
29// DISASM-NEXT: 00401002 _start:
30// DISASM-NEXT: 401002: calll -4 <_start+0x1>
31// DISASM-NEXT: 401007: calll -4 <_start+0x6>
32// DISASM-NEXT: 40100c: calll 31 <bar2@plt>
33// DISASM-NEXT: 401011: calll 42 <zed2@plt>
34// DISASM-EMPTY:
35// DISASM-NEXT: Disassembly of section .plt:
36// DISASM-EMPTY:
37// DISASM-NEXT: 00401020 .plt:
38// DISASM-NEXT: 401020: pushl 4206596
39// DISASM-NEXT: 401026: jmpl *4206600
40// DISASM-NEXT: 40102c: nop
41// DISASM-NEXT: 40102d: nop
42// DISASM-NEXT: 40102e: nop
43// DISASM-NEXT: 40102f: nop
44// DISASM-EMPTY:
45// DISASM-NEXT: 00401030 bar2@plt:
46// DISASM-NEXT: 401030: jmpl *4206604
47// DISASM-NEXT: 401036: pushl $0
48// DISASM-NEXT: 40103b: jmp -32 <.plt>
49// DISASM-EMPTY:
50// DISASM-NEXT: 00401040 zed2@plt:
51// DISASM-NEXT: 401040: jmpl *4206608
52// DISASM-NEXT: 401046: pushl $8
53// DISASM-NEXT: 40104b: jmp -48 <.plt>
54
55.text
56.type foo STT_GNU_IFUNC
57.globl foo
58foo:
59 ret
60
61.type bar STT_GNU_IFUNC
62.globl bar
63bar:
64 ret
65
66.globl _start
67_start:
68 call foo@plt
69 call bar@plt
70 call bar2@plt
71 call zed2@plt
deps/lld/test/ELF/gnu-ifunc-noplt.s created+68
......@@ -0,0 +1,68 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-freebsd %S/Inputs/shared2-x86-64.s -o %t1.o
3// RUN: ld.lld %t1.o --shared -o %t.so
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-freebsd %s -o %t.o
5// RUN: ld.lld -z ifunc-noplt -z notext --hash-style=sysv %t.so %t.o -o %tout
6// RUN: llvm-objdump -d --no-show-raw-insn %tout | FileCheck %s --check-prefix=DISASM
7// RUN: llvm-readobj -r --dynamic-table %tout | FileCheck %s
8
9// Check that we emitted relocations for the ifunc calls
10// CHECK: Relocations [
11// CHECK-NEXT: Section (4) .rela.dyn {
12// CHECK-NEXT: 0x201008 R_X86_64_PLT32 bar 0xFFFFFFFFFFFFFFFC
13// CHECK-NEXT: 0x201003 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC
14// CHECK-NEXT: }
15// CHECK-NEXT: Section (5) .rela.plt {
16// CHECK-NEXT: 0x203018 R_X86_64_JUMP_SLOT bar2 0x0
17// CHECK-NEXT: 0x203020 R_X86_64_JUMP_SLOT zed2 0x0
18// CHECK-NEXT: }
19
20// Check that ifunc call sites still require relocation
21// DISASM: Disassembly of section .text:
22// DISASM-EMPTY:
23// DISASM-NEXT: 0000000000201000 foo:
24// DISASM-NEXT: 201000: retq
25// DISASM-EMPTY:
26// DISASM-NEXT: 0000000000201001 bar:
27// DISASM-NEXT: 201001: retq
28// DISASM-EMPTY:
29// DISASM-NEXT: 0000000000201002 _start:
30// DISASM-NEXT: 201002: callq 0 <_start+0x5>
31// DISASM-NEXT: 201007: callq 0 <_start+0xa>
32// DISASM-NEXT: 20100c: callq 31 <bar2@plt>
33// DISASM-NEXT: 201011: callq 42 <zed2@plt>
34// DISASM-EMPTY:
35// DISASM-NEXT: Disassembly of section .plt:
36// DISASM-EMPTY:
37// DISASM-NEXT: 0000000000201020 .plt:
38// DISASM-NEXT: 201020: pushq 8162(%rip)
39// DISASM-NEXT: 201026: jmpq *8164(%rip)
40// DISASM-NEXT: 20102c: nopl (%rax)
41// DISASM-EMPTY:
42// DISASM-NEXT: 0000000000201030 bar2@plt:
43// DISASM-NEXT: 201030: jmpq *8162(%rip)
44// DISASM-NEXT: 201036: pushq $0
45// DISASM-NEXT: 20103b: jmp -32 <.plt>
46// DISASM-EMPTY:
47// DISASM-NEXT: 0000000000201040 zed2@plt:
48// DISASM-NEXT: 201040: jmpq *8154(%rip)
49// DISASM-NEXT: 201046: pushq $1
50// DISASM-NEXT: 20104b: jmp -48 <.plt>
51
52.text
53.type foo STT_GNU_IFUNC
54.globl foo
55foo:
56 ret
57
58.type bar STT_GNU_IFUNC
59.globl bar
60bar:
61 ret
62
63.globl _start
64_start:
65 call foo
66 call bar
67 call bar2
68 call zed2
deps/lld/test/ELF/gnu-ifunc-nosym-i386.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 -static %t.o -o %tout
4// RUN: llvm-readobj -symbols %tout | FileCheck %s
4// RUN: llvm-readobj --symbols %tout | FileCheck %s
55
66// Check that no __rel_iplt_end/__rel_iplt_start
77// appear in symtab if there is no references to them.
deps/lld/test/ELF/gnu-ifunc-nosym.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 -static %t.o -o %tout
4// RUN: llvm-readobj -symbols %tout | FileCheck %s
4// RUN: llvm-readobj --symbols %tout | FileCheck %s
55
66// Check that no __rela_iplt_end/__rela_iplt_start
77// appear in symtab if there is no references to them.
deps/lld/test/ELF/gnu-ifunc-plt-i386.s+16-13
......@@ -5,21 +5,21 @@
55// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout
66// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
77// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
8// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
8// RUN: llvm-readobj -r --dynamic-table %tout | FileCheck %s
99
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: 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
13// CHECK-NEXT: 0x40300C R_386_JUMP_SLOT bar2
14// CHECK-NEXT: 0x403010 R_386_JUMP_SLOT zed2
15// CHECK-NEXT: 0x403014 R_386_IRELATIVE
16// CHECK-NEXT: 0x403018 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: 402000 00304000 00000000 00000000 36104000
22// GOTPLT-NEXT: 402010 46104000 00104000 01104000
21// GOTPLT: 403000 00204000 00000000 00000000 36104000
22// GOTPLT-NEXT: 403010 46104000 00104000 01104000
2323
2424// Check that the PLTRELSZ tag includes the IRELATIVE relocations
2525// CHECK: DynamicSection [
......@@ -27,6 +27,7 @@
2727
2828// Check that a PLT header is written and the ifunc entries appear last
2929// DISASM: Disassembly of section .text:
30// DISASM-EMPTY:
3031// DISASM-NEXT: foo:
3132// DISASM-NEXT: 401000: c3 retl
3233// DISASM: bar:
......@@ -36,28 +37,30 @@
3637// DISASM-NEXT: 401007: e8 54 00 00 00 calll 84
3738// DISASM-NEXT: 40100c: e8 1f 00 00 00 calll 31
3839// DISASM-NEXT: 401011: e8 2a 00 00 00 calll 42
40// DISASM-EMPTY:
3941// DISASM-NEXT: Disassembly of section .plt:
42// DISASM-EMPTY:
4043// DISASM-NEXT: .plt:
41// DISASM-NEXT: 401020: ff 35 04 20 40 00 pushl 4202500
42// DISASM-NEXT: 401026: ff 25 08 20 40 00 jmpl *4202504
44// DISASM-NEXT: 401020: ff 35 04 30 40 00 pushl 4206596
45// DISASM-NEXT: 401026: ff 25 08 30 40 00 jmpl *4206600
4346// DISASM-NEXT: 40102c: 90 nop
4447// DISASM-NEXT: 40102d: 90 nop
4548// DISASM-NEXT: 40102e: 90 nop
4649// DISASM-NEXT: 40102f: 90 nop
4750// DISASM-EMPTY:
4851// DISASM-NEXT: bar2@plt:
49// DISASM-NEXT: 401030: ff 25 0c 20 40 00 jmpl *4202508
52// DISASM-NEXT: 401030: ff 25 0c 30 40 00 jmpl *4206604
5053// DISASM-NEXT: 401036: 68 00 00 00 00 pushl $0
5154// DISASM-NEXT: 40103b: e9 e0 ff ff ff jmp -32 <.plt>
5255// DISASM-EMPTY:
5356// DISASM-NEXT: zed2@plt:
54// DISASM-NEXT: 401040: ff 25 10 20 40 00 jmpl *4202512
57// DISASM-NEXT: 401040: ff 25 10 30 40 00 jmpl *4206608
5558// DISASM-NEXT: 401046: 68 08 00 00 00 pushl $8
5659// DISASM-NEXT: 40104b: e9 d0 ff ff ff jmp -48 <.plt>
57// DISASM-NEXT: 401050: ff 25 14 20 40 00 jmpl *4202516
60// DISASM-NEXT: 401050: ff 25 14 30 40 00 jmpl *4206612
5861// DISASM-NEXT: 401056: 68 30 00 00 00 pushl $48
5962// DISASM-NEXT: 40105b: e9 e0 ff ff ff jmp -32 <zed2@plt>
60// DISASM-NEXT: 401060: ff 25 18 20 40 00 jmpl *4202520
63// DISASM-NEXT: 401060: ff 25 18 30 40 00 jmpl *4206616
6164// DISASM-NEXT: 401066: 68 38 00 00 00 pushl $56
6265// DISASM-NEXT: 40106b: e9 d0 ff ff ff jmp -48 <zed2@plt>
6366
deps/lld/test/ELF/gnu-ifunc-plt.s+18-15
......@@ -5,22 +5,22 @@
55// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout
66// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
77// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
8// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
8// RUN: llvm-readobj -r --dynamic-table %tout | FileCheck %s
99
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-NEXT: 0x202018 R_X86_64_JUMP_SLOT bar2 0x0
14// CHECK-NEXT: 0x202020 R_X86_64_JUMP_SLOT zed2 0x0
15// CHECK-NEXT: 0x202028 R_X86_64_IRELATIVE - 0x201000
16// CHECK-NEXT: 0x202030 R_X86_64_IRELATIVE - 0x201001
13// CHECK-NEXT: 0x203018 R_X86_64_JUMP_SLOT bar2 0x0
14// CHECK-NEXT: 0x203020 R_X86_64_JUMP_SLOT zed2 0x0
15// CHECK-NEXT: 0x203028 R_X86_64_IRELATIVE - 0x201000
16// CHECK-NEXT: 0x203030 R_X86_64_IRELATIVE - 0x201001
1717
1818// Check that .got.plt entries point back to PLT header
1919// GOTPLT: Contents of section .got.plt:
20// GOTPLT-NEXT: 202000 00302000 00000000 00000000 00000000
21// GOTPLT-NEXT: 202010 00000000 00000000 36102000 00000000
22// GOTPLT-NEXT: 202020 46102000 00000000 56102000 00000000
23// GOTPLT-NEXT: 202030 66102000 00000000
20// GOTPLT-NEXT: 203000 00202000 00000000 00000000 00000000
21// GOTPLT-NEXT: 203010 00000000 00000000 36102000 00000000
22// GOTPLT-NEXT: 203020 46102000 00000000 56102000 00000000
23// GOTPLT-NEXT: 203030 66102000 00000000
2424
2525// Check that the PLTRELSZ tag includes the IRELATIVE relocations
2626// CHECK: DynamicSection [
......@@ -28,6 +28,7 @@
2828
2929// Check that a PLT header is written and the ifunc entries appear last
3030// DISASM: Disassembly of section .text:
31// DISASM-EMPTY:
3132// DISASM-NEXT: foo:
3233// DISASM-NEXT: 201000: c3 retq
3334// DISASM: bar:
......@@ -37,25 +38,27 @@
3738// DISASM-NEXT: 201007: e8 54 00 00 00 callq 84
3839// DISASM-NEXT: 20100c: e8 1f 00 00 00 callq 31
3940// DISASM-NEXT: 201011: e8 2a 00 00 00 callq 42
41// DISASM-EMPTY:
4042// DISASM-NEXT: Disassembly of section .plt:
43// DISASM-EMPTY:
4144// DISASM-NEXT: .plt:
42// DISASM-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)
43// DISASM-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
45// DISASM-NEXT: 201020: ff 35 e2 1f 00 00 pushq 8162(%rip)
46// DISASM-NEXT: 201026: ff 25 e4 1f 00 00 jmpq *8164(%rip)
4447// DISASM-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
4548// DISASM-EMPTY:
4649// DISASM-NEXT: bar2@plt:
47// DISASM-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
50// DISASM-NEXT: 201030: ff 25 e2 1f 00 00 jmpq *8162(%rip)
4851// DISASM-NEXT: 201036: 68 00 00 00 00 pushq $0
4952// DISASM-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
5053// DISASM-EMPTY:
5154// DISASM-NEXT: zed2@plt:
52// DISASM-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)
55// DISASM-NEXT: 201040: ff 25 da 1f 00 00 jmpq *8154(%rip)
5356// DISASM-NEXT: 201046: 68 01 00 00 00 pushq $1
5457// DISASM-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>
55// DISASM-NEXT: 201050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
58// DISASM-NEXT: 201050: ff 25 d2 1f 00 00 jmpq *8146(%rip)
5659// DISASM-NEXT: 201056: 68 00 00 00 00 pushq $0
5760// DISASM-NEXT: 20105b: e9 e0 ff ff ff jmp -32 <zed2@plt>
58// DISASM-NEXT: 201060: ff 25 ca 0f 00 00 jmpq *4042(%rip)
61// DISASM-NEXT: 201060: ff 25 ca 1f 00 00 jmpq *8138(%rip)
5962// DISASM-NEXT: 201066: 68 01 00 00 00 pushq $1
6063// DISASM-NEXT: 20106b: e9 d0 ff ff ff jmp -48 <zed2@plt>
6164
deps/lld/test/ELF/gnu-ifunc-relative.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: ld.lld --strip-all %t.o -o %t
44// RUN: llvm-readobj -r %t | FileCheck %s
55// RUN: ld.lld %t.o -o %t
6// RUN: llvm-readobj -r -t %t | FileCheck %s --check-prefixes=CHECK,SYM
6// RUN: llvm-readobj -r --symbols %t | FileCheck %s --check-prefixes=CHECK,SYM
77
88.type foo STT_GNU_IFUNC
99.globl foo
deps/lld/test/ELF/gnu-ifunc-shared.s+11-8
......@@ -7,6 +7,7 @@
77// Check that an IRELATIVE relocation is used for a non-preemptible ifunc
88// handler and a JUMP_SLOT is used for a preemptible ifunc
99// DISASM: Disassembly of section .text:
10// DISASM-EMPTY:
1011// DISASM-NEXT: fct:
1112// DISASM-NEXT: 1000: c3 retq
1213// DISASM: fct2:
......@@ -18,30 +19,32 @@
1819// DISASM-NEXT: 1011: c3 retq
1920// DISASM: f2:
2021// DISASM-NEXT: 1012: c3 retq
22// DISASM-EMPTY:
2123// DISASM-NEXT: Disassembly of section .plt:
24// DISASM-EMPTY:
2225// DISASM-NEXT: .plt:
23// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)
24// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
26// DISASM-NEXT: 1020: ff 35 e2 1f 00 00 pushq 8162(%rip)
27// DISASM-NEXT: 1026: ff 25 e4 1f 00 00 jmpq *8164(%rip)
2528// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
2629// DISASM-EMPTY:
2730// DISASM-NEXT: fct2@plt:
28// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
31// DISASM-NEXT: 1030: ff 25 e2 1f 00 00 jmpq *8162(%rip)
2932// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
3033// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
3134// DISASM-EMPTY:
3235// DISASM-NEXT: f2@plt:
33// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)
36// DISASM-NEXT: 1040: ff 25 da 1f 00 00 jmpq *8154(%rip)
3437// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
3538// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
36// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
39// DISASM-NEXT: 1050: ff 25 d2 1f 00 00 jmpq *8146(%rip)
3740// DISASM-NEXT: 1056: 68 00 00 00 00 pushq $0
3841// DISASM-NEXT: 105b: e9 e0 ff ff ff jmp -32 <f2@plt>
3942
4043// CHECK: Relocations [
4144// CHECK-NEXT: Section (4) .rela.plt {
42// CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT fct2 0x0
43// CHECK-NEXT: 0x2020 R_X86_64_JUMP_SLOT f2 0x0
44// CHECK-NEXT: 0x2028 R_X86_64_IRELATIVE - 0x1000
45// CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT fct2 0x0
46// CHECK-NEXT: 0x3020 R_X86_64_JUMP_SLOT f2 0x0
47// CHECK-NEXT: 0x3028 R_X86_64_IRELATIVE - 0x1000
4548
4649 // Hidden expect IRELATIVE
4750 .globl fct
deps/lld/test/ELF/gnu-ifunc.s+4-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: ld.lld -static %t.o -o %tout
44// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
5// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
5// RUN: llvm-readobj -r --symbols --sections %tout | FileCheck %s
66
77// CHECK: Sections [
88// CHECK: Section {
......@@ -90,6 +90,7 @@
9090// CHECK-NEXT: ]
9191
9292// DISASM: Disassembly of section .text:
93// DISASM-EMPTY:
9394// DISASM-NEXT: foo:
9495// DISASM-NEXT: 201000: {{.*}} retq
9596// DISASM: bar:
......@@ -100,7 +101,9 @@
100101// DISASM-NEXT: 20100c: {{.*}} movl $2097496, %edx
101102// DISASM-NEXT: 201011: {{.*}} movl $2097544, %edx
102103// DISASM-NEXT: 201016: {{.*}} movl $2097545, %edx
104// DISASM-EMPTY:
103105// DISASM-NEXT: Disassembly of section .plt:
106// DISASM-EMPTY:
104107// DISASM-NEXT: .plt:
105108// DISASM-NEXT: 201020: {{.*}} jmpq *4058(%rip)
106109// DISASM-NEXT: 201026: {{.*}} pushq $0
deps/lld/test/ELF/gnu-unique.s+3-3
......@@ -2,12 +2,12 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33//
44// RUN: ld.lld %t -shared -o %tout.so
5// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=GNU %s
5// RUN: llvm-readobj --dyn-syms %tout.so | FileCheck -check-prefix=GNU %s
66// RUN: ld.lld %t -shared -o %tout.so --gnu-unique
7// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=GNU %s
7// RUN: llvm-readobj --dyn-syms %tout.so | FileCheck -check-prefix=GNU %s
88//
99// RUN: ld.lld %t -shared -o %tout.so --no-gnu-unique
10// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=NO %s
10// RUN: llvm-readobj --dyn-syms %tout.so | FileCheck -check-prefix=NO %s
1111
1212// Check that STB_GNU_UNIQUE is treated as a global and ends up in the dynamic
1313// symbol table as STB_GNU_UNIQUE.
deps/lld/test/ELF/gnustack.s+3-3
......@@ -2,13 +2,13 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
33
44# RUN: ld.lld %t1 -z execstack -o %t
5# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RWX %s
5# RUN: llvm-readobj --program-headers -S %t | FileCheck --check-prefix=RWX %s
66
77# RUN: ld.lld %t1 -o %t
8# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s
8# RUN: llvm-readobj --program-headers -S %t | FileCheck --check-prefix=RW %s
99
1010# RUN: ld.lld %t1 -o %t -z noexecstack
11# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s
11# RUN: llvm-readobj --program-headers -S %t | FileCheck --check-prefix=RW %s
1212
1313# RW: Type: PT_GNU_STACK
1414# RW-NEXT: Offset: 0x0
deps/lld/test/ELF/got-aarch64.s deleted-40
......@@ -1,40 +0,0 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o
3// RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so
4// RUN: llvm-readobj -s -r %t.so | FileCheck %s
5// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
6
7// CHECK: Name: .got
8// CHECK-NEXT: Type: SHT_PROGBITS
9// CHECK-NEXT: Flags [
10// CHECK-NEXT: SHF_ALLOC
11// CHECK-NEXT: SHF_WRITE
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x30090
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 8
16// CHECK-NEXT: Link: 0
17// CHECK-NEXT: Info: 0
18// CHECK-NEXT: AddressAlignment: 8
19
20// CHECK: Relocations [
21// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
22// CHECK-NEXT: 0x30090 R_AARCH64_GLOB_DAT dat 0x0
23// CHECK-NEXT: }
24// CHECK-NEXT: ]
25
26// Page(0x20098) - Page(0x10000) = 0x10000 = 65536
27// 0x20098 & 0xff8 = 0x98 = 152
28
29// DISASM: main:
30// DISASM-NEXT: 10000: 00 01 00 90 adrp x0, #131072
31// DISASM-NEXT: 10004: 00 48 40 f9 ldr x0, [x0, #144]
32
33.global main,foo,dat
34.text
35main:
36 adrp x0, :got:dat
37 ldr x0, [x0, :got_lo12:dat]
38.data
39dat:
40 .word 42
deps/lld/test/ELF/got-i386.s+9-8
......@@ -1,10 +1,10 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
33// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -s -r -t %t | FileCheck %s
4// RUN: llvm-readobj -S -r --symbols %t | FileCheck %s
55// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
66
7// CHECK: Name: .got
7// CHECK: Name: .got.plt
88// CHECK-NEXT: Type: SHT_PROGBITS
99// CHECK-NEXT: Flags [
1010// CHECK-NEXT: SHF_ALLOC
......@@ -12,14 +12,14 @@
1212// CHECK-NEXT: ]
1313// CHECK-NEXT: Address: 0x402000
1414// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 0
15// CHECK-NEXT: Size:
1616// CHECK-NEXT: Link:
1717// CHECK-NEXT: Info:
1818// CHECK-NEXT: AddressAlignment:
1919
2020// CHECK: Symbol {
2121// CHECK: Name: bar
22// CHECK-NEXT: Value: 0x402000
22// CHECK-NEXT: Value: 0x40200C
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: 0x40200A
31// CHECK-NEXT: Value: 0x402016
3232// CHECK-NEXT: Size: 10
3333// CHECK-NEXT: Binding: Global
3434// CHECK-NEXT: Type: Object
......@@ -40,10 +40,11 @@
4040// 0x40200A - 10 = addr(.got) = 0x402000
4141// 0x40200A + 5 - 15 = addr(.got) = 0x402000
4242// DISASM: Disassembly of section .text:
43// DISASM-EMPTY:
4344// DISASM-NEXT: _start:
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)
45// DISASM-NEXT: 401000: c7 81 0c 00 00 00 01 00 00 00 movl $1, 12(%ecx)
46// DISASM-NEXT: 40100a: c7 81 16 00 00 00 02 00 00 00 movl $2, 22(%ecx)
47// DISASM-NEXT: 401014: c7 81 1b 00 00 00 03 00 00 00 movl $3, 27(%ecx)
4748
4849.global _start
4950_start:
deps/lld/test/ELF/got-plt-header.s+11-11
......@@ -1,31 +1,31 @@
11// REQUIRES: x86
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
33// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
55
66 call foo@plt
77
88// Check that the first .got.plt entry has the address of the dynamic table.
99
10// CHECK: Type: SHT_DYNAMIC
11// CHECK-NEXT: Flags [
12// CHECK-NEXT: SHF_ALLOC
13// CHECK-NEXT: SHF_WRITE
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: 0x2000
16
1017// CHECK: Name: .got.plt
1118// CHECK-NEXT: Type: SHT_PROGBITS
1219// CHECK-NEXT: Flags [
1320// CHECK-NEXT: SHF_ALLOC
1421// CHECK-NEXT: SHF_WRITE
1522// CHECK-NEXT: ]
16// CHECK-NEXT: Address: 0x2000
17// CHECK-NEXT: Offset: 0x2000
23// CHECK-NEXT: Address: 0x3000
24// CHECK-NEXT: Offset: 0x3000
1825// CHECK-NEXT: Size: 32
1926// CHECK-NEXT: Link: 0
2027// CHECK-NEXT: Info: 0
2128// CHECK-NEXT: AddressAlignment: 8
2229// CHECK-NEXT: EntrySize: 0
2330// CHECK-NEXT: SectionData (
24// CHECK-NEXT: 0000: 00300000 00000000 00000000 00000000
25
26// CHECK: Type: SHT_DYNAMIC
27// CHECK-NEXT: Flags [
28// CHECK-NEXT: SHF_ALLOC
29// CHECK-NEXT: SHF_WRITE
30// CHECK-NEXT: ]
31// CHECK-NEXT: Address: 0x3000
31// CHECK-NEXT: 0000: 00200000 00000000 00000000 00000000
deps/lld/test/ELF/got.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t
6// RUN: llvm-readobj -s -r %t | FileCheck %s
6// RUN: llvm-readobj -S -r %t | FileCheck %s
77// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
88
99// CHECK: Name: .got
deps/lld/test/ELF/got32-i386.s+1-1
......@@ -16,7 +16,7 @@ _start:
1616# CHECK: _start:
1717# CHECK-NEXT: 401001: 8b 1d {{.*}} movl 4202496, %ebx
1818# CHECK: Sections:
19# CHECK: Name Size Address
19# CHECK: Name Size VMA
2020# CHECK: .got 00000004 0000000000402000
2121
2222# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR
deps/lld/test/ELF/got32x-i386.s+6-6
......@@ -33,13 +33,13 @@
3333
3434## 73728 == 0x12000 == ADDR(.got)
3535# CHECK: _start:
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
36# CHECK-NEXT: 401001: 8b 05 {{.*}} movl 4202496, %eax
37# CHECK-NEXT: 401007: 8b 1d {{.*}} movl 4202496, %ebx
38# CHECK-NEXT: 40100d: 8b 80 {{.*}} movl -4096(%eax), %eax
39# CHECK-NEXT: 401013: 8b 83 {{.*}} movl -4096(%ebx), %eax
4040# CHECK: Sections:
41# CHECK: Name Size Address
42# CHECK: .got 00000004 0000000000403000
41# CHECK: Name Size VMA
42# CHECK: .got.plt 0000000c 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/gotpc-relax-nopic.s+16-14
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: ld.lld --hash-style=sysv %t.o -o %t1
4# RUN: llvm-readobj -symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
4# RUN: llvm-readobj --symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
55# RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
66
77## There is no relocations.
......@@ -14,6 +14,7 @@
1414
1515## 2105344 = 0x202000 (bar)
1616# DISASM: Disassembly of section .text:
17# DISASM-EMPTY:
1718# DISASM-NEXT: _start:
1819# DISASM-NEXT: 201000: {{.*}} adcq $2105344, %rax
1920# DISASM-NEXT: 201007: {{.*}} addq $2105344, %rbx
......@@ -26,7 +27,7 @@
2627# DISASM-NEXT: 201038: {{.*}} testq $2105344, %r15
2728
2829# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2
29# RUN: llvm-readobj -s -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s
30# RUN: llvm-readobj -S -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s
3031# RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM-PIC %s
3132# SEC-PIC: Section {
3233# SEC-PIC: Index:
......@@ -36,8 +37,8 @@
3637# SEC-PIC-NEXT: SHF_ALLOC
3738# SEC-PIC-NEXT: SHF_WRITE
3839# SEC-PIC-NEXT: ]
39# SEC-PIC-NEXT: Address: 0x30A0
40# SEC-PIC-NEXT: Offset: 0x30A0
40# SEC-PIC-NEXT: Address: 0x20A0
41# SEC-PIC-NEXT: Offset: 0x20A0
4142# SEC-PIC-NEXT: Size: 8
4243# SEC-PIC-NEXT: Link:
4344# SEC-PIC-NEXT: Info:
......@@ -46,7 +47,7 @@
4647# SEC-PIC-NEXT: }
4748# SEC-PIC: Relocations [
4849# SEC-PIC-NEXT: Section ({{.*}}) .rela.dyn {
49# SEC-PIC-NEXT: 0x30A0 R_X86_64_RELATIVE - 0x2000
50# SEC-PIC-NEXT: 0x20A0 R_X86_64_RELATIVE - 0x3000
5051# SEC-PIC-NEXT: }
5152# SEC-PIC-NEXT: ]
5253# SEC-PIC: 0x000000006FFFFFF9 RELACOUNT 1
......@@ -55,16 +56,17 @@
5556## Ex: 0x1000 + 4249 + 7 = 0x20A0
5657## 0x102a + 4207 + 7 = 0x20A0
5758# DISASM-PIC: Disassembly of section .text:
59# DISASM-PIC-EMPTY:
5860# DISASM-PIC-NEXT: _start:
59# DISASM-PIC-NEXT: 1000: {{.*}} adcq 8345(%rip), %rax
60# DISASM-PIC-NEXT: 1007: {{.*}} addq 8338(%rip), %rbx
61# DISASM-PIC-NEXT: 100e: {{.*}} andq 8331(%rip), %rcx
62# DISASM-PIC-NEXT: 1015: {{.*}} cmpq 8324(%rip), %rdx
63# DISASM-PIC-NEXT: 101c: {{.*}} orq 8317(%rip), %rdi
64# DISASM-PIC-NEXT: 1023: {{.*}} sbbq 8310(%rip), %rsi
65# DISASM-PIC-NEXT: 102a: {{.*}} subq 8303(%rip), %rbp
66# DISASM-PIC-NEXT: 1031: {{.*}} xorq 8296(%rip), %r8
67# DISASM-PIC-NEXT: 1038: {{.*}} testq %r15, 8289(%rip)
61# DISASM-PIC-NEXT: 1000: {{.*}} adcq 4249(%rip), %rax
62# DISASM-PIC-NEXT: 1007: {{.*}} addq 4242(%rip), %rbx
63# DISASM-PIC-NEXT: 100e: {{.*}} andq 4235(%rip), %rcx
64# DISASM-PIC-NEXT: 1015: {{.*}} cmpq 4228(%rip), %rdx
65# DISASM-PIC-NEXT: 101c: {{.*}} orq 4221(%rip), %rdi
66# DISASM-PIC-NEXT: 1023: {{.*}} sbbq 4214(%rip), %rsi
67# DISASM-PIC-NEXT: 102a: {{.*}} subq 4207(%rip), %rbp
68# DISASM-PIC-NEXT: 1031: {{.*}} xorq 4200(%rip), %r8
69# DISASM-PIC-NEXT: 1038: {{.*}} testq %r15, 4193(%rip)
6870
6971.data
7072.type bar, @object
deps/lld/test/ELF/gotpc-relax-und-dso.s+2-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %S/Inputs/gotpc-relax-und-dso.s -o %tdso.o
44# RUN: ld.lld -shared %tdso.o -o %t.so
55# RUN: ld.lld --hash-style=sysv -shared %t.o %t.so -o %tout
6# RUN: llvm-readobj -r -s %tout | FileCheck --check-prefix=RELOC %s
6# RUN: llvm-readobj -r -S %tout | FileCheck --check-prefix=RELOC %s
77# RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s
88
99# RELOC: Relocations [
......@@ -17,6 +17,7 @@
1717# 0x101e + 7 - 36 = 0x1001
1818# 0x1025 + 7 - 43 = 0x1001
1919# DISASM: Disassembly of section .text:
20# DISASM-EMPTY:
2021# DISASM-NEXT: foo:
2122# DISASM-NEXT: nop
2223# DISASM: hid:
deps/lld/test/ELF/gotpc-relax.s+1
......@@ -13,6 +13,7 @@
1313# 0x201011 + 7 - 23 = 0x201001
1414# 0x201018 + 7 - 30 = 0x201001
1515# DISASM: Disassembly of section .text:
16# DISASM-EMPTY:
1617# DISASM-NEXT: foo:
1718# DISASM-NEXT: 201000: 90 nop
1819# DISASM: hid:
deps/lld/test/ELF/gotpcrelx.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: %s -o %t.o
44// RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELS %s
55// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
6// RUN: llvm-readobj -s -r %t.so | FileCheck %s
6// RUN: llvm-readobj -S -r %t.so | FileCheck %s
77
88movq foo@GOTPCREL(%rip), %rax
99movq bar@GOTPCREL(%rip), %rax
deps/lld/test/ELF/hexagon-shared.s+7-7
......@@ -25,22 +25,22 @@ jumpr r0
2525# R_HEX_GOT_16_X
2626r0 = add(r1,##bar@GOT)
2727
28# PLT: { immext(#65472
29# PLT: r28 = add(pc,##65488) }
28# PLT: { immext(#131008
29# PLT: r28 = add(pc,##131024) }
3030# PLT: { r14 -= add(r28,#16)
3131# PLT: r15 = memw(r28+#8)
3232# PLT: r28 = memw(r28+#4) }
3333# PLT: { r14 = asr(r14,#2)
3434# PLT: jumpr r28 }
3535# PLT: { trap0(#219) }
36# PLT: immext(#65472)
37# PLT: r14 = add(pc,##65472) }
36# PLT: immext(#131008)
37# PLT: r14 = add(pc,##131008) }
3838# PLT: r28 = memw(r14+#0) }
3939# PLT: jumpr r28 }
4040
41# TEXT: 10000: 00 00 02 00 00020000
41# TEXT: 10000: 00 00 01 00 00010000
4242# TEXT: { call 0x10050 }
43# TEXT: r0 = add(r1,##65664) }
43# TEXT: r0 = add(r1,##-65408) }
4444
4545# GOT: .got:
46# GOT: 30080: 00 00 00 00 00000000 <unknown>
46# GOT: 20080: 00 00 00 00 00000000 <unknown>
deps/lld/test/ELF/hidden-shared-err.s+1-1
......@@ -11,7 +11,7 @@
1111# RUN: not ld.lld %t.o %t3.o %t2.so -o %t 2>&1 | FileCheck %s
1212# RUN: not ld.lld %t3.o %t.o %t2.so -o %t 2>&1 | FileCheck %s
1313
14# CHECK: undefined symbol: foo
14# CHECK: undefined hidden symbol: foo
1515
1616.global _start
1717_start:
deps/lld/test/ELF/i386-cet.s created+47
......@@ -0,0 +1,47 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/i386-cet1.s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/i386-cet2.s -o %t2.o
5# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/i386-cet3.s -o %t3.o
6# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/i386-cet4.s -o %t4.o
7
8# RUN: ld.lld -e func1 %t.o %t1.o -o %t
9# RUN: llvm-readelf -n %t | FileCheck -check-prefix=CET -match-full-lines %s
10
11# RUN: ld.lld -e func1 %t.o %t2.o -o %t
12# RUN: llvm-readelf -n %t | FileCheck -check-prefix=CET -match-full-lines %s
13
14# CET: Properties: x86 feature: IBT, SHSTK
15
16# RUN: ld.lld -e func1 %t.o %t3.o -o %t
17# RUN: llvm-readelf -S %t | FileCheck -check-prefix=NOCET %s
18
19# NOCET: Section Headers
20# NOCET-NOT: .note.gnu.property
21
22# RUN: not ld.lld -e func1 %t.o %t3.o -o %t --require-cet 2>&1 \
23# RUN: | FileCheck -check-prefix=ERROR %s
24# ERROR: i386-cet.s.tmp3.o: --require-cet: file is not compatible with CET
25
26# RUN: ld.lld -e func1 %t.o %t4.o -o %t
27# RUN: llvm-readelf -n %t | FileCheck -check-prefix=NOSHSTK -match-full-lines %s
28
29# Check .note.gnu.protery without property SHSTK.
30# NOSHSTK: Properties: x86 feature: IBT
31
32.section ".note.gnu.property", "a"
33.long 4
34.long 0xc
35.long 0x5
36.asciz "GNU"
37
38.long 0xc0000002
39.long 4
40.long 3
41
42.text
43.globl func1
44.type func1,@function
45func1:
46 call func2
47 ret
deps/lld/test/ELF/i386-debug-noabs.test+2-2
......@@ -29,5 +29,5 @@ Sections:
2929 Symbol: _GLOBAL_OFFSET_TABLE_
3030 Type: R_386_GOTPC
3131Symbols:
32 Global:
33 - Name: _GLOBAL_OFFSET_TABLE_
32 - Name: _GLOBAL_OFFSET_TABLE_
33 Binding: STB_GLOBAL
deps/lld/test/ELF/i386-got-and-copy.s+1-1
......@@ -14,8 +14,8 @@
1414
1515# CHECK: Relocations [
1616# CHECK-NEXT: Section (4) .rel.dyn {
17# CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_COPY foo
1817# CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_GLOB_DAT foo
18# CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_COPY foo
1919# CHECK-NEXT: }
2020# CHECK-NEXT: ]
2121
deps/lld/test/ELF/i386-gotoff-shared.s+4-12
......@@ -1,23 +1,15 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
33// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4// RUN: llvm-readobj -s %t.so | FileCheck %s
4// RUN: llvm-readelf -S %t.so | FileCheck %s
55// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
66
77bar:
88 movl bar@GOTOFF(%ebx), %eax
99 mov bar@GOT, %eax
1010
11// CHECK: Name: .got
12// CHECK-NEXT: Type: SHT_PROGBITS
13// CHECK-NEXT: Flags [
14// CHECK-NEXT: SHF_ALLOC
15// CHECK-NEXT: SHF_WRITE
16// CHECK-NEXT: ]
17// CHECK-NEXT: Address: 0x2050
18// CHECK-NEXT: Offset: 0x2050
19// CHECK-NEXT: Size: 4
11// CHECK: .got.plt PROGBITS 00003000
2012
21// 0x1000 - (0x2050 + 4) = -4180
13// 0x1000 - 0x3000 (.got.plt) = -8192
2214
23// DISASM: 1000: {{.*}} movl -4180(%ebx), %eax
15// DISASM: 1000: {{.*}} movl -8192(%ebx), %eax
deps/lld/test/ELF/i386-gotpc-dynamic.s+4-19
......@@ -1,28 +1,13 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
33# RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4# RUN: llvm-readobj -s %t.so | FileCheck %s
4# RUN: llvm-readelf -S %t.so | FileCheck %s
55# RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
66
7# CHECK: Section {
8# CHECK: Index: 7
9# CHECK-NEXT: Name: .got
10# CHECK-NEXT: Type: SHT_PROGBITS
11# CHECK-NEXT: Flags [
12# CHECK-NEXT: SHF_ALLOC
13# CHECK-NEXT: SHF_WRITE
14# CHECK-NEXT: ]
15# CHECK-NEXT: Address: 0x2030
16# CHECK-NEXT: Offset:
17# CHECK-NEXT: Size:
18# CHECK-NEXT: Link:
19# CHECK-NEXT: Info:
20# CHECK-NEXT: AddressAlignment:
21# CHECK-NEXT: EntrySize:
22# CHECK-NEXT: }
7# CHECK: .got.plt PROGBITS 00003000
238
24## 0x1000 + 4144 = 0x2030
25# DISASM: 1000: {{.*}} movl $4144, %eax
9## 0x3000 - 0x1000 = 8192
10# DISASM: 1000: {{.*}} movl $8192, %eax
2611
2712.section .foo,"ax",@progbits
2813foo:
deps/lld/test/ELF/i386-gotpc.s+5-18
......@@ -1,28 +1,15 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
33// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4// RUN: llvm-readobj -s %t.so | FileCheck %s
4// RUN: llvm-readelf -S %t.so | FileCheck %s
55// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
66
77movl $_GLOBAL_OFFSET_TABLE_, %eax
88
9// CHECK: Name: .got.plt
10// CHECK-NEXT: Type: SHT_PROGBITS
11// CHECK-NEXT: Flags [
12// CHECK-NEXT: SHF_ALLOC
13// CHECK-NEXT: SHF_WRITE
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: 0x2000
16
17// CHECK: Name: .got
18// CHECK-NEXT: Type: SHT_PROGBITS
19// CHECK-NEXT: Flags [
20// CHECK-NEXT: SHF_ALLOC
21// CHECK-NEXT: SHF_WRITE
22// CHECK-NEXT: ]
23// CHECK-NEXT: Address: 0x3030
9// CHECK: .got.plt PROGBITS 00003000
2410
2511// DISASM: Disassembly of section .text:
12// DISASM-EMPTY:
2613// DISASM-NEXT: .text:
27// DISASM-NEXT: 1000: {{.*}} movl $8240, %eax
28// 0x3030 - 0x1000 = 0x2030
14// DISASM-NEXT: 1000: {{.*}} movl $8192, %eax
15// 0x3000 (.got.plt) - 0x1000 = 8192
deps/lld/test/ELF/i386-merge.s+5-5
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
33// RUN: ld.lld %t.o -o %t -shared
4// RUN: llvm-readobj -s -section-data %t | FileCheck %s
4// RUN: llvm-readobj -S --section-data %t | FileCheck %s
55
66// CHECK: Name: .mysec
77// CHECK-NEXT: Type:
......@@ -9,7 +9,7 @@
99// CHECK-NEXT: SHF_ALLOC
1010// CHECK-NEXT: SHF_MERGE
1111// CHECK-NEXT: ]
12// CHECK-NEXT: Address: 0x158
12// CHECK-NEXT: Address: 0x178
1313// CHECK-NEXT: Offset:
1414// CHECK-NEXT: Size:
1515// CHECK-NEXT: Link:
......@@ -27,15 +27,15 @@
2727// CHECK-NEXT: SHF_ALLOC
2828// CHECK-NEXT: SHF_WRITE
2929// CHECK-NEXT: ]
30// CHECK-NEXT: Address: 0x1000
31// CHECK-NEXT: Offset: 0x1000
30// CHECK-NEXT: Address: 0x2000
31// CHECK-NEXT: Offset: 0x2000
3232// CHECK-NEXT: Size: 4
3333// CHECK-NEXT: Link: 0
3434// CHECK-NEXT: Info: 0
3535// CHECK-NEXT: AddressAlignment: 1
3636// CHECK-NEXT: EntrySize: 0
3737// CHECK-NEXT: SectionData (
38// CHECK-NEXT: 0000: 58010000 |
38// CHECK-NEXT: 0000: 78010000 |
3939// CHECK-NEXT: )
4040
4141// The content of .data should be the address of .mysec.
deps/lld/test/ELF/i386-pc16.test+6-6
......@@ -32,9 +32,9 @@ Sections:
3232 Symbol: _start
3333 Type: R_386_PC16
3434Symbols:
35 Global:
36 - Name: _start
37 Type: STT_FUNC
38 Section: .text
39 Value: 0x1234
40 Size: 4
35 - Name: _start
36 Type: STT_FUNC
37 Section: .text
38 Value: 0x1234
39 Size: 4
40 Binding: STB_GLOBAL
deps/lld/test/ELF/i386-relax-reloc.s+9-4
......@@ -1,12 +1,17 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o -relax-relocations
33// RUN: ld.lld -shared %t.o -o %t.so
4// RUN: llvm-readelf -S %t.so | FileCheck --check-prefix=SEC %s
45// RUN: llvm-objdump -d %t.so | FileCheck %s
56
7// SEC: .got PROGBITS 00002050
8// SEC-NEXT: .got.plt PROGBITS 00003000
9
10// 0x2050 - 0x3000 = -4016
11// CHECK: foo:
12// CHECK-NEXT: movl -4016(%ebx), %eax
13// CHECK-NEXT: movl -4008(%ebx), %eax
14
615foo:
716 movl bar@GOT(%ebx), %eax
817 movl bar+8@GOT(%ebx), %eax
9
10// CHECK: foo:
11// CHECK-NEXT: movl -4(%ebx), %eax
12// CHECK-NEXT: movl 4(%ebx), %eax
deps/lld/test/ELF/i386-reloc-16.s+16-11
......@@ -1,15 +1,20 @@
1// REQUIRES: x86
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o
23
3// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/x86-64-reloc-16.s -o %t1
4// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/x86-64-reloc-16-error.s -o %t2
5// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
6// RUN: ld.lld -shared %t %t1 -o %t3
7// RUN: llvm-objdump -s %t3 | FileCheck %s
4# RUN: ld.lld %t.o --defsym=a=0 --defsym=b=32768 -o %t
5# RUN: llvm-readelf -x .text %t | FileCheck %s
6# CHECK: b80080bb ffff
87
9// CHECK: Contents of section .text:
10// CHECK-NEXT: 1000 42
8# RUN: not ld.lld %t.o --defsym=a=-1 --defsym=b=0 -o /dev/null 2>&1 | \
9# RUN: FileCheck --check-prefix=OVERFLOW1 %s
10# OVERFLOW1: relocation R_386_16 out of range: -32769 is not in [-32768, 65535]
1111
12// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
13// ERROR: relocation R_386_16 out of range: 65536 is not in [-32768, 32767]
12# RUN: not ld.lld %t.o --defsym=a=0 --defsym=b=32769 -o /dev/null 2>&1 | \
13# RUN: FileCheck --check-prefix=OVERFLOW2 %s
14# OVERFLOW2: relocation R_386_16 out of range: 65536 is not in [-32768, 65535]
1415
15.short foo
16.code16
17.global _start
18_start:
19movw $a-32768, %ax
20movw $b+32767, %bx
deps/lld/test/ELF/i386-reloc-8.s+16-11
......@@ -1,15 +1,20 @@
1// REQUIRES: x86
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o
23
3// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-reloc-8.s -o %t1
4// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-reloc-8-error.s -o %t2
5// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
6// RUN: ld.lld -shared %t %t1 -o %t3
7// RUN: llvm-objdump -s %t3 | FileCheck %s
4# RUN: ld.lld %t.o --defsym=a=0 --defsym=b=128 -o %t
5# RUN: llvm-readelf -x .text %t | FileCheck %s
6# CHECK: b480b7ff
87
9// CHECK: Contents of section .text:
10// CHECK-NEXT: 1000 ff
8# RUN: not ld.lld %t.o --defsym=a=-1 --defsym=b=0 -o /dev/null 2>&1 | \
9# RUN: FileCheck --check-prefix=OVERFLOW1 %s
10# OVERFLOW1: relocation R_386_8 out of range: -129 is not in [-128, 255]
1111
12// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
13// ERROR: relocation R_386_8 out of range: 256 is not in [-128, 127]
12# RUN: not ld.lld %t.o --defsym=a=0 --defsym=b=129 -o /dev/null 2>&1 | \
13# RUN: FileCheck --check-prefix=OVERFLOW2 %s
14# OVERFLOW2: relocation R_386_8 out of range: 256 is not in [-128, 255]
1415
15.byte foo
16.code16
17.globl _start
18_start:
19movb $a-128, %ah
20movb $b+127, %bh
deps/lld/test/ELF/i386-reloc-large-addend.s+1
......@@ -8,6 +8,7 @@
88// RUN: llvm-objdump -d -triple=i386-pc-linux-code16 %t | FileCheck %s
99
1010// CHECK: Disassembly of section .text:
11// CHECK-EMPTY:
1112// CHECK-NEXT: _start:
1213// CHECK-NEXT: 7000: e9 fe 1f jmp 8190
1314// 0x1 + 0x9000 - 0x7003 == 8190
deps/lld/test/ELF/i386-reloc-range.s+1
......@@ -10,6 +10,7 @@
1010// RUN: llvm-objdump -d -triple=i386-pc-linux-code16 %t1 | FileCheck %s
1111
1212// CHECK: Disassembly of section .text:
13// CHECK-EMPTY:
1314// CHECK-NEXT: _start:
1415// CHECK-NEXT: 200: {{.*}} jmp -1
1516// 0x10202 - 0x203 == 0xffff
deps/lld/test/ELF/i386-retpoline-nopic-linkerscript.s+5-4
......@@ -13,10 +13,11 @@
1313// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
1414
1515// CHECK: Disassembly of section .plt:
16// CHECK-EMPTY:
1617// CHECK-NEXT: .plt:
17// CHECK-NEXT: 10: ff 35 84 00 00 00 pushl 132
18// CHECK-NEXT: 10: ff 35 ec 00 00 00 pushl 236
1819// CHECK-NEXT: 16: 50 pushl %eax
19// CHECK-NEXT: 17: a1 88 00 00 00 movl 136, %eax
20// CHECK-NEXT: 17: a1 f0 00 00 00 movl 240, %eax
2021// CHECK-NEXT: 1c: e8 0f 00 00 00 calll 15 <.plt+0x20>
2122// CHECK-NEXT: 21: f3 90 pause
2223// CHECK-NEXT: 23: 0f ae e8 lfence
......@@ -37,7 +38,7 @@
3738// CHECK-NEXT: 3e: c3 retl
3839// CHECK-NEXT: 3f: cc int3
3940// CHECK-NEXT: 40: 50 pushl %eax
40// CHECK-NEXT: 41: a1 8c 00 00 00 movl 140, %eax
41// CHECK-NEXT: 41: a1 f4 00 00 00 movl 244, %eax
4142// CHECK-NEXT: 46: e8 e5 ff ff ff calll -27 <.plt+0x20>
4243// CHECK-NEXT: 4b: e9 d1 ff ff ff jmp -47 <.plt+0x11>
4344// CHECK-NEXT: 50: 68 00 00 00 00 pushl $0
......@@ -49,7 +50,7 @@
4950// CHECK-NEXT: 5e: cc int3
5051// CHECK-NEXT: 5f: cc int3
5152// CHECK-NEXT: 60: 50 pushl %eax
52// CHECK-NEXT: 61: a1 90 00 00 00 movl 144, %eax
53// CHECK-NEXT: 61: a1 f8 00 00 00 movl 248, %eax
5354// CHECK-NEXT: 66: e8 c5 ff ff ff calll -59 <.plt+0x20>
5455// CHECK-NEXT: 6b: e9 b1 ff ff ff jmp -79 <.plt+0x11>
5556// CHECK-NEXT: 70: 68 08 00 00 00 pushl $8
deps/lld/test/ELF/i386-retpoline-nopic.s+6-5
......@@ -7,10 +7,11 @@
77// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
88
99// CHECK: Disassembly of section .plt:
10// CHECK-EMPTY:
1011// CHECK-NEXT: .plt:
11// CHECK-NEXT: 401010: ff 35 04 20 40 00 pushl 4202500
12// CHECK-NEXT: 401010: ff 35 04 30 40 00 pushl 4206596
1213// CHECK-NEXT: 401016: 50 pushl %eax
13// CHECK-NEXT: 401017: a1 08 20 40 00 movl 4202504, %eax
14// CHECK-NEXT: 401017: a1 08 30 40 00 movl 4206600, %eax
1415// CHECK-NEXT: 40101c: e8 0f 00 00 00 calll 15 <.plt+0x20>
1516// CHECK-NEXT: 401021: f3 90 pause
1617// CHECK-NEXT: 401023: 0f ae e8 lfence
......@@ -31,7 +32,7 @@
3132// CHECK-NEXT: 40103e: c3 retl
3233// CHECK-NEXT: 40103f: cc int3
3334// CHECK-NEXT: 401040: 50 pushl %eax
34// CHECK-NEXT: 401041: a1 0c 20 40 00 movl 4202508, %eax
35// CHECK-NEXT: 401041: a1 0c 30 40 00 movl 4206604, %eax
3536// CHECK-NEXT: 401046: e8 e5 ff ff ff calll -27 <.plt+0x20>
3637// CHECK-NEXT: 40104b: e9 d1 ff ff ff jmp -47 <.plt+0x11>
3738// CHECK-NEXT: 401050: 68 00 00 00 00 pushl $0
......@@ -43,7 +44,7 @@
4344// CHECK-NEXT: 40105e: cc int3
4445// CHECK-NEXT: 40105f: cc int3
4546// CHECK-NEXT: 401060: 50 pushl %eax
46// CHECK-NEXT: 401061: a1 10 20 40 00 movl 4202512, %eax
47// CHECK-NEXT: 401061: a1 10 30 40 00 movl 4206608, %eax
4748// CHECK-NEXT: 401066: e8 c5 ff ff ff calll -59 <.plt+0x20>
4849// CHECK-NEXT: 40106b: e9 b1 ff ff ff jmp -79 <.plt+0x11>
4950// CHECK-NEXT: 401070: 68 08 00 00 00 pushl $8
......@@ -56,7 +57,7 @@
5657// CHECK-NEXT: 40107f: cc int3
5758
5859// CHECK: Contents of section .got.plt:
59// CHECK-NEXT: 00304000 00000000 00000000 50104000
60// CHECK-NEXT: 00204000 00000000 00000000 50104000
6061// CHECK-NEXT: 70104000
6162
6263.global _start
deps/lld/test/ELF/i386-retpoline-pic-linkerscript.s+5-4
......@@ -13,10 +13,11 @@
1313// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
1414
1515// CHECK: Disassembly of section .plt:
16// CHECK-EMPTY:
1617// CHECK-NEXT: .plt:
17// CHECK-NEXT: 10: ff b3 84 00 00 00 pushl 132(%ebx)
18// CHECK-NEXT: 10: ff b3 04 00 00 00 pushl 4(%ebx)
1819// CHECK-NEXT: 16: 50 pushl %eax
19// CHECK-NEXT: 17: 8b 83 88 00 00 00 movl 136(%ebx), %eax
20// CHECK-NEXT: 17: 8b 83 08 00 00 00 movl 8(%ebx), %eax
2021// CHECK-NEXT: 1d: e8 0e 00 00 00 calll 14 <.plt+0x20>
2122// CHECK-NEXT: 22: f3 90 pause
2223// CHECK-NEXT: 24: 0f ae e8 lfence
......@@ -36,7 +37,7 @@
3637// CHECK-NEXT: 3e: c3 retl
3738// CHECK-NEXT: 3f: cc int3
3839// CHECK-NEXT: 40: 50 pushl %eax
39// CHECK-NEXT: 41: 8b 83 8c 00 00 00 movl 140(%ebx), %eax
40// CHECK-NEXT: 41: 8b 83 0c 00 00 00 movl 12(%ebx), %eax
4041// CHECK-NEXT: 47: e8 e4 ff ff ff calll -28 <.plt+0x20>
4142// CHECK-NEXT: 4c: e9 d1 ff ff ff jmp -47 <.plt+0x12>
4243// CHECK-NEXT: 51: 68 00 00 00 00 pushl $0
......@@ -47,7 +48,7 @@
4748// CHECK-NEXT: 5e: cc int3
4849// CHECK-NEXT: 5f: cc int3
4950// CHECK-NEXT: 60: 50 pushl %eax
50// CHECK-NEXT: 61: 8b 83 90 00 00 00 movl 144(%ebx), %eax
51// CHECK-NEXT: 61: 8b 83 10 00 00 00 movl 16(%ebx), %eax
5152// CHECK-NEXT: 67: e8 c4 ff ff ff calll -60 <.plt+0x20>
5253// CHECK-NEXT: 6c: e9 b1 ff ff ff jmp -79 <.plt+0x12>
5354// CHECK-NEXT: 71: 68 08 00 00 00 pushl $8
deps/lld/test/ELF/i386-retpoline-pic.s+7-6
......@@ -7,10 +7,11 @@
77// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
88
99// CHECK: Disassembly of section .plt:
10// CHECK-EMPTY:
1011// CHECK-NEXT: .plt:
11// CHECK-NEXT: 1010: ff b3 04 20 00 00 pushl 8196(%ebx)
12// CHECK-NEXT: 1010: ff b3 04 00 00 00 pushl 4(%ebx)
1213// CHECK-NEXT: 1016: 50 pushl %eax
13// CHECK-NEXT: 1017: 8b 83 08 20 00 00 movl 8200(%ebx), %eax
14// CHECK-NEXT: 1017: 8b 83 08 00 00 00 movl 8(%ebx), %eax
1415// CHECK-NEXT: 101d: e8 0e 00 00 00 calll 14 <.plt+0x20>
1516// CHECK-NEXT: 1022: f3 90 pause
1617// CHECK-NEXT: 1024: 0f ae e8 lfence
......@@ -30,7 +31,7 @@
3031// CHECK-NEXT: 103e: c3 retl
3132// CHECK-NEXT: 103f: cc int3
3233// CHECK-NEXT: 1040: 50 pushl %eax
33// CHECK-NEXT: 1041: 8b 83 0c 20 00 00 movl 8204(%ebx), %eax
34// CHECK-NEXT: 1041: 8b 83 0c 00 00 00 movl 12(%ebx), %eax
3435// CHECK-NEXT: 1047: e8 e4 ff ff ff calll -28 <.plt+0x20>
3536// CHECK-NEXT: 104c: e9 d1 ff ff ff jmp -47 <.plt+0x12>
3637// CHECK-NEXT: 1051: 68 00 00 00 00 pushl $0
......@@ -41,7 +42,7 @@
4142// CHECK-NEXT: 105e: cc int3
4243// CHECK-NEXT: 105f: cc int3
4344// CHECK-NEXT: 1060: 50 pushl %eax
44// CHECK-NEXT: 1061: 8b 83 10 20 00 00 movl 8208(%ebx), %eax
45// CHECK-NEXT: 1061: 8b 83 10 00 00 00 movl 16(%ebx), %eax
4546// CHECK-NEXT: 1067: e8 c4 ff ff ff calll -60 <.plt+0x20>
4647// CHECK-NEXT: 106c: e9 b1 ff ff ff jmp -79 <.plt+0x12>
4748// CHECK-NEXT: 1071: 68 08 00 00 00 pushl $8
......@@ -53,8 +54,8 @@
5354// CHECK-NEXT: 107f: cc int3
5455
5556// CHECK: Contents of section .got.plt:
56// CHECK-NEXT: 2000 00300000 00000000 00000000 51100000
57// CHECK-NEXT: 2010 71100000
57// CHECK-NEXT: 3000 00200000 00000000 00000000 51100000
58// CHECK-NEXT: 3010 71100000
5859
5960.global _start
6061_start:
deps/lld/test/ELF/i386-static-tls-model.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model1.s -o %t.o
4# RUN: ld.lld %t.o -o %t1 -shared
5# RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model2.s -o %t.o
8# RUN: ld.lld %t.o -o %t2 -shared
9# RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
10
11# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model3.s -o %t.o
12# RUN: ld.lld %t.o -o %t3 -shared
13# RUN: llvm-readobj --dynamic-table %t3 | FileCheck %s
14
15# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/i386-static-tls-model4.s -o %t.o
16# RUN: ld.lld %t.o -o %t4 -shared
17# RUN: llvm-readobj --dynamic-table %t4 | FileCheck %s
18
19# CHECK: DynamicSection [
20# CHECK: FLAGS STATIC_TLS
deps/lld/test/ELF/i386-tls-ie-shared.s+28-27
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o
44// RUN: ld.lld -shared %tso.o -o %tso
55// RUN: ld.lld --hash-style=sysv -shared %t.o %tso -o %t1
6// RUN: llvm-readobj -s -r -d %t1 | FileCheck --check-prefix=GOTRELSHARED %s
6// RUN: llvm-readobj -S -r -d %t1 | FileCheck --check-prefix=GOTRELSHARED %s
77// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s
88
99// GOTRELSHARED: Section {
......@@ -14,8 +14,8 @@
1414// GOTRELSHARED-NEXT: SHF_ALLOC
1515// GOTRELSHARED-NEXT: SHF_WRITE
1616// GOTRELSHARED-NEXT: ]
17// GOTRELSHARED-NEXT: Address: 0x2058
18// GOTRELSHARED-NEXT: Offset: 0x2058
17// GOTRELSHARED-NEXT: Address: 0x2060
18// GOTRELSHARED-NEXT: Offset: 0x2060
1919// GOTRELSHARED-NEXT: Size: 16
2020// GOTRELSHARED-NEXT: Link: 0
2121// GOTRELSHARED-NEXT: Info: 0
......@@ -32,36 +32,37 @@
3232// GOTRELSHARED-NEXT: 0x102D R_386_RELATIVE - 0x0
3333// GOTRELSHARED-NEXT: 0x1036 R_386_RELATIVE - 0x0
3434// GOTRELSHARED-NEXT: 0x103F R_386_RELATIVE - 0x0
35// GOTRELSHARED-NEXT: 0x2058 R_386_TLS_TPOFF tlslocal0 0x0
36// GOTRELSHARED-NEXT: 0x205C R_386_TLS_TPOFF tlslocal1 0x0
37// GOTRELSHARED-NEXT: 0x2060 R_386_TLS_TPOFF tlsshared0 0x0
38// GOTRELSHARED-NEXT: 0x2064 R_386_TLS_TPOFF tlsshared1 0x0
35// GOTRELSHARED-NEXT: 0x2060 R_386_TLS_TPOFF tlslocal0 0x0
36// GOTRELSHARED-NEXT: 0x2064 R_386_TLS_TPOFF tlslocal1 0x0
37// GOTRELSHARED-NEXT: 0x2068 R_386_TLS_TPOFF tlsshared0 0x0
38// GOTRELSHARED-NEXT: 0x206C R_386_TLS_TPOFF tlsshared1 0x0
3939// GOTRELSHARED-NEXT: }
4040// GOTRELSHARED-NEXT: ]
4141// GOTRELSHARED: 0x6FFFFFFA RELCOUNT 8
4242
4343// DISASMSHARED: Disassembly of section test:
44// DISASMSHARED-EMPTY:
4445// DISASMSHARED-NEXT: _start:
45// (.got)[0] = 0x2058 = 8280
46// (.got)[1] = 0x205C = 8284
47// (.got)[2] = 0x2060 = 8288
48// (.got)[3] = 0x2064 = 8292
49// DISASMSHARED-NEXT: 1000: 8b 0d 58 20 00 00 movl 8280, %ecx
50// DISASMSHARED-NEXT: 1006: 65 8b 01 movl %gs:(%ecx), %eax
51// DISASMSHARED-NEXT: 1009: a1 58 20 00 00 movl 8280, %eax
52// DISASMSHARED-NEXT: 100e: 65 8b 00 movl %gs:(%eax), %eax
53// DISASMSHARED-NEXT: 1011: 03 0d 58 20 00 00 addl 8280, %ecx
54// DISASMSHARED-NEXT: 1017: 65 8b 01 movl %gs:(%ecx), %eax
55// DISASMSHARED-NEXT: 101a: 8b 0d 5c 20 00 00 movl 8284, %ecx
56// DISASMSHARED-NEXT: 1020: 65 8b 01 movl %gs:(%ecx), %eax
57// DISASMSHARED-NEXT: 1023: a1 5c 20 00 00 movl 8284, %eax
58// DISASMSHARED-NEXT: 1028: 65 8b 00 movl %gs:(%eax), %eax
59// DISASMSHARED-NEXT: 102b: 03 0d 5c 20 00 00 addl 8284, %ecx
60// DISASMSHARED-NEXT: 1031: 65 8b 01 movl %gs:(%ecx), %eax
61// DISASMSHARED-NEXT: 1034: 8b 0d 60 20 00 00 movl 8288, %ecx
62// DISASMSHARED-NEXT: 103a: 65 8b 01 movl %gs:(%ecx), %eax
63// DISASMSHARED-NEXT: 103d: 03 0d 64 20 00 00 addl 8292, %ecx
64// DISASMSHARED-NEXT: 1043: 65 8b 01 movl %gs:(%ecx), %eax
46// (.got)[0] = 0x2060 = 8288
47// (.got)[1] = 0x2064 = 8292
48// (.got)[2] = 0x2068 = 8296
49// (.got)[3] = 0x206C = 8300
50// DISASMSHARED-NEXT: 1000: {{.*}} movl 8288, %ecx
51// DISASMSHARED-NEXT: 1006: {{.*}} movl %gs:(%ecx), %eax
52// DISASMSHARED-NEXT: 1009: {{.*}} movl 8288, %eax
53// DISASMSHARED-NEXT: 100e: {{.*}} movl %gs:(%eax), %eax
54// DISASMSHARED-NEXT: 1011: {{.*}} addl 8288, %ecx
55// DISASMSHARED-NEXT: 1017: {{.*}} movl %gs:(%ecx), %eax
56// DISASMSHARED-NEXT: 101a: {{.*}} movl 8292, %ecx
57// DISASMSHARED-NEXT: 1020: {{.*}} movl %gs:(%ecx), %eax
58// DISASMSHARED-NEXT: 1023: {{.*}} movl 8292, %eax
59// DISASMSHARED-NEXT: 1028: {{.*}} movl %gs:(%eax), %eax
60// DISASMSHARED-NEXT: 102b: {{.*}} addl 8292, %ecx
61// DISASMSHARED-NEXT: 1031: {{.*}} movl %gs:(%ecx), %eax
62// DISASMSHARED-NEXT: 1034: {{.*}} movl 8296, %ecx
63// DISASMSHARED-NEXT: 103a: {{.*}} movl %gs:(%ecx), %eax
64// DISASMSHARED-NEXT: 103d: {{.*}} addl 8300, %ecx
65// DISASMSHARED-NEXT: 1043: {{.*}} movl %gs:(%ecx), %eax
6566
6667.type tlslocal0,@object
6768.section .tbss,"awT",@nobits
deps/lld/test/ELF/i386-tls-ld-preemptable.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o
3# RUN: ld.lld %t.o -shared -o %t.so
4# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s
5
6# CHECK: 100b: movl (%eax), %eax
7
8# We used to error on R_386_TLS_LDO_32 to preemptable symbols.
9# i is STB_GLOBAL and preemptable.
10 leal i@TLSLDM(%ebx), %eax
11 calll __tls_get_addr@PLT
12 movl i@DTPOFF(%eax), %eax # R_386_TLS_LDO_32
13
14.section .tbss,"awT",@nobits
15.globl i
16i:
17 .long 0
18 .size i, 4
deps/lld/test/ELF/i386-tls-le-align.s created+29
......@@ -0,0 +1,29 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t | FileCheck %s
5
6# -alignTo(p_memsz, p_align) = -alignTo(4, 64) = -64
7
8# CHECK: movl %gs:0xffffffc0, %eax
9 movl %gs:a@NTPOFF, %eax
10
11# CHECK-NEXT: subl $0x40, %edx
12 subl $a@tpoff, %edx
13
14# GD to LE relaxation.
15# CHECK-NEXT: movl %gs:0x0, %eax
16# CHECK-NEXT: subl $0x40, %eax
17 leal a@tlsgd(,%ebx,1), %eax
18 call ___tls_get_addr@plt
19 ret
20
21.globl ___tls_get_addr
22.type ___tls_get_addr,@function
23___tls_get_addr:
24
25.section .tbss,"awT"
26.align 64
27a:
28.long 0
29.size a, 4
deps/lld/test/ELF/i386-tls-le-undef.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o
3# RUN: ld.lld --noinhibit-exec %t.o -o %t 2>&1
4# RUN: llvm-objdump -d %t | FileCheck %s
5
6## Undefined TLS symbols resolve to 0.
7## In --noinhibit-exec mode, a non-weak undefined symbol is not an error.
8
9# CHECK: subl $0, %eax
10# CHECK: subl $0, %eax
11
12.weak weak_undef
13movl %gs:0, %eax
14subl $weak_undef@tpoff,%eax
15movl %gs:0, %eax
16subl $undef@tpoff,%eax
deps/lld/test/ELF/icf-merged-sections.s+2-2
......@@ -2,7 +2,7 @@
22
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
44# RUN: ld.lld %t.o -o %t --icf=all --ignore-data-address-equality --print-icf-sections | FileCheck -allow-empty --check-prefix=NOICF %s
5# RUN: llvm-readobj -s -section-data %t | FileCheck %s
5# RUN: llvm-readobj -S --section-data %t | FileCheck %s
66
77# Check that merge synthetic sections are not merged by ICF.
88
......@@ -19,7 +19,7 @@
1919# CHECK-NEXT: Size: 16
2020# CHECK-NEXT: Link:
2121# CHECK-NEXT: Info:
22# CHECK-NEXT: AddressAlignment: 8
22# CHECK-NEXT: AddressAlignment: 1
2323# CHECK-NEXT: EntrySize: 0
2424# CHECK-NEXT: SectionData (
2525# CHECK-NEXT: 0000: 67452301 10325476 67452301 10325476
deps/lld/test/ELF/icf-symbol-type.s+1-1
......@@ -7,8 +7,8 @@
77# We used to mark bar as absolute.
88
99# CHECK: .text PROGBITS 0000000000001000
10# CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 foo
1110# CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 bar
11# CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 foo
1212
1313# The nop makes the test more interesting by making the offset of
1414# text.f non zero.
deps/lld/test/ELF/icf10.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-freebsd %s -o %t.o
4# RUN: ld.lld --icf=all %t.o -o /dev/null --print-icf-sections 2>&1 | FileCheck %s
5
6# Checks that ICF does not merge 2 sections the offset of
7# the relocations of which differ.
8
9# CHECK-NOT: selected
10
11.section .text.foo,"ax"
12 .quad -1
13 .reloc 0, R_X86_64_NONE, 0
14
15.section .text.bar,"ax"
16 .quad -1
17 .reloc 1, R_X86_64_NONE, 0
deps/lld/test/ELF/icf10.test deleted-40
......@@ -1,40 +0,0 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld --icf=all %t.o -o /dev/null --print-icf-sections 2>&1 | FileCheck %s
3
4# Checks that ICF does not merge 2 sections the offset of
5# the relocations of which differ.
6
7# CHECK-NOT: selected
8
9!ELF
10FileHeader:
11 Class: ELFCLASS64
12 Data: ELFDATA2LSB
13 OSABI: ELFOSABI_FREEBSD
14 Type: ET_REL
15 Machine: EM_X86_64
16Sections:
17 - Name: .text.foo
18 Type: SHT_PROGBITS
19 Flags: [ SHF_ALLOC, SHF_EXECINSTR]
20 Content: "FFFFFFFFFFFFFFFF"
21 - Name: .text.bar
22 Type: SHT_PROGBITS
23 Flags: [ SHF_ALLOC, SHF_EXECINSTR]
24 Content: "FFFFFFFFFFFFFFFF"
25 - Name: .rela.text.foo
26 Type: SHT_RELA
27 Link: .symtab
28 Info: .text.foo
29 Relocations:
30 - Offset: 0x0000000000000000
31 Symbol: ''
32 Type: R_X86_64_NONE
33 - Name: .rela.text.bar
34 Type: SHT_RELA
35 Link: .symtab
36 Info: .text.bar
37 Relocations:
38 - Offset: 0x0000000000000001
39 Symbol: ''
40 Type: R_X86_64_NONE
deps/lld/test/ELF/icf11.test+6-7
......@@ -33,7 +33,6 @@ Sections:
3333 Info: .text.foo
3434 Relocations:
3535 - Offset: 0x0000000000000000
36 Symbol: ''
3736 Type: R_X86_64_NONE
3837 - Name: .rela.text.bar
3938 Type: SHT_RELA
......@@ -44,9 +43,9 @@ Sections:
4443 Symbol: zed
4544 Type: R_X86_64_64
4645Symbols:
47 Global:
48 - Name: zed
49 Type: STT_FUNC
50 Section: .text
51 Value: 0x0
52 Size: 8
46 - Name: zed
47 Type: STT_FUNC
48 Section: .text
49 Value: 0x0
50 Size: 8
51 Binding: STB_GLOBAL
deps/lld/test/ELF/image-base.s+2-2
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: ld.lld -image-base=0x1000000 %t -o %t1
4# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
4# RUN: llvm-readobj -l %t1 | FileCheck %s
55
66# RUN: not ld.lld -image-base=ABC %t -o %t1 2>&1 | FileCheck --check-prefix=ERR %s
77# ERR: error: -image-base: number expected, but got ABC
......@@ -11,7 +11,7 @@
1111
1212# Check alias.
1313# RUN: ld.lld -image-base 0x1000000 %t -o %t1
14# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
14# RUN: llvm-readobj -l %t1 | FileCheck %s
1515
1616.global _start
1717_start:
deps/lld/test/ELF/init-fini-progbits.s+1-1
......@@ -2,7 +2,7 @@
22
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
44// RUN: ld.lld %t -o %t.exe
5// RUN: llvm-readobj -sections %t.exe | FileCheck %s
5// RUN: llvm-readobj --sections %t.exe | FileCheck %s
66
77// CHECK: Name: .init_array
88// CHECK-NEXT: Type: SHT_INIT_ARRAY
deps/lld/test/ELF/init-fini.s+6-6
......@@ -3,25 +3,25 @@
33
44// Should use "_init" and "_fini" by default when fills dynamic table
55// RUN: ld.lld -shared %t -o %t2
6// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=BYDEF %s
6// RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=BYDEF %s
77// BYDEF: INIT 0x11010
88// BYDEF: FINI 0x11020
99
1010// -init and -fini override symbols to use
1111// RUN: ld.lld -shared %t -o %t2 -init _foo -fini _bar
12// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=OVR %s
12// RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=OVR %s
1313// OVR: INIT 0x11030
1414// OVR: FINI 0x11040
1515
1616// Check aliases as well
1717// RUN: ld.lld -shared %t -o %t2 -init=_foo -fini=_bar
18// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=OVR %s
18// RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=OVR %s
1919
2020// Don't add an entry for undef. The freebsd dynamic linker doesn't
2121// check if the value is null. If it is, it will just call the
2222// load address.
2323// RUN: ld.lld -shared %t -o %t2 -init=_undef -fini=_undef
24// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=UNDEF %s
24// RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=UNDEF %s
2525// UNDEF-NOT: INIT
2626// UNDEF-NOT: FINI
2727
......@@ -30,14 +30,14 @@
3030// RUN: echo > %t.s
3131// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t2.o
3232// RUN: ld.lld -shared %t2.o %t.so -o %t2
33// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=SHARED %s
33// RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=SHARED %s
3434// SHARED-NOT: INIT
3535// SHARED-NOT: FINI
3636
3737// Should not add new entries to the symbol table
3838// and should not require given symbols to be resolved
3939// RUN: ld.lld -shared %t -o %t2 -init=_unknown -fini=_unknown
40// RUN: llvm-readobj -symbols -dynamic-table %t2 | FileCheck --check-prefix=NOENTRY %s
40// RUN: llvm-readobj --symbols --dynamic-table %t2 | FileCheck --check-prefix=NOENTRY %s
4141// NOENTRY: Symbols [
4242// NOENTRY-NOT: Name: _unknown
4343// NOENTRY: ]
deps/lld/test/ELF/invalid-relocations.test+2-2
......@@ -17,7 +17,7 @@ Sections:
1717 Symbol: lulz
1818 Type: R_X86_64_PC32
1919Symbols:
20 Global:
21 - Name: lulz
20 - Name: lulz
21 Binding: STB_GLOBAL
2222
2323# CHECK: invalid relocated section index
deps/lld/test/ELF/invalid-undef-section-symbol.test deleted-27
......@@ -1,27 +0,0 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: not ld.lld -r %t.o -o /dev/null 2>&1 | FileCheck %s
3
4# We used to crash at this.
5# CHECK: STT_SECTION symbol should be defined
6
7--- !ELF
8FileHeader:
9 Class: ELFCLASS64
10 Data: ELFDATA2LSB
11 Type: ET_REL
12 Machine: EM_X86_64
13Sections:
14 - Name: .text
15 Type: SHT_PROGBITS
16 - Name: .rela.text
17 Type: SHT_RELA
18 AddressAlign: 0x0000000000000008
19 Info: .text
20 Relocations:
21 - Offset: 0x0000000000000000
22 Symbol: .text
23 Type: R_X86_64_NONE
24Symbols:
25 Local:
26 - Name: .text
27 Type: STT_SECTION
deps/lld/test/ELF/invalid/Inputs/binding.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/binding.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/broken-relaxation-x64.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/broken-relaxation-x64.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/common-symbol-alignment.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/common-symbol-alignment.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/common-symbol-alignment2.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/common-symbol-alignment2.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/data-encoding.a deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/data-encoding.a and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/dynamic-section-sh_size.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/dynamic-section-sh_size.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/file-class.a deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/file-class.a and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/invalid-e_shnum.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/invalid-e_shnum.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/mips-invalid-options-descriptor.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/mips-invalid-options-descriptor.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/multiple-eh-relocs.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/multiple-eh-relocs.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/section-alignment-notpow2.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/section-alignment-notpow2.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/section-index.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/section-index.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/symbol-index.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/symbol-index.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/symbol-name-offset.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/symbol-name-offset.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/symtab-sh_info.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/symtab-sh_info.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/symtab-sh_info2.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/symtab-sh_info2.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/symtab-sh_info3.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/symtab-sh_info3.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/tls-symbol.elf deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/tls-symbol.elf and /dev/null differ
deps/lld/test/ELF/invalid/Inputs/undefined-local-symbol-in-dso.so deleted
Binary files a/deps/lld/test/ELF/invalid/Inputs/undefined-local-symbol-in-dso.so and /dev/null differ
deps/lld/test/ELF/invalid/bad-arm-attributes.s created+8
......@@ -0,0 +1,8 @@
1# REQUIRES: arm
2# RUN: llvm-mc -filetype=obj -triple=arm-unknown-linux %s -o %t
3# RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
4
5# CHECK: invalid subsection length 0 at offset 1
6
7.section .ARM.attributes,"a",%0x70000003
8 .quad 0
deps/lld/test/ELF/invalid/bad-arm-attributes2.s created+8
......@@ -0,0 +1,8 @@
1# REQUIRES: arm
2# RUN: llvm-mc -filetype=obj -triple=arm-unknown-linux %s -o %t
3# RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
4
5# CHECK: invalid subsection length 4294967295 at offset 1
6
7.section .ARM.attributes,"a",%0x70000003
8 .byte 0, 0xFF, 0xFF, 0xFF, 0xFF
deps/lld/test/ELF/invalid/bad-reloc-target.test created+76
......@@ -0,0 +1,76 @@
1# RUN: yaml2obj -docnum=1 %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--- !ELF
6FileHeader:
7 Class: ELFCLASS64
8 Data: ELFDATA2LSB
9 Type: ET_REL
10 Machine: EM_X86_64
11Sections:
12 - Name: .text
13 Type: SHT_PROGBITS
14 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
15 - Name: .rela.text
16 Type: SHT_RELA
17 Link: .symtab
18 Info: 0
19 Relocations:
20 - Offset: 0x0000000000000000
21 Symbol: foo
22 Type: R_X86_64_64
23Symbols:
24 - Name: foo
25 Binding: STB_GLOBAL
26
27# RUN: yaml2obj -docnum=2 %s -o %t2.o
28# RUN: not ld.lld %t2.o -o %t2 2>&1 | FileCheck %s --check-prefix=ERR2
29# ERR2: error: {{.*}}.o: invalid relocated section index: 99
30
31--- !ELF
32FileHeader:
33 Class: ELFCLASS64
34 Data: ELFDATA2LSB
35 Type: ET_REL
36 Machine: EM_X86_64
37Sections:
38 - Name: .text
39 Type: SHT_PROGBITS
40 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
41 - Name: .rela.text
42 Type: SHT_RELA
43 Link: .symtab
44 Info: 99
45 Relocations:
46 - Offset: 0x0000000000000000
47 Symbol: foo
48 Type: R_X86_64_64
49Symbols:
50 - Name: foo
51 Binding: STB_GLOBAL
52
53## Relocation refers to a symbol with index larger than
54## symbol table size. Check we report it.
55# RUN: yaml2obj -docnum=3 %s -o %t2.o
56# RUN: not ld.lld %t2.o -o %t2 2>&1 | FileCheck %s --check-prefix=ERR3
57# ERR3: error: {{.*}}.o: invalid symbol index
58
59--- !ELF
60FileHeader:
61 Class: ELFCLASS64
62 Data: ELFDATA2LSB
63 Type: ET_REL
64 Machine: EM_X86_64
65Sections:
66 - Name: .text
67 Type: SHT_PROGBITS
68 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
69 - Name: .rela.text
70 Type: SHT_RELA
71 Link: .symtab
72 Info: .text
73 Relocations:
74 - Offset: 0x0000000000000000
75 Symbol: 255
76 Type: R_X86_64_64
deps/lld/test/ELF/invalid/broken-relaxation-x64.test+7-6
......@@ -38,9 +38,10 @@ Sections:
3838 Symbol: foo
3939 Type: R_X86_64_GOTTPOFF
4040Symbols:
41 Global:
42 - Name: foo
43 Type: STT_TLS
44 Section: .text
45 Value: 0x12345
46 Size: 4
41 - Name: foo
42 Type: STT_TLS
43 Section: .text
44 Value: 0x12345
45 Size: 4
46 Binding: STB_GLOBAL
47
\ No newline at end of file
deps/lld/test/ELF/invalid/comdat-broken.test+2-2
......@@ -21,5 +21,5 @@ Sections:
2121 - SectionOrType: 0xFF
2222 - SectionOrType: 3
2323Symbols:
24 Global:
25 - Name: foo
24 - Name: foo
25 Binding: STB_GLOBAL
deps/lld/test/ELF/invalid/common-symbol-alignment.s deleted-12
......@@ -1,12 +0,0 @@
1# REQUIRES: x86
2
3## common-symbol-alignment.elf contains common symbol with zero alignment.
4# RUN: not ld.lld %S/Inputs/common-symbol-alignment.elf \
5# RUN: -o %t 2>&1 | FileCheck %s
6# CHECK: common symbol 'bar' has invalid alignment: 0
7
8## common-symbol-alignment2.elf contains common symbol alignment greater
9## than UINT32_MAX.
10# RUN: not ld.lld %S/Inputs/common-symbol-alignment2.elf \
11# RUN: -o %t 2>&1 | FileCheck %s --check-prefix=BIG
12# BIG: common symbol 'bar' has invalid alignment: 271644049215
deps/lld/test/ELF/invalid/common-symbol-alignment.test created+36
......@@ -0,0 +1,36 @@
1## If an object contains a common symbol with zero alignment,
2## check we report it.
3# RUN: yaml2obj -docnum=1 %s -o %t1.o
4# RUN: not ld.lld %t1.o -o %t 2>&1 | FileCheck %s
5# CHECK: common symbol 'bar' has invalid alignment: 0
6
7--- !ELF
8FileHeader:
9 Class: ELFCLASS64
10 Data: ELFDATA2LSB
11 Type: ET_REL
12 Machine: EM_X86_64
13Symbols:
14 - Name: bar
15 Type: STT_FUNC
16 Index: SHN_COMMON
17 Binding: STB_GLOBAL
18
19## If an object contains a common symbol with alignment greater
20## than UINT32_MAX, check we report it.
21# RUN: yaml2obj -docnum=2 %s -o %t2.o
22# RUN: not ld.lld %t2.o -o %t 2>&1 | FileCheck %s --check-prefix=BIG
23# BIG: common symbol 'bar' has invalid alignment: 271644049215
24
25--- !ELF
26FileHeader:
27 Class: ELFCLASS64
28 Data: ELFDATA2LSB
29 Type: ET_REL
30 Machine: EM_X86_64
31Symbols:
32 - Name: bar
33 Type: STT_FUNC
34 Index: SHN_COMMON
35 Value: 0x0000003F3F3F3F3F
36 Binding: STB_GLOBAL
deps/lld/test/ELF/invalid/data-encoding.test created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2
3# The object in the archive has invalid data encoding.
4# Check we report this.
5
6# RUN: yaml2obj %s -o %t.o
7# RUN: llvm-ar rcs %t.a %t.o
8
9# RUN: not ld.lld --whole-archive %t.a -o /dev/null 2>&1 | FileCheck %s
10# CHECK: {{.*}}.a({{.*}}.o): corrupted ELF file: invalid data encoding
11
12--- !ELF
13FileHeader:
14 Class: ELFCLASS64
15 Data: ELFDATANONE
16 Type: ET_REL
17 Machine: EM_X86_64
deps/lld/test/ELF/invalid/dynamic-section-broken.test created+36
......@@ -0,0 +1,36 @@
1## .dynamic section has invalid sh_entsize, check we report it.
2# RUN: yaml2obj -docnum=1 %s -o %t.so
3# RUN: not ld.lld %t.so -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1
4# ERR1: error: {{.*}}.so: section [index 1] has an invalid sh_entsize: 291
5
6--- !ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_DYN
11 Machine: EM_X86_64
12Sections:
13 - Name: .dynamic
14 Type: SHT_DYNAMIC
15 Flags: [ SHF_ALLOC ]
16 Link: .strtab
17 EntSize: 0x123
18
19## The .dynamic section has invalid sh_size, which is too short and
20## even less than entry size. Check we report it.
21# RUN: yaml2obj -docnum=2 %s -o %t.so
22# RUN: not ld.lld %t.so -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
23# ERR2: error: {{.*}}.so: section [index 1] has an invalid sh_size (1) which is not a multiple of its sh_entsize (16)
24
25--- !ELF
26FileHeader:
27 Class: ELFCLASS64
28 Data: ELFDATA2LSB
29 Type: ET_DYN
30 Machine: EM_X86_64
31Sections:
32 - Name: .dynamic
33 Type: SHT_DYNAMIC
34 Flags: [ SHF_ALLOC ]
35 Link: .strtab
36 Content: "00"
deps/lld/test/ELF/invalid/dynamic-section-size.s deleted-4
......@@ -1,4 +0,0 @@
1## dynamic-section-sh_size.elf has incorrect sh_size of dynamic section.
2# RUN: not ld.lld %p/Inputs/dynamic-section-sh_size.elf -o /dev/null 2>&1 | \
3# RUN: FileCheck %s
4# CHECK: error: {{.*}}: invalid sh_entsize
deps/lld/test/ELF/invalid/ehframe-broken-relocation.test+6-6
......@@ -23,9 +23,9 @@ Sections:
2323 Symbol: zed
2424 Type: R_X86_64_64
2525Symbols:
26 Global:
27 - Name: zed
28 Type: STT_FUNC
29 Section: .eh_frame
30 Value: 0x0
31 Size: 8
26 - Name: zed
27 Type: STT_FUNC
28 Section: .eh_frame
29 Value: 0x0
30 Size: 8
31 Binding: STB_GLOBAL
deps/lld/test/ELF/invalid/invalid-binding.test created+19
......@@ -0,0 +1,19 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
3# CHECK: error: {{.*}}.o: unexpected binding: 9
4
5--- !ELF
6FileHeader:
7 Class: ELFCLASS64
8 Data: ELFDATA2LSB
9 OSABI: ELFOSABI_GNU
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .text
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
16Symbols:
17 - Name: foo
18 Section: .text
19 Binding: 0x9
deps/lld/test/ELF/invalid/invalid-debug-relocations.test+6-6
......@@ -2,7 +2,7 @@
22# RUN: yaml2obj %s -o %t.o
33# RUN: not ld.lld -gdb-index %t.o -o %t.exe 2>&1 | FileCheck %s
44
5# CHECK: error: {{.*}}invalid-debug-relocations.test.tmp.o:(.debug_info+0x0): has non-ABS relocation Unknown (255) against symbol '_start'
5# CHECK: error: {{.*}}invalid-debug-relocations.test.tmp.o:(.debug_info+0x0): unknown relocation (255) against symbol _start
66
77!ELF
88FileHeader:
......@@ -33,8 +33,8 @@ Sections:
3333 Symbol: _start
3434 Type: 0xFF
3535Symbols:
36 Global:
37 - Name: _start
38 Type: STT_FUNC
39 Section: .text
40 Value: 0x0
36 - Name: _start
37 Type: STT_FUNC
38 Section: .text
39 Value: 0x0
40 Binding: STB_GLOBAL
deps/lld/test/ELF/invalid/invalid-e_shnum.s deleted-3
......@@ -1,3 +0,0 @@
1## Spec says that "If a file has no section header table, e_shnum holds the value zero.", though
2## in this test case it holds non-zero and lld used to crash.
3# RUN: ld.lld %p/Inputs/invalid-e_shnum.elf -o /dev/null
deps/lld/test/ELF/invalid/invalid-e_shnum.test created+15
......@@ -0,0 +1,15 @@
1## Spec says that "If a file has no section header table, e_shnum holds the value zero.", though
2## in this test case it holds non-zero and lld used to crash.
3
4# RUN: yaml2obj %s -o %t
5# RUN: ld.lld %t -o /dev/null
6
7--- !ELF
8FileHeader:
9 Class: ELFCLASS64
10 Data: ELFDATA2LSB
11 Type: ET_REL
12 Machine: EM_X86_64
13 SHOffset: 0
14 SHNum: 0x1
15 SHStrNdx: 0
deps/lld/test/ELF/invalid/invalid-elf.test+5-28
......@@ -1,28 +1,5 @@
1# REQUIRES: x86
2# RUN: llvm-mc %s -o %t -filetype=obj -triple x86_64-pc-linux
3
4# RUN: not ld.lld %t %p/Inputs/data-encoding.a -o %t2 2>&1 | \
5# RUN: FileCheck --check-prefix=INVALID-DATA-ENC %s
6# INVALID-DATA-ENC: test.o: invalid data encoding
7
8# RUN: not ld.lld %t %p/Inputs/file-class.a -o %t2 2>&1 | \
9# RUN: FileCheck --check-prefix=INVALID-FILE-CLASS %s
10# INVALID-FILE-CLASS: test.o: invalid file class
11
12# RUN: not ld.lld %p/Inputs/symtab-sh_info.elf -o %t2 2>&1 | \
13# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s
14# INVALID-SYMTAB-SHINFO: invalid sh_info in symbol table
15
16# RUN: not ld.lld %p/Inputs/binding.elf -o %t2 2>&1 | \
17# RUN: FileCheck --check-prefix=INVALID-BINDING %s
18# INVALID-BINDING: unexpected binding
19
20# RUN: not ld.lld %p/Inputs/section-index.elf -o %t2 2>&1 | \
21# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s
22# INVALID-SECTION-INDEX-LLD: invalid section index
23
24# RUN: not ld.lld %p/Inputs/multiple-eh-relocs.elf -o %t2 2>&1 | \
25# RUN: FileCheck --check-prefix=INVALID-EH-RELOCS %s
26# INVALID-EH-RELOCS: multiple relocation sections to one section are not supported
27
28.long foo
1# RUN: rm -rf %t && mkdir -p %t
2# RUN: echo > %t/empty.o
3# RUN: llvm-ar --format=gnu cr %t/not-elf.a %t/empty.o
4# RUN: not ld.lld --whole-archive %t/not-elf.a -o %t2 2>&1 | FileCheck %s
5# CHECK: not-elf.a(empty.o): not an ELF file
deps/lld/test/ELF/invalid/invalid-file-class.test created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: rm -rf %t && mkdir -p %t
3
4## In this test, we check that able to report objects with
5## invalid ELF class type. There are 2 cases we want to check:
6## when the object is a regular input and when it is fetched from the archive.
7
8## Create a broken ELF object with ELFCLASSNONE class using echo. We need to fill
9## first 18 bytes which are used by LLD to check the object.
10## 0x7f, 'E', 'L', 'F', ELFCLASSNONE(0), ELFDATA2LSB(1),
11## EV_CURRENT(1), ELFOSABI_LINUX(3), <padding zero bytes>, ET_REL(1), EM_NONE(0)
12# RUN: echo -e -n "\x7f\x45\x4c\x46\x00\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" > %t/invalid.o
13
14# RUN: llvm-ar --format=gnu cr %t/invalid-class.a %t/invalid.o
15# RUN: not ld.lld -whole-archive %t/invalid-class.a -o %t2 2>&1 | FileCheck %s
16# CHECK: invalid-class.a(invalid.o): corrupted ELF file: invalid file class
17
18# RUN: not ld.lld %t/invalid.o -o %t2 2>&1 | FileCheck %s --check-prefix=OBJ
19# OBJ: invalid.o: corrupted ELF file: invalid file class
deps/lld/test/ELF/invalid/invalid-relocation-x64.test+4-4
......@@ -3,8 +3,8 @@
33# RUN: echo ".global foo; foo:" > %t2.s
44# RUN: llvm-mc %t2.s -o %t2.o -filetype=obj -triple x86_64-pc-linux
55# RUN: not ld.lld %t1.o %t2.o -o /dev/null 2>&1 | FileCheck %s
6# CHECK: error: unrecognized reloc 152
7# CHECK: error: unrecognized reloc 153
6# CHECK: error: unknown relocation (152) against symbol foo
7# CHECK: error: unknown relocation (153) against symbol foo
88
99!ELF
1010FileHeader:
......@@ -29,5 +29,5 @@ Sections:
2929 Symbol: foo
3030 Type: 0x99
3131Symbols:
32 Global:
33 - Name: foo
32 - Name: foo
33 Binding: STB_GLOBAL
deps/lld/test/ELF/invalid/invalid-soname.test+4-1
......@@ -14,5 +14,8 @@ Sections:
1414 - Name: .test
1515 Type: SHT_DYNAMIC
1616 Flags: [ SHF_ALLOC ]
17 Content: "0e000000000000000000000000000001"
1817 Link: .strtab
18 EntSize: 0x0000000000000010
19 Entries:
20 - Tag: DT_SONAME
21 Value: 0x0100000000000000
deps/lld/test/ELF/invalid/mips-invalid-options-descriptor.s deleted-5
......@@ -1,5 +0,0 @@
1## mips-invalid-options-descriptor.elf has option descriptor in
2## .MIPS.options with size of zero.
3# RUN: not ld.lld %p/Inputs/mips-invalid-options-descriptor.elf -o /dev/null 2>&1 | \
4# RUN: FileCheck %s
5# CHECK: error: {{.*}}: invalid section offset
deps/lld/test/ELF/invalid/mips-invalid-options-descriptor.test created+21
......@@ -0,0 +1,21 @@
1# RUN: yaml2obj %s -o %t1.o
2# RUN: not ld.lld %t1.o -o %t 2>&1 | FileCheck %s
3# CHECK: error: {{.*}}1.o: zero option descriptor size
4
5## YAML has a description of ODK_NULL (Undefined) MIPS option,
6## with a size of zero. We do not allow options with a zero size.
7## Check we report it.
8
9--- !ELF
10FileHeader:
11 Class: ELFCLASS64
12 Data: ELFDATA2MSB
13 Type: ET_REL
14 Machine: EM_MIPS
15 Flags: [ EF_MIPS_CPIC, EF_MIPS_ARCH_64 ]
16Sections:
17 - Name: .MIPS.options
18 Type: SHT_MIPS_OPTIONS
19 Flags: [ SHF_ALLOC, SHF_MIPS_NOSTRIP ]
20 AddressAlign: 0x0000000000000008
21 Content: '0000000000000000'
deps/lld/test/ELF/invalid/multiple-relocations-sections.test created+29
......@@ -0,0 +1,29 @@
1# RUN: yaml2obj %s -o %t1.o
2# RUN: not ld.lld %t1.o -o %t 2>&1 | FileCheck %s
3# CHECK: error: {{.*}}1.o: multiple relocation sections to one section are not supported
4
5## The file has two relocation sections referring to a single target section.
6## Multiple relocation sections to one section are not supported, check we report this case.
7
8--- !ELF
9FileHeader:
10 Class: ELFCLASS64
11 Data: ELFDATA2LSB
12 Type: ET_REL
13 Machine: EM_X86_64
14Sections:
15 - Name: .text
16 Type: SHT_PROGBITS
17 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
18 - Name: .rela.text1
19 Type: SHT_RELA
20 Link: .symtab
21 Info: .text
22 - Name: .rela.text2
23 Type: SHT_RELA
24 Link: .symtab
25 Info: .text
26Symbols:
27 - Name: .text
28 Type: STT_SECTION
29 Section: .text
deps/lld/test/ELF/invalid/reloc-section-reordered.test+4
......@@ -28,3 +28,7 @@ Sections:
2828 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
2929 AddressAlign: 0x04
3030 Content: "FFFFFFFFFFFFFFFF"
31Symbols:
32 - Name: .text
33 Type: STT_SECTION
34 Section: .text
deps/lld/test/ELF/invalid/section-alignment2.s+16-5
......@@ -1,5 +1,16 @@
1## section-alignment-notpow2.elf has section alignment
2## 0xFFFFFFFF which is not a power of 2.
3# RUN: not ld.lld %p/Inputs/section-alignment-notpow2.elf -o /dev/null 2>&1 | \
4# RUN: FileCheck %s
5# CHECK: section sh_addralign is not a power of 2
1# RUN: yaml2obj %s -o %t.o
2# RUN: not ld.lld %t.o -o %tout 2>&1 | FileCheck %s
3
4# CHECK: error: {{.*}}.o:(.text): sh_addralign is not a power of 2
5
6!ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .text
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
16 AddressAlign: 0x3
deps/lld/test/ELF/invalid/section-index.test created+16
......@@ -0,0 +1,16 @@
1## If an object contains a symbol with a broken (too large) st_shndx,
2## check we report it.
3
4# RUN: yaml2obj %s -o %t1.o
5# RUN: not ld.lld %t1.o -o %t 2>&1 | FileCheck %s
6# CHECK: {{.*}}1.o: invalid section index: 256
7
8!ELF
9FileHeader:
10 Class: ELFCLASS32
11 Data: ELFDATA2LSB
12 Type: ET_REL
13 Machine: EM_386
14Symbols:
15 - Name: foo
16 Index: 0x100
deps/lld/test/ELF/invalid/sht-group-wrong-section.test+2-2
......@@ -18,5 +18,5 @@ Sections:
1818 - SectionOrType: GRP_COMDAT
1919 - SectionOrType: 12345
2020Symbols:
21 Global:
22 - Name: foo
21 - Name: foo
22 Binding: STB_GLOBAL
deps/lld/test/ELF/invalid/symbol-index.s deleted-10
......@@ -1,10 +0,0 @@
1## symbol-index.elf has incorrect type of .symtab section.
2## There is no symbol bodies because of that and any symbol index becomes incorrect.
3## Section Headers:
4## [Nr] Name Type Address Off Size ES Flg Lk Inf Al
5## [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
6## ...
7## [ 4] .symtab RELA 0000000000000000 000048 000030 18 1 2 8
8# RUN: not ld.lld %p/Inputs/symbol-index.elf -o /dev/null 2>&1 | \
9# RUN: FileCheck --check-prefix=INVALID-SYMBOL-INDEX %s
10# INVALID-SYMBOL-INDEX: invalid symbol index
deps/lld/test/ELF/invalid/symbol-name.s deleted-7
......@@ -1,7 +0,0 @@
1# REQUIRES: x86
2
3## symbol-name-offset.elf contains symbol with invalid (too large)
4## st_name value.
5# RUN: not ld.lld %S/Inputs/symbol-name-offset.elf \
6# RUN: -o /dev/null 2>&1 | FileCheck %s
7# CHECK: invalid symbol name offset
deps/lld/test/ELF/invalid/symbol-name.test created+15
......@@ -0,0 +1,15 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s
3# CHECK: error: {{.*}}.o: invalid symbol name offset
4
5## YAML below contains symbol with name offset in st_name
6## larger than string table size. Check we report it.
7
8!ELF
9FileHeader:
10 Class: ELFCLASS64
11 Data: ELFDATA2LSB
12 Type: ET_REL
13 Machine: EM_X86_64
14Symbols:
15 - NameIndex: 255
deps/lld/test/ELF/invalid/symtab-sh-info.s+59-9
......@@ -1,9 +1,59 @@
1## sh_info contains zero value. First entry in a symbol table is always completely zeroed,
2## so sh_info should be at least 1 in a valid ELF.
3# RUN: not ld.lld %p/Inputs/symtab-sh_info2.elf -o %t2 2>&1 | FileCheck %s
4# CHECK: invalid sh_info in symbol table
5
6## sh_info contains invalid value saying non-local symbol is local.
7# RUN: not ld.lld %p/Inputs/symtab-sh_info3.elf -o %t2 2>&1 | \
8# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s
9# INVALID-SYMTAB-SHINFO: broken object: getLocalSymbols returns a non-local symbol
1## .symtab's sh_info contains zero value. First entry in a .symtab is a
2## zero entry that must exist in a valid object, so sh_info can't be null.
3## Check we report a proper error for that case.
4# RUN: yaml2obj -docnum=1 %s -o %t.o
5# RUN: not ld.lld %t.o -o %t2 2>&1 | FileCheck %s --check-prefix=ERR1
6# ERR1: invalid sh_info in symbol table
7
8--- !ELF
9FileHeader:
10 Class: ELFCLASS64
11 Data: ELFDATA2LSB
12 Type: ET_REL
13 Machine: EM_X86_64
14Sections:
15 - Name: .symtab
16 Info: 0
17 Type: SHT_SYMTAB
18Symbols:
19 - Name: foo
20 Binding: STB_GLOBAL
21
22## sh_info has value 2 what says that non-local symbol `foo` is local.
23## Check we report this case.
24# RUN: yaml2obj -docnum=2 %s -o %t.o
25# RUN: not ld.lld %t.o -o %t2 2>&1 | FileCheck --check-prefix=ERR2 %s
26# ERR2: broken object: getLocalSymbols returns a non-local symbol
27
28--- !ELF
29FileHeader:
30 Class: ELFCLASS64
31 Data: ELFDATA2LSB
32 Type: ET_REL
33 Machine: EM_X86_64
34Sections:
35 - Name: .symtab
36 Info: 2
37 Type: SHT_SYMTAB
38Symbols:
39 - Name: foo
40 Binding: STB_GLOBAL
41
42## sh_info has value 0xff what is larger than number of symbols in a .symtab.
43## Check we report this case.
44# RUN: yaml2obj -docnum=3 %s -o %t.o
45# RUN: not ld.lld %t.o -o %t2 2>&1 | FileCheck --check-prefix=ERR1 %s
46
47--- !ELF
48FileHeader:
49 Class: ELFCLASS64
50 Data: ELFDATA2LSB
51 Type: ET_REL
52 Machine: EM_X86_64
53Sections:
54 - Name: .symtab
55 Info: 0xff
56 Type: SHT_SYMTAB
57Symbols:
58 - Name: foo
59 Binding: STB_GLOBAL
deps/lld/test/ELF/invalid/symtab-symbols.test+2-3
......@@ -20,6 +20,5 @@ Sections:
2020 AddressAlign: 0x0000000000000010
2121 Content: "00000000"
2222Symbols:
23 Local:
24 - Type: STT_NOTYPE
25 Section: .symtab
23 - Type: STT_NOTYPE
24 Section: .symtab
deps/lld/test/ELF/invalid/tls-symbol.s+22-3
......@@ -1,5 +1,24 @@
1# REQUIRES: x86
2
31## The test file contains an STT_TLS symbol but has no TLS section.
4# RUN: not ld.lld %S/Inputs/tls-symbol.elf -o /dev/null 2>&1 | FileCheck %s
2## Check we report an error properly.
3
4# RUN: yaml2obj %s -o %t.o
5# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
6
57# CHECK: has an STT_TLS symbol but doesn't have an SHF_TLS section
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 Content: ''
20Symbols:
21 - Name: bar
22 Type: STT_TLS
23 Section: .text
24 Binding: STB_GLOBAL
deps/lld/test/ELF/invalid/undefined-local-symbol-in-dso.test+16-56
......@@ -8,59 +8,19 @@
88# STB_LOCAL is a nonsensical combination. Nevertheless, we should warn on such
99# input files instead of crashing.
1010
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
11# RUN: yaml2obj %s -o %t.so
12# RUN: ld.lld %t.so -o %t 2>&1 | FileCheck -check-prefix=WARN %s
13# WARN: found local symbol 'foo' in global part of symbol table in file {{.*}}.so
14
15--- !ELF
16FileHeader:
17 Class: ELFCLASS64
18 Data: ELFDATA2LSB
19 Type: ET_DYN
20 Machine: EM_X86_64
21Sections:
22 - Name: .dynsym
23 Info: 1
24 Type: SHT_DYNSYM
25DynamicSymbols:
26 - Name: foo
deps/lld/test/ELF/invalid/verdef-no-symtab.test+1-8
......@@ -14,13 +14,6 @@ Sections:
1414 Type: SHT_GNU_versym
1515 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
1616 AddressAlign: 0x1
17 Content: "00000000"
18
19 - Name: .verdef
20 Type: SHT_GNU_verdef
21 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
22 AddressAlign: 0x1
23 Content: "00000000"
24
17 Entries: [ 0 ]
2518
2619# CHECK: SHT_GNU_versym should be associated with symbol table
deps/lld/test/ELF/invalid/x86-64-tlsdesc-gd.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: echo '.tbss; .globl a; a:' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
4# RUN: ld.lld -shared %t1.o -o %t1.so
5
6## GD to LE relaxation.
7# RUN: not ld.lld %t.o %t1.o -o /dev/null 2>&1 | FileCheck -DINPUT=%t.o %s
8## GD to IE relaxation.
9# RUN: not ld.lld %t.o %t1.so -o /dev/null 2>&1 | FileCheck -DINPUT=%t.o %s
10
11# CHECK: error: [[INPUT]]:(.text+0x0): R_X86_64_GOTPC32_TLSDESC must be used in callq *x@tlsdesc(%rip), %rax
12
13leaq a@tlsdesc(%rip), %rdx
14call *a@tlscall(%rdx)
15movl %fs:(%rax), %eax
deps/lld/test/ELF/linkerscript/absolute-expr.test+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: echo ".global foo; foo = 0x123" | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o
33# RUN: ld.lld -o %t.so --script %s %t.o -shared
4# RUN: llvm-readobj -t %t.so | FileCheck %s
4# RUN: llvm-readobj --symbols %t.so | FileCheck %s
55
66SECTIONS {
77 .text : {
deps/lld/test/ELF/linkerscript/addr-zero.test+10-4
......@@ -1,14 +1,14 @@
1# REQUIRES: x86
1# REQUIRES: x86, aarch64
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o
33# RUN: ld.lld -o %t.so --script %s %t.o -shared
44# RUN: llvm-readobj --symbols %t.so | FileCheck %s
55
6# Test that the script creates a non absolute symbol with value
7# 0 I.E., a symbol that refers to the load address.
6## Test that the script creates a non absolute symbol with value
7## 0 I.E., a symbol that refers to the load address.
88
99# CHECK: Symbol {
1010# CHECK: Name: foo
11# CHECK-NEXT: Value: 0x70
11# CHECK-NEXT: Value: 0x0
1212# CHECK-NEXT: Size: 0
1313# CHECK-NEXT: Binding: Global
1414# CHECK-NEXT: Type: None
......@@ -16,6 +16,12 @@
1616# CHECK-NEXT: Section: .text
1717# CHECK-NEXT: }
1818
19## Because of a bug we had a different behavior (different symbol 'foo' value)
20## on a platforms that might use thunks, like AArch64. Check that issue is fixed.
21# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu /dev/null -o %t.o
22# RUN: ld.lld -o %t.so --script %s %t.o -shared
23# RUN: llvm-readobj --symbols %t.so | FileCheck %s
24
1925SECTIONS {
2026 foo = ADDR(.text) - ABSOLUTE(ADDR(.text));
2127};
deps/lld/test/ELF/linkerscript/addr.test+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
55
66# CHECK: Sections:
7# CHECK-NEXT: Idx Name Size Address Type
7# CHECK-NEXT: Idx Name Size VMA Type
88# CHECK-NEXT: 0 00000000 0000000000000000
99# CHECK-NEXT: 1 .text 00000000 0000000000001000 TEXT
1010# CHECK-NEXT: 2 .foo.1 00000008 0000000000001000 DATA
deps/lld/test/ELF/linkerscript/align-empty.test+1-1
......@@ -13,7 +13,7 @@ SECTIONS {
1313}
1414
1515# CHECK: Sections:
16# CHECK-NEXT: Idx Name Size Address
16# CHECK-NEXT: Idx Name Size VMA
1717# CHECK-NEXT: 0 00000000 0000000000000000
1818# CHECK-NEXT: 1 .dynsym 00000018 0000000000000190
1919# CHECK-NEXT: 2 .gnu.hash 0000001c 00000000000001a8
deps/lld/test/ELF/linkerscript/align1.test+2-2
......@@ -13,7 +13,7 @@ SECTIONS {
1313}
1414
1515# CHECK: Sections:
16# CHECK-NEXT: Idx Name Size Address Type
16# CHECK-NEXT: Idx Name Size VMA Type
1717# CHECK-NEXT: 0 00000000 0000000000000000
1818# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA
1919# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA
......@@ -25,7 +25,7 @@ SECTIONS {
2525# RUN: llvm-objdump -section-headers %t4 | FileCheck %s -check-prefix=ZERO
2626
2727# ZERO: Sections:
28# ZERO-NEXT: Idx Name Size Address Type
28# ZERO-NEXT: Idx Name Size VMA Type
2929# ZERO-NEXT: 0 00000000 0000000000000000
3030# ZERO-NEXT: 1 .aaa 00000008 0000000000000123 DATA
3131
deps/lld/test/ELF/linkerscript/align2.test+1-1
......@@ -13,7 +13,7 @@ SECTIONS {
1313}
1414
1515# CHECK: Sections:
16# CHECK-NEXT: Idx Name Size Address Type
16# CHECK-NEXT: Idx Name Size VMA Type
1717# CHECK-NEXT: 0 00000000 0000000000000000
1818# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA
1919# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA
deps/lld/test/ELF/linkerscript/align3.test+1-1
......@@ -11,7 +11,7 @@ SECTIONS {
1111}
1212
1313# CHECK: Sections:
14# CHECK-NEXT: Idx Name Size Address Type
14# CHECK-NEXT: Idx Name Size VMA Type
1515# CHECK-NEXT: 0 00000000 0000000000000000
1616# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA
1717# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA
deps/lld/test/ELF/linkerscript/alternate-sections.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: echo "SECTIONS { abc : { *(foo) *(bar) *(zed) } }" > %t.script
44# RUN: ld.lld -o %t --script %t.script %t.o -shared
5# RUN: llvm-readobj -s -section-data %t | FileCheck %s
5# RUN: llvm-readobj -S --section-data %t | FileCheck %s
66
77# CHECK: Section {
88# CHECK: Index:
deps/lld/test/ELF/linkerscript/arm-exidx-order.test+2-2
......@@ -2,7 +2,7 @@
22# RUN: echo ".fnstart; .cantunwind; .fnend" \
33# RUN: | llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi - -o %t.o
44# RUN: ld.lld -T %s %t.o -shared -o %t.so
5# RUN: llvm-readobj -s %t.so | FileCheck %s
5# RUN: llvm-readobj -S %t.so | FileCheck %s
66
77SECTIONS {
88 . = SIZEOF_HEADERS;
......@@ -13,7 +13,7 @@ SECTIONS {
1313# CHECK: Section {
1414# CHECK: Index:
1515# CHECK: Name: .foo
16# CHECK-NEXT: Type: SHT_NOBITS
16# CHECK-NEXT: Type: SHT_PROGBITS
1717# CHECK-NEXT: Flags [
1818# CHECK-NEXT: SHF_ALLOC
1919# CHECK-NEXT: ]
deps/lld/test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s+1-1
......@@ -8,7 +8,7 @@
88## was anything but an input section description.
99# RUN: ld.lld --no-merge-exidx-entries -T %t.script %t.o -shared -o %t.so
1010# RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s
11# RUN: llvm-readobj -s -t %t.so | FileCheck %s --check-prefix=SYMBOL
11# RUN: llvm-readobj -S --symbols %t.so | FileCheck %s --check-prefix=SYMBOL
1212
1313 .syntax unified
1414 .text
deps/lld/test/ELF/linkerscript/at-addr.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: .ccc : AT(ADDR(.ccc) - 0x500) { *(.ccc) } \
77# RUN: }" > %t.script
88# RUN: ld.lld %t --script %t.script -o %t2
9# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
9# RUN: llvm-readobj -l %t2 | FileCheck %s
1010
1111# CHECK: Type: PT_LOAD
1212# CHECK-NEXT: Offset: 0x1000
deps/lld/test/ELF/linkerscript/at-self-reference.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: .bbb : AT(ADDR(.bbb)) { *(.bbb) } \
77# RUN: }" > %t.script
88# RUN: ld.lld %t --script %t.script -o %t2
9# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
9# RUN: llvm-readobj -l %t2 | FileCheck %s
1010
1111# CHECK: ProgramHeaders [
1212# CHECK-NEXT: ProgramHeader {
deps/lld/test/ELF/linkerscript/at.s+1-1
......@@ -9,7 +9,7 @@
99# RUN: .eee 0x5000 : AT(0x5000) { *(.eee) } \
1010# RUN: }" > %t.script
1111# RUN: ld.lld %t --script %t.script -o %t2
12# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
12# RUN: llvm-readobj -l %t2 | FileCheck %s
1313
1414# CHECK: ProgramHeaders [
1515# CHECK-NEXT: ProgramHeader {
deps/lld/test/ELF/linkerscript/at2.test+2-2
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/at2.s -o %t.o
33# RUN: ld.lld -o %t.exe %t.o --script %s
4# RUN: llvm-readobj -program-headers %t.exe | FileCheck %s
4# RUN: llvm-readobj -l %t.exe | FileCheck %s
55# RUN: llvm-objdump -section-headers %t.exe | FileCheck %s --check-prefix=SECTIONS
66
77MEMORY {
......@@ -48,7 +48,7 @@ SECTIONS {
4848# CHECK-NEXT: }
4949
5050# SECTIONS: Sections:
51# SECTIONS-NEXT: Idx Name Size Address
51# SECTIONS-NEXT: Idx Name Size VMA
5252# SECTIONS-NEXT: 0 00000000 0000000000000000
5353# SECTIONS-NEXT: 1 .foo1 00000008 0000000000002000
5454# SECTIONS-NEXT: 2 .foo2 00000008 0000000000002008
deps/lld/test/ELF/linkerscript/at4.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: .ccc : { *(.ccc) } \
88# RUN: }" > %t.script
99# RUN: ld.lld %t --script %t.script -o %t2
10# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
10# RUN: llvm-readobj -l %t2 | FileCheck %s
1111
1212# CHECK: Type: PT_LOAD
1313# CHECK-NEXT: Offset: 0x1000
deps/lld/test/ELF/linkerscript/comdat-gc.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/comdat-gc.s -o %t1
55# RUN: echo "SECTIONS { .text : { *(.text*) } }" > %t.script
66# RUN: ld.lld --gc-sections --script %t.script %t %t1 -o %t2
7# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=GC1 %s
7# RUN: llvm-readobj --sections --symbols %t2 | FileCheck -check-prefix=GC1 %s
88
99# GC1: Name: .debug_line
1010
deps/lld/test/ELF/linkerscript/common-assign.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; pfoo = foo; pbar = bar; }" > %t.script
44# RUN: ld.lld -o %t1 --script %t.script %t
5# RUN: llvm-readobj -symbols %t1 | FileCheck %s
5# RUN: llvm-readobj --symbols %t1 | FileCheck %s
66
77# CHECK: Symbol {
88# CHECK: Name: bar
deps/lld/test/ELF/linkerscript/common-exclude.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec2.s -o %tfile2.o
55# RUN: echo "SECTIONS { .common.incl : { *(EXCLUDE_FILE (*file2.o) COMMON) } .common.excl : { *(COMMON) } }" > %t.script
66# RUN: ld.lld -o %t1 --script %t.script %tfile0.o %tfile1.o %tfile2.o
7# RUN: llvm-readobj -s -t %t1 | FileCheck %s
7# RUN: llvm-readobj -S --symbols %t1 | FileCheck %s
88
99# Commons from file0 and file1 are not excluded, so they must be in .common.incl
1010# Commons from file2 are excluded from the first rule and should be caught by
deps/lld/test/ELF/linkerscript/common-filespec.test+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec1.s -o %tfile1.o
55# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec2.s -o %tfile2.o
66# RUN: ld.lld -o %t1 --script %s %tfile0.o %tfile1.o %tfile2.o
7# RUN: llvm-readobj -s -t %t1 | FileCheck %s
7# RUN: llvm-readobj -S --symbols %t1 | FileCheck %s
88
99SECTIONS {
1010 .common_0 : { *file0.o(COMMON) }
deps/lld/test/ELF/linkerscript/common.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .common : { *(COMMON) } }" > %t.script
44# RUN: ld.lld -o %t1 --script %t.script %t
5# RUN: llvm-readobj -s -t %t1 | FileCheck %s
5# RUN: llvm-readobj -S --symbols %t1 | FileCheck %s
66
77# CHECK: Section {
88# CHECK: Index:
deps/lld/test/ELF/linkerscript/compress-debug-sections.s+2-2
......@@ -11,12 +11,12 @@
1111# RUN: echo "SECTIONS { }" > %t.script
1212# RUN: ld.lld -O0 %t1.o %t2.o %t.script -o %t1 --compress-debug-sections=zlib
1313# RUN: llvm-dwarfdump -a %t1 | FileCheck %s
14# RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS
14# RUN: llvm-readobj -S %t1 | FileCheck %s --check-prefix=ZLIBFLAGS
1515
1616# RUN: echo "SECTIONS { .debug_str 0 : { *(.debug_str) } }" > %t2.script
1717# RUN: ld.lld -O0 %t1.o %t2.o %t2.script -o %t2 --compress-debug-sections=zlib
1818# RUN: llvm-dwarfdump -a %t2 | FileCheck %s
19# RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS
19# RUN: llvm-readobj -S %t2 | FileCheck %s --check-prefix=ZLIBFLAGS
2020
2121# CHECK: .debug_str contents:
2222# CHECK-NEXT: CCC
deps/lld/test/ELF/linkerscript/copy-rel-symbol-value.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: ld.lld %t2.o -o %t2.so -shared
55# RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; foo = bar; }" > %t.script
66# RUN: ld.lld %t.o %t2.so --script %t.script -o %t
7# RUN: llvm-readobj -t %t | FileCheck %s
7# RUN: llvm-readobj --symbols %t | FileCheck %s
88
99# CHECK: Name: bar
1010# CHECK-NEXT: Value: 0x[[VAL:.*]]
deps/lld/test/ELF/linkerscript/data-segment-relro.test+2-2
......@@ -7,10 +7,10 @@
77## page boundary.
88
99# RUN: ld.lld --hash-style=sysv -z norelro %t1.o %t2.so --script %s -o %t
10# RUN: llvm-readobj -s %t | FileCheck %s
10# RUN: llvm-readobj -S %t | FileCheck %s
1111
1212# RUN: ld.lld --hash-style=sysv -z relro %t1.o %t2.so --script %s -o %t2
13# RUN: llvm-readobj -s %t2 | FileCheck %s
13# RUN: llvm-readobj -S %t2 | FileCheck %s
1414
1515SECTIONS {
1616 . = SIZEOF_HEADERS;
deps/lld/test/ELF/linkerscript/defsym.s+2-2
......@@ -7,13 +7,13 @@
77
88## Check that linker script can override -defsym assignments.
99# RUN: ld.lld %t.o -defsym=foo=0x11 -script %t.script -o %t
10# RUN: llvm-readobj -t %t | FileCheck %s
10# RUN: llvm-readobj --symbols %t | FileCheck %s
1111# CHECK: Name: foo
1212# CHECK-NEXT: Value: 0x22
1313
1414## Check that -defsym can override linker script. Check that multiple
1515## -defsym commands for the same symbol are allowed.
1616# RUN: ld.lld %t.o -script %t.script -defsym=foo=0x11 -defsym=foo=0x33 -o %t
17# RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=REORDER
17# RUN: llvm-readobj --symbols %t | FileCheck %s --check-prefix=REORDER
1818# REORDER: Name: foo
1919# REORDER-NEXT: Value: 0x33
deps/lld/test/ELF/linkerscript/discard-interp.test+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/../Inputs/shared.s -o %t2.o
44# RUN: ld.lld -shared %t2.o -o %t2.so
55# RUN: ld.lld -dynamic-linker foo -rpath bar -rpath baz --script %s --export-dynamic %t.o %t2.so -o %t
6# RUN: llvm-readobj -s %t | FileCheck %s
6# RUN: llvm-readobj -S %t | FileCheck %s
77
88# CHECK-NOT: Name: .interp
99
deps/lld/test/ELF/linkerscript/discard-phdr.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: echo "PHDRS { \
4# RUN: exec PT_LOAD FLAGS(0x4 | 0x1); \
5# RUN: } \
6# RUN: SECTIONS { \
7# RUN: .text : { *(.text) } :exec \
8# RUN: .foo : { *(.foo) } \
9# RUN: .bar : { *(.bar) } \
10# RUN: /DISCARD/ : { *(.discard) } :NONE \
11# RUN: }" > %t.script
12# RUN: ld.lld -o %t --script %t.script %t.o
13# RUN: llvm-readelf -S -l %t | FileCheck --implicit-check-not=/DISCARD/ %s
14
15## Check that /DISCARD/ does not interfere with the assignment of segments to
16## sections.
17
18# CHECK: Section Headers
19# CHECK: .text
20# CHECK-NEXT: .foo
21# CHECK-NEXT: .bar
22
23# CHECK: Segment Sections
24# CHECK-NEXT: .text .foo .bar
25
26.section .text,"ax"
27 ret
28
29.section .foo,"a"
30 .byte 0
31
32.section .bar,"ax"
33 ret
34
35.section .discard
36 .byte 0
deps/lld/test/ELF/linkerscript/dot-is-not-abs.s+1-1
......@@ -3,7 +3,7 @@
33
44# RUN: echo "SECTIONS { .text : { *(.text) } foo = .; .bar : { *(.bar) } }" > %t1.script
55# RUN: ld.lld -o %t1 --script %t1.script %t.o -shared
6# RUN: llvm-readobj -t -s -section-data %t1 | FileCheck %s
6# RUN: llvm-readobj --symbols -S --section-data %t1 | FileCheck %s
77
88.hidden foo
99.long foo - .
deps/lld/test/ELF/linkerscript/dynamic-sym.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: echo "_DYNAMIC = 0x123;" > %t.script
44# RUN: ld.lld -T %t.script %t.o -shared -o %t.so
5# RUN: llvm-readobj -t %t.so | FileCheck %s
5# RUN: llvm-readobj --symbols %t.so | FileCheck %s
66
77# CHECK: Symbol {
88# CHECK: Name: _DYNAMIC
deps/lld/test/ELF/linkerscript/dynamic.s+1-1
......@@ -5,7 +5,7 @@
55
66# RUN: echo "SECTIONS { }" > %t.script
77# RUN: ld.lld %t1.o %t2.so -o %t
8# RUN: llvm-readobj -dynamic-table %t | FileCheck %s
8# RUN: llvm-readobj --dynamic-table %t | FileCheck %s
99
1010# CHECK: DynamicSection [
1111# CHECK-NEXT: Tag Type Name/Value
deps/lld/test/ELF/linkerscript/eh-frame-merge.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame) } }" > %t.script
4# RUN: ld.lld -o %t --no-threads --eh-frame-hdr --script %t.script %t.o
5# RUN: llvm-readobj -S -u %t | FileCheck %s
6
7# CHECK: Name: .dah
8# CHECK-NOT: Section
9# CHECK: Address: 0x4D
10
11# CHECK: initial_location: 0x4d
12
13.global _start
14_start:
15 nop
16
17.section .dah,"ax",@progbits
18.cfi_startproc
19 nop
20.cfi_endproc
deps/lld/test/ELF/linkerscript/ehdr_start.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
44# RUN: echo "SECTIONS { }" > %t.script
55# RUN: ld.lld %t.o -script %t.script -o %t
6# RUN: llvm-readobj -symbols %t | FileCheck %s
6# RUN: llvm-readobj --symbols %t | FileCheck %s
77# CHECK: Name: __ehdr_start (1)
88# CHECK-NEXT: Value: 0x0
99# CHECK-NEXT: Size: 0
deps/lld/test/ELF/linkerscript/emit-reloc.s+2-2
......@@ -9,9 +9,9 @@
99
1010# CHECK: Relocations [
1111# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
12# CHECK-NEXT: 0x68 R_X86_64_64 .foo 0x0
12# CHECK-NEXT: 0xF8 R_X86_64_64 .foo 0x0
1313# CHECK-NEXT: }
1414# CHECK-NEXT: Section ({{.*}}) .rela.data {
15# CHECK-NEXT: 0x68 R_X86_64_64 .foo 0x0
15# CHECK-NEXT: 0xF8 R_X86_64_64 .foo 0x0
1616# CHECK-NEXT: }
1717# CHECK-NEXT: ]
deps/lld/test/ELF/linkerscript/empty-link-order.test+1-1
......@@ -11,7 +11,7 @@ SECTIONS {
1111# RUN: ld.lld %t.o -o %t --script %s
1212
1313## Check we do not crash and do not set SHF_LINK_ORDER flag for .foo
14# RUN: llvm-readobj -s %t | FileCheck %s
14# RUN: llvm-readobj -S %t | FileCheck %s
1515# CHECK: Section {
1616# CHECK: Index:
1717# CHECK: Name: .foo
deps/lld/test/ELF/linkerscript/empty-relaplt-dyntags.test created+44
......@@ -0,0 +1,44 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o
3# RUN: ld.lld -shared %t.o -T %s -o %t
4# RUN: llvm-readobj --dynamic-table --sections %t | FileCheck %s
5
6## In spite of .rela.plt is empty, it might have been preserved because it is
7## mentioned in the linker script. However, even in that case, we should not
8## produce DT_JMPREL and DT_PLTGOT tags because this can cause a dynamic loader
9## to write into slots in .got.plt it considers reserved to support lazy symbol
10## resolution. In fact, as .got.plt is also empty, that memory might be
11## allocated for something else.
12
13# CHECK: Sections [
14# CHECK: Name: .rela.plt
15# CHECK-NEXT: Type: SHT_RELA
16# CHECK-NEXT: Flags [
17# CHECK-NEXT: SHF_ALLOC
18# CHECK-NEXT: ]
19# CHECK-NEXT: Address:
20# CHECK-NEXT: Offset:
21# CHECK-NEXT: Size: 0
22# CHECK: Name: .got.plt
23# CHECK-NEXT: Type: SHT_PROGBITS
24# CHECK-NEXT: Flags [
25# CHECK-NEXT: SHF_ALLOC
26# CHECK-NEXT: SHF_WRITE
27# CHECK-NEXT: ]
28# CHECK-NEXT: Address:
29# CHECK-NEXT: Offset:
30# CHECK-NEXT: Size: 0
31
32# CHECK: DynamicSection [
33# CHECK-NOT: JMPREL
34# CHECK-NOT: PLTGOT
35
36PHDRS {
37 all PT_LOAD;
38 dyn PT_DYNAMIC;
39}
40SECTIONS {
41 .rela.plt : { *(.rela.plt) }: all
42 .dynamic : { *(.dynamic) }: all : dyn
43 .got.plt : {*(.got.plt)}: all
44}
deps/lld/test/ELF/linkerscript/empty-section-size.test+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o
33# RUN: ld.lld %t.o --script %s -o %t1
4# RUN: llvm-readobj -symbols %t1 | FileCheck %s
4# RUN: llvm-readobj --symbols %t1 | FileCheck %s
55
66## We had a bug when LLD increased the size of the output section even
77## if it was empty. That happened because of empty synthetic sections included.
deps/lld/test/ELF/linkerscript/empty-sections-expressions.test created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: x86
2# RUN: echo ".text; nop; .data; .byte 0" \
3# RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o
4# RUN: ld.lld -o %t --script %s %t.o
5# RUN: llvm-readelf -program-headers %t | FileCheck %s
6
7## Check we do not remove the empty output sections used in LOADADDR/ADDR
8## expressions and hence can evaluate the correct addresses.
9
10# CHECK: Program Headers:
11# CHECK-NEXT: Type Offset VirtAddr PhysAddr
12# CHECK-NEXT: LOAD 0x001000 0x0000000000080000 0x0000000000080000
13# CHECK-NEXT: LOAD 0x001001 0x0000000000080001 0x0000000000082000
14
15# CHECK: Section to Segment mapping:
16# CHECK: 00 .empty .text
17# CHECK-NEXT: 01 .data
18
19SECTIONS {
20 . = 0x00080000;
21 .empty : { *(.empty ) }
22 .text : AT(LOADADDR(.empty) + SIZEOF(.empty)) { *(.text) }
23 .data : AT(ADDR(.empty) + 0x2000) { *(.data) }
24}
deps/lld/test/ELF/linkerscript/empty-synthetic-removed-flags.s+2-2
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: echo "SECTIONS { .foo : { *(.foo) } .bar : { *(.got.plt) BYTE(0x11) }}" > %t.script
44# RUN: ld.lld -o %t --script %t.script %t.o
5# RUN: llvm-readobj -s %t | FileCheck %s
5# RUN: llvm-readobj -S %t | FileCheck %s
66
77## We have ".got.plt" synthetic section with SHF_ALLOC|SHF_WRITE flags.
88## It is empty, so linker removes it, but it has to keep ".got.plt" output
......@@ -21,7 +21,7 @@
2121## Check flags are not the same if we omit empty synthetic section in script.
2222# RUN: echo "SECTIONS { .foo : { *(.foo) } .bar : { BYTE(0x11) }}" > %t.script
2323# RUN: ld.lld -o %t --script %t.script %t.o
24# RUN: llvm-readobj -s %t | FileCheck --check-prefix=EMPTY %s
24# RUN: llvm-readobj -S %t | FileCheck --check-prefix=EMPTY %s
2525
2626# EMPTY: Section {
2727# EMPTY: Index: 2
deps/lld/test/ELF/linkerscript/entry.s+2-2
......@@ -14,7 +14,7 @@
1414# -e has precedence over linker script's ENTRY.
1515# RUN: echo "ENTRY(_label)" > %t.script
1616# RUN: ld.lld -e _start -o %t2 %t.script %t
17# RUN: llvm-readobj -file-headers -symbols %t2 | \
17# RUN: llvm-readobj --file-headers --symbols %t2 | \
1818# RUN: FileCheck -check-prefix=OVERLOAD %s
1919
2020# OVERLOAD: Entry: [[ENTRY:0x[0-9A-F]+]]
......@@ -24,7 +24,7 @@
2424# The entry symbol can be a linker-script-defined symbol.
2525# RUN: echo "ENTRY(foo); foo = 1;" > %t.script
2626# RUN: ld.lld -o %t2 %t.script %t
27# RUN: llvm-readobj -file-headers -symbols %t2 | \
27# RUN: llvm-readobj --file-headers --symbols %t2 | \
2828# RUN: FileCheck -check-prefix=SCRIPT %s
2929
3030# SCRIPT: Entry: 0x1
deps/lld/test/ELF/linkerscript/excludefile.s+3
......@@ -10,6 +10,7 @@
1010# RUN: llvm-objdump -d %t | FileCheck %s
1111
1212# CHECK: Disassembly of section .text:
13# CHECK-EMPTY:
1314# CHECK: _start:
1415# CHECK-NEXT: : 48 c7 c0 3c 00 00 00 movq $60, %rax
1516# CHECK-NEXT: : 48 c7 c7 2a 00 00 00 movq $42, %rdi
......@@ -30,6 +31,7 @@
3031# RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=EXCLUDE
3132
3233# EXCLUDE: Disassembly of section .patatino:
34# EXCLUDE-EMPTY:
3335# EXCLUDE: _start:
3436# EXCLUDE-NEXT: : 48 c7 c0 3c 00 00 00 movq $60, %rax
3537# EXCLUDE-NEXT: : 48 c7 c7 2a 00 00 00 movq $42, %rdi
......@@ -39,6 +41,7 @@
3941# EXCLUDE-NEXT: : 90 nop
4042# EXCLUDE-NEXT: : 90 nop
4143# EXCLUDE: Disassembly of section .text:
44# EXCLUDE-EMPTY:
4245# EXCLUDE: tomato:
4346# EXCLUDE-NEXT: : b8 01 00 00 00 movl $1, %eax
4447
deps/lld/test/ELF/linkerscript/extend-pt-load1.test+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o
33# RUN: ld.lld --hash-style=sysv -o %t1 --script %s %t.o -shared
4# RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck %s
4# RUN: llvm-readelf -S -l %t1 | FileCheck %s
55
66# This test demonstrates an odd consequence of the way we handle sections with just symbol
77# assignments.
deps/lld/test/ELF/linkerscript/extend-pt-load2.test+3-3
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o
33# RUN: ld.lld --hash-style=sysv -o %t2 --script %s %t.o -shared
4# RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck %s
4# RUN: llvm-readelf -S -l %t2 | FileCheck %s
55
66# Then add the section bar. Note how bar is given AX flags, which causes the PT_LOAD to now
77# cover the padding bits created by ALIGN.
......@@ -17,8 +17,8 @@ SECTIONS {
1717}
1818
1919# CHECK: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX
20# CHECK-NEXT: bar NOBITS 00000000000001bd 0001bd 000e43 00 AX
20# CHECK-NEXT: bar PROGBITS 00000000000001bd 0001bd 000e43 00 AX
2121# CHECK-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA
2222
23# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x001000 R E
23# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001000 0x001000 R E
2424# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW
deps/lld/test/ELF/linkerscript/extend-pt-load3.test+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o
33# RUN: ld.lld --hash-style=sysv -o %t3 --script %s %t.o -shared
4# RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck --check-prefix=CHECK %s
4# RUN: llvm-readelf -S -l %t3 | FileCheck --check-prefix=CHECK %s
55
66# If the current behavior becomes a problem we should consider just moving the commands out
77# of the section. That is, handle the above like the following test.
deps/lld/test/ELF/linkerscript/fill.test+6-1
......@@ -7,14 +7,19 @@ SECTIONS {
77 .out : {
88 FILL(0x11111111)
99 . += 2;
10 FILL(0x10101010)
1011 *(.aaa)
1112 . += 4;
1213 *(.bbb)
1314 . += 4;
14 FILL(0x22222222);
15 FILL(0x22220000 + 0x2222);
1516 . += 4;
1617 }
1718}
1819
1920# CHECK: Contents of section .out:
2021# CHECK-NEXT: 2222aa22 222222bb 22222222 22222222
22
23# RUN: echo 'SECTIONS { .out : { FILL 0x11111111 } }' > %t.script
24# RUN: not ld.lld -o /dev/null --script %t.script 2>&1 | FileCheck %s --check-prefix=ERR
25# ERR: ( expected, but got 0x11111111
deps/lld/test/ELF/linkerscript/header-addr.test+2-2
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o
33# RUN: ld.lld --hash-style=sysv -o %t.so --script %s %t.o -shared
4# RUN: llvm-readobj -program-headers %t.so | FileCheck %s
4# RUN: llvm-readobj -l %t.so | FileCheck %s
55
66PHDRS { all PT_LOAD PHDRS; }
77
......@@ -28,7 +28,7 @@ SECTIONS {
2828# CHECK-NEXT: ]
2929
3030# RUN: ld.lld --hash-style=sysv -o %t2.so --script %s %t.o -shared -z max-page-size=0x2000
31# RUN: llvm-readobj -program-headers %t2.so \
31# RUN: llvm-readobj -l %t2.so \
3232# RUN: | FileCheck --check-prefix=MAXPAGE %s
3333
3434# MAXPAGE: ProgramHeaders [
deps/lld/test/ELF/linkerscript/header-phdr.test+1-1
......@@ -2,7 +2,7 @@
22# RUN: echo '.section .zed, "a"; .zero 4' \
33# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o
44# RUN: ld.lld --script %s %t.o -o %t
5# RUN: llvm-readelf -l -S -W %t | FileCheck %s
5# RUN: llvm-readelf -S -l -W %t | FileCheck %s
66
77# CHECK: [ 1] .abc PROGBITS 0000000000001000 001000 000004 00 A 0 0 1
88# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001004 0x001004 R E 0x1000
deps/lld/test/ELF/linkerscript/info-section-type.s+9-5
......@@ -6,7 +6,7 @@
66
77# RUN: echo "SECTIONS { .bar : { *(.foo) } };" > %t.script
88# RUN: ld.lld -o %t --script %t.script %t.o
9# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=DEFAULT
9# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=DEFAULT
1010# DEFAULT: Name: .bar
1111# DEFAULT: Type: SHT_PROGBITS
1212# DEFAULT-NEXT: Flags [
......@@ -15,7 +15,7 @@
1515
1616# RUN: echo "SECTIONS { .bar (COPY) : { *(.foo) } };" > %t.script
1717# RUN: ld.lld -o %t --script %t.script %t.o
18# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
18# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=NONALLOC
1919# NONALLOC: Name: .bar
2020# NONALLOC: Type: SHT_PROGBITS
2121# NONALLOC-NEXT: Flags [
......@@ -23,15 +23,19 @@
2323
2424# RUN: echo "SECTIONS { .bar (INFO) : { *(.foo) } };" > %t.script
2525# RUN: ld.lld -o %t --script %t.script %t.o
26# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
26# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=NONALLOC
2727
2828# RUN: echo "SECTIONS { .bar (OVERLAY) : { *(.foo) } };" > %t.script
2929# RUN: ld.lld -o %t --script %t.script %t.o
30# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
30# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=NONALLOC
31
32# RUN: echo "SECTIONS { .bar (INFO) : { . += 1; } };" > %t.script
33# RUN: ld.lld -o %t --script %t.script %t.o
34# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=NONALLOC
3135
3236# RUN: echo "SECTIONS { .bar 0x20000 (INFO) : { *(.foo) } };" > %t.script
3337# RUN: ld.lld -o %t --script %t.script %t.o
34# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC
38# RUN: llvm-readobj --sections %t | FileCheck %s --check-prefix=NONALLOC
3539
3640# RUN: echo "SECTIONS { .bar 0x20000 (BAR) : { *(.foo) } };" > %t.script
3741# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 |\
deps/lld/test/ELF/linkerscript/insert-after.test+1-1
......@@ -16,7 +16,7 @@ SECTIONS {
1616# RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
1717# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
1818# CHECK: Sections:
19# CHECK-NEXT: Idx Name Size Address Type
19# CHECK-NEXT: Idx Name Size VMA Type
2020# CHECK-NEXT: 0 00000000 0000000000000000
2121# CHECK-NEXT: 1 .text 00000008 0000000000000000 TEXT
2222# CHECK-NEXT: 2 .foo.text 00000008 0000000000000008 TEXT
deps/lld/test/ELF/linkerscript/insert-before.test+1-1
......@@ -16,7 +16,7 @@ SECTIONS {
1616# RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
1717# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
1818# CHECK: Sections:
19# CHECK-NEXT: Idx Name Size Address Type
19# CHECK-NEXT: Idx Name Size VMA Type
2020# CHECK-NEXT: 0 00000000 0000000000000000
2121# CHECK-NEXT: 1 .foo.text 00000008 0000000000000000 TEXT
2222# CHECK-NEXT: 2 .text 00000008 0000000000000008 TEXT
deps/lld/test/ELF/linkerscript/lazy-symbols.test+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-ar rcs %tar %t1
55# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t2
66# RUN: ld.lld %t2 %tar --script %s -o %tout
7# RUN: llvm-readobj -symbols %tout | FileCheck %s
7# RUN: llvm-readobj --symbols %tout | FileCheck %s
88
99foo = 1;
1010
deps/lld/test/ELF/linkerscript/linkerscript.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
44# RUN: %p/Inputs/libsearch-st.s -o %t2.o
55
6# RUN: echo "EXTERN( undef undef2 )" > %t.script
6# RUN: echo "EXTERN( undef undef2 \"undef3\" \"undef4@@other\")" > %t.script
77# RUN: ld.lld %t -o %t2 %t.script
88# RUN: llvm-readobj %t2 > /dev/null
99
deps/lld/test/ELF/linkerscript/locationcountererr2.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: echo ". = 0x150; . = 0x10; .text : {} }" >> %t.script
55# RUN: ld.lld %t.o --script %t.script -o %t -shared
66# RUN: llvm-objdump -section-headers %t | FileCheck %s
7# CHECK: Name Size Address
7# CHECK: Name Size VMA
88# CHECK: .text 00000000 0000000000000010
99
1010# RUN: echo "SECTIONS { . = 0x20; . = ASSERT(0x1, "foo"); }" > %t2.script
deps/lld/test/ELF/linkerscript/memory-at.test+1-1
......@@ -3,7 +3,7 @@
33# RUN: echo '.section .data,"aw"; .quad 0' >> %t.s
44# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t
55# RUN: ld.lld %t --script %s -o %t2
6# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
6# RUN: llvm-readobj -l %t2 | FileCheck %s
77
88MEMORY {
99 FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0x100
deps/lld/test/ELF/linkerscript/memory-region-alignment.test+1-1
......@@ -17,7 +17,7 @@ SECTIONS {
1717}
1818
1919# RUN: ld.lld %t.o -o %t --script %s
20# RUN: llvm-readobj -sections %t | FileCheck %s
20# RUN: llvm-readobj --sections %t | FileCheck %s
2121
2222# CHECK: Name: .foo
2323# CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/linkerscript/memory3.s+1-1
......@@ -14,7 +14,7 @@
1414
1515## Check we place .text into first defined memory region with appropriate flags.
1616# CHECK: Sections:
17# CHECK: Idx Name Size Address
17# CHECK: Idx Name Size VMA
1818# CHECK: 0 00000000 0000000000000000
1919# CHECK: 1 .text 00000001 0000000000001000
2020
deps/lld/test/ELF/linkerscript/memory5.test+2-2
......@@ -5,9 +5,9 @@
55# RUN: llvm-objdump -section-headers %t.so | FileCheck %s
66
77# CHECK: 1 .text 00000001 0000000000042000
8# CHECK-NEXT: 2 .data 00000001 0000000000044001
8# CHECK-NEXT: 2 .data 00000001 0000000000042001
99
10## Test that assign to Dot changes the position in a memory region.
10## Test that assigning to Dot does not change the position in a memory region.
1111
1212MEMORY {
1313 ram (wxa) : ORIGIN = 0x42000, LENGTH = 0x100000
deps/lld/test/ELF/linkerscript/merge-sections.s+3-3
......@@ -6,7 +6,7 @@
66# RUN: .foo : { begin = .; *(.foo.*) end = .;} \
77# RUN: }" > %t.script
88# RUN: ld.lld -o %t1 --script %t.script %t -shared
9# RUN: llvm-readobj -s -t %t1 | FileCheck %s
9# RUN: llvm-readobj -S --symbols %t1 | FileCheck %s
1010
1111# CHECK: Name: .foo
1212# CHECK-NEXT: Type: SHT_PROGBITS
......@@ -32,10 +32,10 @@
3232
3333# Check that we don't crash with --gc-sections
3434# RUN: ld.lld --gc-sections -o %t2 --script %t.script %t -shared
35# RUN: llvm-readobj -s -t %t2 | FileCheck %s --check-prefix=GC
35# RUN: llvm-readobj -S --symbols %t2 | FileCheck %s --check-prefix=GC
3636
3737# GC: Name: .foo
38# GC-NEXT: Type: SHT_NOBITS
38# GC-NEXT: Type: SHT_PROGBITS
3939# GC-NEXT: Flags [
4040# GC-NEXT: SHF_ALLOC
4141# GC-NEXT: ]
deps/lld/test/ELF/linkerscript/multi-sections-constraint.s+2-2
......@@ -8,7 +8,7 @@
88# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
99
1010# CHECK: Sections:
11# CHECK-NEXT: Idx Name Size Address Type
11# CHECK-NEXT: Idx Name Size VMA Type
1212# CHECK: .aaa 00000010 0000000000002000 DATA
1313
1414
......@@ -20,7 +20,7 @@
2020# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=REV
2121
2222# REV: Sections:
23# REV-NEXT: Idx Name Size Address Type
23# REV-NEXT: Idx Name Size VMA Type
2424# REV: .aaa 00000010 0000000000001000 DATA
2525
2626.global _start
deps/lld/test/ELF/linkerscript/multiple-tbss.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: echo "SECTIONS { }" > %t.script
44# RUN: ld.lld -T %t.script %t.o -o %t
5# RUN: llvm-readobj -l -s %t | FileCheck %s
5# RUN: llvm-readobj -S -l %t | FileCheck %s
66
77# CHECK: Name: .tbss
88# CHECK-NEXT: Type: SHT_NOBITS
deps/lld/test/ELF/linkerscript/nmagic-alignment.test created+85
......@@ -0,0 +1,85 @@
1# REQUIRES: x86
2
3# Test that mimics a use case of -n to produce a kernel mapped shared-object
4# in a non paged context. We specifically want to test:
5# - We can allocate the headers into the first program header (via PHDRS)
6# typically -n does not allocate headers.
7# - The alignment of the .text section is not page aligned.
8
9# RUN: echo ".text; .globl foo; foo: nop" > %t.s
10# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t.o
11# RUN: ld.lld %t.o -o %t.so --shared --hash-style=sysv --script %s
12# RUN: llvm-readobj --program-headers %t.so | FileCheck %s
13# RUN: ld.lld %t.o -o %t2.so --shared --hash-style=sysv -n --script %s
14# RUN: llvm-readobj --program-headers %t2.so | FileCheck %s --check-prefix=CHECK-N
15
16SECTIONS {
17 . = 0x0 + SIZEOF_HEADERS;
18 .hash : { *(.hash) } :text
19 .dynsym : { *(.dynsym) }
20 .dynstr : { *(.dynstr) }
21 . = ALIGN(4);
22 .text : { *(.text*) }
23 .dynamic : { *(.dynamic) } :text :dynamic
24}
25
26PHDRS {
27 text PT_LOAD FLAGS(5) FILEHDR PHDRS;
28 dynamic PT_DYNAMIC FLAGS(4);
29}
30
31# CHECK: ProgramHeaders [
32# CHECK-NEXT: ProgramHeader {
33# CHECK-NEXT: Type: PT_LOAD
34# CHECK-NEXT: Offset: 0x0
35# CHECK-NEXT: VirtualAddress: 0x0
36# CHECK-NEXT: PhysicalAddress: 0x0
37# CHECK-NEXT: FileSize:
38# CHECK-NEXT: MemSize:
39# CHECK-NEXT: Flags [
40# CHECK-NEXT: PF_R
41# CHECK-NEXT: PF_X
42# CHECK-NEXT: ]
43# CHECK-NEXT: Alignment: 4096
44# CHECK-NEXT: }
45# CHECK-NEXT: ProgramHeader {
46# CHECK-NEXT: Type: PT_DYNAMIC
47# CHECK-NEXT: Offset: 0x108
48# CHECK-NEXT: VirtualAddress: 0x108
49# CHECK-NEXT: PhysicalAddress: 0x108
50# CHECK-NEXT: FileSize:
51# CHECK-NEXT: MemSize:
52# CHECK-NEXT: Flags [
53# CHECK-NEXT: PF_R
54# CHECK-NEXT: ]
55# CHECK-NEXT: Alignment: 8
56# CHECK-NEXT: }
57# CHECK-NEXT: ]
58
59# CHECK-N: ProgramHeaders [
60# CHECK-N-NEXT: ProgramHeader {
61# CHECK-N-NEXT: Type: PT_LOAD
62# CHECK-N-NEXT: Offset: 0x0
63# CHECK-N-NEXT: VirtualAddress: 0x0
64# CHECK-N-NEXT: PhysicalAddress: 0x0
65# CHECK-N-NEXT: FileSize: 360
66# CHECK-N-NEXT: MemSize: 360
67# CHECK-N-NEXT: Flags [
68# CHECK-N-NEXT: PF_R
69# CHECK-N-NEXT: PF_X
70# CHECK-N-NEXT: ]
71# CHECK-N-NEXT: Alignment: 8
72# CHECK-N-NEXT: }
73# CHECK-N-NEXT: ProgramHeader {
74# CHECK-N-NEXT: Type: PT_DYNAMIC
75# CHECK-N-NEXT: Offset: 0x108
76# CHECK-N-NEXT: VirtualAddress: 0x108
77# CHECK-N-NEXT: PhysicalAddress: 0x108
78# CHECK-N-NEXT: FileSize:
79# CHECK-N-NEXT: MemSize:
80# CHECK-N-NEXT: Flags [
81# CHECK-N-NEXT: PF_R
82# CHECK-N-NEXT: ]
83# CHECK-N-NEXT: Alignment: 8
84# CHECK-N-NEXT: }
85# CHECK-N-NEXT: ]
deps/lld/test/ELF/linkerscript/noload.s+1-1
......@@ -5,7 +5,7 @@
55# RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } \
66# RUN: .text (0x20000) : { *(.text) } };" > %t.script
77# RUN: ld.lld -o %t --script %t.script %t.o
8# RUN: llvm-readobj -sections -program-headers %t | FileCheck %s
8# RUN: llvm-readobj --sections -l %t | FileCheck %s
99
1010# CHECK: Section {
1111# CHECK: Index: 1
deps/lld/test/ELF/linkerscript/non-absolute.s+2-1
......@@ -3,11 +3,12 @@
33# RUN: echo "SECTIONS { A = . - 0x10; B = A + 0x1; }" > %t.script
44# RUN: ld.lld -shared %t1.o --script %t.script -o %t
55# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DUMP
6# RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SYMBOL
6# RUN: llvm-readobj --symbols %t | FileCheck %s --check-prefix=SYMBOL
77
88# B = A + 0x1 = -0x10 + 0x1 = -0xf -> 0xFFFFFFFFFFFFFFF1
99# B - (0x94+6) = -0xf - (0x94+6) = -169
1010# DUMP: Disassembly of section .text:
11# DUMP-EMPTY:
1112# DUMP-NEXT: foo:
1213# DUMP-NEXT: 94: {{.*}} -169(%rip), %eax
1314
deps/lld/test/ELF/linkerscript/non-absolute2.test+1-1
......@@ -9,7 +9,7 @@ SECTIONS {
99}
1010
1111# CHECK: Sections:
12# CHECK-NEXT: Idx Name Size Address
12# CHECK-NEXT: Idx Name Size VMA
1313# CHECK-NEXT: 0 00000000 0000000000000000
1414# CHECK-NEXT: 1 .dynsym 00000030 0000000000001000
1515# CHECK: 5 .text 00000000 000000000000106c
deps/lld/test/ELF/linkerscript/numbers.s+2-2
......@@ -18,7 +18,7 @@
1818# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
1919
2020# CHECK: Sections:
21# CHECK-NEXT: Idx Name Size Address
21# CHECK-NEXT: Idx Name Size VMA
2222# CHECK-NEXT: 0 00000000 0000000000000000
2323# CHECK-NEXT: 1 .hex1 00000008 0000000000001000
2424# CHECK-NEXT: 2 .hex2 00000008 0000000000001010
......@@ -67,7 +67,7 @@
6767# RUN: ld.lld %t --script %t8.script -o %t6
6868# RUN: llvm-objdump -section-headers %t6 | FileCheck -check-prefix=SECADDR %s
6969# SECADDR: Sections:
70# SECADDR-NEXT: Idx Name Size Address
70# SECADDR-NEXT: Idx Name Size VMA
7171# SECADDR-NEXT: 0 00000000 0000000000000000
7272# SECADDR-NEXT: 1 .hex1 00000008 0000000000000400
7373# SECADDR-NEXT: 2 .hex2 00000008 0000000000000500
deps/lld/test/ELF/linkerscript/obj-symbol-value.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: echo "SECTIONS { foo = bar; .bar : { *(.bar*) } }" > %t.script
44# RUN: ld.lld %t.o --script %t.script -o %t.so -shared
5# RUN: llvm-readobj -t %t.so | FileCheck %s
5# RUN: llvm-readobj --symbols %t.so | FileCheck %s
66
77# CHECK: Symbol {
88# CHECK: Name: bar
deps/lld/test/ELF/linkerscript/openbsd-bootdata.test+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux /dev/null -o %t.o
33# RUN: ld.lld --script %s %t.o -o %t
4# RUN: llvm-readobj --program-headers -s %t | FileCheck %s
4# RUN: llvm-readobj --program-headers -S %t | FileCheck %s
55
66PHDRS { boot PT_OPENBSD_BOOTDATA; }
77
deps/lld/test/ELF/linkerscript/openbsd-randomize.s+1-1
......@@ -5,7 +5,7 @@
55# RUN: .text : { *(.text) } \
66# RUN: .openbsd.randomdata : { *(.openbsd.randomdata) } : rand }" > %t.script
77# RUN: ld.lld --script %t.script %t.o -o %t
8# RUN: llvm-readobj --program-headers -s %t | FileCheck %s
8# RUN: llvm-readobj --program-headers -S %t | FileCheck %s
99
1010# CHECK: ProgramHeader {
1111# CHECK: Type: PT_OPENBSD_RANDOMIZE (0x65A3DBE6)
deps/lld/test/ELF/linkerscript/orphan-first-cmd.test+1-1
......@@ -2,7 +2,7 @@
22# RUN: echo '.section .bar, "aw"' \
33# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o
44# RUN: ld.lld -o %t -T %s %t.o -shared
5# RUN: llvm-readobj -s %t | FileCheck %s
5# RUN: llvm-readobj -S %t | FileCheck %s
66
77SECTIONS {
88 foo = 123;
deps/lld/test/ELF/linkerscript/orphan-live-only.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: echo "PHDRS { \
4# RUN: exec PT_LOAD FLAGS(0x4 | 0x1); \
5# RUN: ro PT_LOAD FLAGS(0x4); \
6# RUN: } \
7# RUN: SECTIONS { \
8# RUN: .pad : { QUAD(0); } :exec \
9# RUN: .text : { *(.text) } \
10# RUN: .ro : { *(.ro) } :ro \
11# RUN: }" > %t.script
12# RUN: ld.lld -o %t --script %t.script %t.o
13# RUN: llvm-readelf -S -l %t | FileCheck %s
14
15## The ".pad" section is not "live" and should be ignored by the
16## orphan placement.
17##
18## Check that the orphan section is placed correctly and belongs to
19## the correct segment.
20
21# CHECK: Section Headers
22# CHECK: .pad
23# CHECK-NEXT: .text
24# CHECK-NEXT: .orphan2
25# CHECK-NEXT: .ro
26# CHECK-NEXT: .orphan1
27
28# CHECK: Segment Sections
29# CHECK-NEXT: .pad .text .orphan2
30# CHECK-NEXT: .ro .orphan1
31
32.section .text,"ax"
33 ret
34
35.section .ro,"a"
36 .byte 0
37
38.section .orphan1,"a"
39 .byte 0
40
41.section .orphan2,"ax"
42 ret
deps/lld/test/ELF/linkerscript/orphan-phdrs.s+4-4
......@@ -23,13 +23,13 @@
2323
2424# CHECK: Segment Sections
2525# CHECK-NEXT: .text .orphan
26# CHECK-NEXT: .rw
26# CHECK-NEXT: .empty .rw
2727
28.section .text, "ax"
28.section .text,"ax"
2929 ret
3030
31.section .rw, "aw"
31.section .rw,"aw"
3232 .quad 0
3333
34.section .orphan, "ax"
34.section .orphan,"ax"
3535 ret
deps/lld/test/ELF/linkerscript/orphan-report.s+2-2
......@@ -27,6 +27,7 @@
2727# REPORT-NEXT: <internal>:(.dynamic) is being placed in '.dynamic'
2828# REPORT-NEXT: <internal>:(.dynstr) is being placed in '.dynstr'
2929# REPORT-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn'
30# REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame'
3031# REPORT-NEXT: <internal>:(.got) is being placed in '.got'
3132# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt'
3233# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt'
......@@ -34,9 +35,8 @@
3435# REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt'
3536# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt'
3637# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt'
37# REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame'
3838# REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab'
39# REPORT-NEXT: <internal>:(.symtab_shndxr) is being placed in '.symtab_shndxr'
39# REPORT-NEXT: <internal>:(.symtab_shndx) is being placed in '.symtab_shndx'
4040# REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab'
4141# REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab'
4242
deps/lld/test/ELF/linkerscript/orphan.s+5-5
......@@ -9,15 +9,15 @@
99# RUN: ld.lld -o %t1 --script %t.script %t
1010# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
1111
12## .jcr is a relro section and should be placed after other RW sections.
12## .jcr is a relro section and should be placed before other RW sections.
1313## .bss is SHT_NOBITS section and should be last RW section, so some space
1414## in ELF file could be saved.
1515# CHECK: 0 00000000 0000000000000000
1616# CHECK-NEXT: 1 .text 00000000 0000000000000000 TEXT
17# CHECK-NEXT: 2 .rw1 00000008 0000000000000000 DATA
18# CHECK-NEXT: 3 .rw2 00000008 0000000000000008 DATA
19# CHECK-NEXT: 4 .rw3 00000008 0000000000000010 DATA
20# CHECK-NEXT: 5 .jcr 00000008 0000000000000018 DATA
17# CHECK-NEXT: 2 .jcr 00000008 0000000000000000 DATA
18# CHECK-NEXT: 3 .rw1 00000008 0000000000000008 DATA
19# CHECK-NEXT: 4 .rw2 00000008 0000000000000010 DATA
20# CHECK-NEXT: 5 .rw3 00000008 0000000000000018 DATA
2121# CHECK-NEXT: 6 .bss 00000008 0000000000000020 BSS
2222
2323.section .rw1, "aw"
deps/lld/test/ELF/linkerscript/out-of-order-section-in-region.test created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2
3# RUN: echo ".section .aaa, \"a\"; .quad 0; .section .bbb, \"a\"; .quad 0;" \
4# RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t
5# RUN: ld.lld %t --script %s -o %t2
6
7# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
8# CHECK: .aaa 00000008 0000000000001008 DATA
9# CHECK: .bbb 00000008 0000000000001000 DATA
10
11MEMORY {
12 REGION (rwx) : ORIGIN = 0x1000, LENGTH = 0x100
13}
14
15SECTIONS {
16 .aaa ORIGIN(REGION) + 0x8 : { *(.aaa) } > REGION
17 _stext = .;
18 .bbb ORIGIN(REGION) : { *(.bbb) } > REGION
19 . = _stext;
20}
deps/lld/test/ELF/linkerscript/out-of-order.s+3-3
......@@ -22,10 +22,10 @@
2222# must take responsibility to make sure this does not happen.
2323
2424# CHECK: Sections:
25# CHECK-NEXT: Idx Name Size Address Type
25# CHECK-NEXT: Idx Name Size VMA Type
2626# CHECK-NEXT: 0 00000000 0000000000000000
27# CHECK-NEXT: 1 .data 00000008 0000000000004000
28# CHECK-NEXT: 2 .dynamic 00000060 0000000000004008
27# CHECK-NEXT: 1 .dynamic 00000060 0000000000000000
28# CHECK-NEXT: 2 .data 00000008 0000000000004000
2929# CHECK-NEXT: 3 .dynsym 00000018 0000000000002000
3030# CHECK-NEXT: 4 .dynstr 00000001 0000000000002018
3131# CHECK-NEXT: 5 .hash 00000010 000000000000201c
deps/lld/test/ELF/linkerscript/output-too-large-32bit.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86 && !llvm-64-bits
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: echo "SECTIONS { .text : { . = 0x6fffffffffffffff; *(.text*); } }" > %t.script
5# RUN: not ld.lld --no-check-sections --script %t.script %t.o -o /dev/null 2>&1 | FileCheck %s
6
7# CHECK: output file too large
8
9.global _start
10_start:
11 nop
deps/lld/test/ELF/linkerscript/outsections-addr.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: .ddd 0x5001 : { *(.ddd) } \
88# RUN: }" > %t.script
99# RUN: ld.lld %t --script %t.script -o %tout
10# RUN: llvm-readobj -s %tout | FileCheck %s
10# RUN: llvm-readobj -S %tout | FileCheck %s
1111
1212## Check:
1313## 1) Simple constant as address.
deps/lld/test/ELF/linkerscript/overlapping-sections.s+11-11
......@@ -17,18 +17,18 @@
1717
1818# Verify that the .sec2 was indeed placed in a PT_LOAD where the PhysAddr
1919# overlaps with where .sec1 is loaded:
20# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-LMA
20# RUN: llvm-readelf --sections -l %t.so | FileCheck %s -check-prefix BAD-LMA
2121# BAD-LMA-LABEL: Section Headers:
2222# BAD-LMA: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1
2323# BAD-LMA: .sec2 PROGBITS 0000000000008800 002800 000100 00 WA 0 0 1
2424# BAD-LMA-LABEL: Program Headers:
2525# BAD-LMA-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
2626# BAD-LMA-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000
27# BAD-LMA-NEXT: LOAD 0x001100 0x0000000000000100 0x0000000000000100 0x000070 0x000070 RW 0x1000
2728# BAD-LMA-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW 0x1000
28# BAD-LMA-NEXT: LOAD 0x002800 0x0000000000008800 0x0000000000008080 0x000170 0x000170 RW 0x1000
2929# BAD-LMA-LABEL: Section to Segment mapping:
30# BAD-LMA: 01 .sec1
31# BAD-LMA: 02 .sec2 .dynamic
30# BAD-LMA: 01 .text .dynamic
31# BAD-LMA: 02 .sec1
3232
3333# Now try a script where the virtual memory addresses overlap but ensure that the
3434# load addresses don't:
......@@ -43,18 +43,18 @@
4343
4444# Check that the expected binary was created with --noinhibit-exec:
4545# RUN: ld.lld -o %t.so --script %t-vaddr.script %t.o -shared --noinhibit-exec
46# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-VADDR
46# RUN: llvm-readelf --sections -l %t.so | FileCheck %s -check-prefix BAD-VADDR
4747# BAD-VADDR-LABEL: Section Headers:
4848# BAD-VADDR: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1
4949# BAD-VADDR: .sec2 PROGBITS 0000000000008020 003020 000100 00 WA 0 0 1
5050# BAD-VADDR-LABEL: Program Headers:
5151# BAD-VADDR-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
5252# BAD-VADDR-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000
53# BAD-VADDR-NEXT: LOAD 0x001100 0x0000000000000100 0x0000000000000100 0x000070 0x000070 RW 0x1000
5354# BAD-VADDR-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW 0x1000
54# BAD-VADDR-NEXT: LOAD 0x003020 0x0000000000008020 0x0000000000008800 0x000170 0x000170 RW 0x1000
5555# BAD-VADDR-LABEL: Section to Segment mapping:
56# BAD-VADDR: 01 .sec1
57# BAD-VADDR: 02 .sec2 .dynamic
56# BAD-VADDR: 01 .text .dynamic
57# BAD-VADDR: 02 .sec1
5858
5959# Finally check the case where both LMA and vaddr overlap
6060
......@@ -91,16 +91,16 @@
9191# Starting here the contents of .sec2 overwrites .sec1:
9292# BROKEN-OUTPUT-FILE-NEXT: 8040 02020202 02020202 02020202 02020202
9393
94# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-BOTH
94# RUN: llvm-readelf --sections -l %t.so | FileCheck %s -check-prefix BAD-BOTH
9595# BAD-BOTH-LABEL: Section Headers:
9696# BAD-BOTH: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1
9797# BAD-BOTH: .sec2 PROGBITS 0000000000008040 002040 000100 00 WA 0 0 1
9898# BAD-BOTH-LABEL: Program Headers:
9999# BAD-BOTH-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
100100# BAD-BOTH-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000
101# BAD-BOTH-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x0001b0 0x0001b0 RW 0x1000
101# BAD-BOTH-NEXT: LOAD 0x001100 0x0000000000000100 0x0000000000000100 0x000070 0x000070 RW 0x1000
102102# BAD-BOTH-LABEL: Section to Segment mapping:
103# BAD-BOTH: 01 .sec1 .sec2 .dynamic
103# BAD-BOTH: 01 .text .dynamic
104104
105105.section .first_sec,"aw",@progbits
106106.rept 0x100
deps/lld/test/ELF/linkerscript/overlay.test+1-1
......@@ -16,7 +16,7 @@ SECTIONS {
1616## .text does not cause overlapping error and that
1717## .text's VA is 0x1000 + max(sizeof(.out.big), sizeof(.out.small)).
1818
19# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t | FileCheck %s
19# RUN: llvm-readelf --sections -l %t | FileCheck %s
2020
2121# CHECK: Section Headers:
2222# CHECK: Name Type Address Off Size
deps/lld/test/ELF/linkerscript/page-size-align.test+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o
33# RUN: ld.lld -T %s -z max-page-size=0x4000 %t.o -o %t.so -shared
4# RUN: llvm-readobj -s %t.so | FileCheck %s
4# RUN: llvm-readobj -S %t.so | FileCheck %s
55
66SECTIONS {
77 . = SIZEOF_HEADERS;
deps/lld/test/ELF/linkerscript/page-size.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33
44# RUN: ld.lld -z max-page-size=0x4000 %t -o %t2
5# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
5# RUN: llvm-readobj -l %t2 | FileCheck %s
66
77# CHECK: ProgramHeaders [
88# CHECK: ProgramHeader {
deps/lld/test/ELF/linkerscript/phdr-check.s+1-1
......@@ -3,7 +3,7 @@
33
44# RUN: echo "SECTIONS { . = 0x10000000 + SIZEOF_HEADERS; .text : {*(.text.*)} }" > %t.script
55# RUN: ld.lld -o %t1 --script %t.script %t
6# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
6# RUN: llvm-readobj -l %t1 | FileCheck %s
77# CHECK: ProgramHeaders [
88# CHECK-NEXT: ProgramHeader {
99# CHECK-NEXT: Type: PT_PHDR (0x6)
deps/lld/test/ELF/linkerscript/phdrs-flags.s+2-2
......@@ -7,7 +7,7 @@
77# RUN: .foo : {*(.foo.*)} :all \
88# RUN: .data : {*(.data.*)} :all}" > %t.script
99# RUN: ld.lld -o %t1 --script %t.script %t
10# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
10# RUN: llvm-readobj -l %t1 | FileCheck %s
1111
1212# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS FLAGS (0x1);} \
1313# RUN: SECTIONS { \
......@@ -16,7 +16,7 @@
1616# RUN: .foo : {*(.foo.*)} \
1717# RUN: .data : {*(.data.*)} }" > %t.script
1818# RUN: ld.lld -o %t1 --script %t.script %t
19# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s
19# RUN: llvm-readobj -l %t1 | FileCheck --check-prefix=DEFHDR %s
2020
2121# CHECK: ProgramHeaders [
2222# CHECK-NEXT: ProgramHeader {
deps/lld/test/ELF/linkerscript/phdrs.s+5-5
......@@ -7,7 +7,7 @@
77# RUN: .foo : {*(.foo.*)} :all \
88# RUN: .data : {*(.data.*)} :all}" > %t.script
99# RUN: ld.lld -o %t1 --script %t.script %t
10# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
10# RUN: llvm-readobj -l %t1 | FileCheck %s
1111
1212## Check that program headers are not written, unless we explicitly tell
1313## lld to do this.
......@@ -18,7 +18,7 @@
1818# RUN: .foo : {*(.foo.*)} :all \
1919# RUN: }" > %t.script
2020# RUN: ld.lld -o %t1 --script %t.script %t
21# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=NOPHDR %s
21# RUN: llvm-readobj -l %t1 | FileCheck --check-prefix=NOPHDR %s
2222
2323## Check the AT(expr)
2424# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS AT(0x500 + 0x500) ;} \
......@@ -28,7 +28,7 @@
2828# RUN: .foo : {*(.foo.*)} :all \
2929# RUN: .data : {*(.data.*)} :all}" > %t.script
3030# RUN: ld.lld -o %t1 --script %t.script %t
31# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=AT %s
31# RUN: llvm-readobj -l %t1 | FileCheck --check-prefix=AT %s
3232
3333# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS ;} \
3434# RUN: SECTIONS { \
......@@ -37,7 +37,7 @@
3737# RUN: .foo : {*(.foo.*)} \
3838# RUN: .data : {*(.data.*)} }" > %t.script
3939# RUN: ld.lld -o %t1 --script %t.script %t
40# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s
40# RUN: llvm-readobj -l %t1 | FileCheck --check-prefix=DEFHDR %s
4141
4242## Check that error is reported when trying to use phdr which is not listed
4343## inside PHDRS {} block
......@@ -95,7 +95,7 @@
9595# RUN: echo "PHDRS {text PT_LOAD FILEHDR PHDRS; foo 0x11223344; } \
9696# RUN: SECTIONS { . = SIZEOF_HEADERS; .foo : { *(.foo* .text*) } : text : foo}" > %t1.script
9797# RUN: ld.lld -o %t2 --script %t1.script %t
98# RUN: llvm-readobj -program-headers %t2 | FileCheck --check-prefix=INT-PHDRS %s
98# RUN: llvm-readobj -l %t2 | FileCheck --check-prefix=INT-PHDRS %s
9999
100100# INT-PHDRS: ProgramHeaders [
101101# INT-PHDRS: ProgramHeader {
deps/lld/test/ELF/linkerscript/provide-empty-section.s+4-4
......@@ -8,19 +8,19 @@
88
99# Case 1: Provided symbol is undefined and not referenced - empty section should be removed.
1010# RUN: ld.lld %tundefined.o -T %t.script -o %t1.elf
11# RUN: llvm-readobj -sections %t1.elf | FileCheck %s --check-prefix=NOSECTION
11# RUN: llvm-readobj --sections %t1.elf | FileCheck %s --check-prefix=NOSECTION
1212
1313# Case 2: Provided symbol is undefined and referenced - empty section should not be removed.
1414# RUN: ld.lld %tundefined.o %treference.o -T %t.script -o %t2.elf
15# RUN: llvm-readobj -sections %t2.elf | FileCheck %s --check-prefix=SECTION
15# RUN: llvm-readobj --sections %t2.elf | FileCheck %s --check-prefix=SECTION
1616
1717# Case 3: Provided symbol is defined and not referenced - empty section should be removed.
1818# RUN: ld.lld %tdefined.o -T %t.script -o %t3.elf
19# RUN: llvm-readobj -sections %t3.elf | FileCheck %s --check-prefix=NOSECTION
19# RUN: llvm-readobj --sections %t3.elf | FileCheck %s --check-prefix=NOSECTION
2020
2121# Case 4: Provided symbol is defined and referenced - empty section should not be removed.
2222# RUN: ld.lld %tdefined.o %treference.o -T %t.script -o %t4.elf
23# RUN: llvm-readobj -sections %t4.elf | FileCheck %s --check-prefix=SECTION
23# RUN: llvm-readobj --sections %t4.elf | FileCheck %s --check-prefix=SECTION
2424
2525.global _start
2626_start:
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: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo
1010
1111.global _start
1212_start:
deps/lld/test/ELF/linkerscript/pt-interp.test+3-3
......@@ -5,17 +5,17 @@
55## Check we create PT_INTERP program header when it is specified in PHDRS.
66# RUN: echo "PHDRS { interp PT_INTERP; }" > %t1.script
77# RUN: ld.lld -o %t1 --script %t1.script %t.o %t.so --dynamic-linker foo
8# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
8# RUN: llvm-readobj -l %t1 | FileCheck %s
99# CHECK: PT_INTERP
1010
1111## Check we do not create it if it is not specified,
1212## but only if PHDRS is not empty by itself.
1313# RUN: echo "PHDRS { ph_text PT_LOAD; }" > %t2.script
1414# RUN: ld.lld -o %t1 --script %t2.script %t.o %t.so --dynamic-linker foo
15# RUN: llvm-readobj -program-headers %t1 | FileCheck %s --check-prefix=NOINTERP
15# RUN: llvm-readobj -l %t1 | FileCheck %s --check-prefix=NOINTERP
1616# NOINTERP-NOT: PT_INTERP
1717
1818## Otherwise, if PHDRS is empty, we create PT_INTERP header.
1919# RUN: echo "PHDRS {}" > %t3.script
2020# RUN: ld.lld -o %t1 --script %t3.script %t.o %t.so --dynamic-linker foo
21# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
21# RUN: llvm-readobj -l %t1 | FileCheck %s
deps/lld/test/ELF/linkerscript/quoted-section-name.test created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2
3## Handling of quotes is tricky sometimes. Check we do that right and include
4## "foo bar" section into .data as expected.
5
6# RUN: echo '.section "foo bar", "aw"; nop' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t
7# RUN: ld.lld %t --script %s -o %t2 --print-map | FileCheck %s
8# CHECK: .data
9# CHECK-NEXT: {{.*}}(foo bar)
10
11SECTIONS {
12 .data : { *("foo bar") }
13}
deps/lld/test/ELF/linkerscript/relocatable-discard.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: echo "SECTIONS { /DISCARD/ : { *(.discard.*) }}" > %t.script
44# RUN: ld.lld -o %t --script %t.script -r %t.o
5# RUN: llvm-readobj -sections %t | FileCheck %s
5# RUN: llvm-readobj --sections %t | FileCheck %s
66
77## Test shows that we do not crash after discarding the .discard.foo with -r.
88## Previously it happened because of 2 reasons:
deps/lld/test/ELF/linkerscript/repsection-symbol.s+4-4
......@@ -7,16 +7,16 @@
77# RUN: .foo : {foo1 = .; *(.foo.*) foo2 = .; *(.bar) foo3 = .;} \
88# RUN: }" > %t.script
99# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared
10# RUN: llvm-readobj -t %t1 | FileCheck %s
10# RUN: llvm-readobj --symbols %t1 | FileCheck %s
1111
1212# CHECK: Name: foo1
13# CHECK-NEXT: Value: 0x228
13# CHECK-NEXT: Value: 0x2C0
1414
1515# CHECK: Name: foo2
16# CHECK-NEXT: Value: 0x230
16# CHECK-NEXT: Value: 0x2C8
1717
1818# CHECK: Name: foo3
19# CHECK-NEXT: Value: 0x234
19# CHECK-NEXT: Value: 0x2CC
2020
2121.section .foo.1,"a"
2222 .long 1
deps/lld/test/ELF/linkerscript/repsection-va.s+1-1
......@@ -5,7 +5,7 @@
55# RUN: ld.lld -o %t1 --script %t.script %t
66# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
77# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address Type
8# CHECK-NEXT: Idx Name Size VMA Type
99# CHECK-NOT: .foo
1010# CHECK: .foo 00000008 {{.*}} DATA
1111# CHECK-NOT: .foo
deps/lld/test/ELF/linkerscript/section-align.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: .ccc : ALIGN(4096 * 8) { *(.ccc) } \
88# RUN: }" > %t.script
99# RUN: ld.lld -o %t1 --script %t.script %t
10# RUN: llvm-readobj -sections %t1 | FileCheck %s
10# RUN: llvm-readobj --sections %t1 | FileCheck %s
1111
1212.global _start
1313_start:
deps/lld/test/ELF/linkerscript/sections-constraint2.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: echo "SECTIONS { zed : ONLY_IF_RO { *(foo) *(bar) } }" > %t.script
44# RUN: ld.lld -T %t.script %t.o -o %t.so -shared
5# RUN: llvm-readobj -s %t.so | FileCheck %s
5# RUN: llvm-readobj -S %t.so | FileCheck %s
66
77# CHECK: Sections [
88# CHECK-NOT: zed
deps/lld/test/ELF/linkerscript/sections-constraint3.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: echo "SECTIONS { zed : ONLY_IF_RO { abc = 1; *(foo) } }" > %t.script
44# RUN: ld.lld -T %t.script %t.o -o %t.so -shared
5# RUN: llvm-readobj -t %t.so | FileCheck %s
5# RUN: llvm-readobj --symbols %t.so | FileCheck %s
66
77# CHECK: Symbols [
88# CHECK-NOT: abc
deps/lld/test/ELF/linkerscript/sections-constraint4.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: .foo : ONLY_IF_RO { *(.foo) } \
55# RUN: .bar : {bar1 = .; *(.bar) } }" > %t1.script
66# RUN: ld.lld -o %t1 --script %t1.script %t
7# RUN: llvm-readobj -t %t1 | FileCheck %s
7# RUN: llvm-readobj --symbols %t1 | FileCheck %s
88
99# CHECK: Name: bar1
1010
deps/lld/test/ELF/linkerscript/sections-constraint5.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: }" > %t.script
77
88# RUN: ld.lld -o %t -T %t.script %t.o
9# RUN: llvm-readobj -s -t %t | FileCheck %s
9# RUN: llvm-readobj -S --symbols %t | FileCheck %s
1010
1111# CHECK: Sections [
1212# CHECK: Name: bar
deps/lld/test/ELF/linkerscript/sections-gc2.s+1-1
......@@ -8,7 +8,7 @@
88# RUN: ld.lld -T %t.script -o %t.so %t.o --gc-sections
99# RUN: llvm-objdump -h %t.so | FileCheck %s
1010
11# CHECK: Idx Name Size Address Type
11# CHECK: Idx Name Size VMA Type
1212# CHECK-NEXT: 0
1313# CHECK-NEXT: used_in_reloc
1414# CHECK-NEXT: .text
deps/lld/test/ELF/linkerscript/sections-padding.s+29-4
......@@ -7,11 +7,16 @@
77# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
88# YES: 66000011 22000011 22000011 22000011
99
10# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x1100+0x22 }" > %t.script
11# RUN: ld.lld -o %t.out --script %t.script %t
12# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES2 %s
13# YES2: 66000011 22000011 22000011 22000011
14
1015## Confirming that address was correct:
1116# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99887766 }" > %t.script
1217# RUN: ld.lld -o %t.out --script %t.script %t
13# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES2 %s
14# YES2: 66998877 66998877 66998877 66998877
18# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES3 %s
19# YES3: 66998877 66998877 66998877 66998877
1520
1621## Default padding value is 0x00:
1722# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } }" > %t.script
......@@ -29,9 +34,9 @@
2934# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99XX }" > %t.script
3035# RUN: not ld.lld -o %t.out --script %t.script %t 2>&1 \
3136# RUN: | FileCheck --check-prefix=ERR2 %s
32# ERR2: invalid filler expression: 0x99XX
37# ERR2: malformed number: 0x99XX
3338
34## Check case with space between '=' and expression:
39## Check case with space between '=' and a value:
3540# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } = 0x1122 }" > %t.script
3641# RUN: ld.lld -o %t.out --script %t.script %t
3742# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
......@@ -41,6 +46,26 @@
4146# RUN: ld.lld -o %t.out --script %t.script %t
4247# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
4348
49## Check we can use an artbitrary expression as a filler.
50# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } = ((0x11<<8) | 0x22) }" > %t.script
51# RUN: ld.lld -o %t.out --script %t.script %t
52# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
53
54## Check case with space between '=' and expression:
55# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =((0x11 << 8) | 0x22) }" > %t.script
56# RUN: ld.lld -o %t.out --script %t.script %t
57# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
58
59## Check we report an error if expression value is larger than 32-bits.
60# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =(0x11 << 32) }" > %t.script
61# RUN: not ld.lld -o %t.out --script %t.script %t 2>&1 | FileCheck --check-prefix=ERR3 %s
62# ERR3: filler expression result does not fit 32-bit: 0x1100000000
63
64## Check we report an error if an expression use a symbol.
65# RUN: echo "SECTIONS { foo = 0x11; .mysec : { *(.mysec*) } = foo }" > %t.script
66# RUN: not ld.lld -o %t.out %t --script %t.script 2>&1 | FileCheck --check-prefix=ERR4 %s
67# ERR4: symbol not found: foo
68
4469.section .mysec.1,"a"
4570.align 16
4671.byte 0x66
deps/lld/test/ELF/linkerscript/segment-none.s+1-1
......@@ -23,7 +23,7 @@
2323
2424# CHECK: Section to Segment mapping:
2525# CHECK-NEXT: Segment Sections...
26# CHECK-NOT: .foo
26# CHECK: None {{.*}}.foo
2727
2828# DEFINED: Section to Segment mapping:
2929# DEFINED-NEXT: Segment Sections...
deps/lld/test/ELF/linkerscript/sort-non-script.s+1-1
......@@ -9,8 +9,8 @@
99# CHECK-NEXT: .hash {{.*}} A
1010# CHECK-NEXT: .dynstr {{.*}} A
1111# CHECK-NEXT: .text {{.*}} AX
12# CHECK-NEXT: foo {{.*}} WA
1312# CHECK-NEXT: .dynamic {{.*}} WA
13# CHECK-NEXT: foo {{.*}} WA
1414
1515.section foo, "aw"
1616.byte 0
deps/lld/test/ELF/linkerscript/symbol-alias-relocation.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: echo "aliasto__text = __text; SECTIONS { .text 0x1000 : { __text = . ; *(.text) } }" > %t.script
4# RUN: ld.lld -pie -o %t --script %t.script %t.o
5# RUN: llvm-readobj --symbols %t | FileCheck %s
6
7## Check that alias 'aliasto__text' has the correct value.
8## (It should belong to the section .text and point to it's start).
9
10# CHECK: Symbol {
11# CHECK: Name: __text
12# CHECK-NEXT: Value: 0x1000
13# CHECK-NEXT: Size: 0
14# CHECK-NEXT: Binding: Global
15# CHECK-NEXT: Type: None
16# CHECK-NEXT: Other: 0
17# CHECK-NEXT: Section: .text
18# CHECK-NEXT: }
19
20# CHECK: Symbol {
21# CHECK: Name: aliasto__text
22# CHECK-NEXT: Value: 0x1000
23# CHECK-NEXT: Size: 0
24# CHECK-NEXT: Binding: Global
25# CHECK-NEXT: Type: None
26# CHECK-NEXT: Other: 0
27# CHECK-NEXT: Section: .text
28# CHECK-NEXT: }
29
30.text
31.globl _start
32.type _start, %function
33_start:
34.globl aliasto__text
35 call __text
36 call aliasto__text
deps/lld/test/ELF/linkerscript/symbol-location.s+6-5
......@@ -1,15 +1,16 @@
11# 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
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: echo 'foo = _start;' > %t.script
4# RUN: not ld.lld -shared -T %t.script %t.o -o /dev/null 2>&1 | FileCheck %s
55
66## Here we check that symbol 'foo' location is reported properly.
77
8# CHECK: error: relocation R_X86_64_PLT32 cannot refer to absolute symbol: foo
8# CHECK: error: relocation R_X86_64_PC32 cannot be used against symbol foo
99# CHECK: >>> defined in {{.*}}.script:1
1010# CHECK: >>> referenced by {{.*}}.o:(.text+0x1)
1111
1212.text
1313.globl _start
1414_start:
15 call foo@PLT
15 .byte 0xe8
16 .long foo - .
deps/lld/test/ELF/linkerscript/symbol-only-align.test created+35
......@@ -0,0 +1,35 @@
1# REQUIRES: x86
2# RUN: echo '.text; ret; .data; .quad 0' > %t.s
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o
4# RUN: ld.lld -o %t --script %s %t.o -shared
5# RUN: llvm-readelf -S --symbols -l %t | FileCheck %s
6
7PHDRS {
8 text PT_LOAD FLAGS(0x5);
9 data PT_LOAD FLAGS(0x6);
10}
11
12SECTIONS {
13 . = SIZEOF_HEADERS;
14 .text : { *(.text) } : text
15 . = ALIGN(CONSTANT(MAXPAGESIZE));
16 foo : { __start_foo = .; *(foo); __end_foo = .; } : data
17 .data : { *(.data) }
18 .dynamic : { *(.dynamic) }
19}
20
21## Check that foo, the symbol only section, has the expected aligned address and
22## file offset. Also check that the section's symbols and the data segment's
23## offset and addresses match.
24
25# CHECK: Section Headers
26# CHECK: foo PROGBITS 0000000000[[ADDR:[0-9a-f]*]] [[ADDR]]
27# CHECK-NEXT: .data PROGBITS 0000000000[[ADDR]] [[ADDR]]
28
29# CHECK: Symbol table
30# CHECK: 0000000000[[ADDR]] 0 NOTYPE GLOBAL DEFAULT {{[0-9]+}} __start_foo
31# CHECK: 0000000000[[ADDR]] 0 NOTYPE GLOBAL DEFAULT {{[0-9]+}} __end_foo
32
33# CHECK: Program Headers
34# CHECK: LOAD
35# CHECK-NEXT: LOAD 0x[[ADDR]] 0x0000000000[[ADDR]] 0x0000000000[[ADDR]]
deps/lld/test/ELF/linkerscript/symbol-only-flags.test+2-2
......@@ -2,7 +2,7 @@
22# RUN: echo '.section .tbss,"awT",@nobits; .quad 0' \
33# RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o
44# RUN: ld.lld -o %t --script %s %t.o
5# RUN: llvm-readobj -s %t | FileCheck %s
5# RUN: llvm-readobj -S %t | FileCheck %s
66
77SECTIONS {
88 . = SIZEOF_HEADERS;
......@@ -14,7 +14,7 @@ SECTIONS {
1414# CHECK: Section {
1515# CHECK: Index:
1616# CHECK: Name: .foo
17# CHECK-NEXT: Type: SHT_NOBITS
17# CHECK-NEXT: Type: SHT_PROGBITS
1818# CHECK-NEXT: Flags [
1919# CHECK-NEXT: SHF_ALLOC
2020# CHECK-NEXT: SHF_WRITE
deps/lld/test/ELF/linkerscript/symbol-only.test+1-1
......@@ -12,7 +12,7 @@ SECTIONS {
1212}
1313
1414# CHECK: Sections:
15# CHECK-NEXT: Idx Name Size Address
15# CHECK-NEXT: Idx Name Size VMA
1616# CHECK-NEXT: 0 00000000 0000000000000000
1717# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]]
1818# CHECK: bar 00000000 0000000000001000
deps/lld/test/ELF/linkerscript/symbol-pie.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: echo "SECTIONS { .data 0x2000 : { foo = .; *(.data) } }" > %t.script
5# RUN: ld.lld -pie -o %t --script %t.script %t.o
6# RUN: llvm-readobj -r %t | FileCheck %s
7
8## Position independent executables require dynamic
9## relocations for references to non-absolute script
10## symbols.
11
12# CHECK: Relocations [
13# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
14# CHECK-NEXT: 0x2000 R_X86_64_RELATIVE - 0x2000
15# CHECK-NEXT: }
16# CHECK-NEXT: ]
17
18.data
19.quad foo
deps/lld/test/ELF/linkerscript/tbss.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: bar : { *(bar) } \
88# RUN: }" > %t.script
99# RUN: ld.lld -T %t.script %t.o -o %t
10# RUN: llvm-readobj -s %t | FileCheck %s
10# RUN: llvm-readobj -S %t | FileCheck %s
1111
1212# test that a tbss section doesn't use address space.
1313
deps/lld/test/ELF/linkerscript/ttext-script.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: echo "SECTIONS { .text 0x200000 : { *(.text) } }" > %t.script
44# RUN: ld.lld -T %t.script -Ttext 0x100000 %t.o -o %t
5# RUN: llvm-readobj --elf-output-style=GNU -s %t | FileCheck %s
5# RUN: llvm-readelf -S %t | FileCheck %s
66
77# CHECK: .text PROGBITS 0000000000100000
88
deps/lld/test/ELF/linkerscript/va.s+1-1
......@@ -5,7 +5,7 @@
55# RUN: ld.lld -o %t1 --script %t.script %t
66# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
77# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address
8# CHECK-NEXT: Idx Name Size VMA
99# CHECK-NEXT: 0 00000000 0000000000000000
1010# CHECK-NEXT: 1 .foo 00000004 0000000000000000
1111# CHECK-NEXT: 2 .boo 00000004 0000000000000004
deps/lld/test/ELF/linkerscript/version-linker-symbol.s+2-2
......@@ -3,7 +3,7 @@
33# RUN: echo "VER1 { global: _end; foo ; local: * ; } ;" > %t.script
44# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
55# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
6# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
77
88# CHECK: Name: _end@@VER1
99# CHECK-NEXT: Value: 0
......@@ -11,7 +11,7 @@
1111# CHECK-NEXT: Binding: Global
1212# CHECK-NEXT: Type: None
1313# CHECK-NEXT: Other: 0
14# CHECK-NEXT: Section: .dynamic
14# CHECK-NEXT: Section: .data
1515
1616# CHECK: Name: foo@@VER1
1717# CHECK-NEXT: Value: 0
deps/lld/test/ELF/linkerscript/visibility.s+2-2
......@@ -3,7 +3,7 @@
33
44# RUN: echo "SECTIONS { foo = .; }" > %t1.script
55# RUN: ld.lld -o %t1 --script %t1.script %t.o -shared
6# RUN: llvm-readobj -t %t1 | FileCheck %s
6# RUN: llvm-readobj --symbols %t1 | FileCheck %s
77
88# CHECK: Symbol {
99# CHECK: Name: foo
......@@ -19,4 +19,4 @@
1919
2020 .data
2121 .hidden foo
22 .long foo
22 .quad foo
deps/lld/test/ELF/local-dynamic.s+1-1
......@@ -2,7 +2,7 @@
22// Check that local symbols are not inserted into dynamic table.
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
44// RUN: ld.lld %t -shared -o %t1.so
5// RUN: llvm-readobj -t -dyn-symbols %t1.so | FileCheck %s
5// RUN: llvm-readobj --symbols --dyn-syms %t1.so | FileCheck %s
66
77// CHECK: Symbols [
88// CHECK-NEXT: Symbol {
deps/lld/test/ELF/local-got-pie.s+2-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33// RUN: ld.lld --hash-style=sysv %t.o -o %t -pie
4// RUN: llvm-readobj -s -r -d %t | FileCheck %s
4// RUN: llvm-readobj -S -r -d %t | FileCheck %s
55// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
66
77.globl _start
......@@ -15,6 +15,7 @@ foo:
1515
1616// 0x20B0 - 1001 - 5 = 4266
1717// DISASM: Disassembly of section .text:
18// DISASM-EMPTY:
1819// DISASM-NEXT: _start:
1920// DISASM-NEXT: 1000: {{.*}} callq 4267
2021// DISASM: foo:
deps/lld/test/ELF/local-got-shared.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33// RUN: ld.lld --hash-style=sysv %t.o -o %t -shared
4// RUN: llvm-readobj -s -r -d %t | FileCheck %s
4// RUN: llvm-readobj -S -r -d %t | FileCheck %s
55// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
66
77bar:
deps/lld/test/ELF/local-got.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t
6// RUN: llvm-readobj -s -r -section-data %t | FileCheck %s
6// RUN: llvm-readobj -S -r --section-data %t | FileCheck %s
77// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
88
99 .globl _start
deps/lld/test/ELF/local-symbols-order.s+1-1
......@@ -5,7 +5,7 @@
55# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
66
77# RUN: ld.lld -o %t %t1.o %t2.o --emit-relocs
8# RUN: llvm-readobj -symbols -sections -elf-output-style=GNU %t | FileCheck %s
8# RUN: llvm-readelf --symbols --sections %t | FileCheck %s
99
1010## Check we sort local symbols to match the following order:
1111## file1, local1, section1, hidden1, file2, local2, section2, hidden2 ...
deps/lld/test/ELF/local-undefined-symbol.s+3-5
......@@ -1,10 +1,8 @@
11# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld %t -o %t1
4# RUN: llvm-readobj -t %t1 | FileCheck %s
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
54
6# CHECK: Symbols [
7# CHECK-NOT: Name: foo
5# CHECK: error: undefined symbol: foo
86
97.global _start
108_start:
deps/lld/test/ELF/local.s+1-1
......@@ -2,7 +2,7 @@
22// Check that symbol table is correctly populated with local symbols.
33// RUN: llvm-mc -save-temp-labels -filetype=obj -triple=x86_64-pc-linux %s -o %t
44// RUN: ld.lld %t -o %t1
5// RUN: llvm-readobj -t -s %t1 | FileCheck %s
5// RUN: llvm-readobj --symbols -S %t1 | FileCheck %s
66
77// Check that Info is equal to the number of local symbols.
88// CHECK: Section {
deps/lld/test/ELF/lto/Inputs/irmover-warning.ll created+10
......@@ -0,0 +1,10 @@
1target triple = "x86_64-unknown-linux-gnu"
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4define void @f() {
5 ret void
6}
7
8!0 = !{ i32 2, !"foo", i32 2 }
9
10!llvm.module.flags = !{ !0 }
deps/lld/test/ELF/lto/Inputs/obj-path.ll created+7
......@@ -0,0 +1,7 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @g() {
5entry:
6 ret void
7}
deps/lld/test/ELF/lto/archive-2.ll+2-2
......@@ -4,9 +4,9 @@
44; RUN: llvm-ar rcs %t.a %t1.o
55; RUN: llvm-as %s -o %t2.o
66; RUN: ld.lld %t2.o %t.a -o %t3
7; RUN: llvm-readobj -t %t3 | FileCheck %s
7; RUN: llvm-readobj --symbols %t3 | FileCheck %s
88; RUN: ld.lld %t2.o --whole-archive %t.a -o %t3 -shared
9; RUN: llvm-readobj -t %t3 | FileCheck %s
9; RUN: llvm-readobj --symbols %t3 | FileCheck %s
1010
1111; CHECK: Name: _start (
1212; CHECK-NEXT: Value:
deps/lld/test/ELF/lto/archive-no-index.ll+13-4
......@@ -1,8 +1,6 @@
11; REQUIRES: x86
2; Tests that we suggest that LTO symbols missing from an archive index
3; may be the cause of undefined references, but only if we both
4; encountered an empty archive index and undefined references (to prevent
5; noisy false alarms).
2; Tests that we accept an archive file without symbol table
3; if all the member files are bitcode files.
64
75; RUN: llvm-as -o %t1.o %s
86; RUN: llvm-as -o %t2.o %S/Inputs/archive.ll
......@@ -23,3 +21,14 @@ define i32 @main() {
2321 call void @f()
2422 ret i32 0
2523}
24
25; RUN: echo 'f:' | llvm-mc -triple=x86_64-pc-linux -filetype=obj - -o %t3.o
26; RUN: rm -f %t3.a
27; RUN: llvm-ar crS %t3.a %t3.o
28; RUN: not ld.lld -o /dev/null -emain %t1.o %t3.a 2>&1 | FileCheck -check-prefix=ERR1 %s
29; ERR1: error: {{.*}}.a: archive has no index; run ranlib to add one
30
31; RUN: rm -f %t4.a
32; RUN: llvm-ar cr %t4.a
33; RUN: not ld.lld -o /dev/null -emain %t1.o %t4.a 2>&1 | FileCheck -check-prefix=ERR2 %s
34; ERR2: error: undefined symbol: f
deps/lld/test/ELF/lto/archive.ll+2-2
......@@ -4,9 +4,9 @@
44; RUN: llvm-ar rcs %t.a %t1.o
55; RUN: llvm-as %s -o %t2.o
66; RUN: ld.lld %t2.o %t.a -o %t3 -shared
7; RUN: llvm-readobj -t %t3 | FileCheck %s
7; RUN: llvm-readobj --symbols %t3 | FileCheck %s
88; RUN: ld.lld %t2.o --whole-archive %t.a -o %t3 -shared
9; RUN: llvm-readobj -t %t3 | FileCheck %s
9; RUN: llvm-readobj --symbols %t3 | FileCheck %s
1010
1111; CHECK: Name: g (
1212; CHECK-NEXT: Value:
deps/lld/test/ELF/lto/comdat.ll+1-1
......@@ -1,7 +1,7 @@
11; REQUIRES: x86
22; RUN: llvm-as %s -o %t.o
33; RUN: ld.lld %t.o %t.o -o %t.so -shared
4; RUN: llvm-readobj -t %t.so | FileCheck %s
4; RUN: llvm-readobj --symbols %t.so | FileCheck %s
55
66; CHECK: Name: foo
77; CHECK-NEXT: Value:
deps/lld/test/ELF/lto/comdat2.ll+2-2
......@@ -2,9 +2,9 @@
22; RUN: llvm-as %s -o %t.o
33; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj
44; RUN: ld.lld %t.o %t2.o -o %t.so -shared
5; RUN: llvm-readobj -t %t.so | FileCheck %s
5; RUN: llvm-readobj --symbols %t.so | FileCheck %s
66; RUN: ld.lld %t2.o %t.o -o %t2.so -shared
7; RUN: llvm-readobj -t %t2.so | FileCheck %s --check-prefix=OTHER
7; RUN: llvm-readobj --symbols %t2.so | FileCheck %s --check-prefix=OTHER
88
99
1010target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
deps/lld/test/ELF/lto/common.ll+1-1
......@@ -2,7 +2,7 @@
22; RUN: llvm-as %s -o %t1.o
33; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2.o -filetype=obj
44; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
5; RUN: llvm-readobj -s -t %t.so | FileCheck %s
5; RUN: llvm-readobj -S --symbols %t.so | FileCheck %s
66
77; CHECK: Name: .bss
88; CHECK-NEXT: Type: SHT_NOBITS
deps/lld/test/ELF/lto/common2.ll+1-1
......@@ -2,7 +2,7 @@
22; RUN: llvm-as %s -o %t1.o
33; RUN: ld.lld %t1.o -o %t -shared -save-temps
44; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s
5; RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SHARED
5; RUN: llvm-readobj --symbols %t | FileCheck %s --check-prefix=SHARED
66
77target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
88target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/common4.ll created+21
......@@ -0,0 +1,21 @@
1; REQUIRES: x86
2
3;; Make sure that common symbols are properly internalized.
4;; In this file, @a does not interpose any symbol in a DSO,
5;; so LTO should be able to internelize it.
6
7; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.so.o
8; RUN: ld.lld -shared -o %t.so %t.so.o
9
10; RUN: llvm-as %s -o %t.o
11; RUN: ld.lld -o %t.exe -save-temps %t.o %t.so
12; RUN: llvm-dis < %t.exe.0.2.internalize.bc | FileCheck %s
13
14; RUN: ld.lld -pie -o %t.exe -save-temps %t.o
15; RUN: llvm-dis < %t.exe.0.2.internalize.bc | FileCheck %s
16
17target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
18target triple = "x86_64-unknown-linux-gnu"
19
20@a = common dso_local local_unnamed_addr global i32 0, align 4
21; CHECK-DAG: @a = internal global i32 0, align 4
deps/lld/test/ELF/lto/ctors.ll+1-1
......@@ -1,7 +1,7 @@
11; REQUIRES: x86
22; RUN: llvm-as %s -o %t.o
33; RUN: ld.lld %t.o -o %t.so -shared
4; RUN: llvm-readobj -sections %t.so | FileCheck %s
4; RUN: llvm-readobj --sections %t.so | FileCheck %s
55
66target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
77target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/defsym.ll+4-10
......@@ -11,7 +11,7 @@
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
1313; RUN: llvm-readelf --symbols %t2.so1.lto.o | FileCheck --check-prefix=OBJ %s
14; RUN: llvm-objdump -d %t2.so | FileCheck %s --check-prefix=THIN
14; RUN: llvm-objdump -d %t2.so | FileCheck %s
1515
1616; OBJ: UND bar2
1717
......@@ -19,17 +19,11 @@
1919; Symbol bar3 should not be eliminated
2020
2121; CHECK: foo:
22; CHECK-NEXT: pushq %rax
22; CHECK-NEXT: pushq %rax
2323; CHECK-NEXT: callq
2424; CHECK-NEXT: callq{{.*}}<bar3>
25; CHECK-NEXT: callq
26
27; THIN: foo
28; THIN-NEXT: pushq %rax
29; THIN-NEXT: callq
30; THIN-NEXT: callq{{.*}}<bar3>
31; THIN-NEXT: popq %rax
32; THIN-NEXT: jmp
25; CHECK-NEXT: popq %rax
26; CHECK-NEXT: jmp
3327
3428target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3529target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/deplibs.s created+15
......@@ -0,0 +1,15 @@
1; REQUIRES: x86
2
3; RUN: llvm-as %s -o %t.o
4; RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s -DOBJ=%t.o
5
6; CHECK: error: [[OBJ]]: unable to find library from dependent library specifier: foo
7; CHECK: error: [[OBJ]]: unable to find library from dependent library specifier: bar
8
9target triple = "x86_64-unknown-linux-gnu"
10target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
11
12!llvm.dependent-libraries = !{!0, !1}
13
14!0 = !{!"foo"}
15!1 = !{!"bar"}
deps/lld/test/ELF/lto/dynamic-list.ll+1-1
......@@ -2,7 +2,7 @@
22; RUN: llvm-as %s -o %t.o
33; RUN: echo "{ foo; };" > %t.list
44; RUN: ld.lld -o %t --dynamic-list %t.list -pie %t.o
5; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
5; RUN: llvm-readobj --dyn-syms %t | FileCheck %s
66
77; CHECK: Name: foo
88; CHECK-NEXT: Value: 0x1010
deps/lld/test/ELF/lto/dynsym.ll+2-2
......@@ -3,12 +3,12 @@
33; RUN: ld.lld %t.o -o %t.so -shared
44; RUN: llvm-as %s -o %t2.o
55; RUN: ld.lld %t2.o %t.so -o %t
6; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
6; RUN: llvm-readobj --dyn-syms %t | FileCheck %s
77
88; Check that we don't crash when gc'ing sections and printing the result.
99; RUN: ld.lld %t2.o %t.so --gc-sections --print-gc-sections \
1010; RUN: -o %t
11; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
11; RUN: llvm-readobj --dyn-syms %t | FileCheck %s
1212
1313target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1414target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/irmover-warning.ll created+23
......@@ -0,0 +1,23 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t1.bc %s
3; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-warning.ll
4; RUN: rm -f %t.a
5; RUN: llvm-ar rcs %t.a %t2.bc
6; RUN: ld.lld %t1.bc %t.a -o %t 2>&1 | FileCheck %s
7
8; CHECK: warning: linking module flags 'foo': IDs have conflicting values
9; CHECK-SAME: irmover-warning.ll.tmp.a(irmover-warning.ll.tmp2.bc at {{[0-9]+}})
10
11target triple = "x86_64-unknown-linux-gnu"
12target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
13
14declare void @f()
15
16define void @g() {
17 call void @f()
18 ret void
19}
20
21!0 = !{ i32 2, !"foo", i32 1 }
22
23!llvm.module.flags = !{ !0 }
deps/lld/test/ELF/lto/linker-script-symbols-assign.ll+3-3
......@@ -3,12 +3,12 @@
33
44; RUN: echo "foo = 1;" > %t.script
55; RUN: ld.lld %t.o -o %t2 --script %t.script -save-temps
6; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s
6; RUN: llvm-readobj --symbols %t2.lto.o | FileCheck %s
77
88; CHECK-NOT: bar
99; CHECK-NOT: foo
1010
11; RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=VAL
11; RUN: llvm-readobj --symbols %t2 | FileCheck %s --check-prefix=VAL
1212; VAL: Symbol {
1313; VAL: Name: foo
1414; VAL-NEXT: Value: 0x1
......@@ -21,7 +21,7 @@
2121
2222; RUN: echo "zed = 1;" > %t2.script
2323; RUN: ld.lld %t.o -o %t3 --script %t2.script
24; RUN: llvm-readobj -symbols %t3 | FileCheck %s --check-prefix=ABS
24; RUN: llvm-readobj --symbols %t3 | FileCheck %s --check-prefix=ABS
2525; ABS: Symbol {
2626; ABS: Name: zed
2727; ABS-NEXT: Value: 0x1
deps/lld/test/ELF/lto/linker-script-symbols.ll+2-1
......@@ -3,8 +3,9 @@
33; RUN: echo "foo = bar;" > %t.script
44
55; RUN: ld.lld %t.o -o %t2 --script %t.script -save-temps
6; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s
6; RUN: llvm-readobj --symbols %t2.lto.o | FileCheck %s
77
8; CHECK: Symbols [
89; CHECK-NOT: zed
910; CHECK: Symbol {
1011; CHECK: Name: bar
deps/lld/test/ELF/lto/lto-start.ll+1-1
......@@ -1,7 +1,7 @@
11; REQUIRES: x86
22; RUN: llvm-as %s -o %t.o
33; RUN: ld.lld %t.o -o %t2
4; RUN: llvm-readobj -t %t2 | FileCheck %s
4; RUN: llvm-readobj --symbols %t2 | FileCheck %s
55
66; CHECK: Format: ELF64-x86-64
77; CHECK-NEXT: Arch: x86_64
deps/lld/test/ELF/lto/obj-path.ll created+35
......@@ -0,0 +1,35 @@
1; REQUIRES: x86
2
3; RUN: opt -module-summary %s -o %t1.o
4; RUN: opt -module-summary %p/Inputs/obj-path.ll -o %t2.o
5
6; Test to ensure that obj-path creates the ELF file.
7; RUN: rm -f %t4.o
8; RUN: ld.lld --plugin-opt=obj-path=%t4.o -shared %t1.o %t2.o -o %t3
9; RUN: llvm-readobj --symbols %t3 | FileCheck %s
10; RUN: llvm-readobj -h %t4.o1 | FileCheck %s -check-prefix=ELF1
11; RUN: llvm-readobj -h %t4.o2 | FileCheck %s -check-prefix=ELF2
12; RUN: llvm-nm %t4.o1 2>&1 | FileCheck %s -check-prefix=NM1
13; RUN: llvm-nm %t4.o2 2>&1 | FileCheck %s -check-prefix=NM2
14
15; CHECK: Name: g
16; CHECK-NEXT: Value: 0x1010
17; CHECK: Name: f
18; CHECK-NEXT: Value: 0x1000
19
20; NM1: T f
21; ELF1: Format: ELF64-x86-64
22
23; NM2: T g
24; ELF2: Format: ELF64-x86-64
25
26target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
27target triple = "x86_64-unknown-linux-gnu"
28
29declare void @g(...)
30
31define void @f() {
32entry:
33 call void (...) @g()
34 ret void
35}
deps/lld/test/ELF/lto/opt-remarks.ll+9-1
......@@ -8,10 +8,16 @@
88; RUN: %t.o -o %t -shared
99; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
1010; RUN: cat %t.hot.yaml | FileCheck %s -check-prefix=YAML-HOT
11; RUN: ld.lld --opt-remarks-filename %t1.yaml --opt-remarks-passes inline %t.o \
12; RUN: -o /dev/null -shared
13; RUN: cat %t1.yaml | FileCheck %s -check-prefix=YAML-PASSES
14; RUN: ld.lld --opt-remarks-filename %t1.yaml --opt-remarks-format yaml %t.o \
15; RUN: -o /dev/null -shared
16; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
1117
1218; Check that @tinkywinky is inlined after optimizations.
1319; CHECK-LABEL: define i32 @main
14; CHECK-NEXT: %a.i = call i32 @patatino()
20; CHECK-NEXT: %a.i = {{.*}}call i32 @patatino()
1521; CHECK-NEXT: ret i32 %a.i
1622; CHECK-NEXT: }
1723
......@@ -48,6 +54,8 @@
4854; YAML-HOT-NEXT: - String: ')'
4955; YAML-HOT-NEXT: ...
5056
57; YAML-PASSES: Pass: inline
58
5159target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5260target triple = "x86_64-scei-ps4"
5361
deps/lld/test/ELF/lto/parallel-internalize.ll+1-1
......@@ -3,7 +3,7 @@
33; RUN: rm -f %t.lto.o %t1.lto.o
44; RUN: ld.lld --lto-partitions=2 -save-temps -o %t %t.bc \
55; RUN: -e foo --lto-O0
6; RUN: llvm-readobj -t -dyn-symbols %t | FileCheck %s
6; RUN: llvm-readobj --symbols --dyn-syms %t | FileCheck %s
77; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s
88; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s
99
deps/lld/test/ELF/lto/relocatable.ll+3-1
......@@ -1,7 +1,7 @@
11; REQUIRES: x86
22; RUN: llvm-as %s -o %t1.o
33; RUN: ld.lld %t1.o -r -o %t
4; RUN: llvm-readobj -symbols %t | FileCheck %s
4; RUN: llvm-readobj --symbols %t | FileCheck %s
55
66; CHECK: Symbols [
77; CHECK-NEXT: Symbol {
......@@ -71,3 +71,5 @@ define void @foo() {
7171define internal void @bar() {
7272 ret void
7373}
74
75declare i32 @baz(...)
deps/lld/test/ELF/lto/resolution.ll+1-1
......@@ -2,7 +2,7 @@
22; RUN: llvm-as %s -o %t1.o
33; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2.o -filetype=obj
44; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
5; RUN: llvm-readobj -s --section-data %t.so | FileCheck %s
5; RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
66
77; CHECK: Name: .data
88; CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/lto/riscv32.ll created+10
......@@ -0,0 +1,10 @@
1; REQUIRES: riscv
2
3; RUN: llvm-as %s -o %t.o
4; RUN: ld.lld %t.o -o %t
5target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
6target triple = "riscv32-unknown-elf"
7
8define void @f() {
9 ret void
10}
deps/lld/test/ELF/lto/riscv64.ll created+10
......@@ -0,0 +1,10 @@
1; REQUIRES: riscv
2
3; RUN: llvm-as %s -o %t.o
4; RUN: ld.lld %t.o -o %t
5target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
6target triple = "riscv64-unknown-elf"
7
8define void @f() {
9 ret void
10}
deps/lld/test/ELF/lto/setting-dso-local.ll+1-1
......@@ -2,7 +2,7 @@
22; RUN: llvm-as %s -o %t1.o
33; RUN: not ld.lld -o %t %t1.o 2>&1 | FileCheck %s
44
5; CHECK: undefined symbol: foobar
5; CHECK: undefined hidden symbol: foobar
66
77; We used to crash setting foobar to non-dso_local
88
deps/lld/test/ELF/lto/shlib-undefined.ll+1-1
......@@ -4,7 +4,7 @@
44; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o
55; RUN: ld.lld -shared %t2.o -o %t2.so
66; RUN: ld.lld -o %t %t.o %t2.so
7; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
7; RUN: llvm-readobj --dyn-syms %t | FileCheck %s
88
99; CHECK: Name: __progname
1010; CHECK-NEXT: Value: 0x201010
deps/lld/test/ELF/lto/thinlto-cant-write-index.ll+2-1
......@@ -7,8 +7,9 @@
77; Ensure lld generates error if unable to write to index files
88; RUN: rm -f %t2.o.thinlto.bc
99; RUN: touch %t2.o.thinlto.bc
10; RUN: chmod 400 %t2.o.thinlto.bc
10; RUN: chmod u-w %t2.o.thinlto.bc
1111; RUN: not ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t2.o -o %t3 2>&1 | FileCheck %s
12; RUN: chmod u+w %t2.o.thinlto.bc
1213; CHECK: cannot open {{.*}}2.o.thinlto.bc: {{P|p}}ermission denied
1314
1415target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
deps/lld/test/ELF/lto/thinlto-index-only.ll+4-8
......@@ -38,15 +38,11 @@
3838; RUN: ls %t1.o.thinlto.bc
3939; RUN: ls %t1.o.imports
4040
41; Ensure lld generates an error if unable to write an empty index file
42; for lazy object file that is not added to link.
43; RUN: rm -f %t1.o.thinlto.bc
44; RUN: touch %t1.o.thinlto.bc
45; RUN: chmod 400 %t1.o.thinlto.bc
46; RUN: not ld.lld --plugin-opt=thinlto-index-only -shared %t2.o --start-lib %t1.o --end-lib \
47; RUN: -o %t3 2>&1 | FileCheck %s
48; CHECK: cannot open {{.*}}1.o.thinlto.bc: {{P|p}}ermission denied
41; Ensure LLD generates an empty index for each bitcode file even if all bitcode files are lazy.
4942; RUN: rm -f %t1.o.thinlto.bc
43; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu /dev/null -o %tdummy.o
44; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %tdummy.o --start-lib %t1.o --end-lib -o /dev/null
45; RUN: ls %t1.o.thinlto.bc
5046
5147; NM: T f
5248
deps/lld/test/ELF/lto/tls-preserve.ll+1-1
......@@ -2,7 +2,7 @@
22; REQUIRES: x86
33; RUN: llvm-as %s -o %t1.o
44; RUN: ld.lld -shared %t1.o -o %t1
5; RUN: llvm-readobj -t %t1 | FileCheck %s
5; RUN: llvm-readobj --symbols %t1 | FileCheck %s
66
77target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
88target triple = "x86_64-unknown-linux-gnu"
deps/lld/test/ELF/lto/undef-mixed.ll+1-1
......@@ -2,7 +2,7 @@
22; RUN: llvm-mc %p/Inputs/undef-mixed.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
33; RUN: llvm-as %s -o %t2.o
44; RUN: ld.lld %t2.o %t.o -o %t.so -shared
5; RUN: llvm-readobj -t %t.so | FileCheck %s
5; RUN: llvm-readobj --symbols %t.so | FileCheck %s
66
77; CHECK: Name: bar
88; CHECK-NEXT: Value:
deps/lld/test/ELF/lto/undef-weak.ll+1-1
......@@ -5,7 +5,7 @@
55
66; RUN: llvm-as %s -o %t2.o
77; RUN: ld.lld %t2.o -o %t2.so %t.a -shared
8; RUN: llvm-readobj -t %t2.so | FileCheck %s
8; RUN: llvm-readobj --symbols %t2.so | FileCheck %s
99
1010target triple = "x86_64-unknown-linux-gnu"
1111target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
deps/lld/test/ELF/lto/undef.ll+1-1
......@@ -1,7 +1,7 @@
11; REQUIRES: x86
22; RUN: llvm-as %s -o %t.o
33; RUN: ld.lld %t.o -o %t.so -shared
4; RUN: llvm-readobj -t %t.so | FileCheck %s
4; RUN: llvm-readobj --symbols %t.so | FileCheck %s
55target triple = "x86_64-unknown-linux-gnu"
66target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
77
deps/lld/test/ELF/lto/undefined-puts.ll+2-2
......@@ -3,7 +3,7 @@
33; RUN: ld.lld %t1.o -o %t1.so -shared
44; RUN: llvm-as %s -o %t2.o
55; RUN: ld.lld %t1.so %t2.o -o %t
6; RUN: llvm-readobj -dyn-symbols -dyn-relocations %t | FileCheck %s
6; RUN: llvm-readobj --dyn-syms --dyn-relocations %t | FileCheck %s
77
88target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
99target triple = "x86_64-unknown-linux-gnu"
......@@ -20,7 +20,7 @@ declare i32 @printf(i8*, ...)
2020; Check that puts symbol is present in the dynamic symbol table and
2121; there's a relocation for it.
2222; CHECK: Dynamic Relocations {
23; CHECK-NEXT: 0x202018 R_X86_64_JUMP_SLOT puts 0x0
23; CHECK-NEXT: 0x203018 R_X86_64_JUMP_SLOT puts 0x0
2424; CHECK-NEXT: }
2525
2626; CHECK: DynamicSymbols [
deps/lld/test/ELF/lto/version-script.ll+1-1
......@@ -3,7 +3,7 @@
33; RUN: echo "VERSION_1.0{ global: foo; local: *; }; VERSION_2.0{ global: bar; local: *; };" > %t.script
44; RUN: ld.lld %t.o -o %t2 -shared --version-script %t.script -save-temps
55; RUN: llvm-dis < %t2.0.0.preopt.bc | FileCheck %s
6; RUN: llvm-readobj -V -dyn-symbols %t2 | FileCheck --check-prefix=DSO %s
6; RUN: llvm-readobj -V --dyn-syms %t2 | FileCheck --check-prefix=DSO %s
77
88target triple = "x86_64-unknown-linux-gnu"
99target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
deps/lld/test/ELF/lto/version-script2.ll+1-1
......@@ -2,7 +2,7 @@
22; RUN: llvm-as %s -o %t.o
33; RUN: echo "VER1 {};" > %t.script
44; RUN: ld.lld %t.o -o %t.so -shared --version-script %t.script
5; RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
5; RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
66
77; test that we have the correct version.
88; CHECK: Name: foo@@VER1 (
deps/lld/test/ELF/lto/visibility.ll+2-2
......@@ -3,7 +3,7 @@
33; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2.o -filetype=obj
44; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps
55; RUN: llvm-dis < %t.so.0.2.internalize.bc | FileCheck --check-prefix=IR %s
6; RUN: llvm-readobj -t %t.so | FileCheck %s
6; RUN: llvm-readobj --symbols %t.so | FileCheck %s
77
88; CHECK: Name: g
99; CHECK-NEXT: Value: 0x1000
......@@ -16,7 +16,7 @@
1616; CHECK-NEXT: Section: .text
1717
1818; CHECK: Name: a
19; CHECK-NEXT: Value: 0x2000
19; CHECK-NEXT: Value: 0x3000
2020; CHECK-NEXT: Size: 0
2121; CHECK-NEXT: Binding: Local
2222; CHECK-NEXT: Type: None
deps/lld/test/ELF/lto/weak.ll+1-1
......@@ -1,7 +1,7 @@
11; REQUIRES: x86
22; RUN: llvm-as %s -o %t.o
33; RUN: ld.lld %t.o %t.o -o %t.so -shared
4; RUN: llvm-readobj -t %t.so | FileCheck %s
4; RUN: llvm-readobj --symbols %t.so | FileCheck %s
55
66target triple = "x86_64-unknown-linux-gnu"
77target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
deps/lld/test/ELF/lto/weakodr-visibility.ll+2-2
......@@ -9,7 +9,7 @@
99; but keeps `protected` visibility.
1010
1111; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
12; RUN: llvm-readobj -t %t.so | FileCheck %s
12; RUN: llvm-readobj --symbols %t.so | FileCheck %s
1313; RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=FIRST
1414; CHECK: Symbol {
1515; CHECK: Name: foo
......@@ -27,7 +27,7 @@
2727
2828; Now swap the files order.
2929; RUN: ld.lld %t2.o %t1.o -o %t.so -shared
30; RUN: llvm-readobj -t %t.so | FileCheck %s
30; RUN: llvm-readobj --symbols %t.so | FileCheck %s
3131; RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=SECOND
3232; SECOND: foo:
3333; SECOND-NEXT: movl $42, %eax
deps/lld/test/ELF/lto/wrap-1.ll+2-2
......@@ -2,13 +2,13 @@
22; LTO
33; RUN: llvm-as %s -o %t.o
44; RUN: ld.lld %t.o -o %t.out -wrap=bar -save-temps
5; RUN: llvm-readobj -t %t.out | FileCheck %s
5; RUN: llvm-readobj --symbols %t.out | FileCheck %s
66; RUN: cat %t.out.resolution.txt | FileCheck -check-prefix=RESOLS %s
77
88; ThinLTO
99; RUN: opt -module-summary %s -o %t.o
1010; RUN: ld.lld %t.o -o %t.out -wrap=bar -save-temps
11; RUN: llvm-readobj -t %t.out | FileCheck %s
11; RUN: llvm-readobj --symbols %t.out | FileCheck %s
1212; RUN: cat %t.out.resolution.txt | FileCheck -check-prefix=RESOLS %s
1313
1414; CHECK: Name: __wrap_bar
deps/lld/test/ELF/lto/wrap-2.ll+5-10
......@@ -4,14 +4,14 @@
44; RUN: llvm-as %S/Inputs/wrap-bar.ll -o %t1.o
55; RUN: ld.lld %t.o %t1.o -shared -o %t.so -wrap=bar
66; RUN: llvm-objdump -d %t.so | FileCheck %s
7; RUN: llvm-readobj -t %t.so | FileCheck -check-prefix=BIND %s
7; RUN: llvm-readobj --symbols %t.so | FileCheck -check-prefix=BIND %s
88
99; ThinLTO
1010; RUN: opt -module-summary %s -o %t.o
1111; RUN: opt -module-summary %S/Inputs/wrap-bar.ll -o %t1.o
1212; RUN: ld.lld %t.o %t1.o -shared -o %t.so -wrap=bar
13; RUN: llvm-objdump -d %t.so | FileCheck %s -check-prefix=THIN
14; RUN: llvm-readobj -t %t.so | FileCheck -check-prefix=BIND %s
13; RUN: llvm-objdump -d %t.so | FileCheck %s
14; RUN: llvm-readobj --symbols %t.so | FileCheck -check-prefix=BIND %s
1515
1616; Make sure that calls in foo() are not eliminated and that bar is
1717; routed to __wrap_bar and __real_bar is routed to bar.
......@@ -19,13 +19,8 @@
1919; CHECK: foo:
2020; CHECK-NEXT: pushq %rax
2121; CHECK-NEXT: callq{{.*}}<__wrap_bar>
22; CHECK-NEXT: callq{{.*}}<bar>
23
24; THIN: foo:
25; THIN-NEXT: pushq %rax
26; THIN-NEXT: callq{{.*}}<__wrap_bar>
27; THIN-NEXT: popq %rax
28; THIN-NEXT: jmp{{.*}}<bar>
22; CHECK-NEXT: popq %rax
23; CHECK-NEXT: jmp{{.*}}<bar>
2924
3025; Check that bar and __wrap_bar retain their original binding.
3126; BIND: Name: bar
deps/lld/test/ELF/magic-page-combo-warn.s created+86
......@@ -0,0 +1,86 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# Test that we warn when a page size is set and paging is disabled by -n or -N.
5
6# RUN: ld.lld -z max-page-size=0x10 -z common-page-size=0x10 -N %t -o %t2 2>&1 | FileCheck --check-prefix=WARN %s
7# RUN: llvm-readobj --program-headers %t2 | FileCheck --check-prefix=OMAGIC %s
8# RUN: ld.lld -z max-page-size=0x10 -z common-page-size=0x10 --omagic %t -o %t2 2>&1 | FileCheck --check-prefix=WARN %s
9# RUN: llvm-readobj --program-headers %t2 | FileCheck --check-prefix=OMAGIC %s
10
11# WARN: ld.lld: warning: -z max-page-size set, but paging disabled by omagic or nmagic
12# WARN-NEXT: ld.lld: warning: -z common-page-size set, but paging disabled by omagic or nmagic
13
14# OMAGIC: ProgramHeader {
15# OMAGIC: Type: PT_LOAD
16# OMAGIC-NEXT: Offset: 0xE8
17# OMAGIC-NEXT: VirtualAddress:
18# OMAGIC-NEXT: PhysicalAddress:
19# OMAGIC-NEXT: FileSize:
20# OMAGIC-NEXT: MemSize:
21# OMAGIC-NEXT: Flags [
22# OMAGIC-NEXT: PF_R
23# OMAGIC-NEXT: PF_W
24# OMAGIC-NEXT: PF_X
25# OMAGIC-NEXT: ]
26# OMAGIC-NEXT: Alignment: 8
27# OMAGIC-NEXT: }
28# OMAGIC-NEXT: ProgramHeader {
29# OMAGIC-NEXT: Type: PT_GNU_STACK
30
31# RUN: ld.lld -z max-page-size=0x10 -z common-page-size=0x10 -n %t -o %t3 2>&1 | FileCheck --check-prefix=WARN %s
32# RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=NMAGIC %s
33# RUN: ld.lld -z max-page-size=0x10 -z common-page-size=0x10 --nmagic %t -o %t3 2>&1 | FileCheck --check-prefix=WARN %s
34# RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=NMAGIC %s
35
36# NMAGIC: ProgramHeader {
37# NMAGIC-NEXT: Type: PT_LOAD
38# NMAGIC-NEXT: Offset: 0x158
39# NMAGIC-NEXT: VirtualAddress:
40# NMAGIC-NEXT: PhysicalAddress:
41# NMAGIC-NEXT: FileSize: 1
42# NMAGIC-NEXT: MemSize: 1
43# NMAGIC-NEXT: Flags [
44# NMAGIC-NEXT: PF_R
45# NMAGIC-NEXT: ]
46# NMAGIC-NEXT: Alignment: 8
47# NMAGIC-NEXT: }
48# NMAGIC-NEXT: ProgramHeader {
49# NMAGIC-NEXT: Type: PT_LOAD
50# NMAGIC-NEXT: Offset: 0x15C
51# NMAGIC-NEXT: VirtualAddress:
52# NMAGIC-NEXT: PhysicalAddress:
53# NMAGIC-NEXT: FileSize: 2
54# NMAGIC-NEXT: MemSize: 2
55# NMAGIC-NEXT: Flags [
56# NMAGIC-NEXT: PF_R
57# NMAGIC-NEXT: PF_X
58# NMAGIC-NEXT: ]
59# NMAGIC-NEXT: Alignment: 4
60# NMAGIC-NEXT: }
61# NMAGIC-NEXT: ProgramHeader {
62# NMAGIC-NEXT: Type: PT_LOAD (0x1)
63# NMAGIC-NEXT: Offset: 0x15E
64# NMAGIC-NEXT: VirtualAddress:
65# NMAGIC-NEXT: PhysicalAddress:
66# NMAGIC-NEXT: FileSize: 1
67# NMAGIC-NEXT: MemSize: 1
68# NMAGIC-NEXT: Flags [
69# NMAGIC-NEXT: PF_R
70# NMAGIC-NEXT: PF_W
71# NMAGIC-NEXT: ]
72# NMAGIC-NEXT: Alignment: 1
73# NMAGIC-NEXT: }
74
75.global _start
76_start:
77 nop
78
79.section .ro,"a"
80nop
81
82.section .rw,"aw"
83nop
84
85.section .rx,"ax"
86nop
deps/lld/test/ELF/many-alloc-sections.s+1-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o
33// RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script
44// RUN: ld.lld -T %t.script %t.o -o %t
5// RUN: llvm-readobj -t %t | FileCheck %s
5// RUN: llvm-readobj --symbols %t | FileCheck %s
66
77// Test that _start is in the correct section.
88// CHECK: Name: _start
deps/lld/test/ELF/many-sections.s+3-3
......@@ -1,6 +1,6 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
3// RUN: llvm-readobj -t %t | FileCheck %s
3// RUN: llvm-readobj --symbols %t | FileCheck %s
44
55// Verify that the symbol _start is in a section with an index >= SHN_LORESERVE.
66// CHECK: Name: _start
......@@ -12,12 +12,12 @@
1212// CHECK-NEXT: Section: dm (0xFF00)
1313
1414// RUN: ld.lld %t -o %t2
15// RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s
15// RUN: llvm-readobj --symbols %t2 | FileCheck --check-prefix=LINKED %s
1616
1717// Test also with a linker script.
1818// RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script
1919// RUN: ld.lld -T %t.script %t -o %t2
20// RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s
20// RUN: llvm-readobj --symbols %t2 | FileCheck --check-prefix=LINKED %s
2121
2222// Test that _start is in the correct section.
2323// LINKED: Name: _start
deps/lld/test/ELF/map-file.s+27-27
......@@ -41,22 +41,22 @@ abs = 0xAB5
4141labs = 0x1AB5
4242
4343// CHECK: VMA LMA Size Align Out In Symbol
44// CHECK-NEXT: 2001c8 2001c8 78 8 .dynsym
45// CHECK-NEXT: 2001c8 2001c8 78 8 <internal>:(.dynsym)
46// CHECK-NEXT: 200240 200240 2c 8 .gnu.hash
47// CHECK-NEXT: 200240 200240 2c 8 <internal>:(.gnu.hash)
48// CHECK-NEXT: 20026c 20026c 30 4 .hash
49// CHECK-NEXT: 20026c 20026c 30 4 <internal>:(.hash)
50// CHECK-NEXT: 20029c 20029c 31 1 .dynstr
51// CHECK-NEXT: 20029c 20029c 31 1 <internal>:(.dynstr)
52// CHECK-NEXT: 2002d0 2002d0 30 8 .rela.dyn
53// CHECK-NEXT: 2002d0 2002d0 30 8 <internal>:(.rela.dyn)
54// CHECK-NEXT: 200300 200300 30 8 .rela.plt
55// CHECK-NEXT: 200300 200300 30 8 <internal>:(.rela.plt)
56// CHECK-NEXT: 200330 200330 64 8 .eh_frame
57// CHECK-NEXT: 200330 200330 2c 1 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x0)
58// CHECK-NEXT: 200360 200360 14 1 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x2c)
59// CHECK-NEXT: 200378 200378 18 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.eh_frame+0x18)
44// CHECK-NEXT: 200200 200200 78 8 .dynsym
45// CHECK-NEXT: 200200 200200 78 8 <internal>:(.dynsym)
46// CHECK-NEXT: 200278 200278 2c 8 .gnu.hash
47// CHECK-NEXT: 200278 200278 2c 8 <internal>:(.gnu.hash)
48// CHECK-NEXT: 2002a4 2002a4 30 4 .hash
49// CHECK-NEXT: 2002a4 2002a4 30 4 <internal>:(.hash)
50// CHECK-NEXT: 2002d4 2002d4 31 1 .dynstr
51// CHECK-NEXT: 2002d4 2002d4 31 1 <internal>:(.dynstr)
52// CHECK-NEXT: 200308 200308 30 8 .rela.dyn
53// CHECK-NEXT: 200308 200308 30 8 <internal>:(.rela.dyn)
54// CHECK-NEXT: 200338 200338 30 8 .rela.plt
55// CHECK-NEXT: 200338 200338 30 8 <internal>:(.rela.plt)
56// CHECK-NEXT: 200368 200368 64 8 .eh_frame
57// CHECK-NEXT: 200368 200368 2c 1 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x0)
58// CHECK-NEXT: 200398 200398 14 1 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x2c)
59// CHECK-NEXT: 2003b0 2003b0 18 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.eh_frame+0x18)
6060// CHECK-NEXT: 201000 201000 2d 4 .text
6161// CHECK-NEXT: 201000 201000 28 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text)
6262// CHECK-NEXT: 201000 201000 0 1 _start
......@@ -75,17 +75,17 @@ labs = 0x1AB5
7575// CHECK-NEXT: 201030 201030 30 16 <internal>:(.plt)
7676// CHECK-NEXT: 201040 201040 0 1 sharedFunc1
7777// CHECK-NEXT: 201050 201050 0 1 sharedFunc2
78// CHECK-NEXT: 202000 202000 28 8 .got.plt
79// CHECK-NEXT: 202000 202000 28 8 <internal>:(.got.plt)
80// CHECK-NEXT: 203000 203000 100 8 .dynamic
81// CHECK-NEXT: 203000 203000 100 8 <internal>:(.dynamic)
82// CHECK-NEXT: 204000 204000 10 16 .bss
83// CHECK-NEXT: 204000 204000 4 16 {{.*}}{{/|\\}}map-file.s.tmp1.o:(COMMON)
84// CHECK-NEXT: 204000 204000 4 1 common
85// CHECK-NEXT: 204004 204004 4 1 <internal>:(.bss)
86// CHECK-NEXT: 204004 204004 4 1 sharedFoo
87// CHECK-NEXT: 204008 204008 8 1 <internal>:(.bss)
88// CHECK-NEXT: 204008 204008 8 1 sharedBar
78// CHECK-NEXT: 202000 202000 100 8 .dynamic
79// CHECK-NEXT: 202000 202000 100 8 <internal>:(.dynamic)
80// CHECK-NEXT: 203000 203000 28 8 .got.plt
81// CHECK-NEXT: 203000 203000 28 8 <internal>:(.got.plt)
82// CHECK-NEXT: 203030 203030 10 16 .bss
83// CHECK-NEXT: 203030 203030 4 16 {{.*}}{{/|\\}}map-file.s.tmp1.o:(COMMON)
84// CHECK-NEXT: 203030 203030 4 1 common
85// CHECK-NEXT: 203034 203034 4 1 <internal>:(.bss)
86// CHECK-NEXT: 203034 203034 4 1 sharedFoo
87// CHECK-NEXT: 203038 203038 8 1 <internal>:(.bss)
88// CHECK-NEXT: 203038 203038 8 1 sharedBar
8989// CHECK-NEXT: 0 0 8 1 .comment
9090// CHECK-NEXT: 0 0 8 1 <internal>:(.comment)
9191// CHECK-NEXT: 0 0 198 8 .symtab
deps/lld/test/ELF/merge-align.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 -o %t.so -shared
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
55
66 .section .rodata.foo,"aM",@progbits,1
77 .align 16
deps/lld/test/ELF/merge-align2.s created+35
......@@ -0,0 +1,35 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC %s
6# RUN: llvm-readelf -x .cst8 %t | FileCheck %s
7
8# RUN: ld.lld -O0 -r %t.o -o %t1.o
9# RUN: llvm-readelf -S %t1.o | FileCheck --check-prefix=SEC %s
10# RUN: llvm-readelf -x .cst8 %t1.o | FileCheck %s
11
12## Check that if we have SHF_MERGE sections with the same name, flags and
13## entsize, but different alignments, we combine them with the maximum input
14## alignment as the output alignment.
15
16# SEC: Name Type {{.*}} Size ES Flg Lk Inf Al
17# SEC: .cst8 PROGBITS {{.*}} 000018 08 AM 0 0 8
18
19# CHECK: 0x{{[0-9a-f]+}} 02000000 00000000 01000000 00000000
20# CHECK-NEXT: 0x{{[0-9a-f]+}} 03000000 00000000
21
22.section .cst8,"aM",@progbits,8,unique,0
23.align 4
24.quad 1
25.quad 1
26
27.section .cst8,"aM",@progbits,8,unique,1
28.align 4
29.quad 1
30.quad 2
31
32.section .cst8,"aM",@progbits,8,unique,2
33.align 8
34.quad 1
35.quad 3
deps/lld/test/ELF/merge-entsize.s+8-3
......@@ -1,13 +1,18 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -s %t | FileCheck %s
4// RUN: llvm-readobj -S %t | FileCheck %s
55
66 .section .rodata.1,"aM",@progbits,1
7 .p2align 2
78 .byte 0x42
89
9 .section .rodata.2,"aM",@progbits,2
10// sh_addralign = 4 while sh_entsize = 3.
11// sh_entsize is not necessarily a power of 2 and it can be unrelated to sh_addralign.
12 .section .rodata.2,"aM",@progbits,3
13 .p2align 2
1014 .short 0x42
15 .byte 0
1116
1217// Since the output section has both .rodata.1 and .rodata.2, it
1318// contains elements of different sizes and we use an entsize of 0.
......@@ -23,5 +28,5 @@
2328// CHECK-NEXT: Size:
2429// CHECK-NEXT: Link:
2530// CHECK-NEXT: Info:
26// CHECK-NEXT: AddressAlignment:
31// CHECK-NEXT: AddressAlignment: 4
2732// CHECK-NEXT: EntrySize: 0
deps/lld/test/ELF/merge-entsize2.s created+49
......@@ -0,0 +1,49 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC %s
6# RUN: llvm-readelf -x .cst %t | FileCheck --check-prefix=HEX %s
7
8# RUN: ld.lld -O0 -r %t.o -o %t1.o
9# RUN: llvm-readelf -S %t1.o | FileCheck --check-prefix=SEC-R %s
10# RUN: llvm-readelf -x .cst %t1.o | FileCheck --check-prefix=HEX-R %s
11
12## Check that SHF_MERGE sections with the same name, sh_flags and sh_entsize
13## are grouped together and can be merged within the group.
14
15## .cst 0 and .cst 1 are merged (sh_entsize=4). The result and .cst 2 and
16## combined (sh_entsize=8). The output sh_entsize is 0.
17# SEC: Name Type {{.*}} Size ES Flg Lk Inf Al
18# SEC: .cst PROGBITS {{.*}} 000020 00 AM 0 0 8
19
20## .cst 0 and .cst 1 are merged, but emitted as a separate output section.
21# SEC-R: .cst PROGBITS {{.*}} 00000c 04 AM 0 0 4
22# SEC-R: .cst PROGBITS {{.*}} 000010 08 AM 0 0 8
23
24# HEX: Hex dump of section '.cst':
25# HEX-NEXT: 0x{{[0-9a-f]+}} 01000000 00000000 02000000 00000000
26# HEX-NEXT: 0x{{[0-9a-f]+}} 01000000 00000000 03000000 00000000
27
28# HEX-R: Hex dump of section '.cst':
29# HEX-R-NEXT: 0x00000000 01000000 00000000 02000000
30# HEX-R-EMPTY:
31# HEX-R-NEXT: Hex dump of section '.cst':
32# HEX-R-NEXT: 0x00000000 01000000 00000000 03000000 00000000
33
34.section .cst,"aM",@progbits,4,unique,0
35.align 2
36.long 1
37.long 0
38.long 2
39
40.section .cst,"aM",@progbits,4,unique,1
41.align 4
42.long 1
43.long 0
44.long 2
45
46.section .cst,"aM",@progbits,8,unique,2
47.align 8
48.quad 1
49.quad 3
deps/lld/test/ELF/merge-gc-piece.s+3-3
......@@ -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 -o %t.so -shared --gc-sections
4# RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4# RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
55
66
77# CHECK: Name: .foo
......@@ -10,7 +10,7 @@
1010# CHECK-NEXT: SHF_ALLOC
1111# CHECK-NEXT: SHF_MERGE
1212# CHECK-NEXT: ]
13# CHECK-NEXT: Address: 0x200
13# CHECK-NEXT: Address: 0x1FD
1414
1515# CHECK: Name: .bar
1616# CHECK-NEXT: Type: SHT_PROGBITS
......@@ -24,7 +24,7 @@
2424# CHECK-NEXT: AddressAlignment:
2525# CHECK-NEXT: EntrySize:
2626# CHECK-NEXT: SectionData (
27# CHECK-NEXT: 0000: 01020000 00000000 02020000 00000000
27# CHECK-NEXT: 0000: FE010000 00000000 FF010000 00000000
2828# CHECK-NEXT: )
2929
3030 .section .foo,"aM",@progbits,8
deps/lld/test/ELF/merge-gc-piece2.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 -o %t.so -shared --gc-sections
4# RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4# RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
55
66# CHECK: Name: .bar
77# CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/merge-reloc-O0.s deleted-48
......@@ -1,48 +0,0 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -r -o %t2.o -O0
4# RUN: llvm-readobj -s -section-data %t2.o | FileCheck %s
5
6# We combine just the sections with the same name and sh_entsize.
7
8# CHECK: Name: .foo
9# CHECK-NEXT: Type: SHT_PROGBITS
10# CHECK-NEXT: Flags [
11# CHECK-NEXT: SHF_ALLOC
12# CHECK-NEXT: SHF_MERGE
13# CHECK-NEXT: ]
14# CHECK-NEXT: Address:
15# CHECK-NEXT: Offset:
16# CHECK-NEXT: Size: 16
17# CHECK-NEXT: Link:
18# CHECK-NEXT: Info:
19# CHECK-NEXT: AddressAlignment: 8
20# CHECK-NEXT: EntrySize: 8
21# CHECK-NEXT: SectionData (
22# CHECK-NEXT: 0000: 41000000 00000000 42000000 00000000
23# CHECK-NEXT: )
24
25# CHECK: Name: .foo
26# CHECK-NEXT: Type: SHT_PROGBITS
27# CHECK-NEXT: Flags [
28# CHECK-NEXT: SHF_ALLOC
29# CHECK-NEXT: SHF_MERGE
30# CHECK-NEXT: ]
31# CHECK-NEXT: Address:
32# CHECK-NEXT: Offset:
33# CHECK-NEXT: Size: 8
34# CHECK-NEXT: Link:
35# CHECK-NEXT: Info:
36# CHECK-NEXT: AddressAlignment: 4
37# CHECK-NEXT: EntrySize: 4
38# CHECK-NEXT: SectionData (
39# CHECK-NEXT: 0000: 41000000 42000000
40# CHECK-NEXT: )
41
42 .section .foo, "aM",@progbits,8,unique,0
43 .quad 0x41
44 .section .foo, "aM",@progbits,8,unique,1
45 .quad 0x42
46 .section .foo, "aM",@progbits,4,unique,2
47 .long 0x41
48 .long 0x42
deps/lld/test/ELF/merge-reloc.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 -r -o %t-rel
4# RUN: llvm-readobj -s -section-data %t-rel | FileCheck %s
4# RUN: llvm-readobj -S --section-data %t-rel | FileCheck %s
55
66# When linker generates a relocatable object it does string merging in the same
77# way as for regular link. It should keep SHF_MERGE flag and set proper sh_entsize
deps/lld/test/ELF/merge-section-types.s+3-3
......@@ -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 -shared %t.o -o %t
4// RUN: llvm-readobj -s %t | FileCheck %s
4// RUN: llvm-readobj -S %t | FileCheck %s
55
66// CHECK: Name: .foo
77// CHECK-NEXT: Type: SHT_PROGBITS
......@@ -9,8 +9,8 @@
99// CHECK-NEXT: SHF_ALLOC
1010// CHECK-NEXT: SHF_WRITE
1111// CHECK-NEXT: ]
12// CHECK-NEXT: Address: 0x1000
13// CHECK-NEXT: Offset: 0x1000
12// CHECK-NEXT: Address: 0x2000
13// CHECK-NEXT: Offset: 0x2000
1414// CHECK-NEXT: Size: 16
1515
1616.section .foo, "aw", @progbits, unique, 1
deps/lld/test/ELF/merge-shared-str.s+3-3
......@@ -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 -o %t.so -shared -O3
4// RUN: llvm-readobj -r -s %t.so | FileCheck %s
4// RUN: llvm-readobj -r -S %t.so | FileCheck %s
55
66
77 .section foo,"aMS",@progbits,1
......@@ -19,10 +19,10 @@
1919// CHECK-NEXT: SHF_MERGE
2020// CHECK-NEXT: SHF_STRINGS
2121// CHECK-NEXT: ]
22// CHECK-NEXT: Address: 0x228
22// CHECK-NEXT: Address: 0x260
2323
2424// CHECK: Relocations [
2525// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
26// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x229
26// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x261
2727// CHECK-NEXT: }
2828// CHECK-NEXT: ]
deps/lld/test/ELF/merge-shared.s+3-3
......@@ -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 -o %t.so -shared
4// RUN: llvm-readobj -r -s %t.so | FileCheck %s
4// RUN: llvm-readobj -r -S %t.so | FileCheck %s
55
66 .section foo,"aM",@progbits,4
77 .long 42
......@@ -17,10 +17,10 @@
1717// CHECK-NEXT: SHF_ALLOC
1818// CHECK-NEXT: SHF_MERGE
1919// CHECK-NEXT: ]
20// CHECK-NEXT: Address: 0x228
20// CHECK-NEXT: Address: 0x260
2121
2222// CHECK: Relocations [
2323// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
24// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x22A
24// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x262
2525// CHECK-NEXT: }
2626// CHECK-NEXT: ]
deps/lld/test/ELF/merge-string-align.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 -o %t.so -shared
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
55
66 .section .rodata.foo,"aMS",@progbits,1
77 .align 16
deps/lld/test/ELF/merge-string-align2.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC %s
6# RUN: llvm-readelf -x .rodata %t | FileCheck %s
7
8# SEC: Name Type {{.*}} Size ES Flg Lk Inf Al
9# SEC: .rodata PROGBITS {{.*}} 000006 01 AMS 0 0 8
10
11## Check there is no extra padding.
12
13# CHECK: a.b.c.
14
15.section .rodata.str1.8,"aMS",@progbits,1
16.align 8
17.asciz "a"
18
19.section .rodata.str1.2,"aMS",@progbits,1
20.align 2
21.asciz "b"
22
23.section .rodata.str1.1,"aMS",@progbits,1
24.align 1
25.asciz "c"
deps/lld/test/ELF/merge-string-error.s+1-1
......@@ -6,6 +6,6 @@
66 .asciz "abc"
77
88 .data
9 .long .rodata.str1.1 + 4
9 .quad .rodata.str1.1 + 4
1010
1111// CHECK: merge-string-error.s.tmp.o:(.rodata.str1.1): offset is outside the section
deps/lld/test/ELF/merge-string.s+3-3
......@@ -1,11 +1,11 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: ld.lld -O 2 %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data --symbols %t.so | FileCheck %s
55// RUN: ld.lld -O 1 %t.o -o %t.so -shared
6// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOTAIL %s
6// RUN: llvm-readobj -S --section-data --symbols %t.so | FileCheck --check-prefix=NOTAIL %s
77// RUN: ld.lld -O 0 %t.o -o %t.so -shared
8// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOMERGE %s
8// RUN: llvm-readobj -S --section-data --symbols %t.so | FileCheck --check-prefix=NOMERGE %s
99
1010 .section .rodata1,"aMS",@progbits,1
1111 .asciz "abc"
deps/lld/test/ELF/merge-sym.s+3-3
......@@ -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 -o %t.so -shared
4// RUN: llvm-readobj -t -s %t.so | FileCheck %s
4// RUN: llvm-readobj --symbols -S %t.so | FileCheck %s
55
66 .section .rodata.cst4,"aM",@progbits,4
77 .short 0
......@@ -15,7 +15,7 @@ foo:
1515// CHECK-NEXT: SHF_ALLOC
1616// CHECK-NEXT: SHF_MERGE
1717// CHECK-NEXT: ]
18// CHECK-NEXT: Address: 0x210
18// CHECK-NEXT: Address: 0x20D
1919
2020// CHECK: Name: foo
21// CHECK-NEXT: Value: 0x212
21// CHECK-NEXT: Value: 0x20F
deps/lld/test/ELF/merge-to-non-alloc.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 -o %t.so -shared
4// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data --symbols %t.so | FileCheck %s
55
66// CHECK: Name: .bar
77// CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/merge.s+2-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/merge.s -o %t2.o
44// RUN: ld.lld %t.o %t2.o -o %t
5// RUN: llvm-readobj -s -section-data -t %t | FileCheck %s
5// RUN: llvm-readobj -S --section-data --symbols %t | FileCheck %s
66// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
77
88 .section .mysec,"aM",@progbits,4
......@@ -72,6 +72,7 @@ zed:
7272 .globl _start
7373_start:
7474// DISASM: Disassembly of section .text:
75// DISASM-EMPTY:
7576// DISASM-NEXT: _start:
7677
7778 movl .mysec, %eax
deps/lld/test/ELF/mips-26-mask.s+1
......@@ -6,6 +6,7 @@
66# RUN: llvm-objdump -d %t.exe | FileCheck %s
77
88# CHECK: Disassembly of section .text:
9# CHECK-EMPTY:
910# CHECK: __start:
1011# CHECK-NEXT: 20000: 0e 00 80 00 jal 134348800
1112
deps/lld/test/ELF/mips-26-n32-n64.s deleted-40
......@@ -1,40 +0,0 @@
1# REQUIRES: mips
2# Check R_MIPS_26 relocation handling in case of N64 ABIs.
3
4# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
5# RUN: %S/Inputs/mips-dynamic.s -o %t-so.o
6# RUN: ld.lld %t-so.o -shared -o %t.so
7# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
8# RUN: ld.lld %t.o %t.so -o %t.exe
9# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=CHECK,DEFAULT
10# RUN: ld.lld %t-so.o -shared -o %t.so -z hazardplt
11# RUN: ld.lld %t.o %t.so -o %t.exe -z hazardplt
12# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=CHECK,HAZARDPLT
13
14
15# CHECK: Disassembly of section .text:
16# CHECK-NEXT: __start:
17# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120
18# CHECK-NEXT: 20004: 00 00 00 00 nop
19# CHECK-NEXT: Disassembly of section .plt:
20# CHECK-NEXT: .plt:
21# CHECK-NEXT: 20010: 3c 0e 00 03 lui $14, 3
22# CHECK-NEXT: 20014: dd d9 00 08 ld $25, 8($14)
23# CHECK-NEXT: 20018: 25 ce 00 08 addiu $14, $14, 8
24# CHECK-NEXT: 2001c: 03 0e c0 23 subu $24, $24, $14
25# CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra
26# CHECK-NEXT: 20024: 00 18 c0 c2 srl $24, $24, 3
27# DEFAULT: 20028: 03 20 f8 09 jalr $25
28# HAZARDPLT: 20028: 03 20 fc 09 jalr.hb $25
29# CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2
30# CHECK-NEXT: 20030: 3c 0f 00 03 lui $15, 3
31# CHECK-NEXT: 20034: 8d f9 00 18 lw $25, 24($15)
32# DEFAULT: 20038: 03 20 00 08 jr $25
33# HAZARDPLT: 20038: 03 20 04 08 jr.hb $25
34# CHECK-NEXT: 2003c: 25 f8 00 18 addiu $24, $15, 24
35
36 .text
37 .option pic0
38 .global __start
39__start:
40 jal foo0
deps/lld/test/ELF/mips-26.s+4-1
......@@ -7,10 +7,11 @@
77# RUN: ld.lld %t2.o -shared -o %t.so
88# RUN: ld.lld %t1.o %t.so -o %t.exe
99# RUN: llvm-objdump -d %t.exe | FileCheck %s
10# RUN: llvm-readobj -dynamic-table -s -r -mips-plt-got %t.exe \
10# RUN: llvm-readobj --dynamic-table -S -r --mips-plt-got %t.exe \
1111# RUN: | FileCheck -check-prefix=REL %s
1212
1313# CHECK: Disassembly of section .text:
14# CHECK-EMPTY:
1415# CHECK-NEXT: bar:
1516# CHECK-NEXT: 20000: 0c 00 80 06 jal 131096 <loc>
1617# CHECK-NEXT: 20004: 00 00 00 00 nop
......@@ -24,7 +25,9 @@
2425#
2526# CHECK: loc:
2627# CHECK-NEXT: 20018: 00 00 00 00 nop
28# CHECK-EMPTY:
2729# CHECK-NEXT: Disassembly of section .plt:
30# CHECK-EMPTY:
2831# CHECK-NEXT: .plt:
2932# CHECK-NEXT: 20020: 3c 1c 00 03 lui $gp, 3
3033# CHECK-NEXT: 20024: 8f 99 00 04 lw $25, 4($gp)
deps/lld/test/ELF/mips-32.s+4-6
......@@ -3,16 +3,14 @@
33
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
55# RUN: ld.lld -shared %t-be.o -o %t-be.so
6# RUN: llvm-objdump -t -s %t-be.so \
7# RUN: | FileCheck -check-prefix=SYM -check-prefix=BE %s
8# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-be.so \
6# RUN: llvm-objdump -t -s %t-be.so | FileCheck -check-prefixes=SYM,BE %s
7# RUN: llvm-readobj -r --dynamic-table --mips-plt-got %t-be.so \
98# RUN: | FileCheck -check-prefix=REL %s
109
1110# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
1211# RUN: ld.lld -shared %t-el.o -o %t-el.so
13# RUN: llvm-objdump -t -s %t-el.so \
14# RUN: | FileCheck -check-prefix=SYM -check-prefix=EL %s
15# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-el.so \
12# RUN: llvm-objdump -t -s %t-el.so | FileCheck -check-prefixes=SYM,EL %s
13# RUN: llvm-readobj -r --dynamic-table --mips-plt-got %t-el.so \
1614# RUN: | FileCheck -check-prefix=REL %s
1715
1816 .globl __start
deps/lld/test/ELF/mips-64-disp.s+19-54
......@@ -7,7 +7,7 @@
77# RUN: ld.lld %t.so.o -shared -o %t.so
88# RUN: ld.lld %t.exe.o %t.so -o %t.exe
99# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
10# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s
10# RUN: llvm-readelf -r --mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s
1111
1212# CHECK: __start:
1313# CHECK-NEXT: 20000: 24 42 80 40 addiu $2, $2, -32704
......@@ -20,59 +20,24 @@
2020# CHECK: 0000000000020000 .text 00000000 __start
2121# CHECK: 0000000000000000 g F *UND* 00000000 foo1a
2222
23# GOT: Relocations [
24# GOT-NEXT: ]
25# GOT-NEXT: Primary GOT {
26# GOT-NEXT: Canonical gp value:
27# GOT-NEXT: Reserved entries [
28# GOT-NEXT: Entry {
29# GOT-NEXT: Address:
30# GOT-NEXT: Access: -32752
31# GOT-NEXT: Initial: 0x0
32# GOT-NEXT: Purpose: Lazy resolver
33# GOT-NEXT: }
34# GOT-NEXT: Entry {
35# GOT-NEXT: Address:
36# GOT-NEXT: Access: -32744
37# GOT-NEXT: Initial: 0x8000000000000000
38# GOT-NEXT: Purpose: Module pointer (GNU extension)
39# GOT-NEXT: }
40# GOT-NEXT: ]
41# GOT-NEXT: Local entries [
42# GOT-NEXT: Entry {
43# GOT-NEXT: Address:
44# GOT-NEXT: Access: -32736
45# GOT-NEXT: Initial: 0x20014
46# GOT-NEXT: }
47# GOT-NEXT: Entry {
48# GOT-NEXT: Address:
49# GOT-NEXT: Access: -32728
50# GOT-NEXT: Initial: 0x20004
51# GOT-NEXT: }
52# GOT-NEXT: Entry {
53# GOT-NEXT: Address:
54# GOT-NEXT: Access: -32720
55# GOT-NEXT: Initial: 0x20008
56# GOT-NEXT: }
57# GOT-NEXT: Entry {
58# GOT-NEXT: Address:
59# GOT-NEXT: Access: -32712
60# GOT-NEXT: Initial: 0x2000C
61# GOT-NEXT: }
62# GOT-NEXT: ]
63# GOT-NEXT: Global entries [
64# GOT-NEXT: Entry {
65# GOT-NEXT: Address:
66# GOT-NEXT: Access: -32704
67# GOT-NEXT: Initial: 0x0
68# GOT-NEXT: Value: 0x0
69# GOT-NEXT: Type: Function
70# GOT-NEXT: Section: Undefined
71# GOT-NEXT: Name: foo1a
72# GOT-NEXT: }
73# GOT-NEXT: ]
74# GOT-NEXT: Number of TLS and multi-GOT entries: 0
75# GOT-NEXT: }
23# GOT: Primary GOT:
24# GOT-NEXT: Canonical gp value: 0000000000038000
25# GOT-EMPTY:
26# GOT-NEXT: Reserved entries:
27# GOT-NEXT: Address Access Initial Purpose
28# GOT-NEXT: 0000000000030010 -32752(gp) 0000000000000000 Lazy resolver
29# GOT-NEXT: 0000000000030018 -32744(gp) 8000000000000000 Module pointer (GNU extension)
30# GOT-EMPTY:
31# GOT-NEXT: Local entries:
32# GOT-NEXT: Address Access Initial
33# GOT-NEXT: 0000000000030020 -32736(gp) 0000000000020014
34# GOT-NEXT: 0000000000030028 -32728(gp) 0000000000020004
35# GOT-NEXT: 0000000000030030 -32720(gp) 0000000000020008
36# GOT-NEXT: 0000000000030038 -32712(gp) 000000000002000c
37# GOT-EMPTY:
38# GOT-NEXT: Global entries:
39# GOT-NEXT: Address Access Initial Sym.Val. Type Ndx Name
40# GOT-NEXT: 0000000000030040 -32704(gp) 0000000000000000 0000000000000000 FUNC UND foo1a
7641
7742 .text
7843 .global __start
deps/lld/test/ELF/mips-64-got-overflow.s+27-61
......@@ -6,69 +6,35 @@
66# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t2.so.o
77# RUN: ld.lld -shared -mips-got-size 32 %t1.so.o %t2.so.o -o %t-sgot.so
88# RUN: ld.lld -shared -mips-got-size 24 %t1.so.o %t2.so.o -o %t-mgot.so
9# RUN: llvm-readobj -r -dt -mips-plt-got %t-sgot.so | FileCheck -check-prefix=SGOT %s
10# RUN: llvm-readobj -r -dt -mips-plt-got %t-mgot.so | FileCheck -check-prefix=MGOT %s
9# RUN: llvm-readelf --mips-plt-got %t-sgot.so | FileCheck -check-prefix=SGOT %s
10# RUN: llvm-readelf --mips-plt-got %t-mgot.so | FileCheck -check-prefix=MGOT %s
1111
12# SGOT: Primary GOT {
13# SGOT-NEXT: Canonical gp value: 0x27FF0
14# SGOT-NEXT: Reserved entries [
15# SGOT-NEXT: Entry {
16# SGOT-NEXT: Address:
17# SGOT-NEXT: Access: -32752
18# SGOT-NEXT: Initial: 0x0
19# SGOT-NEXT: Purpose: Lazy resolver
20# SGOT-NEXT: }
21# SGOT-NEXT: Entry {
22# SGOT-NEXT: Address:
23# SGOT-NEXT: Access: -32744
24# SGOT-NEXT: Initial: 0x80000000
25# SGOT-NEXT: Purpose: Module pointer (GNU extension)
26# SGOT-NEXT: }
27# SGOT-NEXT: ]
28# SGOT-NEXT: Local entries [
29# SGOT-NEXT: Entry {
30# SGOT-NEXT: Address:
31# SGOT-NEXT: Access: -32736
32# SGOT-NEXT: Initial: 0x20020
33# SGOT-NEXT: }
34# SGOT-NEXT: Entry {
35# SGOT-NEXT: Address:
36# SGOT-NEXT: Access: -32728
37# SGOT-NEXT: Initial: 0x20030
38# SGOT-NEXT: }
39# SGOT-NEXT: ]
40# SGOT-NEXT: Global entries [
41# SGOT-NEXT: ]
42# SGOT-NEXT: Number of TLS and multi-GOT entries: 0
43# SGOT-NEXT: }
12# SGOT: Primary GOT:
13# SGOT-NEXT: Canonical gp value: 0000000000027ff0
14# SGOT-EMPTY:
15# SGOT-NEXT: Reserved entries:
16# SGOT-NEXT: Address Access Initial Purpose
17# SGOT-NEXT: 0000000000020000 -32752(gp) 0000000000000000 Lazy resolver
18# SGOT-NEXT: 0000000000020008 -32744(gp) 8000000000000000 Module pointer (GNU extension)
19# SGOT-EMPTY:
20# SGOT-NEXT: Local entries:
21# SGOT-NEXT: Address Access Initial
22# SGOT-NEXT: 0000000000020010 -32736(gp) 0000000000020020
23# SGOT-NEXT: 0000000000020018 -32728(gp) 0000000000020030
4424
45# MGOT: Primary GOT {
46# MGOT-NEXT: Canonical gp value: 0x27FF0
47# MGOT-NEXT: Reserved entries [
48# MGOT-NEXT: Entry {
49# MGOT-NEXT: Address:
50# MGOT-NEXT: Access: -32752
51# MGOT-NEXT: Initial: 0x0
52# MGOT-NEXT: Purpose: Lazy resolver
53# MGOT-NEXT: }
54# MGOT-NEXT: Entry {
55# MGOT-NEXT: Address:
56# MGOT-NEXT: Access: -32744
57# MGOT-NEXT: Initial: 0x80000000
58# MGOT-NEXT: Purpose: Module pointer (GNU extension)
59# MGOT-NEXT: }
60# MGOT-NEXT: ]
61# MGOT-NEXT: Local entries [
62# MGOT-NEXT: Entry {
63# MGOT-NEXT: Address:
64# MGOT-NEXT: Access: -32736
65# MGOT-NEXT: Initial: 0x20020
66# MGOT-NEXT: }
67# MGOT-NEXT: ]
68# MGOT-NEXT: Global entries [
69# MGOT-NEXT: ]
70# MGOT-NEXT: Number of TLS and multi-GOT entries: 1
71# MGOT-NEXT: }
25# MGOT: Primary GOT:
26# MGOT-NEXT: Canonical gp value: 0000000000027ff0
27# MGOT-EMPTY:
28# MGOT-NEXT: Reserved entries:
29# MGOT-NEXT: Address Access Initial Purpose
30# MGOT-NEXT: 0000000000020000 -32752(gp) 0000000000000000 Lazy resolver
31# MGOT-NEXT: 0000000000020008 -32744(gp) 8000000000000000 Module pointer (GNU extension)
32# MGOT-EMPTY:
33# MGOT-NEXT: Local entries:
34# MGOT-NEXT: Address Access Initial
35# MGOT-NEXT: 0000000000020010 -32736(gp) 0000000000020020
36# MGOT-EMPTY:
37# MGOT-NEXT: Number of TLS and multi-GOT entries 1
7238
7339 .text
7440 .global foo2
deps/lld/test/ELF/mips-64-got.s+20-54
......@@ -7,7 +7,7 @@
77# RUN: ld.lld %t.so.o -shared -o %t.so
88# RUN: ld.lld %t.exe.o %t.so -o %t.exe
99# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
10# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s
10# RUN: llvm-readelf -r --mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s
1111
1212# CHECK: __start:
1313
......@@ -21,59 +21,25 @@
2121# CHECK: 0000000000020000 .text 00000000 __start
2222# CHECK: 0000000000020014 .text 00000000 bar
2323
24# GOT: Relocations [
25# GOT-NEXT: ]
26# GOT-NEXT: Primary GOT {
27# GOT-NEXT: Canonical gp value:
28# GOT-NEXT: Reserved entries [
29# GOT-NEXT: Entry {
30# GOT-NEXT: Address:
31# GOT-NEXT: Access: -32752
32# GOT-NEXT: Initial: 0x0
33# GOT-NEXT: Purpose: Lazy resolver
34# GOT-NEXT: }
35# GOT-NEXT: Entry {
36# GOT-NEXT: Address:
37# GOT-NEXT: Access: -32744
38# GOT-NEXT: Initial: 0x8000000000000000
39# GOT-NEXT: Purpose: Module pointer (GNU extension)
40# GOT-NEXT: }
41# GOT-NEXT: ]
42# GOT-NEXT: Local entries [
43# GOT-NEXT: Entry {
44# GOT-NEXT: Address:
45# GOT-NEXT: Access: -32736
46# GOT-NEXT: Initial: 0x20000
47# GOT-NEXT: }
48# GOT-NEXT: Entry {
49# GOT-NEXT: Address:
50# GOT-NEXT: Access: -32728
51# GOT-NEXT: Initial: 0x30000
52# GOT-NEXT: }
53# GOT-NEXT: Entry {
54# GOT-NEXT: Address:
55# GOT-NEXT: Access: -32720
56# GOT-NEXT: Initial: 0x20014
57# GOT-NEXT: }
58# GOT-NEXT: Entry {
59# GOT-NEXT: Address:
60# GOT-NEXT: Access: -32712
61# GOT-NEXT: Initial: 0x20018
62# GOT-NEXT: }
63# GOT-NEXT: ]
64# GOT-NEXT: Global entries [
65# GOT-NEXT: Entry {
66# GOT-NEXT: Address:
67# GOT-NEXT: Access: -32704
68# GOT-NEXT: Initial: 0x0
69# GOT-NEXT: Value: 0x0
70# GOT-NEXT: Type: Function
71# GOT-NEXT: Section: Undefined
72# GOT-NEXT: Name: foo1a
73# GOT-NEXT: }
74# GOT-NEXT: ]
75# GOT-NEXT: Number of TLS and multi-GOT entries: 0
76# GOT-NEXT: }
24# GOT: There are no relocations in this file.
25# GOT-NEXT: Primary GOT:
26# GOT-NEXT: Canonical gp value: 0000000000038000
27# GOT-EMPTY:
28# GOT-NEXT: Reserved entries:
29# GOT-NEXT: Address Access Initial Purpose
30# GOT-NEXT: 0000000000030010 -32752(gp) 0000000000000000 Lazy resolver
31# GOT-NEXT: 0000000000030018 -32744(gp) 8000000000000000 Module pointer (GNU extension)
32# GOT-EMPTY:
33# GOT-NEXT: Local entries:
34# GOT-NEXT: Address Access Initial
35# GOT-NEXT: 0000000000030020 -32736(gp) 0000000000020000
36# GOT-NEXT: 0000000000030028 -32728(gp) 0000000000030000
37# GOT-NEXT: 0000000000030030 -32720(gp) 0000000000020014
38# GOT-NEXT: 0000000000030038 -32712(gp) 0000000000020018
39# GOT-EMPTY:
40# GOT-NEXT: Global entries:
41# GOT-NEXT: Address Access Initial Sym.Val. Type Ndx Name
42# GOT-NEXT: 0000000000030040 -32704(gp) 0000000000000000 0000000000000000 FUNC UND foo1a
7743
7844 .text
7945 .global __start, bar
deps/lld/test/ELF/mips-64-gprel-so.s+1
......@@ -6,6 +6,7 @@
66# RUN: llvm-objdump -d -t %t.so | FileCheck %s
77
88# CHECK: Disassembly of section .text:
9# CHECK-EMPTY:
910# CHECK-NEXT: foo:
1011# CHECK-NEXT: 10000: 3c 1c 00 01 lui $gp, 1
1112# CHECK-NEXT: 10004: 03 99 e0 2d daddu $gp, $gp, $25
deps/lld/test/ELF/mips-64.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
55# RUN: ld.lld -shared %t.o -o %t.so
66# RUN: llvm-objdump -t %t.so | FileCheck -check-prefix=SYM %s
7# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t.so | FileCheck %s
7# RUN: llvm-readobj -r --dynamic-table --mips-plt-got %t.so | FileCheck %s
88
99 .global __start
1010__start:
deps/lld/test/ELF/mips-abs-got.s+4-4
......@@ -4,9 +4,9 @@
44
55# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -o %t.o %s
66# RUN: echo "SECTIONS { \
7# RUN: zero = 0; foo = 0x11004; bar = 0x22000; }" > %t.script
7# RUN: zero1 = 0; zero2 = 0; foo = 0x11004; bar = 0x22000; }" > %t.script
88# RUN: ld.lld --script %t.script -o %t.exe %t.o
9# RUN: llvm-readobj -mips-plt-got %t.exe | FileCheck %s
9# RUN: llvm-readobj --mips-plt-got %t.exe | FileCheck %s
1010
1111# CHECK: Static GOT {
1212# CHECK: Local entries [
......@@ -30,7 +30,7 @@
3030
3131 .text
3232 nop
33 .reloc 0, R_MIPS_GOT_PAGE, 0
34 ld $v0, %got_page(zero)($gp)
33 ld $v0, %got_page(zero1)($gp)
34 ld $v0, %got_page(zero2)($gp)
3535 ld $v0, %got_page(foo)($gp)
3636 ld $v0, %got_page(bar+0x10008)($gp)
deps/lld/test/ELF/mips-call-hilo.s+19-31
......@@ -4,9 +4,10 @@
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: ld.lld %t.o -shared -o %t.so
66# RUN: llvm-objdump -d %t.so | FileCheck %s
7# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
7# RUN: llvm-readelf -r --mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
88
99# CHECK: Disassembly of section .text:
10# CHECK-EMPTY:
1011# CHECK-NEXT: foo:
1112# CHECK-NEXT: 10000: 3c 02 00 00 lui $2, 0
1213# CHECK-NEXT: 10004: 8c 42 80 20 lw $2, -32736($2)
......@@ -15,36 +16,23 @@
1516# CHECK-NEXT: 10010: 3c 02 00 00 lui $2, 0
1617# CHECK-NEXT: 10014: 8c 42 80 1c lw $2, -32740($2)
1718
18# GOT: Relocations [
19# GOT-NEXT: ]
20
21# GOT: Primary GOT {
22# GOT-NEXT: Canonical gp value: 0x27FF0
23# GOT: Local entries [
24# GOT-NEXT: Entry {
25# GOT-NEXT: Address: 0x20008
26# GOT-NEXT: Access: -32744
27# GOT-NEXT: Initial: 0x10018
28# GOT-NEXT: }
29# GOT-NEXT: Entry {
30# GOT-NEXT: Address: 0x2000C
31# GOT-NEXT: Access: -32740
32# GOT-NEXT: Initial: 0x1001C
33# GOT-NEXT: }
34# GOT-NEXT: ]
35# GOT-NEXT: Global entries [
36# GOT-NEXT: Entry {
37# GOT-NEXT: Address: 0x20010
38# GOT-NEXT: Access: -32736
39# GOT-NEXT: Initial: 0x0
40# GOT-NEXT: Value: 0x0
41# GOT-NEXT: Type: None
42# GOT-NEXT: Section: Undefined
43# GOT-NEXT: Name: bar
44# GOT-NEXT: }
45# GOT-NEXT: ]
46# GOT-NEXT: Number of TLS and multi-GOT entries: 0
47# GOT-NEXT: }
19# GOT: There are no relocations in this file.
20# GOT: Primary GOT:
21# GOT-NEXT: Canonical gp value: 00027ff0
22# GOT-EMPTY:
23# GOT-NEXT: Reserved entries:
24# GOT-NEXT: Address Access Initial Purpose
25# GOT-NEXT: 00020000 -32752(gp) 00000000 Lazy resolver
26# GOT-NEXT: 00020004 -32748(gp) 80000000 Module pointer (GNU extension)
27# GOT-EMPTY:
28# GOT-NEXT: Local entries:
29# GOT-NEXT: Address Access Initial
30# GOT-NEXT: 00020008 -32744(gp) 00010018
31# GOT-NEXT: 0002000c -32740(gp) 0001001c
32# GOT-EMPTY:
33# GOT-NEXT: Global entries:
34# GOT-NEXT: Address Access Initial Sym.Val. Type Ndx Name
35# GOT-NEXT: 00020010 -32736(gp) 00000000 00000000 NOTYPE UND bar
4836
4937 .text
5038 .global foo
deps/lld/test/ELF/mips-call16.s+2-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: ld.lld %t.o -shared -o %t.exe
66# RUN: llvm-objdump -d %t.exe | FileCheck %s
7# RUN: llvm-readobj -mips-plt-got -symbols %t.exe \
7# RUN: llvm-readobj --mips-plt-got --symbols %t.exe \
88# RUN: | FileCheck -check-prefix=GOT %s
99
1010 .text
......@@ -18,6 +18,7 @@ g1:
1818 nop
1919
2020# CHECK: Disassembly of section .text:
21# CHECK-EMPTY:
2122# CHECK-NEXT: __start:
2223# CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744
2324
deps/lld/test/ELF/mips-dynamic.s+4-4
......@@ -6,19 +6,19 @@
66# RUN: ld.lld -shared %td.o -o %td.so
77
88# RUN: ld.lld %t.o %td.so -o %t.exe
9# RUN: llvm-readobj -sections -dynamic-table %t.exe \
9# RUN: llvm-readobj --sections --dynamic-table %t.exe \
1010# RUN: | FileCheck -check-prefixes=EXE,NOPIE %s
1111
1212# RUN: ld.lld -pie %t.o %td.so -o %t.so
13# RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \
13# RUN: llvm-readobj --sections --dyn-syms --dynamic-table %t.so \
1414# RUN: | FileCheck -check-prefixes=EXE,PIE %s
1515
1616# RUN: ld.lld %t.o --image-base=0x123000 %td.so -o %t.exe
17# RUN: llvm-readobj -sections -dynamic-table %t.exe \
17# RUN: llvm-readobj --sections --dynamic-table %t.exe \
1818# RUN: | FileCheck -check-prefix=IMAGE_BASE %s
1919
2020# RUN: ld.lld -shared %t.o %td.so -o %t.so
21# RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \
21# RUN: llvm-readobj --sections --dyn-syms --dynamic-table %t.so \
2222# RUN: | FileCheck -check-prefix=DSO %s
2323
2424# EXE: Sections [
deps/lld/test/ELF/mips-dynsym-sort.s+2-2
......@@ -3,11 +3,11 @@
33
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
55# RUN: ld.lld -shared %t-be.o -o %t-be.so
6# RUN: llvm-readobj -symbols -dyn-symbols %t-be.so | FileCheck %s
6# RUN: llvm-readobj --symbols --dyn-syms %t-be.so | FileCheck %s
77
88# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
99# RUN: ld.lld -shared %t-el.o -o %t-el.so
10# RUN: llvm-readobj -symbols -dyn-symbols %t-el.so | FileCheck %s
10# RUN: llvm-readobj --symbols --dyn-syms %t-el.so | FileCheck %s
1111
1212 .data
1313 .globl v1,v2,v3
deps/lld/test/ELF/mips-elf-flags.s+7-7
......@@ -4,16 +4,16 @@
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
55# RUN: %S/Inputs/mips-dynamic.s -o %t-so.o
66# RUN: ld.lld %t-so.o --gc-sections -shared -o %t.so
7# RUN: llvm-readobj -h -mips-abi-flags %t.so | FileCheck -check-prefix=SO %s
7# RUN: llvm-readobj -h --mips-abi-flags %t.so | FileCheck -check-prefix=SO %s
88
99# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
1010# RUN: ld.lld %t.o -o %t.exe
11# RUN: llvm-readobj -h -mips-abi-flags %t.exe | FileCheck -check-prefix=EXE %s
11# RUN: llvm-readobj -h --mips-abi-flags %t.exe | FileCheck -check-prefix=EXE %s
1212
1313# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
1414# RUN: -mcpu=mips32r2 %s -o %t-r2.o
1515# RUN: ld.lld %t-r2.o -o %t-r2.exe
16# RUN: llvm-readobj -h -mips-abi-flags %t-r2.exe \
16# RUN: llvm-readobj -h --mips-abi-flags %t-r2.exe \
1717# RUN: | FileCheck -check-prefix=EXE-R2 %s
1818
1919# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
......@@ -21,26 +21,26 @@
2121# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
2222# RUN: -mcpu=mips32r5 %S/Inputs/mips-dynamic.s -o %t-r5.o
2323# RUN: ld.lld %t-r2.o %t-r5.o -o %t-r5.exe
24# RUN: llvm-readobj -h -mips-abi-flags %t-r5.exe \
24# RUN: llvm-readobj -h --mips-abi-flags %t-r5.exe \
2525# RUN: | FileCheck -check-prefix=EXE-R5 %s
2626
2727# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
2828# RUN: -mcpu=mips32r6 %s -o %t-r6.o
2929# RUN: ld.lld %t-r6.o -o %t-r6.exe
30# RUN: llvm-readobj -h -mips-abi-flags %t-r6.exe \
30# RUN: llvm-readobj -h --mips-abi-flags %t-r6.exe \
3131# RUN: | FileCheck -check-prefix=EXE-R6 %s
3232
3333# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
3434# RUN: -position-independent -mcpu=octeon %s -o %t.o
3535# RUN: ld.lld %t.o -o %t.exe
36# RUN: llvm-readobj -h -mips-abi-flags %t.exe \
36# RUN: llvm-readobj -h --mips-abi-flags %t.exe \
3737# RUN: | FileCheck -check-prefix=OCTEON %s
3838
3939# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4040# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
4141# RUN: -mattr=micromips %S/Inputs/mips-fpic.s -o %t-mm.o
4242# RUN: ld.lld %t.o %t-mm.o -o %t.exe
43# RUN: llvm-readobj -h -mips-abi-flags %t.exe | FileCheck -check-prefix=MICRO %s
43# RUN: llvm-readobj -h --mips-abi-flags %t.exe | FileCheck -check-prefix=MICRO %s
4444
4545 .text
4646 .globl __start
deps/lld/test/ELF/mips-got-and-copy.s+1-1
......@@ -10,7 +10,7 @@
1010# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
1111# RUN: ld.lld %t.so.o -shared -o %t.so
1212# RUN: ld.lld %t.o %t.so -o %t.exe
13# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
13# RUN: llvm-readobj -r --mips-plt-got %t.exe | FileCheck %s
1414
1515# CHECK: Relocations [
1616# CHECK-NEXT: Section (7) .rel.dyn {
deps/lld/test/ELF/mips-got-extsym.s+1-1
......@@ -9,7 +9,7 @@
99# RUN: ld.lld -shared %t.so.o -o %t.so
1010# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
1111# RUN: ld.lld %t.o %t.so -o %t.exe
12# RUN: llvm-readobj -dt -t -mips-plt-got %t.exe | FileCheck %s
12# RUN: llvm-readobj --dyn-syms --symbols --mips-plt-got %t.exe | FileCheck %s
1313
1414# CHECK: Symbols [
1515# CHECK: Symbol {
deps/lld/test/ELF/mips-got-hilo.s+2-1
......@@ -4,9 +4,10 @@
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: ld.lld %t.o -shared -o %t.so
66# RUN: llvm-objdump -d %t.so | FileCheck %s
7# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
7# RUN: llvm-readobj -r --mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
88
99# CHECK: Disassembly of section .text:
10# CHECK-EMPTY:
1011# CHECK-NEXT: foo:
1112# CHECK-NEXT: 10000: 3c 02 00 00 lui $2, 0
1213# CHECK-NEXT: 10004: 8c 42 80 20 lw $2, -32736($2)
deps/lld/test/ELF/mips-got-page-script.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: .text : { *(.text) } \
88# RUN: .data 0x10000 : { *(.data) } }" > %t.script
99# RUN: ld.lld -shared --script %t.script -o %t.so %t.o
10# RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s
10# RUN: llvm-readobj --symbols --mips-plt-got %t.so | FileCheck %s
1111
1212# CHECK: Name: foo1
1313# CHECK-NEXT: Value: 0x10000
deps/lld/test/ELF/mips-got-page.s+1-1
......@@ -5,7 +5,7 @@
55
66# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -o %t.o %s
77# RUN: ld.lld --section-start .rodata=0x27FFC -shared -o %t.so %t.o
8# RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s
8# RUN: llvm-readobj --symbols --mips-plt-got %t.so | FileCheck %s
99
1010# CHECK: Name: bar
1111# CHECK-NEXT: Value: 0x28000
deps/lld/test/ELF/mips-got-redundant.s+1-1
......@@ -3,7 +3,7 @@
33
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: ld.lld %t.o -shared -o %t.so
6# RUN: llvm-readobj -mips-plt-got %t.so | FileCheck %s
6# RUN: llvm-readobj --mips-plt-got %t.so | FileCheck %s
77
88# CHECK: Local entries [
99# CHECK-NEXT: Entry {
deps/lld/test/ELF/mips-got-relocs.s+41-74
......@@ -3,33 +3,25 @@
33
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
55# RUN: ld.lld %t-be.o -o %t-be.exe
6# RUN: llvm-objdump -section-headers -t %t-be.exe | FileCheck -check-prefix=EXE_SYM %s
7# RUN: llvm-objdump -s -section=.got %t-be.exe | FileCheck -check-prefix=EXE_GOT_BE %s
8# RUN: llvm-objdump -d %t-be.exe | FileCheck -check-prefix=EXE_DIS_BE %s
9# RUN: llvm-readobj -relocations %t-be.exe | FileCheck -check-prefix=NORELOC %s
10# RUN: llvm-readobj -sections %t-be.exe | FileCheck -check-prefix=SHFLAGS %s
6# RUN: llvm-readobj --sections -r --symbols --mips-plt-got %t-be.exe \
7# RUN: | FileCheck -check-prefixes=ELF,EXE %s
8# RUN: llvm-objdump -d %t-be.exe | FileCheck -check-prefix=DIS %s
119
1210# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
1311# RUN: ld.lld %t-el.o -o %t-el.exe
14# RUN: llvm-objdump -section-headers -t %t-el.exe | FileCheck -check-prefix=EXE_SYM %s
15# RUN: llvm-objdump -s -section=.got %t-el.exe | FileCheck -check-prefix=EXE_GOT_EL %s
16# RUN: llvm-objdump -d %t-el.exe | FileCheck -check-prefix=EXE_DIS_EL %s
17# RUN: llvm-readobj -relocations %t-el.exe | FileCheck -check-prefix=NORELOC %s
18# RUN: llvm-readobj -sections %t-el.exe | FileCheck -check-prefix=SHFLAGS %s
12# RUN: llvm-readobj --sections -r --symbols --mips-plt-got %t-el.exe \
13# RUN: | FileCheck -check-prefixes=ELF,EXE %s
14# RUN: llvm-objdump -d %t-el.exe | FileCheck -check-prefix=DIS %s
1915
2016# RUN: ld.lld -shared %t-be.o -o %t-be.so
21# RUN: llvm-objdump -section-headers -t %t-be.so | FileCheck -check-prefix=DSO_SYM %s
22# RUN: llvm-objdump -s -section=.got %t-be.so | FileCheck -check-prefix=DSO_GOT_BE %s
23# RUN: llvm-objdump -d %t-be.so | FileCheck -check-prefix=DSO_DIS_BE %s
24# RUN: llvm-readobj -relocations %t-be.so | FileCheck -check-prefix=NORELOC %s
25# RUN: llvm-readobj -sections %t-be.so | FileCheck -check-prefix=SHFLAGS %s
17# RUN: llvm-readobj --sections -r --symbols --mips-plt-got %t-be.so \
18# RUN: | FileCheck -check-prefixes=ELF,DSO %s
19# RUN: llvm-objdump -d %t-be.so | FileCheck -check-prefix=DIS %s
2620
2721# RUN: ld.lld -shared %t-el.o -o %t-el.so
28# RUN: llvm-objdump -section-headers -t %t-el.so | FileCheck -check-prefix=DSO_SYM %s
29# RUN: llvm-objdump -s -section=.got %t-el.so | FileCheck -check-prefix=DSO_GOT_EL %s
30# RUN: llvm-objdump -d %t-el.so | FileCheck -check-prefix=DSO_DIS_EL %s
31# RUN: llvm-readobj -relocations %t-el.so | FileCheck -check-prefix=NORELOC %s
32# RUN: llvm-readobj -sections %t-el.so | FileCheck -check-prefix=SHFLAGS %s
22# RUN: llvm-readobj --sections -r --symbols --mips-plt-got %t-el.so \
23# RUN: | FileCheck -check-prefixes=ELF,DSO %s
24# RUN: llvm-objdump -d %t-el.so | FileCheck -check-prefix=DIS %s
3325
3426 .text
3527 .globl __start
......@@ -43,57 +35,32 @@ __start:
4335v1:
4436 .word 0
4537
46# EXE_SYM: Sections:
47# EXE_SYM: .got 0000000c 0000000000030010 DATA
48# EXE_SYM: SYMBOL TABLE:
49# EXE_SYM: 00038000 .got 00000000 .hidden _gp
50# ^-- .got + GP offset (0x7ff0)
51# EXE_SYM: 00030000 g O .data 00000004 v1
52
53
54# EXE_GOT_BE: Contents of section .got:
55# EXE_GOT_BE: 30010 00000000 80000000 00030000
56# ^ ^ ^-- v1 (0x30000)
57# | +-- Module pointer (0x80000000)
58# +-- Lazy resolver (0x0)
59
60# EXE_GOT_EL: Contents of section .got:
61# EXE_GOT_EL: 30010 00000000 00000080 00000300
62# ^ ^ ^-- v1 (0x30000)
63# | +-- Module pointer (0x80000000)
64# +-- Lazy resolver (0x0)
65
66# v1GotAddr (0x3000c) - _gp (0x37ff4) = -0x7fe8 => 0x8018 = 32792
67# EXE_DIS_BE: 20000: 3c 02 80 18 lui $2, 32792
68# EXE_DIS_EL: 20000: 18 80 02 3c lui $2, 32792
69
70# DSO_SYM: Sections:
71# DSO_SYM: .got 0000000c 0000000000020010 DATA
72# DSO_SYM: SYMBOL TABLE:
73# DSO_SYM: 00028000 .got 00000000 .hidden _gp
74# ^-- .got + GP offset (0x7ff0)
75# DSO_SYM: 00020000 g O .data 00000004 v1
76
77# DSO_GOT_BE: Contents of section .got:
78# DSO_GOT_BE: 20010 00000000 80000000 00020000
79# ^ ^ ^-- v1 (0x20000)
80# | +-- Module pointer (0x80000000)
81# +-- Lazy resolver (0x0)
82
83# DSO_GOT_EL: Contents of section .got:
84# DSO_GOT_EL: 20010 00000000 00000080 00000200
85# ^ ^ ^-- v1 (0x20000)
86# | +-- Module pointer (0x80000000)
87# +-- Lazy resolver (0x0)
88
89# v1GotAddr (0x2000c) - _gp (0x27ff4) = -0x7fe8 => 0x8018 = 32792
90# DSO_DIS_BE: 10000: 3c 02 80 18 lui $2, 32792
91# DSO_DIS_EL: 10000: 18 80 02 3c lui $2, 32792
92
93# NORELOC: Relocations [
94# NORELOC-NEXT: ]
95
96# SHFLAGS: Name: .got
97# SHFLAGS-NEXT: Type: SHT_PROGBITS
98# SHFLAGS-NEXT: Flags [ (0x10000003)
99# ^-- SHF_MIPS_GPREL | SHF_ALLOC | SHF_WRITE
38# ELF: Section {
39# ELF: Name: .got
40# ELF: Flags [
41# ELF-NEXT: SHF_ALLOC
42# ELF-NEXT: SHF_MIPS_GPREL
43# ELF-NEXT: SHF_WRITE
44# ELF-NEXT: ]
45#
46# ELF: Relocations [
47# ELF-NEXT: ]
48#
49# ELF: Symbol {
50# ELF: Name: v1
51# ELF-NEXT: Value: 0x[[V1:[0-9A-F]+]]
52#
53# ELF: {{.*}} GOT {
54# EXE-NEXT: Canonical gp value: 0x38000
55# DSO-NEXT: Canonical gp value: 0x28000
56#
57# ELF: Entry {
58# EXE: Address: 0x30018
59# DSO: Address: 0x20018
60# ELF-NEXT: Access: -32744
61# ELF-NEXT: Initial: 0x[[V1]]
62
63# "v1 GOT entry address" - _gp
64# exe: 0x30018 - 0x38000 = -0x7fe8 == 0x8018 == 32792
65# dso: 0x20018 - 0x28000 = -0x7fe8 == 0x8018 == 32792
66# DIS: {{.*}} lui $2, 32792
deps/lld/test/ELF/mips-got-script.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: echo "SECTIONS { .data : { *(.data.1); . += 0x10000; *(.data.2) } }" > %t.script
66# RUN: ld.lld %t.o -shared -o %t.so -T %t.script
7# RUN: llvm-readobj -mips-plt-got -dynamic-table %t.so | FileCheck %s
7# RUN: llvm-readobj --mips-plt-got --dynamic-table %t.so | FileCheck %s
88
99# CHECK: 0x7000000A MIPS_LOCAL_GOTNO 4
1010# ^-- 2 * header + 2 local entries
deps/lld/test/ELF/mips-got-string.s+5-13
......@@ -3,20 +3,12 @@
33
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -o %t.o %s
55# RUN: ld.lld -shared -o %t.so %t.o
6# RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s
6# RUN: llvm-readelf --mips-plt-got %t.so | FileCheck %s
77
8# CHECK: Symbol {
9# CHECK: Name: $.str
10# CHECK-NEXT: Value: 0x1B1
11# CHECK: }
12
13# CHECK: Local entries [
14# CHECK-NEXT: Entry {
15# CHECK-NEXT: Address:
16# CHECK-NEXT: Access: -32744
17# CHECK-NEXT: Initial: 0x0
18# CHECK: }
19# CHECK: ]
8# CHECK: Local entries:
9# CHECK-NEXT: Address Access Initial
10# CHECK-NEXT: {{[0-9a-f]+}} -32744(gp) 00000000
11# CHECK-NEXT: {{[0-9a-f]+}} -32740(gp) 00010000
2012
2113 .text
2214 lw $t9, %got($.str)($gp)
deps/lld/test/ELF/mips-got-weak.s+2-2
......@@ -3,10 +3,10 @@
33
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: ld.lld %t.o -shared -o %t1.so
6# RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t1.so \
6# RUN: llvm-readobj -r --dyn-syms --dynamic-table --mips-plt-got %t1.so \
77# RUN: | FileCheck -check-prefixes=CHECK,NOSYM %s
88# RUN: ld.lld %t.o -shared -Bsymbolic -o %t2.so
9# RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t2.so \
9# RUN: llvm-readobj -r --dyn-syms --dynamic-table --mips-plt-got %t2.so \
1010# RUN: | FileCheck -check-prefixes=CHECK,SYM %s
1111
1212# CHECK: Relocations [
deps/lld/test/ELF/mips-got16-relocatable.s+2
......@@ -9,6 +9,7 @@
99# RUN: llvm-objdump -d %t.so | FileCheck -check-prefix=SO %s
1010
1111# OBJ: Disassembly of section .text:
12# OBJ-EMPTY:
1213# OBJ-NEXT: .text:
1314# OBJ-NEXT: 0: 8f 99 00 00 lw $25, 0($gp)
1415# OBJ-NEXT: 00000000: R_MIPS_GOT16 .data
......@@ -20,6 +21,7 @@
2021# OBJ-NEXT: 00000014: R_MIPS_LO16 .data
2122
2223# SO: Disassembly of section .text:
24# SO-EMPTY:
2325# SO-NEXT: .text:
2426# SO-NEXT: 10000: 8f 99 80 18 lw $25, -32744($gp)
2527# SO-NEXT: 10004: 27 24 00 00 addiu $4, $25, 0
deps/lld/test/ELF/mips-got16.s+24-77
......@@ -4,9 +4,10 @@
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: ld.lld %t.o -shared -o %t.so
66# RUN: llvm-objdump -d -t %t.so | FileCheck %s
7# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
7# RUN: llvm-readelf -r --mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
88
99# CHECK: Disassembly of section .text:
10# CHECK-EMPTY:
1011# CHECK-NEXT: __start:
1112# CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744($gp)
1213# CHECK-NEXT: 10004: 21 08 00 2c addi $8, $8, 44
......@@ -24,83 +25,29 @@
2425# CHECK: 00041008 .data 00000000 .hidden bar
2526# CHECK: 00000000 *UND* 00000000 foo
2627
27# GOT: Relocations [
28# GOT-NEXT: ]
28# GOT: There are no relocations in this file.
2929
30# GOT: Primary GOT {
31# GOT-NEXT: Canonical gp value:
32# GOT-NEXT: Reserved entries [
33# GOT-NEXT: Entry {
34# GOT-NEXT: Address:
35# GOT-NEXT: Access: -32752
36# GOT-NEXT: Initial: 0x0
37# GOT-NEXT: Purpose: Lazy resolver
38# GOT-NEXT: }
39# GOT-NEXT: Entry {
40# GOT-NEXT: Address:
41# GOT-NEXT: Access: -32748
42# GOT-NEXT: Initial: 0x80000000
43# GOT-NEXT: Purpose: Module pointer (GNU extension)
44# GOT-NEXT: }
45# GOT-NEXT: ]
46# GOT-NEXT: Local entries [
47# GOT-NEXT: Entry {
48# GOT-NEXT: Address:
49# GOT-NEXT: Access: -32744
50# GOT-NEXT: Initial: 0x10000
51# ^-- (0x1002c + 0x8000) & ~0xffff
52# GOT-NEXT: }
53# GOT-NEXT: Entry {
54# GOT-NEXT: Address:
55# GOT-NEXT: Access: -32740
56# GOT-NEXT: Initial: 0x20000
57# ^-- redundant unused entry
58# GOT-NEXT: }
59# GOT-NEXT: Entry {
60# GOT-NEXT: Address:
61# GOT-NEXT: Access: -32736
62# GOT-NEXT: Initial: 0x20000
63# ^-- redundant unused entry
64# GOT-NEXT: }
65# GOT-NEXT: Entry {
66# GOT-NEXT: Address:
67# GOT-NEXT: Access: -32732
68# GOT-NEXT: Initial: 0x30000
69# ^-- (0x29000 + 0x8000) & ~0xffff
70# GOT-NEXT: }
71# GOT-NEXT: Entry {
72# GOT-NEXT: Address:
73# GOT-NEXT: Access: -32728
74# GOT-NEXT: Initial: 0x40000
75# ^-- (0x29000 + 0x10004 + 0x8000) & ~0xffff
76# ^-- (0x29000 + 0x18004 + 0x8000) & ~0xffff
77# GOT-NEXT: }
78# GOT-NEXT: Entry {
79# GOT-NEXT: Address:
80# GOT-NEXT: Access: -32724
81# GOT-NEXT: Initial: 0x50000
82# ^-- redundant unused entry
83# GOT-NEXT: }
84# GOT-NEXT: Entry {
85# GOT-NEXT: Address:
86# GOT-NEXT: Access: -32720
87# GOT-NEXT: Initial: 0x41008
88# ^-- 'bar' address
89# GOT-NEXT: }
90# GOT-NEXT: ]
91# GOT-NEXT: Global entries [
92# GOT-NEXT: Entry {
93# GOT-NEXT: Address:
94# GOT-NEXT: Access: -32716
95# GOT-NEXT: Initial: 0x0
96# GOT-NEXT: Value: 0x0
97# GOT-NEXT: Type: None
98# GOT-NEXT: Section: Undefined
99# GOT-NEXT: Name: foo
100# GOT-NEXT: }
101# GOT-NEXT: ]
102# GOT-NEXT: Number of TLS and multi-GOT entries: 0
103# GOT-NEXT: }
30# GOT: Local entries:
31# GOT-NEXT: Address Access Initial
32# GOT-NEXT: 00041018 -32744(gp) 00010000
33# ^-- (0x1002c + 0x8000) & ~0xffff
34# GOT-NEXT: 0004101c -32740(gp) 00020000
35# ^-- redundant unused entry
36# GOT-NEXT: 00041020 -32736(gp) 00020000
37# ^-- redundant unused entry
38# GOT-NEXT: 00041024 -32732(gp) 00030000
39# ^-- (0x29000 + 0x8000) & ~0xffff
40# GOT-NEXT: 00041028 -32728(gp) 00040000
41# ^-- (0x29000 + 0x10004 + 0x8000) & ~0xffff
42# ^-- (0x29000 + 0x18004 + 0x8000) & ~0xffff
43# GOT-NEXT: 0004102c -32724(gp) 00050000
44# ^-- redundant unused entry
45# GOT-NEXT: 00041030 -32720(gp) 00041008
46# ^-- 'bar' address
47# GOT-EMPTY:
48# GOT-NEXT: Global entries:
49# GOT-NEXT: Address Access Initial Sym.Val. Type Ndx Name
50# GOT-NEXT: 00041034 -32716(gp) 00000000 00000000 NOTYPE UND foo
10451
10552 .text
10653 .globl __start
deps/lld/test/ELF/mips-gp-disp.s+4-3
......@@ -4,11 +4,11 @@
44
55# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
66# RUN: ld.lld -shared -o %t.so %t.o %S/Inputs/mips-gp-disp.so
7# RUN: llvm-readobj -symbols %t.so | FileCheck -check-prefix=INT-SO %s
8# RUN: llvm-readobj -symbols %S/Inputs/mips-gp-disp.so \
7# RUN: llvm-readobj --symbols %t.so | FileCheck -check-prefix=INT-SO %s
8# RUN: llvm-readobj --symbols %S/Inputs/mips-gp-disp.so \
99# RUN: | FileCheck -check-prefix=EXT-SO %s
1010# RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=DIS %s
11# RUN: llvm-readobj -relocations %t.so | FileCheck -check-prefix=REL %s
11# RUN: llvm-readobj -r %t.so | FileCheck -check-prefix=REL %s
1212
1313# INT-SO: Name: _gp_disp
1414# INT-SO-NEXT: Value:
......@@ -19,6 +19,7 @@
1919# EXT-SO-NEXT: Value: 0x20000
2020
2121# DIS: Disassembly of section .text:
22# DIS-EMPTY:
2223# DIS-NEXT: __start:
2324# DIS-NEXT: 10000: 3c 08 00 01 lui $8, 1
2425# DIS-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752
deps/lld/test/ELF/mips-gp-local.s+1
......@@ -6,6 +6,7 @@
66# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
77
88# CHECK: Disassembly of section .text:
9# CHECK-EMPTY:
910# CHECK-NEXT: __start:
1011# CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3
1112# CHECK-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752
deps/lld/test/ELF/mips-gp-lowest.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: .sdata : { *(.sdata) } \
88# RUN: .got : { *(.got) } }" > %t.rel.script
99# RUN: ld.lld %t.o --script %t.rel.script -shared -o %t.so
10# RUN: llvm-readobj -s -t %t.so | FileCheck %s
10# RUN: llvm-readobj -S --symbols %t.so | FileCheck %s
1111
1212 .text
1313 .global foo
deps/lld/test/ELF/mips-gprel-sec.s+1-1
......@@ -3,7 +3,7 @@
33
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: ld.lld %t.o -shared -o %t.so
6# RUN: llvm-readobj -s %t.so | FileCheck %s
6# RUN: llvm-readobj -S %t.so | FileCheck %s
77
88 .text
99 nop
deps/lld/test/ELF/mips-gprel32-relocs-gp0.s+2-2
......@@ -3,10 +3,10 @@
33
44# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
55# RUN: ld.lld -r -o %t-rel.o %t.o
6# RUN: llvm-readobj -mips-reginfo %t-rel.o | FileCheck --check-prefix=REL %s
6# RUN: llvm-readobj --mips-reginfo %t-rel.o | FileCheck --check-prefix=REL %s
77
88# RUN: ld.lld -shared -o %t.so %S/Inputs/mips-gp0-non-zero.o
9# RUN: llvm-readobj -mips-reginfo %t.so | FileCheck --check-prefix=DSO %s
9# RUN: llvm-readobj --mips-reginfo %t.so | FileCheck --check-prefix=DSO %s
1010# RUN: llvm-objdump -s -t %t.so | FileCheck --check-prefix=DUMP %s
1111
1212# REL: GP: 0x0
deps/lld/test/ELF/mips-hilo-gp-disp.s+2
......@@ -20,6 +20,7 @@ bar:
2020 addi $t0,$t0,%lo(_gp_disp)
2121
2222# EXE: Disassembly of section .text:
23# EXE-EMPTY:
2324# EXE-NEXT: __start:
2425# EXE-NEXT: 20000: 3c 08 00 02 lui $8, 2
2526# ^-- %hi(0x47ff0-0x20000)
......@@ -37,6 +38,7 @@ bar:
3738# EXE: 00020000 .text 00000000 __start
3839
3940# SO: Disassembly of section .text:
41# SO-EMPTY:
4042# SO-NEXT: __start:
4143# SO-NEXT: 10000: 3c 08 00 02 lui $8, 2
4244# ^-- %hi(0x28000-0x10000)
deps/lld/test/ELF/mips-hilo-hi-only.s+1
......@@ -16,6 +16,7 @@ _label:
1616# WARN: can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16
1717
1818# CHECK: Disassembly of section .text:
19# CHECK-EMPTY:
1920# CHECK-NEXT: __start:
2021# CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3
2122# ^-- %hi(__start) w/o addend
deps/lld/test/ELF/mips-hilo.s+1
......@@ -30,6 +30,7 @@ g1:
3030 .word 0
3131
3232# CHECK: Disassembly of section .text:
33# CHECK-EMPTY:
3334# CHECK-NEXT: __start:
3435# CHECK-NEXT: 20000: 3c 08 00 02 lui $8, 2
3536# ^-- %hi(__start+4)
deps/lld/test/ELF/mips-jalr.test+12-13
......@@ -3,7 +3,7 @@
33# RUN: yaml2obj %s -o %t.o
44# RUN: ld.lld %t.o -o %t.so -shared
55# RUN: llvm-objdump -d %t.so | FileCheck %s
6# RUN: llvm-readobj -relocations %t.so | FileCheck -check-prefix=REL %s
6# RUN: llvm-readobj -r %t.so | FileCheck -check-prefix=REL %s
77
88# REQUIRES: mips
99
......@@ -38,15 +38,14 @@ Sections:
3838 Type: R_MIPS_JALR
3939
4040Symbols:
41 Local:
42 - Name: T1
43 Type: STT_FUNC
44 Section: .text
45 Value: 0
46 Size: 4
47 Global:
48 - Name: __start
49 Type: STT_FUNC
50 Section: .text
51 Value: 0
52 Size: 4
41 - Name: T1
42 Type: STT_FUNC
43 Section: .text
44 Value: 0
45 Size: 4
46 - Name: __start
47 Type: STT_FUNC
48 Section: .text
49 Value: 0
50 Size: 4
51 Binding: STB_GLOBAL
deps/lld/test/ELF/mips-merge-abiflags.s+2-2
......@@ -4,8 +4,8 @@
44
55# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o
66# RUN: ld.lld %t.o %p/Inputs/mips-concatenated-abiflags.o -o %t.exe
7# RUN: llvm-readobj -sections -mips-abi-flags %t.exe | FileCheck %s
8# RUN: llvm-readobj -sections -mips-abi-flags \
7# RUN: llvm-readobj --sections --mips-abi-flags %t.exe | FileCheck %s
8# RUN: llvm-readobj --sections --mips-abi-flags \
99# RUN: %p/Inputs/mips-concatenated-abiflags.o | \
1010# RUN: FileCheck --check-prefix=INPUT-OBJECT %s
1111
deps/lld/test/ELF/mips-mgot.s+21-21
......@@ -8,14 +8,14 @@
88# RUN: %p/Inputs/mips-mgot-2.s -o %t2.o
99# RUN: ld.lld -shared -mips-got-size 52 %t0.o %t1.o %t2.o -o %t.so
1010# RUN: llvm-objdump -s -section=.got -t %t.so | FileCheck %s
11# RUN: llvm-readobj -r -dt -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
11# RUN: llvm-readobj -r --dyn-syms --mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
1212
1313# CHECK: Contents of section .got:
14# CHECK-NEXT: 60000 00000000 80000000 00010000 00010030
15# CHECK-NEXT: 60010 00000000 00000004 00020000 00030000
16# CHECK-NEXT: 60020 00040000 00050000 00060000 00070000
17# CHECK-NEXT: 60030 00000000 00000000 00000000 00000000
18# CHECK-NEXT: 60040 00000000 00000000 00000000
14# CHECK-NEXT: 70000 00000000 80000000 00010000 00010030
15# CHECK-NEXT: 70010 00000000 00000004 00030000 00040000
16# CHECK-NEXT: 70020 00050000 00060000 00070000 00080000
17# CHECK-NEXT: 70030 00000000 00000000 00000000 00000000
18# CHECK-NEXT: 70040 00000000 00000000 00000000
1919
2020# CHECK: SYMBOL TABLE:
2121# CHECK: 00000000 l O .tdata 00000000 loc0
......@@ -28,20 +28,20 @@
2828
2929# GOT: Relocations [
3030# GOT-NEXT: Section (7) .rel.dyn {
31# GOT-NEXT: 0x60018 R_MIPS_REL32 - 0x0
32# GOT-NEXT: 0x6001C R_MIPS_REL32 - 0x0
33# GOT-NEXT: 0x60020 R_MIPS_REL32 - 0x0
34# GOT-NEXT: 0x60024 R_MIPS_REL32 - 0x0
35# GOT-NEXT: 0x60028 R_MIPS_REL32 - 0x0
36# GOT-NEXT: 0x6002C R_MIPS_REL32 - 0x0
37# GOT-NEXT: 0x60030 R_MIPS_REL32 foo0 0x0
38# GOT-NEXT: 0x60034 R_MIPS_REL32 foo2 0x0
39# GOT-NEXT: 0x60044 R_MIPS_TLS_DTPMOD32 - 0x0
40# GOT-NEXT: 0x60010 R_MIPS_TLS_TPREL32 tls0 0x0
41# GOT-NEXT: 0x60038 R_MIPS_TLS_TPREL32 tls0 0x0
42# GOT-NEXT: 0x6003C R_MIPS_TLS_DTPMOD32 tls0 0x0
43# GOT-NEXT: 0x60040 R_MIPS_TLS_DTPREL32 tls0 0x0
44# GOT-NEXT: 0x60014 R_MIPS_TLS_TPREL32 tls1 0x0
31# GOT-NEXT: 0x70018 R_MIPS_REL32 - 0x0
32# GOT-NEXT: 0x7001C R_MIPS_REL32 - 0x0
33# GOT-NEXT: 0x70020 R_MIPS_REL32 - 0x0
34# GOT-NEXT: 0x70024 R_MIPS_REL32 - 0x0
35# GOT-NEXT: 0x70028 R_MIPS_REL32 - 0x0
36# GOT-NEXT: 0x7002C R_MIPS_REL32 - 0x0
37# GOT-NEXT: 0x70030 R_MIPS_REL32 foo0 0x0
38# GOT-NEXT: 0x70034 R_MIPS_REL32 foo2 0x0
39# GOT-NEXT: 0x70044 R_MIPS_TLS_DTPMOD32 - 0x0
40# GOT-NEXT: 0x70010 R_MIPS_TLS_TPREL32 tls0 0x0
41# GOT-NEXT: 0x70038 R_MIPS_TLS_TPREL32 tls0 0x0
42# GOT-NEXT: 0x7003C R_MIPS_TLS_DTPMOD32 tls0 0x0
43# GOT-NEXT: 0x70040 R_MIPS_TLS_DTPREL32 tls0 0x0
44# GOT-NEXT: 0x70014 R_MIPS_TLS_TPREL32 tls1 0x0
4545# GOT-NEXT: }
4646# GOT-NEXT: ]
4747
......@@ -57,7 +57,7 @@
5757# GOT-NEXT: ]
5858
5959# GOT: Primary GOT {
60# GOT-NEXT: Canonical gp value: 0x67FF0
60# GOT-NEXT: Canonical gp value: 0x77FF0
6161# GOT-NEXT: Reserved entries [
6262# GOT-NEXT: Entry {
6363# GOT-NEXT: Address:
deps/lld/test/ELF/mips-micro-bad-cross-calls.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: mips
2# Check error message for invalid cross-mode branch instructions.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
5# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
6# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
7# RUN: not ld.lld -o %t.exe %t1.o %t2.o 2>&1 | FileCheck %s
8
9# CHECK: (.text+0x0): unsupported jump/branch instruction between ISA modes referenced by R_MICROMIPS_PC10_S1 relocation
10
11 .text
12 .set micromips
13 .global __start
14__start:
15 b16 foo0
deps/lld/test/ELF/mips-micro-cross-calls.s created+44
......@@ -0,0 +1,44 @@
1# REQUIRES: mips
2# Check various cases of microMIPS - regular code cross-calls.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
5# RUN: -mattr=micromips %s -o %t-eb.o
6# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
7# RUN: -position-independent -mattr=micromips \
8# RUN: %S/Inputs/mips-micro.s -o %t-eb-pic.o
9# RUN: ld.lld -o %t-eb.exe %t-eb.o %t-eb-pic.o
10# RUN: llvm-objdump -d -mattr=-micromips %t-eb.exe \
11# RUN: | FileCheck --check-prefix=REG %s
12# RUN: llvm-objdump -d -mattr=+micromips %t-eb.exe \
13# RUN: | FileCheck --check-prefix=MICRO %s
14
15# REG: __start:
16# REG-NEXT: 20000: 74 00 80 04 jalx 131088 <micro>
17# REG-NEXT: 20004: 00 00 00 00 nop
18# REG-NEXT: 20008: 74 00 80 08 jalx 131104 <__microLA25Thunk_foo>
19
20# REG: __LA25Thunk_bar:
21# REG-NEXT: 20030: 3c 19 00 02 lui $25, 2
22# REG-NEXT: 20034: 08 00 80 11 j 131140 <bar>
23
24# MICRO: micro:
25# MICRO-NEXT: 20010: f0 00 80 00 jalx 65536
26# MICRO-NEXT: 20014: 00 00 00 00 nop
27# MICRO-NEXT: 20018: f0 00 80 0c jalx 65560
28
29# MICRO: __microLA25Thunk_foo:
30# MICRO-NEXT: 20020: 41 b9 00 02 lui $25, 2
31# MICRO-NEXT: 20024: d4 01 00 20 j 131136
32
33 .text
34 .set nomicromips
35 .global __start
36__start:
37 jal micro
38 jal foo
39
40 .set micromips
41 .global micro
42micro:
43 jal __start
44 jal bar
deps/lld/test/ELF/mips-micro-got.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
88# RUN: ld.lld %t2.o -shared -o %t.so
99# RUN: ld.lld %t1.o %t.so -o %t.exe
10# RUN: llvm-readobj -mips-plt-got %t.exe | FileCheck %s
10# RUN: llvm-readobj --mips-plt-got %t.exe | FileCheck %s
1111
1212# CHECK: Local entries [
1313# CHECK-NEXT: Entry {
deps/lld/test/ELF/mips-micro-jal.s+7-2
......@@ -8,7 +8,7 @@
88# RUN: -mattr=micromips %s -o %t2eb.o
99# RUN: ld.lld -o %teb.exe %t2eb.o %teb.so
1010# RUN: llvm-objdump -d -mattr=micromips %teb.exe | FileCheck --check-prefix=EB %s
11# RUN: llvm-readobj -mips-plt-got %teb.exe | FileCheck --check-prefix=PLT %s
11# RUN: llvm-readobj --mips-plt-got %teb.exe | FileCheck --check-prefix=PLT %s
1212
1313# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \
1414# RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1el.o
......@@ -17,7 +17,7 @@
1717# RUN: -mattr=micromips %s -o %t2el.o
1818# RUN: ld.lld -o %tel.exe %t2el.o %tel.so
1919# RUN: llvm-objdump -d -mattr=micromips %tel.exe | FileCheck --check-prefix=EL %s
20# RUN: llvm-readobj -mips-plt-got %tel.exe | FileCheck --check-prefix=PLT %s
20# RUN: llvm-readobj --mips-plt-got %tel.exe | FileCheck --check-prefix=PLT %s
2121
2222# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
2323# RUN: -mattr=micromips -mcpu=mips32r6 %S/Inputs/mips-micro.s -o %t1eb.o
......@@ -47,6 +47,7 @@
4747# RUN: | FileCheck --check-prefix=MIXED %s
4848
4949# EB: Disassembly of section .plt:
50# EB-EMPTY:
5051# EB-NEXT: .plt:
5152# EB-NEXT: 20010: 79 80 3f fd addiupc $3, 65524
5253# EB-NEXT: 20014: ff 23 00 00 lw $25, 0($3)
......@@ -64,6 +65,7 @@
6465# EB-NEXT: 2003a: 0f 02 move $24, $2
6566
6667# EL: Disassembly of section .plt:
68# EL-EMPTY:
6769# EL-NEXT: .plt:
6870# EL-NEXT: 20010: 80 79 fd 3f addiupc $3, 65524
6971# EL-NEXT: 20014: 23 ff 00 00 lw $25, 0($3)
......@@ -81,6 +83,7 @@
8183# EL-NEXT: 2003a: 02 0f move $24, $2
8284
8385# EBR6: Disassembly of section .plt:
86# EBR6-EMPTY:
8487# EBR6-NEXT: .plt:
8588# EBR6-NEXT: 20010: 78 60 3f fd lapc $3, 65524
8689# EBR6-NEXT: 20014: ff 23 00 00 lw $25, 0($3)
......@@ -97,6 +100,7 @@
97100# EBR6-NEXT: 2003a: 47 23 jrc16 $25
98101
99102# ELR6: Disassembly of section .plt:
103# ELR6-EMPTY:
100104# ELR6-NEXT: .plt:
101105# ELR6-NEXT: 20010: 60 78 fd 3f lapc $3, 65524
102106# ELR6-NEXT: 20014: 23 ff 00 00 lw $25, 0($3)
......@@ -113,6 +117,7 @@
113117# ELR6-NEXT: 2003a: 23 47 jrc16 $25
114118
115119# MIXED: Disassembly of section .plt:
120# MIXED-EMPTY:
116121# MIXED-NEXT: .plt:
117122# MIXED-NEXT: 20020: 79 80 3f f9 addiupc $3, 65508
118123# MIXED-NEXT: 20024: ff 23 00 00 lw $25, 0($3)
deps/lld/test/ELF/mips-micro-plt.s+3-3
......@@ -7,7 +7,7 @@
77# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
88# RUN: -mattr=micromips %s -o %t-exe.o
99# RUN: ld.lld %t-exe.o %t.so -o %t.exe
10# RUN: llvm-readobj -t -dt -mips-plt-got %t.exe | FileCheck %s
10# RUN: llvm-readobj --symbols --dyn-syms --mips-plt-got %t.exe | FileCheck %s
1111# RUN: llvm-objdump -d -mattr=micromips %t.exe | FileCheck --check-prefix=ASM %s
1212
1313# CHECK: Symbols [
......@@ -87,9 +87,9 @@
8787
8888# ASM: __start:
8989# ASM-NEXT: 20000: fd 1c 80 18 lw $8, -32744($gp)
90# ASM-NEXT: 20004: 11 08 00 10 addi $8, $8, 16
90# ASM-NEXT: 20004: 11 08 00 11 addi $8, $8, 17
9191# ASM-NEXT: 20008: 41 a8 00 02 lui $8, 2
92# ASM-NEXT: 2000c: 11 08 00 40 addi $8, $8, 64
92# ASM-NEXT: 2000c: 11 08 00 41 addi $8, $8, 65
9393#
9494# ASM: foo:
9595# ASM-NEXT: 20010: f4 01 00 20 jal 131136
deps/lld/test/ELF/mips-micro-relocs.s+30-7
......@@ -6,20 +6,22 @@
66# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
77# RUN: -mattr=micromips %s -o %t2eb.o
88# RUN: ld.lld -o %teb.exe %t1eb.o %t2eb.o
9# RUN: llvm-objdump -d -t -mattr=micromips %teb.exe \
9# RUN: llvm-objdump -d -t -s -mattr=micromips %teb.exe \
1010# RUN: | FileCheck --check-prefixes=EB,SYM %s
11# RUN: llvm-readobj -h %teb.exe | FileCheck --check-prefix=ELF %s
1112
1213# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \
1314# RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1el.o
1415# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \
1516# RUN: -mattr=micromips %s -o %t2el.o
1617# RUN: ld.lld -o %tel.exe %t1el.o %t2el.o
17# RUN: llvm-objdump -d -t -mattr=micromips %tel.exe \
18# RUN: llvm-objdump -d -t -s -mattr=micromips %tel.exe \
1819# RUN: | FileCheck --check-prefixes=EL,SYM %s
20# RUN: llvm-readobj -h %tel.exe | FileCheck --check-prefix=ELF %s
1921
2022# EB: __start:
2123# EB-NEXT: 20010: 41 a3 00 01 lui $3, 1
22# EB-NEXT: 20014: 30 63 7f df addiu $3, $3, 32735
24# EB-NEXT: 20014: 30 63 7f ef addiu $3, $3, 32751
2325# EB-NEXT: 20018: fc 7c 80 18 lw $3, -32744($gp)
2426# EB-NEXT: 2001c: fc 63 80 18 lw $3, -32744($3)
2527# EB-NEXT: 20020: 8f 70 beqz16 $6, -32
......@@ -28,9 +30,15 @@
2830# EB-NEXT: 20028: 00 00 00 00 nop
2931# EB-NEXT: 2002c: 94 00 ff e8 b -44
3032
33# EB: Contents of section .data:
34# EB-NEXT: 30000 fffe8011
35
36# EB: Contents of section .debug_info
37# EB-NEXT: 0000 00020011
38
3139# EL: __start:
3240# EL-NEXT: 20010: a3 41 01 00 lui $3, 1
33# EL-NEXT: 20014: 63 30 df 7f addiu $3, $3, 32735
41# EL-NEXT: 20014: 63 30 ef 7f addiu $3, $3, 32751
3442# EL-NEXT: 20018: 7c fc 18 80 lw $3, -32744($gp)
3543# EL-NEXT: 2001c: 63 fc 18 80 lw $3, -32744($3)
3644# EL-NEXT: 20020: 70 8f beqz16 $6, -32
......@@ -39,9 +47,18 @@
3947# EL-NEXT: 20028: 00 00 00 00 nop
4048# EL-NEXT: 2002c: 00 94 e8 ff b -44
4149
42# SYM: 00037ff0 .got 00000000 .hidden _gp
43# SYM: 00020000 g F .text 00000000 foo
44# SYM: 00020010 .text 00000000 __start
50# EL: Contents of section .data:
51# EL-NEXT: 30000 1180feff
52
53# EL: Contents of section .debug_info
54# EL-NEXT: 0000 11000200
55
56# SYM: 00038000 .got 00000000 .hidden _gp
57# SYM: 00020000 g F .text 00000000 0x80 foo
58# SYM: 00020010 .text 00000000 0x80 __start
59
60# ELF: ElfHeader {
61# ELF: Entry: 0x20011
4562
4663 .text
4764 .set micromips
......@@ -56,3 +73,9 @@ __start:
5673 beqz16 $6, foo # R_MICROMIPS_PC7_S1
5774 b16 foo # R_MICROMIPS_PC10_S1
5875 b foo # R_MICROMIPS_PC16_S1
76
77 .data
78 .gpword __start # R_MIPS_GPREL32
79
80 .section .debug_info
81 .word __start # R_MIPS_32
deps/lld/test/ELF/mips-micror6-relocs.s+2-2
......@@ -26,8 +26,8 @@
2626# EL-NEXT: 20014: 7f 80 f6 ff beqzc $3, -36
2727# EL-NEXT: 20018: ff b7 f4 ff balc -24 <foo>
2828
29# SYM: 00020000 g F .text 00000000 foo
30# SYM: 00020010 .text 00000000 __start
29# SYM: 00020000 g F .text 00000000 0x80 foo
30# SYM: 00020010 .text 00000000 0x80 __start
3131
3232 .text
3333 .set micromips
deps/lld/test/ELF/mips-n32-rels.s+1
......@@ -24,6 +24,7 @@ loc:
2424 .gpword(loc) # R_MIPS_GPREL32
2525
2626# CHECK: Disassembly of section .text:
27# CHECK-EMPTY:
2728# CHECK-NEXT: __start:
2829# CHECK-NEXT: 20000: 3c 1c 00 01 lui $gp, 1
2930# ^-- 0x20000 - 0x37ff0
deps/lld/test/ELF/mips-non-zero-gp0.s+2-2
......@@ -34,11 +34,11 @@
3434# lui $gp,%hi(%neg(%gp_rel(foo)))
3535
3636# RUN: ld.lld -r -o %t-32.r %S/Inputs/mips-gp0-non-zero.o
37# RUN: llvm-readobj -mips-reginfo %t-32.r | FileCheck --check-prefix=GPVAL %s
37# RUN: llvm-readobj --mips-reginfo %t-32.r | FileCheck --check-prefix=GPVAL %s
3838# RUN: llvm-objdump -s %t-32.r | FileCheck --check-prefix=ADDEND32 %s
3939
4040# RUN: ld.lld -r -o %t-64.r %S/Inputs/mips-n64-gp0-non-zero.o
41# RUN: llvm-readobj -mips-options %t-64.r | FileCheck --check-prefix=GPVAL %s
41# RUN: llvm-readobj --mips-options %t-64.r | FileCheck --check-prefix=GPVAL %s
4242# RUN: llvm-readobj -r %S/Inputs/mips-n64-gp0-non-zero.o %t-64.r \
4343# RUN: | FileCheck --check-prefix=ADDEND64 %s
4444
deps/lld/test/ELF/mips-npic-call-pic-os.s+5
......@@ -14,6 +14,7 @@
1414# RUN: llvm-objdump -d %t.exe | FileCheck %s
1515
1616# CHECK: Disassembly of section .text:
17# CHECK-EMPTY:
1718# CHECK-NEXT: __LA25Thunk_foo1a:
1819# CHECK-NEXT: 20000: 3c 19 00 02 lui $25, 2
1920# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
......@@ -52,7 +53,9 @@
5253
5354# CHECK: fnpic:
5455# CHECK-NEXT: 20070: 00 00 00 00 nop
56# CHECK-EMPTY:
5557# CHECK-NEXT: Disassembly of section differentos:
58# CHECK-EMPTY:
5659# CHECK-NEXT: __start:
5760# CHECK-NEXT: 20074: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
5861# CHECK-NEXT: 20078: 00 00 00 00 nop
......@@ -74,6 +77,7 @@
7477# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s
7578
7679# REVERSE: Disassembly of section .text:
80# REVERSE-EMPTY:
7781# REVERSE-NEXT: __LA25Thunk_foo1a:
7882# REVERSE-NEXT: 20000: 3c 19 00 02 lui $25, 2
7983# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
......@@ -114,6 +118,7 @@
114118# REVERSE-NEXT: 20070: 00 00 00 00 nop
115119
116120# REVERSE: Disassembly of section differentos:
121# REVERSE-EMPTY:
117122# REVERSE-NEXT: __start:
118123# REVERSE-NEXT: 20074: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
119124# REVERSE-NEXT: 20078: 00 00 00 00 nop
deps/lld/test/ELF/mips-npic-call-pic-script.s+5
......@@ -14,6 +14,7 @@
1414# RUN: llvm-objdump -d %t.exe | FileCheck %s
1515
1616# CHECK: Disassembly of section .out:
17# CHECK-EMPTY:
1718# CHECK-NEXT: __LA25Thunk_foo1a:
1819# CHECK-NEXT: 20000: 3c 19 00 02 lui $25, 2
1920# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
......@@ -84,6 +85,7 @@ __start:
8485# RUN: llvm-objdump -d %t2.exe | FileCheck -check-prefix=ORPH1 %s
8586
8687# ORPH1: Disassembly of section .text:
88# ORPH1-EMPTY:
8789# ORPH1-NEXT: __start:
8890# ORPH1-NEXT: 20000: 0c 00 80 15 jal 131156 <__LA25Thunk_foo1a>
8991# ORPH1-NEXT: 20004: 00 00 00 00 nop
......@@ -144,6 +146,7 @@ __start:
144146# RUN: llvm-objdump -d %t3.exe | FileCheck -check-prefix=ORPH2 %s
145147
146148# ORPH2: Disassembly of section .out:
149# ORPH2-EMPTY:
147150# ORPH2-NEXT: __start:
148151# ORPH2-NEXT: 20000: 0c 00 80 18 jal 131168 <__LA25Thunk_foo1a>
149152# ORPH2-NEXT: 20004: 00 00 00 00 nop
......@@ -169,7 +172,9 @@ __start:
169172
170173# ORPH2: fnpic:
171174# ORPH2-NEXT: 20050: 00 00 00 00 nop
175# ORPH2-EMPTY:
172176# ORPH2-NEXT: Disassembly of section .text:
177# ORPH2-EMPTY:
173178
174179# ORPH2-NEXT: __LA25Thunk_foo1a:
175180# ORPH2-NEXT: 20060: 3c 19 00 02 lui $25, 2
deps/lld/test/ELF/mips-npic-call-pic.s+49-23
......@@ -2,18 +2,32 @@
22# Check LA25 stubs creation. This stub code is necessary when
33# non-PIC code calls PIC function.
44
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r2 \
66# RUN: %p/Inputs/mips-fpic.s -o %t-fpic.o
7# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
7# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r2 \
88# RUN: %p/Inputs/mips-fnpic.s -o %t-fnpic.o
9# RUN: ld.lld -r %t-fpic.o %t-fnpic.o -o %t-sto-pic.o
10# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
11# RUN: %p/Inputs/mips-pic.s -o %t-pic.o
12# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o
13# RUN: ld.lld %t-npic.o %t-pic.o %t-sto-pic.o -o %t.exe
14# RUN: llvm-objdump -d %t.exe | FileCheck %s
9# RUN: ld.lld -r %t-fpic.o %t-fnpic.o -o %t-sto-pic-r2.o
10# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r2 \
11# RUN: %p/Inputs/mips-pic.s -o %t-pic-r2.o
12# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r2 \
13# RUN: %s -o %t-npic-r2.o
14# RUN: ld.lld %t-npic-r2.o %t-pic-r2.o %t-sto-pic-r2.o -o %t-r2.exe
15# RUN: llvm-objdump -d %t-r2.exe | FileCheck --check-prefixes=CHECK,R2 %s
16
17# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r6 \
18# RUN: %p/Inputs/mips-fpic.s -o %t-fpic.o
19# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r6 \
20# RUN: %p/Inputs/mips-fnpic.s -o %t-fnpic.o
21# RUN: ld.lld -r %t-fpic.o %t-fnpic.o -o %t-sto-pic-r6.o
22# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r6 \
23# RUN: %p/Inputs/mips-pic.s -o %t-pic-r6.o
24# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r6 \
25# RUN: %s -o %t-npic-r6.o
26# RUN: ld.lld %t-npic-r6.o %t-pic-r6.o %t-sto-pic-r6.o -o %t-r6.exe
27# RUN: llvm-objdump -d %t-r6.exe | FileCheck --check-prefixes=CHECK,R6 %s
1528
1629# CHECK: Disassembly of section .text:
30# CHECK-EMPTY:
1731# CHECK-NEXT: __start:
1832# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120 <__LA25Thunk_foo1a>
1933# CHECK-NEXT: 20004: 00 00 00 00 nop
......@@ -29,13 +43,15 @@
2943# CHECK-NEXT: 2002c: 00 00 00 00 nop
3044#
3145# CHECK: __LA25Thunk_foo1a:
32# CHECK-NEXT: 20030: 3c 19 00 02 lui $25, 2
33# CHECK-NEXT: 20034: 08 00 80 14 j 131152 <foo1a>
46# R2: 20030: 3c 19 00 02 lui $25, 2
47# R6: 20030: 3c 19 00 02 aui $25, $zero, 2
48# CHECK: 20034: 08 00 80 14 j 131152 <foo1a>
3449# CHECK-NEXT: 20038: 27 39 00 50 addiu $25, $25, 80
3550# CHECK-NEXT: 2003c: 00 00 00 00 nop
3651
3752# CHECK: __LA25Thunk_foo1b:
38# CHECK-NEXT: 20040: 3c 19 00 02 lui $25, 2
53# R2: 20040: 3c 19 00 02 lui $25, 2
54# R6: 20040: 3c 19 00 02 aui $25, $zero, 2
3955# CHECK-NEXT: 20044: 08 00 80 15 j 131156 <foo1b>
4056# CHECK-NEXT: 20048: 27 39 00 54 addiu $25, $25, 84
4157# CHECK-NEXT: 2004c: 00 00 00 00 nop
......@@ -47,7 +63,8 @@
4763# CHECK-NEXT: 20054: 00 00 00 00 nop
4864
4965# CHECK: __LA25Thunk_foo2:
50# CHECK-NEXT: 20058: 3c 19 00 02 lui $25, 2
66# R2: 20058: 3c 19 00 02 lui $25, 2
67# R6: 20058: 3c 19 00 02 aui $25, $zero, 2
5168# CHECK-NEXT: 2005c: 08 00 80 1c j 131184 <foo2>
5269# CHECK-NEXT: 20060: 27 39 00 70 addiu $25, $25, 112
5370# CHECK-NEXT: 20064: 00 00 00 00 nop
......@@ -56,7 +73,8 @@
5673# CHECK-NEXT: 20070: 00 00 00 00 nop
5774
5875# CHECK: __LA25Thunk_fpic:
59# CHECK-NEXT: 20074: 3c 19 00 02 lui $25, 2
76# R2: 20074: 3c 19 00 02 lui $25, 2
77# R6: 20074: 3c 19 00 02 aui $25, $zero, 2
6078# CHECK-NEXT: 20078: 08 00 80 24 j 131216 <fpic>
6179# CHECK-NEXT: 2007c: 27 39 00 90 addiu $25, $25, 144
6280# CHECK-NEXT: 20080: 00 00 00 00 nop
......@@ -70,19 +88,25 @@
7088# Make sure the thunks are created properly no matter how
7189# objects are laid out.
7290#
73# RUN: ld.lld %t-pic.o %t-npic.o %t-sto-pic.o -o %t.exe
74# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s
91# RUN: ld.lld %t-pic-r2.o %t-npic-r2.o %t-sto-pic-r2.o -o %t.exe
92# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefixes=REVERSE,REV-R2 %s
93#
94# RUN: ld.lld %t-pic-r6.o %t-npic-r6.o %t-sto-pic-r6.o -o %t.exe
95# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefixes=REVERSE,REV-R6 %s
7596
7697# REVERSE: Disassembly of section .text:
98# REVERSE-EMPTY:
7799# REVERSE-NEXT: __LA25Thunk_foo1a:
78# REVERSE-NEXT: 20000: 3c 19 00 02 lui $25, 2
79# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
100# REV-R2: 20000: 3c 19 00 02 lui $25, 2
101# REV-R6: 20000: 3c 19 00 02 aui $25, $zero, 2
102# REVERSE: 20004: 08 00 80 08 j 131104 <foo1a>
80103# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
81104# REVERSE-NEXT: 2000c: 00 00 00 00 nop
82105
83106# REVERSE: __LA25Thunk_foo1b:
84# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 2
85# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
107# REV-R2: 20010: 3c 19 00 02 lui $25, 2
108# REV-R6: 20010: 3c 19 00 02 aui $25, $zero, 2
109# REVERSE: 20014: 08 00 80 09 j 131108 <foo1b>
86110# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
87111# REVERSE-NEXT: 2001c: 00 00 00 00 nop
88112
......@@ -93,8 +117,9 @@
93117# REVERSE-NEXT: 20024: 00 00 00 00 nop
94118
95119# REVERSE: __LA25Thunk_foo2:
96# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 2
97# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
120# REV-R2: 20028: 3c 19 00 02 lui $25, 2
121# REV-R6: 20028: 3c 19 00 02 aui $25, $zero, 2
122# REVERSE: 2002c: 08 00 80 10 j 131136 <foo2>
98123# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
99124# REVERSE-NEXT: 20034: 00 00 00 00 nop
100125
......@@ -116,8 +141,9 @@
116141# REVERSE-NEXT: 2007c: 00 00 00 00 nop
117142
118143# REVERSE: __LA25Thunk_fpic:
119# REVERSE-NEXT: 20080: 3c 19 00 02 lui $25, 2
120# REVERSE-NEXT: 20084: 08 00 80 24 j 131216 <fpic>
144# REV-R2: 20080: 3c 19 00 02 lui $25, 2
145# REV-R6: 20080: 3c 19 00 02 aui $25, $zero, 2
146# REVERSE: 20084: 08 00 80 24 j 131216 <fpic>
121147# REVERSE-NEXT: 20088: 27 39 00 90 addiu $25, $25, 144
122148# REVERSE-NEXT: 2008c: 00 00 00 00 nop
123149
deps/lld/test/ELF/mips-options-r.test+1-1
......@@ -11,7 +11,7 @@
1111# % as -mabi=64 -mips64r2 t.s
1212
1313# RUN: ld.lld -r %p/Inputs/mips-options.o -o %t.o
14# RUN: llvm-readobj -s %t.o | FileCheck %s
14# RUN: llvm-readobj -S %t.o | FileCheck %s
1515
1616# REQUIRES: mips
1717
deps/lld/test/ELF/mips-options.s+14-1
......@@ -8,7 +8,7 @@
88# RUN: . = 0x100000000; \
99# RUN: .got : { *(.got) } }" > %t.rel.script
1010# RUN: ld.lld %t1.o %t2.o --gc-sections --script %t.rel.script -shared -o %t.so
11# RUN: llvm-readobj -symbols -mips-options %t.so | FileCheck %s
11# RUN: llvm-readobj -l --symbols --mips-options %t.so | FileCheck %s
1212
1313 .text
1414 .globl __start
......@@ -18,6 +18,19 @@ __start:
1818# CHECK: Name: _gp
1919# CHECK-NEXT: Value: 0x[[GP:[0-9A-F]+]]
2020
21# CHECK: ProgramHeader {
22# CHECK: Type: PT_MIPS_OPTIONS
23# CHECK-NEXT: Offset:
24# CHECK-NEXT: VirtualAddress:
25# CHECK-NEXT: PhysicalAddress:
26# CHECK-NEXT: FileSize:
27# CHECK-NEXT: MemSize:
28# CHECK-NEXT: Flags [
29# CHECK-NEXT: PF_R
30# CHECK-NEXT: ]
31# CHECK-NEXT: Alignment: 8
32# CHECK-NEXT: }
33
2134# CHECK: MIPS Options {
2235# CHECK-NEXT: ODK_REGINFO {
2336# CHECK-NEXT: GP: 0x[[GP]]
deps/lld/test/ELF/mips-pc-relocs.s+1
......@@ -22,6 +22,7 @@ __start:
2222 .word _foo+8-. # R_MIPS_PC32
2323
2424# CHECK: Disassembly of section .text:
25# CHECK-EMPTY:
2526# CHECK-NEXT: __start:
2627# CHECK-NEXT: 20000: ec c8 00 08 lwpc $6, 32
2728# ^-- (0x20020-0x20000)>>2
deps/lld/test/ELF/mips-plt-copy.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
88# RUN: ld.lld %t.so.o -shared -o %t.so
99# RUN: ld.lld %t.o %t.so -o %t.exe
10# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
10# RUN: llvm-readobj -r --mips-plt-got %t.exe | FileCheck %s
1111
1212# CHECK: Relocations [
1313# CHECK-NEXT: Section ({{.*}}) .rel.dyn {
deps/lld/test/ELF/mips-plt-n32.s+3
......@@ -14,12 +14,15 @@
1414# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=HAZARDPLT,CHECK
1515
1616# CHECK: Disassembly of section .text:
17# CHECK-EMPTY:
1718# CHECK-NEXT: __start:
1819# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120
1920# ^-- 0x20030 gotplt[foo0]
2021# CHECK-NEXT: 20004: 00 00 00 00 nop
2122#
23# CHECK-EMPTY:
2224# CHECK-NEXT: Disassembly of section .plt:
25# CHECK-EMPTY:
2326# CHECK-NEXT: .plt:
2427# CHECK-NEXT: 20010: 3c 0e 00 03 lui $14, 3
2528# CHECK-NEXT: 20014: 8d d9 00 04 lw $25, 4($14)
deps/lld/test/ELF/mips-plt-n64.s created+42
......@@ -0,0 +1,42 @@
1# REQUIRES: mips
2# Check R_MIPS_26 relocation handling in case of N64 ABIs.
3
4# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
5# RUN: %S/Inputs/mips-dynamic.s -o %t-so.o
6# RUN: ld.lld %t-so.o -shared -o %t.so
7# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
8# RUN: ld.lld %t.o %t.so -o %t.exe
9# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=CHECK,DEFAULT
10# RUN: ld.lld %t-so.o -shared -o %t.so -z hazardplt
11# RUN: ld.lld %t.o %t.so -o %t.exe -z hazardplt
12# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=CHECK,HAZARDPLT
13
14# CHECK: Disassembly of section .text:
15# CHECK-EMPTY:
16# CHECK-NEXT: __start:
17# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120
18# CHECK-NEXT: 20004: 00 00 00 00 nop
19# CHECK-EMPTY:
20# CHECK-NEXT: Disassembly of section .plt:
21# CHECK-EMPTY:
22# CHECK-NEXT: .plt:
23# CHECK-NEXT: 20010: 3c 0e 00 03 lui $14, 3
24# CHECK-NEXT: 20014: dd d9 00 08 ld $25, 8($14)
25# CHECK-NEXT: 20018: 25 ce 00 08 addiu $14, $14, 8
26# CHECK-NEXT: 2001c: 03 0e c0 23 subu $24, $24, $14
27# CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra
28# CHECK-NEXT: 20024: 00 18 c0 c2 srl $24, $24, 3
29# DEFAULT: 20028: 03 20 f8 09 jalr $25
30# HAZARDPLT: 20028: 03 20 fc 09 jalr.hb $25
31# CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2
32# CHECK-NEXT: 20030: 3c 0f 00 03 lui $15, 3
33# CHECK-NEXT: 20034: dd f9 00 18 ld $25, 24($15)
34# DEFAULT: 20038: 03 20 00 08 jr $25
35# HAZARDPLT: 20038: 03 20 04 08 jr.hb $25
36# CHECK-NEXT: 2003c: 65 f8 00 18 daddiu $24, $15, 24
37
38 .text
39 .option pic0
40 .global __start
41__start:
42 jal foo0
deps/lld/test/ELF/mips-plt-r6.s+3
......@@ -13,12 +13,15 @@
1313# RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=HAZARDPLT,CHECK
1414
1515# CHECK: Disassembly of section .text:
16# CHECK-EMPTY:
1617# CHECK-NEXT: __start:
1718# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120
1819# ^-- 0x20030 gotplt[foo0]
1920# CHECK-NEXT: 20004: 00 00 00 00 nop
2021#
22# CHECK-EMPTY:
2123# CHECK-NEXT: Disassembly of section .plt:
24# CHECK-EMPTY:
2225# CHECK-NEXT: .plt:
2326# CHECK-NEXT: 20010: 3c 1c 00 03 aui $gp, $zero, 3
2427# CHECK-NEXT: 20014: 8f 99 00 04 lw $25, 4($gp)
deps/lld/test/ELF/mips-reginfo.s+1-1
......@@ -5,7 +5,7 @@
55# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
66# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
77# RUN: ld.lld %t1.o %t2.o --gc-sections -shared -o %t.so
8# RUN: llvm-readobj -symbols -mips-reginfo %t.so | FileCheck %s
8# RUN: llvm-readobj --symbols --mips-reginfo %t.so | FileCheck %s
99
1010 .text
1111 .globl __start
deps/lld/test/ELF/mips-sto-pic-flag.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
88# RUN: %p/Inputs/mips-pic.s -o %t-pic.o
99# RUN: ld.lld -r %t-npic.o %t-pic.o -o %t-rel.o
10# RUN: llvm-readobj -t %t-rel.o | FileCheck %s
10# RUN: llvm-readobj --symbols %t-rel.o | FileCheck %s
1111
1212# CHECK: Symbol {
1313# CHECK: Name: main
deps/lld/test/ELF/mips-sto-plt.s+1-1
......@@ -6,7 +6,7 @@
66# RUN: ld.lld %t.so.o -shared -o %t.so
77# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
88# RUN: ld.lld %t.o %t.so -o %t.exe
9# RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s
9# RUN: llvm-readobj --dyn-syms --mips-plt-got %t.exe | FileCheck %s
1010
1111# CHECK: Symbol {
1212# CHECK: Name: foo0
deps/lld/test/ELF/mips-tls-64.s+24-24
......@@ -8,11 +8,11 @@
88
99# RUN: ld.lld %t.o %t.so -o %t.exe
1010# RUN: llvm-objdump -d -s -t %t.exe | FileCheck -check-prefix=DIS %s
11# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
11# RUN: llvm-readobj -r --mips-plt-got %t.exe | FileCheck %s
1212
1313# RUN: ld.lld -shared %t.o %t.so -o %t-out.so
1414# RUN: llvm-objdump -d -s -t %t-out.so | FileCheck -check-prefix=DIS-SO %s
15# RUN: llvm-readobj -r -mips-plt-got %t-out.so | FileCheck -check-prefix=SO %s
15# RUN: llvm-readobj -r --mips-plt-got %t-out.so | FileCheck -check-prefix=SO %s
1616
1717# DIS: __start:
1818# DIS-NEXT: 20000: 24 62 80 30 addiu $2, $3, -32720
......@@ -22,11 +22,11 @@
2222# DIS-NEXT: 20010: 24 62 80 28 addiu $2, $3, -32728
2323
2424# DIS: Contents of section .got:
25# DIS-NEXT: 30010 00000000 00000000 80000000 00000000
26# DIS-NEXT: 30020 00000000 00000000 ffffffff ffff9004
27# DIS-NEXT: 30030 00000000 00000000 00000000 00000000
28# DIS-NEXT: 30040 00000000 00000001 00000000 00000000
29# DIS-NEXT: 30050 00000000 00000001 ffffffff ffff8004
25# DIS-NEXT: 40010 00000000 00000000 80000000 00000000
26# DIS-NEXT: 40020 00000000 00000000 ffffffff ffff9004
27# DIS-NEXT: 40030 00000000 00000000 00000000 00000000
28# DIS-NEXT: 40040 00000000 00000001 00000000 00000000
29# DIS-NEXT: 40050 00000000 00000001 ffffffff ffff8004
3030
3131# DIS: 0000000000000000 l O .tdata 00000000 loc
3232# DIS: 0000000000000004 g O .tdata 00000000 bar
......@@ -34,13 +34,13 @@
3434
3535# CHECK: Relocations [
3636# CHECK-NEXT: Section (7) .rel.dyn {
37# CHECK-NEXT: 0x30020 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
38# CHECK-NEXT: 0x30030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
39# CHECK-NEXT: 0x30038 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
37# CHECK-NEXT: 0x40020 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
38# CHECK-NEXT: 0x40030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
39# CHECK-NEXT: 0x40038 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
4040# CHECK-NEXT: }
4141# CHECK-NEXT: ]
4242# CHECK-NEXT: Primary GOT {
43# CHECK-NEXT: Canonical gp value: 0x38000
43# CHECK-NEXT: Canonical gp value: 0x48000
4444# CHECK-NEXT: Reserved entries [
4545# CHECK: ]
4646# CHECK-NEXT: Local entries [
......@@ -58,25 +58,25 @@
5858# ^-- -32680 VA - 0x8000 bar
5959
6060# DIS-SO: Contents of section .got:
61# DIS-SO-NEXT: 20000 00000000 00000000 80000000 00000000
62# DIS-SO-NEXT: 20010 00000000 00000000 00000000 00000004
63# DIS-SO-NEXT: 20020 00000000 00000000 00000000 00000000
64# DIS-SO-NEXT: 20030 00000000 00000000 00000000 00000000
65# DIS-SO-NEXT: 20040 00000000 00000000 00000000 00000000
61# DIS-SO-NEXT: 30000 00000000 00000000 80000000 00000000
62# DIS-SO-NEXT: 30010 00000000 00000000 00000000 00000004
63# DIS-SO-NEXT: 30020 00000000 00000000 00000000 00000000
64# DIS-SO-NEXT: 30030 00000000 00000000 00000000 00000000
65# DIS-SO-NEXT: 30040 00000000 00000000 00000000 00000000
6666
6767# SO: Relocations [
6868# SO-NEXT: Section (7) .rel.dyn {
69# SO-NEXT: 0x20030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0
70# SO-NEXT: 0x20018 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
71# SO-NEXT: 0x20040 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
72# SO-NEXT: 0x20048 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
73# SO-NEXT: 0x20010 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
74# SO-NEXT: 0x20020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
75# SO-NEXT: 0x20028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
69# SO-NEXT: 0x30030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0
70# SO-NEXT: 0x30018 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
71# SO-NEXT: 0x30040 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
72# SO-NEXT: 0x30048 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
73# SO-NEXT: 0x30010 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
74# SO-NEXT: 0x30020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
75# SO-NEXT: 0x30028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
7676# SO-NEXT: }
7777# SO-NEXT: ]
7878# SO-NEXT: Primary GOT {
79# SO-NEXT: Canonical gp value: 0x27FF0
79# SO-NEXT: Canonical gp value: 0x37FF0
8080# SO-NEXT: Reserved entries [
8181# SO: ]
8282# SO-NEXT: Local entries [
deps/lld/test/ELF/mips-tls-hilo.s+2-2
......@@ -5,10 +5,10 @@
55# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
66# RUN: ld.lld %t.o -o %t.exe
77# RUN: llvm-objdump -d -t %t.exe | FileCheck -check-prefix=DIS %s
8# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
8# RUN: llvm-readobj -r --mips-plt-got %t.exe | FileCheck %s
99
1010# RUN: ld.lld %t.o -shared -o %t.so
11# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=SO %s
11# RUN: llvm-readobj -r --mips-plt-got %t.so | FileCheck -check-prefix=SO %s
1212
1313# DIS: __start:
1414# DIS-NEXT: 20000: 24 62 00 00 addiu $2, $3, 0
deps/lld/test/ELF/mips-tls-static-64.s+2-2
......@@ -7,8 +7,8 @@
77# RUN: llvm-objdump -s -t %t.exe | FileCheck %s
88
99# CHECK: Contents of section .data:
10# CHECK-NEXT: 30000 00020004 ffffffff ffff8004 ffffffff
11# CHECK-NEXT: 30010 ffff9004
10# CHECK-NEXT: 40000 00020004 ffffffff ffff8004 ffffffff
11# CHECK-NEXT: 40010 ffff9004
1212#
1313# CHECK: SYMBOL TABLE:
1414# CHECK: 0000000000020004 .text 00000000 __tls_get_addr
deps/lld/test/ELF/mips-tls-static.s+3-3
......@@ -7,10 +7,10 @@
77# RUN: llvm-objdump -s -t %t.exe | FileCheck %s
88
99# CHECK: Contents of section .data:
10# CHECK-NEXT: 30000 0002000c ffff8004 ffff9004
10# CHECK-NEXT: 40000 0002000c ffff8004 ffff9004
1111# CHECK: Contents of section .got:
12# CHECK-NEXT: 30010 00000000 80000000 ffff9000 00000001
13# CHECK-NEXT: 30020 ffff8000 00000001 00000000
12# CHECK-NEXT: 40010 00000000 80000000 ffff9000 00000001
13# CHECK-NEXT: 40020 ffff8000 00000001 00000000
1414#
1515# CHECK: SYMBOL TABLE:
1616# CHECK: 0002000c .text 00000000 __tls_get_addr
deps/lld/test/ELF/mips-tls.s+20-20
......@@ -8,11 +8,11 @@
88
99# RUN: ld.lld %t.o %t.so -o %t.exe
1010# RUN: llvm-objdump -d -s -t %t.exe | FileCheck -check-prefix=DIS %s
11# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
11# RUN: llvm-readobj -r --mips-plt-got %t.exe | FileCheck %s
1212
1313# RUN: ld.lld -shared %t.o %t.so -o %t-out.so
1414# RUN: llvm-objdump -d -s -t %t-out.so | FileCheck -check-prefix=DIS-SO %s
15# RUN: llvm-readobj -r -mips-plt-got %t-out.so | FileCheck -check-prefix=SO %s
15# RUN: llvm-readobj -r --mips-plt-got %t-out.so | FileCheck -check-prefix=SO %s
1616
1717# DIS: __start:
1818# DIS-NEXT: 20000: 24 62 80 20 addiu $2, $3, -32736
......@@ -22,9 +22,9 @@
2222# DIS-NEXT: 20010: 24 62 80 1c addiu $2, $3, -32740
2323
2424# DIS: Contents of section .got:
25# DIS-NEXT: 30010 00000000 80000000 00000000 ffff9004
26# DIS-NEXT: 30020 00000000 00000000 00000001 00000000
27# DIS-NEXT: 30030 00000001 ffff8004
25# DIS-NEXT: 40010 00000000 80000000 00000000 ffff9004
26# DIS-NEXT: 40020 00000000 00000000 00000001 00000000
27# DIS-NEXT: 40030 00000001 ffff8004
2828
2929# DIS: 00000000 l O .tdata 00000000 loc
3030# DIS: 00000004 g O .tdata 00000000 bar
......@@ -32,13 +32,13 @@
3232
3333# CHECK: Relocations [
3434# CHECK-NEXT: Section (7) .rel.dyn {
35# CHECK-NEXT: 0x30018 R_MIPS_TLS_TPREL32 foo 0x0
36# CHECK-NEXT: 0x30020 R_MIPS_TLS_DTPMOD32 foo 0x0
37# CHECK-NEXT: 0x30024 R_MIPS_TLS_DTPREL32 foo 0x0
35# CHECK-NEXT: 0x40018 R_MIPS_TLS_TPREL32 foo 0x0
36# CHECK-NEXT: 0x40020 R_MIPS_TLS_DTPMOD32 foo 0x0
37# CHECK-NEXT: 0x40024 R_MIPS_TLS_DTPREL32 foo 0x0
3838# CHECK-NEXT: }
3939# CHECK-NEXT: ]
4040# CHECK-NEXT: Primary GOT {
41# CHECK-NEXT: Canonical gp value: 0x38000
41# CHECK-NEXT: Canonical gp value: 0x48000
4242# CHECK-NEXT: Reserved entries [
4343# CHECK: ]
4444# CHECK-NEXT: Local entries [
......@@ -56,23 +56,23 @@
5656# ^-- -32716 VA - 0x8000 bar
5757
5858# DIS-SO: Contents of section .got:
59# DIS-SO-NEXT: 20000 00000000 80000000 00000000 00000004
60# DIS-SO-NEXT: 20010 00000000 00000000 00000000 00000000
61# DIS-SO-NEXT: 20020 00000000 00000000
59# DIS-SO-NEXT: 30000 00000000 80000000 00000000 00000004
60# DIS-SO-NEXT: 30010 00000000 00000000 00000000 00000000
61# DIS-SO-NEXT: 30020 00000000 00000000
6262
6363# SO: Relocations [
6464# SO-NEXT: Section (7) .rel.dyn {
65# SO-NEXT: 0x20018 R_MIPS_TLS_DTPMOD32 - 0x0
66# SO-NEXT: 0x2000C R_MIPS_TLS_TPREL32 bar 0x0
67# SO-NEXT: 0x20020 R_MIPS_TLS_DTPMOD32 bar 0x0
68# SO-NEXT: 0x20024 R_MIPS_TLS_DTPREL32 bar 0x0
69# SO-NEXT: 0x20008 R_MIPS_TLS_TPREL32 foo 0x0
70# SO-NEXT: 0x20010 R_MIPS_TLS_DTPMOD32 foo 0x0
71# SO-NEXT: 0x20014 R_MIPS_TLS_DTPREL32 foo 0x0
65# SO-NEXT: 0x30018 R_MIPS_TLS_DTPMOD32 - 0x0
66# SO-NEXT: 0x3000C R_MIPS_TLS_TPREL32 bar 0x0
67# SO-NEXT: 0x30020 R_MIPS_TLS_DTPMOD32 bar 0x0
68# SO-NEXT: 0x30024 R_MIPS_TLS_DTPREL32 bar 0x0
69# SO-NEXT: 0x30008 R_MIPS_TLS_TPREL32 foo 0x0
70# SO-NEXT: 0x30010 R_MIPS_TLS_DTPMOD32 foo 0x0
71# SO-NEXT: 0x30014 R_MIPS_TLS_DTPREL32 foo 0x0
7272# SO-NEXT: }
7373# SO-NEXT: ]
7474# SO-NEXT: Primary GOT {
75# SO-NEXT: Canonical gp value: 0x27FF0
75# SO-NEXT: Canonical gp value: 0x37FF0
7676# SO-NEXT: Reserved entries [
7777# SO: ]
7878# SO-NEXT: Local entries [
deps/lld/test/ELF/mips-xgot-order.s+1
......@@ -7,6 +7,7 @@
77# RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s
88
99# CHECK: Disassembly of section .text:
10# CHECK-EMPTY:
1011# CHECK-NEXT: __start:
1112# CHECK-NEXT: 20000: 3c 02 00 00 lui $2, 0
1213# CHECK-NEXT: 20004: 8c 42 80 24 lw $2, -32732($2)
deps/lld/test/ELF/msp430.s+1
......@@ -13,6 +13,7 @@ foo:
1313 jmp _start
1414
1515; CHECK: Disassembly of section .text:
16; CHECK-EMPTY:
1617; CHECK-NEXT: _start:
1718; CHECK-NEXT: 8000: {{.*}} nop
1819; CHECK: foo:
deps/lld/test/ELF/new-dtags.test+2-2
......@@ -10,11 +10,11 @@
1010// RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=ENABLE %s
1111
1212// DISABLE: DynamicSection [
13// DISABLE: 0x000000000000000F RPATH /somepath
13// DISABLE: 0x000000000000000F RPATH Library rpath: [/somepath]
1414// DISABLE-NOT: RUNPATH
1515// DISABLE: ]
1616
1717// ENABLE: DynamicSection [
18// ENABLE: 0x000000000000001D RUNPATH /somepath
18// ENABLE: 0x000000000000001D RUNPATH Library runpath: [/somepath]
1919// ENABLE-NOT: RPATH
2020// ENABLE: ]
deps/lld/test/ELF/no-discard-this_module.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -save-temp-labels %s -o %t
33// RUN: ld.lld %t -o %t2
4// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
4// RUN: llvm-readobj -S --section-data --symbols %t2 | FileCheck %s
55
66.global _start
77_start:
deps/lld/test/ELF/no-inhibit-exec.s+1
......@@ -6,6 +6,7 @@
66# RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=RELOC
77
88# CHECK: Disassembly of section .text:
9# CHECK-EMPTY:
910# CHECK-NEXT: _start
1011# CHECK-NEXT: 201000: {{.*}} callq -2101253
1112
deps/lld/test/ELF/non-abs-reloc.s+1
......@@ -6,6 +6,7 @@
66
77// RUN: llvm-objdump -D %t | FileCheck --check-prefix=DISASM %s
88// DISASM: Disassembly of section .nonalloc:
9// DISASM-EMPTY:
910// DISASM-NEXT: .nonalloc:
1011// DISASM-NEXT: 0: {{.*}} callq {{.*}} <_start>
1112// DISASM-NEXT: 5: {{.*}} callq {{.*}} <_start>
deps/lld/test/ELF/non-alloc-link-order-gc.s+1
......@@ -6,6 +6,7 @@
66## Check that we are able to GC non-allocatable metadata sections without crash.
77
88# CHECK: Disassembly of section .stack_sizes:
9# CHECK-EMPTY:
910# CHECK-NEXT: .stack_sizes:
1011# CHECK-NEXT: 01
1112
deps/lld/test/ELF/noplt-pie.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
44# RUN: ld.lld -shared %t2.o -o %t2.so
55# RUN: ld.lld --hash-style=sysv %t1.o %t2.so -o %t.out
6# RUN: llvm-readobj -s -r %t.out | FileCheck %s
6# RUN: llvm-readobj -S -r %t.out | FileCheck %s
77
88# CHECK: Section {
99# CHECK-NOT: Name: .plt
deps/lld/test/ELF/note-alignment.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readelf -l %t | FileCheck %s
5
6# Check that we don't mix 4-byte and 8-byte aligned notes in one PT_LOAD.
7# The possible 4-byte padding before the 8-byte align note may make consumers
8# fail to parse it.
9
10# CHECK: NOTE {{0x[0-9a-f]+}} {{0x[0-9a-f]+}} {{0x[0-9a-f]+}} 0x000004 0x000004 R 0x4
11# CHECK: NOTE {{0x[0-9a-f]+}} {{0x[0-9a-f]+}} {{0x[0-9a-f]+}} 0x000010 0x000010 R 0x8
12# CHECK: NOTE {{0x[0-9a-f]+}} {{0x[0-9a-f]+}} {{0x[0-9a-f]+}} 0x000008 0x000008 R 0x4
13
14# CHECK: 03 .note.a
15# CHECK-NEXT: 04 .note.b .note.c
16# CHECK-NEXT: 05 .note.d .note.e
17
18.section .note.a, "a", @note
19.align 4
20.long 0
21
22.section .note.b, "a", @note
23.align 8
24.quad 0
25
26.section .note.c, "a", @note
27.align 8
28.quad 0
29
30.section .note.d, "a", @note
31.align 4
32.long 0
33
34.section .note.e, "a", @note
35.align 4
36.long 0
deps/lld/test/ELF/note-contiguous.s+2-2
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33
44// RUN: ld.lld %t.o -o %t1
5// RUN: llvm-readobj -program-headers %t1 | FileCheck %s
5// RUN: llvm-readobj -l %t1 | FileCheck %s
66
77// CHECK: Type: PT_NOTE
88// CHECK-NEXT: Offset:
......@@ -18,7 +18,7 @@
1818
1919// RUN: echo "SECTIONS { .note : { *(.note.a) *(.note.b) } }" > %t.script
2020// RUN: ld.lld %t.o --script %t.script -o %t2
21// RUN: llvm-readobj -program-headers %t2 | FileCheck -check-prefix=SCRIPT %s
21// RUN: llvm-readobj -l %t2 | FileCheck -check-prefix=SCRIPT %s
2222
2323// SCRIPT: Type: PT_NOTE
2424// SCRIPT-NEXT: Offset:
deps/lld/test/ELF/note-loadaddr.s+1-1
......@@ -5,7 +5,7 @@
55// RUN: .note.b : AT(0x2000) { *(.note.b) } \
66// RUN: }" > %t.script
77// RUN: ld.lld %t.o --script %t.script -o %t
8// RUN: llvm-readobj -program-headers %t | FileCheck %s
8// RUN: llvm-readobj -l %t | FileCheck %s
99
1010// CHECK: Type: PT_NOTE
1111// CHECK-NEXT: Offset: 0x1000
deps/lld/test/ELF/note-multiple.s+1-1
......@@ -7,7 +7,7 @@
77// RUN: .note.d : { *(.note.d) } \
88// RUN: }" > %t.script
99// RUN: ld.lld %t.o --script %t.script -o %t
10// RUN: llvm-readobj -program-headers %t | FileCheck %s
10// RUN: llvm-readobj -l %t | FileCheck %s
1111
1212// CHECK: Type: PT_NOTE
1313// CHECK-NEXT: Offset: 0x1000
deps/lld/test/ELF/note-noalloc.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 -o %t -shared
4// RUN: llvm-readobj -program-headers -sections %t | FileCheck %s
4// RUN: llvm-readobj -l --sections %t | FileCheck %s
55
66// PR37361: A note without SHF_ALLOC should not be included into a PT_NOTE program header.
77
deps/lld/test/ELF/note-noalloc2.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 -o %t
4# RUN: llvm-readobj -program-headers %t | FileCheck %s
4# RUN: llvm-readobj -l %t | FileCheck %s
55
66## Check we do not create a PT_NOTE segment for non-allocatable note section.
77
deps/lld/test/ELF/note.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 -o %t -shared
4// RUN: llvm-readobj -program-headers %t | FileCheck %s
4// RUN: llvm-readobj -l %t | FileCheck %s
55
66// CHECK: Type: PT_NOTE
77// CHECK-NEXT: Offset:
deps/lld/test/ELF/output-section.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %t2
4// RUN: llvm-readobj -t %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols %t2 | FileCheck %s
55
66// CHECK: Symbol {
77// CHECK: Name: bar_sym
deps/lld/test/ELF/pack-dyn-relocs-loop.s+12-12
......@@ -1,8 +1,8 @@
11// REQUIRES: arm, aarch64
22
33// 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
4// RUN: ld.lld -shared %t.o -o %t.so --pack-dyn-relocs=android -z norelro
5// RUN: llvm-readobj -S %t.so | FileCheck %s
66
77// This test is making sure the Android packed relocation support doesn't
88// cause an infinite loop due to the size of the section oscillating
......@@ -16,8 +16,8 @@
1616// CHECK-NEXT: Flags [ (0x2)
1717// CHECK-NEXT: SHF_ALLOC (0x2)
1818// CHECK-NEXT: ]
19// CHECK-NEXT: Address: 0x210
20// CHECK-NEXT: Offset: 0x210
19// CHECK-NEXT: Address: 0x1D8
20// CHECK-NEXT: Offset: 0x1D8
2121// CHECK-NEXT: Size: 21
2222
2323// CHECK: Name: x (43)
......@@ -25,9 +25,9 @@
2525// CHECK-NEXT: Flags [ (0x2)
2626// CHECK-NEXT: SHF_ALLOC (0x2)
2727// CHECK-NEXT: ]
28// CHECK-NEXT: Address: 0x225
29// CHECK-NEXT: Offset: 0x225
30// CHECK-NEXT: Size: 64980
28// CHECK-NEXT: Address: 0x1ED
29// CHECK-NEXT: Offset: 0x1ED
30// CHECK-NEXT: Size: 65036
3131
3232// CHECK: Name: barr (45)
3333// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
......@@ -46,7 +46,7 @@
4646// CHECK-NEXT: ]
4747// CHECK-NEXT: Address: 0x10004
4848// CHECK-NEXT: Offset: 0x10004
49// CHECK-NEXT: Size: 12
49// CHECK-NEXT: Size: 24
5050
5151
5252.data
......@@ -54,12 +54,12 @@
5454
5555.section foo,"aw"
5656foof:
57.long foof
58.long bar-53
59.long bar
57.quad foof
58.quad bar-53
59.quad bar
6060
6161.section x,"a"
62.zero 64980
62.zero 65036
6363
6464.section barr,"a"
6565.p2align 1
deps/lld/test/ELF/pack-dyn-relocs-tls-aarch64.s+1-1
......@@ -2,7 +2,7 @@
22
33// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o
44// RUN: ld.lld -shared --pack-dyn-relocs=android %t.o -o %t.so
5// RUN: llvm-readobj -relocations %t.so | FileCheck %s
5// RUN: llvm-readobj -r %t.so | FileCheck %s
66
77// Bug 37841: Symbol::getVA must work on TLS symbols during the layout loop in
88// finalizeSections.
deps/lld/test/ELF/pack-dyn-relocs-tls-x86-64.s+1-1
......@@ -2,7 +2,7 @@
22
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
44// RUN: ld.lld -shared --pack-dyn-relocs=android %t.o -o %t.so
5// RUN: llvm-readobj -relocations %t.so | FileCheck %s
5// RUN: llvm-readobj -r %t.so | FileCheck %s
66
77// Bug 37841: Symbol::getVA must work on TLS symbols during the layout loop in
88// finalizeSections. This test uses an atypical IE access in a shared object to
deps/lld/test/ELF/pack-dyn-relocs.s+192-192
......@@ -4,45 +4,45 @@
44// RUN: ld.lld -shared %t.a32.so.o -o %t.a32.so
55// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.a32
66// RUN: ld.lld -pie --pack-dyn-relocs=none %t.a32 %t.a32.so -o %t2.a32
7// RUN: llvm-readobj -relocations %t2.a32 | FileCheck --check-prefix=UNPACKED32 %s
7// RUN: llvm-readobj -r %t2.a32 | FileCheck --check-prefix=UNPACKED32 %s
88
99// Unpacked should have the relative relocations in their natural order.
1010// UNPACKED32: Section ({{.+}}) .rel.dyn {
11// UNPACKED32-NEXT: 0x1000 R_ARM_RELATIVE - 0x0
12// UNPACKED32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0
13// UNPACKED32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0
14// UNPACKED32-NEXT: 0x100C R_ARM_RELATIVE - 0x0
15// UNPACKED32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0
16// UNPACKED32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0
17// UNPACKED32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0
18// UNPACKED32-NEXT: 0x101C R_ARM_RELATIVE - 0x0
19
20// UNPACKED32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0
21// UNPACKED32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0
22// UNPACKED32-NEXT: 0x102C R_ARM_RELATIVE - 0x0
23// UNPACKED32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0
24// UNPACKED32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0
25// UNPACKED32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0
26// UNPACKED32-NEXT: 0x103C R_ARM_RELATIVE - 0x0
27
28// UNPACKED32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0
29// UNPACKED32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0
30// UNPACKED32-NEXT: 0x104C R_ARM_RELATIVE - 0x0
31// UNPACKED32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0
32// UNPACKED32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0
33// UNPACKED32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0
34// UNPACKED32-NEXT: 0x105C R_ARM_RELATIVE - 0x0
35// UNPACKED32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0
36// UNPACKED32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0
37
38// UNPACKED32-NEXT: 0x1069 R_ARM_RELATIVE - 0x0
39// UNPACKED32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0
40// UNPACKED32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0
11// UNPACKED32-NEXT: 0x2000 R_ARM_RELATIVE - 0x0
12// UNPACKED32-NEXT: 0x2004 R_ARM_RELATIVE - 0x0
13// UNPACKED32-NEXT: 0x2008 R_ARM_RELATIVE - 0x0
14// UNPACKED32-NEXT: 0x200C R_ARM_RELATIVE - 0x0
15// UNPACKED32-NEXT: 0x2010 R_ARM_RELATIVE - 0x0
16// UNPACKED32-NEXT: 0x2014 R_ARM_RELATIVE - 0x0
17// UNPACKED32-NEXT: 0x2018 R_ARM_RELATIVE - 0x0
18// UNPACKED32-NEXT: 0x201C R_ARM_RELATIVE - 0x0
19
20// UNPACKED32-NEXT: 0x2024 R_ARM_RELATIVE - 0x0
21// UNPACKED32-NEXT: 0x2028 R_ARM_RELATIVE - 0x0
22// UNPACKED32-NEXT: 0x202C R_ARM_RELATIVE - 0x0
23// UNPACKED32-NEXT: 0x2030 R_ARM_RELATIVE - 0x0
24// UNPACKED32-NEXT: 0x2034 R_ARM_RELATIVE - 0x0
25// UNPACKED32-NEXT: 0x2038 R_ARM_RELATIVE - 0x0
26// UNPACKED32-NEXT: 0x203C R_ARM_RELATIVE - 0x0
27
28// UNPACKED32-NEXT: 0x2044 R_ARM_RELATIVE - 0x0
29// UNPACKED32-NEXT: 0x2048 R_ARM_RELATIVE - 0x0
30// UNPACKED32-NEXT: 0x204C R_ARM_RELATIVE - 0x0
31// UNPACKED32-NEXT: 0x2050 R_ARM_RELATIVE - 0x0
32// UNPACKED32-NEXT: 0x2054 R_ARM_RELATIVE - 0x0
33// UNPACKED32-NEXT: 0x2058 R_ARM_RELATIVE - 0x0
34// UNPACKED32-NEXT: 0x205C R_ARM_RELATIVE - 0x0
35// UNPACKED32-NEXT: 0x2060 R_ARM_RELATIVE - 0x0
36// UNPACKED32-NEXT: 0x2064 R_ARM_RELATIVE - 0x0
37
38// UNPACKED32-NEXT: 0x2069 R_ARM_RELATIVE - 0x0
39// UNPACKED32-NEXT: 0x2020 R_ARM_ABS32 bar2 0x0
40// UNPACKED32-NEXT: 0x2040 R_ARM_ABS32 zed2 0x0
4141// UNPACKED32-NEXT: }
4242
4343// RUN: ld.lld -pie --pack-dyn-relocs=android %t.a32 %t.a32.so -o %t3.a32
44// RUN: llvm-readobj -s -dynamic-table %t3.a32 | FileCheck --check-prefix=ANDROID32-HEADERS %s
45// RUN: llvm-readobj -relocations %t3.a32 | FileCheck --check-prefix=ANDROID32 %s
44// RUN: llvm-readobj -S --dynamic-table %t3.a32 | FileCheck --check-prefix=ANDROID32-HEADERS %s
45// RUN: llvm-readobj -r %t3.a32 | FileCheck --check-prefix=ANDROID32 %s
4646
4747// ANDROID32-HEADERS: Index: 1
4848// ANDROID32-HEADERS-NEXT: Name: .dynsym
......@@ -66,42 +66,42 @@
6666// Packed should have the larger groups of relative relocations first,
6767// i.e. the 8 and 9 followed by the 7.
6868// ANDROID32: Section ({{.+}}) .rel.dyn {
69// ANDROID32-NEXT: 0x1000 R_ARM_RELATIVE - 0x0
70// ANDROID32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0
71// ANDROID32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0
72// ANDROID32-NEXT: 0x100C R_ARM_RELATIVE - 0x0
73// ANDROID32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0
74// ANDROID32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0
75// ANDROID32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0
76// ANDROID32-NEXT: 0x101C R_ARM_RELATIVE - 0x0
77
78// ANDROID32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0
79// ANDROID32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0
80// ANDROID32-NEXT: 0x104C R_ARM_RELATIVE - 0x0
81// ANDROID32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0
82// ANDROID32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0
83// ANDROID32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0
84// ANDROID32-NEXT: 0x105C R_ARM_RELATIVE - 0x0
85// ANDROID32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0
86// ANDROID32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0
87
88// ANDROID32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0
89// ANDROID32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0
90// ANDROID32-NEXT: 0x102C R_ARM_RELATIVE - 0x0
91// ANDROID32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0
92// ANDROID32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0
93// ANDROID32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0
94// ANDROID32-NEXT: 0x103C R_ARM_RELATIVE - 0x0
95
96// ANDROID32-NEXT: 0x1069 R_ARM_RELATIVE - 0x0
97// ANDROID32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0
98// ANDROID32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0
69// ANDROID32-NEXT: 0x2000 R_ARM_RELATIVE - 0x0
70// ANDROID32-NEXT: 0x2004 R_ARM_RELATIVE - 0x0
71// ANDROID32-NEXT: 0x2008 R_ARM_RELATIVE - 0x0
72// ANDROID32-NEXT: 0x200C R_ARM_RELATIVE - 0x0
73// ANDROID32-NEXT: 0x2010 R_ARM_RELATIVE - 0x0
74// ANDROID32-NEXT: 0x2014 R_ARM_RELATIVE - 0x0
75// ANDROID32-NEXT: 0x2018 R_ARM_RELATIVE - 0x0
76// ANDROID32-NEXT: 0x201C R_ARM_RELATIVE - 0x0
77
78// ANDROID32-NEXT: 0x2044 R_ARM_RELATIVE - 0x0
79// ANDROID32-NEXT: 0x2048 R_ARM_RELATIVE - 0x0
80// ANDROID32-NEXT: 0x204C R_ARM_RELATIVE - 0x0
81// ANDROID32-NEXT: 0x2050 R_ARM_RELATIVE - 0x0
82// ANDROID32-NEXT: 0x2054 R_ARM_RELATIVE - 0x0
83// ANDROID32-NEXT: 0x2058 R_ARM_RELATIVE - 0x0
84// ANDROID32-NEXT: 0x205C R_ARM_RELATIVE - 0x0
85// ANDROID32-NEXT: 0x2060 R_ARM_RELATIVE - 0x0
86// ANDROID32-NEXT: 0x2064 R_ARM_RELATIVE - 0x0
87
88// ANDROID32-NEXT: 0x2024 R_ARM_RELATIVE - 0x0
89// ANDROID32-NEXT: 0x2028 R_ARM_RELATIVE - 0x0
90// ANDROID32-NEXT: 0x202C R_ARM_RELATIVE - 0x0
91// ANDROID32-NEXT: 0x2030 R_ARM_RELATIVE - 0x0
92// ANDROID32-NEXT: 0x2034 R_ARM_RELATIVE - 0x0
93// ANDROID32-NEXT: 0x2038 R_ARM_RELATIVE - 0x0
94// ANDROID32-NEXT: 0x203C R_ARM_RELATIVE - 0x0
95
96// ANDROID32-NEXT: 0x2069 R_ARM_RELATIVE - 0x0
97// ANDROID32-NEXT: 0x2020 R_ARM_ABS32 bar2 0x0
98// ANDROID32-NEXT: 0x2040 R_ARM_ABS32 zed2 0x0
9999// ANDROID32-NEXT: }
100100
101101// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.a32 %t.a32.so -o %t4.a32
102// RUN: llvm-readobj -s -dynamic-table %t4.a32 | FileCheck --check-prefix=RELR32-HEADERS %s
103// RUN: llvm-readobj -relocations -raw-relr %t4.a32 | FileCheck --check-prefix=RAW-RELR32 %s
104// RUN: llvm-readobj -relocations %t4.a32 | FileCheck --check-prefix=RELR32 %s
102// RUN: llvm-readobj -S --dynamic-table %t4.a32 | FileCheck --check-prefix=RELR32-HEADERS %s
103// RUN: llvm-readobj -r --raw-relr %t4.a32 | FileCheck --check-prefix=RAW-RELR32 %s
104// RUN: llvm-readobj -r %t4.a32 | FileCheck --check-prefix=RELR32 %s
105105
106106// RELR32-HEADERS: Index: 1
107107// RELR32-HEADERS-NEXT: Name: .dynsym
......@@ -126,7 +126,7 @@
126126// SHT_RELR section contains address/bitmap entries
127127// encoding the offsets for relative relocation.
128128// RAW-RELR32: Section ({{.+}}) .relr.dyn {
129// RAW-RELR32-NEXT: 0x1000
129// RAW-RELR32-NEXT: 0x2000
130130// RAW-RELR32-NEXT: 0x3FEFEFF
131131// RAW-RELR32-NEXT: }
132132
......@@ -134,81 +134,81 @@
134134// but contains only the relative relocations.
135135// Any relative relocations with odd offset stay in SHT_REL.
136136// RELR32: Section ({{.+}}) .rel.dyn {
137// RELR32-NEXT: 0x1069 R_ARM_RELATIVE - 0x0
138// RELR32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0
139// RELR32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0
137// RELR32-NEXT: 0x2069 R_ARM_RELATIVE - 0x0
138// RELR32-NEXT: 0x2020 R_ARM_ABS32 bar2 0x0
139// RELR32-NEXT: 0x2040 R_ARM_ABS32 zed2 0x0
140140// RELR32-NEXT: }
141141// RELR32-NEXT: Section ({{.+}}) .relr.dyn {
142// RELR32-NEXT: 0x1000 R_ARM_RELATIVE - 0x0
143// RELR32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0
144// RELR32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0
145// RELR32-NEXT: 0x100C R_ARM_RELATIVE - 0x0
146// RELR32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0
147// RELR32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0
148// RELR32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0
149// RELR32-NEXT: 0x101C R_ARM_RELATIVE - 0x0
150
151// RELR32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0
152// RELR32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0
153// RELR32-NEXT: 0x102C R_ARM_RELATIVE - 0x0
154// RELR32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0
155// RELR32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0
156// RELR32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0
157// RELR32-NEXT: 0x103C R_ARM_RELATIVE - 0x0
158
159// RELR32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0
160// RELR32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0
161// RELR32-NEXT: 0x104C R_ARM_RELATIVE - 0x0
162// RELR32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0
163// RELR32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0
164// RELR32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0
165// RELR32-NEXT: 0x105C R_ARM_RELATIVE - 0x0
166// RELR32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0
167// RELR32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0
142// RELR32-NEXT: 0x2000 R_ARM_RELATIVE - 0x0
143// RELR32-NEXT: 0x2004 R_ARM_RELATIVE - 0x0
144// RELR32-NEXT: 0x2008 R_ARM_RELATIVE - 0x0
145// RELR32-NEXT: 0x200C R_ARM_RELATIVE - 0x0
146// RELR32-NEXT: 0x2010 R_ARM_RELATIVE - 0x0
147// RELR32-NEXT: 0x2014 R_ARM_RELATIVE - 0x0
148// RELR32-NEXT: 0x2018 R_ARM_RELATIVE - 0x0
149// RELR32-NEXT: 0x201C R_ARM_RELATIVE - 0x0
150
151// RELR32-NEXT: 0x2024 R_ARM_RELATIVE - 0x0
152// RELR32-NEXT: 0x2028 R_ARM_RELATIVE - 0x0
153// RELR32-NEXT: 0x202C R_ARM_RELATIVE - 0x0
154// RELR32-NEXT: 0x2030 R_ARM_RELATIVE - 0x0
155// RELR32-NEXT: 0x2034 R_ARM_RELATIVE - 0x0
156// RELR32-NEXT: 0x2038 R_ARM_RELATIVE - 0x0
157// RELR32-NEXT: 0x203C R_ARM_RELATIVE - 0x0
158
159// RELR32-NEXT: 0x2044 R_ARM_RELATIVE - 0x0
160// RELR32-NEXT: 0x2048 R_ARM_RELATIVE - 0x0
161// RELR32-NEXT: 0x204C R_ARM_RELATIVE - 0x0
162// RELR32-NEXT: 0x2050 R_ARM_RELATIVE - 0x0
163// RELR32-NEXT: 0x2054 R_ARM_RELATIVE - 0x0
164// RELR32-NEXT: 0x2058 R_ARM_RELATIVE - 0x0
165// RELR32-NEXT: 0x205C R_ARM_RELATIVE - 0x0
166// RELR32-NEXT: 0x2060 R_ARM_RELATIVE - 0x0
167// RELR32-NEXT: 0x2064 R_ARM_RELATIVE - 0x0
168168// RELR32-NEXT: }
169169
170170// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/shared2.s -o %t.a64.so.o
171171// RUN: ld.lld -shared %t.a64.so.o -o %t.a64.so
172172// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.a64
173173// RUN: ld.lld -pie --pack-dyn-relocs=none %t.a64 %t.a64.so -o %t2.a64
174// RUN: llvm-readobj -relocations %t2.a64 | FileCheck --check-prefix=UNPACKED64 %s
174// RUN: llvm-readobj -r %t2.a64 | FileCheck --check-prefix=UNPACKED64 %s
175175
176176// UNPACKED64: Section ({{.+}}) .rela.dyn {
177// UNPACKED64-NEXT: 0x10000 R_AARCH64_RELATIVE - 0x1
178// UNPACKED64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2
179// UNPACKED64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3
180// UNPACKED64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4
181// UNPACKED64-NEXT: 0x10020 R_AARCH64_RELATIVE - 0x5
182// UNPACKED64-NEXT: 0x10028 R_AARCH64_RELATIVE - 0x6
183// UNPACKED64-NEXT: 0x10030 R_AARCH64_RELATIVE - 0x7
184// UNPACKED64-NEXT: 0x10038 R_AARCH64_RELATIVE - 0x8
185
186// UNPACKED64-NEXT: 0x10048 R_AARCH64_RELATIVE - 0x1
187// UNPACKED64-NEXT: 0x10050 R_AARCH64_RELATIVE - 0x2
188// UNPACKED64-NEXT: 0x10058 R_AARCH64_RELATIVE - 0x3
189// UNPACKED64-NEXT: 0x10060 R_AARCH64_RELATIVE - 0x4
190// UNPACKED64-NEXT: 0x10068 R_AARCH64_RELATIVE - 0x5
191// UNPACKED64-NEXT: 0x10070 R_AARCH64_RELATIVE - 0x6
192// UNPACKED64-NEXT: 0x10078 R_AARCH64_RELATIVE - 0x7
193
194// UNPACKED64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x1
195// UNPACKED64-NEXT: 0x10090 R_AARCH64_RELATIVE - 0x2
196// UNPACKED64-NEXT: 0x10098 R_AARCH64_RELATIVE - 0x3
197// UNPACKED64-NEXT: 0x100A0 R_AARCH64_RELATIVE - 0x4
198// UNPACKED64-NEXT: 0x100A8 R_AARCH64_RELATIVE - 0x5
199// UNPACKED64-NEXT: 0x100B0 R_AARCH64_RELATIVE - 0x6
200// UNPACKED64-NEXT: 0x100B8 R_AARCH64_RELATIVE - 0x7
201// UNPACKED64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x8
202// UNPACKED64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x9
203
204// UNPACKED64-NEXT: 0x100D1 R_AARCH64_RELATIVE - 0xA
205// UNPACKED64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1
206// UNPACKED64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0
177// UNPACKED64-NEXT: 0x20000 R_AARCH64_RELATIVE - 0x1
178// UNPACKED64-NEXT: 0x20008 R_AARCH64_RELATIVE - 0x2
179// UNPACKED64-NEXT: 0x20010 R_AARCH64_RELATIVE - 0x3
180// UNPACKED64-NEXT: 0x20018 R_AARCH64_RELATIVE - 0x4
181// UNPACKED64-NEXT: 0x20020 R_AARCH64_RELATIVE - 0x5
182// UNPACKED64-NEXT: 0x20028 R_AARCH64_RELATIVE - 0x6
183// UNPACKED64-NEXT: 0x20030 R_AARCH64_RELATIVE - 0x7
184// UNPACKED64-NEXT: 0x20038 R_AARCH64_RELATIVE - 0x8
185
186// UNPACKED64-NEXT: 0x20048 R_AARCH64_RELATIVE - 0x1
187// UNPACKED64-NEXT: 0x20050 R_AARCH64_RELATIVE - 0x2
188// UNPACKED64-NEXT: 0x20058 R_AARCH64_RELATIVE - 0x3
189// UNPACKED64-NEXT: 0x20060 R_AARCH64_RELATIVE - 0x4
190// UNPACKED64-NEXT: 0x20068 R_AARCH64_RELATIVE - 0x5
191// UNPACKED64-NEXT: 0x20070 R_AARCH64_RELATIVE - 0x6
192// UNPACKED64-NEXT: 0x20078 R_AARCH64_RELATIVE - 0x7
193
194// UNPACKED64-NEXT: 0x20088 R_AARCH64_RELATIVE - 0x1
195// UNPACKED64-NEXT: 0x20090 R_AARCH64_RELATIVE - 0x2
196// UNPACKED64-NEXT: 0x20098 R_AARCH64_RELATIVE - 0x3
197// UNPACKED64-NEXT: 0x200A0 R_AARCH64_RELATIVE - 0x4
198// UNPACKED64-NEXT: 0x200A8 R_AARCH64_RELATIVE - 0x5
199// UNPACKED64-NEXT: 0x200B0 R_AARCH64_RELATIVE - 0x6
200// UNPACKED64-NEXT: 0x200B8 R_AARCH64_RELATIVE - 0x7
201// UNPACKED64-NEXT: 0x200C0 R_AARCH64_RELATIVE - 0x8
202// UNPACKED64-NEXT: 0x200C8 R_AARCH64_RELATIVE - 0x9
203
204// UNPACKED64-NEXT: 0x200D1 R_AARCH64_RELATIVE - 0xA
205// UNPACKED64-NEXT: 0x20040 R_AARCH64_ABS64 bar2 0x1
206// UNPACKED64-NEXT: 0x20080 R_AARCH64_ABS64 zed2 0x0
207207// UNPACKED64-NEXT: }
208208
209209// RUN: ld.lld -pie --pack-dyn-relocs=android %t.a64 %t.a64.so -o %t3.a64
210// RUN: llvm-readobj -s -dynamic-table %t3.a64 | FileCheck --check-prefix=ANDROID64-HEADERS %s
211// RUN: llvm-readobj -relocations %t3.a64 | FileCheck --check-prefix=ANDROID64 %s
210// RUN: llvm-readobj -S --dynamic-table %t3.a64 | FileCheck --check-prefix=ANDROID64-HEADERS %s
211// RUN: llvm-readobj -r %t3.a64 | FileCheck --check-prefix=ANDROID64 %s
212212
213213// ANDROID64-HEADERS: Index: 1
214214// ANDROID64-HEADERS-NEXT: Name: .dynsym
......@@ -230,42 +230,42 @@
230230// ANDROID64-HEADERS: 0x0000000060000012 ANDROID_RELASZ [[SIZE]]
231231
232232// ANDROID64: Section ({{.+}}) .rela.dyn {
233// ANDROID64-NEXT: 0x10000 R_AARCH64_RELATIVE - 0x1
234// ANDROID64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2
235// ANDROID64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3
236// ANDROID64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4
237// ANDROID64-NEXT: 0x10020 R_AARCH64_RELATIVE - 0x5
238// ANDROID64-NEXT: 0x10028 R_AARCH64_RELATIVE - 0x6
239// ANDROID64-NEXT: 0x10030 R_AARCH64_RELATIVE - 0x7
240// ANDROID64-NEXT: 0x10038 R_AARCH64_RELATIVE - 0x8
241
242// ANDROID64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x1
243// ANDROID64-NEXT: 0x10090 R_AARCH64_RELATIVE - 0x2
244// ANDROID64-NEXT: 0x10098 R_AARCH64_RELATIVE - 0x3
245// ANDROID64-NEXT: 0x100A0 R_AARCH64_RELATIVE - 0x4
246// ANDROID64-NEXT: 0x100A8 R_AARCH64_RELATIVE - 0x5
247// ANDROID64-NEXT: 0x100B0 R_AARCH64_RELATIVE - 0x6
248// ANDROID64-NEXT: 0x100B8 R_AARCH64_RELATIVE - 0x7
249// ANDROID64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x8
250// ANDROID64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x9
251
252// ANDROID64-NEXT: 0x10048 R_AARCH64_RELATIVE - 0x1
253// ANDROID64-NEXT: 0x10050 R_AARCH64_RELATIVE - 0x2
254// ANDROID64-NEXT: 0x10058 R_AARCH64_RELATIVE - 0x3
255// ANDROID64-NEXT: 0x10060 R_AARCH64_RELATIVE - 0x4
256// ANDROID64-NEXT: 0x10068 R_AARCH64_RELATIVE - 0x5
257// ANDROID64-NEXT: 0x10070 R_AARCH64_RELATIVE - 0x6
258// ANDROID64-NEXT: 0x10078 R_AARCH64_RELATIVE - 0x7
259
260// ANDROID64-NEXT: 0x100D1 R_AARCH64_RELATIVE - 0xA
261// ANDROID64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1
262// ANDROID64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0
233// ANDROID64-NEXT: 0x20000 R_AARCH64_RELATIVE - 0x1
234// ANDROID64-NEXT: 0x20008 R_AARCH64_RELATIVE - 0x2
235// ANDROID64-NEXT: 0x20010 R_AARCH64_RELATIVE - 0x3
236// ANDROID64-NEXT: 0x20018 R_AARCH64_RELATIVE - 0x4
237// ANDROID64-NEXT: 0x20020 R_AARCH64_RELATIVE - 0x5
238// ANDROID64-NEXT: 0x20028 R_AARCH64_RELATIVE - 0x6
239// ANDROID64-NEXT: 0x20030 R_AARCH64_RELATIVE - 0x7
240// ANDROID64-NEXT: 0x20038 R_AARCH64_RELATIVE - 0x8
241
242// ANDROID64-NEXT: 0x20088 R_AARCH64_RELATIVE - 0x1
243// ANDROID64-NEXT: 0x20090 R_AARCH64_RELATIVE - 0x2
244// ANDROID64-NEXT: 0x20098 R_AARCH64_RELATIVE - 0x3
245// ANDROID64-NEXT: 0x200A0 R_AARCH64_RELATIVE - 0x4
246// ANDROID64-NEXT: 0x200A8 R_AARCH64_RELATIVE - 0x5
247// ANDROID64-NEXT: 0x200B0 R_AARCH64_RELATIVE - 0x6
248// ANDROID64-NEXT: 0x200B8 R_AARCH64_RELATIVE - 0x7
249// ANDROID64-NEXT: 0x200C0 R_AARCH64_RELATIVE - 0x8
250// ANDROID64-NEXT: 0x200C8 R_AARCH64_RELATIVE - 0x9
251
252// ANDROID64-NEXT: 0x20048 R_AARCH64_RELATIVE - 0x1
253// ANDROID64-NEXT: 0x20050 R_AARCH64_RELATIVE - 0x2
254// ANDROID64-NEXT: 0x20058 R_AARCH64_RELATIVE - 0x3
255// ANDROID64-NEXT: 0x20060 R_AARCH64_RELATIVE - 0x4
256// ANDROID64-NEXT: 0x20068 R_AARCH64_RELATIVE - 0x5
257// ANDROID64-NEXT: 0x20070 R_AARCH64_RELATIVE - 0x6
258// ANDROID64-NEXT: 0x20078 R_AARCH64_RELATIVE - 0x7
259
260// ANDROID64-NEXT: 0x200D1 R_AARCH64_RELATIVE - 0xA
261// ANDROID64-NEXT: 0x20040 R_AARCH64_ABS64 bar2 0x1
262// ANDROID64-NEXT: 0x20080 R_AARCH64_ABS64 zed2 0x0
263263// ANDROID64-NEXT: }
264264
265265// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.a64 %t.a64.so -o %t4.a64
266// RUN: llvm-readobj -s -dynamic-table %t4.a64 | FileCheck --check-prefix=RELR64-HEADERS %s
267// RUN: llvm-readobj -relocations -raw-relr %t4.a64 | FileCheck --check-prefix=RAW-RELR64 %s
268// RUN: llvm-readobj -relocations %t4.a64 | FileCheck --check-prefix=RELR64 %s
266// RUN: llvm-readobj -S --dynamic-table %t4.a64 | FileCheck --check-prefix=RELR64-HEADERS %s
267// RUN: llvm-readobj -r --raw-relr %t4.a64 | FileCheck --check-prefix=RAW-RELR64 %s
268// RUN: llvm-readobj -r %t4.a64 | FileCheck --check-prefix=RELR64 %s
269269
270270// RELR64-HEADERS: Index: 1
271271// RELR64-HEADERS-NEXT: Name: .dynsym
......@@ -290,7 +290,7 @@
290290// SHT_RELR section contains address/bitmap entries
291291// encoding the offsets for relative relocation.
292292// RAW-RELR64: Section ({{.+}}) .relr.dyn {
293// RAW-RELR64-NEXT: 0x10000
293// RAW-RELR64-NEXT: 0x20000
294294// RAW-RELR64-NEXT: 0x3FEFEFF
295295// RAW-RELR64-NEXT: }
296296
......@@ -298,37 +298,37 @@
298298// but contains only the relative relocations.
299299// Any relative relocations with odd offset stay in SHT_RELA.
300300// RELR64: Section ({{.+}}) .rela.dyn {
301// RELR64-NEXT: 0x100D1 R_AARCH64_RELATIVE - 0xA
302// RELR64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1
303// RELR64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0
301// RELR64-NEXT: 0x200D1 R_AARCH64_RELATIVE - 0xA
302// RELR64-NEXT: 0x20040 R_AARCH64_ABS64 bar2 0x1
303// RELR64-NEXT: 0x20080 R_AARCH64_ABS64 zed2 0x0
304304// RELR64-NEXT: }
305305// RELR64-NEXT: Section ({{.+}}) .relr.dyn {
306// RELR64-NEXT: 0x10000 R_AARCH64_RELATIVE - 0x0
307// RELR64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x0
308// RELR64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x0
309// RELR64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x0
310// RELR64-NEXT: 0x10020 R_AARCH64_RELATIVE - 0x0
311// RELR64-NEXT: 0x10028 R_AARCH64_RELATIVE - 0x0
312// RELR64-NEXT: 0x10030 R_AARCH64_RELATIVE - 0x0
313// RELR64-NEXT: 0x10038 R_AARCH64_RELATIVE - 0x0
314
315// RELR64-NEXT: 0x10048 R_AARCH64_RELATIVE - 0x0
316// RELR64-NEXT: 0x10050 R_AARCH64_RELATIVE - 0x0
317// RELR64-NEXT: 0x10058 R_AARCH64_RELATIVE - 0x0
318// RELR64-NEXT: 0x10060 R_AARCH64_RELATIVE - 0x0
319// RELR64-NEXT: 0x10068 R_AARCH64_RELATIVE - 0x0
320// RELR64-NEXT: 0x10070 R_AARCH64_RELATIVE - 0x0
321// RELR64-NEXT: 0x10078 R_AARCH64_RELATIVE - 0x0
322
323// RELR64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x0
324// RELR64-NEXT: 0x10090 R_AARCH64_RELATIVE - 0x0
325// RELR64-NEXT: 0x10098 R_AARCH64_RELATIVE - 0x0
326// RELR64-NEXT: 0x100A0 R_AARCH64_RELATIVE - 0x0
327// RELR64-NEXT: 0x100A8 R_AARCH64_RELATIVE - 0x0
328// RELR64-NEXT: 0x100B0 R_AARCH64_RELATIVE - 0x0
329// RELR64-NEXT: 0x100B8 R_AARCH64_RELATIVE - 0x0
330// RELR64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x0
331// RELR64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x0
306// RELR64-NEXT: 0x20000 R_AARCH64_RELATIVE - 0x0
307// RELR64-NEXT: 0x20008 R_AARCH64_RELATIVE - 0x0
308// RELR64-NEXT: 0x20010 R_AARCH64_RELATIVE - 0x0
309// RELR64-NEXT: 0x20018 R_AARCH64_RELATIVE - 0x0
310// RELR64-NEXT: 0x20020 R_AARCH64_RELATIVE - 0x0
311// RELR64-NEXT: 0x20028 R_AARCH64_RELATIVE - 0x0
312// RELR64-NEXT: 0x20030 R_AARCH64_RELATIVE - 0x0
313// RELR64-NEXT: 0x20038 R_AARCH64_RELATIVE - 0x0
314
315// RELR64-NEXT: 0x20048 R_AARCH64_RELATIVE - 0x0
316// RELR64-NEXT: 0x20050 R_AARCH64_RELATIVE - 0x0
317// RELR64-NEXT: 0x20058 R_AARCH64_RELATIVE - 0x0
318// RELR64-NEXT: 0x20060 R_AARCH64_RELATIVE - 0x0
319// RELR64-NEXT: 0x20068 R_AARCH64_RELATIVE - 0x0
320// RELR64-NEXT: 0x20070 R_AARCH64_RELATIVE - 0x0
321// RELR64-NEXT: 0x20078 R_AARCH64_RELATIVE - 0x0
322
323// RELR64-NEXT: 0x20088 R_AARCH64_RELATIVE - 0x0
324// RELR64-NEXT: 0x20090 R_AARCH64_RELATIVE - 0x0
325// RELR64-NEXT: 0x20098 R_AARCH64_RELATIVE - 0x0
326// RELR64-NEXT: 0x200A0 R_AARCH64_RELATIVE - 0x0
327// RELR64-NEXT: 0x200A8 R_AARCH64_RELATIVE - 0x0
328// RELR64-NEXT: 0x200B0 R_AARCH64_RELATIVE - 0x0
329// RELR64-NEXT: 0x200B8 R_AARCH64_RELATIVE - 0x0
330// RELR64-NEXT: 0x200C0 R_AARCH64_RELATIVE - 0x0
331// RELR64-NEXT: 0x200C8 R_AARCH64_RELATIVE - 0x0
332332// RELR64-NEXT: }
333333
334334.data
deps/lld/test/ELF/pack-dyn-relocs2.s+36-36
......@@ -5,46 +5,46 @@
55
66// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
77// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.o %t.so -o %t.exe
8// RUN: llvm-readobj -relocations %t.exe | FileCheck %s
8// RUN: llvm-readobj -r %t.exe | FileCheck %s
99
1010// CHECK: Section (5) .relr.dyn {
11// CHECK-NEXT: 0x1000 R_ARM_RELATIVE - 0x0
12// CHECK-NEXT: 0x1004 R_ARM_RELATIVE - 0x0
13// CHECK-NEXT: 0x1008 R_ARM_RELATIVE - 0x0
14// CHECK-NEXT: 0x100C R_ARM_RELATIVE - 0x0
15// CHECK-NEXT: 0x1010 R_ARM_RELATIVE - 0x0
16// CHECK-NEXT: 0x1014 R_ARM_RELATIVE - 0x0
17// CHECK-NEXT: 0x1018 R_ARM_RELATIVE - 0x0
18// CHECK-NEXT: 0x101C R_ARM_RELATIVE - 0x0
19// CHECK-NEXT: 0x1020 R_ARM_RELATIVE - 0x0
20// CHECK-NEXT: 0x1024 R_ARM_RELATIVE - 0x0
21// CHECK-NEXT: 0x1028 R_ARM_RELATIVE - 0x0
22// CHECK-NEXT: 0x102C R_ARM_RELATIVE - 0x0
23// CHECK-NEXT: 0x1030 R_ARM_RELATIVE - 0x0
24// CHECK-NEXT: 0x1034 R_ARM_RELATIVE - 0x0
25// CHECK-NEXT: 0x1038 R_ARM_RELATIVE - 0x0
26// CHECK-NEXT: 0x103C R_ARM_RELATIVE - 0x0
27// CHECK-NEXT: 0x1040 R_ARM_RELATIVE - 0x0
28// CHECK-NEXT: 0x1044 R_ARM_RELATIVE - 0x0
29// CHECK-NEXT: 0x1048 R_ARM_RELATIVE - 0x0
30// CHECK-NEXT: 0x104C R_ARM_RELATIVE - 0x0
31// CHECK-NEXT: 0x1050 R_ARM_RELATIVE - 0x0
32// CHECK-NEXT: 0x1054 R_ARM_RELATIVE - 0x0
33// CHECK-NEXT: 0x1058 R_ARM_RELATIVE - 0x0
34// CHECK-NEXT: 0x105C R_ARM_RELATIVE - 0x0
35// CHECK-NEXT: 0x1060 R_ARM_RELATIVE - 0x0
36// CHECK-NEXT: 0x1064 R_ARM_RELATIVE - 0x0
37// CHECK-NEXT: 0x1068 R_ARM_RELATIVE - 0x0
38// CHECK-NEXT: 0x106C R_ARM_RELATIVE - 0x0
39// CHECK-NEXT: 0x1070 R_ARM_RELATIVE - 0x0
40// CHECK-NEXT: 0x1074 R_ARM_RELATIVE - 0x0
41// CHECK-NEXT: 0x1078 R_ARM_RELATIVE - 0x0
42// CHECK-NEXT: 0x107C R_ARM_RELATIVE - 0x0
43// CHECK-NEXT: 0x1080 R_ARM_RELATIVE - 0x0
44// CHECK-NEXT: 0x1084 R_ARM_RELATIVE - 0x0
11// CHECK-NEXT: 0x2000 R_ARM_RELATIVE - 0x0
12// CHECK-NEXT: 0x2004 R_ARM_RELATIVE - 0x0
13// CHECK-NEXT: 0x2008 R_ARM_RELATIVE - 0x0
14// CHECK-NEXT: 0x200C R_ARM_RELATIVE - 0x0
15// CHECK-NEXT: 0x2010 R_ARM_RELATIVE - 0x0
16// CHECK-NEXT: 0x2014 R_ARM_RELATIVE - 0x0
17// CHECK-NEXT: 0x2018 R_ARM_RELATIVE - 0x0
18// CHECK-NEXT: 0x201C R_ARM_RELATIVE - 0x0
19// CHECK-NEXT: 0x2020 R_ARM_RELATIVE - 0x0
20// CHECK-NEXT: 0x2024 R_ARM_RELATIVE - 0x0
21// CHECK-NEXT: 0x2028 R_ARM_RELATIVE - 0x0
22// CHECK-NEXT: 0x202C R_ARM_RELATIVE - 0x0
23// CHECK-NEXT: 0x2030 R_ARM_RELATIVE - 0x0
24// CHECK-NEXT: 0x2034 R_ARM_RELATIVE - 0x0
25// CHECK-NEXT: 0x2038 R_ARM_RELATIVE - 0x0
26// CHECK-NEXT: 0x203C R_ARM_RELATIVE - 0x0
27// CHECK-NEXT: 0x2040 R_ARM_RELATIVE - 0x0
28// CHECK-NEXT: 0x2044 R_ARM_RELATIVE - 0x0
29// CHECK-NEXT: 0x2048 R_ARM_RELATIVE - 0x0
30// CHECK-NEXT: 0x204C R_ARM_RELATIVE - 0x0
31// CHECK-NEXT: 0x2050 R_ARM_RELATIVE - 0x0
32// CHECK-NEXT: 0x2054 R_ARM_RELATIVE - 0x0
33// CHECK-NEXT: 0x2058 R_ARM_RELATIVE - 0x0
34// CHECK-NEXT: 0x205C R_ARM_RELATIVE - 0x0
35// CHECK-NEXT: 0x2060 R_ARM_RELATIVE - 0x0
36// CHECK-NEXT: 0x2064 R_ARM_RELATIVE - 0x0
37// CHECK-NEXT: 0x2068 R_ARM_RELATIVE - 0x0
38// CHECK-NEXT: 0x206C R_ARM_RELATIVE - 0x0
39// CHECK-NEXT: 0x2070 R_ARM_RELATIVE - 0x0
40// CHECK-NEXT: 0x2074 R_ARM_RELATIVE - 0x0
41// CHECK-NEXT: 0x2078 R_ARM_RELATIVE - 0x0
42// CHECK-NEXT: 0x207C R_ARM_RELATIVE - 0x0
43// CHECK-NEXT: 0x2080 R_ARM_RELATIVE - 0x0
44// CHECK-NEXT: 0x2084 R_ARM_RELATIVE - 0x0
4545// CHECK-NEXT: }
4646
47// RUN: llvm-readobj -s -dynamic-table %t.exe | FileCheck --check-prefix=HEADER %s
47// RUN: llvm-readobj -S --dynamic-table %t.exe | FileCheck --check-prefix=HEADER %s
4848// HEADER: 0x00000023 RELRSZ 0xC
4949
5050.data
deps/lld/test/ELF/partition-errors.s created+23
......@@ -0,0 +1,23 @@
1// REQUIRES: x86, mips
2// RUN: llvm-mc -triple=x86_64-unknown-linux -filetype=obj -o %t.o %s
3// RUN: echo "SECTIONS {}" > %t.script
4// RUN: not ld.lld --export-dynamic %t.o %t.script 2>&1 | FileCheck %s
5// RUN: echo "PHDRS { text PT_LOAD; }" > %t2.script
6// RUN: not ld.lld --export-dynamic %t.o %t2.script 2>&1 | FileCheck %s
7// RUN: not ld.lld --export-dynamic %t.o --section-start .text=0 2>&1 | FileCheck %s
8// RUN: not ld.lld --export-dynamic %t.o -Ttext=0 2>&1 | FileCheck %s
9// RUN: not ld.lld --export-dynamic %t.o -Tdata=0 2>&1 | FileCheck %s
10// RUN: not ld.lld --export-dynamic %t.o -Tbss=0 2>&1 | FileCheck %s
11
12// RUN: llvm-mc -triple=mipsel-unknown-linux -filetype=obj -o %t2.o %s
13// RUN: not ld.lld --export-dynamic %t2.o 2>&1 | FileCheck %s
14
15// CHECK: error: {{.*}}.o: partitions cannot be used
16
17.section .llvm_sympart.f1,"",@llvm_sympart
18.asciz "part1"
19.quad f1
20
21.text
22.globl f1
23f1:
deps/lld/test/ELF/partition-exidx.s created+49
......@@ -0,0 +1,49 @@
1// Test that exidx output sections are created correctly for each partition.
2
3// REQUIRES: arm
4// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
5// RUN: ld.lld %t.o -o %t -shared --gc-sections
6
7// RUN: llvm-objcopy --extract-main-partition %t %t0
8// RUN: llvm-objcopy --extract-partition=part1 %t %t1
9
10// Change upper case to lower case so that we can match unwind info (which is dumped
11// in upper case) against program headers (which are dumped in lower case).
12// RUN: llvm-readelf -l --unwind %t0 | tr A-Z a-z | FileCheck %s
13// RUN: llvm-readelf -l --unwind %t1 | tr A-Z a-z | FileCheck %s
14
15// Each file should have one exidx section for its text section and one sentinel.
16// CHECK: sectionoffset: 0x[[EXIDX_OFFSET:.*]]
17// CHECK-NEXT: entries [
18// CHECK-NEXT: entry {
19// CHECK-NEXT: functionaddress: 0x[[TEXT_ADDR:.*]]
20// CHECK-NEXT: model: cantunwind
21// CHECK-NEXT: }
22// CHECK-NEXT: entry {
23// CHECK-NEXT: functionaddress:
24// CHECK-NEXT: model: cantunwind
25// CHECK-NEXT: }
26// CHECK-NEXT: ]
27
28// CHECK: load {{[^ ]*}} 0x{{0*}}[[TEXT_ADDR]] {{.*}} r e
29// CHECK: exidx 0x{{0*}}[[EXIDX_OFFSET]] {{.*}} 0x00010 0x00010 r
30
31.section .llvm_sympart,"",%llvm_sympart
32.asciz "part1"
33.4byte p1
34
35.section .text.p0,"ax",%progbits
36.globl p0
37p0:
38.fnstart
39bx lr
40.cantunwind
41.fnend
42
43.section .text.p1,"ax",%progbits
44.globl p1
45p1:
46.fnstart
47bx lr
48.cantunwind
49.fnend
deps/lld/test/ELF/partition-icf.s created+50
......@@ -0,0 +1,50 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux
3// RUN: ld.lld %t.o -o %t --export-dynamic --gc-sections --icf=all
4// RUN: llvm-readelf -S -s %t | FileCheck %s
5
6// CHECK: [[MAIN:[0-9]+]]] .text
7// CHECK: [[P1:[0-9]+]]] .text
8// CHECK: [[P2:[0-9]+]]] .text
9
10// CHECK: Symbol table '.symtab'
11// CHECK: [[P1]] f1
12// CHECK: [[P2]] f2
13// CHECK: [[MAIN]] g1
14// CHECK: [[MAIN]] g2
15
16.section .llvm_sympart.f1,"",@llvm_sympart
17.asciz "part1"
18.quad f1
19
20.section .llvm_sympart.f2,"",@llvm_sympart
21.asciz "part2"
22.quad f2
23
24.section .llvm_sympart.g1,"",@llvm_sympart
25.asciz "part1"
26.quad g1
27
28.section .llvm_sympart.g2,"",@llvm_sympart
29.asciz "part2"
30.quad g2
31
32.section .text.f1,"ax",@progbits
33.globl f1
34f1:
35.byte 1
36
37.section .text.f2,"ax",@progbits
38.globl f2
39f2:
40.byte 2
41
42.section .text.g1,"ax",@progbits
43.globl g1
44g1:
45.byte 3
46
47.section .text.g2,"ax",@progbits
48.globl g2
49g2:
50.byte 3
deps/lld/test/ELF/partition-move-to-main.s created+44
......@@ -0,0 +1,44 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux
3// RUN: ld.lld %t.o -o %t --export-dynamic --gc-sections
4// RUN: llvm-readelf -S -s %t | FileCheck %s
5
6// Ordinarily, the TLS and IFUNC sections would be split into partitions.
7// Make sure that that didn't happen by checking that there is only one
8// of each section.
9
10// CHECK: .ifunc
11// CHECK: .tdata
12
13// CHECK-NOT: .ifunc
14// CHECK-NOT: .tdata
15
16.section .llvm_sympart.f1,"",@llvm_sympart
17.asciz "part1"
18.quad f1
19
20.section .text._start,"ax",@progbits
21.globl _start
22_start:
23call tls1
24call ifunc1
25
26.section .text.f1,"ax",@progbits
27.globl f1
28f1:
29call tls2
30call ifunc2
31
32.section .ifunc,"ax",@progbits,unique,1
33.type ifunc1 STT_GNU_IFUNC
34ifunc1:
35
36.section .ifunc,"ax",@progbits,unique,2
37.type ifunc2 STT_GNU_IFUNC
38ifunc2:
39
40.section .tdata,"awT",@progbits,unique,1
41tls1:
42
43.section .tdata,"awT",@progbits,unique,2
44tls2:
deps/lld/test/ELF/partition-notes.s created+45
......@@ -0,0 +1,45 @@
1// Test that notes (both from object files and synthetic) are duplicated into
2// each partition.
3
4// REQUIRES: x86
5
6// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux
7// RUN: ld.lld %t.o -o %t --shared --gc-sections --build-id=sha1
8
9// RUN: llvm-objcopy --extract-main-partition %t %t0
10// RUN: llvm-objcopy --extract-partition=part1 %t %t1
11
12// RUN: llvm-readelf --all %t0 | FileCheck --check-prefixes=CHECK,PART0 %s
13// RUN: llvm-readelf --all %t1 | FileCheck --check-prefixes=CHECK,PART1 %s
14
15// CHECK: Program Headers:
16// CHECK: NOTE 0x{{0*}}[[NOTE_OFFSET:[^ ]*]]
17
18// CHECK: Displaying notes found at file offset 0x{{0*}}[[NOTE_OFFSET]]
19// CHECK-NEXT: Owner
20// CHECK-NEXT: foo 0x00000004 NT_VERSION (version)
21// CHECK-NEXT: Displaying notes
22// CHECK-NEXT: Owner
23// CHECK-NEXT: GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
24// CHECK-NEXT: Build ID: 0f4d5297cbbe52e4bea558eeb792944670de22e1
25
26.section .llvm_sympart,"",@llvm_sympart
27.asciz "part1"
28.quad p1
29
30.section .data.p0,"aw",@progbits
31.globl p0
32p0:
33
34.section .data.p1,"aw",@progbits
35.globl p1
36p1:
37
38.section .note.obj,"a",@note
39.align 4
40.long 2f-1f
41.long 3f-2f
42.long 1
431: .asciz "foo"
442: .asciz "bar"
453:
deps/lld/test/ELF/partition-pack-dyn-relocs.s created+51
......@@ -0,0 +1,51 @@
1// Test that both Android and RELR packed relocation sections are created
2// correctly for each partition.
3
4// REQUIRES: x86
5
6// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux
7// RUN: ld.lld %t.o -o %t --shared --gc-sections --pack-dyn-relocs=android+relr
8
9// RUN: llvm-objcopy --extract-main-partition %t %t0
10// RUN: llvm-objcopy --extract-partition=part1 %t %t1
11
12// RUN: llvm-readelf --all %t0 | FileCheck --check-prefixes=CHECK,PART0 %s
13// RUN: llvm-readelf --all %t1 | FileCheck --check-prefixes=CHECK,PART1 %s
14
15// CHECK: Section Headers:
16// CHECK: .rela.dyn ANDROID_RELA {{0*}}[[ANDROID_RELA_ADDR:[^ ]*]]
17// CHECK: .relr.dyn RELR {{0*}}[[RELR_ADDR:[^ ]*]]
18// CHECK: .data PROGBITS 000000000000[[DATA_SEGMENT:.]]000
19
20// CHECK: Relocation section '.rela.dyn'
21// CHECK-NEXT: Offset
22// PART0-NEXT: 000000000000[[DATA_SEGMENT]]008 {{.*}} R_X86_64_64 000000000000[[DATA_SEGMENT]]000 p0 + 0
23// PART1-NEXT: 000000000000[[DATA_SEGMENT]]008 {{.*}} R_X86_64_64 000000000000[[DATA_SEGMENT]]000 p1 + 0
24// CHECK-EMPTY:
25
26// CHECK: Relocation section '.relr.dyn'
27// CHECK-NEXT: Offset
28// CHECK-NEXT: 000000000000[[DATA_SEGMENT]]000 {{.*}} R_X86_64_RELATIVE
29// CHECK-EMPTY:
30
31// CHECK: Dynamic section
32// CHECK: 0x0000000060000011 (ANDROID_RELA) 0x[[ANDROID_RELA_ADDR]]
33// CHECK: 0x0000000000000024 (RELR) 0x[[RELR_ADDR]]
34
35.section .llvm_sympart,"",@llvm_sympart
36.asciz "part1"
37.quad p1
38
39.section .data.p0,"aw",@progbits
40.align 8
41.globl p0
42p0:
43.quad __ehdr_start
44.quad p0
45
46.section .data.p1,"aw",@progbits
47.align 8
48.globl p1
49p1:
50.quad __ehdr_start
51.quad p1
deps/lld/test/ELF/partition-synthetic-sections.s created+241
......@@ -0,0 +1,241 @@
1// Test that synthetic sections are created correctly for each partition.
2
3// REQUIRES: x86
4
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed1.s -o %t1.o
6// RUN: echo "v1 {}; v2 {}; v3 { local: *; };" > %t1.script
7// RUN: ld.lld -shared %t1.o --version-script %t1.script -o %t1.so -soname verneed1.so.0
8
9// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux
10// RUN: echo "x1 { global: p0; }; x2 { global: p1; p1alias; };" > %t.script
11// RUN: ld.lld %t.o %t1.so --version-script %t.script -o %t --shared --gc-sections --eh-frame-hdr -soname main.so
12
13// RUN: llvm-objcopy --extract-main-partition %t %t0
14// RUN: llvm-objcopy --extract-partition=part1 %t %t1
15
16// RUN: llvm-readelf --all --unwind %t0 | FileCheck --check-prefixes=CHECK,PART0 %s
17// RUN: llvm-readelf --all --unwind %t1 | FileCheck --check-prefixes=CHECK,PART1 %s
18
19// FIXME: llvm-objcopy does not preserve padding (see pr42145) so for now we
20// check the combined output file.
21// RUN: od -Ax -x %t | FileCheck %s -check-prefix=FILL
22
23// RUN: llvm-objdump -s -j .rodata -j .dynstr %t0 | FileCheck --check-prefix=PART-INDEX %s
24
25// CHECK: Section Headers:
26// CHECK-NEXT: Name
27// CHECK-NEXT: NULL
28// CHECK-NEXT: .dynsym DYNSYM {{0*}}[[DYNSYM_ADDR:[^ ]*]]
29// CHECK-NEXT: .gnu.version VERSYM {{0*}}[[VERSYM_ADDR:[^ ]*]]
30// CHECK-NEXT: .gnu.version_d VERDEF {{0*}}[[VERDEF_ADDR:[^ ]*]]
31// CHECK-NEXT: .gnu.version_r VERNEED {{0*}}[[VERNEED_ADDR:[^ ]*]]
32// CHECK-NEXT: .gnu.hash GNU_HASH {{0*}}[[GNU_HASH_ADDR:[^ ]*]]
33// CHECK-NEXT: .hash HASH {{0*}}[[HASH_ADDR:[^ ]*]]
34// CHECK-NEXT: .dynstr STRTAB {{0*}}[[DYNSTR_ADDR:[^ ]*]]
35// CHECK-NEXT: .rela.dyn RELA {{0*}}[[RELA_DYN_ADDR:[^ ]*]]
36// PART0-NEXT: .rela.plt RELA {{0*}}[[RELA_PLT_ADDR:[^ ]*]]
37// CHECK-NEXT: .eh_frame_hdr PROGBITS {{0*}}[[EH_FRAME_HDR_ADDR:[^ ]*]]
38// CHECK-NEXT: .eh_frame PROGBITS {{0*}}[[EH_FRAME_ADDR:[^ ]*]]
39// PART0-NEXT: .rodata PROGBITS
40// CHECK-NEXT: .text PROGBITS {{0*}}[[TEXT_ADDR:[^ ]*]]
41// PART0-NEXT: .plt PROGBITS
42// PART0-NEXT: .init_array INIT_ARRAY {{0*}}[[INIT_ARRAY_ADDR:[^ ]*]]
43// CHECK-NEXT: .dynamic DYNAMIC {{0*}}[[DYNAMIC_ADDR:[^ ]*]]
44// CHECK-NEXT: .data PROGBITS 000000000000[[DATA_SEGMENT:.]]000
45// PART0-NEXT: .got.plt PROGBITS {{0*}}[[GOT_PLT_ADDR:[^ ]*]]
46// PART0-NEXT: .part.end NOBITS {{0*}}[[PART_END_ADDR:[^ ]*]]
47// CHECK-NEXT: .comment PROGBITS
48// CHECK-NEXT: .symtab SYMTAB
49// CHECK-NEXT: .shstrtab STRTAB
50// CHECK-NEXT: .strtab STRTAB
51// CHECK-NEXT: Key to Flags
52
53// CHECK: Relocation section '.rela.dyn'
54// CHECK-NEXT: Offset
55// PART0-NEXT: 000000000000[[DATA_SEGMENT]]000 {{.*}} R_X86_64_64 {{.*}} f1@v3 + 0
56// PART0-NEXT: {{0*}}[[INIT_ARRAY_ADDR]] {{.*}} R_X86_64_64 {{.*}} p0@@x1 + 0
57// PART1-NEXT: 000000000000[[DATA_SEGMENT]]018 {{.*}} R_X86_64_RELATIVE 3000
58// PART1-NEXT: 000000000000[[DATA_SEGMENT]]000 {{.*}} R_X86_64_64 {{.*}} f2@v2 + 0
59// PART1-NEXT: 000000000000[[DATA_SEGMENT]]008 {{.*}} R_X86_64_64 {{.*}} p0@@x1 + 0
60// PART1-NEXT: 000000000000[[DATA_SEGMENT]]010 {{.*}} R_X86_64_64 {{.*}} p0@@x1 + 0
61// CHECK-EMPTY:
62
63// PART0: Relocation section '.rela.plt'
64// PART0-NEXT: Offset
65// PART0-NEXT: 000000000000[[DATA_SEGMENT]]020 {{.*}} R_X86_64_JUMP_SLOT {{.*}} f1@v3 + 0
66// PART0-NEXT: 000000000000[[DATA_SEGMENT]]028 {{.*}} R_X86_64_JUMP_SLOT {{.*}} f2@v2 + 0
67// PART0-EMPTY:
68
69// CHECK: Symbol table '.dynsym'
70// PART0: 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND f1@v3
71// PART0: 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND f2@v2
72// PART0: 3: {{0*}}[[TEXT_ADDR]] 0 NOTYPE GLOBAL DEFAULT {{.*}} p0@@x1
73// PART1: 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND f2@v2
74// PART1: 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND p0@@x1
75// PART1: 3: {{0*}}[[TEXT_ADDR]] 0 NOTYPE GLOBAL DEFAULT {{.*}} p1@@x2
76// PART1: 4: {{0*}}[[TEXT_ADDR]] 0 NOTYPE GLOBAL DEFAULT {{.*}} p1alias@@x2
77// CHECK-EMPTY:
78
79// PART0: Symbol table '.symtab'
80// PART0: 000000000000048c 0 NOTYPE LOCAL HIDDEN {{.*}} __part_index_begin
81// PART0: 0000000000000498 0 NOTYPE LOCAL HIDDEN {{.*}} __part_index_end
82
83// PART-INDEX: Contents of section .dynstr:
84// PART-INDEX-NEXT: 03a8 00663100 66320070 30007061 72743100 .f1.f2.p0.part1.
85// PART-INDEX: Contents of section .rodata:
86// 0x48c + 0xffffff26 = 0x3b2
87// 0x490 + 0x3b70 = 0x4000
88// PART-INDEX-NEXT: 048c 26ffffff 703b0000 00400000
89
90// CHECK: {{.*}}EH_FRAME Header
91// CHECK: Address: 0x[[EH_FRAME_HDR_ADDR]]
92// CHECK: eh_frame_ptr: 0x[[EH_FRAME_ADDR]]
93// CHECK: initial_location: 0x[[TEXT_ADDR]]
94// CHECK: address: 0x[[FDE_ADDR:.*]]
95
96// CHECK: .eh_frame section
97// CHECK: 0x[[EH_FRAME_ADDR]]] CIE length=20
98// CHECK-NOT: FDE
99// CHECK: 0x[[FDE_ADDR]]] FDE length=20 cie={{.}}0x[[EH_FRAME_ADDR]]
100// CHECK-NEXT: initial_location: 0x[[TEXT_ADDR]]
101// CHECK-NOT: FDE
102// CHECK: CIE length=0
103
104// CHECK: Dynamic section
105// CHECK-NEXT: Tag
106// CHECK-NEXT: 0x0000000000000001 (NEEDED) Shared library: [verneed1.so.0]
107// PART0-NEXT: 0x000000000000000e (SONAME) Library soname: [main.so]
108// PART1-NEXT: 0x0000000000000001 (NEEDED) Shared library: [main.so]
109// PART1-NEXT: 0x000000000000000e (SONAME) Library soname: [part1]
110// CHECK-NEXT: 0x0000000000000007 (RELA) 0x[[RELA_DYN_ADDR]]
111// CHECK-NEXT: 0x0000000000000008 (RELASZ)
112// CHECK-NEXT: 0x0000000000000009 (RELAENT) 24 (bytes)
113// PART1-NEXT: 0x000000006ffffff9 (RELACOUNT) 1
114// PART0-NEXT: 0x0000000000000017 (JMPREL) 0x[[RELA_PLT_ADDR]]
115// PART0-NEXT: 0x0000000000000002 (PLTRELSZ) 48 (bytes)
116// PART0-NEXT: 0x0000000000000003 (PLTGOT) 0x[[GOT_PLT_ADDR]]
117// PART0-NEXT: 0x0000000000000014 (PLTREL) RELA
118// CHECK-NEXT: 0x0000000000000006 (SYMTAB) 0x[[DYNSYM_ADDR]]
119// CHECK-NEXT: 0x000000000000000b (SYMENT) 24 (bytes)
120// CHECK-NEXT: 0x0000000000000005 (STRTAB) 0x[[DYNSTR_ADDR]]
121// CHECK-NEXT: 0x000000000000000a (STRSZ)
122// CHECK-NEXT: 0x000000006ffffef5 (GNU_HASH) 0x[[GNU_HASH_ADDR]]
123// CHECK-NEXT: 0x0000000000000004 (HASH) 0x[[HASH_ADDR]]
124// PART0-NEXT: 0x0000000000000019 (INIT_ARRAY) 0x[[INIT_ARRAY_ADDR]]
125// PART0-NEXT: 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
126// CHECK-NEXT: 0x000000006ffffff0 (VERSYM) 0x[[VERSYM_ADDR]]
127// CHECK-NEXT: 0x000000006ffffffc (VERDEF) 0x[[VERDEF_ADDR]]
128// CHECK-NEXT: 0x000000006ffffffd (VERDEFNUM) 3
129// CHECK-NEXT: 0x000000006ffffffe (VERNEED) 0x[[VERNEED_ADDR]]
130// CHECK-NEXT: 0x000000006fffffff (VERNEEDNUM) 1
131// PART0-NEXT: 0x0000000000000000 (NULL) 0x0
132
133// CHECK: Program Headers:
134// CHECK-NEXT: Type
135// PART0-NEXT: PHDR {{.*}} 0x000230 0x000230 R
136// PART1-NEXT: PHDR {{.*}} 0x0001f8 0x0001f8 R
137// PART0-NEXT: LOAD 0x000000 0x0000000000000000 0x0000000000000000 {{.*}} R 0x1000
138// PART0-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 {{.*}} R E 0x1000
139// PART0-NEXT: LOAD 0x002000 0x0000000000002000 0x0000000000002000 {{.*}} RW 0x1000
140// PART0-NEXT: LOAD 0x003000 0x0000000000003000 0x0000000000003000 {{.*}} RW 0x1000
141// PART0-NEXT: LOAD 0x004000 0x0000000000008000 0x0000000000008000 0x000000 0x001000 RW 0x1000
142// PART1-NEXT: LOAD 0x000000 0x0000000000004000 0x0000000000004000 {{.*}} R 0x1000
143// PART1-NEXT: LOAD 0x001000 0x0000000000005000 0x0000000000005000 {{.*}} R E 0x1000
144// PART1-NEXT: LOAD 0x002000 0x0000000000006000 0x0000000000006000 {{.*}} RW 0x1000
145// PART1-NEXT: LOAD 0x003000 0x0000000000007000 0x0000000000007000 {{.*}} RW 0x1000
146// CHECK-NEXT: DYNAMIC {{.*}} 0x{{0*}}[[DYNAMIC_ADDR]] 0x{{0*}}[[DYNAMIC_ADDR]] {{.*}} RW 0x8
147// PART0-NEXT: GNU_RELRO 0x002000 0x0000000000002000 0x0000000000002000 {{.*}} R 0x1
148// PART1-NEXT: GNU_RELRO 0x002000 0x0000000000006000 0x0000000000006000 {{.*}} R 0x1
149// CHECK-NEXT: GNU_EH_FRAME {{.*}} 0x{{0*}}[[EH_FRAME_HDR_ADDR]] 0x{{0*}}[[EH_FRAME_HDR_ADDR]] {{.*}} R 0x4
150// CHECK-NEXT: GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x0
151// CHECK-EMPTY:
152
153// CHECK: Version symbols section '.gnu.version'
154// CHECK-NEXT: Addr:
155// PART0-NEXT: 000: 0 (*local*) 4 (v3) 5 (v2) 2 (x1)
156// PART1-NEXT: 000: 0 (*local*) 5 (v2) 2 (x1) 3 (x2)
157
158// CHECK: Version definition section '.gnu.version_d'
159// CHECK-NEXT: Addr:
160// PART0-NEXT: 0x0000: Rev: 1 Flags: BASE Index: 1 Cnt: 1 Name: main.so
161// PART1-NEXT: 0x0000: Rev: 1 Flags: BASE Index: 1 Cnt: 1 Name: part1
162// CHECK-NEXT: 0x001c: Rev: 1 Flags: none Index: 2 Cnt: 1 Name: x1
163// CHECK-NEXT: 0x0038: Rev: 1 Flags: none Index: 3 Cnt: 1 Name: x2
164
165// CHECK: Version needs section '.gnu.version_r'
166// CHECK-NEXT: Addr:
167// CHECK-NEXT: 0x0000: Version: 1 File: verneed1.so.0 Cnt: 2
168// CHECK-NEXT: 0x0010: Name: v2 Flags: none Version: 5
169// CHECK-NEXT: 0x0020: Name: v3 Flags: none Version: 4
170
171// PART0: Histogram for bucket list length (total of 4 buckets)
172// PART0-NEXT: Length Number % of total Coverage
173// PART0-NEXT: 0 1 ( 25.0%) 0.0%
174// PART0-NEXT: 1 3 ( 75.0%) 100.0%
175// PART0-NEXT: Histogram for `.gnu.hash' bucket list length (total of 1 buckets)
176// PART0-NEXT: Length Number % of total Coverage
177// PART0-NEXT: 0 0 ( 0.0%) 0.0%
178// PART0-NEXT: 1 1 (100.0%) 100.0%
179
180// PART1: Histogram for bucket list length (total of 5 buckets)
181// PART1-NEXT: Length Number % of total Coverage
182// PART1-NEXT: 0 3 ( 60.0%) 0.0%
183// PART1-NEXT: 1 2 ( 40.0%) 100.0%
184// PART1-NEXT: Histogram for `.gnu.hash' bucket list length (total of 1 buckets)
185// PART1-NEXT: Length Number % of total Coverage
186// PART1-NEXT: 0 0 ( 0.0%) 0.0%
187// PART1-NEXT: 1 0 ( 0.0%) 0.0%
188// PART1-NEXT: 2 1 (100.0%) 100.0%
189
190// FILL: 001040 cccc cccc cccc cccc cccc cccc cccc cccc
191// FILL-NEXT: *
192// FILL-NEXT: 002000
193
194// FILL: 005010 cccc cccc cccc cccc cccc cccc cccc cccc
195// FILL-NEXT: *
196// FILL-NEXT: 006000
197
198.section .llvm_sympart,"",@llvm_sympart
199.asciz "part1"
200.quad p1
201
202.section .llvm_sympart2,"",@llvm_sympart
203.asciz "part1"
204.quad p1alias
205
206.section .text.p0,"ax",@progbits
207.globl p0
208p0:
209.cfi_startproc
210lea d0(%rip), %rax
211call f1
212ret
213.cfi_endproc
214
215.section .data.d0,"aw",@progbits
216d0:
217.quad f1
218
219.section .text.p1,"ax",@progbits
220.globl p1
221p1:
222.globl p1alias
223p1alias:
224.cfi_startproc
225lea d1(%rip), %rax
226call f2
227ret
228.cfi_endproc
229
230.section .data.d1,"aw",@progbits
231d1:
232.quad f2
233.quad p0
234.quad p0
235.quad d0
236
237.section .init_array,"aw",@init_array
238.quad p0
239
240.globl __part_index_begin
241.globl __part_index_end
deps/lld/test/ELF/partition-thunk-reuse.s created+45
......@@ -0,0 +1,45 @@
1// REQUIRES: arm
2// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=armv7-unknown-linux -arm-add-build-attributes
3// RUN: ld.lld %t.o -o %t --export-dynamic --gc-sections
4// RUN: llvm-nm %t | FileCheck %s
5
6// CHECK: __Thumbv7ABSLongThunk__start
7// CHECK: __Thumbv7ABSLongThunk__start
8
9// CHECK: __Thumbv7ABSLongThunk_foo
10// CHECK-NOT: __Thumbv7ABSLongThunk_foo
11
12.thumb
13
14.section .llvm_sympart.g1,"",%llvm_sympart
15.asciz "part1"
16.4byte f1
17
18.section .llvm_sympart.g2,"",%llvm_sympart
19.asciz "part2"
20.4byte f2
21
22.section .text._start,"ax",%progbits
23.globl _start
24_start:
25bx lr
26foo:
27b f0
28.zero 17*1048576
29
30.section .text.f0,"ax",%progbits
31.globl f0
32f0:
33b foo
34
35.section .text.f1,"aw",%progbits
36.globl f1
37f1:
38b _start
39b foo
40
41.section .text.f2,"ax",%progbits
42.globl f2
43f2:
44b _start
45b foo
deps/lld/test/ELF/partitions.s created+63
......@@ -0,0 +1,63 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=x86_64-unknown-linux
3// RUN: ld.lld %t.o -o %t --export-dynamic --gc-sections
4// RUN: llvm-readelf -S -s %t | FileCheck %s
5
6// This is basically lld/docs/partitions.dot in object file form.
7// Test that the sections are correctly allocated to partitions.
8
9// CHECK: [[MAIN:[0-9]+]]] .text
10// CHECK: [[P1:[0-9]+]]] .text
11// CHECK: [[P2:[0-9]+]]] .text
12
13// CHECK: Symbol table '.symtab'
14// CHECK: [[MAIN]] f3
15// CHECK: [[P1]] f4
16// CHECK: [[MAIN]] f5
17// CHECK: [[P2]] f6
18// CHECK: [[MAIN]] _start
19// CHECK: [[P1]] f1
20// CHECK: [[P2]] f2
21
22.section .llvm_sympart.f1,"",@llvm_sympart
23.asciz "part1"
24.quad f1
25
26.section .llvm_sympart.f2,"",@llvm_sympart
27.asciz "part2"
28.quad f2
29
30.section .text._start,"ax",@progbits
31.globl _start
32_start:
33call f3
34
35.section .text.f1,"ax",@progbits
36.globl f1
37f1:
38call f3
39call f4
40call f5
41
42.section .text.f2,"ax",@progbits
43.globl f2
44f2:
45call f3
46call f5
47call f6
48
49.section .text.f3,"ax",@progbits
50f3:
51ret
52
53.section .text.f4,"ax",@progbits
54f4:
55ret
56
57.section .text.f5,"ax",@progbits
58f5:
59ret
60
61.section .text.f6,"ax",@progbits
62f6:
63ret
deps/lld/test/ELF/phdr-align.s+1-1
......@@ -7,7 +7,7 @@
77# RUN: .data : { *(.data) } \
88# RUN: .text : { *(.text) } }" > %t.script
99# RUN: ld.lld %t.o --script %t.script -o %t
10# RUN: llvm-readobj -sections -symbols %t | FileCheck %s
10# RUN: llvm-readobj --sections --symbols %t | FileCheck %s
1111
1212# CHECK: Sections [
1313# CHECK-NEXT: Section {
deps/lld/test/ELF/pie-weak.s+4-2
......@@ -1,6 +1,8 @@
11# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/dummy-shared.s -o %t1.o
3# RUN: ld.lld %t1.o -shared -o %t1.so
24# RUN: llvm-mc -filetype=obj -relax-relocations=false -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld --hash-style=sysv -pie %t.o -o %t
5# RUN: ld.lld --hash-style=sysv -pie %t.o %t1.so -o %t
46# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s
57# RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
68
......@@ -15,6 +17,6 @@
1517.globl _start
1618_start:
1719# DISASM: _start:
18# DISASM-NEXT: 1000: 48 8b 05 99 10 00 00 movq 4249(%rip), %rax
20# DISASM-NEXT: 1000: 48 8b 05 a9 10 00 00 movq 4265(%rip), %rax
1921# ^ .got - (.text + 7)
2022mov foo@gotpcrel(%rip), %rax
deps/lld/test/ELF/pie.s+5-5
......@@ -3,16 +3,16 @@
33
44## Default is no PIE.
55# RUN: ld.lld %t1.o -o %t
6# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t \
6# RUN: llvm-readobj --file-headers --sections -l --symbols -r %t \
77# RUN: | FileCheck %s --check-prefix=NOPIE
88
99## Check -pie.
1010# RUN: ld.lld -pie %t1.o -o %t
11# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
11# RUN: llvm-readobj --file-headers --sections -l --symbols -r %t | FileCheck %s
1212
1313## Test --pic-executable alias
1414# RUN: ld.lld --pic-executable %t1.o -o %t
15# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
15# RUN: llvm-readobj --file-headers --sections -l --symbols -r %t | FileCheck %s
1616
1717# CHECK: ElfHeader {
1818# CHECK-NEXT: Ident {
......@@ -49,9 +49,9 @@
4949
5050## Check -nopie
5151# RUN: ld.lld -no-pie %t1.o -o %t2
52# RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE
52# RUN: llvm-readobj --file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE
5353# RUN: ld.lld -no-pic-executable %t1.o -o %t2
54# RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE
54# RUN: llvm-readobj --file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE
5555# NOPIE-NOT: Type: SharedObject
5656
5757.globl _start
deps/lld/test/ELF/plt-aarch64.s+36-34
......@@ -4,10 +4,10 @@
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld -shared %t.o %t2.so -o %t.so
66// RUN: ld.lld %t.o %t2.so -o %t.exe
7// RUN: llvm-readobj -s -r %t.so | FileCheck --check-prefix=CHECKDSO %s
7// RUN: llvm-readobj -S -r %t.so | FileCheck --check-prefix=CHECKDSO %s
88// RUN: llvm-objdump -s -section=.got.plt %t.so | FileCheck --check-prefix=DUMPDSO %s
99// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASMDSO %s
10// RUN: llvm-readobj -s -r %t.exe | FileCheck --check-prefix=CHECKEXE %s
10// RUN: llvm-readobj -S -r %t.exe | FileCheck --check-prefix=CHECKEXE %s
1111// RUN: llvm-objdump -s -section=.got.plt %t.exe | FileCheck --check-prefix=DUMPEXE %s
1212// RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASMEXE %s
1313
......@@ -30,7 +30,7 @@
3030// CHECKDSO-NEXT: SHF_ALLOC
3131// CHECKDSO-NEXT: SHF_WRITE
3232// CHECKDSO-NEXT: ]
33// CHECKDSO-NEXT: Address: 0x20000
33// CHECKDSO-NEXT: Address: 0x30000
3434// CHECKDSO-NEXT: Offset:
3535// CHECKDSO-NEXT: Size: 48
3636// CHECKDSO-NEXT: Link:
......@@ -40,23 +40,23 @@
4040// CHECKDSO: Relocations [
4141// CHECKDSO-NEXT: Section ({{.*}}) .rela.plt {
4242
43// &(.got.plt[3]) = 0x20000 + 3 * 8 = 0x30018
44// CHECKDSO-NEXT: 0x20018 R_AARCH64_JUMP_SLOT foo
43// &(.got.plt[3]) = 0x30000 + 3 * 8 = 0x30018
44// CHECKDSO-NEXT: 0x30018 R_AARCH64_JUMP_SLOT foo
4545
46// &(.got.plt[4]) = 0x20000 + 4 * 8 = 0x30020
47// CHECKDSO-NEXT: 0x20020 R_AARCH64_JUMP_SLOT bar
46// &(.got.plt[4]) = 0x30000 + 4 * 8 = 0x30020
47// CHECKDSO-NEXT: 0x30020 R_AARCH64_JUMP_SLOT bar
4848
49// &(.got.plt[5]) = 0x20000 + 5 * 8 = 0x30028
50// CHECKDSO-NEXT: 0x20028 R_AARCH64_JUMP_SLOT weak
49// &(.got.plt[5]) = 0x30000 + 5 * 8 = 0x30028
50// CHECKDSO-NEXT: 0x30028 R_AARCH64_JUMP_SLOT weak
5151// CHECKDSO-NEXT: }
5252// CHECKDSO-NEXT: ]
5353
5454// DUMPDSO: Contents of section .got.plt:
5555// .got.plt[0..2] = 0 (reserved)
5656// .got.plt[3..5] = .plt = 0x10010
57// DUMPDSO-NEXT: 20000 00000000 00000000 00000000 00000000 ................
58// DUMPDSO-NEXT: 20010 00000000 00000000 10000100 00000000 ................
59// DUMPDSO-NEXT: 20020 10000100 00000000 10000100 00000000 ................
57// DUMPDSO-NEXT: 30000 00000000 00000000 00000000 00000000 ................
58// DUMPDSO-NEXT: 30010 00000000 00000000 10000100 00000000 ................
59// DUMPDSO-NEXT: 30020 10000100 00000000 10000100 00000000 ................
6060
6161// DISASMDSO: _start:
6262// 0x10030 - 0x10000 = 0x30 = 48
......@@ -70,11 +70,12 @@
7070// DISASMDSO-NEXT: 1000c: 1f 20 03 d5 nop
7171
7272// DISASMDSO: Disassembly of section .plt:
73// DISASMDSO-EMPTY:
7374// DISASMDSO-NEXT: .plt:
7475// DISASMDSO-NEXT: 10010: f0 7b bf a9 stp x16, x30, [sp, #-16]!
7576// &(.got.plt[2]) = 0x3000 + 2 * 8 = 0x3010
76// Page(0x20010) - Page(0x10014) = 0x20000 - 0x10000 = 0x10000 = 65536
77// DISASMDSO-NEXT: 10014: 90 00 00 90 adrp x16, #65536
77// Page(0x30010) - Page(0x10014) = 0x30000 - 0x10000 = 0x20000 = 131072
78// DISASMDSO-NEXT: 10014: 10 01 00 90 adrp x16, #131072
7879// 0x3010 & 0xFFF = 0x10 = 16
7980// DISASMDSO-NEXT: 10018: 11 0a 40 f9 ldr x17, [x16, #16]
8081// DISASMDSO-NEXT: 1001c: 10 42 00 91 add x16, x16, #16
......@@ -84,30 +85,30 @@
8485// DISASMDSO-NEXT: 1002c: 1f 20 03 d5 nop
8586
8687// foo@plt
87// Page(0x30018) - Page(0x10030) = 0x20000 - 0x10000 = 0x10000 = 65536
88// Page(0x30018) - Page(0x10030) = 0x30000 - 0x10000 = 0x20000 = 131072
8889// DISASMDSO-EMPTY:
8990// DISASMDSO-NEXT: foo@plt:
90// DISASMDSO-NEXT: 10030: 90 00 00 90 adrp x16, #65536
91// DISASMDSO-NEXT: 10030: 10 01 00 90 adrp x16, #131072
9192// 0x3018 & 0xFFF = 0x18 = 24
9293// DISASMDSO-NEXT: 10034: 11 0e 40 f9 ldr x17, [x16, #24]
9394// DISASMDSO-NEXT: 10038: 10 62 00 91 add x16, x16, #24
9495// DISASMDSO-NEXT: 1003c: 20 02 1f d6 br x17
9596
9697// bar@plt
97// Page(0x30020) - Page(0x10040) = 0x20000 - 0x10000 = 0x10000 = 65536
98// Page(0x30020) - Page(0x10040) = 0x30000 - 0x10000 = 0x20000 = 131072
9899// DISASMDSO-EMPTY:
99100// DISASMDSO-NEXT: bar@plt:
100// DISASMDSO-NEXT: 10040: 90 00 00 90 adrp x16, #65536
101// DISASMDSO-NEXT: 10040: 10 01 00 90 adrp x16, #131072
101102// 0x3020 & 0xFFF = 0x20 = 32
102103// DISASMDSO-NEXT: 10044: 11 12 40 f9 ldr x17, [x16, #32]
103104// DISASMDSO-NEXT: 10048: 10 82 00 91 add x16, x16, #32
104105// DISASMDSO-NEXT: 1004c: 20 02 1f d6 br x17
105106
106107// weak@plt
107// Page(0x30028) - Page(0x10050) = 0x20000 - 0x10000 = 0x10000 = 65536
108// Page(0x30028) - Page(0x10050) = 0x30000 - 0x10000 = 0x20000 = 131072
108109// DISASMDSO-EMPTY:
109110// DISASMDSO-NEXT: weak@plt:
110// DISASMDSO-NEXT: 10050: 90 00 00 90 adrp x16, #65536
111// DISASMDSO-NEXT: 10050: 10 01 00 90 adrp x16, #131072
111112// 0x3028 & 0xFFF = 0x28 = 40
112113// DISASMDSO-NEXT: 10054: 11 16 40 f9 ldr x17, [x16, #40]
113114// DISASMDSO-NEXT: 10058: 10 a2 00 91 add x16, x16, #40
......@@ -132,7 +133,7 @@
132133// CHECKEXE-NEXT: SHF_ALLOC
133134// CHECKEXE-NEXT: SHF_WRITE
134135// CHECKEXE-NEXT: ]
135// CHECKEXE-NEXT: Address: 0x220000
136// CHECKEXE-NEXT: Address: 0x230000
136137// CHECKEXE-NEXT: Offset:
137138// CHECKEXE-NEXT: Size: 40
138139// CHECKEXE-NEXT: Link:
......@@ -142,20 +143,20 @@
142143// CHECKEXE: Relocations [
143144// CHECKEXE-NEXT: Section ({{.*}}) .rela.plt {
144145
145// &(.got.plt[3]) = 0x220000 + 3 * 8 = 0x220018
146// CHECKEXE-NEXT: 0x220018 R_AARCH64_JUMP_SLOT bar 0x0
146// &(.got.plt[3]) = 0x230000 + 3 * 8 = 0x230018
147// CHECKEXE-NEXT: 0x230018 R_AARCH64_JUMP_SLOT bar 0x0
147148
148// &(.got.plt[4]) = 0x220000 + 4 * 8 = 0x220020
149// CHECKEXE-NEXT: 0x220020 R_AARCH64_JUMP_SLOT weak 0x0
149// &(.got.plt[4]) = 0x230000 + 4 * 8 = 0x230020
150// CHECKEXE-NEXT: 0x230020 R_AARCH64_JUMP_SLOT weak 0x0
150151// CHECKEXE-NEXT: }
151152// CHECKEXE-NEXT: ]
152153
153154// DUMPEXE: Contents of section .got.plt:
154155// .got.plt[0..2] = 0 (reserved)
155156// .got.plt[3..4] = .plt = 0x40010
156// DUMPEXE-NEXT: 220000 00000000 00000000 00000000 00000000
157// DUMPEXE-NEXT: 220010 00000000 00000000 10002100 00000000
158// DUMPEXE-NEXT: 220020 10002100 00000000
157// DUMPEXE-NEXT: 230000 00000000 00000000 00000000 00000000
158// DUMPEXE-NEXT: 230010 00000000 00000000 10002100 00000000
159// DUMPEXE-NEXT: 230020 10002100 00000000
159160
160161// DISASMEXE: _start:
161162// 0x21000c - 0x210000 = 0xc = 12
......@@ -169,11 +170,12 @@
169170// DISASMEXE-NEXT: 21000c: 1f 20 03 d5 nop
170171
171172// DISASMEXE: Disassembly of section .plt:
173// DISASMEXE-EMPTY:
172174// DISASMEXE-NEXT: .plt:
173175// DISASMEXE-NEXT: 210010: f0 7b bf a9 stp x16, x30, [sp, #-16]!
174176// &(.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
177// Page(0x230010) - Page(0x210014) = 0x230000 - 0x210000 = 0x20000 = 131072
178// DISASMEXE-NEXT: 210014: 10 01 00 90 adrp x16, #131072
177179// 0x120c0 & 0xFFF = 0xC0 = 192
178180// DISASMEXE-NEXT: 210018: 11 0a 40 f9 ldr x17, [x16, #16]
179181// DISASMEXE-NEXT: 21001c: 10 42 00 91 add x16, x16, #16
......@@ -183,19 +185,19 @@
183185// DISASMEXE-NEXT: 21002c: 1f 20 03 d5 nop
184186
185187// bar@plt
186// Page(0x40018) - Page(0x210030) = 0x220000 - 0x210000 = 0x10000 = 65536
188// Page(0x230018) - Page(0x210030) = 0x230000 - 0x210000 = 0x20000 = 131072
187189// DISASMEXE-EMPTY:
188190// DISASMEXE-NEXT: bar@plt:
189// DISASMEXE-NEXT: 210030: 90 00 00 90 adrp x16, #65536
191// DISASMEXE-NEXT: 210030: 10 01 00 90 adrp x16, #131072
190192// DISASMEXE-NEXT: 210034: 11 0e 40 f9 ldr x17, [x16, #24]
191193// DISASMEXE-NEXT: 210038: 10 62 00 91 add x16, x16, #24
192194// DISASMEXE-NEXT: 21003c: 20 02 1f d6 br x17
193195
194196// weak@plt
195// Page(0x40020) - Page(0x210040) = 0x220000 - 0x210000 = 0x10000 = 65536
197// Page(0x230020) - Page(0x210040) = 0x230000 - 0x210000 = 0x20000 = 131072
196198// DISASMEXE-EMPTY:
197199// DISASMEXE-NEXT: weak@plt:
198// DISASMEXE-NEXT: 210040: 90 00 00 90 adrp x16, #65536
200// DISASMEXE-NEXT: 210040: 10 01 00 90 adrp x16, #131072
199201// DISASMEXE-NEXT: 210044: 11 12 40 f9 ldr x17, [x16, #32]
200202// DISASMEXE-NEXT: 210048: 10 82 00 91 add x16, x16, #32
201203// DISASMEXE-NEXT: 21004c: 20 02 1f d6 br x17
deps/lld/test/ELF/plt-i686.s+36-28
......@@ -3,10 +3,10 @@
33// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld %t.o %t2.so -o %t
6// RUN: llvm-readobj -s -r %t | FileCheck %s
6// RUN: llvm-readobj -S -r %t | FileCheck %s
77// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
88// RUN: ld.lld -shared %t.o %t2.so -o %t
9// RUN: llvm-readobj -s -r %t | FileCheck --check-prefix=CHECKSHARED %s
9// RUN: llvm-readobj -S -r %t | FileCheck --check-prefix=CHECKSHARED %s
1010// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMSHARED %s
1111// RUN: ld.lld -pie %t.o %t2.so -o %t
1212// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMPIE %s
......@@ -30,8 +30,8 @@
3030// CHECK-NEXT: SHF_ALLOC
3131// CHECK-NEXT: SHF_WRITE
3232// CHECK-NEXT: ]
33// CHECK-NEXT: Address: 0x402000
34// CHECK-NEXT: Offset: 0x2000
33// CHECK-NEXT: Address: 0x403000
34// CHECK-NEXT: Offset: 0x3000
3535// CHECK-NEXT: Size: 20
3636// CHECK-NEXT: Link: 0
3737// CHECK-NEXT: Info: 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: 0x40200C R_386_JUMP_SLOT bar 0x0
46// CHECK-NEXT: 0x402010 R_386_JUMP_SLOT zed 0x0
45// CHECK-NEXT: 0x40300C R_386_JUMP_SLOT bar 0x0
46// CHECK-NEXT: 0x403010 R_386_JUMP_SLOT zed 0x0
4747// CHECK-NEXT: }
4848// CHECK-NEXT: ]
4949
......@@ -67,26 +67,27 @@
6767
6868// 0x401010 - 0x40102b - 5 = -32
6969// 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
70// 4206596 = 0x403004 = .got.plt (0x403000) + 4
71// 4206600 = 0x403008 = .got.plt (0x403000) + 8
72// 4206604 = 0x40300C = .got.plt (0x403000) + got.plt.reserved(12)
73// 4206608 = 0x403010 = .got.plt (0x403000) + got.plt.reserved(12) + 4
7474// DISASM: Disassembly of section .plt:
75// DISASM-EMPTY:
7576// DISASM-NEXT: .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
77// DISASM-NEXT: 401020: ff 35 04 30 40 00 pushl 4206596
78// DISASM-NEXT: 401026: ff 25 08 30 40 00 jmpl *4206600
7879// DISASM-NEXT: 40102c: 90 nop
7980// DISASM-NEXT: 40102d: 90 nop
8081// DISASM-NEXT: 40102e: 90 nop
8182// DISASM-NEXT: 40102f: 90 nop
8283// DISASM-EMPTY:
8384// DISASM-NEXT: bar@plt:
84// DISASM-NEXT: 401030: ff 25 0c 20 40 00 jmpl *4202508
85// DISASM-NEXT: 401030: ff 25 0c 30 40 00 jmpl *4206604
8586// DISASM-NEXT: 401036: 68 00 00 00 00 pushl $0
8687// DISASM-NEXT: 40103b: e9 e0 ff ff ff jmp -32 <.plt>
8788// DISASM-EMPTY:
8889// DISASM-NEXT: zed@plt:
89// DISASM-NEXT: 401040: ff 25 10 20 40 00 jmpl *4202512
90// DISASM-NEXT: 401040: ff 25 10 30 40 00 jmpl *4206608
9091// DISASM-NEXT: 401046: 68 08 00 00 00 pushl $8
9192// DISASM-NEXT: 40104b: e9 d0 ff ff ff jmp -48 <.plt>
9293
......@@ -110,8 +111,8 @@
110111// CHECKSHARED-NEXT: SHF_ALLOC
111112// CHECKSHARED-NEXT: SHF_WRITE
112113// CHECKSHARED-NEXT: ]
113// CHECKSHARED-NEXT: Address: 0x2000
114// CHECKSHARED-NEXT: Offset: 0x2000
114// CHECKSHARED-NEXT: Address: 0x3000
115// CHECKSHARED-NEXT: Offset: 0x3000
115116// CHECKSHARED-NEXT: Size: 20
116117// CHECKSHARED-NEXT: Link: 0
117118// CHECKSHARED-NEXT: Info: 0
......@@ -119,12 +120,12 @@
119120// CHECKSHARED-NEXT: EntrySize: 0
120121// CHECKSHARED-NEXT: }
121122
122// 0x2000 + got.plt.reserved(12) = 0x200C
123// 0x2000 + got.plt.reserved(12) + 4 = 0x2010
123// 0x3000 + got.plt.reserved(12) = 0x300C
124// 0x3000 + got.plt.reserved(12) + 4 = 0x3010
124125// CHECKSHARED: Relocations [
125126// CHECKSHARED-NEXT: Section ({{.*}}) .rel.plt {
126// CHECKSHARED-NEXT: 0x200C R_386_JUMP_SLOT bar 0x0
127// CHECKSHARED-NEXT: 0x2010 R_386_JUMP_SLOT zed 0x0
127// CHECKSHARED-NEXT: 0x300C R_386_JUMP_SLOT bar 0x0
128// CHECKSHARED-NEXT: 0x3010 R_386_JUMP_SLOT zed 0x0
128129// CHECKSHARED-NEXT: }
129130// CHECKSHARED-NEXT: ]
130131
......@@ -137,33 +138,40 @@
137138// DISASMSHARED-NEXT: 1009: e9 22 00 00 00 jmp 34
138139// DISASMSHARED-NEXT: 100e: e9 2d 00 00 00 jmp 45
139140// DISASMSHARED-NEXT: 1013: e9 e8 ff ff ff jmp -24
141// DISASMSHARED-EMPTY:
140142// DISASMSHARED-NEXT: Disassembly of section .plt:
143// DISASMSHARED-EMPTY:
141144// DISASMSHARED-NEXT: .plt:
142// DISASMSHARED-NEXT: 1020: ff b3 04 20 00 00 pushl 8196(%ebx)
143// DISASMSHARED-NEXT: 1026: ff a3 08 20 00 00 jmpl *8200(%ebx)
145// DISASMSHARED-NEXT: 1020: ff b3 04 00 00 00 pushl 4(%ebx)
146// DISASMSHARED-NEXT: 1026: ff a3 08 00 00 00 jmpl *8(%ebx)
144147// DISASMSHARED-NEXT: 102c: 90 nop
145148// DISASMSHARED-NEXT: 102d: 90 nop
146149// DISASMSHARED-NEXT: 102e: 90 nop
147150// DISASMSHARED-NEXT: 102f: 90 nop
148// DISASMSHARED-NEXT: 1030: ff a3 0c 20 00 00 jmpl *8204(%ebx)
151// DISASMSHARED: bar@plt:
152// DISASMSHARED-NEXT: 1030: ff a3 0c 00 00 00 jmpl *12(%ebx)
149153// DISASMSHARED-NEXT: 1036: 68 00 00 00 00 pushl $0
150154// DISASMSHARED-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
151// DISASMSHARED-NEXT: 1040: ff a3 10 20 00 00 jmpl *8208(%ebx)
155// DISASMSHARED: zed@plt:
156// DISASMSHARED-NEXT: 1040: ff a3 10 00 00 00 jmpl *16(%ebx)
152157// DISASMSHARED-NEXT: 1046: 68 08 00 00 00 pushl $8
153158// DISASMSHARED-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
154159
155160// DISASMPIE: Disassembly of section .plt:
161// DISASMPIE-EMPTY:
156162// DISASMPIE-NEXT: .plt:
157// DISASMPIE-NEXT: 1020: ff b3 04 20 00 00 pushl 8196(%ebx)
158// DISASMPIE-NEXT: 1026: ff a3 08 20 00 00 jmpl *8200(%ebx)
163// DISASMPIE-NEXT: 1020: ff b3 04 00 00 00 pushl 4(%ebx)
164// DISASMPIE-NEXT: 1026: ff a3 08 00 00 00 jmpl *8(%ebx)
159165// DISASMPIE-NEXT: 102c: 90 nop
160166// DISASMPIE-NEXT: 102d: 90 nop
161167// DISASMPIE-NEXT: 102e: 90 nop
162168// DISASMPIE-NEXT: 102f: 90 nop
163// DISASMPIE-NEXT: 1030: ff a3 0c 20 00 00 jmpl *8204(%ebx)
169// DISASMPIE: bar@plt:
170// DISASMPIE-NEXT: 1030: ff a3 0c 00 00 00 jmpl *12(%ebx)
164171// DISASMPIE-NEXT: 1036: 68 00 00 00 00 pushl $0
165172// DISASMPIE-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
166// DISASMPIE-NEXT: 1040: ff a3 10 20 00 00 jmpl *8208(%ebx)
173// DISASMPIE: zed@plt:
174// DISASMPIE-NEXT: 1040: ff a3 10 00 00 00 jmpl *16(%ebx)
167175// DISASMPIE-NEXT: 1046: 68 08 00 00 00 pushl $8
168176// DISASMPIE-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
169177
deps/lld/test/ELF/plt.s+21-19
......@@ -4,9 +4,9 @@
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld -shared %t.o %t2.so -o %t
66// RUN: ld.lld %t.o %t2.so -o %t3
7// RUN: llvm-readobj -s -r %t | FileCheck %s
7// RUN: llvm-readobj -S -r %t | FileCheck %s
88// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
9// RUN: llvm-readobj -s -r %t3 | FileCheck --check-prefix=CHECK2 %s
9// RUN: llvm-readobj -S -r %t3 | FileCheck --check-prefix=CHECK2 %s
1010// RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM2 %s
1111
1212// CHECK: Name: .plt
......@@ -24,9 +24,9 @@
2424
2525// CHECK: Relocations [
2626// CHECK-NEXT: Section ({{.*}}) .rela.plt {
27// CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT bar 0x0
28// CHECK-NEXT: 0x2020 R_X86_64_JUMP_SLOT zed 0x0
29// CHECK-NEXT: 0x2028 R_X86_64_JUMP_SLOT _start 0x0
27// CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT bar 0x0
28// CHECK-NEXT: 0x3020 R_X86_64_JUMP_SLOT zed 0x0
29// CHECK-NEXT: 0x3028 R_X86_64_JUMP_SLOT _start 0x0
3030// CHECK-NEXT: }
3131// CHECK-NEXT: ]
3232
......@@ -45,8 +45,8 @@
4545
4646// CHECK2: Relocations [
4747// CHECK2-NEXT: Section ({{.*}}) .rela.plt {
48// CHECK2-NEXT: 0x202018 R_X86_64_JUMP_SLOT bar 0x0
49// CHECK2-NEXT: 0x202020 R_X86_64_JUMP_SLOT zed 0x0
48// CHECK2-NEXT: 0x203018 R_X86_64_JUMP_SLOT bar 0x0
49// CHECK2-NEXT: 0x203020 R_X86_64_JUMP_SLOT zed 0x0
5050// CHECK2-NEXT: }
5151// CHECK2-NEXT: ]
5252
......@@ -64,28 +64,29 @@
6464// DISASM-NEXT: 100a: e9 {{.*}} jmp 49
6565// DISASM-NEXT: 100f: e9 {{.*}} jmp 60
6666
67// 0x2018 - 0x1036 = 4066
68// 0x2020 - 0x1046 = 4058
69// 0x2028 - 0x1056 = 4050
67// 0x3018 - 0x1036 = 8162
68// 0x3020 - 0x1046 = 8154
69// 0x3028 - 0x1056 = 8146
7070
7171// DISASM: Disassembly of section .plt:
72// DISASM-EMPTY:
7273// DISASM-NEXT: .plt:
73// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)
74// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
74// DISASM-NEXT: 1020: ff 35 e2 1f 00 00 pushq 8162(%rip)
75// DISASM-NEXT: 1026: ff 25 e4 1f 00 00 jmpq *8164(%rip)
7576// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
7677// DISASM-EMPTY:
7778// DISASM-NEXT: bar@plt:
78// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
79// DISASM-NEXT: 1030: ff 25 e2 1f 00 00 jmpq *8162(%rip)
7980// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
8081// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
8182// DISASM-EMPTY:
8283// DISASM-NEXT: zed@plt:
83// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)
84// DISASM-NEXT: 1040: ff 25 da 1f 00 00 jmpq *8154(%rip)
8485// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
8586// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
8687// DISASM-EMPTY:
8788// DISASM-NEXT: _start@plt:
88// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
89// DISASM-NEXT: 1050: ff 25 d2 1f 00 00 jmpq *8146(%rip)
8990// DISASM-NEXT: 1056: 68 02 00 00 00 pushq $2
9091// DISASM-NEXT: 105b: e9 c0 ff ff ff jmp -64 <.plt>
9192
......@@ -104,18 +105,19 @@
104105// 0x202020 - 0x201046 = 4058
105106
106107// DISASM2: Disassembly of section .plt:
108// DISASM2-EMPTY:
107109// DISASM2-NEXT: .plt:
108// DISASM2-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)
109// DISASM2-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
110// DISASM2-NEXT: 201020: ff 35 e2 1f 00 00 pushq 8162(%rip)
111// DISASM2-NEXT: 201026: ff 25 e4 1f 00 00 jmpq *8164(%rip)
110112// DISASM2-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
111113// DISASM2-EMPTY:
112114// DISASM2-NEXT: bar@plt:
113// DISASM2-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
115// DISASM2-NEXT: 201030: ff 25 e2 1f 00 00 jmpq *8162(%rip)
114116// DISASM2-NEXT: 201036: 68 00 00 00 00 pushq $0
115117// DISASM2-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
116118// DISASM2-EMPTY:
117119// DISASM2-NEXT: zed@plt:
118// DISASM2-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)
120// DISASM2-NEXT: 201040: ff 25 da 1f 00 00 jmpq *8154(%rip)
119121// DISASM2-NEXT: 201046: 68 01 00 00 00 pushq $1
120122// DISASM2-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>
121123// DISASM2-NOT: 2010C0
deps/lld/test/ELF/ppc-rela.s+1-1
......@@ -7,5 +7,5 @@
77 .long foo
88
99// CHECK: Section ({{.*}}) .rela.dyn {
10// CHECK-NEXT: 0x1000 R_PPC_ADDR32 foo 0x0
10// CHECK-NEXT: 0x20000 R_PPC_ADDR32 foo 0x0
1111// CHECK-NEXT: }
deps/lld/test/ELF/ppc-relocs.s deleted-101
......@@ -1,101 +0,0 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t
3# RUN: ld.lld %t -o %t2
4# RUN: llvm-objdump -d %t2 | FileCheck %s
5
6.section .R_PPC_ADDR16_HA,"ax",@progbits
7.globl _start
8_start:
9 lis 4, msg@ha
10msg:
11 .string "foo"
12 len = . - msg
13
14# CHECK: Disassembly of section .R_PPC_ADDR16_HA:
15# CHECK: _start:
16# CHECK: 11000: 3c 80 00 01 lis 4, 1
17# CHECK: msg:
18# CHECK: 11004: 66 6f 6f 00 oris 15, 19, 28416
19
20.section .R_PPC_ADDR16_HI,"ax",@progbits
21.globl _starti
22_starti:
23 lis 4,msgi@h
24msgi:
25 .string "foo"
26 leni = . - msgi
27
28# CHECK: Disassembly of section .R_PPC_ADDR16_HI:
29# CHECK: _starti:
30# CHECK: 11008: 3c 80 00 01 lis 4, 1
31# CHECK: msgi:
32# CHECK: 1100c: 66 6f 6f 00 oris 15, 19, 28416
33
34.section .R_PPC_ADDR16_LO,"ax",@progbits
35 addi 4, 4, msg@l
36mystr:
37 .asciz "blah"
38 len = . - mystr
39
40# CHECK: Disassembly of section .R_PPC_ADDR16_LO:
41# CHECK: .R_PPC_ADDR16_LO:
42# CHECK: 11010: 38 84 10 04 addi 4, 4, 4100
43# CHECK: mystr:
44# CHECK: 11014: 62 6c 61 68 ori 12, 19, 24936
45
46.align 2
47.section .R_PPC_REL24,"ax",@progbits
48.globl .FR_PPC_REL24
49.FR_PPC_REL24:
50 b .Lfoox
51.section .R_PPC_REL24_2,"ax",@progbits
52.Lfoox:
53
54# CHECK: Disassembly of section .R_PPC_REL24:
55# CHECK: .FR_PPC_REL24:
56# CHECK: 1101c: 48 00 00 04 b .+4
57
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
69.section .R_PPC_REL32,"ax",@progbits
70.globl .FR_PPC_REL32
71.FR_PPC_REL32:
72 .long .Lfoox3 - .
73.section .R_PPC_REL32_2,"ax",@progbits
74.Lfoox3:
75
76# CHECK: Disassembly of section .R_PPC_REL32:
77# CHECK: .FR_PPC_REL32:
78# CHECK: 11024: 00 00 00 04
79
80.section .R_PPC_ADDR32,"ax",@progbits
81.globl .FR_PPC_ADDR32
82.FR_PPC_ADDR32:
83 .long .Lfoox2
84.section .R_PPC_ADDR32_2,"ax",@progbits
85.Lfoox2:
86
87# CHECK: Disassembly of section .R_PPC_ADDR32:
88# CHECK: .FR_PPC_ADDR32:
89# CHECK: 11028: 00 01 10 2c
90
91.align 2
92.section .R_PPC_PLTREL24,"ax",@progbits
93.globl .R_PPC_PLTREL24
94.FR_PPC_PLTREL24:
95 b .Lfoox4@PLT
96.section .R_PPC_PLTREL24_2,"ax",@progbits
97.Lfoox4:
98
99# CHECK: Disassembly of section .R_PPC_PLTREL24:
100# CHECK: .R_PPC_PLTREL24:
101# CHECK: 1102c: 48 00 00 04 b .+4
deps/lld/test/ELF/ppc32-abs-pic.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: ld.lld -shared %t.o -o %t.so
4# RUN: llvm-nm %t.so | FileCheck --check-prefix=NM %s
5# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOC %s
6
7## R_PPC_ADDR32 is an absolute relocation type.
8## In PIC mode, it creates a relative relocation if the symbol is non-preemptable.
9
10# NM: 00020004 d b
11
12# RELOC: .rela.dyn {
13# RELOC-NEXT: 0x20004 R_PPC_RELATIVE - 0x20004
14# RELOC-NEXT: 0x20000 R_PPC_ADDR32 a 0
15# RELOC-NEXT: }
16
17.globl a, b
18.hidden b
19
20.data
21.long a
22b:
23.long b
deps/lld/test/ELF/ppc32-call-stub-nopic.s created+81
......@@ -0,0 +1,81 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: echo '.globl f, g, h; f: g: h:' | llvm-mc -filetype=obj -triple=powerpc - -o %t1.o
4# RUN: ld.lld -shared %t1.o -soname t1.so -o %t1.so
5
6## Check we can create PLT entries for -fno-PIE executable.
7# RUN: ld.lld %t.o %t1.so -o %t
8# RUN: llvm-readobj -r -d %t | FileCheck --check-prefix=RELOC %s
9# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC %s
10# RUN: llvm-readelf -x .plt %t | FileCheck --check-prefix=HEX %s
11# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
12
13# RELOC: .rela.plt {
14# RELOC-NEXT: 0x10030000 R_PPC_JMP_SLOT f 0x0
15# RELOC-NEXT: 0x10030004 R_PPC_JMP_SLOT g 0x0
16# RELOC-NEXT: }
17
18# SEC: .got PROGBITS 10020070
19# RELOC: PPC_GOT 0x10020070
20
21## .got2+0x8000-0x10004 = 0x30000+0x8000-0x10004 = 65536*2+32764
22# CHECK-LABEL: _start:
23# CHECK-NEXT: bl .+16
24# CHECK-NEXT: bl .+12
25# CHECK-NEXT: bl .+24
26# CHECK-NEXT: bl .+20
27# CHECK-EMPTY:
28
29## -fno-PIC call stubs of f and g.
30## .plt[0] = 0x10030000 = 65536*4099+0
31## .plt[1] = 0x10030004 = 65536*4099+4
32# CHECK-NEXT: 00000000.plt_call32.f:
33# CHECK-NEXT: lis 11, 4099
34# CHECK-NEXT: lwz 11, 0(11)
35# CHECK-NEXT: mtctr 11
36# CHECK-NEXT: bctr
37# CHECK-EMPTY:
38# CHECK-NEXT: 00000000.plt_call32.g:
39# CHECK-NEXT: lis 11, 4099
40# CHECK-NEXT: lwz 11, 4(11)
41# CHECK-NEXT: mtctr 11
42# CHECK-NEXT: bctr
43# CHECK-EMPTY:
44
45## In Secure PLT ABI, .plt stores function pointers to first instructions of .glink
46# HEX: 0x10030000 10010040 10010044
47
48## These instructions are referenced by .plt entries.
49# CHECK: 10010040 .glink:
50# CHECK-NEXT: b .+8
51# CHECK-NEXT: b .+4
52
53## PLTresolve
54## Operands of lis & lwz: .got+4 = 0x10020070+4 = 65536*4098+116
55## Operands of addis & addi: -.glink = -0x10010040 = 65536*-4097-48
56# CHECK-NEXT: lis 12, 4098
57# CHECK-NEXT: addis 11, 11, -4097
58# CHECK-NEXT: lwz 0, 116(12)
59# CHECK-NEXT: addi 11, 11, -64
60
61# CHECK-NEXT: mtctr 0
62# CHECK-NEXT: add 0, 11, 11
63# CHECK-NEXT: lwz 12, 120(12)
64# CHECK-NEXT: add 11, 0, 11
65# CHECK-NEXT: bctr
66
67## glibc crti.o references _GLOBAL_OFFSET_TABLE_.
68.section .init
69 bcl 20, 31, .+4
70.L:
71 mflr 30
72 addis 30, 30, _GLOBAL_OFFSET_TABLE_-.L@ha
73 addi 30, 30, _GLOBAL_OFFSET_TABLE_-.L@l
74
75.text
76.globl _start
77_start:
78 bl f
79 bl f
80 bl g
81 bl g
deps/lld/test/ELF/ppc32-call-stub-pic.s created+151
......@@ -0,0 +1,151 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: echo '.globl f, g, h; f: g: h:' | llvm-mc -filetype=obj -triple=powerpc - -o %t1.o
4# RUN: ld.lld -shared %t1.o -soname t1.so -o %t1.so
5# RUN: echo 'bl f+0x8000@plt' | llvm-mc -filetype=obj -triple=powerpc - -o %t2.o
6
7## Check we can create PLT entries for -fPIE or -fpie executable.
8# RUN: ld.lld -pie %t.o %t1.so %t2.o -o %t
9# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
10# RUN: llvm-readobj -d %t | FileCheck --check-prefix=DYN %s
11# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC %s
12# RUN: llvm-readelf -x .plt %t | FileCheck --check-prefix=HEX %s
13# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,PIE %s
14
15## Check we can create PLT entries for -fPIC or -fpic DSO.
16# RUN: ld.lld -shared %t.o %t1.so %t2.o -o %t
17# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
18# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,SHARED %s
19
20# RELOC: .rela.dyn {
21# RELOC-NEXT: R_PPC_ADDR32 f 0x0
22# RELOC-NEXT: R_PPC_ADDR32 g 0x0
23# RELOC-NEXT: R_PPC_ADDR32 h 0x0
24# RELOC-NEXT: }
25# RELOC-NEXT: .rela.plt {
26# RELOC-NEXT: R_PPC_JMP_SLOT f 0x0
27# RELOC-NEXT: R_PPC_JMP_SLOT g 0x0
28# RELOC-NEXT: R_PPC_JMP_SLOT h 0x0
29# RELOC-NEXT: }
30
31# SEC: .got PROGBITS 00020088
32# DYN: PPC_GOT 0x20088
33
34## .got2+0x8000-0x10004 = 0x30000+0x8000-0x10004 = 65536*2+32764
35# CHECK-LABEL: _start:
36# CHECK-NEXT: bcl 20, 31, .+4
37# CHECK-NEXT: 10004: mflr 30
38# CHECK-NEXT: addis 30, 30, 2
39# CHECK-NEXT: addi 30, 30, 32764
40
41## Two bl 00008000.got2.plt_pic32.f
42# CHECK-NEXT: bl .+40
43# CHECK-NEXT: bl .+36
44## Two bl 00008000.got2.plt_pic32.g
45# CHECK-NEXT: bl .+48
46# CHECK-NEXT: bl .+44
47## Two bl 00008000.got2.plt_pic32.h
48# CHECK-NEXT: bl .+56
49# CHECK-NEXT: bl .+52
50# CHECK-NEXT: addis 30, 30, {{.*}}
51# CHECK-NEXT: addi 30, 30, {{.*}}
52## bl 00008000.plt_pic32.f
53# CHECK-NEXT: bl .+56
54## bl 00008000.plt_pic32.f
55# CHECK-NEXT: bl .+68
56# CHECK-EMPTY:
57
58## -fPIC call stubs of f and g.
59# CHECK-NEXT: 00008000.got2.plt_pic32.f:
60# CHECK-NEXT: lwz 11, 32760(30)
61# CHECK-NEXT: mtctr 11
62# CHECK-NEXT: bctr
63# CHECK-NEXT: nop
64# CHECK-EMPTY:
65# CHECK-NEXT: 00008000.got2.plt_pic32.g:
66# CHECK-NEXT: lwz 11, 32764(30)
67# CHECK-NEXT: mtctr 11
68# CHECK-NEXT: bctr
69# CHECK-NEXT: nop
70# CHECK-EMPTY:
71
72## The -fPIC call stub of h needs two instructions addis+lwz to represent the offset 65536*1-32768.
73# CHECK-NEXT: 00008000.got2.plt_pic32.h:
74# CHECK-NEXT: addis 11, 30, 1
75# CHECK-NEXT: lwz 11, -32768(11)
76# CHECK-NEXT: mtctr 11
77# CHECK-NEXT: bctr
78# CHECK-EMPTY:
79
80## -fpic call stub of f.
81# CHECK-NEXT: 00000000.plt_pic32.f:
82# CHECK-NEXT: addis 11, 30, 2
83# PIE-NEXT: lwz 11, -144(11)
84# SHARED-NEXT: lwz 11, -136(11)
85# CHECK-NEXT: mtctr 11
86# CHECK-NEXT: bctr
87# CHECK-EMPTY:
88
89## Another -fPIC call stub of f from another object file %t2.o
90## .got2 may have different addresses in different object files,
91## so the call stub cannot be shared.
92# CHECK-NEXT: 00008000.got2.plt_pic32.f:
93
94## In Secure PLT ABI, .plt stores function pointers to first instructions of .glink
95# HEX: 0x0003fff8 00010090 00010094 00010098
96
97## These instructions are referenced by .plt entries.
98# CHECK: 00010090 .glink:
99# CHECK-NEXT: b .+12
100# CHECK-NEXT: b .+8
101# CHECK-NEXT: b .+4
102
103## PLTresolve
104## Operand of addi: 0x100a8-.glink = 24
105# CHECK-NEXT: addis 11, 11, 0
106# CHECK-NEXT: mflr 0
107# CHECK-NEXT: bcl 20, 31, .+4
108# CHECK-NEXT: 100a8: addi 11, 11, 24
109
110# CHECK-NEXT: mflr 12
111# CHECK-NEXT: mtlr 0
112# CHECK-NEXT: subf 11, 12, 11
113
114## Operand of lwz in -pie mode: &.got[1] - 0x100a8 = 0x20088+4 - 0x100a8 = 65536*1-28
115# CHECK-NEXT: addis 12, 12, 1
116# PIE-NEXT: lwz 0, -28(12)
117# SHARED-NEXT: lwz 0, -36(12)
118
119# PIE-NEXT: lwz 12, -24(12)
120# SHARED-NEXT: lwz 12, -32(12)
121# CHECK-NEXT: mtctr 0
122# CHECK-NEXT: add 0, 11, 11
123# CHECK-NEXT: add 11, 0, 11
124# CHECK-NEXT: bctr
125
126.section .got2,"aw"
127.space 65516
128.long f
129.long g
130.long h
131
132.text
133.globl _start
134_start:
135 bcl 20,31,.L
136.L:
137 mflr 30
138 addis 30, 30, .got2+0x8000-.L@ha
139 addi 30, 30, .got2+0x8000-.L@l
140 bl f+0x8000@plt
141 bl f+0x8000@plt
142 bl g+0x8000@plt
143 bl g+0x8000@plt
144 bl h+0x8000@plt
145 bl h+0x8000@plt
146
147## An addend of 0 indicates r30 is stored in _GLOBAL_OFFSET_TABLE_.
148## The existing thunk is incompatible, thus it cannot be reused.
149 addis 30, 30, _GLOBAL_OFFSET_TABLE_-.L@ha
150 addi 30, 30, _GLOBAL_OFFSET_TABLE_-.L@l
151 bl f@plt
deps/lld/test/ELF/ppc32-gnu-ifunc-nonpreemptable.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
5# RUN: llvm-readelf -s %t | FileCheck --check-prefix=SYM %s
6# RUN: llvm-readelf -x .got2 %t | FileCheck --check-prefix=HEX %s
7# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
8
9# RELOC: .rela.plt {
10# RELOC-NEXT: 0x10020004 R_PPC_IRELATIVE - 0x10010000
11# RELOC-NEXT: }
12
13# SYM: 10010020 0 FUNC GLOBAL DEFAULT {{.*}} func
14# HEX: 0x10020000 10010020
15
16.section .got2,"aw"
17.long func
18
19# CHECK: func_resolver:
20# CHECK-NEXT: 10010000: blr
21# CHECK: _start:
22# CHECK-NEXT: bl .+12
23# CHECK-NEXT: lis 9, 4097
24# CHECK-NEXT: addi 9, 9, 32
25# CHECK-EMPTY:
26# CHECK-NEXT: 00000000.plt_call32.func:
27## 10020004 = 65536*4098+4
28# CHECK-NEXT: lis 11, 4098
29# CHECK-NEXT: lwz 11, 4(11)
30
31.text
32.globl func
33.type func, @gnu_indirect_function
34func:
35.globl func_resolver
36.type func_resolver, @function
37func_resolver:
38 blr
39
40.globl _start
41_start:
42 bl func
43
44 lis 9, func@ha
45 la 9, func@l(9)
deps/lld/test/ELF/ppc32-gnu-ifunc.s created+41
......@@ -0,0 +1,41 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
5# RUN: llvm-readelf -S -s %t | FileCheck --check-prefixes=SEC,SYM %s
6# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
7
8# RELOC: .rela.plt {
9# RELOC-NEXT: 0x10020000 R_PPC_IRELATIVE - 0x10010000
10# RELOC-NEXT: }
11
12# SEC: .rela.plt RELA 100000d4 0000d4 00000c
13# SYM: 10010000 0 FUNC GLOBAL DEFAULT {{.*}} func
14
15# CHECK: func_resolver:
16# CHECK-NEXT: 10010000:
17# CHECK: _start:
18# CHECK-NEXT: bl .+20
19## .rela.plt = 0x100000d4 = 65536*4096+212
20## end(.rela.plt) = 0x100000d4+0xc = 65536*4096+224
21# CHECK-NEXT: lis 9, 4096
22# CHECK-NEXT: lis 8, 4096
23# CHECK-NEXT: addi 9, 9, 212
24# CHECK-NEXT: addi 8, 8, 224
25
26.globl func
27.type func, @gnu_indirect_function
28func:
29.globl func_resolver
30.type func_resolver, @function
31func_resolver:
32 blr
33
34.globl _start
35_start:
36 bl func
37
38 lis 9, __rela_iplt_start@ha
39 lis 8, __rela_iplt_end@ha
40 la 9, __rela_iplt_start@l(9)
41 la 8, __rela_iplt_end@l(8)
deps/lld/test/ELF/ppc32-local-branch.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: echo '.globl foo; foo: blr' | llvm-mc -filetype=obj -triple=powerpc - -o %t1.o
4# RUN: ld.lld %t.o %t1.o -o %t
5# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
6
7## R_PPC_REL24 and R_PPC_PLTREL24 are converted to PC relative relocations if the
8## symbol is non-preemptable. The addend of R_PPC_PLTREL24 should be ignored.
9
10# CHECK: _start:
11# CHECK-NEXT: b .+12
12# CHECK-NEXT: b .+8
13# CHECK-NEXT: b .+4
14# CHECK-EMPTY:
15# CHECK-NEXT: foo:
16
17.globl _start
18_start:
19 b foo # R_PPC_REL24
20 b foo@plt # R_PPC_PLTREL24
21 b foo+32768@plt #_PPC_PLTREL24 with addend
deps/lld/test/ELF/ppc32-reloc-addr.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: ld.lld %t.o --defsym=a=0x1234 --defsym=b=0xbcdef -o %t
4# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
5# RUN: llvm-objdump -s --no-show-raw-insn %t | FileCheck --check-prefix=HEX %s
6
7.section .R_PPC_ADDR16_HA,"ax",@progbits
8 lis 4, a@ha
9# CHECK-LABEL: section .R_PPC_ADDR16_HA:
10# CHECK: lis 4, 0
11
12.section .R_PPC_ADDR16_HI,"ax",@progbits
13 lis 4, a@h
14# CHECK-LABEL: section .R_PPC_ADDR16_HI:
15# CHECK: lis 4, 0
16
17.section .R_PPC_ADDR16_LO,"ax",@progbits
18 addi 4, 4, a@l
19# CHECK-LABEL: section .R_PPC_ADDR16_LO:
20# CHECK: addi 4, 4, 4660
21
22.section .R_PPC_ADDR32,"a",@progbits
23 .long a
24 .long b
25# HEX-LABEL: section .R_PPC_ADDR32:
26# HEX-NEXT: 100000b4 00001234 000bcdef
deps/lld/test/ELF/ppc32-reloc-got.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: echo '.globl b; b:' | llvm-mc -filetype=obj -triple=powerpc - -o %t1.o
4# RUN: ld.lld -shared %t1.o -o %t1.so
5
6# RUN: ld.lld %t.o %t1.so -o %t
7# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
8# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
9# RUN: llvm-readobj -x .got %t | FileCheck --check-prefix=HEX %s
10# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
11
12## Check we can handle R_PPC_GOT16, which may be generated by -fpic code.
13
14# SEC: .got PROGBITS 00020068 020068 000014
15
16# RELOC: .rela.dyn {
17# RELOC-NEXT: 0x10020078 R_PPC_GLOB_DAT b 0x0
18# RELOC-NEXT: }
19
20# NM: 10030000 d a
21
22## The GOT slot of a can be filled at link time.
23# HEX: section '.got':
24# HEX: 0x10020068 {{[0-9a-f]+}} 00000000 00000000 10030000
25
26## a: &.got[3] - _GLOBAL_OFFSET_TABLE_ = 12
27## b: &.got[4] - _GLOBAL_OFFSET_TABLE_ = 16
28# CHECK: lwz 3, 12(30)
29# CHECK: lwz 4, 16(30)
30
31lwz 3,a@got(30)
32lwz 4,b@got(30)
33
34.data
35a:
36.long _GLOBAL_OFFSET_TABLE_
deps/lld/test/ELF/ppc32-reloc-rel.s created+34
......@@ -0,0 +1,34 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
5
6.section .R_PPC_REL14,"ax",@progbits
7 beq 1f
81:
9# CHECK-LABEL: section .R_PPC_REL14:
10# CHECK: bt 2, .+4
11
12.section .R_PPC_REL24,"ax",@progbits
13 b 1f
141:
15# CHECK-LABEL: section .R_PPC_REL24:
16# CHECK: b .+4
17
18.section .R_PPC_REL32,"ax",@progbits
19 .long 1f - .
201:
21# HEX-LABEL: section .R_PPC_REL32:
22# HEX-NEXT: 10010008 00000004
23
24.section .R_PPC_PLTREL24,"ax",@progbits
25 b 1f@PLT+32768
261:
27# CHECK-LABEL: section .R_PPC_PLTREL24:
28# CHECK: b .+4
29
30.section .R_PPC_LOCAL24PC,"ax",@progbits
31 b 1f@local
321:
33# CHECK-LABEL: section .R_PPC_LOCAL24PC:
34# CHECK: b .+4
deps/lld/test/ELF/ppc32-tls-gd.s created+98
......@@ -0,0 +1,98 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: echo '.tbss; .globl b, c; b: .zero 4; c:' | llvm-mc -filetype=obj -triple=powerpc - -o %t1.o
4# RUN: ld.lld -shared -soname=t1.so %t1.o -o %t1.so
5# RUN: echo '.globl __tls_get_addr; __tls_get_addr:' | llvm-mc -filetype=obj -triple=powerpc - -o %tga.o
6
7# RUN: ld.lld -shared %t.o %t1.o -o %t.so
8# RUN: llvm-readobj -d %t.so | FileCheck --check-prefix=GD-DYN %s
9# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=GD-REL %s
10# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=GD %s
11
12# RUN: ld.lld %t.o %t1.o %tga.o -o %t
13# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
14# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
15
16# RUN: ld.lld %t.o %t1.so -o %t
17# RUN: llvm-readobj -r %t | FileCheck --check-prefix=IE-REL %s
18# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=IE %s
19
20## DT_PPC_GOT represents the address of _GLOBAL_OFFSET_TABLE_.
21# GD-DYN: PPC_GOT 0x20078
22
23# GD-REL: .rela.dyn {
24# GD-REL-NEXT: 0x20078 R_PPC_DTPMOD32 a 0x0
25# GD-REL-NEXT: 0x2007C R_PPC_DTPREL32 a 0x0
26# GD-REL-NEXT: 0x20080 R_PPC_DTPMOD32 b 0x0
27# GD-REL-NEXT: 0x20084 R_PPC_DTPREL32 b 0x0
28# GD-REL-NEXT: 0x20088 R_PPC_DTPMOD32 c 0x0
29# GD-REL-NEXT: 0x2008C R_PPC_DTPREL32 c 0x0
30# GD-REL-NEXT: }
31
32## &DTPMOD(a) - _GLOBAL_OFFSET_TABLE_ = 0x20078 - 0x20078 = 0
33# GD: addi 3, 31, 0
34# GD-NEXT: bl .+32
35# GD-NEXT: lwz 3, 0(3)
36
37## &DTPMOD(b) - _GLOBAL_OFFSET_TABLE_ = 0x20080 - 0x20078 = 8
38# GD-NEXT: addi 3, 31, 8
39# GD-NEXT: bl .+20
40# GD-NEXT: lwz 3, 0(3)
41
42## &DTPMOD(c) - _GLOBAL_OFFSET_TABLE_ = 0x20088 - 0x20078 = 16
43# GD-NEXT: addi 3, 9, 16
44# GD-NEXT: bl .+8
45# GD-NEXT: lwz 3, 0(3)
46
47# NOREL: no relocations
48
49## a@tprel = 8-0x7000 = -28664
50# LE: addis 3, 2, 0
51# LE-NEXT: addi 3, 3, -28664
52# LE-NEXT: lwz 3, 0(3)
53## b@tprel = 12-0x7000 = -28660
54# LE-NEXT: addis 3, 2, 0
55# LE-NEXT: addi 3, 3, -28660
56# LE-NEXT: lwz 3, 0(3)
57## c@tprel = 16-0x7000 = -28656
58# LE-NEXT: addis 3, 2, 0
59# LE-NEXT: addi 3, 3, -28656
60# LE-NEXT: lwz 3, 0(3)
61
62# IE-REL: .rela.dyn {
63# IE-REL-NEXT: 0x10020068 R_PPC_TPREL32 b 0x0
64# IE-REL-NEXT: 0x1002006C R_PPC_TPREL32 c 0x0
65# IE-REL-NEXT: }
66
67## a is relaxed to use LE.
68## a@tprel = st_value(a)-0x8000 = -28664
69# IE: addis 3, 2, 0
70# IE-NEXT: addi 3, 3, -28664
71# IE-NEXT: lwz 3, 0(3)
72## &.got[0] - _GLOBAL_OFFSET_TABLE_ = 0
73# IE-NEXT: lwz 3, 0(31)
74# IE-NEXT: add 3, 3, 2
75# IE-NEXT: lwz 3, 0(3)
76## &.got[1] - _GLOBAL_OFFSET_TABLE_ = 4
77# IE-NEXT: lwz 3, 4(9)
78# IE-NEXT: add 3, 3, 2
79# IE-NEXT: lwz 3, 0(3)
80
81addi 3, 31, a@got@tlsgd
82bl __tls_get_addr(a@tlsgd)
83lwz 3, 0(3)
84
85addi 3, 31, b@got@tlsgd
86bl __tls_get_addr(b@tlsgd)
87lwz 3, 0(3)
88
89## -fpic may use a different register (e.g. r9).
90addi 3, 9, c@got@tlsgd
91bl __tls_get_addr(c@tlsgd)
92lwz 3, 0(3)
93
94.section .tbss
95.globl a
96.zero 8
97a:
98.zero 4
deps/lld/test/ELF/ppc32-tls-ie.s created+67
......@@ -0,0 +1,67 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3
4# RUN: ld.lld -shared %t.o -o %t.so
5# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=IE-REL %s
6# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=IE %s
7
8# RUN: ld.lld %t.o -o %t
9# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
10# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
11
12## A non-preemptable symbol (b) has 0 st_shndx.
13# IE-REL: .rela.dyn {
14# IE-REL-NEXT: 0x2005C R_PPC_TPREL32 - 0xC
15# IE-REL-NEXT: 0x20058 R_PPC_TPREL32 a 0x0
16# IE-REL-NEXT: }
17
18## &.got[0] - _GLOBAL_OFFSET_TABLE_ = 0
19# IE: lwz 10, 0(9)
20# IE-NEXT: add 10, 10, 2
21## &.got[1] - _GLOBAL_OFFSET_TABLE_ = 4
22# IE-NEXT: lwz 8, 4(7)
23# IE-NEXT: lbzx 10, 8, 2
24
25# NOREL: no relocations
26
27## a@tprel = st_value(a)-0x7000 = -28664
28## b@tprel = st_value(b)-0x7000 = -28660
29# LE: addis 10, 2, 0
30# LE-NEXT: addi 10, 10, -28664
31# LE-NEXT: addis 8, 2, 0
32# LE-NEXT: lbz 10, -28660(8)
33
34lwz 10, a@got@tprel(9)
35add 10, 10, a@tls
36
37lwz 8, c@got@tprel(7)
38lbzx 10, 8, c@tls
39
40## In IE, these instructions (op rT, rA, x@tls) are not changed.
41# IE-NEXT: lhzx 12, 2, 2
42# IE-NEXT: lwzx 13, 3, 2
43# IE-NEXT: stbx 14, 4, 2
44# IE-NEXT: sthx 15, 5, 2
45# IE-NEXT: stwx 16, 6, 2
46
47## In LE, these X-Form instructions are changed to their corresponding D-Form.
48# LE-NEXT: lhz 12, -28660(2)
49# LE-NEXT: lwz 13, -28660(3)
50# LE-NEXT: stb 14, -28660(4)
51# LE-NEXT: sth 15, -28660(5)
52# LE-NEXT: stw 16, -28660(6)
53
54lhzx 12, 2, s@tls
55lwzx 13, 3, i@tls
56stbx 14, 4, c@tls
57sthx 15, 5, s@tls
58stwx 16, 6, i@tls
59
60.section .tbss
61.globl a
62.zero 8
63a:
64.zero 4
65c:
66s:
67i:
deps/lld/test/ELF/ppc32-tls-ld.s created+82
......@@ -0,0 +1,82 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: echo '.globl __tls_get_addr; __tls_get_addr:' | llvm-mc -filetype=obj -triple=powerpc - -o %tga.o
4
5# RUN: ld.lld -shared %t.o -o %t.so
6# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=LD-REL %s
7# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=LD %s
8
9# RUN: ld.lld %t.o %tga.o -o %t
10# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
11# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
12
13# LD-REL: .rela.dyn {
14# LD-REL-NEXT: 0x20078 R_PPC_DTPMOD32 - 0x0
15# LD-REL-NEXT: }
16
17## .got - _GLOBAL_OFFSET_TABLE_ = 0
18# LD: addi 3, 30, 0
19# LD-NEXT: bl .+40
20## a@dtprel = st_value(a)-0x8000 = 65540-0x8000 = 65536*1-32764
21## b@dtprel = st_value(a)-0x8000 = 131080-0x8000 = 65536*2-32760
22# LD-NEXT: addis 9, 3, 1
23# LD-NEXT: addis 10, 3, 2
24# LD-NEXT: addi 9, 9, -32764
25# LD-NEXT: addi 10, 10, -32760
26## small@dtprel = st_value(small)-0x8000 = 4-0x8000 = -32764
27# LD-NEXT: addi 9, 3, -32764
28
29## Check that b@got@tlsld does not allocate another GOT entry.
30## It shares In.Got->TlsIndexOff allocated when processing a@got@tlsld.
31## .got - _GLOBAL_OFFSET_TABLE_ = 0
32# LD-NEXT: addi 3, 9, 0
33# LD-NEXT: bl .+12
34## b@dtprel = st_value(a)-0x8000 = 131080-0x8000 = 65536*2-32760
35# LD-NEXT: addis 29, 3, 2
36# LD-NEXT: addi 29, 29, -32760
37
38## When producing an executable, the LD code sequence can be relaxed to LE.
39## It is the same as GD->LE.
40## tpoff(_TLS_MODULE_BASE_) = 0, tpoff(a) = -8, tpoff(b) = -4
41
42# NOREL: no relocations
43
44## Set r3 to r2+4096
45# LE: addis 3, 2, 0
46# LE-NEXT: addi 3, 3, 4096
47## a@tprel = 65540-0x7000 = 65536*1-32764
48## b@tprel = 131080-0x7000 = 65536*2-32760
49# LE-NEXT: addis 9, 3, 1
50# LE-NEXT: addis 10, 3, 2
51# LE-NEXT: addi 9, 9, -32764
52# LE-NEXT: addi 10, 10, -32760
53## small@tprel = 4-0x7000 = -32764
54# LE-NEXT: addi 9, 3, -32764
55
56## Set r3 to r2+4096
57# LE-NEXT: addis 3, 2, 0
58# LE-NEXT: addi 3, 3, 4096
59## b@tprel = 131080-0x7000 = 65536*2-32760
60# LE-NEXT: addis 29, 3, 2
61# LE-NEXT: addi 29, 29, -32760
62
63addi 3, 30, a@got@tlsld
64bl __tls_get_addr(a@tlsld)
65addis 9, 3, a@dtprel@ha
66addis 10, 3, b@dtprel@ha
67addi 9, 9, a@dtprel@l
68addi 10, 10, b@dtprel@l
69addi 9, 3, small@dtprel
70
71addi 3, 9, b@got@tlsld
72bl __tls_get_addr(b@tlsld)
73addis 29, 3, b@dtprel@ha
74addi 29, 29, b@dtprel@l
75
76.section .tbss
77.zero 4
78small:
79.zero 65536
80a:
81.zero 65540
82b:
deps/lld/test/ELF/ppc32-tls-le.s created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
5
6## a@tprel = st_value(a)-0x7000 = -28664
7## b@tprel = st_value(b)-0x7000 = -28660
8# LE: addis 9, 2, 0
9# LE-NEXT: addi 9, 9, -28664
10# LE-NEXT: addis 10, 2, 0
11# LE-NEXT: lwz 9, -28660(10)
12
13addis 9, 2, a@tprel@ha
14addi 9, 9, a@tprel@l
15
16addis 10, 2, b@tprel@ha
17lwz 9,b@tprel@l(10)
18
19.section .tbss
20.globl a
21.zero 8
22a:
23.zero 4
24b:
deps/lld/test/ELF/ppc32-weak-undef-call.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=EXE %s
5# RUN: ld.lld -pie %t.o -o %t
6# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=EXE %s
7# RUN: ld.lld -shared %t.o -o %t
8# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=SHARED %s
9
10## It does not really matter how we fixup it, but we cannot overflow and
11## should not generate a call stub (this would waste space).
12# EXE: bl .+0
13
14## With -shared, create a call stub. ld.bfd produces bl .+0
15# SHARED: bl .+4
16# SHARED: 00000000.plt_pic32.foo:
17
18.weak foo
19bl foo
deps/lld/test/ELF/ppc64-abs32-dyn.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
3# RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s
4
5## Test we don't create R_AARCH64_RELATIVE.
6
7# CHECK: error: relocation R_PPC64_ADDR32 cannot be used against symbol hidden; recompile with -fPIC
8
9.globl hidden
10.hidden hidden
11hidden:
12
13.data
14.long hidden
deps/lld/test/ELF/ppc64-abs64-dyn.s created+29
......@@ -0,0 +1,29 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
3# RUN: ld.lld -shared %t.o -o %t.so
4# RUN: llvm-readobj -r %t.so | FileCheck %s
5
6# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
7# RUN: ld.lld -shared %t.o -o %t.so
8# RUN: llvm-readobj -r %t.so | FileCheck %s
9
10## Test that we create R_PPC64_RELATIVE for R_PPC64_ADDR64 to non-preemptable
11## symbols and R_PPC64_TOC in writable sections.
12
13## FIXME the addend for offset 0x20000 should be TOC base+0x8000+1, not 0x80001.
14# CHECK: .rela.dyn {
15# CHECK-NEXT: 0x20000 R_PPC64_RELATIVE - 0x8001
16# CHECK-NEXT: 0x20008 R_PPC64_RELATIVE - 0x20001
17# CHECK-NEXT: 0x20010 R_PPC64_ADDR64 external 0x1
18# CHECK-NEXT: 0x20018 R_PPC64_ADDR64 global 0x1
19# CHECK-NEXT: }
20
21.data
22.globl global
23global:
24local:
25
26.quad .TOC.@tocbase + 1
27.quad local + 1
28.quad external + 1
29.quad global + 1
deps/lld/test/ELF/ppc64-addr16-error.s deleted-13
......@@ -1,13 +0,0 @@
1// REQUIRES: ppc
2
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
4// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
5// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck %s
6
7// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
8// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
9// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck %s
10
11.short sym+65539
12
13// CHECK: relocation R_PPC64_ADDR16 out of range: 65539 is not in [-32768, 32767]
deps/lld/test/ELF/ppc64-bsymbolic-toc-restore.s+2-2
......@@ -53,7 +53,7 @@ caller:
5353# CHECK-LABEL: caller
5454# CHECK: bl .+44
5555# CHECK-NEXT: mr 31, 3
56# CHECK-NEXT: bl .+67108816
56# CHECK-NEXT: bl .+44
5757# CHECK-NEXT: ld 2, 24(1)
5858# CHECK-NEXT: add 3, 3, 31
5959# CHECK-NEXT: addi 1, 1, 32
......@@ -63,6 +63,6 @@ caller:
6363# CHECK-EMPTY:
6464# CHECK-NEXT: def:
6565# CHECK-NEXT: addis 2, 12, 2
66# CHECK-NEXT: addi 2, 2, -32636
66# CHECK-NEXT: addi 2, 2, -32616
6767# CHECK-NEXT: li 3, 55
6868# CHECK-NEXT: blr
deps/lld/test/ELF/ppc64-call-reach.s+26-30
......@@ -3,16 +3,16 @@
33# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
44# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
55# RUN: %t.o -o %t
6# RUN: llvm-objdump -d %t | FileCheck %s
6# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
77# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
88# RUN: %t.o -o %t
9# RUN: llvm-objdump -d %t | FileCheck %s
9# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
1010# RUN: ld.lld --defsym callee=0xE010014 --defsym tail_callee=0xE010024 \
1111# RUN: %t.o -o %t
12# RUN: llvm-objdump -d %t | FileCheck --check-prefix=NEGOFFSET %s
12# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=NEGOFFSET %s
1313# RUN: ld.lld --defsym callee=0x12010018 --defsym tail_callee=0x12010028 \
1414# RUN: %t.o -o %t
15# RUN: llvm-objdump -d %t | FileCheck --check-prefix=THUNK %s
15# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=THUNK %s
1616# RUN: llvm-readelf --sections %t | FileCheck --check-prefix=BRANCHLT %s
1717# RUN: not ld.lld --defsym callee=0x1001002D --defsym tail_callee=0x1001002F \
1818# RUN: %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s
......@@ -20,16 +20,16 @@
2020# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
2121# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
2222# RUN: %t.o -o %t
23# RUN: llvm-objdump -d %t | FileCheck %s
23# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
2424# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
2525# RUN: %t.o -o %t
26# RUN: llvm-objdump -d %t | FileCheck %s
26# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
2727# RUN: ld.lld --defsym callee=0xE010014 --defsym tail_callee=0xE010024 \
2828# RUN: %t.o -o %t
29# RUN: llvm-objdump -d %t | FileCheck --check-prefix=NEGOFFSET %s
29# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=NEGOFFSET %s
3030# RUN: ld.lld --defsym callee=0x12010018 --defsym tail_callee=0x12010028 \
3131# RUN: %t.o -o %t
32# RUN: llvm-objdump -d %t | FileCheck --check-prefix=THUNK %s
32# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=THUNK %s
3333# RUN: llvm-readelf --sections %t | FileCheck --check-prefix=BRANCHLT %s
3434# RUN: not ld.lld --defsym callee=0x1001002D --defsym tail_callee=0x1001002F \
3535# RUN: %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s
......@@ -58,37 +58,33 @@ test:
5858# Check that we are branching to the definitions, and not range-extending
5959# thunks.
6060# CHECK-LABEL: test
61# CHECK: 10010014: {{.*}} bl .+33554428
62# CHECK: 10010024: {{.*}} b .+33554428
61# CHECK: 10010014: bl .+33554428
62# CHECK: 10010024: b .+33554428
6363
6464# NEGOFFSET-LABEL: test
65# NEGOFFSET: 10010014: {{.*}} bl .+33554432
66# NEGOFFSET: 10010024: {{.*}} b .+33554432
65# NEGOFFSET: 10010014: bl .-33554432
66# NEGOFFSET: 10010024: b .+33554432
67
68# THUNK-LABEL: test:
69# THUNK: 10010014: bl .+20
70# THUNK: 10010024: b .+20
6771
6872# .branch_lt[0]
6973# 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# THUNK-NEXT: 10010028: addis 12, 2, 1
75# THUNK-NEXT: ld 12, -32768(12)
76# THUNK-NEXT: mtctr 12
77# THUNK-NEXT: bctr
7478
7579# .branch_lt[1]
7680# 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
81# THUNK-NEXT: 10010038: addis 12, 2, 1
82# THUNK-NEXT: ld 12, -32760(12)
83# THUNK-NEXT: mtctr 12
84# THUNK-NEXT: bctr
8885
8986# The offset from the TOC to the .branch_lt section is (-1 << 16) - 32768.
9087# Name Type Address Off Size
91# BRANCHLT: .branch_lt PROGBITS 0000000010020000 020000 000010
92# BRANCHLT: .got PROGBITS 0000000010030000 030000 000008
88# BRANCHLT: .got PROGBITS 0000000010020000 020000 000008
89# BRANCHLT: .branch_lt PROGBITS 0000000010030000 030000 000010
9390# BRANCHLT-NOT: .plt
94
deps/lld/test/ELF/ppc64-dtprel.s+17-46
......@@ -4,15 +4,15 @@
44// RUN: ld.lld -shared %t.o -o %t.so
55// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
66// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
7// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
8// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisLE %s
7// RUN: llvm-readelf -x .got %t.so | FileCheck --check-prefix=HEX-LE %s
8// RUN: llvm-objdump -d --no-show-raw-insn %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
1212// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
1313// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
14// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
15// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisBE %s
14// RUN: llvm-readelf -x .got %t.so | FileCheck --check-prefix=HEX-BE %s
15// RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=Dis %s
1616
1717 .text
1818 .abiversion 2
......@@ -97,15 +97,6 @@ test_not_adjusted:
9797 mtlr 0
9898 blr
9999
100 .globl test_got_dtprel
101 .p2align 4
102 .type test_got_dtprel,@function
103test_got_dtprel:
104 addis 3, 2, i@got@dtprel@ha
105 ld 3, i@got@dtprel@l(3)
106 addis 3, 2, i@got@dtprel@h
107 addi 3, 2, i@got@dtprel
108
109100 .section .debug_addr,"",@progbits
110101 .quad i@dtprel+32768
111102
......@@ -137,10 +128,6 @@ k:
137128// InputRelocs: R_PPC64_DTPREL16_HIGHER {{[0-9a-f]+}} k + 0
138129// InputRelocs: R_PPC64_DTPREL16_HI {{[0-9a-f]+}} k + 0
139130// InputRelocs: R_PPC64_DTPREL16_LO {{[0-9a-f]+}} k + 0
140// InputRelocs: R_PPC64_GOT_DTPREL16_HA {{[0-9a-f]+}} i + 0
141// InputRelocs: R_PPC64_GOT_DTPREL16_LO_DS {{[0-9a-f]+}} i + 0
142// InputRelocs: R_PPC64_GOT_DTPREL16_HI {{[0-9a-f]+}} i + 0
143// InputRelocs: R_PPC64_GOT_DTPREL16_DS {{[0-9a-f]+}} i + 0
144131// InputRelocs: Relocation section '.rela.debug_addr'
145132// InputRelocs: R_PPC64_DTPREL64 {{[0-9a-f]+}} i + 8000
146133
......@@ -150,10 +137,19 @@ k:
150137// OutputRelocs-NEXT: R_PPC64_DTPMOD64
151138
152139
153// i@dtprel --> (1024 - 0x8000) = -31744
154// Dis: test:
155// Dis: addi 4, 3, -31744
156// Dis: lwa 4, -31744(3)
140// The got entry for i is at .got+8*3 = 0x420510
141// i@dtprel = 1024 - 0x8000 = -31744 = 0xffffffffffff8400
142// HEX-LE: section '.got':
143// HEX-LE-NEXT: 4204f8 f8844200 00000000 00000000 00000000
144// HEX-LE-NEXT: 420508 00000000 00000000
145
146// HEX-BE: section '.got':
147// HEX-BE-NEXT: 4204f8 00000000 004284f8 00000000 00000000
148// HEX-BE-NEXT: 420508 00000000 00000000
149
150// Dis: test:
151// Dis: addi 4, 3, -31744
152// Dis-NEXT: lwa 4, -31744(3)
157153
158154// #k@dtprel(1024 + 4 + 1024 * 1024 * 4) = 0x400404
159155
......@@ -177,28 +173,3 @@ k:
177173// Dis: oris 4, 4, 63
178174// Dis: ori 4, 4, 33796
179175
180// Check for GOT entry for i. There should be a got entry which holds the offset
181// of i relative to the dynamic thread pointer.
182// i@dtprel -> (1024 - 0x8000) = 0xffff8400
183// GotDisBE: Disassembly of section .got:
184// GotDisBE: 4204f8: 00 00 00 00
185// GotDisBE: 4204fc: 00 42 84 f8
186// GotDisBE: 420510: ff ff ff ff
187// GotDisBE: 420514: ff ff 84 00
188
189// GotDisLE: Disassembly of section .got:
190// GotDisLE: 4204f8: f8 84 42 00
191// GotDisLE: 420510: 00 84 ff ff
192// GotDisLE: 420514: ff ff ff ff
193
194// Check that we have the correct offset to the got entry for i@got@dtprel
195// The got entry for i is 0x420510, and the TOC pointer is 0x4284f8.
196// #ha(i@got@dtprel) --> ((0x420510 - 0x4284f8 + 0x8000) >> 16) & 0xffff = 0
197// #lo(i@got@dtprel) --> (0x420510 - 0x4284f8) & 0xffff = -32744
198// #hi(i@got@dtprel) --> ((0x420510 - 0x4284f8) >> 16) & 0xffff = -1
199// i@got@dtprel --> 0x420510 - 0x4284f8 = -32744
200// Dis: test_got_dtprel:
201// Dis: addis 3, 2, 0
202// Dis: ld 3, -32744(3)
203// Dis: addis 3, 2, -1
204// Dis: addi 3, 2, -32744
deps/lld/test/ELF/ppc64-dynamic-relocations.s deleted-50
......@@ -1,50 +0,0 @@
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/shared-ppc64.s -o %t2.o
5// RUN: ld.lld -shared %t2.o -o %t2.so
6// RUN: ld.lld %t.o %t2.so -o %t
7// RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
8// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=DIS %s
9// RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
10
11// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
12// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
13// RUN: ld.lld -shared %t2.o -o %t2.so
14// RUN: ld.lld %t.o %t2.so -o %t
15// RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
16// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=DIS %s
17// RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
18
19
20// The dynamic relocation for foo should point to 16 bytes past the start of
21// the .plt section.
22// CHECK: Dynamic Relocations {
23// CHECK-NEXT: 0x10030010 R_PPC64_JMP_SLOT foo 0x0
24
25// There should be 2 reserved doublewords before the first entry. The dynamic
26// linker will fill those in with the address of the resolver entry point and
27// the dynamic object identifier.
28// DIS: Idx Name Size Address Type
29// DIS: .plt 00000018 0000000010030000 BSS
30
31// DT_PLTGOT should point to the start of the .plt section.
32// DT: 0x0000000000000003 PLTGOT 0x10030000
33
34 .text
35 .abiversion 2
36 .globl _start
37 .p2align 4
38 .type _start,@function
39_start:
40.Lfunc_begin0:
41.Lfunc_gep0:
42 addis 2, 12, .TOC.-.Lfunc_gep0@ha
43 addi 2, 2, .TOC.-.Lfunc_gep0@l
44.Lfunc_lep0:
45 .localentry _start, .Lfunc_lep0-.Lfunc_gep0
46 bl foo
47 nop
48 li 0, 1
49 sc
50 .size _start, .-.Lfunc_begin0
deps/lld/test/ELF/ppc64-entry-point.s+18-22
......@@ -1,14 +1,14 @@
11# REQUIRES: ppc
22
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
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-nm %t | FileCheck --check-prefix=NM %s
6# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
77
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
8# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
9# RUN: ld.lld %t.o -o %t
10# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
11# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
1212
1313.text
1414.abiversion 2
......@@ -23,8 +23,8 @@ _start:
2323 addi 4, 4, .Lfunc_gep0@l
2424 # now r4 should contain the address of _start
2525
26 lis 5, .TOC.-.Lfunc_gep0@ha
27 addi 5, 5, .TOC.-.Lfunc_gep0@l
26 lis 5, .TOC.-.Lfunc_gep0@ha # R_PPC64_REL16_HA
27 addi 5, 5, .TOC.-.Lfunc_gep0@l # R_PPC64_REL16_LO
2828 # now r5 should contain the offset s.t. r4 + r5 = TOC base
2929
3030 # exit 55
......@@ -34,16 +34,12 @@ _start:
3434.Lfunc_end0:
3535 .size _start, .Lfunc_end0-.Lfunc_begin0
3636
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
37# NM-DAG: 0000000010028000 d .TOC.
38# NM-DAG: 0000000010010000 T _start
4139
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 {{.*}}
40# 0x10010000 = (4097<<16) + 0
41# CHECK: 10010000: lis 4, 4097
42# CHECK-NEXT: 10010004: addi 4, 4, 0
43# .TOC. - _start = (2<<16) - 32768
44# CHECK-NEXT: 10010008: lis 5, 2
45# CHECK-NEXT: 1001000c: addi 5, 5, -32768
deps/lld/test/ELF/ppc64-func-entry-points.s+2-2
......@@ -73,8 +73,8 @@ glob:
7373// CHECK: 10010020: {{.*}} bl .+144
7474// CHECK: 10010034: {{.*}} bl .+84
7575// CHECK: foo_external_diff:
76// CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 2
76// CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 1
7777// CHECK-NEXT: 10010084: {{.*}} addi 2, 2, 32640
78// CHECK-NEXT: 10010088: {{.*}} nop
78// CHECK-NEXT: 10010088: {{.*}} addis 5, 2, 1
7979// CHECK: foo_external_same:
8080// CHECK-NEXT: 100100b0: {{.*}} add 3, 4, 3
deps/lld/test/ELF/ppc64-gd-to-ie.s deleted-104
......@@ -1,104 +0,0 @@
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.s -o %t2.o
5# RUN: ld.lld -shared %t2.o -o %t3.so
6# RUN: ld.lld %t.o %t3.so -o %t
7# 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 -r %t | FileCheck --check-prefix=OutputRelocs %s
10
11# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
12# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-tls.s -o %t2.o
13# RUN: ld.lld -shared %t2.o -o %t3.so
14# RUN: ld.lld %t.o %t3.so -o %t
15# 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 -r %t | FileCheck --check-prefix=OutputRelocs %s
18
19 .text
20 .abiversion 2
21 .globl _start
22 .p2align 4
23 .type _start,@function
24_start:
25.Lfunc_gep0:
26 addis 2, 12, .TOC.-.Lfunc_gep0@ha
27 addi 2, 2, .TOC.-.Lfunc_gep0@l
28.Lfunc_lep0:
29 .localentry _start, .Lfunc_lep0-.Lfunc_gep0
30 mflr 0
31 std 0, 16(1)
32 stdu 1, -32(1)
33 addis 3, 2, a@got@tlsgd@ha
34 addi 3, 3, a@got@tlsgd@l
35 bl __tls_get_addr(a@tlsgd)
36 nop
37 lwa 3, 0(3)
38 addi 1, 1, 32
39 ld 0, 16(1)
40 mtlr 0
41 blr
42
43
44 .globl other_reg
45 .p2align 4
46 .type other_reg,@function
47other_reg:
48.Lfunc_gep1:
49 addis 2, 12, .TOC.-.Lfunc_gep1@ha
50 addi 2, 2, .TOC.-.Lfunc_gep1@l
51.Lfunc_lep1:
52 .localentry other_reg, .Lfunc_lep1-.Lfunc_gep1
53 mflr 0
54 std 0, 16(1)
55 stdu 1, -32(1)
56 addis 5, 2, a@got@tlsgd@ha
57 addi 3, 5, a@got@tlsgd@l
58 bl __tls_get_addr(a@tlsgd)
59 nop
60 lwa 4, 0(3)
61 addis 30, 2, b@got@tlsgd@ha
62 addi 3, 30, b@got@tlsgd@l
63 bl __tls_get_addr(b@tlsgd)
64 nop
65 lwa 3, 0(3)
66 add 3, 4, 3
67 addi 1, 1, 32
68 ld 0, 16(1)
69 mtlr 0
70 blr
71
72 .globl __tls_get_addr
73 .type __tls_get_addr,@function
74__tls_get_addr:
75
76
77# CheckGot: .got 00000018 00000000100200c0 DATA
78# .got is at 0x100200c0 so the toc-base is 100280c0.
79# `a` is at .got[1], we expect the offsets to be:
80# Ha(a) = ((0x100200c8 - 0x100280c0) + 0x8000) >> 16 = 0
81# Lo(a) = (0x100200c8 - 0x100280c0) = -32760
82
83# Dis-LABEL: _start
84# Dis: addis 3, 2, 0
85# Dis-NEXT: ld 3, -32760(3)
86# Dis-NEXT: nop
87# Dis-NEXT: add 3, 3, 13
88
89# Dis-LABEL: other_reg
90# Dis: addis 5, 2, 0
91# Dis-NEXT: ld 3, -32760(5)
92# Dis-NEXT: nop
93# Dis-NEXT: add 3, 3, 13
94# Dis: addis 30, 2, 0
95# Dis: ld 3, -32752(30)
96# Dis-NEXT: nop
97# Dis-NEXT: add 3, 3, 13
98
99# Verify that the only dynamic relocations we emit are TPREL ones rather then
100# the DTPMOD64/DTPREL64 pair for general-dynamic.
101# OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 2 entries:
102# OutputRelocs-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
103# OutputRelocs-NEXT: {{[0-9a-f]+}} {{[0-9a-f]+}} R_PPC64_TPREL64 {{[0-9a-f]+}} a + 0
104# OutputRelocs-NEXT: {{[0-9a-f]+}} {{[0-9a-f]+}} R_PPC64_TPREL64 {{[0-9a-f]+}} b + 0
deps/lld/test/ELF/ppc64-general-dynamic-tls.s deleted-112
......@@ -1,112 +0,0 @@
1// REQUIRES: ppc
2
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: ld.lld -shared %t.o -o %t.so
5// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
6// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
7// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
8// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
9
10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
11// RUN: ld.lld -shared %t.o -o %t.so
12// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
13// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
14// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
15// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
16
17 .text
18 .abiversion 2
19 .globl test
20 .p2align 4
21 .type test,@function
22test:
23.Lfunc_gep0:
24 addis 2, 12, .TOC.-.Lfunc_gep0@ha
25 addi 2, 2, .TOC.-.Lfunc_gep0@l
26.Lfunc_lep0:
27 .localentry test, .Lfunc_lep0-.Lfunc_gep0
28 mflr 0
29 std 31, -8(1)
30 std 0, 16(1)
31 stdu 1, -48(1)
32 mr 31, 1
33 std 30, 32(31)
34 addis 3, 2, i@got@tlsgd@ha
35 addi 3, 3, i@got@tlsgd@l
36 bl __tls_get_addr(i@tlsgd)
37 nop
38 lwz 30, 0(3)
39 extsw 3, 30
40 ld 30, 32(31)
41 addi 1, 1, 48
42 ld 0, 16(1)
43 ld 31, -8(1)
44 mtlr 0
45 blr
46
47
48test_hi:
49.Lfunc_gep1:
50 addis 2, 12, .TOC.-.Lfunc_gep1@ha
51 addi 2, 2, .TOC.-.Lfunc_gep1@l
52.Lfunc_lep1:
53 .localentry test2, .Lfunc_lep1-.Lfunc_gep1
54 addis 3, 0, j@got@tlsgd@h
55 blr
56
57test_16:
58.Lfunc_gep2:
59 addis 2, 12, .TOC.-.Lfunc_gep2@ha
60 addi 2, 2, .TOC.-.Lfunc_gep2@l
61.Lfunc_lep2:
62 .localentry test16, .Lfunc_lep2-.Lfunc_gep2
63 addi 3, 0, k@got@tlsgd
64 blr
65
66// Verify that the input has every general-dynamic tls relocation type.
67// InputRelocs: Relocation section '.rela.text'
68// InputRelocs: R_PPC64_GOT_TLSGD16_HA {{0+}} i + 0
69// InputRelocs: R_PPC64_GOT_TLSGD16_LO {{0+}} i + 0
70// InputRelocs: R_PPC64_TLSGD {{0+}} i + 0
71// InputRelocs: R_PPC64_GOT_TLSGD16_HI {{0+}} j + 0
72// InputRelocs: R_PPC64_GOT_TLSGD16 {{0+}} k + 0
73
74// There is 2 got entries for each tls variable that is accessed with the
75// general-dynamic model. The entries can be though of as a structure to be
76// filled in by the dynamic linker:
77// typedef struct {
78// unsigned long int ti_module; --> R_PPC64_DTPMOD64
79// unsigned long int ti_offset; --> R_PPC64_DTPREL64
80//} tls_index;
81// OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 6 entries:
82// OutputRelocs: R_PPC64_DTPMOD64 {{0+}} i + 0
83// OutputRelocs: R_PPC64_DTPREL64 {{0+}} i + 0
84// OutputRelocs: R_PPC64_DTPMOD64 {{0+}} j + 0
85// OutputRelocs: R_PPC64_DTPREL64 {{0+}} j + 0
86// OutputRelocs: R_PPC64_DTPMOD64 {{0+}} k + 0
87// OutputRelocs: R_PPC64_DTPREL64 {{0+}} k + 0
88
89// Check that the got has 7 entires. (1 for the TOC and 3 structures of
90// 2 entries for the tls variables). Also verify the address so we can check
91// the offsets we calculated for each relocation type.
92// CheckGot: got 00000038 00000000000200f0
93
94// got starts at 0x200f0, so .TOC. will be 0x280f0.
95
96// We are building the address of the first tls_index in the got which starts at
97// 0x200f8 (got[1]).
98// #ha(i@got@tlsgd) --> (0x200f8 - 0x280f0 + 0x8000) >> 16 = 0
99// #lo(i@got@tlsgd) --> (0x200f8 - 0x280f0) & 0xFFFF = -7ff8 = -32760
100// Dis: test:
101// Dis: addis 3, 2, 0
102// Dis: addi 3, 3, -32760
103
104// Second tls_index starts at got[3].
105// #hi(j@got@tlsgd) --> (0x20108 - 0x280f0) >> 16 = -1
106// Dis: test_hi:
107// Dis: lis 3, -1
108
109// Third tls index is at got[5].
110// k@got@tlsgd --> (0x20118 - 0x280f0) = -0x7fd8 = -32728
111// Dis: test_16:
112// Dis: li 3, -32728
deps/lld/test/ELF/ppc64-got-indirect.s deleted-115
......@@ -1,115 +0,0 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-LE %s
5# RUN: ld.lld %t.o -o %t2
6# RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=CHECK-LE
7# RUN: llvm-objdump -D %t2 | FileCheck %s
8
9# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
10# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s
11# RUN: ld.lld %t.o -o %t2
12# RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=CHECK-BE
13# RUN: llvm-objdump -D %t2 | FileCheck %s
14
15# Make sure we calculate the offset correctly for a got-indirect access to a
16# global variable as described by the PPC64 ELF V2 abi.
17 .text
18 .abiversion 2
19 .globl _start # -- Begin function _start
20 .p2align 4
21 .type _start,@function
22_start: # @_start
23.Lfunc_begin0:
24.Lfunc_gep0:
25 addis 2, 12, .TOC.-.Lfunc_gep0@ha
26 addi 2, 2, .TOC.-.Lfunc_gep0@l
27.Lfunc_lep0:
28 .localentry _start, .Lfunc_lep0-.Lfunc_gep0
29# %bb.0: # %entry
30 addis 3, 2, .LC0@toc@ha
31 ld 3, .LC0@toc@l(3)
32 li 4, 0
33 stw 4, -12(1)
34 li 0,1
35 lwa 3, 0(3)
36 sc
37 .long 0
38 .quad 0
39.Lfunc_end0:
40 .size _start, .Lfunc_end0-.Lfunc_begin0
41 # -- End function
42 .section .toc,"aw",@progbits
43.LC0:
44 .tc glob[TC],glob
45 .type glob,@object # @glob
46 .data
47 .globl glob
48 .p2align 2
49glob:
50 .long 55 # 0x37
51 .size glob, 4
52
53# Verify the relocations emitted for glob are through the .toc
54
55# RELOCS-LE: Relocations [
56# RELOCS-LE: .rela.text {
57# RELOCS-LE: 0x0 R_PPC64_REL16_HA .TOC. 0x0
58# RELOCS-LE: 0x4 R_PPC64_REL16_LO .TOC. 0x4
59# RELOCS-LE: 0x8 R_PPC64_TOC16_HA .toc 0x0
60# RELOCS-LE: 0xC R_PPC64_TOC16_LO_DS .toc 0x0
61# RELOCS-LE: }
62# RELOCS-LE: .rela.toc {
63# RELOCS-LE: 0x0 R_PPC64_ADDR64 glob 0x0
64# RELOCS-LE: }
65
66# RELOCS-BE: Relocations [
67# RELOCS-BE: .rela.text {
68# RELOCS-BE: 0x2 R_PPC64_REL16_HA .TOC. 0x2
69# RELOCS-BE: 0x6 R_PPC64_REL16_LO .TOC. 0x6
70# RELOCS-BE: 0xA R_PPC64_TOC16_HA .toc 0x0
71# RELOCS-BE: 0xE R_PPC64_TOC16_LO_DS .toc 0x0
72# RELOCS-BE: }
73# RELOCS-BE: .rela.toc {
74# RELOCS-BE: 0x0 R_PPC64_ADDR64 glob 0x0
75# RELOCS-BE: }
76# RELOCS-BE:]
77
78# Verify that the global variable access is done through the correct
79# toc entry:
80# r2 = .TOC. = 0x10038000.
81# r3 = r2 - 32760 = 0x10030008 -> .toc entry for glob.
82
83# CHECK: _start:
84# CHECK-NEXT: 10010000: {{.*}} addis 2, 12, 3
85# CHECK-NEXT: 10010004: {{.*}} addi 2, 2, -32768
86# CHECK-NEXT: 10010008: {{.*}} nop
87# CHECK-NEXT: 1001000c: {{.*}} ld 3, -32760(2)
88# CHECK: 1001001c: {{.*}} lwa 3, 0(3)
89
90# CHECK-LE: Disassembly of section .data:
91# CHECK-LE-NEXT: glob:
92# CHECK-LE-NEXT: 10020000: 37 00 00 00
93
94# CHECK-LE: Disassembly of section .got:
95# CHECK-LE-NEXT: .got:
96# CHECK-LE-NEXT: 10030000: 00 80 03 10
97# CHECK-LE-NEXT: 10030004: 00 00 00 00
98
99# Verify that .toc comes right after .got
100# CHECK-LE: Disassembly of section .toc:
101# CHECK-LE: 10030008: 00 00 02 10
102
103# CHECK-BE: Disassembly of section .data:
104# CHECK-BE-NEXT: glob:
105# CHECK-BE-NEXT: 10020000: 00 00 00 37
106
107# CHECK-BE: Disassembly of section .got:
108# CHECK-BE-NEXT: .got:
109# CHECK-BE-NEXT: 10030000: 00 00 00 00
110# CHECK-BE-NEXT: 10030004: 10 03 80 00
111
112# Verify that .toc comes right after .got
113# CHECK-BE: Disassembly of section .toc:
114# CHECK-BE: 10030008: 00 00 00 00
115# CHECK-BE: 1003000c: 10 02 00 00
deps/lld/test/ELF/ppc64-ifunc.s+46-58
......@@ -1,79 +1,67 @@
11# REQUIRES: ppc
22
33# 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/shared-ppc64.s -o %t2.o
5# RUN: ld.lld -shared %t2.o -o %t2.so
6# RUN: ld.lld %t.o %t2.so -o %t
7# RUN: llvm-objdump -D %t | FileCheck %s
8# RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
9# RUN: llvm-readelf -dyn-relocations %t | FileCheck --check-prefix=DYNREL %s
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
6# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SECTIONS %s
7# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
8# RUN: llvm-readelf -r %t | FileCheck --check-prefix=DYNREL %s
109
1110# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
12# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
13# RUN: ld.lld -shared %t2.o -o %t2.so
14# RUN: ld.lld %t.o %t2.so -o %t
15# RUN: llvm-objdump -D %t | FileCheck %s
16# RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
17# RUN: llvm-readelf -dyn-relocations %t | FileCheck --check-prefix=DYNREL %s
11# RUN: ld.lld %t.o -o %t
12# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
13# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SECTIONS %s
14# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
15# RUN: llvm-readelf -r %t | FileCheck --check-prefix=DYNREL %s
1816
19# CHECK: Disassembly of section .text:
17# NM-DAG: 0000000010028000 d .TOC.
18# NM-DAG: 0000000010010000 T ifunc
19# NM-DAG: 0000000010010004 T ifunc2
2020
21# Tocbase + (0 << 16) + 32560
22# 0x100280e0 + 0 + 32560 = 0x10030010 (.plt[2])
23# CHECK: __plt_foo:
21# SECTIONS: .plt NOBITS 0000000010030000
22
23# __plt_ifunc - . = 0x10010020 - 0x10010010 = 16
24# __plt_ifunc2 - . = 0x10010044 - 0x10010018 = 28
25# CHECK: _start:
26# CHECK-NEXT: addis 2, 12, 1
27# CHECK-NEXT: addi 2, 2, 32760
28# CHECK-NEXT: 10010010: bl .+16
29# CHECK-NEXT: ld 2, 24(1)
30# CHECK-NEXT: 10010018: bl .+28
31# CHECK-NEXT: ld 2, 24(1)
32
33# .plt[0] - .TOC. = 0x10030000 - 0x10028000 = (1<<16) - 32768
34# CHECK: __plt_ifunc:
2435# CHECK-NEXT: std 2, 24(1)
25# CHECK-NEXT: addis 12, 2, 0
26# CHECK-NEXT: ld 12, 32560(12)
36# CHECK-NEXT: addis 12, 2, 1
37# CHECK-NEXT: ld 12, -32768(12)
2738# CHECK-NEXT: mtctr 12
2839# CHECK-NEXT: bctr
2940
30# Tocbase + (0 << 16) + 32568
31# 0x100280e0 + 0 + 32568 = 0x1003018 (.plt[3])
32# CHECK: __plt_ifunc:
41# .plt[1] - .TOC. = 0x10030000+8 - 0x10028000 = (1<<16) - 32760
42# CHECK: __plt_ifunc2:
3343# CHECK-NEXT: std 2, 24(1)
34# CHECK-NEXT: addis 12, 2, 0
35# CHECK-NEXT: ld 12, 32568(12)
44# CHECK-NEXT: addis 12, 2, 1
45# CHECK-NEXT: ld 12, -32760(12)
3646# CHECK-NEXT: mtctr 12
3747# CHECK-NEXT: bctr
3848
39# CHECK: ifunc:
40# CHECK-NEXT: 10010028: {{.*}} nop
41
42# CHECK: _start:
43# CHECK-NEXT: addis 2, 12, 2
44# CHECK-NEXT: addi 2, 2, -32588
45# CHECK-NEXT: bl .+67108812
46# CHECK-NEXT: ld 2, 24(1)
47# CHECK-NEXT: bl .+67108824
48# CHECK-NEXT: ld 2, 24(1)
49
50# Check tocbase
51# CHECK: Disassembly of section .got:
52# CHECK-NEXT: .got:
53# CHECK-NEXT: 100200e0
54
55# Check .plt address
56# DT_PLTGOT should point to the start of the .plt section.
57# DT: 0x0000000000000003 PLTGOT 0x10030000
58
59# Check that we emit the correct dynamic relocation type for an ifunc
60# DYNREL: 'PLT' relocation section at offset 0x{{[0-9a-f]+}} contains 48 bytes:
61# 48 bytes --> 2 Elf64_Rela relocations
62# DYNREL-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
63# DYNREL-NEXT: {{[0-9a-f]+}} {{[0-9a-f]+}} R_PPC64_JMP_SLOT {{0+}} foo + 0
64# DYNREL-NEXT: {{[0-9a-f]+}} {{[0-9a-f]+}} R_PPC64_IRELATIVE 10010028
65
66
67 .text
68 .abiversion 2
49# Check that we emit 2 R_PPC64_IRELATIVE.
50# DYNREL: R_PPC64_IRELATIVE 10010000
51# DYNREL: R_PPC64_IRELATIVE 10010004
6952
7053.type ifunc STT_GNU_IFUNC
7154.globl ifunc
7255ifunc:
73 nop
56 nop
7457
75 .global _start
76 .type _start,@function
58.type ifunc2 STT_GNU_IFUNC
59.globl ifunc2
60ifunc2:
61 nop
62
63.global _start
64.type _start,@function
7765
7866_start:
7967.Lfunc_gep0:
......@@ -81,7 +69,7 @@ _start:
8169 addi 2, 2, .TOC.-.Lfunc_gep0@l
8270.Lfunc_lep0:
8371 .localentry _start, .Lfunc_lep0-.Lfunc_gep0
84 bl foo
85 nop
8672 bl ifunc
8773 nop
74 bl ifunc2
75 nop
deps/lld/test/ELF/ppc64-initial-exec-tls.s deleted-102
......@@ -1,102 +0,0 @@
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.s -o %t2.o
5// RUN: ld.lld -shared %t2.o -o %t2.so
6// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.so -o %t
7// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
8// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
9// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
10// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
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-tls.s -o %t2.o
14// RUN: ld.lld -shared %t2.o -o %t2.so
15// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.so -o %t
16// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
17// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
18// RUN: llvm-objdump --section-headers %t | FileCheck --check-prefix=CheckGot %s
19// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
20
21 .text
22 .abiversion 2
23 .file "intial_exec.c"
24 .globl test_initial_exec # -- Begin function test_initial_exec
25 .p2align 4
26 .type test_initial_exec,@function
27test_initial_exec: # @test_initial_exec
28.Lfunc_begin0:
29.Lfunc_gep0:
30 addis 2, 12, .TOC.-.Lfunc_gep0@ha
31 addi 2, 2, .TOC.-.Lfunc_gep0@l
32.Lfunc_lep0:
33 .localentry test_initial_exec, .Lfunc_lep0-.Lfunc_gep0
34# %bb.0: # %entry
35 li 3, 0
36 stw 3, -12(1)
37 addis 3, 2, a@got@tprel@ha
38 ld 3, a@got@tprel@l(3)
39 lwzx 4, 3, a@tls
40 extsw 3, 4
41 blr
42
43
44test_hi:
45.Lfunc_gep1:
46 addis 2, 12, .TOC.-.Lfunc_gep1@ha
47 addi 2, 2, .TOC.-.Lfunc_gep1@l
48.Lfunc_lep1:
49 .localentry test2, .Lfunc_lep1-.Lfunc_gep1
50 addis 3, 0, b@got@tprel@h
51 blr
52
53test_ds:
54.Lfunc_gep2:
55 addis 2, 12, .TOC.-.Lfunc_gep2@ha
56 addi 2, 2, .TOC.-.Lfunc_gep2@l
57.Lfunc_lep2:
58 .localentry test16, .Lfunc_lep2-.Lfunc_gep2
59 addi 3, 0, c@got@tprel
60 blr
61
62// Verify that the input has every initial-exec tls relocation type.
63// InputRelocs: Relocation section '.rela.text'
64// InputRelocs: R_PPC64_GOT_TPREL16_HA {{0+}} a + 0
65// InputRelocs: R_PPC64_GOT_TPREL16_LO_DS {{0+}} a + 0
66// InputRelocs: R_PPC64_TLS {{0+}} a + 0
67// InputRelocs: R_PPC64_GOT_TPREL16_HI {{0+}} b + 0
68// InputRelocs: R_PPC64_GOT_TPREL16_DS {{0+}} c + 0
69
70// There is a got entry for each tls variable that is accessed with the
71// initial-exec model to be filled in by the dynamic linker.
72// OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 3 entries:
73// OutputRelocs: R_PPC64_TPREL64 {{0+}} a + 0
74// OutputRelocs: R_PPC64_TPREL64 {{0+}} b + 0
75// OutputRelocs: R_PPC64_TPREL64 {{0+}} c + 0
76
77// Check that the got has 4 entires. (1 for the TOC and 3 entries for TLS
78// variables). Also verify the address so we can check
79// the offsets we calculated for each relocation type.
80// CheckGot: got 00000020 00000000100200c0
81
82// GOT stats at 0x100200c0, so TOC will be 0x100280c0
83
84// We are building the address of the first TLS got entry which contains the
85// offset of the tls variable relative to the thread pointer.
86// 0x100200c8 (got[1]).
87// #ha(a@got@tprel) --> (0x100200c8 - 0x100280c0 + 0x8000) >> 16 = 0
88// #lo(a@got@tprel)) --> (0x100200c8 - 0x100280c0) & 0xFFFF = -7ff8 = -32760
89// Dis: test_initial_exec:
90// Dis: addis 3, 2, 0
91// Dis: ld 3, -32760(3)
92// Dis: lwzx 4, 3, 13
93
94// Second TLS got entry starts at got[2] 0x100200d0
95// #hi(b@got@tprel) --> (0x100200d0 - 0x100280c0) >> 16 = -1
96// Dis: test_hi:
97// Dis: lis 3, -1
98
99// Third TLS got entry starts at got[3] 0x100200d8.
100// c@got@tprel--> (0x100200d8. - 0x100280c0) = -0x7fe8 = 32744
101// Dis: test_ds:
102// Dis: li 3, -32744
deps/lld/test/ELF/ppc64-ld-got-dtprel.s created+44
......@@ -0,0 +1,44 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
4# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOCS %s
5# RUN: ld.lld -shared %t.o -o %t.so
6# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s
7## Check LD->LE relaxation does not affect R_PPC64_GOT_DTPREL16*.
8# RUN: ld.lld %t.o -o %t
9# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
10
11# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o
12# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOCS %s
13# RUN: ld.lld -shared %t.o -o %t.so
14# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s
15# RUN: ld.lld %t.o -o %t
16# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
17
18# RELOCS: .rela.text {
19# RELOCS-NEXT: R_PPC64_GOT_DTPREL16_HA i 0x0
20# RELOCS-NEXT: R_PPC64_GOT_DTPREL16_LO_DS i 0x0
21# RELOCS-NEXT: R_PPC64_GOT_DTPREL16_HI j 0x0
22# RELOCS-NEXT: R_PPC64_GOT_DTPREL16_DS j 0x0
23# RELOCS-NEXT: }
24
25## ha(i@got@dtprel) = (&.got[0] - (.got+0x8000) + 0x8000 >> 16) & 0xffff = 0
26## lo(i@got@dtprel) = &.got[0] - (.got+0x8000) & 0xffff = -32768
27## hi(j@got@dtprel) = (&.got[1] - (.got+0x8000) >> 16) & 0xffff = -1
28## j@got@dtprel = &.got[1] - (.got+0x8000) = -32760
29# CHECK: addis 3, 2, 0
30# CHECK-NEXT: ld 3, -32768(3)
31# CHECK-NEXT: addis 3, 2, -1
32# CHECK-NEXT: addi 3, 2, -32760
33
34 addis 3, 2, i@got@dtprel@ha
35 ld 3, i@got@dtprel@l(3)
36 addis 3, 2, j@got@dtprel@h
37 addi 3, 2, j@got@dtprel
38
39.section .tbss,"awT",@progbits
40.p2align 2
41i:
42 .long 0
43j:
44 .long 0
deps/lld/test/ELF/ppc64-local-dynamic.s+1-1
......@@ -113,7 +113,7 @@ k:
113113// Dis: test:
114114// Dis: addis 3, 2, 0
115115// Dis-NEXT: addi 3, 3, -32760
116// Dis-NEXT: bl .+67108804
116// Dis-NEXT: bl .+60
117117// Dis-NEXT: ld 2, 24(1)
118118// Dis-NEXT: addis 3, 3, 0
119119// Dis-NEXT: lwa 3, -32768(3)
deps/lld/test/ELF/ppc64-local-entry.s created+47
......@@ -0,0 +1,47 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t
4# RUN: ld.lld -r %t -o %t2
5# RUN: llvm-objdump -s -section=.symtab %t2 | FileCheck %s
6
7.text
8.abiversion 2
9.globl _start
10.p2align 2
11.type _start,@function
12
13_start:
14.Lfunc_begin0:
15.Lfunc_gep0:
16 addis 2, 12, .TOC.-.Lfunc_gep0@ha
17 addi 2, 2, .TOC.-.Lfunc_gep0@l
18.Lfunc_lep0:
19 .localentry _start, .Lfunc_lep0-.Lfunc_gep0
20 # The code below is not important, it just needs to access some
21 # global data or function, in order to use the TOC.
22 # In this case, it performs the following:
23 # g += 10;
24 # Also note that this code is not intended to be run, but only
25 # to check if the linker will preserve the localentry info.
26 addis 3, 2, g@toc@ha
27 addi 3, 3, g@toc@l
28 lwz 4, 0(3)
29 addi 4, 4, 10
30 stw 4, 0(3)
31 blr
32 .long 0
33 .quad 0
34.Lfunc_end0:
35 .size _start, .Lfunc_end0-.Lfunc_begin0
36
37 .type g,@object # @g
38 .lcomm g,4,4
39
40// We expect the st_other byte to be 0x60:
41// localentry = 011 (gep + 2 instructions), reserved = 000,
42// visibility = 00 (STV_DEFAULT)
43// Currently, llvm-objdump does not support displaying
44// st_other's PPC64 specific flags, thus we check the
45// result of the hexdump of .symtab section.
46
47// CHECK: 0070 00000000 00000000 00000009 12600001
deps/lld/test/ELF/ppc64-long-branch-init.s created+44
......@@ -0,0 +1,44 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-freebsd13.0 %s -o %t.o
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
6
7## .init consists of sections from several object files. Sections other than the
8## last one do not have a terminator. Check we do not create a long branch stub
9## in the middle.
10## We currently use thunk section spacing to ensure the stub is in the end. This
11## is not foolproof but good enough to not break in practice.
12
13# CHECK: Disassembly of section .init:
14# CHECK-EMPTY:
15# CHECK-LABEL: _init:
16# CHECK: blr
17# CHECK-EMPTY:
18# CHECK-LABEL: __long_branch_foo:
19
20.globl foo
21foo:
22 .space 0x2000000
23 blr
24
25.section .init,"ax",@progbits,unique,0
26.globl _init
27_init:
28 stdu 1, -48(1)
29 mflr 0
30 std 0, 64(1)
31
32.section .init,"ax",@progbits,unique,1
33 bl foo
34 nop
35
36.section .init,"ax",@progbits,unique,2
37 bl foo
38 nop
39
40.section .init,"ax",@progbits,unique,3
41 ld 1, 0(1)
42 ld 0, 16(1)
43 mtlr 0
44 blr
deps/lld/test/ELF/ppc64-long-branch-localentry-offset.s created+30
......@@ -0,0 +1,30 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=ppc64le %s -o %t.o
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-nm %t | FileCheck %s
6
7# CHECK-DAG: 0000000010010000 t __long_branch_callee
8# CHECK-DAG: 0000000010010010 T _start
9# CHECK-DAG: 0000000012010008 T callee
10
11# The bl instruction jumps to the local entry. The distance requires a long branch stub:
12# localentry(callee) - _start = 0x12010008+8 - 0x10010010 = 0x2000000
13
14# We used to compute globalentry(callee) - _start and caused a "R_PPC64_REL24
15# out of range" error because we didn't create the stub.
16
17.globl _start
18_start:
19 bl callee
20
21.space 0x1fffff4
22
23.globl callee
24callee:
25.Lgep0:
26 addis 2, 12, .TOC.-.Lgep0@ha
27 addi 2, 2, .TOC.-.Lgep0@l
28.Llep0:
29 .localentry callee, .Llep0-.Lgep0
30 blr
deps/lld/test/ELF/ppc64-long-branch.s+37-64
......@@ -1,22 +1,16 @@
11# REQUIRES: ppc
22
33# 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
4# RUN: ld.lld --no-toc-optimize %t.o -o %t
5# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
6# RUN: llvm-readelf -x .branch_lt %t | FileCheck %s -check-prefix=BRANCH-LE
7# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
118
129# 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
10# RUN: ld.lld --no-toc-optimize %t.o -o %t
11# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
12# RUN: llvm-readelf -x .branch_lt %t | FileCheck %s -check-prefix=BRANCH-BE
13# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
2014
2115 .text
2216 .abiversion 2
......@@ -52,24 +46,14 @@ _start:
5246 std 0, 16(1)
5347 stdu 1, -32(1)
5448 bl callee
55 bl foo_external_diff
56 nop
49 bl callee
5750 addi 1, 1, 32
5851 ld 0, 16(1)
5952 mtlr 0
6053
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
6854 .section .toc,"aw",@progbits
6955.LC0:
7056 .tc a[TC],a
71.LC1:
72 .tc b[TC],b
7357
7458
7559 .data
......@@ -80,42 +64,31 @@ a:
8064 .long 11
8165 .size a, 4
8266
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
67# NM: 0000000012028000 d .TOC.
68
69# Without --toc-optimize, compute the address of .toc[0] first. .toc[0] stores
70# the address of a.
71# .TOC. - callee = 0x12030000 - 0x10010000 = (514<<16) - 32768
72# CHECK: callee:
73# CHECK: 10010000: addis 2, 12, 514
74# CHECK: 10010004: addi 2, 2, -32768
75# CHECK: 10010008: addis 4, 2, 0
76
77# __long_branch_callee - . = 0x12010050 - 0x12010034 = 20
78# __long_branch_callee is not a PLT call stub. Calling it does not need TOC
79# restore, so it doesn't have to be followed by a nop.
80# CHECK: _start:
81# CHECK: 12010034: bl .+20
82# CHECK: 12010038: bl .+16
83
84# BRANCH-LE: section '.branch_lt':
85# BRANCH-LE-NEXT: 0x12030008 08000110 00000000
86# BRANCH-BE: section '.branch_lt':
87# BRANCH-BE-NEXT: 0x12030008 00000000 10010008
88
89# .branch_lt - .TOC. = 0x12030008 - 0x12028000 = (1<<16) - 32760
90# CHECK: __long_branch_callee:
91# CHECK-NEXT: 12010048: addis 12, 2, 1
92# CHECK-NEXT: ld 12, -32760(12)
93# CHECK-NEXT: mtctr 12
94# CHECK-NEXT: bctr
deps/lld/test/ELF/ppc64-plt-stub.s+36-25
......@@ -1,28 +1,39 @@
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/shared-ppc64.s -o %t2.o
5// RUN: ld.lld -shared %t2.o -o %t2.so
6// RUN: ld.lld %t.o %t2.so -o %t
7// RUN: llvm-objdump -d %t | FileCheck %s
8
9// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
10// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
11// RUN: ld.lld -shared %t2.o -o %t2.so
12// RUN: ld.lld %t.o %t2.so -o %t
13// RUN: llvm-objdump -d %t | FileCheck %s
14
15// CHECK: Disassembly of section .text:
16// CHECK-NEXT: __plt_foo:
17// CHECK-NEXT: std 2, 24(1)
18// CHECK-NEXT: addis 12, 2, 0
19// CHECK-NEXT: ld 12, 32560(12)
20// CHECK-NEXT: mtctr 12
21// CHECK-NEXT: bctr
22
23
24// CHECK: _start:
25// CHECK: bl .+67108824
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/shared-ppc64.s -o %t2.o
5# RUN: ld.lld -shared %t2.o -soname=t2.so -o %t2.so
6# RUN: ld.lld %t.o %t2.so -o %t
7# RUN: llvm-readelf -S -d %t | FileCheck --check-prefix=SEC %s
8# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %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/shared-ppc64.s -o %t2.o
12# RUN: ld.lld -shared %t2.o -soname=t2.so -o %t2.so
13# RUN: ld.lld %t.o %t2.so -o %t
14# RUN: llvm-readelf -S -d %t | FileCheck --check-prefix=SEC %s
15# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
16
17## DT_PLTGOT points to .plt
18# SEC: .plt NOBITS 0000000010030000 030000 000018
19# SEC: 0x0000000000000003 (PLTGOT) 0x10030000
20
21## .plt[0] holds the address of _dl_runtime_resolve.
22## .plt[1] holds the link map.
23## The JMP_SLOT relocation is stored at .plt[2]
24# RELOC: 0x10030010 R_PPC64_JMP_SLOT foo 0x0
25
26# CHECK: _start:
27# CHECK: 10010008: bl .+16
28
29# CHECK-LABEL: 0000000010010018 __plt_foo:
30# CHECK-NEXT: std 2, 24(1)
31# CHECK-NEXT: addis 12, 2, 0
32# CHECK-NEXT: ld 12, 32560(12)
33# CHECK-NEXT: mtctr 12
34# CHECK-NEXT: bctr
35
36
2637 .text
2738 .abiversion 2
2839 .globl _start
deps/lld/test/ELF/ppc64-rel-calls.s+3-3
......@@ -9,6 +9,7 @@
99# RUN: llvm-objdump -d %t2 | FileCheck %s
1010
1111# CHECK: Disassembly of section .text:
12# CHECK-EMPTY:
1213
1314.text
1415.global _start
......@@ -30,9 +31,8 @@ bar:
3031 nop
3132 blr
3233
33# FIXME: The printing here is misleading, the branch offset here is negative.
34# CHECK: 1001000c: {{.*}} bl .+67108852
34# CHECK: 1001000c: {{.*}} bl .-12
3535# CHECK: 10010010: {{.*}} nop
36# CHECK: 10010014: {{.*}} bl .+67108844
36# CHECK: 10010014: {{.*}} bl .-20
3737# CHECK: 10010018: {{.*}} nop
3838# CHECK: 1001001c: {{.*}} blr
deps/lld/test/ELF/ppc64-reloc-addr.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le %S/Inputs/abs255.s -o %t255.o
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le %S/Inputs/abs256.s -o %t256.o
5# RUN: llvm-mc -filetype=obj -triple=powerpc64le %S/Inputs/abs257.s -o %t257.o
6
7# RUN: ld.lld %t.o %t256.o -o %t
8# RUN: llvm-readelf -x .data %t | FileCheck %s
9# CHECK: 0x{{[0-9a-f]+}} ffff0080 ffffffff 00000080
10
11# RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck --check-prefix=OVERFLOW1 %s
12# OVERFLOW1: relocation R_PPC64_ADDR16 out of range: -32769 is not in [-32768, 65535]
13# OVERFLOW1: relocation R_PPC64_ADDR32 out of range: -2147483649 is not in [-2147483648, 4294967295]
14
15# RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck --check-prefix=OVERFLOW2 %s
16# OVERFLOW2: relocation R_PPC64_ADDR16 out of range: 65536 is not in [-32768, 65535]
17# OVERFLOW2: relocation R_PPC64_ADDR32 out of range: 4294967296 is not in [-2147483648, 4294967295]
18
19.globl _start
20_start:
21.data
22.word foo + 0xfeff
23.word foo - 0x8100
24.long foo + 0xfffffeff
25.long foo - 0x80000100
deps/lld/test/ELF/ppc64-relocs.s+66-106
......@@ -1,14 +1,14 @@
11# REQUIRES: ppc
22
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 --check-prefix=DATALE
6# RUN: llvm-objdump -D %t2 | FileCheck %s
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: ld.lld --no-toc-optimize %t.o -o %t
5# RUN: llvm-readelf -x .rodata -x .R_PPC64_TOC -x .eh_frame %t | FileCheck %s --check-prefix=DATALE
6# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
77
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 --check-prefix=DATABE
11# RUN: llvm-objdump -D %t2 | FileCheck %s
8# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
9# RUN: ld.lld --no-toc-optimize %t.o -o %t
10# RUN: llvm-readelf -x .rodata -x .R_PPC64_TOC -x .eh_frame %t | FileCheck %s --check-prefix=DATABE
11# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
1212
1313.text
1414.global _start
......@@ -30,154 +30,106 @@ _start:
3030 .tc .LJTI0_0[TC],.LJTI0_0
3131
3232.section .R_PPC64_TOC16_LO_DS,"ax",@progbits
33.globl .FR_PPC64_TOC16_LO_DS
34.FR_PPC64_TOC16_LO_DS:
3533 ld 1, .L1@toc@l(2)
3634
37# CHECK: Disassembly of section .R_PPC64_TOC16_LO_DS:
38# CHECK: .FR_PPC64_TOC16_LO_DS:
39# CHECK: 1001000c: {{.*}} ld 1, -32768(2)
35# CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_LO_DS:
36# CHECK: 1001000c: ld 1, -32768(2)
4037
4138.section .R_PPC64_TOC16_LO,"ax",@progbits
42.globl .FR_PPC64_TOC16_LO
43.FR_PPC64_TOC16_LO:
4439 addi 1, 2, .L1@toc@l
4540
46# CHECK: Disassembly of section .R_PPC64_TOC16_LO:
47# CHECK: .FR_PPC64_TOC16_LO:
48# CHECK: 10010010: {{.*}} addi 1, 2, -32768
41# CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_LO:
42# CHECK: 10010010: addi 1, 2, -32768
4943
5044.section .R_PPC64_TOC16_HI,"ax",@progbits
51.globl .FR_PPC64_TOC16_HI
52.FR_PPC64_TOC16_HI:
5345 addis 1, 2, .L1@toc@h
5446
55# CHECK: Disassembly of section .R_PPC64_TOC16_HI:
56# CHECK: .FR_PPC64_TOC16_HI:
57# CHECK: 10010014: {{.*}} addis 1, 2, -1
47# CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_HI:
48# CHECK: 10010014: addis 1, 2, -1
5849
5950.section .R_PPC64_TOC16_HA,"ax",@progbits
60.globl .FR_PPC64_TOC16_HA
61.FR_PPC64_TOC16_HA:
6251 addis 1, 2, .L1@toc@ha
6352
64# CHECK: Disassembly of section .R_PPC64_TOC16_HA:
65# CHECK: .FR_PPC64_TOC16_HA:
66# CHECK: 10010018: {{.*}} nop
53# CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_HA:
54# CHECK: 10010018: addis 1, 2, 0
6755
6856.section .R_PPC64_REL24,"ax",@progbits
69.globl .FR_PPC64_REL24
70.FR_PPC64_REL24:
71 b .Lfoox
72.section .R_PPC64_REL24_2,"ax",@progbits
73.Lfoox:
57 b 1f
581:
7459
75# CHECK: Disassembly of section .R_PPC64_REL24:
76# CHECK: .FR_PPC64_REL24:
77# CHECK: 1001001c: {{.*}} b .+4
60# CHECK-LABEL: Disassembly of section .R_PPC64_REL24:
61# CHECK: 1001001c: b .+4
7862
7963.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:
64 beq 1f
651:
8566
86# CHECK: Disassembly of section .R_PPC64_REL14:
87# CHECK: .FR_PPC64_REL14:
88# CHECK: 10010020: {{.*}} bt 2, .+4
67# CHECK-LABEL: Disassembly of section .R_PPC64_REL14:
68# CHECK: 10010020: bt 2, .+4
8969
9070.section .R_PPC64_ADDR16_LO,"ax",@progbits
91.globl .FR_PPC64_ADDR16_LO
92.FR_PPC64_ADDR16_LO:
9371 li 1, .Lfoo@l
9472
95# CHECK: Disassembly of section .R_PPC64_ADDR16_LO:
96# CHECK: .FR_PPC64_ADDR16_LO:
97# CHECK: 10010024: {{.*}} li 1, 0
73# CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_LO:
74# CHECK: 10010024: li 1, 0
9875
9976.section .R_PPC64_ADDR16_HI,"ax",@progbits
100.globl .FR_PPC64_ADDR16_HI
101.FR_PPC64_ADDR16_HI:
10277 li 1, .Lfoo@h
10378
104# CHECK: Disassembly of section .R_PPC64_ADDR16_HI:
105# CHECK: .FR_PPC64_ADDR16_HI:
106# CHECK: 10010028: {{.*}} li 1, 4097
79# CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HI:
80# CHECK: 10010028: li 1, 4097
10781
10882.section .R_PPC64_ADDR16_HA,"ax",@progbits
109.globl .FR_PPC64_ADDR16_HA
110.FR_PPC64_ADDR16_HA:
11183 li 1, .Lfoo@ha
11284
113# CHECK: Disassembly of section .R_PPC64_ADDR16_HA:
114# CHECK: .FR_PPC64_ADDR16_HA:
115# CHECK: 1001002c: {{.*}} li 1, 4097
85# CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HA:
86# CHECK: 1001002c: li 1, 4097
11687
11788.section .R_PPC64_ADDR16_HIGHER,"ax",@progbits
118.globl .FR_PPC64_ADDR16_HIGHER
119.FR_PPC64_ADDR16_HIGHER:
12089 li 1, .Lfoo@higher
12190
122# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER:
123# CHECK: .FR_PPC64_ADDR16_HIGHER:
124# CHECK: 10010030: {{.*}} li 1, 0
91# CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HIGHER:
92# CHECK: 10010030: li 1, 0
12593
12694.section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits
127.globl .FR_PPC64_ADDR16_HIGHERA
128.FR_PPC64_ADDR16_HIGHERA:
12995 li 1, .Lfoo@highera
13096
131# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA:
132# CHECK: .FR_PPC64_ADDR16_HIGHERA:
133# CHECK: 10010034: {{.*}} li 1, 0
97# CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HIGHERA:
98# CHECK: 10010034: li 1, 0
13499
135100.section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits
136.globl .FR_PPC64_ADDR16_HIGHEST
137.FR_PPC64_ADDR16_HIGHEST:
138101 li 1, .Lfoo@highest
139102
140# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST:
141# CHECK: .FR_PPC64_ADDR16_HIGHEST:
142# CHECK: 10010038: {{.*}} li 1, 0
103# CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HIGHEST:
104# CHECK: 10010038: li 1, 0
143105
144106.section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits
145.globl .FR_PPC64_ADDR16_HIGHESTA
146.FR_PPC64_ADDR16_HIGHESTA:
147107 li 1, .Lfoo@highesta
148108
149# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:
150# CHECK: .FR_PPC64_ADDR16_HIGHESTA:
151# CHECK: 1001003c: {{.*}} li 1, 0
109# CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:
110# CHECK: 1001003c: li 1, 0
152111
153112.section .R_PPC64_REL32, "ax",@progbits
154.globl .FR_PPC64_REL32
155.FR_PPC64_REL32:
156113 addis 5, 2, .LC0@toc@ha
157114 ld 5, .LC0@toc@l(5)
158115.LBB0_2:
159116 add 3, 3, 4
160117
161# DATALE: Disassembly of section .rodata:
162# DATALE: .rodata:
163# DATALE: 10000190: b8 fe 00 00
118# DATALE: '.rodata':
119# DATALE: 0x100001c8 80fe0000
164120
165# DATABE: Disassembly of section .rodata:
166# DATABE: .rodata:
167# DATABE: 10000190: 00 00 fe b8
121# DATABE: '.rodata':
122# DATABE: 0x100001c8 0000fe80
168123
169124# Address of rodata + value stored at rodata entry
170125# should equal address of LBB0_2.
171126# 0x10000190 + 0xfeb4 = 0x10010044
172# CHECK: Disassembly of section .R_PPC64_REL32:
173# CHECK: .FR_PPC64_REL32:
174# CHECK: 10010040: {{.*}} nop
175# CHECK: 10010044: {{.*}} ld 5, -32736(2)
176# CHECK: 10010048: {{.*}} add 3, 3, 4
127# CHECK-LABEL: Disassembly of section .R_PPC64_REL32:
128# CHECK: 10010040: addis 5, 2, 0
129# CHECK: 10010044: ld 5, -32736(5)
130# CHECK: 10010048: add 3, 3, 4
177131
178132.section .R_PPC64_REL64, "ax",@progbits
179.globl .FR_PPC64_REL64
180.FR_PPC64_REL64:
181133 .cfi_startproc
182134 .cfi_personality 148, __foo
183135 li 0, 1
......@@ -187,18 +139,26 @@ _start:
187139__foo:
188140 li 3,0
189141
190# Check that address of eh_frame entry + value stored
191# should equal the address of foo. Since it is not aligned,
192# the entry is not stored exactly at 10000198. It starts at
193# address 0x1000019a and has the value 0xfeaa.
194# 0x100001aa + 0xfeae = 0x10010058
195# DATALE: Disassembly of section .eh_frame:
196# DATALE: .eh_frame:
197# DATALE: 100001a8: {{.*}} ae fe
142.section .R_PPC64_TOC,"a",@progbits
143 .quad .TOC.@tocbase
198144
199# DATABE: Disassembly of section .eh_frame:
200# DATABE: .eh_frame:
201# DATABE: 100001b0: fe ae {{.*}}
145# SEC: .got PROGBITS 0000000010020000
146
147## tocbase = .got+0x8000 = 0x10028000
148# DATALE-LABEL: section '.R_PPC64_TOC':
149# DATALE: 00800210 00000000
150
151# DATABE-LABEL: section '.R_PPC64_TOC':
152# DATABE: 00000000 10028000
153
154# Check that the personality (relocated by R_PPC64_REL64) in the .eh_frame
155# equals the address of __foo.
156# 0x100001ea + 0xfe6e = 0x10010058
157# DATALE: section '.eh_frame':
158# DATALE: 0x100001e8 {{....}}6efe
159
160# DATABE: section '.eh_frame':
161# DATABE: 0x100001e8 {{[0-9a-f]+ [0-9a-f]+}} fe6e{{....}}
202162
203163# CHECK: __foo
204# CHECK-NEXT: 10010058: {{.*}} li 3, 0
164# CHECK-NEXT: 10010058: li 3, 0
deps/lld/test/ELF/ppc64-shared-long_branch.s+8-8
......@@ -83,32 +83,32 @@ b:
8383
8484# Verify address of the callee
8585# CALLEE_DUMP: callee:
86# CALLEE_DUMP: 10000: {{.*}} addis 2, 12, 515
86# CALLEE_DUMP: 10000: {{.*}} addis 2, 12, 514
8787# CALLEE_DUMP: 10004: {{.*}} addi 2, 2, -32528
8888# CALLEE_DUMP: 10008: {{.*}} addis 4, 2, 0
8989
9090# Verify the address of _start, and the call to the long-branch thunk.
9191# CALLER_DUMP: _start:
92# CALLER_DUMP: 2010020: {{.*}} addis 2, 12, 3
92# CALLER_DUMP: 2010020: {{.*}} addis 2, 12, 2
9393# CALLER_DUMP: 2010038: {{.*}} bl .+56
9494
9595# Verify the thunks contents: TOC-pointer + offset = .branch_lt[0]
96# 0x20380F0 + 32552 = 0x2040018
96# 0x20280F0 + 32560 = 0x2030020
9797# CALLER_DUMP: __long_branch_callee:
9898# CALLER_DUMP: 2010060: {{.*}} addis 12, 2, 0
99# CALLER_DUMP: 2010064: {{.*}} ld 12, 32552(12)
99# CALLER_DUMP: 2010064: {{.*}} ld 12, 32560(12)
100100# CALLER_DUMP: 2010068: {{.*}} mtctr 12
101101# CALLER_DUMP: 201006c: {{.*}} bctr
102102
103103# .got section is at address 0x20300f0 so TOC pointer points to 0x20400F0.
104104# .plt section has a 2 entry header and a single entry for the long branch.
105105# [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
106# SECTIONS: [10] .got PROGBITS 00000000020200f0 20200f0 000008
107# SECTIONS: [13] .plt NOBITS 0000000002030008 2030008 000018
108# SECTIONS: [14] .branch_lt NOBITS 0000000002030020 2030008 000008
109109
110110# There is a relative dynamic relocation for (.plt + 16 bytes), with a base
111111# address equal to callees local entry point (0x10000 + 8).
112112# DYNRELOC: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 3 entries:
113113# DYNRELOC: Offset Info Type Symbol's Value
114# DYNRELOC: 0000000002040018 0000000000000016 R_PPC64_RELATIVE 10008
114# DYNRELOC: 0000000002030020 0000000000000016 R_PPC64_RELATIVE 10008
deps/lld/test/ELF/ppc64-sort-small-cm-relocs.s created+108
......@@ -0,0 +1,108 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input2.s -o %t2.o
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input3.s -o %t3.o
5# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-sort-small-cm-relocs-input4.s -o %t4.o
6
7# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -Map=%t.map
8# RUN: FileCheck %s < %t.map
9
10# Test an alternate link order.
11# RUN: ld.lld %t2.o %t3.o %t4.o %t1.o -o %t -Map=%t.map
12# RUN: FileCheck %s -check-prefix=ALTERNATE < %t.map
13
14# If a linker script has a sections command then allow that to override the
15# default sorting behavior.
16# RUN: echo "SECTIONS { \
17# RUN: .toc : { \
18# RUN: *ppc64-sort-small-cm-relocs.s.tmp4.o(.toc*) \
19# RUN: *ppc64-sort-small-cm-relocs.s.tmp1.o(.toc*) \
20# RUN: *(.toc*) \
21# RUN: } \
22# RUN: } " > %t.script
23# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
24# RUN: FileCheck %s -check-prefix=SEC-CMD < %t.map
25
26# RUN: echo "SECTIONS { .text : {*(.text*)} } " > %t.script
27# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
28# RUN: FileCheck %s -check-prefix=SEC-CMD2 < %t.map
29
30# Default sort if the linker script does not have a sections command.
31# RUN: echo "" > %t.script
32# RUN: ld.lld %t1.o %t2.o %t3.o %t4.o -o %t -script %t.script -Map=%t.map
33# RUN: FileCheck %s -check-prefix=NOSEC < %t.map
34 .text
35
36 .global _start
37 .type _start,@function
38_start:
39 li 3, 55
40 blr
41
42 .type a,@object
43 .data
44 .global a
45a:
46 .long 10
47 .size a, 4
48
49 .type c,@object
50 .data
51 .global c
52c:
53 .long 55
54 .size c, 4
55
56 .type d,@object
57 .global d
58d:
59 .long 33
60 .size d, 4
61
62 # .toc section contains only some constants.
63 .section .toc,"aw",@progbits
64 .quad 0xa1a1a1a1a1a1a1a1
65 .quad 0xb2b2b2b2b2b2b2b2
66
67# Input files tmp3.o and tmp4.o contain small code model relocs.
68
69# CHECK: .got
70# CHECK-NEXT: <internal>:(.got)
71# CHECK-NEXT: .toc
72# CHECK-NEXT: {{.*}}3.o:(.toc)
73# CHECK-NEXT: {{.*}}4.o:(.toc)
74# CHECK-NEXT: {{.*}}1.o:(.toc)
75# CHECK-NEXT: {{.*}}2.o:(.toc)
76
77# ALTERNATE: .got
78# ALTERNATE-NEXT: <internal>:(.got)
79# ALTERNATE-NEXT: .toc
80# ALTERNATE-NEXT: {{.*}}3.o:(.toc)
81# ALTERNATE-NEXT: {{.*}}4.o:(.toc)
82# ALTERNATE-NEXT: {{.*}}2.o:(.toc)
83# ALTERNATE-NEXT: {{.*}}1.o:(.toc)
84
85# SEC-CMD: .got
86# SEC-CMD-NEXT: <internal>:(.got)
87# SEC-CMD-NEXT: .toc
88# SEC-CMD-NEXT: {{.*}}4.o:(.toc)
89# SEC-CMD-NEXT: {{.*}}1.o:(.toc)
90# SEC-CMD-NEXT: {{.*}}2.o:(.toc)
91# SEC-CMD-NEXT: {{.*}}3.o:(.toc)
92
93# SEC-CMD2: .got
94# SEC-CMD2-NEXT: <internal>:(.got)
95# SEC-CMD2-NEXT: .toc
96# SEC-CMD2-NEXT: {{.*}}1.o:(.toc)
97# SEC-CMD2-NEXT: {{.*}}2.o:(.toc)
98# SEC-CMD2-NEXT: {{.*}}3.o:(.toc)
99# SEC-CMD2-NEXT: {{.*}}4.o:(.toc)
100
101# NOSEC: .got
102# NOSEC-NEXT: <internal>:(.got)
103# NOSEC-NEXT: .toc
104# NOSEC-NEXT: {{.*}}3.o:(.toc)
105# NOSEC-NEXT: {{.*}}4.o:(.toc)
106# NOSEC-NEXT: {{.*}}1.o:(.toc)
107# NOSEC-NEXT: {{.*}}2.o:(.toc)
108
deps/lld/test/ELF/ppc64-tls-gd-le-small.s deleted-61
......@@ -1,61 +0,0 @@
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 deleted-83
......@@ -1,83 +0,0 @@
1// REQUIRES: ppc
2
3// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
5// RUN: ld.lld %t.o -o %t
6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
7// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
8
9// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
10// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
11// RUN: ld.lld %t.o -o %t
12// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
13// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
14
15 .text
16 .abiversion 2
17 .globl _start # -- Begin function _start
18 .p2align 4
19 .type _start,@function
20_start: # @_start
21.Lfunc_begin0:
22.Lfunc_gep0:
23 addis 2, 12, .TOC.-.Lfunc_gep0@ha
24 addi 2, 2, .TOC.-.Lfunc_gep0@l
25.Lfunc_lep0:
26 .localentry _start, .Lfunc_lep0-.Lfunc_gep0
27# %bb.0: # %entry
28 mflr 0
29 std 31, -8(1)
30 std 0, 16(1)
31 stdu 1, -64(1)
32 mr 31, 1
33 std 30, 48(31) # 8-byte Folded Spill
34 li 3, 0
35 stw 3, 44(31)
36 addis 3, 2, a@got@tlsgd@ha
37 addi 3, 3, a@got@tlsgd@l
38 bl __tls_get_addr(a@tlsgd)
39 nop
40 lwz 30, 0(3)
41 extsw 3, 30
42 ld 30, 48(31) # 8-byte Folded Reload
43 addi 1, 1, 64
44 ld 0, 16(1)
45 ld 31, -8(1)
46 mtlr 0
47 blr
48 .long 0
49 .quad 0
50.Lfunc_end0:
51 .size _start, .Lfunc_end0-.Lfunc_begin0
52
53.globl __tls_get_addr
54.type __tls_get_addr,@function
55__tls_get_addr:
56
57 # -- End function
58 .type a,@object # @a
59 .section .tdata,"awT",@progbits
60 .globl a
61 .p2align 2
62a:
63 .long 55 # 0x37
64 .size a, 4
65
66// Verify that the input has general-dynamic tls relocation types
67// InputRelocs: Relocation section '.rela.text'
68// InputRelocs: R_PPC64_GOT_TLSGD16_HA {{0+}} a + 0
69// InputRelocs: R_PPC64_GOT_TLSGD16_LO {{0+}} a + 0
70// InputRelocs: R_PPC64_TLSGD {{0+}} a + 0
71
72// Verify that the general-dynamic sequence is relaxed to local exec.
73// #ha(a@tprel) --> (0 - 0x7000 + 0x8000) >> 16 = 0
74// #lo(a@tprel)) --> (0 - 0x7000) & 0xFFFF = -0x7000 = -28672
75// Dis: _start:
76// Dis: nop
77// Dis: addis 3, 13, 0
78// Dis: nop
79// Dis: addi 3, 3, -28672
80
81// Verify that no general-dynamic relocations exist for the dynamic linker.
82// OutputRelocs-NOT: R_PPC64_DTPMOD64
83// OutputRelocs-NOT: R_PPC64_DTPREL64
deps/lld/test/ELF/ppc64-tls-gd.s created+102
......@@ -0,0 +1,102 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
3# RUN: echo '.tbss; .globl b, c; b: .zero 4; c:' | llvm-mc -filetype=obj -triple=powerpc64le - -o %t1.o
4# RUN: ld.lld -shared -soname=t1.so %t1.o -o %t1.so
5
6# RUN: ld.lld -shared %t.o %t1.o -o %t.so
7# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=GD-REL %s
8# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=GD %s
9
10# RUN: ld.lld %t.o %t1.o -o %t
11# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
12# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
13
14# RUN: ld.lld %t.o %t1.so -o %t
15# RUN: llvm-readobj -r %t | FileCheck --check-prefix=IE-REL %s
16# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=IE %s
17
18# GD-REL: .rela.dyn {
19# GD-REL-NEXT: 0x200F0 R_PPC64_DTPMOD64 a 0x0
20# GD-REL-NEXT: 0x200F8 R_PPC64_DTPREL64 a 0x0
21# GD-REL-NEXT: 0x20100 R_PPC64_DTPMOD64 b 0x0
22# GD-REL-NEXT: 0x20108 R_PPC64_DTPREL64 b 0x0
23# GD-REL-NEXT: 0x20110 R_PPC64_DTPMOD64 c 0x0
24# GD-REL-NEXT: 0x20118 R_PPC64_DTPREL64 c 0x0
25# GD-REL-NEXT: }
26
27## &DTPMOD(a) - .TOC. = &.got[0] - (.got+0x8000) = -32768
28# GD: addis 3, 2, 0
29# GD-NEXT: addi 3, 3, -32768
30# GD-NEXT: bl .+40
31# GD-NEXT: ld 2, 24(1)
32
33## &DTPMOD(b) - .TOC. = &.got[2] - (.got+0x8000) = -32752
34# GD-NEXT: addis 3, 2, 0
35# GD-NEXT: addi 3, 3, -32752
36# GD-NEXT: bl .+24
37# GD-NEXT: ld 2, 24(1)
38
39## &DTPMOD(b) - .TOC. = &.got[4] - (.got+0x8000) = -32736
40# GD-NEXT: li 3, -32736
41# GD-NEXT: bl .+12
42# GD-NEXT: ld 2, 24(1)
43
44# NOREL: no relocations
45
46## a@tprel = st_value(a)-0x7000 = -28664
47# LE: nop
48# LE-NEXT: addis 3, 13, 0
49# LE-NEXT: nop
50# LE-NEXT: addi 3, 3, -28664
51## b@tprel = st_value(b)-0x7000 = -28660
52# LE: nop
53# LE-NEXT: addis 3, 13, 0
54# LE-NEXT: nop
55# LE-NEXT: addi 3, 3, -28660
56## c@tprel = st_value(c)-0x7000 = -28656
57# LE-NEXT: addis 3, 13, 0
58# LE-NEXT: nop
59# LE-NEXT: addi 3, 3, -28656
60
61# IE-REL: .rela.dyn {
62# IE-REL-NEXT: 0x100200C0 R_PPC64_TPREL64 b 0x0
63# IE-REL-NEXT: 0x100200C8 R_PPC64_TPREL64 c 0x0
64# IE-REL-NEXT: }
65
66## a is relaxed to use LE.
67## a@tprel = st_value(a)-0x7000 = -28664
68# IE: nop
69# IE-NEXT: addis 3, 13, 0
70# IE-NEXT: nop
71# IE-NEXT: addi 3, 3, -28664
72## &DTPMOD(b) - .TOC. = &.got[0] - (.got+0x8000) = -32768
73# IE-NEXT: addis 3, 2, 0
74# IE-NEXT: ld 3, -32768(3)
75# IE-NEXT: nop
76# IE-NEXT: add 3, 3, 13
77## &DTPMOD(c) - .TOC. = &.got[1] - (.got+0x8000) = -32760
78## r0 is wrong. R_PPC64_GOT_TLS16 cannot be relaxed to IE but the behavior is
79## consistent with ld.bfd
80# IE-NEXT: ld 3, -32760(0)
81# IE-NEXT: nop
82# IE-NEXT: add 3, 3, 13
83
84addis 3, 2, a@got@tlsgd@ha
85addi 3, 3, a@got@tlsgd@l
86bl __tls_get_addr(a@tlsgd)
87nop
88
89addis 3, 2, b@got@tlsgd@ha
90addi 3, 3, b@got@tlsgd@l
91bl __tls_get_addr(b@tlsgd)
92nop
93
94addi 3, 0, c@got@tlsgd
95bl __tls_get_addr(c@tlsgd)
96nop
97
98.section .tbss
99.globl a
100.zero 8
101a:
102.zero 4
deps/lld/test/ELF/ppc64-tls-ie-le.s deleted-140
......@@ -1,140 +0,0 @@
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-ie.s created+171
......@@ -0,0 +1,171 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
4# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=INPUT-REL %s
5## IE
6# RUN: ld.lld -shared %t.o -o %t.so
7# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=IE-REL %s
8# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=IE %s
9## IE -> LE
10# RUN: ld.lld %t.o -o %t
11# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
12# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
13
14# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o
15# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=INPUT-REL %s
16## IE
17# RUN: ld.lld -shared %t.o -o %t.so
18# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=IE-REL %s
19# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=IE %s
20## IE -> LE
21# RUN: ld.lld %t.o -o %t
22# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
23# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
24
25# IE-REL: .rela.dyn {
26# IE-REL-NEXT: 0x200B0 R_PPC64_TPREL64 c 0x0
27# IE-REL-NEXT: 0x200C0 R_PPC64_TPREL64 i 0x0
28# IE-REL-NEXT: 0x200C8 R_PPC64_TPREL64 l 0x0
29# IE-REL-NEXT: 0x200B8 R_PPC64_TPREL64 s 0x0
30# IE-REL-NEXT: }
31
32# INPUT-REL: R_PPC64_GOT_TPREL16_HA c 0x0
33# INPUT-REL: R_PPC64_GOT_TPREL16_LO_DS c 0x0
34# INPUT-REL: R_PPC64_TLS c 0x0
35## &.got[0] - .TOC. = -32768
36# IE-LABEL: test1:
37# IE-NEXT: addis 3, 2, 0
38# IE-NEXT: ld 3, -32768(3)
39# IE-NEXT: lbzx 3, 3, 13
40# LE-LABEL: test1:
41# LE-NEXT: nop
42# LE-NEXT: addis 3, 13, 0
43# LE-NEXT: lbz 3, -28672(3)
44test1:
45 addis 3, 2, c@got@tprel@ha
46 ld 3, c@got@tprel@l(3)
47 lbzx 3, 3, c@tls
48
49# INPUT-REL: R_PPC64_GOT_TPREL16_HA s 0x0
50# INPUT-REL: R_PPC64_GOT_TPREL16_LO_DS s 0x0
51# INPUT-REL: R_PPC64_TLS s 0x0
52## &.got[1] - .TOC. = -32760
53# IE-LABEL: test2:
54# IE-NEXT: addis 3, 2, 0
55# IE-NEXT: ld 3, -32760(3)
56# IE-NEXT: lhzx 3, 3, 13
57# LE-LABEL: test2:
58# LE-NEXT: nop
59# LE-NEXT: addis 3, 13, 0
60# LE-NEXT: lhz 3, -28670(3)
61test2:
62 addis 3, 2, s@got@tprel@ha
63 ld 3, s@got@tprel@l(3)
64 lhzx 3, 3, s@tls
65
66# INPUT-REL: R_PPC64_GOT_TPREL16_HA i 0x0
67# INPUT-REL: R_PPC64_GOT_TPREL16_LO_DS i 0x0
68# INPUT-REL: R_PPC64_TLS i 0x0
69## &.got[2] - .TOC. = -32752
70# IE-LABEL: test3:
71# IE-NEXT: addis 3, 2, 0
72# IE-NEXT: ld 3, -32752(3)
73# IE-NEXT: lwzx 3, 3, 13
74# LE-LABEL: test3:
75# LE-NEXT: nop
76# LE-NEXT: addis 3, 13, 0
77# LE-NEXT: lwz 3, -28668(3)
78test3:
79 addis 3, 2, i@got@tprel@ha
80 ld 3, i@got@tprel@l(3)
81 lwzx 3, 3, i@tls
82
83# INPUT-REL: R_PPC64_GOT_TPREL16_HA l 0x0
84# INPUT-REL: R_PPC64_GOT_TPREL16_LO_DS l 0x0
85# INPUT-REL: R_PPC64_TLS l 0x0
86## &.got[3] - .TOC. = -32744
87# IE-LABEL: test4:
88# IE-NEXT: addis 3, 2, 0
89# IE-NEXT: ld 3, -32744(3)
90# IE-NEXT: ldx 3, 3, 13
91# LE-LABEL: test4:
92# LE-NEXT: nop
93# LE-NEXT: addis 3, 13, 0
94# LE-NEXT: ld 3, -28664(3)
95test4:
96 addis 3, 2, l@got@tprel@ha
97 ld 3, l@got@tprel@l(3)
98 ldx 3, 3, l@tls
99
100# LE-LABEL: test5:
101# LE-NEXT: nop
102# LE-NEXT: addis 4, 13, 0
103# LE-NEXT: stb 3, -28672(4)
104test5:
105 addis 4, 2, c@got@tprel@ha
106 ld 4, c@got@tprel@l(4)
107 stbx 3, 4, c@tls
108
109
110# LE-LABEL: test6:
111# LE-NEXT: nop
112# LE-NEXT: addis 4, 13, 0
113# LE-NEXT: sth 3, -28670(4)
114test6:
115 addis 4, 2, s@got@tprel@ha
116 ld 4, s@got@tprel@l(4)
117 sthx 3, 4, s@tls
118
119
120# LE-LABEL: test7:
121# LE-NEXT: nop
122# LE-NEXT: addis 4, 13, 0
123# LE-NEXT: stw 3, -28668(4)
124test7:
125 addis 4, 2, i@got@tprel@ha
126 ld 4, i@got@tprel@l(4)
127 stwx 3, 4, i@tls
128
129# LE-LABEL: test8:
130# LE-NEXT: nop
131# LE-NEXT: addis 4, 13, 0
132# LE-NEXT: std 3, -28664(4)
133test8:
134 addis 4, 2, l@got@tprel@ha
135 ld 4, l@got@tprel@l(4)
136 stdx 3, 4, l@tls
137
138# LE-LABEL: test9:
139# LE-NEXT: nop
140# LE-NEXT: addis 3, 13, 0
141# LE-NEXT: addi 3, 3, -28668
142test9:
143 addis 3, 2, i@got@tprel@ha
144 ld 3, i@got@tprel@l(3)
145 add 3, 3, i@tls
146
147# LE-LABEL: test_ds:
148# LE-NEXT: addis 4, 13, 0
149# LE-NEXT: std 3, -28664(4)
150test_ds:
151 ld 4, l@got@tprel(2)
152 stdx 3, 4, l@tls
153
154# NOREL: There are no relocations in this file.
155
156.section .tdata,"awT",@progbits
157.globl c, s, i, l
158c:
159.byte 97
160
161.p2align 1
162s:
163.short 55
164
165.p2align 2
166i:
167.long 55
168
169.p2align 3
170l:
171.quad 55
deps/lld/test/ELF/ppc64-tls-ld-le.s+3-5
......@@ -3,13 +3,13 @@
33// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
44// 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
6// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=Dis %s
77// 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
1010// 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
12// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=Dis %s
1313// RUN: llvm-readelf -r %t | FileCheck --check-prefix=OutputRelocs %s
1414
1515 .text
......@@ -52,9 +52,7 @@ _start: # @_start
5252.Lfunc_end0:
5353 .size _start, .Lfunc_end0-.Lfunc_begin0
5454 # -- End function
55.globl __tls_get_addr
56.type __tls_get_addr,@function
57__tls_get_addr:
55
5856 .type a,@object # @a
5957 .section .tdata,"awT",@progbits
6058 .p2align 2
deps/lld/test/ELF/ppc64-tls-ld-preemptable.s created+35
......@@ -0,0 +1,35 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=ppc64le %s -o %t.o
3# RUN: ld.lld %t.o -shared -o %t.so
4# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s
5# RUN: llvm-nm %t.so | FileCheck --check-prefix=NM %s
6# RUN: llvm-readelf -x .rodata %t.so | FileCheck --check-prefix=RODATA %s
7
8# 0x2a - 0x8000 = -32726
9# CHECK: addis 4, 3, 0
10# CHECK-NEXT: addi 4, 4, -32726
11# CHECK-NEXT: lis 5, 0
12# CHECK-NEXT: ori 5, 5, 0
13
14# NM: 000000000000002a B i
15# RODATA: 2a000000 00000000
16
17# We used to error on R_PPC64_DTPREL* to preemptable symbols.
18# i is STB_GLOBAL and preemptable.
19.globl foo
20foo:
21 addis 4, 3, i@dtprel@ha # R_PPC64_DTPREL16_HA
22 addi 4, 4, i@dtprel@l # R_PPC64_DTPREL16_LO
23
24 lis 5, i@dtprel@highesta # R_PPC64_DTPREL16_HIGHESTA
25 ori 5, 5, i@dtprel@highera # R_PPC64_DTPREL16_HIGHERA
26
27.section .rodata,"a",@progbits
28 .quad i@dtprel+32768
29
30.section .tbss,"awT",@nobits
31 .space 0x2a
32.globl i
33i:
34 .long 0
35 .size i, 4
deps/lld/test/ELF/ppc64-toc-addis-nop-lqsq.s+2-3
......@@ -6,10 +6,10 @@
66# RUN: ld.lld -shared %t2.o -o %t2.so
77
88# RUN: ld.lld %t2.so %p/Inputs/ppc64le-quadword-ldst.o -o %t
9# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
9# RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
1010
1111# 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
12# RUN: llvm-objdump -d %t | FileCheck --check-prefix=NoOpt %s
1313
1414# QuadInputRelocs: Relocation section '.rela.text'
1515# QuadInputRelocs: R_PPC64_TOC16_LO_DS 0000000000000000 quadLd
......@@ -70,4 +70,3 @@
7070# NoOpt-NEXT: addis 3, 2, 0
7171# NoOpt-NEXT: 82 7f 83 f8 <unknown>
7272# NoOpt-NEXT: blr
73
deps/lld/test/ELF/ppc64-toc-addis-nop.s+11-11
......@@ -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
66# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
77# RUN: ld.lld -shared %t2.o -o %t2.so
88#
99# RUN: ld.lld %t2.so %t.o -o %t
10# RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
10# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=Dis %s
1111#
1212# RUN: ld.lld --no-toc-optimize %t2.so %t.o -o %t
13# RUN: llvm-objdump -D %t | FileCheck --check-prefix=NoOpt %s
13# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=NoOpt %s
1414
1515# InputRelocs: Relocation section '.rela.text'
1616# InputRelocs: R_PPC64_TOC16_HA
......@@ -35,7 +35,7 @@ bytes:
3535 addis 4, 2, byteSt@toc@ha
3636 stb 3, byteSt@toc@l(4)
3737 blr
38# Dis-LABEL: bytes
38# Dis-LABEL: bytes:
3939# Dis-NEXT: addis
4040# Dis-NEXT: addi
4141# Dis-NEXT: nop
......@@ -44,7 +44,7 @@ bytes:
4444# Dis-NEXT: stb 3, 32625(2)
4545# Dis-NEXT: blr
4646
47# NoOpt-LABEL: bytes
47# NoOpt-LABEL: bytes:
4848# NoOpt-NEXT: addis
4949# NoOpt-NEXT: addi
5050# NoOpt-NEXT: addis 3, 2, 0
......@@ -69,7 +69,7 @@ halfs:
6969 addis 5, 2, halfSt@toc@ha
7070 sth 4, halfSt@toc@l(5)
7171 blr
72# Dis-LABEL: halfs
72# Dis-LABEL: halfs:
7373# Dis-NEXT: addis
7474# Dis-NEXT: addi
7575# Dis-NEXT: nop
......@@ -80,7 +80,7 @@ halfs:
8080# Dis-NEXT: sth 4, 32628(2)
8181# Dis-NEXT: blr
8282
83# NoOpt-LABEL: halfs
83# NoOpt-LABEL: halfs:
8484# NoOpt-NEXT: addis
8585# NoOpt-NEXT: addi
8686# NoOpt-NEXT: addis 3, 2, 0
......@@ -178,7 +178,7 @@ vec_dq:
178178 stxv 3, vecSt@toc@l(3)
179179 blr
180180
181# Dis-LABEL: vec_dq
181# Dis-LABEL: vec_dq:
182182# Dis-NEXT: addis
183183# Dis-NEXT: addi
184184# Dis-NEXT: nop
......@@ -187,7 +187,7 @@ vec_dq:
187187# Dis-NEXT: stxv 3, 32672(2)
188188# Dis-NEXT: blr
189189
190# NoOpt-LABEL: vec_dq
190# NoOpt-LABEL: vec_dq:
191191# NoOpt-NEXT: addis
192192# NoOpt-NEXT: addi
193193# NoOpt-NEXT: addis 3, 2, 0
......@@ -214,7 +214,7 @@ vec_ds:
214214 addis 3, 2, vecSt@toc@ha
215215 stxssp 3, vecSt@toc@l(3)
216216 blr
217# Dis-LABEL: vec_ds
217# Dis-LABEL: vec_ds:
218218# Dis-NEXT: addis
219219# Dis-NEXT: addi
220220# Dis-NEXT: nop
......@@ -227,7 +227,7 @@ vec_ds:
227227# Dis-NEXT: stxssp 3, 32672(2)
228228# Dis-NEXT: blr
229229
230# NoOpt-LABEL: vec_ds
230# NoOpt-LABEL: vec_ds:
231231# NoOpt-NEXT: addis
232232# NoOpt-NEXT: addi
233233# NoOpt-NEXT: addis 3, 2, 0
deps/lld/test/ELF/ppc64-toc-rel.s+25-30
......@@ -1,16 +1,18 @@
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-LE %s
5# RUN: ld.lld %t.o -o %t2
6# RUN: llvm-objdump -D %t2 | FileCheck %s
7# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-LE %s
4# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOCS-LE %s
5# RUN: ld.lld %t.o -o %t
6# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
7# RUN: llvm-readelf -x .got %t | FileCheck --check-prefix=HEX-LE %s
8# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=CHECK %s
89
910# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
10# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s
11# RUN: ld.lld %t.o -o %t2
12# RUN: llvm-objdump -D %t2 | FileCheck %s
13# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
11# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOCS-BE %s
12# RUN: ld.lld %t.o -o %t
13# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
14# RUN: llvm-readelf -x .got %t | FileCheck --check-prefix=HEX-BE %s
15# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=CHECK %s
1416
1517# Make sure we calculate the offset correctly for a toc-relative access to a
1618# global variable as described by the PPC64 Elf V2 abi.
......@@ -57,26 +59,19 @@ _start:
5759# RELOCS-BE: 0xA R_PPC64_TOC16_HA global_a 0x0
5860# RELOCS-BE: 0xE R_PPC64_TOC16_LO global_a 0x0
5961
60# Want to check _start for the values used to build the offset from the TOC base
61# to global_a. The .TOC. symbol is expected at address 0x10030000, and the
62# TOC base is address-of(.TOC.) + 0x8000. The expected offset is:
63# 0x10020000(global_a) - 0x10038000(Toc base) = -0x18000(Offset)
64# which gets materialized into r3 as ((-1 << 16) - 32768).
62# The .TOC. symbol represents the TOC base address: .got + 0x8000 = 0x10028000,
63# which is stored in the first entry of .got
64# NM: 0000000010028000 d .TOC.
65# NM: 0000000010030000 D global_a
66# HEX-LE: section '.got':
67# HEX-LE-NEXT: 0x10020000 00800210 00000000
68# HEX-BE: section '.got':
69# HEX-BE-NEXT: 0x10020000 00000000 10028000
6570
66# CHECK: Disassembly of section .text:
67# CHECK-NEXT: _start:
68# CHECK: 10010008: {{.*}} addis 3, 2, -1
69# CHECK-NEXT: 1001000c: {{.*}} addi 3, 3, -32768
70
71# CHECK: Disassembly of section .data:
72# CHECK-NEXT: global_a:
73# CHECK-NEXT: 10020000: {{.*}}
74
75# CHECK-LE: Disassembly of section .got:
76# CHECK-LE-NEXT: .got:
77# CHECK-LE-NEXT: 10030000: 00 80 03 10
78
79# CHECK-BE: Disassembly of section .got:
80# CHECK-BE-NEXT: .got:
81# CHECK-BE-NEXT: 10030000: 00 00 00 00
82# CHECK-BE-NEXT: 10030004: 10 03 80 00
71# r2 stores the TOC base address. To access global_a with r3, it
72# computes the address with TOC plus an offset.
73# The offset global_a - .TOC. = 0x10030000 - 0x10028000 = 0x8000
74# gets materialized as (1 << 16) - 32768.
75# CHECK: _start:
76# CHECK: 10010008: addis 3, 2, 1
77# CHECK-NEXT: 1001000c: addi 3, 3, -32768
deps/lld/test/ELF/ppc64-toc-relax-constants.s created+61
......@@ -0,0 +1,61 @@
1# REQUIRES: ppc
2
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unkown-linux %p/Inputs/ppc64-toc-relax-shared.s -o %t.o
4# RUN: ld.lld -shared %t.o -o %t.so
5# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
6# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-toc-relax.s -o %t2.o
7# RUN: llvm-readobj -r %t1.o | FileCheck --check-prefix=RELOCS %s
8# RUN: ld.lld %t1.o %t2.o %t.so -o %t
9# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SECTIONS %s
10# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
11# RUN: llvm-objdump -D %t | FileCheck %s
12
13# In most cases, .toc contains exclusively addresses relocated by R_PPC64_ADDR16.
14# Rarely .toc contain constants or variables.
15# Test we can still perform toc-indirect to toc-relative relaxation.
16
17# RELOCS: .rela.text {
18# RELOCS-NEXT: 0x0 R_PPC64_TOC16_HA .toc 0x0
19# RELOCS-NEXT: 0x4 R_PPC64_TOC16_LO_DS .toc 0x0
20# RELOCS-NEXT: 0x8 R_PPC64_TOC16_HA .toc 0x8
21# RELOCS-NEXT: 0xC R_PPC64_TOC16_LO_DS .toc 0x8
22# RELOCS-NEXT: 0x10 R_PPC64_TOC16_HA .toc 0x10
23# RELOCS-NEXT: 0x14 R_PPC64_TOC16_LO_DS .toc 0x10
24# RELOCS-NEXT: }
25
26# SECTIONS: .got PROGBITS 0000000010020090
27# SECTIONS: .toc PROGBITS 0000000010020090
28
29# NM: 0000000010030000 D default
30
31# .LCONST1 is .toc[0].
32# .LCONST1 - (.got+0x8000) = 0x10020090 - (0x10020090+0x8000) = -32768
33# CHECK: nop
34# CHECK: lwa 3, -32768(2)
35 addis 3, 2, .LCONST1@toc@ha
36 lwa 3, .LCONST1@toc@l(3)
37
38# .LCONST2 is .toc[1]
39# .LCONST2 - (.got+0x8000) = 0x10020098 - (0x10020090+0x8000) = -32760
40# CHECK: nop
41# CHECK: ld 4, -32760(2)
42 addis 4, 2, .LCONST2@toc@ha
43 ld 4, .LCONST2@toc@l(4)
44
45# .Ldefault is .toc[2]. `default` is not preemptable when producing an executable.
46# After toc-indirection to toc-relative relaxation, it is loaded using an
47# offset relative to r2.
48# CHECK: nop
49# CHECK: addi 5, 2, 32624
50# CHECK: lwa 5, 0(5)
51 addis 5, 2, .Ldefault@toc@ha
52 ld 5, .Ldefault@toc@l(5)
53 lwa 5, 0(5)
54
55.section .toc,"aw",@progbits
56.LCONST1:
57 .quad 11
58.LCONST2:
59 .quad 22
60.Ldefault:
61 .tc default[TC],default
deps/lld/test/ELF/ppc64-toc-relax-jumptable.s created+73
......@@ -0,0 +1,73 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readelf -S %t | FileCheck --check-prefixes=SECTIONS %s
5# RUN: llvm-readelf -x .toc %t | FileCheck --check-prefixes=HEX-LE %s
6# RUN: llvm-objdump -d %t | FileCheck --check-prefixes=CHECK %s
7
8# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
9# RUN: ld.lld %t.o -o %t
10# RUN: llvm-readelf -S %t | FileCheck --check-prefixes=SECTIONS %s
11# RUN: llvm-readelf -x .toc %t | FileCheck --check-prefixes=HEX-BE %s
12# RUN: llvm-objdump -d %t | FileCheck --check-prefixes=CHECK %s
13
14# .LJT is a local symbol (non-preemptable).
15# Test we can perform the toc-indirect to toc-relative relaxation.
16
17# SECTIONS: .rodata PROGBITS 00000000100001c8
18
19# HEX-LE: section '.toc':
20# HEX-LE-NEXT: 10020008 c8010010 00000000
21
22# HEX-BE: section '.toc':
23# HEX-BE-NEXT: 10020008 00000000 100001c8
24
25# CHECK-LABEL: _start
26# CHECK: clrldi 3, 3, 62
27# CHECK-NEXT: addis 4, 2, -2
28# CHECK-NEXT: addi 4, 4, -32312
29# CHECK-NEXT: sldi 3, 3, 2
30
31 .text
32 .global _start
33 .type _start, @function
34_start:
35.Lstart_gep:
36 addis 2, 12, .TOC.-.Lstart_gep@ha
37 addi 2, 2, .TOC.-.Lstart_gep@l
38.Lstart_lep:
39 .localentry _start, .Lstart_lep-.Lstart_gep
40 rldicl 3, 3, 0, 62
41 addis 4, 2, .LJTI_TE@toc@ha
42 ld 4, .LJTI_TE@toc@l(4)
43 sldi 3, 3, 2
44 lwax 3, 3, 4
45 add 3, 3, 4
46 mtctr 3
47 bctr
48
49.LBB1:
50 li 3, 0
51 blr
52.LBB2:
53 li 3, 10
54 blr
55.LBB3:
56 li 3, 55
57 blr
58.LBB4:
59 li 3, 255
60 blr
61
62 .section .rodata,"a",@progbits
63 .p2align 2
64.LJT:
65 .long .LBB1-.LJT
66 .long .LBB2-.LJT
67 .long .LBB3-.LJT
68 .long .LBB4-.LJT
69
70.section .toc,"aw",@progbits
71# TOC entry for the jumptable address.
72.LJTI_TE:
73 .tc .LJT[TC],.LJT
deps/lld/test/ELF/ppc64-toc-relax.s created+105
......@@ -0,0 +1,105 @@
1# REQUIRES: ppc
2# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-toc-relax-shared.s -o %t.o
3# RUN: ld.lld -shared %t.o -o %t.so
4# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
5# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-toc-relax.s -o %t2.o
6# RUN: llvm-readobj -r %t1.o | FileCheck --check-prefixes=RELOCS-LE,RELOCS %s
7# RUN: ld.lld %t1.o %t2.o %t.so -o %t
8# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=COMMON,EXE %s
9
10# RUN: ld.lld -shared %t1.o %t2.o %t.so -o %t2.so
11# RUN: llvm-objdump -d --no-show-raw-insn %t2.so | FileCheck --check-prefixes=COMMON,SHARED %s
12
13# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-toc-relax-shared.s -o %t.o
14# RUN: ld.lld -shared %t.o -o %t.so
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-toc-relax.s -o %t2.o
17# RUN: llvm-readobj -r %t1.o | FileCheck --check-prefixes=RELOCS-BE,RELOCS %s
18# RUN: ld.lld %t1.o %t2.o %t.so -o %t
19# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=COMMON,EXE %s
20
21# RUN: ld.lld -shared %t1.o %t2.o %t.so -o %t2.so
22# RUN: llvm-objdump -d --no-show-raw-insn %t2.so | FileCheck --check-prefixes=COMMON,SHARED %s
23
24# RELOCS-LE: .rela.text {
25# RELOCS-LE-NEXT: 0x0 R_PPC64_TOC16_HA .toc 0x0
26# RELOCS-LE-NEXT: 0x4 R_PPC64_TOC16_LO_DS .toc 0x0
27# RELOCS-LE-NEXT: 0xC R_PPC64_TOC16_HA .toc 0x8
28# RELOCS-LE-NEXT: 0x10 R_PPC64_TOC16_LO_DS .toc 0x8
29# RELOCS-LE-NEXT: 0x18 R_PPC64_TOC16_HA .toc 0x10
30# RELOCS-LE-NEXT: 0x1C R_PPC64_TOC16_LO_DS .toc 0x10
31# RELOCS-LE-NEXT: 0x24 R_PPC64_TOC16_HA .toc 0x18
32# RELOCS-LE-NEXT: 0x28 R_PPC64_TOC16_LO_DS .toc 0x18
33# RELOCS-LE-NEXT: }
34
35# RELOCS-BE: .rela.text {
36# RELOCS-BE-NEXT: 0x2 R_PPC64_TOC16_HA .toc 0x0
37# RELOCS-BE-NEXT: 0x6 R_PPC64_TOC16_LO_DS .toc 0x0
38# RELOCS-BE-NEXT: 0xE R_PPC64_TOC16_HA .toc 0x8
39# RELOCS-BE-NEXT: 0x12 R_PPC64_TOC16_LO_DS .toc 0x8
40# RELOCS-BE-NEXT: 0x1A R_PPC64_TOC16_HA .toc 0x10
41# RELOCS-BE-NEXT: 0x1E R_PPC64_TOC16_LO_DS .toc 0x10
42# RELOCS-BE-NEXT: 0x26 R_PPC64_TOC16_HA .toc 0x18
43# RELOCS-BE-NEXT: 0x2A R_PPC64_TOC16_LO_DS .toc 0x18
44# RELOCS-BE-NEXT: }
45
46# RELOCS: .rela.toc {
47# RELOCS-NEXT: 0x0 R_PPC64_ADDR64 hidden 0x0
48# RELOCS-NEXT: 0x8 R_PPC64_ADDR64 hidden2 0x0
49# RELOCS-NEXT: 0x10 R_PPC64_ADDR64 shared 0x0
50# RELOCS-NEXT: 0x18 R_PPC64_ADDR64 default 0x0
51# RELOCS-NEXT: }
52
53# NM-DAG: 0000000010030000 D default
54# NM-DAG: 0000000010030000 d hidden
55# NM-DAG: 0000000010040000 d hidden2
56
57# 'hidden' is non-preemptable. It is relaxed.
58# address(hidden) - (.got+0x8000) = 0x10030000 - (0x100200c0+0x8000) = 32576
59# COMMON: nop
60# COMMON: addi 3, 2, 32576
61# COMMON: lwa 3, 0(3)
62 addis 3, 2, .Lhidden@toc@ha
63 ld 3, .Lhidden@toc@l(3)
64 lwa 3, 0(3)
65
66# address(hidden2) - (.got+0x8000) = 0x10040000 - (0x100200c0+0x8000) = (1<<16)+32576
67# COMMON: addis 3, 2, 1
68# COMMON: addi 3, 3, 32576
69# COMMON: lwa 3, 0(3)
70 addis 3, 2, .Lhidden2@toc@ha
71 ld 3, .Lhidden2@toc@l(3)
72 lwa 3, 0(3)
73
74# 'shared' is not defined in an object file. Its definition is determined at
75# runtime by the dynamic linker, so the extra indirection cannot be relaxed.
76# The first addis can still be relaxed to nop, though.
77# COMMON: nop
78# COMMON: ld 4, -32752(2)
79# COMMON: lwa 4, 0(4)
80 addis 4, 2, .Lshared@toc@ha
81 ld 4, .Lshared@toc@l(4)
82 lwa 4, 0(4)
83
84# 'default' has default visibility. It is non-preemptable when producing an executable.
85# address(default) - (.got+0x8000) = 0x10030000 - (0x100200c0+0x8000) = 32576
86# EXE: nop
87# EXE: addi 5, 2, 32576
88# EXE: lwa 5, 0(5)
89
90# SHARED: nop
91# SHARED: ld 5, -32744(2)
92# SHARED: lwa 5, 0(5)
93 addis 5, 2, .Ldefault@toc@ha
94 ld 5, .Ldefault@toc@l(5)
95 lwa 5, 0(5)
96
97.section .toc,"aw",@progbits
98.Lhidden:
99 .tc hidden[TC], hidden
100.Lhidden2:
101 .tc hidden2[TC], hidden2
102.Lshared:
103 .tc shared[TC], shared
104.Ldefault:
105 .tc default[TC], default
deps/lld/test/ELF/ppc64-toc-restore-recursive-call.s+8-9
......@@ -1,8 +1,8 @@
11# REQUIRES: ppc
22
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
3# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
4# RUN: ld.lld -shared %t.o -o %t.so
5# RUN: llvm-objdump -d --no-show-raw-insn -r %t.so | FileCheck %s
66
77# For a recursive call that is interposable the linker calls the plt-stub rather
88# then calling the function directly. Since the call is through a plt stub and
......@@ -14,12 +14,11 @@
1414# for recursive calls as well as keeps the logic for recursive calls consistent
1515# with non-recursive calls.
1616
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)
17# CHECK-LABEL: 0000000000010000 recursive_func:
18# CHECK: 10028: bl .+32
19# CHECK-NEXT: ld 2, 24(1)
20
21# CHECK-LABEL: 0000000000010048 __plt_recursive_func:
2322
2423 .abiversion 2
2524 .section ".text"
deps/lld/test/ELF/ppc64-toc-restore.s+17-24
......@@ -5,14 +5,14 @@
55// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
66// RUN: ld.lld -shared %t2.o -o %t2.so
77// RUN: ld.lld %t.o %t2.so %t3.o -o %t
8// RUN: llvm-objdump -d %t | FileCheck %s
8// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
99
1010// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
1111// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
1212// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
1313// RUN: ld.lld -shared %t2.o -o %t2.so
1414// RUN: ld.lld %t.o %t2.so %t3.o -o %t
15// RUN: llvm-objdump -d %t | FileCheck %s
15// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
1616
1717 .text
1818 .abiversion 2
......@@ -28,16 +28,11 @@ _start:
2828 bl foo
2929 nop
3030 bl bar_local
31
32
33// CHECK: Disassembly of section .text:
34// CHECK: _start:
35// CHECK: 1001001c: {{.*}} bl .+67108836
36// CHECK-NOT: 10010020: {{.*}} nop
37// CHECK: 10010020: {{.*}} ld 2, 24(1)
38// CHECK: 10010024: {{.*}} bl .+67108848
39// CHECK-NOT: 10010028: {{.*}} nop
40// CHECK-NOT: 10010028: {{.*}} ld 2, 24(1)
31// CHECK-LABEL: _start:
32// CHECK-NEXT: 10010008: bl .+64
33// CHECK-NEXT: 1001000c: ld 2, 24(1)
34// CHECK-NEXT: 10010010: bl .-16
35// CHECK-EMPTY:
4136
4237# Calling a function in another object file which will have same
4338# TOC base does not need a nop. If nop present, do not rewrite to
......@@ -47,26 +42,24 @@ _diff_object:
4742 bl foo_not_shared
4843 bl foo_not_shared
4944 nop
50
51// CHECK: _diff_object:
52// CHECK-NEXT: 10010028: {{.*}} bl .+24
53// CHECK-NEXT: 1001002c: {{.*}} bl .+20
54// CHECK-NEXT: 10010030: {{.*}} nop
45// CHECK-LABEL: _diff_object:
46// CHECK-NEXT: 10010014: bl .+28
47// CHECK-NEXT: 10010018: bl .+24
48// CHECK-NEXT: 1001001c: nop
5549
5650# Branching to a local function does not need a nop
5751.global noretbranch
5852noretbranch:
5953 b bar_local
60// CHECK: noretbranch:
61// CHECK: 10010034: {{.*}} b .+67108832
62// CHECK-NOT: 10010038: {{.*}} nop
63// CHECK-NOT: 1001003c: {{.*}} ld 2, 24(1)
54// CHECK-LABEL: noretbranch:
55// CHECK: 10010020: b .+67108832
56// CHECK-EMPTY:
6457
6558// This should come last to check the end-of-buffer condition.
6659.global last
6760last:
6861 bl foo
6962 nop
70// CHECK: last:
71// CHECK: 10010038: {{.*}} bl .+67108808
72// CHECK-NEXT: 1001003c: {{.*}} ld 2, 24(1)
63// CHECK-LABEL: last:
64// CHECK-NEXT: 10010024: bl .+36
65// CHECK-NEXT: 10010028: ld 2, 24(1)
deps/lld/test/ELF/ppc64-weak-undef-call-shared.s+2-2
......@@ -2,11 +2,11 @@
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-readobj -t -r -dyn-symbols %t.so | FileCheck %s
5# RUN: llvm-readobj --symbols -r --dyn-syms %t.so | FileCheck %s
66
77# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
88# RUN: ld.lld -shared %t.o -o %t.so
9# RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
9# RUN: llvm-readobj --symbols -r --dyn-syms %t.so | FileCheck %s
1010
1111.section ".toc","aw"
1212.quad weakfunc
deps/lld/test/ELF/ppc64-weak-undef-call.s+6-5
......@@ -2,13 +2,14 @@
22
33# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
44# RUN: ld.lld %t -o %t2
5# RUN: llvm-objdump -d %t2 | FileCheck %s
5# RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck %s
66
77# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
88# RUN: ld.lld %t -o %t2
9# RUN: llvm-objdump -d %t2 | FileCheck %s
9# RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck %s
1010
1111# CHECK: Disassembly of section .text:
12# CHECK-EMPTY:
1213
1314.text
1415.global _start
......@@ -23,6 +24,6 @@ _start:
2324# be unreachable. But, we should link successfully. We should not, however,
2425# generate a .plt entry (this would be wasted space). For now, we do nothing
2526# (leaving the zero relative offset present in the input).
26# CHECK: 10010000: {{.*}} bl .+0
27# CHECK: 10010004: {{.*}} nop
28# CHECK: 10010008: {{.*}} blr
27# CHECK: 10010000: bl .+0
28# CHECK: 10010004: nop
29# CHECK: 10010008: blr
deps/lld/test/ELF/pr34660.s+3-2
......@@ -13,11 +13,12 @@
1313# correct symbol.
1414
1515# DISASM: Disassembly of section .text:
16# DISASM-EMPTY:
1617# DISASM-NEXT: $x.0:
17# DISASM-NEXT: 10000: 28 00 08 58 ldr x8, #65540
18# DISASM-NEXT: 10000: 28 00 10 58 ldr x8, #131076
1819
1920# SYM: Symbol table '.symtab'
20# SYM: 0000000000020004 0 NOTYPE LOCAL DEFAULT 5 patatino
21# SYM: 0000000000030004 0 NOTYPE LOCAL DEFAULT 6 patatino
2122
2223 ldr x8, patatino
2324 .data
deps/lld/test/ELF/pr34872.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc %p/Inputs/undefined-error.s -filetype=obj \
44# RUN: -triple=x86_64-pc-linux -o %t2.o
55# RUN: ld.lld -shared %t2.o -o %t2.so
6# RUN: not ld.lld %t2.so %t.o -o /dev/null 2>&1 | FileCheck %s
6# RUN: not ld.lld --allow-shlib-undefined %t2.so %t.o -o /dev/null 2>&1 | FileCheck %s
77
88# CHECK: undefined symbol: fmod
99# Check we're not emitting other diagnostics for this symbol.
deps/lld/test/ELF/pr36475.s+1-1
......@@ -10,7 +10,7 @@
1010# RUN: echo " .got.plt : { BYTE(42); *(.got); } : ph_data" >> %t.script
1111# RUN: echo "}" >> %t.script
1212# RUN: ld.lld -T %t.script %t.o -o %t.elf
13# RUN: llvm-readobj -l -elf-output-style=GNU %t.elf | FileCheck %s
13# RUN: llvm-readelf -l %t.elf | FileCheck %s
1414
1515# CHECK: Section to Segment mapping:
1616# CHECK-NEXT: Segment Sections...
deps/lld/test/ELF/pre_init_fini_array.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2
44// RUN: ld.lld %t2 -o %t2.so -shared
55// RUN: ld.lld %t %t2.so -o %t2
6// RUN: llvm-readobj -r -symbols -sections -dynamic-table %t2 | FileCheck %s
6// RUN: llvm-readobj -r --symbols --sections --dynamic-table %t2 | FileCheck %s
77// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
88
99.globl _start
deps/lld/test/ELF/pre_init_fini_array_missing.s+2
......@@ -20,6 +20,7 @@ _start:
2020// ...
2121
2222// CHECK: Disassembly of section .text:
23// CHECK-EMPTY:
2324// CHECK-NEXT: _start:
2425// CHECK-NEXT: 201000: e8 fb ff ff ff callq -5
2526// CHECK-NEXT: 201005: e8 f6 ff ff ff callq -10
......@@ -31,6 +32,7 @@ _start:
3132// In position-independent binaries, they resolve to .text too.
3233
3334// PIE: Disassembly of section .text:
35// PIE-EMPTY:
3436// PIE-NEXT: _start:
3537// PIE-NEXT: 1000: e8 fb ff ff ff callq -5
3638// PIE-NEXT: 1005: e8 f6 ff ff ff callq -10
deps/lld/test/ELF/progname.s+3-3
......@@ -4,18 +4,18 @@
44// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o
55// RUN: ld.lld -shared %t2.o -o %t2.so
66// RUN: ld.lld -o %t %t.o %t2.so
7// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
7// RUN: llvm-readobj --dyn-syms %t | FileCheck %s
88
99// RUN: echo "VER_1 { global: bar; };" > %t.script
1010// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
1111// RUN: %p/Inputs/progname-ver.s -o %t-ver.o
1212// RUN: ld.lld -shared -o %t.so -version-script %t.script %t-ver.o
1313// RUN: ld.lld -o %t %t.o %t.so
14// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
14// RUN: llvm-readobj --dyn-syms %t | FileCheck %s
1515
1616// RUN: echo "{ _start; };" > %t.dynlist
1717// RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so
18// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
18// RUN: llvm-readobj --dyn-syms %t | FileCheck %s
1919
2020// CHECK: Name: __progname
2121// CHECK-NEXT: Value: 0x201000
deps/lld/test/ELF/program-header-layout.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: ld.lld %t -o %t2
4# RUN: llvm-readobj -sections -program-headers %t2 | FileCheck %s
4# RUN: llvm-readobj --sections -l %t2 | FileCheck %s
55
66# Check that different output sections with the same flags are merged into a
77# single Read/Write PT_LOAD.
deps/lld/test/ELF/protected-shared.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/protected-shared.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld %t.o %t2.so -o %t
6// RUN: llvm-readobj -t --dyn-symbols %t | FileCheck %s
6// RUN: llvm-readobj --symbols --dyn-symbols %t | FileCheck %s
77
88 .global _start
99_start:
deps/lld/test/ELF/push-state.s+2-2
......@@ -19,11 +19,11 @@
1919// RUN: ld.lld -shared %t3.o -soname libfoo -o %t.so
2020
2121// RUN: ld.lld -o %t.exe -push-state -as-needed %t.so %t1.o
22// RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=AS-NEEDED %s
22// RUN: llvm-readobj --dynamic-table %t.exe | FileCheck -check-prefix=AS-NEEDED %s
2323// AS-NEEDED-NOT: NEEDED Shared library: [libfoo]
2424
2525// RUN: ld.lld -o %t.exe -push-state -as-needed -pop-state %t.so %t1.o
26// RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=NO-AS-NEEDED %s
26// RUN: llvm-readobj --dynamic-table %t.exe | FileCheck -check-prefix=NO-AS-NEEDED %s
2727// NO-AS-NEEDED: NEEDED Shared library: [libfoo]
2828
2929
deps/lld/test/ELF/rel-addend-with-rela-input.s+2-2
......@@ -3,7 +3,7 @@
33# uses Elf_Rela
44
55# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t-rela.o
6# RUN: llvm-readobj -h -s -section-data -relocations %t-rela.o | FileCheck -check-prefix INPUT-RELA %s
6# RUN: llvm-readobj -h -S --section-data -r %t-rela.o | FileCheck -check-prefix INPUT-RELA %s
77# INPUT-RELA: ElfHeader {
88# INPUT-RELA: Class: 64-bit
99# INPUT-RELA: DataEncoding: BigEndian
......@@ -21,7 +21,7 @@
2121# Previously the addend to the dynamic relocation in the .data section was not copied if
2222# the input file used RELA and the output uses REL. Check that it works now:
2323# RUN: ld.lld -shared -o %t.so %t-rela.o -verbose
24# RUN: llvm-readobj -h -s -section-data -relocations %t.so | FileCheck -check-prefix RELA-TO-REL %s
24# RUN: llvm-readobj -h -S --section-data -r %t.so | FileCheck -check-prefix RELA-TO-REL %s
2525# RELA-TO-REL: ElfHeader {
2626# RELA-TO-REL: Class: 64-bit
2727# RELA-TO-REL: DataEncoding: BigEndian
deps/lld/test/ELF/rel-offset.s+2-2
......@@ -10,6 +10,6 @@
1010 .quad foo
1111
1212// CHECK: Section ({{.*}}) .rela.dyn {
13// CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0
14// CHECK-NEXT: 0x1008 R_X86_64_64 foo 0x0
13// CHECK-NEXT: 0x2000 R_X86_64_64 foo 0x0
14// CHECK-NEXT: 0x2008 R_X86_64_64 foo 0x0
1515// CHECK-NEXT: }
deps/lld/test/ELF/relative-dynamic-reloc-pie.s+4-4
......@@ -1,14 +1,14 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: ld.lld -pie %t.o -o %t.pie
4# RUN: llvm-readobj -r -dyn-symbols %t.pie | FileCheck %s
4# RUN: llvm-readobj -r --dyn-syms %t.pie | FileCheck %s
55
66## Test that we create R_X86_64_RELATIVE relocations with -pie.
77# CHECK: Relocations [
88# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
9# CHECK-NEXT: 0x2000 R_X86_64_RELATIVE - 0x2000
10# CHECK-NEXT: 0x2008 R_X86_64_RELATIVE - 0x2008
11# CHECK-NEXT: 0x2010 R_X86_64_RELATIVE - 0x2009
9# CHECK-NEXT: 0x3000 R_X86_64_RELATIVE - 0x3000
10# CHECK-NEXT: 0x3008 R_X86_64_RELATIVE - 0x3008
11# CHECK-NEXT: 0x3010 R_X86_64_RELATIVE - 0x3009
1212# CHECK-NEXT: }
1313# CHECK-NEXT: ]
1414
deps/lld/test/ELF/relative-dynamic-reloc-ppc64.s deleted-71
......@@ -1,71 +0,0 @@
1// REQUIRES: ppc
2// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
3// RUN: ld.lld -shared %t.o -o %t.so
4// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
5
6// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
7// RUN: ld.lld -shared %t.o -o %t.so
8// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
9
10// Test that we create R_PPC64_RELATIVE relocations but don't put any
11// symbols in the dynamic symbol table.
12
13// CHECK: Relocations [
14// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
15// CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_PPC64_RELATIVE - 0x[[FOO_ADDR]]
16// CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_PPC64_RELATIVE - 0x[[BAR_ADDR]]
17// CHECK-NEXT: 0x10010 R_PPC64_RELATIVE - 0x10009
18// CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[ZED_ADDR:.*]]
19// CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[FOO_ADDR]]
20// CHECK-NEXT: 0x10028 R_PPC64_ADDR64 external 0x0
21// CHECK-NEXT: }
22// CHECK-NEXT: ]
23
24// CHECK: Symbols [
25// CHECK: Name: foo
26// CHECK-NEXT: Value: 0x[[FOO_ADDR]]
27// CHECK: Name: bar
28// CHECK-NEXT: Value: 0x[[BAR_ADDR]]
29// CHECK: Name: zed
30// CHECK-NEXT: Value: 0x[[ZED_ADDR]]
31// CHECK: ]
32
33// CHECK: DynamicSymbols [
34// CHECK-NEXT: Symbol {
35// CHECK-NEXT: Name:
36// CHECK-NEXT: Value: 0x0
37// CHECK-NEXT: Size: 0
38// CHECK-NEXT: Binding: Local
39// CHECK-NEXT: Type: None
40// CHECK-NEXT: Other: 0
41// CHECK-NEXT: Section: Undefined
42// CHECK-NEXT: }
43// CHECK-NEXT: Symbol {
44// CHECK-NEXT: Name: external
45// CHECK-NEXT: Value: 0x0
46// CHECK-NEXT: Size: 0
47// CHECK-NEXT: Binding: Global
48// CHECK-NEXT: Type: None
49// CHECK-NEXT: Other: 0
50// CHECK-NEXT: Section: Undefined
51// CHECK-NEXT: }
52// CHECK-NEXT: ]
53
54 .data
55foo:
56 .quad foo
57
58 .hidden bar
59 .global bar
60bar:
61 .quad bar
62 .quad bar + 1
63
64 .hidden zed
65 .comm zed,1
66 .quad zed
67
68 .section abc,"aw"
69 .quad foo
70
71 .quad external
deps/lld/test/ELF/relative-dynamic-reloc.s+3-3
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33// RUN: ld.lld -shared %t.o -o %t.so
4// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
4// RUN: llvm-readobj --symbols -r --dyn-syms %t.so | FileCheck %s
55
66// Test that we create R_X86_64_RELATIVE relocations but don't put any
77// symbols in the dynamic symbol table.
......@@ -10,10 +10,10 @@
1010// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
1111// CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_X86_64_RELATIVE - 0x[[FOO_ADDR]]
1212// CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_X86_64_RELATIVE - 0x[[BAR_ADDR]]
13// CHECK-NEXT: 0x1010 R_X86_64_RELATIVE - 0x1009
13// CHECK-NEXT: 0x2010 R_X86_64_RELATIVE - 0x2009
1414// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[ZED_ADDR:.*]]
1515// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[FOO_ADDR]]
16// CHECK-NEXT: 0x1028 R_X86_64_64 external 0x0
16// CHECK-NEXT: 0x2028 R_X86_64_64 external 0x0
1717// CHECK-NEXT: }
1818// CHECK-NEXT: ]
1919
deps/lld/test/ELF/relocatable-bss.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
33# RUN: ld.lld -r %t1.o -o %t
4# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
4# RUN: llvm-readobj --file-headers --sections -l --symbols -r %t | FileCheck %s
55
66## We check here that .bss does not occupy the space in file.
77## If it would, the SectionHeaderOffset would have offset about 5 megabytes.
deps/lld/test/ELF/relocatable-comdat-multiple.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/relocatable-comdat-multiple.s -o %t2.o
44# RUN: ld.lld -r %t.o %t2.o -o %t
5# RUN: llvm-readobj -elf-section-groups %t | FileCheck %s
5# RUN: llvm-readobj --elf-section-groups %t | FileCheck %s
66
77# CHECK: Groups {
88# CHECK-NEXT: Group {
deps/lld/test/ELF/relocatable-comdat.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 -r %t.o %t.o -o %t
4# RUN: llvm-readobj -elf-section-groups -sections %t | FileCheck %s
4# RUN: llvm-readobj --elf-section-groups --sections %t | FileCheck %s
55
66# CHECK: Name: .text.bar
77# CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/relocatable-comdat2.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 -r %t.o -o %t
4# RUN: llvm-readobj -elf-section-groups -s %t | FileCheck %s
4# RUN: llvm-readobj --elf-section-groups -S %t | FileCheck %s
55
66## Check .foo was not merged.
77# CHECK: Sections [
deps/lld/test/ELF/relocatable-comment.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
33# RUN: ld.lld -r %t1.o -o %t
4# RUN: llvm-readobj -s -section-data %t | FileCheck %s
4# RUN: llvm-readobj -S --section-data %t | FileCheck %s
55
66# CHECK: Name: .comment
77# CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/relocatable-common.s+6-6
......@@ -1,17 +1,17 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
33# RUN: ld.lld -r %t1.o -o %t
4# RUN: llvm-readobj -symbols -r %t | FileCheck %s
4# RUN: llvm-readobj --symbols -r %t | FileCheck %s
55# RUN: ld.lld -r --no-define-common %t1.o -o %t
6# RUN: llvm-readobj -symbols -r %t | FileCheck %s
6# RUN: llvm-readobj --symbols -r %t | FileCheck %s
77# RUN: ld.lld -r --define-common %t1.o -o %t
8# RUN: llvm-readobj -symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
8# RUN: llvm-readobj --symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
99# RUN: ld.lld -r -d %t1.o -o %t
10# RUN: llvm-readobj -symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
10# RUN: llvm-readobj --symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
1111# RUN: ld.lld -r -dc %t1.o -o %t
12# RUN: llvm-readobj -symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
12# RUN: llvm-readobj --symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
1313# RUN: ld.lld -r -dp %t1.o -o %t
14# RUN: llvm-readobj -symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
14# RUN: llvm-readobj --symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
1515
1616# CHECK: Symbol {
1717# CHECK: Name: common
deps/lld/test/ELF/relocatable-compressed-input.s+2-2
......@@ -1,11 +1,11 @@
11# REQUIRES: x86, zlib
22
33# RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
4# RUN: llvm-readobj -sections %t1 | FileCheck -check-prefix=GNU %s
4# RUN: llvm-readobj --sections %t1 | FileCheck -check-prefix=GNU %s
55# GNU: Name: .zdebug_str
66
77# RUN: ld.lld %t1 -o %t2 -r
8# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s
8# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s
99
1010## Check we uncompress section and remove ".z" prefix specific for zlib-gnu compression.
1111# CHECK: Section {
deps/lld/test/ELF/relocatable-eh-frame-hdr.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 --eh-frame-hdr -r %t.o -o %t
4# RUN: llvm-readobj -s %t | FileCheck %s
4# RUN: llvm-readobj -S %t | FileCheck %s
55
66# CHECK: Sections [
77# CHECK-NOT: Name: .eh_frame_hdr
deps/lld/test/ELF/relocatable-eh-frame.s deleted-19
......@@ -1,19 +0,0 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld -r %t.o %t.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck %s
5# RUN: ld.lld %t -o %t.so -shared
6# RUN: llvm-objdump -h %t.so | FileCheck --check-prefix=DSO %s
7
8# DSO: .eh_frame 00000034
9
10# CHECK: Relocations [
11# CHECK-NEXT: Section ({{.*}}) .rela.eh_frame {
12# CHECK-NEXT: 0x20 R_X86_64_PC32 .foo 0x0
13# CHECK-NEXT: 0x50 R_X86_64_NONE - 0x0
14# CHECK-NEXT: }
15# CHECK-NEXT: ]
16
17.section .foo,"aG",@progbits,bar,comdat
18.cfi_startproc
19.cfi_endproc
deps/lld/test/ELF/relocatable-ehframe.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/relocatable-ehframe.s -o %t2.o
44# RUN: ld.lld -r %t1.o %t2.o -o %t
5# RUN: llvm-readobj -r -s -section-data %t | FileCheck %s
5# RUN: llvm-readobj -r -S --section-data %t | FileCheck %s
66
77# CHECK: Name: .strtab
88# CHECK-NEXT: Type: SHT_STRTAB
deps/lld/test/ELF/relocatable-empty-archive.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: rm -f %t.a
33# RUN: llvm-ar rc %t.a
44# RUN: ld.lld -m elf_x86_64 %t.a -o %t -r
5# RUN: llvm-readobj -file-headers %t | FileCheck %s
5# RUN: llvm-readobj --file-headers %t | FileCheck %s
66
77# CHECK: Format: ELF64-x86-64
88# CHECK: Arch: x86_64
deps/lld/test/ELF/relocatable-many-sections.s+8-8
......@@ -7,25 +7,25 @@
77
88## Check we emit a valid ELF header when
99## sections amount is greater than SHN_LORESERVE.
10# RUN: llvm-readobj -file-headers %t | FileCheck %s --check-prefix=HDR
10# RUN: llvm-readobj --file-headers %t | FileCheck %s --check-prefix=HDR
1111# HDR: ElfHeader {
1212# HDR: SectionHeaderCount: 0 (65544)
1313# HDR-NEXT: StringTableSectionIndex: 65535 (65542)
1414
1515## Check that:
1616## 1) 65541 is the index of .shstrtab section.
17## 2) .symtab_shndxr is linked with .symtab.
18## 3) .symtab_shndxr entry size and alignment == 4.
19## 4) .symtab_shndxr has size equal to
20## (sizeof(.symtab) / entsize(.symtab)) * entsize(.symtab_shndxr) = 0x4 * 0x180048 / 0x18 == 0x04000c
17## 2) .symtab_shndx is linked with .symtab.
18## 3) .symtab_shndx entry size and alignment == 4.
19## 4) .symtab_shndx has size equal to
20## (sizeof(.symtab) / entsize(.symtab)) * entsize(.symtab_shndx) = 0x4 * 0x180078 / 0x18 == 0x040014
2121
2222# RUN: llvm-readelf -sections -symbols %t | FileCheck %s
2323# [Nr] Name Type Address Off Size ES Flg Lk Inf Al
2424# CHECK: [65539] .note.GNU-stack PROGBITS 0000000000000000 000040 000000 00 0 0 1
2525# 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
26# CHECK: [65541] .symtab_shndx SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04 65540 0 4
27# CHECK: [65542] .shstrtab STRTAB 0000000000000000 1c00cc 0f0044 00 0 0 1
28# CHECK: [65543] .strtab STRTAB 0000000000000000 2b0110 00000c 00 0 0 1
2929
3030# 5) Check we are able to represent symbol foo with section (.bar) index > 0xFF00 (SHN_LORESERVE).
3131# CHECK: GLOBAL DEFAULT 65538 foo
deps/lld/test/ELF/relocatable-rel-iplt.s+2-2
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=i686-- %s -o %t1.o
33# RUN: ld.lld -r %t1.o -o %t2.o
4# RUN: llvm-readobj -t %t2.o | FileCheck %s
4# RUN: llvm-readobj --symbols %t2.o | FileCheck %s
55
66// CHECK: Symbols [
77// CHECK-NEXT: Symbol {
......@@ -14,7 +14,7 @@
1414// CHECK-NEXT: Section: Undefined (0x0)
1515// CHECK-NEXT: }
1616// CHECK-NEXT: Symbol {
17// CHECK-NEXT: Name: (0)
17// CHECK-NEXT: Name: .text (0)
1818// CHECK-NEXT: Value: 0x0
1919// CHECK-NEXT: Size: 0
2020// CHECK-NEXT: Binding: Local (0x0)
deps/lld/test/ELF/relocatable-script.s+1-1
......@@ -2,6 +2,6 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t1.o %s
33# RUN: echo "SECTIONS { .foo : { BYTE(0x0) } }" > %t.script
44# RUN: ld.lld -r %t1.o -script %t.script -o %t2.o
5# RUN: llvm-readobj -sections %t2.o | FileCheck %s
5# RUN: llvm-readobj --sections %t2.o | FileCheck %s
66
77# CHECK: Name: .foo
deps/lld/test/ELF/relocatable-section-symbol.s+1-1
......@@ -13,7 +13,7 @@
1313
1414# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
1515# RUN: ld.lld -r -o %t %t.o %t.o
16# RUN: llvm-readobj -r -s -section-data %t | FileCheck --check-prefix=REL %s
16# RUN: llvm-readobj -r -S --section-data %t | FileCheck --check-prefix=REL %s
1717
1818
1919# REL: Section {
deps/lld/test/ELF/relocatable-symbol-name.s+2-2
......@@ -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 -r %t.o -o %t
4# RUN: llvm-readobj -t %t | FileCheck %s
4# RUN: llvm-readobj --symbols %t | FileCheck %s
55
66# Test that the section symbol has st_name equal to zero. GNU objdump
77# requires this to print relocations against the section.
......@@ -17,7 +17,7 @@
1717# CHECK-NEXT: Section:
1818# CHECK-NEXT: }
1919# CHECK-NEXT: Symbol {
20# CHECK-NEXT: Name: (0)
20# CHECK-NEXT: Name: .text (0)
2121# CHECK-NEXT: Value:
2222# CHECK-NEXT: Size:
2323# CHECK-NEXT: Binding:
deps/lld/test/ELF/relocatable-symbols.s+5-1
......@@ -3,7 +3,7 @@
33# RUN: ld.lld -r %t -o %tout
44# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
55# RUN: llvm-readobj -r %t | FileCheck -check-prefix=RELOC %s
6# RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s
6# RUN: llvm-readobj --symbols -r %tout | FileCheck -check-prefix=SYMBOL %s
77
88# DISASM: _start:
99# DISASM-NEXT: 0: {{.*}} callq 0
......@@ -18,12 +18,16 @@
1818# DISASM-NEXT: 2d: {{.*}} callq 0
1919# DISASM-NEXT: 32: {{.*}} callq 0
2020# DISASM-NEXT: 37: {{.*}} callq 0
21# DISASM-EMPTY:
2122# DISASM-NEXT: Disassembly of section foo:
23# DISASM-EMPTY:
2224# DISASM-NEXT: foo:
2325# DISASM-NEXT: 0: 90 nop
2426# DISASM-NEXT: 1: 90 nop
2527# DISASM-NEXT: 2: 90 nop
28# DISASM-EMPTY:
2629# DISASM-NEXT: Disassembly of section bar:
30# DISASM-EMPTY:
2731# DISASM-NEXT: bar:
2832# DISASM-NEXT: 0: 90 nop
2933# DISASM-NEXT: 1: 90 nop
deps/lld/test/ELF/relocatable-visibility.s+1-1
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: ld.lld -r %t.o -o %t1
4# RUN: llvm-readobj -t %t1 | FileCheck --check-prefix=RELOCATABLE %s
4# RUN: llvm-readobj --symbols %t1 | FileCheck --check-prefix=RELOCATABLE %s
55
66# RELOCATABLE: Name: foo
77# RELOCATABLE-NEXT: Value: 0x0
deps/lld/test/ELF/relocatable.s+5-4
......@@ -3,18 +3,18 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable.s -o %t2.o
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
6# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
6# RUN: llvm-readobj --file-headers --sections -l --symbols -r %t | FileCheck %s
77# RUN: llvm-objdump -section-headers %t | FileCheck -check-prefix=SECTION %s
88# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
99
1010## Test --relocatable alias
1111# RUN: ld.lld --relocatable %t1.o %t2.o %t3.o -o %t
12# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
12# RUN: llvm-readobj --file-headers --sections -l --symbols -r %t | FileCheck %s
1313# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
1414
1515## Verify that we can use our relocation output as input to produce executable
1616# RUN: ld.lld -e main %t -o %texec
17# RUN: llvm-readobj -file-headers %texec | FileCheck -check-prefix=CHECKEXE %s
17# RUN: llvm-readobj --file-headers %texec | FileCheck -check-prefix=CHECKEXE %s
1818
1919# CHECK: ElfHeader {
2020# CHECK-NEXT: Ident {
......@@ -53,7 +53,7 @@
5353# CHECK-NEXT: }
5454
5555# SECTION: Sections:
56# SECTION: Idx Name Size Address Type
56# SECTION: Idx Name Size VMA Type
5757# SECTION: 0 00000000 0000000000000000
5858# SECTION: 1 .text 00000056 0000000000000000 TEXT
5959# SECTION: 2 .rela.text 00000090 0000000000000000
......@@ -64,6 +64,7 @@
6464# SECTION: 7 .strtab 0000002d 0000000000000000
6565
6666# CHECKTEXT: Disassembly of section .text:
67# CHECKTEXT-EMPTY:
6768# CHECKTEXT-NEXT: main:
6869# CHECKTEXT-NEXT: 0: c7 04 25 00 00 00 00 05 00 00 00 movl $5, 0
6970# CHECKTEXT-NEXT: b: c7 04 25 00 00 00 00 07 00 00 00 movl $7, 0
deps/lld/test/ELF/relocation-b-aarch64.test+9-9
......@@ -8,6 +8,7 @@
88# immediate. We use this property to overwrite instructions with a branch.
99
1010# CHECK: Disassembly of section .text:
11# CHECK-EMPTY:
1112# CHECK-NEXT: foo:
1213# CHECK-NEXT: 210000: 01 00 00 14 b #4
1314# CHECK: bar:
......@@ -37,12 +38,11 @@ Sections:
3738 Type: R_AARCH64_JUMP26
3839
3940Symbols:
40 Local:
41 - Type: STT_FUNC
42 Section: .text
43 Name: foo
44 Value: 0
45 - Type: STT_FUNC
46 Section: .text
47 Name: bar
48 Value: 4
41 - Type: STT_FUNC
42 Section: .text
43 Name: foo
44 Value: 0
45 - Type: STT_FUNC
46 Section: .text
47 Name: bar
48 Value: 4
deps/lld/test/ELF/relocation-before-merge-start.s+1-1
......@@ -4,6 +4,6 @@
44// CHECK: relocation-before-merge-start.s.tmp.o:(.foo): offset is outside the section
55
66.data
7.long .foo - 1
7.quad .foo - 1
88.section .foo,"aM",@progbits,4
99.quad 0
deps/lld/test/ELF/relocation-copy-align-common.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: %p/Inputs/relocation-copy-align-common.s -o %t2.o
55# RUN: ld.lld -shared %t2.o -o %t.so
66# RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t3
7# RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
7# RUN: llvm-readobj -S -r --expand-relocs %t3 | FileCheck %s
88
99# CHECK: Section {
1010# CHECK: Index:
deps/lld/test/ELF/relocation-copy-align.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-align.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t.so
55// RUN: ld.lld %t.o %t.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
6// RUN: llvm-readobj -S -r --expand-relocs %t3 | FileCheck %s
77
88.global _start
99_start:
deps/lld/test/ELF/relocation-copy-flags.s+7-7
......@@ -4,7 +4,7 @@
44// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o
55// RUN: ld.lld %t2.o -o %t2.so -shared
66// RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t.exe
7// RUN: llvm-readobj -s -section-data -r %t.exe | FileCheck %s
7// RUN: llvm-readobj -S --section-data -r %t.exe | FileCheck %s
88
99 .global _start
1010_start:
......@@ -30,7 +30,7 @@ _start:
3030// CHECK-NEXT: AddressAlignment: 4
3131// CHECK-NEXT: EntrySize: 0
3232// CHECK-NEXT: SectionData (
33// CHECK-NEXT: 0000: 00402000
33// CHECK-NEXT: 0000: 10302000
3434// CHECK-NEXT: )
3535
3636// CHECK: Name: bar
......@@ -39,8 +39,8 @@ _start:
3939// CHECK-NEXT: SHF_ALLOC
4040// CHECK-NEXT: SHF_WRITE
4141// CHECK-NEXT: ]
42// CHECK-NEXT: Address: 0x202000
43// CHECK-NEXT: Offset: 0x2000
42// CHECK-NEXT: Address: 0x203000
43// CHECK-NEXT: Offset: 0x3000
4444// CHECK-NEXT: Size: 8
4545// CHECK-NEXT: Link: 0
4646// CHECK-NEXT: Info: 0
......@@ -55,7 +55,7 @@ _start:
5555// CHECK-NEXT: Flags [
5656// CHECK-NEXT: ]
5757// CHECK-NEXT: Address: 0x0
58// CHECK-NEXT: Offset: 0x30B0
58// CHECK-NEXT: Offset: 0x3008
5959// CHECK-NEXT: Size: 8
6060// CHECK-NEXT: Link: 0
6161// CHECK-NEXT: Info: 0
......@@ -67,7 +67,7 @@ _start:
6767
6868// CHECK: Relocations [
6969// CHECK-NEXT: Section (4) .rela.dyn {
70// CHECK-NEXT: 0x204000 R_X86_64_COPY x 0x0
71// CHECK-NEXT: 0x202000 R_X86_64_64 z 0x0
70// CHECK-NEXT: 0x203010 R_X86_64_COPY x 0x0
71// CHECK-NEXT: 0x203000 R_X86_64_64 z 0x0
7272// CHECK-NEXT: }
7373// CHECK-NEXT: ]
deps/lld/test/ELF/relocation-copy-i686.s+2-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/relocation-copy.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t.so
55// RUN: ld.lld -e main %t.o %t.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
6// RUN: llvm-readobj -S -r --expand-relocs %t3 | FileCheck %s
77// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
88
99.text
......@@ -57,6 +57,7 @@ movl $9, z
5757// 4206608 = 0x403000 + 16
5858// 4206612 = 0x403000 + 16 + 4
5959// CODE: Disassembly of section .text:
60// CODE-EMPTY:
6061// CODE-NEXT: main:
6162// CODE-NEXT: 401000: c7 05 00 30 40 00 05 00 00 00 movl $5, 4206592
6263// CODE-NEXT: 40100a: c7 05 10 30 40 00 07 00 00 00 movl $7, 4206608
deps/lld/test/ELF/relocation-copy-relro.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-relro.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t.so
55// RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t3
6// RUN: llvm-readobj -program-headers -s -r %t3 | FileCheck %s
6// RUN: llvm-readobj -S -l -r %t3 | FileCheck %s
77
88// CHECK: Name: .bss.rel.ro (48)
99// CHECK-NEXT: Type: SHT_NOBITS (0x8)
deps/lld/test/ELF/relocation-copy.s+2-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t.so
55// RUN: ld.lld %t.o %t.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
6// RUN: llvm-readobj -S -r --expand-relocs %t3 | FileCheck %s
77// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
88
99.text
......@@ -58,6 +58,7 @@ movl $z, %edx
5858// 2109456 = 0x203000 + 16
5959// 2109460 = 0x203000 + 16 + 4
6060// CODE: Disassembly of section .text:
61// CODE-EMPTY:
6162// CODE-NEXT: _start:
6263// CODE-NEXT: 201000: {{.*}} movl $5, 2109440
6364// CODE-NEXT: 20100b: {{.*}} movl $7, 2109456
deps/lld/test/ELF/relocation-dtrace.test deleted-24
......@@ -1,24 +0,0 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld -shared %t.o -o /dev/null
3
4# Test that we can handle R_X86_64_NONE as produced by dtrace.
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 - Name: .text
15 Type: SHT_PROGBITS
16 Flags: [ SHF_ALLOC ]
17 - Name: .rela.text
18 Type: SHT_RELA
19 Link: .symtab
20 Info: .text
21 Relocations:
22 - Offset: 0x0000000000000000
23 Symbol: ''
24 Type: R_X86_64_NONE
deps/lld/test/ELF/relocation-group.test+3-3
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj %s -o %t.o
22# RUN: ld.lld %t.o %t.o -o %t -r
3# RUN: llvm-readobj -s %t | FileCheck %s
3# RUN: llvm-readobj -S %t | FileCheck %s
44
55# CHECK: Name: .text.foo
66# CHECK: Name: .rela.text.foo
......@@ -39,5 +39,5 @@ Sections:
3939 Symbol: foo
4040 Type: R_X86_64_64
4141Symbols:
42 Global:
43 - Name: foo
42 - Name: foo
43 Binding: STB_GLOBAL
deps/lld/test/ELF/relocation-i686.s+17-14
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld --hash-style=sysv %t %t2.so -o %t2
6// RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=ADDR %s
6// RUN: llvm-readobj -S %t2 | FileCheck --check-prefix=ADDR %s
77// RUN: llvm-objdump -d %t2 | FileCheck %s
88
99.global _start
......@@ -26,10 +26,12 @@ R_386_PC32_2:
2626 nop
2727
2828// CHECK: Disassembly of section .R_386_32:
29// CHECK-EMPTY:
2930// CHECK-NEXT: R_386_32:
3031// CHECK-NEXT: 401000: {{.*}} movl $4198401, %edx
3132
3233// CHECK: Disassembly of section .R_386_PC32:
34// CHECK-EMPTY:
3335// CHECK-NEXT: R_386_PC32:
3436// CHECK-NEXT: 401005: e8 04 00 00 00 calll 4
3537
......@@ -49,30 +51,32 @@ movl bar@GOT, %eax
4951// ADDR-NEXT: Offset: 0x1040
5052// ADDR-NEXT: Size: 32
5153
52// ADDR: Name: .got (
54// ADDR: Name: .got.plt (
5355// ADDR-NEXT: Type: SHT_PROGBITS
5456// ADDR-NEXT: Flags [
5557// ADDR-NEXT: SHF_ALLOC
5658// ADDR-NEXT: SHF_WRITE
5759// ADDR-NEXT: ]
58// ADDR-NEXT: Address: 0x403078
60// ADDR-NEXT: Address: 0x403000
5961// ADDR-NEXT: Offset:
60// ADDR-NEXT: Size: 8
62// ADDR-NEXT: Size:
6163
6264.section .R_386_GOTPC,"ax",@progbits
6365R_386_GOTPC:
6466 movl $_GLOBAL_OFFSET_TABLE_, %eax
6567
66// 0x402078 + 8 - 0x401014 = 4204
68// 0x403000 (.got.plt) - 0x401014 = 8300
6769
6870// CHECK: Disassembly of section .R_386_GOTPC:
71// CHECK-EMPTY:
6972// CHECK-NEXT: R_386_GOTPC:
70// CHECK-NEXT: 401014: {{.*}} movl $8300, %eax
73// CHECK-NEXT: 401014: {{.*}} movl $8172, %eax
7174
7275.section .dynamic_reloc, "ax",@progbits
7376 call bar
7477// addr(.plt) + 16 - (0x401019 + 5) = 50
7578// CHECK: Disassembly of section .dynamic_reloc:
79// CHECK-EMPTY:
7680// CHECK-NEXT: .dynamic_reloc:
7781// CHECK-NEXT: 401019: e8 32 00 00 00 calll 50
7882
......@@ -84,13 +88,12 @@ R_386_GOT32:
8488 movl bar+8@GOT, %eax
8589 movl zed+4@GOT, %eax
8690
87// 4294967288 = 0xFFFFFFF8 = got[0](0x402070) - .got(0x402070) - sizeof(.got)(8)
88// 4294967292 = 0xFFFFFFFC = got[1](0x402074) - .got(0x402070) - sizeof(.got)(8)
89// 0xFFFFFFF8 + 8 = 0
90// 0xFFFFFFFC + 4 = 0
91// 4294963320 = 0xfffff078 = got[0](0x402078) - .got.plt(0x403000)
92// 4294963324 = 0xfffff07c = got[1](0x40207c) - .got(0x403000)
9193// CHECK: Disassembly of section .R_386_GOT32:
94// CHECK-EMPTY:
9295// CHECK-NEXT: R_386_GOT32:
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
96// CHECK-NEXT: 40101e: a1 78 f0 ff ff movl 4294963320, %eax
97// CHECK-NEXT: 401023: a1 7c f0 ff ff movl 4294963324, %eax
98// CHECK-NEXT: 401028: a1 80 f0 ff ff movl 4294963328, %eax
99// CHECK-NEXT: 40102d: a1 80 f0 ff ff movl 4294963328, %eax
deps/lld/test/ELF/relocation-local.s+2
......@@ -19,6 +19,7 @@ R_X86_64_32:
1919// FIXME: this would be far more self evident if llvm-objdump printed
2020// constants in hex.
2121// CHECK: Disassembly of section .text2:
22// CHECK-EMPTY:
2223// CHECK-NEXT: R_X86_64_32:
2324// CHECK-NEXT: 201009: {{.*}} movl $2101257, %edx
2425
......@@ -27,6 +28,7 @@ R_X86_64_32S:
2728 movq lulz - 0x100000, %rdx
2829
2930// CHECK: Disassembly of section .R_X86_64_32S:
31// CHECK-EMPTY:
3032// CHECK-NEXT: R_X86_64_32S:
3133// CHECK-NEXT: {{.*}}: {{.*}} movq 1052681, %rdx
3234
deps/lld/test/ELF/relocation-non-alloc.s+12-12
......@@ -2,12 +2,12 @@
22
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
44// RUN: ld.lld %t -o %t2 -shared --apply-dynamic-relocs
5// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix APPLYDYNREL %s
5// RUN: llvm-readobj -S --section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix APPLYDYNREL %s
66
77// RUN: ld.lld %t -o %t2 -shared
8// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
8// RUN: llvm-readobj -S --section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
99// RUN: ld.lld %t -o %t2 -shared --no-apply-dynamic-relocs
10// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
10// RUN: llvm-readobj -S --section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
1111
1212// APPLYDYNREL: Name: .data
1313// APPLYDYNREL-NEXT: Type: SHT_PROGBITS
......@@ -15,15 +15,15 @@
1515// APPLYDYNREL-NEXT: SHF_ALLOC
1616// APPLYDYNREL-NEXT: SHF_WRITE
1717// APPLYDYNREL-NEXT: ]
18// APPLYDYNREL-NEXT: Address: 0x1000
19// APPLYDYNREL-NEXT: Offset: 0x1000
18// APPLYDYNREL-NEXT: Address: 0x2000
19// APPLYDYNREL-NEXT: Offset: 0x2000
2020// APPLYDYNREL-NEXT: Size: 16
2121// APPLYDYNREL-NEXT: Link: 0
2222// APPLYDYNREL-NEXT: Info: 0
2323// APPLYDYNREL-NEXT: AddressAlignment: 1
2424// APPLYDYNREL-NEXT: EntrySize: 0
2525// APPLYDYNREL-NEXT: SectionData (
26// APPLYDYNREL-NEXT: 0000: 00100000 00000000 00000000 00000000
26// APPLYDYNREL-NEXT: 0000: 00200000 00000000 00000000 00000000
2727// APPLYDYNREL-NEXT: )
2828
2929// NOAPPLYDYNREL: Name: .data
......@@ -32,8 +32,8 @@
3232// NOAPPLYDYNREL-NEXT: SHF_ALLOC
3333// NOAPPLYDYNREL-NEXT: SHF_WRITE
3434// NOAPPLYDYNREL-NEXT: ]
35// NOAPPLYDYNREL-NEXT: Address: 0x1000
36// NOAPPLYDYNREL-NEXT: Offset: 0x1000
35// NOAPPLYDYNREL-NEXT: Address: 0x2000
36// NOAPPLYDYNREL-NEXT: Offset: 0x2000
3737// NOAPPLYDYNREL-NEXT: Size: 16
3838// NOAPPLYDYNREL-NEXT: Link: 0
3939// NOAPPLYDYNREL-NEXT: Info: 0
......@@ -55,14 +55,14 @@
5555// CHECK-NEXT: AddressAlignment: 1
5656// CHECK-NEXT: EntrySize: 0
5757// CHECK-NEXT: SectionData (
58// CHECK-NEXT: 0000: 00100000 00000000 00100000 00000000
59// CHECK-NEXT: 0010: 00100000 00000000 00100000 00000000
58// CHECK-NEXT: 0000: 00200000 00000000 00200000 00000000
59// CHECK-NEXT: 0010: 00200000 00000000 00200000 00000000
6060// CHECK-NEXT: )
6161
6262// CHECK: Relocations [
6363// CHECK-NEXT: Section ({{.}}) .rela.dyn {
64// CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x1000
65// CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0
64// CHECK-NEXT: 0x2000 R_X86_64_RELATIVE - 0x2000
65// CHECK-NEXT: 0x2008 R_X86_64_64 zed 0x0
6666// CHECK-NEXT: }
6767// CHECK-NEXT: ]
6868
deps/lld/test/ELF/relocation-none-aarch64.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: aarch64
2
3# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-musl %s -o %t.o
4# RUN: ld.lld --gc-sections %t.o -o %t
5# RUN: llvm-readelf -S -r %t | FileCheck %s
6
7# Test that we discard R_AARCH64_NONE, but respect the references it creates
8# among sections.
9
10# CHECK: .data
11# CHECK: There are no relocations in this file.
12
13# RUN: ld.lld -r %t.o -o %t
14# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
15
16# RELOC: Section ({{.*}}) .rela.text {
17# RELOC-NEXT: 0x0 R_AARCH64_NONE .data 0x0
18# RELOC-NEXT: }
19
20.globl _start
21_start:
22 ret
23 .reloc 0, R_AARCH64_NONE, .data
24
25.data
26 .long 0
deps/lld/test/ELF/relocation-none-aarch64.test deleted-24
......@@ -1,24 +0,0 @@
1# REQUIRES: aarch64
2
3# RUN: yaml2obj %s -o %t.o
4# RUN: ld.lld %t.o -o /dev/null
5
6!ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_AARCH64
12Sections:
13 - Type: SHT_PROGBITS
14 Name: .text
15 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
16 Content: "00000000"
17 - Type: SHT_RELA
18 Name: .rela.text
19 Link: .symtab
20 Info: .text
21 Relocations:
22 - Offset: 0
23 Symbol: ''
24 Type: R_AARCH64_NONE
deps/lld/test/ELF/relocation-none-arm.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: arm
2
3# RUN: llvm-mc -filetype=obj -triple=armv7-linux-musl %s -o %t.o
4# RUN: ld.lld --gc-sections %t.o -o %t
5# RUN: llvm-readelf -S -r %t | FileCheck %s
6
7# Test that we discard R_ARM_NONE, but respect the references it creates among
8# sections.
9
10# CHECK: .data
11# CHECK: There are no relocations in this file.
12
13# RUN: ld.lld -r %t.o -o %t
14# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
15
16# RELOC: Section ({{.*}}) .rel.text {
17# RELOC-NEXT: 0x0 R_ARM_NONE .data 0x0
18# RELOC-NEXT: }
19
20.globl _start
21_start:
22 nop
23 .reloc 0, R_ARM_NONE, .data
24
25.data
26 .long 0
deps/lld/test/ELF/relocation-none-i386.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=i386-linux-musl %s -o %t.o
4# RUN: ld.lld --gc-sections %t.o -o %t
5# RUN: llvm-readelf -S -r %t | FileCheck %s
6
7# Test that we discard R_386_NONE, but respect the
8# references it creates among sections.
9
10# CHECK: .data
11# CHECK: There are no relocations in this file.
12
13# RUN: ld.lld -r %t.o -o %t
14# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
15
16# RELOC: Section ({{.*}}) .rel.text {
17# RELOC-NEXT: 0x0 R_386_NONE .data 0x0
18# RELOC-NEXT: }
19
20.globl _start
21_start:
22 ret
23 .reloc 0, R_386_NONE, .data
24
25.data
26 .long 0
deps/lld/test/ELF/relocation-none-i686.test deleted-23
......@@ -1,23 +0,0 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld %t.o -o /dev/null
3
4# Test that we can handle R_386_NONE.
5
6!ELF
7FileHeader:
8 Class: ELFCLASS32
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_386
12Sections:
13 - Name: .text
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC ]
16 - Name: .rel.text
17 Type: SHT_RELA
18 Link: .symtab
19 Info: .text
20 Relocations:
21 - Offset: 0x0000000000000000
22 Symbol: ''
23 Type: R_386_NONE
deps/lld/test/ELF/relocation-none-x86-64.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-linux-musl %s -o %t.o
4# RUN: ld.lld --gc-sections %t.o -o %t
5# RUN: llvm-readelf -S -r %t | FileCheck %s
6
7# Test that we discard R_X86_64_NONE, but respect the
8# references it creates among sections.
9
10# CHECK: .data
11# CHECK: There are no relocations in this file.
12
13# RUN: ld.lld -r %t.o -o %t
14# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
15
16# RELOC: Section ({{.*}}) .rela.text {
17# RELOC-NEXT: 0x0 R_X86_64_NONE .data 0x0
18# RELOC-NEXT: }
19
20.globl _start
21_start:
22 ret
23 .reloc 0, R_X86_64_NONE, .data
24
25.data
26 .long 0
deps/lld/test/ELF/relocation-past-merge-end.s+1-1
......@@ -4,6 +4,6 @@
44// CHECK: relocation-past-merge-end.s.tmp.o:(.foo): offset is outside the section
55
66.data
7.long .foo + 10
7.quad .foo + 10
88.section .foo,"aM",@progbits,4
99.quad 0
deps/lld/test/ELF/relocation-relative-synthetic.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 -o %t -pie
4# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
4# RUN: llvm-readobj --dyn-relocations %t | FileCheck %s
55
66# CHECK: Dynamic Relocations {
77# CHECK-NEXT: }
deps/lld/test/ELF/relocation-relative-weak.s+5-3
......@@ -1,10 +1,12 @@
11# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/dummy-shared.s -o %t1.o
3# RUN: ld.lld %t1.o -shared -o %t1.so
24# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t -pie
4# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
5# RUN: ld.lld %t.o %t1.so -o %t -pie
6# RUN: llvm-readobj --dyn-relocations %t | FileCheck %s
57
68# CHECK: Dynamic Relocations {
7# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT w 0x0
9# CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT w 0x0
810# CHECK-NEXT: }
911
1012.globl _start
deps/lld/test/ELF/relocation-shared.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-readobj -r -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -r -S --section-data %t.so | FileCheck %s
55
66// CHECK: Name: foo
77// CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/relocation-size-shared.s+1
......@@ -18,6 +18,7 @@
1818// RELOCSHARED-NEXT:]
1919
2020// DISASM: Disassembly of section test
21// DISASM-EMPTY:
2122// DISASM: _data:
2223// DISASM-NEXT: 201000: 19 00
2324// DISASM-NEXT: 201002: 00 00
deps/lld/test/ELF/relocation-size.s+2
......@@ -11,6 +11,7 @@
1111// NORELOC-NEXT: ]
1212
1313// DISASM: Disassembly of section test:
14// DISASM-EMPTY:
1415// DISASM-NEXT: _data:
1516// DISASM-NEXT: 201000: 19 00
1617// DISASM-NEXT: 201002: 00 00
......@@ -56,6 +57,7 @@
5657// RELOCSHARED-NEXT: ]
5758
5859// DISASMSHARED: Disassembly of section test:
60// DISASMSHARED-EMPTY:
5961// DISASMSHARED-NEXT: _data:
6062// DISASMSHARED-NEXT: ...
6163// DISASMSHARED-NEXT: 1018: 19 00
deps/lld/test/ELF/relocation-undefined-weak.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -sections %tout | FileCheck %s
4// RUN: llvm-readobj --sections %tout | FileCheck %s
55// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix DISASM
66
77// Check that undefined weak symbols are treated as having a VA of 0.
deps/lld/test/ELF/relocation.s+21-16
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2
44// RUN: ld.lld %t2 -soname fixed-length-string.so -o %t2.so -shared
55// RUN: ld.lld --hash-style=sysv %t %t2.so -o %t3
6// RUN: llvm-readobj -s %t3 | FileCheck --check-prefix=SEC %s
6// RUN: llvm-readobj -S %t3 | FileCheck --check-prefix=SEC %s
77// RUN: llvm-objdump -s -d %t3 | FileCheck %s
88
99// SEC: Name: .plt
......@@ -16,35 +16,35 @@
1616// SEC-NEXT: Offset: 0x1030
1717// SEC-NEXT: Size: 48
1818
19// SEC: Name: .got.plt
19// SEC: Name: .got
2020// SEC-NEXT: Type: SHT_PROGBITS
2121// SEC-NEXT: Flags [
2222// SEC-NEXT: SHF_ALLOC
2323// SEC-NEXT: SHF_WRITE
2424// SEC-NEXT: ]
25// SEC-NEXT: Address: 0x202000
26// SEC-NEXT: Offset: 0x2000
27// SEC-NEXT: Size: 40
25// SEC-NEXT: Address: 0x2020F0
26// SEC-NEXT: Offset:
27// SEC-NEXT: Size: 8
2828// SEC-NEXT: Link: 0
2929// SEC-NEXT: Info: 0
3030// SEC-NEXT: AddressAlignment: 8
3131// SEC-NEXT: EntrySize: 0
32// SEC-NEXT: }
32// SEC-NEXT: }
3333
34// SEC: Name: .got
34// SEC: Name: .got.plt
3535// SEC-NEXT: Type: SHT_PROGBITS
3636// SEC-NEXT: Flags [
3737// SEC-NEXT: SHF_ALLOC
3838// SEC-NEXT: SHF_WRITE
3939// SEC-NEXT: ]
40// SEC-NEXT: Address: 0x2030F0
41// SEC-NEXT: Offset:
42// SEC-NEXT: Size: 8
40// SEC-NEXT: Address: 0x203000
41// SEC-NEXT: Offset: 0x3000
42// SEC-NEXT: Size: 40
4343// SEC-NEXT: Link: 0
4444// SEC-NEXT: Info: 0
4545// SEC-NEXT: AddressAlignment: 8
4646// SEC-NEXT: EntrySize: 0
47// SEC-NEXT: }
47// SEC-NEXT: }
4848
4949.section .text,"ax",@progbits,unique,1
5050.global _start
......@@ -58,6 +58,7 @@ lulz:
5858 nop
5959
6060// CHECK: Disassembly of section .text:
61// CHECK-EMPTY:
6162// CHECK-NEXT: _start:
6263// CHECK-NEXT: 201000: e8 04 00 00 00 callq 4
6364// CHECK-NEXT: 201005:
......@@ -74,6 +75,7 @@ R_X86_64_32:
7475// FIXME: this would be far more self evident if llvm-objdump printed
7576// constants in hex.
7677// CHECK: Disassembly of section .text2:
78// CHECK-EMPTY:
7779// CHECK-NEXT: R_X86_64_32:
7880// CHECK-NEXT: 20100a: {{.*}} movl $2101258, %edx
7981
......@@ -83,6 +85,7 @@ R_X86_64_32S:
8385 movq lulz - 0x100000, %rdx
8486
8587// CHECK: Disassembly of section .R_X86_64_32S:
88// CHECK-EMPTY:
8689// CHECK-NEXT: R_X86_64_32S:
8790// CHECK-NEXT: {{.*}}: {{.*}} movq 1052681, %rdx
8891
......@@ -94,6 +97,7 @@ R_X86_64_PC32:
9497//16 is a size of PLT[0]
9598// 0x201030 + 16 - (0x201017 + 5) = 20
9699// CHECK: Disassembly of section .R_X86_64_PC32:
100// CHECK-EMPTY:
97101// CHECK-NEXT: R_X86_64_PC32:
98102// CHECK-NEXT: 201017: {{.*}} callq 36
99103// CHECK-NEXT: 20101c: {{.*}} movl $2101312, %eax
......@@ -104,6 +108,7 @@ R_X86_64_32S_2:
104108 mov bar2, %eax
105109// plt is at 0x201030. The second plt entry is at 0x201050 == 69712
106110// CHECK: Disassembly of section .R_X86_64_32S_2:
111// CHECK-EMPTY:
107112// CHECK-NEXT: R_X86_64_32S_2:
108113// CHECK-NEXT: 201021: {{.*}} movl 2101328, %eax
109114
......@@ -113,16 +118,16 @@ R_X86_64_64:
113118 .quad R_X86_64_64
114119
115120// CHECK: Contents of section .R_X86_64_64:
116// CHECK-NEXT: 2002c0 c0022000 00000000
121// CHECK-NEXT: 2002f8 f8022000 00000000
117122
118123.section .R_X86_64_GOTPCREL,"a",@progbits
119124.global R_X86_64_GOTPCREL
120125R_X86_64_GOTPCREL:
121126 .long zed@gotpcrel
122127
123// 0x2030F0(.got) - 0x2002c8(.R_X86_64_GOTPCREL) = 0x2e28
128// 0x2020F0(.got) - 0x2002c8(.R_X86_64_GOTPCREL) = 0x1e28
124129// CHECK: Contents of section .R_X86_64_GOTPCREL
125// CHECK-NEXT: 2002c8 282e0000
130// CHECK-NEXT: 200300 f01d0000
126131
127132.section .R_X86_64_GOT32,"a",@progbits
128133.global R_X86_64_GOT32
......@@ -130,11 +135,11 @@ R_X86_64_GOT32:
130135 .long zed@got
131136
132137// CHECK: Contents of section .R_X86_64_GOT32:
133// CHECK-NEXT: f8ffffff
138// CHECK-NEXT: f0f0ffff
134139
135140
136141// CHECK: Contents of section .R_X86_64_GOT64:
137// CHECK-NEXT: f8ffffff ffffffff
142// CHECK-NEXT: f0f0ffff ffffffff
138143.section .R_X86_64_GOT64,"a",@progbits
139144.global R_X86_64_GOT64
140145R_X86_64_GOT64:
deps/lld/test/ELF/relro-bss.s created+44
......@@ -0,0 +1,44 @@
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-readelf -l %t | FileCheck --check-prefix=SEG %s
5# RUN: llvm-readelf -S %t | FileCheck %s
6
7# We have 2 RW PT_LOAD segments. p_offset p_vaddr p_paddr p_filesz of the first
8# should match PT_GNU_RELRO.
9# Because .bss.rel.ro (nobits) doesn't take space, p_filesz < p_memsz.
10
11# Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
12# SEG: LOAD 0x001000 0x0000000000201000 0x0000000000201000 0x000001 0x000001 R E 0x1000
13# SEG-NEXT: LOAD 0x002000 0x0000000000202000 0x0000000000202000 0x000001 0x002001 RW 0x1000
14# SEG-NEXT: LOAD 0x003000 0x0000000000205000 0x0000000000205000 0x000001 0x000002 RW 0x1000
15# SEG-NEXT: GNU_RELRO 0x002000 0x0000000000202000 0x0000000000202000 0x000001 0x003000 R 0x1
16# SEG-NEXT: GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x0
17
18# SEG: .text
19# SEG-NEXT: .data.rel.ro .bss.rel.ro
20# SEG-NEXT: .data .bss
21
22# And .data is placed in the next page (sh_offset = alignTo(0x2001, 4096) = 0x3000).
23
24# [Nr] Name Type Address Off Size
25# CHECK: .data.rel.ro PROGBITS 0000000000202000 002000 000001
26# CHECK-NEXT: .bss.rel.ro NOBITS 0000000000202001 002001 002000
27# CHECK-NEXT: .data PROGBITS 0000000000205000 003000 000001
28# CHECK-NEXT: .bss NOBITS 0000000000205001 003001 000001
29
30.globl _start
31_start:
32 ret
33
34.section .data.rel.ro, "aw"
35.space 1
36
37.section .bss.rel.ro, "aw", @nobits
38.space 8192
39
40.section .data, "aw"
41.space 1
42
43.section .bss, "aw"
44.space 1
deps/lld/test/ELF/relro-non-contiguous.s+3-3
......@@ -3,12 +3,12 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o
44// RUN: ld.lld -shared %t.o %t2.o -o %t.so
55
6// Place the .got.plt (non relro) immediately after .dynamic. This is the
7// reverse order of the non-linker script case. The linker created .bss.rel.ro
8// section will be placed after .got.plt causing the relro to be non-contiguous.
6// Separate RelRo sections .dynamic .bss.rel.ro with non RelRo .got.plt.
7// This causes the RelRo sections to be non-contiguous.
98// RUN: echo "SECTIONS { \
109// RUN: .dynamic : { *(.dynamic) } \
1110// RUN: .got.plt : { *(.got.plt) } \
11// RUN: .bss.rel.ro : { *(.bss.rel.o) } \
1212// RUN: } " > %t.script
1313// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o
1414
deps/lld/test/ELF/relro-omagic.s+2-2
......@@ -2,12 +2,12 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
44# RUN: ld.lld -shared %t2.o -o %t2.so -soname relro-omagic.s.tmp2.so
5# RUN: ld.lld --hash-style=sysv -N %t.o %t2.so -o %t
5# RUN: ld.lld --hash-style=sysv -N %t.o -Bdynamic %t2.so -o %t
66# RUN: llvm-objdump -section-headers %t | FileCheck --check-prefix=NORELRO %s
77# RUN: llvm-readobj --program-headers %t | FileCheck --check-prefix=NOPHDRS %s
88
99# NORELRO: Sections:
10# NORELRO-NEXT: Idx Name Size Address Type
10# NORELRO-NEXT: Idx Name Size VMA Type
1111# NORELRO-NEXT: 0 00000000 0000000000000000
1212# NORELRO-NEXT: 1 .dynsym 00000048 0000000000200120
1313# NORELRO-NEXT: 2 .hash 00000020 0000000000200168
deps/lld/test/ELF/relro-tls.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -program-headers %tout | FileCheck %s
4// RUN: llvm-readobj -l %tout | FileCheck %s
55
66// CHECK: Type: PT_GNU_RELRO
77// CHECK-NEXT: Offset:
deps/lld/test/ELF/relro.s+6-5
......@@ -5,13 +5,13 @@
55// RUN: ld.lld -shared %t2.o -o %t2.so
66
77// RUN: ld.lld %t.o %t2.so -z now -z norelro -z relro -o %t
8// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=FULLRELRO %s
8// RUN: llvm-readelf -l %t | FileCheck --check-prefix=CHECK --check-prefix=FULLRELRO %s
99
1010// RUN: ld.lld %t.o %t2.so -z norelro -z relro -o %t
11// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=PARTRELRO %s
11// RUN: llvm-readelf -l %t | FileCheck --check-prefix=CHECK --check-prefix=PARTRELRO %s
1212
1313// RUN: ld.lld %t.o %t2.so -z norelro -o %t
14// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=NORELRO %s
14// RUN: llvm-readelf -l %t | FileCheck --check-prefix=NORELRO %s
1515
1616// CHECK: Program Headers:
1717// CHECK-NEXT: Type
......@@ -19,12 +19,13 @@
1919// CHECK-NEXT: LOAD
2020// CHECK-NEXT: LOAD
2121// CHECK-NEXT: LOAD
22// CHECK-NEXT: LOAD
2223// CHECK-NEXT: DYNAMIC
2324// CHECK-NEXT: GNU_RELRO
2425// CHECK: Section to Segment mapping:
2526
26// FULLRELRO: 05 .openbsd.randomdata .dynamic .got .got.plt {{$}}
27// PARTRELRO: 05 .openbsd.randomdata .dynamic .got {{$}}
27// FULLRELRO: 03 .openbsd.randomdata .dynamic .got .got.plt {{$}}
28// PARTRELRO: 03 .openbsd.randomdata .dynamic .got {{$}}
2829
2930
3031// NORELRO-NOT: GNU_RELRO
deps/lld/test/ELF/resolution-end.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-end.s -o %t2.o
44# RUN: ld.lld -shared -o %t2.so %t2.o
55# RUN: ld.lld --hash-style=sysv %t1.o %t2.so -o %t
6# RUN: llvm-readobj -t -s -section-data %t | FileCheck %s
6# RUN: llvm-readobj --symbols -S --section-data %t | FileCheck %s
77
88# Test that we resolve _end to the this executable.
99
deps/lld/test/ELF/resolution-shared.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-shared.s -o %t2.o
44// RUN: ld.lld %t2.o -o %t2.so -shared
55// RUN: ld.lld %t.o %t2.so -o %t3 -shared
6// RUN: llvm-readobj -t %t3 | FileCheck %s
6// RUN: llvm-readobj --symbols %t3 | FileCheck %s
77
88 .weak foo
99foo:
deps/lld/test/ELF/resolution.s+1-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2
44// RUN: ld.lld -discard-all %t %t2 -o %t3
5// RUN: llvm-readobj -t %t3 | FileCheck %s
5// RUN: llvm-readobj --symbols %t3 | FileCheck %s
66
77// This is an exhaustive test for checking which symbol is kept when two
88// have the same name. Each symbol has a different size which is used
deps/lld/test/ELF/riscv-branch.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: riscv
2
3# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o
4# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o
5
6# RUN: ld.lld %t.rv32.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv32
7# RUN: ld.lld %t.rv64.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv64
8# RUN: llvm-objdump -d %t.rv32 | FileCheck %s
9# RUN: llvm-objdump -d %t.rv64 | FileCheck %s
10# CHECK: 63 02 00 00 beqz zero, 4
11# CHECK: e3 1e 00 fe bnez zero, -4
12#
13# RUN: ld.lld %t.rv32.o --defsym foo=_start+0xffe --defsym bar=_start+4-0x1000 -o %t.rv32.limits
14# RUN: ld.lld %t.rv64.o --defsym foo=_start+0xffe --defsym bar=_start+4-0x1000 -o %t.rv64.limits
15# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s
16# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s
17# LIMITS: e3 0f 00 7e beqz zero, 4094
18# LIMITS-NEXT: 63 10 00 80 bnez zero, -4096
19
20# RUN: not ld.lld %t.rv32.o --defsym foo=_start+0x1000 --defsym bar=_start+4-0x1002 -o %t 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s
21# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x1000 --defsym bar=_start+4-0x1002 -o %t 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s
22# ERROR-RANGE: relocation R_RISCV_BRANCH out of range: 2048 is not in [-2048, 2047]
23# ERROR-RANGE-NEXT: relocation R_RISCV_BRANCH out of range: -2049 is not in [-2048, 2047]
24
25# RUN: not ld.lld %t.rv32.o --defsym foo=_start+1 --defsym bar=_start-1 -o %t 2>&1 | FileCheck --check-prefix=ERROR-ALIGN %s
26# RUN: not ld.lld %t.rv64.o --defsym foo=_start+1 --defsym bar=_start-1 -o %t 2>&1 | FileCheck --check-prefix=ERROR-ALIGN %s
27# ERROR-ALIGN: improper alignment for relocation R_RISCV_BRANCH: 0x1 is not aligned to 2 bytes
28
29.global _start
30_start:
31 beq x0, x0, foo
32 bne x0, x0, bar
deps/lld/test/ELF/riscv-branch.test deleted-119
......@@ -1,119 +0,0 @@
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.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: riscv
2
3# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o
4# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o
5
6# RUN: ld.lld %t.rv32.o --defsym foo=_start+8 --defsym bar=_start -o %t.rv32
7# RUN: ld.lld %t.rv64.o --defsym foo=_start+8 --defsym bar=_start -o %t.rv64
8# RUN: llvm-objdump -d %t.rv32 | FileCheck %s
9# RUN: llvm-objdump -d %t.rv64 | FileCheck %s
10# CHECK: 97 00 00 00 auipc ra, 0
11# CHECK-NEXT: e7 80 80 00 jalr 8(ra)
12# CHECK: 97 00 00 00 auipc ra, 0
13# CHECK-NEXT: e7 80 80 ff jalr -8(ra)
14
15# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+8-0x80000800 -o %t.rv32.limits
16# RUN: ld.lld %t.rv64.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+8-0x80000800 -o %t.rv64.limits
17# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s
18# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s
19# LIMITS: 97 f0 ff 7f auipc ra, 524287
20# LIMITS-NEXT: e7 80 f0 7f jalr 2047(ra)
21# LIMITS-NEXT: 97 00 00 80 auipc ra, 524288
22# LIMITS-NEXT: e7 80 00 80 jalr -2048(ra)
23
24# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+8-0x80000801 -o %t
25# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+8-0x80000801 -o %t 2>&1 | FileCheck --check-prefix=ERROR %s
26# ERROR: relocation R_RISCV_CALL out of range: 524288 is not in [-524288, 524287]
27# ERROR-NEXT: relocation R_RISCV_CALL out of range: -524289 is not in [-524288, 524287]
28
29.global _start
30_start:
31 call foo
32 call bar
deps/lld/test/ELF/riscv-call.test deleted-95
......@@ -1,95 +0,0 @@
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-gp-dummy-sdata.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: riscv
2# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
3# RUN: ld.lld -pie %t.32.o -o %t.32
4# RUN: llvm-readelf -S %t.32 | FileCheck --check-prefix=SEC %s
5# RUN: llvm-readelf -s %t.32 | FileCheck --check-prefix=SYM %s
6
7# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
8# RUN: ld.lld -pie %t.64.o -o %t.64
9# RUN: llvm-readelf -S %t.64 | FileCheck --check-prefix=SEC %s
10# RUN: llvm-readelf -s %t.64 | FileCheck --check-prefix=SYM %s
11
12## If there is an undefined reference to __global_pointer$ but .sdata doesn't
13## exist, create a dummy one.
14
15## __global_pointer$ = .sdata+0x800
16# SEC: [ 7] .sdata PROGBITS {{0*}}00003000
17# SYM: {{0*}}00003800 0 NOTYPE GLOBAL DEFAULT 7 __global_pointer$
18
19## If __global_pointer$ is not used, don't create .sdata .
20
21# RUN: llvm-mc -filetype=obj -triple=riscv32 /dev/null -o %t.32.o
22# RUN: ld.lld -pie %t.32.o -o %t.32
23# RUN: llvm-readelf -S %t.32 | FileCheck --implicit-check-not=.sdata /dev/null
24
25lla gp, __global_pointer$
deps/lld/test/ELF/riscv-gp.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: riscv
2# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
3# RUN: ld.lld -pie %t.32.o -o %t.32
4# RUN: llvm-readelf -s %t.32 | FileCheck --check-prefix=SYM %s
5# RUN: llvm-readelf -S %t.32 | FileCheck --check-prefix=SEC %s
6# RUN: not ld.lld -shared %t.32.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s
7
8# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
9# RUN: ld.lld -pie %t.64.o -o %t.64
10# RUN: llvm-readelf -s %t.64 | FileCheck --check-prefix=SYM %s
11# RUN: llvm-readelf -S %t.64 | FileCheck --check-prefix=SEC %s
12# RUN: not ld.lld -shared %t.64.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s
13
14## __global_pointer$ = .sdata+0x800 = 0x3800
15# SEC: [ 7] .sdata PROGBITS {{0*}}00003000
16# SYM: {{0*}}00003800 0 NOTYPE GLOBAL DEFAULT 7 __global_pointer$
17
18## __global_pointer$ - 0x1000 = 4096*3-2048
19# DIS: 1000: auipc gp, 3
20# DIS-NEXT: addi gp, gp, -2048
21
22# ERR: error: relocation R_RISCV_PCREL_HI20 cannot be used against symbol __global_pointer$; recompile with -fPIC
23
24lla gp, __global_pointer$
25
26.section .sdata,"aw"
deps/lld/test/ELF/riscv-hi20-lo12.s created+40
......@@ -0,0 +1,40 @@
1# REQUIRES: riscv
2
3# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o
4# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o
5
6# RUN: ld.lld %t.rv32.o --defsym foo=0 --defsym bar=42 -o %t.rv32
7# RUN: ld.lld %t.rv64.o --defsym foo=0 --defsym bar=42 -o %t.rv64
8# RUN: llvm-objdump -d %t.rv32 | FileCheck %s
9# RUN: llvm-objdump -d %t.rv64 | FileCheck %s
10# CHECK: 37 05 00 00 lui a0, 0
11# CHECK-NEXT: 13 05 05 00 mv a0, a0
12# CHECK-NEXT: 23 20 a5 00 sw a0, 0(a0)
13# CHECK-NEXT: b7 05 00 00 lui a1, 0
14# CHECK-NEXT: 93 85 a5 02 addi a1, a1, 42
15# CHECK-NEXT: 23 a5 b5 02 sw a1, 42(a1)
16
17# RUN: ld.lld %t.rv32.o --defsym foo=0x7ffff7ff --defsym bar=0x7ffff800 -o %t.rv32.limits
18# RUN: ld.lld %t.rv64.o --defsym foo=0x7ffff7ff --defsym bar=0xffffffff7ffff800 -o %t.rv64.limits
19# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s
20# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s
21# LIMITS: 37 f5 ff 7f lui a0, 524287
22# LIMITS-NEXT: 13 05 f5 7f addi a0, a0, 2047
23# LIMITS-NEXT: a3 2f a5 7e sw a0, 2047(a0)
24# LIMITS-NEXT: b7 05 00 80 lui a1, 524288
25# LIMITS-NEXT: 93 85 05 80 addi a1, a1, -2048
26# LIMITS-NEXT: 23 a0 b5 80 sw a1, -2048(a1)
27
28# RUN: not ld.lld %t.rv64.o --defsym foo=0x7ffff800 --defsym bar=0xffffffff7ffff7ff -o %t 2>&1 | FileCheck --check-prefix ERROR %s
29# ERROR: relocation R_RISCV_HI20 out of range: 524288 is not in [-524288, 524287]
30# ERROR-NEXT: relocation R_RISCV_HI20 out of range: -524289 is not in [-524288, 524287]
31
32.global _start
33
34_start:
35 lui a0, %hi(foo)
36 addi a0, a0, %lo(foo)
37 sw a0, %lo(foo)(a0)
38 lui a1, %hi(bar)
39 addi a1, a1, %lo(bar)
40 sw a1, %lo(bar)(a1)
deps/lld/test/ELF/riscv-hi20-lo12.test deleted-86
......@@ -1,86 +0,0 @@
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 deleted-93
......@@ -1,93 +0,0 @@
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.s created+34
......@@ -0,0 +1,34 @@
1# REQUIRES: riscv
2
3# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o
4# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o
5
6# RUN: ld.lld %t.rv32.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv32
7# RUN: ld.lld %t.rv64.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv64
8# RUN: llvm-objdump -d %t.rv32 | FileCheck %s
9# RUN: llvm-objdump -d %t.rv64 | FileCheck %s
10# CHECK: 6f 00 40 00 j 4
11# CHECK: ef f0 df ff jal -4
12
13# RUN: ld.lld %t.rv32.o --defsym foo=_start+0xffffe --defsym bar=_start+4-0x100000 -o %t.rv32.limits
14# RUN: ld.lld %t.rv64.o --defsym foo=_start+0xffffe --defsym bar=_start+4-0x100000 -o %t.rv64.limits
15# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s
16# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s
17# LIMITS: 6f f0 ff 7f j 1048574
18# LIMITS-NEXT: ef 00 00 80 jal -1048576
19
20# RUN: not ld.lld %t.rv32.o --defsym foo=_start+0x100000 --defsym bar=_start+4-0x100002 -o %t 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s
21# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x100000 --defsym bar=_start+4-0x100002 -o %t 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s
22# ERROR-RANGE: relocation R_RISCV_JAL out of range: 524288 is not in [-524288, 524287]
23# ERROR-RANGE-NEXT: relocation R_RISCV_JAL out of range: -524289 is not in [-524288, 524287]
24
25# RUN: not ld.lld %t.rv32.o --defsym foo=_start+1 --defsym bar=_start+4+3 -o %t 2>&1 | FileCheck --check-prefix=ERROR-ALIGN %s
26# RUN: not ld.lld %t.rv64.o --defsym foo=_start+1 --defsym bar=_start+4+3 -o %t 2>&1 | FileCheck --check-prefix=ERROR-ALIGN %s
27# ERROR-ALIGN: improper alignment for relocation R_RISCV_JAL: 0x1 is not aligned to 2 bytes
28# ERROR-ALIGN-NEXT: improper alignment for relocation R_RISCV_JAL: 0x3 is not aligned to 2 bytes
29
30.global _start
31
32_start:
33 jal x0, foo
34 jal x1, bar
deps/lld/test/ELF/riscv-jal.test deleted-161
......@@ -1,161 +0,0 @@
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-error.s created+7
......@@ -0,0 +1,7 @@
1# REQUIRES: riscv
2# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
3# RUN: not ld.lld %t.o --defsym external=0 2>&1 | FileCheck %s
4
5# CHECK: error: R_RISCV_PCREL_LO12 relocation points to an absolute symbol: external
6
7addi sp,sp,%pcrel_lo(external)
deps/lld/test/ELF/riscv-pcrel-hilo.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: riscv
2
3# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o
4# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o
5
6# RUN: ld.lld %t.rv32.o --defsym foo=_start+12 --defsym bar=_start -o %t.rv32
7# RUN: ld.lld %t.rv64.o --defsym foo=_start+12 --defsym bar=_start -o %t.rv64
8# RUN: llvm-objdump -d --no-show-raw-insn %t.rv32 | FileCheck %s
9# RUN: llvm-objdump -d --no-show-raw-insn %t.rv64 | FileCheck %s
10# RUN: ld.lld -pie %t.rv32.o --defsym foo=_start+12 --defsym bar=_start -o %t.rv32
11# RUN: ld.lld -pie %t.rv64.o --defsym foo=_start+12 --defsym bar=_start -o %t.rv64
12# RUN: llvm-objdump -d --no-show-raw-insn %t.rv32 | FileCheck %s
13# RUN: llvm-objdump -d --no-show-raw-insn %t.rv64 | FileCheck %s
14# CHECK: auipc a0, 0
15# CHECK-NEXT: addi a0, a0, 12
16# CHECK-NEXT: sw zero, 12(a0)
17# CHECK: auipc a0, 0
18# CHECK-NEXT: addi a0, a0, -12
19# CHECK-NEXT: sw zero, -12(a0)
20
21# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+12-0x80000800 -o %t.rv32.limits
22# RUN: ld.lld %t.rv64.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+12-0x80000800 -o %t.rv64.limits
23# RUN: llvm-objdump -d --no-show-raw-insn %t.rv32.limits | FileCheck --check-prefix=LIMITS %s
24# RUN: llvm-objdump -d --no-show-raw-insn %t.rv64.limits | FileCheck --check-prefix=LIMITS %s
25# LIMITS: auipc a0, 524287
26# LIMITS-NEXT: addi a0, a0, 2047
27# LIMITS-NEXT: sw zero, 2047(a0)
28# LIMITS: auipc a0, 524288
29# LIMITS-NEXT: addi a0, a0, -2048
30# LIMITS-NEXT: sw zero, -2048(a0)
31
32# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+12-0x80000801 -o %t
33# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+12-0x80000801 -o %t 2>&1 | FileCheck --check-prefix=ERROR %s
34# ERROR: relocation R_RISCV_PCREL_HI20 out of range: 524288 is not in [-524288, 524287]
35# ERROR-NEXT: relocation R_RISCV_PCREL_HI20 out of range: -524289 is not in [-524288, 524287]
36
37.global _start
38_start:
39 auipc a0, %pcrel_hi(foo)
40 addi a0, a0, %pcrel_lo(_start)
41 sw x0, %pcrel_lo(_start)(a0)
42.L1:
43 auipc a0, %pcrel_hi(bar)
44 addi a0, a0, %pcrel_lo(.L1)
45 sw x0, %pcrel_lo(.L1)(a0)
deps/lld/test/ELF/riscv-pcrel-hilo.test deleted-103
......@@ -1,103 +0,0 @@
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/riscv-plt.s created+103
......@@ -0,0 +1,103 @@
1# REQUIRES: riscv
2# RUN: echo '.globl bar, weak; .type bar,@function; .type weak,@function; bar: weak:' > %t1.s
3
4# RUN: llvm-mc -filetype=obj -triple=riscv32 %t1.s -o %t1.32.o
5# RUN: ld.lld -shared %t1.32.o -o %t1.32.so
6# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
7# RUN: ld.lld %t.32.o %t1.32.so -o %t.32
8# RUN: llvm-readelf -S -s %t.32 | FileCheck --check-prefixes=SEC,NM %s
9# RUN: llvm-readobj -r %t.32 | FileCheck --check-prefix=RELOC32 %s
10# RUN: llvm-readelf -x .got.plt %t.32 | FileCheck --check-prefix=GOTPLT32 %s
11# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=DIS,DIS32 %s
12
13# RUN: llvm-mc -filetype=obj -triple=riscv64 %t1.s -o %t1.64.o
14# RUN: ld.lld -shared %t1.64.o -o %t1.64.so
15# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
16# RUN: ld.lld %t.64.o %t1.64.so -o %t.64
17# RUN: llvm-readelf -S -s %t.64 | FileCheck --check-prefixes=SEC,NM %s
18# RUN: llvm-readobj -r %t.64 | FileCheck --check-prefix=RELOC64 %s
19# RUN: llvm-readelf -x .got.plt %t.64 | FileCheck --check-prefix=GOTPLT64 %s
20# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=DIS,DIS64 %s
21
22# SEC: .plt PROGBITS {{0*}}00011030
23
24## A canonical PLT has a non-zero st_value. bar and weak are called but their
25## addresses are not taken, so a canonical PLT is not necessary.
26# NM: {{0*}}00000000 0 FUNC GLOBAL DEFAULT UND bar
27# NM: {{0*}}00000000 0 FUNC WEAK DEFAULT UND weak
28
29## The .got.plt slots relocated by .rela.plt point to .plt
30## This is required by glibc.
31# RELOC32: .rela.plt {
32# RELOC32-NEXT: 0x13008 R_RISCV_JUMP_SLOT bar 0x0
33# RELOC32-NEXT: 0x1300C R_RISCV_JUMP_SLOT weak 0x0
34# RELOC32-NEXT: }
35# GOTPLT32: section '.got.plt'
36# GOTPLT32-NEXT: 0x00013000 00000000 00000000 30100100 30100100
37
38# RELOC64: .rela.plt {
39# RELOC64-NEXT: 0x13010 R_RISCV_JUMP_SLOT bar 0x0
40# RELOC64-NEXT: 0x13018 R_RISCV_JUMP_SLOT weak 0x0
41# RELOC64-NEXT: }
42# GOTPLT64: section '.got.plt'
43# GOTPLT64-NEXT: 0x00013000 00000000 00000000 00000000 00000000
44# GOTPLT64-NEXT: 0x00013010 30100100 00000000 30100100 00000000
45
46# DIS: _start:
47## Direct call
48## foo - . = 0x11020-0x11000 = 32
49# DIS-NEXT: auipc ra, 0
50# DIS-NEXT: 11004: jalr 32(ra)
51## bar@plt - . = 0x11050-0x1100c = 72
52# DIS-NEXT: auipc ra, 0
53# DIS-NEXT: 1100c: jalr 72(ra)
54## bar@plt - . = 0x11050-0x11014 = 64
55# DIS-NEXT: auipc ra, 0
56# DIS-NEXT: 11014: jalr 64(ra)
57## weak@plt - . = 0x11060-0x1101c = 72
58# DIS-NEXT: auipc ra, 0
59# DIS-NEXT: 1101c: jalr 72(ra)
60# DIS: foo:
61# DIS-NEXT: 11020:
62
63# DIS: Disassembly of section .plt:
64# DIS: .plt:
65# DIS-NEXT: auipc t2, 2
66# DIS-NEXT: sub t1, t1, t3
67## .got.plt - .plt = 0x13000 - 0x11030 = 4096*2-48
68# DIS32-NEXT: lw t3, -48(t2)
69# DIS64-NEXT: ld t3, -48(t2)
70# DIS-NEXT: addi t1, t1, -44
71# DIS-NEXT: addi t0, t2, -48
72# DIS32-NEXT: srli t1, t1, 2
73# DIS64-NEXT: srli t1, t1, 1
74# DIS32-NEXT: lw t0, 4(t0)
75# DIS64-NEXT: ld t0, 8(t0)
76# DIS-NEXT: jr t3
77
78## 32-bit: &.got.plt[bar]-. = 0x13008-0x11050 = 4096*2-72
79# DIS: 11050: auipc t3, 2
80# DIS32-NEXT: lw t3, -72(t3)
81# DIS64-NEXT: ld t3, -64(t3)
82# DIS-NEXT: jalr t1, t3
83# DIS-NEXT: nop
84
85## 32-bit: &.got.plt[weak]-. = 0x1300c-0x11060 = 4096*2-84
86# DIS: 11060: auipc t3, 2
87# DIS32-NEXT: lw t3, -84(t3)
88# DIS64-NEXT: ld t3, -72(t3)
89# DIS-NEXT: jalr t1, t3
90# DIS-NEXT: nop
91
92.global _start, foo, bar
93.weak weak
94
95_start:
96 call foo
97 call bar
98 call bar@plt
99 call weak
100
101## foo is local and non-preemptale, no PLT is generated.
102foo:
103 ret
deps/lld/test/ELF/riscv-reloc-64-pic.s created+10
......@@ -0,0 +1,10 @@
1# REQUIRES: riscv
2# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
3# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4
5# CHECK: error: relocation R_RISCV_32 cannot be used against symbol a
6
7.globl a
8
9.data
10.long a
deps/lld/test/ELF/riscv-reloc-add.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: riscv
2# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax %s -o %t.32.o
3# RUN: ld.lld -pie %t.32.o -o %t.32
4# RUN: llvm-readelf -x .rodata %t.32 | FileCheck --check-prefix=HEX %s
5
6# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax %s -o %t.64.o
7# RUN: ld.lld -shared %t.64.o -o %t.64
8# RUN: llvm-readelf -x .rodata %t.64 | FileCheck --check-prefix=HEX %s
9
10# HEX: section '.rodata':
11# HEX-NEXT: 0x{{[0-9a-f]+}} 04000000 00000000 04000000 040004
12
13## R_RISCV_ADD* and R_RISCV_SUB* are link-time constants, otherwise they are
14## not allowed in -pie/-shared mode.
15
16.global _start
17_start:
18.L0:
19 ret
20.L1:
21
22.rodata
23.dword .L1 - .L0
24.word .L1 - .L0
25.half .L1 - .L0
26.byte .L1 - .L0
27
28## Debug section may use R_RISCV_ADD64/R_RISCV_SUB64 pairs to measure lengths
29## of code ranges (e.g. DW_AT_high_pc). Check we allow R_RISCV_ADD*/R_RISCV_SUB*
30## in such non-SHF_ALLOC sections in -pie/-shared mode.
31.section .debug_info
32.quad .L1 - .L0
deps/lld/test/ELF/riscv-reloc-copy.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: riscv
2# RUN: llvm-mc -filetype=obj -triple=riscv32 %p/Inputs/relocation-copy.s -o %t1.o
3# RUN: ld.lld -shared %t1.o -o %t1.so
4# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.o
5# RUN: ld.lld %t.o %t1.so -o %t
6# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
7# RUN: llvm-nm -S %t | FileCheck --check-prefix=NM32 %s
8
9# RUN: llvm-mc -filetype=obj -triple=riscv64 %p/Inputs/relocation-copy.s -o %t1.o
10# RUN: ld.lld -shared %t1.o -o %t1.so
11# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
12# RUN: ld.lld %t.o %t1.so -o %t
13# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
14# RUN: llvm-nm -S %t | FileCheck --check-prefix=NM64 %s
15
16# RELOC: .rela.dyn {
17# RELOC-NEXT: 0x13000 R_RISCV_COPY x 0x0
18# RELOC-NEXT: }
19
20# NM32: 00013000 00000004 B x
21# NM64: 0000000000013000 0000000000000004 B x
22
23la a0, x
deps/lld/test/ELF/riscv-reloc-got.s created+65
......@@ -0,0 +1,65 @@
1# REQUIRES: riscv
2# RUN: echo '.globl b; b:' | llvm-mc -filetype=obj -triple=riscv32 - -o %t1.o
3# RUN: ld.lld -shared %t1.o -o %t1.so
4
5# RUN: llvm-mc -filetype=obj -triple=riscv32 -position-independent %s -o %t.o
6# RUN: ld.lld %t.o %t1.so -o %t
7# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC32 %s
8# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
9# RUN: llvm-readobj -x .got %t | FileCheck --check-prefix=HEX32 %s
10# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=DIS32 %s
11
12# RUN: echo '.globl b; b:' | llvm-mc -filetype=obj -triple=riscv64 - -o %t1.o
13# RUN: ld.lld -shared %t1.o -o %t1.so
14
15# RUN: llvm-mc -filetype=obj -triple=riscv64 -position-independent %s -o %t.o
16# RUN: ld.lld %t.o %t1.so -o %t
17# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC64 %s
18# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
19# RUN: llvm-readobj -x .got %t | FileCheck --check-prefix=HEX64 %s
20# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=DIS64 %s
21
22# SEC: .got PROGBITS 00012060 020060 00000c
23
24# RELOC32: .rela.dyn {
25# RELOC32-NEXT: 0x12068 R_RISCV_32 b 0x0
26# RELOC32-NEXT: }
27
28# RELOC64: .rela.dyn {
29# RELOC64-NEXT: 0x120D0 R_RISCV_64 b 0x0
30# RELOC64-NEXT: }
31
32# NM: 00013000 d a
33
34## .got[0] = _DYNAMIC
35## .got[1] = a (filled at link time)
36## .got[2] = 0 (relocated by R_RISCV_64 at runtime)
37# HEX32: section '.got':
38# HEX32: 0x00012060 00200100 00300100 00000000
39
40# HEX64: section '.got':
41# HEX64: 0x000120c0 00200100 00000000 00300100 00000000
42# HEX64: 0x000120d0 00000000 00000000
43
44## &.got[1]-. = 0x12060-0x11000 = 4096*1+100
45# DIS32: 11000: auipc a0, 1
46# DIS32-NEXT: lw a0, 100(a0)
47## &.got[2]-. = 0x12064-0x11008 = 4096*1+96
48# DIS32: 11008: auipc a0, 1
49# DIS32-NEXT: lw a0, 96(a0)
50
51## &.got[1]-. = 0x120c8-0x11000 = 4096*1+100
52# DIS64: 11000: auipc a0, 1
53# DIS64-NEXT: ld a0, 200(a0)
54## &.got[2]-. = 0x120d0-0x11008 = 4096*1+200
55# DIS64: 11008: auipc a0, 1
56# DIS64-NEXT: ld a0, 200(a0)
57
58la a0,a
59la a0,b
60
61.data
62a:
63## An undefined reference of _GLOBAL_OFFSET_TABLE_ causes .got[0] to be
64## allocated to store _DYNAMIC.
65.long _GLOBAL_OFFSET_TABLE_ - .
deps/lld/test/ELF/riscv-tls-gd.s created+124
......@@ -0,0 +1,124 @@
1# REQUIRES: riscv
2# RUN: echo '.tbss; .globl b, c; b: .zero 4; c:' > %t.s
3# RUN: echo '.globl __tls_get_addr; __tls_get_addr:' > %tga.s
4
5## RISC-V psABI doesn't specify TLS relaxation. Though the code sequences are not
6## relaxed, dynamic relocations can be omitted for GD->LE relaxation.
7
8# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
9# RUN: llvm-mc -filetype=obj -triple=riscv32 %t.s -o %t1.32.o
10# RUN: ld.lld -shared -soname=t1.so %t1.32.o -o %t1.32.so
11# RUN: llvm-mc -filetype=obj -triple=riscv32 %tga.s -o %tga.32.o
12## rv32 GD
13# RUN: ld.lld -shared %t.32.o %t1.32.o -o %t.32.so
14# RUN: llvm-readobj -r %t.32.so | FileCheck --check-prefix=GD32-REL %s
15# RUN: llvm-objdump -d --no-show-raw-insn %t.32.so | FileCheck --check-prefix=GD32 %s
16## rv32 GD -> LE
17# RUN: ld.lld %t.32.o %t1.32.o %tga.32.o -o %t.32
18# RUN: llvm-readelf -r %t.32 | FileCheck --check-prefix=NOREL %s
19# RUN: llvm-readelf -x .got %t.32 | FileCheck --check-prefix=LE32-GOT %s
20# RUN: ld.lld -pie %t.32.o %t1.32.o %tga.32.o -o %t.32
21# RUN: llvm-readelf -r %t.32 | FileCheck --check-prefix=NOREL %s
22# RUN: llvm-readelf -x .got %t.32 | FileCheck --check-prefix=LE32-GOT %s
23## rv32 GD -> IE
24# RUN: ld.lld %t.32.o %t1.32.so %tga.32.o -o %t.32
25# RUN: llvm-readobj -r %t.32 | FileCheck --check-prefix=IE32-REL %s
26# RUN: llvm-readelf -x .got %t.32 | FileCheck --check-prefix=IE32-GOT %s
27
28# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
29# RUN: llvm-mc -filetype=obj -triple=riscv64 %t.s -o %t1.64.o
30# RUN: ld.lld -shared -soname=t1.so %t1.64.o -o %t1.64.so
31# RUN: llvm-mc -filetype=obj -triple=riscv64 %tga.s -o %tga.64.o
32## rv64 GD
33# RUN: ld.lld -shared %t.64.o %t1.64.o -o %t.64.so
34# RUN: llvm-readobj -r %t.64.so | FileCheck --check-prefix=GD64-REL %s
35# RUN: llvm-objdump -d --no-show-raw-insn %t.64.so | FileCheck --check-prefix=GD64 %s
36## rv64 GD -> LE
37# RUN: ld.lld %t.64.o %t1.64.o %tga.64.o -o %t.64
38# RUN: llvm-readelf -r %t.64 | FileCheck --check-prefix=NOREL %s
39# RUN: llvm-readelf -x .got %t.64 | FileCheck --check-prefix=LE64-GOT %s
40# RUN: ld.lld -pie %t.64.o %t1.64.o %tga.64.o -o %t.64
41# RUN: llvm-readelf -r %t.64 | FileCheck --check-prefix=NOREL %s
42# RUN: llvm-readelf -x .got %t.64 | FileCheck --check-prefix=LE64-GOT %s
43## rv64 GD -> IE
44# RUN: ld.lld %t.64.o %t1.64.so %tga.64.o -o %t.64
45# RUN: llvm-readobj -r %t.64 | FileCheck --check-prefix=IE64-REL %s
46# RUN: llvm-readelf -x .got %t.64 | FileCheck --check-prefix=IE64-GOT %s
47
48# GD32-REL: .rela.dyn {
49# GD32-REL-NEXT: 0x2070 R_RISCV_TLS_DTPMOD32 a 0x0
50# GD32-REL-NEXT: 0x2074 R_RISCV_TLS_DTPREL32 a 0x0
51# GD32-REL-NEXT: 0x2078 R_RISCV_TLS_DTPMOD32 b 0x0
52# GD32-REL-NEXT: 0x207C R_RISCV_TLS_DTPREL32 b 0x0
53# GD32-REL-NEXT: }
54
55## &DTPMOD(a) - . = 0x2070 - 0x1000 = 4096*1+112
56# GD32: 1000: auipc a0, 1
57# GD32-NEXT: addi a0, a0, 112
58# GD32-NEXT: auipc ra, 0
59# GD32-NEXT: jalr 56(ra)
60
61## &DTPMOD(b) - . = 0x2078 - 0x1010 = 4096*1+104
62# GD32: 1010: auipc a0, 1
63# GD32-NEXT: addi a0, a0, 104
64# GD32-NEXT: auipc ra, 0
65# GD32-NEXT: jalr 40(ra)
66
67# GD64-REL: .rela.dyn {
68# GD64-REL-NEXT: 0x20E0 R_RISCV_TLS_DTPMOD64 a 0x0
69# GD64-REL-NEXT: 0x20E8 R_RISCV_TLS_DTPREL64 a 0x0
70# GD64-REL-NEXT: 0x20F0 R_RISCV_TLS_DTPMOD64 b 0x0
71# GD64-REL-NEXT: 0x20F8 R_RISCV_TLS_DTPREL64 b 0x0
72# GD64-REL-NEXT: }
73
74## &DTPMOD(a) - . = 0x20e0 - 0x1000 = 4096*1+224
75# GD64: 1000: auipc a0, 1
76# GD64-NEXT: addi a0, a0, 224
77# GD64-NEXT: auipc ra, 0
78# GD64-NEXT: jalr 56(ra)
79
80## &DTPMOD(b) - . = 0x20f0 - 0x1010 = 4096*1+224
81# GD64: 1010: auipc a0, 1
82# GD64-NEXT: addi a0, a0, 224
83# GD64-NEXT: auipc ra, 0
84# GD64-NEXT: jalr 40(ra)
85
86# NOREL: no relocations
87
88## .got contains pre-populated values: [a@dtpmod, a@dtprel, b@dtpmod, b@dtprel]
89## a@dtprel = st_value(a)-0x800 = 0xfffff808
90## b@dtprel = st_value(b)-0x800 = 0xfffff80c
91# LE32-GOT: section '.got':
92# LE32-GOT-NEXT: 0x{{[0-9a-f]+}} 01000000 08f8ffff 01000000 0cf8ffff
93# LE64-GOT: section '.got':
94# LE64-GOT-NEXT: 0x{{[0-9a-f]+}} 01000000 00000000 08f8ffff ffffffff
95# LE64-GOT-NEXT: 0x{{[0-9a-f]+}} 01000000 00000000 0cf8ffff ffffffff
96
97## a is local - relaxed to LE - its DTPMOD/DTPREL slots are link-time constants.
98## b is external - DTPMOD/DTPREL dynamic relocations are required.
99# IE32-REL: .rela.dyn {
100# IE32-REL-NEXT: 0x12068 R_RISCV_TLS_DTPMOD32 b 0x0
101# IE32-REL-NEXT: 0x1206C R_RISCV_TLS_DTPREL32 b 0x0
102# IE32-REL-NEXT: }
103# IE32-GOT: section '.got':
104# IE32-GOT-NEXT: 0x00012060 01000000 08f8ffff 00000000 00000000
105
106# IE64-REL: .rela.dyn {
107# IE64-REL-NEXT: 0x120D0 R_RISCV_TLS_DTPMOD64 b 0x0
108# IE64-REL-NEXT: 0x120D8 R_RISCV_TLS_DTPREL64 b 0x0
109# IE64-REL-NEXT: }
110# IE64-GOT: section '.got':
111# IE64-GOT-NEXT: 0x000120c0 01000000 00000000 08f8ffff ffffffff
112# IE64-GOT-NEXT: 0x000120d0 00000000 00000000 00000000 00000000
113
114la.tls.gd a0,a
115call __tls_get_addr@plt
116
117la.tls.gd a0,b
118call __tls_get_addr@plt
119
120.section .tbss
121.globl a
122.zero 8
123a:
124.zero 4
deps/lld/test/ELF/riscv-tls-ie.s created+82
......@@ -0,0 +1,82 @@
1# REQUIRES: riscv
2
3# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
4## rv32 IE
5# RUN: ld.lld -shared %t.32.o -o %t.32.so
6# RUN: llvm-readobj -r -d %t.32.so | FileCheck --check-prefix=IE32-REL %s
7# RUN: llvm-objdump -d --no-show-raw-insn %t.32.so | FileCheck --check-prefixes=IE,IE32 %s
8## rv32 IE -> LE
9# RUN: ld.lld %t.32.o -o %t.32
10# RUN: llvm-readelf -r %t.32 | FileCheck --check-prefix=NOREL %s
11# RUN: llvm-readelf -x .got %t.32 | FileCheck --check-prefix=LE32-GOT %s
12# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=LE,LE32 %s
13
14# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
15## rv64 IE
16# RUN: ld.lld -shared %t.64.o -o %t.64.so
17# RUN: llvm-readobj -r -d %t.64.so | FileCheck --check-prefix=IE64-REL %s
18# RUN: llvm-objdump -d --no-show-raw-insn %t.64.so | FileCheck --check-prefixes=IE,IE64 %s
19## rv64 IE -> LE
20# RUN: ld.lld %t.64.o -o %t.64
21# RUN: llvm-readelf -r %t.64 | FileCheck --check-prefix=NOREL %s
22# RUN: llvm-readelf -x .got %t.64 | FileCheck --check-prefix=LE64-GOT %s
23# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE,LE64 %s
24
25# IE32-REL: .rela.dyn {
26# IE32-REL-NEXT: 0x205C R_RISCV_TLS_TPREL32 - 0xC
27# IE32-REL-NEXT: 0x2058 R_RISCV_TLS_TPREL32 a 0x0
28# IE32-REL-NEXT: }
29# IE32-REL: FLAGS STATIC_TLS
30
31# IE64-REL: .rela.dyn {
32# IE64-REL-NEXT: 0x20B8 R_RISCV_TLS_TPREL64 - 0xC
33# IE64-REL-NEXT: 0x20B0 R_RISCV_TLS_TPREL64 a 0x0
34# IE64-REL-NEXT: }
35# IE64-REL: FLAGS STATIC_TLS
36
37## rv32: &.got[1] - . = 0x2058 - . = 4096*1+88
38## rv64: &.got[1] - . = 0x20B0 - . = 4096*1+176
39# IE: 1000: auipc a4, 1
40# IE32-NEXT: lw a4, 88(a4)
41# IE64-NEXT: ld a4, 176(a4)
42# IE-NEXT: add a4, a4, tp
43## rv32: &.got[0] - . = 0x205C - . = 4096*1+80
44## rv64: &.got[0] - . = 0x20B8 - . = 4096*1+172
45# IE: 100c: auipc a5, 1
46# IE32-NEXT: lw a5, 80(a5)
47# IE64-NEXT: ld a5, 172(a5)
48# IE-NEXT: add a5, a5, tp
49
50# NOREL: no relocations
51
52# a@tprel = st_value(a) = 0x8
53# b@tprel = st_value(a) = 0xc
54# LE32-GOT: section '.got':
55# LE32-GOT-NEXT: 0x00012000 08000000 0c000000
56# LE64-GOT: section '.got':
57# LE64-GOT-NEXT: 0x00012000 08000000 00000000 0c000000 00000000
58
59## rv32: &.got[0] - . = 0x12000 - 0x11000 = 4096*1+0
60## rv64: &.got[0] - . = 0x12000 - 0x11000 = 4096*1+0
61# LE: 11000: auipc a4, 1
62# LE32-NEXT: lw a4, 0(a4)
63# LE64-NEXT: ld a4, 0(a4)
64# LE-NEXT: add a4, a4, tp
65## rv32: &.got[1] - . = 0x12004 - 0x1100c = 4096*1-8
66## rv64: &.got[1] - . = 0x12008 - 0x1100c = 4096*1-4
67# LE: 1100c: auipc a5, 1
68# LE32-NEXT: lw a5, -8(a5)
69# LE64-NEXT: ld a5, -4(a5)
70# LE-NEXT: add a5, a5, tp
71
72la.tls.ie a4,a
73add a4,a4,tp
74la.tls.ie a5,b
75add a5,a5,tp
76
77.section .tbss
78.globl a
79.zero 8
80a:
81.zero 4
82b:
deps/lld/test/ELF/riscv-tls-ld.s created+90
......@@ -0,0 +1,90 @@
1# REQUIRES: riscv
2# RUN: echo '.tbss; .globl b, c; b: .zero 4; c:' > %t.s
3# RUN: echo '.globl __tls_get_addr; __tls_get_addr:' > %tga.s
4
5## RISC-V psABI doesn't specify TLS relaxation. Though the code sequences are not
6## relaxed, dynamic relocations can be omitted for LD->LE relaxation.
7## LD uses the same relocation as GD: R_RISCV_GD_HI20, the difference is that it
8## references a local symbol (.LANCHOR0).
9
10# RUN: llvm-mc -filetype=obj -triple=riscv32 -position-independent %s -o %t.32.o
11# RUN: llvm-mc -filetype=obj -triple=riscv32 %tga.s -o %tga.o
12## rv32 LD
13# RUN: ld.lld -shared %t.32.o -o %t.32.so
14# RUN: llvm-readobj -r %t.32.so | FileCheck --check-prefix=LD32-REL %s
15# RUN: llvm-readelf -x .got %t.32.so | FileCheck --check-prefix=LD32-GOT %s
16# RUN: llvm-objdump -d --no-show-raw-insn %t.32.so | FileCheck --check-prefixes=LD,LD32 %s
17## rv32 LD -> LE
18# RUN: ld.lld %t.32.o %tga.o -o %t.32
19# RUN: llvm-readelf -r %t.32 | FileCheck --check-prefix=NOREL %s
20# RUN: llvm-readelf -x .got %t.32 | FileCheck --check-prefix=LE32-GOT %s
21# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=LE,LE32 %s
22
23# RUN: llvm-mc -filetype=obj -triple=riscv64 -position-independent %s -o %t.64.o
24# RUN: llvm-mc -filetype=obj -triple=riscv64 %tga.s -o %tga.o
25## rv64 LD
26# RUN: ld.lld -shared %t.64.o -o %t.64.so
27# RUN: llvm-readobj -r %t.64.so | FileCheck --check-prefix=LD64-REL %s
28# RUN: llvm-readelf -x .got %t.64.so | FileCheck --check-prefix=LD64-GOT %s
29# RUN: llvm-objdump -d --no-show-raw-insn %t.64.so | FileCheck --check-prefixes=LD,LD64 %s
30## rv64 LD -> LE
31# RUN: ld.lld %t.64.o %tga.o -o %t.64
32# RUN: llvm-readelf -r %t.64 | FileCheck --check-prefix=NOREL %s
33# RUN: llvm-readelf -x .got %t.64 | FileCheck --check-prefix=LE64-GOT %s
34# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE,LE64 %s
35
36## a@dtprel = st_value(a)-0x800 = 0xfffff808 is a link-time constant.
37# LD32-REL: .rela.dyn {
38# LD32-REL-NEXT: 0x2084
39# LD32-REL-NEXT: 0x207C R_RISCV_TLS_DTPMOD32 - 0x0
40# LD32-REL-NEXT: }
41# LD32-GOT: section '.got':
42# LD32-GOT-NEXT: 0x00002078 00200000 00000000 00f8ffff 00000000
43
44# LD64-REL: .rela.dyn {
45# LD64-REL-NEXT: 0x2108
46# LD64-REL-NEXT: 0x20F8 R_RISCV_TLS_DTPMOD64 - 0x0
47# LD64-REL-NEXT: }
48# LD64-GOT: section '.got':
49# LD64-GOT-NEXT: 0x000020f0 00200000 00000000 00000000 00000000
50# LD64-GOT-NEXT: 0x00002100 00f8ffff ffffffff 00000000 00000000
51
52## rv32: &DTPMOD(a) - . = 0x207c - 0x1000 = 4096*1+124
53## rv64: &DTPMOD(a) - . = 0x20e0 - 0x1000 = 4096*1+248
54# LD: 1000: auipc a0, 1
55# LD32-NEXT: addi a0, a0, 124
56# LD64-NEXT: addi a0, a0, 248
57# LD-NEXT: auipc ra, 0
58# LD-NEXT: jalr 56(ra)
59
60# NOREL: no relocations
61
62## a is local - its DTPMOD/DTPREL slots are link-time constants.
63## a@dtpmod = 1 (main module)
64# LE32-GOT: section '.got':
65# LE32-GOT-NEXT: 0x00012000 00000000 01000000 00f8ffff 00200100
66
67# LE64-GOT: section '.got':
68# LE64-GOT-NEXT: 0x00012000 00000000 00000000 01000000 00000000
69# LE64-GOT-NEXT: 0x00012010 00f8ffff ffffffff 00200100 00000000
70
71## rv32: DTPMOD(.LANCHOR0) - . = 0x12004 - 0x11000 = 4096*1+4
72## rv64: DTPMOD(.LANCHOR0) - . = 0x12008 - 0x11000 = 4096*1+8
73# LE: 11000: auipc a0, 1
74# LE32-NEXT: addi a0, a0, 4
75# LE64-NEXT: addi a0, a0, 8
76# LE-NEXT: auipc ra, 0
77# LE-NEXT: jalr 24(ra)
78
79la.tls.gd a0, .LANCHOR0
80call __tls_get_addr@plt
81lw a4, 0(a0)
82lh a0, 4(a0)
83
84## This is irrelevant to TLS. We use it to take 2 GOT slots to check DTPREL
85## offsets are correct.
86la a5, _GLOBAL_OFFSET_TABLE_
87
88.section .tbss,"awT",@nobits
89.set .LANCHOR0, . + 0
90.zero 8
deps/lld/test/ELF/riscv-tls-le.s created+41
......@@ -0,0 +1,41 @@
1# REQUIRES: riscv
2
3# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o
4# RUN: ld.lld %t.32.o -o %t.32
5# RUN: llvm-nm -p %t.32 | FileCheck --check-prefixes=NM %s
6# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=LE %s
7# RUN: ld.lld -pie %t.32.o -o %t.32
8# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=LE %s
9
10# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o
11# RUN: ld.lld %t.64.o -o %t.64
12# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE %s
13# RUN: ld.lld -pie %t.64.o -o %t.64
14# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE %s
15
16# NM: {{0*}}00000008 b .LANCHOR0
17# NM: {{0*}}0000000c B a
18
19## .LANCHOR0@tprel = 8
20## a@tprel = 12
21# LE: lui a5, 0
22# LE-NEXT: add a5, a5, tp
23# LE-NEXT: addi a5, a5, 8
24# LE-NEXT: lui a5, 0
25# LE-NEXT: add a5, a5, tp
26# LE-NEXT: sw a0, 12(a5)
27
28lui a5, %tprel_hi(.LANCHOR0)
29add a5, a5, tp, %tprel_add(.LANCHOR0)
30addi a5, a5, %tprel_lo(.LANCHOR0)
31
32lui a5, %tprel_hi(a)
33add a5, a5, tp, %tprel_add(a)
34sw a0, %tprel_lo(a)(a5)
35
36.section .tbss
37.space 8
38.LANCHOR0:
39.zero 4
40.globl a
41a:
deps/lld/test/ELF/riscv32-reloc-32-pic.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: riscv
2# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.o
3# RUN: ld.lld -shared %t.o -o %t.so
4# RUN: llvm-nm %t.so | FileCheck --check-prefix=NM %s
5# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOC %s
6
7## R_RISCV_32 is an absolute relocation type.
8## In PIC mode, it creates a relative relocation if the symbol is non-preemptable.
9
10# NM: 00002004 d b
11
12# RELOC: .rela.dyn {
13# RELOC-NEXT: 0x2004 R_RISCV_RELATIVE - 0x2004
14# RELOC-NEXT: 0x2000 R_RISCV_32 a 0
15# RELOC-NEXT: }
16
17.globl a, b
18.hidden b
19
20.data
21.long a
22b:
23.long b
deps/lld/test/ELF/riscv64-reloc-64-pic.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: riscv
2# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o
3# RUN: ld.lld -shared %t.o -o %t.so
4# RUN: llvm-nm %t.so | FileCheck --check-prefix=NM %s
5# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOC %s
6
7## R_RISCV_64 is an absolute relocation type.
8## In PIC mode, it creates a relative relocation if the symbol is non-preemptable.
9
10# NM: 0000000000002008 d b
11
12# RELOC: .rela.dyn {
13# RELOC-NEXT: 0x2008 R_RISCV_RELATIVE - 0x2008
14# RELOC-NEXT: 0x2000 R_RISCV_64 a 0
15# RELOC-NEXT: }
16
17.globl a, b
18.hidden b
19
20.data
21.quad a
22b:
23.quad b
deps/lld/test/ELF/rodynamic.s+4-4
......@@ -4,13 +4,13 @@
44
55# RUN: ld.lld -shared %t.so.o -o %t.so
66# RUN: ld.lld %t.o %t.so -o %t.exe
7# RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=DEFDEBUG %s
8# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=DEFSEC %s
7# RUN: llvm-readobj --dynamic-table %t.exe | FileCheck -check-prefix=DEFDEBUG %s
8# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=DEFSEC %s
99
1010# RUN: ld.lld -shared -z rodynamic %t.so.o -o %t.so
1111# RUN: ld.lld -z rodynamic %t.o %t.so -o %t.exe
12# RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=RODEBUG %s
13# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=ROSEC %s
12# RUN: llvm-readobj --dynamic-table %t.exe | FileCheck -check-prefix=RODEBUG %s
13# RUN: llvm-readobj --sections %t.exe | FileCheck -check-prefix=ROSEC %s
1414
1515.globl _start
1616_start:
deps/lld/test/ELF/section-align-0.test+3-3
......@@ -15,6 +15,6 @@ Sections:
1515 AddressAlign: 0
1616
1717Symbols:
18 Global:
19 - Name: _start
20 Section: .text
18 - Name: _start
19 Section: .text
20 Binding: STB_GLOBAL
deps/lld/test/ELF/section-layout.s+5-4
......@@ -1,7 +1,7 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: ld.lld %t -o %tout
4# RUN: llvm-readobj -sections %tout | FileCheck %s
4# RUN: llvm-readobj --sections %tout | FileCheck %s
55
66# Check that sections are laid out in the correct order.
77
......@@ -32,6 +32,7 @@ _start:
3232// For non-executable and non-writable sections, PROGBITS appear after others.
3333// CHECK: Name: a
3434// CHECK: Name: b
35
3536// CHECK: Name: c
3637// CHECK: Name: d
3738
......@@ -40,13 +41,13 @@ _start:
4041// CHECK: Name: k
4142// CHECK: Name: l
4243
43// Writable sections appear before TLS and other relro sections.
44// CHECK: Name: i
45
4644// TLS sections are only sorted on NOBITS.
4745// CHECK: Name: e
4846// CHECK: Name: g
4947
48// Writable sections appear after TLS and other relro sections.
49// CHECK: Name: i
50
5051// CHECK: Name: j
5152
5253// Non allocated sections are in input order.
deps/lld/test/ELF/section-name.s+6-6
......@@ -45,12 +45,12 @@ _start:
4545// CHECK: 1 .rodata 00000002
4646// CHECK: 2 .gcc_except_table 00000001
4747// CHECK: 3 .text 00000002
48// CHECK: 4 .data 00000002
49// CHECK: 5 .foo.a 00000001
50// CHECK: 6 .foo 00000001
51// CHECK: 7 .tdata 00000001
52// CHECK: 8 .tbss 00000001
53// CHECK: 9 .data.rel.ro 00000004
48// CHECK: 4 .tdata 00000001
49// CHECK: 5 .tbss 00000001
50// CHECK: 6 .data.rel.ro 00000004
51// CHECK: 7 .data 00000002
52// CHECK: 8 .foo.a 00000001
53// CHECK: 9 .foo 00000001
5454// CHECK: 10 .bss 00000002
5555// CHECK: 11 .comment 00000008
5656// CHECK: 12 .symtab 00000030
deps/lld/test/ELF/section-symbol.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33// RUN: ld.lld %t -o %t.so -shared -discard-none
4// RUN: llvm-readobj -t %t.so | FileCheck %s
4// RUN: llvm-readobj --symbols %t.so | FileCheck %s
55
66// Test that we don't include the section symbols from the .o in the .so
77
deps/lld/test/ELF/section-symbols.test+8-9
......@@ -24,12 +24,11 @@ Sections:
2424 Info: .text
2525 Relocations:
2626Symbols:
27 Local:
28 - Type: STT_SECTION
29 Section: .rela.text
30 - Type: STT_SECTION
31 Section: .shstrtab
32 - Type: STT_SECTION
33 Section: .symtab
34 - Type: STT_SECTION
35 Section: .strtab
27 - Type: STT_SECTION
28 Section: .rela.text
29 - Type: STT_SECTION
30 Section: .shstrtab
31 - Type: STT_SECTION
32 Section: .symtab
33 - Type: STT_SECTION
34 Section: .strtab
deps/lld/test/ELF/sectionstart-noallochdr.s+1-1
......@@ -5,7 +5,7 @@
55# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
66
77# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address Type
8# CHECK-NEXT: Idx Name Size VMA Type
99# CHECK-NEXT: 0 00000000 0000000000000000
1010# CHECK-NEXT: 1 .text 00000001 0000000000000010 TEXT
1111# CHECK-NEXT: 2 .data 00000004 0000000000000020 DATA
deps/lld/test/ELF/sectionstart.s+4-4
......@@ -5,7 +5,7 @@
55# RUN: llvm-objdump -section-headers %t | FileCheck %s
66
77# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address Type
8# CHECK-NEXT: Idx Name Size VMA Type
99# CHECK-NEXT: 0 00000000 0000000000000000
1010# CHECK-NEXT: 1 .text 00000001 0000000000100000 TEXT
1111# CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA
......@@ -45,15 +45,15 @@
4545
4646# RUN: not ld.lld %t.o -Ttext=1w0000 -o %t6 2>&1 \
4747# RUN: | FileCheck -check-prefix=ERR3 %s
48# ERR3: invalid argument: --Ttext 1w0000
48# ERR3: invalid argument: -Ttext=1w0000
4949
5050# RUN: not ld.lld %t.o -Tbss=1w0000 -o %t6 2>&1 \
5151# RUN: | FileCheck -check-prefix=ERR4 %s
52# ERR4: invalid argument: --Tbss 1w0000
52# ERR4: invalid argument: -Tbss=1w0000
5353
5454# RUN: not ld.lld %t.o -Tdata=1w0000 -o %t6 2>&1 \
5555# RUN: | FileCheck -check-prefix=ERR5 %s
56# ERR5: invalid argument: --Tdata 1w0000
56# ERR5: invalid argument: -Tdata=1w0000
5757
5858.text
5959.globl _start
deps/lld/test/ELF/segments.s+46-2
......@@ -84,7 +84,7 @@
8484
8585# OMAGIC: ProgramHeader {
8686# OMAGIC: Type: PT_LOAD
87# OMAGIC-NEXT: Offset: 0x0
87# OMAGIC-NEXT: Offset: 0xE8
8888# OMAGIC-NEXT: VirtualAddress:
8989# OMAGIC-NEXT: PhysicalAddress:
9090# OMAGIC-NEXT: FileSize:
......@@ -94,11 +94,55 @@
9494# OMAGIC-NEXT: PF_W
9595# OMAGIC-NEXT: PF_X
9696# OMAGIC-NEXT: ]
97# OMAGIC-NEXT: Alignment: 4096
97# OMAGIC-NEXT: Alignment: 8
9898# OMAGIC-NEXT: }
9999# OMAGIC-NEXT: ProgramHeader {
100100# OMAGIC-NEXT: Type: PT_GNU_STACK
101101
102# RUN: ld.lld -n %t -o %t4
103# RUN: llvm-readobj --program-headers %t4 | FileCheck --check-prefix=NMAGIC %s
104# RUN: ld.lld --nmagic %t -o %t4
105# RUN: llvm-readobj --program-headers %t4 | FileCheck --check-prefix=NMAGIC %s
106
107# NMAGIC: ProgramHeader {
108# NMAGIC-NEXT: Type: PT_LOAD
109# NMAGIC-NEXT: Offset: 0x158
110# NMAGIC-NEXT: VirtualAddress:
111# NMAGIC-NEXT: PhysicalAddress:
112# NMAGIC-NEXT: FileSize: 1
113# NMAGIC-NEXT: MemSize: 1
114# NMAGIC-NEXT: Flags [
115# NMAGIC-NEXT: PF_R
116# NMAGIC-NEXT: ]
117# NMAGIC-NEXT: Alignment: 8
118# NMAGIC-NEXT: }
119# NMAGIC-NEXT: ProgramHeader {
120# NMAGIC-NEXT: Type: PT_LOAD
121# NMAGIC-NEXT: Offset: 0x15C
122# NMAGIC-NEXT: VirtualAddress:
123# NMAGIC-NEXT: PhysicalAddress:
124# NMAGIC-NEXT: FileSize: 2
125# NMAGIC-NEXT: MemSize: 2
126# NMAGIC-NEXT: Flags [
127# NMAGIC-NEXT: PF_R
128# NMAGIC-NEXT: PF_X
129# NMAGIC-NEXT: ]
130# NMAGIC-NEXT: Alignment: 4
131# NMAGIC-NEXT: }
132# NMAGIC-NEXT: ProgramHeader {
133# NMAGIC-NEXT: Type: PT_LOAD (0x1)
134# NMAGIC-NEXT: Offset: 0x15E
135# NMAGIC-NEXT: VirtualAddress:
136# NMAGIC-NEXT: PhysicalAddress:
137# NMAGIC-NEXT: FileSize: 1
138# NMAGIC-NEXT: MemSize: 1
139# NMAGIC-NEXT: Flags [
140# NMAGIC-NEXT: PF_R
141# NMAGIC-NEXT: PF_W
142# NMAGIC-NEXT: ]
143# NMAGIC-NEXT: Alignment: 1
144# NMAGIC-NEXT: }
145
102146.global _start
103147_start:
104148 nop
deps/lld/test/ELF/shared-ppc64.s+5-5
......@@ -4,13 +4,13 @@
44// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared.s -o %t2.o
55// RUN: ld.lld -shared %t2.o -o %t2.so
66// RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
7// RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s
7// RUN: llvm-readobj --dynamic-table -S %t | FileCheck %s
88
99// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
1010// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared.s -o %t2.o
1111// RUN: ld.lld -shared %t2.o -o %t2.so
1212// RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
13// RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s
13// RUN: llvm-readobj --dynamic-table -S %t | FileCheck %s
1414
1515// CHECK: Name: .rela.dyn
1616// CHECK-NEXT: Type: SHT_REL
......@@ -27,7 +27,7 @@
2727
2828// CHECK: DynamicSection [
2929// CHECK-NEXT: Tag Type Name/Value
30// CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar
30// CHECK-NEXT: 0x000000000000001D RUNPATH Library runpath: [foo:bar]
3131// CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so]
3232// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
3333// CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]]
......@@ -39,6 +39,6 @@
3939.global _start
4040_start:
4141.data
42.long bar
43.long zed
42.quad bar
43.quad zed
4444
deps/lld/test/ELF/shared.s+5-5
......@@ -2,11 +2,11 @@
22// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
33// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
44// RUN: ld.lld --hash-style=sysv -shared %t2.o -o %t2.so
5// RUN: llvm-readobj -s %t2.so | FileCheck --check-prefix=SO %s
5// RUN: llvm-readobj -S %t2.so | FileCheck --check-prefix=SO %s
66// RUN: ld.lld --hash-style=sysv -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
7// RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data -hash-table %t | FileCheck %s
7// RUN: llvm-readobj --program-headers --dynamic-table --symbols -S --dyn-syms --section-data --hash-table %t | FileCheck %s
88// RUN: ld.lld --hash-style=sysv %t.o %t2.so %t2.so -o %t2
9// RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s
9// RUN: llvm-readobj --dyn-syms %t2 | FileCheck --check-prefix=DONT_EXPORT %s
1010
1111// Make sure .symtab is properly aligned.
1212// SO: Name: .symtab
......@@ -46,7 +46,7 @@
4646// CHECK-NEXT: SHF_ALLOC
4747// CHECK-NEXT: ]
4848// CHECK-NEXT: Address: [[DYNSYMADDR:.*]]
49// CHECK-NEXT: Offset: 0x150
49// CHECK-NEXT: Offset: 0x170
5050// CHECK-NEXT: Size:
5151// CHECK-NEXT: Link: [[DYNSTR:.*]]
5252// CHECK-NEXT: Info: 1
......@@ -250,7 +250,7 @@
250250
251251// CHECK: DynamicSection [
252252// CHECK-NEXT: Tag Type Name/Value
253// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
253// CHECK-NEXT: 0x0000001D RUNPATH Library runpath: [foo:bar]
254254// CHECK-NEXT: 0x00000001 NEEDED Shared library: [{{.*}}2.so]
255255// CHECK-NEXT: 0x00000015 DEBUG 0x0
256256// CHECK-NEXT: 0x00000011 REL [[RELADDR]]
deps/lld/test/ELF/shf-info-link.test+3-3
......@@ -1,7 +1,7 @@
11# RUN: yaml2obj %s -o %t.o
22# RUN: yaml2obj %S/Inputs/shf-info-link.test -o %t2.o
33# RUN: ld.lld %t.o %t2.o -o %t3.o -r
4# RUN: llvm-readobj -s %t3.o | FileCheck %s
4# RUN: llvm-readobj -S %t3.o | FileCheck %s
55
66# CHECK-NOT: Name: .rela.text
77# CHECK: Name: .rela.text
......@@ -28,5 +28,5 @@ Sections:
2828 Symbol: foo
2929 Type: R_X86_64_64
3030Symbols:
31 Global:
32 - Name: foo
31 - Name: foo
32 Binding: STB_GLOBAL
deps/lld/test/ELF/sht-group-empty.test+5-5
......@@ -1,6 +1,6 @@
11# RUN: yaml2obj %s -o %t.o
22# RUN: ld.lld %t.o %t.o -o %t -r
3# RUN: llvm-readobj -s %t | FileCheck %s
3# RUN: llvm-readobj -S %t | FileCheck %s
44
55# CHECK: Name: .text.foo
66# CHECK: Name: .rela.text.foo
......@@ -49,7 +49,7 @@ Sections:
4949 Symbol: bar
5050 Type: R_X86_64_64
5151Symbols:
52 Global:
53 - Name: foo
54 - Name: bar
55
52 - Name: foo
53 Binding: STB_GLOBAL
54 - Name: bar
55 Binding: STB_GLOBAL
deps/lld/test/ELF/silent-ignore.test+3
......@@ -6,8 +6,11 @@ RUN: -no-allow-shlib-undefined \
66RUN: -no-copy-dt-needed-entries \
77RUN: -no-ctors-in-init-array \
88RUN: -no-keep-memory \
9RUN: -no-pipeline-knowledge \
910RUN: -no-warn-common \
1011RUN: -no-warn-mismatch \
12RUN: -p \
13RUN: -secure-plt \
1114RUN: -sort-common \
1215RUN: -stats \
1316RUN: -warn-execstack \
deps/lld/test/ELF/sort-norosegment.s+1-1
......@@ -8,8 +8,8 @@
88# CHECK-NEXT: .hash {{.*}} A
99# CHECK-NEXT: .dynstr {{.*}} A
1010# CHECK-NEXT: .text {{.*}} AX
11# CHECK-NEXT: foo {{.*}} WA
1211# CHECK-NEXT: .dynamic {{.*}} WA
12# CHECK-NEXT: foo {{.*}} WA
1313
1414.section foo, "aw"
1515.byte 0
deps/lld/test/ELF/start-lib-comdat.s+2-2
......@@ -4,9 +4,9 @@
44// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
55// RUN: %p/Inputs/start-lib-comdat.s -o %t2.o
66// RUN: ld.lld -shared -o %t3 %t1.o --start-lib %t2.o --end-lib
7// RUN: llvm-readobj -t %t3 | FileCheck %s
7// RUN: llvm-readobj --symbols %t3 | FileCheck %s
88// RUN: ld.lld -shared -o %t3 --start-lib %t2.o --end-lib %t1.o
9// RUN: llvm-readobj -t %t3 | FileCheck %s
9// RUN: llvm-readobj --symbols %t3 | FileCheck %s
1010
1111// CHECK: Name: zed
1212// CHECK-NEXT: Value:
deps/lld/test/ELF/startstop-gccollect.s+4
......@@ -20,10 +20,14 @@
2020# DISASM: _start:
2121# DISASM-NEXT: 201000: e8 05 00 00 00 callq 5 <__start_foo>
2222# DISASM-NEXT: 201005: e8 02 00 00 00 callq 2 <__stop_bar>
23# DISASM-EMPTY:
2324# DISASM-NEXT: Disassembly of section foo:
25# DISASM-EMPTY:
2426# DISASM-NEXT: __start_foo:
2527# DISASM-NEXT: 20100a: 90 nop
28# DISASM-EMPTY:
2629# DISASM-NEXT: Disassembly of section bar:
30# DISASM-EMPTY:
2731# DISASM-NEXT: bar:
2832# DISASM-NEXT: 20100b: 90 nop
2933
deps/lld/test/ELF/startstop-shared.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -r -t %t.so | FileCheck %s
4// RUN: llvm-readobj -r --symbols %t.so | FileCheck %s
55
66 .data
77 .quad __start_foo
deps/lld/test/ELF/startstop.s+5-3
......@@ -2,18 +2,20 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld --hash-style=sysv %t -o %tout -shared
44// RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
5// RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s
5// RUN: llvm-readobj --symbols -r %tout | FileCheck -check-prefix=SYMBOL %s
66
77// DISASM: _start:
88// DISASM: 1000: {{.*}} callq 10
99// DISASM: 1005: {{.*}} callq 8
1010// DISASM: 100a: {{.*}} callq 3
1111// DISASM: Disassembly of section foo:
12// DISASM-EMPTY:
1213// DISASM: __start_foo:
1314// DISASM: 100f: 90 nop
1415// DISASM: 1010: 90 nop
1516// DISASM: 1011: 90 nop
1617// DISASM: Disassembly of section bar:
18// DISASM-EMPTY:
1719// DISASM: __start_bar:
1820// DISASM: 1012: 90 nop
1921// DISASM: 1013: 90 nop
......@@ -50,13 +52,13 @@
5052
5153// SYMBOL: Symbol {
5254// SYMBOL: Name: __stop_zed1
53// SYMBOL: Value: 0x2010
55// SYMBOL: Value: 0x3010
5456// SYMBOL: STV_PROTECTED
5557// SYMBOL: Section: zed1
5658// SYMBOL: }
5759// SYMBOL: Symbol {
5860// SYMBOL: Name: __stop_zed2
59// SYMBOL: Value: 0x2020
61// SYMBOL: Value: 0x3020
6062// SYMBOL: STV_PROTECTED
6163// SYMBOL: Section: zed2
6264// SYMBOL: }
deps/lld/test/ELF/static-with-export-dynamic.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i686-unknown-cloudabi %s -o %t.o
33// RUN: ld.lld --export-dynamic %t.o -o %t
4// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
4// RUN: llvm-readobj --dyn-syms %t | FileCheck %s
55
66// Ensure that a dynamic symbol table is present when --export-dynamic
77// is passed in, even when creating statically linked executables.
deps/lld/test/ELF/stdout.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o - > %t1
5# RUN: llvm-objdump -d %t1 | FileCheck %s
6
7# CHECK: 0000000000201000 _start:
8# CHECK: 201000: 90 nop
9
10# RUN: ld.lld %t.o -o %t2
11# RUN: diff %t1 %t2
12
13.globl _start
14_start:
15 nop
deps/lld/test/ELF/string-gc.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 -o %t --gc-sections
4// RUN: llvm-readobj -symbols %t | FileCheck %s
4// RUN: llvm-readobj --symbols %t | FileCheck %s
55
66// CHECK: Symbols [
77// CHECK-NEXT: Symbol {
deps/lld/test/ELF/string-table.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %t2
4// RUN: llvm-readobj -sections %t2 | FileCheck %s
4// RUN: llvm-readobj --sections %t2 | FileCheck %s
55
66.global _start
77_start:
deps/lld/test/ELF/strip-debug.s+3-3
......@@ -1,11 +1,11 @@
11# 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
4# RUN: llvm-readobj -sections %t2 | FileCheck %s
4# RUN: llvm-readobj --sections %t2 | FileCheck %s
55# RUN: ld.lld %t -o %t2 -S
6# RUN: llvm-readobj -sections %t2 | FileCheck %s
6# RUN: llvm-readobj --sections %t2 | FileCheck %s
77# RUN: ld.lld %t -o %t2 --strip-all
8# RUN: llvm-readobj -sections %t2 | FileCheck %s
8# RUN: llvm-readobj --sections %t2 | FileCheck %s
99
1010# CHECK-NOT: Foo
1111# CHECK-NOT: Bar
deps/lld/test/ELF/symbol-ordering-file-cgprofile-conflicts.s created+66
......@@ -0,0 +1,66 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3// RUN: ld.lld -e A %t.o --no-call-graph-profile-sort -o %t
4// RUN: llvm-nm --numeric-sort %t | FileCheck %s --check-prefix=NO_ORDERING
5// NO_ORDERING: 0000000000201000 t D
6// NO_ORDERING-NEXT: 0000000000201001 T C
7// NO_ORDERING-NEXT: 0000000000201002 T B
8// NO_ORDERING-NEXT: 0000000000201003 T A
9
10// RUN: ld.lld -e A %t.o -o %t
11// RUN: llvm-nm --numeric-sort %t | FileCheck %s --check-prefix=CALL_GRAPH
12// CALL_GRAPH: 0000000000201000 T A
13// CALL_GRAPH-NEXT: 0000000000201000 t Aa
14// CALL_GRAPH-NEXT: 0000000000201001 T B
15// CALL_GRAPH-NEXT: 0000000000201002 T C
16// CALL_GRAPH-NEXT: 0000000000201003 t D
17
18// RUN: rm -f %t.symbol_order
19// RUN: echo "C" >> %t.symbol_order
20// RUN: echo "B" >> %t.symbol_order
21// RUN: echo "D" >> %t.symbol_order
22// RUN: echo "A" >> %t.symbol_order
23
24// RUN: ld.lld -e A %t.o --symbol-ordering-file %t.symbol_order -o %t
25// RUN: llvm-nm --numeric-sort %t | FileCheck %s --check-prefix=SYMBOL_ORDER
26// SYMBOL_ORDER: 0000000000201000 T C
27// SYMBOL_ORDER-NEXT: 0000000000201001 T B
28// SYMBOL_ORDER-NEXT: 0000000000201002 t D
29// SYMBOL_ORDER-NEXT: 0000000000201003 T A
30
31// RUN: rm -f %t.call_graph
32// RUN: echo "A B 5" > %t.call_graph
33// RUN: echo "B C 50" >> %t.call_graph
34// RUN: echo "C D 40" >> %t.call_graph
35// RUN: echo "D B 10" >> %t.call_graph
36
37// RUN: not ld.lld -e A %t.o --symbol-ordering-file %t.symbol_order --call-graph-ordering-file %t.call_graph -o %t 2>&1 | FileCheck %s
38// RUN: not ld.lld -e A %t.o --call-graph-ordering-file %t.call_graph --symbol-ordering-file %t.symbol_order -o %t 2>&1 | FileCheck %s
39// CHECK: error: --symbol-ordering-file and --call-graph-order-file may not be used together
40
41 .section .text.D,"ax",@progbits
42D:
43 retq
44
45 .section .text.C,"ax",@progbits
46 .globl C
47C:
48 retq
49
50 .section .text.B,"ax",@progbits
51 .globl B
52B:
53 retq
54
55 .section .text.A,"ax",@progbits
56 .globl A
57A:
58Aa:
59 retq
60
61 .cg_profile A, B, 10
62 .cg_profile A, B, 10
63 .cg_profile Aa, B, 80
64 .cg_profile A, C, 40
65 .cg_profile B, C, 30
66 .cg_profile C, D, 90
deps/lld/test/ELF/symbol-override.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/symbol-override.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld %t1.o %t2.so -o %t
6// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
6// RUN: llvm-readobj --dyn-syms %t | FileCheck %s
77
88// CHECK: DynamicSymbols [
99// CHECK-NEXT: Symbol {
deps/lld/test/ELF/symbols.s+1-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %t2
4// RUN: llvm-readobj -symbols -sections %t2 | FileCheck %s
4// RUN: llvm-readobj --symbols --sections %t2 | FileCheck %s
55
66.type _start, @function
77.globl _start
deps/lld/test/ELF/synthetic-got.s+7-7
......@@ -7,13 +7,13 @@
77# RUN: | FileCheck %s --check-prefix=GOTDATA
88
99# GOT: Sections:
10# GOT: 8 .got.plt 00000020 00000000000000e0 DATA
11# GOT: 10 .got 00000008 00000000000001d0 DATA
12# GOTDATA: Contents of section .got.plt:
13# GOTDATA-NEXT: 00e0 00010000 00000000 00000000 00000000
14# GOTDATA-NEXT: 00f0 00000000 00000000 d6000000 00000000
15# GOTDATA-NEXT: Contents of section .got:
16# GOTDATA-NEXT: 01d0 00000000 00000000
10# GOT: 9 .got 00000008 00000000000001b0 DATA
11# GOT: 10 .got.plt 00000020 00000000000001b8 DATA
12# GOTDATA: Contents of section .got:
13# GOTDATA-NEXT: 01b0 00000000 00000000
14# GOTDATA-NEXT: Contents of section .got.plt:
15# GOTDATA-NEXT: 01b8 e0000000 00000000 00000000 00000000
16# GOTDATA-NEXT: 01c8 00000000 00000000 d6000000 00000000
1717
1818# RUN: echo "SECTIONS { .mygot : { *(.got) *(.got.plt) } }" > %t1.script
1919# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t1.out --script %t1.script
deps/lld/test/ELF/sysv-hash-no-rosegment.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 -shared --no-rosegment -o %t %t.o
4# RUN: llvm-readobj -hash-table %t | FileCheck %s
4# RUN: llvm-readobj --hash-table %t | FileCheck %s
55
66# CHECK: HashTable {
77# CHECK-NEXT: Num Buckets: 2
deps/lld/test/ELF/tail-merge-string-align.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 -o %t.so -shared -O3
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -S --section-data %t.so | FileCheck %s
55
66 .section .rodata.4a,"aMS",@progbits,1
77 .align 4
deps/lld/test/ELF/tls-align.s deleted-21
......@@ -1,21 +0,0 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld %t -o %tout -shared
4// RUN: llvm-readobj -program-headers %tout | FileCheck %s
5
6 .section .tbss,"awT",@nobits
7 .align 8
8 .long 0
9
10// CHECK: ProgramHeader {
11// CHECK: Type: PT_TLS
12// CHECK-NEXT: Offset:
13// CHECK-NEXT: VirtualAddress:
14// CHECK-NEXT: PhysicalAddress:
15// CHECK-NEXT: FileSize: 0
16// CHECK-NEXT: MemSize: 8
17// CHECK-NEXT: Flags [
18// CHECK-NEXT: PF_R (0x4)
19// CHECK-NEXT: ]
20// CHECK-NEXT: Alignment: 8
21// CHECK-NEXT: }
deps/lld/test/ELF/tls-dynamic-i686.s+26-25
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t
3// RUN: ld.lld --hash-style=sysv -shared %t -o %tout
4// RUN: llvm-readobj -sections -relocations %tout | FileCheck %s
3// RUN: ld.lld --hash-style=sysv -shared -z norelro %t -o %tout
4// RUN: llvm-readobj --sections -r %tout | FileCheck %s
55// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
66
77.type tls0,@object
......@@ -56,8 +56,8 @@ addl tls1@gotntpoff(%ebx),%eax
5656// CHECK-NEXT: SHF_ALLOC
5757// CHECK-NEXT: SHF_WRITE
5858// CHECK-NEXT: ]
59// CHECK-NEXT: Address: 0x3068
60// CHECK-NEXT: Offset: 0x3068
59// CHECK-NEXT: Address: 0x2070
60// CHECK-NEXT: Offset: 0x2070
6161// CHECK-NEXT: Size: 32
6262// CHECK-NEXT: Link: 0
6363// CHECK-NEXT: Info: 0
......@@ -66,34 +66,35 @@ addl tls1@gotntpoff(%ebx),%eax
6666
6767// CHECK: Relocations [
6868// CHECK: Section ({{.+}}) .rel.dyn {
69// CHECK-NEXT: 0x3078 R_386_TLS_DTPMOD32 - 0x0
70// CHECK-NEXT: 0x3068 R_386_TLS_DTPMOD32 tls0 0x0
71// CHECK-NEXT: 0x306C R_386_TLS_DTPOFF32 tls0 0x0
72// CHECK-NEXT: 0x3080 R_386_TLS_TPOFF tls0 0x0
73// CHECK-NEXT: 0x3070 R_386_TLS_DTPMOD32 tls1 0x0
74// CHECK-NEXT: 0x3074 R_386_TLS_DTPOFF32 tls1 0x0
75// CHECK-NEXT: 0x3084 R_386_TLS_TPOFF tls1 0x0
69// CHECK-NEXT: 0x2080 R_386_TLS_DTPMOD32 - 0x0
70// CHECK-NEXT: 0x2070 R_386_TLS_DTPMOD32 tls0 0x0
71// CHECK-NEXT: 0x2074 R_386_TLS_DTPOFF32 tls0 0x0
72// CHECK-NEXT: 0x2088 R_386_TLS_TPOFF tls0 0x0
73// CHECK-NEXT: 0x2078 R_386_TLS_DTPMOD32 tls1 0x0
74// CHECK-NEXT: 0x207C R_386_TLS_DTPOFF32 tls1 0x0
75// CHECK-NEXT: 0x208C R_386_TLS_TPOFF tls1 0x0
7676// CHECK-NEXT: }
7777
7878// DIS: Disassembly of section .text:
79// DIS-EMPTY:
7980// DIS-NEXT: _start:
8081// General dynamic model:
8182// -32 and -24 are first and second GOT entries offsets.
8283// Each one is a pair of records.
83// DIS-NEXT: 1000: 8d 04 1d e0 ff ff ff leal -32(,%ebx), %eax
84// DIS-NEXT: 1007: e8 64 00 00 00 calll 100
85// DIS-NEXT: 100c: 8d 04 1d e8 ff ff ff leal -24(,%ebx), %eax
86// DIS-NEXT: 1013: e8 58 00 00 00 calll 88
84// DIS-NEXT: 1000: {{.*}} leal -32(,%ebx), %eax
85// DIS-NEXT: 1007: {{.*}} calll 100
86// DIS-NEXT: 100c: {{.*}} leal -24(,%ebx), %eax
87// DIS-NEXT: 1013: {{.*}} calll 88
8788// Local dynamic model:
8889// -16 is a local module tls index offset.
89// DIS-NEXT: 1018: 8d 83 f0 ff ff ff leal -16(%ebx), %eax
90// DIS-NEXT: 101e: e8 4d 00 00 00 calll 77
91// DIS-NEXT: 1023: 8d 90 08 00 00 00 leal 8(%eax), %edx
92// DIS-NEXT: 1029: 8d 83 f0 ff ff ff leal -16(%ebx), %eax
93// DIS-NEXT: 102f: e8 3c 00 00 00 calll 60
94// DIS-NEXT: 1034: 8d 90 0c 00 00 00 leal 12(%eax), %edx
90// DIS-NEXT: 1018: {{.*}} leal -16(%ebx), %eax
91// DIS-NEXT: 101e: {{.*}} calll 77
92// DIS-NEXT: 1023: {{.*}} leal 8(%eax), %edx
93// DIS-NEXT: 1029: {{.*}} leal -16(%ebx), %eax
94// DIS-NEXT: 102f: {{.*}} calll 60
95// DIS-NEXT: 1034: {{.*}} leal 12(%eax), %edx
9596// Initial exec model:
96// DIS-NEXT: 103a: 65 a1 00 00 00 00 movl %gs:0, %eax
97// DIS-NEXT: 1040: 03 83 f8 ff ff ff addl -8(%ebx), %eax
98// DIS-NEXT: 1046: 65 a1 00 00 00 00 movl %gs:0, %eax
99// DIS-NEXT: 104c: 03 83 fc ff ff ff addl -4(%ebx), %eax
97// DIS-NEXT: 103a: {{.*}} movl %gs:0, %eax
98// DIS-NEXT: 1040: {{.*}} addl -8(%ebx), %eax
99// DIS-NEXT: 1046: {{.*}} movl %gs:0, %eax
100// DIS-NEXT: 104c: {{.*}} addl -4(%ebx), %eax
deps/lld/test/ELF/tls-dynamic.s+15-14
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld --hash-style=sysv -shared %t -o %tout
4// RUN: llvm-readobj -sections -relocations %tout | FileCheck %s
4// RUN: llvm-readobj --sections -r %tout | FileCheck %s
55// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
66
77 leaq a@tlsld(%rip), %rdi
......@@ -48,28 +48,29 @@ c:
4848// CHECK-NEXT: SHF_ALLOC
4949// CHECK-NEXT: SHF_WRITE
5050// CHECK-NEXT: ]
51// CHECK-NEXT: Address: 0x30D0
51// CHECK-NEXT: Address: 0x20E0
5252// CHECK-NEXT: Offset:
5353// CHECK-NEXT: Size: 40
5454
5555// CHECK: Relocations [
5656// CHECK: Section ({{.+}}) .rela.dyn {
57// CHECK-NEXT: 0x30D0 R_X86_64_DTPMOD64 - 0x0
58// CHECK-NEXT: 0x30E0 R_X86_64_DTPMOD64 c 0x0
59// CHECK-NEXT: 0x30E8 R_X86_64_DTPOFF64 c 0x0
60// CHECK-NEXT: 0x30F0 R_X86_64_TPOFF64 c 0x0
57// CHECK-NEXT: 0x20E0 R_X86_64_DTPMOD64 - 0x0
58// CHECK-NEXT: 0x20F0 R_X86_64_DTPMOD64 c 0x0
59// CHECK-NEXT: 0x20F8 R_X86_64_DTPOFF64 c 0x0
60// CHECK-NEXT: 0x2100 R_X86_64_TPOFF64 c 0x0
6161// CHECK-NEXT: }
6262
63// 4297 = (0x20D0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
64// 4285 = (0x20D0 + -4) - (0x100c + 3) // PC relative offset to got entry.
65// 4267 = (0x20E0 + -4) - (0x102e + 3) // PC relative offset to got entry.
66// 4263 = (0x20F0 + -4) - (0x1042 + 3) // PC relative offset to got entry.
63// 4313 = (0x20E0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
64// 4301 = (0x20F0 + -4) - (0x100c + 3) // PC relative offset to got entry.
65// 4283 = (0x20F8 + -4) - (0x102e + 3) // PC relative offset to got entry.
66// 4279 = (0x2100 + -4) - (0x1042 + 3) // PC relative offset to got entry.
6767
6868// DIS: Disassembly of section .text:
69// DIS-EMPTY:
6970// DIS-NEXT: .text:
70// DIS-NEXT: 1000: {{.+}} leaq 8393(%rip), %rdi
71// DIS-NEXT: 1000: {{.+}} leaq 4313(%rip), %rdi
7172// DIS-NEXT: 1007: {{.+}} callq
72// DIS-NEXT: 100c: {{.+}} leaq 8381(%rip), %rdi
73// DIS-NEXT: 100c: {{.+}} leaq 4301(%rip), %rdi
7374// DIS-NEXT: 1013: {{.+}} callq
7475// DIS-NEXT: 1018: {{.+}} leaq (%rax), %rcx
7576// DIS-NEXT: 101f: {{.+}} leaq 4(%rax), %rcx
......@@ -77,10 +78,10 @@ c:
7778// DIS-NEXT: 1028: 00 00
7879// DIS-NEXT: 102a: 00 00
7980// DIS-NEXT: 102c: 00 00
80// DIS-NEXT: 102e: {{.+}} leaq 8363(%rip), %rdi
81// DIS-NEXT: 102e: {{.+}} leaq 4283(%rip), %rdi
8182// DIS-NEXT: 1035: {{.+}} callq
8283// DIS-NEXT: 103b: {{.+}} leaq (%rax), %rcx
83// DIS-NEXT: 1042: {{.+}} movq 8359(%rip), %rax
84// DIS-NEXT: 1042: {{.+}} movq 4279(%rip), %rax
8485// DIS-NEXT: 1049: {{.+}} movq %fs:(%rax), %rax
8586// DIS-NEXT: 104d: {{.+}} movabsq $0, %rax
8687// DIS-NEXT: 1057: {{.+}} movabsq $4, %rax
deps/lld/test/ELF/tls-got.s+17-16
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got.s -o %t2.o
44// RUN: ld.lld -shared %t2.o -o %t2.so
55// RUN: ld.lld --hash-style=sysv -e main %t1.o %t2.so -o %t3
6// RUN: llvm-readobj -s -r %t3 | FileCheck %s
6// RUN: llvm-readobj -S -r %t3 | FileCheck %s
77// RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM %s
88
99// CHECK: Section {
......@@ -15,7 +15,7 @@
1515// CHECK-NEXT: SHF_WRITE
1616// CHECK-NEXT: ]
1717// CHECK-NEXT: Address: [[ADDR:.*]]
18// CHECK-NEXT: Offset: 0x20B0
18// CHECK-NEXT: Offset: 0x20C0
1919// CHECK-NEXT: Size: 16
2020// CHECK-NEXT: Link: 0
2121// CHECK-NEXT: Info: 0
......@@ -25,23 +25,24 @@
2525
2626// CHECK: Relocations [
2727// CHECK-NEXT: Section (4) .rela.dyn {
28// CHECK-NEXT: 0x2020B8 R_X86_64_TPOFF64 tls0 0x0
29// CHECK-NEXT: 0x2020B0 R_X86_64_TPOFF64 tls1 0x0
28// CHECK-NEXT: 0x2020C8 R_X86_64_TPOFF64 tls0 0x0
29// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
3030// CHECK-NEXT: }
3131// CHECK-NEXT: ]
3232
33//0x201000 + 4265 + 7 = 0x2020B0
34//0x20100A + 4263 + 7 = 0x2020B8
35//0x201014 + 4253 + 7 = 0x2020B8
36//DISASM: Disassembly of section .text:
37//DISASM-NEXT: main:
38//DISASM-NEXT: 201000: 48 8b 05 a9 10 00 00 movq 4265(%rip), %rax
39//DISASM-NEXT: 201007: 64 8b 00 movl %fs:(%rax), %eax
40//DISASM-NEXT: 20100a: 48 8b 05 a7 10 00 00 movq 4263(%rip), %rax
41//DISASM-NEXT: 201011: 64 8b 00 movl %fs:(%rax), %eax
42//DISASM-NEXT: 201014: 48 8b 05 9d 10 00 00 movq 4253(%rip), %rax
43//DISASM-NEXT: 20101b: 64 8b 00 movl %fs:(%rax), %eax
44//DISASM-NEXT: 20101e: c3 retq
33// 0x201000 + 4281 + 7 = 0x2020C0
34// 0x20100A + 4279 + 7 = 0x2020C8
35// 0x201014 + 4269 + 7 = 0x2020C8
36// DISASM: Disassembly of section .text:
37// DISASM-EMPTY:
38// DISASM-NEXT: main:
39// DISASM-NEXT: 201000: {{.*}} movq 4281(%rip), %rax
40// DISASM-NEXT: 201007: {{.*}} movl %fs:(%rax), %eax
41// DISASM-NEXT: 20100a: {{.*}} movq 4279(%rip), %rax
42// DISASM-NEXT: 201011: {{.*}} movl %fs:(%rax), %eax
43// DISASM-NEXT: 201014: {{.*}} movq 4269(%rip), %rax
44// DISASM-NEXT: 20101b: {{.*}} movl %fs:(%rax), %eax
45// DISASM-NEXT: 20101e: {{.*}} retq
4546
4647.section .tdata,"awT",@progbits
4748
deps/lld/test/ELF/tls-i686.s+2
......@@ -31,6 +31,7 @@ _start:
3131 leal var1@ntpoff+123(%ecx), %eax
3232
3333// DIS: Disassembly of section test:
34// DIS-EMPTY:
3435// DIS-NEXT: _start:
3536// DIS-NEXT: 401000: ba 08 00 00 00 movl $8, %edx
3637// DIS-NEXT: 401005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
......@@ -47,6 +48,7 @@ _start:
4748// RELOC-NEXT: ]
4849
4950// DISSHARED: Disassembly of section test:
51// DISSHARED-EMPTY:
5052// DISSHARED-NEXT: _start:
5153// DISSHARED-NEXT: 1000: ba 00 00 00 00 movl $0, %edx
5254// DISSHARED-NEXT: 1005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
deps/lld/test/ELF/tls-initial-exec-local.s+9-8
......@@ -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 --hash-style=sysv -shared %t.o -o %t
4// RUN: llvm-readobj -r -s %t | FileCheck %s
4// RUN: llvm-readobj -r -S %t | FileCheck %s
55// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
66
77// CHECK: Name: .got
......@@ -10,21 +10,22 @@
1010// CHECK-NEXT: SHF_ALLOC (0x2)
1111// CHECK-NEXT: SHF_WRITE (0x1)
1212// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x2090
13// CHECK-NEXT: Address: 0x20A0
1414
1515// CHECK: Relocations [
1616// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
17// CHECK-NEXT: 0x2090 R_X86_64_TPOFF64 - 0x0
18// CHECK-NEXT: 0x2098 R_X86_64_TPOFF64 - 0x4
17// CHECK-NEXT: 0x20A0 R_X86_64_TPOFF64 - 0x0
18// CHECK-NEXT: 0x20A8 R_X86_64_TPOFF64 - 0x4
1919// CHECK-NEXT: }
2020// CHECK-NEXT: ]
2121
22// 0x1007 + 4233 = 0x2090
23// 0x100e + 4234 = 0x2098
22// 0x1007 + 4249 = 0x20A0
23// 0x100e + 4250 = 0x20A8
2424// DISASM: Disassembly of section .text:
25// DISASM-EMPTY:
2526// DISASM-NEXT: .text:
26// DISASM-NEXT: 1000: {{.*}} addq 4233(%rip), %rax
27// DISASM-NEXT: 1007: {{.*}} addq 4234(%rip), %rax
27// DISASM-NEXT: 1000: {{.*}} addq 4249(%rip), %rax
28// DISASM-NEXT: 1007: {{.*}} addq 4250(%rip), %rax
2829
2930 addq foo@GOTTPOFF(%rip), %rax
3031 addq bar@GOTTPOFF(%rip), %rax
deps/lld/test/ELF/tls-offset.s+2-2
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -s %tout | FileCheck %s
4// RUN: llvm-readobj -S %tout | FileCheck %s
55// RUN: echo "SECTIONS { \
66// RUN: . = 0x201000; \
77// RUN: .text : { *(.text) } \
......@@ -12,7 +12,7 @@
1212// RUN: }" > %t.script
1313// RUN: ld.lld -T %t.script %t -o %tout2
1414// RUN: echo SCRIPT
15// RUN: llvm-readobj -s %tout2 | FileCheck %s
15// RUN: llvm-readobj -S %tout2 | FileCheck %s
1616 .global _start
1717_start:
1818 retq
deps/lld/test/ELF/tls-opt-gdie.s+2-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o
44// RUN: ld.lld -shared %tso.o -o %t.so
55// RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t1
6// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=RELOC %s
6// RUN: llvm-readobj -S -r %t1 | FileCheck --check-prefix=RELOC %s
77// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
88
99//RELOC: Section {
......@@ -32,6 +32,7 @@
3232//0x201009 + (4256 + 7) = 0x2020B0
3333//0x201019 + (4248 + 7) = 0x2020B8
3434// DISASM: Disassembly of section .text:
35// DISASM-EMPTY:
3536// DISASM-NEXT: _start:
3637// DISASM-NEXT: 201000: {{.*}} movq %fs:0, %rax
3738// DISASM-NEXT: 201009: {{.*}} addq 4256(%rip), %rax
deps/lld/test/ELF/tls-opt-gdiele-i686.s+4-3
......@@ -14,11 +14,12 @@
1414// NORELOC-NEXT: ]
1515
1616// DISASM: Disassembly of section .text:
17// DISASM-EMPTY:
1718// DISASM-NEXT: _start:
1819// 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: 401006: 03 83 58 f0 ff ff addl -4008(%ebx), %eax
2021// 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: 401012: 03 83 5c f0 ff ff addl -4004(%ebx), %eax
2223// DISASM-NEXT: 401018: 65 a1 00 00 00 00 movl %gs:0, %eax
2324// DISASM-NEXT: 40101e: 81 e8 08 00 00 00 subl $8, %eax
2425// DISASM-NEXT: 401024: 65 a1 00 00 00 00 movl %gs:0, %eax
......@@ -53,7 +54,7 @@ leal tlsshared0@tlsgd(,%ebx,1),%eax
5354call ___tls_get_addr@plt
5455leal tlsshared1@tlsgd(,%ebx,1),%eax
5556call ___tls_get_addr@plt
56//GD->IE
57//GD->LE
5758leal tlsexe1@tlsgd(,%ebx,1),%eax
5859call ___tls_get_addr@plt
5960leal tlsexe2@tlsgd(,%ebx,1),%eax
deps/lld/test/ELF/tls-opt-i686.s+1
......@@ -8,6 +8,7 @@
88// NORELOC-NEXT: ]
99
1010// DISASM: Disassembly of section .text:
11// DISASM-EMPTY:
1112// DISASM-NEXT: _start:
1213// LD -> LE:
1314// DISASM-NEXT: 401000: 65 a1 00 00 00 00 movl %gs:0, %eax
deps/lld/test/ELF/tls-opt-iele-i686-nopic.s+24-23
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o
44// RUN: ld.lld -shared %tso.o -o %tso
55// RUN: ld.lld --hash-style=sysv %t.o %tso -o %t1
6// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTREL %s
6// RUN: llvm-readobj -S -r %t1 | FileCheck --check-prefix=GOTREL %s
77// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
88
99// GOTREL: Section {
......@@ -14,8 +14,8 @@
1414// GOTREL-NEXT: SHF_ALLOC
1515// GOTREL-NEXT: SHF_WRITE
1616// GOTREL-NEXT: ]
17// GOTREL-NEXT: Address: 0x402058
18// GOTREL-NEXT: Offset: 0x2058
17// GOTREL-NEXT: Address: 0x402060
18// GOTREL-NEXT: Offset: 0x2060
1919// GOTREL-NEXT: Size: 8
2020// GOTREL-NEXT: Link: 0
2121// GOTREL-NEXT: Info: 0
......@@ -24,33 +24,34 @@
2424// GOTREL-NEXT: }
2525// GOTREL: Relocations [
2626// GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
27// GOTREL-NEXT: 0x402058 R_386_TLS_TPOFF tlsshared0 0x0
28// GOTREL-NEXT: 0x40205C R_386_TLS_TPOFF tlsshared1 0x0
27// GOTREL-NEXT: 0x402060 R_386_TLS_TPOFF tlsshared0 0x0
28// GOTREL-NEXT: 0x402064 R_386_TLS_TPOFF tlsshared1 0x0
2929// GOTREL-NEXT: }
3030// GOTREL-NEXT: ]
3131
3232// DISASM: Disassembly of section .text:
33// DISASM-EMPTY:
3334// DISASM-NEXT: _start:
3435// 4294967288 = 0xFFFFFFF8
3536// 4294967292 = 0xFFFFFFFC
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
37// 4202592 = (.got)[0] = 0x402060
38// 4202596 = (.got)[1] = 0x402064
39// DISASM-NEXT: 401000: {{.*}} movl $4294967288, %ecx
40// DISASM-NEXT: 401006: {{.*}} movl %gs:(%ecx), %eax
41// DISASM-NEXT: 401009: {{.*}} movl $4294967288, %eax
42// DISASM-NEXT: 40100e: {{.*}} movl %gs:(%eax), %eax
43// DISASM-NEXT: 401011: {{.*}} addl $4294967288, %ecx
44// DISASM-NEXT: 401017: {{.*}} movl %gs:(%ecx), %eax
45// DISASM-NEXT: 40101a: {{.*}} movl $4294967292, %ecx
46// DISASM-NEXT: 401020: {{.*}} movl %gs:(%ecx), %eax
47// DISASM-NEXT: 401023: {{.*}} movl $4294967292, %eax
48// DISASM-NEXT: 401028: {{.*}} movl %gs:(%eax), %eax
49// DISASM-NEXT: 40102b: {{.*}} addl $4294967292, %ecx
50// DISASM-NEXT: 401031: {{.*}} movl %gs:(%ecx), %eax
51// DISASM-NEXT: 401034: {{.*}} movl 4202592, %ecx
52// DISASM-NEXT: 40103a: {{.*}} movl %gs:(%ecx), %eax
53// DISASM-NEXT: 40103d: {{.*}} addl 4202596, %ecx
54// DISASM-NEXT: 401043: {{.*}} movl %gs:(%ecx), %eax
5455
5556.type tlslocal0,@object
5657.section .tbss,"awT",@nobits
deps/lld/test/ELF/tls-opt-local.s+1
......@@ -8,6 +8,7 @@
88// NORELOC-NEXT: ]
99
1010// DISASM: Disassembly of section .text:
11// DISASM-EMPTY:
1112// DISASM-NEXT: _start:
1213// DISASM-NEXT: 201000: 48 c7 c0 f8 ff ff ff movq $-8, %rax
1314// DISASM-NEXT: 201007: 49 c7 c7 f8 ff ff ff movq $-8, %r15
deps/lld/test/ELF/tls-opt-no-plt.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-opt-gdie.s -o %t2.o
44// RUN: ld.lld %t2.o -o %t2.so -shared
55// RUN: ld.lld %t.o %t2.so -o %t.exe
6// RUN: llvm-readobj -s %t.exe | FileCheck %s
6// RUN: llvm-readobj -S %t.exe | FileCheck %s
77
88// CHECK-NOT: .plt
99
deps/lld/test/ELF/tls-relocatable.s+1-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
33// RUN: ld.lld %t.o -r -o %tr.o
44// RUN: ld.lld %tr.o -shared -o %t1
5// RUN: llvm-readobj -t %t1 | FileCheck %s
5// RUN: llvm-readobj --symbols %t1 | FileCheck %s
66
77// CHECK: Symbol {
88// CHECK: Name: tls0
deps/lld/test/ELF/tls.s+2-1
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -symbols -sections -program-headers %tout | FileCheck %s
4// RUN: llvm-readobj --symbols --sections -l %tout | FileCheck %s
55// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
66
77.global _start
......@@ -163,6 +163,7 @@ d:
163163// CHECK-NEXT: }
164164
165165// DIS: Disassembly of section .text:
166// DIS-EMPTY:
166167// DIS-NEXT: _start:
167168// DIS-NEXT: 201000: {{.+}} movl %fs:-8, %eax
168169// DIS-NEXT: 201008: {{.+}} movl %fs:-16, %eax
deps/lld/test/ELF/trace-symbols.s+16-11
......@@ -14,46 +14,51 @@
1414# RUN: llvm-ar rcs %t2.a %t2
1515
1616# RUN: ld.lld -y foo -trace-symbol common -trace-symbol=hsymbol \
17# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTRFOO %s
17# RUN: %t %t1 %t2 -o %t3 | FileCheck -check-prefix=OBJECTRFOO %s
1818# OBJECTRFOO: trace-symbols.s.tmp: reference to foo
1919
2020# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
21# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTDCOMMON %s
21# RUN: %t %t1 %t2 -o %t3 | FileCheck -check-prefix=OBJECTDCOMMON %s
2222# OBJECTDCOMMON: trace-symbols.s.tmp1: common definition of common
2323
2424# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
25# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD1FOO %s
25# RUN: %t %t1 %t2 -o %t3 | FileCheck -check-prefix=OBJECTD1FOO %s
2626# OBJECTD1FOO: trace-symbols.s.tmp: reference to foo
2727# OBJECTD1FOO: trace-symbols.s.tmp1: common definition of common
2828# OBJECTD1FOO: trace-symbols.s.tmp1: definition of foo
2929# OBJECTD1FOO: trace-symbols.s.tmp2: definition of foo
3030
31# RUN: ld.lld -y foo %t1 %t2 %t -o %t3 | FileCheck -check-prefix=REFLAST %s
32# REFLAST: trace-symbols.s.tmp1: definition of foo
33# REFLAST: trace-symbols.s.tmp2: definition of foo
34# REFLAST: trace-symbols.s.tmp: reference to foo
35
3136# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
32# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s
37# RUN: %t %t1 %t2 -o %t3 | FileCheck -check-prefix=OBJECTD2FOO %s
3338# RUN: ld.lld -y foo -y common --trace-symbol=hsymbol \
34# RUN: %t %t2 %t1 -o /dev/null 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s
35# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
39# RUN: %t %t2 %t1 -o %t3 | FileCheck -check-prefix=OBJECTD2FOO %s
40# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 | \
3641# RUN: FileCheck -check-prefix=OBJECTD2FOO %s
3742# OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo
3843
39# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \
44# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 | \
4045# RUN: FileCheck -check-prefix=FOO_AND_COMMON %s
4146# FOO_AND_COMMON: trace-symbols.s.tmp: reference to foo
4247# FOO_AND_COMMON: trace-symbols.s.tmp2: definition of foo
4348# FOO_AND_COMMON: trace-symbols.s.tmp1.a: lazy definition of common
4449
45# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
50# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 | \
4651# RUN: FileCheck -check-prefix=SHLIBDCOMMON %s
4752# SHLIBDCOMMON: trace-symbols.s.tmp1.so: shared definition of common
4853
49# RUN: ld.lld -y foo -y common %t %t2.so %t1.so -o %t3 2>&1 | \
54# RUN: ld.lld -y foo -y common %t %t2.so %t1.so -o %t3 | \
5055# RUN: FileCheck -check-prefix=SHLIBD2FOO %s
5156# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \
5257# RUN: FileCheck -check-prefix=NO-SHLIBD2FOO %s
5358# SHLIBD2FOO: trace-symbols.s.tmp2.so: shared definition of foo
5459# NO-SHLIBD2FOO-NOT: trace-symbols.s.tmp2.so: definition of foo
5560
56# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \
61# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 | \
5762# RUN: FileCheck -check-prefix=ARCHIVEDCOMMON %s
5863# ARCHIVEDCOMMON-NOT: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of \
5964# common
......@@ -79,7 +84,7 @@
7984# STARTLIB: trace-symbols.s.tmp1: reference to bar
8085
8186## Check we do not crash when trying to trace special symbol.
82# RUN: not ld.lld -trace-symbol=_end %t -o /dev/null
87# RUN: ld.lld -trace-symbol=_end %t %t1 %t2 -o /dev/null
8388
8489.hidden hsymbol
8590.globl _start
deps/lld/test/ELF/trace.s+1-1
......@@ -6,4 +6,4 @@
66# CHECK: {{.*}}.foo.o
77
88## Check --trace alias
9# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s
9# RUN: ld.lld -shared %t.foo.o -o %t.so --trace 2>&1 | FileCheck %s
deps/lld/test/ELF/ttext-tdata-tbss.s+4-4
......@@ -3,7 +3,7 @@
33
44## Show what regular output gives to us.
55# RUN: ld.lld %t.o -o %t1
6# RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck %s
6# RUN: llvm-readelf -S -l %t1 | FileCheck %s
77# CHECK: .rodata PROGBITS 0000000000200158 000158 000008
88# CHECK-NEXT: .text PROGBITS 0000000000201000 001000 000001
99# CHECK-NEXT: .aw PROGBITS 0000000000202000 002000 000008
......@@ -15,7 +15,7 @@
1515
1616## With .text at 0 there is no space to allocate the headers.
1717# RUN: ld.lld -Ttext 0x0 -Tdata 0x4000 -Tbss 0x8000 %t.o -o %t2
18# RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck %s --check-prefix=USER1
18# RUN: llvm-readelf -S -l %t2 | FileCheck %s --check-prefix=USER1
1919# USER1: .text PROGBITS 0000000000000000 001000 000001
2020# USER1-NEXT: .data PROGBITS 0000000000004000 002000 000008
2121# USER1-NEXT: .bss NOBITS 0000000000008000 002008 000008
......@@ -26,7 +26,7 @@
2626
2727## With .text at 0x1000 there is space to allocate the headers.
2828# RUN: ld.lld -Ttext 0x1000 -Tdata 0x4000 -Tbss 0x8000 %t.o -o %t3
29# RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck %s --check-prefix=USER2
29# RUN: llvm-readelf -S -l %t3 | FileCheck %s --check-prefix=USER2
3030# USER2: .text PROGBITS 0000000000001000 001000 000001
3131# USER2-NEXT: .data PROGBITS 0000000000004000 002000 000008
3232# USER2-NEXT: .bss NOBITS 0000000000008000 002008 000008
......@@ -38,7 +38,7 @@
3838
3939## With .text well above 200000 we don't need to change the image base
4040# RUN: ld.lld -Ttext 0x201000 %t.o -o %t4
41# RUN: llvm-readobj --elf-output-style=GNU -l -s %t4 | FileCheck %s --check-prefix=USER3
41# RUN: llvm-readelf -S -l %t4 | FileCheck %s --check-prefix=USER3
4242# USER3: .text PROGBITS 0000000000201000 001000 000001
4343# USER3-NEX: .rodata PROGBITS 0000000000202000 002000 000008
4444# USER3-NEX: .aw PROGBITS 0000000000203000 003000 000008
deps/lld/test/ELF/undef-broken-debug.test+16-9
......@@ -1,12 +1,12 @@
11# REQUIRES: x86
22# RUN: yaml2obj %s -o %t.o
3# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
3# RUN: not ld.lld %t.o -o /dev/null
44
5# The debug info has a broken relocation. Check that we don't crash
6# and still report the undefined symbol.
5# The debug info has a broken relocation. Check that we don't crash.
76
8# CHECK: error: {{.*}}.o: relocation R_X86_64_64 at 0x29 has unsupported target
9# CHECK: error: undefined symbol: bar
7# We used to dereference null Target in DWARF.cpp:findAux while reporting a duplicate symbol error,
8# because Target wasn't initialized yet.
9# RUN: not ld.lld %t.o %t.o -o /dev/null
1010
1111--- !ELF
1212FileHeader:
......@@ -62,7 +62,14 @@ Sections:
6262 Content: '0111001017000000'
6363
6464Symbols:
65 Global:
66 - Name: _start
67 Section: .text
68 - Name: bar
65 - Name: .debug_abbrev
66 Type: STT_SECTION
67 Section: .debug_abbrev
68 - Name: .debug_line
69 Type: STT_SECTION
70 Section: .debug_line
71 - Name: _start
72 Section: .text
73 Binding: STB_GLOBAL
74 - Name: bar
75 Binding: STB_GLOBAL
deps/lld/test/ELF/undef-multi.s created+65
......@@ -0,0 +1,65 @@
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/undef.s -o %t2.o
4# RUN: not ld.lld %t.o %t2.o -o /dev/null 2>&1 | FileCheck %s
5
6# CHECK: error: undefined symbol: zed2
7# CHECK-NEXT: >>> referenced by undef-multi.s
8# CHECK-NEXT: >>> {{.*}}:(.text+0x1)
9# CHECK-NEXT: >>> referenced by undef-multi.s
10# CHECK-NEXT: >>> {{.*}}:(.text+0x6)
11# CHECK-NEXT: >>> referenced by undef-multi.s
12# CHECK-NEXT: >>> {{.*}}:(.text+0xB)
13# CHECK-NEXT: >>> referenced by undef-multi.s
14# CHECK-NEXT: >>> {{.*}}:(.text+0x10)
15# CHECK-NEXT: >>> referenced by {{.*}}tmp2.o:(.text+0x0)
16
17# All references to a single undefined symbol count as a single error -- but
18# at most 10 references are printed.
19# RUN: echo ".globl _bar" > %t.moreref.s
20# RUN: echo "_bar:" >> %t.moreref.s
21# RUN: echo " call zed2" >> %t.moreref.s
22# RUN: echo " call zed2" >> %t.moreref.s
23# RUN: echo " call zed2" >> %t.moreref.s
24# RUN: echo " call zed2" >> %t.moreref.s
25# RUN: echo " call zed2" >> %t.moreref.s
26# RUN: echo " call zed2" >> %t.moreref.s
27# RUN: echo " call zed2" >> %t.moreref.s
28# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.moreref.s -o %t3.o
29# RUN: not ld.lld %t.o %t2.o %t3.o -o /dev/null -error-limit=2 2>&1 | \
30# RUN: FileCheck --check-prefix=LIMIT %s
31
32# LIMIT: error: undefined symbol: zed2
33# LIMIT-NEXT: >>> referenced by undef-multi.s
34# LIMIT-NEXT: >>> {{.*}}:(.text+0x1)
35# LIMIT-NEXT: >>> referenced by undef-multi.s
36# LIMIT-NEXT: >>> {{.*}}:(.text+0x6)
37# LIMIT-NEXT: >>> referenced by undef-multi.s
38# LIMIT-NEXT: >>> {{.*}}:(.text+0xB)
39# LIMIT-NEXT: >>> referenced by undef-multi.s
40# LIMIT-NEXT: >>> {{.*}}:(.text+0x10)
41# LIMIT-NEXT: >>> referenced by {{.*}}tmp2.o:(.text+0x0)
42# LIMIT-NEXT: >>> referenced by {{.*}}tmp3.o:(.text+0x1)
43# LIMIT-NEXT: >>> referenced by {{.*}}tmp3.o:(.text+0x6)
44# LIMIT-NEXT: >>> referenced by {{.*}}tmp3.o:(.text+0xB)
45# LIMIT-NEXT: >>> referenced by {{.*}}tmp3.o:(.text+0x10)
46# LIMIT-NEXT: >>> referenced by {{.*}}tmp3.o:(.text+0x15)
47# LIMIT-NEXT: >>> referenced 2 more times
48
49.file "undef-multi.s"
50
51 .globl _start
52_start:
53 call zed2
54
55 .globl _f
56_f:
57 call zed2
58
59 .globl _g
60_g:
61 call zed2
62
63 .globl _h
64_h:
65 call zed2
deps/lld/test/ELF/undef-shared.s+3-3
......@@ -2,17 +2,17 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s
44
5# CHECK: error: undefined symbol: hidden
5# CHECK: error: undefined hidden symbol: hidden
66# CHECK: >>> referenced by {{.*}}:(.data+0x0)
77.global hidden
88.hidden hidden
99
10# CHECK: error: undefined symbol: internal
10# CHECK: error: undefined internal symbol: internal
1111# CHECK: >>> referenced by {{.*}}:(.data+0x8)
1212.global internal
1313.internal internal
1414
15# CHECK: error: undefined symbol: protected
15# CHECK: error: undefined protected symbol: protected
1616# CHECK: >>> referenced by {{.*}}:(.data+0x10)
1717.global protected
1818.protected protected
deps/lld/test/ELF/undef-shared2.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: not ld.lld %t.o %t2.o -o %t.so -shared 2>&1 | FileCheck %s
55# RUN: not ld.lld %t2.o %t.o -o %t.so -shared 2>&1 | FileCheck %s
66
7# CHECK: error: undefined symbol: foo
7# CHECK: error: undefined protected symbol: foo
88
99.data
1010.quad foo
deps/lld/test/ELF/undef-version-script.s+1-1
......@@ -2,7 +2,7 @@
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
33# RUN: echo "{ local: *; };" > %t.script
44# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
5# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
5# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
66
77# CHECK: DynamicSymbols [
88# CHECK-NEXT: Symbol {
deps/lld/test/ELF/undef-with-plt-addr-i686.s+1-1
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/undef-with-plt-addr.s -o %t2.o
44// RUN: ld.lld %t2.o -o %t2.so -shared
55// RUN: ld.lld %t.o %t2.so -o %t3
6// RUN: llvm-readobj -t -s %t3 | FileCheck %s
6// RUN: llvm-readobj --symbols -S %t3 | FileCheck %s
77
88.globl _start
99_start:
deps/lld/test/ELF/undef-with-plt-addr.s+3-3
......@@ -3,7 +3,7 @@
33// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/undef-with-plt-addr.s -o %t2.o
44// RUN: ld.lld %t2.o -o %t2.so -shared
55// RUN: ld.lld %t.o %t2.so -o %t3
6// RUN: llvm-readobj -t -s -r %t3 | FileCheck %s
6// RUN: llvm-readobj --symbols -S -r %t3 | FileCheck %s
77
88// Test that -z nocopyreloc doesn't prevent the plt hack.
99// RUN: ld.lld %t.o %t2.so -o %t3 -z nocopyreloc
......@@ -25,10 +25,10 @@ movabsq $set_data, %rax
2525// CHECK-NEXT: Address: 0x201010
2626
2727// CHECK: Section ({{.*}}) .rela.dyn {
28// CHECK-NEXT: 0x202000 R_X86_64_64 foo 0x0
28// CHECK-NEXT: 0x203000 R_X86_64_64 foo 0x0
2929// CHECK-NEXT: }
3030// CHECK-NEXT: Section ({{.*}}) .rela.plt {
31// CHECK-NEXT: 0x202020 R_X86_64_JUMP_SLOT set_data 0x0
31// CHECK-NEXT: 0x203020 R_X86_64_JUMP_SLOT set_data 0x0
3232// CHECK-NEXT: }
3333
3434// CHECK: Name: foo
deps/lld/test/ELF/undefined-glob.s created+58
......@@ -0,0 +1,58 @@
1# REQUIRES: x86
2
3# RUN: echo '.globl foo1; foo1:' | \
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t1.o
5# RUN: echo '.globl foo2; foo2:' | \
6# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t2.o
7# RUN: echo '.globl foo32; foo32:' | \
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t3.o
9# RUN: echo '.globl bar; bar:' | \
10# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t4.o
11# RUN: rm -f %t.a
12# RUN: llvm-ar rcs %t.a %t1.o %t2.o %t3.o %t4.o
13
14# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
15
16# RUN: ld.lld -o %t.exe %t.o %t.a
17# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=NO-OPT %s
18
19# NO-OPT-NOT: foo
20# NO-OPT-NOT: bar
21
22# RUN: ld.lld -o %t.exe %t.o %t.a --undefined-glob foo1
23# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=FOO1 %s
24
25# FOO1: foo1
26# FOO1-NOT: foo2
27
28# RUN: ld.lld -o %t.exe %t.o %t.a --undefined-glob 'foo*'
29# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=FOO-STAR %s
30
31# FOO-STAR: foo1
32# FOO-STAR: foo2
33# FOO-STAR: foo32
34# FOO-STAR-NOT: bar
35
36# RUN: ld.lld -o %t.exe %t.o %t.a --undefined-glob 'foo?'
37# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=FOO-Q %s
38
39# FOO-Q: foo1
40# FOO-Q: foo2
41# FOO-Q-NOT: foo32
42# FOO-Q-NOT: bar
43
44# RUN: ld.lld -o %t.exe %t.o %t.a --undefined-glob 'foo[13]*'
45# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=FOO13 %s
46
47# FOO13: foo1
48# FOO13-NOT: foo2
49# FOO13: foo32
50# FOO13-NOT: bar
51
52# RUN: not ld.lld -o %t.exe %t.o %t.a --undefined-glob '[' 2>&1 | \
53# RUN: FileCheck -check-prefix=BAD-PATTERN %s
54
55# BAD-PATTERN: --undefined-glob: invalid glob pattern: [
56
57.globl _start
58_start:
deps/lld/test/ELF/undefined-opt.s+1-1
......@@ -40,7 +40,7 @@
4040# TWO-UNDEFINED: Name: zed
4141# TWO-UNDEFINED: ]
4242# Now the same logic but linker script is used to set undefines
43# RUN: echo "EXTERN( bar abs )" > %t.script
43# RUN: echo "EXTERN( bar \"abs\" )" > %t.script
4444# RUN: ld.lld -o %t3 %t.o %tar.a %t.script
4545# RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TWO-UNDEFINED %s
4646
deps/lld/test/ELF/undefined-versioned-symbol.s+6-6
......@@ -15,21 +15,21 @@
1515
1616// CHECK: Section ({{.*}}) .rela.dyn {
1717// CHECK-NEXT: Relocation {
18// CHECK-NEXT: Offset: 0x1000
18// CHECK-NEXT: Offset: 0x2000
1919// CHECK-NEXT: Type: R_X86_64_64 (1)
20// CHECK-NEXT: Symbol: basename (1)
20// CHECK-NEXT: Symbol: basename@FBSD_1.1 (1)
2121// CHECK-NEXT: Addend: 0x0
2222// CHECK-NEXT: }
2323// CHECK-NEXT: Relocation {
24// CHECK-NEXT: Offset: 0x1008
24// CHECK-NEXT: Offset: 0x2008
2525// CHECK-NEXT: Type: R_X86_64_64 (1)
26// CHECK-NEXT: Symbol: basename (2)
26// CHECK-NEXT: Symbol: basename@FBSD_1.0 (2)
2727// CHECK-NEXT: Addend: 0x0
2828// CHECK-NEXT: }
2929// CHECK-NEXT: Relocation {
30// CHECK-NEXT: Offset: 0x1010
30// CHECK-NEXT: Offset: 0x2010
3131// CHECK-NEXT: Type: R_X86_64_64 (1)
32// CHECK-NEXT: Symbol: basename (3)
32// CHECK-NEXT: Symbol: basename@FBSD_1.1 (3)
3333// CHECK-NEXT: Addend: 0x0
3434// CHECK-NEXT: }
3535// CHECK-NEXT: }
deps/lld/test/ELF/unresolved-symbols.s+3-3
......@@ -27,21 +27,21 @@
2727# ERRUND: >>> referenced by {{.*}}:(.text+0x1)
2828
2929## Also ignore all should not produce error for symbols from DSOs.
30# RUN: ld.lld %t1.o %t.so -o %t1_3 --unresolved-symbols=ignore-all
30# RUN: ld.lld %t1.o %t.so -o %t1_3 --allow-shlib-undefined --unresolved-symbols=ignore-all
3131# RUN: llvm-readobj %t1_3 > /dev/null 2>&1
3232
3333## Ignoring undefines in objects should not produce error for symbol from object.
3434# RUN: ld.lld %t1.o %t2.o -o %t2 --unresolved-symbols=ignore-in-object-files
3535# RUN: llvm-readobj %t2 > /dev/null 2>&1
3636## And still should not should produce for undefines from DSOs.
37# RUN: ld.lld %t1.o %t.so -o /dev/null --unresolved-symbols=ignore-in-object-files
37# RUN: ld.lld %t1.o %t.so -o /dev/null --allow-shlib-undefined --unresolved-symbols=ignore-in-object-files
3838# RUN: llvm-readobj %t2 > /dev/null 2>&1
3939
4040## Ignoring undefines in shared should produce error for symbol from object.
4141# RUN: not ld.lld %t2.o -o /dev/null --unresolved-symbols=ignore-in-shared-libs 2>&1 | \
4242# RUN: FileCheck -check-prefix=ERRUND %s
4343## And should not produce errors for symbols from DSO.
44# RUN: ld.lld %t1.o %t.so -o %t3_1 --unresolved-symbols=ignore-in-shared-libs
44# RUN: ld.lld %t1.o %t.so -o %t3_1 --allow-shlib-undefined --unresolved-symbols=ignore-in-shared-libs
4545# RUN: llvm-readobj %t3_1 > /dev/null 2>&1
4646
4747## Ignoring undefines in shared libs should not produce error for symbol from object
deps/lld/test/ELF/verdef-defaultver.s+18-16
......@@ -4,7 +4,7 @@
44# RUN: echo "V1 { global: a; local: *; };" > %t.script
55# RUN: echo "V2 { global: b; c; } V1;" >> %t.script
66# RUN: ld.lld --hash-style=sysv -shared -soname shared %t1 --version-script %t.script -o %t.so
7# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
7# RUN: llvm-readobj -V --dyn-syms %t.so | FileCheck --check-prefix=DSO %s
88
99# DSO: DynamicSymbols [
1010# DSO-NEXT: Symbol {
......@@ -108,7 +108,7 @@
108108## Check that we can link against DSO produced.
109109# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
110110# RUN: ld.lld --hash-style=sysv %t2 %t.so -o %t3
111# RUN: llvm-readobj -V -dyn-symbols %t3 | FileCheck --check-prefix=EXE %s
111# RUN: llvm-readobj -V --dyn-syms %t3 | FileCheck --check-prefix=EXE %s
112112
113113# EXE: DynamicSymbols [
114114# EXE-NEXT: Symbol {
......@@ -150,8 +150,8 @@
150150# EXE-NEXT: ]
151151# EXE-NEXT: Version symbols {
152152# EXE-NEXT: Section Name: .gnu.version
153# EXE-NEXT: Address: 0x200228
154# EXE-NEXT: Offset: 0x228
153# EXE-NEXT: Address: 0x200260
154# EXE-NEXT: Offset: 0x260
155155# EXE-NEXT: Link: 1
156156# EXE-NEXT: Symbols [
157157# EXE-NEXT: Symbol {
......@@ -179,18 +179,20 @@
179179# EXE-NEXT: Version: 1
180180# EXE-NEXT: Count: 2
181181# EXE-NEXT: FileName: shared
182# EXE-NEXT: Entry {
183# EXE-NEXT: Hash: 1425
184# EXE-NEXT: Flags: 0x0
185# EXE-NEXT: Index: 2
186# EXE-NEXT: Name: V1
187# EXE-NEXT: }
188# EXE-NEXT: Entry {
189# EXE-NEXT: Hash: 1426
190# EXE-NEXT: Flags: 0x0
191# EXE-NEXT: Index: 3
192# EXE-NEXT: Name: V2
193# EXE-NEXT: }
182# EXE-NEXT: Entries [
183# EXE-NEXT: Entry {
184# EXE-NEXT: Hash: 1425
185# EXE-NEXT: Flags: 0x0
186# EXE-NEXT: Index: 2
187# EXE-NEXT: Name: V1
188# EXE-NEXT: }
189# EXE-NEXT: Entry {
190# EXE-NEXT: Hash: 1426
191# EXE-NEXT: Flags: 0x0
192# EXE-NEXT: Index: 3
193# EXE-NEXT: Name: V2
194# EXE-NEXT: }
195# EXE-NEXT: ]
194196# EXE-NEXT: }
195197# EXE-NEXT: }
196198
deps/lld/test/ELF/verdef-dependency.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; } LIBSAMPLE_1.0;" >> %t.script
55# RUN: echo "LIBSAMPLE_3.0 { global: c; } LIBSAMPLE_2.0;" >> %t.script
66# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so
7# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
7# RUN: llvm-readobj -V --dyn-syms %t.so | FileCheck --check-prefix=DSO %s
88
99# DSO: SHT_GNU_verdef {
1010# DSO-NEXT: Definition {
deps/lld/test/ELF/verdef.s+4-4
......@@ -4,7 +4,7 @@
44# RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; };" >> %t.script
55# RUN: echo "LIBSAMPLE_3.0 { global: c; local: *; };" >> %t.script
66# RUN: ld.lld --hash-style=sysv --version-script %t.script -shared -soname shared %t.o -o %t.so
7# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
7# RUN: llvm-readobj -V --dyn-syms %t.so | FileCheck --check-prefix=DSO %s
88
99# DSO: Version symbols {
1010# DSO-NEXT: Section Name: .gnu.version
......@@ -70,8 +70,8 @@
7070
7171# MAIN: Version symbols {
7272# MAIN-NEXT: Section Name: .gnu.version
73# MAIN-NEXT: Address: 0x200228
74# MAIN-NEXT: Offset: 0x228
73# MAIN-NEXT: Address: 0x200260
74# MAIN-NEXT: Offset: 0x260
7575# MAIN-NEXT: Link: 1
7676# MAIN-NEXT: Symbols [
7777# MAIN-NEXT: Symbol {
......@@ -101,7 +101,7 @@
101101# RUN: echo "LIBSAMPLE_3.0 { global: c; local: *; };" >> %t.script
102102# RUN: echo "}" >> %t.script
103103# RUN: ld.lld --hash-style=sysv --script %t.script -shared -soname shared %t.o -o %t2.so
104# RUN: llvm-readobj -V -dyn-symbols %t2.so | FileCheck --check-prefix=DSO %s
104# RUN: llvm-readobj -V --dyn-syms %t2.so | FileCheck --check-prefix=DSO %s
105105
106106.globl a
107107.type a,@function
deps/lld/test/ELF/verneed.s+31-27
......@@ -7,7 +7,7 @@
77
88# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
99# RUN: ld.lld --hash-style=sysv %t.o %t1.so %t2.so -o %t
10# RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s
10# RUN: llvm-readobj -V --sections --section-data --dyn-syms --dynamic-table %t | FileCheck %s
1111
1212# CHECK: Section {
1313# CHECK: Index: 1
......@@ -16,8 +16,8 @@
1616# CHECK-NEXT: Flags [ (0x2)
1717# CHECK-NEXT: SHF_ALLOC (0x2)
1818# CHECK-NEXT: ]
19# CHECK-NEXT: Address: 0x2001C8
20# CHECK-NEXT: Offset: 0x1C8
19# CHECK-NEXT: Address: 0x200200
20# CHECK-NEXT: Offset: 0x200
2121# CHECK-NEXT: Size: 96
2222# CHECK-NEXT: Link: [[DYNSTR:.*]]
2323# CHECK-NEXT: Info: 1
......@@ -47,7 +47,7 @@
4747# CHECK-NEXT: SHF_ALLOC (0x2)
4848# CHECK-NEXT: ]
4949# CHECK-NEXT: Address: [[VERNEED:.*]]
50# CHECK-NEXT: Offset: 0x230
50# CHECK-NEXT: Offset: 0x268
5151# CHECK-NEXT: Size: 80
5252# CHECK-NEXT: Link: 5
5353# CHECK-NEXT: Info: 2
......@@ -60,17 +60,17 @@
6060# CHECK-NEXT: Flags [ (0x2)
6161# CHECK-NEXT: SHF_ALLOC (0x2)
6262# CHECK-NEXT: ]
63# CHECK-NEXT: Address: 0x2002A8
64# CHECK-NEXT: Offset: 0x2A8
63# CHECK-NEXT: Address: 0x2002E0
64# CHECK-NEXT: Offset: 0x2E0
6565# CHECK-NEXT: Size: 47
6666# CHECK-NEXT: Link: 0
6767# CHECK-NEXT: Info: 0
6868# CHECK-NEXT: AddressAlignment: 1
6969# CHECK-NEXT: EntrySize: 0
7070# CHECK-NEXT: SectionData (
71# CHECK-NEXT: 0000: 00766572 6E656564 312E736F 2E300076 |.verneed1.so.0.v|
72# CHECK-NEXT: 0010: 65726E65 6564322E 736F2E30 00663100 |erneed2.so.0.f1.|
73# CHECK-NEXT: 0020: 76330066 32007632 00673100 763100 |v3.f2.v2.g1.v1.|
71# CHECK-NEXT: 0000: 00663100 66320067 31007665 726E6565 |.f1.f2.g1.vernee|
72# CHECK-NEXT: 0010: 64312E73 6F2E3000 76320076 33007665 |d1.so.0.v2.v3.ve|
73# CHECK-NEXT: 0020: 726E6565 64322E73 6F2E3000 763100 |rneed2.so.0.v1.|
7474# CHECK-NEXT: )
7575# CHECK-NEXT: }
7676
......@@ -148,29 +148,33 @@
148148# CHECK-NEXT: Version: 1
149149# CHECK-NEXT: Count: 2
150150# CHECK-NEXT: FileName: verneed1.so.0
151# CHECK-NEXT: Entry {
152# CHECK-NEXT: Hash: 1938
153# CHECK-NEXT: Flags: 0x0
154# CHECK-NEXT: Index: 3
155# CHECK-NEXT: Name: v2
156# CHECK-NEXT: }
157# CHECK-NEXT: Entry {
158# CHECK-NEXT: Hash: 1939
159# CHECK-NEXT: Flags: 0x0
160# CHECK-NEXT: Index: 2
161# CHECK-NEXT: Name: v3
162# CHECK-NEXT: }
151# CHECK-NEXT: Entries [
152# CHECK-NEXT: Entry {
153# CHECK-NEXT: Hash: 1938
154# CHECK-NEXT: Flags: 0x0
155# CHECK-NEXT: Index: 3
156# CHECK-NEXT: Name: v2
157# CHECK-NEXT: }
158# CHECK-NEXT: Entry {
159# CHECK-NEXT: Hash: 1939
160# CHECK-NEXT: Flags: 0x0
161# CHECK-NEXT: Index: 2
162# CHECK-NEXT: Name: v3
163# CHECK-NEXT: }
164# CHECK-NEXT: ]
163165# CHECK-NEXT: }
164166# CHECK-NEXT: Dependency {
165167# CHECK-NEXT: Version: 1
166168# CHECK-NEXT: Count: 1
167169# CHECK-NEXT: FileName: verneed2.so.0
168# CHECK-NEXT: Entry {
169# CHECK-NEXT: Hash: 1937
170# CHECK-NEXT: Flags: 0x0
171# CHECK-NEXT: Index: 4
172# CHECK-NEXT: Name: v1
173# CHECK-NEXT: }
170# CHECK-NEXT: Entries [
171# CHECK-NEXT: Entry {
172# CHECK-NEXT: Hash: 1937
173# CHECK-NEXT: Flags: 0x0
174# CHECK-NEXT: Index: 4
175# CHECK-NEXT: Name: v1
176# CHECK-NEXT: }
177# CHECK-NEXT: ]
174178# CHECK-NEXT: }
175179# CHECK-NEXT: }
176180
deps/lld/test/ELF/version-exclude-libs.s+2-2
......@@ -4,8 +4,8 @@
44// RUN: llvm-ar -r %t.a %t.o
55// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
66// RUN: ld.lld %t2.o %t.a --shared --exclude-libs ALL -o %t.so
7// RUN: llvm-readobj -symbols %t.so | FileCheck %s
8// RUN: llvm-readobj -dyn-symbols %t.so | FileCheck -check-prefix CHECK-DYN %s
7// RUN: llvm-readobj --symbols %t.so | FileCheck %s
8// RUN: llvm-readobj --dyn-syms %t.so | FileCheck -check-prefix CHECK-DYN %s
99// RUN: not ld.lld %t2.o %t.a --shared -o %t.so 2>&1 | FileCheck -check-prefix=CHECK-ERR %s
1010
1111// Test that we do not give an error message for undefined versions when the
deps/lld/test/ELF/version-script-anonymous-local.s+1-1
......@@ -3,7 +3,7 @@
33
44# RUN: echo "{ global: foo; local: bar; };" > %t.script
55# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols -t %t.so | FileCheck %s
6# RUN: llvm-readobj --dyn-syms --symbols %t.so | FileCheck %s
77
88# CHECK: Symbols [
99# CHECK: Name: bar
deps/lld/test/ELF/version-script-copy-rel.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: ld.lld --version-script %t.script -shared %t1.o -o %t.so
55# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
66# RUN: ld.lld %t2.o %t.so -o %tout
7# RUN: llvm-readobj -dyn-symbols %tout | FileCheck %s
7# RUN: llvm-readobj --dyn-syms %tout | FileCheck %s
88
99# CHECK: DynamicSymbols [
1010# CHECK: Symbol {
deps/lld/test/ELF/version-script-extern-exact.s+2-2
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
44# RUN: echo "FOO { global: extern \"C++\" { \"aaa*\"; }; };" > %t.script
55# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s --check-prefix=NOMATCH
6# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s --check-prefix=NOMATCH
77
88# NOMATCH: DynamicSymbols [
99# NOMATCH-NOT: _Z3aaaPf@@FOO
......@@ -12,7 +12,7 @@
1212
1313# RUN: echo "FOO { global: extern \"C++\" { \"aaa*\"; aaa*; }; };" > %t2.script
1414# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
15# RUN: llvm-readobj -dyn-symbols %t2.so | FileCheck %s --check-prefix=MATCH
15# RUN: llvm-readobj --dyn-syms %t2.so | FileCheck %s --check-prefix=MATCH
1616# MATCH: DynamicSymbols [
1717# MATCH: _Z3aaaPf@@FOO
1818# MATCH: _Z3aaaPi@@FOO
deps/lld/test/ELF/version-script-extern-wildcards-anon.s+1-1
......@@ -12,7 +12,7 @@
1212# RUN: local: *; \
1313# RUN: }; ' > %t.script
1414# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
15# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
15# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
1616
1717# CHECK: DynamicSymbols [
1818# CHECK-NEXT: Symbol {
deps/lld/test/ELF/version-script-extern-wildcards.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: echo "FOO { global: extern \"C++\" { foo*; }; };" > %t.script
55# RUN: echo "BAR { global: extern \"C++\" { zed*; bar; }; };" >> %t.script
66# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
7# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck %s
7# RUN: llvm-readobj -V --dyn-syms %t.so | FileCheck %s
88
99# CHECK: Version symbols {
1010# CHECK: Symbols [
deps/lld/test/ELF/version-script-extern.s+1-1
......@@ -8,7 +8,7 @@
88# RUN: echo ' extern "C" { _Z3bari; };' >> %t.script
99# RUN: echo "};" >> %t.script
1010# RUN: ld.lld --hash-style=sysv --version-script %t.script -soname fixed-length-string -shared %t.o -o %t.so
11# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
11# RUN: llvm-readobj -V --dyn-syms %t.so | FileCheck --check-prefix=DSO %s
1212
1313# DSO: DynamicSymbols [
1414# DSO-NEXT: Symbol {
deps/lld/test/ELF/version-script-glob.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: echo "{ global: foo*; bar*; local: *; };" > %t.script
44# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
55# RUN: ld.lld -shared --version-script %t.script %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
6# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
77
88 .globl foo1
99foo1:
deps/lld/test/ELF/version-script-hide-so-symbol.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: ld.lld -shared %t.o -o %t2.so
55# RUN: echo "{ local: *; };" > %t.script
66# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so
7# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
7# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
88
99# The symbol foo must be hidden. This matches bfd and gold and is
1010# required to make it possible for a c++ library to hide its own
deps/lld/test/ELF/version-script-locals.s+3-3
......@@ -3,7 +3,7 @@
33
44# RUN: echo "VERSION_1.0 { local: foo1; };" > %t.script
55# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=EXACT %s
6# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=EXACT %s
77# EXACT: DynamicSymbols [
88# EXACT: _start
99# EXACT-NOT: foo1
......@@ -12,7 +12,7 @@
1212
1313# RUN: echo "VERSION_1.0 { local: foo*; };" > %t.script
1414# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
15# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=WC %s
15# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=WC %s
1616# WC: DynamicSymbols [
1717# WC: _start
1818# WC-NOT: foo1
......@@ -21,7 +21,7 @@
2121
2222# RUN: echo "VERSION_1.0 { global: *; local: foo*; };" > %t.script
2323# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
24# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=MIX %s
24# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=MIX %s
2525# MIX: DynamicSymbols [
2626# MIX: _start@@VERSION_1.0
2727# MIX-NOT: foo1
deps/lld/test/ELF/version-script-reassign.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: echo '{ local: foo; };' > %tl.ver
4# RUN: echo '{ global: foo; local: *; };' > %tg.ver
5# RUN: echo 'V1 { global: foo; };' > %t1.ver
6# RUN: echo 'V2 { global: foo; };' > %t2.ver
7# RUN: echo 'V2 { global: notexist; local: f*; };' > %t2w.ver
8
9## Note, ld.bfd errors on the two cases.
10# RUN: ld.lld -shared %t.o --version-script %tl.ver --version-script %t1.ver \
11# RUN: -o %t.so 2>&1 | FileCheck --check-prefix=LOCAL %s
12# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=LOCAL-SYM %s
13# RUN: ld.lld -shared %t.o --version-script %tg.ver --version-script %t1.ver \
14# RUN: -o %t.so 2>&1 | FileCheck --check-prefix=GLOBAL %s
15# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=GLOBAL-SYM %s
16
17## Note, ld.bfd silently accepts this case.
18# RUN: ld.lld -shared %t.o --version-script %t1.ver --version-script %t2.ver \
19# RUN: -o %t.so 2>&1 | FileCheck --check-prefix=V1-WARN %s
20# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=V1-SYM %s
21
22# RUN: ld.lld -shared %t.o --version-script %t1.ver --version-script %t2w.ver \
23# RUN: -o %t.so --fatal-warnings
24# RUN: llvm-readelf --dyn-syms %t.so | FileCheck --check-prefix=V1-SYM %s
25
26# LOCAL: warning: attempt to reassign symbol 'foo' of VER_NDX_LOCAL to version 'V1'
27# LOCAL-SYM-NOT: foo
28
29# GLOBAL: warning: attempt to reassign symbol 'foo' of VER_NDX_GLOBAL to version 'V1'
30# GLOBAL-SYM: foo{{$}}
31
32# V1-WARN: warning: attempt to reassign symbol 'foo' of version 'V1' to version 'V2'
33# V1-SYM: foo@@V1
34
35.globl foo
36foo:
deps/lld/test/ELF/version-script-twice.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: echo "FBSD_1.1 {}; FBSD_1.2 {};" > %t.ver
44# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
55# RUN: ld.lld -shared %t.o -o %t.so --version-script=%t.ver
6# RUN: llvm-readobj --dyn-symbols --elf-output-style=GNU %t.so | FileCheck %s
6# RUN: llvm-readelf --dyn-symbols %t.so | FileCheck %s
77
88 .weak openat
99openat:
deps/lld/test/ELF/version-script-weak.s+2-2
......@@ -6,11 +6,11 @@
66# RUN: llvm-ar rcs %t.a %tmp.o
77# RUN: echo "{ local: *; };" > %t.script
88# RUN: ld.lld -shared --version-script %t.script %t.o %t.a -o %t.so
9# RUN: llvm-readobj -dyn-symbols -r %t.so | FileCheck %s
9# RUN: llvm-readobj --dyn-syms -r %t.so | FileCheck %s
1010
1111# CHECK: Relocations [
1212# CHECK-NEXT: Section ({{.*}}) .rela.plt {
13# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo
13# CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT foo
1414# CHECK-NEXT: }
1515# CHECK-NEXT: ]
1616# CHECK: Symbol {
deps/lld/test/ELF/version-script.s+6-12
......@@ -6,19 +6,19 @@
66# RUN: echo "{ global: foo1; foo3; local: *; };" > %t.script
77# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
88# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so
9# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
9# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=DSO %s
1010
1111# RUN: echo "# comment" > %t3.script
1212# RUN: echo "{ local: *; # comment" >> %t3.script
1313# RUN: echo -n "}; # comment" >> %t3.script
1414# RUN: ld.lld --version-script %t3.script -shared %t.o %t2.so -o %t3.so
15# RUN: llvm-readobj -dyn-symbols %t3.so | FileCheck --check-prefix=DSO2 %s
15# RUN: llvm-readobj --dyn-syms %t3.so | FileCheck --check-prefix=DSO2 %s
1616
1717## Also check that both "global:" and "global :" forms are accepted
1818# RUN: echo "VERSION_1.0 { global : foo1; local : *; };" > %t4.script
1919# RUN: echo "VERSION_2.0 { global: foo3; local: *; };" >> %t4.script
2020# RUN: ld.lld --version-script %t4.script -shared %t.o %t2.so -o %t4.so
21# RUN: llvm-readobj -dyn-symbols %t4.so | FileCheck --check-prefix=VERDSO %s
21# RUN: llvm-readobj --dyn-syms %t4.so | FileCheck --check-prefix=VERDSO %s
2222
2323# RUN: echo "VERSION_1.0 { global: foo1; local: *; };" > %t5.script
2424# RUN: echo "{ global: foo3; local: *; };" >> %t5.script
......@@ -32,12 +32,6 @@
3232# RUN: FileCheck -check-prefix=ERR2 %s
3333# ERR2: EOF expected, but got VERSION_2.0
3434
35# RUN: echo "VERSION_1.0 { global: foo1; local: *; };" > %t6.script
36# RUN: echo "VERSION_2.0 { global: foo1; local: *; };" >> %t6.script
37# RUN: not ld.lld --version-script %t6.script -shared %t.o %t2.so -o /dev/null 2>&1 | \
38# RUN: FileCheck -check-prefix=ERR3 %s
39# ERR3: duplicate symbol 'foo1' in version script
40
4135# RUN: echo "{ foo1; foo2; };" > %t.list
4236# RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2
4337# RUN: llvm-readobj %t2 > /dev/null
......@@ -46,7 +40,7 @@
4640# RUN: echo "VERSION_1.0 { global : foo1; local : *; };" > %t7a.script
4741# RUN: echo "VERSION_2.0 { global: foo3; local: *; };" > %t7b.script
4842# RUN: ld.lld --version-script %t7a.script --version-script %t7b.script -shared %t.o %t2.so -o %t7.so
49# RUN: llvm-readobj -dyn-symbols %t7.so | FileCheck --check-prefix=VERDSO %s
43# RUN: llvm-readobj --dyn-syms %t7.so | FileCheck --check-prefix=VERDSO %s
5044
5145# DSO: DynamicSymbols [
5246# DSO-NEXT: Symbol {
......@@ -149,12 +143,12 @@
149143
150144# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
151145# RUN: ld.lld --hash-style=sysv -shared %t.o %t2.so -o %t.so
152# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s
146# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=ALL %s
153147
154148# RUN: echo "{ global: foo1; foo3; };" > %t2.script
155149# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
156150# RUN: ld.lld --hash-style=sysv --version-script %t2.script -shared %t.o %t2.so -o %t.so
157# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s
151# RUN: llvm-readobj --dyn-syms %t.so | FileCheck --check-prefix=ALL %s
158152
159153# ALL: DynamicSymbols [
160154# ALL-NEXT: Symbol {
deps/lld/test/ELF/version-use.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: ld.lld %t.o %p/Inputs/version-use.so -o %t.so -shared -z defs
4// RUN: llvm-readobj -s %t.so | FileCheck %s
4// RUN: llvm-readobj -S %t.so | FileCheck %s
55
66
77 call bar@PLT
deps/lld/test/ELF/version-wildcard.test+2-2
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
44# RUN: echo "VERSION_1.0 { global: foo*; local: *; };" > %t.script
55# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
6# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
77
88# CHECK: DynamicSymbols [
99# CHECK-NEXT: Symbol {
......@@ -48,7 +48,7 @@
4848# RUN: echo "VERSION_1.0 { global: foo2; local: *; };" > %t2.script
4949# RUN: echo "VERSION_2.0 { global: foo*; };" >> %t2.script
5050# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
51# RUN: llvm-readobj -dyn-symbols %t2.so | FileCheck --check-prefix=MIX %s
51# RUN: llvm-readobj --dyn-syms %t2.so | FileCheck --check-prefix=MIX %s
5252
5353# MIX: DynamicSymbols [
5454# MIX-NEXT: Symbol {
deps/lld/test/ELF/visibility.s+1-1
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2
44// RUN: ld.lld -shared %t %t2 -o %t3
5// RUN: llvm-readobj -t -dyn-symbols %t3 | FileCheck %s
5// RUN: llvm-readobj --symbols --dyn-syms %t3 | FileCheck %s
66
77// CHECK: Symbols [
88// CHECK-NEXT: Symbol {
deps/lld/test/ELF/vs-diagnostics-duplicate.s created+63
......@@ -0,0 +1,63 @@
1// REQUIRES: x86
2// 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 %S/Inputs/vs-diagnostics-duplicate2.s -o %t2.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/vs-diagnostics-duplicate3.s -o %t3.o
5// RUN: not ld.lld --vs-diagnostics %t1.o %t2.o %t3.o -o %tout 2>&1 | FileCheck %s
6
7// Case 1. Both symbols have full source location.
8// CHECK: duplicate.s(15): error: duplicate symbol: bar
9// CHECK-NEXT: >>> defined at duplicate.s:15
10// CHECK-NEXT: >>>{{.*}}1.o:(.text+0x{{.+}})
11// CHECK: >>> defined at duplicate2.s:20
12// CHECK: >>>{{.*}}2.o:(.text+0x{{.+}})
13
14// Case 2. The source locations are unknown for both symbols.
15// CHECK: {{.*}}ld.lld{{.*}}: error: duplicate symbol: foo
16// CHECK-NEXT: >>> defined at {{.*}}1.o:(.text+0x{{.+}})
17// CHECK-NEXT: >>> defined at {{.*}}2.o:(.text+0x{{.+}})
18
19// Case 3. For the second definition of `baz` we know only the source file found in a STT_FILE symbol.
20// CHECK: duplicate.s(30): error: duplicate symbol: baz
21// CHECK-NEXT: >>> defined at duplicate.s:30
22// CHECK-NEXT: >>> {{.*}}1.o:(.text+0x{{.+}})
23// CHECK-NEXT: >>> defined at duplicate3.s
24// CHECK-NEXT: >>> {{.*}}3.o:(.text+0x{{.+}})
25
26.global _start, foo, bar, baz
27.text
28_start:
29 nop
30
31foo:
32 nop
33
34.file 1 "duplicate.s"
35.loc 1 15
36
37bar:
38 nop
39
40.loc 1 30
41baz:
42 nop
43
44.section .debug_abbrev,"",@progbits
45 .byte 1 # Abbreviation Code
46 .byte 17 # DW_TAG_compile_unit
47 .byte 0 # DW_CHILDREN_no
48 .byte 16 # DW_AT_stmt_list
49 .byte 23 # DW_FORM_sec_offset
50 .byte 0 # EOM(1)
51 .byte 0 # EOM(2)
52 .byte 0 # EOM(3)
53
54.section .debug_info,"",@progbits
55 .long .Lend0 - .Lbegin0 # Length of Unit
56.Lbegin0:
57 .short 4 # DWARF version number
58 .long .debug_abbrev # Offset Into Abbrev. Section
59 .byte 8 # Address Size (in bytes)
60 .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
61 .long .debug_line # DW_AT_stmt_list
62.Lend0:
63 .section .debug_line,"",@progbits
deps/lld/test/ELF/vs-diagnostics-dynamic-relocation.s created+35
......@@ -0,0 +1,35 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: not ld.lld -shared --vs-diagnostics %t.o -o /dev/null 2>&1 | FileCheck %s
4
5// CHECK: dyn.s(15): error: can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
6// CHECK-NEXT: >>> defined in {{.*}}.o
7// CHECK-NEXT: >>> referenced by dyn.s:15
8// CHECK-NEXT: >>>{{.*}}.o:(.text+0x{{.+}})
9
10.file 1 "dyn.s"
11.loc 1 15
12
13foo:
14.quad foo
15
16.section .debug_abbrev,"",@progbits
17 .byte 1 # Abbreviation Code
18 .byte 17 # DW_TAG_compile_unit
19 .byte 0 # DW_CHILDREN_no
20 .byte 16 # DW_AT_stmt_list
21 .byte 23 # DW_FORM_sec_offset
22 .byte 0 # EOM(1)
23 .byte 0 # EOM(2)
24 .byte 0 # EOM(3)
25
26.section .debug_info,"",@progbits
27 .long .Lend0 - .Lbegin0 # Length of Unit
28.Lbegin0:
29 .short 4 # DWARF version number
30 .long .debug_abbrev # Offset Into Abbrev. Section
31 .byte 8 # Address Size (in bytes)
32 .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
33 .long .debug_line # DW_AT_stmt_list
34.Lend0:
35 .section .debug_line,"",@progbits
deps/lld/test/ELF/vs-diagnostics-undefined-symbol-1.s created+15
......@@ -0,0 +1,15 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3// RUN: not ld.lld --vs-diagnostics %t1.o -o %tout 2>&1 \
4// RUN: | FileCheck -check-prefix=ERR -check-prefix=CHECK -DFILE=%t1.o %s
5// RUN: ld.lld --vs-diagnostics --warn-unresolved-symbols %t1.o -o %tout 2>&1 \
6// RUN: | FileCheck -check-prefix=WARN -check-prefix=CHECK -DFILE=%t1.o %s
7
8// ERR: [[FILE]]: error: undefined symbol: foo
9// WARN: [[FILE]]: warning: undefined symbol: foo
10// CHECK-NEXT: >>> referenced by {{.*}}1.o:(.text+0x{{.+}})
11
12.global _start, foo
13.text
14_start:
15 jmp foo
\ No newline at end of file
deps/lld/test/ELF/vs-diagnostics-undefined-symbol-2.s created+18
......@@ -0,0 +1,18 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3// RUN: not ld.lld --vs-diagnostics %t1.o -o %tout 2>&1 \
4// RUN: | FileCheck -check-prefix=ERR -check-prefix=CHECK %s
5// RUN: ld.lld --vs-diagnostics --warn-unresolved-symbols %t1.o -o %tout 2>&1 \
6// RUN: | FileCheck -check-prefix=WARN -check-prefix=CHECK %s
7
8// ERR: {{.*}}ld.lld{{.*}}: error: undefined symbol: foo
9// WARN: {{.*}}ld.lld{{.*}}: warning: undefined symbol: foo
10// CHECK-NEXT: >>> referenced by undef2.s
11// CHECK-NEXT: >>> {{.*}}1.o:(.text+0x{{.+}})
12
13.file "undef2.s"
14
15.global _start, foo
16.text
17_start:
18 jmp foo
deps/lld/test/ELF/vs-diagnostics-undefined-symbol-3.s created+40
......@@ -0,0 +1,40 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3// RUN: not ld.lld --vs-diagnostics %t1.o -o %tout 2>&1 \
4// RUN: | FileCheck -check-prefix=ERR -check-prefix=CHECK %s
5// RUN: ld.lld --vs-diagnostics --warn-unresolved-symbols %t1.o -o %tout 2>&1 \
6// RUN: | FileCheck -check-prefix=WARN -check-prefix=CHECK %s
7
8// ERR: undef3.s(15): error: undefined symbol: foo
9// WARN: undef3.s(15): warning: undefined symbol: foo
10// CHECK: >>> referenced by undef3.s:15
11// CHECK-NEXT: >>> {{.*}}1.o:(.text+0x{{.+}})
12
13.file 1 "undef3.s"
14
15.global _start, foo
16.text
17_start:
18.loc 1 15
19 jmp foo
20
21.section .debug_abbrev,"",@progbits
22 .byte 1 # Abbreviation Code
23 .byte 17 # DW_TAG_compile_unit
24 .byte 0 # DW_CHILDREN_no
25 .byte 16 # DW_AT_stmt_list
26 .byte 23 # DW_FORM_sec_offset
27 .byte 0 # EOM(1)
28 .byte 0 # EOM(2)
29 .byte 0 # EOM(3)
30
31.section .debug_info,"",@progbits
32 .long .Lend0 - .Lbegin0 # Length of Unit
33.Lbegin0:
34 .short 4 # DWARF version number
35 .long .debug_abbrev # Offset Into Abbrev. Section
36 .byte 8 # Address Size (in bytes)
37 .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
38 .long .debug_line # DW_AT_stmt_list
39.Lend0:
40 .section .debug_line,"",@progbits
deps/lld/test/ELF/vs-diagnostics-versionscript.s created+5
......@@ -0,0 +1,5 @@
1# RUN: echo "\"" > %/terr1.script
2# RUN: not ld.lld --vs-diagnostics --version-script %/terr1.script 2>&1 | \
3# RUN: FileCheck %s -DSCRIPT="%/terr1.script"
4
5# CHECK: [[SCRIPT]](1): error: [[SCRIPT]]:1: unclosed quote
deps/lld/test/ELF/warn-unresolved-symbols-hidden.s+2-2
......@@ -3,8 +3,8 @@
33# RUN: not ld.lld -shared %t.o -o /dev/null -z defs --warn-unresolved-symbols 2>&1| FileCheck %s
44
55# CHECK: warning: undefined symbol: foo
6# CHECK: error: undefined symbol: bar
7# CHECK: error: undefined symbol: zed
6# CHECK: error: undefined hidden symbol: bar
7# CHECK: error: undefined protected symbol: zed
88
99.data
1010.quad foo
deps/lld/test/ELF/weak-undef-export.s+1-1
......@@ -4,7 +4,7 @@
44
55# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
66# RUN: ld.lld --export-dynamic %t.o -o %t
7# RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
7# RUN: llvm-readobj --dyn-syms %t | FileCheck %s
88
99# CHECK: DynamicSymbols [
1010# CHECK-NEXT: Symbol {
deps/lld/test/ELF/weak-undef-hidden.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 -o %t.so -shared
4// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -r -S --section-data %t.so | FileCheck %s
55
66.data
77.weak g
deps/lld/test/ELF/weak-undef-lib.s+1-1
......@@ -4,7 +4,7 @@
44# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o
55
66# RUN: ld.lld -shared -o %t.so %t1.o --start-lib %t2.o
7# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
7# RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
88
99# CHECK: Name: foo
1010# CHECK-NEXT: Value: 0x0
deps/lld/test/ELF/weak-undef-no-shared-libs.s created+28
......@@ -0,0 +1,28 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3// RUN: ld.lld -pie %t.o -o %t
4// RUN: llvm-readobj -V --dyn-syms %t | FileCheck %s
5
6 .globl _start
7_start:
8 .type foo,@function
9 .weak foo
10 .long foo@gotpcrel
11
12// Test that an entry for weak undefined symbols is NOT emitted in .dynsym as
13// the PIE was not linked with any shared libraries. There are other tests which
14// ensure that the weak undefined symbols do get emitted in .dynsym for PIEs
15// linked against dynamic libraries.
16
17
18// CHECK: DynamicSymbols [
19// CHECK-NEXT: Symbol {
20// CHECK-NEXT: Name:
21// CHECK-NEXT: Value: 0x0
22// CHECK-NEXT: Size: 0
23// CHECK-NEXT: Binding: Local (0x0)
24// CHECK-NEXT: Type: None (0x0)
25// CHECK-NEXT: Other: 0
26// CHECK-NEXT: Section: Undefined (0x0)
27// CHECK-NEXT: }
28// CHECK-NEXT: ]
deps/lld/test/ELF/weak-undef-rw.s+6-2
......@@ -1,9 +1,13 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33# RUN: ld.lld %t.o -o %t --export-dynamic
4# RUN: llvm-readobj -r %t | FileCheck %s
4# RUN: llvm-readelf -r %t | FileCheck %s
55
6# CHECK: R_X86_64_64 foobar 0x0
6## gABI leaves the behavior of weak undefined references implementation defined.
7## We choose to resolve it statically and not create a dynamic relocation for
8## implementation simplicity. This also matches ld.bfd and gold.
9
10# CHECK: no relocations
711
812 .global _start
913_start:
deps/lld/test/ELF/weak-undef-shared.s+35-17
......@@ -1,19 +1,37 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: llvm-mc %p/Inputs/shared.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: ld.lld %t.o %t2.so -o %t.exe
6// RUN: llvm-readobj -t %t.exe | FileCheck %s
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: ld.lld -shared %t.o -o %t.so
74
8// CHECK: Name: bar
9// CHECK-NEXT: Value: 0x201020
10// CHECK-NEXT: Size: 0
11// CHECK-NEXT: Binding: Weak
12// CHECK-NEXT: Type: Function
13// CHECK-NEXT: Other: 0
14// CHECK-NEXT: Section: Undefined
5# RUN: echo '.data; .weak foo; .quad foo' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
6# RUN: echo '.data; .quad foo' | llvm-mc -filetype=obj -triple=x86_64 - -o %t2.o
7# RUN: ld.lld -shared %t2.o -o %t2.so
158
16.global _start
17_start:
18 .weak bar
19 .quad bar
9## If the first undefined reference is weak, the binding changes to
10## STB_WEAK.
11# RUN: ld.lld %t1.o %t.so -o %t
12# RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=WEAK %s
13# RUN: ld.lld %t.so %t1.o -o %t
14# RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=WEAK %s
15
16## The binding remains STB_WEAK if there is no STB_GLOBAL undefined reference.
17# RUN: ld.lld %t1.o %t.so %t1.o -o %t
18# RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=WEAK %s
19# RUN: ld.lld %t.so %t1.o %t1.o -o %t
20# RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=WEAK %s
21
22## The binding changes back to STB_GLOBAL if there is a STB_GLOBAL undefined reference.
23# RUN: ld.lld %t1.o %t.so %t2.o -o %t
24# RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=GLOBAL %s
25# RUN: ld.lld %t2.o %t.so %t1.o -o %t
26# RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=GLOBAL %s
27
28## Check the binding (weak) is not affected by the STB_GLOBAL undefined
29## reference in %t2.so
30# RUN: ld.lld %t1.o %t2.so -o %t
31# RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=WEAK %s
32
33# WEAK: NOTYPE WEAK DEFAULT UND foo
34# GLOBAL: NOTYPE GLOBAL DEFAULT UND foo
35
36.globl foo
37foo:
deps/lld/test/ELF/weak-undef-shared2.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: echo '.globl f; f:' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
4# RUN: echo '.weak f; .data; .quad f' | llvm-mc -filetype=obj -triple=x86_64 - -o %t2.o
5# RUN: ld.lld -shared %t1.o -o %t1.so
6# RUN: ld.lld -shared %t2.o -o %t2.so
7
8## The undefined reference is STB_GLOBAL in %t.o while STB_WEAK in %t2.so.
9## Check the binding of the result is STB_GLOBAL.
10
11# RUN: ld.lld %t.o %t1.so %t2.so -o %t
12# RUN: llvm-readelf --dyn-syms %t | FileCheck %s
13# RUN: ld.lld %t1.so %t.o %t2.so -o %t
14# RUN: llvm-readelf --dyn-syms %t | FileCheck %s
15# RUN: ld.lld %t1.so %t2.so %t.o -o %t
16# RUN: llvm-readelf --dyn-syms %t | FileCheck %s
17
18# CHECK: NOTYPE GLOBAL DEFAULT UND f
19
20.data
21.quad f
deps/lld/test/ELF/weak-undef-val.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 -o %t --export-dynamic
4# RUN: llvm-readobj -s -section-data %t | FileCheck %s
4# RUN: llvm-readobj -S --section-data %t | FileCheck %s
55
66# CHECK: Name: .text
77# CHECK-NEXT: Type: SHT_PROGBITS
deps/lld/test/ELF/weak-undef.s+4-2
......@@ -1,7 +1,9 @@
11# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/dummy-shared.s -o %t1.o
3# RUN: ld.lld %t1.o -shared -o %t1.so
24# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t -pie
4# RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
5# RUN: ld.lld %t.o -o %t %t1.so -pie
6# RUN: llvm-readobj --dyn-syms %t | FileCheck %s
57
68# CHECK: DynamicSymbols [
79# CHECK-NEXT: Symbol {
deps/lld/test/ELF/wrap-dynamic-undef.s+1-1
......@@ -3,7 +3,7 @@
33# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-dynamic-undef.s -o %t2.o
44# RUN: ld.lld %t2.o -o %t2.so -shared
55# RUN: ld.lld %t1.o %t2.so -o %t --wrap foo
6# RUN: llvm-readobj -dyn-symbols --elf-output-style=GNU %t | FileCheck %s
6# RUN: llvm-readelf --dyn-syms %t | FileCheck %s
77
88# Test that the dynamic relocation uses foo. We used to produce a
99# relocation with __real_foo.
deps/lld/test/ELF/wrap-entry.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 -o %t.exe %t.o -wrap=_start
5// RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
5// RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
66
77// CHECK: Entry: 0x201001
88
deps/lld/test/ELF/wrap-plt.s+3-3
......@@ -2,7 +2,7 @@
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
33
44// RUN: ld.lld -o %t2 %t -wrap foo -shared
5// RUN: llvm-readobj -s -r %t2 | FileCheck %s
5// RUN: llvm-readobj -S -r %t2 | FileCheck %s
66// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
77
88// CHECK: Name: .plt
......@@ -20,8 +20,8 @@
2020
2121// CHECK: Relocations [
2222// 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
23// CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT __wrap_foo 0x0
24// CHECK-NEXT: 0x3020 R_X86_64_JUMP_SLOT _start 0x0
2525// CHECK-NEXT: }
2626// CHECK-NEXT: ]
2727
deps/lld/test/ELF/wrap.s+1-1
......@@ -14,7 +14,7 @@
1414// CHECK-NEXT: movl $0x11010, %edx
1515// CHECK-NEXT: movl $0x11000, %edx
1616
17// RUN: llvm-readobj -t %t3 > %t4.dump
17// RUN: llvm-readobj --symbols %t3 > %t4.dump
1818// RUN: FileCheck --check-prefix=SYM1 %s < %t4.dump
1919// RUN: FileCheck --check-prefix=SYM2 %s < %t4.dump
2020// RUN: FileCheck --check-prefix=SYM3 %s < %t4.dump
deps/lld/test/ELF/x86-64-cet.s created+48
......@@ -0,0 +1,48 @@
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/x86-64-cet1.s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-cet2.s -o %t2.o
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-cet3.s -o %t3.o
6# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-cet4.s -o %t4.o
7
8# RUN: ld.lld -e func1 %t.o %t1.o -o %t
9# RUN: llvm-readelf -n %t | FileCheck -check-prefix=CET -match-full-lines %s
10
11# RUN: ld.lld -e func1 %t.o %t2.o -o %t
12# RUN: llvm-readelf -n %t | FileCheck -check-prefix=CET -match-full-lines %s
13
14# CET: Properties: x86 feature: IBT, SHSTK
15
16# RUN: ld.lld -e func1 %t.o %t3.o -o %t
17# RUN: llvm-readelf -S %t | FileCheck -check-prefix=NOCET %s
18
19# NOCET: Section Headers
20# NOCET-NOT: .note.gnu.property
21
22# RUN: not ld.lld -e func1 %t.o %t3.o -o %t --require-cet 2>&1 \
23# RUN: | FileCheck -check-prefix=ERROR %s
24# ERROR: x86-64-cet.s.tmp3.o: --require-cet: file is not compatible with CET
25
26# RUN: ld.lld -e func1 %t.o %t4.o -o %t
27# RUN: llvm-readelf -n %t | FileCheck -check-prefix=NOSHSTK -match-full-lines %s
28
29# Check .note.gnu.protery without property SHSTK.
30# NOSHSTK: Properties: x86 feature: IBT
31
32.section ".note.gnu.property", "a"
33.long 4
34.long 0x10
35.long 0x5
36.asciz "GNU"
37
38.long 0xc0000002
39.long 4
40.long 3
41.long 0
42
43.text
44.globl func1
45.type func1,@function
46func1:
47 call func2
48 ret
deps/lld/test/ELF/x86-64-dyn-rel-error5.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: not ld.lld -pie %t.o -o /dev/null 2>&1 | FileCheck %s
4# RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s
5
6## Check we don't create dynamic relocations in a writable section,
7## if the number of bits is smaller than the wordsize.
8
9.globl hidden
10.hidden hidden
11local:
12hidden:
13
14# CHECK: error: relocation R_X86_64_8 cannot be used against local symbol; recompile with -fPIC
15# CHECK-NEXT: >>> defined in {{.*}}.o
16# CHECK-NEXT: >>> referenced by {{.*}}.o:(.data+0x0)
17# CHECK: error: relocation R_X86_64_16 cannot be used against local symbol; recompile with -fPIC
18# CHECK: error: relocation R_X86_64_32 cannot be used against local symbol; recompile with -fPIC
19# CHECK: error: relocation R_X86_64_32 cannot be used against symbol hidden; recompile with -fPIC
20
21.data
22.byte local # R_X86_64_8
23.short local # R_X86_64_16
24.long local # R_X86_64_32
25
26.long hidden # R_X86_64_32
deps/lld/test/ELF/x86-64-pcrel.s created+23
......@@ -0,0 +1,23 @@
1// REQUIRES: x86
2
3// This is a test for R_X86_64_PC8 and R_X86_64_PC16.
4
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
6// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/x86-64-pcrel.s -o %t2.o
7// RUN: ld.lld -o %t.exe %t1.o %t2.o
8// RUN: llvm-objdump -s %t.exe | FileCheck %s
9
10// CHECK: Contents of section .text:
11// CHECK-NEXT: 2000cccc cccccccc cccccccc cccccccc
12// CHECK-NEXT: 20cccccc cccccccc cccccccc cccccccc
13// CHECK-NEXT: e0ffcccc cccccccc cccccccc cccccccc
14// CHECK-NEXT: e0cccccc cccccccc cccccccc cccccccc
15
16.globl _start
17_start:
18
19.word foo - _start
20.fill 14,1,0xcc
21
22.byte foo - _start
23.fill 15,1,0xcc
deps/lld/test/ELF/x86-64-plt-high-addr.s+4-4
......@@ -8,16 +8,16 @@
88// RUN: llvm-objdump -s -j .got.plt %t1.exe | FileCheck %s
99
1010// CHECK: Contents of section .got.plt:
11// CHECK-NEXT: cafe00002000 00300000 feca0000 00000000 00000000
12// CHECK-NEXT: cafe00002010 00000000 00000000 26100000 feca0000
11// CHECK-NEXT: cafe00003000 00200000 feca0000 00000000 00000000
12// CHECK-NEXT: cafe00003010 00000000 00000000 26100000 feca0000
1313
1414// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
1515// RUN: ld.lld -o %t2.exe %t2.o %t.so -image-base=0xcafe00000000 -z retpolineplt
1616// RUN: llvm-objdump -s -j .got.plt %t2.exe | FileCheck -check-prefix=RETPOLINE %s
1717
1818// RETPOLINE: Contents of section .got.plt:
19// RETPOLINE-NEXT: cafe00002000 00300000 feca0000 00000000 00000000
20// RETPOLINE-NEXT: cafe00002010 00000000 00000000 51100000 feca0000
19// RETPOLINE-NEXT: cafe00003000 00200000 feca0000 00000000 00000000
20// RETPOLINE-NEXT: cafe00003010 00000000 00000000 51100000 feca0000
2121
2222.global _start
2323_start:
deps/lld/test/ELF/x86-64-rela.s+2-2
......@@ -1,10 +1,10 @@
11// REQUIRES: x86
22// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -dynamic-table %t.so | FileCheck %s
4// RUN: llvm-readobj --dynamic-table %t.so | FileCheck %s
55// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux-gnux32 %s -o %t.o
66// RUN: ld.lld %t.o -o %t.so -shared
7// RUN: llvm-readobj -dynamic-table %t.so | FileCheck %s
7// RUN: llvm-readobj --dynamic-table %t.so | FileCheck %s
88
99 call foo@plt
1010
deps/lld/test/ELF/x86-64-reloc-16.s deleted-14
......@@ -1,14 +0,0 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-16.s -o %t1
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-16-error.s -o %t2
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
6// RUN: ld.lld -shared %t %t1 -o /dev/null
7
8// CHECK: Contents of section .text:
9// CHECK-NEXT: 200000 42
10
11// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
12// ERROR: relocation R_X86_64_16 out of range: 65536 is not in [0, 65535]
13
14.short foo
deps/lld/test/ELF/x86-64-reloc-8-16.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/abs255.s -o %t255.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/abs256.s -o %t256.o
5# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/abs257.s -o %t257.o
6
7# RUN: ld.lld %t.o %t256.o -o %t
8# RUN: llvm-readelf -x .data %t | FileCheck %s
9# CHECK: 0x{{[0-9a-f]+}} ff80ffff 0080
10
11# RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck --check-prefix=OVERFLOW1 %s
12# OVERFLOW1: relocation R_X86_64_8 out of range: -129 is not in [-128, 255]
13# OVERFLOW1: relocation R_X86_64_16 out of range: -32769 is not in [-32768, 65535]
14
15# RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck --check-prefix=OVERFLOW2 %s
16# OVERFLOW2: relocation R_X86_64_8 out of range: 256 is not in [-128, 255]
17# OVERFLOW2: relocation R_X86_64_16 out of range: 65536 is not in [-32768, 65535]
18
19.globl _start
20_start:
21.data
22.byte foo - 1
23.byte foo - 384
24.word foo + 0xfeff
25.word foo - 0x8100
deps/lld/test/ELF/x86-64-reloc-8.s deleted-14
......@@ -1,14 +0,0 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-8.s -o %t1
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-8-error.s -o %t2
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
6// RUN: ld.lld -shared %t %t1 -o /dev/null
7
8// CHECK: Contents of section .text:
9// CHECK-NEXT: 200000 42
10
11// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
12// ERROR: relocation R_X86_64_8 out of range: 256 is not in [0, 255]
13
14.byte foo
deps/lld/test/ELF/x86-64-reloc-gotoff64.s+6-12
......@@ -4,14 +4,8 @@
44// RUN: llvm-readelf -S %t.so | FileCheck %s -check-prefix=SECTION
55// RUN: llvm-objdump -d %t.so | FileCheck %s
66
7// SECTION: .dynamic DYNAMIC 0000000000003000
8// SECTION: .got PROGBITS 0000000000003070 003070 000000
9
10// All the _GLOBAL_OFFSET_TABLE_ occurrences below refer to the address
11// of GOT base, not the address of the symbol _GLOBAL_OFFSET_TABLE_. These
12// instructions are special and produce GOT base relative relocations. We
13// currently use .got end as the GOT base, which is not equal to
14// the address of the special symbol _GLOBAL_OFFSET_TABLE_.
7// SECTION: .dynamic DYNAMIC 0000000000002000
8// SECTION: .got.plt PROGBITS 0000000000003000 003000 000018
159
1610// The assembly is generated by
1711// gcc -O2 -S -mcmodel=medium -fPIC a.c
......@@ -20,10 +14,10 @@
2014// extern long _DYNAMIC[] __attribute__((visibility("hidden")));
2115// long* dynamic() { return _DYNAMIC; }
2216
23// 0x3070 (.got end) - 0x1007 = 8297
24// 0x3000 (_DYNAMIC) - 0x3070 (.got end) = -112
25// CHECK: 1000: {{.*}} leaq 8297(%rip), %rdx
26// CHECK-NEXT: 1007: {{.*}} movabsq $-112, %rax
17// 0x3000 (.got.plt) - 0x1007 = 8185
18// 0x2000 (_DYNAMIC) - 0x3000 (.got.plt) = -4096
19// CHECK: 1000: {{.*}} leaq 8185(%rip), %rdx
20// CHECK-NEXT: 1007: {{.*}} movabsq $-4096, %rax
2721.global dynamic
2822dynamic:
2923 leaq _GLOBAL_OFFSET_TABLE_(%rip), %rdx
deps/lld/test/ELF/x86-64-reloc-gotpc64.s+3-3
......@@ -4,11 +4,11 @@
44// RUN: llvm-readelf -S %t.so | FileCheck %s -check-prefix=SECTION
55// RUN: llvm-objdump -d %t.so | FileCheck %s
66
7// SECTION: .got PROGBITS 0000000000003070 003070 000000
7// SECTION: .got.plt PROGBITS 0000000000003000 003000 000018
88
9// 0x3070 (.got end) - 0x1000 = 8304
9// 0x3000 (.got.plt) - 0x1000 = 8192
1010// CHECK: gotpc64:
11// CHECK-NEXT: 1000: {{.*}} movabsq $8304, %r11
11// CHECK-NEXT: 1000: {{.*}} movabsq $8192, %r11
1212.global gotpc64
1313gotpc64:
1414 movabsq $_GLOBAL_OFFSET_TABLE_-., %r11
deps/lld/test/ELF/x86-64-retpoline-linkerscript.s+5-4
......@@ -13,9 +13,10 @@
1313// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
1414
1515// CHECK: Disassembly of section .plt:
16// CHECK-EMPTY:
1617// CHECK-NEXT: .plt:
17// CHECK-NEXT: 10: ff 35 72 00 00 00 pushq 114(%rip)
18// CHECK-NEXT: 16: 4c 8b 1d 73 00 00 00 movq 115(%rip), %r11
18// CHECK-NEXT: 10: ff 35 32 01 00 00 pushq 306(%rip)
19// CHECK-NEXT: 16: 4c 8b 1d 33 01 00 00 movq 307(%rip), %r11
1920// CHECK-NEXT: 1d: e8 0e 00 00 00 callq 14 <.plt+0x20>
2021// CHECK-NEXT: 22: f3 90 pause
2122// CHECK-NEXT: 24: 0f ae e8 lfence
......@@ -40,7 +41,7 @@
4041// CHECK-NEXT: 3d: cc int3
4142// CHECK-NEXT: 3e: cc int3
4243// CHECK-NEXT: 3f: cc int3
43// CHECK-NEXT: 40: 4c 8b 1d 51 00 00 00 movq 81(%rip), %r11
44// CHECK-NEXT: 40: 4c 8b 1d 11 01 00 00 movq 273(%rip), %r11
4445// CHECK-NEXT: 47: e8 e4 ff ff ff callq -28 <.plt+0x20>
4546// CHECK-NEXT: 4c: e9 d1 ff ff ff jmp -47 <.plt+0x12>
4647// CHECK-NEXT: 51: 68 00 00 00 00 pushq $0
......@@ -50,7 +51,7 @@
5051// CHECK-NEXT: 5d: cc int3
5152// CHECK-NEXT: 5e: cc int3
5253// CHECK-NEXT: 5f: cc int3
53// CHECK-NEXT: 60: 4c 8b 1d 39 00 00 00 movq 57(%rip), %r11
54// CHECK-NEXT: 60: 4c 8b 1d f9 00 00 00 movq 249(%rip), %r11
5455// CHECK-NEXT: 67: e8 c4 ff ff ff callq -60 <.plt+0x20>
5556// CHECK-NEXT: 6c: e9 b1 ff ff ff jmp -79 <.plt+0x12>
5657// CHECK-NEXT: 71: 68 01 00 00 00 pushq $1
deps/lld/test/ELF/x86-64-retpoline-znow-linkerscript.s+1
......@@ -13,6 +13,7 @@
1313// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
1414
1515// CHECK: Disassembly of section .plt:
16// CHECK-EMPTY:
1617// CHECK-NEXT: .plt:
1718// CHECK-NEXT: 10: e8 0b 00 00 00 callq 11 <.plt+0x10>
1819// CHECK-NEXT: 15: f3 90 pause
deps/lld/test/ELF/x86-64-retpoline-znow.s+1
......@@ -7,6 +7,7 @@
77// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
88
99// CHECK: Disassembly of section .plt:
10// CHECK-EMPTY:
1011// CHECK-NEXT: .plt:
1112// CHECK-NEXT: 1010: e8 0b 00 00 00 callq 11 <.plt+0x10>
1213// CHECK-NEXT: 1015: f3 90 pause
deps/lld/test/ELF/x86-64-retpoline.s+8-7
......@@ -7,9 +7,10 @@
77// RUN: llvm-objdump -d -s %t.exe | FileCheck %s
88
99// CHECK: Disassembly of section .plt:
10// CHECK-EMPTY:
1011// CHECK-NEXT: .plt:
11// CHECK-NEXT: 1010: ff 35 f2 0f 00 00 pushq 4082(%rip)
12// CHECK-NEXT: 1016: 4c 8b 1d f3 0f 00 00 movq 4083(%rip), %r11
12// CHECK-NEXT: 1010: ff 35 f2 1f 00 00 pushq 8178(%rip)
13// CHECK-NEXT: 1016: 4c 8b 1d f3 1f 00 00 movq 8179(%rip), %r11
1314// CHECK-NEXT: 101d: e8 0e 00 00 00 callq 14 <.plt+0x20>
1415// CHECK-NEXT: 1022: f3 90 pause
1516// CHECK-NEXT: 1024: 0f ae e8 lfence
......@@ -34,7 +35,7 @@
3435// CHECK-NEXT: 103d: cc int3
3536// CHECK-NEXT: 103e: cc int3
3637// CHECK-NEXT: 103f: cc int3
37// CHECK-NEXT: 1040: 4c 8b 1d d1 0f 00 00 movq 4049(%rip), %r11
38// CHECK-NEXT: 1040: 4c 8b 1d d1 1f 00 00 movq 8145(%rip), %r11
3839// CHECK-NEXT: 1047: e8 e4 ff ff ff callq -28 <.plt+0x20>
3940// CHECK-NEXT: 104c: e9 d1 ff ff ff jmp -47 <.plt+0x12>
4041// CHECK-NEXT: 1051: 68 00 00 00 00 pushq $0
......@@ -44,7 +45,7 @@
4445// CHECK-NEXT: 105d: cc int3
4546// CHECK-NEXT: 105e: cc int3
4647// CHECK-NEXT: 105f: cc int3
47// CHECK-NEXT: 1060: 4c 8b 1d b9 0f 00 00 movq 4025(%rip), %r11
48// CHECK-NEXT: 1060: 4c 8b 1d b9 1f 00 00 movq 8121(%rip), %r11
4849// CHECK-NEXT: 1067: e8 c4 ff ff ff callq -60 <.plt+0x20>
4950// CHECK-NEXT: 106c: e9 b1 ff ff ff jmp -79 <.plt+0x12>
5051// CHECK-NEXT: 1071: 68 01 00 00 00 pushq $1
......@@ -56,9 +57,9 @@
5657// CHECK-NEXT: 107f: cc int3
5758
5859// CHECK: Contents of section .got.plt:
59// CHECK-NEXT: 2000 00300000 00000000 00000000 00000000
60// CHECK-NEXT: 2010 00000000 00000000 51100000 00000000
61// CHECK-NEXT: 2020 71100000 00000000
60// CHECK-NEXT: 3000 00200000 00000000 00000000 00000000
61// CHECK-NEXT: 3010 00000000 00000000 51100000 00000000
62// CHECK-NEXT: 3020 71100000 00000000
6263
6364.global _start
6465_start:
deps/lld/test/ELF/x86-64-static-tls-model.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2
3## In this test R_X86_64_GOTTPOFF is a IE relocation (static TLS model),
4## test check we add STATIC_TLS flag.
5
6# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
7# RUN: ld.lld %t.o -o %t1 -shared
8# RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s
9
10# CHECK: DynamicSection [
11# CHECK: FLAGS STATIC_TLS
12
13.section ".tdata", "awT", @progbits
14.globl var
15var:
16
17movq var@GOTTPOFF(%rip), %rax # R_X86_64_GOTTPOFF
18movl %fs:0(%rax), %eax
deps/lld/test/ELF/x86-64-tls-gd-local.s+5-5
......@@ -1,7 +1,7 @@
11// REQUIRES: x86
22// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
33// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared
4// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
4// RUN: llvm-readobj -r -S --section-data %t.so | FileCheck %s
55
66 .byte 0x66
77 leaq foo@tlsgd(%rip), %rdi
......@@ -34,8 +34,8 @@ bar:
3434// CHECK-NEXT: SHF_ALLOC (0x2)
3535// CHECK-NEXT: SHF_WRITE (0x1)
3636// CHECK-NEXT: ]
37// CHECK-NEXT: Address: 0x30D0
38// CHECK-NEXT: Offset: 0x30D0
37// CHECK-NEXT: Address: 0x20D0
38// CHECK-NEXT: Offset: 0x20D0
3939// CHECK-NEXT: Size: 32
4040// CHECK-NEXT: Link: 0
4141// CHECK-NEXT: Info: 0
......@@ -47,6 +47,6 @@ bar:
4747// CHECK-NEXT: )
4848
4949// CHECK: Section ({{.*}}) .rela.dyn {
50// CHECK-NEXT: 0x30D0 R_X86_64_DTPMOD64 - 0x0
51// CHECK-NEXT: 0x30E0 R_X86_64_DTPMOD64 - 0x0
50// CHECK-NEXT: 0x20D0 R_X86_64_DTPMOD64 - 0x0
51// CHECK-NEXT: 0x20E0 R_X86_64_DTPMOD64 - 0x0
5252// CHECK-NEXT: }
deps/lld/test/ELF/x86-64-tls-ld-local.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: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -r -s %t.so | FileCheck %s
4// RUN: llvm-readobj -r -S %t.so | FileCheck %s
55
66// CHECK: Relocations [
77// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
deps/lld/test/ELF/x86-64-tls-ld-preemptable.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: ld.lld %t.o -shared -o %t.so
4# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s
5
6# CHECK: 100c: leaq (%rax), %rax
7# CHECK-NEXT: 1013: movabsq 0, %rax
8
9# We used to error on R_X86_64_DTPOFF{32,64} to preemptable symbols.
10# i is STB_GLOBAL and preemptable.
11 leaq i@TLSLD(%rip), %rdi
12 callq __tls_get_addr@PLT
13 leaq i@DTPOFF(%rax), %rax # R_X86_64_DTPOFF32
14 movabsq i@DTPOFF, %rax # R_X86_64_DTPOFF64
15
16.section .tbss,"awT",@nobits
17.globl i
18i:
19 .long 0
20 .size i, 4
deps/lld/test/ELF/x86-64-tls-le-align.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
5
6# -alignTo(p_memsz, p_align) = -alignTo(4, 64) = -64
7
8# CHECK: movl %fs:-64, %eax
9
10 movl %fs:a@TPOFF, %eax
11
12.section .tbss,"awT"
13.align 64
14a:
15.long 0
16.size a, 4
deps/lld/test/ELF/x86-64-tls-le-undef.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: ld.lld --noinhibit-exec %t.o -o %t 2>&1
4# RUN: llvm-objdump -d %t | FileCheck %s
5
6## Undefined TLS symbols resolve to 0.
7## In --noinhibit-exec mode, a non-weak undefined symbol is not an error.
8
9# CHECK: leaq 16(%rax), %rdx
10# CHECK-NEXT: leaq 32(%rax), %rdx
11
12.weak weak
13movq %fs:0, %rax
14leaq weak@tpoff+16(%rax), %rdx
15leaq global@tpoff+32(%rax), %rdx
deps/lld/test/ELF/x86-64-tlsdesc-gd.s created+69
......@@ -0,0 +1,69 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3# RUN: echo '.tbss; .globl b; b:' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
4# RUN: ld.lld -shared -soname=t1.so %t1.o -o %t1.so
5
6# RUN: ld.lld -shared %t.o %t1.o -o %t.so
7# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=GD-REL %s
8# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=GD %s
9
10# RUN: ld.lld %t.o %t1.o -o %t
11# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
12# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
13
14# RUN: ld.lld %t.o %t1.so -o %t
15# RUN: llvm-readobj -r %t | FileCheck --check-prefix=IE-REL %s
16# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=IE %s
17
18# GD-REL: .rela.dyn {
19# GD-REL-NEXT: 0x20A0 R_X86_64_TLSDESC a 0x0
20# GD-REL-NEXT: 0x20B0 R_X86_64_TLSDESC b 0x0
21# GD-REL-NEXT: }
22
23# 0x20a0-0x1007 = 4249
24# GD: leaq 4249(%rip), %rax
25# GD-NEXT: 1007: callq *(%rax)
26# GD-NEXT: movl %fs:(%rax), %eax
27
28# 0x20b0-0x1013 = 4253
29# GD-NEXT: leaq 4253(%rip), %rax
30# GD-NEXT: 1013: callq *(%rax)
31# GD-NEXT: movl %fs:(%rax), %eax
32
33# NOREL: no relocations
34
35## offset(a) = -4
36# LE: movq $-4, %rax
37# LE-NEXT: nop
38# LE-NEXT: movl %fs:(%rax), %eax
39## offset(b) = 0
40# LE: movq $0, %rax
41# LE-NEXT: nop
42# LE-NEXT: movl %fs:(%rax), %eax
43
44# IE-REL: .rela.dyn {
45# IE-REL-NEXT: 0x2020C0 R_X86_64_TPOFF64 b 0x0
46# IE-REL-NEXT: }
47
48## a is relaxed to use LE.
49# IE: movq $-4, %rax
50# IE-NEXT: nop
51# IE-NEXT: movl %fs:(%rax), %eax
52## 0x2020C0 - 0x201013 = 4269
53# IE-NEXT: movq 4269(%rip), %rax
54# IE-NEXT: 201013: nop
55# IE-NEXT: movl %fs:(%rax), %eax
56
57leaq a@tlsdesc(%rip), %rax
58call *a@tlscall(%rax)
59movl %fs:(%rax), %eax
60
61leaq b@tlsdesc(%rip), %rax
62call *b@tlscall(%rax)
63movl %fs:(%rax), %eax
64
65.section .tbss
66.globl a
67.zero 8
68a:
69.zero 4
deps/lld/test/ELF/x86-64-tlsdesc-ld.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
3
4# RUN: ld.lld -shared %t.o -o %t.so
5# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=LD-REL %s
6# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck --check-prefix=LD %s
7
8# RUN: ld.lld %t.o -o %t
9# RUN: llvm-readelf -r %t | FileCheck --check-prefix=NOREL %s
10# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
11
12## Check _TLS_MODULE_BASE_ used by LD produces a dynamic relocation with a value of 0.
13# LD-REL: .rela.dyn {
14# LD-REL-NEXT: 0x20A0 R_X86_64_TLSDESC - 0x0
15# LD-REL-NEXT: }
16
17## 0x20a0-0x1007 = 4249
18## dtpoff(a) = 8, dtpoff(b) = 12
19# LD: leaq 4249(%rip), %rax
20# LD-NEXT: 1007: callq *(%rax)
21# LD-NEXT: movl %fs:8(%rax), %edx
22# LD-NEXT: addl %fs:12(%rax), %edx
23
24## When producing an executable, the LD code sequence can be relaxed to LE.
25## It is the same as GD->LE.
26## tpoff(_TLS_MODULE_BASE_) = 0, tpoff(a) = -8, tpoff(b) = -4
27
28# NOREL: no relocations
29
30# LE: movq $0, %rax
31# LE-NEXT: nop
32# LE-NEXT: movl %fs:-8(%rax), %edx
33# LE-NEXT: addl %fs:-4(%rax), %edx
34
35leaq _TLS_MODULE_BASE_@tlsdesc(%rip), %rax
36call *_TLS_MODULE_BASE_@tlscall(%rax)
37movl %fs:a@dtpoff(%rax), %edx
38addl %fs:b@dtpoff(%rax), %edx
39
40.section .tbss
41.zero 8
42a:
43.zero 4
44b:
45.zero 4
deps/lld/test/ELF/x86-property-relocatable.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 -r %t.o -o %t2.o
4# RUN: llvm-readelf -n %t2.o | FileCheck -match-full-lines %s
5
6## Test that .note.gnu.property is passed through -r, and that we can handle
7## more than one FEATURE_AND in the same object file. This is logically the
8## same as if the features were combined in a single FEATURE_AND as the rule
9## states that the bit in the output pr_data field if it is set in all
10.text
11ret
12
13.section ".note.gnu.property", "a"
14.p2align 3
15.long 4
16.long 0x10
17.long 0x5
18.asciz "GNU"
19
20.long 0xc0000002 // GNU_PROPERTY_X86_FEATURE_1_AND
21.long 4
22.long 1 // GNU_PROPERTY_X86_FEATURE_1_IBT
23.long 0
24
25.long 4
26.long 0x10
27.long 0x5
28.asciz "GNU"
29.long 0xc0000002 // GNU_PROPERTY_X86_FEATURE_1_AND
30.long 4
31.long 2 // GNU_PROPERTY_X86_FEATURE_1_SHSTK
32.long 0
33
34# CHECK: Owner Data size Description
35# CHECK-NEXT: GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 (property note)
36# CHECK-NEXT: Properties: x86 feature: IBT, SHSTK
deps/lld/test/ELF/znotext-plt-relocations.s+2-1
......@@ -16,5 +16,6 @@
1616
1717.text
1818_start:
19callq atexit
19.byte 0xe8
20.long atexit - . - 4
2021.quad foo
deps/lld/test/ELF/zstack-size.s+3-3
......@@ -1,13 +1,13 @@
11# REQUIRES: x86
22# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
33# RUN: ld.lld -z stack-size=0x1000 %t -o %t1
4# RUN: llvm-readobj -program-headers %t1 | FileCheck %s -check-prefix=CHECK1
4# RUN: llvm-readobj -l %t1 | FileCheck %s -check-prefix=CHECK1
55
66# RUN: ld.lld -z stack-size=0 %t -o %t2
7# RUN: llvm-readobj -program-headers %t2 | FileCheck %s -check-prefix=CHECK2
7# RUN: llvm-readobj -l %t2 | FileCheck %s -check-prefix=CHECK2
88
99# 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
10# RUN: llvm-readobj -l %t3 | FileCheck %s -check-prefix=CHECK1
1111
1212.global _start
1313_start:
deps/lld/test/ELF/ztext.s+3-3
......@@ -4,11 +4,11 @@
44# RUN: ld.lld %t2.o -o %t2.so -shared
55
66# RUN: ld.lld -z notext %t.o %t2.so -o %t -shared
7# RUN: llvm-readobj -dynamic-table -r %t | FileCheck %s
7# RUN: llvm-readobj --dynamic-table -r %t | FileCheck %s
88# RUN: ld.lld -z notext %t.o %t2.so -o %t2 -pie
9# RUN: llvm-readobj -dynamic-table -r %t2 | FileCheck %s
9# RUN: llvm-readobj --dynamic-table -r %t2 | FileCheck %s
1010# RUN: ld.lld -z notext %t.o %t2.so -o %t3
11# RUN: llvm-readobj -dynamic-table -r %t3 | FileCheck --check-prefix=STATIC %s
11# RUN: llvm-readobj --dynamic-table -r %t3 | FileCheck --check-prefix=STATIC %s
1212
1313# RUN: not ld.lld %t.o %t2.so -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s
1414# RUN: not ld.lld -z text %t.o %t2.so -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s
deps/lld/test/MinGW/driver.test+49
......@@ -4,6 +4,9 @@ X86-SAME: -machine:x86
44X86-SAME: -alternatename:__image_base__=___ImageBase
55X86-SAME: foo.o
66
7RUN: echo "-### foo.o -m i386pe" > %t.rsp
8RUN: ld.lld @%t.rsp | FileCheck -check-prefix=X86 %s
9
710RUN: ld.lld -### foo.o -m i386pep | FileCheck -check-prefix=X64 %s
811X64: -out:a.exe
912X64-SAME: -machine:x64
......@@ -54,8 +57,24 @@ MLLVM: -mllvm:bar -mllvm:baz
5457
5558RUN: ld.lld -### foo.o -m i386pep -subsystem console | FileCheck -check-prefix=SUBSYSTEM %s
5659RUN: ld.lld -### foo.o -m i386pep --subsystem console | FileCheck -check-prefix=SUBSYSTEM %s
60RUN: ld.lld -### foo.o -m i386pep -subsystem=console | FileCheck -check-prefix=SUBSYSTEM %s
61RUN: ld.lld -### foo.o -m i386pep --subsystem=console | FileCheck -check-prefix=SUBSYSTEM %s
5762SUBSYSTEM: -subsystem:console
5863
64RUN: ld.lld -### foo.o -m i386pep --major-os-version 7 --minor-os-version 8 | FileCheck -check-prefix=SUBSYSTEM_VERSION %s
65RUN: ld.lld -### foo.o -m i386pep --major-subsystem-version 7 --minor-subsystem-version 8 | FileCheck -check-prefix=SUBSYSTEM_VERSION %s
66RUN: ld.lld -### foo.o -m i386pep --major-os-version=7 --minor-os-version=8 --major-subsystem-version=7 --minor-subsystem-version=8 | FileCheck -check-prefix=SUBSYSTEM_VERSION %s
67SUBSYSTEM_VERSION: -subsystem:default,7.8
68
69RUN: ld.lld -### foo.o -m i386pep --minor-subsystem-version 8 | FileCheck -check-prefix=SUBSYSTEM_DEFAULT_MAJOR %s
70SUBSYSTEM_DEFAULT_MAJOR: -subsystem:default,6.8
71
72RUN: ld.lld -### foo.o -m i386pep --major-subsystem-version 7 | FileCheck -check-prefix=SUBSYSTEM_DEFAULT_MINOR %s
73SUBSYSTEM_DEFAULT_MINOR: -subsystem:default,7
74
75RUN: ld.lld -### foo.o -m i386pep --subsystem windows --major-os-version 7 --minor-os-version 8 | FileCheck -check-prefix=SUBSYSTEM_WINDOWS %s
76SUBSYSTEM_WINDOWS: -subsystem:windows,7.8
77
5978RUN: ld.lld -### foo.o -m i386pep -stack 4194304,8192 | FileCheck -check-prefix=STACK %s
6079RUN: ld.lld -### foo.o -m i386pep --stack 4194304,8192 | FileCheck -check-prefix=STACK %s
6180STACK: -stack:4194304,8192
......@@ -74,6 +93,9 @@ WHOLE-ARCHIVE: foo.o -wholearchive:bar.a baz.a
7493RUN: ld.lld -### -m i386pep foo.o | FileCheck -check-prefix MINGW-FLAG %s
7594MINGW-FLAG: -lldmingw
7695
96RUN: ld.lld -### -m i386pep foo.o --exclude-all-symbols | FileCheck -check-prefix EXCLUDE-ALL %s
97EXCLUDE-ALL: -exclude-all-symbols
98
7799RUN: ld.lld -### -m i386pep foo.o --export-all-symbols | FileCheck -check-prefix EXPORT-ALL %s
78100EXPORT-ALL: -export-all-symbols
79101
......@@ -96,9 +118,14 @@ STRIP-DEBUG: -debug:symtab
96118STRIP-DEBUG-NOT: -debug:dwarf
97119
98120RUN: ld.lld -### -m i386pep foo.o -pdb out.pdb | FileCheck -check-prefix PDB %s
121RUN: ld.lld -### -m i386pep foo.o -pdb=out.pdb | FileCheck -check-prefix PDB %s
99122PDB: -debug -pdb:out.pdb
100123PDB-NOT: -debug:dwarf
101124
125RUN: ld.lld -### -m i386pep foo.o -pdb= | FileCheck -check-prefix PDB-DEFAULT %s
126PDB-DEFAULT: -debug
127PDB-DEFAULT-NOT: -pdb:{{.*}}
128
102129RUN: ld.lld -### -m i386pep foo.o --large-address-aware | FileCheck -check-prefix LARGE-ADDRESS-AWARE %s
103130LARGE-ADDRESS-AWARE: -largeaddressaware
104131
......@@ -149,5 +176,27 @@ MAP: -lldmap:bar.map
149176RUN: ld.lld -### foo.o -m i386pe -require-defined _foo --require-defined _bar -require-defined=_baz --require-defined=_foo2 | FileCheck -check-prefix=REQUIRE-DEFINED %s
150177REQUIRE-DEFINED: -include:_foo -include:_bar -include:_baz -include:_foo2
151178
179RUN: ld.lld -### foo.o -m i386pe -u _foo --undefined _bar -undefined=_baz --undefined=_foo2 | FileCheck -check-prefix=UNDEFINED %s
180UNDEFINED: -includeoptional:_foo -includeoptional:_bar -includeoptional:_baz -includeoptional:_foo2
181
152182RUN: ld.lld -### -m i386pep foo.o -Llibpath | FileCheck -check-prefix LIBPATH %s
153183LIBPATH: -libpath:libpath
184
185RUN: ld.lld -### -m i386pep foo.o --no-insert-timestamp | FileCheck -check-prefix NOTIMESTAMP %s
186RUN: ld.lld -### -m i386pep foo.o --insert-timestamp --no-insert-timestamp | FileCheck -check-prefix NOTIMESTAMP %s
187NOTIMESTAMP: -timestamp:0
188RUN: ld.lld -### -m i386pep foo.o --no-insert-timestamp --insert-timestamp | FileCheck -check-prefix TIMESTAMP %s
189TIMESTAMP-NOT: -timestamp:0
190
191RUN: ld.lld -### -m i386pep foo.o -appcontainer | FileCheck -check-prefix APPCONTAINER %s
192RUN: ld.lld -### -m i386pep foo.o --appcontainer | FileCheck -check-prefix APPCONTAINER %s
193APPCONTAINER: -appcontainer
194
195# RUN: ld.lld -m i386pep --version 2>&1 | FileCheck -check-prefix=VERSION %s
196# RUN: ld.lld -m i386pep -v 2>&1 | FileCheck -check-prefix=VERSION %s
197# RUN: not ld.lld -m i386pep -v xyz 2>&1 | FileCheck -check-prefix=VERSION %s
198# VERSION: LLD {{.*}} (compatible with GNU linkers)
199
200# RUN: ld.lld -m i386pep --help 2>&1 | FileCheck -check-prefix=HELP %s
201# HELP: USAGE:
202# HELP: --enable-auto-import
deps/lld/test/lit.cfg.py+6-3
......@@ -87,16 +87,19 @@ config.environment['LLD_IN_TEST'] = '1'
8787# Indirectly check if the mt.exe Microsoft utility exists by searching for
8888# cvtres, which always accompanies it. Alternatively, check if we can use
8989# libxml2 to merge manifests.
90if (lit.util.which('cvtres', config.environment['PATH'])) or \
91 (config.llvm_libxml2_enabled == '1'):
90if (lit.util.which('cvtres', config.environment['PATH']) or
91 config.llvm_libxml2_enabled):
9292 config.available_features.add('manifest_tool')
9393
94if (config.llvm_libxml2_enabled == '1'):
94if config.llvm_libxml2_enabled:
9595 config.available_features.add('libxml2')
9696
9797if config.have_dia_sdk:
9898 config.available_features.add("diasdk")
9999
100if config.sizeof_void_p == 8:
101 config.available_features.add("llvm-64-bits")
102
100103tar_executable = lit.util.which('tar', config.environment['PATH'])
101104if tar_executable:
102105 tar_version = subprocess.Popen(
deps/lld/test/lit.site.cfg.py.in+2-1
......@@ -7,7 +7,7 @@ config.llvm_src_root = "@LLVM_SOURCE_DIR@"
77config.llvm_obj_root = "@LLVM_BINARY_DIR@"
88config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
99config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
10config.llvm_libxml2_enabled = "@LLVM_LIBXML2_ENABLED@"
10config.llvm_libxml2_enabled = @LLVM_LIBXML2_ENABLED@
1111config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
1212config.lld_obj_root = "@LLD_BINARY_DIR@"
1313config.lld_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@"
......@@ -15,6 +15,7 @@ config.lld_tools_dir = "@LLVM_RUNTIME_OUTPUT_INTDIR@"
1515config.target_triple = "@TARGET_TRIPLE@"
1616config.python_executable = "@PYTHON_EXECUTABLE@"
1717config.have_zlib = @HAVE_LIBZ@
18config.sizeof_void_p = @CMAKE_SIZEOF_VOID_P@
1819
1920# Support substitution of the tools and libs dirs with user parameters. This is
2021# used when we can't determine the tool dir at configuration time.
deps/lld/test/mach-o/arm-interworking.yaml+1-1
......@@ -2,7 +2,7 @@
22# RUN: %p/Inputs/arm-interworking.yaml -o %t | FileCheck %s \
33# RUN: && ld64.lld -arch armv7 -dylib -print_atoms \
44# RUN: %p/Inputs/armv7/libSystem.yaml %t -o %t2 | FileCheck %s \
5# RUN: && llvm-readobj -s -sd %t2 | FileCheck -check-prefix=CODE %s
5# RUN: && llvm-readobj -S --section-data %t2 | FileCheck -check-prefix=CODE %s
66#
77# Test thumb and arm branches round trip through -r.
88# Test bl/blx instructions are fixed up properly.
deps/lld/test/mach-o/arm-shims.yaml+1-1
......@@ -1,6 +1,6 @@
11# RUN: ld64.lld -arch armv7 %s %p/Inputs/arm-shims.yaml \
22# RUN: -dylib %p/Inputs/armv7/libSystem.yaml -o %t
3# RUN: llvm-readobj -s -sd %t | FileCheck %s
3# RUN: llvm-readobj -S --section-data %t | FileCheck %s
44#
55# Test b from arm to thumb or vice versa has shims added.s
66#
deps/lld/test/mach-o/exe-offsets.yaml+1-1
......@@ -1,5 +1,5 @@
11# RUN: ld64.lld -arch x86_64 %s -o %t -e start %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-readobj -sections %t | FileCheck %s
2# RUN: llvm-readobj --sections %t | FileCheck %s
33
44# Make sure data gets put at offset
55
deps/lld/test/mach-o/exe-segment-overlap.yaml+1-1
......@@ -1,5 +1,5 @@
11# RUN: ld64.lld -arch x86_64 %s -o %t %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-readobj -sections -section-data %t | FileCheck %s
2# RUN: llvm-readobj --sections --section-data %t | FileCheck %s
33
44--- !native
55defined-atoms:
deps/lld/test/mach-o/executable-exports.yaml+1-1
......@@ -1,6 +1,6 @@
11# RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 \
22# RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t && \
3# RUN: llvm-objdump -exports-trie %t | FileCheck %s
3# RUN: llvm-objdump -macho -exports-trie %t | FileCheck %s
44#
55#
66# Tests that exports trie builds properly.
deps/lld/test/mach-o/export-trie-order.yaml+1-1
......@@ -1,5 +1,5 @@
11# RUN: ld64.lld -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t
2# RUN: llvm-objdump -exports-trie %t | FileCheck %s
2# RUN: llvm-objdump -macho -exports-trie %t | FileCheck %s
33#
44# Test that the export trie is emitted in order.
55#
deps/lld/test/mach-o/got-order.yaml+1-1
......@@ -1,6 +1,6 @@
11# RUN: ld64.lld -arch x86_64 %s %p/Inputs/got-order.yaml \
22# RUN: %p/Inputs/got-order2.yaml -o %t %p/Inputs/x86_64/libSystem.yaml
3# RUN: llvm-objdump -bind %t | FileCheck %s
3# RUN: llvm-objdump -macho -bind %t | FileCheck %s
44#
55# Test that GOT slots are sorted by name
66#
deps/lld/test/mach-o/image-base.yaml+1-1
......@@ -1,5 +1,5 @@
11# RUN: ld64.lld -arch x86_64 -macosx_version_min 10.9 %s -o %t -image_base 31415926000 %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-readobj -macho-segment %t | FileCheck %s
2# RUN: llvm-readobj --macho-segment %t | FileCheck %s
33# RUN: not ld64.lld -arch x86_64 -image_base 0x31415926530 %s >/dev/null 2> %t
44# RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-MISPAGED
55# RUN: not ld64.lld -arch x86_64 -image_base 1000 %s >/dev/null 2> %t
deps/lld/test/mach-o/lazy-bind-x86_64.yaml+1-1
......@@ -4,7 +4,7 @@
44# RUN: %p/Inputs/lazy-bind-x86_64.yaml %p/Inputs/lazy-bind-x86_64-2.yaml \
55# RUN: %p/Inputs/lazy-bind-x86_64-3.yaml -o %t \
66# RUN: %p/Inputs/x86_64/libSystem.yaml
7# RUN: llvm-objdump -lazy-bind %t | FileCheck %s
7# RUN: llvm-objdump -macho -lazy-bind %t | FileCheck %s
88# RUN: llvm-nm -m %t | FileCheck --check-prefix=CHECK-NM %s
99# RUN: llvm-objdump -disassemble %t | FileCheck --check-prefix=CHECK-HELPERS %s
1010# RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-DYLIBS %s
deps/lld/test/mach-o/load-commands-size.yaml created+305
......@@ -0,0 +1,305 @@
1# RUN: ld64.lld -arch x86_64 %s -o %t -dylib \
2# RUN: -macosx_version_min 10.10 -sdk_version 10.10 \
3# RUN: -install_name /usr/lib/foo.dylib \
4# RUN: %p/Inputs/x86_64/libSystem.yaml && \
5# RUN: llvm-readobj %t
6
7# (Tests that lld doesn't crash or produce an invalid file.)
8
9--- !native
10path: '<linker-internal>'
11defined-atoms:
12 - name: _foo
13 scope: global
14 type: unknown
15 content: [ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
16 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
17 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
18 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
19 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
20 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
21 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
22 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
23 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
24 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
25 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
26 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
27 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
28 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
29 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
30 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
31 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
32 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
33 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
34 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
35 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
36 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
37 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
38 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
39 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
40 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
41 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
42 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
43 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
44 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
45 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
46 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
47 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
48 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
49 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
50 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
51 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
52 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
53 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
54 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
55 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
56 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
57 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
58 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
59 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
60 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
61 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
62 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
63 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
64 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
65 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
66 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
67 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
68 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
69 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
70 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
71 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
72 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
73 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
74 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
75 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
76 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
77 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
78 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
79 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
80 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
81 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
82 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
83 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
84 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
85 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
86 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
87 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
88 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
89 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
90 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
91 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
92 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
93 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
94 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
95 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
96 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
97 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
98 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
99 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
100 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
101 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
102 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
103 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
104 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
105 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
106 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
107 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
108 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
109 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
110 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
111 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
112 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
113 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
114 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
115 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
116 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
117 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
118 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
119 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
120 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
121 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
122 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
123 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
124 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
125 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
126 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
127 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
128 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
129 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
130 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
131 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
132 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
133 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
134 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
135 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
136 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
137 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
138 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
139 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
140 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
141 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
142 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
143 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
144 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
145 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
146 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
147 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
148 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
149 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
150 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
151 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
152 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
153 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
154 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
155 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
156 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
157 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
158 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
159 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
160 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
161 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
162 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
163 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
164 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
165 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
166 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
167 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
168 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
169 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
170 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
171 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
172 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
173 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
174 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
175 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
176 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
177 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
178 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
179 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
180 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
181 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
182 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
183 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
184 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
185 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
186 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
187 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
188 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
189 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
190 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
191 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
192 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
193 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
194 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
195 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
196 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
197 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
198 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
199 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
200 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
201 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
202 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
203 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
204 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
205 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
206 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
207 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
208 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
209 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
210 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
211 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
212 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
213 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
214 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
215 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
216 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
217 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
218 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
219 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
220 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
221 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
222 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
223 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
224 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
225 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
226 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
227 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
228 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
229 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
230 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
231 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
232 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
233 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
234 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
235 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
236 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
237 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
238 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
239 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
240 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
241 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
242 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
243 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
244 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
245 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
246 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
247 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
248 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
249 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
250 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
251 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
252 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
253 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
254 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
255 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
256 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
257 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
258 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
259 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
260 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
261 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
262 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
263 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
264 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
265 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
266 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
267 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
268 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
269 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
270 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
271 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
272 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
273 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
274 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
275 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
276 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
277 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
278 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
279 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
280 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
281 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
282 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
283 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
284 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
285 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
286 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
287 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
288 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
289 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
290 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
291 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
292 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
293 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
294 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
295 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
296 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
297 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
298 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
299 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
300 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
301 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
302 00, 00, 00, 00 ]
303 alignment: 16
304 section-choice: custom-required
305 section-name: '__TEXT/__foo'
deps/lld/test/mach-o/sectalign.yaml+1-1
......@@ -1,7 +1,7 @@
11# RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -dylib \
22# RUN: -sectalign __DATA __custom 0x800 -sectalign __TEXT __text 0x400 \
33# RUN: %p/Inputs/x86_64/libSystem.yaml -o %t \
4# RUN: && llvm-readobj -sections %t | FileCheck %s
4# RUN: && llvm-readobj --sections %t | FileCheck %s
55#
66# Test -sectalign option on __text and a custom section.
77#
deps/lld/test/mach-o/subsections-via-symbols-default.yaml+1-1
......@@ -1,5 +1,5 @@
11# RUN: ld64.lld -ios_simulator_version_min 5.0 -arch x86_64 -r %s -o %t
2# RUN: llvm-readobj -file-headers %t | FileCheck %s
2# RUN: llvm-readobj --file-headers %t | FileCheck %s
33
44# Make sure that we have an objc image info in the output. It should have
55# been generated by the objc pass.
deps/lld/test/mach-o/write-final-sections.yaml+1-1
......@@ -1,6 +1,6 @@
11# RUN: ld64.lld -arch x86_64 %s %p/Inputs/write-final-sections.yaml \
22# RUN: -o %t -e _foo
3# RUN: llvm-readobj -sections -section-data %t | FileCheck %s
3# RUN: llvm-readobj --sections --section-data %t | FileCheck %s
44
55--- !native
66defined-atoms:
deps/lld/test/wasm/Inputs/call-ret32.ll created+11
......@@ -0,0 +1,11 @@
1target triple = "wasm32-unknown-unknown"
2
3@ret32_address = global i32 (float)* @ret32, align 4
4
5define hidden i32* @call_ret32() {
6entry:
7 %call1 = call i32 @ret32(float 0.000000e+00)
8 ret i32* bitcast (i32 (float)** @ret32_address to i32*)
9}
10
11declare i32 @ret32(float)
deps/lld/test/wasm/Inputs/comdat1.ll+16-7
......@@ -1,13 +1,22 @@
11target triple = "wasm32-unknown-unknown"
22
3$inlineFn = comdat any
4@constantData = weak_odr constant [3 x i8] c"abc", comdat($inlineFn)
5define linkonce_odr i32 @inlineFn() comdat {
6entry:
3$foo = comdat any
4
5@constantData = constant [3 x i8] c"abc", comdat($foo)
6
7define i32 @comdatFn() comdat($foo) {
78 ret i32 ptrtoint ([3 x i8]* @constantData to i32)
89}
910
10define i32 @callInline1() {
11entry:
12 ret i32 ptrtoint (i32 ()* @inlineFn to i32)
11define internal void @do_init() comdat($foo) {
12 ret void
13}
14
15%0 = type { i32, void ()*, i8* }
16@llvm.global_ctors = appending global [1 x %0 ] [%0 { i32 65535, void ()* @do_init, i8* null }]
17
18; Everything above this is part of the `foo` comdat group
19
20define i32 @callComdatFn1() {
21 ret i32 ptrtoint (i32 ()* @comdatFn to i32)
1322}
deps/lld/test/wasm/Inputs/comdat2.ll+16-7
......@@ -1,13 +1,22 @@
11target triple = "wasm32-unknown-unknown"
22
3$inlineFn = comdat any
4@constantData = weak_odr constant [3 x i8] c"abc", comdat($inlineFn)
5define linkonce_odr i32 @inlineFn() comdat {
6entry:
3$foo = comdat any
4
5@constantData = constant [3 x i8] c"abc", comdat($foo)
6
7define i32 @comdatFn() comdat($foo) {
78 ret i32 ptrtoint ([3 x i8]* @constantData to i32)
89}
910
10define i32 @callInline2() {
11entry:
12 ret i32 ptrtoint (i32 ()* @inlineFn to i32)
11define internal void @do_init() comdat($foo) {
12 ret void
13}
14
15%0 = type { i32, void ()*, i8* }
16@llvm.global_ctors = appending global [1 x %0] [ %0 { i32 65535, void ()* @do_init, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @constantData, i32 0, i32 0) }]
17
18; Everything above this is part of the `foo` comdat group
19
20define i32 @callComdatFn2() {
21 ret i32 ptrtoint (i32 ()* @comdatFn to i32)
1322}
deps/lld/test/wasm/Inputs/disallow-feature-foo.yaml created+13
......@@ -0,0 +1,13 @@
1--- !WASM
2FileHeader:
3 Version: 0x00000001
4Sections:
5 - Type: CUSTOM
6 Name: linking
7 Version: 2
8 - Type: CUSTOM
9 Name: target_features
10 Features:
11 - Prefix: DISALLOWED
12 Name: "foo"
13...
deps/lld/test/wasm/Inputs/explicit-section.ll created+4
......@@ -0,0 +1,4 @@
1target triple = "wasm32-unknown-unknown"
2
3@var1 = global i32 42, section "mysection", align 4
4@var2 = global i32 43, section "mysection", align 4
deps/lld/test/wasm/Inputs/globals.yaml+1-1
......@@ -29,7 +29,7 @@ Sections:
2929 Locals:
3030 Body: 2381808080000B
3131 Relocations:
32 - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
32 - Type: R_WASM_GLOBAL_INDEX_LEB
3333 Index: 1
3434 Offset: 0x00000004
3535 - Type: CUSTOM
deps/lld/test/wasm/Inputs/no-feature-foo.yaml created+11
......@@ -0,0 +1,11 @@
1--- !WASM
2FileHeader:
3 Version: 0x00000001
4Sections:
5 - Type: CUSTOM
6 Name: linking
7 Version: 2
8 - Type: CUSTOM
9 Name: target_features
10 Features: [ ]
11...
deps/lld/test/wasm/Inputs/require-feature-foo.yaml created+13
......@@ -0,0 +1,13 @@
1--- !WASM
2FileHeader:
3 Version: 0x00000001
4Sections:
5 - Type: CUSTOM
6 Name: linking
7 Version: 2
8 - Type: CUSTOM
9 Name: target_features
10 Features:
11 - Prefix: REQUIRED
12 Name: "foo"
13...
deps/lld/test/wasm/Inputs/undefined-globals.yaml+1-1
......@@ -27,7 +27,7 @@ Sections:
2727 Locals:
2828 Body: 2381808080000B
2929 Relocations:
30 - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
30 - Type: R_WASM_GLOBAL_INDEX_LEB
3131 Index: 1
3232 Offset: 0x00000004
3333 - Type: CUSTOM
deps/lld/test/wasm/Inputs/use-feature-foo.yaml created+13
......@@ -0,0 +1,13 @@
1--- !WASM
2FileHeader:
3 Version: 0x00000001
4Sections:
5 - Type: CUSTOM
6 Name: linking
7 Version: 2
8 - Type: CUSTOM
9 Name: target_features
10 Features:
11 - Prefix: USED
12 Name: "foo"
13...
deps/lld/test/wasm/alias.ll+3-26
......@@ -22,7 +22,7 @@ entry:
2222; CHECK-NEXT: ReturnType: NORESULT
2323; CHECK-NEXT: ParamTypes:
2424; CHECK-NEXT: - Type: FUNCTION
25; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
25; CHECK-NEXT: FunctionTypes: [ 0 ]
2626; CHECK-NEXT: - Type: TABLE
2727; CHECK-NEXT: Tables:
2828; CHECK-NEXT: - ElemType: FUNCREF
......@@ -41,48 +41,25 @@ entry:
4141; CHECK-NEXT: InitExpr:
4242; CHECK-NEXT: Opcode: I32_CONST
4343; CHECK-NEXT: Value: 66560
44; CHECK-NEXT: - Index: 1
45; CHECK-NEXT: Type: I32
46; CHECK-NEXT: Mutable: false
47; CHECK-NEXT: InitExpr:
48; CHECK-NEXT: Opcode: I32_CONST
49; CHECK-NEXT: Value: 66560
50; CHECK-NEXT: - Index: 2
51; CHECK-NEXT: Type: I32
52; CHECK-NEXT: Mutable: false
53; CHECK-NEXT: InitExpr:
54; CHECK-NEXT: Opcode: I32_CONST
55; CHECK-NEXT: Value: 1024
5644; CHECK-NEXT: - Type: EXPORT
5745; CHECK-NEXT: Exports:
5846; CHECK-NEXT: - Name: memory
5947; CHECK-NEXT: Kind: MEMORY
6048; CHECK-NEXT: Index: 0
61; CHECK-NEXT: - Name: __heap_base
62; CHECK-NEXT: Kind: GLOBAL
63; CHECK-NEXT: Index: 1
64; CHECK-NEXT: - Name: __data_end
65; CHECK-NEXT: Kind: GLOBAL
66; CHECK-NEXT: Index: 2
6749; CHECK-NEXT: - Name: _start
6850; CHECK-NEXT: Kind: FUNCTION
69; CHECK-NEXT: Index: 1
51; CHECK-NEXT: Index: 0
7052; CHECK-NEXT: - Name: start_alias
7153; CHECK-NEXT: Kind: FUNCTION
72; CHECK-NEXT: Index: 1
54; CHECK-NEXT: Index: 0
7355; CHECK-NEXT: - Type: CODE
7456; CHECK-NEXT: Functions:
7557; CHECK-NEXT: - Index: 0
7658; CHECK-NEXT: Locals:
7759; CHECK-NEXT: Body: 0B
78; CHECK-NEXT: - Index: 1
79; CHECK-NEXT: Locals:
80; CHECK-NEXT: Body: 0B
8160; CHECK-NEXT: - Type: CUSTOM
8261; CHECK-NEXT: Name: name
8362; CHECK-NEXT: FunctionNames:
8463; CHECK-NEXT: - Index: 0
85; CHECK-NEXT: Name: __wasm_call_ctors
86; CHECK-NEXT: - Index: 1
8764; CHECK-NEXT: Name: _start
8865; CHECK-NEXT: ...
deps/lld/test/wasm/archive-export.ll+5-17
......@@ -14,37 +14,25 @@ CHECK: Exports:
1414CHECK-NEXT: - Name: memory
1515CHECK-NEXT: Kind: MEMORY
1616CHECK-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
2317CHECK-NEXT: - Name: foo
2418CHECK-NEXT: Kind: FUNCTION
25CHECK-NEXT: Index: 2
19CHECK-NEXT: Index: 1
2620CHECK-NEXT: - Name: bar
2721CHECK-NEXT: Kind: FUNCTION
28CHECK-NEXT: Index: 3
22CHECK-NEXT: Index: 2
2923CHECK-NEXT: - Name: archive2_symbol
3024CHECK-NEXT: Kind: FUNCTION
31CHECK-NEXT: Index: 4
25CHECK-NEXT: Index: 3
3226CHECK-NEXT: - Name: _start
3327CHECK-NEXT: Kind: FUNCTION
34CHECK-NEXT: Index: 1
28CHECK-NEXT: Index: 0
3529CHECK-NEXT: - Type: CODE
3630
3731NOEXPORT: Exports:
3832NOEXPORT-NEXT: - Name: memory
3933NOEXPORT-NEXT: Kind: MEMORY
4034NOEXPORT-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
4735NOEXPORT-NEXT: - Name: _start
4836NOEXPORT-NEXT: Kind: FUNCTION
49NOEXPORT-NEXT: Index: 1
37NOEXPORT-NEXT: Index: 0
5038NOEXPORT-NEXT: - Type: CODE
deps/lld/test/wasm/archive-no-index.ll created+13
......@@ -0,0 +1,13 @@
1; Tests error on archive file without a symbol table
2; RUN: llvm-as -o %t.o %s
3; RUN: llvm-as -o %t.archive.o %S/Inputs/archive1.ll
4; RUN: rm -f %t.a
5; RUN: llvm-ar crS %t.a %t.archive.o
6
7; RUN: not wasm-ld -o out.wasm %t.o %t.a 2>&1 | FileCheck %s
8
9define i32 @_start() {
10 ret i32 0
11}
12
13; CHECK: archive has no index; run ranlib to add one
deps/lld/test/wasm/archive-weak-undefined.ll created+19
......@@ -0,0 +1,19 @@
1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: llc -filetype=obj %S/Inputs/ret32.ll -o %t.a1.o
3; RUN: rm -f %t.a
4; RUN: llvm-ar rcs %t.a %t.a1.o
5; RUN: wasm-ld %t.o %t.a -o %t.wasm
6; RUN: obj2yaml %t.wasm | FileCheck %s
7
8target triple = "wasm32-unknown-unknown"
9
10declare extern_weak i32 @ret32()
11
12define void @_start() {
13entry:
14 %call1 = call i32 @ret32()
15 ret void
16}
17
18; CHECK: Name: 'undefined:ret32'
19; CHECK-NOT: Name: ret32
deps/lld/test/wasm/archive.ll+5-3
......@@ -33,10 +33,10 @@ entry:
3333; TODO(ncw): Update LLD so that the symbol table is written out for
3434; non-relocatable output (with an option to strip it)
3535
36; CHECK: 00000004 T _start
37; CHECK-NEXT: 00000002 T archive2_symbol
36; CHECK: 00000016 T _start
37; CHECK-NEXT: 0000000a T archive2_symbol
3838; CHECK-NEXT: 00000001 T bar
39; CHECK-NEXT: 00000003 T foo
39; CHECK-NEXT: 0000000d T foo
4040; CHECK-NEXT: U missing_func
4141
4242; Verify that symbols from unused objects don't appear in the symbol table
......@@ -47,6 +47,8 @@ entry:
4747
4848; Verfiy errors include library name
4949; RUN: not wasm-ld -u archive2_symbol -u archive3_symbol %t.a %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-DUP %s
50; And that this also works with --whole-archive
51; RUN: not wasm-ld -u archive2_symbol -u archive3_symbol --whole-archive %t.a %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-DUP %s
5052; CHECK-DUP: error: duplicate symbol: bar
5153; CHECK-DUP: >>> defined in {{.*}}.a({{.*}}.a2.o)
5254; CHECK-DUP: >>> defined in {{.*}}.a({{.*}}.a3.o)
deps/lld/test/wasm/call-indirect.ll+17-40
......@@ -57,7 +57,7 @@ define void @call_ptr(i64 (i64)* %arg) {
5757; CHECK-NEXT: ParamTypes:
5858; CHECK-NEXT: - I32
5959; CHECK-NEXT: - Type: FUNCTION
60; CHECK-NEXT: FunctionTypes: [ 3, 0, 3, 1, 3, 4 ]
60; CHECK-NEXT: FunctionTypes: [ 0, 3, 1, 3, 4 ]
6161; CHECK-NEXT: - Type: TABLE
6262; CHECK-NEXT: Tables:
6363; CHECK-NEXT: - ElemType: FUNCREF
......@@ -81,80 +81,59 @@ define void @call_ptr(i64 (i64)* %arg) {
8181; CHECK-NEXT: Mutable: false
8282; CHECK-NEXT: InitExpr:
8383; CHECK-NEXT: Opcode: I32_CONST
84; CHECK-NEXT: Value: 66576
85; CHECK-NEXT: - Index: 2
86; CHECK-NEXT: Type: I32
87; CHECK-NEXT: Mutable: false
88; CHECK-NEXT: InitExpr:
89; CHECK-NEXT: Opcode: I32_CONST
90; CHECK-NEXT: Value: 1036
91; CHECK-NEXT: - Index: 3
92; CHECK-NEXT: Type: I32
93; CHECK-NEXT: Mutable: false
94; CHECK-NEXT: InitExpr:
95; CHECK-NEXT: Opcode: I32_CONST
9684; CHECK-NEXT: Value: 1032
9785; CHECK-NEXT: - Type: EXPORT
9886; CHECK-NEXT: Exports:
9987; CHECK-NEXT: - Name: memory
10088; CHECK-NEXT: Kind: MEMORY
10189; CHECK-NEXT: Index: 0
102; CHECK-NEXT: - Name: __heap_base
103; CHECK-NEXT: Kind: GLOBAL
104; CHECK-NEXT: Index: 1
105; CHECK-NEXT: - Name: __data_end
106; CHECK-NEXT: Kind: GLOBAL
107; CHECK-NEXT: Index: 2
10890; CHECK-NEXT: - Name: bar
10991; CHECK-NEXT: Kind: FUNCTION
110; CHECK-NEXT: Index: 1
92; CHECK-NEXT: Index: 0
11193; CHECK-NEXT: - Name: call_bar_indirect
11294; CHECK-NEXT: Kind: FUNCTION
113; CHECK-NEXT: Index: 2
95; CHECK-NEXT: Index: 1
11496; CHECK-NEXT: - Name: foo
11597; CHECK-NEXT: Kind: FUNCTION
116; CHECK-NEXT: Index: 3
98; CHECK-NEXT: Index: 2
11799; CHECK-NEXT: - Name: _start
118100; CHECK-NEXT: Kind: FUNCTION
119; CHECK-NEXT: Index: 4
101; CHECK-NEXT: Index: 3
120102; CHECK-NEXT: - Name: indirect_func
121103; CHECK-NEXT: Kind: GLOBAL
122; CHECK-NEXT: Index: 3
104; CHECK-NEXT: Index: 1
123105; CHECK-NEXT: - Name: call_ptr
124106; CHECK-NEXT: Kind: FUNCTION
125; CHECK-NEXT: Index: 5
107; CHECK-NEXT: Index: 4
126108; CHECK-NEXT: - Type: ELEM
127109; CHECK-NEXT: Segments:
128110; CHECK-NEXT: - Offset:
129111; CHECK-NEXT: Opcode: I32_CONST
130112; CHECK-NEXT: Value: 1
131; CHECK-NEXT: Functions: [ 1, 3 ]
113; CHECK-NEXT: Functions: [ 0, 2 ]
132114; CHECK-NEXT: - Type: CODE
133115; CHECK-NEXT: Functions:
134116; CHECK-NEXT: - Index: 0
135117; CHECK-NEXT: Locals:
136; CHECK-NEXT: Body: 0B
137; CHECK-NEXT: - Index: 1
138; CHECK-NEXT: Locals:
139118; CHECK-NEXT: Body: 42010B
140; CHECK-NEXT: - Index: 2
119; CHECK-NEXT: - Index: 1
141120; CHECK-NEXT: Locals:
142121; CHECK-NEXT: - Type: I32
143122; CHECK-NEXT: Count: 1
144123; CHECK-NEXT: Body: 4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B
145; CHECK-NEXT: - Index: 3
124; CHECK-NEXT: - Index: 2
146125; CHECK-NEXT: Locals:
147126; CHECK-NEXT: Body: 41020B
148; CHECK-NEXT: - Index: 4
127; CHECK-NEXT: - Index: 3
149128; CHECK-NEXT: Locals:
150129; CHECK-NEXT: Body: 410028028888808000118180808000001A0B
151; CHECK-NEXT: - Index: 5
130; CHECK-NEXT: - Index: 4
152131; CHECK-NEXT: Locals:
153132; CHECK-NEXT: Body: 42012000118280808000001A0B
154133; CHECK-NEXT: - Type: DATA
155134; CHECK-NEXT: Segments:
156135; CHECK-NEXT: - SectionOffset: 7
157; CHECK-NEXT: MemoryIndex: 0
136; CHECK-NEXT: InitFlags: 0
158137; CHECK-NEXT: Offset:
159138; CHECK-NEXT: Opcode: I32_CONST
160139; CHECK-NEXT: Value: 1024
......@@ -163,15 +142,13 @@ define void @call_ptr(i64 (i64)* %arg) {
163142; CHECK-NEXT: Name: name
164143; CHECK-NEXT: FunctionNames:
165144; CHECK-NEXT: - Index: 0
166; CHECK-NEXT: Name: __wasm_call_ctors
167; CHECK-NEXT: - Index: 1
168145; CHECK-NEXT: Name: bar
169; CHECK-NEXT: - Index: 2
146; CHECK-NEXT: - Index: 1
170147; CHECK-NEXT: Name: call_bar_indirect
171; CHECK-NEXT: - Index: 3
148; CHECK-NEXT: - Index: 2
172149; CHECK-NEXT: Name: foo
173; CHECK-NEXT: - Index: 4
150; CHECK-NEXT: - Index: 3
174151; CHECK-NEXT: Name: _start
175; CHECK-NEXT: - Index: 5
152; CHECK-NEXT: - Index: 4
176153; CHECK-NEXT: Name: call_ptr
177154; CHECK-NEXT: ...
deps/lld/test/wasm/comdats.ll+18-31
......@@ -6,11 +6,13 @@
66
77target triple = "wasm32-unknown-unknown"
88
9declare i32 @inlineFn()
9declare void @__wasm_call_ctors()
10declare i32 @comdatFn()
1011
11define void @_start() local_unnamed_addr {
12define void @_start() {
1213entry:
13 %call = call i32 @inlineFn()
14 call void @__wasm_call_ctors()
15 %call = call i32 @comdatFn()
1416 ret void
1517}
1618
......@@ -27,45 +29,27 @@ entry:
2729; CHECK-NEXT: Mutable: false
2830; CHECK-NEXT: InitExpr:
2931; CHECK-NEXT: Opcode: I32_CONST
30; CHECK-NEXT: Value: 66576
31; CHECK-NEXT: - Index: 2
32; CHECK-NEXT: Type: I32
33; CHECK-NEXT: Mutable: false
34; CHECK-NEXT: InitExpr:
35; CHECK-NEXT: Opcode: I32_CONST
36; CHECK-NEXT: Value: 1027
37; CHECK-NEXT: - Index: 3
38; CHECK-NEXT: Type: I32
39; CHECK-NEXT: Mutable: false
40; CHECK-NEXT: InitExpr:
41; CHECK-NEXT: Opcode: I32_CONST
4232; CHECK-NEXT: Value: 1024
4333; CHECK-NEXT: - Type: EXPORT
4434; CHECK-NEXT: Exports:
4535; CHECK-NEXT: - Name: memory
4636; CHECK-NEXT: Kind: MEMORY
4737; CHECK-NEXT: Index: 0
48; CHECK-NEXT: - Name: __heap_base
49; CHECK-NEXT: Kind: GLOBAL
50; CHECK-NEXT: Index: 1
51; CHECK-NEXT: - Name: __data_end
52; CHECK-NEXT: Kind: GLOBAL
53; CHECK-NEXT: Index: 2
5438; CHECK-NEXT: - Name: _start
5539; CHECK-NEXT: Kind: FUNCTION
5640; CHECK-NEXT: Index: 1
57; CHECK-NEXT: - Name: inlineFn
41; CHECK-NEXT: - Name: comdatFn
5842; CHECK-NEXT: Kind: FUNCTION
5943; CHECK-NEXT: Index: 2
6044; CHECK-NEXT: - Name: constantData
6145; CHECK-NEXT: Kind: GLOBAL
62; CHECK-NEXT: Index: 3
63; CHECK-NEXT: - Name: callInline1
64; CHECK-NEXT: Kind: FUNCTION
65; CHECK-NEXT: Index: 3
66; CHECK-NEXT: - Name: callInline2
46; CHECK-NEXT: Index: 1
47; CHECK-NEXT: - Name: callComdatFn1
6748; CHECK-NEXT: Kind: FUNCTION
6849; CHECK-NEXT: Index: 4
50; CHECK-NEXT: - Name: callComdatFn2
51; CHECK-NEXT: Kind: FUNCTION
52; CHECK-NEXT: Index: 5
6953; CHECK-NEXT: - Type: ELEM
7054; CHECK-NEXT: Segments:
7155; CHECK-NEXT: - Offset:
......@@ -76,23 +60,26 @@ entry:
7660; CHECK-NEXT: Functions:
7761; CHECK-NEXT: - Index: 0
7862; CHECK-NEXT: Locals:
79; CHECK-NEXT: Body: 0B
63; CHECK-NEXT: Body: 10030B
8064; CHECK-NEXT: - Index: 1
8165; CHECK-NEXT: Locals:
82; CHECK-NEXT: Body: 1082808080001A0B
66; CHECK-NEXT: Body: 1080808080001082808080001A0B
8367; CHECK-NEXT: - Index: 2
8468; CHECK-NEXT: Locals:
8569; CHECK-NEXT: Body: 4180888080000B
8670; CHECK-NEXT: - Index: 3
8771; CHECK-NEXT: Locals:
88; CHECK-NEXT: Body: 4181808080000B
72; CHECK-NEXT: Body: 0B
8973; CHECK-NEXT: - Index: 4
9074; CHECK-NEXT: Locals:
9175; CHECK-NEXT: Body: 4181808080000B
76; CHECK-NEXT: - Index: 5
77; CHECK-NEXT: Locals:
78; CHECK-NEXT: Body: 4181808080000B
9279; CHECK-NEXT: - Type: DATA
9380; CHECK-NEXT: Segments:
9481; CHECK-NEXT: - SectionOffset: 7
95; CHECK-NEXT: MemoryIndex: 0
82; CHECK-NEXT: InitFlags: 0
9683; CHECK-NEXT: Offset:
9784; CHECK-NEXT: Opcode: I32_CONST
9885; CHECK-NEXT: Value: 1024
deps/lld/test/wasm/corrupted.wasm.test created
Binary files /dev/null and b/deps/lld/test/wasm/corrupted.wasm.test differ
deps/lld/test/wasm/cxx-mangling.ll+8-19
......@@ -26,43 +26,32 @@ define void @_start() {
2626; CHECK-NEXT: - Name: memory
2727; CHECK-NEXT: Kind: MEMORY
2828; CHECK-NEXT: Index: 0
29; CHECK-NEXT: - Name: __heap_base
30; CHECK-NEXT: Kind: GLOBAL
31; CHECK-NEXT: Index: 1
32; CHECK-NEXT: - Name: __data_end
33; CHECK-NEXT: Kind: GLOBAL
34; CHECK-NEXT: Index: 2
3529; CHECK-NEXT: - Name: _Z3fooi
3630; CHECK-NEXT: Kind: FUNCTION
37; CHECK-NEXT: Index: 2
31; CHECK-NEXT: Index: 1
3832; CHECK-NEXT: - Name: _start
3933; CHECK-NEXT: Kind: FUNCTION
40; CHECK-NEXT: Index: 3
34; CHECK-NEXT: Index: 2
4135; CHECK-NEXT: - Type: CODE
4236; CHECK-NEXT: Functions:
4337; CHECK-NEXT: - Index: 0
4438; CHECK-NEXT: Locals:
45; CHECK-NEXT: Body: 0B
46; CHECK-NEXT: - Index: 1
47; CHECK-NEXT: Locals:
4839; CHECK-NEXT: Body: 000B
49; CHECK-NEXT: - Index: 2
40; CHECK-NEXT: - Index: 1
5041; CHECK-NEXT: Locals:
5142; CHECK-NEXT: Body: 0B
52; CHECK-NEXT: - Index: 3
43; CHECK-NEXT: - Index: 2
5344; CHECK-NEXT: Locals:
54; CHECK-NEXT: Body: 410110828080800041011081808080000B
45; CHECK-NEXT: Body: 410110818080800041011080808080000B
5546; CHECK-NEXT: - Type: CUSTOM
5647; CHECK-NEXT: Name: name
5748; CHECK-NEXT: FunctionNames:
5849; CHECK-NEXT: - Index: 0
59; CHECK-NEXT: Name: __wasm_call_ctors
50; DEMANGLE-NEXT: Name: 'undefined:bar(int)'
51; MANGLE-NEXT: Name: 'undefined:_Z3bari'
6052; CHECK-NEXT: - Index: 1
61; DEMANGLE-NEXT: Name: 'undefined function bar(int)'
62; MANGLE-NEXT: Name: undefined function _Z3bari
63; CHECK-NEXT: - Index: 2
6453; DEMANGLE-NEXT: Name: 'foo(int)'
6554; MANGLE-NEXT: Name: _Z3fooi
66; CHECK-NEXT: - Index: 3
55; CHECK-NEXT: - Index: 2
6756; CHECK-NEXT: Name: _start
6857; CHECK-NEXT: ...
deps/lld/test/wasm/data-layout.ll+23-17
......@@ -13,7 +13,7 @@ target triple = "wasm32-unknown-unknown"
1313@local_struct = hidden global %struct.s zeroinitializer, align 4
1414@local_struct_internal_ptr = hidden local_unnamed_addr global i32* getelementptr inbounds (%struct.s, %struct.s* @local_struct, i32 0, i32 1), align 4
1515
16; RUN: wasm-ld -no-gc-sections --allow-undefined --no-entry -o %t.wasm %t.o %t.hello.o
16; RUN: wasm-ld -no-gc-sections --export=__data_end --export=__heap_base --allow-undefined --no-entry -o %t.wasm %t.o %t.hello.o
1717; RUN: obj2yaml %t.wasm | FileCheck %s
1818
1919; CHECK: - Type: MEMORY
......@@ -32,25 +32,31 @@ target triple = "wasm32-unknown-unknown"
3232; CHECK-NEXT: Mutable: false
3333; CHECK-NEXT: InitExpr:
3434; CHECK-NEXT: Opcode: I32_CONST
35; CHECK-NEXT: Value: 1071
36; CHECK-NEXT: - Index: 2
37; CHECK-NEXT: Type: I32
38; CHECK-NEXT: Mutable: false
39; CHECK-NEXT: InitExpr:
40; CHECK-NEXT: Opcode: I32_CONST
3541; CHECK-NEXT: Value: 66608
3642
37; CHECK: - Type: DATA
43; CHECK: - Type: DATA
3844; CHECK-NEXT: Segments:
3945; CHECK-NEXT: - SectionOffset: 7
40; CHECK-NEXT: MemoryIndex: 0
46; CHECK-NEXT: InitFlags: 0
4147; CHECK-NEXT: Offset:
4248; CHECK-NEXT: Opcode: I32_CONST
4349; CHECK-NEXT: Value: 1024
4450; CHECK-NEXT: Content: '0100000000000000000000000000000003000000000000002804000024040000'
4551; CHECK-NEXT: - SectionOffset: 45
46; CHECK-NEXT: MemoryIndex: 0
52; CHECK-NEXT: InitFlags: 0
4753; CHECK-NEXT: Offset:
4854; CHECK-NEXT: Opcode: I32_CONST
4955; CHECK-NEXT: Value: 1056
5056; CHECK-NEXT: Content: '0000000000000000'
5157; CHECK-NEXT: - SectionOffset: 59
52; CHECK-NEXT: MemoryIndex: 0
53; CHECK-NEXT: Offset:
58; CHECK-NEXT: InitFlags: 0
59; CHECK-NEXT: Offset:
5460; CHECK-NEXT: Opcode: I32_CONST
5561; CHECK-NEXT: Value: 1064
5662; CHECK-NEXT: Content: 68656C6C6F0A00
......@@ -70,7 +76,7 @@ target triple = "wasm32-unknown-unknown"
7076
7177; RUN: wasm-ld -no-gc-sections --allow-undefined --no-entry --shared-memory \
7278; RUN: --initial-memory=131072 --max-memory=131072 -o %t_max.wasm %t.o \
73; RUN: %t.hello.o
79; RUN: --active-segments %t.hello.o
7480; RUN: obj2yaml %t_max.wasm | FileCheck %s -check-prefix=CHECK-SHARED
7581
7682; CHECK-SHARED: - Type: MEMORY
......@@ -84,46 +90,46 @@ target triple = "wasm32-unknown-unknown"
8490
8591; RELOC: - Type: DATA
8692; RELOC-NEXT: Relocations:
87; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
93; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
8894; RELOC-NEXT: Index: 3
8995; RELOC-NEXT: Offset: 0x00000018
90; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
96; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
9197; RELOC-NEXT: Index: 4
9298; RELOC-NEXT: Offset: 0x0000002E
9399; RELOC-NEXT: Addend: 4
94100; RELOC-NEXT: Segments:
95101; RELOC-NEXT: - SectionOffset: 6
96; RELOC-NEXT: MemoryIndex: 0
102; RELOC-NEXT: InitFlags: 0
97103; RELOC-NEXT: Offset:
98104; RELOC-NEXT: Opcode: I32_CONST
99105; RELOC-NEXT: Value: 0
100106; RELOC-NEXT: Content: '01000000'
101107; RELOC-NEXT: - SectionOffset: 15
102; RELOC-NEXT: MemoryIndex: 0
108; RELOC-NEXT: InitFlags: 0
103109; RELOC-NEXT: Offset:
104110; RELOC-NEXT: Opcode: I32_CONST
105111; RELOC-NEXT: Value: 16
106112; RELOC-NEXT: Content: '03000000'
107113; RELOC-NEXT: - SectionOffset: 24
108; RELOC-NEXT: MemoryIndex: 0
114; RELOC-NEXT: InitFlags: 0
109115; RELOC-NEXT: Offset:
110116; RELOC-NEXT: Opcode: I32_CONST
111117; RELOC-NEXT: Value: 24
112118; RELOC-NEXT: Content: '28000000'
113119; RELOC-NEXT: - SectionOffset: 33
114; RELOC-NEXT: MemoryIndex: 0
115; RELOC-NEXT: Offset:
120; RELOC-NEXT: InitFlags: 0
121; RELOC-NEXT: Offset:
116122; RELOC-NEXT: Opcode: I32_CONST
117123; RELOC-NEXT: Value: 28
118124; RELOC-NEXT: Content: '0000000000000000'
119125; RELOC-NEXT: - SectionOffset: 46
120; RELOC-NEXT: MemoryIndex: 0
121; RELOC-NEXT: Offset:
126; RELOC-NEXT: InitFlags: 0
127; RELOC-NEXT: Offset:
122128; RELOC-NEXT: Opcode: I32_CONST
123129; RELOC-NEXT: Value: 36
124130; RELOC-NEXT: Content: '20000000'
125131; RELOC-NEXT: - SectionOffset: 55
126; RELOC-NEXT: MemoryIndex: 0
132; RELOC-NEXT: InitFlags: 0
127133; RELOC-NEXT: Offset:
128134; RELOC-NEXT: Opcode: I32_CONST
129135; RELOC-NEXT: Value: 40
deps/lld/test/wasm/data-segment-merging.ll+110-17
......@@ -8,24 +8,117 @@ target triple = "wasm32-unknown-unknown"
88@e = private constant [9 x i8] c"constant\00", align 1
99@f = private constant i8 43, align 4
1010
11; RUN: llc -filetype=obj %s -o %t.data-segment-merging.o
11; RUN: llc -mattr=+bulk-memory -filetype=obj %s -o %t.o
1212
13; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.data-segment-merging.o
13; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.o
1414; RUN: obj2yaml %t.merged.wasm | FileCheck %s --check-prefix=MERGE
15; MERGE: - Type: DATA
16; MERGE: Segments:
17; MERGE: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000
18; MERGE: Content: 636F6E7374616E74000000002B
19; MERGE-NOT: Content:
2015
21; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.data-segment-merging.o
16; MERGE-LABEL: - Type: DATA
17; MERGE-NEXT: Segments:
18; MERGE-NEXT: - SectionOffset: 7
19; MERGE-NEXT: InitFlags: 0
20; MERGE-NEXT: Offset:
21; MERGE: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000
22; MERGE-NEXT: - SectionOffset: 41
23; MERGE-NEXT: InitFlags: 0
24; MERGE-NEXT: Offset:
25; MERGE: Content: 636F6E7374616E74000000002B
26; MERGE-NEXT: - Type: CUSTOM
27; MERGE-NEXT: Name: name
28; MERGE-NEXT: FunctionNames:
29; MERGE-NEXT: - Index: 0
30; MERGE-NEXT: Name: __wasm_call_ctors
31; MERGE-NOT: - Index:
32
33; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.o
2234; RUN: obj2yaml %t.separate.wasm | FileCheck %s --check-prefix=SEPARATE
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:
35
36; SEPARATE-NOT: DATACOUNT
37; SEPARATE-LABEL: - Type: DATA
38; SEPARATE-NEXT: Segments:
39; SEPARATE-NEXT: - SectionOffset: 7
40; SEPARATE-NEXT: InitFlags: 0
41; SEPARATE-NEXT: Offset:
42; SEPARATE: Content: 68656C6C6F00
43; SEPARATE-NEXT: - SectionOffset: 19
44; SEPARATE-NEXT: InitFlags: 0
45; SEPARATE-NEXT: Offset:
46; SEPARATE: Content: 676F6F6462796500
47; SEPARATE-NEXT: - SectionOffset: 33
48; SEPARATE-NEXT: InitFlags: 0
49; SEPARATE-NEXT: Offset:
50; SEPARATE: Content: '776861746576657200'
51; SEPARATE-NEXT: - SectionOffset: 48
52; SEPARATE-NEXT: InitFlags: 0
53; SEPARATE-NEXT: Offset:
54; SEPARATE: Content: 2A000000
55; SEPARATE-NEXT: - SectionOffset: 58
56; SEPARATE-NEXT: InitFlags: 0
57; SEPARATE-NEXT: Offset:
58; SEPARATE: Content: 636F6E7374616E7400
59; SEPARATE-NEXT: - SectionOffset: 73
60; SEPARATE-NEXT: InitFlags: 0
61; SEPARATE-NEXT: Offset:
62; SEPARATE: Content: 2B
63; SEPARATE-NEXT: - Type: CUSTOM
64; SEPARATE-NEXT: Name: name
65; SEPARATE-NEXT: FunctionNames:
66; SEPARATE-NEXT: - Index: 0
67; SEPARATE-NEXT: Name: __wasm_call_ctors
68; SEPARATE-NOT: - Index:
69
70; RUN: wasm-ld -no-gc-sections --no-entry --passive-segments -o %t.merged.passive.wasm %t.o
71; RUN: obj2yaml %t.merged.passive.wasm | FileCheck %s --check-prefix=PASSIVE-MERGE
72
73; PASSIVE-MERGE-LABEL: - Type: DATACOUNT
74; PASSIVE-MERGE-NEXT: Count: 2
75; PASSIVE-MERGE-LABEL: - Type: DATA
76; PASSIVE-MERGE-NEXT: Segments:
77; PASSIVE-MERGE-NEXT: - SectionOffset: 3
78; PASSIVE-MERGE-NEXT: InitFlags: 1
79; PASSIVE-MERGE-NEXT: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000
80; PASSIVE-MERGE-NEXT: - SectionOffset: 33
81; PASSIVE-MERGE-NEXT: InitFlags: 1
82; PASSIVE-MERGE-NEXT: Content: 636F6E7374616E74000000002B
83; PASSIVE-MERGE-NEXT: - Type: CUSTOM
84; PASSIVE-MERGE-NEXT: Name: name
85; PASSIVE-MERGE-NEXT: FunctionNames:
86; PASSIVE-MERGE-NEXT: - Index: 0
87; PASSIVE-MERGE-NEXT: Name: __wasm_call_ctors
88; PASSIVE-MERGE-NEXT: - Index: 1
89; PASSIVE-MERGE-NEXT: Name: __wasm_init_memory
90; PASSIVE-MERGE-NOT: - Index:
91
92; RUN: wasm-ld -no-gc-sections --no-entry --passive-segments -no-merge-data-segments -o %t.separate.passive.wasm %t.o
93; RUN: obj2yaml %t.separate.passive.wasm | FileCheck %s --check-prefix=PASSIVE-SEPARATE
94
95; PASSIVE-SEPARATE-LABEL: - Type: DATACOUNT
96; PASSIVE-SEPARATE-NEXT: Count: 6
97; PASSIVE-SEPARATE-LABEL: - Type: DATA
98; PASSIVE-SEPARATE-NEXT: Segments:
99; PASSIVE-SEPARATE-NEXT: - SectionOffset: 3
100; PASSIVE-SEPARATE-NEXT: InitFlags: 1
101; PASSIVE-SEPARATE-NEXT: Content: 68656C6C6F00
102; PASSIVE-SEPARATE-NEXT: - SectionOffset: 11
103; PASSIVE-SEPARATE-NEXT: InitFlags: 1
104; PASSIVE-SEPARATE-NEXT: Content: 676F6F6462796500
105; PASSIVE-SEPARATE-NEXT: - SectionOffset: 21
106; PASSIVE-SEPARATE-NEXT: InitFlags: 1
107; PASSIVE-SEPARATE-NEXT: Content: '776861746576657200'
108; PASSIVE-SEPARATE-NEXT: - SectionOffset: 32
109; PASSIVE-SEPARATE-NEXT: InitFlags: 1
110; PASSIVE-SEPARATE-NEXT: Content: 2A000000
111; PASSIVE-SEPARATE-NEXT: - SectionOffset: 38
112; PASSIVE-SEPARATE-NEXT: InitFlags: 1
113; PASSIVE-SEPARATE-NEXT: Content: 636F6E7374616E7400
114; PASSIVE-SEPARATE-NEXT: - SectionOffset: 49
115; PASSIVE-SEPARATE-NEXT: InitFlags: 1
116; PASSIVE-SEPARATE-NEXT: Content: 2B
117; PASSIVE-SEPARATE-NEXT: - Type: CUSTOM
118; PASSIVE-SEPARATE-NEXT: Name: name
119; PASSIVE-SEPARATE-NEXT: FunctionNames:
120; PASSIVE-SEPARATE-NEXT: - Index: 0
121; PASSIVE-SEPARATE-NEXT: Name: __wasm_call_ctors
122; PASSIVE-SEPARATE-NEXT: - Index: 1
123; PASSIVE-SEPARATE-NEXT: Name: __wasm_init_memory
124; PASSIVE-SEPARATE-NOT: - Index
deps/lld/test/wasm/data-segments.ll created+119
......@@ -0,0 +1,119 @@
1; RUN: llc -filetype=obj %s -o %t.atomics.o -mattr=+atomics
2; RUN: llc -filetype=obj %s -o %t.bulk-mem.o -mattr=+bulk-memory
3; RUN: llc -filetype=obj %s -o %t.atomics.bulk-mem.o -mattr=+atomics,+bulk-memory
4
5; atomics => error
6; RUN: not wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.o -o %t.atomics.wasm 2>&1 | FileCheck %s --check-prefix ERROR
7
8; atomics, active segments => active segments
9; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 --active-segments %t.atomics.o -o %t.atomics.active.wasm
10; RUN: obj2yaml %t.atomics.active.wasm | FileCheck %s --check-prefixes ACTIVE,ACTIVE-TLS
11
12; atomics, passive segments => error
13; RUN: not wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 --passive-segments %t.atomics.o -o %t.atomics.passive.wasm 2>&1 | FileCheck %s --check-prefix ERROR
14
15; bulk memory => active segments
16; RUN: wasm-ld -no-gc-sections --no-entry %t.bulk-mem.o -o %t.bulk-mem.wasm
17; RUN: obj2yaml %t.bulk-mem.wasm | FileCheck %s --check-prefix ACTIVE
18
19; bulk-memory, active segments => active segments
20; RUN: wasm-ld -no-gc-sections --no-entry --active-segments %t.bulk-mem.o -o %t.bulk-mem.active.wasm
21; RUN: obj2yaml %t.bulk-mem.active.wasm | FileCheck %s --check-prefix ACTIVE
22
23; bulk memory, passive segments => passive segments
24; RUN: wasm-ld -no-gc-sections --no-entry --passive-segments %t.bulk-mem.o -o %t.bulk-mem.passive.wasm
25; RUN: obj2yaml %t.bulk-mem.passive.wasm | FileCheck %s --check-prefix PASSIVE
26
27; atomics, bulk memory => passive segments
28; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.o -o %t.atomics.bulk-mem.wasm
29; RUN: obj2yaml %t.atomics.bulk-mem.wasm | FileCheck %s --check-prefixes PASSIVE,PASSIVE-TLS
30
31; atomics, bulk memory, active segments => active segments
32; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 --active-segments %t.atomics.bulk-mem.o -o %t.atomics.bulk-mem.active.wasm
33; RUN: obj2yaml %t.atomics.bulk-mem.active.wasm | FileCheck %s --check-prefixes ACTIVE,ACTIVE-TLS
34
35; atomics, bulk memory, passive segments => passive segments
36; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 --passive-segments %t.atomics.bulk-mem.o -o %t.atomics.bulk-mem.passive.wasm
37; RUN: obj2yaml %t.atomics.bulk-mem.passive.wasm | FileCheck %s --check-prefixes PASSIVE,PASSIVE-TLS
38
39target triple = "wasm32-unknown-unknown"
40
41@a = hidden global [6 x i8] c"hello\00", align 1
42@b = hidden global [8 x i8] c"goodbye\00", align 1
43@c = hidden global [10000 x i8] zeroinitializer, align 1
44@d = hidden global i32 42, align 4
45
46@e = private constant [9 x i8] c"constant\00", align 1
47@f = private constant i8 43, align 4
48
49; ERROR: 'bulk-memory' feature must be used in order to emit passive segments
50
51; ACTIVE-LABEL: - Type: CODE
52; ACTIVE-NEXT: Functions:
53; ACTIVE-NEXT: - Index: 0
54; ACTIVE-NEXT: Locals: []
55; ACTIVE-NEXT: Body: 0B
56; ACTIVE-TLS-NEXT: - Index: 1
57; ACTIVE-TLS-NEXT: Locals: []
58; ACTIVE-TLS-NEXT: Body: 0B
59; ACTIVE-NEXT: - Type: DATA
60; ACTIVE-NEXT: Segments:
61; ACTIVE-NEXT: - SectionOffset: 7
62; ACTIVE-NEXT: InitFlags: 0
63; ACTIVE-NEXT: Offset:
64; ACTIVE-NEXT: Opcode: I32_CONST
65; ACTIVE-NEXT: Value: 1024
66; ACTIVE-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000
67; ACTIVE-NEXT: - SectionOffset: 34
68; ACTIVE-NEXT: InitFlags: 0
69; ACTIVE-NEXT: Offset:
70; ACTIVE-NEXT: Opcode: I32_CONST
71; ACTIVE-NEXT: Value: 1044
72; ACTIVE-NEXT: Content: '0000000000
73; ACTIVE-SAME: 0000000000'
74; ACTIVE-NEXT: - SectionOffset: 10041
75; ACTIVE-NEXT: InitFlags: 0
76; ACTIVE-NEXT: Offset:
77; ACTIVE-NEXT: Opcode: I32_CONST
78; ACTIVE-NEXT: Value: 11044
79; ACTIVE-NEXT: Content: 636F6E7374616E74000000002B
80; ACTIVE-NEXT: - Type: CUSTOM
81; ACTIVE-NEXT: Name: name
82; ACTIVE-NEXT: FunctionNames:
83; ACTIVE-NEXT: - Index: 0
84; ACTIVE-NEXT: Name: __wasm_call_ctors
85; ACTIVE-TLS-NEXT: - Index: 1
86; ACTIVE-TLS-NEXT: Name: __wasm_init_tls
87
88; PASSIVE-LABEL: - Type: CODE
89; PASSIVE-NEXT: Functions:
90; PASSIVE-NEXT: - Index: 0
91; PASSIVE-NEXT: Locals: []
92; PASSIVE-NEXT: Body: 10010B
93; PASSIVE-NEXT: - Index: 1
94; PASSIVE-NEXT: Locals: []
95; PASSIVE-NEXT: Body: 41800841004114FC080000FC090041940841004190CE00FC080100FC090141A4D6004100410DFC080200FC09020B
96; PASSIVE-TLS-NEXT: - Index: 2
97; PASSIVE-TLS-NEXT: Locals: []
98; PASSIVE-TLS-NEXT: Body: 0B
99; PASSIVE-NEXT: - Type: DATA
100; PASSIVE-NEXT: Segments:
101; PASSIVE-NEXT: - SectionOffset: 3
102; PASSIVE-NEXT: InitFlags: 1
103; PASSIVE-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000
104; PASSIVE-NEXT: - SectionOffset: 26
105; PASSIVE-NEXT: InitFlags: 1
106; PASSIVE-NEXT: Content: '0000000000
107; PASSIVE-SAME: 0000000000'
108; PASSIVE-NEXT: - SectionOffset: 10028
109; PASSIVE-NEXT: InitFlags: 1
110; PASSIVE-NEXT: Content: 636F6E7374616E74000000002B
111; PASSIVE-NEXT: - Type: CUSTOM
112; PASSIVE-NEXT: Name: name
113; PASSIVE-NEXT: FunctionNames:
114; PASSIVE-NEXT: - Index: 0
115; PASSIVE-NEXT: Name: __wasm_call_ctors
116; PASSIVE-NEXT: - Index: 1
117; PASSIVE-NEXT: Name: __wasm_init_memory
118; PASSIVE-TLS-NEXT: - Index: 2
119; PASSIVE-TLS-NEXT: Name: __wasm_init_tls
deps/lld/test/wasm/emit-relocs-fpic.s created+20
......@@ -0,0 +1,20 @@
1# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -o %t.o < %s
2# RUN: llc --relocation-model=pic -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
3# RUN: wasm-ld -pie --export-all --no-gc-sections --no-entry --emit-relocs -o %t.wasm %t.o %t.ret32.o
4# RUN: obj2yaml %t.wasm | FileCheck %s
5
6load_hidden_data:
7 .functype load_hidden_data () -> (i32)
8 i32.const .L.hidden_data@MBREL
9 end_function
10
11.section .rodata.hidden_data,"",@
12.L.hidden_data:
13 .int8 100
14 .size .L.hidden_data, 1
15
16# We just want to make sure that processing this relocation doesn't
17# cause corrupt output. We get most of the way there, by just checking
18# that obj2yaml doesn't fail. Here we just make sure that the relocation
19# survived the trip.
20# CHECK: R_WASM_MEMORY_ADDR_REL_SLEB
deps/lld/test/wasm/emit-relocs.ll created+39
......@@ -0,0 +1,39 @@
1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
3; RUN: wasm-ld --emit-relocs -o %t.wasm %t.o %t.ret32.o
4; RUN: obj2yaml %t.wasm | FileCheck %s
5
6target triple = "wasm32-unknown-unknown"
7
8declare i32 @ret32(float)
9
10define void @unused_function() {
11 ret void
12}
13
14define hidden void @_start() local_unnamed_addr #0 {
15entry:
16 call i32 @ret32(float 0.0)
17 ret void
18}
19
20; CHECK: - Type: CODE
21; CHECK-NEXT: Relocations:
22; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
23; CHECK-NEXT: Index: 1
24; CHECK-NEXT: Offset: 0x00000009
25
26; CHECK: - Type: CUSTOM
27; CHECK-NEXT: Name: linking
28; CHECK-NEXT: Version: 2
29; CHECK-NEXT: SymbolTable:
30; CHECK-NEXT: - Index: 0
31; CHECK-NEXT: Kind: FUNCTION
32; CHECK-NEXT: Name: _start
33; CHECK-NEXT: Flags: [ ]
34; CHECK-NEXT: Function: 0
35; CHECK-NEXT: - Index: 1
36; CHECK-NEXT: Kind: FUNCTION
37; CHECK-NEXT: Name: ret32
38; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
39; CHECK-NEXT: Function: 1
deps/lld/test/wasm/entry.ll+1-13
......@@ -17,15 +17,9 @@ entry:
1717; CHECK-NEXT: - Name: memory
1818; CHECK-NEXT: Kind: MEMORY
1919; CHECK-NEXT: Index: 0
20; CHECK-NEXT: - Name: __heap_base
21; CHECK-NEXT: Kind: GLOBAL
22; CHECK-NEXT: Index: 1
23; CHECK-NEXT: - Name: __data_end
24; CHECK-NEXT: Kind: GLOBAL
25; CHECK-NEXT: Index: 2
2620; CHECK-NEXT: - Name: entry
2721; CHECK-NEXT: Kind: FUNCTION
28; CHECK-NEXT: Index: 1
22; CHECK-NEXT: Index: 0
2923; CHECK-NEXT: - Type:
3024
3125; The __wasm_call_ctors is somewhat special since its created by the linker.
......@@ -41,10 +35,4 @@ entry:
4135; CHECK-CTOR-NEXT: - Name: __wasm_call_ctors
4236; CHECK-CTOR-NEXT: Kind: FUNCTION
4337; CHECK-CTOR-NEXT: Index: 0
44; CHECK-CTOR-NEXT: - Name: __heap_base
45; CHECK-CTOR-NEXT: Kind: GLOBAL
46; CHECK-CTOR-NEXT: Index: 1
47; CHECK-CTOR-NEXT: - Name: __data_end
48; CHECK-CTOR-NEXT: Kind: GLOBAL
49; CHECK-CTOR-NEXT: Index: 2
5038; CHECK-CTOR-NEXT: - Type:
deps/lld/test/wasm/export.ll+21-6
......@@ -3,13 +3,29 @@
33; RUN: wasm-ld --export=hidden_function -o %t.wasm %t.o
44; RUN: obj2yaml %t.wasm | FileCheck %s
55
6@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @used_function to i8*)], section "llvm.metadata"
7
68target triple = "wasm32-unknown-unknown"
79
10; Not exported by default, but forced via commandline
811define hidden i32 @hidden_function() local_unnamed_addr {
912entry:
1013 ret i32 0
1114}
1215
16; Not exported by default
17define i32 @default_function() local_unnamed_addr {
18entry:
19 ret i32 0
20}
21
22; Exported because its part of llvm.used
23define i32 @used_function() local_unnamed_addr {
24entry:
25 ret i32 0
26}
27
28; Exported by default
1329define void @_start() local_unnamed_addr {
1430entry:
1531 ret void
......@@ -17,19 +33,18 @@ entry:
1733
1834; CHECK-ERROR: error: symbol exported via --export not found: missing
1935
36; CHECK-NOT: - Name: default_function
37
2038; CHECK: - Type: EXPORT
2139; CHECK-NEXT: Exports:
2240; CHECK-NEXT: - Name: memory
2341; CHECK-NEXT: Kind: MEMORY
2442; CHECK-NEXT: Index: 0
25; CHECK-NEXT: - Name: __heap_base
26; CHECK-NEXT: Kind: GLOBAL
27; CHECK-NEXT: Index: 1
28; CHECK-NEXT: - Name: __data_end
29; CHECK-NEXT: Kind: GLOBAL
30; CHECK-NEXT: Index: 2
3143; CHECK-NEXT: - Name: hidden_function
3244; CHECK-NEXT: Kind: FUNCTION
45; CHECK-NEXT: Index: 0
46; CHECK-NEXT: - Name: used_function
47; CHECK-NEXT: Kind: FUNCTION
3348; CHECK-NEXT: Index: 1
3449; CHECK-NEXT: - Name: _start
3550; CHECK-NEXT: Kind: FUNCTION
deps/lld/test/wasm/fatal-warnings.ll+2-2
......@@ -1,7 +1,7 @@
11; RUN: llc -filetype=obj %s -o %t.main.o
22; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
3; RUN: lld -flavor wasm -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-WARN
4; RUN: not lld -flavor wasm --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-FATAL
3; RUN: wasm-ld -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-WARN
4; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-FATAL
55
66; CHECK-WARN: warning: function signature mismatch: ret32
77; CHECK-FATAL: error: function signature mismatch: ret32
deps/lld/test/wasm/function-imports-first.ll+3-8
......@@ -24,25 +24,20 @@ declare i32 @ret32(float) local_unnamed_addr #1
2424; CHECK-NEXT: ParamTypes:
2525; CHECK-NEXT: - F32
2626; CHECK: - Type: FUNCTION
27; CHECK-NEXT: FunctionTypes: [ 0, 0, 1 ]
27; CHECK-NEXT: FunctionTypes: [ 0, 1 ]
2828; CHECK: - Type: CODE
2929; CHECK-NEXT: Functions:
3030; CHECK-NEXT: - Index: 0
3131; CHECK-NEXT: Locals:
32; CHECK-NEXT: Body: 0B
32; CHECK-NEXT: Body: 43000000001081808080001A0B
3333; CHECK-NEXT: - Index: 1
3434; CHECK-NEXT: Locals:
35; CHECK-NEXT: Body: 43000000001082808080001A0B
36; CHECK-NEXT: - Index: 2
37; CHECK-NEXT: Locals:
3835; CHECK-NEXT: Body: 41000B
3936; CHECK-NEXT: - Type: CUSTOM
4037; CHECK-NEXT: Name: name
4138; CHECK-NEXT: FunctionNames:
4239; CHECK-NEXT: - Index: 0
43; CHECK-NEXT: Name: __wasm_call_ctors
44; CHECK-NEXT: - Index: 1
4540; CHECK-NEXT: Name: _start
46; CHECK-NEXT: - Index: 2
41; CHECK-NEXT: - Index: 1
4742; CHECK-NEXT: Name: ret32
4843; CHECK-NEXT: ...
deps/lld/test/wasm/function-imports.ll+5-8
......@@ -18,25 +18,22 @@ declare i32 @ret32(float) local_unnamed_addr #1
1818; CHECK: - Type: TYPE
1919; CHECK-NEXT: Signatures:
2020; CHECK-NEXT: - Index: 0
21; CHECK-NEXT: ReturnType: NORESULT
22; CHECK-NEXT: ParamTypes:
23; CHECK-NEXT: - Index: 1
2421; CHECK-NEXT: ReturnType: I32
2522; CHECK-NEXT: ParamTypes:
2623; CHECK-NEXT: - F32
24; CHECK-NEXT: - Index: 1
25; CHECK-NEXT: ReturnType: NORESULT
26; CHECK-NEXT: ParamTypes:
2727; CHECK-NEXT: - Type: FUNCTION
28; CHECK-NEXT: FunctionTypes: [ 0, 1, 0 ]
28; CHECK-NEXT: FunctionTypes: [ 0, 1 ]
2929; CHECK: - Type: CODE
3030; CHECK-NEXT: Functions:
3131; CHECK: - Index: 0
3232; CHECK: - Index: 1
33; CHECK: - Index: 2
3433; CHECK: Name: name
3534; CHECK-NEXT: FunctionNames:
3635; CHECK-NEXT: - Index: 0
37; CHECK-NEXT: Name: __wasm_call_ctors
38; CHECK-NEXT: - Index: 1
3936; CHECK-NEXT: Name: ret32
40; CHECK-NEXT: - Index: 2
37; CHECK-NEXT: - Index: 1
4138; CHECK-NEXT: Name: _start
4239; CHECK-NEXT: ...
deps/lld/test/wasm/gc-imports.ll+1-3
......@@ -43,10 +43,8 @@ entry:
4343; CHECK-NEXT: - Index: 0
4444; CHECK-NEXT: Name: used_undef_function
4545; CHECK-NEXT: - Index: 1
46; CHECK-NEXT: Name: __wasm_call_ctors
47; CHECK-NEXT: - Index: 2
4846; CHECK-NEXT: Name: _start
49; CHECK-NEXT: - Index: 3
47; CHECK-NEXT: - Index: 2
5048; CHECK-NEXT: Name: use_undef_global
5149; CHECK-NEXT: ...
5250
deps/lld/test/wasm/gc-sections.ll+8-10
......@@ -38,10 +38,10 @@ entry:
3838; CHECK: - Type: TYPE
3939; CHECK-NEXT: Signatures:
4040; CHECK-NEXT: - Index: 0
41; CHECK-NEXT: ReturnType: NORESULT
41; CHECK-NEXT: ReturnType: I32
4242; CHECK-NEXT: ParamTypes:
4343; CHECK-NEXT: - Index: 1
44; CHECK-NEXT: ReturnType: I32
44; CHECK-NEXT: ReturnType: NORESULT
4545; CHECK-NEXT: ParamTypes:
4646; CHECK-NEXT: - Index: 2
4747; CHECK-NEXT: ReturnType: I64
......@@ -66,8 +66,8 @@ entry:
6666; CHECK: - Type: DATA
6767; CHECK-NEXT: Segments:
6868; CHECK-NEXT: - SectionOffset: 7
69; CHECK-NEXT: MemoryIndex: 0
70; CHECK-NEXT: Offset:
69; CHECK-NEXT: InitFlags: 0
70; CHECK-NEXT: Offset:
7171; CHECK-NEXT: Opcode: I32_CONST
7272; CHECK-NEXT: Value: 1024
7373; CHECK-NEXT: Content: '02000000'
......@@ -75,12 +75,10 @@ entry:
7575; CHECK-NEXT: Name: name
7676; CHECK-NEXT: FunctionNames:
7777; CHECK-NEXT: - Index: 0
78; CHECK-NEXT: Name: __wasm_call_ctors
79; CHECK-NEXT: - Index: 1
8078; CHECK-NEXT: Name: used_function
81; CHECK-NEXT: - Index: 2
79; CHECK-NEXT: - Index: 1
8280; CHECK-NEXT: Name: _start
83; CHECK-NEXT: - Index: 3
81; CHECK-NEXT: - Index: 2
8482; CHECK-NEXT: Name: use_global
8583; CHECK-NEXT: ...
8684
......@@ -129,8 +127,8 @@ entry:
129127; NO-GC: - Type: DATA
130128; NO-GC-NEXT: Segments:
131129; NO-GC-NEXT: - SectionOffset: 7
132; NO-GC-NEXT: MemoryIndex: 0
133; NO-GC-NEXT: Offset:
130; NO-GC-NEXT: InitFlags: 0
131; NO-GC-NEXT: Offset:
134132; NO-GC-NEXT: Opcode: I32_CONST
135133; NO-GC-NEXT: Value: 1024
136134; NO-GC-NEXT: Content: '010000000000000002000000'
deps/lld/test/wasm/global-base.test created+71
......@@ -0,0 +1,71 @@
1RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o
2
3RUN: wasm-ld --export=__global_base --export=__data_end --allow-undefined -o %t.wasm %t.o
4RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-1024
5CHECK-1024: - Type: GLOBAL
6CHECK-1024-NEXT: Globals:
7CHECK-1024-NEXT: - Index: 0
8CHECK-1024-NEXT: Type: I32
9CHECK-1024-NEXT: Mutable: true
10CHECK-1024-NEXT: InitExpr:
11CHECK-1024-NEXT: Opcode: I32_CONST
12CHECK-1024-NEXT: Value: 66560
13CHECK-1024-NEXT: - Index: 1
14CHECK-1024-NEXT: Type: I32
15CHECK-1024-NEXT: Mutable: false
16CHECK-1024-NEXT: InitExpr:
17CHECK-1024-NEXT: Opcode: I32_CONST
18CHECK-1024-NEXT: Value: 1024
19CHECK-1024-NEXT: - Index: 2
20CHECK-1024-NEXT: Type: I32
21CHECK-1024-NEXT: Mutable: false
22CHECK-1024-NEXT: InitExpr:
23CHECK-1024-NEXT: Opcode: I32_CONST
24CHECK-1024-NEXT: Value: 1024
25
26CHECK-1024: - Type: EXPORT
27CHECK-1024-NEXT: Exports:
28CHECK-1024-NEXT: - Name: memory
29CHECK-1024-NEXT: Kind: MEMORY
30CHECK-1024-NEXT: Index: 0
31CHECK-1024-NEXT: - Name: __data_end
32CHECK-1024-NEXT: Kind: GLOBAL
33CHECK-1024-NEXT: Index: 1
34CHECK-1024-NEXT: - Name: __global_base
35CHECK-1024-NEXT: Kind: GLOBAL
36CHECK-1024-NEXT: Index: 2
37
38RUN: wasm-ld --export=__global_base --export=__data_end --allow-undefined --global-base=16777216 -o %t.wasm %t.o
39RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-16777216
40CHECK-16777216: - Type: GLOBAL
41CHECK-16777216-NEXT: Globals:
42CHECK-16777216-NEXT: - Index: 0
43CHECK-16777216-NEXT: Type: I32
44CHECK-16777216-NEXT: Mutable: true
45CHECK-16777216-NEXT: InitExpr:
46CHECK-16777216-NEXT: Opcode: I32_CONST
47CHECK-16777216-NEXT: Value: 16842752
48CHECK-16777216-NEXT: - Index: 1
49CHECK-16777216-NEXT: Type: I32
50CHECK-16777216-NEXT: Mutable: false
51CHECK-16777216-NEXT: InitExpr:
52CHECK-16777216-NEXT: Opcode: I32_CONST
53CHECK-16777216-NEXT: Value: 16777216
54CHECK-16777216-NEXT: - Index: 2
55CHECK-16777216-NEXT: Type: I32
56CHECK-16777216-NEXT: Mutable: false
57CHECK-16777216-NEXT: InitExpr:
58CHECK-16777216-NEXT: Opcode: I32_CONST
59CHECK-16777216-NEXT: Value: 16777216
60
61CHECK-16777216: - Type: EXPORT
62CHECK-16777216-NEXT: Exports:
63CHECK-16777216-NEXT: - Name: memory
64CHECK-16777216-NEXT: Kind: MEMORY
65CHECK-16777216-NEXT: Index: 0
66CHECK-16777216-NEXT: - Name: __data_end
67CHECK-16777216-NEXT: Kind: GLOBAL
68CHECK-16777216-NEXT: Index: 1
69CHECK-16777216-NEXT: - Name: __global_base
70CHECK-16777216-NEXT: Kind: GLOBAL
71CHECK-16777216-NEXT: Index: 2
deps/lld/test/wasm/import-memory.test+2-2
......@@ -32,8 +32,8 @@
3232# CHECK-MAX-NEXT: Maximum: 0x00000005
3333# CHECK-MAX-NEXT: - Type:
3434
35# RUN: wasm-ld --import-memory --shared-memory --initial-memory=262144 \
36# RUN: --max-memory=327680 -o %t.max.wasm %t.start.o
35# RUN: wasm-ld --import-memory --shared-memory --active-segments \
36# RUN: --initial-memory=262144 --max-memory=327680 -o %t.max.wasm %t.start.o
3737# RUN: obj2yaml %t.max.wasm | FileCheck -check-prefix=CHECK-SHARED %s
3838
3939# Verify the --shared-memory flag works with imports
deps/lld/test/wasm/init-fini-gc.ll created+48
......@@ -0,0 +1,48 @@
1; RUN: llc -filetype=obj -o %t.o %s
2; RUN: wasm-ld %t.o -o %t.wasm
3; RUN: obj2yaml %t.wasm | FileCheck %s
4
5; RUN: wasm-ld %t.o -o %t.wasm
6; RUN: obj2yaml %t.wasm | FileCheck %s
7
8; RUN: wasm-ld --export=__wasm_call_ctors %t.o -o %t.export.wasm
9; RUN: obj2yaml %t.export.wasm | FileCheck %s -check-prefix=EXPORT
10
11; Test that the __wasm_call_ctor function if not referenced
12
13target triple = "wasm32-unknown-unknown"
14
15define hidden void @_start() {
16entry:
17 ret void
18}
19
20define hidden void @func1() {
21entry:
22 ret void
23}
24
25define hidden void @func2() {
26entry:
27 ret void
28}
29
30define i32 @__cxa_atexit(i32 %func, i32 %arg, i32 %dso_handle) {
31 ret i32 0
32}
33
34@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [
35 { i32, void ()*, i8* } { i32 1, void ()* @func1, i8* null }
36]
37
38@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [
39 { i32, void ()*, i8* } { i32 1, void ()* @func2, i8* null }
40]
41
42; CHECK-NOT: __cxa_atexit
43; CHECK-NOT: __wasm_call_ctors
44
45; EXPORT: __wasm_call_ctors
46; EXPORT: func1
47; EXPORT: func2
48; EXPORT: __cxa_atexit
deps/lld/test/wasm/init-fini.ll+20-198
......@@ -25,6 +25,7 @@ entry:
2525
2626declare hidden void @externCtor()
2727declare hidden void @externDtor()
28declare hidden void @__wasm_call_ctors()
2829
2930define i32 @__cxa_atexit(i32 %func, i32 %arg, i32 %dso_handle) {
3031 ret i32 0
......@@ -32,6 +33,7 @@ define i32 @__cxa_atexit(i32 %func, i32 %arg, i32 %dso_handle) {
3233
3334define hidden void @_start() {
3435entry:
36 call void @__wasm_call_ctors();
3537 ret void
3638}
3739
......@@ -75,7 +77,7 @@ entry:
7577; CHECK-NEXT: Body: 10031004100A100F1012100F10141003100C100F10161001100E0B
7678; CHECK: - Index: 22
7779; CHECK-NEXT: Locals:
78; CHECK-NEXT: Body: 024041868080800041004180888080001087808080000D000F0B00000B
80; CHECK-NEXT: Body: 02404186808080004100418088808000108780808000450D0000000B0B
7981; CHECK-NEXT: - Type: CUSTOM
8082; CHECK-NEXT: Name: name
8183; CHECK-NEXT: FunctionNames:
......@@ -127,202 +129,22 @@ entry:
127129; CHECK-NEXT: Name: .Lregister_call_dtors.2002
128130; CHECK-NEXT: ...
129131
130
131132; RUN: wasm-ld -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm
132; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s
133; RUN: llvm-readobj --symbols --sections %t.reloc.wasm | FileCheck -check-prefix=RELOC %s
133134
134; RELOC: SymbolTable:
135; RELOC-NEXT: - Index: 0
136; RELOC-NEXT: Kind: FUNCTION
137; RELOC-NEXT: Name: func1
138; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
139; RELOC-NEXT: Function: 2
140; RELOC-NEXT: - Index: 1
141; RELOC-NEXT: Kind: FUNCTION
142; RELOC-NEXT: Name: func2
143; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
144; RELOC-NEXT: Function: 3
145; RELOC-NEXT: - Index: 2
146; RELOC-NEXT: Kind: FUNCTION
147; RELOC-NEXT: Name: func3
148; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
149; RELOC-NEXT: Function: 4
150; RELOC-NEXT: - Index: 3
151; RELOC-NEXT: Kind: FUNCTION
152; RELOC-NEXT: Name: func4
153; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
154; RELOC-NEXT: Function: 5
155; RELOC-NEXT: - Index: 4
156; RELOC-NEXT: Kind: FUNCTION
157; RELOC-NEXT: Name: __cxa_atexit
158; RELOC-NEXT: Flags: [ ]
159; RELOC-NEXT: Function: 6
160; RELOC-NEXT: - Index: 5
161; RELOC-NEXT: Kind: FUNCTION
162; RELOC-NEXT: Name: _start
163; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
164; RELOC-NEXT: Function: 7
165; RELOC-NEXT: - Index: 6
166; RELOC-NEXT: Kind: DATA
167; RELOC-NEXT: Name: __dso_handle
168; RELOC-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ]
169; RELOC-NEXT: - Index: 7
170; RELOC-NEXT: Kind: FUNCTION
171; RELOC-NEXT: Name: externDtor
172; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ]
173; RELOC-NEXT: Function: 0
174; RELOC-NEXT: - Index: 8
175; RELOC-NEXT: Kind: FUNCTION
176; RELOC-NEXT: Name: externCtor
177; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ]
178; RELOC-NEXT: Function: 1
179; RELOC-NEXT: - Index: 9
180; RELOC-NEXT: Kind: FUNCTION
181; RELOC-NEXT: Name: myctor
182; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
183; RELOC-NEXT: Function: 14
184; RELOC-NEXT: - Index: 10
185; RELOC-NEXT: Kind: FUNCTION
186; RELOC-NEXT: Name: mydtor
187; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ]
188; RELOC-NEXT: Function: 15
189; RELOC-NEXT: - Index: 11
190; RELOC-NEXT: Kind: GLOBAL
191; RELOC-NEXT: Name: __stack_pointer
192; RELOC-NEXT: Flags: [ UNDEFINED ]
193; RELOC-NEXT: Global: 0
194; RELOC-NEXT: - Index: 12
195; RELOC-NEXT: Kind: FUNCTION
196; RELOC-NEXT: Name: .Lcall_dtors.101
197; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
198; RELOC-NEXT: Function: 8
199; RELOC-NEXT: - Index: 13
200; RELOC-NEXT: Kind: FUNCTION
201; RELOC-NEXT: Name: .Lregister_call_dtors.101
202; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
203; RELOC-NEXT: Function: 9
204; RELOC-NEXT: - Index: 14
205; RELOC-NEXT: Kind: FUNCTION
206; RELOC-NEXT: Name: .Lcall_dtors.1001
207; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
208; RELOC-NEXT: Function: 10
209; RELOC-NEXT: - Index: 15
210; RELOC-NEXT: Kind: FUNCTION
211; RELOC-NEXT: Name: .Lregister_call_dtors.1001
212; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
213; RELOC-NEXT: Function: 11
214; RELOC-NEXT: - Index: 16
215; RELOC-NEXT: Kind: FUNCTION
216; RELOC-NEXT: Name: .Lcall_dtors.4000
217; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
218; RELOC-NEXT: Function: 12
219; RELOC-NEXT: - Index: 17
220; RELOC-NEXT: Kind: FUNCTION
221; RELOC-NEXT: Name: .Lregister_call_dtors.4000
222; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
223; RELOC-NEXT: Function: 13
224; RELOC-NEXT: - Index: 18
225; RELOC-NEXT: Kind: FUNCTION
226; RELOC-NEXT: Name: .Lcall_dtors.101
227; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
228; RELOC-NEXT: Function: 16
229; RELOC-NEXT: - Index: 19
230; RELOC-NEXT: Kind: FUNCTION
231; RELOC-NEXT: Name: .Lregister_call_dtors.101
232; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
233; RELOC-NEXT: Function: 17
234; RELOC-NEXT: - Index: 20
235; RELOC-NEXT: Kind: FUNCTION
236; RELOC-NEXT: Name: .Lcall_dtors.202
237; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
238; RELOC-NEXT: Function: 18
239; RELOC-NEXT: - Index: 21
240; RELOC-NEXT: Kind: FUNCTION
241; RELOC-NEXT: Name: .Lregister_call_dtors.202
242; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
243; RELOC-NEXT: Function: 19
244; RELOC-NEXT: - Index: 22
245; RELOC-NEXT: Kind: FUNCTION
246; RELOC-NEXT: Name: .Lcall_dtors.2002
247; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
248; RELOC-NEXT: Function: 20
249; RELOC-NEXT: - Index: 23
250; RELOC-NEXT: Kind: FUNCTION
251; RELOC-NEXT: Name: .Lregister_call_dtors.2002
252; RELOC-NEXT: Flags: [ BINDING_LOCAL ]
253; RELOC-NEXT: Function: 21
254; RELOC-NEXT: InitFunctions:
255; RELOC-NEXT: - Priority: 101
256; RELOC-NEXT: Symbol: 0
257; RELOC-NEXT: - Priority: 101
258; RELOC-NEXT: Symbol: 1
259; RELOC-NEXT: - Priority: 101
260; RELOC-NEXT: Symbol: 13
261; RELOC-NEXT: - Priority: 101
262; RELOC-NEXT: Symbol: 9
263; RELOC-NEXT: - Priority: 101
264; RELOC-NEXT: Symbol: 19
265; RELOC-NEXT: - Priority: 202
266; RELOC-NEXT: Symbol: 9
267; RELOC-NEXT: - Priority: 202
268; RELOC-NEXT: Symbol: 21
269; RELOC-NEXT: - Priority: 1001
270; RELOC-NEXT: Symbol: 0
271; RELOC-NEXT: - Priority: 1001
272; RELOC-NEXT: Symbol: 15
273; RELOC-NEXT: - Priority: 2002
274; RELOC-NEXT: Symbol: 9
275; RELOC-NEXT: - Priority: 2002
276; RELOC-NEXT: Symbol: 23
277; RELOC-NEXT: - Priority: 4000
278; RELOC-NEXT: Symbol: 8
279; RELOC-NEXT: - Priority: 4000
280; RELOC-NEXT: Symbol: 17
281; RELOC-NEXT: - Type: CUSTOM
282; RELOC-NEXT: Name: name
283; RELOC-NEXT: FunctionNames:
284; RELOC-NEXT: - Index: 0
285; RELOC-NEXT: Name: externDtor
286; RELOC-NEXT: - Index: 1
287; RELOC-NEXT: Name: externCtor
288; RELOC-NEXT: - Index: 2
289; RELOC-NEXT: Name: func1
290; RELOC-NEXT: - Index: 3
291; RELOC-NEXT: Name: func2
292; RELOC-NEXT: - Index: 4
293; RELOC-NEXT: Name: func3
294; RELOC-NEXT: - Index: 5
295; RELOC-NEXT: Name: func4
296; RELOC-NEXT: - Index: 6
297; RELOC-NEXT: Name: __cxa_atexit
298; RELOC-NEXT: - Index: 7
299; RELOC-NEXT: Name: _start
300; RELOC-NEXT: - Index: 8
301; RELOC-NEXT: Name: .Lcall_dtors.101
302; RELOC-NEXT: - Index: 9
303; RELOC-NEXT: Name: .Lregister_call_dtors.101
304; RELOC-NEXT: - Index: 10
305; RELOC-NEXT: Name: .Lcall_dtors.1001
306; RELOC-NEXT: - Index: 11
307; RELOC-NEXT: Name: .Lregister_call_dtors.1001
308; RELOC-NEXT: - Index: 12
309; RELOC-NEXT: Name: .Lcall_dtors.4000
310; RELOC-NEXT: - Index: 13
311; RELOC-NEXT: Name: .Lregister_call_dtors.4000
312; RELOC-NEXT: - Index: 14
313; RELOC-NEXT: Name: myctor
314; RELOC-NEXT: - Index: 15
315; RELOC-NEXT: Name: mydtor
316; RELOC-NEXT: - Index: 16
317; RELOC-NEXT: Name: .Lcall_dtors.101
318; RELOC-NEXT: - Index: 17
319; RELOC-NEXT: Name: .Lregister_call_dtors.101
320; RELOC-NEXT: - Index: 18
321; RELOC-NEXT: Name: .Lcall_dtors.202
322; RELOC-NEXT: - Index: 19
323; RELOC-NEXT: Name: .Lregister_call_dtors.202
324; RELOC-NEXT: - Index: 20
325; RELOC-NEXT: Name: .Lcall_dtors.2002
326; RELOC-NEXT: - Index: 21
327; RELOC-NEXT: Name: .Lregister_call_dtors.2002
328; RELOC-NEXT: ...
135; RELOC: Name: linking
136; RELOC-NEXT: InitFunctions [
137; RELOC-NEXT: 0 (priority=101)
138; RELOC-NEXT: 1 (priority=101)
139; RELOC-NEXT: 14 (priority=101)
140; RELOC-NEXT: 10 (priority=101)
141; RELOC-NEXT: 20 (priority=101)
142; RELOC-NEXT: 10 (priority=202)
143; RELOC-NEXT: 22 (priority=202)
144; RELOC-NEXT: 0 (priority=1001)
145; RELOC-NEXT: 16 (priority=1001)
146; RELOC-NEXT: 10 (priority=2002)
147; RELOC-NEXT: 24 (priority=2002)
148; RELOC-NEXT: 9 (priority=4000)
149; RELOC-NEXT: 18 (priority=4000)
150; RELOC-NEXT: ]
deps/lld/test/wasm/large-memory.test created+5
......@@ -0,0 +1,5 @@
1RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o
2
3; Verify we can parse large integers such as when we ask for 2G of total
4; memory.
5RUN: wasm-ld %t.o -o %t.wasm --max-memory=2147483648
deps/lld/test/wasm/lit.local.cfg+1-1
......@@ -1,4 +1,4 @@
11if 'wasm' not in config.available_features:
22 config.unsupported = True
33
4config.suffixes = ['.test', '.yaml', '.ll']
4config.suffixes = ['.test', '.yaml', '.ll', '.s']
deps/lld/test/wasm/local-symbols.ll+9-32
......@@ -27,13 +27,13 @@ entry:
2727; CHECK-NEXT: - Type: TYPE
2828; CHECK-NEXT: Signatures:
2929; CHECK-NEXT: - Index: 0
30; CHECK-NEXT: ReturnType: NORESULT
30; CHECK-NEXT: ReturnType: I32
3131; CHECK-NEXT: ParamTypes:
3232; CHECK-NEXT: - Index: 1
33; CHECK-NEXT: ReturnType: I32
33; CHECK-NEXT: ReturnType: NORESULT
3434; CHECK-NEXT: ParamTypes:
3535; CHECK-NEXT: - Type: FUNCTION
36; CHECK-NEXT: FunctionTypes: [ 0, 1, 0 ]
36; CHECK-NEXT: FunctionTypes: [ 0, 1 ]
3737; CHECK-NEXT: - Type: TABLE
3838; CHECK-NEXT: Tables:
3939; CHECK-NEXT: - ElemType: FUNCREF
......@@ -57,51 +57,30 @@ entry:
5757; CHECK-NEXT: Mutable: false
5858; CHECK-NEXT: InitExpr:
5959; CHECK-NEXT: Opcode: I32_CONST
60; CHECK-NEXT: Value: 66576
61; CHECK-NEXT: - Index: 2
62; CHECK-NEXT: Type: I32
63; CHECK-NEXT: Mutable: false
64; CHECK-NEXT: InitExpr:
65; CHECK-NEXT: Opcode: I32_CONST
66; CHECK-NEXT: Value: 1032
67; CHECK-NEXT: - Index: 3
68; CHECK-NEXT: Type: I32
69; CHECK-NEXT: Mutable: false
70; CHECK-NEXT: InitExpr:
71; CHECK-NEXT: Opcode: I32_CONST
7260; CHECK-NEXT: Value: 1024
7361; CHECK-NEXT: - Type: EXPORT
7462; CHECK-NEXT: Exports:
7563; CHECK-NEXT: - Name: memory
7664; CHECK-NEXT: Kind: MEMORY
7765; CHECK-NEXT: Index: 0
78; CHECK-NEXT: - Name: __heap_base
79; CHECK-NEXT: Kind: GLOBAL
80; CHECK-NEXT: Index: 1
81; CHECK-NEXT: - Name: __data_end
82; CHECK-NEXT: Kind: GLOBAL
83; CHECK-NEXT: Index: 2
8466; CHECK-NEXT: - Name: _start
8567; CHECK-NEXT: Kind: FUNCTION
86; CHECK-NEXT: Index: 2
68; CHECK-NEXT: Index: 1
8769; CHECK-NEXT: - Name: foo
8870; CHECK-NEXT: Kind: GLOBAL
89; CHECK-NEXT: Index: 3
71; CHECK-NEXT: Index: 1
9072; CHECK-NEXT: - Type: CODE
9173; CHECK-NEXT: Functions:
9274; CHECK-NEXT: - Index: 0
9375; CHECK-NEXT: Locals:
94; CHECK-NEXT: Body: 0B
95; CHECK-NEXT: - Index: 1
96; CHECK-NEXT: Locals:
9776; CHECK-NEXT: Body: 4100280284888080000B
98; CHECK-NEXT: - Index: 2
77; CHECK-NEXT: - Index: 1
9978; CHECK-NEXT: Locals:
100; CHECK-NEXT: Body: 1081808080001A0B
79; CHECK-NEXT: Body: 1080808080001A0B
10180; CHECK-NEXT: - Type: DATA
10281; CHECK-NEXT: Segments:
10382; CHECK-NEXT: - SectionOffset: 7
104; CHECK-NEXT: MemoryIndex: 0
83; CHECK-NEXT: InitFlags: 0
10584; CHECK-NEXT: Offset:
10685; CHECK-NEXT: Opcode: I32_CONST
10786; CHECK-NEXT: Value: 1024
......@@ -110,9 +89,7 @@ entry:
11089; CHECK-NEXT: Name: name
11190; CHECK-NEXT: FunctionNames:
11291; CHECK-NEXT: - Index: 0
113; CHECK-NEXT: Name: __wasm_call_ctors
114; CHECK-NEXT: - Index: 1
11592; CHECK-NEXT: Name: baz
116; CHECK-NEXT: - Index: 2
93; CHECK-NEXT: - Index: 1
11794; CHECK-NEXT: Name: _start
11895; CHECK-NEXT: ...
deps/lld/test/wasm/locals-duplicate.test+66-92
......@@ -10,14 +10,11 @@
1010; CHECK-NEXT: - Type: TYPE
1111; CHECK-NEXT: Signatures:
1212; CHECK-NEXT: - Index: 0
13; CHECK-NEXT: ReturnType: NORESULT
14; CHECK-NEXT: ParamTypes:
15; CHECK-NEXT: - Index: 1
1613; CHECK-NEXT: ReturnType: I32
1714; CHECK-NEXT: ParamTypes:
1815; CHECK-NEXT: - Type: FUNCTION
19; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
20; CHECK-NEXT: 1, 1, 1 ]
16; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17; CHECK-NEXT: 0, 0 ]
2118; CHECK-NEXT: - Type: TABLE
2219; CHECK-NEXT: Tables:
2320; CHECK-NEXT: - ElemType: FUNCREF
......@@ -41,20 +38,8 @@
4138; CHECK-NEXT: Mutable: false
4239; CHECK-NEXT: InitExpr:
4340; CHECK-NEXT: Opcode: I32_CONST
44; CHECK-NEXT: Value: 66592
45; CHECK-NEXT: - Index: 2
46; CHECK-NEXT: Type: I32
47; CHECK-NEXT: Mutable: false
48; CHECK-NEXT: InitExpr:
49; CHECK-NEXT: Opcode: I32_CONST
50; CHECK-NEXT: Value: 1048
51; CHECK-NEXT: - Index: 3
52; CHECK-NEXT: Type: I32
53; CHECK-NEXT: Mutable: false
54; CHECK-NEXT: InitExpr:
55; CHECK-NEXT: Opcode: I32_CONST
5641; CHECK-NEXT: Value: 1028
57; CHECK-NEXT: - Index: 4
42; CHECK-NEXT: - Index: 2
5843; CHECK-NEXT: Type: I32
5944; CHECK-NEXT: Mutable: false
6045; CHECK-NEXT: InitExpr:
......@@ -65,71 +50,65 @@
6550; CHECK-NEXT: - Name: memory
6651; CHECK-NEXT: Kind: MEMORY
6752; CHECK-NEXT: Index: 0
68; CHECK-NEXT: - Name: __heap_base
69; CHECK-NEXT: Kind: GLOBAL
70; CHECK-NEXT: Index: 1
71; CHECK-NEXT: - Name: __data_end
72; CHECK-NEXT: Kind: GLOBAL
73; CHECK-NEXT: Index: 2
7453; CHECK-NEXT: - Name: colliding_func2
7554; CHECK-NEXT: Kind: FUNCTION
76; CHECK-NEXT: Index: 2
55; CHECK-NEXT: Index: 1
7756; CHECK-NEXT: - Name: get_global1A
7857; CHECK-NEXT: Kind: FUNCTION
79; CHECK-NEXT: Index: 4
58; CHECK-NEXT: Index: 3
8059; CHECK-NEXT: - Name: get_global2A
8160; CHECK-NEXT: Kind: FUNCTION
82; CHECK-NEXT: Index: 5
61; CHECK-NEXT: Index: 4
8362; CHECK-NEXT: - Name: colliding_global2
8463; CHECK-NEXT: Kind: GLOBAL
85; CHECK-NEXT: Index: 3
64; CHECK-NEXT: Index: 1
8665; CHECK-NEXT: - Name: get_global3A
8766; CHECK-NEXT: Kind: FUNCTION
88; CHECK-NEXT: Index: 6
67; CHECK-NEXT: Index: 5
8968; CHECK-NEXT: - Name: get_func1A
9069; CHECK-NEXT: Kind: FUNCTION
91; CHECK-NEXT: Index: 7
70; CHECK-NEXT: Index: 6
9271; CHECK-NEXT: - Name: get_func2A
9372; CHECK-NEXT: Kind: FUNCTION
94; CHECK-NEXT: Index: 8
73; CHECK-NEXT: Index: 7
9574; CHECK-NEXT: - Name: get_func3A
9675; CHECK-NEXT: Kind: FUNCTION
97; CHECK-NEXT: Index: 9
76; CHECK-NEXT: Index: 8
9877; CHECK-NEXT: - Name: colliding_func1
9978; CHECK-NEXT: Kind: FUNCTION
100; CHECK-NEXT: Index: 10
79; CHECK-NEXT: Index: 9
10180; CHECK-NEXT: - Name: get_global1B
10281; CHECK-NEXT: Kind: FUNCTION
103; CHECK-NEXT: Index: 13
82; CHECK-NEXT: Index: 12
10483; CHECK-NEXT: - Name: colliding_global1
10584; CHECK-NEXT: Kind: GLOBAL
106; CHECK-NEXT: Index: 4
85; CHECK-NEXT: Index: 2
10786; CHECK-NEXT: - Name: get_global2B
10887; CHECK-NEXT: Kind: FUNCTION
109; CHECK-NEXT: Index: 14
88; CHECK-NEXT: Index: 13
11089; CHECK-NEXT: - Name: get_global3B
11190; CHECK-NEXT: Kind: FUNCTION
112; CHECK-NEXT: Index: 15
91; CHECK-NEXT: Index: 14
11392; CHECK-NEXT: - Name: get_func1B
11493; CHECK-NEXT: Kind: FUNCTION
115; CHECK-NEXT: Index: 16
94; CHECK-NEXT: Index: 15
11695; CHECK-NEXT: - Name: get_func2B
11796; CHECK-NEXT: Kind: FUNCTION
118; CHECK-NEXT: Index: 17
97; CHECK-NEXT: Index: 16
11998; CHECK-NEXT: - Name: get_func3B
12099; CHECK-NEXT: Kind: FUNCTION
121; CHECK-NEXT: Index: 18
100; CHECK-NEXT: Index: 17
122101; CHECK-NEXT: - Type: ELEM
123102; CHECK-NEXT: Segments:
124103; CHECK-NEXT: - Offset:
125104; CHECK-NEXT: Opcode: I32_CONST
126105; CHECK-NEXT: Value: 1
127; CHECK-NEXT: Functions: [ 1, 2, 3, 10, 11, 12 ]
106; CHECK-NEXT: Functions: [ 0, 1, 2, 9, 10, 11 ]
128107; CHECK-NEXT: - Type: CODE
129108; CHECK-NEXT: Functions:
130109; CHECK-NEXT: - Index: 0
131110; CHECK-NEXT: Locals:
132; CHECK-NEXT: Body: 0B
111; CHECK-NEXT: Body: 41020B
133112; CHECK-NEXT: - Index: 1
134113; CHECK-NEXT: Locals:
135114; CHECK-NEXT: Body: 41020B
......@@ -138,25 +117,25 @@
138117; CHECK-NEXT: Body: 41020B
139118; CHECK-NEXT: - Index: 3
140119; CHECK-NEXT: Locals:
141; CHECK-NEXT: Body: 41020B
120; CHECK-NEXT: Body: 4180888080000B
142121; CHECK-NEXT: - Index: 4
143122; CHECK-NEXT: Locals:
144; CHECK-NEXT: Body: 4180888080000B
123; CHECK-NEXT: Body: 4184888080000B
145124; CHECK-NEXT: - Index: 5
146125; CHECK-NEXT: Locals:
147; CHECK-NEXT: Body: 4184888080000B
126; CHECK-NEXT: Body: 4188888080000B
148127; CHECK-NEXT: - Index: 6
149128; CHECK-NEXT: Locals:
150; CHECK-NEXT: Body: 4188888080000B
129; CHECK-NEXT: Body: 4181808080000B
151130; CHECK-NEXT: - Index: 7
152131; CHECK-NEXT: Locals:
153; CHECK-NEXT: Body: 4181808080000B
132; CHECK-NEXT: Body: 4182808080000B
154133; CHECK-NEXT: - Index: 8
155134; CHECK-NEXT: Locals:
156; CHECK-NEXT: Body: 4182808080000B
135; CHECK-NEXT: Body: 4183808080000B
157136; CHECK-NEXT: - Index: 9
158137; CHECK-NEXT: Locals:
159; CHECK-NEXT: Body: 4183808080000B
138; CHECK-NEXT: Body: 41020B
160139; CHECK-NEXT: - Index: 10
161140; CHECK-NEXT: Locals:
162141; CHECK-NEXT: Body: 41020B
......@@ -165,29 +144,26 @@
165144; CHECK-NEXT: Body: 41020B
166145; CHECK-NEXT: - Index: 12
167146; CHECK-NEXT: Locals:
168; CHECK-NEXT: Body: 41020B
169; CHECK-NEXT: - Index: 13
170; CHECK-NEXT: Locals:
171147; CHECK-NEXT: Body: 418C888080000B
172; CHECK-NEXT: - Index: 14
148; CHECK-NEXT: - Index: 13
173149; CHECK-NEXT: Locals:
174150; CHECK-NEXT: Body: 4190888080000B
175; CHECK-NEXT: - Index: 15
151; CHECK-NEXT: - Index: 14
176152; CHECK-NEXT: Locals:
177153; CHECK-NEXT: Body: 4194888080000B
178; CHECK-NEXT: - Index: 16
154; CHECK-NEXT: - Index: 15
179155; CHECK-NEXT: Locals:
180156; CHECK-NEXT: Body: 4184808080000B
181; CHECK-NEXT: - Index: 17
157; CHECK-NEXT: - Index: 16
182158; CHECK-NEXT: Locals:
183159; CHECK-NEXT: Body: 4185808080000B
184; CHECK-NEXT: - Index: 18
160; CHECK-NEXT: - Index: 17
185161; CHECK-NEXT: Locals:
186162; CHECK-NEXT: Body: 4186808080000B
187163; CHECK-NEXT: - Type: DATA
188164; CHECK-NEXT: Segments:
189165; CHECK-NEXT: - SectionOffset: 7
190; CHECK-NEXT: MemoryIndex: 0
166; CHECK-NEXT: InitFlags: 0
191167; CHECK-NEXT: Offset:
192168; CHECK-NEXT: Opcode: I32_CONST
193169; CHECK-NEXT: Value: 1024
......@@ -196,42 +172,40 @@
196172; CHECK-NEXT: Name: name
197173; CHECK-NEXT: FunctionNames:
198174; CHECK-NEXT: - Index: 0
199; CHECK-NEXT: Name: __wasm_call_ctors
200; CHECK-NEXT: - Index: 1
201175; CHECK-NEXT: Name: colliding_func1
202; CHECK-NEXT: - Index: 2
176; CHECK-NEXT: - Index: 1
203177; CHECK-NEXT: Name: colliding_func2
204; CHECK-NEXT: - Index: 3
178; CHECK-NEXT: - Index: 2
205179; CHECK-NEXT: Name: colliding_func3
206; CHECK-NEXT: - Index: 4
180; CHECK-NEXT: - Index: 3
207181; CHECK-NEXT: Name: get_global1A
208; CHECK-NEXT: - Index: 5
182; CHECK-NEXT: - Index: 4
209183; CHECK-NEXT: Name: get_global2A
210; CHECK-NEXT: - Index: 6
184; CHECK-NEXT: - Index: 5
211185; CHECK-NEXT: Name: get_global3A
212; CHECK-NEXT: - Index: 7
186; CHECK-NEXT: - Index: 6
213187; CHECK-NEXT: Name: get_func1A
214; CHECK-NEXT: - Index: 8
188; CHECK-NEXT: - Index: 7
215189; CHECK-NEXT: Name: get_func2A
216; CHECK-NEXT: - Index: 9
190; CHECK-NEXT: - Index: 8
217191; CHECK-NEXT: Name: get_func3A
218; CHECK-NEXT: - Index: 10
192; CHECK-NEXT: - Index: 9
219193; CHECK-NEXT: Name: colliding_func1
220; CHECK-NEXT: - Index: 11
194; CHECK-NEXT: - Index: 10
221195; CHECK-NEXT: Name: colliding_func2
222; CHECK-NEXT: - Index: 12
196; CHECK-NEXT: - Index: 11
223197; CHECK-NEXT: Name: colliding_func3
224; CHECK-NEXT: - Index: 13
198; CHECK-NEXT: - Index: 12
225199; CHECK-NEXT: Name: get_global1B
226; CHECK-NEXT: - Index: 14
200; CHECK-NEXT: - Index: 13
227201; CHECK-NEXT: Name: get_global2B
228; CHECK-NEXT: - Index: 15
202; CHECK-NEXT: - Index: 14
229203; CHECK-NEXT: Name: get_global3B
230; CHECK-NEXT: - Index: 16
204; CHECK-NEXT: - Index: 15
231205; CHECK-NEXT: Name: get_func1B
232; CHECK-NEXT: - Index: 17
206; CHECK-NEXT: - Index: 16
233207; CHECK-NEXT: Name: get_func2B
234; CHECK-NEXT: - Index: 18
208; CHECK-NEXT: - Index: 17
235209; CHECK-NEXT: Name: get_func3B
236210; CHECK-NEXT: ...
237211
......@@ -269,40 +243,40 @@
269243; RELOC-NEXT: Functions: [ 0, 1, 2, 9, 10, 11 ]
270244; RELOC-NEXT: - Type: CODE
271245; RELOC-NEXT: Relocations:
272; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
246; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
273247; RELOC-NEXT: Index: 18
274248; RELOC-NEXT: Offset: 0x00000013
275; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
249; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
276250; RELOC-NEXT: Index: 3
277251; RELOC-NEXT: Offset: 0x0000001C
278; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
252; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
279253; RELOC-NEXT: Index: 19
280254; RELOC-NEXT: Offset: 0x00000025
281; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
255; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
282256; RELOC-NEXT: Index: 16
283257; RELOC-NEXT: Offset: 0x0000002E
284; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
258; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
285259; RELOC-NEXT: Index: 0
286260; RELOC-NEXT: Offset: 0x00000037
287; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
261; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
288262; RELOC-NEXT: Index: 17
289263; RELOC-NEXT: Offset: 0x00000040
290; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
264; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
291265; RELOC-NEXT: Index: 10
292266; RELOC-NEXT: Offset: 0x00000058
293; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
267; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
294268; RELOC-NEXT: Index: 22
295269; RELOC-NEXT: Offset: 0x00000061
296; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
270; RELOC-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
297271; RELOC-NEXT: Index: 23
298272; RELOC-NEXT: Offset: 0x0000006A
299; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
273; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
300274; RELOC-NEXT: Index: 8
301275; RELOC-NEXT: Offset: 0x00000073
302; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
276; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
303277; RELOC-NEXT: Index: 20
304278; RELOC-NEXT: Offset: 0x0000007C
305; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
279; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
306280; RELOC-NEXT: Index: 21
307281; RELOC-NEXT: Offset: 0x00000085
308282; RELOC-NEXT: Functions:
......@@ -363,19 +337,19 @@
363337; RELOC-NEXT: - Type: DATA
364338; RELOC-NEXT: Segments:
365339; RELOC-NEXT: - SectionOffset: 6
366; RELOC-NEXT: MemoryIndex: 0
340; RELOC-NEXT: InitFlags: 0
367341; RELOC-NEXT: Offset:
368342; RELOC-NEXT: Opcode: I32_CONST
369343; RELOC-NEXT: Value: 0
370344; RELOC-NEXT: Content: '0000000000000000'
371345; RELOC-NEXT: - SectionOffset: 19
372; RELOC-NEXT: MemoryIndex: 0
346; RELOC-NEXT: InitFlags: 0
373347; RELOC-NEXT: Offset:
374348; RELOC-NEXT: Opcode: I32_CONST
375349; RELOC-NEXT: Value: 8
376350; RELOC-NEXT: Content: '0000000000000000'
377351; RELOC-NEXT: - SectionOffset: 32
378; RELOC-NEXT: MemoryIndex: 0
352; RELOC-NEXT: InitFlags: 0
379353; RELOC-NEXT: Offset:
380354; RELOC-NEXT: Opcode: I32_CONST
381355; RELOC-NEXT: Value: 16
deps/lld/test/wasm/lto/archive.ll+1-3
......@@ -18,8 +18,6 @@ declare void @f()
1818; CHECK: Name: name
1919; CHECK-NEXT: FunctionNames:
2020; CHECK-NEXT: - Index: 0
21; CHECK-NEXT: Name: __wasm_call_ctors
22; CHECK-NEXT: - Index: 1
2321; CHECK-NEXT: Name: _start
24; CHECK-NEXT: - Index: 2
22; CHECK-NEXT: - Index: 1
2523; CHECK-NEXT: Name: f
deps/lld/test/wasm/lto/atomics.ll+3-2
......@@ -1,7 +1,8 @@
11; RUN: llvm-as %s -o %t.o
22; RUN: wasm-ld %t.o -o %t.wasm -lto-O0
3; Atomic operations with fail to compile if the ThreadModel is not
4; correctly set to Single (i.e. if atomics are not lowered to regular ops).
3
4; Atomic operations will not fail to compile if atomics are not
5; enabled because LLVM atomics will be lowered to regular ops.
56
67target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
78target triple = "wasm32-unknown-unknown-wasm"
deps/lld/test/wasm/lto/comdat.ll created+17
......@@ -0,0 +1,17 @@
1; Verify that comdat symbols can be defined in LTO objects. We had a
2; regression where the comdat handling code was causing symbol in the lto object
3; to be ignored.
4; RUN: llvm-as %s -o %t.bc
5; RUN: llc -filetype=obj %s -o %t.o
6; RUN: wasm-ld %t.bc %t.o -o %t.wasm
7; RUN: wasm-ld %t.o %t.bc -o %t.wasm
8
9target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
10target triple = "wasm32-unknown-unknown"
11
12$foo = comdat any
13
14define void @_start() comdat($foo) {
15entry:
16 ret void
17}
deps/lld/test/wasm/lto/export.ll+2-8
......@@ -23,16 +23,10 @@ entry:
2323; CHECK-NEXT: - Name: memory
2424; CHECK-NEXT: Kind: MEMORY
2525; CHECK-NEXT: Index: 0
26; CHECK-NEXT: - Name: __heap_base
27; CHECK-NEXT: Kind: GLOBAL
28; CHECK-NEXT: Index: 1
29; CHECK-NEXT: - Name: __data_end
30; CHECK-NEXT: Kind: GLOBAL
31; CHECK-NEXT: Index: 2
3226; CHECK-NEXT: - Name: hidden_function
3327; CHECK-NEXT: Kind: FUNCTION
34; CHECK-NEXT: Index: 1
28; CHECK-NEXT: Index: 0
3529; CHECK-NEXT: - Name: _start
3630; CHECK-NEXT: Kind: FUNCTION
37; CHECK-NEXT: Index: 2
31; CHECK-NEXT: Index: 1
3832; CHECK-NEXT: - Type: CODE
deps/lld/test/wasm/lto/lto-start.ll-2
......@@ -6,8 +6,6 @@
66; CHECK-NEXT: Name: name
77; CHECK-NEXT: FunctionNames:
88; CHECK-NEXT: - Index: 0
9; CHECK-NEXT: Name: __wasm_call_ctors
10; CHECK-NEXT: - Index: 1
119; CHECK-NEXT: Name: _start
1210
1311target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
deps/lld/test/wasm/lto/opt-level.ll+2-2
......@@ -7,11 +7,11 @@
77; RUN: obj2yaml %t2a | FileCheck --check-prefix=CHECK-O2 %s
88
99; Reject invalid optimization levels.
10; RUN: not ld.lld -o %t3 -e main --lto-O6 %t.o 2>&1 | \
10; RUN: not wasm-ld -o %t3 -e main --lto-O6 %t.o 2>&1 | \
1111; RUN: FileCheck --check-prefix=INVALID %s
1212; INVALID: invalid optimization level for LTO: 6
1313
14; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
14; RUN: not wasm-ld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
1515; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s
1616; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295
1717
deps/lld/test/wasm/lto/relocatable.ll created+27
......@@ -0,0 +1,27 @@
1; RUN: llvm-as %s -o %t1.o
2; RUN: wasm-ld %t1.o -r -o %t
3; RUN: llvm-readobj --symbols %t | FileCheck %s
4
5; CHECK: Symbols [
6; CHECK-NEXT: Symbol {
7; CHECK-NEXT: Name: foo
8; CHECK-NEXT: Type: FUNCTION (0x0)
9; CHECK-NEXT: Flags [ (0x0)
10; CHECK-NEXT: ]
11; CHECK-NEXT: ElementIndex: 0x0
12; CHECK-NEXT: }
13; CHECK-NEXT: ]
14
15target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
16target triple = "wasm32-unknown-unknown"
17
18define void @foo() {
19 call void @bar()
20 ret void
21}
22
23define internal void @bar() {
24 ret void
25}
26
27declare i32 @baz(...)
deps/lld/test/wasm/lto/signature-mismatch.ll+1
......@@ -15,5 +15,6 @@ define void @_start() {
1515 ret void
1616}
1717
18; CHECK: error: function signature mismatch: f
1819; CHECK: >>> defined as (i32) -> void in {{.*}}signature-mismatch.ll.tmp1.o
1920; CHECK: >>> defined as () -> void in lto.tmp
deps/lld/test/wasm/lto/undef.ll+18-2
......@@ -5,10 +5,22 @@
55target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
66target triple = "wasm32-unknown-unknown"
77
8declare void @bar()
8declare i32 @bar()
9
10; Symbols such as foo which are only called indirectly are handled slightly
11; differently with resepect to signature checking.
12declare i32 @foo()
13
14@ptr = global i8* bitcast (i32 ()* @foo to i8*), align 8
15; Ensure access to ptr is not inlined below, even under LTO
16@llvm.used = appending global [1 x i8**] [i8** @ptr], section "llvm.metadata"
917
1018define void @_start() {
11 call void @bar()
19 call i32 @bar()
20
21 %addr = load i32 ()*, i32 ()** bitcast (i8** @ptr to i32 ()**), align 8
22 call i32 %addr()
23
1224 ret void
1325}
1426
......@@ -18,3 +30,7 @@ define void @_start() {
1830; CHECK-NEXT: Field: bar
1931; CHECK-NEXT: Kind: FUNCTION
2032; CHECK-NEXT: SigIndex: 0
33; CHECK-NEXT: - Module: env
34; CHECK-NEXT: Field: foo
35; CHECK-NEXT: Kind: FUNCTION
36; CHECK-NEXT: SigIndex: 0
deps/lld/test/wasm/lto/used.ll+2-4
......@@ -28,7 +28,7 @@ return:
2828; CHECK: - Type: DATA
2929; CHECK-NEXT: Segments:
3030; CHECK-NEXT: - SectionOffset: 7
31; CHECK-NEXT: MemoryIndex: 0
31; CHECK-NEXT: InitFlags: 0
3232; CHECK-NEXT: Offset:
3333; CHECK-NEXT: Opcode: I32_CONST
3434; CHECK-NEXT: Value: 1024
......@@ -38,8 +38,6 @@ return:
3838; CHECK-NEXT: Name: name
3939; CHECK-NEXT: FunctionNames:
4040; CHECK-NEXT: - Index: 0
41; CHECK-NEXT: Name: __wasm_call_ctors
42; CHECK-NEXT: - Index: 1
4341; CHECK-NEXT: Name: _start
44; CHECK-NEXT: - Index: 2
42; CHECK-NEXT: - Index: 1
4543; CHECK-NEXT: Name: bar
deps/lld/test/wasm/lto/weak-undefined.ll created+20
......@@ -0,0 +1,20 @@
1; RUN: llvm-as %s -o %t.o
2; RUN: wasm-ld %t.o -o %t.wasm
3; RUN: obj2yaml %t.wasm | FileCheck %s
4
5; Test that undefined weak external functions are handled in the LTO case
6; We had a bug where stub function generation was failing because functions
7; that are in bitcode (pre-LTO) don't have signatures assigned.
8
9target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
10target triple = "wasm32-unknown-unknown"
11
12declare extern_weak i32 @foo()
13
14define void @_start() #0 {
15entry:
16 %call2 = call i32 @foo()
17 ret void
18}
19
20; CHECK: Name: 'undefined:foo'
deps/lld/test/wasm/lto/weak.ll+5-2
......@@ -1,6 +1,6 @@
11; RUN: llvm-as %s -o %t.o
22; RUN: wasm-ld %t.o %t.o -o %t.wasm -r
3; RUN: llvm-readobj -t %t.wasm | FileCheck %s
3; RUN: llvm-readobj --symbols %t.wasm | FileCheck %s
44
55target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
66target triple = "wasm32-unknown-unknown-wasm"
......@@ -12,5 +12,8 @@ define weak void @f() {
1212; CHECK: Symbol {
1313; CHECK-NEXT: Name: f
1414; CHECK-NEXT: Type: FUNCTION (0x0)
15; CHECK-NEXT: Flags: 0x1
15; CHECK-NEXT: Flags [ (0x1)
16; CHECK-NEXT: BINDING_WEAK (0x1)
17; CHECK-NEXT: ]
18; CHECK-NEXT: ElementIndex: 0x0
1619; CHECK-NEXT: }
deps/lld/test/wasm/many-functions.ll+132-132
......@@ -18,394 +18,394 @@ entry:
1818
1919; CHECK: - Type: CODE
2020; CHECK-NEXT: Relocations:
21; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
21; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
2222; CHECK-NEXT: Index: 1
2323; CHECK-NEXT: Offset: 0x00000008
24; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
24; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
2525; CHECK-NEXT: Index: 1
2626; CHECK-NEXT: Offset: 0x00000014
27; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
27; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
2828; CHECK-NEXT: Index: 1
2929; CHECK-NEXT: Offset: 0x00000020
30; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
30; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
3131; CHECK-NEXT: Index: 1
3232; CHECK-NEXT: Offset: 0x0000002C
33; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
33; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
3434; CHECK-NEXT: Index: 1
3535; CHECK-NEXT: Offset: 0x00000038
36; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
36; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
3737; CHECK-NEXT: Index: 1
3838; CHECK-NEXT: Offset: 0x00000044
39; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
39; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
4040; CHECK-NEXT: Index: 1
4141; CHECK-NEXT: Offset: 0x00000050
42; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
42; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
4343; CHECK-NEXT: Index: 1
4444; CHECK-NEXT: Offset: 0x0000005C
45; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
45; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
4646; CHECK-NEXT: Index: 1
4747; CHECK-NEXT: Offset: 0x00000068
48; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
48; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
4949; CHECK-NEXT: Index: 1
5050; CHECK-NEXT: Offset: 0x00000074
51; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
51; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
5252; CHECK-NEXT: Index: 1
5353; CHECK-NEXT: Offset: 0x00000080
54; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
54; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
5555; CHECK-NEXT: Index: 1
5656; CHECK-NEXT: Offset: 0x0000008C
57; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
57; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
5858; CHECK-NEXT: Index: 1
5959; CHECK-NEXT: Offset: 0x00000098
60; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
60; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
6161; CHECK-NEXT: Index: 1
6262; CHECK-NEXT: Offset: 0x000000A4
63; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
63; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
6464; CHECK-NEXT: Index: 1
6565; CHECK-NEXT: Offset: 0x000000B0
66; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
66; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
6767; CHECK-NEXT: Index: 1
6868; CHECK-NEXT: Offset: 0x000000BC
69; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
69; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
7070; CHECK-NEXT: Index: 1
7171; CHECK-NEXT: Offset: 0x000000C8
72; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
72; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
7373; CHECK-NEXT: Index: 1
7474; CHECK-NEXT: Offset: 0x000000D4
75; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
75; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
7676; CHECK-NEXT: Index: 1
7777; CHECK-NEXT: Offset: 0x000000E0
78; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
78; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
7979; CHECK-NEXT: Index: 1
8080; CHECK-NEXT: Offset: 0x000000EC
81; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
81; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
8282; CHECK-NEXT: Index: 1
8383; CHECK-NEXT: Offset: 0x000000F8
84; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
84; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
8585; CHECK-NEXT: Index: 1
8686; CHECK-NEXT: Offset: 0x00000104
87; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
87; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
8888; CHECK-NEXT: Index: 1
8989; CHECK-NEXT: Offset: 0x00000110
90; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
90; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
9191; CHECK-NEXT: Index: 1
9292; CHECK-NEXT: Offset: 0x0000011C
93; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
93; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
9494; CHECK-NEXT: Index: 1
9595; CHECK-NEXT: Offset: 0x00000128
96; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
96; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
9797; CHECK-NEXT: Index: 1
9898; CHECK-NEXT: Offset: 0x00000134
99; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
99; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
100100; CHECK-NEXT: Index: 1
101101; CHECK-NEXT: Offset: 0x00000140
102; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
102; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
103103; CHECK-NEXT: Index: 1
104104; CHECK-NEXT: Offset: 0x0000014C
105; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
105; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
106106; CHECK-NEXT: Index: 1
107107; CHECK-NEXT: Offset: 0x00000158
108; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
108; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
109109; CHECK-NEXT: Index: 1
110110; CHECK-NEXT: Offset: 0x00000164
111; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
111; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
112112; CHECK-NEXT: Index: 1
113113; CHECK-NEXT: Offset: 0x00000170
114; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
114; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
115115; CHECK-NEXT: Index: 1
116116; CHECK-NEXT: Offset: 0x0000017C
117; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
117; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
118118; CHECK-NEXT: Index: 1
119119; CHECK-NEXT: Offset: 0x00000188
120; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
120; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
121121; CHECK-NEXT: Index: 1
122122; CHECK-NEXT: Offset: 0x00000194
123; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
123; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
124124; CHECK-NEXT: Index: 1
125125; CHECK-NEXT: Offset: 0x000001A0
126; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
126; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
127127; CHECK-NEXT: Index: 1
128128; CHECK-NEXT: Offset: 0x000001AC
129; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
129; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
130130; CHECK-NEXT: Index: 1
131131; CHECK-NEXT: Offset: 0x000001B8
132; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
132; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
133133; CHECK-NEXT: Index: 1
134134; CHECK-NEXT: Offset: 0x000001C4
135; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
135; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
136136; CHECK-NEXT: Index: 1
137137; CHECK-NEXT: Offset: 0x000001D0
138; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
138; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
139139; CHECK-NEXT: Index: 1
140140; CHECK-NEXT: Offset: 0x000001DC
141; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
141; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
142142; CHECK-NEXT: Index: 1
143143; CHECK-NEXT: Offset: 0x000001E8
144; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
144; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
145145; CHECK-NEXT: Index: 1
146146; CHECK-NEXT: Offset: 0x000001F4
147; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
147; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
148148; CHECK-NEXT: Index: 1
149149; CHECK-NEXT: Offset: 0x00000200
150; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
150; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
151151; CHECK-NEXT: Index: 1
152152; CHECK-NEXT: Offset: 0x0000020C
153; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
153; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
154154; CHECK-NEXT: Index: 1
155155; CHECK-NEXT: Offset: 0x00000218
156; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
156; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
157157; CHECK-NEXT: Index: 1
158158; CHECK-NEXT: Offset: 0x00000224
159; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
159; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
160160; CHECK-NEXT: Index: 1
161161; CHECK-NEXT: Offset: 0x00000230
162; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
162; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
163163; CHECK-NEXT: Index: 1
164164; CHECK-NEXT: Offset: 0x0000023C
165; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
165; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
166166; CHECK-NEXT: Index: 1
167167; CHECK-NEXT: Offset: 0x00000248
168; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
168; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
169169; CHECK-NEXT: Index: 1
170170; CHECK-NEXT: Offset: 0x00000254
171; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
171; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
172172; CHECK-NEXT: Index: 1
173173; CHECK-NEXT: Offset: 0x00000260
174; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
174; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
175175; CHECK-NEXT: Index: 1
176176; CHECK-NEXT: Offset: 0x0000026C
177; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
177; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
178178; CHECK-NEXT: Index: 1
179179; CHECK-NEXT: Offset: 0x00000278
180; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
180; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
181181; CHECK-NEXT: Index: 1
182182; CHECK-NEXT: Offset: 0x00000284
183; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
183; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
184184; CHECK-NEXT: Index: 1
185185; CHECK-NEXT: Offset: 0x00000290
186; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
186; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
187187; CHECK-NEXT: Index: 1
188188; CHECK-NEXT: Offset: 0x0000029C
189; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
189; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
190190; CHECK-NEXT: Index: 1
191191; CHECK-NEXT: Offset: 0x000002A8
192; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
192; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
193193; CHECK-NEXT: Index: 1
194194; CHECK-NEXT: Offset: 0x000002B4
195; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
195; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
196196; CHECK-NEXT: Index: 1
197197; CHECK-NEXT: Offset: 0x000002C0
198; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
198; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
199199; CHECK-NEXT: Index: 1
200200; CHECK-NEXT: Offset: 0x000002CC
201; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
201; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
202202; CHECK-NEXT: Index: 1
203203; CHECK-NEXT: Offset: 0x000002D8
204; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
204; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
205205; CHECK-NEXT: Index: 1
206206; CHECK-NEXT: Offset: 0x000002E4
207; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
207; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
208208; CHECK-NEXT: Index: 1
209209; CHECK-NEXT: Offset: 0x000002F0
210; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
210; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
211211; CHECK-NEXT: Index: 1
212212; CHECK-NEXT: Offset: 0x000002FC
213; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
213; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
214214; CHECK-NEXT: Index: 1
215215; CHECK-NEXT: Offset: 0x00000308
216; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
216; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
217217; CHECK-NEXT: Index: 1
218218; CHECK-NEXT: Offset: 0x00000314
219; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
219; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
220220; CHECK-NEXT: Index: 1
221221; CHECK-NEXT: Offset: 0x00000320
222; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
222; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
223223; CHECK-NEXT: Index: 1
224224; CHECK-NEXT: Offset: 0x0000032C
225; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
225; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
226226; CHECK-NEXT: Index: 1
227227; CHECK-NEXT: Offset: 0x00000338
228; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
228; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
229229; CHECK-NEXT: Index: 1
230230; CHECK-NEXT: Offset: 0x00000344
231; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
231; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
232232; CHECK-NEXT: Index: 1
233233; CHECK-NEXT: Offset: 0x00000350
234; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
234; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
235235; CHECK-NEXT: Index: 1
236236; CHECK-NEXT: Offset: 0x0000035C
237; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
237; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
238238; CHECK-NEXT: Index: 1
239239; CHECK-NEXT: Offset: 0x00000368
240; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
240; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
241241; CHECK-NEXT: Index: 1
242242; CHECK-NEXT: Offset: 0x00000374
243; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
243; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
244244; CHECK-NEXT: Index: 1
245245; CHECK-NEXT: Offset: 0x00000380
246; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
246; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
247247; CHECK-NEXT: Index: 1
248248; CHECK-NEXT: Offset: 0x0000038C
249; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
249; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
250250; CHECK-NEXT: Index: 1
251251; CHECK-NEXT: Offset: 0x00000398
252; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
252; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
253253; CHECK-NEXT: Index: 1
254254; CHECK-NEXT: Offset: 0x000003A4
255; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
255; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
256256; CHECK-NEXT: Index: 1
257257; CHECK-NEXT: Offset: 0x000003B0
258; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
258; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
259259; CHECK-NEXT: Index: 1
260260; CHECK-NEXT: Offset: 0x000003BC
261; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
261; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
262262; CHECK-NEXT: Index: 1
263263; CHECK-NEXT: Offset: 0x000003C8
264; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
264; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
265265; CHECK-NEXT: Index: 1
266266; CHECK-NEXT: Offset: 0x000003D4
267; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
267; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
268268; CHECK-NEXT: Index: 1
269269; CHECK-NEXT: Offset: 0x000003E0
270; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
270; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
271271; CHECK-NEXT: Index: 1
272272; CHECK-NEXT: Offset: 0x000003EC
273; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
273; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
274274; CHECK-NEXT: Index: 1
275275; CHECK-NEXT: Offset: 0x000003F8
276; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
276; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
277277; CHECK-NEXT: Index: 1
278278; CHECK-NEXT: Offset: 0x00000404
279; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
279; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
280280; CHECK-NEXT: Index: 1
281281; CHECK-NEXT: Offset: 0x00000410
282; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
282; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
283283; CHECK-NEXT: Index: 1
284284; CHECK-NEXT: Offset: 0x0000041C
285; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
285; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
286286; CHECK-NEXT: Index: 1
287287; CHECK-NEXT: Offset: 0x00000428
288; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
288; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
289289; CHECK-NEXT: Index: 1
290290; CHECK-NEXT: Offset: 0x00000434
291; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
291; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
292292; CHECK-NEXT: Index: 1
293293; CHECK-NEXT: Offset: 0x00000440
294; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
294; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
295295; CHECK-NEXT: Index: 1
296296; CHECK-NEXT: Offset: 0x0000044C
297; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
297; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
298298; CHECK-NEXT: Index: 1
299299; CHECK-NEXT: Offset: 0x00000458
300; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
300; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
301301; CHECK-NEXT: Index: 1
302302; CHECK-NEXT: Offset: 0x00000464
303; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
303; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
304304; CHECK-NEXT: Index: 1
305305; CHECK-NEXT: Offset: 0x00000470
306; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
306; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
307307; CHECK-NEXT: Index: 1
308308; CHECK-NEXT: Offset: 0x0000047C
309; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
309; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
310310; CHECK-NEXT: Index: 1
311311; CHECK-NEXT: Offset: 0x00000488
312; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
312; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
313313; CHECK-NEXT: Index: 1
314314; CHECK-NEXT: Offset: 0x00000494
315; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
315; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
316316; CHECK-NEXT: Index: 1
317317; CHECK-NEXT: Offset: 0x000004A0
318; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
318; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
319319; CHECK-NEXT: Index: 1
320320; CHECK-NEXT: Offset: 0x000004AC
321; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
321; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
322322; CHECK-NEXT: Index: 1
323323; CHECK-NEXT: Offset: 0x000004B8
324; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
324; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
325325; CHECK-NEXT: Index: 1
326326; CHECK-NEXT: Offset: 0x000004C4
327; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
327; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
328328; CHECK-NEXT: Index: 1
329329; CHECK-NEXT: Offset: 0x000004D0
330; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
330; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
331331; CHECK-NEXT: Index: 1
332332; CHECK-NEXT: Offset: 0x000004DC
333; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
333; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
334334; CHECK-NEXT: Index: 1
335335; CHECK-NEXT: Offset: 0x000004E8
336; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
336; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
337337; CHECK-NEXT: Index: 1
338338; CHECK-NEXT: Offset: 0x000004F4
339; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
339; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
340340; CHECK-NEXT: Index: 1
341341; CHECK-NEXT: Offset: 0x00000500
342; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
342; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
343343; CHECK-NEXT: Index: 1
344344; CHECK-NEXT: Offset: 0x0000050C
345; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
345; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
346346; CHECK-NEXT: Index: 1
347347; CHECK-NEXT: Offset: 0x00000518
348; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
348; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
349349; CHECK-NEXT: Index: 1
350350; CHECK-NEXT: Offset: 0x00000524
351; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
351; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
352352; CHECK-NEXT: Index: 1
353353; CHECK-NEXT: Offset: 0x00000530
354; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
354; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
355355; CHECK-NEXT: Index: 1
356356; CHECK-NEXT: Offset: 0x0000053C
357; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
357; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
358358; CHECK-NEXT: Index: 1
359359; CHECK-NEXT: Offset: 0x00000548
360; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
360; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
361361; CHECK-NEXT: Index: 1
362362; CHECK-NEXT: Offset: 0x00000554
363; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
363; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
364364; CHECK-NEXT: Index: 1
365365; CHECK-NEXT: Offset: 0x00000560
366; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
366; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
367367; CHECK-NEXT: Index: 1
368368; CHECK-NEXT: Offset: 0x0000056C
369; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
369; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
370370; CHECK-NEXT: Index: 1
371371; CHECK-NEXT: Offset: 0x00000578
372; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
372; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
373373; CHECK-NEXT: Index: 1
374374; CHECK-NEXT: Offset: 0x00000584
375; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
375; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
376376; CHECK-NEXT: Index: 1
377377; CHECK-NEXT: Offset: 0x00000590
378; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
378; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
379379; CHECK-NEXT: Index: 1
380380; CHECK-NEXT: Offset: 0x0000059C
381; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
381; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
382382; CHECK-NEXT: Index: 1
383383; CHECK-NEXT: Offset: 0x000005A8
384; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
384; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
385385; CHECK-NEXT: Index: 1
386386; CHECK-NEXT: Offset: 0x000005B4
387; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
387; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
388388; CHECK-NEXT: Index: 1
389389; CHECK-NEXT: Offset: 0x000005C0
390; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
390; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
391391; CHECK-NEXT: Index: 1
392392; CHECK-NEXT: Offset: 0x000005CC
393; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
393; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
394394; CHECK-NEXT: Index: 1
395395; CHECK-NEXT: Offset: 0x000005D8
396; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
396; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
397397; CHECK-NEXT: Index: 1
398398; CHECK-NEXT: Offset: 0x000005E4
399; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
399; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
400400; CHECK-NEXT: Index: 1
401401; CHECK-NEXT: Offset: 0x000005F0
402; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
402; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
403403; CHECK-NEXT: Index: 129
404404; CHECK-NEXT: Offset: 0x000005FC
405; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
405; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
406406; CHECK-NEXT: Index: 129
407407; CHECK-NEXT: Offset: 0x00000608
408; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
408; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
409409; CHECK-NEXT: Index: 131
410410; CHECK-NEXT: Offset: 0x00000611
411411; CHECK-NEXT: Functions:
......@@ -802,13 +802,13 @@ entry:
802802; CHECK-NEXT: - Type: DATA
803803; CHECK-NEXT: Segments:
804804; CHECK-NEXT: - SectionOffset: 6
805; CHECK-NEXT: MemoryIndex: 0
805; CHECK-NEXT: InitFlags: 0
806806; CHECK-NEXT: Offset:
807807; CHECK-NEXT: Opcode: I32_CONST
808808; CHECK-NEXT: Value: 0
809809; CHECK-NEXT: Content: '01000000'
810810; CHECK-NEXT: - SectionOffset: 15
811; CHECK-NEXT: MemoryIndex: 0
811; CHECK-NEXT: InitFlags: 0
812812; CHECK-NEXT: Offset:
813813; CHECK-NEXT: Opcode: I32_CONST
814814; CHECK-NEXT: Value: 4
deps/lld/test/wasm/pie.ll created+58
......@@ -0,0 +1,58 @@
1; RUN: llc -relocation-model=pic -filetype=obj %s -o %t.o
2; RUN: wasm-ld --no-gc-sections --allow-undefined -pie -o %t.wasm %t.o
3; RUN: obj2yaml %t.wasm | FileCheck %s
4
5target triple = "wasm32-unknown-emscripten"
6
7@data = global i32 2, align 4
8@data_external = external global i32
9@indirect_func = local_unnamed_addr global i32 ()* @foo, align 4
10
11@data_addr = local_unnamed_addr global i32* @data, align 4
12@data_addr_external = local_unnamed_addr global i32* @data_external, align 4
13
14define hidden i32 @foo() {
15entry:
16 ; To ensure we use __stack_pointer
17 %ptr = alloca i32
18 %0 = load i32, i32* @data, align 4
19 %1 = load i32 ()*, i32 ()** @indirect_func, align 4
20 call i32 %1()
21 ret i32 %0
22}
23
24define default i32** @get_data_address() {
25entry:
26 ret i32** @data_addr_external
27}
28
29define void @_start() {
30 ret void
31}
32
33; CHECK: - Type: IMPORT
34; CHECK-NEXT: Imports:
35; CHECK-NEXT: - Module: env
36; CHECK-NEXT: Field: __indirect_function_table
37; CHECK-NEXT: Kind: TABLE
38; CHECK-NEXT: Table:
39; CHECK-NEXT: ElemType: FUNCREF
40; CHECK-NEXT: Limits:
41; CHECK-NEXT: Initial: 0x00000001
42; CHECK-NEXT: - Module: env
43; CHECK-NEXT: Field: __stack_pointer
44; CHECK-NEXT: Kind: GLOBAL
45; CHECK-NEXT: GlobalType: I32
46; CHECK-NEXT: GlobalMutable: true
47; CHECK-NEXT: - Module: env
48; CHECK-NEXT: Field: __memory_base
49; CHECK-NEXT: Kind: GLOBAL
50; CHECK-NEXT: GlobalType: I32
51; CHECK-NEXT: GlobalMutable: false
52; CHECK-NEXT: - Module: env
53; CHECK-NEXT: Field: __table_base
54; CHECK-NEXT: Kind: GLOBAL
55; CHECK-NEXT: GlobalType: I32
56; CHECK-NEXT: GlobalMutable: false
57
58
deps/lld/test/wasm/reloc-addend.ll+1-1
......@@ -13,7 +13,7 @@ target triple = "wasm32-unknown-unknown"
1313
1414; CHECK: - Type: DATA
1515; CHECK-NEXT: Relocations:
16; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
16; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
1717; CHECK-NEXT: Index: 0
1818; CHECK-NEXT: Offset: 0x0000013D
1919; CHECK-NEXT: Addend: 64
deps/lld/test/wasm/relocatable.ll+15-15
......@@ -79,19 +79,19 @@ entry:
7979; CHECK-NEXT: Functions: [ 4, 1, 2 ]
8080; CHECK-NEXT: - Type: CODE
8181; CHECK-NEXT: Relocations:
82; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
82; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
8383; CHECK-NEXT: Index: 1
8484; CHECK-NEXT: Offset: 0x00000004
85; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
85; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
8686; CHECK-NEXT: Index: 2
8787; CHECK-NEXT: Offset: 0x0000000A
88; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
88; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
8989; CHECK-NEXT: Index: 4
9090; CHECK-NEXT: Offset: 0x00000013
91; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
91; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
9292; CHECK-NEXT: Index: 5
9393; CHECK-NEXT: Offset: 0x0000001A
94; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
94; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
9595; CHECK-NEXT: Index: 7
9696; CHECK-NEXT: Offset: 0x00000026
9797; CHECK-NEXT: Functions:
......@@ -106,51 +106,51 @@ entry:
106106; CHECK-NEXT: Body: 419C808080000B
107107; CHECK-NEXT: - Type: DATA
108108; CHECK-NEXT: Relocations:
109; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
109; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
110110; CHECK-NEXT: Index: 3
111111; CHECK-NEXT: Offset: 0x00000012
112; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
112; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
113113; CHECK-NEXT: Index: 4
114114; CHECK-NEXT: Offset: 0x0000001B
115; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
115; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
116116; CHECK-NEXT: Index: 5
117117; CHECK-NEXT: Offset: 0x00000024
118; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
118; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
119119; CHECK-NEXT: Index: 12
120120; CHECK-NEXT: Offset: 0x0000002D
121121; CHECK-NEXT: Segments:
122122; CHECK-NEXT: - SectionOffset: 6
123; CHECK-NEXT: MemoryIndex: 0
123; CHECK-NEXT: InitFlags: 0
124124; CHECK-NEXT: Offset:
125125; CHECK-NEXT: Opcode: I32_CONST
126126; CHECK-NEXT: Value: 0
127127; CHECK-NEXT: Content: 68656C6C6F0A00
128128; CHECK-NEXT: - SectionOffset: 18
129; CHECK-NEXT: MemoryIndex: 0
129; CHECK-NEXT: InitFlags: 0
130130; CHECK-NEXT: Offset:
131131; CHECK-NEXT: Opcode: I32_CONST
132132; CHECK-NEXT: Value: 8
133133; CHECK-NEXT: Content: '01000000'
134134; CHECK-NEXT: - SectionOffset: 27
135; CHECK-NEXT: MemoryIndex: 0
135; CHECK-NEXT: InitFlags: 0
136136; CHECK-NEXT: Offset:
137137; CHECK-NEXT: Opcode: I32_CONST
138138; CHECK-NEXT: Value: 12
139139; CHECK-NEXT: Content: '02000000'
140140; CHECK-NEXT: - SectionOffset: 36
141; CHECK-NEXT: MemoryIndex: 0
141; CHECK-NEXT: InitFlags: 0
142142; CHECK-NEXT: Offset:
143143; CHECK-NEXT: Opcode: I32_CONST
144144; CHECK-NEXT: Value: 16
145145; CHECK-NEXT: Content: '03000000'
146146; CHECK-NEXT: - SectionOffset: 45
147; CHECK-NEXT: MemoryIndex: 0
147; CHECK-NEXT: InitFlags: 0
148148; CHECK-NEXT: Offset:
149149; CHECK-NEXT: Opcode: I32_CONST
150150; CHECK-NEXT: Value: 24
151151; CHECK-NEXT: Content: '00000000'
152152; CHECK-NEXT: - SectionOffset: 54
153; CHECK-NEXT: MemoryIndex: 0
153; CHECK-NEXT: InitFlags: 0
154154; CHECK-NEXT: Offset:
155155; CHECK-NEXT: Opcode: I32_CONST
156156; CHECK-NEXT: Value: 28
deps/lld/test/wasm/reproduce.ll created+27
......@@ -0,0 +1,27 @@
1; REQUIRES: shell
2; RUN: rm -rf %t.dir
3; RUN: mkdir -p %t.dir
4; RUN: llc -filetype=obj %s -o %t.dir/foo.o
5; RUN: wasm-ld --reproduce=%t.dir/repro.tar -o %t.dir/out.wasm %t.dir/foo.o
6
7; RUN: cd %t.dir
8; RUN: tar tf repro.tar | FileCheck --check-prefix=TAR %s
9
10; TAR: repro/response.txt
11; TAR: repro/version.txt
12; TAR: repro/{{.*}}/foo.o
13
14; RUN: tar xf repro.tar
15; RUN: FileCheck --check-prefix=RSP %s < repro/response.txt
16
17; RSP: -o {{.*}}out.wasm
18; RSP: {{.*}}/foo.o
19
20; RUN: FileCheck %s --check-prefix=VERSION < repro/version.txt
21; VERSION: LLD
22
23target triple = "wasm32-unknown-unknown"
24
25define void @_start() {
26 ret void
27}
deps/lld/test/wasm/section-symbol-relocs.yaml created+61
......@@ -0,0 +1,61 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: llc -filetype=obj %S/Inputs/custom.ll -o %t2.o
3# RUN: wasm-ld --no-entry -o - %t2.o %t.o | obj2yaml | FileCheck %s
4# RUN: wasm-ld -r --no-entry -o - %t2.o %t.o | obj2yaml | FileCheck %s -check-prefix=RELOC
5
6--- !WASM
7FileHeader:
8 Version: 0x00000001
9Sections:
10 - Type: CUSTOM
11 Name: green
12 Payload: 'AA0000000000000000'
13 Relocations:
14 - Type: R_WASM_SECTION_OFFSET_I32
15 Index: 0
16 Offset: 0x00000001
17 - Type: R_WASM_SECTION_OFFSET_I32
18 Index: 1
19 Offset: 0x00000005
20 - Type: CUSTOM
21 Name: red
22 Payload: 'BB0000000000000000'
23 - Type: CUSTOM
24 Name: linking
25 Version: 2
26 SymbolTable:
27 - Index: 0
28 Kind: SECTION
29 Section: 0
30 Flags: [ BINDING_LOCAL ]
31 - Index: 1
32 Kind: SECTION
33 Section: 1
34 Flags: [ BINDING_LOCAL ]
35...
36
37# CHECK: Name: green
38# CHECK-NEXT: Payload: 626172717578AA0600000003000000
39# CHECK: Name: red
40# CHECK-NEXT: Payload: 666F6FBB0000000000000000
41
42# RELOC: Relocations:
43# RELOC-NEXT: - Type: R_WASM_SECTION_OFFSET_I32
44# RELOC-NEXT: Index: 0
45# RELOC-NEXT: Offset: 0x00000007
46# RELOC-NEXT: Addend: 6
47# RELOC-NEXT: - Type: R_WASM_SECTION_OFFSET_I32
48# RELOC-NEXT: Index: 1
49# RELOC-NEXT: Offset: 0x0000000B
50# RELOC-NEXT: Addend: 3
51# RELOC-NEXT: Name: green
52#
53# RELOC: SymbolTable:
54# RELOC-NEXT: - Index: 0
55# RELOC-NEXT: Kind: SECTION
56# RELOC-NEXT: Flags: [ BINDING_LOCAL ]
57# RELOC-NEXT: Section: 2
58# RELOC-NEXT: - Index: 1
59# RELOC-NEXT: Kind: SECTION
60# RELOC-NEXT: Flags: [ BINDING_LOCAL ]
61# RELOC-NEXT: Section: 3
deps/lld/test/wasm/shared-memory-no-atomics.yaml created+60
......@@ -0,0 +1,60 @@
1# RUN: yaml2obj %s -o %t1.o
2
3# RUN: wasm-ld --no-entry %t1.o -o - | obj2yaml | FileCheck %s --check-prefix NO-SHARED
4
5# RUN: not wasm-ld --no-entry --shared-memory --max-memory=131072 %t1.o -o - 2>&1 | FileCheck %s --check-prefix SHARED
6
7--- !WASM
8FileHeader:
9 Version: 0x00000001
10Sections:
11 - Type: IMPORT
12 Imports:
13 - Module: env
14 Field: __linear_memory
15 Kind: MEMORY
16 Memory:
17 Initial: 0x00000001
18 - Module: env
19 Field: __indirect_function_table
20 Kind: TABLE
21 Table:
22 ElemType: FUNCREF
23 Limits:
24 Initial: 0x00000000
25 - Type: DATA
26 Segments:
27 - SectionOffset: 6
28 InitFlags: 0
29 Offset:
30 Opcode: I32_CONST
31 Value: 0
32 Content: 68656C6C6F0A00
33 - Type: CUSTOM
34 Name: linking
35 Version: 2
36 SymbolTable:
37 - Index: 0
38 Kind: DATA
39 Name: hello_str
40 Flags: [ ]
41 Segment: 0
42 Size: 7
43 SegmentInfo:
44 - Index: 0
45 Name: .rodata.hello_str
46 Alignment: 0
47 Flags: [ ]
48 - Type: CUSTOM
49 Name: target_features
50 Features:
51 - Prefix: DISALLOWED
52 Name: "atomics"
53...
54
55# NO-SHARED: - Type: MEMORY
56# NO-SHARED-NEXT: Memories:
57# NO-SHARED-NEXT: - Initial: 0x00000002
58# NO-SHARED-NOT: Maximum:
59
60# SHARED: 'atomics' feature is disallowed by {{.*}}shared-memory-no-atomics.yaml.tmp1.o, so --shared-memory must not be used{{$}}
deps/lld/test/wasm/shared-memory.yaml created+75
......@@ -0,0 +1,75 @@
1# RUN: yaml2obj %s -o %t1.o
2
3# RUN: not wasm-ld --no-entry --shared-memory --active-segments %t1.o -o - 2>&1 | FileCheck %s --check-prefix SHARED-NO-MAX
4
5# RUN: not wasm-ld --no-entry --shared-memory --active-segments --max-memory=100000 %t1.o -o - 2>&1 | FileCheck %s --check-prefix SHARED-UNALIGNED
6
7# RUN: wasm-ld --no-entry --shared-memory --active-segments --max-memory=131072 %t1.o -o - | obj2yaml | FileCheck %s --check-prefix SHARED
8
9# RUN: not wasm-ld --no-entry --features=atomics %t1.o -o - 2>&1 | FileCheck %s --check-prefix ATOMICS-NO-SHARED
10
11# RUN: not wasm-ld --no-entry --features=atomics --shared-memory --active-segments %t1.o -o - 2>&1 | FileCheck %s --check-prefix ATOMICS-NO-MAX
12
13# RUN: not wasm-ld --no-entry --features=atomics --shared-memory --active-segments --max-memory=100000 %t1.o -o - 2>&1 | FileCheck %s --check-prefix ATOMICS-UNALIGNED
14
15# RUN: wasm-ld --no-entry --features=atomics --shared-memory --active-segments --max-memory=131072 %t1.o -o - | obj2yaml | FileCheck %s --check-prefix SHARED
16
17
18--- !WASM
19FileHeader:
20 Version: 0x00000001
21Sections:
22 - Type: IMPORT
23 Imports:
24 - Module: env
25 Field: __linear_memory
26 Kind: MEMORY
27 Memory:
28 Initial: 0x00000001
29 - Module: env
30 Field: __indirect_function_table
31 Kind: TABLE
32 Table:
33 ElemType: FUNCREF
34 Limits:
35 Initial: 0x00000000
36 - Type: DATA
37 Segments:
38 - SectionOffset: 6
39 InitFlags: 0
40 Offset:
41 Opcode: I32_CONST
42 Value: 0
43 Content: 68656C6C6F0A00
44 - Type: CUSTOM
45 Name: linking
46 Version: 2
47 SymbolTable:
48 - Index: 0
49 Kind: DATA
50 Name: hello_str
51 Flags: [ ]
52 Segment: 0
53 Size: 7
54 SegmentInfo:
55 - Index: 0
56 Name: .rodata.hello_str
57 Alignment: 0
58 Flags: [ ]
59...
60
61# SHARED-NO-MAX: maximum memory too small, 66560 bytes needed{{$}}
62
63# SHARED-UNALIGNED: maximum memory must be 65536-byte aligned{{$}}
64
65# SHARED: - Type: MEMORY
66# SHARED-NEXT: Memories:
67# SHARED-NEXT: - Flags: [ HAS_MAX, IS_SHARED ]
68# SHARED-NEXT: Initial: 0x00000002
69# SHARED-NEXT: Maximum: 0x00000002
70
71# ATOMICS-NO-SHARED: 'atomics' feature is used, so --shared-memory must be used{{$}}
72
73# ATOMICS-NO-MAX: maximum memory too small, 66560 bytes needed{{$}}
74
75# ATOMICS-UNALIGNED: maximum memory must be 65536-byte aligned{{$}}
deps/lld/test/wasm/shared-needed.ll created+38
......@@ -0,0 +1,38 @@
1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
3
4; RUN: wasm-ld -shared -o %t1.so %t.o
5; RUN: obj2yaml %t1.so | FileCheck %s -check-prefix=SO1
6
7; RUN: wasm-ld -shared -o %t2.so %t1.so %t.ret32.o
8; RUN: obj2yaml %t2.so | FileCheck %s -check-prefix=SO2
9
10target triple = "wasm32-unknown-unknown"
11
12@data = global i32 2, align 4
13
14define default void @foo() {
15entry:
16 ret void
17}
18
19; SO1: Sections:
20; SO1-NEXT: - Type: CUSTOM
21; SO1-NEXT: Name: dylink
22; SO1-NEXT: MemorySize: 4
23; SO1-NEXT: MemoryAlignment: 2
24; SO1-NEXT: TableSize: 0
25; SO1-NEXT: TableAlignment: 0
26; SO1-NEXT: Needed: []
27; SO1-NEXT: - Type: TYPE
28
29; SO2: Sections:
30; SO2-NEXT: - Type: CUSTOM
31; SO2-NEXT: Name: dylink
32; SO2-NEXT: MemorySize: 0
33; SO2-NEXT: MemoryAlignment: 0
34; SO2-NEXT: TableSize: 0
35; SO2-NEXT: TableAlignment: 0
36; SO2-NEXT: Needed:
37; SO2-NEXT: - shared-needed.ll.tmp1.so
38; SO2-NEXT: - Type: TYPE
deps/lld/test/wasm/shared.ll+87-14
......@@ -1,44 +1,74 @@
1; RUN: llc -O0 -filetype=obj %s -o %t.o
1; RUN: llc -relocation-model=pic -filetype=obj %s -o %t.o
22; RUN: wasm-ld -shared -o %t.wasm %t.o
33; RUN: obj2yaml %t.wasm | FileCheck %s
44
5target triple = "wasm32-unknown-unknown"
5target triple = "wasm32-unknown-emscripten"
66
77@data = hidden global i32 2, align 4
8@indirect_func = local_unnamed_addr global void ()* @foo, align 4
8@data_external = external global i32
9@indirect_func = local_unnamed_addr global i32 ()* @foo, align 4
910@indirect_func_external = local_unnamed_addr global void ()* @func_external, align 4
1011
11define default void @foo() {
12; Test data relocations
13@data_addr = local_unnamed_addr global i32* @data, align 4
14; .. against external symbols
15@data_addr_external = local_unnamed_addr global i32* @data_external, align 4
16; .. including addends
17%struct.s = type { i32, i32 }
18@extern_struct = external global %struct.s
19@extern_struct_internal_ptr = local_unnamed_addr global i32* getelementptr inbounds (%struct.s, %struct.s* @extern_struct, i32 0, i32 1), align 4
20
21define hidden i32 @foo() {
1222entry:
1323 ; To ensure we use __stack_pointer
1424 %ptr = alloca i32
1525 %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
26 %1 = load i32 ()*, i32 ()** @indirect_func, align 4
27 call i32 %1()
28 ret i32 %0
2029}
2130
22declare void @func_external()
31define hidden i32* @get_data_address() {
32entry:
33 ret i32* @data_external
34}
2335
24@data_external = external global i32
36define hidden i8* @get_func_address() {
37entry:
38 ret i8* bitcast (void ()* @func_external to i8*)
39}
2540
41define default i8* @get_local_func_address() {
42entry:
43 ; Verify that a function which is otherwise not address taken *is* added to
44 ; the wasm table with referenced via R_WASM_TABLE_INDEX_REL_SLEB
45 ret i8* bitcast (i8* ()* @get_func_address to i8*)
46}
47
48declare void @func_external()
2649
2750; check for dylink section at start
2851
2952; CHECK: Sections:
3053; CHECK-NEXT: - Type: CUSTOM
3154; CHECK-NEXT: Name: dylink
32; CHECK-NEXT: MemorySize: 8
55; CHECK-NEXT: MemorySize: 24
3356; CHECK-NEXT: MemoryAlignment: 2
3457; CHECK-NEXT: TableSize: 2
3558; CHECK-NEXT: TableAlignment: 0
59; CHECK-NEXT: Needed: []
60; CHECK-NEXT: - Type: TYPE
3661
3762; check for import of __table_base and __memory_base globals
3863
3964; CHECK: - Type: IMPORT
4065; CHECK-NEXT: Imports:
4166; CHECK-NEXT: - Module: env
67; CHECK-NEXT: Field: memory
68; CHECK-NEXT: Kind: MEMORY
69; CHECK-NEXT: Memory:
70; CHECK-NEXT: Initial: 0x0000000
71; CHECK-NEXT: - Module: env
4272; CHECK-NEXT: Field: __indirect_function_table
4373; CHECK-NEXT: Kind: TABLE
4474; CHECK-NEXT: Table:
......@@ -60,6 +90,37 @@ declare void @func_external()
6090; CHECK-NEXT: Kind: GLOBAL
6191; CHECK-NEXT: GlobalType: I32
6292; CHECK-NEXT: GlobalMutable: false
93; CHECK-NEXT: - Module: env
94; CHECK-NEXT: Field: func_external
95; CHECK-NEXT: Kind: FUNCTION
96; CHECK-NEXT: SigIndex: 1
97; CHECK-NEXT: - Module: GOT.mem
98; CHECK-NEXT: Field: indirect_func
99; CHECK-NEXT: Kind: GLOBAL
100; CHECK-NEXT: GlobalType: I32
101; CHECK-NEXT: GlobalMutable: true
102; CHECK-NEXT: - Module: GOT.func
103; CHECK-NEXT: Field: func_external
104; CHECK-NEXT: Kind: GLOBAL
105; CHECK-NEXT: GlobalType: I32
106; CHECK-NEXT: GlobalMutable: true
107; CHECK-NEXT: - Module: GOT.mem
108; CHECK-NEXT: Field: data_external
109; CHECK-NEXT: Kind: GLOBAL
110; CHECK-NEXT: GlobalType: I32
111; CHECK-NEXT: GlobalMutable: true
112; CHECK-NEXT: - Module: GOT.mem
113; CHECK-NEXT: Field: extern_struct
114; CHECK-NEXT: Kind: GLOBAL
115; CHECK-NEXT: GlobalType: I32
116; CHECK-NEXT: GlobalMutable: true
117; CHECK-NEXT: - Type: FUNCTION
118
119; CHECK: - Type: EXPORT
120; CHECK-NEXT: Exports:
121; CHECK-NEXT: - Name: __wasm_call_ctors
122; CHECK-NEXT: Kind: FUNCTION
123; CHECK-NEXT: Index: 1
63124
64125; check for elem segment initialized with __table_base global as offset
65126
......@@ -68,15 +129,27 @@ declare void @func_external()
68129; CHECK-NEXT: - Offset:
69130; CHECK-NEXT: Opcode: GLOBAL_GET
70131; CHECK-NEXT: Index: 2
71; CHECK-NEXT: Functions: [ 2, 0 ]
132; CHECK-NEXT: Functions: [ 4, 3 ]
133
134; check the generated code in __wasm_call_ctors and __wasm_apply_relocs functions
135; TODO(sbc): Disassemble and verify instructions.
136
137; CHECK: - Type: CODE
138; CHECK-NEXT: Functions:
139; CHECK-NEXT: - Index: 1
140; CHECK-NEXT: Locals: []
141; CHECK-NEXT: Body: 10020B
142; CHECK-NEXT: - Index: 2
143; CHECK-NEXT: Locals: []
144; CHECK-NEXT: Body: 230141046A230241016A360200230141086A23043602002301410C6A230141006A360200230141106A2305360200230141146A230641046A3602000B
72145
73146; check the data segment initialized with __memory_base global as offset
74147
75148; CHECK: - Type: DATA
76149; CHECK-NEXT: Segments:
77150; CHECK-NEXT: - SectionOffset: 6
78; CHECK-NEXT: MemoryIndex: 0
151; CHECK-NEXT: InitFlags: 0
79152; CHECK-NEXT: Offset:
80153; CHECK-NEXT: Opcode: GLOBAL_GET
81154; CHECK-NEXT: Index: 1
82; CHECK-NEXT: Content: '0000000001000000'
155; CHECK-NEXT: Content: '020000000100000000000000000000000000000000000000'
deps/lld/test/wasm/signature-mismatch-export.ll created+30
......@@ -0,0 +1,30 @@
1; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
2; RUN: llc -filetype=obj %s -o %t.main.o
3; RUN: wasm-ld --export=ret32 -o %t.wasm %t.main.o %t.ret32.o
4; RUN: obj2yaml %t.wasm | FileCheck %s
5
6target triple = "wasm32-unknown-unknown"
7
8declare i32 @ret32(i32)
9
10define void @_start() {
11entry:
12 %call1 = call i32 @ret32(i32 0)
13 ret void
14}
15
16; CHECK: - Type: EXPORT
17; CHECK: - Name: ret32
18; CHECK-NEXT: Kind: FUNCTION
19; CHECK-NEXT: Index: 2
20
21; CHECK: - Type: CUSTOM
22; CHECK-NEXT: Name: name
23; CHECK-NEXT: FunctionNames:
24; CHECK-NEXT: - Index: 0
25; CHECK-NEXT: Name: 'unreachable:ret32'
26; CHECK-NEXT: - Index: 1
27; CHECK-NEXT: Name: _start
28; CHECK-NEXT: - Index: 2
29; CHECK-NEXT: Name: ret32
30; CHECK-NEXT: ...
deps/lld/test/wasm/signature-mismatch-unknown.ll created+19
......@@ -0,0 +1,19 @@
1; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
2; RUN: llc -filetype=obj %s -o %t.main.o
3; RUN: wasm-ld --fatal-warnings -o %t.wasm %t.ret32.o %t.main.o
4; RUN: wasm-ld --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o
5
6target triple = "wasm32-unknown-unknown"
7
8; Function declartion with incorrect signature.
9declare dso_local void @ret32()
10
11; Simply taking the address of the function should *not* generate the
12; the signature mismatch warning.
13@ptr = dso_local global i8* bitcast (void ()* @ret32 to i8*), align 8
14
15define hidden void @_start() local_unnamed_addr {
16 %addr = load i32 ()*, i32 ()** bitcast (i8** @ptr to i32 ()**), align 8
17 call i32 %addr()
18 ret void
19}
deps/lld/test/wasm/signature-mismatch.ll+39-14
......@@ -1,26 +1,51 @@
11; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
2; RUN: llc -filetype=obj %p/Inputs/call-ret32.ll -o %t.call.o
23; RUN: llc -filetype=obj %s -o %t.main.o
3; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s
4; Run the test again by with the object files in the other order to verify
5; the check works when the undefined symbol is resolved by an existing defined
6; one.
7; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.ret32.o %t.main.o 2>&1 | FileCheck %s -check-prefix=REVERSE
4; RUN: wasm-ld --export=call_ret32 --export=ret32 -o %t.wasm %t.main.o %t.ret32.o %t.call.o 2>&1 | FileCheck %s -check-prefix=WARN
5; RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=YAML
6; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o %t.call.o 2>&1 | FileCheck %s -check-prefix=ERROR
87
98target triple = "wasm32-unknown-unknown"
109
10@ret32_address_main = global i32 (i32, i64, i32)* @ret32, align 4
11
1112; Function Attrs: nounwind
12define hidden void @_start() local_unnamed_addr #0 {
13define hidden void @_start() local_unnamed_addr {
1314entry:
14 %call = tail call i32 @ret32(i32 1, i64 2, i32 3) #2
15 %call1 = call i32 @ret32(i32 1, i64 2, i32 3)
16 %addr = load i32 (i32, i64, i32)*, i32 (i32, i64, i32)** @ret32_address_main, align 4
17 %call2 = call i32 %addr(i32 1, i64 2, i32 3)
1518 ret void
1619}
1720
18declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1
21declare i32 @ret32(i32, i64, i32) local_unnamed_addr
22
23; WARN: warning: function signature mismatch: ret32
24; WARN-NEXT: >>> defined as (i32, i64, i32) -> i32 in {{.*}}.main.o
25; WARN-NEXT: >>> defined as (f32) -> i32 in {{.*}}.ret32.o
26
27; ERROR: error: function signature mismatch: ret32
28; ERROR-NEXT: >>> defined as (i32, i64, i32) -> i32 in {{.*}}.main.o
29; ERROR-NEXT: >>> defined as (f32) -> i32 in {{.*}}.ret32.o
30
31; YAML: - Type: EXPORT
32; YAML: - Name: ret32
33; YAML-NEXT: Kind: FUNCTION
34; YAML-NEXT: Index: 2
35; YAML-NEXT: - Name: call_ret32
36; YAML-NEXT: Kind: FUNCTION
37; YAML-NEXT: Index: 3
1938
20; 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
39; YAML: - Type: CUSTOM
40; YAML-NEXT: Name: name
41; YAML-NEXT: FunctionNames:
42; YAML-NEXT: - Index: 0
43; YAML-NEXT: Name: 'unreachable:ret32'
44; YAML-NEXT: - Index: 1
45; YAML-NEXT: Name: _start
46; YAML-NEXT: - Index: 2
47; YAML-NEXT: Name: ret32
48; YAML-NEXT: - Index: 3
49; YAML-NEXT: Name: call_ret32
50; YAML-NEXT: ...
2351
24; 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
deps/lld/test/wasm/stack-first.test+6-5
......@@ -4,8 +4,7 @@
44; global should be initialized to 512.
55
66RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o
7
8RUN: wasm-ld -z stack-size=512 --stack-first --allow-undefined -o %t.wasm %t.o
7RUN: wasm-ld -z stack-size=512 --stack-first --export=__data_end --export=__heap_base -o %t.wasm %t.o
98RUN: obj2yaml %t.wasm | FileCheck %s
109
1110CHECK: - Type: GLOBAL
......@@ -33,10 +32,12 @@ CHECK-NEXT: Exports:
3332CHECK-NEXT: - Name: memory
3433CHECK-NEXT: Kind: MEMORY
3534CHECK-NEXT: Index: 0
36CHECK-NEXT: - Name: __heap_base
35CHECK-NEXT: - Name: __data_end
3736CHECK-NEXT: Kind: GLOBAL
3837CHECK-NEXT: Index: 1
39CHECK-NEXT: - Name: __data_end
38CHECK-NEXT: - Name: __heap_base
4039CHECK-NEXT: Kind: GLOBAL
4140CHECK-NEXT: Index: 2
42
41CHECK-NEXT: - Name: _start
42CHECK-NEXT: Kind: FUNCTION
43CHECK-NEXT: Index: 0
deps/lld/test/wasm/stack-pointer.ll+1-1
......@@ -41,7 +41,7 @@ entry:
4141; CHECK-NEXT: - Initial: 0x00000000
4242; CHECK-NEXT: - Type: CODE
4343; CHECK-NEXT: Relocations:
44; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
44; CHECK-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
4545; CHECK-NEXT: Index: 1
4646; CHECK-NEXT: Offset: 0x00000004
4747; CHECK-NEXT: Functions:
deps/lld/test/wasm/startstop.ll created+53
......@@ -0,0 +1,53 @@
1; RUN: llc -filetype=obj -o %t.o %s
2; RUN: llc -filetype=obj %p/Inputs/explicit-section.ll -o %t2.o
3; RUN: wasm-ld --export=get_start --export=get_end --export=foo --export=var1 %t.o %t2.o -o %t.wasm
4; RUN: obj2yaml %t.wasm | FileCheck %s
5
6target triple = "wasm32-unknown-unknown"
7
8@foo = global i32 3, section "mysection", align 4
9@bar = global i32 4, section "mysection", align 4
10
11@__start_mysection = external global i8*
12@__stop_mysection = external global i8*
13
14define i8** @get_start() {
15 ret i8** @__start_mysection
16}
17
18define i8** @get_end() {
19 ret i8** @__stop_mysection
20}
21
22define void @_start() {
23entry:
24 ret void
25}
26; CHECK: - Type: CODE
27; CHECK-NEXT: Functions:
28; CHECK-NEXT: - Index: 0
29; CHECK-NEXT: Locals: []
30; CHECK-NEXT: Body: 4180888080000B
31; CHECK-NEXT: - Index: 1
32; CHECK-NEXT: Locals: []
33; CHECK-NEXT: Body: 4190888080000B
34; CHECK-NEXT: - Index: 2
35; CHECK-NEXT: Locals: []
36; CHECK-NEXT: Body: 0B
37; CHECK-NEXT: - Type: DATA
38; CHECK-NEXT: Segments:
39; CHECK-NEXT: - SectionOffset: 7
40; CHECK-NEXT: InitFlags: 0
41; CHECK-NEXT: Offset:
42; CHECK-NEXT: Opcode: I32_CONST
43; CHECK-NEXT: Value: 1024
44; CHECK-NEXT: Content: 03000000040000002A0000002B000000
45; CHECK-NEXT: - Type: CUSTOM
46; CHECK-NEXT: Name: name
47; CHECK-NEXT: FunctionNames:
48; CHECK-NEXT: - Index: 0
49; CHECK-NEXT: Name: get_start
50; CHECK-NEXT: - Index: 1
51; CHECK-NEXT: Name: get_end
52; CHECK-NEXT: - Index: 2
53; CHECK-NEXT: Name: _start
deps/lld/test/wasm/target-feature-disallowed.yaml created+72
......@@ -0,0 +1,72 @@
1# RUN: yaml2obj %s -o %t1.o
2
3# RUN: wasm-ld --no-entry --features=foo,bar,baz -o %t.specified.wasm %t1.o
4# RUN: obj2yaml %t.specified.wasm | FileCheck %s --check-prefix SPECIFIED
5
6# RUN: wasm-ld --no-entry --features=bar,baz,quux -o %t.unspecified.wasm %t1.o
7# RUN: obj2yaml %t.unspecified.wasm | FileCheck %s --check-prefix UNSPECIFIED
8
9# RUN: yaml2obj %S/Inputs/disallow-feature-foo.yaml -o %t.disallowed.o
10# RUN: wasm-ld --no-entry -o - %t1.o %t.disallowed.o | obj2yaml | FileCheck %s --check-prefix DISALLOWED
11
12# RUN: yaml2obj %S/Inputs/no-feature-foo.yaml -o %t.none.o
13# RUN: wasm-ld --no-entry -o - %t1.o %t.none.o | obj2yaml | FileCheck %s --check-prefix NONE
14
15# Check that the following combinations of feature linkage policies
16# give the expected results:
17#
18# DISALLOWED x DISALLOWED => NONE
19# DISALLOWED x NONE => NONE
20
21--- !WASM
22FileHeader:
23 Version: 0x00000001
24Sections:
25 - Type: CUSTOM
26 Name: linking
27 Version: 2
28 - Type: CUSTOM
29 Name: target_features
30 Features:
31 - Prefix: DISALLOWED
32 Name: "foo"
33 # included so output has target features section
34 - Prefix: USED
35 Name: "bar"
36...
37
38# SPECIFIED: - Type: CUSTOM
39# SPECIFIED-NEXT: Name: target_features
40# SPECIFIED-NEXT: Features:
41# SPECIFIED-NEXT: - Prefix: USED
42# SPECIFIED-NEXT: Name: bar
43# SPECIFIED-NEXT: - Prefix: USED
44# SPECIFIED-NEXT: Name: baz
45# SPECIFIED-NEXT: - Prefix: USED
46# SPECIFIED-NEXT: Name: foo
47# SPECIFIED-NEXT: ...
48
49# UNSPECIFIED: - Type: CUSTOM
50# UNSPECIFIED-NEXT: Name: target_features
51# UNSPECIFIED-NEXT: Features:
52# UNSPECIFIED-NEXT: - Prefix: USED
53# UNSPECIFIED-NEXT: Name: bar
54# UNSPECIFIED-NEXT: - Prefix: USED
55# UNSPECIFIED-NEXT: Name: baz
56# UNSPECIFIED-NEXT: - Prefix: USED
57# UNSPECIFIED-NEXT: Name: quux
58# UNSPECIFIED-NEXT: ...
59
60# DISALLOWED: - Type: CUSTOM
61# DISALLOWED-NEXT: Name: target_features
62# DISALLOWED-NEXT: Features:
63# DISALLOWED-NEXT: - Prefix: USED
64# DISALLOWED-NEXT: Name: bar
65# DISALLOWED-NEXT: ...
66
67# NONE: - Type: CUSTOM
68# NONE-NEXT: Name: target_features
69# NONE-NEXT: Features:
70# NONE-NEXT: - Prefix: USED
71# NONE-NEXT: Name: bar
72# NONE-NEXT: ...
deps/lld/test/wasm/target-feature-none.yaml created+33
......@@ -0,0 +1,33 @@
1# RUN: yaml2obj %s -o %t1.o
2
3# RUN: wasm-ld --no-entry -o - %t1.o | obj2yaml | FileCheck %s --check-prefix EMPTY
4
5# RUN: wasm-ld --no-entry --features= -o - %t1.o | obj2yaml | FileCheck %s --check-prefix EMPTY
6
7# RUN: wasm-ld --no-entry --features=foo,bar,baz -o - %t1.o | obj2yaml | FileCheck %s --check-prefix SPECIFIED
8
9--- !WASM
10FileHeader:
11 Version: 0x00000001
12Sections:
13 - Type: CUSTOM
14 Name: linking
15 Version: 2
16 - Type: CUSTOM
17 Name: target_features
18 Features: [ ]
19...
20
21# section is not emitted if it would be empty
22# EMPTY-NOT: target_features
23
24# SPECIFIED: - Type: CUSTOM
25# SPECIFIED-NEXT: Name: target_features
26# SPECIFIED-NEXT: Features:
27# SPECIFIED-NEXT: - Prefix: USED
28# SPECIFIED-NEXT: Name: bar
29# SPECIFIED-NEXT: - Prefix: USED
30# SPECIFIED-NEXT: Name: baz
31# SPECIFIED-NEXT: - Prefix: USED
32# SPECIFIED-NEXT: Name: foo
33# SPECIFIED-NEXT: ...
deps/lld/test/wasm/target-feature-required.yaml created+90
......@@ -0,0 +1,90 @@
1# RUN: yaml2obj %s -o %t1.o
2
3# RUN: wasm-ld --no-entry --features=foo,bar,baz -o - %t1.o | obj2yaml | FileCheck %s --check-prefix SPECIFIED
4
5# RUN: not wasm-ld --no-entry --features=bar,baz,quux -o /dev/null %t1.o 2>&1 | FileCheck %s --check-prefix UNSPECIFIED
6
7# RUN: wasm-ld --no-entry --no-check-features --features=bar,baz,quux -o - %t1.o | obj2yaml | FileCheck %s --check-prefix UNSPECIFIED-NOCHECK
8
9# RUN: yaml2obj %S/Inputs/require-feature-foo.yaml -o %t.required.o
10# RUN: wasm-ld --no-entry -o - %t1.o %t.required.o | obj2yaml | FileCheck %s --check-prefix REQUIRED
11
12# RUN: yaml2obj %S/Inputs/disallow-feature-foo.yaml -o %t.disallowed.o
13# RUN: not wasm-ld --no-entry -o /dev/null %t1.o %t.disallowed.o 2>&1 | FileCheck %s --check-prefix DISALLOWED
14
15# RUN: wasm-ld --no-entry --no-check-features -o - %t1.o %t.disallowed.o | obj2yaml | FileCheck %s --check-prefix DISALLOWED-NOCHECK
16
17# RUN: yaml2obj %S/Inputs/no-feature-foo.yaml -o %t.none.o
18# RUN: not wasm-ld --no-entry -o /dev/null %t1.o %t.none.o 2>&1 | FileCheck %s --check-prefix NONE
19
20# RUN: wasm-ld --no-entry --no-check-features -o - %t1.o %t.none.o | obj2yaml | FileCheck %s --check-prefix NONE-NOCHECK
21
22# Check that the following combinations of feature linkage policies
23# give the expected results:
24#
25# REQUIRED x REQUIRED => USED
26# REQUIRED x DISALLOWED => Error
27# REQUIRED x NONE => Error
28
29--- !WASM
30FileHeader:
31 Version: 0x00000001
32Sections:
33 - Type: CUSTOM
34 Name: linking
35 Version: 2
36 - Type: CUSTOM
37 Name: target_features
38 Features:
39 - Prefix: REQUIRED
40 Name: "foo"
41...
42
43# SPECIFIED: - Type: CUSTOM
44# SPECIFIED-NEXT: Name: target_features
45# SPECIFIED-NEXT: Features:
46# SPECIFIED-NEXT: - Prefix: USED
47# SPECIFIED-NEXT: Name: bar
48# SPECIFIED-NEXT: - Prefix: USED
49# SPECIFIED-NEXT: Name: baz
50# SPECIFIED-NEXT: - Prefix: USED
51# SPECIFIED-NEXT: Name: foo
52# SPECIFIED-NEXT: ...
53
54# UNSPECIFIED: Target feature 'foo' used by {{.*}}target-feature-required.yaml.tmp1.o is not allowed.{{$}}
55
56# UNSPECIFIED-NOCHECK: - Type: CUSTOM
57# UNSPECIFIED-NOCHECK-NEXT: Name: target_features
58# UNSPECIFIED-NOCHECK-NEXT: Features:
59# UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED
60# UNSPECIFIED-NOCHECK-NEXT: Name: bar
61# UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED
62# UNSPECIFIED-NOCHECK-NEXT: Name: baz
63# UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED
64# UNSPECIFIED-NOCHECK-NEXT: Name: quux
65# UNSPECIFIED-NOCHECK-NEXT: ...
66
67# REQUIRED: - Type: CUSTOM
68# REQUIRED-NEXT: Name: target_features
69# REQUIRED-NEXT: Features:
70# REQUIRED-NEXT: - Prefix: USED
71# REQUIRED-NEXT: Name: foo
72# REQUIRED-NEXT: ...
73
74# DISALLOWED: Target feature 'foo' used in {{.*}}target-feature-required.yaml.tmp1.o is disallowed by {{.*}}target-feature-required.yaml.tmp.disallowed.o. Use --no-check-features to suppress.{{$}}
75
76# DISALLOWED-NOCHECK: - Type: CUSTOM
77# DISALLOWED-NOCHECK-NEXT: Name: target_features
78# DISALLOWED-NOCHECK-NEXT: Features:
79# DISALLOWED-NOCHECK-NEXT: - Prefix: USED
80# DISALLOWED-NOCHECK-NEXT: Name: foo
81# DISALLOWED-NOCHECK-NEXT: ...
82
83# NONE: Missing target feature 'foo' in {{.*}}target-feature-required.yaml.tmp.none.o, required by {{.*}}target-feature-required.yaml.tmp1.o. Use --no-check-features to suppress.{{$}}
84
85# NONE-NOCHECK: - Type: CUSTOM
86# NONE-NOCHECK-NEXT: Name: target_features
87# NONE-NOCHECK-NEXT: Features:
88# NONE-NOCHECK-NEXT: - Prefix: USED
89# NONE-NOCHECK-NEXT: Name: foo
90# NONE-NOCHECK-NEXT: ...
deps/lld/test/wasm/target-feature-used.yaml created+97
......@@ -0,0 +1,97 @@
1# RUN: yaml2obj %s -o %t1.o
2
3# RUN: wasm-ld --no-entry --features=foo,bar,baz -o - %t1.o | obj2yaml | FileCheck %s --check-prefix SPECIFIED
4
5# RUN: not wasm-ld --no-entry --features=bar,baz,quux -o /dev/null %t1.o 2>&1 | FileCheck %s --check-prefix UNSPECIFIED
6
7# RUN: wasm-ld --no-entry --no-check-features --features=bar,baz,quux -o - %t1.o | obj2yaml | FileCheck %s --check-prefix UNSPECIFIED-NOCHECK
8
9# RUN: yaml2obj %S/Inputs/use-feature-foo.yaml -o %t.used.o
10# RUN: wasm-ld --no-entry -o - %t1.o %t.used.o | obj2yaml | FileCheck %s --check-prefix USED
11
12# RUN: yaml2obj %S/Inputs/require-feature-foo.yaml -o %t.required.o
13# RUN: wasm-ld --no-entry -o - %t1.o %t.required.o | obj2yaml | FileCheck %s --check-prefix REQUIRED
14
15# RUN: yaml2obj %S/Inputs/disallow-feature-foo.yaml -o %t.disallowed.o
16# RUN: not wasm-ld --no-entry -o /dev/null %t1.o %t.disallowed.o 2>&1 | FileCheck %s --check-prefix DISALLOWED
17
18# RUN: wasm-ld --no-entry --no-check-features -o - %t1.o %t.disallowed.o | obj2yaml | FileCheck %s --check-prefix DISALLOWED-NOCHECK
19
20# RUN: yaml2obj %S/Inputs/no-feature-foo.yaml -o %t.none.o
21# RUN: wasm-ld --no-entry -o - %t1.o %t.none.o | obj2yaml | FileCheck %s --check-prefix NONE
22
23# Check that the following combinations of feature linkage policies
24# give the expected results:
25#
26# USED x USED => USED
27# USED x REQUIRED => USED
28# USED x DISALLOWED => Error
29# USED x NONE => USED
30
31--- !WASM
32FileHeader:
33 Version: 0x00000001
34Sections:
35 - Type: CUSTOM
36 Name: linking
37 Version: 2
38 - Type: CUSTOM
39 Name: target_features
40 Features:
41 - Prefix: USED
42 Name: "foo"
43...
44
45# SPECIFIED: - Type: CUSTOM
46# SPECIFIED-NEXT: Name: target_features
47# SPECIFIED-NEXT: Features:
48# SPECIFIED-NEXT: - Prefix: USED
49# SPECIFIED-NEXT: Name: bar
50# SPECIFIED-NEXT: - Prefix: USED
51# SPECIFIED-NEXT: Name: baz
52# SPECIFIED-NEXT: - Prefix: USED
53# SPECIFIED-NEXT: Name: foo
54# SPECIFIED-NEXT: ...
55
56# UNSPECIFIED: Target feature 'foo' used by {{.*}}target-feature-used.yaml.tmp1.o is not allowed.{{$}}
57
58# UNSPECIFIED-NOCHECK: - Type: CUSTOM
59# UNSPECIFIED-NOCHECK-NEXT: Name: target_features
60# UNSPECIFIED-NOCHECK-NEXT: Features:
61# UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED
62# UNSPECIFIED-NOCHECK-NEXT: Name: bar
63# UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED
64# UNSPECIFIED-NOCHECK-NEXT: Name: baz
65# UNSPECIFIED-NOCHECK-NEXT: - Prefix: USED
66# UNSPECIFIED-NOCHECK-NEXT: Name: quux
67# UNSPECIFIED-NOCHECK-NEXT: ...
68
69# USED: - Type: CUSTOM
70# USED-NEXT: Name: target_features
71# USED-NEXT: Features:
72# USED-NEXT: - Prefix: USED
73# USED-NEXT: Name: foo
74# USED-NEXT: ...
75
76# REQUIRED: - Type: CUSTOM
77# REQUIRED-NEXT: Name: target_features
78# REQUIRED-NEXT: Features:
79# REQUIRED-NEXT: - Prefix: USED
80# REQUIRED-NEXT: Name: foo
81# REQUIRED-NEXT: ...
82
83# DISALLOWED: Target feature 'foo' used in {{.*}}target-feature-used.yaml.tmp1.o is disallowed by {{.*}}target-feature-used.yaml.tmp.disallowed.o. Use --no-check-features to suppress.{{$}}
84
85# DISALLOWED-NOCHECK: - Type: CUSTOM
86# DISALLOWED-NOCHECK-NEXT: Name: target_features
87# DISALLOWED-NOCHECK-NEXT: Features:
88# DISALLOWED-NOCHECK-NEXT: - Prefix: USED
89# DISALLOWED-NOCHECK-NEXT: Name: foo
90# DISALLOWED-NOCHECK-NEXT: ...
91
92# NONE: - Type: CUSTOM
93# NONE-NEXT: Name: target_features
94# NONE-NEXT: Features:
95# NONE-NEXT: - Prefix: USED
96# NONE-NEXT: Name: foo
97# NONE-NEXT: ...
deps/lld/test/wasm/tls.ll created+79
......@@ -0,0 +1,79 @@
1; RUN: llc -mattr=+bulk-memory -filetype=obj %s -o %t.o
2
3target triple = "wasm32-unknown-unknown"
4
5@no_tls = global i32 0, align 4
6@tls1 = thread_local(localexec) global i32 1, align 4
7@tls2 = thread_local(localexec) global i32 1, align 4
8
9define i32* @tls1_addr() {
10 ret i32* @tls1
11}
12
13define i32* @tls2_addr() {
14 ret i32* @tls2
15}
16
17; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-entry -o %t.wasm %t.o
18; RUN: obj2yaml %t.wasm | FileCheck %s
19
20; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-merge-data-segments --no-entry -o %t.wasm %t.o
21; RUN: obj2yaml %t.wasm | FileCheck %s
22
23; CHECK: - Type: GLOBAL
24; CHECK-NEXT: Globals:
25; CHECK-NEXT: - Index: 0
26; CHECK-NEXT: Type: I32
27; CHECK-NEXT: Mutable: true
28; CHECK-NEXT: InitExpr:
29; CHECK-NEXT: Opcode: I32_CONST
30; CHECK-NEXT: Value: 66576
31; CHECK-NEXT: - Index: 1
32; CHECK-NEXT: Type: I32
33; CHECK-NEXT: Mutable: true
34; CHECK-NEXT: InitExpr:
35; CHECK-NEXT: Opcode: I32_CONST
36; CHECK-NEXT: Value: 0
37; CHECK-NEXT: - Index: 2
38; CHECK-NEXT: Type: I32
39; CHECK-NEXT: Mutable: false
40; CHECK-NEXT: InitExpr:
41; CHECK-NEXT: Opcode: I32_CONST
42; CHECK-NEXT: Value: 8
43
44
45; CHECK: - Type: CODE
46; CHECK-NEXT: Functions:
47; Skip __wasm_call_ctors and __wasm_init_memory
48; CHECK: - Index: 2
49; CHECK-NEXT: Locals: []
50; CHECK-NEXT: Body: 20002401200041004108FC0801000B
51
52; Expected body of __wasm_init_tls:
53; local.get 0
54; global.set 1
55; local.get 0
56; i32.const 0
57; i32.const 8
58; memory.init 1, 0
59; end
60
61; CHECK-NEXT: - Index: 3
62; CHECK-NEXT: Locals: []
63; CHECK-NEXT: Body: 2381808080004180808080006A0B
64
65; Expected body of tls1_addr:
66; global.get 1
67; i32.const 0
68; i32.add
69; end
70
71; CHECK-NEXT: - Index: 4
72; CHECK-NEXT: Locals: []
73; CHECK-NEXT: Body: 2381808080004184808080006A0B
74
75; Expected body of tls1_addr:
76; global.get 1
77; i32.const 4
78; i32.add
79; end
deps/lld/test/wasm/trace-symbol.ll created+28
......@@ -0,0 +1,28 @@
1; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
2; RUN: llc -filetype=obj -o %t.start.o %s
3; RUN: wasm-ld -o %t.wasm %t.start.o %t.ret32.o -y ret32 -y _start | FileCheck %s -check-prefix=BOTH
4; RUN: wasm-ld -o %t.wasm %t.ret32.o %t.start.o -y ret32 -y _start | FileCheck %s -check-prefix=REVERSED
5
6; check alias
7; RUN: wasm-ld -o %t.wasm %t.start.o %t.ret32.o -trace-symbol=_start | FileCheck %s -check-prefixes=JUST-START
8
9target triple = "wasm32-unknown-unknown"
10
11declare i32 @ret32(float %arg)
12
13define void @_start() {
14entry:
15 %call1 = call i32 @ret32(float 0.0)
16 ret void
17}
18
19; BOTH: start.o: definition of _start
20; BOTH-NEXT: start.o: reference to ret32
21; BOTH-NEXT: ret32.o: definition of ret32
22
23; REVERSED: ret32.o: definition of ret32
24; REVERSED-NEXT: start.o: definition of _start
25; REVERSED-NEXT: start.o: reference to ret32
26
27; JUST-START: start.o: definition of _start
28; JUST-START-NOT: ret32
deps/lld/test/wasm/trace.test created+8
......@@ -0,0 +1,8 @@
1RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.foo.o
2
3# Check -t
4RUN: wasm-ld %t.foo.o -o %t.t.out.wasm -t 2>&1 | FileCheck %s
5CHECK: {{.*}}.foo.o
6
7# Check --trace alias
8RUN: wasm-ld %t.foo.o -o %t.trace.out.wasm --trace 2>&1 | FileCheck %s
deps/lld/test/wasm/undefined-data.ll created+17
......@@ -0,0 +1,17 @@
1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: not wasm-ld -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=UNDEF
3; RUN: not wasm-ld --allow-undefined -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=UNDEF
4; RUN: not wasm-ld --shared -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=SHARED
5
6target triple = "wasm32-unknown-unknown"
7
8@data_external = external global i32
9
10define i32 @_start() {
11entry:
12 %0 = load i32, i32* @data_external, align 4
13 ret i32 %0
14}
15
16; UNDEF: error: {{.*}}undefined-data.ll.tmp.o: undefined symbol: data_external
17; SHARED: error: {{.*}}undefined-data.ll.tmp.o: relocation R_WASM_MEMORY_ADDR_LEB cannot be used against symbol data_external; recompile with -fPIC
deps/lld/test/wasm/undefined-weak-call.ll+7-30
......@@ -42,7 +42,7 @@ define i32 @callWeakFuncs() {
4242; CHECK-NEXT: ReturnType: I32
4343; CHECK-NEXT: ParamTypes:
4444; CHECK-NEXT: - Type: FUNCTION
45; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 1, 2 ]
45; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 2 ]
4646; CHECK-NEXT: - Type: TABLE
4747; CHECK-NEXT: Tables:
4848; CHECK-NEXT: - ElemType: FUNCREF
......@@ -61,37 +61,19 @@ define i32 @callWeakFuncs() {
6161; CHECK-NEXT: InitExpr:
6262; CHECK-NEXT: Opcode: I32_CONST
6363; CHECK-NEXT: Value: 66560
64; CHECK-NEXT: - Index: 1
65; CHECK-NEXT: Type: I32
66; CHECK-NEXT: Mutable: false
67; CHECK-NEXT: InitExpr:
68; CHECK-NEXT: Opcode: I32_CONST
69; CHECK-NEXT: Value: 66560
70; CHECK-NEXT: - Index: 2
71; CHECK-NEXT: Type: I32
72; CHECK-NEXT: Mutable: false
73; CHECK-NEXT: InitExpr:
74; CHECK-NEXT: Opcode: I32_CONST
75; CHECK-NEXT: Value: 1024
7664; CHECK-NEXT: - Type: EXPORT
7765; CHECK-NEXT: Exports:
7866; CHECK-NEXT: - Name: memory
7967; CHECK-NEXT: Kind: MEMORY
8068; CHECK-NEXT: Index: 0
81; CHECK-NEXT: - Name: __heap_base
82; CHECK-NEXT: Kind: GLOBAL
83; CHECK-NEXT: Index: 1
84; CHECK-NEXT: - Name: __data_end
85; CHECK-NEXT: Kind: GLOBAL
86; CHECK-NEXT: Index: 2
8769; CHECK-NEXT: - Name: callWeakFuncs
8870; CHECK-NEXT: Kind: FUNCTION
89; CHECK-NEXT: Index: 4
71; CHECK-NEXT: Index: 3
9072; CHECK-NEXT: - Type: CODE
9173; CHECK-NEXT: Functions:
9274; CHECK-NEXT: - Index: 0
9375; CHECK-NEXT: Locals:
94; CHECK-NEXT: Body: 0B
76; CHECK-NEXT: Body: 000B
9577; CHECK-NEXT: - Index: 1
9678; CHECK-NEXT: Locals:
9779; CHECK-NEXT: Body: 000B
......@@ -100,21 +82,16 @@ define i32 @callWeakFuncs() {
10082; CHECK-NEXT: Body: 000B
10183; CHECK-NEXT: - Index: 3
10284; CHECK-NEXT: Locals:
103; CHECK-NEXT: Body: 000B
104; CHECK-NEXT: - Index: 4
105; CHECK-NEXT: Locals:
106; CHECK-NEXT: Body: 10818080800010828080800041021083808080004180808080004180808080006A0B
85; CHECK-NEXT: Body: 10808080800010818080800041021082808080004180808080004180808080006A0B
10786; CHECK-NEXT: - Type: CUSTOM
10887; CHECK-NEXT: Name: name
10988; CHECK-NEXT: FunctionNames:
11089; CHECK-NEXT: - Index: 0
111; CHECK-NEXT: Name: __wasm_call_ctors
90; CHECK-NEXT: Name: 'undefined:weakFunc1'
11291; CHECK-NEXT: - Index: 1
113; CHECK-NEXT: Name: undefined function weakFunc1
92; CHECK-NEXT: Name: 'undefined:weakFunc2'
11493; CHECK-NEXT: - Index: 2
115; CHECK-NEXT: Name: undefined function weakFunc2
94; CHECK-NEXT: Name: 'undefined:weakFunc3'
11695; CHECK-NEXT: - Index: 3
117; CHECK-NEXT: Name: undefined function weakFunc3
118; CHECK-NEXT: - Index: 4
11996; CHECK-NEXT: Name: callWeakFuncs
12097; CHECK-NEXT: ...
deps/lld/test/wasm/undefined.ll+3-2
......@@ -1,7 +1,7 @@
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'
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
77; CHECK-NOT: undefined symbol: baz
......@@ -16,7 +16,8 @@
1616target triple = "wasm32-unknown-unknown"
1717
1818; Takes the address of the external foo() resulting in undefined external
19@bar = hidden local_unnamed_addr global i8* bitcast (i32 ()* @foo to i8*), align 4
19@bar = global i8* bitcast (i32 ()* @foo to i8*), align 4
20@llvm.used = appending global [1 x i8**] [i8** @bar], section "llvm.metadata"
2021
2122declare i32 @foo() #0
2223
deps/lld/test/wasm/version.ll+1-1
......@@ -1,6 +1,6 @@
11; RUN: llc -filetype=obj %s -o %t.o
22; RUN: wasm-ld -o %t.wasm %t.o
3; RUN: llvm-readobj -file-headers %t.wasm | FileCheck %s
3; RUN: llvm-readobj --file-headers %t.wasm | FileCheck %s
44
55target triple = "wasm32-unknown-unknown"
66
deps/lld/test/wasm/visibility-hidden.ll+4-16
......@@ -43,21 +43,15 @@ entry:
4343; CHECK-NEXT: - Name: memory
4444; CHECK-NEXT: Kind: MEMORY
4545; CHECK-NEXT: Index: 0
46; CHECK-NEXT: - Name: __heap_base
47; CHECK-NEXT: Kind: GLOBAL
48; CHECK-NEXT: Index: 1
49; CHECK-NEXT: - Name: __data_end
50; CHECK-NEXT: Kind: GLOBAL
51; CHECK-NEXT: Index: 2
5246; CHECK-NEXT: - Name: objectDefault
5347; CHECK-NEXT: Kind: FUNCTION
54; CHECK-NEXT: Index: 2
48; CHECK-NEXT: Index: 1
5549; CHECK-NEXT: - Name: _start
5650; CHECK-NEXT: Kind: FUNCTION
57; CHECK-NEXT: Index: 3
51; CHECK-NEXT: Index: 2
5852; CHECK-NEXT: - Name: archiveDefault
5953; CHECK-NEXT: Kind: FUNCTION
60; CHECK-NEXT: Index: 5
54; CHECK-NEXT: Index: 4
6155; CHECK-NEXT: - Type:
6256
6357
......@@ -66,13 +60,7 @@ entry:
6660; NO-DEFAULT-NEXT: - Name: memory
6761; NO-DEFAULT-NEXT: Kind: MEMORY
6862; 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
7563; NO-DEFAULT-NEXT: - Name: _start
7664; NO-DEFAULT-NEXT: Kind: FUNCTION
77; NO-DEFAULT-NEXT: Index: 3
65; NO-DEFAULT-NEXT: Index: 2
7866; NO-DEFAULT-NEXT: - Type:
deps/lld/test/wasm/weak-alias-overide.ll+25-48
......@@ -26,13 +26,13 @@ entry:
2626; CHECK-NEXT: - Type: TYPE
2727; CHECK-NEXT: Signatures:
2828; CHECK-NEXT: - Index: 0
29; CHECK-NEXT: ReturnType: NORESULT
29; CHECK-NEXT: ReturnType: I32
3030; CHECK-NEXT: ParamTypes:
3131; CHECK-NEXT: - Index: 1
32; CHECK-NEXT: ReturnType: I32
32; CHECK-NEXT: ReturnType: NORESULT
3333; CHECK-NEXT: ParamTypes:
3434; CHECK-NEXT: - Type: FUNCTION
35; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1, 1, 1, 1, 1 ]
35; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0, 0, 0, 0 ]
3636; CHECK-NEXT: - Type: TABLE
3737; CHECK-NEXT: Tables:
3838; CHECK-NEXT: - ElemType: FUNCREF
......@@ -51,103 +51,80 @@ entry:
5151; CHECK-NEXT: InitExpr:
5252; CHECK-NEXT: Opcode: I32_CONST
5353; CHECK-NEXT: Value: 66560
54; CHECK-NEXT: - Index: 1
55; CHECK-NEXT: Type: I32
56; CHECK-NEXT: Mutable: false
57; CHECK-NEXT: InitExpr:
58; CHECK-NEXT: Opcode: I32_CONST
59; CHECK-NEXT: Value: 66560
60; CHECK-NEXT: - Index: 2
61; CHECK-NEXT: Type: I32
62; CHECK-NEXT: Mutable: false
63; CHECK-NEXT: InitExpr:
64; CHECK-NEXT: Opcode: I32_CONST
65; CHECK-NEXT: Value: 1024
6654; CHECK-NEXT: - Type: EXPORT
6755; CHECK-NEXT: Exports:
6856; CHECK-NEXT: - Name: memory
6957; CHECK-NEXT: Kind: MEMORY
7058; CHECK-NEXT: Index: 0
71; CHECK-NEXT: - Name: __heap_base
72; CHECK-NEXT: Kind: GLOBAL
73; CHECK-NEXT: Index: 1
74; CHECK-NEXT: - Name: __data_end
75; CHECK-NEXT: Kind: GLOBAL
76; CHECK-NEXT: Index: 2
7759; CHECK-NEXT: - Name: alias_fn
7860; CHECK-NEXT: Kind: FUNCTION
79; CHECK-NEXT: Index: 1
61; CHECK-NEXT: Index: 0
8062; CHECK-NEXT: - Name: _start
8163; CHECK-NEXT: Kind: FUNCTION
82; CHECK-NEXT: Index: 2
64; CHECK-NEXT: Index: 1
8365; CHECK-NEXT: - Name: direct_fn
8466; CHECK-NEXT: Kind: FUNCTION
85; CHECK-NEXT: Index: 3
67; CHECK-NEXT: Index: 2
8668; CHECK-NEXT: - Name: call_direct
8769; CHECK-NEXT: Kind: FUNCTION
88; CHECK-NEXT: Index: 4
70; CHECK-NEXT: Index: 3
8971; CHECK-NEXT: - Name: call_alias
9072; CHECK-NEXT: Kind: FUNCTION
91; CHECK-NEXT: Index: 5
73; CHECK-NEXT: Index: 4
9274; CHECK-NEXT: - Name: call_alias_ptr
9375; CHECK-NEXT: Kind: FUNCTION
94; CHECK-NEXT: Index: 6
76; CHECK-NEXT: Index: 5
9577; CHECK-NEXT: - Name: call_direct_ptr
9678; CHECK-NEXT: Kind: FUNCTION
97; CHECK-NEXT: Index: 7
79; CHECK-NEXT: Index: 6
9880; CHECK-NEXT: - Type: ELEM
9981; CHECK-NEXT: Segments:
10082; CHECK-NEXT: - Offset:
10183; CHECK-NEXT: Opcode: I32_CONST
10284; CHECK-NEXT: Value: 1
103; CHECK-NEXT: Functions: [ 1, 3 ]
85; CHECK-NEXT: Functions: [ 0, 2 ]
10486; CHECK-NEXT: - Type: CODE
10587; CHECK-NEXT: Functions:
10688; CHECK-NEXT: - Index: 0
10789; CHECK-NEXT: Locals:
108; CHECK-NEXT: Body: 0B
90; CHECK-NEXT: Body: 41010B
10991; CHECK-NEXT: - Index: 1
11092; CHECK-NEXT: Locals:
111; CHECK-NEXT: Body: 41010B
93; CHECK-NEXT: Body: 1080808080001A0B
11294; CHECK-NEXT: - Index: 2
11395; CHECK-NEXT: Locals:
114; CHECK-NEXT: Body: 1081808080001A0B
96; CHECK-NEXT: Body: 41000B
11597; CHECK-NEXT: - Index: 3
11698; CHECK-NEXT: Locals:
117; CHECK-NEXT: Body: 41000B
99; CHECK-NEXT: Body: 1082808080000B
118100; CHECK-NEXT: - Index: 4
119101; CHECK-NEXT: Locals:
120; CHECK-NEXT: Body: 1083808080000B
102; CHECK-NEXT: Body: 1080808080000B
121103; CHECK-NEXT: - Index: 5
122104; CHECK-NEXT: Locals:
123; CHECK-NEXT: Body: 1081808080000B
124; CHECK-NEXT: - Index: 6
125; CHECK-NEXT: Locals:
126105; CHECK-NEXT: - Type: I32
127106; CHECK-NEXT: Count: 2
128; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
129; CHECK-NEXT: - Index: 7
107; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081080808080002101200041106A24808080800020010B
108; CHECK-NEXT: - Index: 6
130109; CHECK-NEXT: Locals:
131110; CHECK-NEXT: - Type: I32
132111; CHECK-NEXT: Count: 2
133; CHECK-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081083808080002101200041106A24808080800020010B
112; CHECK-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081082808080002101200041106A24808080800020010B
134113; CHECK-NEXT: - Type: CUSTOM
135114; CHECK-NEXT: Name: name
136115; CHECK-NEXT: FunctionNames:
137116; CHECK-NEXT: - Index: 0
138; CHECK-NEXT: Name: __wasm_call_ctors
139; CHECK-NEXT: - Index: 1
140117; CHECK-NEXT: Name: alias_fn
141; CHECK-NEXT: - Index: 2
118; CHECK-NEXT: - Index: 1
142119; CHECK-NEXT: Name: _start
143; CHECK-NEXT: - Index: 3
120; CHECK-NEXT: - Index: 2
144121; CHECK-NEXT: Name: direct_fn
145; CHECK-NEXT: - Index: 4
122; CHECK-NEXT: - Index: 3
146123; CHECK-NEXT: Name: call_direct
147; CHECK-NEXT: - Index: 5
124; CHECK-NEXT: - Index: 4
148125; CHECK-NEXT: Name: call_alias
149; CHECK-NEXT: - Index: 6
126; CHECK-NEXT: - Index: 5
150127; CHECK-NEXT: Name: call_alias_ptr
151; CHECK-NEXT: - Index: 7
128; CHECK-NEXT: - Index: 6
152129; CHECK-NEXT: Name: call_direct_ptr
153130; CHECK-NEXT: ...
deps/lld/test/wasm/weak-alias.ll+34-57
......@@ -29,7 +29,7 @@ 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, 1 ]
32; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1, 1 ]
3333; CHECK-NEXT: - Type: TABLE
3434; CHECK-NEXT: Tables:
3535; CHECK-NEXT: - ElemType: FUNCREF
......@@ -48,99 +48,76 @@ entry:
4848; CHECK-NEXT: InitExpr:
4949; CHECK-NEXT: Opcode: I32_CONST
5050; CHECK-NEXT: Value: 66560
51; CHECK-NEXT: - Index: 1
52; CHECK-NEXT: Type: I32
53; CHECK-NEXT: Mutable: false
54; CHECK-NEXT: InitExpr:
55; CHECK-NEXT: Opcode: I32_CONST
56; CHECK-NEXT: Value: 66560
57; CHECK-NEXT: - Index: 2
58; CHECK-NEXT: Type: I32
59; CHECK-NEXT: Mutable: false
60; CHECK-NEXT: InitExpr:
61; CHECK-NEXT: Opcode: I32_CONST
62; CHECK-NEXT: Value: 1024
6351; CHECK-NEXT: - Type: EXPORT
6452; CHECK-NEXT: Exports:
6553; CHECK-NEXT: - Name: memory
6654; CHECK-NEXT: Kind: MEMORY
6755; CHECK-NEXT: Index: 0
68; CHECK-NEXT: - Name: __heap_base
69; CHECK-NEXT: Kind: GLOBAL
70; CHECK-NEXT: Index: 1
71; CHECK-NEXT: - Name: __data_end
72; CHECK-NEXT: Kind: GLOBAL
73; CHECK-NEXT: Index: 2
7456; CHECK-NEXT: - Name: _start
7557; CHECK-NEXT: Kind: FUNCTION
76; CHECK-NEXT: Index: 1
58; CHECK-NEXT: Index: 0
7759; CHECK-NEXT: - Name: alias_fn
7860; CHECK-NEXT: Kind: FUNCTION
79; CHECK-NEXT: Index: 2
61; CHECK-NEXT: Index: 1
8062; CHECK-NEXT: - Name: direct_fn
8163; CHECK-NEXT: Kind: FUNCTION
82; CHECK-NEXT: Index: 2
64; CHECK-NEXT: Index: 1
8365; CHECK-NEXT: - Name: call_direct
8466; CHECK-NEXT: Kind: FUNCTION
85; CHECK-NEXT: Index: 3
67; CHECK-NEXT: Index: 2
8668; CHECK-NEXT: - Name: call_alias
8769; CHECK-NEXT: Kind: FUNCTION
88; CHECK-NEXT: Index: 4
70; CHECK-NEXT: Index: 3
8971; CHECK-NEXT: - Name: call_alias_ptr
9072; CHECK-NEXT: Kind: FUNCTION
91; CHECK-NEXT: Index: 5
73; CHECK-NEXT: Index: 4
9274; CHECK-NEXT: - Name: call_direct_ptr
9375; CHECK-NEXT: Kind: FUNCTION
94; CHECK-NEXT: Index: 6
76; CHECK-NEXT: Index: 5
9577; CHECK-NEXT: - Type: ELEM
9678; CHECK-NEXT: Segments:
9779; CHECK-NEXT: - Offset:
9880; CHECK-NEXT: Opcode: I32_CONST
9981; CHECK-NEXT: Value: 1
100; CHECK-NEXT: Functions: [ 2 ]
82; CHECK-NEXT: Functions: [ 1 ]
10183; CHECK-NEXT: - Type: CODE
10284; CHECK-NEXT: Functions:
10385; CHECK-NEXT: - Index: 0
10486; CHECK-NEXT: Locals:
105; CHECK-NEXT: Body: 0B
87; CHECK-NEXT: Body: 1081808080001A0B
10688; CHECK-NEXT: - Index: 1
10789; CHECK-NEXT: Locals:
108; CHECK-NEXT: Body: 1082808080001A0B
90; CHECK-NEXT: Body: 41000B
10991; CHECK-NEXT: - Index: 2
11092; CHECK-NEXT: Locals:
111; CHECK-NEXT: Body: 41000B
93; CHECK-NEXT: Body: 1081808080000B
11294; CHECK-NEXT: - Index: 3
11395; CHECK-NEXT: Locals:
114; CHECK-NEXT: Body: 1082808080000B
96; CHECK-NEXT: Body: 1081808080000B
11597; CHECK-NEXT: - Index: 4
11698; CHECK-NEXT: Locals:
117; CHECK-NEXT: Body: 1082808080000B
118; CHECK-NEXT: - Index: 5
119; CHECK-NEXT: Locals:
12099; CHECK-NEXT: - Type: I32
121100; CHECK-NEXT: Count: 2
122; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081082808080002101200041106A24808080800020010B
123; CHECK-NEXT: - Index: 6
101; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
102; CHECK-NEXT: - Index: 5
124103; CHECK-NEXT: Locals:
125104; CHECK-NEXT: - Type: I32
126105; CHECK-NEXT: Count: 2
127; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081082808080002101200041106A24808080800020010B
106; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
128107; CHECK-NEXT: - Type: CUSTOM
129108; CHECK-NEXT: Name: name
130109; CHECK-NEXT: FunctionNames:
131110; CHECK-NEXT: - Index: 0
132; CHECK-NEXT: Name: __wasm_call_ctors
133; CHECK-NEXT: - Index: 1
134111; CHECK-NEXT: Name: _start
135; CHECK-NEXT: - Index: 2
112; CHECK-NEXT: - Index: 1
136113; CHECK-NEXT: Name: direct_fn
137; CHECK-NEXT: - Index: 3
114; CHECK-NEXT: - Index: 2
138115; CHECK-NEXT: Name: call_direct
139; CHECK-NEXT: - Index: 4
116; CHECK-NEXT: - Index: 3
140117; CHECK-NEXT: Name: call_alias
141; CHECK-NEXT: - Index: 5
118; CHECK-NEXT: - Index: 4
142119; CHECK-NEXT: Name: call_alias_ptr
143; CHECK-NEXT: - Index: 6
120; CHECK-NEXT: - Index: 5
144121; CHECK-NEXT: Name: call_direct_ptr
145122; CHECK-NEXT: ...
146123
......@@ -186,43 +163,43 @@ entry:
186163; RELOC-NEXT: Functions: [ 1 ]
187164; RELOC-NEXT: - Type: CODE
188165; RELOC-NEXT: Relocations:
189; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
166; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
190167; RELOC-NEXT: Index: 1
191168; RELOC-NEXT: Offset: 0x00000004
192; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
169; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
193170; RELOC-NEXT: Index: 2
194171; RELOC-NEXT: Offset: 0x00000013
195; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
172; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
196173; RELOC-NEXT: Index: 1
197174; RELOC-NEXT: Offset: 0x0000001C
198; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
175; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
199176; RELOC-NEXT: Index: 6
200177; RELOC-NEXT: Offset: 0x00000027
201; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
178; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
202179; RELOC-NEXT: Index: 6
203180; RELOC-NEXT: Offset: 0x00000032
204; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
181; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
205182; RELOC-NEXT: Index: 1
206183; RELOC-NEXT: Offset: 0x0000003A
207; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
184; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
208185; RELOC-NEXT: Index: 1
209186; RELOC-NEXT: Offset: 0x00000043
210; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
187; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
211188; RELOC-NEXT: Index: 6
212189; RELOC-NEXT: Offset: 0x00000050
213; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
190; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
214191; RELOC-NEXT: Index: 6
215192; RELOC-NEXT: Offset: 0x0000005D
216; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
193; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
217194; RELOC-NEXT: Index: 6
218195; RELOC-NEXT: Offset: 0x00000068
219; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
196; RELOC-NEXT: - Type: R_WASM_TABLE_INDEX_SLEB
220197; RELOC-NEXT: Index: 2
221198; RELOC-NEXT: Offset: 0x00000070
222; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
199; RELOC-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
223200; RELOC-NEXT: Index: 2
224201; RELOC-NEXT: Offset: 0x00000079
225; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
202; RELOC-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
226203; RELOC-NEXT: Index: 6
227204; RELOC-NEXT: Offset: 0x00000086
228205; RELOC-NEXT: Functions:
deps/lld/test/wasm/weak-symbols.ll+14-37
......@@ -29,7 +29,7 @@ entry:
2929; CHECK-NEXT: ReturnType: I32
3030; CHECK-NEXT: ParamTypes:
3131; CHECK-NEXT: - Type: FUNCTION
32; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1 ]
32; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 1 ]
3333; CHECK-NEXT: - Type: TABLE
3434; CHECK-NEXT: Tables:
3535; CHECK-NEXT: - ElemType: FUNCREF
......@@ -53,72 +53,51 @@ entry:
5353; CHECK-NEXT: Mutable: false
5454; CHECK-NEXT: InitExpr:
5555; CHECK-NEXT: Opcode: I32_CONST
56; CHECK-NEXT: Value: 66576
57; CHECK-NEXT: - Index: 2
58; CHECK-NEXT: Type: I32
59; CHECK-NEXT: Mutable: false
60; CHECK-NEXT: InitExpr:
61; CHECK-NEXT: Opcode: I32_CONST
62; CHECK-NEXT: Value: 1028
63; CHECK-NEXT: - Index: 3
64; CHECK-NEXT: Type: I32
65; CHECK-NEXT: Mutable: false
66; CHECK-NEXT: InitExpr:
67; CHECK-NEXT: Opcode: I32_CONST
6856; CHECK-NEXT: Value: 1024
6957; CHECK-NEXT: - Type: EXPORT
7058; CHECK-NEXT: Exports:
7159; CHECK-NEXT: - Name: memory
7260; CHECK-NEXT: Kind: MEMORY
7361; CHECK-NEXT: Index: 0
74; CHECK-NEXT: - Name: __heap_base
75; CHECK-NEXT: Kind: GLOBAL
76; CHECK-NEXT: Index: 1
77; CHECK-NEXT: - Name: __data_end
78; CHECK-NEXT: Kind: GLOBAL
79; CHECK-NEXT: Index: 2
8062; CHECK-NEXT: - Name: _start
8163; CHECK-NEXT: Kind: FUNCTION
82; CHECK-NEXT: Index: 1
64; CHECK-NEXT: Index: 0
8365; CHECK-NEXT: - Name: weakFn
8466; CHECK-NEXT: Kind: FUNCTION
85; CHECK-NEXT: Index: 2
67; CHECK-NEXT: Index: 1
8668; CHECK-NEXT: - Name: exportWeak1
8769; CHECK-NEXT: Kind: FUNCTION
88; CHECK-NEXT: Index: 3
70; CHECK-NEXT: Index: 2
8971; CHECK-NEXT: - Name: weakGlobal
9072; CHECK-NEXT: Kind: GLOBAL
91; CHECK-NEXT: Index: 3
73; CHECK-NEXT: Index: 1
9274; CHECK-NEXT: - Name: exportWeak2
9375; CHECK-NEXT: Kind: FUNCTION
94; CHECK-NEXT: Index: 4
76; CHECK-NEXT: Index: 3
9577; CHECK-NEXT: - Type: ELEM
9678; CHECK-NEXT: Segments:
9779; CHECK-NEXT: - Offset:
9880; CHECK-NEXT: Opcode: I32_CONST
9981; CHECK-NEXT: Value: 1
100; CHECK-NEXT: Functions: [ 2 ]
82; CHECK-NEXT: Functions: [ 1 ]
10183; CHECK-NEXT: - Type: CODE
10284; CHECK-NEXT: Functions:
10385; CHECK-NEXT: - Index: 0
10486; CHECK-NEXT: Locals:
105; CHECK-NEXT: Body: 0B
87; CHECK-NEXT: Body: 1081808080001A0B
10688; CHECK-NEXT: - Index: 1
10789; CHECK-NEXT: Locals:
108; CHECK-NEXT: Body: 1082808080001A0B
109; CHECK-NEXT: - Index: 2
110; CHECK-NEXT: Locals:
11190; CHECK-NEXT: Body: 41010B
112; CHECK-NEXT: - Index: 3
91; CHECK-NEXT: - Index: 2
11392; CHECK-NEXT: Locals:
11493; CHECK-NEXT: Body: 4181808080000B
115; CHECK-NEXT: - Index: 4
94; CHECK-NEXT: - Index: 3
11695; CHECK-NEXT: Locals:
11796; CHECK-NEXT: Body: 4181808080000B
11897; CHECK-NEXT: - Type: DATA
11998; CHECK-NEXT: Segments:
12099; CHECK-NEXT: - SectionOffset: 7
121; CHECK-NEXT: MemoryIndex: 0
100; CHECK-NEXT: InitFlags: 0
122101; CHECK-NEXT: Offset:
123102; CHECK-NEXT: Opcode: I32_CONST
124103; CHECK-NEXT: Value: 1024
......@@ -127,13 +106,11 @@ entry:
127106; CHECK-NEXT: Name: name
128107; CHECK-NEXT: FunctionNames:
129108; CHECK-NEXT: - Index: 0
130; CHECK-NEXT: Name: __wasm_call_ctors
131; CHECK-NEXT: - Index: 1
132109; CHECK-NEXT: Name: _start
133; CHECK-NEXT: - Index: 2
110; CHECK-NEXT: - Index: 1
134111; CHECK-NEXT: Name: weakFn
135; CHECK-NEXT: - Index: 3
112; CHECK-NEXT: - Index: 2
136113; CHECK-NEXT: Name: exportWeak1
137; CHECK-NEXT: - Index: 4
114; CHECK-NEXT: - Index: 3
138115; CHECK-NEXT: Name: exportWeak2
139116; CHECK-NEXT: ...
deps/lld/test/wasm/weak-undefined.ll+6-27
......@@ -34,13 +34,13 @@ entry:
3434; CHECK-NEXT: - Type: TYPE
3535; CHECK-NEXT: Signatures:
3636; CHECK-NEXT: - Index: 0
37; CHECK-NEXT: ReturnType: NORESULT
37; CHECK-NEXT: ReturnType: I32
3838; CHECK-NEXT: ParamTypes:
3939; CHECK-NEXT: - Index: 1
40; CHECK-NEXT: ReturnType: I32
40; CHECK-NEXT: ReturnType: NORESULT
4141; CHECK-NEXT: ParamTypes:
4242; CHECK-NEXT: - Type: FUNCTION
43; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 0 ]
43; CHECK-NEXT: FunctionTypes: [ 0, 0, 1 ]
4444; CHECK-NEXT: - Type: TABLE
4545; CHECK-NEXT: Tables:
4646; CHECK-NEXT: - ElemType: FUNCREF
......@@ -59,44 +59,23 @@ entry:
5959; CHECK-NEXT: InitExpr:
6060; CHECK-NEXT: Opcode: I32_CONST
6161; CHECK-NEXT: Value: 66560
62; CHECK-NEXT: - Index: 1
63; CHECK-NEXT: Type: I32
64; CHECK-NEXT: Mutable: false
65; CHECK-NEXT: InitExpr:
66; CHECK-NEXT: Opcode: I32_CONST
67; CHECK-NEXT: Value: 66560
68; CHECK-NEXT: - Index: 2
69; CHECK-NEXT: Type: I32
70; CHECK-NEXT: Mutable: false
71; CHECK-NEXT: InitExpr:
72; CHECK-NEXT: Opcode: I32_CONST
73; CHECK-NEXT: Value: 1024
7462; CHECK-NEXT: - Type: EXPORT
7563; CHECK-NEXT: Exports:
7664; CHECK-NEXT: - Name: memory
7765; CHECK-NEXT: Kind: MEMORY
7866; CHECK-NEXT: Index: 0
79; CHECK-NEXT: - Name: __heap_base
80; CHECK-NEXT: Kind: GLOBAL
81; CHECK-NEXT: Index: 1
82; CHECK-NEXT: - Name: __data_end
83; CHECK-NEXT: Kind: GLOBAL
84; CHECK-NEXT: Index: 2
8567; CHECK-NEXT: - Name: _start
8668; CHECK-NEXT: Kind: FUNCTION
87; CHECK-NEXT: Index: 3
69; CHECK-NEXT: Index: 2
8870; CHECK-NEXT: - Type: CODE
8971; CHECK-NEXT: Functions:
9072; CHECK-NEXT: - Index: 0
9173; CHECK-NEXT: Locals:
92; CHECK-NEXT: Body: 0B
74; CHECK-NEXT: Body: 4180808080000B
9375; CHECK-NEXT: - Index: 1
9476; CHECK-NEXT: Locals:
9577; CHECK-NEXT: Body: 4180808080000B
9678; CHECK-NEXT: - Index: 2
9779; CHECK-NEXT: Locals:
98; CHECK-NEXT: Body: 4180808080000B
99; CHECK-NEXT: - Index: 3
100; CHECK-NEXT: Locals:
101; CHECK-NEXT: Body: 1082808080001A1081808080001A0B
80; CHECK-NEXT: Body: 1081808080001A1080808080001A0B
10281; CHECK-NEXT: ...
deps/lld/test/wasm/wrap.ll created+40
......@@ -0,0 +1,40 @@
1; RUN: llc -filetype=obj %s -o %t.o
2; RUN: wasm-ld -wrap nosuchsym -wrap foo -o %t.wasm %t.o
3; RUN: wasm-ld -emit-relocs -wrap foo -o %t.wasm %t.o
4; RUN: obj2yaml %t.wasm | FileCheck %s
5
6target triple = "wasm32-unknown-unknown"
7
8define i32 @foo() {
9 ret i32 1
10}
11
12define void @_start() {
13entry:
14 call i32 @foo()
15 ret void
16}
17
18declare i32 @__real_foo()
19
20define i32 @__wrap_foo() {
21 %rtn = call i32 @__real_foo()
22 ret i32 %rtn
23}
24
25; CHECK: - Type: CODE
26; CHECK-NEXT: Relocations:
27; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
28; CHECK-NEXT: Index: 2
29; CHECK-NEXT: Offset: 0x00000009
30; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
31; CHECK-NEXT: Index: 0
32; CHECK-NEXT: Offset: 0x00000013
33
34; CHECK: FunctionNames:
35; CHECK-NEXT: - Index: 0
36; CHECK-NEXT: Name: foo
37; CHECK-NEXT: - Index: 1
38; CHECK-NEXT: Name: _start
39; CHECK-NEXT: - Index: 2
40; CHECK-NEXT: Name: __wrap_foo
deps/lld/tools/lld/CMakeLists.txt+1
......@@ -8,6 +8,7 @@ add_lld_tool(lld
88
99target_link_libraries(lld
1010 PRIVATE
11 lldCommon
1112 lldCOFF
1213 lldDriver
1314 lldELF
deps/lld/tools/lld/lld.cpp+64-43
......@@ -1,9 +1,8 @@
11//===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -27,9 +26,13 @@
2726//===----------------------------------------------------------------------===//
2827
2928#include "lld/Common/Driver.h"
29#include "lld/Common/Memory.h"
3030#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/SmallVector.h"
3132#include "llvm/ADT/StringSwitch.h"
33#include "llvm/ADT/Triple.h"
3234#include "llvm/ADT/Twine.h"
35#include "llvm/Support/CommandLine.h"
3336#include "llvm/Support/InitLLVM.h"
3437#include "llvm/Support/Path.h"
3538#include <cstdlib>
......@@ -46,13 +49,13 @@ enum Flavor {
4649 Wasm, // -flavor wasm
4750};
4851
49LLVM_ATTRIBUTE_NORETURN static void die(const Twine &S) {
50 errs() << S << "\n";
52LLVM_ATTRIBUTE_NORETURN static void die(const Twine &s) {
53 errs() << s << "\n";
5154 exit(1);
5255}
5356
54static Flavor getFlavor(StringRef S) {
55 return StringSwitch<Flavor>(S)
57static Flavor getFlavor(StringRef s) {
58 return StringSwitch<Flavor>(s)
5659 .CasesLower("ld", "ld.lld", "gnu", Gnu)
5760 .CasesLower("wasm", "ld-wasm", Wasm)
5861 .CaseLower("link", WinLink)
......@@ -60,55 +63,73 @@ static Flavor getFlavor(StringRef S) {
6063 .Default(Invalid);
6164}
6265
63static bool isPETarget(const std::vector<const char *> &V) {
64 for (auto It = V.begin(); It + 1 != V.end(); ++It) {
65 if (StringRef(*It) != "-m")
66static cl::TokenizerCallback getDefaultQuotingStyle() {
67 if (Triple(sys::getProcessTriple()).getOS() == Triple::Win32)
68 return cl::TokenizeWindowsCommandLine;
69 return cl::TokenizeGNUCommandLine;
70}
71
72static bool isPETargetName(StringRef s) {
73 return s == "i386pe" || s == "i386pep" || s == "thumb2pe" || s == "arm64pe";
74}
75
76static bool isPETarget(std::vector<const char *> &v) {
77 for (auto it = v.begin(); it + 1 != v.end(); ++it) {
78 if (StringRef(*it) != "-m")
79 continue;
80 return isPETargetName(*(it + 1));
81 }
82 // Expand response files (arguments in the form of @<filename>)
83 // to allow detecting the -m argument from arguments in them.
84 SmallVector<const char *, 256> expandedArgs(v.data(), v.data() + v.size());
85 cl::ExpandResponseFiles(saver, getDefaultQuotingStyle(), expandedArgs);
86 for (auto it = expandedArgs.begin(); it + 1 != expandedArgs.end(); ++it) {
87 if (StringRef(*it) != "-m")
6688 continue;
67 StringRef S = *(It + 1);
68 return S == "i386pe" || S == "i386pep" || S == "thumb2pe" || S == "arm64pe";
89 return isPETargetName(*(it + 1));
6990 }
7091 return false;
7192}
7293
73static Flavor parseProgname(StringRef Progname) {
94static Flavor parseProgname(StringRef progname) {
7495#if __APPLE__
7596 // Use Darwin driver for "ld" on Darwin.
76 if (Progname == "ld")
97 if (progname == "ld")
7798 return Darwin;
7899#endif
79100
80101#if LLVM_ON_UNIX
81102 // Use GNU driver for "ld" on other Unix-like system.
82 if (Progname == "ld")
103 if (progname == "ld")
83104 return Gnu;
84105#endif
85106
86107 // Progname may be something like "lld-gnu". Parse it.
87 SmallVector<StringRef, 3> V;
88 Progname.split(V, "-");
89 for (StringRef S : V)
90 if (Flavor F = getFlavor(S))
91 return F;
108 SmallVector<StringRef, 3> v;
109 progname.split(v, "-");
110 for (StringRef s : v)
111 if (Flavor f = getFlavor(s))
112 return f;
92113 return Invalid;
93114}
94115
95static Flavor parseFlavor(std::vector<const char *> &V) {
116static Flavor parseFlavor(std::vector<const char *> &v) {
96117 // Parse -flavor option.
97 if (V.size() > 1 && V[1] == StringRef("-flavor")) {
98 if (V.size() <= 2)
118 if (v.size() > 1 && v[1] == StringRef("-flavor")) {
119 if (v.size() <= 2)
99120 die("missing arg value for '-flavor'");
100 Flavor F = getFlavor(V[2]);
101 if (F == Invalid)
102 die("Unknown flavor: " + StringRef(V[2]));
103 V.erase(V.begin() + 1, V.begin() + 3);
104 return F;
121 Flavor f = getFlavor(v[2]);
122 if (f == Invalid)
123 die("Unknown flavor: " + StringRef(v[2]));
124 v.erase(v.begin() + 1, v.begin() + 3);
125 return f;
105126 }
106127
107128 // Deduct the flavor from argv[0].
108 StringRef Arg0 = path::filename(V[0]);
109 if (Arg0.endswith_lower(".exe"))
110 Arg0 = Arg0.drop_back(4);
111 return parseProgname(Arg0);
129 StringRef arg0 = path::filename(v[0]);
130 if (arg0.endswith_lower(".exe"))
131 arg0 = arg0.drop_back(4);
132 return parseProgname(arg0);
112133}
113134
114135// If this function returns true, lld calls _exit() so that it quickly
......@@ -121,21 +142,21 @@ static bool canExitEarly() { return StringRef(getenv("LLD_IN_TEST")) != "1"; }
121142
122143/// Universal linker main(). This linker emulates the gnu, darwin, or
123144/// windows linker based on the argv[0] or -flavor option.
124int main(int Argc, const char **Argv) {
125 InitLLVM X(Argc, Argv);
145int main(int argc, const char **argv) {
146 InitLLVM x(argc, argv);
126147
127 std::vector<const char *> Args(Argv, Argv + Argc);
128 switch (parseFlavor(Args)) {
148 std::vector<const char *> args(argv, argv + argc);
149 switch (parseFlavor(args)) {
129150 case Gnu:
130 if (isPETarget(Args))
131 return !mingw::link(Args);
132 return !elf::link(Args, canExitEarly());
151 if (isPETarget(args))
152 return !mingw::link(args);
153 return !elf::link(args, canExitEarly());
133154 case WinLink:
134 return !coff::link(Args, canExitEarly());
155 return !coff::link(args, canExitEarly());
135156 case Darwin:
136 return !mach_o::link(Args, canExitEarly());
157 return !mach_o::link(args, canExitEarly());
137158 case Wasm:
138 return !wasm::link(Args, canExitEarly());
159 return !wasm::link(args, canExitEarly());
139160 default:
140161 die("lld is a generic driver.\n"
141162 "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld"
deps/lld/unittests/DriverTests/DarwinLdDriverTest.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lld/unittest/DarwinLdDriverTest.cpp --------------------------------===//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98///
deps/lld/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lld/unittest/MachOTests/MachONormalizedFileBinaryReaderTests.cpp ---===//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lld/unittest/MachOTests/MachONormalizedFileBinaryWriterTests.cpp ---===//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lld/unittest/MachOTests/MachONormalizedFileToAtomsTests.cpp --------===//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp+3-4
......@@ -1,9 +1,8 @@
11//===- lld/unittest/MachOTests/MachONormalizedFileYAMLTests.cpp -----------===//
22//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/utils/benchmark.py+12-8
......@@ -1,9 +1,8 @@
11#!/usr/bin/env python
22#
3# The LLVM Compiler Infrastructure
4#
5# This file is distributed under the University of Illinois Open Source
6# License. See LICENSE.TXT for details.
3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4# See https://llvm.org/LICENSE.txt for license information.
5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76#
87# ==------------------------------------------------------------------------==#
98
......@@ -14,8 +13,13 @@ import subprocess
1413import json
1514import datetime
1615import argparse
17import urllib
18import urllib2
16try:
17 from urllib.parse import urlencode
18 from urllib.request import urlopen, Request
19except ImportError:
20 from urllib import urlencode
21 from urllib2 import urlopen, Request
22
1923
2024parser = argparse.ArgumentParser()
2125parser.add_argument('benchmark_directory')
......@@ -127,8 +131,8 @@ def buildLntJson(benchmarks):
127131 return json.dumps(ret, sort_keys=True, indent=4)
128132
129133def submitToServer(data):
130 data2 = urllib.urlencode({ 'input_data' : data }).encode('ascii')
131 urllib2.urlopen(urllib2.Request(args.url, data2))
134 data2 = urlencode({ 'input_data' : data }).encode('ascii')
135 urlopen(Request(args.url, data2))
132136
133137os.chdir(args.benchmark_directory)
134138data = buildLntJson(getBenchmarks())
deps/lld/wasm/CMakeLists.txt+3-1
......@@ -13,8 +13,10 @@ add_lld_library(lldWasm
1313 LTO.cpp
1414 MarkLive.cpp
1515 OutputSections.cpp
16 Relocations.cpp
1617 SymbolTable.cpp
1718 Symbols.cpp
19 SyntheticSections.cpp
1820 Writer.cpp
1921 WriterUtils.cpp
2022
......@@ -35,4 +37,4 @@ add_lld_library(lldWasm
3537 DEPENDS
3638 WasmOptionsTableGen
3739 ${tablegen_deps}
38 )
\ No newline at end of file
40 )
deps/lld/wasm/Config.h+53-40
......@@ -1,9 +1,8 @@
11//===- Config.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -18,49 +17,63 @@
1817namespace lld {
1918namespace wasm {
2019
20// This struct contains the global configuration for the linker.
21// Most fields are direct mapping from the command line options
22// and such fields have the same name as the corresponding options.
23// Most fields are initialized by the driver.
2124struct Configuration {
22 bool AllowUndefined;
23 bool CompressRelocations;
24 bool Demangle;
25 bool DisableVerify;
26 bool ExportAll;
27 bool ExportDynamic;
28 bool ExportTable;
29 bool GcSections;
30 bool ImportMemory;
31 bool SharedMemory;
32 bool ImportTable;
33 bool MergeDataSegments;
34 bool Pie;
35 bool PrintGcSections;
36 bool Relocatable;
37 bool SaveTemps;
38 bool Shared;
39 bool StripAll;
40 bool StripDebug;
41 bool StackFirst;
42 uint32_t GlobalBase;
43 uint32_t InitialMemory;
44 uint32_t MaxMemory;
45 uint32_t ZStackSize;
46 unsigned LTOPartitions;
47 unsigned LTOO;
48 unsigned Optimize;
49 unsigned ThinLTOJobs;
50 llvm::StringRef Entry;
51 llvm::StringRef OutputFile;
52 llvm::StringRef ThinLTOCacheDir;
25 bool allowUndefined;
26 bool checkFeatures;
27 bool compressRelocations;
28 bool demangle;
29 bool disableVerify;
30 bool emitRelocs;
31 bool exportAll;
32 bool exportDynamic;
33 bool exportTable;
34 bool gcSections;
35 bool importMemory;
36 bool sharedMemory;
37 bool passiveSegments;
38 bool importTable;
39 bool mergeDataSegments;
40 bool pie;
41 bool printGcSections;
42 bool relocatable;
43 bool saveTemps;
44 bool shared;
45 bool stripAll;
46 bool stripDebug;
47 bool stackFirst;
48 bool trace;
49 uint32_t globalBase;
50 uint32_t initialMemory;
51 uint32_t maxMemory;
52 uint32_t zStackSize;
53 unsigned ltoPartitions;
54 unsigned ltoo;
55 unsigned optimize;
56 unsigned thinLTOJobs;
57
58 llvm::StringRef entry;
59 llvm::StringRef outputFile;
60 llvm::StringRef thinLTOCacheDir;
61
62 llvm::StringSet<> allowUndefinedSymbols;
63 llvm::StringSet<> exportedSymbols;
64 std::vector<llvm::StringRef> searchPaths;
65 llvm::CachePruningPolicy thinLTOCachePolicy;
66 llvm::Optional<std::vector<std::string>> features;
5367
54 llvm::StringSet<> AllowUndefinedSymbols;
55 std::vector<llvm::StringRef> SearchPaths;
56 llvm::CachePruningPolicy ThinLTOCachePolicy;
68 // The following config options do not directly correspond to any
69 // particualr command line options.
5770
5871 // True if we are creating position-independent code.
59 bool Pic;
72 bool isPic;
6073};
6174
6275// The only instance of Configuration struct.
63extern Configuration *Config;
76extern Configuration *config;
6477
6578} // namespace wasm
6679} // namespace lld
deps/lld/wasm/Driver.cpp+498-325
......@@ -1,9 +1,8 @@
11//===- Driver.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -17,15 +16,18 @@
1716#include "lld/Common/Args.h"
1817#include "lld/Common/ErrorHandler.h"
1918#include "lld/Common/Memory.h"
19#include "lld/Common/Reproduce.h"
2020#include "lld/Common/Strings.h"
2121#include "lld/Common/Threads.h"
2222#include "lld/Common/Version.h"
2323#include "llvm/ADT/Twine.h"
2424#include "llvm/Object/Wasm.h"
25#include "llvm/Option/Arg.h"
2526#include "llvm/Option/ArgList.h"
2627#include "llvm/Support/CommandLine.h"
2728#include "llvm/Support/Path.h"
2829#include "llvm/Support/Process.h"
30#include "llvm/Support/TarWriter.h"
2931#include "llvm/Support/TargetSelect.h"
3032
3133#define DEBUG_TYPE "lld"
......@@ -38,7 +40,7 @@ using namespace llvm::wasm;
3840using namespace lld;
3941using namespace lld::wasm;
4042
41Configuration *lld::wasm::Config;
43Configuration *lld::wasm::config;
4244
4345namespace {
4446
......@@ -63,39 +65,39 @@ static void initLLVM() {
6365
6466class LinkerDriver {
6567public:
66 void link(ArrayRef<const char *> ArgsArr);
68 void link(ArrayRef<const char *> argsArr);
6769
6870private:
69 void createFiles(opt::InputArgList &Args);
70 void addFile(StringRef Path);
71 void addLibrary(StringRef Name);
71 void createFiles(opt::InputArgList &args);
72 void addFile(StringRef path);
73 void addLibrary(StringRef name);
7274
7375 // True if we are in --whole-archive and --no-whole-archive.
74 bool InWholeArchive = false;
76 bool inWholeArchive = false;
7577
76 std::vector<InputFile *> Files;
78 std::vector<InputFile *> files;
7779};
7880} // anonymous namespace
7981
80bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,
81 raw_ostream &Error) {
82 errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
83 errorHandler().ErrorOS = &Error;
84 errorHandler().ColorDiagnostics = Error.has_colors();
85 errorHandler().ErrorLimitExceededMsg =
82bool lld::wasm::link(ArrayRef<const char *> args, bool canExitEarly,
83 raw_ostream &error) {
84 errorHandler().logName = args::getFilenameWithoutExe(args[0]);
85 errorHandler().errorOS = &error;
86 errorHandler().colorDiagnostics = error.has_colors();
87 errorHandler().errorLimitExceededMsg =
8688 "too many errors emitted, stopping now (use "
8789 "-error-limit=0 to see all errors)";
8890
89 Config = make<Configuration>();
90 Symtab = make<SymbolTable>();
91 config = make<Configuration>();
92 symtab = make<SymbolTable>();
9193
9294 initLLVM();
93 LinkerDriver().link(Args);
95 LinkerDriver().link(args);
9496
9597 // Exit immediately if we don't need to return to the caller.
9698 // This saves time because the overhead of calling destructors
9799 // for all globally-allocated objects is not negligible.
98 if (CanExitEarly)
100 if (canExitEarly)
99101 exitLld(errorCount() ? 1 : 0);
100102
101103 freeArena();
......@@ -108,7 +110,7 @@ bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,
108110#undef PREFIX
109111
110112// Create table mapping all options defined in Options.td
111static const opt::OptTable::Info OptInfo[] = {
113static const opt::OptTable::Info optInfo[] = {
112114#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
113115 {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
114116 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
......@@ -119,57 +121,57 @@ static const opt::OptTable::Info OptInfo[] = {
119121namespace {
120122class WasmOptTable : public llvm::opt::OptTable {
121123public:
122 WasmOptTable() : OptTable(OptInfo) {}
123 opt::InputArgList parse(ArrayRef<const char *> Argv);
124 WasmOptTable() : OptTable(optInfo) {}
125 opt::InputArgList parse(ArrayRef<const char *> argv);
124126};
125127} // namespace
126128
127129// Set color diagnostics according to -color-diagnostics={auto,always,never}
128130// or -no-color-diagnostics flags.
129static void handleColorDiagnostics(opt::InputArgList &Args) {
130 auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
131static void handleColorDiagnostics(opt::InputArgList &args) {
132 auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
131133 OPT_no_color_diagnostics);
132 if (!Arg)
134 if (!arg)
133135 return;
134 if (Arg->getOption().getID() == OPT_color_diagnostics) {
135 errorHandler().ColorDiagnostics = true;
136 } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) {
137 errorHandler().ColorDiagnostics = false;
136 if (arg->getOption().getID() == OPT_color_diagnostics) {
137 errorHandler().colorDiagnostics = true;
138 } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
139 errorHandler().colorDiagnostics = false;
138140 } else {
139 StringRef S = Arg->getValue();
140 if (S == "always")
141 errorHandler().ColorDiagnostics = true;
142 else if (S == "never")
143 errorHandler().ColorDiagnostics = false;
144 else if (S != "auto")
145 error("unknown option: --color-diagnostics=" + S);
141 StringRef s = arg->getValue();
142 if (s == "always")
143 errorHandler().colorDiagnostics = true;
144 else if (s == "never")
145 errorHandler().colorDiagnostics = false;
146 else if (s != "auto")
147 error("unknown option: --color-diagnostics=" + s);
146148 }
147149}
148150
149151// Find a file by concatenating given paths.
150static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
151 SmallString<128> S;
152 path::append(S, Path1, Path2);
153 if (fs::exists(S))
154 return S.str().str();
152static Optional<std::string> findFile(StringRef path1, const Twine &path2) {
153 SmallString<128> s;
154 path::append(s, path1, path2);
155 if (fs::exists(s))
156 return s.str().str();
155157 return None;
156158}
157159
158opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) {
159 SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());
160opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> argv) {
161 SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
160162
161 unsigned MissingIndex;
162 unsigned MissingCount;
163 unsigned missingIndex;
164 unsigned missingCount;
163165
164166 // Expand response files (arguments in the form of @<filename>)
165 cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Vec);
167 cl::ExpandResponseFiles(saver, cl::TokenizeGNUCommandLine, vec);
166168
167 opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
169 opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount);
168170
169 handleColorDiagnostics(Args);
170 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
171 error("unknown argument: " + Arg->getSpelling());
172 return Args;
171 handleColorDiagnostics(args);
172 for (auto *arg : args.filtered(OPT_UNKNOWN))
173 error("unknown argument: " + arg->getAsString(args));
174 return args;
173175}
174176
175177// Currently we allow a ".imports" to live alongside a library. This can
......@@ -179,149 +181,188 @@ opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) {
179181// In the long run this information would be better stored as a symbol
180182// attribute/flag in the object file itself.
181183// See: https://github.com/WebAssembly/tool-conventions/issues/35
182static void readImportFile(StringRef Filename) {
183 if (Optional<MemoryBufferRef> Buf = readFile(Filename))
184 for (StringRef Sym : args::getLines(*Buf))
185 Config->AllowUndefinedSymbols.insert(Sym);
184static void readImportFile(StringRef filename) {
185 if (Optional<MemoryBufferRef> buf = readFile(filename))
186 for (StringRef sym : args::getLines(*buf))
187 config->allowUndefinedSymbols.insert(sym);
186188}
187189
188190// Returns slices of MB by parsing MB as an archive file.
189191// Each slice consists of a member file in the archive.
190std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef MB) {
191 std::unique_ptr<Archive> File =
192 CHECK(Archive::create(MB),
193 MB.getBufferIdentifier() + ": failed to parse archive");
194
195 std::vector<MemoryBufferRef> V;
196 Error Err = Error::success();
197 for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
198 Archive::Child C =
199 CHECK(COrErr, MB.getBufferIdentifier() +
192std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef mb) {
193 std::unique_ptr<Archive> file =
194 CHECK(Archive::create(mb),
195 mb.getBufferIdentifier() + ": failed to parse archive");
196
197 std::vector<MemoryBufferRef> v;
198 Error err = Error::success();
199 for (const ErrorOr<Archive::Child> &cOrErr : file->children(err)) {
200 Archive::Child c =
201 CHECK(cOrErr, mb.getBufferIdentifier() +
200202 ": could not get the child of the archive");
201 MemoryBufferRef MBRef =
202 CHECK(C.getMemoryBufferRef(),
203 MB.getBufferIdentifier() +
203 MemoryBufferRef mbref =
204 CHECK(c.getMemoryBufferRef(),
205 mb.getBufferIdentifier() +
204206 ": could not get the buffer for a child of the archive");
205 V.push_back(MBRef);
207 v.push_back(mbref);
206208 }
207 if (Err)
208 fatal(MB.getBufferIdentifier() +
209 ": Archive::children failed: " + toString(std::move(Err)));
209 if (err)
210 fatal(mb.getBufferIdentifier() +
211 ": Archive::children failed: " + toString(std::move(err)));
210212
211213 // Take ownership of memory buffers created for members of thin archives.
212 for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
213 make<std::unique_ptr<MemoryBuffer>>(std::move(MB));
214 for (std::unique_ptr<MemoryBuffer> &mb : file->takeThinBuffers())
215 make<std::unique_ptr<MemoryBuffer>>(std::move(mb));
214216
215 return V;
217 return v;
216218}
217219
218void LinkerDriver::addFile(StringRef Path) {
219 Optional<MemoryBufferRef> Buffer = readFile(Path);
220 if (!Buffer.hasValue())
220void LinkerDriver::addFile(StringRef path) {
221 Optional<MemoryBufferRef> buffer = readFile(path);
222 if (!buffer.hasValue())
221223 return;
222 MemoryBufferRef MBRef = *Buffer;
224 MemoryBufferRef mbref = *buffer;
223225
224 switch (identify_magic(MBRef.getBuffer())) {
226 switch (identify_magic(mbref.getBuffer())) {
225227 case file_magic::archive: {
228 SmallString<128> importFile = path;
229 path::replace_extension(importFile, ".imports");
230 if (fs::exists(importFile))
231 readImportFile(importFile.str());
232
226233 // Handle -whole-archive.
227 if (InWholeArchive) {
228 for (MemoryBufferRef &M : getArchiveMembers(MBRef))
229 Files.push_back(createObjectFile(M));
234 if (inWholeArchive) {
235 for (MemoryBufferRef &m : getArchiveMembers(mbref))
236 files.push_back(createObjectFile(m, path));
230237 return;
231238 }
232239
233 SmallString<128> ImportFile = Path;
234 path::replace_extension(ImportFile, ".imports");
235 if (fs::exists(ImportFile))
236 readImportFile(ImportFile.str());
240 std::unique_ptr<Archive> file =
241 CHECK(Archive::create(mbref), path + ": failed to parse archive");
242
243 if (!file->isEmpty() && !file->hasSymbolTable()) {
244 error(mbref.getBufferIdentifier() +
245 ": archive has no index; run ranlib to add one");
246 }
237247
238 Files.push_back(make<ArchiveFile>(MBRef));
248 files.push_back(make<ArchiveFile>(mbref));
239249 return;
240250 }
241251 case file_magic::bitcode:
242252 case file_magic::wasm_object:
243 Files.push_back(createObjectFile(MBRef));
253 files.push_back(createObjectFile(mbref));
244254 break;
245255 default:
246 error("unknown file type: " + MBRef.getBufferIdentifier());
256 error("unknown file type: " + mbref.getBufferIdentifier());
247257 }
248258}
249259
250260// Add a given library by searching it from input search paths.
251void LinkerDriver::addLibrary(StringRef Name) {
252 for (StringRef Dir : Config->SearchPaths) {
253 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) {
254 addFile(*S);
261void LinkerDriver::addLibrary(StringRef name) {
262 for (StringRef dir : config->searchPaths) {
263 if (Optional<std::string> s = findFile(dir, "lib" + name + ".a")) {
264 addFile(*s);
255265 return;
256266 }
257267 }
258268
259 error("unable to find library -l" + Name);
269 error("unable to find library -l" + name);
260270}
261271
262void LinkerDriver::createFiles(opt::InputArgList &Args) {
263 for (auto *Arg : Args) {
264 switch (Arg->getOption().getUnaliasedOption().getID()) {
272void LinkerDriver::createFiles(opt::InputArgList &args) {
273 for (auto *arg : args) {
274 switch (arg->getOption().getID()) {
265275 case OPT_l:
266 addLibrary(Arg->getValue());
276 addLibrary(arg->getValue());
267277 break;
268278 case OPT_INPUT:
269 addFile(Arg->getValue());
279 addFile(arg->getValue());
270280 break;
271281 case OPT_whole_archive:
272 InWholeArchive = true;
282 inWholeArchive = true;
273283 break;
274284 case OPT_no_whole_archive:
275 InWholeArchive = false;
285 inWholeArchive = false;
276286 break;
277287 }
278288 }
279289}
280290
281static StringRef getEntry(opt::InputArgList &Args, StringRef Default) {
282 auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry);
283 if (!Arg)
284 return Default;
285 if (Arg->getOption().getID() == OPT_no_entry)
291static StringRef getEntry(opt::InputArgList &args) {
292 auto *arg = args.getLastArg(OPT_entry, OPT_no_entry);
293 if (!arg) {
294 if (args.hasArg(OPT_relocatable))
295 return "";
296 if (args.hasArg(OPT_shared))
297 return "__wasm_call_ctors";
298 return "_start";
299 }
300 if (arg->getOption().getID() == OPT_no_entry)
286301 return "";
287 return Arg->getValue();
302 return arg->getValue();
288303}
289304
290static const uint8_t UnreachableFn[] = {
291 0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
292 0x00 /* opcode unreachable */, 0x0b /* opcode end */
293};
294
295// For weak undefined functions, there may be "call" instructions that reference
296// the symbol. In this case, we need to synthesise a dummy/stub function that
297// will abort at runtime, so that relocations can still provided an operand to
298// the call instruction that passes Wasm validation.
299static void handleWeakUndefines() {
300 for (Symbol *Sym : Symtab->getSymbols()) {
301 if (!Sym->isUndefined() || !Sym->isWeak())
302 continue;
303 auto *FuncSym = dyn_cast<FunctionSymbol>(Sym);
304 if (!FuncSym)
305 continue;
306
307 // It is possible for undefined functions not to have a signature (eg. if
308 // added via "--undefined"), but weak undefined ones do have a signature.
309 assert(FuncSym->Signature);
310 const WasmSignature &Sig = *FuncSym->Signature;
311
312 // Add a synthetic dummy for weak undefined functions. These dummies will
313 // be GC'd if not used as the target of any "call" instructions.
314 std::string SymName = toString(*Sym);
315 StringRef DebugName = Saver.save("undefined function " + SymName);
316 auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
317 Func->setBody(UnreachableFn);
318 // Ensure it compares equal to the null pointer, and so that table relocs
319 // don't pull in the stub body (only call-operand relocs should do that).
320 Func->setTableIndex(0);
321 Symtab->SyntheticFunctions.emplace_back(Func);
322 // Hide our dummy to prevent export.
323 uint32_t Flags = WASM_SYMBOL_VISIBILITY_HIDDEN;
324 replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Flags, nullptr, Func);
305// Initializes Config members by the command line options.
306static void readConfigs(opt::InputArgList &args) {
307 config->allowUndefined = args.hasArg(OPT_allow_undefined);
308 config->checkFeatures =
309 args.hasFlag(OPT_check_features, OPT_no_check_features, true);
310 config->compressRelocations = args.hasArg(OPT_compress_relocations);
311 config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
312 config->disableVerify = args.hasArg(OPT_disable_verify);
313 config->emitRelocs = args.hasArg(OPT_emit_relocs);
314 config->entry = getEntry(args);
315 config->exportAll = args.hasArg(OPT_export_all);
316 config->exportDynamic = args.hasFlag(OPT_export_dynamic,
317 OPT_no_export_dynamic, false);
318 config->exportTable = args.hasArg(OPT_export_table);
319 errorHandler().fatalWarnings =
320 args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
321 config->importMemory = args.hasArg(OPT_import_memory);
322 config->sharedMemory = args.hasArg(OPT_shared_memory);
323 config->passiveSegments = args.hasFlag(
324 OPT_passive_segments, OPT_active_segments, config->sharedMemory);
325 config->importTable = args.hasArg(OPT_import_table);
326 config->ltoo = args::getInteger(args, OPT_lto_O, 2);
327 config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
328 config->optimize = args::getInteger(args, OPT_O, 0);
329 config->outputFile = args.getLastArgValue(OPT_o);
330 config->relocatable = args.hasArg(OPT_relocatable);
331 config->gcSections =
332 args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !config->relocatable);
333 config->mergeDataSegments =
334 args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
335 !config->relocatable);
336 config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
337 config->printGcSections =
338 args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
339 config->saveTemps = args.hasArg(OPT_save_temps);
340 config->searchPaths = args::getStrings(args, OPT_L);
341 config->shared = args.hasArg(OPT_shared);
342 config->stripAll = args.hasArg(OPT_strip_all);
343 config->stripDebug = args.hasArg(OPT_strip_debug);
344 config->stackFirst = args.hasArg(OPT_stack_first);
345 config->trace = args.hasArg(OPT_trace);
346 config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
347 config->thinLTOCachePolicy = CHECK(
348 parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
349 "--thinlto-cache-policy: invalid cache policy");
350 config->thinLTOJobs = args::getInteger(args, OPT_thinlto_jobs, -1u);
351 errorHandler().verbose = args.hasArg(OPT_verbose);
352 LLVM_DEBUG(errorHandler().verbose = true);
353 threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true);
354
355 config->initialMemory = args::getInteger(args, OPT_initial_memory, 0);
356 config->globalBase = args::getInteger(args, OPT_global_base, 1024);
357 config->maxMemory = args::getInteger(args, OPT_max_memory, 0);
358 config->zStackSize =
359 args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize);
360
361 if (auto *arg = args.getLastArg(OPT_features)) {
362 config->features =
363 llvm::Optional<std::vector<std::string>>(std::vector<std::string>());
364 for (StringRef s : arg->getValues())
365 config->features->push_back(s);
325366 }
326367}
327368
......@@ -329,286 +370,418 @@ static void handleWeakUndefines() {
329370// command line options, but computed based on other Config values.
330371// This function initialize such members. See Config.h for the details
331372// of these values.
332static void setConfigs(opt::InputArgList &Args) {
333 Config->AllowUndefined = Args.hasArg(OPT_allow_undefined);
334 Config->CompressRelocations = Args.hasArg(OPT_compress_relocations);
335 Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
336 Config->DisableVerify = Args.hasArg(OPT_disable_verify);
337 Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
338 Config->ExportAll = Args.hasArg(OPT_export_all);
339 Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic,
340 OPT_no_export_dynamic, false);
341 Config->ExportTable = Args.hasArg(OPT_export_table);
342 errorHandler().FatalWarnings =
343 Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
344 Config->ImportMemory = Args.hasArg(OPT_import_memory);
345 Config->SharedMemory = Args.hasArg(OPT_shared_memory);
346 Config->ImportTable = Args.hasArg(OPT_import_table);
347 Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
348 Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
349 Config->Optimize = args::getInteger(Args, OPT_O, 0);
350 Config->OutputFile = Args.getLastArgValue(OPT_o);
351 Config->Relocatable = Args.hasArg(OPT_relocatable);
352 Config->GcSections =
353 Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable);
354 Config->MergeDataSegments =
355 Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
356 !Config->Relocatable);
357 Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
358 Config->PrintGcSections =
359 Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
360 Config->SaveTemps = Args.hasArg(OPT_save_temps);
361 Config->SearchPaths = args::getStrings(Args, OPT_L);
362 Config->Shared = Args.hasArg(OPT_shared);
363 Config->StripAll = Args.hasArg(OPT_strip_all);
364 Config->StripDebug = Args.hasArg(OPT_strip_debug);
365 Config->StackFirst = Args.hasArg(OPT_stack_first);
366 Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
367 Config->ThinLTOCachePolicy = CHECK(
368 parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
369 "--thinlto-cache-policy: invalid cache policy");
370 Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
371 errorHandler().Verbose = Args.hasArg(OPT_verbose);
372 ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
373
374 Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0);
375 Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024);
376 Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0);
377 Config->ZStackSize =
378 args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);
373static void setConfigs() {
374 config->isPic = config->pie || config->shared;
375
376 if (config->isPic) {
377 if (config->exportTable)
378 error("-shared/-pie is incompatible with --export-table");
379 config->importTable = true;
380 }
381
382 if (config->shared) {
383 config->importMemory = true;
384 config->exportDynamic = true;
385 config->allowUndefined = true;
386 }
379387}
380388
381389// Some command line options or some combinations of them are not allowed.
382390// This function checks for such errors.
383static void checkOptions(opt::InputArgList &Args) {
384 if (!Config->StripDebug && !Config->StripAll && Config->CompressRelocations)
391static void checkOptions(opt::InputArgList &args) {
392 if (!config->stripDebug && !config->stripAll && config->compressRelocations)
385393 error("--compress-relocations is incompatible with output debug"
386394 " information. Please pass --strip-debug or --strip-all");
387395
388 if (Config->LTOO > 3)
389 error("invalid optimization level for LTO: " + Twine(Config->LTOO));
390 if (Config->LTOPartitions == 0)
396 if (config->ltoo > 3)
397 error("invalid optimization level for LTO: " + Twine(config->ltoo));
398 if (config->ltoPartitions == 0)
391399 error("--lto-partitions: number of threads must be > 0");
392 if (Config->ThinLTOJobs == 0)
400 if (config->thinLTOJobs == 0)
393401 error("--thinlto-jobs: number of threads must be > 0");
394402
395 if (Config->Pie && Config->Shared)
403 if (config->pie && config->shared)
396404 error("-shared and -pie may not be used together");
397405
398 if (Config->OutputFile.empty())
406 if (config->outputFile.empty())
399407 error("no output file specified");
400408
401 if (Config->ImportTable && Config->ExportTable)
409 if (config->importTable && config->exportTable)
402410 error("--import-table and --export-table may not be used together");
403411
404 if (Config->Relocatable) {
405 if (!Config->Entry.empty())
412 if (config->relocatable) {
413 if (!config->entry.empty())
406414 error("entry point specified for relocatable output file");
407 if (Config->GcSections)
415 if (config->gcSections)
408416 error("-r and --gc-sections may not be used together");
409 if (Config->CompressRelocations)
417 if (config->compressRelocations)
410418 error("-r -and --compress-relocations may not be used together");
411 if (Args.hasArg(OPT_undefined))
419 if (args.hasArg(OPT_undefined))
412420 error("-r -and --undefined may not be used together");
413 if (Config->Pie)
421 if (config->pie)
414422 error("-r and -pie may not be used together");
415423 }
416424}
417425
418426// 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)
427static Symbol *handleUndefined(StringRef name) {
428 Symbol *sym = symtab->find(name);
429 if (!sym)
422430 return nullptr;
423431
424432 // Since symbol S may not be used inside the program, LTO may
425433 // eliminate it. Mark the symbol as "used" to prevent it.
426 Sym->IsUsedInRegularObj = true;
434 sym->isUsedInRegularObj = true;
427435
428 if (auto *LazySym = dyn_cast<LazySymbol>(Sym))
429 LazySym->fetch();
436 if (auto *lazySym = dyn_cast<LazySymbol>(sym))
437 lazySym->fetch();
430438
431 return Sym;
439 return sym;
432440}
433441
434442static UndefinedGlobal *
435createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) {
436 auto *Sym =
437 cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, Name,
438 DefaultModule, 0,
439 nullptr, Type));
440 Config->AllowUndefinedSymbols.insert(Sym->getName());
441 Sym->IsUsedInRegularObj = true;
442 return Sym;
443createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) {
444 auto *sym =
445 cast<UndefinedGlobal>(symtab->addUndefinedGlobal(name, name,
446 defaultModule, 0,
447 nullptr, type));
448 config->allowUndefinedSymbols.insert(sym->getName());
449 sym->isUsedInRegularObj = true;
450 return sym;
443451}
444452
445453// Create ABI-defined synthetic symbols
446454static void createSyntheticSymbols() {
447 static WasmSignature NullSignature = {{}, {}};
448 static llvm::wasm::WasmGlobalType GlobalTypeI32 = {WASM_TYPE_I32, false};
449 static llvm::wasm::WasmGlobalType MutableGlobalTypeI32 = {WASM_TYPE_I32,
455 static WasmSignature nullSignature = {{}, {}};
456 static WasmSignature i32ArgSignature = {{}, {ValType::I32}};
457 static llvm::wasm::WasmGlobalType globalTypeI32 = {WASM_TYPE_I32, false};
458 static llvm::wasm::WasmGlobalType mutableGlobalTypeI32 = {WASM_TYPE_I32,
450459 true};
451460
452 if (!Config->Relocatable)
453 WasmSym::CallCtors = Symtab->addSyntheticFunction(
461 if (!config->relocatable) {
462 WasmSym::callCtors = symtab->addSyntheticFunction(
454463 "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
455 make<SyntheticFunction>(NullSignature, "__wasm_call_ctors"));
464 make<SyntheticFunction>(nullSignature, "__wasm_call_ctors"));
465
466 if (config->passiveSegments) {
467 // Passive segments are used to avoid memory being reinitialized on each
468 // thread's instantiation. These passive segments are initialized and
469 // dropped in __wasm_init_memory, which is the first function called from
470 // __wasm_call_ctors.
471 WasmSym::initMemory = symtab->addSyntheticFunction(
472 "__wasm_init_memory", WASM_SYMBOL_VISIBILITY_HIDDEN,
473 make<SyntheticFunction>(nullSignature, "__wasm_init_memory"));
474 }
456475
457 // The __stack_pointer is imported in the shared library case, and exported
458 // in the non-shared (executable) case.
459 if (Config->Shared) {
460 WasmSym::StackPointer =
461 createUndefinedGlobal("__stack_pointer", &MutableGlobalTypeI32);
462 } else {
463 llvm::wasm::WasmGlobal Global;
464 Global.Type = {WASM_TYPE_I32, true};
465 Global.InitExpr.Value.Int32 = 0;
466 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
467 Global.SymbolName = "__stack_pointer";
468 auto *StackPointer = make<InputGlobal>(Global, nullptr);
469 StackPointer->Live = true;
470 // For non-PIC code
471 // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global
472 // spec proposal is implemented in all major browsers.
473 // See: https://github.com/WebAssembly/mutable-global
474 WasmSym::StackPointer = Symtab->addSyntheticGlobal(
475 "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
476 WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0);
477 WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0);
478
479 // These two synthetic symbols exist purely for the embedder so we always
480 // want to export them.
481 WasmSym::HeapBase->ForceExport = true;
482 WasmSym::DataEnd->ForceExport = true;
476 if (config->isPic) {
477 // For PIC code we create a synthetic function __wasm_apply_relocs which
478 // is called from __wasm_call_ctors before the user-level constructors.
479 WasmSym::applyRelocs = symtab->addSyntheticFunction(
480 "__wasm_apply_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN,
481 make<SyntheticFunction>(nullSignature, "__wasm_apply_relocs"));
482 }
483483 }
484484
485 if (Config->Pic) {
485 if (!config->shared)
486 WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");
487
488 if (config->isPic) {
489 WasmSym::stackPointer =
490 createUndefinedGlobal("__stack_pointer", &mutableGlobalTypeI32);
486491 // For PIC code, we import two global variables (__memory_base and
487492 // __table_base) from the environment and use these as the offset at
488493 // which to load our static data and function table.
489494 // See:
490495 // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
491 WasmSym::MemoryBase =
492 createUndefinedGlobal("__memory_base", &GlobalTypeI32);
493 WasmSym::TableBase = createUndefinedGlobal("__table_base", &GlobalTypeI32);
494 WasmSym::MemoryBase->markLive();
495 WasmSym::TableBase->markLive();
496 WasmSym::memoryBase =
497 createUndefinedGlobal("__memory_base", &globalTypeI32);
498 WasmSym::tableBase = createUndefinedGlobal("__table_base", &globalTypeI32);
499 WasmSym::memoryBase->markLive();
500 WasmSym::tableBase->markLive();
501 } else {
502 llvm::wasm::WasmGlobal global;
503 global.Type = {WASM_TYPE_I32, true};
504 global.InitExpr.Value.Int32 = 0;
505 global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
506 global.SymbolName = "__stack_pointer";
507 auto *stackPointer = make<InputGlobal>(global, nullptr);
508 stackPointer->live = true;
509 // For non-PIC code
510 // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global
511 // spec proposal is implemented in all major browsers.
512 // See: https://github.com/WebAssembly/mutable-global
513 WasmSym::stackPointer = symtab->addSyntheticGlobal(
514 "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, stackPointer);
515 WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base");
516 WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base");
496517 }
497518
498 WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
519 if (config->sharedMemory && !config->shared) {
520 llvm::wasm::WasmGlobal tlsBaseGlobal;
521 tlsBaseGlobal.Type = {WASM_TYPE_I32, true};
522 tlsBaseGlobal.InitExpr.Value.Int32 = 0;
523 tlsBaseGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
524 tlsBaseGlobal.SymbolName = "__tls_base";
525 WasmSym::tlsBase =
526 symtab->addSyntheticGlobal("__tls_base", WASM_SYMBOL_VISIBILITY_HIDDEN,
527 make<InputGlobal>(tlsBaseGlobal, nullptr));
528
529 llvm::wasm::WasmGlobal tlsSizeGlobal;
530 tlsSizeGlobal.Type = {WASM_TYPE_I32, false};
531 tlsSizeGlobal.InitExpr.Value.Int32 = 0;
532 tlsSizeGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
533 tlsSizeGlobal.SymbolName = "__tls_size";
534 WasmSym::tlsSize =
535 symtab->addSyntheticGlobal("__tls_size", WASM_SYMBOL_VISIBILITY_HIDDEN,
536 make<InputGlobal>(tlsSizeGlobal, nullptr));
537
538 WasmSym::initTLS = symtab->addSyntheticFunction(
539 "__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN,
540 make<SyntheticFunction>(i32ArgSignature, "__wasm_init_tls"));
541 }
542
543 WasmSym::dsoHandle = symtab->addSyntheticDataSymbol(
499544 "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
500545}
501546
502void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
503 WasmOptTable Parser;
504 opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
547// Reconstructs command line arguments so that so that you can re-run
548// the same command with the same inputs. This is for --reproduce.
549static std::string createResponseFile(const opt::InputArgList &args) {
550 SmallString<0> data;
551 raw_svector_ostream os(data);
552
553 // Copy the command line to the output while rewriting paths.
554 for (auto *arg : args) {
555 switch (arg->getOption().getID()) {
556 case OPT_reproduce:
557 break;
558 case OPT_INPUT:
559 os << quote(relativeToRoot(arg->getValue())) << "\n";
560 break;
561 case OPT_o:
562 // If -o path contains directories, "lld @response.txt" will likely
563 // fail because the archive we are creating doesn't contain empty
564 // directories for the output path (-o doesn't create directories).
565 // Strip directories to prevent the issue.
566 os << "-o " << quote(sys::path::filename(arg->getValue())) << "\n";
567 break;
568 default:
569 os << toString(*arg) << "\n";
570 }
571 }
572 return data.str();
573}
574
575// The --wrap option is a feature to rename symbols so that you can write
576// wrappers for existing functions. If you pass `-wrap=foo`, all
577// occurrences of symbol `foo` are resolved to `wrap_foo` (so, you are
578// expected to write `wrap_foo` function as a wrapper). The original
579// symbol becomes accessible as `real_foo`, so you can call that from your
580// wrapper.
581//
582// This data structure is instantiated for each -wrap option.
583struct WrappedSymbol {
584 Symbol *sym;
585 Symbol *real;
586 Symbol *wrap;
587};
588
589static Symbol *addUndefined(StringRef name) {
590 return symtab->addUndefinedFunction(name, "", "", 0, nullptr, nullptr, false);
591}
592
593// Handles -wrap option.
594//
595// This function instantiates wrapper symbols. At this point, they seem
596// like they are not being used at all, so we explicitly set some flags so
597// that LTO won't eliminate them.
598static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
599 std::vector<WrappedSymbol> v;
600 DenseSet<StringRef> seen;
601
602 for (auto *arg : args.filtered(OPT_wrap)) {
603 StringRef name = arg->getValue();
604 if (!seen.insert(name).second)
605 continue;
606
607 Symbol *sym = symtab->find(name);
608 if (!sym)
609 continue;
610
611 Symbol *real = addUndefined(saver.save("__real_" + name));
612 Symbol *wrap = addUndefined(saver.save("__wrap_" + name));
613 v.push_back({sym, real, wrap});
614
615 // We want to tell LTO not to inline symbols to be overwritten
616 // because LTO doesn't know the final symbol contents after renaming.
617 real->canInline = false;
618 sym->canInline = false;
619
620 // Tell LTO not to eliminate these symbols.
621 sym->isUsedInRegularObj = true;
622 wrap->isUsedInRegularObj = true;
623 real->isUsedInRegularObj = false;
624 }
625 return v;
626}
627
628// Do renaming for -wrap by updating pointers to symbols.
629//
630// When this function is executed, only InputFiles and symbol table
631// contain pointers to symbol objects. We visit them to replace pointers,
632// so that wrapped symbols are swapped as instructed by the command line.
633static void wrapSymbols(ArrayRef<WrappedSymbol> wrapped) {
634 DenseMap<Symbol *, Symbol *> map;
635 for (const WrappedSymbol &w : wrapped) {
636 map[w.sym] = w.wrap;
637 map[w.real] = w.sym;
638 }
639
640 // Update pointers in input files.
641 parallelForEach(symtab->objectFiles, [&](InputFile *file) {
642 MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
643 for (size_t i = 0, e = syms.size(); i != e; ++i)
644 if (Symbol *s = map.lookup(syms[i]))
645 syms[i] = s;
646 });
647
648 // Update pointers in the symbol table.
649 for (const WrappedSymbol &w : wrapped)
650 symtab->wrap(w.sym, w.real, w.wrap);
651}
652
653void LinkerDriver::link(ArrayRef<const char *> argsArr) {
654 WasmOptTable parser;
655 opt::InputArgList args = parser.parse(argsArr.slice(1));
505656
506657 // Handle --help
507 if (Args.hasArg(OPT_help)) {
508 Parser.PrintHelp(outs(),
509 (std::string(ArgsArr[0]) + " [options] file...").c_str(),
658 if (args.hasArg(OPT_help)) {
659 parser.PrintHelp(outs(),
660 (std::string(argsArr[0]) + " [options] file...").c_str(),
510661 "LLVM Linker", false);
511662 return;
512663 }
513664
514665 // Handle --version
515 if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) {
666 if (args.hasArg(OPT_version) || args.hasArg(OPT_v)) {
516667 outs() << getLLDVersion() << "\n";
517668 return;
518669 }
519670
671 // Handle --reproduce
672 if (auto *arg = args.getLastArg(OPT_reproduce)) {
673 StringRef path = arg->getValue();
674 Expected<std::unique_ptr<TarWriter>> errOrWriter =
675 TarWriter::create(path, path::stem(path));
676 if (errOrWriter) {
677 tar = std::move(*errOrWriter);
678 tar->append("response.txt", createResponseFile(args));
679 tar->append("version.txt", getLLDVersion() + "\n");
680 } else {
681 error("--reproduce: " + toString(errOrWriter.takeError()));
682 }
683 }
684
520685 // Parse and evaluate -mllvm options.
521 std::vector<const char *> V;
522 V.push_back("wasm-ld (LLVM option parsing)");
523 for (auto *Arg : Args.filtered(OPT_mllvm))
524 V.push_back(Arg->getValue());
525 cl::ParseCommandLineOptions(V.size(), V.data());
686 std::vector<const char *> v;
687 v.push_back("wasm-ld (LLVM option parsing)");
688 for (auto *arg : args.filtered(OPT_mllvm))
689 v.push_back(arg->getValue());
690 cl::ParseCommandLineOptions(v.size(), v.data());
526691
527 errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
692 errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20);
528693
529 setConfigs(Args);
530 checkOptions(Args);
694 readConfigs(args);
695 setConfigs();
696 checkOptions(args);
531697
532 if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))
533 readImportFile(Arg->getValue());
698 if (auto *arg = args.getLastArg(OPT_allow_undefined_file))
699 readImportFile(arg->getValue());
534700
535 if (!Args.hasArg(OPT_INPUT)) {
701 if (!args.hasArg(OPT_INPUT)) {
536702 error("no input files");
537703 return;
538704 }
539705
540 Config->Pic = Config->Pie || Config->Shared;
541
542 if (Config->Pic) {
543 if (Config->ExportTable)
544 error("-shared/-pie is incompatible with --export-table");
545 Config->ImportTable = true;
546 }
706 // Handle --trace-symbol.
707 for (auto *arg : args.filtered(OPT_trace_symbol))
708 symtab->trace(arg->getValue());
547709
548 if (Config->Shared) {
549 Config->ExportDynamic = true;
550 Config->AllowUndefined = true;
551 }
710 for (auto *arg : args.filtered(OPT_export))
711 config->exportedSymbols.insert(arg->getValue());
552712
553 if (!Config->Relocatable)
713 if (!config->relocatable)
554714 createSyntheticSymbols();
555715
556 createFiles(Args);
716 createFiles(args);
557717 if (errorCount())
558718 return;
559719
560720 // Add all files to the symbol table. This will add almost all
561721 // symbols that we need to the symbol table.
562 for (InputFile *F : Files)
563 Symtab->addFile(F);
722 for (InputFile *f : files)
723 symtab->addFile(f);
564724 if (errorCount())
565725 return;
566726
567727 // Handle the `--undefined <sym>` options.
568 for (auto *Arg : Args.filtered(OPT_undefined))
569 handleUndefined(Arg->getValue());
728 for (auto *arg : args.filtered(OPT_undefined))
729 handleUndefined(arg->getValue());
570730
571731 // Handle the `--export <sym>` options
572732 // This works like --undefined but also exports the symbol if its found
573 for (auto *Arg : Args.filtered(OPT_export)) {
574 Symbol *Sym = handleUndefined(Arg->getValue());
575 if (Sym && Sym->isDefined())
576 Sym->ForceExport = true;
577 else if (!Config->AllowUndefined)
578 error(Twine("symbol exported via --export not found: ") +
579 Arg->getValue());
580 }
581
582 Symbol *EntrySym = nullptr;
583 if (!Config->Relocatable) {
584 // Add synthetic dummies for weak undefined functions.
585 handleWeakUndefines();
586
587 if (!Config->Shared && !Config->Entry.empty()) {
588 EntrySym = handleUndefined(Config->Entry);
589 if (EntrySym && EntrySym->isDefined())
590 EntrySym->ForceExport = true;
591 else
592 error("entry symbol not defined (pass --no-entry to supress): " +
593 Config->Entry);
594 }
595
596 // Make sure we have resolved all symbols.
597 if (!Config->AllowUndefined)
598 Symtab->reportRemainingUndefines();
733 for (auto *arg : args.filtered(OPT_export))
734 handleUndefined(arg->getValue());
735
736 Symbol *entrySym = nullptr;
737 if (!config->relocatable && !config->entry.empty()) {
738 entrySym = handleUndefined(config->entry);
739 if (entrySym && entrySym->isDefined())
740 entrySym->forceExport = true;
741 else
742 error("entry symbol not defined (pass --no-entry to supress): " +
743 config->entry);
599744 }
600745
601746 if (errorCount())
602747 return;
603748
749 // Create wrapped symbols for -wrap option.
750 std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
751
604752 // Do link-time optimization if given files are LLVM bitcode files.
605753 // This compiles bitcode files into real object files.
606 Symtab->addCombinedLTOObject();
754 symtab->addCombinedLTOObject();
607755 if (errorCount())
608756 return;
609757
610 if (EntrySym)
611 EntrySym->setHidden(false);
758 // Resolve any variant symbols that were created due to signature
759 // mismatchs.
760 symtab->handleSymbolVariants();
761 if (errorCount())
762 return;
763
764 // Apply symbol renames for -wrap.
765 if (!wrapped.empty())
766 wrapSymbols(wrapped);
767
768 for (auto *arg : args.filtered(OPT_export)) {
769 Symbol *sym = symtab->find(arg->getValue());
770 if (sym && sym->isDefined())
771 sym->forceExport = true;
772 else if (!config->allowUndefined)
773 error(Twine("symbol exported via --export not found: ") +
774 arg->getValue());
775 }
776
777 if (!config->relocatable) {
778 // Add synthetic dummies for weak undefined functions. Must happen
779 // after LTO otherwise functions may not yet have signatures.
780 symtab->handleWeakUndefines();
781 }
782
783 if (entrySym)
784 entrySym->setHidden(false);
612785
613786 if (errorCount())
614787 return;
deps/lld/wasm/InputChunks.cpp+214-158
......@@ -1,9 +1,8 @@
11//===- InputChunks.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -23,8 +22,8 @@ using namespace llvm::support::endian;
2322using namespace lld;
2423using namespace lld::wasm;
2524
26static StringRef reloctTypeToString(uint8_t RelocType) {
27 switch (RelocType) {
25StringRef lld::relocTypeToString(uint8_t relocType) {
26 switch (relocType) {
2827#define WASM_RELOC(NAME, REL) \
2928 case REL: \
3029 return #NAME;
......@@ -34,62 +33,67 @@ static StringRef reloctTypeToString(uint8_t RelocType) {
3433 llvm_unreachable("unknown reloc type");
3534}
3635
37std::string lld::toString(const InputChunk *C) {
38 return (toString(C->File) + ":(" + C->getName() + ")").str();
36std::string lld::toString(const InputChunk *c) {
37 return (toString(c->file) + ":(" + c->getName() + ")").str();
3938}
4039
4140StringRef InputChunk::getComdatName() const {
42 uint32_t Index = getComdat();
43 if (Index == UINT32_MAX)
41 uint32_t index = getComdat();
42 if (index == UINT32_MAX)
4443 return StringRef();
45 return File->getWasmObj()->linkingData().Comdats[Index];
44 return file->getWasmObj()->linkingData().Comdats[index];
4645}
4746
4847void InputChunk::verifyRelocTargets() const {
49 for (const WasmRelocation &Rel : Relocations) {
50 uint32_t ExistingValue;
51 unsigned BytesRead = 0;
52 uint32_t Offset = Rel.Offset - getInputSectionOffset();
53 const uint8_t *Loc = data().data() + Offset;
54 switch (Rel.Type) {
55 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
56 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
57 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
58 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
59 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
60 ExistingValue = decodeULEB128(Loc, &BytesRead);
48 for (const WasmRelocation &rel : relocations) {
49 uint32_t existingValue;
50 unsigned bytesRead = 0;
51 uint32_t offset = rel.Offset - getInputSectionOffset();
52 const uint8_t *loc = data().data() + offset;
53 switch (rel.Type) {
54 case R_WASM_TYPE_INDEX_LEB:
55 case R_WASM_FUNCTION_INDEX_LEB:
56 case R_WASM_GLOBAL_INDEX_LEB:
57 case R_WASM_EVENT_INDEX_LEB:
58 case R_WASM_MEMORY_ADDR_LEB:
59 existingValue = decodeULEB128(loc, &bytesRead);
6160 break;
62 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
63 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
64 ExistingValue = static_cast<uint32_t>(decodeSLEB128(Loc, &BytesRead));
61 case R_WASM_TABLE_INDEX_SLEB:
62 case R_WASM_TABLE_INDEX_REL_SLEB:
63 case R_WASM_MEMORY_ADDR_SLEB:
64 case R_WASM_MEMORY_ADDR_REL_SLEB:
65 existingValue = static_cast<uint32_t>(decodeSLEB128(loc, &bytesRead));
6566 break;
66 case R_WEBASSEMBLY_TABLE_INDEX_I32:
67 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
68 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
69 case R_WEBASSEMBLY_SECTION_OFFSET_I32:
70 ExistingValue = static_cast<uint32_t>(read32le(Loc));
67 case R_WASM_TABLE_INDEX_I32:
68 case R_WASM_MEMORY_ADDR_I32:
69 case R_WASM_FUNCTION_OFFSET_I32:
70 case R_WASM_SECTION_OFFSET_I32:
71 existingValue = static_cast<uint32_t>(read32le(loc));
7172 break;
7273 default:
7374 llvm_unreachable("unknown relocation type");
7475 }
7576
76 if (BytesRead && BytesRead != 5)
77 if (bytesRead && bytesRead != 5)
7778 warn("expected LEB at relocation site be 5-byte padded");
78 uint32_t ExpectedValue = File->calcExpectedValue(Rel);
79 if (ExpectedValue != ExistingValue)
80 warn("unexpected existing value for " + reloctTypeToString(Rel.Type) +
81 ": existing=" + Twine(ExistingValue) +
82 " expected=" + Twine(ExpectedValue));
79
80 if (rel.Type != R_WASM_GLOBAL_INDEX_LEB) {
81 uint32_t expectedValue = file->calcExpectedValue(rel);
82 if (expectedValue != existingValue)
83 warn("unexpected existing value for " + relocTypeToString(rel.Type) +
84 ": existing=" + Twine(existingValue) +
85 " expected=" + Twine(expectedValue));
86 }
8387 }
8488}
8589
8690// Copy this input chunk to an mmap'ed output file and apply relocations.
87void InputChunk::writeTo(uint8_t *Buf) const {
91void InputChunk::writeTo(uint8_t *buf) const {
8892 // Copy contents
89 memcpy(Buf + OutputOffset, data().data(), data().size());
93 memcpy(buf + outputOffset, data().data(), data().size());
9094
9195 // Apply relocations
92 if (Relocations.empty())
96 if (relocations.empty())
9397 return;
9498
9599#ifndef NDEBUG
......@@ -97,34 +101,38 @@ void InputChunk::writeTo(uint8_t *Buf) const {
97101#endif
98102
99103 LLVM_DEBUG(dbgs() << "applying relocations: " << getName()
100 << " count=" << Relocations.size() << "\n");
101 int32_t Off = OutputOffset - getInputSectionOffset();
102
103 for (const WasmRelocation &Rel : Relocations) {
104 uint8_t *Loc = Buf + Rel.Offset + Off;
105 uint32_t Value = File->calcNewValue(Rel);
106 LLVM_DEBUG(dbgs() << "apply reloc: type=" << reloctTypeToString(Rel.Type)
107 << " addend=" << Rel.Addend << " index=" << Rel.Index
108 << " value=" << Value << " offset=" << Rel.Offset
104 << " count=" << relocations.size() << "\n");
105 int32_t off = outputOffset - getInputSectionOffset();
106
107 for (const WasmRelocation &rel : relocations) {
108 uint8_t *loc = buf + rel.Offset + off;
109 uint32_t value = file->calcNewValue(rel);
110 LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(rel.Type));
111 if (rel.Type != R_WASM_TYPE_INDEX_LEB)
112 LLVM_DEBUG(dbgs() << " sym=" << file->getSymbols()[rel.Index]->getName());
113 LLVM_DEBUG(dbgs() << " addend=" << rel.Addend << " index=" << rel.Index
114 << " value=" << value << " offset=" << rel.Offset
109115 << "\n");
110116
111 switch (Rel.Type) {
112 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
113 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
114 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
115 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
116 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
117 encodeULEB128(Value, Loc, 5);
117 switch (rel.Type) {
118 case R_WASM_TYPE_INDEX_LEB:
119 case R_WASM_FUNCTION_INDEX_LEB:
120 case R_WASM_GLOBAL_INDEX_LEB:
121 case R_WASM_EVENT_INDEX_LEB:
122 case R_WASM_MEMORY_ADDR_LEB:
123 encodeULEB128(value, loc, 5);
118124 break;
119 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
120 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
121 encodeSLEB128(static_cast<int32_t>(Value), Loc, 5);
125 case R_WASM_TABLE_INDEX_SLEB:
126 case R_WASM_TABLE_INDEX_REL_SLEB:
127 case R_WASM_MEMORY_ADDR_SLEB:
128 case R_WASM_MEMORY_ADDR_REL_SLEB:
129 encodeSLEB128(static_cast<int32_t>(value), loc, 5);
122130 break;
123 case R_WEBASSEMBLY_TABLE_INDEX_I32:
124 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
125 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
126 case R_WEBASSEMBLY_SECTION_OFFSET_I32:
127 write32le(Loc, Value);
131 case R_WASM_TABLE_INDEX_I32:
132 case R_WASM_MEMORY_ADDR_I32:
133 case R_WASM_FUNCTION_OFFSET_I32:
134 case R_WASM_SECTION_OFFSET_I32:
135 write32le(loc, value);
128136 break;
129137 default:
130138 llvm_unreachable("unknown relocation type");
......@@ -135,82 +143,75 @@ void InputChunk::writeTo(uint8_t *Buf) const {
135143// Copy relocation entries to a given output stream.
136144// This function is used only when a user passes "-r". For a regular link,
137145// we consume relocations instead of copying them to an output file.
138void InputChunk::writeRelocations(raw_ostream &OS) const {
139 if (Relocations.empty())
146void InputChunk::writeRelocations(raw_ostream &os) const {
147 if (relocations.empty())
140148 return;
141149
142 int32_t Off = OutputOffset - getInputSectionOffset();
143 LLVM_DEBUG(dbgs() << "writeRelocations: " << File->getName()
144 << " offset=" << Twine(Off) << "\n");
145
146 for (const WasmRelocation &Rel : Relocations) {
147 writeUleb128(OS, Rel.Type, "reloc type");
148 writeUleb128(OS, Rel.Offset + Off, "reloc offset");
149 writeUleb128(OS, File->calcNewIndex(Rel), "reloc index");
150
151 switch (Rel.Type) {
152 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
153 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
154 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
155 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
156 case R_WEBASSEMBLY_SECTION_OFFSET_I32:
157 writeSleb128(OS, File->calcNewAddend(Rel), "reloc addend");
158 break;
159 }
150 int32_t off = outputOffset - getInputSectionOffset();
151 LLVM_DEBUG(dbgs() << "writeRelocations: " << file->getName()
152 << " offset=" << Twine(off) << "\n");
153
154 for (const WasmRelocation &rel : relocations) {
155 writeUleb128(os, rel.Type, "reloc type");
156 writeUleb128(os, rel.Offset + off, "reloc offset");
157 writeUleb128(os, file->calcNewIndex(rel), "reloc index");
158
159 if (relocTypeHasAddend(rel.Type))
160 writeSleb128(os, file->calcNewAddend(rel), "reloc addend");
160161 }
161162}
162163
163void InputFunction::setFunctionIndex(uint32_t Index) {
164void InputFunction::setFunctionIndex(uint32_t index) {
164165 LLVM_DEBUG(dbgs() << "InputFunction::setFunctionIndex: " << getName()
165 << " -> " << Index << "\n");
166 << " -> " << index << "\n");
166167 assert(!hasFunctionIndex());
167 FunctionIndex = Index;
168 functionIndex = index;
168169}
169170
170void InputFunction::setTableIndex(uint32_t Index) {
171void InputFunction::setTableIndex(uint32_t index) {
171172 LLVM_DEBUG(dbgs() << "InputFunction::setTableIndex: " << getName() << " -> "
172 << Index << "\n");
173 << index << "\n");
173174 assert(!hasTableIndex());
174 TableIndex = Index;
175 tableIndex = index;
175176}
176177
177178// Write a relocation value without padding and return the number of bytes
178179// witten.
179static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel,
180 uint32_t Value) {
181 switch (Rel.Type) {
182 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
183 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
184 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
185 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
186 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
187 return encodeULEB128(Value, Buf);
188 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
189 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
190 return encodeSLEB128(static_cast<int32_t>(Value), Buf);
180static unsigned writeCompressedReloc(uint8_t *buf, const WasmRelocation &rel,
181 uint32_t value) {
182 switch (rel.Type) {
183 case R_WASM_TYPE_INDEX_LEB:
184 case R_WASM_FUNCTION_INDEX_LEB:
185 case R_WASM_GLOBAL_INDEX_LEB:
186 case R_WASM_EVENT_INDEX_LEB:
187 case R_WASM_MEMORY_ADDR_LEB:
188 return encodeULEB128(value, buf);
189 case R_WASM_TABLE_INDEX_SLEB:
190 case R_WASM_MEMORY_ADDR_SLEB:
191 return encodeSLEB128(static_cast<int32_t>(value), buf);
191192 default:
192193 llvm_unreachable("unexpected relocation type");
193194 }
194195}
195196
196static unsigned getRelocWidthPadded(const WasmRelocation &Rel) {
197 switch (Rel.Type) {
198 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
199 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
200 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
201 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
202 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
203 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
204 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
197static unsigned getRelocWidthPadded(const WasmRelocation &rel) {
198 switch (rel.Type) {
199 case R_WASM_TYPE_INDEX_LEB:
200 case R_WASM_FUNCTION_INDEX_LEB:
201 case R_WASM_GLOBAL_INDEX_LEB:
202 case R_WASM_EVENT_INDEX_LEB:
203 case R_WASM_MEMORY_ADDR_LEB:
204 case R_WASM_TABLE_INDEX_SLEB:
205 case R_WASM_MEMORY_ADDR_SLEB:
205206 return 5;
206207 default:
207208 llvm_unreachable("unexpected relocation type");
208209 }
209210}
210211
211static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) {
212 uint8_t Buf[5];
213 return writeCompressedReloc(Buf, Rel, Value);
212static unsigned getRelocWidth(const WasmRelocation &rel, uint32_t value) {
213 uint8_t buf[5];
214 return writeCompressedReloc(buf, rel, value);
214215}
215216
216217// Relocations of type LEB and SLEB in the code section are padded to 5 bytes
......@@ -224,69 +225,124 @@ static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) {
224225// This function only computes the final output size. It must be called
225226// before getSize() is used to calculate of layout of the code section.
226227void InputFunction::calculateSize() {
227 if (!File || !Config->CompressRelocations)
228 if (!file || !config->compressRelocations)
228229 return;
229230
230231 LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n");
231232
232 const uint8_t *SecStart = File->CodeSection->Content.data();
233 const uint8_t *FuncStart = SecStart + getInputSectionOffset();
234 uint32_t FunctionSizeLength;
235 decodeULEB128(FuncStart, &FunctionSizeLength);
233 const uint8_t *secStart = file->codeSection->Content.data();
234 const uint8_t *funcStart = secStart + getInputSectionOffset();
235 uint32_t functionSizeLength;
236 decodeULEB128(funcStart, &functionSizeLength);
236237
237 uint32_t Start = getInputSectionOffset();
238 uint32_t End = Start + Function->Size;
238 uint32_t start = getInputSectionOffset();
239 uint32_t end = start + function->Size;
239240
240 uint32_t LastRelocEnd = Start + FunctionSizeLength;
241 for (const WasmRelocation &Rel : Relocations) {
242 LLVM_DEBUG(dbgs() << " region: " << (Rel.Offset - LastRelocEnd) << "\n");
243 CompressedFuncSize += Rel.Offset - LastRelocEnd;
244 CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel));
245 LastRelocEnd = Rel.Offset + getRelocWidthPadded(Rel);
241 uint32_t lastRelocEnd = start + functionSizeLength;
242 for (const WasmRelocation &rel : relocations) {
243 LLVM_DEBUG(dbgs() << " region: " << (rel.Offset - lastRelocEnd) << "\n");
244 compressedFuncSize += rel.Offset - lastRelocEnd;
245 compressedFuncSize += getRelocWidth(rel, file->calcNewValue(rel));
246 lastRelocEnd = rel.Offset + getRelocWidthPadded(rel);
246247 }
247 LLVM_DEBUG(dbgs() << " final region: " << (End - LastRelocEnd) << "\n");
248 CompressedFuncSize += End - LastRelocEnd;
248 LLVM_DEBUG(dbgs() << " final region: " << (end - lastRelocEnd) << "\n");
249 compressedFuncSize += end - lastRelocEnd;
249250
250251 // Now we know how long the resulting function is we can add the encoding
251252 // of its length
252 uint8_t Buf[5];
253 CompressedSize = CompressedFuncSize + encodeULEB128(CompressedFuncSize, Buf);
253 uint8_t buf[5];
254 compressedSize = compressedFuncSize + encodeULEB128(compressedFuncSize, buf);
254255
255 LLVM_DEBUG(dbgs() << " calculateSize orig: " << Function->Size << "\n");
256 LLVM_DEBUG(dbgs() << " calculateSize new: " << CompressedSize << "\n");
256 LLVM_DEBUG(dbgs() << " calculateSize orig: " << function->Size << "\n");
257 LLVM_DEBUG(dbgs() << " calculateSize new: " << compressedSize << "\n");
257258}
258259
259260// Override the default writeTo method so that we can (optionally) write the
260261// compressed version of the function.
261void InputFunction::writeTo(uint8_t *Buf) const {
262 if (!File || !Config->CompressRelocations)
263 return InputChunk::writeTo(Buf);
262void InputFunction::writeTo(uint8_t *buf) const {
263 if (!file || !config->compressRelocations)
264 return InputChunk::writeTo(buf);
264265
265 Buf += OutputOffset;
266 uint8_t *Orig = Buf;
267 (void)Orig;
266 buf += outputOffset;
267 uint8_t *orig = buf;
268 (void)orig;
268269
269 const uint8_t *SecStart = File->CodeSection->Content.data();
270 const uint8_t *FuncStart = SecStart + getInputSectionOffset();
271 const uint8_t *End = FuncStart + Function->Size;
272 uint32_t Count;
273 decodeULEB128(FuncStart, &Count);
274 FuncStart += Count;
270 const uint8_t *secStart = file->codeSection->Content.data();
271 const uint8_t *funcStart = secStart + getInputSectionOffset();
272 const uint8_t *end = funcStart + function->Size;
273 uint32_t count;
274 decodeULEB128(funcStart, &count);
275 funcStart += count;
275276
276277 LLVM_DEBUG(dbgs() << "write func: " << getName() << "\n");
277 Buf += encodeULEB128(CompressedFuncSize, Buf);
278 const uint8_t *LastRelocEnd = FuncStart;
279 for (const WasmRelocation &Rel : Relocations) {
280 unsigned ChunkSize = (SecStart + Rel.Offset) - LastRelocEnd;
281 LLVM_DEBUG(dbgs() << " write chunk: " << ChunkSize << "\n");
282 memcpy(Buf, LastRelocEnd, ChunkSize);
283 Buf += ChunkSize;
284 Buf += writeCompressedReloc(Buf, Rel, File->calcNewValue(Rel));
285 LastRelocEnd = SecStart + Rel.Offset + getRelocWidthPadded(Rel);
278 buf += encodeULEB128(compressedFuncSize, buf);
279 const uint8_t *lastRelocEnd = funcStart;
280 for (const WasmRelocation &rel : relocations) {
281 unsigned chunkSize = (secStart + rel.Offset) - lastRelocEnd;
282 LLVM_DEBUG(dbgs() << " write chunk: " << chunkSize << "\n");
283 memcpy(buf, lastRelocEnd, chunkSize);
284 buf += chunkSize;
285 buf += writeCompressedReloc(buf, rel, file->calcNewValue(rel));
286 lastRelocEnd = secStart + rel.Offset + getRelocWidthPadded(rel);
286287 }
287288
288 unsigned ChunkSize = End - LastRelocEnd;
289 LLVM_DEBUG(dbgs() << " write final chunk: " << ChunkSize << "\n");
290 memcpy(Buf, LastRelocEnd, ChunkSize);
291 LLVM_DEBUG(dbgs() << " total: " << (Buf + ChunkSize - Orig) << "\n");
289 unsigned chunkSize = end - lastRelocEnd;
290 LLVM_DEBUG(dbgs() << " write final chunk: " << chunkSize << "\n");
291 memcpy(buf, lastRelocEnd, chunkSize);
292 LLVM_DEBUG(dbgs() << " total: " << (buf + chunkSize - orig) << "\n");
293}
294
295// Generate code to apply relocations to the data section at runtime.
296// This is only called when generating shared libaries (PIC) where address are
297// not known at static link time.
298void InputSegment::generateRelocationCode(raw_ostream &os) const {
299 LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName()
300 << " count=" << relocations.size() << "\n");
301
302 // TODO(sbc): Encode the relocations in the data section and write a loop
303 // here to apply them.
304 uint32_t segmentVA = outputSeg->startVA + outputSegmentOffset;
305 for (const WasmRelocation &rel : relocations) {
306 uint32_t offset = rel.Offset - getInputSectionOffset();
307 uint32_t outputOffset = segmentVA + offset;
308
309 LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type)
310 << " addend=" << rel.Addend << " index=" << rel.Index
311 << " output offset=" << outputOffset << "\n");
312
313 // Get __memory_base
314 writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
315 writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), "memory_base");
316
317 // Add the offset of the relocation
318 writeU8(os, WASM_OPCODE_I32_CONST, "I32_CONST");
319 writeSleb128(os, outputOffset, "offset");
320 writeU8(os, WASM_OPCODE_I32_ADD, "ADD");
321
322 Symbol *sym = file->getSymbol(rel);
323 // Now figure out what we want to store
324 if (sym->hasGOTIndex()) {
325 writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
326 writeUleb128(os, sym->getGOTIndex(), "global index");
327 if (rel.Addend) {
328 writeU8(os, WASM_OPCODE_I32_CONST, "CONST");
329 writeSleb128(os, rel.Addend, "addend");
330 writeU8(os, WASM_OPCODE_I32_ADD, "ADD");
331 }
332 } else {
333 const GlobalSymbol* baseSymbol = WasmSym::memoryBase;
334 if (rel.Type == R_WASM_TABLE_INDEX_I32)
335 baseSymbol = WasmSym::tableBase;
336 writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
337 writeUleb128(os, baseSymbol->getGlobalIndex(), "base");
338 writeU8(os, WASM_OPCODE_I32_CONST, "CONST");
339 writeSleb128(os, file->calcNewValue(rel), "offset");
340 writeU8(os, WASM_OPCODE_I32_ADD, "ADD");
341 }
342
343 // Store that value at the virtual address
344 writeU8(os, WASM_OPCODE_I32_STORE, "I32_STORE");
345 writeUleb128(os, 2, "align");
346 writeUleb128(os, 0, "offset");
347 }
292348}
deps/lld/wasm/InputChunks.h+86-77
......@@ -1,9 +1,8 @@
11//===- InputChunks.h --------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -32,20 +31,21 @@ namespace wasm {
3231
3332class ObjFile;
3433class OutputSegment;
34class OutputSection;
3535
3636class InputChunk {
3737public:
3838 enum Kind { DataSegment, Function, SyntheticFunction, Section };
3939
40 Kind kind() const { return SectionKind; }
40 Kind kind() const { return sectionKind; }
4141
4242 virtual uint32_t getSize() const { return data().size(); }
4343 virtual uint32_t getInputSize() const { return getSize(); };
4444
45 virtual void writeTo(uint8_t *SectionStart) const;
45 virtual void writeTo(uint8_t *sectionStart) const;
4646
47 ArrayRef<WasmRelocation> getRelocations() const { return Relocations; }
48 void setRelocations(ArrayRef<WasmRelocation> Rs) { Relocations = Rs; }
47 ArrayRef<WasmRelocation> getRelocations() const { return relocations; }
48 void setRelocations(ArrayRef<WasmRelocation> rs) { relocations = rs; }
4949
5050 virtual StringRef getName() const = 0;
5151 virtual StringRef getDebugName() const = 0;
......@@ -53,20 +53,23 @@ public:
5353 StringRef getComdatName() const;
5454 virtual uint32_t getInputSectionOffset() const = 0;
5555
56 size_t NumRelocations() const { return Relocations.size(); }
57 void writeRelocations(llvm::raw_ostream &OS) const;
56 size_t getNumRelocations() const { return relocations.size(); }
57 void writeRelocations(llvm::raw_ostream &os) const;
5858
59 ObjFile *File;
60 int32_t OutputOffset = 0;
59 ObjFile *file;
60 int32_t outputOffset = 0;
6161
6262 // Signals that the section is part of the output. The garbage collector,
6363 // and COMDAT handling can set a sections' Live bit.
6464 // If GC is disabled, all sections start out as live by default.
65 unsigned Live : 1;
65 unsigned live : 1;
66
67 // Signals the chunk was discarded by COMDAT handling.
68 unsigned discarded : 1;
6669
6770protected:
68 InputChunk(ObjFile *F, Kind K)
69 : File(F), Live(!Config->GcSections), SectionKind(K) {}
71 InputChunk(ObjFile *f, Kind k)
72 : file(f), live(!config->gcSections), discarded(false), sectionKind(k) {}
7073 virtual ~InputChunk() = default;
7174 virtual ArrayRef<uint8_t> data() const = 0;
7275
......@@ -74,8 +77,8 @@ protected:
7477 // This is performed only debug builds as an extra sanity check.
7578 void verifyRelocTargets() const;
7679
77 ArrayRef<WasmRelocation> Relocations;
78 Kind SectionKind;
80 ArrayRef<WasmRelocation> relocations;
81 Kind sectionKind;
7982};
8083
8184// Represents a WebAssembly data segment which can be included as part of
......@@ -88,63 +91,65 @@ protected:
8891// each global variable.
8992class InputSegment : public InputChunk {
9093public:
91 InputSegment(const WasmSegment &Seg, ObjFile *F)
92 : InputChunk(F, InputChunk::DataSegment), Segment(Seg) {}
94 InputSegment(const WasmSegment &seg, ObjFile *f)
95 : InputChunk(f, InputChunk::DataSegment), segment(seg) {}
96
97 static bool classof(const InputChunk *c) { return c->kind() == DataSegment; }
9398
94 static bool classof(const InputChunk *C) { return C->kind() == DataSegment; }
99 void generateRelocationCode(raw_ostream &os) const;
95100
96 uint32_t getAlignment() const { return Segment.Data.Alignment; }
97 StringRef getName() const override { return Segment.Data.Name; }
101 uint32_t getAlignment() const { return segment.Data.Alignment; }
102 StringRef getName() const override { return segment.Data.Name; }
98103 StringRef getDebugName() const override { return StringRef(); }
99 uint32_t getComdat() const override { return Segment.Data.Comdat; }
104 uint32_t getComdat() const override { return segment.Data.Comdat; }
100105 uint32_t getInputSectionOffset() const override {
101 return Segment.SectionOffset;
106 return segment.SectionOffset;
102107 }
103108
104 const OutputSegment *OutputSeg = nullptr;
105 int32_t OutputSegmentOffset = 0;
109 const OutputSegment *outputSeg = nullptr;
110 int32_t outputSegmentOffset = 0;
106111
107112protected:
108 ArrayRef<uint8_t> data() const override { return Segment.Data.Content; }
113 ArrayRef<uint8_t> data() const override { return segment.Data.Content; }
109114
110 const WasmSegment &Segment;
115 const WasmSegment &segment;
111116};
112117
113118// Represents a single wasm function within and input file. These are
114119// combined to create the final output CODE section.
115120class InputFunction : public InputChunk {
116121public:
117 InputFunction(const WasmSignature &S, const WasmFunction *Func, ObjFile *F)
118 : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {}
122 InputFunction(const WasmSignature &s, const WasmFunction *func, ObjFile *f)
123 : InputChunk(f, InputChunk::Function), signature(s), function(func) {}
119124
120 static bool classof(const InputChunk *C) {
121 return C->kind() == InputChunk::Function ||
122 C->kind() == InputChunk::SyntheticFunction;
125 static bool classof(const InputChunk *c) {
126 return c->kind() == InputChunk::Function ||
127 c->kind() == InputChunk::SyntheticFunction;
123128 }
124129
125 void writeTo(uint8_t *SectionStart) const override;
126 StringRef getName() const override { return Function->SymbolName; }
127 StringRef getDebugName() const override { return Function->DebugName; }
128 uint32_t getComdat() const override { return Function->Comdat; }
130 void writeTo(uint8_t *sectionStart) const override;
131 StringRef getName() const override { return function->SymbolName; }
132 StringRef getDebugName() const override { return function->DebugName; }
133 uint32_t getComdat() const override { return function->Comdat; }
129134 uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); }
130 uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; }
135 uint32_t getFunctionCodeOffset() const { return function->CodeOffset; }
131136 uint32_t getSize() const override {
132 if (Config->CompressRelocations && File) {
133 assert(CompressedSize);
134 return CompressedSize;
137 if (config->compressRelocations && file) {
138 assert(compressedSize);
139 return compressedSize;
135140 }
136141 return data().size();
137142 }
138 uint32_t getInputSize() const override { return Function->Size; }
139 uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); }
140 bool hasFunctionIndex() const { return FunctionIndex.hasValue(); }
141 void setFunctionIndex(uint32_t Index);
143 uint32_t getInputSize() const override { return function->Size; }
144 uint32_t getFunctionIndex() const { return functionIndex.getValue(); }
145 bool hasFunctionIndex() const { return functionIndex.hasValue(); }
146 void setFunctionIndex(uint32_t index);
142147 uint32_t getInputSectionOffset() const override {
143 return Function->CodeSectionOffset;
148 return function->CodeSectionOffset;
144149 }
145 uint32_t getTableIndex() const { return TableIndex.getValue(); }
146 bool hasTableIndex() const { return TableIndex.hasValue(); }
147 void setTableIndex(uint32_t Index);
150 uint32_t getTableIndex() const { return tableIndex.getValue(); }
151 bool hasTableIndex() const { return tableIndex.hasValue(); }
152 void setTableIndex(uint32_t index);
148153
149154 // The size of a given input function can depend on the values of the
150155 // LEB relocations within it. This finalizeContents method is called after
......@@ -152,73 +157,77 @@ public:
152157 // called.
153158 void calculateSize();
154159
155 const WasmSignature &Signature;
160 const WasmSignature &signature;
156161
157162protected:
158163 ArrayRef<uint8_t> data() const override {
159 assert(!Config->CompressRelocations);
160 return File->CodeSection->Content.slice(getInputSectionOffset(),
161 Function->Size);
164 assert(!config->compressRelocations);
165 return file->codeSection->Content.slice(getInputSectionOffset(),
166 function->Size);
162167 }
163168
164 const WasmFunction *Function;
165 llvm::Optional<uint32_t> FunctionIndex;
166 llvm::Optional<uint32_t> TableIndex;
167 uint32_t CompressedFuncSize = 0;
168 uint32_t CompressedSize = 0;
169 const WasmFunction *function;
170 llvm::Optional<uint32_t> functionIndex;
171 llvm::Optional<uint32_t> tableIndex;
172 uint32_t compressedFuncSize = 0;
173 uint32_t compressedSize = 0;
169174};
170175
171176class SyntheticFunction : public InputFunction {
172177public:
173 SyntheticFunction(const WasmSignature &S, StringRef Name,
174 StringRef DebugName = {})
175 : InputFunction(S, nullptr, nullptr), Name(Name), DebugName(DebugName) {
176 SectionKind = InputChunk::SyntheticFunction;
178 SyntheticFunction(const WasmSignature &s, StringRef name,
179 StringRef debugName = {})
180 : InputFunction(s, nullptr, nullptr), name(name), debugName(debugName) {
181 sectionKind = InputChunk::SyntheticFunction;
177182 }
178183
179 static bool classof(const InputChunk *C) {
180 return C->kind() == InputChunk::SyntheticFunction;
184 static bool classof(const InputChunk *c) {
185 return c->kind() == InputChunk::SyntheticFunction;
181186 }
182187
183 StringRef getName() const override { return Name; }
184 StringRef getDebugName() const override { return DebugName; }
188 StringRef getName() const override { return name; }
189 StringRef getDebugName() const override { return debugName; }
185190 uint32_t getComdat() const override { return UINT32_MAX; }
186191
187 void setBody(ArrayRef<uint8_t> Body_) { Body = Body_; }
192 void setBody(ArrayRef<uint8_t> body_) { body = body_; }
188193
189194protected:
190 ArrayRef<uint8_t> data() const override { return Body; }
195 ArrayRef<uint8_t> data() const override { return body; }
191196
192 StringRef Name;
193 StringRef DebugName;
194 ArrayRef<uint8_t> Body;
197 StringRef name;
198 StringRef debugName;
199 ArrayRef<uint8_t> body;
195200};
196201
197202// Represents a single Wasm Section within an input file.
198203class InputSection : public InputChunk {
199204public:
200 InputSection(const WasmSection &S, ObjFile *F)
201 : InputChunk(F, InputChunk::Section), Section(S) {
202 assert(Section.Type == llvm::wasm::WASM_SEC_CUSTOM);
205 InputSection(const WasmSection &s, ObjFile *f)
206 : InputChunk(f, InputChunk::Section), section(s) {
207 assert(section.Type == llvm::wasm::WASM_SEC_CUSTOM);
203208 }
204209
205 StringRef getName() const override { return Section.Name; }
210 StringRef getName() const override { return section.Name; }
206211 StringRef getDebugName() const override { return StringRef(); }
207212 uint32_t getComdat() const override { return UINT32_MAX; }
208213
214 OutputSection *outputSec = nullptr;
215
209216protected:
210 ArrayRef<uint8_t> data() const override { return Section.Content; }
217 ArrayRef<uint8_t> data() const override { return section.Content; }
211218
212219 // Offset within the input section. This is only zero since this chunk
213220 // type represents an entire input section, not part of one.
214221 uint32_t getInputSectionOffset() const override { return 0; }
215222
216 const WasmSection &Section;
223 const WasmSection &section;
217224};
218225
219226} // namespace wasm
220227
221228std::string toString(const wasm::InputChunk *);
229StringRef relocTypeToString(uint8_t relocType);
230
222231} // namespace lld
223232
224233#endif // LLD_WASM_INPUT_CHUNKS_H
deps/lld/wasm/InputEvent.h+18-19
......@@ -1,9 +1,8 @@
11//===- InputEvent.h ---------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -29,33 +28,33 @@ namespace wasm {
2928// form the final EVENTS section.
3029class InputEvent {
3130public:
32 InputEvent(const WasmSignature &S, const WasmEvent &E, ObjFile *F)
33 : File(F), Event(E), Signature(S), Live(!Config->GcSections) {}
31 InputEvent(const WasmSignature &s, const WasmEvent &e, ObjFile *f)
32 : file(f), event(e), signature(s), live(!config->gcSections) {}
3433
35 StringRef getName() const { return Event.SymbolName; }
36 const WasmEventType &getType() const { return Event.Type; }
34 StringRef getName() const { return event.SymbolName; }
35 const WasmEventType &getType() const { return event.Type; }
3736
38 uint32_t getEventIndex() const { return EventIndex.getValue(); }
39 bool hasEventIndex() const { return EventIndex.hasValue(); }
40 void setEventIndex(uint32_t Index) {
37 uint32_t getEventIndex() const { return eventIndex.getValue(); }
38 bool hasEventIndex() const { return eventIndex.hasValue(); }
39 void setEventIndex(uint32_t index) {
4140 assert(!hasEventIndex());
42 EventIndex = Index;
41 eventIndex = index;
4342 }
4443
45 ObjFile *File;
46 WasmEvent Event;
47 const WasmSignature &Signature;
44 ObjFile *file;
45 WasmEvent event;
46 const WasmSignature &signature;
4847
49 bool Live = false;
48 bool live = false;
5049
5150protected:
52 llvm::Optional<uint32_t> EventIndex;
51 llvm::Optional<uint32_t> eventIndex;
5352};
5453
5554} // namespace wasm
5655
57inline std::string toString(const wasm::InputEvent *E) {
58 return (toString(E->File) + ":(" + E->getName() + ")").str();
56inline std::string toString(const wasm::InputEvent *e) {
57 return (toString(e->file) + ":(" + e->getName() + ")").str();
5958}
6059
6160} // namespace lld
deps/lld/wasm/InputFiles.cpp+353-289
......@@ -1,9 +1,8 @@
11//===- InputFiles.cpp -----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -15,8 +14,10 @@
1514#include "SymbolTable.h"
1615#include "lld/Common/ErrorHandler.h"
1716#include "lld/Common/Memory.h"
17#include "lld/Common/Reproduce.h"
1818#include "llvm/Object/Binary.h"
1919#include "llvm/Object/Wasm.h"
20#include "llvm/Support/TarWriter.h"
2021#include "llvm/Support/raw_ostream.h"
2122
2223#define DEBUG_TYPE "lld"
......@@ -28,62 +29,77 @@ using namespace llvm;
2829using namespace llvm::object;
2930using namespace llvm::wasm;
3031
31Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) {
32 log("Loading: " + Path);
32std::unique_ptr<llvm::TarWriter> lld::wasm::tar;
33
34Optional<MemoryBufferRef> lld::wasm::readFile(StringRef path) {
35 log("Loading: " + path);
3336
34 auto MBOrErr = MemoryBuffer::getFile(Path);
35 if (auto EC = MBOrErr.getError()) {
36 error("cannot open " + Path + ": " + EC.message());
37 auto mbOrErr = MemoryBuffer::getFile(path);
38 if (auto ec = mbOrErr.getError()) {
39 error("cannot open " + path + ": " + ec.message());
3740 return None;
3841 }
39 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
40 MemoryBufferRef MBRef = MB->getMemBufferRef();
41 make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
42 std::unique_ptr<MemoryBuffer> &mb = *mbOrErr;
43 MemoryBufferRef mbref = mb->getMemBufferRef();
44 make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take MB ownership
4245
43 return MBRef;
46 if (tar)
47 tar->append(relativeToRoot(path), mbref.getBuffer());
48 return mbref;
4449}
4550
46InputFile *lld::wasm::createObjectFile(MemoryBufferRef MB) {
47 file_magic Magic = identify_magic(MB.getBuffer());
48 if (Magic == file_magic::wasm_object)
49 return make<ObjFile>(MB);
51InputFile *lld::wasm::createObjectFile(MemoryBufferRef mb,
52 StringRef archiveName) {
53 file_magic magic = identify_magic(mb.getBuffer());
54 if (magic == file_magic::wasm_object) {
55 std::unique_ptr<Binary> bin =
56 CHECK(createBinary(mb), mb.getBufferIdentifier());
57 auto *obj = cast<WasmObjectFile>(bin.get());
58 if (obj->isSharedObject())
59 return make<SharedFile>(mb);
60 return make<ObjFile>(mb, archiveName);
61 }
5062
51 if (Magic == file_magic::bitcode)
52 return make<BitcodeFile>(MB);
63 if (magic == file_magic::bitcode)
64 return make<BitcodeFile>(mb, archiveName);
5365
54 fatal("unknown file type: " + MB.getBufferIdentifier());
66 fatal("unknown file type: " + mb.getBufferIdentifier());
5567}
5668
5769void ObjFile::dumpInfo() const {
58 log("info for: " + getName() +
59 "\n Symbols : " + Twine(Symbols.size()) +
60 "\n Function Imports : " + Twine(WasmObj->getNumImportedFunctions()) +
61 "\n Global Imports : " + Twine(WasmObj->getNumImportedGlobals()) +
62 "\n Event Imports : " + Twine(WasmObj->getNumImportedEvents()));
70 log("info for: " + toString(this) +
71 "\n Symbols : " + Twine(symbols.size()) +
72 "\n Function Imports : " + Twine(wasmObj->getNumImportedFunctions()) +
73 "\n Global Imports : " + Twine(wasmObj->getNumImportedGlobals()) +
74 "\n Event Imports : " + Twine(wasmObj->getNumImportedEvents()));
6375}
6476
6577// Relocations contain either symbol or type indices. This function takes a
6678// relocation and returns relocated index (i.e. translates from the input
6779// symbol/type space to the output symbol/type space).
68uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
69 if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
70 assert(TypeIsUsed[Reloc.Index]);
71 return TypeMap[Reloc.Index];
80uint32_t ObjFile::calcNewIndex(const WasmRelocation &reloc) const {
81 if (reloc.Type == R_WASM_TYPE_INDEX_LEB) {
82 assert(typeIsUsed[reloc.Index]);
83 return typeMap[reloc.Index];
7284 }
73 return Symbols[Reloc.Index]->getOutputSymbolIndex();
85 const Symbol *sym = symbols[reloc.Index];
86 if (auto *ss = dyn_cast<SectionSymbol>(sym))
87 sym = ss->getOutputSectionSymbol();
88 return sym->getOutputSymbolIndex();
7489}
7590
7691// Relocations can contain addend for combined sections. This function takes a
7792// relocation and returns updated addend by offset in the output section.
78uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const {
79 switch (Reloc.Type) {
80 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
81 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
82 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
83 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
84 return Reloc.Addend;
85 case R_WEBASSEMBLY_SECTION_OFFSET_I32:
86 return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
93uint32_t ObjFile::calcNewAddend(const WasmRelocation &reloc) const {
94 switch (reloc.Type) {
95 case R_WASM_MEMORY_ADDR_LEB:
96 case R_WASM_MEMORY_ADDR_SLEB:
97 case R_WASM_MEMORY_ADDR_REL_SLEB:
98 case R_WASM_MEMORY_ADDR_I32:
99 case R_WASM_FUNCTION_OFFSET_I32:
100 return reloc.Addend;
101 case R_WASM_SECTION_OFFSET_I32:
102 return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend;
87103 default:
88104 llvm_unreachable("unexpected relocation type");
89105 }
......@@ -92,39 +108,42 @@ uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const {
92108// Calculate the value we expect to find at the relocation location.
93109// This is used as a sanity check before applying a relocation to a given
94110// location. It is useful for catching bugs in the compiler and linker.
95uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
96 switch (Reloc.Type) {
97 case R_WEBASSEMBLY_TABLE_INDEX_I32:
98 case R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
99 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
100 return TableEntries[Sym.Info.ElementIndex];
111uint32_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const {
112 switch (reloc.Type) {
113 case R_WASM_TABLE_INDEX_I32:
114 case R_WASM_TABLE_INDEX_SLEB:
115 case R_WASM_TABLE_INDEX_REL_SLEB: {
116 const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
117 return tableEntries[sym.Info.ElementIndex];
101118 }
102 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
103 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
104 case R_WEBASSEMBLY_MEMORY_ADDR_LEB: {
105 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
106 if (Sym.isUndefined())
119 case R_WASM_MEMORY_ADDR_SLEB:
120 case R_WASM_MEMORY_ADDR_I32:
121 case R_WASM_MEMORY_ADDR_LEB:
122 case R_WASM_MEMORY_ADDR_REL_SLEB: {
123 const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
124 if (sym.isUndefined())
107125 return 0;
108 const WasmSegment &Segment =
109 WasmObj->dataSegments()[Sym.Info.DataRef.Segment];
110 return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset +
111 Reloc.Addend;
126 const WasmSegment &segment =
127 wasmObj->dataSegments()[sym.Info.DataRef.Segment];
128 return segment.Data.Offset.Value.Int32 + sym.Info.DataRef.Offset +
129 reloc.Addend;
112130 }
113 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
114 if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
115 return Sym->Function->getFunctionInputOffset() +
116 Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
117 }
118 return 0;
119 case R_WEBASSEMBLY_SECTION_OFFSET_I32:
120 return Reloc.Addend;
121 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
122 return Reloc.Index;
123 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
124 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
125 case R_WEBASSEMBLY_EVENT_INDEX_LEB: {
126 const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index];
127 return Sym.Info.ElementIndex;
131 case R_WASM_FUNCTION_OFFSET_I32: {
132 const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
133 InputFunction *f =
134 functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()];
135 return f->getFunctionInputOffset() + f->getFunctionCodeOffset() +
136 reloc.Addend;
137 }
138 case R_WASM_SECTION_OFFSET_I32:
139 return reloc.Addend;
140 case R_WASM_TYPE_INDEX_LEB:
141 return reloc.Index;
142 case R_WASM_FUNCTION_INDEX_LEB:
143 case R_WASM_GLOBAL_INDEX_LEB:
144 case R_WASM_EVENT_INDEX_LEB: {
145 const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
146 return sym.Info.ElementIndex;
128147 }
129148 default:
130149 llvm_unreachable("unknown relocation type");
......@@ -132,260 +151,299 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const {
132151}
133152
134153// Translate from the relocation's index into the final linked output value.
135uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
136 switch (Reloc.Type) {
137 case R_WEBASSEMBLY_TABLE_INDEX_I32:
138 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
139 return getFunctionSymbol(Reloc.Index)->getTableIndex();
140 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
141 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
142 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
143 if (auto *Sym = dyn_cast<DefinedData>(getDataSymbol(Reloc.Index)))
144 if (Sym->isLive())
145 return Sym->getVirtualAddress() + Reloc.Addend;
146 return 0;
147 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
148 return TypeMap[Reloc.Index];
149 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
150 return getFunctionSymbol(Reloc.Index)->getFunctionIndex();
151 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
152 return getGlobalSymbol(Reloc.Index)->getGlobalIndex();
153 case R_WEBASSEMBLY_EVENT_INDEX_LEB:
154 return getEventSymbol(Reloc.Index)->getEventIndex();
155 case R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
156 if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) {
157 if (Sym->isLive())
158 return Sym->Function->OutputOffset +
159 Sym->Function->getFunctionCodeOffset() + Reloc.Addend;
160 }
161 return 0;
162 case R_WEBASSEMBLY_SECTION_OFFSET_I32:
163 return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend;
154uint32_t ObjFile::calcNewValue(const WasmRelocation &reloc) const {
155 const Symbol* sym = nullptr;
156 if (reloc.Type != R_WASM_TYPE_INDEX_LEB) {
157 sym = symbols[reloc.Index];
158
159 // We can end up with relocations against non-live symbols. For example
160 // in debug sections.
161 if ((isa<FunctionSymbol>(sym) || isa<DataSymbol>(sym)) && !sym->isLive())
162 return 0;
163 }
164
165 switch (reloc.Type) {
166 case R_WASM_TABLE_INDEX_I32:
167 case R_WASM_TABLE_INDEX_SLEB:
168 case R_WASM_TABLE_INDEX_REL_SLEB:
169 if (config->isPic && !getFunctionSymbol(reloc.Index)->hasTableIndex())
170 return 0;
171 return getFunctionSymbol(reloc.Index)->getTableIndex();
172 case R_WASM_MEMORY_ADDR_SLEB:
173 case R_WASM_MEMORY_ADDR_I32:
174 case R_WASM_MEMORY_ADDR_LEB:
175 case R_WASM_MEMORY_ADDR_REL_SLEB:
176 if (isa<UndefinedData>(sym))
177 return 0;
178 return cast<DefinedData>(sym)->getVirtualAddress() + reloc.Addend;
179 case R_WASM_TYPE_INDEX_LEB:
180 return typeMap[reloc.Index];
181 case R_WASM_FUNCTION_INDEX_LEB:
182 return getFunctionSymbol(reloc.Index)->getFunctionIndex();
183 case R_WASM_GLOBAL_INDEX_LEB:
184 if (auto gs = dyn_cast<GlobalSymbol>(sym))
185 return gs->getGlobalIndex();
186 return sym->getGOTIndex();
187 case R_WASM_EVENT_INDEX_LEB:
188 return getEventSymbol(reloc.Index)->getEventIndex();
189 case R_WASM_FUNCTION_OFFSET_I32: {
190 auto *f = cast<DefinedFunction>(sym);
191 return f->function->outputOffset + f->function->getFunctionCodeOffset() +
192 reloc.Addend;
193 }
194 case R_WASM_SECTION_OFFSET_I32:
195 return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend;
164196 default:
165197 llvm_unreachable("unknown relocation type");
166198 }
167199}
168200
169201template <class T>
170static void setRelocs(const std::vector<T *> &Chunks,
171 const WasmSection *Section) {
172 if (!Section)
202static void setRelocs(const std::vector<T *> &chunks,
203 const WasmSection *section) {
204 if (!section)
173205 return;
174206
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;
207 ArrayRef<WasmRelocation> relocs = section->Relocations;
208 assert(std::is_sorted(relocs.begin(), relocs.end(),
209 [](const WasmRelocation &r1, const WasmRelocation &r2) {
210 return r1.Offset < r2.Offset;
179211 }));
180212 assert(std::is_sorted(
181 Chunks.begin(), Chunks.end(), [](InputChunk *C1, InputChunk *C2) {
182 return C1->getInputSectionOffset() < C2->getInputSectionOffset();
213 chunks.begin(), chunks.end(), [](InputChunk *c1, InputChunk *c2) {
214 return c1->getInputSectionOffset() < c2->getInputSectionOffset();
183215 }));
184216
185 auto RelocsNext = Relocs.begin();
186 auto RelocsEnd = Relocs.end();
187 auto RelocLess = [](const WasmRelocation &R, uint32_t Val) {
188 return R.Offset < Val;
217 auto relocsNext = relocs.begin();
218 auto relocsEnd = relocs.end();
219 auto relocLess = [](const WasmRelocation &r, uint32_t val) {
220 return r.Offset < val;
189221 };
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));
222 for (InputChunk *c : chunks) {
223 auto relocsStart = std::lower_bound(relocsNext, relocsEnd,
224 c->getInputSectionOffset(), relocLess);
225 relocsNext = std::lower_bound(
226 relocsStart, relocsEnd, c->getInputSectionOffset() + c->getInputSize(),
227 relocLess);
228 c->setRelocations(ArrayRef<WasmRelocation>(relocsStart, relocsNext));
197229 }
198230}
199231
200void ObjFile::parse() {
232void ObjFile::parse(bool ignoreComdats) {
201233 // Parse a memory buffer as a wasm file.
202234 LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
203 std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this));
235 std::unique_ptr<Binary> bin = CHECK(createBinary(mb), toString(this));
204236
205 auto *Obj = dyn_cast<WasmObjectFile>(Bin.get());
206 if (!Obj)
237 auto *obj = dyn_cast<WasmObjectFile>(bin.get());
238 if (!obj)
207239 fatal(toString(this) + ": not a wasm file");
208 if (!Obj->isRelocatableObject())
240 if (!obj->isRelocatableObject())
209241 fatal(toString(this) + ": not a relocatable wasm file");
210242
211 Bin.release();
212 WasmObj.reset(Obj);
243 bin.release();
244 wasmObj.reset(obj);
213245
214246 // Build up a map of function indices to table indices for use when
215247 // verifying the existing table index relocations
216 uint32_t TotalFunctions =
217 WasmObj->getNumImportedFunctions() + WasmObj->functions().size();
218 TableEntries.resize(TotalFunctions);
219 for (const WasmElemSegment &Seg : WasmObj->elements()) {
220 if (Seg.Offset.Opcode != WASM_OPCODE_I32_CONST)
248 uint32_t totalFunctions =
249 wasmObj->getNumImportedFunctions() + wasmObj->functions().size();
250 tableEntries.resize(totalFunctions);
251 for (const WasmElemSegment &seg : wasmObj->elements()) {
252 if (seg.Offset.Opcode != WASM_OPCODE_I32_CONST)
221253 fatal(toString(this) + ": invalid table elements");
222 uint32_t Offset = Seg.Offset.Value.Int32;
223 for (uint32_t Index = 0; Index < Seg.Functions.size(); Index++) {
254 uint32_t offset = seg.Offset.Value.Int32;
255 for (uint32_t index = 0; index < seg.Functions.size(); index++) {
224256
225 uint32_t FunctionIndex = Seg.Functions[Index];
226 TableEntries[FunctionIndex] = Offset + Index;
257 uint32_t functionIndex = seg.Functions[index];
258 tableEntries[functionIndex] = offset + index;
227259 }
228260 }
229261
230 // Find the code and data sections. Wasm objects can have at most one code
231 // and one data section.
232 uint32_t SectionIndex = 0;
233 for (const SectionRef &Sec : WasmObj->sections()) {
234 const WasmSection &Section = WasmObj->getWasmSection(Sec);
235 if (Section.Type == WASM_SEC_CODE) {
236 CodeSection = &Section;
237 } else if (Section.Type == WASM_SEC_DATA) {
238 DataSection = &Section;
239 } else if (Section.Type == WASM_SEC_CUSTOM) {
240 CustomSections.emplace_back(make<InputSection>(Section, this));
241 CustomSections.back()->setRelocations(Section.Relocations);
242 CustomSectionsByIndex[SectionIndex] = CustomSections.back();
262 uint32_t sectionIndex = 0;
263
264 // Bool for each symbol, true if called directly. This allows us to implement
265 // a weaker form of signature checking where undefined functions that are not
266 // called directly (i.e. only address taken) don't have to match the defined
267 // function's signature. We cannot do this for directly called functions
268 // because those signatures are checked at validation times.
269 // See https://bugs.llvm.org/show_bug.cgi?id=40412
270 std::vector<bool> isCalledDirectly(wasmObj->getNumberOfSymbols(), false);
271 for (const SectionRef &sec : wasmObj->sections()) {
272 const WasmSection &section = wasmObj->getWasmSection(sec);
273 // Wasm objects can have at most one code and one data section.
274 if (section.Type == WASM_SEC_CODE) {
275 assert(!codeSection);
276 codeSection = &section;
277 } else if (section.Type == WASM_SEC_DATA) {
278 assert(!dataSection);
279 dataSection = &section;
280 } else if (section.Type == WASM_SEC_CUSTOM) {
281 customSections.emplace_back(make<InputSection>(section, this));
282 customSections.back()->setRelocations(section.Relocations);
283 customSectionsByIndex[sectionIndex] = customSections.back();
243284 }
244 SectionIndex++;
285 sectionIndex++;
286 // Scans relocations to dermine determine if a function symbol is called
287 // directly
288 for (const WasmRelocation &reloc : section.Relocations)
289 if (reloc.Type == R_WASM_FUNCTION_INDEX_LEB)
290 isCalledDirectly[reloc.Index] = true;
245291 }
246292
247 TypeMap.resize(getWasmObj()->types().size());
248 TypeIsUsed.resize(getWasmObj()->types().size(), false);
293 typeMap.resize(getWasmObj()->types().size());
294 typeIsUsed.resize(getWasmObj()->types().size(), false);
249295
250 ArrayRef<StringRef> Comdats = WasmObj->linkingData().Comdats;
251 UsedComdats.resize(Comdats.size());
252 for (unsigned I = 0; I < Comdats.size(); ++I)
253 UsedComdats[I] = Symtab->addComdat(Comdats[I]);
296 ArrayRef<StringRef> comdats = wasmObj->linkingData().Comdats;
297 for (StringRef comdat : comdats) {
298 bool isNew = ignoreComdats || symtab->addComdat(comdat);
299 keptComdats.push_back(isNew);
300 }
254301
255302 // Populate `Segments`.
256 for (const WasmSegment &S : WasmObj->dataSegments())
257 Segments.emplace_back(make<InputSegment>(S, this));
258 setRelocs(Segments, DataSection);
303 for (const WasmSegment &s : wasmObj->dataSegments()) {
304 auto* seg = make<InputSegment>(s, this);
305 seg->discarded = isExcludedByComdat(seg);
306 segments.emplace_back(seg);
307 }
308 setRelocs(segments, dataSection);
259309
260310 // Populate `Functions`.
261 ArrayRef<WasmFunction> Funcs = WasmObj->functions();
262 ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes();
263 ArrayRef<WasmSignature> Types = WasmObj->types();
264 Functions.reserve(Funcs.size());
265
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);
311 ArrayRef<WasmFunction> funcs = wasmObj->functions();
312 ArrayRef<uint32_t> funcTypes = wasmObj->functionTypes();
313 ArrayRef<WasmSignature> types = wasmObj->types();
314 functions.reserve(funcs.size());
315
316 for (size_t i = 0, e = funcs.size(); i != e; ++i) {
317 auto* func = make<InputFunction>(types[funcTypes[i]], &funcs[i], this);
318 func->discarded = isExcludedByComdat(func);
319 functions.emplace_back(func);
320 }
321 setRelocs(functions, codeSection);
270322
271323 // Populate `Globals`.
272 for (const WasmGlobal &G : WasmObj->globals())
273 Globals.emplace_back(make<InputGlobal>(G, this));
324 for (const WasmGlobal &g : wasmObj->globals())
325 globals.emplace_back(make<InputGlobal>(g, this));
274326
275327 // Populate `Events`.
276 for (const WasmEvent &E : WasmObj->events())
277 Events.emplace_back(make<InputEvent>(Types[E.Type.SigIndex], E, this));
278
279 // Populate `Symbols` based on the WasmSymbols in the object.
280 Symbols.reserve(WasmObj->getNumberOfSymbols());
281 for (const SymbolRef &Sym : WasmObj->symbols()) {
282 const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl());
283 if (Symbol *Sym = createDefined(WasmSym))
284 Symbols.push_back(Sym);
285 else
286 Symbols.push_back(createUndefined(WasmSym));
328 for (const WasmEvent &e : wasmObj->events())
329 events.emplace_back(make<InputEvent>(types[e.Type.SigIndex], e, this));
330
331 // Populate `Symbols` based on the symbols in the object.
332 symbols.reserve(wasmObj->getNumberOfSymbols());
333 for (const SymbolRef &sym : wasmObj->symbols()) {
334 const WasmSymbol &wasmSym = wasmObj->getWasmSymbol(sym.getRawDataRefImpl());
335 if (wasmSym.isDefined()) {
336 // createDefined may fail if the symbol is comdat excluded in which case
337 // we fall back to creating an undefined symbol
338 if (Symbol *d = createDefined(wasmSym)) {
339 symbols.push_back(d);
340 continue;
341 }
342 }
343 size_t idx = symbols.size();
344 symbols.push_back(createUndefined(wasmSym, isCalledDirectly[idx]));
287345 }
288346}
289347
290bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const {
291 uint32_t C = Chunk->getComdat();
292 if (C == UINT32_MAX)
348bool ObjFile::isExcludedByComdat(InputChunk *chunk) const {
349 uint32_t c = chunk->getComdat();
350 if (c == UINT32_MAX)
293351 return false;
294 return !UsedComdats[C];
352 return !keptComdats[c];
295353}
296354
297FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t Index) const {
298 return cast<FunctionSymbol>(Symbols[Index]);
355FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t index) const {
356 return cast<FunctionSymbol>(symbols[index]);
299357}
300358
301GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const {
302 return cast<GlobalSymbol>(Symbols[Index]);
359GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t index) const {
360 return cast<GlobalSymbol>(symbols[index]);
303361}
304362
305EventSymbol *ObjFile::getEventSymbol(uint32_t Index) const {
306 return cast<EventSymbol>(Symbols[Index]);
363EventSymbol *ObjFile::getEventSymbol(uint32_t index) const {
364 return cast<EventSymbol>(symbols[index]);
307365}
308366
309SectionSymbol *ObjFile::getSectionSymbol(uint32_t Index) const {
310 return cast<SectionSymbol>(Symbols[Index]);
367SectionSymbol *ObjFile::getSectionSymbol(uint32_t index) const {
368 return cast<SectionSymbol>(symbols[index]);
311369}
312370
313DataSymbol *ObjFile::getDataSymbol(uint32_t Index) const {
314 return cast<DataSymbol>(Symbols[Index]);
371DataSymbol *ObjFile::getDataSymbol(uint32_t index) const {
372 return cast<DataSymbol>(symbols[index]);
315373}
316374
317Symbol *ObjFile::createDefined(const WasmSymbol &Sym) {
318 if (!Sym.isDefined())
319 return nullptr;
320
321 StringRef Name = Sym.Info.Name;
322 uint32_t Flags = Sym.Info.Flags;
375Symbol *ObjFile::createDefined(const WasmSymbol &sym) {
376 StringRef name = sym.Info.Name;
377 uint32_t flags = sym.Info.Flags;
323378
324 switch (Sym.Info.Kind) {
379 switch (sym.Info.Kind) {
325380 case WASM_SYMBOL_TYPE_FUNCTION: {
326 InputFunction *Func =
327 Functions[Sym.Info.ElementIndex - WasmObj->getNumImportedFunctions()];
328 if (isExcludedByComdat(Func)) {
329 Func->Live = false;
381 InputFunction *func =
382 functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()];
383 if (sym.isBindingLocal())
384 return make<DefinedFunction>(name, flags, this, func);
385 if (func->discarded)
330386 return nullptr;
331 }
332
333 if (Sym.isBindingLocal())
334 return make<DefinedFunction>(Name, Flags, this, Func);
335 return Symtab->addDefinedFunction(Name, Flags, this, Func);
387 return symtab->addDefinedFunction(name, flags, this, func);
336388 }
337389 case WASM_SYMBOL_TYPE_DATA: {
338 InputSegment *Seg = Segments[Sym.Info.DataRef.Segment];
339 if (isExcludedByComdat(Seg)) {
340 Seg->Live = false;
390 InputSegment *seg = segments[sym.Info.DataRef.Segment];
391 uint32_t offset = sym.Info.DataRef.Offset;
392 uint32_t size = sym.Info.DataRef.Size;
393 if (sym.isBindingLocal())
394 return make<DefinedData>(name, flags, this, seg, offset, size);
395 if (seg->discarded)
341396 return nullptr;
342 }
343
344 uint32_t Offset = Sym.Info.DataRef.Offset;
345 uint32_t Size = Sym.Info.DataRef.Size;
346
347 if (Sym.isBindingLocal())
348 return make<DefinedData>(Name, Flags, this, Seg, Offset, Size);
349 return Symtab->addDefinedData(Name, Flags, this, Seg, Offset, Size);
397 return symtab->addDefinedData(name, flags, this, seg, offset, size);
350398 }
351399 case WASM_SYMBOL_TYPE_GLOBAL: {
352 InputGlobal *Global =
353 Globals[Sym.Info.ElementIndex - WasmObj->getNumImportedGlobals()];
354 if (Sym.isBindingLocal())
355 return make<DefinedGlobal>(Name, Flags, this, Global);
356 return Symtab->addDefinedGlobal(Name, Flags, this, Global);
400 InputGlobal *global =
401 globals[sym.Info.ElementIndex - wasmObj->getNumImportedGlobals()];
402 if (sym.isBindingLocal())
403 return make<DefinedGlobal>(name, flags, this, global);
404 return symtab->addDefinedGlobal(name, flags, this, global);
357405 }
358406 case WASM_SYMBOL_TYPE_SECTION: {
359 InputSection *Section = CustomSectionsByIndex[Sym.Info.ElementIndex];
360 assert(Sym.isBindingLocal());
361 return make<SectionSymbol>(Name, Flags, Section, this);
407 InputSection *section = customSectionsByIndex[sym.Info.ElementIndex];
408 assert(sym.isBindingLocal());
409 return make<SectionSymbol>(flags, section, this);
362410 }
363411 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);
412 InputEvent *event =
413 events[sym.Info.ElementIndex - wasmObj->getNumImportedEvents()];
414 if (sym.isBindingLocal())
415 return make<DefinedEvent>(name, flags, this, event);
416 return symtab->addDefinedEvent(name, flags, this, event);
369417 }
370418 }
371419 llvm_unreachable("unknown symbol kind");
372420}
373421
374Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
375 StringRef Name = Sym.Info.Name;
376 uint32_t Flags = Sym.Info.Flags;
422Symbol *ObjFile::createUndefined(const WasmSymbol &sym, bool isCalledDirectly) {
423 StringRef name = sym.Info.Name;
424 uint32_t flags = sym.Info.Flags;
377425
378 switch (Sym.Info.Kind) {
426 switch (sym.Info.Kind) {
379427 case WASM_SYMBOL_TYPE_FUNCTION:
380 return Symtab->addUndefinedFunction(Name, Sym.Info.ImportName,
381 Sym.Info.ImportModule, Flags, this,
382 Sym.Signature);
428 if (sym.isBindingLocal())
429 return make<UndefinedFunction>(name, sym.Info.ImportName,
430 sym.Info.ImportModule, flags, this,
431 sym.Signature, isCalledDirectly);
432 return symtab->addUndefinedFunction(name, sym.Info.ImportName,
433 sym.Info.ImportModule, flags, this,
434 sym.Signature, isCalledDirectly);
383435 case WASM_SYMBOL_TYPE_DATA:
384 return Symtab->addUndefinedData(Name, Flags, this);
436 if (sym.isBindingLocal())
437 return make<UndefinedData>(name, flags, this);
438 return symtab->addUndefinedData(name, flags, this);
385439 case WASM_SYMBOL_TYPE_GLOBAL:
386 return Symtab->addUndefinedGlobal(Name, Sym.Info.ImportName,
387 Sym.Info.ImportModule, Flags, this,
388 Sym.GlobalType);
440 if (sym.isBindingLocal())
441 return make<UndefinedGlobal>(name, sym.Info.ImportName,
442 sym.Info.ImportModule, flags, this,
443 sym.GlobalType);
444 return symtab->addUndefinedGlobal(name, sym.Info.ImportName,
445 sym.Info.ImportModule, flags, this,
446 sym.GlobalType);
389447 case WASM_SYMBOL_TYPE_SECTION:
390448 llvm_unreachable("section symbols cannot be undefined");
391449 }
......@@ -395,42 +453,41 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
395453void ArchiveFile::parse() {
396454 // Parse a MemoryBufferRef as an archive file.
397455 LLVM_DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n");
398 File = CHECK(Archive::create(MB), toString(this));
456 file = CHECK(Archive::create(mb), toString(this));
399457
400458 // Read the symbol table to construct Lazy symbols.
401 int Count = 0;
402 for (const Archive::Symbol &Sym : File->symbols()) {
403 Symtab->addLazy(this, &Sym);
404 ++Count;
459 int count = 0;
460 for (const Archive::Symbol &sym : file->symbols()) {
461 symtab->addLazy(this, &sym);
462 ++count;
405463 }
406 LLVM_DEBUG(dbgs() << "Read " << Count << " symbols\n");
464 LLVM_DEBUG(dbgs() << "Read " << count << " symbols\n");
407465}
408466
409void ArchiveFile::addMember(const Archive::Symbol *Sym) {
410 const Archive::Child &C =
411 CHECK(Sym->getMember(),
412 "could not get the member for symbol " + Sym->getName());
467void ArchiveFile::addMember(const Archive::Symbol *sym) {
468 const Archive::Child &c =
469 CHECK(sym->getMember(),
470 "could not get the member for symbol " + sym->getName());
413471
414472 // Don't try to load the same member twice (this can happen when members
415473 // mutually reference each other).
416 if (!Seen.insert(C.getChildOffset()).second)
474 if (!seen.insert(c.getChildOffset()).second)
417475 return;
418476
419 LLVM_DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n");
477 LLVM_DEBUG(dbgs() << "loading lazy: " << sym->getName() << "\n");
420478 LLVM_DEBUG(dbgs() << "from archive: " << toString(this) << "\n");
421479
422 MemoryBufferRef MB =
423 CHECK(C.getMemoryBufferRef(),
480 MemoryBufferRef mb =
481 CHECK(c.getMemoryBufferRef(),
424482 "could not get the buffer for the member defining symbol " +
425 Sym->getName());
483 sym->getName());
426484
427 InputFile *Obj = createObjectFile(MB);
428 Obj->ArchiveName = getName();
429 Symtab->addFile(Obj);
485 InputFile *obj = createObjectFile(mb, getName());
486 symtab->addFile(obj);
430487}
431488
432static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
433 switch (GvVisibility) {
489static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
490 switch (gvVisibility) {
434491 case GlobalValue::DefaultVisibility:
435492 return WASM_SYMBOL_VISIBILITY_DEFAULT;
436493 case GlobalValue::HiddenVisibility:
......@@ -440,45 +497,52 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
440497 llvm_unreachable("unknown visibility");
441498}
442499
443static Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &ObjSym,
444 BitcodeFile &F) {
445 StringRef Name = Saver.save(ObjSym.getName());
500static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
501 const lto::InputFile::Symbol &objSym,
502 BitcodeFile &f) {
503 StringRef name = saver.save(objSym.getName());
504
505 uint32_t flags = objSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0;
506 flags |= mapVisibility(objSym.getVisibility());
446507
447 uint32_t Flags = ObjSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0;
448 Flags |= mapVisibility(ObjSym.getVisibility());
508 int c = objSym.getComdatIndex();
509 bool excludedByComdat = c != -1 && !keptComdats[c];
449510
450 if (ObjSym.isUndefined()) {
451 if (ObjSym.isExecutable())
452 return Symtab->addUndefinedFunction(Name, Name, DefaultModule, Flags, &F,
453 nullptr);
454 return Symtab->addUndefinedData(Name, Flags, &F);
511 if (objSym.isUndefined() || excludedByComdat) {
512 if (objSym.isExecutable())
513 return symtab->addUndefinedFunction(name, name, defaultModule, flags, &f,
514 nullptr, true);
515 return symtab->addUndefinedData(name, flags, &f);
455516 }
456517
457 if (ObjSym.isExecutable())
458 return Symtab->addDefinedFunction(Name, Flags, &F, nullptr);
459 return Symtab->addDefinedData(Name, Flags, &F, nullptr, 0, 0);
518 if (objSym.isExecutable())
519 return symtab->addDefinedFunction(name, flags, &f, nullptr);
520 return symtab->addDefinedData(name, flags, &f, nullptr, 0, 0);
460521}
461522
462523void BitcodeFile::parse() {
463 Obj = check(lto::InputFile::create(MemoryBufferRef(
464 MB.getBuffer(), Saver.save(ArchiveName + MB.getBufferIdentifier()))));
465 Triple T(Obj->getTargetTriple());
466 if (T.getArch() != Triple::wasm32) {
467 error(toString(MB.getBufferIdentifier()) + ": machine type must be wasm32");
524 obj = check(lto::InputFile::create(MemoryBufferRef(
525 mb.getBuffer(), saver.save(archiveName + mb.getBufferIdentifier()))));
526 Triple t(obj->getTargetTriple());
527 if (t.getArch() != Triple::wasm32) {
528 error(toString(mb.getBufferIdentifier()) + ": machine type must be wasm32");
468529 return;
469530 }
531 std::vector<bool> keptComdats;
532 for (StringRef s : obj->getComdatTable())
533 keptComdats.push_back(symtab->addComdat(s));
470534
471 for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
472 Symbols.push_back(createBitcodeSymbol(ObjSym, *this));
535 for (const lto::InputFile::Symbol &objSym : obj->symbols())
536 symbols.push_back(createBitcodeSymbol(keptComdats, objSym, *this));
473537}
474538
475539// Returns a string in the format of "foo.o" or "foo.a(bar.o)".
476std::string lld::toString(const wasm::InputFile *File) {
477 if (!File)
540std::string lld::toString(const wasm::InputFile *file) {
541 if (!file)
478542 return "<internal>";
479543
480 if (File->ArchiveName.empty())
481 return File->getName();
544 if (file->archiveName.empty())
545 return file->getName();
482546
483 return (File->ArchiveName + "(" + File->getName() + ")").str();
547 return (file->archiveName + "(" + file->getName() + ")").str();
484548}
deps/lld/wasm/InputFiles.h+85-61
......@@ -1,9 +1,8 @@
11//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -20,6 +19,10 @@
2019#include "llvm/Support/MemoryBuffer.h"
2120#include <vector>
2221
22namespace llvm {
23class TarWriter;
24}
25
2326namespace lld {
2427namespace wasm {
2528
......@@ -30,10 +33,15 @@ class InputGlobal;
3033class InputEvent;
3134class InputSection;
3235
36// If --reproduce option is given, all input files are written
37// to this tar archive.
38extern std::unique_ptr<llvm::TarWriter> tar;
39
3340class InputFile {
3441public:
3542 enum Kind {
3643 ObjectKind,
44 SharedKind,
3745 ArchiveKind,
3846 BitcodeKind,
3947 };
......@@ -41,113 +49,129 @@ public:
4149 virtual ~InputFile() {}
4250
4351 // Returns the filename.
44 StringRef getName() const { return MB.getBufferIdentifier(); }
52 StringRef getName() const { return mb.getBufferIdentifier(); }
4553
46 // Reads a file (the constructor doesn't do that).
47 virtual void parse() = 0;
48
49 Kind kind() const { return FileKind; }
54 Kind kind() const { return fileKind; }
5055
5156 // An archive file name if this file is created from an archive.
52 StringRef ArchiveName;
57 StringRef archiveName;
58
59 ArrayRef<Symbol *> getSymbols() const { return symbols; }
5360
54 ArrayRef<Symbol *> getSymbols() const { return Symbols; }
61 MutableArrayRef<Symbol *> getMutableSymbols() { return symbols; }
5562
5663protected:
57 InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
58 MemoryBufferRef MB;
64 InputFile(Kind k, MemoryBufferRef m) : mb(m), fileKind(k) {}
65 MemoryBufferRef mb;
5966
6067 // List of all symbols referenced or defined by this file.
61 std::vector<Symbol *> Symbols;
68 std::vector<Symbol *> symbols;
6269
6370private:
64 const Kind FileKind;
71 const Kind fileKind;
6572};
6673
6774// .a file (ar archive)
6875class ArchiveFile : public InputFile {
6976public:
70 explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
71 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
77 explicit ArchiveFile(MemoryBufferRef m) : InputFile(ArchiveKind, m) {}
78 static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; }
7279
73 void addMember(const llvm::object::Archive::Symbol *Sym);
80 void addMember(const llvm::object::Archive::Symbol *sym);
7481
75 void parse() override;
82 void parse();
7683
7784private:
78 std::unique_ptr<llvm::object::Archive> File;
79 llvm::DenseSet<uint64_t> Seen;
85 std::unique_ptr<llvm::object::Archive> file;
86 llvm::DenseSet<uint64_t> seen;
8087};
8188
8289// .o file (wasm object file)
8390class ObjFile : public InputFile {
8491public:
85 explicit ObjFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {}
86 static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
92 explicit ObjFile(MemoryBufferRef m, StringRef archiveName)
93 : InputFile(ObjectKind, m) {
94 this->archiveName = archiveName;
95 }
96 static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
8797
88 void parse() override;
98 void parse(bool ignoreComdats = false);
8999
90100 // Returns the underlying wasm file.
91 const WasmObjectFile *getWasmObj() const { return WasmObj.get(); }
101 const WasmObjectFile *getWasmObj() const { return wasmObj.get(); }
92102
93103 void dumpInfo() const;
94104
95 uint32_t calcNewIndex(const WasmRelocation &Reloc) const;
96 uint32_t calcNewValue(const WasmRelocation &Reloc) const;
97 uint32_t calcNewAddend(const WasmRelocation &Reloc) const;
98 uint32_t calcExpectedValue(const WasmRelocation &Reloc) const;
105 uint32_t calcNewIndex(const WasmRelocation &reloc) const;
106 uint32_t calcNewValue(const WasmRelocation &reloc) const;
107 uint32_t calcNewAddend(const WasmRelocation &reloc) const;
108 uint32_t calcExpectedValue(const WasmRelocation &reloc) const;
109 Symbol *getSymbol(const WasmRelocation &reloc) const {
110 return symbols[reloc.Index];
111 };
99112
100 const WasmSection *CodeSection = nullptr;
101 const WasmSection *DataSection = nullptr;
113 const WasmSection *codeSection = nullptr;
114 const WasmSection *dataSection = nullptr;
102115
103116 // Maps input type indices to output type indices
104 std::vector<uint32_t> TypeMap;
105 std::vector<bool> TypeIsUsed;
117 std::vector<uint32_t> typeMap;
118 std::vector<bool> typeIsUsed;
106119 // Maps function indices to table indices
107 std::vector<uint32_t> TableEntries;
108 std::vector<bool> UsedComdats;
109 std::vector<InputSegment *> Segments;
110 std::vector<InputFunction *> Functions;
111 std::vector<InputGlobal *> Globals;
112 std::vector<InputEvent *> Events;
113 std::vector<InputSection *> CustomSections;
114 llvm::DenseMap<uint32_t, InputSection *> CustomSectionsByIndex;
115
116 Symbol *getSymbol(uint32_t Index) const { return Symbols[Index]; }
117 FunctionSymbol *getFunctionSymbol(uint32_t Index) const;
118 DataSymbol *getDataSymbol(uint32_t Index) const;
119 GlobalSymbol *getGlobalSymbol(uint32_t Index) const;
120 SectionSymbol *getSectionSymbol(uint32_t Index) const;
121 EventSymbol *getEventSymbol(uint32_t Index) const;
120 std::vector<uint32_t> tableEntries;
121 std::vector<bool> keptComdats;
122 std::vector<InputSegment *> segments;
123 std::vector<InputFunction *> functions;
124 std::vector<InputGlobal *> globals;
125 std::vector<InputEvent *> events;
126 std::vector<InputSection *> customSections;
127 llvm::DenseMap<uint32_t, InputSection *> customSectionsByIndex;
128
129 Symbol *getSymbol(uint32_t index) const { return symbols[index]; }
130 FunctionSymbol *getFunctionSymbol(uint32_t index) const;
131 DataSymbol *getDataSymbol(uint32_t index) const;
132 GlobalSymbol *getGlobalSymbol(uint32_t index) const;
133 SectionSymbol *getSectionSymbol(uint32_t index) const;
134 EventSymbol *getEventSymbol(uint32_t index) const;
122135
123136private:
124 Symbol *createDefined(const WasmSymbol &Sym);
125 Symbol *createUndefined(const WasmSymbol &Sym);
137 Symbol *createDefined(const WasmSymbol &sym);
138 Symbol *createUndefined(const WasmSymbol &sym, bool isCalledDirectly);
126139
127 bool isExcludedByComdat(InputChunk *Chunk) const;
140 bool isExcludedByComdat(InputChunk *chunk) const;
128141
129 std::unique_ptr<WasmObjectFile> WasmObj;
142 std::unique_ptr<WasmObjectFile> wasmObj;
130143};
131144
132class BitcodeFile : public InputFile {
145// .so file.
146class SharedFile : public InputFile {
133147public:
134 explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {}
135 static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
148 explicit SharedFile(MemoryBufferRef m) : InputFile(SharedKind, m) {}
149 static bool classof(const InputFile *f) { return f->kind() == SharedKind; }
150};
136151
137 void parse() override;
138 std::unique_ptr<llvm::lto::InputFile> Obj;
152// .bc file
153class BitcodeFile : public InputFile {
154public:
155 explicit BitcodeFile(MemoryBufferRef m, StringRef archiveName)
156 : InputFile(BitcodeKind, m) {
157 this->archiveName = archiveName;
158 }
159 static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
160
161 void parse();
162 std::unique_ptr<llvm::lto::InputFile> obj;
139163};
140164
141165// Will report a fatal() error if the input buffer is not a valid bitcode
142// or was object file.
143InputFile *createObjectFile(MemoryBufferRef MB);
166// or wasm object file.
167InputFile *createObjectFile(MemoryBufferRef mb, StringRef archiveName = "");
144168
145169// Opens a given file.
146llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
170llvm::Optional<MemoryBufferRef> readFile(StringRef path);
147171
148172} // namespace wasm
149173
150std::string toString(const wasm::InputFile *File);
174std::string toString(const wasm::InputFile *file);
151175
152176} // namespace lld
153177
deps/lld/wasm/InputGlobal.h+17-18
......@@ -1,9 +1,8 @@
11//===- InputGlobal.h --------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -23,32 +22,32 @@ namespace wasm {
2322// combined to form the final GLOBALS section.
2423class InputGlobal {
2524public:
26 InputGlobal(const WasmGlobal &G, ObjFile *F)
27 : File(F), Global(G), Live(!Config->GcSections) {}
25 InputGlobal(const WasmGlobal &g, ObjFile *f)
26 : file(f), global(g), live(!config->gcSections) {}
2827
29 StringRef getName() const { return Global.SymbolName; }
30 const WasmGlobalType &getType() const { return Global.Type; }
28 StringRef getName() const { return global.SymbolName; }
29 const WasmGlobalType &getType() const { return global.Type; }
3130
32 uint32_t getGlobalIndex() const { return GlobalIndex.getValue(); }
33 bool hasGlobalIndex() const { return GlobalIndex.hasValue(); }
34 void setGlobalIndex(uint32_t Index) {
31 uint32_t getGlobalIndex() const { return globalIndex.getValue(); }
32 bool hasGlobalIndex() const { return globalIndex.hasValue(); }
33 void setGlobalIndex(uint32_t index) {
3534 assert(!hasGlobalIndex());
36 GlobalIndex = Index;
35 globalIndex = index;
3736 }
3837
39 ObjFile *File;
40 WasmGlobal Global;
38 ObjFile *file;
39 WasmGlobal global;
4140
42 bool Live = false;
41 bool live = false;
4342
4443protected:
45 llvm::Optional<uint32_t> GlobalIndex;
44 llvm::Optional<uint32_t> globalIndex;
4645};
4746
4847} // namespace wasm
4948
50inline std::string toString(const wasm::InputGlobal *G) {
51 return (toString(G->File) + ":(" + G->getName() + ")").str();
49inline std::string toString(const wasm::InputGlobal *g) {
50 return (toString(g->file) + ":(" + g->getName() + ")").str();
5251}
5352
5453} // namespace lld
deps/lld/wasm/LTO.cpp+82-79
......@@ -1,9 +1,8 @@
11//===- LTO.cpp ------------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -11,6 +10,7 @@
1110#include "Config.h"
1211#include "InputFiles.h"
1312#include "Symbols.h"
13#include "lld/Common/Args.h"
1414#include "lld/Common/ErrorHandler.h"
1515#include "lld/Common/Strings.h"
1616#include "lld/Common/TargetOptionsCommandFlags.h"
......@@ -40,124 +40,127 @@ using namespace lld;
4040using namespace lld::wasm;
4141
4242static std::unique_ptr<lto::LTO> createLTO() {
43 lto::Config C;
44 C.Options = InitTargetOptionsFromCodeGenFlags();
43 lto::Config c;
44 c.Options = initTargetOptionsFromCodeGenFlags();
4545
4646 // Always emit a section per function/data with LTO.
47 C.Options.FunctionSections = true;
48 C.Options.DataSections = true;
49
50 // Wasm currently only supports ThreadModel::Single
51 C.Options.ThreadModel = ThreadModel::Single;
52
53 C.DisableVerify = Config->DisableVerify;
54 C.DiagHandler = diagnosticHandler;
55 C.OptLevel = Config->LTOO;
56 C.MAttrs = GetMAttrs();
57
58 if (Config->Relocatable)
59 C.RelocModel = None;
60 else if (Config->Pic)
61 C.RelocModel = Reloc::PIC_;
47 c.Options.FunctionSections = true;
48 c.Options.DataSections = true;
49
50 c.DisableVerify = config->disableVerify;
51 c.DiagHandler = diagnosticHandler;
52 c.OptLevel = config->ltoo;
53 c.MAttrs = getMAttrs();
54 c.CGOptLevel = args::getCGOptLevel(config->ltoo);
55
56 if (config->relocatable)
57 c.RelocModel = None;
58 else if (config->isPic)
59 c.RelocModel = Reloc::PIC_;
6260 else
63 C.RelocModel = Reloc::Static;
61 c.RelocModel = Reloc::Static;
6462
65 if (Config->SaveTemps)
66 checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
63 if (config->saveTemps)
64 checkError(c.addSaveTemps(config->outputFile.str() + ".",
6765 /*UseInputModulePath*/ true));
6866
69 lto::ThinBackend Backend;
70 if (Config->ThinLTOJobs != -1U)
71 Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
72 return llvm::make_unique<lto::LTO>(std::move(C), Backend,
73 Config->LTOPartitions);
67 lto::ThinBackend backend;
68 if (config->thinLTOJobs != -1U)
69 backend = lto::createInProcessThinBackend(config->thinLTOJobs);
70 return llvm::make_unique<lto::LTO>(std::move(c), backend,
71 config->ltoPartitions);
7472}
7573
76BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {}
74BitcodeCompiler::BitcodeCompiler() : ltoObj(createLTO()) {}
7775
7876BitcodeCompiler::~BitcodeCompiler() = default;
7977
80static void undefine(Symbol *S) {
81 if (auto F = dyn_cast<DefinedFunction>(S))
82 replaceSymbol<UndefinedFunction>(F, F->getName(), F->getName(),
83 DefaultModule, 0,
84 F->getFile(), F->Signature);
85 else if (isa<DefinedData>(S))
86 replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile());
78static void undefine(Symbol *s) {
79 if (auto f = dyn_cast<DefinedFunction>(s))
80 replaceSymbol<UndefinedFunction>(f, f->getName(), f->getName(),
81 defaultModule, 0,
82 f->getFile(), f->signature);
83 else if (isa<DefinedData>(s))
84 replaceSymbol<UndefinedData>(s, s->getName(), 0, s->getFile());
8785 else
8886 llvm_unreachable("unexpected symbol kind");
8987}
9088
91void BitcodeCompiler::add(BitcodeFile &F) {
92 lto::InputFile &Obj = *F.Obj;
93 unsigned SymNum = 0;
94 ArrayRef<Symbol *> Syms = F.getSymbols();
95 std::vector<lto::SymbolResolution> Resols(Syms.size());
89void BitcodeCompiler::add(BitcodeFile &f) {
90 lto::InputFile &obj = *f.obj;
91 unsigned symNum = 0;
92 ArrayRef<Symbol *> syms = f.getSymbols();
93 std::vector<lto::SymbolResolution> resols(syms.size());
9694
9795 // Provide a resolution to the LTO API for each symbol.
98 for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
99 Symbol *Sym = Syms[SymNum];
100 lto::SymbolResolution &R = Resols[SymNum];
101 ++SymNum;
96 for (const lto::InputFile::Symbol &objSym : obj.symbols()) {
97 Symbol *sym = syms[symNum];
98 lto::SymbolResolution &r = resols[symNum];
99 ++symNum;
102100
103101 // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
104102 // reports two symbols for module ASM defined. Without this check, lld
105103 // flags an undefined in IR with a definition in ASM as prevailing.
106104 // Once IRObjectFile is fixed to report only one symbol this hack can
107105 // be removed.
108 R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F;
109 R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj ||
110 (R.Prevailing && Sym->isExported());
111 if (R.Prevailing)
112 undefine(Sym);
106 r.Prevailing = !objSym.isUndefined() && sym->getFile() == &f;
107 r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj ||
108 (r.Prevailing && sym->isExported());
109 if (r.Prevailing)
110 undefine(sym);
111
112 // We tell LTO to not apply interprocedural optimization for wrapped
113 // (with --wrap) symbols because otherwise LTO would inline them while
114 // their values are still not final.
115 r.LinkerRedefined = !sym->canInline;
113116 }
114 checkError(LTOObj->add(std::move(F.Obj), Resols));
117 checkError(ltoObj->add(std::move(f.obj), resols));
115118}
116119
117120// Merge all the bitcode files we have seen, codegen the result
118121// and return the resulting objects.
119122std::vector<StringRef> BitcodeCompiler::compile() {
120 unsigned MaxTasks = LTOObj->getMaxTasks();
121 Buf.resize(MaxTasks);
122 Files.resize(MaxTasks);
123 unsigned maxTasks = ltoObj->getMaxTasks();
124 buf.resize(maxTasks);
125 files.resize(maxTasks);
123126
124127 // The --thinlto-cache-dir option specifies the path to a directory in which
125128 // to cache native object files for ThinLTO incremental builds. If a path was
126129 // specified, configure LTO to use it as the cache directory.
127 lto::NativeObjectCache Cache;
128 if (!Config->ThinLTOCacheDir.empty())
129 Cache = check(
130 lto::localCache(Config->ThinLTOCacheDir,
131 [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
132 Files[Task] = std::move(MB);
130 lto::NativeObjectCache cache;
131 if (!config->thinLTOCacheDir.empty())
132 cache = check(
133 lto::localCache(config->thinLTOCacheDir,
134 [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
135 files[task] = std::move(mb);
133136 }));
134137
135 checkError(LTOObj->run(
136 [&](size_t Task) {
138 checkError(ltoObj->run(
139 [&](size_t task) {
137140 return llvm::make_unique<lto::NativeObjectStream>(
138 llvm::make_unique<raw_svector_ostream>(Buf[Task]));
141 llvm::make_unique<raw_svector_ostream>(buf[task]));
139142 },
140 Cache));
143 cache));
141144
142 if (!Config->ThinLTOCacheDir.empty())
143 pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
145 if (!config->thinLTOCacheDir.empty())
146 pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy);
144147
145 std::vector<StringRef> Ret;
146 for (unsigned I = 0; I != MaxTasks; ++I) {
147 if (Buf[I].empty())
148 std::vector<StringRef> ret;
149 for (unsigned i = 0; i != maxTasks; ++i) {
150 if (buf[i].empty())
148151 continue;
149 if (Config->SaveTemps) {
150 if (I == 0)
151 saveBuffer(Buf[I], Config->OutputFile + ".lto.o");
152 if (config->saveTemps) {
153 if (i == 0)
154 saveBuffer(buf[i], config->outputFile + ".lto.o");
152155 else
153 saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o");
156 saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o");
154157 }
155 Ret.emplace_back(Buf[I].data(), Buf[I].size());
158 ret.emplace_back(buf[i].data(), buf[i].size());
156159 }
157160
158 for (std::unique_ptr<MemoryBuffer> &File : Files)
159 if (File)
160 Ret.push_back(File->getBuffer());
161 for (std::unique_ptr<MemoryBuffer> &file : files)
162 if (file)
163 ret.push_back(file->getBuffer());
161164
162 return Ret;
165 return ret;
163166}
deps/lld/wasm/LTO.h+7-8
......@@ -1,9 +1,8 @@
11//===- LTO.h ----------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -44,13 +43,13 @@ public:
4443 BitcodeCompiler();
4544 ~BitcodeCompiler();
4645
47 void add(BitcodeFile &F);
46 void add(BitcodeFile &f);
4847 std::vector<StringRef> compile();
4948
5049private:
51 std::unique_ptr<llvm::lto::LTO> LTOObj;
52 std::vector<SmallString<0>> Buf;
53 std::vector<std::unique_ptr<MemoryBuffer>> Files;
50 std::unique_ptr<llvm::lto::LTO> ltoObj;
51 std::vector<SmallString<0>> buf;
52 std::vector<std::unique_ptr<MemoryBuffer>> files;
5453};
5554} // namespace wasm
5655} // namespace lld
deps/lld/wasm/MarkLive.cpp+75-56
......@@ -1,9 +1,8 @@
11//===- MarkLive.cpp -------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98//
......@@ -33,48 +32,68 @@ using namespace llvm;
3332using namespace llvm::wasm;
3433
3534void lld::wasm::markLive() {
36 if (!Config->GcSections)
35 if (!config->gcSections)
3736 return;
3837
3938 LLVM_DEBUG(dbgs() << "markLive\n");
40 SmallVector<InputChunk *, 256> Q;
39 SmallVector<InputChunk *, 256> q;
4140
42 auto Enqueue = [&](Symbol *Sym) {
43 if (!Sym || Sym->isLive())
41 std::function<void(Symbol*)> enqueue = [&](Symbol *sym) {
42 if (!sym || sym->isLive())
4443 return;
45 LLVM_DEBUG(dbgs() << "markLive: " << Sym->getName() << "\n");
46 Sym->markLive();
47 if (InputChunk *Chunk = Sym->getChunk())
48 Q.push_back(Chunk);
44 LLVM_DEBUG(dbgs() << "markLive: " << sym->getName() << "\n");
45 sym->markLive();
46 if (InputChunk *chunk = sym->getChunk())
47 q.push_back(chunk);
48
49 // The ctor functions are all referenced by the synthetic callCtors
50 // function. However, this function does not contain relocations so we
51 // have to manually mark the ctors as live if callCtors itself is live.
52 if (sym == WasmSym::callCtors) {
53 if (config->passiveSegments)
54 enqueue(WasmSym::initMemory);
55 if (config->isPic)
56 enqueue(WasmSym::applyRelocs);
57 for (const ObjFile *obj : symtab->objectFiles) {
58 const WasmLinkingData &l = obj->getWasmObj()->linkingData();
59 for (const WasmInitFunc &f : l.InitFunctions) {
60 auto* initSym = obj->getFunctionSymbol(f.Symbol);
61 if (!initSym->isDiscarded())
62 enqueue(initSym);
63 }
64 }
65 }
4966 };
5067
5168 // Add GC root symbols.
52 if (!Config->Entry.empty())
53 Enqueue(Symtab->find(Config->Entry));
54 Enqueue(WasmSym::CallCtors);
69 if (!config->entry.empty())
70 enqueue(symtab->find(config->entry));
5571
5672 // We need to preserve any exported symbol
57 for (Symbol *Sym : Symtab->getSymbols())
58 if (Sym->isExported())
59 Enqueue(Sym);
60
61 // The ctor functions are all used in the synthetic __wasm_call_ctors
62 // function, but since this function is created in-place it doesn't contain
63 // relocations which mean we have to manually mark the ctors.
64 for (const ObjFile *Obj : Symtab->ObjectFiles) {
65 const WasmLinkingData &L = Obj->getWasmObj()->linkingData();
66 for (const WasmInitFunc &F : L.InitFunctions)
67 Enqueue(Obj->getFunctionSymbol(F.Symbol));
73 for (Symbol *sym : symtab->getSymbols())
74 if (sym->isExported())
75 enqueue(sym);
76
77 // For relocatable output, we need to preserve all the ctor functions
78 if (config->relocatable) {
79 for (const ObjFile *obj : symtab->objectFiles) {
80 const WasmLinkingData &l = obj->getWasmObj()->linkingData();
81 for (const WasmInitFunc &f : l.InitFunctions)
82 enqueue(obj->getFunctionSymbol(f.Symbol));
83 }
6884 }
6985
86 if (config->isPic)
87 enqueue(WasmSym::callCtors);
88
7089 // Follow relocations to mark all reachable chunks.
71 while (!Q.empty()) {
72 InputChunk *C = Q.pop_back_val();
90 while (!q.empty()) {
91 InputChunk *c = q.pop_back_val();
7392
74 for (const WasmRelocation Reloc : C->getRelocations()) {
75 if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB)
93 for (const WasmRelocation reloc : c->getRelocations()) {
94 if (reloc.Type == R_WASM_TYPE_INDEX_LEB)
7695 continue;
77 Symbol *Sym = C->File->getSymbol(Reloc.Index);
96 Symbol *sym = c->file->getSymbol(reloc.Index);
7897
7998 // If the function has been assigned the special index zero in the table,
8099 // the relocation doesn't pull in the function body, since the function
......@@ -83,38 +102,38 @@ void lld::wasm::markLive() {
83102 // zero is only reachable via "call", not via "call_indirect". The stub
84103 // functions used for weak-undefined symbols have this behaviour (compare
85104 // equal to null pointer, only reachable via direct call).
86 if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB ||
87 Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32) {
88 auto *FuncSym = cast<FunctionSymbol>(Sym);
89 if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0)
105 if (reloc.Type == R_WASM_TABLE_INDEX_SLEB ||
106 reloc.Type == R_WASM_TABLE_INDEX_I32) {
107 auto *funcSym = cast<FunctionSymbol>(sym);
108 if (funcSym->hasTableIndex() && funcSym->getTableIndex() == 0)
90109 continue;
91110 }
92111
93 Enqueue(Sym);
112 enqueue(sym);
94113 }
95114 }
96115
97116 // Report garbage-collected sections.
98 if (Config->PrintGcSections) {
99 for (const ObjFile *Obj : Symtab->ObjectFiles) {
100 for (InputChunk *C : Obj->Functions)
101 if (!C->Live)
102 message("removing unused section " + toString(C));
103 for (InputChunk *C : Obj->Segments)
104 if (!C->Live)
105 message("removing unused section " + toString(C));
106 for (InputGlobal *G : Obj->Globals)
107 if (!G->Live)
108 message("removing unused section " + toString(G));
109 for (InputEvent *E : Obj->Events)
110 if (!E->Live)
111 message("removing unused section " + toString(E));
117 if (config->printGcSections) {
118 for (const ObjFile *obj : symtab->objectFiles) {
119 for (InputChunk *c : obj->functions)
120 if (!c->live)
121 message("removing unused section " + toString(c));
122 for (InputChunk *c : obj->segments)
123 if (!c->live)
124 message("removing unused section " + toString(c));
125 for (InputGlobal *g : obj->globals)
126 if (!g->live)
127 message("removing unused section " + toString(g));
128 for (InputEvent *e : obj->events)
129 if (!e->live)
130 message("removing unused section " + toString(e));
112131 }
113 for (InputChunk *C : Symtab->SyntheticFunctions)
114 if (!C->Live)
115 message("removing unused section " + toString(C));
116 for (InputGlobal *G : Symtab->SyntheticGlobals)
117 if (!G->Live)
118 message("removing unused section " + toString(G));
132 for (InputChunk *c : symtab->syntheticFunctions)
133 if (!c->live)
134 message("removing unused section " + toString(c));
135 for (InputGlobal *g : symtab->syntheticGlobals)
136 if (!g->live)
137 message("removing unused section " + toString(g));
119138 }
120139}
deps/lld/wasm/MarkLive.h+3-4
......@@ -1,9 +1,8 @@
11//===- MarkLive.h -----------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
deps/lld/wasm/Options.td+26
......@@ -31,6 +31,8 @@ defm demangle: B<"demangle",
3131 "Demangle symbol names",
3232 "Do not demangle symbol names">;
3333
34def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">;
35
3436defm export_dynamic: B<"export-dynamic",
3537 "Put symbols in the dynamic symbol table",
3638 "Do not put symbols in the dynamic symbol table (default)">;
......@@ -85,6 +87,8 @@ defm print_gc_sections: B<"print-gc-sections",
8587
8688def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
8789
90defm reproduce: Eq<"reproduce", "Dump linker invocation and input files for debugging">;
91
8892def shared: F<"shared">, HelpText<"Build a shared object">;
8993
9094def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;
......@@ -93,6 +97,10 @@ def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;
9397
9498def threads: F<"threads">, HelpText<"Run the linker multi-threaded">;
9599
100def trace: F<"trace">, HelpText<"Print the names of the input files">;
101
102defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">;
103
96104defm undefined: Eq<"undefined", "Force undefined symbol during linking">;
97105
98106def v: Flag<["-"], "v">, HelpText<"Display the version number">;
......@@ -104,6 +112,9 @@ def version: F<"version">, HelpText<"Display the version number and exit">;
104112def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
105113 HelpText<"Linker option extensions">;
106114
115defm wrap: Eq<"wrap", "Use wrapper functions for symbol">,
116 MetaVarName<"<symbol>=<symbol>">;
117
107118// The follow flags are unique to wasm
108119
109120def allow_undefined: F<"allow-undefined">,
......@@ -132,6 +143,12 @@ def import_memory: F<"import-memory">,
132143def shared_memory: F<"shared-memory">,
133144 HelpText<"Use shared linear memory">;
134145
146def active_segments: F<"active-segments">,
147 HelpText<"Force segments to be active (default with unshared memory)">;
148
149def passive_segments: F<"passive-segments">,
150 HelpText<"Force segments to be passive (default with shared memory)">;
151
135152def import_table: F<"import-table">,
136153 HelpText<"Import function table from the environment">;
137154
......@@ -151,6 +168,13 @@ defm whole_archive: B<"whole-archive",
151168 "Force load of all members in a static library",
152169 "Do not force load of all members in a static library (default)">;
153170
171defm check_features: B<"check-features",
172 "Check feature compatibility of linked objects (default)",
173 "Ignore feature compatibility of linked objects">;
174
175def features: CommaJoined<["--", "-"], "features=">,
176 HelpText<"Comma-separated used features, inferred from input objects by default.">;
177
154178// Aliases
155179def: JoinedOrSeparate<["-"], "e">, Alias<entry>;
156180def: J<"entry=">, Alias<entry>;
......@@ -160,6 +184,8 @@ def: Flag<["-"], "m">, Alias<max_memory>;
160184def: Flag<["-"], "r">, Alias<relocatable>;
161185def: Flag<["-"], "s">, Alias<strip_all>, HelpText<"Alias for --strip-all">;
162186def: Flag<["-"], "S">, Alias<strip_debug>, HelpText<"Alias for --strip-debug">;
187def: Flag<["-"], "t">, Alias<trace>, HelpText<"Alias for --trace">;
188def: JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>, HelpText<"Alias for --trace-symbol">;
163189def: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
164190
165191// LTO-related options.
deps/lld/wasm/OutputSections.cpp+136-135
......@@ -1,9 +1,8 @@
11//===- OutputSections.cpp -------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -24,8 +23,8 @@ using namespace llvm::wasm;
2423using namespace lld;
2524using namespace lld::wasm;
2625
27static StringRef sectionTypeToString(uint32_t SectionType) {
28 switch (SectionType) {
26static StringRef sectionTypeToString(uint32_t sectionType) {
27 switch (sectionType) {
2928 case WASM_SEC_CUSTOM:
3029 return "CUSTOM";
3130 case WASM_SEC_TYPE:
......@@ -52,198 +51,200 @@ static StringRef sectionTypeToString(uint32_t SectionType) {
5251 return "CODE";
5352 case WASM_SEC_DATA:
5453 return "DATA";
54 case WASM_SEC_DATACOUNT:
55 return "DATACOUNT";
5556 default:
5657 fatal("invalid section type");
5758 }
5859}
5960
6061// Returns a string, e.g. "FUNCTION(.text)".
61std::string lld::toString(const OutputSection &Sec) {
62 if (!Sec.Name.empty())
63 return (Sec.getSectionName() + "(" + Sec.Name + ")").str();
64 return Sec.getSectionName();
62std::string lld::toString(const OutputSection &sec) {
63 if (!sec.name.empty())
64 return (sec.getSectionName() + "(" + sec.name + ")").str();
65 return sec.getSectionName();
6566}
6667
6768StringRef OutputSection::getSectionName() const {
68 return sectionTypeToString(Type);
69 return sectionTypeToString(type);
6970}
7071
71void OutputSection::createHeader(size_t BodySize) {
72 raw_string_ostream OS(Header);
73 debugWrite(OS.tell(), "section type [" + getSectionName() + "]");
74 encodeULEB128(Type, OS);
75 writeUleb128(OS, BodySize, "section size");
76 OS.flush();
77 log("createHeader: " + toString(*this) + " body=" + Twine(BodySize) +
72void OutputSection::createHeader(size_t bodySize) {
73 raw_string_ostream os(header);
74 debugWrite(os.tell(), "section type [" + getSectionName() + "]");
75 encodeULEB128(type, os);
76 writeUleb128(os, bodySize, "section size");
77 os.flush();
78 log("createHeader: " + toString(*this) + " body=" + Twine(bodySize) +
7879 " total=" + Twine(getSize()));
7980}
8081
81CodeSection::CodeSection(ArrayRef<InputFunction *> Functions)
82 : OutputSection(WASM_SEC_CODE), Functions(Functions) {
83 assert(Functions.size() > 0);
84
85 raw_string_ostream OS(CodeSectionHeader);
86 writeUleb128(OS, Functions.size(), "function count");
87 OS.flush();
88 BodySize = CodeSectionHeader.size();
82void CodeSection::finalizeContents() {
83 raw_string_ostream os(codeSectionHeader);
84 writeUleb128(os, functions.size(), "function count");
85 os.flush();
86 bodySize = codeSectionHeader.size();
8987
90 for (InputFunction *Func : Functions) {
91 Func->OutputOffset = BodySize;
92 Func->calculateSize();
93 BodySize += Func->getSize();
88 for (InputFunction *func : functions) {
89 func->outputOffset = bodySize;
90 func->calculateSize();
91 bodySize += func->getSize();
9492 }
9593
96 createHeader(BodySize);
94 createHeader(bodySize);
9795}
9896
99void CodeSection::writeTo(uint8_t *Buf) {
97void CodeSection::writeTo(uint8_t *buf) {
10098 log("writing " + toString(*this));
10199 log(" size=" + Twine(getSize()));
102 log(" headersize=" + Twine(Header.size()));
103 log(" codeheadersize=" + Twine(CodeSectionHeader.size()));
104 Buf += Offset;
100 log(" headersize=" + Twine(header.size()));
101 log(" codeheadersize=" + Twine(codeSectionHeader.size()));
102 buf += offset;
105103
106104 // Write section header
107 memcpy(Buf, Header.data(), Header.size());
108 Buf += Header.size();
105 memcpy(buf, header.data(), header.size());
106 buf += header.size();
109107
110108 // Write code section headers
111 memcpy(Buf, CodeSectionHeader.data(), CodeSectionHeader.size());
109 memcpy(buf, codeSectionHeader.data(), codeSectionHeader.size());
112110
113111 // Write code section bodies
114 for (const InputChunk *Chunk : Functions)
115 Chunk->writeTo(Buf);
116}
117
118uint32_t CodeSection::numRelocations() const {
119 uint32_t Count = 0;
120 for (const InputChunk *Func : Functions)
121 Count += Func->NumRelocations();
122 return Count;
123}
124
125void CodeSection::writeRelocations(raw_ostream &OS) const {
126 for (const InputChunk *C : Functions)
127 C->writeRelocations(OS);
128}
129
130DataSection::DataSection(ArrayRef<OutputSegment *> Segments)
131 : OutputSection(WASM_SEC_DATA), Segments(Segments) {
132 raw_string_ostream OS(DataSectionHeader);
133
134 writeUleb128(OS, Segments.size(), "data segment count");
135 OS.flush();
136 BodySize = DataSectionHeader.size();
137
138 for (OutputSegment *Segment : Segments) {
139 raw_string_ostream OS(Segment->Header);
140 writeUleb128(OS, 0, "memory index");
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;
112 for (const InputChunk *chunk : functions)
113 chunk->writeTo(buf);
114}
115
116uint32_t CodeSection::getNumRelocations() const {
117 uint32_t count = 0;
118 for (const InputChunk *func : functions)
119 count += func->getNumRelocations();
120 return count;
121}
122
123void CodeSection::writeRelocations(raw_ostream &os) const {
124 for (const InputChunk *c : functions)
125 c->writeRelocations(os);
126}
127
128void DataSection::finalizeContents() {
129 raw_string_ostream os(dataSectionHeader);
130
131 writeUleb128(os, segments.size(), "data segment count");
132 os.flush();
133 bodySize = dataSectionHeader.size();
134
135 assert((!config->isPic || segments.size() <= 1) &&
136 "Currenly only a single data segment is supported in PIC mode");
137
138 for (OutputSegment *segment : segments) {
139 raw_string_ostream os(segment->header);
140 writeUleb128(os, segment->initFlags, "init flags");
141 if (segment->initFlags & WASM_SEGMENT_HAS_MEMINDEX)
142 writeUleb128(os, 0, "memory index");
143 if ((segment->initFlags & WASM_SEGMENT_IS_PASSIVE) == 0) {
144 WasmInitExpr initExpr;
145 if (config->isPic) {
146 initExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
147 initExpr.Value.Global = WasmSym::memoryBase->getGlobalIndex();
148 } else {
149 initExpr.Opcode = WASM_OPCODE_I32_CONST;
150 initExpr.Value.Int32 = segment->startVA;
151 }
152 writeInitExpr(os, initExpr);
150153 }
151 writeInitExpr(OS, InitExpr);
152 writeUleb128(OS, Segment->Size, "segment size");
153 OS.flush();
154 writeUleb128(os, segment->size, "segment size");
155 os.flush();
154156
155 Segment->SectionOffset = BodySize;
156 BodySize += Segment->Header.size() + Segment->Size;
157 log("Data segment: size=" + Twine(Segment->Size));
157 segment->sectionOffset = bodySize;
158 bodySize += segment->header.size() + segment->size;
159 log("Data segment: size=" + Twine(segment->size) + ", startVA=" +
160 Twine::utohexstr(segment->startVA) + ", name=" + segment->name);
158161
159 for (InputSegment *InputSeg : Segment->InputSegments)
160 InputSeg->OutputOffset = Segment->SectionOffset + Segment->Header.size() +
161 InputSeg->OutputSegmentOffset;
162 for (InputSegment *inputSeg : segment->inputSegments)
163 inputSeg->outputOffset = segment->sectionOffset + segment->header.size() +
164 inputSeg->outputSegmentOffset;
162165 }
163166
164 createHeader(BodySize);
167 createHeader(bodySize);
165168}
166169
167void DataSection::writeTo(uint8_t *Buf) {
170void DataSection::writeTo(uint8_t *buf) {
168171 log("writing " + toString(*this) + " size=" + Twine(getSize()) +
169 " body=" + Twine(BodySize));
170 Buf += Offset;
172 " body=" + Twine(bodySize));
173 buf += offset;
171174
172175 // Write section header
173 memcpy(Buf, Header.data(), Header.size());
174 Buf += Header.size();
176 memcpy(buf, header.data(), header.size());
177 buf += header.size();
175178
176179 // Write data section headers
177 memcpy(Buf, DataSectionHeader.data(), DataSectionHeader.size());
180 memcpy(buf, dataSectionHeader.data(), dataSectionHeader.size());
178181
179 for (const OutputSegment *Segment : Segments) {
182 for (const OutputSegment *segment : segments) {
180183 // Write data segment header
181 uint8_t *SegStart = Buf + Segment->SectionOffset;
182 memcpy(SegStart, Segment->Header.data(), Segment->Header.size());
184 uint8_t *segStart = buf + segment->sectionOffset;
185 memcpy(segStart, segment->header.data(), segment->header.size());
183186
184187 // Write segment data payload
185 for (const InputChunk *Chunk : Segment->InputSegments)
186 Chunk->writeTo(Buf);
188 for (const InputChunk *chunk : segment->inputSegments)
189 chunk->writeTo(buf);
187190 }
188191}
189192
190uint32_t DataSection::numRelocations() const {
191 uint32_t Count = 0;
192 for (const OutputSegment *Seg : Segments)
193 for (const InputChunk *InputSeg : Seg->InputSegments)
194 Count += InputSeg->NumRelocations();
195 return Count;
193uint32_t DataSection::getNumRelocations() const {
194 uint32_t count = 0;
195 for (const OutputSegment *seg : segments)
196 for (const InputChunk *inputSeg : seg->inputSegments)
197 count += inputSeg->getNumRelocations();
198 return count;
196199}
197200
198void DataSection::writeRelocations(raw_ostream &OS) const {
199 for (const OutputSegment *Seg : Segments)
200 for (const InputChunk *C : Seg->InputSegments)
201 C->writeRelocations(OS);
201void DataSection::writeRelocations(raw_ostream &os) const {
202 for (const OutputSegment *seg : segments)
203 for (const InputChunk *c : seg->inputSegments)
204 c->writeRelocations(os);
202205}
203206
204CustomSection::CustomSection(std::string Name,
205 ArrayRef<InputSection *> InputSections)
206 : OutputSection(WASM_SEC_CUSTOM, Name), PayloadSize(0),
207 InputSections(InputSections) {
208 raw_string_ostream OS(NameData);
209 encodeULEB128(Name.size(), OS);
210 OS << Name;
211 OS.flush();
207void CustomSection::finalizeContents() {
208 raw_string_ostream os(nameData);
209 encodeULEB128(name.size(), os);
210 os << name;
211 os.flush();
212212
213 for (InputSection *Section : InputSections) {
214 Section->OutputOffset = PayloadSize;
215 PayloadSize += Section->getSize();
213 for (InputSection *section : inputSections) {
214 section->outputOffset = payloadSize;
215 section->outputSec = this;
216 payloadSize += section->getSize();
216217 }
217218
218 createHeader(PayloadSize + NameData.size());
219 createHeader(payloadSize + nameData.size());
219220}
220221
221void CustomSection::writeTo(uint8_t *Buf) {
222void CustomSection::writeTo(uint8_t *buf) {
222223 log("writing " + toString(*this) + " size=" + Twine(getSize()) +
223 " chunks=" + Twine(InputSections.size()));
224 " chunks=" + Twine(inputSections.size()));
224225
225 assert(Offset);
226 Buf += Offset;
226 assert(offset);
227 buf += offset;
227228
228229 // Write section header
229 memcpy(Buf, Header.data(), Header.size());
230 Buf += Header.size();
231 memcpy(Buf, NameData.data(), NameData.size());
232 Buf += NameData.size();
230 memcpy(buf, header.data(), header.size());
231 buf += header.size();
232 memcpy(buf, nameData.data(), nameData.size());
233 buf += nameData.size();
233234
234235 // Write custom sections payload
235 for (const InputSection *Section : InputSections)
236 Section->writeTo(Buf);
236 for (const InputSection *section : inputSections)
237 section->writeTo(buf);
237238}
238239
239uint32_t CustomSection::numRelocations() const {
240 uint32_t Count = 0;
241 for (const InputSection *InputSect : InputSections)
242 Count += InputSect->NumRelocations();
243 return Count;
240uint32_t CustomSection::getNumRelocations() const {
241 uint32_t count = 0;
242 for (const InputSection *inputSect : inputSections)
243 count += inputSect->getNumRelocations();
244 return count;
244245}
245246
246void CustomSection::writeRelocations(raw_ostream &OS) const {
247 for (const InputSection *S : InputSections)
248 S->writeRelocations(OS);
247void CustomSection::writeRelocations(raw_ostream &os) const {
248 for (const InputSection *s : inputSections)
249 s->writeRelocations(os);
249250}
deps/lld/wasm/OutputSections.h+56-73
......@@ -1,9 +1,8 @@
11//===- OutputSections.h -----------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -21,7 +20,7 @@ namespace lld {
2120namespace wasm {
2221class OutputSection;
2322}
24std::string toString(const wasm::OutputSection &Section);
23std::string toString(const wasm::OutputSection &section);
2524
2625namespace wasm {
2726
......@@ -29,86 +28,67 @@ class OutputSegment;
2928
3029class OutputSection {
3130public:
32 OutputSection(uint32_t Type, std::string Name = "")
33 : Type(Type), Name(Name) {}
31 OutputSection(uint32_t type, std::string name = "")
32 : type(type), name(name) {}
3433 virtual ~OutputSection() = default;
3534
3635 StringRef getSectionName() const;
37 void setOffset(size_t NewOffset) {
38 log("setOffset: " + toString(*this) + ": " + Twine(NewOffset));
39 Offset = NewOffset;
36 void setOffset(size_t newOffset) {
37 log("setOffset: " + toString(*this) + ": " + Twine(newOffset));
38 offset = newOffset;
4039 }
41 void createHeader(size_t BodySize);
40 void createHeader(size_t bodySize);
41 virtual bool isNeeded() const { return true; }
4242 virtual size_t getSize() const = 0;
43 virtual void writeTo(uint8_t *Buf) = 0;
44 virtual void finalizeContents() {}
45 virtual uint32_t numRelocations() const { return 0; }
46 virtual void writeRelocations(raw_ostream &OS) const {}
47
48 std::string Header;
49 uint32_t Type;
50 std::string Name;
51
52protected:
53 size_t Offset = 0;
54};
55
56class SyntheticSection : public OutputSection {
57public:
58 SyntheticSection(uint32_t Type, std::string Name = "")
59 : OutputSection(Type, Name), BodyOutputStream(Body) {
60 if (!Name.empty())
61 writeStr(BodyOutputStream, Name, "section name");
62 }
43 virtual void writeTo(uint8_t *buf) = 0;
44 virtual void finalizeContents() = 0;
45 virtual uint32_t getNumRelocations() const { return 0; }
46 virtual void writeRelocations(raw_ostream &os) const {}
6347
64 void writeTo(uint8_t *Buf) override {
65 assert(Offset);
66 log("writing " + toString(*this));
67 memcpy(Buf + Offset, Header.data(), Header.size());
68 memcpy(Buf + Offset + Header.size(), Body.data(), Body.size());
69 }
70
71 size_t getSize() const override { return Header.size() + Body.size(); }
72
73 void finalizeContents() override {
74 BodyOutputStream.flush();
75 createHeader(Body.size());
76 }
77
78 raw_ostream &getStream() { return BodyOutputStream; }
79
80 std::string Body;
48 std::string header;
49 uint32_t type;
50 uint32_t sectionIndex = UINT32_MAX;
51 std::string name;
52 OutputSectionSymbol *sectionSym = nullptr;
8153
8254protected:
83 llvm::raw_string_ostream BodyOutputStream;
55 size_t offset = 0;
8456};
8557
8658class CodeSection : public OutputSection {
8759public:
88 explicit CodeSection(ArrayRef<InputFunction *> Functions);
89 size_t getSize() const override { return Header.size() + BodySize; }
90 void writeTo(uint8_t *Buf) override;
91 uint32_t numRelocations() const override;
92 void writeRelocations(raw_ostream &OS) const override;
60 explicit CodeSection(ArrayRef<InputFunction *> functions)
61 : OutputSection(llvm::wasm::WASM_SEC_CODE), functions(functions) {}
62
63 size_t getSize() const override { return header.size() + bodySize; }
64 void writeTo(uint8_t *buf) override;
65 uint32_t getNumRelocations() const override;
66 void writeRelocations(raw_ostream &os) const override;
67 bool isNeeded() const override { return functions.size() > 0; }
68 void finalizeContents() override;
9369
9470protected:
95 ArrayRef<InputFunction *> Functions;
96 std::string CodeSectionHeader;
97 size_t BodySize = 0;
71 ArrayRef<InputFunction *> functions;
72 std::string codeSectionHeader;
73 size_t bodySize = 0;
9874};
9975
10076class DataSection : public OutputSection {
10177public:
102 explicit DataSection(ArrayRef<OutputSegment *> Segments);
103 size_t getSize() const override { return Header.size() + BodySize; }
104 void writeTo(uint8_t *Buf) override;
105 uint32_t numRelocations() const override;
106 void writeRelocations(raw_ostream &OS) const override;
78 explicit DataSection(ArrayRef<OutputSegment *> segments)
79 : OutputSection(llvm::wasm::WASM_SEC_DATA), segments(segments) {}
80
81 size_t getSize() const override { return header.size() + bodySize; }
82 void writeTo(uint8_t *buf) override;
83 uint32_t getNumRelocations() const override;
84 void writeRelocations(raw_ostream &os) const override;
85 bool isNeeded() const override { return segments.size() > 0; }
86 void finalizeContents() override;
10787
10888protected:
109 ArrayRef<OutputSegment *> Segments;
110 std::string DataSectionHeader;
111 size_t BodySize = 0;
89 ArrayRef<OutputSegment *> segments;
90 std::string dataSectionHeader;
91 size_t bodySize = 0;
11292};
11393
11494// Represents a custom section in the output file. Wasm custom sections are
......@@ -120,18 +100,21 @@ protected:
120100// separately and are instead synthesized by the linker.
121101class CustomSection : public OutputSection {
122102public:
123 CustomSection(std::string Name, ArrayRef<InputSection *> InputSections);
103 CustomSection(std::string name, ArrayRef<InputSection *> inputSections)
104 : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, name),
105 inputSections(inputSections) {}
124106 size_t getSize() const override {
125 return Header.size() + NameData.size() + PayloadSize;
107 return header.size() + nameData.size() + payloadSize;
126108 }
127 void writeTo(uint8_t *Buf) override;
128 uint32_t numRelocations() const override;
129 void writeRelocations(raw_ostream &OS) const override;
109 void writeTo(uint8_t *buf) override;
110 uint32_t getNumRelocations() const override;
111 void writeRelocations(raw_ostream &os) const override;
112 void finalizeContents() override;
130113
131114protected:
132 size_t PayloadSize;
133 ArrayRef<InputSection *> InputSections;
134 std::string NameData;
115 size_t payloadSize = 0;
116 ArrayRef<InputSection *> inputSections;
117 std::string nameData;
135118};
136119
137120} // namespace wasm
deps/lld/wasm/OutputSegment.h+21-21
......@@ -1,9 +1,8 @@
11//===- OutputSegment.h ------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -21,29 +20,30 @@ class InputSegment;
2120
2221class OutputSegment {
2322public:
24 OutputSegment(StringRef N, uint32_t Index) : Name(N), Index(Index) {}
25
26 void addInputSegment(InputSegment *InSeg) {
27 Alignment = std::max(Alignment, InSeg->getAlignment());
28 InputSegments.push_back(InSeg);
29 Size = llvm::alignTo(Size, 1 << InSeg->getAlignment());
30 InSeg->OutputSeg = this;
31 InSeg->OutputSegmentOffset = Size;
32 Size += InSeg->getSize();
23 OutputSegment(StringRef n, uint32_t index) : name(n), index(index) {}
24
25 void addInputSegment(InputSegment *inSeg) {
26 alignment = std::max(alignment, inSeg->getAlignment());
27 inputSegments.push_back(inSeg);
28 size = llvm::alignTo(size, 1ULL << inSeg->getAlignment());
29 inSeg->outputSeg = this;
30 inSeg->outputSegmentOffset = size;
31 size += inSeg->getSize();
3332 }
3433
35 StringRef Name;
36 const uint32_t Index;
37 uint32_t SectionOffset = 0;
38 uint32_t Alignment = 0;
39 uint32_t StartVA = 0;
40 std::vector<InputSegment *> InputSegments;
34 StringRef name;
35 const uint32_t index;
36 uint32_t initFlags = 0;
37 uint32_t sectionOffset = 0;
38 uint32_t alignment = 0;
39 uint32_t startVA = 0;
40 std::vector<InputSegment *> inputSegments;
4141
4242 // Sum of the size of the all the input segments
43 uint32_t Size = 0;
43 uint32_t size = 0;
4444
4545 // Segment header
46 std::string Header;
46 std::string header;
4747};
4848
4949} // namespace wasm
deps/lld/wasm/Relocations.cpp created+101
......@@ -0,0 +1,101 @@
1//===- Relocations.cpp ----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "Relocations.h"
10
11#include "InputChunks.h"
12#include "SyntheticSections.h"
13
14using namespace llvm;
15using namespace llvm::wasm;
16
17using namespace lld;
18using namespace lld::wasm;
19
20static bool requiresGOTAccess(const Symbol *sym) {
21 return config->isPic && !sym->isHidden() && !sym->isLocal();
22}
23
24static bool allowUndefined(const Symbol* sym) {
25 // Historically --allow-undefined doesn't work for data symbols since we don't
26 // have any way to represent these as imports in the final binary. The idea
27 // behind allowing undefined symbols is to allow importing these symbols from
28 // the embedder and we can't do this for data symbols (at least not without
29 // compiling with -fPIC)
30 if (isa<DataSymbol>(sym))
31 return false;
32 return (config->allowUndefined ||
33 config->allowUndefinedSymbols.count(sym->getName()) != 0);
34}
35
36static void reportUndefined(const Symbol* sym) {
37 assert(sym->isUndefined());
38 assert(!sym->isWeak());
39 if (!allowUndefined(sym))
40 error(toString(sym->getFile()) + ": undefined symbol: " + toString(*sym));
41}
42
43void lld::wasm::scanRelocations(InputChunk *chunk) {
44 if (!chunk->live)
45 return;
46 ObjFile *file = chunk->file;
47 ArrayRef<WasmSignature> types = file->getWasmObj()->types();
48 for (const WasmRelocation &reloc : chunk->getRelocations()) {
49 if (reloc.Type == R_WASM_TYPE_INDEX_LEB) {
50 // Mark target type as live
51 file->typeMap[reloc.Index] =
52 out.typeSec->registerType(types[reloc.Index]);
53 file->typeIsUsed[reloc.Index] = true;
54 continue;
55 }
56
57 // Other relocation types all have a corresponding symbol
58 Symbol *sym = file->getSymbols()[reloc.Index];
59
60 switch (reloc.Type) {
61 case R_WASM_TABLE_INDEX_I32:
62 case R_WASM_TABLE_INDEX_SLEB:
63 case R_WASM_TABLE_INDEX_REL_SLEB:
64 if (requiresGOTAccess(sym))
65 break;
66 out.elemSec->addEntry(cast<FunctionSymbol>(sym));
67 break;
68 case R_WASM_GLOBAL_INDEX_LEB:
69 if (!isa<GlobalSymbol>(sym))
70 out.importSec->addGOTEntry(sym);
71 break;
72 }
73
74 if (config->isPic) {
75 switch (reloc.Type) {
76 case R_WASM_TABLE_INDEX_SLEB:
77 case R_WASM_MEMORY_ADDR_SLEB:
78 case R_WASM_MEMORY_ADDR_LEB:
79 // Certain relocation types can't be used when building PIC output,
80 // since they would require absolute symbol addresses at link time.
81 error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) +
82 " cannot be used against symbol " + toString(*sym) +
83 "; recompile with -fPIC");
84 break;
85 case R_WASM_TABLE_INDEX_I32:
86 case R_WASM_MEMORY_ADDR_I32:
87 // These relocation types are only present in the data section and
88 // will be converted into code by `generateRelocationCode`. This code
89 // requires the symbols to have GOT entires.
90 if (requiresGOTAccess(sym))
91 out.importSec->addGOTEntry(sym);
92 break;
93 }
94 } else {
95 // Report undefined symbols
96 if (sym->isUndefined() && !config->relocatable && !sym->isWeak())
97 reportUndefined(sym);
98 }
99
100 }
101}
deps/lld/wasm/Relocations.h created+22
......@@ -0,0 +1,22 @@
1//===- Relocations.h -------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLD_WASM_RELOCATIONS_H
10#define LLD_WASM_RELOCATIONS_H
11
12namespace lld {
13namespace wasm {
14
15class InputChunk;
16
17void scanRelocations(InputChunk *chunk);
18
19} // namespace wasm
20} // namespace lld
21
22#endif
deps/lld/wasm/SymbolTable.cpp+541-255
......@@ -1,9 +1,8 @@
11//===- SymbolTable.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -25,17 +24,37 @@ using namespace llvm::object;
2524using namespace lld;
2625using namespace lld::wasm;
2726
28SymbolTable *lld::wasm::Symtab;
27SymbolTable *lld::wasm::symtab;
2928
30void SymbolTable::addFile(InputFile *File) {
31 log("Processing: " + toString(File));
32 File->parse();
29void SymbolTable::addFile(InputFile *file) {
30 log("Processing: " + toString(file));
31
32 // .a file
33 if (auto *f = dyn_cast<ArchiveFile>(file)) {
34 f->parse();
35 return;
36 }
37
38 // .so file
39 if (auto *f = dyn_cast<SharedFile>(file)) {
40 sharedFiles.push_back(f);
41 return;
42 }
43
44 if (config->trace)
45 message(toString(file));
3346
3447 // LLVM bitcode file
35 if (auto *F = dyn_cast<BitcodeFile>(File))
36 BitcodeFiles.push_back(F);
37 else if (auto *F = dyn_cast<ObjFile>(File))
38 ObjectFiles.push_back(F);
48 if (auto *f = dyn_cast<BitcodeFile>(file)) {
49 f->parse();
50 bitcodeFiles.push_back(f);
51 return;
52 }
53
54 // Regular object file
55 auto *f = cast<ObjFile>(file);
56 f->parse(false);
57 objectFiles.push_back(f);
3958}
4059
4160// This function is where all the optimizations of link-time
......@@ -46,353 +65,620 @@ void SymbolTable::addFile(InputFile *File) {
4665// Because all bitcode files that the program consists of are passed
4766// to the compiler at once, it can do whole-program optimization.
4867void SymbolTable::addCombinedLTOObject() {
49 if (BitcodeFiles.empty())
68 if (bitcodeFiles.empty())
5069 return;
5170
5271 // Compile bitcode files and replace bitcode symbols.
53 LTO.reset(new BitcodeCompiler);
54 for (BitcodeFile *F : BitcodeFiles)
55 LTO->add(*F);
56
57 for (StringRef Filename : LTO->compile()) {
58 auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp"));
59 Obj->parse();
60 ObjectFiles.push_back(Obj);
72 lto.reset(new BitcodeCompiler);
73 for (BitcodeFile *f : bitcodeFiles)
74 lto->add(*f);
75
76 for (StringRef filename : lto->compile()) {
77 auto *obj = make<ObjFile>(MemoryBufferRef(filename, "lto.tmp"), "");
78 obj->parse(true);
79 objectFiles.push_back(obj);
6180 }
6281}
6382
64void SymbolTable::reportRemainingUndefines() {
65 for (Symbol *Sym : SymVector) {
66 if (!Sym->isUndefined() || Sym->isWeak())
67 continue;
68 if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0)
69 continue;
70 if (!Sym->IsUsedInRegularObj)
71 continue;
72 error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym));
73 }
83Symbol *SymbolTable::find(StringRef name) {
84 auto it = symMap.find(CachedHashStringRef(name));
85 if (it == symMap.end() || it->second == -1)
86 return nullptr;
87 return symVector[it->second];
7488}
7589
76Symbol *SymbolTable::find(StringRef Name) {
77 return SymMap.lookup(CachedHashStringRef(Name));
90void SymbolTable::replace(StringRef name, Symbol* sym) {
91 auto it = symMap.find(CachedHashStringRef(name));
92 symVector[it->second] = sym;
7893}
7994
80std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
81 bool Inserted = false;
82 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
83 if (!Sym) {
84 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
85 Sym->IsUsedInRegularObj = false;
86 SymVector.emplace_back(Sym);
87 Inserted = true;
95std::pair<Symbol *, bool> SymbolTable::insertName(StringRef name) {
96 bool trace = false;
97 auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
98 int &symIndex = p.first->second;
99 bool isNew = p.second;
100 if (symIndex == -1) {
101 symIndex = symVector.size();
102 trace = true;
103 isNew = true;
88104 }
89 if (!File || File->kind() == InputFile::ObjectKind)
90 Sym->IsUsedInRegularObj = true;
91 return {Sym, Inserted};
92}
93105
94static void reportTypeError(const Symbol *Existing, const InputFile *File,
95 llvm::wasm::WasmSymbolType Type) {
96 error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " +
97 toString(Existing->getWasmType()) + " in " +
98 toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) +
99 " in " + toString(File));
106 if (!isNew)
107 return {symVector[symIndex], false};
108
109 Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
110 sym->isUsedInRegularObj = false;
111 sym->canInline = true;
112 sym->traced = trace;
113 symVector.emplace_back(sym);
114 return {sym, true};
100115}
101116
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.
104static void checkFunctionType(Symbol *Existing, const InputFile *File,
105 const WasmSignature *NewSig) {
106 auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);
107 if (!ExistingFunction) {
108 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_FUNCTION);
109 return;
110 }
117std::pair<Symbol *, bool> SymbolTable::insert(StringRef name,
118 const InputFile *file) {
119 Symbol *s;
120 bool wasInserted;
121 std::tie(s, wasInserted) = insertName(name);
111122
112 if (!NewSig)
113 return;
123 if (!file || file->kind() == InputFile::ObjectKind)
124 s->isUsedInRegularObj = true;
114125
115 const WasmSignature *OldSig = ExistingFunction->Signature;
116 if (!OldSig) {
117 ExistingFunction->Signature = NewSig;
118 return;
119 }
126 return {s, wasInserted};
127}
120128
121 if (*NewSig != *OldSig)
122 warn("function signature mismatch: " + Existing->getName() +
123 "\n>>> defined as " + toString(*OldSig) + " in " +
124 toString(Existing->getFile()) + "\n>>> defined as " +
125 toString(*NewSig) + " in " + toString(File));
129static void reportTypeError(const Symbol *existing, const InputFile *file,
130 llvm::wasm::WasmSymbolType type) {
131 error("symbol type mismatch: " + toString(*existing) + "\n>>> defined as " +
132 toString(existing->getWasmType()) + " in " +
133 toString(existing->getFile()) + "\n>>> defined as " + toString(type) +
134 " in " + toString(file));
126135}
127136
128static void checkGlobalType(const Symbol *Existing, const InputFile *File,
129 const WasmGlobalType *NewType) {
130 if (!isa<GlobalSymbol>(Existing)) {
131 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL);
137// Check the type of new symbol matches that of the symbol is replacing.
138// Returns true if the function types match, false is there is a singature
139// mismatch.
140static bool signatureMatches(FunctionSymbol *existing,
141 const WasmSignature *newSig) {
142 const WasmSignature *oldSig = existing->signature;
143
144 // If either function is missing a signature (this happend for bitcode
145 // symbols) then assume they match. Any mismatch will be reported later
146 // when the LTO objects are added.
147 if (!newSig || !oldSig)
148 return true;
149
150 return *newSig == *oldSig;
151}
152
153static void checkGlobalType(const Symbol *existing, const InputFile *file,
154 const WasmGlobalType *newType) {
155 if (!isa<GlobalSymbol>(existing)) {
156 reportTypeError(existing, file, WASM_SYMBOL_TYPE_GLOBAL);
132157 return;
133158 }
134159
135 const WasmGlobalType *OldType = cast<GlobalSymbol>(Existing)->getGlobalType();
136 if (*NewType != *OldType) {
137 error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " +
138 toString(*OldType) + " in " + toString(Existing->getFile()) +
139 "\n>>> defined as " + toString(*NewType) + " in " + toString(File));
160 const WasmGlobalType *oldType = cast<GlobalSymbol>(existing)->getGlobalType();
161 if (*newType != *oldType) {
162 error("Global type mismatch: " + existing->getName() + "\n>>> defined as " +
163 toString(*oldType) + " in " + toString(existing->getFile()) +
164 "\n>>> defined as " + toString(*newType) + " in " + toString(file));
140165 }
141166}
142167
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);
168static void checkEventType(const Symbol *existing, const InputFile *file,
169 const WasmEventType *newType,
170 const WasmSignature *newSig) {
171 auto existingEvent = dyn_cast<EventSymbol>(existing);
172 if (!isa<EventSymbol>(existing)) {
173 reportTypeError(existing, file, WASM_SYMBOL_TYPE_EVENT);
149174 return;
150175 }
151176
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));
177 const WasmEventType *oldType = cast<EventSymbol>(existing)->getEventType();
178 const WasmSignature *oldSig = existingEvent->signature;
179 if (newType->Attribute != oldType->Attribute)
180 error("Event type mismatch: " + existing->getName() + "\n>>> defined as " +
181 toString(*oldType) + " in " + toString(existing->getFile()) +
182 "\n>>> defined as " + toString(*newType) + " in " + toString(file));
183 if (*newSig != *oldSig)
184 warn("Event signature mismatch: " + existing->getName() +
185 "\n>>> defined as " + toString(*oldSig) + " in " +
186 toString(existing->getFile()) + "\n>>> defined as " +
187 toString(*newSig) + " in " + toString(file));
188}
189
190static void checkDataType(const Symbol *existing, const InputFile *file) {
191 if (!isa<DataSymbol>(existing))
192 reportTypeError(existing, file, WASM_SYMBOL_TYPE_DATA);
163193}
164194
165static void checkDataType(const Symbol *Existing, const InputFile *File) {
166 if (!isa<DataSymbol>(Existing))
167 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA);
195DefinedFunction *SymbolTable::addSyntheticFunction(StringRef name,
196 uint32_t flags,
197 InputFunction *function) {
198 LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << name << "\n");
199 assert(!find(name));
200 syntheticFunctions.emplace_back(function);
201 return replaceSymbol<DefinedFunction>(insertName(name).first, name,
202 flags, nullptr, function);
168203}
169204
170DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
171 uint32_t Flags,
172 InputFunction *Function) {
173 LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
174 assert(!find(Name));
175 SyntheticFunctions.emplace_back(Function);
176 return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name,
177 Flags, nullptr, Function);
205// Adds an optional, linker generated, data symbols. The symbol will only be
206// added if there is an undefine reference to it, or if it is explictly exported
207// via the --export flag. Otherwise we don't add the symbol and return nullptr.
208DefinedData *SymbolTable::addOptionalDataSymbol(StringRef name, uint32_t value,
209 uint32_t flags) {
210 Symbol *s = find(name);
211 if (!s && (config->exportAll || config->exportedSymbols.count(name) != 0))
212 s = insertName(name).first;
213 else if (!s || s->isDefined())
214 return nullptr;
215 LLVM_DEBUG(dbgs() << "addOptionalDataSymbol: " << name << "\n");
216 auto *rtn = replaceSymbol<DefinedData>(s, name, flags);
217 rtn->setVirtualAddress(value);
218 rtn->referenced = true;
219 return rtn;
178220}
179221
180DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
181 uint32_t Flags) {
182 LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
183 assert(!find(Name));
184 return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags);
222DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef name,
223 uint32_t flags) {
224 LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << name << "\n");
225 assert(!find(name));
226 return replaceSymbol<DefinedData>(insertName(name).first, name, flags);
185227}
186228
187DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
188 InputGlobal *Global) {
189 LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global
229DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef name, uint32_t flags,
230 InputGlobal *global) {
231 LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << name << " -> " << global
190232 << "\n");
191 assert(!find(Name));
192 SyntheticGlobals.emplace_back(Global);
193 return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags,
194 nullptr, Global);
233 assert(!find(name));
234 syntheticGlobals.emplace_back(global);
235 return replaceSymbol<DefinedGlobal>(insertName(name).first, name, flags,
236 nullptr, global);
195237}
196238
197static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,
198 uint32_t NewFlags) {
239static bool shouldReplace(const Symbol *existing, InputFile *newFile,
240 uint32_t newFlags) {
199241 // If existing symbol is undefined, replace it.
200 if (!Existing->isDefined()) {
242 if (!existing->isDefined()) {
201243 LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: "
202 << Existing->getName() << "\n");
244 << existing->getName() << "\n");
203245 return true;
204246 }
205247
206248 // Now we have two defined symbols. If the new one is weak, we can ignore it.
207 if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
249 if ((newFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
208250 LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n");
209251 return false;
210252 }
211253
212254 // If the existing symbol is weak, we should replace it.
213 if (Existing->isWeak()) {
255 if (existing->isWeak()) {
214256 LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n");
215257 return true;
216258 }
217259
218260 // Neither symbol is week. They conflict.
219 error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " +
220 toString(Existing->getFile()) + "\n>>> defined in " +
221 toString(NewFile));
261 error("duplicate symbol: " + toString(*existing) + "\n>>> defined in " +
262 toString(existing->getFile()) + "\n>>> defined in " +
263 toString(newFile));
222264 return true;
223265}
224266
225Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
226 InputFile *File,
227 InputFunction *Function) {
228 LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " ["
229 << (Function ? toString(Function->Signature) : "none")
267Symbol *SymbolTable::addDefinedFunction(StringRef name, uint32_t flags,
268 InputFile *file,
269 InputFunction *function) {
270 LLVM_DEBUG(dbgs() << "addDefinedFunction: " << name << " ["
271 << (function ? toString(function->signature) : "none")
230272 << "]\n");
231 Symbol *S;
232 bool WasInserted;
233 std::tie(S, WasInserted) = insert(Name, File);
273 Symbol *s;
274 bool wasInserted;
275 std::tie(s, wasInserted) = insert(name, file);
234276
235 if (WasInserted || S->isLazy()) {
236 replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
237 return S;
277 auto replaceSym = [&](Symbol *sym) {
278 // If the new defined function doesn't have signture (i.e. bitcode
279 // functions) but the old symbol does, then preserve the old signature
280 const WasmSignature *oldSig = s->getSignature();
281 auto* newSym = replaceSymbol<DefinedFunction>(sym, name, flags, file, function);
282 if (!newSym->signature)
283 newSym->signature = oldSig;
284 };
285
286 if (wasInserted || s->isLazy()) {
287 replaceSym(s);
288 return s;
238289 }
239290
240 if (Function)
241 checkFunctionType(S, File, &Function->Signature);
291 auto existingFunction = dyn_cast<FunctionSymbol>(s);
292 if (!existingFunction) {
293 reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
294 return s;
295 }
242296
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;
297 bool checkSig = true;
298 if (auto ud = dyn_cast<UndefinedFunction>(existingFunction))
299 checkSig = ud->isCalledDirectly;
300
301 if (checkSig && function && !signatureMatches(existingFunction, &function->signature)) {
302 Symbol* variant;
303 if (getFunctionVariant(s, &function->signature, file, &variant))
304 // New variant, always replace
305 replaceSym(variant);
306 else if (shouldReplace(s, file, flags))
307 // Variant already exists, replace it after checking shouldReplace
308 replaceSym(variant);
309
310 // This variant we found take the place in the symbol table as the primary
311 // variant.
312 replace(name, variant);
313 return variant;
252314 }
253 return S;
315
316 // Existing function with matching signature.
317 if (shouldReplace(s, file, flags))
318 replaceSym(s);
319
320 return s;
254321}
255322
256Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
257 InputFile *File, InputSegment *Segment,
258 uint32_t Address, uint32_t Size) {
259 LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address
323Symbol *SymbolTable::addDefinedData(StringRef name, uint32_t flags,
324 InputFile *file, InputSegment *segment,
325 uint32_t address, uint32_t size) {
326 LLVM_DEBUG(dbgs() << "addDefinedData:" << name << " addr:" << address
260327 << "\n");
261 Symbol *S;
262 bool WasInserted;
263 std::tie(S, WasInserted) = insert(Name, File);
328 Symbol *s;
329 bool wasInserted;
330 std::tie(s, wasInserted) = insert(name, file);
331
332 auto replaceSym = [&]() {
333 replaceSymbol<DefinedData>(s, name, flags, file, segment, address, size);
334 };
264335
265 if (WasInserted || S->isLazy()) {
266 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
267 return S;
336 if (wasInserted || s->isLazy()) {
337 replaceSym();
338 return s;
268339 }
269340
270 checkDataType(S, File);
341 checkDataType(s, file);
271342
272 if (shouldReplace(S, File, Flags))
273 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
274 return S;
343 if (shouldReplace(s, file, flags))
344 replaceSym();
345 return s;
275346}
276347
277Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
278 InputFile *File, InputGlobal *Global) {
279 LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
348Symbol *SymbolTable::addDefinedGlobal(StringRef name, uint32_t flags,
349 InputFile *file, InputGlobal *global) {
350 LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << name << "\n");
280351
281 Symbol *S;
282 bool WasInserted;
283 std::tie(S, WasInserted) = insert(Name, File);
352 Symbol *s;
353 bool wasInserted;
354 std::tie(s, wasInserted) = insert(name, file);
284355
285 if (WasInserted || S->isLazy()) {
286 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
287 return S;
356 auto replaceSym = [&]() {
357 replaceSymbol<DefinedGlobal>(s, name, flags, file, global);
358 };
359
360 if (wasInserted || s->isLazy()) {
361 replaceSym();
362 return s;
288363 }
289364
290 checkGlobalType(S, File, &Global->getType());
365 checkGlobalType(s, file, &global->getType());
291366
292 if (shouldReplace(S, File, Flags))
293 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
294 return S;
367 if (shouldReplace(s, file, flags))
368 replaceSym();
369 return s;
295370}
296371
297Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags,
298 InputFile *File, InputEvent *Event) {
299 LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n");
372Symbol *SymbolTable::addDefinedEvent(StringRef name, uint32_t flags,
373 InputFile *file, InputEvent *event) {
374 LLVM_DEBUG(dbgs() << "addDefinedEvent:" << name << "\n");
375
376 Symbol *s;
377 bool wasInserted;
378 std::tie(s, wasInserted) = insert(name, file);
300379
301 Symbol *S;
302 bool WasInserted;
303 std::tie(S, WasInserted) = insert(Name, File);
380 auto replaceSym = [&]() {
381 replaceSymbol<DefinedEvent>(s, name, flags, file, event);
382 };
304383
305 if (WasInserted || S->isLazy()) {
306 replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
307 return S;
384 if (wasInserted || s->isLazy()) {
385 replaceSym();
386 return s;
308387 }
309388
310 checkEventType(S, File, &Event->getType(), &Event->Signature);
389 checkEventType(s, file, &event->getType(), &event->signature);
311390
312 if (shouldReplace(S, File, Flags))
313 replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
314 return S;
391 if (shouldReplace(s, file, flags))
392 replaceSym();
393 return s;
315394}
316395
317Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName,
318 StringRef ImportModule,
319 uint32_t Flags, InputFile *File,
320 const WasmSignature *Sig) {
321 LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
322 " [" << (Sig ? toString(*Sig) : "none") << "]\n");
396Symbol *SymbolTable::addUndefinedFunction(StringRef name, StringRef importName,
397 StringRef importModule,
398 uint32_t flags, InputFile *file,
399 const WasmSignature *sig,
400 bool isCalledDirectly) {
401 LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << name << " ["
402 << (sig ? toString(*sig) : "none")
403 << "] IsCalledDirectly:" << isCalledDirectly << "\n");
404
405 Symbol *s;
406 bool wasInserted;
407 std::tie(s, wasInserted) = insert(name, file);
408 if (s->traced)
409 printTraceSymbolUndefined(name, file);
410
411 auto replaceSym = [&]() {
412 replaceSymbol<UndefinedFunction>(s, name, importName, importModule, flags,
413 file, sig, isCalledDirectly);
414 };
415
416 if (wasInserted)
417 replaceSym();
418 else if (auto *lazy = dyn_cast<LazySymbol>(s))
419 lazy->fetch();
420 else {
421 auto existingFunction = dyn_cast<FunctionSymbol>(s);
422 if (!existingFunction) {
423 reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
424 return s;
425 }
426 if (!existingFunction->signature && sig)
427 existingFunction->signature = sig;
428 if (isCalledDirectly && !signatureMatches(existingFunction, sig))
429 if (getFunctionVariant(s, sig, file, &s))
430 replaceSym();
431 }
323432
324 Symbol *S;
325 bool WasInserted;
326 std::tie(S, WasInserted) = insert(Name, File);
433 return s;
434}
327435
328 if (WasInserted)
329 replaceSymbol<UndefinedFunction>(S, Name, ImportName, ImportModule, Flags,
330 File, Sig);
331 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
332 Lazy->fetch();
333 else
334 checkFunctionType(S, File, Sig);
436Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
437 InputFile *file) {
438 LLVM_DEBUG(dbgs() << "addUndefinedData: " << name << "\n");
439
440 Symbol *s;
441 bool wasInserted;
442 std::tie(s, wasInserted) = insert(name, file);
443 if (s->traced)
444 printTraceSymbolUndefined(name, file);
445
446 if (wasInserted)
447 replaceSymbol<UndefinedData>(s, name, flags, file);
448 else if (auto *lazy = dyn_cast<LazySymbol>(s))
449 lazy->fetch();
450 else if (s->isDefined())
451 checkDataType(s, file);
452 return s;
453}
335454
336 return S;
455Symbol *SymbolTable::addUndefinedGlobal(StringRef name, StringRef importName,
456 StringRef importModule, uint32_t flags,
457 InputFile *file,
458 const WasmGlobalType *type) {
459 LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << name << "\n");
460
461 Symbol *s;
462 bool wasInserted;
463 std::tie(s, wasInserted) = insert(name, file);
464 if (s->traced)
465 printTraceSymbolUndefined(name, file);
466
467 if (wasInserted)
468 replaceSymbol<UndefinedGlobal>(s, name, importName, importModule, flags,
469 file, type);
470 else if (auto *lazy = dyn_cast<LazySymbol>(s))
471 lazy->fetch();
472 else if (s->isDefined())
473 checkGlobalType(s, file, type);
474 return s;
337475}
338476
339Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,
340 InputFile *File) {
341 LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n");
477void SymbolTable::addLazy(ArchiveFile *file, const Archive::Symbol *sym) {
478 LLVM_DEBUG(dbgs() << "addLazy: " << sym->getName() << "\n");
479 StringRef name = sym->getName();
342480
343 Symbol *S;
344 bool WasInserted;
345 std::tie(S, WasInserted) = insert(Name, File);
481 Symbol *s;
482 bool wasInserted;
483 std::tie(s, wasInserted) = insertName(name);
346484
347 if (WasInserted)
348 replaceSymbol<UndefinedData>(S, Name, Flags, File);
349 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
350 Lazy->fetch();
351 else if (S->isDefined())
352 checkDataType(S, File);
353 return S;
354}
485 if (wasInserted) {
486 replaceSymbol<LazySymbol>(s, name, 0, file, *sym);
487 return;
488 }
355489
356Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, StringRef ImportName,
357 StringRef ImportModule, uint32_t Flags,
358 InputFile *File,
359 const WasmGlobalType *Type) {
360 LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n");
490 if (!s->isUndefined())
491 return;
361492
362 Symbol *S;
363 bool WasInserted;
364 std::tie(S, WasInserted) = insert(Name, File);
493 // The existing symbol is undefined, load a new one from the archive,
494 // unless the the existing symbol is weak in which case replace the undefined
495 // symbols with a LazySymbol.
496 if (s->isWeak()) {
497 const WasmSignature *oldSig = nullptr;
498 // In the case of an UndefinedFunction we need to preserve the expected
499 // signature.
500 if (auto *f = dyn_cast<UndefinedFunction>(s))
501 oldSig = f->signature;
502 LLVM_DEBUG(dbgs() << "replacing existing weak undefined symbol\n");
503 auto newSym = replaceSymbol<LazySymbol>(s, name, WASM_SYMBOL_BINDING_WEAK,
504 file, *sym);
505 newSym->signature = oldSig;
506 return;
507 }
365508
366 if (WasInserted)
367 replaceSymbol<UndefinedGlobal>(S, Name, ImportName, ImportModule, Flags,
368 File, Type);
369 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
370 Lazy->fetch();
371 else if (S->isDefined())
372 checkGlobalType(S, File, Type);
373 return S;
509 LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
510 file->addMember(sym);
374511}
375512
376void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {
377 LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n");
378 StringRef Name = Sym->getName();
513bool SymbolTable::addComdat(StringRef name) {
514 return comdatGroups.insert(CachedHashStringRef(name)).second;
515}
379516
380 Symbol *S;
381 bool WasInserted;
382 std::tie(S, WasInserted) = insert(Name, nullptr);
517// The new signature doesn't match. Create a variant to the symbol with the
518// signature encoded in the name and return that instead. These symbols are
519// then unified later in handleSymbolVariants.
520bool SymbolTable::getFunctionVariant(Symbol* sym, const WasmSignature *sig,
521 const InputFile *file, Symbol **out) {
522 LLVM_DEBUG(dbgs() << "getFunctionVariant: " << sym->getName() << " -> "
523 << " " << toString(*sig) << "\n");
524 Symbol *variant = nullptr;
525
526 // Linear search through symbol variants. Should never be more than two
527 // or three entries here.
528 auto &variants = symVariants[CachedHashStringRef(sym->getName())];
529 if (variants.empty())
530 variants.push_back(sym);
531
532 for (Symbol* v : variants) {
533 if (*v->getSignature() == *sig) {
534 variant = v;
535 break;
536 }
537 }
383538
384 if (WasInserted) {
385 replaceSymbol<LazySymbol>(S, Name, File, *Sym);
386 return;
539 bool wasAdded = !variant;
540 if (wasAdded) {
541 // Create a new variant;
542 LLVM_DEBUG(dbgs() << "added new variant\n");
543 variant = reinterpret_cast<Symbol *>(make<SymbolUnion>());
544 variants.push_back(variant);
545 } else {
546 LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*variant) << "\n");
547 assert(*variant->getSignature() == *sig);
387548 }
388549
389 // If there is an existing undefined symbol, load a new one from the archive.
390 if (S->isUndefined()) {
391 LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
392 File->addMember(Sym);
550 *out = variant;
551 return wasAdded;
552}
553
554// Set a flag for --trace-symbol so that we can print out a log message
555// if a new symbol with the same name is inserted into the symbol table.
556void SymbolTable::trace(StringRef name) {
557 symMap.insert({CachedHashStringRef(name), -1});
558}
559
560void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
561 // Swap symbols as instructed by -wrap.
562 int &origIdx = symMap[CachedHashStringRef(sym->getName())];
563 int &realIdx= symMap[CachedHashStringRef(real->getName())];
564 int &wrapIdx = symMap[CachedHashStringRef(wrap->getName())];
565 LLVM_DEBUG(dbgs() << "wrap: " << sym->getName() << "\n");
566
567 // Anyone looking up __real symbols should get the original
568 realIdx = origIdx;
569 // Anyone looking up the original should get the __wrap symbol
570 origIdx = wrapIdx;
571}
572
573static const uint8_t unreachableFn[] = {
574 0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
575 0x00 /* opcode unreachable */, 0x0b /* opcode end */
576};
577
578// Replace the given symbol body with an unreachable function.
579// This is used by handleWeakUndefines in order to generate a callable
580// equivalent of an undefined function and also handleSymbolVariants for
581// undefined functions that don't match the signature of the definition.
582InputFunction *SymbolTable::replaceWithUnreachable(Symbol *sym,
583 const WasmSignature &sig,
584 StringRef debugName) {
585 auto *func = make<SyntheticFunction>(sig, sym->getName(), debugName);
586 func->setBody(unreachableFn);
587 syntheticFunctions.emplace_back(func);
588 replaceSymbol<DefinedFunction>(sym, sym->getName(), sym->getFlags(), nullptr,
589 func);
590 return func;
591}
592
593// For weak undefined functions, there may be "call" instructions that reference
594// the symbol. In this case, we need to synthesise a dummy/stub function that
595// will abort at runtime, so that relocations can still provided an operand to
596// the call instruction that passes Wasm validation.
597void SymbolTable::handleWeakUndefines() {
598 for (Symbol *sym : getSymbols()) {
599 if (!sym->isUndefWeak())
600 continue;
601
602 const WasmSignature *sig = sym->getSignature();
603 if (!sig) {
604 // It is possible for undefined functions not to have a signature (eg. if
605 // added via "--undefined"), but weak undefined ones do have a signature.
606 // Lazy symbols may not be functions and therefore Sig can still be null
607 // in some circumstantce.
608 assert(!isa<FunctionSymbol>(sym));
609 continue;
610 }
611
612 // Add a synthetic dummy for weak undefined functions. These dummies will
613 // be GC'd if not used as the target of any "call" instructions.
614 StringRef debugName = saver.save("undefined:" + toString(*sym));
615 InputFunction* func = replaceWithUnreachable(sym, *sig, debugName);
616 // Ensure it compares equal to the null pointer, and so that table relocs
617 // don't pull in the stub body (only call-operand relocs should do that).
618 func->setTableIndex(0);
619 // Hide our dummy to prevent export.
620 sym->setHidden(true);
393621 }
394622}
395623
396bool SymbolTable::addComdat(StringRef Name) {
397 return Comdats.insert(CachedHashStringRef(Name)).second;
624static void reportFunctionSignatureMismatch(StringRef symName,
625 FunctionSymbol *a,
626 FunctionSymbol *b, bool isError) {
627 std::string msg = ("function signature mismatch: " + symName +
628 "\n>>> defined as " + toString(*a->signature) + " in " +
629 toString(a->getFile()) + "\n>>> defined as " +
630 toString(*b->signature) + " in " + toString(b->getFile()))
631 .str();
632 if (isError)
633 error(msg);
634 else
635 warn(msg);
636}
637
638// Remove any variant symbols that were created due to function signature
639// mismatches.
640void SymbolTable::handleSymbolVariants() {
641 for (auto pair : symVariants) {
642 // Push the initial symbol onto the list of variants.
643 StringRef symName = pair.first.val();
644 std::vector<Symbol *> &variants = pair.second;
645
646#ifndef NDEBUG
647 LLVM_DEBUG(dbgs() << "symbol with (" << variants.size()
648 << ") variants: " << symName << "\n");
649 for (auto *s: variants) {
650 auto *f = cast<FunctionSymbol>(s);
651 LLVM_DEBUG(dbgs() << " variant: " + f->getName() << " "
652 << toString(*f->signature) << "\n");
653 }
654#endif
655
656 // Find the one definition.
657 DefinedFunction *defined = nullptr;
658 for (auto *symbol : variants) {
659 if (auto f = dyn_cast<DefinedFunction>(symbol)) {
660 defined = f;
661 break;
662 }
663 }
664
665 // If there are no definitions, and the undefined symbols disagree on
666 // the signature, there is not we can do since we don't know which one
667 // to use as the signature on the import.
668 if (!defined) {
669 reportFunctionSignatureMismatch(symName,
670 cast<FunctionSymbol>(variants[0]),
671 cast<FunctionSymbol>(variants[1]), true);
672 return;
673 }
674
675 for (auto *symbol : variants) {
676 if (symbol != defined) {
677 auto *f = cast<FunctionSymbol>(symbol);
678 reportFunctionSignatureMismatch(symName, f, defined, false);
679 StringRef debugName = saver.save("unreachable:" + toString(*f));
680 replaceWithUnreachable(f, *f->signature, debugName);
681 }
682 }
683 }
398684}
deps/lld/wasm/SymbolTable.h+69-41
......@@ -1,9 +1,8 @@
11//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -36,60 +35,89 @@ class InputSegment;
3635// There is one add* function per symbol type.
3736class SymbolTable {
3837public:
39 void addFile(InputFile *File);
38 void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
39
40 void addFile(InputFile *file);
41
4042 void addCombinedLTOObject();
4143
42 std::vector<ObjFile *> ObjectFiles;
43 std::vector<BitcodeFile *> BitcodeFiles;
44 std::vector<InputFunction *> SyntheticFunctions;
45 std::vector<InputGlobal *> SyntheticGlobals;
44 ArrayRef<Symbol *> getSymbols() const { return symVector; }
45
46 Symbol *find(StringRef name);
4647
47 void reportRemainingUndefines();
48 void replace(StringRef name, Symbol* sym);
4849
49 ArrayRef<Symbol *> getSymbols() const { return SymVector; }
50 Symbol *find(StringRef Name);
50 void trace(StringRef name);
5151
52 Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File,
53 InputFunction *Function);
54 Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *File,
55 InputSegment *Segment, uint32_t Address,
56 uint32_t Size);
57 Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
58 InputGlobal *G);
59 Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
60 InputEvent *E);
52 Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file,
53 InputFunction *function);
54 Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file,
55 InputSegment *segment, uint32_t address,
56 uint32_t size);
57 Symbol *addDefinedGlobal(StringRef name, uint32_t flags, InputFile *file,
58 InputGlobal *g);
59 Symbol *addDefinedEvent(StringRef name, uint32_t flags, InputFile *file,
60 InputEvent *e);
6161
62 Symbol *addUndefinedFunction(StringRef Name, StringRef ImportName,
63 StringRef ImportModule, uint32_t Flags,
64 InputFile *File, const WasmSignature *Signature);
65 Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File);
66 Symbol *addUndefinedGlobal(StringRef Name, StringRef ImportName,
67 StringRef ImportModule, uint32_t Flags,
68 InputFile *File, const WasmGlobalType *Type);
62 Symbol *addUndefinedFunction(StringRef name, StringRef importName,
63 StringRef importModule, uint32_t flags,
64 InputFile *file, const WasmSignature *signature,
65 bool isCalledDirectly);
66 Symbol *addUndefinedData(StringRef name, uint32_t flags, InputFile *file);
67 Symbol *addUndefinedGlobal(StringRef name, StringRef importName,
68 StringRef importModule, uint32_t flags,
69 InputFile *file, const WasmGlobalType *type);
6970
70 void addLazy(ArchiveFile *F, const llvm::object::Archive::Symbol *Sym);
71 void addLazy(ArchiveFile *f, const llvm::object::Archive::Symbol *sym);
7172
72 bool addComdat(StringRef Name);
73 bool addComdat(StringRef name);
7374
74 DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags);
75 DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags,
76 InputGlobal *Global);
77 DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags,
78 InputFunction *Function);
75 DefinedData *addSyntheticDataSymbol(StringRef name, uint32_t flags);
76 DefinedGlobal *addSyntheticGlobal(StringRef name, uint32_t flags,
77 InputGlobal *global);
78 DefinedFunction *addSyntheticFunction(StringRef name, uint32_t flags,
79 InputFunction *function);
80 DefinedData *addOptionalDataSymbol(StringRef name, uint32_t value = 0,
81 uint32_t flags = 0);
82
83 void handleSymbolVariants();
84 void handleWeakUndefines();
85
86 std::vector<ObjFile *> objectFiles;
87 std::vector<SharedFile *> sharedFiles;
88 std::vector<BitcodeFile *> bitcodeFiles;
89 std::vector<InputFunction *> syntheticFunctions;
90 std::vector<InputGlobal *> syntheticGlobals;
7991
8092private:
81 std::pair<Symbol *, bool> insert(StringRef Name, InputFile *File);
93 std::pair<Symbol *, bool> insert(StringRef name, const InputFile *file);
94 std::pair<Symbol *, bool> insertName(StringRef name);
95
96 bool getFunctionVariant(Symbol* sym, const WasmSignature *sig,
97 const InputFile *file, Symbol **out);
98 InputFunction *replaceWithUnreachable(Symbol *sym, const WasmSignature &sig,
99 StringRef debugName);
100
101 // Maps symbol names to index into the symVector. -1 means that symbols
102 // is to not yet in the vector but it should have tracing enabled if it is
103 // ever added.
104 llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
105 std::vector<Symbol *> symVector;
82106
83 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap;
84 std::vector<Symbol *> SymVector;
107 // For certain symbols types, e.g. function symbols, we allow for muliple
108 // variants of the same symbol with different signatures.
109 llvm::DenseMap<llvm::CachedHashStringRef, std::vector<Symbol *>> symVariants;
85110
86 llvm::DenseSet<llvm::CachedHashStringRef> Comdats;
111 // Comdat groups define "link once" sections. If two comdat groups have the
112 // same name, only one of them is linked, and the other is ignored. This set
113 // is used to uniquify them.
114 llvm::DenseSet<llvm::CachedHashStringRef> comdatGroups;
87115
88116 // For LTO.
89 std::unique_ptr<BitcodeCompiler> LTO;
117 std::unique_ptr<BitcodeCompiler> lto;
90118};
91119
92extern SymbolTable *Symtab;
120extern SymbolTable *symtab;
93121
94122} // namespace wasm
95123} // namespace lld
deps/lld/wasm/Symbols.cpp+193-140
......@@ -1,9 +1,8 @@
11//===- Symbols.cpp --------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -13,6 +12,7 @@
1312#include "InputEvent.h"
1413#include "InputFiles.h"
1514#include "InputGlobal.h"
15#include "OutputSections.h"
1616#include "OutputSegment.h"
1717#include "lld/Common/ErrorHandler.h"
1818#include "lld/Common/Strings.h"
......@@ -24,13 +24,19 @@ using namespace llvm::wasm;
2424using namespace lld;
2525using namespace lld::wasm;
2626
27DefinedFunction *WasmSym::CallCtors;
28DefinedData *WasmSym::DsoHandle;
29DefinedData *WasmSym::DataEnd;
30DefinedData *WasmSym::HeapBase;
31GlobalSymbol *WasmSym::StackPointer;
32UndefinedGlobal *WasmSym::TableBase;
33UndefinedGlobal *WasmSym::MemoryBase;
27DefinedFunction *WasmSym::callCtors;
28DefinedFunction *WasmSym::initMemory;
29DefinedFunction *WasmSym::applyRelocs;
30DefinedFunction *WasmSym::initTLS;
31DefinedData *WasmSym::dsoHandle;
32DefinedData *WasmSym::dataEnd;
33DefinedData *WasmSym::globalBase;
34DefinedData *WasmSym::heapBase;
35GlobalSymbol *WasmSym::stackPointer;
36GlobalSymbol *WasmSym::tlsBase;
37GlobalSymbol *WasmSym::tlsSize;
38UndefinedGlobal *WasmSym::tableBase;
39UndefinedGlobal *WasmSym::memoryBase;
3440
3541WasmSymbolType Symbol::getWasmType() const {
3642 if (isa<FunctionSymbol>(this))
......@@ -41,238 +47,260 @@ WasmSymbolType Symbol::getWasmType() const {
4147 return WASM_SYMBOL_TYPE_GLOBAL;
4248 if (isa<EventSymbol>(this))
4349 return WASM_SYMBOL_TYPE_EVENT;
44 if (isa<SectionSymbol>(this))
50 if (isa<SectionSymbol>(this) || isa<OutputSectionSymbol>(this))
4551 return WASM_SYMBOL_TYPE_SECTION;
4652 llvm_unreachable("invalid symbol kind");
4753}
4854
55const WasmSignature *Symbol::getSignature() const {
56 if (auto* f = dyn_cast<FunctionSymbol>(this))
57 return f->signature;
58 if (auto *l = dyn_cast<LazySymbol>(this))
59 return l->signature;
60 return nullptr;
61}
62
4963InputChunk *Symbol::getChunk() const {
50 if (auto *F = dyn_cast<DefinedFunction>(this))
51 return F->Function;
52 if (auto *D = dyn_cast<DefinedData>(this))
53 return D->Segment;
64 if (auto *f = dyn_cast<DefinedFunction>(this))
65 return f->function;
66 if (auto *d = dyn_cast<DefinedData>(this))
67 return d->segment;
5468 return nullptr;
5569}
5670
71bool Symbol::isDiscarded() const {
72 if (InputChunk *c = getChunk())
73 return c->discarded;
74 return false;
75}
76
5777bool Symbol::isLive() const {
58 if (auto *G = dyn_cast<DefinedGlobal>(this))
59 return G->Global->Live;
60 if (auto *E = dyn_cast<DefinedEvent>(this))
61 return E->Event->Live;
62 if (InputChunk *C = getChunk())
63 return C->Live;
64 return Referenced;
78 if (auto *g = dyn_cast<DefinedGlobal>(this))
79 return g->global->live;
80 if (auto *e = dyn_cast<DefinedEvent>(this))
81 return e->event->live;
82 if (InputChunk *c = getChunk())
83 return c->live;
84 return referenced;
6585}
6686
6787void Symbol::markLive() {
68 if (auto *G = dyn_cast<DefinedGlobal>(this))
69 G->Global->Live = true;
70 if (auto *E = dyn_cast<DefinedEvent>(this))
71 E->Event->Live = true;
72 if (InputChunk *C = getChunk())
73 C->Live = true;
74 Referenced = true;
88 assert(!isDiscarded());
89 if (auto *g = dyn_cast<DefinedGlobal>(this))
90 g->global->live = true;
91 if (auto *e = dyn_cast<DefinedEvent>(this))
92 e->event->live = true;
93 if (InputChunk *c = getChunk())
94 c->live = true;
95 referenced = true;
7596}
7697
7798uint32_t Symbol::getOutputSymbolIndex() const {
78 assert(OutputSymbolIndex != INVALID_INDEX);
79 return OutputSymbolIndex;
99 assert(outputSymbolIndex != INVALID_INDEX);
100 return outputSymbolIndex;
80101}
81102
82void Symbol::setOutputSymbolIndex(uint32_t Index) {
83 LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index
103void Symbol::setOutputSymbolIndex(uint32_t index) {
104 LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << name << " -> " << index
84105 << "\n");
85 assert(OutputSymbolIndex == INVALID_INDEX);
86 OutputSymbolIndex = Index;
106 assert(outputSymbolIndex == INVALID_INDEX);
107 outputSymbolIndex = index;
108}
109
110void Symbol::setGOTIndex(uint32_t index) {
111 LLVM_DEBUG(dbgs() << "setGOTIndex " << name << " -> " << index << "\n");
112 assert(gotIndex == INVALID_INDEX);
113 // Any symbol that is assigned a GOT entry must be exported othewise the
114 // dynamic linker won't be able create the entry that contains it.
115 forceExport = true;
116 gotIndex = index;
87117}
88118
89119bool Symbol::isWeak() const {
90 return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
120 return (flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
91121}
92122
93123bool Symbol::isLocal() const {
94 return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
124 return (flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
95125}
96126
97127bool Symbol::isHidden() const {
98 return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
128 return (flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
99129}
100130
101void Symbol::setHidden(bool IsHidden) {
102 LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
103 Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
104 if (IsHidden)
105 Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
131void Symbol::setHidden(bool isHidden) {
132 LLVM_DEBUG(dbgs() << "setHidden: " << name << " -> " << isHidden << "\n");
133 flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
134 if (isHidden)
135 flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
106136 else
107 Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
137 flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
108138}
109139
110140bool Symbol::isExported() const {
111141 if (!isDefined() || isLocal())
112142 return false;
113143
114 if (ForceExport || Config->ExportAll)
144 if (forceExport || config->exportAll)
115145 return true;
116146
117 if (Config->ExportDynamic && !isHidden())
147 if (config->exportDynamic && !isHidden())
118148 return true;
119149
120 return false;
150 return flags & WASM_SYMBOL_EXPORTED;
121151}
122152
123153uint32_t FunctionSymbol::getFunctionIndex() const {
124 if (auto *F = dyn_cast<DefinedFunction>(this))
125 return F->Function->getFunctionIndex();
126 assert(FunctionIndex != INVALID_INDEX);
127 return FunctionIndex;
154 if (auto *f = dyn_cast<DefinedFunction>(this))
155 return f->function->getFunctionIndex();
156 assert(functionIndex != INVALID_INDEX);
157 return functionIndex;
128158}
129159
130void FunctionSymbol::setFunctionIndex(uint32_t Index) {
131 LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n");
132 assert(FunctionIndex == INVALID_INDEX);
133 FunctionIndex = Index;
160void FunctionSymbol::setFunctionIndex(uint32_t index) {
161 LLVM_DEBUG(dbgs() << "setFunctionIndex " << name << " -> " << index << "\n");
162 assert(functionIndex == INVALID_INDEX);
163 functionIndex = index;
134164}
135165
136166bool FunctionSymbol::hasFunctionIndex() const {
137 if (auto *F = dyn_cast<DefinedFunction>(this))
138 return F->Function->hasFunctionIndex();
139 return FunctionIndex != INVALID_INDEX;
167 if (auto *f = dyn_cast<DefinedFunction>(this))
168 return f->function->hasFunctionIndex();
169 return functionIndex != INVALID_INDEX;
140170}
141171
142172uint32_t FunctionSymbol::getTableIndex() const {
143 if (auto *F = dyn_cast<DefinedFunction>(this))
144 return F->Function->getTableIndex();
145 assert(TableIndex != INVALID_INDEX);
146 return TableIndex;
173 if (auto *f = dyn_cast<DefinedFunction>(this))
174 return f->function->getTableIndex();
175 assert(tableIndex != INVALID_INDEX);
176 return tableIndex;
147177}
148178
149179bool FunctionSymbol::hasTableIndex() const {
150 if (auto *F = dyn_cast<DefinedFunction>(this))
151 return F->Function->hasTableIndex();
152 return TableIndex != INVALID_INDEX;
180 if (auto *f = dyn_cast<DefinedFunction>(this))
181 return f->function->hasTableIndex();
182 return tableIndex != INVALID_INDEX;
153183}
154184
155void FunctionSymbol::setTableIndex(uint32_t Index) {
185void FunctionSymbol::setTableIndex(uint32_t index) {
156186 // For imports, we set the table index here on the Symbol; for defined
157187 // functions we set the index on the InputFunction so that we don't export
158188 // the same thing twice (keeps the table size down).
159 if (auto *F = dyn_cast<DefinedFunction>(this)) {
160 F->Function->setTableIndex(Index);
189 if (auto *f = dyn_cast<DefinedFunction>(this)) {
190 f->function->setTableIndex(index);
161191 return;
162192 }
163 LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
164 assert(TableIndex == INVALID_INDEX);
165 TableIndex = Index;
193 LLVM_DEBUG(dbgs() << "setTableIndex " << name << " -> " << index << "\n");
194 assert(tableIndex == INVALID_INDEX);
195 tableIndex = index;
166196}
167197
168DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
169 InputFunction *Function)
170 : FunctionSymbol(Name, DefinedFunctionKind, Flags, F,
171 Function ? &Function->Signature : nullptr),
172 Function(Function) {}
198DefinedFunction::DefinedFunction(StringRef name, uint32_t flags, InputFile *f,
199 InputFunction *function)
200 : FunctionSymbol(name, DefinedFunctionKind, flags, f,
201 function ? &function->signature : nullptr),
202 function(function) {}
173203
174204uint32_t DefinedData::getVirtualAddress() const {
175205 LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
176 if (Segment)
177 return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset;
178 return Offset;
206 if (segment) {
207 // For thread local data, the symbol location is relative to the start of
208 // the .tdata section, since they are used as offsets from __tls_base.
209 // Hence, we do not add in segment->outputSeg->startVA.
210 if (segment->outputSeg->name == ".tdata")
211 return segment->outputSegmentOffset + offset;
212 return segment->outputSeg->startVA + segment->outputSegmentOffset + offset;
213 }
214 return offset;
179215}
180216
181void DefinedData::setVirtualAddress(uint32_t Value) {
182 LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
183 assert(!Segment);
184 Offset = Value;
217void DefinedData::setVirtualAddress(uint32_t value) {
218 LLVM_DEBUG(dbgs() << "setVirtualAddress " << name << " -> " << value << "\n");
219 assert(!segment);
220 offset = value;
185221}
186222
187223uint32_t DefinedData::getOutputSegmentOffset() const {
188224 LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
189 return Segment->OutputSegmentOffset + Offset;
225 return segment->outputSegmentOffset + offset;
190226}
191227
192228uint32_t DefinedData::getOutputSegmentIndex() const {
193229 LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
194 return Segment->OutputSeg->Index;
230 return segment->outputSeg->index;
195231}
196232
197233uint32_t GlobalSymbol::getGlobalIndex() const {
198 if (auto *F = dyn_cast<DefinedGlobal>(this))
199 return F->Global->getGlobalIndex();
200 assert(GlobalIndex != INVALID_INDEX);
201 return GlobalIndex;
234 if (auto *f = dyn_cast<DefinedGlobal>(this))
235 return f->global->getGlobalIndex();
236 assert(globalIndex != INVALID_INDEX);
237 return globalIndex;
202238}
203239
204void GlobalSymbol::setGlobalIndex(uint32_t Index) {
205 LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n");
206 assert(GlobalIndex == INVALID_INDEX);
207 GlobalIndex = Index;
240void GlobalSymbol::setGlobalIndex(uint32_t index) {
241 LLVM_DEBUG(dbgs() << "setGlobalIndex " << name << " -> " << index << "\n");
242 assert(globalIndex == INVALID_INDEX);
243 globalIndex = index;
208244}
209245
210246bool GlobalSymbol::hasGlobalIndex() const {
211 if (auto *F = dyn_cast<DefinedGlobal>(this))
212 return F->Global->hasGlobalIndex();
213 return GlobalIndex != INVALID_INDEX;
247 if (auto *f = dyn_cast<DefinedGlobal>(this))
248 return f->global->hasGlobalIndex();
249 return globalIndex != INVALID_INDEX;
214250}
215251
216DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
217 InputGlobal *Global)
218 : GlobalSymbol(Name, DefinedGlobalKind, Flags, File,
219 Global ? &Global->getType() : nullptr),
220 Global(Global) {}
252DefinedGlobal::DefinedGlobal(StringRef name, uint32_t flags, InputFile *file,
253 InputGlobal *global)
254 : GlobalSymbol(name, DefinedGlobalKind, flags, file,
255 global ? &global->getType() : nullptr),
256 global(global) {}
221257
222258uint32_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;
259 if (auto *f = dyn_cast<DefinedEvent>(this))
260 return f->event->getEventIndex();
261 assert(eventIndex != INVALID_INDEX);
262 return eventIndex;
227263}
228264
229void EventSymbol::setEventIndex(uint32_t Index) {
230 LLVM_DEBUG(dbgs() << "setEventIndex " << Name << " -> " << Index << "\n");
231 assert(EventIndex == INVALID_INDEX);
232 EventIndex = Index;
265void EventSymbol::setEventIndex(uint32_t index) {
266 LLVM_DEBUG(dbgs() << "setEventIndex " << name << " -> " << index << "\n");
267 assert(eventIndex == INVALID_INDEX);
268 eventIndex = index;
233269}
234270
235271bool EventSymbol::hasEventIndex() const {
236 if (auto *F = dyn_cast<DefinedEvent>(this))
237 return F->Event->hasEventIndex();
238 return EventIndex != INVALID_INDEX;
272 if (auto *f = dyn_cast<DefinedEvent>(this))
273 return f->event->hasEventIndex();
274 return eventIndex != INVALID_INDEX;
239275}
240276
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
248uint32_t SectionSymbol::getOutputSectionIndex() const {
249 LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");
250 assert(OutputSectionIndex != INVALID_INDEX);
251 return OutputSectionIndex;
252}
277DefinedEvent::DefinedEvent(StringRef name, uint32_t flags, InputFile *file,
278 InputEvent *event)
279 : EventSymbol(name, DefinedEventKind, flags, file,
280 event ? &event->getType() : nullptr,
281 event ? &event->signature : nullptr),
282 event(event) {}
253283
254void SectionSymbol::setOutputSectionIndex(uint32_t Index) {
255 LLVM_DEBUG(dbgs() << "setOutputSectionIndex: " << getName() << " -> " << Index
256 << "\n");
257 assert(Index != INVALID_INDEX);
258 OutputSectionIndex = Index;
284const OutputSectionSymbol *SectionSymbol::getOutputSectionSymbol() const {
285 assert(section->outputSec && section->outputSec->sectionSym);
286 return section->outputSec->sectionSym;
259287}
260288
261void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }
289void LazySymbol::fetch() { cast<ArchiveFile>(file)->addMember(&archiveSymbol); }
262290
263std::string lld::toString(const wasm::Symbol &Sym) {
264 return lld::maybeDemangleSymbol(Sym.getName());
291std::string lld::toString(const wasm::Symbol &sym) {
292 return lld::maybeDemangleSymbol(sym.getName());
265293}
266294
267std::string lld::maybeDemangleSymbol(StringRef Name) {
268 if (Config->Demangle)
269 if (Optional<std::string> S = demangleItanium(Name))
270 return *S;
271 return Name;
295std::string lld::maybeDemangleSymbol(StringRef name) {
296 if (config->demangle)
297 if (Optional<std::string> s = demangleItanium(name))
298 return *s;
299 return name;
272300}
273301
274std::string lld::toString(wasm::Symbol::Kind Kind) {
275 switch (Kind) {
302std::string lld::toString(wasm::Symbol::Kind kind) {
303 switch (kind) {
276304 case wasm::Symbol::DefinedFunctionKind:
277305 return "DefinedFunction";
278306 case wasm::Symbol::DefinedDataKind:
......@@ -291,6 +319,31 @@ std::string lld::toString(wasm::Symbol::Kind Kind) {
291319 return "LazyKind";
292320 case wasm::Symbol::SectionKind:
293321 return "SectionKind";
322 case wasm::Symbol::OutputSectionKind:
323 return "OutputSectionKind";
294324 }
295325 llvm_unreachable("invalid symbol kind");
296326}
327
328
329void lld::wasm::printTraceSymbolUndefined(StringRef name, const InputFile* file) {
330 message(toString(file) + ": reference to " + name);
331}
332
333// Print out a log message for --trace-symbol.
334void lld::wasm::printTraceSymbol(Symbol *sym) {
335 // Undefined symbols are traced via printTraceSymbolUndefined
336 if (sym->isUndefined())
337 return;
338
339 std::string s;
340 if (sym->isLazy())
341 s = ": lazy definition of ";
342 else
343 s = ": definition of ";
344
345 message(toString(sym->getFile()) + s + sym->getName());
346}
347
348const char *lld::wasm::defaultModule = "env";
349const char *lld::wasm::functionTableName = "__indirect_function_table";
deps/lld/wasm/Symbols.h+273-155
......@@ -1,9 +1,8 @@
11//===- Symbols.h ------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -18,6 +17,14 @@
1817namespace lld {
1918namespace wasm {
2019
20// Shared string constants
21
22// The default module name to use for symbol imports.
23extern const char *defaultModule;
24
25// The name under which to import or export the wasm table.
26extern const char *functionTableName;
27
2128using llvm::wasm::WasmSymbolType;
2229
2330class InputFile;
......@@ -27,48 +34,58 @@ class InputFunction;
2734class InputGlobal;
2835class InputEvent;
2936class InputSection;
37class OutputSection;
3038
3139#define INVALID_INDEX UINT32_MAX
3240
3341// The base class for real symbol classes.
3442class Symbol {
3543public:
36 enum Kind {
44 enum Kind : uint8_t {
3745 DefinedFunctionKind,
3846 DefinedDataKind,
3947 DefinedGlobalKind,
4048 DefinedEventKind,
4149 SectionKind,
50 OutputSectionKind,
4251 UndefinedFunctionKind,
4352 UndefinedDataKind,
4453 UndefinedGlobalKind,
4554 LazyKind,
4655 };
4756
48 Kind kind() const { return SymbolKind; }
57 Kind kind() const { return symbolKind; }
4958
50 bool isDefined() const {
51 return SymbolKind == DefinedFunctionKind || SymbolKind == DefinedDataKind ||
52 SymbolKind == DefinedGlobalKind || SymbolKind == DefinedEventKind ||
53 SymbolKind == SectionKind;
54 }
59 bool isDefined() const { return !isLazy() && !isUndefined(); }
5560
5661 bool isUndefined() const {
57 return SymbolKind == UndefinedFunctionKind ||
58 SymbolKind == UndefinedDataKind || SymbolKind == UndefinedGlobalKind;
62 return symbolKind == UndefinedFunctionKind ||
63 symbolKind == UndefinedDataKind || symbolKind == UndefinedGlobalKind;
5964 }
6065
61 bool isLazy() const { return SymbolKind == LazyKind; }
66 bool isLazy() const { return symbolKind == LazyKind; }
6267
6368 bool isLocal() const;
6469 bool isWeak() const;
6570 bool isHidden() const;
6671
72 // Returns true if this symbol exists in a discarded (due to COMDAT) section
73 bool isDiscarded() const;
74
75 // True if this is an undefined weak symbol. This only works once
76 // all input files have been added.
77 bool isUndefWeak() const {
78 // See comment on lazy symbols for details.
79 return isWeak() && (isUndefined() || isLazy());
80 }
81
6782 // Returns the symbol name.
68 StringRef getName() const { return Name; }
83 StringRef getName() const { return name; }
6984
7085 // Returns the file from which this symbol was created.
71 InputFile *getFile() const { return File; }
86 InputFile *getFile() const { return file; }
87
88 uint32_t getFlags() const { return flags; }
7289
7390 InputChunk *getChunk() const;
7491
......@@ -80,205 +97,249 @@ public:
8097 // final image.
8198 void markLive();
8299
83 void setHidden(bool IsHidden);
100 void setHidden(bool isHidden);
84101
85102 // Get/set the index in the output symbol table. This is only used for
86103 // relocatable output.
87104 uint32_t getOutputSymbolIndex() const;
88 void setOutputSymbolIndex(uint32_t Index);
105 void setOutputSymbolIndex(uint32_t index);
89106
90107 WasmSymbolType getWasmType() const;
91108 bool isExported() const;
92109
93 // True if this symbol was referenced by a regular (non-bitcode) object.
94 unsigned IsUsedInRegularObj : 1;
95 unsigned ForceExport : 1;
110 const WasmSignature* getSignature() const;
111
112 bool isInGOT() const { return gotIndex != INVALID_INDEX; }
113
114 uint32_t getGOTIndex() const {
115 assert(gotIndex != INVALID_INDEX);
116 return gotIndex;
117 }
118
119 void setGOTIndex(uint32_t index);
120 bool hasGOTIndex() const { return gotIndex != INVALID_INDEX; }
96121
97122protected:
98 Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
99 : IsUsedInRegularObj(false), ForceExport(false), Name(Name),
100 SymbolKind(K), Flags(Flags), File(F), Referenced(!Config->GcSections) {}
101
102 StringRef Name;
103 Kind SymbolKind;
104 uint32_t Flags;
105 InputFile *File;
106 uint32_t OutputSymbolIndex = INVALID_INDEX;
107 bool Referenced;
123 Symbol(StringRef name, Kind k, uint32_t flags, InputFile *f)
124 : name(name), file(f), flags(flags), symbolKind(k),
125 referenced(!config->gcSections), isUsedInRegularObj(false),
126 forceExport(false), canInline(false), traced(false) {}
127
128 StringRef name;
129 InputFile *file;
130 uint32_t flags;
131 uint32_t outputSymbolIndex = INVALID_INDEX;
132 uint32_t gotIndex = INVALID_INDEX;
133 Kind symbolKind;
134
135public:
136 bool referenced : 1;
137
138 // True if the symbol was used for linking and thus need to be added to the
139 // output file's symbol table. This is true for all symbols except for
140 // unreferenced DSO symbols, lazy (archive) symbols, and bitcode symbols that
141 // are unreferenced except by other bitcode objects.
142 bool isUsedInRegularObj : 1;
143
144 // True if ths symbol is explicity marked for export (i.e. via the -e/--export
145 // command line flag)
146 bool forceExport : 1;
147
148 // False if LTO shouldn't inline whatever this symbol points to. If a symbol
149 // is overwritten after LTO, LTO shouldn't inline the symbol because it
150 // doesn't know the final contents of the symbol.
151 bool canInline : 1;
152
153 // True if this symbol is specified by --trace-symbol option.
154 bool traced : 1;
108155};
109156
110157class FunctionSymbol : public Symbol {
111158public:
112 static bool classof(const Symbol *S) {
113 return S->kind() == DefinedFunctionKind ||
114 S->kind() == UndefinedFunctionKind;
159 static bool classof(const Symbol *s) {
160 return s->kind() == DefinedFunctionKind ||
161 s->kind() == UndefinedFunctionKind;
115162 }
116163
117164 // Get/set the table index
118 void setTableIndex(uint32_t Index);
165 void setTableIndex(uint32_t index);
119166 uint32_t getTableIndex() const;
120167 bool hasTableIndex() const;
121168
122169 // Get/set the function index
123170 uint32_t getFunctionIndex() const;
124 void setFunctionIndex(uint32_t Index);
171 void setFunctionIndex(uint32_t index);
125172 bool hasFunctionIndex() const;
126173
127 const WasmSignature *Signature;
174 const WasmSignature *signature;
128175
129176protected:
130 FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
131 const WasmSignature *Sig)
132 : Symbol(Name, K, Flags, F), Signature(Sig) {}
177 FunctionSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f,
178 const WasmSignature *sig)
179 : Symbol(name, k, flags, f), signature(sig) {}
133180
134 uint32_t TableIndex = INVALID_INDEX;
135 uint32_t FunctionIndex = INVALID_INDEX;
181 uint32_t tableIndex = INVALID_INDEX;
182 uint32_t functionIndex = INVALID_INDEX;
136183};
137184
138185class DefinedFunction : public FunctionSymbol {
139186public:
140 DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
141 InputFunction *Function);
187 DefinedFunction(StringRef name, uint32_t flags, InputFile *f,
188 InputFunction *function);
142189
143 static bool classof(const Symbol *S) {
144 return S->kind() == DefinedFunctionKind;
190 static bool classof(const Symbol *s) {
191 return s->kind() == DefinedFunctionKind;
145192 }
146193
147 InputFunction *Function;
194 InputFunction *function;
148195};
149196
150197class UndefinedFunction : public FunctionSymbol {
151198public:
152 UndefinedFunction(StringRef Name, StringRef ImportName,
153 StringRef ImportModule, uint32_t Flags,
154 InputFile *File = nullptr,
155 const WasmSignature *Type = nullptr)
156 : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type),
157 ImportName(ImportName), ImportModule(ImportModule) {}
158
159 static bool classof(const Symbol *S) {
160 return S->kind() == UndefinedFunctionKind;
199 UndefinedFunction(StringRef name, StringRef importName,
200 StringRef importModule, uint32_t flags,
201 InputFile *file = nullptr,
202 const WasmSignature *type = nullptr,
203 bool isCalledDirectly = true)
204 : FunctionSymbol(name, UndefinedFunctionKind, flags, file, type),
205 importName(importName), importModule(importModule), isCalledDirectly(isCalledDirectly) {}
206
207 static bool classof(const Symbol *s) {
208 return s->kind() == UndefinedFunctionKind;
161209 }
162210
163 StringRef ImportName;
164 StringRef ImportModule;
211 StringRef importName;
212 StringRef importModule;
213 bool isCalledDirectly;
165214};
166215
167class SectionSymbol : public Symbol {
216// Section symbols for output sections are different from those for input
217// section. These are generated by the linker and point the OutputSection
218// rather than an InputSection.
219class OutputSectionSymbol : public Symbol {
168220public:
169 static bool classof(const Symbol *S) { return S->kind() == SectionKind; }
221 OutputSectionSymbol(const OutputSection *s)
222 : Symbol("", OutputSectionKind, llvm::wasm::WASM_SYMBOL_BINDING_LOCAL,
223 nullptr),
224 section(s) {}
170225
171 SectionSymbol(StringRef Name, uint32_t Flags, const InputSection *S,
172 InputFile *F = nullptr)
173 : Symbol(Name, SectionKind, Flags, F), Section(S) {}
226 static bool classof(const Symbol *s) {
227 return s->kind() == OutputSectionKind;
228 }
174229
175 const InputSection *Section;
230 const OutputSection *section;
231};
176232
177 uint32_t getOutputSectionIndex() const;
178 void setOutputSectionIndex(uint32_t Index);
233class SectionSymbol : public Symbol {
234public:
235 SectionSymbol(uint32_t flags, const InputSection *s, InputFile *f = nullptr)
236 : Symbol("", SectionKind, flags, f), section(s) {}
179237
180protected:
181 uint32_t OutputSectionIndex = INVALID_INDEX;
238 static bool classof(const Symbol *s) { return s->kind() == SectionKind; }
239
240 const OutputSectionSymbol *getOutputSectionSymbol() const;
241
242 const InputSection *section;
182243};
183244
184245class DataSymbol : public Symbol {
185246public:
186 static bool classof(const Symbol *S) {
187 return S->kind() == DefinedDataKind || S->kind() == UndefinedDataKind;
247 static bool classof(const Symbol *s) {
248 return s->kind() == DefinedDataKind || s->kind() == UndefinedDataKind;
188249 }
189250
190251protected:
191 DataSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
192 : Symbol(Name, K, Flags, F) {}
252 DataSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f)
253 : Symbol(name, k, flags, f) {}
193254};
194255
195256class DefinedData : public DataSymbol {
196257public:
197258 // Constructor for regular data symbols originating from input files.
198 DefinedData(StringRef Name, uint32_t Flags, InputFile *F,
199 InputSegment *Segment, uint32_t Offset, uint32_t Size)
200 : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment),
201 Offset(Offset), Size(Size) {}
259 DefinedData(StringRef name, uint32_t flags, InputFile *f,
260 InputSegment *segment, uint32_t offset, uint32_t size)
261 : DataSymbol(name, DefinedDataKind, flags, f), segment(segment),
262 offset(offset), size(size) {}
202263
203264 // Constructor for linker synthetic data symbols.
204 DefinedData(StringRef Name, uint32_t Flags)
205 : DataSymbol(Name, DefinedDataKind, Flags, nullptr) {}
265 DefinedData(StringRef name, uint32_t flags)
266 : DataSymbol(name, DefinedDataKind, flags, nullptr) {}
206267
207 static bool classof(const Symbol *S) { return S->kind() == DefinedDataKind; }
268 static bool classof(const Symbol *s) { return s->kind() == DefinedDataKind; }
208269
209270 // Returns the output virtual address of a defined data symbol.
210271 uint32_t getVirtualAddress() const;
211 void setVirtualAddress(uint32_t VA);
272 void setVirtualAddress(uint32_t va);
212273
213274 // Returns the offset of a defined data symbol within its OutputSegment.
214275 uint32_t getOutputSegmentOffset() const;
215276 uint32_t getOutputSegmentIndex() const;
216 uint32_t getSize() const { return Size; }
277 uint32_t getSize() const { return size; }
217278
218 InputSegment *Segment = nullptr;
279 InputSegment *segment = nullptr;
219280
220281protected:
221 uint32_t Offset = 0;
222 uint32_t Size = 0;
282 uint32_t offset = 0;
283 uint32_t size = 0;
223284};
224285
225286class UndefinedData : public DataSymbol {
226287public:
227 UndefinedData(StringRef Name, uint32_t Flags, InputFile *File = nullptr)
228 : DataSymbol(Name, UndefinedDataKind, Flags, File) {}
229 static bool classof(const Symbol *S) {
230 return S->kind() == UndefinedDataKind;
288 UndefinedData(StringRef name, uint32_t flags, InputFile *file = nullptr)
289 : DataSymbol(name, UndefinedDataKind, flags, file) {}
290 static bool classof(const Symbol *s) {
291 return s->kind() == UndefinedDataKind;
231292 }
232293};
233294
234295class GlobalSymbol : public Symbol {
235296public:
236 static bool classof(const Symbol *S) {
237 return S->kind() == DefinedGlobalKind || S->kind() == UndefinedGlobalKind;
297 static bool classof(const Symbol *s) {
298 return s->kind() == DefinedGlobalKind || s->kind() == UndefinedGlobalKind;
238299 }
239300
240 const WasmGlobalType *getGlobalType() const { return GlobalType; }
301 const WasmGlobalType *getGlobalType() const { return globalType; }
241302
242303 // Get/set the global index
243304 uint32_t getGlobalIndex() const;
244 void setGlobalIndex(uint32_t Index);
305 void setGlobalIndex(uint32_t index);
245306 bool hasGlobalIndex() const;
246307
247308protected:
248 GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
249 const WasmGlobalType *GlobalType)
250 : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {}
309 GlobalSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f,
310 const WasmGlobalType *globalType)
311 : Symbol(name, k, flags, f), globalType(globalType) {}
251312
252 const WasmGlobalType *GlobalType;
253 uint32_t GlobalIndex = INVALID_INDEX;
313 const WasmGlobalType *globalType;
314 uint32_t globalIndex = INVALID_INDEX;
254315};
255316
256317class DefinedGlobal : public GlobalSymbol {
257318public:
258 DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
259 InputGlobal *Global);
319 DefinedGlobal(StringRef name, uint32_t flags, InputFile *file,
320 InputGlobal *global);
260321
261 static bool classof(const Symbol *S) {
262 return S->kind() == DefinedGlobalKind;
322 static bool classof(const Symbol *s) {
323 return s->kind() == DefinedGlobalKind;
263324 }
264325
265 InputGlobal *Global;
326 InputGlobal *global;
266327};
267328
268329class UndefinedGlobal : public GlobalSymbol {
269330public:
270 UndefinedGlobal(StringRef Name, StringRef ImportName, StringRef ImportModule,
271 uint32_t Flags, InputFile *File = nullptr,
272 const WasmGlobalType *Type = nullptr)
273 : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type),
274 ImportName(ImportName), ImportModule(ImportModule) {}
275
276 static bool classof(const Symbol *S) {
277 return S->kind() == UndefinedGlobalKind;
331 UndefinedGlobal(StringRef name, StringRef importName, StringRef importModule,
332 uint32_t flags, InputFile *file = nullptr,
333 const WasmGlobalType *type = nullptr)
334 : GlobalSymbol(name, UndefinedGlobalKind, flags, file, type),
335 importName(importName), importModule(importModule) {}
336
337 static bool classof(const Symbol *s) {
338 return s->kind() == UndefinedGlobalKind;
278339 }
279340
280 StringRef ImportName;
281 StringRef ImportModule;
341 StringRef importName;
342 StringRef importModule;
282343};
283344
284345// Wasm events are features that suspend the current execution and transfer the
......@@ -295,100 +356,149 @@ public:
295356// are used, and has name '__cpp_exception' for linking.
296357class EventSymbol : public Symbol {
297358public:
298 static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; }
359 static bool classof(const Symbol *s) { return s->kind() == DefinedEventKind; }
299360
300 const WasmEventType *getEventType() const { return EventType; }
361 const WasmEventType *getEventType() const { return eventType; }
301362
302363 // Get/set the event index
303364 uint32_t getEventIndex() const;
304 void setEventIndex(uint32_t Index);
365 void setEventIndex(uint32_t index);
305366 bool hasEventIndex() const;
306367
307 const WasmSignature *Signature;
368 const WasmSignature *signature;
308369
309370protected:
310 EventSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
311 const WasmEventType *EventType, const WasmSignature *Sig)
312 : Symbol(Name, K, Flags, F), Signature(Sig), EventType(EventType) {}
371 EventSymbol(StringRef name, Kind k, uint32_t flags, InputFile *f,
372 const WasmEventType *eventType, const WasmSignature *sig)
373 : Symbol(name, k, flags, f), signature(sig), eventType(eventType) {}
313374
314 const WasmEventType *EventType;
315 uint32_t EventIndex = INVALID_INDEX;
375 const WasmEventType *eventType;
376 uint32_t eventIndex = INVALID_INDEX;
316377};
317378
318379class DefinedEvent : public EventSymbol {
319380public:
320 DefinedEvent(StringRef Name, uint32_t Flags, InputFile *File,
321 InputEvent *Event);
381 DefinedEvent(StringRef name, uint32_t flags, InputFile *file,
382 InputEvent *event);
322383
323 static bool classof(const Symbol *S) { return S->kind() == DefinedEventKind; }
384 static bool classof(const Symbol *s) { return s->kind() == DefinedEventKind; }
324385
325 InputEvent *Event;
386 InputEvent *event;
326387};
327388
389// LazySymbol represents a symbol that is not yet in the link, but we know where
390// to find it if needed. If the resolver finds both Undefined and Lazy for the
391// same name, it will ask the Lazy to load a file.
392//
393// A special complication is the handling of weak undefined symbols. They should
394// not load a file, but we have to remember we have seen both the weak undefined
395// and the lazy. We represent that with a lazy symbol with a weak binding. This
396// means that code looking for undefined symbols normally also has to take lazy
397// symbols into consideration.
328398class LazySymbol : public Symbol {
329399public:
330 LazySymbol(StringRef Name, InputFile *File,
331 const llvm::object::Archive::Symbol &Sym)
332 : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {}
400 LazySymbol(StringRef name, uint32_t flags, InputFile *file,
401 const llvm::object::Archive::Symbol &sym)
402 : Symbol(name, LazyKind, flags, file), archiveSymbol(sym) {}
333403
334 static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
404 static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
335405 void fetch();
336406
407 // Lazy symbols can have a signature because they can replace an
408 // UndefinedFunction which which case we need to be able to preserve the
409 // signture.
410 // TODO(sbc): This repetition of the signature field is inelegant. Revisit
411 // the use of class hierarchy to represent symbol taxonomy.
412 const WasmSignature *signature = nullptr;
413
337414private:
338 llvm::object::Archive::Symbol ArchiveSymbol;
415 llvm::object::Archive::Symbol archiveSymbol;
339416};
340417
341418// linker-generated symbols
342419struct WasmSym {
420 // __global_base
421 // Symbol marking the start of the global section.
422 static DefinedData *globalBase;
423
343424 // __stack_pointer
344425 // Global that holds the address of the top of the explicit value stack in
345426 // linear memory.
346 static GlobalSymbol *StackPointer;
427 static GlobalSymbol *stackPointer;
428
429 // __tls_base
430 // Global that holds the address of the base of the current thread's
431 // TLS block.
432 static GlobalSymbol *tlsBase;
433
434 // __tls_size
435 // Symbol whose value is the size of the TLS block.
436 static GlobalSymbol *tlsSize;
347437
348438 // __data_end
349439 // Symbol marking the end of the data and bss.
350 static DefinedData *DataEnd;
440 static DefinedData *dataEnd;
351441
352442 // __heap_base
353443 // Symbol marking the end of the data, bss and explicit stack. Any linear
354444 // memory following this address is not used by the linked code and can
355445 // therefore be used as a backing store for brk()/malloc() implementations.
356 static DefinedData *HeapBase;
446 static DefinedData *heapBase;
357447
358448 // __wasm_call_ctors
359449 // Function that directly calls all ctors in priority order.
360 static DefinedFunction *CallCtors;
450 static DefinedFunction *callCtors;
451
452 // __wasm_init_memory
453 // Function that initializes passive data segments post-instantiation.
454 static DefinedFunction *initMemory;
455
456 // __wasm_apply_relocs
457 // Function that applies relocations to data segment post-instantiation.
458 static DefinedFunction *applyRelocs;
459
460 // __wasm_init_tls
461 // Function that allocates thread-local storage and initializes it.
462 static DefinedFunction *initTLS;
361463
362464 // __dso_handle
363465 // Symbol used in calls to __cxa_atexit to determine current DLL
364 static DefinedData *DsoHandle;
466 static DefinedData *dsoHandle;
365467
366468 // __table_base
367469 // Used in PIC code for offset of indirect function table
368 static UndefinedGlobal *TableBase;
470 static UndefinedGlobal *tableBase;
369471
370472 // __memory_base
371473 // Used in PIC code for offset of global data
372 static UndefinedGlobal *MemoryBase;
474 static UndefinedGlobal *memoryBase;
373475};
374476
375477// A buffer class that is large enough to hold any Symbol-derived
376478// object. We allocate memory using this class and instantiate a symbol
377479// using the placement new.
378480union SymbolUnion {
379 alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
380 alignas(DefinedData) char B[sizeof(DefinedData)];
381 alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)];
382 alignas(DefinedEvent) char D[sizeof(DefinedEvent)];
383 alignas(LazySymbol) char E[sizeof(LazySymbol)];
384 alignas(UndefinedFunction) char F[sizeof(UndefinedFunction)];
385 alignas(UndefinedData) char G[sizeof(UndefinedData)];
386 alignas(UndefinedGlobal) char H[sizeof(UndefinedGlobal)];
387 alignas(SectionSymbol) char I[sizeof(SectionSymbol)];
481 alignas(DefinedFunction) char a[sizeof(DefinedFunction)];
482 alignas(DefinedData) char b[sizeof(DefinedData)];
483 alignas(DefinedGlobal) char c[sizeof(DefinedGlobal)];
484 alignas(DefinedEvent) char d[sizeof(DefinedEvent)];
485 alignas(LazySymbol) char e[sizeof(LazySymbol)];
486 alignas(UndefinedFunction) char f[sizeof(UndefinedFunction)];
487 alignas(UndefinedData) char g[sizeof(UndefinedData)];
488 alignas(UndefinedGlobal) char h[sizeof(UndefinedGlobal)];
489 alignas(SectionSymbol) char i[sizeof(SectionSymbol)];
388490};
389491
492// It is important to keep the size of SymbolUnion small for performance and
493// memory usage reasons. 96 bytes is a soft limit based on the size of
494// UndefinedFunction on a 64-bit system.
495static_assert(sizeof(SymbolUnion) <= 96, "SymbolUnion too large");
496
497void printTraceSymbol(Symbol *sym);
498void printTraceSymbolUndefined(StringRef name, const InputFile* file);
499
390500template <typename T, typename... ArgT>
391T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
501T *replaceSymbol(Symbol *s, ArgT &&... arg) {
392502 static_assert(std::is_trivially_destructible<T>(),
393503 "Symbol types must be trivially destructible");
394504 static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
......@@ -397,20 +507,28 @@ T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
397507 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
398508 "Not a Symbol");
399509
400 Symbol SymCopy = *S;
510 Symbol symCopy = *s;
511
512 T *s2 = new (s) T(std::forward<ArgT>(arg)...);
513 s2->isUsedInRegularObj = symCopy.isUsedInRegularObj;
514 s2->forceExport = symCopy.forceExport;
515 s2->canInline = symCopy.canInline;
516 s2->traced = symCopy.traced;
517
518 // Print out a log message if --trace-symbol was specified.
519 // This is for debugging.
520 if (s2->traced)
521 printTraceSymbol(s2);
401522
402 T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
403 S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
404 S2->ForceExport = SymCopy.ForceExport;
405 return S2;
523 return s2;
406524}
407525
408526} // namespace wasm
409527
410528// Returns a symbol name for an error message.
411std::string toString(const wasm::Symbol &Sym);
412std::string toString(wasm::Symbol::Kind Kind);
413std::string maybeDemangleSymbol(StringRef Name);
529std::string toString(const wasm::Symbol &sym);
530std::string toString(wasm::Symbol::Kind kind);
531std::string maybeDemangleSymbol(StringRef name);
414532
415533} // namespace lld
416534
deps/lld/wasm/SyntheticSections.cpp created+547
......@@ -0,0 +1,547 @@
1//===- SyntheticSections.cpp ----------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains linker-synthesized sections.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SyntheticSections.h"
14
15#include "InputChunks.h"
16#include "InputEvent.h"
17#include "InputGlobal.h"
18#include "OutputSegment.h"
19#include "SymbolTable.h"
20#include "llvm/Support/Path.h"
21
22using namespace llvm;
23using namespace llvm::wasm;
24
25using namespace lld;
26using namespace lld::wasm;
27
28OutStruct lld::wasm::out;
29
30namespace {
31
32// Some synthetic sections (e.g. "name" and "linking") have subsections.
33// Just like the synthetic sections themselves these need to be created before
34// they can be written out (since they are preceded by their length). This
35// class is used to create subsections and then write them into the stream
36// of the parent section.
37class SubSection {
38public:
39 explicit SubSection(uint32_t type) : type(type) {}
40
41 void writeTo(raw_ostream &to) {
42 os.flush();
43 writeUleb128(to, type, "subsection type");
44 writeUleb128(to, body.size(), "subsection size");
45 to.write(body.data(), body.size());
46 }
47
48private:
49 uint32_t type;
50 std::string body;
51
52public:
53 raw_string_ostream os{body};
54};
55
56} // namespace
57
58void DylinkSection::writeBody() {
59 raw_ostream &os = bodyOutputStream;
60
61 writeUleb128(os, memSize, "MemSize");
62 writeUleb128(os, memAlign, "MemAlign");
63 writeUleb128(os, out.elemSec->numEntries(), "TableSize");
64 writeUleb128(os, 0, "TableAlign");
65 writeUleb128(os, symtab->sharedFiles.size(), "Needed");
66 for (auto *so : symtab->sharedFiles)
67 writeStr(os, llvm::sys::path::filename(so->getName()), "so name");
68}
69
70uint32_t TypeSection::registerType(const WasmSignature &sig) {
71 auto pair = typeIndices.insert(std::make_pair(sig, types.size()));
72 if (pair.second) {
73 LLVM_DEBUG(llvm::dbgs() << "type " << toString(sig) << "\n");
74 types.push_back(&sig);
75 }
76 return pair.first->second;
77}
78
79uint32_t TypeSection::lookupType(const WasmSignature &sig) {
80 auto it = typeIndices.find(sig);
81 if (it == typeIndices.end()) {
82 error("type not found: " + toString(sig));
83 return 0;
84 }
85 return it->second;
86}
87
88void TypeSection::writeBody() {
89 writeUleb128(bodyOutputStream, types.size(), "type count");
90 for (const WasmSignature *sig : types)
91 writeSig(bodyOutputStream, *sig);
92}
93
94uint32_t ImportSection::getNumImports() const {
95 assert(isSealed);
96 uint32_t numImports = importedSymbols.size() + gotSymbols.size();
97 if (config->importMemory)
98 ++numImports;
99 if (config->importTable)
100 ++numImports;
101 return numImports;
102}
103
104void ImportSection::addGOTEntry(Symbol *sym) {
105 assert(!isSealed);
106 if (sym->hasGOTIndex())
107 return;
108 sym->setGOTIndex(numImportedGlobals++);
109 gotSymbols.push_back(sym);
110}
111
112void ImportSection::addImport(Symbol *sym) {
113 assert(!isSealed);
114 importedSymbols.emplace_back(sym);
115 if (auto *f = dyn_cast<FunctionSymbol>(sym))
116 f->setFunctionIndex(numImportedFunctions++);
117 else if (auto *g = dyn_cast<GlobalSymbol>(sym))
118 g->setGlobalIndex(numImportedGlobals++);
119 else
120 cast<EventSymbol>(sym)->setEventIndex(numImportedEvents++);
121}
122
123void ImportSection::writeBody() {
124 raw_ostream &os = bodyOutputStream;
125
126 writeUleb128(os, getNumImports(), "import count");
127
128 if (config->importMemory) {
129 WasmImport import;
130 import.Module = defaultModule;
131 import.Field = "memory";
132 import.Kind = WASM_EXTERNAL_MEMORY;
133 import.Memory.Flags = 0;
134 import.Memory.Initial = out.memorySec->numMemoryPages;
135 if (out.memorySec->maxMemoryPages != 0 || config->sharedMemory) {
136 import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
137 import.Memory.Maximum = out.memorySec->maxMemoryPages;
138 }
139 if (config->sharedMemory)
140 import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
141 writeImport(os, import);
142 }
143
144 if (config->importTable) {
145 uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries();
146 WasmImport import;
147 import.Module = defaultModule;
148 import.Field = functionTableName;
149 import.Kind = WASM_EXTERNAL_TABLE;
150 import.Table.ElemType = WASM_TYPE_FUNCREF;
151 import.Table.Limits = {0, tableSize, 0};
152 writeImport(os, import);
153 }
154
155 for (const Symbol *sym : importedSymbols) {
156 WasmImport import;
157 if (auto *f = dyn_cast<UndefinedFunction>(sym)) {
158 import.Field = f->importName;
159 import.Module = f->importModule;
160 } else if (auto *g = dyn_cast<UndefinedGlobal>(sym)) {
161 import.Field = g->importName;
162 import.Module = g->importModule;
163 } else {
164 import.Field = sym->getName();
165 import.Module = defaultModule;
166 }
167
168 if (auto *functionSym = dyn_cast<FunctionSymbol>(sym)) {
169 import.Kind = WASM_EXTERNAL_FUNCTION;
170 import.SigIndex = out.typeSec->lookupType(*functionSym->signature);
171 } else if (auto *globalSym = dyn_cast<GlobalSymbol>(sym)) {
172 import.Kind = WASM_EXTERNAL_GLOBAL;
173 import.Global = *globalSym->getGlobalType();
174 } else {
175 auto *eventSym = cast<EventSymbol>(sym);
176 import.Kind = WASM_EXTERNAL_EVENT;
177 import.Event.Attribute = eventSym->getEventType()->Attribute;
178 import.Event.SigIndex = out.typeSec->lookupType(*eventSym->signature);
179 }
180 writeImport(os, import);
181 }
182
183 for (const Symbol *sym : gotSymbols) {
184 WasmImport import;
185 import.Kind = WASM_EXTERNAL_GLOBAL;
186 import.Global = {WASM_TYPE_I32, true};
187 if (isa<DataSymbol>(sym))
188 import.Module = "GOT.mem";
189 else
190 import.Module = "GOT.func";
191 import.Field = sym->getName();
192 writeImport(os, import);
193 }
194}
195
196void FunctionSection::writeBody() {
197 raw_ostream &os = bodyOutputStream;
198
199 writeUleb128(os, inputFunctions.size(), "function count");
200 for (const InputFunction *func : inputFunctions)
201 writeUleb128(os, out.typeSec->lookupType(func->signature), "sig index");
202}
203
204void FunctionSection::addFunction(InputFunction *func) {
205 if (!func->live)
206 return;
207 uint32_t functionIndex =
208 out.importSec->getNumImportedFunctions() + inputFunctions.size();
209 inputFunctions.emplace_back(func);
210 func->setFunctionIndex(functionIndex);
211}
212
213void TableSection::writeBody() {
214 uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries();
215
216 raw_ostream &os = bodyOutputStream;
217 writeUleb128(os, 1, "table count");
218 WasmLimits limits = {WASM_LIMITS_FLAG_HAS_MAX, tableSize, tableSize};
219 writeTableType(os, WasmTable{WASM_TYPE_FUNCREF, limits});
220}
221
222void MemorySection::writeBody() {
223 raw_ostream &os = bodyOutputStream;
224
225 bool hasMax = maxMemoryPages != 0 || config->sharedMemory;
226 writeUleb128(os, 1, "memory count");
227 unsigned flags = 0;
228 if (hasMax)
229 flags |= WASM_LIMITS_FLAG_HAS_MAX;
230 if (config->sharedMemory)
231 flags |= WASM_LIMITS_FLAG_IS_SHARED;
232 writeUleb128(os, flags, "memory limits flags");
233 writeUleb128(os, numMemoryPages, "initial pages");
234 if (hasMax)
235 writeUleb128(os, maxMemoryPages, "max pages");
236}
237
238void GlobalSection::writeBody() {
239 raw_ostream &os = bodyOutputStream;
240
241 writeUleb128(os, numGlobals(), "global count");
242 for (const InputGlobal *g : inputGlobals)
243 writeGlobal(os, g->global);
244 for (const DefinedData *sym : definedFakeGlobals) {
245 WasmGlobal global;
246 global.Type = {WASM_TYPE_I32, false};
247 global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
248 global.InitExpr.Value.Int32 = sym->getVirtualAddress();
249 writeGlobal(os, global);
250 }
251}
252
253void GlobalSection::addGlobal(InputGlobal *global) {
254 if (!global->live)
255 return;
256 uint32_t globalIndex =
257 out.importSec->getNumImportedGlobals() + inputGlobals.size();
258 LLVM_DEBUG(dbgs() << "addGlobal: " << globalIndex << "\n");
259 global->setGlobalIndex(globalIndex);
260 out.globalSec->inputGlobals.push_back(global);
261}
262
263void EventSection::writeBody() {
264 raw_ostream &os = bodyOutputStream;
265
266 writeUleb128(os, inputEvents.size(), "event count");
267 for (InputEvent *e : inputEvents) {
268 e->event.Type.SigIndex = out.typeSec->lookupType(e->signature);
269 writeEvent(os, e->event);
270 }
271}
272
273void EventSection::addEvent(InputEvent *event) {
274 if (!event->live)
275 return;
276 uint32_t eventIndex =
277 out.importSec->getNumImportedEvents() + inputEvents.size();
278 LLVM_DEBUG(dbgs() << "addEvent: " << eventIndex << "\n");
279 event->setEventIndex(eventIndex);
280 inputEvents.push_back(event);
281}
282
283void ExportSection::writeBody() {
284 raw_ostream &os = bodyOutputStream;
285
286 writeUleb128(os, exports.size(), "export count");
287 for (const WasmExport &export_ : exports)
288 writeExport(os, export_);
289}
290
291void ElemSection::addEntry(FunctionSymbol *sym) {
292 if (sym->hasTableIndex())
293 return;
294 sym->setTableIndex(elemOffset + indirectFunctions.size());
295 indirectFunctions.emplace_back(sym);
296}
297
298void ElemSection::writeBody() {
299 raw_ostream &os = bodyOutputStream;
300
301 writeUleb128(os, 1, "segment count");
302 writeUleb128(os, 0, "table index");
303 WasmInitExpr initExpr;
304 if (config->isPic) {
305 initExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
306 initExpr.Value.Global = WasmSym::tableBase->getGlobalIndex();
307 } else {
308 initExpr.Opcode = WASM_OPCODE_I32_CONST;
309 initExpr.Value.Int32 = elemOffset;
310 }
311 writeInitExpr(os, initExpr);
312 writeUleb128(os, indirectFunctions.size(), "elem count");
313
314 uint32_t tableIndex = elemOffset;
315 for (const FunctionSymbol *sym : indirectFunctions) {
316 assert(sym->getTableIndex() == tableIndex);
317 writeUleb128(os, sym->getFunctionIndex(), "function index");
318 ++tableIndex;
319 }
320}
321
322void DataCountSection::writeBody() {
323 writeUleb128(bodyOutputStream, numSegments, "data count");
324}
325
326bool DataCountSection::isNeeded() const {
327 return numSegments && config->passiveSegments;
328}
329
330static uint32_t getWasmFlags(const Symbol *sym) {
331 uint32_t flags = 0;
332 if (sym->isLocal())
333 flags |= WASM_SYMBOL_BINDING_LOCAL;
334 if (sym->isWeak())
335 flags |= WASM_SYMBOL_BINDING_WEAK;
336 if (sym->isHidden())
337 flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
338 if (sym->isUndefined())
339 flags |= WASM_SYMBOL_UNDEFINED;
340 if (auto *f = dyn_cast<UndefinedFunction>(sym)) {
341 if (f->getName() != f->importName)
342 flags |= WASM_SYMBOL_EXPLICIT_NAME;
343 } else if (auto *g = dyn_cast<UndefinedGlobal>(sym)) {
344 if (g->getName() != g->importName)
345 flags |= WASM_SYMBOL_EXPLICIT_NAME;
346 }
347 return flags;
348}
349
350void LinkingSection::writeBody() {
351 raw_ostream &os = bodyOutputStream;
352
353 writeUleb128(os, WasmMetadataVersion, "Version");
354
355 if (!symtabEntries.empty()) {
356 SubSection sub(WASM_SYMBOL_TABLE);
357 writeUleb128(sub.os, symtabEntries.size(), "num symbols");
358
359 for (const Symbol *sym : symtabEntries) {
360 assert(sym->isDefined() || sym->isUndefined());
361 WasmSymbolType kind = sym->getWasmType();
362 uint32_t flags = getWasmFlags(sym);
363
364 writeU8(sub.os, kind, "sym kind");
365 writeUleb128(sub.os, flags, "sym flags");
366
367 if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
368 writeUleb128(sub.os, f->getFunctionIndex(), "index");
369 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
370 writeStr(sub.os, sym->getName(), "sym name");
371 } else if (auto *g = dyn_cast<GlobalSymbol>(sym)) {
372 writeUleb128(sub.os, g->getGlobalIndex(), "index");
373 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
374 writeStr(sub.os, sym->getName(), "sym name");
375 } else if (auto *e = dyn_cast<EventSymbol>(sym)) {
376 writeUleb128(sub.os, e->getEventIndex(), "index");
377 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
378 writeStr(sub.os, sym->getName(), "sym name");
379 } else if (isa<DataSymbol>(sym)) {
380 writeStr(sub.os, sym->getName(), "sym name");
381 if (auto *dataSym = dyn_cast<DefinedData>(sym)) {
382 writeUleb128(sub.os, dataSym->getOutputSegmentIndex(), "index");
383 writeUleb128(sub.os, dataSym->getOutputSegmentOffset(),
384 "data offset");
385 writeUleb128(sub.os, dataSym->getSize(), "data size");
386 }
387 } else {
388 auto *s = cast<OutputSectionSymbol>(sym);
389 writeUleb128(sub.os, s->section->sectionIndex, "sym section index");
390 }
391 }
392
393 sub.writeTo(os);
394 }
395
396 if (dataSegments.size()) {
397 SubSection sub(WASM_SEGMENT_INFO);
398 writeUleb128(sub.os, dataSegments.size(), "num data segments");
399 for (const OutputSegment *s : dataSegments) {
400 writeStr(sub.os, s->name, "segment name");
401 writeUleb128(sub.os, s->alignment, "alignment");
402 writeUleb128(sub.os, 0, "flags");
403 }
404 sub.writeTo(os);
405 }
406
407 if (!initFunctions.empty()) {
408 SubSection sub(WASM_INIT_FUNCS);
409 writeUleb128(sub.os, initFunctions.size(), "num init functions");
410 for (const WasmInitEntry &f : initFunctions) {
411 writeUleb128(sub.os, f.priority, "priority");
412 writeUleb128(sub.os, f.sym->getOutputSymbolIndex(), "function index");
413 }
414 sub.writeTo(os);
415 }
416
417 struct ComdatEntry {
418 unsigned kind;
419 uint32_t index;
420 };
421 std::map<StringRef, std::vector<ComdatEntry>> comdats;
422
423 for (const InputFunction *f : out.functionSec->inputFunctions) {
424 StringRef comdat = f->getComdatName();
425 if (!comdat.empty())
426 comdats[comdat].emplace_back(
427 ComdatEntry{WASM_COMDAT_FUNCTION, f->getFunctionIndex()});
428 }
429 for (uint32_t i = 0; i < dataSegments.size(); ++i) {
430 const auto &inputSegments = dataSegments[i]->inputSegments;
431 if (inputSegments.empty())
432 continue;
433 StringRef comdat = inputSegments[0]->getComdatName();
434#ifndef NDEBUG
435 for (const InputSegment *isec : inputSegments)
436 assert(isec->getComdatName() == comdat);
437#endif
438 if (!comdat.empty())
439 comdats[comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, i});
440 }
441
442 if (!comdats.empty()) {
443 SubSection sub(WASM_COMDAT_INFO);
444 writeUleb128(sub.os, comdats.size(), "num comdats");
445 for (const auto &c : comdats) {
446 writeStr(sub.os, c.first, "comdat name");
447 writeUleb128(sub.os, 0, "comdat flags"); // flags for future use
448 writeUleb128(sub.os, c.second.size(), "num entries");
449 for (const ComdatEntry &entry : c.second) {
450 writeU8(sub.os, entry.kind, "entry kind");
451 writeUleb128(sub.os, entry.index, "entry index");
452 }
453 }
454 sub.writeTo(os);
455 }
456}
457
458void LinkingSection::addToSymtab(Symbol *sym) {
459 sym->setOutputSymbolIndex(symtabEntries.size());
460 symtabEntries.emplace_back(sym);
461}
462
463unsigned NameSection::numNames() const {
464 unsigned numNames = out.importSec->getNumImportedFunctions();
465 for (const InputFunction *f : out.functionSec->inputFunctions)
466 if (!f->getName().empty() || !f->getDebugName().empty())
467 ++numNames;
468
469 return numNames;
470}
471
472// Create the custom "name" section containing debug symbol names.
473void NameSection::writeBody() {
474 SubSection sub(WASM_NAMES_FUNCTION);
475 writeUleb128(sub.os, numNames(), "name count");
476
477 // Names must appear in function index order. As it happens importedSymbols
478 // and inputFunctions are numbered in order with imported functions coming
479 // first.
480 for (const Symbol *s : out.importSec->importedSymbols) {
481 if (auto *f = dyn_cast<FunctionSymbol>(s)) {
482 writeUleb128(sub.os, f->getFunctionIndex(), "func index");
483 writeStr(sub.os, toString(*s), "symbol name");
484 }
485 }
486 for (const InputFunction *f : out.functionSec->inputFunctions) {
487 if (!f->getName().empty()) {
488 writeUleb128(sub.os, f->getFunctionIndex(), "func index");
489 if (!f->getDebugName().empty()) {
490 writeStr(sub.os, f->getDebugName(), "symbol name");
491 } else {
492 writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name");
493 }
494 }
495 }
496
497 sub.writeTo(bodyOutputStream);
498}
499
500void ProducersSection::addInfo(const WasmProducerInfo &info) {
501 for (auto &producers :
502 {std::make_pair(&info.Languages, &languages),
503 std::make_pair(&info.Tools, &tools), std::make_pair(&info.SDKs, &sDKs)})
504 for (auto &producer : *producers.first)
505 if (producers.second->end() ==
506 llvm::find_if(*producers.second,
507 [&](std::pair<std::string, std::string> seen) {
508 return seen.first == producer.first;
509 }))
510 producers.second->push_back(producer);
511}
512
513void ProducersSection::writeBody() {
514 auto &os = bodyOutputStream;
515 writeUleb128(os, fieldCount(), "field count");
516 for (auto &field :
517 {std::make_pair("language", languages),
518 std::make_pair("processed-by", tools), std::make_pair("sdk", sDKs)}) {
519 if (field.second.empty())
520 continue;
521 writeStr(os, field.first, "field name");
522 writeUleb128(os, field.second.size(), "number of entries");
523 for (auto &entry : field.second) {
524 writeStr(os, entry.first, "producer name");
525 writeStr(os, entry.second, "producer version");
526 }
527 }
528}
529
530void TargetFeaturesSection::writeBody() {
531 SmallVector<std::string, 8> emitted(features.begin(), features.end());
532 llvm::sort(emitted);
533 auto &os = bodyOutputStream;
534 writeUleb128(os, emitted.size(), "feature count");
535 for (auto &feature : emitted) {
536 writeU8(os, WASM_FEATURE_PREFIX_USED, "feature used prefix");
537 writeStr(os, feature, "feature name");
538 }
539}
540
541void RelocSection::writeBody() {
542 uint32_t count = sec->getNumRelocations();
543 assert(sec->sectionIndex != UINT32_MAX);
544 writeUleb128(bodyOutputStream, sec->sectionIndex, "reloc section");
545 writeUleb128(bodyOutputStream, count, "reloc count");
546 sec->writeRelocations(bodyOutputStream);
547}
deps/lld/wasm/SyntheticSections.h created+339
......@@ -0,0 +1,339 @@
1//===- SyntheticSection.h ---------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Synthetic sections represent chunks of linker-created data. If you
10// need to create a chunk of data that to be included in some section
11// in the result, you probably want to create that as a synthetic section.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLD_WASM_SYNTHETIC_SECTIONS_H
16#define LLD_WASM_SYNTHETIC_SECTIONS_H
17
18#include "OutputSections.h"
19
20#include "llvm/ADT/SmallSet.h"
21#include "llvm/ADT/StringMap.h"
22#include "llvm/Object/WasmTraits.h"
23
24#define DEBUG_TYPE "lld"
25
26namespace lld {
27namespace wasm {
28
29// An init entry to be written to either the synthetic init func or the
30// linking metadata.
31struct WasmInitEntry {
32 const FunctionSymbol *sym;
33 uint32_t priority;
34};
35
36class SyntheticSection : public OutputSection {
37public:
38 SyntheticSection(uint32_t type, std::string name = "")
39 : OutputSection(type, name), bodyOutputStream(body) {
40 if (!name.empty())
41 writeStr(bodyOutputStream, name, "section name");
42 }
43
44 void writeTo(uint8_t *buf) override {
45 assert(offset);
46 log("writing " + toString(*this));
47 memcpy(buf + offset, header.data(), header.size());
48 memcpy(buf + offset + header.size(), body.data(), body.size());
49 }
50
51 size_t getSize() const override { return header.size() + body.size(); }
52
53 virtual void writeBody() {}
54
55 void finalizeContents() override {
56 writeBody();
57 bodyOutputStream.flush();
58 createHeader(body.size());
59 }
60
61 raw_ostream &getStream() { return bodyOutputStream; }
62
63 std::string body;
64
65protected:
66 llvm::raw_string_ostream bodyOutputStream;
67};
68
69// Create the custom "dylink" section containing information for the dynamic
70// linker.
71// See
72// https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
73class DylinkSection : public SyntheticSection {
74public:
75 DylinkSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "dylink") {}
76 bool isNeeded() const override { return config->isPic; }
77 void writeBody() override;
78
79 uint32_t memAlign = 0;
80 uint32_t memSize = 0;
81};
82
83class TypeSection : public SyntheticSection {
84public:
85 TypeSection() : SyntheticSection(llvm::wasm::WASM_SEC_TYPE) {}
86
87 bool isNeeded() const override { return types.size() > 0; };
88 void writeBody() override;
89 uint32_t registerType(const WasmSignature &sig);
90 uint32_t lookupType(const WasmSignature &sig);
91
92protected:
93 std::vector<const WasmSignature *> types;
94 llvm::DenseMap<WasmSignature, int32_t> typeIndices;
95};
96
97class ImportSection : public SyntheticSection {
98public:
99 ImportSection() : SyntheticSection(llvm::wasm::WASM_SEC_IMPORT) {}
100 bool isNeeded() const override { return getNumImports() > 0; }
101 void writeBody() override;
102 void addImport(Symbol *sym);
103 void addGOTEntry(Symbol *sym);
104 void seal() { isSealed = true; }
105 uint32_t getNumImports() const;
106 uint32_t getNumImportedGlobals() const {
107 assert(isSealed);
108 return numImportedGlobals;
109 }
110 uint32_t getNumImportedFunctions() const {
111 assert(isSealed);
112 return numImportedFunctions;
113 }
114 uint32_t getNumImportedEvents() const {
115 assert(isSealed);
116 return numImportedEvents;
117 }
118
119 std::vector<const Symbol *> importedSymbols;
120
121protected:
122 bool isSealed = false;
123 unsigned numImportedGlobals = 0;
124 unsigned numImportedFunctions = 0;
125 unsigned numImportedEvents = 0;
126 std::vector<const Symbol *> gotSymbols;
127};
128
129class FunctionSection : public SyntheticSection {
130public:
131 FunctionSection() : SyntheticSection(llvm::wasm::WASM_SEC_FUNCTION) {}
132
133 bool isNeeded() const override { return inputFunctions.size() > 0; };
134 void writeBody() override;
135 void addFunction(InputFunction *func);
136
137 std::vector<InputFunction *> inputFunctions;
138
139protected:
140};
141
142class MemorySection : public SyntheticSection {
143public:
144 MemorySection() : SyntheticSection(llvm::wasm::WASM_SEC_MEMORY) {}
145
146 bool isNeeded() const override { return !config->importMemory; }
147 void writeBody() override;
148
149 uint32_t numMemoryPages = 0;
150 uint32_t maxMemoryPages = 0;
151};
152
153class TableSection : public SyntheticSection {
154public:
155 TableSection() : SyntheticSection(llvm::wasm::WASM_SEC_TABLE) {}
156
157 bool isNeeded() const override {
158 // Always output a table section (or table import), even if there are no
159 // indirect calls. There are two reasons for this:
160 // 1. For executables it is useful to have an empty table slot at 0
161 // which can be filled with a null function call handler.
162 // 2. If we don't do this, any program that contains a call_indirect but
163 // no address-taken function will fail at validation time since it is
164 // a validation error to include a call_indirect instruction if there
165 // is not table.
166 return !config->importTable;
167 }
168
169 void writeBody() override;
170};
171
172class GlobalSection : public SyntheticSection {
173public:
174 GlobalSection() : SyntheticSection(llvm::wasm::WASM_SEC_GLOBAL) {}
175 uint32_t numGlobals() const {
176 return inputGlobals.size() + definedFakeGlobals.size();
177 }
178 bool isNeeded() const override { return numGlobals() > 0; }
179 void writeBody() override;
180 void addGlobal(InputGlobal *global);
181
182 std::vector<const DefinedData *> definedFakeGlobals;
183 std::vector<InputGlobal *> inputGlobals;
184};
185
186// The event section contains a list of declared wasm events associated with the
187// module. Currently the only supported event kind is exceptions. A single event
188// entry represents a single event with an event tag. All C++ exceptions are
189// represented by a single event. An event entry in this section contains
190// information on what kind of event it is (e.g. exception) and the type of
191// values contained in a single event object. (In wasm, an event can contain
192// multiple values of primitive types. But for C++ exceptions, we just throw a
193// pointer which is an i32 value (for wasm32 architecture), so the signature of
194// C++ exception is (i32)->(void), because all event types are assumed to have
195// void return type to share WasmSignature with functions.)
196class EventSection : public SyntheticSection {
197public:
198 EventSection() : SyntheticSection(llvm::wasm::WASM_SEC_EVENT) {}
199 void writeBody() override;
200 bool isNeeded() const override { return inputEvents.size() > 0; }
201 void addEvent(InputEvent *event);
202
203 std::vector<InputEvent *> inputEvents;
204};
205
206class ExportSection : public SyntheticSection {
207public:
208 ExportSection() : SyntheticSection(llvm::wasm::WASM_SEC_EXPORT) {}
209 bool isNeeded() const override { return exports.size() > 0; }
210 void writeBody() override;
211
212 std::vector<llvm::wasm::WasmExport> exports;
213};
214
215class ElemSection : public SyntheticSection {
216public:
217 ElemSection(uint32_t offset)
218 : SyntheticSection(llvm::wasm::WASM_SEC_ELEM), elemOffset(offset) {}
219 bool isNeeded() const override { return indirectFunctions.size() > 0; };
220 void writeBody() override;
221 void addEntry(FunctionSymbol *sym);
222 uint32_t numEntries() const { return indirectFunctions.size(); }
223 uint32_t elemOffset;
224
225protected:
226 std::vector<const FunctionSymbol *> indirectFunctions;
227};
228
229class DataCountSection : public SyntheticSection {
230public:
231 DataCountSection(uint32_t numSegments)
232 : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT),
233 numSegments(numSegments) {}
234 bool isNeeded() const override;
235 void writeBody() override;
236
237protected:
238 uint32_t numSegments;
239};
240
241// Create the custom "linking" section containing linker metadata.
242// This is only created when relocatable output is requested.
243class LinkingSection : public SyntheticSection {
244public:
245 LinkingSection(const std::vector<WasmInitEntry> &initFunctions,
246 const std::vector<OutputSegment *> &dataSegments)
247 : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "linking"),
248 initFunctions(initFunctions), dataSegments(dataSegments) {}
249 bool isNeeded() const override {
250 return config->relocatable || config->emitRelocs;
251 }
252 void writeBody() override;
253 void addToSymtab(Symbol *sym);
254
255protected:
256 std::vector<const Symbol *> symtabEntries;
257 llvm::StringMap<uint32_t> sectionSymbolIndices;
258 const std::vector<WasmInitEntry> &initFunctions;
259 const std::vector<OutputSegment *> &dataSegments;
260};
261
262// Create the custom "name" section containing debug symbol names.
263class NameSection : public SyntheticSection {
264public:
265 NameSection() : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "name") {}
266 bool isNeeded() const override {
267 return !config->stripDebug && !config->stripAll && numNames() > 0;
268 }
269 void writeBody() override;
270 unsigned numNames() const;
271};
272
273class ProducersSection : public SyntheticSection {
274public:
275 ProducersSection()
276 : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "producers") {}
277 bool isNeeded() const override {
278 return !config->stripAll && fieldCount() > 0;
279 }
280 void writeBody() override;
281 void addInfo(const llvm::wasm::WasmProducerInfo &info);
282
283protected:
284 int fieldCount() const {
285 return int(!languages.empty()) + int(!tools.empty()) + int(!sDKs.empty());
286 }
287 SmallVector<std::pair<std::string, std::string>, 8> languages;
288 SmallVector<std::pair<std::string, std::string>, 8> tools;
289 SmallVector<std::pair<std::string, std::string>, 8> sDKs;
290};
291
292class TargetFeaturesSection : public SyntheticSection {
293public:
294 TargetFeaturesSection()
295 : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, "target_features") {}
296 bool isNeeded() const override {
297 return !config->stripAll && features.size() > 0;
298 }
299 void writeBody() override;
300
301 llvm::SmallSet<std::string, 8> features;
302};
303
304class RelocSection : public SyntheticSection {
305public:
306 RelocSection(StringRef name, OutputSection *sec)
307 : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, name), sec(sec) {}
308 void writeBody() override;
309 bool isNeeded() const override { return sec->getNumRelocations() > 0; };
310
311protected:
312 OutputSection *sec;
313};
314
315// Linker generated output sections
316struct OutStruct {
317 DylinkSection *dylinkSec;
318 TypeSection *typeSec;
319 FunctionSection *functionSec;
320 ImportSection *importSec;
321 TableSection *tableSec;
322 MemorySection *memorySec;
323 GlobalSection *globalSec;
324 EventSection *eventSec;
325 ExportSection *exportSec;
326 ElemSection *elemSec;
327 DataCountSection *dataCountSec;
328 LinkingSection *linkingSec;
329 NameSection *nameSec;
330 ProducersSection *producersSec;
331 TargetFeaturesSection *targetFeaturesSec;
332};
333
334extern OutStruct out;
335
336} // namespace wasm
337} // namespace lld
338
339#endif
deps/lld/wasm/Writer.cpp+659-909
......@@ -1,9 +1,8 @@
11//===- Writer.cpp ---------------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -14,13 +13,17 @@
1413#include "InputGlobal.h"
1514#include "OutputSections.h"
1615#include "OutputSegment.h"
16#include "Relocations.h"
1717#include "SymbolTable.h"
18#include "SyntheticSections.h"
1819#include "WriterUtils.h"
1920#include "lld/Common/ErrorHandler.h"
2021#include "lld/Common/Memory.h"
2122#include "lld/Common/Strings.h"
2223#include "lld/Common/Threads.h"
2324#include "llvm/ADT/DenseSet.h"
25#include "llvm/ADT/SmallSet.h"
26#include "llvm/ADT/SmallVector.h"
2427#include "llvm/ADT/StringMap.h"
2528#include "llvm/BinaryFormat/Wasm.h"
2629#include "llvm/Object/WasmTraits.h"
......@@ -39,19 +42,10 @@ using namespace llvm::wasm;
3942using namespace lld;
4043using namespace lld::wasm;
4144
42static constexpr int StackAlignment = 16;
43static constexpr const char *FunctionTableName = "__indirect_function_table";
44const char *lld::wasm::DefaultModule = "env";
45static constexpr int stackAlignment = 16;
4546
4647namespace {
4748
48// An init entry to be written to either the synthetic init func or the
49// linking metadata.
50struct WasmInitEntry {
51 const FunctionSymbol *Sym;
52 uint32_t Priority;
53};
54
5549// The writer writes a SymbolTable result to a file.
5650class Writer {
5751public:
......@@ -60,613 +54,145 @@ public:
6054private:
6155 void openFile();
6256
63 uint32_t lookupType(const WasmSignature &Sig);
64 uint32_t registerType(const WasmSignature &Sig);
57 void createInitMemoryFunction();
58 void createApplyRelocationsFunction();
59 void createCallCtorsFunction();
60 void createInitTLSFunction();
6561
66 void createCtorFunction();
67 void calculateInitFunctions();
6862 void assignIndexes();
63 void populateSymtab();
64 void populateProducers();
65 void populateTargetFeatures();
66 void calculateInitFunctions();
6967 void calculateImports();
7068 void calculateExports();
7169 void calculateCustomSections();
72 void assignSymtab();
7370 void calculateTypes();
7471 void createOutputSegments();
7572 void layoutMemory();
7673 void createHeader();
77 void createSections();
78 SyntheticSection *createSyntheticSection(uint32_t Type, StringRef Name = "");
79
80 // Builtin sections
81 void createTypeSection();
82 void createFunctionSection();
83 void createTableSection();
84 void createGlobalSection();
85 void createEventSection();
86 void createExportSection();
87 void createImportSection();
88 void createMemorySection();
89 void createElemSection();
90 void createCodeSection();
91 void createDataSection();
74
75 void addSection(OutputSection *sec);
76
77 void addSections();
78
9279 void createCustomSections();
80 void createSyntheticSections();
81 void finalizeSections();
9382
9483 // Custom sections
95 void createDylinkSection();
9684 void createRelocSections();
97 void createLinkingSection();
98 void createNameSection();
9985
10086 void writeHeader();
10187 void writeSections();
10288
103 uint64_t FileSize = 0;
104 uint32_t TableBase = 0;
105 uint32_t NumMemoryPages = 0;
106 uint32_t MaxMemoryPages = 0;
107 // Memory size and aligment. Written to the "dylink" section
108 // when build with -shared or -pie.
109 uint32_t MemAlign = 0;
110 uint32_t MemSize = 0;
111
112 std::vector<const WasmSignature *> Types;
113 DenseMap<WasmSignature, int32_t> TypeIndices;
114 std::vector<const Symbol *> ImportedSymbols;
115 unsigned NumImportedFunctions = 0;
116 unsigned NumImportedGlobals = 0;
117 unsigned NumImportedEvents = 0;
118 std::vector<WasmExport> Exports;
119 std::vector<const DefinedData *> DefinedFakeGlobals;
120 std::vector<InputGlobal *> InputGlobals;
121 std::vector<InputFunction *> InputFunctions;
122 std::vector<InputEvent *> InputEvents;
123 std::vector<const FunctionSymbol *> IndirectFunctions;
124 std::vector<const Symbol *> SymtabEntries;
125 std::vector<WasmInitEntry> InitFunctions;
126
127 llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping;
128 llvm::StringMap<SectionSymbol *> CustomSectionSymbols;
89 uint64_t fileSize = 0;
90 uint32_t tableBase = 0;
91
92 std::vector<WasmInitEntry> initFunctions;
93 llvm::StringMap<std::vector<InputSection *>> customSectionMapping;
12994
13095 // Elements that are used to construct the final output
131 std::string Header;
132 std::vector<OutputSection *> OutputSections;
96 std::string header;
97 std::vector<OutputSection *> outputSections;
13398
134 std::unique_ptr<FileOutputBuffer> Buffer;
99 std::unique_ptr<FileOutputBuffer> buffer;
135100
136 std::vector<OutputSegment *> Segments;
137 llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap;
101 std::vector<OutputSegment *> segments;
102 llvm::SmallDenseMap<StringRef, OutputSegment *> segmentMap;
138103};
139104
140105} // anonymous namespace
141106
142void Writer::createImportSection() {
143 uint32_t NumImports = ImportedSymbols.size();
144 if (Config->ImportMemory)
145 ++NumImports;
146 if (Config->ImportTable)
147 ++NumImports;
148
149 if (NumImports == 0)
150 return;
151
152 SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT);
153 raw_ostream &OS = Section->getStream();
154
155 writeUleb128(OS, NumImports, "import count");
156
157 if (Config->ImportMemory) {
158 WasmImport Import;
159 Import.Module = DefaultModule;
160 Import.Field = "memory";
161 Import.Kind = WASM_EXTERNAL_MEMORY;
162 Import.Memory.Flags = 0;
163 Import.Memory.Initial = NumMemoryPages;
164 if (MaxMemoryPages != 0) {
165 Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
166 Import.Memory.Maximum = MaxMemoryPages;
167 }
168 if (Config->SharedMemory)
169 Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
170 writeImport(OS, Import);
171 }
172
173 if (Config->ImportTable) {
174 uint32_t TableSize = TableBase + IndirectFunctions.size();
175 WasmImport Import;
176 Import.Module = DefaultModule;
177 Import.Field = FunctionTableName;
178 Import.Kind = WASM_EXTERNAL_TABLE;
179 Import.Table.ElemType = WASM_TYPE_FUNCREF;
180 Import.Table.Limits = {0, TableSize, 0};
181 writeImport(OS, Import);
182 }
183
184 for (const Symbol *Sym : ImportedSymbols) {
185 WasmImport Import;
186 if (auto *F = dyn_cast<UndefinedFunction>(Sym)) {
187 Import.Field = F->ImportName;
188 Import.Module = F->ImportModule;
189 } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) {
190 Import.Field = G->ImportName;
191 Import.Module = G->ImportModule;
192 } else {
193 Import.Field = Sym->getName();
194 Import.Module = DefaultModule;
195 }
196
197 if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
198 Import.Kind = WASM_EXTERNAL_FUNCTION;
199 Import.SigIndex = lookupType(*FunctionSym->Signature);
200 } else if (auto *GlobalSym = dyn_cast<GlobalSymbol>(Sym)) {
201 Import.Kind = WASM_EXTERNAL_GLOBAL;
202 Import.Global = *GlobalSym->getGlobalType();
203 } else {
204 auto *EventSym = cast<EventSymbol>(Sym);
205 Import.Kind = WASM_EXTERNAL_EVENT;
206 Import.Event.Attribute = EventSym->getEventType()->Attribute;
207 Import.Event.SigIndex = lookupType(*EventSym->Signature);
208 }
209 writeImport(OS, Import);
210 }
211}
212
213void Writer::createTypeSection() {
214 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE);
215 raw_ostream &OS = Section->getStream();
216 writeUleb128(OS, Types.size(), "type count");
217 for (const WasmSignature *Sig : Types)
218 writeSig(OS, *Sig);
219}
220
221void Writer::createFunctionSection() {
222 if (InputFunctions.empty())
223 return;
224
225 SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION);
226 raw_ostream &OS = Section->getStream();
227
228 writeUleb128(OS, InputFunctions.size(), "function count");
229 for (const InputFunction *Func : InputFunctions)
230 writeUleb128(OS, lookupType(Func->Signature), "sig index");
231}
232
233void Writer::createMemorySection() {
234 if (Config->ImportMemory)
235 return;
236
237 SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY);
238 raw_ostream &OS = Section->getStream();
239
240 bool HasMax = MaxMemoryPages != 0;
241 writeUleb128(OS, 1, "memory count");
242 unsigned Flags = 0;
243 if (HasMax)
244 Flags |= WASM_LIMITS_FLAG_HAS_MAX;
245 if (Config->SharedMemory)
246 Flags |= WASM_LIMITS_FLAG_IS_SHARED;
247 writeUleb128(OS, Flags, "memory limits flags");
248 writeUleb128(OS, NumMemoryPages, "initial pages");
249 if (HasMax)
250 writeUleb128(OS, MaxMemoryPages, "max pages");
251}
252
253void Writer::createGlobalSection() {
254 unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size();
255 if (NumGlobals == 0)
256 return;
257
258 SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
259 raw_ostream &OS = Section->getStream();
260
261 writeUleb128(OS, NumGlobals, "global count");
262 for (const InputGlobal *G : InputGlobals)
263 writeGlobal(OS, G->Global);
264 for (const DefinedData *Sym : DefinedFakeGlobals) {
265 WasmGlobal Global;
266 Global.Type = {WASM_TYPE_I32, false};
267 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
268 Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
269 writeGlobal(OS, Global);
270 }
271}
272
273// The event section contains a list of declared wasm events associated with the
274// module. Currently the only supported event kind is exceptions. A single event
275// entry represents a single event with an event tag. All C++ exceptions are
276// represented by a single event. An event entry in this section contains
277// information on what kind of event it is (e.g. exception) and the type of
278// values contained in a single event object. (In wasm, an event can contain
279// multiple values of primitive types. But for C++ exceptions, we just throw a
280// pointer which is an i32 value (for wasm32 architecture), so the signature of
281// C++ exception is (i32)->(void), because all event types are assumed to have
282// void return type to share WasmSignature with functions.)
283void Writer::createEventSection() {
284 unsigned NumEvents = InputEvents.size();
285 if (NumEvents == 0)
286 return;
287
288 SyntheticSection *Section = createSyntheticSection(WASM_SEC_EVENT);
289 raw_ostream &OS = Section->getStream();
290
291 writeUleb128(OS, NumEvents, "event count");
292 for (InputEvent *E : InputEvents) {
293 E->Event.Type.SigIndex = lookupType(E->Signature);
294 writeEvent(OS, E->Event);
295 }
296}
297
298void Writer::createTableSection() {
299 if (Config->ImportTable)
300 return;
301
302 // Always output a table section (or table import), even if there are no
303 // indirect calls. There are two reasons for this:
304 // 1. For executables it is useful to have an empty table slot at 0
305 // which can be filled with a null function call handler.
306 // 2. If we don't do this, any program that contains a call_indirect but
307 // no address-taken function will fail at validation time since it is
308 // a validation error to include a call_indirect instruction if there
309 // is not table.
310 uint32_t TableSize = TableBase + IndirectFunctions.size();
311
312 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE);
313 raw_ostream &OS = Section->getStream();
314
315 writeUleb128(OS, 1, "table count");
316 WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
317 writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits});
318}
319
320void Writer::createExportSection() {
321 if (!Exports.size())
322 return;
323
324 SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT);
325 raw_ostream &OS = Section->getStream();
326
327 writeUleb128(OS, Exports.size(), "export count");
328 for (const WasmExport &Export : Exports)
329 writeExport(OS, Export);
330}
331
332107void Writer::calculateCustomSections() {
333108 log("calculateCustomSections");
334 bool StripDebug = Config->StripDebug || Config->StripAll;
335 for (ObjFile *File : Symtab->ObjectFiles) {
336 for (InputSection *Section : File->CustomSections) {
337 StringRef Name = Section->getName();
109 bool stripDebug = config->stripDebug || config->stripAll;
110 for (ObjFile *file : symtab->objectFiles) {
111 for (InputSection *section : file->customSections) {
112 StringRef name = section->getName();
338113 // These custom sections are known the linker and synthesized rather than
339114 // blindly copied
340 if (Name == "linking" || Name == "name" || Name.startswith("reloc."))
115 if (name == "linking" || name == "name" || name == "producers" ||
116 name == "target_features" || name.startswith("reloc."))
341117 continue;
342118 // .. or it is a debug section
343 if (StripDebug && Name.startswith(".debug_"))
119 if (stripDebug && name.startswith(".debug_"))
344120 continue;
345 CustomSectionMapping[Name].push_back(Section);
121 customSectionMapping[name].push_back(section);
346122 }
347123 }
348124}
349125
350126void Writer::createCustomSections() {
351127 log("createCustomSections");
352 for (auto &Pair : CustomSectionMapping) {
353 StringRef Name = Pair.first();
354
355 auto P = CustomSectionSymbols.find(Name);
356 if (P != CustomSectionSymbols.end()) {
357 uint32_t SectionIndex = OutputSections.size();
358 P->second->setOutputSectionIndex(SectionIndex);
128 for (auto &pair : customSectionMapping) {
129 StringRef name = pair.first();
130 LLVM_DEBUG(dbgs() << "createCustomSection: " << name << "\n");
131
132 OutputSection *sec = make<CustomSection>(name, pair.second);
133 if (config->relocatable || config->emitRelocs) {
134 auto *sym = make<OutputSectionSymbol>(sec);
135 out.linkingSec->addToSymtab(sym);
136 sec->sectionSym = sym;
359137 }
360
361 LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n");
362 OutputSections.push_back(make<CustomSection>(Name, Pair.second));
138 addSection(sec);
363139 }
364140}
365141
366void Writer::createElemSection() {
367 if (IndirectFunctions.empty())
368 return;
369
370 SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM);
371 raw_ostream &OS = Section->getStream();
372
373 writeUleb128(OS, 1, "segment count");
374 writeUleb128(OS, 0, "table index");
375 WasmInitExpr InitExpr;
376 if (Config->Pic) {
377 InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
378 InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex();
379 } else {
380 InitExpr.Opcode = WASM_OPCODE_I32_CONST;
381 InitExpr.Value.Int32 = TableBase;
382 }
383 writeInitExpr(OS, InitExpr);
384 writeUleb128(OS, IndirectFunctions.size(), "elem count");
385
386 uint32_t TableIndex = TableBase;
387 for (const FunctionSymbol *Sym : IndirectFunctions) {
388 assert(Sym->getTableIndex() == TableIndex);
389 writeUleb128(OS, Sym->getFunctionIndex(), "function index");
390 ++TableIndex;
391 }
392}
393
394void Writer::createCodeSection() {
395 if (InputFunctions.empty())
396 return;
397
398 log("createCodeSection");
399
400 auto Section = make<CodeSection>(InputFunctions);
401 OutputSections.push_back(Section);
402}
403
404void Writer::createDataSection() {
405 if (!Segments.size())
406 return;
407
408 log("createDataSection");
409 auto Section = make<DataSection>(Segments);
410 OutputSections.push_back(Section);
411}
412
413142// Create relocations sections in the final output.
414143// These are only created when relocatable output is requested.
415144void Writer::createRelocSections() {
416145 log("createRelocSections");
417146 // Don't use iterator here since we are adding to OutputSection
418 size_t OrigSize = OutputSections.size();
419 for (size_t I = 0; I < OrigSize; I++) {
420 OutputSection *OSec = OutputSections[I];
421 uint32_t Count = OSec->numRelocations();
422 if (!Count)
147 size_t origSize = outputSections.size();
148 for (size_t i = 0; i < origSize; i++) {
149 LLVM_DEBUG(dbgs() << "check section " << i << "\n");
150 OutputSection *sec = outputSections[i];
151
152 // Count the number of needed sections.
153 uint32_t count = sec->getNumRelocations();
154 if (!count)
423155 continue;
424156
425 StringRef Name;
426 if (OSec->Type == WASM_SEC_DATA)
427 Name = "reloc.DATA";
428 else if (OSec->Type == WASM_SEC_CODE)
429 Name = "reloc.CODE";
430 else if (OSec->Type == WASM_SEC_CUSTOM)
431 Name = Saver.save("reloc." + OSec->Name);
157 StringRef name;
158 if (sec->type == WASM_SEC_DATA)
159 name = "reloc.DATA";
160 else if (sec->type == WASM_SEC_CODE)
161 name = "reloc.CODE";
162 else if (sec->type == WASM_SEC_CUSTOM)
163 name = saver.save("reloc." + sec->name);
432164 else
433165 llvm_unreachable(
434166 "relocations only supported for code, data, or custom sections");
435167
436 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name);
437 raw_ostream &OS = Section->getStream();
438 writeUleb128(OS, I, "reloc section");
439 writeUleb128(OS, Count, "reloc count");
440 OSec->writeRelocations(OS);
441 }
442}
443
444static uint32_t getWasmFlags(const Symbol *Sym) {
445 uint32_t Flags = 0;
446 if (Sym->isLocal())
447 Flags |= WASM_SYMBOL_BINDING_LOCAL;
448 if (Sym->isWeak())
449 Flags |= WASM_SYMBOL_BINDING_WEAK;
450 if (Sym->isHidden())
451 Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
452 if (Sym->isUndefined())
453 Flags |= WASM_SYMBOL_UNDEFINED;
454 if (auto *F = dyn_cast<UndefinedFunction>(Sym)) {
455 if (F->getName() != F->ImportName)
456 Flags |= WASM_SYMBOL_EXPLICIT_NAME;
457 } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) {
458 if (G->getName() != G->ImportName)
459 Flags |= WASM_SYMBOL_EXPLICIT_NAME;
168 addSection(make<RelocSection>(name, sec));
460169 }
461 return Flags;
462170}
463171
464// Some synthetic sections (e.g. "name" and "linking") have subsections.
465// Just like the synthetic sections themselves these need to be created before
466// they can be written out (since they are preceded by their length). This
467// class is used to create subsections and then write them into the stream
468// of the parent section.
469class SubSection {
470public:
471 explicit SubSection(uint32_t Type) : Type(Type) {}
472
473 void writeTo(raw_ostream &To) {
474 OS.flush();
475 writeUleb128(To, Type, "subsection type");
476 writeUleb128(To, Body.size(), "subsection size");
477 To.write(Body.data(), Body.size());
172void Writer::populateProducers() {
173 for (ObjFile *file : symtab->objectFiles) {
174 const WasmProducerInfo &info = file->getWasmObj()->getProducerInfo();
175 out.producersSec->addInfo(info);
478176 }
479
480private:
481 uint32_t Type;
482 std::string Body;
483
484public:
485 raw_string_ostream OS{Body};
486};
487
488// Create the custom "dylink" section containing information for the dynamic
489// linker.
490// See
491// https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
492void Writer::createDylinkSection() {
493 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "dylink");
494 raw_ostream &OS = Section->getStream();
495
496 writeUleb128(OS, MemSize, "MemSize");
497 writeUleb128(OS, MemAlign, "MemAlign");
498 writeUleb128(OS, IndirectFunctions.size(), "TableSize");
499 writeUleb128(OS, 0, "TableAlign");
500 writeUleb128(OS, 0, "Needed"); // TODO: Support "needed" shared libraries
501}
502
503// Create the custom "linking" section containing linker metadata.
504// This is only created when relocatable output is requested.
505void Writer::createLinkingSection() {
506 SyntheticSection *Section =
507 createSyntheticSection(WASM_SEC_CUSTOM, "linking");
508 raw_ostream &OS = Section->getStream();
509
510 writeUleb128(OS, WasmMetadataVersion, "Version");
511
512 if (!SymtabEntries.empty()) {
513 SubSection Sub(WASM_SYMBOL_TABLE);
514 writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols");
515
516 for (const Symbol *Sym : SymtabEntries) {
517 assert(Sym->isDefined() || Sym->isUndefined());
518 WasmSymbolType Kind = Sym->getWasmType();
519 uint32_t Flags = getWasmFlags(Sym);
520
521 writeU8(Sub.OS, Kind, "sym kind");
522 writeUleb128(Sub.OS, Flags, "sym flags");
523
524 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
525 writeUleb128(Sub.OS, F->getFunctionIndex(), "index");
526 if (Sym->isDefined() ||
527 (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
528 writeStr(Sub.OS, Sym->getName(), "sym name");
529 } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {
530 writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
531 if (Sym->isDefined() ||
532 (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
533 writeStr(Sub.OS, Sym->getName(), "sym name");
534 } else if (auto *E = dyn_cast<EventSymbol>(Sym)) {
535 writeUleb128(Sub.OS, E->getEventIndex(), "index");
536 if (Sym->isDefined() ||
537 (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
538 writeStr(Sub.OS, Sym->getName(), "sym name");
539 } else if (isa<DataSymbol>(Sym)) {
540 writeStr(Sub.OS, Sym->getName(), "sym name");
541 if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
542 writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index");
543 writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(),
544 "data offset");
545 writeUleb128(Sub.OS, DataSym->getSize(), "data size");
546 }
547 } else {
548 auto *S = cast<SectionSymbol>(Sym);
549 writeUleb128(Sub.OS, S->getOutputSectionIndex(), "sym section index");
550 }
551 }
552
553 Sub.writeTo(OS);
554 }
555
556 if (Segments.size()) {
557 SubSection Sub(WASM_SEGMENT_INFO);
558 writeUleb128(Sub.OS, Segments.size(), "num data segments");
559 for (const OutputSegment *S : Segments) {
560 writeStr(Sub.OS, S->Name, "segment name");
561 writeUleb128(Sub.OS, S->Alignment, "alignment");
562 writeUleb128(Sub.OS, 0, "flags");
563 }
564 Sub.writeTo(OS);
565 }
566
567 if (!InitFunctions.empty()) {
568 SubSection Sub(WASM_INIT_FUNCS);
569 writeUleb128(Sub.OS, InitFunctions.size(), "num init functions");
570 for (const WasmInitEntry &F : InitFunctions) {
571 writeUleb128(Sub.OS, F.Priority, "priority");
572 writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index");
573 }
574 Sub.writeTo(OS);
575 }
576
577 struct ComdatEntry {
578 unsigned Kind;
579 uint32_t Index;
580 };
581 std::map<StringRef, std::vector<ComdatEntry>> Comdats;
582
583 for (const InputFunction *F : InputFunctions) {
584 StringRef Comdat = F->getComdatName();
585 if (!Comdat.empty())
586 Comdats[Comdat].emplace_back(
587 ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()});
588 }
589 for (uint32_t I = 0; I < Segments.size(); ++I) {
590 const auto &InputSegments = Segments[I]->InputSegments;
591 if (InputSegments.empty())
592 continue;
593 StringRef Comdat = InputSegments[0]->getComdatName();
594#ifndef NDEBUG
595 for (const InputSegment *IS : InputSegments)
596 assert(IS->getComdatName() == Comdat);
597#endif
598 if (!Comdat.empty())
599 Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I});
600 }
601
602 if (!Comdats.empty()) {
603 SubSection Sub(WASM_COMDAT_INFO);
604 writeUleb128(Sub.OS, Comdats.size(), "num comdats");
605 for (const auto &C : Comdats) {
606 writeStr(Sub.OS, C.first, "comdat name");
607 writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use
608 writeUleb128(Sub.OS, C.second.size(), "num entries");
609 for (const ComdatEntry &Entry : C.second) {
610 writeU8(Sub.OS, Entry.Kind, "entry kind");
611 writeUleb128(Sub.OS, Entry.Index, "entry index");
612 }
613 }
614 Sub.writeTo(OS);
615 }
616}
617
618// Create the custom "name" section containing debug symbol names.
619void Writer::createNameSection() {
620 unsigned NumNames = NumImportedFunctions;
621 for (const InputFunction *F : InputFunctions)
622 if (!F->getName().empty() || !F->getDebugName().empty())
623 ++NumNames;
624
625 if (NumNames == 0)
626 return;
627
628 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name");
629
630 SubSection Sub(WASM_NAMES_FUNCTION);
631 writeUleb128(Sub.OS, NumNames, "name count");
632
633 // Names must appear in function index order. As it happens ImportedSymbols
634 // and InputFunctions are numbered in order with imported functions coming
635 // first.
636 for (const Symbol *S : ImportedSymbols) {
637 if (auto *F = dyn_cast<FunctionSymbol>(S)) {
638 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
639 writeStr(Sub.OS, toString(*S), "symbol name");
640 }
641 }
642 for (const InputFunction *F : InputFunctions) {
643 if (!F->getName().empty()) {
644 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
645 if (!F->getDebugName().empty()) {
646 writeStr(Sub.OS, F->getDebugName(), "symbol name");
647 } else {
648 writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name");
649 }
650 }
651 }
652
653 Sub.writeTo(Section->getStream());
654177}
655178
656179void Writer::writeHeader() {
657 memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
180 memcpy(buffer->getBufferStart(), header.data(), header.size());
658181}
659182
660183void Writer::writeSections() {
661 uint8_t *Buf = Buffer->getBufferStart();
662 parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); });
184 uint8_t *buf = buffer->getBufferStart();
185 parallelForEach(outputSections, [buf](OutputSection *s) {
186 assert(s->isNeeded());
187 s->writeTo(buf);
188 });
663189}
664190
665191// Fix the memory layout of the output binary. This assigns memory offsets
666192// to each of the input data sections as well as the explicit stack region.
667193// The default memory layout is as follows, from low to high.
668194//
669// - initialized data (starting at Config->GlobalBase)
195// - initialized data (starting at Config->globalBase)
670196// - BSS data (not currently implemented in llvm)
671197// - explicit stack (Config->ZStackSize)
672198// - heap start / unallocated
......@@ -676,264 +202,349 @@ void Writer::writeSections() {
676202// rather than overwriting global data, but also increases code size since all
677203// static data loads and stores requires larger offsets.
678204void Writer::layoutMemory() {
679 createOutputSegments();
205 uint32_t memoryPtr = 0;
680206
681 uint32_t MemoryPtr = 0;
682
683 auto PlaceStack = [&]() {
684 if (Config->Relocatable || Config->Shared)
207 auto placeStack = [&]() {
208 if (config->relocatable || config->isPic)
685209 return;
686 MemoryPtr = alignTo(MemoryPtr, StackAlignment);
687 if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment))
688 error("stack size must be " + Twine(StackAlignment) + "-byte aligned");
689 log("mem: stack size = " + Twine(Config->ZStackSize));
690 log("mem: stack base = " + Twine(MemoryPtr));
691 MemoryPtr += Config->ZStackSize;
692 auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer);
693 SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
694 log("mem: stack top = " + Twine(MemoryPtr));
210 memoryPtr = alignTo(memoryPtr, stackAlignment);
211 if (config->zStackSize != alignTo(config->zStackSize, stackAlignment))
212 error("stack size must be " + Twine(stackAlignment) + "-byte aligned");
213 log("mem: stack size = " + Twine(config->zStackSize));
214 log("mem: stack base = " + Twine(memoryPtr));
215 memoryPtr += config->zStackSize;
216 auto *sp = cast<DefinedGlobal>(WasmSym::stackPointer);
217 sp->global->global.InitExpr.Value.Int32 = memoryPtr;
218 log("mem: stack top = " + Twine(memoryPtr));
695219 };
696220
697 if (Config->StackFirst) {
698 PlaceStack();
221 if (config->stackFirst) {
222 placeStack();
699223 } else {
700 MemoryPtr = Config->GlobalBase;
701 log("mem: global base = " + Twine(Config->GlobalBase));
224 memoryPtr = config->globalBase;
225 log("mem: global base = " + Twine(config->globalBase));
702226 }
703227
704 uint32_t DataStart = MemoryPtr;
228 if (WasmSym::globalBase)
229 WasmSym::globalBase->setVirtualAddress(config->globalBase);
230
231 uint32_t dataStart = memoryPtr;
705232
706233 // Arbitrarily set __dso_handle handle to point to the start of the data
707234 // segments.
708 if (WasmSym::DsoHandle)
709 WasmSym::DsoHandle->setVirtualAddress(DataStart);
710
711 MemAlign = 0;
712 for (OutputSegment *Seg : Segments) {
713 MemAlign = std::max(MemAlign, Seg->Alignment);
714 MemoryPtr = alignTo(MemoryPtr, 1 << Seg->Alignment);
715 Seg->StartVA = MemoryPtr;
716 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
717 MemoryPtr, Seg->Size, Seg->Alignment));
718 MemoryPtr += Seg->Size;
235 if (WasmSym::dsoHandle)
236 WasmSym::dsoHandle->setVirtualAddress(dataStart);
237
238 out.dylinkSec->memAlign = 0;
239 for (OutputSegment *seg : segments) {
240 out.dylinkSec->memAlign = std::max(out.dylinkSec->memAlign, seg->alignment);
241 memoryPtr = alignTo(memoryPtr, 1ULL << seg->alignment);
242 seg->startVA = memoryPtr;
243 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", seg->name,
244 memoryPtr, seg->size, seg->alignment));
245 memoryPtr += seg->size;
246
247 if (WasmSym::tlsSize && seg->name == ".tdata") {
248 auto *tlsSize = cast<DefinedGlobal>(WasmSym::tlsSize);
249 tlsSize->global->global.InitExpr.Value.Int32 = seg->size;
250 }
719251 }
720252
721253 // TODO: Add .bss space here.
722 if (WasmSym::DataEnd)
723 WasmSym::DataEnd->setVirtualAddress(MemoryPtr);
254 if (WasmSym::dataEnd)
255 WasmSym::dataEnd->setVirtualAddress(memoryPtr);
724256
725 log("mem: static data = " + Twine(MemoryPtr - DataStart));
257 log("mem: static data = " + Twine(memoryPtr - dataStart));
726258
727 if (Config->Shared) {
728 MemSize = MemoryPtr;
259 if (config->shared) {
260 out.dylinkSec->memSize = memoryPtr;
729261 return;
730262 }
731263
732 if (!Config->StackFirst)
733 PlaceStack();
264 if (!config->stackFirst)
265 placeStack();
734266
735267 // Set `__heap_base` to directly follow the end of the stack or global data.
736268 // The fact that this comes last means that a malloc/brk implementation
737269 // can grow the heap at runtime.
738 if (!Config->Relocatable) {
739 WasmSym::HeapBase->setVirtualAddress(MemoryPtr);
740 log("mem: heap base = " + Twine(MemoryPtr));
741 }
270 log("mem: heap base = " + Twine(memoryPtr));
271 if (WasmSym::heapBase)
272 WasmSym::heapBase->setVirtualAddress(memoryPtr);
742273
743 if (Config->InitialMemory != 0) {
744 if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize))
274 if (config->initialMemory != 0) {
275 if (config->initialMemory != alignTo(config->initialMemory, WasmPageSize))
745276 error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
746 if (MemoryPtr > Config->InitialMemory)
747 error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed");
277 if (memoryPtr > config->initialMemory)
278 error("initial memory too small, " + Twine(memoryPtr) + " bytes needed");
748279 else
749 MemoryPtr = Config->InitialMemory;
280 memoryPtr = config->initialMemory;
750281 }
751 MemSize = MemoryPtr;
752 NumMemoryPages = alignTo(MemoryPtr, WasmPageSize) / WasmPageSize;
753 log("mem: total pages = " + Twine(NumMemoryPages));
282 out.dylinkSec->memSize = memoryPtr;
283 out.memorySec->numMemoryPages =
284 alignTo(memoryPtr, WasmPageSize) / WasmPageSize;
285 log("mem: total pages = " + Twine(out.memorySec->numMemoryPages));
754286
755 if (Config->MaxMemory != 0) {
756 if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize))
287 // Check max if explicitly supplied or required by shared memory
288 if (config->maxMemory != 0 || config->sharedMemory) {
289 if (config->maxMemory != alignTo(config->maxMemory, WasmPageSize))
757290 error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
758 if (MemoryPtr > Config->MaxMemory)
759 error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed");
760 MaxMemoryPages = Config->MaxMemory / WasmPageSize;
761 log("mem: max pages = " + Twine(MaxMemoryPages));
291 if (memoryPtr > config->maxMemory)
292 error("maximum memory too small, " + Twine(memoryPtr) + " bytes needed");
293 out.memorySec->maxMemoryPages = config->maxMemory / WasmPageSize;
294 log("mem: max pages = " + Twine(out.memorySec->maxMemoryPages));
762295 }
763296}
764297
765SyntheticSection *Writer::createSyntheticSection(uint32_t Type,
766 StringRef Name) {
767 auto Sec = make<SyntheticSection>(Type, Name);
768 log("createSection: " + toString(*Sec));
769 OutputSections.push_back(Sec);
770 return Sec;
771}
298void Writer::addSection(OutputSection *sec) {
299 if (!sec->isNeeded())
300 return;
301 log("addSection: " + toString(*sec));
302 sec->sectionIndex = outputSections.size();
303 outputSections.push_back(sec);
304}
305
306// If a section name is valid as a C identifier (which is rare because of
307// the leading '.'), linkers are expected to define __start_<secname> and
308// __stop_<secname> symbols. They are at beginning and end of the section,
309// respectively. This is not requested by the ELF standard, but GNU ld and
310// gold provide the feature, and used by many programs.
311static void addStartStopSymbols(const OutputSegment *seg) {
312 StringRef name = seg->name;
313 if (!isValidCIdentifier(name))
314 return;
315 LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << name << "\n");
316 uint32_t start = seg->startVA;
317 uint32_t stop = start + seg->size;
318 symtab->addOptionalDataSymbol(saver.save("__start_" + name), start);
319 symtab->addOptionalDataSymbol(saver.save("__stop_" + name), stop);
320}
321
322void Writer::addSections() {
323 addSection(out.dylinkSec);
324 addSection(out.typeSec);
325 addSection(out.importSec);
326 addSection(out.functionSec);
327 addSection(out.tableSec);
328 addSection(out.memorySec);
329 addSection(out.globalSec);
330 addSection(out.eventSec);
331 addSection(out.exportSec);
332 addSection(out.elemSec);
333 addSection(out.dataCountSec);
334
335 addSection(make<CodeSection>(out.functionSec->inputFunctions));
336 addSection(make<DataSection>(segments));
772337
773void Writer::createSections() {
774 // Known sections
775 if (Config->Pic)
776 createDylinkSection();
777 createTypeSection();
778 createImportSection();
779 createFunctionSection();
780 createTableSection();
781 createMemorySection();
782 createGlobalSection();
783 createEventSection();
784 createExportSection();
785 createElemSection();
786 createCodeSection();
787 createDataSection();
788338 createCustomSections();
789339
790 // Custom sections
791 if (Config->Relocatable) {
792 createLinkingSection();
340 addSection(out.linkingSec);
341 if (config->emitRelocs || config->relocatable) {
793342 createRelocSections();
794343 }
795 if (!Config->StripDebug && !Config->StripAll)
796 createNameSection();
797344
798 for (OutputSection *S : OutputSections) {
799 S->setOffset(FileSize);
800 S->finalizeContents();
801 FileSize += S->getSize();
345 addSection(out.nameSec);
346 addSection(out.producersSec);
347 addSection(out.targetFeaturesSec);
348}
349
350void Writer::finalizeSections() {
351 for (OutputSection *s : outputSections) {
352 s->setOffset(fileSize);
353 s->finalizeContents();
354 fileSize += s->getSize();
355 }
356}
357
358void Writer::populateTargetFeatures() {
359 StringMap<std::string> used;
360 StringMap<std::string> required;
361 StringMap<std::string> disallowed;
362 bool tlsUsed = false;
363
364 // Only infer used features if user did not specify features
365 bool inferFeatures = !config->features.hasValue();
366
367 if (!inferFeatures) {
368 for (auto &feature : config->features.getValue())
369 out.targetFeaturesSec->features.insert(feature);
370 // No need to read or check features
371 if (!config->checkFeatures)
372 return;
373 }
374
375 // Find the sets of used, required, and disallowed features
376 for (ObjFile *file : symtab->objectFiles) {
377 StringRef fileName(file->getName());
378 for (auto &feature : file->getWasmObj()->getTargetFeatures()) {
379 switch (feature.Prefix) {
380 case WASM_FEATURE_PREFIX_USED:
381 used.insert({feature.Name, fileName});
382 break;
383 case WASM_FEATURE_PREFIX_REQUIRED:
384 used.insert({feature.Name, fileName});
385 required.insert({feature.Name, fileName});
386 break;
387 case WASM_FEATURE_PREFIX_DISALLOWED:
388 disallowed.insert({feature.Name, fileName});
389 break;
390 default:
391 error("Unrecognized feature policy prefix " +
392 std::to_string(feature.Prefix));
393 }
394 }
395
396 for (InputSegment *segment : file->segments) {
397 if (!segment->live)
398 continue;
399 StringRef name = segment->getName();
400 if (name.startswith(".tdata") || name.startswith(".tbss"))
401 tlsUsed = true;
402 }
403 }
404
405 if (inferFeatures)
406 out.targetFeaturesSec->features.insert(used.keys().begin(),
407 used.keys().end());
408
409 if (out.targetFeaturesSec->features.count("atomics") &&
410 !config->sharedMemory) {
411 if (inferFeatures)
412 error(Twine("'atomics' feature is used by ") + used["atomics"] +
413 ", so --shared-memory must be used");
414 else
415 error("'atomics' feature is used, so --shared-memory must be used");
416 }
417
418 if (!config->checkFeatures)
419 return;
420
421 if (disallowed.count("atomics") && config->sharedMemory)
422 error("'atomics' feature is disallowed by " + disallowed["atomics"] +
423 ", so --shared-memory must not be used");
424
425 if (!used.count("bulk-memory") && config->passiveSegments)
426 error("'bulk-memory' feature must be used in order to emit passive "
427 "segments");
428
429 if (!used.count("bulk-memory") && tlsUsed)
430 error("'bulk-memory' feature must be used in order to use thread-local "
431 "storage");
432
433 // Validate that used features are allowed in output
434 if (!inferFeatures) {
435 for (auto &feature : used.keys()) {
436 if (!out.targetFeaturesSec->features.count(feature))
437 error(Twine("Target feature '") + feature + "' used by " +
438 used[feature] + " is not allowed.");
439 }
440 }
441
442 // Validate the required and disallowed constraints for each file
443 for (ObjFile *file : symtab->objectFiles) {
444 StringRef fileName(file->getName());
445 SmallSet<std::string, 8> objectFeatures;
446 for (auto &feature : file->getWasmObj()->getTargetFeatures()) {
447 if (feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED)
448 continue;
449 objectFeatures.insert(feature.Name);
450 if (disallowed.count(feature.Name))
451 error(Twine("Target feature '") + feature.Name + "' used in " +
452 fileName + " is disallowed by " + disallowed[feature.Name] +
453 ". Use --no-check-features to suppress.");
454 }
455 for (auto &feature : required.keys()) {
456 if (!objectFeatures.count(feature))
457 error(Twine("Missing target feature '") + feature + "' in " + fileName +
458 ", required by " + required[feature] +
459 ". Use --no-check-features to suppress.");
460 }
802461 }
803462}
804463
805464void Writer::calculateImports() {
806 for (Symbol *Sym : Symtab->getSymbols()) {
807 if (!Sym->isUndefined())
465 for (Symbol *sym : symtab->getSymbols()) {
466 if (!sym->isUndefined())
808467 continue;
809 if (isa<DataSymbol>(Sym))
468 if (sym->isWeak() && !config->relocatable)
810469 continue;
811 if (Sym->isWeak() && !Config->Relocatable)
470 if (!sym->isLive())
812471 continue;
813 if (!Sym->isLive())
472 if (!sym->isUsedInRegularObj)
814473 continue;
815 if (!Sym->IsUsedInRegularObj)
474 // We don't generate imports for data symbols. They however can be imported
475 // as GOT entries.
476 if (isa<DataSymbol>(sym))
816477 continue;
817478
818 LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
819 ImportedSymbols.emplace_back(Sym);
820 if (auto *F = dyn_cast<FunctionSymbol>(Sym))
821 F->setFunctionIndex(NumImportedFunctions++);
822 else if (auto *G = dyn_cast<GlobalSymbol>(Sym))
823 G->setGlobalIndex(NumImportedGlobals++);
824 else
825 cast<EventSymbol>(Sym)->setEventIndex(NumImportedEvents++);
479 LLVM_DEBUG(dbgs() << "import: " << sym->getName() << "\n");
480 out.importSec->addImport(sym);
826481 }
827482}
828483
829484void Writer::calculateExports() {
830 if (Config->Relocatable)
485 if (config->relocatable)
831486 return;
832487
833 if (!Config->Relocatable && !Config->ImportMemory)
834 Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
488 if (!config->relocatable && !config->importMemory)
489 out.exportSec->exports.push_back(
490 WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
835491
836 if (!Config->Relocatable && Config->ExportTable)
837 Exports.push_back(WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0});
492 if (!config->relocatable && config->exportTable)
493 out.exportSec->exports.push_back(
494 WasmExport{functionTableName, WASM_EXTERNAL_TABLE, 0});
838495
839 unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
496 unsigned fakeGlobalIndex = out.importSec->getNumImportedGlobals() +
497 out.globalSec->inputGlobals.size();
840498
841 for (Symbol *Sym : Symtab->getSymbols()) {
842 if (!Sym->isExported())
499 for (Symbol *sym : symtab->getSymbols()) {
500 if (!sym->isExported())
843501 continue;
844 if (!Sym->isLive())
502 if (!sym->isLive())
845503 continue;
846504
847 StringRef Name = Sym->getName();
848 WasmExport Export;
849 if (auto *F = dyn_cast<DefinedFunction>(Sym)) {
850 Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
851 } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
505 StringRef name = sym->getName();
506 WasmExport export_;
507 if (auto *f = dyn_cast<DefinedFunction>(sym)) {
508 export_ = {name, WASM_EXTERNAL_FUNCTION, f->getFunctionIndex()};
509 } else if (auto *g = dyn_cast<DefinedGlobal>(sym)) {
852510 // TODO(sbc): Remove this check once to mutable global proposal is
853511 // implement in all major browsers.
854512 // See: https://github.com/WebAssembly/mutable-global
855 if (G->getGlobalType()->Mutable) {
856 // Only the __stack_pointer should ever be create as mutable.
857 assert(G == WasmSym::StackPointer);
513 if (g->getGlobalType()->Mutable) {
514 // Only __stack_pointer and __tls_base should ever be create as mutable.
515 assert(g == WasmSym::stackPointer || g == WasmSym::tlsBase);
858516 continue;
859517 }
860 Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
861 } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) {
862 Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()};
518 export_ = {name, WASM_EXTERNAL_GLOBAL, g->getGlobalIndex()};
519 } else if (auto *e = dyn_cast<DefinedEvent>(sym)) {
520 export_ = {name, WASM_EXTERNAL_EVENT, e->getEventIndex()};
863521 } else {
864 auto *D = cast<DefinedData>(Sym);
865 DefinedFakeGlobals.emplace_back(D);
866 Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++};
522 auto *d = cast<DefinedData>(sym);
523 out.globalSec->definedFakeGlobals.emplace_back(d);
524 export_ = {name, WASM_EXTERNAL_GLOBAL, fakeGlobalIndex++};
867525 }
868526
869 LLVM_DEBUG(dbgs() << "Export: " << Name << "\n");
870 Exports.push_back(Export);
527 LLVM_DEBUG(dbgs() << "Export: " << name << "\n");
528 out.exportSec->exports.push_back(export_);
871529 }
872530}
873531
874void Writer::assignSymtab() {
875 if (!Config->Relocatable)
532void Writer::populateSymtab() {
533 if (!config->relocatable && !config->emitRelocs)
876534 return;
877535
878 StringMap<uint32_t> SectionSymbolIndices;
879
880 unsigned SymbolIndex = SymtabEntries.size();
881
882 auto AddSymbol = [&](Symbol *Sym) {
883 if (auto *S = dyn_cast<SectionSymbol>(Sym)) {
884 StringRef Name = S->getName();
885 if (CustomSectionMapping.count(Name) == 0)
886 return;
887
888 auto SSI = SectionSymbolIndices.find(Name);
889 if (SSI != SectionSymbolIndices.end()) {
890 Sym->setOutputSymbolIndex(SSI->second);
891 return;
892 }
893
894 SectionSymbolIndices[Name] = SymbolIndex;
895 CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym);
896
897 Sym->markLive();
898 }
899
900 // (Since this is relocatable output, GC is not performed so symbols must
901 // be live.)
902 assert(Sym->isLive());
903 Sym->setOutputSymbolIndex(SymbolIndex++);
904 SymtabEntries.emplace_back(Sym);
905 };
906
907 for (Symbol *Sym : Symtab->getSymbols())
908 if (!Sym->isLazy())
909 AddSymbol(Sym);
536 for (Symbol *sym : symtab->getSymbols())
537 if (sym->isUsedInRegularObj && sym->isLive())
538 out.linkingSec->addToSymtab(sym);
910539
911 for (ObjFile *File : Symtab->ObjectFiles) {
912 LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n");
913 for (Symbol *Sym : File->getSymbols())
914 if (Sym->isLocal())
915 AddSymbol(Sym);
540 for (ObjFile *file : symtab->objectFiles) {
541 LLVM_DEBUG(dbgs() << "Local symtab entries: " << file->getName() << "\n");
542 for (Symbol *sym : file->getSymbols())
543 if (sym->isLocal() && !isa<SectionSymbol>(sym) && sym->isLive())
544 out.linkingSec->addToSymtab(sym);
916545 }
917546}
918547
919uint32_t Writer::lookupType(const WasmSignature &Sig) {
920 auto It = TypeIndices.find(Sig);
921 if (It == TypeIndices.end()) {
922 error("type not found: " + toString(Sig));
923 return 0;
924 }
925 return It->second;
926}
927
928uint32_t Writer::registerType(const WasmSignature &Sig) {
929 auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size()));
930 if (Pair.second) {
931 LLVM_DEBUG(dbgs() << "type " << toString(Sig) << "\n");
932 Types.push_back(&Sig);
933 }
934 return Pair.first->second;
935}
936
937548void Writer::calculateTypes() {
938549 // The output type section is the union of the following sets:
939550 // 1. Any signature used in the TYPE relocation
......@@ -942,244 +553,383 @@ void Writer::calculateTypes() {
942553 // 4. The signatures of all imported events
943554 // 5. The signatures of all defined events
944555
945 for (ObjFile *File : Symtab->ObjectFiles) {
946 ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
947 for (uint32_t I = 0; I < Types.size(); I++)
948 if (File->TypeIsUsed[I])
949 File->TypeMap[I] = registerType(Types[I]);
556 for (ObjFile *file : symtab->objectFiles) {
557 ArrayRef<WasmSignature> types = file->getWasmObj()->types();
558 for (uint32_t i = 0; i < types.size(); i++)
559 if (file->typeIsUsed[i])
560 file->typeMap[i] = out.typeSec->registerType(types[i]);
950561 }
951562
952 for (const Symbol *Sym : ImportedSymbols) {
953 if (auto *F = dyn_cast<FunctionSymbol>(Sym))
954 registerType(*F->Signature);
955 else if (auto *E = dyn_cast<EventSymbol>(Sym))
956 registerType(*E->Signature);
563 for (const Symbol *sym : out.importSec->importedSymbols) {
564 if (auto *f = dyn_cast<FunctionSymbol>(sym))
565 out.typeSec->registerType(*f->signature);
566 else if (auto *e = dyn_cast<EventSymbol>(sym))
567 out.typeSec->registerType(*e->signature);
957568 }
958569
959 for (const InputFunction *F : InputFunctions)
960 registerType(F->Signature);
570 for (const InputFunction *f : out.functionSec->inputFunctions)
571 out.typeSec->registerType(f->signature);
961572
962 for (const InputEvent *E : InputEvents)
963 registerType(E->Signature);
573 for (const InputEvent *e : out.eventSec->inputEvents)
574 out.typeSec->registerType(e->signature);
964575}
965576
966void Writer::assignIndexes() {
967 assert(InputFunctions.empty());
968 uint32_t FunctionIndex = NumImportedFunctions;
969 auto AddDefinedFunction = [&](InputFunction *Func) {
970 if (!Func->Live)
971 return;
972 InputFunctions.emplace_back(Func);
973 Func->setFunctionIndex(FunctionIndex++);
974 };
975
976 for (InputFunction *Func : Symtab->SyntheticFunctions)
977 AddDefinedFunction(Func);
978
979 for (ObjFile *File : Symtab->ObjectFiles) {
980 LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
981 for (InputFunction *Func : File->Functions)
982 AddDefinedFunction(Func);
577static void scanRelocations() {
578 for (ObjFile *file : symtab->objectFiles) {
579 LLVM_DEBUG(dbgs() << "scanRelocations: " << file->getName() << "\n");
580 for (InputChunk *chunk : file->functions)
581 scanRelocations(chunk);
582 for (InputChunk *chunk : file->segments)
583 scanRelocations(chunk);
584 for (auto &p : file->customSections)
585 scanRelocations(p);
983586 }
587}
984588
985 uint32_t TableIndex = TableBase;
986 auto HandleRelocs = [&](InputChunk *Chunk) {
987 if (!Chunk->Live)
988 return;
989 ObjFile *File = Chunk->File;
990 ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
991 for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
992 if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
993 Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
994 FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
995 if (Sym->hasTableIndex() || !Sym->hasFunctionIndex())
996 continue;
997 Sym->setTableIndex(TableIndex++);
998 IndirectFunctions.emplace_back(Sym);
999 } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
1000 // Mark target type as live
1001 File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
1002 File->TypeIsUsed[Reloc.Index] = true;
1003 }
1004 }
1005 };
589void Writer::assignIndexes() {
590 // Seal the import section, since other index spaces such as function and
591 // global are effected by the number of imports.
592 out.importSec->seal();
1006593
1007 for (ObjFile *File : Symtab->ObjectFiles) {
1008 LLVM_DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
1009 for (InputChunk *Chunk : File->Functions)
1010 HandleRelocs(Chunk);
1011 for (InputChunk *Chunk : File->Segments)
1012 HandleRelocs(Chunk);
1013 for (auto &P : File->CustomSections)
1014 HandleRelocs(P);
1015 }
594 for (InputFunction *func : symtab->syntheticFunctions)
595 out.functionSec->addFunction(func);
1016596
1017 assert(InputGlobals.empty());
1018 uint32_t GlobalIndex = NumImportedGlobals;
1019 auto AddDefinedGlobal = [&](InputGlobal *Global) {
1020 if (Global->Live) {
1021 LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
1022 Global->setGlobalIndex(GlobalIndex++);
1023 InputGlobals.push_back(Global);
1024 }
1025 };
597 for (ObjFile *file : symtab->objectFiles) {
598 LLVM_DEBUG(dbgs() << "Functions: " << file->getName() << "\n");
599 for (InputFunction *func : file->functions)
600 out.functionSec->addFunction(func);
601 }
1026602
1027 for (InputGlobal *Global : Symtab->SyntheticGlobals)
1028 AddDefinedGlobal(Global);
603 for (InputGlobal *global : symtab->syntheticGlobals)
604 out.globalSec->addGlobal(global);
1029605
1030 for (ObjFile *File : Symtab->ObjectFiles) {
1031 LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
1032 for (InputGlobal *Global : File->Globals)
1033 AddDefinedGlobal(Global);
606 for (ObjFile *file : symtab->objectFiles) {
607 LLVM_DEBUG(dbgs() << "Globals: " << file->getName() << "\n");
608 for (InputGlobal *global : file->globals)
609 out.globalSec->addGlobal(global);
1034610 }
1035611
1036 assert(InputEvents.empty());
1037 uint32_t EventIndex = NumImportedEvents;
1038 auto AddDefinedEvent = [&](InputEvent *Event) {
1039 if (Event->Live) {
1040 LLVM_DEBUG(dbgs() << "AddDefinedEvent: " << EventIndex << "\n");
1041 Event->setEventIndex(EventIndex++);
1042 InputEvents.push_back(Event);
1043 }
1044 };
1045
1046 for (ObjFile *File : Symtab->ObjectFiles) {
1047 LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n");
1048 for (InputEvent *Event : File->Events)
1049 AddDefinedEvent(Event);
612 for (ObjFile *file : symtab->objectFiles) {
613 LLVM_DEBUG(dbgs() << "Events: " << file->getName() << "\n");
614 for (InputEvent *event : file->events)
615 out.eventSec->addEvent(event);
1050616 }
1051617}
1052618
1053static StringRef getOutputDataSegmentName(StringRef Name) {
619static StringRef getOutputDataSegmentName(StringRef name) {
1054620 // With PIC code we currently only support a single data segment since
1055621 // we only have a single __memory_base to use as our base address.
1056 if (Config->Pic)
1057 return "data";
1058 if (!Config->MergeDataSegments)
1059 return Name;
1060 if (Name.startswith(".text."))
622 if (config->isPic)
623 return ".data";
624 // We only support one thread-local segment, so we must merge the segments
625 // despite --no-merge-data-segments.
626 // We also need to merge .tbss into .tdata so they share the same offsets.
627 if (name.startswith(".tdata") || name.startswith(".tbss"))
628 return ".tdata";
629 if (!config->mergeDataSegments)
630 return name;
631 if (name.startswith(".text."))
1061632 return ".text";
1062 if (Name.startswith(".data."))
633 if (name.startswith(".data."))
1063634 return ".data";
1064 if (Name.startswith(".bss."))
635 if (name.startswith(".bss."))
1065636 return ".bss";
1066 if (Name.startswith(".rodata."))
637 if (name.startswith(".rodata."))
1067638 return ".rodata";
1068 return Name;
639 return name;
1069640}
1070641
1071642void Writer::createOutputSegments() {
1072 for (ObjFile *File : Symtab->ObjectFiles) {
1073 for (InputSegment *Segment : File->Segments) {
1074 if (!Segment->Live)
643 for (ObjFile *file : symtab->objectFiles) {
644 for (InputSegment *segment : file->segments) {
645 if (!segment->live)
1075646 continue;
1076 StringRef Name = getOutputDataSegmentName(Segment->getName());
1077 OutputSegment *&S = SegmentMap[Name];
1078 if (S == nullptr) {
1079 LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n");
1080 S = make<OutputSegment>(Name, Segments.size());
1081 Segments.push_back(S);
647 StringRef name = getOutputDataSegmentName(segment->getName());
648 OutputSegment *&s = segmentMap[name];
649 if (s == nullptr) {
650 LLVM_DEBUG(dbgs() << "new segment: " << name << "\n");
651 s = make<OutputSegment>(name, segments.size());
652 if (config->passiveSegments || name == ".tdata")
653 s->initFlags = WASM_SEGMENT_IS_PASSIVE;
654 segments.push_back(s);
655 }
656 s->addInputSegment(segment);
657 LLVM_DEBUG(dbgs() << "added data: " << name << ": " << s->size << "\n");
658 }
659 }
660}
661
662static void createFunction(DefinedFunction *func, StringRef bodyContent) {
663 std::string functionBody;
664 {
665 raw_string_ostream os(functionBody);
666 writeUleb128(os, bodyContent.size(), "function size");
667 os << bodyContent;
668 }
669 ArrayRef<uint8_t> body = arrayRefFromStringRef(saver.save(functionBody));
670 cast<SyntheticFunction>(func->function)->setBody(body);
671}
672
673void Writer::createInitMemoryFunction() {
674 LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n");
675 std::string bodyContent;
676 {
677 raw_string_ostream os(bodyContent);
678 writeUleb128(os, 0, "num locals");
679
680 // initialize passive data segments
681 for (const OutputSegment *s : segments) {
682 if (s->initFlags & WASM_SEGMENT_IS_PASSIVE && s->name != ".tdata") {
683 // destination address
684 writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");
685 writeSleb128(os, s->startVA, "destination address");
686 // source segment offset
687 writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");
688 writeSleb128(os, 0, "segment offset");
689 // memory region size
690 writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");
691 writeSleb128(os, s->size, "memory region size");
692 // memory.init instruction
693 writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
694 writeUleb128(os, WASM_OPCODE_MEMORY_INIT, "MEMORY.INIT");
695 writeUleb128(os, s->index, "segment index immediate");
696 writeU8(os, 0, "memory index immediate");
697 // data.drop instruction
698 writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
699 writeUleb128(os, WASM_OPCODE_DATA_DROP, "DATA.DROP");
700 writeUleb128(os, s->index, "segment index immediate");
1082701 }
1083 S->addInputSegment(Segment);
1084 LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
1085702 }
703 writeU8(os, WASM_OPCODE_END, "END");
1086704 }
705
706 createFunction(WasmSym::initMemory, bodyContent);
1087707}
1088708
1089static const int OPCODE_CALL = 0x10;
1090static const int OPCODE_END = 0xb;
709// For -shared (PIC) output, we create create a synthetic function which will
710// apply any relocations to the data segments on startup. This function is
711// called __wasm_apply_relocs and is added at the beginning of __wasm_call_ctors
712// before any of the constructors run.
713void Writer::createApplyRelocationsFunction() {
714 LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n");
715 // First write the body's contents to a string.
716 std::string bodyContent;
717 {
718 raw_string_ostream os(bodyContent);
719 writeUleb128(os, 0, "num locals");
720 for (const OutputSegment *seg : segments)
721 for (const InputSegment *inSeg : seg->inputSegments)
722 inSeg->generateRelocationCode(os);
723 writeU8(os, WASM_OPCODE_END, "END");
724 }
725
726 createFunction(WasmSym::applyRelocs, bodyContent);
727}
1091728
1092729// Create synthetic "__wasm_call_ctors" function based on ctor functions
1093730// in input object.
1094void Writer::createCtorFunction() {
731void Writer::createCallCtorsFunction() {
732 if (!WasmSym::callCtors->isLive())
733 return;
734
1095735 // First write the body's contents to a string.
1096 std::string BodyContent;
736 std::string bodyContent;
1097737 {
1098 raw_string_ostream OS(BodyContent);
1099 writeUleb128(OS, 0, "num locals");
1100 for (const WasmInitEntry &F : InitFunctions) {
1101 writeU8(OS, OPCODE_CALL, "CALL");
1102 writeUleb128(OS, F.Sym->getFunctionIndex(), "function index");
738 raw_string_ostream os(bodyContent);
739 writeUleb128(os, 0, "num locals");
740
741 if (config->passiveSegments) {
742 writeU8(os, WASM_OPCODE_CALL, "CALL");
743 writeUleb128(os, WasmSym::initMemory->getFunctionIndex(),
744 "function index");
745 }
746
747 if (config->isPic) {
748 writeU8(os, WASM_OPCODE_CALL, "CALL");
749 writeUleb128(os, WasmSym::applyRelocs->getFunctionIndex(),
750 "function index");
751 }
752
753 // Call constructors
754 for (const WasmInitEntry &f : initFunctions) {
755 writeU8(os, WASM_OPCODE_CALL, "CALL");
756 writeUleb128(os, f.sym->getFunctionIndex(), "function index");
1103757 }
1104 writeU8(OS, OPCODE_END, "END");
758 writeU8(os, WASM_OPCODE_END, "END");
1105759 }
1106760
1107 // Once we know the size of the body we can create the final function body
1108 std::string FunctionBody;
761 createFunction(WasmSym::callCtors, bodyContent);
762}
763
764void Writer::createInitTLSFunction() {
765 if (!WasmSym::initTLS->isLive())
766 return;
767
768 std::string bodyContent;
1109769 {
1110 raw_string_ostream OS(FunctionBody);
1111 writeUleb128(OS, BodyContent.size(), "function size");
1112 OS << BodyContent;
770 raw_string_ostream os(bodyContent);
771
772 OutputSegment *tlsSeg = nullptr;
773 for (auto *seg : segments) {
774 if (seg->name == ".tdata") {
775 tlsSeg = seg;
776 break;
777 }
778 }
779
780 writeUleb128(os, 0, "num locals");
781 if (tlsSeg) {
782 writeU8(os, WASM_OPCODE_LOCAL_GET, "local.get");
783 writeUleb128(os, 0, "local index");
784
785 writeU8(os, WASM_OPCODE_GLOBAL_SET, "global.set");
786 writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(), "global index");
787
788 writeU8(os, WASM_OPCODE_LOCAL_GET, "local.get");
789 writeUleb128(os, 0, "local index");
790
791 writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");
792 writeSleb128(os, 0, "segment offset");
793
794 writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");
795 writeSleb128(os, tlsSeg->size, "memory region size");
796
797 writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
798 writeUleb128(os, WASM_OPCODE_MEMORY_INIT, "MEMORY.INIT");
799 writeUleb128(os, tlsSeg->index, "segment index immediate");
800 writeU8(os, 0, "memory index immediate");
801 }
802 writeU8(os, WASM_OPCODE_END, "end function");
1113803 }
1114804
1115 ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
1116 cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);
805 createFunction(WasmSym::initTLS, bodyContent);
1117806}
1118807
1119808// Populate InitFunctions vector with init functions from all input objects.
1120809// This is then used either when creating the output linking section or to
1121810// synthesize the "__wasm_call_ctors" function.
1122811void Writer::calculateInitFunctions() {
1123 for (ObjFile *File : Symtab->ObjectFiles) {
1124 const WasmLinkingData &L = File->getWasmObj()->linkingData();
1125 for (const WasmInitFunc &F : L.InitFunctions) {
1126 FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
1127 if (*Sym->Signature != WasmSignature{{}, {}})
1128 error("invalid signature for init func: " + toString(*Sym));
1129 InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
812 if (!config->relocatable && !WasmSym::callCtors->isLive())
813 return;
814
815 for (ObjFile *file : symtab->objectFiles) {
816 const WasmLinkingData &l = file->getWasmObj()->linkingData();
817 for (const WasmInitFunc &f : l.InitFunctions) {
818 FunctionSymbol *sym = file->getFunctionSymbol(f.Symbol);
819 // comdat exclusions can cause init functions be discarded.
820 if (sym->isDiscarded())
821 continue;
822 assert(sym->isLive());
823 if (*sym->signature != WasmSignature{{}, {}})
824 error("invalid signature for init func: " + toString(*sym));
825 LLVM_DEBUG(dbgs() << "initFunctions: " << toString(*sym) << "\n");
826 initFunctions.emplace_back(WasmInitEntry{sym, f.Priority});
1130827 }
1131828 }
1132829
1133830 // Sort in order of priority (lowest first) so that they are called
1134831 // in the correct order.
1135 std::stable_sort(InitFunctions.begin(), InitFunctions.end(),
1136 [](const WasmInitEntry &L, const WasmInitEntry &R) {
1137 return L.Priority < R.Priority;
1138 });
832 llvm::stable_sort(initFunctions,
833 [](const WasmInitEntry &l, const WasmInitEntry &r) {
834 return l.priority < r.priority;
835 });
836}
837
838void Writer::createSyntheticSections() {
839 out.dylinkSec = make<DylinkSection>();
840 out.typeSec = make<TypeSection>();
841 out.importSec = make<ImportSection>();
842 out.functionSec = make<FunctionSection>();
843 out.tableSec = make<TableSection>();
844 out.memorySec = make<MemorySection>();
845 out.globalSec = make<GlobalSection>();
846 out.eventSec = make<EventSection>();
847 out.exportSec = make<ExportSection>();
848 out.elemSec = make<ElemSection>(tableBase);
849 out.dataCountSec = make<DataCountSection>(segments.size());
850 out.linkingSec = make<LinkingSection>(initFunctions, segments);
851 out.nameSec = make<NameSection>();
852 out.producersSec = make<ProducersSection>();
853 out.targetFeaturesSec = make<TargetFeaturesSection>();
1139854}
1140855
1141856void Writer::run() {
1142 if (Config->Relocatable || Config->Pic)
1143 Config->GlobalBase = 0;
857 if (config->relocatable || config->isPic)
858 config->globalBase = 0;
1144859
1145860 // For PIC code the table base is assigned dynamically by the loader.
1146861 // For non-PIC, we start at 1 so that accessing table index 0 always traps.
1147 if (!Config->Pic)
1148 TableBase = 1;
862 if (!config->isPic)
863 tableBase = 1;
1149864
865 log("-- createOutputSegments");
866 createOutputSegments();
867 log("-- createSyntheticSections");
868 createSyntheticSections();
869 log("-- populateProducers");
870 populateProducers();
871 log("-- populateTargetFeatures");
872 populateTargetFeatures();
1150873 log("-- calculateImports");
1151874 calculateImports();
875 log("-- layoutMemory");
876 layoutMemory();
877
878 if (!config->relocatable) {
879 // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols
880 // This has to be done after memory layout is performed.
881 for (const OutputSegment *seg : segments)
882 addStartStopSymbols(seg);
883 }
884
885 log("-- scanRelocations");
886 scanRelocations();
1152887 log("-- assignIndexes");
1153888 assignIndexes();
1154889 log("-- calculateInitFunctions");
1155890 calculateInitFunctions();
1156 if (!Config->Relocatable)
1157 createCtorFunction();
891
892 if (!config->relocatable) {
893 // Create linker synthesized functions
894 if (config->passiveSegments)
895 createInitMemoryFunction();
896 if (config->isPic)
897 createApplyRelocationsFunction();
898 createCallCtorsFunction();
899 }
900
901 if (config->sharedMemory && !config->shared)
902 createInitTLSFunction();
903
904 if (errorCount())
905 return;
906
1158907 log("-- calculateTypes");
1159908 calculateTypes();
1160 log("-- layoutMemory");
1161 layoutMemory();
1162909 log("-- calculateExports");
1163910 calculateExports();
1164911 log("-- calculateCustomSections");
1165912 calculateCustomSections();
1166 log("-- assignSymtab");
1167 assignSymtab();
1168
1169 if (errorHandler().Verbose) {
1170 log("Defined Functions: " + Twine(InputFunctions.size()));
1171 log("Defined Globals : " + Twine(InputGlobals.size()));
1172 log("Defined Events : " + Twine(InputEvents.size()));
1173 log("Function Imports : " + Twine(NumImportedFunctions));
1174 log("Global Imports : " + Twine(NumImportedGlobals));
1175 log("Event Imports : " + Twine(NumImportedEvents));
1176 for (ObjFile *File : Symtab->ObjectFiles)
1177 File->dumpInfo();
913 log("-- populateSymtab");
914 populateSymtab();
915 log("-- addSections");
916 addSections();
917
918 if (errorHandler().verbose) {
919 log("Defined Functions: " + Twine(out.functionSec->inputFunctions.size()));
920 log("Defined Globals : " + Twine(out.globalSec->inputGlobals.size()));
921 log("Defined Events : " + Twine(out.eventSec->inputEvents.size()));
922 log("Function Imports : " +
923 Twine(out.importSec->getNumImportedFunctions()));
924 log("Global Imports : " + Twine(out.importSec->getNumImportedGlobals()));
925 log("Event Imports : " + Twine(out.importSec->getNumImportedEvents()));
926 for (ObjFile *file : symtab->objectFiles)
927 file->dumpInfo();
1178928 }
1179929
1180930 createHeader();
1181 log("-- createSections");
1182 createSections();
931 log("-- finalizeSections");
932 finalizeSections();
1183933
1184934 log("-- openFile");
1185935 openFile();
......@@ -1193,31 +943,31 @@ void Writer::run() {
1193943 if (errorCount())
1194944 return;
1195945
1196 if (Error E = Buffer->commit())
1197 fatal("failed to write the output file: " + toString(std::move(E)));
946 if (Error e = buffer->commit())
947 fatal("failed to write the output file: " + toString(std::move(e)));
1198948}
1199949
1200950// Open a result file.
1201951void Writer::openFile() {
1202 log("writing: " + Config->OutputFile);
952 log("writing: " + config->outputFile);
1203953
1204 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
1205 FileOutputBuffer::create(Config->OutputFile, FileSize,
954 Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
955 FileOutputBuffer::create(config->outputFile, fileSize,
1206956 FileOutputBuffer::F_executable);
1207957
1208 if (!BufferOrErr)
1209 error("failed to open " + Config->OutputFile + ": " +
1210 toString(BufferOrErr.takeError()));
958 if (!bufferOrErr)
959 error("failed to open " + config->outputFile + ": " +
960 toString(bufferOrErr.takeError()));
1211961 else
1212 Buffer = std::move(*BufferOrErr);
962 buffer = std::move(*bufferOrErr);
1213963}
1214964
1215965void Writer::createHeader() {
1216 raw_string_ostream OS(Header);
1217 writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic");
1218 writeU32(OS, WasmVersion, "wasm version");
1219 OS.flush();
1220 FileSize += Header.size();
966 raw_string_ostream os(header);
967 writeBytes(os, WasmMagic, sizeof(WasmMagic), "wasm magic");
968 writeU32(os, WasmVersion, "wasm version");
969 os.flush();
970 fileSize += header.size();
1221971}
1222972
1223973void lld::wasm::writeResult() { Writer().run(); }
deps/lld/wasm/Writer.h+3-6
......@@ -1,9 +1,8 @@
11//===- Writer.h -------------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -15,8 +14,6 @@ namespace wasm {
1514
1615void writeResult();
1716
18extern const char *DefaultModule;
19
2017} // namespace wasm
2118} // namespace lld
2219
deps/lld/wasm/WriterUtils.cpp+104-105
......@@ -1,9 +1,8 @@
11//===- WriterUtils.cpp ----------------------------------------------------===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -20,159 +19,159 @@ using namespace llvm::wasm;
2019
2120namespace lld {
2221
23void wasm::debugWrite(uint64_t Offset, const Twine &Msg) {
24 LLVM_DEBUG(dbgs() << format(" | %08lld: ", Offset) << Msg << "\n");
22void wasm::debugWrite(uint64_t offset, const Twine &msg) {
23 LLVM_DEBUG(dbgs() << format(" | %08lld: ", offset) << msg << "\n");
2524}
2625
27void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
28 debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]");
29 encodeULEB128(Number, OS);
26void wasm::writeUleb128(raw_ostream &os, uint32_t number, const Twine &msg) {
27 debugWrite(os.tell(), msg + "[" + utohexstr(number) + "]");
28 encodeULEB128(number, os);
3029}
3130
32void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg) {
33 debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]");
34 encodeSLEB128(Number, OS);
31void wasm::writeSleb128(raw_ostream &os, int32_t number, const Twine &msg) {
32 debugWrite(os.tell(), msg + "[" + utohexstr(number) + "]");
33 encodeSLEB128(number, os);
3534}
3635
37void wasm::writeBytes(raw_ostream &OS, const char *Bytes, size_t Count,
38 const Twine &Msg) {
39 debugWrite(OS.tell(), Msg + " [data[" + Twine(Count) + "]]");
40 OS.write(Bytes, Count);
36void wasm::writeBytes(raw_ostream &os, const char *bytes, size_t count,
37 const Twine &msg) {
38 debugWrite(os.tell(), msg + " [data[" + Twine(count) + "]]");
39 os.write(bytes, count);
4140}
4241
43void wasm::writeStr(raw_ostream &OS, StringRef String, const Twine &Msg) {
44 debugWrite(OS.tell(),
45 Msg + " [str[" + Twine(String.size()) + "]: " + String + "]");
46 encodeULEB128(String.size(), OS);
47 OS.write(String.data(), String.size());
42void wasm::writeStr(raw_ostream &os, StringRef string, const Twine &msg) {
43 debugWrite(os.tell(),
44 msg + " [str[" + Twine(string.size()) + "]: " + string + "]");
45 encodeULEB128(string.size(), os);
46 os.write(string.data(), string.size());
4847}
4948
50void wasm::writeU8(raw_ostream &OS, uint8_t Byte, const Twine &Msg) {
51 debugWrite(OS.tell(), Msg + " [0x" + utohexstr(Byte) + "]");
52 OS << Byte;
49void wasm::writeU8(raw_ostream &os, uint8_t byte, const Twine &msg) {
50 debugWrite(os.tell(), msg + " [0x" + utohexstr(byte) + "]");
51 os << byte;
5352}
5453
55void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
56 debugWrite(OS.tell(), Msg + "[0x" + utohexstr(Number) + "]");
57 support::endian::write(OS, Number, support::little);
54void wasm::writeU32(raw_ostream &os, uint32_t number, const Twine &msg) {
55 debugWrite(os.tell(), msg + "[0x" + utohexstr(number) + "]");
56 support::endian::write(os, number, support::little);
5857}
5958
60void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) {
61 writeU8(OS, static_cast<uint8_t>(Type),
62 Msg + "[type: " + toString(Type) + "]");
59void wasm::writeValueType(raw_ostream &os, ValType type, const Twine &msg) {
60 writeU8(os, static_cast<uint8_t>(type),
61 msg + "[type: " + toString(type) + "]");
6362}
6463
65void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) {
66 writeU8(OS, WASM_TYPE_FUNC, "signature type");
67 writeUleb128(OS, Sig.Params.size(), "param Count");
68 for (ValType ParamType : Sig.Params) {
69 writeValueType(OS, ParamType, "param type");
64void wasm::writeSig(raw_ostream &os, const WasmSignature &sig) {
65 writeU8(os, WASM_TYPE_FUNC, "signature type");
66 writeUleb128(os, sig.Params.size(), "param Count");
67 for (ValType paramType : sig.Params) {
68 writeValueType(os, paramType, "param type");
7069 }
71 writeUleb128(OS, Sig.Returns.size(), "result Count");
72 if (Sig.Returns.size()) {
73 writeValueType(OS, Sig.Returns[0], "result type");
70 writeUleb128(os, sig.Returns.size(), "result Count");
71 if (sig.Returns.size()) {
72 writeValueType(os, sig.Returns[0], "result type");
7473 }
7574}
7675
77void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) {
78 writeU8(OS, InitExpr.Opcode, "opcode");
79 switch (InitExpr.Opcode) {
76void wasm::writeInitExpr(raw_ostream &os, const WasmInitExpr &initExpr) {
77 writeU8(os, initExpr.Opcode, "opcode");
78 switch (initExpr.Opcode) {
8079 case WASM_OPCODE_I32_CONST:
81 writeSleb128(OS, InitExpr.Value.Int32, "literal (i32)");
80 writeSleb128(os, initExpr.Value.Int32, "literal (i32)");
8281 break;
8382 case WASM_OPCODE_I64_CONST:
84 writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");
83 writeSleb128(os, initExpr.Value.Int64, "literal (i64)");
8584 break;
8685 case WASM_OPCODE_GLOBAL_GET:
87 writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");
86 writeUleb128(os, initExpr.Value.Global, "literal (global index)");
8887 break;
8988 default:
90 fatal("unknown opcode in init expr: " + Twine(InitExpr.Opcode));
89 fatal("unknown opcode in init expr: " + Twine(initExpr.Opcode));
9190 }
92 writeU8(OS, WASM_OPCODE_END, "opcode:end");
91 writeU8(os, WASM_OPCODE_END, "opcode:end");
9392}
9493
95void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) {
96 writeU8(OS, Limits.Flags, "limits flags");
97 writeUleb128(OS, Limits.Initial, "limits initial");
98 if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX)
99 writeUleb128(OS, Limits.Maximum, "limits max");
94void wasm::writeLimits(raw_ostream &os, const WasmLimits &limits) {
95 writeU8(os, limits.Flags, "limits flags");
96 writeUleb128(os, limits.Initial, "limits initial");
97 if (limits.Flags & WASM_LIMITS_FLAG_HAS_MAX)
98 writeUleb128(os, limits.Maximum, "limits max");
10099}
101100
102void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) {
101void wasm::writeGlobalType(raw_ostream &os, const WasmGlobalType &type) {
103102 // TODO: Update WasmGlobalType to use ValType and remove this cast.
104 writeValueType(OS, ValType(Type.Type), "global type");
105 writeU8(OS, Type.Mutable, "global mutable");
103 writeValueType(os, ValType(type.Type), "global type");
104 writeU8(os, type.Mutable, "global mutable");
106105}
107106
108void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) {
109 writeGlobalType(OS, Global.Type);
110 writeInitExpr(OS, Global.InitExpr);
107void wasm::writeGlobal(raw_ostream &os, const WasmGlobal &global) {
108 writeGlobalType(os, global.Type);
109 writeInitExpr(os, global.InitExpr);
111110}
112111
113void wasm::writeEventType(raw_ostream &OS, const WasmEventType &Type) {
114 writeUleb128(OS, Type.Attribute, "event attribute");
115 writeUleb128(OS, Type.SigIndex, "sig index");
112void wasm::writeEventType(raw_ostream &os, const WasmEventType &type) {
113 writeUleb128(os, type.Attribute, "event attribute");
114 writeUleb128(os, type.SigIndex, "sig index");
116115}
117116
118void wasm::writeEvent(raw_ostream &OS, const WasmEvent &Event) {
119 writeEventType(OS, Event.Type);
117void wasm::writeEvent(raw_ostream &os, const WasmEvent &event) {
118 writeEventType(os, event.Type);
120119}
121120
122void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) {
123 writeU8(OS, WASM_TYPE_FUNCREF, "table type");
124 writeLimits(OS, Type.Limits);
121void wasm::writeTableType(raw_ostream &os, const llvm::wasm::WasmTable &type) {
122 writeU8(os, WASM_TYPE_FUNCREF, "table type");
123 writeLimits(os, type.Limits);
125124}
126125
127void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) {
128 writeStr(OS, Import.Module, "import module name");
129 writeStr(OS, Import.Field, "import field name");
130 writeU8(OS, Import.Kind, "import kind");
131 switch (Import.Kind) {
126void wasm::writeImport(raw_ostream &os, const WasmImport &import) {
127 writeStr(os, import.Module, "import module name");
128 writeStr(os, import.Field, "import field name");
129 writeU8(os, import.Kind, "import kind");
130 switch (import.Kind) {
132131 case WASM_EXTERNAL_FUNCTION:
133 writeUleb128(OS, Import.SigIndex, "import sig index");
132 writeUleb128(os, import.SigIndex, "import sig index");
134133 break;
135134 case WASM_EXTERNAL_GLOBAL:
136 writeGlobalType(OS, Import.Global);
135 writeGlobalType(os, import.Global);
137136 break;
138137 case WASM_EXTERNAL_EVENT:
139 writeEventType(OS, Import.Event);
138 writeEventType(os, import.Event);
140139 break;
141140 case WASM_EXTERNAL_MEMORY:
142 writeLimits(OS, Import.Memory);
141 writeLimits(os, import.Memory);
143142 break;
144143 case WASM_EXTERNAL_TABLE:
145 writeTableType(OS, Import.Table);
144 writeTableType(os, import.Table);
146145 break;
147146 default:
148 fatal("unsupported import type: " + Twine(Import.Kind));
147 fatal("unsupported import type: " + Twine(import.Kind));
149148 }
150149}
151150
152void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) {
153 writeStr(OS, Export.Name, "export name");
154 writeU8(OS, Export.Kind, "export kind");
155 switch (Export.Kind) {
151void wasm::writeExport(raw_ostream &os, const WasmExport &export_) {
152 writeStr(os, export_.Name, "export name");
153 writeU8(os, export_.Kind, "export kind");
154 switch (export_.Kind) {
156155 case WASM_EXTERNAL_FUNCTION:
157 writeUleb128(OS, Export.Index, "function index");
156 writeUleb128(os, export_.Index, "function index");
158157 break;
159158 case WASM_EXTERNAL_GLOBAL:
160 writeUleb128(OS, Export.Index, "global index");
159 writeUleb128(os, export_.Index, "global index");
161160 break;
162161 case WASM_EXTERNAL_MEMORY:
163 writeUleb128(OS, Export.Index, "memory index");
162 writeUleb128(os, export_.Index, "memory index");
164163 break;
165164 case WASM_EXTERNAL_TABLE:
166 writeUleb128(OS, Export.Index, "table index");
165 writeUleb128(os, export_.Index, "table index");
167166 break;
168167 default:
169 fatal("unsupported export type: " + Twine(Export.Kind));
168 fatal("unsupported export type: " + Twine(export_.Kind));
170169 }
171170}
172171} // namespace lld
173172
174std::string lld::toString(ValType Type) {
175 switch (Type) {
173std::string lld::toString(ValType type) {
174 switch (type) {
176175 case ValType::I32:
177176 return "i32";
178177 case ValType::I64:
......@@ -183,34 +182,34 @@ std::string lld::toString(ValType Type) {
183182 return "f64";
184183 case ValType::V128:
185184 return "v128";
186 case ValType::EXCEPT_REF:
187 return "except_ref";
185 case ValType::EXNREF:
186 return "exnref";
188187 }
189188 llvm_unreachable("Invalid wasm::ValType");
190189}
191190
192std::string lld::toString(const WasmSignature &Sig) {
193 SmallString<128> S("(");
194 for (ValType Type : Sig.Params) {
195 if (S.size() != 1)
196 S += ", ";
197 S += toString(Type);
191std::string lld::toString(const WasmSignature &sig) {
192 SmallString<128> s("(");
193 for (ValType type : sig.Params) {
194 if (s.size() != 1)
195 s += ", ";
196 s += toString(type);
198197 }
199 S += ") -> ";
200 if (Sig.Returns.size() == 0)
201 S += "void";
198 s += ") -> ";
199 if (sig.Returns.empty())
200 s += "void";
202201 else
203 S += toString(Sig.Returns[0]);
204 return S.str();
202 s += toString(sig.Returns[0]);
203 return s.str();
205204}
206205
207std::string lld::toString(const WasmGlobalType &Type) {
208 return (Type.Mutable ? "var " : "const ") +
209 toString(static_cast<ValType>(Type.Type));
206std::string lld::toString(const WasmGlobalType &type) {
207 return (type.Mutable ? "var " : "const ") +
208 toString(static_cast<ValType>(type.Type));
210209}
211210
212std::string lld::toString(const WasmEventType &Type) {
213 if (Type.Attribute == WASM_EVENT_ATTRIBUTE_EXCEPTION)
211std::string lld::toString(const WasmEventType &type) {
212 if (type.Attribute == WASM_EVENT_ATTRIBUTE_EXCEPTION)
214213 return "exception";
215214 return "unknown";
216215}
deps/lld/wasm/WriterUtils.h+27-28
......@@ -1,9 +1,8 @@
11//===- WriterUtils.h --------------------------------------------*- C++ -*-===//
22//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
76//
87//===----------------------------------------------------------------------===//
98
......@@ -17,50 +16,50 @@
1716namespace lld {
1817namespace wasm {
1918
20void debugWrite(uint64_t Offset, const Twine &Msg);
19void debugWrite(uint64_t offset, const Twine &msg);
2120
22void writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg);
21void writeUleb128(raw_ostream &os, uint32_t number, const Twine &msg);
2322
24void writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg);
23void writeSleb128(raw_ostream &os, int32_t number, const Twine &msg);
2524
26void writeBytes(raw_ostream &OS, const char *Bytes, size_t count,
27 const Twine &Msg);
25void writeBytes(raw_ostream &os, const char *bytes, size_t count,
26 const Twine &msg);
2827
29void writeStr(raw_ostream &OS, StringRef String, const Twine &Msg);
28void writeStr(raw_ostream &os, StringRef string, const Twine &msg);
3029
31void writeU8(raw_ostream &OS, uint8_t byte, const Twine &Msg);
30void writeU8(raw_ostream &os, uint8_t byte, const Twine &msg);
3231
33void writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg);
32void writeU32(raw_ostream &os, uint32_t number, const Twine &msg);
3433
35void writeValueType(raw_ostream &OS, llvm::wasm::ValType Type,
36 const Twine &Msg);
34void writeValueType(raw_ostream &os, llvm::wasm::ValType type,
35 const Twine &msg);
3736
38void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig);
37void writeSig(raw_ostream &os, const llvm::wasm::WasmSignature &sig);
3938
40void writeInitExpr(raw_ostream &OS, const llvm::wasm::WasmInitExpr &InitExpr);
39void writeInitExpr(raw_ostream &os, const llvm::wasm::WasmInitExpr &initExpr);
4140
42void writeLimits(raw_ostream &OS, const llvm::wasm::WasmLimits &Limits);
41void writeLimits(raw_ostream &os, const llvm::wasm::WasmLimits &limits);
4342
44void writeGlobalType(raw_ostream &OS, const llvm::wasm::WasmGlobalType &Type);
43void writeGlobalType(raw_ostream &os, const llvm::wasm::WasmGlobalType &type);
4544
46void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global);
45void writeGlobal(raw_ostream &os, const llvm::wasm::WasmGlobal &global);
4746
48void writeEventType(raw_ostream &OS, const llvm::wasm::WasmEventType &Type);
47void writeEventType(raw_ostream &os, const llvm::wasm::WasmEventType &type);
4948
50void writeEvent(raw_ostream &OS, const llvm::wasm::WasmEvent &Event);
49void writeEvent(raw_ostream &os, const llvm::wasm::WasmEvent &event);
5150
52void writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type);
51void writeTableType(raw_ostream &os, const llvm::wasm::WasmTable &type);
5352
54void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import);
53void writeImport(raw_ostream &os, const llvm::wasm::WasmImport &import);
5554
56void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export);
55void writeExport(raw_ostream &os, const llvm::wasm::WasmExport &export_);
5756
5857} // namespace wasm
5958
60std::string toString(llvm::wasm::ValType Type);
61std::string toString(const llvm::wasm::WasmSignature &Sig);
62std::string toString(const llvm::wasm::WasmGlobalType &Type);
63std::string toString(const llvm::wasm::WasmEventType &Type);
59std::string toString(llvm::wasm::ValType type);
60std::string toString(const llvm::wasm::WasmSignature &sig);
61std::string toString(const llvm::wasm::WasmGlobalType &type);
62std::string toString(const llvm::wasm::WasmEventType &type);
6463
6564} // namespace lld
6665