| author | |
| committer | |
| log | cfb29f18e476a3d814664a0944699927ce5bf190 |
| tree | 761b59a7f13dd917649ea717507f5f0b9d82926b |
| parent | b48948d6e805cdee7f33243098af9a862c152df1 |
1616 files changed, 41551 insertions(+), 12592 deletions(-)
deps/lld-prebuilt/COFF/Options.inc+42-12| ... | @@ -12,8 +12,8 @@ | ... | @@ -12,8 +12,8 @@ |
| 12 | #ifdef PREFIX | 12 | #ifdef PREFIX |
| 13 | #define COMMA , | 13 | #define COMMA , |
| 14 | PREFIX(prefix_0, {nullptr}) | 14 | PREFIX(prefix_0, {nullptr}) |
| 15 | PREFIX(prefix_3, {"--" COMMA nullptr}) | 15 | PREFIX(prefix_2, {"--" COMMA nullptr}) |
| 16 | PREFIX(prefix_2, {"/" COMMA "-" COMMA nullptr}) | 16 | PREFIX(prefix_3, {"/" COMMA "-" COMMA nullptr}) |
| 17 | PREFIX(prefix_1, {"/" COMMA "-" COMMA "-?" COMMA nullptr}) | 17 | PREFIX(prefix_1, {"/" COMMA "-" COMMA "-?" COMMA nullptr}) |
| 18 | PREFIX(prefix_4, {"/?" COMMA "-?" COMMA nullptr}) | 18 | PREFIX(prefix_4, {"/?" COMMA "-?" COMMA nullptr}) |
| 19 | #undef COMMA | 19 | #undef COMMA |
| ... | @@ -49,13 +49,21 @@ OPTION(prefix_1, "appcontainer", appcontainer, Flag, INVALID, INVALID, nullptr, | ... | @@ -49,13 +49,21 @@ OPTION(prefix_1, "appcontainer", appcontainer, Flag, INVALID, INVALID, nullptr, |
| 49 | "Image can only be run in an app container", nullptr, nullptr) | 49 | "Image can only be run in an app container", nullptr, nullptr) |
| 50 | OPTION(prefix_1, "base:", base, Joined, INVALID, INVALID, nullptr, 0, 0, | 50 | OPTION(prefix_1, "base:", base, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 51 | "Base address of the program", nullptr, nullptr) | 51 | "Base address of the program", nullptr, nullptr) |
| 52 | OPTION(prefix_1, "Brepro", repro, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 53 | "Use a hash of the executable as the PE header timestamp", nullptr, nullptr) | ||
| 54 | OPTION(prefix_2, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 55 | "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr) | ||
| 56 | OPTION(prefix_2, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 57 | "Use colors in diagnostics", nullptr, nullptr) | ||
| 52 | OPTION(prefix_1, "debug:dwarf", debug_dwarf, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 58 | OPTION(prefix_1, "debug:dwarf", debug_dwarf, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 59 | OPTION(prefix_1, "debug:full", debug_full, Flag, INVALID, debug, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 53 | OPTION(prefix_1, "debug:ghash", debug_ghash, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 60 | OPTION(prefix_1, "debug:ghash", debug_ghash, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 61 | OPTION(prefix_1, "debug:symtab", debug_symtab, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 54 | OPTION(prefix_1, "debugtype:", debugtype, Joined, INVALID, INVALID, nullptr, 0, 0, | 62 | OPTION(prefix_1, "debugtype:", debugtype, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 55 | "Debug Info Options", nullptr, nullptr) | 63 | "Debug Info Options", nullptr, nullptr) |
| 56 | OPTION(prefix_1, "debug", debug, Flag, INVALID, INVALID, nullptr, 0, 0, | 64 | OPTION(prefix_1, "debug", debug, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 57 | "Embed a symbol table in the image", nullptr, nullptr) | 65 | "Embed a symbol table in the image", nullptr, nullptr) |
| 58 | OPTION(prefix_2, "def:", deffile, Joined, INVALID, INVALID, nullptr, 0, 0, | 66 | OPTION(prefix_3, "def:", deffile, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 59 | "Use module-definition file", nullptr, nullptr) | 67 | "Use module-definition file", nullptr, nullptr) |
| 60 | OPTION(prefix_1, "defaultlib:", defaultlib, Joined, INVALID, INVALID, nullptr, 0, 0, | 68 | OPTION(prefix_1, "defaultlib:", defaultlib, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 61 | "Add the library to the list of input files", nullptr, nullptr) | 69 | "Add the library to the list of input files", nullptr, nullptr) |
| ... | @@ -91,6 +99,8 @@ OPTION(prefix_1, "force:unresolved", force_unresolved, Flag, INVALID, INVALID, n | ... | @@ -91,6 +99,8 @@ OPTION(prefix_1, "force:unresolved", force_unresolved, Flag, INVALID, INVALID, n |
| 91 | OPTION(prefix_1, "force", force, Flag, INVALID, INVALID, nullptr, 0, 0, | 99 | OPTION(prefix_1, "force", force, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 92 | "Allow undefined symbols when creating executables", nullptr, nullptr) | 100 | "Allow undefined symbols when creating executables", nullptr, nullptr) |
| 93 | OPTION(prefix_1, "functionpadmin", functionpadmin, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 101 | OPTION(prefix_1, "functionpadmin", functionpadmin, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 102 | OPTION(prefix_1, "guard:", guard, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 103 | "Control flow guard", nullptr, nullptr) | ||
| 94 | OPTION(prefix_1, "guardsym:", guardsym, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 104 | OPTION(prefix_1, "guardsym:", guardsym, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 95 | OPTION(prefix_1, "heap:", heap, Joined, INVALID, INVALID, nullptr, 0, 0, | 105 | OPTION(prefix_1, "heap:", heap, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 96 | "Size of the heap", nullptr, nullptr) | 106 | "Size of the heap", nullptr, nullptr) |
| ... | @@ -105,23 +115,32 @@ OPTION(prefix_1, "ignore:", ignore, Joined, INVALID, INVALID, nullptr, 0, 0, | ... | @@ -105,23 +115,32 @@ OPTION(prefix_1, "ignore:", ignore, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 105 | OPTION(prefix_1, "ignoreidl", ignoreidl, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 115 | OPTION(prefix_1, "ignoreidl", ignoreidl, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 106 | OPTION(prefix_1, "implib:", implib, Joined, INVALID, INVALID, nullptr, 0, 0, | 116 | OPTION(prefix_1, "implib:", implib, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 107 | "Import library name", nullptr, nullptr) | 117 | "Import library name", nullptr, nullptr) |
| 108 | OPTION(prefix_2, "include:", incl, Joined, INVALID, INVALID, nullptr, 0, 0, | 118 | OPTION(prefix_3, "include:", incl, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 109 | "Force symbol to be added to symbol table as undefined one", nullptr, nullptr) | 119 | "Force symbol to be added to symbol table as undefined one", nullptr, nullptr) |
| 110 | OPTION(prefix_1, "incremental:no", no_incremental, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 120 | OPTION(prefix_1, "incremental:no", incremental_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 111 | OPTION(prefix_1, "incremental", incremental, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 121 | "Overwrite import library even if contents are unchanged", nullptr, nullptr) |
| 122 | OPTION(prefix_1, "incremental", incremental, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 123 | "Keep original import library if contents are unchanged", nullptr, nullptr) | ||
| 124 | OPTION(prefix_1, "integritycheck:no", integritycheck_no, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 125 | "No effect (default)", nullptr, nullptr) | ||
| 126 | OPTION(prefix_1, "integritycheck", integritycheck, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 127 | "Set FORCE_INTEGRITY bit in PE header", nullptr, nullptr) | ||
| 128 | OPTION(prefix_1, "kill-at", kill_at, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 112 | OPTION(prefix_1, "largeaddressaware:no", largeaddressaware_no, Flag, INVALID, INVALID, nullptr, 0, 0, | 129 | OPTION(prefix_1, "largeaddressaware:no", largeaddressaware_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 113 | "Disable large addresses (default on 32-bit)", nullptr, nullptr) | 130 | "Disable large addresses (default on 32-bit)", nullptr, nullptr) |
| 114 | OPTION(prefix_1, "largeaddressaware", largeaddressaware, Flag, INVALID, INVALID, nullptr, 0, 0, | 131 | OPTION(prefix_1, "largeaddressaware", largeaddressaware, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 115 | "Enable large addresses (default on 64-bit)", nullptr, nullptr) | 132 | "Enable large addresses (default on 64-bit)", nullptr, nullptr) |
| 116 | OPTION(prefix_1, "libpath:", libpath, Joined, INVALID, INVALID, nullptr, 0, 0, | 133 | OPTION(prefix_1, "libpath:", libpath, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 117 | "Additional library search path", nullptr, nullptr) | 134 | "Additional library search path", nullptr, nullptr) |
| 135 | OPTION(prefix_1, "lib", lib, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 136 | "Act like lib.exe; must be first argument if present", nullptr, nullptr) | ||
| 118 | OPTION(prefix_1, "linkrepro:", linkrepro, Joined, INVALID, INVALID, nullptr, 0, 0, | 137 | OPTION(prefix_1, "linkrepro:", linkrepro, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 119 | "Dump linker invocation and input files for debugging", nullptr, nullptr) | 138 | "Dump linker invocation and input files for debugging", nullptr, nullptr) |
| 120 | OPTION(prefix_1, "lldltocache:", lldltocache, Joined, INVALID, INVALID, nullptr, 0, 0, | 139 | OPTION(prefix_1, "lldltocache:", lldltocache, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 121 | "Path to ThinLTO cached object file directory", nullptr, nullptr) | 140 | "Path to ThinLTO cached object file directory", nullptr, nullptr) |
| 122 | OPTION(prefix_1, "lldltocachepolicy:", lldltocachepolicy, Joined, INVALID, INVALID, nullptr, 0, 0, | 141 | OPTION(prefix_1, "lldltocachepolicy:", lldltocachepolicy, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 123 | "Pruning policy for the ThinLTO cache", nullptr, nullptr) | 142 | "Pruning policy for the ThinLTO cache", nullptr, nullptr) |
| 124 | OPTION(prefix_2, "lldmap:", lldmap_file, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 143 | OPTION(prefix_3, "lldmap:", lldmap_file, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 125 | OPTION(prefix_1, "lldmap", lldmap, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 144 | OPTION(prefix_1, "lldmap", lldmap, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 126 | OPTION(prefix_1, "lldmingw", lldmingw, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 145 | OPTION(prefix_1, "lldmingw", lldmingw, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 127 | OPTION(prefix_1, "lldsavetemps", lldsavetemps, Flag, INVALID, INVALID, nullptr, 0, 0, | 146 | OPTION(prefix_1, "lldsavetemps", lldsavetemps, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -145,7 +164,10 @@ OPTION(prefix_1, "merge:", merge, Joined, INVALID, INVALID, nullptr, 0, 0, | ... | @@ -145,7 +164,10 @@ OPTION(prefix_1, "merge:", merge, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 145 | OPTION(prefix_1, "mllvm:", mllvm, Joined, INVALID, INVALID, nullptr, 0, 0, | 164 | OPTION(prefix_1, "mllvm:", mllvm, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 146 | "Options to pass to LLVM", nullptr, nullptr) | 165 | "Options to pass to LLVM", nullptr, nullptr) |
| 147 | OPTION(prefix_1, "msvclto", msvclto, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 166 | OPTION(prefix_1, "msvclto", msvclto, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 148 | OPTION(prefix_1, "natvis:", natvis, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 167 | OPTION(prefix_1, "natvis:", natvis, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 168 | "Path to natvis file to embed in the PDB", nullptr, nullptr) | ||
| 169 | OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 170 | "Do not use colors in diagnostics", nullptr, nullptr) | ||
| 149 | OPTION(prefix_1, "nodefaultlib:", nodefaultlib, Joined, INVALID, INVALID, nullptr, 0, 0, | 171 | OPTION(prefix_1, "nodefaultlib:", nodefaultlib, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 150 | "Remove a default library", nullptr, nullptr) | 172 | "Remove a default library", nullptr, nullptr) |
| 151 | OPTION(prefix_1, "nodefaultlib", nodefaultlib_all, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 173 | OPTION(prefix_1, "nodefaultlib", nodefaultlib_all, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| ... | @@ -157,14 +179,19 @@ OPTION(prefix_1, "nxcompat", nxcompat, Flag, INVALID, INVALID, nullptr, 0, 0, | ... | @@ -157,14 +179,19 @@ OPTION(prefix_1, "nxcompat", nxcompat, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 157 | "Enable data execution prevention (default)", nullptr, nullptr) | 179 | "Enable data execution prevention (default)", nullptr, nullptr) |
| 158 | OPTION(prefix_1, "opt:", opt, Joined, INVALID, INVALID, nullptr, 0, 0, | 180 | OPTION(prefix_1, "opt:", opt, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 159 | "Control optimizations", nullptr, nullptr) | 181 | "Control optimizations", nullptr, nullptr) |
| 182 | OPTION(prefix_1, "order:", order, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 183 | "Put functions in order", nullptr, nullptr) | ||
| 160 | OPTION(prefix_1, "out:", out, Joined, INVALID, INVALID, nullptr, 0, 0, | 184 | OPTION(prefix_1, "out:", out, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 161 | "Path to file to write output", nullptr, nullptr) | 185 | "Path to file to write output", nullptr, nullptr) |
| 162 | OPTION(prefix_2, "output-def:", output_def, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 186 | OPTION(prefix_3, "output-def:", output_def, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 163 | OPTION(prefix_1, "pdb:", pdb, Joined, INVALID, INVALID, nullptr, 0, 0, | 187 | OPTION(prefix_1, "pdb:", pdb, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 164 | "PDB file path", nullptr, nullptr) | 188 | "PDB file path", nullptr, nullptr) |
| 165 | OPTION(prefix_1, "pdbaltpath:", pdbaltpath, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 189 | OPTION(prefix_1, "pdbaltpath:", pdbaltpath, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 190 | "PDB file path to embed in the image", nullptr, nullptr) | ||
| 191 | OPTION(prefix_1, "pdbsourcepath:", pdb_source_path, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 192 | "Base path used to make relative source file path absolute in PDB", nullptr, nullptr) | ||
| 166 | OPTION(prefix_1, "profile", profile, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 193 | OPTION(prefix_1, "profile", profile, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 167 | OPTION(prefix_3, "rsp-quoting=", rsp_quoting, Joined, INVALID, INVALID, nullptr, 0, 0, | 194 | OPTION(prefix_2, "rsp-quoting=", rsp_quoting, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 168 | "Quoting style for response files, 'windows' (default) or 'posix'", nullptr, nullptr) | 195 | "Quoting style for response files, 'windows' (default) or 'posix'", nullptr, nullptr) |
| 169 | OPTION(prefix_1, "safeseh:no", safeseh_no, Flag, INVALID, INVALID, nullptr, 0, 0, | 196 | OPTION(prefix_1, "safeseh:no", safeseh_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 170 | "Don't produce an image with Safe Exception Handler", nullptr, nullptr) | 197 | "Don't produce an image with Safe Exception Handler", nullptr, nullptr) |
| ... | @@ -181,6 +208,9 @@ OPTION(prefix_1, "subsystem:", subsystem, Joined, INVALID, INVALID, nullptr, 0, | ... | @@ -181,6 +208,9 @@ OPTION(prefix_1, "subsystem:", subsystem, Joined, INVALID, INVALID, nullptr, 0, |
| 181 | OPTION(prefix_1, "swaprun:cd", swaprun_cd, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 208 | OPTION(prefix_1, "swaprun:cd", swaprun_cd, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 182 | OPTION(prefix_1, "swaprun:net", swaprun_net, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 209 | OPTION(prefix_1, "swaprun:net", swaprun_net, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 183 | OPTION(prefix_1, "throwingnew", throwingnew, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 210 | OPTION(prefix_1, "throwingnew", throwingnew, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 211 | OPTION(prefix_1, "timestamp:", timestamp, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 212 | "Specify the PE header timestamp", nullptr, nullptr) | ||
| 213 | OPTION(prefix_1, "time", show_timing, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 184 | OPTION(prefix_1, "tlbid:", tlbid, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 214 | OPTION(prefix_1, "tlbid:", tlbid, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 185 | OPTION(prefix_1, "tlbout:", tlbout, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 215 | OPTION(prefix_1, "tlbout:", tlbout, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 186 | OPTION(prefix_1, "tsaware:no", tsaware_no, Flag, INVALID, INVALID, nullptr, 0, 0, | 216 | OPTION(prefix_1, "tsaware:no", tsaware_no, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -191,7 +221,7 @@ OPTION(prefix_1, "verbose:", verbose_all, Joined, INVALID, INVALID, nullptr, 0, | ... | @@ -191,7 +221,7 @@ OPTION(prefix_1, "verbose:", verbose_all, Joined, INVALID, INVALID, nullptr, 0, |
| 191 | OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 221 | OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 192 | OPTION(prefix_1, "version:", version, Joined, INVALID, INVALID, nullptr, 0, 0, | 222 | OPTION(prefix_1, "version:", version, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 193 | "Specify a version number in the PE header", nullptr, nullptr) | 223 | "Specify a version number in the PE header", nullptr, nullptr) |
| 194 | OPTION(prefix_3, "version", dash_dash_version, Flag, INVALID, INVALID, nullptr, 0, 0, | 224 | OPTION(prefix_2, "version", dash_dash_version, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 195 | "Print version information", nullptr, nullptr) | 225 | "Print version information", nullptr, nullptr) |
| 196 | OPTION(prefix_1, "wholearchive:", wholearchive_file, Joined, INVALID, INVALID, nullptr, 0, 0, | 226 | OPTION(prefix_1, "wholearchive:", wholearchive_file, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 197 | "Include all object files from this archive", nullptr, nullptr) | 227 | "Include all object files from this archive", nullptr, nullptr) |
deps/lld-prebuilt/DarwinLdOptions.inc+5| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | #define COMMA , | 13 | #define COMMA , |
| 14 | PREFIX(prefix_0, {nullptr}) | 14 | PREFIX(prefix_0, {nullptr}) |
| 15 | PREFIX(prefix_1, {"-" COMMA nullptr}) | 15 | PREFIX(prefix_1, {"-" COMMA nullptr}) |
| 16 | PREFIX(prefix_2, {"-" COMMA "--" COMMA nullptr}) | ||
| 16 | #undef COMMA | 17 | #undef COMMA |
| 17 | #endif // PREFIX | 18 | #endif // PREFIX |
| 18 | 19 | ||
| ... | @@ -67,6 +68,8 @@ OPTION(prefix_1, "dylib", dylib, Flag, grp_kind, INVALID, nullptr, 0, 0, | ... | @@ -67,6 +68,8 @@ OPTION(prefix_1, "dylib", dylib, Flag, grp_kind, INVALID, nullptr, 0, 0, |
| 67 | "Create dynamic library", nullptr, nullptr) | 68 | "Create dynamic library", nullptr, nullptr) |
| 68 | OPTION(prefix_1, "dynamic", dynamic, Flag, grp_kind, INVALID, nullptr, 0, 0, | 69 | OPTION(prefix_1, "dynamic", dynamic, Flag, grp_kind, INVALID, nullptr, 0, 0, |
| 69 | "Create dynamic executable (default)", nullptr, nullptr) | 70 | "Create dynamic executable (default)", nullptr, nullptr) |
| 71 | OPTION(prefix_2, "error-limit", error_limit, Separate, INVALID, INVALID, nullptr, 0, 0, | ||
| 72 | "Maximum number of errors to emit before stopping (0 = no limit)", "<number>", nullptr) | ||
| 70 | OPTION(prefix_1, "execute", execute, Flag, grp_kind, INVALID, nullptr, 0, 0, | 73 | OPTION(prefix_1, "execute", execute, Flag, grp_kind, INVALID, nullptr, 0, 0, |
| 71 | "Create main executable (default)", nullptr, nullptr) | 74 | "Create main executable (default)", nullptr, nullptr) |
| 72 | OPTION(prefix_1, "export_dynamic", export_dynamic, Flag, grp_main, INVALID, nullptr, 0, 0, | 75 | OPTION(prefix_1, "export_dynamic", export_dynamic, Flag, grp_main, INVALID, nullptr, 0, 0, |
| ... | @@ -99,6 +102,8 @@ OPTION(prefix_1, "ios_version_min", ios_version_min, Separate, grp_opts, INVALID | ... | @@ -99,6 +102,8 @@ OPTION(prefix_1, "ios_version_min", ios_version_min, Separate, grp_opts, INVALID |
| 99 | OPTION(prefix_1, "iphoneos_version_min", iphoneos_version_min, Separate, INVALID, ios_version_min, nullptr, 0, 0, nullptr, nullptr, nullptr) | 102 | OPTION(prefix_1, "iphoneos_version_min", iphoneos_version_min, Separate, INVALID, ios_version_min, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 100 | OPTION(prefix_1, "keep_private_externs", keep_private_externs, Flag, grp_opts, INVALID, nullptr, 0, 0, | 103 | OPTION(prefix_1, "keep_private_externs", keep_private_externs, Flag, grp_opts, INVALID, nullptr, 0, 0, |
| 101 | "Private extern (hidden) symbols should not be transformed into local symbols", nullptr, nullptr) | 104 | "Private extern (hidden) symbols should not be transformed into local symbols", nullptr, nullptr) |
| 105 | OPTION(prefix_1, "lto_library", lto_library, Separate, INVALID, INVALID, nullptr, 0, 0, | ||
| 106 | "Ignored for compatibility with other linkers", "<path>", nullptr) | ||
| 102 | OPTION(prefix_1, "L", L, JoinedOrSeparate, grp_libs, INVALID, nullptr, 0, 0, | 107 | OPTION(prefix_1, "L", L, JoinedOrSeparate, grp_libs, INVALID, nullptr, 0, 0, |
| 103 | "Add directory to library search path", "<dir>", nullptr) | 108 | "Add directory to library search path", "<dir>", nullptr) |
| 104 | OPTION(prefix_1, "l", l, Joined, INVALID, INVALID, nullptr, 0, 0, | 109 | OPTION(prefix_1, "l", l, Joined, INVALID, INVALID, nullptr, 0, 0, |
deps/lld-prebuilt/ELF/Options.inc+285-175| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | #define COMMA , | 13 | #define COMMA , |
| 14 | PREFIX(prefix_0, {nullptr}) | 14 | PREFIX(prefix_0, {nullptr}) |
| 15 | PREFIX(prefix_1, {"-" COMMA nullptr}) | 15 | PREFIX(prefix_1, {"-" COMMA nullptr}) |
| 16 | PREFIX(prefix_4, {"-" COMMA "--" COMMA nullptr}) | ||
| 16 | PREFIX(prefix_3, {"--" COMMA nullptr}) | 17 | PREFIX(prefix_3, {"--" COMMA nullptr}) |
| 17 | PREFIX(prefix_2, {"--" COMMA "-" COMMA nullptr}) | 18 | PREFIX(prefix_2, {"--" COMMA "-" COMMA nullptr}) |
| 18 | #undef COMMA | 19 | #undef COMMA |
| ... | @@ -28,18 +29,24 @@ PREFIX(prefix_2, {"--" COMMA "-" COMMA nullptr}) | ... | @@ -28,18 +29,24 @@ PREFIX(prefix_2, {"--" COMMA "-" COMMA nullptr}) |
| 28 | 29 | ||
| 29 | OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 30 | OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 30 | OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 31 | OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 31 | OPTION(prefix_1, "(", start_group_paren, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 32 | OPTION(prefix_1, "(", anonymous_30, Flag, INVALID, start_group, nullptr, 0, 0, |
| 32 | OPTION(prefix_1, ")", end_group_paren, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 33 | "Alias for --start-group", nullptr, nullptr) |
| 34 | OPTION(prefix_1, ")", anonymous_12, Flag, INVALID, end_group, nullptr, 0, 0, | ||
| 35 | "Alias for --end-group", nullptr, nullptr) | ||
| 33 | OPTION(prefix_2, "allow-multiple-definition", allow_multiple_definition, Flag, INVALID, INVALID, nullptr, 0, 0, | 36 | OPTION(prefix_2, "allow-multiple-definition", allow_multiple_definition, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 34 | "Allow multiple definitions", nullptr, nullptr) | 37 | "Allow multiple definitions", nullptr, nullptr) |
| 35 | OPTION(prefix_2, "allow-shlib-undefined", allow_shlib_undefined, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 38 | OPTION(prefix_2, "allow-shlib-undefined", anonymous_47, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 39 | OPTION(prefix_2, "apply-dynamic-relocs", apply_dynamic_relocs, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 40 | "Apply link-time values for dynamic relocations", nullptr, nullptr) | ||
| 36 | OPTION(prefix_2, "as-needed", as_needed, Flag, INVALID, INVALID, nullptr, 0, 0, | 41 | OPTION(prefix_2, "as-needed", as_needed, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 37 | "Only set DT_NEEDED for shared libraries if used", nullptr, nullptr) | 42 | "Only set DT_NEEDED for shared libraries if used", nullptr, nullptr) |
| 38 | OPTION(prefix_2, "auxiliary", auxiliary, Separate, INVALID, INVALID, nullptr, 0, 0, | 43 | OPTION(prefix_2, "auxiliary=", auxiliary_eq, Joined, INVALID, auxiliary, nullptr, 0, 0, |
| 39 | "Set DT_AUXILIARY field to the specified name", nullptr, nullptr) | 44 | "Set DT_AUXILIARY field to the specified name", nullptr, nullptr) |
| 45 | OPTION(prefix_2, "auxiliary", auxiliary, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 40 | OPTION(prefix_2, "Bdynamic", Bdynamic, Flag, INVALID, INVALID, nullptr, 0, 0, | 46 | OPTION(prefix_2, "Bdynamic", Bdynamic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 41 | "Link against shared libraries", nullptr, nullptr) | 47 | "Link against shared libraries (default)", nullptr, nullptr) |
| 42 | OPTION(prefix_2, "Bshareable", alias_shared_Bshareable, Flag, INVALID, shared, nullptr, 0, 0, nullptr, nullptr, nullptr) | 48 | OPTION(prefix_2, "Bshareable", anonymous_28, Flag, INVALID, shared, nullptr, 0, 0, |
| 49 | "Alias for --shared", nullptr, nullptr) | ||
| 43 | OPTION(prefix_2, "Bstatic", Bstatic, Flag, INVALID, INVALID, nullptr, 0, 0, | 50 | OPTION(prefix_2, "Bstatic", Bstatic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 44 | "Do not link against shared libraries", nullptr, nullptr) | 51 | "Do not link against shared libraries", nullptr, nullptr) |
| 45 | OPTION(prefix_2, "Bsymbolic-functions", Bsymbolic_functions, Flag, INVALID, INVALID, nullptr, 0, 0, | 52 | OPTION(prefix_2, "Bsymbolic-functions", Bsymbolic_functions, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -47,31 +54,38 @@ OPTION(prefix_2, "Bsymbolic-functions", Bsymbolic_functions, Flag, INVALID, INVA | ... | @@ -47,31 +54,38 @@ OPTION(prefix_2, "Bsymbolic-functions", Bsymbolic_functions, Flag, INVALID, INVA |
| 47 | OPTION(prefix_2, "Bsymbolic", Bsymbolic, Flag, INVALID, INVALID, nullptr, 0, 0, | 54 | OPTION(prefix_2, "Bsymbolic", Bsymbolic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 48 | "Bind defined symbols locally", nullptr, nullptr) | 55 | "Bind defined symbols locally", nullptr, nullptr) |
| 49 | OPTION(prefix_2, "build-id=", build_id_eq, Joined, INVALID, INVALID, nullptr, 0, 0, | 56 | OPTION(prefix_2, "build-id=", build_id_eq, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 50 | "Generate build ID note", nullptr, nullptr) | 57 | "Generate build ID note", "[fast,md5,sha,uuid,0x<hexstring>]", nullptr) |
| 51 | OPTION(prefix_2, "build-id", build_id, Flag, INVALID, INVALID, nullptr, 0, 0, | 58 | OPTION(prefix_2, "build-id", build_id, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 52 | "Generate build ID note", nullptr, nullptr) | 59 | "Alias for --build-id=fast", nullptr, nullptr) |
| 53 | OPTION(prefix_2, "b", alias_format_b, Separate, INVALID, format, nullptr, 0, 0, nullptr, nullptr, nullptr) | 60 | OPTION(prefix_1, "b", anonymous_16, Separate, INVALID, format, nullptr, 0, 0, |
| 54 | OPTION(prefix_2, "call_shared", alias_Bdynamic_call_shared, Flag, INVALID, Bdynamic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 61 | "Alias for --format", nullptr, nullptr) |
| 62 | OPTION(prefix_2, "call-graph-ordering-file=", call_graph_ordering_file_eq, Joined, INVALID, call_graph_ordering_file, nullptr, 0, 0, | ||
| 63 | "Layout sections to optimize the given callgraph", nullptr, nullptr) | ||
| 64 | OPTION(prefix_2, "call-graph-ordering-file", call_graph_ordering_file, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 65 | OPTION(prefix_2, "call_shared", anonymous_1, Flag, INVALID, Bdynamic, nullptr, 0, 0, | ||
| 66 | "Alias for --Bdynamic", nullptr, nullptr) | ||
| 67 | OPTION(prefix_2, "check-sections", check_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 68 | "Check section addresses for overlaps (default)", nullptr, nullptr) | ||
| 55 | OPTION(prefix_2, "chroot", chroot, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 69 | OPTION(prefix_2, "chroot", chroot, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 56 | OPTION(prefix_2, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, INVALID, nullptr, 0, 0, | 70 | OPTION(prefix_2, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 57 | "Use colors in diagnostics", nullptr, nullptr) | 71 | "Use colors in diagnostics", "[auto,always,never]", nullptr) |
| 58 | OPTION(prefix_2, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, | 72 | OPTION(prefix_2, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 59 | "Use colors in diagnostics", nullptr, nullptr) | 73 | "Alias for --color-diagnostics=always", nullptr, nullptr) |
| 60 | OPTION(prefix_2, "compress-debug-sections=", compress_debug_sections_eq, Joined, INVALID, compress_debug_sections, nullptr, 0, 0, | 74 | OPTION(prefix_2, "compress-debug-sections=", compress_debug_sections_eq, Joined, INVALID, compress_debug_sections, nullptr, 0, 0, |
| 61 | "Compress DWARF debug sections", nullptr, nullptr) | 75 | "Compress DWARF debug sections", "[none,zlib]", nullptr) |
| 62 | OPTION(prefix_2, "compress-debug-sections", compress_debug_sections, Separate, INVALID, INVALID, nullptr, 0, 0, | 76 | OPTION(prefix_2, "compress-debug-sections", compress_debug_sections, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[none,zlib]", nullptr) |
| 63 | "Compress DWARF debug sections", nullptr, nullptr) | 77 | OPTION(prefix_2, "cref", cref, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 64 | OPTION(prefix_2, "cref", cref, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 78 | "Output cross reference table", nullptr, nullptr) |
| 65 | OPTION(prefix_2, "dc", alias_define_common_dc, Flag, INVALID, define_common, nullptr, 0, 0, nullptr, nullptr, nullptr) | 79 | OPTION(prefix_2, "dc", anonymous_7, Flag, INVALID, define_common, nullptr, 0, 0, |
| 80 | "Alias for --define-common", nullptr, nullptr) | ||
| 66 | OPTION(prefix_2, "define-common", define_common, Flag, INVALID, INVALID, nullptr, 0, 0, | 81 | OPTION(prefix_2, "define-common", define_common, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 67 | "Assign space to common symbols", nullptr, nullptr) | 82 | "Assign space to common symbols", nullptr, nullptr) |
| 68 | OPTION(prefix_2, "defsym=", defsym_eq, Joined, INVALID, defsym, nullptr, 0, 0, | 83 | OPTION(prefix_2, "defsym=", defsym_eq, Joined, INVALID, defsym, nullptr, 0, 0, |
| 69 | "Define a symbol alias", nullptr, nullptr) | 84 | "Define a symbol alias", "<symbol>=<value>", nullptr) |
| 70 | OPTION(prefix_2, "defsym", defsym, Separate, INVALID, INVALID, nullptr, 0, 0, | 85 | OPTION(prefix_2, "defsym", defsym, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<symbol>=<value>", nullptr) |
| 71 | "Define a symbol alias", nullptr, nullptr) | ||
| 72 | OPTION(prefix_2, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0, | 86 | OPTION(prefix_2, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 73 | "Demangle symbol names", nullptr, nullptr) | 87 | "Demangle symbol names (default)", nullptr, nullptr) |
| 74 | OPTION(prefix_2, "detect-odr-violations", detect_odr_violations, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 88 | OPTION(prefix_2, "detect-odr-violations", anonymous_48, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 75 | OPTION(prefix_2, "disable-new-dtags", disable_new_dtags, Flag, INVALID, INVALID, nullptr, 0, 0, | 89 | OPTION(prefix_2, "disable-new-dtags", disable_new_dtags, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 76 | "Disable new dynamic tags", nullptr, nullptr) | 90 | "Disable new dynamic tags", nullptr, nullptr) |
| 77 | OPTION(prefix_2, "disable-verify", disable_verify, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 91 | OPTION(prefix_2, "disable-verify", disable_verify, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| ... | @@ -81,133 +95,164 @@ OPTION(prefix_2, "discard-locals", discard_locals, Flag, INVALID, INVALID, nullp | ... | @@ -81,133 +95,164 @@ OPTION(prefix_2, "discard-locals", discard_locals, Flag, INVALID, INVALID, nullp |
| 81 | "Delete temporary local symbols", nullptr, nullptr) | 95 | "Delete temporary local symbols", nullptr, nullptr) |
| 82 | OPTION(prefix_2, "discard-none", discard_none, Flag, INVALID, INVALID, nullptr, 0, 0, | 96 | OPTION(prefix_2, "discard-none", discard_none, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 83 | "Keep all symbols in the symbol table", nullptr, nullptr) | 97 | "Keep all symbols in the symbol table", nullptr, nullptr) |
| 84 | OPTION(prefix_2, "dn", alias_Bstatic_dn, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 98 | OPTION(prefix_2, "dn", anonymous_3, Flag, INVALID, Bstatic, nullptr, 0, 0, |
| 85 | OPTION(prefix_2, "dp", alias_define_common_dp, Flag, INVALID, define_common, nullptr, 0, 0, nullptr, nullptr, nullptr) | 99 | "Alias for --Bstatic", nullptr, nullptr) |
| 86 | OPTION(prefix_2, "dynamic-linker", dynamic_linker, Separate, INVALID, INVALID, nullptr, 0, 0, | 100 | OPTION(prefix_2, "dp", anonymous_8, Flag, INVALID, define_common, nullptr, 0, 0, |
| 101 | "Alias for --define-common", nullptr, nullptr) | ||
| 102 | OPTION(prefix_2, "dynamic-linker=", dynamic_linker_eq, Joined, INVALID, dynamic_linker, nullptr, 0, 0, | ||
| 87 | "Which dynamic linker to use", nullptr, nullptr) | 103 | "Which dynamic linker to use", nullptr, nullptr) |
| 104 | OPTION(prefix_2, "dynamic-linker", dynamic_linker, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 88 | OPTION(prefix_2, "dynamic-list=", dynamic_list_eq, Joined, INVALID, dynamic_list, nullptr, 0, 0, | 105 | OPTION(prefix_2, "dynamic-list=", dynamic_list_eq, Joined, INVALID, dynamic_list, nullptr, 0, 0, |
| 89 | "Read a list of dynamic symbols", nullptr, nullptr) | 106 | "Read a list of dynamic symbols", nullptr, nullptr) |
| 90 | OPTION(prefix_2, "dynamic-list", dynamic_list, Separate, INVALID, INVALID, nullptr, 0, 0, | 107 | OPTION(prefix_2, "dynamic-list", dynamic_list, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 91 | "Read a list of dynamic symbols", nullptr, nullptr) | 108 | OPTION(prefix_2, "dy", anonymous_2, Flag, INVALID, Bdynamic, nullptr, 0, 0, |
| 92 | OPTION(prefix_2, "dy", alias_Bdynamic_dy, Flag, INVALID, Bdynamic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 109 | "Alias for --Bdynamic", nullptr, nullptr) |
| 93 | OPTION(prefix_1, "d", alias_define_common_d, Flag, INVALID, define_common, nullptr, 0, 0, nullptr, nullptr, nullptr) | 110 | OPTION(prefix_1, "d", anonymous_6, Flag, INVALID, define_common, nullptr, 0, 0, |
| 94 | OPTION(prefix_2, "EB", EB, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 111 | "Alias for --define-common", nullptr, nullptr) |
| 112 | OPTION(prefix_2, "EB", anonymous_65, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 95 | OPTION(prefix_2, "eh-frame-hdr", eh_frame_hdr, Flag, INVALID, INVALID, nullptr, 0, 0, | 113 | OPTION(prefix_2, "eh-frame-hdr", eh_frame_hdr, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 96 | "Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header", nullptr, nullptr) | 114 | "Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header", nullptr, nullptr) |
| 97 | OPTION(prefix_2, "EL", EL, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 115 | OPTION(prefix_2, "EL", anonymous_66, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 98 | OPTION(prefix_2, "emit-relocs", emit_relocs, Flag, INVALID, INVALID, nullptr, 0, 0, | 116 | OPTION(prefix_2, "emit-relocs", emit_relocs, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 99 | "Generate relocations in output", nullptr, nullptr) | 117 | "Generate relocations in output", nullptr, nullptr) |
| 100 | OPTION(prefix_2, "enable-new-dtags", enable_new_dtags, Flag, INVALID, INVALID, nullptr, 0, 0, | 118 | OPTION(prefix_2, "enable-new-dtags", enable_new_dtags, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 101 | "Enable new dynamic tags", nullptr, nullptr) | 119 | "Enable new dynamic tags (default)", nullptr, nullptr) |
| 102 | OPTION(prefix_2, "end-group", end_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 120 | OPTION(prefix_2, "end-group", end_group, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 121 | "Ignored for compatibility with GNU unless you pass --warn-backrefs", nullptr, nullptr) | ||
| 103 | OPTION(prefix_2, "end-lib", end_lib, Flag, INVALID, INVALID, nullptr, 0, 0, | 122 | OPTION(prefix_2, "end-lib", end_lib, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 104 | "End a grouping of objects that should be treated as if they were together in an archive", nullptr, nullptr) | 123 | "End a grouping of objects that should be treated as if they were together in an archive", nullptr, nullptr) |
| 105 | OPTION(prefix_2, "entry=", entry_eq, Joined, INVALID, entry, nullptr, 0, 0, | 124 | OPTION(prefix_2, "entry=", entry_eq, Joined, INVALID, entry, nullptr, 0, 0, |
| 106 | "Name of entry point symbol", "<entry>", nullptr) | 125 | "Name of entry point symbol", "<entry>", nullptr) |
| 107 | OPTION(prefix_2, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0, | 126 | OPTION(prefix_2, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<entry>", nullptr) |
| 108 | "Name of entry point symbol", "<entry>", nullptr) | ||
| 109 | OPTION(prefix_2, "error-limit=", error_limit_eq, Joined, INVALID, error_limit, nullptr, 0, 0, | 127 | OPTION(prefix_2, "error-limit=", error_limit_eq, Joined, INVALID, error_limit, nullptr, 0, 0, |
| 110 | "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr) | 128 | "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr) |
| 111 | OPTION(prefix_2, "error-limit", error_limit, Separate, INVALID, INVALID, nullptr, 0, 0, | 129 | OPTION(prefix_2, "error-limit", error_limit, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 112 | "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr) | ||
| 113 | OPTION(prefix_2, "error-unresolved-symbols", error_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, | 130 | OPTION(prefix_2, "error-unresolved-symbols", error_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 114 | "Report unresolved symbols as errors", nullptr, nullptr) | 131 | "Report unresolved symbols as errors", nullptr, nullptr) |
| 115 | OPTION(prefix_2, "exclude-libs=", exclude_libs_eq, Joined, INVALID, exclude_libs, nullptr, 0, 0, | 132 | OPTION(prefix_2, "exclude-libs=", exclude_libs_eq, Joined, INVALID, exclude_libs, nullptr, 0, 0, |
| 116 | "Exclude static libraries from automatic export", nullptr, nullptr) | 133 | "Exclude static libraries from automatic export", nullptr, nullptr) |
| 117 | OPTION(prefix_2, "exclude-libs", exclude_libs, Separate, INVALID, INVALID, nullptr, 0, 0, | 134 | OPTION(prefix_2, "exclude-libs", exclude_libs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 118 | "Exclude static libraries from automatic export", nullptr, nullptr) | 135 | OPTION(prefix_2, "execute-only", execute_only, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 136 | "Do not mark executable sections readable", nullptr, nullptr) | ||
| 119 | OPTION(prefix_2, "export-dynamic-symbol=", export_dynamic_symbol_eq, Joined, INVALID, export_dynamic_symbol, nullptr, 0, 0, | 137 | OPTION(prefix_2, "export-dynamic-symbol=", export_dynamic_symbol_eq, Joined, INVALID, export_dynamic_symbol, nullptr, 0, 0, |
| 120 | "Put a symbol in the dynamic symbol table", nullptr, nullptr) | 138 | "Put a symbol in the dynamic symbol table", nullptr, nullptr) |
| 121 | OPTION(prefix_2, "export-dynamic-symbol", export_dynamic_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, | 139 | OPTION(prefix_2, "export-dynamic-symbol", export_dynamic_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 122 | "Put a symbol in the dynamic symbol table", nullptr, nullptr) | ||
| 123 | OPTION(prefix_2, "export-dynamic", export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0, | 140 | OPTION(prefix_2, "export-dynamic", export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 124 | "Put symbols in the dynamic symbol table", nullptr, nullptr) | 141 | "Put symbols in the dynamic symbol table", nullptr, nullptr) |
| 125 | OPTION(prefix_1, "E", alias_export_dynamic_E, Flag, INVALID, export_dynamic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 142 | OPTION(prefix_1, "E", anonymous_14, Flag, INVALID, export_dynamic, nullptr, 0, 0, |
| 126 | OPTION(prefix_1, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) | 143 | "Alias for --export-dynamic", nullptr, nullptr) |
| 144 | OPTION(prefix_1, "e", anonymous_13, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, | ||
| 145 | "Alias for --entry", nullptr, nullptr) | ||
| 127 | OPTION(prefix_2, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, | 146 | OPTION(prefix_2, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 128 | "Treat warnings as errors", nullptr, nullptr) | 147 | "Treat warnings as errors", nullptr, nullptr) |
| 129 | OPTION(prefix_2, "filter=", filter_eq, Joined, INVALID, filter, nullptr, 0, 0, | 148 | OPTION(prefix_2, "filter=", filter_eq, Joined, INVALID, filter, nullptr, 0, 0, |
| 130 | "Set DT_FILTER field to the specified name", nullptr, nullptr) | 149 | "Set DT_FILTER field to the specified name", nullptr, nullptr) |
| 131 | OPTION(prefix_2, "filter", filter, Separate, INVALID, INVALID, nullptr, 0, 0, | 150 | OPTION(prefix_2, "filter", filter, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 132 | "Set DT_FILTER field to the specified name", nullptr, nullptr) | ||
| 133 | OPTION(prefix_2, "fini=", fini_eq, Joined, INVALID, fini, nullptr, 0, 0, | 151 | OPTION(prefix_2, "fini=", fini_eq, Joined, INVALID, fini, nullptr, 0, 0, |
| 134 | "Specify a finalizer function", "<symbol>", nullptr) | 152 | "Specify a finalizer function", "<symbol>", nullptr) |
| 135 | OPTION(prefix_2, "fini", fini, Separate, INVALID, INVALID, nullptr, 0, 0, | 153 | OPTION(prefix_2, "fini", fini, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<symbol>", nullptr) |
| 136 | "Specify a finalizer function", "<symbol>", nullptr) | ||
| 137 | OPTION(prefix_2, "fix-cortex-a53-843419", fix_cortex_a53_843419, Flag, INVALID, INVALID, nullptr, 0, 0, | 154 | OPTION(prefix_2, "fix-cortex-a53-843419", fix_cortex_a53_843419, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 138 | "Apply fixes for AArch64 Cortex-A53 erratum 843419", nullptr, nullptr) | 155 | "Apply fixes for AArch64 Cortex-A53 erratum 843419", nullptr, nullptr) |
| 139 | OPTION(prefix_2, "format=", format_eq, Joined, INVALID, format, nullptr, 0, 0, | 156 | OPTION(prefix_2, "format=", format_eq, Joined, INVALID, format, nullptr, 0, 0, |
| 140 | "Change the input format of the inputs following this option", "<input-format>", nullptr) | 157 | "Change the input format of the inputs following this option", "[default,elf,binary]", nullptr) |
| 141 | OPTION(prefix_2, "format", format, Separate, INVALID, INVALID, nullptr, 0, 0, | 158 | OPTION(prefix_2, "format", format, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[default,elf,binary]", nullptr) |
| 142 | "Change the input format of the inputs following this option", "<input-format>", nullptr) | 159 | OPTION(prefix_1, "F", anonymous_15, Separate, INVALID, filter, nullptr, 0, 0, |
| 143 | OPTION(prefix_2, "full-shutdown", full_shutdown, Flag, INVALID, INVALID, nullptr, 0, 0, | 160 | "Alias for --filter", nullptr, nullptr) |
| 144 | "Perform a full shutdown instead of calling _exit", nullptr, nullptr) | 161 | OPTION(prefix_1, "f", anonymous_0, Separate, INVALID, auxiliary, nullptr, 0, 0, |
| 145 | OPTION(prefix_1, "F", alias_filter, Separate, INVALID, filter, nullptr, 0, 0, nullptr, nullptr, nullptr) | 162 | "Alias for --auxiliary", nullptr, nullptr) |
| 146 | OPTION(prefix_1, "f", alias_auxiliary, Separate, INVALID, auxiliary, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 147 | OPTION(prefix_2, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | 163 | OPTION(prefix_2, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 148 | "Enable garbage collection of unused sections", nullptr, nullptr) | 164 | "Enable garbage collection of unused sections", nullptr, nullptr) |
| 149 | OPTION(prefix_2, "gdb-index", gdb_index, Flag, INVALID, INVALID, nullptr, 0, 0, | 165 | OPTION(prefix_2, "gdb-index", gdb_index, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 150 | "Generate .gdb_index section", nullptr, nullptr) | 166 | "Generate .gdb_index section", nullptr, nullptr) |
| 151 | OPTION(prefix_1, "G", G, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 167 | OPTION(prefix_2, "gnu-unique", gnu_unique, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 152 | OPTION(prefix_1, "g", g, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 168 | "Enable STB_GNU_UNIQUE symbol binding (default)", nullptr, nullptr) |
| 169 | OPTION(prefix_1, "G", anonymous_67, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 170 | OPTION(prefix_1, "g", anonymous_49, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 153 | OPTION(prefix_2, "hash-style=", hash_style_eq, Joined, INVALID, hash_style, nullptr, 0, 0, | 171 | OPTION(prefix_2, "hash-style=", hash_style_eq, Joined, INVALID, hash_style, nullptr, 0, 0, |
| 154 | "Specify hash style (sysv, gnu or both)", nullptr, nullptr) | 172 | "Specify hash style (sysv, gnu or both)", nullptr, nullptr) |
| 155 | OPTION(prefix_2, "hash-style", hash_style, Separate, INVALID, INVALID, nullptr, 0, 0, | 173 | OPTION(prefix_2, "hash-style", hash_style, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 156 | "Specify hash style (sysv, gnu or both)", nullptr, nullptr) | ||
| 157 | OPTION(prefix_2, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0, | 174 | OPTION(prefix_2, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 158 | "Print option help", nullptr, nullptr) | 175 | "Print option help", nullptr, nullptr) |
| 159 | OPTION(prefix_1, "h", alias_soname_h, JoinedOrSeparate, INVALID, soname, nullptr, 0, 0, nullptr, nullptr, nullptr) | 176 | OPTION(prefix_1, "h", anonymous_29, JoinedOrSeparate, INVALID, soname, nullptr, 0, 0, |
| 160 | OPTION(prefix_2, "icf-data", icf_data, Flag, INVALID, INVALID, nullptr, 0, 0, | 177 | "Alias for --soname", nullptr, nullptr) |
| 161 | "Enable ICF to also fold identical read only data", nullptr, nullptr) | ||
| 162 | OPTION(prefix_2, "icf=all", icf_all, Flag, INVALID, INVALID, nullptr, 0, 0, | 178 | OPTION(prefix_2, "icf=all", icf_all, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 163 | "Enable identical code folding", nullptr, nullptr) | 179 | "Enable identical code folding", nullptr, nullptr) |
| 164 | OPTION(prefix_2, "icf=none", icf_none, Flag, INVALID, INVALID, nullptr, 0, 0, | 180 | OPTION(prefix_2, "icf=none", icf_none, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 165 | "Disable identical code folding", nullptr, nullptr) | 181 | "Disable identical code folding (default)", nullptr, nullptr) |
| 182 | OPTION(prefix_2, "icf=safe", icf_safe, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 183 | "Enable safe identical code folding", nullptr, nullptr) | ||
| 184 | OPTION(prefix_2, "ignore-data-address-equality", ignore_data_address_equality, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 185 | "lld can break the address equality of data", nullptr, nullptr) | ||
| 186 | OPTION(prefix_2, "ignore-function-address-equality", ignore_function_address_equality, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 187 | "lld can break the address equality of functions", nullptr, nullptr) | ||
| 166 | OPTION(prefix_2, "image-base=", image_base_eq, Joined, INVALID, image_base, nullptr, 0, 0, | 188 | OPTION(prefix_2, "image-base=", image_base_eq, Joined, INVALID, image_base, nullptr, 0, 0, |
| 167 | "Set the base address", nullptr, nullptr) | 189 | "Set the base address", nullptr, nullptr) |
| 168 | OPTION(prefix_2, "image-base", image_base, Separate, INVALID, INVALID, nullptr, 0, 0, | 190 | OPTION(prefix_2, "image-base", image_base, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 169 | "Set the base address", nullptr, nullptr) | ||
| 170 | OPTION(prefix_2, "init=", init_eq, Joined, INVALID, init, nullptr, 0, 0, | 191 | OPTION(prefix_2, "init=", init_eq, Joined, INVALID, init, nullptr, 0, 0, |
| 171 | "Specify an initializer function", "<symbol>", nullptr) | 192 | "Specify an initializer function", "<symbol>", nullptr) |
| 172 | OPTION(prefix_2, "init", init, Separate, INVALID, INVALID, nullptr, 0, 0, | 193 | OPTION(prefix_2, "init", init, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<symbol>", nullptr) |
| 173 | "Specify an initializer function", "<symbol>", nullptr) | 194 | OPTION(prefix_2, "just-symbols=", just_symbols_eq, Joined, INVALID, just_symbols, nullptr, 0, 0, |
| 195 | "Just link symbols", nullptr, nullptr) | ||
| 196 | OPTION(prefix_2, "just-symbols", just_symbols, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 197 | OPTION(prefix_2, "keep-unique=", keep_unique_eq, Joined, INVALID, keep_unique, nullptr, 0, 0, | ||
| 198 | "Do not fold this symbol during ICF", nullptr, nullptr) | ||
| 199 | OPTION(prefix_2, "keep-unique", keep_unique, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 174 | OPTION(prefix_2, "library-path=", library_path_eq, Joined, INVALID, library_path, nullptr, 0, 0, | 200 | OPTION(prefix_2, "library-path=", library_path_eq, Joined, INVALID, library_path, nullptr, 0, 0, |
| 175 | "Add a directory to the library search path", "<dir>", nullptr) | 201 | "Add a directory to the library search path", "<dir>", nullptr) |
| 176 | OPTION(prefix_2, "library-path", library_path, Separate, INVALID, INVALID, nullptr, 0, 0, | 202 | OPTION(prefix_2, "library-path", library_path, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<dir>", nullptr) |
| 177 | "Add a directory to the library search path", "<dir>", nullptr) | ||
| 178 | OPTION(prefix_2, "library=", library_eq, Joined, INVALID, library, nullptr, 0, 0, | 203 | OPTION(prefix_2, "library=", library_eq, Joined, INVALID, library, nullptr, 0, 0, |
| 179 | "Root name of library to use", "<libName>", nullptr) | 204 | "Root name of library to use", "<libName>", nullptr) |
| 180 | OPTION(prefix_2, "library", library, Separate, INVALID, INVALID, nullptr, 0, 0, | 205 | OPTION(prefix_2, "library", library, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<libName>", nullptr) |
| 181 | "Root name of library to use", "<libName>", nullptr) | 206 | OPTION(prefix_2, "long-plt", anonymous_50, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 182 | OPTION(prefix_2, "long-plt", long_plt, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 183 | OPTION(prefix_2, "lto-aa-pipeline=", lto_aa_pipeline, Joined, INVALID, INVALID, nullptr, 0, 0, | 207 | OPTION(prefix_2, "lto-aa-pipeline=", lto_aa_pipeline, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 184 | "AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes", nullptr, nullptr) | 208 | "AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes", nullptr, nullptr) |
| 209 | OPTION(prefix_2, "lto-debug-pass-manager", lto_debug_pass_manager, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 210 | "Debug new pass manager", nullptr, nullptr) | ||
| 211 | OPTION(prefix_2, "lto-new-pass-manager", lto_new_pass_manager, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 212 | "Use new pass manager", nullptr, nullptr) | ||
| 185 | OPTION(prefix_2, "lto-newpm-passes=", lto_newpm_passes, Joined, INVALID, INVALID, nullptr, 0, 0, | 213 | OPTION(prefix_2, "lto-newpm-passes=", lto_newpm_passes, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 186 | "Passes to run during LTO", nullptr, nullptr) | 214 | "Passes to run during LTO", nullptr, nullptr) |
| 187 | OPTION(prefix_2, "lto-O", lto_O, Joined, INVALID, INVALID, nullptr, 0, 0, | 215 | OPTION(prefix_2, "lto-O", lto_O, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 188 | "Optimization level for LTO", "<opt-level>", nullptr) | 216 | "Optimization level for LTO", "<opt-level>", nullptr) |
| 189 | OPTION(prefix_2, "lto-partitions=", lto_partitions, Joined, INVALID, INVALID, nullptr, 0, 0, | 217 | OPTION(prefix_2, "lto-partitions=", lto_partitions, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 190 | "Number of LTO codegen partitions", nullptr, nullptr) | 218 | "Number of LTO codegen partitions", nullptr, nullptr) |
| 191 | OPTION(prefix_1, "L", alias_library_path, JoinedOrSeparate, INVALID, library_path, nullptr, 0, 0, nullptr, nullptr, nullptr) | 219 | OPTION(prefix_2, "lto-sample-profile=", lto_sample_profile, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 192 | OPTION(prefix_1, "l", alias_library, JoinedOrSeparate, INVALID, library, nullptr, 0, 0, nullptr, nullptr, nullptr) | 220 | "Sample profile file path", nullptr, nullptr) |
| 221 | OPTION(prefix_1, "L", anonymous_18, JoinedOrSeparate, INVALID, library_path, nullptr, 0, 0, | ||
| 222 | "Alias for --library-path", nullptr, nullptr) | ||
| 223 | OPTION(prefix_1, "l", anonymous_17, JoinedOrSeparate, INVALID, library, nullptr, 0, 0, | ||
| 224 | "Alias for --library", nullptr, nullptr) | ||
| 193 | OPTION(prefix_2, "Map=", Map_eq, Joined, INVALID, Map, nullptr, 0, 0, | 225 | OPTION(prefix_2, "Map=", Map_eq, Joined, INVALID, Map, nullptr, 0, 0, |
| 194 | "Print a link map to the specified file", nullptr, nullptr) | 226 | "Print a link map to the specified file", nullptr, nullptr) |
| 195 | OPTION(prefix_2, "Map", Map, Separate, INVALID, INVALID, nullptr, 0, 0, | 227 | OPTION(prefix_2, "Map", Map, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 196 | "Print a link map to the specified file", nullptr, nullptr) | ||
| 197 | OPTION(prefix_2, "merge-exidx-entries", merge_exidx_entries, Flag, INVALID, INVALID, nullptr, 0, 0, | 228 | OPTION(prefix_2, "merge-exidx-entries", merge_exidx_entries, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 198 | "Enable merging .ARM.exidx entries", nullptr, nullptr) | 229 | "Enable merging .ARM.exidx entries (default)", nullptr, nullptr) |
| 230 | OPTION(prefix_2, "mips-got-size=", mips_got_size_eq, Joined, INVALID, mips_got_size, nullptr, HelpHidden, 0, | ||
| 231 | "Max size of a single MIPS GOT. 0x10000 by default.", nullptr, nullptr) | ||
| 232 | OPTION(prefix_2, "mips-got-size", mips_got_size, Separate, INVALID, INVALID, nullptr, HelpHidden, 0, nullptr, nullptr, nullptr) | ||
| 233 | OPTION(prefix_2, "mllvm=", mllvm_eq, Joined, INVALID, mllvm, nullptr, 0, 0, | ||
| 234 | "Additional arguments to forward to LLVM's option processing", nullptr, nullptr) | ||
| 199 | OPTION(prefix_2, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 235 | OPTION(prefix_2, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 200 | OPTION(prefix_1, "M", alias_print_map_M, Flag, INVALID, print_map, nullptr, 0, 0, nullptr, nullptr, nullptr) | 236 | OPTION(prefix_1, "M", anonymous_24, Flag, INVALID, print_map, nullptr, 0, 0, |
| 237 | "Alias for --print-map", nullptr, nullptr) | ||
| 201 | OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 238 | OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 202 | "Set target emulation", nullptr, nullptr) | 239 | "Set target emulation", nullptr, nullptr) |
| 203 | OPTION(prefix_2, "no-add-needed", no_add_needed, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 240 | OPTION(prefix_2, "no-add-needed", anonymous_51, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 204 | OPTION(prefix_2, "no-allow-shlib-undefined", no_allow_shlib_undefined, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 241 | OPTION(prefix_2, "no-allow-multiple-definition", no_allow_multiple_definition, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 242 | "Do not allow multiple definitions (default)", nullptr, nullptr) | ||
| 243 | OPTION(prefix_2, "no-allow-shlib-undefined", anonymous_52, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 244 | OPTION(prefix_2, "no-apply-dynamic-relocs", no_apply_dynamic_relocs, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 245 | "Do not apply link-time values for dynamic relocations (default)", nullptr, nullptr) | ||
| 205 | OPTION(prefix_2, "no-as-needed", no_as_needed, Flag, INVALID, INVALID, nullptr, 0, 0, | 246 | OPTION(prefix_2, "no-as-needed", no_as_needed, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 206 | "Always DT_NEEDED for shared libraries", nullptr, nullptr) | 247 | "Always set DT_NEEDED for shared libraries (default)", nullptr, nullptr) |
| 248 | OPTION(prefix_2, "no-check-sections", no_check_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 249 | "Do not check section addresses for overlaps", nullptr, nullptr) | ||
| 207 | OPTION(prefix_2, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, | 250 | OPTION(prefix_2, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 208 | "Do not use colors in diagnostics", nullptr, nullptr) | 251 | "Do not use colors in diagnostics", nullptr, nullptr) |
| 209 | OPTION(prefix_2, "no-copy-dt-needed-entries", no_copy_dt_needed_entries, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 252 | OPTION(prefix_2, "no-copy-dt-needed-entries", anonymous_53, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 210 | OPTION(prefix_2, "no-ctors-in-init-array", no_ctors_in_init_array, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 253 | OPTION(prefix_2, "no-cref", no_cref, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 254 | "Do not output cross reference table", nullptr, nullptr) | ||
| 255 | OPTION(prefix_2, "no-ctors-in-init-array", anonymous_54, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 211 | OPTION(prefix_2, "no-define-common", no_define_common, Flag, INVALID, INVALID, nullptr, 0, 0, | 256 | OPTION(prefix_2, "no-define-common", no_define_common, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 212 | "Do not assign space to common symbols", nullptr, nullptr) | 257 | "Do not assign space to common symbols", nullptr, nullptr) |
| 213 | OPTION(prefix_2, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0, | 258 | OPTION(prefix_2, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -216,22 +261,32 @@ OPTION(prefix_2, "no-dynamic-linker", no_dynamic_linker, Flag, INVALID, INVALID, | ... | @@ -216,22 +261,32 @@ OPTION(prefix_2, "no-dynamic-linker", no_dynamic_linker, Flag, INVALID, INVALID, |
| 216 | "Inhibit output of .interp section", nullptr, nullptr) | 261 | "Inhibit output of .interp section", nullptr, nullptr) |
| 217 | OPTION(prefix_2, "no-eh-frame-hdr", no_eh_frame_hdr, Flag, INVALID, INVALID, nullptr, 0, 0, | 262 | OPTION(prefix_2, "no-eh-frame-hdr", no_eh_frame_hdr, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 218 | "Do not create .eh_frame_hdr section", nullptr, nullptr) | 263 | "Do not create .eh_frame_hdr section", nullptr, nullptr) |
| 219 | OPTION(prefix_2, "no-export-dynamic", no_export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 264 | OPTION(prefix_2, "no-execute-only", no_execute_only, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 220 | OPTION(prefix_2, "no-fatal-warnings", no_fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 265 | "Mark executable sections readable (default)", nullptr, nullptr) |
| 266 | OPTION(prefix_2, "no-export-dynamic", no_export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 267 | "Do not put symbols in the dynamic symbol table (default)", nullptr, nullptr) | ||
| 268 | OPTION(prefix_2, "no-fatal-warnings", no_fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 269 | "Do not treat warnings as errors (default)", nullptr, nullptr) | ||
| 221 | OPTION(prefix_2, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | 270 | OPTION(prefix_2, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 222 | "Disable garbage collection of unused sections", nullptr, nullptr) | 271 | "Disable garbage collection of unused sections (default)", nullptr, nullptr) |
| 223 | OPTION(prefix_2, "no-gdb-index", no_gdb_index, Flag, INVALID, INVALID, nullptr, 0, 0, | 272 | OPTION(prefix_2, "no-gdb-index", no_gdb_index, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 224 | "Do not generate .gdb_index section", nullptr, nullptr) | 273 | "Do not generate .gdb_index section (default)", nullptr, nullptr) |
| 225 | OPTION(prefix_2, "no-gnu-unique", no_gnu_unique, Flag, INVALID, INVALID, nullptr, 0, 0, | 274 | OPTION(prefix_2, "no-gnu-unique", no_gnu_unique, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 226 | "Disable STB_GNU_UNIQUE symbol binding", nullptr, nullptr) | 275 | "Disable STB_GNU_UNIQUE symbol binding", nullptr, nullptr) |
| 227 | OPTION(prefix_2, "no-keep-memory", no_keep_memory, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 276 | OPTION(prefix_2, "no-keep-memory", anonymous_55, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 228 | OPTION(prefix_2, "no-merge-exidx-entries", no_merge_exidx_entries, Flag, INVALID, INVALID, nullptr, 0, 0, | 277 | OPTION(prefix_2, "no-merge-exidx-entries", no_merge_exidx_entries, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 229 | "Disable merging .ARM.exidx entries", nullptr, nullptr) | 278 | "Disable merging .ARM.exidx entries", nullptr, nullptr) |
| 230 | OPTION(prefix_2, "no-mmap-output-file", no_mmap_output_file, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 279 | OPTION(prefix_2, "no-mmap-output-file", anonymous_56, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 231 | OPTION(prefix_3, "no-omagic", no_omagic, Flag, INVALID, INVALID, nullptr, 0, 0, | 280 | OPTION(prefix_2, "no-omagic", no_omagic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 232 | "Do not set the text data sections to be writable", "<magic>", nullptr) | 281 | "Do not set the text data sections to be writable", "<magic>", nullptr) |
| 282 | OPTION(prefix_2, "no-pic-executable", anonymous_19, Flag, INVALID, no_pie, nullptr, 0, 0, | ||
| 283 | "Alias for --no-pie", nullptr, nullptr) | ||
| 284 | OPTION(prefix_2, "no-pie", no_pie, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 285 | "Do not create a position independent executable (default)", nullptr, nullptr) | ||
| 233 | OPTION(prefix_2, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | 286 | OPTION(prefix_2, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 234 | "Do not list removed unused sections", nullptr, nullptr) | 287 | "Do not list removed unused sections (default)", nullptr, nullptr) |
| 288 | OPTION(prefix_2, "no-print-icf-sections", no_print_icf_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 289 | "Do not list identical folded sections (default)", nullptr, nullptr) | ||
| 235 | OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr, 0, 0, | 290 | OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 236 | "Do not put read-only non-executable sections in their own segment", nullptr, nullptr) | 291 | "Do not put read-only non-executable sections in their own segment", nullptr, nullptr) |
| 237 | OPTION(prefix_2, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0, | 292 | OPTION(prefix_2, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -240,18 +295,25 @@ OPTION(prefix_2, "no-undefined-version", no_undefined_version, Flag, INVALID, IN | ... | @@ -240,18 +295,25 @@ OPTION(prefix_2, "no-undefined-version", no_undefined_version, Flag, INVALID, IN |
| 240 | "Report version scripts that refer undefined symbols", nullptr, nullptr) | 295 | "Report version scripts that refer undefined symbols", nullptr, nullptr) |
| 241 | OPTION(prefix_2, "no-undefined", no_undefined, Flag, INVALID, INVALID, nullptr, 0, 0, | 296 | OPTION(prefix_2, "no-undefined", no_undefined, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 242 | "Report unresolved symbols even if the linker is creating a shared library", nullptr, nullptr) | 297 | "Report unresolved symbols even if the linker is creating a shared library", nullptr, nullptr) |
| 243 | OPTION(prefix_2, "no-warn-common", no_warn_common, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 298 | OPTION(prefix_2, "no-use-android-relr-tags", no_use_android_relr_tags, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 244 | OPTION(prefix_2, "no-warn-mismatch", no_warn_mismatch, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 299 | "Use SHT_RELR / DT_RELR* tags (default)", nullptr, nullptr) |
| 300 | OPTION(prefix_2, "no-warn-backrefs", no_warn_backrefs, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 301 | "Do not warn about backward symbol references to fetch archive members (default)", nullptr, nullptr) | ||
| 302 | OPTION(prefix_2, "no-warn-common", no_warn_common, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 303 | "Do not warn about duplicate common symbols (default)", nullptr, nullptr) | ||
| 304 | OPTION(prefix_2, "no-warn-mismatch", anonymous_57, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 305 | OPTION(prefix_2, "no-warn-symbol-ordering", no_warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 306 | "Do not warn about problems with the symbol ordering file", nullptr, nullptr) | ||
| 245 | OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, | 307 | OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 246 | "Restores the default behavior of loading archive members", nullptr, nullptr) | 308 | "Do not force load of all members in a static library (default)", nullptr, nullptr) |
| 247 | OPTION(prefix_2, "noinhibit-exec", noinhibit_exec, Flag, INVALID, INVALID, nullptr, 0, 0, | 309 | OPTION(prefix_2, "noinhibit-exec", noinhibit_exec, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 248 | "Retain the executable output file whenever it is still usable", nullptr, nullptr) | 310 | "Retain the executable output file whenever it is still usable", nullptr, nullptr) |
| 249 | OPTION(prefix_2, "non_shared", alias_Bstatic_non_shared, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 311 | OPTION(prefix_2, "non_shared", anonymous_4, Flag, INVALID, Bstatic, nullptr, 0, 0, |
| 250 | OPTION(prefix_2, "nopie", nopie, Flag, INVALID, INVALID, nullptr, 0, 0, | 312 | "Alias for --Bstatic", nullptr, nullptr) |
| 251 | "Do not create a position independent executable", nullptr, nullptr) | ||
| 252 | OPTION(prefix_2, "nostdlib", nostdlib, Flag, INVALID, INVALID, nullptr, 0, 0, | 313 | OPTION(prefix_2, "nostdlib", nostdlib, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 253 | "Only search directories specified on the command line", nullptr, nullptr) | 314 | "Only search directories specified on the command line", nullptr, nullptr) |
| 254 | OPTION(prefix_1, "N", alias_omagic, Flag, INVALID, omagic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 315 | OPTION(prefix_1, "N", anonymous_20, Flag, INVALID, omagic, nullptr, 0, 0, |
| 316 | "Alias for --omagic", nullptr, nullptr) | ||
| 255 | OPTION(prefix_3, "oformat", oformat, Separate, INVALID, INVALID, nullptr, 0, 0, | 317 | OPTION(prefix_3, "oformat", oformat, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 256 | "Specify the binary format for the output object file", "<format>", nullptr) | 318 | "Specify the binary format for the output object file", "<format>", nullptr) |
| 257 | OPTION(prefix_3, "omagic", omagic, Flag, INVALID, INVALID, nullptr, 0, 0, | 319 | OPTION(prefix_3, "omagic", omagic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -259,165 +321,213 @@ OPTION(prefix_3, "omagic", omagic, Flag, INVALID, INVALID, nullptr, 0, 0, | ... | @@ -259,165 +321,213 @@ OPTION(prefix_3, "omagic", omagic, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 259 | OPTION(prefix_3, "opt-remarks-filename", opt_remarks_filename, Separate, INVALID, INVALID, nullptr, 0, 0, | 321 | OPTION(prefix_3, "opt-remarks-filename", opt_remarks_filename, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 260 | "YAML output file for optimization remarks", nullptr, nullptr) | 322 | "YAML output file for optimization remarks", nullptr, nullptr) |
| 261 | OPTION(prefix_3, "opt-remarks-with-hotness", opt_remarks_with_hotness, Flag, INVALID, INVALID, nullptr, 0, 0, | 323 | OPTION(prefix_3, "opt-remarks-with-hotness", opt_remarks_with_hotness, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 262 | "Include hotness informations in the optimization remarks file", nullptr, nullptr) | 324 | "Include hotness information in the optimization remarks file", nullptr, nullptr) |
| 263 | OPTION(prefix_2, "orphan-handling=", orphan_handling_eq, Joined, INVALID, orphan_handling, nullptr, 0, 0, | 325 | OPTION(prefix_2, "orphan-handling=", orphan_handling_eq, Joined, INVALID, orphan_handling, nullptr, 0, 0, |
| 264 | "Control how orphan sections are handled when linker script used", nullptr, nullptr) | 326 | "Control how orphan sections are handled when linker script used", nullptr, nullptr) |
| 265 | OPTION(prefix_2, "orphan-handling", orphan_handling, Separate, INVALID, INVALID, nullptr, 0, 0, | 327 | OPTION(prefix_2, "orphan-handling", orphan_handling, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 266 | "Control how orphan sections are handled when linker script used", nullptr, nullptr) | 328 | OPTION(prefix_3, "output=", anonymous_21, Joined, INVALID, o, nullptr, 0, 0, |
| 267 | OPTION(prefix_3, "output=", alias_o_output, Joined, INVALID, o, nullptr, 0, 0, nullptr, nullptr, nullptr) | 329 | "Alias for -o", nullptr, nullptr) |
| 268 | OPTION(prefix_3, "output", alias_o_output2, Separate, INVALID, o, nullptr, 0, 0, nullptr, nullptr, nullptr) | 330 | OPTION(prefix_3, "output", anonymous_22, Separate, INVALID, o, nullptr, 0, 0, |
| 331 | "Alias for -o", nullptr, nullptr) | ||
| 269 | OPTION(prefix_1, "O", O, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 332 | OPTION(prefix_1, "O", O, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 270 | "Optimize output file size", nullptr, nullptr) | 333 | "Optimize output file size", nullptr, nullptr) |
| 271 | OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 334 | OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 272 | "Path to file to write output", "<path>", nullptr) | 335 | "Path to file to write output", "<path>", nullptr) |
| 273 | OPTION(prefix_2, "pack-dyn-relocs=", pack_dyn_relocs_eq, Joined, INVALID, INVALID, nullptr, 0, 0, | 336 | OPTION(prefix_2, "pack-dyn-relocs=", pack_dyn_relocs_eq, Joined, INVALID, pack_dyn_relocs, nullptr, 0, 0, |
| 274 | "Pack dynamic relocations in the given format (none or android)", "<format>", nullptr) | 337 | "Pack dynamic relocations in the given format", "[none,android,relr,android+relr]", nullptr) |
| 275 | OPTION(prefix_2, "pic-executable", alias_pie_pic_executable, Flag, INVALID, pie, nullptr, 0, 0, nullptr, nullptr, nullptr) | 338 | OPTION(prefix_2, "pack-dyn-relocs", pack_dyn_relocs, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[none,android,relr,android+relr]", nullptr) |
| 339 | OPTION(prefix_2, "pic-executable", anonymous_23, Flag, INVALID, pie, nullptr, 0, 0, | ||
| 340 | "Alias for --pie", nullptr, nullptr) | ||
| 276 | OPTION(prefix_2, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0, | 341 | OPTION(prefix_2, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 277 | "Create a position independent executable", nullptr, nullptr) | 342 | "Create a position independent executable", nullptr, nullptr) |
| 343 | OPTION(prefix_2, "plugin-opt=-fresolution=", plugin_opt_fresolution_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 344 | OPTION(prefix_2, "plugin-opt=-pass-through=", plugin_opt_pass_through_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 345 | OPTION(prefix_2, "plugin-opt=/", plugin_opt_slash, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 346 | OPTION(prefix_2, "plugin-opt=debug-pass-manager", anonymous_40, Flag, INVALID, lto_debug_pass_manager, nullptr, 0, 0, | ||
| 347 | "Alias for -lto-debug-pass-manager", nullptr, nullptr) | ||
| 348 | OPTION(prefix_2, "plugin-opt=disable-verify", anonymous_41, Flag, INVALID, disable_verify, nullptr, 0, 0, | ||
| 349 | "Alias for -disable-verify", nullptr, nullptr) | ||
| 350 | OPTION(prefix_2, "plugin-opt=dwo_dir=", plugin_opt_dwo_dir_eq, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 351 | "Directory to store .dwo files when LTO and debug fission are used", nullptr, nullptr) | ||
| 352 | OPTION(prefix_2, "plugin-opt=jobs=", anonymous_42, Joined, INVALID, thinlto_jobs, nullptr, 0, 0, | ||
| 353 | "Alias for -thinlto-jobs", nullptr, nullptr) | ||
| 354 | OPTION(prefix_2, "plugin-opt=lto-partitions=", anonymous_43, Joined, INVALID, lto_partitions, nullptr, 0, 0, | ||
| 355 | "Alias for -lto-partitions", nullptr, nullptr) | ||
| 356 | OPTION(prefix_2, "plugin-opt=mcpu=", plugin_opt_mcpu_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 357 | OPTION(prefix_2, "plugin-opt=new-pass-manager", anonymous_44, Flag, INVALID, lto_new_pass_manager, nullptr, 0, 0, | ||
| 358 | "Alias for -lto-new-pass-manager", nullptr, nullptr) | ||
| 359 | OPTION(prefix_2, "plugin-opt=obj-path=", plugin_opt_obj_path_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 360 | OPTION(prefix_2, "plugin-opt=O", anonymous_39, Joined, INVALID, lto_O, nullptr, 0, 0, | ||
| 361 | "Alias for -lto-O", nullptr, nullptr) | ||
| 362 | OPTION(prefix_2, "plugin-opt=sample-profile=", anonymous_45, Joined, INVALID, lto_sample_profile, nullptr, 0, 0, | ||
| 363 | "Alias for -lto-sample-profile", nullptr, nullptr) | ||
| 364 | OPTION(prefix_2, "plugin-opt=save-temps", anonymous_46, Flag, INVALID, save_temps, nullptr, 0, 0, | ||
| 365 | "Alias for -save-temps", nullptr, nullptr) | ||
| 366 | OPTION(prefix_2, "plugin-opt=thinlto-emit-imports-files", plugin_opt_thinlto_emit_imports_files, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 367 | OPTION(prefix_2, "plugin-opt=thinlto-index-only=", plugin_opt_thinlto_index_only_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 368 | OPTION(prefix_2, "plugin-opt=thinlto-index-only", plugin_opt_thinlto_index_only, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 369 | OPTION(prefix_2, "plugin-opt=thinlto-object-suffix-replace=", plugin_opt_thinlto_object_suffix_replace_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 370 | OPTION(prefix_2, "plugin-opt=thinlto-prefix-replace=", plugin_opt_thinlto_prefix_replace_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 371 | OPTION(prefix_2, "plugin-opt=thinlto", plugin_opt_thinlto, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 278 | OPTION(prefix_2, "plugin-opt=", plugin_opt_eq, Joined, INVALID, plugin_opt, nullptr, 0, 0, | 372 | OPTION(prefix_2, "plugin-opt=", plugin_opt_eq, Joined, INVALID, plugin_opt, nullptr, 0, 0, |
| 279 | "specifies LTO options for compatibility with GNU linkers", nullptr, nullptr) | 373 | "specifies LTO options for compatibility with GNU linkers", nullptr, nullptr) |
| 280 | OPTION(prefix_2, "plugin-opt", plugin_opt, Separate, INVALID, INVALID, nullptr, 0, 0, | 374 | OPTION(prefix_2, "plugin-opt", plugin_opt, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 281 | "specifies LTO options for compatibility with GNU linkers", nullptr, nullptr) | 375 | OPTION(prefix_2, "plugin=", plugin_eq, Joined, INVALID, plugin, nullptr, 0, 0, |
| 282 | OPTION(prefix_2, "plugin=", plugin_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 376 | "Ignored for compatibility with GNU linkers", nullptr, nullptr) |
| 283 | OPTION(prefix_2, "plugin", plugin, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 377 | OPTION(prefix_2, "plugin", plugin, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 378 | OPTION(prefix_2, "pop-state", pop_state, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 379 | "Undo the effect of -push-state", nullptr, nullptr) | ||
| 284 | OPTION(prefix_2, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | 380 | OPTION(prefix_2, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 285 | "List removed unused sections", nullptr, nullptr) | 381 | "List removed unused sections", nullptr, nullptr) |
| 382 | OPTION(prefix_2, "print-icf-sections", print_icf_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 383 | "List identical folded sections", nullptr, nullptr) | ||
| 286 | OPTION(prefix_2, "print-map", print_map, Flag, INVALID, INVALID, nullptr, 0, 0, | 384 | OPTION(prefix_2, "print-map", print_map, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 287 | "Print a link map to the standard output", nullptr, nullptr) | 385 | "Print a link map to the standard output", nullptr, nullptr) |
| 288 | OPTION(prefix_2, "Qy", Qy, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 386 | OPTION(prefix_2, "push-state", push_state, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 289 | OPTION(prefix_1, "q", alias_emit_relocs, Flag, INVALID, emit_relocs, nullptr, 0, 0, nullptr, nullptr, nullptr) | 387 | "Save the current state of -as-needed, -static and -whole-archive", nullptr, nullptr) |
| 388 | OPTION(prefix_2, "Qy", anonymous_68, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 389 | OPTION(prefix_1, "q", anonymous_11, Flag, INVALID, emit_relocs, nullptr, 0, 0, | ||
| 390 | "Alias for --emit-relocs", nullptr, nullptr) | ||
| 290 | OPTION(prefix_2, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0, | 391 | OPTION(prefix_2, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 291 | "Create relocatable object file", nullptr, nullptr) | 392 | "Create relocatable object file", nullptr, nullptr) |
| 292 | OPTION(prefix_2, "reproduce=", reproduce_eq, Joined, INVALID, reproduce, nullptr, 0, 0, | 393 | OPTION(prefix_2, "reproduce=", reproduce_eq, Joined, INVALID, reproduce, nullptr, 0, 0, |
| 293 | "Dump linker invocation and input files for debugging", nullptr, nullptr) | 394 | "Dump linker invocation and input files for debugging", nullptr, nullptr) |
| 294 | OPTION(prefix_2, "reproduce", reproduce, Separate, INVALID, INVALID, nullptr, 0, 0, | 395 | OPTION(prefix_2, "reproduce", reproduce, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 295 | "Dump linker invocation and input files for debugging", nullptr, nullptr) | ||
| 296 | OPTION(prefix_2, "retain-symbols-file=", retain_symbols_file_eq, Joined, INVALID, retain_symbols_file, nullptr, 0, 0, | 396 | OPTION(prefix_2, "retain-symbols-file=", retain_symbols_file_eq, Joined, INVALID, retain_symbols_file, nullptr, 0, 0, |
| 297 | "Retain only the symbols listed in the file", "<file>", nullptr) | 397 | "Retain only the symbols listed in the file", "<file>", nullptr) |
| 298 | OPTION(prefix_2, "retain-symbols-file", retain_symbols_file, Separate, INVALID, INVALID, nullptr, 0, 0, | 398 | OPTION(prefix_2, "retain-symbols-file", retain_symbols_file, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<file>", nullptr) |
| 299 | "Retain only the symbols listed in the file", "<file>", nullptr) | 399 | OPTION(prefix_2, "rpath-link=", anonymous_59, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 300 | OPTION(prefix_2, "rpath-link=", rpath_link_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 400 | OPTION(prefix_2, "rpath-link", anonymous_58, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 301 | OPTION(prefix_2, "rpath-link", rpath_link, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 302 | OPTION(prefix_2, "rpath=", rpath_eq, Joined, INVALID, rpath, nullptr, 0, 0, | 401 | OPTION(prefix_2, "rpath=", rpath_eq, Joined, INVALID, rpath, nullptr, 0, 0, |
| 303 | "Add a DT_RUNPATH to the output", nullptr, nullptr) | 402 | "Add a DT_RUNPATH to the output", nullptr, nullptr) |
| 304 | OPTION(prefix_2, "rpath", rpath, Separate, INVALID, INVALID, nullptr, 0, 0, | 403 | OPTION(prefix_2, "rpath", rpath, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 305 | "Add a DT_RUNPATH to the output", nullptr, nullptr) | ||
| 306 | OPTION(prefix_2, "rsp-quoting=", rsp_quoting_eq, Joined, INVALID, rsp_quoting, nullptr, 0, 0, | 404 | OPTION(prefix_2, "rsp-quoting=", rsp_quoting_eq, Joined, INVALID, rsp_quoting, nullptr, 0, 0, |
| 307 | "Quoting style for response files. Values supported: windows|posix", nullptr, nullptr) | 405 | "Quoting style for response files", "[posix,windows]", nullptr) |
| 308 | OPTION(prefix_2, "rsp-quoting", rsp_quoting, Separate, INVALID, INVALID, nullptr, 0, 0, | 406 | OPTION(prefix_2, "rsp-quoting", rsp_quoting, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "[posix,windows]", nullptr) |
| 309 | "Quoting style for response files. Values supported: windows|posix", nullptr, nullptr) | 407 | OPTION(prefix_1, "R", anonymous_26, JoinedOrSeparate, INVALID, rpath, nullptr, 0, 0, |
| 310 | OPTION(prefix_1, "R", alias_rpath_R, JoinedOrSeparate, INVALID, rpath, nullptr, 0, 0, nullptr, nullptr, nullptr) | 408 | "Alias for --rpath", nullptr, nullptr) |
| 311 | OPTION(prefix_1, "r", alias_relocatable_r, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr) | 409 | OPTION(prefix_1, "r", anonymous_25, Flag, INVALID, relocatable, nullptr, 0, 0, |
| 410 | "Alias for --relocatable", nullptr, nullptr) | ||
| 312 | OPTION(prefix_2, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 411 | OPTION(prefix_2, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 313 | OPTION(prefix_2, "script=", script_eq, Joined, INVALID, script, nullptr, 0, 0, | 412 | OPTION(prefix_2, "script=", script_eq, Joined, INVALID, script, nullptr, 0, 0, |
| 314 | "Read linker script", nullptr, nullptr) | 413 | "Read linker script", nullptr, nullptr) |
| 315 | OPTION(prefix_2, "script", script, Separate, INVALID, INVALID, nullptr, 0, 0, | 414 | OPTION(prefix_2, "script", script, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 316 | "Read linker script", nullptr, nullptr) | 415 | OPTION(prefix_2, "section-start=", section_start_eq, Joined, INVALID, section_start, nullptr, 0, 0, |
| 317 | OPTION(prefix_2, "section-start", section_start, Separate, INVALID, INVALID, nullptr, 0, 0, | ||
| 318 | "Set address of section", "<address>", nullptr) | 416 | "Set address of section", "<address>", nullptr) |
| 417 | OPTION(prefix_2, "section-start", section_start, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<address>", nullptr) | ||
| 319 | OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0, | 418 | OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 320 | "Build a shared object", nullptr, nullptr) | 419 | "Build a shared object", nullptr, nullptr) |
| 321 | OPTION(prefix_2, "soname=", soname_eq, Joined, INVALID, soname, nullptr, 0, 0, | 420 | OPTION(prefix_2, "soname=", soname_eq, Joined, INVALID, soname, nullptr, 0, 0, |
| 322 | "Set DT_SONAME", nullptr, nullptr) | 421 | "Set DT_SONAME", nullptr, nullptr) |
| 323 | OPTION(prefix_2, "soname", soname, Separate, INVALID, INVALID, nullptr, 0, 0, | 422 | OPTION(prefix_2, "soname", soname, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 324 | "Set DT_SONAME", nullptr, nullptr) | 423 | OPTION(prefix_2, "sort-common", anonymous_60, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 325 | OPTION(prefix_2, "sort-common", sort_common, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 326 | OPTION(prefix_2, "sort-section=", sort_section_eq, Joined, INVALID, sort_section, nullptr, 0, 0, | 424 | OPTION(prefix_2, "sort-section=", sort_section_eq, Joined, INVALID, sort_section, nullptr, 0, 0, |
| 327 | "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr) | 425 | "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr) |
| 328 | OPTION(prefix_2, "sort-section", sort_section, Separate, INVALID, INVALID, nullptr, 0, 0, | 426 | OPTION(prefix_2, "sort-section", sort_section, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 329 | "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr) | 427 | OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 330 | OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 428 | "Ignored for compatibility with GNU unless you pass --warn-backrefs", nullptr, nullptr) |
| 331 | OPTION(prefix_2, "start-lib", start_lib, Flag, INVALID, INVALID, nullptr, 0, 0, | 429 | OPTION(prefix_2, "start-lib", start_lib, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 332 | "Start a grouping of objects that should be treated as if they were together in an archive", nullptr, nullptr) | 430 | "Start a grouping of objects that should be treated as if they were together in an archive", nullptr, nullptr) |
| 333 | OPTION(prefix_2, "static", alias_Bstatic_static, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr) | 431 | OPTION(prefix_2, "static", anonymous_5, Flag, INVALID, Bstatic, nullptr, 0, 0, |
| 334 | OPTION(prefix_2, "stats", stats, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 432 | "Alias for --Bstatic", nullptr, nullptr) |
| 433 | OPTION(prefix_2, "stats", anonymous_61, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 335 | OPTION(prefix_2, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0, | 434 | OPTION(prefix_2, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 336 | "Strip all symbols", nullptr, nullptr) | 435 | "Strip all symbols", nullptr, nullptr) |
| 337 | OPTION(prefix_2, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0, | 436 | OPTION(prefix_2, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 338 | "Strip debugging information", nullptr, nullptr) | 437 | "Strip debugging information", nullptr, nullptr) |
| 339 | OPTION(prefix_2, "symbol-ordering-file", symbol_ordering_file, Separate, INVALID, INVALID, nullptr, 0, 0, | 438 | OPTION(prefix_2, "symbol-ordering-file=", symbol_ordering_file_eq, Joined, INVALID, symbol_ordering_file, nullptr, 0, 0, |
| 340 | "Layout sections in the order specified by symbol file", nullptr, nullptr) | 439 | "Layout sections to place symbols in the order specified by symbol ordering file", nullptr, nullptr) |
| 440 | OPTION(prefix_2, "symbol-ordering-file", symbol_ordering_file, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 341 | OPTION(prefix_2, "sysroot=", sysroot_eq, Joined, INVALID, sysroot, nullptr, 0, 0, | 441 | OPTION(prefix_2, "sysroot=", sysroot_eq, Joined, INVALID, sysroot, nullptr, 0, 0, |
| 342 | "Set the system root", nullptr, nullptr) | 442 | "Set the system root", nullptr, nullptr) |
| 343 | OPTION(prefix_2, "sysroot", sysroot, Separate, INVALID, INVALID, nullptr, 0, 0, | 443 | OPTION(prefix_2, "sysroot", sysroot, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 344 | "Set the system root", nullptr, nullptr) | 444 | OPTION(prefix_1, "S", anonymous_32, Flag, INVALID, strip_debug, nullptr, 0, 0, |
| 345 | OPTION(prefix_1, "S", alias_strip_debug_S, Flag, INVALID, strip_debug, nullptr, 0, 0, nullptr, nullptr, nullptr) | 445 | "Alias for --strip-debug", nullptr, nullptr) |
| 346 | OPTION(prefix_1, "s", alias_strip_all, Flag, INVALID, strip_all, nullptr, 0, 0, nullptr, nullptr, nullptr) | 446 | OPTION(prefix_1, "s", anonymous_31, Flag, INVALID, strip_all, nullptr, 0, 0, |
| 447 | "Alias for --strip-all", nullptr, nullptr) | ||
| 347 | OPTION(prefix_2, "target1-abs", target1_abs, Flag, INVALID, INVALID, nullptr, 0, 0, | 448 | OPTION(prefix_2, "target1-abs", target1_abs, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 348 | "Interpret R_ARM_TARGET1 as R_ARM_ABS32", nullptr, nullptr) | 449 | "Interpret R_ARM_TARGET1 as R_ARM_ABS32 (default)", nullptr, nullptr) |
| 349 | OPTION(prefix_2, "target1-rel", target1_rel, Flag, INVALID, INVALID, nullptr, 0, 0, | 450 | OPTION(prefix_2, "target1-rel", target1_rel, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 350 | "Interpret R_ARM_TARGET1 as R_ARM_REL32", nullptr, nullptr) | 451 | "Interpret R_ARM_TARGET1 as R_ARM_REL32", nullptr, nullptr) |
| 351 | OPTION(prefix_2, "target2=", target2_eq, Joined, INVALID, target2, nullptr, 0, 0, | 452 | OPTION(prefix_2, "target2=", target2_eq, Joined, INVALID, target2, nullptr, 0, 0, |
| 352 | "Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel", "<type>", nullptr) | 453 | "Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel", "<type>", nullptr) |
| 353 | OPTION(prefix_2, "target2", target2, Separate, INVALID, INVALID, nullptr, 0, 0, | 454 | OPTION(prefix_2, "target2", target2, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<type>", nullptr) |
| 354 | "Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel", "<type>", nullptr) | ||
| 355 | OPTION(prefix_2, "Tbss=", Tbss_eq, Joined, INVALID, Tbss, nullptr, 0, 0, | 455 | OPTION(prefix_2, "Tbss=", Tbss_eq, Joined, INVALID, Tbss, nullptr, 0, 0, |
| 356 | "Same as --section-start with .bss as the sectionname", nullptr, nullptr) | 456 | "Same as --section-start with .bss as the sectionname", nullptr, nullptr) |
| 357 | OPTION(prefix_2, "Tbss", Tbss, Separate, INVALID, INVALID, nullptr, 0, 0, | 457 | OPTION(prefix_2, "Tbss", Tbss, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 358 | "Same as --section-start with .bss as the sectionname", nullptr, nullptr) | ||
| 359 | OPTION(prefix_2, "Tdata=", Tdata_eq, Joined, INVALID, Tdata, nullptr, 0, 0, | 458 | OPTION(prefix_2, "Tdata=", Tdata_eq, Joined, INVALID, Tdata, nullptr, 0, 0, |
| 360 | "Same as --section-start with .data as the sectionname", nullptr, nullptr) | 459 | "Same as --section-start with .data as the sectionname", nullptr, nullptr) |
| 361 | OPTION(prefix_2, "Tdata", Tdata, Separate, INVALID, INVALID, nullptr, 0, 0, | 460 | OPTION(prefix_2, "Tdata", Tdata, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 362 | "Same as --section-start with .data as the sectionname", nullptr, nullptr) | ||
| 363 | OPTION(prefix_2, "thinlto-cache-dir=", thinlto_cache_dir, Joined, INVALID, INVALID, nullptr, 0, 0, | 461 | OPTION(prefix_2, "thinlto-cache-dir=", thinlto_cache_dir, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 364 | "Path to ThinLTO cached object file directory", nullptr, nullptr) | 462 | "Path to ThinLTO cached object file directory", nullptr, nullptr) |
| 365 | OPTION(prefix_2, "thinlto-cache-policy", thinlto_cache_policy, Separate, INVALID, INVALID, nullptr, 0, 0, | 463 | OPTION(prefix_2, "thinlto-cache-policy=", thinlto_cache_policy_eq, Joined, INVALID, thinlto_cache_policy, nullptr, 0, 0, |
| 366 | "Pruning policy for the ThinLTO cache", nullptr, nullptr) | 464 | "Pruning policy for the ThinLTO cache", nullptr, nullptr) |
| 465 | OPTION(prefix_2, "thinlto-cache-policy", thinlto_cache_policy, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 367 | OPTION(prefix_2, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullptr, 0, 0, | 466 | OPTION(prefix_2, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 368 | "Number of ThinLTO jobs", nullptr, nullptr) | 467 | "Number of ThinLTO jobs", nullptr, nullptr) |
| 369 | OPTION(prefix_2, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0, | 468 | OPTION(prefix_2, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 370 | "Run the linker multi-threaded", nullptr, nullptr) | 469 | "Run the linker multi-threaded (default)", nullptr, nullptr) |
| 371 | OPTION(prefix_2, "trace-symbol=", trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0, | 470 | OPTION(prefix_2, "trace-symbol=", trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0, |
| 372 | "Trace references to symbols", nullptr, nullptr) | 471 | "Trace references to symbols", nullptr, nullptr) |
| 373 | OPTION(prefix_2, "trace-symbol", trace_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, | 472 | OPTION(prefix_2, "trace-symbol", trace_symbol, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 374 | "Trace references to symbols", nullptr, nullptr) | ||
| 375 | OPTION(prefix_2, "trace", trace, Flag, INVALID, INVALID, nullptr, 0, 0, | 473 | OPTION(prefix_2, "trace", trace, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 376 | "Print the names of the input files", nullptr, nullptr) | 474 | "Print the names of the input files", nullptr, nullptr) |
| 377 | OPTION(prefix_2, "Ttext-segment=", alias_Ttext_segment_eq, Joined, INVALID, Ttext, nullptr, 0, 0, nullptr, nullptr, nullptr) | 475 | OPTION(prefix_4, "Ttext-segment=", anonymous_36, Joined, INVALID, Ttext, nullptr, 0, 0, |
| 378 | OPTION(prefix_2, "Ttext-segment", alias_Ttext_segment, Separate, INVALID, Ttext, nullptr, 0, 0, nullptr, nullptr, nullptr) | 476 | "Alias for --Ttext", nullptr, nullptr) |
| 477 | OPTION(prefix_4, "Ttext-segment", anonymous_35, Separate, INVALID, Ttext, nullptr, 0, 0, | ||
| 478 | "Alias for --Ttext", nullptr, nullptr) | ||
| 379 | OPTION(prefix_2, "Ttext=", Ttext_eq, Joined, INVALID, Ttext, nullptr, 0, 0, | 479 | OPTION(prefix_2, "Ttext=", Ttext_eq, Joined, INVALID, Ttext, nullptr, 0, 0, |
| 380 | "Same as --section-start with .text as the sectionname", nullptr, nullptr) | 480 | "Same as --section-start with .text as the sectionname", nullptr, nullptr) |
| 381 | OPTION(prefix_2, "Ttext", Ttext, Separate, INVALID, INVALID, nullptr, 0, 0, | 481 | OPTION(prefix_2, "Ttext", Ttext, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 382 | "Same as --section-start with .text as the sectionname", nullptr, nullptr) | 482 | OPTION(prefix_1, "T", anonymous_27, JoinedOrSeparate, INVALID, script, nullptr, 0, 0, |
| 383 | OPTION(prefix_1, "T", alias_script_T, JoinedOrSeparate, INVALID, script, nullptr, 0, 0, nullptr, nullptr, nullptr) | 483 | "Alias for --script", nullptr, nullptr) |
| 384 | OPTION(prefix_1, "t", alias_trace, Flag, INVALID, trace, nullptr, 0, 0, nullptr, nullptr, nullptr) | 484 | OPTION(prefix_1, "t", anonymous_33, Flag, INVALID, trace, nullptr, 0, 0, |
| 485 | "Alias for --trace", nullptr, nullptr) | ||
| 486 | OPTION(prefix_2, "undefined-version", undefined_version, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 487 | "Allow unused version in version script (default)", nullptr, nullptr) | ||
| 385 | OPTION(prefix_2, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, | 488 | OPTION(prefix_2, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, |
| 386 | "Force undefined symbol during linking", nullptr, nullptr) | 489 | "Force undefined symbol during linking", "<symbol>", nullptr) |
| 387 | OPTION(prefix_2, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0, | 490 | OPTION(prefix_2, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<symbol>", nullptr) |
| 388 | "Force undefined symbol during linking", nullptr, nullptr) | ||
| 389 | OPTION(prefix_2, "unresolved-symbols=", unresolved_symbols_eq, Joined, INVALID, unresolved_symbols, nullptr, 0, 0, | 491 | OPTION(prefix_2, "unresolved-symbols=", unresolved_symbols_eq, Joined, INVALID, unresolved_symbols, nullptr, 0, 0, |
| 390 | "Determine how to handle unresolved symbols", nullptr, nullptr) | 492 | "Determine how to handle unresolved symbols", nullptr, nullptr) |
| 391 | OPTION(prefix_2, "unresolved-symbols", unresolved_symbols, Separate, INVALID, INVALID, nullptr, 0, 0, | 493 | OPTION(prefix_2, "unresolved-symbols", unresolved_symbols, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 392 | "Determine how to handle unresolved symbols", nullptr, nullptr) | 494 | OPTION(prefix_2, "use-android-relr-tags", use_android_relr_tags, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 393 | OPTION(prefix_1, "u", alias_undefined_u, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr) | 495 | "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*", nullptr, nullptr) |
| 496 | OPTION(prefix_1, "u", anonymous_37, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, | ||
| 497 | "Alias for --undefined", nullptr, nullptr) | ||
| 394 | OPTION(prefix_2, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, | 498 | OPTION(prefix_2, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 395 | "Verbose mode", nullptr, nullptr) | 499 | "Verbose mode", nullptr, nullptr) |
| 396 | OPTION(prefix_2, "version-script=", version_script_eq, Joined, INVALID, version_script, nullptr, 0, 0, | 500 | OPTION(prefix_2, "version-script=", version_script_eq, Joined, INVALID, version_script, nullptr, 0, 0, |
| 397 | "Read a version script", nullptr, nullptr) | 501 | "Read a version script", nullptr, nullptr) |
| 398 | OPTION(prefix_2, "version-script", version_script, Separate, INVALID, INVALID, nullptr, 0, 0, | 502 | OPTION(prefix_2, "version-script", version_script, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 399 | "Read a version script", nullptr, nullptr) | ||
| 400 | OPTION(prefix_2, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0, | 503 | OPTION(prefix_2, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 401 | "Display the version number and exit", nullptr, nullptr) | 504 | "Display the version number and exit", nullptr, nullptr) |
| 402 | OPTION(prefix_1, "V", alias_version_V, Flag, INVALID, version, nullptr, 0, 0, nullptr, nullptr, nullptr) | 505 | OPTION(prefix_1, "V", anonymous_38, Flag, INVALID, version, nullptr, 0, 0, |
| 506 | "Alias for --version", nullptr, nullptr) | ||
| 403 | OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0, | 507 | OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 404 | "Display the version number", nullptr, nullptr) | 508 | "Display the version number", nullptr, nullptr) |
| 509 | OPTION(prefix_2, "warn-backrefs", warn_backrefs, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 510 | "Warn about backward symbol references to fetch archive members", nullptr, nullptr) | ||
| 405 | OPTION(prefix_2, "warn-common", warn_common, Flag, INVALID, INVALID, nullptr, 0, 0, | 511 | OPTION(prefix_2, "warn-common", warn_common, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 406 | "Warn about duplicate common symbols", nullptr, nullptr) | 512 | "Warn about duplicate common symbols", nullptr, nullptr) |
| 407 | OPTION(prefix_2, "warn-execstack", warn_execstack, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 513 | OPTION(prefix_2, "warn-execstack", anonymous_62, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 408 | OPTION(prefix_2, "warn-once", warn_once, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 514 | OPTION(prefix_2, "warn-once", anonymous_63, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 409 | OPTION(prefix_2, "warn-shared-textrel", warn_shared_textrel, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 515 | OPTION(prefix_2, "warn-shared-textrel", anonymous_64, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 516 | OPTION(prefix_2, "warn-symbol-ordering", warn_symbol_ordering, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 517 | "Warn about problems with the symbol ordering file (default)", nullptr, nullptr) | ||
| 410 | OPTION(prefix_2, "warn-unresolved-symbols", warn_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, | 518 | OPTION(prefix_2, "warn-unresolved-symbols", warn_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 411 | "Report unresolved symbols as warnings", nullptr, nullptr) | 519 | "Report unresolved symbols as warnings", nullptr, nullptr) |
| 412 | OPTION(prefix_2, "whole-archive", whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, | 520 | OPTION(prefix_2, "whole-archive", whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 413 | "Force load of all members in a static library", nullptr, nullptr) | 521 | "Force load of all members in a static library", nullptr, nullptr) |
| 414 | OPTION(prefix_2, "wrap=", wrap_eq, Joined, INVALID, wrap, nullptr, 0, 0, | 522 | OPTION(prefix_2, "wrap=", wrap_eq, Joined, INVALID, wrap, nullptr, 0, 0, |
| 415 | "Use wrapper functions for symbol", "<symbol>", nullptr) | 523 | "Use wrapper functions for symbol", "<symbol>=<symbol>", nullptr) |
| 416 | OPTION(prefix_2, "wrap", wrap, Separate, INVALID, INVALID, nullptr, 0, 0, | 524 | OPTION(prefix_2, "wrap", wrap, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, "<symbol>=<symbol>", nullptr) |
| 417 | "Use wrapper functions for symbol", "<symbol>", nullptr) | 525 | OPTION(prefix_1, "X", anonymous_10, Flag, INVALID, discard_locals, nullptr, 0, 0, |
| 418 | OPTION(prefix_1, "X", alias_discard_locals_X, Flag, INVALID, discard_locals, nullptr, 0, 0, nullptr, nullptr, nullptr) | 526 | "Alias for --discard-locals", nullptr, nullptr) |
| 419 | OPTION(prefix_1, "x", alias_discard_all_x, Flag, INVALID, discard_all, nullptr, 0, 0, nullptr, nullptr, nullptr) | 527 | OPTION(prefix_1, "x", anonymous_9, Flag, INVALID, discard_all, nullptr, 0, 0, |
| 420 | OPTION(prefix_1, "y", alias_trace_symbol_y, JoinedOrSeparate, INVALID, trace_symbol, nullptr, 0, 0, nullptr, nullptr, nullptr) | 528 | "Alias for --discard-all", nullptr, nullptr) |
| 529 | OPTION(prefix_1, "y", anonymous_34, JoinedOrSeparate, INVALID, trace_symbol, nullptr, 0, 0, | ||
| 530 | "Alias for --trace-symbol", nullptr, nullptr) | ||
| 421 | OPTION(prefix_1, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 531 | OPTION(prefix_1, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 422 | "Linker option extensions", "<option>", nullptr) | 532 | "Linker option extensions", "<option>", nullptr) |
| 423 | #endif // OPTION | 533 | #endif // OPTION |
deps/lld-prebuilt/MinGW/Options.inc+12| ... | @@ -40,6 +40,7 @@ OPTION(prefix_2, "dynamicbase", dynamicbase, Flag, INVALID, INVALID, nullptr, 0, | ... | @@ -40,6 +40,7 @@ OPTION(prefix_2, "dynamicbase", dynamicbase, Flag, INVALID, INVALID, nullptr, 0, |
| 40 | "Enable ASLR", nullptr, nullptr) | 40 | "Enable ASLR", nullptr, nullptr) |
| 41 | OPTION(prefix_2, "enable-auto-image-base", enable_auto_image_base, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 41 | OPTION(prefix_2, "enable-auto-image-base", enable_auto_image_base, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 42 | OPTION(prefix_2, "enable-auto-import", enable_auto_import, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 42 | OPTION(prefix_2, "enable-auto-import", enable_auto_import, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 43 | OPTION(prefix_2, "end-group", end_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 43 | OPTION(prefix_2, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0, | 44 | OPTION(prefix_2, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 44 | "Name of entry point symbol", "<entry>", nullptr) | 45 | "Name of entry point symbol", "<entry>", nullptr) |
| 45 | OPTION(prefix_2, "export-all-symbols", export_all_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, | 46 | OPTION(prefix_2, "export-all-symbols", export_all_symbols, Flag, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -54,6 +55,8 @@ OPTION(prefix_2, "icf=", icf, Joined, INVALID, INVALID, nullptr, 0, 0, | ... | @@ -54,6 +55,8 @@ OPTION(prefix_2, "icf=", icf, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 54 | "Identical code folding", nullptr, nullptr) | 55 | "Identical code folding", nullptr, nullptr) |
| 55 | OPTION(prefix_2, "image-base", image_base, Separate, INVALID, INVALID, nullptr, 0, 0, | 56 | OPTION(prefix_2, "image-base", image_base, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 56 | "Base address of the program", nullptr, nullptr) | 57 | "Base address of the program", nullptr, nullptr) |
| 58 | OPTION(prefix_2, "kill-at", kill_at, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 59 | "Remove @n from exported symbols", nullptr, nullptr) | ||
| 57 | OPTION(prefix_3, "large-address-aware", large_address_aware, Flag, INVALID, INVALID, nullptr, 0, 0, | 60 | OPTION(prefix_3, "large-address-aware", large_address_aware, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 58 | "Enable large addresses", nullptr, nullptr) | 61 | "Enable large addresses", nullptr, nullptr) |
| 59 | OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 62 | OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -61,6 +64,9 @@ OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | ... | @@ -61,6 +64,9 @@ OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 61 | OPTION(prefix_1, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 64 | OPTION(prefix_1, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 62 | "Root name of library to use", "<libName>", nullptr) | 65 | "Root name of library to use", "<libName>", nullptr) |
| 63 | OPTION(prefix_2, "major-image-version", major_image_version, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 66 | OPTION(prefix_2, "major-image-version", major_image_version, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 67 | OPTION(prefix_2, "Map=", map_eq, Joined, INVALID, map, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 68 | OPTION(prefix_2, "Map", map, Separate, INVALID, INVALID, nullptr, 0, 0, | ||
| 69 | "Output a linker map", nullptr, nullptr) | ||
| 64 | OPTION(prefix_2, "minor-image-version", minor_image_version, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 70 | OPTION(prefix_2, "minor-image-version", minor_image_version, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 65 | OPTION(prefix_2, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 71 | OPTION(prefix_2, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 66 | OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 72 | OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| ... | @@ -81,16 +87,22 @@ OPTION(prefix_1, "O", O, Joined, INVALID, INVALID, nullptr, 0, 0, | ... | @@ -81,16 +87,22 @@ OPTION(prefix_1, "O", O, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 81 | "Optimize output file size", nullptr, nullptr) | 87 | "Optimize output file size", nullptr, nullptr) |
| 82 | OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 88 | OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 83 | "Path to file to write output", "<path>", nullptr) | 89 | "Path to file to write output", "<path>", nullptr) |
| 90 | OPTION(prefix_2, "pdb", pdb, Separate, INVALID, INVALID, nullptr, 0, 0, | ||
| 91 | "Specify output PDB debug information file", nullptr, nullptr) | ||
| 84 | OPTION(prefix_2, "pic-executable", pic_executable, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 92 | OPTION(prefix_2, "pic-executable", pic_executable, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 85 | OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0, | 93 | OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 86 | "Build a shared object", nullptr, nullptr) | 94 | "Build a shared object", nullptr, nullptr) |
| 87 | OPTION(prefix_2, "stack", stack, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | 95 | OPTION(prefix_2, "stack", stack, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 96 | OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 88 | OPTION(prefix_2, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0, | 97 | OPTION(prefix_2, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 89 | "Omit all symbol information from the output binary", nullptr, nullptr) | 98 | "Omit all symbol information from the output binary", nullptr, nullptr) |
| 99 | OPTION(prefix_2, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 100 | "Omit all debug information, but keep symbol information", nullptr, nullptr) | ||
| 90 | OPTION(prefix_2, "subsystem", subs, Separate, INVALID, INVALID, nullptr, 0, 0, | 101 | OPTION(prefix_2, "subsystem", subs, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 91 | "Specify subsystem", nullptr, nullptr) | 102 | "Specify subsystem", nullptr, nullptr) |
| 92 | OPTION(prefix_2, "sysroot", sysroot, Joined, INVALID, INVALID, nullptr, 0, 0, | 103 | OPTION(prefix_2, "sysroot", sysroot, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 93 | "Sysroot", nullptr, nullptr) | 104 | "Sysroot", nullptr, nullptr) |
| 105 | OPTION(prefix_1, "S", alias_strip_S, Flag, INVALID, strip_debug, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 94 | OPTION(prefix_1, "s", alias_strip_s, Flag, INVALID, strip_all, nullptr, 0, 0, nullptr, nullptr, nullptr) | 106 | OPTION(prefix_1, "s", alias_strip_s, Flag, INVALID, strip_all, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 95 | OPTION(prefix_2, "tsaware", tsaware, Flag, INVALID, INVALID, nullptr, 0, 0, | 107 | OPTION(prefix_2, "tsaware", tsaware, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 96 | "Create Terminal Server aware executable", nullptr, nullptr) | 108 | "Create Terminal Server aware executable", nullptr, nullptr) |
deps/lld-prebuilt/lld/Common/Version.inc+3-3| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | #define LLD_VERSION 6.0.0 | 1 | #define LLD_VERSION 7.0.0 |
| 2 | #define LLD_VERSION_STRING "6.0.0" | 2 | #define LLD_VERSION_STRING "7.0.0" |
| 3 | #define LLD_VERSION_MAJOR 6 | 3 | #define LLD_VERSION_MAJOR 7 |
| 4 | #define LLD_VERSION_MINOR 0 | 4 | #define LLD_VERSION_MINOR 0 |
| 5 | #define LLD_REVISION_STRING "" | 5 | #define LLD_REVISION_STRING "" |
| 6 | #define LLD_REPOSITORY_STRING "" | 6 | #define LLD_REPOSITORY_STRING "" |
deps/lld-prebuilt/wasm/Options.inc+52-7| ... | @@ -32,55 +32,98 @@ OPTION(prefix_1, "allow-undefined-file=", allow_undefined_file, Joined, INVALID, | ... | @@ -32,55 +32,98 @@ OPTION(prefix_1, "allow-undefined-file=", allow_undefined_file, Joined, INVALID, |
| 32 | OPTION(prefix_2, "allow-undefined-file", allow_undefined_file_s, Separate, INVALID, allow_undefined_file, nullptr, 0, 0, nullptr, nullptr, nullptr) | 32 | OPTION(prefix_2, "allow-undefined-file", allow_undefined_file_s, Separate, INVALID, allow_undefined_file, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 33 | OPTION(prefix_1, "allow-undefined", allow_undefined, Flag, INVALID, INVALID, nullptr, 0, 0, | 33 | OPTION(prefix_1, "allow-undefined", allow_undefined, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 34 | "Allow undefined symbols in linked binary", nullptr, nullptr) | 34 | "Allow undefined symbols in linked binary", nullptr, nullptr) |
| 35 | OPTION(prefix_1, "check-signatures", check_signatures, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 36 | "Check function signatures", nullptr, nullptr) | ||
| 37 | OPTION(prefix_1, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, INVALID, nullptr, 0, 0, | 35 | OPTION(prefix_1, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 38 | "Use colors in diagnostics", nullptr, nullptr) | 36 | "Use colors in diagnostics; one of 'always', 'never', 'auto'", nullptr, nullptr) |
| 39 | OPTION(prefix_1, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, | 37 | OPTION(prefix_1, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 40 | "Use colors in diagnostics", nullptr, nullptr) | 38 | "Use colors in diagnostics", nullptr, nullptr) |
| 41 | OPTION(prefix_1, "emit-relocs", emit_relocs, Flag, INVALID, INVALID, nullptr, 0, 0, | 39 | OPTION(prefix_1, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 42 | "Generate relocations in output", nullptr, nullptr) | 40 | "Demangle symbol names", nullptr, nullptr) |
| 41 | OPTION(prefix_1, "disable-verify", disable_verify, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 43 | OPTION(prefix_1, "entry=", alias_entry_entry, Joined, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) | 42 | OPTION(prefix_1, "entry=", alias_entry_entry, Joined, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 44 | OPTION(prefix_1, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0, | 43 | OPTION(prefix_1, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 45 | "Name of entry point symbol", "<entry>", nullptr) | 44 | "Name of entry point symbol", "<entry>", nullptr) |
| 46 | OPTION(prefix_1, "error-limit=", error_limit, Joined, INVALID, INVALID, nullptr, 0, 0, | 45 | OPTION(prefix_1, "error-limit=", error_limit, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 47 | "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr) | 46 | "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr) |
| 47 | OPTION(prefix_1, "export-all", export_all, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 48 | "Export all symbols (normally combined with --no-gc-sections)", nullptr, nullptr) | ||
| 49 | OPTION(prefix_1, "export-table", export_table, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 50 | "Export function table to the environment", nullptr, nullptr) | ||
| 51 | OPTION(prefix_1, "export=", export_eq, Joined, INVALID, export, nullptr, 0, 0, | ||
| 52 | "Force a symbol to be exported", nullptr, nullptr) | ||
| 53 | OPTION(prefix_1, "export", export, Separate, INVALID, INVALID, nullptr, 0, 0, | ||
| 54 | "Force a symbol to be exported", nullptr, nullptr) | ||
| 48 | OPTION(prefix_2, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) | 55 | OPTION(prefix_2, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 56 | OPTION(prefix_1, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 57 | "Treat warnings as errors", nullptr, nullptr) | ||
| 58 | OPTION(prefix_1, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 59 | "Enable garbage collection of unused sections", nullptr, nullptr) | ||
| 49 | OPTION(prefix_1, "global-base=", global_base, Joined, INVALID, INVALID, nullptr, 0, 0, | 60 | OPTION(prefix_1, "global-base=", global_base, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 50 | "Where to start to place global data", nullptr, nullptr) | 61 | "Where to start to place global data", nullptr, nullptr) |
| 51 | OPTION(prefix_1, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0, | 62 | OPTION(prefix_1, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 52 | "Print option help", nullptr, nullptr) | 63 | "Print option help", nullptr, nullptr) |
| 53 | OPTION(prefix_1, "import-memory", import_memory, Flag, INVALID, INVALID, nullptr, 0, 0, | 64 | OPTION(prefix_1, "import-memory", import_memory, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 54 | "Import memory from the environment", nullptr, nullptr) | 65 | "Import memory from the environment", nullptr, nullptr) |
| 66 | OPTION(prefix_1, "import-table", import_table, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 67 | "Import function table from the environment", nullptr, nullptr) | ||
| 55 | OPTION(prefix_1, "initial-memory=", initial_memory, Joined, INVALID, INVALID, nullptr, 0, 0, | 68 | OPTION(prefix_1, "initial-memory=", initial_memory, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 56 | "Initial size of the linear memory", nullptr, nullptr) | 69 | "Initial size of the linear memory", nullptr, nullptr) |
| 57 | OPTION(prefix_2, "i", alias_initial_memory_i, Flag, INVALID, initial_memory, nullptr, 0, 0, nullptr, nullptr, nullptr) | 70 | OPTION(prefix_2, "i", alias_initial_memory_i, Flag, INVALID, initial_memory, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 71 | OPTION(prefix_1, "lto-O", lto_O, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 72 | "Optimization level for LTO", "<opt-level>", nullptr) | ||
| 73 | OPTION(prefix_1, "lto-partitions=", lto_partitions, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 74 | "Number of LTO codegen partitions", nullptr, nullptr) | ||
| 58 | OPTION(prefix_2, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 75 | OPTION(prefix_2, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 59 | "Add a directory to the library search path", "<dir>", nullptr) | 76 | "Add a directory to the library search path", "<dir>", nullptr) |
| 60 | OPTION(prefix_2, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 77 | OPTION(prefix_2, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 61 | "Root name of library to use", "<libName>", nullptr) | 78 | "Root name of library to use", "<libName>", nullptr) |
| 62 | OPTION(prefix_1, "max-memory=", max_memory, Joined, INVALID, INVALID, nullptr, 0, 0, | 79 | OPTION(prefix_1, "max-memory=", max_memory, Joined, INVALID, INVALID, nullptr, 0, 0, |
| 63 | "Maximum size of the linear memory", nullptr, nullptr) | 80 | "Maximum size of the linear memory", nullptr, nullptr) |
| 81 | OPTION(prefix_1, "merge-data-segments", merge_data_segments, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 82 | "Enable merging data segments", nullptr, nullptr) | ||
| 64 | OPTION(prefix_1, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, | 83 | OPTION(prefix_1, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, |
| 65 | "Options to pass to LLVM", nullptr, nullptr) | 84 | "Options to pass to LLVM", nullptr, nullptr) |
| 66 | OPTION(prefix_2, "m", alias_max_memory_m, Flag, INVALID, max_memory, nullptr, 0, 0, nullptr, nullptr, nullptr) | 85 | OPTION(prefix_2, "m", alias_max_memory_m, Flag, INVALID, max_memory, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 67 | OPTION(prefix_1, "no-check-signatures", no_check_signatures, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 68 | "Don't check function signatures", nullptr, nullptr) | ||
| 69 | OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, | 86 | OPTION(prefix_1, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 70 | "Do not use colors in diagnostics", nullptr, nullptr) | 87 | "Do not use colors in diagnostics", nullptr, nullptr) |
| 88 | OPTION(prefix_1, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 89 | "Do not demangle symbol names", nullptr, nullptr) | ||
| 71 | OPTION(prefix_1, "no-entry", no_entry, Flag, INVALID, INVALID, nullptr, 0, 0, | 90 | OPTION(prefix_1, "no-entry", no_entry, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 72 | "Do not output any entry point", nullptr, nullptr) | 91 | "Do not output any entry point", nullptr, nullptr) |
| 92 | OPTION(prefix_1, "no-fatal-warnings", no_fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 93 | OPTION(prefix_1, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 94 | "Disable garbage collection of unused sections", nullptr, nullptr) | ||
| 95 | OPTION(prefix_1, "no-merge-data-segments", no_merge_data_segments, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 96 | "Disable merging data segments", nullptr, nullptr) | ||
| 97 | OPTION(prefix_1, "no-print-gc-sections", no_print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 98 | "Do not list removed unused sections", nullptr, nullptr) | ||
| 73 | OPTION(prefix_1, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0, | 99 | OPTION(prefix_1, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 74 | "Do not run the linker multi-threaded", nullptr, nullptr) | 100 | "Do not run the linker multi-threaded", nullptr, nullptr) |
| 101 | OPTION(prefix_1, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 102 | "Do not force load of all members in a static library (default)", nullptr, nullptr) | ||
| 103 | OPTION(prefix_2, "O", O, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | ||
| 104 | "Optimize output file size", nullptr, nullptr) | ||
| 75 | OPTION(prefix_2, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 105 | OPTION(prefix_2, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 76 | "Path to file to write output", "<path>", nullptr) | 106 | "Path to file to write output", "<path>", nullptr) |
| 107 | OPTION(prefix_1, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 108 | "List removed unused sections", nullptr, nullptr) | ||
| 77 | OPTION(prefix_1, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0, | 109 | OPTION(prefix_1, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 78 | "Create relocatable object file", nullptr, nullptr) | 110 | "Create relocatable object file", nullptr, nullptr) |
| 79 | OPTION(prefix_2, "r", alias_relocatable_r, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr) | 111 | OPTION(prefix_2, "r", alias_relocatable_r, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr) |
| 112 | OPTION(prefix_1, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr) | ||
| 113 | OPTION(prefix_1, "stack-first", stack_first, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 114 | "Place stack at start of linear memory rather than after data", nullptr, nullptr) | ||
| 80 | OPTION(prefix_1, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0, | 115 | OPTION(prefix_1, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 81 | "Strip all symbols", nullptr, nullptr) | 116 | "Strip all symbols", nullptr, nullptr) |
| 82 | OPTION(prefix_1, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0, | 117 | OPTION(prefix_1, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 83 | "Strip debugging information", nullptr, nullptr) | 118 | "Strip debugging information", nullptr, nullptr) |
| 119 | OPTION(prefix_1, "thinlto-cache-dir=", thinlto_cache_dir, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 120 | "Path to ThinLTO cached object file directory", nullptr, nullptr) | ||
| 121 | OPTION(prefix_1, "thinlto-cache-policy=", thinlto_cache_policy_eq, Joined, INVALID, thinlto_cache_policy, nullptr, 0, 0, | ||
| 122 | "Pruning policy for the ThinLTO cache", nullptr, nullptr) | ||
| 123 | OPTION(prefix_1, "thinlto-cache-policy", thinlto_cache_policy, Separate, INVALID, INVALID, nullptr, 0, 0, | ||
| 124 | "Pruning policy for the ThinLTO cache", nullptr, nullptr) | ||
| 125 | OPTION(prefix_1, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullptr, 0, 0, | ||
| 126 | "Number of ThinLTO jobs", nullptr, nullptr) | ||
| 84 | OPTION(prefix_1, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0, | 127 | OPTION(prefix_1, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 85 | "Run the linker multi-threaded", nullptr, nullptr) | 128 | "Run the linker multi-threaded", nullptr, nullptr) |
| 86 | OPTION(prefix_1, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, | 129 | OPTION(prefix_1, "undefined=", undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, |
| ... | @@ -94,6 +137,8 @@ OPTION(prefix_1, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0, | ... | @@ -94,6 +137,8 @@ OPTION(prefix_1, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 94 | "Display the version number and exit", nullptr, nullptr) | 137 | "Display the version number and exit", nullptr, nullptr) |
| 95 | OPTION(prefix_2, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0, | 138 | OPTION(prefix_2, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0, |
| 96 | "Display the version number", nullptr, nullptr) | 139 | "Display the version number", nullptr, nullptr) |
| 140 | OPTION(prefix_1, "whole-archive", whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0, | ||
| 141 | "Force load of all members in a static library", nullptr, nullptr) | ||
| 97 | OPTION(prefix_2, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, | 142 | OPTION(prefix_2, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, |
| 98 | "Linker option extensions", "<option>", nullptr) | 143 | "Linker option extensions", "<option>", nullptr) |
| 99 | #endif // OPTION | 144 | #endif // OPTION |
deps/lld/COFF/CMakeLists.txt-1| ... | @@ -18,7 +18,6 @@ add_lld_library(lldCOFF | ... | @@ -18,7 +18,6 @@ add_lld_library(lldCOFF |
| 18 | MarkLive.cpp | 18 | MarkLive.cpp |
| 19 | MinGW.cpp | 19 | MinGW.cpp |
| 20 | PDB.cpp | 20 | PDB.cpp |
| 21 | Strings.cpp | ||
| 22 | SymbolTable.cpp | 21 | SymbolTable.cpp |
| 23 | Symbols.cpp | 22 | Symbols.cpp |
| 24 | Writer.cpp | 23 | Writer.cpp |
deps/lld/COFF/Chunks.cpp+142-33| ... | @@ -31,8 +31,7 @@ namespace coff { | ... | @@ -31,8 +31,7 @@ namespace coff { |
| 31 | 31 | ||
| 32 | SectionChunk::SectionChunk(ObjFile *F, const coff_section *H) | 32 | SectionChunk::SectionChunk(ObjFile *F, const coff_section *H) |
| 33 | : Chunk(SectionKind), Repl(this), Header(H), File(F), | 33 | : Chunk(SectionKind), Repl(this), Header(H), File(F), |
| 34 | Relocs(File->getCOFFObj()->getRelocations(Header)), | 34 | Relocs(File->getCOFFObj()->getRelocations(Header)) { |
| 35 | NumRelocs(std::distance(Relocs.begin(), Relocs.end())) { | ||
| 36 | // Initialize SectionName. | 35 | // Initialize SectionName. |
| 37 | File->getCOFFObj()->getSectionName(Header, SectionName); | 36 | File->getCOFFObj()->getSectionName(Header, SectionName); |
| 38 | 37 | ||
| ... | @@ -51,13 +50,21 @@ static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); } | ... | @@ -51,13 +50,21 @@ static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); } |
| 51 | static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); } | 50 | static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); } |
| 52 | static void or32(uint8_t *P, uint32_t V) { write32le(P, read32le(P) | V); } | 51 | static void or32(uint8_t *P, uint32_t V) { write32le(P, read32le(P) | V); } |
| 53 | 52 | ||
| 53 | // Verify that given sections are appropriate targets for SECREL | ||
| 54 | // relocations. This check is relaxed because unfortunately debug | ||
| 55 | // sections have section-relative relocations against absolute symbols. | ||
| 56 | static bool checkSecRel(const SectionChunk *Sec, OutputSection *OS) { | ||
| 57 | if (OS) | ||
| 58 | return true; | ||
| 59 | if (Sec->isCodeView()) | ||
| 60 | return false; | ||
| 61 | fatal("SECREL relocation cannot be applied to absolute symbols"); | ||
| 62 | } | ||
| 63 | |||
| 54 | static void applySecRel(const SectionChunk *Sec, uint8_t *Off, | 64 | static void applySecRel(const SectionChunk *Sec, uint8_t *Off, |
| 55 | OutputSection *OS, uint64_t S) { | 65 | OutputSection *OS, uint64_t S) { |
| 56 | if (!OS) { | 66 | if (!checkSecRel(Sec, OS)) |
| 57 | if (Sec->isCodeView()) | 67 | return; |
| 58 | return; | ||
| 59 | fatal("SECREL relocation cannot be applied to absolute symbols"); | ||
| 60 | } | ||
| 61 | uint64_t SecRel = S - OS->getRVA(); | 68 | uint64_t SecRel = S - OS->getRVA(); |
| 62 | if (SecRel > UINT32_MAX) { | 69 | if (SecRel > UINT32_MAX) { |
| 63 | error("overflow in SECREL relocation in section: " + Sec->getSectionName()); | 70 | error("overflow in SECREL relocation in section: " + Sec->getSectionName()); |
| ... | @@ -67,10 +74,13 @@ static void applySecRel(const SectionChunk *Sec, uint8_t *Off, | ... | @@ -67,10 +74,13 @@ static void applySecRel(const SectionChunk *Sec, uint8_t *Off, |
| 67 | } | 74 | } |
| 68 | 75 | ||
| 69 | static void applySecIdx(uint8_t *Off, OutputSection *OS) { | 76 | static void applySecIdx(uint8_t *Off, OutputSection *OS) { |
| 70 | // If we have no output section, this must be an absolute symbol. Use the | 77 | // Absolute symbol doesn't have section index, but section index relocation |
| 71 | // sentinel absolute symbol section index. | 78 | // against absolute symbol should be resolved to one plus the last output |
| 72 | uint16_t SecIdx = OS ? OS->SectionIndex : DefinedAbsolute::OutputSectionIndex; | 79 | // section index. This is required for compatibility with MSVC. |
| 73 | add16(Off, SecIdx); | 80 | if (OS) |
| 81 | add16(Off, OS->SectionIndex); | ||
| 82 | else | ||
| 83 | add16(Off, DefinedAbsolute::NumOutputSections + 1); | ||
| 74 | } | 84 | } |
| 75 | 85 | ||
| 76 | void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, | 86 | void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, |
| ... | @@ -88,7 +98,8 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, | ... | @@ -88,7 +98,8 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, |
| 88 | case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break; | 98 | case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break; |
| 89 | case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break; | 99 | case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break; |
| 90 | default: | 100 | default: |
| 91 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); | 101 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + |
| 102 | toString(File)); | ||
| 92 | } | 103 | } |
| 93 | } | 104 | } |
| 94 | 105 | ||
| ... | @@ -102,7 +113,8 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS, | ... | @@ -102,7 +113,8 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS, |
| 102 | case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break; | 113 | case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break; |
| 103 | case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break; | 114 | case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break; |
| 104 | default: | 115 | default: |
| 105 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); | 116 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + |
| 117 | toString(File)); | ||
| 106 | } | 118 | } |
| 107 | } | 119 | } |
| 108 | 120 | ||
| ... | @@ -112,11 +124,10 @@ static void applyMOV(uint8_t *Off, uint16_t V) { | ... | @@ -112,11 +124,10 @@ static void applyMOV(uint8_t *Off, uint16_t V) { |
| 112 | } | 124 | } |
| 113 | 125 | ||
| 114 | static uint16_t readMOV(uint8_t *Off) { | 126 | static uint16_t readMOV(uint8_t *Off) { |
| 115 | uint16_t Opcode1 = read16le(Off); | 127 | uint16_t Op1 = read16le(Off); |
| 116 | uint16_t Opcode2 = read16le(Off + 2); | 128 | uint16_t Op2 = read16le(Off + 2); |
| 117 | uint16_t Imm = (Opcode2 & 0x00ff) | ((Opcode2 >> 4) & 0x0700); | 129 | return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) | |
| 118 | Imm |= ((Opcode1 << 1) & 0x0800) | ((Opcode1 & 0x000f) << 12); | 130 | ((Op1 & 0x000f) << 12); |
| 119 | return Imm; | ||
| 120 | } | 131 | } |
| 121 | 132 | ||
| 122 | void applyMOV32T(uint8_t *Off, uint32_t V) { | 133 | void applyMOV32T(uint8_t *Off, uint32_t V) { |
| ... | @@ -153,7 +164,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, | ... | @@ -153,7 +164,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, |
| 153 | uint64_t S, uint64_t P) const { | 164 | uint64_t S, uint64_t P) const { |
| 154 | // Pointer to thumb code must have the LSB set. | 165 | // Pointer to thumb code must have the LSB set. |
| 155 | uint64_t SX = S; | 166 | uint64_t SX = S; |
| 156 | if (OS && (OS->getPermissions() & IMAGE_SCN_MEM_EXECUTE)) | 167 | if (OS && (OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)) |
| 157 | SX |= 1; | 168 | SX |= 1; |
| 158 | switch (Type) { | 169 | switch (Type) { |
| 159 | case IMAGE_REL_ARM_ADDR32: add32(Off, SX + Config->ImageBase); break; | 170 | case IMAGE_REL_ARM_ADDR32: add32(Off, SX + Config->ImageBase); break; |
| ... | @@ -165,18 +176,19 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, | ... | @@ -165,18 +176,19 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, |
| 165 | case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break; | 176 | case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break; |
| 166 | case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break; | 177 | case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break; |
| 167 | default: | 178 | default: |
| 168 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); | 179 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + |
| 180 | toString(File)); | ||
| 169 | } | 181 | } |
| 170 | } | 182 | } |
| 171 | 183 | ||
| 172 | // Interpret the existing immediate value as a byte offset to the | 184 | // Interpret the existing immediate value as a byte offset to the |
| 173 | // target symbol, then update the instruction with the immediate as | 185 | // target symbol, then update the instruction with the immediate as |
| 174 | // the page offset from the current instruction to the target. | 186 | // the page offset from the current instruction to the target. |
| 175 | static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P) { | 187 | static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) { |
| 176 | uint32_t Orig = read32le(Off); | 188 | uint32_t Orig = read32le(Off); |
| 177 | uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC); | 189 | uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC); |
| 178 | S += Imm; | 190 | S += Imm; |
| 179 | Imm = (S >> 12) - (P >> 12); | 191 | Imm = (S >> Shift) - (P >> Shift); |
| 180 | uint32_t ImmLo = (Imm & 0x3) << 29; | 192 | uint32_t ImmLo = (Imm & 0x3) << 29; |
| 181 | uint32_t ImmHi = (Imm & 0x1FFFFC) << 3; | 193 | uint32_t ImmHi = (Imm & 0x1FFFFC) << 3; |
| 182 | uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3); | 194 | uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3); |
| ... | @@ -213,19 +225,70 @@ static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) { | ... | @@ -213,19 +225,70 @@ static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) { |
| 213 | applyArm64Imm(Off, Imm >> Size, Size); | 225 | applyArm64Imm(Off, Imm >> Size, Size); |
| 214 | } | 226 | } |
| 215 | 227 | ||
| 228 | static void applySecRelLow12A(const SectionChunk *Sec, uint8_t *Off, | ||
| 229 | OutputSection *OS, uint64_t S) { | ||
| 230 | if (checkSecRel(Sec, OS)) | ||
| 231 | applyArm64Imm(Off, (S - OS->getRVA()) & 0xfff, 0); | ||
| 232 | } | ||
| 233 | |||
| 234 | static void applySecRelHigh12A(const SectionChunk *Sec, uint8_t *Off, | ||
| 235 | OutputSection *OS, uint64_t S) { | ||
| 236 | if (!checkSecRel(Sec, OS)) | ||
| 237 | return; | ||
| 238 | uint64_t SecRel = (S - OS->getRVA()) >> 12; | ||
| 239 | if (0xfff < SecRel) { | ||
| 240 | error("overflow in SECREL_HIGH12A relocation in section: " + | ||
| 241 | Sec->getSectionName()); | ||
| 242 | return; | ||
| 243 | } | ||
| 244 | applyArm64Imm(Off, SecRel & 0xfff, 0); | ||
| 245 | } | ||
| 246 | |||
| 247 | static void applySecRelLdr(const SectionChunk *Sec, uint8_t *Off, | ||
| 248 | OutputSection *OS, uint64_t S) { | ||
| 249 | if (checkSecRel(Sec, OS)) | ||
| 250 | applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff); | ||
| 251 | } | ||
| 252 | |||
| 253 | static void applyArm64Branch26(uint8_t *Off, int64_t V) { | ||
| 254 | if (!isInt<28>(V)) | ||
| 255 | fatal("relocation out of range"); | ||
| 256 | or32(Off, (V & 0x0FFFFFFC) >> 2); | ||
| 257 | } | ||
| 258 | |||
| 259 | static void applyArm64Branch19(uint8_t *Off, int64_t V) { | ||
| 260 | if (!isInt<21>(V)) | ||
| 261 | fatal("relocation out of range"); | ||
| 262 | or32(Off, (V & 0x001FFFFC) << 3); | ||
| 263 | } | ||
| 264 | |||
| 265 | static void applyArm64Branch14(uint8_t *Off, int64_t V) { | ||
| 266 | if (!isInt<16>(V)) | ||
| 267 | fatal("relocation out of range"); | ||
| 268 | or32(Off, (V & 0x0000FFFC) << 3); | ||
| 269 | } | ||
| 270 | |||
| 216 | void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, | 271 | void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, |
| 217 | uint64_t S, uint64_t P) const { | 272 | uint64_t S, uint64_t P) const { |
| 218 | switch (Type) { | 273 | switch (Type) { |
| 219 | case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P); break; | 274 | case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P, 12); break; |
| 275 | case IMAGE_REL_ARM64_REL21: applyArm64Addr(Off, S, P, 0); break; | ||
| 220 | case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff, 0); break; | 276 | case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff, 0); break; |
| 221 | case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break; | 277 | case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break; |
| 222 | case IMAGE_REL_ARM64_BRANCH26: or32(Off, ((S - P) & 0x0FFFFFFC) >> 2); break; | 278 | case IMAGE_REL_ARM64_BRANCH26: applyArm64Branch26(Off, S - P); break; |
| 279 | case IMAGE_REL_ARM64_BRANCH19: applyArm64Branch19(Off, S - P); break; | ||
| 280 | case IMAGE_REL_ARM64_BRANCH14: applyArm64Branch14(Off, S - P); break; | ||
| 223 | case IMAGE_REL_ARM64_ADDR32: add32(Off, S + Config->ImageBase); break; | 281 | case IMAGE_REL_ARM64_ADDR32: add32(Off, S + Config->ImageBase); break; |
| 224 | case IMAGE_REL_ARM64_ADDR32NB: add32(Off, S); break; | 282 | case IMAGE_REL_ARM64_ADDR32NB: add32(Off, S); break; |
| 225 | case IMAGE_REL_ARM64_ADDR64: add64(Off, S + Config->ImageBase); break; | 283 | case IMAGE_REL_ARM64_ADDR64: add64(Off, S + Config->ImageBase); break; |
| 226 | case IMAGE_REL_ARM64_SECREL: applySecRel(this, Off, OS, S); break; | 284 | case IMAGE_REL_ARM64_SECREL: applySecRel(this, Off, OS, S); break; |
| 285 | case IMAGE_REL_ARM64_SECREL_LOW12A: applySecRelLow12A(this, Off, OS, S); break; | ||
| 286 | case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, Off, OS, S); break; | ||
| 287 | case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break; | ||
| 288 | case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break; | ||
| 227 | default: | 289 | default: |
| 228 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); | 290 | fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + |
| 291 | toString(File)); | ||
| 229 | } | 292 | } |
| 230 | } | 293 | } |
| 231 | 294 | ||
| ... | @@ -234,7 +297,8 @@ void SectionChunk::writeTo(uint8_t *Buf) const { | ... | @@ -234,7 +297,8 @@ void SectionChunk::writeTo(uint8_t *Buf) const { |
| 234 | return; | 297 | return; |
| 235 | // Copy section contents from source object file to output file. | 298 | // Copy section contents from source object file to output file. |
| 236 | ArrayRef<uint8_t> A = getContents(); | 299 | ArrayRef<uint8_t> A = getContents(); |
| 237 | memcpy(Buf + OutputSectionOff, A.data(), A.size()); | 300 | if (!A.empty()) |
| 301 | memcpy(Buf + OutputSectionOff, A.data(), A.size()); | ||
| 238 | 302 | ||
| 239 | // Apply relocations. | 303 | // Apply relocations. |
| 240 | size_t InputSize = getSize(); | 304 | size_t InputSize = getSize(); |
| ... | @@ -350,8 +414,8 @@ bool SectionChunk::hasData() const { | ... | @@ -350,8 +414,8 @@ bool SectionChunk::hasData() const { |
| 350 | return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA); | 414 | return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA); |
| 351 | } | 415 | } |
| 352 | 416 | ||
| 353 | uint32_t SectionChunk::getPermissions() const { | 417 | uint32_t SectionChunk::getOutputCharacteristics() const { |
| 354 | return Header->Characteristics & PermMask; | 418 | return Header->Characteristics & (PermMask | TypeMask); |
| 355 | } | 419 | } |
| 356 | 420 | ||
| 357 | bool SectionChunk::isCOMDAT() const { | 421 | bool SectionChunk::isCOMDAT() const { |
| ... | @@ -378,6 +442,7 @@ ArrayRef<uint8_t> SectionChunk::getContents() const { | ... | @@ -378,6 +442,7 @@ ArrayRef<uint8_t> SectionChunk::getContents() const { |
| 378 | } | 442 | } |
| 379 | 443 | ||
| 380 | void SectionChunk::replace(SectionChunk *Other) { | 444 | void SectionChunk::replace(SectionChunk *Other) { |
| 445 | Alignment = std::max(Alignment, Other->Alignment); | ||
| 381 | Other->Repl = Repl; | 446 | Other->Repl = Repl; |
| 382 | Other->Live = false; | 447 | Other->Live = false; |
| 383 | } | 448 | } |
| ... | @@ -388,7 +453,7 @@ CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) { | ... | @@ -388,7 +453,7 @@ CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) { |
| 388 | Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue())); | 453 | Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue())); |
| 389 | } | 454 | } |
| 390 | 455 | ||
| 391 | uint32_t CommonChunk::getPermissions() const { | 456 | uint32_t CommonChunk::getOutputCharacteristics() const { |
| 392 | return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | | 457 | return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | |
| 393 | IMAGE_SCN_MEM_WRITE; | 458 | IMAGE_SCN_MEM_WRITE; |
| 394 | } | 459 | } |
| ... | @@ -433,7 +498,7 @@ void ImportThunkChunkARM::writeTo(uint8_t *Buf) const { | ... | @@ -433,7 +498,7 @@ void ImportThunkChunkARM::writeTo(uint8_t *Buf) const { |
| 433 | void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const { | 498 | void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const { |
| 434 | int64_t Off = ImpSymbol->getRVA() & 0xfff; | 499 | int64_t Off = ImpSymbol->getRVA() & 0xfff; |
| 435 | memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64)); | 500 | memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64)); |
| 436 | applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA); | 501 | applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA, 12); |
| 437 | applyArm64Ldr(Buf + OutputSectionOff + 4, Off); | 502 | applyArm64Ldr(Buf + OutputSectionOff + 4, Off); |
| 438 | } | 503 | } |
| 439 | 504 | ||
| ... | @@ -453,12 +518,14 @@ void LocalImportChunk::writeTo(uint8_t *Buf) const { | ... | @@ -453,12 +518,14 @@ void LocalImportChunk::writeTo(uint8_t *Buf) const { |
| 453 | } | 518 | } |
| 454 | } | 519 | } |
| 455 | 520 | ||
| 456 | void SEHTableChunk::writeTo(uint8_t *Buf) const { | 521 | void RVATableChunk::writeTo(uint8_t *Buf) const { |
| 457 | ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff); | 522 | ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff); |
| 458 | size_t Cnt = 0; | 523 | size_t Cnt = 0; |
| 459 | for (Defined *D : Syms) | 524 | for (const ChunkAndOffset &CO : Syms) |
| 460 | Begin[Cnt++] = D->getRVA(); | 525 | Begin[Cnt++] = CO.InputChunk->getRVA() + CO.Offset; |
| 461 | std::sort(Begin, Begin + Cnt); | 526 | std::sort(Begin, Begin + Cnt); |
| 527 | assert(std::unique(Begin, Begin + Cnt) == Begin + Cnt && | ||
| 528 | "RVA tables should be de-duplicated"); | ||
| 462 | } | 529 | } |
| 463 | 530 | ||
| 464 | // Windows-specific. This class represents a block in .reloc section. | 531 | // Windows-specific. This class represents a block in .reloc section. |
| ... | @@ -531,5 +598,47 @@ uint8_t Baserel::getDefaultType() { | ... | @@ -531,5 +598,47 @@ uint8_t Baserel::getDefaultType() { |
| 531 | } | 598 | } |
| 532 | } | 599 | } |
| 533 | 600 | ||
| 601 | std::map<uint32_t, MergeChunk *> MergeChunk::Instances; | ||
| 602 | |||
| 603 | MergeChunk::MergeChunk(uint32_t Alignment) | ||
| 604 | : Builder(StringTableBuilder::RAW, Alignment) { | ||
| 605 | this->Alignment = Alignment; | ||
| 606 | } | ||
| 607 | |||
| 608 | void MergeChunk::addSection(SectionChunk *C) { | ||
| 609 | auto *&MC = Instances[C->Alignment]; | ||
| 610 | if (!MC) | ||
| 611 | MC = make<MergeChunk>(C->Alignment); | ||
| 612 | MC->Sections.push_back(C); | ||
| 613 | } | ||
| 614 | |||
| 615 | void MergeChunk::finalizeContents() { | ||
| 616 | for (SectionChunk *C : Sections) | ||
| 617 | if (C->isLive()) | ||
| 618 | Builder.add(toStringRef(C->getContents())); | ||
| 619 | Builder.finalize(); | ||
| 620 | |||
| 621 | for (SectionChunk *C : Sections) { | ||
| 622 | if (!C->isLive()) | ||
| 623 | continue; | ||
| 624 | size_t Off = Builder.getOffset(toStringRef(C->getContents())); | ||
| 625 | C->setOutputSection(Out); | ||
| 626 | C->setRVA(RVA + Off); | ||
| 627 | C->OutputSectionOff = OutputSectionOff + Off; | ||
| 628 | } | ||
| 629 | } | ||
| 630 | |||
| 631 | uint32_t MergeChunk::getOutputCharacteristics() const { | ||
| 632 | return IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA; | ||
| 633 | } | ||
| 634 | |||
| 635 | size_t MergeChunk::getSize() const { | ||
| 636 | return Builder.getSize(); | ||
| 637 | } | ||
| 638 | |||
| 639 | void MergeChunk::writeTo(uint8_t *Buf) const { | ||
| 640 | Builder.write(Buf + OutputSectionOff); | ||
| 641 | } | ||
| 642 | |||
| 534 | } // namespace coff | 643 | } // namespace coff |
| 535 | } // namespace lld | 644 | } // namespace lld |
deps/lld/COFF/Chunks.h+78-14| ... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
| 16 | #include "llvm/ADT/ArrayRef.h" | 16 | #include "llvm/ADT/ArrayRef.h" |
| 17 | #include "llvm/ADT/iterator.h" | 17 | #include "llvm/ADT/iterator.h" |
| 18 | #include "llvm/ADT/iterator_range.h" | 18 | #include "llvm/ADT/iterator_range.h" |
| 19 | #include "llvm/MC/StringTableBuilder.h" | ||
| 19 | #include "llvm/Object/COFF.h" | 20 | #include "llvm/Object/COFF.h" |
| 20 | #include <utility> | 21 | #include <utility> |
| 21 | #include <vector> | 22 | #include <vector> |
| ... | @@ -37,9 +38,11 @@ class ObjFile; | ... | @@ -37,9 +38,11 @@ class ObjFile; |
| 37 | class OutputSection; | 38 | class OutputSection; |
| 38 | class Symbol; | 39 | class Symbol; |
| 39 | 40 | ||
| 40 | // Mask for section types (code, data, bss, disacardable, etc.) | 41 | // Mask for permissions (discardable, writable, readable, executable, etc). |
| 41 | // and permissions (writable, readable or executable). | 42 | const uint32_t PermMask = 0xFE000000; |
| 42 | const uint32_t PermMask = 0xFF0000F0; | 43 | |
| 44 | // Mask for section types (code, data, bss). | ||
| 45 | const uint32_t TypeMask = 0x000000E0; | ||
| 43 | 46 | ||
| 44 | // A Chunk represents a chunk of data that will occupy space in the | 47 | // A Chunk represents a chunk of data that will occupy space in the |
| 45 | // output (if the resolver chose that). It may or may not be backed by | 48 | // output (if the resolver chose that). It may or may not be backed by |
| ... | @@ -60,6 +63,10 @@ public: | ... | @@ -60,6 +63,10 @@ public: |
| 60 | // before calling this function. | 63 | // before calling this function. |
| 61 | virtual void writeTo(uint8_t *Buf) const {} | 64 | virtual void writeTo(uint8_t *Buf) const {} |
| 62 | 65 | ||
| 66 | // Called by the writer after an RVA is assigned, but before calling | ||
| 67 | // getSize(). | ||
| 68 | virtual void finalizeContents() {} | ||
| 69 | |||
| 63 | // The writer sets and uses the addresses. | 70 | // The writer sets and uses the addresses. |
| 64 | uint64_t getRVA() const { return RVA; } | 71 | uint64_t getRVA() const { return RVA; } |
| 65 | void setRVA(uint64_t V) { RVA = V; } | 72 | void setRVA(uint64_t V) { RVA = V; } |
| ... | @@ -70,7 +77,7 @@ public: | ... | @@ -70,7 +77,7 @@ public: |
| 70 | virtual bool hasData() const { return true; } | 77 | virtual bool hasData() const { return true; } |
| 71 | 78 | ||
| 72 | // Returns readable/writable/executable bits. | 79 | // Returns readable/writable/executable bits. |
| 73 | virtual uint32_t getPermissions() const { return 0; } | 80 | virtual uint32_t getOutputCharacteristics() const { return 0; } |
| 74 | 81 | ||
| 75 | // Returns the section name if this is a section chunk. | 82 | // Returns the section name if this is a section chunk. |
| 76 | // It is illegal to call this function on non-section chunks. | 83 | // It is illegal to call this function on non-section chunks. |
| ... | @@ -137,7 +144,7 @@ public: | ... | @@ -137,7 +144,7 @@ public: |
| 137 | ArrayRef<uint8_t> getContents() const; | 144 | ArrayRef<uint8_t> getContents() const; |
| 138 | void writeTo(uint8_t *Buf) const override; | 145 | void writeTo(uint8_t *Buf) const override; |
| 139 | bool hasData() const override; | 146 | bool hasData() const override; |
| 140 | uint32_t getPermissions() const override; | 147 | uint32_t getOutputCharacteristics() const override; |
| 141 | StringRef getSectionName() const override { return SectionName; } | 148 | StringRef getSectionName() const override { return SectionName; } |
| 142 | void getBaserels(std::vector<Baserel> *Res) override; | 149 | void getBaserels(std::vector<Baserel> *Res) override; |
| 143 | bool isCOMDAT() const; | 150 | bool isCOMDAT() const; |
| ... | @@ -208,11 +215,11 @@ public: | ... | @@ -208,11 +215,11 @@ public: |
| 208 | // The COMDAT leader symbol if this is a COMDAT chunk. | 215 | // The COMDAT leader symbol if this is a COMDAT chunk. |
| 209 | DefinedRegular *Sym = nullptr; | 216 | DefinedRegular *Sym = nullptr; |
| 210 | 217 | ||
| 218 | ArrayRef<coff_relocation> Relocs; | ||
| 219 | |||
| 211 | private: | 220 | private: |
| 212 | StringRef SectionName; | 221 | StringRef SectionName; |
| 213 | std::vector<SectionChunk *> AssocChildren; | 222 | std::vector<SectionChunk *> AssocChildren; |
| 214 | llvm::iterator_range<const coff_relocation *> Relocs; | ||
| 215 | size_t NumRelocs; | ||
| 216 | 223 | ||
| 217 | // Used by the garbage collector. | 224 | // Used by the garbage collector. |
| 218 | bool Live; | 225 | bool Live; |
| ... | @@ -222,13 +229,40 @@ private: | ... | @@ -222,13 +229,40 @@ private: |
| 222 | uint32_t Class[2] = {0, 0}; | 229 | uint32_t Class[2] = {0, 0}; |
| 223 | }; | 230 | }; |
| 224 | 231 | ||
| 232 | // This class is used to implement an lld-specific feature (not implemented in | ||
| 233 | // MSVC) that minimizes the output size by finding string literals sharing tail | ||
| 234 | // parts and merging them. | ||
| 235 | // | ||
| 236 | // If string tail merging is enabled and a section is identified as containing a | ||
| 237 | // string literal, it is added to a MergeChunk with an appropriate alignment. | ||
| 238 | // The MergeChunk then tail merges the strings using the StringTableBuilder | ||
| 239 | // class and assigns RVAs and section offsets to each of the member chunks based | ||
| 240 | // on the offsets assigned by the StringTableBuilder. | ||
| 241 | class MergeChunk : public Chunk { | ||
| 242 | public: | ||
| 243 | MergeChunk(uint32_t Alignment); | ||
| 244 | static void addSection(SectionChunk *C); | ||
| 245 | void finalizeContents() override; | ||
| 246 | |||
| 247 | uint32_t getOutputCharacteristics() const override; | ||
| 248 | StringRef getSectionName() const override { return ".rdata"; } | ||
| 249 | size_t getSize() const override; | ||
| 250 | void writeTo(uint8_t *Buf) const override; | ||
| 251 | |||
| 252 | static std::map<uint32_t, MergeChunk *> Instances; | ||
| 253 | std::vector<SectionChunk *> Sections; | ||
| 254 | |||
| 255 | private: | ||
| 256 | llvm::StringTableBuilder Builder; | ||
| 257 | }; | ||
| 258 | |||
| 225 | // A chunk for common symbols. Common chunks don't have actual data. | 259 | // A chunk for common symbols. Common chunks don't have actual data. |
| 226 | class CommonChunk : public Chunk { | 260 | class CommonChunk : public Chunk { |
| 227 | public: | 261 | public: |
| 228 | CommonChunk(const COFFSymbolRef Sym); | 262 | CommonChunk(const COFFSymbolRef Sym); |
| 229 | size_t getSize() const override { return Sym.getValue(); } | 263 | size_t getSize() const override { return Sym.getValue(); } |
| 230 | bool hasData() const override { return false; } | 264 | bool hasData() const override { return false; } |
| 231 | uint32_t getPermissions() const override; | 265 | uint32_t getOutputCharacteristics() const override; |
| 232 | StringRef getSectionName() const override { return ".bss"; } | 266 | StringRef getSectionName() const override { return ".bss"; } |
| 233 | 267 | ||
| 234 | private: | 268 | private: |
| ... | @@ -320,17 +354,41 @@ private: | ... | @@ -320,17 +354,41 @@ private: |
| 320 | Defined *Sym; | 354 | Defined *Sym; |
| 321 | }; | 355 | }; |
| 322 | 356 | ||
| 323 | // Windows-specific. | 357 | // Duplicate RVAs are not allowed in RVA tables, so unique symbols by chunk and |
| 324 | // A chunk for SEH table which contains RVAs of safe exception handler | 358 | // offset into the chunk. Order does not matter as the RVA table will be sorted |
| 325 | // functions. x86-only. | 359 | // later. |
| 326 | class SEHTableChunk : public Chunk { | 360 | struct ChunkAndOffset { |
| 361 | Chunk *InputChunk; | ||
| 362 | uint32_t Offset; | ||
| 363 | |||
| 364 | struct DenseMapInfo { | ||
| 365 | static ChunkAndOffset getEmptyKey() { | ||
| 366 | return {llvm::DenseMapInfo<Chunk *>::getEmptyKey(), 0}; | ||
| 367 | } | ||
| 368 | static ChunkAndOffset getTombstoneKey() { | ||
| 369 | return {llvm::DenseMapInfo<Chunk *>::getTombstoneKey(), 0}; | ||
| 370 | } | ||
| 371 | static unsigned getHashValue(const ChunkAndOffset &CO) { | ||
| 372 | return llvm::DenseMapInfo<std::pair<Chunk *, uint32_t>>::getHashValue( | ||
| 373 | {CO.InputChunk, CO.Offset}); | ||
| 374 | } | ||
| 375 | static bool isEqual(const ChunkAndOffset &LHS, const ChunkAndOffset &RHS) { | ||
| 376 | return LHS.InputChunk == RHS.InputChunk && LHS.Offset == RHS.Offset; | ||
| 377 | } | ||
| 378 | }; | ||
| 379 | }; | ||
| 380 | |||
| 381 | using SymbolRVASet = llvm::DenseSet<ChunkAndOffset>; | ||
| 382 | |||
| 383 | // Table which contains symbol RVAs. Used for /safeseh and /guard:cf. | ||
| 384 | class RVATableChunk : public Chunk { | ||
| 327 | public: | 385 | public: |
| 328 | explicit SEHTableChunk(std::set<Defined *> S) : Syms(std::move(S)) {} | 386 | explicit RVATableChunk(SymbolRVASet S) : Syms(std::move(S)) {} |
| 329 | size_t getSize() const override { return Syms.size() * 4; } | 387 | size_t getSize() const override { return Syms.size() * 4; } |
| 330 | void writeTo(uint8_t *Buf) const override; | 388 | void writeTo(uint8_t *Buf) const override; |
| 331 | 389 | ||
| 332 | private: | 390 | private: |
| 333 | std::set<Defined *> Syms; | 391 | SymbolRVASet Syms; |
| 334 | }; | 392 | }; |
| 335 | 393 | ||
| 336 | // Windows-specific. | 394 | // Windows-specific. |
| ... | @@ -362,4 +420,10 @@ void applyBranch24T(uint8_t *Off, int32_t V); | ... | @@ -362,4 +420,10 @@ void applyBranch24T(uint8_t *Off, int32_t V); |
| 362 | } // namespace coff | 420 | } // namespace coff |
| 363 | } // namespace lld | 421 | } // namespace lld |
| 364 | 422 | ||
| 423 | namespace llvm { | ||
| 424 | template <> | ||
| 425 | struct DenseMapInfo<lld::coff::ChunkAndOffset> | ||
| 426 | : lld::coff::ChunkAndOffset::DenseMapInfo {}; | ||
| 427 | } | ||
| 428 | |||
| 365 | #endif | 429 | #endif |
deps/lld/COFF/Config.h+27-3| ... | @@ -10,6 +10,7 @@ | ... | @@ -10,6 +10,7 @@ |
| 10 | #ifndef LLD_COFF_CONFIG_H | 10 | #ifndef LLD_COFF_CONFIG_H |
| 11 | #define LLD_COFF_CONFIG_H | 11 | #define LLD_COFF_CONFIG_H |
| 12 | 12 | ||
| 13 | #include "llvm/ADT/StringMap.h" | ||
| 13 | #include "llvm/ADT/StringRef.h" | 14 | #include "llvm/ADT/StringRef.h" |
| 14 | #include "llvm/Object/COFF.h" | 15 | #include "llvm/Object/COFF.h" |
| 15 | #include "llvm/Support/CachePruning.h" | 16 | #include "llvm/Support/CachePruning.h" |
| ... | @@ -71,6 +72,12 @@ enum class DebugType { | ... | @@ -71,6 +72,12 @@ enum class DebugType { |
| 71 | Fixup = 0x4, /// Relocation Table | 72 | Fixup = 0x4, /// Relocation Table |
| 72 | }; | 73 | }; |
| 73 | 74 | ||
| 75 | enum class GuardCFLevel { | ||
| 76 | Off, | ||
| 77 | NoLongJmp, // Emit gfids but no longjmp tables | ||
| 78 | Full, // Enable all protections. | ||
| 79 | }; | ||
| 80 | |||
| 74 | // Global configuration. | 81 | // Global configuration. |
| 75 | struct Configuration { | 82 | struct Configuration { |
| 76 | enum ManifestKind { SideBySide, Embed, No }; | 83 | enum ManifestKind { SideBySide, Embed, No }; |
| ... | @@ -85,13 +92,19 @@ struct Configuration { | ... | @@ -85,13 +92,19 @@ struct Configuration { |
| 85 | std::string ImportName; | 92 | std::string ImportName; |
| 86 | bool DoGC = true; | 93 | bool DoGC = true; |
| 87 | bool DoICF = true; | 94 | bool DoICF = true; |
| 95 | bool TailMerge; | ||
| 88 | bool Relocatable = true; | 96 | bool Relocatable = true; |
| 89 | bool Force = false; | 97 | bool Force = false; |
| 90 | bool Debug = false; | 98 | bool Debug = false; |
| 91 | bool DebugDwarf = false; | 99 | bool DebugDwarf = false; |
| 92 | bool DebugGHashes = false; | 100 | bool DebugGHashes = false; |
| 101 | bool DebugSymtab = false; | ||
| 102 | bool ShowTiming = false; | ||
| 93 | unsigned DebugTypes = static_cast<unsigned>(DebugType::None); | 103 | unsigned DebugTypes = static_cast<unsigned>(DebugType::None); |
| 104 | std::vector<std::string> NatvisFiles; | ||
| 105 | llvm::SmallString<128> PDBAltPath; | ||
| 94 | llvm::SmallString<128> PDBPath; | 106 | llvm::SmallString<128> PDBPath; |
| 107 | llvm::SmallString<128> PDBSourcePath; | ||
| 95 | std::vector<llvm::StringRef> Argv; | 108 | std::vector<llvm::StringRef> Argv; |
| 96 | 109 | ||
| 97 | // Symbols in this set are considered as live by the garbage collector. | 110 | // Symbols in this set are considered as live by the garbage collector. |
| ... | @@ -110,15 +123,18 @@ struct Configuration { | ... | @@ -110,15 +123,18 @@ struct Configuration { |
| 110 | 123 | ||
| 111 | bool SaveTemps = false; | 124 | bool SaveTemps = false; |
| 112 | 125 | ||
| 126 | // /guard:cf | ||
| 127 | GuardCFLevel GuardCF = GuardCFLevel::Off; | ||
| 128 | |||
| 113 | // Used for SafeSEH. | 129 | // Used for SafeSEH. |
| 114 | Symbol *SEHTable = nullptr; | 130 | Symbol *SEHTable = nullptr; |
| 115 | Symbol *SEHCount = nullptr; | 131 | Symbol *SEHCount = nullptr; |
| 116 | 132 | ||
| 117 | // Used for /opt:lldlto=N | 133 | // Used for /opt:lldlto=N |
| 118 | unsigned LTOOptLevel = 2; | 134 | unsigned LTOO = 2; |
| 119 | 135 | ||
| 120 | // Used for /opt:lldltojobs=N | 136 | // Used for /opt:lldltojobs=N |
| 121 | unsigned LTOJobs = 0; | 137 | unsigned ThinLTOJobs = 0; |
| 122 | // Used for /opt:lldltopartitions=N | 138 | // Used for /opt:lldltopartitions=N |
| 123 | unsigned LTOPartitions = 1; | 139 | unsigned LTOPartitions = 1; |
| 124 | 140 | ||
| ... | @@ -152,6 +168,9 @@ struct Configuration { | ... | @@ -152,6 +168,9 @@ struct Configuration { |
| 152 | // Used for /alternatename. | 168 | // Used for /alternatename. |
| 153 | std::map<StringRef, StringRef> AlternateNames; | 169 | std::map<StringRef, StringRef> AlternateNames; |
| 154 | 170 | ||
| 171 | // Used for /order. | ||
| 172 | llvm::StringMap<int> Order; | ||
| 173 | |||
| 155 | // Used for /lldmap. | 174 | // Used for /lldmap. |
| 156 | std::string MapFile; | 175 | std::string MapFile; |
| 157 | 176 | ||
| ... | @@ -164,7 +183,7 @@ struct Configuration { | ... | @@ -164,7 +183,7 @@ struct Configuration { |
| 164 | uint32_t MinorImageVersion = 0; | 183 | uint32_t MinorImageVersion = 0; |
| 165 | uint32_t MajorOSVersion = 6; | 184 | uint32_t MajorOSVersion = 6; |
| 166 | uint32_t MinorOSVersion = 0; | 185 | uint32_t MinorOSVersion = 0; |
| 167 | bool CanExitEarly = false; | 186 | uint32_t Timestamp = 0; |
| 168 | bool DynamicBase = true; | 187 | bool DynamicBase = true; |
| 169 | bool AllowBind = true; | 188 | bool AllowBind = true; |
| 170 | bool NxCompat = true; | 189 | bool NxCompat = true; |
| ... | @@ -174,7 +193,12 @@ struct Configuration { | ... | @@ -174,7 +193,12 @@ struct Configuration { |
| 174 | bool HighEntropyVA = false; | 193 | bool HighEntropyVA = false; |
| 175 | bool AppContainer = false; | 194 | bool AppContainer = false; |
| 176 | bool MinGW = false; | 195 | bool MinGW = false; |
| 196 | bool WarnMissingOrderSymbol = true; | ||
| 177 | bool WarnLocallyDefinedImported = true; | 197 | bool WarnLocallyDefinedImported = true; |
| 198 | bool Incremental = true; | ||
| 199 | bool IntegrityCheck = false; | ||
| 200 | bool KillAt = false; | ||
| 201 | bool Repro = false; | ||
| 178 | }; | 202 | }; |
| 179 | 203 | ||
| 180 | extern Configuration *Config; | 204 | extern Configuration *Config; |
deps/lld/COFF/DLL.cpp+1-1| ... | @@ -18,8 +18,8 @@ | ... | @@ -18,8 +18,8 @@ |
| 18 | // | 18 | // |
| 19 | //===----------------------------------------------------------------------===// | 19 | //===----------------------------------------------------------------------===// |
| 20 | 20 | ||
| 21 | #include "Chunks.h" | ||
| 22 | #include "DLL.h" | 21 | #include "DLL.h" |
| 22 | #include "Chunks.h" | ||
| 23 | #include "llvm/Object/COFF.h" | 23 | #include "llvm/Object/COFF.h" |
| 24 | #include "llvm/Support/Endian.h" | 24 | #include "llvm/Support/Endian.h" |
| 25 | #include "llvm/Support/Path.h" | 25 | #include "llvm/Support/Path.h" |
deps/lld/COFF/DLL.h+5| ... | @@ -76,6 +76,11 @@ class EdataContents { | ... | @@ -76,6 +76,11 @@ class EdataContents { |
| 76 | public: | 76 | public: |
| 77 | EdataContents(); | 77 | EdataContents(); |
| 78 | std::vector<Chunk *> Chunks; | 78 | std::vector<Chunk *> Chunks; |
| 79 | |||
| 80 | uint64_t getRVA() { return Chunks[0]->getRVA(); } | ||
| 81 | uint64_t getSize() { | ||
| 82 | return Chunks.back()->getRVA() + Chunks.back()->getSize() - getRVA(); | ||
| 83 | } | ||
| 79 | }; | 84 | }; |
| 80 | 85 | ||
| 81 | } // namespace coff | 86 | } // namespace coff |
deps/lld/COFF/Driver.cpp+340-86| ... | @@ -9,14 +9,18 @@ | ... | @@ -9,14 +9,18 @@ |
| 9 | 9 | ||
| 10 | #include "Driver.h" | 10 | #include "Driver.h" |
| 11 | #include "Config.h" | 11 | #include "Config.h" |
| 12 | #include "ICF.h" | ||
| 12 | #include "InputFiles.h" | 13 | #include "InputFiles.h" |
| 14 | #include "MarkLive.h" | ||
| 13 | #include "MinGW.h" | 15 | #include "MinGW.h" |
| 14 | #include "SymbolTable.h" | 16 | #include "SymbolTable.h" |
| 15 | #include "Symbols.h" | 17 | #include "Symbols.h" |
| 16 | #include "Writer.h" | 18 | #include "Writer.h" |
| 19 | #include "lld/Common/Args.h" | ||
| 17 | #include "lld/Common/Driver.h" | 20 | #include "lld/Common/Driver.h" |
| 18 | #include "lld/Common/ErrorHandler.h" | 21 | #include "lld/Common/ErrorHandler.h" |
| 19 | #include "lld/Common/Memory.h" | 22 | #include "lld/Common/Memory.h" |
| 23 | #include "lld/Common/Timer.h" | ||
| 20 | #include "lld/Common/Version.h" | 24 | #include "lld/Common/Version.h" |
| 21 | #include "llvm/ADT/Optional.h" | 25 | #include "llvm/ADT/Optional.h" |
| 22 | #include "llvm/ADT/StringSwitch.h" | 26 | #include "llvm/ADT/StringSwitch.h" |
| ... | @@ -35,9 +39,8 @@ | ... | @@ -35,9 +39,8 @@ |
| 35 | #include "llvm/Support/raw_ostream.h" | 39 | #include "llvm/Support/raw_ostream.h" |
| 36 | #include "llvm/ToolDrivers/llvm-lib/LibDriver.h" | 40 | #include "llvm/ToolDrivers/llvm-lib/LibDriver.h" |
| 37 | #include <algorithm> | 41 | #include <algorithm> |
| 38 | #include <memory> | ||
| 39 | |||
| 40 | #include <future> | 42 | #include <future> |
| 43 | #include <memory> | ||
| 41 | 44 | ||
| 42 | using namespace llvm; | 45 | using namespace llvm; |
| 43 | using namespace llvm::object; | 46 | using namespace llvm::object; |
| ... | @@ -47,20 +50,20 @@ using llvm::sys::Process; | ... | @@ -47,20 +50,20 @@ using llvm::sys::Process; |
| 47 | namespace lld { | 50 | namespace lld { |
| 48 | namespace coff { | 51 | namespace coff { |
| 49 | 52 | ||
| 53 | static Timer InputFileTimer("Input File Reading", Timer::root()); | ||
| 54 | |||
| 50 | Configuration *Config; | 55 | Configuration *Config; |
| 51 | LinkerDriver *Driver; | 56 | LinkerDriver *Driver; |
| 52 | 57 | ||
| 53 | bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) { | 58 | bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) { |
| 54 | errorHandler().LogName = Args[0]; | 59 | errorHandler().LogName = sys::path::filename(Args[0]); |
| 55 | errorHandler().ErrorOS = &Diag; | 60 | errorHandler().ErrorOS = &Diag; |
| 56 | errorHandler().ColorDiagnostics = Diag.has_colors(); | 61 | errorHandler().ColorDiagnostics = Diag.has_colors(); |
| 57 | errorHandler().ErrorLimitExceededMsg = | 62 | errorHandler().ErrorLimitExceededMsg = |
| 58 | "too many errors emitted, stopping now" | 63 | "too many errors emitted, stopping now" |
| 59 | " (use /ERRORLIMIT:0 to see all errors)"; | 64 | " (use /errorlimit:0 to see all errors)"; |
| 60 | errorHandler().ExitEarly = CanExitEarly; | 65 | errorHandler().ExitEarly = CanExitEarly; |
| 61 | Config = make<Configuration>(); | 66 | Config = make<Configuration>(); |
| 62 | Config->Argv = {Args.begin(), Args.end()}; | ||
| 63 | Config->CanExitEarly = CanExitEarly; | ||
| 64 | 67 | ||
| 65 | Symtab = make<SymbolTable>(); | 68 | Symtab = make<SymbolTable>(); |
| 66 | 69 | ||
| ... | @@ -96,7 +99,7 @@ typedef std::pair<std::unique_ptr<MemoryBuffer>, std::error_code> MBErrPair; | ... | @@ -96,7 +99,7 @@ typedef std::pair<std::unique_ptr<MemoryBuffer>, std::error_code> MBErrPair; |
| 96 | // Create a std::future that opens and maps a file using the best strategy for | 99 | // Create a std::future that opens and maps a file using the best strategy for |
| 97 | // the host platform. | 100 | // the host platform. |
| 98 | static std::future<MBErrPair> createFutureForFile(std::string Path) { | 101 | static std::future<MBErrPair> createFutureForFile(std::string Path) { |
| 99 | #if LLVM_ON_WIN32 | 102 | #if _WIN32 |
| 100 | // On Windows, file I/O is relatively slow so it is best to do this | 103 | // On Windows, file I/O is relatively slow so it is best to do this |
| 101 | // asynchronously. | 104 | // asynchronously. |
| 102 | auto Strategy = std::launch::async; | 105 | auto Strategy = std::launch::async; |
| ... | @@ -104,7 +107,9 @@ static std::future<MBErrPair> createFutureForFile(std::string Path) { | ... | @@ -104,7 +107,9 @@ static std::future<MBErrPair> createFutureForFile(std::string Path) { |
| 104 | auto Strategy = std::launch::deferred; | 107 | auto Strategy = std::launch::deferred; |
| 105 | #endif | 108 | #endif |
| 106 | return std::async(Strategy, [=]() { | 109 | return std::async(Strategy, [=]() { |
| 107 | auto MBOrErr = MemoryBuffer::getFile(Path); | 110 | auto MBOrErr = MemoryBuffer::getFile(Path, |
| 111 | /*FileSize*/ -1, | ||
| 112 | /*RequiresNullTerminator*/ false); | ||
| 108 | if (!MBOrErr) | 113 | if (!MBOrErr) |
| 109 | return MBErrPair{nullptr, MBOrErr.getError()}; | 114 | return MBErrPair{nullptr, MBOrErr.getError()}; |
| 110 | return MBErrPair{std::move(*MBOrErr), std::error_code()}; | 115 | return MBErrPair{std::move(*MBOrErr), std::error_code()}; |
| ... | @@ -123,39 +128,46 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) { | ... | @@ -123,39 +128,46 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) { |
| 123 | 128 | ||
| 124 | void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB, | 129 | void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB, |
| 125 | bool WholeArchive) { | 130 | bool WholeArchive) { |
| 131 | StringRef Filename = MB->getBufferIdentifier(); | ||
| 132 | |||
| 126 | MemoryBufferRef MBRef = takeBuffer(std::move(MB)); | 133 | MemoryBufferRef MBRef = takeBuffer(std::move(MB)); |
| 127 | FilePaths.push_back(MBRef.getBufferIdentifier()); | 134 | FilePaths.push_back(Filename); |
| 128 | 135 | ||
| 129 | // File type is detected by contents, not by file extension. | 136 | // File type is detected by contents, not by file extension. |
| 130 | switch (identify_magic(MBRef.getBuffer())) { | 137 | switch (identify_magic(MBRef.getBuffer())) { |
| 131 | case file_magic::windows_resource: | 138 | case file_magic::windows_resource: |
| 132 | Resources.push_back(MBRef); | 139 | Resources.push_back(MBRef); |
| 133 | break; | 140 | break; |
| 134 | |||
| 135 | case file_magic::archive: | 141 | case file_magic::archive: |
| 136 | if (WholeArchive) { | 142 | if (WholeArchive) { |
| 137 | std::unique_ptr<Archive> File = | 143 | std::unique_ptr<Archive> File = |
| 138 | CHECK(Archive::create(MBRef), | 144 | CHECK(Archive::create(MBRef), Filename + ": failed to parse archive"); |
| 139 | MBRef.getBufferIdentifier() + ": failed to parse archive"); | ||
| 140 | 145 | ||
| 141 | for (MemoryBufferRef M : getArchiveMembers(File.get())) | 146 | for (MemoryBufferRef M : getArchiveMembers(File.get())) |
| 142 | addArchiveBuffer(M, "<whole-archive>", MBRef.getBufferIdentifier()); | 147 | addArchiveBuffer(M, "<whole-archive>", Filename); |
| 143 | return; | 148 | return; |
| 144 | } | 149 | } |
| 145 | Symtab->addFile(make<ArchiveFile>(MBRef)); | 150 | Symtab->addFile(make<ArchiveFile>(MBRef)); |
| 146 | break; | 151 | break; |
| 147 | |||
| 148 | case file_magic::bitcode: | 152 | case file_magic::bitcode: |
| 149 | Symtab->addFile(make<BitcodeFile>(MBRef)); | 153 | Symtab->addFile(make<BitcodeFile>(MBRef)); |
| 150 | break; | 154 | break; |
| 151 | 155 | case file_magic::coff_object: | |
| 156 | case file_magic::coff_import_library: | ||
| 157 | Symtab->addFile(make<ObjFile>(MBRef)); | ||
| 158 | break; | ||
| 152 | case file_magic::coff_cl_gl_object: | 159 | case file_magic::coff_cl_gl_object: |
| 153 | error(MBRef.getBufferIdentifier() + ": is not a native COFF file. " | 160 | error(Filename + ": is not a native COFF file. Recompile without /GL"); |
| 154 | "Recompile without /GL"); | ||
| 155 | break; | 161 | break; |
| 156 | 162 | case file_magic::pecoff_executable: | |
| 163 | if (Filename.endswith_lower(".dll")) { | ||
| 164 | error(Filename + ": bad file type. Did you specify a DLL instead of an " | ||
| 165 | "import library?"); | ||
| 166 | break; | ||
| 167 | } | ||
| 168 | LLVM_FALLTHROUGH; | ||
| 157 | default: | 169 | default: |
| 158 | Symtab->addFile(make<ObjFile>(MBRef)); | 170 | error(MBRef.getBufferIdentifier() + ": unknown file type"); |
| 159 | break; | 171 | break; |
| 160 | } | 172 | } |
| 161 | } | 173 | } |
| ... | @@ -231,7 +243,29 @@ static bool isDecorated(StringRef Sym) { | ... | @@ -231,7 +243,29 @@ static bool isDecorated(StringRef Sym) { |
| 231 | void LinkerDriver::parseDirectives(StringRef S) { | 243 | void LinkerDriver::parseDirectives(StringRef S) { |
| 232 | ArgParser Parser; | 244 | ArgParser Parser; |
| 233 | // .drectve is always tokenized using Windows shell rules. | 245 | // .drectve is always tokenized using Windows shell rules. |
| 234 | opt::InputArgList Args = Parser.parseDirectives(S); | 246 | // /EXPORT: option can appear too many times, processing in fastpath. |
| 247 | opt::InputArgList Args; | ||
| 248 | std::vector<StringRef> Exports; | ||
| 249 | std::tie(Args, Exports) = Parser.parseDirectives(S); | ||
| 250 | |||
| 251 | for (StringRef E : Exports) { | ||
| 252 | // If a common header file contains dllexported function | ||
| 253 | // declarations, many object files may end up with having the | ||
| 254 | // same /EXPORT options. In order to save cost of parsing them, | ||
| 255 | // we dedup them first. | ||
| 256 | if (!DirectivesExports.insert(E).second) | ||
| 257 | continue; | ||
| 258 | |||
| 259 | Export Exp = parseExport(E); | ||
| 260 | if (Config->Machine == I386 && Config->MinGW) { | ||
| 261 | if (!isDecorated(Exp.Name)) | ||
| 262 | Exp.Name = Saver.save("_" + Exp.Name); | ||
| 263 | if (!Exp.ExtName.empty() && !isDecorated(Exp.ExtName)) | ||
| 264 | Exp.ExtName = Saver.save("_" + Exp.ExtName); | ||
| 265 | } | ||
| 266 | Exp.Directives = true; | ||
| 267 | Config->Exports.push_back(Exp); | ||
| 268 | } | ||
| 235 | 269 | ||
| 236 | for (auto *Arg : Args) { | 270 | for (auto *Arg : Args) { |
| 237 | switch (Arg->getOption().getUnaliasedOption().getID()) { | 271 | switch (Arg->getOption().getUnaliasedOption().getID()) { |
| ... | @@ -248,25 +282,6 @@ void LinkerDriver::parseDirectives(StringRef S) { | ... | @@ -248,25 +282,6 @@ void LinkerDriver::parseDirectives(StringRef S) { |
| 248 | case OPT_entry: | 282 | case OPT_entry: |
| 249 | Config->Entry = addUndefined(mangle(Arg->getValue())); | 283 | Config->Entry = addUndefined(mangle(Arg->getValue())); |
| 250 | break; | 284 | break; |
| 251 | case OPT_export: { | ||
| 252 | // If a common header file contains dllexported function | ||
| 253 | // declarations, many object files may end up with having the | ||
| 254 | // same /EXPORT options. In order to save cost of parsing them, | ||
| 255 | // we dedup them first. | ||
| 256 | if (!DirectivesExports.insert(Arg->getValue()).second) | ||
| 257 | break; | ||
| 258 | |||
| 259 | Export E = parseExport(Arg->getValue()); | ||
| 260 | if (Config->Machine == I386 && Config->MinGW) { | ||
| 261 | if (!isDecorated(E.Name)) | ||
| 262 | E.Name = Saver.save("_" + E.Name); | ||
| 263 | if (!E.ExtName.empty() && !isDecorated(E.ExtName)) | ||
| 264 | E.ExtName = Saver.save("_" + E.ExtName); | ||
| 265 | } | ||
| 266 | E.Directives = true; | ||
| 267 | Config->Exports.push_back(E); | ||
| 268 | break; | ||
| 269 | } | ||
| 270 | case OPT_failifmismatch: | 285 | case OPT_failifmismatch: |
| 271 | checkFailIfMismatch(Arg->getValue()); | 286 | checkFailIfMismatch(Arg->getValue()); |
| 272 | break; | 287 | break; |
| ... | @@ -319,13 +334,24 @@ StringRef LinkerDriver::doFindFile(StringRef Filename) { | ... | @@ -319,13 +334,24 @@ StringRef LinkerDriver::doFindFile(StringRef Filename) { |
| 319 | return Filename; | 334 | return Filename; |
| 320 | } | 335 | } |
| 321 | 336 | ||
| 337 | static Optional<sys::fs::UniqueID> getUniqueID(StringRef Path) { | ||
| 338 | sys::fs::UniqueID Ret; | ||
| 339 | if (sys::fs::getUniqueID(Path, Ret)) | ||
| 340 | return None; | ||
| 341 | return Ret; | ||
| 342 | } | ||
| 343 | |||
| 322 | // Resolves a file path. This never returns the same path | 344 | // Resolves a file path. This never returns the same path |
| 323 | // (in that case, it returns None). | 345 | // (in that case, it returns None). |
| 324 | Optional<StringRef> LinkerDriver::findFile(StringRef Filename) { | 346 | Optional<StringRef> LinkerDriver::findFile(StringRef Filename) { |
| 325 | StringRef Path = doFindFile(Filename); | 347 | StringRef Path = doFindFile(Filename); |
| 326 | bool Seen = !VisitedFiles.insert(Path.lower()).second; | 348 | |
| 327 | if (Seen) | 349 | if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) { |
| 328 | return None; | 350 | bool Seen = !VisitedFiles.insert(*ID).second; |
| 351 | if (Seen) | ||
| 352 | return None; | ||
| 353 | } | ||
| 354 | |||
| 329 | if (Path.endswith_lower(".lib")) | 355 | if (Path.endswith_lower(".lib")) |
| 330 | VisitedLibs.insert(sys::path::filename(Path)); | 356 | VisitedLibs.insert(sys::path::filename(Path)); |
| 331 | return Path; | 357 | return Path; |
| ... | @@ -348,11 +374,14 @@ Optional<StringRef> LinkerDriver::findLib(StringRef Filename) { | ... | @@ -348,11 +374,14 @@ Optional<StringRef> LinkerDriver::findLib(StringRef Filename) { |
| 348 | return None; | 374 | return None; |
| 349 | if (!VisitedLibs.insert(Filename.lower()).second) | 375 | if (!VisitedLibs.insert(Filename.lower()).second) |
| 350 | return None; | 376 | return None; |
| 377 | |||
| 351 | StringRef Path = doFindLib(Filename); | 378 | StringRef Path = doFindLib(Filename); |
| 352 | if (Config->NoDefaultLibs.count(Path)) | 379 | if (Config->NoDefaultLibs.count(Path)) |
| 353 | return None; | 380 | return None; |
| 354 | if (!VisitedFiles.insert(Path.lower()).second) | 381 | |
| 355 | return None; | 382 | if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) |
| 383 | if (!VisitedFiles.insert(*ID).second) | ||
| 384 | return None; | ||
| 356 | return Path; | 385 | return Path; |
| 357 | } | 386 | } |
| 358 | 387 | ||
| ... | @@ -387,7 +416,24 @@ StringRef LinkerDriver::mangle(StringRef Sym) { | ... | @@ -387,7 +416,24 @@ StringRef LinkerDriver::mangle(StringRef Sym) { |
| 387 | } | 416 | } |
| 388 | 417 | ||
| 389 | // Windows specific -- find default entry point name. | 418 | // Windows specific -- find default entry point name. |
| 419 | // | ||
| 420 | // There are four different entry point functions for Windows executables, | ||
| 421 | // each of which corresponds to a user-defined "main" function. This function | ||
| 422 | // infers an entry point from a user-defined "main" function. | ||
| 390 | StringRef LinkerDriver::findDefaultEntry() { | 423 | StringRef LinkerDriver::findDefaultEntry() { |
| 424 | // As a special case, if /nodefaultlib is given, we directly look for an | ||
| 425 | // entry point. This is because, if no default library is linked, users | ||
| 426 | // need to define an entry point instead of a "main". | ||
| 427 | if (Config->NoDefaultLibAll) { | ||
| 428 | for (StringRef S : {"mainCRTStartup", "wmainCRTStartup", | ||
| 429 | "WinMainCRTStartup", "wWinMainCRTStartup"}) { | ||
| 430 | StringRef Entry = Symtab->findMangle(S); | ||
| 431 | if (!Entry.empty() && !isa<Undefined>(Symtab->find(Entry))) | ||
| 432 | return mangle(S); | ||
| 433 | } | ||
| 434 | return ""; | ||
| 435 | } | ||
| 436 | |||
| 391 | // User-defined main functions and their corresponding entry points. | 437 | // User-defined main functions and their corresponding entry points. |
| 392 | static const char *Entries[][2] = { | 438 | static const char *Entries[][2] = { |
| 393 | {"main", "mainCRTStartup"}, | 439 | {"main", "mainCRTStartup"}, |
| ... | @@ -537,10 +583,49 @@ static void createImportLibrary(bool AsLib) { | ... | @@ -537,10 +583,49 @@ static void createImportLibrary(bool AsLib) { |
| 537 | Exports.push_back(E2); | 583 | Exports.push_back(E2); |
| 538 | } | 584 | } |
| 539 | 585 | ||
| 540 | auto E = writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports, | 586 | auto HandleError = [](Error &&E) { |
| 541 | Config->Machine, false); | 587 | handleAllErrors(std::move(E), |
| 542 | handleAllErrors(std::move(E), | 588 | [](ErrorInfoBase &EIB) { error(EIB.message()); }); |
| 543 | [&](ErrorInfoBase &EIB) { error(EIB.message()); }); | 589 | }; |
| 590 | std::string LibName = getImportName(AsLib); | ||
| 591 | std::string Path = getImplibPath(); | ||
| 592 | |||
| 593 | if (!Config->Incremental) { | ||
| 594 | HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine, | ||
| 595 | Config->MinGW)); | ||
| 596 | return; | ||
| 597 | } | ||
| 598 | |||
| 599 | // If the import library already exists, replace it only if the contents | ||
| 600 | // have changed. | ||
| 601 | ErrorOr<std::unique_ptr<MemoryBuffer>> OldBuf = MemoryBuffer::getFile( | ||
| 602 | Path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false); | ||
| 603 | if (!OldBuf) { | ||
| 604 | HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine, | ||
| 605 | Config->MinGW)); | ||
| 606 | return; | ||
| 607 | } | ||
| 608 | |||
| 609 | SmallString<128> TmpName; | ||
| 610 | if (std::error_code EC = | ||
| 611 | sys::fs::createUniqueFile(Path + ".tmp-%%%%%%%%.lib", TmpName)) | ||
| 612 | fatal("cannot create temporary file for import library " + Path + ": " + | ||
| 613 | EC.message()); | ||
| 614 | |||
| 615 | if (Error E = writeImportLibrary(LibName, TmpName, Exports, Config->Machine, | ||
| 616 | Config->MinGW)) { | ||
| 617 | HandleError(std::move(E)); | ||
| 618 | return; | ||
| 619 | } | ||
| 620 | |||
| 621 | std::unique_ptr<MemoryBuffer> NewBuf = check(MemoryBuffer::getFile( | ||
| 622 | TmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false)); | ||
| 623 | if ((*OldBuf)->getBuffer() != NewBuf->getBuffer()) { | ||
| 624 | OldBuf->reset(); | ||
| 625 | HandleError(errorCodeToError(sys::fs::rename(TmpName, Path))); | ||
| 626 | } else { | ||
| 627 | sys::fs::remove(TmpName); | ||
| 628 | } | ||
| 544 | } | 629 | } |
| 545 | 630 | ||
| 546 | static void parseModuleDefs(StringRef Path) { | 631 | static void parseModuleDefs(StringRef Path) { |
| ... | @@ -573,9 +658,18 @@ static void parseModuleDefs(StringRef Path) { | ... | @@ -573,9 +658,18 @@ static void parseModuleDefs(StringRef Path) { |
| 573 | 658 | ||
| 574 | for (COFFShortExport E1 : M.Exports) { | 659 | for (COFFShortExport E1 : M.Exports) { |
| 575 | Export E2; | 660 | Export E2; |
| 661 | // In simple cases, only Name is set. Renamed exports are parsed | ||
| 662 | // and set as "ExtName = Name". If Name has the form "OtherDll.Func", | ||
| 663 | // it shouldn't be a normal exported function but a forward to another | ||
| 664 | // DLL instead. This is supported by both MS and GNU linkers. | ||
| 665 | if (E1.ExtName != E1.Name && StringRef(E1.Name).contains('.')) { | ||
| 666 | E2.Name = Saver.save(E1.ExtName); | ||
| 667 | E2.ForwardTo = Saver.save(E1.Name); | ||
| 668 | Config->Exports.push_back(E2); | ||
| 669 | continue; | ||
| 670 | } | ||
| 576 | E2.Name = Saver.save(E1.Name); | 671 | E2.Name = Saver.save(E1.Name); |
| 577 | if (E1.isWeak()) | 672 | E2.ExtName = Saver.save(E1.ExtName); |
| 578 | E2.ExtName = Saver.save(E1.ExtName); | ||
| 579 | E2.Ordinal = E1.Ordinal; | 673 | E2.Ordinal = E1.Ordinal; |
| 580 | E2.Noname = E1.Noname; | 674 | E2.Noname = E1.Noname; |
| 581 | E2.Data = E1.Data; | 675 | E2.Data = E1.Data; |
| ... | @@ -638,8 +732,8 @@ filterBitcodeFiles(StringRef Path, std::vector<std::string> &TemporaryFiles) { | ... | @@ -638,8 +732,8 @@ filterBitcodeFiles(StringRef Path, std::vector<std::string> &TemporaryFiles) { |
| 638 | log("Creating a temporary archive for " + Path + " to remove bitcode files"); | 732 | log("Creating a temporary archive for " + Path + " to remove bitcode files"); |
| 639 | 733 | ||
| 640 | SmallString<128> S; | 734 | SmallString<128> S; |
| 641 | if (auto EC = sys::fs::createTemporaryFile("lld-" + sys::path::stem(Path), | 735 | if (std::error_code EC = sys::fs::createTemporaryFile( |
| 642 | ".lib", S)) | 736 | "lld-" + sys::path::stem(Path), ".lib", S)) |
| 643 | fatal("cannot create a temporary file: " + EC.message()); | 737 | fatal("cannot create a temporary file: " + EC.message()); |
| 644 | std::string Temp = S.str(); | 738 | std::string Temp = S.str(); |
| 645 | TemporaryFiles.push_back(Temp); | 739 | TemporaryFiles.push_back(Temp); |
| ... | @@ -715,6 +809,8 @@ void LinkerDriver::enqueueTask(std::function<void()> Task) { | ... | @@ -715,6 +809,8 @@ void LinkerDriver::enqueueTask(std::function<void()> Task) { |
| 715 | } | 809 | } |
| 716 | 810 | ||
| 717 | bool LinkerDriver::run() { | 811 | bool LinkerDriver::run() { |
| 812 | ScopedTimer T(InputFileTimer); | ||
| 813 | |||
| 718 | bool DidWork = !TaskQueue.empty(); | 814 | bool DidWork = !TaskQueue.empty(); |
| 719 | while (!TaskQueue.empty()) { | 815 | while (!TaskQueue.empty()) { |
| 720 | TaskQueue.front()(); | 816 | TaskQueue.front()(); |
| ... | @@ -723,6 +819,46 @@ bool LinkerDriver::run() { | ... | @@ -723,6 +819,46 @@ bool LinkerDriver::run() { |
| 723 | return DidWork; | 819 | return DidWork; |
| 724 | } | 820 | } |
| 725 | 821 | ||
| 822 | // Parse an /order file. If an option is given, the linker places | ||
| 823 | // COMDAT sections in the same order as their names appear in the | ||
| 824 | // given file. | ||
| 825 | static void parseOrderFile(StringRef Arg) { | ||
| 826 | // For some reason, the MSVC linker requires a filename to be | ||
| 827 | // preceded by "@". | ||
| 828 | if (!Arg.startswith("@")) { | ||
| 829 | error("malformed /order option: '@' missing"); | ||
| 830 | return; | ||
| 831 | } | ||
| 832 | |||
| 833 | // Get a list of all comdat sections for error checking. | ||
| 834 | DenseSet<StringRef> Set; | ||
| 835 | for (Chunk *C : Symtab->getChunks()) | ||
| 836 | if (auto *Sec = dyn_cast<SectionChunk>(C)) | ||
| 837 | if (Sec->Sym) | ||
| 838 | Set.insert(Sec->Sym->getName()); | ||
| 839 | |||
| 840 | // Open a file. | ||
| 841 | StringRef Path = Arg.substr(1); | ||
| 842 | std::unique_ptr<MemoryBuffer> MB = CHECK( | ||
| 843 | MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); | ||
| 844 | |||
| 845 | // Parse a file. An order file contains one symbol per line. | ||
| 846 | // All symbols that were not present in a given order file are | ||
| 847 | // considered to have the lowest priority 0 and are placed at | ||
| 848 | // end of an output section. | ||
| 849 | for (std::string S : args::getLines(MB->getMemBufferRef())) { | ||
| 850 | if (Config->Machine == I386 && !isDecorated(S)) | ||
| 851 | S = "_" + S; | ||
| 852 | |||
| 853 | if (Set.count(S) == 0) { | ||
| 854 | if (Config->WarnMissingOrderSymbol) | ||
| 855 | warn("/order:" + Arg + ": missing symbol: " + S + " [LNK4037]"); | ||
| 856 | } | ||
| 857 | else | ||
| 858 | Config->Order[S] = INT_MIN + Config->Order.size(); | ||
| 859 | } | ||
| 860 | } | ||
| 861 | |||
| 726 | void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | 862 | void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 727 | // If the first command line argument is "/lib", link.exe acts like lib.exe. | 863 | // If the first command line argument is "/lib", link.exe acts like lib.exe. |
| 728 | // We call our own implementation of lib.exe that understands bitcode files. | 864 | // We call our own implementation of lib.exe that understands bitcode files. |
| ... | @@ -738,11 +874,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -738,11 +874,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 738 | InitializeAllTargetMCs(); | 874 | InitializeAllTargetMCs(); |
| 739 | InitializeAllAsmParsers(); | 875 | InitializeAllAsmParsers(); |
| 740 | InitializeAllAsmPrinters(); | 876 | InitializeAllAsmPrinters(); |
| 741 | InitializeAllDisassemblers(); | ||
| 742 | 877 | ||
| 743 | // Parse command line options. | 878 | // Parse command line options. |
| 744 | ArgParser Parser; | 879 | ArgParser Parser; |
| 745 | opt::InputArgList Args = Parser.parseLINK(ArgsArr.slice(1)); | 880 | opt::InputArgList Args = Parser.parseLINK(ArgsArr); |
| 746 | 881 | ||
| 747 | // Parse and evaluate -mllvm options. | 882 | // Parse and evaluate -mllvm options. |
| 748 | std::vector<const char *> V; | 883 | std::vector<const char *> V; |
| ... | @@ -766,6 +901,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -766,6 +901,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 766 | return; | 901 | return; |
| 767 | } | 902 | } |
| 768 | 903 | ||
| 904 | if (Args.hasArg(OPT_show_timing)) | ||
| 905 | Config->ShowTiming = true; | ||
| 906 | |||
| 907 | ScopedTimer T(Timer::root()); | ||
| 769 | // Handle --version, which is an lld extension. This option is a bit odd | 908 | // Handle --version, which is an lld extension. This option is a bit odd |
| 770 | // because it doesn't start with "/", but we deliberately chose "--" to | 909 | // because it doesn't start with "/", but we deliberately chose "--" to |
| 771 | // avoid conflict with /version and for compatibility with clang-cl. | 910 | // avoid conflict with /version and for compatibility with clang-cl. |
| ... | @@ -808,7 +947,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -808,7 +947,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 808 | 947 | ||
| 809 | // Handle /ignore | 948 | // Handle /ignore |
| 810 | for (auto *Arg : Args.filtered(OPT_ignore)) { | 949 | for (auto *Arg : Args.filtered(OPT_ignore)) { |
| 811 | if (StringRef(Arg->getValue()) == "4217") | 950 | if (StringRef(Arg->getValue()) == "4037") |
| 951 | Config->WarnMissingOrderSymbol = false; | ||
| 952 | else if (StringRef(Arg->getValue()) == "4217") | ||
| 812 | Config->WarnLocallyDefinedImported = false; | 953 | Config->WarnLocallyDefinedImported = false; |
| 813 | // Other warning numbers are ignored. | 954 | // Other warning numbers are ignored. |
| 814 | } | 955 | } |
| ... | @@ -829,6 +970,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -829,6 +970,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 829 | // Handle /debug | 970 | // Handle /debug |
| 830 | if (Args.hasArg(OPT_debug, OPT_debug_dwarf, OPT_debug_ghash)) { | 971 | if (Args.hasArg(OPT_debug, OPT_debug_dwarf, OPT_debug_ghash)) { |
| 831 | Config->Debug = true; | 972 | Config->Debug = true; |
| 973 | Config->Incremental = true; | ||
| 832 | if (auto *Arg = Args.getLastArg(OPT_debugtype)) | 974 | if (auto *Arg = Args.getLastArg(OPT_debugtype)) |
| 833 | Config->DebugTypes = parseDebugType(Arg->getValue()); | 975 | Config->DebugTypes = parseDebugType(Arg->getValue()); |
| 834 | else | 976 | else |
| ... | @@ -837,9 +979,17 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -837,9 +979,17 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 837 | 979 | ||
| 838 | // Handle /pdb | 980 | // Handle /pdb |
| 839 | bool ShouldCreatePDB = Args.hasArg(OPT_debug, OPT_debug_ghash); | 981 | bool ShouldCreatePDB = Args.hasArg(OPT_debug, OPT_debug_ghash); |
| 840 | if (ShouldCreatePDB) | 982 | if (ShouldCreatePDB) { |
| 841 | if (auto *Arg = Args.getLastArg(OPT_pdb)) | 983 | if (auto *Arg = Args.getLastArg(OPT_pdb)) |
| 842 | Config->PDBPath = Arg->getValue(); | 984 | Config->PDBPath = Arg->getValue(); |
| 985 | if (auto *Arg = Args.getLastArg(OPT_pdbaltpath)) | ||
| 986 | Config->PDBAltPath = Arg->getValue(); | ||
| 987 | if (Args.hasArg(OPT_natvis)) | ||
| 988 | Config->NatvisFiles = Args.getAllArgValues(OPT_natvis); | ||
| 989 | |||
| 990 | if (auto *Arg = Args.getLastArg(OPT_pdb_source_path)) | ||
| 991 | Config->PDBSourcePath = Arg->getValue(); | ||
| 992 | } | ||
| 843 | 993 | ||
| 844 | // Handle /noentry | 994 | // Handle /noentry |
| 845 | if (Args.hasArg(OPT_noentry)) { | 995 | if (Args.hasArg(OPT_noentry)) { |
| ... | @@ -863,6 +1013,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -863,6 +1013,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 863 | DynamicBaseArg->getOption().getID() == OPT_dynamicbase_no) | 1013 | DynamicBaseArg->getOption().getID() == OPT_dynamicbase_no) |
| 864 | Config->DynamicBase = false; | 1014 | Config->DynamicBase = false; |
| 865 | 1015 | ||
| 1016 | // MSDN claims "/FIXED:NO is the default setting for a DLL, and /FIXED is the | ||
| 1017 | // default setting for any other project type.", but link.exe defaults to | ||
| 1018 | // /FIXED:NO for exe outputs as well. Match behavior, not docs. | ||
| 866 | bool Fixed = Args.hasFlag(OPT_fixed, OPT_fixed_no, false); | 1019 | bool Fixed = Args.hasFlag(OPT_fixed, OPT_fixed_no, false); |
| 867 | if (Fixed) { | 1020 | if (Fixed) { |
| 868 | if (DynamicBaseArg && | 1021 | if (DynamicBaseArg && |
| ... | @@ -898,6 +1051,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -898,6 +1051,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 898 | if (auto *Arg = Args.getLastArg(OPT_stack)) | 1051 | if (auto *Arg = Args.getLastArg(OPT_stack)) |
| 899 | parseNumbers(Arg->getValue(), &Config->StackReserve, &Config->StackCommit); | 1052 | parseNumbers(Arg->getValue(), &Config->StackReserve, &Config->StackCommit); |
| 900 | 1053 | ||
| 1054 | // Handle /guard:cf | ||
| 1055 | if (auto *Arg = Args.getLastArg(OPT_guard)) | ||
| 1056 | parseGuard(Arg->getValue()); | ||
| 1057 | |||
| 901 | // Handle /heap | 1058 | // Handle /heap |
| 902 | if (auto *Arg = Args.getLastArg(OPT_heap)) | 1059 | if (auto *Arg = Args.getLastArg(OPT_heap)) |
| 903 | parseNumbers(Arg->getValue(), &Config->HeapReserve, &Config->HeapCommit); | 1060 | parseNumbers(Arg->getValue(), &Config->HeapReserve, &Config->HeapCommit); |
| ... | @@ -912,6 +1069,23 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -912,6 +1069,23 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 912 | parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion, | 1069 | parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion, |
| 913 | &Config->MinorOSVersion); | 1070 | &Config->MinorOSVersion); |
| 914 | 1071 | ||
| 1072 | // Handle /timestamp | ||
| 1073 | if (llvm::opt::Arg *Arg = Args.getLastArg(OPT_timestamp, OPT_repro)) { | ||
| 1074 | if (Arg->getOption().getID() == OPT_repro) { | ||
| 1075 | Config->Timestamp = 0; | ||
| 1076 | Config->Repro = true; | ||
| 1077 | } else { | ||
| 1078 | Config->Repro = false; | ||
| 1079 | StringRef Value(Arg->getValue()); | ||
| 1080 | if (Value.getAsInteger(0, Config->Timestamp)) | ||
| 1081 | fatal(Twine("invalid timestamp: ") + Value + | ||
| 1082 | ". Expected 32-bit integer"); | ||
| 1083 | } | ||
| 1084 | } else { | ||
| 1085 | Config->Repro = false; | ||
| 1086 | Config->Timestamp = time(nullptr); | ||
| 1087 | } | ||
| 1088 | |||
| 915 | // Handle /alternatename | 1089 | // Handle /alternatename |
| 916 | for (auto *Arg : Args.filtered(OPT_alternatename)) | 1090 | for (auto *Arg : Args.filtered(OPT_alternatename)) |
| 917 | parseAlternateName(Arg->getValue()); | 1091 | parseAlternateName(Arg->getValue()); |
| ... | @@ -925,8 +1099,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -925,8 +1099,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 925 | Config->Implib = Arg->getValue(); | 1099 | Config->Implib = Arg->getValue(); |
| 926 | 1100 | ||
| 927 | // Handle /opt. | 1101 | // Handle /opt. |
| 928 | bool DoGC = !Args.hasArg(OPT_debug); | 1102 | bool DoGC = !Args.hasArg(OPT_debug) || Args.hasArg(OPT_profile); |
| 929 | unsigned ICFLevel = 1; // 0: off, 1: limited, 2: on | 1103 | unsigned ICFLevel = |
| 1104 | Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on | ||
| 1105 | unsigned TailMerge = 1; | ||
| 930 | for (auto *Arg : Args.filtered(OPT_opt)) { | 1106 | for (auto *Arg : Args.filtered(OPT_opt)) { |
| 931 | std::string Str = StringRef(Arg->getValue()).lower(); | 1107 | std::string Str = StringRef(Arg->getValue()).lower(); |
| 932 | SmallVector<StringRef, 1> Vec; | 1108 | SmallVector<StringRef, 1> Vec; |
| ... | @@ -940,14 +1116,18 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -940,14 +1116,18 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 940 | ICFLevel = 2; | 1116 | ICFLevel = 2; |
| 941 | } else if (S == "noicf") { | 1117 | } else if (S == "noicf") { |
| 942 | ICFLevel = 0; | 1118 | ICFLevel = 0; |
| 1119 | } else if (S == "lldtailmerge") { | ||
| 1120 | TailMerge = 2; | ||
| 1121 | } else if (S == "nolldtailmerge") { | ||
| 1122 | TailMerge = 0; | ||
| 943 | } else if (S.startswith("lldlto=")) { | 1123 | } else if (S.startswith("lldlto=")) { |
| 944 | StringRef OptLevel = S.substr(7); | 1124 | StringRef OptLevel = S.substr(7); |
| 945 | if (OptLevel.getAsInteger(10, Config->LTOOptLevel) || | 1125 | if (OptLevel.getAsInteger(10, Config->LTOO) || Config->LTOO > 3) |
| 946 | Config->LTOOptLevel > 3) | ||
| 947 | error("/opt:lldlto: invalid optimization level: " + OptLevel); | 1126 | error("/opt:lldlto: invalid optimization level: " + OptLevel); |
| 948 | } else if (S.startswith("lldltojobs=")) { | 1127 | } else if (S.startswith("lldltojobs=")) { |
| 949 | StringRef Jobs = S.substr(11); | 1128 | StringRef Jobs = S.substr(11); |
| 950 | if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0) | 1129 | if (Jobs.getAsInteger(10, Config->ThinLTOJobs) || |
| 1130 | Config->ThinLTOJobs == 0) | ||
| 951 | error("/opt:lldltojobs: invalid job count: " + Jobs); | 1131 | error("/opt:lldltojobs: invalid job count: " + Jobs); |
| 952 | } else if (S.startswith("lldltopartitions=")) { | 1132 | } else if (S.startswith("lldltopartitions=")) { |
| 953 | StringRef N = S.substr(17); | 1133 | StringRef N = S.substr(17); |
| ... | @@ -968,11 +1148,16 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -968,11 +1148,16 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 968 | ICFLevel = 0; | 1148 | ICFLevel = 0; |
| 969 | Config->DoGC = DoGC; | 1149 | Config->DoGC = DoGC; |
| 970 | Config->DoICF = ICFLevel > 0; | 1150 | Config->DoICF = ICFLevel > 0; |
| 1151 | Config->TailMerge = (TailMerge == 1 && Config->DoICF) || TailMerge == 2; | ||
| 971 | 1152 | ||
| 972 | // Handle /lldsavetemps | 1153 | // Handle /lldsavetemps |
| 973 | if (Args.hasArg(OPT_lldsavetemps)) | 1154 | if (Args.hasArg(OPT_lldsavetemps)) |
| 974 | Config->SaveTemps = true; | 1155 | Config->SaveTemps = true; |
| 975 | 1156 | ||
| 1157 | // Handle /kill-at | ||
| 1158 | if (Args.hasArg(OPT_kill_at)) | ||
| 1159 | Config->KillAt = true; | ||
| 1160 | |||
| 976 | // Handle /lldltocache | 1161 | // Handle /lldltocache |
| 977 | if (auto *Arg = Args.getLastArg(OPT_lldltocache)) | 1162 | if (auto *Arg = Args.getLastArg(OPT_lldltocache)) |
| 978 | Config->LTOCache = Arg->getValue(); | 1163 | Config->LTOCache = Arg->getValue(); |
| ... | @@ -991,6 +1176,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -991,6 +1176,14 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 991 | for (auto *Arg : Args.filtered(OPT_merge)) | 1176 | for (auto *Arg : Args.filtered(OPT_merge)) |
| 992 | parseMerge(Arg->getValue()); | 1177 | parseMerge(Arg->getValue()); |
| 993 | 1178 | ||
| 1179 | // Add default section merging rules after user rules. User rules take | ||
| 1180 | // precedence, but we will emit a warning if there is a conflict. | ||
| 1181 | parseMerge(".idata=.rdata"); | ||
| 1182 | parseMerge(".didat=.rdata"); | ||
| 1183 | parseMerge(".edata=.rdata"); | ||
| 1184 | parseMerge(".xdata=.rdata"); | ||
| 1185 | parseMerge(".bss=.data"); | ||
| 1186 | |||
| 994 | // Handle /section | 1187 | // Handle /section |
| 995 | for (auto *Arg : Args.filtered(OPT_section)) | 1188 | for (auto *Arg : Args.filtered(OPT_section)) |
| 996 | parseSection(Arg->getValue()); | 1189 | parseSection(Arg->getValue()); |
| ... | @@ -1028,39 +1221,77 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -1028,39 +1221,77 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1028 | 1221 | ||
| 1029 | if (!Config->ManifestInput.empty() && | 1222 | if (!Config->ManifestInput.empty() && |
| 1030 | Config->Manifest != Configuration::Embed) { | 1223 | Config->Manifest != Configuration::Embed) { |
| 1031 | fatal("/MANIFESTINPUT: requires /MANIFEST:EMBED"); | 1224 | fatal("/manifestinput: requires /manifest:embed"); |
| 1032 | } | 1225 | } |
| 1033 | 1226 | ||
| 1034 | // Handle miscellaneous boolean flags. | 1227 | // Handle miscellaneous boolean flags. |
| 1035 | Config->AllowBind = Args.hasFlag(OPT_allowbind, OPT_allowbind_no, true); | 1228 | Config->AllowBind = Args.hasFlag(OPT_allowbind, OPT_allowbind_no, true); |
| 1036 | Config->AllowIsolation = | 1229 | Config->AllowIsolation = |
| 1037 | Args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true); | 1230 | Args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true); |
| 1231 | Config->Incremental = | ||
| 1232 | Args.hasFlag(OPT_incremental, OPT_incremental_no, | ||
| 1233 | !Config->DoGC && !Config->DoICF && !Args.hasArg(OPT_order) && | ||
| 1234 | !Args.hasArg(OPT_profile)); | ||
| 1235 | Config->IntegrityCheck = | ||
| 1236 | Args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false); | ||
| 1038 | Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); | 1237 | Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); |
| 1039 | Config->TerminalServerAware = Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true); | 1238 | Config->TerminalServerAware = |
| 1239 | !Config->DLL && Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true); | ||
| 1040 | Config->DebugDwarf = Args.hasArg(OPT_debug_dwarf); | 1240 | Config->DebugDwarf = Args.hasArg(OPT_debug_dwarf); |
| 1041 | Config->DebugGHashes = Args.hasArg(OPT_debug_ghash); | 1241 | Config->DebugGHashes = Args.hasArg(OPT_debug_ghash); |
| 1242 | Config->DebugSymtab = Args.hasArg(OPT_debug_symtab); | ||
| 1042 | 1243 | ||
| 1043 | Config->MapFile = getMapFile(Args); | 1244 | Config->MapFile = getMapFile(Args); |
| 1044 | 1245 | ||
| 1246 | if (Config->Incremental && Args.hasArg(OPT_profile)) { | ||
| 1247 | warn("ignoring '/incremental' due to '/profile' specification"); | ||
| 1248 | Config->Incremental = false; | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | if (Config->Incremental && Args.hasArg(OPT_order)) { | ||
| 1252 | warn("ignoring '/incremental' due to '/order' specification"); | ||
| 1253 | Config->Incremental = false; | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | if (Config->Incremental && Config->DoGC) { | ||
| 1257 | warn("ignoring '/incremental' because REF is enabled; use '/opt:noref' to " | ||
| 1258 | "disable"); | ||
| 1259 | Config->Incremental = false; | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | if (Config->Incremental && Config->DoICF) { | ||
| 1263 | warn("ignoring '/incremental' because ICF is enabled; use '/opt:noicf' to " | ||
| 1264 | "disable"); | ||
| 1265 | Config->Incremental = false; | ||
| 1266 | } | ||
| 1267 | |||
| 1045 | if (errorCount()) | 1268 | if (errorCount()) |
| 1046 | return; | 1269 | return; |
| 1047 | 1270 | ||
| 1048 | bool WholeArchiveFlag = Args.hasArg(OPT_wholearchive_flag); | 1271 | std::set<sys::fs::UniqueID> WholeArchives; |
| 1272 | for (auto *Arg : Args.filtered(OPT_wholearchive_file)) | ||
| 1273 | if (Optional<StringRef> Path = doFindFile(Arg->getValue())) | ||
| 1274 | if (Optional<sys::fs::UniqueID> ID = getUniqueID(*Path)) | ||
| 1275 | WholeArchives.insert(*ID); | ||
| 1276 | |||
| 1277 | // A predicate returning true if a given path is an argument for | ||
| 1278 | // /wholearchive:, or /wholearchive is enabled globally. | ||
| 1279 | // This function is a bit tricky because "foo.obj /wholearchive:././foo.obj" | ||
| 1280 | // needs to be handled as "/wholearchive:foo.obj foo.obj". | ||
| 1281 | auto IsWholeArchive = [&](StringRef Path) -> bool { | ||
| 1282 | if (Args.hasArg(OPT_wholearchive_flag)) | ||
| 1283 | return true; | ||
| 1284 | if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) | ||
| 1285 | return WholeArchives.count(*ID); | ||
| 1286 | return false; | ||
| 1287 | }; | ||
| 1288 | |||
| 1049 | // Create a list of input files. Files can be given as arguments | 1289 | // Create a list of input files. Files can be given as arguments |
| 1050 | // for /defaultlib option. | 1290 | // for /defaultlib option. |
| 1051 | std::vector<MemoryBufferRef> MBs; | 1291 | for (auto *Arg : Args.filtered(OPT_INPUT, OPT_wholearchive_file)) |
| 1052 | for (auto *Arg : Args.filtered(OPT_INPUT, OPT_wholearchive_file)) { | 1292 | if (Optional<StringRef> Path = findFile(Arg->getValue())) |
| 1053 | switch (Arg->getOption().getID()) { | 1293 | enqueuePath(*Path, IsWholeArchive(*Path)); |
| 1054 | case OPT_INPUT: | 1294 | |
| 1055 | if (Optional<StringRef> Path = findFile(Arg->getValue())) | ||
| 1056 | enqueuePath(*Path, WholeArchiveFlag); | ||
| 1057 | break; | ||
| 1058 | case OPT_wholearchive_file: | ||
| 1059 | if (Optional<StringRef> Path = findFile(Arg->getValue())) | ||
| 1060 | enqueuePath(*Path, true); | ||
| 1061 | break; | ||
| 1062 | } | ||
| 1063 | } | ||
| 1064 | for (auto *Arg : Args.filtered(OPT_defaultlib)) | 1295 | for (auto *Arg : Args.filtered(OPT_defaultlib)) |
| 1065 | if (Optional<StringRef> Path = findLib(Arg->getValue())) | 1296 | if (Optional<StringRef> Path = findLib(Arg->getValue())) |
| 1066 | enqueuePath(*Path, false); | 1297 | enqueuePath(*Path, false); |
| ... | @@ -1164,10 +1395,24 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -1164,10 +1395,24 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1164 | getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue()); | 1395 | getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue()); |
| 1165 | } | 1396 | } |
| 1166 | 1397 | ||
| 1167 | // Put the PDB next to the image if no /pdb flag was passed. | 1398 | if (ShouldCreatePDB) { |
| 1168 | if (ShouldCreatePDB && Config->PDBPath.empty()) { | 1399 | // Put the PDB next to the image if no /pdb flag was passed. |
| 1169 | Config->PDBPath = Config->OutputFile; | 1400 | if (Config->PDBPath.empty()) { |
| 1170 | sys::path::replace_extension(Config->PDBPath, ".pdb"); | 1401 | Config->PDBPath = Config->OutputFile; |
| 1402 | sys::path::replace_extension(Config->PDBPath, ".pdb"); | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | // The embedded PDB path should be the absolute path to the PDB if no | ||
| 1406 | // /pdbaltpath flag was passed. | ||
| 1407 | if (Config->PDBAltPath.empty()) { | ||
| 1408 | Config->PDBAltPath = Config->PDBPath; | ||
| 1409 | |||
| 1410 | // It's important to make the path absolute and remove dots. This path | ||
| 1411 | // will eventually be written into the PE header, and certain Microsoft | ||
| 1412 | // tools won't work correctly if these assumptions are not held. | ||
| 1413 | sys::fs::make_absolute(Config->PDBAltPath); | ||
| 1414 | sys::path::remove_dots(Config->PDBAltPath); | ||
| 1415 | } | ||
| 1171 | } | 1416 | } |
| 1172 | 1417 | ||
| 1173 | // Set default image base if /base is not given. | 1418 | // Set default image base if /base is not given. |
| ... | @@ -1180,11 +1425,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -1180,11 +1425,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1180 | Symtab->addAbsolute("___safe_se_handler_count", 0); | 1425 | Symtab->addAbsolute("___safe_se_handler_count", 0); |
| 1181 | } | 1426 | } |
| 1182 | 1427 | ||
| 1183 | // We do not support /guard:cf (control flow protection) yet. | ||
| 1184 | // Define CFG symbols anyway so that we can link MSVC 2015 CRT. | ||
| 1185 | Symtab->addAbsolute(mangle("__guard_fids_count"), 0); | 1428 | Symtab->addAbsolute(mangle("__guard_fids_count"), 0); |
| 1186 | Symtab->addAbsolute(mangle("__guard_fids_table"), 0); | 1429 | Symtab->addAbsolute(mangle("__guard_fids_table"), 0); |
| 1187 | Symtab->addAbsolute(mangle("__guard_flags"), 0x100); | 1430 | Symtab->addAbsolute(mangle("__guard_flags"), 0); |
| 1188 | Symtab->addAbsolute(mangle("__guard_iat_count"), 0); | 1431 | Symtab->addAbsolute(mangle("__guard_iat_count"), 0); |
| 1189 | Symtab->addAbsolute(mangle("__guard_iat_table"), 0); | 1432 | Symtab->addAbsolute(mangle("__guard_iat_table"), 0); |
| 1190 | Symtab->addAbsolute(mangle("__guard_longjmp_count"), 0); | 1433 | Symtab->addAbsolute(mangle("__guard_longjmp_count"), 0); |
| ... | @@ -1259,7 +1502,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -1259,7 +1502,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1259 | // Handle /safeseh. | 1502 | // Handle /safeseh. |
| 1260 | if (Args.hasFlag(OPT_safeseh, OPT_safeseh_no, false)) { | 1503 | if (Args.hasFlag(OPT_safeseh, OPT_safeseh_no, false)) { |
| 1261 | for (ObjFile *File : ObjFile::Instances) | 1504 | for (ObjFile *File : ObjFile::Instances) |
| 1262 | if (!File->SEHCompat) | 1505 | if (!File->hasSafeSEH()) |
| 1263 | error("/safeseh: " + File->getName() + " is not compatible with SEH"); | 1506 | error("/safeseh: " + File->getName() + " is not compatible with SEH"); |
| 1264 | if (errorCount()) | 1507 | if (errorCount()) |
| 1265 | return; | 1508 | return; |
| ... | @@ -1279,7 +1522,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -1279,7 +1522,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1279 | E.Name = Def->getName(); | 1522 | E.Name = Def->getName(); |
| 1280 | E.Sym = Def; | 1523 | E.Sym = Def; |
| 1281 | if (Def->getChunk() && | 1524 | if (Def->getChunk() && |
| 1282 | !(Def->getChunk()->getPermissions() & IMAGE_SCN_MEM_EXECUTE)) | 1525 | !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) |
| 1283 | E.Data = true; | 1526 | E.Data = true; |
| 1284 | Config->Exports.push_back(E); | 1527 | Config->Exports.push_back(E); |
| 1285 | }); | 1528 | }); |
| ... | @@ -1322,6 +1565,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -1322,6 +1565,12 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1322 | if (Config->Manifest == Configuration::SideBySide) | 1565 | if (Config->Manifest == Configuration::SideBySide) |
| 1323 | createSideBySideManifest(); | 1566 | createSideBySideManifest(); |
| 1324 | 1567 | ||
| 1568 | // Handle /order. We want to do this at this moment because we | ||
| 1569 | // need a complete list of comdat sections to warn on nonexistent | ||
| 1570 | // functions. | ||
| 1571 | if (auto *Arg = Args.getLastArg(OPT_order)) | ||
| 1572 | parseOrderFile(Arg->getValue()); | ||
| 1573 | |||
| 1325 | // Identify unreferenced COMDAT sections. | 1574 | // Identify unreferenced COMDAT sections. |
| 1326 | if (Config->DoGC) | 1575 | if (Config->DoGC) |
| 1327 | markLive(Symtab->getChunks()); | 1576 | markLive(Symtab->getChunks()); |
| ... | @@ -1332,6 +1581,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -1332,6 +1581,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 1332 | 1581 | ||
| 1333 | // Write the result. | 1582 | // Write the result. |
| 1334 | writeResult(); | 1583 | writeResult(); |
| 1584 | |||
| 1585 | // Stop early so we can print the results. | ||
| 1586 | Timer::root().stop(); | ||
| 1587 | if (Config->ShowTiming) | ||
| 1588 | Timer::root().print(); | ||
| 1335 | } | 1589 | } |
| 1336 | 1590 | ||
| 1337 | } // namespace coff | 1591 | } // namespace coff |
deps/lld/COFF/Driver.h+12-9| ... | @@ -21,6 +21,7 @@ | ... | @@ -21,6 +21,7 @@ |
| 21 | #include "llvm/Object/COFF.h" | 21 | #include "llvm/Object/COFF.h" |
| 22 | #include "llvm/Option/Arg.h" | 22 | #include "llvm/Option/Arg.h" |
| 23 | #include "llvm/Option/ArgList.h" | 23 | #include "llvm/Option/ArgList.h" |
| 24 | #include "llvm/Support/FileSystem.h" | ||
| 24 | #include "llvm/Support/TarWriter.h" | 25 | #include "llvm/Support/TarWriter.h" |
| 25 | #include <memory> | 26 | #include <memory> |
| 26 | #include <set> | 27 | #include <set> |
| ... | @@ -36,12 +37,6 @@ using llvm::COFF::MachineTypes; | ... | @@ -36,12 +37,6 @@ using llvm::COFF::MachineTypes; |
| 36 | using llvm::COFF::WindowsSubsystem; | 37 | using llvm::COFF::WindowsSubsystem; |
| 37 | using llvm::Optional; | 38 | using llvm::Optional; |
| 38 | 39 | ||
| 39 | // Implemented in MarkLive.cpp. | ||
| 40 | void markLive(ArrayRef<Chunk *> Chunks); | ||
| 41 | |||
| 42 | // Implemented in ICF.cpp. | ||
| 43 | void doICF(ArrayRef<Chunk *> Chunks); | ||
| 44 | |||
| 45 | class COFFOptTable : public llvm::opt::OptTable { | 40 | class COFFOptTable : public llvm::opt::OptTable { |
| 46 | public: | 41 | public: |
| 47 | COFFOptTable(); | 42 | COFFOptTable(); |
| ... | @@ -56,8 +51,10 @@ public: | ... | @@ -56,8 +51,10 @@ public: |
| 56 | llvm::opt::InputArgList parse(StringRef S) { return parse(tokenize(S)); } | 51 | llvm::opt::InputArgList parse(StringRef S) { return parse(tokenize(S)); } |
| 57 | 52 | ||
| 58 | // Tokenizes a given string and then parses as command line options in | 53 | // Tokenizes a given string and then parses as command line options in |
| 59 | // .drectve section. | 54 | // .drectve section. /EXPORT options are returned in second element |
| 60 | llvm::opt::InputArgList parseDirectives(StringRef S); | 55 | // to be processed in fastpath. |
| 56 | std::pair<llvm::opt::InputArgList, std::vector<StringRef>> | ||
| 57 | parseDirectives(StringRef S); | ||
| 61 | 58 | ||
| 62 | private: | 59 | private: |
| 63 | // Parses command line options. | 60 | // Parses command line options. |
| ... | @@ -98,7 +95,11 @@ private: | ... | @@ -98,7 +95,11 @@ private: |
| 98 | 95 | ||
| 99 | // Library search path. The first element is always "" (current directory). | 96 | // Library search path. The first element is always "" (current directory). |
| 100 | std::vector<StringRef> SearchPaths; | 97 | std::vector<StringRef> SearchPaths; |
| 101 | std::set<std::string> VisitedFiles; | 98 | |
| 99 | // We don't want to add the same file more than once. | ||
| 100 | // Files are uniquified by their filesystem and file number. | ||
| 101 | std::set<llvm::sys::fs::UniqueID> VisitedFiles; | ||
| 102 | |||
| 102 | std::set<std::string> VisitedLibs; | 103 | std::set<std::string> VisitedLibs; |
| 103 | 104 | ||
| 104 | Symbol *addUndefined(StringRef Sym); | 105 | Symbol *addUndefined(StringRef Sym); |
| ... | @@ -143,6 +144,8 @@ StringRef machineToStr(MachineTypes MT); | ... | @@ -143,6 +144,8 @@ StringRef machineToStr(MachineTypes MT); |
| 143 | // Parses a string in the form of "<integer>[,<integer>]". | 144 | // Parses a string in the form of "<integer>[,<integer>]". |
| 144 | void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size = nullptr); | 145 | void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size = nullptr); |
| 145 | 146 | ||
| 147 | void parseGuard(StringRef Arg); | ||
| 148 | |||
| 146 | // Parses a string in the form of "<integer>[.<integer>]". | 149 | // Parses a string in the form of "<integer>[.<integer>]". |
| 147 | // Minor's default value is 0. | 150 | // Minor's default value is 0. |
| 148 | void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor); | 151 | void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor); |
deps/lld/COFF/DriverUtils.cpp+119-25| ... | @@ -61,12 +61,7 @@ public: | ... | @@ -61,12 +61,7 @@ public: |
| 61 | StringRef Exe = Saver.save(*ExeOrErr); | 61 | StringRef Exe = Saver.save(*ExeOrErr); |
| 62 | Args.insert(Args.begin(), Exe); | 62 | Args.insert(Args.begin(), Exe); |
| 63 | 63 | ||
| 64 | std::vector<const char *> Vec; | 64 | if (sys::ExecuteAndWait(Args[0], Args) != 0) |
| 65 | for (StringRef S : Args) | ||
| 66 | Vec.push_back(S.data()); | ||
| 67 | Vec.push_back(nullptr); | ||
| 68 | |||
| 69 | if (sys::ExecuteAndWait(Args[0], Vec.data()) != 0) | ||
| 70 | fatal("ExecuteAndWait failed: " + | 65 | fatal("ExecuteAndWait failed: " + |
| 71 | llvm::join(Args.begin(), Args.end(), " ")); | 66 | llvm::join(Args.begin(), Args.end(), " ")); |
| 72 | } | 67 | } |
| ... | @@ -128,6 +123,21 @@ void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor) { | ... | @@ -128,6 +123,21 @@ void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor) { |
| 128 | fatal("invalid number: " + S2); | 123 | fatal("invalid number: " + S2); |
| 129 | } | 124 | } |
| 130 | 125 | ||
| 126 | void 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; | ||
| 136 | else | ||
| 137 | fatal("invalid argument to /guard: " + Arg); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 131 | // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]". | 141 | // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]". |
| 132 | void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major, | 142 | void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major, |
| 133 | uint32_t *Minor) { | 143 | uint32_t *Minor) { |
| ... | @@ -170,6 +180,10 @@ void parseMerge(StringRef S) { | ... | @@ -170,6 +180,10 @@ void parseMerge(StringRef S) { |
| 170 | std::tie(From, To) = S.split('='); | 180 | std::tie(From, To) = S.split('='); |
| 171 | if (From.empty() || To.empty()) | 181 | if (From.empty() || To.empty()) |
| 172 | fatal("/merge: invalid argument: " + S); | 182 | fatal("/merge: invalid argument: " + S); |
| 183 | if (From == ".rsrc" || To == ".rsrc") | ||
| 184 | fatal("/merge: cannot merge '.rsrc' with any section"); | ||
| 185 | if (From == ".reloc" || To == ".reloc") | ||
| 186 | fatal("/merge: cannot merge '.reloc' with any section"); | ||
| 173 | auto Pair = Config->Merge.insert(std::make_pair(From, To)); | 187 | auto Pair = Config->Merge.insert(std::make_pair(From, To)); |
| 174 | bool Inserted = Pair.second; | 188 | bool Inserted = Pair.second; |
| 175 | if (!Inserted) { | 189 | if (!Inserted) { |
| ... | @@ -418,15 +432,15 @@ static std::string createManifestXml() { | ... | @@ -418,15 +432,15 @@ static std::string createManifestXml() { |
| 418 | return createManifestXmlWithExternalMt(DefaultXml); | 432 | return createManifestXmlWithExternalMt(DefaultXml); |
| 419 | } | 433 | } |
| 420 | 434 | ||
| 421 | static std::unique_ptr<MemoryBuffer> | 435 | static std::unique_ptr<WritableMemoryBuffer> |
| 422 | createMemoryBufferForManifestRes(size_t ManifestSize) { | 436 | createMemoryBufferForManifestRes(size_t ManifestSize) { |
| 423 | size_t ResSize = alignTo( | 437 | size_t ResSize = alignTo( |
| 424 | object::WIN_RES_MAGIC_SIZE + object::WIN_RES_NULL_ENTRY_SIZE + | 438 | object::WIN_RES_MAGIC_SIZE + object::WIN_RES_NULL_ENTRY_SIZE + |
| 425 | sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) + | 439 | sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) + |
| 426 | sizeof(object::WinResHeaderSuffix) + ManifestSize, | 440 | sizeof(object::WinResHeaderSuffix) + ManifestSize, |
| 427 | object::WIN_RES_DATA_ALIGNMENT); | 441 | object::WIN_RES_DATA_ALIGNMENT); |
| 428 | return MemoryBuffer::getNewMemBuffer(ResSize, | 442 | return WritableMemoryBuffer::getNewMemBuffer(ResSize, Config->OutputFile + |
| 429 | Config->OutputFile + ".manifest.res"); | 443 | ".manifest.res"); |
| 430 | } | 444 | } |
| 431 | 445 | ||
| 432 | static void writeResFileHeader(char *&Buf) { | 446 | static void writeResFileHeader(char *&Buf) { |
| ... | @@ -465,16 +479,16 @@ static void writeResEntryHeader(char *&Buf, size_t ManifestSize) { | ... | @@ -465,16 +479,16 @@ static void writeResEntryHeader(char *&Buf, size_t ManifestSize) { |
| 465 | std::unique_ptr<MemoryBuffer> createManifestRes() { | 479 | std::unique_ptr<MemoryBuffer> createManifestRes() { |
| 466 | std::string Manifest = createManifestXml(); | 480 | std::string Manifest = createManifestXml(); |
| 467 | 481 | ||
| 468 | std::unique_ptr<MemoryBuffer> Res = | 482 | std::unique_ptr<WritableMemoryBuffer> Res = |
| 469 | createMemoryBufferForManifestRes(Manifest.size()); | 483 | createMemoryBufferForManifestRes(Manifest.size()); |
| 470 | 484 | ||
| 471 | char *Buf = const_cast<char *>(Res->getBufferStart()); | 485 | char *Buf = Res->getBufferStart(); |
| 472 | writeResFileHeader(Buf); | 486 | writeResFileHeader(Buf); |
| 473 | writeResEntryHeader(Buf, Manifest.size()); | 487 | writeResEntryHeader(Buf, Manifest.size()); |
| 474 | 488 | ||
| 475 | // Copy the manifest data into the .res file. | 489 | // Copy the manifest data into the .res file. |
| 476 | std::copy(Manifest.begin(), Manifest.end(), Buf); | 490 | std::copy(Manifest.begin(), Manifest.end(), Buf); |
| 477 | return Res; | 491 | return std::move(Res); |
| 478 | } | 492 | } |
| 479 | 493 | ||
| 480 | void createSideBySideManifest() { | 494 | void createSideBySideManifest() { |
| ... | @@ -558,9 +572,35 @@ err: | ... | @@ -558,9 +572,35 @@ err: |
| 558 | static StringRef undecorate(StringRef Sym) { | 572 | static StringRef undecorate(StringRef Sym) { |
| 559 | if (Config->Machine != I386) | 573 | if (Config->Machine != I386) |
| 560 | return Sym; | 574 | return Sym; |
| 575 | // In MSVC mode, a fully decorated stdcall function is exported | ||
| 576 | // as-is with the leading underscore (with type IMPORT_NAME). | ||
| 577 | // In MinGW mode, a decorated stdcall function gets the underscore | ||
| 578 | // removed, just like normal cdecl functions. | ||
| 579 | if (Sym.startswith("_") && Sym.contains('@') && !Config->MinGW) | ||
| 580 | return Sym; | ||
| 561 | return Sym.startswith("_") ? Sym.substr(1) : Sym; | 581 | return Sym.startswith("_") ? Sym.substr(1) : Sym; |
| 562 | } | 582 | } |
| 563 | 583 | ||
| 584 | // Convert stdcall/fastcall style symbols into unsuffixed symbols, | ||
| 585 | // with or without a leading underscore. (MinGW specific.) | ||
| 586 | static StringRef killAt(StringRef Sym, bool Prefix) { | ||
| 587 | if (Sym.empty()) | ||
| 588 | return Sym; | ||
| 589 | // 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; | ||
| 595 | } | ||
| 596 | // For fastcall, remove the leading @ and replace it with an | ||
| 597 | // underscore, if prefixes are used. | ||
| 598 | Sym = Sym.substr(1); | ||
| 599 | if (Prefix) | ||
| 600 | Sym = Saver.save("_" + Sym); | ||
| 601 | return Sym; | ||
| 602 | } | ||
| 603 | |||
| 564 | // Performs error checking on all /export arguments. | 604 | // Performs error checking on all /export arguments. |
| 565 | // It also sets ordinals. | 605 | // It also sets ordinals. |
| 566 | void fixupExports() { | 606 | void fixupExports() { |
| ... | @@ -593,6 +633,15 @@ void fixupExports() { | ... | @@ -593,6 +633,15 @@ void fixupExports() { |
| 593 | } | 633 | } |
| 594 | } | 634 | } |
| 595 | 635 | ||
| 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); | ||
| 642 | } | ||
| 643 | } | ||
| 644 | |||
| 596 | // Uniquefy by name. | 645 | // Uniquefy by name. |
| 597 | DenseMap<StringRef, Export *> Map(Config->Exports.size()); | 646 | DenseMap<StringRef, Export *> Map(Config->Exports.size()); |
| 598 | std::vector<Export> V; | 647 | std::vector<Export> V; |
| ... | @@ -702,6 +751,28 @@ static const llvm::opt::OptTable::Info InfoTable[] = { | ... | @@ -702,6 +751,28 @@ static const llvm::opt::OptTable::Info InfoTable[] = { |
| 702 | 751 | ||
| 703 | COFFOptTable::COFFOptTable() : OptTable(InfoTable, true) {} | 752 | COFFOptTable::COFFOptTable() : OptTable(InfoTable, true) {} |
| 704 | 753 | ||
| 754 | // Set color diagnostics according to --color-diagnostics={auto,always,never} | ||
| 755 | // or --no-color-diagnostics flags. | ||
| 756 | static void handleColorDiagnostics(opt::InputArgList &Args) { | ||
| 757 | auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, | ||
| 758 | OPT_no_color_diagnostics); | ||
| 759 | if (!Arg) | ||
| 760 | return; | ||
| 761 | if (Arg->getOption().getID() == OPT_color_diagnostics) { | ||
| 762 | errorHandler().ColorDiagnostics = true; | ||
| 763 | } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) { | ||
| 764 | errorHandler().ColorDiagnostics = false; | ||
| 765 | } else { | ||
| 766 | StringRef S = Arg->getValue(); | ||
| 767 | if (S == "always") | ||
| 768 | errorHandler().ColorDiagnostics = true; | ||
| 769 | else if (S == "never") | ||
| 770 | errorHandler().ColorDiagnostics = false; | ||
| 771 | else if (S != "auto") | ||
| 772 | error("unknown option: --color-diagnostics=" + S); | ||
| 773 | } | ||
| 774 | } | ||
| 775 | |||
| 705 | static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) { | 776 | static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) { |
| 706 | if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) { | 777 | if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) { |
| 707 | StringRef S = Arg->getValue(); | 778 | StringRef S = Arg->getValue(); |
| ... | @@ -720,50 +791,73 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> Argv) { | ... | @@ -720,50 +791,73 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> Argv) { |
| 720 | // Make InputArgList from string vectors. | 791 | // Make InputArgList from string vectors. |
| 721 | unsigned MissingIndex; | 792 | unsigned MissingIndex; |
| 722 | unsigned MissingCount; | 793 | unsigned MissingCount; |
| 723 | SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); | ||
| 724 | 794 | ||
| 725 | // We need to get the quoting style for response files before parsing all | 795 | // We need to get the quoting style for response files before parsing all |
| 726 | // options so we parse here before and ignore all the options but | 796 | // options so we parse here before and ignore all the options but |
| 727 | // --rsp-quoting. | 797 | // --rsp-quoting. |
| 728 | opt::InputArgList Args = Table.ParseArgs(Vec, MissingIndex, MissingCount); | 798 | opt::InputArgList Args = Table.ParseArgs(Argv, MissingIndex, MissingCount); |
| 729 | 799 | ||
| 730 | // Expand response files (arguments in the form of @<filename>) | 800 | // Expand response files (arguments in the form of @<filename>) |
| 731 | // and then parse the argument again. | 801 | // and then parse the argument again. |
| 732 | cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec); | 802 | SmallVector<const char *, 256> ExpandedArgv(Argv.data(), Argv.data() + Argv.size()); |
| 733 | Args = Table.ParseArgs(Vec, MissingIndex, MissingCount); | 803 | cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), ExpandedArgv); |
| 804 | Args = Table.ParseArgs(makeArrayRef(ExpandedArgv).drop_front(), MissingIndex, | ||
| 805 | MissingCount); | ||
| 734 | 806 | ||
| 735 | // Print the real command line if response files are expanded. | 807 | // Print the real command line if response files are expanded. |
| 736 | if (Args.hasArg(OPT_verbose) && Argv.size() != Vec.size()) { | 808 | if (Args.hasArg(OPT_verbose) && Argv.size() != ExpandedArgv.size()) { |
| 737 | std::string Msg = "Command line:"; | 809 | std::string Msg = "Command line:"; |
| 738 | for (const char *S : Vec) | 810 | for (const char *S : ExpandedArgv) |
| 739 | Msg += " " + std::string(S); | 811 | Msg += " " + std::string(S); |
| 740 | message(Msg); | 812 | message(Msg); |
| 741 | } | 813 | } |
| 742 | 814 | ||
| 815 | // Save the command line after response file expansion so we can write it to | ||
| 816 | // the PDB if necessary. | ||
| 817 | Config->Argv = {ExpandedArgv.begin(), ExpandedArgv.end()}; | ||
| 818 | |||
| 743 | // Handle /WX early since it converts missing argument warnings to errors. | 819 | // Handle /WX early since it converts missing argument warnings to errors. |
| 744 | errorHandler().FatalWarnings = Args.hasFlag(OPT_WX, OPT_WX_no, false); | 820 | errorHandler().FatalWarnings = Args.hasFlag(OPT_WX, OPT_WX_no, false); |
| 745 | 821 | ||
| 746 | if (MissingCount) | 822 | if (MissingCount) |
| 747 | fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); | 823 | fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); |
| 824 | |||
| 825 | handleColorDiagnostics(Args); | ||
| 826 | |||
| 748 | for (auto *Arg : Args.filtered(OPT_UNKNOWN)) | 827 | for (auto *Arg : Args.filtered(OPT_UNKNOWN)) |
| 749 | warn("ignoring unknown argument: " + Arg->getSpelling()); | 828 | warn("ignoring unknown argument: " + Arg->getSpelling()); |
| 829 | |||
| 830 | if (Args.hasArg(OPT_lib)) | ||
| 831 | warn("ignoring /lib since it's not the first argument"); | ||
| 832 | |||
| 750 | return Args; | 833 | return Args; |
| 751 | } | 834 | } |
| 752 | 835 | ||
| 753 | // Tokenizes and parses a given string as command line in .drective section. | 836 | // Tokenizes and parses a given string as command line in .drective section. |
| 754 | opt::InputArgList ArgParser::parseDirectives(StringRef S) { | 837 | // /EXPORT options are processed in fastpath. |
| 755 | // Make InputArgList from string vectors. | 838 | std::pair<opt::InputArgList, std::vector<StringRef>> |
| 839 | ArgParser::parseDirectives(StringRef S) { | ||
| 840 | std::vector<StringRef> Exports; | ||
| 841 | SmallVector<const char *, 16> Rest; | ||
| 842 | |||
| 843 | for (StringRef Tok : tokenize(S)) { | ||
| 844 | if (Tok.startswith_lower("/export:") || Tok.startswith_lower("-export:")) | ||
| 845 | Exports.push_back(Tok.substr(strlen("/export:"))); | ||
| 846 | else | ||
| 847 | Rest.push_back(Tok.data()); | ||
| 848 | } | ||
| 849 | |||
| 850 | // Make InputArgList from unparsed string vectors. | ||
| 756 | unsigned MissingIndex; | 851 | unsigned MissingIndex; |
| 757 | unsigned MissingCount; | 852 | unsigned MissingCount; |
| 758 | 853 | ||
| 759 | opt::InputArgList Args = | 854 | opt::InputArgList Args = Table.ParseArgs(Rest, MissingIndex, MissingCount); |
| 760 | Table.ParseArgs(tokenize(S), MissingIndex, MissingCount); | ||
| 761 | 855 | ||
| 762 | if (MissingCount) | 856 | if (MissingCount) |
| 763 | fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); | 857 | fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument"); |
| 764 | for (auto *Arg : Args.filtered(OPT_UNKNOWN)) | 858 | for (auto *Arg : Args.filtered(OPT_UNKNOWN)) |
| 765 | warn("ignoring unknown argument: " + Arg->getSpelling()); | 859 | warn("ignoring unknown argument: " + Arg->getSpelling()); |
| 766 | return Args; | 860 | return {std::move(Args), std::move(Exports)}; |
| 767 | } | 861 | } |
| 768 | 862 | ||
| 769 | // link.exe has an interesting feature. If LINK or _LINK_ environment | 863 | // link.exe has an interesting feature. If LINK or _LINK_ environment |
| ... | @@ -773,11 +867,11 @@ opt::InputArgList ArgParser::parseLINK(std::vector<const char *> Argv) { | ... | @@ -773,11 +867,11 @@ opt::InputArgList ArgParser::parseLINK(std::vector<const char *> Argv) { |
| 773 | // Concatenate LINK env and command line arguments, and then parse them. | 867 | // Concatenate LINK env and command line arguments, and then parse them. |
| 774 | if (Optional<std::string> S = Process::GetEnv("LINK")) { | 868 | if (Optional<std::string> S = Process::GetEnv("LINK")) { |
| 775 | std::vector<const char *> V = tokenize(*S); | 869 | std::vector<const char *> V = tokenize(*S); |
| 776 | Argv.insert(Argv.begin(), V.begin(), V.end()); | 870 | Argv.insert(std::next(Argv.begin()), V.begin(), V.end()); |
| 777 | } | 871 | } |
| 778 | if (Optional<std::string> S = Process::GetEnv("_LINK_")) { | 872 | if (Optional<std::string> S = Process::GetEnv("_LINK_")) { |
| 779 | std::vector<const char *> V = tokenize(*S); | 873 | std::vector<const char *> V = tokenize(*S); |
| 780 | Argv.insert(Argv.begin(), V.begin(), V.end()); | 874 | Argv.insert(std::next(Argv.begin()), V.begin(), V.end()); |
| 781 | } | 875 | } |
| 782 | return parse(Argv); | 876 | return parse(Argv); |
| 783 | } | 877 | } |
deps/lld/COFF/ICF.cpp+67-29| ... | @@ -18,13 +18,16 @@ | ... | @@ -18,13 +18,16 @@ |
| 18 | // | 18 | // |
| 19 | //===----------------------------------------------------------------------===// | 19 | //===----------------------------------------------------------------------===// |
| 20 | 20 | ||
| 21 | #include "ICF.h" | ||
| 21 | #include "Chunks.h" | 22 | #include "Chunks.h" |
| 22 | #include "Symbols.h" | 23 | #include "Symbols.h" |
| 23 | #include "lld/Common/ErrorHandler.h" | 24 | #include "lld/Common/ErrorHandler.h" |
| 25 | #include "lld/Common/Timer.h" | ||
| 24 | #include "llvm/ADT/Hashing.h" | 26 | #include "llvm/ADT/Hashing.h" |
| 25 | #include "llvm/Support/Debug.h" | 27 | #include "llvm/Support/Debug.h" |
| 26 | #include "llvm/Support/Parallel.h" | 28 | #include "llvm/Support/Parallel.h" |
| 27 | #include "llvm/Support/raw_ostream.h" | 29 | #include "llvm/Support/raw_ostream.h" |
| 30 | #include "llvm/Support/xxhash.h" | ||
| 28 | #include <algorithm> | 31 | #include <algorithm> |
| 29 | #include <atomic> | 32 | #include <atomic> |
| 30 | #include <vector> | 33 | #include <vector> |
| ... | @@ -34,6 +37,8 @@ using namespace llvm; | ... | @@ -34,6 +37,8 @@ using namespace llvm; |
| 34 | namespace lld { | 37 | namespace lld { |
| 35 | namespace coff { | 38 | namespace coff { |
| 36 | 39 | ||
| 40 | static Timer ICFTimer("ICF", Timer::root()); | ||
| 41 | |||
| 37 | class ICF { | 42 | class ICF { |
| 38 | public: | 43 | public: |
| 39 | void run(ArrayRef<Chunk *> V); | 44 | void run(ArrayRef<Chunk *> V); |
| ... | @@ -41,6 +46,8 @@ public: | ... | @@ -41,6 +46,8 @@ public: |
| 41 | private: | 46 | private: |
| 42 | void segregate(size_t Begin, size_t End, bool Constant); | 47 | void segregate(size_t Begin, size_t End, bool Constant); |
| 43 | 48 | ||
| 49 | bool assocEquals(const SectionChunk *A, const SectionChunk *B); | ||
| 50 | |||
| 44 | bool equalsConstant(const SectionChunk *A, const SectionChunk *B); | 51 | bool equalsConstant(const SectionChunk *A, const SectionChunk *B); |
| 45 | bool equalsVariable(const SectionChunk *A, const SectionChunk *B); | 52 | bool equalsVariable(const SectionChunk *A, const SectionChunk *B); |
| 46 | 53 | ||
| ... | @@ -59,13 +66,6 @@ private: | ... | @@ -59,13 +66,6 @@ private: |
| 59 | std::atomic<bool> Repeat = {false}; | 66 | std::atomic<bool> Repeat = {false}; |
| 60 | }; | 67 | }; |
| 61 | 68 | ||
| 62 | // Returns a hash value for S. | ||
| 63 | uint32_t ICF::getHash(SectionChunk *C) { | ||
| 64 | return hash_combine(C->getPermissions(), C->SectionName, C->NumRelocs, | ||
| 65 | C->Alignment, uint32_t(C->Header->SizeOfRawData), | ||
| 66 | C->Checksum, C->getContents()); | ||
| 67 | } | ||
| 68 | |||
| 69 | // Returns true if section S is subject of ICF. | 69 | // Returns true if section S is subject of ICF. |
| 70 | // | 70 | // |
| 71 | // Microsoft's documentation | 71 | // Microsoft's documentation |
| ... | @@ -73,21 +73,27 @@ uint32_t ICF::getHash(SectionChunk *C) { | ... | @@ -73,21 +73,27 @@ uint32_t ICF::getHash(SectionChunk *C) { |
| 73 | // 2017) says that /opt:icf folds both functions and read-only data. | 73 | // 2017) says that /opt:icf folds both functions and read-only data. |
| 74 | // Despite that, the MSVC linker folds only functions. We found | 74 | // Despite that, the MSVC linker folds only functions. We found |
| 75 | // a few instances of programs that are not safe for data merging. | 75 | // a few instances of programs that are not safe for data merging. |
| 76 | // Therefore, we merge only functions just like the MSVC tool. However, we merge | 76 | // Therefore, we merge only functions just like the MSVC tool. However, we also |
| 77 | // identical .xdata sections, because the address of unwind information is | 77 | // merge read-only sections in a couple of cases where the address of the |
| 78 | // insignificant to the user program and the Visual C++ linker does this. | 78 | // section is insignificant to the user program and the behaviour matches that |
| 79 | // of the Visual C++ linker. | ||
| 79 | bool ICF::isEligible(SectionChunk *C) { | 80 | bool ICF::isEligible(SectionChunk *C) { |
| 80 | // Non-comdat chunks, dead chunks, and writable chunks are not elegible. | 81 | // Non-comdat chunks, dead chunks, and writable chunks are not elegible. |
| 81 | bool Writable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_WRITE; | 82 | bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE; |
| 82 | if (!C->isCOMDAT() || !C->isLive() || Writable) | 83 | if (!C->isCOMDAT() || !C->isLive() || Writable) |
| 83 | return false; | 84 | return false; |
| 84 | 85 | ||
| 85 | // Code sections are eligible. | 86 | // Code sections are eligible. |
| 86 | if (C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE) | 87 | if (C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE) |
| 87 | return true; | 88 | return true; |
| 88 | 89 | ||
| 89 | // .xdata unwind info sections are eligble. | 90 | // .pdata and .xdata unwind info sections are eligible. |
| 90 | return C->getSectionName().split('$').first == ".xdata"; | 91 | StringRef OutSecName = C->getSectionName().split('$').first; |
| 92 | if (OutSecName == ".pdata" || OutSecName == ".xdata") | ||
| 93 | return true; | ||
| 94 | |||
| 95 | // So are vtables. | ||
| 96 | return C->Sym && C->Sym->getName().startswith("??_7"); | ||
| 91 | } | 97 | } |
| 92 | 98 | ||
| 93 | // Split an equivalence class into smaller classes. | 99 | // Split an equivalence class into smaller classes. |
| ... | @@ -116,10 +122,23 @@ void ICF::segregate(size_t Begin, size_t End, bool Constant) { | ... | @@ -116,10 +122,23 @@ void ICF::segregate(size_t Begin, size_t End, bool Constant) { |
| 116 | } | 122 | } |
| 117 | } | 123 | } |
| 118 | 124 | ||
| 125 | // Returns true if two sections' associative children are equal. | ||
| 126 | bool ICF::assocEquals(const SectionChunk *A, const SectionChunk *B) { | ||
| 127 | auto ChildClasses = [&](const SectionChunk *SC) { | ||
| 128 | std::vector<uint32_t> Classes; | ||
| 129 | for (const SectionChunk *C : SC->children()) | ||
| 130 | if (!C->SectionName.startswith(".debug") && | ||
| 131 | C->SectionName != ".gfids$y" && C->SectionName != ".gljmp$y") | ||
| 132 | Classes.push_back(C->Class[Cnt % 2]); | ||
| 133 | return Classes; | ||
| 134 | }; | ||
| 135 | return ChildClasses(A) == ChildClasses(B); | ||
| 136 | } | ||
| 137 | |||
| 119 | // Compare "non-moving" part of two sections, namely everything | 138 | // Compare "non-moving" part of two sections, namely everything |
| 120 | // except relocation targets. | 139 | // except relocation targets. |
| 121 | bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) { | 140 | bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) { |
| 122 | if (A->NumRelocs != B->NumRelocs) | 141 | if (A->Relocs.size() != B->Relocs.size()) |
| 123 | return false; | 142 | return false; |
| 124 | 143 | ||
| 125 | // Compare relocations. | 144 | // Compare relocations. |
| ... | @@ -142,10 +161,11 @@ bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) { | ... | @@ -142,10 +161,11 @@ bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) { |
| 142 | return false; | 161 | return false; |
| 143 | 162 | ||
| 144 | // Compare section attributes and contents. | 163 | // Compare section attributes and contents. |
| 145 | return A->getPermissions() == B->getPermissions() && | 164 | return A->getOutputCharacteristics() == B->getOutputCharacteristics() && |
| 146 | A->SectionName == B->SectionName && A->Alignment == B->Alignment && | 165 | A->SectionName == B->SectionName && |
| 147 | A->Header->SizeOfRawData == B->Header->SizeOfRawData && | 166 | A->Header->SizeOfRawData == B->Header->SizeOfRawData && |
| 148 | A->Checksum == B->Checksum && A->getContents() == B->getContents(); | 167 | A->Checksum == B->Checksum && A->getContents() == B->getContents() && |
| 168 | assocEquals(A, B); | ||
| 149 | } | 169 | } |
| 150 | 170 | ||
| 151 | // Compare "moving" part of two sections, namely relocation targets. | 171 | // Compare "moving" part of two sections, namely relocation targets. |
| ... | @@ -161,9 +181,12 @@ bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) { | ... | @@ -161,9 +181,12 @@ bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) { |
| 161 | return D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2]; | 181 | return D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2]; |
| 162 | return false; | 182 | return false; |
| 163 | }; | 183 | }; |
| 164 | return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq); | 184 | return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), |
| 185 | Eq) && | ||
| 186 | assocEquals(A, B); | ||
| 165 | } | 187 | } |
| 166 | 188 | ||
| 189 | // Find the first Chunk after Begin that has a different class from Begin. | ||
| 167 | size_t ICF::findBoundary(size_t Begin, size_t End) { | 190 | size_t ICF::findBoundary(size_t Begin, size_t End) { |
| 168 | for (size_t I = Begin + 1; I < End; ++I) | 191 | for (size_t I = Begin + 1; I < End; ++I) |
| 169 | if (Chunks[Begin]->Class[Cnt % 2] != Chunks[I]->Class[Cnt % 2]) | 192 | if (Chunks[Begin]->Class[Cnt % 2] != Chunks[I]->Class[Cnt % 2]) |
| ... | @@ -173,11 +196,8 @@ size_t ICF::findBoundary(size_t Begin, size_t End) { | ... | @@ -173,11 +196,8 @@ size_t ICF::findBoundary(size_t Begin, size_t End) { |
| 173 | 196 | ||
| 174 | void ICF::forEachClassRange(size_t Begin, size_t End, | 197 | void ICF::forEachClassRange(size_t Begin, size_t End, |
| 175 | std::function<void(size_t, size_t)> Fn) { | 198 | std::function<void(size_t, size_t)> Fn) { |
| 176 | if (Begin > 0) | ||
| 177 | Begin = findBoundary(Begin - 1, End); | ||
| 178 | |||
| 179 | while (Begin < End) { | 199 | while (Begin < End) { |
| 180 | size_t Mid = findBoundary(Begin, Chunks.size()); | 200 | size_t Mid = findBoundary(Begin, End); |
| 181 | Fn(Begin, Mid); | 201 | Fn(Begin, Mid); |
| 182 | Begin = Mid; | 202 | Begin = Mid; |
| 183 | } | 203 | } |
| ... | @@ -193,12 +213,22 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) { | ... | @@ -193,12 +213,22 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) { |
| 193 | return; | 213 | return; |
| 194 | } | 214 | } |
| 195 | 215 | ||
| 196 | // Split sections into 256 shards and call Fn in parallel. | 216 | // Shard into non-overlapping intervals, and call Fn in parallel. |
| 197 | size_t NumShards = 256; | 217 | // The sharding must be completed before any calls to Fn are made |
| 218 | // so that Fn can modify the Chunks in its shard without causing data | ||
| 219 | // races. | ||
| 220 | const size_t NumShards = 256; | ||
| 198 | size_t Step = Chunks.size() / NumShards; | 221 | size_t Step = Chunks.size() / NumShards; |
| 199 | for_each_n(parallel::par, size_t(0), NumShards, [&](size_t I) { | 222 | size_t Boundaries[NumShards + 1]; |
| 200 | size_t End = (I == NumShards - 1) ? Chunks.size() : (I + 1) * Step; | 223 | Boundaries[0] = 0; |
| 201 | forEachClassRange(I * Step, End, Fn); | 224 | Boundaries[NumShards] = Chunks.size(); |
| 225 | for_each_n(parallel::par, size_t(1), NumShards, [&](size_t I) { | ||
| 226 | Boundaries[I] = findBoundary((I - 1) * Step, Chunks.size()); | ||
| 227 | }); | ||
| 228 | for_each_n(parallel::par, size_t(1), NumShards + 1, [&](size_t I) { | ||
| 229 | if (Boundaries[I - 1] < Boundaries[I]) { | ||
| 230 | forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn); | ||
| 231 | } | ||
| 202 | }); | 232 | }); |
| 203 | ++Cnt; | 233 | ++Cnt; |
| 204 | } | 234 | } |
| ... | @@ -207,6 +237,8 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) { | ... | @@ -207,6 +237,8 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) { |
| 207 | // Two sections are considered the same if their section headers, | 237 | // Two sections are considered the same if their section headers, |
| 208 | // contents and relocations are all the same. | 238 | // contents and relocations are all the same. |
| 209 | void ICF::run(ArrayRef<Chunk *> Vec) { | 239 | void ICF::run(ArrayRef<Chunk *> Vec) { |
| 240 | ScopedTimer T(ICFTimer); | ||
| 241 | |||
| 210 | // Collect only mergeable sections and group by hash value. | 242 | // Collect only mergeable sections and group by hash value. |
| 211 | uint32_t NextId = 1; | 243 | uint32_t NextId = 1; |
| 212 | for (Chunk *C : Vec) { | 244 | for (Chunk *C : Vec) { |
| ... | @@ -218,10 +250,16 @@ void ICF::run(ArrayRef<Chunk *> Vec) { | ... | @@ -218,10 +250,16 @@ void ICF::run(ArrayRef<Chunk *> Vec) { |
| 218 | } | 250 | } |
| 219 | } | 251 | } |
| 220 | 252 | ||
| 253 | // Make sure that ICF doesn't merge sections that are being handled by string | ||
| 254 | // tail merging. | ||
| 255 | for (auto &P : MergeChunk::Instances) | ||
| 256 | for (SectionChunk *SC : P.second->Sections) | ||
| 257 | SC->Class[0] = NextId++; | ||
| 258 | |||
| 221 | // Initially, we use hash values to partition sections. | 259 | // Initially, we use hash values to partition sections. |
| 222 | for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) { | 260 | for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) { |
| 223 | // Set MSB to 1 to avoid collisions with non-hash classs. | 261 | // Set MSB to 1 to avoid collisions with non-hash classs. |
| 224 | SC->Class[0] = getHash(SC) | (1 << 31); | 262 | SC->Class[0] = xxHash64(SC->getContents()) | (1 << 31); |
| 225 | }); | 263 | }); |
| 226 | 264 | ||
| 227 | // From now on, sections in Chunks are ordered so that sections in | 265 | // From now on, sections in Chunks are ordered so that sections in |
deps/lld/COFF/ICF.h created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | //===- ICF.h --------------------------------------------------------------===// | ||
| 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_COFF_ICF_H | ||
| 11 | #define LLD_COFF_ICF_H | ||
| 12 | |||
| 13 | #include "lld/Common/LLVM.h" | ||
| 14 | #include "llvm/ADT/ArrayRef.h" | ||
| 15 | |||
| 16 | namespace lld { | ||
| 17 | namespace coff { | ||
| 18 | |||
| 19 | class Chunk; | ||
| 20 | |||
| 21 | void doICF(ArrayRef<Chunk *> Chunks); | ||
| 22 | |||
| 23 | } // namespace coff | ||
| 24 | } // namespace lld | ||
| 25 | |||
| 26 | #endif | ||
deps/lld/COFF/InputFiles.cpp+53-39| ... | @@ -27,6 +27,7 @@ | ... | @@ -27,6 +27,7 @@ |
| 27 | #include "llvm/Support/Error.h" | 27 | #include "llvm/Support/Error.h" |
| 28 | #include "llvm/Support/ErrorOr.h" | 28 | #include "llvm/Support/ErrorOr.h" |
| 29 | #include "llvm/Support/FileSystem.h" | 29 | #include "llvm/Support/FileSystem.h" |
| 30 | #include "llvm/Support/Path.h" | ||
| 30 | #include "llvm/Target/TargetOptions.h" | 31 | #include "llvm/Target/TargetOptions.h" |
| 31 | #include <cstring> | 32 | #include <cstring> |
| 32 | #include <system_error> | 33 | #include <system_error> |
| ... | @@ -138,12 +139,13 @@ void ObjFile::initializeChunks() { | ... | @@ -138,12 +139,13 @@ void ObjFile::initializeChunks() { |
| 138 | if (Sec->Characteristics & IMAGE_SCN_LNK_COMDAT) | 139 | if (Sec->Characteristics & IMAGE_SCN_LNK_COMDAT) |
| 139 | SparseChunks[I] = PendingComdat; | 140 | SparseChunks[I] = PendingComdat; |
| 140 | else | 141 | else |
| 141 | SparseChunks[I] = readSection(I, nullptr); | 142 | SparseChunks[I] = readSection(I, nullptr, ""); |
| 142 | } | 143 | } |
| 143 | } | 144 | } |
| 144 | 145 | ||
| 145 | SectionChunk *ObjFile::readSection(uint32_t SectionNumber, | 146 | SectionChunk *ObjFile::readSection(uint32_t SectionNumber, |
| 146 | const coff_aux_section_definition *Def) { | 147 | const coff_aux_section_definition *Def, |
| 148 | StringRef LeaderName) { | ||
| 147 | const coff_section *Sec; | 149 | const coff_section *Sec; |
| 148 | StringRef Name; | 150 | StringRef Name; |
| 149 | if (auto EC = COFFObj->getSection(SectionNumber, Sec)) | 151 | if (auto EC = COFFObj->getSection(SectionNumber, Sec)) |
| ... | @@ -151,15 +153,7 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, | ... | @@ -151,15 +153,7 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, |
| 151 | if (auto EC = COFFObj->getSectionName(Sec, Name)) | 153 | if (auto EC = COFFObj->getSectionName(Sec, Name)) |
| 152 | fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " + | 154 | fatal("getSectionName failed: #" + Twine(SectionNumber) + ": " + |
| 153 | EC.message()); | 155 | EC.message()); |
| 154 | if (Name == ".sxdata") { | 156 | |
| 155 | ArrayRef<uint8_t> Data; | ||
| 156 | COFFObj->getSectionContents(Sec, Data); | ||
| 157 | if (Data.size() % 4 != 0) | ||
| 158 | fatal(".sxdata must be an array of symbol table indices"); | ||
| 159 | SXData = {reinterpret_cast<const ulittle32_t *>(Data.data()), | ||
| 160 | Data.size() / 4}; | ||
| 161 | return nullptr; | ||
| 162 | } | ||
| 163 | if (Name == ".drectve") { | 157 | if (Name == ".drectve") { |
| 164 | ArrayRef<uint8_t> Data; | 158 | ArrayRef<uint8_t> Data; |
| 165 | COFFObj->getSectionContents(Sec, Data); | 159 | COFFObj->getSectionContents(Sec, Data); |
| ... | @@ -177,8 +171,8 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, | ... | @@ -177,8 +171,8 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, |
| 177 | // CodeView needs a linker support. We need to interpret and debug | 171 | // CodeView needs a linker support. We need to interpret and debug |
| 178 | // info, and then write it to a separate .pdb file. | 172 | // info, and then write it to a separate .pdb file. |
| 179 | 173 | ||
| 180 | // Ignore debug info unless /debug is given. | 174 | // Ignore DWARF debug info unless /debug is given. |
| 181 | if (!Config->Debug && Name.startswith(".debug")) | 175 | if (!Config->Debug && Name.startswith(".debug_")) |
| 182 | return nullptr; | 176 | return nullptr; |
| 183 | 177 | ||
| 184 | if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) | 178 | if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) |
| ... | @@ -191,6 +185,18 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, | ... | @@ -191,6 +185,18 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber, |
| 191 | // linked in the regular manner. | 185 | // linked in the regular manner. |
| 192 | if (C->isCodeView()) | 186 | if (C->isCodeView()) |
| 193 | DebugChunks.push_back(C); | 187 | DebugChunks.push_back(C); |
| 188 | else if (Config->GuardCF != GuardCFLevel::Off && Name == ".gfids$y") | ||
| 189 | GuardFidChunks.push_back(C); | ||
| 190 | else if (Config->GuardCF != GuardCFLevel::Off && Name == ".gljmp$y") | ||
| 191 | GuardLJmpChunks.push_back(C); | ||
| 192 | else if (Name == ".sxdata") | ||
| 193 | SXDataChunks.push_back(C); | ||
| 194 | else if (Config->TailMerge && Sec->NumberOfRelocations == 0 && | ||
| 195 | Name == ".rdata" && LeaderName.startswith("??_C@")) | ||
| 196 | // COFF sections that look like string literal sections (i.e. no | ||
| 197 | // relocations, in .rdata, leader symbol name matches the MSVC name mangling | ||
| 198 | // for string literals) are subject to string tail merging. | ||
| 199 | MergeChunk::addSection(C); | ||
| 194 | else | 200 | else |
| 195 | Chunks.push_back(C); | 201 | Chunks.push_back(C); |
| 196 | 202 | ||
| ... | @@ -211,7 +217,7 @@ void ObjFile::readAssociativeDefinition( | ... | @@ -211,7 +217,7 @@ void ObjFile::readAssociativeDefinition( |
| 211 | // the section; otherwise mark it as discarded. | 217 | // the section; otherwise mark it as discarded. |
| 212 | int32_t SectionNumber = Sym.getSectionNumber(); | 218 | int32_t SectionNumber = Sym.getSectionNumber(); |
| 213 | if (Parent) { | 219 | if (Parent) { |
| 214 | SparseChunks[SectionNumber] = readSection(SectionNumber, Def); | 220 | SparseChunks[SectionNumber] = readSection(SectionNumber, Def, ""); |
| 215 | if (SparseChunks[SectionNumber]) | 221 | if (SparseChunks[SectionNumber]) |
| 216 | Parent->addAssociative(SparseChunks[SectionNumber]); | 222 | Parent->addAssociative(SparseChunks[SectionNumber]); |
| 217 | } else { | 223 | } else { |
| ... | @@ -275,6 +281,13 @@ void ObjFile::initializeSymbols() { | ... | @@ -275,6 +281,13 @@ void ObjFile::initializeSymbols() { |
| 275 | if (auto *Def = Sym.getSectionDefinition()) | 281 | if (auto *Def = Sym.getSectionDefinition()) |
| 276 | if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) | 282 | if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) |
| 277 | readAssociativeDefinition(Sym, Def); | 283 | readAssociativeDefinition(Sym, Def); |
| 284 | if (SparseChunks[Sym.getSectionNumber()] == PendingComdat) { | ||
| 285 | StringRef Name; | ||
| 286 | COFFObj->getSymbolName(Sym, Name); | ||
| 287 | log("comdat section " + Name + | ||
| 288 | " without leader and unassociated, discarding"); | ||
| 289 | continue; | ||
| 290 | } | ||
| 278 | Symbols[I] = createRegular(Sym); | 291 | Symbols[I] = createRegular(Sym); |
| 279 | } | 292 | } |
| 280 | 293 | ||
| ... | @@ -294,43 +307,46 @@ Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) { | ... | @@ -294,43 +307,46 @@ Symbol *ObjFile::createUndefined(COFFSymbolRef Sym) { |
| 294 | Optional<Symbol *> ObjFile::createDefined( | 307 | Optional<Symbol *> ObjFile::createDefined( |
| 295 | COFFSymbolRef Sym, | 308 | COFFSymbolRef Sym, |
| 296 | std::vector<const coff_aux_section_definition *> &ComdatDefs) { | 309 | std::vector<const coff_aux_section_definition *> &ComdatDefs) { |
| 297 | StringRef Name; | 310 | auto GetName = [&]() { |
| 311 | StringRef S; | ||
| 312 | COFFObj->getSymbolName(Sym, S); | ||
| 313 | return S; | ||
| 314 | }; | ||
| 315 | |||
| 298 | if (Sym.isCommon()) { | 316 | if (Sym.isCommon()) { |
| 299 | auto *C = make<CommonChunk>(Sym); | 317 | auto *C = make<CommonChunk>(Sym); |
| 300 | Chunks.push_back(C); | 318 | Chunks.push_back(C); |
| 301 | COFFObj->getSymbolName(Sym, Name); | 319 | return Symtab->addCommon(this, GetName(), Sym.getValue(), Sym.getGeneric(), |
| 302 | Symbol *S = | 320 | C); |
| 303 | Symtab->addCommon(this, Name, Sym.getValue(), Sym.getGeneric(), C); | ||
| 304 | return S; | ||
| 305 | } | 321 | } |
| 322 | |||
| 306 | if (Sym.isAbsolute()) { | 323 | if (Sym.isAbsolute()) { |
| 307 | COFFObj->getSymbolName(Sym, Name); | 324 | StringRef Name = GetName(); |
| 325 | |||
| 308 | // Skip special symbols. | 326 | // Skip special symbols. |
| 309 | if (Name == "@comp.id") | 327 | if (Name == "@comp.id") |
| 310 | return nullptr; | 328 | return nullptr; |
| 311 | // COFF spec 5.10.1. The .sxdata section. | ||
| 312 | if (Name == "@feat.00") { | 329 | if (Name == "@feat.00") { |
| 313 | if (Sym.getValue() & 1) | 330 | Feat00Flags = Sym.getValue(); |
| 314 | SEHCompat = true; | ||
| 315 | return nullptr; | 331 | return nullptr; |
| 316 | } | 332 | } |
| 333 | |||
| 317 | if (Sym.isExternal()) | 334 | if (Sym.isExternal()) |
| 318 | return Symtab->addAbsolute(Name, Sym); | 335 | return Symtab->addAbsolute(Name, Sym); |
| 319 | else | 336 | return make<DefinedAbsolute>(Name, Sym); |
| 320 | return make<DefinedAbsolute>(Name, Sym); | ||
| 321 | } | 337 | } |
| 338 | |||
| 322 | int32_t SectionNumber = Sym.getSectionNumber(); | 339 | int32_t SectionNumber = Sym.getSectionNumber(); |
| 323 | if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) | 340 | if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) |
| 324 | return nullptr; | 341 | return nullptr; |
| 325 | 342 | ||
| 326 | // Reserved sections numbers don't have contents. | ||
| 327 | if (llvm::COFF::isReservedSectionNumber(SectionNumber)) | 343 | if (llvm::COFF::isReservedSectionNumber(SectionNumber)) |
| 328 | fatal("broken object file: " + toString(this)); | 344 | fatal(toString(this) + ": " + GetName() + |
| 345 | " should not refer to special section " + Twine(SectionNumber)); | ||
| 329 | 346 | ||
| 330 | // This symbol references a section which is not present in the section | ||
| 331 | // header. | ||
| 332 | if ((uint32_t)SectionNumber >= SparseChunks.size()) | 347 | if ((uint32_t)SectionNumber >= SparseChunks.size()) |
| 333 | fatal("broken object file: " + toString(this)); | 348 | fatal(toString(this) + ": " + GetName() + |
| 349 | " should not refer to non-existent section " + Twine(SectionNumber)); | ||
| 334 | 350 | ||
| 335 | // Handle comdat leader symbols. | 351 | // Handle comdat leader symbols. |
| 336 | if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) { | 352 | if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) { |
| ... | @@ -338,16 +354,16 @@ Optional<Symbol *> ObjFile::createDefined( | ... | @@ -338,16 +354,16 @@ Optional<Symbol *> ObjFile::createDefined( |
| 338 | Symbol *Leader; | 354 | Symbol *Leader; |
| 339 | bool Prevailing; | 355 | bool Prevailing; |
| 340 | if (Sym.isExternal()) { | 356 | if (Sym.isExternal()) { |
| 341 | COFFObj->getSymbolName(Sym, Name); | ||
| 342 | std::tie(Leader, Prevailing) = | 357 | std::tie(Leader, Prevailing) = |
| 343 | Symtab->addComdat(this, Name, Sym.getGeneric()); | 358 | Symtab->addComdat(this, GetName(), Sym.getGeneric()); |
| 344 | } else { | 359 | } else { |
| 345 | Leader = make<DefinedRegular>(this, /*Name*/ "", false, | 360 | Leader = make<DefinedRegular>(this, /*Name*/ "", false, |
| 346 | /*IsExternal*/ false, Sym.getGeneric()); | 361 | /*IsExternal*/ false, Sym.getGeneric()); |
| 347 | Prevailing = true; | 362 | Prevailing = true; |
| 348 | } | 363 | } |
| 364 | |||
| 349 | if (Prevailing) { | 365 | if (Prevailing) { |
| 350 | SectionChunk *C = readSection(SectionNumber, Def); | 366 | SectionChunk *C = readSection(SectionNumber, Def, GetName()); |
| 351 | SparseChunks[SectionNumber] = C; | 367 | SparseChunks[SectionNumber] = C; |
| 352 | C->Sym = cast<DefinedRegular>(Leader); | 368 | C->Sym = cast<DefinedRegular>(Leader); |
| 353 | cast<DefinedRegular>(Leader)->Data = &C->Repl; | 369 | cast<DefinedRegular>(Leader)->Data = &C->Repl; |
| ... | @@ -429,7 +445,8 @@ void ImportFile::parse() { | ... | @@ -429,7 +445,8 @@ void ImportFile::parse() { |
| 429 | // address pointed by the __imp_ symbol. (This allows you to call | 445 | // address pointed by the __imp_ symbol. (This allows you to call |
| 430 | // DLL functions just like regular non-DLL functions.) | 446 | // DLL functions just like regular non-DLL functions.) |
| 431 | if (Hdr->getType() == llvm::COFF::IMPORT_CODE) | 447 | if (Hdr->getType() == llvm::COFF::IMPORT_CODE) |
| 432 | ThunkSym = Symtab->addImportThunk(Name, ImpSym, Hdr->Machine); | 448 | ThunkSym = Symtab->addImportThunk( |
| 449 | Name, cast_or_null<DefinedImportData>(ImpSym), Hdr->Machine); | ||
| 433 | } | 450 | } |
| 434 | 451 | ||
| 435 | void BitcodeFile::parse() { | 452 | void BitcodeFile::parse() { |
| ... | @@ -462,7 +479,7 @@ void BitcodeFile::parse() { | ... | @@ -462,7 +479,7 @@ void BitcodeFile::parse() { |
| 462 | } else { | 479 | } else { |
| 463 | Sym = Symtab->addRegular(this, SymName); | 480 | Sym = Symtab->addRegular(this, SymName); |
| 464 | } | 481 | } |
| 465 | SymbolBodies.push_back(Sym); | 482 | Symbols.push_back(Sym); |
| 466 | } | 483 | } |
| 467 | Directives = Obj->getCOFFLinkerOpts(); | 484 | Directives = Obj->getCOFFLinkerOpts(); |
| 468 | } | 485 | } |
| ... | @@ -486,10 +503,7 @@ MachineTypes BitcodeFile::getMachineType() { | ... | @@ -486,10 +503,7 @@ MachineTypes BitcodeFile::getMachineType() { |
| 486 | 503 | ||
| 487 | // Returns the last element of a path, which is supposed to be a filename. | 504 | // Returns the last element of a path, which is supposed to be a filename. |
| 488 | static StringRef getBasename(StringRef Path) { | 505 | static StringRef getBasename(StringRef Path) { |
| 489 | size_t Pos = Path.find_last_of("\\/"); | 506 | return sys::path::filename(Path, sys::path::Style::windows); |
| 490 | if (Pos == StringRef::npos) | ||
| 491 | return Path; | ||
| 492 | return Path.substr(Pos + 1); | ||
| 493 | } | 507 | } |
| 494 | 508 | ||
| 495 | // Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)". | 509 | // Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)". |
deps/lld/COFF/InputFiles.h+35-16| ... | @@ -110,6 +110,9 @@ public: | ... | @@ -110,6 +110,9 @@ public: |
| 110 | MachineTypes getMachineType() override; | 110 | MachineTypes getMachineType() override; |
| 111 | ArrayRef<Chunk *> getChunks() { return Chunks; } | 111 | ArrayRef<Chunk *> getChunks() { return Chunks; } |
| 112 | ArrayRef<SectionChunk *> getDebugChunks() { return DebugChunks; } | 112 | ArrayRef<SectionChunk *> getDebugChunks() { return DebugChunks; } |
| 113 | ArrayRef<SectionChunk *> getSXDataChunks() { return SXDataChunks; } | ||
| 114 | ArrayRef<SectionChunk *> getGuardFidChunks() { return GuardFidChunks; } | ||
| 115 | ArrayRef<SectionChunk *> getGuardLJmpChunks() { return GuardLJmpChunks; } | ||
| 113 | ArrayRef<Symbol *> getSymbols() { return Symbols; } | 116 | ArrayRef<Symbol *> getSymbols() { return Symbols; } |
| 114 | 117 | ||
| 115 | // Returns a Symbol object for the SymbolIndex'th symbol in the | 118 | // Returns a Symbol object for the SymbolIndex'th symbol in the |
| ... | @@ -123,13 +126,17 @@ public: | ... | @@ -123,13 +126,17 @@ public: |
| 123 | 126 | ||
| 124 | static std::vector<ObjFile *> Instances; | 127 | static std::vector<ObjFile *> Instances; |
| 125 | 128 | ||
| 126 | // True if this object file is compatible with SEH. | 129 | // Flags in the absolute @feat.00 symbol if it is present. These usually |
| 127 | // COFF-specific and x86-only. | 130 | // indicate if an object was compiled with certain security features enabled |
| 128 | bool SEHCompat = false; | 131 | // like stack guard, safeseh, /guard:cf, or other things. |
| 132 | uint32_t Feat00Flags = 0; | ||
| 129 | 133 | ||
| 130 | // The symbol table indexes of the safe exception handlers. | 134 | // True if this object file is compatible with SEH. COFF-specific and |
| 131 | // COFF-specific and x86-only. | 135 | // x86-only. COFF spec 5.10.1. The .sxdata section. |
| 132 | ArrayRef<llvm::support::ulittle32_t> SXData; | 136 | bool hasSafeSEH() { return Feat00Flags & 0x1; } |
| 137 | |||
| 138 | // True if this file was compiled with /guard:cf. | ||
| 139 | bool hasGuardCF() { return Feat00Flags & 0x800; } | ||
| 133 | 140 | ||
| 134 | // Pointer to the PDB module descriptor builder. Various debug info records | 141 | // Pointer to the PDB module descriptor builder. Various debug info records |
| 135 | // will reference object files by "module index", which is here. Things like | 142 | // will reference object files by "module index", which is here. Things like |
| ... | @@ -143,7 +150,8 @@ private: | ... | @@ -143,7 +150,8 @@ private: |
| 143 | 150 | ||
| 144 | SectionChunk * | 151 | SectionChunk * |
| 145 | readSection(uint32_t SectionNumber, | 152 | readSection(uint32_t SectionNumber, |
| 146 | const llvm::object::coff_aux_section_definition *Def); | 153 | const llvm::object::coff_aux_section_definition *Def, |
| 154 | StringRef LeaderName); | ||
| 147 | 155 | ||
| 148 | void readAssociativeDefinition( | 156 | void readAssociativeDefinition( |
| 149 | COFFSymbolRef COFFSym, | 157 | COFFSymbolRef COFFSym, |
| ... | @@ -165,6 +173,15 @@ private: | ... | @@ -165,6 +173,15 @@ private: |
| 165 | // CodeView debug info sections. | 173 | // CodeView debug info sections. |
| 166 | std::vector<SectionChunk *> DebugChunks; | 174 | std::vector<SectionChunk *> DebugChunks; |
| 167 | 175 | ||
| 176 | // Chunks containing symbol table indices of exception handlers. Only used for | ||
| 177 | // 32-bit x86. | ||
| 178 | std::vector<SectionChunk *> SXDataChunks; | ||
| 179 | |||
| 180 | // Chunks containing symbol table indices of address taken symbols and longjmp | ||
| 181 | // targets. These are not linked into the final binary when /guard:cf is set. | ||
| 182 | std::vector<SectionChunk *> GuardFidChunks; | ||
| 183 | std::vector<SectionChunk *> GuardLJmpChunks; | ||
| 184 | |||
| 168 | // This vector contains the same chunks as Chunks, but they are | 185 | // This vector contains the same chunks as Chunks, but they are |
| 169 | // indexed such that you can get a SectionChunk by section index. | 186 | // indexed such that you can get a SectionChunk by section index. |
| 170 | // Nonexistent section indices are filled with null pointers. | 187 | // Nonexistent section indices are filled with null pointers. |
| ... | @@ -184,15 +201,14 @@ private: | ... | @@ -184,15 +201,14 @@ private: |
| 184 | // for details about the format. | 201 | // for details about the format. |
| 185 | class ImportFile : public InputFile { | 202 | class ImportFile : public InputFile { |
| 186 | public: | 203 | public: |
| 187 | explicit ImportFile(MemoryBufferRef M) | 204 | explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind, M) {} |
| 188 | : InputFile(ImportKind, M), Live(!Config->DoGC) {} | ||
| 189 | 205 | ||
| 190 | static bool classof(const InputFile *F) { return F->kind() == ImportKind; } | 206 | static bool classof(const InputFile *F) { return F->kind() == ImportKind; } |
| 191 | 207 | ||
| 192 | static std::vector<ImportFile *> Instances; | 208 | static std::vector<ImportFile *> Instances; |
| 193 | 209 | ||
| 194 | DefinedImportData *ImpSym = nullptr; | 210 | Symbol *ImpSym = nullptr; |
| 195 | DefinedImportThunk *ThunkSym = nullptr; | 211 | Symbol *ThunkSym = nullptr; |
| 196 | std::string DLLName; | 212 | std::string DLLName; |
| 197 | 213 | ||
| 198 | private: | 214 | private: |
| ... | @@ -204,12 +220,15 @@ public: | ... | @@ -204,12 +220,15 @@ public: |
| 204 | Chunk *Location = nullptr; | 220 | Chunk *Location = nullptr; |
| 205 | 221 | ||
| 206 | // We want to eliminate dllimported symbols if no one actually refers them. | 222 | // We want to eliminate dllimported symbols if no one actually refers them. |
| 207 | // This "Live" bit is used to keep track of which import library members | 223 | // These "Live" bits are used to keep track of which import library members |
| 208 | // are actually in use. | 224 | // are actually in use. |
| 209 | // | 225 | // |
| 210 | // If the Live bit is turned off by MarkLive, Writer will ignore dllimported | 226 | // If the Live bit is turned off by MarkLive, Writer will ignore dllimported |
| 211 | // symbols provided by this import library member. | 227 | // symbols provided by this import library member. We also track whether the |
| 212 | bool Live; | 228 | // imported symbol is used separately from whether the thunk is used in order |
| 229 | // to avoid creating unnecessary thunks. | ||
| 230 | bool Live = !Config->DoGC; | ||
| 231 | bool ThunkLive = !Config->DoGC; | ||
| 213 | }; | 232 | }; |
| 214 | 233 | ||
| 215 | // Used for LTO. | 234 | // Used for LTO. |
| ... | @@ -217,7 +236,7 @@ class BitcodeFile : public InputFile { | ... | @@ -217,7 +236,7 @@ class BitcodeFile : public InputFile { |
| 217 | public: | 236 | public: |
| 218 | explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {} | 237 | explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {} |
| 219 | static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } | 238 | static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } |
| 220 | ArrayRef<Symbol *> getSymbols() { return SymbolBodies; } | 239 | ArrayRef<Symbol *> getSymbols() { return Symbols; } |
| 221 | MachineTypes getMachineType() override; | 240 | MachineTypes getMachineType() override; |
| 222 | static std::vector<BitcodeFile *> Instances; | 241 | static std::vector<BitcodeFile *> Instances; |
| 223 | std::unique_ptr<llvm::lto::InputFile> Obj; | 242 | std::unique_ptr<llvm::lto::InputFile> Obj; |
| ... | @@ -225,7 +244,7 @@ public: | ... | @@ -225,7 +244,7 @@ public: |
| 225 | private: | 244 | private: |
| 226 | void parse() override; | 245 | void parse() override; |
| 227 | 246 | ||
| 228 | std::vector<Symbol *> SymbolBodies; | 247 | std::vector<Symbol *> Symbols; |
| 229 | }; | 248 | }; |
| 230 | } // namespace coff | 249 | } // namespace coff |
| 231 | 250 |
deps/lld/COFF/LTO.cpp+28-42| ... | @@ -12,6 +12,7 @@ | ... | @@ -12,6 +12,7 @@ |
| 12 | #include "InputFiles.h" | 12 | #include "InputFiles.h" |
| 13 | #include "Symbols.h" | 13 | #include "Symbols.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | 14 | #include "lld/Common/ErrorHandler.h" |
| 15 | #include "lld/Common/Strings.h" | ||
| 15 | #include "lld/Common/TargetOptionsCommandFlags.h" | 16 | #include "lld/Common/TargetOptionsCommandFlags.h" |
| 16 | #include "llvm/ADT/STLExtras.h" | 17 | #include "llvm/ADT/STLExtras.h" |
| 17 | #include "llvm/ADT/SmallString.h" | 18 | #include "llvm/ADT/SmallString.h" |
| ... | @@ -40,47 +41,32 @@ using namespace llvm::object; | ... | @@ -40,47 +41,32 @@ using namespace llvm::object; |
| 40 | using namespace lld; | 41 | using namespace lld; |
| 41 | using namespace lld::coff; | 42 | using namespace lld::coff; |
| 42 | 43 | ||
| 43 | static void diagnosticHandler(const DiagnosticInfo &DI) { | 44 | static std::unique_ptr<lto::LTO> createLTO() { |
| 44 | SmallString<128> ErrStorage; | 45 | lto::Config C; |
| 45 | raw_svector_ostream OS(ErrStorage); | 46 | C.Options = InitTargetOptionsFromCodeGenFlags(); |
| 46 | DiagnosticPrinterRawOStream DP(OS); | ||
| 47 | DI.print(DP); | ||
| 48 | warn(ErrStorage); | ||
| 49 | } | ||
| 50 | |||
| 51 | static void checkError(Error E) { | ||
| 52 | handleAllErrors(std::move(E), | ||
| 53 | [&](ErrorInfoBase &EIB) { error(EIB.message()); }); | ||
| 54 | } | ||
| 55 | 47 | ||
| 56 | static void saveBuffer(StringRef Buffer, const Twine &Path) { | 48 | // Always emit a section per function/datum with LTO. LLVM LTO should get most |
| 57 | std::error_code EC; | 49 | // of the benefit of linker GC, but there are still opportunities for ICF. |
| 58 | raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); | 50 | C.Options.FunctionSections = true; |
| 59 | if (EC) | 51 | C.Options.DataSections = true; |
| 60 | error("cannot create " + Path + ": " + EC.message()); | ||
| 61 | OS << Buffer; | ||
| 62 | } | ||
| 63 | 52 | ||
| 64 | static std::unique_ptr<lto::LTO> createLTO() { | ||
| 65 | lto::Config Conf; | ||
| 66 | Conf.Options = InitTargetOptionsFromCodeGenFlags(); | ||
| 67 | // Use static reloc model on 32-bit x86 because it usually results in more | 53 | // Use static reloc model on 32-bit x86 because it usually results in more |
| 68 | // compact code, and because there are also known code generation bugs when | 54 | // compact code, and because there are also known code generation bugs when |
| 69 | // using the PIC model (see PR34306). | 55 | // using the PIC model (see PR34306). |
| 70 | if (Config->Machine == COFF::IMAGE_FILE_MACHINE_I386) | 56 | if (Config->Machine == COFF::IMAGE_FILE_MACHINE_I386) |
| 71 | Conf.RelocModel = Reloc::Static; | 57 | C.RelocModel = Reloc::Static; |
| 72 | else | 58 | else |
| 73 | Conf.RelocModel = Reloc::PIC_; | 59 | C.RelocModel = Reloc::PIC_; |
| 74 | Conf.DisableVerify = true; | 60 | C.DisableVerify = true; |
| 75 | Conf.DiagHandler = diagnosticHandler; | 61 | C.DiagHandler = diagnosticHandler; |
| 76 | Conf.OptLevel = Config->LTOOptLevel; | 62 | C.OptLevel = Config->LTOO; |
| 77 | if (Config->SaveTemps) | 63 | if (Config->SaveTemps) |
| 78 | checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".", | 64 | checkError(C.addSaveTemps(std::string(Config->OutputFile) + ".", |
| 79 | /*UseInputModulePath*/ true)); | 65 | /*UseInputModulePath*/ true)); |
| 80 | lto::ThinBackend Backend; | 66 | lto::ThinBackend Backend; |
| 81 | if (Config->LTOJobs != 0) | 67 | if (Config->ThinLTOJobs != 0) |
| 82 | Backend = lto::createInProcessThinBackend(Config->LTOJobs); | 68 | Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs); |
| 83 | return llvm::make_unique<lto::LTO>(std::move(Conf), Backend, | 69 | return llvm::make_unique<lto::LTO>(std::move(C), Backend, |
| 84 | Config->LTOPartitions); | 70 | Config->LTOPartitions); |
| 85 | } | 71 | } |
| 86 | 72 | ||
| ... | @@ -119,7 +105,7 @@ void BitcodeCompiler::add(BitcodeFile &F) { | ... | @@ -119,7 +105,7 @@ void BitcodeCompiler::add(BitcodeFile &F) { |
| 119 | // and return the resulting objects. | 105 | // and return the resulting objects. |
| 120 | std::vector<StringRef> BitcodeCompiler::compile() { | 106 | std::vector<StringRef> BitcodeCompiler::compile() { |
| 121 | unsigned MaxTasks = LTOObj->getMaxTasks(); | 107 | unsigned MaxTasks = LTOObj->getMaxTasks(); |
| 122 | Buff.resize(MaxTasks); | 108 | Buf.resize(MaxTasks); |
| 123 | Files.resize(MaxTasks); | 109 | Files.resize(MaxTasks); |
| 124 | 110 | ||
| 125 | // The /lldltocache option specifies the path to a directory in which to cache | 111 | // The /lldltocache option specifies the path to a directory in which to cache |
| ... | @@ -127,15 +113,15 @@ std::vector<StringRef> BitcodeCompiler::compile() { | ... | @@ -127,15 +113,15 @@ std::vector<StringRef> BitcodeCompiler::compile() { |
| 127 | // specified, configure LTO to use it as the cache directory. | 113 | // specified, configure LTO to use it as the cache directory. |
| 128 | lto::NativeObjectCache Cache; | 114 | lto::NativeObjectCache Cache; |
| 129 | if (!Config->LTOCache.empty()) | 115 | if (!Config->LTOCache.empty()) |
| 130 | Cache = check( | 116 | Cache = check(lto::localCache( |
| 131 | lto::localCache(Config->LTOCache, | 117 | Config->LTOCache, [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) { |
| 132 | [&](size_t Task, std::unique_ptr<MemoryBuffer> MB, | 118 | Files[Task] = std::move(MB); |
| 133 | StringRef Path) { Files[Task] = std::move(MB); })); | 119 | })); |
| 134 | 120 | ||
| 135 | checkError(LTOObj->run( | 121 | checkError(LTOObj->run( |
| 136 | [&](size_t Task) { | 122 | [&](size_t Task) { |
| 137 | return llvm::make_unique<lto::NativeObjectStream>( | 123 | return llvm::make_unique<lto::NativeObjectStream>( |
| 138 | llvm::make_unique<raw_svector_ostream>(Buff[Task])); | 124 | llvm::make_unique<raw_svector_ostream>(Buf[Task])); |
| 139 | }, | 125 | }, |
| 140 | Cache)); | 126 | Cache)); |
| 141 | 127 | ||
| ... | @@ -144,15 +130,15 @@ std::vector<StringRef> BitcodeCompiler::compile() { | ... | @@ -144,15 +130,15 @@ std::vector<StringRef> BitcodeCompiler::compile() { |
| 144 | 130 | ||
| 145 | std::vector<StringRef> Ret; | 131 | std::vector<StringRef> Ret; |
| 146 | for (unsigned I = 0; I != MaxTasks; ++I) { | 132 | for (unsigned I = 0; I != MaxTasks; ++I) { |
| 147 | if (Buff[I].empty()) | 133 | if (Buf[I].empty()) |
| 148 | continue; | 134 | continue; |
| 149 | if (Config->SaveTemps) { | 135 | if (Config->SaveTemps) { |
| 150 | if (I == 0) | 136 | if (I == 0) |
| 151 | saveBuffer(Buff[I], Config->OutputFile + ".lto.obj"); | 137 | saveBuffer(Buf[I], Config->OutputFile + ".lto.obj"); |
| 152 | else | 138 | else |
| 153 | saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.obj"); | 139 | saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.obj"); |
| 154 | } | 140 | } |
| 155 | Ret.emplace_back(Buff[I].data(), Buff[I].size()); | 141 | Ret.emplace_back(Buf[I].data(), Buf[I].size()); |
| 156 | } | 142 | } |
| 157 | 143 | ||
| 158 | for (std::unique_ptr<MemoryBuffer> &File : Files) | 144 | for (std::unique_ptr<MemoryBuffer> &File : Files) |
deps/lld/COFF/LTO.h+1-1| ... | @@ -48,7 +48,7 @@ public: | ... | @@ -48,7 +48,7 @@ public: |
| 48 | 48 | ||
| 49 | private: | 49 | private: |
| 50 | std::unique_ptr<llvm::lto::LTO> LTOObj; | 50 | std::unique_ptr<llvm::lto::LTO> LTOObj; |
| 51 | std::vector<SmallString<0>> Buff; | 51 | std::vector<SmallString<0>> Buf; |
| 52 | std::vector<std::unique_ptr<MemoryBuffer>> Files; | 52 | std::vector<std::unique_ptr<MemoryBuffer>> Files; |
| 53 | }; | 53 | }; |
| 54 | } | 54 | } |
deps/lld/COFF/MapFile.cpp+6-6| ... | @@ -23,7 +23,6 @@ | ... | @@ -23,7 +23,6 @@ |
| 23 | #include "SymbolTable.h" | 23 | #include "SymbolTable.h" |
| 24 | #include "Symbols.h" | 24 | #include "Symbols.h" |
| 25 | #include "Writer.h" | 25 | #include "Writer.h" |
| 26 | |||
| 27 | #include "lld/Common/ErrorHandler.h" | 26 | #include "lld/Common/ErrorHandler.h" |
| 28 | #include "llvm/Support/Parallel.h" | 27 | #include "llvm/Support/Parallel.h" |
| 29 | #include "llvm/Support/raw_ostream.h" | 28 | #include "llvm/Support/raw_ostream.h" |
| ... | @@ -37,14 +36,15 @@ using namespace lld::coff; | ... | @@ -37,14 +36,15 @@ using namespace lld::coff; |
| 37 | typedef DenseMap<const SectionChunk *, SmallVector<DefinedRegular *, 4>> | 36 | typedef DenseMap<const SectionChunk *, SmallVector<DefinedRegular *, 4>> |
| 38 | SymbolMapTy; | 37 | SymbolMapTy; |
| 39 | 38 | ||
| 39 | static const std::string Indent8 = " "; // 8 spaces | ||
| 40 | static const std::string Indent16 = " "; // 16 spaces | ||
| 41 | |||
| 40 | // Print out the first three columns of a line. | 42 | // Print out the first three columns of a line. |
| 41 | static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size, | 43 | static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size, |
| 42 | uint64_t Align) { | 44 | uint64_t Align) { |
| 43 | OS << format("%08llx %08llx %5lld ", Addr, Size, Align); | 45 | OS << format("%08llx %08llx %5lld ", Addr, Size, Align); |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | static std::string indent(int Depth) { return std::string(Depth * 8, ' '); } | ||
| 47 | |||
| 48 | // Returns a list of all symbols that we want to print out. | 48 | // Returns a list of all symbols that we want to print out. |
| 49 | static std::vector<DefinedRegular *> getSymbols() { | 49 | static std::vector<DefinedRegular *> getSymbols() { |
| 50 | std::vector<DefinedRegular *> V; | 50 | std::vector<DefinedRegular *> V; |
| ... | @@ -79,7 +79,7 @@ getSymbolStrings(ArrayRef<DefinedRegular *> Syms) { | ... | @@ -79,7 +79,7 @@ getSymbolStrings(ArrayRef<DefinedRegular *> Syms) { |
| 79 | for_each_n(parallel::par, (size_t)0, Syms.size(), [&](size_t I) { | 79 | for_each_n(parallel::par, (size_t)0, Syms.size(), [&](size_t I) { |
| 80 | raw_string_ostream OS(Str[I]); | 80 | raw_string_ostream OS(Str[I]); |
| 81 | writeHeader(OS, Syms[I]->getRVA(), 0, 0); | 81 | writeHeader(OS, Syms[I]->getRVA(), 0, 0); |
| 82 | OS << indent(2) << toString(*Syms[I]); | 82 | OS << Indent16 << toString(*Syms[I]); |
| 83 | }); | 83 | }); |
| 84 | 84 | ||
| 85 | DenseMap<DefinedRegular *, std::string> Ret; | 85 | DenseMap<DefinedRegular *, std::string> Ret; |
| ... | @@ -108,7 +108,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) { | ... | @@ -108,7 +108,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) { |
| 108 | // Print out file contents. | 108 | // Print out file contents. |
| 109 | for (OutputSection *Sec : OutputSections) { | 109 | for (OutputSection *Sec : OutputSections) { |
| 110 | writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize); | 110 | writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize); |
| 111 | OS << Sec->getName() << '\n'; | 111 | OS << Sec->Name << '\n'; |
| 112 | 112 | ||
| 113 | for (Chunk *C : Sec->getChunks()) { | 113 | for (Chunk *C : Sec->getChunks()) { |
| 114 | auto *SC = dyn_cast<SectionChunk>(C); | 114 | auto *SC = dyn_cast<SectionChunk>(C); |
| ... | @@ -116,7 +116,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) { | ... | @@ -116,7 +116,7 @@ void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) { |
| 116 | continue; | 116 | continue; |
| 117 | 117 | ||
| 118 | writeHeader(OS, SC->getRVA(), SC->getSize(), SC->Alignment); | 118 | writeHeader(OS, SC->getRVA(), SC->getSize(), SC->Alignment); |
| 119 | OS << indent(1) << SC->File->getName() << ":(" << SC->getSectionName() | 119 | OS << Indent8 << SC->File->getName() << ":(" << SC->getSectionName() |
| 120 | << ")\n"; | 120 | << ")\n"; |
| 121 | for (DefinedRegular *Sym : SectionSyms[SC]) | 121 | for (DefinedRegular *Sym : SectionSyms[SC]) |
| 122 | OS << SymStr[Sym] << '\n'; | 122 | OS << SymStr[Sym] << '\n'; |
deps/lld/COFF/MarkLive.cpp+6-1| ... | @@ -9,16 +9,21 @@ | ... | @@ -9,16 +9,21 @@ |
| 9 | 9 | ||
| 10 | #include "Chunks.h" | 10 | #include "Chunks.h" |
| 11 | #include "Symbols.h" | 11 | #include "Symbols.h" |
| 12 | #include "lld/Common/Timer.h" | ||
| 12 | #include "llvm/ADT/STLExtras.h" | 13 | #include "llvm/ADT/STLExtras.h" |
| 13 | #include <vector> | 14 | #include <vector> |
| 14 | 15 | ||
| 15 | namespace lld { | 16 | namespace lld { |
| 16 | namespace coff { | 17 | namespace coff { |
| 17 | 18 | ||
| 19 | static Timer GCTimer("GC", Timer::root()); | ||
| 20 | |||
| 18 | // Set live bit on for each reachable chunk. Unmarked (unreachable) | 21 | // Set live bit on for each reachable chunk. Unmarked (unreachable) |
| 19 | // COMDAT chunks will be ignored by Writer, so they will be excluded | 22 | // COMDAT chunks will be ignored by Writer, so they will be excluded |
| 20 | // from the final output. | 23 | // from the final output. |
| 21 | void markLive(ArrayRef<Chunk *> Chunks) { | 24 | void markLive(ArrayRef<Chunk *> Chunks) { |
| 25 | ScopedTimer T(GCTimer); | ||
| 26 | |||
| 22 | // We build up a worklist of sections which have been marked as live. We only | 27 | // We build up a worklist of sections which have been marked as live. We only |
| 23 | // push into the worklist when we discover an unmarked section, and we mark | 28 | // push into the worklist when we discover an unmarked section, and we mark |
| 24 | // as we push, so sections never appear twice in the list. | 29 | // as we push, so sections never appear twice in the list. |
| ... | @@ -43,7 +48,7 @@ void markLive(ArrayRef<Chunk *> Chunks) { | ... | @@ -43,7 +48,7 @@ void markLive(ArrayRef<Chunk *> Chunks) { |
| 43 | else if (auto *Sym = dyn_cast<DefinedImportData>(B)) | 48 | else if (auto *Sym = dyn_cast<DefinedImportData>(B)) |
| 44 | Sym->File->Live = true; | 49 | Sym->File->Live = true; |
| 45 | else if (auto *Sym = dyn_cast<DefinedImportThunk>(B)) | 50 | else if (auto *Sym = dyn_cast<DefinedImportThunk>(B)) |
| 46 | Sym->WrappedSym->File->Live = true; | 51 | Sym->WrappedSym->File->Live = Sym->WrappedSym->File->ThunkLive = true; |
| 47 | }; | 52 | }; |
| 48 | 53 | ||
| 49 | // Add GC root chunks. | 54 | // Add GC root chunks. |
deps/lld/COFF/MarkLive.h created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | //===- MarkLive.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_COFF_MARKLIVE_H | ||
| 11 | #define LLD_COFF_MARKLIVE_H | ||
| 12 | |||
| 13 | #include "lld/Common/LLVM.h" | ||
| 14 | #include "llvm/ADT/ArrayRef.h" | ||
| 15 | |||
| 16 | namespace lld { | ||
| 17 | namespace coff { | ||
| 18 | |||
| 19 | void markLive(ArrayRef<Chunk *> Chunks); | ||
| 20 | |||
| 21 | } // namespace coff | ||
| 22 | } // namespace lld | ||
| 23 | |||
| 24 | #endif // LLD_COFF_MARKLIVE_H | ||
deps/lld/COFF/MinGW.cpp+1-1| ... | @@ -138,7 +138,7 @@ void coff::writeDefFile(StringRef Name) { | ... | @@ -138,7 +138,7 @@ void coff::writeDefFile(StringRef Name) { |
| 138 | << "@" << E.Ordinal; | 138 | << "@" << E.Ordinal; |
| 139 | if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) { | 139 | if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) { |
| 140 | if (Def && Def->getChunk() && | 140 | if (Def && Def->getChunk() && |
| 141 | !(Def->getChunk()->getPermissions() & IMAGE_SCN_MEM_EXECUTE)) | 141 | !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) |
| 142 | OS << " DATA"; | 142 | OS << " DATA"; |
| 143 | } | 143 | } |
| 144 | OS << "\n"; | 144 | OS << "\n"; |
deps/lld/COFF/Options.td+26-4| ... | @@ -20,6 +20,10 @@ def align : P<"align", "Section alignment">; | ... | @@ -20,6 +20,10 @@ def align : P<"align", "Section alignment">; |
| 20 | def aligncomm : P<"aligncomm", "Set common symbol alignment">; | 20 | def aligncomm : P<"aligncomm", "Set common symbol alignment">; |
| 21 | def alternatename : P<"alternatename", "Define weak alias">; | 21 | def alternatename : P<"alternatename", "Define weak alias">; |
| 22 | def base : P<"base", "Base address of the program">; | 22 | def base : P<"base", "Base address of the program">; |
| 23 | def color_diagnostics: Flag<["--"], "color-diagnostics">, | ||
| 24 | HelpText<"Use colors in diagnostics">; | ||
| 25 | def color_diagnostics_eq: Joined<["--"], "color-diagnostics=">, | ||
| 26 | HelpText<"Use colors in diagnostics; one of 'always', 'never', 'auto'">; | ||
| 23 | def defaultlib : P<"defaultlib", "Add the library to the list of input files">; | 27 | def defaultlib : P<"defaultlib", "Add the library to the list of input files">; |
| 24 | def delayload : P<"delayload", "Delay loaded DLL name">; | 28 | def delayload : P<"delayload", "Delay loaded DLL name">; |
| 25 | def entry : P<"entry", "Name of entry point symbol">; | 29 | def entry : P<"entry", "Name of entry point symbol">; |
| ... | @@ -28,9 +32,12 @@ def errorlimit : P<"errorlimit", | ... | @@ -28,9 +32,12 @@ def errorlimit : P<"errorlimit", |
| 28 | def export : P<"export", "Export a function">; | 32 | def export : P<"export", "Export a function">; |
| 29 | // No help text because /failifmismatch is not intended to be used by the user. | 33 | // No help text because /failifmismatch is not intended to be used by the user. |
| 30 | def failifmismatch : P<"failifmismatch", "">; | 34 | def failifmismatch : P<"failifmismatch", "">; |
| 35 | def guard : P<"guard", "Control flow guard">; | ||
| 31 | def heap : P<"heap", "Size of the heap">; | 36 | def heap : P<"heap", "Size of the heap">; |
| 32 | def ignore : P<"ignore", "Specify warning codes to ignore">; | 37 | def ignore : P<"ignore", "Specify warning codes to ignore">; |
| 33 | def implib : P<"implib", "Import library name">; | 38 | def implib : P<"implib", "Import library name">; |
| 39 | def lib : F<"lib">, | ||
| 40 | HelpText<"Act like lib.exe; must be first argument if present">; | ||
| 34 | def libpath : P<"libpath", "Additional library search path">; | 41 | def libpath : P<"libpath", "Additional library search path">; |
| 35 | def linkrepro : P<"linkrepro", "Dump linker invocation and input files for debugging">; | 42 | def linkrepro : P<"linkrepro", "Dump linker invocation and input files for debugging">; |
| 36 | def lldltocache : P<"lldltocache", "Path to ThinLTO cached object file directory">; | 43 | def lldltocache : P<"lldltocache", "Path to ThinLTO cached object file directory">; |
| ... | @@ -42,12 +49,18 @@ def merge : P<"merge", "Combine sections">; | ... | @@ -42,12 +49,18 @@ def merge : P<"merge", "Combine sections">; |
| 42 | def mllvm : P<"mllvm", "Options to pass to LLVM">; | 49 | def mllvm : P<"mllvm", "Options to pass to LLVM">; |
| 43 | def nodefaultlib : P<"nodefaultlib", "Remove a default library">; | 50 | def nodefaultlib : P<"nodefaultlib", "Remove a default library">; |
| 44 | def opt : P<"opt", "Control optimizations">; | 51 | def opt : P<"opt", "Control optimizations">; |
| 52 | def order : P<"order", "Put functions in order">; | ||
| 45 | def out : P<"out", "Path to file to write output">; | 53 | def out : P<"out", "Path to file to write output">; |
| 54 | def natvis : P<"natvis", "Path to natvis file to embed in the PDB">; | ||
| 55 | def no_color_diagnostics: F<"no-color-diagnostics">, | ||
| 56 | HelpText<"Do not use colors in diagnostics">; | ||
| 46 | def pdb : P<"pdb", "PDB file path">; | 57 | def pdb : P<"pdb", "PDB file path">; |
| 58 | def pdbaltpath : P<"pdbaltpath", "PDB file path to embed in the image">; | ||
| 47 | def section : P<"section", "Specify section attributes">; | 59 | def section : P<"section", "Specify section attributes">; |
| 48 | def stack : P<"stack", "Size of the stack">; | 60 | def stack : P<"stack", "Size of the stack">; |
| 49 | def stub : P<"stub", "Specify DOS stub file">; | 61 | def stub : P<"stub", "Specify DOS stub file">; |
| 50 | def subsystem : P<"subsystem", "Specify subsystem">; | 62 | def subsystem : P<"subsystem", "Specify subsystem">; |
| 63 | def timestamp : P<"timestamp", "Specify the PE header timestamp">; | ||
| 51 | def version : P<"version", "Specify a version number in the PE header">; | 64 | def version : P<"version", "Specify a version number in the PE header">; |
| 52 | def wholearchive_file : P<"wholearchive", "Include all object files from this archive">; | 65 | def wholearchive_file : P<"wholearchive", "Include all object files from this archive">; |
| 53 | 66 | ||
| ... | @@ -72,12 +85,14 @@ def deffile : Joined<["/", "-"], "def:">, | ... | @@ -72,12 +85,14 @@ def deffile : Joined<["/", "-"], "def:">, |
| 72 | HelpText<"Use module-definition file">; | 85 | HelpText<"Use module-definition file">; |
| 73 | 86 | ||
| 74 | def debug : F<"debug">, HelpText<"Embed a symbol table in the image">; | 87 | def debug : F<"debug">, HelpText<"Embed a symbol table in the image">; |
| 88 | def debug_full : F<"debug:full">, Alias<debug>; | ||
| 75 | def debugtype : P<"debugtype", "Debug Info Options">; | 89 | def debugtype : P<"debugtype", "Debug Info Options">; |
| 76 | def dll : F<"dll">, HelpText<"Create a DLL">; | 90 | def dll : F<"dll">, HelpText<"Create a DLL">; |
| 77 | def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">; | 91 | def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">; |
| 78 | def nodefaultlib_all : F<"nodefaultlib">; | 92 | def nodefaultlib_all : F<"nodefaultlib">; |
| 79 | def noentry : F<"noentry">; | 93 | def noentry : F<"noentry">; |
| 80 | def profile : F<"profile">; | 94 | def profile : F<"profile">; |
| 95 | def repro : F<"Brepro">, HelpText<"Use a hash of the executable as the PE header timestamp">; | ||
| 81 | def swaprun_cd : F<"swaprun:cd">; | 96 | def swaprun_cd : F<"swaprun:cd">; |
| 82 | def swaprun_net : F<"swaprun:net">; | 97 | def swaprun_net : F<"swaprun:net">; |
| 83 | def verbose : F<"verbose">; | 98 | def verbose : F<"verbose">; |
| ... | @@ -102,6 +117,12 @@ defm fixed : B<"fixed", "Disable base relocations", | ... | @@ -102,6 +117,12 @@ defm fixed : B<"fixed", "Disable base relocations", |
| 102 | defm highentropyva : B<"highentropyva", | 117 | defm highentropyva : B<"highentropyva", |
| 103 | "Enable 64-bit ASLR (default on 64-bit)", | 118 | "Enable 64-bit ASLR (default on 64-bit)", |
| 104 | "Disable 64-bit ASLR">; | 119 | "Disable 64-bit ASLR">; |
| 120 | defm incremental : B<"incremental", | ||
| 121 | "Keep original import library if contents are unchanged", | ||
| 122 | "Overwrite import library even if contents are unchanged">; | ||
| 123 | defm integritycheck : B<"integritycheck", | ||
| 124 | "Set FORCE_INTEGRITY bit in PE header", | ||
| 125 | "No effect (default)">; | ||
| 105 | defm largeaddressaware : B<"largeaddressaware", | 126 | defm largeaddressaware : B<"largeaddressaware", |
| 106 | "Enable large addresses (default on 64-bit)", | 127 | "Enable large addresses (default on 64-bit)", |
| 107 | "Disable large addresses (default on 32-bit)">; | 128 | "Disable large addresses (default on 32-bit)">; |
| ... | @@ -120,10 +141,14 @@ def help_q : Flag<["/?", "-?"], "">, Alias<help>; | ... | @@ -120,10 +141,14 @@ def help_q : Flag<["/?", "-?"], "">, Alias<help>; |
| 120 | // LLD extensions | 141 | // LLD extensions |
| 121 | def debug_ghash : F<"debug:ghash">; | 142 | def debug_ghash : F<"debug:ghash">; |
| 122 | def debug_dwarf : F<"debug:dwarf">; | 143 | def debug_dwarf : F<"debug:dwarf">; |
| 144 | def debug_symtab : F<"debug:symtab">; | ||
| 123 | def export_all_symbols : F<"export-all-symbols">; | 145 | def export_all_symbols : F<"export-all-symbols">; |
| 146 | def kill_at : F<"kill-at">; | ||
| 124 | def lldmingw : F<"lldmingw">; | 147 | def lldmingw : F<"lldmingw">; |
| 125 | def msvclto : F<"msvclto">; | 148 | def msvclto : F<"msvclto">; |
| 126 | def output_def : Joined<["/", "-"], "output-def:">; | 149 | def output_def : Joined<["/", "-"], "output-def:">; |
| 150 | def pdb_source_path : P<"pdbsourcepath", | ||
| 151 | "Base path used to make relative source file path absolute in PDB">; | ||
| 127 | def rsp_quoting : Joined<["--"], "rsp-quoting=">, | 152 | def rsp_quoting : Joined<["--"], "rsp-quoting=">, |
| 128 | HelpText<"Quoting style for response files, 'windows' (default) or 'posix'">; | 153 | HelpText<"Quoting style for response files, 'windows' (default) or 'posix'">; |
| 129 | def dash_dash_version : Flag<["--"], "version">, | 154 | def dash_dash_version : Flag<["--"], "version">, |
| ... | @@ -132,6 +157,7 @@ def dash_dash_version : Flag<["--"], "version">, | ... | @@ -132,6 +157,7 @@ def dash_dash_version : Flag<["--"], "version">, |
| 132 | // Flags for debugging | 157 | // Flags for debugging |
| 133 | def lldmap : F<"lldmap">; | 158 | def lldmap : F<"lldmap">; |
| 134 | def lldmap_file : Joined<["/", "-"], "lldmap:">; | 159 | def lldmap_file : Joined<["/", "-"], "lldmap:">; |
| 160 | def show_timing : F<"time">; | ||
| 135 | 161 | ||
| 136 | //============================================================================== | 162 | //============================================================================== |
| 137 | // The flags below do nothing. They are defined only for link.exe compatibility. | 163 | // The flags below do nothing. They are defined only for link.exe compatibility. |
| ... | @@ -146,8 +172,6 @@ multiclass QB<string name> { | ... | @@ -146,8 +172,6 @@ multiclass QB<string name> { |
| 146 | 172 | ||
| 147 | def functionpadmin : F<"functionpadmin">; | 173 | def functionpadmin : F<"functionpadmin">; |
| 148 | def ignoreidl : F<"ignoreidl">; | 174 | def ignoreidl : F<"ignoreidl">; |
| 149 | def incremental : F<"incremental">; | ||
| 150 | def no_incremental : F<"incremental:no">; | ||
| 151 | def nologo : F<"nologo">; | 175 | def nologo : F<"nologo">; |
| 152 | def throwingnew : F<"throwingnew">; | 176 | def throwingnew : F<"throwingnew">; |
| 153 | def editandcontinue : F<"editandcontinue">; | 177 | def editandcontinue : F<"editandcontinue">; |
| ... | @@ -157,8 +181,6 @@ def delay : QF<"delay">; | ... | @@ -157,8 +181,6 @@ def delay : QF<"delay">; |
| 157 | def errorreport : QF<"errorreport">; | 181 | def errorreport : QF<"errorreport">; |
| 158 | def idlout : QF<"idlout">; | 182 | def idlout : QF<"idlout">; |
| 159 | def maxilksize : QF<"maxilksize">; | 183 | def maxilksize : QF<"maxilksize">; |
| 160 | def natvis : QF<"natvis">; | ||
| 161 | def pdbaltpath : QF<"pdbaltpath">; | ||
| 162 | def tlbid : QF<"tlbid">; | 184 | def tlbid : QF<"tlbid">; |
| 163 | def tlbout : QF<"tlbout">; | 185 | def tlbout : QF<"tlbout">; |
| 164 | def verbose_all : QF<"verbose">; | 186 | def verbose_all : QF<"verbose">; |
deps/lld/COFF/PDB.cpp+417-105| ... | @@ -15,7 +15,7 @@ | ... | @@ -15,7 +15,7 @@ |
| 15 | #include "Symbols.h" | 15 | #include "Symbols.h" |
| 16 | #include "Writer.h" | 16 | #include "Writer.h" |
| 17 | #include "lld/Common/ErrorHandler.h" | 17 | #include "lld/Common/ErrorHandler.h" |
| 18 | #include "llvm/DebugInfo/CodeView/CVDebugRecord.h" | 18 | #include "lld/Common/Timer.h" |
| 19 | #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" | 19 | #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" |
| 20 | #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" | 20 | #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" |
| 21 | #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" | 21 | #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" |
| ... | @@ -45,8 +45,10 @@ | ... | @@ -45,8 +45,10 @@ |
| 45 | #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h" | 45 | #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h" |
| 46 | #include "llvm/DebugInfo/PDB/PDB.h" | 46 | #include "llvm/DebugInfo/PDB/PDB.h" |
| 47 | #include "llvm/Object/COFF.h" | 47 | #include "llvm/Object/COFF.h" |
| 48 | #include "llvm/Object/CVDebugRecord.h" | ||
| 48 | #include "llvm/Support/BinaryByteStream.h" | 49 | #include "llvm/Support/BinaryByteStream.h" |
| 49 | #include "llvm/Support/Endian.h" | 50 | #include "llvm/Support/Endian.h" |
| 51 | #include "llvm/Support/FormatVariadic.h" | ||
| 50 | #include "llvm/Support/JamCRC.h" | 52 | #include "llvm/Support/JamCRC.h" |
| 51 | #include "llvm/Support/Path.h" | 53 | #include "llvm/Support/Path.h" |
| 52 | #include "llvm/Support/ScopedPrinter.h" | 54 | #include "llvm/Support/ScopedPrinter.h" |
| ... | @@ -61,6 +63,15 @@ using llvm::object::coff_section; | ... | @@ -61,6 +63,15 @@ using llvm::object::coff_section; |
| 61 | 63 | ||
| 62 | static ExitOnError ExitOnErr; | 64 | static ExitOnError ExitOnErr; |
| 63 | 65 | ||
| 66 | static Timer TotalPdbLinkTimer("PDB Emission (Cumulative)", Timer::root()); | ||
| 67 | |||
| 68 | static Timer AddObjectsTimer("Add Objects", TotalPdbLinkTimer); | ||
| 69 | static Timer TypeMergingTimer("Type Merging", AddObjectsTimer); | ||
| 70 | static Timer SymbolMergingTimer("Symbol Merging", AddObjectsTimer); | ||
| 71 | static Timer GlobalsLayoutTimer("Globals Stream Layout", TotalPdbLinkTimer); | ||
| 72 | static Timer TpiStreamLayoutTimer("TPI Stream Layout", TotalPdbLinkTimer); | ||
| 73 | static Timer DiskCommitTimer("Commit to Disk", TotalPdbLinkTimer); | ||
| 74 | |||
| 64 | namespace { | 75 | namespace { |
| 65 | /// Map from type index and item index in a type server PDB to the | 76 | /// Map from type index and item index in a type server PDB to the |
| 66 | /// corresponding index in the destination PDB. | 77 | /// corresponding index in the destination PDB. |
| ... | @@ -74,11 +85,19 @@ class PDBLinker { | ... | @@ -74,11 +85,19 @@ class PDBLinker { |
| 74 | public: | 85 | public: |
| 75 | PDBLinker(SymbolTable *Symtab) | 86 | PDBLinker(SymbolTable *Symtab) |
| 76 | : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc), | 87 | : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc), |
| 77 | IDTable(Alloc), GlobalTypeTable(Alloc), GlobalIDTable(Alloc) {} | 88 | IDTable(Alloc), GlobalTypeTable(Alloc), GlobalIDTable(Alloc) { |
| 89 | // This isn't strictly necessary, but link.exe usually puts an empty string | ||
| 90 | // as the first "valid" string in the string table, so we do the same in | ||
| 91 | // order to maintain as much byte-for-byte compatibility as possible. | ||
| 92 | PDBStrTab.insert(""); | ||
| 93 | } | ||
| 78 | 94 | ||
| 79 | /// Emit the basic PDB structure: initial streams, headers, etc. | 95 | /// Emit the basic PDB structure: initial streams, headers, etc. |
| 80 | void initialize(const llvm::codeview::DebugInfo &BuildId); | 96 | void initialize(const llvm::codeview::DebugInfo &BuildId); |
| 81 | 97 | ||
| 98 | /// Add natvis files specified on the command line. | ||
| 99 | void addNatvisFiles(); | ||
| 100 | |||
| 82 | /// Link CodeView from each object file in the symbol table into the PDB. | 101 | /// Link CodeView from each object file in the symbol table into the PDB. |
| 83 | void addObjectsToPDB(); | 102 | void addObjectsToPDB(); |
| 84 | 103 | ||
| ... | @@ -106,9 +125,6 @@ public: | ... | @@ -106,9 +125,6 @@ public: |
| 106 | void addSections(ArrayRef<OutputSection *> OutputSections, | 125 | void addSections(ArrayRef<OutputSection *> OutputSections, |
| 107 | ArrayRef<uint8_t> SectionTable); | 126 | ArrayRef<uint8_t> SectionTable); |
| 108 | 127 | ||
| 109 | void addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule, | ||
| 110 | OutputSection *OS, Chunk *C); | ||
| 111 | |||
| 112 | /// Write the PDB to disk. | 128 | /// Write the PDB to disk. |
| 113 | void commit(); | 129 | void commit(); |
| 114 | 130 | ||
| ... | @@ -137,6 +153,11 @@ private: | ... | @@ -137,6 +153,11 @@ private: |
| 137 | 153 | ||
| 138 | llvm::SmallString<128> NativePath; | 154 | llvm::SmallString<128> NativePath; |
| 139 | 155 | ||
| 156 | /// A list of other PDBs which are loaded during the linking process and which | ||
| 157 | /// we need to keep around since the linking operation may reference pointers | ||
| 158 | /// inside of these PDBs. | ||
| 159 | llvm::SmallVector<std::unique_ptr<pdb::NativeSession>, 2> LoadedPDBs; | ||
| 160 | |||
| 140 | std::vector<pdb::SecMapEntry> SectionMap; | 161 | std::vector<pdb::SecMapEntry> SectionMap; |
| 141 | 162 | ||
| 142 | /// Type index mappings of type server PDBs that we've loaded so far. | 163 | /// Type index mappings of type server PDBs that we've loaded so far. |
| ... | @@ -184,8 +205,8 @@ static bool canUseDebugH(ArrayRef<uint8_t> DebugH) { | ... | @@ -184,8 +205,8 @@ static bool canUseDebugH(ArrayRef<uint8_t> DebugH) { |
| 184 | DebugH = DebugH.drop_front(sizeof(object::debug_h_header)); | 205 | DebugH = DebugH.drop_front(sizeof(object::debug_h_header)); |
| 185 | return Header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC && | 206 | return Header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC && |
| 186 | Header->Version == 0 && | 207 | Header->Version == 0 && |
| 187 | Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1) && | 208 | Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1_8) && |
| 188 | (DebugH.size() % 20 == 0); | 209 | (DebugH.size() % 8 == 0); |
| 189 | } | 210 | } |
| 190 | 211 | ||
| 191 | static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *File) { | 212 | static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *File) { |
| ... | @@ -237,6 +258,8 @@ maybeReadTypeServerRecord(CVTypeArray &Types) { | ... | @@ -237,6 +258,8 @@ maybeReadTypeServerRecord(CVTypeArray &Types) { |
| 237 | 258 | ||
| 238 | Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File, | 259 | Expected<const CVIndexMap&> PDBLinker::mergeDebugT(ObjFile *File, |
| 239 | CVIndexMap &ObjectIndexMap) { | 260 | CVIndexMap &ObjectIndexMap) { |
| 261 | ScopedTimer T(TypeMergingTimer); | ||
| 262 | |||
| 240 | ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T"); | 263 | ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T"); |
| 241 | if (Data.empty()) | 264 | if (Data.empty()) |
| 242 | return ObjectIndexMap; | 265 | return ObjectIndexMap; |
| ... | @@ -348,10 +371,16 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, | ... | @@ -348,10 +371,16 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, |
| 348 | return std::move(E); | 371 | return std::move(E); |
| 349 | } | 372 | } |
| 350 | 373 | ||
| 351 | auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream(); | 374 | pdb::NativeSession *Session = ExpectedSession->get(); |
| 375 | |||
| 376 | // Keep a strong reference to this PDB, so that it's safe to hold pointers | ||
| 377 | // into the file. | ||
| 378 | LoadedPDBs.push_back(std::move(*ExpectedSession)); | ||
| 379 | |||
| 380 | auto ExpectedTpi = Session->getPDBFile().getPDBTpiStream(); | ||
| 352 | if (auto E = ExpectedTpi.takeError()) | 381 | if (auto E = ExpectedTpi.takeError()) |
| 353 | fatal("Type server does not have TPI stream: " + toString(std::move(E))); | 382 | fatal("Type server does not have TPI stream: " + toString(std::move(E))); |
| 354 | auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream(); | 383 | auto ExpectedIpi = Session->getPDBFile().getPDBIpiStream(); |
| 355 | if (auto E = ExpectedIpi.takeError()) | 384 | if (auto E = ExpectedIpi.takeError()) |
| 356 | fatal("Type server does not have TPI stream: " + toString(std::move(E))); | 385 | fatal("Type server does not have TPI stream: " + toString(std::move(E))); |
| 357 | 386 | ||
| ... | @@ -428,6 +457,38 @@ static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind, | ... | @@ -428,6 +457,38 @@ static void remapTypesInSymbolRecord(ObjFile *File, SymbolKind SymKind, |
| 428 | } | 457 | } |
| 429 | } | 458 | } |
| 430 | 459 | ||
| 460 | static void | ||
| 461 | recordStringTableReferenceAtOffset(MutableArrayRef<uint8_t> Contents, | ||
| 462 | uint32_t Offset, | ||
| 463 | std::vector<ulittle32_t *> &StrTableRefs) { | ||
| 464 | Contents = | ||
| 465 | Contents.drop_front(Offset).take_front(sizeof(support::ulittle32_t)); | ||
| 466 | ulittle32_t *Index = reinterpret_cast<ulittle32_t *>(Contents.data()); | ||
| 467 | StrTableRefs.push_back(Index); | ||
| 468 | } | ||
| 469 | |||
| 470 | static void | ||
| 471 | recordStringTableReferences(SymbolKind Kind, MutableArrayRef<uint8_t> Contents, | ||
| 472 | std::vector<ulittle32_t *> &StrTableRefs) { | ||
| 473 | // For now we only handle S_FILESTATIC, but we may need the same logic for | ||
| 474 | // S_DEFRANGE and S_DEFRANGE_SUBFIELD. However, I cannot seem to generate any | ||
| 475 | // PDBs that contain these types of records, so because of the uncertainty | ||
| 476 | // they are omitted here until we can prove that it's necessary. | ||
| 477 | switch (Kind) { | ||
| 478 | case SymbolKind::S_FILESTATIC: | ||
| 479 | // FileStaticSym::ModFileOffset | ||
| 480 | recordStringTableReferenceAtOffset(Contents, 4, StrTableRefs); | ||
| 481 | break; | ||
| 482 | case SymbolKind::S_DEFRANGE: | ||
| 483 | case SymbolKind::S_DEFRANGE_SUBFIELD: | ||
| 484 | log("Not fixing up string table reference in S_DEFRANGE / " | ||
| 485 | "S_DEFRANGE_SUBFIELD record"); | ||
| 486 | break; | ||
| 487 | default: | ||
| 488 | break; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 431 | static SymbolKind symbolKind(ArrayRef<uint8_t> RecordData) { | 492 | static SymbolKind symbolKind(ArrayRef<uint8_t> RecordData) { |
| 432 | const RecordPrefix *Prefix = | 493 | const RecordPrefix *Prefix = |
| 433 | reinterpret_cast<const RecordPrefix *>(RecordData.data()); | 494 | reinterpret_cast<const RecordPrefix *>(RecordData.data()); |
| ... | @@ -644,53 +705,65 @@ static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File, | ... | @@ -644,53 +705,65 @@ static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjFile *File, |
| 644 | pdb::GSIStreamBuilder &GsiBuilder, | 705 | pdb::GSIStreamBuilder &GsiBuilder, |
| 645 | const CVIndexMap &IndexMap, | 706 | const CVIndexMap &IndexMap, |
| 646 | TypeCollection &IDTable, | 707 | TypeCollection &IDTable, |
| 708 | std::vector<ulittle32_t *> &StringTableRefs, | ||
| 647 | BinaryStreamRef SymData) { | 709 | BinaryStreamRef SymData) { |
| 648 | // FIXME: Improve error recovery by warning and skipping records when | 710 | // FIXME: Improve error recovery by warning and skipping records when |
| 649 | // possible. | 711 | // possible. |
| 650 | CVSymbolArray Syms; | 712 | ArrayRef<uint8_t> SymsBuffer; |
| 651 | BinaryStreamReader Reader(SymData); | 713 | cantFail(SymData.readBytes(0, SymData.getLength(), SymsBuffer)); |
| 652 | ExitOnErr(Reader.readArray(Syms, Reader.getLength())); | ||
| 653 | SmallVector<SymbolScope, 4> Scopes; | 714 | SmallVector<SymbolScope, 4> Scopes; |
| 654 | for (CVSymbol Sym : Syms) { | ||
| 655 | // Discover type index references in the record. Skip it if we don't know | ||
| 656 | // where they are. | ||
| 657 | SmallVector<TiReference, 32> TypeRefs; | ||
| 658 | if (!discoverTypeIndicesInSymbol(Sym, TypeRefs)) { | ||
| 659 | log("ignoring unknown symbol record with kind 0x" + utohexstr(Sym.kind())); | ||
| 660 | continue; | ||
| 661 | } | ||
| 662 | |||
| 663 | // Copy the symbol record so we can mutate it. | ||
| 664 | MutableArrayRef<uint8_t> NewData = copySymbolForPdb(Sym, Alloc); | ||
| 665 | |||
| 666 | // Re-map all the type index references. | ||
| 667 | MutableArrayRef<uint8_t> Contents = | ||
| 668 | NewData.drop_front(sizeof(RecordPrefix)); | ||
| 669 | remapTypesInSymbolRecord(File, Sym.kind(), Contents, IndexMap, TypeRefs); | ||
| 670 | 715 | ||
| 671 | // An object file may have S_xxx_ID symbols, but these get converted to | 716 | auto EC = forEachCodeViewRecord<CVSymbol>( |
| 672 | // "real" symbols in a PDB. | 717 | SymsBuffer, [&](const CVSymbol &Sym) -> llvm::Error { |
| 673 | translateIdSymbols(NewData, IDTable); | 718 | // Discover type index references in the record. Skip it if we don't |
| 674 | 719 | // know where they are. | |
| 675 | SymbolKind NewKind = symbolKind(NewData); | 720 | SmallVector<TiReference, 32> TypeRefs; |
| 676 | 721 | if (!discoverTypeIndicesInSymbol(Sym, TypeRefs)) { | |
| 677 | // Fill in "Parent" and "End" fields by maintaining a stack of scopes. | 722 | log("ignoring unknown symbol record with kind 0x" + |
| 678 | CVSymbol NewSym(NewKind, NewData); | 723 | utohexstr(Sym.kind())); |
| 679 | if (symbolOpensScope(NewKind)) | 724 | return Error::success(); |
| 680 | scopeStackOpen(Scopes, File->ModuleDBI->getNextSymbolOffset(), NewSym); | 725 | } |
| 681 | else if (symbolEndsScope(NewKind)) | ||
| 682 | scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File); | ||
| 683 | |||
| 684 | // Add the symbol to the globals stream if necessary. Do this before adding | ||
| 685 | // the symbol to the module since we may need to get the next symbol offset, | ||
| 686 | // and writing to the module's symbol stream will update that offset. | ||
| 687 | if (symbolGoesInGlobalsStream(NewSym)) | ||
| 688 | addGlobalSymbol(GsiBuilder, *File, NewSym); | ||
| 689 | 726 | ||
| 690 | // Add the symbol to the module. | 727 | // Copy the symbol record so we can mutate it. |
| 691 | if (symbolGoesInModuleStream(NewSym)) | 728 | MutableArrayRef<uint8_t> NewData = copySymbolForPdb(Sym, Alloc); |
| 692 | File->ModuleDBI->addSymbol(NewSym); | 729 | |
| 693 | } | 730 | // Re-map all the type index references. |
| 731 | MutableArrayRef<uint8_t> Contents = | ||
| 732 | NewData.drop_front(sizeof(RecordPrefix)); | ||
| 733 | remapTypesInSymbolRecord(File, Sym.kind(), Contents, IndexMap, | ||
| 734 | TypeRefs); | ||
| 735 | |||
| 736 | // An object file may have S_xxx_ID symbols, but these get converted to | ||
| 737 | // "real" symbols in a PDB. | ||
| 738 | translateIdSymbols(NewData, IDTable); | ||
| 739 | |||
| 740 | // If this record refers to an offset in the object file's string table, | ||
| 741 | // add that item to the global PDB string table and re-write the index. | ||
| 742 | recordStringTableReferences(Sym.kind(), Contents, StringTableRefs); | ||
| 743 | |||
| 744 | SymbolKind NewKind = symbolKind(NewData); | ||
| 745 | |||
| 746 | // Fill in "Parent" and "End" fields by maintaining a stack of scopes. | ||
| 747 | CVSymbol NewSym(NewKind, NewData); | ||
| 748 | if (symbolOpensScope(NewKind)) | ||
| 749 | scopeStackOpen(Scopes, File->ModuleDBI->getNextSymbolOffset(), | ||
| 750 | NewSym); | ||
| 751 | else if (symbolEndsScope(NewKind)) | ||
| 752 | scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File); | ||
| 753 | |||
| 754 | // Add the symbol to the globals stream if necessary. Do this before | ||
| 755 | // adding the symbol to the module since we may need to get the next | ||
| 756 | // symbol offset, and writing to the module's symbol stream will update | ||
| 757 | // that offset. | ||
| 758 | if (symbolGoesInGlobalsStream(NewSym)) | ||
| 759 | addGlobalSymbol(GsiBuilder, *File, NewSym); | ||
| 760 | |||
| 761 | // Add the symbol to the module. | ||
| 762 | if (symbolGoesInModuleStream(NewSym)) | ||
| 763 | File->ModuleDBI->addSymbol(NewSym); | ||
| 764 | return Error::success(); | ||
| 765 | }); | ||
| 766 | cantFail(std::move(EC)); | ||
| 694 | } | 767 | } |
| 695 | 768 | ||
| 696 | // Allocate memory for a .debug$S section and relocate it. | 769 | // Allocate memory for a .debug$S section and relocate it. |
| ... | @@ -704,6 +777,32 @@ static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc, | ... | @@ -704,6 +777,32 @@ static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc, |
| 704 | ".debug$S"); | 777 | ".debug$S"); |
| 705 | } | 778 | } |
| 706 | 779 | ||
| 780 | static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) { | ||
| 781 | OutputSection *OS = C->getOutputSection(); | ||
| 782 | pdb::SectionContrib SC; | ||
| 783 | memset(&SC, 0, sizeof(SC)); | ||
| 784 | SC.ISect = OS->SectionIndex; | ||
| 785 | SC.Off = C->getRVA() - OS->getRVA(); | ||
| 786 | SC.Size = C->getSize(); | ||
| 787 | if (auto *SecChunk = dyn_cast<SectionChunk>(C)) { | ||
| 788 | SC.Characteristics = SecChunk->Header->Characteristics; | ||
| 789 | SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex(); | ||
| 790 | ArrayRef<uint8_t> Contents = SecChunk->getContents(); | ||
| 791 | JamCRC CRC(0); | ||
| 792 | ArrayRef<char> CharContents = makeArrayRef( | ||
| 793 | reinterpret_cast<const char *>(Contents.data()), Contents.size()); | ||
| 794 | CRC.update(CharContents); | ||
| 795 | SC.DataCrc = CRC.getCRC(); | ||
| 796 | } else { | ||
| 797 | SC.Characteristics = OS->Header.Characteristics; | ||
| 798 | // FIXME: When we start creating DBI for import libraries, use those here. | ||
| 799 | SC.Imod = Modi; | ||
| 800 | } | ||
| 801 | SC.RelocCrc = 0; // FIXME | ||
| 802 | |||
| 803 | return SC; | ||
| 804 | } | ||
| 805 | |||
| 707 | void PDBLinker::addObjFile(ObjFile *File) { | 806 | void PDBLinker::addObjFile(ObjFile *File) { |
| 708 | // Add a module descriptor for every object file. We need to put an absolute | 807 | // Add a module descriptor for every object file. We need to put an absolute |
| 709 | // path to the object into the PDB. If this is a plain object, we make its | 808 | // path to the object into the PDB. If this is a plain object, we make its |
| ... | @@ -718,6 +817,17 @@ void PDBLinker::addObjFile(ObjFile *File) { | ... | @@ -718,6 +817,17 @@ void PDBLinker::addObjFile(ObjFile *File) { |
| 718 | File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name)); | 817 | File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name)); |
| 719 | File->ModuleDBI->setObjFileName(Path); | 818 | File->ModuleDBI->setObjFileName(Path); |
| 720 | 819 | ||
| 820 | auto Chunks = File->getChunks(); | ||
| 821 | uint32_t Modi = File->ModuleDBI->getModuleIndex(); | ||
| 822 | for (Chunk *C : Chunks) { | ||
| 823 | auto *SecChunk = dyn_cast<SectionChunk>(C); | ||
| 824 | if (!SecChunk || !SecChunk->isLive()) | ||
| 825 | continue; | ||
| 826 | pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi); | ||
| 827 | File->ModuleDBI->setFirstSectionContrib(SC); | ||
| 828 | break; | ||
| 829 | } | ||
| 830 | |||
| 721 | // Before we can process symbol substreams from .debug$S, we need to process | 831 | // Before we can process symbol substreams from .debug$S, we need to process |
| 722 | // type information, file checksums, and the string table. Add type info to | 832 | // type information, file checksums, and the string table. Add type info to |
| 723 | // the PDB first, so that we can get the map from object file type and item | 833 | // the PDB first, so that we can get the map from object file type and item |
| ... | @@ -734,7 +844,12 @@ void PDBLinker::addObjFile(ObjFile *File) { | ... | @@ -734,7 +844,12 @@ void PDBLinker::addObjFile(ObjFile *File) { |
| 734 | 844 | ||
| 735 | const CVIndexMap &IndexMap = *IndexMapResult; | 845 | const CVIndexMap &IndexMap = *IndexMapResult; |
| 736 | 846 | ||
| 847 | ScopedTimer T(SymbolMergingTimer); | ||
| 848 | |||
| 737 | // Now do all live .debug$S sections. | 849 | // Now do all live .debug$S sections. |
| 850 | DebugStringTableSubsectionRef CVStrTab; | ||
| 851 | DebugChecksumsSubsectionRef Checksums; | ||
| 852 | std::vector<ulittle32_t *> StringTableReferences; | ||
| 738 | for (SectionChunk *DebugChunk : File->getDebugChunks()) { | 853 | for (SectionChunk *DebugChunk : File->getDebugChunks()) { |
| 739 | if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S") | 854 | if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S") |
| 740 | continue; | 855 | continue; |
| ... | @@ -748,14 +863,17 @@ void PDBLinker::addObjFile(ObjFile *File) { | ... | @@ -748,14 +863,17 @@ void PDBLinker::addObjFile(ObjFile *File) { |
| 748 | BinaryStreamReader Reader(RelocatedDebugContents, support::little); | 863 | BinaryStreamReader Reader(RelocatedDebugContents, support::little); |
| 749 | ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size())); | 864 | ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size())); |
| 750 | 865 | ||
| 751 | DebugStringTableSubsectionRef CVStrTab; | ||
| 752 | DebugChecksumsSubsectionRef Checksums; | ||
| 753 | for (const DebugSubsectionRecord &SS : Subsections) { | 866 | for (const DebugSubsectionRecord &SS : Subsections) { |
| 754 | switch (SS.kind()) { | 867 | switch (SS.kind()) { |
| 755 | case DebugSubsectionKind::StringTable: | 868 | case DebugSubsectionKind::StringTable: { |
| 869 | assert(!CVStrTab.valid() && | ||
| 870 | "Encountered multiple string table subsections!"); | ||
| 756 | ExitOnErr(CVStrTab.initialize(SS.getRecordData())); | 871 | ExitOnErr(CVStrTab.initialize(SS.getRecordData())); |
| 757 | break; | 872 | break; |
| 873 | } | ||
| 758 | case DebugSubsectionKind::FileChecksums: | 874 | case DebugSubsectionKind::FileChecksums: |
| 875 | assert(!Checksums.valid() && | ||
| 876 | "Encountered multiple checksum subsections!"); | ||
| 759 | ExitOnErr(Checksums.initialize(SS.getRecordData())); | 877 | ExitOnErr(Checksums.initialize(SS.getRecordData())); |
| 760 | break; | 878 | break; |
| 761 | case DebugSubsectionKind::Lines: | 879 | case DebugSubsectionKind::Lines: |
| ... | @@ -766,10 +884,12 @@ void PDBLinker::addObjFile(ObjFile *File) { | ... | @@ -766,10 +884,12 @@ void PDBLinker::addObjFile(ObjFile *File) { |
| 766 | case DebugSubsectionKind::Symbols: | 884 | case DebugSubsectionKind::Symbols: |
| 767 | if (Config->DebugGHashes) { | 885 | if (Config->DebugGHashes) { |
| 768 | mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, | 886 | mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, |
| 769 | GlobalIDTable, SS.getRecordData()); | 887 | GlobalIDTable, StringTableReferences, |
| 888 | SS.getRecordData()); | ||
| 770 | } else { | 889 | } else { |
| 771 | mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, | 890 | mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, |
| 772 | IDTable, SS.getRecordData()); | 891 | IDTable, StringTableReferences, |
| 892 | SS.getRecordData()); | ||
| 773 | } | 893 | } |
| 774 | break; | 894 | break; |
| 775 | default: | 895 | default: |
| ... | @@ -777,25 +897,55 @@ void PDBLinker::addObjFile(ObjFile *File) { | ... | @@ -777,25 +897,55 @@ void PDBLinker::addObjFile(ObjFile *File) { |
| 777 | break; | 897 | break; |
| 778 | } | 898 | } |
| 779 | } | 899 | } |
| 900 | } | ||
| 780 | 901 | ||
| 781 | if (Checksums.valid()) { | 902 | // We should have seen all debug subsections across the entire object file now |
| 782 | // Make a new file checksum table that refers to offsets in the PDB-wide | 903 | // which means that if a StringTable subsection and Checksums subsection were |
| 783 | // string table. Generally the string table subsection appears after the | 904 | // present, now is the time to handle them. |
| 784 | // checksum table, so we have to do this after looping over all the | 905 | if (!CVStrTab.valid()) { |
| 785 | // subsections. | 906 | if (Checksums.valid()) |
| 786 | if (!CVStrTab.valid()) | 907 | fatal(".debug$S sections with a checksums subsection must also contain a " |
| 787 | fatal(".debug$S sections must have both a string table subsection " | 908 | "string table subsection"); |
| 788 | "and a checksum subsection table or neither"); | 909 | |
| 789 | auto NewChecksums = make_unique<DebugChecksumsSubsection>(PDBStrTab); | 910 | if (!StringTableReferences.empty()) |
| 790 | for (FileChecksumEntry &FC : Checksums) { | 911 | warn("No StringTable subsection was encountered, but there are string " |
| 791 | StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset)); | 912 | "table references"); |
| 792 | ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(*File->ModuleDBI, | 913 | return; |
| 793 | FileName)); | 914 | } |
| 794 | NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum); | 915 | |
| 795 | } | 916 | // Rewrite each string table reference based on the value that the string |
| 796 | File->ModuleDBI->addDebugSubsection(std::move(NewChecksums)); | 917 | // assumes in the final PDB. |
| 918 | for (ulittle32_t *Ref : StringTableReferences) { | ||
| 919 | auto ExpectedString = CVStrTab.getString(*Ref); | ||
| 920 | if (!ExpectedString) { | ||
| 921 | warn("Invalid string table reference"); | ||
| 922 | consumeError(ExpectedString.takeError()); | ||
| 923 | continue; | ||
| 797 | } | 924 | } |
| 925 | |||
| 926 | *Ref = PDBStrTab.insert(*ExpectedString); | ||
| 798 | } | 927 | } |
| 928 | |||
| 929 | // Make a new file checksum table that refers to offsets in the PDB-wide | ||
| 930 | // string table. Generally the string table subsection appears after the | ||
| 931 | // checksum table, so we have to do this after looping over all the | ||
| 932 | // subsections. | ||
| 933 | auto NewChecksums = make_unique<DebugChecksumsSubsection>(PDBStrTab); | ||
| 934 | for (FileChecksumEntry &FC : Checksums) { | ||
| 935 | SmallString<128> FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset)); | ||
| 936 | if (!sys::path::is_absolute(FileName) && | ||
| 937 | !Config->PDBSourcePath.empty()) { | ||
| 938 | SmallString<128> AbsoluteFileName = Config->PDBSourcePath; | ||
| 939 | sys::path::append(AbsoluteFileName, FileName); | ||
| 940 | sys::path::native(AbsoluteFileName); | ||
| 941 | sys::path::remove_dots(AbsoluteFileName, /*remove_dot_dots=*/true); | ||
| 942 | FileName = std::move(AbsoluteFileName); | ||
| 943 | } | ||
| 944 | ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(*File->ModuleDBI, | ||
| 945 | FileName)); | ||
| 946 | NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum); | ||
| 947 | } | ||
| 948 | File->ModuleDBI->addDebugSubsection(std::move(NewChecksums)); | ||
| 799 | } | 949 | } |
| 800 | 950 | ||
| 801 | static PublicSym32 createPublic(Defined *Def) { | 951 | static PublicSym32 createPublic(Defined *Def) { |
| ... | @@ -818,12 +968,15 @@ static PublicSym32 createPublic(Defined *Def) { | ... | @@ -818,12 +968,15 @@ static PublicSym32 createPublic(Defined *Def) { |
| 818 | // Add all object files to the PDB. Merge .debug$T sections into IpiData and | 968 | // Add all object files to the PDB. Merge .debug$T sections into IpiData and |
| 819 | // TpiData. | 969 | // TpiData. |
| 820 | void PDBLinker::addObjectsToPDB() { | 970 | void PDBLinker::addObjectsToPDB() { |
| 971 | ScopedTimer T1(AddObjectsTimer); | ||
| 821 | for (ObjFile *File : ObjFile::Instances) | 972 | for (ObjFile *File : ObjFile::Instances) |
| 822 | addObjFile(File); | 973 | addObjFile(File); |
| 823 | 974 | ||
| 824 | Builder.getStringTableBuilder().setStrings(PDBStrTab); | 975 | Builder.getStringTableBuilder().setStrings(PDBStrTab); |
| 976 | T1.stop(); | ||
| 825 | 977 | ||
| 826 | // Construct TPI and IPI stream contents. | 978 | // Construct TPI and IPI stream contents. |
| 979 | ScopedTimer T2(TpiStreamLayoutTimer); | ||
| 827 | if (Config->DebugGHashes) { | 980 | if (Config->DebugGHashes) { |
| 828 | addTypeInfo(Builder.getTpiBuilder(), GlobalTypeTable); | 981 | addTypeInfo(Builder.getTpiBuilder(), GlobalTypeTable); |
| 829 | addTypeInfo(Builder.getIpiBuilder(), GlobalIDTable); | 982 | addTypeInfo(Builder.getIpiBuilder(), GlobalIDTable); |
| ... | @@ -831,7 +984,9 @@ void PDBLinker::addObjectsToPDB() { | ... | @@ -831,7 +984,9 @@ void PDBLinker::addObjectsToPDB() { |
| 831 | addTypeInfo(Builder.getTpiBuilder(), TypeTable); | 984 | addTypeInfo(Builder.getTpiBuilder(), TypeTable); |
| 832 | addTypeInfo(Builder.getIpiBuilder(), IDTable); | 985 | addTypeInfo(Builder.getIpiBuilder(), IDTable); |
| 833 | } | 986 | } |
| 987 | T2.stop(); | ||
| 834 | 988 | ||
| 989 | ScopedTimer T3(GlobalsLayoutTimer); | ||
| 835 | // Compute the public and global symbols. | 990 | // Compute the public and global symbols. |
| 836 | auto &GsiBuilder = Builder.getGsiBuilder(); | 991 | auto &GsiBuilder = Builder.getGsiBuilder(); |
| 837 | std::vector<PublicSym32> Publics; | 992 | std::vector<PublicSym32> Publics; |
| ... | @@ -853,6 +1008,35 @@ void PDBLinker::addObjectsToPDB() { | ... | @@ -853,6 +1008,35 @@ void PDBLinker::addObjectsToPDB() { |
| 853 | } | 1008 | } |
| 854 | } | 1009 | } |
| 855 | 1010 | ||
| 1011 | void PDBLinker::addNatvisFiles() { | ||
| 1012 | for (StringRef File : Config->NatvisFiles) { | ||
| 1013 | ErrorOr<std::unique_ptr<MemoryBuffer>> DataOrErr = | ||
| 1014 | MemoryBuffer::getFile(File); | ||
| 1015 | if (!DataOrErr) { | ||
| 1016 | warn("Cannot open input file: " + File); | ||
| 1017 | continue; | ||
| 1018 | } | ||
| 1019 | Builder.addInjectedSource(File, std::move(*DataOrErr)); | ||
| 1020 | } | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | static codeview::CPUType toCodeViewMachine(COFF::MachineTypes Machine) { | ||
| 1024 | switch (Machine) { | ||
| 1025 | case COFF::IMAGE_FILE_MACHINE_AMD64: | ||
| 1026 | return codeview::CPUType::X64; | ||
| 1027 | case COFF::IMAGE_FILE_MACHINE_ARM: | ||
| 1028 | return codeview::CPUType::ARM7; | ||
| 1029 | case COFF::IMAGE_FILE_MACHINE_ARM64: | ||
| 1030 | return codeview::CPUType::ARM64; | ||
| 1031 | case COFF::IMAGE_FILE_MACHINE_ARMNT: | ||
| 1032 | return codeview::CPUType::ARMNT; | ||
| 1033 | case COFF::IMAGE_FILE_MACHINE_I386: | ||
| 1034 | return codeview::CPUType::Intel80386; | ||
| 1035 | default: | ||
| 1036 | llvm_unreachable("Unsupported CPU Type"); | ||
| 1037 | } | ||
| 1038 | } | ||
| 1039 | |||
| 856 | static void addCommonLinkerModuleSymbols(StringRef Path, | 1040 | static void addCommonLinkerModuleSymbols(StringRef Path, |
| 857 | pdb::DbiModuleDescriptorBuilder &Mod, | 1041 | pdb::DbiModuleDescriptorBuilder &Mod, |
| 858 | BumpPtrAllocator &Allocator) { | 1042 | BumpPtrAllocator &Allocator) { |
| ... | @@ -863,7 +1047,7 @@ static void addCommonLinkerModuleSymbols(StringRef Path, | ... | @@ -863,7 +1047,7 @@ static void addCommonLinkerModuleSymbols(StringRef Path, |
| 863 | ONS.Name = "* Linker *"; | 1047 | ONS.Name = "* Linker *"; |
| 864 | ONS.Signature = 0; | 1048 | ONS.Signature = 0; |
| 865 | 1049 | ||
| 866 | CS.Machine = Config->is64() ? CPUType::X64 : CPUType::Intel80386; | 1050 | CS.Machine = toCodeViewMachine(Config->Machine); |
| 867 | // Interestingly, if we set the string to 0.0.0.0, then when trying to view | 1051 | // Interestingly, if we set the string to 0.0.0.0, then when trying to view |
| 868 | // local variables WinDbg emits an error that private symbols are not present. | 1052 | // local variables WinDbg emits an error that private symbols are not present. |
| 869 | // By setting this to a valid MSVC linker version string, local variables are | 1053 | // By setting this to a valid MSVC linker version string, local variables are |
| ... | @@ -914,9 +1098,9 @@ static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod, | ... | @@ -914,9 +1098,9 @@ static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod, |
| 914 | BumpPtrAllocator &Allocator) { | 1098 | BumpPtrAllocator &Allocator) { |
| 915 | SectionSym Sym(SymbolRecordKind::SectionSym); | 1099 | SectionSym Sym(SymbolRecordKind::SectionSym); |
| 916 | Sym.Alignment = 12; // 2^12 = 4KB | 1100 | Sym.Alignment = 12; // 2^12 = 4KB |
| 917 | Sym.Characteristics = OS.getCharacteristics(); | 1101 | Sym.Characteristics = OS.Header.Characteristics; |
| 918 | Sym.Length = OS.getVirtualSize(); | 1102 | Sym.Length = OS.getVirtualSize(); |
| 919 | Sym.Name = OS.getName(); | 1103 | Sym.Name = OS.Name; |
| 920 | Sym.Rva = OS.getRVA(); | 1104 | Sym.Rva = OS.getRVA(); |
| 921 | Sym.SectionNumber = OS.SectionIndex; | 1105 | Sym.SectionNumber = OS.SectionIndex; |
| 922 | Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( | 1106 | Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( |
| ... | @@ -928,10 +1112,15 @@ void coff::createPDB(SymbolTable *Symtab, | ... | @@ -928,10 +1112,15 @@ void coff::createPDB(SymbolTable *Symtab, |
| 928 | ArrayRef<OutputSection *> OutputSections, | 1112 | ArrayRef<OutputSection *> OutputSections, |
| 929 | ArrayRef<uint8_t> SectionTable, | 1113 | ArrayRef<uint8_t> SectionTable, |
| 930 | const llvm::codeview::DebugInfo &BuildId) { | 1114 | const llvm::codeview::DebugInfo &BuildId) { |
| 1115 | ScopedTimer T1(TotalPdbLinkTimer); | ||
| 931 | PDBLinker PDB(Symtab); | 1116 | PDBLinker PDB(Symtab); |
| 1117 | |||
| 932 | PDB.initialize(BuildId); | 1118 | PDB.initialize(BuildId); |
| 933 | PDB.addObjectsToPDB(); | 1119 | PDB.addObjectsToPDB(); |
| 934 | PDB.addSections(OutputSections, SectionTable); | 1120 | PDB.addSections(OutputSections, SectionTable); |
| 1121 | PDB.addNatvisFiles(); | ||
| 1122 | |||
| 1123 | ScopedTimer T2(DiskCommitTimer); | ||
| 935 | PDB.commit(); | 1124 | PDB.commit(); |
| 936 | } | 1125 | } |
| 937 | 1126 | ||
| ... | @@ -945,44 +1134,22 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) { | ... | @@ -945,44 +1134,22 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) { |
| 945 | 1134 | ||
| 946 | // Add an Info stream. | 1135 | // Add an Info stream. |
| 947 | auto &InfoBuilder = Builder.getInfoBuilder(); | 1136 | auto &InfoBuilder = Builder.getInfoBuilder(); |
| 948 | InfoBuilder.setAge(BuildId.PDB70.Age); | ||
| 949 | |||
| 950 | GUID uuid; | 1137 | GUID uuid; |
| 951 | memcpy(&uuid, &BuildId.PDB70.Signature, sizeof(uuid)); | 1138 | memcpy(&uuid, &BuildId.PDB70.Signature, sizeof(uuid)); |
| 1139 | InfoBuilder.setAge(BuildId.PDB70.Age); | ||
| 952 | InfoBuilder.setGuid(uuid); | 1140 | InfoBuilder.setGuid(uuid); |
| 953 | InfoBuilder.setSignature(time(nullptr)); | ||
| 954 | InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70); | 1141 | InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70); |
| 955 | 1142 | ||
| 956 | // Add an empty DBI stream. | 1143 | // Add an empty DBI stream. |
| 957 | pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); | 1144 | pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); |
| 958 | DbiBuilder.setAge(BuildId.PDB70.Age); | 1145 | DbiBuilder.setAge(BuildId.PDB70.Age); |
| 959 | DbiBuilder.setVersionHeader(pdb::PdbDbiV70); | 1146 | DbiBuilder.setVersionHeader(pdb::PdbDbiV70); |
| 960 | ExitOnErr(DbiBuilder.addDbgStream(pdb::DbgHeaderType::NewFPO, {})); | 1147 | DbiBuilder.setMachineType(Config->Machine); |
| 961 | } | 1148 | // Technically we are not link.exe 14.11, but there are known cases where |
| 962 | 1149 | // debugging tools on Windows expect Microsoft-specific version numbers or | |
| 963 | void PDBLinker::addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule, | 1150 | // they fail to work at all. Since we know we produce PDBs that are |
| 964 | OutputSection *OS, Chunk *C) { | 1151 | // compatible with LINK 14.11, we set that version number here. |
| 965 | pdb::SectionContrib SC; | 1152 | DbiBuilder.setBuildNumber(14, 11); |
| 966 | memset(&SC, 0, sizeof(SC)); | ||
| 967 | SC.ISect = OS->SectionIndex; | ||
| 968 | SC.Off = C->getRVA() - OS->getRVA(); | ||
| 969 | SC.Size = C->getSize(); | ||
| 970 | if (auto *SecChunk = dyn_cast<SectionChunk>(C)) { | ||
| 971 | SC.Characteristics = SecChunk->Header->Characteristics; | ||
| 972 | SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex(); | ||
| 973 | ArrayRef<uint8_t> Contents = SecChunk->getContents(); | ||
| 974 | JamCRC CRC(0); | ||
| 975 | ArrayRef<char> CharContents = makeArrayRef( | ||
| 976 | reinterpret_cast<const char *>(Contents.data()), Contents.size()); | ||
| 977 | CRC.update(CharContents); | ||
| 978 | SC.DataCrc = CRC.getCRC(); | ||
| 979 | } else { | ||
| 980 | SC.Characteristics = OS->getCharacteristics(); | ||
| 981 | // FIXME: When we start creating DBI for import libraries, use those here. | ||
| 982 | SC.Imod = LinkerModule.getModuleIndex(); | ||
| 983 | } | ||
| 984 | SC.RelocCrc = 0; // FIXME | ||
| 985 | Builder.getDbiBuilder().addSectionContrib(SC); | ||
| 986 | } | 1153 | } |
| 987 | 1154 | ||
| 988 | void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections, | 1155 | void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections, |
| ... | @@ -1000,8 +1167,11 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections, | ... | @@ -1000,8 +1167,11 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections, |
| 1000 | // Add section contributions. They must be ordered by ascending RVA. | 1167 | // Add section contributions. They must be ordered by ascending RVA. |
| 1001 | for (OutputSection *OS : OutputSections) { | 1168 | for (OutputSection *OS : OutputSections) { |
| 1002 | addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc); | 1169 | addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc); |
| 1003 | for (Chunk *C : OS->getChunks()) | 1170 | for (Chunk *C : OS->getChunks()) { |
| 1004 | addSectionContrib(LinkerModule, OS, C); | 1171 | pdb::SectionContrib SC = |
| 1172 | createSectionContrib(C, LinkerModule.getModuleIndex()); | ||
| 1173 | Builder.getDbiBuilder().addSectionContrib(SC); | ||
| 1174 | } | ||
| 1005 | } | 1175 | } |
| 1006 | 1176 | ||
| 1007 | // Add Section Map stream. | 1177 | // Add Section Map stream. |
| ... | @@ -1020,3 +1190,145 @@ void PDBLinker::commit() { | ... | @@ -1020,3 +1190,145 @@ void PDBLinker::commit() { |
| 1020 | // Write to a file. | 1190 | // Write to a file. |
| 1021 | ExitOnErr(Builder.commit(Config->PDBPath)); | 1191 | ExitOnErr(Builder.commit(Config->PDBPath)); |
| 1022 | } | 1192 | } |
| 1193 | |||
| 1194 | static Expected<StringRef> | ||
| 1195 | getFileName(const DebugStringTableSubsectionRef &Strings, | ||
| 1196 | const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) { | ||
| 1197 | auto Iter = Checksums.getArray().at(FileID); | ||
| 1198 | if (Iter == Checksums.getArray().end()) | ||
| 1199 | return make_error<CodeViewError>(cv_error_code::no_records); | ||
| 1200 | uint32_t Offset = Iter->FileNameOffset; | ||
| 1201 | return Strings.getString(Offset); | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | static uint32_t getSecrelReloc() { | ||
| 1205 | switch (Config->Machine) { | ||
| 1206 | case AMD64: | ||
| 1207 | return COFF::IMAGE_REL_AMD64_SECREL; | ||
| 1208 | case I386: | ||
| 1209 | return COFF::IMAGE_REL_I386_SECREL; | ||
| 1210 | case ARMNT: | ||
| 1211 | return COFF::IMAGE_REL_ARM_SECREL; | ||
| 1212 | case ARM64: | ||
| 1213 | return COFF::IMAGE_REL_ARM64_SECREL; | ||
| 1214 | default: | ||
| 1215 | llvm_unreachable("unknown machine type"); | ||
| 1216 | } | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | // Try to find a line table for the given offset Addr into the given chunk C. | ||
| 1220 | // If a line table was found, the line table, the string and checksum tables | ||
| 1221 | // that are used to interpret the line table, and the offset of Addr in the line | ||
| 1222 | // table are stored in the output arguments. Returns whether a line table was | ||
| 1223 | // found. | ||
| 1224 | static bool findLineTable(const SectionChunk *C, uint32_t Addr, | ||
| 1225 | DebugStringTableSubsectionRef &CVStrTab, | ||
| 1226 | DebugChecksumsSubsectionRef &Checksums, | ||
| 1227 | DebugLinesSubsectionRef &Lines, | ||
| 1228 | uint32_t &OffsetInLinetable) { | ||
| 1229 | ExitOnError ExitOnErr; | ||
| 1230 | uint32_t SecrelReloc = getSecrelReloc(); | ||
| 1231 | |||
| 1232 | for (SectionChunk *DbgC : C->File->getDebugChunks()) { | ||
| 1233 | if (DbgC->getSectionName() != ".debug$S") | ||
| 1234 | continue; | ||
| 1235 | |||
| 1236 | // Build a mapping of SECREL relocations in DbgC that refer to C. | ||
| 1237 | DenseMap<uint32_t, uint32_t> Secrels; | ||
| 1238 | for (const coff_relocation &R : DbgC->Relocs) { | ||
| 1239 | if (R.Type != SecrelReloc) | ||
| 1240 | continue; | ||
| 1241 | |||
| 1242 | if (auto *S = dyn_cast_or_null<DefinedRegular>( | ||
| 1243 | C->File->getSymbols()[R.SymbolTableIndex])) | ||
| 1244 | if (S->getChunk() == C) | ||
| 1245 | Secrels[R.VirtualAddress] = S->getValue(); | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | ArrayRef<uint8_t> Contents = | ||
| 1249 | consumeDebugMagic(DbgC->getContents(), ".debug$S"); | ||
| 1250 | DebugSubsectionArray Subsections; | ||
| 1251 | BinaryStreamReader Reader(Contents, support::little); | ||
| 1252 | ExitOnErr(Reader.readArray(Subsections, Contents.size())); | ||
| 1253 | |||
| 1254 | for (const DebugSubsectionRecord &SS : Subsections) { | ||
| 1255 | switch (SS.kind()) { | ||
| 1256 | case DebugSubsectionKind::StringTable: { | ||
| 1257 | assert(!CVStrTab.valid() && | ||
| 1258 | "Encountered multiple string table subsections!"); | ||
| 1259 | ExitOnErr(CVStrTab.initialize(SS.getRecordData())); | ||
| 1260 | break; | ||
| 1261 | } | ||
| 1262 | case DebugSubsectionKind::FileChecksums: | ||
| 1263 | assert(!Checksums.valid() && | ||
| 1264 | "Encountered multiple checksum subsections!"); | ||
| 1265 | ExitOnErr(Checksums.initialize(SS.getRecordData())); | ||
| 1266 | break; | ||
| 1267 | case DebugSubsectionKind::Lines: { | ||
| 1268 | ArrayRef<uint8_t> Bytes; | ||
| 1269 | auto Ref = SS.getRecordData(); | ||
| 1270 | ExitOnErr(Ref.readLongestContiguousChunk(0, Bytes)); | ||
| 1271 | size_t OffsetInDbgC = Bytes.data() - DbgC->getContents().data(); | ||
| 1272 | |||
| 1273 | // Check whether this line table refers to C. | ||
| 1274 | auto I = Secrels.find(OffsetInDbgC); | ||
| 1275 | if (I == Secrels.end()) | ||
| 1276 | break; | ||
| 1277 | |||
| 1278 | // Check whether this line table covers Addr in C. | ||
| 1279 | DebugLinesSubsectionRef LinesTmp; | ||
| 1280 | ExitOnErr(LinesTmp.initialize(BinaryStreamReader(Ref))); | ||
| 1281 | uint32_t OffsetInC = I->second + LinesTmp.header()->RelocOffset; | ||
| 1282 | if (Addr < OffsetInC || Addr >= OffsetInC + LinesTmp.header()->CodeSize) | ||
| 1283 | break; | ||
| 1284 | |||
| 1285 | assert(!Lines.header() && | ||
| 1286 | "Encountered multiple line tables for function!"); | ||
| 1287 | ExitOnErr(Lines.initialize(BinaryStreamReader(Ref))); | ||
| 1288 | OffsetInLinetable = Addr - OffsetInC; | ||
| 1289 | break; | ||
| 1290 | } | ||
| 1291 | default: | ||
| 1292 | break; | ||
| 1293 | } | ||
| 1294 | |||
| 1295 | if (CVStrTab.valid() && Checksums.valid() && Lines.header()) | ||
| 1296 | return true; | ||
| 1297 | } | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | return false; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | // Use CodeView line tables to resolve a file and line number for the given | ||
| 1304 | // offset into the given chunk and return them, or {"", 0} if a line table was | ||
| 1305 | // not found. | ||
| 1306 | std::pair<StringRef, uint32_t> coff::getFileLine(const SectionChunk *C, | ||
| 1307 | uint32_t Addr) { | ||
| 1308 | ExitOnError ExitOnErr; | ||
| 1309 | |||
| 1310 | DebugStringTableSubsectionRef CVStrTab; | ||
| 1311 | DebugChecksumsSubsectionRef Checksums; | ||
| 1312 | DebugLinesSubsectionRef Lines; | ||
| 1313 | uint32_t OffsetInLinetable; | ||
| 1314 | |||
| 1315 | if (!findLineTable(C, Addr, CVStrTab, Checksums, Lines, OffsetInLinetable)) | ||
| 1316 | return {"", 0}; | ||
| 1317 | |||
| 1318 | uint32_t NameIndex; | ||
| 1319 | uint32_t LineNumber; | ||
| 1320 | for (LineColumnEntry &Entry : Lines) { | ||
| 1321 | for (const LineNumberEntry &LN : Entry.LineNumbers) { | ||
| 1322 | if (LN.Offset > OffsetInLinetable) { | ||
| 1323 | StringRef Filename = | ||
| 1324 | ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex)); | ||
| 1325 | return {Filename, LineNumber}; | ||
| 1326 | } | ||
| 1327 | LineInfo LI(LN.Flags); | ||
| 1328 | NameIndex = Entry.NameIndex; | ||
| 1329 | LineNumber = LI.getStartLine(); | ||
| 1330 | } | ||
| 1331 | } | ||
| 1332 | StringRef Filename = ExitOnErr(getFileName(CVStrTab, Checksums, NameIndex)); | ||
| 1333 | return {Filename, LineNumber}; | ||
| 1334 | } |
deps/lld/COFF/PDB.h+4| ... | @@ -22,12 +22,16 @@ union DebugInfo; | ... | @@ -22,12 +22,16 @@ union DebugInfo; |
| 22 | namespace lld { | 22 | namespace lld { |
| 23 | namespace coff { | 23 | namespace coff { |
| 24 | class OutputSection; | 24 | class OutputSection; |
| 25 | class SectionChunk; | ||
| 25 | class SymbolTable; | 26 | class SymbolTable; |
| 26 | 27 | ||
| 27 | void createPDB(SymbolTable *Symtab, | 28 | void createPDB(SymbolTable *Symtab, |
| 28 | llvm::ArrayRef<OutputSection *> OutputSections, | 29 | llvm::ArrayRef<OutputSection *> OutputSections, |
| 29 | llvm::ArrayRef<uint8_t> SectionTable, | 30 | llvm::ArrayRef<uint8_t> SectionTable, |
| 30 | const llvm::codeview::DebugInfo &BuildId); | 31 | const llvm::codeview::DebugInfo &BuildId); |
| 32 | |||
| 33 | std::pair<llvm::StringRef, uint32_t> getFileLine(const SectionChunk *C, | ||
| 34 | uint32_t Addr); | ||
| 31 | } | 35 | } |
| 32 | } | 36 | } |
| 33 | 37 |
deps/lld/COFF/Strings.cpp deleted-35| ... | @@ -1,35 +0,0 @@ | ||
| 1 | //===- Strings.cpp -------------------------------------------------------===// | ||
| 2 | // | ||
| 3 | // The LLVM Linker | ||
| 4 | // | ||
| 5 | // This file is distributed under the University of Illinois Open Source | ||
| 6 | // License. See LICENSE.TXT for details. | ||
| 7 | // | ||
| 8 | //===----------------------------------------------------------------------===// | ||
| 9 | |||
| 10 | #include "Strings.h" | ||
| 11 | #include <mutex> | ||
| 12 | |||
| 13 | #if defined(_MSC_VER) | ||
| 14 | #include <Windows.h> | ||
| 15 | #include <DbgHelp.h> | ||
| 16 | #pragma comment(lib, "dbghelp.lib") | ||
| 17 | #endif | ||
| 18 | |||
| 19 | using namespace lld; | ||
| 20 | using namespace lld::coff; | ||
| 21 | using namespace llvm; | ||
| 22 | |||
| 23 | Optional<std::string> coff::demangleMSVC(StringRef S) { | ||
| 24 | #if defined(_MSC_VER) | ||
| 25 | // UnDecorateSymbolName is not thread-safe, so we need a mutex. | ||
| 26 | static std::mutex Mu; | ||
| 27 | std::lock_guard<std::mutex> Lock(Mu); | ||
| 28 | |||
| 29 | char Buf[4096]; | ||
| 30 | if (S.startswith("?")) | ||
| 31 | if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0)) | ||
| 32 | return std::string(Buf, Len); | ||
| 33 | #endif | ||
| 34 | return None; | ||
| 35 | } | ||
deps/lld/COFF/Strings.h deleted-23| ... | @@ -1,23 +0,0 @@ | ||
| 1 | //===- Strings.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_COFF_STRINGS_H | ||
| 11 | #define LLD_COFF_STRINGS_H | ||
| 12 | |||
| 13 | #include "llvm/ADT/Optional.h" | ||
| 14 | #include "llvm/ADT/StringRef.h" | ||
| 15 | #include <string> | ||
| 16 | |||
| 17 | namespace lld { | ||
| 18 | namespace coff { | ||
| 19 | llvm::Optional<std::string> demangleMSVC(llvm::StringRef S); | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | #endif | ||
deps/lld/COFF/SymbolTable.cpp+81-15| ... | @@ -11,9 +11,11 @@ | ... | @@ -11,9 +11,11 @@ |
| 11 | #include "Config.h" | 11 | #include "Config.h" |
| 12 | #include "Driver.h" | 12 | #include "Driver.h" |
| 13 | #include "LTO.h" | 13 | #include "LTO.h" |
| 14 | #include "PDB.h" | ||
| 14 | #include "Symbols.h" | 15 | #include "Symbols.h" |
| 15 | #include "lld/Common/ErrorHandler.h" | 16 | #include "lld/Common/ErrorHandler.h" |
| 16 | #include "lld/Common/Memory.h" | 17 | #include "lld/Common/Memory.h" |
| 18 | #include "lld/Common/Timer.h" | ||
| 17 | #include "llvm/IR/LLVMContext.h" | 19 | #include "llvm/IR/LLVMContext.h" |
| 18 | #include "llvm/Support/Debug.h" | 20 | #include "llvm/Support/Debug.h" |
| 19 | #include "llvm/Support/raw_ostream.h" | 21 | #include "llvm/Support/raw_ostream.h" |
| ... | @@ -24,6 +26,8 @@ using namespace llvm; | ... | @@ -24,6 +26,8 @@ using namespace llvm; |
| 24 | namespace lld { | 26 | namespace lld { |
| 25 | namespace coff { | 27 | namespace coff { |
| 26 | 28 | ||
| 29 | static Timer LTOTimer("LTO", Timer::root()); | ||
| 30 | |||
| 27 | SymbolTable *Symtab; | 31 | SymbolTable *Symtab; |
| 28 | 32 | ||
| 29 | void SymbolTable::addFile(InputFile *File) { | 33 | void SymbolTable::addFile(InputFile *File) { |
| ... | @@ -34,8 +38,9 @@ void SymbolTable::addFile(InputFile *File) { | ... | @@ -34,8 +38,9 @@ void SymbolTable::addFile(InputFile *File) { |
| 34 | if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { | 38 | if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { |
| 35 | Config->Machine = MT; | 39 | Config->Machine = MT; |
| 36 | } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) { | 40 | } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) { |
| 37 | fatal(toString(File) + ": machine type " + machineToStr(MT) + | 41 | error(toString(File) + ": machine type " + machineToStr(MT) + |
| 38 | " conflicts with " + machineToStr(Config->Machine)); | 42 | " conflicts with " + machineToStr(Config->Machine)); |
| 43 | return; | ||
| 39 | } | 44 | } |
| 40 | 45 | ||
| 41 | if (auto *F = dyn_cast<ObjFile>(File)) { | 46 | if (auto *F = dyn_cast<ObjFile>(File)) { |
| ... | @@ -61,6 +66,66 @@ static void errorOrWarn(const Twine &S) { | ... | @@ -61,6 +66,66 @@ static void errorOrWarn(const Twine &S) { |
| 61 | error(S); | 66 | error(S); |
| 62 | } | 67 | } |
| 63 | 68 | ||
| 69 | // Returns the name of the symbol in SC whose value is <= Addr that is closest | ||
| 70 | // to Addr. This is generally the name of the global variable or function whose | ||
| 71 | // definition contains Addr. | ||
| 72 | static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) { | ||
| 73 | DefinedRegular *Candidate = nullptr; | ||
| 74 | |||
| 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())) | ||
| 79 | continue; | ||
| 80 | |||
| 81 | Candidate = D; | ||
| 82 | } | ||
| 83 | |||
| 84 | if (!Candidate) | ||
| 85 | return ""; | ||
| 86 | return Candidate->getName(); | ||
| 87 | } | ||
| 88 | |||
| 89 | static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) { | ||
| 90 | struct Location { | ||
| 91 | StringRef SymName; | ||
| 92 | std::pair<StringRef, uint32_t> FileLine; | ||
| 93 | }; | ||
| 94 | std::vector<Location> Locations; | ||
| 95 | |||
| 96 | for (Chunk *C : File->getChunks()) { | ||
| 97 | auto *SC = dyn_cast<SectionChunk>(C); | ||
| 98 | if (!SC) | ||
| 99 | continue; | ||
| 100 | for (const coff_relocation &R : SC->Relocs) { | ||
| 101 | if (R.SymbolTableIndex != SymIndex) | ||
| 102 | continue; | ||
| 103 | std::pair<StringRef, uint32_t> FileLine = | ||
| 104 | getFileLine(SC, R.VirtualAddress); | ||
| 105 | StringRef SymName = getSymbolName(SC, R.VirtualAddress); | ||
| 106 | if (!FileLine.first.empty() || !SymName.empty()) | ||
| 107 | Locations.push_back({SymName, FileLine}); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | if (Locations.empty()) | ||
| 112 | return "\n>>> referenced by " + toString(File) + "\n"; | ||
| 113 | |||
| 114 | std::string Out; | ||
| 115 | llvm::raw_string_ostream OS(Out); | ||
| 116 | for (Location Loc : Locations) { | ||
| 117 | OS << "\n>>> referenced by "; | ||
| 118 | if (!Loc.FileLine.first.empty()) | ||
| 119 | OS << Loc.FileLine.first << ":" << Loc.FileLine.second | ||
| 120 | << "\n>>> "; | ||
| 121 | OS << toString(File); | ||
| 122 | if (!Loc.SymName.empty()) | ||
| 123 | OS << ":(" << Loc.SymName << ')'; | ||
| 124 | } | ||
| 125 | OS << '\n'; | ||
| 126 | return OS.str(); | ||
| 127 | } | ||
| 128 | |||
| 64 | void SymbolTable::reportRemainingUndefines() { | 129 | void SymbolTable::reportRemainingUndefines() { |
| 65 | SmallPtrSet<Symbol *, 8> Undefs; | 130 | SmallPtrSet<Symbol *, 8> Undefs; |
| 66 | DenseMap<Symbol *, Symbol *> LocalImports; | 131 | DenseMap<Symbol *, Symbol *> LocalImports; |
| ... | @@ -120,20 +185,23 @@ void SymbolTable::reportRemainingUndefines() { | ... | @@ -120,20 +185,23 @@ void SymbolTable::reportRemainingUndefines() { |
| 120 | if (Config->WarnLocallyDefinedImported) | 185 | if (Config->WarnLocallyDefinedImported) |
| 121 | if (Symbol *Imp = LocalImports.lookup(B)) | 186 | if (Symbol *Imp = LocalImports.lookup(B)) |
| 122 | warn("<root>: locally defined symbol imported: " + Imp->getName() + | 187 | warn("<root>: locally defined symbol imported: " + Imp->getName() + |
| 123 | " (defined in " + toString(Imp->getFile()) + ")"); | 188 | " (defined in " + toString(Imp->getFile()) + ") [LNK4217]"); |
| 124 | } | 189 | } |
| 125 | 190 | ||
| 126 | for (ObjFile *File : ObjFile::Instances) { | 191 | for (ObjFile *File : ObjFile::Instances) { |
| 192 | size_t SymIndex = (size_t)-1; | ||
| 127 | for (Symbol *Sym : File->getSymbols()) { | 193 | for (Symbol *Sym : File->getSymbols()) { |
| 194 | ++SymIndex; | ||
| 128 | if (!Sym) | 195 | if (!Sym) |
| 129 | continue; | 196 | continue; |
| 130 | if (Undefs.count(Sym)) | 197 | if (Undefs.count(Sym)) |
| 131 | errorOrWarn(toString(File) + ": undefined symbol: " + Sym->getName()); | 198 | errorOrWarn("undefined symbol: " + Sym->getName() + |
| 199 | getSymbolLocations(File, SymIndex)); | ||
| 132 | if (Config->WarnLocallyDefinedImported) | 200 | if (Config->WarnLocallyDefinedImported) |
| 133 | if (Symbol *Imp = LocalImports.lookup(Sym)) | 201 | if (Symbol *Imp = LocalImports.lookup(Sym)) |
| 134 | warn(toString(File) + ": locally defined symbol imported: " + | 202 | warn(toString(File) + ": locally defined symbol imported: " + |
| 135 | Imp->getName() + " (defined in " + toString(Imp->getFile()) + | 203 | Imp->getName() + " (defined in " + toString(Imp->getFile()) + |
| 136 | ")"); | 204 | ") [LNK4217]"); |
| 137 | } | 205 | } |
| 138 | } | 206 | } |
| 139 | } | 207 | } |
| ... | @@ -142,7 +210,7 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { | ... | @@ -142,7 +210,7 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { |
| 142 | Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; | 210 | Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; |
| 143 | if (Sym) | 211 | if (Sym) |
| 144 | return {Sym, false}; | 212 | return {Sym, false}; |
| 145 | Sym = (Symbol *)make<SymbolUnion>(); | 213 | Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); |
| 146 | Sym->IsUsedInRegularObj = false; | 214 | Sym->IsUsedInRegularObj = false; |
| 147 | Sym->PendingArchiveLoad = false; | 215 | Sym->PendingArchiveLoad = false; |
| 148 | return {Sym, true}; | 216 | return {Sym, true}; |
| ... | @@ -274,30 +342,29 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, | ... | @@ -274,30 +342,29 @@ Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, |
| 274 | return S; | 342 | return S; |
| 275 | } | 343 | } |
| 276 | 344 | ||
| 277 | DefinedImportData *SymbolTable::addImportData(StringRef N, ImportFile *F) { | 345 | Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) { |
| 278 | Symbol *S; | 346 | Symbol *S; |
| 279 | bool WasInserted; | 347 | bool WasInserted; |
| 280 | std::tie(S, WasInserted) = insert(N); | 348 | std::tie(S, WasInserted) = insert(N); |
| 281 | S->IsUsedInRegularObj = true; | 349 | S->IsUsedInRegularObj = true; |
| 282 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) { | 350 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) { |
| 283 | replaceSymbol<DefinedImportData>(S, N, F); | 351 | replaceSymbol<DefinedImportData>(S, N, F); |
| 284 | return cast<DefinedImportData>(S); | 352 | return S; |
| 285 | } | 353 | } |
| 286 | 354 | ||
| 287 | reportDuplicate(S, F); | 355 | reportDuplicate(S, F); |
| 288 | return nullptr; | 356 | return nullptr; |
| 289 | } | 357 | } |
| 290 | 358 | ||
| 291 | DefinedImportThunk *SymbolTable::addImportThunk(StringRef Name, | 359 | Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID, |
| 292 | DefinedImportData *ID, | 360 | uint16_t Machine) { |
| 293 | uint16_t Machine) { | ||
| 294 | Symbol *S; | 361 | Symbol *S; |
| 295 | bool WasInserted; | 362 | bool WasInserted; |
| 296 | std::tie(S, WasInserted) = insert(Name); | 363 | std::tie(S, WasInserted) = insert(Name); |
| 297 | S->IsUsedInRegularObj = true; | 364 | S->IsUsedInRegularObj = true; |
| 298 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) { | 365 | if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) { |
| 299 | replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine); | 366 | replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine); |
| 300 | return cast<DefinedImportThunk>(S); | 367 | return S; |
| 301 | } | 368 | } |
| 302 | 369 | ||
| 303 | reportDuplicate(S, ID->File); | 370 | reportDuplicate(S, ID->File); |
| ... | @@ -314,10 +381,7 @@ std::vector<Chunk *> SymbolTable::getChunks() { | ... | @@ -314,10 +381,7 @@ std::vector<Chunk *> SymbolTable::getChunks() { |
| 314 | } | 381 | } |
| 315 | 382 | ||
| 316 | Symbol *SymbolTable::find(StringRef Name) { | 383 | Symbol *SymbolTable::find(StringRef Name) { |
| 317 | auto It = SymMap.find(CachedHashStringRef(Name)); | 384 | return SymMap.lookup(CachedHashStringRef(Name)); |
| 318 | if (It == SymMap.end()) | ||
| 319 | return nullptr; | ||
| 320 | return It->second; | ||
| 321 | } | 385 | } |
| 322 | 386 | ||
| 323 | Symbol *SymbolTable::findUnderscore(StringRef Name) { | 387 | Symbol *SymbolTable::findUnderscore(StringRef Name) { |
| ... | @@ -384,6 +448,8 @@ std::vector<StringRef> SymbolTable::compileBitcodeFiles() { | ... | @@ -384,6 +448,8 @@ std::vector<StringRef> SymbolTable::compileBitcodeFiles() { |
| 384 | void SymbolTable::addCombinedLTOObjects() { | 448 | void SymbolTable::addCombinedLTOObjects() { |
| 385 | if (BitcodeFile::Instances.empty()) | 449 | if (BitcodeFile::Instances.empty()) |
| 386 | return; | 450 | return; |
| 451 | |||
| 452 | ScopedTimer T(LTOTimer); | ||
| 387 | for (StringRef Object : compileBitcodeFiles()) { | 453 | for (StringRef Object : compileBitcodeFiles()) { |
| 388 | auto *Obj = make<ObjFile>(MemoryBufferRef(Object, "lto.tmp")); | 454 | auto *Obj = make<ObjFile>(MemoryBufferRef(Object, "lto.tmp")); |
| 389 | Obj->parse(); | 455 | Obj->parse(); |
deps/lld/COFF/SymbolTable.h+3-3| ... | @@ -92,9 +92,9 @@ public: | ... | @@ -92,9 +92,9 @@ public: |
| 92 | Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size, | 92 | Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size, |
| 93 | const llvm::object::coff_symbol_generic *S = nullptr, | 93 | const llvm::object::coff_symbol_generic *S = nullptr, |
| 94 | CommonChunk *C = nullptr); | 94 | CommonChunk *C = nullptr); |
| 95 | DefinedImportData *addImportData(StringRef N, ImportFile *F); | 95 | Symbol *addImportData(StringRef N, ImportFile *F); |
| 96 | DefinedImportThunk *addImportThunk(StringRef Name, DefinedImportData *S, | 96 | Symbol *addImportThunk(StringRef Name, DefinedImportData *S, |
| 97 | uint16_t Machine); | 97 | uint16_t Machine); |
| 98 | 98 | ||
| 99 | void reportDuplicate(Symbol *Existing, InputFile *NewFile); | 99 | void reportDuplicate(Symbol *Existing, InputFile *NewFile); |
| 100 | 100 |
deps/lld/COFF/Symbols.cpp+4-4| ... | @@ -9,9 +9,9 @@ | ... | @@ -9,9 +9,9 @@ |
| 9 | 9 | ||
| 10 | #include "Symbols.h" | 10 | #include "Symbols.h" |
| 11 | #include "InputFiles.h" | 11 | #include "InputFiles.h" |
| 12 | #include "Strings.h" | ||
| 13 | #include "lld/Common/ErrorHandler.h" | 12 | #include "lld/Common/ErrorHandler.h" |
| 14 | #include "lld/Common/Memory.h" | 13 | #include "lld/Common/Memory.h" |
| 14 | #include "lld/Common/Strings.h" | ||
| 15 | #include "llvm/ADT/STLExtras.h" | 15 | #include "llvm/ADT/STLExtras.h" |
| 16 | #include "llvm/Support/Debug.h" | 16 | #include "llvm/Support/Debug.h" |
| 17 | #include "llvm/Support/raw_ostream.h" | 17 | #include "llvm/Support/raw_ostream.h" |
| ... | @@ -21,7 +21,7 @@ using namespace llvm::object; | ... | @@ -21,7 +21,7 @@ using namespace llvm::object; |
| 21 | 21 | ||
| 22 | // Returns a symbol name for an error message. | 22 | // Returns a symbol name for an error message. |
| 23 | std::string lld::toString(coff::Symbol &B) { | 23 | std::string lld::toString(coff::Symbol &B) { |
| 24 | if (Optional<std::string> S = coff::demangleMSVC(B.getName())) | 24 | if (Optional<std::string> S = lld::demangleMSVC(B.getName())) |
| 25 | return ("\"" + *S + "\" (" + B.getName() + ")").str(); | 25 | return ("\"" + *S + "\" (" + B.getName() + ")").str(); |
| 26 | return B.getName(); | 26 | return B.getName(); |
| 27 | } | 27 | } |
| ... | @@ -58,7 +58,7 @@ bool Symbol::isLive() const { | ... | @@ -58,7 +58,7 @@ bool Symbol::isLive() const { |
| 58 | if (auto *Imp = dyn_cast<DefinedImportData>(this)) | 58 | if (auto *Imp = dyn_cast<DefinedImportData>(this)) |
| 59 | return Imp->File->Live; | 59 | return Imp->File->Live; |
| 60 | if (auto *Imp = dyn_cast<DefinedImportThunk>(this)) | 60 | if (auto *Imp = dyn_cast<DefinedImportThunk>(this)) |
| 61 | return Imp->WrappedSym->File->Live; | 61 | return Imp->WrappedSym->File->ThunkLive; |
| 62 | // Assume any other kind of symbol is live. | 62 | // Assume any other kind of symbol is live. |
| 63 | return true; | 63 | return true; |
| 64 | } | 64 | } |
| ... | @@ -71,7 +71,7 @@ COFFSymbolRef DefinedCOFF::getCOFFSymbol() { | ... | @@ -71,7 +71,7 @@ COFFSymbolRef DefinedCOFF::getCOFFSymbol() { |
| 71 | return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym)); | 71 | return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym)); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | uint16_t DefinedAbsolute::OutputSectionIndex = 0; | 74 | uint16_t DefinedAbsolute::NumOutputSections; |
| 75 | 75 | ||
| 76 | static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) { | 76 | static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) { |
| 77 | if (Machine == AMD64) | 77 | if (Machine == AMD64) |
deps/lld/COFF/Symbols.h+6-5| ... | @@ -213,11 +213,10 @@ public: | ... | @@ -213,11 +213,10 @@ public: |
| 213 | uint64_t getRVA() { return VA - Config->ImageBase; } | 213 | uint64_t getRVA() { return VA - Config->ImageBase; } |
| 214 | void setVA(uint64_t V) { VA = V; } | 214 | void setVA(uint64_t V) { VA = V; } |
| 215 | 215 | ||
| 216 | // The sentinel absolute symbol section index. Section index relocations | 216 | // Section index relocations against absolute symbols resolve to |
| 217 | // against absolute symbols resolve to this 16 bit number, and it is the | 217 | // this 16 bit number, and it is the largest valid section index |
| 218 | // largest valid section index plus one. This is written by the Writer. | 218 | // plus one. This variable keeps it. |
| 219 | static uint16_t OutputSectionIndex; | 219 | static uint16_t NumOutputSections; |
| 220 | uint16_t getSecIdx() { return OutputSectionIndex; } | ||
| 221 | 220 | ||
| 222 | private: | 221 | private: |
| 223 | uint64_t VA; | 222 | uint64_t VA; |
| ... | @@ -416,6 +415,8 @@ union SymbolUnion { | ... | @@ -416,6 +415,8 @@ union SymbolUnion { |
| 416 | 415 | ||
| 417 | template <typename T, typename... ArgT> | 416 | template <typename T, typename... ArgT> |
| 418 | void replaceSymbol(Symbol *S, ArgT &&... Arg) { | 417 | void replaceSymbol(Symbol *S, ArgT &&... Arg) { |
| 418 | static_assert(std::is_trivially_destructible<T>(), | ||
| 419 | "Symbol types must be trivially destructible"); | ||
| 419 | static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small"); | 420 | static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small"); |
| 420 | static_assert(alignof(T) <= alignof(SymbolUnion), | 421 | static_assert(alignof(T) <= alignof(SymbolUnion), |
| 421 | "SymbolUnion not aligned enough"); | 422 | "SymbolUnion not aligned enough"); |
deps/lld/COFF/Writer.cpp+573-252| ... | @@ -17,6 +17,7 @@ | ... | @@ -17,6 +17,7 @@ |
| 17 | #include "Symbols.h" | 17 | #include "Symbols.h" |
| 18 | #include "lld/Common/ErrorHandler.h" | 18 | #include "lld/Common/ErrorHandler.h" |
| 19 | #include "lld/Common/Memory.h" | 19 | #include "lld/Common/Memory.h" |
| 20 | #include "lld/Common/Timer.h" | ||
| 20 | #include "llvm/ADT/DenseMap.h" | 21 | #include "llvm/ADT/DenseMap.h" |
| 21 | #include "llvm/ADT/STLExtras.h" | 22 | #include "llvm/ADT/STLExtras.h" |
| 22 | #include "llvm/ADT/StringSwitch.h" | 23 | #include "llvm/ADT/StringSwitch.h" |
| ... | @@ -25,7 +26,9 @@ | ... | @@ -25,7 +26,9 @@ |
| 25 | #include "llvm/Support/Endian.h" | 26 | #include "llvm/Support/Endian.h" |
| 26 | #include "llvm/Support/FileOutputBuffer.h" | 27 | #include "llvm/Support/FileOutputBuffer.h" |
| 27 | #include "llvm/Support/Parallel.h" | 28 | #include "llvm/Support/Parallel.h" |
| 29 | #include "llvm/Support/Path.h" | ||
| 28 | #include "llvm/Support/RandomNumberGenerator.h" | 30 | #include "llvm/Support/RandomNumberGenerator.h" |
| 31 | #include "llvm/Support/xxhash.h" | ||
| 29 | #include <algorithm> | 32 | #include <algorithm> |
| 30 | #include <cstdio> | 33 | #include <cstdio> |
| 31 | #include <map> | 34 | #include <map> |
| ... | @@ -40,8 +43,40 @@ using namespace llvm::support::endian; | ... | @@ -40,8 +43,40 @@ using namespace llvm::support::endian; |
| 40 | using namespace lld; | 43 | using namespace lld; |
| 41 | using namespace lld::coff; | 44 | using namespace lld::coff; |
| 42 | 45 | ||
| 46 | /* To re-generate DOSProgram: | ||
| 47 | $ cat > /tmp/DOSProgram.asm | ||
| 48 | org 0 | ||
| 49 | ; Copy cs to ds. | ||
| 50 | push cs | ||
| 51 | pop ds | ||
| 52 | ; Point ds:dx at the $-terminated string. | ||
| 53 | mov dx, str | ||
| 54 | ; Int 21/AH=09h: Write string to standard output. | ||
| 55 | mov ah, 0x9 | ||
| 56 | int 0x21 | ||
| 57 | ; Int 21/AH=4Ch: Exit with return code (in AL). | ||
| 58 | mov ax, 0x4C01 | ||
| 59 | int 0x21 | ||
| 60 | str: | ||
| 61 | db 'This program cannot be run in DOS mode.$' | ||
| 62 | align 8, db 0 | ||
| 63 | $ nasm -fbin /tmp/DOSProgram.asm -o /tmp/DOSProgram.bin | ||
| 64 | $ xxd -i /tmp/DOSProgram.bin | ||
| 65 | */ | ||
| 66 | static unsigned char DOSProgram[] = { | ||
| 67 | 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, | ||
| 68 | 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, | ||
| 69 | 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, | ||
| 70 | 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, | ||
| 71 | 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x24, 0x00, 0x00 | ||
| 72 | }; | ||
| 73 | static_assert(sizeof(DOSProgram) % 8 == 0, | ||
| 74 | "DOSProgram size must be multiple of 8"); | ||
| 75 | |||
| 43 | static const int SectorSize = 512; | 76 | static const int SectorSize = 512; |
| 44 | static const int DOSStubSize = 64; | 77 | static const int DOSStubSize = sizeof(dos_header) + sizeof(DOSProgram); |
| 78 | static_assert(DOSStubSize % 8 == 0, "DOSStub size must be multiple of 8"); | ||
| 79 | |||
| 45 | static const int NumberfOfDataDirectory = 16; | 80 | static const int NumberfOfDataDirectory = 16; |
| 46 | 81 | ||
| 47 | namespace { | 82 | namespace { |
| ... | @@ -69,24 +104,25 @@ public: | ... | @@ -69,24 +104,25 @@ public: |
| 69 | uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA()); | 104 | uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA()); |
| 70 | D->PointerToRawData = Offs; | 105 | D->PointerToRawData = Offs; |
| 71 | 106 | ||
| 107 | TimeDateStamps.push_back(&D->TimeDateStamp); | ||
| 72 | ++D; | 108 | ++D; |
| 73 | } | 109 | } |
| 74 | } | 110 | } |
| 75 | 111 | ||
| 112 | void setTimeDateStamp(uint32_t TimeDateStamp) { | ||
| 113 | for (support::ulittle32_t *TDS : TimeDateStamps) | ||
| 114 | *TDS = TimeDateStamp; | ||
| 115 | } | ||
| 116 | |||
| 76 | private: | 117 | private: |
| 118 | mutable std::vector<support::ulittle32_t *> TimeDateStamps; | ||
| 77 | const std::vector<Chunk *> &Records; | 119 | const std::vector<Chunk *> &Records; |
| 78 | }; | 120 | }; |
| 79 | 121 | ||
| 80 | class CVDebugRecordChunk : public Chunk { | 122 | class CVDebugRecordChunk : public Chunk { |
| 81 | public: | 123 | public: |
| 82 | CVDebugRecordChunk() { | ||
| 83 | PDBAbsPath = Config->PDBPath; | ||
| 84 | if (!PDBAbsPath.empty()) | ||
| 85 | llvm::sys::fs::make_absolute(PDBAbsPath); | ||
| 86 | } | ||
| 87 | |||
| 88 | size_t getSize() const override { | 124 | size_t getSize() const override { |
| 89 | return sizeof(codeview::DebugInfo) + PDBAbsPath.size() + 1; | 125 | return sizeof(codeview::DebugInfo) + Config->PDBAltPath.size() + 1; |
| 90 | } | 126 | } |
| 91 | 127 | ||
| 92 | void writeTo(uint8_t *B) const override { | 128 | void writeTo(uint8_t *B) const override { |
| ... | @@ -96,12 +132,11 @@ public: | ... | @@ -96,12 +132,11 @@ public: |
| 96 | 132 | ||
| 97 | // variable sized field (PDB Path) | 133 | // variable sized field (PDB Path) |
| 98 | char *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*BuildId)); | 134 | char *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*BuildId)); |
| 99 | if (!PDBAbsPath.empty()) | 135 | if (!Config->PDBAltPath.empty()) |
| 100 | memcpy(P, PDBAbsPath.data(), PDBAbsPath.size()); | 136 | memcpy(P, Config->PDBAltPath.data(), Config->PDBAltPath.size()); |
| 101 | P[PDBAbsPath.size()] = '\0'; | 137 | P[Config->PDBAltPath.size()] = '\0'; |
| 102 | } | 138 | } |
| 103 | 139 | ||
| 104 | SmallString<128> PDBAbsPath; | ||
| 105 | mutable codeview::DebugInfo *BuildId = nullptr; | 140 | mutable codeview::DebugInfo *BuildId = nullptr; |
| 106 | }; | 141 | }; |
| 107 | 142 | ||
| ... | @@ -116,12 +151,19 @@ private: | ... | @@ -116,12 +151,19 @@ private: |
| 116 | void createMiscChunks(); | 151 | void createMiscChunks(); |
| 117 | void createImportTables(); | 152 | void createImportTables(); |
| 118 | void createExportTable(); | 153 | void createExportTable(); |
| 154 | void mergeSections(); | ||
| 119 | void assignAddresses(); | 155 | void assignAddresses(); |
| 120 | void removeEmptySections(); | 156 | void removeEmptySections(); |
| 121 | void createSymbolAndStringTable(); | 157 | void createSymbolAndStringTable(); |
| 122 | void openFile(StringRef OutputPath); | 158 | void openFile(StringRef OutputPath); |
| 123 | template <typename PEHeaderTy> void writeHeader(); | 159 | template <typename PEHeaderTy> void writeHeader(); |
| 124 | void createSEHTable(OutputSection *RData); | 160 | void createSEHTable(); |
| 161 | void createGuardCFTables(); | ||
| 162 | void markSymbolsForRVATable(ObjFile *File, | ||
| 163 | ArrayRef<SectionChunk *> SymIdxChunks, | ||
| 164 | SymbolRVASet &TableSymbols); | ||
| 165 | void maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym, | ||
| 166 | StringRef CountSym); | ||
| 125 | void setSectionPermissions(); | 167 | void setSectionPermissions(); |
| 126 | void writeSections(); | 168 | void writeSections(); |
| 127 | void writeBuildId(); | 169 | void writeBuildId(); |
| ... | @@ -131,9 +173,8 @@ private: | ... | @@ -131,9 +173,8 @@ private: |
| 131 | size_t addEntryToStringTable(StringRef Str); | 173 | size_t addEntryToStringTable(StringRef Str); |
| 132 | 174 | ||
| 133 | OutputSection *findSection(StringRef Name); | 175 | OutputSection *findSection(StringRef Name); |
| 134 | OutputSection *createSection(StringRef Name); | 176 | void addBaserels(); |
| 135 | void addBaserels(OutputSection *Dest); | 177 | void addBaserelBlocks(std::vector<Baserel> &V); |
| 136 | void addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V); | ||
| 137 | 178 | ||
| 138 | uint32_t getSizeOfInitializedData(); | 179 | uint32_t getSizeOfInitializedData(); |
| 139 | std::map<StringRef, std::vector<DefinedImportData *>> binImports(); | 180 | std::map<StringRef, std::vector<DefinedImportData *>> binImports(); |
| ... | @@ -145,9 +186,9 @@ private: | ... | @@ -145,9 +186,9 @@ private: |
| 145 | IdataContents Idata; | 186 | IdataContents Idata; |
| 146 | DelayLoadContents DelayIdata; | 187 | DelayLoadContents DelayIdata; |
| 147 | EdataContents Edata; | 188 | EdataContents Edata; |
| 148 | SEHTableChunk *SEHTable = nullptr; | 189 | bool SetNoSEHCharacteristic = false; |
| 149 | 190 | ||
| 150 | Chunk *DebugDirectory = nullptr; | 191 | DebugDirectoryChunk *DebugDirectory = nullptr; |
| 151 | std::vector<Chunk *> DebugRecords; | 192 | std::vector<Chunk *> DebugRecords; |
| 152 | CVDebugRecordChunk *BuildId = nullptr; | 193 | CVDebugRecordChunk *BuildId = nullptr; |
| 153 | Optional<codeview::DebugInfo> PreviousBuildId; | 194 | Optional<codeview::DebugInfo> PreviousBuildId; |
| ... | @@ -157,50 +198,55 @@ private: | ... | @@ -157,50 +198,55 @@ private: |
| 157 | uint32_t PointerToSymbolTable = 0; | 198 | uint32_t PointerToSymbolTable = 0; |
| 158 | uint64_t SizeOfImage; | 199 | uint64_t SizeOfImage; |
| 159 | uint64_t SizeOfHeaders; | 200 | uint64_t SizeOfHeaders; |
| 201 | |||
| 202 | OutputSection *TextSec; | ||
| 203 | OutputSection *RdataSec; | ||
| 204 | OutputSection *BuildidSec; | ||
| 205 | OutputSection *DataSec; | ||
| 206 | OutputSection *PdataSec; | ||
| 207 | OutputSection *IdataSec; | ||
| 208 | OutputSection *EdataSec; | ||
| 209 | OutputSection *DidatSec; | ||
| 210 | OutputSection *RsrcSec; | ||
| 211 | OutputSection *RelocSec; | ||
| 212 | |||
| 213 | // The first and last .pdata sections in the output file. | ||
| 214 | // | ||
| 215 | // We need to keep track of the location of .pdata in whichever section it | ||
| 216 | // gets merged into so that we can sort its contents and emit a correct data | ||
| 217 | // directory entry for the exception table. This is also the case for some | ||
| 218 | // other sections (such as .edata) but because the contents of those sections | ||
| 219 | // are entirely linker-generated we can keep track of their locations using | ||
| 220 | // the chunks that the linker creates. All .pdata chunks come from input | ||
| 221 | // files, so we need to keep track of them separately. | ||
| 222 | Chunk *FirstPdata = nullptr; | ||
| 223 | Chunk *LastPdata; | ||
| 160 | }; | 224 | }; |
| 161 | } // anonymous namespace | 225 | } // anonymous namespace |
| 162 | 226 | ||
| 163 | namespace lld { | 227 | namespace lld { |
| 164 | namespace coff { | 228 | namespace coff { |
| 165 | 229 | ||
| 166 | void writeResult() { Writer().run(); } | 230 | static Timer CodeLayoutTimer("Code Layout", Timer::root()); |
| 167 | 231 | static Timer DiskCommitTimer("Commit Output File", Timer::root()); | |
| 168 | void OutputSection::setRVA(uint64_t RVA) { | ||
| 169 | Header.VirtualAddress = RVA; | ||
| 170 | for (Chunk *C : Chunks) | ||
| 171 | C->setRVA(C->getRVA() + RVA); | ||
| 172 | } | ||
| 173 | 232 | ||
| 174 | void OutputSection::setFileOffset(uint64_t Off) { | 233 | void writeResult() { Writer().run(); } |
| 175 | // If a section has no actual data (i.e. BSS section), we want to | ||
| 176 | // set 0 to its PointerToRawData. Otherwise the output is rejected | ||
| 177 | // by the loader. | ||
| 178 | if (Header.SizeOfRawData == 0) | ||
| 179 | return; | ||
| 180 | Header.PointerToRawData = Off; | ||
| 181 | } | ||
| 182 | 234 | ||
| 183 | void OutputSection::addChunk(Chunk *C) { | 235 | void OutputSection::addChunk(Chunk *C) { |
| 184 | Chunks.push_back(C); | 236 | Chunks.push_back(C); |
| 185 | C->setOutputSection(this); | 237 | C->setOutputSection(this); |
| 186 | uint64_t Off = Header.VirtualSize; | ||
| 187 | Off = alignTo(Off, C->Alignment); | ||
| 188 | C->setRVA(Off); | ||
| 189 | C->OutputSectionOff = Off; | ||
| 190 | Off += C->getSize(); | ||
| 191 | if (Off > UINT32_MAX) | ||
| 192 | error("section larger than 4 GiB: " + Name); | ||
| 193 | Header.VirtualSize = Off; | ||
| 194 | if (C->hasData()) | ||
| 195 | Header.SizeOfRawData = alignTo(Off, SectorSize); | ||
| 196 | } | 238 | } |
| 197 | 239 | ||
| 198 | void OutputSection::addPermissions(uint32_t C) { | 240 | void OutputSection::setPermissions(uint32_t C) { |
| 199 | Header.Characteristics |= C & PermMask; | 241 | Header.Characteristics &= ~PermMask; |
| 242 | Header.Characteristics |= C; | ||
| 200 | } | 243 | } |
| 201 | 244 | ||
| 202 | void OutputSection::setPermissions(uint32_t C) { | 245 | void OutputSection::merge(OutputSection *Other) { |
| 203 | Header.Characteristics = C & PermMask; | 246 | for (Chunk *C : Other->Chunks) |
| 247 | C->setOutputSection(this); | ||
| 248 | Chunks.insert(Chunks.end(), Other->Chunks.begin(), Other->Chunks.end()); | ||
| 249 | Other->Chunks.clear(); | ||
| 204 | } | 250 | } |
| 205 | 251 | ||
| 206 | // Write the section header to a given buffer. | 252 | // Write the section header to a given buffer. |
| ... | @@ -284,17 +330,22 @@ static Optional<codeview::DebugInfo> loadExistingBuildId(StringRef Path) { | ... | @@ -284,17 +330,22 @@ static Optional<codeview::DebugInfo> loadExistingBuildId(StringRef Path) { |
| 284 | 330 | ||
| 285 | // The main function of the writer. | 331 | // The main function of the writer. |
| 286 | void Writer::run() { | 332 | void Writer::run() { |
| 333 | ScopedTimer T1(CodeLayoutTimer); | ||
| 334 | |||
| 287 | createSections(); | 335 | createSections(); |
| 288 | createMiscChunks(); | 336 | createMiscChunks(); |
| 289 | createImportTables(); | 337 | createImportTables(); |
| 290 | createExportTable(); | 338 | createExportTable(); |
| 291 | if (Config->Relocatable) | 339 | mergeSections(); |
| 292 | createSection(".reloc"); | ||
| 293 | assignAddresses(); | 340 | assignAddresses(); |
| 294 | removeEmptySections(); | 341 | removeEmptySections(); |
| 295 | setSectionPermissions(); | 342 | setSectionPermissions(); |
| 296 | createSymbolAndStringTable(); | 343 | createSymbolAndStringTable(); |
| 297 | 344 | ||
| 345 | if (FileSize > UINT32_MAX) | ||
| 346 | fatal("image size (" + Twine(FileSize) + ") " + | ||
| 347 | "exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")"); | ||
| 348 | |||
| 298 | // We must do this before opening the output file, as it depends on being able | 349 | // We must do this before opening the output file, as it depends on being able |
| 299 | // to read the contents of the existing output file. | 350 | // to read the contents of the existing output file. |
| 300 | PreviousBuildId = loadExistingBuildId(Config->OutputFile); | 351 | PreviousBuildId = loadExistingBuildId(Config->OutputFile); |
| ... | @@ -308,35 +359,79 @@ void Writer::run() { | ... | @@ -308,35 +359,79 @@ void Writer::run() { |
| 308 | sortExceptionTable(); | 359 | sortExceptionTable(); |
| 309 | writeBuildId(); | 360 | writeBuildId(); |
| 310 | 361 | ||
| 311 | if (!Config->PDBPath.empty() && Config->Debug) { | 362 | T1.stop(); |
| 312 | 363 | ||
| 364 | if (!Config->PDBPath.empty() && Config->Debug) { | ||
| 313 | assert(BuildId); | 365 | assert(BuildId); |
| 314 | createPDB(Symtab, OutputSections, SectionTable, *BuildId->BuildId); | 366 | createPDB(Symtab, OutputSections, SectionTable, *BuildId->BuildId); |
| 315 | } | 367 | } |
| 316 | 368 | ||
| 317 | writeMapFile(OutputSections); | 369 | writeMapFile(OutputSections); |
| 318 | 370 | ||
| 371 | ScopedTimer T2(DiskCommitTimer); | ||
| 319 | if (auto E = Buffer->commit()) | 372 | if (auto E = Buffer->commit()) |
| 320 | fatal("failed to write the output file: " + toString(std::move(E))); | 373 | fatal("failed to write the output file: " + toString(std::move(E))); |
| 321 | } | 374 | } |
| 322 | 375 | ||
| 323 | static StringRef getOutputSection(StringRef Name) { | 376 | static StringRef getOutputSectionName(StringRef Name) { |
| 324 | StringRef S = Name.split('$').first; | 377 | StringRef S = Name.split('$').first; |
| 325 | 378 | ||
| 326 | // Treat a later period as a separator for MinGW, for sections like | 379 | // Treat a later period as a separator for MinGW, for sections like |
| 327 | // ".ctors.01234". | 380 | // ".ctors.01234". |
| 328 | S = S.substr(0, S.find('.', 1)); | 381 | return S.substr(0, S.find('.', 1)); |
| 382 | } | ||
| 329 | 383 | ||
| 330 | auto It = Config->Merge.find(S); | 384 | // For /order. |
| 331 | if (It == Config->Merge.end()) | 385 | static void sortBySectionOrder(std::vector<Chunk *> &Chunks) { |
| 332 | return S; | 386 | auto GetPriority = [](const Chunk *C) { |
| 333 | return It->second; | 387 | if (auto *Sec = dyn_cast<SectionChunk>(C)) |
| 388 | if (Sec->Sym) | ||
| 389 | return Config->Order.lookup(Sec->Sym->getName()); | ||
| 390 | return 0; | ||
| 391 | }; | ||
| 392 | |||
| 393 | std::stable_sort(Chunks.begin(), Chunks.end(), | ||
| 394 | [=](const Chunk *A, const Chunk *B) { | ||
| 395 | return GetPriority(A) < GetPriority(B); | ||
| 396 | }); | ||
| 334 | } | 397 | } |
| 335 | 398 | ||
| 336 | // Create output section objects and add them to OutputSections. | 399 | // Create output section objects and add them to OutputSections. |
| 337 | void Writer::createSections() { | 400 | void Writer::createSections() { |
| 338 | // First, bin chunks by name. | 401 | // First, create the builtin sections. |
| 339 | std::map<StringRef, std::vector<Chunk *>> Map; | 402 | const uint32_t DATA = IMAGE_SCN_CNT_INITIALIZED_DATA; |
| 403 | const uint32_t BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA; | ||
| 404 | const uint32_t CODE = IMAGE_SCN_CNT_CODE; | ||
| 405 | const uint32_t DISCARDABLE = IMAGE_SCN_MEM_DISCARDABLE; | ||
| 406 | const uint32_t R = IMAGE_SCN_MEM_READ; | ||
| 407 | const uint32_t W = IMAGE_SCN_MEM_WRITE; | ||
| 408 | const uint32_t X = IMAGE_SCN_MEM_EXECUTE; | ||
| 409 | |||
| 410 | SmallDenseMap<std::pair<StringRef, uint32_t>, OutputSection *> Sections; | ||
| 411 | auto CreateSection = [&](StringRef Name, uint32_t OutChars) { | ||
| 412 | OutputSection *&Sec = Sections[{Name, OutChars}]; | ||
| 413 | if (!Sec) { | ||
| 414 | Sec = make<OutputSection>(Name, OutChars); | ||
| 415 | OutputSections.push_back(Sec); | ||
| 416 | } | ||
| 417 | return Sec; | ||
| 418 | }; | ||
| 419 | |||
| 420 | // Try to match the section order used by link.exe. | ||
| 421 | TextSec = CreateSection(".text", CODE | R | X); | ||
| 422 | CreateSection(".bss", BSS | R | W); | ||
| 423 | RdataSec = CreateSection(".rdata", DATA | R); | ||
| 424 | BuildidSec = CreateSection(".buildid", DATA | R); | ||
| 425 | DataSec = CreateSection(".data", DATA | R | W); | ||
| 426 | PdataSec = CreateSection(".pdata", DATA | R); | ||
| 427 | IdataSec = CreateSection(".idata", DATA | R); | ||
| 428 | EdataSec = CreateSection(".edata", DATA | R); | ||
| 429 | DidatSec = CreateSection(".didat", DATA | R); | ||
| 430 | RsrcSec = CreateSection(".rsrc", DATA | R); | ||
| 431 | RelocSec = CreateSection(".reloc", DATA | DISCARDABLE | R); | ||
| 432 | |||
| 433 | // Then bin chunks by name and output characteristics. | ||
| 434 | std::map<std::pair<StringRef, uint32_t>, std::vector<Chunk *>> Map; | ||
| 340 | for (Chunk *C : Symtab->getChunks()) { | 435 | for (Chunk *C : Symtab->getChunks()) { |
| 341 | auto *SC = dyn_cast<SectionChunk>(C); | 436 | auto *SC = dyn_cast<SectionChunk>(C); |
| 342 | if (SC && !SC->isLive()) { | 437 | if (SC && !SC->isLive()) { |
| ... | @@ -344,42 +439,71 @@ void Writer::createSections() { | ... | @@ -344,42 +439,71 @@ void Writer::createSections() { |
| 344 | SC->printDiscardedMessage(); | 439 | SC->printDiscardedMessage(); |
| 345 | continue; | 440 | continue; |
| 346 | } | 441 | } |
| 347 | Map[C->getSectionName()].push_back(C); | 442 | Map[{C->getSectionName(), C->getOutputCharacteristics()}].push_back(C); |
| 348 | } | 443 | } |
| 349 | 444 | ||
| 445 | // Process an /order option. | ||
| 446 | if (!Config->Order.empty()) | ||
| 447 | for (auto &Pair : Map) | ||
| 448 | sortBySectionOrder(Pair.second); | ||
| 449 | |||
| 350 | // Then create an OutputSection for each section. | 450 | // Then create an OutputSection for each section. |
| 351 | // '$' and all following characters in input section names are | 451 | // '$' and all following characters in input section names are |
| 352 | // discarded when determining output section. So, .text$foo | 452 | // discarded when determining output section. So, .text$foo |
| 353 | // contributes to .text, for example. See PE/COFF spec 3.2. | 453 | // contributes to .text, for example. See PE/COFF spec 3.2. |
| 354 | SmallDenseMap<StringRef, OutputSection *> Sections; | ||
| 355 | for (auto Pair : Map) { | 454 | for (auto Pair : Map) { |
| 356 | StringRef Name = getOutputSection(Pair.first); | 455 | StringRef Name = getOutputSectionName(Pair.first.first); |
| 357 | OutputSection *&Sec = Sections[Name]; | 456 | uint32_t OutChars = Pair.first.second; |
| 358 | if (!Sec) { | 457 | |
| 359 | Sec = make<OutputSection>(Name); | 458 | // In link.exe, there is a special case for the I386 target where .CRT |
| 360 | OutputSections.push_back(Sec); | 459 | // sections are treated as if they have output characteristics DATA | R if |
| 361 | } | 460 | // their characteristics are DATA | R | W. This implements the same special |
| 461 | // case for all architectures. | ||
| 462 | if (Name == ".CRT") | ||
| 463 | OutChars = DATA | R; | ||
| 464 | |||
| 465 | OutputSection *Sec = CreateSection(Name, OutChars); | ||
| 362 | std::vector<Chunk *> &Chunks = Pair.second; | 466 | std::vector<Chunk *> &Chunks = Pair.second; |
| 363 | for (Chunk *C : Chunks) { | 467 | for (Chunk *C : Chunks) |
| 364 | Sec->addChunk(C); | 468 | Sec->addChunk(C); |
| 365 | Sec->addPermissions(C->getPermissions()); | ||
| 366 | } | ||
| 367 | } | 469 | } |
| 470 | |||
| 471 | // Finally, move some output sections to the end. | ||
| 472 | auto SectionOrder = [&](OutputSection *S) { | ||
| 473 | // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because | ||
| 474 | // the loader cannot handle holes. Stripping can remove other discardable ones | ||
| 475 | // than .reloc, which is first of them (created early). | ||
| 476 | if (S->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) | ||
| 477 | return 2; | ||
| 478 | // .rsrc should come at the end of the non-discardable sections because its | ||
| 479 | // size may change by the Win32 UpdateResources() function, causing | ||
| 480 | // subsequent sections to move (see https://crbug.com/827082). | ||
| 481 | if (S == RsrcSec) | ||
| 482 | return 1; | ||
| 483 | return 0; | ||
| 484 | }; | ||
| 485 | std::stable_sort(OutputSections.begin(), OutputSections.end(), | ||
| 486 | [&](OutputSection *S, OutputSection *T) { | ||
| 487 | return SectionOrder(S) < SectionOrder(T); | ||
| 488 | }); | ||
| 368 | } | 489 | } |
| 369 | 490 | ||
| 370 | void Writer::createMiscChunks() { | 491 | void Writer::createMiscChunks() { |
| 371 | OutputSection *RData = createSection(".rdata"); | 492 | for (auto &P : MergeChunk::Instances) |
| 493 | RdataSec->addChunk(P.second); | ||
| 372 | 494 | ||
| 373 | // Create thunks for locally-dllimported symbols. | 495 | // Create thunks for locally-dllimported symbols. |
| 374 | if (!Symtab->LocalImportChunks.empty()) { | 496 | if (!Symtab->LocalImportChunks.empty()) { |
| 375 | for (Chunk *C : Symtab->LocalImportChunks) | 497 | for (Chunk *C : Symtab->LocalImportChunks) |
| 376 | RData->addChunk(C); | 498 | RdataSec->addChunk(C); |
| 377 | } | 499 | } |
| 378 | 500 | ||
| 379 | // Create Debug Information Chunks | 501 | // Create Debug Information Chunks |
| 380 | if (Config->Debug) { | 502 | if (Config->Debug) { |
| 381 | DebugDirectory = make<DebugDirectoryChunk>(DebugRecords); | 503 | DebugDirectory = make<DebugDirectoryChunk>(DebugRecords); |
| 382 | 504 | ||
| 505 | OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec; | ||
| 506 | |||
| 383 | // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We | 507 | // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We |
| 384 | // output a PDB no matter what, and this chunk provides the only means of | 508 | // output a PDB no matter what, and this chunk provides the only means of |
| 385 | // allowing a debugger to match a PDB and an executable. So we need it even | 509 | // allowing a debugger to match a PDB and an executable. So we need it even |
| ... | @@ -388,12 +512,18 @@ void Writer::createMiscChunks() { | ... | @@ -388,12 +512,18 @@ void Writer::createMiscChunks() { |
| 388 | BuildId = CVChunk; | 512 | BuildId = CVChunk; |
| 389 | DebugRecords.push_back(CVChunk); | 513 | DebugRecords.push_back(CVChunk); |
| 390 | 514 | ||
| 391 | RData->addChunk(DebugDirectory); | 515 | DebugInfoSec->addChunk(DebugDirectory); |
| 392 | for (Chunk *C : DebugRecords) | 516 | for (Chunk *C : DebugRecords) |
| 393 | RData->addChunk(C); | 517 | DebugInfoSec->addChunk(C); |
| 394 | } | 518 | } |
| 395 | 519 | ||
| 396 | createSEHTable(RData); | 520 | // Create SEH table. x86-only. |
| 521 | if (Config->Machine == I386) | ||
| 522 | createSEHTable(); | ||
| 523 | |||
| 524 | // Create /guard:cf tables if requested. | ||
| 525 | if (Config->GuardCF != GuardCFLevel::Off) | ||
| 526 | createGuardCFTables(); | ||
| 397 | } | 527 | } |
| 398 | 528 | ||
| 399 | // Create .idata section for the DLL-imported symbol table. | 529 | // Create .idata section for the DLL-imported symbol table. |
| ... | @@ -414,53 +544,49 @@ void Writer::createImportTables() { | ... | @@ -414,53 +544,49 @@ void Writer::createImportTables() { |
| 414 | std::string DLL = StringRef(File->DLLName).lower(); | 544 | std::string DLL = StringRef(File->DLLName).lower(); |
| 415 | if (Config->DLLOrder.count(DLL) == 0) | 545 | if (Config->DLLOrder.count(DLL) == 0) |
| 416 | Config->DLLOrder[DLL] = Config->DLLOrder.size(); | 546 | Config->DLLOrder[DLL] = Config->DLLOrder.size(); |
| 417 | } | ||
| 418 | 547 | ||
| 419 | OutputSection *Text = createSection(".text"); | 548 | if (File->ThunkSym) { |
| 420 | for (ImportFile *File : ImportFile::Instances) { | 549 | if (!isa<DefinedImportThunk>(File->ThunkSym)) |
| 421 | if (!File->Live) | 550 | fatal(toString(*File->ThunkSym) + " was replaced"); |
| 422 | continue; | 551 | DefinedImportThunk *Thunk = cast<DefinedImportThunk>(File->ThunkSym); |
| 423 | 552 | if (File->ThunkLive) | |
| 424 | if (DefinedImportThunk *Thunk = File->ThunkSym) | 553 | TextSec->addChunk(Thunk->getChunk()); |
| 425 | Text->addChunk(Thunk->getChunk()); | 554 | } |
| 426 | 555 | ||
| 556 | if (File->ImpSym && !isa<DefinedImportData>(File->ImpSym)) | ||
| 557 | fatal(toString(*File->ImpSym) + " was replaced"); | ||
| 558 | DefinedImportData *ImpSym = cast_or_null<DefinedImportData>(File->ImpSym); | ||
| 427 | if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) { | 559 | if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) { |
| 428 | if (!File->ThunkSym) | 560 | if (!File->ThunkSym) |
| 429 | fatal("cannot delay-load " + toString(File) + | 561 | fatal("cannot delay-load " + toString(File) + |
| 430 | " due to import of data: " + toString(*File->ImpSym)); | 562 | " due to import of data: " + toString(*ImpSym)); |
| 431 | DelayIdata.add(File->ImpSym); | 563 | DelayIdata.add(ImpSym); |
| 432 | } else { | 564 | } else { |
| 433 | Idata.add(File->ImpSym); | 565 | Idata.add(ImpSym); |
| 434 | } | 566 | } |
| 435 | } | 567 | } |
| 436 | 568 | ||
| 437 | if (!Idata.empty()) { | 569 | if (!Idata.empty()) |
| 438 | OutputSection *Sec = createSection(".idata"); | ||
| 439 | for (Chunk *C : Idata.getChunks()) | 570 | for (Chunk *C : Idata.getChunks()) |
| 440 | Sec->addChunk(C); | 571 | IdataSec->addChunk(C); |
| 441 | } | ||
| 442 | 572 | ||
| 443 | if (!DelayIdata.empty()) { | 573 | if (!DelayIdata.empty()) { |
| 444 | Defined *Helper = cast<Defined>(Config->DelayLoadHelper); | 574 | Defined *Helper = cast<Defined>(Config->DelayLoadHelper); |
| 445 | DelayIdata.create(Helper); | 575 | DelayIdata.create(Helper); |
| 446 | OutputSection *Sec = createSection(".didat"); | ||
| 447 | for (Chunk *C : DelayIdata.getChunks()) | 576 | for (Chunk *C : DelayIdata.getChunks()) |
| 448 | Sec->addChunk(C); | 577 | DidatSec->addChunk(C); |
| 449 | Sec = createSection(".data"); | ||
| 450 | for (Chunk *C : DelayIdata.getDataChunks()) | 578 | for (Chunk *C : DelayIdata.getDataChunks()) |
| 451 | Sec->addChunk(C); | 579 | DataSec->addChunk(C); |
| 452 | Sec = createSection(".text"); | ||
| 453 | for (Chunk *C : DelayIdata.getCodeChunks()) | 580 | for (Chunk *C : DelayIdata.getCodeChunks()) |
| 454 | Sec->addChunk(C); | 581 | TextSec->addChunk(C); |
| 455 | } | 582 | } |
| 456 | } | 583 | } |
| 457 | 584 | ||
| 458 | void Writer::createExportTable() { | 585 | void Writer::createExportTable() { |
| 459 | if (Config->Exports.empty()) | 586 | if (Config->Exports.empty()) |
| 460 | return; | 587 | return; |
| 461 | OutputSection *Sec = createSection(".edata"); | ||
| 462 | for (Chunk *C : Edata.Chunks) | 588 | for (Chunk *C : Edata.Chunks) |
| 463 | Sec->addChunk(C); | 589 | EdataSec->addChunk(C); |
| 464 | } | 590 | } |
| 465 | 591 | ||
| 466 | // The Windows loader doesn't seem to like empty sections, | 592 | // The Windows loader doesn't seem to like empty sections, |
| ... | @@ -484,19 +610,31 @@ size_t Writer::addEntryToStringTable(StringRef Str) { | ... | @@ -484,19 +610,31 @@ size_t Writer::addEntryToStringTable(StringRef Str) { |
| 484 | } | 610 | } |
| 485 | 611 | ||
| 486 | Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { | 612 | Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { |
| 487 | // Relative symbols are unrepresentable in a COFF symbol table. | 613 | coff_symbol16 Sym; |
| 488 | if (isa<DefinedSynthetic>(Def)) | 614 | switch (Def->kind()) { |
| 489 | return None; | 615 | case Symbol::DefinedAbsoluteKind: |
| 490 | 616 | Sym.Value = Def->getRVA(); | |
| 491 | // Don't write dead symbols or symbols in codeview sections to the symbol | 617 | Sym.SectionNumber = IMAGE_SYM_ABSOLUTE; |
| 492 | // table. | 618 | break; |
| 493 | if (!Def->isLive()) | 619 | case Symbol::DefinedSyntheticKind: |
| 620 | // Relative symbols are unrepresentable in a COFF symbol table. | ||
| 494 | return None; | 621 | return None; |
| 495 | if (auto *D = dyn_cast<DefinedRegular>(Def)) | 622 | default: { |
| 496 | if (D->getChunk()->isCodeView()) | 623 | // Don't write symbols that won't be written to the output to the symbol |
| 624 | // table. | ||
| 625 | Chunk *C = Def->getChunk(); | ||
| 626 | if (!C) | ||
| 627 | return None; | ||
| 628 | OutputSection *OS = C->getOutputSection(); | ||
| 629 | if (!OS) | ||
| 497 | return None; | 630 | return None; |
| 498 | 631 | ||
| 499 | coff_symbol16 Sym; | 632 | Sym.Value = Def->getRVA() - OS->getRVA(); |
| 633 | Sym.SectionNumber = OS->SectionIndex; | ||
| 634 | break; | ||
| 635 | } | ||
| 636 | } | ||
| 637 | |||
| 500 | StringRef Name = Def->getName(); | 638 | StringRef Name = Def->getName(); |
| 501 | if (Name.size() > COFF::NameSize) { | 639 | if (Name.size() > COFF::NameSize) { |
| 502 | Sym.Name.Offset.Zeroes = 0; | 640 | Sym.Name.Offset.Zeroes = 0; |
| ... | @@ -515,46 +653,27 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { | ... | @@ -515,46 +653,27 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { |
| 515 | Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; | 653 | Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; |
| 516 | } | 654 | } |
| 517 | Sym.NumberOfAuxSymbols = 0; | 655 | Sym.NumberOfAuxSymbols = 0; |
| 518 | |||
| 519 | switch (Def->kind()) { | ||
| 520 | case Symbol::DefinedAbsoluteKind: | ||
| 521 | Sym.Value = Def->getRVA(); | ||
| 522 | Sym.SectionNumber = IMAGE_SYM_ABSOLUTE; | ||
| 523 | break; | ||
| 524 | default: { | ||
| 525 | uint64_t RVA = Def->getRVA(); | ||
| 526 | OutputSection *Sec = nullptr; | ||
| 527 | for (OutputSection *S : OutputSections) { | ||
| 528 | if (S->getRVA() > RVA) | ||
| 529 | break; | ||
| 530 | Sec = S; | ||
| 531 | } | ||
| 532 | Sym.Value = RVA - Sec->getRVA(); | ||
| 533 | Sym.SectionNumber = Sec->SectionIndex; | ||
| 534 | break; | ||
| 535 | } | ||
| 536 | } | ||
| 537 | return Sym; | 656 | return Sym; |
| 538 | } | 657 | } |
| 539 | 658 | ||
| 540 | void Writer::createSymbolAndStringTable() { | 659 | void Writer::createSymbolAndStringTable() { |
| 541 | // Name field in the section table is 8 byte long. Longer names need | 660 | // PE/COFF images are limited to 8 byte section names. Longer names can be |
| 542 | // to be written to the string table. First, construct string table. | 661 | // supported by writing a non-standard string table, but this string table is |
| 662 | // not mapped at runtime and the long names will therefore be inaccessible. | ||
| 663 | // link.exe always truncates section names to 8 bytes, whereas binutils always | ||
| 664 | // preserves long section names via the string table. LLD adopts a hybrid | ||
| 665 | // solution where discardable sections have long names preserved and | ||
| 666 | // non-discardable sections have their names truncated, to ensure that any | ||
| 667 | // section which is mapped at runtime also has its name mapped at runtime. | ||
| 543 | for (OutputSection *Sec : OutputSections) { | 668 | for (OutputSection *Sec : OutputSections) { |
| 544 | StringRef Name = Sec->getName(); | 669 | if (Sec->Name.size() <= COFF::NameSize) |
| 545 | if (Name.size() <= COFF::NameSize) | ||
| 546 | continue; | 670 | continue; |
| 547 | // If a section isn't discardable (i.e. will be mapped at runtime), | 671 | if ((Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0) |
| 548 | // prefer a truncated section name over a long section name in | ||
| 549 | // the string table that is unavailable at runtime. This is different from | ||
| 550 | // what link.exe does, but finding ".eh_fram" instead of "/4" is useful | ||
| 551 | // to libunwind. | ||
| 552 | if ((Sec->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0) | ||
| 553 | continue; | 672 | continue; |
| 554 | Sec->setStringTableOff(addEntryToStringTable(Name)); | 673 | Sec->setStringTableOff(addEntryToStringTable(Sec->Name)); |
| 555 | } | 674 | } |
| 556 | 675 | ||
| 557 | if (Config->DebugDwarf) { | 676 | if (Config->DebugDwarf || Config->DebugSymtab) { |
| 558 | for (ObjFile *File : ObjFile::Instances) { | 677 | for (ObjFile *File : ObjFile::Instances) { |
| 559 | for (Symbol *B : File->getSymbols()) { | 678 | for (Symbol *B : File->getSymbols()) { |
| 560 | auto *D = dyn_cast_or_null<Defined>(B); | 679 | auto *D = dyn_cast_or_null<Defined>(B); |
| ... | @@ -571,16 +690,45 @@ void Writer::createSymbolAndStringTable() { | ... | @@ -571,16 +690,45 @@ void Writer::createSymbolAndStringTable() { |
| 571 | if (OutputSymtab.empty() && Strtab.empty()) | 690 | if (OutputSymtab.empty() && Strtab.empty()) |
| 572 | return; | 691 | return; |
| 573 | 692 | ||
| 574 | OutputSection *LastSection = OutputSections.back(); | ||
| 575 | // We position the symbol table to be adjacent to the end of the last section. | 693 | // We position the symbol table to be adjacent to the end of the last section. |
| 576 | uint64_t FileOff = LastSection->getFileOff() + | 694 | uint64_t FileOff = FileSize; |
| 577 | alignTo(LastSection->getRawSize(), SectorSize); | ||
| 578 | PointerToSymbolTable = FileOff; | 695 | PointerToSymbolTable = FileOff; |
| 579 | FileOff += OutputSymtab.size() * sizeof(coff_symbol16); | 696 | FileOff += OutputSymtab.size() * sizeof(coff_symbol16); |
| 580 | FileOff += 4 + Strtab.size(); | 697 | FileOff += 4 + Strtab.size(); |
| 581 | FileSize = alignTo(FileOff, SectorSize); | 698 | FileSize = alignTo(FileOff, SectorSize); |
| 582 | } | 699 | } |
| 583 | 700 | ||
| 701 | void Writer::mergeSections() { | ||
| 702 | if (!PdataSec->getChunks().empty()) { | ||
| 703 | FirstPdata = PdataSec->getChunks().front(); | ||
| 704 | LastPdata = PdataSec->getChunks().back(); | ||
| 705 | } | ||
| 706 | |||
| 707 | for (auto &P : Config->Merge) { | ||
| 708 | StringRef ToName = P.second; | ||
| 709 | if (P.first == ToName) | ||
| 710 | continue; | ||
| 711 | StringSet<> Names; | ||
| 712 | while (1) { | ||
| 713 | if (!Names.insert(ToName).second) | ||
| 714 | fatal("/merge: cycle found for section '" + P.first + "'"); | ||
| 715 | auto I = Config->Merge.find(ToName); | ||
| 716 | if (I == Config->Merge.end()) | ||
| 717 | break; | ||
| 718 | ToName = I->second; | ||
| 719 | } | ||
| 720 | OutputSection *From = findSection(P.first); | ||
| 721 | OutputSection *To = findSection(ToName); | ||
| 722 | if (!From) | ||
| 723 | continue; | ||
| 724 | if (!To) { | ||
| 725 | From->Name = ToName; | ||
| 726 | continue; | ||
| 727 | } | ||
| 728 | To->merge(From); | ||
| 729 | } | ||
| 730 | } | ||
| 731 | |||
| 584 | // Visits all sections to assign incremental, non-overlapping RVAs and | 732 | // Visits all sections to assign incremental, non-overlapping RVAs and |
| 585 | // file offsets. | 733 | // file offsets. |
| 586 | void Writer::assignAddresses() { | 734 | void Writer::assignAddresses() { |
| ... | @@ -590,35 +738,57 @@ void Writer::assignAddresses() { | ... | @@ -590,35 +738,57 @@ void Writer::assignAddresses() { |
| 590 | SizeOfHeaders += | 738 | SizeOfHeaders += |
| 591 | Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); | 739 | Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); |
| 592 | SizeOfHeaders = alignTo(SizeOfHeaders, SectorSize); | 740 | SizeOfHeaders = alignTo(SizeOfHeaders, SectorSize); |
| 593 | uint64_t RVA = 0x1000; // The first page is kept unmapped. | 741 | uint64_t RVA = PageSize; // The first page is kept unmapped. |
| 594 | FileSize = SizeOfHeaders; | 742 | FileSize = SizeOfHeaders; |
| 595 | // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because | 743 | |
| 596 | // the loader cannot handle holes. | ||
| 597 | std::stable_partition( | ||
| 598 | OutputSections.begin(), OutputSections.end(), [](OutputSection *S) { | ||
| 599 | return (S->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0; | ||
| 600 | }); | ||
| 601 | for (OutputSection *Sec : OutputSections) { | 744 | for (OutputSection *Sec : OutputSections) { |
| 602 | if (Sec->getName() == ".reloc") | 745 | if (Sec == RelocSec) |
| 603 | addBaserels(Sec); | 746 | addBaserels(); |
| 604 | Sec->setRVA(RVA); | 747 | uint64_t RawSize = 0, VirtualSize = 0; |
| 605 | Sec->setFileOffset(FileSize); | 748 | Sec->Header.VirtualAddress = RVA; |
| 606 | RVA += alignTo(Sec->getVirtualSize(), PageSize); | 749 | for (Chunk *C : Sec->getChunks()) { |
| 607 | FileSize += alignTo(Sec->getRawSize(), SectorSize); | 750 | VirtualSize = alignTo(VirtualSize, C->Alignment); |
| 751 | C->setRVA(RVA + VirtualSize); | ||
| 752 | C->OutputSectionOff = VirtualSize; | ||
| 753 | C->finalizeContents(); | ||
| 754 | VirtualSize += C->getSize(); | ||
| 755 | if (C->hasData()) | ||
| 756 | RawSize = alignTo(VirtualSize, SectorSize); | ||
| 757 | } | ||
| 758 | if (VirtualSize > UINT32_MAX) | ||
| 759 | error("section larger than 4 GiB: " + Sec->Name); | ||
| 760 | Sec->Header.VirtualSize = VirtualSize; | ||
| 761 | Sec->Header.SizeOfRawData = RawSize; | ||
| 762 | if (RawSize != 0) | ||
| 763 | Sec->Header.PointerToRawData = FileSize; | ||
| 764 | RVA += alignTo(VirtualSize, PageSize); | ||
| 765 | FileSize += alignTo(RawSize, SectorSize); | ||
| 608 | } | 766 | } |
| 609 | SizeOfImage = alignTo(RVA, PageSize); | 767 | SizeOfImage = alignTo(RVA, PageSize); |
| 610 | } | 768 | } |
| 611 | 769 | ||
| 612 | template <typename PEHeaderTy> void Writer::writeHeader() { | 770 | template <typename PEHeaderTy> void Writer::writeHeader() { |
| 613 | // Write DOS stub | 771 | // Write DOS header. For backwards compatibility, the first part of a PE/COFF |
| 772 | // executable consists of an MS-DOS MZ executable. If the executable is run | ||
| 773 | // under DOS, that program gets run (usually to just print an error message). | ||
| 774 | // When run under Windows, the loader looks at AddressOfNewExeHeader and uses | ||
| 775 | // the PE header instead. | ||
| 614 | uint8_t *Buf = Buffer->getBufferStart(); | 776 | uint8_t *Buf = Buffer->getBufferStart(); |
| 615 | auto *DOS = reinterpret_cast<dos_header *>(Buf); | 777 | auto *DOS = reinterpret_cast<dos_header *>(Buf); |
| 616 | Buf += DOSStubSize; | 778 | Buf += sizeof(dos_header); |
| 617 | DOS->Magic[0] = 'M'; | 779 | DOS->Magic[0] = 'M'; |
| 618 | DOS->Magic[1] = 'Z'; | 780 | DOS->Magic[1] = 'Z'; |
| 781 | DOS->UsedBytesInTheLastPage = DOSStubSize % 512; | ||
| 782 | DOS->FileSizeInPages = divideCeil(DOSStubSize, 512); | ||
| 783 | DOS->HeaderSizeInParagraphs = sizeof(dos_header) / 16; | ||
| 784 | |||
| 619 | DOS->AddressOfRelocationTable = sizeof(dos_header); | 785 | DOS->AddressOfRelocationTable = sizeof(dos_header); |
| 620 | DOS->AddressOfNewExeHeader = DOSStubSize; | 786 | DOS->AddressOfNewExeHeader = DOSStubSize; |
| 621 | 787 | ||
| 788 | // Write DOS program. | ||
| 789 | memcpy(Buf, DOSProgram, sizeof(DOSProgram)); | ||
| 790 | Buf += sizeof(DOSProgram); | ||
| 791 | |||
| 622 | // Write PE magic | 792 | // Write PE magic |
| 623 | memcpy(Buf, PEMagic, sizeof(PEMagic)); | 793 | memcpy(Buf, PEMagic, sizeof(PEMagic)); |
| 624 | Buf += sizeof(PEMagic); | 794 | Buf += sizeof(PEMagic); |
| ... | @@ -688,24 +858,27 @@ template <typename PEHeaderTy> void Writer::writeHeader() { | ... | @@ -688,24 +858,27 @@ template <typename PEHeaderTy> void Writer::writeHeader() { |
| 688 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT; | 858 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT; |
| 689 | if (!Config->AllowIsolation) | 859 | if (!Config->AllowIsolation) |
| 690 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION; | 860 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION; |
| 691 | if (Config->Machine == I386 && !SEHTable && | 861 | if (Config->GuardCF != GuardCFLevel::Off) |
| 692 | !Symtab->findUnderscore("_load_config_used")) | 862 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF; |
| 863 | if (Config->IntegrityCheck) | ||
| 864 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY; | ||
| 865 | if (SetNoSEHCharacteristic) | ||
| 693 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH; | 866 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH; |
| 694 | if (Config->TerminalServerAware) | 867 | if (Config->TerminalServerAware) |
| 695 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; | 868 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; |
| 696 | PE->NumberOfRvaAndSize = NumberfOfDataDirectory; | 869 | PE->NumberOfRvaAndSize = NumberfOfDataDirectory; |
| 697 | if (OutputSection *Text = findSection(".text")) { | 870 | if (TextSec->getVirtualSize()) { |
| 698 | PE->BaseOfCode = Text->getRVA(); | 871 | PE->BaseOfCode = TextSec->getRVA(); |
| 699 | PE->SizeOfCode = Text->getRawSize(); | 872 | PE->SizeOfCode = TextSec->getRawSize(); |
| 700 | } | 873 | } |
| 701 | PE->SizeOfInitializedData = getSizeOfInitializedData(); | 874 | PE->SizeOfInitializedData = getSizeOfInitializedData(); |
| 702 | 875 | ||
| 703 | // Write data directory | 876 | // Write data directory |
| 704 | auto *Dir = reinterpret_cast<data_directory *>(Buf); | 877 | auto *Dir = reinterpret_cast<data_directory *>(Buf); |
| 705 | Buf += sizeof(*Dir) * NumberfOfDataDirectory; | 878 | Buf += sizeof(*Dir) * NumberfOfDataDirectory; |
| 706 | if (OutputSection *Sec = findSection(".edata")) { | 879 | if (!Config->Exports.empty()) { |
| 707 | Dir[EXPORT_TABLE].RelativeVirtualAddress = Sec->getRVA(); | 880 | Dir[EXPORT_TABLE].RelativeVirtualAddress = Edata.getRVA(); |
| 708 | Dir[EXPORT_TABLE].Size = Sec->getVirtualSize(); | 881 | Dir[EXPORT_TABLE].Size = Edata.getSize(); |
| 709 | } | 882 | } |
| 710 | if (!Idata.empty()) { | 883 | if (!Idata.empty()) { |
| 711 | Dir[IMPORT_TABLE].RelativeVirtualAddress = Idata.getDirRVA(); | 884 | Dir[IMPORT_TABLE].RelativeVirtualAddress = Idata.getDirRVA(); |
| ... | @@ -713,17 +886,18 @@ template <typename PEHeaderTy> void Writer::writeHeader() { | ... | @@ -713,17 +886,18 @@ template <typename PEHeaderTy> void Writer::writeHeader() { |
| 713 | Dir[IAT].RelativeVirtualAddress = Idata.getIATRVA(); | 886 | Dir[IAT].RelativeVirtualAddress = Idata.getIATRVA(); |
| 714 | Dir[IAT].Size = Idata.getIATSize(); | 887 | Dir[IAT].Size = Idata.getIATSize(); |
| 715 | } | 888 | } |
| 716 | if (OutputSection *Sec = findSection(".rsrc")) { | 889 | if (RsrcSec->getVirtualSize()) { |
| 717 | Dir[RESOURCE_TABLE].RelativeVirtualAddress = Sec->getRVA(); | 890 | Dir[RESOURCE_TABLE].RelativeVirtualAddress = RsrcSec->getRVA(); |
| 718 | Dir[RESOURCE_TABLE].Size = Sec->getVirtualSize(); | 891 | Dir[RESOURCE_TABLE].Size = RsrcSec->getVirtualSize(); |
| 719 | } | 892 | } |
| 720 | if (OutputSection *Sec = findSection(".pdata")) { | 893 | if (FirstPdata) { |
| 721 | Dir[EXCEPTION_TABLE].RelativeVirtualAddress = Sec->getRVA(); | 894 | Dir[EXCEPTION_TABLE].RelativeVirtualAddress = FirstPdata->getRVA(); |
| 722 | Dir[EXCEPTION_TABLE].Size = Sec->getVirtualSize(); | 895 | Dir[EXCEPTION_TABLE].Size = |
| 896 | LastPdata->getRVA() + LastPdata->getSize() - FirstPdata->getRVA(); | ||
| 723 | } | 897 | } |
| 724 | if (OutputSection *Sec = findSection(".reloc")) { | 898 | if (RelocSec->getVirtualSize()) { |
| 725 | Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = Sec->getRVA(); | 899 | Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = RelocSec->getRVA(); |
| 726 | Dir[BASE_RELOCATION_TABLE].Size = Sec->getVirtualSize(); | 900 | Dir[BASE_RELOCATION_TABLE].Size = RelocSec->getVirtualSize(); |
| 727 | } | 901 | } |
| 728 | if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) { | 902 | if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) { |
| 729 | if (Defined *B = dyn_cast<Defined>(Sym)) { | 903 | if (Defined *B = dyn_cast<Defined>(Sym)) { |
| ... | @@ -792,35 +966,172 @@ void Writer::openFile(StringRef Path) { | ... | @@ -792,35 +966,172 @@ void Writer::openFile(StringRef Path) { |
| 792 | "failed to open " + Path); | 966 | "failed to open " + Path); |
| 793 | } | 967 | } |
| 794 | 968 | ||
| 795 | void Writer::createSEHTable(OutputSection *RData) { | 969 | void Writer::createSEHTable() { |
| 796 | // Create SEH table. x86-only. | 970 | // Set the no SEH characteristic on x86 binaries unless we find exception |
| 797 | if (Config->Machine != I386) | 971 | // handlers. |
| 798 | return; | 972 | SetNoSEHCharacteristic = true; |
| 799 | |||
| 800 | std::set<Defined *> Handlers; | ||
| 801 | 973 | ||
| 974 | SymbolRVASet Handlers; | ||
| 802 | for (ObjFile *File : ObjFile::Instances) { | 975 | for (ObjFile *File : ObjFile::Instances) { |
| 803 | if (!File->SEHCompat) | 976 | // FIXME: We should error here instead of earlier unless /safeseh:no was |
| 977 | // passed. | ||
| 978 | if (!File->hasSafeSEH()) | ||
| 804 | return; | 979 | return; |
| 805 | for (uint32_t I : File->SXData) | 980 | |
| 806 | if (Symbol *B = File->getSymbol(I)) | 981 | markSymbolsForRVATable(File, File->getSXDataChunks(), Handlers); |
| 807 | if (B->isLive()) | 982 | } |
| 808 | Handlers.insert(cast<Defined>(B)); | 983 | |
| 984 | // Remove the "no SEH" characteristic if all object files were built with | ||
| 985 | // safeseh, we found some exception handlers, and there is a load config in | ||
| 986 | // the object. | ||
| 987 | SetNoSEHCharacteristic = | ||
| 988 | Handlers.empty() || !Symtab->findUnderscore("_load_config_used"); | ||
| 989 | |||
| 990 | maybeAddRVATable(std::move(Handlers), "__safe_se_handler_table", | ||
| 991 | "__safe_se_handler_count"); | ||
| 992 | } | ||
| 993 | |||
| 994 | // Add a symbol to an RVA set. Two symbols may have the same RVA, but an RVA set | ||
| 995 | // cannot contain duplicates. Therefore, the set is uniqued by Chunk and the | ||
| 996 | // symbol's offset into that Chunk. | ||
| 997 | static void addSymbolToRVASet(SymbolRVASet &RVASet, Defined *S) { | ||
| 998 | Chunk *C = S->getChunk(); | ||
| 999 | if (auto *SC = dyn_cast<SectionChunk>(C)) | ||
| 1000 | C = SC->Repl; // Look through ICF replacement. | ||
| 1001 | uint32_t Off = S->getRVA() - (C ? C->getRVA() : 0); | ||
| 1002 | RVASet.insert({C, Off}); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | // Visit all relocations from all section contributions of this object file and | ||
| 1006 | // mark the relocation target as address-taken. | ||
| 1007 | static void markSymbolsWithRelocations(ObjFile *File, | ||
| 1008 | SymbolRVASet &UsedSymbols) { | ||
| 1009 | for (Chunk *C : File->getChunks()) { | ||
| 1010 | // We only care about live section chunks. Common chunks and other chunks | ||
| 1011 | // don't generally contain relocations. | ||
| 1012 | SectionChunk *SC = dyn_cast<SectionChunk>(C); | ||
| 1013 | if (!SC || !SC->isLive()) | ||
| 1014 | continue; | ||
| 1015 | |||
| 1016 | // Look for relocations in this section against symbols in executable output | ||
| 1017 | // sections. | ||
| 1018 | for (Symbol *Ref : SC->symbols()) { | ||
| 1019 | // FIXME: Do further testing to see if the relocation type matters, | ||
| 1020 | // especially for 32-bit where taking the address of something usually | ||
| 1021 | // uses an absolute relocation instead of a relative one. | ||
| 1022 | if (auto *D = dyn_cast_or_null<Defined>(Ref)) { | ||
| 1023 | Chunk *RefChunk = D->getChunk(); | ||
| 1024 | OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr; | ||
| 1025 | if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE) | ||
| 1026 | addSymbolToRVASet(UsedSymbols, D); | ||
| 1027 | } | ||
| 1028 | } | ||
| 1029 | } | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | // Create the guard function id table. This is a table of RVAs of all | ||
| 1033 | // address-taken functions. It is sorted and uniqued, just like the safe SEH | ||
| 1034 | // table. | ||
| 1035 | void Writer::createGuardCFTables() { | ||
| 1036 | SymbolRVASet AddressTakenSyms; | ||
| 1037 | SymbolRVASet LongJmpTargets; | ||
| 1038 | for (ObjFile *File : ObjFile::Instances) { | ||
| 1039 | // If the object was compiled with /guard:cf, the address taken symbols | ||
| 1040 | // are in .gfids$y sections, and the longjmp targets are in .gljmp$y | ||
| 1041 | // sections. If the object was not compiled with /guard:cf, we assume there | ||
| 1042 | // were no setjmp targets, and that all code symbols with relocations are | ||
| 1043 | // possibly address-taken. | ||
| 1044 | if (File->hasGuardCF()) { | ||
| 1045 | markSymbolsForRVATable(File, File->getGuardFidChunks(), AddressTakenSyms); | ||
| 1046 | markSymbolsForRVATable(File, File->getGuardLJmpChunks(), LongJmpTargets); | ||
| 1047 | } else { | ||
| 1048 | markSymbolsWithRelocations(File, AddressTakenSyms); | ||
| 1049 | } | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | // Mark the image entry as address-taken. | ||
| 1053 | if (Config->Entry) | ||
| 1054 | addSymbolToRVASet(AddressTakenSyms, cast<Defined>(Config->Entry)); | ||
| 1055 | |||
| 1056 | // Ensure sections referenced in the gfid table are 16-byte aligned. | ||
| 1057 | for (const ChunkAndOffset &C : AddressTakenSyms) | ||
| 1058 | if (C.InputChunk->Alignment < 16) | ||
| 1059 | C.InputChunk->Alignment = 16; | ||
| 1060 | |||
| 1061 | maybeAddRVATable(std::move(AddressTakenSyms), "__guard_fids_table", | ||
| 1062 | "__guard_fids_count"); | ||
| 1063 | |||
| 1064 | // Add the longjmp target table unless the user told us not to. | ||
| 1065 | if (Config->GuardCF == GuardCFLevel::Full) | ||
| 1066 | maybeAddRVATable(std::move(LongJmpTargets), "__guard_longjmp_table", | ||
| 1067 | "__guard_longjmp_count"); | ||
| 1068 | |||
| 1069 | // Set __guard_flags, which will be used in the load config to indicate that | ||
| 1070 | // /guard:cf was enabled. | ||
| 1071 | uint32_t GuardFlags = uint32_t(coff_guard_flags::CFInstrumented) | | ||
| 1072 | uint32_t(coff_guard_flags::HasFidTable); | ||
| 1073 | if (Config->GuardCF == GuardCFLevel::Full) | ||
| 1074 | GuardFlags |= uint32_t(coff_guard_flags::HasLongJmpTable); | ||
| 1075 | Symbol *FlagSym = Symtab->findUnderscore("__guard_flags"); | ||
| 1076 | cast<DefinedAbsolute>(FlagSym)->setVA(GuardFlags); | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | // Take a list of input sections containing symbol table indices and add those | ||
| 1080 | // symbols to an RVA table. The challenge is that symbol RVAs are not known and | ||
| 1081 | // depend on the table size, so we can't directly build a set of integers. | ||
| 1082 | void Writer::markSymbolsForRVATable(ObjFile *File, | ||
| 1083 | ArrayRef<SectionChunk *> SymIdxChunks, | ||
| 1084 | SymbolRVASet &TableSymbols) { | ||
| 1085 | for (SectionChunk *C : SymIdxChunks) { | ||
| 1086 | // Skip sections discarded by linker GC. This comes up when a .gfids section | ||
| 1087 | // is associated with something like a vtable and the vtable is discarded. | ||
| 1088 | // In this case, the associated gfids section is discarded, and we don't | ||
| 1089 | // mark the virtual member functions as address-taken by the vtable. | ||
| 1090 | if (!C->isLive()) | ||
| 1091 | continue; | ||
| 1092 | |||
| 1093 | // Validate that the contents look like symbol table indices. | ||
| 1094 | ArrayRef<uint8_t> Data = C->getContents(); | ||
| 1095 | if (Data.size() % 4 != 0) { | ||
| 1096 | warn("ignoring " + C->getSectionName() + | ||
| 1097 | " symbol table index section in object " + toString(File)); | ||
| 1098 | continue; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | // Read each symbol table index and check if that symbol was included in the | ||
| 1102 | // final link. If so, add it to the table symbol set. | ||
| 1103 | ArrayRef<ulittle32_t> SymIndices( | ||
| 1104 | reinterpret_cast<const ulittle32_t *>(Data.data()), Data.size() / 4); | ||
| 1105 | ArrayRef<Symbol *> ObjSymbols = File->getSymbols(); | ||
| 1106 | for (uint32_t SymIndex : SymIndices) { | ||
| 1107 | if (SymIndex >= ObjSymbols.size()) { | ||
| 1108 | warn("ignoring invalid symbol table index in section " + | ||
| 1109 | C->getSectionName() + " in object " + toString(File)); | ||
| 1110 | continue; | ||
| 1111 | } | ||
| 1112 | if (Symbol *S = ObjSymbols[SymIndex]) { | ||
| 1113 | if (S->isLive()) | ||
| 1114 | addSymbolToRVASet(TableSymbols, cast<Defined>(S)); | ||
| 1115 | } | ||
| 1116 | } | ||
| 809 | } | 1117 | } |
| 1118 | } | ||
| 810 | 1119 | ||
| 811 | if (Handlers.empty()) | 1120 | // Replace the absolute table symbol with a synthetic symbol pointing to |
| 1121 | // TableChunk so that we can emit base relocations for it and resolve section | ||
| 1122 | // relative relocations. | ||
| 1123 | void Writer::maybeAddRVATable(SymbolRVASet TableSymbols, StringRef TableSym, | ||
| 1124 | StringRef CountSym) { | ||
| 1125 | if (TableSymbols.empty()) | ||
| 812 | return; | 1126 | return; |
| 813 | 1127 | ||
| 814 | SEHTable = make<SEHTableChunk>(Handlers); | 1128 | RVATableChunk *TableChunk = make<RVATableChunk>(std::move(TableSymbols)); |
| 815 | RData->addChunk(SEHTable); | 1129 | RdataSec->addChunk(TableChunk); |
| 816 | 1130 | ||
| 817 | // Replace the absolute table symbol with a synthetic symbol pointing to the | 1131 | Symbol *T = Symtab->findUnderscore(TableSym); |
| 818 | // SEHTable chunk so that we can emit base relocations for it and resolve | 1132 | Symbol *C = Symtab->findUnderscore(CountSym); |
| 819 | // section relative relocations. | 1133 | replaceSymbol<DefinedSynthetic>(T, T->getName(), TableChunk); |
| 820 | Symbol *T = Symtab->find("___safe_se_handler_table"); | 1134 | cast<DefinedAbsolute>(C)->setVA(TableChunk->getSize() / 4); |
| 821 | Symbol *C = Symtab->find("___safe_se_handler_count"); | ||
| 822 | replaceSymbol<DefinedSynthetic>(T, T->getName(), SEHTable); | ||
| 823 | cast<DefinedAbsolute>(C)->setVA(SEHTable->getSize() / 4); | ||
| 824 | } | 1135 | } |
| 825 | 1136 | ||
| 826 | // Handles /section options to allow users to overwrite | 1137 | // Handles /section options to allow users to overwrite |
| ... | @@ -829,16 +1140,17 @@ void Writer::setSectionPermissions() { | ... | @@ -829,16 +1140,17 @@ void Writer::setSectionPermissions() { |
| 829 | for (auto &P : Config->Section) { | 1140 | for (auto &P : Config->Section) { |
| 830 | StringRef Name = P.first; | 1141 | StringRef Name = P.first; |
| 831 | uint32_t Perm = P.second; | 1142 | uint32_t Perm = P.second; |
| 832 | if (auto *Sec = findSection(Name)) | 1143 | for (OutputSection *Sec : OutputSections) |
| 833 | Sec->setPermissions(Perm); | 1144 | if (Sec->Name == Name) |
| 1145 | Sec->setPermissions(Perm); | ||
| 834 | } | 1146 | } |
| 835 | } | 1147 | } |
| 836 | 1148 | ||
| 837 | // Write section contents to a mmap'ed file. | 1149 | // Write section contents to a mmap'ed file. |
| 838 | void Writer::writeSections() { | 1150 | void Writer::writeSections() { |
| 839 | // Record the section index that should be used when resolving a section | 1151 | // Record the number of sections to apply section index relocations |
| 840 | // relocation against an absolute symbol. | 1152 | // against absolute symbols. See applySecIdx in Chunks.cpp.. |
| 841 | DefinedAbsolute::OutputSectionIndex = OutputSections.size() + 1; | 1153 | DefinedAbsolute::NumOutputSections = OutputSections.size(); |
| 842 | 1154 | ||
| 843 | uint8_t *Buf = Buffer->getBufferStart(); | 1155 | uint8_t *Buf = Buffer->getBufferStart(); |
| 844 | for (OutputSection *Sec : OutputSections) { | 1156 | for (OutputSection *Sec : OutputSections) { |
| ... | @@ -846,7 +1158,7 @@ void Writer::writeSections() { | ... | @@ -846,7 +1158,7 @@ void Writer::writeSections() { |
| 846 | // Fill gaps between functions in .text with INT3 instructions | 1158 | // Fill gaps between functions in .text with INT3 instructions |
| 847 | // instead of leaving as NUL bytes (which can be interpreted as | 1159 | // instead of leaving as NUL bytes (which can be interpreted as |
| 848 | // ADD instructions). | 1160 | // ADD instructions). |
| 849 | if (Sec->getPermissions() & IMAGE_SCN_CNT_CODE) | 1161 | if (Sec->Header.Characteristics & IMAGE_SCN_CNT_CODE) |
| 850 | memset(SecBuf, 0xCC, Sec->getRawSize()); | 1162 | memset(SecBuf, 0xCC, Sec->getRawSize()); |
| 851 | for_each(parallel::par, Sec->getChunks().begin(), Sec->getChunks().end(), | 1163 | for_each(parallel::par, Sec->getChunks().begin(), Sec->getChunks().end(), |
| 852 | [&](Chunk *C) { C->writeTo(SecBuf); }); | 1164 | [&](Chunk *C) { C->writeTo(SecBuf); }); |
| ... | @@ -854,32 +1166,65 @@ void Writer::writeSections() { | ... | @@ -854,32 +1166,65 @@ void Writer::writeSections() { |
| 854 | } | 1166 | } |
| 855 | 1167 | ||
| 856 | void Writer::writeBuildId() { | 1168 | void Writer::writeBuildId() { |
| 857 | // If we're not writing a build id (e.g. because /debug is not specified), | 1169 | // There are two important parts to the build ID. |
| 858 | // then just return; | 1170 | // 1) If building with debug info, the COFF debug directory contains a |
| 859 | if (!Config->Debug) | 1171 | // timestamp as well as a Guid and Age of the PDB. |
| 860 | return; | 1172 | // 2) In all cases, the PE COFF file header also contains a timestamp. |
| 1173 | // For reproducibility, instead of a timestamp we want to use a hash of the | ||
| 1174 | // binary, however when building with debug info the hash needs to take into | ||
| 1175 | // account the debug info, since it's possible to add blank lines to a file | ||
| 1176 | // which causes the debug info to change but not the generated code. | ||
| 1177 | // | ||
| 1178 | // To handle this, we first set the Guid and Age in the debug directory (but | ||
| 1179 | // only if we're doing a debug build). Then, we hash the binary (thus causing | ||
| 1180 | // the hash to change if only the debug info changes, since the Age will be | ||
| 1181 | // different). Finally, we write that hash into the debug directory (if | ||
| 1182 | // present) as well as the COFF file header (always). | ||
| 1183 | if (Config->Debug) { | ||
| 1184 | assert(BuildId && "BuildId is not set!"); | ||
| 1185 | if (PreviousBuildId.hasValue()) { | ||
| 1186 | *BuildId->BuildId = *PreviousBuildId; | ||
| 1187 | BuildId->BuildId->PDB70.Age = BuildId->BuildId->PDB70.Age + 1; | ||
| 1188 | } else { | ||
| 1189 | BuildId->BuildId->Signature.CVSignature = OMF::Signature::PDB70; | ||
| 1190 | BuildId->BuildId->PDB70.Age = 1; | ||
| 1191 | llvm::getRandomBytes(BuildId->BuildId->PDB70.Signature, 16); | ||
| 1192 | } | ||
| 1193 | } | ||
| 861 | 1194 | ||
| 862 | assert(BuildId && "BuildId is not set!"); | 1195 | // At this point the only fields in the COFF file which remain unset are the |
| 1196 | // "timestamp" in the COFF file header, and the ones in the coff debug | ||
| 1197 | // directory. Now we can hash the file and write that hash to the various | ||
| 1198 | // timestamp fields in the file. | ||
| 1199 | StringRef OutputFileData( | ||
| 1200 | reinterpret_cast<const char *>(Buffer->getBufferStart()), | ||
| 1201 | Buffer->getBufferSize()); | ||
| 863 | 1202 | ||
| 864 | if (PreviousBuildId.hasValue()) { | 1203 | uint32_t Timestamp = Config->Timestamp; |
| 865 | *BuildId->BuildId = *PreviousBuildId; | 1204 | if (Config->Repro) |
| 866 | BuildId->BuildId->PDB70.Age = BuildId->BuildId->PDB70.Age + 1; | 1205 | Timestamp = static_cast<uint32_t>(xxHash64(OutputFileData)); |
| 867 | return; | 1206 | |
| 868 | } | 1207 | if (DebugDirectory) |
| 1208 | DebugDirectory->setTimeDateStamp(Timestamp); | ||
| 869 | 1209 | ||
| 870 | BuildId->BuildId->Signature.CVSignature = OMF::Signature::PDB70; | 1210 | uint8_t *Buf = Buffer->getBufferStart(); |
| 871 | BuildId->BuildId->PDB70.Age = 1; | 1211 | Buf += DOSStubSize + sizeof(PEMagic); |
| 872 | llvm::getRandomBytes(BuildId->BuildId->PDB70.Signature, 16); | 1212 | object::coff_file_header *CoffHeader = |
| 1213 | reinterpret_cast<coff_file_header *>(Buf); | ||
| 1214 | CoffHeader->TimeDateStamp = Timestamp; | ||
| 873 | } | 1215 | } |
| 874 | 1216 | ||
| 875 | // Sort .pdata section contents according to PE/COFF spec 5.5. | 1217 | // Sort .pdata section contents according to PE/COFF spec 5.5. |
| 876 | void Writer::sortExceptionTable() { | 1218 | void Writer::sortExceptionTable() { |
| 877 | OutputSection *Sec = findSection(".pdata"); | 1219 | if (!FirstPdata) |
| 878 | if (!Sec) | ||
| 879 | return; | 1220 | return; |
| 880 | // We assume .pdata contains function table entries only. | 1221 | // We assume .pdata contains function table entries only. |
| 881 | uint8_t *Begin = Buffer->getBufferStart() + Sec->getFileOff(); | 1222 | auto BufAddr = [&](Chunk *C) { |
| 882 | uint8_t *End = Begin + Sec->getVirtualSize(); | 1223 | return Buffer->getBufferStart() + C->getOutputSection()->getFileOff() + |
| 1224 | C->getRVA() - C->getOutputSection()->getRVA(); | ||
| 1225 | }; | ||
| 1226 | uint8_t *Begin = BufAddr(FirstPdata); | ||
| 1227 | uint8_t *End = BufAddr(LastPdata) + LastPdata->getSize(); | ||
| 883 | if (Config->Machine == AMD64) { | 1228 | if (Config->Machine == AMD64) { |
| 884 | struct Entry { ulittle32_t Begin, End, Unwind; }; | 1229 | struct Entry { ulittle32_t Begin, End, Unwind; }; |
| 885 | sort(parallel::par, (Entry *)Begin, (Entry *)End, | 1230 | sort(parallel::par, (Entry *)Begin, (Entry *)End, |
| ... | @@ -897,7 +1242,7 @@ void Writer::sortExceptionTable() { | ... | @@ -897,7 +1242,7 @@ void Writer::sortExceptionTable() { |
| 897 | 1242 | ||
| 898 | OutputSection *Writer::findSection(StringRef Name) { | 1243 | OutputSection *Writer::findSection(StringRef Name) { |
| 899 | for (OutputSection *Sec : OutputSections) | 1244 | for (OutputSection *Sec : OutputSections) |
| 900 | if (Sec->getName() == Name) | 1245 | if (Sec->Name == Name) |
| 901 | return Sec; | 1246 | return Sec; |
| 902 | return nullptr; | 1247 | return nullptr; |
| 903 | } | 1248 | } |
| ... | @@ -905,55 +1250,31 @@ OutputSection *Writer::findSection(StringRef Name) { | ... | @@ -905,55 +1250,31 @@ OutputSection *Writer::findSection(StringRef Name) { |
| 905 | uint32_t Writer::getSizeOfInitializedData() { | 1250 | uint32_t Writer::getSizeOfInitializedData() { |
| 906 | uint32_t Res = 0; | 1251 | uint32_t Res = 0; |
| 907 | for (OutputSection *S : OutputSections) | 1252 | for (OutputSection *S : OutputSections) |
| 908 | if (S->getPermissions() & IMAGE_SCN_CNT_INITIALIZED_DATA) | 1253 | if (S->Header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) |
| 909 | Res += S->getRawSize(); | 1254 | Res += S->getRawSize(); |
| 910 | return Res; | 1255 | return Res; |
| 911 | } | 1256 | } |
| 912 | 1257 | ||
| 913 | // Returns an existing section or create a new one if not found. | 1258 | // Add base relocations to .reloc section. |
| 914 | OutputSection *Writer::createSection(StringRef Name) { | 1259 | void Writer::addBaserels() { |
| 915 | if (auto *Sec = findSection(Name)) | 1260 | if (!Config->Relocatable) |
| 916 | return Sec; | 1261 | return; |
| 917 | const auto DATA = IMAGE_SCN_CNT_INITIALIZED_DATA; | ||
| 918 | const auto BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA; | ||
| 919 | const auto CODE = IMAGE_SCN_CNT_CODE; | ||
| 920 | const auto DISCARDABLE = IMAGE_SCN_MEM_DISCARDABLE; | ||
| 921 | const auto R = IMAGE_SCN_MEM_READ; | ||
| 922 | const auto W = IMAGE_SCN_MEM_WRITE; | ||
| 923 | const auto X = IMAGE_SCN_MEM_EXECUTE; | ||
| 924 | uint32_t Perms = StringSwitch<uint32_t>(Name) | ||
| 925 | .Case(".bss", BSS | R | W) | ||
| 926 | .Case(".data", DATA | R | W) | ||
| 927 | .Cases(".didat", ".edata", ".idata", ".rdata", DATA | R) | ||
| 928 | .Case(".reloc", DATA | DISCARDABLE | R) | ||
| 929 | .Case(".text", CODE | R | X) | ||
| 930 | .Default(0); | ||
| 931 | if (!Perms) | ||
| 932 | llvm_unreachable("unknown section name"); | ||
| 933 | auto Sec = make<OutputSection>(Name); | ||
| 934 | Sec->addPermissions(Perms); | ||
| 935 | OutputSections.push_back(Sec); | ||
| 936 | return Sec; | ||
| 937 | } | ||
| 938 | |||
| 939 | // Dest is .reloc section. Add contents to that section. | ||
| 940 | void Writer::addBaserels(OutputSection *Dest) { | ||
| 941 | std::vector<Baserel> V; | 1262 | std::vector<Baserel> V; |
| 942 | for (OutputSection *Sec : OutputSections) { | 1263 | for (OutputSection *Sec : OutputSections) { |
| 943 | if (Sec == Dest) | 1264 | if (Sec->Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) |
| 944 | continue; | 1265 | continue; |
| 945 | // Collect all locations for base relocations. | 1266 | // Collect all locations for base relocations. |
| 946 | for (Chunk *C : Sec->getChunks()) | 1267 | for (Chunk *C : Sec->getChunks()) |
| 947 | C->getBaserels(&V); | 1268 | C->getBaserels(&V); |
| 948 | // Add the addresses to .reloc section. | 1269 | // Add the addresses to .reloc section. |
| 949 | if (!V.empty()) | 1270 | if (!V.empty()) |
| 950 | addBaserelBlocks(Dest, V); | 1271 | addBaserelBlocks(V); |
| 951 | V.clear(); | 1272 | V.clear(); |
| 952 | } | 1273 | } |
| 953 | } | 1274 | } |
| 954 | 1275 | ||
| 955 | // Add addresses to .reloc section. Note that addresses are grouped by page. | 1276 | // Add addresses to .reloc section. Note that addresses are grouped by page. |
| 956 | void Writer::addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V) { | 1277 | void Writer::addBaserelBlocks(std::vector<Baserel> &V) { |
| 957 | const uint32_t Mask = ~uint32_t(PageSize - 1); | 1278 | const uint32_t Mask = ~uint32_t(PageSize - 1); |
| 958 | uint32_t Page = V[0].RVA & Mask; | 1279 | uint32_t Page = V[0].RVA & Mask; |
| 959 | size_t I = 0, J = 1; | 1280 | size_t I = 0, J = 1; |
| ... | @@ -961,11 +1282,11 @@ void Writer::addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V) { | ... | @@ -961,11 +1282,11 @@ void Writer::addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V) { |
| 961 | uint32_t P = V[J].RVA & Mask; | 1282 | uint32_t P = V[J].RVA & Mask; |
| 962 | if (P == Page) | 1283 | if (P == Page) |
| 963 | continue; | 1284 | continue; |
| 964 | Dest->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J)); | 1285 | RelocSec->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J)); |
| 965 | I = J; | 1286 | I = J; |
| 966 | Page = P; | 1287 | Page = P; |
| 967 | } | 1288 | } |
| 968 | if (I == J) | 1289 | if (I == J) |
| 969 | return; | 1290 | return; |
| 970 | Dest->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J)); | 1291 | RelocSec->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J)); |
| 971 | } | 1292 | } |
deps/lld/COFF/Writer.h+8-8| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | #include "Chunks.h" | 13 | #include "Chunks.h" |
| 14 | #include "llvm/ADT/StringRef.h" | 14 | #include "llvm/ADT/StringRef.h" |
| 15 | #include "llvm/Object/COFF.h" | 15 | #include "llvm/Object/COFF.h" |
| 16 | #include <chrono> | ||
| 16 | #include <cstdint> | 17 | #include <cstdint> |
| 17 | #include <vector> | 18 | #include <vector> |
| 18 | 19 | ||
| ... | @@ -29,16 +30,14 @@ void writeResult(); | ... | @@ -29,16 +30,14 @@ void writeResult(); |
| 29 | // non-overlapping file offsets and RVAs. | 30 | // non-overlapping file offsets and RVAs. |
| 30 | class OutputSection { | 31 | class OutputSection { |
| 31 | public: | 32 | public: |
| 32 | OutputSection(llvm::StringRef N) : Name(N), Header({}) {} | 33 | OutputSection(llvm::StringRef N, uint32_t Chars) : Name(N) { |
| 33 | void setRVA(uint64_t); | 34 | Header.Characteristics = Chars; |
| 34 | void setFileOffset(uint64_t); | 35 | } |
| 35 | void addChunk(Chunk *C); | 36 | void addChunk(Chunk *C); |
| 36 | llvm::StringRef getName() { return Name; } | 37 | void merge(OutputSection *Other); |
| 37 | ArrayRef<Chunk *> getChunks() { return Chunks; } | 38 | ArrayRef<Chunk *> getChunks() { return Chunks; } |
| 38 | void addPermissions(uint32_t C); | 39 | void addPermissions(uint32_t C); |
| 39 | void setPermissions(uint32_t C); | 40 | void setPermissions(uint32_t C); |
| 40 | uint32_t getPermissions() { return Header.Characteristics & PermMask; } | ||
| 41 | uint32_t getCharacteristics() { return Header.Characteristics; } | ||
| 42 | uint64_t getRVA() { return Header.VirtualAddress; } | 41 | uint64_t getRVA() { return Header.VirtualAddress; } |
| 43 | uint64_t getFileOff() { return Header.PointerToRawData; } | 42 | uint64_t getFileOff() { return Header.PointerToRawData; } |
| 44 | void writeHeaderTo(uint8_t *Buf); | 43 | void writeHeaderTo(uint8_t *Buf); |
| ... | @@ -60,9 +59,10 @@ public: | ... | @@ -60,9 +59,10 @@ public: |
| 60 | // N.B. The section index is one based. | 59 | // N.B. The section index is one based. |
| 61 | uint32_t SectionIndex = 0; | 60 | uint32_t SectionIndex = 0; |
| 62 | 61 | ||
| 63 | private: | ||
| 64 | llvm::StringRef Name; | 62 | llvm::StringRef Name; |
| 65 | llvm::object::coff_section Header; | 63 | llvm::object::coff_section Header = {}; |
| 64 | |||
| 65 | private: | ||
| 66 | uint32_t StringTableOff = 0; | 66 | uint32_t StringTableOff = 0; |
| 67 | std::vector<Chunk *> Chunks; | 67 | std::vector<Chunk *> Chunks; |
| 68 | }; | 68 | }; |
deps/lld/Common/Args.cpp+11-7| ... | @@ -18,13 +18,17 @@ using namespace llvm; | ... | @@ -18,13 +18,17 @@ using namespace llvm; |
| 18 | using namespace lld; | 18 | using namespace lld; |
| 19 | 19 | ||
| 20 | int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) { | 20 | int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) { |
| 21 | int V = Default; | 21 | auto *A = Args.getLastArg(Key); |
| 22 | if (auto *Arg = Args.getLastArg(Key)) { | 22 | if (!A) |
| 23 | StringRef S = Arg->getValue(); | 23 | return Default; |
| 24 | if (!to_integer(S, V, 10)) | 24 | |
| 25 | error(Arg->getSpelling() + ": number expected, but got '" + S + "'"); | 25 | int V; |
| 26 | } | 26 | if (to_integer(A->getValue(), V, 10)) |
| 27 | return V; | 27 | return V; |
| 28 | |||
| 29 | StringRef Spelling = Args.getArgString(A->getIndex()); | ||
| 30 | error(Spelling + ": number expected, but got '" + A->getValue() + "'"); | ||
| 31 | return 0; | ||
| 28 | } | 32 | } |
| 29 | 33 | ||
| 30 | std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) { | 34 | std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) { |
deps/lld/Common/CMakeLists.txt+1| ... | @@ -10,6 +10,7 @@ add_lld_library(lldCommon | ... | @@ -10,6 +10,7 @@ add_lld_library(lldCommon |
| 10 | Strings.cpp | 10 | Strings.cpp |
| 11 | TargetOptionsCommandFlags.cpp | 11 | TargetOptionsCommandFlags.cpp |
| 12 | Threads.cpp | 12 | Threads.cpp |
| 13 | Timer.cpp | ||
| 13 | Version.cpp | 14 | Version.cpp |
| 14 | 15 | ||
| 15 | ADDITIONAL_HEADER_DIRS | 16 | ADDITIONAL_HEADER_DIRS |
deps/lld/Common/ErrorHandler.cpp+26-1| ... | @@ -12,7 +12,8 @@ | ... | @@ -12,7 +12,8 @@ |
| 12 | #include "lld/Common/Threads.h" | 12 | #include "lld/Common/Threads.h" |
| 13 | 13 | ||
| 14 | #include "llvm/ADT/Twine.h" | 14 | #include "llvm/ADT/Twine.h" |
| 15 | #include "llvm/Support/Error.h" | 15 | #include "llvm/IR/DiagnosticInfo.h" |
| 16 | #include "llvm/IR/DiagnosticPrinter.h" | ||
| 16 | #include "llvm/Support/ManagedStatic.h" | 17 | #include "llvm/Support/ManagedStatic.h" |
| 17 | #include "llvm/Support/raw_ostream.h" | 18 | #include "llvm/Support/raw_ostream.h" |
| 18 | #include <mutex> | 19 | #include <mutex> |
| ... | @@ -59,6 +60,30 @@ void lld::exitLld(int Val) { | ... | @@ -59,6 +60,30 @@ void lld::exitLld(int Val) { |
| 59 | _exit(Val); | 60 | _exit(Val); |
| 60 | } | 61 | } |
| 61 | 62 | ||
| 63 | void lld::diagnosticHandler(const DiagnosticInfo &DI) { | ||
| 64 | SmallString<128> S; | ||
| 65 | raw_svector_ostream OS(S); | ||
| 66 | DiagnosticPrinterRawOStream DP(OS); | ||
| 67 | DI.print(DP); | ||
| 68 | switch (DI.getSeverity()) { | ||
| 69 | case DS_Error: | ||
| 70 | error(S); | ||
| 71 | break; | ||
| 72 | case DS_Warning: | ||
| 73 | warn(S); | ||
| 74 | break; | ||
| 75 | case DS_Remark: | ||
| 76 | case DS_Note: | ||
| 77 | message(S); | ||
| 78 | break; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | void lld::checkError(Error E) { | ||
| 83 | handleAllErrors(std::move(E), | ||
| 84 | [&](ErrorInfoBase &EIB) { error(EIB.message()); }); | ||
| 85 | } | ||
| 86 | |||
| 62 | void ErrorHandler::print(StringRef S, raw_ostream::Colors C) { | 87 | void ErrorHandler::print(StringRef S, raw_ostream::Colors C) { |
| 63 | *ErrorOS << LogName << ": "; | 88 | *ErrorOS << LogName << ": "; |
| 64 | if (ColorDiagnostics) { | 89 | if (ColorDiagnostics) { |
deps/lld/Common/Strings.cpp+77| ... | @@ -8,7 +8,21 @@ | ... | @@ -8,7 +8,21 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | ||
| 10 | #include "lld/Common/Strings.h" | 10 | #include "lld/Common/Strings.h" |
| 11 | #include "lld/Common/ErrorHandler.h" | ||
| 12 | #include "lld/Common/LLVM.h" | ||
| 11 | #include "llvm/Demangle/Demangle.h" | 13 | #include "llvm/Demangle/Demangle.h" |
| 14 | #include "llvm/Support/GlobPattern.h" | ||
| 15 | #include <algorithm> | ||
| 16 | #include <mutex> | ||
| 17 | #include <vector> | ||
| 18 | |||
| 19 | #if defined(_MSC_VER) | ||
| 20 | #include <Windows.h> | ||
| 21 | |||
| 22 | // DbgHelp.h must be included after Windows.h. | ||
| 23 | #include <DbgHelp.h> | ||
| 24 | #pragma comment(lib, "dbghelp.lib") | ||
| 25 | #endif | ||
| 12 | 26 | ||
| 13 | using namespace llvm; | 27 | using namespace llvm; |
| 14 | using namespace lld; | 28 | using namespace lld; |
| ... | @@ -30,3 +44,66 @@ Optional<std::string> lld::demangleItanium(StringRef Name) { | ... | @@ -30,3 +44,66 @@ Optional<std::string> lld::demangleItanium(StringRef Name) { |
| 30 | free(Buf); | 44 | free(Buf); |
| 31 | return S; | 45 | return S; |
| 32 | } | 46 | } |
| 47 | |||
| 48 | Optional<std::string> lld::demangleMSVC(StringRef S) { | ||
| 49 | #if defined(_MSC_VER) | ||
| 50 | // UnDecorateSymbolName is not thread-safe, so we need a mutex. | ||
| 51 | static std::mutex Mu; | ||
| 52 | std::lock_guard<std::mutex> Lock(Mu); | ||
| 53 | |||
| 54 | char Buf[4096]; | ||
| 55 | if (S.startswith("?")) | ||
| 56 | if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0)) | ||
| 57 | return std::string(Buf, Len); | ||
| 58 | #endif | ||
| 59 | return None; | ||
| 60 | } | ||
| 61 | |||
| 62 | StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) { | ||
| 63 | for (StringRef S : Pat) { | ||
| 64 | Expected<GlobPattern> Pat = GlobPattern::create(S); | ||
| 65 | if (!Pat) | ||
| 66 | error(toString(Pat.takeError())); | ||
| 67 | else | ||
| 68 | Patterns.push_back(*Pat); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | bool StringMatcher::match(StringRef S) const { | ||
| 73 | for (const GlobPattern &Pat : Patterns) | ||
| 74 | if (Pat.match(S)) | ||
| 75 | return true; | ||
| 76 | return false; | ||
| 77 | } | ||
| 78 | |||
| 79 | // Converts a hex string (e.g. "deadbeef") to a vector. | ||
| 80 | std::vector<uint8_t> lld::parseHex(StringRef S) { | ||
| 81 | std::vector<uint8_t> Hex; | ||
| 82 | while (!S.empty()) { | ||
| 83 | StringRef B = S.substr(0, 2); | ||
| 84 | S = S.substr(2); | ||
| 85 | uint8_t H; | ||
| 86 | if (!to_integer(B, H, 16)) { | ||
| 87 | error("not a hexadecimal value: " + B); | ||
| 88 | return {}; | ||
| 89 | } | ||
| 90 | Hex.push_back(H); | ||
| 91 | } | ||
| 92 | return Hex; | ||
| 93 | } | ||
| 94 | |||
| 95 | // Returns true if S is valid as a C language identifier. | ||
| 96 | bool lld::isValidCIdentifier(StringRef S) { | ||
| 97 | return !S.empty() && (isAlpha(S[0]) || S[0] == '_') && | ||
| 98 | std::all_of(S.begin() + 1, S.end(), | ||
| 99 | [](char C) { return C == '_' || isAlnum(C); }); | ||
| 100 | } | ||
| 101 | |||
| 102 | // Write the contents of the a buffer to a file | ||
| 103 | void lld::saveBuffer(StringRef Buffer, const Twine &Path) { | ||
| 104 | std::error_code EC; | ||
| 105 | raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); | ||
| 106 | if (EC) | ||
| 107 | error("cannot create " + Path + ": " + EC.message()); | ||
| 108 | OS << Buffer; | ||
| 109 | } |
deps/lld/Common/TargetOptionsCommandFlags.cpp+5-3| ... | @@ -8,7 +8,7 @@ | ... | @@ -8,7 +8,7 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | // | 9 | // |
| 10 | // This file exists as a place for global variables defined in LLVM's | 10 | // This file exists as a place for global variables defined in LLVM's |
| 11 | // CodeGen/CommandFlags.def. By putting the resulting object file in | 11 | // CodeGen/CommandFlags.inc. By putting the resulting object file in |
| 12 | // an archive and linking with it, the definitions will automatically be | 12 | // an archive and linking with it, the definitions will automatically be |
| 13 | // included when needed and skipped when already present. | 13 | // included when needed and skipped when already present. |
| 14 | // | 14 | // |
| ... | @@ -16,12 +16,12 @@ | ... | @@ -16,12 +16,12 @@ |
| 16 | 16 | ||
| 17 | #include "lld/Common/TargetOptionsCommandFlags.h" | 17 | #include "lld/Common/TargetOptionsCommandFlags.h" |
| 18 | 18 | ||
| 19 | #include "llvm/CodeGen/CommandFlags.def" | 19 | #include "llvm/CodeGen/CommandFlags.inc" |
| 20 | #include "llvm/Target/TargetOptions.h" | 20 | #include "llvm/Target/TargetOptions.h" |
| 21 | 21 | ||
| 22 | // Define an externally visible version of | 22 | // Define an externally visible version of |
| 23 | // InitTargetOptionsFromCodeGenFlags, so that its functionality can be | 23 | // InitTargetOptionsFromCodeGenFlags, so that its functionality can be |
| 24 | // used without having to include llvm/CodeGen/CommandFlags.def, which | 24 | // used without having to include llvm/CodeGen/CommandFlags.inc, which |
| 25 | // would lead to multiple definitions of the command line flags. | 25 | // would lead to multiple definitions of the command line flags. |
| 26 | llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() { | 26 | llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() { |
| 27 | return ::InitTargetOptionsFromCodeGenFlags(); | 27 | return ::InitTargetOptionsFromCodeGenFlags(); |
| ... | @@ -30,3 +30,5 @@ llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() { | ... | @@ -30,3 +30,5 @@ llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() { |
| 30 | llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() { | 30 | llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() { |
| 31 | return getCodeModel(); | 31 | return getCodeModel(); |
| 32 | } | 32 | } |
| 33 | |||
| 34 | std::string lld::GetCPUStr() { return ::getCPUStr(); } |
deps/lld/Common/Timer.cpp created+80| ... | @@ -0,0 +1,80 @@ | ||
| 1 | //===- Timer.cpp ----------------------------------------------------------===// | ||
| 2 | // | ||
| 3 | // The LLVM Linker | ||
| 4 | // | ||
| 5 | // This file is distributed under the University of Illinois Open Source | ||
| 6 | // License. See LICENSE.TXT for details. | ||
| 7 | // | ||
| 8 | //===----------------------------------------------------------------------===// | ||
| 9 | |||
| 10 | #include "lld/Common/Timer.h" | ||
| 11 | #include "lld/Common/ErrorHandler.h" | ||
| 12 | #include "llvm/Support/Format.h" | ||
| 13 | |||
| 14 | using namespace lld; | ||
| 15 | using namespace llvm; | ||
| 16 | |||
| 17 | ScopedTimer::ScopedTimer(Timer &T) : T(&T) { T.start(); } | ||
| 18 | |||
| 19 | void ScopedTimer::stop() { | ||
| 20 | if (!T) | ||
| 21 | return; | ||
| 22 | T->stop(); | ||
| 23 | T = nullptr; | ||
| 24 | } | ||
| 25 | |||
| 26 | ScopedTimer::~ScopedTimer() { stop(); } | ||
| 27 | |||
| 28 | Timer::Timer(llvm::StringRef Name) : Name(Name), Parent(nullptr) {} | ||
| 29 | Timer::Timer(llvm::StringRef Name, Timer &Parent) | ||
| 30 | : Name(Name), Parent(&Parent) {} | ||
| 31 | |||
| 32 | void Timer::start() { | ||
| 33 | if (Parent && Total.count() == 0) | ||
| 34 | Parent->Children.push_back(this); | ||
| 35 | StartTime = std::chrono::high_resolution_clock::now(); | ||
| 36 | } | ||
| 37 | |||
| 38 | void Timer::stop() { | ||
| 39 | Total += (std::chrono::high_resolution_clock::now() - StartTime); | ||
| 40 | } | ||
| 41 | |||
| 42 | Timer &Timer::root() { | ||
| 43 | static Timer RootTimer("Total Link Time"); | ||
| 44 | return RootTimer; | ||
| 45 | } | ||
| 46 | |||
| 47 | void Timer::print() { | ||
| 48 | double TotalDuration = static_cast<double>(root().millis()); | ||
| 49 | |||
| 50 | // We want to print the grand total under all the intermediate phases, so we | ||
| 51 | // print all children first, then print the total under that. | ||
| 52 | for (const auto &Child : Children) | ||
| 53 | Child->print(1, TotalDuration); | ||
| 54 | |||
| 55 | message(std::string(49, '-')); | ||
| 56 | |||
| 57 | root().print(0, root().millis(), false); | ||
| 58 | } | ||
| 59 | |||
| 60 | double Timer::millis() const { | ||
| 61 | return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>( | ||
| 62 | Total) | ||
| 63 | .count(); | ||
| 64 | } | ||
| 65 | |||
| 66 | void Timer::print(int Depth, double TotalDuration, bool Recurse) const { | ||
| 67 | double P = 100.0 * millis() / TotalDuration; | ||
| 68 | |||
| 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); | ||
| 73 | |||
| 74 | message(Str); | ||
| 75 | |||
| 76 | if (Recurse) { | ||
| 77 | for (const auto &Child : Children) | ||
| 78 | Child->print(Depth + 1, TotalDuration); | ||
| 79 | } | ||
| 80 | } | ||
deps/lld/ELF/AArch64ErrataFix.cpp+6-8| ... | @@ -34,12 +34,11 @@ | ... | @@ -34,12 +34,11 @@ |
| 34 | #include "LinkerScript.h" | 34 | #include "LinkerScript.h" |
| 35 | #include "OutputSections.h" | 35 | #include "OutputSections.h" |
| 36 | #include "Relocations.h" | 36 | #include "Relocations.h" |
| 37 | #include "Strings.h" | ||
| 38 | #include "Symbols.h" | 37 | #include "Symbols.h" |
| 39 | #include "SyntheticSections.h" | 38 | #include "SyntheticSections.h" |
| 40 | #include "Target.h" | 39 | #include "Target.h" |
| 41 | #include "lld/Common/Memory.h" | 40 | #include "lld/Common/Memory.h" |
| 42 | 41 | #include "lld/Common/Strings.h" | |
| 43 | #include "llvm/Support/Endian.h" | 42 | #include "llvm/Support/Endian.h" |
| 44 | #include "llvm/Support/raw_ostream.h" | 43 | #include "llvm/Support/raw_ostream.h" |
| 45 | #include <algorithm> | 44 | #include <algorithm> |
| ... | @@ -342,7 +341,7 @@ static bool is843419ErratumSequence(uint32_t Instr1, uint32_t Instr2, | ... | @@ -342,7 +341,7 @@ static bool is843419ErratumSequence(uint32_t Instr1, uint32_t Instr2, |
| 342 | // patch or 0 if no patch required. | 341 | // patch or 0 if no patch required. |
| 343 | static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off, | 342 | static uint64_t scanCortexA53Errata843419(InputSection *IS, uint64_t &Off, |
| 344 | uint64_t Limit) { | 343 | uint64_t Limit) { |
| 345 | uint64_t ISAddr = IS->getParent()->Addr + IS->OutSecOff; | 344 | uint64_t ISAddr = IS->getVA(0); |
| 346 | 345 | ||
| 347 | // Advance Off so that (ISAddr + Off) modulo 0x1000 is at least 0xff8. | 346 | // Advance Off so that (ISAddr + Off) modulo 0x1000 is at least 0xff8. |
| 348 | uint64_t InitialPageOff = (ISAddr + Off) & 0xfff; | 347 | uint64_t InitialPageOff = (ISAddr + Off) & 0xfff; |
| ... | @@ -406,7 +405,7 @@ lld::elf::Patch843419Section::Patch843419Section(InputSection *P, uint64_t Off) | ... | @@ -406,7 +405,7 @@ lld::elf::Patch843419Section::Patch843419Section(InputSection *P, uint64_t Off) |
| 406 | } | 405 | } |
| 407 | 406 | ||
| 408 | uint64_t lld::elf::Patch843419Section::getLDSTAddr() const { | 407 | uint64_t lld::elf::Patch843419Section::getLDSTAddr() const { |
| 409 | return Patchee->getParent()->Addr + Patchee->OutSecOff + PatcheeOffset; | 408 | return Patchee->getVA(PatcheeOffset); |
| 410 | } | 409 | } |
| 411 | 410 | ||
| 412 | void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) { | 411 | void lld::elf::Patch843419Section::writeTo(uint8_t *Buf) { |
| ... | @@ -555,9 +554,8 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset, | ... | @@ -555,9 +554,8 @@ static void implementPatch(uint64_t AdrpAddr, uint64_t PatcheeOffset, |
| 555 | if (RelIt != IS->Relocations.end() && RelIt->Type == R_AARCH64_JUMP26) | 554 | if (RelIt != IS->Relocations.end() && RelIt->Type == R_AARCH64_JUMP26) |
| 556 | return; | 555 | return; |
| 557 | 556 | ||
| 558 | if (Config->Verbose) | 557 | log("detected cortex-a53-843419 erratum sequence starting at " + |
| 559 | message("detected cortex-a53-843419 erratum sequence starting at " + | 558 | utohexstr(AdrpAddr) + " in unpatched output."); |
| 560 | utohexstr(AdrpAddr) + " in unpatched output."); | ||
| 561 | 559 | ||
| 562 | auto *PS = make<Patch843419Section>(IS, PatcheeOffset); | 560 | auto *PS = make<Patch843419Section>(IS, PatcheeOffset); |
| 563 | Patches.push_back(PS); | 561 | Patches.push_back(PS); |
| ... | @@ -603,7 +601,7 @@ AArch64Err843419Patcher::patchInputSectionDescription( | ... | @@ -603,7 +601,7 @@ AArch64Err843419Patcher::patchInputSectionDescription( |
| 603 | (DataSym == MapSyms.end()) ? IS->Data.size() : (*DataSym)->Value; | 601 | (DataSym == MapSyms.end()) ? IS->Data.size() : (*DataSym)->Value; |
| 604 | 602 | ||
| 605 | while (Off < Limit) { | 603 | while (Off < Limit) { |
| 606 | uint64_t StartAddr = IS->getParent()->Addr + IS->OutSecOff + Off; | 604 | uint64_t StartAddr = IS->getVA(Off); |
| 607 | if (uint64_t PatcheeOffset = scanCortexA53Errata843419(IS, Off, Limit)) | 605 | if (uint64_t PatcheeOffset = scanCortexA53Errata843419(IS, Off, Limit)) |
| 608 | implementPatch(StartAddr, PatcheeOffset, IS, Patches); | 606 | implementPatch(StartAddr, PatcheeOffset, IS, Patches); |
| 609 | } | 607 | } |
deps/lld/ELF/AArch64ErrataFix.h-1| ... | @@ -11,7 +11,6 @@ | ... | @@ -11,7 +11,6 @@ |
| 11 | #define LLD_ELF_AARCH64ERRATAFIX_H | 11 | #define LLD_ELF_AARCH64ERRATAFIX_H |
| 12 | 12 | ||
| 13 | #include "lld/Common/LLVM.h" | 13 | #include "lld/Common/LLVM.h" |
| 14 | |||
| 15 | #include <map> | 14 | #include <map> |
| 16 | #include <vector> | 15 | #include <vector> |
| 17 | 16 |
deps/lld/ELF/Arch/AArch64.cpp+33-24| ... | @@ -34,7 +34,7 @@ public: | ... | @@ -34,7 +34,7 @@ public: |
| 34 | AArch64(); | 34 | AArch64(); |
| 35 | RelExpr getRelExpr(RelType Type, const Symbol &S, | 35 | RelExpr getRelExpr(RelType Type, const Symbol &S, |
| 36 | const uint8_t *Loc) const override; | 36 | const uint8_t *Loc) const override; |
| 37 | bool isPicRel(RelType Type) const override; | 37 | RelType getDynRel(RelType Type) const override; |
| 38 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | 38 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; |
| 39 | void writePltHeader(uint8_t *Buf) const override; | 39 | void writePltHeader(uint8_t *Buf) const override; |
| 40 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | 40 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, |
| ... | @@ -89,6 +89,11 @@ RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -89,6 +89,11 @@ RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S, |
| 89 | return R_TLSDESC_CALL; | 89 | return R_TLSDESC_CALL; |
| 90 | case R_AARCH64_TLSLE_ADD_TPREL_HI12: | 90 | case R_AARCH64_TLSLE_ADD_TPREL_HI12: |
| 91 | case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: | 91 | case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: |
| 92 | case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: | ||
| 93 | case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: | ||
| 94 | case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: | ||
| 95 | case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: | ||
| 96 | case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: | ||
| 92 | return R_TLS; | 97 | return R_TLS; |
| 93 | case R_AARCH64_CALL26: | 98 | case R_AARCH64_CALL26: |
| 94 | case R_AARCH64_CONDBR19: | 99 | case R_AARCH64_CONDBR19: |
| ... | @@ -144,8 +149,10 @@ bool AArch64::usesOnlyLowPageBits(RelType Type) const { | ... | @@ -144,8 +149,10 @@ bool AArch64::usesOnlyLowPageBits(RelType Type) const { |
| 144 | } | 149 | } |
| 145 | } | 150 | } |
| 146 | 151 | ||
| 147 | bool AArch64::isPicRel(RelType Type) const { | 152 | RelType AArch64::getDynRel(RelType Type) const { |
| 148 | return Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64; | 153 | if (Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64) |
| 154 | return Type; | ||
| 155 | return R_AARCH64_NONE; | ||
| 149 | } | 156 | } |
| 150 | 157 | ||
| 151 | void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const { | 158 | void AArch64::writeGotPlt(uint8_t *Buf, const Symbol &) const { |
| ... | @@ -240,12 +247,12 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -240,12 +247,12 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 240 | switch (Type) { | 247 | switch (Type) { |
| 241 | case R_AARCH64_ABS16: | 248 | case R_AARCH64_ABS16: |
| 242 | case R_AARCH64_PREL16: | 249 | case R_AARCH64_PREL16: |
| 243 | checkIntUInt<16>(Loc, Val, Type); | 250 | checkIntUInt(Loc, Val, 16, Type); |
| 244 | write16le(Loc, Val); | 251 | write16le(Loc, Val); |
| 245 | break; | 252 | break; |
| 246 | case R_AARCH64_ABS32: | 253 | case R_AARCH64_ABS32: |
| 247 | case R_AARCH64_PREL32: | 254 | case R_AARCH64_PREL32: |
| 248 | checkIntUInt<32>(Loc, Val, Type); | 255 | checkIntUInt(Loc, Val, 32, Type); |
| 249 | write32le(Loc, Val); | 256 | write32le(Loc, Val); |
| 250 | break; | 257 | break; |
| 251 | case R_AARCH64_ABS64: | 258 | case R_AARCH64_ABS64: |
| ... | @@ -260,11 +267,11 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -260,11 +267,11 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 260 | case R_AARCH64_ADR_PREL_PG_HI21: | 267 | case R_AARCH64_ADR_PREL_PG_HI21: |
| 261 | case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: | 268 | case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: |
| 262 | case R_AARCH64_TLSDESC_ADR_PAGE21: | 269 | case R_AARCH64_TLSDESC_ADR_PAGE21: |
| 263 | checkInt<33>(Loc, Val, Type); | 270 | checkInt(Loc, Val, 33, Type); |
| 264 | write32AArch64Addr(Loc, Val >> 12); | 271 | write32AArch64Addr(Loc, Val >> 12); |
| 265 | break; | 272 | break; |
| 266 | case R_AARCH64_ADR_PREL_LO21: | 273 | case R_AARCH64_ADR_PREL_LO21: |
| 267 | checkInt<21>(Loc, Val, Type); | 274 | checkInt(Loc, Val, 21, Type); |
| 268 | write32AArch64Addr(Loc, Val); | 275 | write32AArch64Addr(Loc, Val); |
| 269 | break; | 276 | break; |
| 270 | case R_AARCH64_JUMP26: | 277 | case R_AARCH64_JUMP26: |
| ... | @@ -278,38 +285,40 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -278,38 +285,40 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 278 | write32le(Loc, 0x14000000); | 285 | write32le(Loc, 0x14000000); |
| 279 | LLVM_FALLTHROUGH; | 286 | LLVM_FALLTHROUGH; |
| 280 | case R_AARCH64_CALL26: | 287 | case R_AARCH64_CALL26: |
| 281 | checkInt<28>(Loc, Val, Type); | 288 | checkInt(Loc, Val, 28, Type); |
| 282 | or32le(Loc, (Val & 0x0FFFFFFC) >> 2); | 289 | or32le(Loc, (Val & 0x0FFFFFFC) >> 2); |
| 283 | break; | 290 | break; |
| 284 | case R_AARCH64_CONDBR19: | 291 | case R_AARCH64_CONDBR19: |
| 285 | case R_AARCH64_LD_PREL_LO19: | 292 | case R_AARCH64_LD_PREL_LO19: |
| 286 | checkAlignment<4>(Loc, Val, Type); | 293 | checkAlignment(Loc, Val, 4, Type); |
| 287 | checkInt<21>(Loc, Val, Type); | 294 | checkInt(Loc, Val, 21, Type); |
| 288 | or32le(Loc, (Val & 0x1FFFFC) << 3); | 295 | or32le(Loc, (Val & 0x1FFFFC) << 3); |
| 289 | break; | 296 | break; |
| 290 | case R_AARCH64_LD64_GOT_LO12_NC: | ||
| 291 | case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: | ||
| 292 | case R_AARCH64_TLSDESC_LD64_LO12: | ||
| 293 | checkAlignment<8>(Loc, Val, Type); | ||
| 294 | or32le(Loc, (Val & 0xFF8) << 7); | ||
| 295 | break; | ||
| 296 | case R_AARCH64_LDST8_ABS_LO12_NC: | 297 | case R_AARCH64_LDST8_ABS_LO12_NC: |
| 298 | case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: | ||
| 297 | or32AArch64Imm(Loc, getBits(Val, 0, 11)); | 299 | or32AArch64Imm(Loc, getBits(Val, 0, 11)); |
| 298 | break; | 300 | break; |
| 299 | case R_AARCH64_LDST16_ABS_LO12_NC: | 301 | case R_AARCH64_LDST16_ABS_LO12_NC: |
| 300 | checkAlignment<2>(Loc, Val, Type); | 302 | case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: |
| 303 | checkAlignment(Loc, Val, 2, Type); | ||
| 301 | or32AArch64Imm(Loc, getBits(Val, 1, 11)); | 304 | or32AArch64Imm(Loc, getBits(Val, 1, 11)); |
| 302 | break; | 305 | break; |
| 303 | case R_AARCH64_LDST32_ABS_LO12_NC: | 306 | case R_AARCH64_LDST32_ABS_LO12_NC: |
| 304 | checkAlignment<4>(Loc, Val, Type); | 307 | case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: |
| 308 | checkAlignment(Loc, Val, 4, Type); | ||
| 305 | or32AArch64Imm(Loc, getBits(Val, 2, 11)); | 309 | or32AArch64Imm(Loc, getBits(Val, 2, 11)); |
| 306 | break; | 310 | break; |
| 307 | case R_AARCH64_LDST64_ABS_LO12_NC: | 311 | case R_AARCH64_LDST64_ABS_LO12_NC: |
| 308 | checkAlignment<8>(Loc, Val, Type); | 312 | case R_AARCH64_LD64_GOT_LO12_NC: |
| 313 | case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: | ||
| 314 | case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: | ||
| 315 | case R_AARCH64_TLSDESC_LD64_LO12: | ||
| 316 | checkAlignment(Loc, Val, 8, Type); | ||
| 309 | or32AArch64Imm(Loc, getBits(Val, 3, 11)); | 317 | or32AArch64Imm(Loc, getBits(Val, 3, 11)); |
| 310 | break; | 318 | break; |
| 311 | case R_AARCH64_LDST128_ABS_LO12_NC: | 319 | case R_AARCH64_LDST128_ABS_LO12_NC: |
| 312 | checkAlignment<16>(Loc, Val, Type); | 320 | case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: |
| 321 | checkAlignment(Loc, Val, 16, Type); | ||
| 313 | or32AArch64Imm(Loc, getBits(Val, 4, 11)); | 322 | or32AArch64Imm(Loc, getBits(Val, 4, 11)); |
| 314 | break; | 323 | break; |
| 315 | case R_AARCH64_MOVW_UABS_G0_NC: | 324 | case R_AARCH64_MOVW_UABS_G0_NC: |
| ... | @@ -325,11 +334,11 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -325,11 +334,11 @@ void AArch64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 325 | or32le(Loc, (Val & 0xFFFF000000000000) >> 43); | 334 | or32le(Loc, (Val & 0xFFFF000000000000) >> 43); |
| 326 | break; | 335 | break; |
| 327 | case R_AARCH64_TSTBR14: | 336 | case R_AARCH64_TSTBR14: |
| 328 | checkInt<16>(Loc, Val, Type); | 337 | checkInt(Loc, Val, 16, Type); |
| 329 | or32le(Loc, (Val & 0xFFFC) << 3); | 338 | or32le(Loc, (Val & 0xFFFC) << 3); |
| 330 | break; | 339 | break; |
| 331 | case R_AARCH64_TLSLE_ADD_TPREL_HI12: | 340 | case R_AARCH64_TLSLE_ADD_TPREL_HI12: |
| 332 | checkInt<24>(Loc, Val, Type); | 341 | checkInt(Loc, Val, 24, Type); |
| 333 | or32AArch64Imm(Loc, Val >> 12); | 342 | or32AArch64Imm(Loc, Val >> 12); |
| 334 | break; | 343 | break; |
| 335 | case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: | 344 | case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: |
| ... | @@ -353,7 +362,7 @@ void AArch64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -353,7 +362,7 @@ void AArch64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 353 | // movk x0, #0x10 | 362 | // movk x0, #0x10 |
| 354 | // nop | 363 | // nop |
| 355 | // nop | 364 | // nop |
| 356 | checkUInt<32>(Loc, Val, Type); | 365 | checkUInt(Loc, Val, 32, Type); |
| 357 | 366 | ||
| 358 | switch (Type) { | 367 | switch (Type) { |
| 359 | case R_AARCH64_TLSDESC_ADD_LO12: | 368 | case R_AARCH64_TLSDESC_ADD_LO12: |
| ... | @@ -403,7 +412,7 @@ void AArch64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -403,7 +412,7 @@ void AArch64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 403 | } | 412 | } |
| 404 | 413 | ||
| 405 | void AArch64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | 414 | void AArch64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 406 | checkUInt<32>(Loc, Val, Type); | 415 | checkUInt(Loc, Val, 32, Type); |
| 407 | 416 | ||
| 408 | if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) { | 417 | if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) { |
| 409 | // Generate MOVZ. | 418 | // Generate MOVZ. |
deps/lld/ELF/Arch/AMDGPU.cpp+2| ... | @@ -66,6 +66,7 @@ void AMDGPU::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -66,6 +66,7 @@ void AMDGPU::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 66 | write32le(Loc, Val); | 66 | write32le(Loc, Val); |
| 67 | break; | 67 | break; |
| 68 | case R_AMDGPU_ABS64: | 68 | case R_AMDGPU_ABS64: |
| 69 | case R_AMDGPU_REL64: | ||
| 69 | write64le(Loc, Val); | 70 | write64le(Loc, Val); |
| 70 | break; | 71 | break; |
| 71 | case R_AMDGPU_GOTPCREL32_HI: | 72 | case R_AMDGPU_GOTPCREL32_HI: |
| ... | @@ -86,6 +87,7 @@ RelExpr AMDGPU::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -86,6 +87,7 @@ RelExpr AMDGPU::getRelExpr(RelType Type, const Symbol &S, |
| 86 | case R_AMDGPU_REL32: | 87 | case R_AMDGPU_REL32: |
| 87 | case R_AMDGPU_REL32_LO: | 88 | case R_AMDGPU_REL32_LO: |
| 88 | case R_AMDGPU_REL32_HI: | 89 | case R_AMDGPU_REL32_HI: |
| 90 | case R_AMDGPU_REL64: | ||
| 89 | return R_PC; | 91 | return R_PC; |
| 90 | case R_AMDGPU_GOTPCREL: | 92 | case R_AMDGPU_GOTPCREL: |
| 91 | case R_AMDGPU_GOTPCREL32_LO: | 93 | case R_AMDGPU_GOTPCREL32_LO: |
deps/lld/ELF/Arch/ARM.cpp+21-20| ... | @@ -29,7 +29,6 @@ public: | ... | @@ -29,7 +29,6 @@ public: |
| 29 | uint32_t calcEFlags() const override; | 29 | uint32_t calcEFlags() const override; |
| 30 | RelExpr getRelExpr(RelType Type, const Symbol &S, | 30 | RelExpr getRelExpr(RelType Type, const Symbol &S, |
| 31 | const uint8_t *Loc) const override; | 31 | const uint8_t *Loc) const override; |
| 32 | bool isPicRel(RelType Type) const override; | ||
| 33 | RelType getDynRel(RelType Type) const override; | 32 | RelType getDynRel(RelType Type) const override; |
| 34 | int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; | 33 | int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; |
| 35 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | 34 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; |
| ... | @@ -55,6 +54,7 @@ ARM::ARM() { | ... | @@ -55,6 +54,7 @@ ARM::ARM() { |
| 55 | TlsGotRel = R_ARM_TLS_TPOFF32; | 54 | TlsGotRel = R_ARM_TLS_TPOFF32; |
| 56 | TlsModuleIndexRel = R_ARM_TLS_DTPMOD32; | 55 | TlsModuleIndexRel = R_ARM_TLS_DTPMOD32; |
| 57 | TlsOffsetRel = R_ARM_TLS_DTPOFF32; | 56 | TlsOffsetRel = R_ARM_TLS_DTPOFF32; |
| 57 | GotBaseSymInGotPlt = false; | ||
| 58 | GotEntrySize = 4; | 58 | GotEntrySize = 4; |
| 59 | GotPltEntrySize = 4; | 59 | GotPltEntrySize = 4; |
| 60 | PltEntrySize = 16; | 60 | PltEntrySize = 16; |
| ... | @@ -97,10 +97,19 @@ ARM::ARM() { | ... | @@ -97,10 +97,19 @@ ARM::ARM() { |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | uint32_t ARM::calcEFlags() const { | 99 | uint32_t ARM::calcEFlags() const { |
| 100 | // The ABIFloatType is used by loaders to detect the floating point calling | ||
| 101 | // convention. | ||
| 102 | uint32_t ABIFloatType = 0; | ||
| 103 | if (Config->ARMVFPArgs == ARMVFPArgKind::Base || | ||
| 104 | Config->ARMVFPArgs == ARMVFPArgKind::Default) | ||
| 105 | ABIFloatType = EF_ARM_ABI_FLOAT_SOFT; | ||
| 106 | else if (Config->ARMVFPArgs == ARMVFPArgKind::VFP) | ||
| 107 | ABIFloatType = EF_ARM_ABI_FLOAT_HARD; | ||
| 108 | |||
| 100 | // We don't currently use any features incompatible with EF_ARM_EABI_VER5, | 109 | // We don't currently use any features incompatible with EF_ARM_EABI_VER5, |
| 101 | // but we don't have any firm guarantees of conformance. Linux AArch64 | 110 | // but we don't have any firm guarantees of conformance. Linux AArch64 |
| 102 | // kernels (as of 2016) require an EABI version to be set. | 111 | // kernels (as of 2016) require an EABI version to be set. |
| 103 | return EF_ARM_EABI_VER5; | 112 | return EF_ARM_EABI_VER5 | ABIFloatType; |
| 104 | } | 113 | } |
| 105 | 114 | ||
| 106 | RelExpr ARM::getRelExpr(RelType Type, const Symbol &S, | 115 | RelExpr ARM::getRelExpr(RelType Type, const Symbol &S, |
| ... | @@ -161,18 +170,10 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -161,18 +170,10 @@ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S, |
| 161 | } | 170 | } |
| 162 | } | 171 | } |
| 163 | 172 | ||
| 164 | bool ARM::isPicRel(RelType Type) const { | ||
| 165 | return (Type == R_ARM_TARGET1 && !Config->Target1Rel) || | ||
| 166 | (Type == R_ARM_ABS32); | ||
| 167 | } | ||
| 168 | |||
| 169 | RelType ARM::getDynRel(RelType Type) const { | 173 | RelType ARM::getDynRel(RelType Type) const { |
| 170 | if (Type == R_ARM_TARGET1 && !Config->Target1Rel) | 174 | if ((Type == R_ARM_ABS32) || (Type == R_ARM_TARGET1 && !Config->Target1Rel)) |
| 171 | return R_ARM_ABS32; | 175 | return R_ARM_ABS32; |
| 172 | if (Type == R_ARM_ABS32) | 176 | return R_ARM_NONE; |
| 173 | return Type; | ||
| 174 | // Keep it going with a dummy value so that we can find more reloc errors. | ||
| 175 | return R_ARM_ABS32; | ||
| 176 | } | 177 | } |
| 177 | 178 | ||
| 178 | void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const { | 179 | void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const { |
| ... | @@ -392,7 +393,7 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -392,7 +393,7 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 392 | write32le(Loc, 1); | 393 | write32le(Loc, 1); |
| 393 | break; | 394 | break; |
| 394 | case R_ARM_PREL31: | 395 | case R_ARM_PREL31: |
| 395 | checkInt<31>(Loc, Val, Type); | 396 | checkInt(Loc, Val, 31, Type); |
| 396 | write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000)); | 397 | write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000)); |
| 397 | break; | 398 | break; |
| 398 | case R_ARM_CALL: | 399 | case R_ARM_CALL: |
| ... | @@ -401,7 +402,7 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -401,7 +402,7 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 401 | if (Val & 1) { | 402 | if (Val & 1) { |
| 402 | // If bit 0 of Val is 1 the target is Thumb, we must select a BLX. | 403 | // If bit 0 of Val is 1 the target is Thumb, we must select a BLX. |
| 403 | // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1' | 404 | // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1' |
| 404 | checkInt<26>(Loc, Val, Type); | 405 | checkInt(Loc, Val, 26, Type); |
| 405 | write32le(Loc, 0xfa000000 | // opcode | 406 | write32le(Loc, 0xfa000000 | // opcode |
| 406 | ((Val & 2) << 23) | // H | 407 | ((Val & 2) << 23) | // H |
| 407 | ((Val >> 2) & 0x00ffffff)); // imm24 | 408 | ((Val >> 2) & 0x00ffffff)); // imm24 |
| ... | @@ -416,16 +417,16 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -416,16 +417,16 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 416 | case R_ARM_JUMP24: | 417 | case R_ARM_JUMP24: |
| 417 | case R_ARM_PC24: | 418 | case R_ARM_PC24: |
| 418 | case R_ARM_PLT32: | 419 | case R_ARM_PLT32: |
| 419 | checkInt<26>(Loc, Val, Type); | 420 | checkInt(Loc, Val, 26, Type); |
| 420 | write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff)); | 421 | write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff)); |
| 421 | break; | 422 | break; |
| 422 | case R_ARM_THM_JUMP11: | 423 | case R_ARM_THM_JUMP11: |
| 423 | checkInt<12>(Loc, Val, Type); | 424 | checkInt(Loc, Val, 12, Type); |
| 424 | write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff)); | 425 | write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff)); |
| 425 | break; | 426 | break; |
| 426 | case R_ARM_THM_JUMP19: | 427 | case R_ARM_THM_JUMP19: |
| 427 | // Encoding T3: Val = S:J2:J1:imm6:imm11:0 | 428 | // Encoding T3: Val = S:J2:J1:imm6:imm11:0 |
| 428 | checkInt<21>(Loc, Val, Type); | 429 | checkInt(Loc, Val, 21, Type); |
| 429 | write16le(Loc, | 430 | write16le(Loc, |
| 430 | (read16le(Loc) & 0xfbc0) | // opcode cond | 431 | (read16le(Loc) & 0xfbc0) | // opcode cond |
| 431 | ((Val >> 10) & 0x0400) | // S | 432 | ((Val >> 10) & 0x0400) | // S |
| ... | @@ -451,7 +452,7 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -451,7 +452,7 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 451 | case R_ARM_THM_JUMP24: | 452 | case R_ARM_THM_JUMP24: |
| 452 | // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0 | 453 | // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0 |
| 453 | // FIXME: Use of I1 and I2 require v6T2ops | 454 | // FIXME: Use of I1 and I2 require v6T2ops |
| 454 | checkInt<25>(Loc, Val, Type); | 455 | checkInt(Loc, Val, 25, Type); |
| 455 | write16le(Loc, | 456 | write16le(Loc, |
| 456 | 0xf000 | // opcode | 457 | 0xf000 | // opcode |
| 457 | ((Val >> 14) & 0x0400) | // S | 458 | ((Val >> 14) & 0x0400) | // S |
| ... | @@ -469,14 +470,14 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -469,14 +470,14 @@ void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 469 | break; | 470 | break; |
| 470 | case R_ARM_MOVT_ABS: | 471 | case R_ARM_MOVT_ABS: |
| 471 | case R_ARM_MOVT_PREL: | 472 | case R_ARM_MOVT_PREL: |
| 472 | checkInt<32>(Loc, Val, Type); | 473 | checkInt(Loc, Val, 32, Type); |
| 473 | write32le(Loc, (read32le(Loc) & ~0x000f0fff) | | 474 | write32le(Loc, (read32le(Loc) & ~0x000f0fff) | |
| 474 | (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff)); | 475 | (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff)); |
| 475 | break; | 476 | break; |
| 476 | case R_ARM_THM_MOVT_ABS: | 477 | case R_ARM_THM_MOVT_ABS: |
| 477 | case R_ARM_THM_MOVT_PREL: | 478 | case R_ARM_THM_MOVT_PREL: |
| 478 | // Encoding T1: A = imm4:i:imm3:imm8 | 479 | // Encoding T1: A = imm4:i:imm3:imm8 |
| 479 | checkInt<32>(Loc, Val, Type); | 480 | checkInt(Loc, Val, 32, Type); |
| 480 | write16le(Loc, | 481 | write16le(Loc, |
| 481 | 0xf2c0 | // opcode | 482 | 0xf2c0 | // opcode |
| 482 | ((Val >> 17) & 0x0400) | // i | 483 | ((Val >> 17) & 0x0400) | // i |
deps/lld/ELF/Arch/Hexagon.cpp created+103| ... | @@ -0,0 +1,103 @@ | ||
| 1 | //===-- Hexagon.cpp -------------------------------------------------------===// | ||
| 2 | // | ||
| 3 | // The LLVM Linker | ||
| 4 | // | ||
| 5 | // This file is distributed under the University of Illinois Open Source | ||
| 6 | // License. See LICENSE.TXT for details. | ||
| 7 | // | ||
| 8 | //===----------------------------------------------------------------------===// | ||
| 9 | |||
| 10 | #include "InputFiles.h" | ||
| 11 | #include "Symbols.h" | ||
| 12 | #include "Target.h" | ||
| 13 | #include "lld/Common/ErrorHandler.h" | ||
| 14 | #include "llvm/BinaryFormat/ELF.h" | ||
| 15 | #include "llvm/Object/ELF.h" | ||
| 16 | #include "llvm/Support/Endian.h" | ||
| 17 | |||
| 18 | using namespace llvm; | ||
| 19 | using namespace llvm::object; | ||
| 20 | using namespace llvm::support::endian; | ||
| 21 | using namespace llvm::ELF; | ||
| 22 | using namespace lld; | ||
| 23 | using namespace lld::elf; | ||
| 24 | |||
| 25 | namespace { | ||
| 26 | class Hexagon final : public TargetInfo { | ||
| 27 | public: | ||
| 28 | uint32_t calcEFlags() const override; | ||
| 29 | RelExpr getRelExpr(RelType Type, const Symbol &S, | ||
| 30 | const uint8_t *Loc) const override; | ||
| 31 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | ||
| 32 | }; | ||
| 33 | } // namespace | ||
| 34 | |||
| 35 | // Support V60 only at the moment. | ||
| 36 | uint32_t Hexagon::calcEFlags() const { return 0x60; } | ||
| 37 | |||
| 38 | static uint32_t applyMask(uint32_t Mask, uint32_t Data) { | ||
| 39 | uint32_t Result = 0; | ||
| 40 | size_t Off = 0; | ||
| 41 | |||
| 42 | for (size_t Bit = 0; Bit != 32; ++Bit) { | ||
| 43 | uint32_t ValBit = (Data >> Off) & 1; | ||
| 44 | uint32_t MaskBit = (Mask >> Bit) & 1; | ||
| 45 | if (MaskBit) { | ||
| 46 | Result |= (ValBit << Bit); | ||
| 47 | ++Off; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | return Result; | ||
| 51 | } | ||
| 52 | |||
| 53 | RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S, | ||
| 54 | const uint8_t *Loc) const { | ||
| 55 | switch (Type) { | ||
| 56 | case R_HEX_B15_PCREL: | ||
| 57 | case R_HEX_B15_PCREL_X: | ||
| 58 | case R_HEX_B22_PCREL: | ||
| 59 | case R_HEX_B22_PCREL_X: | ||
| 60 | case R_HEX_B32_PCREL_X: | ||
| 61 | return R_PC; | ||
| 62 | default: | ||
| 63 | return R_ABS; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); } | ||
| 68 | |||
| 69 | void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ||
| 70 | switch (Type) { | ||
| 71 | case R_HEX_NONE: | ||
| 72 | break; | ||
| 73 | case R_HEX_12_X: | ||
| 74 | or32le(Loc, applyMask(0x000007e0, Val)); | ||
| 75 | break; | ||
| 76 | case R_HEX_32_6_X: | ||
| 77 | or32le(Loc, applyMask(0x0fff3fff, Val >> 6)); | ||
| 78 | break; | ||
| 79 | case R_HEX_B15_PCREL: | ||
| 80 | or32le(Loc, applyMask(0x00df20fe, Val >> 2)); | ||
| 81 | break; | ||
| 82 | case R_HEX_B15_PCREL_X: | ||
| 83 | or32le(Loc, applyMask(0x00df20fe, Val & 0x3f)); | ||
| 84 | break; | ||
| 85 | case R_HEX_B22_PCREL: | ||
| 86 | or32le(Loc, applyMask(0x1ff3ffe, Val >> 2)); | ||
| 87 | break; | ||
| 88 | case R_HEX_B22_PCREL_X: | ||
| 89 | or32le(Loc, applyMask(0x1ff3ffe, Val & 0x3f)); | ||
| 90 | break; | ||
| 91 | case R_HEX_B32_PCREL_X: | ||
| 92 | or32le(Loc, applyMask(0x0fff3fff, Val >> 6)); | ||
| 93 | break; | ||
| 94 | default: | ||
| 95 | error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type)); | ||
| 96 | break; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | TargetInfo *elf::getHexagonTargetInfo() { | ||
| 101 | static Hexagon Target; | ||
| 102 | return &Target; | ||
| 103 | } | ||
deps/lld/ELF/Arch/Mips.cpp+83-92| ... | @@ -32,7 +32,6 @@ public: | ... | @@ -32,7 +32,6 @@ public: |
| 32 | RelExpr getRelExpr(RelType Type, const Symbol &S, | 32 | RelExpr getRelExpr(RelType Type, const Symbol &S, |
| 33 | const uint8_t *Loc) const override; | 33 | const uint8_t *Loc) const override; |
| 34 | int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; | 34 | int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; |
| 35 | bool isPicRel(RelType Type) const override; | ||
| 36 | RelType getDynRel(RelType Type) const override; | 35 | RelType getDynRel(RelType Type) const override; |
| 37 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | 36 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; |
| 38 | void writePltHeader(uint8_t *Buf) const override; | 37 | void writePltHeader(uint8_t *Buf) const override; |
| ... | @@ -50,6 +49,7 @@ template <class ELFT> MIPS<ELFT>::MIPS() { | ... | @@ -50,6 +49,7 @@ template <class ELFT> MIPS<ELFT>::MIPS() { |
| 50 | DefaultMaxPageSize = 65536; | 49 | DefaultMaxPageSize = 65536; |
| 51 | GotEntrySize = sizeof(typename ELFT::uint); | 50 | GotEntrySize = sizeof(typename ELFT::uint); |
| 52 | GotPltEntrySize = sizeof(typename ELFT::uint); | 51 | GotPltEntrySize = sizeof(typename ELFT::uint); |
| 52 | GotBaseSymInGotPlt = false; | ||
| 53 | PltEntrySize = 16; | 53 | PltEntrySize = 16; |
| 54 | PltHeaderSize = 32; | 54 | PltHeaderSize = 32; |
| 55 | CopyRel = R_MIPS_COPY; | 55 | CopyRel = R_MIPS_COPY; |
| ... | @@ -101,8 +101,6 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -101,8 +101,6 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, |
| 101 | case R_MIPS_HIGHEST: | 101 | case R_MIPS_HIGHEST: |
| 102 | case R_MICROMIPS_HI16: | 102 | case R_MICROMIPS_HI16: |
| 103 | case R_MICROMIPS_LO16: | 103 | case R_MICROMIPS_LO16: |
| 104 | case R_MICROMIPS_HIGHER: | ||
| 105 | case R_MICROMIPS_HIGHEST: | ||
| 106 | // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate | 104 | // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate |
| 107 | // offset between start of function and 'gp' value which by default | 105 | // offset between start of function and 'gp' value which by default |
| 108 | // equal to the start of .got section. In that case we consider these | 106 | // equal to the start of .got section. In that case we consider these |
| ... | @@ -124,8 +122,6 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -124,8 +122,6 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, |
| 124 | case R_MIPS_TLS_TPREL_LO16: | 122 | case R_MIPS_TLS_TPREL_LO16: |
| 125 | case R_MIPS_TLS_TPREL32: | 123 | case R_MIPS_TLS_TPREL32: |
| 126 | case R_MIPS_TLS_TPREL64: | 124 | case R_MIPS_TLS_TPREL64: |
| 127 | case R_MICROMIPS_GOT_OFST: | ||
| 128 | case R_MICROMIPS_SUB: | ||
| 129 | case R_MICROMIPS_TLS_DTPREL_HI16: | 125 | case R_MICROMIPS_TLS_DTPREL_HI16: |
| 130 | case R_MICROMIPS_TLS_DTPREL_LO16: | 126 | case R_MICROMIPS_TLS_DTPREL_LO16: |
| 131 | case R_MICROMIPS_TLS_TPREL_HI16: | 127 | case R_MICROMIPS_TLS_TPREL_HI16: |
| ... | @@ -155,7 +151,6 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -155,7 +151,6 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, |
| 155 | case R_MIPS_GOT_DISP: | 151 | case R_MIPS_GOT_DISP: |
| 156 | case R_MIPS_TLS_GOTTPREL: | 152 | case R_MIPS_TLS_GOTTPREL: |
| 157 | case R_MICROMIPS_CALL16: | 153 | case R_MICROMIPS_CALL16: |
| 158 | case R_MICROMIPS_GOT_DISP: | ||
| 159 | case R_MICROMIPS_TLS_GOTTPREL: | 154 | case R_MICROMIPS_TLS_GOTTPREL: |
| 160 | return R_MIPS_GOT_OFF; | 155 | return R_MIPS_GOT_OFF; |
| 161 | case R_MIPS_CALL_HI16: | 156 | case R_MIPS_CALL_HI16: |
| ... | @@ -168,7 +163,6 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -168,7 +163,6 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, |
| 168 | case R_MICROMIPS_GOT_LO16: | 163 | case R_MICROMIPS_GOT_LO16: |
| 169 | return R_MIPS_GOT_OFF32; | 164 | return R_MIPS_GOT_OFF32; |
| 170 | case R_MIPS_GOT_PAGE: | 165 | case R_MIPS_GOT_PAGE: |
| 171 | case R_MICROMIPS_GOT_PAGE: | ||
| 172 | return R_MIPS_GOT_LOCAL_PAGE; | 166 | return R_MIPS_GOT_LOCAL_PAGE; |
| 173 | case R_MIPS_TLS_GD: | 167 | case R_MIPS_TLS_GD: |
| 174 | case R_MICROMIPS_TLS_GD: | 168 | case R_MICROMIPS_TLS_GD: |
| ... | @@ -183,12 +177,10 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -183,12 +177,10 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S, |
| 183 | } | 177 | } |
| 184 | } | 178 | } |
| 185 | 179 | ||
| 186 | template <class ELFT> bool MIPS<ELFT>::isPicRel(RelType Type) const { | ||
| 187 | return Type == R_MIPS_32 || Type == R_MIPS_64; | ||
| 188 | } | ||
| 189 | |||
| 190 | template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const { | 180 | template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const { |
| 191 | return RelativeRel; | 181 | if (Type == R_MIPS_32 || Type == R_MIPS_64) |
| 182 | return RelativeRel; | ||
| 183 | return R_MIPS_NONE; | ||
| 192 | } | 184 | } |
| 193 | 185 | ||
| 194 | template <class ELFT> | 186 | template <class ELFT> |
| ... | @@ -213,8 +205,8 @@ template <endianness E> static uint32_t readShuffle(const uint8_t *Loc) { | ... | @@ -213,8 +205,8 @@ template <endianness E> static uint32_t readShuffle(const uint8_t *Loc) { |
| 213 | } | 205 | } |
| 214 | 206 | ||
| 215 | template <endianness E> | 207 | template <endianness E> |
| 216 | static void writeRelocation(uint8_t *Loc, uint64_t V, uint8_t BitsSize, | 208 | static void writeValue(uint8_t *Loc, uint64_t V, uint8_t BitsSize, |
| 217 | uint8_t Shift) { | 209 | uint8_t Shift) { |
| 218 | uint32_t Instr = read32<E>(Loc); | 210 | uint32_t Instr = read32<E>(Loc); |
| 219 | uint32_t Mask = 0xffffffff >> (32 - BitsSize); | 211 | uint32_t Mask = 0xffffffff >> (32 - BitsSize); |
| 220 | uint32_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask); | 212 | uint32_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask); |
| ... | @@ -222,14 +214,14 @@ static void writeRelocation(uint8_t *Loc, uint64_t V, uint8_t BitsSize, | ... | @@ -222,14 +214,14 @@ static void writeRelocation(uint8_t *Loc, uint64_t V, uint8_t BitsSize, |
| 222 | } | 214 | } |
| 223 | 215 | ||
| 224 | template <endianness E> | 216 | template <endianness E> |
| 225 | static void writeMicroRelocation32(uint8_t *Loc, uint64_t V, uint8_t BitsSize, | 217 | static void writeShuffleValue(uint8_t *Loc, uint64_t V, uint8_t BitsSize, |
| 226 | uint8_t Shift) { | 218 | uint8_t Shift) { |
| 227 | // See comments in readShuffle for purpose of this code. | 219 | // See comments in readShuffle for purpose of this code. |
| 228 | uint16_t *Words = (uint16_t *)Loc; | 220 | uint16_t *Words = (uint16_t *)Loc; |
| 229 | if (E == support::little) | 221 | if (E == support::little) |
| 230 | std::swap(Words[0], Words[1]); | 222 | std::swap(Words[0], Words[1]); |
| 231 | 223 | ||
| 232 | writeRelocation<E>(Loc, V, BitsSize, Shift); | 224 | writeValue<E>(Loc, V, BitsSize, Shift); |
| 233 | 225 | ||
| 234 | if (E == support::little) | 226 | if (E == support::little) |
| 235 | std::swap(Words[0], Words[1]); | 227 | std::swap(Words[0], Words[1]); |
| ... | @@ -296,13 +288,14 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const { | ... | @@ -296,13 +288,14 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const { |
| 296 | write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2 | 288 | write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2 |
| 297 | } | 289 | } |
| 298 | 290 | ||
| 299 | write32<E>(Buf + 24, 0x0320f809); // jalr $25 | 291 | uint32_t JalrInst = Config->ZHazardplt ? 0x0320fc09 : 0x0320f809; |
| 292 | write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25 | ||
| 300 | write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2 | 293 | write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2 |
| 301 | 294 | ||
| 302 | uint64_t GotPlt = InX::GotPlt->getVA(); | 295 | uint64_t GotPlt = InX::GotPlt->getVA(); |
| 303 | writeRelocation<E>(Buf, GotPlt + 0x8000, 16, 16); | 296 | writeValue<E>(Buf, GotPlt + 0x8000, 16, 16); |
| 304 | writeRelocation<E>(Buf + 4, GotPlt, 16, 0); | 297 | writeValue<E>(Buf + 4, GotPlt, 16, 0); |
| 305 | writeRelocation<E>(Buf + 8, GotPlt, 16, 0); | 298 | writeValue<E>(Buf + 8, GotPlt, 16, 0); |
| 306 | } | 299 | } |
| 307 | 300 | ||
| 308 | template <class ELFT> | 301 | template <class ELFT> |
| ... | @@ -330,13 +323,16 @@ void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ... | @@ -330,13 +323,16 @@ void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 330 | return; | 323 | return; |
| 331 | } | 324 | } |
| 332 | 325 | ||
| 326 | uint32_t JrInst = isMipsR6() ? (Config->ZHazardplt ? 0x03200409 : 0x03200009) | ||
| 327 | : (Config->ZHazardplt ? 0x03200408 : 0x03200008); | ||
| 328 | |||
| 333 | write32<E>(Buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry) | 329 | write32<E>(Buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry) |
| 334 | write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15) | 330 | write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15) |
| 335 | write32<E>(Buf + 8, isMipsR6() ? 0x03200009 : 0x03200008); // jr $25 | 331 | write32<E>(Buf + 8, JrInst); // jr $25 / jr.hb $25 |
| 336 | write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry) | 332 | write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry) |
| 337 | writeRelocation<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16); | 333 | writeValue<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16); |
| 338 | writeRelocation<E>(Buf + 4, GotPltEntryAddr, 16, 0); | 334 | writeValue<E>(Buf + 4, GotPltEntryAddr, 16, 0); |
| 339 | writeRelocation<E>(Buf + 12, GotPltEntryAddr, 16, 0); | 335 | writeValue<E>(Buf + 12, GotPltEntryAddr, 16, 0); |
| 340 | } | 336 | } |
| 341 | 337 | ||
| 342 | template <class ELFT> | 338 | template <class ELFT> |
| ... | @@ -455,9 +451,6 @@ calculateMipsRelChain(uint8_t *Loc, RelType Type, uint64_t Val) { | ... | @@ -455,9 +451,6 @@ calculateMipsRelChain(uint8_t *Loc, RelType Type, uint64_t Val) { |
| 455 | return std::make_pair(Type2, Val); | 451 | return std::make_pair(Type2, Val); |
| 456 | if (Type2 == R_MIPS_SUB && (Type3 == R_MIPS_HI16 || Type3 == R_MIPS_LO16)) | 452 | if (Type2 == R_MIPS_SUB && (Type3 == R_MIPS_HI16 || Type3 == R_MIPS_LO16)) |
| 457 | return std::make_pair(Type3, -Val); | 453 | return std::make_pair(Type3, -Val); |
| 458 | if (Type2 == R_MICROMIPS_SUB && | ||
| 459 | (Type3 == R_MICROMIPS_HI16 || Type3 == R_MICROMIPS_LO16)) | ||
| 460 | return std::make_pair(Type3, -Val); | ||
| 461 | error(getErrorLocation(Loc) + "unsupported relocations combination " + | 454 | error(getErrorLocation(Loc) + "unsupported relocations combination " + |
| 462 | Twine(Type)); | 455 | Twine(Type)); |
| 463 | return std::make_pair(Type & 0xff, Val); | 456 | return std::make_pair(Type & 0xff, Val); |
| ... | @@ -467,6 +460,9 @@ template <class ELFT> | ... | @@ -467,6 +460,9 @@ template <class ELFT> |
| 467 | void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | 460 | void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 468 | const endianness E = ELFT::TargetEndianness; | 461 | const endianness E = ELFT::TargetEndianness; |
| 469 | 462 | ||
| 463 | if (ELFT::Is64Bits || Config->MipsN32Abi) | ||
| 464 | std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val); | ||
| 465 | |||
| 470 | // Thread pointer and DRP offsets from the start of TLS data area. | 466 | // Thread pointer and DRP offsets from the start of TLS data area. |
| 471 | // https://www.linux-mips.org/wiki/NPTL | 467 | // https://www.linux-mips.org/wiki/NPTL |
| 472 | if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 || | 468 | if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 || |
| ... | @@ -481,9 +477,6 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -481,9 +477,6 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 481 | Val -= 0x7000; | 477 | Val -= 0x7000; |
| 482 | } | 478 | } |
| 483 | 479 | ||
| 484 | if (ELFT::Is64Bits || Config->MipsN32Abi) | ||
| 485 | std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val); | ||
| 486 | |||
| 487 | switch (Type) { | 480 | switch (Type) { |
| 488 | case R_MIPS_32: | 481 | case R_MIPS_32: |
| 489 | case R_MIPS_GPREL32: | 482 | case R_MIPS_GPREL32: |
| ... | @@ -497,25 +490,25 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -497,25 +490,25 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 497 | write64<E>(Loc, Val); | 490 | write64<E>(Loc, Val); |
| 498 | break; | 491 | break; |
| 499 | case R_MIPS_26: | 492 | case R_MIPS_26: |
| 500 | writeRelocation<E>(Loc, Val, 26, 2); | 493 | writeValue<E>(Loc, Val, 26, 2); |
| 501 | break; | 494 | break; |
| 502 | case R_MIPS_GOT16: | 495 | case R_MIPS_GOT16: |
| 503 | // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode | 496 | // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode |
| 504 | // is updated addend (not a GOT index). In that case write high 16 bits | 497 | // is updated addend (not a GOT index). In that case write high 16 bits |
| 505 | // to store a correct addend value. | 498 | // to store a correct addend value. |
| 506 | if (Config->Relocatable) { | 499 | if (Config->Relocatable) { |
| 507 | writeRelocation<E>(Loc, Val + 0x8000, 16, 16); | 500 | writeValue<E>(Loc, Val + 0x8000, 16, 16); |
| 508 | } else { | 501 | } else { |
| 509 | checkInt<16>(Loc, Val, Type); | 502 | checkInt(Loc, Val, 16, Type); |
| 510 | writeRelocation<E>(Loc, Val, 16, 0); | 503 | writeValue<E>(Loc, Val, 16, 0); |
| 511 | } | 504 | } |
| 512 | break; | 505 | break; |
| 513 | case R_MICROMIPS_GOT16: | 506 | case R_MICROMIPS_GOT16: |
| 514 | if (Config->Relocatable) { | 507 | if (Config->Relocatable) { |
| 515 | writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16); | 508 | writeShuffleValue<E>(Loc, Val + 0x8000, 16, 16); |
| 516 | } else { | 509 | } else { |
| 517 | checkInt<16>(Loc, Val, Type); | 510 | checkInt(Loc, Val, 16, Type); |
| 518 | writeMicroRelocation32<E>(Loc, Val, 16, 0); | 511 | writeShuffleValue<E>(Loc, Val, 16, 0); |
| 519 | } | 512 | } |
| 520 | break; | 513 | break; |
| 521 | case R_MIPS_CALL16: | 514 | case R_MIPS_CALL16: |
| ... | @@ -525,7 +518,7 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -525,7 +518,7 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 525 | case R_MIPS_TLS_GD: | 518 | case R_MIPS_TLS_GD: |
| 526 | case R_MIPS_TLS_GOTTPREL: | 519 | case R_MIPS_TLS_GOTTPREL: |
| 527 | case R_MIPS_TLS_LDM: | 520 | case R_MIPS_TLS_LDM: |
| 528 | checkInt<16>(Loc, Val, Type); | 521 | checkInt(Loc, Val, 16, Type); |
| 529 | LLVM_FALLTHROUGH; | 522 | LLVM_FALLTHROUGH; |
| 530 | case R_MIPS_CALL_LO16: | 523 | case R_MIPS_CALL_LO16: |
| 531 | case R_MIPS_GOT_LO16: | 524 | case R_MIPS_GOT_LO16: |
| ... | @@ -534,28 +527,25 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -534,28 +527,25 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 534 | case R_MIPS_PCLO16: | 527 | case R_MIPS_PCLO16: |
| 535 | case R_MIPS_TLS_DTPREL_LO16: | 528 | case R_MIPS_TLS_DTPREL_LO16: |
| 536 | case R_MIPS_TLS_TPREL_LO16: | 529 | case R_MIPS_TLS_TPREL_LO16: |
| 537 | writeRelocation<E>(Loc, Val, 16, 0); | 530 | writeValue<E>(Loc, Val, 16, 0); |
| 538 | break; | 531 | break; |
| 539 | case R_MICROMIPS_GOT_DISP: | ||
| 540 | case R_MICROMIPS_GOT_PAGE: | ||
| 541 | case R_MICROMIPS_GPREL16: | 532 | case R_MICROMIPS_GPREL16: |
| 542 | case R_MICROMIPS_TLS_GD: | 533 | case R_MICROMIPS_TLS_GD: |
| 543 | case R_MICROMIPS_TLS_LDM: | 534 | case R_MICROMIPS_TLS_LDM: |
| 544 | checkInt<16>(Loc, Val, Type); | 535 | checkInt(Loc, Val, 16, Type); |
| 545 | writeMicroRelocation32<E>(Loc, Val, 16, 0); | 536 | writeShuffleValue<E>(Loc, Val, 16, 0); |
| 546 | break; | 537 | break; |
| 547 | case R_MICROMIPS_CALL16: | 538 | case R_MICROMIPS_CALL16: |
| 548 | case R_MICROMIPS_CALL_LO16: | 539 | case R_MICROMIPS_CALL_LO16: |
| 549 | case R_MICROMIPS_GOT_OFST: | ||
| 550 | case R_MICROMIPS_LO16: | 540 | case R_MICROMIPS_LO16: |
| 551 | case R_MICROMIPS_TLS_DTPREL_LO16: | 541 | case R_MICROMIPS_TLS_DTPREL_LO16: |
| 552 | case R_MICROMIPS_TLS_GOTTPREL: | 542 | case R_MICROMIPS_TLS_GOTTPREL: |
| 553 | case R_MICROMIPS_TLS_TPREL_LO16: | 543 | case R_MICROMIPS_TLS_TPREL_LO16: |
| 554 | writeMicroRelocation32<E>(Loc, Val, 16, 0); | 544 | writeShuffleValue<E>(Loc, Val, 16, 0); |
| 555 | break; | 545 | break; |
| 556 | case R_MICROMIPS_GPREL7_S2: | 546 | case R_MICROMIPS_GPREL7_S2: |
| 557 | checkInt<7>(Loc, Val, Type); | 547 | checkInt(Loc, Val, 7, Type); |
| 558 | writeMicroRelocation32<E>(Loc, Val, 7, 2); | 548 | writeShuffleValue<E>(Loc, Val, 7, 2); |
| 559 | break; | 549 | break; |
| 560 | case R_MIPS_CALL_HI16: | 550 | case R_MIPS_CALL_HI16: |
| 561 | case R_MIPS_GOT_HI16: | 551 | case R_MIPS_GOT_HI16: |
| ... | @@ -563,86 +553,80 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -563,86 +553,80 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 563 | case R_MIPS_PCHI16: | 553 | case R_MIPS_PCHI16: |
| 564 | case R_MIPS_TLS_DTPREL_HI16: | 554 | case R_MIPS_TLS_DTPREL_HI16: |
| 565 | case R_MIPS_TLS_TPREL_HI16: | 555 | case R_MIPS_TLS_TPREL_HI16: |
| 566 | writeRelocation<E>(Loc, Val + 0x8000, 16, 16); | 556 | writeValue<E>(Loc, Val + 0x8000, 16, 16); |
| 567 | break; | 557 | break; |
| 568 | case R_MICROMIPS_CALL_HI16: | 558 | case R_MICROMIPS_CALL_HI16: |
| 569 | case R_MICROMIPS_GOT_HI16: | 559 | case R_MICROMIPS_GOT_HI16: |
| 570 | case R_MICROMIPS_HI16: | 560 | case R_MICROMIPS_HI16: |
| 571 | case R_MICROMIPS_TLS_DTPREL_HI16: | 561 | case R_MICROMIPS_TLS_DTPREL_HI16: |
| 572 | case R_MICROMIPS_TLS_TPREL_HI16: | 562 | case R_MICROMIPS_TLS_TPREL_HI16: |
| 573 | writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16); | 563 | writeShuffleValue<E>(Loc, Val + 0x8000, 16, 16); |
| 574 | break; | 564 | break; |
| 575 | case R_MIPS_HIGHER: | 565 | case R_MIPS_HIGHER: |
| 576 | writeRelocation<E>(Loc, Val + 0x80008000, 16, 32); | 566 | writeValue<E>(Loc, Val + 0x80008000, 16, 32); |
| 577 | break; | 567 | break; |
| 578 | case R_MIPS_HIGHEST: | 568 | case R_MIPS_HIGHEST: |
| 579 | writeRelocation<E>(Loc, Val + 0x800080008000, 16, 48); | 569 | writeValue<E>(Loc, Val + 0x800080008000, 16, 48); |
| 580 | break; | ||
| 581 | case R_MICROMIPS_HIGHER: | ||
| 582 | writeMicroRelocation32<E>(Loc, Val + 0x80008000, 16, 32); | ||
| 583 | break; | ||
| 584 | case R_MICROMIPS_HIGHEST: | ||
| 585 | writeMicroRelocation32<E>(Loc, Val + 0x800080008000, 16, 48); | ||
| 586 | break; | 570 | break; |
| 587 | case R_MIPS_JALR: | 571 | case R_MIPS_JALR: |
| 588 | case R_MICROMIPS_JALR: | 572 | case R_MICROMIPS_JALR: |
| 589 | // Ignore this optimization relocation for now | 573 | // Ignore this optimization relocation for now |
| 590 | break; | 574 | break; |
| 591 | case R_MIPS_PC16: | 575 | case R_MIPS_PC16: |
| 592 | checkAlignment<4>(Loc, Val, Type); | 576 | checkAlignment(Loc, Val, 4, Type); |
| 593 | checkInt<18>(Loc, Val, Type); | 577 | checkInt(Loc, Val, 18, Type); |
| 594 | writeRelocation<E>(Loc, Val, 16, 2); | 578 | writeValue<E>(Loc, Val, 16, 2); |
| 595 | break; | 579 | break; |
| 596 | case R_MIPS_PC19_S2: | 580 | case R_MIPS_PC19_S2: |
| 597 | checkAlignment<4>(Loc, Val, Type); | 581 | checkAlignment(Loc, Val, 4, Type); |
| 598 | checkInt<21>(Loc, Val, Type); | 582 | checkInt(Loc, Val, 21, Type); |
| 599 | writeRelocation<E>(Loc, Val, 19, 2); | 583 | writeValue<E>(Loc, Val, 19, 2); |
| 600 | break; | 584 | break; |
| 601 | case R_MIPS_PC21_S2: | 585 | case R_MIPS_PC21_S2: |
| 602 | checkAlignment<4>(Loc, Val, Type); | 586 | checkAlignment(Loc, Val, 4, Type); |
| 603 | checkInt<23>(Loc, Val, Type); | 587 | checkInt(Loc, Val, 23, Type); |
| 604 | writeRelocation<E>(Loc, Val, 21, 2); | 588 | writeValue<E>(Loc, Val, 21, 2); |
| 605 | break; | 589 | break; |
| 606 | case R_MIPS_PC26_S2: | 590 | case R_MIPS_PC26_S2: |
| 607 | checkAlignment<4>(Loc, Val, Type); | 591 | checkAlignment(Loc, Val, 4, Type); |
| 608 | checkInt<28>(Loc, Val, Type); | 592 | checkInt(Loc, Val, 28, Type); |
| 609 | writeRelocation<E>(Loc, Val, 26, 2); | 593 | writeValue<E>(Loc, Val, 26, 2); |
| 610 | break; | 594 | break; |
| 611 | case R_MIPS_PC32: | 595 | case R_MIPS_PC32: |
| 612 | writeRelocation<E>(Loc, Val, 32, 0); | 596 | writeValue<E>(Loc, Val, 32, 0); |
| 613 | break; | 597 | break; |
| 614 | case R_MICROMIPS_26_S1: | 598 | case R_MICROMIPS_26_S1: |
| 615 | case R_MICROMIPS_PC26_S1: | 599 | case R_MICROMIPS_PC26_S1: |
| 616 | checkInt<27>(Loc, Val, Type); | 600 | checkInt(Loc, Val, 27, Type); |
| 617 | writeMicroRelocation32<E>(Loc, Val, 26, 1); | 601 | writeShuffleValue<E>(Loc, Val, 26, 1); |
| 618 | break; | 602 | break; |
| 619 | case R_MICROMIPS_PC7_S1: | 603 | case R_MICROMIPS_PC7_S1: |
| 620 | checkInt<8>(Loc, Val, Type); | 604 | checkInt(Loc, Val, 8, Type); |
| 621 | writeMicroRelocation16<E>(Loc, Val, 7, 1); | 605 | writeMicroRelocation16<E>(Loc, Val, 7, 1); |
| 622 | break; | 606 | break; |
| 623 | case R_MICROMIPS_PC10_S1: | 607 | case R_MICROMIPS_PC10_S1: |
| 624 | checkInt<11>(Loc, Val, Type); | 608 | checkInt(Loc, Val, 11, Type); |
| 625 | writeMicroRelocation16<E>(Loc, Val, 10, 1); | 609 | writeMicroRelocation16<E>(Loc, Val, 10, 1); |
| 626 | break; | 610 | break; |
| 627 | case R_MICROMIPS_PC16_S1: | 611 | case R_MICROMIPS_PC16_S1: |
| 628 | checkInt<17>(Loc, Val, Type); | 612 | checkInt(Loc, Val, 17, Type); |
| 629 | writeMicroRelocation32<E>(Loc, Val, 16, 1); | 613 | writeShuffleValue<E>(Loc, Val, 16, 1); |
| 630 | break; | 614 | break; |
| 631 | case R_MICROMIPS_PC18_S3: | 615 | case R_MICROMIPS_PC18_S3: |
| 632 | checkInt<21>(Loc, Val, Type); | 616 | checkInt(Loc, Val, 21, Type); |
| 633 | writeMicroRelocation32<E>(Loc, Val, 18, 3); | 617 | writeShuffleValue<E>(Loc, Val, 18, 3); |
| 634 | break; | 618 | break; |
| 635 | case R_MICROMIPS_PC19_S2: | 619 | case R_MICROMIPS_PC19_S2: |
| 636 | checkInt<21>(Loc, Val, Type); | 620 | checkInt(Loc, Val, 21, Type); |
| 637 | writeMicroRelocation32<E>(Loc, Val, 19, 2); | 621 | writeShuffleValue<E>(Loc, Val, 19, 2); |
| 638 | break; | 622 | break; |
| 639 | case R_MICROMIPS_PC21_S1: | 623 | case R_MICROMIPS_PC21_S1: |
| 640 | checkInt<22>(Loc, Val, Type); | 624 | checkInt(Loc, Val, 22, Type); |
| 641 | writeMicroRelocation32<E>(Loc, Val, 21, 1); | 625 | writeShuffleValue<E>(Loc, Val, 21, 1); |
| 642 | break; | 626 | break; |
| 643 | case R_MICROMIPS_PC23_S2: | 627 | case R_MICROMIPS_PC23_S2: |
| 644 | checkInt<25>(Loc, Val, Type); | 628 | checkInt(Loc, Val, 25, Type); |
| 645 | writeMicroRelocation32<E>(Loc, Val, 23, 2); | 629 | writeShuffleValue<E>(Loc, Val, 23, 2); |
| 646 | break; | 630 | break; |
| 647 | default: | 631 | default: |
| 648 | error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); | 632 | error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); |
| ... | @@ -651,19 +635,26 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -651,19 +635,26 @@ void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 651 | 635 | ||
| 652 | template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const { | 636 | template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const { |
| 653 | return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST || | 637 | return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST || |
| 654 | Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_GOT_OFST; | 638 | Type == R_MICROMIPS_LO16; |
| 655 | } | 639 | } |
| 656 | 640 | ||
| 657 | // Return true if the symbol is a PIC function. | 641 | // Return true if the symbol is a PIC function. |
| 658 | template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) { | 642 | template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) { |
| 659 | typedef typename ELFT::Ehdr Elf_Ehdr; | 643 | if (!Sym->isFunc()) |
| 660 | if (!Sym->Section || !Sym->isFunc()) | 644 | return false; |
| 645 | |||
| 646 | if (Sym->StOther & STO_MIPS_PIC) | ||
| 647 | return true; | ||
| 648 | |||
| 649 | if (!Sym->Section) | ||
| 650 | return false; | ||
| 651 | |||
| 652 | ObjFile<ELFT> *File = | ||
| 653 | cast<InputSectionBase>(Sym->Section)->template getFile<ELFT>(); | ||
| 654 | if (!File) | ||
| 661 | return false; | 655 | return false; |
| 662 | 656 | ||
| 663 | auto *Sec = cast<InputSectionBase>(Sym->Section); | 657 | return File->getObj().getHeader()->e_flags & EF_MIPS_PIC; |
| 664 | const Elf_Ehdr *Hdr = Sec->template getFile<ELFT>()->getObj().getHeader(); | ||
| 665 | return (Sym->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC || | ||
| 666 | (Hdr->e_flags & EF_MIPS_PIC); | ||
| 667 | } | 658 | } |
| 668 | 659 | ||
| 669 | template <class ELFT> TargetInfo *elf::getMipsTargetInfo() { | 660 | template <class ELFT> TargetInfo *elf::getMipsTargetInfo() { |
deps/lld/ELF/Arch/MipsArchTree.cpp+22-15| ... | @@ -65,25 +65,30 @@ static StringRef getNanName(bool IsNan2008) { | ... | @@ -65,25 +65,30 @@ static StringRef getNanName(bool IsNan2008) { |
| 65 | static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; } | 65 | static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; } |
| 66 | 66 | ||
| 67 | static void checkFlags(ArrayRef<FileFlags> Files) { | 67 | static void checkFlags(ArrayRef<FileFlags> Files) { |
| 68 | assert(!Files.empty() && "expected non-empty file list"); | ||
| 69 | |||
| 68 | uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2); | 70 | uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2); |
| 69 | bool Nan = Files[0].Flags & EF_MIPS_NAN2008; | 71 | bool Nan = Files[0].Flags & EF_MIPS_NAN2008; |
| 70 | bool Fp = Files[0].Flags & EF_MIPS_FP64; | 72 | bool Fp = Files[0].Flags & EF_MIPS_FP64; |
| 71 | 73 | ||
| 72 | for (const FileFlags &F : Files.slice(1)) { | 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"); | ||
| 77 | |||
| 73 | uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2); | 78 | uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2); |
| 74 | if (ABI != ABI2) | 79 | if (ABI != ABI2) |
| 75 | error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" + | 80 | error(toString(F.File) + ": ABI '" + getAbiName(ABI2) + |
| 76 | getAbiName(ABI2) + "': " + toString(F.File)); | 81 | "' is incompatible with target ABI '" + getAbiName(ABI) + "'"); |
| 77 | 82 | ||
| 78 | bool Nan2 = F.Flags & EF_MIPS_NAN2008; | 83 | bool Nan2 = F.Flags & EF_MIPS_NAN2008; |
| 79 | if (Nan != Nan2) | 84 | if (Nan != Nan2) |
| 80 | error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" + | 85 | error(toString(F.File) + ": -mnan=" + getNanName(Nan2) + |
| 81 | getNanName(Nan2) + ": " + toString(F.File)); | 86 | " is incompatible with target -mnan=" + getNanName(Nan)); |
| 82 | 87 | ||
| 83 | bool Fp2 = F.Flags & EF_MIPS_FP64; | 88 | bool Fp2 = F.Flags & EF_MIPS_FP64; |
| 84 | if (Fp != Fp2) | 89 | if (Fp != Fp2) |
| 85 | error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" + | 90 | error(toString(F.File) + ": -mfp" + getFpName(Fp2) + |
| 86 | getFpName(Fp2) + ": " + toString(F.File)); | 91 | " is incompatible with target -mfp" + getFpName(Fp)); |
| 87 | } | 92 | } |
| 88 | } | 93 | } |
| 89 | 94 | ||
| ... | @@ -102,11 +107,13 @@ static uint32_t getPicFlags(ArrayRef<FileFlags> Files) { | ... | @@ -102,11 +107,13 @@ static uint32_t getPicFlags(ArrayRef<FileFlags> Files) { |
| 102 | for (const FileFlags &F : Files.slice(1)) { | 107 | for (const FileFlags &F : Files.slice(1)) { |
| 103 | bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC); | 108 | bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC); |
| 104 | if (IsPic && !IsPic2) | 109 | if (IsPic && !IsPic2) |
| 105 | warn("linking abicalls code " + toString(Files[0].File) + | 110 | warn(toString(F.File) + |
| 106 | " with non-abicalls file: " + toString(F.File)); | 111 | ": linking non-abicalls code with abicalls code " + |
| 112 | toString(Files[0].File)); | ||
| 107 | if (!IsPic && IsPic2) | 113 | if (!IsPic && IsPic2) |
| 108 | warn("linking non-abicalls code " + toString(Files[0].File) + | 114 | warn(toString(F.File) + |
| 109 | " with abicalls file: " + toString(F.File)); | 115 | ": linking abicalls code with non-abicalls code " + |
| 116 | toString(Files[0].File)); | ||
| 110 | } | 117 | } |
| 111 | 118 | ||
| 112 | // Compute the result PIC/non-PIC flag. | 119 | // Compute the result PIC/non-PIC flag. |
| ... | @@ -326,7 +333,7 @@ static StringRef getMipsFpAbiName(uint8_t FpAbi) { | ... | @@ -326,7 +333,7 @@ static StringRef getMipsFpAbiName(uint8_t FpAbi) { |
| 326 | case Mips::Val_GNU_MIPS_ABI_FP_SOFT: | 333 | case Mips::Val_GNU_MIPS_ABI_FP_SOFT: |
| 327 | return "-msoft-float"; | 334 | return "-msoft-float"; |
| 328 | case Mips::Val_GNU_MIPS_ABI_FP_OLD_64: | 335 | case Mips::Val_GNU_MIPS_ABI_FP_OLD_64: |
| 329 | return "-mips32r2 -mfp64 (old)"; | 336 | return "-mgp32 -mfp64 (old)"; |
| 330 | case Mips::Val_GNU_MIPS_ABI_FP_XX: | 337 | case Mips::Val_GNU_MIPS_ABI_FP_XX: |
| 331 | return "-mfpxx"; | 338 | return "-mfpxx"; |
| 332 | case Mips::Val_GNU_MIPS_ABI_FP_64: | 339 | case Mips::Val_GNU_MIPS_ABI_FP_64: |
| ... | @@ -343,9 +350,9 @@ uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag, | ... | @@ -343,9 +350,9 @@ uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag, |
| 343 | if (compareMipsFpAbi(NewFlag, OldFlag) >= 0) | 350 | if (compareMipsFpAbi(NewFlag, OldFlag) >= 0) |
| 344 | return NewFlag; | 351 | return NewFlag; |
| 345 | if (compareMipsFpAbi(OldFlag, NewFlag) < 0) | 352 | if (compareMipsFpAbi(OldFlag, NewFlag) < 0) |
| 346 | error("target floating point ABI '" + getMipsFpAbiName(OldFlag) + | 353 | error(FileName + ": floating point ABI '" + getMipsFpAbiName(NewFlag) + |
| 347 | "' is incompatible with '" + getMipsFpAbiName(NewFlag) + | 354 | "' is incompatible with target floating point ABI '" + |
| 348 | "': " + FileName); | 355 | getMipsFpAbiName(OldFlag) + "'"); |
| 349 | return OldFlag; | 356 | return OldFlag; |
| 350 | } | 357 | } |
| 351 | 358 |
deps/lld/ELF/Arch/PPC.cpp+6-1| ... | @@ -21,13 +21,18 @@ using namespace lld::elf; | ... | @@ -21,13 +21,18 @@ using namespace lld::elf; |
| 21 | namespace { | 21 | namespace { |
| 22 | class PPC final : public TargetInfo { | 22 | class PPC final : public TargetInfo { |
| 23 | public: | 23 | public: |
| 24 | PPC() { GotBaseSymOff = 0x8000; } | 24 | PPC(); |
| 25 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | 25 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; |
| 26 | RelExpr getRelExpr(RelType Type, const Symbol &S, | 26 | RelExpr getRelExpr(RelType Type, const Symbol &S, |
| 27 | const uint8_t *Loc) const override; | 27 | const uint8_t *Loc) const override; |
| 28 | }; | 28 | }; |
| 29 | } // namespace | 29 | } // namespace |
| 30 | 30 | ||
| 31 | PPC::PPC() { | ||
| 32 | GotBaseSymOff = 0x8000; | ||
| 33 | GotBaseSymInGotPlt = false; | ||
| 34 | } | ||
| 35 | |||
| 31 | RelExpr PPC::getRelExpr(RelType Type, const Symbol &S, | 36 | RelExpr PPC::getRelExpr(RelType Type, const Symbol &S, |
| 32 | const uint8_t *Loc) const { | 37 | const uint8_t *Loc) const { |
| 33 | switch (Type) { | 38 | switch (Type) { |
deps/lld/ELF/Arch/PPC64.cpp+369-54| ... | @@ -14,12 +14,14 @@ | ... | @@ -14,12 +14,14 @@ |
| 14 | #include "llvm/Support/Endian.h" | 14 | #include "llvm/Support/Endian.h" |
| 15 | 15 | ||
| 16 | using namespace llvm; | 16 | using namespace llvm; |
| 17 | using namespace llvm::object; | ||
| 17 | using namespace llvm::support::endian; | 18 | using namespace llvm::support::endian; |
| 18 | using namespace llvm::ELF; | 19 | using namespace llvm::ELF; |
| 19 | using namespace lld; | 20 | using namespace lld; |
| 20 | using namespace lld::elf; | 21 | using namespace lld::elf; |
| 21 | 22 | ||
| 22 | static uint64_t PPC64TocOffset = 0x8000; | 23 | static uint64_t PPC64TocOffset = 0x8000; |
| 24 | static uint64_t DynamicThreadPointerOffset = 0x8000; | ||
| 23 | 25 | ||
| 24 | uint64_t elf::getPPC64TocBase() { | 26 | uint64_t elf::getPPC64TocBase() { |
| 25 | // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The | 27 | // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The |
| ... | @@ -39,11 +41,21 @@ namespace { | ... | @@ -39,11 +41,21 @@ namespace { |
| 39 | class PPC64 final : public TargetInfo { | 41 | class PPC64 final : public TargetInfo { |
| 40 | public: | 42 | public: |
| 41 | PPC64(); | 43 | PPC64(); |
| 44 | uint32_t calcEFlags() const override; | ||
| 42 | RelExpr getRelExpr(RelType Type, const Symbol &S, | 45 | RelExpr getRelExpr(RelType Type, const Symbol &S, |
| 43 | const uint8_t *Loc) const override; | 46 | const uint8_t *Loc) const override; |
| 47 | void writePltHeader(uint8_t *Buf) const override; | ||
| 44 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, | 48 | void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, |
| 45 | int32_t Index, unsigned RelOff) const override; | 49 | int32_t Index, unsigned RelOff) const override; |
| 46 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; | 50 | void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; |
| 51 | void writeGotHeader(uint8_t *Buf) const override; | ||
| 52 | bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | ||
| 53 | uint64_t BranchAddr, const Symbol &S) const override; | ||
| 54 | RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data, | ||
| 55 | RelExpr Expr) const override; | ||
| 56 | void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | ||
| 57 | void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | ||
| 58 | void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | ||
| 47 | }; | 59 | }; |
| 48 | } // namespace | 60 | } // namespace |
| 49 | 61 | ||
| ... | @@ -51,21 +63,35 @@ public: | ... | @@ -51,21 +63,35 @@ public: |
| 51 | // #higher(value), #highera(value), #highest(value), and #highesta(value) | 63 | // #higher(value), #highera(value), #highest(value), and #highesta(value) |
| 52 | // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi | 64 | // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi |
| 53 | // document. | 65 | // document. |
| 54 | static uint16_t applyPPCLo(uint64_t V) { return V; } | 66 | static uint16_t lo(uint64_t V) { return V; } |
| 55 | static uint16_t applyPPCHi(uint64_t V) { return V >> 16; } | 67 | static uint16_t hi(uint64_t V) { return V >> 16; } |
| 56 | static uint16_t applyPPCHa(uint64_t V) { return (V + 0x8000) >> 16; } | 68 | static uint16_t ha(uint64_t V) { return (V + 0x8000) >> 16; } |
| 57 | static uint16_t applyPPCHigher(uint64_t V) { return V >> 32; } | 69 | static uint16_t higher(uint64_t V) { return V >> 32; } |
| 58 | static uint16_t applyPPCHighera(uint64_t V) { return (V + 0x8000) >> 32; } | 70 | static uint16_t highera(uint64_t V) { return (V + 0x8000) >> 32; } |
| 59 | static uint16_t applyPPCHighest(uint64_t V) { return V >> 48; } | 71 | static uint16_t highest(uint64_t V) { return V >> 48; } |
| 60 | static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; } | 72 | static uint16_t highesta(uint64_t V) { return (V + 0x8000) >> 48; } |
| 61 | 73 | ||
| 62 | PPC64::PPC64() { | 74 | PPC64::PPC64() { |
| 63 | PltRel = GotRel = R_PPC64_GLOB_DAT; | 75 | GotRel = R_PPC64_GLOB_DAT; |
| 76 | PltRel = R_PPC64_JMP_SLOT; | ||
| 64 | RelativeRel = R_PPC64_RELATIVE; | 77 | RelativeRel = R_PPC64_RELATIVE; |
| 78 | IRelativeRel = R_PPC64_IRELATIVE; | ||
| 65 | GotEntrySize = 8; | 79 | GotEntrySize = 8; |
| 80 | PltEntrySize = 4; | ||
| 66 | GotPltEntrySize = 8; | 81 | GotPltEntrySize = 8; |
| 67 | PltEntrySize = 32; | 82 | GotBaseSymInGotPlt = false; |
| 68 | PltHeaderSize = 0; | 83 | GotBaseSymOff = 0x8000; |
| 84 | GotHeaderEntriesNum = 1; | ||
| 85 | GotPltHeaderEntriesNum = 2; | ||
| 86 | PltHeaderSize = 60; | ||
| 87 | NeedsThunks = true; | ||
| 88 | TcbSize = 8; | ||
| 89 | TlsTpOffset = 0x7000; | ||
| 90 | |||
| 91 | TlsModuleIndexRel = R_PPC64_DTPMOD64; | ||
| 92 | TlsOffsetRel = R_PPC64_DTPREL64; | ||
| 93 | |||
| 94 | TlsGotRel = R_PPC64_TPREL64; | ||
| 69 | 95 | ||
| 70 | // We need 64K pages (at least under glibc/Linux, the loader won't | 96 | // We need 64K pages (at least under glibc/Linux, the loader won't |
| 71 | // set different permissions on a finer granularity than that). | 97 | // set different permissions on a finer granularity than that). |
| ... | @@ -80,6 +106,110 @@ PPC64::PPC64() { | ... | @@ -80,6 +106,110 @@ PPC64::PPC64() { |
| 80 | // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers | 106 | // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers |
| 81 | // use 0x10000000 as the starting address. | 107 | // use 0x10000000 as the starting address. |
| 82 | DefaultImageBase = 0x10000000; | 108 | DefaultImageBase = 0x10000000; |
| 109 | |||
| 110 | TrapInstr = | ||
| 111 | (Config->IsLE == sys::IsLittleEndianHost) ? 0x7fe00008 : 0x0800e07f; | ||
| 112 | } | ||
| 113 | |||
| 114 | static uint32_t getEFlags(InputFile *File) { | ||
| 115 | if (Config->EKind == ELF64BEKind) | ||
| 116 | return cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags; | ||
| 117 | return cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags; | ||
| 118 | } | ||
| 119 | |||
| 120 | // This file implements v2 ABI. This function makes sure that all | ||
| 121 | // object files have v2 or an unspecified version as an ABI version. | ||
| 122 | uint32_t PPC64::calcEFlags() const { | ||
| 123 | for (InputFile *F : ObjectFiles) { | ||
| 124 | uint32_t Flag = getEFlags(F); | ||
| 125 | if (Flag == 1) | ||
| 126 | error(toString(F) + ": ABI version 1 is not supported"); | ||
| 127 | else if (Flag > 2) | ||
| 128 | error(toString(F) + ": unrecognized e_flags: " + Twine(Flag)); | ||
| 129 | } | ||
| 130 | return 2; | ||
| 131 | } | ||
| 132 | |||
| 133 | void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | ||
| 134 | // Reference: 3.7.4.2 of the 64-bit ELF V2 abi supplement. | ||
| 135 | // The general dynamic code sequence for a global `x` will look like: | ||
| 136 | // Instruction Relocation Symbol | ||
| 137 | // addis r3, r2, x@got@tlsgd@ha R_PPC64_GOT_TLSGD16_HA x | ||
| 138 | // addi r3, r3, x@got@tlsgd@l R_PPC64_GOT_TLSGD16_LO x | ||
| 139 | // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSGD x | ||
| 140 | // R_PPC64_REL24 __tls_get_addr | ||
| 141 | // nop None None | ||
| 142 | |||
| 143 | // Relaxing to local exec entails converting: | ||
| 144 | // addis r3, r2, x@got@tlsgd@ha into nop | ||
| 145 | // addi r3, r3, x@got@tlsgd@l into addis r3, r13, x@tprel@ha | ||
| 146 | // bl __tls_get_addr(x@tlsgd) into nop | ||
| 147 | // nop into addi r3, r3, x@tprel@l | ||
| 148 | |||
| 149 | uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U; | ||
| 150 | |||
| 151 | switch (Type) { | ||
| 152 | case R_PPC64_GOT_TLSGD16_HA: | ||
| 153 | write32(Loc - EndianOffset, 0x60000000); // nop | ||
| 154 | break; | ||
| 155 | case R_PPC64_GOT_TLSGD16_LO: | ||
| 156 | write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13 | ||
| 157 | relocateOne(Loc, R_PPC64_TPREL16_HA, Val); | ||
| 158 | break; | ||
| 159 | case R_PPC64_TLSGD: | ||
| 160 | write32(Loc, 0x60000000); // nop | ||
| 161 | write32(Loc + 4, 0x38630000); // addi r3, r3 | ||
| 162 | relocateOne(Loc + 4 + EndianOffset, R_PPC64_TPREL16_LO, Val); | ||
| 163 | break; | ||
| 164 | default: | ||
| 165 | llvm_unreachable("unsupported relocation for TLS GD to LE relaxation"); | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | |||
| 170 | void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { | ||
| 171 | // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement. | ||
| 172 | // The local dynamic code sequence for a global `x` will look like: | ||
| 173 | // Instruction Relocation Symbol | ||
| 174 | // addis r3, r2, x@got@tlsld@ha R_PPC64_GOT_TLSLD16_HA x | ||
| 175 | // addi r3, r3, x@got@tlsld@l R_PPC64_GOT_TLSLD16_LO x | ||
| 176 | // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSLD x | ||
| 177 | // R_PPC64_REL24 __tls_get_addr | ||
| 178 | // nop None None | ||
| 179 | |||
| 180 | // Relaxing to local exec entails converting: | ||
| 181 | // addis r3, r2, x@got@tlsld@ha into nop | ||
| 182 | // addi r3, r3, x@got@tlsld@l into addis r3, r13, 0 | ||
| 183 | // bl __tls_get_addr(x@tlsgd) into nop | ||
| 184 | // nop into addi r3, r3, 4096 | ||
| 185 | |||
| 186 | uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U; | ||
| 187 | switch (Type) { | ||
| 188 | case R_PPC64_GOT_TLSLD16_HA: | ||
| 189 | write32(Loc - EndianOffset, 0x60000000); // nop | ||
| 190 | break; | ||
| 191 | case R_PPC64_GOT_TLSLD16_LO: | ||
| 192 | write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13, 0 | ||
| 193 | break; | ||
| 194 | case R_PPC64_TLSLD: | ||
| 195 | write32(Loc, 0x60000000); // nop | ||
| 196 | write32(Loc + 4, 0x38631000); // addi r3, r3, 4096 | ||
| 197 | break; | ||
| 198 | case R_PPC64_DTPREL16: | ||
| 199 | case R_PPC64_DTPREL16_HA: | ||
| 200 | case R_PPC64_DTPREL16_HI: | ||
| 201 | case R_PPC64_DTPREL16_DS: | ||
| 202 | case R_PPC64_DTPREL16_LO: | ||
| 203 | case R_PPC64_DTPREL16_LO_DS: | ||
| 204 | case R_PPC64_GOT_DTPREL16_HA: | ||
| 205 | case R_PPC64_GOT_DTPREL16_LO_DS: | ||
| 206 | case R_PPC64_GOT_DTPREL16_DS: | ||
| 207 | case R_PPC64_GOT_DTPREL16_HI: | ||
| 208 | relocateOne(Loc, Type, Val); | ||
| 209 | break; | ||
| 210 | default: | ||
| 211 | llvm_unreachable("unsupported relocation for TLS LD to LE relaxation"); | ||
| 212 | } | ||
| 83 | } | 213 | } |
| 84 | 214 | ||
| 85 | RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S, | 215 | RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S, |
| ... | @@ -95,48 +225,162 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -95,48 +225,162 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S, |
| 95 | case R_PPC64_TOC: | 225 | case R_PPC64_TOC: |
| 96 | return R_PPC_TOC; | 226 | return R_PPC_TOC; |
| 97 | case R_PPC64_REL24: | 227 | case R_PPC64_REL24: |
| 98 | return R_PPC_PLT_OPD; | 228 | return R_PPC_CALL_PLT; |
| 229 | case R_PPC64_REL16_LO: | ||
| 230 | case R_PPC64_REL16_HA: | ||
| 231 | case R_PPC64_REL32: | ||
| 232 | case R_PPC64_REL64: | ||
| 233 | return R_PC; | ||
| 234 | case R_PPC64_GOT_TLSGD16: | ||
| 235 | case R_PPC64_GOT_TLSGD16_HA: | ||
| 236 | case R_PPC64_GOT_TLSGD16_HI: | ||
| 237 | case R_PPC64_GOT_TLSGD16_LO: | ||
| 238 | return R_TLSGD_GOT; | ||
| 239 | case R_PPC64_GOT_TLSLD16: | ||
| 240 | case R_PPC64_GOT_TLSLD16_HA: | ||
| 241 | case R_PPC64_GOT_TLSLD16_HI: | ||
| 242 | case R_PPC64_GOT_TLSLD16_LO: | ||
| 243 | return R_TLSLD_GOT; | ||
| 244 | case R_PPC64_GOT_TPREL16_HA: | ||
| 245 | case R_PPC64_GOT_TPREL16_LO_DS: | ||
| 246 | case R_PPC64_GOT_TPREL16_DS: | ||
| 247 | case R_PPC64_GOT_TPREL16_HI: | ||
| 248 | return R_GOT_OFF; | ||
| 249 | case R_PPC64_GOT_DTPREL16_HA: | ||
| 250 | case R_PPC64_GOT_DTPREL16_LO_DS: | ||
| 251 | case R_PPC64_GOT_DTPREL16_DS: | ||
| 252 | case R_PPC64_GOT_DTPREL16_HI: | ||
| 253 | return R_TLSLD_GOT_OFF; | ||
| 254 | case R_PPC64_TPREL16: | ||
| 255 | case R_PPC64_TPREL16_HA: | ||
| 256 | case R_PPC64_TPREL16_LO: | ||
| 257 | case R_PPC64_TPREL16_HI: | ||
| 258 | case R_PPC64_TPREL16_DS: | ||
| 259 | case R_PPC64_TPREL16_LO_DS: | ||
| 260 | case R_PPC64_TPREL16_HIGHER: | ||
| 261 | case R_PPC64_TPREL16_HIGHERA: | ||
| 262 | case R_PPC64_TPREL16_HIGHEST: | ||
| 263 | case R_PPC64_TPREL16_HIGHESTA: | ||
| 264 | return R_TLS; | ||
| 265 | case R_PPC64_DTPREL16: | ||
| 266 | case R_PPC64_DTPREL16_DS: | ||
| 267 | case R_PPC64_DTPREL16_HA: | ||
| 268 | case R_PPC64_DTPREL16_HI: | ||
| 269 | case R_PPC64_DTPREL16_HIGHER: | ||
| 270 | case R_PPC64_DTPREL16_HIGHERA: | ||
| 271 | case R_PPC64_DTPREL16_HIGHEST: | ||
| 272 | case R_PPC64_DTPREL16_HIGHESTA: | ||
| 273 | case R_PPC64_DTPREL16_LO: | ||
| 274 | case R_PPC64_DTPREL16_LO_DS: | ||
| 275 | case R_PPC64_DTPREL64: | ||
| 276 | return R_ABS; | ||
| 277 | case R_PPC64_TLSGD: | ||
| 278 | return R_TLSDESC_CALL; | ||
| 279 | case R_PPC64_TLSLD: | ||
| 280 | return R_TLSLD_HINT; | ||
| 281 | case R_PPC64_TLS: | ||
| 282 | return R_HINT; | ||
| 99 | default: | 283 | default: |
| 100 | return R_ABS; | 284 | return R_ABS; |
| 101 | } | 285 | } |
| 102 | } | 286 | } |
| 103 | 287 | ||
| 288 | void PPC64::writeGotHeader(uint8_t *Buf) const { | ||
| 289 | write64(Buf, getPPC64TocBase()); | ||
| 290 | } | ||
| 291 | |||
| 292 | void PPC64::writePltHeader(uint8_t *Buf) const { | ||
| 293 | // The generic resolver stub goes first. | ||
| 294 | write32(Buf + 0, 0x7c0802a6); // mflr r0 | ||
| 295 | write32(Buf + 4, 0x429f0005); // bcl 20,4*cr7+so,8 <_glink+0x8> | ||
| 296 | write32(Buf + 8, 0x7d6802a6); // mflr r11 | ||
| 297 | write32(Buf + 12, 0x7c0803a6); // mtlr r0 | ||
| 298 | write32(Buf + 16, 0x7d8b6050); // subf r12, r11, r12 | ||
| 299 | write32(Buf + 20, 0x380cffcc); // subi r0,r12,52 | ||
| 300 | write32(Buf + 24, 0x7800f082); // srdi r0,r0,62,2 | ||
| 301 | write32(Buf + 28, 0xe98b002c); // ld r12,44(r11) | ||
| 302 | write32(Buf + 32, 0x7d6c5a14); // add r11,r12,r11 | ||
| 303 | write32(Buf + 36, 0xe98b0000); // ld r12,0(r11) | ||
| 304 | write32(Buf + 40, 0xe96b0008); // ld r11,8(r11) | ||
| 305 | write32(Buf + 44, 0x7d8903a6); // mtctr r12 | ||
| 306 | write32(Buf + 48, 0x4e800420); // bctr | ||
| 307 | |||
| 308 | // The 'bcl' instruction will set the link register to the address of the | ||
| 309 | // following instruction ('mflr r11'). Here we store the offset from that | ||
| 310 | // instruction to the first entry in the GotPlt section. | ||
| 311 | int64_t GotPltOffset = InX::GotPlt->getVA() - (InX::Plt->getVA() + 8); | ||
| 312 | write64(Buf + 52, GotPltOffset); | ||
| 313 | } | ||
| 314 | |||
| 104 | void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | 315 | void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 105 | uint64_t PltEntryAddr, int32_t Index, | 316 | uint64_t PltEntryAddr, int32_t Index, |
| 106 | unsigned RelOff) const { | 317 | unsigned RelOff) const { |
| 107 | uint64_t Off = GotPltEntryAddr - getPPC64TocBase(); | 318 | int32_t Offset = PltHeaderSize + Index * PltEntrySize; |
| 108 | 319 | // bl __glink_PLTresolve | |
| 109 | // FIXME: What we should do, in theory, is get the offset of the function | 320 | write32(Buf, 0x48000000 | ((-Offset) & 0x03FFFFFc)); |
| 110 | // descriptor in the .opd section, and use that as the offset from %r2 (the | ||
| 111 | // TOC-base pointer). Instead, we have the GOT-entry offset, and that will | ||
| 112 | // be a pointer to the function descriptor in the .opd section. Using | ||
| 113 | // this scheme is simpler, but requires an extra indirection per PLT dispatch. | ||
| 114 | |||
| 115 | write32be(Buf, 0xf8410028); // std %r2, 40(%r1) | ||
| 116 | write32be(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha | ||
| 117 | write32be(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11) | ||
| 118 | write32be(Buf + 12, 0xe96c0000); // ld %r11,0(%r12) | ||
| 119 | write32be(Buf + 16, 0x7d6903a6); // mtctr %r11 | ||
| 120 | write32be(Buf + 20, 0xe84c0008); // ld %r2,8(%r12) | ||
| 121 | write32be(Buf + 24, 0xe96c0010); // ld %r11,16(%r12) | ||
| 122 | write32be(Buf + 28, 0x4e800420); // bctr | ||
| 123 | } | 321 | } |
| 124 | 322 | ||
| 125 | static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) { | 323 | static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) { |
| 126 | uint64_t V = Val - PPC64TocOffset; | 324 | // Relocations relative to the toc-base need to be adjusted by the Toc offset. |
| 325 | uint64_t TocBiasedVal = Val - PPC64TocOffset; | ||
| 326 | // Relocations relative to dtv[dtpmod] need to be adjusted by the DTP offset. | ||
| 327 | uint64_t DTPBiasedVal = Val - DynamicThreadPointerOffset; | ||
| 328 | |||
| 127 | switch (Type) { | 329 | switch (Type) { |
| 330 | // TOC biased relocation. | ||
| 331 | case R_PPC64_GOT_TLSGD16: | ||
| 332 | case R_PPC64_GOT_TLSLD16: | ||
| 128 | case R_PPC64_TOC16: | 333 | case R_PPC64_TOC16: |
| 129 | return {R_PPC64_ADDR16, V}; | 334 | return {R_PPC64_ADDR16, TocBiasedVal}; |
| 130 | case R_PPC64_TOC16_DS: | 335 | case R_PPC64_TOC16_DS: |
| 131 | return {R_PPC64_ADDR16_DS, V}; | 336 | case R_PPC64_GOT_TPREL16_DS: |
| 337 | case R_PPC64_GOT_DTPREL16_DS: | ||
| 338 | return {R_PPC64_ADDR16_DS, TocBiasedVal}; | ||
| 339 | case R_PPC64_GOT_TLSGD16_HA: | ||
| 340 | case R_PPC64_GOT_TLSLD16_HA: | ||
| 341 | case R_PPC64_GOT_TPREL16_HA: | ||
| 342 | case R_PPC64_GOT_DTPREL16_HA: | ||
| 132 | case R_PPC64_TOC16_HA: | 343 | case R_PPC64_TOC16_HA: |
| 133 | return {R_PPC64_ADDR16_HA, V}; | 344 | return {R_PPC64_ADDR16_HA, TocBiasedVal}; |
| 345 | case R_PPC64_GOT_TLSGD16_HI: | ||
| 346 | case R_PPC64_GOT_TLSLD16_HI: | ||
| 347 | case R_PPC64_GOT_TPREL16_HI: | ||
| 348 | case R_PPC64_GOT_DTPREL16_HI: | ||
| 134 | case R_PPC64_TOC16_HI: | 349 | case R_PPC64_TOC16_HI: |
| 135 | return {R_PPC64_ADDR16_HI, V}; | 350 | return {R_PPC64_ADDR16_HI, TocBiasedVal}; |
| 351 | case R_PPC64_GOT_TLSGD16_LO: | ||
| 352 | case R_PPC64_GOT_TLSLD16_LO: | ||
| 136 | case R_PPC64_TOC16_LO: | 353 | case R_PPC64_TOC16_LO: |
| 137 | return {R_PPC64_ADDR16_LO, V}; | 354 | return {R_PPC64_ADDR16_LO, TocBiasedVal}; |
| 138 | case R_PPC64_TOC16_LO_DS: | 355 | case R_PPC64_TOC16_LO_DS: |
| 139 | return {R_PPC64_ADDR16_LO_DS, V}; | 356 | case R_PPC64_GOT_TPREL16_LO_DS: |
| 357 | case R_PPC64_GOT_DTPREL16_LO_DS: | ||
| 358 | return {R_PPC64_ADDR16_LO_DS, TocBiasedVal}; | ||
| 359 | |||
| 360 | // Dynamic Thread pointer biased relocation types. | ||
| 361 | case R_PPC64_DTPREL16: | ||
| 362 | return {R_PPC64_ADDR16, DTPBiasedVal}; | ||
| 363 | case R_PPC64_DTPREL16_DS: | ||
| 364 | return {R_PPC64_ADDR16_DS, DTPBiasedVal}; | ||
| 365 | case R_PPC64_DTPREL16_HA: | ||
| 366 | return {R_PPC64_ADDR16_HA, DTPBiasedVal}; | ||
| 367 | case R_PPC64_DTPREL16_HI: | ||
| 368 | return {R_PPC64_ADDR16_HI, DTPBiasedVal}; | ||
| 369 | case R_PPC64_DTPREL16_HIGHER: | ||
| 370 | return {R_PPC64_ADDR16_HIGHER, DTPBiasedVal}; | ||
| 371 | case R_PPC64_DTPREL16_HIGHERA: | ||
| 372 | return {R_PPC64_ADDR16_HIGHERA, DTPBiasedVal}; | ||
| 373 | case R_PPC64_DTPREL16_HIGHEST: | ||
| 374 | return {R_PPC64_ADDR16_HIGHEST, DTPBiasedVal}; | ||
| 375 | case R_PPC64_DTPREL16_HIGHESTA: | ||
| 376 | return {R_PPC64_ADDR16_HIGHESTA, DTPBiasedVal}; | ||
| 377 | case R_PPC64_DTPREL16_LO: | ||
| 378 | return {R_PPC64_ADDR16_LO, DTPBiasedVal}; | ||
| 379 | case R_PPC64_DTPREL16_LO_DS: | ||
| 380 | return {R_PPC64_ADDR16_LO_DS, DTPBiasedVal}; | ||
| 381 | case R_PPC64_DTPREL64: | ||
| 382 | return {R_PPC64_ADDR64, DTPBiasedVal}; | ||
| 383 | |||
| 140 | default: | 384 | default: |
| 141 | return {Type, Val}; | 385 | return {Type, Val}; |
| 142 | } | 386 | } |
| ... | @@ -149,68 +393,139 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -149,68 +393,139 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 149 | 393 | ||
| 150 | switch (Type) { | 394 | switch (Type) { |
| 151 | case R_PPC64_ADDR14: { | 395 | case R_PPC64_ADDR14: { |
| 152 | checkAlignment<4>(Loc, Val, Type); | 396 | checkAlignment(Loc, Val, 4, Type); |
| 153 | // Preserve the AA/LK bits in the branch instruction | 397 | // Preserve the AA/LK bits in the branch instruction |
| 154 | uint8_t AALK = Loc[3]; | 398 | uint8_t AALK = Loc[3]; |
| 155 | write16be(Loc + 2, (AALK & 3) | (Val & 0xfffc)); | 399 | write16(Loc + 2, (AALK & 3) | (Val & 0xfffc)); |
| 156 | break; | 400 | break; |
| 157 | } | 401 | } |
| 158 | case R_PPC64_ADDR16: | 402 | case R_PPC64_ADDR16: |
| 159 | checkInt<16>(Loc, Val, Type); | 403 | case R_PPC64_TPREL16: |
| 160 | write16be(Loc, Val); | 404 | checkInt(Loc, Val, 16, Type); |
| 405 | write16(Loc, Val); | ||
| 161 | break; | 406 | break; |
| 162 | case R_PPC64_ADDR16_DS: | 407 | case R_PPC64_ADDR16_DS: |
| 163 | checkInt<16>(Loc, Val, Type); | 408 | case R_PPC64_TPREL16_DS: |
| 164 | write16be(Loc, (read16be(Loc) & 3) | (Val & ~3)); | 409 | checkInt(Loc, Val, 16, Type); |
| 410 | write16(Loc, (read16(Loc) & 3) | (Val & ~3)); | ||
| 165 | break; | 411 | break; |
| 166 | case R_PPC64_ADDR16_HA: | 412 | case R_PPC64_ADDR16_HA: |
| 167 | case R_PPC64_REL16_HA: | 413 | case R_PPC64_REL16_HA: |
| 168 | write16be(Loc, applyPPCHa(Val)); | 414 | case R_PPC64_TPREL16_HA: |
| 415 | write16(Loc, ha(Val)); | ||
| 169 | break; | 416 | break; |
| 170 | case R_PPC64_ADDR16_HI: | 417 | case R_PPC64_ADDR16_HI: |
| 171 | case R_PPC64_REL16_HI: | 418 | case R_PPC64_REL16_HI: |
| 172 | write16be(Loc, applyPPCHi(Val)); | 419 | case R_PPC64_TPREL16_HI: |
| 420 | write16(Loc, hi(Val)); | ||
| 173 | break; | 421 | break; |
| 174 | case R_PPC64_ADDR16_HIGHER: | 422 | case R_PPC64_ADDR16_HIGHER: |
| 175 | write16be(Loc, applyPPCHigher(Val)); | 423 | case R_PPC64_TPREL16_HIGHER: |
| 424 | write16(Loc, higher(Val)); | ||
| 176 | break; | 425 | break; |
| 177 | case R_PPC64_ADDR16_HIGHERA: | 426 | case R_PPC64_ADDR16_HIGHERA: |
| 178 | write16be(Loc, applyPPCHighera(Val)); | 427 | case R_PPC64_TPREL16_HIGHERA: |
| 428 | write16(Loc, highera(Val)); | ||
| 179 | break; | 429 | break; |
| 180 | case R_PPC64_ADDR16_HIGHEST: | 430 | case R_PPC64_ADDR16_HIGHEST: |
| 181 | write16be(Loc, applyPPCHighest(Val)); | 431 | case R_PPC64_TPREL16_HIGHEST: |
| 432 | write16(Loc, highest(Val)); | ||
| 182 | break; | 433 | break; |
| 183 | case R_PPC64_ADDR16_HIGHESTA: | 434 | case R_PPC64_ADDR16_HIGHESTA: |
| 184 | write16be(Loc, applyPPCHighesta(Val)); | 435 | case R_PPC64_TPREL16_HIGHESTA: |
| 436 | write16(Loc, highesta(Val)); | ||
| 185 | break; | 437 | break; |
| 186 | case R_PPC64_ADDR16_LO: | 438 | case R_PPC64_ADDR16_LO: |
| 187 | write16be(Loc, applyPPCLo(Val)); | 439 | case R_PPC64_REL16_LO: |
| 440 | case R_PPC64_TPREL16_LO: | ||
| 441 | write16(Loc, lo(Val)); | ||
| 188 | break; | 442 | break; |
| 189 | case R_PPC64_ADDR16_LO_DS: | 443 | case R_PPC64_ADDR16_LO_DS: |
| 190 | case R_PPC64_REL16_LO: | 444 | case R_PPC64_TPREL16_LO_DS: |
| 191 | write16be(Loc, (read16be(Loc) & 3) | (applyPPCLo(Val) & ~3)); | 445 | write16(Loc, (read16(Loc) & 3) | (lo(Val) & ~3)); |
| 192 | break; | 446 | break; |
| 193 | case R_PPC64_ADDR32: | 447 | case R_PPC64_ADDR32: |
| 194 | case R_PPC64_REL32: | 448 | case R_PPC64_REL32: |
| 195 | checkInt<32>(Loc, Val, Type); | 449 | checkInt(Loc, Val, 32, Type); |
| 196 | write32be(Loc, Val); | 450 | write32(Loc, Val); |
| 197 | break; | 451 | break; |
| 198 | case R_PPC64_ADDR64: | 452 | case R_PPC64_ADDR64: |
| 199 | case R_PPC64_REL64: | 453 | case R_PPC64_REL64: |
| 200 | case R_PPC64_TOC: | 454 | case R_PPC64_TOC: |
| 201 | write64be(Loc, Val); | 455 | write64(Loc, Val); |
| 202 | break; | 456 | break; |
| 203 | case R_PPC64_REL24: { | 457 | case R_PPC64_REL24: { |
| 204 | uint32_t Mask = 0x03FFFFFC; | 458 | uint32_t Mask = 0x03FFFFFC; |
| 205 | checkInt<24>(Loc, Val, Type); | 459 | checkInt(Loc, Val, 24, Type); |
| 206 | write32be(Loc, (read32be(Loc) & ~Mask) | (Val & Mask)); | 460 | write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask)); |
| 207 | break; | 461 | break; |
| 208 | } | 462 | } |
| 463 | case R_PPC64_DTPREL64: | ||
| 464 | write64(Loc, Val - DynamicThreadPointerOffset); | ||
| 465 | break; | ||
| 209 | default: | 466 | default: |
| 210 | error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); | 467 | error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); |
| 211 | } | 468 | } |
| 212 | } | 469 | } |
| 213 | 470 | ||
| 471 | bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | ||
| 472 | uint64_t BranchAddr, const Symbol &S) const { | ||
| 473 | // If a function is in the plt it needs to be called through | ||
| 474 | // a call stub. | ||
| 475 | return Type == R_PPC64_REL24 && S.isInPlt(); | ||
| 476 | } | ||
| 477 | |||
| 478 | RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data, | ||
| 479 | RelExpr Expr) const { | ||
| 480 | if (Expr == R_RELAX_TLS_GD_TO_IE) | ||
| 481 | return R_RELAX_TLS_GD_TO_IE_GOT_OFF; | ||
| 482 | if (Expr == R_RELAX_TLS_LD_TO_LE) | ||
| 483 | return R_RELAX_TLS_LD_TO_LE_ABS; | ||
| 484 | return Expr; | ||
| 485 | } | ||
| 486 | |||
| 487 | // Reference: 3.7.4.1 of the 64-bit ELF V2 abi supplement. | ||
| 488 | // The general dynamic code sequence for a global `x` uses 4 instructions. | ||
| 489 | // Instruction Relocation Symbol | ||
| 490 | // addis r3, r2, x@got@tlsgd@ha R_PPC64_GOT_TLSGD16_HA x | ||
| 491 | // addi r3, r3, x@got@tlsgd@l R_PPC64_GOT_TLSGD16_LO x | ||
| 492 | // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSGD x | ||
| 493 | // R_PPC64_REL24 __tls_get_addr | ||
| 494 | // nop None None | ||
| 495 | // | ||
| 496 | // Relaxing to initial-exec entails: | ||
| 497 | // 1) Convert the addis/addi pair that builds the address of the tls_index | ||
| 498 | // struct for 'x' to an addis/ld pair that loads an offset from a got-entry. | ||
| 499 | // 2) Convert the call to __tls_get_addr to a nop. | ||
| 500 | // 3) Convert the nop following the call to an add of the loaded offset to the | ||
| 501 | // thread pointer. | ||
| 502 | // Since the nop must directly follow the call, the R_PPC64_TLSGD relocation is | ||
| 503 | // used as the relaxation hint for both steps 2 and 3. | ||
| 504 | void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const { | ||
| 505 | switch (Type) { | ||
| 506 | case R_PPC64_GOT_TLSGD16_HA: | ||
| 507 | // This is relaxed from addis rT, r2, sym@got@tlsgd@ha to | ||
| 508 | // addis rT, r2, sym@got@tprel@ha. | ||
| 509 | relocateOne(Loc, R_PPC64_GOT_TPREL16_HA, Val); | ||
| 510 | return; | ||
| 511 | case R_PPC64_GOT_TLSGD16_LO: { | ||
| 512 | // Relax from addi r3, rA, sym@got@tlsgd@l to | ||
| 513 | // ld r3, sym@got@tprel@l(rA) | ||
| 514 | uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U; | ||
| 515 | uint32_t InputRegister = (read32(Loc - EndianOffset) & (0x1f << 16)); | ||
| 516 | write32(Loc - EndianOffset, 0xE8600000 | InputRegister); | ||
| 517 | relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val); | ||
| 518 | return; | ||
| 519 | } | ||
| 520 | case R_PPC64_TLSGD: | ||
| 521 | write32(Loc, 0x60000000); // bl __tls_get_addr(sym@tlsgd) --> nop | ||
| 522 | write32(Loc + 4, 0x7c636A14); // nop --> add r3, r3, r13 | ||
| 523 | return; | ||
| 524 | default: | ||
| 525 | llvm_unreachable("unsupported relocation for TLS GD to IE relaxation"); | ||
| 526 | } | ||
| 527 | } | ||
| 528 | |||
| 214 | TargetInfo *elf::getPPC64TargetInfo() { | 529 | TargetInfo *elf::getPPC64TargetInfo() { |
| 215 | static PPC64 Target; | 530 | static PPC64 Target; |
| 216 | return &Target; | 531 | return &Target; |
deps/lld/ELF/Arch/SPARCV9.cpp+6-6| ... | @@ -77,23 +77,23 @@ void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -77,23 +77,23 @@ void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 77 | case R_SPARC_32: | 77 | case R_SPARC_32: |
| 78 | case R_SPARC_UA32: | 78 | case R_SPARC_UA32: |
| 79 | // V-word32 | 79 | // V-word32 |
| 80 | checkUInt<32>(Loc, Val, Type); | 80 | checkUInt(Loc, Val, 32, Type); |
| 81 | write32be(Loc, Val); | 81 | write32be(Loc, Val); |
| 82 | break; | 82 | break; |
| 83 | case R_SPARC_DISP32: | 83 | case R_SPARC_DISP32: |
| 84 | // V-disp32 | 84 | // V-disp32 |
| 85 | checkInt<32>(Loc, Val, Type); | 85 | checkInt(Loc, Val, 32, Type); |
| 86 | write32be(Loc, Val); | 86 | write32be(Loc, Val); |
| 87 | break; | 87 | break; |
| 88 | case R_SPARC_WDISP30: | 88 | case R_SPARC_WDISP30: |
| 89 | case R_SPARC_WPLT30: | 89 | case R_SPARC_WPLT30: |
| 90 | // V-disp30 | 90 | // V-disp30 |
| 91 | checkInt<32>(Loc, Val, Type); | 91 | checkInt(Loc, Val, 32, Type); |
| 92 | write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff)); | 92 | write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff)); |
| 93 | break; | 93 | break; |
| 94 | case R_SPARC_22: | 94 | case R_SPARC_22: |
| 95 | // V-imm22 | 95 | // V-imm22 |
| 96 | checkUInt<22>(Loc, Val, Type); | 96 | checkUInt(Loc, Val, 22, Type); |
| 97 | write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff)); | 97 | write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff)); |
| 98 | break; | 98 | break; |
| 99 | case R_SPARC_GOT22: | 99 | case R_SPARC_GOT22: |
| ... | @@ -103,7 +103,7 @@ void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -103,7 +103,7 @@ void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 103 | break; | 103 | break; |
| 104 | case R_SPARC_WDISP19: | 104 | case R_SPARC_WDISP19: |
| 105 | // V-disp19 | 105 | // V-disp19 |
| 106 | checkInt<21>(Loc, Val, Type); | 106 | checkInt(Loc, Val, 21, Type); |
| 107 | write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff)); | 107 | write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff)); |
| 108 | break; | 108 | break; |
| 109 | case R_SPARC_GOT10: | 109 | case R_SPARC_GOT10: |
| ... | @@ -137,7 +137,7 @@ void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, | ... | @@ -137,7 +137,7 @@ void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, |
| 137 | }; | 137 | }; |
| 138 | memcpy(Buf, PltData, sizeof(PltData)); | 138 | memcpy(Buf, PltData, sizeof(PltData)); |
| 139 | 139 | ||
| 140 | uint64_t Off = PltHeaderSize + Index * PltEntrySize; | 140 | uint64_t Off = getPltEntryOffset(Index); |
| 141 | relocateOne(Buf, R_SPARC_22, Off); | 141 | relocateOne(Buf, R_SPARC_22, Off); |
| 142 | relocateOne(Buf + 4, R_SPARC_WDISP19, -(Off + 4 - PltEntrySize)); | 142 | relocateOne(Buf + 4, R_SPARC_WDISP19, -(Off + 4 - PltEntrySize)); |
| 143 | } | 143 | } |
deps/lld/ELF/Arch/X86.cpp+35-29| ... | @@ -46,7 +46,6 @@ public: | ... | @@ -46,7 +46,6 @@ public: |
| 46 | } // namespace | 46 | } // namespace |
| 47 | 47 | ||
| 48 | X86::X86() { | 48 | X86::X86() { |
| 49 | GotBaseSymOff = -1; | ||
| 50 | CopyRel = R_386_COPY; | 49 | CopyRel = R_386_COPY; |
| 51 | GotRel = R_386_GLOB_DAT; | 50 | GotRel = R_386_GLOB_DAT; |
| 52 | PltRel = R_386_JUMP_SLOT; | 51 | PltRel = R_386_JUMP_SLOT; |
| ... | @@ -74,9 +73,9 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -74,9 +73,9 @@ RelExpr X86::getRelExpr(RelType Type, const Symbol &S, |
| 74 | case R_386_TLS_LDO_32: | 73 | case R_386_TLS_LDO_32: |
| 75 | return R_ABS; | 74 | return R_ABS; |
| 76 | case R_386_TLS_GD: | 75 | case R_386_TLS_GD: |
| 77 | return R_TLSGD; | 76 | return R_TLSGD_GOT_FROM_END; |
| 78 | case R_386_TLS_LDM: | 77 | case R_386_TLS_LDM: |
| 79 | return R_TLSLD; | 78 | return R_TLSLD_GOT_FROM_END; |
| 80 | case R_386_PLT32: | 79 | case R_386_PLT32: |
| 81 | return R_PLT_PC; | 80 | return R_PLT_PC; |
| 82 | case R_386_PC8: | 81 | case R_386_PC8: |
| ... | @@ -224,7 +223,7 @@ void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ... | @@ -224,7 +223,7 @@ void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 224 | } | 223 | } |
| 225 | 224 | ||
| 226 | write32le(Buf + 7, RelOff); | 225 | write32le(Buf + 7, RelOff); |
| 227 | write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16); | 226 | write32le(Buf + 12, -getPltEntryOffset(Index) - 16); |
| 228 | } | 227 | } |
| 229 | 228 | ||
| 230 | int64_t X86::getImplicitAddend(const uint8_t *Buf, RelType Type) const { | 229 | int64_t X86::getImplicitAddend(const uint8_t *Buf, RelType Type) const { |
| ... | @@ -256,15 +255,15 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -256,15 +255,15 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 256 | // R_386_{PC,}{8,16} are not part of the i386 psABI, but they are | 255 | // R_386_{PC,}{8,16} are not part of the i386 psABI, but they are |
| 257 | // being used for some 16-bit programs such as boot loaders, so | 256 | // being used for some 16-bit programs such as boot loaders, so |
| 258 | // we want to support them. | 257 | // we want to support them. |
| 259 | checkUInt<8>(Loc, Val, Type); | 258 | checkIntUInt(Loc, Val, 8, Type); |
| 260 | *Loc = Val; | 259 | *Loc = Val; |
| 261 | break; | 260 | break; |
| 262 | case R_386_PC8: | 261 | case R_386_PC8: |
| 263 | checkInt<8>(Loc, Val, Type); | 262 | checkInt(Loc, Val, 8, Type); |
| 264 | *Loc = Val; | 263 | *Loc = Val; |
| 265 | break; | 264 | break; |
| 266 | case R_386_16: | 265 | case R_386_16: |
| 267 | checkUInt<16>(Loc, Val, Type); | 266 | checkIntUInt(Loc, Val, 16, Type); |
| 268 | write16le(Loc, Val); | 267 | write16le(Loc, Val); |
| 269 | break; | 268 | break; |
| 270 | case R_386_PC16: | 269 | case R_386_PC16: |
| ... | @@ -278,7 +277,7 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -278,7 +277,7 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 278 | // current location subtracted from it. | 277 | // current location subtracted from it. |
| 279 | // We just check that Val fits in 17 bits. This misses some cases, but | 278 | // We just check that Val fits in 17 bits. This misses some cases, but |
| 280 | // should have no false positives. | 279 | // should have no false positives. |
| 281 | checkInt<17>(Loc, Val, Type); | 280 | checkInt(Loc, Val, 17, Type); |
| 282 | write16le(Loc, Val); | 281 | write16le(Loc, Val); |
| 283 | break; | 282 | break; |
| 284 | case R_386_32: | 283 | case R_386_32: |
| ... | @@ -301,7 +300,7 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -301,7 +300,7 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 301 | case R_386_TLS_LE_32: | 300 | case R_386_TLS_LE_32: |
| 302 | case R_386_TLS_TPOFF: | 301 | case R_386_TLS_TPOFF: |
| 303 | case R_386_TLS_TPOFF32: | 302 | case R_386_TLS_TPOFF32: |
| 304 | checkInt<32>(Loc, Val, Type); | 303 | checkInt(Loc, Val, 32, Type); |
| 305 | write32le(Loc, Val); | 304 | write32le(Loc, Val); |
| 306 | break; | 305 | break; |
| 307 | default: | 306 | default: |
| ... | @@ -444,6 +443,7 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const { | ... | @@ -444,6 +443,7 @@ void RetpolinePic::writePltHeader(uint8_t *Buf) const { |
| 444 | 0x89, 0xc8, // 2b: mov %ecx, %eax | 443 | 0x89, 0xc8, // 2b: mov %ecx, %eax |
| 445 | 0x59, // 2d: pop %ecx | 444 | 0x59, // 2d: pop %ecx |
| 446 | 0xc3, // 2e: ret | 445 | 0xc3, // 2e: ret |
| 446 | 0xcc, // 2f: int3; padding | ||
| 447 | }; | 447 | }; |
| 448 | memcpy(Buf, Insn, sizeof(Insn)); | 448 | memcpy(Buf, Insn, sizeof(Insn)); |
| 449 | 449 | ||
| ... | @@ -457,21 +457,23 @@ void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ... | @@ -457,21 +457,23 @@ void RetpolinePic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 457 | uint64_t PltEntryAddr, int32_t Index, | 457 | uint64_t PltEntryAddr, int32_t Index, |
| 458 | unsigned RelOff) const { | 458 | unsigned RelOff) const { |
| 459 | const uint8_t Insn[] = { | 459 | const uint8_t Insn[] = { |
| 460 | 0x50, // pushl %eax | 460 | 0x50, // pushl %eax |
| 461 | 0x8b, 0x83, 0, 0, 0, 0, // mov foo@GOT(%ebx), %eax | 461 | 0x8b, 0x83, 0, 0, 0, 0, // mov foo@GOT(%ebx), %eax |
| 462 | 0xe8, 0, 0, 0, 0, // call plt+0x20 | 462 | 0xe8, 0, 0, 0, 0, // call plt+0x20 |
| 463 | 0xe9, 0, 0, 0, 0, // jmp plt+0x12 | 463 | 0xe9, 0, 0, 0, 0, // jmp plt+0x12 |
| 464 | 0x68, 0, 0, 0, 0, // pushl $reloc_offset | 464 | 0x68, 0, 0, 0, 0, // pushl $reloc_offset |
| 465 | 0xe9, 0, 0, 0, 0, // jmp plt+0 | 465 | 0xe9, 0, 0, 0, 0, // jmp plt+0 |
| 466 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // int3; padding | ||
| 466 | }; | 467 | }; |
| 467 | memcpy(Buf, Insn, sizeof(Insn)); | 468 | memcpy(Buf, Insn, sizeof(Insn)); |
| 468 | 469 | ||
| 469 | uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); | 470 | uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize(); |
| 471 | unsigned Off = getPltEntryOffset(Index); | ||
| 470 | write32le(Buf + 3, GotPltEntryAddr - Ebx); | 472 | write32le(Buf + 3, GotPltEntryAddr - Ebx); |
| 471 | write32le(Buf + 8, -Index * PltEntrySize - PltHeaderSize - 12 + 32); | 473 | write32le(Buf + 8, -Off - 12 + 32); |
| 472 | write32le(Buf + 13, -Index * PltEntrySize - PltHeaderSize - 17 + 18); | 474 | write32le(Buf + 13, -Off - 17 + 18); |
| 473 | write32le(Buf + 18, RelOff); | 475 | write32le(Buf + 18, RelOff); |
| 474 | write32le(Buf + 23, -Index * PltEntrySize - PltHeaderSize - 27); | 476 | write32le(Buf + 23, -Off - 27); |
| 475 | } | 477 | } |
| 476 | 478 | ||
| 477 | RetpolineNoPic::RetpolineNoPic() { | 479 | RetpolineNoPic::RetpolineNoPic() { |
| ... | @@ -484,7 +486,7 @@ void RetpolineNoPic::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | ... | @@ -484,7 +486,7 @@ void RetpolineNoPic::writeGotPlt(uint8_t *Buf, const Symbol &S) const { |
| 484 | } | 486 | } |
| 485 | 487 | ||
| 486 | void RetpolineNoPic::writePltHeader(uint8_t *Buf) const { | 488 | void RetpolineNoPic::writePltHeader(uint8_t *Buf) const { |
| 487 | const uint8_t PltData[] = { | 489 | const uint8_t Insn[] = { |
| 488 | 0xff, 0x35, 0, 0, 0, 0, // 0: pushl GOTPLT+4 | 490 | 0xff, 0x35, 0, 0, 0, 0, // 0: pushl GOTPLT+4 |
| 489 | 0x50, // 6: pushl %eax | 491 | 0x50, // 6: pushl %eax |
| 490 | 0xa1, 0, 0, 0, 0, // 7: mov GOTPLT+8, %eax | 492 | 0xa1, 0, 0, 0, 0, // 7: mov GOTPLT+8, %eax |
| ... | @@ -500,8 +502,9 @@ void RetpolineNoPic::writePltHeader(uint8_t *Buf) const { | ... | @@ -500,8 +502,9 @@ void RetpolineNoPic::writePltHeader(uint8_t *Buf) const { |
| 500 | 0x89, 0xc8, // 2b: mov %ecx, %eax | 502 | 0x89, 0xc8, // 2b: mov %ecx, %eax |
| 501 | 0x59, // 2d: pop %ecx | 503 | 0x59, // 2d: pop %ecx |
| 502 | 0xc3, // 2e: ret | 504 | 0xc3, // 2e: ret |
| 505 | 0xcc, // 2f: int3; padding | ||
| 503 | }; | 506 | }; |
| 504 | memcpy(Buf, PltData, sizeof(PltData)); | 507 | memcpy(Buf, Insn, sizeof(Insn)); |
| 505 | 508 | ||
| 506 | uint32_t GotPlt = InX::GotPlt->getVA(); | 509 | uint32_t GotPlt = InX::GotPlt->getVA(); |
| 507 | write32le(Buf + 2, GotPlt + 4); | 510 | write32le(Buf + 2, GotPlt + 4); |
| ... | @@ -512,20 +515,23 @@ void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ... | @@ -512,20 +515,23 @@ void RetpolineNoPic::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 512 | uint64_t PltEntryAddr, int32_t Index, | 515 | uint64_t PltEntryAddr, int32_t Index, |
| 513 | unsigned RelOff) const { | 516 | unsigned RelOff) const { |
| 514 | const uint8_t Insn[] = { | 517 | const uint8_t Insn[] = { |
| 515 | 0x50, // 0: pushl %eax | 518 | 0x50, // 0: pushl %eax |
| 516 | 0xa1, 0, 0, 0, 0, // 1: mov foo_in_GOT, %eax | 519 | 0xa1, 0, 0, 0, 0, // 1: mov foo_in_GOT, %eax |
| 517 | 0xe8, 0, 0, 0, 0, // 6: call plt+0x20 | 520 | 0xe8, 0, 0, 0, 0, // 6: call plt+0x20 |
| 518 | 0xe9, 0, 0, 0, 0, // b: jmp plt+0x11 | 521 | 0xe9, 0, 0, 0, 0, // b: jmp plt+0x11 |
| 519 | 0x68, 0, 0, 0, 0, // 10: pushl $reloc_offset | 522 | 0x68, 0, 0, 0, 0, // 10: pushl $reloc_offset |
| 520 | 0xe9, 0, 0, 0, 0, // 15: jmp plt+0 | 523 | 0xe9, 0, 0, 0, 0, // 15: jmp plt+0 |
| 524 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1a: int3; padding | ||
| 525 | 0xcc, // 1f: int3; padding | ||
| 521 | }; | 526 | }; |
| 522 | memcpy(Buf, Insn, sizeof(Insn)); | 527 | memcpy(Buf, Insn, sizeof(Insn)); |
| 523 | 528 | ||
| 529 | unsigned Off = getPltEntryOffset(Index); | ||
| 524 | write32le(Buf + 2, GotPltEntryAddr); | 530 | write32le(Buf + 2, GotPltEntryAddr); |
| 525 | write32le(Buf + 7, -Index * PltEntrySize - PltHeaderSize - 11 + 32); | 531 | write32le(Buf + 7, -Off - 11 + 32); |
| 526 | write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16 + 17); | 532 | write32le(Buf + 12, -Off - 16 + 17); |
| 527 | write32le(Buf + 17, RelOff); | 533 | write32le(Buf + 17, RelOff); |
| 528 | write32le(Buf + 22, -Index * PltEntrySize - PltHeaderSize - 26); | 534 | write32le(Buf + 22, -Off - 26); |
| 529 | } | 535 | } |
| 530 | 536 | ||
| 531 | TargetInfo *elf::getX86TargetInfo() { | 537 | TargetInfo *elf::getX86TargetInfo() { |
deps/lld/ELF/Arch/X86_64.cpp+88-22| ... | @@ -28,7 +28,7 @@ public: | ... | @@ -28,7 +28,7 @@ public: |
| 28 | X86_64(); | 28 | X86_64(); |
| 29 | RelExpr getRelExpr(RelType Type, const Symbol &S, | 29 | RelExpr getRelExpr(RelType Type, const Symbol &S, |
| 30 | const uint8_t *Loc) const override; | 30 | const uint8_t *Loc) const override; |
| 31 | bool isPicRel(RelType Type) const override; | 31 | RelType getDynRel(RelType Type) const override; |
| 32 | void writeGotPltHeader(uint8_t *Buf) const override; | 32 | void writeGotPltHeader(uint8_t *Buf) const override; |
| 33 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; | 33 | void writeGotPlt(uint8_t *Buf, const Symbol &S) const override; |
| 34 | void writePltHeader(uint8_t *Buf) const override; | 34 | void writePltHeader(uint8_t *Buf) const override; |
| ... | @@ -43,6 +43,8 @@ public: | ... | @@ -43,6 +43,8 @@ public: |
| 43 | void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | 43 | void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; |
| 44 | void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | 44 | void relaxTlsIeToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; |
| 45 | void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; | 45 | void relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override; |
| 46 | bool adjustPrologueForCrossSplitStack(uint8_t *Loc, | ||
| 47 | uint8_t *End) const override; | ||
| 46 | 48 | ||
| 47 | private: | 49 | private: |
| 48 | void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op, | 50 | void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op, |
| ... | @@ -51,7 +53,6 @@ private: | ... | @@ -51,7 +53,6 @@ private: |
| 51 | } // namespace | 53 | } // namespace |
| 52 | 54 | ||
| 53 | template <class ELFT> X86_64<ELFT>::X86_64() { | 55 | template <class ELFT> X86_64<ELFT>::X86_64() { |
| 54 | GotBaseSymOff = -1; | ||
| 55 | CopyRel = R_X86_64_COPY; | 56 | CopyRel = R_X86_64_COPY; |
| 56 | GotRel = R_X86_64_GLOB_DAT; | 57 | GotRel = R_X86_64_GLOB_DAT; |
| 57 | PltRel = R_X86_64_JUMP_SLOT; | 58 | PltRel = R_X86_64_JUMP_SLOT; |
| ... | @@ -106,6 +107,11 @@ RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S, | ... | @@ -106,6 +107,11 @@ RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S, |
| 106 | case R_X86_64_REX_GOTPCRELX: | 107 | case R_X86_64_REX_GOTPCRELX: |
| 107 | case R_X86_64_GOTTPOFF: | 108 | case R_X86_64_GOTTPOFF: |
| 108 | return R_GOT_PC; | 109 | return R_GOT_PC; |
| 110 | case R_X86_64_GOTOFF64: | ||
| 111 | return R_GOTREL_FROM_END; | ||
| 112 | case R_X86_64_GOTPC32: | ||
| 113 | case R_X86_64_GOTPC64: | ||
| 114 | return R_GOTONLY_PC_FROM_END; | ||
| 109 | case R_X86_64_NONE: | 115 | case R_X86_64_NONE: |
| 110 | return R_NONE; | 116 | return R_NONE; |
| 111 | default: | 117 | default: |
| ... | @@ -124,7 +130,7 @@ template <class ELFT> void X86_64<ELFT>::writeGotPltHeader(uint8_t *Buf) const { | ... | @@ -124,7 +130,7 @@ template <class ELFT> void X86_64<ELFT>::writeGotPltHeader(uint8_t *Buf) const { |
| 124 | template <class ELFT> | 130 | template <class ELFT> |
| 125 | void X86_64<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | 131 | void X86_64<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const { |
| 126 | // See comments in X86::writeGotPlt. | 132 | // See comments in X86::writeGotPlt. |
| 127 | write32le(Buf, S.getPltVA() + 6); | 133 | write64le(Buf, S.getPltVA() + 6); |
| 128 | } | 134 | } |
| 129 | 135 | ||
| 130 | template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const { | 136 | template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const { |
| ... | @@ -153,12 +159,14 @@ void X86_64<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ... | @@ -153,12 +159,14 @@ void X86_64<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 153 | 159 | ||
| 154 | write32le(Buf + 2, GotPltEntryAddr - PltEntryAddr - 6); | 160 | write32le(Buf + 2, GotPltEntryAddr - PltEntryAddr - 6); |
| 155 | write32le(Buf + 7, Index); | 161 | write32le(Buf + 7, Index); |
| 156 | write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16); | 162 | write32le(Buf + 12, -getPltEntryOffset(Index) - 16); |
| 157 | } | 163 | } |
| 158 | 164 | ||
| 159 | template <class ELFT> bool X86_64<ELFT>::isPicRel(RelType Type) const { | 165 | template <class ELFT> RelType X86_64<ELFT>::getDynRel(RelType Type) const { |
| 160 | return Type != R_X86_64_PC32 && Type != R_X86_64_32 && | 166 | if (Type == R_X86_64_64 || Type == R_X86_64_PC64 || Type == R_X86_64_SIZE32 || |
| 161 | Type != R_X86_64_TPOFF32; | 167 | Type == R_X86_64_SIZE64) |
| 168 | return Type; | ||
| 169 | return R_X86_64_NONE; | ||
| 162 | } | 170 | } |
| 163 | 171 | ||
| 164 | template <class ELFT> | 172 | template <class ELFT> |
| ... | @@ -285,20 +293,21 @@ template <class ELFT> | ... | @@ -285,20 +293,21 @@ template <class ELFT> |
| 285 | void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | 293 | void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 286 | switch (Type) { | 294 | switch (Type) { |
| 287 | case R_X86_64_8: | 295 | case R_X86_64_8: |
| 288 | checkUInt<8>(Loc, Val, Type); | 296 | checkUInt(Loc, Val, 8, Type); |
| 289 | *Loc = Val; | 297 | *Loc = Val; |
| 290 | break; | 298 | break; |
| 291 | case R_X86_64_16: | 299 | case R_X86_64_16: |
| 292 | checkUInt<16>(Loc, Val, Type); | 300 | checkUInt(Loc, Val, 16, Type); |
| 293 | write16le(Loc, Val); | 301 | write16le(Loc, Val); |
| 294 | break; | 302 | break; |
| 295 | case R_X86_64_32: | 303 | case R_X86_64_32: |
| 296 | checkUInt<32>(Loc, Val, Type); | 304 | checkUInt(Loc, Val, 32, Type); |
| 297 | write32le(Loc, Val); | 305 | write32le(Loc, Val); |
| 298 | break; | 306 | break; |
| 299 | case R_X86_64_32S: | 307 | case R_X86_64_32S: |
| 300 | case R_X86_64_TPOFF32: | 308 | case R_X86_64_TPOFF32: |
| 301 | case R_X86_64_GOT32: | 309 | case R_X86_64_GOT32: |
| 310 | case R_X86_64_GOTPC32: | ||
| 302 | case R_X86_64_GOTPCREL: | 311 | case R_X86_64_GOTPCREL: |
| 303 | case R_X86_64_GOTPCRELX: | 312 | case R_X86_64_GOTPCRELX: |
| 304 | case R_X86_64_REX_GOTPCRELX: | 313 | case R_X86_64_REX_GOTPCRELX: |
| ... | @@ -309,7 +318,7 @@ void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -309,7 +318,7 @@ void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 309 | case R_X86_64_TLSLD: | 318 | case R_X86_64_TLSLD: |
| 310 | case R_X86_64_DTPOFF32: | 319 | case R_X86_64_DTPOFF32: |
| 311 | case R_X86_64_SIZE32: | 320 | case R_X86_64_SIZE32: |
| 312 | checkInt<32>(Loc, Val, Type); | 321 | checkInt(Loc, Val, 32, Type); |
| 313 | write32le(Loc, Val); | 322 | write32le(Loc, Val); |
| 314 | break; | 323 | break; |
| 315 | case R_X86_64_64: | 324 | case R_X86_64_64: |
| ... | @@ -318,6 +327,8 @@ void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { | ... | @@ -318,6 +327,8 @@ void X86_64<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { |
| 318 | case R_X86_64_PC64: | 327 | case R_X86_64_PC64: |
| 319 | case R_X86_64_SIZE64: | 328 | case R_X86_64_SIZE64: |
| 320 | case R_X86_64_GOT64: | 329 | case R_X86_64_GOT64: |
| 330 | case R_X86_64_GOTOFF64: | ||
| 331 | case R_X86_64_GOTPC64: | ||
| 321 | write64le(Loc, Val); | 332 | write64le(Loc, Val); |
| 322 | break; | 333 | break; |
| 323 | default: | 334 | default: |
| ... | @@ -460,6 +471,55 @@ void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const { | ... | @@ -460,6 +471,55 @@ void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const { |
| 460 | write32le(Loc - 1, Val + 1); | 471 | write32le(Loc - 1, Val + 1); |
| 461 | } | 472 | } |
| 462 | 473 | ||
| 474 | // This anonymous namespace works around a warning bug in | ||
| 475 | // old versions of gcc. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480 | ||
| 476 | namespace { | ||
| 477 | |||
| 478 | // A split-stack prologue starts by checking the amount of stack remaining | ||
| 479 | // in one of two ways: | ||
| 480 | // A) Comparing of the stack pointer to a field in the tcb. | ||
| 481 | // B) Or a load of a stack pointer offset with an lea to r10 or r11. | ||
| 482 | template <> | ||
| 483 | bool X86_64<ELF64LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc, | ||
| 484 | uint8_t *End) const { | ||
| 485 | // Replace "cmp %fs:0x70,%rsp" and subsequent branch | ||
| 486 | // with "stc, nopl 0x0(%rax,%rax,1)" | ||
| 487 | if (Loc + 8 < End && memcmp(Loc, "\x64\x48\x3b\x24\x25", 4) == 0) { | ||
| 488 | memcpy(Loc, "\xf9\x0f\x1f\x84\x00\x00\x00\x00", 8); | ||
| 489 | return true; | ||
| 490 | } | ||
| 491 | |||
| 492 | // Adjust "lea -0x200(%rsp),%r10" to lea "-0x4200(%rsp),%r10" | ||
| 493 | if (Loc + 7 < End && memcmp(Loc, "\x4c\x8d\x94\x24\x00\xfe\xff", 7) == 0) { | ||
| 494 | memcpy(Loc, "\x4c\x8d\x94\x24\x00\xbe\xff", 7); | ||
| 495 | return true; | ||
| 496 | } | ||
| 497 | |||
| 498 | // Adjust "lea -0x200(%rsp),%r11" to lea "-0x4200(%rsp),%r11" | ||
| 499 | if (Loc + 7 < End && memcmp(Loc, "\x4c\x8d\x9c\x24\x00\xfe\xff", 7) == 0) { | ||
| 500 | memcpy(Loc, "\x4c\x8d\x9c\x24\x00\xbe\xff", 7); | ||
| 501 | return true; | ||
| 502 | } | ||
| 503 | return false; | ||
| 504 | } | ||
| 505 | |||
| 506 | template <> | ||
| 507 | bool X86_64<ELF32LE>::adjustPrologueForCrossSplitStack(uint8_t *Loc, | ||
| 508 | uint8_t *End) const { | ||
| 509 | llvm_unreachable("Target doesn't support split stacks."); | ||
| 510 | } | ||
| 511 | |||
| 512 | } // namespace | ||
| 513 | |||
| 514 | // These nonstandard PLT entries are to migtigate Spectre v2 security | ||
| 515 | // vulnerability. In order to mitigate Spectre v2, we want to avoid indirect | ||
| 516 | // branch instructions such as `jmp *GOTPLT(%rip)`. So, in the following PLT | ||
| 517 | // entries, we use a CALL followed by MOV and RET to do the same thing as an | ||
| 518 | // indirect jump. That instruction sequence is so-called "retpoline". | ||
| 519 | // | ||
| 520 | // We have two types of retpoline PLTs as a size optimization. If `-z now` | ||
| 521 | // is specified, all dynamic symbols are resolved at load-time. Thus, when | ||
| 522 | // that option is given, we can omit code for symbol lazy resolution. | ||
| 463 | namespace { | 523 | namespace { |
| 464 | template <class ELFT> class Retpoline : public X86_64<ELFT> { | 524 | template <class ELFT> class Retpoline : public X86_64<ELFT> { |
| 465 | public: | 525 | public: |
| ... | @@ -487,7 +547,7 @@ template <class ELFT> Retpoline<ELFT>::Retpoline() { | ... | @@ -487,7 +547,7 @@ template <class ELFT> Retpoline<ELFT>::Retpoline() { |
| 487 | 547 | ||
| 488 | template <class ELFT> | 548 | template <class ELFT> |
| 489 | void Retpoline<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const { | 549 | void Retpoline<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &S) const { |
| 490 | write32le(Buf, S.getPltVA() + 17); | 550 | write64le(Buf, S.getPltVA() + 17); |
| 491 | } | 551 | } |
| 492 | 552 | ||
| 493 | template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const { | 553 | template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const { |
| ... | @@ -501,6 +561,8 @@ template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const { | ... | @@ -501,6 +561,8 @@ template <class ELFT> void Retpoline<ELFT>::writePltHeader(uint8_t *Buf) const { |
| 501 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 19: int3; .align 16 | 561 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 19: int3; .align 16 |
| 502 | 0x4c, 0x89, 0x1c, 0x24, // 20: next: mov %r11, (%rsp) | 562 | 0x4c, 0x89, 0x1c, 0x24, // 20: next: mov %r11, (%rsp) |
| 503 | 0xc3, // 24: ret | 563 | 0xc3, // 24: ret |
| 564 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 25: int3; padding | ||
| 565 | 0xcc, 0xcc, 0xcc, 0xcc, // 2c: int3; padding | ||
| 504 | }; | 566 | }; |
| 505 | memcpy(Buf, Insn, sizeof(Insn)); | 567 | memcpy(Buf, Insn, sizeof(Insn)); |
| 506 | 568 | ||
| ... | @@ -516,14 +578,15 @@ void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ... | @@ -516,14 +578,15 @@ void Retpoline<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 516 | unsigned RelOff) const { | 578 | unsigned RelOff) const { |
| 517 | const uint8_t Insn[] = { | 579 | const uint8_t Insn[] = { |
| 518 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0: mov foo@GOTPLT(%rip), %r11 | 580 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // 0: mov foo@GOTPLT(%rip), %r11 |
| 519 | 0xe8, 0, 0, 0, 0, // 7: callq plt+0x20 | 581 | 0xe8, 0, 0, 0, 0, // 7: callq plt+0x20 |
| 520 | 0xe9, 0, 0, 0, 0, // c: jmp plt+0x12 | 582 | 0xe9, 0, 0, 0, 0, // c: jmp plt+0x12 |
| 521 | 0x68, 0, 0, 0, 0, // 11: pushq <relocation index> | 583 | 0x68, 0, 0, 0, 0, // 11: pushq <relocation index> |
| 522 | 0xe9, 0, 0, 0, 0, // 16: jmp plt+0 | 584 | 0xe9, 0, 0, 0, 0, // 16: jmp plt+0 |
| 585 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1b: int3; padding | ||
| 523 | }; | 586 | }; |
| 524 | memcpy(Buf, Insn, sizeof(Insn)); | 587 | memcpy(Buf, Insn, sizeof(Insn)); |
| 525 | 588 | ||
| 526 | uint64_t Off = TargetInfo::PltHeaderSize + TargetInfo::PltEntrySize * Index; | 589 | uint64_t Off = TargetInfo::getPltEntryOffset(Index); |
| 527 | 590 | ||
| 528 | write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7); | 591 | write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7); |
| 529 | write32le(Buf + 8, -Off - 12 + 32); | 592 | write32le(Buf + 8, -Off - 12 + 32); |
| ... | @@ -547,6 +610,9 @@ void RetpolineZNow<ELFT>::writePltHeader(uint8_t *Buf) const { | ... | @@ -547,6 +610,9 @@ void RetpolineZNow<ELFT>::writePltHeader(uint8_t *Buf) const { |
| 547 | 0xcc, 0xcc, 0xcc, 0xcc, // c: int3; .align 16 | 610 | 0xcc, 0xcc, 0xcc, 0xcc, // c: int3; .align 16 |
| 548 | 0x4c, 0x89, 0x1c, 0x24, // 10: next: mov %r11, (%rsp) | 611 | 0x4c, 0x89, 0x1c, 0x24, // 10: next: mov %r11, (%rsp) |
| 549 | 0xc3, // 14: ret | 612 | 0xc3, // 14: ret |
| 613 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 15: int3; padding | ||
| 614 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // 1a: int3; padding | ||
| 615 | 0xcc, // 1f: int3; padding | ||
| 550 | }; | 616 | }; |
| 551 | memcpy(Buf, Insn, sizeof(Insn)); | 617 | memcpy(Buf, Insn, sizeof(Insn)); |
| 552 | } | 618 | } |
| ... | @@ -556,17 +622,17 @@ void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, | ... | @@ -556,17 +622,17 @@ void RetpolineZNow<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, |
| 556 | uint64_t PltEntryAddr, int32_t Index, | 622 | uint64_t PltEntryAddr, int32_t Index, |
| 557 | unsigned RelOff) const { | 623 | unsigned RelOff) const { |
| 558 | const uint8_t Insn[] = { | 624 | const uint8_t Insn[] = { |
| 559 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // mov foo@GOTPLT(%rip), %r11 | 625 | 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, // mov foo@GOTPLT(%rip), %r11 |
| 560 | 0xe9, 0, 0, 0, 0, // jmp plt+0 | 626 | 0xe9, 0, 0, 0, 0, // jmp plt+0 |
| 627 | 0xcc, 0xcc, 0xcc, 0xcc, // int3; padding | ||
| 561 | }; | 628 | }; |
| 562 | memcpy(Buf, Insn, sizeof(Insn)); | 629 | memcpy(Buf, Insn, sizeof(Insn)); |
| 563 | 630 | ||
| 564 | write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7); | 631 | write32le(Buf + 3, GotPltEntryAddr - PltEntryAddr - 7); |
| 565 | write32le(Buf + 8, | 632 | write32le(Buf + 8, -TargetInfo::getPltEntryOffset(Index) - 12); |
| 566 | -Index * TargetInfo::PltEntrySize - TargetInfo::PltHeaderSize - 12); | ||
| 567 | } | 633 | } |
| 568 | 634 | ||
| 569 | template <class ELFT> TargetInfo *getTargetInfo() { | 635 | template <class ELFT> static TargetInfo *getTargetInfo() { |
| 570 | if (Config->ZRetpolineplt) { | 636 | if (Config->ZRetpolineplt) { |
| 571 | if (Config->ZNow) { | 637 | if (Config->ZNow) { |
| 572 | static RetpolineZNow<ELFT> T; | 638 | static RetpolineZNow<ELFT> T; |
deps/lld/ELF/CMakeLists.txt+3-1| ... | @@ -12,6 +12,7 @@ add_lld_library(lldELF | ... | @@ -12,6 +12,7 @@ add_lld_library(lldELF |
| 12 | Arch/AMDGPU.cpp | 12 | Arch/AMDGPU.cpp |
| 13 | Arch/ARM.cpp | 13 | Arch/ARM.cpp |
| 14 | Arch/AVR.cpp | 14 | Arch/AVR.cpp |
| 15 | Arch/Hexagon.cpp | ||
| 15 | Arch/Mips.cpp | 16 | Arch/Mips.cpp |
| 16 | Arch/MipsArchTree.cpp | 17 | Arch/MipsArchTree.cpp |
| 17 | Arch/PPC.cpp | 18 | Arch/PPC.cpp |
| ... | @@ -19,6 +20,7 @@ add_lld_library(lldELF | ... | @@ -19,6 +20,7 @@ add_lld_library(lldELF |
| 19 | Arch/SPARCV9.cpp | 20 | Arch/SPARCV9.cpp |
| 20 | Arch/X86.cpp | 21 | Arch/X86.cpp |
| 21 | Arch/X86_64.cpp | 22 | Arch/X86_64.cpp |
| 23 | CallGraphSort.cpp | ||
| 22 | Driver.cpp | 24 | Driver.cpp |
| 23 | DriverUtils.cpp | 25 | DriverUtils.cpp |
| 24 | EhFrame.cpp | 26 | EhFrame.cpp |
| ... | @@ -35,7 +37,6 @@ add_lld_library(lldELF | ... | @@ -35,7 +37,6 @@ add_lld_library(lldELF |
| 35 | Relocations.cpp | 37 | Relocations.cpp |
| 36 | ScriptLexer.cpp | 38 | ScriptLexer.cpp |
| 37 | ScriptParser.cpp | 39 | ScriptParser.cpp |
| 38 | Strings.cpp | ||
| 39 | SymbolTable.cpp | 40 | SymbolTable.cpp |
| 40 | Symbols.cpp | 41 | Symbols.cpp |
| 41 | SyntheticSections.cpp | 42 | SyntheticSections.cpp |
| ... | @@ -46,6 +47,7 @@ add_lld_library(lldELF | ... | @@ -46,6 +47,7 @@ add_lld_library(lldELF |
| 46 | LINK_COMPONENTS | 47 | LINK_COMPONENTS |
| 47 | ${LLVM_TARGETS_TO_BUILD} | 48 | ${LLVM_TARGETS_TO_BUILD} |
| 48 | BinaryFormat | 49 | BinaryFormat |
| 50 | BitWriter | ||
| 49 | Core | 51 | Core |
| 50 | DebugInfoDWARF | 52 | DebugInfoDWARF |
| 51 | LTO | 53 | LTO |
deps/lld/ELF/CallGraphSort.cpp created+249| ... | @@ -0,0 +1,249 @@ | ||
| 1 | //===- CallGraphSort.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 | /// Implementation of Call-Chain Clustering from: Optimizing Function Placement | ||
| 11 | /// for Large-Scale Data-Center Applications | ||
| 12 | /// https://research.fb.com/wp-content/uploads/2017/01/cgo2017-hfsort-final1.pdf | ||
| 13 | /// | ||
| 14 | /// The goal of this algorithm is to improve runtime performance of the final | ||
| 15 | /// executable by arranging code sections such that page table and i-cache | ||
| 16 | /// misses are minimized. | ||
| 17 | /// | ||
| 18 | /// Definitions: | ||
| 19 | /// * Cluster | ||
| 20 | /// * An ordered list of input sections which are layed out as a unit. At the | ||
| 21 | /// beginning of the algorithm each input section has its own cluster and | ||
| 22 | /// the weight of the cluster is the sum of the weight of all incomming | ||
| 23 | /// edges. | ||
| 24 | /// * Call-Chain Clustering (C³) Heuristic | ||
| 25 | /// * Defines when and how clusters are combined. Pick the highest weighted | ||
| 26 | /// input section then add it to its most likely predecessor if it wouldn't | ||
| 27 | /// penalize it too much. | ||
| 28 | /// * Density | ||
| 29 | /// * The weight of the cluster divided by the size of the cluster. This is a | ||
| 30 | /// proxy for the ammount of execution time spent per byte of the cluster. | ||
| 31 | /// | ||
| 32 | /// It does so given a call graph profile by the following: | ||
| 33 | /// * Build a weighted call graph from the call graph profile | ||
| 34 | /// * Sort input sections by weight | ||
| 35 | /// * For each input section starting with the highest weight | ||
| 36 | /// * Find its most likely predecessor cluster | ||
| 37 | /// * Check if the combined cluster would be too large, or would have too low | ||
| 38 | /// a density. | ||
| 39 | /// * If not, then combine the clusters. | ||
| 40 | /// * Sort non-empty clusters by density | ||
| 41 | /// | ||
| 42 | //===----------------------------------------------------------------------===// | ||
| 43 | |||
| 44 | #include "CallGraphSort.h" | ||
| 45 | #include "OutputSections.h" | ||
| 46 | #include "SymbolTable.h" | ||
| 47 | #include "Symbols.h" | ||
| 48 | |||
| 49 | using namespace llvm; | ||
| 50 | using namespace lld; | ||
| 51 | using namespace lld::elf; | ||
| 52 | |||
| 53 | namespace { | ||
| 54 | struct Edge { | ||
| 55 | int From; | ||
| 56 | uint64_t Weight; | ||
| 57 | }; | ||
| 58 | |||
| 59 | struct Cluster { | ||
| 60 | Cluster(int Sec, size_t S) { | ||
| 61 | Sections.push_back(Sec); | ||
| 62 | Size = S; | ||
| 63 | } | ||
| 64 | |||
| 65 | double getDensity() const { | ||
| 66 | if (Size == 0) | ||
| 67 | return 0; | ||
| 68 | return double(Weight) / double(Size); | ||
| 69 | } | ||
| 70 | |||
| 71 | std::vector<int> Sections; | ||
| 72 | size_t Size = 0; | ||
| 73 | uint64_t Weight = 0; | ||
| 74 | uint64_t InitialWeight = 0; | ||
| 75 | std::vector<Edge> Preds; | ||
| 76 | }; | ||
| 77 | |||
| 78 | class CallGraphSort { | ||
| 79 | public: | ||
| 80 | CallGraphSort(); | ||
| 81 | |||
| 82 | DenseMap<const InputSectionBase *, int> run(); | ||
| 83 | |||
| 84 | private: | ||
| 85 | std::vector<Cluster> Clusters; | ||
| 86 | std::vector<const InputSectionBase *> Sections; | ||
| 87 | |||
| 88 | void groupClusters(); | ||
| 89 | }; | ||
| 90 | |||
| 91 | // Maximum ammount the combined cluster density can be worse than the original | ||
| 92 | // cluster to consider merging. | ||
| 93 | constexpr int MAX_DENSITY_DEGRADATION = 8; | ||
| 94 | |||
| 95 | // Maximum cluster size in bytes. | ||
| 96 | constexpr uint64_t MAX_CLUSTER_SIZE = 1024 * 1024; | ||
| 97 | } // end anonymous namespace | ||
| 98 | |||
| 99 | // Take the edge list in Config->CallGraphProfile, resolve symbol names to | ||
| 100 | // Symbols, and generate a graph between InputSections with the provided | ||
| 101 | // weights. | ||
| 102 | CallGraphSort::CallGraphSort() { | ||
| 103 | llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>, | ||
| 104 | uint64_t> &Profile = Config->CallGraphProfile; | ||
| 105 | DenseMap<const InputSectionBase *, int> SecToCluster; | ||
| 106 | |||
| 107 | auto GetOrCreateNode = [&](const InputSectionBase *IS) -> int { | ||
| 108 | auto Res = SecToCluster.insert(std::make_pair(IS, Clusters.size())); | ||
| 109 | if (Res.second) { | ||
| 110 | Sections.push_back(IS); | ||
| 111 | Clusters.emplace_back(Clusters.size(), IS->getSize()); | ||
| 112 | } | ||
| 113 | return Res.first->second; | ||
| 114 | }; | ||
| 115 | |||
| 116 | // Create the graph. | ||
| 117 | for (const auto &C : Profile) { | ||
| 118 | const auto *FromSB = cast<InputSectionBase>(C.first.first->Repl); | ||
| 119 | const auto *ToSB = cast<InputSectionBase>(C.first.second->Repl); | ||
| 120 | uint64_t Weight = C.second; | ||
| 121 | |||
| 122 | // Ignore edges between input sections belonging to different output | ||
| 123 | // sections. This is done because otherwise we would end up with clusters | ||
| 124 | // containing input sections that can't actually be placed adjacently in the | ||
| 125 | // output. This messes with the cluster size and density calculations. We | ||
| 126 | // would also end up moving input sections in other output sections without | ||
| 127 | // moving them closer to what calls them. | ||
| 128 | if (FromSB->getOutputSection() != ToSB->getOutputSection()) | ||
| 129 | continue; | ||
| 130 | |||
| 131 | int From = GetOrCreateNode(FromSB); | ||
| 132 | int To = GetOrCreateNode(ToSB); | ||
| 133 | |||
| 134 | Clusters[To].Weight += Weight; | ||
| 135 | |||
| 136 | if (From == To) | ||
| 137 | continue; | ||
| 138 | |||
| 139 | // Add an edge | ||
| 140 | Clusters[To].Preds.push_back({From, Weight}); | ||
| 141 | } | ||
| 142 | for (Cluster &C : Clusters) | ||
| 143 | C.InitialWeight = C.Weight; | ||
| 144 | } | ||
| 145 | |||
| 146 | // It's bad to merge clusters which would degrade the density too much. | ||
| 147 | static bool isNewDensityBad(Cluster &A, Cluster &B) { | ||
| 148 | double NewDensity = double(A.Weight + B.Weight) / double(A.Size + B.Size); | ||
| 149 | if (NewDensity < A.getDensity() / MAX_DENSITY_DEGRADATION) | ||
| 150 | return true; | ||
| 151 | return false; | ||
| 152 | } | ||
| 153 | |||
| 154 | static 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; | ||
| 162 | } | ||
| 163 | |||
| 164 | // Group InputSections into clusters using the Call-Chain Clustering heuristic | ||
| 165 | // then sort the clusters by density. | ||
| 166 | void CallGraphSort::groupClusters() { | ||
| 167 | std::vector<int> SortedSecs(Clusters.size()); | ||
| 168 | std::vector<Cluster *> SecToCluster(Clusters.size()); | ||
| 169 | |||
| 170 | for (int SI = 0, SE = Clusters.size(); SI != SE; ++SI) { | ||
| 171 | SortedSecs[SI] = SI; | ||
| 172 | SecToCluster[SI] = &Clusters[SI]; | ||
| 173 | } | ||
| 174 | |||
| 175 | std::stable_sort(SortedSecs.begin(), SortedSecs.end(), [&](int A, int B) { | ||
| 176 | return Clusters[B].getDensity() < Clusters[A].getDensity(); | ||
| 177 | }); | ||
| 178 | |||
| 179 | for (int SI : SortedSecs) { | ||
| 180 | // Clusters[SI] is the same as SecToClusters[SI] here because it has not | ||
| 181 | // been merged into another cluster yet. | ||
| 182 | Cluster &C = Clusters[SI]; | ||
| 183 | |||
| 184 | int BestPred = -1; | ||
| 185 | uint64_t BestWeight = 0; | ||
| 186 | |||
| 187 | for (Edge &E : C.Preds) { | ||
| 188 | if (BestPred == -1 || E.Weight > BestWeight) { | ||
| 189 | BestPred = E.From; | ||
| 190 | BestWeight = E.Weight; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | // don't consider merging if the edge is unlikely. | ||
| 195 | if (BestWeight * 10 <= C.InitialWeight) | ||
| 196 | continue; | ||
| 197 | |||
| 198 | Cluster *PredC = SecToCluster[BestPred]; | ||
| 199 | if (PredC == &C) | ||
| 200 | continue; | ||
| 201 | |||
| 202 | if (C.Size + PredC->Size > MAX_CLUSTER_SIZE) | ||
| 203 | continue; | ||
| 204 | |||
| 205 | if (isNewDensityBad(*PredC, C)) | ||
| 206 | continue; | ||
| 207 | |||
| 208 | // NOTE: Consider using a disjoint-set to track section -> cluster mapping | ||
| 209 | // if this is ever slow. | ||
| 210 | for (int SI : C.Sections) | ||
| 211 | SecToCluster[SI] = PredC; | ||
| 212 | |||
| 213 | mergeClusters(*PredC, C); | ||
| 214 | } | ||
| 215 | |||
| 216 | // Remove empty or dead nodes. Invalidates all cluster indices. | ||
| 217 | llvm::erase_if(Clusters, [](const Cluster &C) { | ||
| 218 | return C.Size == 0 || C.Sections.empty(); | ||
| 219 | }); | ||
| 220 | |||
| 221 | // Sort by density. | ||
| 222 | std::stable_sort(Clusters.begin(), Clusters.end(), | ||
| 223 | [](const Cluster &A, const Cluster &B) { | ||
| 224 | return A.getDensity() > B.getDensity(); | ||
| 225 | }); | ||
| 226 | } | ||
| 227 | |||
| 228 | DenseMap<const InputSectionBase *, int> CallGraphSort::run() { | ||
| 229 | groupClusters(); | ||
| 230 | |||
| 231 | // Generate order. | ||
| 232 | llvm::DenseMap<const InputSectionBase *, int> OrderMap; | ||
| 233 | ssize_t CurOrder = 1; | ||
| 234 | |||
| 235 | for (const Cluster &C : Clusters) | ||
| 236 | for (int SecIndex : C.Sections) | ||
| 237 | OrderMap[Sections[SecIndex]] = CurOrder++; | ||
| 238 | |||
| 239 | return OrderMap; | ||
| 240 | } | ||
| 241 | |||
| 242 | // Sort sections by the profile data provided by -callgraph-profile-file | ||
| 243 | // | ||
| 244 | // This first builds a call graph based on the profile data then merges sections | ||
| 245 | // according to the C³ huristic. All clusters are then sorted by a density | ||
| 246 | // metric to further improve locality. | ||
| 247 | DenseMap<const InputSectionBase *, int> elf::computeCallGraphProfileOrder() { | ||
| 248 | return CallGraphSort().run(); | ||
| 249 | } | ||
deps/lld/ELF/CallGraphSort.h created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | //===- CallGraphSort.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_CALL_GRAPH_SORT_H | ||
| 11 | #define LLD_ELF_CALL_GRAPH_SORT_H | ||
| 12 | |||
| 13 | #include "llvm/ADT/DenseMap.h" | ||
| 14 | |||
| 15 | namespace lld { | ||
| 16 | namespace elf { | ||
| 17 | class InputSectionBase; | ||
| 18 | |||
| 19 | llvm::DenseMap<const InputSectionBase *, int> computeCallGraphProfileOrder(); | ||
| 20 | } // namespace elf | ||
| 21 | } // namespace lld | ||
| 22 | |||
| 23 | #endif | ||
deps/lld/ELF/Config.h+49-10| ... | @@ -10,6 +10,7 @@ | ... | @@ -10,6 +10,7 @@ |
| 10 | #ifndef LLD_ELF_CONFIG_H | 10 | #ifndef LLD_ELF_CONFIG_H |
| 11 | #define LLD_ELF_CONFIG_H | 11 | #define LLD_ELF_CONFIG_H |
| 12 | 12 | ||
| 13 | #include "lld/Common/ErrorHandler.h" | ||
| 13 | #include "llvm/ADT/MapVector.h" | 14 | #include "llvm/ADT/MapVector.h" |
| 14 | #include "llvm/ADT/StringRef.h" | 15 | #include "llvm/ADT/StringRef.h" |
| 15 | #include "llvm/ADT/StringSet.h" | 16 | #include "llvm/ADT/StringSet.h" |
| ... | @@ -17,13 +18,13 @@ | ... | @@ -17,13 +18,13 @@ |
| 17 | #include "llvm/Support/CachePruning.h" | 18 | #include "llvm/Support/CachePruning.h" |
| 18 | #include "llvm/Support/CodeGen.h" | 19 | #include "llvm/Support/CodeGen.h" |
| 19 | #include "llvm/Support/Endian.h" | 20 | #include "llvm/Support/Endian.h" |
| 20 | |||
| 21 | #include <vector> | 21 | #include <vector> |
| 22 | 22 | ||
| 23 | namespace lld { | 23 | namespace lld { |
| 24 | namespace elf { | 24 | namespace elf { |
| 25 | 25 | ||
| 26 | class InputFile; | 26 | class InputFile; |
| 27 | class InputSectionBase; | ||
| 27 | 28 | ||
| 28 | enum ELFKind { | 29 | enum ELFKind { |
| 29 | ELFNoneKind, | 30 | ELFNoneKind, |
| ... | @@ -39,6 +40,9 @@ enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid }; | ... | @@ -39,6 +40,9 @@ enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid }; |
| 39 | // For --discard-{all,locals,none}. | 40 | // For --discard-{all,locals,none}. |
| 40 | enum class DiscardPolicy { Default, All, Locals, None }; | 41 | enum class DiscardPolicy { Default, All, Locals, None }; |
| 41 | 42 | ||
| 43 | // For --icf={none,safe,all}. | ||
| 44 | enum class ICFLevel { None, Safe, All }; | ||
| 45 | |||
| 42 | // For --strip-{all,debug}. | 46 | // For --strip-{all,debug}. |
| 43 | enum class StripPolicy { None, All, Debug }; | 47 | enum class StripPolicy { None, All, Debug }; |
| 44 | 48 | ||
| ... | @@ -54,6 +58,9 @@ enum class SortSectionPolicy { Default, None, Alignment, Name, Priority }; | ... | @@ -54,6 +58,9 @@ enum class SortSectionPolicy { Default, None, Alignment, Name, Priority }; |
| 54 | // For --target2 | 58 | // For --target2 |
| 55 | enum class Target2Policy { Abs, Rel, GotRel }; | 59 | enum class Target2Policy { Abs, Rel, GotRel }; |
| 56 | 60 | ||
| 61 | // For tracking ARM Float Argument PCS | ||
| 62 | enum class ARMVFPArgKind { Default, Base, VFP, ToolChain }; | ||
| 63 | |||
| 57 | struct SymbolVersion { | 64 | struct SymbolVersion { |
| 58 | llvm::StringRef Name; | 65 | llvm::StringRef Name; |
| 59 | bool IsExternCpp; | 66 | bool IsExternCpp; |
| ... | @@ -79,21 +86,27 @@ struct Configuration { | ... | @@ -79,21 +86,27 @@ struct Configuration { |
| 79 | llvm::StringMap<uint64_t> SectionStartMap; | 86 | llvm::StringMap<uint64_t> SectionStartMap; |
| 80 | llvm::StringRef Chroot; | 87 | llvm::StringRef Chroot; |
| 81 | llvm::StringRef DynamicLinker; | 88 | llvm::StringRef DynamicLinker; |
| 89 | llvm::StringRef DwoDir; | ||
| 82 | llvm::StringRef Entry; | 90 | llvm::StringRef Entry; |
| 83 | llvm::StringRef Emulation; | 91 | llvm::StringRef Emulation; |
| 84 | llvm::StringRef Fini; | 92 | llvm::StringRef Fini; |
| 85 | llvm::StringRef Init; | 93 | llvm::StringRef Init; |
| 86 | llvm::StringRef LTOAAPipeline; | 94 | llvm::StringRef LTOAAPipeline; |
| 87 | llvm::StringRef LTONewPmPasses; | 95 | llvm::StringRef LTONewPmPasses; |
| 96 | llvm::StringRef LTOObjPath; | ||
| 97 | llvm::StringRef LTOSampleProfile; | ||
| 88 | llvm::StringRef MapFile; | 98 | llvm::StringRef MapFile; |
| 89 | llvm::StringRef OutputFile; | 99 | llvm::StringRef OutputFile; |
| 90 | llvm::StringRef OptRemarksFilename; | 100 | llvm::StringRef OptRemarksFilename; |
| 101 | llvm::StringRef ProgName; | ||
| 91 | llvm::StringRef SoName; | 102 | llvm::StringRef SoName; |
| 92 | llvm::StringRef Sysroot; | 103 | llvm::StringRef Sysroot; |
| 93 | llvm::StringRef ThinLTOCacheDir; | 104 | llvm::StringRef ThinLTOCacheDir; |
| 105 | llvm::StringRef ThinLTOIndexOnlyArg; | ||
| 106 | std::pair<llvm::StringRef, llvm::StringRef> ThinLTOObjectSuffixReplace; | ||
| 107 | std::pair<llvm::StringRef, llvm::StringRef> ThinLTOPrefixReplace; | ||
| 94 | std::string Rpath; | 108 | std::string Rpath; |
| 95 | std::vector<VersionDefinition> VersionDefinitions; | 109 | std::vector<VersionDefinition> VersionDefinitions; |
| 96 | std::vector<llvm::StringRef> Argv; | ||
| 97 | std::vector<llvm::StringRef> AuxiliaryList; | 110 | std::vector<llvm::StringRef> AuxiliaryList; |
| 98 | std::vector<llvm::StringRef> FilterList; | 111 | std::vector<llvm::StringRef> FilterList; |
| 99 | std::vector<llvm::StringRef> SearchPaths; | 112 | std::vector<llvm::StringRef> SearchPaths; |
| ... | @@ -103,34 +116,41 @@ struct Configuration { | ... | @@ -103,34 +116,41 @@ struct Configuration { |
| 103 | std::vector<SymbolVersion> VersionScriptGlobals; | 116 | std::vector<SymbolVersion> VersionScriptGlobals; |
| 104 | std::vector<SymbolVersion> VersionScriptLocals; | 117 | std::vector<SymbolVersion> VersionScriptLocals; |
| 105 | std::vector<uint8_t> BuildIdVector; | 118 | std::vector<uint8_t> BuildIdVector; |
| 119 | llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>, | ||
| 120 | uint64_t> | ||
| 121 | CallGraphProfile; | ||
| 106 | bool AllowMultipleDefinition; | 122 | bool AllowMultipleDefinition; |
| 107 | bool AndroidPackDynRelocs = false; | 123 | bool AndroidPackDynRelocs; |
| 108 | bool ARMHasBlx = false; | 124 | bool ARMHasBlx = false; |
| 109 | bool ARMHasMovtMovw = false; | 125 | bool ARMHasMovtMovw = false; |
| 110 | bool ARMJ1J2BranchEncoding = false; | 126 | bool ARMJ1J2BranchEncoding = false; |
| 111 | bool AsNeeded = false; | 127 | bool AsNeeded = false; |
| 112 | bool Bsymbolic; | 128 | bool Bsymbolic; |
| 113 | bool BsymbolicFunctions; | 129 | bool BsymbolicFunctions; |
| 130 | bool CheckSections; | ||
| 114 | bool CompressDebugSections; | 131 | bool CompressDebugSections; |
| 132 | bool Cref; | ||
| 115 | bool DefineCommon; | 133 | bool DefineCommon; |
| 116 | bool Demangle = true; | 134 | bool Demangle = true; |
| 117 | bool DisableVerify; | 135 | bool DisableVerify; |
| 118 | bool EhFrameHdr; | 136 | bool EhFrameHdr; |
| 119 | bool EmitRelocs; | 137 | bool EmitRelocs; |
| 120 | bool EnableNewDtags; | 138 | bool EnableNewDtags; |
| 139 | bool ExecuteOnly; | ||
| 121 | bool ExportDynamic; | 140 | bool ExportDynamic; |
| 122 | bool FixCortexA53Errata843419; | 141 | bool FixCortexA53Errata843419; |
| 123 | bool GcSections; | 142 | bool GcSections; |
| 124 | bool GdbIndex; | 143 | bool GdbIndex; |
| 125 | bool GnuHash = false; | 144 | bool GnuHash = false; |
| 145 | bool GnuUnique; | ||
| 126 | bool HasDynamicList = false; | 146 | bool HasDynamicList = false; |
| 127 | bool HasDynSymTab; | 147 | bool HasDynSymTab; |
| 128 | bool ICF; | 148 | bool IgnoreDataAddressEquality; |
| 129 | bool ICFData; | 149 | bool IgnoreFunctionAddressEquality; |
| 150 | bool LTODebugPassManager; | ||
| 151 | bool LTONewPassManager; | ||
| 130 | bool MergeArmExidx; | 152 | bool MergeArmExidx; |
| 131 | bool MipsN32Abi = false; | 153 | bool MipsN32Abi = false; |
| 132 | bool NoGnuUnique; | ||
| 133 | bool NoUndefinedVersion; | ||
| 134 | bool NoinhibitExec; | 154 | bool NoinhibitExec; |
| 135 | bool Nostdlib; | 155 | bool Nostdlib; |
| 136 | bool OFormatBinary; | 156 | bool OFormatBinary; |
| ... | @@ -138,7 +158,9 @@ struct Configuration { | ... | @@ -138,7 +158,9 @@ struct Configuration { |
| 138 | bool OptRemarksWithHotness; | 158 | bool OptRemarksWithHotness; |
| 139 | bool Pie; | 159 | bool Pie; |
| 140 | bool PrintGcSections; | 160 | bool PrintGcSections; |
| 161 | bool PrintIcfSections; | ||
| 141 | bool Relocatable; | 162 | bool Relocatable; |
| 163 | bool RelrPackDynRelocs; | ||
| 142 | bool SaveTemps; | 164 | bool SaveTemps; |
| 143 | bool SingleRoRx; | 165 | bool SingleRoRx; |
| 144 | bool Shared; | 166 | bool Shared; |
| ... | @@ -146,12 +168,21 @@ struct Configuration { | ... | @@ -146,12 +168,21 @@ struct Configuration { |
| 146 | bool SysvHash = false; | 168 | bool SysvHash = false; |
| 147 | bool Target1Rel; | 169 | bool Target1Rel; |
| 148 | bool Trace; | 170 | bool Trace; |
| 149 | bool Verbose; | 171 | bool ThinLTOEmitImportsFiles; |
| 172 | bool ThinLTOIndexOnly; | ||
| 173 | bool UndefinedVersion; | ||
| 174 | bool UseAndroidRelrTags = false; | ||
| 175 | bool WarnBackrefs; | ||
| 150 | bool WarnCommon; | 176 | bool WarnCommon; |
| 151 | bool WarnMissingEntry; | 177 | bool WarnMissingEntry; |
| 178 | bool WarnSymbolOrdering; | ||
| 179 | bool WriteAddends; | ||
| 152 | bool ZCombreloc; | 180 | bool ZCombreloc; |
| 181 | bool ZCopyreloc; | ||
| 153 | bool ZExecstack; | 182 | bool ZExecstack; |
| 154 | bool ZNocopyreloc; | 183 | bool ZHazardplt; |
| 184 | bool ZInitfirst; | ||
| 185 | bool ZKeepTextSectionPrefix; | ||
| 155 | bool ZNodelete; | 186 | bool ZNodelete; |
| 156 | bool ZNodlopen; | 187 | bool ZNodlopen; |
| 157 | bool ZNow; | 188 | bool ZNow; |
| ... | @@ -160,20 +191,22 @@ struct Configuration { | ... | @@ -160,20 +191,22 @@ struct Configuration { |
| 160 | bool ZRodynamic; | 191 | bool ZRodynamic; |
| 161 | bool ZText; | 192 | bool ZText; |
| 162 | bool ZRetpolineplt; | 193 | bool ZRetpolineplt; |
| 163 | bool ExitEarly; | ||
| 164 | bool ZWxneeded; | 194 | bool ZWxneeded; |
| 165 | DiscardPolicy Discard; | 195 | DiscardPolicy Discard; |
| 196 | ICFLevel ICF; | ||
| 166 | OrphanHandlingPolicy OrphanHandling; | 197 | OrphanHandlingPolicy OrphanHandling; |
| 167 | SortSectionPolicy SortSection; | 198 | SortSectionPolicy SortSection; |
| 168 | StripPolicy Strip; | 199 | StripPolicy Strip; |
| 169 | UnresolvedPolicy UnresolvedSymbols; | 200 | UnresolvedPolicy UnresolvedSymbols; |
| 170 | Target2Policy Target2; | 201 | Target2Policy Target2; |
| 202 | ARMVFPArgKind ARMVFPArgs = ARMVFPArgKind::Default; | ||
| 171 | BuildIdKind BuildId = BuildIdKind::None; | 203 | BuildIdKind BuildId = BuildIdKind::None; |
| 172 | ELFKind EKind = ELFNoneKind; | 204 | ELFKind EKind = ELFNoneKind; |
| 173 | uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL; | 205 | uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL; |
| 174 | uint16_t EMachine = llvm::ELF::EM_NONE; | 206 | uint16_t EMachine = llvm::ELF::EM_NONE; |
| 175 | llvm::Optional<uint64_t> ImageBase; | 207 | llvm::Optional<uint64_t> ImageBase; |
| 176 | uint64_t MaxPageSize; | 208 | uint64_t MaxPageSize; |
| 209 | uint64_t MipsGotSize; | ||
| 177 | uint64_t ZStackSize; | 210 | uint64_t ZStackSize; |
| 178 | unsigned LTOPartitions; | 211 | unsigned LTOPartitions; |
| 179 | unsigned LTOO; | 212 | unsigned LTOO; |
| ... | @@ -239,6 +272,12 @@ struct Configuration { | ... | @@ -239,6 +272,12 @@ struct Configuration { |
| 239 | // The only instance of Configuration struct. | 272 | // The only instance of Configuration struct. |
| 240 | extern Configuration *Config; | 273 | extern Configuration *Config; |
| 241 | 274 | ||
| 275 | static inline void errorOrWarn(const Twine &Msg) { | ||
| 276 | if (!Config->NoinhibitExec) | ||
| 277 | error(Msg); | ||
| 278 | else | ||
| 279 | warn(Msg); | ||
| 280 | } | ||
| 242 | } // namespace elf | 281 | } // namespace elf |
| 243 | } // namespace lld | 282 | } // namespace lld |
| 244 | 283 |
deps/lld/ELF/Driver.cpp+501-116| ... | @@ -30,9 +30,9 @@ | ... | @@ -30,9 +30,9 @@ |
| 30 | #include "InputFiles.h" | 30 | #include "InputFiles.h" |
| 31 | #include "InputSection.h" | 31 | #include "InputSection.h" |
| 32 | #include "LinkerScript.h" | 32 | #include "LinkerScript.h" |
| 33 | #include "MarkLive.h" | ||
| 33 | #include "OutputSections.h" | 34 | #include "OutputSections.h" |
| 34 | #include "ScriptParser.h" | 35 | #include "ScriptParser.h" |
| 35 | #include "Strings.h" | ||
| 36 | #include "SymbolTable.h" | 36 | #include "SymbolTable.h" |
| 37 | #include "Symbols.h" | 37 | #include "Symbols.h" |
| 38 | #include "SyntheticSections.h" | 38 | #include "SyntheticSections.h" |
| ... | @@ -42,12 +42,16 @@ | ... | @@ -42,12 +42,16 @@ |
| 42 | #include "lld/Common/Driver.h" | 42 | #include "lld/Common/Driver.h" |
| 43 | #include "lld/Common/ErrorHandler.h" | 43 | #include "lld/Common/ErrorHandler.h" |
| 44 | #include "lld/Common/Memory.h" | 44 | #include "lld/Common/Memory.h" |
| 45 | #include "lld/Common/Strings.h" | ||
| 46 | #include "lld/Common/TargetOptionsCommandFlags.h" | ||
| 45 | #include "lld/Common/Threads.h" | 47 | #include "lld/Common/Threads.h" |
| 46 | #include "lld/Common/Version.h" | 48 | #include "lld/Common/Version.h" |
| 49 | #include "llvm/ADT/SetVector.h" | ||
| 47 | #include "llvm/ADT/StringExtras.h" | 50 | #include "llvm/ADT/StringExtras.h" |
| 48 | #include "llvm/ADT/StringSwitch.h" | 51 | #include "llvm/ADT/StringSwitch.h" |
| 49 | #include "llvm/Support/CommandLine.h" | 52 | #include "llvm/Support/CommandLine.h" |
| 50 | #include "llvm/Support/Compression.h" | 53 | #include "llvm/Support/Compression.h" |
| 54 | #include "llvm/Support/LEB128.h" | ||
| 51 | #include "llvm/Support/Path.h" | 55 | #include "llvm/Support/Path.h" |
| 52 | #include "llvm/Support/TarWriter.h" | 56 | #include "llvm/Support/TarWriter.h" |
| 53 | #include "llvm/Support/TargetSelect.h" | 57 | #include "llvm/Support/TargetSelect.h" |
| ... | @@ -66,16 +70,18 @@ using namespace lld::elf; | ... | @@ -66,16 +70,18 @@ using namespace lld::elf; |
| 66 | Configuration *elf::Config; | 70 | Configuration *elf::Config; |
| 67 | LinkerDriver *elf::Driver; | 71 | LinkerDriver *elf::Driver; |
| 68 | 72 | ||
| 69 | static void setConfigs(); | 73 | static void setConfigs(opt::InputArgList &Args); |
| 70 | 74 | ||
| 71 | bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly, | 75 | bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly, |
| 72 | raw_ostream &Error) { | 76 | raw_ostream &Error) { |
| 73 | errorHandler().LogName = Args[0]; | 77 | errorHandler().LogName = sys::path::filename(Args[0]); |
| 74 | errorHandler().ErrorLimitExceededMsg = | 78 | errorHandler().ErrorLimitExceededMsg = |
| 75 | "too many errors emitted, stopping now (use " | 79 | "too many errors emitted, stopping now (use " |
| 76 | "-error-limit=0 to see all errors)"; | 80 | "-error-limit=0 to see all errors)"; |
| 77 | errorHandler().ErrorOS = &Error; | 81 | errorHandler().ErrorOS = &Error; |
| 82 | errorHandler().ExitEarly = CanExitEarly; | ||
| 78 | errorHandler().ColorDiagnostics = Error.has_colors(); | 83 | errorHandler().ColorDiagnostics = Error.has_colors(); |
| 84 | |||
| 79 | InputSections.clear(); | 85 | InputSections.clear(); |
| 80 | OutputSections.clear(); | 86 | OutputSections.clear(); |
| 81 | Tar = nullptr; | 87 | Tar = nullptr; |
| ... | @@ -88,14 +94,14 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly, | ... | @@ -88,14 +94,14 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly, |
| 88 | Driver = make<LinkerDriver>(); | 94 | Driver = make<LinkerDriver>(); |
| 89 | Script = make<LinkerScript>(); | 95 | Script = make<LinkerScript>(); |
| 90 | Symtab = make<SymbolTable>(); | 96 | Symtab = make<SymbolTable>(); |
| 91 | Config->Argv = {Args.begin(), Args.end()}; | 97 | Config->ProgName = Args[0]; |
| 92 | 98 | ||
| 93 | Driver->main(Args, CanExitEarly); | 99 | Driver->main(Args); |
| 94 | 100 | ||
| 95 | // Exit immediately if we don't need to return to the caller. | 101 | // Exit immediately if we don't need to return to the caller. |
| 96 | // This saves time because the overhead of calling destructors | 102 | // This saves time because the overhead of calling destructors |
| 97 | // for all globally-allocated objects is not negligible. | 103 | // for all globally-allocated objects is not negligible. |
| 98 | if (Config->ExitEarly) | 104 | if (CanExitEarly) |
| 99 | exitLld(errorCount() ? 1 : 0); | 105 | exitLld(errorCount() ? 1 : 0); |
| 100 | 106 | ||
| 101 | freeArena(); | 107 | freeArena(); |
| ... | @@ -113,7 +119,8 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) { | ... | @@ -113,7 +119,8 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) { |
| 113 | 119 | ||
| 114 | std::pair<ELFKind, uint16_t> Ret = | 120 | std::pair<ELFKind, uint16_t> Ret = |
| 115 | StringSwitch<std::pair<ELFKind, uint16_t>>(S) | 121 | StringSwitch<std::pair<ELFKind, uint16_t>>(S) |
| 116 | .Cases("aarch64elf", "aarch64linux", {ELF64LEKind, EM_AARCH64}) | 122 | .Cases("aarch64elf", "aarch64linux", "aarch64_elf64_le_vec", |
| 123 | {ELF64LEKind, EM_AARCH64}) | ||
| 117 | .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM}) | 124 | .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM}) |
| 118 | .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64}) | 125 | .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64}) |
| 119 | .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS}) | 126 | .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS}) |
| ... | @@ -122,6 +129,7 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) { | ... | @@ -122,6 +129,7 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) { |
| 122 | .Case("elf64btsmip", {ELF64BEKind, EM_MIPS}) | 129 | .Case("elf64btsmip", {ELF64BEKind, EM_MIPS}) |
| 123 | .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS}) | 130 | .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS}) |
| 124 | .Case("elf64ppc", {ELF64BEKind, EM_PPC64}) | 131 | .Case("elf64ppc", {ELF64BEKind, EM_PPC64}) |
| 132 | .Case("elf64lppc", {ELF64LEKind, EM_PPC64}) | ||
| 125 | .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64}) | 133 | .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64}) |
| 126 | .Case("elf_i386", {ELF32LEKind, EM_386}) | 134 | .Case("elf_i386", {ELF32LEKind, EM_386}) |
| 127 | .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU}) | 135 | .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU}) |
| ... | @@ -228,11 +236,15 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) { | ... | @@ -228,11 +236,15 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) { |
| 228 | Files.push_back( | 236 | Files.push_back( |
| 229 | createSharedFile(MBRef, WithLOption ? path::filename(Path) : Path)); | 237 | createSharedFile(MBRef, WithLOption ? path::filename(Path) : Path)); |
| 230 | return; | 238 | return; |
| 231 | default: | 239 | case file_magic::bitcode: |
| 240 | case file_magic::elf_relocatable: | ||
| 232 | if (InLib) | 241 | if (InLib) |
| 233 | Files.push_back(make<LazyObjFile>(MBRef, "", 0)); | 242 | Files.push_back(make<LazyObjFile>(MBRef, "", 0)); |
| 234 | else | 243 | else |
| 235 | Files.push_back(createObjectFile(MBRef)); | 244 | Files.push_back(createObjectFile(MBRef)); |
| 245 | break; | ||
| 246 | default: | ||
| 247 | error(Path + ": unknown file type"); | ||
| 236 | } | 248 | } |
| 237 | } | 249 | } |
| 238 | 250 | ||
| ... | @@ -248,18 +260,11 @@ void LinkerDriver::addLibrary(StringRef Name) { | ... | @@ -248,18 +260,11 @@ void LinkerDriver::addLibrary(StringRef Name) { |
| 248 | // LTO calls LLVM functions to compile bitcode files to native code. | 260 | // LTO calls LLVM functions to compile bitcode files to native code. |
| 249 | // Technically this can be delayed until we read bitcode files, but | 261 | // Technically this can be delayed until we read bitcode files, but |
| 250 | // we don't bother to do lazily because the initialization is fast. | 262 | // we don't bother to do lazily because the initialization is fast. |
| 251 | static void initLLVM(opt::InputArgList &Args) { | 263 | static void initLLVM() { |
| 252 | InitializeAllTargets(); | 264 | InitializeAllTargets(); |
| 253 | InitializeAllTargetMCs(); | 265 | InitializeAllTargetMCs(); |
| 254 | InitializeAllAsmPrinters(); | 266 | InitializeAllAsmPrinters(); |
| 255 | InitializeAllAsmParsers(); | 267 | InitializeAllAsmParsers(); |
| 256 | |||
| 257 | // Parse and evaluate -mllvm options. | ||
| 258 | std::vector<const char *> V; | ||
| 259 | V.push_back("lld (LLVM option parsing)"); | ||
| 260 | for (auto *Arg : Args.filtered(OPT_mllvm)) | ||
| 261 | V.push_back(Arg->getValue()); | ||
| 262 | cl::ParseCommandLineOptions(V.size(), V.data()); | ||
| 263 | } | 268 | } |
| 264 | 269 | ||
| 265 | // Some command line options or some combinations of them are not allowed. | 270 | // Some command line options or some combinations of them are not allowed. |
| ... | @@ -290,11 +295,21 @@ static void checkOptions(opt::InputArgList &Args) { | ... | @@ -290,11 +295,21 @@ static void checkOptions(opt::InputArgList &Args) { |
| 290 | error("-r and -shared may not be used together"); | 295 | error("-r and -shared may not be used together"); |
| 291 | if (Config->GcSections) | 296 | if (Config->GcSections) |
| 292 | error("-r and --gc-sections may not be used together"); | 297 | error("-r and --gc-sections may not be used together"); |
| 293 | if (Config->ICF) | 298 | if (Config->GdbIndex) |
| 299 | error("-r and --gdb-index may not be used together"); | ||
| 300 | if (Config->ICF != ICFLevel::None) | ||
| 294 | error("-r and --icf may not be used together"); | 301 | error("-r and --icf may not be used together"); |
| 295 | if (Config->Pie) | 302 | if (Config->Pie) |
| 296 | error("-r and -pie may not be used together"); | 303 | error("-r and -pie may not be used together"); |
| 297 | } | 304 | } |
| 305 | |||
| 306 | if (Config->ExecuteOnly) { | ||
| 307 | if (Config->EMachine != EM_AARCH64) | ||
| 308 | error("-execute-only is only supported on AArch64 targets"); | ||
| 309 | |||
| 310 | if (Config->SingleRoRx && !Script->HasSectionsCommand) | ||
| 311 | error("-execute-only and -no-rosegment cannot be used together"); | ||
| 312 | } | ||
| 298 | } | 313 | } |
| 299 | 314 | ||
| 300 | static const char *getReproduceOption(opt::InputArgList &Args) { | 315 | static const char *getReproduceOption(opt::InputArgList &Args) { |
| ... | @@ -310,7 +325,37 @@ static bool hasZOption(opt::InputArgList &Args, StringRef Key) { | ... | @@ -310,7 +325,37 @@ static bool hasZOption(opt::InputArgList &Args, StringRef Key) { |
| 310 | return false; | 325 | return false; |
| 311 | } | 326 | } |
| 312 | 327 | ||
| 313 | void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { | 328 | static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2, |
| 329 | bool Default) { | ||
| 330 | for (auto *Arg : Args.filtered_reverse(OPT_z)) { | ||
| 331 | if (K1 == Arg->getValue()) | ||
| 332 | return true; | ||
| 333 | if (K2 == Arg->getValue()) | ||
| 334 | return false; | ||
| 335 | } | ||
| 336 | return Default; | ||
| 337 | } | ||
| 338 | |||
| 339 | static bool isKnown(StringRef S) { | ||
| 340 | return S == "combreloc" || S == "copyreloc" || S == "defs" || | ||
| 341 | S == "execstack" || S == "hazardplt" || S == "initfirst" || | ||
| 342 | S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" || | ||
| 343 | S == "nocombreloc" || S == "nocopyreloc" || S == "nodelete" || | ||
| 344 | S == "nodlopen" || S == "noexecstack" || | ||
| 345 | S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" || | ||
| 346 | S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" || | ||
| 347 | S == "rodynamic" || S == "text" || S == "wxneeded" || | ||
| 348 | S.startswith("max-page-size=") || S.startswith("stack-size="); | ||
| 349 | } | ||
| 350 | |||
| 351 | // Report an error for an unknown -z option. | ||
| 352 | static void checkZOptions(opt::InputArgList &Args) { | ||
| 353 | for (auto *Arg : Args.filtered(OPT_z)) | ||
| 354 | if (!isKnown(Arg->getValue())) | ||
| 355 | error("unknown -z value: " + StringRef(Arg->getValue())); | ||
| 356 | } | ||
| 357 | |||
| 358 | void LinkerDriver::main(ArrayRef<const char *> ArgsArr) { | ||
| 314 | ELFOptTable Parser; | 359 | ELFOptTable Parser; |
| 315 | opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); | 360 | opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); |
| 316 | 361 | ||
| ... | @@ -319,7 +364,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { | ... | @@ -319,7 +364,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { |
| 319 | 364 | ||
| 320 | // Handle -help | 365 | // Handle -help |
| 321 | if (Args.hasArg(OPT_help)) { | 366 | if (Args.hasArg(OPT_help)) { |
| 322 | printHelp(ArgsArr[0]); | 367 | printHelp(); |
| 323 | return; | 368 | return; |
| 324 | } | 369 | } |
| 325 | 370 | ||
| ... | @@ -348,9 +393,6 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { | ... | @@ -348,9 +393,6 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { |
| 348 | if (Args.hasArg(OPT_version)) | 393 | if (Args.hasArg(OPT_version)) |
| 349 | return; | 394 | return; |
| 350 | 395 | ||
| 351 | Config->ExitEarly = CanExitEarly && !Args.hasArg(OPT_full_shutdown); | ||
| 352 | errorHandler().ExitEarly = Config->ExitEarly; | ||
| 353 | |||
| 354 | if (const char *Path = getReproduceOption(Args)) { | 396 | if (const char *Path = getReproduceOption(Args)) { |
| 355 | // Note that --reproduce is a debug option so you can ignore it | 397 | // Note that --reproduce is a debug option so you can ignore it |
| 356 | // if you are trying to understand the whole picture of the code. | 398 | // if you are trying to understand the whole picture of the code. |
| ... | @@ -368,10 +410,14 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { | ... | @@ -368,10 +410,14 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { |
| 368 | } | 410 | } |
| 369 | 411 | ||
| 370 | readConfigs(Args); | 412 | readConfigs(Args); |
| 371 | initLLVM(Args); | 413 | checkZOptions(Args); |
| 414 | initLLVM(); | ||
| 372 | createFiles(Args); | 415 | createFiles(Args); |
| 416 | if (errorCount()) | ||
| 417 | return; | ||
| 418 | |||
| 373 | inferMachineType(); | 419 | inferMachineType(); |
| 374 | setConfigs(); | 420 | setConfigs(Args); |
| 375 | checkOptions(Args); | 421 | checkOptions(Args); |
| 376 | if (errorCount()) | 422 | if (errorCount()) |
| 377 | return; | 423 | return; |
| ... | @@ -455,6 +501,8 @@ static bool isOutputFormatBinary(opt::InputArgList &Args) { | ... | @@ -455,6 +501,8 @@ static bool isOutputFormatBinary(opt::InputArgList &Args) { |
| 455 | StringRef S = Arg->getValue(); | 501 | StringRef S = Arg->getValue(); |
| 456 | if (S == "binary") | 502 | if (S == "binary") |
| 457 | return true; | 503 | return true; |
| 504 | if (S.startswith("elf")) | ||
| 505 | return false; | ||
| 458 | error("unknown --oformat value: " + S); | 506 | error("unknown --oformat value: " + S); |
| 459 | } | 507 | } |
| 460 | return false; | 508 | return false; |
| ... | @@ -482,6 +530,15 @@ static StringRef getDynamicLinker(opt::InputArgList &Args) { | ... | @@ -482,6 +530,15 @@ static StringRef getDynamicLinker(opt::InputArgList &Args) { |
| 482 | return Arg->getValue(); | 530 | return Arg->getValue(); |
| 483 | } | 531 | } |
| 484 | 532 | ||
| 533 | static ICFLevel getICF(opt::InputArgList &Args) { | ||
| 534 | auto *Arg = Args.getLastArg(OPT_icf_none, OPT_icf_safe, OPT_icf_all); | ||
| 535 | if (!Arg || Arg->getOption().getID() == OPT_icf_none) | ||
| 536 | return ICFLevel::None; | ||
| 537 | if (Arg->getOption().getID() == OPT_icf_safe) | ||
| 538 | return ICFLevel::Safe; | ||
| 539 | return ICFLevel::All; | ||
| 540 | } | ||
| 541 | |||
| 485 | static StripPolicy getStrip(opt::InputArgList &Args) { | 542 | static StripPolicy getStrip(opt::InputArgList &Args) { |
| 486 | if (Args.hasArg(OPT_relocatable)) | 543 | if (Args.hasArg(OPT_relocatable)) |
| 487 | return StripPolicy::None; | 544 | return StripPolicy::None; |
| ... | @@ -556,6 +613,8 @@ getBuildId(opt::InputArgList &Args) { | ... | @@ -556,6 +613,8 @@ getBuildId(opt::InputArgList &Args) { |
| 556 | return {BuildIdKind::Fast, {}}; | 613 | return {BuildIdKind::Fast, {}}; |
| 557 | 614 | ||
| 558 | StringRef S = Arg->getValue(); | 615 | StringRef S = Arg->getValue(); |
| 616 | if (S == "fast") | ||
| 617 | return {BuildIdKind::Fast, {}}; | ||
| 559 | if (S == "md5") | 618 | if (S == "md5") |
| 560 | return {BuildIdKind::Md5, {}}; | 619 | return {BuildIdKind::Md5, {}}; |
| 561 | if (S == "sha1" || S == "tree") | 620 | if (S == "sha1" || S == "tree") |
| ... | @@ -570,6 +629,57 @@ getBuildId(opt::InputArgList &Args) { | ... | @@ -570,6 +629,57 @@ getBuildId(opt::InputArgList &Args) { |
| 570 | return {BuildIdKind::None, {}}; | 629 | return {BuildIdKind::None, {}}; |
| 571 | } | 630 | } |
| 572 | 631 | ||
| 632 | static std::pair<bool, bool> getPackDynRelocs(opt::InputArgList &Args) { | ||
| 633 | StringRef S = Args.getLastArgValue(OPT_pack_dyn_relocs, "none"); | ||
| 634 | if (S == "android") | ||
| 635 | return {true, false}; | ||
| 636 | if (S == "relr") | ||
| 637 | return {false, true}; | ||
| 638 | if (S == "android+relr") | ||
| 639 | return {true, true}; | ||
| 640 | |||
| 641 | if (S != "none") | ||
| 642 | error("unknown -pack-dyn-relocs format: " + S); | ||
| 643 | return {false, false}; | ||
| 644 | } | ||
| 645 | |||
| 646 | static void readCallGraph(MemoryBufferRef MB) { | ||
| 647 | // Build a map from symbol name to section | ||
| 648 | DenseMap<StringRef, const Symbol *> SymbolNameToSymbol; | ||
| 649 | for (InputFile *File : ObjectFiles) | ||
| 650 | for (Symbol *Sym : File->getSymbols()) | ||
| 651 | SymbolNameToSymbol[Sym->getName()] = Sym; | ||
| 652 | |||
| 653 | for (StringRef L : args::getLines(MB)) { | ||
| 654 | SmallVector<StringRef, 3> Fields; | ||
| 655 | L.split(Fields, ' '); | ||
| 656 | uint64_t Count; | ||
| 657 | if (Fields.size() != 3 || !to_integer(Fields[2], Count)) | ||
| 658 | fatal(MB.getBufferIdentifier() + ": parse error"); | ||
| 659 | const Symbol *FromSym = SymbolNameToSymbol.lookup(Fields[0]); | ||
| 660 | const Symbol *ToSym = SymbolNameToSymbol.lookup(Fields[1]); | ||
| 661 | if (Config->WarnSymbolOrdering) { | ||
| 662 | if (!FromSym) | ||
| 663 | warn(MB.getBufferIdentifier() + ": no such symbol: " + Fields[0]); | ||
| 664 | if (!ToSym) | ||
| 665 | warn(MB.getBufferIdentifier() + ": no such symbol: " + Fields[1]); | ||
| 666 | } | ||
| 667 | if (!FromSym || !ToSym || Count == 0) | ||
| 668 | continue; | ||
| 669 | warnUnorderableSymbol(FromSym); | ||
| 670 | warnUnorderableSymbol(ToSym); | ||
| 671 | const Defined *FromSymD = dyn_cast<Defined>(FromSym); | ||
| 672 | const Defined *ToSymD = dyn_cast<Defined>(ToSym); | ||
| 673 | if (!FromSymD || !ToSymD) | ||
| 674 | continue; | ||
| 675 | const auto *FromSB = dyn_cast_or_null<InputSectionBase>(FromSymD->Section); | ||
| 676 | const auto *ToSB = dyn_cast_or_null<InputSectionBase>(ToSymD->Section); | ||
| 677 | if (!FromSB || !ToSB) | ||
| 678 | continue; | ||
| 679 | Config->CallGraphProfile[std::make_pair(FromSB, ToSB)] += Count; | ||
| 680 | } | ||
| 681 | } | ||
| 682 | |||
| 573 | static bool getCompressDebugSections(opt::InputArgList &Args) { | 683 | static bool getCompressDebugSections(opt::InputArgList &Args) { |
| 574 | StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none"); | 684 | StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none"); |
| 575 | if (S == "none") | 685 | if (S == "none") |
| ... | @@ -581,54 +691,100 @@ static bool getCompressDebugSections(opt::InputArgList &Args) { | ... | @@ -581,54 +691,100 @@ static bool getCompressDebugSections(opt::InputArgList &Args) { |
| 581 | return true; | 691 | return true; |
| 582 | } | 692 | } |
| 583 | 693 | ||
| 584 | static int parseInt(StringRef S, opt::Arg *Arg) { | 694 | static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &Args, |
| 585 | int V = 0; | 695 | unsigned Id) { |
| 586 | if (!to_integer(S, V, 10)) | 696 | auto *Arg = Args.getLastArg(Id); |
| 587 | error(Arg->getSpelling() + ": number expected, but got '" + S + "'"); | 697 | if (!Arg) |
| 588 | return V; | 698 | return {"", ""}; |
| 699 | |||
| 700 | StringRef S = Arg->getValue(); | ||
| 701 | std::pair<StringRef, StringRef> Ret = S.split(';'); | ||
| 702 | if (Ret.second.empty()) | ||
| 703 | error(Arg->getSpelling() + " expects 'old;new' format, but got " + S); | ||
| 704 | return Ret; | ||
| 705 | } | ||
| 706 | |||
| 707 | // Parse the symbol ordering file and warn for any duplicate entries. | ||
| 708 | static std::vector<StringRef> getSymbolOrderingFile(MemoryBufferRef MB) { | ||
| 709 | SetVector<StringRef> Names; | ||
| 710 | for (StringRef S : args::getLines(MB)) | ||
| 711 | if (!Names.insert(S) && Config->WarnSymbolOrdering) | ||
| 712 | warn(MB.getBufferIdentifier() + ": duplicate ordered symbol: " + S); | ||
| 713 | |||
| 714 | return Names.takeVector(); | ||
| 715 | } | ||
| 716 | |||
| 717 | static void parseClangOption(StringRef Opt, const Twine &Msg) { | ||
| 718 | std::string Err; | ||
| 719 | raw_string_ostream OS(Err); | ||
| 720 | |||
| 721 | const char *Argv[] = {Config->ProgName.data(), Opt.data()}; | ||
| 722 | if (cl::ParseCommandLineOptions(2, Argv, "", &OS)) | ||
| 723 | return; | ||
| 724 | OS.flush(); | ||
| 725 | error(Msg + ": " + StringRef(Err).trim()); | ||
| 589 | } | 726 | } |
| 590 | 727 | ||
| 591 | // Initializes Config members by the command line options. | 728 | // Initializes Config members by the command line options. |
| 592 | void LinkerDriver::readConfigs(opt::InputArgList &Args) { | 729 | void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 730 | errorHandler().Verbose = Args.hasArg(OPT_verbose); | ||
| 731 | errorHandler().FatalWarnings = | ||
| 732 | Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); | ||
| 733 | ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); | ||
| 734 | |||
| 593 | Config->AllowMultipleDefinition = | 735 | Config->AllowMultipleDefinition = |
| 594 | Args.hasArg(OPT_allow_multiple_definition) || hasZOption(Args, "muldefs"); | 736 | Args.hasFlag(OPT_allow_multiple_definition, |
| 737 | OPT_no_allow_multiple_definition, false) || | ||
| 738 | hasZOption(Args, "muldefs"); | ||
| 595 | Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary); | 739 | Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary); |
| 596 | Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); | 740 | Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); |
| 597 | Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); | 741 | Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); |
| 742 | Config->CheckSections = | ||
| 743 | Args.hasFlag(OPT_check_sections, OPT_no_check_sections, true); | ||
| 598 | Config->Chroot = Args.getLastArgValue(OPT_chroot); | 744 | Config->Chroot = Args.getLastArgValue(OPT_chroot); |
| 599 | Config->CompressDebugSections = getCompressDebugSections(Args); | 745 | Config->CompressDebugSections = getCompressDebugSections(Args); |
| 746 | Config->Cref = Args.hasFlag(OPT_cref, OPT_no_cref, false); | ||
| 600 | Config->DefineCommon = Args.hasFlag(OPT_define_common, OPT_no_define_common, | 747 | Config->DefineCommon = Args.hasFlag(OPT_define_common, OPT_no_define_common, |
| 601 | !Args.hasArg(OPT_relocatable)); | 748 | !Args.hasArg(OPT_relocatable)); |
| 602 | Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true); | 749 | Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true); |
| 603 | Config->DisableVerify = Args.hasArg(OPT_disable_verify); | 750 | Config->DisableVerify = Args.hasArg(OPT_disable_verify); |
| 604 | Config->Discard = getDiscard(Args); | 751 | Config->Discard = getDiscard(Args); |
| 752 | Config->DwoDir = Args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq); | ||
| 605 | Config->DynamicLinker = getDynamicLinker(Args); | 753 | Config->DynamicLinker = getDynamicLinker(Args); |
| 606 | Config->EhFrameHdr = | 754 | Config->EhFrameHdr = |
| 607 | Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false); | 755 | Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false); |
| 608 | Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); | 756 | Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); |
| 609 | Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags); | 757 | Config->EnableNewDtags = |
| 758 | Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true); | ||
| 610 | Config->Entry = Args.getLastArgValue(OPT_entry); | 759 | Config->Entry = Args.getLastArgValue(OPT_entry); |
| 760 | Config->ExecuteOnly = | ||
| 761 | Args.hasFlag(OPT_execute_only, OPT_no_execute_only, false); | ||
| 611 | Config->ExportDynamic = | 762 | Config->ExportDynamic = |
| 612 | Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false); | 763 | Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false); |
| 613 | errorHandler().FatalWarnings = | ||
| 614 | Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); | ||
| 615 | Config->FilterList = args::getStrings(Args, OPT_filter); | 764 | Config->FilterList = args::getStrings(Args, OPT_filter); |
| 616 | Config->Fini = Args.getLastArgValue(OPT_fini, "_fini"); | 765 | Config->Fini = Args.getLastArgValue(OPT_fini, "_fini"); |
| 617 | Config->FixCortexA53Errata843419 = Args.hasArg(OPT_fix_cortex_a53_843419); | 766 | Config->FixCortexA53Errata843419 = Args.hasArg(OPT_fix_cortex_a53_843419); |
| 618 | Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false); | 767 | Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false); |
| 768 | Config->GnuUnique = Args.hasFlag(OPT_gnu_unique, OPT_no_gnu_unique, true); | ||
| 619 | Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false); | 769 | Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false); |
| 620 | Config->ICF = Args.hasFlag(OPT_icf_all, OPT_icf_none, false); | 770 | Config->ICF = getICF(Args); |
| 621 | Config->ICFData = Args.hasArg(OPT_icf_data); | 771 | Config->IgnoreDataAddressEquality = |
| 772 | Args.hasArg(OPT_ignore_data_address_equality); | ||
| 773 | Config->IgnoreFunctionAddressEquality = | ||
| 774 | Args.hasArg(OPT_ignore_function_address_equality); | ||
| 622 | Config->Init = Args.getLastArgValue(OPT_init, "_init"); | 775 | Config->Init = Args.getLastArgValue(OPT_init, "_init"); |
| 623 | Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline); | 776 | Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline); |
| 777 | Config->LTODebugPassManager = Args.hasArg(OPT_lto_debug_pass_manager); | ||
| 778 | Config->LTONewPassManager = Args.hasArg(OPT_lto_new_pass_manager); | ||
| 624 | Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes); | 779 | Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes); |
| 625 | Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); | 780 | Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); |
| 781 | Config->LTOObjPath = Args.getLastArgValue(OPT_plugin_opt_obj_path_eq); | ||
| 626 | Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1); | 782 | Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1); |
| 783 | Config->LTOSampleProfile = Args.getLastArgValue(OPT_lto_sample_profile); | ||
| 627 | Config->MapFile = Args.getLastArgValue(OPT_Map); | 784 | Config->MapFile = Args.getLastArgValue(OPT_Map); |
| 628 | Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique); | 785 | Config->MipsGotSize = args::getInteger(Args, OPT_mips_got_size, 0xfff0); |
| 629 | Config->MergeArmExidx = | 786 | Config->MergeArmExidx = |
| 630 | Args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true); | 787 | Args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true); |
| 631 | Config->NoUndefinedVersion = Args.hasArg(OPT_no_undefined_version); | ||
| 632 | Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec); | 788 | Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec); |
| 633 | Config->Nostdlib = Args.hasArg(OPT_nostdlib); | 789 | Config->Nostdlib = Args.hasArg(OPT_nostdlib); |
| 634 | Config->OFormatBinary = isOutputFormatBinary(Args); | 790 | Config->OFormatBinary = isOutputFormatBinary(Args); |
| ... | @@ -638,7 +794,9 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { | ... | @@ -638,7 +794,9 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 638 | Config->Optimize = args::getInteger(Args, OPT_O, 1); | 794 | Config->Optimize = args::getInteger(Args, OPT_O, 1); |
| 639 | Config->OrphanHandling = getOrphanHandling(Args); | 795 | Config->OrphanHandling = getOrphanHandling(Args); |
| 640 | Config->OutputFile = Args.getLastArgValue(OPT_o); | 796 | Config->OutputFile = Args.getLastArgValue(OPT_o); |
| 641 | Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false); | 797 | Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false); |
| 798 | Config->PrintIcfSections = | ||
| 799 | Args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false); | ||
| 642 | Config->PrintGcSections = | 800 | Config->PrintGcSections = |
| 643 | Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); | 801 | Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); |
| 644 | Config->Rpath = getRpath(Args); | 802 | Config->Rpath = getRpath(Args); |
| ... | @@ -658,47 +816,58 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { | ... | @@ -658,47 +816,58 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 658 | Config->ThinLTOCachePolicy = CHECK( | 816 | Config->ThinLTOCachePolicy = CHECK( |
| 659 | parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)), | 817 | parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)), |
| 660 | "--thinlto-cache-policy: invalid cache policy"); | 818 | "--thinlto-cache-policy: invalid cache policy"); |
| 819 | Config->ThinLTOEmitImportsFiles = | ||
| 820 | Args.hasArg(OPT_plugin_opt_thinlto_emit_imports_files); | ||
| 821 | Config->ThinLTOIndexOnly = Args.hasArg(OPT_plugin_opt_thinlto_index_only) || | ||
| 822 | Args.hasArg(OPT_plugin_opt_thinlto_index_only_eq); | ||
| 823 | Config->ThinLTOIndexOnlyArg = | ||
| 824 | Args.getLastArgValue(OPT_plugin_opt_thinlto_index_only_eq); | ||
| 661 | Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u); | 825 | Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u); |
| 662 | ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); | 826 | Config->ThinLTOObjectSuffixReplace = |
| 827 | getOldNewOptions(Args, OPT_plugin_opt_thinlto_object_suffix_replace_eq); | ||
| 828 | Config->ThinLTOPrefixReplace = | ||
| 829 | getOldNewOptions(Args, OPT_plugin_opt_thinlto_prefix_replace_eq); | ||
| 663 | Config->Trace = Args.hasArg(OPT_trace); | 830 | Config->Trace = Args.hasArg(OPT_trace); |
| 664 | Config->Undefined = args::getStrings(Args, OPT_undefined); | 831 | Config->Undefined = args::getStrings(Args, OPT_undefined); |
| 832 | Config->UndefinedVersion = | ||
| 833 | Args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true); | ||
| 834 | Config->UseAndroidRelrTags = Args.hasFlag( | ||
| 835 | OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false); | ||
| 665 | Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args); | 836 | Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args); |
| 666 | Config->Verbose = Args.hasArg(OPT_verbose); | 837 | Config->WarnBackrefs = |
| 667 | errorHandler().Verbose = Config->Verbose; | 838 | Args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false); |
| 668 | Config->WarnCommon = Args.hasArg(OPT_warn_common); | 839 | Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false); |
| 669 | Config->ZCombreloc = !hasZOption(Args, "nocombreloc"); | 840 | Config->WarnSymbolOrdering = |
| 670 | Config->ZExecstack = hasZOption(Args, "execstack"); | 841 | Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true); |
| 671 | Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc"); | 842 | Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true); |
| 843 | Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true); | ||
| 844 | Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false); | ||
| 845 | Config->ZHazardplt = hasZOption(Args, "hazardplt"); | ||
| 846 | Config->ZInitfirst = hasZOption(Args, "initfirst"); | ||
| 847 | Config->ZKeepTextSectionPrefix = getZFlag( | ||
| 848 | Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false); | ||
| 672 | Config->ZNodelete = hasZOption(Args, "nodelete"); | 849 | Config->ZNodelete = hasZOption(Args, "nodelete"); |
| 673 | Config->ZNodlopen = hasZOption(Args, "nodlopen"); | 850 | Config->ZNodlopen = hasZOption(Args, "nodlopen"); |
| 674 | Config->ZNow = hasZOption(Args, "now"); | 851 | Config->ZNow = getZFlag(Args, "now", "lazy", false); |
| 675 | Config->ZOrigin = hasZOption(Args, "origin"); | 852 | Config->ZOrigin = hasZOption(Args, "origin"); |
| 676 | Config->ZRelro = !hasZOption(Args, "norelro"); | 853 | Config->ZRelro = getZFlag(Args, "relro", "norelro", true); |
| 677 | Config->ZRetpolineplt = hasZOption(Args, "retpolineplt"); | 854 | Config->ZRetpolineplt = hasZOption(Args, "retpolineplt"); |
| 678 | Config->ZRodynamic = hasZOption(Args, "rodynamic"); | 855 | Config->ZRodynamic = hasZOption(Args, "rodynamic"); |
| 679 | Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0); | 856 | Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0); |
| 680 | Config->ZText = !hasZOption(Args, "notext"); | 857 | Config->ZText = getZFlag(Args, "text", "notext", true); |
| 681 | Config->ZWxneeded = hasZOption(Args, "wxneeded"); | 858 | Config->ZWxneeded = hasZOption(Args, "wxneeded"); |
| 682 | 859 | ||
| 683 | // Parse LTO plugin-related options for compatibility with gold. | 860 | // Parse LTO options. |
| 684 | for (auto *Arg : Args.filtered(OPT_plugin_opt, OPT_plugin_opt_eq)) { | 861 | if (auto *Arg = Args.getLastArg(OPT_plugin_opt_mcpu_eq)) |
| 685 | StringRef S = Arg->getValue(); | 862 | parseClangOption(Saver.save("-mcpu=" + StringRef(Arg->getValue())), |
| 686 | if (S == "disable-verify") | 863 | Arg->getSpelling()); |
| 687 | Config->DisableVerify = true; | 864 | |
| 688 | else if (S == "save-temps") | 865 | for (auto *Arg : Args.filtered(OPT_plugin_opt)) |
| 689 | Config->SaveTemps = true; | 866 | parseClangOption(Arg->getValue(), Arg->getSpelling()); |
| 690 | else if (S.startswith("O")) | 867 | |
| 691 | Config->LTOO = parseInt(S.substr(1), Arg); | 868 | // Parse -mllvm options. |
| 692 | else if (S.startswith("lto-partitions=")) | 869 | for (auto *Arg : Args.filtered(OPT_mllvm)) |
| 693 | Config->LTOPartitions = parseInt(S.substr(15), Arg); | 870 | parseClangOption(Arg->getValue(), Arg->getSpelling()); |
| 694 | else if (S.startswith("jobs=")) | ||
| 695 | Config->ThinLTOJobs = parseInt(S.substr(5), Arg); | ||
| 696 | else if (!S.startswith("/") && !S.startswith("-fresolution=") && | ||
| 697 | !S.startswith("-pass-through=") && !S.startswith("mcpu=") && | ||
| 698 | !S.startswith("thinlto") && S != "-function-sections" && | ||
| 699 | S != "-data-sections") | ||
| 700 | error(Arg->getSpelling() + ": unknown option: " + S); | ||
| 701 | } | ||
| 702 | 871 | ||
| 703 | if (Config->LTOO > 3) | 872 | if (Config->LTOO > 3) |
| 704 | error("invalid optimization level for LTO: " + Twine(Config->LTOO)); | 873 | error("invalid optimization level for LTO: " + Twine(Config->LTOO)); |
| ... | @@ -741,17 +910,12 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { | ... | @@ -741,17 +910,12 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 741 | 910 | ||
| 742 | std::tie(Config->BuildId, Config->BuildIdVector) = getBuildId(Args); | 911 | std::tie(Config->BuildId, Config->BuildIdVector) = getBuildId(Args); |
| 743 | 912 | ||
| 744 | if (auto *Arg = Args.getLastArg(OPT_pack_dyn_relocs_eq)) { | 913 | std::tie(Config->AndroidPackDynRelocs, Config->RelrPackDynRelocs) = |
| 745 | StringRef S = Arg->getValue(); | 914 | getPackDynRelocs(Args); |
| 746 | if (S == "android") | ||
| 747 | Config->AndroidPackDynRelocs = true; | ||
| 748 | else if (S != "none") | ||
| 749 | error("unknown -pack-dyn-relocs format: " + S); | ||
| 750 | } | ||
| 751 | 915 | ||
| 752 | if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file)) | 916 | if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file)) |
| 753 | if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) | 917 | if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) |
| 754 | Config->SymbolOrderingFile = args::getLines(*Buffer); | 918 | Config->SymbolOrderingFile = getSymbolOrderingFile(*Buffer); |
| 755 | 919 | ||
| 756 | // If --retain-symbol-file is used, we'll keep only the symbols listed in | 920 | // If --retain-symbol-file is used, we'll keep only the symbols listed in |
| 757 | // the file and discard all others. | 921 | // the file and discard all others. |
| ... | @@ -779,32 +943,67 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { | ... | @@ -779,32 +943,67 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { |
| 779 | {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false}); | 943 | {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false}); |
| 780 | } | 944 | } |
| 781 | 945 | ||
| 946 | // If --export-dynamic-symbol=foo is given and symbol foo is defined in | ||
| 947 | // an object file in an archive file, that object file should be pulled | ||
| 948 | // out and linked. (It doesn't have to behave like that from technical | ||
| 949 | // point of view, but this is needed for compatibility with GNU.) | ||
| 950 | for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol)) | ||
| 951 | Config->Undefined.push_back(Arg->getValue()); | ||
| 952 | |||
| 782 | for (auto *Arg : Args.filtered(OPT_version_script)) | 953 | for (auto *Arg : Args.filtered(OPT_version_script)) |
| 783 | if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) | 954 | if (Optional<std::string> Path = searchScript(Arg->getValue())) { |
| 784 | readVersionScript(*Buffer); | 955 | if (Optional<MemoryBufferRef> Buffer = readFile(*Path)) |
| 956 | readVersionScript(*Buffer); | ||
| 957 | } else { | ||
| 958 | error(Twine("cannot find version script ") + Arg->getValue()); | ||
| 959 | } | ||
| 785 | } | 960 | } |
| 786 | 961 | ||
| 787 | // Some Config members do not directly correspond to any particular | 962 | // Some Config members do not directly correspond to any particular |
| 788 | // command line options, but computed based on other Config values. | 963 | // command line options, but computed based on other Config values. |
| 789 | // This function initialize such members. See Config.h for the details | 964 | // This function initialize such members. See Config.h for the details |
| 790 | // of these values. | 965 | // of these values. |
| 791 | static void setConfigs() { | 966 | static void setConfigs(opt::InputArgList &Args) { |
| 792 | ELFKind Kind = Config->EKind; | 967 | ELFKind Kind = Config->EKind; |
| 793 | uint16_t Machine = Config->EMachine; | 968 | uint16_t Machine = Config->EMachine; |
| 794 | 969 | ||
| 795 | // There is an ILP32 ABI for x86-64, although it's not very popular. | ||
| 796 | // It is called the x32 ABI. | ||
| 797 | bool IsX32 = (Kind == ELF32LEKind && Machine == EM_X86_64); | ||
| 798 | |||
| 799 | Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs); | 970 | Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs); |
| 800 | Config->Is64 = (Kind == ELF64LEKind || Kind == ELF64BEKind); | 971 | Config->Is64 = (Kind == ELF64LEKind || Kind == ELF64BEKind); |
| 801 | Config->IsLE = (Kind == ELF32LEKind || Kind == ELF64LEKind); | 972 | Config->IsLE = (Kind == ELF32LEKind || Kind == ELF64LEKind); |
| 802 | Config->Endianness = | 973 | Config->Endianness = |
| 803 | Config->IsLE ? support::endianness::little : support::endianness::big; | 974 | Config->IsLE ? support::endianness::little : support::endianness::big; |
| 804 | Config->IsMips64EL = (Kind == ELF64LEKind && Machine == EM_MIPS); | 975 | Config->IsMips64EL = (Kind == ELF64LEKind && Machine == EM_MIPS); |
| 805 | Config->IsRela = Config->Is64 || IsX32 || Config->MipsN32Abi; | ||
| 806 | Config->Pic = Config->Pie || Config->Shared; | 976 | Config->Pic = Config->Pie || Config->Shared; |
| 807 | Config->Wordsize = Config->Is64 ? 8 : 4; | 977 | Config->Wordsize = Config->Is64 ? 8 : 4; |
| 978 | |||
| 979 | // There is an ILP32 ABI for x86-64, although it's not very popular. | ||
| 980 | // It is called the x32 ABI. | ||
| 981 | bool IsX32 = (Kind == ELF32LEKind && Machine == EM_X86_64); | ||
| 982 | |||
| 983 | // ELF defines two different ways to store relocation addends as shown below: | ||
| 984 | // | ||
| 985 | // Rel: Addends are stored to the location where relocations are applied. | ||
| 986 | // Rela: Addends are stored as part of relocation entry. | ||
| 987 | // | ||
| 988 | // In other words, Rela makes it easy to read addends at the price of extra | ||
| 989 | // 4 or 8 byte for each relocation entry. We don't know why ELF defined two | ||
| 990 | // different mechanisms in the first place, but this is how the spec is | ||
| 991 | // defined. | ||
| 992 | // | ||
| 993 | // You cannot choose which one, Rel or Rela, you want to use. Instead each | ||
| 994 | // ABI defines which one you need to use. The following expression expresses | ||
| 995 | // that. | ||
| 996 | Config->IsRela = | ||
| 997 | (Config->Is64 || IsX32 || Machine == EM_PPC) && Machine != EM_MIPS; | ||
| 998 | |||
| 999 | // If the output uses REL relocations we must store the dynamic relocation | ||
| 1000 | // addends to the output sections. We also store addends for RELA relocations | ||
| 1001 | // if --apply-dynamic-relocs is used. | ||
| 1002 | // We default to not writing the addends when using RELA relocations since | ||
| 1003 | // any standard conforming tool can find it in r_addend. | ||
| 1004 | Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs, | ||
| 1005 | OPT_no_apply_dynamic_relocs, false) || | ||
| 1006 | !Config->IsRela; | ||
| 808 | } | 1007 | } |
| 809 | 1008 | ||
| 810 | // Returns a value of "-format" option. | 1009 | // Returns a value of "-format" option. |
| ... | @@ -819,6 +1018,10 @@ static bool getBinaryOption(StringRef S) { | ... | @@ -819,6 +1018,10 @@ static bool getBinaryOption(StringRef S) { |
| 819 | } | 1018 | } |
| 820 | 1019 | ||
| 821 | void LinkerDriver::createFiles(opt::InputArgList &Args) { | 1020 | void LinkerDriver::createFiles(opt::InputArgList &Args) { |
| 1021 | // For --{push,pop}-state. | ||
| 1022 | std::vector<std::tuple<bool, bool, bool>> Stack; | ||
| 1023 | |||
| 1024 | // Iterate over argv to process input files and positional arguments. | ||
| 822 | for (auto *Arg : Args) { | 1025 | for (auto *Arg : Args) { |
| 823 | switch (Arg->getOption().getUnaliasedOption().getID()) { | 1026 | switch (Arg->getOption().getUnaliasedOption().getID()) { |
| 824 | case OPT_library: | 1027 | case OPT_library: |
| ... | @@ -827,8 +1030,15 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) { | ... | @@ -827,8 +1030,15 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) { |
| 827 | case OPT_INPUT: | 1030 | case OPT_INPUT: |
| 828 | addFile(Arg->getValue(), /*WithLOption=*/false); | 1031 | addFile(Arg->getValue(), /*WithLOption=*/false); |
| 829 | break; | 1032 | break; |
| 1033 | case OPT_defsym: { | ||
| 1034 | StringRef From; | ||
| 1035 | StringRef To; | ||
| 1036 | std::tie(From, To) = StringRef(Arg->getValue()).split('='); | ||
| 1037 | readDefsym(From, MemoryBufferRef(To, "-defsym")); | ||
| 1038 | break; | ||
| 1039 | } | ||
| 830 | case OPT_script: | 1040 | case OPT_script: |
| 831 | if (Optional<std::string> Path = searchLinkerScript(Arg->getValue())) { | 1041 | if (Optional<std::string> Path = searchScript(Arg->getValue())) { |
| 832 | if (Optional<MemoryBufferRef> MB = readFile(*Path)) | 1042 | if (Optional<MemoryBufferRef> MB = readFile(*Path)) |
| 833 | readLinkerScript(*MB); | 1043 | readLinkerScript(*MB); |
| 834 | break; | 1044 | break; |
| ... | @@ -856,11 +1066,48 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) { | ... | @@ -856,11 +1066,48 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) { |
| 856 | case OPT_no_whole_archive: | 1066 | case OPT_no_whole_archive: |
| 857 | InWholeArchive = false; | 1067 | InWholeArchive = false; |
| 858 | break; | 1068 | break; |
| 1069 | case OPT_just_symbols: | ||
| 1070 | if (Optional<MemoryBufferRef> MB = readFile(Arg->getValue())) { | ||
| 1071 | Files.push_back(createObjectFile(*MB)); | ||
| 1072 | Files.back()->JustSymbols = true; | ||
| 1073 | } | ||
| 1074 | break; | ||
| 1075 | case OPT_start_group: | ||
| 1076 | if (InputFile::IsInGroup) | ||
| 1077 | error("nested --start-group"); | ||
| 1078 | InputFile::IsInGroup = true; | ||
| 1079 | break; | ||
| 1080 | case OPT_end_group: | ||
| 1081 | if (!InputFile::IsInGroup) | ||
| 1082 | error("stray --end-group"); | ||
| 1083 | InputFile::IsInGroup = false; | ||
| 1084 | ++InputFile::NextGroupId; | ||
| 1085 | break; | ||
| 859 | case OPT_start_lib: | 1086 | case OPT_start_lib: |
| 1087 | if (InLib) | ||
| 1088 | error("nested --start-lib"); | ||
| 1089 | if (InputFile::IsInGroup) | ||
| 1090 | error("may not nest --start-lib in --start-group"); | ||
| 860 | InLib = true; | 1091 | InLib = true; |
| 1092 | InputFile::IsInGroup = true; | ||
| 861 | break; | 1093 | break; |
| 862 | case OPT_end_lib: | 1094 | case OPT_end_lib: |
| 1095 | if (!InLib) | ||
| 1096 | error("stray --end-lib"); | ||
| 863 | InLib = false; | 1097 | InLib = false; |
| 1098 | InputFile::IsInGroup = false; | ||
| 1099 | ++InputFile::NextGroupId; | ||
| 1100 | break; | ||
| 1101 | case OPT_push_state: | ||
| 1102 | Stack.emplace_back(Config->AsNeeded, Config->Static, InWholeArchive); | ||
| 1103 | break; | ||
| 1104 | case OPT_pop_state: | ||
| 1105 | if (Stack.empty()) { | ||
| 1106 | error("unbalanced --push-state/--pop-state"); | ||
| 1107 | break; | ||
| 1108 | } | ||
| 1109 | std::tie(Config->AsNeeded, Config->Static, InWholeArchive) = Stack.back(); | ||
| 1110 | Stack.pop_back(); | ||
| 864 | break; | 1111 | break; |
| 865 | } | 1112 | } |
| 866 | } | 1113 | } |
| ... | @@ -933,14 +1180,6 @@ static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) { | ... | @@ -933,14 +1180,6 @@ static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) { |
| 933 | return Ret; | 1180 | return Ret; |
| 934 | } | 1181 | } |
| 935 | 1182 | ||
| 936 | static Optional<StringRef> getArchiveName(InputFile *File) { | ||
| 937 | if (isa<ArchiveFile>(File)) | ||
| 938 | return File->getName(); | ||
| 939 | if (!File->ArchiveName.empty()) | ||
| 940 | return File->ArchiveName; | ||
| 941 | return None; | ||
| 942 | } | ||
| 943 | |||
| 944 | // Handles the -exclude-libs option. If a static library file is specified | 1183 | // Handles the -exclude-libs option. If a static library file is specified |
| 945 | // by the -exclude-libs option, all public symbols from the archive become | 1184 | // by the -exclude-libs option, all public symbols from the archive become |
| 946 | // private unless otherwise specified by version scripts or something. | 1185 | // private unless otherwise specified by version scripts or something. |
| ... | @@ -948,18 +1187,140 @@ static Optional<StringRef> getArchiveName(InputFile *File) { | ... | @@ -948,18 +1187,140 @@ static Optional<StringRef> getArchiveName(InputFile *File) { |
| 948 | // | 1187 | // |
| 949 | // This is not a popular option, but some programs such as bionic libc use it. | 1188 | // This is not a popular option, but some programs such as bionic libc use it. |
| 950 | template <class ELFT> | 1189 | template <class ELFT> |
| 951 | static void excludeLibs(opt::InputArgList &Args, ArrayRef<InputFile *> Files) { | 1190 | static void excludeLibs(opt::InputArgList &Args) { |
| 952 | DenseSet<StringRef> Libs = getExcludeLibs(Args); | 1191 | DenseSet<StringRef> Libs = getExcludeLibs(Args); |
| 953 | bool All = Libs.count("ALL"); | 1192 | bool All = Libs.count("ALL"); |
| 954 | 1193 | ||
| 955 | for (InputFile *File : Files) | 1194 | auto Visit = [&](InputFile *File) { |
| 956 | if (Optional<StringRef> Archive = getArchiveName(File)) | 1195 | if (!File->ArchiveName.empty()) |
| 957 | if (All || Libs.count(path::filename(*Archive))) | 1196 | if (All || Libs.count(path::filename(File->ArchiveName))) |
| 958 | for (Symbol *Sym : File->getSymbols()) | 1197 | for (Symbol *Sym : File->getSymbols()) |
| 959 | if (!Sym->isLocal()) | 1198 | if (!Sym->isLocal() && Sym->File == File) |
| 960 | Sym->VersionId = VER_NDX_LOCAL; | 1199 | Sym->VersionId = VER_NDX_LOCAL; |
| 1200 | }; | ||
| 1201 | |||
| 1202 | for (InputFile *File : ObjectFiles) | ||
| 1203 | Visit(File); | ||
| 1204 | |||
| 1205 | for (BitcodeFile *File : BitcodeFiles) | ||
| 1206 | Visit(File); | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | // Force Sym to be entered in the output. Used for -u or equivalent. | ||
| 1210 | template <class ELFT> static void handleUndefined(StringRef Name) { | ||
| 1211 | Symbol *Sym = Symtab->find(Name); | ||
| 1212 | if (!Sym) | ||
| 1213 | return; | ||
| 1214 | |||
| 1215 | // Since symbol S may not be used inside the program, LTO may | ||
| 1216 | // eliminate it. Mark the symbol as "used" to prevent it. | ||
| 1217 | Sym->IsUsedInRegularObj = true; | ||
| 1218 | |||
| 1219 | if (Sym->isLazy()) | ||
| 1220 | Symtab->fetchLazy<ELFT>(Sym); | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | template <class ELFT> static bool shouldDemote(Symbol &Sym) { | ||
| 1224 | // If all references to a DSO happen to be weak, the DSO is not added to | ||
| 1225 | // DT_NEEDED. If that happens, we need to eliminate shared symbols created | ||
| 1226 | // from the DSO. Otherwise, they become dangling references that point to a | ||
| 1227 | // non-existent DSO. | ||
| 1228 | if (auto *S = dyn_cast<SharedSymbol>(&Sym)) | ||
| 1229 | return !S->getFile<ELFT>().IsNeeded; | ||
| 1230 | |||
| 1231 | // We are done processing archives, so lazy symbols that were used but not | ||
| 1232 | // found can be converted to undefined. We could also just delete the other | ||
| 1233 | // lazy symbols, but that seems to be more work than it is worth. | ||
| 1234 | return Sym.isLazy() && Sym.IsUsedInRegularObj; | ||
| 961 | } | 1235 | } |
| 962 | 1236 | ||
| 1237 | // Some files, such as .so or files between -{start,end}-lib may be removed | ||
| 1238 | // after their symbols are added to the symbol table. If that happens, we | ||
| 1239 | // need to remove symbols that refer files that no longer exist, so that | ||
| 1240 | // they won't appear in the symbol table of the output file. | ||
| 1241 | // | ||
| 1242 | // We remove symbols by demoting them to undefined symbol. | ||
| 1243 | template <class ELFT> static void demoteSymbols() { | ||
| 1244 | for (Symbol *Sym : Symtab->getSymbols()) { | ||
| 1245 | if (shouldDemote<ELFT>(*Sym)) { | ||
| 1246 | bool Used = Sym->Used; | ||
| 1247 | replaceSymbol<Undefined>(Sym, nullptr, Sym->getName(), Sym->Binding, | ||
| 1248 | Sym->StOther, Sym->Type); | ||
| 1249 | Sym->Used = Used; | ||
| 1250 | } | ||
| 1251 | } | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | // The section referred to by S is considered address-significant. Set the | ||
| 1255 | // KeepUnique flag on the section if appropriate. | ||
| 1256 | static void markAddrsig(Symbol *S) { | ||
| 1257 | if (auto *D = dyn_cast_or_null<Defined>(S)) | ||
| 1258 | if (D->Section) | ||
| 1259 | // We don't need to keep text sections unique under --icf=all even if they | ||
| 1260 | // are address-significant. | ||
| 1261 | if (Config->ICF == ICFLevel::Safe || !(D->Section->Flags & SHF_EXECINSTR)) | ||
| 1262 | D->Section->KeepUnique = true; | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | // Record sections that define symbols mentioned in --keep-unique <symbol> | ||
| 1266 | // and symbols referred to by address-significance tables. These sections are | ||
| 1267 | // ineligible for ICF. | ||
| 1268 | template <class ELFT> | ||
| 1269 | static void findKeepUniqueSections(opt::InputArgList &Args) { | ||
| 1270 | for (auto *Arg : Args.filtered(OPT_keep_unique)) { | ||
| 1271 | StringRef Name = Arg->getValue(); | ||
| 1272 | auto *D = dyn_cast_or_null<Defined>(Symtab->find(Name)); | ||
| 1273 | if (!D || !D->Section) { | ||
| 1274 | warn("could not find symbol " + Name + " to keep unique"); | ||
| 1275 | continue; | ||
| 1276 | } | ||
| 1277 | D->Section->KeepUnique = true; | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | // --icf=all --ignore-data-address-equality means that we can ignore | ||
| 1281 | // the dynsym and address-significance tables entirely. | ||
| 1282 | if (Config->ICF == ICFLevel::All && Config->IgnoreDataAddressEquality) | ||
| 1283 | return; | ||
| 1284 | |||
| 1285 | // Symbols in the dynsym could be address-significant in other executables | ||
| 1286 | // or DSOs, so we conservatively mark them as address-significant. | ||
| 1287 | for (Symbol *S : Symtab->getSymbols()) | ||
| 1288 | if (S->includeInDynsym()) | ||
| 1289 | markAddrsig(S); | ||
| 1290 | |||
| 1291 | // Visit the address-significance table in each object file and mark each | ||
| 1292 | // referenced symbol as address-significant. | ||
| 1293 | for (InputFile *F : ObjectFiles) { | ||
| 1294 | auto *Obj = cast<ObjFile<ELFT>>(F); | ||
| 1295 | ArrayRef<Symbol *> Syms = Obj->getSymbols(); | ||
| 1296 | if (Obj->AddrsigSec) { | ||
| 1297 | ArrayRef<uint8_t> Contents = | ||
| 1298 | check(Obj->getObj().getSectionContents(Obj->AddrsigSec)); | ||
| 1299 | const uint8_t *Cur = Contents.begin(); | ||
| 1300 | while (Cur != Contents.end()) { | ||
| 1301 | unsigned Size; | ||
| 1302 | const char *Err; | ||
| 1303 | uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err); | ||
| 1304 | if (Err) | ||
| 1305 | fatal(toString(F) + ": could not decode addrsig section: " + Err); | ||
| 1306 | markAddrsig(Syms[SymIndex]); | ||
| 1307 | Cur += Size; | ||
| 1308 | } | ||
| 1309 | } else { | ||
| 1310 | // If an object file does not have an address-significance table, | ||
| 1311 | // conservatively mark all of its symbols as address-significant. | ||
| 1312 | for (Symbol *S : Syms) | ||
| 1313 | markAddrsig(S); | ||
| 1314 | } | ||
| 1315 | } | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | static const char *LibcallRoutineNames[] = { | ||
| 1319 | #define HANDLE_LIBCALL(code, name) name, | ||
| 1320 | #include "llvm/IR/RuntimeLibcalls.def" | ||
| 1321 | #undef HANDLE_LIBCALL | ||
| 1322 | }; | ||
| 1323 | |||
| 963 | // Do actual linking. Note that when this function is called, | 1324 | // Do actual linking. Note that when this function is called, |
| 964 | // all linker scripts have already been parsed. | 1325 | // all linker scripts have already been parsed. |
| 965 | template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { | 1326 | template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { |
| ... | @@ -1008,14 +1369,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { | ... | @@ -1008,14 +1369,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { |
| 1008 | for (InputFile *F : Files) | 1369 | for (InputFile *F : Files) |
| 1009 | Symtab->addFile<ELFT>(F); | 1370 | Symtab->addFile<ELFT>(F); |
| 1010 | 1371 | ||
| 1011 | // Process -defsym option. | ||
| 1012 | for (auto *Arg : Args.filtered(OPT_defsym)) { | ||
| 1013 | StringRef From; | ||
| 1014 | StringRef To; | ||
| 1015 | std::tie(From, To) = StringRef(Arg->getValue()).split('='); | ||
| 1016 | readDefsym(From, MemoryBufferRef(To, "-defsym")); | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | // Now that we have every file, we can decide if we will need a | 1372 | // Now that we have every file, we can decide if we will need a |
| 1020 | // dynamic symbol table. | 1373 | // dynamic symbol table. |
| 1021 | // We need one if we were asked to export dynamic symbols or if we are | 1374 | // We need one if we were asked to export dynamic symbols or if we are |
| ... | @@ -1032,24 +1385,39 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { | ... | @@ -1032,24 +1385,39 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { |
| 1032 | 1385 | ||
| 1033 | // Handle the `--undefined <sym>` options. | 1386 | // Handle the `--undefined <sym>` options. |
| 1034 | for (StringRef S : Config->Undefined) | 1387 | for (StringRef S : Config->Undefined) |
| 1035 | Symtab->fetchIfLazy<ELFT>(S); | 1388 | handleUndefined<ELFT>(S); |
| 1036 | 1389 | ||
| 1037 | // If an entry symbol is in a static archive, pull out that file now | 1390 | // If an entry symbol is in a static archive, pull out that file now. |
| 1038 | // to complete the symbol table. After this, no new names except a | 1391 | handleUndefined<ELFT>(Config->Entry); |
| 1039 | // few linker-synthesized ones will be added to the symbol table. | 1392 | |
| 1040 | Symtab->fetchIfLazy<ELFT>(Config->Entry); | 1393 | // If any of our inputs are bitcode files, the LTO code generator may create |
| 1394 | // references to certain library functions that might not be explicit in the | ||
| 1395 | // bitcode file's symbol table. If any of those library functions are defined | ||
| 1396 | // in a bitcode file in an archive member, we need to arrange to use LTO to | ||
| 1397 | // compile those archive members by adding them to the link beforehand. | ||
| 1398 | // | ||
| 1399 | // With this the symbol table should be complete. After this, no new names | ||
| 1400 | // except a few linker-synthesized ones will be added to the symbol table. | ||
| 1401 | if (!BitcodeFiles.empty()) | ||
| 1402 | for (const char *S : LibcallRoutineNames) | ||
| 1403 | handleUndefined<ELFT>(S); | ||
| 1041 | 1404 | ||
| 1042 | // Return if there were name resolution errors. | 1405 | // Return if there were name resolution errors. |
| 1043 | if (errorCount()) | 1406 | if (errorCount()) |
| 1044 | return; | 1407 | return; |
| 1045 | 1408 | ||
| 1046 | // Handle undefined symbols in DSOs. | 1409 | // Now when we read all script files, we want to finalize order of linker |
| 1047 | if (!Config->Shared) | 1410 | // script commands, which can be not yet final because of INSERT commands. |
| 1048 | Symtab->scanShlibUndefined<ELFT>(); | 1411 | Script->processInsertCommands(); |
| 1412 | |||
| 1413 | // We want to declare linker script's symbols early, | ||
| 1414 | // so that we can version them. | ||
| 1415 | // They also might be exported if referenced by DSOs. | ||
| 1416 | Script->declareSymbols(); | ||
| 1049 | 1417 | ||
| 1050 | // Handle the -exclude-libs option. | 1418 | // Handle the -exclude-libs option. |
| 1051 | if (Args.hasArg(OPT_exclude_libs)) | 1419 | if (Args.hasArg(OPT_exclude_libs)) |
| 1052 | excludeLibs<ELFT>(Args, Files); | 1420 | excludeLibs<ELFT>(Args); |
| 1053 | 1421 | ||
| 1054 | // Create ElfHeader early. We need a dummy section in | 1422 | // Create ElfHeader early. We need a dummy section in |
| 1055 | // addReservedSymbols to mark the created symbols as not absolute. | 1423 | // addReservedSymbols to mark the created symbols as not absolute. |
| ... | @@ -1072,10 +1440,18 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { | ... | @@ -1072,10 +1440,18 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { |
| 1072 | for (auto *Arg : Args.filtered(OPT_wrap)) | 1440 | for (auto *Arg : Args.filtered(OPT_wrap)) |
| 1073 | Symtab->addSymbolWrap<ELFT>(Arg->getValue()); | 1441 | Symtab->addSymbolWrap<ELFT>(Arg->getValue()); |
| 1074 | 1442 | ||
| 1443 | // Do link-time optimization if given files are LLVM bitcode files. | ||
| 1444 | // This compiles bitcode files into real object files. | ||
| 1075 | Symtab->addCombinedLTOObject<ELFT>(); | 1445 | Symtab->addCombinedLTOObject<ELFT>(); |
| 1076 | if (errorCount()) | 1446 | if (errorCount()) |
| 1077 | return; | 1447 | return; |
| 1078 | 1448 | ||
| 1449 | // If -thinlto-index-only is given, we should create only "index | ||
| 1450 | // files" and not object files. Index file creation is already done | ||
| 1451 | // in addCombinedLTOObject, so we are done if that's the case. | ||
| 1452 | if (Config->ThinLTOIndexOnly) | ||
| 1453 | return; | ||
| 1454 | |||
| 1079 | // Apply symbol renames for -wrap. | 1455 | // Apply symbol renames for -wrap. |
| 1080 | Symtab->applySymbolWrap(); | 1456 | Symtab->applySymbolWrap(); |
| 1081 | 1457 | ||
| ... | @@ -1122,11 +1498,20 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { | ... | @@ -1122,11 +1498,20 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { |
| 1122 | 1498 | ||
| 1123 | // Do size optimizations: garbage collection, merging of SHF_MERGE sections | 1499 | // Do size optimizations: garbage collection, merging of SHF_MERGE sections |
| 1124 | // and identical code folding. | 1500 | // and identical code folding. |
| 1125 | markLive<ELFT>(); | ||
| 1126 | decompressSections(); | 1501 | decompressSections(); |
| 1502 | splitSections<ELFT>(); | ||
| 1503 | markLive<ELFT>(); | ||
| 1504 | demoteSymbols<ELFT>(); | ||
| 1127 | mergeSections(); | 1505 | mergeSections(); |
| 1128 | if (Config->ICF) | 1506 | if (Config->ICF != ICFLevel::None) { |
| 1507 | findKeepUniqueSections<ELFT>(Args); | ||
| 1129 | doIcf<ELFT>(); | 1508 | doIcf<ELFT>(); |
| 1509 | } | ||
| 1510 | |||
| 1511 | // Read the callgraph now that we know what was gced or icfed | ||
| 1512 | if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file)) | ||
| 1513 | if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) | ||
| 1514 | readCallGraph(*Buffer); | ||
| 1130 | 1515 | ||
| 1131 | // Write the result to the file. | 1516 | // Write the result to the file. |
| 1132 | writeResult<ELFT>(); | 1517 | writeResult<ELFT>(); |
deps/lld/ELF/Driver.h+3-3| ... | @@ -26,7 +26,7 @@ extern class LinkerDriver *Driver; | ... | @@ -26,7 +26,7 @@ extern class LinkerDriver *Driver; |
| 26 | 26 | ||
| 27 | class LinkerDriver { | 27 | class LinkerDriver { |
| 28 | public: | 28 | public: |
| 29 | void main(ArrayRef<const char *> Args, bool CanExitEarly); | 29 | void main(ArrayRef<const char *> Args); |
| 30 | void addFile(StringRef Path, bool WithLOption); | 30 | void addFile(StringRef Path, bool WithLOption); |
| 31 | void addLibrary(StringRef Name); | 31 | void addLibrary(StringRef Name); |
| 32 | 32 | ||
| ... | @@ -63,11 +63,11 @@ enum { | ... | @@ -63,11 +63,11 @@ enum { |
| 63 | #undef OPTION | 63 | #undef OPTION |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | void printHelp(const char *Argv0); | 66 | void printHelp(); |
| 67 | std::string createResponseFile(const llvm::opt::InputArgList &Args); | 67 | std::string createResponseFile(const llvm::opt::InputArgList &Args); |
| 68 | 68 | ||
| 69 | llvm::Optional<std::string> findFromSearchPaths(StringRef Path); | 69 | llvm::Optional<std::string> findFromSearchPaths(StringRef Path); |
| 70 | llvm::Optional<std::string> searchLinkerScript(StringRef Path); | 70 | llvm::Optional<std::string> searchScript(StringRef Path); |
| 71 | llvm::Optional<std::string> searchLibrary(StringRef Path); | 71 | llvm::Optional<std::string> searchLibrary(StringRef Path); |
| 72 | 72 | ||
| 73 | } // namespace elf | 73 | } // namespace elf |
deps/lld/ELF/DriverUtils.cpp+37-18| ... | @@ -29,6 +29,7 @@ | ... | @@ -29,6 +29,7 @@ |
| 29 | 29 | ||
| 30 | using namespace llvm; | 30 | using namespace llvm; |
| 31 | using namespace llvm::sys; | 31 | using namespace llvm::sys; |
| 32 | using namespace llvm::opt; | ||
| 32 | 33 | ||
| 33 | using namespace lld; | 34 | using namespace lld; |
| 34 | using namespace lld::elf; | 35 | using namespace lld::elf; |
| ... | @@ -58,18 +59,18 @@ static void handleColorDiagnostics(opt::InputArgList &Args) { | ... | @@ -58,18 +59,18 @@ static void handleColorDiagnostics(opt::InputArgList &Args) { |
| 58 | OPT_no_color_diagnostics); | 59 | OPT_no_color_diagnostics); |
| 59 | if (!Arg) | 60 | if (!Arg) |
| 60 | return; | 61 | return; |
| 61 | else if (Arg->getOption().getID() == OPT_color_diagnostics) | 62 | if (Arg->getOption().getID() == OPT_color_diagnostics) { |
| 62 | errorHandler().ColorDiagnostics = true; | 63 | errorHandler().ColorDiagnostics = true; |
| 63 | else if (Arg->getOption().getID() == OPT_no_color_diagnostics) | 64 | } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) { |
| 64 | errorHandler().ColorDiagnostics = false; | 65 | errorHandler().ColorDiagnostics = false; |
| 65 | else { | 66 | } else { |
| 66 | StringRef S = Arg->getValue(); | 67 | StringRef S = Arg->getValue(); |
| 67 | if (S == "always") | 68 | if (S == "always") |
| 68 | errorHandler().ColorDiagnostics = true; | 69 | errorHandler().ColorDiagnostics = true; |
| 69 | else if (S == "never") | 70 | else if (S == "never") |
| 70 | errorHandler().ColorDiagnostics = false; | 71 | errorHandler().ColorDiagnostics = false; |
| 71 | else if (S != "auto") | 72 | else if (S != "auto") |
| 72 | error("unknown option: -color-diagnostics=" + S); | 73 | error("unknown option: --color-diagnostics=" + S); |
| 73 | } | 74 | } |
| 74 | } | 75 | } |
| 75 | 76 | ||
| ... | @@ -87,6 +88,29 @@ static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) { | ... | @@ -87,6 +88,29 @@ static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) { |
| 87 | return cl::TokenizeGNUCommandLine; | 88 | return cl::TokenizeGNUCommandLine; |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 91 | // Gold LTO plugin takes a `--plugin-opt foo=bar` option as an alias for | ||
| 92 | // `--plugin-opt=foo=bar`. We want to handle `--plugin-opt=foo=` as an | ||
| 93 | // option name and `bar` as a value. Unfortunately, OptParser cannot | ||
| 94 | // handle an option with a space in it. | ||
| 95 | // | ||
| 96 | // In this function, we concatenate command line arguments so that | ||
| 97 | // `--plugin-opt <foo>` is converted to `--plugin-opt=<foo>`. This is a | ||
| 98 | // bit hacky, but looks like it is still better than handling --plugin-opt | ||
| 99 | // options by hand. | ||
| 100 | static 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; | ||
| 107 | } else { | ||
| 108 | V.push_back(Args[I]); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | Args = std::move(V); | ||
| 112 | } | ||
| 113 | |||
| 90 | // Parses a given list of options. | 114 | // Parses a given list of options. |
| 91 | opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { | 115 | opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { |
| 92 | // Make InputArgList from string vectors. | 116 | // Make InputArgList from string vectors. |
| ... | @@ -102,6 +126,7 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { | ... | @@ -102,6 +126,7 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { |
| 102 | // Expand response files (arguments in the form of @<filename>) | 126 | // Expand response files (arguments in the form of @<filename>) |
| 103 | // and then parse the argument again. | 127 | // and then parse the argument again. |
| 104 | cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec); | 128 | cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec); |
| 129 | concatLTOPluginOptions(Vec); | ||
| 105 | Args = this->ParseArgs(Vec, MissingIndex, MissingCount); | 130 | Args = this->ParseArgs(Vec, MissingIndex, MissingCount); |
| 106 | 131 | ||
| 107 | handleColorDiagnostics(Args); | 132 | handleColorDiagnostics(Args); |
| ... | @@ -113,9 +138,9 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { | ... | @@ -113,9 +138,9 @@ opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) { |
| 113 | return Args; | 138 | return Args; |
| 114 | } | 139 | } |
| 115 | 140 | ||
| 116 | void elf::printHelp(const char *Argv0) { | 141 | void elf::printHelp() { |
| 117 | ELFOptTable().PrintHelp(outs(), Argv0, "lld", false /*ShowHidden*/, | 142 | ELFOptTable().PrintHelp(outs(), Config->ProgName.data(), "lld", |
| 118 | true /*ShowAllAliases*/); | 143 | false /*ShowHidden*/, true /*ShowAllAliases*/); |
| 119 | outs() << "\n"; | 144 | outs() << "\n"; |
| 120 | 145 | ||
| 121 | // Scripts generated by Libtool versions up to at least 2.4.6 (the most | 146 | // Scripts generated by Libtool versions up to at least 2.4.6 (the most |
| ... | @@ -123,13 +148,7 @@ void elf::printHelp(const char *Argv0) { | ... | @@ -123,13 +148,7 @@ void elf::printHelp(const char *Argv0) { |
| 123 | // in a message for the -help option. If it doesn't match, the scripts | 148 | // in a message for the -help option. If it doesn't match, the scripts |
| 124 | // assume that the linker doesn't support very basic features such as | 149 | // assume that the linker doesn't support very basic features such as |
| 125 | // shared libraries. Therefore, we need to print out at least "elf". | 150 | // shared libraries. Therefore, we need to print out at least "elf". |
| 126 | // Here, we print out all the targets that we support. | 151 | outs() << Config->ProgName << ": supported targets: elf\n"; |
| 127 | outs() << Argv0 << ": supported targets: " | ||
| 128 | << "elf32-i386 elf32-iamcu elf32-littlearm elf32-ntradbigmips " | ||
| 129 | << "elf32-ntradlittlemips elf32-powerpc elf32-tradbigmips " | ||
| 130 | << "elf32-tradlittlemips elf32-x86-64 " | ||
| 131 | << "elf64-amdgpu elf64-littleaarch64 elf64-powerpc elf64-tradbigmips " | ||
| 132 | << "elf64-tradlittlemips elf64-x86-64\n"; | ||
| 133 | } | 152 | } |
| 134 | 153 | ||
| 135 | // Reconstructs command line arguments so that so that you can re-run | 154 | // Reconstructs command line arguments so that so that you can re-run |
| ... | @@ -208,10 +227,10 @@ Optional<std::string> elf::searchLibrary(StringRef Name) { | ... | @@ -208,10 +227,10 @@ Optional<std::string> elf::searchLibrary(StringRef Name) { |
| 208 | return None; | 227 | return None; |
| 209 | } | 228 | } |
| 210 | 229 | ||
| 211 | // If a linker script doesn't exist in the current directory, we also look for | 230 | // If a linker/version script doesn't exist in the current directory, we also |
| 212 | // the script in the '-L' search paths. This matches the behaviour of both '-T' | 231 | // look for the script in the '-L' search paths. This matches the behaviour of |
| 213 | // and linker script INPUT() directives in ld.bfd. | 232 | // '-T', --version-script=, and linker script INPUT() command in ld.bfd. |
| 214 | Optional<std::string> elf::searchLinkerScript(StringRef Name) { | 233 | Optional<std::string> elf::searchScript(StringRef Name) { |
| 215 | if (fs::exists(Name)) | 234 | if (fs::exists(Name)) |
| 216 | return Name.str(); | 235 | return Name.str(); |
| 217 | return findFromSearchPaths(Name); | 236 | return findFromSearchPaths(Name); |
deps/lld/ELF/EhFrame.cpp+3-5| ... | @@ -20,18 +20,16 @@ | ... | @@ -20,18 +20,16 @@ |
| 20 | #include "Config.h" | 20 | #include "Config.h" |
| 21 | #include "InputSection.h" | 21 | #include "InputSection.h" |
| 22 | #include "Relocations.h" | 22 | #include "Relocations.h" |
| 23 | #include "Strings.h" | 23 | #include "Target.h" |
| 24 | |||
| 25 | #include "lld/Common/ErrorHandler.h" | 24 | #include "lld/Common/ErrorHandler.h" |
| 25 | #include "lld/Common/Strings.h" | ||
| 26 | #include "llvm/BinaryFormat/Dwarf.h" | 26 | #include "llvm/BinaryFormat/Dwarf.h" |
| 27 | #include "llvm/Object/ELF.h" | 27 | #include "llvm/Object/ELF.h" |
| 28 | #include "llvm/Support/Endian.h" | ||
| 29 | 28 | ||
| 30 | using namespace llvm; | 29 | using namespace llvm; |
| 31 | using namespace llvm::ELF; | 30 | using namespace llvm::ELF; |
| 32 | using namespace llvm::dwarf; | 31 | using namespace llvm::dwarf; |
| 33 | using namespace llvm::object; | 32 | using namespace llvm::object; |
| 34 | using namespace llvm::support::endian; | ||
| 35 | 33 | ||
| 36 | using namespace lld; | 34 | using namespace lld; |
| 37 | using namespace lld::elf; | 35 | using namespace lld::elf; |
| ... | @@ -73,7 +71,7 @@ size_t EhReader::readEhRecordSize() { | ... | @@ -73,7 +71,7 @@ size_t EhReader::readEhRecordSize() { |
| 73 | // First 4 bytes of CIE/FDE is the size of the record. | 71 | // First 4 bytes of CIE/FDE is the size of the record. |
| 74 | // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead, | 72 | // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead, |
| 75 | // but we do not support that format yet. | 73 | // but we do not support that format yet. |
| 76 | uint64_t V = read32(D.data(), Config->Endianness); | 74 | uint64_t V = read32(D.data()); |
| 77 | if (V == UINT32_MAX) | 75 | if (V == UINT32_MAX) |
| 78 | failOn(D.data(), "CIE/FDE too large"); | 76 | failOn(D.data(), "CIE/FDE too large"); |
| 79 | uint64_t Size = V + 4; | 77 | uint64_t Size = V + 4; |
deps/lld/ELF/Filesystem.cpp+1-1| ... | @@ -44,7 +44,7 @@ using namespace lld::elf; | ... | @@ -44,7 +44,7 @@ using namespace lld::elf; |
| 44 | // The calling thread returns almost immediately. | 44 | // The calling thread returns almost immediately. |
| 45 | void elf::unlinkAsync(StringRef Path) { | 45 | void elf::unlinkAsync(StringRef Path) { |
| 46 | // Removing a file is async on windows. | 46 | // Removing a file is async on windows. |
| 47 | #if defined(LLVM_ON_WIN32) | 47 | #if defined(_WIN32) |
| 48 | sys::fs::remove(Path); | 48 | sys::fs::remove(Path); |
| 49 | #else | 49 | #else |
| 50 | if (!ThreadsEnabled || !sys::fs::exists(Path) || | 50 | if (!ThreadsEnabled || !sys::fs::exists(Path) || |
deps/lld/ELF/GdbIndex.cpp+1-1| ... | @@ -34,7 +34,7 @@ template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *Obj) { | ... | @@ -34,7 +34,7 @@ template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *Obj) { |
| 34 | .Case(".debug_ranges", &RangeSection) | 34 | .Case(".debug_ranges", &RangeSection) |
| 35 | .Case(".debug_line", &LineSection) | 35 | .Case(".debug_line", &LineSection) |
| 36 | .Default(nullptr)) { | 36 | .Default(nullptr)) { |
| 37 | Sec->maybeUncompress(); | 37 | Sec->maybeDecompress(); |
| 38 | M->Data = toStringRef(Sec->Data); | 38 | M->Data = toStringRef(Sec->Data); |
| 39 | M->Sec = Sec; | 39 | M->Sec = Sec; |
| 40 | continue; | 40 | continue; |
deps/lld/ELF/GdbIndex.h-1| ... | @@ -49,7 +49,6 @@ public: | ... | @@ -49,7 +49,6 @@ public: |
| 49 | return LineSection; | 49 | return LineSection; |
| 50 | } | 50 | } |
| 51 | StringRef getFileName() const override { return ""; } | 51 | StringRef getFileName() const override { return ""; } |
| 52 | StringRef getCUIndexSection() const override { return ""; } | ||
| 53 | StringRef getAbbrevSection() const override { return AbbrevSection; } | 52 | StringRef getAbbrevSection() const override { return AbbrevSection; } |
| 54 | StringRef getStringSection() const override { return StrSection; } | 53 | StringRef getStringSection() const override { return StrSection; } |
| 55 | StringRef getGnuPubNamesSection() const override { | 54 | StringRef getGnuPubNamesSection() const override { |
deps/lld/ELF/ICF.cpp+78-47| ... | @@ -77,10 +77,13 @@ | ... | @@ -77,10 +77,13 @@ |
| 77 | #include "Config.h" | 77 | #include "Config.h" |
| 78 | #include "SymbolTable.h" | 78 | #include "SymbolTable.h" |
| 79 | #include "Symbols.h" | 79 | #include "Symbols.h" |
| 80 | #include "SyntheticSections.h" | ||
| 81 | #include "Writer.h" | ||
| 80 | #include "lld/Common/Threads.h" | 82 | #include "lld/Common/Threads.h" |
| 81 | #include "llvm/ADT/Hashing.h" | 83 | #include "llvm/ADT/StringExtras.h" |
| 82 | #include "llvm/BinaryFormat/ELF.h" | 84 | #include "llvm/BinaryFormat/ELF.h" |
| 83 | #include "llvm/Object/ELF.h" | 85 | #include "llvm/Object/ELF.h" |
| 86 | #include "llvm/Support/xxhash.h" | ||
| 84 | #include <algorithm> | 87 | #include <algorithm> |
| 85 | #include <atomic> | 88 | #include <atomic> |
| 86 | 89 | ||
| ... | @@ -112,9 +115,9 @@ private: | ... | @@ -112,9 +115,9 @@ private: |
| 112 | size_t findBoundary(size_t Begin, size_t End); | 115 | size_t findBoundary(size_t Begin, size_t End); |
| 113 | 116 | ||
| 114 | void forEachClassRange(size_t Begin, size_t End, | 117 | void forEachClassRange(size_t Begin, size_t End, |
| 115 | std::function<void(size_t, size_t)> Fn); | 118 | llvm::function_ref<void(size_t, size_t)> Fn); |
| 116 | 119 | ||
| 117 | void forEachClass(std::function<void(size_t, size_t)> Fn); | 120 | void forEachClass(llvm::function_ref<void(size_t, size_t)> Fn); |
| 118 | 121 | ||
| 119 | std::vector<InputSection *> Sections; | 122 | std::vector<InputSection *> Sections; |
| 120 | 123 | ||
| ... | @@ -153,23 +156,40 @@ private: | ... | @@ -153,23 +156,40 @@ private: |
| 153 | }; | 156 | }; |
| 154 | } | 157 | } |
| 155 | 158 | ||
| 156 | // Returns a hash value for S. Note that the information about | ||
| 157 | // relocation targets is not included in the hash value. | ||
| 158 | template <class ELFT> static uint32_t getHash(InputSection *S) { | ||
| 159 | return hash_combine(S->Flags, S->getSize(), S->NumRelocations, S->Data); | ||
| 160 | } | ||
| 161 | |||
| 162 | // Returns true if section S is subject of ICF. | 159 | // Returns true if section S is subject of ICF. |
| 163 | static bool isEligible(InputSection *S) { | 160 | static bool isEligible(InputSection *S) { |
| 164 | // Don't merge read only data sections unless --icf-data was passed. | 161 | if (!S->Live || S->KeepUnique || !(S->Flags & SHF_ALLOC)) |
| 165 | if (!(S->Flags & SHF_EXECINSTR) && !Config->ICFData) | 162 | return false; |
| 163 | |||
| 164 | // Don't merge writable sections. .data.rel.ro sections are marked as writable | ||
| 165 | // but are semantically read-only. | ||
| 166 | if ((S->Flags & SHF_WRITE) && S->Name != ".data.rel.ro" && | ||
| 167 | !S->Name.startswith(".data.rel.ro.")) | ||
| 166 | return false; | 168 | return false; |
| 167 | 169 | ||
| 168 | // .init and .fini contains instructions that must be executed to | 170 | // SHF_LINK_ORDER sections are ICF'd as a unit with their dependent sections, |
| 169 | // initialize and finalize the process. They cannot and should not | 171 | // so we don't consider them for ICF individually. |
| 170 | // be merged. | 172 | if (S->Flags & SHF_LINK_ORDER) |
| 171 | return S->Live && (S->Flags & SHF_ALLOC) && !(S->Flags & SHF_WRITE) && | 173 | return false; |
| 172 | S->Name != ".init" && S->Name != ".fini"; | 174 | |
| 175 | // Don't merge synthetic sections as their Data member is not valid and empty. | ||
| 176 | // The Data member needs to be valid for ICF as it is used by ICF to determine | ||
| 177 | // the equality of section contents. | ||
| 178 | if (isa<SyntheticSection>(S)) | ||
| 179 | return false; | ||
| 180 | |||
| 181 | // .init and .fini contains instructions that must be executed to initialize | ||
| 182 | // and finalize the process. They cannot and should not be merged. | ||
| 183 | if (S->Name == ".init" || S->Name == ".fini") | ||
| 184 | return false; | ||
| 185 | |||
| 186 | // A user program may enumerate sections named with a C identifier using | ||
| 187 | // __start_* and __stop_* symbols. We cannot ICF any such sections because | ||
| 188 | // that could change program semantics. | ||
| 189 | if (isValidCIdentifier(S->Name)) | ||
| 190 | return false; | ||
| 191 | |||
| 192 | return true; | ||
| 173 | } | 193 | } |
| 174 | 194 | ||
| 175 | // Split an equivalence class into smaller classes. | 195 | // Split an equivalence class into smaller classes. |
| ... | @@ -214,9 +234,6 @@ template <class ELFT> | ... | @@ -214,9 +234,6 @@ template <class ELFT> |
| 214 | template <class RelTy> | 234 | template <class RelTy> |
| 215 | bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA, | 235 | bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA, |
| 216 | const InputSection *SecB, ArrayRef<RelTy> RB) { | 236 | const InputSection *SecB, ArrayRef<RelTy> RB) { |
| 217 | if (RA.size() != RB.size()) | ||
| 218 | return false; | ||
| 219 | |||
| 220 | for (size_t I = 0; I < RA.size(); ++I) { | 237 | for (size_t I = 0; I < RA.size(); ++I) { |
| 221 | if (RA[I].r_offset != RB[I].r_offset || | 238 | if (RA[I].r_offset != RB[I].r_offset || |
| 222 | RA[I].getType(Config->IsMips64EL) != RB[I].getType(Config->IsMips64EL)) | 239 | RA[I].getType(Config->IsMips64EL) != RB[I].getType(Config->IsMips64EL)) |
| ... | @@ -284,6 +301,13 @@ bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) { | ... | @@ -284,6 +301,13 @@ bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) { |
| 284 | A->getSize() != B->getSize() || A->Data != B->Data) | 301 | A->getSize() != B->getSize() || A->Data != B->Data) |
| 285 | return false; | 302 | return false; |
| 286 | 303 | ||
| 304 | // If two sections have different output sections, we cannot merge them. | ||
| 305 | // FIXME: This doesn't do the right thing in the case where there is a linker | ||
| 306 | // script. We probably need to move output section assignment before ICF to | ||
| 307 | // get the correct behaviour here. | ||
| 308 | if (getOutputSectionName(A) != getOutputSectionName(B)) | ||
| 309 | return false; | ||
| 310 | |||
| 287 | if (A->AreRelocsRela) | 311 | if (A->AreRelocsRela) |
| 288 | return constantEq(A, A->template relas<ELFT>(), B, | 312 | return constantEq(A, A->template relas<ELFT>(), B, |
| 289 | B->template relas<ELFT>()); | 313 | B->template relas<ELFT>()); |
| ... | @@ -350,17 +374,12 @@ template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) { | ... | @@ -350,17 +374,12 @@ template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) { |
| 350 | // vector. Therefore, Sections vector can be considered as contiguous | 374 | // vector. Therefore, Sections vector can be considered as contiguous |
| 351 | // groups of sections, grouped by the class. | 375 | // groups of sections, grouped by the class. |
| 352 | // | 376 | // |
| 353 | // This function calls Fn on every group that starts within [Begin, End). | 377 | // This function calls Fn on every group within [Begin, End). |
| 354 | // Note that a group must start in that range but doesn't necessarily | ||
| 355 | // have to end before End. | ||
| 356 | template <class ELFT> | 378 | template <class ELFT> |
| 357 | void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End, | 379 | void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End, |
| 358 | std::function<void(size_t, size_t)> Fn) { | 380 | llvm::function_ref<void(size_t, size_t)> Fn) { |
| 359 | if (Begin > 0) | ||
| 360 | Begin = findBoundary(Begin - 1, End); | ||
| 361 | |||
| 362 | while (Begin < End) { | 381 | while (Begin < End) { |
| 363 | size_t Mid = findBoundary(Begin, Sections.size()); | 382 | size_t Mid = findBoundary(Begin, End); |
| 364 | Fn(Begin, Mid); | 383 | Fn(Begin, Mid); |
| 365 | Begin = Mid; | 384 | Begin = Mid; |
| 366 | } | 385 | } |
| ... | @@ -368,7 +387,7 @@ void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End, | ... | @@ -368,7 +387,7 @@ void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End, |
| 368 | 387 | ||
| 369 | // Call Fn on each equivalence class. | 388 | // Call Fn on each equivalence class. |
| 370 | template <class ELFT> | 389 | template <class ELFT> |
| 371 | void ICF<ELFT>::forEachClass(std::function<void(size_t, size_t)> Fn) { | 390 | void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> Fn) { |
| 372 | // If threading is disabled or the number of sections are | 391 | // If threading is disabled or the number of sections are |
| 373 | // too small to use threading, call Fn sequentially. | 392 | // too small to use threading, call Fn sequentially. |
| 374 | if (!ThreadsEnabled || Sections.size() < 1024) { | 393 | if (!ThreadsEnabled || Sections.size() < 1024) { |
| ... | @@ -380,16 +399,32 @@ void ICF<ELFT>::forEachClass(std::function<void(size_t, size_t)> Fn) { | ... | @@ -380,16 +399,32 @@ void ICF<ELFT>::forEachClass(std::function<void(size_t, size_t)> Fn) { |
| 380 | Current = Cnt % 2; | 399 | Current = Cnt % 2; |
| 381 | Next = (Cnt + 1) % 2; | 400 | Next = (Cnt + 1) % 2; |
| 382 | 401 | ||
| 383 | // Split sections into 256 shards and call Fn in parallel. | 402 | // Shard into non-overlapping intervals, and call Fn in parallel. |
| 384 | size_t NumShards = 256; | 403 | // The sharding must be completed before any calls to Fn are made |
| 404 | // so that Fn can modify the Chunks in its shard without causing data | ||
| 405 | // races. | ||
| 406 | const size_t NumShards = 256; | ||
| 385 | size_t Step = Sections.size() / NumShards; | 407 | size_t Step = Sections.size() / NumShards; |
| 386 | parallelForEachN(0, NumShards, [&](size_t I) { | 408 | size_t Boundaries[NumShards + 1]; |
| 387 | size_t End = (I == NumShards - 1) ? Sections.size() : (I + 1) * Step; | 409 | Boundaries[0] = 0; |
| 388 | forEachClassRange(I * Step, End, Fn); | 410 | Boundaries[NumShards] = Sections.size(); |
| 411 | |||
| 412 | parallelForEachN(1, NumShards, [&](size_t I) { | ||
| 413 | Boundaries[I] = findBoundary((I - 1) * Step, Sections.size()); | ||
| 414 | }); | ||
| 415 | |||
| 416 | parallelForEachN(1, NumShards + 1, [&](size_t I) { | ||
| 417 | if (Boundaries[I - 1] < Boundaries[I]) | ||
| 418 | forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn); | ||
| 389 | }); | 419 | }); |
| 390 | ++Cnt; | 420 | ++Cnt; |
| 391 | } | 421 | } |
| 392 | 422 | ||
| 423 | static void print(const Twine &S) { | ||
| 424 | if (Config->PrintIcfSections) | ||
| 425 | message(S); | ||
| 426 | } | ||
| 427 | |||
| 393 | // The main function of ICF. | 428 | // The main function of ICF. |
| 394 | template <class ELFT> void ICF<ELFT>::run() { | 429 | template <class ELFT> void ICF<ELFT>::run() { |
| 395 | // Collect sections to merge. | 430 | // Collect sections to merge. |
| ... | @@ -401,7 +436,7 @@ template <class ELFT> void ICF<ELFT>::run() { | ... | @@ -401,7 +436,7 @@ template <class ELFT> void ICF<ELFT>::run() { |
| 401 | // Initially, we use hash values to partition sections. | 436 | // Initially, we use hash values to partition sections. |
| 402 | parallelForEach(Sections, [&](InputSection *S) { | 437 | parallelForEach(Sections, [&](InputSection *S) { |
| 403 | // Set MSB to 1 to avoid collisions with non-hash IDs. | 438 | // Set MSB to 1 to avoid collisions with non-hash IDs. |
| 404 | S->Class[0] = getHash<ELFT>(S) | (1 << 31); | 439 | S->Class[0] = xxHash64(S->Data) | (1U << 31); |
| 405 | }); | 440 | }); |
| 406 | 441 | ||
| 407 | // From now on, sections in Sections vector are ordered so that sections | 442 | // From now on, sections in Sections vector are ordered so that sections |
| ... | @@ -424,25 +459,21 @@ template <class ELFT> void ICF<ELFT>::run() { | ... | @@ -424,25 +459,21 @@ template <class ELFT> void ICF<ELFT>::run() { |
| 424 | log("ICF needed " + Twine(Cnt) + " iterations"); | 459 | log("ICF needed " + Twine(Cnt) + " iterations"); |
| 425 | 460 | ||
| 426 | // Merge sections by the equivalence class. | 461 | // Merge sections by the equivalence class. |
| 427 | forEachClass([&](size_t Begin, size_t End) { | 462 | forEachClassRange(0, Sections.size(), [&](size_t Begin, size_t End) { |
| 428 | if (End - Begin == 1) | 463 | if (End - Begin == 1) |
| 429 | return; | 464 | return; |
| 430 | 465 | print("selected section " + toString(Sections[Begin])); | |
| 431 | log("selected " + Sections[Begin]->Name); | ||
| 432 | for (size_t I = Begin + 1; I < End; ++I) { | 466 | for (size_t I = Begin + 1; I < End; ++I) { |
| 433 | log(" removed " + Sections[I]->Name); | 467 | print(" removing identical section " + toString(Sections[I])); |
| 434 | Sections[Begin]->replace(Sections[I]); | 468 | Sections[Begin]->replace(Sections[I]); |
| 469 | |||
| 470 | // At this point we know sections merged are fully identical and hence | ||
| 471 | // we want to remove duplicate implicit dependencies such as link order | ||
| 472 | // and relocation sections. | ||
| 473 | for (InputSection *IS : Sections[I]->DependentSections) | ||
| 474 | IS->Live = false; | ||
| 435 | } | 475 | } |
| 436 | }); | 476 | }); |
| 437 | |||
| 438 | // Mark ARM Exception Index table sections that refer to folded code | ||
| 439 | // sections as not live. These sections have an implict dependency | ||
| 440 | // via the link order dependency. | ||
| 441 | if (Config->EMachine == EM_ARM) | ||
| 442 | for (InputSectionBase *Sec : InputSections) | ||
| 443 | if (auto *S = dyn_cast<InputSection>(Sec)) | ||
| 444 | if (S->Flags & SHF_LINK_ORDER) | ||
| 445 | S->Live = S->getLinkOrderDep()->Live; | ||
| 446 | } | 477 | } |
| 447 | 478 | ||
| 448 | // ICF entry point function. | 479 | // ICF entry point function. |
deps/lld/ELF/ICF.h+3-1| ... | @@ -12,8 +12,10 @@ | ... | @@ -12,8 +12,10 @@ |
| 12 | 12 | ||
| 13 | namespace lld { | 13 | namespace lld { |
| 14 | namespace elf { | 14 | namespace elf { |
| 15 | |||
| 15 | template <class ELFT> void doIcf(); | 16 | template <class ELFT> void doIcf(); |
| 16 | } | 17 | |
| 18 | } // namespace elf | ||
| 17 | } // namespace lld | 19 | } // namespace lld |
| 18 | 20 | ||
| 19 | #endif | 21 | #endif |
deps/lld/ELF/InputFiles.cpp+402-256| ... | @@ -38,14 +38,23 @@ using namespace llvm::sys::fs; | ... | @@ -38,14 +38,23 @@ using namespace llvm::sys::fs; |
| 38 | using namespace lld; | 38 | using namespace lld; |
| 39 | using namespace lld::elf; | 39 | using namespace lld::elf; |
| 40 | 40 | ||
| 41 | bool InputFile::IsInGroup; | ||
| 42 | uint32_t InputFile::NextGroupId; | ||
| 41 | std::vector<BinaryFile *> elf::BinaryFiles; | 43 | std::vector<BinaryFile *> elf::BinaryFiles; |
| 42 | std::vector<BitcodeFile *> elf::BitcodeFiles; | 44 | std::vector<BitcodeFile *> elf::BitcodeFiles; |
| 45 | std::vector<LazyObjFile *> elf::LazyObjFiles; | ||
| 43 | std::vector<InputFile *> elf::ObjectFiles; | 46 | std::vector<InputFile *> elf::ObjectFiles; |
| 44 | std::vector<InputFile *> elf::SharedFiles; | 47 | std::vector<InputFile *> elf::SharedFiles; |
| 45 | 48 | ||
| 46 | TarWriter *elf::Tar; | 49 | TarWriter *elf::Tar; |
| 47 | 50 | ||
| 48 | InputFile::InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} | 51 | InputFile::InputFile(Kind K, MemoryBufferRef M) |
| 52 | : MB(M), GroupId(NextGroupId), FileKind(K) { | ||
| 53 | // All files within the same --{start,end}-group get the same group ID. | ||
| 54 | // Otherwise, a new file will get a new group ID. | ||
| 55 | if (!IsInGroup) | ||
| 56 | ++NextGroupId; | ||
| 57 | } | ||
| 49 | 58 | ||
| 50 | Optional<MemoryBufferRef> elf::readFile(StringRef Path) { | 59 | Optional<MemoryBufferRef> elf::readFile(StringRef Path) { |
| 51 | // The --chroot option changes our virtual root directory. | 60 | // The --chroot option changes our virtual root directory. |
| ... | @@ -55,7 +64,7 @@ Optional<MemoryBufferRef> elf::readFile(StringRef Path) { | ... | @@ -55,7 +64,7 @@ Optional<MemoryBufferRef> elf::readFile(StringRef Path) { |
| 55 | 64 | ||
| 56 | log(Path); | 65 | log(Path); |
| 57 | 66 | ||
| 58 | auto MBOrErr = MemoryBuffer::getFile(Path); | 67 | auto MBOrErr = MemoryBuffer::getFile(Path, -1, false); |
| 59 | if (auto EC = MBOrErr.getError()) { | 68 | if (auto EC = MBOrErr.getError()) { |
| 60 | error("cannot open " + Path + ": " + EC.message()); | 69 | error("cannot open " + Path + ": " + EC.message()); |
| 61 | return None; | 70 | return None; |
| ... | @@ -115,51 +124,60 @@ std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec, | ... | @@ -115,51 +124,60 @@ std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec, |
| 115 | } | 124 | } |
| 116 | 125 | ||
| 117 | template <class ELFT> void ObjFile<ELFT>::initializeDwarf() { | 126 | template <class ELFT> void ObjFile<ELFT>::initializeDwarf() { |
| 118 | DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(this)); | 127 | Dwarf = llvm::make_unique<DWARFContext>(make_unique<LLDDwarfObj<ELFT>>(this)); |
| 119 | const DWARFObject &Obj = Dwarf.getDWARFObj(); | 128 | const DWARFObject &Obj = Dwarf->getDWARFObj(); |
| 120 | DwarfLine.reset(new DWARFDebugLine); | ||
| 121 | DWARFDataExtractor LineData(Obj, Obj.getLineSection(), Config->IsLE, | 129 | DWARFDataExtractor LineData(Obj, Obj.getLineSection(), Config->IsLE, |
| 122 | Config->Wordsize); | 130 | Config->Wordsize); |
| 123 | 131 | ||
| 124 | // The second parameter is offset in .debug_line section | 132 | for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf->compile_units()) { |
| 125 | // for compilation unit (CU) of interest. We have only one | 133 | auto Report = [](Error Err) { |
| 126 | // CU (object file), so offset is always 0. | 134 | handleAllErrors(std::move(Err), |
| 127 | // FIXME: Provide the associated DWARFUnit if there is one. DWARF v5 | 135 | [](ErrorInfoBase &Info) { warn(Info.message()); }); |
| 128 | // needs it in order to find indirect strings. | 136 | }; |
| 129 | const DWARFDebugLine::LineTable *LT = | 137 | Expected<const DWARFDebugLine::LineTable *> ExpectedLT = |
| 130 | DwarfLine->getOrParseLineTable(LineData, 0, nullptr); | 138 | Dwarf->getLineTableForUnit(CU.get(), Report); |
| 131 | 139 | const DWARFDebugLine::LineTable *LT = nullptr; | |
| 132 | // Return if there is no debug information about CU available. | 140 | if (ExpectedLT) |
| 133 | if (!Dwarf.getNumCompileUnits()) | 141 | LT = *ExpectedLT; |
| 134 | return; | 142 | else |
| 135 | 143 | Report(ExpectedLT.takeError()); | |
| 136 | // Loop over variable records and insert them to VariableLoc. | 144 | if (!LT) |
| 137 | DWARFCompileUnit *CU = Dwarf.getCompileUnitAtIndex(0); | ||
| 138 | for (const auto &Entry : CU->dies()) { | ||
| 139 | DWARFDie Die(CU, &Entry); | ||
| 140 | // Skip all tags that are not variables. | ||
| 141 | if (Die.getTag() != dwarf::DW_TAG_variable) | ||
| 142 | continue; | 145 | continue; |
| 146 | LineTables.push_back(LT); | ||
| 143 | 147 | ||
| 144 | // Skip if a local variable because we don't need them for generating error | 148 | // Loop over variable records and insert them to VariableLoc. |
| 145 | // messages. In general, only non-local symbols can fail to be linked. | 149 | for (const auto &Entry : CU->dies()) { |
| 146 | if (!dwarf::toUnsigned(Die.find(dwarf::DW_AT_external), 0)) | 150 | DWARFDie Die(CU.get(), &Entry); |
| 147 | continue; | 151 | // Skip all tags that are not variables. |
| 152 | if (Die.getTag() != dwarf::DW_TAG_variable) | ||
| 153 | continue; | ||
| 148 | 154 | ||
| 149 | // Get the source filename index for the variable. | 155 | // Skip if a local variable because we don't need them for generating |
| 150 | unsigned File = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_file), 0); | 156 | // error messages. In general, only non-local symbols can fail to be |
| 151 | if (!LT->hasFileAtIndex(File)) | 157 | // linked. |
| 152 | continue; | 158 | if (!dwarf::toUnsigned(Die.find(dwarf::DW_AT_external), 0)) |
| 159 | continue; | ||
| 153 | 160 | ||
| 154 | // Get the line number on which the variable is declared. | 161 | // Get the source filename index for the variable. |
| 155 | unsigned Line = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_line), 0); | 162 | unsigned File = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_file), 0); |
| 163 | if (!LT->hasFileAtIndex(File)) | ||
| 164 | continue; | ||
| 156 | 165 | ||
| 157 | // Get the name of the variable and add the collected information to | 166 | // Get the line number on which the variable is declared. |
| 158 | // VariableLoc. Usually Name is non-empty, but it can be empty if the input | 167 | unsigned Line = dwarf::toUnsigned(Die.find(dwarf::DW_AT_decl_line), 0); |
| 159 | // object file lacks some debug info. | 168 | |
| 160 | StringRef Name = dwarf::toString(Die.find(dwarf::DW_AT_name), ""); | 169 | // Here we want to take the variable name to add it into VariableLoc. |
| 161 | if (!Name.empty()) | 170 | // Variable can have regular and linkage name associated. At first, we try |
| 162 | VariableLoc.insert({Name, {File, Line}}); | 171 | // to get linkage name as it can be different, for example when we have |
| 172 | // two variables in different namespaces of the same object. Use common | ||
| 173 | // name otherwise, but handle the case when it also absent in case if the | ||
| 174 | // input object file lacks some debug info. | ||
| 175 | StringRef Name = | ||
| 176 | dwarf::toString(Die.find(dwarf::DW_AT_linkage_name), | ||
| 177 | dwarf::toString(Die.find(dwarf::DW_AT_name), "")); | ||
| 178 | if (!Name.empty()) | ||
| 179 | VariableLoc.insert({Name, {LT, File, Line}}); | ||
| 180 | } | ||
| 163 | } | 181 | } |
| 164 | } | 182 | } |
| 165 | 183 | ||
| ... | @@ -170,11 +188,6 @@ Optional<std::pair<std::string, unsigned>> | ... | @@ -170,11 +188,6 @@ Optional<std::pair<std::string, unsigned>> |
| 170 | ObjFile<ELFT>::getVariableLoc(StringRef Name) { | 188 | ObjFile<ELFT>::getVariableLoc(StringRef Name) { |
| 171 | llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); }); | 189 | llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); }); |
| 172 | 190 | ||
| 173 | // There is always only one CU so it's offset is 0. | ||
| 174 | const DWARFDebugLine::LineTable *LT = DwarfLine->getLineTable(0); | ||
| 175 | if (!LT) | ||
| 176 | return None; | ||
| 177 | |||
| 178 | // Return if we have no debug information about data object. | 191 | // Return if we have no debug information about data object. |
| 179 | auto It = VariableLoc.find(Name); | 192 | auto It = VariableLoc.find(Name); |
| 180 | if (It == VariableLoc.end()) | 193 | if (It == VariableLoc.end()) |
| ... | @@ -182,12 +195,12 @@ ObjFile<ELFT>::getVariableLoc(StringRef Name) { | ... | @@ -182,12 +195,12 @@ ObjFile<ELFT>::getVariableLoc(StringRef Name) { |
| 182 | 195 | ||
| 183 | // Take file name string from line table. | 196 | // Take file name string from line table. |
| 184 | std::string FileName; | 197 | std::string FileName; |
| 185 | if (!LT->getFileNameByIndex( | 198 | if (!It->second.LT->getFileNameByIndex( |
| 186 | It->second.first /* File */, nullptr, | 199 | It->second.File, nullptr, |
| 187 | DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FileName)) | 200 | DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FileName)) |
| 188 | return None; | 201 | return None; |
| 189 | 202 | ||
| 190 | return std::make_pair(FileName, It->second.second /*Line*/); | 203 | return std::make_pair(FileName, It->second.Line); |
| 191 | } | 204 | } |
| 192 | 205 | ||
| 193 | // Returns source line information for a given offset | 206 | // Returns source line information for a given offset |
| ... | @@ -197,29 +210,15 @@ Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *S, | ... | @@ -197,29 +210,15 @@ Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *S, |
| 197 | uint64_t Offset) { | 210 | uint64_t Offset) { |
| 198 | llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); }); | 211 | llvm::call_once(InitDwarfLine, [this]() { initializeDwarf(); }); |
| 199 | 212 | ||
| 200 | // The offset to CU is 0. | ||
| 201 | const DWARFDebugLine::LineTable *Tbl = DwarfLine->getLineTable(0); | ||
| 202 | if (!Tbl) | ||
| 203 | return None; | ||
| 204 | |||
| 205 | // Use fake address calcuated by adding section file offset and offset in | 213 | // Use fake address calcuated by adding section file offset and offset in |
| 206 | // section. See comments for ObjectInfo class. | 214 | // section. See comments for ObjectInfo class. |
| 207 | DILineInfo Info; | 215 | DILineInfo Info; |
| 208 | Tbl->getFileLineInfoForAddress( | 216 | for (const llvm::DWARFDebugLine::LineTable *LT : LineTables) |
| 209 | S->getOffsetInFile() + Offset, nullptr, | 217 | if (LT->getFileLineInfoForAddress( |
| 210 | DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info); | 218 | S->getOffsetInFile() + Offset, nullptr, |
| 211 | if (Info.Line == 0) | 219 | DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info)) |
| 212 | return None; | 220 | return Info; |
| 213 | return Info; | 221 | return None; |
| 214 | } | ||
| 215 | |||
| 216 | // Returns source line information for a given offset | ||
| 217 | // using DWARF debug info. | ||
| 218 | template <class ELFT> | ||
| 219 | std::string ObjFile<ELFT>::getLineInfo(InputSectionBase *S, uint64_t Offset) { | ||
| 220 | if (Optional<DILineInfo> Info = getDILineInfo(S, Offset)) | ||
| 221 | return Info->FileName + ":" + std::to_string(Info->Line); | ||
| 222 | return ""; | ||
| 223 | } | 222 | } |
| 224 | 223 | ||
| 225 | // Returns "<internal>", "foo.a(bar.o)" or "baz.o". | 224 | // Returns "<internal>", "foo.a(bar.o)" or "baz.o". |
| ... | @@ -249,7 +248,7 @@ ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) { | ... | @@ -249,7 +248,7 @@ ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) { |
| 249 | 248 | ||
| 250 | template <class ELFT> | 249 | template <class ELFT> |
| 251 | typename ELFT::SymRange ELFFileBase<ELFT>::getGlobalELFSyms() { | 250 | typename ELFT::SymRange ELFFileBase<ELFT>::getGlobalELFSyms() { |
| 252 | return makeArrayRef(ELFSyms.begin() + FirstNonLocal, ELFSyms.end()); | 251 | return makeArrayRef(ELFSyms.begin() + FirstGlobal, ELFSyms.end()); |
| 253 | } | 252 | } |
| 254 | 253 | ||
| 255 | template <class ELFT> | 254 | template <class ELFT> |
| ... | @@ -260,9 +259,9 @@ uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const { | ... | @@ -260,9 +259,9 @@ uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const { |
| 260 | template <class ELFT> | 259 | template <class ELFT> |
| 261 | void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections, | 260 | void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections, |
| 262 | const Elf_Shdr *Symtab) { | 261 | const Elf_Shdr *Symtab) { |
| 263 | FirstNonLocal = Symtab->sh_info; | 262 | FirstGlobal = Symtab->sh_info; |
| 264 | ELFSyms = CHECK(getObj().symbols(Symtab), this); | 263 | ELFSyms = CHECK(getObj().symbols(Symtab), this); |
| 265 | if (FirstNonLocal == 0 || FirstNonLocal > ELFSyms.size()) | 264 | if (FirstGlobal == 0 || FirstGlobal > ELFSyms.size()) |
| 266 | fatal(toString(this) + ": invalid sh_info in symbol table"); | 265 | fatal(toString(this) + ": invalid sh_info in symbol table"); |
| 267 | 266 | ||
| 268 | StringTable = | 267 | StringTable = |
| ... | @@ -278,13 +277,22 @@ ObjFile<ELFT>::ObjFile(MemoryBufferRef M, StringRef ArchiveName) | ... | @@ -278,13 +277,22 @@ ObjFile<ELFT>::ObjFile(MemoryBufferRef M, StringRef ArchiveName) |
| 278 | template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getLocalSymbols() { | 277 | template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getLocalSymbols() { |
| 279 | if (this->Symbols.empty()) | 278 | if (this->Symbols.empty()) |
| 280 | return {}; | 279 | return {}; |
| 281 | return makeArrayRef(this->Symbols).slice(1, this->FirstNonLocal - 1); | 280 | return makeArrayRef(this->Symbols).slice(1, this->FirstGlobal - 1); |
| 281 | } | ||
| 282 | |||
| 283 | template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getGlobalSymbols() { | ||
| 284 | return makeArrayRef(this->Symbols).slice(this->FirstGlobal); | ||
| 282 | } | 285 | } |
| 283 | 286 | ||
| 284 | template <class ELFT> | 287 | template <class ELFT> |
| 285 | void ObjFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) { | 288 | void ObjFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) { |
| 286 | // Read section and symbol tables. | 289 | // Read a section table. JustSymbols is usually false. |
| 287 | initializeSections(ComdatGroups); | 290 | if (this->JustSymbols) |
| 291 | initializeJustSymbols(); | ||
| 292 | else | ||
| 293 | initializeSections(ComdatGroups); | ||
| 294 | |||
| 295 | // Read a symbol table. | ||
| 288 | initializeSymbols(); | 296 | initializeSymbols(); |
| 289 | } | 297 | } |
| 290 | 298 | ||
| ... | @@ -308,7 +316,7 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections, | ... | @@ -308,7 +316,7 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections, |
| 308 | // we use a section name as a signature. | 316 | // we use a section name as a signature. |
| 309 | // | 317 | // |
| 310 | // Such SHT_GROUP sections are invalid from the perspective of the ELF | 318 | // Such SHT_GROUP sections are invalid from the perspective of the ELF |
| 311 | // standard, but GNU gold 1.14 (the neweset version as of July 2017) or | 319 | // standard, but GNU gold 1.14 (the newest version as of July 2017) or |
| 312 | // older produce such sections as outputs for the -r option, so we need | 320 | // older produce such sections as outputs for the -r option, so we need |
| 313 | // a bug-compatibility. | 321 | // a bug-compatibility. |
| 314 | if (Signature.empty() && Sym->getType() == STT_SECTION) | 322 | if (Signature.empty() && Sym->getType() == STT_SECTION) |
| ... | @@ -328,9 +336,19 @@ ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { | ... | @@ -328,9 +336,19 @@ ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { |
| 328 | } | 336 | } |
| 329 | 337 | ||
| 330 | template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { | 338 | template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { |
| 331 | // We don't merge sections if -O0 (default is -O1). This makes sometimes | 339 | // On a regular link we don't merge sections if -O0 (default is -O1). This |
| 332 | // the linker significantly faster, although the output will be bigger. | 340 | // sometimes makes the linker significantly faster, although the output will |
| 333 | if (Config->Optimize == 0) | 341 | // be bigger. |
| 342 | // | ||
| 343 | // Doing the same for -r would create a problem as it would combine sections | ||
| 344 | // with different sh_entsize. One option would be to just copy every SHF_MERGE | ||
| 345 | // section as is to the output. While this would produce a valid ELF file with | ||
| 346 | // usable SHF_MERGE sections, tools like (llvm-)?dwarfdump get confused when | ||
| 347 | // they see two .debug_str. We could have separate logic for combining | ||
| 348 | // SHF_MERGE sections based both on their name and sh_entsize, but that seems | ||
| 349 | // to be more trouble than it is worth. Instead, we just use the regular (-O1) | ||
| 350 | // logic for -r. | ||
| 351 | if (Config->Optimize == 0 && !Config->Relocatable) | ||
| 334 | return false; | 352 | return false; |
| 335 | 353 | ||
| 336 | // A mergeable section with size 0 is useless because they don't have | 354 | // A mergeable section with size 0 is useless because they don't have |
| ... | @@ -361,12 +379,33 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { | ... | @@ -361,12 +379,33 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { |
| 361 | return true; | 379 | return true; |
| 362 | } | 380 | } |
| 363 | 381 | ||
| 382 | // This is for --just-symbols. | ||
| 383 | // | ||
| 384 | // --just-symbols is a very minor feature that allows you to link your | ||
| 385 | // output against other existing program, so that if you load both your | ||
| 386 | // program and the other program into memory, your output can refer the | ||
| 387 | // other program's symbols. | ||
| 388 | // | ||
| 389 | // When the option is given, we link "just symbols". The section table is | ||
| 390 | // initialized with null pointers. | ||
| 391 | template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() { | ||
| 392 | ArrayRef<Elf_Shdr> ObjSections = CHECK(this->getObj().sections(), this); | ||
| 393 | this->Sections.resize(ObjSections.size()); | ||
| 394 | |||
| 395 | for (const Elf_Shdr &Sec : ObjSections) { | ||
| 396 | if (Sec.sh_type != SHT_SYMTAB) | ||
| 397 | continue; | ||
| 398 | this->initSymtab(ObjSections, &Sec); | ||
| 399 | return; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 364 | template <class ELFT> | 403 | template <class ELFT> |
| 365 | void ObjFile<ELFT>::initializeSections( | 404 | void ObjFile<ELFT>::initializeSections( |
| 366 | DenseSet<CachedHashStringRef> &ComdatGroups) { | 405 | DenseSet<CachedHashStringRef> &ComdatGroups) { |
| 367 | const ELFFile<ELFT> &Obj = this->getObj(); | 406 | const ELFFile<ELFT> &Obj = this->getObj(); |
| 368 | 407 | ||
| 369 | ArrayRef<Elf_Shdr> ObjSections = CHECK(this->getObj().sections(), this); | 408 | ArrayRef<Elf_Shdr> ObjSections = CHECK(Obj.sections(), this); |
| 370 | uint64_t Size = ObjSections.size(); | 409 | uint64_t Size = ObjSections.size(); |
| 371 | this->Sections.resize(Size); | 410 | this->Sections.resize(Size); |
| 372 | this->SectionStringTable = | 411 | this->SectionStringTable = |
| ... | @@ -381,6 +420,17 @@ void ObjFile<ELFT>::initializeSections( | ... | @@ -381,6 +420,17 @@ void ObjFile<ELFT>::initializeSections( |
| 381 | // if -r is given, we'll let the final link discard such sections. | 420 | // if -r is given, we'll let the final link discard such sections. |
| 382 | // This is compatible with GNU. | 421 | // This is compatible with GNU. |
| 383 | if ((Sec.sh_flags & SHF_EXCLUDE) && !Config->Relocatable) { | 422 | if ((Sec.sh_flags & SHF_EXCLUDE) && !Config->Relocatable) { |
| 423 | if (Sec.sh_type == SHT_LLVM_ADDRSIG) { | ||
| 424 | // We ignore the address-significance table if we know that the object | ||
| 425 | // file was created by objcopy or ld -r. This is because these tools | ||
| 426 | // will reorder the symbols in the symbol table, invalidating the data | ||
| 427 | // in the address-significance table, which refers to symbols by index. | ||
| 428 | if (Sec.sh_link != 0) | ||
| 429 | this->AddrsigSec = &Sec; | ||
| 430 | else if (Config->ICF == ICFLevel::Safe) | ||
| 431 | warn(toString(this) + ": --icf=safe is incompatible with object " | ||
| 432 | "files created using objcopy or ld -r"); | ||
| 433 | } | ||
| 384 | this->Sections[I] = &InputSection::Discarded; | 434 | this->Sections[I] = &InputSection::Discarded; |
| 385 | continue; | 435 | continue; |
| 386 | } | 436 | } |
| ... | @@ -431,12 +481,59 @@ void ObjFile<ELFT>::initializeSections( | ... | @@ -431,12 +481,59 @@ void ObjFile<ELFT>::initializeSections( |
| 431 | if (Sec.sh_link >= this->Sections.size()) | 481 | if (Sec.sh_link >= this->Sections.size()) |
| 432 | fatal(toString(this) + | 482 | fatal(toString(this) + |
| 433 | ": invalid sh_link index: " + Twine(Sec.sh_link)); | 483 | ": invalid sh_link index: " + Twine(Sec.sh_link)); |
| 434 | this->Sections[Sec.sh_link]->DependentSections.push_back( | 484 | |
| 435 | cast<InputSection>(this->Sections[I])); | 485 | InputSectionBase *LinkSec = this->Sections[Sec.sh_link]; |
| 486 | InputSection *IS = cast<InputSection>(this->Sections[I]); | ||
| 487 | LinkSec->DependentSections.push_back(IS); | ||
| 488 | if (!isa<InputSection>(LinkSec)) | ||
| 489 | error("a section " + IS->Name + | ||
| 490 | " with SHF_LINK_ORDER should not refer a non-regular " | ||
| 491 | "section: " + | ||
| 492 | toString(LinkSec)); | ||
| 436 | } | 493 | } |
| 437 | } | 494 | } |
| 438 | } | 495 | } |
| 439 | 496 | ||
| 497 | // For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD | ||
| 498 | // flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how | ||
| 499 | // the input objects have been compiled. | ||
| 500 | static void updateARMVFPArgs(const ARMAttributeParser &Attributes, | ||
| 501 | const InputFile *F) { | ||
| 502 | if (!Attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args)) | ||
| 503 | // If an ABI tag isn't present then it is implicitly given the value of 0 | ||
| 504 | // which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files, | ||
| 505 | // including some in glibc that don't use FP args (and should have value 3) | ||
| 506 | // don't have the attribute so we do not consider an implicit value of 0 | ||
| 507 | // as a clash. | ||
| 508 | return; | ||
| 509 | |||
| 510 | unsigned VFPArgs = Attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args); | ||
| 511 | ARMVFPArgKind Arg; | ||
| 512 | switch (VFPArgs) { | ||
| 513 | case ARMBuildAttrs::BaseAAPCS: | ||
| 514 | Arg = ARMVFPArgKind::Base; | ||
| 515 | break; | ||
| 516 | case ARMBuildAttrs::HardFPAAPCS: | ||
| 517 | Arg = ARMVFPArgKind::VFP; | ||
| 518 | break; | ||
| 519 | case ARMBuildAttrs::ToolChainFPPCS: | ||
| 520 | // Tool chain specific convention that conforms to neither AAPCS variant. | ||
| 521 | Arg = ARMVFPArgKind::ToolChain; | ||
| 522 | break; | ||
| 523 | case ARMBuildAttrs::CompatibleFPAAPCS: | ||
| 524 | // Object compatible with all conventions. | ||
| 525 | return; | ||
| 526 | default: | ||
| 527 | error(toString(F) + ": unknown Tag_ABI_VFP_args value: " + Twine(VFPArgs)); | ||
| 528 | return; | ||
| 529 | } | ||
| 530 | // Follow ld.bfd and error if there is a mix of calling conventions. | ||
| 531 | if (Config->ARMVFPArgs != Arg && Config->ARMVFPArgs != ARMVFPArgKind::Default) | ||
| 532 | error(toString(F) + ": incompatible Tag_ABI_VFP_args"); | ||
| 533 | else | ||
| 534 | Config->ARMVFPArgs = Arg; | ||
| 535 | } | ||
| 536 | |||
| 440 | // The ARM support in lld makes some use of instructions that are not available | 537 | // The ARM support in lld makes some use of instructions that are not available |
| 441 | // on all ARM architectures. Namely: | 538 | // on all ARM architectures. Namely: |
| 442 | // - Use of BLX instruction for interworking between ARM and Thumb state. | 539 | // - Use of BLX instruction for interworking between ARM and Thumb state. |
| ... | @@ -516,6 +613,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | ... | @@ -516,6 +613,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 516 | ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec)); | 613 | ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec)); |
| 517 | Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind); | 614 | Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind); |
| 518 | updateSupportedARMFeatures(Attributes); | 615 | updateSupportedARMFeatures(Attributes); |
| 616 | updateARMVFPArgs(Attributes, this); | ||
| 617 | |||
| 519 | // FIXME: Retain the first attribute section we see. The eglibc ARM | 618 | // FIXME: Retain the first attribute section we see. The eglibc ARM |
| 520 | // dynamic loaders require the presence of an attribute section for dlopen | 619 | // dynamic loaders require the presence of an attribute section for dlopen |
| 521 | // to work. In a full implementation we would merge all attribute sections. | 620 | // to work. In a full implementation we would merge all attribute sections. |
| ... | @@ -527,10 +626,11 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | ... | @@ -527,10 +626,11 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 527 | } | 626 | } |
| 528 | case SHT_RELA: | 627 | case SHT_RELA: |
| 529 | case SHT_REL: { | 628 | case SHT_REL: { |
| 530 | // Find the relocation target section and associate this | 629 | // Find a relocation target section and associate this section with that. |
| 531 | // section with it. Target can be discarded, for example | 630 | // Target may have been discarded if it is in a different section group |
| 532 | // if it is a duplicated member of SHT_GROUP section, we | 631 | // and the group is discarded, even though it's a violation of the |
| 533 | // do not create or proccess relocatable sections then. | 632 | // spec. We handle that situation gracefully by discarding dangling |
| 633 | // relocation sections. | ||
| 534 | InputSectionBase *Target = getRelocTarget(Sec); | 634 | InputSectionBase *Target = getRelocTarget(Sec); |
| 535 | if (!Target) | 635 | if (!Target) |
| 536 | return nullptr; | 636 | return nullptr; |
| ... | @@ -545,32 +645,28 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | ... | @@ -545,32 +645,28 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 545 | fatal(toString(this) + | 645 | fatal(toString(this) + |
| 546 | ": multiple relocation sections to one section are not supported"); | 646 | ": multiple relocation sections to one section are not supported"); |
| 547 | 647 | ||
| 548 | // Mergeable sections with relocations are tricky because relocations | 648 | // ELF spec allows mergeable sections with relocations, but they are |
| 549 | // need to be taken into account when comparing section contents for | 649 | // rare, and it is in practice hard to merge such sections by contents, |
| 550 | // merging. It's not worth supporting such mergeable sections because | 650 | // because applying relocations at end of linking changes section |
| 551 | // they are rare and it'd complicates the internal design (we usually | 651 | // contents. So, we simply handle such sections as non-mergeable ones. |
| 552 | // have to determine if two sections are mergeable early in the link | 652 | // Degrading like this is acceptable because section merging is optional. |
| 553 | // process much before applying relocations). We simply handle mergeable | ||
| 554 | // sections with relocations as non-mergeable. | ||
| 555 | if (auto *MS = dyn_cast<MergeInputSection>(Target)) { | 653 | if (auto *MS = dyn_cast<MergeInputSection>(Target)) { |
| 556 | Target = toRegularSection(MS); | 654 | Target = toRegularSection(MS); |
| 557 | this->Sections[Sec.sh_info] = Target; | 655 | this->Sections[Sec.sh_info] = Target; |
| 558 | } | 656 | } |
| 559 | 657 | ||
| 560 | size_t NumRelocations; | ||
| 561 | if (Sec.sh_type == SHT_RELA) { | 658 | if (Sec.sh_type == SHT_RELA) { |
| 562 | ArrayRef<Elf_Rela> Rels = CHECK(this->getObj().relas(&Sec), this); | 659 | ArrayRef<Elf_Rela> Rels = CHECK(this->getObj().relas(&Sec), this); |
| 563 | Target->FirstRelocation = Rels.begin(); | 660 | Target->FirstRelocation = Rels.begin(); |
| 564 | NumRelocations = Rels.size(); | 661 | Target->NumRelocations = Rels.size(); |
| 565 | Target->AreRelocsRela = true; | 662 | Target->AreRelocsRela = true; |
| 566 | } else { | 663 | } else { |
| 567 | ArrayRef<Elf_Rel> Rels = CHECK(this->getObj().rels(&Sec), this); | 664 | ArrayRef<Elf_Rel> Rels = CHECK(this->getObj().rels(&Sec), this); |
| 568 | Target->FirstRelocation = Rels.begin(); | 665 | Target->FirstRelocation = Rels.begin(); |
| 569 | NumRelocations = Rels.size(); | 666 | Target->NumRelocations = Rels.size(); |
| 570 | Target->AreRelocsRela = false; | 667 | Target->AreRelocsRela = false; |
| 571 | } | 668 | } |
| 572 | assert(isUInt<31>(NumRelocations)); | 669 | assert(isUInt<31>(Target->NumRelocations)); |
| 573 | Target->NumRelocations = NumRelocations; | ||
| 574 | 670 | ||
| 575 | // Relocation sections processed by the linker are usually removed | 671 | // Relocation sections processed by the linker are usually removed |
| 576 | // from the output, so returning `nullptr` for the normal case. | 672 | // from the output, so returning `nullptr` for the normal case. |
| ... | @@ -602,13 +698,24 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | ... | @@ -602,13 +698,24 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 602 | if (Name == ".note.GNU-stack") | 698 | if (Name == ".note.GNU-stack") |
| 603 | return &InputSection::Discarded; | 699 | return &InputSection::Discarded; |
| 604 | 700 | ||
| 605 | // Split stacks is a feature to support a discontiguous stack. At least | 701 | // Split stacks is a feature to support a discontiguous stack, |
| 606 | // as of 2017, it seems that the feature is not being used widely. | 702 | // commonly used in the programming language Go. For the details, |
| 607 | // Only GNU gold supports that. We don't. For the details about that, | 703 | // see https://gcc.gnu.org/wiki/SplitStacks. An object file compiled |
| 608 | // see https://gcc.gnu.org/wiki/SplitStacks | 704 | // for split stack will include a .note.GNU-split-stack section. |
| 609 | if (Name == ".note.GNU-split-stack") { | 705 | if (Name == ".note.GNU-split-stack") { |
| 610 | error(toString(this) + | 706 | if (Config->Relocatable) { |
| 611 | ": object file compiled with -fsplit-stack is not supported"); | 707 | error("Cannot mix split-stack and non-split-stack in a relocatable link"); |
| 708 | return &InputSection::Discarded; | ||
| 709 | } | ||
| 710 | this->SplitStack = true; | ||
| 711 | return &InputSection::Discarded; | ||
| 712 | } | ||
| 713 | |||
| 714 | // An object file cmpiled for split stack, but where some of the | ||
| 715 | // functions were compiled with the no_split_stack_attribute will | ||
| 716 | // include a .note.GNU-no-split-stack section. | ||
| 717 | if (Name == ".note.GNU-no-split-stack") { | ||
| 718 | this->SomeNoSplitStack = true; | ||
| 612 | return &InputSection::Discarded; | 719 | return &InputSection::Discarded; |
| 613 | } | 720 | } |
| 614 | 721 | ||
| ... | @@ -620,6 +727,14 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { | ... | @@ -620,6 +727,14 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { |
| 620 | if (Name.startswith(".gnu.linkonce.")) | 727 | if (Name.startswith(".gnu.linkonce.")) |
| 621 | return &InputSection::Discarded; | 728 | return &InputSection::Discarded; |
| 622 | 729 | ||
| 730 | // If we are creating a new .build-id section, strip existing .build-id | ||
| 731 | // sections so that the output won't have more than one .build-id. | ||
| 732 | // This is not usually a problem because input object files normally don't | ||
| 733 | // have .build-id sections, but you can create such files by | ||
| 734 | // "ld.{bfd,gold,lld} -r --build-id", and we want to guard against it. | ||
| 735 | if (Name == ".note.gnu.build-id" && Config->BuildId != BuildIdKind::None) | ||
| 736 | return &InputSection::Discarded; | ||
| 737 | |||
| 623 | // The linker merges EH (exception handling) frames and creates a | 738 | // The linker merges EH (exception handling) frames and creates a |
| 624 | // .eh_frame_hdr section for runtime. So we handle them with a special | 739 | // .eh_frame_hdr section for runtime. So we handle them with a special |
| 625 | // class. For relocatable outputs, they are just passed through. | 740 | // class. For relocatable outputs, they are just passed through. |
| ... | @@ -701,33 +816,33 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File) | ... | @@ -701,33 +816,33 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File) |
| 701 | File(std::move(File)) {} | 816 | File(std::move(File)) {} |
| 702 | 817 | ||
| 703 | template <class ELFT> void ArchiveFile::parse() { | 818 | template <class ELFT> void ArchiveFile::parse() { |
| 704 | Symbols.reserve(File->getNumberOfSymbols()); | ||
| 705 | for (const Archive::Symbol &Sym : File->symbols()) | 819 | for (const Archive::Symbol &Sym : File->symbols()) |
| 706 | Symbols.push_back(Symtab->addLazyArchive<ELFT>(Sym.getName(), *this, Sym)); | 820 | Symtab->addLazyArchive<ELFT>(Sym.getName(), *this, Sym); |
| 707 | } | 821 | } |
| 708 | 822 | ||
| 709 | // Returns a buffer pointing to a member file containing a given symbol. | 823 | // Returns a buffer pointing to a member file containing a given symbol. |
| 710 | std::pair<MemoryBufferRef, uint64_t> | 824 | InputFile *ArchiveFile::fetch(const Archive::Symbol &Sym) { |
| 711 | ArchiveFile::getMember(const Archive::Symbol *Sym) { | ||
| 712 | Archive::Child C = | 825 | Archive::Child C = |
| 713 | CHECK(Sym->getMember(), toString(this) + | 826 | CHECK(Sym.getMember(), toString(this) + |
| 714 | ": could not get the member for symbol " + | 827 | ": could not get the member for symbol " + |
| 715 | Sym->getName()); | 828 | Sym.getName()); |
| 716 | 829 | ||
| 717 | if (!Seen.insert(C.getChildOffset()).second) | 830 | if (!Seen.insert(C.getChildOffset()).second) |
| 718 | return {MemoryBufferRef(), 0}; | 831 | return nullptr; |
| 719 | 832 | ||
| 720 | MemoryBufferRef Ret = | 833 | MemoryBufferRef MB = |
| 721 | CHECK(C.getMemoryBufferRef(), | 834 | CHECK(C.getMemoryBufferRef(), |
| 722 | toString(this) + | 835 | toString(this) + |
| 723 | ": could not get the buffer for the member defining symbol " + | 836 | ": could not get the buffer for the member defining symbol " + |
| 724 | Sym->getName()); | 837 | Sym.getName()); |
| 838 | |||
| 839 | if (Tar && C.getParent()->isThin()) | ||
| 840 | Tar->append(relativeToRoot(CHECK(C.getFullName(), this)), MB.getBuffer()); | ||
| 725 | 841 | ||
| 726 | if (C.getParent()->isThin() && Tar) | 842 | InputFile *File = createObjectFile( |
| 727 | Tar->append(relativeToRoot(CHECK(C.getFullName(), this)), Ret.getBuffer()); | 843 | MB, getName(), C.getParent()->isThin() ? 0 : C.getChildOffset()); |
| 728 | if (C.getParent()->isThin()) | 844 | File->GroupId = GroupId; |
| 729 | return {Ret, 0}; | 845 | return File; |
| 730 | return {Ret, C.getChildOffset()}; | ||
| 731 | } | 846 | } |
| 732 | 847 | ||
| 733 | template <class ELFT> | 848 | template <class ELFT> |
| ... | @@ -784,34 +899,42 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() { | ... | @@ -784,34 +899,42 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() { |
| 784 | } | 899 | } |
| 785 | } | 900 | } |
| 786 | 901 | ||
| 902 | // Parses ".gnu.version" section which is a parallel array for the symbol table. | ||
| 903 | // If a given file doesn't have ".gnu.version" section, returns VER_NDX_GLOBAL. | ||
| 904 | template <class ELFT> std::vector<uint32_t> SharedFile<ELFT>::parseVersyms() { | ||
| 905 | size_t Size = this->ELFSyms.size() - this->FirstGlobal; | ||
| 906 | if (!VersymSec) | ||
| 907 | return std::vector<uint32_t>(Size, VER_NDX_GLOBAL); | ||
| 908 | |||
| 909 | const char *Base = this->MB.getBuffer().data(); | ||
| 910 | const Elf_Versym *Versym = | ||
| 911 | reinterpret_cast<const Elf_Versym *>(Base + VersymSec->sh_offset) + | ||
| 912 | this->FirstGlobal; | ||
| 913 | |||
| 914 | std::vector<uint32_t> Ret(Size); | ||
| 915 | for (size_t I = 0; I < Size; ++I) | ||
| 916 | Ret[I] = Versym[I].vs_index; | ||
| 917 | return Ret; | ||
| 918 | } | ||
| 919 | |||
| 787 | // Parse the version definitions in the object file if present. Returns a vector | 920 | // Parse the version definitions in the object file if present. Returns a vector |
| 788 | // whose nth element contains a pointer to the Elf_Verdef for version identifier | 921 | // whose nth element contains a pointer to the Elf_Verdef for version identifier |
| 789 | // n. Version identifiers that are not definitions map to nullptr. The array | 922 | // n. Version identifiers that are not definitions map to nullptr. |
| 790 | // always has at least length 1. | ||
| 791 | template <class ELFT> | 923 | template <class ELFT> |
| 792 | std::vector<const typename ELFT::Verdef *> | 924 | std::vector<const typename ELFT::Verdef *> SharedFile<ELFT>::parseVerdefs() { |
| 793 | SharedFile<ELFT>::parseVerdefs(const Elf_Versym *&Versym) { | 925 | if (!VerdefSec) |
| 794 | std::vector<const Elf_Verdef *> Verdefs(1); | 926 | return {}; |
| 795 | // We only need to process symbol versions for this DSO if it has both a | ||
| 796 | // versym and a verdef section, which indicates that the DSO contains symbol | ||
| 797 | // version definitions. | ||
| 798 | if (!VersymSec || !VerdefSec) | ||
| 799 | return Verdefs; | ||
| 800 | |||
| 801 | // The location of the first global versym entry. | ||
| 802 | const char *Base = this->MB.getBuffer().data(); | ||
| 803 | Versym = reinterpret_cast<const Elf_Versym *>(Base + VersymSec->sh_offset) + | ||
| 804 | this->FirstNonLocal; | ||
| 805 | 927 | ||
| 806 | // We cannot determine the largest verdef identifier without inspecting | 928 | // We cannot determine the largest verdef identifier without inspecting |
| 807 | // every Elf_Verdef, but both bfd and gold assign verdef identifiers | 929 | // every Elf_Verdef, but both bfd and gold assign verdef identifiers |
| 808 | // sequentially starting from 1, so we predict that the largest identifier | 930 | // sequentially starting from 1, so we predict that the largest identifier |
| 809 | // will be VerdefCount. | 931 | // will be VerdefCount. |
| 810 | unsigned VerdefCount = VerdefSec->sh_info; | 932 | unsigned VerdefCount = VerdefSec->sh_info; |
| 811 | Verdefs.resize(VerdefCount + 1); | 933 | std::vector<const Elf_Verdef *> Verdefs(VerdefCount + 1); |
| 812 | 934 | ||
| 813 | // Build the Verdefs array by following the chain of Elf_Verdef objects | 935 | // Build the Verdefs array by following the chain of Elf_Verdef objects |
| 814 | // from the start of the .gnu.version_d section. | 936 | // from the start of the .gnu.version_d section. |
| 937 | const char *Base = this->MB.getBuffer().data(); | ||
| 815 | const char *Verdef = Base + VerdefSec->sh_offset; | 938 | const char *Verdef = Base + VerdefSec->sh_offset; |
| 816 | for (unsigned I = 0; I != VerdefCount; ++I) { | 939 | for (unsigned I = 0; I != VerdefCount; ++I) { |
| 817 | auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef); | 940 | auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef); |
| ... | @@ -825,82 +948,99 @@ SharedFile<ELFT>::parseVerdefs(const Elf_Versym *&Versym) { | ... | @@ -825,82 +948,99 @@ SharedFile<ELFT>::parseVerdefs(const Elf_Versym *&Versym) { |
| 825 | return Verdefs; | 948 | return Verdefs; |
| 826 | } | 949 | } |
| 827 | 950 | ||
| 951 | // We do not usually care about alignments of data in shared object | ||
| 952 | // files because the loader takes care of it. However, if we promote a | ||
| 953 | // DSO symbol to point to .bss due to copy relocation, we need to keep | ||
| 954 | // the original alignment requirements. We infer it in this function. | ||
| 955 | template <class ELFT> | ||
| 956 | uint32_t SharedFile<ELFT>::getAlignment(ArrayRef<Elf_Shdr> Sections, | ||
| 957 | const Elf_Sym &Sym) { | ||
| 958 | uint64_t Ret = UINT64_MAX; | ||
| 959 | if (Sym.st_value) | ||
| 960 | Ret = 1ULL << countTrailingZeros((uint64_t)Sym.st_value); | ||
| 961 | if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size()) | ||
| 962 | Ret = std::min<uint64_t>(Ret, Sections[Sym.st_shndx].sh_addralign); | ||
| 963 | return (Ret > UINT32_MAX) ? 0 : Ret; | ||
| 964 | } | ||
| 965 | |||
| 828 | // Fully parse the shared object file. This must be called after parseSoName(). | 966 | // Fully parse the shared object file. This must be called after parseSoName(). |
| 967 | // | ||
| 968 | // This function parses symbol versions. If a DSO has version information, | ||
| 969 | // the file has a ".gnu.version_d" section which contains symbol version | ||
| 970 | // definitions. Each symbol is associated to one version through a table in | ||
| 971 | // ".gnu.version" section. That table is a parallel array for the symbol | ||
| 972 | // table, and each table entry contains an index in ".gnu.version_d". | ||
| 973 | // | ||
| 974 | // The special index 0 is reserved for VERF_NDX_LOCAL and 1 is for | ||
| 975 | // VER_NDX_GLOBAL. There's no table entry for these special versions in | ||
| 976 | // ".gnu.version_d". | ||
| 977 | // | ||
| 978 | // The file format for symbol versioning is perhaps a bit more complicated | ||
| 979 | // than necessary, but you can easily understand the code if you wrap your | ||
| 980 | // head around the data structure described above. | ||
| 829 | template <class ELFT> void SharedFile<ELFT>::parseRest() { | 981 | template <class ELFT> void SharedFile<ELFT>::parseRest() { |
| 830 | // Create mapping from version identifiers to Elf_Verdef entries. | 982 | Verdefs = parseVerdefs(); // parse .gnu.version_d |
| 831 | const Elf_Versym *Versym = nullptr; | 983 | std::vector<uint32_t> Versyms = parseVersyms(); // parse .gnu.version |
| 832 | Verdefs = parseVerdefs(Versym); | ||
| 833 | |||
| 834 | ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this); | 984 | ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj().sections(), this); |
| 835 | 985 | ||
| 986 | // System libraries can have a lot of symbols with versions. Using a | ||
| 987 | // fixed buffer for computing the versions name (foo@ver) can save a | ||
| 988 | // lot of allocations. | ||
| 989 | SmallString<0> VersionedNameBuffer; | ||
| 990 | |||
| 836 | // Add symbols to the symbol table. | 991 | // Add symbols to the symbol table. |
| 837 | Elf_Sym_Range Syms = this->getGlobalELFSyms(); | 992 | ArrayRef<Elf_Sym> Syms = this->getGlobalELFSyms(); |
| 838 | for (const Elf_Sym &Sym : Syms) { | 993 | for (size_t I = 0; I < Syms.size(); ++I) { |
| 839 | unsigned VersymIndex = VER_NDX_GLOBAL; | 994 | const Elf_Sym &Sym = Syms[I]; |
| 840 | if (Versym) { | ||
| 841 | VersymIndex = Versym->vs_index; | ||
| 842 | ++Versym; | ||
| 843 | } | ||
| 844 | bool Hidden = VersymIndex & VERSYM_HIDDEN; | ||
| 845 | VersymIndex = VersymIndex & ~VERSYM_HIDDEN; | ||
| 846 | 995 | ||
| 847 | StringRef Name = CHECK(Sym.getName(this->StringTable), this); | 996 | StringRef Name = CHECK(Sym.getName(this->StringTable), this); |
| 848 | if (Sym.isUndefined()) { | 997 | if (Sym.isUndefined()) { |
| 849 | Undefs.push_back(Name); | 998 | Symbol *S = Symtab->addUndefined<ELFT>(Name, Sym.getBinding(), |
| 999 | Sym.st_other, Sym.getType(), | ||
| 1000 | /*CanOmitFromDynSym=*/false, this); | ||
| 1001 | S->ExportDynamic = true; | ||
| 850 | continue; | 1002 | continue; |
| 851 | } | 1003 | } |
| 852 | 1004 | ||
| 1005 | // ELF spec requires that all local symbols precede weak or global | ||
| 1006 | // symbols in each symbol table, and the index of first non-local symbol | ||
| 1007 | // is stored to sh_info. If a local symbol appears after some non-local | ||
| 1008 | // symbol, that's a violation of the spec. | ||
| 853 | if (Sym.getBinding() == STB_LOCAL) { | 1009 | if (Sym.getBinding() == STB_LOCAL) { |
| 854 | warn("found local symbol '" + Name + | 1010 | warn("found local symbol '" + Name + |
| 855 | "' in global part of symbol table in file " + toString(this)); | 1011 | "' in global part of symbol table in file " + toString(this)); |
| 856 | continue; | 1012 | continue; |
| 857 | } | 1013 | } |
| 858 | 1014 | ||
| 859 | if (Config->EMachine == EM_MIPS) { | 1015 | // MIPS BFD linker puts _gp_disp symbol into DSO files and incorrectly |
| 860 | // FIXME: MIPS BFD linker puts _gp_disp symbol into DSO files | 1016 | // assigns VER_NDX_LOCAL to this section global symbol. Here is a |
| 861 | // and incorrectly assigns VER_NDX_LOCAL to this section global | 1017 | // workaround for this bug. |
| 862 | // symbol. Here is a workaround for this bug. | 1018 | uint32_t Idx = Versyms[I] & ~VERSYM_HIDDEN; |
| 863 | if (Versym && VersymIndex == VER_NDX_LOCAL && Name == "_gp_disp") | 1019 | if (Config->EMachine == EM_MIPS && Idx == VER_NDX_LOCAL && |
| 864 | continue; | 1020 | Name == "_gp_disp") |
| 865 | } | 1021 | continue; |
| 866 | |||
| 867 | const Elf_Verdef *Ver = nullptr; | ||
| 868 | if (VersymIndex != VER_NDX_GLOBAL) { | ||
| 869 | if (VersymIndex >= Verdefs.size() || VersymIndex == VER_NDX_LOCAL) { | ||
| 870 | error("corrupt input file: version definition index " + | ||
| 871 | Twine(VersymIndex) + " for symbol " + Name + | ||
| 872 | " is out of bounds\n>>> defined in " + toString(this)); | ||
| 873 | continue; | ||
| 874 | } | ||
| 875 | Ver = Verdefs[VersymIndex]; | ||
| 876 | } else { | ||
| 877 | VersymIndex = 0; | ||
| 878 | } | ||
| 879 | |||
| 880 | // We do not usually care about alignments of data in shared object | ||
| 881 | // files because the loader takes care of it. However, if we promote a | ||
| 882 | // DSO symbol to point to .bss due to copy relocation, we need to keep | ||
| 883 | // the original alignment requirements. We infer it here. | ||
| 884 | uint64_t Alignment = 1; | ||
| 885 | if (Sym.st_value) | ||
| 886 | Alignment = 1ULL << countTrailingZeros((uint64_t)Sym.st_value); | ||
| 887 | if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size()) { | ||
| 888 | uint64_t SecAlign = Sections[Sym.st_shndx].sh_addralign; | ||
| 889 | Alignment = std::min(Alignment, SecAlign); | ||
| 890 | } | ||
| 891 | if (Alignment > UINT32_MAX) | ||
| 892 | error(toString(this) + ": alignment too large: " + Name); | ||
| 893 | 1022 | ||
| 894 | if (!Hidden) | 1023 | uint64_t Alignment = getAlignment(Sections, Sym); |
| 895 | Symtab->addShared(Name, *this, Sym, Alignment, VersymIndex); | 1024 | if (!(Versyms[I] & VERSYM_HIDDEN)) |
| 1025 | Symtab->addShared(Name, *this, Sym, Alignment, Idx); | ||
| 896 | 1026 | ||
| 897 | // Also add the symbol with the versioned name to handle undefined symbols | 1027 | // Also add the symbol with the versioned name to handle undefined symbols |
| 898 | // with explicit versions. | 1028 | // with explicit versions. |
| 899 | if (Ver) { | 1029 | if (Idx == VER_NDX_GLOBAL) |
| 900 | StringRef VerName = this->StringTable.data() + Ver->getAux()->vda_name; | 1030 | continue; |
| 901 | Name = Saver.save(Name + "@" + VerName); | 1031 | |
| 902 | Symtab->addShared(Name, *this, Sym, Alignment, VersymIndex); | 1032 | if (Idx >= Verdefs.size() || Idx == VER_NDX_LOCAL) { |
| 1033 | error("corrupt input file: version definition index " + Twine(Idx) + | ||
| 1034 | " for symbol " + Name + " is out of bounds\n>>> defined in " + | ||
| 1035 | toString(this)); | ||
| 1036 | continue; | ||
| 903 | } | 1037 | } |
| 1038 | |||
| 1039 | StringRef VerName = | ||
| 1040 | this->StringTable.data() + Verdefs[Idx]->getAux()->vda_name; | ||
| 1041 | VersionedNameBuffer.clear(); | ||
| 1042 | Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer); | ||
| 1043 | Symtab->addShared(Saver.save(Name), *this, Sym, Alignment, Idx); | ||
| 904 | } | 1044 | } |
| 905 | } | 1045 | } |
| 906 | 1046 | ||
| ... | @@ -933,8 +1073,9 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) { | ... | @@ -933,8 +1073,9 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) { |
| 933 | case Triple::x86_64: | 1073 | case Triple::x86_64: |
| 934 | return EM_X86_64; | 1074 | return EM_X86_64; |
| 935 | default: | 1075 | default: |
| 936 | fatal(Path + ": could not infer e_machine from bitcode target triple " + | 1076 | error(Path + ": could not infer e_machine from bitcode target triple " + |
| 937 | T.str()); | 1077 | T.str()); |
| 1078 | return EM_NONE; | ||
| 938 | } | 1079 | } |
| 939 | } | 1080 | } |
| 940 | 1081 | ||
| ... | @@ -943,17 +1084,21 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, | ... | @@ -943,17 +1084,21 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, |
| 943 | : InputFile(BitcodeKind, MB) { | 1084 | : InputFile(BitcodeKind, MB) { |
| 944 | this->ArchiveName = ArchiveName; | 1085 | this->ArchiveName = ArchiveName; |
| 945 | 1086 | ||
| 946 | // Here we pass a new MemoryBufferRef which is identified by ArchiveName | 1087 | std::string Path = MB.getBufferIdentifier().str(); |
| 947 | // (the fully resolved path of the archive) + member name + offset of the | 1088 | if (Config->ThinLTOIndexOnly) |
| 948 | // member in the archive. | 1089 | Path = replaceThinLTOSuffix(MB.getBufferIdentifier()); |
| 949 | // ThinLTO uses the MemoryBufferRef identifier to access its internal | 1090 | |
| 950 | // data structures and if two archives define two members with the same name, | 1091 | // ThinLTO assumes that all MemoryBufferRefs given to it have a unique |
| 951 | // this causes a collision which result in only one of the objects being | 1092 | // name. If two archives define two members with the same name, this |
| 952 | // taken into consideration at LTO time (which very likely causes undefined | 1093 | // causes a collision which result in only one of the objects being taken |
| 953 | // symbols later in the link stage). | 1094 | // into consideration at LTO time (which very likely causes undefined |
| 954 | MemoryBufferRef MBRef(MB.getBuffer(), | 1095 | // symbols later in the link stage). So we append file offset to make |
| 955 | Saver.save(ArchiveName + MB.getBufferIdentifier() + | 1096 | // filename unique. |
| 956 | utostr(OffsetInArchive))); | 1097 | MemoryBufferRef MBRef( |
| 1098 | MB.getBuffer(), | ||
| 1099 | Saver.save(ArchiveName + Path + | ||
| 1100 | (ArchiveName.empty() ? "" : utostr(OffsetInArchive)))); | ||
| 1101 | |||
| 957 | Obj = CHECK(lto::InputFile::create(MBRef), this); | 1102 | Obj = CHECK(lto::InputFile::create(MBRef), this); |
| 958 | 1103 | ||
| 959 | Triple T(Obj->getTargetTriple()); | 1104 | Triple T(Obj->getTargetTriple()); |
| ... | @@ -977,7 +1122,7 @@ template <class ELFT> | ... | @@ -977,7 +1122,7 @@ template <class ELFT> |
| 977 | static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats, | 1122 | static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats, |
| 978 | const lto::InputFile::Symbol &ObjSym, | 1123 | const lto::InputFile::Symbol &ObjSym, |
| 979 | BitcodeFile &F) { | 1124 | BitcodeFile &F) { |
| 980 | StringRef NameRef = Saver.save(ObjSym.getName()); | 1125 | StringRef Name = Saver.save(ObjSym.getName()); |
| 981 | uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL; | 1126 | uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL; |
| 982 | 1127 | ||
| 983 | uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE; | 1128 | uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE; |
| ... | @@ -986,20 +1131,20 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats, | ... | @@ -986,20 +1131,20 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats, |
| 986 | 1131 | ||
| 987 | int C = ObjSym.getComdatIndex(); | 1132 | int C = ObjSym.getComdatIndex(); |
| 988 | if (C != -1 && !KeptComdats[C]) | 1133 | if (C != -1 && !KeptComdats[C]) |
| 989 | return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type, | 1134 | return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type, |
| 990 | CanOmitFromDynSym, &F); | 1135 | CanOmitFromDynSym, &F); |
| 991 | 1136 | ||
| 992 | if (ObjSym.isUndefined()) | 1137 | if (ObjSym.isUndefined()) |
| 993 | return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type, | 1138 | return Symtab->addUndefined<ELFT>(Name, Binding, Visibility, Type, |
| 994 | CanOmitFromDynSym, &F); | 1139 | CanOmitFromDynSym, &F); |
| 995 | 1140 | ||
| 996 | if (ObjSym.isCommon()) | 1141 | if (ObjSym.isCommon()) |
| 997 | return Symtab->addCommon(NameRef, ObjSym.getCommonSize(), | 1142 | return Symtab->addCommon(Name, ObjSym.getCommonSize(), |
| 998 | ObjSym.getCommonAlignment(), Binding, Visibility, | 1143 | ObjSym.getCommonAlignment(), Binding, Visibility, |
| 999 | STT_OBJECT, F); | 1144 | STT_OBJECT, F); |
| 1000 | 1145 | ||
| 1001 | return Symtab->addBitcode(NameRef, Binding, Visibility, Type, | 1146 | return Symtab->addBitcode(Name, Binding, Visibility, Type, CanOmitFromDynSym, |
| 1002 | CanOmitFromDynSym, F); | 1147 | F); |
| 1003 | } | 1148 | } |
| 1004 | 1149 | ||
| 1005 | template <class ELFT> | 1150 | template <class ELFT> |
| ... | @@ -1034,8 +1179,8 @@ static ELFKind getELFKind(MemoryBufferRef MB) { | ... | @@ -1034,8 +1179,8 @@ static ELFKind getELFKind(MemoryBufferRef MB) { |
| 1034 | 1179 | ||
| 1035 | void BinaryFile::parse() { | 1180 | void BinaryFile::parse() { |
| 1036 | ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer()); | 1181 | ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer()); |
| 1037 | auto *Section = make<InputSection>(nullptr, SHF_ALLOC | SHF_WRITE, | 1182 | auto *Section = make<InputSection>(this, SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, |
| 1038 | SHT_PROGBITS, 8, Data, ".data"); | 1183 | 8, Data, ".data"); |
| 1039 | Sections.push_back(Section); | 1184 | Sections.push_back(Section); |
| 1040 | 1185 | ||
| 1041 | // For each input file foo that is embedded to a result as a binary | 1186 | // For each input file foo that is embedded to a result as a binary |
| ... | @@ -1055,11 +1200,6 @@ void BinaryFile::parse() { | ... | @@ -1055,11 +1200,6 @@ void BinaryFile::parse() { |
| 1055 | Data.size(), 0, STB_GLOBAL, nullptr, nullptr); | 1200 | Data.size(), 0, STB_GLOBAL, nullptr, nullptr); |
| 1056 | } | 1201 | } |
| 1057 | 1202 | ||
| 1058 | static bool isBitcode(MemoryBufferRef MB) { | ||
| 1059 | using namespace sys::fs; | ||
| 1060 | return identify_magic(MB.getBuffer()) == file_magic::bitcode; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName, | 1203 | InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName, |
| 1064 | uint64_t OffsetInArchive) { | 1204 | uint64_t OffsetInArchive) { |
| 1065 | if (isBitcode(MB)) | 1205 | if (isBitcode(MB)) |
| ... | @@ -1095,9 +1235,9 @@ InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) { | ... | @@ -1095,9 +1235,9 @@ InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) { |
| 1095 | } | 1235 | } |
| 1096 | 1236 | ||
| 1097 | MemoryBufferRef LazyObjFile::getBuffer() { | 1237 | MemoryBufferRef LazyObjFile::getBuffer() { |
| 1098 | if (Seen) | 1238 | if (AddedToLink) |
| 1099 | return MemoryBufferRef(); | 1239 | return MemoryBufferRef(); |
| 1100 | Seen = true; | 1240 | AddedToLink = true; |
| 1101 | return MB; | 1241 | return MB; |
| 1102 | } | 1242 | } |
| 1103 | 1243 | ||
| ... | @@ -1105,66 +1245,72 @@ InputFile *LazyObjFile::fetch() { | ... | @@ -1105,66 +1245,72 @@ InputFile *LazyObjFile::fetch() { |
| 1105 | MemoryBufferRef MBRef = getBuffer(); | 1245 | MemoryBufferRef MBRef = getBuffer(); |
| 1106 | if (MBRef.getBuffer().empty()) | 1246 | if (MBRef.getBuffer().empty()) |
| 1107 | return nullptr; | 1247 | return nullptr; |
| 1108 | return createObjectFile(MBRef, ArchiveName, OffsetInArchive); | 1248 | |
| 1249 | InputFile *File = createObjectFile(MBRef, ArchiveName, OffsetInArchive); | ||
| 1250 | File->GroupId = GroupId; | ||
| 1251 | return File; | ||
| 1109 | } | 1252 | } |
| 1110 | 1253 | ||
| 1111 | template <class ELFT> void LazyObjFile::parse() { | 1254 | template <class ELFT> void LazyObjFile::parse() { |
| 1112 | for (StringRef Sym : getSymbolNames()) | 1255 | // A lazy object file wraps either a bitcode file or an ELF file. |
| 1113 | Symtab->addLazyObject<ELFT>(Sym, *this); | 1256 | if (isBitcode(this->MB)) { |
| 1257 | std::unique_ptr<lto::InputFile> Obj = | ||
| 1258 | CHECK(lto::InputFile::create(this->MB), this); | ||
| 1259 | for (const lto::InputFile::Symbol &Sym : Obj->symbols()) | ||
| 1260 | if (!Sym.isUndefined()) | ||
| 1261 | Symtab->addLazyObject<ELFT>(Saver.save(Sym.getName()), *this); | ||
| 1262 | return; | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | switch (getELFKind(this->MB)) { | ||
| 1266 | case ELF32LEKind: | ||
| 1267 | addElfSymbols<ELF32LE>(); | ||
| 1268 | return; | ||
| 1269 | case ELF32BEKind: | ||
| 1270 | addElfSymbols<ELF32BE>(); | ||
| 1271 | return; | ||
| 1272 | case ELF64LEKind: | ||
| 1273 | addElfSymbols<ELF64LE>(); | ||
| 1274 | return; | ||
| 1275 | case ELF64BEKind: | ||
| 1276 | addElfSymbols<ELF64BE>(); | ||
| 1277 | return; | ||
| 1278 | default: | ||
| 1279 | llvm_unreachable("getELFKind"); | ||
| 1280 | } | ||
| 1114 | } | 1281 | } |
| 1115 | 1282 | ||
| 1116 | template <class ELFT> std::vector<StringRef> LazyObjFile::getElfSymbols() { | 1283 | template <class ELFT> void LazyObjFile::addElfSymbols() { |
| 1117 | typedef typename ELFT::Shdr Elf_Shdr; | 1284 | ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer())); |
| 1118 | typedef typename ELFT::Sym Elf_Sym; | 1285 | ArrayRef<typename ELFT::Shdr> Sections = CHECK(Obj.sections(), this); |
| 1119 | typedef typename ELFT::SymRange Elf_Sym_Range; | ||
| 1120 | 1286 | ||
| 1121 | ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(this->MB.getBuffer())); | 1287 | for (const typename ELFT::Shdr &Sec : Sections) { |
| 1122 | ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this); | ||
| 1123 | for (const Elf_Shdr &Sec : Sections) { | ||
| 1124 | if (Sec.sh_type != SHT_SYMTAB) | 1288 | if (Sec.sh_type != SHT_SYMTAB) |
| 1125 | continue; | 1289 | continue; |
| 1126 | 1290 | ||
| 1127 | Elf_Sym_Range Syms = CHECK(Obj.symbols(&Sec), this); | 1291 | typename ELFT::SymRange Syms = CHECK(Obj.symbols(&Sec), this); |
| 1128 | uint32_t FirstNonLocal = Sec.sh_info; | 1292 | uint32_t FirstGlobal = Sec.sh_info; |
| 1129 | StringRef StringTable = | 1293 | StringRef StringTable = |
| 1130 | CHECK(Obj.getStringTableForSymtab(Sec, Sections), this); | 1294 | CHECK(Obj.getStringTableForSymtab(Sec, Sections), this); |
| 1131 | std::vector<StringRef> V; | ||
| 1132 | 1295 | ||
| 1133 | for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal)) | 1296 | for (const typename ELFT::Sym &Sym : Syms.slice(FirstGlobal)) |
| 1134 | if (Sym.st_shndx != SHN_UNDEF) | 1297 | if (Sym.st_shndx != SHN_UNDEF) |
| 1135 | V.push_back(CHECK(Sym.getName(StringTable), this)); | 1298 | Symtab->addLazyObject<ELFT>(CHECK(Sym.getName(StringTable), this), |
| 1136 | return V; | 1299 | *this); |
| 1300 | return; | ||
| 1137 | } | 1301 | } |
| 1138 | return {}; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | std::vector<StringRef> LazyObjFile::getBitcodeSymbols() { | ||
| 1142 | std::unique_ptr<lto::InputFile> Obj = | ||
| 1143 | CHECK(lto::InputFile::create(this->MB), this); | ||
| 1144 | std::vector<StringRef> V; | ||
| 1145 | for (const lto::InputFile::Symbol &Sym : Obj->symbols()) | ||
| 1146 | if (!Sym.isUndefined()) | ||
| 1147 | V.push_back(Saver.save(Sym.getName())); | ||
| 1148 | return V; | ||
| 1149 | } | 1302 | } |
| 1150 | 1303 | ||
| 1151 | // Returns a vector of globally-visible defined symbol names. | 1304 | std::string elf::replaceThinLTOSuffix(StringRef Path) { |
| 1152 | std::vector<StringRef> LazyObjFile::getSymbolNames() { | 1305 | StringRef Suffix = Config->ThinLTOObjectSuffixReplace.first; |
| 1153 | if (isBitcode(this->MB)) | 1306 | StringRef Repl = Config->ThinLTOObjectSuffixReplace.second; |
| 1154 | return getBitcodeSymbols(); | ||
| 1155 | 1307 | ||
| 1156 | switch (getELFKind(this->MB)) { | 1308 | if (!Path.endswith(Suffix)) { |
| 1157 | case ELF32LEKind: | 1309 | error("-thinlto-object-suffix-replace=" + Suffix + ";" + Repl + |
| 1158 | return getElfSymbols<ELF32LE>(); | 1310 | " was given, but " + Path + " does not end with the suffix"); |
| 1159 | case ELF32BEKind: | 1311 | return ""; |
| 1160 | return getElfSymbols<ELF32BE>(); | ||
| 1161 | case ELF64LEKind: | ||
| 1162 | return getElfSymbols<ELF64LE>(); | ||
| 1163 | case ELF64BEKind: | ||
| 1164 | return getElfSymbols<ELF64BE>(); | ||
| 1165 | default: | ||
| 1166 | llvm_unreachable("getELFKind"); | ||
| 1167 | } | 1312 | } |
| 1313 | return (Path.drop_back(Suffix.size()) + Repl).str(); | ||
| 1168 | } | 1314 | } |
| 1169 | 1315 | ||
| 1170 | template void ArchiveFile::parse<ELF32LE>(); | 1316 | template void ArchiveFile::parse<ELF32LE>(); |
deps/lld/ELF/InputFiles.h+57-26| ... | @@ -12,22 +12,20 @@ | ... | @@ -12,22 +12,20 @@ |
| 12 | 12 | ||
| 13 | #include "Config.h" | 13 | #include "Config.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | 14 | #include "lld/Common/ErrorHandler.h" |
| 15 | |||
| 16 | #include "lld/Common/LLVM.h" | 15 | #include "lld/Common/LLVM.h" |
| 17 | #include "lld/Common/Reproduce.h" | 16 | #include "lld/Common/Reproduce.h" |
| 18 | #include "llvm/ADT/CachedHashString.h" | 17 | #include "llvm/ADT/CachedHashString.h" |
| 19 | #include "llvm/ADT/DenseSet.h" | 18 | #include "llvm/ADT/DenseSet.h" |
| 20 | #include "llvm/ADT/STLExtras.h" | 19 | #include "llvm/ADT/STLExtras.h" |
| 20 | #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" | ||
| 21 | #include "llvm/IR/Comdat.h" | 21 | #include "llvm/IR/Comdat.h" |
| 22 | #include "llvm/Object/Archive.h" | 22 | #include "llvm/Object/Archive.h" |
| 23 | #include "llvm/Object/ELF.h" | 23 | #include "llvm/Object/ELF.h" |
| 24 | #include "llvm/Object/IRObjectFile.h" | 24 | #include "llvm/Object/IRObjectFile.h" |
| 25 | #include "llvm/Support/Threading.h" | 25 | #include "llvm/Support/Threading.h" |
| 26 | |||
| 27 | #include <map> | 26 | #include <map> |
| 28 | 27 | ||
| 29 | namespace llvm { | 28 | namespace llvm { |
| 30 | class DWARFDebugLine; | ||
| 31 | class TarWriter; | 29 | class TarWriter; |
| 32 | struct DILineInfo; | 30 | struct DILineInfo; |
| 33 | namespace lto { | 31 | namespace lto { |
| ... | @@ -48,7 +46,6 @@ namespace elf { | ... | @@ -48,7 +46,6 @@ namespace elf { |
| 48 | 46 | ||
| 49 | using llvm::object::Archive; | 47 | using llvm::object::Archive; |
| 50 | 48 | ||
| 51 | class Lazy; | ||
| 52 | class Symbol; | 49 | class Symbol; |
| 53 | 50 | ||
| 54 | // If -reproduce option is given, all input files are written | 51 | // If -reproduce option is given, all input files are written |
| ... | @@ -90,15 +87,15 @@ public: | ... | @@ -90,15 +87,15 @@ public: |
| 90 | // Returns object file symbols. It is a runtime error to call this | 87 | // Returns object file symbols. It is a runtime error to call this |
| 91 | // function on files of other types. | 88 | // function on files of other types. |
| 92 | ArrayRef<Symbol *> getSymbols() { | 89 | ArrayRef<Symbol *> getSymbols() { |
| 93 | assert(FileKind == ObjKind || FileKind == BitcodeKind || | 90 | assert(FileKind == BinaryKind || FileKind == ObjKind || |
| 94 | FileKind == ArchiveKind); | 91 | FileKind == BitcodeKind); |
| 95 | return Symbols; | 92 | return Symbols; |
| 96 | } | 93 | } |
| 97 | 94 | ||
| 98 | // Filename of .a which contained this file. If this file was | 95 | // Filename of .a which contained this file. If this file was |
| 99 | // not in an archive file, it is the empty string. We use this | 96 | // not in an archive file, it is the empty string. We use this |
| 100 | // string for creating error messages. | 97 | // string for creating error messages. |
| 101 | StringRef ArchiveName; | 98 | std::string ArchiveName; |
| 102 | 99 | ||
| 103 | // If this is an architecture-specific file, the following members | 100 | // If this is an architecture-specific file, the following members |
| 104 | // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type. | 101 | // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type. |
| ... | @@ -112,6 +109,20 @@ public: | ... | @@ -112,6 +109,20 @@ public: |
| 112 | std::string getSrcMsg(const Symbol &Sym, InputSectionBase &Sec, | 109 | std::string getSrcMsg(const Symbol &Sym, InputSectionBase &Sec, |
| 113 | uint64_t Offset); | 110 | uint64_t Offset); |
| 114 | 111 | ||
| 112 | // True if this is an argument for --just-symbols. Usually false. | ||
| 113 | bool JustSymbols = false; | ||
| 114 | |||
| 115 | // GroupId is used for --warn-backrefs which is an optional error | ||
| 116 | // checking feature. All files within the same --{start,end}-group or | ||
| 117 | // --{start,end}-lib get the same group ID. Otherwise, each file gets a new | ||
| 118 | // group ID. For more info, see checkDependency() in SymbolTable.cpp. | ||
| 119 | uint32_t GroupId; | ||
| 120 | static bool IsInGroup; | ||
| 121 | static uint32_t NextGroupId; | ||
| 122 | |||
| 123 | // Index of MIPS GOT built for this file. | ||
| 124 | llvm::Optional<size_t> MipsGotIndex; | ||
| 125 | |||
| 115 | protected: | 126 | protected: |
| 116 | InputFile(Kind K, MemoryBufferRef M); | 127 | InputFile(Kind K, MemoryBufferRef M); |
| 117 | std::vector<InputSectionBase *> Sections; | 128 | std::vector<InputSectionBase *> Sections; |
| ... | @@ -144,7 +155,7 @@ public: | ... | @@ -144,7 +155,7 @@ public: |
| 144 | 155 | ||
| 145 | protected: | 156 | protected: |
| 146 | ArrayRef<Elf_Sym> ELFSyms; | 157 | ArrayRef<Elf_Sym> ELFSyms; |
| 147 | uint32_t FirstNonLocal = 0; | 158 | uint32_t FirstGlobal = 0; |
| 148 | ArrayRef<Elf_Word> SymtabSHNDX; | 159 | ArrayRef<Elf_Word> SymtabSHNDX; |
| 149 | StringRef StringTable; | 160 | StringRef StringTable; |
| 150 | void initSymtab(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr *Symtab); | 161 | void initSymtab(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr *Symtab); |
| ... | @@ -167,6 +178,7 @@ public: | ... | @@ -167,6 +178,7 @@ public: |
| 167 | static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } | 178 | static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } |
| 168 | 179 | ||
| 169 | ArrayRef<Symbol *> getLocalSymbols(); | 180 | ArrayRef<Symbol *> getLocalSymbols(); |
| 181 | ArrayRef<Symbol *> getGlobalSymbols(); | ||
| 170 | 182 | ||
| 171 | ObjFile(MemoryBufferRef M, StringRef ArchiveName); | 183 | ObjFile(MemoryBufferRef M, StringRef ArchiveName); |
| 172 | void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); | 184 | void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); |
| ... | @@ -182,9 +194,6 @@ public: | ... | @@ -182,9 +194,6 @@ public: |
| 182 | return getSymbol(SymIndex); | 194 | return getSymbol(SymIndex); |
| 183 | } | 195 | } |
| 184 | 196 | ||
| 185 | // Returns source line information for a given offset. | ||
| 186 | // If no information is available, returns "". | ||
| 187 | std::string getLineInfo(InputSectionBase *S, uint64_t Offset); | ||
| 188 | llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t); | 197 | llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t); |
| 189 | llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef Name); | 198 | llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef Name); |
| 190 | 199 | ||
| ... | @@ -198,10 +207,22 @@ public: | ... | @@ -198,10 +207,22 @@ public: |
| 198 | // symbol table. | 207 | // symbol table. |
| 199 | StringRef SourceFile; | 208 | StringRef SourceFile; |
| 200 | 209 | ||
| 210 | // True if the file defines functions compiled with | ||
| 211 | // -fsplit-stack. Usually false. | ||
| 212 | bool SplitStack = false; | ||
| 213 | |||
| 214 | // True if the file defines functions compiled with -fsplit-stack, | ||
| 215 | // but had one or more functions with the no_split_stack attribute. | ||
| 216 | bool SomeNoSplitStack = false; | ||
| 217 | |||
| 218 | // Pointer to this input file's .llvm_addrsig section, if it has one. | ||
| 219 | const Elf_Shdr *AddrsigSec = nullptr; | ||
| 220 | |||
| 201 | private: | 221 | private: |
| 202 | void | 222 | void |
| 203 | initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); | 223 | initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); |
| 204 | void initializeSymbols(); | 224 | void initializeSymbols(); |
| 225 | void initializeJustSymbols(); | ||
| 205 | void initializeDwarf(); | 226 | void initializeDwarf(); |
| 206 | InputSectionBase *getRelocTarget(const Elf_Shdr &Sec); | 227 | InputSectionBase *getRelocTarget(const Elf_Shdr &Sec); |
| 207 | InputSectionBase *createInputSection(const Elf_Shdr &Sec); | 228 | InputSectionBase *createInputSection(const Elf_Shdr &Sec); |
| ... | @@ -217,8 +238,14 @@ private: | ... | @@ -217,8 +238,14 @@ private: |
| 217 | // reporting. Linker may find reasonable number of errors in a | 238 | // reporting. Linker may find reasonable number of errors in a |
| 218 | // single object file, so we cache debugging information in order to | 239 | // single object file, so we cache debugging information in order to |
| 219 | // parse it only once for each object file we link. | 240 | // parse it only once for each object file we link. |
| 220 | std::unique_ptr<llvm::DWARFDebugLine> DwarfLine; | 241 | std::unique_ptr<llvm::DWARFContext> Dwarf; |
| 221 | llvm::DenseMap<StringRef, std::pair<unsigned, unsigned>> VariableLoc; | 242 | std::vector<const llvm::DWARFDebugLine::LineTable *> LineTables; |
| 243 | struct VarLoc { | ||
| 244 | const llvm::DWARFDebugLine::LineTable *LT; | ||
| 245 | unsigned File; | ||
| 246 | unsigned Line; | ||
| 247 | }; | ||
| 248 | llvm::DenseMap<StringRef, VarLoc> VariableLoc; | ||
| 222 | llvm::once_flag InitDwarfLine; | 249 | llvm::once_flag InitDwarfLine; |
| 223 | }; | 250 | }; |
| 224 | 251 | ||
| ... | @@ -242,13 +269,11 @@ public: | ... | @@ -242,13 +269,11 @@ public: |
| 242 | template <class ELFT> void parse(); | 269 | template <class ELFT> void parse(); |
| 243 | MemoryBufferRef getBuffer(); | 270 | MemoryBufferRef getBuffer(); |
| 244 | InputFile *fetch(); | 271 | InputFile *fetch(); |
| 272 | bool AddedToLink = false; | ||
| 245 | 273 | ||
| 246 | private: | 274 | private: |
| 247 | std::vector<StringRef> getSymbolNames(); | 275 | template <class ELFT> void addElfSymbols(); |
| 248 | template <class ELFT> std::vector<StringRef> getElfSymbols(); | ||
| 249 | std::vector<StringRef> getBitcodeSymbols(); | ||
| 250 | 276 | ||
| 251 | bool Seen = false; | ||
| 252 | uint64_t OffsetInArchive; | 277 | uint64_t OffsetInArchive; |
| 253 | }; | 278 | }; |
| 254 | 279 | ||
| ... | @@ -259,11 +284,11 @@ public: | ... | @@ -259,11 +284,11 @@ public: |
| 259 | static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } | 284 | static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } |
| 260 | template <class ELFT> void parse(); | 285 | template <class ELFT> void parse(); |
| 261 | 286 | ||
| 262 | // Returns a memory buffer for a given symbol and the offset in the archive | 287 | // Pulls out an object file that contains a definition for Sym and |
| 263 | // for the member. An empty memory buffer and an offset of zero | 288 | // returns it. If the same file was instantiated before, this |
| 264 | // is returned if we have already returned the same memory buffer. | 289 | // function returns a nullptr (so we don't instantiate the same file |
| 265 | // (So that we don't instantiate same members more than once.) | 290 | // more than once.) |
| 266 | std::pair<MemoryBufferRef, uint64_t> getMember(const Archive::Symbol *Sym); | 291 | InputFile *fetch(const Archive::Symbol &Sym); |
| 267 | 292 | ||
| 268 | private: | 293 | private: |
| 269 | std::unique_ptr<Archive> File; | 294 | std::unique_ptr<Archive> File; |
| ... | @@ -290,7 +315,6 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> { | ... | @@ -290,7 +315,6 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> { |
| 290 | typedef typename ELFT::Verdef Elf_Verdef; | 315 | typedef typename ELFT::Verdef Elf_Verdef; |
| 291 | typedef typename ELFT::Versym Elf_Versym; | 316 | typedef typename ELFT::Versym Elf_Versym; |
| 292 | 317 | ||
| 293 | std::vector<StringRef> Undefs; | ||
| 294 | const Elf_Shdr *VersymSec = nullptr; | 318 | const Elf_Shdr *VersymSec = nullptr; |
| 295 | const Elf_Shdr *VerdefSec = nullptr; | 319 | const Elf_Shdr *VerdefSec = nullptr; |
| 296 | 320 | ||
| ... | @@ -298,8 +322,6 @@ public: | ... | @@ -298,8 +322,6 @@ public: |
| 298 | std::vector<const Elf_Verdef *> Verdefs; | 322 | std::vector<const Elf_Verdef *> Verdefs; |
| 299 | std::string SoName; | 323 | std::string SoName; |
| 300 | 324 | ||
| 301 | llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; } | ||
| 302 | |||
| 303 | static bool classof(const InputFile *F) { | 325 | static bool classof(const InputFile *F) { |
| 304 | return F->kind() == Base::SharedKind; | 326 | return F->kind() == Base::SharedKind; |
| 305 | } | 327 | } |
| ... | @@ -308,7 +330,9 @@ public: | ... | @@ -308,7 +330,9 @@ public: |
| 308 | 330 | ||
| 309 | void parseSoName(); | 331 | void parseSoName(); |
| 310 | void parseRest(); | 332 | void parseRest(); |
| 311 | std::vector<const Elf_Verdef *> parseVerdefs(const Elf_Versym *&Versym); | 333 | uint32_t getAlignment(ArrayRef<Elf_Shdr> Sections, const Elf_Sym &Sym); |
| 334 | std::vector<const Elf_Verdef *> parseVerdefs(); | ||
| 335 | std::vector<uint32_t> parseVersyms(); | ||
| 312 | 336 | ||
| 313 | struct NeededVer { | 337 | struct NeededVer { |
| 314 | // The string table offset of the version name in the output file. | 338 | // The string table offset of the version name in the output file. |
| ... | @@ -337,8 +361,15 @@ InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "", | ... | @@ -337,8 +361,15 @@ InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "", |
| 337 | uint64_t OffsetInArchive = 0); | 361 | uint64_t OffsetInArchive = 0); |
| 338 | InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName); | 362 | InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName); |
| 339 | 363 | ||
| 364 | inline bool isBitcode(MemoryBufferRef MB) { | ||
| 365 | return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode; | ||
| 366 | } | ||
| 367 | |||
| 368 | std::string replaceThinLTOSuffix(StringRef Path); | ||
| 369 | |||
| 340 | extern std::vector<BinaryFile *> BinaryFiles; | 370 | extern std::vector<BinaryFile *> BinaryFiles; |
| 341 | extern std::vector<BitcodeFile *> BitcodeFiles; | 371 | extern std::vector<BitcodeFile *> BitcodeFiles; |
| 372 | extern std::vector<LazyObjFile *> LazyObjFiles; | ||
| 342 | extern std::vector<InputFile *> ObjectFiles; | 373 | extern std::vector<InputFile *> ObjectFiles; |
| 343 | extern std::vector<InputFile *> SharedFiles; | 374 | extern std::vector<InputFile *> SharedFiles; |
| 344 | 375 |
deps/lld/ELF/InputSection.cpp+327-151| ... | @@ -14,6 +14,7 @@ | ... | @@ -14,6 +14,7 @@ |
| 14 | #include "LinkerScript.h" | 14 | #include "LinkerScript.h" |
| 15 | #include "OutputSections.h" | 15 | #include "OutputSections.h" |
| 16 | #include "Relocations.h" | 16 | #include "Relocations.h" |
| 17 | #include "SymbolTable.h" | ||
| 17 | #include "Symbols.h" | 18 | #include "Symbols.h" |
| 18 | #include "SyntheticSections.h" | 19 | #include "SyntheticSections.h" |
| 19 | #include "Target.h" | 20 | #include "Target.h" |
| ... | @@ -26,7 +27,10 @@ | ... | @@ -26,7 +27,10 @@ |
| 26 | #include "llvm/Support/Endian.h" | 27 | #include "llvm/Support/Endian.h" |
| 27 | #include "llvm/Support/Threading.h" | 28 | #include "llvm/Support/Threading.h" |
| 28 | #include "llvm/Support/xxhash.h" | 29 | #include "llvm/Support/xxhash.h" |
| 30 | #include <algorithm> | ||
| 29 | #include <mutex> | 31 | #include <mutex> |
| 32 | #include <set> | ||
| 33 | #include <vector> | ||
| 30 | 34 | ||
| 31 | using namespace llvm; | 35 | using namespace llvm; |
| 32 | using namespace llvm::ELF; | 36 | using namespace llvm::ELF; |
| ... | @@ -45,32 +49,6 @@ std::string lld::toString(const InputSectionBase *Sec) { | ... | @@ -45,32 +49,6 @@ std::string lld::toString(const InputSectionBase *Sec) { |
| 45 | return (toString(Sec->File) + ":(" + Sec->Name + ")").str(); | 49 | return (toString(Sec->File) + ":(" + Sec->Name + ")").str(); |
| 46 | } | 50 | } |
| 47 | 51 | ||
| 48 | DenseMap<SectionBase *, int> elf::buildSectionOrder() { | ||
| 49 | DenseMap<SectionBase *, int> SectionOrder; | ||
| 50 | if (Config->SymbolOrderingFile.empty()) | ||
| 51 | return SectionOrder; | ||
| 52 | |||
| 53 | // Build a map from symbols to their priorities. Symbols that didn't | ||
| 54 | // appear in the symbol ordering file have the lowest priority 0. | ||
| 55 | // All explicitly mentioned symbols have negative (higher) priorities. | ||
| 56 | DenseMap<StringRef, int> SymbolOrder; | ||
| 57 | int Priority = -Config->SymbolOrderingFile.size(); | ||
| 58 | for (StringRef S : Config->SymbolOrderingFile) | ||
| 59 | SymbolOrder.insert({S, Priority++}); | ||
| 60 | |||
| 61 | // Build a map from sections to their priorities. | ||
| 62 | for (InputFile *File : ObjectFiles) { | ||
| 63 | for (Symbol *Sym : File->getSymbols()) { | ||
| 64 | auto *D = dyn_cast<Defined>(Sym); | ||
| 65 | if (!D || !D->Section) | ||
| 66 | continue; | ||
| 67 | int &Priority = SectionOrder[D->Section]; | ||
| 68 | Priority = std::min(Priority, SymbolOrder.lookup(D->getName())); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | return SectionOrder; | ||
| 72 | } | ||
| 73 | |||
| 74 | template <class ELFT> | 52 | template <class ELFT> |
| 75 | static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &File, | 53 | static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &File, |
| 76 | const typename ELFT::Shdr &Hdr) { | 54 | const typename ELFT::Shdr &Hdr) { |
| ... | @@ -168,12 +146,8 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const { | ... | @@ -168,12 +146,8 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const { |
| 168 | return Offset == uint64_t(-1) ? OS->Size : Offset; | 146 | return Offset == uint64_t(-1) ? OS->Size : Offset; |
| 169 | } | 147 | } |
| 170 | case Regular: | 148 | case Regular: |
| 171 | return cast<InputSection>(this)->OutSecOff + Offset; | 149 | case Synthetic: |
| 172 | case Synthetic: { | 150 | return cast<InputSection>(this)->getOffset(Offset); |
| 173 | auto *IS = cast<InputSection>(this); | ||
| 174 | // For synthetic sections we treat offset -1 as the end of the section. | ||
| 175 | return IS->OutSecOff + (Offset == uint64_t(-1) ? IS->getSize() : Offset); | ||
| 176 | } | ||
| 177 | case EHFrame: | 151 | case EHFrame: |
| 178 | // The file crtbeginT.o has relocations pointing to the start of an empty | 152 | // The file crtbeginT.o has relocations pointing to the start of an empty |
| 179 | // .eh_frame that is known to be the first in the link. It does that to | 153 | // .eh_frame that is known to be the first in the link. It does that to |
| ... | @@ -182,16 +156,21 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const { | ... | @@ -182,16 +156,21 @@ uint64_t SectionBase::getOffset(uint64_t Offset) const { |
| 182 | case Merge: | 156 | case Merge: |
| 183 | const MergeInputSection *MS = cast<MergeInputSection>(this); | 157 | const MergeInputSection *MS = cast<MergeInputSection>(this); |
| 184 | if (InputSection *IS = MS->getParent()) | 158 | if (InputSection *IS = MS->getParent()) |
| 185 | return IS->OutSecOff + MS->getOffset(Offset); | 159 | return IS->getOffset(MS->getParentOffset(Offset)); |
| 186 | return MS->getOffset(Offset); | 160 | return MS->getParentOffset(Offset); |
| 187 | } | 161 | } |
| 188 | llvm_unreachable("invalid section kind"); | 162 | llvm_unreachable("invalid section kind"); |
| 189 | } | 163 | } |
| 190 | 164 | ||
| 165 | uint64_t SectionBase::getVA(uint64_t Offset) const { | ||
| 166 | const OutputSection *Out = getOutputSection(); | ||
| 167 | return (Out ? Out->Addr : 0) + getOffset(Offset); | ||
| 168 | } | ||
| 169 | |||
| 191 | OutputSection *SectionBase::getOutputSection() { | 170 | OutputSection *SectionBase::getOutputSection() { |
| 192 | InputSection *Sec; | 171 | InputSection *Sec; |
| 193 | if (auto *IS = dyn_cast<InputSection>(this)) | 172 | if (auto *IS = dyn_cast<InputSection>(this)) |
| 194 | return IS->getParent(); | 173 | Sec = IS; |
| 195 | else if (auto *MS = dyn_cast<MergeInputSection>(this)) | 174 | else if (auto *MS = dyn_cast<MergeInputSection>(this)) |
| 196 | Sec = MS->getParent(); | 175 | Sec = MS->getParent(); |
| 197 | else if (auto *EH = dyn_cast<EhInputSection>(this)) | 176 | else if (auto *EH = dyn_cast<EhInputSection>(this)) |
| ... | @@ -201,34 +180,50 @@ OutputSection *SectionBase::getOutputSection() { | ... | @@ -201,34 +180,50 @@ OutputSection *SectionBase::getOutputSection() { |
| 201 | return Sec ? Sec->getParent() : nullptr; | 180 | return Sec ? Sec->getParent() : nullptr; |
| 202 | } | 181 | } |
| 203 | 182 | ||
| 204 | // Uncompress section contents if required. Note that this function | 183 | // Decompress section contents if required. Note that this function |
| 205 | // is called from parallelForEach, so it must be thread-safe. | 184 | // is called from parallelForEach, so it must be thread-safe. |
| 206 | void InputSectionBase::maybeUncompress() { | 185 | void InputSectionBase::maybeDecompress() { |
| 207 | if (UncompressBuf || !Decompressor::isCompressedELFSection(Flags, Name)) | 186 | if (DecompressBuf) |
| 187 | return; | ||
| 188 | if (!(Flags & SHF_COMPRESSED) && !Name.startswith(".zdebug")) | ||
| 208 | return; | 189 | return; |
| 209 | 190 | ||
| 191 | // Decompress a section. | ||
| 210 | Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data), | 192 | Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data), |
| 211 | Config->IsLE, Config->Is64)); | 193 | Config->IsLE, Config->Is64)); |
| 212 | 194 | ||
| 213 | size_t Size = Dec.getDecompressedSize(); | 195 | size_t Size = Dec.getDecompressedSize(); |
| 214 | UncompressBuf.reset(new char[Size]()); | 196 | DecompressBuf.reset(new char[Size + Name.size()]()); |
| 215 | if (Error E = Dec.decompress({UncompressBuf.get(), Size})) | 197 | if (Error E = Dec.decompress({DecompressBuf.get(), Size})) |
| 216 | fatal(toString(this) + | 198 | fatal(toString(this) + |
| 217 | ": decompress failed: " + llvm::toString(std::move(E))); | 199 | ": decompress failed: " + llvm::toString(std::move(E))); |
| 218 | 200 | ||
| 219 | Data = makeArrayRef((uint8_t *)UncompressBuf.get(), Size); | 201 | Data = makeArrayRef((uint8_t *)DecompressBuf.get(), Size); |
| 220 | Flags &= ~(uint64_t)SHF_COMPRESSED; | 202 | Flags &= ~(uint64_t)SHF_COMPRESSED; |
| 203 | |||
| 204 | // A section name may have been altered if compressed. If that's | ||
| 205 | // the case, restore the original name. (i.e. ".zdebug_" -> ".debug_") | ||
| 206 | if (Name.startswith(".zdebug")) { | ||
| 207 | DecompressBuf[Size] = '.'; | ||
| 208 | memcpy(&DecompressBuf[Size + 1], Name.data() + 2, Name.size() - 2); | ||
| 209 | Name = StringRef(&DecompressBuf[Size], Name.size() - 1); | ||
| 210 | } | ||
| 221 | } | 211 | } |
| 222 | 212 | ||
| 223 | InputSection *InputSectionBase::getLinkOrderDep() const { | 213 | InputSection *InputSectionBase::getLinkOrderDep() const { |
| 224 | if ((Flags & SHF_LINK_ORDER) && Link != 0) { | 214 | assert(Link); |
| 225 | InputSectionBase *L = File->getSections()[Link]; | 215 | assert(Flags & SHF_LINK_ORDER); |
| 226 | if (auto *IS = dyn_cast<InputSection>(L)) | 216 | return cast<InputSection>(File->getSections()[Link]); |
| 227 | return IS; | 217 | } |
| 228 | error("a section with SHF_LINK_ORDER should not refer a non-regular " | 218 | |
| 229 | "section: " + | 219 | // Find a function symbol that encloses a given location. |
| 230 | toString(L)); | 220 | template <class ELFT> |
| 231 | } | 221 | Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) { |
| 222 | for (Symbol *B : File->getSymbols()) | ||
| 223 | if (Defined *D = dyn_cast<Defined>(B)) | ||
| 224 | if (D->Section == this && D->Type == STT_FUNC && D->Value <= Offset && | ||
| 225 | Offset < D->Value + D->Size) | ||
| 226 | return D; | ||
| 232 | return nullptr; | 227 | return nullptr; |
| 233 | } | 228 | } |
| 234 | 229 | ||
| ... | @@ -241,9 +236,8 @@ std::string InputSectionBase::getLocation(uint64_t Offset) { | ... | @@ -241,9 +236,8 @@ std::string InputSectionBase::getLocation(uint64_t Offset) { |
| 241 | .str(); | 236 | .str(); |
| 242 | 237 | ||
| 243 | // First check if we can get desired values from debugging information. | 238 | // First check if we can get desired values from debugging information. |
| 244 | std::string LineInfo = getFile<ELFT>()->getLineInfo(this, Offset); | 239 | if (Optional<DILineInfo> Info = getFile<ELFT>()->getDILineInfo(this, Offset)) |
| 245 | if (!LineInfo.empty()) | 240 | return Info->FileName + ":" + std::to_string(Info->Line); |
| 246 | return LineInfo; | ||
| 247 | 241 | ||
| 248 | // File->SourceFile contains STT_FILE symbol that contains a | 242 | // File->SourceFile contains STT_FILE symbol that contains a |
| 249 | // source file name. If it's missing, we use an object file name. | 243 | // source file name. If it's missing, we use an object file name. |
| ... | @@ -251,12 +245,8 @@ std::string InputSectionBase::getLocation(uint64_t Offset) { | ... | @@ -251,12 +245,8 @@ std::string InputSectionBase::getLocation(uint64_t Offset) { |
| 251 | if (SrcFile.empty()) | 245 | if (SrcFile.empty()) |
| 252 | SrcFile = toString(File); | 246 | SrcFile = toString(File); |
| 253 | 247 | ||
| 254 | // Find a function symbol that encloses a given location. | 248 | if (Defined *D = getEnclosingFunction<ELFT>(Offset)) |
| 255 | for (Symbol *B : File->getSymbols()) | 249 | return SrcFile + ":(function " + toString(*D) + ")"; |
| 256 | if (auto *D = dyn_cast<Defined>(B)) | ||
| 257 | if (D->Section == this && D->Type == STT_FUNC) | ||
| 258 | if (D->Value <= Offset && Offset < D->Value + D->Size) | ||
| 259 | return SrcFile + ":(function " + toString(*D) + ")"; | ||
| 260 | 250 | ||
| 261 | // If there's no symbol, print out the offset in the section. | 251 | // If there's no symbol, print out the offset in the section. |
| 262 | return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str(); | 252 | return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str(); |
| ... | @@ -292,7 +282,7 @@ std::string InputSectionBase::getObjMsg(uint64_t Off) { | ... | @@ -292,7 +282,7 @@ std::string InputSectionBase::getObjMsg(uint64_t Off) { |
| 292 | 282 | ||
| 293 | std::string Archive; | 283 | std::string Archive; |
| 294 | if (!File->ArchiveName.empty()) | 284 | if (!File->ArchiveName.empty()) |
| 295 | Archive = (" in archive " + File->ArchiveName).str(); | 285 | Archive = " in archive " + File->ArchiveName; |
| 296 | 286 | ||
| 297 | // Find a symbol that encloses a given location. | 287 | // Find a symbol that encloses a given location. |
| 298 | for (Symbol *B : File->getSymbols()) | 288 | for (Symbol *B : File->getSymbols()) |
| ... | @@ -345,8 +335,9 @@ template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) { | ... | @@ -345,8 +335,9 @@ template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) { |
| 345 | *To++ = Sections[Idx]->getOutputSection()->SectionIndex; | 335 | *To++ = Sections[Idx]->getOutputSection()->SectionIndex; |
| 346 | } | 336 | } |
| 347 | 337 | ||
| 348 | InputSectionBase *InputSection::getRelocatedSection() { | 338 | InputSectionBase *InputSection::getRelocatedSection() const { |
| 349 | assert(Type == SHT_RELA || Type == SHT_REL); | 339 | if (!File || (Type != SHT_RELA && Type != SHT_REL)) |
| 340 | return nullptr; | ||
| 350 | ArrayRef<InputSectionBase *> Sections = File->getSections(); | 341 | ArrayRef<InputSectionBase *> Sections = File->getSections(); |
| 351 | return Sections[Info]; | 342 | return Sections[Info]; |
| 352 | } | 343 | } |
| ... | @@ -365,12 +356,12 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { | ... | @@ -365,12 +356,12 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 365 | auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf); | 356 | auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf); |
| 366 | Buf += sizeof(RelTy); | 357 | Buf += sizeof(RelTy); |
| 367 | 358 | ||
| 368 | if (Config->IsRela) | 359 | if (RelTy::IsRela) |
| 369 | P->r_addend = getAddend<ELFT>(Rel); | 360 | P->r_addend = getAddend<ELFT>(Rel); |
| 370 | 361 | ||
| 371 | // Output section VA is zero for -r, so r_offset is an offset within the | 362 | // Output section VA is zero for -r, so r_offset is an offset within the |
| 372 | // section, but for --emit-relocs it is an virtual address. | 363 | // section, but for --emit-relocs it is an virtual address. |
| 373 | P->r_offset = Sec->getOutputSection()->Addr + Sec->getOffset(Rel.r_offset); | 364 | P->r_offset = Sec->getVA(Rel.r_offset); |
| 374 | P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Sym), Type, | 365 | P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Sym), Type, |
| 375 | Config->IsMips64EL); | 366 | Config->IsMips64EL); |
| 376 | 367 | ||
| ... | @@ -395,17 +386,32 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { | ... | @@ -395,17 +386,32 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 395 | continue; | 386 | continue; |
| 396 | } | 387 | } |
| 397 | 388 | ||
| 398 | if (Config->IsRela) { | 389 | int64_t Addend = getAddend<ELFT>(Rel); |
| 399 | P->r_addend = | 390 | const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset; |
| 400 | Sym.getVA(getAddend<ELFT>(Rel)) - Section->getOutputSection()->Addr; | 391 | if (!RelTy::IsRela) |
| 401 | } else if (Config->Relocatable) { | 392 | Addend = Target->getImplicitAddend(BufLoc, Type); |
| 402 | const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset; | 393 | |
| 403 | Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, | 394 | if (Config->EMachine == EM_MIPS && Config->Relocatable && |
| 404 | Target->getImplicitAddend(BufLoc, Type), | 395 | Target->getRelExpr(Type, Sym, BufLoc) == R_MIPS_GOTREL) { |
| 405 | &Sym}); | 396 | // Some MIPS relocations depend on "gp" value. By default, |
| 397 | // this value has 0x7ff0 offset from a .got section. But | ||
| 398 | // relocatable files produced by a complier or a linker | ||
| 399 | // might redefine this default value and we must use it | ||
| 400 | // for a calculation of the relocation result. When we | ||
| 401 | // generate EXE or DSO it's trivial. Generating a relocatable | ||
| 402 | // output is more difficult case because the linker does | ||
| 403 | // not calculate relocations in this mode and loses | ||
| 404 | // individual "gp" values used by each input object file. | ||
| 405 | // As a workaround we add the "gp" value to the relocation | ||
| 406 | // addend and save it back to the file. | ||
| 407 | Addend += Sec->getFile<ELFT>()->MipsGp0; | ||
| 406 | } | 408 | } |
| 407 | } | ||
| 408 | 409 | ||
| 410 | if (RelTy::IsRela) | ||
| 411 | P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr; | ||
| 412 | else if (Config->Relocatable) | ||
| 413 | Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym}); | ||
| 414 | } | ||
| 409 | } | 415 | } |
| 410 | } | 416 | } |
| 411 | 417 | ||
| ... | @@ -481,14 +487,17 @@ static uint64_t getARMStaticBase(const Symbol &Sym) { | ... | @@ -481,14 +487,17 @@ static uint64_t getARMStaticBase(const Symbol &Sym) { |
| 481 | return OS->PtLoad->FirstSec->Addr; | 487 | return OS->PtLoad->FirstSec->Addr; |
| 482 | } | 488 | } |
| 483 | 489 | ||
| 484 | static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, | 490 | static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A, |
| 485 | const Symbol &Sym, RelExpr Expr) { | 491 | uint64_t P, const Symbol &Sym, RelExpr Expr) { |
| 486 | switch (Expr) { | 492 | switch (Expr) { |
| 487 | case R_INVALID: | 493 | case R_INVALID: |
| 488 | return 0; | 494 | return 0; |
| 489 | case R_ABS: | 495 | case R_ABS: |
| 496 | case R_RELAX_TLS_LD_TO_LE_ABS: | ||
| 490 | case R_RELAX_GOT_PC_NOPIC: | 497 | case R_RELAX_GOT_PC_NOPIC: |
| 491 | return Sym.getVA(A); | 498 | return Sym.getVA(A); |
| 499 | case R_ADDEND: | ||
| 500 | return A; | ||
| 492 | case R_ARM_SBREL: | 501 | case R_ARM_SBREL: |
| 493 | return Sym.getVA(A) - getARMStaticBase(Sym); | 502 | return Sym.getVA(A) - getARMStaticBase(Sym); |
| 494 | case R_GOT: | 503 | case R_GOT: |
| ... | @@ -505,7 +514,9 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, | ... | @@ -505,7 +514,9 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, |
| 505 | case R_GOT_FROM_END: | 514 | case R_GOT_FROM_END: |
| 506 | case R_RELAX_TLS_GD_TO_IE_END: | 515 | case R_RELAX_TLS_GD_TO_IE_END: |
| 507 | return Sym.getGotOffset() + A - InX::Got->getSize(); | 516 | return Sym.getGotOffset() + A - InX::Got->getSize(); |
| 517 | case R_TLSLD_GOT_OFF: | ||
| 508 | case R_GOT_OFF: | 518 | case R_GOT_OFF: |
| 519 | case R_RELAX_TLS_GD_TO_IE_GOT_OFF: | ||
| 509 | return Sym.getGotOffset() + A; | 520 | return Sym.getGotOffset() + A; |
| 510 | case R_GOT_PAGE_PC: | 521 | case R_GOT_PAGE_PC: |
| 511 | case R_RELAX_TLS_GD_TO_IE_PAGE_PC: | 522 | case R_RELAX_TLS_GD_TO_IE_PAGE_PC: |
| ... | @@ -516,11 +527,12 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, | ... | @@ -516,11 +527,12 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, |
| 516 | case R_HINT: | 527 | case R_HINT: |
| 517 | case R_NONE: | 528 | case R_NONE: |
| 518 | case R_TLSDESC_CALL: | 529 | case R_TLSDESC_CALL: |
| 530 | case R_TLSLD_HINT: | ||
| 519 | llvm_unreachable("cannot relocate hint relocs"); | 531 | llvm_unreachable("cannot relocate hint relocs"); |
| 520 | case R_MIPS_GOTREL: | 532 | case R_MIPS_GOTREL: |
| 521 | return Sym.getVA(A) - InX::MipsGot->getGp(); | 533 | return Sym.getVA(A) - InX::MipsGot->getGp(File); |
| 522 | case R_MIPS_GOT_GP: | 534 | case R_MIPS_GOT_GP: |
| 523 | return InX::MipsGot->getGp() + A; | 535 | return InX::MipsGot->getGp(File) + A; |
| 524 | case R_MIPS_GOT_GP_PC: { | 536 | case R_MIPS_GOT_GP_PC: { |
| 525 | // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target | 537 | // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target |
| 526 | // is _gp_disp symbol. In that case we should use the following | 538 | // is _gp_disp symbol. In that case we should use the following |
| ... | @@ -529,7 +541,7 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, | ... | @@ -529,7 +541,7 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, |
| 529 | // microMIPS variants of these relocations use slightly different | 541 | // microMIPS variants of these relocations use slightly different |
| 530 | // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi() | 542 | // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi() |
| 531 | // to correctly handle less-sugnificant bit of the microMIPS symbol. | 543 | // to correctly handle less-sugnificant bit of the microMIPS symbol. |
| 532 | uint64_t V = InX::MipsGot->getGp() + A - P; | 544 | uint64_t V = InX::MipsGot->getGp(File) + A - P; |
| 533 | if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16) | 545 | if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16) |
| 534 | V += 4; | 546 | V += 4; |
| 535 | if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16) | 547 | if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16) |
| ... | @@ -540,21 +552,23 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, | ... | @@ -540,21 +552,23 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, |
| 540 | // If relocation against MIPS local symbol requires GOT entry, this entry | 552 | // If relocation against MIPS local symbol requires GOT entry, this entry |
| 541 | // should be initialized by 'page address'. This address is high 16-bits | 553 | // should be initialized by 'page address'. This address is high 16-bits |
| 542 | // of sum the symbol's value and the addend. | 554 | // of sum the symbol's value and the addend. |
| 543 | return InX::MipsGot->getVA() + InX::MipsGot->getPageEntryOffset(Sym, A) - | 555 | return InX::MipsGot->getVA() + |
| 544 | InX::MipsGot->getGp(); | 556 | InX::MipsGot->getPageEntryOffset(File, Sym, A) - |
| 557 | InX::MipsGot->getGp(File); | ||
| 545 | case R_MIPS_GOT_OFF: | 558 | case R_MIPS_GOT_OFF: |
| 546 | case R_MIPS_GOT_OFF32: | 559 | case R_MIPS_GOT_OFF32: |
| 547 | // In case of MIPS if a GOT relocation has non-zero addend this addend | 560 | // In case of MIPS if a GOT relocation has non-zero addend this addend |
| 548 | // should be applied to the GOT entry content not to the GOT entry offset. | 561 | // should be applied to the GOT entry content not to the GOT entry offset. |
| 549 | // That is why we use separate expression type. | 562 | // That is why we use separate expression type. |
| 550 | return InX::MipsGot->getVA() + InX::MipsGot->getSymEntryOffset(Sym, A) - | 563 | return InX::MipsGot->getVA() + |
| 551 | InX::MipsGot->getGp(); | 564 | InX::MipsGot->getSymEntryOffset(File, Sym, A) - |
| 565 | InX::MipsGot->getGp(File); | ||
| 552 | case R_MIPS_TLSGD: | 566 | case R_MIPS_TLSGD: |
| 553 | return InX::MipsGot->getVA() + InX::MipsGot->getTlsOffset() + | 567 | return InX::MipsGot->getVA() + InX::MipsGot->getGlobalDynOffset(File, Sym) - |
| 554 | InX::MipsGot->getGlobalDynOffset(Sym) - InX::MipsGot->getGp(); | 568 | InX::MipsGot->getGp(File); |
| 555 | case R_MIPS_TLSLD: | 569 | case R_MIPS_TLSLD: |
| 556 | return InX::MipsGot->getVA() + InX::MipsGot->getTlsOffset() + | 570 | return InX::MipsGot->getVA() + InX::MipsGot->getTlsIndexOffset(File) - |
| 557 | InX::MipsGot->getTlsIndexOff() - InX::MipsGot->getGp(); | 571 | InX::MipsGot->getGp(File); |
| 558 | case R_PAGE_PC: | 572 | case R_PAGE_PC: |
| 559 | case R_PLT_PAGE_PC: { | 573 | case R_PLT_PAGE_PC: { |
| 560 | uint64_t Dest; | 574 | uint64_t Dest; |
| ... | @@ -583,25 +597,27 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, | ... | @@ -583,25 +597,27 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, |
| 583 | case R_PLT: | 597 | case R_PLT: |
| 584 | return Sym.getPltVA() + A; | 598 | return Sym.getPltVA() + A; |
| 585 | case R_PLT_PC: | 599 | case R_PLT_PC: |
| 586 | case R_PPC_PLT_OPD: | 600 | case R_PPC_CALL_PLT: |
| 587 | return Sym.getPltVA() + A - P; | 601 | return Sym.getPltVA() + A - P; |
| 588 | case R_PPC_OPD: { | 602 | case R_PPC_CALL: { |
| 589 | uint64_t SymVA = Sym.getVA(A); | 603 | uint64_t SymVA = Sym.getVA(A); |
| 590 | // If we have an undefined weak symbol, we might get here with a symbol | 604 | // If we have an undefined weak symbol, we might get here with a symbol |
| 591 | // address of zero. That could overflow, but the code must be unreachable, | 605 | // address of zero. That could overflow, but the code must be unreachable, |
| 592 | // so don't bother doing anything at all. | 606 | // so don't bother doing anything at all. |
| 593 | if (!SymVA) | 607 | if (!SymVA) |
| 594 | return 0; | 608 | return 0; |
| 595 | if (Out::Opd) { | 609 | |
| 596 | // If this is a local call, and we currently have the address of a | 610 | // PPC64 V2 ABI describes two entry points to a function. The global entry |
| 597 | // function-descriptor, get the underlying code address instead. | 611 | // point sets up the TOC base pointer. When calling a local function, the |
| 598 | uint64_t OpdStart = Out::Opd->Addr; | 612 | // call should branch to the local entry point rather than the global entry |
| 599 | uint64_t OpdEnd = OpdStart + Out::Opd->Size; | 613 | // point. Section 3.4.1 describes using the 3 most significant bits of the |
| 600 | bool InOpd = OpdStart <= SymVA && SymVA < OpdEnd; | 614 | // st_other field to find out how many instructions there are between the |
| 601 | if (InOpd) | 615 | // local and global entry point. |
| 602 | SymVA = read64be(&Out::OpdBuf[SymVA - OpdStart]); | 616 | uint8_t StOther = (Sym.StOther >> 5) & 7; |
| 603 | } | 617 | if (StOther == 0 || StOther == 1) |
| 604 | return SymVA - P; | 618 | return SymVA - P; |
| 619 | |||
| 620 | return SymVA - P + (1LL << StOther); | ||
| 605 | } | 621 | } |
| 606 | case R_PPC_TOC: | 622 | case R_PPC_TOC: |
| 607 | return getPPC64TocBase() + A; | 623 | return getPPC64TocBase() + A; |
| ... | @@ -618,25 +634,44 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, | ... | @@ -618,25 +634,44 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P, |
| 618 | // statically to zero. | 634 | // statically to zero. |
| 619 | if (Sym.isTls() && Sym.isUndefWeak()) | 635 | if (Sym.isTls() && Sym.isUndefWeak()) |
| 620 | return 0; | 636 | return 0; |
| 621 | if (Target->TcbSize) | 637 | |
| 638 | // For TLS variant 1 the TCB is a fixed size, whereas for TLS variant 2 the | ||
| 639 | // TCB is on unspecified size and content. Targets that implement variant 1 | ||
| 640 | // should set TcbSize. | ||
| 641 | if (Target->TcbSize) { | ||
| 642 | // PPC64 V2 ABI has the thread pointer offset into the middle of the TLS | ||
| 643 | // storage area by TlsTpOffset for efficient addressing TCB and up to | ||
| 644 | // 4KB – 8 B of other thread library information (placed before the TCB). | ||
| 645 | // Subtracting this offset will get the address of the first TLS block. | ||
| 646 | if (Target->TlsTpOffset) | ||
| 647 | return Sym.getVA(A) - Target->TlsTpOffset; | ||
| 648 | |||
| 649 | // If thread pointer is not offset into the middle, the first thing in the | ||
| 650 | // TLS storage area is the TCB. Add the TcbSize to get the address of the | ||
| 651 | // first TLS block. | ||
| 622 | return Sym.getVA(A) + alignTo(Target->TcbSize, Out::TlsPhdr->p_align); | 652 | return Sym.getVA(A) + alignTo(Target->TcbSize, Out::TlsPhdr->p_align); |
| 653 | } | ||
| 623 | return Sym.getVA(A) - Out::TlsPhdr->p_memsz; | 654 | return Sym.getVA(A) - Out::TlsPhdr->p_memsz; |
| 624 | case R_RELAX_TLS_GD_TO_LE_NEG: | 655 | case R_RELAX_TLS_GD_TO_LE_NEG: |
| 625 | case R_NEG_TLS: | 656 | case R_NEG_TLS: |
| 626 | return Out::TlsPhdr->p_memsz - Sym.getVA(A); | 657 | return Out::TlsPhdr->p_memsz - Sym.getVA(A); |
| 627 | case R_SIZE: | 658 | case R_SIZE: |
| 628 | return A; // Sym.getSize was already folded into the addend. | 659 | return Sym.getSize() + A; |
| 629 | case R_TLSDESC: | 660 | case R_TLSDESC: |
| 630 | return InX::Got->getGlobalDynAddr(Sym) + A; | 661 | return InX::Got->getGlobalDynAddr(Sym) + A; |
| 631 | case R_TLSDESC_PAGE: | 662 | case R_TLSDESC_PAGE: |
| 632 | return getAArch64Page(InX::Got->getGlobalDynAddr(Sym) + A) - | 663 | return getAArch64Page(InX::Got->getGlobalDynAddr(Sym) + A) - |
| 633 | getAArch64Page(P); | 664 | getAArch64Page(P); |
| 634 | case R_TLSGD: | 665 | case R_TLSGD_GOT: |
| 666 | return InX::Got->getGlobalDynOffset(Sym) + A; | ||
| 667 | case R_TLSGD_GOT_FROM_END: | ||
| 635 | return InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize(); | 668 | return InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize(); |
| 636 | case R_TLSGD_PC: | 669 | case R_TLSGD_PC: |
| 637 | return InX::Got->getGlobalDynAddr(Sym) + A - P; | 670 | return InX::Got->getGlobalDynAddr(Sym) + A - P; |
| 638 | case R_TLSLD: | 671 | case R_TLSLD_GOT_FROM_END: |
| 639 | return InX::Got->getTlsIndexOff() + A - InX::Got->getSize(); | 672 | return InX::Got->getTlsIndexOff() + A - InX::Got->getSize(); |
| 673 | case R_TLSLD_GOT: | ||
| 674 | return InX::Got->getTlsIndexOff() + A; | ||
| 640 | case R_TLSLD_PC: | 675 | case R_TLSLD_PC: |
| 641 | return InX::Got->getTlsIndexVA() + A - P; | 676 | return InX::Got->getTlsIndexVA() + A - P; |
| 642 | } | 677 | } |
| ... | @@ -656,6 +691,14 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { | ... | @@ -656,6 +691,14 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 656 | 691 | ||
| 657 | for (const RelTy &Rel : Rels) { | 692 | for (const RelTy &Rel : Rels) { |
| 658 | RelType Type = Rel.getType(Config->IsMips64EL); | 693 | RelType Type = Rel.getType(Config->IsMips64EL); |
| 694 | |||
| 695 | // GCC 8.0 or earlier have a bug that they emit R_386_GOTPC relocations | ||
| 696 | // against _GLOBAL_OFFSET_TABLE_ for .debug_info. The bug has been fixed | ||
| 697 | // in 2017 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630), but we | ||
| 698 | // need to keep this bug-compatible code for a while. | ||
| 699 | if (Config->EMachine == EM_386 && Type == R_386_GOTPC) | ||
| 700 | continue; | ||
| 701 | |||
| 659 | uint64_t Offset = getOffset(Rel.r_offset); | 702 | uint64_t Offset = getOffset(Rel.r_offset); |
| 660 | uint8_t *BufLoc = Buf + Offset; | 703 | uint8_t *BufLoc = Buf + Offset; |
| 661 | int64_t Addend = getAddend<ELFT>(Rel); | 704 | int64_t Addend = getAddend<ELFT>(Rel); |
| ... | @@ -666,17 +709,27 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { | ... | @@ -666,17 +709,27 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 666 | RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc); | 709 | RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc); |
| 667 | if (Expr == R_NONE) | 710 | if (Expr == R_NONE) |
| 668 | continue; | 711 | continue; |
| 712 | |||
| 669 | if (Expr != R_ABS) { | 713 | if (Expr != R_ABS) { |
| 670 | // GCC 8.0 or earlier have a bug that it emits R_386_GOTPC relocations | 714 | std::string Msg = getLocation<ELFT>(Offset) + |
| 671 | // against _GLOBAL_OFFSET_TABLE for .debug_info. The bug seems to have | 715 | ": has non-ABS relocation " + toString(Type) + |
| 672 | // been fixed in 2017: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630, | 716 | " against symbol '" + toString(Sym) + "'"; |
| 673 | // but we need to keep this bug-compatible code for a while. | 717 | if (Expr != R_PC) { |
| 674 | if (Config->EMachine == EM_386 && Type == R_386_GOTPC) | 718 | error(Msg); |
| 675 | continue; | 719 | return; |
| 720 | } | ||
| 676 | 721 | ||
| 677 | error(getLocation<ELFT>(Offset) + ": has non-ABS relocation " + | 722 | // If the control reaches here, we found a PC-relative relocation in a |
| 678 | toString(Type) + " against symbol '" + toString(Sym) + "'"); | 723 | // non-ALLOC section. Since non-ALLOC section is not loaded into memory |
| 679 | return; | 724 | // at runtime, the notion of PC-relative doesn't make sense here. So, |
| 725 | // this is a usage error. However, GNU linkers historically accept such | ||
| 726 | // relocations without any errors and relocate them as if they were at | ||
| 727 | // address 0. For bug-compatibilty, we accept them with warnings. We | ||
| 728 | // know Steel Bank Common Lisp as of 2018 have this bug. | ||
| 729 | warn(Msg); | ||
| 730 | Target->relocateOne(BufLoc, Type, | ||
| 731 | SignExtend64<Bits>(Sym.getVA(Addend - Offset))); | ||
| 732 | continue; | ||
| 680 | } | 733 | } |
| 681 | 734 | ||
| 682 | if (Sym.isTls() && !Out::TlsPhdr) | 735 | if (Sym.isTls() && !Out::TlsPhdr) |
| ... | @@ -686,15 +739,37 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { | ... | @@ -686,15 +739,37 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) { |
| 686 | } | 739 | } |
| 687 | } | 740 | } |
| 688 | 741 | ||
| 742 | // This is used when '-r' is given. | ||
| 743 | // For REL targets, InputSection::copyRelocations() may store artificial | ||
| 744 | // relocations aimed to update addends. They are handled in relocateAlloc() | ||
| 745 | // for allocatable sections, and this function does the same for | ||
| 746 | // non-allocatable sections, such as sections with debug information. | ||
| 747 | static void relocateNonAllocForRelocatable(InputSection *Sec, uint8_t *Buf) { | ||
| 748 | const unsigned Bits = Config->Is64 ? 64 : 32; | ||
| 749 | |||
| 750 | for (const Relocation &Rel : Sec->Relocations) { | ||
| 751 | // InputSection::copyRelocations() adds only R_ABS relocations. | ||
| 752 | assert(Rel.Expr == R_ABS); | ||
| 753 | uint8_t *BufLoc = Buf + Rel.Offset + Sec->OutSecOff; | ||
| 754 | uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits); | ||
| 755 | Target->relocateOne(BufLoc, Rel.Type, TargetVA); | ||
| 756 | } | ||
| 757 | } | ||
| 758 | |||
| 689 | template <class ELFT> | 759 | template <class ELFT> |
| 690 | void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) { | 760 | void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) { |
| 761 | if (Flags & SHF_EXECINSTR) | ||
| 762 | adjustSplitStackFunctionPrologues<ELFT>(Buf, BufEnd); | ||
| 763 | |||
| 691 | if (Flags & SHF_ALLOC) { | 764 | if (Flags & SHF_ALLOC) { |
| 692 | relocateAlloc(Buf, BufEnd); | 765 | relocateAlloc(Buf, BufEnd); |
| 693 | return; | 766 | return; |
| 694 | } | 767 | } |
| 695 | 768 | ||
| 696 | auto *Sec = cast<InputSection>(this); | 769 | auto *Sec = cast<InputSection>(this); |
| 697 | if (Sec->AreRelocsRela) | 770 | if (Config->Relocatable) |
| 771 | relocateNonAllocForRelocatable(Sec, Buf); | ||
| 772 | else if (Sec->AreRelocsRela) | ||
| 698 | Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>()); | 773 | Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>()); |
| 699 | else | 774 | else |
| 700 | Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>()); | 775 | Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>()); |
| ... | @@ -705,14 +780,17 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { | ... | @@ -705,14 +780,17 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { |
| 705 | const unsigned Bits = Config->Wordsize * 8; | 780 | const unsigned Bits = Config->Wordsize * 8; |
| 706 | 781 | ||
| 707 | for (const Relocation &Rel : Relocations) { | 782 | for (const Relocation &Rel : Relocations) { |
| 708 | uint64_t Offset = getOffset(Rel.Offset); | 783 | uint64_t Offset = Rel.Offset; |
| 784 | if (auto *Sec = dyn_cast<InputSection>(this)) | ||
| 785 | Offset += Sec->OutSecOff; | ||
| 709 | uint8_t *BufLoc = Buf + Offset; | 786 | uint8_t *BufLoc = Buf + Offset; |
| 710 | RelType Type = Rel.Type; | 787 | RelType Type = Rel.Type; |
| 711 | 788 | ||
| 712 | uint64_t AddrLoc = getOutputSection()->Addr + Offset; | 789 | uint64_t AddrLoc = getOutputSection()->Addr + Offset; |
| 713 | RelExpr Expr = Rel.Expr; | 790 | RelExpr Expr = Rel.Expr; |
| 714 | uint64_t TargetVA = SignExtend64( | 791 | uint64_t TargetVA = SignExtend64( |
| 715 | getRelocTargetVA(Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr), Bits); | 792 | getRelocTargetVA(File, Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr), |
| 793 | Bits); | ||
| 716 | 794 | ||
| 717 | switch (Expr) { | 795 | switch (Expr) { |
| 718 | case R_RELAX_GOT_PC: | 796 | case R_RELAX_GOT_PC: |
| ... | @@ -723,6 +801,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { | ... | @@ -723,6 +801,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { |
| 723 | Target->relaxTlsIeToLe(BufLoc, Type, TargetVA); | 801 | Target->relaxTlsIeToLe(BufLoc, Type, TargetVA); |
| 724 | break; | 802 | break; |
| 725 | case R_RELAX_TLS_LD_TO_LE: | 803 | case R_RELAX_TLS_LD_TO_LE: |
| 804 | case R_RELAX_TLS_LD_TO_LE_ABS: | ||
| 726 | Target->relaxTlsLdToLe(BufLoc, Type, TargetVA); | 805 | Target->relaxTlsLdToLe(BufLoc, Type, TargetVA); |
| 727 | break; | 806 | break; |
| 728 | case R_RELAX_TLS_GD_TO_LE: | 807 | case R_RELAX_TLS_GD_TO_LE: |
| ... | @@ -731,15 +810,28 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { | ... | @@ -731,15 +810,28 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { |
| 731 | break; | 810 | break; |
| 732 | case R_RELAX_TLS_GD_TO_IE: | 811 | case R_RELAX_TLS_GD_TO_IE: |
| 733 | case R_RELAX_TLS_GD_TO_IE_ABS: | 812 | case R_RELAX_TLS_GD_TO_IE_ABS: |
| 813 | case R_RELAX_TLS_GD_TO_IE_GOT_OFF: | ||
| 734 | case R_RELAX_TLS_GD_TO_IE_PAGE_PC: | 814 | case R_RELAX_TLS_GD_TO_IE_PAGE_PC: |
| 735 | case R_RELAX_TLS_GD_TO_IE_END: | 815 | case R_RELAX_TLS_GD_TO_IE_END: |
| 736 | Target->relaxTlsGdToIe(BufLoc, Type, TargetVA); | 816 | Target->relaxTlsGdToIe(BufLoc, Type, TargetVA); |
| 737 | break; | 817 | break; |
| 738 | case R_PPC_PLT_OPD: | 818 | case R_PPC_CALL: |
| 819 | // If this is a call to __tls_get_addr, it may be part of a TLS | ||
| 820 | // sequence that has been relaxed and turned into a nop. In this | ||
| 821 | // case, we don't want to handle it as a call. | ||
| 822 | if (read32(BufLoc) == 0x60000000) // nop | ||
| 823 | break; | ||
| 824 | |||
| 739 | // Patch a nop (0x60000000) to a ld. | 825 | // Patch a nop (0x60000000) to a ld. |
| 740 | if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == 0x60000000) | 826 | if (Rel.Sym->NeedsTocRestore) { |
| 741 | write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1) | 827 | if (BufLoc + 8 > BufEnd || read32(BufLoc + 4) != 0x60000000) { |
| 742 | LLVM_FALLTHROUGH; | 828 | error(getErrorLocation(BufLoc) + "call lacks nop, can't restore toc"); |
| 829 | break; | ||
| 830 | } | ||
| 831 | write32(BufLoc + 4, 0xe8410018); // ld %r2, 24(%r1) | ||
| 832 | } | ||
| 833 | Target->relocateOne(BufLoc, Type, TargetVA); | ||
| 834 | break; | ||
| 743 | default: | 835 | default: |
| 744 | Target->relocateOne(BufLoc, Type, TargetVA); | 836 | Target->relocateOne(BufLoc, Type, TargetVA); |
| 745 | break; | 837 | break; |
| ... | @@ -747,6 +839,101 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { | ... | @@ -747,6 +839,101 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { |
| 747 | } | 839 | } |
| 748 | } | 840 | } |
| 749 | 841 | ||
| 842 | // For each function-defining prologue, find any calls to __morestack, | ||
| 843 | // and replace them with calls to __morestack_non_split. | ||
| 844 | static void switchMorestackCallsToMorestackNonSplit( | ||
| 845 | DenseSet<Defined *> &Prologues, std::vector<Relocation *> &MorestackCalls) { | ||
| 846 | |||
| 847 | // If the target adjusted a function's prologue, all calls to | ||
| 848 | // __morestack inside that function should be switched to | ||
| 849 | // __morestack_non_split. | ||
| 850 | Symbol *MoreStackNonSplit = Symtab->find("__morestack_non_split"); | ||
| 851 | |||
| 852 | // Sort both collections to compare addresses efficiently. | ||
| 853 | llvm::sort(MorestackCalls.begin(), MorestackCalls.end(), | ||
| 854 | [](const Relocation *L, const Relocation *R) { | ||
| 855 | return L->Offset < R->Offset; | ||
| 856 | }); | ||
| 857 | std::vector<Defined *> Functions(Prologues.begin(), Prologues.end()); | ||
| 858 | llvm::sort( | ||
| 859 | Functions.begin(), Functions.end(), | ||
| 860 | [](const Defined *L, const Defined *R) { return L->Value < R->Value; }); | ||
| 861 | |||
| 862 | auto It = MorestackCalls.begin(); | ||
| 863 | for (Defined *F : Functions) { | ||
| 864 | // Find the first call to __morestack within the function. | ||
| 865 | while (It != MorestackCalls.end() && (*It)->Offset < F->Value) | ||
| 866 | ++It; | ||
| 867 | // Adjust all calls inside the function. | ||
| 868 | while (It != MorestackCalls.end() && (*It)->Offset < F->Value + F->Size) { | ||
| 869 | (*It)->Sym = MoreStackNonSplit; | ||
| 870 | ++It; | ||
| 871 | } | ||
| 872 | } | ||
| 873 | } | ||
| 874 | |||
| 875 | static bool enclosingPrologueAdjusted(uint64_t Offset, | ||
| 876 | const DenseSet<Defined *> &Prologues) { | ||
| 877 | for (Defined *F : Prologues) | ||
| 878 | if (F->Value <= Offset && Offset < F->Value + F->Size) | ||
| 879 | return true; | ||
| 880 | return false; | ||
| 881 | } | ||
| 882 | |||
| 883 | // If a function compiled for split stack calls a function not | ||
| 884 | // compiled for split stack, then the caller needs its prologue | ||
| 885 | // adjusted to ensure that the called function will have enough stack | ||
| 886 | // available. Find those functions, and adjust their prologues. | ||
| 887 | template <class ELFT> | ||
| 888 | void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf, | ||
| 889 | uint8_t *End) { | ||
| 890 | if (!getFile<ELFT>()->SplitStack) | ||
| 891 | return; | ||
| 892 | DenseSet<Defined *> AdjustedPrologues; | ||
| 893 | std::vector<Relocation *> MorestackCalls; | ||
| 894 | |||
| 895 | for (Relocation &Rel : Relocations) { | ||
| 896 | // Local symbols can't possibly be cross-calls, and should have been | ||
| 897 | // resolved long before this line. | ||
| 898 | if (Rel.Sym->isLocal()) | ||
| 899 | continue; | ||
| 900 | |||
| 901 | Defined *D = dyn_cast<Defined>(Rel.Sym); | ||
| 902 | // A reference to an undefined symbol was an error, and should not | ||
| 903 | // have gotten to this point. | ||
| 904 | if (!D) | ||
| 905 | continue; | ||
| 906 | |||
| 907 | // Ignore calls into the split-stack api. | ||
| 908 | if (D->getName().startswith("__morestack")) { | ||
| 909 | if (D->getName().equals("__morestack")) | ||
| 910 | MorestackCalls.push_back(&Rel); | ||
| 911 | continue; | ||
| 912 | } | ||
| 913 | |||
| 914 | // A relocation to non-function isn't relevant. Sometimes | ||
| 915 | // __morestack is not marked as a function, so this check comes | ||
| 916 | // after the name check. | ||
| 917 | if (D->Type != STT_FUNC) | ||
| 918 | continue; | ||
| 919 | |||
| 920 | if (enclosingPrologueAdjusted(Rel.Offset, AdjustedPrologues)) | ||
| 921 | continue; | ||
| 922 | |||
| 923 | if (Defined *F = getEnclosingFunction<ELFT>(Rel.Offset)) { | ||
| 924 | if (Target->adjustPrologueForCrossSplitStack(Buf + F->Value, End)) { | ||
| 925 | AdjustedPrologues.insert(F); | ||
| 926 | continue; | ||
| 927 | } | ||
| 928 | } | ||
| 929 | if (!getFile<ELFT>()->SomeNoSplitStack) | ||
| 930 | error("function call at " + getErrorLocation(Buf + Rel.Offset) + | ||
| 931 | "crosses a split-stack boundary, but unable " + | ||
| 932 | "to adjust the enclosing function's prologue"); | ||
| 933 | } | ||
| 934 | switchMorestackCallsToMorestackNonSplit(AdjustedPrologues, MorestackCalls); | ||
| 935 | } | ||
| 936 | |||
| 750 | template <class ELFT> void InputSection::writeTo(uint8_t *Buf) { | 937 | template <class ELFT> void InputSection::writeTo(uint8_t *Buf) { |
| 751 | if (Type == SHT_NOBITS) | 938 | if (Type == SHT_NOBITS) |
| 752 | return; | 939 | return; |
| ... | @@ -818,10 +1005,6 @@ static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels, | ... | @@ -818,10 +1005,6 @@ static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels, |
| 818 | // .eh_frame is a sequence of CIE or FDE records. | 1005 | // .eh_frame is a sequence of CIE or FDE records. |
| 819 | // This function splits an input section into records and returns them. | 1006 | // This function splits an input section into records and returns them. |
| 820 | template <class ELFT> void EhInputSection::split() { | 1007 | template <class ELFT> void EhInputSection::split() { |
| 821 | // Early exit if already split. | ||
| 822 | if (!Pieces.empty()) | ||
| 823 | return; | ||
| 824 | |||
| 825 | if (AreRelocsRela) | 1008 | if (AreRelocsRela) |
| 826 | split<ELFT>(relas<ELFT>()); | 1009 | split<ELFT>(relas<ELFT>()); |
| 827 | else | 1010 | else |
| ... | @@ -886,8 +1069,7 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data, | ... | @@ -886,8 +1069,7 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data, |
| 886 | bool IsAlloc = Flags & SHF_ALLOC; | 1069 | bool IsAlloc = Flags & SHF_ALLOC; |
| 887 | 1070 | ||
| 888 | for (size_t I = 0; I != Size; I += EntSize) | 1071 | for (size_t I = 0; I != Size; I += EntSize) |
| 889 | Pieces.emplace_back(I, xxHash64(toStringRef(Data.slice(I, EntSize))), | 1072 | Pieces.emplace_back(I, xxHash64(Data.slice(I, EntSize)), !IsAlloc); |
| 890 | !IsAlloc); | ||
| 891 | } | 1073 | } |
| 892 | 1074 | ||
| 893 | template <class ELFT> | 1075 | template <class ELFT> |
| ... | @@ -916,15 +1098,9 @@ void MergeInputSection::splitIntoPieces() { | ... | @@ -916,15 +1098,9 @@ void MergeInputSection::splitIntoPieces() { |
| 916 | else | 1098 | else |
| 917 | splitNonStrings(Data, Entsize); | 1099 | splitNonStrings(Data, Entsize); |
| 918 | 1100 | ||
| 919 | if (Config->GcSections && (Flags & SHF_ALLOC)) | 1101 | OffsetMap.reserve(Pieces.size()); |
| 920 | for (uint64_t Off : LiveOffsets) | 1102 | for (size_t I = 0, E = Pieces.size(); I != E; ++I) |
| 921 | getSectionPiece(Off)->Live = true; | 1103 | OffsetMap[Pieces[I].InputOff] = I; |
| 922 | } | ||
| 923 | |||
| 924 | // Do binary search to get a section piece at a given input offset. | ||
| 925 | SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) { | ||
| 926 | auto *This = static_cast<const MergeInputSection *>(this); | ||
| 927 | return const_cast<SectionPiece *>(This->getSectionPiece(Offset)); | ||
| 928 | } | 1104 | } |
| 929 | 1105 | ||
| 930 | template <class It, class T, class Compare> | 1106 | template <class It, class T, class Compare> |
| ... | @@ -940,32 +1116,34 @@ static It fastUpperBound(It First, It Last, const T &Value, Compare Comp) { | ... | @@ -940,32 +1116,34 @@ static It fastUpperBound(It First, It Last, const T &Value, Compare Comp) { |
| 940 | return Comp(Value, *First) ? First : First + 1; | 1116 | return Comp(Value, *First) ? First : First + 1; |
| 941 | } | 1117 | } |
| 942 | 1118 | ||
| 943 | const SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) const { | 1119 | // Do binary search to get a section piece at a given input offset. |
| 944 | if (Data.size() <= Offset) | 1120 | static SectionPiece *findSectionPiece(MergeInputSection *Sec, uint64_t Offset) { |
| 945 | fatal(toString(this) + ": entry is past the end of the section"); | 1121 | if (Sec->Data.size() <= Offset) |
| 1122 | fatal(toString(Sec) + ": entry is past the end of the section"); | ||
| 946 | 1123 | ||
| 947 | // Find the element this offset points to. | 1124 | // Find the element this offset points to. |
| 948 | auto I = fastUpperBound( | 1125 | auto I = fastUpperBound( |
| 949 | Pieces.begin(), Pieces.end(), Offset, | 1126 | Sec->Pieces.begin(), Sec->Pieces.end(), Offset, |
| 950 | [](const uint64_t &A, const SectionPiece &B) { return A < B.InputOff; }); | 1127 | [](const uint64_t &A, const SectionPiece &B) { return A < B.InputOff; }); |
| 951 | --I; | 1128 | --I; |
| 952 | return &*I; | 1129 | return &*I; |
| 953 | } | 1130 | } |
| 954 | 1131 | ||
| 1132 | SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) { | ||
| 1133 | // Find a piece starting at a given offset. | ||
| 1134 | auto It = OffsetMap.find(Offset); | ||
| 1135 | if (It != OffsetMap.end()) | ||
| 1136 | return &Pieces[It->second]; | ||
| 1137 | |||
| 1138 | // If Offset is not at beginning of a section piece, it is not in the map. | ||
| 1139 | // In that case we need to search from the original section piece vector. | ||
| 1140 | return findSectionPiece(this, Offset); | ||
| 1141 | } | ||
| 1142 | |||
| 955 | // Returns the offset in an output section for a given input offset. | 1143 | // Returns the offset in an output section for a given input offset. |
| 956 | // Because contents of a mergeable section is not contiguous in output, | 1144 | // Because contents of a mergeable section is not contiguous in output, |
| 957 | // it is not just an addition to a base output offset. | 1145 | // it is not just an addition to a base output offset. |
| 958 | uint64_t MergeInputSection::getOffset(uint64_t Offset) const { | 1146 | uint64_t MergeInputSection::getParentOffset(uint64_t Offset) const { |
| 959 | if (!Live) | ||
| 960 | return 0; | ||
| 961 | |||
| 962 | // Initialize OffsetMap lazily. | ||
| 963 | llvm::call_once(InitOffsetMap, [&] { | ||
| 964 | OffsetMap.reserve(Pieces.size()); | ||
| 965 | for (size_t I = 0; I < Pieces.size(); ++I) | ||
| 966 | OffsetMap[Pieces[I].InputOff] = I; | ||
| 967 | }); | ||
| 968 | |||
| 969 | // Find a string starting at a given offset. | 1147 | // Find a string starting at a given offset. |
| 970 | auto It = OffsetMap.find(Offset); | 1148 | auto It = OffsetMap.find(Offset); |
| 971 | if (It != OffsetMap.end()) | 1149 | if (It != OffsetMap.end()) |
| ... | @@ -973,10 +1151,8 @@ uint64_t MergeInputSection::getOffset(uint64_t Offset) const { | ... | @@ -973,10 +1151,8 @@ uint64_t MergeInputSection::getOffset(uint64_t Offset) const { |
| 973 | 1151 | ||
| 974 | // If Offset is not at beginning of a section piece, it is not in the map. | 1152 | // If Offset is not at beginning of a section piece, it is not in the map. |
| 975 | // In that case we need to search from the original section piece vector. | 1153 | // In that case we need to search from the original section piece vector. |
| 976 | const SectionPiece &Piece = *getSectionPiece(Offset); | 1154 | const SectionPiece &Piece = |
| 977 | if (!Piece.Live) | 1155 | *findSectionPiece(const_cast<MergeInputSection *>(this), Offset); |
| 978 | return 0; | ||
| 979 | |||
| 980 | uint64_t Addend = Offset - Piece.InputOff; | 1156 | uint64_t Addend = Offset - Piece.InputOff; |
| 981 | return Piece.OutputOff + Addend; | 1157 | return Piece.OutputOff + Addend; |
| 982 | } | 1158 | } |
deps/lld/ELF/InputSection.h+36-29| ... | @@ -18,8 +18,6 @@ | ... | @@ -18,8 +18,6 @@ |
| 18 | #include "llvm/ADT/DenseSet.h" | 18 | #include "llvm/ADT/DenseSet.h" |
| 19 | #include "llvm/ADT/TinyPtrVector.h" | 19 | #include "llvm/ADT/TinyPtrVector.h" |
| 20 | #include "llvm/Object/ELF.h" | 20 | #include "llvm/Object/ELF.h" |
| 21 | #include "llvm/Support/Threading.h" | ||
| 22 | #include <mutex> | ||
| 23 | 21 | ||
| 24 | namespace lld { | 22 | namespace lld { |
| 25 | namespace elf { | 23 | namespace elf { |
| ... | @@ -63,6 +61,9 @@ public: | ... | @@ -63,6 +61,9 @@ public: |
| 63 | 61 | ||
| 64 | unsigned Bss : 1; | 62 | unsigned Bss : 1; |
| 65 | 63 | ||
| 64 | // Set for sections that should not be folded by ICF. | ||
| 65 | unsigned KeepUnique : 1; | ||
| 66 | |||
| 66 | // These corresponds to the fields in Elf_Shdr. | 67 | // These corresponds to the fields in Elf_Shdr. |
| 67 | uint32_t Alignment; | 68 | uint32_t Alignment; |
| 68 | uint64_t Flags; | 69 | uint64_t Flags; |
| ... | @@ -80,13 +81,15 @@ public: | ... | @@ -80,13 +81,15 @@ public: |
| 80 | // section. | 81 | // section. |
| 81 | uint64_t getOffset(uint64_t Offset) const; | 82 | uint64_t getOffset(uint64_t Offset) const; |
| 82 | 83 | ||
| 84 | uint64_t getVA(uint64_t Offset = 0) const; | ||
| 85 | |||
| 83 | protected: | 86 | protected: |
| 84 | SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags, | 87 | SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags, |
| 85 | uint64_t Entsize, uint64_t Alignment, uint32_t Type, | 88 | uint64_t Entsize, uint64_t Alignment, uint32_t Type, |
| 86 | uint32_t Info, uint32_t Link) | 89 | uint32_t Info, uint32_t Link) |
| 87 | : Name(Name), Repl(this), SectionKind(SectionKind), Live(false), | 90 | : Name(Name), Repl(this), SectionKind(SectionKind), Live(false), |
| 88 | Bss(false), Alignment(Alignment), Flags(Flags), Entsize(Entsize), | 91 | Bss(false), KeepUnique(false), Alignment(Alignment), Flags(Flags), |
| 89 | Type(Type), Link(Link), Info(Info) {} | 92 | Entsize(Entsize), Type(Type), Link(Link), Info(Info) {} |
| 90 | }; | 93 | }; |
| 91 | 94 | ||
| 92 | // This corresponds to a section of an input file. | 95 | // This corresponds to a section of an input file. |
| ... | @@ -103,7 +106,7 @@ public: | ... | @@ -103,7 +106,7 @@ public: |
| 103 | 106 | ||
| 104 | static bool classof(const SectionBase *S) { return S->kind() != Output; } | 107 | static bool classof(const SectionBase *S) { return S->kind() != Output; } |
| 105 | 108 | ||
| 106 | // The file which contains this section. It's dynamic type is always | 109 | // The file which contains this section. Its dynamic type is always |
| 107 | // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as | 110 | // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as |
| 108 | // its static type. | 111 | // its static type. |
| 109 | InputFile *File; | 112 | InputFile *File; |
| ... | @@ -161,10 +164,15 @@ public: | ... | @@ -161,10 +164,15 @@ public: |
| 161 | 164 | ||
| 162 | InputSection *getLinkOrderDep() const; | 165 | InputSection *getLinkOrderDep() const; |
| 163 | 166 | ||
| 167 | // Get the function symbol that encloses this offset from within the | ||
| 168 | // section. | ||
| 169 | template <class ELFT> | ||
| 170 | Defined *getEnclosingFunction(uint64_t Offset); | ||
| 171 | |||
| 164 | // Compilers emit zlib-compressed debug sections if the -gz option | 172 | // Compilers emit zlib-compressed debug sections if the -gz option |
| 165 | // is given. This function checks if this section is compressed, and | 173 | // is given. This function checks if this section is compressed, and |
| 166 | // if so, decompress in memory. | 174 | // if so, decompress in memory. |
| 167 | void maybeUncompress(); | 175 | void maybeDecompress(); |
| 168 | 176 | ||
| 169 | // Returns a source location string. Used to construct an error message. | 177 | // Returns a source location string. Used to construct an error message. |
| 170 | template <class ELFT> std::string getLocation(uint64_t Offset); | 178 | template <class ELFT> std::string getLocation(uint64_t Offset); |
| ... | @@ -182,6 +190,15 @@ public: | ... | @@ -182,6 +190,15 @@ public: |
| 182 | // This vector contains such "cooked" relocations. | 190 | // This vector contains such "cooked" relocations. |
| 183 | std::vector<Relocation> Relocations; | 191 | std::vector<Relocation> Relocations; |
| 184 | 192 | ||
| 193 | // A function compiled with -fsplit-stack calling a function | ||
| 194 | // compiled without -fsplit-stack needs its prologue adjusted. Find | ||
| 195 | // such functions and adjust their prologues. This is very similar | ||
| 196 | // to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more | ||
| 197 | // information. | ||
| 198 | template <typename ELFT> | ||
| 199 | void adjustSplitStackFunctionPrologues(uint8_t *Buf, uint8_t *End); | ||
| 200 | |||
| 201 | |||
| 185 | template <typename T> llvm::ArrayRef<T> getDataAs() const { | 202 | template <typename T> llvm::ArrayRef<T> getDataAs() const { |
| 186 | size_t S = Data.size(); | 203 | size_t S = Data.size(); |
| 187 | assert(S % sizeof(T) == 0); | 204 | assert(S % sizeof(T) == 0); |
| ... | @@ -189,9 +206,9 @@ public: | ... | @@ -189,9 +206,9 @@ public: |
| 189 | } | 206 | } |
| 190 | 207 | ||
| 191 | private: | 208 | private: |
| 192 | // A pointer that owns uncompressed data if a section is compressed by zlib. | 209 | // A pointer that owns decompressed data if a section is compressed by zlib. |
| 193 | // Since the feature is not used often, this is usually a nullptr. | 210 | // Since the feature is not used often, this is usually a nullptr. |
| 194 | std::unique_ptr<char[]> UncompressBuf; | 211 | std::unique_ptr<char[]> DecompressBuf; |
| 195 | }; | 212 | }; |
| 196 | 213 | ||
| 197 | // SectionPiece represents a piece of splittable section contents. | 214 | // SectionPiece represents a piece of splittable section contents. |
| ... | @@ -200,7 +217,7 @@ private: | ... | @@ -200,7 +217,7 @@ private: |
| 200 | // be found by looking at the next one). | 217 | // be found by looking at the next one). |
| 201 | struct SectionPiece { | 218 | struct SectionPiece { |
| 202 | SectionPiece(size_t Off, uint32_t Hash, bool Live) | 219 | SectionPiece(size_t Off, uint32_t Hash, bool Live) |
| 203 | : InputOff(Off), Hash(Hash), OutputOff(-1), | 220 | : InputOff(Off), Hash(Hash), OutputOff(0), |
| 204 | Live(Live || !Config->GcSections) {} | 221 | Live(Live || !Config->GcSections) {} |
| 205 | 222 | ||
| 206 | uint32_t InputOff; | 223 | uint32_t InputOff; |
| ... | @@ -223,19 +240,14 @@ public: | ... | @@ -223,19 +240,14 @@ public: |
| 223 | static bool classof(const SectionBase *S) { return S->kind() == Merge; } | 240 | static bool classof(const SectionBase *S) { return S->kind() == Merge; } |
| 224 | void splitIntoPieces(); | 241 | void splitIntoPieces(); |
| 225 | 242 | ||
| 226 | // Mark the piece at a given offset live. Used by GC. | 243 | // Translate an offset in the input section to an offset in the parent |
| 227 | void markLiveAt(uint64_t Offset) { | 244 | // MergeSyntheticSection. |
| 228 | if (this->Flags & llvm::ELF::SHF_ALLOC) | 245 | uint64_t getParentOffset(uint64_t Offset) const; |
| 229 | LiveOffsets.insert(Offset); | ||
| 230 | } | ||
| 231 | |||
| 232 | // Translate an offset in the input section to an offset | ||
| 233 | // in the output section. | ||
| 234 | uint64_t getOffset(uint64_t Offset) const; | ||
| 235 | 246 | ||
| 236 | // Splittable sections are handled as a sequence of data | 247 | // Splittable sections are handled as a sequence of data |
| 237 | // rather than a single large blob of data. | 248 | // rather than a single large blob of data. |
| 238 | std::vector<SectionPiece> Pieces; | 249 | std::vector<SectionPiece> Pieces; |
| 250 | llvm::DenseMap<uint32_t, uint32_t> OffsetMap; | ||
| 239 | 251 | ||
| 240 | // Returns I'th piece's data. This function is very hot when | 252 | // Returns I'th piece's data. This function is very hot when |
| 241 | // string merging is enabled, so we want to inline. | 253 | // string merging is enabled, so we want to inline. |
| ... | @@ -249,18 +261,15 @@ public: | ... | @@ -249,18 +261,15 @@ public: |
| 249 | 261 | ||
| 250 | // Returns the SectionPiece at a given input section offset. | 262 | // Returns the SectionPiece at a given input section offset. |
| 251 | SectionPiece *getSectionPiece(uint64_t Offset); | 263 | SectionPiece *getSectionPiece(uint64_t Offset); |
| 252 | const SectionPiece *getSectionPiece(uint64_t Offset) const; | 264 | const SectionPiece *getSectionPiece(uint64_t Offset) const { |
| 265 | return const_cast<MergeInputSection *>(this)->getSectionPiece(Offset); | ||
| 266 | } | ||
| 253 | 267 | ||
| 254 | SyntheticSection *getParent() const; | 268 | SyntheticSection *getParent() const; |
| 255 | 269 | ||
| 256 | private: | 270 | private: |
| 257 | void splitStrings(ArrayRef<uint8_t> A, size_t Size); | 271 | void splitStrings(ArrayRef<uint8_t> A, size_t Size); |
| 258 | void splitNonStrings(ArrayRef<uint8_t> A, size_t Size); | 272 | void splitNonStrings(ArrayRef<uint8_t> A, size_t Size); |
| 259 | |||
| 260 | mutable llvm::DenseMap<uint32_t, uint32_t> OffsetMap; | ||
| 261 | mutable llvm::once_flag InitOffsetMap; | ||
| 262 | |||
| 263 | llvm::DenseSet<uint64_t> LiveOffsets; | ||
| 264 | }; | 273 | }; |
| 265 | 274 | ||
| 266 | struct EhSectionPiece { | 275 | struct EhSectionPiece { |
| ... | @@ -310,6 +319,8 @@ public: | ... | @@ -310,6 +319,8 @@ public: |
| 310 | // beginning of the output section. | 319 | // beginning of the output section. |
| 311 | template <class ELFT> void writeTo(uint8_t *Buf); | 320 | template <class ELFT> void writeTo(uint8_t *Buf); |
| 312 | 321 | ||
| 322 | uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; } | ||
| 323 | |||
| 313 | OutputSection *getParent() const; | 324 | OutputSection *getParent() const; |
| 314 | 325 | ||
| 315 | // This variable has two usages. Initially, it represents an index in the | 326 | // This variable has two usages. Initially, it represents an index in the |
| ... | @@ -320,7 +331,7 @@ public: | ... | @@ -320,7 +331,7 @@ public: |
| 320 | 331 | ||
| 321 | static bool classof(const SectionBase *S); | 332 | static bool classof(const SectionBase *S); |
| 322 | 333 | ||
| 323 | InputSectionBase *getRelocatedSection(); | 334 | InputSectionBase *getRelocatedSection() const; |
| 324 | 335 | ||
| 325 | template <class ELFT, class RelTy> | 336 | template <class ELFT, class RelTy> |
| 326 | void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels); | 337 | void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels); |
| ... | @@ -342,10 +353,6 @@ private: | ... | @@ -342,10 +353,6 @@ private: |
| 342 | 353 | ||
| 343 | // The list of all input sections. | 354 | // The list of all input sections. |
| 344 | extern std::vector<InputSectionBase *> InputSections; | 355 | extern std::vector<InputSectionBase *> InputSections; |
| 345 | |||
| 346 | // Builds section order for handling --symbol-ordering-file. | ||
| 347 | llvm::DenseMap<SectionBase *, int> buildSectionOrder(); | ||
| 348 | |||
| 349 | } // namespace elf | 356 | } // namespace elf |
| 350 | 357 | ||
| 351 | std::string toString(const elf::InputSectionBase *); | 358 | std::string toString(const elf::InputSectionBase *); |
deps/lld/ELF/LTO.cpp+145-69| ... | @@ -20,6 +20,8 @@ | ... | @@ -20,6 +20,8 @@ |
| 20 | #include "llvm/ADT/StringRef.h" | 20 | #include "llvm/ADT/StringRef.h" |
| 21 | #include "llvm/ADT/Twine.h" | 21 | #include "llvm/ADT/Twine.h" |
| 22 | #include "llvm/BinaryFormat/ELF.h" | 22 | #include "llvm/BinaryFormat/ELF.h" |
| 23 | #include "llvm/Bitcode/BitcodeReader.h" | ||
| 24 | #include "llvm/Bitcode/BitcodeWriter.h" | ||
| 23 | #include "llvm/IR/DiagnosticPrinter.h" | 25 | #include "llvm/IR/DiagnosticPrinter.h" |
| 24 | #include "llvm/LTO/Caching.h" | 26 | #include "llvm/LTO/Caching.h" |
| 25 | #include "llvm/LTO/Config.h" | 27 | #include "llvm/LTO/Config.h" |
| ... | @@ -29,7 +31,6 @@ | ... | @@ -29,7 +31,6 @@ |
| 29 | #include "llvm/Support/Error.h" | 31 | #include "llvm/Support/Error.h" |
| 30 | #include "llvm/Support/FileSystem.h" | 32 | #include "llvm/Support/FileSystem.h" |
| 31 | #include "llvm/Support/MemoryBuffer.h" | 33 | #include "llvm/Support/MemoryBuffer.h" |
| 32 | #include "llvm/Support/raw_ostream.h" | ||
| 33 | #include <algorithm> | 34 | #include <algorithm> |
| 34 | #include <cstddef> | 35 | #include <cstddef> |
| 35 | #include <memory> | 36 | #include <memory> |
| ... | @@ -44,70 +45,92 @@ using namespace llvm::ELF; | ... | @@ -44,70 +45,92 @@ using namespace llvm::ELF; |
| 44 | using namespace lld; | 45 | using namespace lld; |
| 45 | using namespace lld::elf; | 46 | using namespace lld::elf; |
| 46 | 47 | ||
| 47 | // This is for use when debugging LTO. | 48 | // Creates an empty file to store a list of object files for final |
| 48 | static void saveBuffer(StringRef Buffer, const Twine &Path) { | 49 | // linking of distributed ThinLTO. |
| 50 | static std::unique_ptr<raw_fd_ostream> openFile(StringRef File) { | ||
| 49 | std::error_code EC; | 51 | std::error_code EC; |
| 50 | raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); | 52 | auto Ret = |
| 51 | if (EC) | 53 | llvm::make_unique<raw_fd_ostream>(File, EC, sys::fs::OpenFlags::F_None); |
| 52 | error("cannot create " + Path + ": " + EC.message()); | 54 | if (EC) { |
| 53 | OS << Buffer; | 55 | error("cannot open " + File + ": " + EC.message()); |
| 54 | } | 56 | return nullptr; |
| 55 | 57 | } | |
| 56 | static void diagnosticHandler(const DiagnosticInfo &DI) { | 58 | return Ret; |
| 57 | SmallString<128> ErrStorage; | ||
| 58 | raw_svector_ostream OS(ErrStorage); | ||
| 59 | DiagnosticPrinterRawOStream DP(OS); | ||
| 60 | DI.print(DP); | ||
| 61 | warn(ErrStorage); | ||
| 62 | } | 59 | } |
| 63 | 60 | ||
| 64 | static void checkError(Error E) { | 61 | static std::string getThinLTOOutputFile(StringRef ModulePath) { |
| 65 | handleAllErrors(std::move(E), | 62 | return lto::getThinLTOOutputFile(ModulePath, |
| 66 | [&](ErrorInfoBase &EIB) { error(EIB.message()); }); | 63 | Config->ThinLTOPrefixReplace.first, |
| 64 | Config->ThinLTOPrefixReplace.second); | ||
| 67 | } | 65 | } |
| 68 | 66 | ||
| 69 | static std::unique_ptr<lto::LTO> createLTO() { | 67 | static lto::Config createConfig() { |
| 70 | lto::Config Conf; | 68 | lto::Config C; |
| 71 | 69 | ||
| 72 | // LLD supports the new relocations. | 70 | // LLD supports the new relocations. |
| 73 | Conf.Options = InitTargetOptionsFromCodeGenFlags(); | 71 | C.Options = InitTargetOptionsFromCodeGenFlags(); |
| 74 | Conf.Options.RelaxELFRelocations = true; | 72 | C.Options.RelaxELFRelocations = true; |
| 75 | 73 | ||
| 76 | // Always emit a section per function/datum with LTO. | 74 | // Always emit a section per function/datum with LTO. |
| 77 | Conf.Options.FunctionSections = true; | 75 | C.Options.FunctionSections = true; |
| 78 | Conf.Options.DataSections = true; | 76 | C.Options.DataSections = true; |
| 79 | 77 | ||
| 80 | if (Config->Relocatable) | 78 | if (Config->Relocatable) |
| 81 | Conf.RelocModel = None; | 79 | C.RelocModel = None; |
| 82 | else if (Config->Pic) | 80 | else if (Config->Pic) |
| 83 | Conf.RelocModel = Reloc::PIC_; | 81 | C.RelocModel = Reloc::PIC_; |
| 84 | else | 82 | else |
| 85 | Conf.RelocModel = Reloc::Static; | 83 | C.RelocModel = Reloc::Static; |
| 86 | Conf.CodeModel = GetCodeModelFromCMModel(); | 84 | |
| 87 | Conf.DisableVerify = Config->DisableVerify; | 85 | C.CodeModel = GetCodeModelFromCMModel(); |
| 88 | Conf.DiagHandler = diagnosticHandler; | 86 | C.DisableVerify = Config->DisableVerify; |
| 89 | Conf.OptLevel = Config->LTOO; | 87 | C.DiagHandler = diagnosticHandler; |
| 88 | C.OptLevel = Config->LTOO; | ||
| 89 | C.CPU = GetCPUStr(); | ||
| 90 | 90 | ||
| 91 | // Set up a custom pipeline if we've been asked to. | 91 | // Set up a custom pipeline if we've been asked to. |
| 92 | Conf.OptPipeline = Config->LTONewPmPasses; | 92 | C.OptPipeline = Config->LTONewPmPasses; |
| 93 | Conf.AAPipeline = Config->LTOAAPipeline; | 93 | C.AAPipeline = Config->LTOAAPipeline; |
| 94 | 94 | ||
| 95 | // Set up optimization remarks if we've been asked to. | 95 | // Set up optimization remarks if we've been asked to. |
| 96 | Conf.RemarksFilename = Config->OptRemarksFilename; | 96 | C.RemarksFilename = Config->OptRemarksFilename; |
| 97 | Conf.RemarksWithHotness = Config->OptRemarksWithHotness; | 97 | C.RemarksWithHotness = Config->OptRemarksWithHotness; |
| 98 | |||
| 99 | C.SampleProfile = Config->LTOSampleProfile; | ||
| 100 | C.UseNewPM = Config->LTONewPassManager; | ||
| 101 | C.DebugPassManager = Config->LTODebugPassManager; | ||
| 102 | C.DwoDir = Config->DwoDir; | ||
| 98 | 103 | ||
| 99 | if (Config->SaveTemps) | 104 | if (Config->SaveTemps) |
| 100 | checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".", | 105 | checkError(C.addSaveTemps(Config->OutputFile.str() + ".", |
| 101 | /*UseInputModulePath*/ true)); | 106 | /*UseInputModulePath*/ true)); |
| 107 | return C; | ||
| 108 | } | ||
| 102 | 109 | ||
| 110 | BitcodeCompiler::BitcodeCompiler() { | ||
| 111 | // Initialize LTOObj. | ||
| 103 | lto::ThinBackend Backend; | 112 | lto::ThinBackend Backend; |
| 104 | if (Config->ThinLTOJobs != -1u) | 113 | |
| 114 | if (Config->ThinLTOIndexOnly) { | ||
| 115 | StringRef Path = Config->ThinLTOIndexOnlyArg; | ||
| 116 | if (!Path.empty()) | ||
| 117 | IndexFile = openFile(Path); | ||
| 118 | |||
| 119 | auto OnIndexWrite = [&](const std::string &Identifier) { | ||
| 120 | ObjectToIndexFileState[Identifier] = true; | ||
| 121 | }; | ||
| 122 | |||
| 123 | Backend = lto::createWriteIndexesThinBackend( | ||
| 124 | Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second, | ||
| 125 | Config->ThinLTOEmitImportsFiles, IndexFile.get(), OnIndexWrite); | ||
| 126 | } else if (Config->ThinLTOJobs != -1U) { | ||
| 105 | Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs); | 127 | Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs); |
| 106 | return llvm::make_unique<lto::LTO>(std::move(Conf), Backend, | 128 | } |
| 107 | Config->LTOPartitions); | ||
| 108 | } | ||
| 109 | 129 | ||
| 110 | BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) { | 130 | LTOObj = llvm::make_unique<lto::LTO>(createConfig(), Backend, |
| 131 | Config->LTOPartitions); | ||
| 132 | |||
| 133 | // Initialize UsedStartStop. | ||
| 111 | for (Symbol *Sym : Symtab->getSymbols()) { | 134 | for (Symbol *Sym : Symtab->getSymbols()) { |
| 112 | StringRef Name = Sym->getName(); | 135 | StringRef Name = Sym->getName(); |
| 113 | for (StringRef Prefix : {"__start_", "__stop_"}) | 136 | for (StringRef Prefix : {"__start_", "__stop_"}) |
| ... | @@ -125,20 +148,20 @@ static void undefine(Symbol *S) { | ... | @@ -125,20 +148,20 @@ static void undefine(Symbol *S) { |
| 125 | 148 | ||
| 126 | void BitcodeCompiler::add(BitcodeFile &F) { | 149 | void BitcodeCompiler::add(BitcodeFile &F) { |
| 127 | lto::InputFile &Obj = *F.Obj; | 150 | lto::InputFile &Obj = *F.Obj; |
| 128 | unsigned SymNum = 0; | 151 | bool IsExec = !Config->Shared && !Config->Relocatable; |
| 129 | std::vector<Symbol *> Syms = F.getSymbols(); | ||
| 130 | std::vector<lto::SymbolResolution> Resols(Syms.size()); | ||
| 131 | 152 | ||
| 132 | DenseSet<StringRef> ScriptSymbols; | 153 | if (Config->ThinLTOIndexOnly) |
| 133 | for (BaseCommand *Base : Script->SectionCommands) | 154 | ObjectToIndexFileState.insert({Obj.getName(), false}); |
| 134 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) | 155 | |
| 135 | ScriptSymbols.insert(Cmd->Name); | 156 | ArrayRef<Symbol *> Syms = F.getSymbols(); |
| 157 | ArrayRef<lto::InputFile::Symbol> ObjSyms = Obj.symbols(); | ||
| 158 | std::vector<lto::SymbolResolution> Resols(Syms.size()); | ||
| 136 | 159 | ||
| 137 | // Provide a resolution to the LTO API for each symbol. | 160 | // Provide a resolution to the LTO API for each symbol. |
| 138 | for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { | 161 | for (size_t I = 0, E = Syms.size(); I != E; ++I) { |
| 139 | Symbol *Sym = Syms[SymNum]; | 162 | Symbol *Sym = Syms[I]; |
| 140 | lto::SymbolResolution &R = Resols[SymNum]; | 163 | const lto::InputFile::Symbol &ObjSym = ObjSyms[I]; |
| 141 | ++SymNum; | 164 | lto::SymbolResolution &R = Resols[I]; |
| 142 | 165 | ||
| 143 | // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile | 166 | // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile |
| 144 | // reports two symbols for module ASM defined. Without this check, lld | 167 | // reports two symbols for module ASM defined. Without this check, lld |
| ... | @@ -156,25 +179,46 @@ void BitcodeCompiler::add(BitcodeFile &F) { | ... | @@ -156,25 +179,46 @@ void BitcodeCompiler::add(BitcodeFile &F) { |
| 156 | R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || | 179 | R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || |
| 157 | (R.Prevailing && Sym->includeInDynsym()) || | 180 | (R.Prevailing && Sym->includeInDynsym()) || |
| 158 | UsedStartStop.count(ObjSym.getSectionName()); | 181 | UsedStartStop.count(ObjSym.getSectionName()); |
| 182 | const auto *DR = dyn_cast<Defined>(Sym); | ||
| 183 | R.FinalDefinitionInLinkageUnit = | ||
| 184 | (IsExec || Sym->Visibility != STV_DEFAULT) && DR && | ||
| 185 | // Skip absolute symbols from ELF objects, otherwise PC-rel relocations | ||
| 186 | // will be generated by for them, triggering linker errors. | ||
| 187 | // Symbol section is always null for bitcode symbols, hence the check | ||
| 188 | // for isElf(). Skip linker script defined symbols as well: they have | ||
| 189 | // no File defined. | ||
| 190 | !(DR->Section == nullptr && (!Sym->File || Sym->File->isElf())); | ||
| 191 | |||
| 159 | if (R.Prevailing) | 192 | if (R.Prevailing) |
| 160 | undefine(Sym); | 193 | undefine(Sym); |
| 161 | 194 | ||
| 162 | // We tell LTO to not apply interprocedural optimization for following | 195 | // We tell LTO to not apply interprocedural optimization for wrapped |
| 163 | // symbols because otherwise LTO would inline them while their values are | 196 | // (with --wrap) symbols because otherwise LTO would inline them while |
| 164 | // still not final: | 197 | // their values are still not final. |
| 165 | // 1) Aliased (with --defsym) or wrapped (with --wrap) symbols. | 198 | R.LinkerRedefined = !Sym->CanInline; |
| 166 | // 2) Symbols redefined in linker script. | ||
| 167 | R.LinkerRedefined = !Sym->CanInline || ScriptSymbols.count(Sym->getName()); | ||
| 168 | } | 199 | } |
| 169 | checkError(LTOObj->add(std::move(F.Obj), Resols)); | 200 | checkError(LTOObj->add(std::move(F.Obj), Resols)); |
| 170 | } | 201 | } |
| 171 | 202 | ||
| 203 | static void createEmptyIndex(StringRef ModulePath) { | ||
| 204 | std::string Path = replaceThinLTOSuffix(getThinLTOOutputFile(ModulePath)); | ||
| 205 | std::unique_ptr<raw_fd_ostream> OS = openFile(Path + ".thinlto.bc"); | ||
| 206 | if (!OS) | ||
| 207 | return; | ||
| 208 | |||
| 209 | ModuleSummaryIndex M(/*HaveGVs*/ false); | ||
| 210 | M.setSkipModuleByDistributedBackend(); | ||
| 211 | WriteIndexToFile(M, *OS); | ||
| 212 | |||
| 213 | if (Config->ThinLTOEmitImportsFiles) | ||
| 214 | openFile(Path + ".imports"); | ||
| 215 | } | ||
| 216 | |||
| 172 | // Merge all the bitcode files we have seen, codegen the result | 217 | // Merge all the bitcode files we have seen, codegen the result |
| 173 | // and return the resulting ObjectFile(s). | 218 | // and return the resulting ObjectFile(s). |
| 174 | std::vector<InputFile *> BitcodeCompiler::compile() { | 219 | std::vector<InputFile *> BitcodeCompiler::compile() { |
| 175 | std::vector<InputFile *> Ret; | ||
| 176 | unsigned MaxTasks = LTOObj->getMaxTasks(); | 220 | unsigned MaxTasks = LTOObj->getMaxTasks(); |
| 177 | Buff.resize(MaxTasks); | 221 | Buf.resize(MaxTasks); |
| 178 | Files.resize(MaxTasks); | 222 | Files.resize(MaxTasks); |
| 179 | 223 | ||
| 180 | // The --thinlto-cache-dir option specifies the path to a directory in which | 224 | // The --thinlto-cache-dir option specifies the path to a directory in which |
| ... | @@ -184,35 +228,67 @@ std::vector<InputFile *> BitcodeCompiler::compile() { | ... | @@ -184,35 +228,67 @@ std::vector<InputFile *> BitcodeCompiler::compile() { |
| 184 | if (!Config->ThinLTOCacheDir.empty()) | 228 | if (!Config->ThinLTOCacheDir.empty()) |
| 185 | Cache = check( | 229 | Cache = check( |
| 186 | lto::localCache(Config->ThinLTOCacheDir, | 230 | lto::localCache(Config->ThinLTOCacheDir, |
| 187 | [&](size_t Task, std::unique_ptr<MemoryBuffer> MB, | 231 | [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) { |
| 188 | StringRef Path) { Files[Task] = std::move(MB); })); | 232 | Files[Task] = std::move(MB); |
| 233 | })); | ||
| 189 | 234 | ||
| 190 | checkError(LTOObj->run( | 235 | checkError(LTOObj->run( |
| 191 | [&](size_t Task) { | 236 | [&](size_t Task) { |
| 192 | return llvm::make_unique<lto::NativeObjectStream>( | 237 | return llvm::make_unique<lto::NativeObjectStream>( |
| 193 | llvm::make_unique<raw_svector_ostream>(Buff[Task])); | 238 | llvm::make_unique<raw_svector_ostream>(Buf[Task])); |
| 194 | }, | 239 | }, |
| 195 | Cache)); | 240 | Cache)); |
| 196 | 241 | ||
| 242 | // Emit empty index files for non-indexed files | ||
| 243 | if (Config->ThinLTOIndexOnly) { | ||
| 244 | for (auto &Identifier : ObjectToIndexFileState) | ||
| 245 | if (!Identifier.getValue()) { | ||
| 246 | std::string Path = getThinLTOOutputFile(Identifier.getKey()); | ||
| 247 | openFile(Path + ".thinlto.bc"); | ||
| 248 | |||
| 249 | if (Config->ThinLTOEmitImportsFiles) | ||
| 250 | openFile(Path + ".imports"); | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | // If LazyObjFile has not been added to link, emit empty index files. | ||
| 255 | // This is needed because this is what GNU gold plugin does and we have a | ||
| 256 | // distributed build system that depends on that behavior. | ||
| 257 | if (Config->ThinLTOIndexOnly) { | ||
| 258 | for (LazyObjFile *F : LazyObjFiles) | ||
| 259 | if (!F->AddedToLink && isBitcode(F->MB)) | ||
| 260 | createEmptyIndex(F->getName()); | ||
| 261 | |||
| 262 | if (!Config->LTOObjPath.empty()) | ||
| 263 | saveBuffer(Buf[0], Config->LTOObjPath); | ||
| 264 | |||
| 265 | // ThinLTO with index only option is required to generate only the index | ||
| 266 | // files. After that, we exit from linker and ThinLTO backend runs in a | ||
| 267 | // distributed environment. | ||
| 268 | if (IndexFile) | ||
| 269 | IndexFile->close(); | ||
| 270 | return {}; | ||
| 271 | } | ||
| 272 | |||
| 197 | if (!Config->ThinLTOCacheDir.empty()) | 273 | if (!Config->ThinLTOCacheDir.empty()) |
| 198 | pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy); | 274 | pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy); |
| 199 | 275 | ||
| 276 | std::vector<InputFile *> Ret; | ||
| 200 | for (unsigned I = 0; I != MaxTasks; ++I) { | 277 | for (unsigned I = 0; I != MaxTasks; ++I) { |
| 201 | if (Buff[I].empty()) | 278 | if (Buf[I].empty()) |
| 202 | continue; | 279 | continue; |
| 203 | if (Config->SaveTemps) { | 280 | if (Config->SaveTemps) { |
| 204 | if (I == 0) | 281 | if (I == 0) |
| 205 | saveBuffer(Buff[I], Config->OutputFile + ".lto.o"); | 282 | saveBuffer(Buf[I], Config->OutputFile + ".lto.o"); |
| 206 | else | 283 | else |
| 207 | saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.o"); | 284 | saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o"); |
| 208 | } | 285 | } |
| 209 | InputFile *Obj = createObjectFile(MemoryBufferRef(Buff[I], "lto.tmp")); | 286 | InputFile *Obj = createObjectFile(MemoryBufferRef(Buf[I], "lto.tmp")); |
| 210 | Ret.push_back(Obj); | 287 | Ret.push_back(Obj); |
| 211 | } | 288 | } |
| 212 | 289 | ||
| 213 | for (std::unique_ptr<MemoryBuffer> &File : Files) | 290 | for (std::unique_ptr<MemoryBuffer> &File : Files) |
| 214 | if (File) | 291 | if (File) |
| 215 | Ret.push_back(createObjectFile(*File)); | 292 | Ret.push_back(createObjectFile(*File)); |
| 216 | |||
| 217 | return Ret; | 293 | return Ret; |
| 218 | } | 294 | } |
deps/lld/ELF/LTO.h+5-1| ... | @@ -24,6 +24,7 @@ | ... | @@ -24,6 +24,7 @@ |
| 24 | #include "lld/Common/LLVM.h" | 24 | #include "lld/Common/LLVM.h" |
| 25 | #include "llvm/ADT/DenseSet.h" | 25 | #include "llvm/ADT/DenseSet.h" |
| 26 | #include "llvm/ADT/SmallString.h" | 26 | #include "llvm/ADT/SmallString.h" |
| 27 | #include "llvm/Support/raw_ostream.h" | ||
| 27 | #include <memory> | 28 | #include <memory> |
| 28 | #include <vector> | 29 | #include <vector> |
| 29 | 30 | ||
| ... | @@ -38,6 +39,7 @@ namespace elf { | ... | @@ -38,6 +39,7 @@ namespace elf { |
| 38 | 39 | ||
| 39 | class BitcodeFile; | 40 | class BitcodeFile; |
| 40 | class InputFile; | 41 | class InputFile; |
| 42 | class LazyObjFile; | ||
| 41 | 43 | ||
| 42 | class BitcodeCompiler { | 44 | class BitcodeCompiler { |
| 43 | public: | 45 | public: |
| ... | @@ -49,9 +51,11 @@ public: | ... | @@ -49,9 +51,11 @@ public: |
| 49 | 51 | ||
| 50 | private: | 52 | private: |
| 51 | std::unique_ptr<llvm::lto::LTO> LTOObj; | 53 | std::unique_ptr<llvm::lto::LTO> LTOObj; |
| 52 | std::vector<SmallString<0>> Buff; | 54 | std::vector<SmallString<0>> Buf; |
| 53 | std::vector<std::unique_ptr<MemoryBuffer>> Files; | 55 | std::vector<std::unique_ptr<MemoryBuffer>> Files; |
| 54 | llvm::DenseSet<StringRef> UsedStartStop; | 56 | llvm::DenseSet<StringRef> UsedStartStop; |
| 57 | std::unique_ptr<llvm::raw_fd_ostream> IndexFile; | ||
| 58 | llvm::StringMap<bool> ObjectToIndexFileState; | ||
| 55 | }; | 59 | }; |
| 56 | } // namespace elf | 60 | } // namespace elf |
| 57 | } // namespace lld | 61 | } // namespace lld |
deps/lld/ELF/LinkerScript.cpp+248-125| ... | @@ -15,13 +15,13 @@ | ... | @@ -15,13 +15,13 @@ |
| 15 | #include "Config.h" | 15 | #include "Config.h" |
| 16 | #include "InputSection.h" | 16 | #include "InputSection.h" |
| 17 | #include "OutputSections.h" | 17 | #include "OutputSections.h" |
| 18 | #include "Strings.h" | ||
| 19 | #include "SymbolTable.h" | 18 | #include "SymbolTable.h" |
| 20 | #include "Symbols.h" | 19 | #include "Symbols.h" |
| 21 | #include "SyntheticSections.h" | 20 | #include "SyntheticSections.h" |
| 22 | #include "Target.h" | 21 | #include "Target.h" |
| 23 | #include "Writer.h" | 22 | #include "Writer.h" |
| 24 | #include "lld/Common/Memory.h" | 23 | #include "lld/Common/Memory.h" |
| 24 | #include "lld/Common/Strings.h" | ||
| 25 | #include "lld/Common/Threads.h" | 25 | #include "lld/Common/Threads.h" |
| 26 | #include "llvm/ADT/STLExtras.h" | 26 | #include "llvm/ADT/STLExtras.h" |
| 27 | #include "llvm/ADT/StringRef.h" | 27 | #include "llvm/ADT/StringRef.h" |
| ... | @@ -74,7 +74,7 @@ uint64_t ExprValue::getSectionOffset() const { | ... | @@ -74,7 +74,7 @@ uint64_t ExprValue::getSectionOffset() const { |
| 74 | // If the alignment is trivial, we don't have to compute the full | 74 | // If the alignment is trivial, we don't have to compute the full |
| 75 | // value to know the offset. This allows this function to succeed in | 75 | // value to know the offset. This allows this function to succeed in |
| 76 | // cases where the output section is not yet known. | 76 | // cases where the output section is not yet known. |
| 77 | if (Alignment == 1) | 77 | if (Alignment == 1 && (!Sec || !Sec->getOutputSection())) |
| 78 | return Val; | 78 | return Val; |
| 79 | return getValue() - getSecAddr(); | 79 | return getValue() - getSecAddr(); |
| 80 | } | 80 | } |
| ... | @@ -102,28 +102,67 @@ OutputSection *LinkerScript::getOrCreateOutputSection(StringRef Name) { | ... | @@ -102,28 +102,67 @@ OutputSection *LinkerScript::getOrCreateOutputSection(StringRef Name) { |
| 102 | return CmdRef; | 102 | return CmdRef; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | // Expands the memory region by the specified size. | ||
| 106 | static 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"); | ||
| 113 | } | ||
| 114 | |||
| 115 | void LinkerScript::expandMemoryRegions(uint64_t Size) { | ||
| 116 | if (Ctx->MemRegion) | ||
| 117 | expandMemoryRegion(Ctx->MemRegion, Size, Ctx->MemRegion->Name, | ||
| 118 | Ctx->OutSec->Name); | ||
| 119 | if (Ctx->LMARegion) | ||
| 120 | expandMemoryRegion(Ctx->LMARegion, Size, Ctx->LMARegion->Name, | ||
| 121 | Ctx->OutSec->Name); | ||
| 122 | } | ||
| 123 | |||
| 124 | void LinkerScript::expandOutputSection(uint64_t Size) { | ||
| 125 | Ctx->OutSec->Size += Size; | ||
| 126 | expandMemoryRegions(Size); | ||
| 127 | } | ||
| 128 | |||
| 105 | void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) { | 129 | void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) { |
| 106 | uint64_t Val = E().getValue(); | 130 | uint64_t Val = E().getValue(); |
| 107 | if (Val < Dot && InSec) | 131 | if (Val < Dot && InSec) |
| 108 | error(Loc + ": unable to move location counter backward for: " + | 132 | error(Loc + ": unable to move location counter backward for: " + |
| 109 | Ctx->OutSec->Name); | 133 | Ctx->OutSec->Name); |
| 110 | Dot = Val; | ||
| 111 | 134 | ||
| 112 | // Update to location counter means update to section size. | 135 | // Update to location counter means update to section size. |
| 113 | if (InSec) | 136 | if (InSec) |
| 114 | Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr; | 137 | expandOutputSection(Val - Dot); |
| 138 | else | ||
| 139 | expandMemoryRegions(Val - Dot); | ||
| 140 | |||
| 141 | Dot = Val; | ||
| 115 | } | 142 | } |
| 116 | 143 | ||
| 117 | // This function is called from processSectionCommands, | 144 | // Used for handling linker symbol assignments, for both finalizing |
| 118 | // while we are fixing the output section layout. | 145 | // their values and doing early declarations. Returns true if symbol |
| 119 | void LinkerScript::addSymbol(SymbolAssignment *Cmd) { | 146 | // should be defined from linker script. |
| 147 | static bool shouldDefineSym(SymbolAssignment *Cmd) { | ||
| 120 | if (Cmd->Name == ".") | 148 | if (Cmd->Name == ".") |
| 121 | return; | 149 | return false; |
| 150 | |||
| 151 | if (!Cmd->Provide) | ||
| 152 | return true; | ||
| 122 | 153 | ||
| 123 | // If a symbol was in PROVIDE(), we need to define it only when | 154 | // If a symbol was in PROVIDE(), we need to define it only |
| 124 | // it is a referenced undefined symbol. | 155 | // when it is a referenced undefined symbol. |
| 125 | Symbol *B = Symtab->find(Cmd->Name); | 156 | Symbol *B = Symtab->find(Cmd->Name); |
| 126 | if (Cmd->Provide && (!B || B->isDefined())) | 157 | if (B && !B->isDefined()) |
| 158 | return true; | ||
| 159 | return false; | ||
| 160 | } | ||
| 161 | |||
| 162 | // This function is called from processSectionCommands, | ||
| 163 | // while we are fixing the output section layout. | ||
| 164 | void LinkerScript::addSymbol(SymbolAssignment *Cmd) { | ||
| 165 | if (!shouldDefineSym(Cmd)) | ||
| 127 | return; | 166 | return; |
| 128 | 167 | ||
| 129 | // Define a symbol. | 168 | // Define a symbol. |
| ... | @@ -153,6 +192,76 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) { | ... | @@ -153,6 +192,76 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) { |
| 153 | Cmd->Sym = cast<Defined>(Sym); | 192 | Cmd->Sym = cast<Defined>(Sym); |
| 154 | } | 193 | } |
| 155 | 194 | ||
| 195 | // This function is called from LinkerScript::declareSymbols. | ||
| 196 | // It creates a placeholder symbol if needed. | ||
| 197 | static void declareSymbol(SymbolAssignment *Cmd) { | ||
| 198 | if (!shouldDefineSym(Cmd)) | ||
| 199 | return; | ||
| 200 | |||
| 201 | // We can't calculate final value right now. | ||
| 202 | Symbol *Sym; | ||
| 203 | uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; | ||
| 204 | std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility, | ||
| 205 | /*CanOmitFromDynSym*/ false, | ||
| 206 | /*File*/ nullptr); | ||
| 207 | replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility, | ||
| 208 | STT_NOTYPE, 0, 0, nullptr); | ||
| 209 | Cmd->Sym = cast<Defined>(Sym); | ||
| 210 | Cmd->Provide = false; | ||
| 211 | } | ||
| 212 | |||
| 213 | // This method is used to handle INSERT AFTER statement. Here we rebuild | ||
| 214 | // the list of script commands to mix sections inserted into. | ||
| 215 | void LinkerScript::processInsertCommands() { | ||
| 216 | std::vector<BaseCommand *> V; | ||
| 217 | auto Insert = [&](std::vector<BaseCommand *> &From) { | ||
| 218 | V.insert(V.end(), From.begin(), From.end()); | ||
| 219 | From.clear(); | ||
| 220 | }; | ||
| 221 | |||
| 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]); | ||
| 227 | continue; | ||
| 228 | } | ||
| 229 | V.push_back(Base); | ||
| 230 | } | ||
| 231 | |||
| 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 + | ||
| 236 | ": section not defined"); | ||
| 237 | |||
| 238 | SectionCommands = std::move(V); | ||
| 239 | } | ||
| 240 | |||
| 241 | // Symbols defined in script should not be inlined by LTO. At the same time | ||
| 242 | // we don't know their final values until late stages of link. Here we scan | ||
| 243 | // over symbol assignment commands and create placeholder symbols if needed. | ||
| 244 | void LinkerScript::declareSymbols() { | ||
| 245 | assert(!Ctx); | ||
| 246 | for (BaseCommand *Base : SectionCommands) { | ||
| 247 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { | ||
| 248 | declareSymbol(Cmd); | ||
| 249 | continue; | ||
| 250 | } | ||
| 251 | |||
| 252 | // If the output section directive has constraints, | ||
| 253 | // we can't say for sure if it is going to be included or not. | ||
| 254 | // Skip such sections for now. Improve the checks if we ever | ||
| 255 | // need symbols from that sections to be declared early. | ||
| 256 | auto *Sec = cast<OutputSection>(Base); | ||
| 257 | if (Sec->Constraint != ConstraintKind::NoConstraint) | ||
| 258 | continue; | ||
| 259 | for (BaseCommand *Base2 : Sec->SectionCommands) | ||
| 260 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base2)) | ||
| 261 | declareSymbol(Cmd); | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 156 | // This function is called from assignAddresses, while we are | 265 | // This function is called from assignAddresses, while we are |
| 157 | // fixing the output section addresses. This function is supposed | 266 | // fixing the output section addresses. This function is supposed |
| 158 | // to set the final value for a given symbol assignment. | 267 | // to set the final value for a given symbol assignment. |
| ... | @@ -249,23 +358,11 @@ static void sortSections(MutableArrayRef<InputSection *> Vec, | ... | @@ -249,23 +358,11 @@ static void sortSections(MutableArrayRef<InputSection *> Vec, |
| 249 | // --sort-section is handled as an inner SORT command. | 358 | // --sort-section is handled as an inner SORT command. |
| 250 | // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. | 359 | // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. |
| 251 | // 4. If no SORT command is given, sort according to --sort-section. | 360 | // 4. If no SORT command is given, sort according to --sort-section. |
| 252 | // 5. If no SORT commands are given and --sort-section is not specified, | 361 | static void sortInputSections(MutableArrayRef<InputSection *> Vec, |
| 253 | // apply sorting provided by --symbol-ordering-file if any exist. | 362 | const SectionPattern &Pat) { |
| 254 | static void sortInputSections( | ||
| 255 | MutableArrayRef<InputSection *> Vec, const SectionPattern &Pat, | ||
| 256 | const DenseMap<SectionBase *, int> &Order) { | ||
| 257 | if (Pat.SortOuter == SortSectionPolicy::None) | 363 | if (Pat.SortOuter == SortSectionPolicy::None) |
| 258 | return; | 364 | return; |
| 259 | 365 | ||
| 260 | if (Pat.SortOuter == SortSectionPolicy::Default && | ||
| 261 | Config->SortSection == SortSectionPolicy::Default) { | ||
| 262 | // If -symbol-ordering-file was given, sort accordingly. | ||
| 263 | // Usually, Order is empty. | ||
| 264 | if (!Order.empty()) | ||
| 265 | sortByOrder(Vec, [&](InputSectionBase *S) { return Order.lookup(S); }); | ||
| 266 | return; | ||
| 267 | } | ||
| 268 | |||
| 269 | if (Pat.SortInner == SortSectionPolicy::Default) | 366 | if (Pat.SortInner == SortSectionPolicy::Default) |
| 270 | sortSections(Vec, Config->SortSection); | 367 | sortSections(Vec, Config->SortSection); |
| 271 | else | 368 | else |
| ... | @@ -275,8 +372,7 @@ static void sortInputSections( | ... | @@ -275,8 +372,7 @@ static void sortInputSections( |
| 275 | 372 | ||
| 276 | // Compute and remember which sections the InputSectionDescription matches. | 373 | // Compute and remember which sections the InputSectionDescription matches. |
| 277 | std::vector<InputSection *> | 374 | std::vector<InputSection *> |
| 278 | LinkerScript::computeInputSections(const InputSectionDescription *Cmd, | 375 | LinkerScript::computeInputSections(const InputSectionDescription *Cmd) { |
| 279 | const DenseMap<SectionBase *, int> &Order) { | ||
| 280 | std::vector<InputSection *> Ret; | 376 | std::vector<InputSection *> Ret; |
| 281 | 377 | ||
| 282 | // Collects all sections that satisfy constraints of Cmd. | 378 | // Collects all sections that satisfy constraints of Cmd. |
| ... | @@ -290,8 +386,11 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd, | ... | @@ -290,8 +386,11 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd, |
| 290 | // For -emit-relocs we have to ignore entries like | 386 | // For -emit-relocs we have to ignore entries like |
| 291 | // .rela.dyn : { *(.rela.data) } | 387 | // .rela.dyn : { *(.rela.data) } |
| 292 | // which are common because they are in the default bfd script. | 388 | // which are common because they are in the default bfd script. |
| 293 | if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA) | 389 | // We do not ignore SHT_REL[A] linker-synthesized sections here because |
| 294 | continue; | 390 | // want to support scripts that do custom layout for them. |
| 391 | if (auto *IS = dyn_cast<InputSection>(Sec)) | ||
| 392 | if (IS->getRelocatedSection()) | ||
| 393 | continue; | ||
| 295 | 394 | ||
| 296 | std::string Filename = getFilename(Sec->File); | 395 | std::string Filename = getFilename(Sec->File); |
| 297 | if (!Cmd->FilePat.match(Filename) || | 396 | if (!Cmd->FilePat.match(Filename) || |
| ... | @@ -307,7 +406,7 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd, | ... | @@ -307,7 +406,7 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd, |
| 307 | } | 406 | } |
| 308 | 407 | ||
| 309 | sortInputSections(MutableArrayRef<InputSection *>(Ret).slice(SizeBefore), | 408 | sortInputSections(MutableArrayRef<InputSection *>(Ret).slice(SizeBefore), |
| 310 | Pat, Order); | 409 | Pat); |
| 311 | } | 410 | } |
| 312 | return Ret; | 411 | return Ret; |
| 313 | } | 412 | } |
| ... | @@ -315,22 +414,31 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd, | ... | @@ -315,22 +414,31 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd, |
| 315 | void LinkerScript::discard(ArrayRef<InputSection *> V) { | 414 | void LinkerScript::discard(ArrayRef<InputSection *> V) { |
| 316 | for (InputSection *S : V) { | 415 | for (InputSection *S : V) { |
| 317 | if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab || | 416 | if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab || |
| 318 | S == InX::DynStrTab) | 417 | S == InX::DynStrTab || S == InX::RelaPlt || S == InX::RelaDyn || |
| 418 | S == InX::RelrDyn) | ||
| 319 | error("discarding " + S->Name + " section is not allowed"); | 419 | error("discarding " + S->Name + " section is not allowed"); |
| 320 | 420 | ||
| 421 | // You can discard .hash and .gnu.hash sections by linker scripts. Since | ||
| 422 | // they are synthesized sections, we need to handle them differently than | ||
| 423 | // other regular sections. | ||
| 424 | if (S == InX::GnuHashTab) | ||
| 425 | InX::GnuHashTab = nullptr; | ||
| 426 | if (S == InX::HashTab) | ||
| 427 | InX::HashTab = nullptr; | ||
| 428 | |||
| 321 | S->Assigned = false; | 429 | S->Assigned = false; |
| 322 | S->Live = false; | 430 | S->Live = false; |
| 323 | discard(S->DependentSections); | 431 | discard(S->DependentSections); |
| 324 | } | 432 | } |
| 325 | } | 433 | } |
| 326 | 434 | ||
| 327 | std::vector<InputSection *> LinkerScript::createInputSectionList( | 435 | std::vector<InputSection *> |
| 328 | OutputSection &OutCmd, const DenseMap<SectionBase *, int> &Order) { | 436 | LinkerScript::createInputSectionList(OutputSection &OutCmd) { |
| 329 | std::vector<InputSection *> Ret; | 437 | std::vector<InputSection *> Ret; |
| 330 | 438 | ||
| 331 | for (BaseCommand *Base : OutCmd.SectionCommands) { | 439 | for (BaseCommand *Base : OutCmd.SectionCommands) { |
| 332 | if (auto *Cmd = dyn_cast<InputSectionDescription>(Base)) { | 440 | if (auto *Cmd = dyn_cast<InputSectionDescription>(Base)) { |
| 333 | Cmd->Sections = computeInputSections(Cmd, Order); | 441 | Cmd->Sections = computeInputSections(Cmd); |
| 334 | Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end()); | 442 | Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end()); |
| 335 | } | 443 | } |
| 336 | } | 444 | } |
| ... | @@ -359,7 +467,6 @@ void LinkerScript::processSectionCommands() { | ... | @@ -359,7 +467,6 @@ void LinkerScript::processSectionCommands() { |
| 359 | Ctx->OutSec = Aether; | 467 | Ctx->OutSec = Aether; |
| 360 | 468 | ||
| 361 | size_t I = 0; | 469 | size_t I = 0; |
| 362 | DenseMap<SectionBase *, int> Order = buildSectionOrder(); | ||
| 363 | // Add input sections to output sections. | 470 | // Add input sections to output sections. |
| 364 | for (BaseCommand *Base : SectionCommands) { | 471 | for (BaseCommand *Base : SectionCommands) { |
| 365 | // Handle symbol assignments outside of any output section. | 472 | // Handle symbol assignments outside of any output section. |
| ... | @@ -369,12 +476,13 @@ void LinkerScript::processSectionCommands() { | ... | @@ -369,12 +476,13 @@ void LinkerScript::processSectionCommands() { |
| 369 | } | 476 | } |
| 370 | 477 | ||
| 371 | if (auto *Sec = dyn_cast<OutputSection>(Base)) { | 478 | if (auto *Sec = dyn_cast<OutputSection>(Base)) { |
| 372 | std::vector<InputSection *> V = createInputSectionList(*Sec, Order); | 479 | std::vector<InputSection *> V = createInputSectionList(*Sec); |
| 373 | 480 | ||
| 374 | // The output section name `/DISCARD/' is special. | 481 | // The output section name `/DISCARD/' is special. |
| 375 | // Any input section assigned to it is discarded. | 482 | // Any input section assigned to it is discarded. |
| 376 | if (Sec->Name == "/DISCARD/") { | 483 | if (Sec->Name == "/DISCARD/") { |
| 377 | discard(V); | 484 | discard(V); |
| 485 | Sec->SectionCommands.clear(); | ||
| 378 | continue; | 486 | continue; |
| 379 | } | 487 | } |
| 380 | 488 | ||
| ... | @@ -414,6 +522,8 @@ void LinkerScript::processSectionCommands() { | ... | @@ -414,6 +522,8 @@ void LinkerScript::processSectionCommands() { |
| 414 | Sec->SectionIndex = I++; | 522 | Sec->SectionIndex = I++; |
| 415 | if (Sec->Noload) | 523 | if (Sec->Noload) |
| 416 | Sec->Type = SHT_NOBITS; | 524 | Sec->Type = SHT_NOBITS; |
| 525 | if (Sec->NonAlloc) | ||
| 526 | Sec->Flags &= ~(uint64_t)SHF_ALLOC; | ||
| 417 | } | 527 | } |
| 418 | } | 528 | } |
| 419 | Ctx = nullptr; | 529 | Ctx = nullptr; |
| ... | @@ -484,7 +594,7 @@ static OutputSection *addInputSec(StringMap<OutputSection *> &Map, | ... | @@ -484,7 +594,7 @@ static OutputSection *addInputSec(StringMap<OutputSection *> &Map, |
| 484 | // ignored. We should not have two output .text sections just because one was | 594 | // ignored. We should not have two output .text sections just because one was |
| 485 | // in a group and another was not for example. | 595 | // in a group and another was not for example. |
| 486 | // | 596 | // |
| 487 | // It also seems that that wording was a late addition and didn't get the | 597 | // It also seems that wording was a late addition and didn't get the |
| 488 | // necessary scrutiny. | 598 | // necessary scrutiny. |
| 489 | // | 599 | // |
| 490 | // Merging sections with different flags is expected by some users. One | 600 | // Merging sections with different flags is expected by some users. One |
| ... | @@ -529,11 +639,11 @@ static OutputSection *addInputSec(StringMap<OutputSection *> &Map, | ... | @@ -529,11 +639,11 @@ static OutputSection *addInputSec(StringMap<OutputSection *> &Map, |
| 529 | void LinkerScript::addOrphanSections() { | 639 | void LinkerScript::addOrphanSections() { |
| 530 | unsigned End = SectionCommands.size(); | 640 | unsigned End = SectionCommands.size(); |
| 531 | StringMap<OutputSection *> Map; | 641 | StringMap<OutputSection *> Map; |
| 532 | |||
| 533 | std::vector<OutputSection *> V; | 642 | std::vector<OutputSection *> V; |
| 534 | for (InputSectionBase *S : InputSections) { | 643 | |
| 644 | auto Add = [&](InputSectionBase *S) { | ||
| 535 | if (!S->Live || S->Parent) | 645 | if (!S->Live || S->Parent) |
| 536 | continue; | 646 | return; |
| 537 | 647 | ||
| 538 | StringRef Name = getOutputSectionName(S); | 648 | StringRef Name = getOutputSectionName(S); |
| 539 | 649 | ||
| ... | @@ -545,12 +655,24 @@ void LinkerScript::addOrphanSections() { | ... | @@ -545,12 +655,24 @@ void LinkerScript::addOrphanSections() { |
| 545 | if (OutputSection *Sec = | 655 | if (OutputSection *Sec = |
| 546 | findByName(makeArrayRef(SectionCommands).slice(0, End), Name)) { | 656 | findByName(makeArrayRef(SectionCommands).slice(0, End), Name)) { |
| 547 | Sec->addSection(cast<InputSection>(S)); | 657 | Sec->addSection(cast<InputSection>(S)); |
| 548 | continue; | 658 | return; |
| 549 | } | 659 | } |
| 550 | 660 | ||
| 551 | if (OutputSection *OS = addInputSec(Map, S, Name)) | 661 | if (OutputSection *OS = addInputSec(Map, S, Name)) |
| 552 | V.push_back(OS); | 662 | V.push_back(OS); |
| 553 | assert(S->getOutputSection()->SectionIndex == INT_MAX); | 663 | assert(S->getOutputSection()->SectionIndex == UINT32_MAX); |
| 664 | }; | ||
| 665 | |||
| 666 | // For futher --emit-reloc handling code we need target output section | ||
| 667 | // to be created before we create relocation output section, so we want | ||
| 668 | // to create target sections first. We do not want priority handling | ||
| 669 | // 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); | ||
| 554 | } | 676 | } |
| 555 | 677 | ||
| 556 | // If no SECTIONS command was given, we should insert sections commands | 678 | // If no SECTIONS command was given, we should insert sections commands |
| ... | @@ -585,33 +707,15 @@ void LinkerScript::output(InputSection *S) { | ... | @@ -585,33 +707,15 @@ void LinkerScript::output(InputSection *S) { |
| 585 | // Update output section size after adding each section. This is so that | 707 | // Update output section size after adding each section. This is so that |
| 586 | // SIZEOF works correctly in the case below: | 708 | // SIZEOF works correctly in the case below: |
| 587 | // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } | 709 | // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) } |
| 588 | Ctx->OutSec->Size = Pos - Ctx->OutSec->Addr; | 710 | expandOutputSection(Pos - Before); |
| 589 | |||
| 590 | // If there is a memory region associated with this input section, then | ||
| 591 | // place the section in that region and update the region index. | ||
| 592 | if (Ctx->LMARegion) | ||
| 593 | Ctx->LMARegion->CurPos += Pos - Before; | ||
| 594 | // FIXME: should we also produce overflow errors for LMARegion? | ||
| 595 | |||
| 596 | if (Ctx->MemRegion) { | ||
| 597 | uint64_t &CurOffset = Ctx->MemRegion->CurPos; | ||
| 598 | CurOffset += Pos - Before; | ||
| 599 | uint64_t CurSize = CurOffset - Ctx->MemRegion->Origin; | ||
| 600 | if (CurSize > Ctx->MemRegion->Length) { | ||
| 601 | uint64_t OverflowAmt = CurSize - Ctx->MemRegion->Length; | ||
| 602 | error("section '" + Ctx->OutSec->Name + "' will not fit in region '" + | ||
| 603 | Ctx->MemRegion->Name + "': overflowed by " + Twine(OverflowAmt) + | ||
| 604 | " bytes"); | ||
| 605 | } | ||
| 606 | } | ||
| 607 | } | 711 | } |
| 608 | 712 | ||
| 609 | void LinkerScript::switchTo(OutputSection *Sec) { | 713 | void LinkerScript::switchTo(OutputSection *Sec) { |
| 610 | if (Ctx->OutSec == Sec) | ||
| 611 | return; | ||
| 612 | |||
| 613 | Ctx->OutSec = Sec; | 714 | Ctx->OutSec = Sec; |
| 715 | |||
| 716 | uint64_t Before = advance(0, 1); | ||
| 614 | Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment); | 717 | Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment); |
| 718 | expandMemoryRegions(Ctx->OutSec->Addr - Before); | ||
| 615 | } | 719 | } |
| 616 | 720 | ||
| 617 | // This function searches for a memory region to place the given output | 721 | // This function searches for a memory region to place the given output |
| ... | @@ -674,9 +778,8 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { | ... | @@ -674,9 +778,8 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { |
| 674 | if (PhdrEntry *L = Ctx->OutSec->PtLoad) | 778 | if (PhdrEntry *L = Ctx->OutSec->PtLoad) |
| 675 | L->LMAOffset = Ctx->LMAOffset; | 779 | L->LMAOffset = Ctx->LMAOffset; |
| 676 | 780 | ||
| 677 | // The Size previously denoted how many InputSections had been added to this | 781 | // We can call this method multiple times during the creation of |
| 678 | // section, and was used for sorting SHF_LINK_ORDER sections. Reset it to | 782 | // thunks and want to start over calculation each time. |
| 679 | // compute the actual size value. | ||
| 680 | Sec->Size = 0; | 783 | Sec->Size = 0; |
| 681 | 784 | ||
| 682 | // We visited SectionsCommands from processSectionCommands to | 785 | // We visited SectionsCommands from processSectionCommands to |
| ... | @@ -685,7 +788,9 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { | ... | @@ -685,7 +788,9 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { |
| 685 | for (BaseCommand *Base : Sec->SectionCommands) { | 788 | for (BaseCommand *Base : Sec->SectionCommands) { |
| 686 | // This handles the assignments to symbol or to the dot. | 789 | // This handles the assignments to symbol or to the dot. |
| 687 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { | 790 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { |
| 791 | Cmd->Addr = Dot; | ||
| 688 | assignSymbol(Cmd, true); | 792 | assignSymbol(Cmd, true); |
| 793 | Cmd->Size = Dot - Cmd->Addr; | ||
| 689 | continue; | 794 | continue; |
| 690 | } | 795 | } |
| 691 | 796 | ||
| ... | @@ -693,17 +798,7 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { | ... | @@ -693,17 +798,7 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { |
| 693 | if (auto *Cmd = dyn_cast<ByteCommand>(Base)) { | 798 | if (auto *Cmd = dyn_cast<ByteCommand>(Base)) { |
| 694 | Cmd->Offset = Dot - Ctx->OutSec->Addr; | 799 | Cmd->Offset = Dot - Ctx->OutSec->Addr; |
| 695 | Dot += Cmd->Size; | 800 | Dot += Cmd->Size; |
| 696 | if (Ctx->MemRegion) | 801 | expandOutputSection(Cmd->Size); |
| 697 | Ctx->MemRegion->CurPos += Cmd->Size; | ||
| 698 | if (Ctx->LMARegion) | ||
| 699 | Ctx->LMARegion->CurPos += Cmd->Size; | ||
| 700 | Ctx->OutSec->Size = Dot - Ctx->OutSec->Addr; | ||
| 701 | continue; | ||
| 702 | } | ||
| 703 | |||
| 704 | // Handle ASSERT(). | ||
| 705 | if (auto *Cmd = dyn_cast<AssertCommand>(Base)) { | ||
| 706 | Cmd->Expression(); | ||
| 707 | continue; | 802 | continue; |
| 708 | } | 803 | } |
| 709 | 804 | ||
| ... | @@ -728,24 +823,28 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { | ... | @@ -728,24 +823,28 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { |
| 728 | } | 823 | } |
| 729 | } | 824 | } |
| 730 | 825 | ||
| 731 | void LinkerScript::removeEmptyCommands() { | 826 | static bool isDiscardable(OutputSection &Sec) { |
| 732 | // It is common practice to use very generic linker scripts. So for any | 827 | // We do not remove empty sections that are explicitly |
| 733 | // given run some of the output sections in the script will be empty. | 828 | // assigned to any segment. |
| 734 | // We could create corresponding empty output sections, but that would | 829 | if (!Sec.Phdrs.empty()) |
| 735 | // clutter the output. | ||
| 736 | // We instead remove trivially empty sections. The bfd linker seems even | ||
| 737 | // more aggressive at removing them. | ||
| 738 | llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { | ||
| 739 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | ||
| 740 | return !Sec->Live; | ||
| 741 | return false; | 830 | return false; |
| 742 | }); | ||
| 743 | } | ||
| 744 | 831 | ||
| 745 | static bool isAllSectionDescription(const OutputSection &Cmd) { | 832 | // We do not want to remove sections that reference symbols in address and |
| 746 | for (BaseCommand *Base : Cmd.SectionCommands) | 833 | // other expressions. We add script symbols as undefined, and want to ensure |
| 834 | // all of them are defined in the output, hence have to keep them. | ||
| 835 | if (Sec.ExpressionsUseSymbols) | ||
| 836 | return false; | ||
| 837 | |||
| 838 | for (BaseCommand *Base : Sec.SectionCommands) { | ||
| 839 | if (auto Cmd = dyn_cast<SymbolAssignment>(Base)) | ||
| 840 | // Don't create empty output sections just for unreferenced PROVIDE | ||
| 841 | // symbols. | ||
| 842 | if (Cmd->Name != "." && !Cmd->Sym) | ||
| 843 | continue; | ||
| 844 | |||
| 747 | if (!isa<InputSectionDescription>(*Base)) | 845 | if (!isa<InputSectionDescription>(*Base)) |
| 748 | return false; | 846 | return false; |
| 847 | } | ||
| 749 | return true; | 848 | return true; |
| 750 | } | 849 | } |
| 751 | 850 | ||
| ... | @@ -761,7 +860,7 @@ void LinkerScript::adjustSectionsBeforeSorting() { | ... | @@ -761,7 +860,7 @@ void LinkerScript::adjustSectionsBeforeSorting() { |
| 761 | // Given that we want to create the section, we have to worry what impact | 860 | // Given that we want to create the section, we have to worry what impact |
| 762 | // it will have on the link. For example, if we just create a section with | 861 | // it will have on the link. For example, if we just create a section with |
| 763 | // 0 for flags, it would change which PT_LOADs are created. | 862 | // 0 for flags, it would change which PT_LOADs are created. |
| 764 | // We could remember that that particular section is dummy and ignore it in | 863 | // We could remember that particular section is dummy and ignore it in |
| 765 | // other parts of the linker, but unfortunately there are quite a few places | 864 | // other parts of the linker, but unfortunately there are quite a few places |
| 766 | // that would need to change: | 865 | // that would need to change: |
| 767 | // * The program header creation. | 866 | // * The program header creation. |
| ... | @@ -772,29 +871,47 @@ void LinkerScript::adjustSectionsBeforeSorting() { | ... | @@ -772,29 +871,47 @@ void LinkerScript::adjustSectionsBeforeSorting() { |
| 772 | // the previous sections. Only a few flags are needed to keep the impact low. | 871 | // the previous sections. Only a few flags are needed to keep the impact low. |
| 773 | uint64_t Flags = SHF_ALLOC; | 872 | uint64_t Flags = SHF_ALLOC; |
| 774 | 873 | ||
| 775 | for (BaseCommand *Cmd : SectionCommands) { | 874 | for (BaseCommand *&Cmd : SectionCommands) { |
| 776 | auto *Sec = dyn_cast<OutputSection>(Cmd); | 875 | auto *Sec = dyn_cast<OutputSection>(Cmd); |
| 777 | if (!Sec) | 876 | if (!Sec) |
| 778 | continue; | 877 | continue; |
| 779 | if (Sec->Live) { | ||
| 780 | Flags = Sec->Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); | ||
| 781 | continue; | ||
| 782 | } | ||
| 783 | |||
| 784 | if (isAllSectionDescription(*Sec)) | ||
| 785 | continue; | ||
| 786 | 878 | ||
| 787 | Sec->Live = true; | 879 | // Handle align (e.g. ".foo : ALIGN(16) { ... }"). |
| 788 | Sec->Flags = Flags; | 880 | if (Sec->AlignExpr) |
| 881 | Sec->Alignment = | ||
| 882 | std::max<uint32_t>(Sec->Alignment, Sec->AlignExpr().getValue()); | ||
| 883 | |||
| 884 | // A live output section means that some input section was added to it. It | ||
| 885 | // might have been removed (if it was empty synthetic section), but we at | ||
| 886 | // least know the flags. | ||
| 887 | if (Sec->Live) | ||
| 888 | Flags = Sec->Flags; | ||
| 889 | |||
| 890 | // We do not want to keep any special flags for output section | ||
| 891 | // in case it is empty. | ||
| 892 | bool IsEmpty = getInputSections(Sec).empty(); | ||
| 893 | if (IsEmpty) | ||
| 894 | Sec->Flags = Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); | ||
| 895 | |||
| 896 | if (IsEmpty && isDiscardable(*Sec)) { | ||
| 897 | Sec->Live = false; | ||
| 898 | Cmd = nullptr; | ||
| 899 | } | ||
| 789 | } | 900 | } |
| 901 | |||
| 902 | // It is common practice to use very generic linker scripts. So for any | ||
| 903 | // given run some of the output sections in the script will be empty. | ||
| 904 | // We could create corresponding empty output sections, but that would | ||
| 905 | // clutter the output. | ||
| 906 | // We instead remove trivially empty sections. The bfd linker seems even | ||
| 907 | // more aggressive at removing them. | ||
| 908 | llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { return !Base; }); | ||
| 790 | } | 909 | } |
| 791 | 910 | ||
| 792 | void LinkerScript::adjustSectionsAfterSorting() { | 911 | void LinkerScript::adjustSectionsAfterSorting() { |
| 793 | // Try and find an appropriate memory region to assign offsets in. | 912 | // Try and find an appropriate memory region to assign offsets in. |
| 794 | for (BaseCommand *Base : SectionCommands) { | 913 | for (BaseCommand *Base : SectionCommands) { |
| 795 | if (auto *Sec = dyn_cast<OutputSection>(Base)) { | 914 | if (auto *Sec = dyn_cast<OutputSection>(Base)) { |
| 796 | if (!Sec->Live) | ||
| 797 | continue; | ||
| 798 | if (!Sec->LMARegionName.empty()) { | 915 | if (!Sec->LMARegionName.empty()) { |
| 799 | if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName)) | 916 | if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName)) |
| 800 | Sec->LMARegion = M; | 917 | Sec->LMARegion = M; |
| ... | @@ -802,10 +919,6 @@ void LinkerScript::adjustSectionsAfterSorting() { | ... | @@ -802,10 +919,6 @@ void LinkerScript::adjustSectionsAfterSorting() { |
| 802 | error("memory region '" + Sec->LMARegionName + "' not declared"); | 919 | error("memory region '" + Sec->LMARegionName + "' not declared"); |
| 803 | } | 920 | } |
| 804 | Sec->MemRegion = findMemoryRegion(Sec); | 921 | Sec->MemRegion = findMemoryRegion(Sec); |
| 805 | // Handle align (e.g. ".foo : ALIGN(16) { ... }"). | ||
| 806 | if (Sec->AlignExpr) | ||
| 807 | Sec->Alignment = | ||
| 808 | std::max<uint32_t>(Sec->Alignment, Sec->AlignExpr().getValue()); | ||
| 809 | } | 922 | } |
| 810 | } | 923 | } |
| 811 | 924 | ||
| ... | @@ -816,9 +929,9 @@ void LinkerScript::adjustSectionsAfterSorting() { | ... | @@ -816,9 +929,9 @@ void LinkerScript::adjustSectionsAfterSorting() { |
| 816 | // PHDRS { seg PT_LOAD; } | 929 | // PHDRS { seg PT_LOAD; } |
| 817 | // SECTIONS { .aaa : { *(.aaa) } } | 930 | // SECTIONS { .aaa : { *(.aaa) } } |
| 818 | std::vector<StringRef> DefPhdrs; | 931 | std::vector<StringRef> DefPhdrs; |
| 819 | auto FirstPtLoad = | 932 | auto FirstPtLoad = llvm::find_if(PhdrsCommands, [](const PhdrsCommand &Cmd) { |
| 820 | std::find_if(PhdrsCommands.begin(), PhdrsCommands.end(), | 933 | return Cmd.Type == PT_LOAD; |
| 821 | [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; }); | 934 | }); |
| 822 | if (FirstPtLoad != PhdrsCommands.end()) | 935 | if (FirstPtLoad != PhdrsCommands.end()) |
| 823 | DefPhdrs.push_back(FirstPtLoad->Name); | 936 | DefPhdrs.push_back(FirstPtLoad->Name); |
| 824 | 937 | ||
| ... | @@ -847,6 +960,15 @@ static OutputSection *findFirstSection(PhdrEntry *Load) { | ... | @@ -847,6 +960,15 @@ static OutputSection *findFirstSection(PhdrEntry *Load) { |
| 847 | return nullptr; | 960 | return nullptr; |
| 848 | } | 961 | } |
| 849 | 962 | ||
| 963 | static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) { | ||
| 964 | // If there is no SECTIONS or if the linkerscript is explicit about program | ||
| 965 | // headers, do our best to allocate them. | ||
| 966 | if (!Script->HasSectionsCommand || AllocateHeaders) | ||
| 967 | return 0; | ||
| 968 | // Otherwise only allocate program headers if that would not add a page. | ||
| 969 | return alignDown(Min, Config->MaxPageSize); | ||
| 970 | } | ||
| 971 | |||
| 850 | // Try to find an address for the file and program headers output sections, | 972 | // Try to find an address for the file and program headers output sections, |
| 851 | // which were unconditionally added to the first PT_LOAD segment earlier. | 973 | // which were unconditionally added to the first PT_LOAD segment earlier. |
| 852 | // | 974 | // |
| ... | @@ -870,17 +992,22 @@ void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) { | ... | @@ -870,17 +992,22 @@ void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) { |
| 870 | return; | 992 | return; |
| 871 | PhdrEntry *FirstPTLoad = *It; | 993 | PhdrEntry *FirstPTLoad = *It; |
| 872 | 994 | ||
| 995 | bool HasExplicitHeaders = | ||
| 996 | llvm::any_of(PhdrsCommands, [](const PhdrsCommand &Cmd) { | ||
| 997 | return Cmd.HasPhdrs || Cmd.HasFilehdr; | ||
| 998 | }); | ||
| 873 | uint64_t HeaderSize = getHeaderSize(); | 999 | uint64_t HeaderSize = getHeaderSize(); |
| 874 | // When linker script with SECTIONS is being used, don't output headers | 1000 | if (HeaderSize <= Min - computeBase(Min, HasExplicitHeaders)) { |
| 875 | // unless there's a space for them. | ||
| 876 | uint64_t Base = HasSectionsCommand ? alignDown(Min, Config->MaxPageSize) : 0; | ||
| 877 | if (HeaderSize <= Min - Base || Script->hasPhdrsCommands()) { | ||
| 878 | Min = alignDown(Min - HeaderSize, Config->MaxPageSize); | 1001 | Min = alignDown(Min - HeaderSize, Config->MaxPageSize); |
| 879 | Out::ElfHeader->Addr = Min; | 1002 | Out::ElfHeader->Addr = Min; |
| 880 | Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size; | 1003 | Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size; |
| 881 | return; | 1004 | return; |
| 882 | } | 1005 | } |
| 883 | 1006 | ||
| 1007 | // Error if we were explicitly asked to allocate headers. | ||
| 1008 | if (HasExplicitHeaders) | ||
| 1009 | error("could not allocate headers"); | ||
| 1010 | |||
| 884 | Out::ElfHeader->PtLoad = nullptr; | 1011 | Out::ElfHeader->PtLoad = nullptr; |
| 885 | Out::ProgramHeaders->PtLoad = nullptr; | 1012 | Out::ProgramHeaders->PtLoad = nullptr; |
| 886 | FirstPTLoad->FirstSec = findFirstSection(FirstPTLoad); | 1013 | FirstPTLoad->FirstSec = findFirstSection(FirstPTLoad); |
| ... | @@ -924,15 +1051,11 @@ void LinkerScript::assignAddresses() { | ... | @@ -924,15 +1051,11 @@ void LinkerScript::assignAddresses() { |
| 924 | 1051 | ||
| 925 | for (BaseCommand *Base : SectionCommands) { | 1052 | for (BaseCommand *Base : SectionCommands) { |
| 926 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { | 1053 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { |
| 1054 | Cmd->Addr = Dot; | ||
| 927 | assignSymbol(Cmd, false); | 1055 | assignSymbol(Cmd, false); |
| 1056 | Cmd->Size = Dot - Cmd->Addr; | ||
| 928 | continue; | 1057 | continue; |
| 929 | } | 1058 | } |
| 930 | |||
| 931 | if (auto *Cmd = dyn_cast<AssertCommand>(Base)) { | ||
| 932 | Cmd->Expression(); | ||
| 933 | continue; | ||
| 934 | } | ||
| 935 | |||
| 936 | assignOffsets(cast<OutputSection>(Base)); | 1059 | assignOffsets(cast<OutputSection>(Base)); |
| 937 | } | 1060 | } |
| 938 | Ctx = nullptr; | 1061 | Ctx = nullptr; |
| ... | @@ -996,9 +1119,9 @@ ExprValue LinkerScript::getSymbolValue(StringRef Name, const Twine &Loc) { | ... | @@ -996,9 +1119,9 @@ ExprValue LinkerScript::getSymbolValue(StringRef Name, const Twine &Loc) { |
| 996 | if (Symbol *Sym = Symtab->find(Name)) { | 1119 | if (Symbol *Sym = Symtab->find(Name)) { |
| 997 | if (auto *DS = dyn_cast<Defined>(Sym)) | 1120 | if (auto *DS = dyn_cast<Defined>(Sym)) |
| 998 | return {DS->Section, false, DS->Value, Loc}; | 1121 | return {DS->Section, false, DS->Value, Loc}; |
| 999 | if (auto *SS = dyn_cast<SharedSymbol>(Sym)) | 1122 | if (isa<SharedSymbol>(Sym)) |
| 1000 | if (!ErrorOnMissingSection || SS->CopyRelSec) | 1123 | if (!ErrorOnMissingSection) |
| 1001 | return {SS->CopyRelSec, false, 0, Loc}; | 1124 | return {nullptr, false, 0, Loc}; |
| 1002 | } | 1125 | } |
| 1003 | 1126 | ||
| 1004 | error(Loc + ": symbol not found: " + Name); | 1127 | error(Loc + ": symbol not found: " + Name); |
deps/lld/ELF/LinkerScript.h+34-19| ... | @@ -11,9 +11,9 @@ | ... | @@ -11,9 +11,9 @@ |
| 11 | #define LLD_ELF_LINKER_SCRIPT_H | 11 | #define LLD_ELF_LINKER_SCRIPT_H |
| 12 | 12 | ||
| 13 | #include "Config.h" | 13 | #include "Config.h" |
| 14 | #include "Strings.h" | ||
| 15 | #include "Writer.h" | 14 | #include "Writer.h" |
| 16 | #include "lld/Common/LLVM.h" | 15 | #include "lld/Common/LLVM.h" |
| 16 | #include "lld/Common/Strings.h" | ||
| 17 | #include "llvm/ADT/ArrayRef.h" | 17 | #include "llvm/ADT/ArrayRef.h" |
| 18 | #include "llvm/ADT/DenseMap.h" | 18 | #include "llvm/ADT/DenseMap.h" |
| 19 | #include "llvm/ADT/DenseSet.h" | 19 | #include "llvm/ADT/DenseSet.h" |
| ... | @@ -75,7 +75,6 @@ enum SectionsCommandKind { | ... | @@ -75,7 +75,6 @@ enum SectionsCommandKind { |
| 75 | AssignmentKind, // . = expr or <sym> = expr | 75 | AssignmentKind, // . = expr or <sym> = expr |
| 76 | OutputSectionKind, | 76 | OutputSectionKind, |
| 77 | InputSectionKind, | 77 | InputSectionKind, |
| 78 | AssertKind, // ASSERT(expr) | ||
| 79 | ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) | 78 | ByteKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr) |
| 80 | }; | 79 | }; |
| 81 | 80 | ||
| ... | @@ -106,6 +105,16 @@ struct SymbolAssignment : BaseCommand { | ... | @@ -106,6 +105,16 @@ struct SymbolAssignment : BaseCommand { |
| 106 | 105 | ||
| 107 | // Holds file name and line number for error reporting. | 106 | // Holds file name and line number for error reporting. |
| 108 | std::string Location; | 107 | std::string Location; |
| 108 | |||
| 109 | // A string representation of this command. We use this for -Map. | ||
| 110 | std::string CommandString; | ||
| 111 | |||
| 112 | // Address of this assignment command. | ||
| 113 | unsigned Addr; | ||
| 114 | |||
| 115 | // Size of this assignment command. This is usually 0, but if | ||
| 116 | // you move '.' this may be greater than 0. | ||
| 117 | unsigned Size; | ||
| 109 | }; | 118 | }; |
| 110 | 119 | ||
| 111 | // Linker scripts allow additional constraints to be put on ouput sections. | 120 | // Linker scripts allow additional constraints to be put on ouput sections. |
| ... | @@ -167,24 +176,23 @@ struct InputSectionDescription : BaseCommand { | ... | @@ -167,24 +176,23 @@ struct InputSectionDescription : BaseCommand { |
| 167 | std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections; | 176 | std::vector<std::pair<ThunkSection *, uint32_t>> ThunkSections; |
| 168 | }; | 177 | }; |
| 169 | 178 | ||
| 170 | // Represents an ASSERT(). | ||
| 171 | struct AssertCommand : BaseCommand { | ||
| 172 | AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {} | ||
| 173 | |||
| 174 | static bool classof(const BaseCommand *C) { return C->Kind == AssertKind; } | ||
| 175 | |||
| 176 | Expr Expression; | ||
| 177 | }; | ||
| 178 | |||
| 179 | // Represents BYTE(), SHORT(), LONG(), or QUAD(). | 179 | // Represents BYTE(), SHORT(), LONG(), or QUAD(). |
| 180 | struct ByteCommand : BaseCommand { | 180 | struct ByteCommand : BaseCommand { |
| 181 | ByteCommand(Expr E, unsigned Size) | 181 | ByteCommand(Expr E, unsigned Size, std::string CommandString) |
| 182 | : BaseCommand(ByteKind), Expression(E), Size(Size) {} | 182 | : BaseCommand(ByteKind), CommandString(CommandString), Expression(E), |
| 183 | Size(Size) {} | ||
| 183 | 184 | ||
| 184 | static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; } | 185 | static bool classof(const BaseCommand *C) { return C->Kind == ByteKind; } |
| 185 | 186 | ||
| 187 | // Keeps string representing the command. Used for -Map" is perhaps better. | ||
| 188 | std::string CommandString; | ||
| 189 | |||
| 186 | Expr Expression; | 190 | Expr Expression; |
| 191 | |||
| 192 | // This is just an offset of this assignment command in the output section. | ||
| 187 | unsigned Offset; | 193 | unsigned Offset; |
| 194 | |||
| 195 | // Size of this data command. | ||
| 188 | unsigned Size; | 196 | unsigned Size; |
| 189 | }; | 197 | }; |
| 190 | 198 | ||
| ... | @@ -215,14 +223,13 @@ class LinkerScript final { | ... | @@ -215,14 +223,13 @@ class LinkerScript final { |
| 215 | void addSymbol(SymbolAssignment *Cmd); | 223 | void addSymbol(SymbolAssignment *Cmd); |
| 216 | void assignSymbol(SymbolAssignment *Cmd, bool InSec); | 224 | void assignSymbol(SymbolAssignment *Cmd, bool InSec); |
| 217 | void setDot(Expr E, const Twine &Loc, bool InSec); | 225 | void setDot(Expr E, const Twine &Loc, bool InSec); |
| 226 | void expandOutputSection(uint64_t Size); | ||
| 227 | void expandMemoryRegions(uint64_t Size); | ||
| 218 | 228 | ||
| 219 | std::vector<InputSection *> | 229 | std::vector<InputSection *> |
| 220 | computeInputSections(const InputSectionDescription *, | 230 | computeInputSections(const InputSectionDescription *); |
| 221 | const llvm::DenseMap<SectionBase *, int> &Order); | ||
| 222 | 231 | ||
| 223 | std::vector<InputSection *> | 232 | std::vector<InputSection *> createInputSectionList(OutputSection &Cmd); |
| 224 | createInputSectionList(OutputSection &Cmd, | ||
| 225 | const llvm::DenseMap<SectionBase *, int> &Order); | ||
| 226 | 233 | ||
| 227 | std::vector<size_t> getPhdrIndices(OutputSection *Sec); | 234 | std::vector<size_t> getPhdrIndices(OutputSection *Sec); |
| 228 | 235 | ||
| ... | @@ -257,7 +264,6 @@ public: | ... | @@ -257,7 +264,6 @@ public: |
| 257 | ExprValue getSymbolValue(StringRef Name, const Twine &Loc); | 264 | ExprValue getSymbolValue(StringRef Name, const Twine &Loc); |
| 258 | 265 | ||
| 259 | void addOrphanSections(); | 266 | void addOrphanSections(); |
| 260 | void removeEmptyCommands(); | ||
| 261 | void adjustSectionsBeforeSorting(); | 267 | void adjustSectionsBeforeSorting(); |
| 262 | void adjustSectionsAfterSorting(); | 268 | void adjustSectionsAfterSorting(); |
| 263 | 269 | ||
| ... | @@ -268,6 +274,10 @@ public: | ... | @@ -268,6 +274,10 @@ public: |
| 268 | void assignAddresses(); | 274 | void assignAddresses(); |
| 269 | void allocateHeaders(std::vector<PhdrEntry *> &Phdrs); | 275 | void allocateHeaders(std::vector<PhdrEntry *> &Phdrs); |
| 270 | void processSectionCommands(); | 276 | void processSectionCommands(); |
| 277 | void declareSymbols(); | ||
| 278 | |||
| 279 | // Used to handle INSERT AFTER statements. | ||
| 280 | void processInsertCommands(); | ||
| 271 | 281 | ||
| 272 | // SECTIONS command list. | 282 | // SECTIONS command list. |
| 273 | std::vector<BaseCommand *> SectionCommands; | 283 | std::vector<BaseCommand *> SectionCommands; |
| ... | @@ -287,6 +297,11 @@ public: | ... | @@ -287,6 +297,11 @@ public: |
| 287 | 297 | ||
| 288 | // A list of symbols referenced by the script. | 298 | // A list of symbols referenced by the script. |
| 289 | std::vector<llvm::StringRef> ReferencedSymbols; | 299 | std::vector<llvm::StringRef> ReferencedSymbols; |
| 300 | |||
| 301 | // Used to implement INSERT [AFTER|BEFORE]. Contains commands that need | ||
| 302 | // to be inserted into SECTIONS commands list. | ||
| 303 | llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands; | ||
| 304 | llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertBeforeCommands; | ||
| 290 | }; | 305 | }; |
| 291 | 306 | ||
| 292 | extern LinkerScript *Script; | 307 | extern LinkerScript *Script; |
deps/lld/ELF/MapFile.cpp+161-52| ... | @@ -23,11 +23,13 @@ | ... | @@ -23,11 +23,13 @@ |
| 23 | #include "InputFiles.h" | 23 | #include "InputFiles.h" |
| 24 | #include "LinkerScript.h" | 24 | #include "LinkerScript.h" |
| 25 | #include "OutputSections.h" | 25 | #include "OutputSections.h" |
| 26 | #include "Strings.h" | ||
| 27 | #include "SymbolTable.h" | 26 | #include "SymbolTable.h" |
| 28 | #include "Symbols.h" | 27 | #include "Symbols.h" |
| 29 | #include "SyntheticSections.h" | 28 | #include "SyntheticSections.h" |
| 29 | #include "lld/Common/Strings.h" | ||
| 30 | #include "lld/Common/Threads.h" | 30 | #include "lld/Common/Threads.h" |
| 31 | #include "llvm/ADT/MapVector.h" | ||
| 32 | #include "llvm/ADT/SetVector.h" | ||
| 31 | #include "llvm/Support/raw_ostream.h" | 33 | #include "llvm/Support/raw_ostream.h" |
| 32 | 34 | ||
| 33 | using namespace llvm; | 35 | using namespace llvm; |
| ... | @@ -36,57 +38,46 @@ using namespace llvm::object; | ... | @@ -36,57 +38,46 @@ using namespace llvm::object; |
| 36 | using namespace lld; | 38 | using namespace lld; |
| 37 | using namespace lld::elf; | 39 | using namespace lld::elf; |
| 38 | 40 | ||
| 39 | typedef DenseMap<const SectionBase *, SmallVector<Symbol *, 4>> SymbolMapTy; | 41 | typedef DenseMap<const SectionBase *, SmallVector<Defined *, 4>> SymbolMapTy; |
| 42 | |||
| 43 | static const std::string Indent8 = " "; // 8 spaces | ||
| 44 | static const std::string Indent16 = " "; // 16 spaces | ||
| 40 | 45 | ||
| 41 | // Print out the first three columns of a line. | 46 | // Print out the first three columns of a line. |
| 42 | static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size, | 47 | static void writeHeader(raw_ostream &OS, uint64_t VMA, uint64_t LMA, |
| 43 | uint64_t Align) { | 48 | uint64_t Size, uint64_t Align) { |
| 44 | int W = Config->Is64 ? 16 : 8; | 49 | if (Config->Is64) |
| 45 | OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align); | 50 | OS << format("%16llx %16llx %8llx %5lld ", VMA, LMA, Size, Align); |
| 51 | else | ||
| 52 | OS << format("%8llx %8llx %8llx %5lld ", VMA, LMA, Size, Align); | ||
| 46 | } | 53 | } |
| 47 | 54 | ||
| 48 | static std::string indent(int Depth) { return std::string(Depth * 8, ' '); } | ||
| 49 | |||
| 50 | // Returns a list of all symbols that we want to print out. | 55 | // Returns a list of all symbols that we want to print out. |
| 51 | static std::vector<Symbol *> getSymbols() { | 56 | static std::vector<Defined *> getSymbols() { |
| 52 | std::vector<Symbol *> V; | 57 | std::vector<Defined *> V; |
| 53 | for (InputFile *File : ObjectFiles) { | 58 | for (InputFile *File : ObjectFiles) |
| 54 | for (Symbol *B : File->getSymbols()) { | 59 | for (Symbol *B : File->getSymbols()) |
| 55 | if (auto *SS = dyn_cast<SharedSymbol>(B)) | ||
| 56 | if (SS->CopyRelSec || SS->NeedsPltAddr) | ||
| 57 | V.push_back(SS); | ||
| 58 | if (auto *DR = dyn_cast<Defined>(B)) | 60 | if (auto *DR = dyn_cast<Defined>(B)) |
| 59 | if (DR->File == File && !DR->isSection() && DR->Section && | 61 | if (!DR->isSection() && DR->Section && DR->Section->Live && |
| 60 | DR->Section->Live) | 62 | (DR->File == File || DR->NeedsPltAddr || DR->Section->Bss)) |
| 61 | V.push_back(DR); | 63 | V.push_back(DR); |
| 62 | } | ||
| 63 | } | ||
| 64 | return V; | 64 | return V; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | // Returns a map from sections to their symbols. | 67 | // Returns a map from sections to their symbols. |
| 68 | static SymbolMapTy getSectionSyms(ArrayRef<Symbol *> Syms) { | 68 | static SymbolMapTy getSectionSyms(ArrayRef<Defined *> Syms) { |
| 69 | SymbolMapTy Ret; | 69 | SymbolMapTy Ret; |
| 70 | for (Symbol *S : Syms) { | 70 | for (Defined *DR : Syms) |
| 71 | if (auto *DR = dyn_cast<Defined>(S)) { | 71 | Ret[DR->Section].push_back(DR); |
| 72 | Ret[DR->Section].push_back(S); | ||
| 73 | continue; | ||
| 74 | } | ||
| 75 | |||
| 76 | SharedSymbol *SS = cast<SharedSymbol>(S); | ||
| 77 | if (SS->CopyRelSec) | ||
| 78 | Ret[SS->CopyRelSec].push_back(S); | ||
| 79 | else | ||
| 80 | Ret[InX::Plt].push_back(S); | ||
| 81 | } | ||
| 82 | 72 | ||
| 83 | // Sort symbols by address. We want to print out symbols in the | 73 | // Sort symbols by address. We want to print out symbols in the |
| 84 | // order in the output file rather than the order they appeared | 74 | // order in the output file rather than the order they appeared |
| 85 | // in the input files. | 75 | // in the input files. |
| 86 | for (auto &It : Ret) { | 76 | for (auto &It : Ret) { |
| 87 | SmallVectorImpl<Symbol *> &V = It.second; | 77 | SmallVectorImpl<Defined *> &V = It.second; |
| 88 | std::sort(V.begin(), V.end(), | 78 | std::stable_sort(V.begin(), V.end(), [](Defined *A, Defined *B) { |
| 89 | [](Symbol *A, Symbol *B) { return A->getVA() < B->getVA(); }); | 79 | return A->getVA() < B->getVA(); |
| 80 | }); | ||
| 90 | } | 81 | } |
| 91 | return Ret; | 82 | return Ret; |
| 92 | } | 83 | } |
| ... | @@ -95,12 +86,15 @@ static SymbolMapTy getSectionSyms(ArrayRef<Symbol *> Syms) { | ... | @@ -95,12 +86,15 @@ static SymbolMapTy getSectionSyms(ArrayRef<Symbol *> Syms) { |
| 95 | // Demangling symbols (which is what toString() does) is slow, so | 86 | // Demangling symbols (which is what toString() does) is slow, so |
| 96 | // we do that in batch using parallel-for. | 87 | // we do that in batch using parallel-for. |
| 97 | static DenseMap<Symbol *, std::string> | 88 | static DenseMap<Symbol *, std::string> |
| 98 | getSymbolStrings(ArrayRef<Symbol *> Syms) { | 89 | getSymbolStrings(ArrayRef<Defined *> Syms) { |
| 99 | std::vector<std::string> Str(Syms.size()); | 90 | std::vector<std::string> Str(Syms.size()); |
| 100 | parallelForEachN(0, Syms.size(), [&](size_t I) { | 91 | parallelForEachN(0, Syms.size(), [&](size_t I) { |
| 101 | raw_string_ostream OS(Str[I]); | 92 | raw_string_ostream OS(Str[I]); |
| 102 | writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0); | 93 | OutputSection *OSec = Syms[I]->getOutputSection(); |
| 103 | OS << indent(2) << toString(*Syms[I]); | 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]); | ||
| 104 | }); | 98 | }); |
| 105 | 99 | ||
| 106 | DenseMap<Symbol *, std::string> Ret; | 100 | DenseMap<Symbol *, std::string> Ret; |
| ... | @@ -109,6 +103,44 @@ getSymbolStrings(ArrayRef<Symbol *> Syms) { | ... | @@ -109,6 +103,44 @@ getSymbolStrings(ArrayRef<Symbol *> Syms) { |
| 109 | return Ret; | 103 | return Ret; |
| 110 | } | 104 | } |
| 111 | 105 | ||
| 106 | // Print .eh_frame contents. Since the section consists of EhSectionPieces, | ||
| 107 | // we need a specialized printer for that section. | ||
| 108 | // | ||
| 109 | // .eh_frame tend to contain a lot of section pieces that are contiguous | ||
| 110 | // both in input file and output file. Such pieces are squashed before | ||
| 111 | // being displayed to make output compact. | ||
| 112 | static void printEhFrame(raw_ostream &OS, OutputSection *OSec) { | ||
| 113 | std::vector<EhSectionPiece> Pieces; | ||
| 114 | |||
| 115 | auto Add = [&](const EhSectionPiece &P) { | ||
| 116 | // 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; | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | Pieces.push_back(P); | ||
| 126 | }; | ||
| 127 | |||
| 128 | // Gather section pieces. | ||
| 129 | for (const CieRecord *Rec : InX::EhFrame->getCieRecords()) { | ||
| 130 | Add(*Rec->Cie); | ||
| 131 | for (const EhSectionPiece *Fde : Rec->Fdes) | ||
| 132 | Add(*Fde); | ||
| 133 | } | ||
| 134 | |||
| 135 | // 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"; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 112 | void elf::writeMapFile() { | 144 | void elf::writeMapFile() { |
| 113 | if (Config->MapFile.empty()) | 145 | if (Config->MapFile.empty()) |
| 114 | return; | 146 | return; |
| ... | @@ -122,32 +154,109 @@ void elf::writeMapFile() { | ... | @@ -122,32 +154,109 @@ void elf::writeMapFile() { |
| 122 | } | 154 | } |
| 123 | 155 | ||
| 124 | // Collect symbol info that we want to print out. | 156 | // Collect symbol info that we want to print out. |
| 125 | std::vector<Symbol *> Syms = getSymbols(); | 157 | std::vector<Defined *> Syms = getSymbols(); |
| 126 | SymbolMapTy SectionSyms = getSectionSyms(Syms); | 158 | SymbolMapTy SectionSyms = getSectionSyms(Syms); |
| 127 | DenseMap<Symbol *, std::string> SymStr = getSymbolStrings(Syms); | 159 | DenseMap<Symbol *, std::string> SymStr = getSymbolStrings(Syms); |
| 128 | 160 | ||
| 129 | // Print out the header line. | 161 | // Print out the header line. |
| 130 | int W = Config->Is64 ? 16 : 8; | 162 | int W = Config->Is64 ? 16 : 8; |
| 131 | OS << left_justify("Address", W) << ' ' << left_justify("Size", W) | 163 | OS << right_justify("VMA", W) << ' ' << right_justify("LMA", W) |
| 132 | << " Align Out In Symbol\n"; | 164 | << " Size Align Out In Symbol\n"; |
| 165 | |||
| 166 | for (BaseCommand *Base : Script->SectionCommands) { | ||
| 167 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { | ||
| 168 | if (Cmd->Provide && !Cmd->Sym) | ||
| 169 | continue; | ||
| 170 | //FIXME: calculate and print LMA. | ||
| 171 | writeHeader(OS, Cmd->Addr, 0, Cmd->Size, 1); | ||
| 172 | OS << Cmd->CommandString << '\n'; | ||
| 173 | continue; | ||
| 174 | } | ||
| 133 | 175 | ||
| 134 | // Print out file contents. | 176 | auto *OSec = cast<OutputSection>(Base); |
| 135 | for (OutputSection *OSec : OutputSections) { | 177 | writeHeader(OS, OSec->Addr, OSec->getLMA(), OSec->Size, OSec->Alignment); |
| 136 | writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment); | ||
| 137 | OS << OSec->Name << '\n'; | 178 | OS << OSec->Name << '\n'; |
| 138 | 179 | ||
| 139 | // Dump symbols for each input section. | 180 | // Dump symbols for each input section. |
| 140 | for (BaseCommand *Base : OSec->SectionCommands) { | 181 | for (BaseCommand *Base : OSec->SectionCommands) { |
| 141 | auto *ISD = dyn_cast<InputSectionDescription>(Base); | 182 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) { |
| 142 | if (!ISD) | 183 | for (InputSection *IS : ISD->Sections) { |
| 184 | if (IS == InX::EhFrame) { | ||
| 185 | printEhFrame(OS, OSec); | ||
| 186 | continue; | ||
| 187 | } | ||
| 188 | |||
| 189 | writeHeader(OS, IS->getVA(0), OSec->getLMA() + IS->getOffset(0), | ||
| 190 | IS->getSize(), IS->Alignment); | ||
| 191 | OS << Indent8 << toString(IS) << '\n'; | ||
| 192 | for (Symbol *Sym : SectionSyms[IS]) | ||
| 193 | OS << SymStr[Sym] << '\n'; | ||
| 194 | } | ||
| 195 | continue; | ||
| 196 | } | ||
| 197 | |||
| 198 | if (auto *Cmd = dyn_cast<ByteCommand>(Base)) { | ||
| 199 | writeHeader(OS, OSec->Addr + Cmd->Offset, OSec->getLMA() + Cmd->Offset, | ||
| 200 | Cmd->Size, 1); | ||
| 201 | OS << Indent8 << Cmd->CommandString << '\n'; | ||
| 202 | continue; | ||
| 203 | } | ||
| 204 | |||
| 205 | if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { | ||
| 206 | if (Cmd->Provide && !Cmd->Sym) | ||
| 207 | continue; | ||
| 208 | writeHeader(OS, Cmd->Addr, OSec->getLMA() + Cmd->Addr - OSec->getVA(0), | ||
| 209 | Cmd->Size, 1); | ||
| 210 | OS << Indent8 << Cmd->CommandString << '\n'; | ||
| 143 | continue; | 211 | continue; |
| 144 | for (InputSection *IS : ISD->Sections) { | ||
| 145 | writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), | ||
| 146 | IS->Alignment); | ||
| 147 | OS << indent(1) << toString(IS) << '\n'; | ||
| 148 | for (Symbol *Sym : SectionSyms[IS]) | ||
| 149 | OS << SymStr[Sym] << '\n'; | ||
| 150 | } | 212 | } |
| 151 | } | 213 | } |
| 152 | } | 214 | } |
| 153 | } | 215 | } |
| 216 | |||
| 217 | static void print(StringRef A, StringRef B) { | ||
| 218 | outs() << left_justify(A, 49) << " " << B << "\n"; | ||
| 219 | } | ||
| 220 | |||
| 221 | // Output a cross reference table to stdout. This is for --cref. | ||
| 222 | // | ||
| 223 | // For each global symbol, we print out a file that defines the symbol | ||
| 224 | // followed by files that uses that symbol. Here is an example. | ||
| 225 | // | ||
| 226 | // strlen /lib/x86_64-linux-gnu/libc.so.6 | ||
| 227 | // tools/lld/tools/lld/CMakeFiles/lld.dir/lld.cpp.o | ||
| 228 | // lib/libLLVMSupport.a(PrettyStackTrace.cpp.o) | ||
| 229 | // | ||
| 230 | // In this case, strlen is defined by libc.so.6 and used by other two | ||
| 231 | // files. | ||
| 232 | void elf::writeCrossReferenceTable() { | ||
| 233 | if (!Config->Cref) | ||
| 234 | return; | ||
| 235 | |||
| 236 | // Collect symbols and files. | ||
| 237 | MapVector<Symbol *, SetVector<InputFile *>> Map; | ||
| 238 | for (InputFile *File : ObjectFiles) { | ||
| 239 | for (Symbol *Sym : File->getSymbols()) { | ||
| 240 | if (isa<SharedSymbol>(Sym)) | ||
| 241 | Map[Sym].insert(File); | ||
| 242 | if (auto *D = dyn_cast<Defined>(Sym)) | ||
| 243 | if (!D->isLocal() && (!D->Section || D->Section->Live)) | ||
| 244 | Map[D].insert(File); | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | // Print out a header. | ||
| 249 | outs() << "Cross Reference Table\n\n"; | ||
| 250 | print("Symbol", "File"); | ||
| 251 | |||
| 252 | // Print out a table. | ||
| 253 | for (auto KV : Map) { | ||
| 254 | Symbol *Sym = KV.first; | ||
| 255 | SetVector<InputFile *> &Files = KV.second; | ||
| 256 | |||
| 257 | print(toString(*Sym), toString(Sym->File)); | ||
| 258 | for (InputFile *File : Files) | ||
| 259 | if (File != Sym->File) | ||
| 260 | print("", toString(File)); | ||
| 261 | } | ||
| 262 | } |
deps/lld/ELF/MapFile.h+1| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | namespace lld { | 13 | namespace lld { |
| 14 | namespace elf { | 14 | namespace elf { |
| 15 | void writeMapFile(); | 15 | void writeMapFile(); |
| 16 | void writeCrossReferenceTable(); | ||
| 16 | } // namespace elf | 17 | } // namespace elf |
| 17 | } // namespace lld | 18 | } // namespace lld |
| 18 | 19 |
deps/lld/ELF/MarkLive.cpp+20-27| ... | @@ -20,15 +20,15 @@ | ... | @@ -20,15 +20,15 @@ |
| 20 | // | 20 | // |
| 21 | //===----------------------------------------------------------------------===// | 21 | //===----------------------------------------------------------------------===// |
| 22 | 22 | ||
| 23 | #include "MarkLive.h" | ||
| 23 | #include "InputSection.h" | 24 | #include "InputSection.h" |
| 24 | #include "LinkerScript.h" | 25 | #include "LinkerScript.h" |
| 25 | #include "OutputSections.h" | 26 | #include "OutputSections.h" |
| 26 | #include "Strings.h" | ||
| 27 | #include "SymbolTable.h" | 27 | #include "SymbolTable.h" |
| 28 | #include "Symbols.h" | 28 | #include "Symbols.h" |
| 29 | #include "Target.h" | 29 | #include "Target.h" |
| 30 | #include "Writer.h" | ||
| 31 | #include "lld/Common/Memory.h" | 30 | #include "lld/Common/Memory.h" |
| 31 | #include "lld/Common/Strings.h" | ||
| 32 | #include "llvm/ADT/STLExtras.h" | 32 | #include "llvm/ADT/STLExtras.h" |
| 33 | #include "llvm/Object/ELF.h" | 33 | #include "llvm/Object/ELF.h" |
| 34 | #include <functional> | 34 | #include <functional> |
| ... | @@ -60,8 +60,9 @@ static typename ELFT::uint getAddend(InputSectionBase &Sec, | ... | @@ -60,8 +60,9 @@ static typename ELFT::uint getAddend(InputSectionBase &Sec, |
| 60 | static DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections; | 60 | static DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections; |
| 61 | 61 | ||
| 62 | template <class ELFT, class RelT> | 62 | template <class ELFT, class RelT> |
| 63 | static void resolveReloc(InputSectionBase &Sec, RelT &Rel, | 63 | static void |
| 64 | std::function<void(InputSectionBase *, uint64_t)> Fn) { | 64 | resolveReloc(InputSectionBase &Sec, RelT &Rel, |
| 65 | llvm::function_ref<void(InputSectionBase *, uint64_t)> Fn) { | ||
| 65 | Symbol &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); | 66 | Symbol &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); |
| 66 | 67 | ||
| 67 | // If a symbol is referenced in a live section, it is used. | 68 | // If a symbol is referenced in a live section, it is used. |
| ... | @@ -90,7 +91,7 @@ static void resolveReloc(InputSectionBase &Sec, RelT &Rel, | ... | @@ -90,7 +91,7 @@ static void resolveReloc(InputSectionBase &Sec, RelT &Rel, |
| 90 | template <class ELFT> | 91 | template <class ELFT> |
| 91 | static void | 92 | static void |
| 92 | forEachSuccessor(InputSection &Sec, | 93 | forEachSuccessor(InputSection &Sec, |
| 93 | std::function<void(InputSectionBase *, uint64_t)> Fn) { | 94 | llvm::function_ref<void(InputSectionBase *, uint64_t)> Fn) { |
| 94 | if (Sec.AreRelocsRela) { | 95 | if (Sec.AreRelocsRela) { |
| 95 | for (const typename ELFT::Rela &Rel : Sec.template relas<ELFT>()) | 96 | for (const typename ELFT::Rela &Rel : Sec.template relas<ELFT>()) |
| 96 | resolveReloc<ELFT>(Sec, Rel, Fn); | 97 | resolveReloc<ELFT>(Sec, Rel, Fn); |
| ... | @@ -120,7 +121,7 @@ forEachSuccessor(InputSection &Sec, | ... | @@ -120,7 +121,7 @@ forEachSuccessor(InputSection &Sec, |
| 120 | template <class ELFT, class RelTy> | 121 | template <class ELFT, class RelTy> |
| 121 | static void | 122 | static void |
| 122 | scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels, | 123 | scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels, |
| 123 | std::function<void(InputSectionBase *, uint64_t)> Fn) { | 124 | llvm::function_ref<void(InputSectionBase *, uint64_t)> Fn) { |
| 124 | const endianness E = ELFT::TargetEndianness; | 125 | const endianness E = ELFT::TargetEndianness; |
| 125 | 126 | ||
| 126 | for (unsigned I = 0, N = EH.Pieces.size(); I < N; ++I) { | 127 | for (unsigned I = 0, N = EH.Pieces.size(); I < N; ++I) { |
| ... | @@ -155,14 +156,10 @@ scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels, | ... | @@ -155,14 +156,10 @@ scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels, |
| 155 | template <class ELFT> | 156 | template <class ELFT> |
| 156 | static void | 157 | static void |
| 157 | scanEhFrameSection(EhInputSection &EH, | 158 | scanEhFrameSection(EhInputSection &EH, |
| 158 | std::function<void(InputSectionBase *, uint64_t)> Fn) { | 159 | llvm::function_ref<void(InputSectionBase *, uint64_t)> Fn) { |
| 159 | if (!EH.NumRelocations) | 160 | if (!EH.NumRelocations) |
| 160 | return; | 161 | return; |
| 161 | 162 | ||
| 162 | // Unfortunately we need to split .eh_frame early since some relocations in | ||
| 163 | // .eh_frame keep other section alive and some don't. | ||
| 164 | EH.split<ELFT>(); | ||
| 165 | |||
| 166 | if (EH.AreRelocsRela) | 163 | if (EH.AreRelocsRela) |
| 167 | scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Fn); | 164 | scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Fn); |
| 168 | else | 165 | else |
| ... | @@ -207,7 +204,7 @@ template <class ELFT> static void doGcSections() { | ... | @@ -207,7 +204,7 @@ template <class ELFT> static void doGcSections() { |
| 207 | // (splittable) sections, each piece of data has independent liveness bit. | 204 | // (splittable) sections, each piece of data has independent liveness bit. |
| 208 | // So we explicitly tell it which offset is in use. | 205 | // So we explicitly tell it which offset is in use. |
| 209 | if (auto *MS = dyn_cast<MergeInputSection>(Sec)) | 206 | if (auto *MS = dyn_cast<MergeInputSection>(Sec)) |
| 210 | MS->markLiveAt(Offset); | 207 | MS->getSectionPiece(Offset)->Live = true; |
| 211 | 208 | ||
| 212 | if (Sec->Live) | 209 | if (Sec->Live) |
| 213 | return; | 210 | return; |
| ... | @@ -279,13 +276,18 @@ template <class ELFT> void elf::markLive() { | ... | @@ -279,13 +276,18 @@ template <class ELFT> void elf::markLive() { |
| 279 | 276 | ||
| 280 | // The -gc-sections option works only for SHF_ALLOC sections | 277 | // The -gc-sections option works only for SHF_ALLOC sections |
| 281 | // (sections that are memory-mapped at runtime). So we can | 278 | // (sections that are memory-mapped at runtime). So we can |
| 282 | // unconditionally make non-SHF_ALLOC sections alive. | 279 | // unconditionally make non-SHF_ALLOC sections alive except |
| 280 | // SHF_LINK_ORDER and SHT_REL/SHT_RELA sections. | ||
| 283 | // | 281 | // |
| 284 | // Non SHF_ALLOC sections are not removed even if they are | 282 | // Usually, SHF_ALLOC sections are not removed even if they are |
| 285 | // unreachable through relocations because reachability is not | 283 | // unreachable through relocations because reachability is not |
| 286 | // a good signal whether they are garbage or not (e.g. there is | 284 | // a good signal whether they are garbage or not (e.g. there is |
| 287 | // usually no section referring to a .comment section, but we | 285 | // usually no section referring to a .comment section, but we |
| 288 | // want to keep it.) | 286 | // want to keep it.). |
| 287 | // | ||
| 288 | // Note on SHF_LINK_ORDER: Such sections contain metadata and they | ||
| 289 | // have a reverse dependency on the InputSection they are linked with. | ||
| 290 | // We are able to garbage collect them. | ||
| 289 | // | 291 | // |
| 290 | // Note on SHF_REL{,A}: Such sections reach here only when -r | 292 | // Note on SHF_REL{,A}: Such sections reach here only when -r |
| 291 | // or -emit-reloc were given. And they are subject of garbage | 293 | // or -emit-reloc were given. And they are subject of garbage |
| ... | @@ -293,29 +295,20 @@ template <class ELFT> void elf::markLive() { | ... | @@ -293,29 +295,20 @@ template <class ELFT> void elf::markLive() { |
| 293 | // remove its relocation section. | 295 | // remove its relocation section. |
| 294 | for (InputSectionBase *Sec : InputSections) { | 296 | for (InputSectionBase *Sec : InputSections) { |
| 295 | bool IsAlloc = (Sec->Flags & SHF_ALLOC); | 297 | bool IsAlloc = (Sec->Flags & SHF_ALLOC); |
| 298 | bool IsLinkOrder = (Sec->Flags & SHF_LINK_ORDER); | ||
| 296 | bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA); | 299 | bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA); |
| 297 | if (!IsAlloc && !IsRel) | 300 | if (!IsAlloc && !IsLinkOrder && !IsRel) |
| 298 | Sec->Live = true; | 301 | Sec->Live = true; |
| 299 | } | 302 | } |
| 300 | 303 | ||
| 301 | // Follow the graph to mark all live sections. | 304 | // Follow the graph to mark all live sections. |
| 302 | doGcSections<ELFT>(); | 305 | doGcSections<ELFT>(); |
| 303 | 306 | ||
| 304 | // If all references to a DSO happen to be weak, the DSO is removed from | ||
| 305 | // DT_NEEDED, which creates dangling shared symbols to non-existent DSO. | ||
| 306 | // We'll replace such symbols with undefined ones to fix it. | ||
| 307 | for (Symbol *Sym : Symtab->getSymbols()) | ||
| 308 | if (auto *S = dyn_cast<SharedSymbol>(Sym)) | ||
| 309 | if (S->isWeak() && !S->getFile<ELFT>().IsNeeded) | ||
| 310 | replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther, | ||
| 311 | S->Type); | ||
| 312 | |||
| 313 | // Report garbage-collected sections. | 307 | // Report garbage-collected sections. |
| 314 | if (Config->PrintGcSections) | 308 | if (Config->PrintGcSections) |
| 315 | for (InputSectionBase *Sec : InputSections) | 309 | for (InputSectionBase *Sec : InputSections) |
| 316 | if (!Sec->Live) | 310 | if (!Sec->Live) |
| 317 | message("removing unused section from '" + Sec->Name + "' in file '" + | 311 | message("removing unused section " + toString(Sec)); |
| 318 | Sec->File->getName() + "'"); | ||
| 319 | } | 312 | } |
| 320 | 313 | ||
| 321 | template void elf::markLive<ELF32LE>(); | 314 | template void elf::markLive<ELF32LE>(); |
deps/lld/ELF/MarkLive.h created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | //===- MarkLive.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_MARKLIVE_H | ||
| 11 | #define LLD_ELF_MARKLIVE_H | ||
| 12 | |||
| 13 | namespace lld { | ||
| 14 | namespace elf { | ||
| 15 | |||
| 16 | template <class ELFT> void markLive(); | ||
| 17 | |||
| 18 | } // namespace elf | ||
| 19 | } // namespace lld | ||
| 20 | |||
| 21 | #endif // LLD_ELF_MARKLIVE_H | ||
deps/lld/ELF/Options.td+293-231| ... | @@ -4,66 +4,91 @@ include "llvm/Option/OptParser.td" | ... | @@ -4,66 +4,91 @@ include "llvm/Option/OptParser.td" |
| 4 | // two can precede the option name except those that start with 'o'. | 4 | // two can precede the option name except those that start with 'o'. |
| 5 | class F<string name>: Flag<["--", "-"], name>; | 5 | class F<string name>: Flag<["--", "-"], name>; |
| 6 | class J<string name>: Joined<["--", "-"], name>; | 6 | class J<string name>: Joined<["--", "-"], name>; |
| 7 | class S<string name>: Separate<["--", "-"], name>; | ||
| 8 | 7 | ||
| 9 | multiclass Eq<string name> { | 8 | multiclass Eq<string name, string help> { |
| 10 | def "": Separate<["--", "-"], name>; | 9 | def NAME: Separate<["--", "-"], name>; |
| 11 | def _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>; | 10 | def NAME # _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>, |
| 11 | HelpText<help>; | ||
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | def auxiliary: S<"auxiliary">, HelpText<"Set DT_AUXILIARY field to the specified name">; | 14 | multiclass B<string name, string help1, string help2> { |
| 15 | def NAME: Flag<["--", "-"], name>, HelpText<help1>; | ||
| 16 | def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>; | ||
| 17 | } | ||
| 18 | |||
| 19 | defm auxiliary: Eq<"auxiliary", "Set DT_AUXILIARY field to the specified name">; | ||
| 15 | 20 | ||
| 16 | def Bsymbolic: F<"Bsymbolic">, HelpText<"Bind defined symbols locally">; | 21 | def Bsymbolic: F<"Bsymbolic">, HelpText<"Bind defined symbols locally">; |
| 17 | 22 | ||
| 18 | def Bsymbolic_functions: F<"Bsymbolic-functions">, | 23 | def Bsymbolic_functions: F<"Bsymbolic-functions">, |
| 19 | HelpText<"Bind defined function symbols locally">; | 24 | HelpText<"Bind defined function symbols locally">; |
| 20 | 25 | ||
| 21 | def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">; | 26 | def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries (default)">; |
| 22 | 27 | ||
| 23 | def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">; | 28 | def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">; |
| 24 | 29 | ||
| 25 | def build_id: F<"build-id">, HelpText<"Generate build ID note">; | 30 | def build_id: F<"build-id">, HelpText<"Alias for --build-id=fast">; |
| 31 | |||
| 32 | def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">, | ||
| 33 | MetaVarName<"[fast,md5,sha,uuid,0x<hexstring>]">; | ||
| 26 | 34 | ||
| 27 | def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">; | 35 | defm check_sections: B<"check-sections", |
| 36 | "Check section addresses for overlaps (default)", | ||
| 37 | "Do not check section addresses for overlaps">; | ||
| 28 | 38 | ||
| 29 | defm compress_debug_sections : Eq<"compress-debug-sections">, | 39 | defm compress_debug_sections: |
| 30 | HelpText<"Compress DWARF debug sections">; | 40 | Eq<"compress-debug-sections", "Compress DWARF debug sections">, |
| 41 | MetaVarName<"[none,zlib]">; | ||
| 31 | 42 | ||
| 32 | defm defsym: Eq<"defsym">, HelpText<"Define a symbol alias">; | 43 | defm defsym: Eq<"defsym", "Define a symbol alias">, MetaVarName<"<symbol>=<value>">; |
| 33 | 44 | ||
| 34 | defm library_path: Eq<"library-path">, | 45 | defm library_path: |
| 35 | HelpText<"Add a directory to the library search path">, MetaVarName<"<dir>">; | 46 | Eq<"library-path", "Add a directory to the library search path">, MetaVarName<"<dir>">; |
| 36 | 47 | ||
| 37 | def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">; | 48 | def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">; |
| 38 | 49 | ||
| 39 | defm Tbss: Eq<"Tbss">, | 50 | defm Tbss: Eq<"Tbss", "Same as --section-start with .bss as the sectionname">; |
| 40 | HelpText<"Same as --section-start with .bss as the sectionname">; | ||
| 41 | 51 | ||
| 42 | defm Tdata: Eq<"Tdata">, | 52 | defm Tdata: Eq<"Tdata", "Same as --section-start with .data as the sectionname">; |
| 43 | HelpText<"Same as --section-start with .data as the sectionname">; | ||
| 44 | 53 | ||
| 45 | defm Ttext: Eq<"Ttext">, | 54 | defm Ttext: Eq<"Ttext", "Same as --section-start with .text as the sectionname">; |
| 46 | HelpText<"Same as --section-start with .text as the sectionname">; | ||
| 47 | 55 | ||
| 48 | def allow_multiple_definition: F<"allow-multiple-definition">, | 56 | defm allow_multiple_definition: B<"allow-multiple-definition", |
| 49 | HelpText<"Allow multiple definitions">; | 57 | "Allow multiple definitions", |
| 58 | "Do not allow multiple definitions (default)">; | ||
| 50 | 59 | ||
| 51 | def as_needed: F<"as-needed">, | 60 | defm apply_dynamic_relocs: B<"apply-dynamic-relocs", |
| 52 | HelpText<"Only set DT_NEEDED for shared libraries if used">; | 61 | "Apply link-time values for dynamic relocations", |
| 62 | "Do not apply link-time values for dynamic relocations (default)">; | ||
| 63 | |||
| 64 | defm as_needed: B<"as-needed", | ||
| 65 | "Only set DT_NEEDED for shared libraries if used", | ||
| 66 | "Always set DT_NEEDED for shared libraries (default)">; | ||
| 67 | |||
| 68 | defm call_graph_ordering_file: | ||
| 69 | Eq<"call-graph-ordering-file", "Layout sections to optimize the given callgraph">; | ||
| 53 | 70 | ||
| 54 | // -chroot doesn't have a help text because it is an internal option. | 71 | // -chroot doesn't have a help text because it is an internal option. |
| 55 | def chroot: S<"chroot">; | 72 | def chroot: Separate<["--", "-"], "chroot">; |
| 56 | 73 | ||
| 57 | def color_diagnostics: F<"color-diagnostics">, | 74 | def color_diagnostics: F<"color-diagnostics">, |
| 58 | HelpText<"Use colors in diagnostics">; | 75 | HelpText<"Alias for --color-diagnostics=always">; |
| 59 | 76 | ||
| 60 | def color_diagnostics_eq: J<"color-diagnostics=">, | 77 | def color_diagnostics_eq: J<"color-diagnostics=">, |
| 61 | HelpText<"Use colors in diagnostics">; | 78 | HelpText<"Use colors in diagnostics">, |
| 79 | MetaVarName<"[auto,always,never]">; | ||
| 80 | |||
| 81 | defm cref: B<"cref", | ||
| 82 | "Output cross reference table", | ||
| 83 | "Do not output cross reference table">; | ||
| 62 | 84 | ||
| 63 | def define_common: F<"define-common">, | 85 | defm define_common: B<"define-common", |
| 64 | HelpText<"Assign space to common symbols">; | 86 | "Assign space to common symbols", |
| 87 | "Do not assign space to common symbols">; | ||
| 65 | 88 | ||
| 66 | def demangle: F<"demangle">, HelpText<"Demangle symbol names">; | 89 | defm demangle: B<"demangle", |
| 90 | "Demangle symbol names (default)", | ||
| 91 | "Do not demangle symbol names">; | ||
| 67 | 92 | ||
| 68 | def disable_new_dtags: F<"disable-new-dtags">, | 93 | def disable_new_dtags: F<"disable-new-dtags">, |
| 69 | HelpText<"Disable new dynamic tags">; | 94 | HelpText<"Disable new dynamic tags">; |
| ... | @@ -76,158 +101,130 @@ def discard_locals: F<"discard-locals">, | ... | @@ -76,158 +101,130 @@ def discard_locals: F<"discard-locals">, |
| 76 | def discard_none: F<"discard-none">, | 101 | def discard_none: F<"discard-none">, |
| 77 | HelpText<"Keep all symbols in the symbol table">; | 102 | HelpText<"Keep all symbols in the symbol table">; |
| 78 | 103 | ||
| 79 | def dynamic_linker: S<"dynamic-linker">, | 104 | defm dynamic_linker: Eq<"dynamic-linker", "Which dynamic linker to use">; |
| 80 | HelpText<"Which dynamic linker to use">; | ||
| 81 | 105 | ||
| 82 | defm dynamic_list: Eq<"dynamic-list">, | 106 | defm dynamic_list: Eq<"dynamic-list", "Read a list of dynamic symbols">; |
| 83 | HelpText<"Read a list of dynamic symbols">; | ||
| 84 | 107 | ||
| 85 | def eh_frame_hdr: F<"eh-frame-hdr">, | 108 | defm eh_frame_hdr: B<"eh-frame-hdr", |
| 86 | HelpText<"Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header">; | 109 | "Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header", |
| 110 | "Do not create .eh_frame_hdr section">; | ||
| 87 | 111 | ||
| 88 | def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">; | 112 | def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">; |
| 89 | 113 | ||
| 90 | def enable_new_dtags: F<"enable-new-dtags">, | 114 | def enable_new_dtags: F<"enable-new-dtags">, |
| 91 | HelpText<"Enable new dynamic tags">; | 115 | HelpText<"Enable new dynamic tags (default)">; |
| 116 | |||
| 117 | def end_group: F<"end-group">, | ||
| 118 | HelpText<"Ignored for compatibility with GNU unless you pass --warn-backrefs">; | ||
| 92 | 119 | ||
| 93 | def end_lib: F<"end-lib">, | 120 | def end_lib: F<"end-lib">, |
| 94 | HelpText<"End a grouping of objects that should be treated as if they were together in an archive">; | 121 | HelpText<"End a grouping of objects that should be treated as if they were together in an archive">; |
| 95 | 122 | ||
| 96 | defm entry: Eq<"entry">, HelpText<"Name of entry point symbol">, | 123 | defm entry: Eq<"entry", "Name of entry point symbol">, |
| 97 | MetaVarName<"<entry>">; | 124 | MetaVarName<"<entry>">; |
| 98 | 125 | ||
| 99 | defm error_limit: Eq<"error-limit">, | 126 | defm error_limit: |
| 100 | HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">; | 127 | Eq<"error-limit", "Maximum number of errors to emit before stopping (0 = no limit)">; |
| 101 | 128 | ||
| 102 | def error_unresolved_symbols: F<"error-unresolved-symbols">, | 129 | def error_unresolved_symbols: F<"error-unresolved-symbols">, |
| 103 | HelpText<"Report unresolved symbols as errors">; | 130 | HelpText<"Report unresolved symbols as errors">; |
| 104 | 131 | ||
| 105 | defm exclude_libs: Eq<"exclude-libs">, | 132 | defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">; |
| 106 | HelpText<"Exclude static libraries from automatic export">; | 133 | |
| 134 | defm execute_only: B<"execute-only", | ||
| 135 | "Do not mark executable sections readable", | ||
| 136 | "Mark executable sections readable (default)">; | ||
| 107 | 137 | ||
| 108 | def export_dynamic: F<"export-dynamic">, | 138 | defm export_dynamic: B<"export-dynamic", |
| 109 | HelpText<"Put symbols in the dynamic symbol table">; | 139 | "Put symbols in the dynamic symbol table", |
| 140 | "Do not put symbols in the dynamic symbol table (default)">; | ||
| 110 | 141 | ||
| 111 | defm export_dynamic_symbol: Eq<"export-dynamic-symbol">, | 142 | defm export_dynamic_symbol: |
| 112 | HelpText<"Put a symbol in the dynamic symbol table">; | 143 | Eq<"export-dynamic-symbol", "Put a symbol in the dynamic symbol table">; |
| 113 | 144 | ||
| 114 | def fatal_warnings: F<"fatal-warnings">, | 145 | defm fatal_warnings: B<"fatal-warnings", |
| 115 | HelpText<"Treat warnings as errors">; | 146 | "Treat warnings as errors", |
| 147 | "Do not treat warnings as errors (default)">; | ||
| 116 | 148 | ||
| 117 | defm filter: Eq<"filter">, | 149 | defm filter: Eq<"filter", "Set DT_FILTER field to the specified name">; |
| 118 | HelpText<"Set DT_FILTER field to the specified name">; | ||
| 119 | 150 | ||
| 120 | defm fini: Eq<"fini">, | 151 | defm fini: Eq<"fini", "Specify a finalizer function">, MetaVarName<"<symbol>">; |
| 121 | HelpText<"Specify a finalizer function">, MetaVarName<"<symbol>">; | ||
| 122 | 152 | ||
| 123 | def fix_cortex_a53_843419: F<"fix-cortex-a53-843419">, | 153 | def fix_cortex_a53_843419: F<"fix-cortex-a53-843419">, |
| 124 | HelpText<"Apply fixes for AArch64 Cortex-A53 erratum 843419">; | 154 | HelpText<"Apply fixes for AArch64 Cortex-A53 erratum 843419">; |
| 125 | 155 | ||
| 126 | def full_shutdown : F<"full-shutdown">, | 156 | defm format: Eq<"format", "Change the input format of the inputs following this option">, |
| 127 | HelpText<"Perform a full shutdown instead of calling _exit">; | 157 | MetaVarName<"[default,elf,binary]">; |
| 128 | 158 | ||
| 129 | defm format: Eq<"format">, | 159 | defm gc_sections: B<"gc-sections", |
| 130 | HelpText<"Change the input format of the inputs following this option">, | 160 | "Enable garbage collection of unused sections", |
| 131 | MetaVarName<"<input-format>">; | 161 | "Disable garbage collection of unused sections (default)">; |
| 132 | 162 | ||
| 133 | def gc_sections: F<"gc-sections">, | 163 | defm gdb_index: B<"gdb-index", |
| 134 | HelpText<"Enable garbage collection of unused sections">; | 164 | "Generate .gdb_index section", |
| 165 | "Do not generate .gdb_index section (default)">; | ||
| 135 | 166 | ||
| 136 | def gdb_index: F<"gdb-index">, | 167 | defm gnu_unique: B<"gnu-unique", |
| 137 | HelpText<"Generate .gdb_index section">; | 168 | "Enable STB_GNU_UNIQUE symbol binding (default)", |
| 169 | "Disable STB_GNU_UNIQUE symbol binding">; | ||
| 138 | 170 | ||
| 139 | defm hash_style: Eq<"hash-style">, | 171 | defm hash_style: Eq<"hash-style", "Specify hash style (sysv, gnu or both)">; |
| 140 | HelpText<"Specify hash style (sysv, gnu or both)">; | ||
| 141 | 172 | ||
| 142 | def help: F<"help">, HelpText<"Print option help">; | 173 | def help: F<"help">, HelpText<"Print option help">; |
| 143 | 174 | ||
| 144 | def icf_all: F<"icf=all">, HelpText<"Enable identical code folding">; | 175 | def icf_all: F<"icf=all">, HelpText<"Enable identical code folding">; |
| 145 | 176 | ||
| 146 | def icf_data: F<"icf-data">, | 177 | def icf_safe: F<"icf=safe">, HelpText<"Enable safe identical code folding">; |
| 147 | HelpText<"Enable ICF to also fold identical read only data">; | 178 | |
| 179 | def icf_none: F<"icf=none">, HelpText<"Disable identical code folding (default)">; | ||
| 148 | 180 | ||
| 149 | def icf_none: F<"icf=none">, HelpText<"Disable identical code folding">; | 181 | def ignore_function_address_equality: F<"ignore-function-address-equality">, |
| 182 | HelpText<"lld can break the address equality of functions">; | ||
| 150 | 183 | ||
| 151 | defm image_base : Eq<"image-base">, HelpText<"Set the base address">; | 184 | def ignore_data_address_equality: F<"ignore-data-address-equality">, |
| 185 | HelpText<"lld can break the address equality of data">; | ||
| 152 | 186 | ||
| 153 | defm init: Eq<"init">, HelpText<"Specify an initializer function">, | 187 | defm image_base: Eq<"image-base", "Set the base address">; |
| 188 | |||
| 189 | defm init: Eq<"init", "Specify an initializer function">, | ||
| 154 | MetaVarName<"<symbol>">; | 190 | MetaVarName<"<symbol>">; |
| 155 | 191 | ||
| 156 | defm library: Eq<"library">, HelpText<"Root name of library to use">, | 192 | defm just_symbols: Eq<"just-symbols", "Just link symbols">; |
| 157 | MetaVarName<"<libName>">; | ||
| 158 | 193 | ||
| 159 | def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">, | 194 | defm keep_unique: Eq<"keep-unique", "Do not fold this symbol during ICF">; |
| 160 | HelpText<"Optimization level for LTO">; | 195 | |
| 196 | defm library: Eq<"library", "Root name of library to use">, | ||
| 197 | MetaVarName<"<libName>">; | ||
| 161 | 198 | ||
| 162 | def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">; | 199 | def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">; |
| 163 | 200 | ||
| 164 | defm Map: Eq<"Map">, HelpText<"Print a link map to the specified file">; | 201 | defm Map: Eq<"Map", "Print a link map to the specified file">; |
| 165 | 202 | ||
| 166 | def merge_exidx_entries: F<"merge-exidx-entries">, | 203 | defm merge_exidx_entries: B<"merge-exidx-entries", |
| 167 | HelpText<"Enable merging .ARM.exidx entries">; | 204 | "Enable merging .ARM.exidx entries (default)", |
| 205 | "Disable merging .ARM.exidx entries">; | ||
| 168 | 206 | ||
| 169 | def nostdlib: F<"nostdlib">, | 207 | def nostdlib: F<"nostdlib">, |
| 170 | HelpText<"Only search directories specified on the command line">; | 208 | HelpText<"Only search directories specified on the command line">; |
| 171 | 209 | ||
| 172 | def no_as_needed: F<"no-as-needed">, | ||
| 173 | HelpText<"Always DT_NEEDED for shared libraries">; | ||
| 174 | |||
| 175 | def no_color_diagnostics: F<"no-color-diagnostics">, | 210 | def no_color_diagnostics: F<"no-color-diagnostics">, |
| 176 | HelpText<"Do not use colors in diagnostics">; | 211 | HelpText<"Do not use colors in diagnostics">; |
| 177 | 212 | ||
| 178 | def no_define_common: F<"no-define-common">, | ||
| 179 | HelpText<"Do not assign space to common symbols">; | ||
| 180 | |||
| 181 | def no_demangle: F<"no-demangle">, | ||
| 182 | HelpText<"Do not demangle symbol names">; | ||
| 183 | |||
| 184 | def no_dynamic_linker: F<"no-dynamic-linker">, | 213 | def no_dynamic_linker: F<"no-dynamic-linker">, |
| 185 | HelpText<"Inhibit output of .interp section">; | 214 | HelpText<"Inhibit output of .interp section">; |
| 186 | 215 | ||
| 187 | def no_eh_frame_hdr: F<"no-eh-frame-hdr">, | ||
| 188 | HelpText<"Do not create .eh_frame_hdr section">; | ||
| 189 | |||
| 190 | def no_export_dynamic: F<"no-export-dynamic">; | ||
| 191 | def no_fatal_warnings: F<"no-fatal-warnings">; | ||
| 192 | |||
| 193 | def no_gc_sections: F<"no-gc-sections">, | ||
| 194 | HelpText<"Disable garbage collection of unused sections">; | ||
| 195 | |||
| 196 | def no_gdb_index: F<"no-gdb-index">, | ||
| 197 | HelpText<"Do not generate .gdb_index section">; | ||
| 198 | |||
| 199 | def no_gnu_unique: F<"no-gnu-unique">, | ||
| 200 | HelpText<"Disable STB_GNU_UNIQUE symbol binding">; | ||
| 201 | |||
| 202 | def no_merge_exidx_entries: F<"no-merge-exidx-entries">, | ||
| 203 | HelpText<"Disable merging .ARM.exidx entries">; | ||
| 204 | |||
| 205 | def no_threads: F<"no-threads">, | ||
| 206 | HelpText<"Do not run the linker multi-threaded">; | ||
| 207 | |||
| 208 | def no_whole_archive: F<"no-whole-archive">, | ||
| 209 | HelpText<"Restores the default behavior of loading archive members">; | ||
| 210 | |||
| 211 | def noinhibit_exec: F<"noinhibit-exec">, | 216 | def noinhibit_exec: F<"noinhibit-exec">, |
| 212 | HelpText<"Retain the executable output file whenever it is still usable">; | 217 | HelpText<"Retain the executable output file whenever it is still usable">; |
| 213 | 218 | ||
| 214 | def nopie: F<"nopie">, HelpText<"Do not create a position independent executable">; | 219 | def no_omagic: F<"no-omagic">, MetaVarName<"<magic>">, |
| 215 | |||
| 216 | def no_omagic: Flag<["--"], "no-omagic">, MetaVarName<"<magic>">, | ||
| 217 | HelpText<"Do not set the text data sections to be writable">; | 220 | HelpText<"Do not set the text data sections to be writable">; |
| 218 | 221 | ||
| 219 | def no_print_gc_sections: F<"no-print-gc-sections">, | ||
| 220 | HelpText<"Do not list removed unused sections">; | ||
| 221 | |||
| 222 | def no_rosegment: F<"no-rosegment">, | 222 | def no_rosegment: F<"no-rosegment">, |
| 223 | HelpText<"Do not put read-only non-executable sections in their own segment">; | 223 | HelpText<"Do not put read-only non-executable sections in their own segment">; |
| 224 | 224 | ||
| 225 | def no_undefined: F<"no-undefined">, | 225 | def no_undefined: F<"no-undefined">, |
| 226 | HelpText<"Report unresolved symbols even if the linker is creating a shared library">; | 226 | HelpText<"Report unresolved symbols even if the linker is creating a shared library">; |
| 227 | 227 | ||
| 228 | def no_undefined_version: F<"no-undefined-version">, | ||
| 229 | HelpText<"Report version scripts that refer undefined symbols">; | ||
| 230 | |||
| 231 | def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">, | 228 | def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">, |
| 232 | HelpText<"Path to file to write output">; | 229 | HelpText<"Path to file to write output">; |
| 233 | 230 | ||
| ... | @@ -237,42 +234,62 @@ def oformat: Separate<["--"], "oformat">, MetaVarName<"<format>">, | ... | @@ -237,42 +234,62 @@ def oformat: Separate<["--"], "oformat">, MetaVarName<"<format>">, |
| 237 | def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">, | 234 | def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">, |
| 238 | HelpText<"Set the text and data sections to be readable and writable">; | 235 | HelpText<"Set the text and data sections to be readable and writable">; |
| 239 | 236 | ||
| 240 | defm orphan_handling: Eq<"orphan-handling">, | 237 | defm orphan_handling: |
| 241 | HelpText<"Control how orphan sections are handled when linker script used">; | 238 | Eq<"orphan-handling", "Control how orphan sections are handled when linker script used">; |
| 239 | |||
| 240 | defm pack_dyn_relocs: | ||
| 241 | Eq<"pack-dyn-relocs", "Pack dynamic relocations in the given format">, | ||
| 242 | MetaVarName<"[none,android,relr,android+relr]">; | ||
| 243 | |||
| 244 | defm use_android_relr_tags: B<"use-android-relr-tags", | ||
| 245 | "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*", | ||
| 246 | "Use SHT_RELR / DT_RELR* tags (default)">; | ||
| 247 | |||
| 248 | defm pie: B<"pie", | ||
| 249 | "Create a position independent executable", | ||
| 250 | "Do not create a position independent executable (default)">; | ||
| 251 | |||
| 252 | defm print_gc_sections: B<"print-gc-sections", | ||
| 253 | "List removed unused sections", | ||
| 254 | "Do not list removed unused sections (default)">; | ||
| 242 | 255 | ||
| 243 | def pack_dyn_relocs_eq: J<"pack-dyn-relocs=">, MetaVarName<"<format>">, | 256 | defm print_icf_sections: B<"print-icf-sections", |
| 244 | HelpText<"Pack dynamic relocations in the given format (none or android)">; | 257 | "List identical folded sections", |
| 258 | "Do not list identical folded sections (default)">; | ||
| 245 | 259 | ||
| 246 | def pie: F<"pie">, HelpText<"Create a position independent executable">; | 260 | def pop_state: F<"pop-state">, |
| 261 | HelpText<"Undo the effect of -push-state">; | ||
| 247 | 262 | ||
| 248 | def print_gc_sections: F<"print-gc-sections">, | 263 | def push_state: F<"push-state">, |
| 249 | HelpText<"List removed unused sections">; | 264 | HelpText<"Save the current state of -as-needed, -static and -whole-archive">; |
| 250 | 265 | ||
| 251 | def print_map: F<"print-map">, | 266 | def print_map: F<"print-map">, |
| 252 | HelpText<"Print a link map to the standard output">; | 267 | HelpText<"Print a link map to the standard output">; |
| 253 | 268 | ||
| 254 | defm reproduce: Eq<"reproduce">, | 269 | defm reproduce: Eq<"reproduce", "Dump linker invocation and input files for debugging">; |
| 255 | HelpText<"Dump linker invocation and input files for debugging">; | ||
| 256 | 270 | ||
| 257 | defm rpath: Eq<"rpath">, HelpText<"Add a DT_RUNPATH to the output">; | 271 | defm rpath: Eq<"rpath", "Add a DT_RUNPATH to the output">; |
| 258 | 272 | ||
| 259 | def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">; | 273 | def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">; |
| 260 | 274 | ||
| 261 | defm retain_symbols_file: Eq<"retain-symbols-file">, | 275 | defm retain_symbols_file: |
| 262 | HelpText<"Retain only the symbols listed in the file">, | 276 | Eq<"retain-symbols-file", "Retain only the symbols listed in the file">, |
| 263 | MetaVarName<"<file>">; | 277 | MetaVarName<"<file>">; |
| 264 | 278 | ||
| 265 | defm script: Eq<"script">, HelpText<"Read linker script">; | 279 | defm script: Eq<"script", "Read linker script">; |
| 266 | 280 | ||
| 267 | def section_start: S<"section-start">, MetaVarName<"<address>">, | 281 | defm section_start: Eq<"section-start", "Set address of section">, |
| 268 | HelpText<"Set address of section">; | 282 | MetaVarName<"<address>">; |
| 269 | 283 | ||
| 270 | def shared: F<"shared">, HelpText<"Build a shared object">; | 284 | def shared: F<"shared">, HelpText<"Build a shared object">; |
| 271 | 285 | ||
| 272 | defm soname: Eq<"soname">, HelpText<"Set DT_SONAME">; | 286 | defm soname: Eq<"soname", "Set DT_SONAME">; |
| 273 | 287 | ||
| 274 | defm sort_section: Eq<"sort-section">, | 288 | defm sort_section: |
| 275 | HelpText<"Specifies sections sorting rule when linkerscript is used">; | 289 | Eq<"sort-section", "Specifies sections sorting rule when linkerscript is used">; |
| 290 | |||
| 291 | def start_group: F<"start-group">, | ||
| 292 | HelpText<"Ignored for compatibility with GNU unless you pass --warn-backrefs">; | ||
| 276 | 293 | ||
| 277 | def start_lib: F<"start-lib">, | 294 | def start_lib: F<"start-lib">, |
| 278 | HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">; | 295 | HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">; |
| ... | @@ -281,33 +298,39 @@ def strip_all: F<"strip-all">, HelpText<"Strip all symbols">; | ... | @@ -281,33 +298,39 @@ def strip_all: F<"strip-all">, HelpText<"Strip all symbols">; |
| 281 | 298 | ||
| 282 | def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">; | 299 | def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">; |
| 283 | 300 | ||
| 284 | def symbol_ordering_file: S<"symbol-ordering-file">, | 301 | defm symbol_ordering_file: |
| 285 | HelpText<"Layout sections in the order specified by symbol file">; | 302 | Eq<"symbol-ordering-file", "Layout sections to place symbols in the order specified by symbol ordering file">; |
| 286 | 303 | ||
| 287 | defm sysroot: Eq<"sysroot">, HelpText<"Set the system root">; | 304 | defm sysroot: Eq<"sysroot", "Set the system root">; |
| 288 | 305 | ||
| 289 | def target1_rel: F<"target1-rel">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_REL32">; | 306 | def target1_rel: F<"target1-rel">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_REL32">; |
| 290 | 307 | ||
| 291 | def target1_abs: F<"target1-abs">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">; | 308 | def target1_abs: F<"target1-abs">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32 (default)">; |
| 292 | 309 | ||
| 293 | defm target2: Eq<"target2">, | 310 | defm target2: |
| 294 | HelpText<"Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel">, | 311 | Eq<"target2", "Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel">, |
| 295 | MetaVarName<"<type>">; | 312 | MetaVarName<"<type>">; |
| 296 | 313 | ||
| 297 | def threads: F<"threads">, HelpText<"Run the linker multi-threaded">; | 314 | defm threads: B<"threads", |
| 315 | "Run the linker multi-threaded (default)", | ||
| 316 | "Do not run the linker multi-threaded">; | ||
| 298 | 317 | ||
| 299 | def trace: F<"trace">, HelpText<"Print the names of the input files">; | 318 | def trace: F<"trace">, HelpText<"Print the names of the input files">; |
| 300 | 319 | ||
| 301 | defm trace_symbol : Eq<"trace-symbol">, HelpText<"Trace references to symbols">; | 320 | defm trace_symbol: Eq<"trace-symbol", "Trace references to symbols">; |
| 321 | |||
| 322 | defm undefined: Eq<"undefined", "Force undefined symbol during linking">, | ||
| 323 | MetaVarName<"<symbol>">; | ||
| 302 | 324 | ||
| 303 | defm undefined: Eq<"undefined">, | 325 | defm unresolved_symbols: |
| 304 | HelpText<"Force undefined symbol during linking">; | 326 | Eq<"unresolved-symbols", "Determine how to handle unresolved symbols">; |
| 305 | 327 | ||
| 306 | defm unresolved_symbols: Eq<"unresolved-symbols">, | 328 | defm undefined_version: B<"undefined-version", |
| 307 | HelpText<"Determine how to handle unresolved symbols">; | 329 | "Allow unused version in version script (default)", |
| 330 | "Report version scripts that refer undefined symbols">; | ||
| 308 | 331 | ||
| 309 | defm rsp_quoting: Eq<"rsp-quoting">, | 332 | defm rsp_quoting: Eq<"rsp-quoting", "Quoting style for response files">, |
| 310 | HelpText<"Quoting style for response files. Values supported: windows|posix">; | 333 | MetaVarName<"[posix,windows]">; |
| 311 | 334 | ||
| 312 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; | 335 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; |
| 313 | 336 | ||
| ... | @@ -315,91 +338,123 @@ def verbose: F<"verbose">, HelpText<"Verbose mode">; | ... | @@ -315,91 +338,123 @@ def verbose: F<"verbose">, HelpText<"Verbose mode">; |
| 315 | 338 | ||
| 316 | def version: F<"version">, HelpText<"Display the version number and exit">; | 339 | def version: F<"version">, HelpText<"Display the version number and exit">; |
| 317 | 340 | ||
| 318 | defm version_script: Eq<"version-script">, HelpText<"Read a version script">; | 341 | defm version_script: Eq<"version-script", "Read a version script">; |
| 342 | |||
| 343 | defm warn_backrefs: B<"warn-backrefs", | ||
| 344 | "Warn about backward symbol references to fetch archive members", | ||
| 345 | "Do not warn about backward symbol references to fetch archive members (default)">; | ||
| 346 | |||
| 347 | defm warn_common: B<"warn-common", | ||
| 348 | "Warn about duplicate common symbols", | ||
| 349 | "Do not warn about duplicate common symbols (default)">; | ||
| 319 | 350 | ||
| 320 | def warn_common: F<"warn-common">, | 351 | defm warn_symbol_ordering: B<"warn-symbol-ordering", |
| 321 | HelpText<"Warn about duplicate common symbols">; | 352 | "Warn about problems with the symbol ordering file (default)", |
| 353 | "Do not warn about problems with the symbol ordering file">; | ||
| 322 | 354 | ||
| 323 | def warn_unresolved_symbols: F<"warn-unresolved-symbols">, | 355 | def warn_unresolved_symbols: F<"warn-unresolved-symbols">, |
| 324 | HelpText<"Report unresolved symbols as warnings">; | 356 | HelpText<"Report unresolved symbols as warnings">; |
| 325 | 357 | ||
| 326 | def whole_archive: F<"whole-archive">, | 358 | defm whole_archive: B<"whole-archive", |
| 327 | HelpText<"Force load of all members in a static library">; | 359 | "Force load of all members in a static library", |
| 360 | "Do not force load of all members in a static library (default)">; | ||
| 328 | 361 | ||
| 329 | defm wrap: Eq<"wrap">, HelpText<"Use wrapper functions for symbol">, | 362 | defm wrap: Eq<"wrap", "Use wrapper functions for symbol">, |
| 330 | MetaVarName<"<symbol>">; | 363 | MetaVarName<"<symbol>=<symbol>">; |
| 331 | 364 | ||
| 332 | def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, | 365 | def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, |
| 333 | HelpText<"Linker option extensions">; | 366 | HelpText<"Linker option extensions">; |
| 334 | 367 | ||
| 335 | // Aliases | 368 | // Aliases |
| 336 | def alias_auxiliary: Separate<["-"], "f">, Alias<auxiliary>; | 369 | def: Separate<["-"], "f">, Alias<auxiliary>, HelpText<"Alias for --auxiliary">; |
| 337 | def alias_Bdynamic_call_shared: F<"call_shared">, Alias<Bdynamic>; | 370 | def: F<"call_shared">, Alias<Bdynamic>, HelpText<"Alias for --Bdynamic">; |
| 338 | def alias_Bdynamic_dy: F<"dy">, Alias<Bdynamic>; | 371 | def: F<"dy">, Alias<Bdynamic>, HelpText<"Alias for --Bdynamic">; |
| 339 | def alias_Bstatic_dn: F<"dn">, Alias<Bstatic>; | 372 | def: F<"dn">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">; |
| 340 | def alias_Bstatic_non_shared: F<"non_shared">, Alias<Bstatic>; | 373 | def: F<"non_shared">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">; |
| 341 | def alias_Bstatic_static: F<"static">, Alias<Bstatic>; | 374 | def: F<"static">, Alias<Bstatic>, HelpText<"Alias for --Bstatic">; |
| 342 | def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>; | 375 | def: Flag<["-"], "d">, Alias<define_common>, HelpText<"Alias for --define-common">; |
| 343 | def alias_define_common_dc: F<"dc">, Alias<define_common>; | 376 | def: F<"dc">, Alias<define_common>, HelpText<"Alias for --define-common">; |
| 344 | def alias_define_common_dp: F<"dp">, Alias<define_common>; | 377 | def: F<"dp">, Alias<define_common>, HelpText<"Alias for --define-common">; |
| 345 | def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>; | 378 | def: Flag<["-"], "x">, Alias<discard_all>, HelpText<"Alias for --discard-all">; |
| 346 | def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>; | 379 | def: Flag<["-"], "X">, Alias<discard_locals>, HelpText<"Alias for --discard-locals">; |
| 347 | def alias_emit_relocs: Flag<["-"], "q">, Alias<emit_relocs>; | 380 | def: Flag<["-"], "q">, Alias<emit_relocs>, HelpText<"Alias for --emit-relocs">; |
| 348 | def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>; | 381 | def: Flag<["-"], ")">, Alias<end_group>, HelpText<"Alias for --end-group">; |
| 349 | def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>; | 382 | def: JoinedOrSeparate<["-"], "e">, Alias<entry>, HelpText<"Alias for --entry">; |
| 350 | def alias_filter: Separate<["-"], "F">, Alias<filter>; | 383 | def: Flag<["-"], "E">, Alias<export_dynamic>, HelpText<"Alias for --export-dynamic">; |
| 351 | def alias_format_b: S<"b">, Alias<format>; | 384 | def: Separate<["-"], "F">, Alias<filter>, HelpText<"Alias for --filter">; |
| 352 | def alias_library: JoinedOrSeparate<["-"], "l">, Alias<library>; | 385 | def: Separate<["-"], "b">, Alias<format>, HelpText<"Alias for --format">; |
| 353 | def alias_library_path: JoinedOrSeparate<["-"], "L">, Alias<library_path>; | 386 | def: JoinedOrSeparate<["-"], "l">, Alias<library>, HelpText<"Alias for --library">; |
| 354 | def alias_omagic: Flag<["-"], "N">, Alias<omagic>; | 387 | def: JoinedOrSeparate<["-"], "L">, Alias<library_path>, HelpText<"Alias for --library-path">; |
| 355 | def alias_o_output: Joined<["--"], "output=">, Alias<o>; | 388 | def: F<"no-pic-executable">, Alias<no_pie>, HelpText<"Alias for --no-pie">; |
| 356 | def alias_o_output2 : Separate<["--"], "output">, Alias<o>; | 389 | def: Flag<["-"], "N">, Alias<omagic>, HelpText<"Alias for --omagic">; |
| 357 | def alias_pie_pic_executable: F<"pic-executable">, Alias<pie>; | 390 | def: Joined<["--"], "output=">, Alias<o>, HelpText<"Alias for -o">; |
| 358 | def alias_print_map_M: Flag<["-"], "M">, Alias<print_map>; | 391 | def: Separate<["--"], "output">, Alias<o>, HelpText<"Alias for -o">; |
| 359 | def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>; | 392 | def: F<"pic-executable">, Alias<pie>, HelpText<"Alias for --pie">; |
| 360 | def alias_rpath_R: JoinedOrSeparate<["-"], "R">, Alias<rpath>; | 393 | def: Flag<["-"], "M">, Alias<print_map>, HelpText<"Alias for --print-map">; |
| 361 | def alias_script_T: JoinedOrSeparate<["-"], "T">, Alias<script>; | 394 | def: Flag<["-"], "r">, Alias<relocatable>, HelpText<"Alias for --relocatable">; |
| 362 | def alias_shared_Bshareable: F<"Bshareable">, Alias<shared>; | 395 | def: JoinedOrSeparate<["-"], "R">, Alias<rpath>, HelpText<"Alias for --rpath">; |
| 363 | def alias_soname_h: JoinedOrSeparate<["-"], "h">, Alias<soname>; | 396 | def: JoinedOrSeparate<["-"], "T">, Alias<script>, HelpText<"Alias for --script">; |
| 364 | def alias_strip_all: Flag<["-"], "s">, Alias<strip_all>; | 397 | def: F<"Bshareable">, Alias<shared>, HelpText<"Alias for --shared">; |
| 365 | def alias_strip_debug_S: Flag<["-"], "S">, Alias<strip_debug>; | 398 | def: JoinedOrSeparate<["-"], "h">, Alias<soname>, HelpText<"Alias for --soname">; |
| 366 | def alias_trace: Flag<["-"], "t">, Alias<trace>; | 399 | def: Flag<["-"], "(">, Alias<start_group>, HelpText<"Alias for --start-group">; |
| 367 | def alias_trace_symbol_y : JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>; | 400 | def: Flag<["-"], "s">, Alias<strip_all>, HelpText<"Alias for --strip-all">; |
| 368 | def alias_Ttext_segment: S<"Ttext-segment">, Alias<Ttext>; | 401 | def: Flag<["-"], "S">, Alias<strip_debug>, HelpText<"Alias for --strip-debug">; |
| 369 | def alias_Ttext_segment_eq: J<"Ttext-segment=">, Alias<Ttext>; | 402 | def: Flag<["-"], "t">, Alias<trace>, HelpText<"Alias for --trace">; |
| 370 | def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>; | 403 | def: JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>, HelpText<"Alias for --trace-symbol">; |
| 371 | def alias_version_V: Flag<["-"], "V">, Alias<version>; | 404 | def: Separate<["-", "--"], "Ttext-segment">, Alias<Ttext>, HelpText<"Alias for --Ttext">; |
| 372 | 405 | def: Joined<["-", "--"], "Ttext-segment=">, Alias<Ttext>, HelpText<"Alias for --Ttext">; | |
| 373 | // Our symbol resolution algorithm handles symbols in archive files differently | 406 | def: JoinedOrSeparate<["-"], "u">, Alias<undefined>, HelpText<"Alias for --undefined">; |
| 374 | // than traditional linkers, so we don't need --start-group and --end-group. | 407 | def: Flag<["-"], "V">, Alias<version>, HelpText<"Alias for --version">; |
| 375 | // These options are recongized for compatibility but ignored. | ||
| 376 | def end_group: F<"end-group">; | ||
| 377 | def end_group_paren: Flag<["-"], ")">; | ||
| 378 | def start_group: F<"start-group">; | ||
| 379 | def start_group_paren: Flag<["-"], "(">; | ||
| 380 | 408 | ||
| 381 | // LTO-related options. | 409 | // LTO-related options. |
| 382 | def lto_aa_pipeline: J<"lto-aa-pipeline=">, | 410 | def lto_aa_pipeline: J<"lto-aa-pipeline=">, |
| 383 | HelpText<"AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes">; | 411 | HelpText<"AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes">; |
| 412 | def lto_debug_pass_manager: F<"lto-debug-pass-manager">, | ||
| 413 | HelpText<"Debug new pass manager">; | ||
| 414 | def lto_new_pass_manager: F<"lto-new-pass-manager">, | ||
| 415 | HelpText<"Use new pass manager">; | ||
| 384 | def lto_newpm_passes: J<"lto-newpm-passes=">, | 416 | def lto_newpm_passes: J<"lto-newpm-passes=">, |
| 385 | HelpText<"Passes to run during LTO">; | 417 | HelpText<"Passes to run during LTO">; |
| 418 | def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">, | ||
| 419 | HelpText<"Optimization level for LTO">; | ||
| 386 | def lto_partitions: J<"lto-partitions=">, | 420 | def lto_partitions: J<"lto-partitions=">, |
| 387 | HelpText<"Number of LTO codegen partitions">; | 421 | HelpText<"Number of LTO codegen partitions">; |
| 422 | def lto_sample_profile: J<"lto-sample-profile=">, | ||
| 423 | HelpText<"Sample profile file path">; | ||
| 388 | def disable_verify: F<"disable-verify">; | 424 | def disable_verify: F<"disable-verify">; |
| 389 | def mllvm: S<"mllvm">; | 425 | defm mllvm: Eq<"mllvm", "Additional arguments to forward to LLVM's option processing">; |
| 390 | def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">, | 426 | def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">, |
| 391 | HelpText<"YAML output file for optimization remarks">; | 427 | HelpText<"YAML output file for optimization remarks">; |
| 392 | def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">, | 428 | def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">, |
| 393 | HelpText<"Include hotness informations in the optimization remarks file">; | 429 | HelpText<"Include hotness information in the optimization remarks file">; |
| 394 | defm plugin_opt: Eq<"plugin-opt">, | 430 | defm plugin_opt: Eq<"plugin-opt", "specifies LTO options for compatibility with GNU linkers">; |
| 395 | HelpText<"specifies LTO options for compatibility with GNU linkers">; | ||
| 396 | def save_temps: F<"save-temps">; | 431 | def save_temps: F<"save-temps">; |
| 397 | def thinlto_cache_dir: J<"thinlto-cache-dir=">, | 432 | def thinlto_cache_dir: J<"thinlto-cache-dir=">, |
| 398 | HelpText<"Path to ThinLTO cached object file directory">; | 433 | HelpText<"Path to ThinLTO cached object file directory">; |
| 399 | def thinlto_cache_policy: S<"thinlto-cache-policy">, | 434 | defm thinlto_cache_policy: Eq<"thinlto-cache-policy", "Pruning policy for the ThinLTO cache">; |
| 400 | HelpText<"Pruning policy for the ThinLTO cache">; | ||
| 401 | def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">; | 435 | def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">; |
| 402 | 436 | ||
| 437 | def: J<"plugin-opt=O">, Alias<lto_O>, HelpText<"Alias for -lto-O">; | ||
| 438 | def: F<"plugin-opt=debug-pass-manager">, | ||
| 439 | Alias<lto_debug_pass_manager>, HelpText<"Alias for -lto-debug-pass-manager">; | ||
| 440 | def: F<"plugin-opt=disable-verify">, Alias<disable_verify>, HelpText<"Alias for -disable-verify">; | ||
| 441 | def plugin_opt_dwo_dir_eq: J<"plugin-opt=dwo_dir=">, | ||
| 442 | HelpText<"Directory to store .dwo files when LTO and debug fission are used">; | ||
| 443 | def: J<"plugin-opt=jobs=">, Alias<thinlto_jobs>, HelpText<"Alias for -thinlto-jobs">; | ||
| 444 | def: J<"plugin-opt=lto-partitions=">, Alias<lto_partitions>, HelpText<"Alias for -lto-partitions">; | ||
| 445 | def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">; | ||
| 446 | def: F<"plugin-opt=new-pass-manager">, | ||
| 447 | Alias<lto_new_pass_manager>, HelpText<"Alias for -lto-new-pass-manager">; | ||
| 448 | def plugin_opt_obj_path_eq: J<"plugin-opt=obj-path=">; | ||
| 449 | def: J<"plugin-opt=sample-profile=">, | ||
| 450 | Alias<lto_sample_profile>, HelpText<"Alias for -lto-sample-profile">; | ||
| 451 | def: F<"plugin-opt=save-temps">, Alias<save_temps>, HelpText<"Alias for -save-temps">; | ||
| 452 | def plugin_opt_thinlto_emit_imports_files: F<"plugin-opt=thinlto-emit-imports-files">; | ||
| 453 | def plugin_opt_thinlto_index_only: F<"plugin-opt=thinlto-index-only">; | ||
| 454 | def plugin_opt_thinlto_index_only_eq: J<"plugin-opt=thinlto-index-only=">; | ||
| 455 | def plugin_opt_thinlto_object_suffix_replace_eq: J<"plugin-opt=thinlto-object-suffix-replace=">; | ||
| 456 | def plugin_opt_thinlto_prefix_replace_eq: J<"plugin-opt=thinlto-prefix-replace=">; | ||
| 457 | |||
| 403 | // Ignore LTO plugin-related options. | 458 | // Ignore LTO plugin-related options. |
| 404 | // clang -flto passes -plugin and -plugin-opt to the linker. This is required | 459 | // clang -flto passes -plugin and -plugin-opt to the linker. This is required |
| 405 | // for ld.gold and ld.bfd to get LTO working. But it's not for lld which doesn't | 460 | // for ld.gold and ld.bfd to get LTO working. But it's not for lld which doesn't |
| ... | @@ -407,31 +462,38 @@ def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">; | ... | @@ -407,31 +462,38 @@ def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">; |
| 407 | // just ignore the option on lld side as it's easier. In fact, the linker could | 462 | // just ignore the option on lld side as it's easier. In fact, the linker could |
| 408 | // be called 'ld' and understanding which linker is used would require parsing of | 463 | // be called 'ld' and understanding which linker is used would require parsing of |
| 409 | // --version output. | 464 | // --version output. |
| 410 | def plugin: S<"plugin">; | 465 | defm plugin: Eq<"plugin", "Ignored for compatibility with GNU linkers">; |
| 411 | def plugin_eq: J<"plugin=">; | 466 | |
| 467 | def plugin_opt_fresolution_eq: J<"plugin-opt=-fresolution=">; | ||
| 468 | def plugin_opt_pass_through_eq: J<"plugin-opt=-pass-through=">; | ||
| 469 | def plugin_opt_thinlto: J<"plugin-opt=thinlto">; | ||
| 470 | def plugin_opt_slash: J<"plugin-opt=/">; | ||
| 412 | 471 | ||
| 413 | // Options listed below are silently ignored for now for compatibility. | 472 | // Options listed below are silently ignored for now for compatibility. |
| 414 | def allow_shlib_undefined: F<"allow-shlib-undefined">; | 473 | def: F<"allow-shlib-undefined">; |
| 415 | def cref: F<"cref">; | 474 | def: F<"detect-odr-violations">; |
| 416 | def detect_odr_violations: F<"detect-odr-violations">; | 475 | def: Flag<["-"], "g">; |
| 417 | def g: Flag<["-"], "g">; | 476 | def: F<"long-plt">; |
| 418 | def long_plt: F<"long-plt">; | 477 | def: F<"no-add-needed">; |
| 419 | def no_add_needed: F<"no-add-needed">; | 478 | def: F<"no-allow-shlib-undefined">; |
| 420 | def no_allow_shlib_undefined: F<"no-allow-shlib-undefined">; | 479 | def: F<"no-copy-dt-needed-entries">; |
| 421 | def no_copy_dt_needed_entries: F<"no-copy-dt-needed-entries">; | 480 | def: F<"no-ctors-in-init-array">; |
| 422 | def no_ctors_in_init_array: F<"no-ctors-in-init-array">; | 481 | def: F<"no-keep-memory">; |
| 423 | def no_keep_memory: F<"no-keep-memory">; | 482 | def: F<"no-mmap-output-file">; |
| 424 | def no_mmap_output_file: F<"no-mmap-output-file">; | 483 | def: F<"no-warn-mismatch">; |
| 425 | def no_warn_common: F<"no-warn-common">; | 484 | def: Separate<["--", "-"], "rpath-link">; |
| 426 | def no_warn_mismatch: F<"no-warn-mismatch">; | 485 | def: J<"rpath-link=">; |
| 427 | def rpath_link: S<"rpath-link">; | 486 | def: F<"sort-common">; |
| 428 | def rpath_link_eq: J<"rpath-link=">; | 487 | def: F<"stats">; |
| 429 | def sort_common: F<"sort-common">; | 488 | def: F<"warn-execstack">; |
| 430 | def stats: F<"stats">; | 489 | def: F<"warn-once">; |
| 431 | def warn_execstack: F<"warn-execstack">; | 490 | def: F<"warn-shared-textrel">; |
| 432 | def warn_once: F<"warn-once">; | 491 | def: F<"EB">; |
| 433 | def warn_shared_textrel: F<"warn-shared-textrel">; | 492 | def: F<"EL">; |
| 434 | def EB : F<"EB">; | 493 | def: JoinedOrSeparate<["-"], "G">; |
| 435 | def EL : F<"EL">; | 494 | def: F<"Qy">; |
| 436 | def G: JoinedOrSeparate<["-"], "G">; | 495 | |
| 437 | def Qy : F<"Qy">; | 496 | // Hidden option used for testing MIPS multi-GOT implementation. |
| 497 | defm mips_got_size: | ||
| 498 | Eq<"mips-got-size", "Max size of a single MIPS GOT. 0x10000 by default.">, | ||
| 499 | Flags<[HelpHidden]>; |
deps/lld/ELF/OutputSections.cpp+41-40| ... | @@ -10,11 +10,11 @@ | ... | @@ -10,11 +10,11 @@ |
| 10 | #include "OutputSections.h" | 10 | #include "OutputSections.h" |
| 11 | #include "Config.h" | 11 | #include "Config.h" |
| 12 | #include "LinkerScript.h" | 12 | #include "LinkerScript.h" |
| 13 | #include "Strings.h" | ||
| 14 | #include "SymbolTable.h" | 13 | #include "SymbolTable.h" |
| 15 | #include "SyntheticSections.h" | 14 | #include "SyntheticSections.h" |
| 16 | #include "Target.h" | 15 | #include "Target.h" |
| 17 | #include "lld/Common/Memory.h" | 16 | #include "lld/Common/Memory.h" |
| 17 | #include "lld/Common/Strings.h" | ||
| 18 | #include "lld/Common/Threads.h" | 18 | #include "lld/Common/Threads.h" |
| 19 | #include "llvm/BinaryFormat/Dwarf.h" | 19 | #include "llvm/BinaryFormat/Dwarf.h" |
| 20 | #include "llvm/Support/Compression.h" | 20 | #include "llvm/Support/Compression.h" |
| ... | @@ -25,15 +25,12 @@ | ... | @@ -25,15 +25,12 @@ |
| 25 | using namespace llvm; | 25 | using namespace llvm; |
| 26 | using namespace llvm::dwarf; | 26 | using namespace llvm::dwarf; |
| 27 | using namespace llvm::object; | 27 | using namespace llvm::object; |
| 28 | using namespace llvm::support::endian; | ||
| 29 | using namespace llvm::ELF; | 28 | using namespace llvm::ELF; |
| 30 | 29 | ||
| 31 | using namespace lld; | 30 | using namespace lld; |
| 32 | using namespace lld::elf; | 31 | using namespace lld::elf; |
| 33 | 32 | ||
| 34 | uint8_t Out::First; | 33 | uint8_t Out::First; |
| 35 | OutputSection *Out::Opd; | ||
| 36 | uint8_t *Out::OpdBuf; | ||
| 37 | PhdrEntry *Out::TlsPhdr; | 34 | PhdrEntry *Out::TlsPhdr; |
| 38 | OutputSection *Out::DebugInfo; | 35 | OutputSection *Out::DebugInfo; |
| 39 | OutputSection *Out::ElfHeader; | 36 | OutputSection *Out::ElfHeader; |
| ... | @@ -45,7 +42,9 @@ OutputSection *Out::FiniArray; | ... | @@ -45,7 +42,9 @@ OutputSection *Out::FiniArray; |
| 45 | std::vector<OutputSection *> elf::OutputSections; | 42 | std::vector<OutputSection *> elf::OutputSections; |
| 46 | 43 | ||
| 47 | uint32_t OutputSection::getPhdrFlags() const { | 44 | uint32_t OutputSection::getPhdrFlags() const { |
| 48 | uint32_t Ret = PF_R; | 45 | uint32_t Ret = 0; |
| 46 | if (Config->EMachine != EM_ARM || !(Flags & SHF_ARM_PURECODE)) | ||
| 47 | Ret |= PF_R; | ||
| 49 | if (Flags & SHF_WRITE) | 48 | if (Flags & SHF_WRITE) |
| 50 | Ret |= PF_W; | 49 | Ret |= PF_W; |
| 51 | if (Flags & SHF_EXECINSTR) | 50 | if (Flags & SHF_EXECINSTR) |
| ... | @@ -70,9 +69,7 @@ void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) { | ... | @@ -70,9 +69,7 @@ void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) { |
| 70 | OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags) | 69 | OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags) |
| 71 | : BaseCommand(OutputSectionKind), | 70 | : BaseCommand(OutputSectionKind), |
| 72 | SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type, | 71 | SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type, |
| 73 | /*Info*/ 0, | 72 | /*Info*/ 0, /*Link*/ 0) { |
| 74 | /*Link*/ 0), | ||
| 75 | SectionIndex(INT_MAX) { | ||
| 76 | Live = false; | 73 | Live = false; |
| 77 | } | 74 | } |
| 78 | 75 | ||
| ... | @@ -91,13 +88,15 @@ static bool canMergeToProgbits(unsigned Type) { | ... | @@ -91,13 +88,15 @@ static bool canMergeToProgbits(unsigned Type) { |
| 91 | void OutputSection::addSection(InputSection *IS) { | 88 | void OutputSection::addSection(InputSection *IS) { |
| 92 | if (!Live) { | 89 | if (!Live) { |
| 93 | // If IS is the first section to be added to this section, | 90 | // If IS is the first section to be added to this section, |
| 94 | // initialize Type and Entsize from IS. | 91 | // initialize Type, Entsize and flags from IS. |
| 95 | Live = true; | 92 | Live = true; |
| 96 | Type = IS->Type; | 93 | Type = IS->Type; |
| 97 | Entsize = IS->Entsize; | 94 | Entsize = IS->Entsize; |
| 95 | Flags = IS->Flags; | ||
| 98 | } else { | 96 | } else { |
| 99 | // Otherwise, check if new type or flags are compatible with existing ones. | 97 | // Otherwise, check if new type or flags are compatible with existing ones. |
| 100 | if ((Flags & (SHF_ALLOC | SHF_TLS)) != (IS->Flags & (SHF_ALLOC | SHF_TLS))) | 98 | unsigned Mask = SHF_ALLOC | SHF_TLS | SHF_LINK_ORDER; |
| 99 | if ((Flags & Mask) != (IS->Flags & Mask)) | ||
| 101 | error("incompatible section flags for " + Name + "\n>>> " + toString(IS) + | 100 | error("incompatible section flags for " + Name + "\n>>> " + toString(IS) + |
| 102 | ": 0x" + utohexstr(IS->Flags) + "\n>>> output section " + Name + | 101 | ": 0x" + utohexstr(IS->Flags) + "\n>>> output section " + Name + |
| 103 | ": 0x" + utohexstr(Flags)); | 102 | ": 0x" + utohexstr(Flags)); |
| ... | @@ -114,9 +113,14 @@ void OutputSection::addSection(InputSection *IS) { | ... | @@ -114,9 +113,14 @@ void OutputSection::addSection(InputSection *IS) { |
| 114 | } | 113 | } |
| 115 | 114 | ||
| 116 | IS->Parent = this; | 115 | IS->Parent = this; |
| 117 | Flags |= IS->Flags; | 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; | ||
| 122 | |||
| 118 | Alignment = std::max(Alignment, IS->Alignment); | 123 | Alignment = std::max(Alignment, IS->Alignment); |
| 119 | IS->OutSecOff = Size++; | ||
| 120 | 124 | ||
| 121 | // If this section contains a table of fixed-size entries, sh_entsize | 125 | // If this section contains a table of fixed-size entries, sh_entsize |
| 122 | // holds the element size. If it contains elements of different size we | 126 | // holds the element size. If it contains elements of different size we |
| ... | @@ -134,8 +138,8 @@ void OutputSection::addSection(InputSection *IS) { | ... | @@ -134,8 +138,8 @@ void OutputSection::addSection(InputSection *IS) { |
| 134 | } | 138 | } |
| 135 | } | 139 | } |
| 136 | 140 | ||
| 137 | void elf::sortByOrder(MutableArrayRef<InputSection *> In, | 141 | static void sortByOrder(MutableArrayRef<InputSection *> In, |
| 138 | std::function<int(InputSectionBase *S)> Order) { | 142 | llvm::function_ref<int(InputSectionBase *S)> Order) { |
| 139 | typedef std::pair<int, InputSection *> Pair; | 143 | typedef std::pair<int, InputSection *> Pair; |
| 140 | auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; }; | 144 | auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; }; |
| 141 | 145 | ||
| ... | @@ -158,11 +162,11 @@ bool OutputSection::classof(const BaseCommand *C) { | ... | @@ -158,11 +162,11 @@ bool OutputSection::classof(const BaseCommand *C) { |
| 158 | return C->Kind == OutputSectionKind; | 162 | return C->Kind == OutputSectionKind; |
| 159 | } | 163 | } |
| 160 | 164 | ||
| 161 | void OutputSection::sort(std::function<int(InputSectionBase *S)> Order) { | 165 | void OutputSection::sort(llvm::function_ref<int(InputSectionBase *S)> Order) { |
| 162 | assert(Live); | 166 | assert(Live); |
| 163 | assert(SectionCommands.size() == 1); | 167 | for (BaseCommand *B : SectionCommands) |
| 164 | sortByOrder(cast<InputSectionDescription>(SectionCommands[0])->Sections, | 168 | if (auto *ISD = dyn_cast<InputSectionDescription>(B)) |
| 165 | Order); | 169 | sortByOrder(ISD->Sections, Order); |
| 166 | } | 170 | } |
| 167 | 171 | ||
| 168 | // Fill [Buf, Buf + Size) with Filler. | 172 | // Fill [Buf, Buf + Size) with Filler. |
| ... | @@ -205,11 +209,11 @@ static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { | ... | @@ -205,11 +209,11 @@ static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) { |
| 205 | if (Size == 1) | 209 | if (Size == 1) |
| 206 | *Buf = Data; | 210 | *Buf = Data; |
| 207 | else if (Size == 2) | 211 | else if (Size == 2) |
| 208 | write16(Buf, Data, Config->Endianness); | 212 | write16(Buf, Data); |
| 209 | else if (Size == 4) | 213 | else if (Size == 4) |
| 210 | write32(Buf, Data, Config->Endianness); | 214 | write32(Buf, Data); |
| 211 | else if (Size == 8) | 215 | else if (Size == 8) |
| 212 | write64(Buf, Data, Config->Endianness); | 216 | write64(Buf, Data); |
| 213 | else | 217 | else |
| 214 | llvm_unreachable("unsupported Size argument"); | 218 | llvm_unreachable("unsupported Size argument"); |
| 215 | } | 219 | } |
| ... | @@ -231,12 +235,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) { | ... | @@ -231,12 +235,7 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) { |
| 231 | } | 235 | } |
| 232 | 236 | ||
| 233 | // Write leading padding. | 237 | // Write leading padding. |
| 234 | std::vector<InputSection *> Sections; | 238 | std::vector<InputSection *> Sections = getInputSections(this); |
| 235 | for (BaseCommand *Cmd : SectionCommands) | ||
| 236 | if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd)) | ||
| 237 | for (InputSection *IS : ISD->Sections) | ||
| 238 | if (IS->Live) | ||
| 239 | Sections.push_back(IS); | ||
| 240 | uint32_t Filler = getFiller(); | 239 | uint32_t Filler = getFiller(); |
| 241 | if (Filler) | 240 | if (Filler) |
| 242 | fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler); | 241 | fill(Buf, Sections.empty() ? Size : Sections[0]->OutSecOff, Filler); |
| ... | @@ -281,17 +280,13 @@ static void finalizeShtGroup(OutputSection *OS, | ... | @@ -281,17 +280,13 @@ static void finalizeShtGroup(OutputSection *OS, |
| 281 | } | 280 | } |
| 282 | 281 | ||
| 283 | template <class ELFT> void OutputSection::finalize() { | 282 | template <class ELFT> void OutputSection::finalize() { |
| 284 | InputSection *First = nullptr; | 283 | if (Type == SHT_NOBITS) |
| 285 | for (BaseCommand *Base : SectionCommands) { | 284 | for (BaseCommand *Base : SectionCommands) |
| 286 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) { | 285 | if (isa<ByteCommand>(Base)) |
| 287 | if (ISD->Sections.empty()) | 286 | Type = SHT_PROGBITS; |
| 288 | continue; | 287 | |
| 289 | if (First == nullptr) | 288 | std::vector<InputSection *> V = getInputSections(this); |
| 290 | First = ISD->Sections.front(); | 289 | InputSection *First = V.empty() ? nullptr : V[0]; |
| 291 | } | ||
| 292 | if (isa<ByteCommand>(Base) && Type == SHT_NOBITS) | ||
| 293 | Type = SHT_PROGBITS; | ||
| 294 | } | ||
| 295 | 290 | ||
| 296 | if (Flags & SHF_LINK_ORDER) { | 291 | if (Flags & SHF_LINK_ORDER) { |
| 297 | // We must preserve the link order dependency of sections with the | 292 | // We must preserve the link order dependency of sections with the |
| ... | @@ -367,8 +362,6 @@ static bool compCtors(const InputSection *A, const InputSection *B) { | ... | @@ -367,8 +362,6 @@ static bool compCtors(const InputSection *A, const InputSection *B) { |
| 367 | assert(Y.startswith(".ctors") || Y.startswith(".dtors")); | 362 | assert(Y.startswith(".ctors") || Y.startswith(".dtors")); |
| 368 | X = X.substr(6); | 363 | X = X.substr(6); |
| 369 | Y = Y.substr(6); | 364 | Y = Y.substr(6); |
| 370 | if (X.empty() && Y.empty()) | ||
| 371 | return false; | ||
| 372 | return X < Y; | 365 | return X < Y; |
| 373 | } | 366 | } |
| 374 | 367 | ||
| ... | @@ -394,6 +387,14 @@ int elf::getPriority(StringRef S) { | ... | @@ -394,6 +387,14 @@ int elf::getPriority(StringRef S) { |
| 394 | return V; | 387 | return V; |
| 395 | } | 388 | } |
| 396 | 389 | ||
| 390 | std::vector<InputSection *> elf::getInputSections(OutputSection *OS) { | ||
| 391 | std::vector<InputSection *> Ret; | ||
| 392 | for (BaseCommand *Base : OS->SectionCommands) | ||
| 393 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) | ||
| 394 | Ret.insert(Ret.end(), ISD->Sections.begin(), ISD->Sections.end()); | ||
| 395 | return Ret; | ||
| 396 | } | ||
| 397 | |||
| 397 | // Sorts input sections by section name suffixes, so that .foo.N comes | 398 | // Sorts input sections by section name suffixes, so that .foo.N comes |
| 398 | // before .foo.M if N < M. Used to sort .{init,fini}_array.N sections. | 399 | // before .foo.M if N < M. Used to sort .{init,fini}_array.N sections. |
| 399 | // We want to keep the original order if the priorities are the same | 400 | // We want to keep the original order if the priorities are the same |
deps/lld/ELF/OutputSections.h+7-7| ... | @@ -14,7 +14,6 @@ | ... | @@ -14,7 +14,6 @@ |
| 14 | #include "InputSection.h" | 14 | #include "InputSection.h" |
| 15 | #include "LinkerScript.h" | 15 | #include "LinkerScript.h" |
| 16 | #include "Relocations.h" | 16 | #include "Relocations.h" |
| 17 | |||
| 18 | #include "lld/Common/LLVM.h" | 17 | #include "lld/Common/LLVM.h" |
| 19 | #include "llvm/MC/StringTableBuilder.h" | 18 | #include "llvm/MC/StringTableBuilder.h" |
| 20 | #include "llvm/Object/ELF.h" | 19 | #include "llvm/Object/ELF.h" |
| ... | @@ -52,7 +51,7 @@ public: | ... | @@ -52,7 +51,7 @@ public: |
| 52 | uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; } | 51 | uint64_t getLMA() const { return PtLoad ? Addr + PtLoad->LMAOffset : Addr; } |
| 53 | template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr); | 52 | template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr); |
| 54 | 53 | ||
| 55 | unsigned SectionIndex; | 54 | uint32_t SectionIndex = UINT32_MAX; |
| 56 | unsigned SortRank; | 55 | unsigned SortRank; |
| 57 | 56 | ||
| 58 | uint32_t getPhdrFlags() const; | 57 | uint32_t getPhdrFlags() const; |
| ... | @@ -100,13 +99,16 @@ public: | ... | @@ -100,13 +99,16 @@ public: |
| 100 | std::string Location; | 99 | std::string Location; |
| 101 | std::string MemoryRegionName; | 100 | std::string MemoryRegionName; |
| 102 | std::string LMARegionName; | 101 | std::string LMARegionName; |
| 102 | bool NonAlloc = false; | ||
| 103 | bool Noload = false; | 103 | bool Noload = false; |
| 104 | bool ExpressionsUseSymbols = false; | ||
| 105 | bool InOverlay = false; | ||
| 104 | 106 | ||
| 105 | template <class ELFT> void finalize(); | 107 | template <class ELFT> void finalize(); |
| 106 | template <class ELFT> void writeTo(uint8_t *Buf); | 108 | template <class ELFT> void writeTo(uint8_t *Buf); |
| 107 | template <class ELFT> void maybeCompress(); | 109 | template <class ELFT> void maybeCompress(); |
| 108 | 110 | ||
| 109 | void sort(std::function<int(InputSectionBase *S)> Order); | 111 | void sort(llvm::function_ref<int(InputSectionBase *S)> Order); |
| 110 | void sortInitFini(); | 112 | void sortInitFini(); |
| 111 | void sortCtorsDtors(); | 113 | void sortCtorsDtors(); |
| 112 | 114 | ||
| ... | @@ -120,13 +122,13 @@ private: | ... | @@ -120,13 +122,13 @@ private: |
| 120 | 122 | ||
| 121 | int getPriority(StringRef S); | 123 | int getPriority(StringRef S); |
| 122 | 124 | ||
| 125 | std::vector<InputSection *> getInputSections(OutputSection* OS); | ||
| 126 | |||
| 123 | // All output sections that are handled by the linker specially are | 127 | // All output sections that are handled by the linker specially are |
| 124 | // globally accessible. Writer initializes them, so don't use them | 128 | // globally accessible. Writer initializes them, so don't use them |
| 125 | // until Writer is initialized. | 129 | // until Writer is initialized. |
| 126 | struct Out { | 130 | struct Out { |
| 127 | static uint8_t First; | 131 | static uint8_t First; |
| 128 | static OutputSection *Opd; | ||
| 129 | static uint8_t *OpdBuf; | ||
| 130 | static PhdrEntry *TlsPhdr; | 132 | static PhdrEntry *TlsPhdr; |
| 131 | static OutputSection *DebugInfo; | 133 | static OutputSection *DebugInfo; |
| 132 | static OutputSection *ElfHeader; | 134 | static OutputSection *ElfHeader; |
| ... | @@ -143,8 +145,6 @@ namespace lld { | ... | @@ -143,8 +145,6 @@ namespace lld { |
| 143 | namespace elf { | 145 | namespace elf { |
| 144 | 146 | ||
| 145 | uint64_t getHeaderSize(); | 147 | uint64_t getHeaderSize(); |
| 146 | void sortByOrder(llvm::MutableArrayRef<InputSection *> In, | ||
| 147 | std::function<int(InputSectionBase *S)> Order); | ||
| 148 | 148 | ||
| 149 | extern std::vector<OutputSection *> OutputSections; | 149 | extern std::vector<OutputSection *> OutputSections; |
| 150 | } // namespace elf | 150 | } // namespace elf |
deps/lld/ELF/Relocations.cpp+415-393| ... | @@ -45,14 +45,14 @@ | ... | @@ -45,14 +45,14 @@ |
| 45 | #include "Config.h" | 45 | #include "Config.h" |
| 46 | #include "LinkerScript.h" | 46 | #include "LinkerScript.h" |
| 47 | #include "OutputSections.h" | 47 | #include "OutputSections.h" |
| 48 | #include "Strings.h" | ||
| 49 | #include "SymbolTable.h" | 48 | #include "SymbolTable.h" |
| 50 | #include "Symbols.h" | 49 | #include "Symbols.h" |
| 51 | #include "SyntheticSections.h" | 50 | #include "SyntheticSections.h" |
| 52 | #include "Target.h" | 51 | #include "Target.h" |
| 53 | #include "Thunks.h" | 52 | #include "Thunks.h" |
| 54 | #include "lld/Common/Memory.h" | 53 | #include "lld/Common/Memory.h" |
| 55 | 54 | #include "lld/Common/Strings.h" | |
| 55 | #include "llvm/ADT/SmallSet.h" | ||
| 56 | #include "llvm/Support/Endian.h" | 56 | #include "llvm/Support/Endian.h" |
| 57 | #include "llvm/Support/raw_ostream.h" | 57 | #include "llvm/Support/raw_ostream.h" |
| 58 | #include <algorithm> | 58 | #include <algorithm> |
| ... | @@ -80,55 +80,22 @@ static std::string getLocation(InputSectionBase &S, const Symbol &Sym, | ... | @@ -80,55 +80,22 @@ static std::string getLocation(InputSectionBase &S, const Symbol &Sym, |
| 80 | return Msg + S.getObjMsg(Off); | 80 | return Msg + S.getObjMsg(Off); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | // This is a MIPS-specific rule. | ||
| 84 | // | ||
| 85 | // In case of MIPS GP-relative relocations always resolve to a definition | ||
| 86 | // in a regular input file, ignoring the one-definition rule. So we, | ||
| 87 | // for example, should not attempt to create a dynamic relocation even | ||
| 88 | // if the target symbol is preemptible. There are two two MIPS GP-relative | ||
| 89 | // relocations R_MIPS_GPREL16 and R_MIPS_GPREL32. But only R_MIPS_GPREL16 | ||
| 90 | // can be against a preemptible symbol. | ||
| 91 | // | ||
| 92 | // To get MIPS relocation type we apply 0xff mask. In case of O32 ABI all | ||
| 93 | // relocation types occupy eight bit. In case of N64 ABI we extract first | ||
| 94 | // relocation from 3-in-1 packet because only the first relocation can | ||
| 95 | // be against a real symbol. | ||
| 96 | static bool isMipsGprel(RelType Type) { | ||
| 97 | if (Config->EMachine != EM_MIPS) | ||
| 98 | return false; | ||
| 99 | Type &= 0xff; | ||
| 100 | return Type == R_MIPS_GPREL16 || Type == R_MICROMIPS_GPREL16 || | ||
| 101 | Type == R_MICROMIPS_GPREL7_S2; | ||
| 102 | } | ||
| 103 | |||
| 104 | // This function is similar to the `handleTlsRelocation`. MIPS does not | 83 | // This function is similar to the `handleTlsRelocation`. MIPS does not |
| 105 | // support any relaxations for TLS relocations so by factoring out MIPS | 84 | // support any relaxations for TLS relocations so by factoring out MIPS |
| 106 | // handling in to the separate function we can simplify the code and do not | 85 | // handling in to the separate function we can simplify the code and do not |
| 107 | // pollute other `handleTlsRelocation` by MIPS `ifs` statements. | 86 | // pollute other `handleTlsRelocation` by MIPS `ifs` statements. |
| 108 | // Mips has a custom MipsGotSection that handles the writing of GOT entries | 87 | // Mips has a custom MipsGotSection that handles the writing of GOT entries |
| 109 | // without dynamic relocations. | 88 | // without dynamic relocations. |
| 110 | template <class ELFT> | ||
| 111 | static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym, | 89 | static unsigned handleMipsTlsRelocation(RelType Type, Symbol &Sym, |
| 112 | InputSectionBase &C, uint64_t Offset, | 90 | InputSectionBase &C, uint64_t Offset, |
| 113 | int64_t Addend, RelExpr Expr) { | 91 | int64_t Addend, RelExpr Expr) { |
| 114 | if (Expr == R_MIPS_TLSLD) { | 92 | if (Expr == R_MIPS_TLSLD) { |
| 115 | if (InX::MipsGot->addTlsIndex() && Config->Pic) | 93 | InX::MipsGot->addTlsIndex(*C.File); |
| 116 | InX::RelaDyn->addReloc({Target->TlsModuleIndexRel, InX::MipsGot, | ||
| 117 | InX::MipsGot->getTlsIndexOff(), false, nullptr, | ||
| 118 | 0}); | ||
| 119 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | 94 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); |
| 120 | return 1; | 95 | return 1; |
| 121 | } | 96 | } |
| 122 | |||
| 123 | if (Expr == R_MIPS_TLSGD) { | 97 | if (Expr == R_MIPS_TLSGD) { |
| 124 | if (InX::MipsGot->addDynTlsEntry(Sym) && Sym.IsPreemptible) { | 98 | InX::MipsGot->addDynTlsEntry(*C.File, Sym); |
| 125 | uint64_t Off = InX::MipsGot->getGlobalDynOffset(Sym); | ||
| 126 | InX::RelaDyn->addReloc( | ||
| 127 | {Target->TlsModuleIndexRel, InX::MipsGot, Off, false, &Sym, 0}); | ||
| 128 | if (Sym.IsPreemptible) | ||
| 129 | InX::RelaDyn->addReloc({Target->TlsOffsetRel, InX::MipsGot, | ||
| 130 | Off + Config->Wordsize, false, &Sym, 0}); | ||
| 131 | } | ||
| 132 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | 99 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); |
| 133 | return 1; | 100 | return 1; |
| 134 | } | 101 | } |
| ... | @@ -161,7 +128,7 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym, | ... | @@ -161,7 +128,7 @@ static unsigned handleARMTlsRelocation(RelType Type, Symbol &Sym, |
| 161 | 128 | ||
| 162 | auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) { | 129 | auto AddTlsReloc = [&](uint64_t Off, RelType Type, Symbol *Dest, bool Dyn) { |
| 163 | if (Dyn) | 130 | if (Dyn) |
| 164 | InX::RelaDyn->addReloc({Type, InX::Got, Off, false, Dest, 0}); | 131 | InX::RelaDyn->addReloc(Type, InX::Got, Off, Dest); |
| 165 | else | 132 | else |
| 166 | InX::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest}); | 133 | InX::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest}); |
| 167 | }; | 134 | }; |
| ... | @@ -207,7 +174,7 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, | ... | @@ -207,7 +174,7 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, |
| 207 | if (Config->EMachine == EM_ARM) | 174 | if (Config->EMachine == EM_ARM) |
| 208 | return handleARMTlsRelocation<ELFT>(Type, Sym, C, Offset, Addend, Expr); | 175 | return handleARMTlsRelocation<ELFT>(Type, Sym, C, Offset, Addend, Expr); |
| 209 | if (Config->EMachine == EM_MIPS) | 176 | if (Config->EMachine == EM_MIPS) |
| 210 | return handleMipsTlsRelocation<ELFT>(Type, Sym, C, Offset, Addend, Expr); | 177 | return handleMipsTlsRelocation(Type, Sym, C, Offset, Addend, Expr); |
| 211 | 178 | ||
| 212 | if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) && | 179 | if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) && |
| 213 | Config->Shared) { | 180 | Config->Shared) { |
| ... | @@ -221,40 +188,62 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, | ... | @@ -221,40 +188,62 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, |
| 221 | return 1; | 188 | return 1; |
| 222 | } | 189 | } |
| 223 | 190 | ||
| 224 | if (isRelExprOneOf<R_TLSLD_PC, R_TLSLD>(Expr)) { | 191 | if (isRelExprOneOf<R_TLSLD_GOT, R_TLSLD_GOT_FROM_END, R_TLSLD_PC, |
| 192 | R_TLSLD_HINT>(Expr)) { | ||
| 225 | // Local-Dynamic relocs can be relaxed to Local-Exec. | 193 | // Local-Dynamic relocs can be relaxed to Local-Exec. |
| 226 | if (!Config->Shared) { | 194 | if (!Config->Shared) { |
| 227 | C.Relocations.push_back( | 195 | C.Relocations.push_back( |
| 228 | {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Sym}); | 196 | {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type, |
| 229 | return 2; | 197 | Offset, Addend, &Sym}); |
| 198 | return Target->TlsGdRelaxSkip; | ||
| 230 | } | 199 | } |
| 200 | if (Expr == R_TLSLD_HINT) | ||
| 201 | return 1; | ||
| 231 | if (InX::Got->addTlsIndex()) | 202 | if (InX::Got->addTlsIndex()) |
| 232 | InX::RelaDyn->addReloc({Target->TlsModuleIndexRel, InX::Got, | 203 | InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got, |
| 233 | InX::Got->getTlsIndexOff(), false, nullptr, 0}); | 204 | InX::Got->getTlsIndexOff(), nullptr); |
| 234 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | 205 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); |
| 235 | return 1; | 206 | return 1; |
| 236 | } | 207 | } |
| 237 | 208 | ||
| 238 | // Local-Dynamic relocs can be relaxed to Local-Exec. | 209 | // Local-Dynamic relocs can be relaxed to Local-Exec. |
| 239 | if (isRelExprOneOf<R_ABS, R_TLSLD, R_TLSLD_PC>(Expr) && !Config->Shared) { | 210 | if (Expr == R_ABS && !Config->Shared) { |
| 240 | C.Relocations.push_back({R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Sym}); | 211 | C.Relocations.push_back( |
| 212 | {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_LD_TO_LE), Type, | ||
| 213 | Offset, Addend, &Sym}); | ||
| 241 | return 1; | 214 | return 1; |
| 242 | } | 215 | } |
| 243 | 216 | ||
| 244 | if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD, | 217 | // Local-Dynamic sequence where offset of tls variable relative to dynamic |
| 245 | R_TLSGD_PC>(Expr)) { | 218 | // thread pointer is stored in the got. |
| 219 | if (Expr == R_TLSLD_GOT_OFF) { | ||
| 220 | // Local-Dynamic relocs can be relaxed to local-exec | ||
| 221 | if (!Config->Shared) { | ||
| 222 | C.Relocations.push_back({R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Sym}); | ||
| 223 | return 1; | ||
| 224 | } | ||
| 225 | if (!Sym.isInGot()) { | ||
| 226 | InX::Got->addEntry(Sym); | ||
| 227 | uint64_t Off = Sym.getGotOffset(); | ||
| 228 | InX::Got->Relocations.push_back({R_ABS, Target->TlsOffsetRel, Off, 0, &Sym}); | ||
| 229 | } | ||
| 230 | C.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | ||
| 231 | return 1; | ||
| 232 | } | ||
| 233 | |||
| 234 | if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD_GOT, | ||
| 235 | R_TLSGD_GOT_FROM_END, R_TLSGD_PC>(Expr)) { | ||
| 246 | if (Config->Shared) { | 236 | if (Config->Shared) { |
| 247 | if (InX::Got->addDynTlsEntry(Sym)) { | 237 | if (InX::Got->addDynTlsEntry(Sym)) { |
| 248 | uint64_t Off = InX::Got->getGlobalDynOffset(Sym); | 238 | uint64_t Off = InX::Got->getGlobalDynOffset(Sym); |
| 249 | InX::RelaDyn->addReloc( | 239 | InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, InX::Got, Off, &Sym); |
| 250 | {Target->TlsModuleIndexRel, InX::Got, Off, false, &Sym, 0}); | ||
| 251 | 240 | ||
| 252 | // If the symbol is preemptible we need the dynamic linker to write | 241 | // If the symbol is preemptible we need the dynamic linker to write |
| 253 | // the offset too. | 242 | // the offset too. |
| 254 | uint64_t OffsetOff = Off + Config->Wordsize; | 243 | uint64_t OffsetOff = Off + Config->Wordsize; |
| 255 | if (Sym.IsPreemptible) | 244 | if (Sym.IsPreemptible) |
| 256 | InX::RelaDyn->addReloc( | 245 | InX::RelaDyn->addReloc(Target->TlsOffsetRel, InX::Got, OffsetOff, |
| 257 | {Target->TlsOffsetRel, InX::Got, OffsetOff, false, &Sym, 0}); | 246 | &Sym); |
| 258 | else | 247 | else |
| 259 | InX::Got->Relocations.push_back( | 248 | InX::Got->Relocations.push_back( |
| 260 | {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym}); | 249 | {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Sym}); |
| ... | @@ -271,8 +260,8 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, | ... | @@ -271,8 +260,8 @@ handleTlsRelocation(RelType Type, Symbol &Sym, InputSectionBase &C, |
| 271 | Offset, Addend, &Sym}); | 260 | Offset, Addend, &Sym}); |
| 272 | if (!Sym.isInGot()) { | 261 | if (!Sym.isInGot()) { |
| 273 | InX::Got->addEntry(Sym); | 262 | InX::Got->addEntry(Sym); |
| 274 | InX::RelaDyn->addReloc( | 263 | InX::RelaDyn->addReloc(Target->TlsGotRel, InX::Got, Sym.getGotOffset(), |
| 275 | {Target->TlsGotRel, InX::Got, Sym.getGotOffset(), false, &Sym, 0}); | 264 | &Sym); |
| 276 | } | 265 | } |
| 277 | } else { | 266 | } else { |
| 278 | C.Relocations.push_back( | 267 | C.Relocations.push_back( |
| ... | @@ -336,7 +325,7 @@ static bool isAbsoluteValue(const Symbol &Sym) { | ... | @@ -336,7 +325,7 @@ static bool isAbsoluteValue(const Symbol &Sym) { |
| 336 | 325 | ||
| 337 | // Returns true if Expr refers a PLT entry. | 326 | // Returns true if Expr refers a PLT entry. |
| 338 | static bool needsPlt(RelExpr Expr) { | 327 | static bool needsPlt(RelExpr Expr) { |
| 339 | return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT, R_PLT_PAGE_PC>(Expr); | 328 | return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_PLT_PAGE_PC>(Expr); |
| 340 | } | 329 | } |
| 341 | 330 | ||
| 342 | // Returns true if Expr refers a GOT entry. Note that this function | 331 | // Returns true if Expr refers a GOT entry. Note that this function |
| ... | @@ -352,7 +341,8 @@ static bool needsGot(RelExpr Expr) { | ... | @@ -352,7 +341,8 @@ static bool needsGot(RelExpr Expr) { |
| 352 | // file (PC, or GOT for example). | 341 | // file (PC, or GOT for example). |
| 353 | static bool isRelExpr(RelExpr Expr) { | 342 | static bool isRelExpr(RelExpr Expr) { |
| 354 | return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL, | 343 | return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL, |
| 355 | R_PAGE_PC, R_RELAX_GOT_PC>(Expr); | 344 | R_PPC_CALL, R_PPC_CALL_PLT, R_PAGE_PC, |
| 345 | R_RELAX_GOT_PC>(Expr); | ||
| 356 | } | 346 | } |
| 357 | 347 | ||
| 358 | // Returns true if a given relocation can be computed at link-time. | 348 | // Returns true if a given relocation can be computed at link-time. |
| ... | @@ -367,11 +357,13 @@ static bool isRelExpr(RelExpr Expr) { | ... | @@ -367,11 +357,13 @@ static bool isRelExpr(RelExpr Expr) { |
| 367 | static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, | 357 | static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, |
| 368 | InputSectionBase &S, uint64_t RelOff) { | 358 | InputSectionBase &S, uint64_t RelOff) { |
| 369 | // These expressions always compute a constant | 359 | // These expressions always compute a constant |
| 370 | if (isRelExprOneOf<R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, | 360 | if (isRelExprOneOf< |
| 371 | R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, | 361 | R_GOT_FROM_END, R_GOT_OFF, R_TLSLD_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, |
| 372 | R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, | 362 | R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, |
| 373 | R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC, R_TLSGD, | 363 | R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, |
| 374 | R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E)) | 364 | R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOT_FROM_END, |
| 365 | R_TLSGD_PC, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT, | ||
| 366 | R_TLSLD_HINT>(E)) | ||
| 375 | return true; | 367 | return true; |
| 376 | 368 | ||
| 377 | // These never do, except if the entire file is position dependent or if | 369 | // These never do, except if the entire file is position dependent or if |
| ... | @@ -417,39 +409,45 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, | ... | @@ -417,39 +409,45 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, |
| 417 | } | 409 | } |
| 418 | 410 | ||
| 419 | static RelExpr toPlt(RelExpr Expr) { | 411 | static RelExpr toPlt(RelExpr Expr) { |
| 420 | if (Expr == R_PPC_OPD) | 412 | switch (Expr) { |
| 421 | return R_PPC_PLT_OPD; | 413 | case R_PPC_CALL: |
| 422 | if (Expr == R_PC) | 414 | return R_PPC_CALL_PLT; |
| 415 | case R_PC: | ||
| 423 | return R_PLT_PC; | 416 | return R_PLT_PC; |
| 424 | if (Expr == R_PAGE_PC) | 417 | case R_PAGE_PC: |
| 425 | return R_PLT_PAGE_PC; | 418 | return R_PLT_PAGE_PC; |
| 426 | if (Expr == R_ABS) | 419 | case R_ABS: |
| 427 | return R_PLT; | 420 | return R_PLT; |
| 428 | return Expr; | 421 | default: |
| 422 | return Expr; | ||
| 423 | } | ||
| 429 | } | 424 | } |
| 430 | 425 | ||
| 431 | static RelExpr fromPlt(RelExpr Expr) { | 426 | static RelExpr fromPlt(RelExpr Expr) { |
| 432 | // We decided not to use a plt. Optimize a reference to the plt to a | 427 | // We decided not to use a plt. Optimize a reference to the plt to a |
| 433 | // reference to the symbol itself. | 428 | // reference to the symbol itself. |
| 434 | if (Expr == R_PLT_PC) | 429 | switch (Expr) { |
| 430 | case R_PLT_PC: | ||
| 435 | return R_PC; | 431 | return R_PC; |
| 436 | if (Expr == R_PPC_PLT_OPD) | 432 | case R_PPC_CALL_PLT: |
| 437 | return R_PPC_OPD; | 433 | return R_PPC_CALL; |
| 438 | if (Expr == R_PLT) | 434 | case R_PLT: |
| 439 | return R_ABS; | 435 | return R_ABS; |
| 440 | return Expr; | 436 | default: |
| 437 | return Expr; | ||
| 438 | } | ||
| 441 | } | 439 | } |
| 442 | 440 | ||
| 443 | // Returns true if a given shared symbol is in a read-only segment in a DSO. | 441 | // Returns true if a given shared symbol is in a read-only segment in a DSO. |
| 444 | template <class ELFT> static bool isReadOnly(SharedSymbol *SS) { | 442 | template <class ELFT> static bool isReadOnly(SharedSymbol &SS) { |
| 445 | typedef typename ELFT::Phdr Elf_Phdr; | 443 | typedef typename ELFT::Phdr Elf_Phdr; |
| 446 | 444 | ||
| 447 | // Determine if the symbol is read-only by scanning the DSO's program headers. | 445 | // Determine if the symbol is read-only by scanning the DSO's program headers. |
| 448 | const SharedFile<ELFT> &File = SS->getFile<ELFT>(); | 446 | const SharedFile<ELFT> &File = SS.getFile<ELFT>(); |
| 449 | for (const Elf_Phdr &Phdr : check(File.getObj().program_headers())) | 447 | for (const Elf_Phdr &Phdr : check(File.getObj().program_headers())) |
| 450 | if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) && | 448 | if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) && |
| 451 | !(Phdr.p_flags & ELF::PF_W) && SS->Value >= Phdr.p_vaddr && | 449 | !(Phdr.p_flags & ELF::PF_W) && SS.Value >= Phdr.p_vaddr && |
| 452 | SS->Value < Phdr.p_vaddr + Phdr.p_memsz) | 450 | SS.Value < Phdr.p_vaddr + Phdr.p_memsz) |
| 453 | return true; | 451 | return true; |
| 454 | return false; | 452 | return false; |
| 455 | } | 453 | } |
| ... | @@ -458,26 +456,45 @@ template <class ELFT> static bool isReadOnly(SharedSymbol *SS) { | ... | @@ -458,26 +456,45 @@ template <class ELFT> static bool isReadOnly(SharedSymbol *SS) { |
| 458 | // | 456 | // |
| 459 | // If two or more symbols are at the same offset, and at least one of | 457 | // If two or more symbols are at the same offset, and at least one of |
| 460 | // them are copied by a copy relocation, all of them need to be copied. | 458 | // them are copied by a copy relocation, all of them need to be copied. |
| 461 | // Otherwise, they would refer different places at runtime. | 459 | // Otherwise, they would refer to different places at runtime. |
| 462 | template <class ELFT> | 460 | template <class ELFT> |
| 463 | static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) { | 461 | static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) { |
| 464 | typedef typename ELFT::Sym Elf_Sym; | 462 | typedef typename ELFT::Sym Elf_Sym; |
| 465 | 463 | ||
| 466 | SharedFile<ELFT> &File = SS->getFile<ELFT>(); | 464 | SharedFile<ELFT> &File = SS.getFile<ELFT>(); |
| 467 | 465 | ||
| 468 | std::vector<SharedSymbol *> Ret; | 466 | SmallSet<SharedSymbol *, 4> Ret; |
| 469 | for (const Elf_Sym &S : File.getGlobalELFSyms()) { | 467 | for (const Elf_Sym &S : File.getGlobalELFSyms()) { |
| 470 | if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS || | 468 | if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS || |
| 471 | S.st_value != SS->Value) | 469 | S.st_value != SS.Value) |
| 472 | continue; | 470 | continue; |
| 473 | StringRef Name = check(S.getName(File.getStringTable())); | 471 | StringRef Name = check(S.getName(File.getStringTable())); |
| 474 | Symbol *Sym = Symtab->find(Name); | 472 | Symbol *Sym = Symtab->find(Name); |
| 475 | if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym)) | 473 | if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym)) |
| 476 | Ret.push_back(Alias); | 474 | Ret.insert(Alias); |
| 477 | } | 475 | } |
| 478 | return Ret; | 476 | return Ret; |
| 479 | } | 477 | } |
| 480 | 478 | ||
| 479 | // When a symbol is copy relocated or we create a canonical plt entry, it is | ||
| 480 | // effectively a defined symbol. In the case of copy relocation the symbol is | ||
| 481 | // in .bss and in the case of a canonical plt entry it is in .plt. This function | ||
| 482 | // replaces the existing symbol with a Defined pointing to the appropriate | ||
| 483 | // location. | ||
| 484 | static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value, | ||
| 485 | uint64_t Size) { | ||
| 486 | Symbol Old = Sym; | ||
| 487 | replaceSymbol<Defined>(&Sym, Sym.File, Sym.getName(), Sym.Binding, | ||
| 488 | Sym.StOther, Sym.Type, Value, Size, Sec); | ||
| 489 | Sym.PltIndex = Old.PltIndex; | ||
| 490 | Sym.GotIndex = Old.GotIndex; | ||
| 491 | Sym.VerdefIndex = Old.VerdefIndex; | ||
| 492 | Sym.IsPreemptible = true; | ||
| 493 | Sym.ExportDynamic = true; | ||
| 494 | Sym.IsUsedInRegularObj = true; | ||
| 495 | Sym.Used = true; | ||
| 496 | } | ||
| 497 | |||
| 481 | // Reserve space in .bss or .bss.rel.ro for copy relocation. | 498 | // Reserve space in .bss or .bss.rel.ro for copy relocation. |
| 482 | // | 499 | // |
| 483 | // The copy relocation is pretty much a hack. If you use a copy relocation | 500 | // The copy relocation is pretty much a hack. If you use a copy relocation |
| ... | @@ -520,17 +537,17 @@ static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) { | ... | @@ -520,17 +537,17 @@ static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) { |
| 520 | // to the variable in .bss. This kind of issue is sometimes very hard to | 537 | // to the variable in .bss. This kind of issue is sometimes very hard to |
| 521 | // debug. What's a solution? Instead of exporting a varaible V from a DSO, | 538 | // debug. What's a solution? Instead of exporting a varaible V from a DSO, |
| 522 | // define an accessor getV(). | 539 | // define an accessor getV(). |
| 523 | template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) { | 540 | template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) { |
| 524 | // Copy relocation against zero-sized symbol doesn't make sense. | 541 | // Copy relocation against zero-sized symbol doesn't make sense. |
| 525 | uint64_t SymSize = SS->getSize(); | 542 | uint64_t SymSize = SS.getSize(); |
| 526 | if (SymSize == 0) | 543 | if (SymSize == 0 || SS.Alignment == 0) |
| 527 | fatal("cannot create a copy relocation for symbol " + toString(*SS)); | 544 | fatal("cannot create a copy relocation for symbol " + toString(SS)); |
| 528 | 545 | ||
| 529 | // See if this symbol is in a read-only segment. If so, preserve the symbol's | 546 | // See if this symbol is in a read-only segment. If so, preserve the symbol's |
| 530 | // memory protection by reserving space in the .bss.rel.ro section. | 547 | // memory protection by reserving space in the .bss.rel.ro section. |
| 531 | bool IsReadOnly = isReadOnly<ELFT>(SS); | 548 | bool IsReadOnly = isReadOnly<ELFT>(SS); |
| 532 | BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss", | 549 | BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss", |
| 533 | SymSize, SS->Alignment); | 550 | SymSize, SS.Alignment); |
| 534 | if (IsReadOnly) | 551 | if (IsReadOnly) |
| 535 | InX::BssRelRo->getParent()->addSection(Sec); | 552 | InX::BssRelRo->getParent()->addSection(Sec); |
| 536 | else | 553 | else |
| ... | @@ -539,125 +556,10 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) { | ... | @@ -539,125 +556,10 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) { |
| 539 | // Look through the DSO's dynamic symbol table for aliases and create a | 556 | // Look through the DSO's dynamic symbol table for aliases and create a |
| 540 | // dynamic symbol for each one. This causes the copy relocation to correctly | 557 | // dynamic symbol for each one. This causes the copy relocation to correctly |
| 541 | // interpose any aliases. | 558 | // interpose any aliases. |
| 542 | for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) { | 559 | for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) |
| 543 | Sym->CopyRelSec = Sec; | 560 | replaceWithDefined(*Sym, Sec, 0, Sym->Size); |
| 544 | Sym->IsPreemptible = false; | ||
| 545 | Sym->IsUsedInRegularObj = true; | ||
| 546 | Sym->Used = true; | ||
| 547 | } | ||
| 548 | 561 | ||
| 549 | InX::RelaDyn->addReloc({Target->CopyRel, Sec, 0, false, SS, 0}); | 562 | InX::RelaDyn->addReloc(Target->CopyRel, Sec, 0, &SS); |
| 550 | } | ||
| 551 | |||
| 552 | static void errorOrWarn(const Twine &Msg) { | ||
| 553 | if (!Config->NoinhibitExec) | ||
| 554 | error(Msg); | ||
| 555 | else | ||
| 556 | warn(Msg); | ||
| 557 | } | ||
| 558 | |||
| 559 | // Returns PLT relocation expression. | ||
| 560 | // | ||
| 561 | // This handles a non PIC program call to function in a shared library. In | ||
| 562 | // an ideal world, we could just report an error saying the relocation can | ||
| 563 | // overflow at runtime. In the real world with glibc, crt1.o has a | ||
| 564 | // R_X86_64_PC32 pointing to libc.so. | ||
| 565 | // | ||
| 566 | // The general idea on how to handle such cases is to create a PLT entry and | ||
| 567 | // use that as the function value. | ||
| 568 | // | ||
| 569 | // For the static linking part, we just return a plt expr and everything | ||
| 570 | // else will use the the PLT entry as the address. | ||
| 571 | // | ||
| 572 | // The remaining problem is making sure pointer equality still works. We | ||
| 573 | // need the help of the dynamic linker for that. We let it know that we have | ||
| 574 | // a direct reference to a so symbol by creating an undefined symbol with a | ||
| 575 | // non zero st_value. Seeing that, the dynamic linker resolves the symbol to | ||
| 576 | // the value of the symbol we created. This is true even for got entries, so | ||
| 577 | // pointer equality is maintained. To avoid an infinite loop, the only entry | ||
| 578 | // that points to the real function is a dedicated got entry used by the | ||
| 579 | // plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT, | ||
| 580 | // R_386_JMP_SLOT, etc). | ||
| 581 | static RelExpr getPltExpr(Symbol &Sym, RelExpr Expr, bool &IsConstant) { | ||
| 582 | Sym.NeedsPltAddr = true; | ||
| 583 | Sym.IsPreemptible = false; | ||
| 584 | IsConstant = true; | ||
| 585 | return toPlt(Expr); | ||
| 586 | } | ||
| 587 | |||
| 588 | // This modifies the expression if we can use a copy relocation or point the | ||
| 589 | // symbol to the PLT. | ||
| 590 | template <class ELFT> | ||
| 591 | static RelExpr adjustExpr(Symbol &Sym, RelExpr Expr, RelType Type, | ||
| 592 | InputSectionBase &S, uint64_t RelOff, | ||
| 593 | bool &IsConstant) { | ||
| 594 | // If a relocation can be applied at link-time, we don't need to | ||
| 595 | // create a dynamic relocation in the first place. | ||
| 596 | if (IsConstant) | ||
| 597 | return Expr; | ||
| 598 | |||
| 599 | // We can create any dynamic relocation supported by the dynamic linker if a | ||
| 600 | // section is writable or we are passed -z notext. | ||
| 601 | bool CanWrite = (S.Flags & SHF_WRITE) || !Config->ZText; | ||
| 602 | if (CanWrite && Target->isPicRel(Type)) | ||
| 603 | return Expr; | ||
| 604 | |||
| 605 | // If the relocation is to a weak undef, and we are producing | ||
| 606 | // executable, give up on it and produce a non preemptible 0. | ||
| 607 | if (!Config->Shared && Sym.isUndefWeak()) { | ||
| 608 | Sym.IsPreemptible = false; | ||
| 609 | IsConstant = true; | ||
| 610 | return Expr; | ||
| 611 | } | ||
| 612 | |||
| 613 | // If we got here we know that this relocation would require the dynamic | ||
| 614 | // linker to write a value to read only memory or use an unsupported | ||
| 615 | // relocation. | ||
| 616 | |||
| 617 | // We can hack around it if we are producing an executable and | ||
| 618 | // the refered symbol can be preemepted to refer to the executable. | ||
| 619 | if (!CanWrite && (Config->Shared || (Config->Pic && !isRelExpr(Expr)))) { | ||
| 620 | error( | ||
| 621 | "can't create dynamic relocation " + toString(Type) + " against " + | ||
| 622 | (Sym.getName().empty() ? "local symbol" : "symbol: " + toString(Sym)) + | ||
| 623 | " in readonly segment; recompile object files with -fPIC" + | ||
| 624 | getLocation(S, Sym, RelOff)); | ||
| 625 | return Expr; | ||
| 626 | } | ||
| 627 | |||
| 628 | // Copy relocations are only possible if we are creating an executable and the | ||
| 629 | // symbol is shared. | ||
| 630 | if (!Sym.isShared() || Config->Shared) | ||
| 631 | return Expr; | ||
| 632 | |||
| 633 | if (Sym.getVisibility() != STV_DEFAULT) { | ||
| 634 | error("cannot preempt symbol: " + toString(Sym) + | ||
| 635 | getLocation(S, Sym, RelOff)); | ||
| 636 | return Expr; | ||
| 637 | } | ||
| 638 | |||
| 639 | if (Sym.isObject()) { | ||
| 640 | // Produce a copy relocation. | ||
| 641 | auto *B = dyn_cast<SharedSymbol>(&Sym); | ||
| 642 | if (B && !B->CopyRelSec) { | ||
| 643 | if (Config->ZNocopyreloc) | ||
| 644 | error("unresolvable relocation " + toString(Type) + | ||
| 645 | " against symbol '" + toString(*B) + | ||
| 646 | "'; recompile with -fPIC or remove '-z nocopyreloc'" + | ||
| 647 | getLocation(S, Sym, RelOff)); | ||
| 648 | |||
| 649 | addCopyRelSymbol<ELFT>(B); | ||
| 650 | } | ||
| 651 | IsConstant = true; | ||
| 652 | return Expr; | ||
| 653 | } | ||
| 654 | |||
| 655 | if (Sym.isFunc()) | ||
| 656 | return getPltExpr(Sym, Expr, IsConstant); | ||
| 657 | |||
| 658 | errorOrWarn("symbol '" + toString(Sym) + "' defined in " + | ||
| 659 | toString(Sym.File) + " has no type"); | ||
| 660 | return Expr; | ||
| 661 | } | 563 | } |
| 662 | 564 | ||
| 663 | // MIPS has an odd notion of "paired" relocations to calculate addends. | 565 | // MIPS has an odd notion of "paired" relocations to calculate addends. |
| ... | @@ -732,7 +634,7 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec, | ... | @@ -732,7 +634,7 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec, |
| 732 | return false; | 634 | return false; |
| 733 | 635 | ||
| 734 | bool CanBeExternal = | 636 | bool CanBeExternal = |
| 735 | Sym.computeBinding() != STB_LOCAL && Sym.getVisibility() == STV_DEFAULT; | 637 | Sym.computeBinding() != STB_LOCAL && Sym.Visibility == STV_DEFAULT; |
| 736 | if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal) | 638 | if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal) |
| 737 | return false; | 639 | return false; |
| 738 | 640 | ||
| ... | @@ -760,12 +662,12 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec, | ... | @@ -760,12 +662,12 @@ static bool maybeReportUndefined(Symbol &Sym, InputSectionBase &Sec, |
| 760 | // this for the N32 ABI. Iterate over relocation with the same offset and put | 662 | // this for the N32 ABI. Iterate over relocation with the same offset and put |
| 761 | // theirs types into the single bit-set. | 663 | // theirs types into the single bit-set. |
| 762 | template <class RelTy> static RelType getMipsN32RelType(RelTy *&Rel, RelTy *End) { | 664 | template <class RelTy> static RelType getMipsN32RelType(RelTy *&Rel, RelTy *End) { |
| 763 | RelType Type = Rel->getType(Config->IsMips64EL); | 665 | RelType Type = 0; |
| 764 | uint64_t Offset = Rel->r_offset; | 666 | uint64_t Offset = Rel->r_offset; |
| 765 | 667 | ||
| 766 | int N = 0; | 668 | int N = 0; |
| 767 | while (Rel + 1 != End && (Rel + 1)->r_offset == Offset) | 669 | while (Rel != End && Rel->r_offset == Offset) |
| 768 | Type |= (++Rel)->getType(Config->IsMips64EL) << (8 * ++N); | 670 | Type |= (Rel++)->getType(Config->IsMips64EL) << (8 * N++); |
| 769 | return Type; | 671 | return Type; |
| 770 | } | 672 | } |
| 771 | 673 | ||
| ... | @@ -815,16 +717,34 @@ private: | ... | @@ -815,16 +717,34 @@ private: |
| 815 | }; | 717 | }; |
| 816 | } // namespace | 718 | } // namespace |
| 817 | 719 | ||
| 720 | static void addRelativeReloc(InputSectionBase *IS, uint64_t OffsetInSec, | ||
| 721 | Symbol *Sym, int64_t Addend, RelExpr Expr, | ||
| 722 | RelType Type) { | ||
| 723 | // Add a relative relocation. If RelrDyn section is enabled, and the | ||
| 724 | // relocation offset is guaranteed to be even, add the relocation to | ||
| 725 | // the RelrDyn section, otherwise add it to the RelaDyn section. | ||
| 726 | // RelrDyn sections don't support odd offsets. Also, RelrDyn sections | ||
| 727 | // don't store the addend values, so we must write it to the relocated | ||
| 728 | // address. | ||
| 729 | if (InX::RelrDyn && IS->Alignment >= 2 && OffsetInSec % 2 == 0) { | ||
| 730 | IS->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym}); | ||
| 731 | InX::RelrDyn->Relocs.push_back({IS, OffsetInSec}); | ||
| 732 | return; | ||
| 733 | } | ||
| 734 | InX::RelaDyn->addReloc(Target->RelativeRel, IS, OffsetInSec, Sym, Addend, | ||
| 735 | Expr, Type); | ||
| 736 | } | ||
| 737 | |||
| 818 | template <class ELFT, class GotPltSection> | 738 | template <class ELFT, class GotPltSection> |
| 819 | static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt, | 739 | static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt, |
| 820 | RelocationBaseSection *Rel, RelType Type, Symbol &Sym, | 740 | RelocationBaseSection *Rel, RelType Type, Symbol &Sym) { |
| 821 | bool UseSymVA) { | ||
| 822 | Plt->addEntry<ELFT>(Sym); | 741 | Plt->addEntry<ELFT>(Sym); |
| 823 | GotPlt->addEntry(Sym); | 742 | GotPlt->addEntry(Sym); |
| 824 | Rel->addReloc({Type, GotPlt, Sym.getGotPltOffset(), UseSymVA, &Sym, 0}); | 743 | Rel->addReloc( |
| 744 | {Type, GotPlt, Sym.getGotPltOffset(), !Sym.IsPreemptible, &Sym, 0}); | ||
| 825 | } | 745 | } |
| 826 | 746 | ||
| 827 | template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { | 747 | template <class ELFT> static void addGotEntry(Symbol &Sym) { |
| 828 | InX::Got->addEntry(Sym); | 748 | InX::Got->addEntry(Sym); |
| 829 | 749 | ||
| 830 | RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS; | 750 | RelExpr Expr = Sym.isTls() ? R_TLS : R_ABS; |
| ... | @@ -837,7 +757,8 @@ template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { | ... | @@ -837,7 +757,8 @@ template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { |
| 837 | // add a static relocation to a Relocations vector so that | 757 | // add a static relocation to a Relocations vector so that |
| 838 | // InputSection::relocate will do the work for us. We may be able | 758 | // InputSection::relocate will do the work for us. We may be able |
| 839 | // to just write a value now, but it is a TODO.) | 759 | // to just write a value now, but it is a TODO.) |
| 840 | bool IsLinkTimeConstant = !Preemptible && (!Config->Pic || isAbsolute(Sym)); | 760 | bool IsLinkTimeConstant = |
| 761 | !Sym.IsPreemptible && (!Config->Pic || isAbsolute(Sym)); | ||
| 841 | if (IsLinkTimeConstant) { | 762 | if (IsLinkTimeConstant) { |
| 842 | InX::Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym}); | 763 | InX::Got->Relocations.push_back({Expr, Target->GotRel, Off, 0, &Sym}); |
| 843 | return; | 764 | return; |
| ... | @@ -845,23 +766,33 @@ template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { | ... | @@ -845,23 +766,33 @@ template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { |
| 845 | 766 | ||
| 846 | // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that | 767 | // Otherwise, we emit a dynamic relocation to .rel[a].dyn so that |
| 847 | // the GOT slot will be fixed at load-time. | 768 | // the GOT slot will be fixed at load-time. |
| 848 | RelType Type; | 769 | if (!Sym.isTls() && !Sym.IsPreemptible && Config->Pic && !isAbsolute(Sym)) { |
| 849 | if (Sym.isTls()) | 770 | addRelativeReloc(InX::Got, Off, &Sym, 0, R_ABS, Target->GotRel); |
| 850 | Type = Target->TlsGotRel; | 771 | return; |
| 851 | else if (!Preemptible && Config->Pic && !isAbsolute(Sym)) | 772 | } |
| 852 | Type = Target->RelativeRel; | 773 | InX::RelaDyn->addReloc(Sym.isTls() ? Target->TlsGotRel : Target->GotRel, |
| 853 | else | 774 | InX::Got, Off, &Sym, 0, |
| 854 | Type = Target->GotRel; | 775 | Sym.IsPreemptible ? R_ADDEND : R_ABS, Target->GotRel); |
| 855 | InX::RelaDyn->addReloc({Type, InX::Got, Off, !Preemptible, &Sym, 0}); | 776 | } |
| 856 | 777 | ||
| 857 | // REL type relocations don't have addend fields unlike RELAs, and | 778 | // Return true if we can define a symbol in the executable that |
| 858 | // their addends are stored to the section to which they are applied. | 779 | // contains the value/function of a symbol defined in a shared |
| 859 | // So, store addends if we need to. | 780 | // library. |
| 860 | // | 781 | static bool canDefineSymbolInExecutable(Symbol &Sym) { |
| 861 | // This is ugly -- the difference between REL and RELA should be | 782 | // If the symbol has default visibility the symbol defined in the |
| 862 | // handled in a better way. It's a TODO. | 783 | // executable will preempt it. |
| 863 | if (!Config->IsRela && !Preemptible) | 784 | // Note that we want the visibility of the shared symbol itself, not |
| 864 | InX::Got->Relocations.push_back({R_ABS, Target->GotRel, Off, 0, &Sym}); | 785 | // the visibility of the symbol in the output file we are producing. That is |
| 786 | // why we use Sym.StOther. | ||
| 787 | if ((Sym.StOther & 0x3) == STV_DEFAULT) | ||
| 788 | return true; | ||
| 789 | |||
| 790 | // If we are allowed to break address equality of functions, defining | ||
| 791 | // a plt entry will allow the program to call the function in the | ||
| 792 | // .so, but the .so and the executable will no agree on the address | ||
| 793 | // of the function. Similar logic for objects. | ||
| 794 | return ((Sym.isFunc() && Config->IgnoreFunctionAddressEquality) || | ||
| 795 | (Sym.isObject() && Config->IgnoreDataAddressEquality)); | ||
| 865 | } | 796 | } |
| 866 | 797 | ||
| 867 | // The reason we have to do this early scan is as follows | 798 | // The reason we have to do this early scan is as follows |
| ... | @@ -878,129 +809,23 @@ template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { | ... | @@ -878,129 +809,23 @@ template <class ELFT> static void addGotEntry(Symbol &Sym, bool Preemptible) { |
| 878 | // complicates things for the dynamic linker and means we would have to reserve | 809 | // complicates things for the dynamic linker and means we would have to reserve |
| 879 | // space for the extra PT_LOAD even if we end up not using it. | 810 | // space for the extra PT_LOAD even if we end up not using it. |
| 880 | template <class ELFT, class RelTy> | 811 | template <class ELFT, class RelTy> |
| 881 | static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { | 812 | static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type, |
| 882 | OffsetGetter GetOffset(Sec); | 813 | uint64_t Offset, Symbol &Sym, const RelTy &Rel, |
| 883 | 814 | int64_t Addend) { | |
| 884 | // Not all relocations end up in Sec.Relocations, but a lot do. | 815 | if (isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Offset)) { |
| 885 | Sec.Relocations.reserve(Rels.size()); | 816 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); |
| 886 | 817 | return; | |
| 887 | for (auto I = Rels.begin(), End = Rels.end(); I != End; ++I) { | 818 | } |
| 888 | const RelTy &Rel = *I; | 819 | bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText; |
| 889 | Symbol &Sym = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); | 820 | if (CanWrite) { |
| 890 | RelType Type = Rel.getType(Config->IsMips64EL); | 821 | // R_GOT refers to a position in the got, even if the symbol is preemptible. |
| 891 | 822 | bool IsPreemptibleValue = Sym.IsPreemptible && Expr != R_GOT; | |
| 892 | // Deal with MIPS oddity. | ||
| 893 | if (Config->MipsN32Abi) | ||
| 894 | Type = getMipsN32RelType(I, End); | ||
| 895 | |||
| 896 | // Get an offset in an output section this relocation is applied to. | ||
| 897 | uint64_t Offset = GetOffset.get(Rel.r_offset); | ||
| 898 | if (Offset == uint64_t(-1)) | ||
| 899 | continue; | ||
| 900 | |||
| 901 | // Skip if the target symbol is an erroneous undefined symbol. | ||
| 902 | if (maybeReportUndefined(Sym, Sec, Rel.r_offset)) | ||
| 903 | continue; | ||
| 904 | |||
| 905 | RelExpr Expr = | ||
| 906 | Target->getRelExpr(Type, Sym, Sec.Data.begin() + Rel.r_offset); | ||
| 907 | |||
| 908 | // Ignore "hint" relocations because they are only markers for relaxation. | ||
| 909 | if (isRelExprOneOf<R_HINT, R_NONE>(Expr)) | ||
| 910 | continue; | ||
| 911 | |||
| 912 | // Handle yet another MIPS-ness. | ||
| 913 | if (isMipsGprel(Type)) { | ||
| 914 | int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal()); | ||
| 915 | Sec.Relocations.push_back({R_MIPS_GOTREL, Type, Offset, Addend, &Sym}); | ||
| 916 | continue; | ||
| 917 | } | ||
| 918 | |||
| 919 | bool Preemptible = Sym.IsPreemptible; | ||
| 920 | |||
| 921 | // Strenghten or relax a PLT access. | ||
| 922 | // | ||
| 923 | // GNU ifunc symbols must be accessed via PLT because their addresses | ||
| 924 | // are determined by runtime. | ||
| 925 | // | ||
| 926 | // On the other hand, if we know that a PLT entry will be resolved within | ||
| 927 | // the same ELF module, we can skip PLT access and directly jump to the | ||
| 928 | // destination function. For example, if we are linking a main exectuable, | ||
| 929 | // all dynamic symbols that can be resolved within the executable will | ||
| 930 | // actually be resolved that way at runtime, because the main exectuable | ||
| 931 | // is always at the beginning of a search list. We can leverage that fact. | ||
| 932 | if (Sym.isGnuIFunc()) | ||
| 933 | Expr = toPlt(Expr); | ||
| 934 | else if (!Preemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym)) | ||
| 935 | Expr = | ||
| 936 | Target->adjustRelaxExpr(Type, Sec.Data.data() + Rel.r_offset, Expr); | ||
| 937 | else if (!Preemptible) | ||
| 938 | Expr = fromPlt(Expr); | ||
| 939 | |||
| 940 | bool IsConstant = | ||
| 941 | isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Rel.r_offset); | ||
| 942 | |||
| 943 | Expr = adjustExpr<ELFT>(Sym, Expr, Type, Sec, Rel.r_offset, IsConstant); | ||
| 944 | if (errorCount()) | ||
| 945 | continue; | ||
| 946 | |||
| 947 | // This relocation does not require got entry, but it is relative to got and | ||
| 948 | // needs it to be created. Here we request for that. | ||
| 949 | if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL, | ||
| 950 | R_GOTREL_FROM_END, R_PPC_TOC>(Expr)) | ||
| 951 | InX::Got->HasGotOffRel = true; | ||
| 952 | |||
| 953 | // Read an addend. | ||
| 954 | int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal()); | ||
| 955 | |||
| 956 | // Process some TLS relocations, including relaxing TLS relocations. | ||
| 957 | // Note that this function does not handle all TLS relocations. | ||
| 958 | if (unsigned Processed = | ||
| 959 | handleTlsRelocation<ELFT>(Type, Sym, Sec, Offset, Addend, Expr)) { | ||
| 960 | I += (Processed - 1); | ||
| 961 | continue; | ||
| 962 | } | ||
| 963 | |||
| 964 | // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol. | ||
| 965 | if (needsPlt(Expr) && !Sym.isInPlt()) { | ||
| 966 | if (Sym.isGnuIFunc() && !Preemptible) | ||
| 967 | addPltEntry<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt, | ||
| 968 | Target->IRelativeRel, Sym, true); | ||
| 969 | else | ||
| 970 | addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel, | ||
| 971 | Sym, !Preemptible); | ||
| 972 | } | ||
| 973 | |||
| 974 | // Create a GOT slot if a relocation needs GOT. | ||
| 975 | if (needsGot(Expr)) { | ||
| 976 | if (Config->EMachine == EM_MIPS) { | ||
| 977 | // MIPS ABI has special rules to process GOT entries and doesn't | ||
| 978 | // require relocation entries for them. A special case is TLS | ||
| 979 | // relocations. In that case dynamic loader applies dynamic | ||
| 980 | // relocations to initialize TLS GOT entries. | ||
| 981 | // See "Global Offset Table" in Chapter 5 in the following document | ||
| 982 | // for detailed description: | ||
| 983 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf | ||
| 984 | InX::MipsGot->addEntry(Sym, Addend, Expr); | ||
| 985 | if (Sym.isTls() && Sym.IsPreemptible) | ||
| 986 | InX::RelaDyn->addReloc({Target->TlsGotRel, InX::MipsGot, | ||
| 987 | Sym.getGotOffset(), false, &Sym, 0}); | ||
| 988 | } else if (!Sym.isInGot()) { | ||
| 989 | addGotEntry<ELFT>(Sym, Preemptible); | ||
| 990 | } | ||
| 991 | } | ||
| 992 | |||
| 993 | if (!needsPlt(Expr) && !needsGot(Expr) && Sym.IsPreemptible) { | ||
| 994 | // We don't know anything about the finaly symbol. Just ask the dynamic | ||
| 995 | // linker to handle the relocation for us. | ||
| 996 | if (!Target->isPicRel(Type)) | ||
| 997 | errorOrWarn( | ||
| 998 | "relocation " + toString(Type) + | ||
| 999 | " cannot be used against shared object; recompile with -fPIC" + | ||
| 1000 | getLocation(Sec, Sym, Offset)); | ||
| 1001 | 823 | ||
| 1002 | InX::RelaDyn->addReloc( | 824 | if (!IsPreemptibleValue) { |
| 1003 | {Target->getDynRel(Type), &Sec, Offset, false, &Sym, Addend}); | 825 | addRelativeReloc(&Sec, Offset, &Sym, Addend, Expr, Type); |
| 826 | return; | ||
| 827 | } else if (RelType Rel = Target->getDynRel(Type)) { | ||
| 828 | InX::RelaDyn->addReloc(Rel, &Sec, Offset, &Sym, Addend, R_ADDEND, Type); | ||
| 1004 | 829 | ||
| 1005 | // MIPS ABI turns using of GOT and dynamic relocations inside out. | 830 | // MIPS ABI turns using of GOT and dynamic relocations inside out. |
| 1006 | // While regular ABI uses dynamic relocations to fill up GOT entries | 831 | // While regular ABI uses dynamic relocations to fill up GOT entries |
| ... | @@ -1018,37 +843,210 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { | ... | @@ -1018,37 +843,210 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { |
| 1018 | // a dynamic relocation. | 843 | // a dynamic relocation. |
| 1019 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19 | 844 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19 |
| 1020 | if (Config->EMachine == EM_MIPS) | 845 | if (Config->EMachine == EM_MIPS) |
| 1021 | InX::MipsGot->addEntry(Sym, Addend, Expr); | 846 | InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr); |
| 1022 | continue; | 847 | return; |
| 1023 | } | 848 | } |
| 849 | } | ||
| 1024 | 850 | ||
| 1025 | // The size is not going to change, so we fold it in here. | 851 | // If the relocation is to a weak undef, and we are producing |
| 1026 | if (Expr == R_SIZE) | 852 | // executable, give up on it and produce a non preemptible 0. |
| 1027 | Addend += Sym.getSize(); | 853 | if (!Config->Shared && Sym.isUndefWeak()) { |
| 854 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | ||
| 855 | return; | ||
| 856 | } | ||
| 1028 | 857 | ||
| 1029 | // If the produced value is a constant, we just remember to write it | 858 | if (!CanWrite && (Config->Pic && !isRelExpr(Expr))) { |
| 1030 | // when outputting this section. We also have to do it if the format | 859 | error( |
| 1031 | // uses Elf_Rel, since in that case the written value is the addend. | 860 | "can't create dynamic relocation " + toString(Type) + " against " + |
| 1032 | if (IsConstant) { | 861 | (Sym.getName().empty() ? "local symbol" : "symbol: " + toString(Sym)) + |
| 1033 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | 862 | " in readonly segment; recompile object files with -fPIC " |
| 1034 | continue; | 863 | "or pass '-Wl,-z,notext' to allow text relocations in the output" + |
| 864 | getLocation(Sec, Sym, Offset)); | ||
| 865 | return; | ||
| 866 | } | ||
| 867 | |||
| 868 | // Copy relocations are only possible if we are creating an executable. | ||
| 869 | if (Config->Shared) { | ||
| 870 | errorOrWarn("relocation " + toString(Type) + | ||
| 871 | " cannot be used against symbol " + toString(Sym) + | ||
| 872 | "; recompile with -fPIC" + getLocation(Sec, Sym, Offset)); | ||
| 873 | return; | ||
| 874 | } | ||
| 875 | |||
| 876 | // If the symbol is undefined we already reported any relevant errors. | ||
| 877 | if (Sym.isUndefined()) | ||
| 878 | return; | ||
| 879 | |||
| 880 | if (!canDefineSymbolInExecutable(Sym)) { | ||
| 881 | error("cannot preempt symbol: " + toString(Sym) + | ||
| 882 | getLocation(Sec, Sym, Offset)); | ||
| 883 | return; | ||
| 884 | } | ||
| 885 | |||
| 886 | if (Sym.isObject()) { | ||
| 887 | // Produce a copy relocation. | ||
| 888 | if (auto *SS = dyn_cast<SharedSymbol>(&Sym)) { | ||
| 889 | if (!Config->ZCopyreloc) | ||
| 890 | error("unresolvable relocation " + toString(Type) + | ||
| 891 | " against symbol '" + toString(*SS) + | ||
| 892 | "'; recompile with -fPIC or remove '-z nocopyreloc'" + | ||
| 893 | getLocation(Sec, Sym, Offset)); | ||
| 894 | addCopyRelSymbol<ELFT>(*SS); | ||
| 1035 | } | 895 | } |
| 896 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | ||
| 897 | return; | ||
| 898 | } | ||
| 1036 | 899 | ||
| 1037 | // If the output being produced is position independent, the final value | 900 | if (Sym.isFunc()) { |
| 1038 | // is still not known. In that case we still need some help from the | 901 | // This handles a non PIC program call to function in a shared library. In |
| 1039 | // dynamic linker. We can however do better than just copying the incoming | 902 | // an ideal world, we could just report an error saying the relocation can |
| 1040 | // relocation. We can process some of it and and just ask the dynamic | 903 | // overflow at runtime. In the real world with glibc, crt1.o has a |
| 1041 | // linker to add the load address. | 904 | // R_X86_64_PC32 pointing to libc.so. |
| 1042 | if (Config->IsRela) { | 905 | // |
| 1043 | InX::RelaDyn->addReloc( | 906 | // The general idea on how to handle such cases is to create a PLT entry and |
| 1044 | {Target->RelativeRel, &Sec, Offset, true, &Sym, Addend}); | 907 | // use that as the function value. |
| 1045 | } else { | 908 | // |
| 1046 | // In REL, addends are stored to the target section. | 909 | // For the static linking part, we just return a plt expr and everything |
| 1047 | InX::RelaDyn->addReloc( | 910 | // else will use the PLT entry as the address. |
| 1048 | {Target->RelativeRel, &Sec, Offset, true, &Sym, 0}); | 911 | // |
| 1049 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | 912 | // The remaining problem is making sure pointer equality still works. We |
| 913 | // need the help of the dynamic linker for that. We let it know that we have | ||
| 914 | // a direct reference to a so symbol by creating an undefined symbol with a | ||
| 915 | // non zero st_value. Seeing that, the dynamic linker resolves the symbol to | ||
| 916 | // the value of the symbol we created. This is true even for got entries, so | ||
| 917 | // pointer equality is maintained. To avoid an infinite loop, the only entry | ||
| 918 | // that points to the real function is a dedicated got entry used by the | ||
| 919 | // plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT, | ||
| 920 | // R_386_JMP_SLOT, etc). | ||
| 921 | |||
| 922 | // For position independent executable on i386, the plt entry requires ebx | ||
| 923 | // to be set. This causes two problems: | ||
| 924 | // * If some code has a direct reference to a function, it was probably | ||
| 925 | // compiled without -fPIE/-fPIC and doesn't maintain ebx. | ||
| 926 | // * If a library definition gets preempted to the executable, it will have | ||
| 927 | // the wrong ebx value. | ||
| 928 | if (Config->Pie && Config->EMachine == EM_386) | ||
| 929 | errorOrWarn("symbol '" + toString(Sym) + | ||
| 930 | "' cannot be preempted; recompile with -fPIE" + | ||
| 931 | getLocation(Sec, Sym, Offset)); | ||
| 932 | if (!Sym.isInPlt()) | ||
| 933 | addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel, | ||
| 934 | Sym); | ||
| 935 | if (!Sym.isDefined()) | ||
| 936 | replaceWithDefined(Sym, InX::Plt, Sym.getPltOffset(), 0); | ||
| 937 | Sym.NeedsPltAddr = true; | ||
| 938 | Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); | ||
| 939 | return; | ||
| 940 | } | ||
| 941 | |||
| 942 | errorOrWarn("symbol '" + toString(Sym) + "' has no type" + | ||
| 943 | getLocation(Sec, Sym, Offset)); | ||
| 944 | } | ||
| 945 | |||
| 946 | template <class ELFT, class RelTy> | ||
| 947 | static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I, | ||
| 948 | RelTy *End) { | ||
| 949 | const RelTy &Rel = *I; | ||
| 950 | Symbol &Sym = Sec.getFile<ELFT>()->getRelocTargetSym(Rel); | ||
| 951 | RelType Type; | ||
| 952 | |||
| 953 | // Deal with MIPS oddity. | ||
| 954 | if (Config->MipsN32Abi) { | ||
| 955 | Type = getMipsN32RelType(I, End); | ||
| 956 | } else { | ||
| 957 | Type = Rel.getType(Config->IsMips64EL); | ||
| 958 | ++I; | ||
| 959 | } | ||
| 960 | |||
| 961 | // Get an offset in an output section this relocation is applied to. | ||
| 962 | uint64_t Offset = GetOffset.get(Rel.r_offset); | ||
| 963 | if (Offset == uint64_t(-1)) | ||
| 964 | return; | ||
| 965 | |||
| 966 | // Skip if the target symbol is an erroneous undefined symbol. | ||
| 967 | if (maybeReportUndefined(Sym, Sec, Rel.r_offset)) | ||
| 968 | return; | ||
| 969 | |||
| 970 | const uint8_t *RelocatedAddr = Sec.Data.begin() + Rel.r_offset; | ||
| 971 | RelExpr Expr = Target->getRelExpr(Type, Sym, RelocatedAddr); | ||
| 972 | |||
| 973 | // Ignore "hint" relocations because they are only markers for relaxation. | ||
| 974 | if (isRelExprOneOf<R_HINT, R_NONE>(Expr)) | ||
| 975 | return; | ||
| 976 | |||
| 977 | // Strenghten or relax relocations. | ||
| 978 | // | ||
| 979 | // GNU ifunc symbols must be accessed via PLT because their addresses | ||
| 980 | // are determined by runtime. | ||
| 981 | // | ||
| 982 | // On the other hand, if we know that a PLT entry will be resolved within | ||
| 983 | // the same ELF module, we can skip PLT access and directly jump to the | ||
| 984 | // destination function. For example, if we are linking a main exectuable, | ||
| 985 | // all dynamic symbols that can be resolved within the executable will | ||
| 986 | // actually be resolved that way at runtime, because the main exectuable | ||
| 987 | // is always at the beginning of a search list. We can leverage that fact. | ||
| 988 | if (Sym.isGnuIFunc()) | ||
| 989 | Expr = toPlt(Expr); | ||
| 990 | else if (!Sym.IsPreemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym)) | ||
| 991 | Expr = Target->adjustRelaxExpr(Type, RelocatedAddr, Expr); | ||
| 992 | else if (!Sym.IsPreemptible) | ||
| 993 | Expr = fromPlt(Expr); | ||
| 994 | |||
| 995 | // This relocation does not require got entry, but it is relative to got and | ||
| 996 | // needs it to be created. Here we request for that. | ||
| 997 | if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL, | ||
| 998 | R_GOTREL_FROM_END, R_PPC_TOC>(Expr)) | ||
| 999 | InX::Got->HasGotOffRel = true; | ||
| 1000 | |||
| 1001 | // Read an addend. | ||
| 1002 | int64_t Addend = computeAddend<ELFT>(Rel, End, Sec, Expr, Sym.isLocal()); | ||
| 1003 | |||
| 1004 | // Process some TLS relocations, including relaxing TLS relocations. | ||
| 1005 | // Note that this function does not handle all TLS relocations. | ||
| 1006 | if (unsigned Processed = | ||
| 1007 | handleTlsRelocation<ELFT>(Type, Sym, Sec, Offset, Addend, Expr)) { | ||
| 1008 | I += (Processed - 1); | ||
| 1009 | return; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol. | ||
| 1013 | if (needsPlt(Expr) && !Sym.isInPlt()) { | ||
| 1014 | if (Sym.isGnuIFunc() && !Sym.IsPreemptible) | ||
| 1015 | addPltEntry<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt, | ||
| 1016 | Target->IRelativeRel, Sym); | ||
| 1017 | else | ||
| 1018 | addPltEntry<ELFT>(InX::Plt, InX::GotPlt, InX::RelaPlt, Target->PltRel, | ||
| 1019 | Sym); | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | // Create a GOT slot if a relocation needs GOT. | ||
| 1023 | if (needsGot(Expr)) { | ||
| 1024 | if (Config->EMachine == EM_MIPS) { | ||
| 1025 | // MIPS ABI has special rules to process GOT entries and doesn't | ||
| 1026 | // require relocation entries for them. A special case is TLS | ||
| 1027 | // relocations. In that case dynamic loader applies dynamic | ||
| 1028 | // relocations to initialize TLS GOT entries. | ||
| 1029 | // See "Global Offset Table" in Chapter 5 in the following document | ||
| 1030 | // for detailed description: | ||
| 1031 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf | ||
| 1032 | InX::MipsGot->addEntry(*Sec.File, Sym, Addend, Expr); | ||
| 1033 | } else if (!Sym.isInGot()) { | ||
| 1034 | addGotEntry<ELFT>(Sym); | ||
| 1050 | } | 1035 | } |
| 1051 | } | 1036 | } |
| 1037 | |||
| 1038 | processRelocAux<ELFT>(Sec, Expr, Type, Offset, Sym, Rel, Addend); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | template <class ELFT, class RelTy> | ||
| 1042 | static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) { | ||
| 1043 | OffsetGetter GetOffset(Sec); | ||
| 1044 | |||
| 1045 | // Not all relocations end up in Sec.Relocations, but a lot do. | ||
| 1046 | Sec.Relocations.reserve(Rels.size()); | ||
| 1047 | |||
| 1048 | for (auto I = Rels.begin(), End = Rels.end(); I != End;) | ||
| 1049 | scanReloc<ELFT>(Sec, GetOffset, I, End); | ||
| 1052 | } | 1050 | } |
| 1053 | 1051 | ||
| 1054 | template <class ELFT> void elf::scanRelocations(InputSectionBase &S) { | 1052 | template <class ELFT> void elf::scanRelocations(InputSectionBase &S) { |
| ... | @@ -1263,17 +1261,30 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) { | ... | @@ -1263,17 +1261,30 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) { |
| 1263 | // | 1261 | // |
| 1264 | // We follow a simple but conservative heuristic to place ThunkSections at | 1262 | // We follow a simple but conservative heuristic to place ThunkSections at |
| 1265 | // offsets that are multiples of a Target specific branch range. | 1263 | // offsets that are multiples of a Target specific branch range. |
| 1266 | // For an InputSectionRange that is smaller than the range, a single | 1264 | // For an InputSectionDescription that is smaller than the range, a single |
| 1267 | // ThunkSection at the end of the range will do. | 1265 | // ThunkSection at the end of the range will do. |
| 1266 | // | ||
| 1267 | // For an InputSectionDescription that is more than twice the size of the range, | ||
| 1268 | // we place the last ThunkSection at range bytes from the end of the | ||
| 1269 | // InputSectionDescription in order to increase the likelihood that the | ||
| 1270 | // distance from a thunk to its target will be sufficiently small to | ||
| 1271 | // allow for the creation of a short thunk. | ||
| 1268 | void ThunkCreator::createInitialThunkSections( | 1272 | void ThunkCreator::createInitialThunkSections( |
| 1269 | ArrayRef<OutputSection *> OutputSections) { | 1273 | ArrayRef<OutputSection *> OutputSections) { |
| 1270 | forEachInputSectionDescription( | 1274 | forEachInputSectionDescription( |
| 1271 | OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) { | 1275 | OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) { |
| 1272 | if (ISD->Sections.empty()) | 1276 | if (ISD->Sections.empty()) |
| 1273 | return; | 1277 | return; |
| 1278 | uint32_t ISDBegin = ISD->Sections.front()->OutSecOff; | ||
| 1279 | uint32_t ISDEnd = | ||
| 1280 | ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize(); | ||
| 1281 | uint32_t LastThunkLowerBound = -1; | ||
| 1282 | if (ISDEnd - ISDBegin > Target->ThunkSectionSpacing * 2) | ||
| 1283 | LastThunkLowerBound = ISDEnd - Target->ThunkSectionSpacing; | ||
| 1284 | |||
| 1274 | uint32_t ISLimit; | 1285 | uint32_t ISLimit; |
| 1275 | uint32_t PrevISLimit = ISD->Sections.front()->OutSecOff; | 1286 | uint32_t PrevISLimit = ISDBegin; |
| 1276 | uint32_t ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing; | 1287 | uint32_t ThunkUpperBound = ISDBegin + Target->ThunkSectionSpacing; |
| 1277 | 1288 | ||
| 1278 | for (const InputSection *IS : ISD->Sections) { | 1289 | for (const InputSection *IS : ISD->Sections) { |
| 1279 | ISLimit = IS->OutSecOff + IS->getSize(); | 1290 | ISLimit = IS->OutSecOff + IS->getSize(); |
| ... | @@ -1281,6 +1292,8 @@ void ThunkCreator::createInitialThunkSections( | ... | @@ -1281,6 +1292,8 @@ void ThunkCreator::createInitialThunkSections( |
| 1281 | addThunkSection(OS, ISD, PrevISLimit); | 1292 | addThunkSection(OS, ISD, PrevISLimit); |
| 1282 | ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing; | 1293 | ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing; |
| 1283 | } | 1294 | } |
| 1295 | if (ISLimit > LastThunkLowerBound) | ||
| 1296 | break; | ||
| 1284 | PrevISLimit = ISLimit; | 1297 | PrevISLimit = ISLimit; |
| 1285 | } | 1298 | } |
| 1286 | addThunkSection(OS, ISD, ISLimit); | 1299 | addThunkSection(OS, ISD, ISLimit); |
| ... | @@ -1297,17 +1310,22 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS, | ... | @@ -1297,17 +1310,22 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS, |
| 1297 | 1310 | ||
| 1298 | std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type, | 1311 | std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type, |
| 1299 | uint64_t Src) { | 1312 | uint64_t Src) { |
| 1300 | auto Res = ThunkedSymbols.insert({&Sym, std::vector<Thunk *>()}); | 1313 | std::vector<Thunk *> *ThunkVec = nullptr; |
| 1301 | if (!Res.second) { | 1314 | // We use (section, offset) pair to find the thunk position if possible so |
| 1302 | // Check existing Thunks for Sym to see if they can be reused | 1315 | // that we create only one thunk for aliased symbols or ICFed sections. |
| 1303 | for (Thunk *ET : Res.first->second) | 1316 | if (auto *D = dyn_cast<Defined>(&Sym)) |
| 1304 | if (ET->isCompatibleWith(Type) && | 1317 | if (!D->isInPlt() && D->Section) |
| 1305 | Target->inBranchRange(Type, Src, ET->ThunkSym->getVA())) | 1318 | ThunkVec = &ThunkedSymbolsBySection[{D->Section->Repl, D->Value}]; |
| 1306 | return std::make_pair(ET, false); | 1319 | if (!ThunkVec) |
| 1307 | } | 1320 | ThunkVec = &ThunkedSymbols[&Sym]; |
| 1321 | // Check existing Thunks for Sym to see if they can be reused | ||
| 1322 | for (Thunk *ET : *ThunkVec) | ||
| 1323 | if (ET->isCompatibleWith(Type) && | ||
| 1324 | Target->inBranchRange(Type, Src, ET->getThunkTargetSym()->getVA())) | ||
| 1325 | return std::make_pair(ET, false); | ||
| 1308 | // No existing compatible Thunk in range, create a new one | 1326 | // No existing compatible Thunk in range, create a new one |
| 1309 | Thunk *T = addThunk(Type, Sym); | 1327 | Thunk *T = addThunk(Type, Sym); |
| 1310 | Res.first->second.push_back(T); | 1328 | ThunkVec->push_back(T); |
| 1311 | return std::make_pair(T, true); | 1329 | return std::make_pair(T, true); |
| 1312 | } | 1330 | } |
| 1313 | 1331 | ||
| ... | @@ -1315,7 +1333,7 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type, | ... | @@ -1315,7 +1333,7 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type, |
| 1315 | // InputSectionDescription::Sections. | 1333 | // InputSectionDescription::Sections. |
| 1316 | void ThunkCreator::forEachInputSectionDescription( | 1334 | void ThunkCreator::forEachInputSectionDescription( |
| 1317 | ArrayRef<OutputSection *> OutputSections, | 1335 | ArrayRef<OutputSection *> OutputSections, |
| 1318 | std::function<void(OutputSection *, InputSectionDescription *)> Fn) { | 1336 | llvm::function_ref<void(OutputSection *, InputSectionDescription *)> Fn) { |
| 1319 | for (OutputSection *OS : OutputSections) { | 1337 | for (OutputSection *OS : OutputSections) { |
| 1320 | if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR)) | 1338 | if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR)) |
| 1321 | continue; | 1339 | continue; |
| ... | @@ -1383,7 +1401,7 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) { | ... | @@ -1383,7 +1401,7 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) { |
| 1383 | OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) { | 1401 | OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) { |
| 1384 | for (InputSection *IS : ISD->Sections) | 1402 | for (InputSection *IS : ISD->Sections) |
| 1385 | for (Relocation &Rel : IS->Relocations) { | 1403 | for (Relocation &Rel : IS->Relocations) { |
| 1386 | uint64_t Src = OS->Addr + IS->OutSecOff + Rel.Offset; | 1404 | uint64_t Src = IS->getVA(Rel.Offset); |
| 1387 | 1405 | ||
| 1388 | // If we are a relocation to an existing Thunk, check if it is | 1406 | // If we are a relocation to an existing Thunk, check if it is |
| 1389 | // still in range. If not then Rel will be altered to point to its | 1407 | // still in range. If not then Rel will be altered to point to its |
| ... | @@ -1398,7 +1416,6 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) { | ... | @@ -1398,7 +1416,6 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) { |
| 1398 | bool IsNew; | 1416 | bool IsNew; |
| 1399 | std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src); | 1417 | std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src); |
| 1400 | if (IsNew) { | 1418 | if (IsNew) { |
| 1401 | AddressesChanged = true; | ||
| 1402 | // Find or create a ThunkSection for the new Thunk | 1419 | // Find or create a ThunkSection for the new Thunk |
| 1403 | ThunkSection *TS; | 1420 | ThunkSection *TS; |
| 1404 | if (auto *TIS = T->getTargetInputSection()) | 1421 | if (auto *TIS = T->getTargetInputSection()) |
| ... | @@ -1406,13 +1423,18 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) { | ... | @@ -1406,13 +1423,18 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) { |
| 1406 | else | 1423 | else |
| 1407 | TS = getISDThunkSec(OS, IS, ISD, Rel.Type, Src); | 1424 | TS = getISDThunkSec(OS, IS, ISD, Rel.Type, Src); |
| 1408 | TS->addThunk(T); | 1425 | TS->addThunk(T); |
| 1409 | Thunks[T->ThunkSym] = T; | 1426 | Thunks[T->getThunkTargetSym()] = T; |
| 1410 | } | 1427 | } |
| 1411 | // Redirect relocation to Thunk, we never go via the PLT to a Thunk | 1428 | // Redirect relocation to Thunk, we never go via the PLT to a Thunk |
| 1412 | Rel.Sym = T->ThunkSym; | 1429 | Rel.Sym = T->getThunkTargetSym(); |
| 1413 | Rel.Expr = fromPlt(Rel.Expr); | 1430 | Rel.Expr = fromPlt(Rel.Expr); |
| 1414 | } | 1431 | } |
| 1432 | for (auto &P : ISD->ThunkSections) | ||
| 1433 | AddressesChanged |= P.first->assignOffsets(); | ||
| 1415 | }); | 1434 | }); |
| 1435 | for (auto &P : ThunkedSections) | ||
| 1436 | AddressesChanged |= P.second->assignOffsets(); | ||
| 1437 | |||
| 1416 | // Merge all created synthetic ThunkSections back into OutputSection | 1438 | // Merge all created synthetic ThunkSections back into OutputSection |
| 1417 | mergeThunks(OutputSections); | 1439 | mergeThunks(OutputSections); |
| 1418 | ++Pass; | 1440 | ++Pass; |
deps/lld/ELF/Relocations.h+15-6| ... | @@ -21,7 +21,7 @@ class Symbol; | ... | @@ -21,7 +21,7 @@ class Symbol; |
| 21 | class InputSection; | 21 | class InputSection; |
| 22 | class InputSectionBase; | 22 | class InputSectionBase; |
| 23 | class OutputSection; | 23 | class OutputSection; |
| 24 | class OutputSection; | 24 | class SectionBase; |
| 25 | 25 | ||
| 26 | // Represents a relocation type, such as R_X86_64_PC32 or R_ARM_THM_CALL. | 26 | // Represents a relocation type, such as R_X86_64_PC32 or R_ARM_THM_CALL. |
| 27 | typedef uint32_t RelType; | 27 | typedef uint32_t RelType; |
| ... | @@ -32,6 +32,7 @@ typedef uint32_t RelType; | ... | @@ -32,6 +32,7 @@ typedef uint32_t RelType; |
| 32 | enum RelExpr { | 32 | enum RelExpr { |
| 33 | R_INVALID, | 33 | R_INVALID, |
| 34 | R_ABS, | 34 | R_ABS, |
| 35 | R_ADDEND, | ||
| 35 | R_ARM_SBREL, | 36 | R_ARM_SBREL, |
| 36 | R_GOT, | 37 | R_GOT, |
| 37 | R_GOTONLY_PC, | 38 | R_GOTONLY_PC, |
| ... | @@ -58,27 +59,33 @@ enum RelExpr { | ... | @@ -58,27 +59,33 @@ enum RelExpr { |
| 58 | R_PLT, | 59 | R_PLT, |
| 59 | R_PLT_PAGE_PC, | 60 | R_PLT_PAGE_PC, |
| 60 | R_PLT_PC, | 61 | R_PLT_PC, |
| 61 | R_PPC_OPD, | 62 | R_PPC_CALL, |
| 62 | R_PPC_PLT_OPD, | 63 | R_PPC_CALL_PLT, |
| 63 | R_PPC_TOC, | 64 | R_PPC_TOC, |
| 64 | R_RELAX_GOT_PC, | 65 | R_RELAX_GOT_PC, |
| 65 | R_RELAX_GOT_PC_NOPIC, | 66 | R_RELAX_GOT_PC_NOPIC, |
| 66 | R_RELAX_TLS_GD_TO_IE, | 67 | R_RELAX_TLS_GD_TO_IE, |
| 67 | R_RELAX_TLS_GD_TO_IE_ABS, | 68 | R_RELAX_TLS_GD_TO_IE_ABS, |
| 68 | R_RELAX_TLS_GD_TO_IE_END, | 69 | R_RELAX_TLS_GD_TO_IE_END, |
| 70 | R_RELAX_TLS_GD_TO_IE_GOT_OFF, | ||
| 69 | R_RELAX_TLS_GD_TO_IE_PAGE_PC, | 71 | R_RELAX_TLS_GD_TO_IE_PAGE_PC, |
| 70 | R_RELAX_TLS_GD_TO_LE, | 72 | R_RELAX_TLS_GD_TO_LE, |
| 71 | R_RELAX_TLS_GD_TO_LE_NEG, | 73 | R_RELAX_TLS_GD_TO_LE_NEG, |
| 72 | R_RELAX_TLS_IE_TO_LE, | 74 | R_RELAX_TLS_IE_TO_LE, |
| 73 | R_RELAX_TLS_LD_TO_LE, | 75 | R_RELAX_TLS_LD_TO_LE, |
| 76 | R_RELAX_TLS_LD_TO_LE_ABS, | ||
| 74 | R_SIZE, | 77 | R_SIZE, |
| 75 | R_TLS, | 78 | R_TLS, |
| 76 | R_TLSDESC, | 79 | R_TLSDESC, |
| 77 | R_TLSDESC_CALL, | 80 | R_TLSDESC_CALL, |
| 78 | R_TLSDESC_PAGE, | 81 | R_TLSDESC_PAGE, |
| 79 | R_TLSGD, | 82 | R_TLSGD_GOT, |
| 83 | R_TLSGD_GOT_FROM_END, | ||
| 80 | R_TLSGD_PC, | 84 | R_TLSGD_PC, |
| 81 | R_TLSLD, | 85 | R_TLSLD_GOT, |
| 86 | R_TLSLD_GOT_FROM_END, | ||
| 87 | R_TLSLD_GOT_OFF, | ||
| 88 | R_TLSLD_HINT, | ||
| 82 | R_TLSLD_PC, | 89 | R_TLSLD_PC, |
| 83 | }; | 90 | }; |
| 84 | 91 | ||
| ... | @@ -150,7 +157,7 @@ private: | ... | @@ -150,7 +157,7 @@ private: |
| 150 | 157 | ||
| 151 | void forEachInputSectionDescription( | 158 | void forEachInputSectionDescription( |
| 152 | ArrayRef<OutputSection *> OutputSections, | 159 | ArrayRef<OutputSection *> OutputSections, |
| 153 | std::function<void(OutputSection *, InputSectionDescription *)> Fn); | 160 | llvm::function_ref<void(OutputSection *, InputSectionDescription *)> Fn); |
| 154 | 161 | ||
| 155 | std::pair<Thunk *, bool> getThunk(Symbol &Sym, RelType Type, uint64_t Src); | 162 | std::pair<Thunk *, bool> getThunk(Symbol &Sym, RelType Type, uint64_t Src); |
| 156 | 163 | ||
| ... | @@ -160,6 +167,8 @@ private: | ... | @@ -160,6 +167,8 @@ private: |
| 160 | bool normalizeExistingThunk(Relocation &Rel, uint64_t Src); | 167 | bool normalizeExistingThunk(Relocation &Rel, uint64_t Src); |
| 161 | 168 | ||
| 162 | // Record all the available Thunks for a Symbol | 169 | // Record all the available Thunks for a Symbol |
| 170 | llvm::DenseMap<std::pair<SectionBase *, uint64_t>, std::vector<Thunk *>> | ||
| 171 | ThunkedSymbolsBySection; | ||
| 163 | llvm::DenseMap<Symbol *, std::vector<Thunk *>> ThunkedSymbols; | 172 | llvm::DenseMap<Symbol *, std::vector<Thunk *>> ThunkedSymbols; |
| 164 | 173 | ||
| 165 | // Find a Thunk from the Thunks symbol definition, we can use this to find | 174 | // Find a Thunk from the Thunks symbol definition, we can use this to find |
deps/lld/ELF/ScriptLexer.cpp+3-7| ... | @@ -66,8 +66,6 @@ size_t ScriptLexer::getColumnNumber() { | ... | @@ -66,8 +66,6 @@ size_t ScriptLexer::getColumnNumber() { |
| 66 | 66 | ||
| 67 | std::string ScriptLexer::getCurrentLocation() { | 67 | std::string ScriptLexer::getCurrentLocation() { |
| 68 | std::string Filename = getCurrentMB().getBufferIdentifier(); | 68 | std::string Filename = getCurrentMB().getBufferIdentifier(); |
| 69 | if (!Pos) | ||
| 70 | return Filename; | ||
| 71 | return (Filename + ":" + Twine(getLineNumber())).str(); | 69 | return (Filename + ":" + Twine(getLineNumber())).str(); |
| 72 | } | 70 | } |
| 73 | 71 | ||
| ... | @@ -116,8 +114,9 @@ void ScriptLexer::tokenize(MemoryBufferRef MB) { | ... | @@ -116,8 +114,9 @@ void ScriptLexer::tokenize(MemoryBufferRef MB) { |
| 116 | } | 114 | } |
| 117 | 115 | ||
| 118 | // ">foo" is parsed to ">" and "foo", but ">>" is parsed to ">>". | 116 | // ">foo" is parsed to ">" and "foo", but ">>" is parsed to ">>". |
| 117 | // "|", "||", "&" and "&&" are different operators. | ||
| 119 | if (S.startswith("<<") || S.startswith("<=") || S.startswith(">>") || | 118 | if (S.startswith("<<") || S.startswith("<=") || S.startswith(">>") || |
| 120 | S.startswith(">=")) { | 119 | S.startswith(">=") || S.startswith("||") || S.startswith("&&")) { |
| 121 | Vec.push_back(S.substr(0, 2)); | 120 | Vec.push_back(S.substr(0, 2)); |
| 122 | S = S.substr(2); | 121 | S = S.substr(2); |
| 123 | continue; | 122 | continue; |
| ... | @@ -282,10 +281,7 @@ static bool encloses(StringRef S, StringRef T) { | ... | @@ -282,10 +281,7 @@ static bool encloses(StringRef S, StringRef T) { |
| 282 | 281 | ||
| 283 | MemoryBufferRef ScriptLexer::getCurrentMB() { | 282 | MemoryBufferRef ScriptLexer::getCurrentMB() { |
| 284 | // Find input buffer containing the current token. | 283 | // Find input buffer containing the current token. |
| 285 | assert(!MBs.empty()); | 284 | assert(!MBs.empty() && Pos > 0); |
| 286 | if (!Pos) | ||
| 287 | return MBs[0]; | ||
| 288 | |||
| 289 | for (MemoryBufferRef MB : MBs) | 285 | for (MemoryBufferRef MB : MBs) |
| 290 | if (encloses(MB.getBuffer(), Tokens[Pos - 1])) | 286 | if (encloses(MB.getBuffer(), Tokens[Pos - 1])) |
| 291 | return MB; | 287 | return MB; |
deps/lld/ELF/ScriptParser.cpp+209-82| ... | @@ -63,6 +63,7 @@ private: | ... | @@ -63,6 +63,7 @@ private: |
| 63 | void readExtern(); | 63 | void readExtern(); |
| 64 | void readGroup(); | 64 | void readGroup(); |
| 65 | void readInclude(); | 65 | void readInclude(); |
| 66 | void readInput(); | ||
| 66 | void readMemory(); | 67 | void readMemory(); |
| 67 | void readOutput(); | 68 | void readOutput(); |
| 68 | void readOutputArch(); | 69 | void readOutputArch(); |
| ... | @@ -74,12 +75,14 @@ private: | ... | @@ -74,12 +75,14 @@ private: |
| 74 | void readVersion(); | 75 | void readVersion(); |
| 75 | void readVersionScriptCommand(); | 76 | void readVersionScriptCommand(); |
| 76 | 77 | ||
| 77 | SymbolAssignment *readAssignment(StringRef Name); | 78 | SymbolAssignment *readSymbolAssignment(StringRef Name); |
| 78 | ByteCommand *readByteCommand(StringRef Tok); | 79 | ByteCommand *readByteCommand(StringRef Tok); |
| 79 | uint32_t readFill(); | 80 | uint32_t readFill(); |
| 80 | uint32_t parseFill(StringRef Tok); | 81 | uint32_t parseFill(StringRef Tok); |
| 81 | void readSectionAddressType(OutputSection *Cmd); | 82 | void readSectionAddressType(OutputSection *Cmd); |
| 83 | OutputSection *readOverlaySectionDescription(); | ||
| 82 | OutputSection *readOutputSectionDescription(StringRef OutSec); | 84 | OutputSection *readOutputSectionDescription(StringRef OutSec); |
| 85 | std::vector<BaseCommand *> readOverlay(); | ||
| 83 | std::vector<StringRef> readOutputSectionPhdrs(); | 86 | std::vector<StringRef> readOutputSectionPhdrs(); |
| 84 | InputSectionDescription *readInputSectionDescription(StringRef Tok); | 87 | InputSectionDescription *readInputSectionDescription(StringRef Tok); |
| 85 | StringMatcher readFilePatterns(); | 88 | StringMatcher readFilePatterns(); |
| ... | @@ -88,16 +91,16 @@ private: | ... | @@ -88,16 +91,16 @@ private: |
| 88 | unsigned readPhdrType(); | 91 | unsigned readPhdrType(); |
| 89 | SortSectionPolicy readSortKind(); | 92 | SortSectionPolicy readSortKind(); |
| 90 | SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); | 93 | SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); |
| 91 | SymbolAssignment *readProvideOrAssignment(StringRef Tok); | 94 | SymbolAssignment *readAssignment(StringRef Tok); |
| 92 | void readSort(); | 95 | void readSort(); |
| 93 | AssertCommand *readAssert(); | 96 | Expr readAssert(); |
| 94 | Expr readAssertExpr(); | ||
| 95 | Expr readConstant(); | 97 | Expr readConstant(); |
| 96 | Expr getPageSize(); | 98 | Expr getPageSize(); |
| 97 | 99 | ||
| 98 | uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); | 100 | uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); |
| 99 | std::pair<uint32_t, uint32_t> readMemoryAttributes(); | 101 | std::pair<uint32_t, uint32_t> readMemoryAttributes(); |
| 100 | 102 | ||
| 103 | Expr combine(StringRef Op, Expr L, Expr R); | ||
| 101 | Expr readExpr(); | 104 | Expr readExpr(); |
| 102 | Expr readExpr1(Expr Lhs, int MinPrec); | 105 | Expr readExpr1(Expr Lhs, int MinPrec); |
| 103 | StringRef readParenLiteral(); | 106 | StringRef readParenLiteral(); |
| ... | @@ -157,17 +160,6 @@ static ExprValue sub(ExprValue A, ExprValue B) { | ... | @@ -157,17 +160,6 @@ static ExprValue sub(ExprValue A, ExprValue B) { |
| 157 | return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc}; | 160 | return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc}; |
| 158 | } | 161 | } |
| 159 | 162 | ||
| 160 | static ExprValue mul(ExprValue A, ExprValue B) { | ||
| 161 | return A.getValue() * B.getValue(); | ||
| 162 | } | ||
| 163 | |||
| 164 | static ExprValue div(ExprValue A, ExprValue B) { | ||
| 165 | if (uint64_t BV = B.getValue()) | ||
| 166 | return A.getValue() / BV; | ||
| 167 | error("division by zero"); | ||
| 168 | return 0; | ||
| 169 | } | ||
| 170 | |||
| 171 | static ExprValue bitAnd(ExprValue A, ExprValue B) { | 163 | static ExprValue bitAnd(ExprValue A, ExprValue B) { |
| 172 | moveAbsRight(A, B); | 164 | moveAbsRight(A, B); |
| 173 | return {A.Sec, A.ForceAbsolute, | 165 | return {A.Sec, A.ForceAbsolute, |
| ... | @@ -237,16 +229,16 @@ void ScriptParser::readLinkerScript() { | ... | @@ -237,16 +229,16 @@ void ScriptParser::readLinkerScript() { |
| 237 | if (Tok == ";") | 229 | if (Tok == ";") |
| 238 | continue; | 230 | continue; |
| 239 | 231 | ||
| 240 | if (Tok == "ASSERT") { | 232 | if (Tok == "ENTRY") { |
| 241 | Script->SectionCommands.push_back(readAssert()); | ||
| 242 | } else if (Tok == "ENTRY") { | ||
| 243 | readEntry(); | 233 | readEntry(); |
| 244 | } else if (Tok == "EXTERN") { | 234 | } else if (Tok == "EXTERN") { |
| 245 | readExtern(); | 235 | readExtern(); |
| 246 | } else if (Tok == "GROUP" || Tok == "INPUT") { | 236 | } else if (Tok == "GROUP") { |
| 247 | readGroup(); | 237 | readGroup(); |
| 248 | } else if (Tok == "INCLUDE") { | 238 | } else if (Tok == "INCLUDE") { |
| 249 | readInclude(); | 239 | readInclude(); |
| 240 | } else if (Tok == "INPUT") { | ||
| 241 | readInput(); | ||
| 250 | } else if (Tok == "MEMORY") { | 242 | } else if (Tok == "MEMORY") { |
| 251 | readMemory(); | 243 | readMemory(); |
| 252 | } else if (Tok == "OUTPUT") { | 244 | } else if (Tok == "OUTPUT") { |
| ... | @@ -265,7 +257,7 @@ void ScriptParser::readLinkerScript() { | ... | @@ -265,7 +257,7 @@ void ScriptParser::readLinkerScript() { |
| 265 | readSections(); | 257 | readSections(); |
| 266 | } else if (Tok == "VERSION") { | 258 | } else if (Tok == "VERSION") { |
| 267 | readVersion(); | 259 | readVersion(); |
| 268 | } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { | 260 | } else if (SymbolAssignment *Cmd = readAssignment(Tok)) { |
| 269 | Script->SectionCommands.push_back(Cmd); | 261 | Script->SectionCommands.push_back(Cmd); |
| 270 | } else { | 262 | } else { |
| 271 | setError("unknown directive: " + Tok); | 263 | setError("unknown directive: " + Tok); |
| ... | @@ -336,13 +328,12 @@ void ScriptParser::readExtern() { | ... | @@ -336,13 +328,12 @@ void ScriptParser::readExtern() { |
| 336 | } | 328 | } |
| 337 | 329 | ||
| 338 | void ScriptParser::readGroup() { | 330 | void ScriptParser::readGroup() { |
| 339 | expect("("); | 331 | bool Orig = InputFile::IsInGroup; |
| 340 | while (!errorCount() && !consume(")")) { | 332 | InputFile::IsInGroup = true; |
| 341 | if (consume("AS_NEEDED")) | 333 | readInput(); |
| 342 | readAsNeeded(); | 334 | InputFile::IsInGroup = Orig; |
| 343 | else | 335 | if (!Orig) |
| 344 | addFile(unquote(next())); | 336 | ++InputFile::NextGroupId; |
| 345 | } | ||
| 346 | } | 337 | } |
| 347 | 338 | ||
| 348 | void ScriptParser::readInclude() { | 339 | void ScriptParser::readInclude() { |
| ... | @@ -353,7 +344,7 @@ void ScriptParser::readInclude() { | ... | @@ -353,7 +344,7 @@ void ScriptParser::readInclude() { |
| 353 | return; | 344 | return; |
| 354 | } | 345 | } |
| 355 | 346 | ||
| 356 | if (Optional<std::string> Path = searchLinkerScript(Tok)) { | 347 | if (Optional<std::string> Path = searchScript(Tok)) { |
| 357 | if (Optional<MemoryBufferRef> MB = readFile(*Path)) | 348 | if (Optional<MemoryBufferRef> MB = readFile(*Path)) |
| 358 | tokenize(*MB); | 349 | tokenize(*MB); |
| 359 | return; | 350 | return; |
| ... | @@ -361,6 +352,16 @@ void ScriptParser::readInclude() { | ... | @@ -361,6 +352,16 @@ void ScriptParser::readInclude() { |
| 361 | setError("cannot find linker script " + Tok); | 352 | setError("cannot find linker script " + Tok); |
| 362 | } | 353 | } |
| 363 | 354 | ||
| 355 | void ScriptParser::readInput() { | ||
| 356 | expect("("); | ||
| 357 | while (!errorCount() && !consume(")")) { | ||
| 358 | if (consume("AS_NEEDED")) | ||
| 359 | readAsNeeded(); | ||
| 360 | else | ||
| 361 | addFile(unquote(next())); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | |||
| 364 | void ScriptParser::readOutput() { | 365 | void ScriptParser::readOutput() { |
| 365 | // -o <file> takes predecence over OUTPUT(<file>). | 366 | // -o <file> takes predecence over OUTPUT(<file>). |
| 366 | expect("("); | 367 | expect("("); |
| ... | @@ -437,6 +438,49 @@ void ScriptParser::readSearchDir() { | ... | @@ -437,6 +438,49 @@ void ScriptParser::readSearchDir() { |
| 437 | expect(")"); | 438 | expect(")"); |
| 438 | } | 439 | } |
| 439 | 440 | ||
| 441 | // This reads an overlay description. Overlays are used to describe output | ||
| 442 | // sections that use the same virtual memory range and normally would trigger | ||
| 443 | // linker's sections sanity check failures. | ||
| 444 | // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description | ||
| 445 | std::vector<BaseCommand *> ScriptParser::readOverlay() { | ||
| 446 | // VA and LMA expressions are optional, though for simplicity of | ||
| 447 | // implementation we assume they are not. That is what OVERLAY was designed | ||
| 448 | // for first of all: to allow sections with overlapping VAs at different LMAs. | ||
| 449 | Expr AddrExpr = readExpr(); | ||
| 450 | expect(":"); | ||
| 451 | expect("AT"); | ||
| 452 | Expr LMAExpr = readParenExpr(); | ||
| 453 | expect("{"); | ||
| 454 | |||
| 455 | std::vector<BaseCommand *> V; | ||
| 456 | OutputSection *Prev = nullptr; | ||
| 457 | while (!errorCount() && !consume("}")) { | ||
| 458 | // VA is the same for all sections. The LMAs are consecutive in memory | ||
| 459 | // starting from the base load address specified. | ||
| 460 | OutputSection *OS = readOverlaySectionDescription(); | ||
| 461 | OS->AddrExpr = AddrExpr; | ||
| 462 | if (Prev) | ||
| 463 | OS->LMAExpr = [=] { return Prev->getLMA() + Prev->Size; }; | ||
| 464 | else | ||
| 465 | OS->LMAExpr = LMAExpr; | ||
| 466 | V.push_back(OS); | ||
| 467 | Prev = OS; | ||
| 468 | } | ||
| 469 | |||
| 470 | // According to the specification, at the end of the overlay, the location | ||
| 471 | // counter should be equal to the overlay base address plus size of the | ||
| 472 | // largest section seen in the overlay. | ||
| 473 | // Here we want to create the Dot assignment command to achieve that. | ||
| 474 | Expr MoveDot = [=] { | ||
| 475 | uint64_t Max = 0; | ||
| 476 | for (BaseCommand *Cmd : V) | ||
| 477 | Max = std::max(Max, cast<OutputSection>(Cmd)->Size); | ||
| 478 | return AddrExpr().getValue() + Max; | ||
| 479 | }; | ||
| 480 | V.push_back(make<SymbolAssignment>(".", MoveDot, getCurrentLocation())); | ||
| 481 | return V; | ||
| 482 | } | ||
| 483 | |||
| 440 | void ScriptParser::readSections() { | 484 | void ScriptParser::readSections() { |
| 441 | Script->HasSectionsCommand = true; | 485 | Script->HasSectionsCommand = true; |
| 442 | 486 | ||
| ... | @@ -446,26 +490,48 @@ void ScriptParser::readSections() { | ... | @@ -446,26 +490,48 @@ void ScriptParser::readSections() { |
| 446 | Config->SingleRoRx = true; | 490 | Config->SingleRoRx = true; |
| 447 | 491 | ||
| 448 | expect("{"); | 492 | expect("{"); |
| 493 | std::vector<BaseCommand *> V; | ||
| 449 | while (!errorCount() && !consume("}")) { | 494 | while (!errorCount() && !consume("}")) { |
| 450 | StringRef Tok = next(); | 495 | StringRef Tok = next(); |
| 451 | BaseCommand *Cmd = readProvideOrAssignment(Tok); | 496 | if (Tok == "OVERLAY") { |
| 452 | if (!Cmd) { | 497 | for (BaseCommand *Cmd : readOverlay()) |
| 453 | if (Tok == "ASSERT") | 498 | V.push_back(Cmd); |
| 454 | Cmd = readAssert(); | 499 | continue; |
| 455 | else | ||
| 456 | Cmd = readOutputSectionDescription(Tok); | ||
| 457 | } | 500 | } |
| 458 | Script->SectionCommands.push_back(Cmd); | 501 | |
| 502 | if (BaseCommand *Cmd = readAssignment(Tok)) | ||
| 503 | V.push_back(Cmd); | ||
| 504 | else | ||
| 505 | V.push_back(readOutputSectionDescription(Tok)); | ||
| 506 | } | ||
| 507 | |||
| 508 | if (!atEOF() && consume("INSERT")) { | ||
| 509 | std::vector<BaseCommand *> *Dest = nullptr; | ||
| 510 | if (consume("AFTER")) | ||
| 511 | Dest = &Script->InsertAfterCommands[next()]; | ||
| 512 | else if (consume("BEFORE")) | ||
| 513 | Dest = &Script->InsertBeforeCommands[next()]; | ||
| 514 | else | ||
| 515 | setError("expected AFTER/BEFORE, but got '" + next() + "'"); | ||
| 516 | if (Dest) | ||
| 517 | Dest->insert(Dest->end(), V.begin(), V.end()); | ||
| 518 | return; | ||
| 459 | } | 519 | } |
| 520 | |||
| 521 | Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(), | ||
| 522 | V.end()); | ||
| 460 | } | 523 | } |
| 461 | 524 | ||
| 462 | static int precedence(StringRef Op) { | 525 | static int precedence(StringRef Op) { |
| 463 | return StringSwitch<int>(Op) | 526 | return StringSwitch<int>(Op) |
| 464 | .Cases("*", "/", 5) | 527 | .Cases("*", "/", "%", 8) |
| 465 | .Cases("+", "-", 4) | 528 | .Cases("+", "-", 7) |
| 466 | .Cases("<<", ">>", 3) | 529 | .Cases("<<", ">>", 6) |
| 467 | .Cases("<", "<=", ">", ">=", "==", "!=", 2) | 530 | .Cases("<", "<=", ">", ">=", "==", "!=", 5) |
| 468 | .Cases("&", "|", 1) | 531 | .Case("&", 4) |
| 532 | .Case("|", 3) | ||
| 533 | .Case("&&", 2) | ||
| 534 | .Case("||", 1) | ||
| 469 | .Default(-1); | 535 | .Default(-1); |
| 470 | } | 536 | } |
| 471 | 537 | ||
| ... | @@ -588,11 +654,7 @@ void ScriptParser::readSort() { | ... | @@ -588,11 +654,7 @@ void ScriptParser::readSort() { |
| 588 | expect(")"); | 654 | expect(")"); |
| 589 | } | 655 | } |
| 590 | 656 | ||
| 591 | AssertCommand *ScriptParser::readAssert() { | 657 | Expr ScriptParser::readAssert() { |
| 592 | return make<AssertCommand>(readAssertExpr()); | ||
| 593 | } | ||
| 594 | |||
| 595 | Expr ScriptParser::readAssertExpr() { | ||
| 596 | expect("("); | 658 | expect("("); |
| 597 | Expr E = readExpr(); | 659 | Expr E = readExpr(); |
| 598 | expect(","); | 660 | expect(","); |
| ... | @@ -617,12 +679,14 @@ uint32_t ScriptParser::readFill() { | ... | @@ -617,12 +679,14 @@ uint32_t ScriptParser::readFill() { |
| 617 | return V; | 679 | return V; |
| 618 | } | 680 | } |
| 619 | 681 | ||
| 620 | // Reads an expression and/or the special directive "(NOLOAD)" for an | 682 | // Reads an expression and/or the special directive for an output |
| 621 | // output section definition. | 683 | // section definition. Directive is one of following: "(NOLOAD)", |
| 684 | // "(COPY)", "(INFO)" or "(OVERLAY)". | ||
| 622 | // | 685 | // |
| 623 | // An output section name can be followed by an address expression | 686 | // An output section name can be followed by an address expression |
| 624 | // and/or by "(NOLOAD)". This grammar is not LL(1) because "(" can be | 687 | // and/or directive. This grammar is not LL(1) because "(" can be |
| 625 | // interpreted as either the beginning of some expression or "(NOLOAD)". | 688 | // interpreted as either the beginning of some expression or beginning |
| 689 | // of directive. | ||
| 626 | // | 690 | // |
| 627 | // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html | 691 | // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html |
| 628 | // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html | 692 | // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html |
| ... | @@ -633,6 +697,11 @@ void ScriptParser::readSectionAddressType(OutputSection *Cmd) { | ... | @@ -633,6 +697,11 @@ void ScriptParser::readSectionAddressType(OutputSection *Cmd) { |
| 633 | Cmd->Noload = true; | 697 | Cmd->Noload = true; |
| 634 | return; | 698 | return; |
| 635 | } | 699 | } |
| 700 | if (consume("COPY") || consume("INFO") || consume("OVERLAY")) { | ||
| 701 | expect(")"); | ||
| 702 | Cmd->NonAlloc = true; | ||
| 703 | return; | ||
| 704 | } | ||
| 636 | Cmd->AddrExpr = readExpr(); | 705 | Cmd->AddrExpr = readExpr(); |
| 637 | expect(")"); | 706 | expect(")"); |
| 638 | } else { | 707 | } else { |
| ... | @@ -657,10 +726,23 @@ static Expr checkAlignment(Expr E, std::string &Loc) { | ... | @@ -657,10 +726,23 @@ static Expr checkAlignment(Expr E, std::string &Loc) { |
| 657 | }; | 726 | }; |
| 658 | } | 727 | } |
| 659 | 728 | ||
| 729 | OutputSection *ScriptParser::readOverlaySectionDescription() { | ||
| 730 | OutputSection *Cmd = | ||
| 731 | Script->createOutputSection(next(), getCurrentLocation()); | ||
| 732 | Cmd->InOverlay = true; | ||
| 733 | expect("{"); | ||
| 734 | while (!errorCount() && !consume("}")) | ||
| 735 | Cmd->SectionCommands.push_back(readInputSectionRules(next())); | ||
| 736 | Cmd->Phdrs = readOutputSectionPhdrs(); | ||
| 737 | return Cmd; | ||
| 738 | } | ||
| 739 | |||
| 660 | OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { | 740 | OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { |
| 661 | OutputSection *Cmd = | 741 | OutputSection *Cmd = |
| 662 | Script->createOutputSection(OutSec, getCurrentLocation()); | 742 | Script->createOutputSection(OutSec, getCurrentLocation()); |
| 663 | 743 | ||
| 744 | size_t SymbolsReferenced = Script->ReferencedSymbols.size(); | ||
| 745 | |||
| 664 | if (peek() != ":") | 746 | if (peek() != ":") |
| 665 | readSectionAddressType(Cmd); | 747 | readSectionAddressType(Cmd); |
| 666 | expect(":"); | 748 | expect(":"); |
| ... | @@ -684,13 +766,10 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { | ... | @@ -684,13 +766,10 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { |
| 684 | StringRef Tok = next(); | 766 | StringRef Tok = next(); |
| 685 | if (Tok == ";") { | 767 | if (Tok == ";") { |
| 686 | // Empty commands are allowed. Do nothing here. | 768 | // Empty commands are allowed. Do nothing here. |
| 687 | } else if (SymbolAssignment *Assign = readProvideOrAssignment(Tok)) { | 769 | } else if (SymbolAssignment *Assign = readAssignment(Tok)) { |
| 688 | Cmd->SectionCommands.push_back(Assign); | 770 | Cmd->SectionCommands.push_back(Assign); |
| 689 | } else if (ByteCommand *Data = readByteCommand(Tok)) { | 771 | } else if (ByteCommand *Data = readByteCommand(Tok)) { |
| 690 | Cmd->SectionCommands.push_back(Data); | 772 | Cmd->SectionCommands.push_back(Data); |
| 691 | } else if (Tok == "ASSERT") { | ||
| 692 | Cmd->SectionCommands.push_back(readAssert()); | ||
| 693 | expect(";"); | ||
| 694 | } else if (Tok == "CONSTRUCTORS") { | 773 | } else if (Tok == "CONSTRUCTORS") { |
| 695 | // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors | 774 | // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors |
| 696 | // by name. This is for very old file formats such as ECOFF/XCOFF. | 775 | // by name. This is for very old file formats such as ECOFF/XCOFF. |
| ... | @@ -727,6 +806,8 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { | ... | @@ -727,6 +806,8 @@ OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { |
| 727 | // Consume optional comma following output section command. | 806 | // Consume optional comma following output section command. |
| 728 | consume(","); | 807 | consume(","); |
| 729 | 808 | ||
| 809 | if (Script->ReferencedSymbols.size() > SymbolsReferenced) | ||
| 810 | Cmd->ExpressionsUseSymbols = true; | ||
| 730 | return Cmd; | 811 | return Cmd; |
| 731 | } | 812 | } |
| 732 | 813 | ||
| ... | @@ -749,30 +830,39 @@ uint32_t ScriptParser::parseFill(StringRef Tok) { | ... | @@ -749,30 +830,39 @@ uint32_t ScriptParser::parseFill(StringRef Tok) { |
| 749 | 830 | ||
| 750 | SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { | 831 | SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { |
| 751 | expect("("); | 832 | expect("("); |
| 752 | SymbolAssignment *Cmd = readAssignment(next()); | 833 | SymbolAssignment *Cmd = readSymbolAssignment(next()); |
| 753 | Cmd->Provide = Provide; | 834 | Cmd->Provide = Provide; |
| 754 | Cmd->Hidden = Hidden; | 835 | Cmd->Hidden = Hidden; |
| 755 | expect(")"); | 836 | expect(")"); |
| 756 | expect(";"); | ||
| 757 | return Cmd; | 837 | return Cmd; |
| 758 | } | 838 | } |
| 759 | 839 | ||
| 760 | SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) { | 840 | SymbolAssignment *ScriptParser::readAssignment(StringRef Tok) { |
| 841 | // Assert expression returns Dot, so this is equal to ".=." | ||
| 842 | if (Tok == "ASSERT") | ||
| 843 | return make<SymbolAssignment>(".", readAssert(), getCurrentLocation()); | ||
| 844 | |||
| 845 | size_t OldPos = Pos; | ||
| 761 | SymbolAssignment *Cmd = nullptr; | 846 | SymbolAssignment *Cmd = nullptr; |
| 762 | if (peek() == "=" || peek() == "+=") { | 847 | if (peek() == "=" || peek() == "+=") |
| 763 | Cmd = readAssignment(Tok); | 848 | Cmd = readSymbolAssignment(Tok); |
| 764 | expect(";"); | 849 | else if (Tok == "PROVIDE") |
| 765 | } else if (Tok == "PROVIDE") { | ||
| 766 | Cmd = readProvideHidden(true, false); | 850 | Cmd = readProvideHidden(true, false); |
| 767 | } else if (Tok == "HIDDEN") { | 851 | else if (Tok == "HIDDEN") |
| 768 | Cmd = readProvideHidden(false, true); | 852 | Cmd = readProvideHidden(false, true); |
| 769 | } else if (Tok == "PROVIDE_HIDDEN") { | 853 | else if (Tok == "PROVIDE_HIDDEN") |
| 770 | Cmd = readProvideHidden(true, true); | 854 | Cmd = readProvideHidden(true, true); |
| 855 | |||
| 856 | if (Cmd) { | ||
| 857 | Cmd->CommandString = | ||
| 858 | Tok.str() + " " + | ||
| 859 | llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " "); | ||
| 860 | expect(";"); | ||
| 771 | } | 861 | } |
| 772 | return Cmd; | 862 | return Cmd; |
| 773 | } | 863 | } |
| 774 | 864 | ||
| 775 | SymbolAssignment *ScriptParser::readAssignment(StringRef Name) { | 865 | SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) { |
| 776 | StringRef Op = next(); | 866 | StringRef Op = next(); |
| 777 | assert(Op == "=" || Op == "+="); | 867 | assert(Op == "=" || Op == "+="); |
| 778 | Expr E = readExpr(); | 868 | Expr E = readExpr(); |
| ... | @@ -795,15 +885,31 @@ Expr ScriptParser::readExpr() { | ... | @@ -795,15 +885,31 @@ Expr ScriptParser::readExpr() { |
| 795 | return E; | 885 | return E; |
| 796 | } | 886 | } |
| 797 | 887 | ||
| 798 | static Expr combine(StringRef Op, Expr L, Expr R) { | 888 | Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) { |
| 799 | if (Op == "+") | 889 | if (Op == "+") |
| 800 | return [=] { return add(L(), R()); }; | 890 | return [=] { return add(L(), R()); }; |
| 801 | if (Op == "-") | 891 | if (Op == "-") |
| 802 | return [=] { return sub(L(), R()); }; | 892 | return [=] { return sub(L(), R()); }; |
| 803 | if (Op == "*") | 893 | if (Op == "*") |
| 804 | return [=] { return mul(L(), R()); }; | 894 | return [=] { return L().getValue() * R().getValue(); }; |
| 805 | if (Op == "/") | 895 | if (Op == "/") { |
| 806 | return [=] { return div(L(), R()); }; | 896 | std::string Loc = getCurrentLocation(); |
| 897 | return [=]() -> uint64_t { | ||
| 898 | if (uint64_t RV = R().getValue()) | ||
| 899 | return L().getValue() / RV; | ||
| 900 | error(Loc + ": division by zero"); | ||
| 901 | return 0; | ||
| 902 | }; | ||
| 903 | } | ||
| 904 | if (Op == "%") { | ||
| 905 | std::string Loc = getCurrentLocation(); | ||
| 906 | return [=]() -> uint64_t { | ||
| 907 | if (uint64_t RV = R().getValue()) | ||
| 908 | return L().getValue() % RV; | ||
| 909 | error(Loc + ": modulo by zero"); | ||
| 910 | return 0; | ||
| 911 | }; | ||
| 912 | } | ||
| 807 | if (Op == "<<") | 913 | if (Op == "<<") |
| 808 | return [=] { return L().getValue() << R().getValue(); }; | 914 | return [=] { return L().getValue() << R().getValue(); }; |
| 809 | if (Op == ">>") | 915 | if (Op == ">>") |
| ... | @@ -820,6 +926,10 @@ static Expr combine(StringRef Op, Expr L, Expr R) { | ... | @@ -820,6 +926,10 @@ static Expr combine(StringRef Op, Expr L, Expr R) { |
| 820 | return [=] { return L().getValue() == R().getValue(); }; | 926 | return [=] { return L().getValue() == R().getValue(); }; |
| 821 | if (Op == "!=") | 927 | if (Op == "!=") |
| 822 | return [=] { return L().getValue() != R().getValue(); }; | 928 | return [=] { return L().getValue() != R().getValue(); }; |
| 929 | if (Op == "||") | ||
| 930 | return [=] { return L().getValue() || R().getValue(); }; | ||
| 931 | if (Op == "&&") | ||
| 932 | return [=] { return L().getValue() && R().getValue(); }; | ||
| 823 | if (Op == "&") | 933 | if (Op == "&") |
| 824 | return [=] { return bitAnd(L(), R()); }; | 934 | return [=] { return bitAnd(L(), R()); }; |
| 825 | if (Op == "|") | 935 | if (Op == "|") |
| ... | @@ -873,20 +983,13 @@ Expr ScriptParser::readConstant() { | ... | @@ -873,20 +983,13 @@ Expr ScriptParser::readConstant() { |
| 873 | if (S == "MAXPAGESIZE") | 983 | if (S == "MAXPAGESIZE") |
| 874 | return [] { return Config->MaxPageSize; }; | 984 | return [] { return Config->MaxPageSize; }; |
| 875 | setError("unknown constant: " + S); | 985 | setError("unknown constant: " + S); |
| 876 | return {}; | 986 | return [] { return 0; }; |
| 877 | } | 987 | } |
| 878 | 988 | ||
| 879 | // Parses Tok as an integer. It recognizes hexadecimal (prefixed with | 989 | // Parses Tok as an integer. It recognizes hexadecimal (prefixed with |
| 880 | // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may | 990 | // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may |
| 881 | // have "K" (Ki) or "M" (Mi) suffixes. | 991 | // have "K" (Ki) or "M" (Mi) suffixes. |
| 882 | static Optional<uint64_t> parseInt(StringRef Tok) { | 992 | static Optional<uint64_t> parseInt(StringRef Tok) { |
| 883 | // Negative number | ||
| 884 | if (Tok.startswith("-")) { | ||
| 885 | if (Optional<uint64_t> Val = parseInt(Tok.substr(1))) | ||
| 886 | return -*Val; | ||
| 887 | return None; | ||
| 888 | } | ||
| 889 | |||
| 890 | // Hexadecimal | 993 | // Hexadecimal |
| 891 | uint64_t Val; | 994 | uint64_t Val; |
| 892 | if (Tok.startswith_lower("0x")) { | 995 | if (Tok.startswith_lower("0x")) { |
| ... | @@ -925,7 +1028,13 @@ ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { | ... | @@ -925,7 +1028,13 @@ ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { |
| 925 | .Default(-1); | 1028 | .Default(-1); |
| 926 | if (Size == -1) | 1029 | if (Size == -1) |
| 927 | return nullptr; | 1030 | return nullptr; |
| 928 | return make<ByteCommand>(readParenExpr(), Size); | 1031 | |
| 1032 | size_t OldPos = Pos; | ||
| 1033 | Expr E = readParenExpr(); | ||
| 1034 | std::string CommandString = | ||
| 1035 | Tok.str() + " " + | ||
| 1036 | llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " "); | ||
| 1037 | return make<ByteCommand>(E, Size, CommandString); | ||
| 929 | } | 1038 | } |
| 930 | 1039 | ||
| 931 | StringRef ScriptParser::readParenLiteral() { | 1040 | StringRef ScriptParser::readParenLiteral() { |
| ... | @@ -1006,7 +1115,7 @@ Expr ScriptParser::readPrimary() { | ... | @@ -1006,7 +1115,7 @@ Expr ScriptParser::readPrimary() { |
| 1006 | }; | 1115 | }; |
| 1007 | } | 1116 | } |
| 1008 | if (Tok == "ASSERT") | 1117 | if (Tok == "ASSERT") |
| 1009 | return readAssertExpr(); | 1118 | return readAssert(); |
| 1010 | if (Tok == "CONSTANT") | 1119 | if (Tok == "CONSTANT") |
| 1011 | return readConstant(); | 1120 | return readConstant(); |
| 1012 | if (Tok == "DATA_SEGMENT_ALIGN") { | 1121 | if (Tok == "DATA_SEGMENT_ALIGN") { |
| ... | @@ -1043,8 +1152,10 @@ Expr ScriptParser::readPrimary() { | ... | @@ -1043,8 +1152,10 @@ Expr ScriptParser::readPrimary() { |
| 1043 | } | 1152 | } |
| 1044 | if (Tok == "LENGTH") { | 1153 | if (Tok == "LENGTH") { |
| 1045 | StringRef Name = readParenLiteral(); | 1154 | StringRef Name = readParenLiteral(); |
| 1046 | if (Script->MemoryRegions.count(Name) == 0) | 1155 | if (Script->MemoryRegions.count(Name) == 0) { |
| 1047 | setError("memory region not defined: " + Name); | 1156 | setError("memory region not defined: " + Name); |
| 1157 | return [] { return 0; }; | ||
| 1158 | } | ||
| 1048 | return [=] { return Script->MemoryRegions[Name]->Length; }; | 1159 | return [=] { return Script->MemoryRegions[Name]->Length; }; |
| 1049 | } | 1160 | } |
| 1050 | if (Tok == "LOADADDR") { | 1161 | if (Tok == "LOADADDR") { |
| ... | @@ -1055,10 +1166,22 @@ Expr ScriptParser::readPrimary() { | ... | @@ -1055,10 +1166,22 @@ Expr ScriptParser::readPrimary() { |
| 1055 | return Cmd->getLMA(); | 1166 | return Cmd->getLMA(); |
| 1056 | }; | 1167 | }; |
| 1057 | } | 1168 | } |
| 1169 | if (Tok == "MAX" || Tok == "MIN") { | ||
| 1170 | expect("("); | ||
| 1171 | Expr A = readExpr(); | ||
| 1172 | expect(","); | ||
| 1173 | Expr B = readExpr(); | ||
| 1174 | expect(")"); | ||
| 1175 | if (Tok == "MIN") | ||
| 1176 | return [=] { return std::min(A().getValue(), B().getValue()); }; | ||
| 1177 | return [=] { return std::max(A().getValue(), B().getValue()); }; | ||
| 1178 | } | ||
| 1058 | if (Tok == "ORIGIN") { | 1179 | if (Tok == "ORIGIN") { |
| 1059 | StringRef Name = readParenLiteral(); | 1180 | StringRef Name = readParenLiteral(); |
| 1060 | if (Script->MemoryRegions.count(Name) == 0) | 1181 | if (Script->MemoryRegions.count(Name) == 0) { |
| 1061 | setError("memory region not defined: " + Name); | 1182 | setError("memory region not defined: " + Name); |
| 1183 | return [] { return 0; }; | ||
| 1184 | } | ||
| 1062 | return [=] { return Script->MemoryRegions[Name]->Origin; }; | 1185 | return [=] { return Script->MemoryRegions[Name]->Origin; }; |
| 1063 | } | 1186 | } |
| 1064 | if (Tok == "SEGMENT_START") { | 1187 | if (Tok == "SEGMENT_START") { |
| ... | @@ -1240,6 +1363,9 @@ ScriptParser::readSymbols() { | ... | @@ -1240,6 +1363,9 @@ ScriptParser::readSymbols() { |
| 1240 | 1363 | ||
| 1241 | // Reads an "extern C++" directive, e.g., | 1364 | // Reads an "extern C++" directive, e.g., |
| 1242 | // "extern "C++" { ns::*; "f(int, double)"; };" | 1365 | // "extern "C++" { ns::*; "f(int, double)"; };" |
| 1366 | // | ||
| 1367 | // The last semicolon is optional. E.g. this is OK: | ||
| 1368 | // "extern "C++" { ns::*; "f(int, double)" };" | ||
| 1243 | std::vector<SymbolVersion> ScriptParser::readVersionExtern() { | 1369 | std::vector<SymbolVersion> ScriptParser::readVersionExtern() { |
| 1244 | StringRef Tok = next(); | 1370 | StringRef Tok = next(); |
| 1245 | bool IsCXX = Tok == "\"C++\""; | 1371 | bool IsCXX = Tok == "\"C++\""; |
| ... | @@ -1252,6 +1378,8 @@ std::vector<SymbolVersion> ScriptParser::readVersionExtern() { | ... | @@ -1252,6 +1378,8 @@ std::vector<SymbolVersion> ScriptParser::readVersionExtern() { |
| 1252 | StringRef Tok = next(); | 1378 | StringRef Tok = next(); |
| 1253 | bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); | 1379 | bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); |
| 1254 | Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); | 1380 | Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); |
| 1381 | if (consume("}")) | ||
| 1382 | return Ret; | ||
| 1255 | expect(";"); | 1383 | expect(";"); |
| 1256 | } | 1384 | } |
| 1257 | 1385 | ||
| ... | @@ -1291,11 +1419,10 @@ void ScriptParser::readMemory() { | ... | @@ -1291,11 +1419,10 @@ void ScriptParser::readMemory() { |
| 1291 | uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); | 1419 | uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); |
| 1292 | 1420 | ||
| 1293 | // Add the memory region to the region map. | 1421 | // Add the memory region to the region map. |
| 1294 | if (Script->MemoryRegions.count(Name)) | ||
| 1295 | setError("region '" + Name + "' already defined"); | ||
| 1296 | MemoryRegion *MR = | 1422 | MemoryRegion *MR = |
| 1297 | make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags); | 1423 | make<MemoryRegion>(Name, Origin, Length, Flags, NegFlags); |
| 1298 | Script->MemoryRegions[Name] = MR; | 1424 | if (!Script->MemoryRegions.insert({Name, MR}).second) |
| 1425 | setError("region '" + Name + "' already defined"); | ||
| 1299 | } | 1426 | } |
| 1300 | } | 1427 | } |
| 1301 | 1428 |
deps/lld/ELF/Strings.cpp deleted-62| ... | @@ -1,62 +0,0 @@ | ||
| 1 | //===- Strings.cpp -------------------------------------------------------===// | ||
| 2 | // | ||
| 3 | // The LLVM Linker | ||
| 4 | // | ||
| 5 | // This file is distributed under the University of Illinois Open Source | ||
| 6 | // License. See LICENSE.TXT for details. | ||
| 7 | // | ||
| 8 | //===----------------------------------------------------------------------===// | ||
| 9 | |||
| 10 | #include "Strings.h" | ||
| 11 | #include "Config.h" | ||
| 12 | #include "lld/Common/ErrorHandler.h" | ||
| 13 | #include "llvm/ADT/ArrayRef.h" | ||
| 14 | #include "llvm/ADT/StringRef.h" | ||
| 15 | #include "llvm/ADT/Twine.h" | ||
| 16 | #include "llvm/Demangle/Demangle.h" | ||
| 17 | #include <algorithm> | ||
| 18 | #include <cstring> | ||
| 19 | |||
| 20 | using namespace llvm; | ||
| 21 | using namespace lld; | ||
| 22 | using namespace lld::elf; | ||
| 23 | |||
| 24 | StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) { | ||
| 25 | for (StringRef S : Pat) { | ||
| 26 | Expected<GlobPattern> Pat = GlobPattern::create(S); | ||
| 27 | if (!Pat) | ||
| 28 | error(toString(Pat.takeError())); | ||
| 29 | else | ||
| 30 | Patterns.push_back(*Pat); | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | bool StringMatcher::match(StringRef S) const { | ||
| 35 | for (const GlobPattern &Pat : Patterns) | ||
| 36 | if (Pat.match(S)) | ||
| 37 | return true; | ||
| 38 | return false; | ||
| 39 | } | ||
| 40 | |||
| 41 | // Converts a hex string (e.g. "deadbeef") to a vector. | ||
| 42 | std::vector<uint8_t> elf::parseHex(StringRef S) { | ||
| 43 | std::vector<uint8_t> Hex; | ||
| 44 | while (!S.empty()) { | ||
| 45 | StringRef B = S.substr(0, 2); | ||
| 46 | S = S.substr(2); | ||
| 47 | uint8_t H; | ||
| 48 | if (!to_integer(B, H, 16)) { | ||
| 49 | error("not a hexadecimal value: " + B); | ||
| 50 | return {}; | ||
| 51 | } | ||
| 52 | Hex.push_back(H); | ||
| 53 | } | ||
| 54 | return Hex; | ||
| 55 | } | ||
| 56 | |||
| 57 | // Returns true if S is valid as a C language identifier. | ||
| 58 | bool elf::isValidCIdentifier(StringRef S) { | ||
| 59 | return !S.empty() && (isAlpha(S[0]) || S[0] == '_') && | ||
| 60 | std::all_of(S.begin() + 1, S.end(), | ||
| 61 | [](char C) { return C == '_' || isAlnum(C); }); | ||
| 62 | } | ||
deps/lld/ELF/Strings.h deleted-75| ... | @@ -1,75 +0,0 @@ | ||
| 1 | //===- Strings.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_STRINGS_H | ||
| 11 | #define LLD_ELF_STRINGS_H | ||
| 12 | |||
| 13 | #include "lld/Common/LLVM.h" | ||
| 14 | #include "llvm/ADT/ArrayRef.h" | ||
| 15 | #include "llvm/ADT/BitVector.h" | ||
| 16 | #include "llvm/ADT/Optional.h" | ||
| 17 | #include "llvm/ADT/StringRef.h" | ||
| 18 | #include "llvm/Support/GlobPattern.h" | ||
| 19 | #include <vector> | ||
| 20 | |||
| 21 | namespace lld { | ||
| 22 | namespace elf { | ||
| 23 | |||
| 24 | std::vector<uint8_t> parseHex(StringRef S); | ||
| 25 | bool isValidCIdentifier(StringRef S); | ||
| 26 | |||
| 27 | // This is a lazy version of StringRef. String size is computed lazily | ||
| 28 | // when it is needed. It is more efficient than StringRef to instantiate | ||
| 29 | // if you have a string whose size is unknown. | ||
| 30 | // | ||
| 31 | // ELF string tables contain a lot of null-terminated strings. | ||
| 32 | // Most of them are not necessary for the linker because they are names | ||
| 33 | // of local symbols and the linker doesn't use local symbol names for | ||
| 34 | // name resolution. So, we use this class to represents strings read | ||
| 35 | // from string tables. | ||
| 36 | class StringRefZ { | ||
| 37 | public: | ||
| 38 | StringRefZ() : Start(nullptr), Size(0) {} | ||
| 39 | StringRefZ(const char *S, size_t Size) : Start(S), Size(Size) {} | ||
| 40 | |||
| 41 | /*implicit*/ StringRefZ(const char *S) : Start(S), Size(-1) {} | ||
| 42 | |||
| 43 | /*implicit*/ StringRefZ(llvm::StringRef S) | ||
| 44 | : Start(S.data()), Size(S.size()) {} | ||
| 45 | |||
| 46 | operator llvm::StringRef() const { | ||
| 47 | if (Size == (size_t)-1) | ||
| 48 | Size = strlen(Start); | ||
| 49 | return {Start, Size}; | ||
| 50 | } | ||
| 51 | |||
| 52 | private: | ||
| 53 | const char *Start; | ||
| 54 | mutable size_t Size; | ||
| 55 | }; | ||
| 56 | |||
| 57 | // This class represents multiple glob patterns. | ||
| 58 | class StringMatcher { | ||
| 59 | public: | ||
| 60 | StringMatcher() = default; | ||
| 61 | explicit StringMatcher(ArrayRef<StringRef> Pat); | ||
| 62 | |||
| 63 | bool match(StringRef S) const; | ||
| 64 | |||
| 65 | private: | ||
| 66 | std::vector<llvm::GlobPattern> Patterns; | ||
| 67 | }; | ||
| 68 | |||
| 69 | inline ArrayRef<uint8_t> toArrayRef(StringRef S) { | ||
| 70 | return {(const uint8_t *)S.data(), S.size()}; | ||
| 71 | } | ||
| 72 | } // namespace elf | ||
| 73 | } // namespace lld | ||
| 74 | |||
| 75 | #endif | ||
deps/lld/ELF/SymbolTable.cpp+172-125| ... | @@ -38,7 +38,7 @@ static InputFile *getFirstElf() { | ... | @@ -38,7 +38,7 @@ static InputFile *getFirstElf() { |
| 38 | return ObjectFiles[0]; | 38 | return ObjectFiles[0]; |
| 39 | if (!SharedFiles.empty()) | 39 | if (!SharedFiles.empty()) |
| 40 | return SharedFiles[0]; | 40 | return SharedFiles[0]; |
| 41 | return nullptr; | 41 | return BitcodeFiles[0]; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | // All input object files must be for the same architecture | 44 | // All input object files must be for the same architecture |
| ... | @@ -82,6 +82,7 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) { | ... | @@ -82,6 +82,7 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) { |
| 82 | 82 | ||
| 83 | // Lazy object file | 83 | // Lazy object file |
| 84 | if (auto *F = dyn_cast<LazyObjFile>(File)) { | 84 | if (auto *F = dyn_cast<LazyObjFile>(File)) { |
| 85 | LazyObjFiles.push_back(F); | ||
| 85 | F->parse<ELFT>(); | 86 | F->parse<ELFT>(); |
| 86 | return; | 87 | return; |
| 87 | } | 88 | } |
| ... | @@ -117,7 +118,7 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) { | ... | @@ -117,7 +118,7 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) { |
| 117 | // not in native object file format but in the LLVM bitcode format. | 118 | // not in native object file format but in the LLVM bitcode format. |
| 118 | // This function compiles bitcode files into a few big native files | 119 | // This function compiles bitcode files into a few big native files |
| 119 | // using LLVM functions and replaces bitcode symbols with the results. | 120 | // using LLVM functions and replaces bitcode symbols with the results. |
| 120 | // Because all bitcode files that consist of a program are passed | 121 | // Because all bitcode files that the program consists of are passed |
| 121 | // to the compiler at once, it can do whole-program optimization. | 122 | // to the compiler at once, it can do whole-program optimization. |
| 122 | template <class ELFT> void SymbolTable::addCombinedLTOObject() { | 123 | template <class ELFT> void SymbolTable::addCombinedLTOObject() { |
| 123 | if (BitcodeFiles.empty()) | 124 | if (BitcodeFiles.empty()) |
| ... | @@ -130,7 +131,10 @@ template <class ELFT> void SymbolTable::addCombinedLTOObject() { | ... | @@ -130,7 +131,10 @@ template <class ELFT> void SymbolTable::addCombinedLTOObject() { |
| 130 | 131 | ||
| 131 | for (InputFile *File : LTO->compile()) { | 132 | for (InputFile *File : LTO->compile()) { |
| 132 | DenseSet<CachedHashStringRef> DummyGroups; | 133 | DenseSet<CachedHashStringRef> DummyGroups; |
| 133 | cast<ObjFile<ELFT>>(File)->parse(DummyGroups); | 134 | auto *Obj = cast<ObjFile<ELFT>>(File); |
| 135 | Obj->parse(DummyGroups); | ||
| 136 | for (Symbol *Sym : Obj->getGlobalSymbols()) | ||
| 137 | Sym->parseSymbolVersion(); | ||
| 134 | ObjectFiles.push_back(File); | 138 | ObjectFiles.push_back(File); |
| 135 | } | 139 | } |
| 136 | } | 140 | } |
| ... | @@ -154,6 +158,12 @@ template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) { | ... | @@ -154,6 +158,12 @@ template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) { |
| 154 | Symbol *Sym = find(Name); | 158 | Symbol *Sym = find(Name); |
| 155 | if (!Sym) | 159 | if (!Sym) |
| 156 | return; | 160 | return; |
| 161 | |||
| 162 | // Do not wrap the same symbol twice. | ||
| 163 | for (const WrappedSymbol &S : WrappedSymbols) | ||
| 164 | if (S.Sym == Sym) | ||
| 165 | return; | ||
| 166 | |||
| 157 | Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name)); | 167 | Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name)); |
| 158 | Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name)); | 168 | Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name)); |
| 159 | WrappedSymbols.push_back({Sym, Real, Wrap}); | 169 | WrappedSymbols.push_back({Sym, Real, Wrap}); |
| ... | @@ -186,7 +196,7 @@ void SymbolTable::applySymbolWrap() { | ... | @@ -186,7 +196,7 @@ void SymbolTable::applySymbolWrap() { |
| 186 | // First, make a copy of __real_sym. | 196 | // First, make a copy of __real_sym. |
| 187 | Symbol *Real = nullptr; | 197 | Symbol *Real = nullptr; |
| 188 | if (W.Real->isDefined()) { | 198 | if (W.Real->isDefined()) { |
| 189 | Real = (Symbol *)make<SymbolUnion>(); | 199 | Real = reinterpret_cast<Symbol *>(make<SymbolUnion>()); |
| 190 | memcpy(Real, W.Real, sizeof(SymbolUnion)); | 200 | memcpy(Real, W.Real, sizeof(SymbolUnion)); |
| 191 | } | 201 | } |
| 192 | 202 | ||
| ... | @@ -234,8 +244,7 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { | ... | @@ -234,8 +244,7 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { |
| 234 | 244 | ||
| 235 | Symbol *Sym; | 245 | Symbol *Sym; |
| 236 | if (IsNew) { | 246 | if (IsNew) { |
| 237 | Sym = (Symbol *)make<SymbolUnion>(); | 247 | Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); |
| 238 | Sym->InVersionScript = false; | ||
| 239 | Sym->Visibility = STV_DEFAULT; | 248 | Sym->Visibility = STV_DEFAULT; |
| 240 | Sym->IsUsedInRegularObj = false; | 249 | Sym->IsUsedInRegularObj = false; |
| 241 | Sym->ExportDynamic = false; | 250 | Sym->ExportDynamic = false; |
| ... | @@ -294,26 +303,88 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding, | ... | @@ -294,26 +303,88 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding, |
| 294 | uint8_t Visibility = getVisibility(StOther); | 303 | uint8_t Visibility = getVisibility(StOther); |
| 295 | std::tie(S, WasInserted) = | 304 | std::tie(S, WasInserted) = |
| 296 | insert(Name, Type, Visibility, CanOmitFromDynSym, File); | 305 | insert(Name, Type, Visibility, CanOmitFromDynSym, File); |
| 306 | |||
| 297 | // An undefined symbol with non default visibility must be satisfied | 307 | // An undefined symbol with non default visibility must be satisfied |
| 298 | // in the same DSO. | 308 | // in the same DSO. |
| 299 | if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) { | 309 | if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) { |
| 300 | replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type); | 310 | replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type); |
| 301 | return S; | 311 | return S; |
| 302 | } | 312 | } |
| 313 | |||
| 303 | if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK)) | 314 | if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK)) |
| 304 | S->Binding = Binding; | 315 | S->Binding = Binding; |
| 305 | if (Binding != STB_WEAK) { | 316 | |
| 317 | if (!Config->GcSections && Binding != STB_WEAK) | ||
| 306 | if (auto *SS = dyn_cast<SharedSymbol>(S)) | 318 | if (auto *SS = dyn_cast<SharedSymbol>(S)) |
| 307 | if (!Config->GcSections) | 319 | SS->getFile<ELFT>().IsNeeded = true; |
| 308 | SS->getFile<ELFT>().IsNeeded = true; | 320 | |
| 309 | } | 321 | if (S->isLazy()) { |
| 310 | if (auto *L = dyn_cast<Lazy>(S)) { | ||
| 311 | // An undefined weak will not fetch archive members. See comment on Lazy in | 322 | // An undefined weak will not fetch archive members. See comment on Lazy in |
| 312 | // Symbols.h for the details. | 323 | // Symbols.h for the details. |
| 313 | if (Binding == STB_WEAK) | 324 | if (Binding == STB_WEAK) { |
| 314 | L->Type = Type; | 325 | S->Type = Type; |
| 315 | else if (InputFile *F = L->fetch()) | 326 | return S; |
| 316 | addFile<ELFT>(F); | 327 | } |
| 328 | |||
| 329 | // Do extra check for --warn-backrefs. | ||
| 330 | // | ||
| 331 | // --warn-backrefs is an option to prevent an undefined reference from | ||
| 332 | // fetching an archive member written earlier in the command line. It can be | ||
| 333 | // used to keep compatibility with GNU linkers to some degree. | ||
| 334 | // I'll explain the feature and why you may find it useful in this comment. | ||
| 335 | // | ||
| 336 | // lld's symbol resolution semantics is more relaxed than traditional Unix | ||
| 337 | // linkers. For example, | ||
| 338 | // | ||
| 339 | // ld.lld foo.a bar.o | ||
| 340 | // | ||
| 341 | // succeeds even if bar.o contains an undefined symbol that has to be | ||
| 342 | // resolved by some object file in foo.a. Traditional Unix linkers don't | ||
| 343 | // allow this kind of backward reference, as they visit each file only once | ||
| 344 | // from left to right in the command line while resolving all undefined | ||
| 345 | // symbols at the moment of visiting. | ||
| 346 | // | ||
| 347 | // In the above case, since there's no undefined symbol when a linker visits | ||
| 348 | // foo.a, no files are pulled out from foo.a, and because the linker forgets | ||
| 349 | // about foo.a after visiting, it can't resolve undefined symbols in bar.o | ||
| 350 | // that could have been resolved otherwise. | ||
| 351 | // | ||
| 352 | // That lld accepts more relaxed form means that (besides it'd make more | ||
| 353 | // sense) you can accidentally write a command line or a build file that | ||
| 354 | // works only with lld, even if you have a plan to distribute it to wider | ||
| 355 | // users who may be using GNU linkers. With --warn-backrefs, you can detect | ||
| 356 | // a library order that doesn't work with other Unix linkers. | ||
| 357 | // | ||
| 358 | // The option is also useful to detect cyclic dependencies between static | ||
| 359 | // archives. Again, lld accepts | ||
| 360 | // | ||
| 361 | // ld.lld foo.a bar.a | ||
| 362 | // | ||
| 363 | // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is | ||
| 364 | // handled as an error. | ||
| 365 | // | ||
| 366 | // Here is how the option works. We assign a group ID to each file. A file | ||
| 367 | // with a smaller group ID can pull out object files from an archive file | ||
| 368 | // with an equal or greater group ID. Otherwise, it is a reverse dependency | ||
| 369 | // and an error. | ||
| 370 | // | ||
| 371 | // A file outside --{start,end}-group gets a fresh ID when instantiated. All | ||
| 372 | // files within the same --{start,end}-group get the same group ID. E.g. | ||
| 373 | // | ||
| 374 | // ld.lld A B --start-group C D --end-group E | ||
| 375 | // | ||
| 376 | // A forms group 0. B form group 1. C and D (including their member object | ||
| 377 | // files) form group 2. E forms group 3. I think that you can see how this | ||
| 378 | // group assignment rule simulates the traditional linker's semantics. | ||
| 379 | bool Backref = | ||
| 380 | Config->WarnBackrefs && File && S->File->GroupId < File->GroupId; | ||
| 381 | fetchLazy<ELFT>(S); | ||
| 382 | |||
| 383 | // We don't report backward references to weak symbols as they can be | ||
| 384 | // overridden later. | ||
| 385 | if (Backref && S->Binding != STB_WEAK) | ||
| 386 | warn("backward reference detected: " + Name + " in " + toString(File) + | ||
| 387 | " refers to " + toString(S->File)); | ||
| 317 | } | 388 | } |
| 318 | return S; | 389 | return S; |
| 319 | } | 390 | } |
| ... | @@ -381,7 +452,11 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment, | ... | @@ -381,7 +452,11 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment, |
| 381 | bool WasInserted; | 452 | bool WasInserted; |
| 382 | std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther), | 453 | std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther), |
| 383 | /*CanOmitFromDynSym*/ false, &File); | 454 | /*CanOmitFromDynSym*/ false, &File); |
| 455 | |||
| 384 | int Cmp = compareDefined(S, WasInserted, Binding, N); | 456 | int Cmp = compareDefined(S, WasInserted, Binding, N); |
| 457 | if (Cmp < 0) | ||
| 458 | return S; | ||
| 459 | |||
| 385 | if (Cmp > 0) { | 460 | if (Cmp > 0) { |
| 386 | auto *Bss = make<BssSection>("COMMON", Size, Alignment); | 461 | auto *Bss = make<BssSection>("COMMON", Size, Alignment); |
| 387 | Bss->File = &File; | 462 | Bss->File = &File; |
| ... | @@ -389,45 +464,43 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment, | ... | @@ -389,45 +464,43 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment, |
| 389 | InputSections.push_back(Bss); | 464 | InputSections.push_back(Bss); |
| 390 | 465 | ||
| 391 | replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss); | 466 | replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss); |
| 392 | } else if (Cmp == 0) { | 467 | return S; |
| 393 | auto *D = cast<Defined>(S); | 468 | } |
| 394 | auto *Bss = dyn_cast_or_null<BssSection>(D->Section); | ||
| 395 | if (!Bss) { | ||
| 396 | // Non-common symbols take precedence over common symbols. | ||
| 397 | if (Config->WarnCommon) | ||
| 398 | warn("common " + S->getName() + " is overridden"); | ||
| 399 | return S; | ||
| 400 | } | ||
| 401 | 469 | ||
| 470 | auto *D = cast<Defined>(S); | ||
| 471 | auto *Bss = dyn_cast_or_null<BssSection>(D->Section); | ||
| 472 | if (!Bss) { | ||
| 473 | // Non-common symbols take precedence over common symbols. | ||
| 402 | if (Config->WarnCommon) | 474 | if (Config->WarnCommon) |
| 403 | warn("multiple common of " + D->getName()); | 475 | warn("common " + S->getName() + " is overridden"); |
| 476 | return S; | ||
| 477 | } | ||
| 404 | 478 | ||
| 405 | Bss->Alignment = std::max(Bss->Alignment, Alignment); | 479 | if (Config->WarnCommon) |
| 406 | if (Size > Bss->Size) { | 480 | warn("multiple common of " + D->getName()); |
| 407 | D->File = Bss->File = &File; | 481 | |
| 408 | D->Size = Bss->Size = Size; | 482 | Bss->Alignment = std::max(Bss->Alignment, Alignment); |
| 409 | } | 483 | if (Size > Bss->Size) { |
| 484 | D->File = Bss->File = &File; | ||
| 485 | D->Size = Bss->Size = Size; | ||
| 410 | } | 486 | } |
| 411 | return S; | 487 | return S; |
| 412 | } | 488 | } |
| 413 | 489 | ||
| 414 | static void warnOrError(const Twine &Msg) { | ||
| 415 | if (Config->AllowMultipleDefinition) | ||
| 416 | warn(Msg); | ||
| 417 | else | ||
| 418 | error(Msg); | ||
| 419 | } | ||
| 420 | |||
| 421 | static void reportDuplicate(Symbol *Sym, InputFile *NewFile) { | 490 | static void reportDuplicate(Symbol *Sym, InputFile *NewFile) { |
| 422 | warnOrError("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " + | 491 | if (!Config->AllowMultipleDefinition) |
| 423 | toString(Sym->File) + "\n>>> defined in " + toString(NewFile)); | 492 | error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " + |
| 493 | toString(Sym->File) + "\n>>> defined in " + toString(NewFile)); | ||
| 424 | } | 494 | } |
| 425 | 495 | ||
| 426 | static void reportDuplicate(Symbol *Sym, InputSectionBase *ErrSec, | 496 | static void reportDuplicate(Symbol *Sym, InputFile *NewFile, |
| 427 | uint64_t ErrOffset) { | 497 | InputSectionBase *ErrSec, uint64_t ErrOffset) { |
| 498 | if (Config->AllowMultipleDefinition) | ||
| 499 | return; | ||
| 500 | |||
| 428 | Defined *D = cast<Defined>(Sym); | 501 | Defined *D = cast<Defined>(Sym); |
| 429 | if (!D->Section || !ErrSec) { | 502 | if (!D->Section || !ErrSec) { |
| 430 | reportDuplicate(Sym, ErrSec ? ErrSec->File : nullptr); | 503 | reportDuplicate(Sym, NewFile); |
| 431 | return; | 504 | return; |
| 432 | } | 505 | } |
| 433 | 506 | ||
| ... | @@ -451,7 +524,7 @@ static void reportDuplicate(Symbol *Sym, InputSectionBase *ErrSec, | ... | @@ -451,7 +524,7 @@ static void reportDuplicate(Symbol *Sym, InputSectionBase *ErrSec, |
| 451 | if (!Src2.empty()) | 524 | if (!Src2.empty()) |
| 452 | Msg += Src2 + "\n>>> "; | 525 | Msg += Src2 + "\n>>> "; |
| 453 | Msg += Obj2; | 526 | Msg += Obj2; |
| 454 | warnOrError(Msg); | 527 | error(Msg); |
| 455 | } | 528 | } |
| 456 | 529 | ||
| 457 | Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, | 530 | Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, |
| ... | @@ -467,7 +540,8 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, | ... | @@ -467,7 +540,8 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, |
| 467 | replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size, | 540 | replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size, |
| 468 | Section); | 541 | Section); |
| 469 | else if (Cmp == 0) | 542 | else if (Cmp == 0) |
| 470 | reportDuplicate(S, dyn_cast_or_null<InputSectionBase>(Section), Value); | 543 | reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section), |
| 544 | Value); | ||
| 471 | return S; | 545 | return S; |
| 472 | } | 546 | } |
| 473 | 547 | ||
| ... | @@ -488,8 +562,8 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File, | ... | @@ -488,8 +562,8 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File, |
| 488 | 562 | ||
| 489 | // An undefined symbol with non default visibility must be satisfied | 563 | // An undefined symbol with non default visibility must be satisfied |
| 490 | // in the same DSO. | 564 | // in the same DSO. |
| 491 | if (WasInserted || ((S->isUndefined() || S->isLazy()) && | 565 | if (WasInserted || |
| 492 | S->getVisibility() == STV_DEFAULT)) { | 566 | ((S->isUndefined() || S->isLazy()) && S->Visibility == STV_DEFAULT)) { |
| 493 | uint8_t Binding = S->Binding; | 567 | uint8_t Binding = S->Binding; |
| 494 | bool WasUndefined = S->isUndefined(); | 568 | bool WasUndefined = S->isUndefined(); |
| 495 | replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other, | 569 | replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other, |
| ... | @@ -528,85 +602,58 @@ Symbol *SymbolTable::find(StringRef Name) { | ... | @@ -528,85 +602,58 @@ Symbol *SymbolTable::find(StringRef Name) { |
| 528 | return SymVector[It->second]; | 602 | return SymVector[It->second]; |
| 529 | } | 603 | } |
| 530 | 604 | ||
| 531 | template <class ELFT> | 605 | // This is used to handle lazy symbols. May replace existent |
| 532 | Symbol *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F, | 606 | // symbol with lazy version or request to Fetch it. |
| 533 | const object::Archive::Symbol Sym) { | 607 | template <class ELFT, typename LazyT, typename... ArgT> |
| 608 | static void replaceOrFetchLazy(StringRef Name, InputFile &File, | ||
| 609 | llvm::function_ref<InputFile *()> Fetch, | ||
| 610 | ArgT &&... Arg) { | ||
| 534 | Symbol *S; | 611 | Symbol *S; |
| 535 | bool WasInserted; | 612 | bool WasInserted; |
| 536 | std::tie(S, WasInserted) = insert(Name); | 613 | std::tie(S, WasInserted) = Symtab->insert(Name); |
| 537 | if (WasInserted) { | 614 | if (WasInserted) { |
| 538 | replaceSymbol<LazyArchive>(S, F, Sym, Symbol::UnknownType); | 615 | replaceSymbol<LazyT>(S, File, Symbol::UnknownType, |
| 539 | return S; | 616 | std::forward<ArgT>(Arg)...); |
| 617 | return; | ||
| 540 | } | 618 | } |
| 541 | if (!S->isUndefined()) | 619 | if (!S->isUndefined()) |
| 542 | return S; | 620 | return; |
| 543 | 621 | ||
| 544 | // An undefined weak will not fetch archive members. See comment on Lazy in | 622 | // An undefined weak will not fetch archive members. See comment on Lazy in |
| 545 | // Symbols.h for the details. | 623 | // Symbols.h for the details. |
| 546 | if (S->isWeak()) { | 624 | if (S->isWeak()) { |
| 547 | replaceSymbol<LazyArchive>(S, F, Sym, S->Type); | 625 | replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...); |
| 548 | S->Binding = STB_WEAK; | 626 | S->Binding = STB_WEAK; |
| 549 | return S; | 627 | return; |
| 550 | } | 628 | } |
| 551 | std::pair<MemoryBufferRef, uint64_t> MBInfo = F.getMember(&Sym); | 629 | |
| 552 | if (!MBInfo.first.getBuffer().empty()) | 630 | if (InputFile *F = Fetch()) |
| 553 | addFile<ELFT>(createObjectFile(MBInfo.first, F.getName(), MBInfo.second)); | 631 | Symtab->addFile<ELFT>(F); |
| 554 | return S; | ||
| 555 | } | 632 | } |
| 556 | 633 | ||
| 557 | template <class ELFT> | 634 | template <class ELFT> |
| 558 | void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) { | 635 | void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F, |
| 559 | Symbol *S; | 636 | const object::Archive::Symbol Sym) { |
| 560 | bool WasInserted; | 637 | replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() { return F.fetch(Sym); }, |
| 561 | std::tie(S, WasInserted) = insert(Name); | 638 | Sym); |
| 562 | if (WasInserted) { | ||
| 563 | replaceSymbol<LazyObject>(S, Obj, Name, Symbol::UnknownType); | ||
| 564 | return; | ||
| 565 | } | ||
| 566 | if (!S->isUndefined()) | ||
| 567 | return; | ||
| 568 | |||
| 569 | // See comment for addLazyArchive above. | ||
| 570 | if (S->isWeak()) | ||
| 571 | replaceSymbol<LazyObject>(S, Obj, Name, S->Type); | ||
| 572 | else if (InputFile *F = Obj.fetch()) | ||
| 573 | addFile<ELFT>(F); | ||
| 574 | } | ||
| 575 | |||
| 576 | // If we already saw this symbol, force loading its file. | ||
| 577 | template <class ELFT> void SymbolTable::fetchIfLazy(StringRef Name) { | ||
| 578 | if (Symbol *B = find(Name)) { | ||
| 579 | // Mark the symbol not to be eliminated by LTO | ||
| 580 | // even if it is a bitcode symbol. | ||
| 581 | B->IsUsedInRegularObj = true; | ||
| 582 | if (auto *L = dyn_cast<Lazy>(B)) | ||
| 583 | if (InputFile *File = L->fetch()) | ||
| 584 | addFile<ELFT>(File); | ||
| 585 | } | ||
| 586 | } | 639 | } |
| 587 | 640 | ||
| 588 | // This function takes care of the case in which shared libraries depend on | 641 | template <class ELFT> |
| 589 | // the user program (not the other way, which is usual). Shared libraries | 642 | void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) { |
| 590 | // may have undefined symbols, expecting that the user program provides | 643 | replaceOrFetchLazy<ELFT, LazyObject>(Name, Obj, [&]() { return Obj.fetch(); }, |
| 591 | // the definitions for them. An example is BSD's __progname symbol. | 644 | Name); |
| 592 | // We need to put such symbols to the main program's .dynsym so that | 645 | } |
| 593 | // shared libraries can find them. | ||
| 594 | // Except this, we ignore undefined symbols in DSOs. | ||
| 595 | template <class ELFT> void SymbolTable::scanShlibUndefined() { | ||
| 596 | for (InputFile *F : SharedFiles) { | ||
| 597 | for (StringRef U : cast<SharedFile<ELFT>>(F)->getUndefinedSymbols()) { | ||
| 598 | Symbol *Sym = find(U); | ||
| 599 | if (!Sym || !Sym->isDefined()) | ||
| 600 | continue; | ||
| 601 | Sym->ExportDynamic = true; | ||
| 602 | 646 | ||
| 603 | // If -dynamic-list is given, the default version is set to | 647 | template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) { |
| 604 | // VER_NDX_LOCAL, which prevents a symbol to be exported via .dynsym. | 648 | if (auto *S = dyn_cast<LazyArchive>(Sym)) { |
| 605 | // Set to VER_NDX_GLOBAL so the symbol will be handled as if it were | 649 | if (InputFile *File = S->fetch()) |
| 606 | // specified by -dynamic-list. | 650 | addFile<ELFT>(File); |
| 607 | Sym->VersionId = VER_NDX_GLOBAL; | 651 | return; |
| 608 | } | ||
| 609 | } | 652 | } |
| 653 | |||
| 654 | auto *S = cast<LazyObject>(Sym); | ||
| 655 | if (InputFile *File = cast<LazyObjFile>(S->File)->fetch()) | ||
| 656 | addFile<ELFT>(File); | ||
| 610 | } | 657 | } |
| 611 | 658 | ||
| 612 | // Initialize DemangledSyms with a map from demangled symbols to symbol | 659 | // Initialize DemangledSyms with a map from demangled symbols to symbol |
| ... | @@ -705,7 +752,7 @@ void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId, | ... | @@ -705,7 +752,7 @@ void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId, |
| 705 | // Get a list of symbols which we need to assign the version to. | 752 | // Get a list of symbols which we need to assign the version to. |
| 706 | std::vector<Symbol *> Syms = findByVersion(Ver); | 753 | std::vector<Symbol *> Syms = findByVersion(Ver); |
| 707 | if (Syms.empty()) { | 754 | if (Syms.empty()) { |
| 708 | if (Config->NoUndefinedVersion) | 755 | if (!Config->UndefinedVersion) |
| 709 | error("version script assignment of '" + VersionName + "' to symbol '" + | 756 | error("version script assignment of '" + VersionName + "' to symbol '" + |
| 710 | Ver.Name + "' failed: symbol not defined"); | 757 | Ver.Name + "' failed: symbol not defined"); |
| 711 | return; | 758 | return; |
| ... | @@ -719,10 +766,10 @@ void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId, | ... | @@ -719,10 +766,10 @@ void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId, |
| 719 | if (Sym->getName().contains('@')) | 766 | if (Sym->getName().contains('@')) |
| 720 | continue; | 767 | continue; |
| 721 | 768 | ||
| 722 | if (Sym->InVersionScript) | 769 | if (Sym->VersionId != Config->DefaultSymbolVersion && |
| 723 | warn("duplicate symbol '" + Ver.Name + "' in version script"); | 770 | Sym->VersionId != VersionId) |
| 771 | error("duplicate symbol '" + Ver.Name + "' in version script"); | ||
| 724 | Sym->VersionId = VersionId; | 772 | Sym->VersionId = VersionId; |
| 725 | Sym->InVersionScript = true; | ||
| 726 | } | 773 | } |
| 727 | } | 774 | } |
| 728 | 775 | ||
| ... | @@ -770,6 +817,11 @@ void SymbolTable::scanVersionScript() { | ... | @@ -770,6 +817,11 @@ void SymbolTable::scanVersionScript() { |
| 770 | Sym->parseSymbolVersion(); | 817 | Sym->parseSymbolVersion(); |
| 771 | } | 818 | } |
| 772 | 819 | ||
| 820 | template void SymbolTable::addFile<ELF32LE>(InputFile *); | ||
| 821 | template void SymbolTable::addFile<ELF32BE>(InputFile *); | ||
| 822 | template void SymbolTable::addFile<ELF64LE>(InputFile *); | ||
| 823 | template void SymbolTable::addFile<ELF64BE>(InputFile *); | ||
| 824 | |||
| 773 | template void SymbolTable::addSymbolWrap<ELF32LE>(StringRef); | 825 | template void SymbolTable::addSymbolWrap<ELF32LE>(StringRef); |
| 774 | template void SymbolTable::addSymbolWrap<ELF32BE>(StringRef); | 826 | template void SymbolTable::addSymbolWrap<ELF32BE>(StringRef); |
| 775 | template void SymbolTable::addSymbolWrap<ELF64LE>(StringRef); | 827 | template void SymbolTable::addSymbolWrap<ELF64LE>(StringRef); |
| ... | @@ -794,16 +846,16 @@ template void SymbolTable::addCombinedLTOObject<ELF32BE>(); | ... | @@ -794,16 +846,16 @@ template void SymbolTable::addCombinedLTOObject<ELF32BE>(); |
| 794 | template void SymbolTable::addCombinedLTOObject<ELF64LE>(); | 846 | template void SymbolTable::addCombinedLTOObject<ELF64LE>(); |
| 795 | template void SymbolTable::addCombinedLTOObject<ELF64BE>(); | 847 | template void SymbolTable::addCombinedLTOObject<ELF64BE>(); |
| 796 | 848 | ||
| 797 | template Symbol * | 849 | template void |
| 798 | SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile &, | 850 | SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile &, |
| 799 | const object::Archive::Symbol); | 851 | const object::Archive::Symbol); |
| 800 | template Symbol * | 852 | template void |
| 801 | SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile &, | 853 | SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile &, |
| 802 | const object::Archive::Symbol); | 854 | const object::Archive::Symbol); |
| 803 | template Symbol * | 855 | template void |
| 804 | SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile &, | 856 | SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile &, |
| 805 | const object::Archive::Symbol); | 857 | const object::Archive::Symbol); |
| 806 | template Symbol * | 858 | template void |
| 807 | SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile &, | 859 | SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile &, |
| 808 | const object::Archive::Symbol); | 860 | const object::Archive::Symbol); |
| 809 | 861 | ||
| ... | @@ -812,6 +864,11 @@ template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjFile &); | ... | @@ -812,6 +864,11 @@ template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjFile &); |
| 812 | template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &); | 864 | template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &); |
| 813 | template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &); | 865 | template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &); |
| 814 | 866 | ||
| 867 | template void SymbolTable::fetchLazy<ELF32LE>(Symbol *); | ||
| 868 | template void SymbolTable::fetchLazy<ELF32BE>(Symbol *); | ||
| 869 | template void SymbolTable::fetchLazy<ELF64LE>(Symbol *); | ||
| 870 | template void SymbolTable::fetchLazy<ELF64BE>(Symbol *); | ||
| 871 | |||
| 815 | template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &, | 872 | template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &, |
| 816 | const typename ELF32LE::Sym &, | 873 | const typename ELF32LE::Sym &, |
| 817 | uint32_t Alignment, uint32_t); | 874 | uint32_t Alignment, uint32_t); |
| ... | @@ -824,13 +881,3 @@ template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &, | ... | @@ -824,13 +881,3 @@ template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &, |
| 824 | template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &, | 881 | template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &, |
| 825 | const typename ELF64BE::Sym &, | 882 | const typename ELF64BE::Sym &, |
| 826 | uint32_t Alignment, uint32_t); | 883 | uint32_t Alignment, uint32_t); |
| 827 | |||
| 828 | template void SymbolTable::fetchIfLazy<ELF32LE>(StringRef); | ||
| 829 | template void SymbolTable::fetchIfLazy<ELF32BE>(StringRef); | ||
| 830 | template void SymbolTable::fetchIfLazy<ELF64LE>(StringRef); | ||
| 831 | template void SymbolTable::fetchIfLazy<ELF64BE>(StringRef); | ||
| 832 | |||
| 833 | template void SymbolTable::scanShlibUndefined<ELF32LE>(); | ||
| 834 | template void SymbolTable::scanShlibUndefined<ELF32BE>(); | ||
| 835 | template void SymbolTable::scanShlibUndefined<ELF64LE>(); | ||
| 836 | template void SymbolTable::scanShlibUndefined<ELF64BE>(); |
deps/lld/ELF/SymbolTable.h+5-6| ... | @@ -12,7 +12,7 @@ | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | ||
| 13 | #include "InputFiles.h" | 13 | #include "InputFiles.h" |
| 14 | #include "LTO.h" | 14 | #include "LTO.h" |
| 15 | #include "Strings.h" | 15 | #include "lld/Common/Strings.h" |
| 16 | #include "llvm/ADT/CachedHashString.h" | 16 | #include "llvm/ADT/CachedHashString.h" |
| 17 | #include "llvm/ADT/DenseMap.h" | 17 | #include "llvm/ADT/DenseMap.h" |
| 18 | 18 | ||
| ... | @@ -60,8 +60,8 @@ public: | ... | @@ -60,8 +60,8 @@ public: |
| 60 | uint32_t VerdefIndex); | 60 | uint32_t VerdefIndex); |
| 61 | 61 | ||
| 62 | template <class ELFT> | 62 | template <class ELFT> |
| 63 | Symbol *addLazyArchive(StringRef Name, ArchiveFile &F, | 63 | void addLazyArchive(StringRef Name, ArchiveFile &F, |
| 64 | const llvm::object::Archive::Symbol S); | 64 | const llvm::object::Archive::Symbol S); |
| 65 | 65 | ||
| 66 | template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj); | 66 | template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj); |
| 67 | 67 | ||
| ... | @@ -77,8 +77,8 @@ public: | ... | @@ -77,8 +77,8 @@ public: |
| 77 | uint8_t Visibility, bool CanOmitFromDynSym, | 77 | uint8_t Visibility, bool CanOmitFromDynSym, |
| 78 | InputFile *File); | 78 | InputFile *File); |
| 79 | 79 | ||
| 80 | template <class ELFT> void fetchIfLazy(StringRef Name); | 80 | template <class ELFT> void fetchLazy(Symbol *Sym); |
| 81 | template <class ELFT> void scanShlibUndefined(); | 81 | |
| 82 | void scanVersionScript(); | 82 | void scanVersionScript(); |
| 83 | 83 | ||
| 84 | Symbol *find(StringRef Name); | 84 | Symbol *find(StringRef Name); |
| ... | @@ -90,7 +90,6 @@ public: | ... | @@ -90,7 +90,6 @@ public: |
| 90 | private: | 90 | private: |
| 91 | std::vector<Symbol *> findByVersion(SymbolVersion Ver); | 91 | std::vector<Symbol *> findByVersion(SymbolVersion Ver); |
| 92 | std::vector<Symbol *> findAllByVersion(SymbolVersion Ver); | 92 | std::vector<Symbol *> findAllByVersion(SymbolVersion Ver); |
| 93 | void defsym(Symbol *Dst, Symbol *Src); | ||
| 94 | 93 | ||
| 95 | llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms(); | 94 | llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms(); |
| 96 | void handleAnonymousVersion(); | 95 | void handleAnonymousVersion(); |
deps/lld/ELF/Symbols.cpp+43-52| ... | @@ -14,7 +14,6 @@ | ... | @@ -14,7 +14,6 @@ |
| 14 | #include "SyntheticSections.h" | 14 | #include "SyntheticSections.h" |
| 15 | #include "Target.h" | 15 | #include "Target.h" |
| 16 | #include "Writer.h" | 16 | #include "Writer.h" |
| 17 | |||
| 18 | #include "lld/Common/ErrorHandler.h" | 17 | #include "lld/Common/ErrorHandler.h" |
| 19 | #include "lld/Common/Strings.h" | 18 | #include "lld/Common/Strings.h" |
| 20 | #include "llvm/ADT/STLExtras.h" | 19 | #include "llvm/ADT/STLExtras.h" |
| ... | @@ -39,6 +38,7 @@ Defined *ElfSym::GlobalOffsetTable; | ... | @@ -39,6 +38,7 @@ Defined *ElfSym::GlobalOffsetTable; |
| 39 | Defined *ElfSym::MipsGp; | 38 | Defined *ElfSym::MipsGp; |
| 40 | Defined *ElfSym::MipsGpDisp; | 39 | Defined *ElfSym::MipsGpDisp; |
| 41 | Defined *ElfSym::MipsLocalGp; | 40 | Defined *ElfSym::MipsLocalGp; |
| 41 | Defined *ElfSym::RelaIpltEnd; | ||
| 42 | 42 | ||
| 43 | static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { | 43 | static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { |
| 44 | switch (Sym.kind()) { | 44 | switch (Sym.kind()) { |
| ... | @@ -58,6 +58,7 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { | ... | @@ -58,6 +58,7 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { |
| 58 | return D.Value; | 58 | return D.Value; |
| 59 | 59 | ||
| 60 | IS = IS->Repl; | 60 | IS = IS->Repl; |
| 61 | |||
| 61 | uint64_t Offset = D.Value; | 62 | uint64_t Offset = D.Value; |
| 62 | 63 | ||
| 63 | // An object in an SHF_MERGE section might be referenced via a | 64 | // An object in an SHF_MERGE section might be referenced via a |
| ... | @@ -76,8 +77,6 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { | ... | @@ -76,8 +77,6 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { |
| 76 | Addend = 0; | 77 | Addend = 0; |
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | const OutputSection *OutSec = IS->getOutputSection(); | ||
| 80 | |||
| 81 | // In the typical case, this is actually very simple and boils | 80 | // In the typical case, this is actually very simple and boils |
| 82 | // down to adding together 3 numbers: | 81 | // down to adding together 3 numbers: |
| 83 | // 1. The address of the output section. | 82 | // 1. The address of the output section. |
| ... | @@ -88,7 +87,7 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { | ... | @@ -88,7 +87,7 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { |
| 88 | // If you understand the data structures involved with this next | 87 | // If you understand the data structures involved with this next |
| 89 | // line (and how they get built), then you have a pretty good | 88 | // line (and how they get built), then you have a pretty good |
| 90 | // understanding of the linker. | 89 | // understanding of the linker. |
| 91 | uint64_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset(Offset); | 90 | uint64_t VA = IS->getVA(Offset); |
| 92 | 91 | ||
| 93 | if (D.isTls() && !Config->Relocatable) { | 92 | if (D.isTls() && !Config->Relocatable) { |
| 94 | if (!Out::TlsPhdr) | 93 | if (!Out::TlsPhdr) |
| ... | @@ -98,20 +97,12 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { | ... | @@ -98,20 +97,12 @@ static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { |
| 98 | } | 97 | } |
| 99 | return VA; | 98 | return VA; |
| 100 | } | 99 | } |
| 101 | case Symbol::SharedKind: { | 100 | case Symbol::SharedKind: |
| 102 | auto &SS = cast<SharedSymbol>(Sym); | ||
| 103 | if (SS.CopyRelSec) | ||
| 104 | return SS.CopyRelSec->getParent()->Addr + SS.CopyRelSec->OutSecOff; | ||
| 105 | if (SS.NeedsPltAddr) | ||
| 106 | return Sym.getPltVA(); | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | case Symbol::UndefinedKind: | 101 | case Symbol::UndefinedKind: |
| 110 | return 0; | 102 | return 0; |
| 111 | case Symbol::LazyArchiveKind: | 103 | case Symbol::LazyArchiveKind: |
| 112 | case Symbol::LazyObjectKind: | 104 | case Symbol::LazyObjectKind: |
| 113 | assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer"); | 105 | llvm_unreachable("lazy symbol reached writer"); |
| 114 | return 0; | ||
| 115 | } | 106 | } |
| 116 | llvm_unreachable("invalid symbol kind"); | 107 | llvm_unreachable("invalid symbol kind"); |
| 117 | } | 108 | } |
| ... | @@ -134,22 +125,26 @@ uint64_t Symbol::getGotPltVA() const { | ... | @@ -134,22 +125,26 @@ uint64_t Symbol::getGotPltVA() const { |
| 134 | } | 125 | } |
| 135 | 126 | ||
| 136 | uint64_t Symbol::getGotPltOffset() const { | 127 | uint64_t Symbol::getGotPltOffset() const { |
| 137 | return GotPltIndex * Target->GotPltEntrySize; | 128 | if (IsInIgot) |
| 129 | return PltIndex * Target->GotPltEntrySize; | ||
| 130 | return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize; | ||
| 138 | } | 131 | } |
| 139 | 132 | ||
| 140 | uint64_t Symbol::getPltVA() const { | 133 | uint64_t Symbol::getPltVA() const { |
| 141 | if (this->IsInIplt) | 134 | if (this->IsInIplt) |
| 142 | return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize; | 135 | return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize; |
| 143 | return InX::Plt->getVA() + Target->PltHeaderSize + | 136 | return InX::Plt->getVA() + Target->getPltEntryOffset(PltIndex); |
| 144 | PltIndex * Target->PltEntrySize; | 137 | } |
| 138 | |||
| 139 | uint64_t Symbol::getPltOffset() const { | ||
| 140 | assert(!this->IsInIplt); | ||
| 141 | return Target->getPltEntryOffset(PltIndex); | ||
| 145 | } | 142 | } |
| 146 | 143 | ||
| 147 | uint64_t Symbol::getSize() const { | 144 | uint64_t Symbol::getSize() const { |
| 148 | if (const auto *DR = dyn_cast<Defined>(this)) | 145 | if (const auto *DR = dyn_cast<Defined>(this)) |
| 149 | return DR->Size; | 146 | return DR->Size; |
| 150 | if (const auto *S = dyn_cast<SharedSymbol>(this)) | 147 | return cast<SharedSymbol>(this)->Size; |
| 151 | return S->Size; | ||
| 152 | return 0; | ||
| 153 | } | 148 | } |
| 154 | 149 | ||
| 155 | OutputSection *Symbol::getOutputSection() const { | 150 | OutputSection *Symbol::getOutputSection() const { |
| ... | @@ -158,13 +153,6 @@ OutputSection *Symbol::getOutputSection() const { | ... | @@ -158,13 +153,6 @@ OutputSection *Symbol::getOutputSection() const { |
| 158 | return Sec->Repl->getOutputSection(); | 153 | return Sec->Repl->getOutputSection(); |
| 159 | return nullptr; | 154 | return nullptr; |
| 160 | } | 155 | } |
| 161 | |||
| 162 | if (auto *S = dyn_cast<SharedSymbol>(this)) { | ||
| 163 | if (S->CopyRelSec) | ||
| 164 | return S->CopyRelSec->getParent(); | ||
| 165 | return nullptr; | ||
| 166 | } | ||
| 167 | |||
| 168 | return nullptr; | 156 | return nullptr; |
| 169 | } | 157 | } |
| 170 | 158 | ||
| ... | @@ -180,7 +168,7 @@ void Symbol::parseSymbolVersion() { | ... | @@ -180,7 +168,7 @@ void Symbol::parseSymbolVersion() { |
| 180 | return; | 168 | return; |
| 181 | 169 | ||
| 182 | // Truncate the symbol name so that it doesn't include the version string. | 170 | // Truncate the symbol name so that it doesn't include the version string. |
| 183 | Name = {S.data(), Pos}; | 171 | NameSize = Pos; |
| 184 | 172 | ||
| 185 | // If this is not in this DSO, it is not a definition. | 173 | // If this is not in this DSO, it is not a definition. |
| 186 | if (!isDefined()) | 174 | if (!isDefined()) |
| ... | @@ -206,33 +194,15 @@ void Symbol::parseSymbolVersion() { | ... | @@ -206,33 +194,15 @@ void Symbol::parseSymbolVersion() { |
| 206 | // It is an error if the specified version is not defined. | 194 | // It is an error if the specified version is not defined. |
| 207 | // Usually version script is not provided when linking executable, | 195 | // Usually version script is not provided when linking executable, |
| 208 | // but we may still want to override a versioned symbol from DSO, | 196 | // but we may still want to override a versioned symbol from DSO, |
| 209 | // so we do not report error in this case. | 197 | // so we do not report error in this case. We also do not error |
| 210 | if (Config->Shared) | 198 | // if the symbol has a local version as it won't be in the dynamic |
| 199 | // symbol table. | ||
| 200 | if (Config->Shared && VersionId != VER_NDX_LOCAL) | ||
| 211 | error(toString(File) + ": symbol " + S + " has undefined version " + | 201 | error(toString(File) + ": symbol " + S + " has undefined version " + |
| 212 | Verstr); | 202 | Verstr); |
| 213 | } | 203 | } |
| 214 | 204 | ||
| 215 | InputFile *Lazy::fetch() { | 205 | InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); } |
| 216 | if (auto *S = dyn_cast<LazyArchive>(this)) | ||
| 217 | return S->fetch(); | ||
| 218 | return cast<LazyObject>(this)->fetch(); | ||
| 219 | } | ||
| 220 | |||
| 221 | ArchiveFile &LazyArchive::getFile() { return *cast<ArchiveFile>(File); } | ||
| 222 | |||
| 223 | InputFile *LazyArchive::fetch() { | ||
| 224 | std::pair<MemoryBufferRef, uint64_t> MBInfo = getFile().getMember(&Sym); | ||
| 225 | |||
| 226 | // getMember returns an empty buffer if the member was already | ||
| 227 | // read from the library. | ||
| 228 | if (MBInfo.first.getBuffer().empty()) | ||
| 229 | return nullptr; | ||
| 230 | return createObjectFile(MBInfo.first, getFile().getName(), MBInfo.second); | ||
| 231 | } | ||
| 232 | |||
| 233 | LazyObjFile &LazyObject::getFile() { return *cast<LazyObjFile>(File); } | ||
| 234 | |||
| 235 | InputFile *LazyObject::fetch() { return getFile().fetch(); } | ||
| 236 | 206 | ||
| 237 | uint8_t Symbol::computeBinding() const { | 207 | uint8_t Symbol::computeBinding() const { |
| 238 | if (Config->Relocatable) | 208 | if (Config->Relocatable) |
| ... | @@ -241,7 +211,7 @@ uint8_t Symbol::computeBinding() const { | ... | @@ -241,7 +211,7 @@ uint8_t Symbol::computeBinding() const { |
| 241 | return STB_LOCAL; | 211 | return STB_LOCAL; |
| 242 | if (VersionId == VER_NDX_LOCAL && isDefined()) | 212 | if (VersionId == VER_NDX_LOCAL && isDefined()) |
| 243 | return STB_LOCAL; | 213 | return STB_LOCAL; |
| 244 | if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE) | 214 | if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE) |
| 245 | return STB_GLOBAL; | 215 | return STB_GLOBAL; |
| 246 | return Binding; | 216 | return Binding; |
| 247 | } | 217 | } |
| ... | @@ -273,6 +243,27 @@ void elf::printTraceSymbol(Symbol *Sym) { | ... | @@ -273,6 +243,27 @@ void elf::printTraceSymbol(Symbol *Sym) { |
| 273 | message(toString(Sym->File) + S + Sym->getName()); | 243 | message(toString(Sym->File) + S + Sym->getName()); |
| 274 | } | 244 | } |
| 275 | 245 | ||
| 246 | void elf::warnUnorderableSymbol(const Symbol *Sym) { | ||
| 247 | if (!Config->WarnSymbolOrdering) | ||
| 248 | return; | ||
| 249 | |||
| 250 | const InputFile *File = Sym->File; | ||
| 251 | auto *D = dyn_cast<Defined>(Sym); | ||
| 252 | |||
| 253 | auto Warn = [&](StringRef S) { warn(toString(File) + S + Sym->getName()); }; | ||
| 254 | |||
| 255 | if (Sym->isUndefined()) | ||
| 256 | Warn(": unable to order undefined symbol: "); | ||
| 257 | else if (Sym->isShared()) | ||
| 258 | Warn(": unable to order shared symbol: "); | ||
| 259 | else if (D && !D->Section) | ||
| 260 | Warn(": unable to order absolute symbol: "); | ||
| 261 | else if (D && isa<OutputSection>(D->Section)) | ||
| 262 | Warn(": unable to order synthetic symbol: "); | ||
| 263 | else if (D && !D->Section->Repl->Live) | ||
| 264 | Warn(": unable to order discarded symbol: "); | ||
| 265 | } | ||
| 266 | |||
| 276 | // Returns a symbol for an error message. | 267 | // Returns a symbol for an error message. |
| 277 | std::string lld::toString(const Symbol &B) { | 268 | std::string lld::toString(const Symbol &B) { |
| 278 | if (Config->Demangle) | 269 | if (Config->Demangle) |
deps/lld/ELF/Symbols.h+80-79| ... | @@ -7,8 +7,7 @@ | ... | @@ -7,8 +7,7 @@ |
| 7 | // | 7 | // |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | // | 9 | // |
| 10 | // All symbols are handled as SymbolBodies regardless of their types. | 10 | // This file defines various types of Symbols. |
| 11 | // This file defines various types of SymbolBodies. | ||
| 12 | // | 11 | // |
| 13 | //===----------------------------------------------------------------------===// | 12 | //===----------------------------------------------------------------------===// |
| 14 | 13 | ||
| ... | @@ -16,9 +15,8 @@ | ... | @@ -16,9 +15,8 @@ |
| 16 | #define LLD_ELF_SYMBOLS_H | 15 | #define LLD_ELF_SYMBOLS_H |
| 17 | 16 | ||
| 18 | #include "InputSection.h" | 17 | #include "InputSection.h" |
| 19 | #include "Strings.h" | ||
| 20 | |||
| 21 | #include "lld/Common/LLVM.h" | 18 | #include "lld/Common/LLVM.h" |
| 19 | #include "lld/Common/Strings.h" | ||
| 22 | #include "llvm/Object/Archive.h" | 20 | #include "llvm/Object/Archive.h" |
| 23 | #include "llvm/Object/ELF.h" | 21 | #include "llvm/Object/ELF.h" |
| 24 | 22 | ||
| ... | @@ -34,6 +32,20 @@ template <class ELFT> class ObjFile; | ... | @@ -34,6 +32,20 @@ template <class ELFT> class ObjFile; |
| 34 | class OutputSection; | 32 | class OutputSection; |
| 35 | template <class ELFT> class SharedFile; | 33 | template <class ELFT> class SharedFile; |
| 36 | 34 | ||
| 35 | // This is a StringRef-like container that doesn't run strlen(). | ||
| 36 | // | ||
| 37 | // ELF string tables contain a lot of null-terminated strings. Most of them | ||
| 38 | // are not necessary for the linker because they are names of local symbols, | ||
| 39 | // and the linker doesn't use local symbol names for name resolution. So, we | ||
| 40 | // use this class to represents strings read from string tables. | ||
| 41 | struct StringRefZ { | ||
| 42 | StringRefZ(const char *S) : Data(S), Size(-1) {} | ||
| 43 | StringRefZ(StringRef S) : Data(S.data()), Size(S.size()) {} | ||
| 44 | |||
| 45 | const char *Data; | ||
| 46 | const uint32_t Size; | ||
| 47 | }; | ||
| 48 | |||
| 37 | // The base class for real symbol classes. | 49 | // The base class for real symbol classes. |
| 38 | class Symbol { | 50 | class Symbol { |
| 39 | public: | 51 | public: |
| ... | @@ -47,6 +59,25 @@ public: | ... | @@ -47,6 +59,25 @@ public: |
| 47 | 59 | ||
| 48 | Kind kind() const { return static_cast<Kind>(SymbolKind); } | 60 | Kind kind() const { return static_cast<Kind>(SymbolKind); } |
| 49 | 61 | ||
| 62 | // The file from which this symbol was created. | ||
| 63 | InputFile *File; | ||
| 64 | |||
| 65 | protected: | ||
| 66 | const char *NameData; | ||
| 67 | mutable uint32_t NameSize; | ||
| 68 | |||
| 69 | public: | ||
| 70 | uint32_t DynsymIndex = 0; | ||
| 71 | uint32_t GotIndex = -1; | ||
| 72 | uint32_t PltIndex = -1; | ||
| 73 | uint32_t GlobalDynIndex = -1; | ||
| 74 | |||
| 75 | // This field is a index to the symbol's version definition. | ||
| 76 | uint32_t VerdefIndex = -1; | ||
| 77 | |||
| 78 | // Version definition index. | ||
| 79 | uint16_t VersionId; | ||
| 80 | |||
| 50 | // Symbol binding. This is not overwritten by replaceSymbol to track | 81 | // Symbol binding. This is not overwritten by replaceSymbol to track |
| 51 | // changes during resolution. In particular: | 82 | // changes during resolution. In particular: |
| 52 | // - An undefined weak is still weak when it resolves to a shared library. | 83 | // - An undefined weak is still weak when it resolves to a shared library. |
| ... | @@ -54,8 +85,11 @@ public: | ... | @@ -54,8 +85,11 @@ public: |
| 54 | // remember it is weak. | 85 | // remember it is weak. |
| 55 | uint8_t Binding; | 86 | uint8_t Binding; |
| 56 | 87 | ||
| 57 | // Version definition index. | 88 | // The following fields have the same meaning as the ELF symbol attributes. |
| 58 | uint16_t VersionId; | 89 | uint8_t Type; // symbol type |
| 90 | uint8_t StOther; // st_other field value | ||
| 91 | |||
| 92 | const uint8_t SymbolKind; | ||
| 59 | 93 | ||
| 60 | // Symbol visibility. This is the computed minimum visibility of all | 94 | // Symbol visibility. This is the computed minimum visibility of all |
| 61 | // observed non-DSO symbols. | 95 | // observed non-DSO symbols. |
| ... | @@ -81,12 +115,6 @@ public: | ... | @@ -81,12 +115,6 @@ public: |
| 81 | // True if this symbol is specified by --trace-symbol option. | 115 | // True if this symbol is specified by --trace-symbol option. |
| 82 | unsigned Traced : 1; | 116 | unsigned Traced : 1; |
| 83 | 117 | ||
| 84 | // This symbol version was found in a version script. | ||
| 85 | unsigned InVersionScript : 1; | ||
| 86 | |||
| 87 | // The file from which this symbol was created. | ||
| 88 | InputFile *File; | ||
| 89 | |||
| 90 | bool includeInDynsym() const; | 118 | bool includeInDynsym() const; |
| 91 | uint8_t computeBinding() const; | 119 | uint8_t computeBinding() const; |
| 92 | bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; } | 120 | bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; } |
| ... | @@ -100,15 +128,15 @@ public: | ... | @@ -100,15 +128,15 @@ public: |
| 100 | return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind; | 128 | return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind; |
| 101 | } | 129 | } |
| 102 | 130 | ||
| 103 | // True is this is an undefined weak symbol. This only works once | 131 | // True if this is an undefined weak symbol. |
| 104 | // all input files have been added. | 132 | bool isUndefWeak() const { return isWeak() && isUndefined(); } |
| 105 | bool isUndefWeak() const { | 133 | |
| 106 | // See comment on Lazy the details. | 134 | StringRef getName() const { |
| 107 | return isWeak() && (isUndefined() || isLazy()); | 135 | if (NameSize == (uint32_t)-1) |
| 136 | NameSize = strlen(NameData); | ||
| 137 | return {NameData, NameSize}; | ||
| 108 | } | 138 | } |
| 109 | 139 | ||
| 110 | StringRef getName() const { return Name; } | ||
| 111 | uint8_t getVisibility() const { return StOther & 0x3; } | ||
| 112 | void parseSymbolVersion(); | 140 | void parseSymbolVersion(); |
| 113 | 141 | ||
| 114 | bool isInGot() const { return GotIndex != -1U; } | 142 | bool isInGot() const { return GotIndex != -1U; } |
| ... | @@ -121,34 +149,22 @@ public: | ... | @@ -121,34 +149,22 @@ public: |
| 121 | uint64_t getGotPltOffset() const; | 149 | uint64_t getGotPltOffset() const; |
| 122 | uint64_t getGotPltVA() const; | 150 | uint64_t getGotPltVA() const; |
| 123 | uint64_t getPltVA() const; | 151 | uint64_t getPltVA() const; |
| 152 | uint64_t getPltOffset() const; | ||
| 124 | uint64_t getSize() const; | 153 | uint64_t getSize() const; |
| 125 | OutputSection *getOutputSection() const; | 154 | OutputSection *getOutputSection() const; |
| 126 | 155 | ||
| 127 | uint32_t DynsymIndex = 0; | ||
| 128 | uint32_t GotIndex = -1; | ||
| 129 | uint32_t GotPltIndex = -1; | ||
| 130 | uint32_t PltIndex = -1; | ||
| 131 | uint32_t GlobalDynIndex = -1; | ||
| 132 | |||
| 133 | protected: | 156 | protected: |
| 134 | Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding, | 157 | Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding, |
| 135 | uint8_t StOther, uint8_t Type) | 158 | uint8_t StOther, uint8_t Type) |
| 136 | : Binding(Binding), File(File), SymbolKind(K), NeedsPltAddr(false), | 159 | : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding), |
| 137 | IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), | 160 | Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false), |
| 138 | IsInIgot(false), IsPreemptible(false), Used(!Config->GcSections), | 161 | IsInIplt(false), IsInIgot(false), IsPreemptible(false), |
| 139 | Type(Type), StOther(StOther), Name(Name) {} | 162 | Used(!Config->GcSections), NeedsTocRestore(false) {} |
| 140 | |||
| 141 | const unsigned SymbolKind : 8; | ||
| 142 | 163 | ||
| 143 | public: | 164 | public: |
| 144 | // True the symbol should point to its PLT entry. | 165 | // True the symbol should point to its PLT entry. |
| 145 | // For SharedSymbol only. | 166 | // For SharedSymbol only. |
| 146 | unsigned NeedsPltAddr : 1; | 167 | unsigned NeedsPltAddr : 1; |
| 147 | // True if this symbol has an entry in the global part of MIPS GOT. | ||
| 148 | unsigned IsInGlobalMipsGot : 1; | ||
| 149 | |||
| 150 | // True if this symbol is referenced by 32-bit GOT relocations. | ||
| 151 | unsigned Is32BitMipsGot : 1; | ||
| 152 | 168 | ||
| 153 | // True if this symbol is in the Iplt sub-section of the Plt. | 169 | // True if this symbol is in the Iplt sub-section of the Plt. |
| 154 | unsigned IsInIplt : 1; | 170 | unsigned IsInIplt : 1; |
| ... | @@ -156,14 +172,15 @@ public: | ... | @@ -156,14 +172,15 @@ public: |
| 156 | // True if this symbol is in the Igot sub-section of the .got.plt or .got. | 172 | // True if this symbol is in the Igot sub-section of the .got.plt or .got. |
| 157 | unsigned IsInIgot : 1; | 173 | unsigned IsInIgot : 1; |
| 158 | 174 | ||
| 175 | // True if this symbol is preemptible at load time. | ||
| 159 | unsigned IsPreemptible : 1; | 176 | unsigned IsPreemptible : 1; |
| 160 | 177 | ||
| 161 | // True if an undefined or shared symbol is used from a live section. | 178 | // True if an undefined or shared symbol is used from a live section. |
| 162 | unsigned Used : 1; | 179 | unsigned Used : 1; |
| 163 | 180 | ||
| 164 | // The following fields have the same meaning as the ELF symbol attributes. | 181 | // True if a call to this symbol needs to be followed by a restore of the |
| 165 | uint8_t Type; // symbol type | 182 | // PPC64 toc pointer. |
| 166 | uint8_t StOther; // st_other field value | 183 | unsigned NeedsTocRestore : 1; |
| 167 | 184 | ||
| 168 | // The Type field may also have this value. It means that we have not yet seen | 185 | // The Type field may also have this value. It means that we have not yet seen |
| 169 | // a non-Lazy symbol with this name, so we don't know what its type is. The | 186 | // a non-Lazy symbol with this name, so we don't know what its type is. The |
| ... | @@ -178,9 +195,6 @@ public: | ... | @@ -178,9 +195,6 @@ public: |
| 178 | bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; } | 195 | bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; } |
| 179 | bool isObject() const { return Type == llvm::ELF::STT_OBJECT; } | 196 | bool isObject() const { return Type == llvm::ELF::STT_OBJECT; } |
| 180 | bool isFile() const { return Type == llvm::ELF::STT_FILE; } | 197 | bool isFile() const { return Type == llvm::ELF::STT_FILE; } |
| 181 | |||
| 182 | protected: | ||
| 183 | StringRefZ Name; | ||
| 184 | }; | 198 | }; |
| 185 | 199 | ||
| 186 | // Represents a symbol that is defined in the current output file. | 200 | // Represents a symbol that is defined in the current output file. |
| ... | @@ -214,8 +228,9 @@ public: | ... | @@ -214,8 +228,9 @@ public: |
| 214 | SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding, | 228 | SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding, |
| 215 | uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size, | 229 | uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size, |
| 216 | uint32_t Alignment, uint32_t VerdefIndex) | 230 | uint32_t Alignment, uint32_t VerdefIndex) |
| 217 | : Symbol(SharedKind, &File, Name, Binding, StOther, Type), Value(Value), | 231 | : Symbol(SharedKind, &File, Name, Binding, StOther, Type), |
| 218 | Size(Size), VerdefIndex(VerdefIndex), Alignment(Alignment) { | 232 | Alignment(Alignment), Value(Value), Size(Size) { |
| 233 | this->VerdefIndex = VerdefIndex; | ||
| 219 | // GNU ifunc is a mechanism to allow user-supplied functions to | 234 | // GNU ifunc is a mechanism to allow user-supplied functions to |
| 220 | // resolve PLT slot values at load-time. This is contrary to the | 235 | // resolve PLT slot values at load-time. This is contrary to the |
| 221 | // regular symbol resolution scheme in which symbols are resolved just | 236 | // regular symbol resolution scheme in which symbols are resolved just |
| ... | @@ -240,54 +255,36 @@ public: | ... | @@ -240,54 +255,36 @@ public: |
| 240 | return *cast<SharedFile<ELFT>>(File); | 255 | return *cast<SharedFile<ELFT>>(File); |
| 241 | } | 256 | } |
| 242 | 257 | ||
| 243 | // If not null, there is a copy relocation to this section. | 258 | uint32_t Alignment; |
| 244 | InputSection *CopyRelSec = nullptr; | ||
| 245 | 259 | ||
| 246 | uint64_t Value; // st_value | 260 | uint64_t Value; // st_value |
| 247 | uint64_t Size; // st_size | 261 | uint64_t Size; // st_size |
| 248 | |||
| 249 | // This field is a index to the symbol's version definition. | ||
| 250 | uint32_t VerdefIndex; | ||
| 251 | |||
| 252 | uint32_t Alignment; | ||
| 253 | }; | 262 | }; |
| 254 | 263 | ||
| 255 | // This represents a symbol that is not yet in the link, but we know where to | 264 | // LazyArchive and LazyObject represent a symbols that is not yet in the link, |
| 256 | // find it if needed. If the resolver finds both Undefined and Lazy for the same | 265 | // but we know where to find it if needed. If the resolver finds both Undefined |
| 257 | // name, it will ask the Lazy to load a file. | 266 | // and Lazy for the same name, it will ask the Lazy to load a file. |
| 258 | // | 267 | // |
| 259 | // A special complication is the handling of weak undefined symbols. They should | 268 | // A special complication is the handling of weak undefined symbols. They should |
| 260 | // not load a file, but we have to remember we have seen both the weak undefined | 269 | // not load a file, but we have to remember we have seen both the weak undefined |
| 261 | // and the lazy. We represent that with a lazy symbol with a weak binding. This | 270 | // and the lazy. We represent that with a lazy symbol with a weak binding. This |
| 262 | // means that code looking for undefined symbols normally also has to take lazy | 271 | // means that code looking for undefined symbols normally also has to take lazy |
| 263 | // symbols into consideration. | 272 | // symbols into consideration. |
| 264 | class Lazy : public Symbol { | ||
| 265 | public: | ||
| 266 | static bool classof(const Symbol *S) { return S->isLazy(); } | ||
| 267 | |||
| 268 | // Returns an object file for this symbol, or a nullptr if the file | ||
| 269 | // was already returned. | ||
| 270 | InputFile *fetch(); | ||
| 271 | |||
| 272 | protected: | ||
| 273 | Lazy(Kind K, InputFile &File, StringRef Name, uint8_t Type) | ||
| 274 | : Symbol(K, &File, Name, llvm::ELF::STB_GLOBAL, llvm::ELF::STV_DEFAULT, | ||
| 275 | Type) {} | ||
| 276 | }; | ||
| 277 | 273 | ||
| 278 | // This class represents a symbol defined in an archive file. It is | 274 | // This class represents a symbol defined in an archive file. It is |
| 279 | // created from an archive file header, and it knows how to load an | 275 | // created from an archive file header, and it knows how to load an |
| 280 | // object file from an archive to replace itself with a defined | 276 | // object file from an archive to replace itself with a defined |
| 281 | // symbol. | 277 | // symbol. |
| 282 | class LazyArchive : public Lazy { | 278 | class LazyArchive : public Symbol { |
| 283 | public: | 279 | public: |
| 284 | LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S, | 280 | LazyArchive(InputFile &File, uint8_t Type, |
| 285 | uint8_t Type) | 281 | const llvm::object::Archive::Symbol S) |
| 286 | : Lazy(LazyArchiveKind, File, S.getName(), Type), Sym(S) {} | 282 | : Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL, |
| 283 | llvm::ELF::STV_DEFAULT, Type), | ||
| 284 | Sym(S) {} | ||
| 287 | 285 | ||
| 288 | static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; } | 286 | static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; } |
| 289 | 287 | ||
| 290 | ArchiveFile &getFile(); | ||
| 291 | InputFile *fetch(); | 288 | InputFile *fetch(); |
| 292 | 289 | ||
| 293 | private: | 290 | private: |
| ... | @@ -296,15 +293,13 @@ private: | ... | @@ -296,15 +293,13 @@ private: |
| 296 | 293 | ||
| 297 | // LazyObject symbols represents symbols in object files between | 294 | // LazyObject symbols represents symbols in object files between |
| 298 | // --start-lib and --end-lib options. | 295 | // --start-lib and --end-lib options. |
| 299 | class LazyObject : public Lazy { | 296 | class LazyObject : public Symbol { |
| 300 | public: | 297 | public: |
| 301 | LazyObject(InputFile &File, StringRef Name, uint8_t Type) | 298 | LazyObject(InputFile &File, uint8_t Type, StringRef Name) |
| 302 | : Lazy(LazyObjectKind, File, Name, Type) {} | 299 | : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL, |
| 300 | llvm::ELF::STV_DEFAULT, Type) {} | ||
| 303 | 301 | ||
| 304 | static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; } | 302 | static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; } |
| 305 | |||
| 306 | LazyObjFile &getFile(); | ||
| 307 | InputFile *fetch(); | ||
| 308 | }; | 303 | }; |
| 309 | 304 | ||
| 310 | // Some linker-generated symbols need to be created as | 305 | // Some linker-generated symbols need to be created as |
| ... | @@ -334,6 +329,9 @@ struct ElfSym { | ... | @@ -334,6 +329,9 @@ struct ElfSym { |
| 334 | static Defined *MipsGp; | 329 | static Defined *MipsGp; |
| 335 | static Defined *MipsGpDisp; | 330 | static Defined *MipsGpDisp; |
| 336 | static Defined *MipsLocalGp; | 331 | static Defined *MipsLocalGp; |
| 332 | |||
| 333 | // __rela_iplt_end or __rel_iplt_end | ||
| 334 | static Defined *RelaIpltEnd; | ||
| 337 | }; | 335 | }; |
| 338 | 336 | ||
| 339 | // A buffer class that is large enough to hold any Symbol-derived | 337 | // A buffer class that is large enough to hold any Symbol-derived |
| ... | @@ -351,6 +349,8 @@ void printTraceSymbol(Symbol *Sym); | ... | @@ -351,6 +349,8 @@ void printTraceSymbol(Symbol *Sym); |
| 351 | 349 | ||
| 352 | template <typename T, typename... ArgT> | 350 | template <typename T, typename... ArgT> |
| 353 | void replaceSymbol(Symbol *S, ArgT &&... Arg) { | 351 | void replaceSymbol(Symbol *S, ArgT &&... Arg) { |
| 352 | static_assert(std::is_trivially_destructible<T>(), | ||
| 353 | "Symbol types must be trivially destructible"); | ||
| 354 | static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small"); | 354 | static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small"); |
| 355 | static_assert(alignof(T) <= alignof(SymbolUnion), | 355 | static_assert(alignof(T) <= alignof(SymbolUnion), |
| 356 | "SymbolUnion not aligned enough"); | 356 | "SymbolUnion not aligned enough"); |
| ... | @@ -367,13 +367,14 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) { | ... | @@ -367,13 +367,14 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) { |
| 367 | S->ExportDynamic = Sym.ExportDynamic; | 367 | S->ExportDynamic = Sym.ExportDynamic; |
| 368 | S->CanInline = Sym.CanInline; | 368 | S->CanInline = Sym.CanInline; |
| 369 | S->Traced = Sym.Traced; | 369 | S->Traced = Sym.Traced; |
| 370 | S->InVersionScript = Sym.InVersionScript; | ||
| 371 | 370 | ||
| 372 | // Print out a log message if --trace-symbol was specified. | 371 | // Print out a log message if --trace-symbol was specified. |
| 373 | // This is for debugging. | 372 | // This is for debugging. |
| 374 | if (S->Traced) | 373 | if (S->Traced) |
| 375 | printTraceSymbol(S); | 374 | printTraceSymbol(S); |
| 376 | } | 375 | } |
| 376 | |||
| 377 | void warnUnorderableSymbol(const Symbol *Sym); | ||
| 377 | } // namespace elf | 378 | } // namespace elf |
| 378 | 379 | ||
| 379 | std::string toString(const elf::Symbol &B); | 380 | std::string toString(const elf::Symbol &B); |
deps/lld/ELF/SyntheticSections.cpp+990-541| ... | @@ -20,15 +20,16 @@ | ... | @@ -20,15 +20,16 @@ |
| 20 | #include "InputFiles.h" | 20 | #include "InputFiles.h" |
| 21 | #include "LinkerScript.h" | 21 | #include "LinkerScript.h" |
| 22 | #include "OutputSections.h" | 22 | #include "OutputSections.h" |
| 23 | #include "Strings.h" | ||
| 24 | #include "SymbolTable.h" | 23 | #include "SymbolTable.h" |
| 25 | #include "Symbols.h" | 24 | #include "Symbols.h" |
| 26 | #include "Target.h" | 25 | #include "Target.h" |
| 27 | #include "Writer.h" | 26 | #include "Writer.h" |
| 28 | #include "lld/Common/ErrorHandler.h" | 27 | #include "lld/Common/ErrorHandler.h" |
| 29 | #include "lld/Common/Memory.h" | 28 | #include "lld/Common/Memory.h" |
| 29 | #include "lld/Common/Strings.h" | ||
| 30 | #include "lld/Common/Threads.h" | 30 | #include "lld/Common/Threads.h" |
| 31 | #include "lld/Common/Version.h" | 31 | #include "lld/Common/Version.h" |
| 32 | #include "llvm/ADT/SetOperations.h" | ||
| 32 | #include "llvm/BinaryFormat/Dwarf.h" | 33 | #include "llvm/BinaryFormat/Dwarf.h" |
| 33 | #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" | 34 | #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" |
| 34 | #include "llvm/Object/Decompressor.h" | 35 | #include "llvm/Object/Decompressor.h" |
| ... | @@ -47,27 +48,20 @@ using namespace llvm::dwarf; | ... | @@ -47,27 +48,20 @@ using namespace llvm::dwarf; |
| 47 | using namespace llvm::ELF; | 48 | using namespace llvm::ELF; |
| 48 | using namespace llvm::object; | 49 | using namespace llvm::object; |
| 49 | using namespace llvm::support; | 50 | using namespace llvm::support; |
| 50 | using namespace llvm::support::endian; | ||
| 51 | 51 | ||
| 52 | using namespace lld; | 52 | using namespace lld; |
| 53 | using namespace lld::elf; | 53 | using namespace lld::elf; |
| 54 | 54 | ||
| 55 | constexpr size_t MergeNoTailSection::NumShards; | 55 | using llvm::support::endian::read32le; |
| 56 | 56 | using llvm::support::endian::write32le; | |
| 57 | static void write32(void *Buf, uint32_t Val) { | 57 | using llvm::support::endian::write64le; |
| 58 | endian::write32(Buf, Val, Config->Endianness); | ||
| 59 | } | ||
| 60 | 58 | ||
| 61 | uint64_t SyntheticSection::getVA() const { | 59 | constexpr size_t MergeNoTailSection::NumShards; |
| 62 | if (OutputSection *Sec = getParent()) | ||
| 63 | return Sec->Addr + OutSecOff; | ||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | 60 | ||
| 67 | // Returns an LLD version string. | 61 | // Returns an LLD version string. |
| 68 | static ArrayRef<uint8_t> getVersion() { | 62 | static ArrayRef<uint8_t> getVersion() { |
| 69 | // Check LLD_VERSION first for ease of testing. | 63 | // Check LLD_VERSION first for ease of testing. |
| 70 | // You can get consitent output by using the environment variable. | 64 | // You can get consistent output by using the environment variable. |
| 71 | // This is only for testing. | 65 | // This is only for testing. |
| 72 | StringRef S = getenv("LLD_VERSION"); | 66 | StringRef S = getenv("LLD_VERSION"); |
| 73 | if (S.empty()) | 67 | if (S.empty()) |
| ... | @@ -192,8 +186,6 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() { | ... | @@ -192,8 +186,6 @@ MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() { |
| 192 | 186 | ||
| 193 | auto *Opt = reinterpret_cast<const Elf_Mips_Options *>(D.data()); | 187 | auto *Opt = reinterpret_cast<const Elf_Mips_Options *>(D.data()); |
| 194 | if (Opt->kind == ODK_REGINFO) { | 188 | if (Opt->kind == ODK_REGINFO) { |
| 195 | if (Config->Relocatable && Opt->getRegInfo().ri_gp_value) | ||
| 196 | error(Filename + ": unsupported non-zero ri_gp_value"); | ||
| 197 | Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask; | 189 | Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask; |
| 198 | Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value; | 190 | Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value; |
| 199 | break; | 191 | break; |
| ... | @@ -244,10 +236,8 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() { | ... | @@ -244,10 +236,8 @@ MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() { |
| 244 | error(toString(Sec->File) + ": invalid size of .reginfo section"); | 236 | error(toString(Sec->File) + ": invalid size of .reginfo section"); |
| 245 | return nullptr; | 237 | return nullptr; |
| 246 | } | 238 | } |
| 247 | auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data()); | ||
| 248 | if (Config->Relocatable && R->ri_gp_value) | ||
| 249 | error(toString(Sec->File) + ": unsupported non-zero ri_gp_value"); | ||
| 250 | 239 | ||
| 240 | auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data()); | ||
| 251 | Reginfo.ri_gprmask |= R->ri_gprmask; | 241 | Reginfo.ri_gprmask |= R->ri_gprmask; |
| 252 | Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value; | 242 | Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value; |
| 253 | }; | 243 | }; |
| ... | @@ -266,8 +256,8 @@ InputSection *elf::createInterpSection() { | ... | @@ -266,8 +256,8 @@ InputSection *elf::createInterpSection() { |
| 266 | return Sec; | 256 | return Sec; |
| 267 | } | 257 | } |
| 268 | 258 | ||
| 269 | Symbol *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, | 259 | Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, |
| 270 | uint64_t Size, InputSectionBase &Section) { | 260 | uint64_t Size, InputSectionBase &Section) { |
| 271 | auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type, | 261 | auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type, |
| 272 | Value, Size, &Section); | 262 | Value, Size, &Section); |
| 273 | if (InX::SymTab) | 263 | if (InX::SymTab) |
| ... | @@ -338,8 +328,6 @@ void BuildIdSection::computeHash( | ... | @@ -338,8 +328,6 @@ void BuildIdSection::computeHash( |
| 338 | BssSection::BssSection(StringRef Name, uint64_t Size, uint32_t Alignment) | 328 | BssSection::BssSection(StringRef Name, uint64_t Size, uint32_t Alignment) |
| 339 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Name) { | 329 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Name) { |
| 340 | this->Bss = true; | 330 | this->Bss = true; |
| 341 | if (OutputSection *Sec = getParent()) | ||
| 342 | Sec->Alignment = std::max(Sec->Alignment, Alignment); | ||
| 343 | this->Size = Size; | 331 | this->Size = Size; |
| 344 | } | 332 | } |
| 345 | 333 | ||
| ... | @@ -347,7 +335,7 @@ void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) { | ... | @@ -347,7 +335,7 @@ void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) { |
| 347 | switch (Config->BuildId) { | 335 | switch (Config->BuildId) { |
| 348 | case BuildIdKind::Fast: | 336 | case BuildIdKind::Fast: |
| 349 | computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) { | 337 | computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) { |
| 350 | write64le(Dest, xxHash64(toStringRef(Arr))); | 338 | write64le(Dest, xxHash64(Arr)); |
| 351 | }); | 339 | }); |
| 352 | break; | 340 | break; |
| 353 | case BuildIdKind::Md5: | 341 | case BuildIdKind::Md5: |
| ... | @@ -380,15 +368,11 @@ EhFrameSection::EhFrameSection() | ... | @@ -380,15 +368,11 @@ EhFrameSection::EhFrameSection() |
| 380 | // and where their relocations point to. | 368 | // and where their relocations point to. |
| 381 | template <class ELFT, class RelTy> | 369 | template <class ELFT, class RelTy> |
| 382 | CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, ArrayRef<RelTy> Rels) { | 370 | CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, ArrayRef<RelTy> Rels) { |
| 383 | auto *Sec = cast<EhInputSection>(Cie.Sec); | ||
| 384 | if (read32(Cie.data().data() + 4, Config->Endianness) != 0) | ||
| 385 | fatal(toString(Sec) + ": CIE expected at beginning of .eh_frame"); | ||
| 386 | |||
| 387 | Symbol *Personality = nullptr; | 371 | Symbol *Personality = nullptr; |
| 388 | unsigned FirstRelI = Cie.FirstRelocation; | 372 | unsigned FirstRelI = Cie.FirstRelocation; |
| 389 | if (FirstRelI != (unsigned)-1) | 373 | if (FirstRelI != (unsigned)-1) |
| 390 | Personality = | 374 | Personality = |
| 391 | &Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]); | 375 | &Cie.Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]); |
| 392 | 376 | ||
| 393 | // Search for an existing CIE by CIE contents/relocation target pair. | 377 | // Search for an existing CIE by CIE contents/relocation target pair. |
| 394 | CieRecord *&Rec = CieMap[{Cie.data(), Personality}]; | 378 | CieRecord *&Rec = CieMap[{Cie.data(), Personality}]; |
| ... | @@ -433,14 +417,14 @@ bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) { | ... | @@ -433,14 +417,14 @@ bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) { |
| 433 | // one and associates FDEs to the CIE. | 417 | // one and associates FDEs to the CIE. |
| 434 | template <class ELFT, class RelTy> | 418 | template <class ELFT, class RelTy> |
| 435 | void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) { | 419 | void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) { |
| 436 | DenseMap<size_t, CieRecord *> OffsetToCie; | 420 | OffsetToCie.clear(); |
| 437 | for (EhSectionPiece &Piece : Sec->Pieces) { | 421 | for (EhSectionPiece &Piece : Sec->Pieces) { |
| 438 | // The empty record is the end marker. | 422 | // The empty record is the end marker. |
| 439 | if (Piece.Size == 4) | 423 | if (Piece.Size == 4) |
| 440 | return; | 424 | return; |
| 441 | 425 | ||
| 442 | size_t Offset = Piece.InputOff; | 426 | size_t Offset = Piece.InputOff; |
| 443 | uint32_t ID = read32(Piece.data().data() + 4, Config->Endianness); | 427 | uint32_t ID = read32(Piece.data().data() + 4); |
| 444 | if (ID == 0) { | 428 | if (ID == 0) { |
| 445 | OffsetToCie[Offset] = addCie<ELFT>(Piece, Rels); | 429 | OffsetToCie[Offset] = addCie<ELFT>(Piece, Rels); |
| 446 | continue; | 430 | continue; |
| ... | @@ -468,10 +452,6 @@ template <class ELFT> void EhFrameSection::addSection(InputSectionBase *C) { | ... | @@ -468,10 +452,6 @@ template <class ELFT> void EhFrameSection::addSection(InputSectionBase *C) { |
| 468 | for (auto *DS : Sec->DependentSections) | 452 | for (auto *DS : Sec->DependentSections) |
| 469 | DependentSections.push_back(DS); | 453 | DependentSections.push_back(DS); |
| 470 | 454 | ||
| 471 | // .eh_frame is a sequence of CIE or FDE records. This function | ||
| 472 | // splits it into pieces so that we can call | ||
| 473 | // SplitInputSection::getSectionPiece on the section. | ||
| 474 | Sec->split<ELFT>(); | ||
| 475 | if (Sec->Pieces.empty()) | 455 | if (Sec->Pieces.empty()) |
| 476 | return; | 456 | return; |
| 477 | 457 | ||
| ... | @@ -494,9 +474,7 @@ static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) { | ... | @@ -494,9 +474,7 @@ static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) { |
| 494 | } | 474 | } |
| 495 | 475 | ||
| 496 | void EhFrameSection::finalizeContents() { | 476 | void EhFrameSection::finalizeContents() { |
| 497 | if (this->Size) | 477 | assert(!this->Size); // Not finalized. |
| 498 | return; // Already finalized. | ||
| 499 | |||
| 500 | size_t Off = 0; | 478 | size_t Off = 0; |
| 501 | for (CieRecord *Rec : CieRecords) { | 479 | for (CieRecord *Rec : CieRecords) { |
| 502 | Rec->Cie->OutputOff = Off; | 480 | Rec->Cie->OutputOff = Off; |
| ... | @@ -509,10 +487,10 @@ void EhFrameSection::finalizeContents() { | ... | @@ -509,10 +487,10 @@ void EhFrameSection::finalizeContents() { |
| 509 | } | 487 | } |
| 510 | 488 | ||
| 511 | // The LSB standard does not allow a .eh_frame section with zero | 489 | // The LSB standard does not allow a .eh_frame section with zero |
| 512 | // Call Frame Information records. Therefore add a CIE record length | 490 | // Call Frame Information records. glibc unwind-dw2-fde.c |
| 513 | // 0 as a terminator if this .eh_frame section is empty. | 491 | // classify_object_over_fdes expects there is a CIE record length 0 as a |
| 514 | if (Off == 0) | 492 | // terminator. Thus we add one unconditionally. |
| 515 | Off = 4; | 493 | Off += 4; |
| 516 | 494 | ||
| 517 | this->Size = Off; | 495 | this->Size = Off; |
| 518 | } | 496 | } |
| ... | @@ -524,25 +502,47 @@ std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const { | ... | @@ -524,25 +502,47 @@ std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const { |
| 524 | uint8_t *Buf = getParent()->Loc + OutSecOff; | 502 | uint8_t *Buf = getParent()->Loc + OutSecOff; |
| 525 | std::vector<FdeData> Ret; | 503 | std::vector<FdeData> Ret; |
| 526 | 504 | ||
| 505 | uint64_t VA = InX::EhFrameHdr->getVA(); | ||
| 527 | for (CieRecord *Rec : CieRecords) { | 506 | for (CieRecord *Rec : CieRecords) { |
| 528 | uint8_t Enc = getFdeEncoding(Rec->Cie); | 507 | uint8_t Enc = getFdeEncoding(Rec->Cie); |
| 529 | for (EhSectionPiece *Fde : Rec->Fdes) { | 508 | for (EhSectionPiece *Fde : Rec->Fdes) { |
| 530 | uint32_t Pc = getFdePc(Buf, Fde->OutputOff, Enc); | 509 | uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc); |
| 531 | uint32_t FdeVA = getParent()->Addr + Fde->OutputOff; | 510 | uint64_t FdeVA = getParent()->Addr + Fde->OutputOff; |
| 532 | Ret.push_back({Pc, FdeVA}); | 511 | if (!isInt<32>(Pc - VA)) |
| 512 | fatal(toString(Fde->Sec) + ": PC offset is too large: 0x" + | ||
| 513 | Twine::utohexstr(Pc - VA)); | ||
| 514 | Ret.push_back({uint32_t(Pc - VA), uint32_t(FdeVA - VA)}); | ||
| 533 | } | 515 | } |
| 534 | } | 516 | } |
| 517 | |||
| 518 | // Sort the FDE list by their PC and uniqueify. Usually there is only | ||
| 519 | // one FDE for a PC (i.e. function), but if ICF merges two functions | ||
| 520 | // into one, there can be more than one FDEs pointing to the address. | ||
| 521 | auto Less = [](const FdeData &A, const FdeData &B) { | ||
| 522 | return A.PcRel < B.PcRel; | ||
| 523 | }; | ||
| 524 | std::stable_sort(Ret.begin(), Ret.end(), Less); | ||
| 525 | auto Eq = [](const FdeData &A, const FdeData &B) { | ||
| 526 | return A.PcRel == B.PcRel; | ||
| 527 | }; | ||
| 528 | Ret.erase(std::unique(Ret.begin(), Ret.end(), Eq), Ret.end()); | ||
| 529 | |||
| 535 | return Ret; | 530 | return Ret; |
| 536 | } | 531 | } |
| 537 | 532 | ||
| 538 | static uint64_t readFdeAddr(uint8_t *Buf, int Size) { | 533 | static uint64_t readFdeAddr(uint8_t *Buf, int Size) { |
| 539 | switch (Size) { | 534 | switch (Size) { |
| 540 | case DW_EH_PE_udata2: | 535 | case DW_EH_PE_udata2: |
| 541 | return read16(Buf, Config->Endianness); | 536 | return read16(Buf); |
| 537 | case DW_EH_PE_sdata2: | ||
| 538 | return (int16_t)read16(Buf); | ||
| 542 | case DW_EH_PE_udata4: | 539 | case DW_EH_PE_udata4: |
| 543 | return read32(Buf, Config->Endianness); | 540 | return read32(Buf); |
| 541 | case DW_EH_PE_sdata4: | ||
| 542 | return (int32_t)read32(Buf); | ||
| 544 | case DW_EH_PE_udata8: | 543 | case DW_EH_PE_udata8: |
| 545 | return read64(Buf, Config->Endianness); | 544 | case DW_EH_PE_sdata8: |
| 545 | return read64(Buf); | ||
| 546 | case DW_EH_PE_absptr: | 546 | case DW_EH_PE_absptr: |
| 547 | return readUint(Buf); | 547 | return readUint(Buf); |
| 548 | } | 548 | } |
| ... | @@ -556,7 +556,7 @@ uint64_t EhFrameSection::getFdePc(uint8_t *Buf, size_t FdeOff, | ... | @@ -556,7 +556,7 @@ uint64_t EhFrameSection::getFdePc(uint8_t *Buf, size_t FdeOff, |
| 556 | // The starting address to which this FDE applies is | 556 | // The starting address to which this FDE applies is |
| 557 | // stored at FDE + 8 byte. | 557 | // stored at FDE + 8 byte. |
| 558 | size_t Off = FdeOff + 8; | 558 | size_t Off = FdeOff + 8; |
| 559 | uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0x7); | 559 | uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0xf); |
| 560 | if ((Enc & 0x70) == DW_EH_PE_absptr) | 560 | if ((Enc & 0x70) == DW_EH_PE_absptr) |
| 561 | return Addr; | 561 | return Addr; |
| 562 | if ((Enc & 0x70) == DW_EH_PE_pcrel) | 562 | if ((Enc & 0x70) == DW_EH_PE_pcrel) |
| ... | @@ -589,7 +589,15 @@ void EhFrameSection::writeTo(uint8_t *Buf) { | ... | @@ -589,7 +589,15 @@ void EhFrameSection::writeTo(uint8_t *Buf) { |
| 589 | 589 | ||
| 590 | GotSection::GotSection() | 590 | GotSection::GotSection() |
| 591 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, | 591 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, |
| 592 | Target->GotEntrySize, ".got") {} | 592 | Target->GotEntrySize, ".got") { |
| 593 | // PPC64 saves the ElfSym::GlobalOffsetTable .TOC. as the first entry in the | ||
| 594 | // .got. If there are no references to .TOC. in the symbol table, | ||
| 595 | // ElfSym::GlobalOffsetTable will not be defined and we won't need to save | ||
| 596 | // .TOC. in the .got. When it is defined, we increase NumEntries by the number | ||
| 597 | // of entries used to emit ElfSym::GlobalOffsetTable. | ||
| 598 | if (ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt) | ||
| 599 | NumEntries += Target->GotHeaderEntriesNum; | ||
| 600 | } | ||
| 593 | 601 | ||
| 594 | void GotSection::addEntry(Symbol &Sym) { | 602 | void GotSection::addEntry(Symbol &Sym) { |
| 595 | Sym.GotIndex = NumEntries; | 603 | Sym.GotIndex = NumEntries; |
| ... | @@ -623,196 +631,383 @@ uint64_t GotSection::getGlobalDynOffset(const Symbol &B) const { | ... | @@ -623,196 +631,383 @@ uint64_t GotSection::getGlobalDynOffset(const Symbol &B) const { |
| 623 | return B.GlobalDynIndex * Config->Wordsize; | 631 | return B.GlobalDynIndex * Config->Wordsize; |
| 624 | } | 632 | } |
| 625 | 633 | ||
| 626 | void GotSection::finalizeContents() { Size = NumEntries * Config->Wordsize; } | 634 | void GotSection::finalizeContents() { |
| 635 | Size = NumEntries * Config->Wordsize; | ||
| 636 | } | ||
| 627 | 637 | ||
| 628 | bool GotSection::empty() const { | 638 | bool GotSection::empty() const { |
| 629 | // We need to emit a GOT even if it's empty if there's a relocation that is | 639 | // We need to emit a GOT even if it's empty if there's a relocation that is |
| 630 | // relative to GOT(such as GOTOFFREL) or there's a symbol that points to a GOT | 640 | // relative to GOT(such as GOTOFFREL) or there's a symbol that points to a GOT |
| 631 | // (i.e. _GLOBAL_OFFSET_TABLE_). | 641 | // (i.e. _GLOBAL_OFFSET_TABLE_) that the target defines relative to the .got. |
| 632 | return NumEntries == 0 && !HasGotOffRel && !ElfSym::GlobalOffsetTable; | 642 | return NumEntries == 0 && !HasGotOffRel && |
| 643 | !(ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt); | ||
| 633 | } | 644 | } |
| 634 | 645 | ||
| 635 | void GotSection::writeTo(uint8_t *Buf) { | 646 | void GotSection::writeTo(uint8_t *Buf) { |
| 636 | // Buf points to the start of this section's buffer, | 647 | // Buf points to the start of this section's buffer, |
| 637 | // whereas InputSectionBase::relocateAlloc() expects its argument | 648 | // whereas InputSectionBase::relocateAlloc() expects its argument |
| 638 | // to point to the start of the output section. | 649 | // to point to the start of the output section. |
| 650 | Target->writeGotHeader(Buf); | ||
| 639 | relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + Size); | 651 | relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + Size); |
| 640 | } | 652 | } |
| 641 | 653 | ||
| 654 | static uint64_t getMipsPageAddr(uint64_t Addr) { | ||
| 655 | return (Addr + 0x8000) & ~0xffff; | ||
| 656 | } | ||
| 657 | |||
| 658 | static uint64_t getMipsPageCount(uint64_t Size) { | ||
| 659 | return (Size + 0xfffe) / 0xffff + 1; | ||
| 660 | } | ||
| 661 | |||
| 642 | MipsGotSection::MipsGotSection() | 662 | MipsGotSection::MipsGotSection() |
| 643 | : SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16, | 663 | : SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16, |
| 644 | ".got") {} | 664 | ".got") {} |
| 645 | 665 | ||
| 646 | void MipsGotSection::addEntry(Symbol &Sym, int64_t Addend, RelExpr Expr) { | 666 | void MipsGotSection::addEntry(InputFile &File, Symbol &Sym, int64_t Addend, |
| 647 | // For "true" local symbols which can be referenced from the same module | 667 | RelExpr Expr) { |
| 648 | // only compiler creates two instructions for address loading: | 668 | FileGot &G = getGot(File); |
| 649 | // | ||
| 650 | // lw $8, 0($gp) # R_MIPS_GOT16 | ||
| 651 | // addi $8, $8, 0 # R_MIPS_LO16 | ||
| 652 | // | ||
| 653 | // The first instruction loads high 16 bits of the symbol address while | ||
| 654 | // the second adds an offset. That allows to reduce number of required | ||
| 655 | // GOT entries because only one global offset table entry is necessary | ||
| 656 | // for every 64 KBytes of local data. So for local symbols we need to | ||
| 657 | // allocate number of GOT entries to hold all required "page" addresses. | ||
| 658 | // | ||
| 659 | // All global symbols (hidden and regular) considered by compiler uniformly. | ||
| 660 | // It always generates a single `lw` instruction and R_MIPS_GOT16 relocation | ||
| 661 | // to load address of the symbol. So for each such symbol we need to | ||
| 662 | // allocate dedicated GOT entry to store its address. | ||
| 663 | // | ||
| 664 | // If a symbol is preemptible we need help of dynamic linker to get its | ||
| 665 | // final address. The corresponding GOT entries are allocated in the | ||
| 666 | // "global" part of GOT. Entries for non preemptible global symbol allocated | ||
| 667 | // in the "local" part of GOT. | ||
| 668 | // | ||
| 669 | // See "Global Offset Table" in Chapter 5: | ||
| 670 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf | ||
| 671 | if (Expr == R_MIPS_GOT_LOCAL_PAGE) { | 669 | if (Expr == R_MIPS_GOT_LOCAL_PAGE) { |
| 672 | // At this point we do not know final symbol value so to reduce number | 670 | if (const OutputSection *OS = Sym.getOutputSection()) |
| 673 | // of allocated GOT entries do the following trick. Save all output | 671 | G.PagesMap.insert({OS, {}}); |
| 674 | // sections referenced by GOT relocations. Then later in the `finalize` | 672 | else |
| 675 | // method calculate number of "pages" required to cover all saved output | 673 | G.Local16.insert({{nullptr, getMipsPageAddr(Sym.getVA(Addend))}, 0}); |
| 676 | // section and allocate appropriate number of GOT entries. | 674 | } else if (Sym.isTls()) |
| 677 | PageIndexMap.insert({Sym.getOutputSection(), 0}); | 675 | G.Tls.insert({&Sym, 0}); |
| 678 | return; | 676 | else if (Sym.IsPreemptible && Expr == R_ABS) |
| 679 | } | 677 | G.Relocs.insert({&Sym, 0}); |
| 680 | if (Sym.isTls()) { | 678 | else if (Sym.IsPreemptible) |
| 681 | // GOT entries created for MIPS TLS relocations behave like | 679 | G.Global.insert({&Sym, 0}); |
| 682 | // almost GOT entries from other ABIs. They go to the end | 680 | else if (Expr == R_MIPS_GOT_OFF32) |
| 683 | // of the global offset table. | 681 | G.Local32.insert({{&Sym, Addend}, 0}); |
| 684 | Sym.GotIndex = TlsEntries.size(); | 682 | else |
| 685 | TlsEntries.push_back(&Sym); | 683 | G.Local16.insert({{&Sym, Addend}, 0}); |
| 686 | return; | ||
| 687 | } | ||
| 688 | auto AddEntry = [&](Symbol &S, uint64_t A, GotEntries &Items) { | ||
| 689 | if (S.isInGot() && !A) | ||
| 690 | return; | ||
| 691 | size_t NewIndex = Items.size(); | ||
| 692 | if (!EntryIndexMap.insert({{&S, A}, NewIndex}).second) | ||
| 693 | return; | ||
| 694 | Items.emplace_back(&S, A); | ||
| 695 | if (!A) | ||
| 696 | S.GotIndex = NewIndex; | ||
| 697 | }; | ||
| 698 | if (Sym.IsPreemptible) { | ||
| 699 | // Ignore addends for preemptible symbols. They got single GOT entry anyway. | ||
| 700 | AddEntry(Sym, 0, GlobalEntries); | ||
| 701 | Sym.IsInGlobalMipsGot = true; | ||
| 702 | } else if (Expr == R_MIPS_GOT_OFF32) { | ||
| 703 | AddEntry(Sym, Addend, LocalEntries32); | ||
| 704 | Sym.Is32BitMipsGot = true; | ||
| 705 | } else { | ||
| 706 | // Hold local GOT entries accessed via a 16-bit index separately. | ||
| 707 | // That allows to write them in the beginning of the GOT and keep | ||
| 708 | // their indexes as less as possible to escape relocation's overflow. | ||
| 709 | AddEntry(Sym, Addend, LocalEntries); | ||
| 710 | } | ||
| 711 | } | 684 | } |
| 712 | 685 | ||
| 713 | bool MipsGotSection::addDynTlsEntry(Symbol &Sym) { | 686 | void MipsGotSection::addDynTlsEntry(InputFile &File, Symbol &Sym) { |
| 714 | if (Sym.GlobalDynIndex != -1U) | 687 | getGot(File).DynTlsSymbols.insert({&Sym, 0}); |
| 715 | return false; | ||
| 716 | Sym.GlobalDynIndex = TlsEntries.size(); | ||
| 717 | // Global Dynamic TLS entries take two GOT slots. | ||
| 718 | TlsEntries.push_back(nullptr); | ||
| 719 | TlsEntries.push_back(&Sym); | ||
| 720 | return true; | ||
| 721 | } | 688 | } |
| 722 | 689 | ||
| 723 | // Reserves TLS entries for a TLS module ID and a TLS block offset. | 690 | void MipsGotSection::addTlsIndex(InputFile &File) { |
| 724 | // In total it takes two GOT slots. | 691 | getGot(File).DynTlsSymbols.insert({nullptr, 0}); |
| 725 | bool MipsGotSection::addTlsIndex() { | ||
| 726 | if (TlsIndexOff != uint32_t(-1)) | ||
| 727 | return false; | ||
| 728 | TlsIndexOff = TlsEntries.size() * Config->Wordsize; | ||
| 729 | TlsEntries.push_back(nullptr); | ||
| 730 | TlsEntries.push_back(nullptr); | ||
| 731 | return true; | ||
| 732 | } | 692 | } |
| 733 | 693 | ||
| 734 | static uint64_t getMipsPageAddr(uint64_t Addr) { | 694 | size_t MipsGotSection::FileGot::getEntriesNum() const { |
| 735 | return (Addr + 0x8000) & ~0xffff; | 695 | return getPageEntriesNum() + Local16.size() + Global.size() + Relocs.size() + |
| 696 | Tls.size() + DynTlsSymbols.size() * 2; | ||
| 736 | } | 697 | } |
| 737 | 698 | ||
| 738 | static uint64_t getMipsPageCount(uint64_t Size) { | 699 | size_t MipsGotSection::FileGot::getPageEntriesNum() const { |
| 739 | return (Size + 0xfffe) / 0xffff + 1; | 700 | size_t Num = 0; |
| 701 | for (const std::pair<const OutputSection *, FileGot::PageBlock> &P : PagesMap) | ||
| 702 | Num += P.second.Count; | ||
| 703 | return Num; | ||
| 740 | } | 704 | } |
| 741 | 705 | ||
| 742 | uint64_t MipsGotSection::getPageEntryOffset(const Symbol &B, | 706 | size_t MipsGotSection::FileGot::getIndexedEntriesNum() const { |
| 743 | int64_t Addend) const { | 707 | size_t Count = getPageEntriesNum() + Local16.size() + Global.size(); |
| 744 | const OutputSection *OutSec = B.getOutputSection(); | 708 | // If there are relocation-only entries in the GOT, TLS entries |
| 745 | uint64_t SecAddr = getMipsPageAddr(OutSec->Addr); | 709 | // are allocated after them. TLS entries should be addressable |
| 746 | uint64_t SymAddr = getMipsPageAddr(B.getVA(Addend)); | 710 | // by 16-bit index so count both reloc-only and TLS entries. |
| 747 | uint64_t Index = PageIndexMap.lookup(OutSec) + (SymAddr - SecAddr) / 0xffff; | 711 | if (!Tls.empty() || !DynTlsSymbols.empty()) |
| 748 | assert(Index < PageEntriesNum); | 712 | Count += Relocs.size() + Tls.size() + DynTlsSymbols.size() * 2; |
| 749 | return (HeaderEntriesNum + Index) * Config->Wordsize; | 713 | return Count; |
| 750 | } | 714 | } |
| 751 | 715 | ||
| 752 | uint64_t MipsGotSection::getSymEntryOffset(const Symbol &B, | 716 | MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &F) { |
| 753 | int64_t Addend) const { | 717 | if (!F.MipsGotIndex.hasValue()) { |
| 754 | // Calculate offset of the GOT entries block: TLS, global, local. | 718 | Gots.emplace_back(); |
| 755 | uint64_t Index = HeaderEntriesNum + PageEntriesNum; | 719 | Gots.back().File = &F; |
| 756 | if (B.isTls()) | 720 | F.MipsGotIndex = Gots.size() - 1; |
| 757 | Index += LocalEntries.size() + LocalEntries32.size() + GlobalEntries.size(); | 721 | } |
| 758 | else if (B.IsInGlobalMipsGot) | 722 | return Gots[*F.MipsGotIndex]; |
| 759 | Index += LocalEntries.size() + LocalEntries32.size(); | 723 | } |
| 760 | else if (B.Is32BitMipsGot) | 724 | |
| 761 | Index += LocalEntries.size(); | 725 | uint64_t MipsGotSection::getPageEntryOffset(const InputFile *F, |
| 762 | // Calculate offset of the GOT entry in the block. | 726 | const Symbol &Sym, |
| 763 | if (B.isInGot()) | 727 | int64_t Addend) const { |
| 764 | Index += B.GotIndex; | 728 | const FileGot &G = Gots[*F->MipsGotIndex]; |
| 765 | else { | 729 | uint64_t Index = 0; |
| 766 | auto It = EntryIndexMap.find({&B, Addend}); | 730 | if (const OutputSection *OutSec = Sym.getOutputSection()) { |
| 767 | assert(It != EntryIndexMap.end()); | 731 | uint64_t SecAddr = getMipsPageAddr(OutSec->Addr); |
| 768 | Index += It->second; | 732 | uint64_t SymAddr = getMipsPageAddr(Sym.getVA(Addend)); |
| 733 | Index = G.PagesMap.lookup(OutSec).FirstIndex + (SymAddr - SecAddr) / 0xffff; | ||
| 734 | } else { | ||
| 735 | Index = G.Local16.lookup({nullptr, getMipsPageAddr(Sym.getVA(Addend))}); | ||
| 769 | } | 736 | } |
| 770 | return Index * Config->Wordsize; | 737 | return Index * Config->Wordsize; |
| 771 | } | 738 | } |
| 772 | 739 | ||
| 773 | uint64_t MipsGotSection::getTlsOffset() const { | 740 | uint64_t MipsGotSection::getSymEntryOffset(const InputFile *F, const Symbol &S, |
| 774 | return (getLocalEntriesNum() + GlobalEntries.size()) * Config->Wordsize; | 741 | int64_t Addend) const { |
| 742 | const FileGot &G = Gots[*F->MipsGotIndex]; | ||
| 743 | Symbol *Sym = const_cast<Symbol *>(&S); | ||
| 744 | if (Sym->isTls()) | ||
| 745 | return G.Tls.lookup(Sym) * Config->Wordsize; | ||
| 746 | if (Sym->IsPreemptible) | ||
| 747 | return G.Global.lookup(Sym) * Config->Wordsize; | ||
| 748 | return G.Local16.lookup({Sym, Addend}) * Config->Wordsize; | ||
| 775 | } | 749 | } |
| 776 | 750 | ||
| 777 | uint64_t MipsGotSection::getGlobalDynOffset(const Symbol &B) const { | 751 | uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *F) const { |
| 778 | return B.GlobalDynIndex * Config->Wordsize; | 752 | const FileGot &G = Gots[*F->MipsGotIndex]; |
| 753 | return G.DynTlsSymbols.lookup(nullptr) * Config->Wordsize; | ||
| 754 | } | ||
| 755 | |||
| 756 | uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *F, | ||
| 757 | const Symbol &S) const { | ||
| 758 | const FileGot &G = Gots[*F->MipsGotIndex]; | ||
| 759 | Symbol *Sym = const_cast<Symbol *>(&S); | ||
| 760 | return G.DynTlsSymbols.lookup(Sym) * Config->Wordsize; | ||
| 779 | } | 761 | } |
| 780 | 762 | ||
| 781 | const Symbol *MipsGotSection::getFirstGlobalEntry() const { | 763 | const Symbol *MipsGotSection::getFirstGlobalEntry() const { |
| 782 | return GlobalEntries.empty() ? nullptr : GlobalEntries.front().first; | 764 | if (Gots.empty()) |
| 765 | return nullptr; | ||
| 766 | const FileGot &PrimGot = Gots.front(); | ||
| 767 | if (!PrimGot.Global.empty()) | ||
| 768 | return PrimGot.Global.front().first; | ||
| 769 | if (!PrimGot.Relocs.empty()) | ||
| 770 | return PrimGot.Relocs.front().first; | ||
| 771 | return nullptr; | ||
| 783 | } | 772 | } |
| 784 | 773 | ||
| 785 | unsigned MipsGotSection::getLocalEntriesNum() const { | 774 | unsigned MipsGotSection::getLocalEntriesNum() const { |
| 786 | return HeaderEntriesNum + PageEntriesNum + LocalEntries.size() + | 775 | if (Gots.empty()) |
| 787 | LocalEntries32.size(); | 776 | return HeaderEntriesNum; |
| 777 | return HeaderEntriesNum + Gots.front().getPageEntriesNum() + | ||
| 778 | Gots.front().Local16.size(); | ||
| 779 | } | ||
| 780 | |||
| 781 | bool MipsGotSection::tryMergeGots(FileGot &Dst, FileGot &Src, bool IsPrimary) { | ||
| 782 | FileGot Tmp = Dst; | ||
| 783 | set_union(Tmp.PagesMap, Src.PagesMap); | ||
| 784 | set_union(Tmp.Local16, Src.Local16); | ||
| 785 | set_union(Tmp.Global, Src.Global); | ||
| 786 | set_union(Tmp.Relocs, Src.Relocs); | ||
| 787 | set_union(Tmp.Tls, Src.Tls); | ||
| 788 | set_union(Tmp.DynTlsSymbols, Src.DynTlsSymbols); | ||
| 789 | |||
| 790 | size_t Count = IsPrimary ? HeaderEntriesNum : 0; | ||
| 791 | Count += Tmp.getIndexedEntriesNum(); | ||
| 792 | |||
| 793 | if (Count * Config->Wordsize > Config->MipsGotSize) | ||
| 794 | return false; | ||
| 795 | |||
| 796 | std::swap(Tmp, Dst); | ||
| 797 | return true; | ||
| 788 | } | 798 | } |
| 789 | 799 | ||
| 790 | void MipsGotSection::finalizeContents() { updateAllocSize(); } | 800 | void MipsGotSection::finalizeContents() { updateAllocSize(); } |
| 791 | 801 | ||
| 792 | bool MipsGotSection::updateAllocSize() { | 802 | bool MipsGotSection::updateAllocSize() { |
| 793 | PageEntriesNum = 0; | 803 | Size = HeaderEntriesNum * Config->Wordsize; |
| 794 | for (std::pair<const OutputSection *, size_t> &P : PageIndexMap) { | 804 | for (const FileGot &G : Gots) |
| 795 | // For each output section referenced by GOT page relocations calculate | 805 | Size += G.getEntriesNum() * Config->Wordsize; |
| 796 | // and save into PageIndexMap an upper bound of MIPS GOT entries required | ||
| 797 | // to store page addresses of local symbols. We assume the worst case - | ||
| 798 | // each 64kb page of the output section has at least one GOT relocation | ||
| 799 | // against it. And take in account the case when the section intersects | ||
| 800 | // page boundaries. | ||
| 801 | P.second = PageEntriesNum; | ||
| 802 | PageEntriesNum += getMipsPageCount(P.first->Size); | ||
| 803 | } | ||
| 804 | Size = (getLocalEntriesNum() + GlobalEntries.size() + TlsEntries.size()) * | ||
| 805 | Config->Wordsize; | ||
| 806 | return false; | 806 | return false; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| 809 | template <class ELFT> void MipsGotSection::build() { | ||
| 810 | if (Gots.empty()) | ||
| 811 | return; | ||
| 812 | |||
| 813 | std::vector<FileGot> MergedGots(1); | ||
| 814 | |||
| 815 | // For each GOT move non-preemptible symbols from the `Global` | ||
| 816 | // to `Local16` list. Preemptible symbol might become non-preemptible | ||
| 817 | // one if, for example, it gets a related copy relocation. | ||
| 818 | for (FileGot &Got : Gots) { | ||
| 819 | for (auto &P: Got.Global) | ||
| 820 | if (!P.first->IsPreemptible) | ||
| 821 | Got.Local16.insert({{P.first, 0}, 0}); | ||
| 822 | Got.Global.remove_if([&](const std::pair<Symbol *, size_t> &P) { | ||
| 823 | return !P.first->IsPreemptible; | ||
| 824 | }); | ||
| 825 | } | ||
| 826 | |||
| 827 | // For each GOT remove "reloc-only" entry if there is "global" | ||
| 828 | // entry for the same symbol. And add local entries which indexed | ||
| 829 | // using 32-bit value at the end of 16-bit entries. | ||
| 830 | for (FileGot &Got : Gots) { | ||
| 831 | Got.Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) { | ||
| 832 | return Got.Global.count(P.first); | ||
| 833 | }); | ||
| 834 | set_union(Got.Local16, Got.Local32); | ||
| 835 | Got.Local32.clear(); | ||
| 836 | } | ||
| 837 | |||
| 838 | // Evaluate number of "reloc-only" entries in the resulting GOT. | ||
| 839 | // To do that put all unique "reloc-only" and "global" entries | ||
| 840 | // from all GOTs to the future primary GOT. | ||
| 841 | FileGot *PrimGot = &MergedGots.front(); | ||
| 842 | for (FileGot &Got : Gots) { | ||
| 843 | set_union(PrimGot->Relocs, Got.Global); | ||
| 844 | set_union(PrimGot->Relocs, Got.Relocs); | ||
| 845 | Got.Relocs.clear(); | ||
| 846 | } | ||
| 847 | |||
| 848 | // Evaluate number of "page" entries in each GOT. | ||
| 849 | for (FileGot &Got : Gots) { | ||
| 850 | for (std::pair<const OutputSection *, FileGot::PageBlock> &P : | ||
| 851 | Got.PagesMap) { | ||
| 852 | const OutputSection *OS = P.first; | ||
| 853 | uint64_t SecSize = 0; | ||
| 854 | for (BaseCommand *Cmd : OS->SectionCommands) { | ||
| 855 | if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd)) | ||
| 856 | for (InputSection *IS : ISD->Sections) { | ||
| 857 | uint64_t Off = alignTo(SecSize, IS->Alignment); | ||
| 858 | SecSize = Off + IS->getSize(); | ||
| 859 | } | ||
| 860 | } | ||
| 861 | P.second.Count = getMipsPageCount(SecSize); | ||
| 862 | } | ||
| 863 | } | ||
| 864 | |||
| 865 | // Merge GOTs. Try to join as much as possible GOTs but do not exceed | ||
| 866 | // maximum GOT size. At first, try to fill the primary GOT because | ||
| 867 | // the primary GOT can be accessed in the most effective way. If it | ||
| 868 | // is not possible, try to fill the last GOT in the list, and finally | ||
| 869 | // create a new GOT if both attempts failed. | ||
| 870 | for (FileGot &SrcGot : Gots) { | ||
| 871 | InputFile *File = SrcGot.File; | ||
| 872 | if (tryMergeGots(MergedGots.front(), SrcGot, true)) { | ||
| 873 | File->MipsGotIndex = 0; | ||
| 874 | } else { | ||
| 875 | // If this is the first time we failed to merge with the primary GOT, | ||
| 876 | // MergedGots.back() will also be the primary GOT. We must make sure not | ||
| 877 | // to try to merge again with IsPrimary=false, as otherwise, if the | ||
| 878 | // inputs are just right, we could allow the primary GOT to become 1 or 2 | ||
| 879 | // words too big due to ignoring the header size. | ||
| 880 | if (MergedGots.size() == 1 || | ||
| 881 | !tryMergeGots(MergedGots.back(), SrcGot, false)) { | ||
| 882 | MergedGots.emplace_back(); | ||
| 883 | std::swap(MergedGots.back(), SrcGot); | ||
| 884 | } | ||
| 885 | File->MipsGotIndex = MergedGots.size() - 1; | ||
| 886 | } | ||
| 887 | } | ||
| 888 | std::swap(Gots, MergedGots); | ||
| 889 | |||
| 890 | // Reduce number of "reloc-only" entries in the primary GOT | ||
| 891 | // by substracting "global" entries exist in the primary GOT. | ||
| 892 | PrimGot = &Gots.front(); | ||
| 893 | PrimGot->Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) { | ||
| 894 | return PrimGot->Global.count(P.first); | ||
| 895 | }); | ||
| 896 | |||
| 897 | // Calculate indexes for each GOT entry. | ||
| 898 | size_t Index = HeaderEntriesNum; | ||
| 899 | for (FileGot &Got : Gots) { | ||
| 900 | Got.StartIndex = &Got == PrimGot ? 0 : Index; | ||
| 901 | for (std::pair<const OutputSection *, FileGot::PageBlock> &P : | ||
| 902 | Got.PagesMap) { | ||
| 903 | // For each output section referenced by GOT page relocations calculate | ||
| 904 | // and save into PagesMap an upper bound of MIPS GOT entries required | ||
| 905 | // to store page addresses of local symbols. We assume the worst case - | ||
| 906 | // each 64kb page of the output section has at least one GOT relocation | ||
| 907 | // against it. And take in account the case when the section intersects | ||
| 908 | // page boundaries. | ||
| 909 | P.second.FirstIndex = Index; | ||
| 910 | Index += P.second.Count; | ||
| 911 | } | ||
| 912 | for (auto &P: Got.Local16) | ||
| 913 | P.second = Index++; | ||
| 914 | for (auto &P: Got.Global) | ||
| 915 | P.second = Index++; | ||
| 916 | for (auto &P: Got.Relocs) | ||
| 917 | P.second = Index++; | ||
| 918 | for (auto &P: Got.Tls) | ||
| 919 | P.second = Index++; | ||
| 920 | for (auto &P: Got.DynTlsSymbols) { | ||
| 921 | P.second = Index; | ||
| 922 | Index += 2; | ||
| 923 | } | ||
| 924 | } | ||
| 925 | |||
| 926 | // Update Symbol::GotIndex field to use this | ||
| 927 | // value later in the `sortMipsSymbols` function. | ||
| 928 | for (auto &P : PrimGot->Global) | ||
| 929 | P.first->GotIndex = P.second; | ||
| 930 | for (auto &P : PrimGot->Relocs) | ||
| 931 | P.first->GotIndex = P.second; | ||
| 932 | |||
| 933 | // Create dynamic relocations. | ||
| 934 | for (FileGot &Got : Gots) { | ||
| 935 | // Create dynamic relocations for TLS entries. | ||
| 936 | for (std::pair<Symbol *, size_t> &P : Got.Tls) { | ||
| 937 | Symbol *S = P.first; | ||
| 938 | uint64_t Offset = P.second * Config->Wordsize; | ||
| 939 | if (S->IsPreemptible) | ||
| 940 | InX::RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S); | ||
| 941 | } | ||
| 942 | for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) { | ||
| 943 | Symbol *S = P.first; | ||
| 944 | uint64_t Offset = P.second * Config->Wordsize; | ||
| 945 | if (S == nullptr) { | ||
| 946 | if (!Config->Pic) | ||
| 947 | continue; | ||
| 948 | InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S); | ||
| 949 | } else { | ||
| 950 | // When building a shared library we still need a dynamic relocation | ||
| 951 | // for the module index. Therefore only checking for | ||
| 952 | // S->IsPreemptible is not sufficient (this happens e.g. for | ||
| 953 | // thread-locals that have been marked as local through a linker script) | ||
| 954 | if (!S->IsPreemptible && !Config->Pic) | ||
| 955 | continue; | ||
| 956 | InX::RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S); | ||
| 957 | // However, we can skip writing the TLS offset reloc for non-preemptible | ||
| 958 | // symbols since it is known even in shared libraries | ||
| 959 | if (!S->IsPreemptible) | ||
| 960 | continue; | ||
| 961 | Offset += Config->Wordsize; | ||
| 962 | InX::RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S); | ||
| 963 | } | ||
| 964 | } | ||
| 965 | |||
| 966 | // Do not create dynamic relocations for non-TLS | ||
| 967 | // entries in the primary GOT. | ||
| 968 | if (&Got == PrimGot) | ||
| 969 | continue; | ||
| 970 | |||
| 971 | // Dynamic relocations for "global" entries. | ||
| 972 | for (const std::pair<Symbol *, size_t> &P : Got.Global) { | ||
| 973 | uint64_t Offset = P.second * Config->Wordsize; | ||
| 974 | InX::RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first); | ||
| 975 | } | ||
| 976 | if (!Config->Pic) | ||
| 977 | continue; | ||
| 978 | // Dynamic relocations for "local" entries in case of PIC. | ||
| 979 | for (const std::pair<const OutputSection *, FileGot::PageBlock> &L : | ||
| 980 | Got.PagesMap) { | ||
| 981 | size_t PageCount = L.second.Count; | ||
| 982 | for (size_t PI = 0; PI < PageCount; ++PI) { | ||
| 983 | uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize; | ||
| 984 | InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first, | ||
| 985 | int64_t(PI * 0x10000)}); | ||
| 986 | } | ||
| 987 | } | ||
| 988 | for (const std::pair<GotEntry, size_t> &P : Got.Local16) { | ||
| 989 | uint64_t Offset = P.second * Config->Wordsize; | ||
| 990 | InX::RelaDyn->addReloc({Target->RelativeRel, this, Offset, true, | ||
| 991 | P.first.first, P.first.second}); | ||
| 992 | } | ||
| 993 | } | ||
| 994 | } | ||
| 995 | |||
| 809 | bool MipsGotSection::empty() const { | 996 | bool MipsGotSection::empty() const { |
| 810 | // We add the .got section to the result for dynamic MIPS target because | 997 | // We add the .got section to the result for dynamic MIPS target because |
| 811 | // its address and properties are mentioned in the .dynamic section. | 998 | // its address and properties are mentioned in the .dynamic section. |
| 812 | return Config->Relocatable; | 999 | return Config->Relocatable; |
| 813 | } | 1000 | } |
| 814 | 1001 | ||
| 815 | uint64_t MipsGotSection::getGp() const { return ElfSym::MipsGp->getVA(0); } | 1002 | uint64_t MipsGotSection::getGp(const InputFile *F) const { |
| 1003 | // For files without related GOT or files refer a primary GOT | ||
| 1004 | // returns "common" _gp value. For secondary GOTs calculate | ||
| 1005 | // individual _gp values. | ||
| 1006 | if (!F || !F->MipsGotIndex.hasValue() || *F->MipsGotIndex == 0) | ||
| 1007 | return ElfSym::MipsGp->getVA(0); | ||
| 1008 | return getVA() + Gots[*F->MipsGotIndex].StartIndex * Config->Wordsize + | ||
| 1009 | 0x7ff0; | ||
| 1010 | } | ||
| 816 | 1011 | ||
| 817 | void MipsGotSection::writeTo(uint8_t *Buf) { | 1012 | void MipsGotSection::writeTo(uint8_t *Buf) { |
| 818 | // Set the MSB of the second GOT slot. This is not required by any | 1013 | // Set the MSB of the second GOT slot. This is not required by any |
| ... | @@ -830,59 +1025,67 @@ void MipsGotSection::writeTo(uint8_t *Buf) { | ... | @@ -830,59 +1025,67 @@ void MipsGotSection::writeTo(uint8_t *Buf) { |
| 830 | // keep doing this for now. We really need to revisit this to see | 1025 | // keep doing this for now. We really need to revisit this to see |
| 831 | // if we had to do this. | 1026 | // if we had to do this. |
| 832 | writeUint(Buf + Config->Wordsize, (uint64_t)1 << (Config->Wordsize * 8 - 1)); | 1027 | writeUint(Buf + Config->Wordsize, (uint64_t)1 << (Config->Wordsize * 8 - 1)); |
| 833 | Buf += HeaderEntriesNum * Config->Wordsize; | 1028 | for (const FileGot &G : Gots) { |
| 834 | // Write 'page address' entries to the local part of the GOT. | 1029 | auto Write = [&](size_t I, const Symbol *S, int64_t A) { |
| 835 | for (std::pair<const OutputSection *, size_t> &L : PageIndexMap) { | 1030 | uint64_t VA = A; |
| 836 | size_t PageCount = getMipsPageCount(L.first->Size); | 1031 | if (S) { |
| 837 | uint64_t FirstPageAddr = getMipsPageAddr(L.first->Addr); | 1032 | VA = S->getVA(A); |
| 838 | for (size_t PI = 0; PI < PageCount; ++PI) { | 1033 | if (S->StOther & STO_MIPS_MICROMIPS) |
| 839 | uint8_t *Entry = Buf + (L.second + PI) * Config->Wordsize; | 1034 | VA |= 1; |
| 840 | writeUint(Entry, FirstPageAddr + PI * 0x10000); | 1035 | } |
| 841 | } | 1036 | writeUint(Buf + I * Config->Wordsize, VA); |
| 842 | } | 1037 | }; |
| 843 | Buf += PageEntriesNum * Config->Wordsize; | 1038 | // Write 'page address' entries to the local part of the GOT. |
| 844 | auto AddEntry = [&](const GotEntry &SA) { | 1039 | for (const std::pair<const OutputSection *, FileGot::PageBlock> &L : |
| 845 | uint8_t *Entry = Buf; | 1040 | G.PagesMap) { |
| 846 | Buf += Config->Wordsize; | 1041 | size_t PageCount = L.second.Count; |
| 847 | const Symbol *Sym = SA.first; | 1042 | uint64_t FirstPageAddr = getMipsPageAddr(L.first->Addr); |
| 848 | uint64_t VA = Sym->getVA(SA.second); | 1043 | for (size_t PI = 0; PI < PageCount; ++PI) |
| 849 | if (Sym->StOther & STO_MIPS_MICROMIPS) | 1044 | Write(L.second.FirstIndex + PI, nullptr, FirstPageAddr + PI * 0x10000); |
| 850 | VA |= 1; | ||
| 851 | writeUint(Entry, VA); | ||
| 852 | }; | ||
| 853 | std::for_each(std::begin(LocalEntries), std::end(LocalEntries), AddEntry); | ||
| 854 | std::for_each(std::begin(LocalEntries32), std::end(LocalEntries32), AddEntry); | ||
| 855 | std::for_each(std::begin(GlobalEntries), std::end(GlobalEntries), AddEntry); | ||
| 856 | // Initialize TLS-related GOT entries. If the entry has a corresponding | ||
| 857 | // dynamic relocations, leave it initialized by zero. Write down adjusted | ||
| 858 | // TLS symbol's values otherwise. To calculate the adjustments use offsets | ||
| 859 | // for thread-local storage. | ||
| 860 | // https://www.linux-mips.org/wiki/NPTL | ||
| 861 | if (TlsIndexOff != -1U && !Config->Pic) | ||
| 862 | writeUint(Buf + TlsIndexOff, 1); | ||
| 863 | for (const Symbol *B : TlsEntries) { | ||
| 864 | if (!B || B->IsPreemptible) | ||
| 865 | continue; | ||
| 866 | uint64_t VA = B->getVA(); | ||
| 867 | if (B->GotIndex != -1U) { | ||
| 868 | uint8_t *Entry = Buf + B->GotIndex * Config->Wordsize; | ||
| 869 | writeUint(Entry, VA - 0x7000); | ||
| 870 | } | 1045 | } |
| 871 | if (B->GlobalDynIndex != -1U) { | 1046 | // Local, global, TLS, reloc-only entries. |
| 872 | uint8_t *Entry = Buf + B->GlobalDynIndex * Config->Wordsize; | 1047 | // If TLS entry has a corresponding dynamic relocations, leave it |
| 873 | writeUint(Entry, 1); | 1048 | // initialized by zero. Write down adjusted TLS symbol's values otherwise. |
| 874 | Entry += Config->Wordsize; | 1049 | // To calculate the adjustments use offsets for thread-local storage. |
| 875 | writeUint(Entry, VA - 0x8000); | 1050 | // https://www.linux-mips.org/wiki/NPTL |
| 1051 | for (const std::pair<GotEntry, size_t> &P : G.Local16) | ||
| 1052 | Write(P.second, P.first.first, P.first.second); | ||
| 1053 | // Write VA to the primary GOT only. For secondary GOTs that | ||
| 1054 | // will be done by REL32 dynamic relocations. | ||
| 1055 | if (&G == &Gots.front()) | ||
| 1056 | for (const std::pair<const Symbol *, size_t> &P : G.Global) | ||
| 1057 | Write(P.second, P.first, 0); | ||
| 1058 | for (const std::pair<Symbol *, size_t> &P : G.Relocs) | ||
| 1059 | Write(P.second, P.first, 0); | ||
| 1060 | for (const std::pair<Symbol *, size_t> &P : G.Tls) | ||
| 1061 | Write(P.second, P.first, P.first->IsPreemptible ? 0 : -0x7000); | ||
| 1062 | for (const std::pair<Symbol *, size_t> &P : G.DynTlsSymbols) { | ||
| 1063 | if (P.first == nullptr && !Config->Pic) | ||
| 1064 | Write(P.second, nullptr, 1); | ||
| 1065 | else if (P.first && !P.first->IsPreemptible) { | ||
| 1066 | // If we are emitting PIC code with relocations we mustn't write | ||
| 1067 | // anything to the GOT here. When using Elf_Rel relocations the value | ||
| 1068 | // one will be treated as an addend and will cause crashes at runtime | ||
| 1069 | if (!Config->Pic) | ||
| 1070 | Write(P.second, nullptr, 1); | ||
| 1071 | Write(P.second + 1, P.first, -0x8000); | ||
| 1072 | } | ||
| 876 | } | 1073 | } |
| 877 | } | 1074 | } |
| 878 | } | 1075 | } |
| 879 | 1076 | ||
| 1077 | // On PowerPC the .plt section is used to hold the table of function addresses | ||
| 1078 | // instead of the .got.plt, and the type is SHT_NOBITS similar to a .bss | ||
| 1079 | // section. I don't know why we have a BSS style type for the section but it is | ||
| 1080 | // consitent across both 64-bit PowerPC ABIs as well as the 32-bit PowerPC ABI. | ||
| 880 | GotPltSection::GotPltSection() | 1081 | GotPltSection::GotPltSection() |
| 881 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, | 1082 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, |
| 882 | Target->GotPltEntrySize, ".got.plt") {} | 1083 | Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS, |
| 1084 | Target->GotPltEntrySize, | ||
| 1085 | Config->EMachine == EM_PPC64 ? ".plt" : ".got.plt") {} | ||
| 883 | 1086 | ||
| 884 | void GotPltSection::addEntry(Symbol &Sym) { | 1087 | void GotPltSection::addEntry(Symbol &Sym) { |
| 885 | Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size(); | 1088 | assert(Sym.PltIndex == Entries.size()); |
| 886 | Entries.push_back(&Sym); | 1089 | Entries.push_back(&Sym); |
| 887 | } | 1090 | } |
| 888 | 1091 | ||
| ... | @@ -900,16 +1103,37 @@ void GotPltSection::writeTo(uint8_t *Buf) { | ... | @@ -900,16 +1103,37 @@ void GotPltSection::writeTo(uint8_t *Buf) { |
| 900 | } | 1103 | } |
| 901 | } | 1104 | } |
| 902 | 1105 | ||
| 903 | // On ARM the IgotPltSection is part of the GotSection, on other Targets it is | 1106 | bool GotPltSection::empty() const { |
| 904 | // part of the .got.plt | 1107 | // We need to emit a GOT.PLT even if it's empty if there's a symbol that |
| 1108 | // references the _GLOBAL_OFFSET_TABLE_ and the Target defines the symbol | ||
| 1109 | // relative to the .got.plt section. | ||
| 1110 | return Entries.empty() && | ||
| 1111 | !(ElfSym::GlobalOffsetTable && Target->GotBaseSymInGotPlt); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | static StringRef getIgotPltName() { | ||
| 1115 | // On ARM the IgotPltSection is part of the GotSection. | ||
| 1116 | if (Config->EMachine == EM_ARM) | ||
| 1117 | return ".got"; | ||
| 1118 | |||
| 1119 | // On PowerPC64 the GotPltSection is renamed to '.plt' so the IgotPltSection | ||
| 1120 | // needs to be named the same. | ||
| 1121 | if (Config->EMachine == EM_PPC64) | ||
| 1122 | return ".plt"; | ||
| 1123 | |||
| 1124 | return ".got.plt"; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | // On PowerPC64 the GotPltSection type is SHT_NOBITS so we have to follow suit | ||
| 1128 | // with the IgotPltSection. | ||
| 905 | IgotPltSection::IgotPltSection() | 1129 | IgotPltSection::IgotPltSection() |
| 906 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, | 1130 | : SyntheticSection(SHF_ALLOC | SHF_WRITE, |
| 907 | Target->GotPltEntrySize, | 1131 | Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS, |
| 908 | Config->EMachine == EM_ARM ? ".got" : ".got.plt") {} | 1132 | Target->GotPltEntrySize, getIgotPltName()) {} |
| 909 | 1133 | ||
| 910 | void IgotPltSection::addEntry(Symbol &Sym) { | 1134 | void IgotPltSection::addEntry(Symbol &Sym) { |
| 911 | Sym.IsInIgot = true; | 1135 | Sym.IsInIgot = true; |
| 912 | Sym.GotPltIndex = Entries.size(); | 1136 | assert(Sym.PltIndex == Entries.size()); |
| 913 | Entries.push_back(&Sym); | 1137 | Entries.push_back(&Sym); |
| 914 | } | 1138 | } |
| 915 | 1139 | ||
| ... | @@ -1005,8 +1229,14 @@ void DynamicSection<ELFT>::addInt(int32_t Tag, uint64_t Val) { | ... | @@ -1005,8 +1229,14 @@ void DynamicSection<ELFT>::addInt(int32_t Tag, uint64_t Val) { |
| 1005 | 1229 | ||
| 1006 | template <class ELFT> | 1230 | template <class ELFT> |
| 1007 | void DynamicSection<ELFT>::addInSec(int32_t Tag, InputSection *Sec) { | 1231 | void DynamicSection<ELFT>::addInSec(int32_t Tag, InputSection *Sec) { |
| 1232 | Entries.push_back({Tag, [=] { return Sec->getVA(0); }}); | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | template <class ELFT> | ||
| 1236 | void DynamicSection<ELFT>::addInSecRelative(int32_t Tag, InputSection *Sec) { | ||
| 1237 | size_t TagOffset = Entries.size() * Entsize; | ||
| 1008 | Entries.push_back( | 1238 | Entries.push_back( |
| 1009 | {Tag, [=] { return Sec->getParent()->Addr + Sec->OutSecOff; }}); | 1239 | {Tag, [=] { return Sec->getVA(0) - (getVA() + TagOffset); }}); |
| 1010 | } | 1240 | } |
| 1011 | 1241 | ||
| 1012 | template <class ELFT> | 1242 | template <class ELFT> |
| ... | @@ -1034,6 +1264,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { | ... | @@ -1034,6 +1264,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { |
| 1034 | uint32_t DtFlags1 = 0; | 1264 | uint32_t DtFlags1 = 0; |
| 1035 | if (Config->Bsymbolic) | 1265 | if (Config->Bsymbolic) |
| 1036 | DtFlags |= DF_SYMBOLIC; | 1266 | DtFlags |= DF_SYMBOLIC; |
| 1267 | if (Config->ZInitfirst) | ||
| 1268 | DtFlags1 |= DF_1_INITFIRST; | ||
| 1037 | if (Config->ZNodelete) | 1269 | if (Config->ZNodelete) |
| 1038 | DtFlags1 |= DF_1_NODELETE; | 1270 | DtFlags1 |= DF_1_NODELETE; |
| 1039 | if (Config->ZNodlopen) | 1271 | if (Config->ZNodlopen) |
| ... | @@ -1046,6 +1278,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { | ... | @@ -1046,6 +1278,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { |
| 1046 | DtFlags |= DF_ORIGIN; | 1278 | DtFlags |= DF_ORIGIN; |
| 1047 | DtFlags1 |= DF_1_ORIGIN; | 1279 | DtFlags1 |= DF_1_ORIGIN; |
| 1048 | } | 1280 | } |
| 1281 | if (!Config->ZText) | ||
| 1282 | DtFlags |= DF_TEXTREL; | ||
| 1049 | 1283 | ||
| 1050 | if (DtFlags) | 1284 | if (DtFlags) |
| 1051 | addInt(DT_FLAGS, DtFlags); | 1285 | addInt(DT_FLAGS, DtFlags); |
| ... | @@ -1081,6 +1315,14 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { | ... | @@ -1081,6 +1315,14 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { |
| 1081 | addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels); | 1315 | addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels); |
| 1082 | } | 1316 | } |
| 1083 | } | 1317 | } |
| 1318 | if (InX::RelrDyn && !InX::RelrDyn->Relocs.empty()) { | ||
| 1319 | addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR, | ||
| 1320 | InX::RelrDyn); | ||
| 1321 | addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ, | ||
| 1322 | InX::RelrDyn->getParent()); | ||
| 1323 | addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT, | ||
| 1324 | sizeof(Elf_Relr)); | ||
| 1325 | } | ||
| 1084 | // .rel[a].plt section usually consists of two parts, containing plt and | 1326 | // .rel[a].plt section usually consists of two parts, containing plt and |
| 1085 | // iplt relocations. It is possible to have only iplt relocations in the | 1327 | // iplt relocations. It is possible to have only iplt relocations in the |
| 1086 | // output. In that case RelaPlt is empty and have zero offset, the same offset | 1328 | // output. In that case RelaPlt is empty and have zero offset, the same offset |
| ... | @@ -1160,8 +1402,23 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { | ... | @@ -1160,8 +1402,23 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() { |
| 1160 | else | 1402 | else |
| 1161 | addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols()); | 1403 | addInt(DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols()); |
| 1162 | addInSec(DT_PLTGOT, InX::MipsGot); | 1404 | addInSec(DT_PLTGOT, InX::MipsGot); |
| 1163 | if (InX::MipsRldMap) | 1405 | if (InX::MipsRldMap) { |
| 1164 | addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap); | 1406 | if (!Config->Pie) |
| 1407 | addInSec(DT_MIPS_RLD_MAP, InX::MipsRldMap); | ||
| 1408 | // Store the offset to the .rld_map section | ||
| 1409 | // relative to the address of the tag. | ||
| 1410 | addInSecRelative(DT_MIPS_RLD_MAP_REL, InX::MipsRldMap); | ||
| 1411 | } | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | // Glink dynamic tag is required by the V2 abi if the plt section isn't empty. | ||
| 1415 | if (Config->EMachine == EM_PPC64 && !InX::Plt->empty()) { | ||
| 1416 | // The Glink tag points to 32 bytes before the first lazy symbol resolution | ||
| 1417 | // stub, which starts directly after the header. | ||
| 1418 | Entries.push_back({DT_PPC64_GLINK, [=] { | ||
| 1419 | unsigned Offset = Target->PltHeaderSize - 32; | ||
| 1420 | return InX::Plt->getVA(0) + Offset; | ||
| 1421 | }}); | ||
| 1165 | } | 1422 | } |
| 1166 | 1423 | ||
| 1167 | addInt(DT_NULL, 0); | 1424 | addInt(DT_NULL, 0); |
| ... | @@ -1181,13 +1438,16 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { | ... | @@ -1181,13 +1438,16 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1181 | } | 1438 | } |
| 1182 | 1439 | ||
| 1183 | uint64_t DynamicReloc::getOffset() const { | 1440 | uint64_t DynamicReloc::getOffset() const { |
| 1184 | return InputSec->getOutputSection()->Addr + InputSec->getOffset(OffsetInSec); | 1441 | return InputSec->getVA(OffsetInSec); |
| 1185 | } | 1442 | } |
| 1186 | 1443 | ||
| 1187 | int64_t DynamicReloc::getAddend() const { | 1444 | int64_t DynamicReloc::computeAddend() const { |
| 1188 | if (UseSymVA) | 1445 | if (UseSymVA) |
| 1189 | return Sym->getVA(Addend); | 1446 | return Sym->getVA(Addend); |
| 1190 | return Addend; | 1447 | if (!OutputSec) |
| 1448 | return Addend; | ||
| 1449 | // See the comment in the DynamicReloc ctor. | ||
| 1450 | return getMipsPageAddr(OutputSec->Addr) + Addend; | ||
| 1191 | } | 1451 | } |
| 1192 | 1452 | ||
| 1193 | uint32_t DynamicReloc::getSymIndex() const { | 1453 | uint32_t DynamicReloc::getSymIndex() const { |
| ... | @@ -1202,6 +1462,23 @@ RelocationBaseSection::RelocationBaseSection(StringRef Name, uint32_t Type, | ... | @@ -1202,6 +1462,23 @@ RelocationBaseSection::RelocationBaseSection(StringRef Name, uint32_t Type, |
| 1202 | : SyntheticSection(SHF_ALLOC, Type, Config->Wordsize, Name), | 1462 | : SyntheticSection(SHF_ALLOC, Type, Config->Wordsize, Name), |
| 1203 | DynamicTag(DynamicTag), SizeDynamicTag(SizeDynamicTag) {} | 1463 | DynamicTag(DynamicTag), SizeDynamicTag(SizeDynamicTag) {} |
| 1204 | 1464 | ||
| 1465 | void RelocationBaseSection::addReloc(RelType DynType, InputSectionBase *IS, | ||
| 1466 | uint64_t OffsetInSec, Symbol *Sym) { | ||
| 1467 | addReloc({DynType, IS, OffsetInSec, false, Sym, 0}); | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | void RelocationBaseSection::addReloc(RelType DynType, | ||
| 1471 | InputSectionBase *InputSec, | ||
| 1472 | uint64_t OffsetInSec, Symbol *Sym, | ||
| 1473 | int64_t Addend, RelExpr Expr, | ||
| 1474 | RelType Type) { | ||
| 1475 | // Write the addends to the relocated address if required. We skip | ||
| 1476 | // it if the written value would be zero. | ||
| 1477 | if (Config->WriteAddends && (Expr != R_ADDEND || Addend != 0)) | ||
| 1478 | InputSec->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym}); | ||
| 1479 | addReloc({DynType, InputSec, OffsetInSec, Expr != R_ADDEND, Sym, Addend}); | ||
| 1480 | } | ||
| 1481 | |||
| 1205 | void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) { | 1482 | void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) { |
| 1206 | if (Reloc.Type == Target->RelativeRel) | 1483 | if (Reloc.Type == Target->RelativeRel) |
| 1207 | ++NumRelativeRelocs; | 1484 | ++NumRelativeRelocs; |
| ... | @@ -1218,23 +1495,17 @@ void RelocationBaseSection::finalizeContents() { | ... | @@ -1218,23 +1495,17 @@ void RelocationBaseSection::finalizeContents() { |
| 1218 | getParent()->Link = Link; | 1495 | getParent()->Link = Link; |
| 1219 | } | 1496 | } |
| 1220 | 1497 | ||
| 1498 | RelrBaseSection::RelrBaseSection() | ||
| 1499 | : SyntheticSection(SHF_ALLOC, | ||
| 1500 | Config->UseAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR, | ||
| 1501 | Config->Wordsize, ".relr.dyn") {} | ||
| 1502 | |||
| 1221 | template <class ELFT> | 1503 | template <class ELFT> |
| 1222 | static void encodeDynamicReloc(typename ELFT::Rela *P, | 1504 | static void encodeDynamicReloc(typename ELFT::Rela *P, |
| 1223 | const DynamicReloc &Rel) { | 1505 | const DynamicReloc &Rel) { |
| 1224 | if (Config->IsRela) | 1506 | if (Config->IsRela) |
| 1225 | P->r_addend = Rel.getAddend(); | 1507 | P->r_addend = Rel.computeAddend(); |
| 1226 | P->r_offset = Rel.getOffset(); | 1508 | P->r_offset = Rel.getOffset(); |
| 1227 | if (Config->EMachine == EM_MIPS && Rel.getInputSec() == InX::MipsGot) | ||
| 1228 | // The MIPS GOT section contains dynamic relocations that correspond to TLS | ||
| 1229 | // entries. These entries are placed after the global and local sections of | ||
| 1230 | // the GOT. At the point when we create these relocations, the size of the | ||
| 1231 | // global and local sections is unknown, so the offset that we store in the | ||
| 1232 | // TLS entry's DynamicReloc is relative to the start of the TLS section of | ||
| 1233 | // the GOT, rather than being relative to the start of the GOT. This line of | ||
| 1234 | // code adds the size of the global and local sections to the virtual | ||
| 1235 | // address computed by getOffset() in order to adjust it into the TLS | ||
| 1236 | // section. | ||
| 1237 | P->r_offset += InX::MipsGot->getTlsOffset(); | ||
| 1238 | P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->IsMips64EL); | 1509 | P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->IsMips64EL); |
| 1239 | } | 1510 | } |
| 1240 | 1511 | ||
| ... | @@ -1247,32 +1518,22 @@ RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort) | ... | @@ -1247,32 +1518,22 @@ RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort) |
| 1247 | this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); | 1518 | this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); |
| 1248 | } | 1519 | } |
| 1249 | 1520 | ||
| 1250 | template <class ELFT, class RelTy> | 1521 | static bool compRelocations(const DynamicReloc &A, const DynamicReloc &B) { |
| 1251 | static bool compRelocations(const RelTy &A, const RelTy &B) { | 1522 | bool AIsRel = A.Type == Target->RelativeRel; |
| 1252 | bool AIsRel = A.getType(Config->IsMips64EL) == Target->RelativeRel; | 1523 | bool BIsRel = B.Type == Target->RelativeRel; |
| 1253 | bool BIsRel = B.getType(Config->IsMips64EL) == Target->RelativeRel; | ||
| 1254 | if (AIsRel != BIsRel) | 1524 | if (AIsRel != BIsRel) |
| 1255 | return AIsRel; | 1525 | return AIsRel; |
| 1256 | 1526 | return A.getSymIndex() < B.getSymIndex(); | |
| 1257 | return A.getSymbol(Config->IsMips64EL) < B.getSymbol(Config->IsMips64EL); | ||
| 1258 | } | 1527 | } |
| 1259 | 1528 | ||
| 1260 | template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { | 1529 | template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1261 | uint8_t *BufBegin = Buf; | 1530 | if (Sort) |
| 1531 | std::stable_sort(Relocs.begin(), Relocs.end(), compRelocations); | ||
| 1532 | |||
| 1262 | for (const DynamicReloc &Rel : Relocs) { | 1533 | for (const DynamicReloc &Rel : Relocs) { |
| 1263 | encodeDynamicReloc<ELFT>(reinterpret_cast<Elf_Rela *>(Buf), Rel); | 1534 | encodeDynamicReloc<ELFT>(reinterpret_cast<Elf_Rela *>(Buf), Rel); |
| 1264 | Buf += Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); | 1535 | Buf += Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); |
| 1265 | } | 1536 | } |
| 1266 | |||
| 1267 | if (Sort) { | ||
| 1268 | if (Config->IsRela) | ||
| 1269 | std::stable_sort((Elf_Rela *)BufBegin, | ||
| 1270 | (Elf_Rela *)BufBegin + Relocs.size(), | ||
| 1271 | compRelocations<ELFT, Elf_Rela>); | ||
| 1272 | else | ||
| 1273 | std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(), | ||
| 1274 | compRelocations<ELFT, Elf_Rel>); | ||
| 1275 | } | ||
| 1276 | } | 1537 | } |
| 1277 | 1538 | ||
| 1278 | template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() { | 1539 | template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() { |
| ... | @@ -1360,10 +1621,10 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() { | ... | @@ -1360,10 +1621,10 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() { |
| 1360 | NonRelatives.push_back(R); | 1621 | NonRelatives.push_back(R); |
| 1361 | } | 1622 | } |
| 1362 | 1623 | ||
| 1363 | std::sort(Relatives.begin(), Relatives.end(), | 1624 | llvm::sort(Relatives.begin(), Relatives.end(), |
| 1364 | [](const Elf_Rel &A, const Elf_Rel &B) { | 1625 | [](const Elf_Rel &A, const Elf_Rel &B) { |
| 1365 | return A.r_offset < B.r_offset; | 1626 | return A.r_offset < B.r_offset; |
| 1366 | }); | 1627 | }); |
| 1367 | 1628 | ||
| 1368 | // Try to find groups of relative relocations which are spaced one word | 1629 | // Try to find groups of relative relocations which are spaced one word |
| 1369 | // apart from one another. These generally correspond to vtable entries. The | 1630 | // apart from one another. These generally correspond to vtable entries. The |
| ... | @@ -1441,10 +1702,10 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() { | ... | @@ -1441,10 +1702,10 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() { |
| 1441 | } | 1702 | } |
| 1442 | 1703 | ||
| 1443 | // Finally the non-relative relocations. | 1704 | // Finally the non-relative relocations. |
| 1444 | std::sort(NonRelatives.begin(), NonRelatives.end(), | 1705 | llvm::sort(NonRelatives.begin(), NonRelatives.end(), |
| 1445 | [](const Elf_Rela &A, const Elf_Rela &B) { | 1706 | [](const Elf_Rela &A, const Elf_Rela &B) { |
| 1446 | return A.r_offset < B.r_offset; | 1707 | return A.r_offset < B.r_offset; |
| 1447 | }); | 1708 | }); |
| 1448 | if (!NonRelatives.empty()) { | 1709 | if (!NonRelatives.empty()) { |
| 1449 | Add(NonRelatives.size()); | 1710 | Add(NonRelatives.size()); |
| 1450 | Add(HasAddendIfRela); | 1711 | Add(HasAddendIfRela); |
| ... | @@ -1467,6 +1728,97 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() { | ... | @@ -1467,6 +1728,97 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() { |
| 1467 | return RelocData.size() != OldSize; | 1728 | return RelocData.size() != OldSize; |
| 1468 | } | 1729 | } |
| 1469 | 1730 | ||
| 1731 | template <class ELFT> RelrSection<ELFT>::RelrSection() { | ||
| 1732 | this->Entsize = Config->Wordsize; | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() { | ||
| 1736 | // This function computes the contents of an SHT_RELR packed relocation | ||
| 1737 | // section. | ||
| 1738 | // | ||
| 1739 | // Proposal for adding SHT_RELR sections to generic-abi is here: | ||
| 1740 | // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg | ||
| 1741 | // | ||
| 1742 | // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks | ||
| 1743 | // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ] | ||
| 1744 | // | ||
| 1745 | // i.e. start with an address, followed by any number of bitmaps. The address | ||
| 1746 | // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63 | ||
| 1747 | // relocations each, at subsequent offsets following the last address entry. | ||
| 1748 | // | ||
| 1749 | // The bitmap entries must have 1 in the least significant bit. The assumption | ||
| 1750 | // here is that an address cannot have 1 in lsb. Odd addresses are not | ||
| 1751 | // supported. | ||
| 1752 | // | ||
| 1753 | // Excluding the least significant bit in the bitmap, each non-zero bit in | ||
| 1754 | // the bitmap represents a relocation to be applied to a corresponding machine | ||
| 1755 | // word that follows the base address word. The second least significant bit | ||
| 1756 | // represents the machine word immediately following the initial address, and | ||
| 1757 | // each bit that follows represents the next word, in linear order. As such, | ||
| 1758 | // a single bitmap can encode up to 31 relocations in a 32-bit object, and | ||
| 1759 | // 63 relocations in a 64-bit object. | ||
| 1760 | // | ||
| 1761 | // This encoding has a couple of interesting properties: | ||
| 1762 | // 1. Looking at any entry, it is clear whether it's an address or a bitmap: | ||
| 1763 | // even means address, odd means bitmap. | ||
| 1764 | // 2. Just a simple list of addresses is a valid encoding. | ||
| 1765 | |||
| 1766 | size_t OldSize = RelrRelocs.size(); | ||
| 1767 | RelrRelocs.clear(); | ||
| 1768 | |||
| 1769 | // Same as Config->Wordsize but faster because this is a compile-time | ||
| 1770 | // constant. | ||
| 1771 | const size_t Wordsize = sizeof(typename ELFT::uint); | ||
| 1772 | |||
| 1773 | // Number of bits to use for the relocation offsets bitmap. | ||
| 1774 | // Must be either 63 or 31. | ||
| 1775 | const size_t NBits = Wordsize * 8 - 1; | ||
| 1776 | |||
| 1777 | // Get offsets for all relative relocations and sort them. | ||
| 1778 | std::vector<uint64_t> Offsets; | ||
| 1779 | for (const RelativeReloc &Rel : Relocs) | ||
| 1780 | Offsets.push_back(Rel.getOffset()); | ||
| 1781 | llvm::sort(Offsets.begin(), Offsets.end()); | ||
| 1782 | |||
| 1783 | // For each leading relocation, find following ones that can be folded | ||
| 1784 | // as a bitmap and fold them. | ||
| 1785 | for (size_t I = 0, E = Offsets.size(); I < E;) { | ||
| 1786 | // Add a leading relocation. | ||
| 1787 | RelrRelocs.push_back(Elf_Relr(Offsets[I])); | ||
| 1788 | uint64_t Base = Offsets[I] + Wordsize; | ||
| 1789 | ++I; | ||
| 1790 | |||
| 1791 | // Find foldable relocations to construct bitmaps. | ||
| 1792 | while (I < E) { | ||
| 1793 | uint64_t Bitmap = 0; | ||
| 1794 | |||
| 1795 | while (I < E) { | ||
| 1796 | uint64_t Delta = Offsets[I] - Base; | ||
| 1797 | |||
| 1798 | // If it is too far, it cannot be folded. | ||
| 1799 | if (Delta >= NBits * Wordsize) | ||
| 1800 | break; | ||
| 1801 | |||
| 1802 | // If it is not a multiple of wordsize away, it cannot be folded. | ||
| 1803 | if (Delta % Wordsize) | ||
| 1804 | break; | ||
| 1805 | |||
| 1806 | // Fold it. | ||
| 1807 | Bitmap |= 1ULL << (Delta / Wordsize); | ||
| 1808 | ++I; | ||
| 1809 | } | ||
| 1810 | |||
| 1811 | if (!Bitmap) | ||
| 1812 | break; | ||
| 1813 | |||
| 1814 | RelrRelocs.push_back(Elf_Relr((Bitmap << 1) | 1)); | ||
| 1815 | Base += NBits * Wordsize; | ||
| 1816 | } | ||
| 1817 | } | ||
| 1818 | |||
| 1819 | return RelrRelocs.size() != OldSize; | ||
| 1820 | } | ||
| 1821 | |||
| 1470 | SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec) | 1822 | SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec) |
| 1471 | : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0, | 1823 | : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0, |
| 1472 | StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB, | 1824 | StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB, |
| ... | @@ -1482,50 +1834,70 @@ SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec) | ... | @@ -1482,50 +1834,70 @@ SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec) |
| 1482 | static bool sortMipsSymbols(const SymbolTableEntry &L, | 1834 | static bool sortMipsSymbols(const SymbolTableEntry &L, |
| 1483 | const SymbolTableEntry &R) { | 1835 | const SymbolTableEntry &R) { |
| 1484 | // Sort entries related to non-local preemptible symbols by GOT indexes. | 1836 | // Sort entries related to non-local preemptible symbols by GOT indexes. |
| 1485 | // All other entries go to the first part of GOT in arbitrary order. | 1837 | // All other entries go to the beginning of a dynsym in arbitrary order. |
| 1486 | bool LIsInLocalGot = !L.Sym->IsInGlobalMipsGot; | 1838 | if (L.Sym->isInGot() && R.Sym->isInGot()) |
| 1487 | bool RIsInLocalGot = !R.Sym->IsInGlobalMipsGot; | 1839 | return L.Sym->GotIndex < R.Sym->GotIndex; |
| 1488 | if (LIsInLocalGot || RIsInLocalGot) | 1840 | if (!L.Sym->isInGot() && !R.Sym->isInGot()) |
| 1489 | return !RIsInLocalGot; | 1841 | return false; |
| 1490 | return L.Sym->GotIndex < R.Sym->GotIndex; | 1842 | return !L.Sym->isInGot(); |
| 1491 | } | 1843 | } |
| 1492 | 1844 | ||
| 1493 | void SymbolTableBaseSection::finalizeContents() { | 1845 | void SymbolTableBaseSection::finalizeContents() { |
| 1494 | getParent()->Link = StrTabSec.getParent()->SectionIndex; | 1846 | getParent()->Link = StrTabSec.getParent()->SectionIndex; |
| 1495 | 1847 | ||
| 1848 | if (this->Type != SHT_DYNSYM) | ||
| 1849 | return; | ||
| 1850 | |||
| 1496 | // If it is a .dynsym, there should be no local symbols, but we need | 1851 | // If it is a .dynsym, there should be no local symbols, but we need |
| 1497 | // to do a few things for the dynamic linker. | 1852 | // to do a few things for the dynamic linker. |
| 1498 | if (this->Type == SHT_DYNSYM) { | ||
| 1499 | // Section's Info field has the index of the first non-local symbol. | ||
| 1500 | // Because the first symbol entry is a null entry, 1 is the first. | ||
| 1501 | getParent()->Info = 1; | ||
| 1502 | |||
| 1503 | if (InX::GnuHashTab) { | ||
| 1504 | // NB: It also sorts Symbols to meet the GNU hash table requirements. | ||
| 1505 | InX::GnuHashTab->addSymbols(Symbols); | ||
| 1506 | } else if (Config->EMachine == EM_MIPS) { | ||
| 1507 | std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols); | ||
| 1508 | } | ||
| 1509 | 1853 | ||
| 1510 | size_t I = 0; | 1854 | // Section's Info field has the index of the first non-local symbol. |
| 1511 | for (const SymbolTableEntry &S : Symbols) S.Sym->DynsymIndex = ++I; | 1855 | // Because the first symbol entry is a null entry, 1 is the first. |
| 1512 | return; | 1856 | getParent()->Info = 1; |
| 1857 | |||
| 1858 | if (InX::GnuHashTab) { | ||
| 1859 | // NB: It also sorts Symbols to meet the GNU hash table requirements. | ||
| 1860 | InX::GnuHashTab->addSymbols(Symbols); | ||
| 1861 | } else if (Config->EMachine == EM_MIPS) { | ||
| 1862 | std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols); | ||
| 1513 | } | 1863 | } |
| 1864 | |||
| 1865 | size_t I = 0; | ||
| 1866 | for (const SymbolTableEntry &S : Symbols) | ||
| 1867 | S.Sym->DynsymIndex = ++I; | ||
| 1514 | } | 1868 | } |
| 1515 | 1869 | ||
| 1516 | // The ELF spec requires that all local symbols precede global symbols, so we | 1870 | // The ELF spec requires that all local symbols precede global symbols, so we |
| 1517 | // sort symbol entries in this function. (For .dynsym, we don't do that because | 1871 | // sort symbol entries in this function. (For .dynsym, we don't do that because |
| 1518 | // symbols for dynamic linking are inherently all globals.) | 1872 | // symbols for dynamic linking are inherently all globals.) |
| 1873 | // | ||
| 1874 | // Aside from above, we put local symbols in groups starting with the STT_FILE | ||
| 1875 | // symbol. That is convenient for purpose of identifying where are local symbols | ||
| 1876 | // coming from. | ||
| 1519 | void SymbolTableBaseSection::postThunkContents() { | 1877 | void SymbolTableBaseSection::postThunkContents() { |
| 1520 | if (this->Type == SHT_DYNSYM) | 1878 | assert(this->Type == SHT_SYMTAB); |
| 1521 | return; | 1879 | |
| 1522 | // move all local symbols before global symbols. | 1880 | // Move all local symbols before global symbols. |
| 1523 | auto It = std::stable_partition( | 1881 | auto E = std::stable_partition( |
| 1524 | Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) { | 1882 | Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) { |
| 1525 | return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL; | 1883 | return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL; |
| 1526 | }); | 1884 | }); |
| 1527 | size_t NumLocals = It - Symbols.begin(); | 1885 | size_t NumLocals = E - Symbols.begin(); |
| 1528 | getParent()->Info = NumLocals + 1; | 1886 | getParent()->Info = NumLocals + 1; |
| 1887 | |||
| 1888 | // We want to group the local symbols by file. For that we rebuild the local | ||
| 1889 | // part of the symbols vector. We do not need to care about the STT_FILE | ||
| 1890 | // symbols, they are already naturally placed first in each group. That | ||
| 1891 | // happens because STT_FILE is always the first symbol in the object and hence | ||
| 1892 | // precede all other local symbols we add for a file. | ||
| 1893 | MapVector<InputFile *, std::vector<SymbolTableEntry>> Arr; | ||
| 1894 | for (const SymbolTableEntry &S : llvm::make_range(Symbols.begin(), E)) | ||
| 1895 | Arr[S.Sym->File].push_back(S); | ||
| 1896 | |||
| 1897 | auto I = Symbols.begin(); | ||
| 1898 | for (std::pair<InputFile *, std::vector<SymbolTableEntry>> &P : Arr) | ||
| 1899 | for (SymbolTableEntry &Entry : P.second) | ||
| 1900 | *I++ = Entry; | ||
| 1529 | } | 1901 | } |
| 1530 | 1902 | ||
| 1531 | void SymbolTableBaseSection::addSymbol(Symbol *B) { | 1903 | void SymbolTableBaseSection::addSymbol(Symbol *B) { |
| ... | @@ -1563,6 +1935,23 @@ SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec) | ... | @@ -1563,6 +1935,23 @@ SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec) |
| 1563 | this->Entsize = sizeof(Elf_Sym); | 1935 | this->Entsize = sizeof(Elf_Sym); |
| 1564 | } | 1936 | } |
| 1565 | 1937 | ||
| 1938 | static BssSection *getCommonSec(Symbol *Sym) { | ||
| 1939 | if (!Config->DefineCommon) | ||
| 1940 | if (auto *D = dyn_cast<Defined>(Sym)) | ||
| 1941 | return dyn_cast_or_null<BssSection>(D->Section); | ||
| 1942 | return nullptr; | ||
| 1943 | } | ||
| 1944 | |||
| 1945 | static uint32_t getSymSectionIndex(Symbol *Sym) { | ||
| 1946 | if (getCommonSec(Sym)) | ||
| 1947 | return SHN_COMMON; | ||
| 1948 | if (!isa<Defined>(Sym) || Sym->NeedsPltAddr) | ||
| 1949 | return SHN_UNDEF; | ||
| 1950 | if (const OutputSection *OS = Sym->getOutputSection()) | ||
| 1951 | return OS->SectionIndex >= SHN_LORESERVE ? SHN_XINDEX : OS->SectionIndex; | ||
| 1952 | return SHN_ABS; | ||
| 1953 | } | ||
| 1954 | |||
| 1566 | // Write the internal symbol table contents to the output symbol table. | 1955 | // Write the internal symbol table contents to the output symbol table. |
| 1567 | template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { | 1956 | template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1568 | // The first entry is a null entry as per the ELF spec. | 1957 | // The first entry is a null entry as per the ELF spec. |
| ... | @@ -1584,20 +1973,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { | ... | @@ -1584,20 +1973,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1584 | } | 1973 | } |
| 1585 | 1974 | ||
| 1586 | ESym->st_name = Ent.StrTabOffset; | 1975 | ESym->st_name = Ent.StrTabOffset; |
| 1587 | 1976 | ESym->st_shndx = getSymSectionIndex(Ent.Sym); | |
| 1588 | // Set a section index. | ||
| 1589 | BssSection *CommonSec = nullptr; | ||
| 1590 | if (!Config->DefineCommon) | ||
| 1591 | if (auto *D = dyn_cast<Defined>(Sym)) | ||
| 1592 | CommonSec = dyn_cast_or_null<BssSection>(D->Section); | ||
| 1593 | if (CommonSec) | ||
| 1594 | ESym->st_shndx = SHN_COMMON; | ||
| 1595 | else if (const OutputSection *OutSec = Sym->getOutputSection()) | ||
| 1596 | ESym->st_shndx = OutSec->SectionIndex; | ||
| 1597 | else if (isa<Defined>(Sym)) | ||
| 1598 | ESym->st_shndx = SHN_ABS; | ||
| 1599 | else | ||
| 1600 | ESym->st_shndx = SHN_UNDEF; | ||
| 1601 | 1977 | ||
| 1602 | // Copy symbol size if it is a defined symbol. st_size is not significant | 1978 | // Copy symbol size if it is a defined symbol. st_size is not significant |
| 1603 | // for undefined symbols, so whether copying it or not is up to us if that's | 1979 | // for undefined symbols, so whether copying it or not is up to us if that's |
| ... | @@ -1612,7 +1988,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { | ... | @@ -1612,7 +1988,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1612 | // st_value is usually an address of a symbol, but that has a | 1988 | // st_value is usually an address of a symbol, but that has a |
| 1613 | // special meaining for uninstantiated common symbols (this can | 1989 | // special meaining for uninstantiated common symbols (this can |
| 1614 | // occur if -r is given). | 1990 | // occur if -r is given). |
| 1615 | if (CommonSec) | 1991 | if (BssSection *CommonSec = getCommonSec(Ent.Sym)) |
| 1616 | ESym->st_value = CommonSec->Alignment; | 1992 | ESym->st_value = CommonSec->Alignment; |
| 1617 | else | 1993 | else |
| 1618 | ESym->st_value = Sym->getVA(); | 1994 | ESym->st_value = Sym->getVA(); |
| ... | @@ -1633,9 +2009,11 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { | ... | @@ -1633,9 +2009,11 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1633 | ESym->st_other |= STO_MIPS_PLT; | 2009 | ESym->st_other |= STO_MIPS_PLT; |
| 1634 | if (isMicroMips()) { | 2010 | if (isMicroMips()) { |
| 1635 | // Set STO_MIPS_MICROMIPS flag and less-significant bit for | 2011 | // Set STO_MIPS_MICROMIPS flag and less-significant bit for |
| 1636 | // defined microMIPS symbols and shared symbols with PLT record. | 2012 | // a defined microMIPS symbol and symbol should point to its |
| 1637 | if ((Sym->isDefined() && (Sym->StOther & STO_MIPS_MICROMIPS)) || | 2013 | // PLT entry (in case of microMIPS, PLT entries always contain |
| 1638 | (Sym->isShared() && Sym->NeedsPltAddr)) { | 2014 | // microMIPS code). |
| 2015 | if (Sym->isDefined() && | ||
| 2016 | ((Sym->StOther & STO_MIPS_MICROMIPS) || Sym->NeedsPltAddr)) { | ||
| 1639 | if (StrTabSec.isDynamic()) | 2017 | if (StrTabSec.isDynamic()) |
| 1640 | ESym->st_value |= 1; | 2018 | ESym->st_value |= 1; |
| 1641 | ESym->st_other |= STO_MIPS_MICROMIPS; | 2019 | ESym->st_other |= STO_MIPS_MICROMIPS; |
| ... | @@ -1650,6 +2028,44 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { | ... | @@ -1650,6 +2028,44 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 1650 | } | 2028 | } |
| 1651 | } | 2029 | } |
| 1652 | 2030 | ||
| 2031 | SymtabShndxSection::SymtabShndxSection() | ||
| 2032 | : SyntheticSection(0, SHT_SYMTAB_SHNDX, 4, ".symtab_shndxr") { | ||
| 2033 | this->Entsize = 4; | ||
| 2034 | } | ||
| 2035 | |||
| 2036 | void SymtabShndxSection::writeTo(uint8_t *Buf) { | ||
| 2037 | // We write an array of 32 bit values, where each value has 1:1 association | ||
| 2038 | // with an entry in .symtab. If the corresponding entry contains SHN_XINDEX, | ||
| 2039 | // we need to write actual index, otherwise, we must write SHN_UNDEF(0). | ||
| 2040 | Buf += 4; // Ignore .symtab[0] entry. | ||
| 2041 | for (const SymbolTableEntry &Entry : InX::SymTab->getSymbols()) { | ||
| 2042 | if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX) | ||
| 2043 | write32(Buf, Entry.Sym->getOutputSection()->SectionIndex); | ||
| 2044 | Buf += 4; | ||
| 2045 | } | ||
| 2046 | } | ||
| 2047 | |||
| 2048 | bool SymtabShndxSection::empty() const { | ||
| 2049 | // SHT_SYMTAB can hold symbols with section indices values up to | ||
| 2050 | // SHN_LORESERVE. If we need more, we want to use extension SHT_SYMTAB_SHNDX | ||
| 2051 | // section. Problem is that we reveal the final section indices a bit too | ||
| 2052 | // late, and we do not know them here. For simplicity, we just always create | ||
| 2053 | // a .symtab_shndxr section when the amount of output sections is huge. | ||
| 2054 | size_t Size = 0; | ||
| 2055 | for (BaseCommand *Base : Script->SectionCommands) | ||
| 2056 | if (isa<OutputSection>(Base)) | ||
| 2057 | ++Size; | ||
| 2058 | return Size < SHN_LORESERVE; | ||
| 2059 | } | ||
| 2060 | |||
| 2061 | void SymtabShndxSection::finalizeContents() { | ||
| 2062 | getParent()->Link = InX::SymTab->getParent()->SectionIndex; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | size_t SymtabShndxSection::getSize() const { | ||
| 2066 | return InX::SymTab->getNumSymbols() * 4; | ||
| 2067 | } | ||
| 2068 | |||
| 1653 | // .hash and .gnu.hash sections contain on-disk hash tables that map | 2069 | // .hash and .gnu.hash sections contain on-disk hash tables that map |
| 1654 | // symbol names to their dynamic symbol table indices. Their purpose | 2070 | // symbol names to their dynamic symbol table indices. Their purpose |
| 1655 | // is to help the dynamic linker resolve symbols quickly. If ELF files | 2071 | // is to help the dynamic linker resolve symbols quickly. If ELF files |
| ... | @@ -1688,12 +2104,14 @@ GnuHashTableSection::GnuHashTableSection() | ... | @@ -1688,12 +2104,14 @@ GnuHashTableSection::GnuHashTableSection() |
| 1688 | void GnuHashTableSection::finalizeContents() { | 2104 | void GnuHashTableSection::finalizeContents() { |
| 1689 | getParent()->Link = InX::DynSymTab->getParent()->SectionIndex; | 2105 | getParent()->Link = InX::DynSymTab->getParent()->SectionIndex; |
| 1690 | 2106 | ||
| 1691 | // Computes bloom filter size in word size. We want to allocate 8 | 2107 | // Computes bloom filter size in word size. We want to allocate 12 |
| 1692 | // bits for each symbol. It must be a power of two. | 2108 | // bits for each symbol. It must be a power of two. |
| 1693 | if (Symbols.empty()) | 2109 | if (Symbols.empty()) { |
| 1694 | MaskWords = 1; | 2110 | MaskWords = 1; |
| 1695 | else | 2111 | } else { |
| 1696 | MaskWords = NextPowerOf2((Symbols.size() - 1) / Config->Wordsize); | 2112 | uint64_t NumBits = Symbols.size() * 12; |
| 2113 | MaskWords = NextPowerOf2(NumBits / (Config->Wordsize * 8)); | ||
| 2114 | } | ||
| 1697 | 2115 | ||
| 1698 | Size = 16; // Header | 2116 | Size = 16; // Header |
| 1699 | Size += Config->Wordsize * MaskWords; // Bloom filter | 2117 | Size += Config->Wordsize * MaskWords; // Bloom filter |
| ... | @@ -1711,7 +2129,7 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) { | ... | @@ -1711,7 +2129,7 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) { |
| 1711 | write32(Buf, NBuckets); | 2129 | write32(Buf, NBuckets); |
| 1712 | write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size()); | 2130 | write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size()); |
| 1713 | write32(Buf + 8, MaskWords); | 2131 | write32(Buf + 8, MaskWords); |
| 1714 | write32(Buf + 12, getShift2()); | 2132 | write32(Buf + 12, Shift2); |
| 1715 | Buf += 16; | 2133 | Buf += 16; |
| 1716 | 2134 | ||
| 1717 | // Write a bloom filter and a hash table. | 2135 | // Write a bloom filter and a hash table. |
| ... | @@ -1728,12 +2146,12 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) { | ... | @@ -1728,12 +2146,12 @@ void GnuHashTableSection::writeTo(uint8_t *Buf) { |
| 1728 | // [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2), | 2146 | // [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2), |
| 1729 | // p.9, https://www.akkadia.org/drepper/dsohowto.pdf | 2147 | // p.9, https://www.akkadia.org/drepper/dsohowto.pdf |
| 1730 | void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) { | 2148 | void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) { |
| 1731 | const unsigned C = Config->Wordsize * 8; | 2149 | unsigned C = Config->Is64 ? 64 : 32; |
| 1732 | for (const Entry &Sym : Symbols) { | 2150 | for (const Entry &Sym : Symbols) { |
| 1733 | size_t I = (Sym.Hash / C) & (MaskWords - 1); | 2151 | size_t I = (Sym.Hash / C) & (MaskWords - 1); |
| 1734 | uint64_t Val = readUint(Buf + I * Config->Wordsize); | 2152 | uint64_t Val = readUint(Buf + I * Config->Wordsize); |
| 1735 | Val |= uint64_t(1) << (Sym.Hash % C); | 2153 | Val |= uint64_t(1) << (Sym.Hash % C); |
| 1736 | Val |= uint64_t(1) << ((Sym.Hash >> getShift2()) % C); | 2154 | Val |= uint64_t(1) << ((Sym.Hash >> Shift2) % C); |
| 1737 | writeUint(Buf + I * Config->Wordsize, Val); | 2155 | writeUint(Buf + I * Config->Wordsize, Val); |
| 1738 | } | 2156 | } |
| 1739 | } | 2157 | } |
| ... | @@ -1775,21 +2193,23 @@ void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) { | ... | @@ -1775,21 +2193,23 @@ void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) { |
| 1775 | // its type correctly. | 2193 | // its type correctly. |
| 1776 | std::vector<SymbolTableEntry>::iterator Mid = | 2194 | std::vector<SymbolTableEntry>::iterator Mid = |
| 1777 | std::stable_partition(V.begin(), V.end(), [](const SymbolTableEntry &S) { | 2195 | std::stable_partition(V.begin(), V.end(), [](const SymbolTableEntry &S) { |
| 1778 | // Shared symbols that this executable preempts are special. The dynamic | ||
| 1779 | // linker has to look them up, so they have to be in the hash table. | ||
| 1780 | if (auto *SS = dyn_cast<SharedSymbol>(S.Sym)) | ||
| 1781 | return SS->CopyRelSec == nullptr && !SS->NeedsPltAddr; | ||
| 1782 | return !S.Sym->isDefined(); | 2196 | return !S.Sym->isDefined(); |
| 1783 | }); | 2197 | }); |
| 1784 | if (Mid == V.end()) | ||
| 1785 | return; | ||
| 1786 | 2198 | ||
| 1787 | // We chose load factor 4 for the on-disk hash table. For each hash | 2199 | // We chose load factor 4 for the on-disk hash table. For each hash |
| 1788 | // collision, the dynamic linker will compare a uint32_t hash value. | 2200 | // collision, the dynamic linker will compare a uint32_t hash value. |
| 1789 | // Since the integer comparison is quite fast, we believe we can make | 2201 | // Since the integer comparison is quite fast, we believe we can |
| 1790 | // the load factor even larger. 4 is just a conservative choice. | 2202 | // make the load factor even larger. 4 is just a conservative choice. |
| 2203 | // | ||
| 2204 | // Note that we don't want to create a zero-sized hash table because | ||
| 2205 | // Android loader as of 2018 doesn't like a .gnu.hash containing such | ||
| 2206 | // table. If that's the case, we create a hash table with one unused | ||
| 2207 | // dummy slot. | ||
| 1791 | NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1); | 2208 | NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1); |
| 1792 | 2209 | ||
| 2210 | if (Mid == V.end()) | ||
| 2211 | return; | ||
| 2212 | |||
| 1793 | for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) { | 2213 | for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) { |
| 1794 | Symbol *B = Ent.Sym; | 2214 | Symbol *B = Ent.Sym; |
| 1795 | uint32_t Hash = hashGnu(B->getName()); | 2215 | uint32_t Hash = hashGnu(B->getName()); |
| ... | @@ -1845,9 +2265,12 @@ void HashTableSection::writeTo(uint8_t *Buf) { | ... | @@ -1845,9 +2265,12 @@ void HashTableSection::writeTo(uint8_t *Buf) { |
| 1845 | } | 2265 | } |
| 1846 | } | 2266 | } |
| 1847 | 2267 | ||
| 1848 | PltSection::PltSection(size_t S) | 2268 | // On PowerPC64 the lazy symbol resolvers go into the `global linkage table` |
| 1849 | : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"), | 2269 | // in the .glink section, rather then the typical .plt section. |
| 1850 | HeaderSize(S) { | 2270 | PltSection::PltSection(bool IsIplt) |
| 2271 | : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, | ||
| 2272 | Config->EMachine == EM_PPC64 ? ".glink" : ".plt"), | ||
| 2273 | HeaderSize(IsIplt ? 0 : Target->PltHeaderSize), IsIplt(IsIplt) { | ||
| 1851 | // The PLT needs to be writable on SPARC as the dynamic linker will | 2274 | // The PLT needs to be writable on SPARC as the dynamic linker will |
| 1852 | // modify the instructions in the PLT entries. | 2275 | // modify the instructions in the PLT entries. |
| 1853 | if (Config->EMachine == EM_SPARCV9) | 2276 | if (Config->EMachine == EM_SPARCV9) |
| ... | @@ -1857,7 +2280,7 @@ PltSection::PltSection(size_t S) | ... | @@ -1857,7 +2280,7 @@ PltSection::PltSection(size_t S) |
| 1857 | void PltSection::writeTo(uint8_t *Buf) { | 2280 | void PltSection::writeTo(uint8_t *Buf) { |
| 1858 | // At beginning of PLT but not the IPLT, we have code to call the dynamic | 2281 | // At beginning of PLT but not the IPLT, we have code to call the dynamic |
| 1859 | // linker to resolve dynsyms at runtime. Write such code. | 2282 | // linker to resolve dynsyms at runtime. Write such code. |
| 1860 | if (HeaderSize != 0) | 2283 | if (!IsIplt) |
| 1861 | Target->writePltHeader(Buf); | 2284 | Target->writePltHeader(Buf); |
| 1862 | size_t Off = HeaderSize; | 2285 | size_t Off = HeaderSize; |
| 1863 | // The IPlt is immediately after the Plt, account for this in RelOff | 2286 | // The IPlt is immediately after the Plt, account for this in RelOff |
| ... | @@ -1876,7 +2299,7 @@ void PltSection::writeTo(uint8_t *Buf) { | ... | @@ -1876,7 +2299,7 @@ void PltSection::writeTo(uint8_t *Buf) { |
| 1876 | template <class ELFT> void PltSection::addEntry(Symbol &Sym) { | 2299 | template <class ELFT> void PltSection::addEntry(Symbol &Sym) { |
| 1877 | Sym.PltIndex = Entries.size(); | 2300 | Sym.PltIndex = Entries.size(); |
| 1878 | RelocationBaseSection *PltRelocSection = InX::RelaPlt; | 2301 | RelocationBaseSection *PltRelocSection = InX::RelaPlt; |
| 1879 | if (HeaderSize == 0) { | 2302 | if (IsIplt) { |
| 1880 | PltRelocSection = InX::RelaIplt; | 2303 | PltRelocSection = InX::RelaIplt; |
| 1881 | Sym.IsInIplt = true; | 2304 | Sym.IsInIplt = true; |
| 1882 | } | 2305 | } |
| ... | @@ -1893,7 +2316,7 @@ size_t PltSection::getSize() const { | ... | @@ -1893,7 +2316,7 @@ size_t PltSection::getSize() const { |
| 1893 | // example ARM uses mapping symbols to aid disassembly | 2316 | // example ARM uses mapping symbols to aid disassembly |
| 1894 | void PltSection::addSymbols() { | 2317 | void PltSection::addSymbols() { |
| 1895 | // The PLT may have symbols defined for the Header, the IPLT has no header | 2318 | // The PLT may have symbols defined for the Header, the IPLT has no header |
| 1896 | if (HeaderSize != 0) | 2319 | if (!IsIplt) |
| 1897 | Target->addPltHeaderSymbols(*this); | 2320 | Target->addPltHeaderSymbols(*this); |
| 1898 | size_t Off = HeaderSize; | 2321 | size_t Off = HeaderSize; |
| 1899 | for (size_t I = 0; I < Entries.size(); ++I) { | 2322 | for (size_t I = 0; I < Entries.size(); ++I) { |
| ... | @@ -1903,7 +2326,7 @@ void PltSection::addSymbols() { | ... | @@ -1903,7 +2326,7 @@ void PltSection::addSymbols() { |
| 1903 | } | 2326 | } |
| 1904 | 2327 | ||
| 1905 | unsigned PltSection::getPltRelocOff() const { | 2328 | unsigned PltSection::getPltRelocOff() const { |
| 1906 | return (HeaderSize == 0) ? InX::Plt->getSize() : 0; | 2329 | return IsIplt ? InX::Plt->getSize() : 0; |
| 1907 | } | 2330 | } |
| 1908 | 2331 | ||
| 1909 | // The string hash function for .gdb_index. | 2332 | // The string hash function for .gdb_index. |
| ... | @@ -1914,16 +2337,48 @@ static uint32_t computeGdbHash(StringRef S) { | ... | @@ -1914,16 +2337,48 @@ static uint32_t computeGdbHash(StringRef S) { |
| 1914 | return H; | 2337 | return H; |
| 1915 | } | 2338 | } |
| 1916 | 2339 | ||
| 1917 | static std::vector<GdbIndexChunk::CuEntry> readCuList(DWARFContext &Dwarf) { | 2340 | GdbIndexSection::GdbIndexSection() |
| 1918 | std::vector<GdbIndexChunk::CuEntry> Ret; | 2341 | : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index") {} |
| 2342 | |||
| 2343 | // Returns the desired size of an on-disk hash table for a .gdb_index section. | ||
| 2344 | // There's a tradeoff between size and collision rate. We aim 75% utilization. | ||
| 2345 | size_t GdbIndexSection::computeSymtabSize() const { | ||
| 2346 | return std::max<size_t>(NextPowerOf2(Symbols.size() * 4 / 3), 1024); | ||
| 2347 | } | ||
| 2348 | |||
| 2349 | // Compute the output section size. | ||
| 2350 | void GdbIndexSection::initOutputSize() { | ||
| 2351 | Size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8; | ||
| 2352 | |||
| 2353 | for (GdbChunk &Chunk : Chunks) | ||
| 2354 | Size += Chunk.CompilationUnits.size() * 16 + Chunk.AddressAreas.size() * 20; | ||
| 2355 | |||
| 2356 | // Add the constant pool size if exists. | ||
| 2357 | if (!Symbols.empty()) { | ||
| 2358 | GdbSymbol &Sym = Symbols.back(); | ||
| 2359 | Size += Sym.NameOff + Sym.Name.size() + 1; | ||
| 2360 | } | ||
| 2361 | } | ||
| 2362 | |||
| 2363 | static std::vector<InputSection *> getDebugInfoSections() { | ||
| 2364 | std::vector<InputSection *> Ret; | ||
| 2365 | for (InputSectionBase *S : InputSections) | ||
| 2366 | if (InputSection *IS = dyn_cast<InputSection>(S)) | ||
| 2367 | if (IS->Name == ".debug_info") | ||
| 2368 | Ret.push_back(IS); | ||
| 2369 | return Ret; | ||
| 2370 | } | ||
| 2371 | |||
| 2372 | static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &Dwarf) { | ||
| 2373 | std::vector<GdbIndexSection::CuEntry> Ret; | ||
| 1919 | for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units()) | 2374 | for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units()) |
| 1920 | Ret.push_back({Cu->getOffset(), Cu->getLength() + 4}); | 2375 | Ret.push_back({Cu->getOffset(), Cu->getLength() + 4}); |
| 1921 | return Ret; | 2376 | return Ret; |
| 1922 | } | 2377 | } |
| 1923 | 2378 | ||
| 1924 | static std::vector<GdbIndexChunk::AddressEntry> | 2379 | static std::vector<GdbIndexSection::AddressEntry> |
| 1925 | readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) { | 2380 | readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) { |
| 1926 | std::vector<GdbIndexChunk::AddressEntry> Ret; | 2381 | std::vector<GdbIndexSection::AddressEntry> Ret; |
| 1927 | 2382 | ||
| 1928 | uint32_t CuIdx = 0; | 2383 | uint32_t CuIdx = 0; |
| 1929 | for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units()) { | 2384 | for (std::unique_ptr<DWARFCompileUnit> &Cu : Dwarf.compile_units()) { |
| ... | @@ -1947,218 +2402,192 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) { | ... | @@ -1947,218 +2402,192 @@ readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) { |
| 1947 | return Ret; | 2402 | return Ret; |
| 1948 | } | 2403 | } |
| 1949 | 2404 | ||
| 1950 | static std::vector<GdbIndexChunk::NameTypeEntry> | 2405 | static std::vector<GdbIndexSection::NameTypeEntry> |
| 1951 | readPubNamesAndTypes(DWARFContext &Dwarf) { | 2406 | readPubNamesAndTypes(DWARFContext &Dwarf, uint32_t Idx) { |
| 1952 | StringRef Sec1 = Dwarf.getDWARFObj().getGnuPubNamesSection(); | 2407 | StringRef Sec1 = Dwarf.getDWARFObj().getGnuPubNamesSection(); |
| 1953 | StringRef Sec2 = Dwarf.getDWARFObj().getGnuPubTypesSection(); | 2408 | StringRef Sec2 = Dwarf.getDWARFObj().getGnuPubTypesSection(); |
| 1954 | 2409 | ||
| 1955 | std::vector<GdbIndexChunk::NameTypeEntry> Ret; | 2410 | std::vector<GdbIndexSection::NameTypeEntry> Ret; |
| 1956 | for (StringRef Sec : {Sec1, Sec2}) { | 2411 | for (StringRef Sec : {Sec1, Sec2}) { |
| 1957 | DWARFDebugPubTable Table(Sec, Config->IsLE, true); | 2412 | DWARFDebugPubTable Table(Sec, Config->IsLE, true); |
| 1958 | for (const DWARFDebugPubTable::Set &Set : Table.getData()) { | 2413 | for (const DWARFDebugPubTable::Set &Set : Table.getData()) |
| 1959 | for (const DWARFDebugPubTable::Entry &Ent : Set.Entries) { | 2414 | for (const DWARFDebugPubTable::Entry &Ent : Set.Entries) |
| 1960 | CachedHashStringRef S(Ent.Name, computeGdbHash(Ent.Name)); | 2415 | Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)}, |
| 1961 | Ret.push_back({S, Ent.Descriptor.toBits()}); | 2416 | (Ent.Descriptor.toBits() << 24) | Idx}); |
| 1962 | } | ||
| 1963 | } | ||
| 1964 | } | 2417 | } |
| 1965 | return Ret; | 2418 | return Ret; |
| 1966 | } | 2419 | } |
| 1967 | 2420 | ||
| 1968 | static std::vector<InputSection *> getDebugInfoSections() { | 2421 | // Create a list of symbols from a given list of symbol names and types |
| 1969 | std::vector<InputSection *> Ret; | 2422 | // by uniquifying them by name. |
| 1970 | for (InputSectionBase *S : InputSections) | 2423 | static std::vector<GdbIndexSection::GdbSymbol> |
| 1971 | if (InputSection *IS = dyn_cast<InputSection>(S)) | 2424 | createSymbols(ArrayRef<std::vector<GdbIndexSection::NameTypeEntry>> NameTypes) { |
| 1972 | if (IS->Name == ".debug_info") | 2425 | typedef GdbIndexSection::GdbSymbol GdbSymbol; |
| 1973 | Ret.push_back(IS); | 2426 | typedef GdbIndexSection::NameTypeEntry NameTypeEntry; |
| 1974 | return Ret; | ||
| 1975 | } | ||
| 1976 | 2427 | ||
| 1977 | void GdbIndexSection::fixCuIndex() { | 2428 | // The number of symbols we will handle in this function is of the order |
| 1978 | uint32_t Idx = 0; | 2429 | // of millions for very large executables, so we use multi-threading to |
| 1979 | for (GdbIndexChunk &Chunk : Chunks) { | 2430 | // speed it up. |
| 1980 | for (GdbIndexChunk::AddressEntry &Ent : Chunk.AddressAreas) | 2431 | size_t NumShards = 32; |
| 1981 | Ent.CuIndex += Idx; | 2432 | size_t Concurrency = 1; |
| 1982 | Idx += Chunk.CompilationUnits.size(); | 2433 | if (ThreadsEnabled) |
| 1983 | } | 2434 | Concurrency = |
| 1984 | } | 2435 | std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards); |
| 1985 | 2436 | ||
| 1986 | std::vector<std::vector<uint32_t>> GdbIndexSection::createCuVectors() { | 2437 | // A sharded map to uniquify symbols by name. |
| 1987 | std::vector<std::vector<uint32_t>> Ret; | 2438 | std::vector<DenseMap<CachedHashStringRef, size_t>> Map(NumShards); |
| 1988 | uint32_t Idx = 0; | 2439 | size_t Shift = 32 - countTrailingZeros(NumShards); |
| 1989 | uint32_t Off = 0; | ||
| 1990 | 2440 | ||
| 1991 | for (GdbIndexChunk &Chunk : Chunks) { | 2441 | // Instantiate GdbSymbols while uniqufying them by name. |
| 1992 | for (GdbIndexChunk::NameTypeEntry &Ent : Chunk.NamesAndTypes) { | 2442 | std::vector<std::vector<GdbSymbol>> Symbols(NumShards); |
| 1993 | GdbSymbol *&Sym = Symbols[Ent.Name]; | 2443 | parallelForEachN(0, Concurrency, [&](size_t ThreadId) { |
| 1994 | if (!Sym) { | 2444 | for (ArrayRef<NameTypeEntry> Entries : NameTypes) { |
| 1995 | Sym = make<GdbSymbol>(GdbSymbol{Ent.Name.hash(), Off, Ret.size()}); | 2445 | for (const NameTypeEntry &Ent : Entries) { |
| 1996 | Off += Ent.Name.size() + 1; | 2446 | size_t ShardId = Ent.Name.hash() >> Shift; |
| 1997 | Ret.push_back({}); | 2447 | if ((ShardId & (Concurrency - 1)) != ThreadId) |
| 1998 | } | 2448 | continue; |
| 2449 | |||
| 2450 | size_t &Idx = Map[ShardId][Ent.Name]; | ||
| 2451 | if (Idx) { | ||
| 2452 | Symbols[ShardId][Idx - 1].CuVector.push_back(Ent.Type); | ||
| 2453 | continue; | ||
| 2454 | } | ||
| 1999 | 2455 | ||
| 2000 | // gcc 5.4.1 produces a buggy .debug_gnu_pubnames that contains | 2456 | Idx = Symbols[ShardId].size() + 1; |
| 2001 | // duplicate entries, so we want to dedup them. | 2457 | Symbols[ShardId].push_back({Ent.Name, {Ent.Type}, 0, 0}); |
| 2002 | std::vector<uint32_t> &Vec = Ret[Sym->CuVectorIndex]; | 2458 | } |
| 2003 | uint32_t Val = (Ent.Type << 24) | Idx; | ||
| 2004 | if (Vec.empty() || Vec.back() != Val) | ||
| 2005 | Vec.push_back(Val); | ||
| 2006 | } | 2459 | } |
| 2007 | Idx += Chunk.CompilationUnits.size(); | 2460 | }); |
| 2461 | |||
| 2462 | size_t NumSymbols = 0; | ||
| 2463 | for (ArrayRef<GdbSymbol> V : Symbols) | ||
| 2464 | NumSymbols += V.size(); | ||
| 2465 | |||
| 2466 | // The return type is a flattened vector, so we'll copy each vector | ||
| 2467 | // contents to Ret. | ||
| 2468 | std::vector<GdbSymbol> Ret; | ||
| 2469 | Ret.reserve(NumSymbols); | ||
| 2470 | for (std::vector<GdbSymbol> &Vec : Symbols) | ||
| 2471 | for (GdbSymbol &Sym : Vec) | ||
| 2472 | Ret.push_back(std::move(Sym)); | ||
| 2473 | |||
| 2474 | // CU vectors and symbol names are adjacent in the output file. | ||
| 2475 | // We can compute their offsets in the output file now. | ||
| 2476 | size_t Off = 0; | ||
| 2477 | for (GdbSymbol &Sym : Ret) { | ||
| 2478 | Sym.CuVectorOff = Off; | ||
| 2479 | Off += (Sym.CuVector.size() + 1) * 4; | ||
| 2480 | } | ||
| 2481 | for (GdbSymbol &Sym : Ret) { | ||
| 2482 | Sym.NameOff = Off; | ||
| 2483 | Off += Sym.Name.size() + 1; | ||
| 2008 | } | 2484 | } |
| 2009 | 2485 | ||
| 2010 | StringPoolSize = Off; | ||
| 2011 | return Ret; | 2486 | return Ret; |
| 2012 | } | 2487 | } |
| 2013 | 2488 | ||
| 2014 | template <class ELFT> GdbIndexSection *elf::createGdbIndex() { | 2489 | // Returns a newly-created .gdb_index section. |
| 2015 | // Gather debug info to create a .gdb_index section. | 2490 | template <class ELFT> GdbIndexSection *GdbIndexSection::create() { |
| 2016 | std::vector<InputSection *> Sections = getDebugInfoSections(); | 2491 | std::vector<InputSection *> Sections = getDebugInfoSections(); |
| 2017 | std::vector<GdbIndexChunk> Chunks(Sections.size()); | ||
| 2018 | |||
| 2019 | parallelForEachN(0, Chunks.size(), [&](size_t I) { | ||
| 2020 | ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>(); | ||
| 2021 | DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(File)); | ||
| 2022 | |||
| 2023 | Chunks[I].DebugInfoSec = Sections[I]; | ||
| 2024 | Chunks[I].CompilationUnits = readCuList(Dwarf); | ||
| 2025 | Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]); | ||
| 2026 | Chunks[I].NamesAndTypes = readPubNamesAndTypes(Dwarf); | ||
| 2027 | }); | ||
| 2028 | 2492 | ||
| 2029 | // .debug_gnu_pub{names,types} are useless in executables. | 2493 | // .debug_gnu_pub{names,types} are useless in executables. |
| 2030 | // They are present in input object files solely for creating | 2494 | // They are present in input object files solely for creating |
| 2031 | // a .gdb_index. So we can remove it from the output. | 2495 | // a .gdb_index. So we can remove them from the output. |
| 2032 | for (InputSectionBase *S : InputSections) | 2496 | for (InputSectionBase *S : InputSections) |
| 2033 | if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes") | 2497 | if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes") |
| 2034 | S->Live = false; | 2498 | S->Live = false; |
| 2035 | 2499 | ||
| 2036 | // Create a .gdb_index and returns it. | 2500 | std::vector<GdbChunk> Chunks(Sections.size()); |
| 2037 | return make<GdbIndexSection>(std::move(Chunks)); | 2501 | std::vector<std::vector<NameTypeEntry>> NameTypes(Sections.size()); |
| 2038 | } | ||
| 2039 | |||
| 2040 | static size_t getCuSize(ArrayRef<GdbIndexChunk> Arr) { | ||
| 2041 | size_t Ret = 0; | ||
| 2042 | for (const GdbIndexChunk &D : Arr) | ||
| 2043 | Ret += D.CompilationUnits.size(); | ||
| 2044 | return Ret; | ||
| 2045 | } | ||
| 2046 | |||
| 2047 | static size_t getAddressAreaSize(ArrayRef<GdbIndexChunk> Arr) { | ||
| 2048 | size_t Ret = 0; | ||
| 2049 | for (const GdbIndexChunk &D : Arr) | ||
| 2050 | Ret += D.AddressAreas.size(); | ||
| 2051 | return Ret; | ||
| 2052 | } | ||
| 2053 | 2502 | ||
| 2054 | std::vector<GdbSymbol *> GdbIndexSection::createGdbSymtab() { | 2503 | parallelForEachN(0, Sections.size(), [&](size_t I) { |
| 2055 | uint32_t Size = NextPowerOf2(Symbols.size() * 4 / 3); | 2504 | ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>(); |
| 2056 | if (Size < 1024) | 2505 | DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(File)); |
| 2057 | Size = 1024; | ||
| 2058 | |||
| 2059 | uint32_t Mask = Size - 1; | ||
| 2060 | std::vector<GdbSymbol *> Ret(Size); | ||
| 2061 | 2506 | ||
| 2062 | for (auto &KV : Symbols) { | 2507 | Chunks[I].Sec = Sections[I]; |
| 2063 | GdbSymbol *Sym = KV.second; | 2508 | Chunks[I].CompilationUnits = readCuList(Dwarf); |
| 2064 | uint32_t I = Sym->NameHash & Mask; | 2509 | Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]); |
| 2065 | uint32_t Step = ((Sym->NameHash * 17) & Mask) | 1; | 2510 | NameTypes[I] = readPubNamesAndTypes(Dwarf, I); |
| 2511 | }); | ||
| 2066 | 2512 | ||
| 2067 | while (Ret[I]) | 2513 | auto *Ret = make<GdbIndexSection>(); |
| 2068 | I = (I + Step) & Mask; | 2514 | Ret->Chunks = std::move(Chunks); |
| 2069 | Ret[I] = Sym; | 2515 | Ret->Symbols = createSymbols(NameTypes); |
| 2070 | } | 2516 | Ret->initOutputSize(); |
| 2071 | return Ret; | 2517 | return Ret; |
| 2072 | } | 2518 | } |
| 2073 | 2519 | ||
| 2074 | GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&C) | ||
| 2075 | : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"), Chunks(std::move(C)) { | ||
| 2076 | fixCuIndex(); | ||
| 2077 | CuVectors = createCuVectors(); | ||
| 2078 | GdbSymtab = createGdbSymtab(); | ||
| 2079 | |||
| 2080 | // Compute offsets early to know the section size. | ||
| 2081 | // Each chunk size needs to be in sync with what we write in writeTo. | ||
| 2082 | CuTypesOffset = CuListOffset + getCuSize(Chunks) * 16; | ||
| 2083 | SymtabOffset = CuTypesOffset + getAddressAreaSize(Chunks) * 20; | ||
| 2084 | ConstantPoolOffset = SymtabOffset + GdbSymtab.size() * 8; | ||
| 2085 | |||
| 2086 | size_t Off = 0; | ||
| 2087 | for (ArrayRef<uint32_t> Vec : CuVectors) { | ||
| 2088 | CuVectorOffsets.push_back(Off); | ||
| 2089 | Off += (Vec.size() + 1) * 4; | ||
| 2090 | } | ||
| 2091 | StringPoolOffset = ConstantPoolOffset + Off; | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | size_t GdbIndexSection::getSize() const { | ||
| 2095 | return StringPoolOffset + StringPoolSize; | ||
| 2096 | } | ||
| 2097 | |||
| 2098 | void GdbIndexSection::writeTo(uint8_t *Buf) { | 2520 | void GdbIndexSection::writeTo(uint8_t *Buf) { |
| 2099 | // Write the section header. | 2521 | // Write the header. |
| 2100 | write32le(Buf, 7); | 2522 | auto *Hdr = reinterpret_cast<GdbIndexHeader *>(Buf); |
| 2101 | write32le(Buf + 4, CuListOffset); | 2523 | uint8_t *Start = Buf; |
| 2102 | write32le(Buf + 8, CuTypesOffset); | 2524 | Hdr->Version = 7; |
| 2103 | write32le(Buf + 12, CuTypesOffset); | 2525 | Buf += sizeof(*Hdr); |
| 2104 | write32le(Buf + 16, SymtabOffset); | ||
| 2105 | write32le(Buf + 20, ConstantPoolOffset); | ||
| 2106 | Buf += 24; | ||
| 2107 | 2526 | ||
| 2108 | // Write the CU list. | 2527 | // Write the CU list. |
| 2109 | for (GdbIndexChunk &D : Chunks) { | 2528 | Hdr->CuListOff = Buf - Start; |
| 2110 | for (GdbIndexChunk::CuEntry &Cu : D.CompilationUnits) { | 2529 | for (GdbChunk &Chunk : Chunks) { |
| 2111 | write64le(Buf, D.DebugInfoSec->OutSecOff + Cu.CuOffset); | 2530 | for (CuEntry &Cu : Chunk.CompilationUnits) { |
| 2531 | write64le(Buf, Chunk.Sec->OutSecOff + Cu.CuOffset); | ||
| 2112 | write64le(Buf + 8, Cu.CuLength); | 2532 | write64le(Buf + 8, Cu.CuLength); |
| 2113 | Buf += 16; | 2533 | Buf += 16; |
| 2114 | } | 2534 | } |
| 2115 | } | 2535 | } |
| 2116 | 2536 | ||
| 2117 | // Write the address area. | 2537 | // Write the address area. |
| 2118 | for (GdbIndexChunk &D : Chunks) { | 2538 | Hdr->CuTypesOff = Buf - Start; |
| 2119 | for (GdbIndexChunk::AddressEntry &E : D.AddressAreas) { | 2539 | Hdr->AddressAreaOff = Buf - Start; |
| 2120 | uint64_t BaseAddr = | 2540 | uint32_t CuOff = 0; |
| 2121 | E.Section->getParent()->Addr + E.Section->getOffset(0); | 2541 | for (GdbChunk &Chunk : Chunks) { |
| 2542 | for (AddressEntry &E : Chunk.AddressAreas) { | ||
| 2543 | uint64_t BaseAddr = E.Section->getVA(0); | ||
| 2122 | write64le(Buf, BaseAddr + E.LowAddress); | 2544 | write64le(Buf, BaseAddr + E.LowAddress); |
| 2123 | write64le(Buf + 8, BaseAddr + E.HighAddress); | 2545 | write64le(Buf + 8, BaseAddr + E.HighAddress); |
| 2124 | write32le(Buf + 16, E.CuIndex); | 2546 | write32le(Buf + 16, E.CuIndex + CuOff); |
| 2125 | Buf += 20; | 2547 | Buf += 20; |
| 2126 | } | 2548 | } |
| 2549 | CuOff += Chunk.CompilationUnits.size(); | ||
| 2127 | } | 2550 | } |
| 2128 | 2551 | ||
| 2129 | // Write the symbol table. | 2552 | // Write the on-disk open-addressing hash table containing symbols. |
| 2130 | for (GdbSymbol *Sym : GdbSymtab) { | 2553 | Hdr->SymtabOff = Buf - Start; |
| 2131 | if (Sym) { | 2554 | size_t SymtabSize = computeSymtabSize(); |
| 2132 | write32le(Buf, Sym->NameOffset + StringPoolOffset - ConstantPoolOffset); | 2555 | uint32_t Mask = SymtabSize - 1; |
| 2133 | write32le(Buf + 4, CuVectorOffsets[Sym->CuVectorIndex]); | 2556 | |
| 2134 | } | 2557 | for (GdbSymbol &Sym : Symbols) { |
| 2135 | Buf += 8; | 2558 | uint32_t H = Sym.Name.hash(); |
| 2559 | uint32_t I = H & Mask; | ||
| 2560 | uint32_t Step = ((H * 17) & Mask) | 1; | ||
| 2561 | |||
| 2562 | while (read32le(Buf + I * 8)) | ||
| 2563 | I = (I + Step) & Mask; | ||
| 2564 | |||
| 2565 | write32le(Buf + I * 8, Sym.NameOff); | ||
| 2566 | write32le(Buf + I * 8 + 4, Sym.CuVectorOff); | ||
| 2136 | } | 2567 | } |
| 2137 | 2568 | ||
| 2569 | Buf += SymtabSize * 8; | ||
| 2570 | |||
| 2571 | // Write the string pool. | ||
| 2572 | Hdr->ConstantPoolOff = Buf - Start; | ||
| 2573 | for (GdbSymbol &Sym : Symbols) | ||
| 2574 | memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size()); | ||
| 2575 | |||
| 2138 | // Write the CU vectors. | 2576 | // Write the CU vectors. |
| 2139 | for (ArrayRef<uint32_t> Vec : CuVectors) { | 2577 | for (GdbSymbol &Sym : Symbols) { |
| 2140 | write32le(Buf, Vec.size()); | 2578 | write32le(Buf, Sym.CuVector.size()); |
| 2141 | Buf += 4; | 2579 | Buf += 4; |
| 2142 | for (uint32_t Val : Vec) { | 2580 | for (uint32_t Val : Sym.CuVector) { |
| 2143 | write32le(Buf, Val); | 2581 | write32le(Buf, Val); |
| 2144 | Buf += 4; | 2582 | Buf += 4; |
| 2145 | } | 2583 | } |
| 2146 | } | 2584 | } |
| 2147 | |||
| 2148 | // Write the string pool. | ||
| 2149 | for (auto &KV : Symbols) { | ||
| 2150 | CachedHashStringRef S = KV.first; | ||
| 2151 | GdbSymbol *Sym = KV.second; | ||
| 2152 | size_t Off = Sym->NameOffset; | ||
| 2153 | memcpy(Buf + Off, S.val().data(), S.size()); | ||
| 2154 | Buf[Off + S.size()] = '\0'; | ||
| 2155 | } | ||
| 2156 | } | 2585 | } |
| 2157 | 2586 | ||
| 2158 | bool GdbIndexSection::empty() const { return !Out::DebugInfo; } | 2587 | bool GdbIndexSection::empty() const { return !Out::DebugInfo; } |
| 2159 | 2588 | ||
| 2160 | EhFrameHeader::EhFrameHeader() | 2589 | EhFrameHeader::EhFrameHeader() |
| 2161 | : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame_hdr") {} | 2590 | : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {} |
| 2162 | 2591 | ||
| 2163 | // .eh_frame_hdr contains a binary search table of pointers to FDEs. | 2592 | // .eh_frame_hdr contains a binary search table of pointers to FDEs. |
| 2164 | // Each entry of the search table consists of two values, | 2593 | // Each entry of the search table consists of two values, |
| ... | @@ -2169,14 +2598,6 @@ void EhFrameHeader::writeTo(uint8_t *Buf) { | ... | @@ -2169,14 +2598,6 @@ void EhFrameHeader::writeTo(uint8_t *Buf) { |
| 2169 | 2598 | ||
| 2170 | std::vector<FdeData> Fdes = InX::EhFrame->getFdeData(); | 2599 | std::vector<FdeData> Fdes = InX::EhFrame->getFdeData(); |
| 2171 | 2600 | ||
| 2172 | // Sort the FDE list by their PC and uniqueify. Usually there is only | ||
| 2173 | // one FDE for a PC (i.e. function), but if ICF merges two functions | ||
| 2174 | // into one, there can be more than one FDEs pointing to the address. | ||
| 2175 | auto Less = [](const FdeData &A, const FdeData &B) { return A.Pc < B.Pc; }; | ||
| 2176 | std::stable_sort(Fdes.begin(), Fdes.end(), Less); | ||
| 2177 | auto Eq = [](const FdeData &A, const FdeData &B) { return A.Pc == B.Pc; }; | ||
| 2178 | Fdes.erase(std::unique(Fdes.begin(), Fdes.end(), Eq), Fdes.end()); | ||
| 2179 | |||
| 2180 | Buf[0] = 1; | 2601 | Buf[0] = 1; |
| 2181 | Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; | 2602 | Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; |
| 2182 | Buf[2] = DW_EH_PE_udata4; | 2603 | Buf[2] = DW_EH_PE_udata4; |
| ... | @@ -2185,10 +2606,9 @@ void EhFrameHeader::writeTo(uint8_t *Buf) { | ... | @@ -2185,10 +2606,9 @@ void EhFrameHeader::writeTo(uint8_t *Buf) { |
| 2185 | write32(Buf + 8, Fdes.size()); | 2606 | write32(Buf + 8, Fdes.size()); |
| 2186 | Buf += 12; | 2607 | Buf += 12; |
| 2187 | 2608 | ||
| 2188 | uint64_t VA = this->getVA(); | ||
| 2189 | for (FdeData &Fde : Fdes) { | 2609 | for (FdeData &Fde : Fdes) { |
| 2190 | write32(Buf, Fde.Pc - VA); | 2610 | write32(Buf, Fde.PcRel); |
| 2191 | write32(Buf + 4, Fde.FdeVA - VA); | 2611 | write32(Buf + 4, Fde.FdeVARel); |
| 2192 | Buf += 8; | 2612 | Buf += 8; |
| 2193 | } | 2613 | } |
| 2194 | } | 2614 | } |
| ... | @@ -2298,11 +2718,9 @@ VersionNeedSection<ELFT>::VersionNeedSection() | ... | @@ -2298,11 +2718,9 @@ VersionNeedSection<ELFT>::VersionNeedSection() |
| 2298 | NextIndex = getVerDefNum() + 1; | 2718 | NextIndex = getVerDefNum() + 1; |
| 2299 | } | 2719 | } |
| 2300 | 2720 | ||
| 2301 | template <class ELFT> | 2721 | template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) { |
| 2302 | void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) { | 2722 | auto &File = cast<SharedFile<ELFT>>(*SS->File); |
| 2303 | SharedFile<ELFT> &File = SS->getFile<ELFT>(); | 2723 | if (SS->VerdefIndex == VER_NDX_GLOBAL) { |
| 2304 | const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex]; | ||
| 2305 | if (!Ver) { | ||
| 2306 | SS->VersionId = VER_NDX_GLOBAL; | 2724 | SS->VersionId = VER_NDX_GLOBAL; |
| 2307 | return; | 2725 | return; |
| 2308 | } | 2726 | } |
| ... | @@ -2312,7 +2730,9 @@ void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) { | ... | @@ -2312,7 +2730,9 @@ void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) { |
| 2312 | // for the soname. | 2730 | // for the soname. |
| 2313 | if (File.VerdefMap.empty()) | 2731 | if (File.VerdefMap.empty()) |
| 2314 | Needed.push_back({&File, InX::DynStrTab->addString(File.SoName)}); | 2732 | Needed.push_back({&File, InX::DynStrTab->addString(File.SoName)}); |
| 2733 | const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex]; | ||
| 2315 | typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver]; | 2734 | typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver]; |
| 2735 | |||
| 2316 | // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef, | 2736 | // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef, |
| 2317 | // prepare to create one by allocating a version identifier and creating a | 2737 | // prepare to create one by allocating a version identifier and creating a |
| 2318 | // dynstr entry for the version name. | 2738 | // dynstr entry for the version name. |
| ... | @@ -2476,11 +2896,20 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef Name, | ... | @@ -2476,11 +2896,20 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef Name, |
| 2476 | return make<MergeNoTailSection>(Name, Type, Flags, Alignment); | 2896 | return make<MergeNoTailSection>(Name, Type, Flags, Alignment); |
| 2477 | } | 2897 | } |
| 2478 | 2898 | ||
| 2479 | // Debug sections may be compressed by zlib. Uncompress if exists. | 2899 | // Debug sections may be compressed by zlib. Decompress if exists. |
| 2480 | void elf::decompressSections() { | 2900 | void elf::decompressSections() { |
| 2901 | parallelForEach(InputSections, | ||
| 2902 | [](InputSectionBase *Sec) { Sec->maybeDecompress(); }); | ||
| 2903 | } | ||
| 2904 | |||
| 2905 | template <class ELFT> void elf::splitSections() { | ||
| 2906 | // splitIntoPieces needs to be called on each MergeInputSection | ||
| 2907 | // before calling finalizeContents(). | ||
| 2481 | parallelForEach(InputSections, [](InputSectionBase *Sec) { | 2908 | parallelForEach(InputSections, [](InputSectionBase *Sec) { |
| 2482 | if (Sec->Live) | 2909 | if (auto *S = dyn_cast<MergeInputSection>(Sec)) |
| 2483 | Sec->maybeUncompress(); | 2910 | S->splitIntoPieces(); |
| 2911 | else if (auto *Eh = dyn_cast<EhInputSection>(Sec)) | ||
| 2912 | Eh->split<ELFT>(); | ||
| 2484 | }); | 2913 | }); |
| 2485 | } | 2914 | } |
| 2486 | 2915 | ||
| ... | @@ -2492,14 +2921,6 @@ void elf::decompressSections() { | ... | @@ -2492,14 +2921,6 @@ void elf::decompressSections() { |
| 2492 | // that it replaces. It then finalizes each synthetic section in order | 2921 | // that it replaces. It then finalizes each synthetic section in order |
| 2493 | // to compute an output offset for each piece of each input section. | 2922 | // to compute an output offset for each piece of each input section. |
| 2494 | void elf::mergeSections() { | 2923 | void elf::mergeSections() { |
| 2495 | // splitIntoPieces needs to be called on each MergeInputSection | ||
| 2496 | // before calling finalizeContents(). Do that first. | ||
| 2497 | parallelForEach(InputSections, [](InputSectionBase *Sec) { | ||
| 2498 | if (Sec->Live) | ||
| 2499 | if (auto *S = dyn_cast<MergeInputSection>(Sec)) | ||
| 2500 | S->splitIntoPieces(); | ||
| 2501 | }); | ||
| 2502 | |||
| 2503 | std::vector<MergeSyntheticSection *> MergeSections; | 2924 | std::vector<MergeSyntheticSection *> MergeSections; |
| 2504 | for (InputSectionBase *&S : InputSections) { | 2925 | for (InputSectionBase *&S : InputSections) { |
| 2505 | MergeInputSection *MS = dyn_cast<MergeInputSection>(S); | 2926 | MergeInputSection *MS = dyn_cast<MergeInputSection>(S); |
| ... | @@ -2561,8 +2982,7 @@ ARMExidxSentinelSection::ARMExidxSentinelSection() | ... | @@ -2561,8 +2982,7 @@ ARMExidxSentinelSection::ARMExidxSentinelSection() |
| 2561 | // address described by any other table entry. | 2982 | // address described by any other table entry. |
| 2562 | void ARMExidxSentinelSection::writeTo(uint8_t *Buf) { | 2983 | void ARMExidxSentinelSection::writeTo(uint8_t *Buf) { |
| 2563 | assert(Highest); | 2984 | assert(Highest); |
| 2564 | uint64_t S = | 2985 | uint64_t S = Highest->getVA(Highest->getSize()); |
| 2565 | Highest->getParent()->Addr + Highest->getOffset(Highest->getSize()); | ||
| 2566 | uint64_t P = getVA(); | 2986 | uint64_t P = getVA(); |
| 2567 | Target->relocateOne(Buf, R_ARM_PREL31, S - P); | 2987 | Target->relocateOne(Buf, R_ARM_PREL31, S - P); |
| 2568 | write32le(Buf + 4, 1); | 2988 | write32le(Buf + 4, 1); |
| ... | @@ -2570,15 +2990,16 @@ void ARMExidxSentinelSection::writeTo(uint8_t *Buf) { | ... | @@ -2570,15 +2990,16 @@ void ARMExidxSentinelSection::writeTo(uint8_t *Buf) { |
| 2570 | 2990 | ||
| 2571 | // The sentinel has to be removed if there are no other .ARM.exidx entries. | 2991 | // The sentinel has to be removed if there are no other .ARM.exidx entries. |
| 2572 | bool ARMExidxSentinelSection::empty() const { | 2992 | bool ARMExidxSentinelSection::empty() const { |
| 2573 | OutputSection *OS = getParent(); | 2993 | for (InputSection *IS : getInputSections(getParent())) |
| 2574 | for (auto *B : OS->SectionCommands) | 2994 | if (!isa<ARMExidxSentinelSection>(IS)) |
| 2575 | if (auto *ISD = dyn_cast<InputSectionDescription>(B)) | 2995 | return false; |
| 2576 | for (auto *S : ISD->Sections) | ||
| 2577 | if (!isa<ARMExidxSentinelSection>(S)) | ||
| 2578 | return false; | ||
| 2579 | return true; | 2996 | return true; |
| 2580 | } | 2997 | } |
| 2581 | 2998 | ||
| 2999 | bool ARMExidxSentinelSection::classof(const SectionBase *D) { | ||
| 3000 | return D->kind() == InputSectionBase::Synthetic && D->Type == SHT_ARM_EXIDX; | ||
| 3001 | } | ||
| 3002 | |||
| 2582 | ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off) | 3003 | ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off) |
| 2583 | : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, | 3004 | : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, |
| 2584 | Config->Wordsize, ".text.thunk") { | 3005 | Config->Wordsize, ".text.thunk") { |
| ... | @@ -2587,16 +3008,13 @@ ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off) | ... | @@ -2587,16 +3008,13 @@ ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off) |
| 2587 | } | 3008 | } |
| 2588 | 3009 | ||
| 2589 | void ThunkSection::addThunk(Thunk *T) { | 3010 | void ThunkSection::addThunk(Thunk *T) { |
| 2590 | uint64_t Off = alignTo(Size, T->Alignment); | ||
| 2591 | T->Offset = Off; | ||
| 2592 | Thunks.push_back(T); | 3011 | Thunks.push_back(T); |
| 2593 | T->addSymbols(*this); | 3012 | T->addSymbols(*this); |
| 2594 | Size = Off + T->size(); | ||
| 2595 | } | 3013 | } |
| 2596 | 3014 | ||
| 2597 | void ThunkSection::writeTo(uint8_t *Buf) { | 3015 | void ThunkSection::writeTo(uint8_t *Buf) { |
| 2598 | for (const Thunk *T : Thunks) | 3016 | for (Thunk *T : Thunks) |
| 2599 | T->writeTo(Buf + T->Offset, *this); | 3017 | T->writeTo(Buf + T->Offset); |
| 2600 | } | 3018 | } |
| 2601 | 3019 | ||
| 2602 | InputSection *ThunkSection::getTargetInputSection() const { | 3020 | InputSection *ThunkSection::getTargetInputSection() const { |
| ... | @@ -2606,6 +3024,20 @@ InputSection *ThunkSection::getTargetInputSection() const { | ... | @@ -2606,6 +3024,20 @@ InputSection *ThunkSection::getTargetInputSection() const { |
| 2606 | return T->getTargetInputSection(); | 3024 | return T->getTargetInputSection(); |
| 2607 | } | 3025 | } |
| 2608 | 3026 | ||
| 3027 | bool ThunkSection::assignOffsets() { | ||
| 3028 | uint64_t Off = 0; | ||
| 3029 | for (Thunk *T : Thunks) { | ||
| 3030 | Off = alignTo(Off, T->Alignment); | ||
| 3031 | T->setOffset(Off); | ||
| 3032 | uint32_t Size = T->size(); | ||
| 3033 | T->getThunkTargetSym()->Size = Size; | ||
| 3034 | Off += Size; | ||
| 3035 | } | ||
| 3036 | bool Changed = Off != Size; | ||
| 3037 | Size = Off; | ||
| 3038 | return Changed; | ||
| 3039 | } | ||
| 3040 | |||
| 2609 | InputSection *InX::ARMAttributes; | 3041 | InputSection *InX::ARMAttributes; |
| 2610 | BssSection *InX::Bss; | 3042 | BssSection *InX::Bss; |
| 2611 | BssSection *InX::BssRelRo; | 3043 | BssSection *InX::BssRelRo; |
| ... | @@ -2627,16 +3059,23 @@ MipsRldMapSection *InX::MipsRldMap; | ... | @@ -2627,16 +3059,23 @@ MipsRldMapSection *InX::MipsRldMap; |
| 2627 | PltSection *InX::Plt; | 3059 | PltSection *InX::Plt; |
| 2628 | PltSection *InX::Iplt; | 3060 | PltSection *InX::Iplt; |
| 2629 | RelocationBaseSection *InX::RelaDyn; | 3061 | RelocationBaseSection *InX::RelaDyn; |
| 3062 | RelrBaseSection *InX::RelrDyn; | ||
| 2630 | RelocationBaseSection *InX::RelaPlt; | 3063 | RelocationBaseSection *InX::RelaPlt; |
| 2631 | RelocationBaseSection *InX::RelaIplt; | 3064 | RelocationBaseSection *InX::RelaIplt; |
| 2632 | StringTableSection *InX::ShStrTab; | 3065 | StringTableSection *InX::ShStrTab; |
| 2633 | StringTableSection *InX::StrTab; | 3066 | StringTableSection *InX::StrTab; |
| 2634 | SymbolTableBaseSection *InX::SymTab; | 3067 | SymbolTableBaseSection *InX::SymTab; |
| 3068 | SymtabShndxSection *InX::SymTabShndx; | ||
| 3069 | |||
| 3070 | template GdbIndexSection *GdbIndexSection::create<ELF32LE>(); | ||
| 3071 | template GdbIndexSection *GdbIndexSection::create<ELF32BE>(); | ||
| 3072 | template GdbIndexSection *GdbIndexSection::create<ELF64LE>(); | ||
| 3073 | template GdbIndexSection *GdbIndexSection::create<ELF64BE>(); | ||
| 2635 | 3074 | ||
| 2636 | template GdbIndexSection *elf::createGdbIndex<ELF32LE>(); | 3075 | template void elf::splitSections<ELF32LE>(); |
| 2637 | template GdbIndexSection *elf::createGdbIndex<ELF32BE>(); | 3076 | template void elf::splitSections<ELF32BE>(); |
| 2638 | template GdbIndexSection *elf::createGdbIndex<ELF64LE>(); | 3077 | template void elf::splitSections<ELF64LE>(); |
| 2639 | template GdbIndexSection *elf::createGdbIndex<ELF64BE>(); | 3078 | template void elf::splitSections<ELF64BE>(); |
| 2640 | 3079 | ||
| 2641 | template void EhFrameSection::addSection<ELF32LE>(InputSectionBase *); | 3080 | template void EhFrameSection::addSection<ELF32LE>(InputSectionBase *); |
| 2642 | template void EhFrameSection::addSection<ELF32BE>(InputSectionBase *); | 3081 | template void EhFrameSection::addSection<ELF32BE>(InputSectionBase *); |
| ... | @@ -2648,6 +3087,11 @@ template void PltSection::addEntry<ELF32BE>(Symbol &Sym); | ... | @@ -2648,6 +3087,11 @@ template void PltSection::addEntry<ELF32BE>(Symbol &Sym); |
| 2648 | template void PltSection::addEntry<ELF64LE>(Symbol &Sym); | 3087 | template void PltSection::addEntry<ELF64LE>(Symbol &Sym); |
| 2649 | template void PltSection::addEntry<ELF64BE>(Symbol &Sym); | 3088 | template void PltSection::addEntry<ELF64BE>(Symbol &Sym); |
| 2650 | 3089 | ||
| 3090 | template void MipsGotSection::build<ELF32LE>(); | ||
| 3091 | template void MipsGotSection::build<ELF32BE>(); | ||
| 3092 | template void MipsGotSection::build<ELF64LE>(); | ||
| 3093 | template void MipsGotSection::build<ELF64BE>(); | ||
| 3094 | |||
| 2651 | template class elf::MipsAbiFlagsSection<ELF32LE>; | 3095 | template class elf::MipsAbiFlagsSection<ELF32LE>; |
| 2652 | template class elf::MipsAbiFlagsSection<ELF32BE>; | 3096 | template class elf::MipsAbiFlagsSection<ELF32BE>; |
| 2653 | template class elf::MipsAbiFlagsSection<ELF64LE>; | 3097 | template class elf::MipsAbiFlagsSection<ELF64LE>; |
| ... | @@ -2678,6 +3122,11 @@ template class elf::AndroidPackedRelocationSection<ELF32BE>; | ... | @@ -2678,6 +3122,11 @@ template class elf::AndroidPackedRelocationSection<ELF32BE>; |
| 2678 | template class elf::AndroidPackedRelocationSection<ELF64LE>; | 3122 | template class elf::AndroidPackedRelocationSection<ELF64LE>; |
| 2679 | template class elf::AndroidPackedRelocationSection<ELF64BE>; | 3123 | template class elf::AndroidPackedRelocationSection<ELF64BE>; |
| 2680 | 3124 | ||
| 3125 | template class elf::RelrSection<ELF32LE>; | ||
| 3126 | template class elf::RelrSection<ELF32BE>; | ||
| 3127 | template class elf::RelrSection<ELF64LE>; | ||
| 3128 | template class elf::RelrSection<ELF64BE>; | ||
| 3129 | |||
| 2681 | template class elf::SymbolTableSection<ELF32LE>; | 3130 | template class elf::SymbolTableSection<ELF32LE>; |
| 2682 | template class elf::SymbolTableSection<ELF32BE>; | 3131 | template class elf::SymbolTableSection<ELF32BE>; |
| 2683 | template class elf::SymbolTableSection<ELF64LE>; | 3132 | template class elf::SymbolTableSection<ELF64LE>; |
deps/lld/ELF/SyntheticSections.h+251-95| ... | @@ -26,10 +26,12 @@ | ... | @@ -26,10 +26,12 @@ |
| 26 | #include "InputSection.h" | 26 | #include "InputSection.h" |
| 27 | #include "llvm/ADT/MapVector.h" | 27 | #include "llvm/ADT/MapVector.h" |
| 28 | #include "llvm/MC/StringTableBuilder.h" | 28 | #include "llvm/MC/StringTableBuilder.h" |
| 29 | #include "llvm/Support/Endian.h" | ||
| 29 | #include <functional> | 30 | #include <functional> |
| 30 | 31 | ||
| 31 | namespace lld { | 32 | namespace lld { |
| 32 | namespace elf { | 33 | namespace elf { |
| 34 | class Defined; | ||
| 33 | class SharedSymbol; | 35 | class SharedSymbol; |
| 34 | 36 | ||
| 35 | class SyntheticSection : public InputSection { | 37 | class SyntheticSection : public InputSection { |
| ... | @@ -51,7 +53,6 @@ public: | ... | @@ -51,7 +53,6 @@ public: |
| 51 | // If any additional finalization of contents are needed post thunk creation. | 53 | // If any additional finalization of contents are needed post thunk creation. |
| 52 | virtual void postThunkContents() {} | 54 | virtual void postThunkContents() {} |
| 53 | virtual bool empty() const { return false; } | 55 | virtual bool empty() const { return false; } |
| 54 | uint64_t getVA() const; | ||
| 55 | 56 | ||
| 56 | static bool classof(const SectionBase *D) { | 57 | static bool classof(const SectionBase *D) { |
| 57 | return D->kind() == InputSectionBase::Synthetic; | 58 | return D->kind() == InputSectionBase::Synthetic; |
| ... | @@ -78,13 +79,18 @@ public: | ... | @@ -78,13 +79,18 @@ public: |
| 78 | size_t NumFdes = 0; | 79 | size_t NumFdes = 0; |
| 79 | 80 | ||
| 80 | struct FdeData { | 81 | struct FdeData { |
| 81 | uint32_t Pc; | 82 | uint32_t PcRel; |
| 82 | uint32_t FdeVA; | 83 | uint32_t FdeVARel; |
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| 85 | std::vector<FdeData> getFdeData() const; | 86 | std::vector<FdeData> getFdeData() const; |
| 87 | ArrayRef<CieRecord *> getCieRecords() const { return CieRecords; } | ||
| 86 | 88 | ||
| 87 | private: | 89 | private: |
| 90 | // This is used only when parsing EhInputSection. We keep it here to avoid | ||
| 91 | // allocating one for each EhInputSection. | ||
| 92 | llvm::DenseMap<size_t, CieRecord *> OffsetToCie; | ||
| 93 | |||
| 88 | uint64_t Size = 0; | 94 | uint64_t Size = 0; |
| 89 | 95 | ||
| 90 | template <class ELFT, class RelTy> | 96 | template <class ELFT, class RelTy> |
| ... | @@ -173,12 +179,21 @@ public: | ... | @@ -173,12 +179,21 @@ public: |
| 173 | bool updateAllocSize() override; | 179 | bool updateAllocSize() override; |
| 174 | void finalizeContents() override; | 180 | void finalizeContents() override; |
| 175 | bool empty() const override; | 181 | bool empty() const override; |
| 176 | void addEntry(Symbol &Sym, int64_t Addend, RelExpr Expr); | 182 | |
| 177 | bool addDynTlsEntry(Symbol &Sym); | 183 | // Join separate GOTs built for each input file to generate |
| 178 | bool addTlsIndex(); | 184 | // primary and optional multiple secondary GOTs. |
| 179 | uint64_t getPageEntryOffset(const Symbol &B, int64_t Addend) const; | 185 | template <class ELFT> void build(); |
| 180 | uint64_t getSymEntryOffset(const Symbol &B, int64_t Addend) const; | 186 | |
| 181 | uint64_t getGlobalDynOffset(const Symbol &B) const; | 187 | void addEntry(InputFile &File, Symbol &Sym, int64_t Addend, RelExpr Expr); |
| 188 | void addDynTlsEntry(InputFile &File, Symbol &Sym); | ||
| 189 | void addTlsIndex(InputFile &File); | ||
| 190 | |||
| 191 | uint64_t getPageEntryOffset(const InputFile *F, const Symbol &S, | ||
| 192 | int64_t Addend) const; | ||
| 193 | uint64_t getSymEntryOffset(const InputFile *F, const Symbol &S, | ||
| 194 | int64_t Addend) const; | ||
| 195 | uint64_t getGlobalDynOffset(const InputFile *F, const Symbol &S) const; | ||
| 196 | uint64_t getTlsIndexOffset(const InputFile *F) const; | ||
| 182 | 197 | ||
| 183 | // Returns the symbol which corresponds to the first entry of the global part | 198 | // Returns the symbol which corresponds to the first entry of the global part |
| 184 | // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic | 199 | // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic |
| ... | @@ -190,13 +205,8 @@ public: | ... | @@ -190,13 +205,8 @@ public: |
| 190 | // the number of reserved entries. | 205 | // the number of reserved entries. |
| 191 | unsigned getLocalEntriesNum() const; | 206 | unsigned getLocalEntriesNum() const; |
| 192 | 207 | ||
| 193 | // Returns offset of TLS part of the MIPS GOT table. This part goes | 208 | // Return _gp value for primary GOT (nullptr) or particular input file. |
| 194 | // after 'local' and 'global' entries. | 209 | uint64_t getGp(const InputFile *F = nullptr) const; |
| 195 | uint64_t getTlsOffset() const; | ||
| 196 | |||
| 197 | uint32_t getTlsIndexOff() const { return TlsIndexOff; } | ||
| 198 | |||
| 199 | uint64_t getGp() const; | ||
| 200 | 210 | ||
| 201 | private: | 211 | private: |
| 202 | // MIPS GOT consists of three parts: local, global and tls. Each part | 212 | // MIPS GOT consists of three parts: local, global and tls. Each part |
| ... | @@ -235,32 +245,110 @@ private: | ... | @@ -235,32 +245,110 @@ private: |
| 235 | // addressing, but MIPS ABI requires that these entries be present in GOT. | 245 | // addressing, but MIPS ABI requires that these entries be present in GOT. |
| 236 | // TLS entries: | 246 | // TLS entries: |
| 237 | // Entries created by TLS relocations. | 247 | // Entries created by TLS relocations. |
| 248 | // | ||
| 249 | // If the sum of local, global and tls entries is less than 64K only single | ||
| 250 | // got is enough. Otherwise, multi-got is created. Series of primary and | ||
| 251 | // multiple secondary GOTs have the following layout: | ||
| 252 | // - Primary GOT | ||
| 253 | // Header | ||
| 254 | // Local entries | ||
| 255 | // Global entries | ||
| 256 | // Relocation only entries | ||
| 257 | // TLS entries | ||
| 258 | // | ||
| 259 | // - Secondary GOT | ||
| 260 | // Local entries | ||
| 261 | // Global entries | ||
| 262 | // TLS entries | ||
| 263 | // ... | ||
| 264 | // | ||
| 265 | // All GOT entries required by relocations from a single input file entirely | ||
| 266 | // belong to either primary or one of secondary GOTs. To reference GOT entries | ||
| 267 | // each GOT has its own _gp value points to the "middle" of the GOT. | ||
| 268 | // In the code this value loaded to the register which is used for GOT access. | ||
| 269 | // | ||
| 270 | // MIPS 32 function's prologue: | ||
| 271 | // lui v0,0x0 | ||
| 272 | // 0: R_MIPS_HI16 _gp_disp | ||
| 273 | // addiu v0,v0,0 | ||
| 274 | // 4: R_MIPS_LO16 _gp_disp | ||
| 275 | // | ||
| 276 | // MIPS 64: | ||
| 277 | // lui at,0x0 | ||
| 278 | // 14: R_MIPS_GPREL16 main | ||
| 279 | // | ||
| 280 | // Dynamic linker does not know anything about secondary GOTs and cannot | ||
| 281 | // use a regular MIPS mechanism for GOT entries initialization. So we have | ||
| 282 | // to use an approach accepted by other architectures and create dynamic | ||
| 283 | // relocations R_MIPS_REL32 to initialize global entries (and local in case | ||
| 284 | // of PIC code) in secondary GOTs. But ironically MIPS dynamic linker | ||
| 285 | // requires GOT entries and correspondingly ordered dynamic symbol table | ||
| 286 | // entries to deal with dynamic relocations. To handle this problem | ||
| 287 | // relocation-only section in the primary GOT contains entries for all | ||
| 288 | // symbols referenced in global parts of secondary GOTs. Although the sum | ||
| 289 | // of local and normal global entries of the primary got should be less | ||
| 290 | // than 64K, the size of the primary got (including relocation-only entries | ||
| 291 | // can be greater than 64K, because parts of the primary got that overflow | ||
| 292 | // the 64K limit are used only by the dynamic linker at dynamic link-time | ||
| 293 | // and not by 16-bit gp-relative addressing at run-time. | ||
| 294 | // | ||
| 295 | // For complete multi-GOT description see the following link | ||
| 296 | // https://dmz-portal.mips.com/wiki/MIPS_Multi_GOT | ||
| 238 | 297 | ||
| 239 | // Number of "Header" entries. | 298 | // Number of "Header" entries. |
| 240 | static const unsigned HeaderEntriesNum = 2; | 299 | static const unsigned HeaderEntriesNum = 2; |
| 241 | // Number of allocated "Page" entries. | ||
| 242 | uint32_t PageEntriesNum = 0; | ||
| 243 | // Map output sections referenced by MIPS GOT relocations | ||
| 244 | // to the first index of "Page" entries allocated for this section. | ||
| 245 | llvm::SmallMapVector<const OutputSection *, size_t, 16> PageIndexMap; | ||
| 246 | |||
| 247 | typedef std::pair<const Symbol *, uint64_t> GotEntry; | ||
| 248 | typedef std::vector<GotEntry> GotEntries; | ||
| 249 | // Map from Symbol-Addend pair to the GOT index. | ||
| 250 | llvm::DenseMap<GotEntry, size_t> EntryIndexMap; | ||
| 251 | // Local entries (16-bit access). | ||
| 252 | GotEntries LocalEntries; | ||
| 253 | // Local entries (32-bit access). | ||
| 254 | GotEntries LocalEntries32; | ||
| 255 | |||
| 256 | // Normal and reloc-only global entries. | ||
| 257 | GotEntries GlobalEntries; | ||
| 258 | |||
| 259 | // TLS entries. | ||
| 260 | std::vector<const Symbol *> TlsEntries; | ||
| 261 | 300 | ||
| 262 | uint32_t TlsIndexOff = -1; | ||
| 263 | uint64_t Size = 0; | 301 | uint64_t Size = 0; |
| 302 | |||
| 303 | size_t LocalEntriesNum = 0; | ||
| 304 | |||
| 305 | // Symbol and addend. | ||
| 306 | typedef std::pair<Symbol *, int64_t> GotEntry; | ||
| 307 | |||
| 308 | struct FileGot { | ||
| 309 | InputFile *File = nullptr; | ||
| 310 | size_t StartIndex = 0; | ||
| 311 | |||
| 312 | struct PageBlock { | ||
| 313 | size_t FirstIndex = 0; | ||
| 314 | size_t Count = 0; | ||
| 315 | }; | ||
| 316 | |||
| 317 | // Map output sections referenced by MIPS GOT relocations | ||
| 318 | // to the description (index/count) "page" entries allocated | ||
| 319 | // for this section. | ||
| 320 | llvm::SmallMapVector<const OutputSection *, PageBlock, 16> PagesMap; | ||
| 321 | // Maps from Symbol+Addend pair or just Symbol to the GOT entry index. | ||
| 322 | llvm::MapVector<GotEntry, size_t> Local16; | ||
| 323 | llvm::MapVector<GotEntry, size_t> Local32; | ||
| 324 | llvm::MapVector<Symbol *, size_t> Global; | ||
| 325 | llvm::MapVector<Symbol *, size_t> Relocs; | ||
| 326 | llvm::MapVector<Symbol *, size_t> Tls; | ||
| 327 | // Set of symbols referenced by dynamic TLS relocations. | ||
| 328 | llvm::MapVector<Symbol *, size_t> DynTlsSymbols; | ||
| 329 | |||
| 330 | // Total number of all entries. | ||
| 331 | size_t getEntriesNum() const; | ||
| 332 | // Number of "page" entries. | ||
| 333 | size_t getPageEntriesNum() const; | ||
| 334 | // Number of entries require 16-bit index to access. | ||
| 335 | size_t getIndexedEntriesNum() const; | ||
| 336 | |||
| 337 | bool isOverflow() const; | ||
| 338 | }; | ||
| 339 | |||
| 340 | // Container of GOT created for each input file. | ||
| 341 | // After building a final series of GOTs this container | ||
| 342 | // holds primary and secondary GOT's. | ||
| 343 | std::vector<FileGot> Gots; | ||
| 344 | |||
| 345 | // Return (and create if necessary) `FileGot`. | ||
| 346 | FileGot &getGot(InputFile &F); | ||
| 347 | |||
| 348 | // Try to merge two GOTs. In case of success the `Dst` contains | ||
| 349 | // result of merging and the function returns true. In case of | ||
| 350 | // ovwerflow the `Dst` is unchanged and the function returns false. | ||
| 351 | bool tryMergeGots(FileGot & Dst, FileGot & Src, bool IsPrimary); | ||
| 264 | }; | 352 | }; |
| 265 | 353 | ||
| 266 | class GotPltSection final : public SyntheticSection { | 354 | class GotPltSection final : public SyntheticSection { |
| ... | @@ -269,7 +357,7 @@ public: | ... | @@ -269,7 +357,7 @@ public: |
| 269 | void addEntry(Symbol &Sym); | 357 | void addEntry(Symbol &Sym); |
| 270 | size_t getSize() const override; | 358 | size_t getSize() const override; |
| 271 | void writeTo(uint8_t *Buf) override; | 359 | void writeTo(uint8_t *Buf) override; |
| 272 | bool empty() const override { return Entries.empty(); } | 360 | bool empty() const override; |
| 273 | 361 | ||
| 274 | private: | 362 | private: |
| 275 | std::vector<const Symbol *> Entries; | 363 | std::vector<const Symbol *> Entries; |
| ... | @@ -310,30 +398,48 @@ private: | ... | @@ -310,30 +398,48 @@ private: |
| 310 | 398 | ||
| 311 | class DynamicReloc { | 399 | class DynamicReloc { |
| 312 | public: | 400 | public: |
| 313 | DynamicReloc(uint32_t Type, const InputSectionBase *InputSec, | 401 | DynamicReloc(RelType Type, const InputSectionBase *InputSec, |
| 314 | uint64_t OffsetInSec, bool UseSymVA, Symbol *Sym, int64_t Addend) | 402 | uint64_t OffsetInSec, bool UseSymVA, Symbol *Sym, int64_t Addend) |
| 315 | : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), | 403 | : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), |
| 316 | UseSymVA(UseSymVA), Addend(Addend) {} | 404 | UseSymVA(UseSymVA), Addend(Addend), OutputSec(nullptr) {} |
| 405 | // This constructor records dynamic relocation settings used by MIPS | ||
| 406 | // multi-GOT implementation. It's to relocate addresses of 64kb pages | ||
| 407 | // lie inside the output section. | ||
| 408 | DynamicReloc(RelType Type, const InputSectionBase *InputSec, | ||
| 409 | uint64_t OffsetInSec, const OutputSection *OutputSec, | ||
| 410 | int64_t Addend) | ||
| 411 | : Type(Type), Sym(nullptr), InputSec(InputSec), OffsetInSec(OffsetInSec), | ||
| 412 | UseSymVA(false), Addend(Addend), OutputSec(OutputSec) {} | ||
| 317 | 413 | ||
| 318 | uint64_t getOffset() const; | 414 | uint64_t getOffset() const; |
| 319 | int64_t getAddend() const; | ||
| 320 | uint32_t getSymIndex() const; | 415 | uint32_t getSymIndex() const; |
| 321 | const InputSectionBase *getInputSec() const { return InputSec; } | 416 | const InputSectionBase *getInputSec() const { return InputSec; } |
| 322 | 417 | ||
| 323 | uint32_t Type; | 418 | // Computes the addend of the dynamic relocation. Note that this is not the |
| 419 | // same as the Addend member variable as it also includes the symbol address | ||
| 420 | // if UseSymVA is true. | ||
| 421 | int64_t computeAddend() const; | ||
| 422 | |||
| 423 | RelType Type; | ||
| 324 | 424 | ||
| 325 | private: | 425 | private: |
| 326 | Symbol *Sym; | 426 | Symbol *Sym; |
| 327 | const InputSectionBase *InputSec = nullptr; | 427 | const InputSectionBase *InputSec = nullptr; |
| 328 | uint64_t OffsetInSec; | 428 | uint64_t OffsetInSec; |
| 429 | // If this member is true, the dynamic relocation will not be against the | ||
| 430 | // symbol but will instead be a relative relocation that simply adds the | ||
| 431 | // load address. This means we need to write the symbol virtual address | ||
| 432 | // plus the original addend as the final relocation addend. | ||
| 329 | bool UseSymVA; | 433 | bool UseSymVA; |
| 330 | int64_t Addend; | 434 | int64_t Addend; |
| 435 | const OutputSection *OutputSec; | ||
| 331 | }; | 436 | }; |
| 332 | 437 | ||
| 333 | template <class ELFT> class DynamicSection final : public SyntheticSection { | 438 | template <class ELFT> class DynamicSection final : public SyntheticSection { |
| 334 | typedef typename ELFT::Dyn Elf_Dyn; | 439 | typedef typename ELFT::Dyn Elf_Dyn; |
| 335 | typedef typename ELFT::Rel Elf_Rel; | 440 | typedef typename ELFT::Rel Elf_Rel; |
| 336 | typedef typename ELFT::Rela Elf_Rela; | 441 | typedef typename ELFT::Rela Elf_Rela; |
| 442 | typedef typename ELFT::Relr Elf_Relr; | ||
| 337 | typedef typename ELFT::Shdr Elf_Shdr; | 443 | typedef typename ELFT::Shdr Elf_Shdr; |
| 338 | typedef typename ELFT::Sym Elf_Sym; | 444 | typedef typename ELFT::Sym Elf_Sym; |
| 339 | 445 | ||
| ... | @@ -350,6 +456,7 @@ private: | ... | @@ -350,6 +456,7 @@ private: |
| 350 | void add(int32_t Tag, std::function<uint64_t()> Fn); | 456 | void add(int32_t Tag, std::function<uint64_t()> Fn); |
| 351 | void addInt(int32_t Tag, uint64_t Val); | 457 | void addInt(int32_t Tag, uint64_t Val); |
| 352 | void addInSec(int32_t Tag, InputSection *Sec); | 458 | void addInSec(int32_t Tag, InputSection *Sec); |
| 459 | void addInSecRelative(int32_t Tag, InputSection *Sec); | ||
| 353 | void addOutSec(int32_t Tag, OutputSection *Sec); | 460 | void addOutSec(int32_t Tag, OutputSection *Sec); |
| 354 | void addSize(int32_t Tag, OutputSection *Sec); | 461 | void addSize(int32_t Tag, OutputSection *Sec); |
| 355 | void addSym(int32_t Tag, Symbol *Sym); | 462 | void addSym(int32_t Tag, Symbol *Sym); |
| ... | @@ -361,6 +468,13 @@ class RelocationBaseSection : public SyntheticSection { | ... | @@ -361,6 +468,13 @@ class RelocationBaseSection : public SyntheticSection { |
| 361 | public: | 468 | public: |
| 362 | RelocationBaseSection(StringRef Name, uint32_t Type, int32_t DynamicTag, | 469 | RelocationBaseSection(StringRef Name, uint32_t Type, int32_t DynamicTag, |
| 363 | int32_t SizeDynamicTag); | 470 | int32_t SizeDynamicTag); |
| 471 | void addReloc(RelType DynType, InputSectionBase *IS, uint64_t OffsetInSec, | ||
| 472 | Symbol *Sym); | ||
| 473 | // Add a dynamic relocation that might need an addend. This takes care of | ||
| 474 | // writing the addend to the output section if needed. | ||
| 475 | void addReloc(RelType DynType, InputSectionBase *InputSec, | ||
| 476 | uint64_t OffsetInSec, Symbol *Sym, int64_t Addend, RelExpr Expr, | ||
| 477 | RelType Type); | ||
| 364 | void addReloc(const DynamicReloc &Reloc); | 478 | void addReloc(const DynamicReloc &Reloc); |
| 365 | bool empty() const override { return Relocs.empty(); } | 479 | bool empty() const override { return Relocs.empty(); } |
| 366 | size_t getSize() const override { return Relocs.size() * this->Entsize; } | 480 | size_t getSize() const override { return Relocs.size() * this->Entsize; } |
| ... | @@ -405,6 +519,39 @@ private: | ... | @@ -405,6 +519,39 @@ private: |
| 405 | SmallVector<char, 0> RelocData; | 519 | SmallVector<char, 0> RelocData; |
| 406 | }; | 520 | }; |
| 407 | 521 | ||
| 522 | struct RelativeReloc { | ||
| 523 | uint64_t getOffset() const { return InputSec->getVA(OffsetInSec); } | ||
| 524 | |||
| 525 | const InputSectionBase *InputSec; | ||
| 526 | uint64_t OffsetInSec; | ||
| 527 | }; | ||
| 528 | |||
| 529 | class RelrBaseSection : public SyntheticSection { | ||
| 530 | public: | ||
| 531 | RelrBaseSection(); | ||
| 532 | std::vector<RelativeReloc> Relocs; | ||
| 533 | }; | ||
| 534 | |||
| 535 | // RelrSection is used to encode offsets for relative relocations. | ||
| 536 | // Proposal for adding SHT_RELR sections to generic-abi is here: | ||
| 537 | // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg | ||
| 538 | // For more details, see the comment in RelrSection::updateAllocSize(). | ||
| 539 | template <class ELFT> class RelrSection final : public RelrBaseSection { | ||
| 540 | typedef typename ELFT::Relr Elf_Relr; | ||
| 541 | |||
| 542 | public: | ||
| 543 | RelrSection(); | ||
| 544 | |||
| 545 | bool updateAllocSize() override; | ||
| 546 | size_t getSize() const override { return RelrRelocs.size() * this->Entsize; } | ||
| 547 | void writeTo(uint8_t *Buf) override { | ||
| 548 | memcpy(Buf, RelrRelocs.data(), getSize()); | ||
| 549 | } | ||
| 550 | |||
| 551 | private: | ||
| 552 | std::vector<Elf_Relr> RelrRelocs; | ||
| 553 | }; | ||
| 554 | |||
| 408 | struct SymbolTableEntry { | 555 | struct SymbolTableEntry { |
| 409 | Symbol *Sym; | 556 | Symbol *Sym; |
| 410 | size_t StrTabOffset; | 557 | size_t StrTabOffset; |
| ... | @@ -441,6 +588,16 @@ public: | ... | @@ -441,6 +588,16 @@ public: |
| 441 | void writeTo(uint8_t *Buf) override; | 588 | void writeTo(uint8_t *Buf) override; |
| 442 | }; | 589 | }; |
| 443 | 590 | ||
| 591 | class SymtabShndxSection final : public SyntheticSection { | ||
| 592 | public: | ||
| 593 | SymtabShndxSection(); | ||
| 594 | |||
| 595 | void writeTo(uint8_t *Buf) override; | ||
| 596 | size_t getSize() const override; | ||
| 597 | bool empty() const override; | ||
| 598 | void finalizeContents() override; | ||
| 599 | }; | ||
| 600 | |||
| 444 | // Outputs GNU Hash section. For detailed explanation see: | 601 | // Outputs GNU Hash section. For detailed explanation see: |
| 445 | // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections | 602 | // https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections |
| 446 | class GnuHashTableSection final : public SyntheticSection { | 603 | class GnuHashTableSection final : public SyntheticSection { |
| ... | @@ -455,7 +612,7 @@ public: | ... | @@ -455,7 +612,7 @@ public: |
| 455 | void addSymbols(std::vector<SymbolTableEntry> &Symbols); | 612 | void addSymbols(std::vector<SymbolTableEntry> &Symbols); |
| 456 | 613 | ||
| 457 | private: | 614 | private: |
| 458 | size_t getShift2() const { return Config->Is64 ? 6 : 5; } | 615 | enum { Shift2 = 6 }; |
| 459 | 616 | ||
| 460 | void writeBloomFilter(uint8_t *Buf); | 617 | void writeBloomFilter(uint8_t *Buf); |
| 461 | void writeHashTable(uint8_t *Buf); | 618 | void writeHashTable(uint8_t *Buf); |
| ... | @@ -484,13 +641,13 @@ private: | ... | @@ -484,13 +641,13 @@ private: |
| 484 | size_t Size = 0; | 641 | size_t Size = 0; |
| 485 | }; | 642 | }; |
| 486 | 643 | ||
| 487 | // The PltSection is used for both the Plt and Iplt. The former always has a | 644 | // The PltSection is used for both the Plt and Iplt. The former usually has a |
| 488 | // header as its first entry that is used at run-time to resolve lazy binding. | 645 | // header as its first entry that is used at run-time to resolve lazy binding. |
| 489 | // The latter is used for GNU Ifunc symbols, that will be subject to a | 646 | // The latter is used for GNU Ifunc symbols, that will be subject to a |
| 490 | // Target->IRelativeRel. | 647 | // Target->IRelativeRel. |
| 491 | class PltSection : public SyntheticSection { | 648 | class PltSection : public SyntheticSection { |
| 492 | public: | 649 | public: |
| 493 | PltSection(size_t HeaderSize); | 650 | PltSection(bool IsIplt); |
| 494 | void writeTo(uint8_t *Buf) override; | 651 | void writeTo(uint8_t *Buf) override; |
| 495 | size_t getSize() const override; | 652 | size_t getSize() const override; |
| 496 | bool empty() const override { return Entries.empty(); } | 653 | bool empty() const override { return Entries.empty(); } |
| ... | @@ -501,13 +658,12 @@ public: | ... | @@ -501,13 +658,12 @@ public: |
| 501 | private: | 658 | private: |
| 502 | unsigned getPltRelocOff() const; | 659 | unsigned getPltRelocOff() const; |
| 503 | std::vector<std::pair<const Symbol *, unsigned>> Entries; | 660 | std::vector<std::pair<const Symbol *, unsigned>> Entries; |
| 504 | // Iplt always has HeaderSize of 0, the Plt HeaderSize is always non-zero | ||
| 505 | size_t HeaderSize; | 661 | size_t HeaderSize; |
| 662 | bool IsIplt; | ||
| 506 | }; | 663 | }; |
| 507 | 664 | ||
| 508 | // GdbIndexChunk is created for each .debug_info section and contains | 665 | class GdbIndexSection final : public SyntheticSection { |
| 509 | // information to create a part of .gdb_index for a given input section. | 666 | public: |
| 510 | struct GdbIndexChunk { | ||
| 511 | struct AddressEntry { | 667 | struct AddressEntry { |
| 512 | InputSection *Section; | 668 | InputSection *Section; |
| 513 | uint64_t LowAddress; | 669 | uint64_t LowAddress; |
| ... | @@ -522,59 +678,51 @@ struct GdbIndexChunk { | ... | @@ -522,59 +678,51 @@ struct GdbIndexChunk { |
| 522 | 678 | ||
| 523 | struct NameTypeEntry { | 679 | struct NameTypeEntry { |
| 524 | llvm::CachedHashStringRef Name; | 680 | llvm::CachedHashStringRef Name; |
| 525 | uint8_t Type; | 681 | uint32_t Type; |
| 526 | }; | 682 | }; |
| 527 | 683 | ||
| 528 | InputSection *DebugInfoSec; | 684 | struct GdbChunk { |
| 529 | std::vector<AddressEntry> AddressAreas; | 685 | InputSection *Sec; |
| 530 | std::vector<CuEntry> CompilationUnits; | 686 | std::vector<AddressEntry> AddressAreas; |
| 531 | std::vector<NameTypeEntry> NamesAndTypes; | 687 | std::vector<CuEntry> CompilationUnits; |
| 532 | }; | 688 | }; |
| 533 | 689 | ||
| 534 | // The symbol type for the .gdb_index section. | 690 | struct GdbSymbol { |
| 535 | struct GdbSymbol { | 691 | llvm::CachedHashStringRef Name; |
| 536 | uint32_t NameHash; | 692 | std::vector<uint32_t> CuVector; |
| 537 | size_t NameOffset; | 693 | uint32_t NameOff; |
| 538 | size_t CuVectorIndex; | 694 | uint32_t CuVectorOff; |
| 539 | }; | 695 | }; |
| 540 | 696 | ||
| 541 | class GdbIndexSection final : public SyntheticSection { | 697 | GdbIndexSection(); |
| 542 | public: | 698 | template <typename ELFT> static GdbIndexSection *create(); |
| 543 | GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks); | ||
| 544 | void writeTo(uint8_t *Buf) override; | 699 | void writeTo(uint8_t *Buf) override; |
| 545 | size_t getSize() const override; | 700 | size_t getSize() const override { return Size; } |
| 546 | bool empty() const override; | 701 | bool empty() const override; |
| 547 | 702 | ||
| 548 | private: | 703 | private: |
| 549 | void fixCuIndex(); | 704 | struct GdbIndexHeader { |
| 550 | std::vector<std::vector<uint32_t>> createCuVectors(); | 705 | llvm::support::ulittle32_t Version; |
| 551 | std::vector<GdbSymbol *> createGdbSymtab(); | 706 | llvm::support::ulittle32_t CuListOff; |
| 552 | 707 | llvm::support::ulittle32_t CuTypesOff; | |
| 553 | // A symbol table for this .gdb_index section. | 708 | llvm::support::ulittle32_t AddressAreaOff; |
| 554 | std::vector<GdbSymbol *> GdbSymtab; | 709 | llvm::support::ulittle32_t SymtabOff; |
| 555 | 710 | llvm::support::ulittle32_t ConstantPoolOff; | |
| 556 | // CU vector is a part of constant pool area of section. | 711 | }; |
| 557 | std::vector<std::vector<uint32_t>> CuVectors; | ||
| 558 | 712 | ||
| 559 | // Symbol table contents. | 713 | void initOutputSize(); |
| 560 | llvm::DenseMap<llvm::CachedHashStringRef, GdbSymbol *> Symbols; | 714 | size_t computeSymtabSize() const; |
| 561 | 715 | ||
| 562 | // Each chunk contains information gathered from a debug sections of single | 716 | // Each chunk contains information gathered from debug sections of a |
| 563 | // object and used to build different areas of gdb index. | 717 | // single object file. |
| 564 | std::vector<GdbIndexChunk> Chunks; | 718 | std::vector<GdbChunk> Chunks; |
| 565 | 719 | ||
| 566 | static constexpr uint32_t CuListOffset = 24; | 720 | // A symbol table for this .gdb_index section. |
| 567 | uint32_t CuTypesOffset; | 721 | std::vector<GdbSymbol> Symbols; |
| 568 | uint32_t SymtabOffset; | ||
| 569 | uint32_t ConstantPoolOffset; | ||
| 570 | uint32_t StringPoolOffset; | ||
| 571 | uint32_t StringPoolSize; | ||
| 572 | 722 | ||
| 573 | std::vector<size_t> CuVectorOffsets; | 723 | size_t Size; |
| 574 | }; | 724 | }; |
| 575 | 725 | ||
| 576 | template <class ELFT> GdbIndexSection *createGdbIndex(); | ||
| 577 | |||
| 578 | // --eh-frame-hdr option tells linker to construct a header for all the | 726 | // --eh-frame-hdr option tells linker to construct a header for all the |
| 579 | // .eh_frame sections. This header is placed to a section named .eh_frame_hdr | 727 | // .eh_frame sections. This header is placed to a section named .eh_frame_hdr |
| 580 | // and also to a PT_GNU_EH_FRAME segment. | 728 | // and also to a PT_GNU_EH_FRAME segment. |
| ... | @@ -653,7 +801,7 @@ template <class ELFT> class VersionNeedSection final : public SyntheticSection { | ... | @@ -653,7 +801,7 @@ template <class ELFT> class VersionNeedSection final : public SyntheticSection { |
| 653 | 801 | ||
| 654 | public: | 802 | public: |
| 655 | VersionNeedSection(); | 803 | VersionNeedSection(); |
| 656 | void addSymbol(SharedSymbol *SS); | 804 | void addSymbol(Symbol *Sym); |
| 657 | void finalizeContents() override; | 805 | void finalizeContents() override; |
| 658 | void writeTo(uint8_t *Buf) override; | 806 | void writeTo(uint8_t *Buf) override; |
| 659 | size_t getSize() const override; | 807 | size_t getSize() const override; |
| ... | @@ -668,13 +816,12 @@ public: | ... | @@ -668,13 +816,12 @@ public: |
| 668 | class MergeSyntheticSection : public SyntheticSection { | 816 | class MergeSyntheticSection : public SyntheticSection { |
| 669 | public: | 817 | public: |
| 670 | void addSection(MergeInputSection *MS); | 818 | void addSection(MergeInputSection *MS); |
| 819 | std::vector<MergeInputSection *> Sections; | ||
| 671 | 820 | ||
| 672 | protected: | 821 | protected: |
| 673 | MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags, | 822 | MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags, |
| 674 | uint32_t Alignment) | 823 | uint32_t Alignment) |
| 675 | : SyntheticSection(Flags, Type, Alignment, Name) {} | 824 | : SyntheticSection(Flags, Type, Alignment, Name) {} |
| 676 | |||
| 677 | std::vector<MergeInputSection *> Sections; | ||
| 678 | }; | 825 | }; |
| 679 | 826 | ||
| 680 | class MergeTailSection final : public MergeSyntheticSection { | 827 | class MergeTailSection final : public MergeSyntheticSection { |
| ... | @@ -787,7 +934,12 @@ public: | ... | @@ -787,7 +934,12 @@ public: |
| 787 | void writeTo(uint8_t *Buf) override; | 934 | void writeTo(uint8_t *Buf) override; |
| 788 | bool empty() const override; | 935 | bool empty() const override; |
| 789 | 936 | ||
| 790 | InputSection *Highest = 0; | 937 | static bool classof(const SectionBase *D); |
| 938 | |||
| 939 | // The last section referenced by a regular .ARM.exidx section. | ||
| 940 | // It is found and filled in Writer<ELFT>::resolveShfLinkOrder(). | ||
| 941 | // The sentinel points at the end of that section. | ||
| 942 | InputSection *Highest = nullptr; | ||
| 791 | }; | 943 | }; |
| 792 | 944 | ||
| 793 | // A container for one or more linker generated thunks. Instances of these | 945 | // A container for one or more linker generated thunks. Instances of these |
| ... | @@ -805,19 +957,21 @@ public: | ... | @@ -805,19 +957,21 @@ public: |
| 805 | size_t getSize() const override { return Size; } | 957 | size_t getSize() const override { return Size; } |
| 806 | void writeTo(uint8_t *Buf) override; | 958 | void writeTo(uint8_t *Buf) override; |
| 807 | InputSection *getTargetInputSection() const; | 959 | InputSection *getTargetInputSection() const; |
| 960 | bool assignOffsets(); | ||
| 808 | 961 | ||
| 809 | private: | 962 | private: |
| 810 | std::vector<const Thunk *> Thunks; | 963 | std::vector<Thunk *> Thunks; |
| 811 | size_t Size = 0; | 964 | size_t Size = 0; |
| 812 | }; | 965 | }; |
| 813 | 966 | ||
| 814 | InputSection *createInterpSection(); | 967 | InputSection *createInterpSection(); |
| 815 | MergeInputSection *createCommentSection(); | 968 | MergeInputSection *createCommentSection(); |
| 816 | void decompressSections(); | 969 | void decompressSections(); |
| 970 | template <class ELFT> void splitSections(); | ||
| 817 | void mergeSections(); | 971 | void mergeSections(); |
| 818 | 972 | ||
| 819 | Symbol *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, | 973 | Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, |
| 820 | uint64_t Size, InputSectionBase &Section); | 974 | uint64_t Size, InputSectionBase &Section); |
| 821 | 975 | ||
| 822 | // Linker generated sections which can be used as inputs. | 976 | // Linker generated sections which can be used as inputs. |
| 823 | struct InX { | 977 | struct InX { |
| ... | @@ -842,11 +996,13 @@ struct InX { | ... | @@ -842,11 +996,13 @@ struct InX { |
| 842 | static PltSection *Plt; | 996 | static PltSection *Plt; |
| 843 | static PltSection *Iplt; | 997 | static PltSection *Iplt; |
| 844 | static RelocationBaseSection *RelaDyn; | 998 | static RelocationBaseSection *RelaDyn; |
| 999 | static RelrBaseSection *RelrDyn; | ||
| 845 | static RelocationBaseSection *RelaPlt; | 1000 | static RelocationBaseSection *RelaPlt; |
| 846 | static RelocationBaseSection *RelaIplt; | 1001 | static RelocationBaseSection *RelaIplt; |
| 847 | static StringTableSection *ShStrTab; | 1002 | static StringTableSection *ShStrTab; |
| 848 | static StringTableSection *StrTab; | 1003 | static StringTableSection *StrTab; |
| 849 | static SymbolTableBaseSection *SymTab; | 1004 | static SymbolTableBaseSection *SymTab; |
| 1005 | static SymtabShndxSection* SymTabShndx; | ||
| 850 | }; | 1006 | }; |
| 851 | 1007 | ||
| 852 | template <class ELFT> struct In { | 1008 | template <class ELFT> struct In { |
deps/lld/ELF/Target.cpp+18-10| ... | @@ -60,6 +60,8 @@ TargetInfo *elf::getTarget() { | ... | @@ -60,6 +60,8 @@ TargetInfo *elf::getTarget() { |
| 60 | return getARMTargetInfo(); | 60 | return getARMTargetInfo(); |
| 61 | case EM_AVR: | 61 | case EM_AVR: |
| 62 | return getAVRTargetInfo(); | 62 | return getAVRTargetInfo(); |
| 63 | case EM_HEXAGON: | ||
| 64 | return getHexagonTargetInfo(); | ||
| 63 | case EM_MIPS: | 65 | case EM_MIPS: |
| 64 | switch (Config->EKind) { | 66 | switch (Config->EKind) { |
| 65 | case ELF32LEKind: | 67 | case ELF32LEKind: |
| ... | @@ -87,29 +89,29 @@ TargetInfo *elf::getTarget() { | ... | @@ -87,29 +89,29 @@ TargetInfo *elf::getTarget() { |
| 87 | fatal("unknown target machine"); | 89 | fatal("unknown target machine"); |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 90 | template <class ELFT> static std::string getErrorLoc(const uint8_t *Loc) { | 92 | template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *Loc) { |
| 91 | for (InputSectionBase *D : InputSections) { | 93 | for (InputSectionBase *D : InputSections) { |
| 92 | auto *IS = dyn_cast<InputSection>(D); | 94 | auto *IS = cast<InputSection>(D); |
| 93 | if (!IS || !IS->getParent()) | 95 | if (!IS->getParent()) |
| 94 | continue; | 96 | continue; |
| 95 | 97 | ||
| 96 | uint8_t *ISLoc = IS->getParent()->Loc + IS->OutSecOff; | 98 | uint8_t *ISLoc = IS->getParent()->Loc + IS->OutSecOff; |
| 97 | if (ISLoc <= Loc && Loc < ISLoc + IS->getSize()) | 99 | if (ISLoc <= Loc && Loc < ISLoc + IS->getSize()) |
| 98 | return IS->template getLocation<ELFT>(Loc - ISLoc) + ": "; | 100 | return {IS, IS->template getLocation<ELFT>(Loc - ISLoc) + ": "}; |
| 99 | } | 101 | } |
| 100 | return ""; | 102 | return {}; |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | std::string elf::getErrorLocation(const uint8_t *Loc) { | 105 | ErrorPlace elf::getErrorPlace(const uint8_t *Loc) { |
| 104 | switch (Config->EKind) { | 106 | switch (Config->EKind) { |
| 105 | case ELF32LEKind: | 107 | case ELF32LEKind: |
| 106 | return getErrorLoc<ELF32LE>(Loc); | 108 | return getErrPlace<ELF32LE>(Loc); |
| 107 | case ELF32BEKind: | 109 | case ELF32BEKind: |
| 108 | return getErrorLoc<ELF32BE>(Loc); | 110 | return getErrPlace<ELF32BE>(Loc); |
| 109 | case ELF64LEKind: | 111 | case ELF64LEKind: |
| 110 | return getErrorLoc<ELF64LE>(Loc); | 112 | return getErrPlace<ELF64LE>(Loc); |
| 111 | case ELF64BEKind: | 113 | case ELF64BEKind: |
| 112 | return getErrorLoc<ELF64BE>(Loc); | 114 | return getErrPlace<ELF64BE>(Loc); |
| 113 | default: | 115 | default: |
| 114 | llvm_unreachable("unknown ELF type"); | 116 | llvm_unreachable("unknown ELF type"); |
| 115 | } | 117 | } |
| ... | @@ -128,6 +130,12 @@ bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, | ... | @@ -128,6 +130,12 @@ bool TargetInfo::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, |
| 128 | return false; | 130 | return false; |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 133 | bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *Loc, | ||
| 134 | uint8_t *End) const { | ||
| 135 | llvm_unreachable("Target doesn't support split stacks."); | ||
| 136 | } | ||
| 137 | |||
| 138 | |||
| 131 | bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const { | 139 | bool TargetInfo::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const { |
| 132 | return true; | 140 | return true; |
| 133 | } | 141 | } |
deps/lld/ELF/Target.h+90-23| ... | @@ -25,9 +25,9 @@ class Symbol; | ... | @@ -25,9 +25,9 @@ class Symbol; |
| 25 | class TargetInfo { | 25 | class TargetInfo { |
| 26 | public: | 26 | public: |
| 27 | virtual uint32_t calcEFlags() const { return 0; } | 27 | virtual uint32_t calcEFlags() const { return 0; } |
| 28 | virtual bool isPicRel(RelType Type) const { return true; } | ||
| 29 | virtual RelType getDynRel(RelType Type) const { return Type; } | 28 | virtual RelType getDynRel(RelType Type) const { return Type; } |
| 30 | virtual void writeGotPltHeader(uint8_t *Buf) const {} | 29 | virtual void writeGotPltHeader(uint8_t *Buf) const {} |
| 30 | virtual void writeGotHeader(uint8_t *Buf) const {} | ||
| 31 | virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {}; | 31 | virtual void writeGotPlt(uint8_t *Buf, const Symbol &S) const {}; |
| 32 | virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const; | 32 | virtual void writeIgotPlt(uint8_t *Buf, const Symbol &S) const; |
| 33 | virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const; | 33 | virtual int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const; |
| ... | @@ -43,8 +43,12 @@ public: | ... | @@ -43,8 +43,12 @@ public: |
| 43 | virtual void addPltHeaderSymbols(InputSection &IS) const {} | 43 | virtual void addPltHeaderSymbols(InputSection &IS) const {} |
| 44 | virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {} | 44 | virtual void addPltSymbols(InputSection &IS, uint64_t Off) const {} |
| 45 | 45 | ||
| 46 | unsigned getPltEntryOffset(unsigned Index) const { | ||
| 47 | return Index * PltEntrySize + PltHeaderSize; | ||
| 48 | } | ||
| 49 | |||
| 46 | // Returns true if a relocation only uses the low bits of a value such that | 50 | // Returns true if a relocation only uses the low bits of a value such that |
| 47 | // all those bits are in in the same page. For example, if the relocation | 51 | // all those bits are in the same page. For example, if the relocation |
| 48 | // only uses the low 12 bits in a system with 4k pages. If this is true, the | 52 | // only uses the low 12 bits in a system with 4k pages. If this is true, the |
| 49 | // bits will always have the same value at runtime and we don't have to emit | 53 | // bits will always have the same value at runtime and we don't have to emit |
| 50 | // a dynamic relocation. | 54 | // a dynamic relocation. |
| ... | @@ -55,6 +59,13 @@ public: | ... | @@ -55,6 +59,13 @@ public: |
| 55 | virtual bool needsThunk(RelExpr Expr, RelType RelocType, | 59 | virtual bool needsThunk(RelExpr Expr, RelType RelocType, |
| 56 | const InputFile *File, uint64_t BranchAddr, | 60 | const InputFile *File, uint64_t BranchAddr, |
| 57 | const Symbol &S) const; | 61 | const Symbol &S) const; |
| 62 | |||
| 63 | // The function with a prologue starting at Loc was compiled with | ||
| 64 | // -fsplit-stack and it calls a function compiled without. Adjust the prologue | ||
| 65 | // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks. | ||
| 66 | virtual bool adjustPrologueForCrossSplitStack(uint8_t *Loc, | ||
| 67 | uint8_t *End) const; | ||
| 68 | |||
| 58 | // Return true if we can reach Dst from Src with Relocation RelocType | 69 | // Return true if we can reach Dst from Src with Relocation RelocType |
| 59 | virtual bool inBranchRange(RelType Type, uint64_t Src, | 70 | virtual bool inBranchRange(RelType Type, uint64_t Src, |
| 60 | uint64_t Dst) const; | 71 | uint64_t Dst) const; |
| ... | @@ -71,9 +82,10 @@ public: | ... | @@ -71,9 +82,10 @@ public: |
| 71 | 82 | ||
| 72 | uint64_t getImageBase(); | 83 | uint64_t getImageBase(); |
| 73 | 84 | ||
| 74 | // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for | 85 | // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got or .got.plt section. |
| 75 | // end of .got | ||
| 76 | uint64_t GotBaseSymOff = 0; | 86 | uint64_t GotBaseSymOff = 0; |
| 87 | // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got. | ||
| 88 | bool GotBaseSymInGotPlt = true; | ||
| 77 | 89 | ||
| 78 | // On systems with range extensions we place collections of Thunks at | 90 | // On systems with range extensions we place collections of Thunks at |
| 79 | // regular spacings that enable the majority of branches reach the Thunks. | 91 | // regular spacings that enable the majority of branches reach the Thunks. |
| ... | @@ -97,9 +109,18 @@ public: | ... | @@ -97,9 +109,18 @@ public: |
| 97 | // to support lazy loading. | 109 | // to support lazy loading. |
| 98 | unsigned GotPltHeaderEntriesNum = 3; | 110 | unsigned GotPltHeaderEntriesNum = 3; |
| 99 | 111 | ||
| 100 | // Set to 0 for variant 2 | 112 | // On PPC ELF V2 abi, the first entry in the .got is the .TOC. |
| 113 | unsigned GotHeaderEntriesNum = 0; | ||
| 114 | |||
| 115 | // For TLS variant 1, the TCB is a fixed size specified by the Target. | ||
| 116 | // For variant 2, the TCB is an unspecified size. | ||
| 117 | // Set to 0 for variant 2. | ||
| 101 | unsigned TcbSize = 0; | 118 | unsigned TcbSize = 0; |
| 102 | 119 | ||
| 120 | // Set to the offset (in bytes) that the thread pointer is initialized to | ||
| 121 | // point to, relative to the start of the thread local storage. | ||
| 122 | unsigned TlsTpOffset = 0; | ||
| 123 | |||
| 103 | bool NeedsThunks = false; | 124 | bool NeedsThunks = false; |
| 104 | 125 | ||
| 105 | // A 4-byte field corresponding to one or more trap instructions, used to pad | 126 | // A 4-byte field corresponding to one or more trap instructions, used to pad |
| ... | @@ -126,6 +147,7 @@ TargetInfo *getAArch64TargetInfo(); | ... | @@ -126,6 +147,7 @@ TargetInfo *getAArch64TargetInfo(); |
| 126 | TargetInfo *getAMDGPUTargetInfo(); | 147 | TargetInfo *getAMDGPUTargetInfo(); |
| 127 | TargetInfo *getARMTargetInfo(); | 148 | TargetInfo *getARMTargetInfo(); |
| 128 | TargetInfo *getAVRTargetInfo(); | 149 | TargetInfo *getAVRTargetInfo(); |
| 150 | TargetInfo *getHexagonTargetInfo(); | ||
| 129 | TargetInfo *getPPC64TargetInfo(); | 151 | TargetInfo *getPPC64TargetInfo(); |
| 130 | TargetInfo *getPPCTargetInfo(); | 152 | TargetInfo *getPPCTargetInfo(); |
| 131 | TargetInfo *getSPARCV9TargetInfo(); | 153 | TargetInfo *getSPARCV9TargetInfo(); |
| ... | @@ -134,7 +156,17 @@ TargetInfo *getX86TargetInfo(); | ... | @@ -134,7 +156,17 @@ TargetInfo *getX86TargetInfo(); |
| 134 | TargetInfo *getX86_64TargetInfo(); | 156 | TargetInfo *getX86_64TargetInfo(); |
| 135 | template <class ELFT> TargetInfo *getMipsTargetInfo(); | 157 | template <class ELFT> TargetInfo *getMipsTargetInfo(); |
| 136 | 158 | ||
| 137 | std::string getErrorLocation(const uint8_t *Loc); | 159 | struct ErrorPlace { |
| 160 | InputSectionBase *IS; | ||
| 161 | std::string Loc; | ||
| 162 | }; | ||
| 163 | |||
| 164 | // Returns input section and corresponding source string for the given location. | ||
| 165 | ErrorPlace getErrorPlace(const uint8_t *Loc); | ||
| 166 | |||
| 167 | static inline std::string getErrorLocation(const uint8_t *Loc) { | ||
| 168 | return getErrorPlace(Loc).Loc; | ||
| 169 | } | ||
| 138 | 170 | ||
| 139 | uint64_t getPPC64TocBase(); | 171 | uint64_t getPPC64TocBase(); |
| 140 | uint64_t getAArch64Page(uint64_t Expr); | 172 | uint64_t getAArch64Page(uint64_t Expr); |
| ... | @@ -146,39 +178,74 @@ template <class ELFT> bool isMipsPIC(const Defined *Sym); | ... | @@ -146,39 +178,74 @@ template <class ELFT> bool isMipsPIC(const Defined *Sym); |
| 146 | 178 | ||
| 147 | static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V, | 179 | static inline void reportRangeError(uint8_t *Loc, RelType Type, const Twine &V, |
| 148 | int64_t Min, uint64_t Max) { | 180 | int64_t Min, uint64_t Max) { |
| 149 | error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) + | 181 | ErrorPlace ErrPlace = getErrorPlace(Loc); |
| 150 | " out of range: " + V + " is not in [" + Twine(Min) + ", " + | 182 | StringRef Hint; |
| 151 | Twine(Max) + "]"); | 183 | if (ErrPlace.IS && ErrPlace.IS->Name.startswith(".debug")) |
| 184 | Hint = "; consider recompiling with -fdebug-types-section to reduce size " | ||
| 185 | "of debug sections"; | ||
| 186 | |||
| 187 | error(ErrPlace.Loc + "relocation " + lld::toString(Type) + | ||
| 188 | " out of range: " + V.str() + " is not in [" + Twine(Min).str() + ", " + | ||
| 189 | Twine(Max).str() + "]" + Hint); | ||
| 152 | } | 190 | } |
| 153 | 191 | ||
| 154 | template <unsigned N> | 192 | // Sign-extend Nth bit all the way to MSB. |
| 155 | static void checkInt(uint8_t *Loc, int64_t V, RelType Type) { | 193 | inline int64_t signExtend(uint64_t V, int N) { |
| 156 | if (!llvm::isInt<N>(V)) | 194 | return int64_t(V << (64 - N)) >> (64 - N); |
| 195 | } | ||
| 196 | |||
| 197 | // Make sure that V can be represented as an N bit signed integer. | ||
| 198 | inline void checkInt(uint8_t *Loc, int64_t V, int N, RelType Type) { | ||
| 199 | if (V != signExtend(V, N)) | ||
| 157 | reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N)); | 200 | reportRangeError(Loc, Type, Twine(V), llvm::minIntN(N), llvm::maxIntN(N)); |
| 158 | } | 201 | } |
| 159 | 202 | ||
| 160 | template <unsigned N> | 203 | // Make sure that V can be represented as an N bit unsigned integer. |
| 161 | static void checkUInt(uint8_t *Loc, uint64_t V, RelType Type) { | 204 | inline void checkUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) { |
| 162 | if (!llvm::isUInt<N>(V)) | 205 | if ((V >> N) != 0) |
| 163 | reportRangeError(Loc, Type, Twine(V), 0, llvm::maxUIntN(N)); | 206 | reportRangeError(Loc, Type, Twine(V), 0, llvm::maxUIntN(N)); |
| 164 | } | 207 | } |
| 165 | 208 | ||
| 166 | template <unsigned N> | 209 | // Make sure that V can be represented as an N bit signed or unsigned integer. |
| 167 | static void checkIntUInt(uint8_t *Loc, uint64_t V, RelType Type) { | 210 | inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) { |
| 168 | if (!llvm::isInt<N>(V) && !llvm::isUInt<N>(V)) | 211 | // For the error message we should cast V to a signed integer so that error |
| 169 | // For the error message we should cast V to a signed integer so that error | 212 | // messages show a small negative value rather than an extremely large one |
| 170 | // messages show a small negative value rather than an extremely large one | 213 | if (V != (uint64_t)signExtend(V, N) && (V >> N) != 0) |
| 171 | reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N), | 214 | reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N), |
| 172 | llvm::maxUIntN(N)); | 215 | llvm::maxIntN(N)); |
| 173 | } | 216 | } |
| 174 | 217 | ||
| 175 | template <unsigned N> | 218 | inline void checkAlignment(uint8_t *Loc, uint64_t V, int N, RelType Type) { |
| 176 | static void checkAlignment(uint8_t *Loc, uint64_t V, RelType Type) { | ||
| 177 | if ((V & (N - 1)) != 0) | 219 | if ((V & (N - 1)) != 0) |
| 178 | error(getErrorLocation(Loc) + "improper alignment for relocation " + | 220 | error(getErrorLocation(Loc) + "improper alignment for relocation " + |
| 179 | lld::toString(Type) + ": 0x" + llvm::utohexstr(V) + | 221 | lld::toString(Type) + ": 0x" + llvm::utohexstr(V) + |
| 180 | " is not aligned to " + Twine(N) + " bytes"); | 222 | " is not aligned to " + Twine(N) + " bytes"); |
| 181 | } | 223 | } |
| 224 | |||
| 225 | // Endianness-aware read/write. | ||
| 226 | inline uint16_t read16(const void *P) { | ||
| 227 | return llvm::support::endian::read16(P, Config->Endianness); | ||
| 228 | } | ||
| 229 | |||
| 230 | inline uint32_t read32(const void *P) { | ||
| 231 | return llvm::support::endian::read32(P, Config->Endianness); | ||
| 232 | } | ||
| 233 | |||
| 234 | inline uint64_t read64(const void *P) { | ||
| 235 | return llvm::support::endian::read64(P, Config->Endianness); | ||
| 236 | } | ||
| 237 | |||
| 238 | inline void write16(void *P, uint16_t V) { | ||
| 239 | llvm::support::endian::write16(P, V, Config->Endianness); | ||
| 240 | } | ||
| 241 | |||
| 242 | inline void write32(void *P, uint32_t V) { | ||
| 243 | llvm::support::endian::write32(P, V, Config->Endianness); | ||
| 244 | } | ||
| 245 | |||
| 246 | inline void write64(void *P, uint64_t V) { | ||
| 247 | llvm::support::endian::write64(P, V, Config->Endianness); | ||
| 248 | } | ||
| 182 | } // namespace elf | 249 | } // namespace elf |
| 183 | } // namespace lld | 250 | } // namespace lld |
| 184 | 251 |
deps/lld/ELF/Thunks.cpp+273-117| ... | @@ -40,7 +40,6 @@ | ... | @@ -40,7 +40,6 @@ |
| 40 | 40 | ||
| 41 | using namespace llvm; | 41 | using namespace llvm; |
| 42 | using namespace llvm::object; | 42 | using namespace llvm::object; |
| 43 | using namespace llvm::support::endian; | ||
| 44 | using namespace llvm::ELF; | 43 | using namespace llvm::ELF; |
| 45 | 44 | ||
| 46 | namespace lld { | 45 | namespace lld { |
| ... | @@ -52,59 +51,112 @@ namespace { | ... | @@ -52,59 +51,112 @@ namespace { |
| 52 | class AArch64ABSLongThunk final : public Thunk { | 51 | class AArch64ABSLongThunk final : public Thunk { |
| 53 | public: | 52 | public: |
| 54 | AArch64ABSLongThunk(Symbol &Dest) : Thunk(Dest) {} | 53 | AArch64ABSLongThunk(Symbol &Dest) : Thunk(Dest) {} |
| 55 | uint32_t size() const override { return 16; } | 54 | uint32_t size() override { return 16; } |
| 56 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 55 | void writeTo(uint8_t *Buf) override; |
| 57 | void addSymbols(ThunkSection &IS) override; | 56 | void addSymbols(ThunkSection &IS) override; |
| 58 | }; | 57 | }; |
| 59 | 58 | ||
| 60 | class AArch64ADRPThunk final : public Thunk { | 59 | class AArch64ADRPThunk final : public Thunk { |
| 61 | public: | 60 | public: |
| 62 | AArch64ADRPThunk(Symbol &Dest) : Thunk(Dest) {} | 61 | AArch64ADRPThunk(Symbol &Dest) : Thunk(Dest) {} |
| 63 | uint32_t size() const override { return 12; } | 62 | uint32_t size() override { return 12; } |
| 64 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 63 | void writeTo(uint8_t *Buf) override; |
| 65 | void addSymbols(ThunkSection &IS) override; | 64 | void addSymbols(ThunkSection &IS) override; |
| 66 | }; | 65 | }; |
| 67 | 66 | ||
| 67 | // Base class for ARM thunks. | ||
| 68 | // | ||
| 69 | // An ARM thunk may be either short or long. A short thunk is simply a branch | ||
| 70 | // (B) instruction, and it may be used to call ARM functions when the distance | ||
| 71 | // from the thunk to the target is less than 32MB. Long thunks can branch to any | ||
| 72 | // virtual address and can switch between ARM and Thumb, and they are | ||
| 73 | // implemented in the derived classes. This class tries to create a short thunk | ||
| 74 | // if the target is in range, otherwise it creates a long thunk. | ||
| 75 | class ARMThunk : public Thunk { | ||
| 76 | public: | ||
| 77 | ARMThunk(Symbol &Dest) : Thunk(Dest) {} | ||
| 78 | |||
| 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; | ||
| 83 | |||
| 84 | // Returns the size of a long thunk. | ||
| 85 | virtual uint32_t sizeLong() = 0; | ||
| 86 | |||
| 87 | // Writes a long thunk to Buf. | ||
| 88 | virtual void writeLong(uint8_t *Buf) = 0; | ||
| 89 | |||
| 90 | private: | ||
| 91 | // This field tracks whether all previously considered layouts would allow | ||
| 92 | // this thunk to be short. If we have ever needed a long thunk, we always | ||
| 93 | // create a long thunk, even if the thunk may be short given the current | ||
| 94 | // distance to the target. We do this because transitioning from long to short | ||
| 95 | // can create layout oscillations in certain corner cases which would prevent | ||
| 96 | // the layout from converging. | ||
| 97 | bool MayUseShortThunk = true; | ||
| 98 | }; | ||
| 99 | |||
| 100 | // Base class for Thumb-2 thunks. | ||
| 101 | // | ||
| 102 | // This class is similar to ARMThunk, but it uses the Thumb-2 B.W instruction | ||
| 103 | // which has a range of 16MB. | ||
| 104 | class ThumbThunk : public Thunk { | ||
| 105 | public: | ||
| 106 | ThumbThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; } | ||
| 107 | |||
| 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; | ||
| 112 | |||
| 113 | // Returns the size of a long thunk. | ||
| 114 | virtual uint32_t sizeLong() = 0; | ||
| 115 | |||
| 116 | // Writes a long thunk to Buf. | ||
| 117 | virtual void writeLong(uint8_t *Buf) = 0; | ||
| 118 | |||
| 119 | private: | ||
| 120 | // See comment in ARMThunk above. | ||
| 121 | bool MayUseShortThunk = true; | ||
| 122 | }; | ||
| 123 | |||
| 68 | // Specific ARM Thunk implementations. The naming convention is: | 124 | // Specific ARM Thunk implementations. The naming convention is: |
| 69 | // Source State, TargetState, Target Requirement, ABS or PI, Range | 125 | // Source State, TargetState, Target Requirement, ABS or PI, Range |
| 70 | class ARMV7ABSLongThunk final : public Thunk { | 126 | class ARMV7ABSLongThunk final : public ARMThunk { |
| 71 | public: | 127 | public: |
| 72 | ARMV7ABSLongThunk(Symbol &Dest) : Thunk(Dest) {} | 128 | ARMV7ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {} |
| 73 | 129 | ||
| 74 | uint32_t size() const override { return 12; } | 130 | uint32_t sizeLong() override { return 12; } |
| 75 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 131 | void writeLong(uint8_t *Buf) override; |
| 76 | void addSymbols(ThunkSection &IS) override; | 132 | void addSymbols(ThunkSection &IS) override; |
| 77 | bool isCompatibleWith(RelType Type) const override; | ||
| 78 | }; | 133 | }; |
| 79 | 134 | ||
| 80 | class ARMV7PILongThunk final : public Thunk { | 135 | class ARMV7PILongThunk final : public ARMThunk { |
| 81 | public: | 136 | public: |
| 82 | ARMV7PILongThunk(Symbol &Dest) : Thunk(Dest) {} | 137 | ARMV7PILongThunk(Symbol &Dest) : ARMThunk(Dest) {} |
| 83 | 138 | ||
| 84 | uint32_t size() const override { return 16; } | 139 | uint32_t sizeLong() override { return 16; } |
| 85 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 140 | void writeLong(uint8_t *Buf) override; |
| 86 | void addSymbols(ThunkSection &IS) override; | 141 | void addSymbols(ThunkSection &IS) override; |
| 87 | bool isCompatibleWith(RelType Type) const override; | ||
| 88 | }; | 142 | }; |
| 89 | 143 | ||
| 90 | class ThumbV7ABSLongThunk final : public Thunk { | 144 | class ThumbV7ABSLongThunk final : public ThumbThunk { |
| 91 | public: | 145 | public: |
| 92 | ThumbV7ABSLongThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; } | 146 | ThumbV7ABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {} |
| 93 | 147 | ||
| 94 | uint32_t size() const override { return 10; } | 148 | uint32_t sizeLong() override { return 10; } |
| 95 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 149 | void writeLong(uint8_t *Buf) override; |
| 96 | void addSymbols(ThunkSection &IS) override; | 150 | void addSymbols(ThunkSection &IS) override; |
| 97 | bool isCompatibleWith(RelType Type) const override; | ||
| 98 | }; | 151 | }; |
| 99 | 152 | ||
| 100 | class ThumbV7PILongThunk final : public Thunk { | 153 | class ThumbV7PILongThunk final : public ThumbThunk { |
| 101 | public: | 154 | public: |
| 102 | ThumbV7PILongThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; } | 155 | ThumbV7PILongThunk(Symbol &Dest) : ThumbThunk(Dest) {} |
| 103 | 156 | ||
| 104 | uint32_t size() const override { return 12; } | 157 | uint32_t sizeLong() override { return 12; } |
| 105 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 158 | void writeLong(uint8_t *Buf) override; |
| 106 | void addSymbols(ThunkSection &IS) override; | 159 | void addSymbols(ThunkSection &IS) override; |
| 107 | bool isCompatibleWith(RelType Type) const override; | ||
| 108 | }; | 160 | }; |
| 109 | 161 | ||
| 110 | // MIPS LA25 thunk | 162 | // MIPS LA25 thunk |
| ... | @@ -112,8 +164,8 @@ class MipsThunk final : public Thunk { | ... | @@ -112,8 +164,8 @@ class MipsThunk final : public Thunk { |
| 112 | public: | 164 | public: |
| 113 | MipsThunk(Symbol &Dest) : Thunk(Dest) {} | 165 | MipsThunk(Symbol &Dest) : Thunk(Dest) {} |
| 114 | 166 | ||
| 115 | uint32_t size() const override { return 16; } | 167 | uint32_t size() override { return 16; } |
| 116 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 168 | void writeTo(uint8_t *Buf) override; |
| 117 | void addSymbols(ThunkSection &IS) override; | 169 | void addSymbols(ThunkSection &IS) override; |
| 118 | InputSection *getTargetInputSection() const override; | 170 | InputSection *getTargetInputSection() const override; |
| 119 | }; | 171 | }; |
| ... | @@ -123,8 +175,8 @@ class MicroMipsThunk final : public Thunk { | ... | @@ -123,8 +175,8 @@ class MicroMipsThunk final : public Thunk { |
| 123 | public: | 175 | public: |
| 124 | MicroMipsThunk(Symbol &Dest) : Thunk(Dest) {} | 176 | MicroMipsThunk(Symbol &Dest) : Thunk(Dest) {} |
| 125 | 177 | ||
| 126 | uint32_t size() const override { return 14; } | 178 | uint32_t size() override { return 14; } |
| 127 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 179 | void writeTo(uint8_t *Buf) override; |
| 128 | void addSymbols(ThunkSection &IS) override; | 180 | void addSymbols(ThunkSection &IS) override; |
| 129 | InputSection *getTargetInputSection() const override; | 181 | InputSection *getTargetInputSection() const override; |
| 130 | }; | 182 | }; |
| ... | @@ -134,14 +186,44 @@ class MicroMipsR6Thunk final : public Thunk { | ... | @@ -134,14 +186,44 @@ class MicroMipsR6Thunk final : public Thunk { |
| 134 | public: | 186 | public: |
| 135 | MicroMipsR6Thunk(Symbol &Dest) : Thunk(Dest) {} | 187 | MicroMipsR6Thunk(Symbol &Dest) : Thunk(Dest) {} |
| 136 | 188 | ||
| 137 | uint32_t size() const override { return 12; } | 189 | uint32_t size() override { return 12; } |
| 138 | void writeTo(uint8_t *Buf, ThunkSection &IS) const override; | 190 | void writeTo(uint8_t *Buf) override; |
| 139 | void addSymbols(ThunkSection &IS) override; | 191 | void addSymbols(ThunkSection &IS) override; |
| 140 | InputSection *getTargetInputSection() const override; | 192 | InputSection *getTargetInputSection() const override; |
| 141 | }; | 193 | }; |
| 142 | 194 | ||
| 195 | |||
| 196 | // PPC64 Plt call stubs. | ||
| 197 | // Any call site that needs to call through a plt entry needs a call stub in | ||
| 198 | // the .text section. The call stub is responsible for: | ||
| 199 | // 1) Saving the toc-pointer to the stack. | ||
| 200 | // 2) Loading the target functions address from the procedure linkage table into | ||
| 201 | // r12 for use by the target functions global entry point, and into the count | ||
| 202 | // register. | ||
| 203 | // 3) Transfering control to the target function through an indirect branch. | ||
| 204 | class PPC64PltCallStub final : public Thunk { | ||
| 205 | public: | ||
| 206 | PPC64PltCallStub(Symbol &Dest) : Thunk(Dest) {} | ||
| 207 | uint32_t size() override { return 20; } | ||
| 208 | void writeTo(uint8_t *Buf) override; | ||
| 209 | void addSymbols(ThunkSection &IS) override; | ||
| 210 | }; | ||
| 211 | |||
| 143 | } // end anonymous namespace | 212 | } // end anonymous namespace |
| 144 | 213 | ||
| 214 | Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value, | ||
| 215 | InputSectionBase &Section) { | ||
| 216 | Defined *D = addSyntheticLocal(Name, Type, Value, /*Size=*/0, Section); | ||
| 217 | Syms.push_back(D); | ||
| 218 | return D; | ||
| 219 | } | ||
| 220 | |||
| 221 | void Thunk::setOffset(uint64_t NewOffset) { | ||
| 222 | for (Defined *D : Syms) | ||
| 223 | D->Value = D->Value - Offset + NewOffset; | ||
| 224 | Offset = NewOffset; | ||
| 225 | } | ||
| 226 | |||
| 145 | // AArch64 long range Thunks | 227 | // AArch64 long range Thunks |
| 146 | 228 | ||
| 147 | static uint64_t getAArch64ThunkDestVA(const Symbol &S) { | 229 | static uint64_t getAArch64ThunkDestVA(const Symbol &S) { |
| ... | @@ -149,7 +231,7 @@ static uint64_t getAArch64ThunkDestVA(const Symbol &S) { | ... | @@ -149,7 +231,7 @@ static uint64_t getAArch64ThunkDestVA(const Symbol &S) { |
| 149 | return V; | 231 | return V; |
| 150 | } | 232 | } |
| 151 | 233 | ||
| 152 | void AArch64ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | 234 | void AArch64ABSLongThunk::writeTo(uint8_t *Buf) { |
| 153 | const uint8_t Data[] = { | 235 | const uint8_t Data[] = { |
| 154 | 0x50, 0x00, 0x00, 0x58, // ldr x16, L0 | 236 | 0x50, 0x00, 0x00, 0x58, // ldr x16, L0 |
| 155 | 0x00, 0x02, 0x1f, 0xd6, // br x16 | 237 | 0x00, 0x02, 0x1f, 0xd6, // br x16 |
| ... | @@ -162,11 +244,10 @@ void AArch64ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ... | @@ -162,11 +244,10 @@ void AArch64ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 162 | } | 244 | } |
| 163 | 245 | ||
| 164 | void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) { | 246 | void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) { |
| 165 | ThunkSym = addSyntheticLocal( | 247 | addSymbol(Saver.save("__AArch64AbsLongThunk_" + Destination.getName()), |
| 166 | Saver.save("__AArch64AbsLongThunk_" + Destination.getName()), STT_FUNC, | 248 | STT_FUNC, 0, IS); |
| 167 | Offset, size(), IS); | 249 | addSymbol("$x", STT_NOTYPE, 0, IS); |
| 168 | addSyntheticLocal("$x", STT_NOTYPE, Offset, 0, IS); | 250 | addSymbol("$d", STT_NOTYPE, 8, IS); |
| 169 | addSyntheticLocal("$d", STT_NOTYPE, Offset + 8, 0, IS); | ||
| 170 | } | 251 | } |
| 171 | 252 | ||
| 172 | // This Thunk has a maximum range of 4Gb, this is sufficient for all programs | 253 | // This Thunk has a maximum range of 4Gb, this is sufficient for all programs |
| ... | @@ -174,26 +255,24 @@ void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) { | ... | @@ -174,26 +255,24 @@ void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) { |
| 174 | // clang and gcc do not support the large code model for position independent | 255 | // clang and gcc do not support the large code model for position independent |
| 175 | // code so it is safe to use this for position independent thunks without | 256 | // code so it is safe to use this for position independent thunks without |
| 176 | // worrying about the destination being more than 4Gb away. | 257 | // worrying about the destination being more than 4Gb away. |
| 177 | void AArch64ADRPThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | 258 | void AArch64ADRPThunk::writeTo(uint8_t *Buf) { |
| 178 | const uint8_t Data[] = { | 259 | const uint8_t Data[] = { |
| 179 | 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest R_AARCH64_ADR_PREL_PG_HI21(Dest) | 260 | 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest R_AARCH64_ADR_PREL_PG_HI21(Dest) |
| 180 | 0x10, 0x02, 0x00, 0x91, // add x16, x16, R_AARCH64_ADD_ABS_LO12_NC(Dest) | 261 | 0x10, 0x02, 0x00, 0x91, // add x16, x16, R_AARCH64_ADD_ABS_LO12_NC(Dest) |
| 181 | 0x00, 0x02, 0x1f, 0xd6, // br x16 | 262 | 0x00, 0x02, 0x1f, 0xd6, // br x16 |
| 182 | }; | 263 | }; |
| 183 | uint64_t S = getAArch64ThunkDestVA(Destination); | 264 | uint64_t S = getAArch64ThunkDestVA(Destination); |
| 184 | uint64_t P = ThunkSym->getVA(); | 265 | uint64_t P = getThunkTargetSym()->getVA(); |
| 185 | memcpy(Buf, Data, sizeof(Data)); | 266 | memcpy(Buf, Data, sizeof(Data)); |
| 186 | Target->relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21, | 267 | Target->relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21, |
| 187 | getAArch64Page(S) - getAArch64Page(P)); | 268 | getAArch64Page(S) - getAArch64Page(P)); |
| 188 | Target->relocateOne(Buf + 4, R_AARCH64_ADD_ABS_LO12_NC, S); | 269 | Target->relocateOne(Buf + 4, R_AARCH64_ADD_ABS_LO12_NC, S); |
| 189 | } | 270 | } |
| 190 | 271 | ||
| 191 | void AArch64ADRPThunk::addSymbols(ThunkSection &IS) | 272 | void AArch64ADRPThunk::addSymbols(ThunkSection &IS) { |
| 192 | { | 273 | addSymbol(Saver.save("__AArch64ADRPThunk_" + Destination.getName()), STT_FUNC, |
| 193 | ThunkSym = addSyntheticLocal( | 274 | 0, IS); |
| 194 | Saver.save("__AArch64ADRPThunk_" + Destination.getName()), STT_FUNC, | 275 | addSymbol("$x", STT_NOTYPE, 0, IS); |
| 195 | Offset, size(), IS); | ||
| 196 | addSyntheticLocal("$x", STT_NOTYPE, Offset, 0, IS); | ||
| 197 | } | 276 | } |
| 198 | 277 | ||
| 199 | // ARM Target Thunks | 278 | // ARM Target Thunks |
| ... | @@ -202,7 +281,81 @@ static uint64_t getARMThunkDestVA(const Symbol &S) { | ... | @@ -202,7 +281,81 @@ static uint64_t getARMThunkDestVA(const Symbol &S) { |
| 202 | return SignExtend64<32>(V); | 281 | return SignExtend64<32>(V); |
| 203 | } | 282 | } |
| 204 | 283 | ||
| 205 | void ARMV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | 284 | // This function returns true if the target is not Thumb and is within 2^26, and |
| 285 | // it has not previously returned false (see comment for MayUseShortThunk). | ||
| 286 | bool ARMThunk::mayUseShortThunk() { | ||
| 287 | if (!MayUseShortThunk) | ||
| 288 | return false; | ||
| 289 | uint64_t S = getARMThunkDestVA(Destination); | ||
| 290 | if (S & 1) { | ||
| 291 | MayUseShortThunk = false; | ||
| 292 | return false; | ||
| 293 | } | ||
| 294 | uint64_t P = getThunkTargetSym()->getVA(); | ||
| 295 | int64_t Offset = S - P - 8; | ||
| 296 | MayUseShortThunk = llvm::isInt<26>(Offset); | ||
| 297 | return MayUseShortThunk; | ||
| 298 | } | ||
| 299 | |||
| 300 | void ARMThunk::writeTo(uint8_t *Buf) { | ||
| 301 | if (!mayUseShortThunk()) { | ||
| 302 | writeLong(Buf); | ||
| 303 | return; | ||
| 304 | } | ||
| 305 | |||
| 306 | uint64_t S = getARMThunkDestVA(Destination); | ||
| 307 | uint64_t P = getThunkTargetSym()->getVA(); | ||
| 308 | int64_t Offset = S - P - 8; | ||
| 309 | const uint8_t Data[] = { | ||
| 310 | 0x00, 0x00, 0x00, 0xea, // b S | ||
| 311 | }; | ||
| 312 | memcpy(Buf, Data, sizeof(Data)); | ||
| 313 | Target->relocateOne(Buf, R_ARM_JUMP24, Offset); | ||
| 314 | } | ||
| 315 | |||
| 316 | bool ARMThunk::isCompatibleWith(RelType Type) const { | ||
| 317 | // Thumb branch relocations can't use BLX | ||
| 318 | return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24; | ||
| 319 | } | ||
| 320 | |||
| 321 | // This function returns true if the target is Thumb and is within 2^25, and | ||
| 322 | // it has not previously returned false (see comment for MayUseShortThunk). | ||
| 323 | bool ThumbThunk::mayUseShortThunk() { | ||
| 324 | if (!MayUseShortThunk) | ||
| 325 | return false; | ||
| 326 | uint64_t S = getARMThunkDestVA(Destination); | ||
| 327 | if ((S & 1) == 0) { | ||
| 328 | MayUseShortThunk = false; | ||
| 329 | return false; | ||
| 330 | } | ||
| 331 | uint64_t P = getThunkTargetSym()->getVA() & ~1; | ||
| 332 | int64_t Offset = S - P - 4; | ||
| 333 | MayUseShortThunk = llvm::isInt<25>(Offset); | ||
| 334 | return MayUseShortThunk; | ||
| 335 | } | ||
| 336 | |||
| 337 | void ThumbThunk::writeTo(uint8_t *Buf) { | ||
| 338 | if (!mayUseShortThunk()) { | ||
| 339 | writeLong(Buf); | ||
| 340 | return; | ||
| 341 | } | ||
| 342 | |||
| 343 | uint64_t S = getARMThunkDestVA(Destination); | ||
| 344 | uint64_t P = getThunkTargetSym()->getVA(); | ||
| 345 | int64_t Offset = S - P - 4; | ||
| 346 | const uint8_t Data[] = { | ||
| 347 | 0x00, 0xf0, 0x00, 0xb0, // b.w S | ||
| 348 | }; | ||
| 349 | memcpy(Buf, Data, sizeof(Data)); | ||
| 350 | Target->relocateOne(Buf, R_ARM_THM_JUMP24, Offset); | ||
| 351 | } | ||
| 352 | |||
| 353 | bool ThumbThunk::isCompatibleWith(RelType Type) const { | ||
| 354 | // ARM branch relocations can't use BLX | ||
| 355 | return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32; | ||
| 356 | } | ||
| 357 | |||
| 358 | void ARMV7ABSLongThunk::writeLong(uint8_t *Buf) { | ||
| 206 | const uint8_t Data[] = { | 359 | const uint8_t Data[] = { |
| 207 | 0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S | 360 | 0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S |
| 208 | 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S | 361 | 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S |
| ... | @@ -215,18 +368,12 @@ void ARMV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ... | @@ -215,18 +368,12 @@ void ARMV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 215 | } | 368 | } |
| 216 | 369 | ||
| 217 | void ARMV7ABSLongThunk::addSymbols(ThunkSection &IS) { | 370 | void ARMV7ABSLongThunk::addSymbols(ThunkSection &IS) { |
| 218 | ThunkSym = addSyntheticLocal( | 371 | addSymbol(Saver.save("__ARMv7ABSLongThunk_" + Destination.getName()), |
| 219 | Saver.save("__ARMv7ABSLongThunk_" + Destination.getName()), STT_FUNC, | 372 | STT_FUNC, 0, IS); |
| 220 | Offset, size(), IS); | 373 | addSymbol("$a", STT_NOTYPE, 0, IS); |
| 221 | addSyntheticLocal("$a", STT_NOTYPE, Offset, 0, IS); | ||
| 222 | } | ||
| 223 | |||
| 224 | bool ARMV7ABSLongThunk::isCompatibleWith(RelType Type) const { | ||
| 225 | // Thumb branch relocations can't use BLX | ||
| 226 | return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24; | ||
| 227 | } | 374 | } |
| 228 | 375 | ||
| 229 | void ThumbV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | 376 | void ThumbV7ABSLongThunk::writeLong(uint8_t *Buf) { |
| 230 | const uint8_t Data[] = { | 377 | const uint8_t Data[] = { |
| 231 | 0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S | 378 | 0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S |
| 232 | 0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S | 379 | 0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S |
| ... | @@ -239,18 +386,12 @@ void ThumbV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ... | @@ -239,18 +386,12 @@ void ThumbV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 239 | } | 386 | } |
| 240 | 387 | ||
| 241 | void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) { | 388 | void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) { |
| 242 | ThunkSym = addSyntheticLocal( | 389 | addSymbol(Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()), |
| 243 | Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()), STT_FUNC, | 390 | STT_FUNC, 1, IS); |
| 244 | Offset | 0x1, size(), IS); | 391 | addSymbol("$t", STT_NOTYPE, 0, IS); |
| 245 | addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, IS); | ||
| 246 | } | 392 | } |
| 247 | 393 | ||
| 248 | bool ThumbV7ABSLongThunk::isCompatibleWith(RelType Type) const { | 394 | void ARMV7PILongThunk::writeLong(uint8_t *Buf) { |
| 249 | // ARM branch relocations can't use BLX | ||
| 250 | return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32; | ||
| 251 | } | ||
| 252 | |||
| 253 | void ARMV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ||
| 254 | const uint8_t Data[] = { | 395 | const uint8_t Data[] = { |
| 255 | 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) + 8) | 396 | 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) + 8) |
| 256 | 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P) + 8) | 397 | 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P) + 8) |
| ... | @@ -258,7 +399,7 @@ void ARMV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ... | @@ -258,7 +399,7 @@ void ARMV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 258 | 0x1c, 0xff, 0x2f, 0xe1, // bx r12 | 399 | 0x1c, 0xff, 0x2f, 0xe1, // bx r12 |
| 259 | }; | 400 | }; |
| 260 | uint64_t S = getARMThunkDestVA(Destination); | 401 | uint64_t S = getARMThunkDestVA(Destination); |
| 261 | uint64_t P = ThunkSym->getVA(); | 402 | uint64_t P = getThunkTargetSym()->getVA(); |
| 262 | uint64_t Offset = S - P - 16; | 403 | uint64_t Offset = S - P - 16; |
| 263 | memcpy(Buf, Data, sizeof(Data)); | 404 | memcpy(Buf, Data, sizeof(Data)); |
| 264 | Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset); | 405 | Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset); |
| ... | @@ -266,18 +407,12 @@ void ARMV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ... | @@ -266,18 +407,12 @@ void ARMV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 266 | } | 407 | } |
| 267 | 408 | ||
| 268 | void ARMV7PILongThunk::addSymbols(ThunkSection &IS) { | 409 | void ARMV7PILongThunk::addSymbols(ThunkSection &IS) { |
| 269 | ThunkSym = addSyntheticLocal( | 410 | addSymbol(Saver.save("__ARMV7PILongThunk_" + Destination.getName()), STT_FUNC, |
| 270 | Saver.save("__ARMV7PILongThunk_" + Destination.getName()), STT_FUNC, | 411 | 0, IS); |
| 271 | Offset, size(), IS); | 412 | addSymbol("$a", STT_NOTYPE, 0, IS); |
| 272 | addSyntheticLocal("$a", STT_NOTYPE, Offset, 0, IS); | ||
| 273 | } | 413 | } |
| 274 | 414 | ||
| 275 | bool ARMV7PILongThunk::isCompatibleWith(RelType Type) const { | 415 | void ThumbV7PILongThunk::writeLong(uint8_t *Buf) { |
| 276 | // Thumb branch relocations can't use BLX | ||
| 277 | return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24; | ||
| 278 | } | ||
| 279 | |||
| 280 | void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ||
| 281 | const uint8_t Data[] = { | 416 | const uint8_t Data[] = { |
| 282 | 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4) | 417 | 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4) |
| 283 | 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4) | 418 | 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P) + 4) |
| ... | @@ -285,7 +420,7 @@ void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ... | @@ -285,7 +420,7 @@ void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 285 | 0x60, 0x47, // bx r12 | 420 | 0x60, 0x47, // bx r12 |
| 286 | }; | 421 | }; |
| 287 | uint64_t S = getARMThunkDestVA(Destination); | 422 | uint64_t S = getARMThunkDestVA(Destination); |
| 288 | uint64_t P = ThunkSym->getVA() & ~0x1; | 423 | uint64_t P = getThunkTargetSym()->getVA() & ~0x1; |
| 289 | uint64_t Offset = S - P - 12; | 424 | uint64_t Offset = S - P - 12; |
| 290 | memcpy(Buf, Data, sizeof(Data)); | 425 | memcpy(Buf, Data, sizeof(Data)); |
| 291 | Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset); | 426 | Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset); |
| ... | @@ -293,32 +428,25 @@ void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { | ... | @@ -293,32 +428,25 @@ void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const { |
| 293 | } | 428 | } |
| 294 | 429 | ||
| 295 | void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) { | 430 | void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) { |
| 296 | ThunkSym = addSyntheticLocal( | 431 | addSymbol(Saver.save("__ThumbV7PILongThunk_" + Destination.getName()), |
| 297 | Saver.save("__ThumbV7PILongThunk_" + Destination.getName()), STT_FUNC, | 432 | STT_FUNC, 1, IS); |
| 298 | Offset | 0x1, size(), IS); | 433 | addSymbol("$t", STT_NOTYPE, 0, IS); |
| 299 | addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, IS); | ||
| 300 | } | ||
| 301 | |||
| 302 | bool ThumbV7PILongThunk::isCompatibleWith(RelType Type) const { | ||
| 303 | // ARM branch relocations can't use BLX | ||
| 304 | return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32; | ||
| 305 | } | 434 | } |
| 306 | 435 | ||
| 307 | // Write MIPS LA25 thunk code to call PIC function from the non-PIC one. | 436 | // Write MIPS LA25 thunk code to call PIC function from the non-PIC one. |
| 308 | void MipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const { | 437 | void MipsThunk::writeTo(uint8_t *Buf) { |
| 309 | uint64_t S = Destination.getVA(); | 438 | uint64_t S = Destination.getVA(); |
| 310 | write32(Buf, 0x3c190000, Config->Endianness); // lui $25, %hi(func) | 439 | write32(Buf, 0x3c190000); // lui $25, %hi(func) |
| 311 | write32(Buf + 4, 0x08000000 | (S >> 2), Config->Endianness); // j func | 440 | write32(Buf + 4, 0x08000000 | (S >> 2)); // j func |
| 312 | write32(Buf + 8, 0x27390000, Config->Endianness); // addiu $25, $25, %lo(func) | 441 | write32(Buf + 8, 0x27390000); // addiu $25, $25, %lo(func) |
| 313 | write32(Buf + 12, 0x00000000, Config->Endianness); // nop | 442 | write32(Buf + 12, 0x00000000); // nop |
| 314 | Target->relocateOne(Buf, R_MIPS_HI16, S); | 443 | Target->relocateOne(Buf, R_MIPS_HI16, S); |
| 315 | Target->relocateOne(Buf + 8, R_MIPS_LO16, S); | 444 | Target->relocateOne(Buf + 8, R_MIPS_LO16, S); |
| 316 | } | 445 | } |
| 317 | 446 | ||
| 318 | void MipsThunk::addSymbols(ThunkSection &IS) { | 447 | void MipsThunk::addSymbols(ThunkSection &IS) { |
| 319 | ThunkSym = | 448 | addSymbol(Saver.save("__LA25Thunk_" + Destination.getName()), STT_FUNC, 0, |
| 320 | addSyntheticLocal(Saver.save("__LA25Thunk_" + Destination.getName()), | 449 | IS); |
| 321 | STT_FUNC, Offset, size(), IS); | ||
| 322 | } | 450 | } |
| 323 | 451 | ||
| 324 | InputSection *MipsThunk::getTargetInputSection() const { | 452 | InputSection *MipsThunk::getTargetInputSection() const { |
| ... | @@ -328,22 +456,21 @@ InputSection *MipsThunk::getTargetInputSection() const { | ... | @@ -328,22 +456,21 @@ InputSection *MipsThunk::getTargetInputSection() const { |
| 328 | 456 | ||
| 329 | // Write microMIPS R2-R5 LA25 thunk code | 457 | // Write microMIPS R2-R5 LA25 thunk code |
| 330 | // to call PIC function from the non-PIC one. | 458 | // to call PIC function from the non-PIC one. |
| 331 | void MicroMipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const { | 459 | void MicroMipsThunk::writeTo(uint8_t *Buf) { |
| 332 | uint64_t S = Destination.getVA() | 1; | 460 | uint64_t S = Destination.getVA() | 1; |
| 333 | write16(Buf, 0x41b9, Config->Endianness); // lui $25, %hi(func) | 461 | write16(Buf, 0x41b9); // lui $25, %hi(func) |
| 334 | write16(Buf + 4, 0xd400, Config->Endianness); // j func | 462 | write16(Buf + 4, 0xd400); // j func |
| 335 | write16(Buf + 8, 0x3339, Config->Endianness); // addiu $25, $25, %lo(func) | 463 | write16(Buf + 8, 0x3339); // addiu $25, $25, %lo(func) |
| 336 | write16(Buf + 12, 0x0c00, Config->Endianness); // nop | 464 | write16(Buf + 12, 0x0c00); // nop |
| 337 | Target->relocateOne(Buf, R_MICROMIPS_HI16, S); | 465 | Target->relocateOne(Buf, R_MICROMIPS_HI16, S); |
| 338 | Target->relocateOne(Buf + 4, R_MICROMIPS_26_S1, S); | 466 | Target->relocateOne(Buf + 4, R_MICROMIPS_26_S1, S); |
| 339 | Target->relocateOne(Buf + 8, R_MICROMIPS_LO16, S); | 467 | Target->relocateOne(Buf + 8, R_MICROMIPS_LO16, S); |
| 340 | } | 468 | } |
| 341 | 469 | ||
| 342 | void MicroMipsThunk::addSymbols(ThunkSection &IS) { | 470 | void MicroMipsThunk::addSymbols(ThunkSection &IS) { |
| 343 | ThunkSym = | 471 | Defined *D = addSymbol( |
| 344 | addSyntheticLocal(Saver.save("__microLA25Thunk_" + Destination.getName()), | 472 | Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS); |
| 345 | STT_FUNC, Offset, size(), IS); | 473 | D->StOther |= STO_MIPS_MICROMIPS; |
| 346 | ThunkSym->StOther |= STO_MIPS_MICROMIPS; | ||
| 347 | } | 474 | } |
| 348 | 475 | ||
| 349 | InputSection *MicroMipsThunk::getTargetInputSection() const { | 476 | InputSection *MicroMipsThunk::getTargetInputSection() const { |
| ... | @@ -353,22 +480,21 @@ InputSection *MicroMipsThunk::getTargetInputSection() const { | ... | @@ -353,22 +480,21 @@ InputSection *MicroMipsThunk::getTargetInputSection() const { |
| 353 | 480 | ||
| 354 | // Write microMIPS R6 LA25 thunk code | 481 | // Write microMIPS R6 LA25 thunk code |
| 355 | // to call PIC function from the non-PIC one. | 482 | // to call PIC function from the non-PIC one. |
| 356 | void MicroMipsR6Thunk::writeTo(uint8_t *Buf, ThunkSection &) const { | 483 | void MicroMipsR6Thunk::writeTo(uint8_t *Buf) { |
| 357 | uint64_t S = Destination.getVA() | 1; | 484 | uint64_t S = Destination.getVA() | 1; |
| 358 | uint64_t P = ThunkSym->getVA(); | 485 | uint64_t P = getThunkTargetSym()->getVA(); |
| 359 | write16(Buf, 0x1320, Config->Endianness); // lui $25, %hi(func) | 486 | write16(Buf, 0x1320); // lui $25, %hi(func) |
| 360 | write16(Buf + 4, 0x3339, Config->Endianness); // addiu $25, $25, %lo(func) | 487 | write16(Buf + 4, 0x3339); // addiu $25, $25, %lo(func) |
| 361 | write16(Buf + 8, 0x9400, Config->Endianness); // bc func | 488 | write16(Buf + 8, 0x9400); // bc func |
| 362 | Target->relocateOne(Buf, R_MICROMIPS_HI16, S); | 489 | Target->relocateOne(Buf, R_MICROMIPS_HI16, S); |
| 363 | Target->relocateOne(Buf + 4, R_MICROMIPS_LO16, S); | 490 | Target->relocateOne(Buf + 4, R_MICROMIPS_LO16, S); |
| 364 | Target->relocateOne(Buf + 8, R_MICROMIPS_PC26_S1, S - P - 12); | 491 | Target->relocateOne(Buf + 8, R_MICROMIPS_PC26_S1, S - P - 12); |
| 365 | } | 492 | } |
| 366 | 493 | ||
| 367 | void MicroMipsR6Thunk::addSymbols(ThunkSection &IS) { | 494 | void MicroMipsR6Thunk::addSymbols(ThunkSection &IS) { |
| 368 | ThunkSym = | 495 | Defined *D = addSymbol( |
| 369 | addSyntheticLocal(Saver.save("__microLA25Thunk_" + Destination.getName()), | 496 | Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS); |
| 370 | STT_FUNC, Offset, size(), IS); | 497 | D->StOther |= STO_MIPS_MICROMIPS; |
| 371 | ThunkSym->StOther |= STO_MIPS_MICROMIPS; | ||
| 372 | } | 498 | } |
| 373 | 499 | ||
| 374 | InputSection *MicroMipsR6Thunk::getTargetInputSection() const { | 500 | InputSection *MicroMipsR6Thunk::getTargetInputSection() const { |
| ... | @@ -376,6 +502,25 @@ InputSection *MicroMipsR6Thunk::getTargetInputSection() const { | ... | @@ -376,6 +502,25 @@ InputSection *MicroMipsR6Thunk::getTargetInputSection() const { |
| 376 | return dyn_cast<InputSection>(DR.Section); | 502 | return dyn_cast<InputSection>(DR.Section); |
| 377 | } | 503 | } |
| 378 | 504 | ||
| 505 | void PPC64PltCallStub::writeTo(uint8_t *Buf) { | ||
| 506 | int64_t Off = Destination.getGotPltVA() - getPPC64TocBase(); | ||
| 507 | // Need to add 0x8000 to offset to account for the low bits being signed. | ||
| 508 | uint16_t OffHa = (Off + 0x8000) >> 16; | ||
| 509 | uint16_t OffLo = Off; | ||
| 510 | |||
| 511 | write32(Buf + 0, 0xf8410018); // std r2,24(r1) | ||
| 512 | write32(Buf + 4, 0x3d820000 | OffHa); // addis r12,r2, X@plt@to@ha | ||
| 513 | write32(Buf + 8, 0xe98c0000 | OffLo); // ld r12,X@plt@toc@l(r12) | ||
| 514 | write32(Buf + 12, 0x7d8903a6); // mtctr r12 | ||
| 515 | write32(Buf + 16, 0x4e800420); // bctr | ||
| 516 | } | ||
| 517 | |||
| 518 | void PPC64PltCallStub::addSymbols(ThunkSection &IS) { | ||
| 519 | Defined *S = addSymbol(Saver.save("__plt_" + Destination.getName()), STT_FUNC, | ||
| 520 | 0, IS); | ||
| 521 | S->NeedsTocRestore = true; | ||
| 522 | } | ||
| 523 | |||
| 379 | Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {} | 524 | Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {} |
| 380 | 525 | ||
| 381 | Thunk::~Thunk() = default; | 526 | Thunk::~Thunk() = default; |
| ... | @@ -419,15 +564,26 @@ static Thunk *addThunkMips(RelType Type, Symbol &S) { | ... | @@ -419,15 +564,26 @@ static Thunk *addThunkMips(RelType Type, Symbol &S) { |
| 419 | return make<MipsThunk>(S); | 564 | return make<MipsThunk>(S); |
| 420 | } | 565 | } |
| 421 | 566 | ||
| 567 | static Thunk *addThunkPPC64(RelType Type, Symbol &S) { | ||
| 568 | if (Type == R_PPC64_REL24) | ||
| 569 | return make<PPC64PltCallStub>(S); | ||
| 570 | fatal("unexpected relocation type"); | ||
| 571 | } | ||
| 572 | |||
| 422 | Thunk *addThunk(RelType Type, Symbol &S) { | 573 | Thunk *addThunk(RelType Type, Symbol &S) { |
| 423 | if (Config->EMachine == EM_AARCH64) | 574 | if (Config->EMachine == EM_AARCH64) |
| 424 | return addThunkAArch64(Type, S); | 575 | return addThunkAArch64(Type, S); |
| 425 | else if (Config->EMachine == EM_ARM) | 576 | |
| 577 | if (Config->EMachine == EM_ARM) | ||
| 426 | return addThunkArm(Type, S); | 578 | return addThunkArm(Type, S); |
| 427 | else if (Config->EMachine == EM_MIPS) | 579 | |
| 580 | if (Config->EMachine == EM_MIPS) | ||
| 428 | return addThunkMips(Type, S); | 581 | return addThunkMips(Type, S); |
| 429 | llvm_unreachable("add Thunk only supported for ARM and Mips"); | 582 | |
| 430 | return nullptr; | 583 | if (Config->EMachine == EM_PPC64) |
| 584 | return addThunkPPC64(Type, S); | ||
| 585 | |||
| 586 | llvm_unreachable("add Thunk only supported for ARM, Mips and PowerPC"); | ||
| 431 | } | 587 | } |
| 432 | 588 | ||
| 433 | } // end namespace elf | 589 | } // end namespace elf |
deps/lld/ELF/Thunks.h+14-6| ... | @@ -14,6 +14,7 @@ | ... | @@ -14,6 +14,7 @@ |
| 14 | 14 | ||
| 15 | namespace lld { | 15 | namespace lld { |
| 16 | namespace elf { | 16 | namespace elf { |
| 17 | class Defined; | ||
| 17 | class Symbol; | 18 | class Symbol; |
| 18 | class ThunkSection; | 19 | class ThunkSection; |
| 19 | // Class to describe an instance of a Thunk. | 20 | // Class to describe an instance of a Thunk. |
| ... | @@ -30,12 +31,17 @@ public: | ... | @@ -30,12 +31,17 @@ public: |
| 30 | Thunk(Symbol &Destination); | 31 | Thunk(Symbol &Destination); |
| 31 | virtual ~Thunk(); | 32 | virtual ~Thunk(); |
| 32 | 33 | ||
| 33 | virtual uint32_t size() const { return 0; } | 34 | virtual uint32_t size() = 0; |
| 34 | virtual void writeTo(uint8_t *Buf, ThunkSection &IS) const {} | 35 | virtual void writeTo(uint8_t *Buf) = 0; |
| 35 | 36 | ||
| 36 | // All Thunks must define at least one symbol ThunkSym so that we can | 37 | // All Thunks must define at least one symbol, known as the thunk target |
| 37 | // redirect relocations to it. | 38 | // symbol, so that we can redirect relocations to it. The thunk may define |
| 38 | virtual void addSymbols(ThunkSection &IS) {} | 39 | // additional symbols, but these are never targets for relocations. |
| 40 | virtual void addSymbols(ThunkSection &IS) = 0; | ||
| 41 | |||
| 42 | void setOffset(uint64_t Offset); | ||
| 43 | Defined *addSymbol(StringRef Name, uint8_t Type, uint64_t Value, | ||
| 44 | InputSectionBase &Section); | ||
| 39 | 45 | ||
| 40 | // Some Thunks must be placed immediately before their Target as they elide | 46 | // Some Thunks must be placed immediately before their Target as they elide |
| 41 | // a branch and fall through to the first Symbol in the Target. | 47 | // a branch and fall through to the first Symbol in the Target. |
| ... | @@ -45,10 +51,12 @@ public: | ... | @@ -45,10 +51,12 @@ public: |
| 45 | // compatible with it. | 51 | // compatible with it. |
| 46 | virtual bool isCompatibleWith(RelType Type) const { return true; } | 52 | virtual bool isCompatibleWith(RelType Type) const { return true; } |
| 47 | 53 | ||
| 54 | Defined *getThunkTargetSym() const { return Syms[0]; } | ||
| 55 | |||
| 48 | // The alignment requirement for this Thunk, defaults to the size of the | 56 | // The alignment requirement for this Thunk, defaults to the size of the |
| 49 | // typical code section alignment. | 57 | // typical code section alignment. |
| 50 | Symbol &Destination; | 58 | Symbol &Destination; |
| 51 | Symbol *ThunkSym; | 59 | llvm::SmallVector<Defined *, 3> Syms; |
| 52 | uint64_t Offset = 0; | 60 | uint64_t Offset = 0; |
| 53 | uint32_t Alignment = 4; | 61 | uint32_t Alignment = 4; |
| 54 | }; | 62 | }; |
deps/lld/ELF/Writer.cpp+533-204| ... | @@ -9,18 +9,19 @@ | ... | @@ -9,18 +9,19 @@ |
| 9 | 9 | ||
| 10 | #include "Writer.h" | 10 | #include "Writer.h" |
| 11 | #include "AArch64ErrataFix.h" | 11 | #include "AArch64ErrataFix.h" |
| 12 | #include "CallGraphSort.h" | ||
| 12 | #include "Config.h" | 13 | #include "Config.h" |
| 13 | #include "Filesystem.h" | 14 | #include "Filesystem.h" |
| 14 | #include "LinkerScript.h" | 15 | #include "LinkerScript.h" |
| 15 | #include "MapFile.h" | 16 | #include "MapFile.h" |
| 16 | #include "OutputSections.h" | 17 | #include "OutputSections.h" |
| 17 | #include "Relocations.h" | 18 | #include "Relocations.h" |
| 18 | #include "Strings.h" | ||
| 19 | #include "SymbolTable.h" | 19 | #include "SymbolTable.h" |
| 20 | #include "Symbols.h" | 20 | #include "Symbols.h" |
| 21 | #include "SyntheticSections.h" | 21 | #include "SyntheticSections.h" |
| 22 | #include "Target.h" | 22 | #include "Target.h" |
| 23 | #include "lld/Common/Memory.h" | 23 | #include "lld/Common/Memory.h" |
| 24 | #include "lld/Common/Strings.h" | ||
| 24 | #include "lld/Common/Threads.h" | 25 | #include "lld/Common/Threads.h" |
| 25 | #include "llvm/ADT/StringMap.h" | 26 | #include "llvm/ADT/StringMap.h" |
| 26 | #include "llvm/ADT/StringSwitch.h" | 27 | #include "llvm/ADT/StringSwitch.h" |
| ... | @@ -49,7 +50,7 @@ public: | ... | @@ -49,7 +50,7 @@ public: |
| 49 | private: | 50 | private: |
| 50 | void copyLocalSymbols(); | 51 | void copyLocalSymbols(); |
| 51 | void addSectionSymbols(); | 52 | void addSectionSymbols(); |
| 52 | void forEachRelSec(std::function<void(InputSectionBase &)> Fn); | 53 | void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn); |
| 53 | void sortSections(); | 54 | void sortSections(); |
| 54 | void resolveShfLinkOrder(); | 55 | void resolveShfLinkOrder(); |
| 55 | void sortInputSections(); | 56 | void sortInputSections(); |
| ... | @@ -62,6 +63,7 @@ private: | ... | @@ -62,6 +63,7 @@ private: |
| 62 | void assignFileOffsets(); | 63 | void assignFileOffsets(); |
| 63 | void assignFileOffsetsBinary(); | 64 | void assignFileOffsetsBinary(); |
| 64 | void setPhdrs(); | 65 | void setPhdrs(); |
| 66 | void checkSections(); | ||
| 65 | void fixSectionAlignments(); | 67 | void fixSectionAlignments(); |
| 66 | void openFile(); | 68 | void openFile(); |
| 67 | void writeTrapInstr(); | 69 | void writeTrapInstr(); |
| ... | @@ -81,39 +83,48 @@ private: | ... | @@ -81,39 +83,48 @@ private: |
| 81 | 83 | ||
| 82 | uint64_t FileSize; | 84 | uint64_t FileSize; |
| 83 | uint64_t SectionHeaderOff; | 85 | uint64_t SectionHeaderOff; |
| 84 | |||
| 85 | bool HasGotBaseSym = false; | ||
| 86 | }; | 86 | }; |
| 87 | } // anonymous namespace | 87 | } // anonymous namespace |
| 88 | 88 | ||
| 89 | StringRef elf::getOutputSectionName(InputSectionBase *S) { | 89 | static bool isSectionPrefix(StringRef Prefix, StringRef Name) { |
| 90 | // ".zdebug_" is a prefix for ZLIB-compressed sections. | 90 | return Name.startswith(Prefix) || Name == Prefix.drop_back(); |
| 91 | // Because we decompressed input sections, we want to remove 'z'. | 91 | } |
| 92 | if (S->Name.startswith(".zdebug_")) | ||
| 93 | return Saver.save("." + S->Name.substr(2)); | ||
| 94 | 92 | ||
| 93 | StringRef elf::getOutputSectionName(const InputSectionBase *S) { | ||
| 95 | if (Config->Relocatable) | 94 | if (Config->Relocatable) |
| 96 | return S->Name; | 95 | return S->Name; |
| 97 | 96 | ||
| 98 | // This is for --emit-relocs. If .text.foo is emitted as .text.bar, we want | 97 | // This is for --emit-relocs. If .text.foo is emitted as .text.bar, we want |
| 99 | // to emit .rela.text.foo as .rela.text.bar for consistency (this is not | 98 | // to emit .rela.text.foo as .rela.text.bar for consistency (this is not |
| 100 | // technically required, but not doing it is odd). This code guarantees that. | 99 | // technically required, but not doing it is odd). This code guarantees that. |
| 101 | if ((S->Type == SHT_REL || S->Type == SHT_RELA) && | 100 | if (auto *IS = dyn_cast<InputSection>(S)) { |
| 102 | !isa<SyntheticSection>(S)) { | 101 | if (InputSectionBase *Rel = IS->getRelocatedSection()) { |
| 103 | OutputSection *Out = | 102 | OutputSection *Out = Rel->getOutputSection(); |
| 104 | cast<InputSection>(S)->getRelocatedSection()->getOutputSection(); | 103 | if (S->Type == SHT_RELA) |
| 105 | if (S->Type == SHT_RELA) | 104 | return Saver.save(".rela" + Out->Name); |
| 106 | return Saver.save(".rela" + Out->Name); | 105 | return Saver.save(".rel" + Out->Name); |
| 107 | return Saver.save(".rel" + Out->Name); | 106 | } |
| 108 | } | 107 | } |
| 109 | 108 | ||
| 109 | // This check is for -z keep-text-section-prefix. This option separates text | ||
| 110 | // sections with prefix ".text.hot", ".text.unlikely", ".text.startup" or | ||
| 111 | // ".text.exit". | ||
| 112 | // When enabled, this allows identifying the hot code region (.text.hot) in | ||
| 113 | // the final binary which can be selectively mapped to huge pages or mlocked, | ||
| 114 | // for instance. | ||
| 115 | if (Config->ZKeepTextSectionPrefix) | ||
| 116 | for (StringRef V : | ||
| 117 | {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."}) { | ||
| 118 | if (isSectionPrefix(V, S->Name)) | ||
| 119 | return V.drop_back(); | ||
| 120 | } | ||
| 121 | |||
| 110 | for (StringRef V : | 122 | for (StringRef V : |
| 111 | {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.", | 123 | {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.", |
| 112 | ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", | 124 | ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", |
| 113 | ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) { | 125 | ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) { |
| 114 | StringRef Prefix = V.drop_back(); | 126 | if (isSectionPrefix(V, S->Name)) |
| 115 | if (S->Name.startswith(V) || S->Name == Prefix) | 127 | return V.drop_back(); |
| 116 | return Prefix; | ||
| 117 | } | 128 | } |
| 118 | 129 | ||
| 119 | // CommonSection is identified as "COMMON" in linker scripts. | 130 | // CommonSection is identified as "COMMON" in linker scripts. |
| ... | @@ -194,21 +205,30 @@ void elf::addReservedSymbols() { | ... | @@ -194,21 +205,30 @@ void elf::addReservedSymbols() { |
| 194 | Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL); | 205 | Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL); |
| 195 | } | 206 | } |
| 196 | 207 | ||
| 208 | // The Power Architecture 64-bit v2 ABI defines a TableOfContents (TOC) which | ||
| 209 | // combines the typical ELF GOT with the small data sections. It commonly | ||
| 210 | // includes .got .toc .sdata .sbss. The .TOC. symbol replaces both | ||
| 211 | // _GLOBAL_OFFSET_TABLE_ and _SDA_BASE_ from the 32-bit ABI. It is used to | ||
| 212 | // represent the TOC base which is offset by 0x8000 bytes from the start of | ||
| 213 | // the .got section. | ||
| 197 | ElfSym::GlobalOffsetTable = addOptionalRegular( | 214 | ElfSym::GlobalOffsetTable = addOptionalRegular( |
| 198 | "_GLOBAL_OFFSET_TABLE_", Out::ElfHeader, Target->GotBaseSymOff); | 215 | (Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_", |
| 216 | Out::ElfHeader, Target->GotBaseSymOff); | ||
| 199 | 217 | ||
| 200 | // __ehdr_start is the location of ELF file headers. Note that we define | 218 | // __ehdr_start is the location of ELF file headers. Note that we define |
| 201 | // this symbol unconditionally even when using a linker script, which | 219 | // this symbol unconditionally even when using a linker script, which |
| 202 | // differs from the behavior implemented by GNU linker which only define | 220 | // differs from the behavior implemented by GNU linker which only define |
| 203 | // this symbol if ELF headers are in the memory mapped segment. | 221 | // this symbol if ELF headers are in the memory mapped segment. |
| 222 | addOptionalRegular("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN); | ||
| 223 | |||
| 204 | // __executable_start is not documented, but the expectation of at | 224 | // __executable_start is not documented, but the expectation of at |
| 205 | // least the android libc is that it points to the elf header too. | 225 | // least the Android libc is that it points to the ELF header. |
| 226 | addOptionalRegular("__executable_start", Out::ElfHeader, 0, STV_HIDDEN); | ||
| 227 | |||
| 206 | // __dso_handle symbol is passed to cxa_finalize as a marker to identify | 228 | // __dso_handle symbol is passed to cxa_finalize as a marker to identify |
| 207 | // each DSO. The address of the symbol doesn't matter as long as they are | 229 | // each DSO. The address of the symbol doesn't matter as long as they are |
| 208 | // different in different DSOs, so we chose the start address of the DSO. | 230 | // different in different DSOs, so we chose the start address of the DSO. |
| 209 | for (const char *Name : | 231 | addOptionalRegular("__dso_handle", Out::ElfHeader, 0, STV_HIDDEN); |
| 210 | {"__ehdr_start", "__executable_start", "__dso_handle"}) | ||
| 211 | addOptionalRegular(Name, Out::ElfHeader, 0, STV_HIDDEN); | ||
| 212 | 232 | ||
| 213 | // If linker script do layout we do not need to create any standart symbols. | 233 | // If linker script do layout we do not need to create any standart symbols. |
| 214 | if (Script->HasSectionsCommand) | 234 | if (Script->HasSectionsCommand) |
| ... | @@ -267,6 +287,7 @@ template <class ELFT> static void createSyntheticSections() { | ... | @@ -267,6 +287,7 @@ template <class ELFT> static void createSyntheticSections() { |
| 267 | if (Config->Strip != StripPolicy::All) { | 287 | if (Config->Strip != StripPolicy::All) { |
| 268 | InX::StrTab = make<StringTableSection>(".strtab", false); | 288 | InX::StrTab = make<StringTableSection>(".strtab", false); |
| 269 | InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab); | 289 | InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab); |
| 290 | InX::SymTabShndx = make<SymtabShndxSection>(); | ||
| 270 | } | 291 | } |
| 271 | 292 | ||
| 272 | if (Config->BuildId != BuildIdKind::None) { | 293 | if (Config->BuildId != BuildIdKind::None) { |
| ... | @@ -280,10 +301,9 @@ template <class ELFT> static void createSyntheticSections() { | ... | @@ -280,10 +301,9 @@ template <class ELFT> static void createSyntheticSections() { |
| 280 | // If there is a SECTIONS command and a .data.rel.ro section name use name | 301 | // If there is a SECTIONS command and a .data.rel.ro section name use name |
| 281 | // .data.rel.ro.bss so that we match in the .data.rel.ro output section. | 302 | // .data.rel.ro.bss so that we match in the .data.rel.ro output section. |
| 282 | // This makes sure our relro is contiguous. | 303 | // This makes sure our relro is contiguous. |
| 283 | bool HasDataRelRo = | 304 | bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro"); |
| 284 | Script->HasSectionsCommand && findSection(".data.rel.ro"); | 305 | InX::BssRelRo = |
| 285 | InX::BssRelRo = make<BssSection>( | 306 | make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1); |
| 286 | HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1); | ||
| 287 | Add(InX::BssRelRo); | 307 | Add(InX::BssRelRo); |
| 288 | 308 | ||
| 289 | // Add MIPS-specific sections. | 309 | // Add MIPS-specific sections. |
| ... | @@ -330,6 +350,11 @@ template <class ELFT> static void createSyntheticSections() { | ... | @@ -330,6 +350,11 @@ template <class ELFT> static void createSyntheticSections() { |
| 330 | Add(InX::RelaDyn); | 350 | Add(InX::RelaDyn); |
| 331 | } | 351 | } |
| 332 | 352 | ||
| 353 | if (Config->RelrPackDynRelocs) { | ||
| 354 | InX::RelrDyn = make<RelrSection<ELFT>>(); | ||
| 355 | Add(InX::RelrDyn); | ||
| 356 | } | ||
| 357 | |||
| 333 | // Add .got. MIPS' .got is so different from the other archs, | 358 | // Add .got. MIPS' .got is so different from the other archs, |
| 334 | // it has its own class. | 359 | // it has its own class. |
| 335 | if (Config->EMachine == EM_MIPS) { | 360 | if (Config->EMachine == EM_MIPS) { |
| ... | @@ -346,7 +371,7 @@ template <class ELFT> static void createSyntheticSections() { | ... | @@ -346,7 +371,7 @@ template <class ELFT> static void createSyntheticSections() { |
| 346 | Add(InX::IgotPlt); | 371 | Add(InX::IgotPlt); |
| 347 | 372 | ||
| 348 | if (Config->GdbIndex) { | 373 | if (Config->GdbIndex) { |
| 349 | InX::GdbIndex = createGdbIndex<ELFT>(); | 374 | InX::GdbIndex = GdbIndexSection::create<ELFT>(); |
| 350 | Add(InX::GdbIndex); | 375 | Add(InX::GdbIndex); |
| 351 | } | 376 | } |
| 352 | 377 | ||
| ... | @@ -369,9 +394,9 @@ template <class ELFT> static void createSyntheticSections() { | ... | @@ -369,9 +394,9 @@ template <class ELFT> static void createSyntheticSections() { |
| 369 | false /*Sort*/); | 394 | false /*Sort*/); |
| 370 | Add(InX::RelaIplt); | 395 | Add(InX::RelaIplt); |
| 371 | 396 | ||
| 372 | InX::Plt = make<PltSection>(Target->PltHeaderSize); | 397 | InX::Plt = make<PltSection>(false); |
| 373 | Add(InX::Plt); | 398 | Add(InX::Plt); |
| 374 | InX::Iplt = make<PltSection>(0); | 399 | InX::Iplt = make<PltSection>(true); |
| 375 | Add(InX::Iplt); | 400 | Add(InX::Iplt); |
| 376 | 401 | ||
| 377 | if (!Config->Relocatable) { | 402 | if (!Config->Relocatable) { |
| ... | @@ -385,6 +410,8 @@ template <class ELFT> static void createSyntheticSections() { | ... | @@ -385,6 +410,8 @@ template <class ELFT> static void createSyntheticSections() { |
| 385 | 410 | ||
| 386 | if (InX::SymTab) | 411 | if (InX::SymTab) |
| 387 | Add(InX::SymTab); | 412 | Add(InX::SymTab); |
| 413 | if (InX::SymTabShndx) | ||
| 414 | Add(InX::SymTabShndx); | ||
| 388 | Add(InX::ShStrTab); | 415 | Add(InX::ShStrTab); |
| 389 | if (InX::StrTab) | 416 | if (InX::StrTab) |
| 390 | Add(InX::StrTab); | 417 | Add(InX::StrTab); |
| ... | @@ -454,6 +481,9 @@ template <class ELFT> void Writer<ELFT>::run() { | ... | @@ -454,6 +481,9 @@ template <class ELFT> void Writer<ELFT>::run() { |
| 454 | Sec->Addr = 0; | 481 | Sec->Addr = 0; |
| 455 | } | 482 | } |
| 456 | 483 | ||
| 484 | if (Config->CheckSections) | ||
| 485 | checkSections(); | ||
| 486 | |||
| 457 | // It does not make sense try to open the file if we have error already. | 487 | // It does not make sense try to open the file if we have error already. |
| 458 | if (errorCount()) | 488 | if (errorCount()) |
| 459 | return; | 489 | return; |
| ... | @@ -476,8 +506,9 @@ template <class ELFT> void Writer<ELFT>::run() { | ... | @@ -476,8 +506,9 @@ template <class ELFT> void Writer<ELFT>::run() { |
| 476 | if (errorCount()) | 506 | if (errorCount()) |
| 477 | return; | 507 | return; |
| 478 | 508 | ||
| 479 | // Handle -Map option. | 509 | // Handle -Map and -cref options. |
| 480 | writeMapFile(); | 510 | writeMapFile(); |
| 511 | writeCrossReferenceTable(); | ||
| 481 | if (errorCount()) | 512 | if (errorCount()) |
| 482 | return; | 513 | return; |
| 483 | 514 | ||
| ... | @@ -487,11 +518,7 @@ template <class ELFT> void Writer<ELFT>::run() { | ... | @@ -487,11 +518,7 @@ template <class ELFT> void Writer<ELFT>::run() { |
| 487 | 518 | ||
| 488 | static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName, | 519 | static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName, |
| 489 | const Symbol &B) { | 520 | const Symbol &B) { |
| 490 | if (B.isFile() || B.isSection()) | 521 | if (B.isSection()) |
| 491 | return false; | ||
| 492 | |||
| 493 | // If sym references a section in a discarded group, don't keep it. | ||
| 494 | if (Sec == &InputSection::Discarded) | ||
| 495 | return false; | 522 | return false; |
| 496 | 523 | ||
| 497 | if (Config->Discard == DiscardPolicy::None) | 524 | if (Config->Discard == DiscardPolicy::None) |
| ... | @@ -638,6 +665,9 @@ static bool isRelroSection(const OutputSection *Sec) { | ... | @@ -638,6 +665,9 @@ static bool isRelroSection(const OutputSection *Sec) { |
| 638 | if (InX::Got && Sec == InX::Got->getParent()) | 665 | if (InX::Got && Sec == InX::Got->getParent()) |
| 639 | return true; | 666 | return true; |
| 640 | 667 | ||
| 668 | if (Sec->Name.equals(".toc")) | ||
| 669 | return true; | ||
| 670 | |||
| 641 | // .got.plt contains pointers to external function symbols. They are | 671 | // .got.plt contains pointers to external function symbols. They are |
| 642 | // by default resolved lazily, so we usually cannot put it into RELRO. | 672 | // by default resolved lazily, so we usually cannot put it into RELRO. |
| 643 | // However, if "-z now" is given, the lazy symbol resolution is | 673 | // However, if "-z now" is given, the lazy symbol resolution is |
| ... | @@ -669,20 +699,22 @@ static bool isRelroSection(const OutputSection *Sec) { | ... | @@ -669,20 +699,22 @@ static bool isRelroSection(const OutputSection *Sec) { |
| 669 | // * It is easy to check if a give branch was taken. | 699 | // * It is easy to check if a give branch was taken. |
| 670 | // * It is easy two see how similar two ranks are (see getRankProximity). | 700 | // * It is easy two see how similar two ranks are (see getRankProximity). |
| 671 | enum RankFlags { | 701 | enum RankFlags { |
| 672 | RF_NOT_ADDR_SET = 1 << 16, | 702 | RF_NOT_ADDR_SET = 1 << 18, |
| 673 | RF_NOT_INTERP = 1 << 15, | 703 | RF_NOT_INTERP = 1 << 17, |
| 674 | RF_NOT_ALLOC = 1 << 14, | 704 | RF_NOT_ALLOC = 1 << 16, |
| 675 | RF_WRITE = 1 << 13, | 705 | RF_WRITE = 1 << 15, |
| 676 | RF_EXEC_WRITE = 1 << 12, | 706 | RF_EXEC_WRITE = 1 << 14, |
| 677 | RF_EXEC = 1 << 11, | 707 | RF_EXEC = 1 << 13, |
| 678 | RF_NON_TLS_BSS = 1 << 10, | 708 | RF_RODATA = 1 << 12, |
| 679 | RF_NON_TLS_BSS_RO = 1 << 9, | 709 | RF_NON_TLS_BSS = 1 << 11, |
| 680 | RF_NOT_TLS = 1 << 8, | 710 | RF_NON_TLS_BSS_RO = 1 << 10, |
| 681 | RF_BSS = 1 << 7, | 711 | RF_NOT_TLS = 1 << 9, |
| 712 | RF_BSS = 1 << 8, | ||
| 713 | RF_NOTE = 1 << 7, | ||
| 682 | RF_PPC_NOT_TOCBSS = 1 << 6, | 714 | RF_PPC_NOT_TOCBSS = 1 << 6, |
| 683 | RF_PPC_OPD = 1 << 5, | 715 | RF_PPC_TOCL = 1 << 5, |
| 684 | RF_PPC_TOCL = 1 << 4, | 716 | RF_PPC_TOC = 1 << 4, |
| 685 | RF_PPC_TOC = 1 << 3, | 717 | RF_PPC_GOT = 1 << 3, |
| 686 | RF_PPC_BRANCH_LT = 1 << 2, | 718 | RF_PPC_BRANCH_LT = 1 << 2, |
| 687 | RF_MIPS_GPREL = 1 << 1, | 719 | RF_MIPS_GPREL = 1 << 1, |
| 688 | RF_MIPS_NOT_GOT = 1 << 0 | 720 | RF_MIPS_NOT_GOT = 1 << 0 |
| ... | @@ -713,8 +745,7 @@ static unsigned getSectionRank(const OutputSection *Sec) { | ... | @@ -713,8 +745,7 @@ static unsigned getSectionRank(const OutputSection *Sec) { |
| 713 | // considerations: | 745 | // considerations: |
| 714 | // * Read-only sections come first such that they go in the | 746 | // * Read-only sections come first such that they go in the |
| 715 | // PT_LOAD covering the program headers at the start of the file. | 747 | // PT_LOAD covering the program headers at the start of the file. |
| 716 | // * Read-only, executable sections come next, unless the | 748 | // * Read-only, executable sections come next. |
| 717 | // -no-rosegment option is used. | ||
| 718 | // * Writable, executable sections follow such that .plt on | 749 | // * Writable, executable sections follow such that .plt on |
| 719 | // architectures where it needs to be writable will be placed | 750 | // architectures where it needs to be writable will be placed |
| 720 | // between .text and .data. | 751 | // between .text and .data. |
| ... | @@ -726,11 +757,16 @@ static unsigned getSectionRank(const OutputSection *Sec) { | ... | @@ -726,11 +757,16 @@ static unsigned getSectionRank(const OutputSection *Sec) { |
| 726 | if (IsExec) { | 757 | if (IsExec) { |
| 727 | if (IsWrite) | 758 | if (IsWrite) |
| 728 | Rank |= RF_EXEC_WRITE; | 759 | Rank |= RF_EXEC_WRITE; |
| 729 | else if (!Config->SingleRoRx) | 760 | else |
| 730 | Rank |= RF_EXEC; | 761 | Rank |= RF_EXEC; |
| 731 | } else { | 762 | } else if (IsWrite) { |
| 732 | if (IsWrite) | 763 | Rank |= RF_WRITE; |
| 733 | Rank |= RF_WRITE; | 764 | } else if (Sec->Type == SHT_PROGBITS) { |
| 765 | // Make non-executable and non-writable PROGBITS sections (e.g .rodata | ||
| 766 | // .eh_frame) closer to .text. They likely contain PC or GOT relative | ||
| 767 | // relocations and there could be relocation overflow if other huge sections | ||
| 768 | // (.dynstr .dynsym) were placed in between. | ||
| 769 | Rank |= RF_RODATA; | ||
| 734 | } | 770 | } |
| 735 | 771 | ||
| 736 | // If we got here we know that both A and B are in the same PT_LOAD. | 772 | // If we got here we know that both A and B are in the same PT_LOAD. |
| ... | @@ -766,6 +802,12 @@ static unsigned getSectionRank(const OutputSection *Sec) { | ... | @@ -766,6 +802,12 @@ static unsigned getSectionRank(const OutputSection *Sec) { |
| 766 | if (IsNoBits) | 802 | if (IsNoBits) |
| 767 | Rank |= RF_BSS; | 803 | Rank |= RF_BSS; |
| 768 | 804 | ||
| 805 | // We create a NOTE segment for contiguous .note sections, so make | ||
| 806 | // them contigous if there are more than one .note section with the | ||
| 807 | // same attributes. | ||
| 808 | if (Sec->Type == SHT_NOTE) | ||
| 809 | Rank |= RF_NOTE; | ||
| 810 | |||
| 769 | // Some architectures have additional ordering restrictions for sections | 811 | // Some architectures have additional ordering restrictions for sections |
| 770 | // within the same PT_LOAD. | 812 | // within the same PT_LOAD. |
| 771 | if (Config->EMachine == EM_PPC64) { | 813 | if (Config->EMachine == EM_PPC64) { |
| ... | @@ -779,18 +821,19 @@ static unsigned getSectionRank(const OutputSection *Sec) { | ... | @@ -779,18 +821,19 @@ static unsigned getSectionRank(const OutputSection *Sec) { |
| 779 | if (Name != ".tocbss") | 821 | if (Name != ".tocbss") |
| 780 | Rank |= RF_PPC_NOT_TOCBSS; | 822 | Rank |= RF_PPC_NOT_TOCBSS; |
| 781 | 823 | ||
| 782 | if (Name == ".opd") | ||
| 783 | Rank |= RF_PPC_OPD; | ||
| 784 | |||
| 785 | if (Name == ".toc1") | 824 | if (Name == ".toc1") |
| 786 | Rank |= RF_PPC_TOCL; | 825 | Rank |= RF_PPC_TOCL; |
| 787 | 826 | ||
| 788 | if (Name == ".toc") | 827 | if (Name == ".toc") |
| 789 | Rank |= RF_PPC_TOC; | 828 | Rank |= RF_PPC_TOC; |
| 790 | 829 | ||
| 830 | if (Name == ".got") | ||
| 831 | Rank |= RF_PPC_GOT; | ||
| 832 | |||
| 791 | if (Name == ".branch_lt") | 833 | if (Name == ".branch_lt") |
| 792 | Rank |= RF_PPC_BRANCH_LT; | 834 | Rank |= RF_PPC_BRANCH_LT; |
| 793 | } | 835 | } |
| 836 | |||
| 794 | if (Config->EMachine == EM_MIPS) { | 837 | if (Config->EMachine == EM_MIPS) { |
| 795 | // All sections with SHF_MIPS_GPREL flag should be grouped together | 838 | // All sections with SHF_MIPS_GPREL flag should be grouped together |
| 796 | // because data in these sections is addressable with a gp relative address. | 839 | // because data in these sections is addressable with a gp relative address. |
| ... | @@ -822,8 +865,6 @@ void PhdrEntry::add(OutputSection *Sec) { | ... | @@ -822,8 +865,6 @@ void PhdrEntry::add(OutputSection *Sec) { |
| 822 | p_align = std::max(p_align, Sec->Alignment); | 865 | p_align = std::max(p_align, Sec->Alignment); |
| 823 | if (p_type == PT_LOAD) | 866 | if (p_type == PT_LOAD) |
| 824 | Sec->PtLoad = this; | 867 | Sec->PtLoad = this; |
| 825 | if (Sec->LMAExpr) | ||
| 826 | ASectionHasLMA = true; | ||
| 827 | } | 868 | } |
| 828 | 869 | ||
| 829 | // The beginning and the ending of .rel[a].plt section are marked | 870 | // The beginning and the ending of .rel[a].plt section are marked |
| ... | @@ -833,17 +874,19 @@ void PhdrEntry::add(OutputSection *Sec) { | ... | @@ -833,17 +874,19 @@ void PhdrEntry::add(OutputSection *Sec) { |
| 833 | // need these symbols, since IRELATIVE relocs are resolved through GOT | 874 | // need these symbols, since IRELATIVE relocs are resolved through GOT |
| 834 | // and PLT. For details, see http://www.airs.com/blog/archives/403. | 875 | // and PLT. For details, see http://www.airs.com/blog/archives/403. |
| 835 | template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() { | 876 | template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() { |
| 836 | if (!Config->Static) | 877 | if (needsInterpSection()) |
| 837 | return; | 878 | return; |
| 838 | StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start"; | 879 | StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start"; |
| 839 | addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); | 880 | addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); |
| 840 | 881 | ||
| 841 | S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end"; | 882 | S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end"; |
| 842 | addOptionalRegular(S, InX::RelaIplt, -1, STV_HIDDEN, STB_WEAK); | 883 | ElfSym::RelaIpltEnd = |
| 884 | addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK); | ||
| 843 | } | 885 | } |
| 844 | 886 | ||
| 845 | template <class ELFT> | 887 | template <class ELFT> |
| 846 | void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) { | 888 | void Writer<ELFT>::forEachRelSec( |
| 889 | llvm::function_ref<void(InputSectionBase &)> Fn) { | ||
| 847 | // Scan all relocations. Each relocation goes through a series | 890 | // Scan all relocations. Each relocation goes through a series |
| 848 | // of tests to determine if it needs special treatment, such as | 891 | // of tests to determine if it needs special treatment, such as |
| 849 | // creating GOT, PLT, copy relocations, etc. | 892 | // creating GOT, PLT, copy relocations, etc. |
| ... | @@ -863,14 +906,18 @@ void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) { | ... | @@ -863,14 +906,18 @@ void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) { |
| 863 | // defining these symbols explicitly in the linker script. | 906 | // defining these symbols explicitly in the linker script. |
| 864 | template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() { | 907 | template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() { |
| 865 | if (ElfSym::GlobalOffsetTable) { | 908 | if (ElfSym::GlobalOffsetTable) { |
| 866 | // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to | 909 | // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually |
| 867 | // be at some offset from the base of the .got section, usually 0 or the end | 910 | // to the start of the .got or .got.plt section. |
| 868 | // of the .got | 911 | InputSection *GotSection = InX::GotPlt; |
| 869 | InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot) | 912 | if (!Target->GotBaseSymInGotPlt) |
| 870 | : cast<InputSection>(InX::Got); | 913 | GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot) |
| 914 | : cast<InputSection>(InX::Got); | ||
| 871 | ElfSym::GlobalOffsetTable->Section = GotSection; | 915 | ElfSym::GlobalOffsetTable->Section = GotSection; |
| 872 | } | 916 | } |
| 873 | 917 | ||
| 918 | if (ElfSym::RelaIpltEnd) | ||
| 919 | ElfSym::RelaIpltEnd->Value = InX::RelaIplt->getSize(); | ||
| 920 | |||
| 874 | PhdrEntry *Last = nullptr; | 921 | PhdrEntry *Last = nullptr; |
| 875 | PhdrEntry *LastRO = nullptr; | 922 | PhdrEntry *LastRO = nullptr; |
| 876 | 923 | ||
| ... | @@ -940,8 +987,7 @@ static int getRankProximityAux(OutputSection *A, OutputSection *B) { | ... | @@ -940,8 +987,7 @@ static int getRankProximityAux(OutputSection *A, OutputSection *B) { |
| 940 | 987 | ||
| 941 | static int getRankProximity(OutputSection *A, BaseCommand *B) { | 988 | static int getRankProximity(OutputSection *A, BaseCommand *B) { |
| 942 | if (auto *Sec = dyn_cast<OutputSection>(B)) | 989 | if (auto *Sec = dyn_cast<OutputSection>(B)) |
| 943 | if (Sec->Live) | 990 | return getRankProximityAux(A, Sec); |
| 944 | return getRankProximityAux(A, Sec); | ||
| 945 | return -1; | 991 | return -1; |
| 946 | } | 992 | } |
| 947 | 993 | ||
| ... | @@ -960,11 +1006,9 @@ static int getRankProximity(OutputSection *A, BaseCommand *B) { | ... | @@ -960,11 +1006,9 @@ static int getRankProximity(OutputSection *A, BaseCommand *B) { |
| 960 | // rw_sec : { *(rw_sec) } | 1006 | // rw_sec : { *(rw_sec) } |
| 961 | // would mean that the RW PT_LOAD would become unaligned. | 1007 | // would mean that the RW PT_LOAD would become unaligned. |
| 962 | static bool shouldSkip(BaseCommand *Cmd) { | 1008 | static bool shouldSkip(BaseCommand *Cmd) { |
| 963 | if (isa<OutputSection>(Cmd)) | ||
| 964 | return false; | ||
| 965 | if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd)) | 1009 | if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd)) |
| 966 | return Assign->Name != "."; | 1010 | return Assign->Name != "."; |
| 967 | return true; | 1011 | return false; |
| 968 | } | 1012 | } |
| 969 | 1013 | ||
| 970 | // We want to place orphan sections so that they share as much | 1014 | // We want to place orphan sections so that they share as much |
| ... | @@ -987,20 +1031,16 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B, | ... | @@ -987,20 +1031,16 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B, |
| 987 | int Proximity = getRankProximity(Sec, *I); | 1031 | int Proximity = getRankProximity(Sec, *I); |
| 988 | for (; I != E; ++I) { | 1032 | for (; I != E; ++I) { |
| 989 | auto *CurSec = dyn_cast<OutputSection>(*I); | 1033 | auto *CurSec = dyn_cast<OutputSection>(*I); |
| 990 | if (!CurSec || !CurSec->Live) | 1034 | if (!CurSec) |
| 991 | continue; | 1035 | continue; |
| 992 | if (getRankProximity(Sec, CurSec) != Proximity || | 1036 | if (getRankProximity(Sec, CurSec) != Proximity || |
| 993 | Sec->SortRank < CurSec->SortRank) | 1037 | Sec->SortRank < CurSec->SortRank) |
| 994 | break; | 1038 | break; |
| 995 | } | 1039 | } |
| 996 | 1040 | ||
| 997 | auto IsLiveSection = [](BaseCommand *Cmd) { | 1041 | auto IsOutputSec = [](BaseCommand *Cmd) { return isa<OutputSection>(Cmd); }; |
| 998 | auto *OS = dyn_cast<OutputSection>(Cmd); | ||
| 999 | return OS && OS->Live; | ||
| 1000 | }; | ||
| 1001 | |||
| 1002 | auto J = std::find_if(llvm::make_reverse_iterator(I), | 1042 | auto J = std::find_if(llvm::make_reverse_iterator(I), |
| 1003 | llvm::make_reverse_iterator(B), IsLiveSection); | 1043 | llvm::make_reverse_iterator(B), IsOutputSec); |
| 1004 | I = J.base(); | 1044 | I = J.base(); |
| 1005 | 1045 | ||
| 1006 | // As a special case, if the orphan section is the last section, put | 1046 | // As a special case, if the orphan section is the last section, put |
| ... | @@ -1008,7 +1048,7 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B, | ... | @@ -1008,7 +1048,7 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B, |
| 1008 | // This matches bfd's behavior and is convenient when the linker script fully | 1048 | // This matches bfd's behavior and is convenient when the linker script fully |
| 1009 | // specifies the start of the file, but doesn't care about the end (the non | 1049 | // specifies the start of the file, but doesn't care about the end (the non |
| 1010 | // alloc sections for example). | 1050 | // alloc sections for example). |
| 1011 | auto NextSec = std::find_if(I, E, IsLiveSection); | 1051 | auto NextSec = std::find_if(I, E, IsOutputSec); |
| 1012 | if (NextSec == E) | 1052 | if (NextSec == E) |
| 1013 | return E; | 1053 | return E; |
| 1014 | 1054 | ||
| ... | @@ -1017,32 +1057,172 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B, | ... | @@ -1017,32 +1057,172 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B, |
| 1017 | return I; | 1057 | return I; |
| 1018 | } | 1058 | } |
| 1019 | 1059 | ||
| 1020 | // If no layout was provided by linker script, we want to apply default | 1060 | // Builds section order for handling --symbol-ordering-file. |
| 1021 | // sorting for special input sections and handle --symbol-ordering-file. | 1061 | static DenseMap<const InputSectionBase *, int> buildSectionOrder() { |
| 1022 | template <class ELFT> void Writer<ELFT>::sortInputSections() { | 1062 | DenseMap<const InputSectionBase *, int> SectionOrder; |
| 1023 | assert(!Script->HasSectionsCommand); | 1063 | // Use the rarely used option -call-graph-ordering-file to sort sections. |
| 1064 | if (!Config->CallGraphProfile.empty()) | ||
| 1065 | return computeCallGraphProfileOrder(); | ||
| 1024 | 1066 | ||
| 1025 | // Sort input sections by priority using the list provided | 1067 | if (Config->SymbolOrderingFile.empty()) |
| 1026 | // by --symbol-ordering-file. | 1068 | return SectionOrder; |
| 1027 | DenseMap<SectionBase *, int> Order = buildSectionOrder(); | 1069 | |
| 1028 | if (!Order.empty()) | 1070 | struct SymbolOrderEntry { |
| 1029 | for (BaseCommand *Base : Script->SectionCommands) | 1071 | int Priority; |
| 1030 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | 1072 | bool Present; |
| 1031 | if (Sec->Live) | 1073 | }; |
| 1032 | Sec->sort([&](InputSectionBase *S) { return Order.lookup(S); }); | 1074 | |
| 1075 | // Build a map from symbols to their priorities. Symbols that didn't | ||
| 1076 | // appear in the symbol ordering file have the lowest priority 0. | ||
| 1077 | // All explicitly mentioned symbols have negative (higher) priorities. | ||
| 1078 | DenseMap<StringRef, SymbolOrderEntry> SymbolOrder; | ||
| 1079 | int Priority = -Config->SymbolOrderingFile.size(); | ||
| 1080 | for (StringRef S : Config->SymbolOrderingFile) | ||
| 1081 | SymbolOrder.insert({S, {Priority++, false}}); | ||
| 1082 | |||
| 1083 | // Build a map from sections to their priorities. | ||
| 1084 | auto AddSym = [&](Symbol &Sym) { | ||
| 1085 | auto It = SymbolOrder.find(Sym.getName()); | ||
| 1086 | if (It == SymbolOrder.end()) | ||
| 1087 | return; | ||
| 1088 | SymbolOrderEntry &Ent = It->second; | ||
| 1089 | Ent.Present = true; | ||
| 1090 | |||
| 1091 | warnUnorderableSymbol(&Sym); | ||
| 1092 | |||
| 1093 | if (auto *D = dyn_cast<Defined>(&Sym)) { | ||
| 1094 | if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) { | ||
| 1095 | int &Priority = SectionOrder[cast<InputSectionBase>(Sec->Repl)]; | ||
| 1096 | Priority = std::min(Priority, Ent.Priority); | ||
| 1097 | } | ||
| 1098 | } | ||
| 1099 | }; | ||
| 1100 | // We want both global and local symbols. We get the global ones from the | ||
| 1101 | // symbol table and iterate the object files for the local ones. | ||
| 1102 | for (Symbol *Sym : Symtab->getSymbols()) | ||
| 1103 | if (!Sym->isLazy()) | ||
| 1104 | AddSym(*Sym); | ||
| 1105 | for (InputFile *File : ObjectFiles) | ||
| 1106 | for (Symbol *Sym : File->getSymbols()) | ||
| 1107 | if (Sym->isLocal()) | ||
| 1108 | AddSym(*Sym); | ||
| 1109 | |||
| 1110 | if (Config->WarnSymbolOrdering) | ||
| 1111 | for (auto OrderEntry : SymbolOrder) | ||
| 1112 | if (!OrderEntry.second.Present) | ||
| 1113 | warn("symbol ordering file: no such symbol: " + OrderEntry.first); | ||
| 1114 | |||
| 1115 | return SectionOrder; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | // Sorts the sections in ISD according to the provided section order. | ||
| 1119 | static void | ||
| 1120 | sortISDBySectionOrder(InputSectionDescription *ISD, | ||
| 1121 | const DenseMap<const InputSectionBase *, int> &Order) { | ||
| 1122 | std::vector<InputSection *> UnorderedSections; | ||
| 1123 | std::vector<std::pair<InputSection *, int>> OrderedSections; | ||
| 1124 | uint64_t UnorderedSize = 0; | ||
| 1125 | |||
| 1126 | for (InputSection *IS : ISD->Sections) { | ||
| 1127 | auto I = Order.find(IS); | ||
| 1128 | if (I == Order.end()) { | ||
| 1129 | UnorderedSections.push_back(IS); | ||
| 1130 | UnorderedSize += IS->getSize(); | ||
| 1131 | continue; | ||
| 1132 | } | ||
| 1133 | OrderedSections.push_back({IS, I->second}); | ||
| 1134 | } | ||
| 1135 | llvm::sort( | ||
| 1136 | OrderedSections.begin(), OrderedSections.end(), | ||
| 1137 | [&](std::pair<InputSection *, int> A, std::pair<InputSection *, int> B) { | ||
| 1138 | return A.second < B.second; | ||
| 1139 | }); | ||
| 1140 | |||
| 1141 | // Find an insertion point for the ordered section list in the unordered | ||
| 1142 | // section list. On targets with limited-range branches, this is the mid-point | ||
| 1143 | // of the unordered section list. This decreases the likelihood that a range | ||
| 1144 | // extension thunk will be needed to enter or exit the ordered region. If the | ||
| 1145 | // ordered section list is a list of hot functions, we can generally expect | ||
| 1146 | // the ordered functions to be called more often than the unordered functions, | ||
| 1147 | // making it more likely that any particular call will be within range, and | ||
| 1148 | // therefore reducing the number of thunks required. | ||
| 1149 | // | ||
| 1150 | // For example, imagine that you have 8MB of hot code and 32MB of cold code. | ||
| 1151 | // If the layout is: | ||
| 1152 | // | ||
| 1153 | // 8MB hot | ||
| 1154 | // 32MB cold | ||
| 1155 | // | ||
| 1156 | // only the first 8-16MB of the cold code (depending on which hot function it | ||
| 1157 | // is actually calling) can call the hot code without a range extension thunk. | ||
| 1158 | // However, if we use this layout: | ||
| 1159 | // | ||
| 1160 | // 16MB cold | ||
| 1161 | // 8MB hot | ||
| 1162 | // 16MB cold | ||
| 1163 | // | ||
| 1164 | // both the last 8-16MB of the first block of cold code and the first 8-16MB | ||
| 1165 | // of the second block of cold code can call the hot code without a thunk. So | ||
| 1166 | // we effectively double the amount of code that could potentially call into | ||
| 1167 | // the hot code without a thunk. | ||
| 1168 | size_t InsPt = 0; | ||
| 1169 | if (Target->ThunkSectionSpacing && !OrderedSections.empty()) { | ||
| 1170 | uint64_t UnorderedPos = 0; | ||
| 1171 | for (; InsPt != UnorderedSections.size(); ++InsPt) { | ||
| 1172 | UnorderedPos += UnorderedSections[InsPt]->getSize(); | ||
| 1173 | if (UnorderedPos > UnorderedSize / 2) | ||
| 1174 | break; | ||
| 1175 | } | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | ISD->Sections.clear(); | ||
| 1179 | for (InputSection *IS : makeArrayRef(UnorderedSections).slice(0, InsPt)) | ||
| 1180 | ISD->Sections.push_back(IS); | ||
| 1181 | for (std::pair<InputSection *, int> P : OrderedSections) | ||
| 1182 | ISD->Sections.push_back(P.first); | ||
| 1183 | for (InputSection *IS : makeArrayRef(UnorderedSections).slice(InsPt)) | ||
| 1184 | ISD->Sections.push_back(IS); | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | static void sortSection(OutputSection *Sec, | ||
| 1188 | const DenseMap<const InputSectionBase *, int> &Order) { | ||
| 1189 | StringRef Name = Sec->Name; | ||
| 1033 | 1190 | ||
| 1034 | // Sort input sections by section name suffixes for | 1191 | // Sort input sections by section name suffixes for |
| 1035 | // __attribute__((init_priority(N))). | 1192 | // __attribute__((init_priority(N))). |
| 1036 | if (OutputSection *Sec = findSection(".init_array")) | 1193 | if (Name == ".init_array" || Name == ".fini_array") { |
| 1037 | Sec->sortInitFini(); | 1194 | if (!Script->HasSectionsCommand) |
| 1038 | if (OutputSection *Sec = findSection(".fini_array")) | 1195 | Sec->sortInitFini(); |
| 1039 | Sec->sortInitFini(); | 1196 | return; |
| 1197 | } | ||
| 1040 | 1198 | ||
| 1041 | // Sort input sections by the special rule for .ctors and .dtors. | 1199 | // Sort input sections by the special rule for .ctors and .dtors. |
| 1042 | if (OutputSection *Sec = findSection(".ctors")) | 1200 | if (Name == ".ctors" || Name == ".dtors") { |
| 1043 | Sec->sortCtorsDtors(); | 1201 | if (!Script->HasSectionsCommand) |
| 1044 | if (OutputSection *Sec = findSection(".dtors")) | 1202 | Sec->sortCtorsDtors(); |
| 1045 | Sec->sortCtorsDtors(); | 1203 | return; |
| 1204 | } | ||
| 1205 | |||
| 1206 | // Never sort these. | ||
| 1207 | if (Name == ".init" || Name == ".fini") | ||
| 1208 | return; | ||
| 1209 | |||
| 1210 | // Sort input sections by priority using the list provided | ||
| 1211 | // by --symbol-ordering-file. | ||
| 1212 | if (!Order.empty()) | ||
| 1213 | for (BaseCommand *B : Sec->SectionCommands) | ||
| 1214 | if (auto *ISD = dyn_cast<InputSectionDescription>(B)) | ||
| 1215 | sortISDBySectionOrder(ISD, Order); | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | // If no layout was provided by linker script, we want to apply default | ||
| 1219 | // sorting for special input sections. This also handles --symbol-ordering-file. | ||
| 1220 | template <class ELFT> void Writer<ELFT>::sortInputSections() { | ||
| 1221 | // Build the order once since it is expensive. | ||
| 1222 | DenseMap<const InputSectionBase *, int> Order = buildSectionOrder(); | ||
| 1223 | for (BaseCommand *Base : Script->SectionCommands) | ||
| 1224 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | ||
| 1225 | sortSection(Sec, Order); | ||
| 1046 | } | 1226 | } |
| 1047 | 1227 | ||
| 1048 | template <class ELFT> void Writer<ELFT>::sortSections() { | 1228 | template <class ELFT> void Writer<ELFT>::sortSections() { |
| ... | @@ -1053,22 +1233,29 @@ template <class ELFT> void Writer<ELFT>::sortSections() { | ... | @@ -1053,22 +1233,29 @@ template <class ELFT> void Writer<ELFT>::sortSections() { |
| 1053 | if (Config->Relocatable) | 1233 | if (Config->Relocatable) |
| 1054 | return; | 1234 | return; |
| 1055 | 1235 | ||
| 1056 | for (BaseCommand *Base : Script->SectionCommands) | 1236 | sortInputSections(); |
| 1057 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | ||
| 1058 | Sec->SortRank = getSectionRank(Sec); | ||
| 1059 | 1237 | ||
| 1060 | if (!Script->HasSectionsCommand) { | 1238 | for (BaseCommand *Base : Script->SectionCommands) { |
| 1061 | sortInputSections(); | 1239 | auto *OS = dyn_cast<OutputSection>(Base); |
| 1240 | if (!OS) | ||
| 1241 | continue; | ||
| 1242 | OS->SortRank = getSectionRank(OS); | ||
| 1243 | |||
| 1244 | // We want to assign rude approximation values to OutSecOff fields | ||
| 1245 | // to know the relative order of the input sections. We use it for | ||
| 1246 | // sorting SHF_LINK_ORDER sections. See resolveShfLinkOrder(). | ||
| 1247 | uint64_t I = 0; | ||
| 1248 | for (InputSection *Sec : getInputSections(OS)) | ||
| 1249 | Sec->OutSecOff = I++; | ||
| 1250 | } | ||
| 1062 | 1251 | ||
| 1252 | if (!Script->HasSectionsCommand) { | ||
| 1063 | // We know that all the OutputSections are contiguous in this case. | 1253 | // We know that all the OutputSections are contiguous in this case. |
| 1064 | auto E = Script->SectionCommands.end(); | ||
| 1065 | auto I = Script->SectionCommands.begin(); | ||
| 1066 | auto IsSection = [](BaseCommand *Base) { return isa<OutputSection>(Base); }; | 1254 | auto IsSection = [](BaseCommand *Base) { return isa<OutputSection>(Base); }; |
| 1067 | I = std::find_if(I, E, IsSection); | 1255 | std::stable_sort( |
| 1068 | E = std::find_if(llvm::make_reverse_iterator(E), | 1256 | llvm::find_if(Script->SectionCommands, IsSection), |
| 1069 | llvm::make_reverse_iterator(I), IsSection) | 1257 | llvm::find_if(llvm::reverse(Script->SectionCommands), IsSection).base(), |
| 1070 | .base(); | 1258 | compareSections); |
| 1071 | std::stable_sort(I, E, compareSections); | ||
| 1072 | return; | 1259 | return; |
| 1073 | } | 1260 | } |
| 1074 | 1261 | ||
| ... | @@ -1099,7 +1286,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() { | ... | @@ -1099,7 +1286,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() { |
| 1099 | // The way we define an order then is: | 1286 | // The way we define an order then is: |
| 1100 | // * Sort only the orphan sections. They are in the end right now. | 1287 | // * Sort only the orphan sections. They are in the end right now. |
| 1101 | // * Move each orphan section to its preferred position. We try | 1288 | // * Move each orphan section to its preferred position. We try |
| 1102 | // to put each section in the last position where it it can share | 1289 | // to put each section in the last position where it can share |
| 1103 | // a PT_LOAD. | 1290 | // a PT_LOAD. |
| 1104 | // | 1291 | // |
| 1105 | // There is some ambiguity as to where exactly a new entry should be | 1292 | // There is some ambiguity as to where exactly a new entry should be |
| ... | @@ -1115,7 +1302,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() { | ... | @@ -1115,7 +1302,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() { |
| 1115 | auto E = Script->SectionCommands.end(); | 1302 | auto E = Script->SectionCommands.end(); |
| 1116 | auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) { | 1303 | auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) { |
| 1117 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | 1304 | if (auto *Sec = dyn_cast<OutputSection>(Base)) |
| 1118 | return Sec->Live && Sec->SectionIndex == INT_MAX; | 1305 | return Sec->SectionIndex == UINT32_MAX; |
| 1119 | return false; | 1306 | return false; |
| 1120 | }); | 1307 | }); |
| 1121 | 1308 | ||
| ... | @@ -1190,8 +1377,7 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) { | ... | @@ -1190,8 +1377,7 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) { |
| 1190 | }; | 1377 | }; |
| 1191 | 1378 | ||
| 1192 | // Get the last table Entry from the previous .ARM.exidx section. | 1379 | // Get the last table Entry from the previous .ARM.exidx section. |
| 1193 | const ExidxEntry &PrevEntry = *reinterpret_cast<const ExidxEntry *>( | 1380 | const ExidxEntry &PrevEntry = Prev->getDataAs<ExidxEntry>().back(); |
| 1194 | Prev->Data.data() + Prev->getSize() - sizeof(ExidxEntry)); | ||
| 1195 | if (IsExtabRef(PrevEntry.Unwind)) | 1381 | if (IsExtabRef(PrevEntry.Unwind)) |
| 1196 | return false; | 1382 | return false; |
| 1197 | 1383 | ||
| ... | @@ -1203,14 +1389,7 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) { | ... | @@ -1203,14 +1389,7 @@ static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) { |
| 1203 | // consecutive identical entries are rare and the effort to check that they | 1389 | // consecutive identical entries are rare and the effort to check that they |
| 1204 | // are identical is high. | 1390 | // are identical is high. |
| 1205 | 1391 | ||
| 1206 | if (isa<SyntheticSection>(Cur)) | 1392 | for (const ExidxEntry Entry : Cur->getDataAs<ExidxEntry>()) |
| 1207 | // Exidx sentinel section has implicit EXIDX_CANTUNWIND; | ||
| 1208 | return PrevEntry.Unwind == 0x1; | ||
| 1209 | |||
| 1210 | ArrayRef<const ExidxEntry> Entries( | ||
| 1211 | reinterpret_cast<const ExidxEntry *>(Cur->Data.data()), | ||
| 1212 | Cur->getSize() / sizeof(ExidxEntry)); | ||
| 1213 | for (const ExidxEntry &Entry : Entries) | ||
| 1214 | if (IsExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind) | 1393 | if (IsExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind) |
| 1215 | return false; | 1394 | return false; |
| 1216 | // All table entries in this .ARM.exidx Section can be merged into the | 1395 | // All table entries in this .ARM.exidx Section can be merged into the |
| ... | @@ -1240,13 +1419,12 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { | ... | @@ -1240,13 +1419,12 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { |
| 1240 | if (!Config->Relocatable && Config->EMachine == EM_ARM && | 1419 | if (!Config->Relocatable && Config->EMachine == EM_ARM && |
| 1241 | Sec->Type == SHT_ARM_EXIDX) { | 1420 | Sec->Type == SHT_ARM_EXIDX) { |
| 1242 | 1421 | ||
| 1243 | if (!Sections.empty() && isa<ARMExidxSentinelSection>(Sections.back())) { | 1422 | if (auto *Sentinel = dyn_cast<ARMExidxSentinelSection>(Sections.back())) { |
| 1244 | assert(Sections.size() >= 2 && | 1423 | assert(Sections.size() >= 2 && |
| 1245 | "We should create a sentinel section only if there are " | 1424 | "We should create a sentinel section only if there are " |
| 1246 | "alive regular exidx sections."); | 1425 | "alive regular exidx sections."); |
| 1247 | // The last executable section is required to fill the sentinel. | 1426 | // The last executable section is required to fill the sentinel. |
| 1248 | // Remember it here so that we don't have to find it again. | 1427 | // Remember it here so that we don't have to find it again. |
| 1249 | auto *Sentinel = cast<ARMExidxSentinelSection>(Sections.back()); | ||
| 1250 | Sentinel->Highest = Sections[Sections.size() - 2]->getLinkOrderDep(); | 1428 | Sentinel->Highest = Sections[Sections.size() - 2]->getLinkOrderDep(); |
| 1251 | } | 1429 | } |
| 1252 | 1430 | ||
| ... | @@ -1257,16 +1435,13 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { | ... | @@ -1257,16 +1435,13 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { |
| 1257 | // previous one. This does not require any rewriting of InputSection | 1435 | // previous one. This does not require any rewriting of InputSection |
| 1258 | // contents but misses opportunities for fine grained deduplication | 1436 | // contents but misses opportunities for fine grained deduplication |
| 1259 | // where only a subset of the InputSection contents can be merged. | 1437 | // where only a subset of the InputSection contents can be merged. |
| 1260 | int Cur = 1; | 1438 | size_t Prev = 0; |
| 1261 | int Prev = 0; | ||
| 1262 | // The last one is a sentinel entry which should not be removed. | 1439 | // The last one is a sentinel entry which should not be removed. |
| 1263 | int N = Sections.size() - 1; | 1440 | for (size_t I = 1; I < Sections.size() - 1; ++I) { |
| 1264 | while (Cur < N) { | 1441 | if (isDuplicateArmExidxSec(Sections[Prev], Sections[I])) |
| 1265 | if (isDuplicateArmExidxSec(Sections[Prev], Sections[Cur])) | 1442 | Sections[I] = nullptr; |
| 1266 | Sections[Cur] = nullptr; | ||
| 1267 | else | 1443 | else |
| 1268 | Prev = Cur; | 1444 | Prev = I; |
| 1269 | ++Cur; | ||
| 1270 | } | 1445 | } |
| 1271 | } | 1446 | } |
| 1272 | } | 1447 | } |
| ... | @@ -1277,14 +1452,12 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { | ... | @@ -1277,14 +1452,12 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { |
| 1277 | // Remove the Sections we marked as duplicate earlier. | 1452 | // Remove the Sections we marked as duplicate earlier. |
| 1278 | for (BaseCommand *Base : Sec->SectionCommands) | 1453 | for (BaseCommand *Base : Sec->SectionCommands) |
| 1279 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) | 1454 | if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) |
| 1280 | ISD->Sections.erase( | 1455 | llvm::erase_if(ISD->Sections, [](InputSection *IS) { return !IS; }); |
| 1281 | std::remove(ISD->Sections.begin(), ISD->Sections.end(), nullptr), | ||
| 1282 | ISD->Sections.end()); | ||
| 1283 | } | 1456 | } |
| 1284 | } | 1457 | } |
| 1285 | 1458 | ||
| 1286 | static void applySynthetic(const std::vector<SyntheticSection *> &Sections, | 1459 | static void applySynthetic(const std::vector<SyntheticSection *> &Sections, |
| 1287 | std::function<void(SyntheticSection *)> Fn) { | 1460 | llvm::function_ref<void(SyntheticSection *)> Fn) { |
| 1288 | for (SyntheticSection *SS : Sections) | 1461 | for (SyntheticSection *SS : Sections) |
| 1289 | if (SS && SS->getParent() && !SS->empty()) | 1462 | if (SS && SS->getParent() && !SS->empty()) |
| 1290 | Fn(SS); | 1463 | Fn(SS); |
| ... | @@ -1311,27 +1484,15 @@ static void removeUnusedSyntheticSections() { | ... | @@ -1311,27 +1484,15 @@ static void removeUnusedSyntheticSections() { |
| 1311 | if (!SS) | 1484 | if (!SS) |
| 1312 | return; | 1485 | return; |
| 1313 | OutputSection *OS = SS->getParent(); | 1486 | OutputSection *OS = SS->getParent(); |
| 1314 | if (!SS->empty() || !OS) | 1487 | if (!OS || !SS->empty()) |
| 1315 | continue; | 1488 | continue; |
| 1316 | 1489 | ||
| 1317 | std::vector<BaseCommand *>::iterator Empty = OS->SectionCommands.end(); | 1490 | // If we reach here, then SS is an unused synthetic section and we want to |
| 1318 | for (auto I = OS->SectionCommands.begin(), E = OS->SectionCommands.end(); | 1491 | // remove it from corresponding input section description of output section. |
| 1319 | I != E; ++I) { | 1492 | for (BaseCommand *B : OS->SectionCommands) |
| 1320 | BaseCommand *B = *I; | 1493 | if (auto *ISD = dyn_cast<InputSectionDescription>(B)) |
| 1321 | if (auto *ISD = dyn_cast<InputSectionDescription>(B)) { | ||
| 1322 | llvm::erase_if(ISD->Sections, | 1494 | llvm::erase_if(ISD->Sections, |
| 1323 | [=](InputSection *IS) { return IS == SS; }); | 1495 | [=](InputSection *IS) { return IS == SS; }); |
| 1324 | if (ISD->Sections.empty()) | ||
| 1325 | Empty = I; | ||
| 1326 | } | ||
| 1327 | } | ||
| 1328 | if (Empty != OS->SectionCommands.end()) | ||
| 1329 | OS->SectionCommands.erase(Empty); | ||
| 1330 | |||
| 1331 | // If there are no other sections in the output section, remove it from the | ||
| 1332 | // output. | ||
| 1333 | if (OS->SectionCommands.empty()) | ||
| 1334 | OS->Live = false; | ||
| 1335 | } | 1496 | } |
| 1336 | } | 1497 | } |
| 1337 | 1498 | ||
| ... | @@ -1423,9 +1584,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { | ... | @@ -1423,9 +1584,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1423 | 1584 | ||
| 1424 | if (InX::DynSymTab && Sym->includeInDynsym()) { | 1585 | if (InX::DynSymTab && Sym->includeInDynsym()) { |
| 1425 | InX::DynSymTab->addSymbol(Sym); | 1586 | InX::DynSymTab->addSymbol(Sym); |
| 1426 | if (auto *SS = dyn_cast<SharedSymbol>(Sym)) | 1587 | if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File)) |
| 1427 | if (cast<SharedFile<ELFT>>(Sym->File)->IsNeeded) | 1588 | if (File->IsNeeded && !Sym->isUndefined()) |
| 1428 | In<ELFT>::VerNeed->addSymbol(SS); | 1589 | In<ELFT>::VerNeed->addSymbol(Sym); |
| 1429 | } | 1590 | } |
| 1430 | } | 1591 | } |
| 1431 | 1592 | ||
| ... | @@ -1433,10 +1594,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { | ... | @@ -1433,10 +1594,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1433 | if (errorCount()) | 1594 | if (errorCount()) |
| 1434 | return; | 1595 | return; |
| 1435 | 1596 | ||
| 1597 | if (InX::MipsGot) | ||
| 1598 | InX::MipsGot->build<ELFT>(); | ||
| 1599 | |||
| 1436 | removeUnusedSyntheticSections(); | 1600 | removeUnusedSyntheticSections(); |
| 1437 | 1601 | ||
| 1438 | sortSections(); | 1602 | sortSections(); |
| 1439 | Script->removeEmptyCommands(); | ||
| 1440 | 1603 | ||
| 1441 | // Now that we have the final list, create a list of all the | 1604 | // Now that we have the final list, create a list of all the |
| 1442 | // OutputSections for convenience. | 1605 | // OutputSections for convenience. |
| ... | @@ -1444,6 +1607,15 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { | ... | @@ -1444,6 +1607,15 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1444 | if (auto *Sec = dyn_cast<OutputSection>(Base)) | 1607 | if (auto *Sec = dyn_cast<OutputSection>(Base)) |
| 1445 | OutputSections.push_back(Sec); | 1608 | OutputSections.push_back(Sec); |
| 1446 | 1609 | ||
| 1610 | // Ensure data sections are not mixed with executable sections when | ||
| 1611 | // -execute-only is used. | ||
| 1612 | if (Config->ExecuteOnly) | ||
| 1613 | for (OutputSection *OS : OutputSections) | ||
| 1614 | if (OS->Flags & SHF_EXECINSTR) | ||
| 1615 | for (InputSection *IS : getInputSections(OS)) | ||
| 1616 | if (!(IS->Flags & SHF_EXECINSTR)) | ||
| 1617 | error("-execute-only does not support intermingling data and code"); | ||
| 1618 | |||
| 1447 | // Prefer command line supplied address over other constraints. | 1619 | // Prefer command line supplied address over other constraints. |
| 1448 | for (OutputSection *Sec : OutputSections) { | 1620 | for (OutputSection *Sec : OutputSections) { |
| 1449 | auto I = Config->SectionStartMap.find(Sec->Name); | 1621 | auto I = Config->SectionStartMap.find(Sec->Name); |
| ... | @@ -1452,7 +1624,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { | ... | @@ -1452,7 +1624,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1452 | } | 1624 | } |
| 1453 | 1625 | ||
| 1454 | // This is a bit of a hack. A value of 0 means undef, so we set it | 1626 | // This is a bit of a hack. A value of 0 means undef, so we set it |
| 1455 | // to 1 t make __ehdr_start defined. The section number is not | 1627 | // to 1 to make __ehdr_start defined. The section number is not |
| 1456 | // particularly relevant. | 1628 | // particularly relevant. |
| 1457 | Out::ElfHeader->SectionIndex = 1; | 1629 | Out::ElfHeader->SectionIndex = 1; |
| 1458 | 1630 | ||
| ... | @@ -1478,12 +1650,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { | ... | @@ -1478,12 +1650,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1478 | // Dynamic section must be the last one in this list and dynamic | 1650 | // Dynamic section must be the last one in this list and dynamic |
| 1479 | // symbol table section (DynSymTab) must be the first one. | 1651 | // symbol table section (DynSymTab) must be the first one. |
| 1480 | applySynthetic( | 1652 | applySynthetic( |
| 1481 | {InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab, | 1653 | {InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab, |
| 1482 | InX::HashTab, InX::SymTab, InX::ShStrTab, InX::StrTab, | 1654 | InX::HashTab, InX::SymTab, InX::SymTabShndx, InX::ShStrTab, |
| 1483 | In<ELFT>::VerDef, InX::DynStrTab, InX::Got, InX::MipsGot, | 1655 | InX::StrTab, In<ELFT>::VerDef, InX::DynStrTab, InX::Got, |
| 1484 | InX::IgotPlt, InX::GotPlt, InX::RelaDyn, InX::RelaIplt, | 1656 | InX::MipsGot, InX::IgotPlt, InX::GotPlt, InX::RelaDyn, |
| 1485 | InX::RelaPlt, InX::Plt, InX::Iplt, InX::EhFrameHdr, | 1657 | InX::RelrDyn, InX::RelaIplt, InX::RelaPlt, InX::Plt, |
| 1486 | In<ELFT>::VerSym, In<ELFT>::VerNeed, InX::Dynamic}, | 1658 | InX::Iplt, InX::EhFrameHdr, In<ELFT>::VerSym, In<ELFT>::VerNeed, |
| 1659 | InX::Dynamic}, | ||
| 1487 | [](SyntheticSection *SS) { SS->finalizeContents(); }); | 1660 | [](SyntheticSection *SS) { SS->finalizeContents(); }); |
| 1488 | 1661 | ||
| 1489 | if (!Script->HasSectionsCommand && !Config->Relocatable) | 1662 | if (!Script->HasSectionsCommand && !Config->Relocatable) |
| ... | @@ -1495,10 +1668,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { | ... | @@ -1495,10 +1668,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1495 | 1668 | ||
| 1496 | // Some architectures need to generate content that depends on the address | 1669 | // Some architectures need to generate content that depends on the address |
| 1497 | // of InputSections. For example some architectures use small displacements | 1670 | // of InputSections. For example some architectures use small displacements |
| 1498 | // for jump instructions that is is the linker's responsibility for creating | 1671 | // for jump instructions that is the linker's responsibility for creating |
| 1499 | // range extension thunks for. As the generation of the content may also | 1672 | // range extension thunks for. As the generation of the content may also |
| 1500 | // alter InputSection addresses we must converge to a fixed point. | 1673 | // alter InputSection addresses we must converge to a fixed point. |
| 1501 | if (Target->NeedsThunks || Config->AndroidPackDynRelocs) { | 1674 | if (Target->NeedsThunks || Config->AndroidPackDynRelocs || |
| 1675 | Config->RelrPackDynRelocs) { | ||
| 1502 | ThunkCreator TC; | 1676 | ThunkCreator TC; |
| 1503 | AArch64Err843419Patcher A64P; | 1677 | AArch64Err843419Patcher A64P; |
| 1504 | bool Changed; | 1678 | bool Changed; |
| ... | @@ -1515,34 +1689,48 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { | ... | @@ -1515,34 +1689,48 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { |
| 1515 | if (InX::MipsGot) | 1689 | if (InX::MipsGot) |
| 1516 | InX::MipsGot->updateAllocSize(); | 1690 | InX::MipsGot->updateAllocSize(); |
| 1517 | Changed |= InX::RelaDyn->updateAllocSize(); | 1691 | Changed |= InX::RelaDyn->updateAllocSize(); |
| 1692 | if (InX::RelrDyn) | ||
| 1693 | Changed |= InX::RelrDyn->updateAllocSize(); | ||
| 1518 | } while (Changed); | 1694 | } while (Changed); |
| 1519 | } | 1695 | } |
| 1520 | 1696 | ||
| 1697 | // createThunks may have added local symbols to the static symbol table | ||
| 1698 | applySynthetic({InX::SymTab}, | ||
| 1699 | [](SyntheticSection *SS) { SS->postThunkContents(); }); | ||
| 1700 | |||
| 1521 | // Fill other section headers. The dynamic table is finalized | 1701 | // Fill other section headers. The dynamic table is finalized |
| 1522 | // at the end because some tags like RELSZ depend on result | 1702 | // at the end because some tags like RELSZ depend on result |
| 1523 | // of finalizing other sections. | 1703 | // of finalizing other sections. |
| 1524 | for (OutputSection *Sec : OutputSections) | 1704 | for (OutputSection *Sec : OutputSections) |
| 1525 | Sec->finalize<ELFT>(); | 1705 | Sec->finalize<ELFT>(); |
| 1526 | |||
| 1527 | // createThunks may have added local symbols to the static symbol table | ||
| 1528 | applySynthetic({InX::SymTab}, | ||
| 1529 | [](SyntheticSection *SS) { SS->postThunkContents(); }); | ||
| 1530 | } | 1706 | } |
| 1531 | 1707 | ||
| 1532 | // The linker is expected to define SECNAME_start and SECNAME_end | 1708 | // The linker is expected to define SECNAME_start and SECNAME_end |
| 1533 | // symbols for a few sections. This function defines them. | 1709 | // symbols for a few sections. This function defines them. |
| 1534 | template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { | 1710 | template <class ELFT> void Writer<ELFT>::addStartEndSymbols() { |
| 1535 | auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) { | 1711 | // If a section does not exist, there's ambiguity as to how we |
| 1536 | // These symbols resolve to the image base if the section does not exist. | 1712 | // define _start and _end symbols for an init/fini section. Since |
| 1537 | // A special value -1 indicates end of the section. | 1713 | // the loader assume that the symbols are always defined, we need to |
| 1714 | // always define them. But what value? The loader iterates over all | ||
| 1715 | // pointers between _start and _end to run global ctors/dtors, so if | ||
| 1716 | // the section is empty, their symbol values don't actually matter | ||
| 1717 | // as long as _start and _end point to the same location. | ||
| 1718 | // | ||
| 1719 | // That said, we don't want to set the symbols to 0 (which is | ||
| 1720 | // probably the simplest value) because that could cause some | ||
| 1721 | // program to fail to link due to relocation overflow, if their | ||
| 1722 | // program text is above 2 GiB. We use the address of the .text | ||
| 1723 | // section instead to prevent that failure. | ||
| 1724 | OutputSection *Default = findSection(".text"); | ||
| 1725 | if (!Default) | ||
| 1726 | Default = Out::ElfHeader; | ||
| 1727 | auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) { | ||
| 1538 | if (OS) { | 1728 | if (OS) { |
| 1539 | addOptionalRegular(Start, OS, 0); | 1729 | addOptionalRegular(Start, OS, 0); |
| 1540 | addOptionalRegular(End, OS, -1); | 1730 | addOptionalRegular(End, OS, -1); |
| 1541 | } else { | 1731 | } else { |
| 1542 | if (Config->Pic) | 1732 | addOptionalRegular(Start, Default, 0); |
| 1543 | OS = Out::ElfHeader; | 1733 | addOptionalRegular(End, Default, 0); |
| 1544 | addOptionalRegular(Start, OS, 0); | ||
| 1545 | addOptionalRegular(End, OS, 0); | ||
| 1546 | } | 1734 | } |
| 1547 | }; | 1735 | }; |
| 1548 | 1736 | ||
| ... | @@ -1564,12 +1752,12 @@ void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) { | ... | @@ -1564,12 +1752,12 @@ void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) { |
| 1564 | StringRef S = Sec->Name; | 1752 | StringRef S = Sec->Name; |
| 1565 | if (!isValidCIdentifier(S)) | 1753 | if (!isValidCIdentifier(S)) |
| 1566 | return; | 1754 | return; |
| 1567 | addOptionalRegular(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT); | 1755 | addOptionalRegular(Saver.save("__start_" + S), Sec, 0, STV_PROTECTED); |
| 1568 | addOptionalRegular(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT); | 1756 | addOptionalRegular(Saver.save("__stop_" + S), Sec, -1, STV_PROTECTED); |
| 1569 | } | 1757 | } |
| 1570 | 1758 | ||
| 1571 | static bool needsPtLoad(OutputSection *Sec) { | 1759 | static bool needsPtLoad(OutputSection *Sec) { |
| 1572 | if (!(Sec->Flags & SHF_ALLOC)) | 1760 | if (!(Sec->Flags & SHF_ALLOC) || Sec->Noload) |
| 1573 | return false; | 1761 | return false; |
| 1574 | 1762 | ||
| 1575 | // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is | 1763 | // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is |
| ... | @@ -1587,6 +1775,8 @@ static bool needsPtLoad(OutputSection *Sec) { | ... | @@ -1587,6 +1775,8 @@ static bool needsPtLoad(OutputSection *Sec) { |
| 1587 | static uint64_t computeFlags(uint64_t Flags) { | 1775 | static uint64_t computeFlags(uint64_t Flags) { |
| 1588 | if (Config->Omagic) | 1776 | if (Config->Omagic) |
| 1589 | return PF_R | PF_W | PF_X; | 1777 | return PF_R | PF_W | PF_X; |
| 1778 | if (Config->ExecuteOnly && (Flags & PF_X)) | ||
| 1779 | return Flags & ~PF_R; | ||
| 1590 | if (Config->SingleRoRx && !(Flags & PF_W)) | 1780 | if (Config->SingleRoRx && !(Flags & PF_W)) |
| 1591 | return Flags | PF_X; | 1781 | return Flags | PF_X; |
| 1592 | return Flags; | 1782 | return Flags; |
| ... | @@ -1626,9 +1816,11 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { | ... | @@ -1626,9 +1816,11 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { |
| 1626 | // (e.g. executable or writable). There is one phdr for each segment. | 1816 | // (e.g. executable or writable). There is one phdr for each segment. |
| 1627 | // Therefore, we need to create a new phdr when the next section has | 1817 | // Therefore, we need to create a new phdr when the next section has |
| 1628 | // different flags or is loaded at a discontiguous address using AT linker | 1818 | // different flags or is loaded at a discontiguous address using AT linker |
| 1629 | // script command. | 1819 | // script command. At the same time, we don't want to create a separate |
| 1820 | // load segment for the headers, even if the first output section has | ||
| 1821 | // an AT attribute. | ||
| 1630 | uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); | 1822 | uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); |
| 1631 | if ((Sec->LMAExpr && Load->ASectionHasLMA) || | 1823 | if ((Sec->LMAExpr && Load->LastSec != Out::ProgramHeaders) || |
| 1632 | Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { | 1824 | Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { |
| 1633 | 1825 | ||
| 1634 | Load = AddHdr(PT_LOAD, NewFlags); | 1826 | Load = AddHdr(PT_LOAD, NewFlags); |
| ... | @@ -1691,11 +1883,9 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { | ... | @@ -1691,11 +1883,9 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { |
| 1691 | // pages for the stack non-executable. If you really want an executable | 1883 | // pages for the stack non-executable. If you really want an executable |
| 1692 | // stack, you can pass -z execstack, but that's not recommended for | 1884 | // stack, you can pass -z execstack, but that's not recommended for |
| 1693 | // security reasons. | 1885 | // security reasons. |
| 1694 | unsigned Perm; | 1886 | unsigned Perm = PF_R | PF_W; |
| 1695 | if (Config->ZExecstack) | 1887 | if (Config->ZExecstack) |
| 1696 | Perm = PF_R | PF_W | PF_X; | 1888 | Perm |= PF_X; |
| 1697 | else | ||
| 1698 | Perm = PF_R | PF_W; | ||
| 1699 | AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize; | 1889 | AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize; |
| 1700 | 1890 | ||
| 1701 | // PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable | 1891 | // PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable |
| ... | @@ -1708,7 +1898,7 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { | ... | @@ -1708,7 +1898,7 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { |
| 1708 | // Create one PT_NOTE per a group of contiguous .note sections. | 1898 | // Create one PT_NOTE per a group of contiguous .note sections. |
| 1709 | PhdrEntry *Note = nullptr; | 1899 | PhdrEntry *Note = nullptr; |
| 1710 | for (OutputSection *Sec : OutputSections) { | 1900 | for (OutputSection *Sec : OutputSections) { |
| 1711 | if (Sec->Type == SHT_NOTE) { | 1901 | if (Sec->Type == SHT_NOTE && (Sec->Flags & SHF_ALLOC)) { |
| 1712 | if (!Note || Sec->LMAExpr) | 1902 | if (!Note || Sec->LMAExpr) |
| 1713 | Note = AddHdr(PT_NOTE, PF_R); | 1903 | Note = AddHdr(PT_NOTE, PF_R); |
| 1714 | Note->add(Sec); | 1904 | Note->add(Sec); |
| ... | @@ -1813,6 +2003,12 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() { | ... | @@ -1813,6 +2003,12 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() { |
| 1813 | FileSize = alignTo(Off, Config->Wordsize); | 2003 | FileSize = alignTo(Off, Config->Wordsize); |
| 1814 | } | 2004 | } |
| 1815 | 2005 | ||
| 2006 | static std::string rangeToString(uint64_t Addr, uint64_t Len) { | ||
| 2007 | if (Len == 0) | ||
| 2008 | return "<empty range at 0x" + utohexstr(Addr) + ">"; | ||
| 2009 | return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]"; | ||
| 2010 | } | ||
| 2011 | |||
| 1816 | // Assign file offsets to output sections. | 2012 | // Assign file offsets to output sections. |
| 1817 | template <class ELFT> void Writer<ELFT>::assignFileOffsets() { | 2013 | template <class ELFT> void Writer<ELFT>::assignFileOffsets() { |
| 1818 | uint64_t Off = 0; | 2014 | uint64_t Off = 0; |
| ... | @@ -1837,6 +2033,24 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() { | ... | @@ -1837,6 +2033,24 @@ template <class ELFT> void Writer<ELFT>::assignFileOffsets() { |
| 1837 | 2033 | ||
| 1838 | SectionHeaderOff = alignTo(Off, Config->Wordsize); | 2034 | SectionHeaderOff = alignTo(Off, Config->Wordsize); |
| 1839 | FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr); | 2035 | FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr); |
| 2036 | |||
| 2037 | // Our logic assumes that sections have rising VA within the same segment. | ||
| 2038 | // With use of linker scripts it is possible to violate this rule and get file | ||
| 2039 | // offset overlaps or overflows. That should never happen with a valid script | ||
| 2040 | // which does not move the location counter backwards and usually scripts do | ||
| 2041 | // not do that. Unfortunately, there are apps in the wild, for example, Linux | ||
| 2042 | // kernel, which control segment distribution explicitly and move the counter | ||
| 2043 | // backwards, so we have to allow doing that to support linking them. We | ||
| 2044 | // perform non-critical checks for overlaps in checkSectionOverlap(), but here | ||
| 2045 | // we want to prevent file size overflows because it would crash the linker. | ||
| 2046 | for (OutputSection *Sec : OutputSections) { | ||
| 2047 | if (Sec->Type == SHT_NOBITS) | ||
| 2048 | continue; | ||
| 2049 | if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize)) | ||
| 2050 | error("unable to place section " + Sec->Name + " at file offset " + | ||
| 2051 | rangeToString(Sec->Offset, Sec->Offset + Sec->Size) + | ||
| 2052 | "; check your linker script for overflows"); | ||
| 2053 | } | ||
| 1840 | } | 2054 | } |
| 1841 | 2055 | ||
| 1842 | // Finalize the program headers. We call this function after we assign | 2056 | // Finalize the program headers. We call this function after we assign |
| ... | @@ -1875,6 +2089,97 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() { | ... | @@ -1875,6 +2089,97 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() { |
| 1875 | } | 2089 | } |
| 1876 | } | 2090 | } |
| 1877 | 2091 | ||
| 2092 | // A helper struct for checkSectionOverlap. | ||
| 2093 | namespace { | ||
| 2094 | struct SectionOffset { | ||
| 2095 | OutputSection *Sec; | ||
| 2096 | uint64_t Offset; | ||
| 2097 | }; | ||
| 2098 | } // namespace | ||
| 2099 | |||
| 2100 | // Check whether sections overlap for a specific address range (file offsets, | ||
| 2101 | // load and virtual adresses). | ||
| 2102 | static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections, | ||
| 2103 | bool IsVirtualAddr) { | ||
| 2104 | llvm::sort(Sections.begin(), Sections.end(), | ||
| 2105 | [=](const SectionOffset &A, const SectionOffset &B) { | ||
| 2106 | return A.Offset < B.Offset; | ||
| 2107 | }); | ||
| 2108 | |||
| 2109 | // Finding overlap is easy given a vector is sorted by start position. | ||
| 2110 | // If an element starts before the end of the previous element, they overlap. | ||
| 2111 | for (size_t I = 1, End = Sections.size(); I < End; ++I) { | ||
| 2112 | SectionOffset A = Sections[I - 1]; | ||
| 2113 | SectionOffset B = Sections[I]; | ||
| 2114 | if (B.Offset >= A.Offset + A.Sec->Size) | ||
| 2115 | continue; | ||
| 2116 | |||
| 2117 | // If both sections are in OVERLAY we allow the overlapping of virtual | ||
| 2118 | // addresses, because it is what OVERLAY was designed for. | ||
| 2119 | if (IsVirtualAddr && A.Sec->InOverlay && B.Sec->InOverlay) | ||
| 2120 | continue; | ||
| 2121 | |||
| 2122 | errorOrWarn("section " + A.Sec->Name + " " + Name + | ||
| 2123 | " range overlaps with " + B.Sec->Name + "\n>>> " + A.Sec->Name + | ||
| 2124 | " range is " + rangeToString(A.Offset, A.Sec->Size) + "\n>>> " + | ||
| 2125 | B.Sec->Name + " range is " + | ||
| 2126 | rangeToString(B.Offset, B.Sec->Size)); | ||
| 2127 | } | ||
| 2128 | } | ||
| 2129 | |||
| 2130 | // Check for overlapping sections and address overflows. | ||
| 2131 | // | ||
| 2132 | // In this function we check that none of the output sections have overlapping | ||
| 2133 | // file offsets. For SHF_ALLOC sections we also check that the load address | ||
| 2134 | // ranges and the virtual address ranges don't overlap | ||
| 2135 | template <class ELFT> void Writer<ELFT>::checkSections() { | ||
| 2136 | // First, check that section's VAs fit in available address space for target. | ||
| 2137 | for (OutputSection *OS : OutputSections) | ||
| 2138 | if ((OS->Addr + OS->Size < OS->Addr) || | ||
| 2139 | (!ELFT::Is64Bits && OS->Addr + OS->Size > UINT32_MAX)) | ||
| 2140 | errorOrWarn("section " + OS->Name + " at 0x" + utohexstr(OS->Addr) + | ||
| 2141 | " of size 0x" + utohexstr(OS->Size) + | ||
| 2142 | " exceeds available address space"); | ||
| 2143 | |||
| 2144 | // Check for overlapping file offsets. In this case we need to skip any | ||
| 2145 | // section marked as SHT_NOBITS. These sections don't actually occupy space in | ||
| 2146 | // the file so Sec->Offset + Sec->Size can overlap with others. If --oformat | ||
| 2147 | // binary is specified only add SHF_ALLOC sections are added to the output | ||
| 2148 | // file so we skip any non-allocated sections in that case. | ||
| 2149 | std::vector<SectionOffset> FileOffs; | ||
| 2150 | for (OutputSection *Sec : OutputSections) | ||
| 2151 | if (0 < Sec->Size && Sec->Type != SHT_NOBITS && | ||
| 2152 | (!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC))) | ||
| 2153 | FileOffs.push_back({Sec, Sec->Offset}); | ||
| 2154 | checkOverlap("file", FileOffs, false); | ||
| 2155 | |||
| 2156 | // When linking with -r there is no need to check for overlapping virtual/load | ||
| 2157 | // addresses since those addresses will only be assigned when the final | ||
| 2158 | // executable/shared object is created. | ||
| 2159 | if (Config->Relocatable) | ||
| 2160 | return; | ||
| 2161 | |||
| 2162 | // Checking for overlapping virtual and load addresses only needs to take | ||
| 2163 | // into account SHF_ALLOC sections since others will not be loaded. | ||
| 2164 | // Furthermore, we also need to skip SHF_TLS sections since these will be | ||
| 2165 | // mapped to other addresses at runtime and can therefore have overlapping | ||
| 2166 | // ranges in the file. | ||
| 2167 | std::vector<SectionOffset> VMAs; | ||
| 2168 | for (OutputSection *Sec : OutputSections) | ||
| 2169 | if (0 < Sec->Size && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS)) | ||
| 2170 | VMAs.push_back({Sec, Sec->Addr}); | ||
| 2171 | checkOverlap("virtual address", VMAs, true); | ||
| 2172 | |||
| 2173 | // Finally, check that the load addresses don't overlap. This will usually be | ||
| 2174 | // the same as the virtual addresses but can be different when using a linker | ||
| 2175 | // script with AT(). | ||
| 2176 | std::vector<SectionOffset> LMAs; | ||
| 2177 | for (OutputSection *Sec : OutputSections) | ||
| 2178 | if (0 < Sec->Size && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS)) | ||
| 2179 | LMAs.push_back({Sec, Sec->getLMA()}); | ||
| 2180 | checkOverlap("load address", LMAs, false); | ||
| 2181 | } | ||
| 2182 | |||
| 1878 | // The entry point address is chosen in the following ways. | 2183 | // The entry point address is chosen in the following ways. |
| 1879 | // | 2184 | // |
| 1880 | // 1. the '-e' entry command-line option; | 2185 | // 1. the '-e' entry command-line option; |
| ... | @@ -1916,8 +2221,20 @@ static uint16_t getELFType() { | ... | @@ -1916,8 +2221,20 @@ static uint16_t getELFType() { |
| 1916 | return ET_EXEC; | 2221 | return ET_EXEC; |
| 1917 | } | 2222 | } |
| 1918 | 2223 | ||
| 2224 | static uint8_t getAbiVersion() { | ||
| 2225 | // MIPS non-PIC executable gets ABI version 1. | ||
| 2226 | if (Config->EMachine == EM_MIPS && getELFType() == ET_EXEC && | ||
| 2227 | (Config->EFlags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC) | ||
| 2228 | return 1; | ||
| 2229 | return 0; | ||
| 2230 | } | ||
| 2231 | |||
| 1919 | template <class ELFT> void Writer<ELFT>::writeHeader() { | 2232 | template <class ELFT> void Writer<ELFT>::writeHeader() { |
| 1920 | uint8_t *Buf = Buffer->getBufferStart(); | 2233 | uint8_t *Buf = Buffer->getBufferStart(); |
| 2234 | // For executable segments, the trap instructions are written before writing | ||
| 2235 | // the header. Setting Elf header bytes to zero ensures that any unused bytes | ||
| 2236 | // in header are zero-cleared, instead of having trap instructions. | ||
| 2237 | memset(Buf, 0, sizeof(Elf_Ehdr)); | ||
| 1921 | memcpy(Buf, "\177ELF", 4); | 2238 | memcpy(Buf, "\177ELF", 4); |
| 1922 | 2239 | ||
| 1923 | // Write the ELF header. | 2240 | // Write the ELF header. |
| ... | @@ -1926,6 +2243,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { | ... | @@ -1926,6 +2243,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { |
| 1926 | EHdr->e_ident[EI_DATA] = Config->IsLE ? ELFDATA2LSB : ELFDATA2MSB; | 2243 | EHdr->e_ident[EI_DATA] = Config->IsLE ? ELFDATA2LSB : ELFDATA2MSB; |
| 1927 | EHdr->e_ident[EI_VERSION] = EV_CURRENT; | 2244 | EHdr->e_ident[EI_VERSION] = EV_CURRENT; |
| 1928 | EHdr->e_ident[EI_OSABI] = Config->OSABI; | 2245 | EHdr->e_ident[EI_OSABI] = Config->OSABI; |
| 2246 | EHdr->e_ident[EI_ABIVERSION] = getAbiVersion(); | ||
| 1929 | EHdr->e_type = getELFType(); | 2247 | EHdr->e_type = getELFType(); |
| 1930 | EHdr->e_machine = Config->EMachine; | 2248 | EHdr->e_machine = Config->EMachine; |
| 1931 | EHdr->e_version = EV_CURRENT; | 2249 | EHdr->e_version = EV_CURRENT; |
| ... | @@ -1935,8 +2253,6 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { | ... | @@ -1935,8 +2253,6 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { |
| 1935 | EHdr->e_ehsize = sizeof(Elf_Ehdr); | 2253 | EHdr->e_ehsize = sizeof(Elf_Ehdr); |
| 1936 | EHdr->e_phnum = Phdrs.size(); | 2254 | EHdr->e_phnum = Phdrs.size(); |
| 1937 | EHdr->e_shentsize = sizeof(Elf_Shdr); | 2255 | EHdr->e_shentsize = sizeof(Elf_Shdr); |
| 1938 | EHdr->e_shnum = OutputSections.size() + 1; | ||
| 1939 | EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex; | ||
| 1940 | 2256 | ||
| 1941 | if (!Config->Relocatable) { | 2257 | if (!Config->Relocatable) { |
| 1942 | EHdr->e_phoff = sizeof(Elf_Ehdr); | 2258 | EHdr->e_phoff = sizeof(Elf_Ehdr); |
| ... | @@ -1957,8 +2273,30 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { | ... | @@ -1957,8 +2273,30 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { |
| 1957 | ++HBuf; | 2273 | ++HBuf; |
| 1958 | } | 2274 | } |
| 1959 | 2275 | ||
| 1960 | // Write the section header table. Note that the first table entry is null. | 2276 | // Write the section header table. |
| 2277 | // | ||
| 2278 | // The ELF header can only store numbers up to SHN_LORESERVE in the e_shnum | ||
| 2279 | // and e_shstrndx fields. When the value of one of these fields exceeds | ||
| 2280 | // SHN_LORESERVE ELF requires us to put sentinel values in the ELF header and | ||
| 2281 | // use fields in the section header at index 0 to store | ||
| 2282 | // the value. The sentinel values and fields are: | ||
| 2283 | // e_shnum = 0, SHdrs[0].sh_size = number of sections. | ||
| 2284 | // e_shstrndx = SHN_XINDEX, SHdrs[0].sh_link = .shstrtab section index. | ||
| 1961 | auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff); | 2285 | auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff); |
| 2286 | size_t Num = OutputSections.size() + 1; | ||
| 2287 | if (Num >= SHN_LORESERVE) | ||
| 2288 | SHdrs->sh_size = Num; | ||
| 2289 | else | ||
| 2290 | EHdr->e_shnum = Num; | ||
| 2291 | |||
| 2292 | uint32_t StrTabIndex = InX::ShStrTab->getParent()->SectionIndex; | ||
| 2293 | if (StrTabIndex >= SHN_LORESERVE) { | ||
| 2294 | SHdrs->sh_link = StrTabIndex; | ||
| 2295 | EHdr->e_shstrndx = SHN_XINDEX; | ||
| 2296 | } else { | ||
| 2297 | EHdr->e_shstrndx = StrTabIndex; | ||
| 2298 | } | ||
| 2299 | |||
| 1962 | for (OutputSection *Sec : OutputSections) | 2300 | for (OutputSection *Sec : OutputSections) |
| 1963 | Sec->writeHeaderTo<ELFT>(++SHdrs); | 2301 | Sec->writeHeaderTo<ELFT>(++SHdrs); |
| 1964 | } | 2302 | } |
| ... | @@ -2029,14 +2367,6 @@ template <class ELFT> void Writer<ELFT>::writeTrapInstr() { | ... | @@ -2029,14 +2367,6 @@ template <class ELFT> void Writer<ELFT>::writeTrapInstr() { |
| 2029 | template <class ELFT> void Writer<ELFT>::writeSections() { | 2367 | template <class ELFT> void Writer<ELFT>::writeSections() { |
| 2030 | uint8_t *Buf = Buffer->getBufferStart(); | 2368 | uint8_t *Buf = Buffer->getBufferStart(); |
| 2031 | 2369 | ||
| 2032 | // PPC64 needs to process relocations in the .opd section | ||
| 2033 | // before processing relocations in code-containing sections. | ||
| 2034 | if (auto *OpdCmd = findSection(".opd")) { | ||
| 2035 | Out::Opd = OpdCmd; | ||
| 2036 | Out::OpdBuf = Buf + Out::Opd->Offset; | ||
| 2037 | OpdCmd->template writeTo<ELFT>(Buf + Out::Opd->Offset); | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | OutputSection *EhFrameHdr = nullptr; | 2370 | OutputSection *EhFrameHdr = nullptr; |
| 2041 | if (InX::EhFrameHdr && !InX::EhFrameHdr->empty()) | 2371 | if (InX::EhFrameHdr && !InX::EhFrameHdr->empty()) |
| 2042 | EhFrameHdr = InX::EhFrameHdr->getParent(); | 2372 | EhFrameHdr = InX::EhFrameHdr->getParent(); |
| ... | @@ -2049,8 +2379,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() { | ... | @@ -2049,8 +2379,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() { |
| 2049 | Sec->writeTo<ELFT>(Buf + Sec->Offset); | 2379 | Sec->writeTo<ELFT>(Buf + Sec->Offset); |
| 2050 | 2380 | ||
| 2051 | for (OutputSection *Sec : OutputSections) | 2381 | for (OutputSection *Sec : OutputSections) |
| 2052 | if (Sec != Out::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL && | 2382 | if (Sec != EhFrameHdr && Sec->Type != SHT_REL && Sec->Type != SHT_RELA) |
| 2053 | Sec->Type != SHT_RELA) | ||
| 2054 | Sec->writeTo<ELFT>(Buf + Sec->Offset); | 2383 | Sec->writeTo<ELFT>(Buf + Sec->Offset); |
| 2055 | 2384 | ||
| 2056 | // The .eh_frame_hdr depends on .eh_frame section contents, therefore | 2385 | // The .eh_frame_hdr depends on .eh_frame section contents, therefore |
deps/lld/ELF/Writer.h+1-7| ... | @@ -23,7 +23,6 @@ class InputSectionBase; | ... | @@ -23,7 +23,6 @@ class InputSectionBase; |
| 23 | template <class ELFT> class ObjFile; | 23 | template <class ELFT> class ObjFile; |
| 24 | class SymbolTable; | 24 | class SymbolTable; |
| 25 | template <class ELFT> void writeResult(); | 25 | template <class ELFT> void writeResult(); |
| 26 | template <class ELFT> void markLive(); | ||
| 27 | 26 | ||
| 28 | // This describes a program header entry. | 27 | // This describes a program header entry. |
| 29 | // Each contains type, access flags and range of output sections that will be | 28 | // Each contains type, access flags and range of output sections that will be |
| ... | @@ -45,16 +44,11 @@ struct PhdrEntry { | ... | @@ -45,16 +44,11 @@ struct PhdrEntry { |
| 45 | OutputSection *LastSec = nullptr; | 44 | OutputSection *LastSec = nullptr; |
| 46 | bool HasLMA = false; | 45 | bool HasLMA = false; |
| 47 | 46 | ||
| 48 | // True if one of the sections in this program header has a LMA specified via | ||
| 49 | // linker script: AT(addr). We never allow 2 or more sections with LMA in the | ||
| 50 | // same program header. | ||
| 51 | bool ASectionHasLMA = false; | ||
| 52 | |||
| 53 | uint64_t LMAOffset = 0; | 47 | uint64_t LMAOffset = 0; |
| 54 | }; | 48 | }; |
| 55 | 49 | ||
| 56 | void addReservedSymbols(); | 50 | void addReservedSymbols(); |
| 57 | llvm::StringRef getOutputSectionName(InputSectionBase *S); | 51 | llvm::StringRef getOutputSectionName(const InputSectionBase *S); |
| 58 | 52 | ||
| 59 | template <class ELFT> uint32_t calcMipsEFlags(); | 53 | template <class ELFT> uint32_t calcMipsEFlags(); |
| 60 | 54 |
deps/lld/LICENSE.TXT+1-1| ... | @@ -4,7 +4,7 @@ lld License | ... | @@ -4,7 +4,7 @@ lld License |
| 4 | University of Illinois/NCSA | 4 | University of Illinois/NCSA |
| 5 | Open Source License | 5 | Open Source License |
| 6 | 6 | ||
| 7 | Copyright (c) 2011-2016 by the contributors listed in CREDITS.TXT | 7 | Copyright (c) 2011-2018 by the contributors listed in CREDITS.TXT |
| 8 | All rights reserved. | 8 | All rights reserved. |
| 9 | 9 | ||
| 10 | Developed by: | 10 | Developed by: |
deps/lld/MinGW/Driver.cpp+13-2| ... | @@ -136,6 +136,8 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) { | ... | @@ -136,6 +136,8 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) { |
| 136 | Add("-output-def:" + StringRef(A->getValue())); | 136 | Add("-output-def:" + StringRef(A->getValue())); |
| 137 | if (auto *A = Args.getLastArg(OPT_image_base)) | 137 | if (auto *A = Args.getLastArg(OPT_image_base)) |
| 138 | Add("-base:" + StringRef(A->getValue())); | 138 | Add("-base:" + StringRef(A->getValue())); |
| 139 | if (auto *A = Args.getLastArg(OPT_map)) | ||
| 140 | Add("-lldmap:" + StringRef(A->getValue())); | ||
| 139 | 141 | ||
| 140 | if (auto *A = Args.getLastArg(OPT_o)) | 142 | if (auto *A = Args.getLastArg(OPT_o)) |
| 141 | Add("-out:" + StringRef(A->getValue())); | 143 | Add("-out:" + StringRef(A->getValue())); |
| ... | @@ -144,16 +146,25 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) { | ... | @@ -144,16 +146,25 @@ bool mingw::link(ArrayRef<const char *> ArgsArr, raw_ostream &Diag) { |
| 144 | else | 146 | else |
| 145 | Add("-out:a.exe"); | 147 | Add("-out:a.exe"); |
| 146 | 148 | ||
| 149 | if (auto *A = Args.getLastArg(OPT_pdb)) { | ||
| 150 | Add("-debug"); | ||
| 151 | Add("-pdb:" + StringRef(A->getValue())); | ||
| 152 | } else if (Args.hasArg(OPT_strip_debug)) { | ||
| 153 | Add("-debug:symtab"); | ||
| 154 | } else if (!Args.hasArg(OPT_strip_all)) { | ||
| 155 | Add("-debug:dwarf"); | ||
| 156 | } | ||
| 157 | |||
| 147 | if (Args.hasArg(OPT_shared)) | 158 | if (Args.hasArg(OPT_shared)) |
| 148 | Add("-dll"); | 159 | Add("-dll"); |
| 149 | if (Args.hasArg(OPT_verbose)) | 160 | if (Args.hasArg(OPT_verbose)) |
| 150 | Add("-verbose"); | 161 | Add("-verbose"); |
| 151 | if (Args.hasArg(OPT_export_all_symbols)) | 162 | if (Args.hasArg(OPT_export_all_symbols)) |
| 152 | Add("-export-all-symbols"); | 163 | Add("-export-all-symbols"); |
| 153 | if (!Args.hasArg(OPT_strip_all)) | ||
| 154 | Add("-debug:dwarf"); | ||
| 155 | if (Args.hasArg(OPT_large_address_aware)) | 164 | if (Args.hasArg(OPT_large_address_aware)) |
| 156 | Add("-largeaddressaware"); | 165 | Add("-largeaddressaware"); |
| 166 | if (Args.hasArg(OPT_kill_at)) | ||
| 167 | Add("-kill-at"); | ||
| 157 | 168 | ||
| 158 | if (Args.getLastArgValue(OPT_m) != "thumb2pe" && | 169 | if (Args.getLastArgValue(OPT_m) != "thumb2pe" && |
| 159 | Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase)) | 170 | Args.getLastArgValue(OPT_m) != "arm64pe" && !Args.hasArg(OPT_dynamicbase)) |
deps/lld/MinGW/Options.td+9| ... | @@ -14,9 +14,12 @@ def export_all_symbols: F<"export-all-symbols">, | ... | @@ -14,9 +14,12 @@ def export_all_symbols: F<"export-all-symbols">, |
| 14 | def gc_sections: F<"gc-sections">, HelpText<"Remove unused sections">; | 14 | def gc_sections: F<"gc-sections">, HelpText<"Remove unused sections">; |
| 15 | def icf: J<"icf=">, HelpText<"Identical code folding">; | 15 | def icf: J<"icf=">, HelpText<"Identical code folding">; |
| 16 | def image_base: S<"image-base">, HelpText<"Base address of the program">; | 16 | def image_base: S<"image-base">, HelpText<"Base address of the program">; |
| 17 | def kill_at: F<"kill-at">, HelpText<"Remove @n from exported symbols">; | ||
| 17 | def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">, | 18 | def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">, |
| 18 | HelpText<"Root name of library to use">; | 19 | HelpText<"Root name of library to use">; |
| 19 | def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">; | 20 | def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">; |
| 21 | def map: S<"Map">, HelpText<"Output a linker map">; | ||
| 22 | def map_eq: J<"Map=">, Alias<map>; | ||
| 20 | def no_whole_archive: F<"no-whole-archive">, | 23 | def no_whole_archive: F<"no-whole-archive">, |
| 21 | HelpText<"No longer include all object files for following archives">; | 24 | HelpText<"No longer include all object files for following archives">; |
| 22 | def large_address_aware: Flag<["--"], "large-address-aware">, | 25 | def large_address_aware: Flag<["--"], "large-address-aware">, |
| ... | @@ -32,6 +35,8 @@ def subs: S<"subsystem">, HelpText<"Specify subsystem">; | ... | @@ -32,6 +35,8 @@ def subs: S<"subsystem">, HelpText<"Specify subsystem">; |
| 32 | def stack: S<"stack">; | 35 | def stack: S<"stack">; |
| 33 | def strip_all: F<"strip-all">, | 36 | def strip_all: F<"strip-all">, |
| 34 | HelpText<"Omit all symbol information from the output binary">; | 37 | HelpText<"Omit all symbol information from the output binary">; |
| 38 | def strip_debug: F<"strip-debug">, | ||
| 39 | HelpText<"Omit all debug information, but keep symbol information">; | ||
| 35 | def whole_archive: F<"whole-archive">, | 40 | def whole_archive: F<"whole-archive">, |
| 36 | HelpText<"Include all object files for following archives">; | 41 | HelpText<"Include all object files for following archives">; |
| 37 | def verbose: F<"verbose">, HelpText<"Verbose mode">; | 42 | def verbose: F<"verbose">, HelpText<"Verbose mode">; |
| ... | @@ -40,6 +45,7 @@ def verbose: F<"verbose">, HelpText<"Verbose mode">; | ... | @@ -40,6 +45,7 @@ def verbose: F<"verbose">, HelpText<"Verbose mode">; |
| 40 | def _HASH_HASH_HASH : Flag<["-"], "###">, | 45 | def _HASH_HASH_HASH : Flag<["-"], "###">, |
| 41 | HelpText<"Print (but do not run) the commands to run for this compilation">; | 46 | HelpText<"Print (but do not run) the commands to run for this compilation">; |
| 42 | def mllvm: S<"mllvm">; | 47 | def mllvm: S<"mllvm">; |
| 48 | def pdb: S<"pdb">, HelpText<"Specify output PDB debug information file">; | ||
| 43 | def Xlink : J<"Xlink=">, MetaVarName<"<arg>">, | 49 | def Xlink : J<"Xlink=">, MetaVarName<"<arg>">, |
| 44 | HelpText<"Pass <arg> to the COFF linker">; | 50 | HelpText<"Pass <arg> to the COFF linker">; |
| 45 | 51 | ||
| ... | @@ -51,6 +57,7 @@ def build_id: F<"build-id">; | ... | @@ -51,6 +57,7 @@ def build_id: F<"build-id">; |
| 51 | def disable_auto_image_base: F<"disable-auto-image-base">; | 57 | def disable_auto_image_base: F<"disable-auto-image-base">; |
| 52 | def enable_auto_image_base: F<"enable-auto-image-base">; | 58 | def enable_auto_image_base: F<"enable-auto-image-base">; |
| 53 | def enable_auto_import: F<"enable-auto-import">; | 59 | def enable_auto_import: F<"enable-auto-import">; |
| 60 | def end_group: F<"end-group">; | ||
| 54 | def full_shutdown: Flag<["--"], "full-shutdown">; | 61 | def full_shutdown: Flag<["--"], "full-shutdown">; |
| 55 | def high_entropy_va: F<"high-entropy-va">, HelpText<"Enable 64-bit ASLR">; | 62 | def high_entropy_va: F<"high-entropy-va">, HelpText<"Enable 64-bit ASLR">; |
| 56 | def major_image_version: S<"major-image-version">; | 63 | def major_image_version: S<"major-image-version">; |
| ... | @@ -59,6 +66,7 @@ def no_seh: F<"no-seh">; | ... | @@ -59,6 +66,7 @@ def no_seh: F<"no-seh">; |
| 59 | def nxcompat: F<"nxcompat">, HelpText<"Enable data execution prevention">; | 66 | def nxcompat: F<"nxcompat">, HelpText<"Enable data execution prevention">; |
| 60 | def pic_executable: F<"pic-executable">; | 67 | def pic_executable: F<"pic-executable">; |
| 61 | def sysroot: J<"sysroot">, HelpText<"Sysroot">; | 68 | def sysroot: J<"sysroot">, HelpText<"Sysroot">; |
| 69 | def start_group: F<"start-group">; | ||
| 62 | def tsaware: F<"tsaware">, HelpText<"Create Terminal Server aware executable">; | 70 | def tsaware: F<"tsaware">, HelpText<"Create Terminal Server aware executable">; |
| 63 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; | 71 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; |
| 64 | def version: F<"version">, HelpText<"Display the version number and exit">; | 72 | def version: F<"version">, HelpText<"Display the version number and exit">; |
| ... | @@ -66,3 +74,4 @@ def version: F<"version">, HelpText<"Display the version number and exit">; | ... | @@ -66,3 +74,4 @@ def version: F<"version">, HelpText<"Display the version number and exit">; |
| 66 | // Alias | 74 | // Alias |
| 67 | def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>; | 75 | def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>; |
| 68 | def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>; | 76 | def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>; |
| 77 | def alias_strip_S: Flag<["-"], "S">, Alias<strip_debug>; |
deps/lld/cmake/modules/AddLLD.cmake+1-1| ... | @@ -10,7 +10,7 @@ macro(add_lld_library name) | ... | @@ -10,7 +10,7 @@ macro(add_lld_library name) |
| 10 | llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS}) | 10 | llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS}) |
| 11 | set_target_properties(${name} PROPERTIES FOLDER "lld libraries") | 11 | set_target_properties(${name} PROPERTIES FOLDER "lld libraries") |
| 12 | 12 | ||
| 13 | if (LLD_BUILD_TOOLS) | 13 | if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) |
| 14 | if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR | 14 | if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR |
| 15 | NOT LLVM_DISTRIBUTION_COMPONENTS) | 15 | NOT LLVM_DISTRIBUTION_COMPONENTS) |
| 16 | set(export_to_lldtargets EXPORT lldTargets) | 16 | set(export_to_lldtargets EXPORT lldTargets) |
deps/lld/docs/ReleaseNotes.rst+12-74| ... | @@ -1,14 +1,19 @@ | ... | @@ -1,14 +1,19 @@ |
| 1 | ======================= | 1 | ======================= |
| 2 | LLD 6.0.0 Release Notes | 2 | LLD 7.0.0 Release Notes |
| 3 | ======================= | 3 | ======================= |
| 4 | 4 | ||
| 5 | .. contents:: | 5 | .. contents:: |
| 6 | :local: | 6 | :local: |
| 7 | 7 | ||
| 8 | .. warning:: | ||
| 9 | These are in-progress notes for the upcoming LLVM 7.0.0 release. | ||
| 10 | Release notes for previous releases can be found on | ||
| 11 | `the Download Page <http://releases.llvm.org/download.html>`_. | ||
| 12 | |||
| 8 | Introduction | 13 | Introduction |
| 9 | ============ | 14 | ============ |
| 10 | 15 | ||
| 11 | This document contains the release notes for the lld linker, release 6.0.0. | 16 | This document contains the release notes for the lld linker, release 7.0.0. |
| 12 | Here we describe the status of lld, including major improvements | 17 | Here we describe the status of lld, including major improvements |
| 13 | from the previous release. All lld releases may be downloaded | 18 | from the previous release. All lld releases may be downloaded |
| 14 | from the `LLVM releases web site <http://llvm.org/releases/>`_. | 19 | from the `LLVM releases web site <http://llvm.org/releases/>`_. |
| ... | @@ -19,81 +24,14 @@ Non-comprehensive list of changes in this release | ... | @@ -19,81 +24,14 @@ Non-comprehensive list of changes in this release |
| 19 | ELF Improvements | 24 | ELF Improvements |
| 20 | ---------------- | 25 | ---------------- |
| 21 | 26 | ||
| 22 | * A lot of bugs and compatibility issues have been identified and fixed as a | 27 | * Item 1. |
| 23 | result of people using lld 5.0 as a standard system linker. In particular, | ||
| 24 | linker script and version script support has significantly improved that | ||
| 25 | it should be able to handle almost all scripts. | ||
| 26 | |||
| 27 | * A mitigation for Spectre v2 has been implemented. If you pass ``-z | ||
| 28 | retpolineplt``, lld uses RET instruction instead of JMP instruction in PLT. | ||
| 29 | The option is available for x86 and x86-64. | ||
| 30 | |||
| 31 | * Identical Code Folding (ICF) now de-duplicates .eh_frame entries, so lld now | ||
| 32 | generates slightly smaller outputs than before when you pass ``--icf=all``. | ||
| 33 | |||
| 34 | * Analysis for ``--as-needed`` is now done after garbage collection. If garbage | ||
| 35 | collector eliminates all sections that use some library, that library is | ||
| 36 | eliminated from DT_NEEDED tags. Previously, the analysis ran before garbage | ||
| 37 | collection. | ||
| 38 | |||
| 39 | * Size of code segment is now always rounded up to page size to make sure that | ||
| 40 | unused bytes at end of code segment is filled with trap instructions (such | ||
| 41 | as INT3) instead of zeros. | ||
| 42 | |||
| 43 | * lld is now able to generate Android-style compact dynamic relocation table. | ||
| 44 | You can turn on the feature by passing ``--pack-dyn-relocs=android``. | ||
| 45 | |||
| 46 | * Debug information is used in more cases when reporting errors. | ||
| 47 | |||
| 48 | * ``--gdb-index`` gets faster than before. | ||
| 49 | |||
| 50 | * String merging is now multi-threaded, which makes ``-O2`` faster. | ||
| 51 | |||
| 52 | * ``--hash-style=both`` is now default instead of ``--hash-style=sysv`` to | ||
| 53 | match the behavior of recent versions of GNU linkers. | ||
| 54 | |||
| 55 | * ARM PLT entries automatically use short or long variants. | ||
| 56 | |||
| 57 | * lld can now identify and patch a code sequence that triggers AArch64 errata 843419. | ||
| 58 | Add ``--fix-cortex-a53-843419`` to enable the feature. | ||
| 59 | |||
| 60 | * lld can now generate thunks for out of range thunks. | ||
| 61 | |||
| 62 | * MIPS port now generates all output dynamic relocations using Elf_Rel format only. | ||
| 63 | |||
| 64 | * Added handling of the R_MIPS_26 relocation in case of N32/N64 ABIs and | ||
| 65 | generating proper PLT entries. | ||
| 66 | |||
| 67 | * The following options have been added: ``--icf=none`` ``-z muldefs`` | ||
| 68 | ``--plugin-opt`` ``--no-eh-frame-hdr`` ``--no-gdb-index`` | ||
| 69 | ``--orphan-handling={place,discard,warn,error}`` | ||
| 70 | ``--pack-dyn-relocs={none,android}`` ``--no-omagic`` | ||
| 71 | ``--no-print-gc-sections`` ``--ignore-function-address-equality`` ``-z | ||
| 72 | retpolineplt`` ``--print-icf-sections`` ``--no-pie`` | ||
| 73 | 28 | ||
| 74 | COFF Improvements | 29 | COFF Improvements |
| 75 | ----------------- | 30 | ----------------- |
| 76 | 31 | ||
| 77 | * A GNU ld style frontend for the COFF linker has been added for MinGW. | 32 | * Item 1. |
| 78 | In MinGW environments, the linker is invoked with GNU ld style parameters; | ||
| 79 | which lld previously only supported when used as an ELF linker. When | ||
| 80 | a PE/COFF target is chosen, those parameters are rewritten into the | ||
| 81 | lld-link style parameters and the COFF linker is invoked instead. | ||
| 82 | |||
| 83 | * Initial support for the ARM64 architecture has been added. | ||
| 84 | |||
| 85 | * New ``--version`` flag. | ||
| 86 | |||
| 87 | * Significantly improved support for writing PDB Files. | ||
| 88 | |||
| 89 | * New ``--rsp-quoting`` flag, like ``clang-cl``. | ||
| 90 | |||
| 91 | * ``/manifestuac:no`` no longer incorrectly disables ``/manifestdependency:``. | ||
| 92 | |||
| 93 | * Only write ``.manifest`` files if ``/manifest`` is passed. | ||
| 94 | 33 | ||
| 95 | WebAssembly Improvements | 34 | MachO Improvements |
| 96 | ------------------------ | 35 | ------------------ |
| 97 | 36 | ||
| 98 | * Initial version of WebAssembly support has landed. You can invoke the | 37 | * Item 1. |
| 99 | WebAssembly linker by ``wasm-ld``. |
deps/lld/docs/WebAssembly.rst+1-1| ... | @@ -18,7 +18,7 @@ the WebAssembly tool conventions | ... | @@ -18,7 +18,7 @@ the WebAssembly tool conventions |
| 18 | https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md. | 18 | https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md. |
| 19 | 19 | ||
| 20 | This is object format that the llvm will produce when run with the | 20 | This is object format that the llvm will produce when run with the |
| 21 | ``wasm32-unknown-unknown-wasm`` target. To build llvm with WebAssembly support | 21 | ``wasm32-unknown-unknown`` target. To build llvm with WebAssembly support |
| 22 | currently requires enabling the experimental backed using | 22 | currently requires enabling the experimental backed using |
| 23 | ``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``. | 23 | ``-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly``. |
| 24 | 24 |
deps/lld/docs/conf.py+2-2| ... | @@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year | ... | @@ -48,9 +48,9 @@ copyright = u'2011-%d, LLVM Project' % date.today().year |
| 48 | # built documents. | 48 | # built documents. |
| 49 | # | 49 | # |
| 50 | # The short version. | 50 | # The short version. |
| 51 | version = '6' | 51 | version = '7' |
| 52 | # The full version, including alpha/beta/rc tags. | 52 | # The full version, including alpha/beta/rc tags. |
| 53 | release = '6' | 53 | release = '7' |
| 54 | 54 | ||
| 55 | # The language for content autogenerated by Sphinx. Refer to documentation | 55 | # The language for content autogenerated by Sphinx. Refer to documentation |
| 56 | # for a list of supported languages. | 56 | # for a list of supported languages. |
deps/lld/docs/index.rst+1-1| ... | @@ -8,7 +8,7 @@ features that are useful for toolchain developers. | ... | @@ -8,7 +8,7 @@ features that are useful for toolchain developers. |
| 8 | The linker supports ELF (Unix), PE/COFF (Windows), Mach-O (macOS) and | 8 | The linker supports ELF (Unix), PE/COFF (Windows), Mach-O (macOS) and |
| 9 | WebAssembly in descending order of completeness. Internally, LLD consists of | 9 | WebAssembly in descending order of completeness. Internally, LLD consists of |
| 10 | several different linkers. The ELF port is the one that will be described in | 10 | several different linkers. The ELF port is the one that will be described in |
| 11 | this document. The PE/COFF port is almost complete except the lack of the | 11 | this document. The PE/COFF port is complete, including |
| 12 | Windows debug info (PDB) support. The WebAssembly port is still a work in | 12 | Windows debug info (PDB) support. The WebAssembly port is still a work in |
| 13 | progress (See :doc:`WebAssembly`). The Mach-O port is built based on a | 13 | progress (See :doc:`WebAssembly`). The Mach-O port is built based on a |
| 14 | different architecture than the others. For the details about Mach-O, please | 14 | different architecture than the others. For the details about Mach-O, please |
deps/lld/docs/ld.lld.1 created+559| ... | @@ -0,0 +1,559 @@ | ||
| 1 | .\" This file is distributed under the University of Illinois Open Source | ||
| 2 | .\" License. See LICENSE.TXT for details. | ||
| 3 | .\" | ||
| 4 | .\" This man page documents only lld's ELF linking support, obtained originally | ||
| 5 | .\" from FreeBSD. | ||
| 6 | .Dd July 30, 2018 | ||
| 7 | .Dt LD.LLD 1 | ||
| 8 | .Os | ||
| 9 | .Sh NAME | ||
| 10 | .Nm ld.lld | ||
| 11 | .Nd ELF linker from the LLVM project | ||
| 12 | .Sh SYNOPSIS | ||
| 13 | .Nm ld.lld | ||
| 14 | .Op Ar options | ||
| 15 | .Ar objfile ... | ||
| 16 | .Sh DESCRIPTION | ||
| 17 | A linker takes one or more object, archive, and library files, and combines | ||
| 18 | them into an output file (an executable, a shared library, or another object | ||
| 19 | file). | ||
| 20 | It relocates code and data from the input files and resolves symbol | ||
| 21 | references between them. | ||
| 22 | .Pp | ||
| 23 | .Nm | ||
| 24 | is a drop-in replacement for the GNU BFD and gold linkers. | ||
| 25 | It accepts most of the same command line arguments and linker scripts | ||
| 26 | as GNU linkers. | ||
| 27 | .Pp | ||
| 28 | These options are available: | ||
| 29 | .Bl -tag -width indent | ||
| 30 | .It Fl -allow-multiple-definition | ||
| 31 | Do not error if a symbol is defined multiple times. | ||
| 32 | The first definition will be used. | ||
| 33 | .It Fl -apply-dynamic-relocs | ||
| 34 | Apply link-time values for dynamic relocations. | ||
| 35 | .It Fl -as-needed | ||
| 36 | Only set | ||
| 37 | .Dv DT_NEEDED | ||
| 38 | for shared libraries if used. | ||
| 39 | .It Fl -auxiliary Ns = Ns Ar value | ||
| 40 | Set the | ||
| 41 | .Dv DT_AUXILIARY | ||
| 42 | field to the specified name. | ||
| 43 | .It Fl -Bdynamic , Fl -dy | ||
| 44 | Link against shared libraries. | ||
| 45 | .It Fl -Bstatic , Fl -static , Fl -dn | ||
| 46 | Do not link against shared libraries. | ||
| 47 | .It Fl -Bsymbolic | ||
| 48 | Bind defined symbols locally. | ||
| 49 | .It Fl -Bsymbolic-functions | ||
| 50 | Bind defined function symbols locally. | ||
| 51 | .It Fl -build-id Ns = Ns Ar value | ||
| 52 | Generate a build ID note. | ||
| 53 | .Ar value | ||
| 54 | may be one of | ||
| 55 | .Cm fast , | ||
| 56 | .Cm md5 , | ||
| 57 | .Cm sha1 , | ||
| 58 | .Cm tree , | ||
| 59 | .Cm uuid , | ||
| 60 | .Cm 0x Ns Ar hex-string , | ||
| 61 | and | ||
| 62 | .Cm none . | ||
| 63 | .Cm tree | ||
| 64 | is an alias for | ||
| 65 | .Cm sha1 . | ||
| 66 | Build-IDs of type | ||
| 67 | .Cm fast , | ||
| 68 | .Cm md5 , | ||
| 69 | .Cm sha1 , | ||
| 70 | and | ||
| 71 | .Cm tree | ||
| 72 | are calculated from the object contents. | ||
| 73 | .Cm fast | ||
| 74 | is not intended to be cryptographically secure. | ||
| 75 | .It Fl -build-id | ||
| 76 | Synonym for | ||
| 77 | .Fl -build-id Ns = Ns Cm fast . | ||
| 78 | .It Fl -color-diagnostics Ns = Ns Ar value | ||
| 79 | Use colors in diagnostics. | ||
| 80 | .Ar value | ||
| 81 | may be one of | ||
| 82 | .Cm always , | ||
| 83 | .Cm auto , | ||
| 84 | and | ||
| 85 | .Cm never . | ||
| 86 | .Cm auto | ||
| 87 | enables color if and only if output is to a terminal. | ||
| 88 | .It Fl -color-diagnostics | ||
| 89 | Alias for | ||
| 90 | .Fl -color-diagnostics Ns = Ns Cm auto . | ||
| 91 | .It Fl -compress-debug-sections Ns = Ns Ar value | ||
| 92 | Compress DWARF debug sections. | ||
| 93 | .Ar value | ||
| 94 | may be | ||
| 95 | .Cm none | ||
| 96 | or | ||
| 97 | .Cm zlib . | ||
| 98 | .It Fl -cref | ||
| 99 | Output cross reference table. | ||
| 100 | .It Fl -define-common , Fl d | ||
| 101 | Assign space to common symbols. | ||
| 102 | .It Fl -defsym Ns = Ns Ar symbol Ns = Ns Ar expression | ||
| 103 | Define a symbol alias. | ||
| 104 | .Ar expression | ||
| 105 | may be another symbol or a linker script expression. | ||
| 106 | For example, | ||
| 107 | .Ql --defsym=foo=bar | ||
| 108 | or | ||
| 109 | .Ql --defsym=foo=bar+0x100 . | ||
| 110 | .It Fl -demangle | ||
| 111 | Demangle symbol names. | ||
| 112 | .It Fl -disable-new-dtags | ||
| 113 | Disable new dynamic tags. | ||
| 114 | .It Fl -discard-all , Fl x | ||
| 115 | Delete all local symbols. | ||
| 116 | .It Fl -discard-locals , Fl X | ||
| 117 | Delete temporary local symbols. | ||
| 118 | .It Fl -discard-none | ||
| 119 | Keep all symbols in the symbol table. | ||
| 120 | .It Fl -dynamic-linker Ns = Ns Ar value | ||
| 121 | Specify the dynamic linker to be used for a dynamically linked executable. | ||
| 122 | This is recorded in an ELF segment of type | ||
| 123 | .Dv PT_INTERP . | ||
| 124 | .It Fl -dynamic-list Ns = Ns Ar file | ||
| 125 | Read a list of dynamic symbols from | ||
| 126 | .Ar file . | ||
| 127 | .It Fl -eh-frame-hdr | ||
| 128 | Request creation of | ||
| 129 | .Li .eh_frame_hdr | ||
| 130 | section and | ||
| 131 | .Dv PT_GNU_EH_FRAME | ||
| 132 | segment header. | ||
| 133 | .It Fl -emit-relocs , Fl q | ||
| 134 | Generate relocations in the output. | ||
| 135 | .It Fl -enable-new-dtags | ||
| 136 | Enable new dynamic tags. | ||
| 137 | .It Fl -end-lib | ||
| 138 | End a grouping of objects that should be treated as if they were together | ||
| 139 | in an archive. | ||
| 140 | .It Fl -entry Ns = Ns Ar entry | ||
| 141 | Name of entry point symbol. | ||
| 142 | .It Fl -error-limit Ns = Ns Ar value | ||
| 143 | Maximum number of errors to emit before stopping. | ||
| 144 | A value of zero indicates that there is no limit. | ||
| 145 | .It Fl -error-unresolved-symbols | ||
| 146 | Report unresolved symbols as errors. | ||
| 147 | .It Fl -exclude-libs Ns = Ns Ar value | ||
| 148 | Exclude static libraries from automatic export. | ||
| 149 | .It Fl -export-dynamic , Fl E | ||
| 150 | Put symbols in the dynamic symbol table. | ||
| 151 | .It Fl -export-dynamic-symbol Ns = Ns Ar symbol | ||
| 152 | Include | ||
| 153 | .Ar symbol | ||
| 154 | in the dynamic symbol table. | ||
| 155 | .It Fl -fatal-warnings | ||
| 156 | Treat warnings as errors. | ||
| 157 | .It Fl -filter Ns = Ns Ar value , Fl F Ar value | ||
| 158 | Set the | ||
| 159 | .Dv DT_FILTER | ||
| 160 | field to the specified value. | ||
| 161 | .It Fl -fini Ns = Ns Ar symbol | ||
| 162 | Specify a finalizer function. | ||
| 163 | .It Fl -format Ns = Ns Ar input-format , Fl b Ar input-format | ||
| 164 | Specify the format of the inputs following this option. | ||
| 165 | .Ar input-format | ||
| 166 | may be one of | ||
| 167 | .Cm binary , | ||
| 168 | .Cm elf , | ||
| 169 | and | ||
| 170 | .Cm default . | ||
| 171 | .Cm default | ||
| 172 | is a synonym for | ||
| 173 | .Cm elf . | ||
| 174 | .It Fl -gc-sections | ||
| 175 | Enable garbage collection of unused sections. | ||
| 176 | .It Fl -gdb-index | ||
| 177 | Generate | ||
| 178 | .Li .gdb_index | ||
| 179 | section. | ||
| 180 | .It Fl -hash-style Ns = Ns Ar value | ||
| 181 | Specify hash style. | ||
| 182 | .Ar value | ||
| 183 | may be | ||
| 184 | .Cm sysv , | ||
| 185 | .Cm gnu , | ||
| 186 | or | ||
| 187 | .Cm both . | ||
| 188 | .Cm both | ||
| 189 | is the default. | ||
| 190 | .It Fl -help | ||
| 191 | Print a help message. | ||
| 192 | .It Fl -icf Ns = Ns Cm all | ||
| 193 | Enable identical code folding. | ||
| 194 | .It Fl -icf Ns = Ns Cm safe | ||
| 195 | Enable safe identical code folding. | ||
| 196 | .It Fl -icf Ns = Ns Cm none | ||
| 197 | Disable identical code folding. | ||
| 198 | .It Fl -image-base Ns = Ns Ar value | ||
| 199 | Set the base address to | ||
| 200 | .Ar value . | ||
| 201 | .It Fl -init Ns = Ns Ar symbol | ||
| 202 | Specify an initializer function. | ||
| 203 | .It Fl -keep-unique Ns = Ns Ar symbol | ||
| 204 | Do not fold | ||
| 205 | .Ar symbol | ||
| 206 | during ICF. | ||
| 207 | .It Fl l Ar libName, Fl -library Ns = Ns Ar libName | ||
| 208 | Root name of library to use. | ||
| 209 | .It Fl L Ar dir , Fl -library-path Ns = Ns Ar dir | ||
| 210 | Add a directory to the library search path. | ||
| 211 | .It Fl -lto-aa-pipeline Ns = Ns Ar value | ||
| 212 | AA pipeline to run during LTO. | ||
| 213 | Used in conjunction with | ||
| 214 | .Fl -lto-newpm-passes . | ||
| 215 | .It Fl -lto-newpm-passes Ns = Ns Ar value | ||
| 216 | Passes to run during LTO. | ||
| 217 | .It Fl -lto-O Ns Ar opt-level | ||
| 218 | Optimization level for LTO. | ||
| 219 | .It Fl -lto-partitions Ns = Ns Ar value | ||
| 220 | Number of LTO codegen partitions. | ||
| 221 | .It Fl m Ar value | ||
| 222 | Set target emulation. | ||
| 223 | .It Fl -Map Ns = Ns Ar file , Fl M Ar file | ||
| 224 | Print a link map to | ||
| 225 | .Ar file . | ||
| 226 | .It Fl -no-as-needed | ||
| 227 | Always set | ||
| 228 | .Dv DT_NEEDED | ||
| 229 | for shared libraries. | ||
| 230 | .It Fl -no-color-diagnostics | ||
| 231 | Do not use colors in diagnostics. | ||
| 232 | .It Fl -no-define-common | ||
| 233 | Do not assign space to common symbols. | ||
| 234 | .It Fl -no-demangle | ||
| 235 | Do not demangle symbol names. | ||
| 236 | .It Fl -no-dynamic-linker | ||
| 237 | Inhibit output of an | ||
| 238 | .Li .interp | ||
| 239 | section. | ||
| 240 | .It Fl -no-gc-sections | ||
| 241 | Disable garbage collection of unused sections. | ||
| 242 | .It Fl -no-gnu-unique | ||
| 243 | Disable STB_GNU_UNIQUE symbol binding. | ||
| 244 | .It Fl -no-rosegment | ||
| 245 | Do not put read-only non-executable sections in their own segment. | ||
| 246 | .It Fl -no-threads | ||
| 247 | Do not run the linker multi-threaded. | ||
| 248 | .It Fl -no-undefined-version | ||
| 249 | Report version scripts that refer undefined symbols. | ||
| 250 | .It Fl -no-undefined | ||
| 251 | Report unresolved symbols even if the linker is creating a shared library. | ||
| 252 | .It Fl -no-whole-archive | ||
| 253 | Restores the default behavior of loading archive members. | ||
| 254 | .It Fl -no-pie | ||
| 255 | Do not create a position independent executable. | ||
| 256 | .It Fl -noinhibit-exec | ||
| 257 | Retain the executable output file whenever it is still usable. | ||
| 258 | .It Fl -nostdlib | ||
| 259 | Only search directories specified on the command line. | ||
| 260 | .It Fl o Ar path | ||
| 261 | Write the output executable, library, or object to | ||
| 262 | .Ar path . | ||
| 263 | If not specified, | ||
| 264 | .Dv a.out | ||
| 265 | is used as a default. | ||
| 266 | .It Fl O Ns Ar value | ||
| 267 | Optimize output file size. | ||
| 268 | .Ar value | ||
| 269 | may be: | ||
| 270 | .Pp | ||
| 271 | .Bl -tag -width 2n -compact | ||
| 272 | .It Cm 0 | ||
| 273 | Disable string merging. | ||
| 274 | .It Cm 1 | ||
| 275 | Enable string merging. | ||
| 276 | .It Cm 2 | ||
| 277 | Enable string tail merging. | ||
| 278 | .El | ||
| 279 | .Pp | ||
| 280 | .Fl O Ns Cm 1 | ||
| 281 | is the default. | ||
| 282 | .It Fl -oformat Ns = Ns Ar format | ||
| 283 | Specify the format for the output object file. | ||
| 284 | The only supported | ||
| 285 | .Ar format | ||
| 286 | is | ||
| 287 | .Cm binary , | ||
| 288 | which produces output with no ELF header. | ||
| 289 | .It Fl -omagic , Fl N | ||
| 290 | Set the text and data sections to be readable and writable. | ||
| 291 | .It Fl -opt-remarks-filename Ar file | ||
| 292 | Write optimization remarks in YAML format to | ||
| 293 | .Ar file . | ||
| 294 | .It Fl -opt-remarks-with-hotness | ||
| 295 | Include hotness information in the optimization remarks file. | ||
| 296 | .It Fl -pie | ||
| 297 | Create a position independent executable. | ||
| 298 | .It Fl -print-gc-sections | ||
| 299 | List removed unused sections. | ||
| 300 | .It Fl -print-map | ||
| 301 | Print a link map to the standard output. | ||
| 302 | .It Fl -push-state | ||
| 303 | Save the current state of | ||
| 304 | .Fl -as-needed , | ||
| 305 | .Fl -static , | ||
| 306 | and | ||
| 307 | .Fl -while-archive. | ||
| 308 | .It Fl -pop-state | ||
| 309 | Undo the effect of | ||
| 310 | .Fl -push-state. | ||
| 311 | .It Fl -relocatable , Fl r | ||
| 312 | Create relocatable object file. | ||
| 313 | .It Fl -reproduce Ns = Ns Ar value | ||
| 314 | Dump linker invocation and input files for debugging. | ||
| 315 | .It Fl -retain-symbols-file Ns = Ns Ar file | ||
| 316 | Retain only the symbols listed in the file. | ||
| 317 | .It Fl -rpath Ns = Ns Ar value , Fl R Ar value | ||
| 318 | Add a | ||
| 319 | .Dv DT_RUNPATH | ||
| 320 | to the output. | ||
| 321 | .It Fl -rsp-quoting Ns = Ns Ar value | ||
| 322 | Quoting style for response files. | ||
| 323 | The supported values are | ||
| 324 | .Cm windows | ||
| 325 | and | ||
| 326 | .Cm posix . | ||
| 327 | .It Fl -script Ns = Ns Ar file , Fl T Ar file | ||
| 328 | Read linker script from | ||
| 329 | .Ar file . | ||
| 330 | .It Fl -section-start Ns = Ns Ar section Ns = Ns Ar address | ||
| 331 | Set address of section. | ||
| 332 | .It Fl -shared , Fl -Bsharable | ||
| 333 | Build a shared object. | ||
| 334 | .It Fl -soname Ns = Ns Ar value , Fl h Ar value | ||
| 335 | Set | ||
| 336 | .Dv DT_SONAME | ||
| 337 | to | ||
| 338 | .Ar value . | ||
| 339 | .It Fl -sort-section Ns = Ns Ar value | ||
| 340 | Specifies sections sorting rule when linkerscript is used. | ||
| 341 | .It Fl -start-lib | ||
| 342 | Start a grouping of objects that should be treated as if they were together | ||
| 343 | in an archive. | ||
| 344 | .It Fl -strip-all , Fl s | ||
| 345 | Strip all symbols. | ||
| 346 | .It Fl -strip-debug , Fl S | ||
| 347 | Strip debugging information. | ||
| 348 | .It Fl -symbol-ordering-file Ns = Ns Ar file | ||
| 349 | Lay out sections in the order specified by | ||
| 350 | .Ar file . | ||
| 351 | .It Fl -sysroot Ns = Ns Ar value | ||
| 352 | Set the system root. | ||
| 353 | .It Fl -target1-abs | ||
| 354 | Interpret | ||
| 355 | .Dv R_ARM_TARGET1 | ||
| 356 | as | ||
| 357 | .Dv R_ARM_ABS32 . | ||
| 358 | .It Fl -target1-rel | ||
| 359 | Interpret | ||
| 360 | .Dv R_ARM_TARGET1 | ||
| 361 | as | ||
| 362 | .Dv R_ARM_REL32 . | ||
| 363 | .It Fl -target2 Ns = Ns Ar type | ||
| 364 | Interpret | ||
| 365 | .Dv R_ARM_TARGET2 | ||
| 366 | as | ||
| 367 | .Ar type , | ||
| 368 | where | ||
| 369 | .Ar type | ||
| 370 | is one of | ||
| 371 | .Cm rel , | ||
| 372 | .Cm abs , | ||
| 373 | or | ||
| 374 | .Cm got-rel . | ||
| 375 | .It Fl -Tbss Ns = Ns Ar value | ||
| 376 | Same as | ||
| 377 | .Fl -section-start | ||
| 378 | with | ||
| 379 | .Li .bss | ||
| 380 | as the sectionname. | ||
| 381 | .It Fl -Tdata Ns = Ns Ar value | ||
| 382 | Same as | ||
| 383 | .Fl -section-start | ||
| 384 | with | ||
| 385 | .Li .data | ||
| 386 | as the sectionname. | ||
| 387 | .It Fl -Ttext Ns = Ns Ar value | ||
| 388 | Same as | ||
| 389 | .Fl -section-start | ||
| 390 | with | ||
| 391 | .Li .text | ||
| 392 | as the sectionname. | ||
| 393 | .It Fl -thinlto-cache-dir Ns = Ns Ar value | ||
| 394 | Path to ThinLTO cached object file directory. | ||
| 395 | .It Fl -thinlto-cache-policy Ns = Ns Ar value | ||
| 396 | Pruning policy for the ThinLTO cache. | ||
| 397 | .It Fl -thinlto-jobs Ns = Ns Ar value | ||
| 398 | Number of ThinLTO jobs. | ||
| 399 | .It Fl -threads | ||
| 400 | Run the linker multi-threaded. | ||
| 401 | This option is enabled by default. | ||
| 402 | .It Fl -trace | ||
| 403 | Print the names of the input files. | ||
| 404 | .It Fl -trace-symbol Ns = Ns Ar symbol , Fl y Ar symbol | ||
| 405 | Trace references to | ||
| 406 | .Ar symbol . | ||
| 407 | .It Fl -undefined Ns = Ns Ar symbol , Fl u Ar symbol | ||
| 408 | Force | ||
| 409 | .Ar symbol | ||
| 410 | to be an undefined symbol during linking. | ||
| 411 | .It Fl -unresolved-symbols Ns = Ns Ar value | ||
| 412 | Determine how to handle unresolved symbols. | ||
| 413 | .It Fl v | ||
| 414 | Display the version number and proceed with linking if object files are | ||
| 415 | specified. | ||
| 416 | .It Fl V , Fl -version | ||
| 417 | Display the version number and exit. | ||
| 418 | .It Fl -verbose | ||
| 419 | Verbose mode. | ||
| 420 | .It Fl -version-script Ns = Ns Ar file | ||
| 421 | Read version script from | ||
| 422 | .Ar file . | ||
| 423 | .It Fl -warn-backrefs | ||
| 424 | Warn about reverse or cyclic dependencies to or between static archives. | ||
| 425 | This can be used to ensure linker invocation remains compatible with | ||
| 426 | traditional Unix-like linkers. | ||
| 427 | .It Fl -warn-common | ||
| 428 | Warn about duplicate common symbols. | ||
| 429 | .It Fl -warn-unresolved-symbols | ||
| 430 | Report unresolved symbols as warnings. | ||
| 431 | .It Fl -whole-archive | ||
| 432 | Force load of all members in a static library. | ||
| 433 | .It Fl -wrap Ns = Ns Ar symbol | ||
| 434 | Use wrapper functions for symbol. | ||
| 435 | .It Fl z Ar option | ||
| 436 | Linker option extensions. | ||
| 437 | .Bl -tag -width indent | ||
| 438 | .It Cm execstack | ||
| 439 | Make the main stack executable. | ||
| 440 | Stack permissions are recorded in the | ||
| 441 | .Dv PT_GNU_STACK | ||
| 442 | segment. | ||
| 443 | .It Cm initfirst | ||
| 444 | Sets the | ||
| 445 | .Dv DF_1_INITFIRST | ||
| 446 | flag to indicate the module should be initialized first. | ||
| 447 | .It Cm muldefs | ||
| 448 | Do not error if a symbol is defined multiple times. | ||
| 449 | The first definition will be used. | ||
| 450 | This is a synonym for | ||
| 451 | .Fl -allow-multiple-definition. | ||
| 452 | .It Cm nocombreloc | ||
| 453 | Disable combining and sorting multiple relocation sections. | ||
| 454 | .It Cm nocopyreloc | ||
| 455 | Disable the creation of copy relocations. | ||
| 456 | .It Cm nodelete | ||
| 457 | Set the | ||
| 458 | .Dv DF_1_NODELETE | ||
| 459 | flag to indicate that the object cannot be unloaded from a process. | ||
| 460 | .It Cm nodlopen | ||
| 461 | Set the | ||
| 462 | .Dv DF_1_NOOPEN | ||
| 463 | flag to indcate that the object may not be opened by | ||
| 464 | .Xr dlopen 3 . | ||
| 465 | .It Cm norelro | ||
| 466 | Do not indicate that portions of the object shold be mapped read-only | ||
| 467 | after initial relocation processing. | ||
| 468 | The object will omit the | ||
| 469 | .Dv PT_GNU_RELRO | ||
| 470 | segment. | ||
| 471 | .It Cm notext | ||
| 472 | Allow relocations against read-only segments. | ||
| 473 | Sets the | ||
| 474 | .Dv DT_TEXTREL flag in the | ||
| 475 | .Dv DYNAMIC | ||
| 476 | section. | ||
| 477 | .It Cm now | ||
| 478 | Set the | ||
| 479 | .Dv DF_BIND_NOW | ||
| 480 | flag to indicate that the run-time loader should perform all relocation | ||
| 481 | processing as part of object initialization. | ||
| 482 | By default relocations may be performed on demand. | ||
| 483 | .It Cm origin | ||
| 484 | Set the | ||
| 485 | .Dv DF_ORIGIN | ||
| 486 | flag to indicate that the object requires | ||
| 487 | $ORIGIN | ||
| 488 | processing. | ||
| 489 | .It Cm retpolineplt | ||
| 490 | Emit retpoline format PLT entries as a mitigation for CVE-2017-5715. | ||
| 491 | .It Cm rodynamic | ||
| 492 | Make the | ||
| 493 | .Li .dynamic | ||
| 494 | section read-only. | ||
| 495 | The | ||
| 496 | .Dv DT_DEBUG | ||
| 497 | tag will not be emitted. | ||
| 498 | .It Cm stack-size Ns = Ns Ar size | ||
| 499 | Set the main thread's stack size to | ||
| 500 | .Ar size . | ||
| 501 | The stack size is recorded as the size of the | ||
| 502 | .Ar size . | ||
| 503 | .Dv PT_GNU_STACK | ||
| 504 | program segment. | ||
| 505 | .It Cm text | ||
| 506 | Do not allow relocations against read-only segments. | ||
| 507 | This is the default. | ||
| 508 | .It Cm wxneeded | ||
| 509 | Create a | ||
| 510 | .Dv PT_OPENBSD_WXNEEDED | ||
| 511 | segment. | ||
| 512 | .El | ||
| 513 | .El | ||
| 514 | .Sh IMPLEMENTATION NOTES | ||
| 515 | .Nm Ap s | ||
| 516 | handing of archive files (those with a | ||
| 517 | .Pa .a | ||
| 518 | file extension) is different from traditional linkers used on Unix-like | ||
| 519 | systems. | ||
| 520 | .Pp | ||
| 521 | Traditional linkers maintain a set of undefined symbols during linking. | ||
| 522 | The linker processes each file in the order in which it appears on the | ||
| 523 | command line, until the set of undefined symbols becomes empty. | ||
| 524 | An object file is linked into the output object when it is encountered, | ||
| 525 | with its undefined symbols added to the set. | ||
| 526 | Upon encountering an archive file a traditional linker searches the objects | ||
| 527 | contained therein, and processes those that satisfy symbols in the unresolved | ||
| 528 | set. | ||
| 529 | .Pp | ||
| 530 | Handling mutually dependent archives may be awkward when using a traditional | ||
| 531 | linker. | ||
| 532 | Archive files may have to be specified multiple times, or the special command | ||
| 533 | line options | ||
| 534 | .Fl -start-group | ||
| 535 | and | ||
| 536 | .Fl -end-group | ||
| 537 | may be used to have the linker loop over the files in the group until no new | ||
| 538 | symbols are added to the set. | ||
| 539 | .Pp | ||
| 540 | .Nm | ||
| 541 | records all symbols found in objects and archives as it iterates over | ||
| 542 | command line arguments. | ||
| 543 | When | ||
| 544 | .Nm | ||
| 545 | encounters an undefined symbol that can be resolved by an object file | ||
| 546 | contained in a previously processed archive file, it immediately extracts | ||
| 547 | and links it into the output object. | ||
| 548 | .Pp | ||
| 549 | With certain archive inputs | ||
| 550 | .Nm | ||
| 551 | may produce different results compared to traditional linkers. | ||
| 552 | In practice, large bodies of third party software have been linked with | ||
| 553 | .Nm | ||
| 554 | without material issues. | ||
| 555 | .Pp | ||
| 556 | The | ||
| 557 | .Fl -warn-backrefs | ||
| 558 | option may be used to identify a linker invocation that may be incompatible | ||
| 559 | with traditional Unix-like linker behavior. | ||
deps/lld/docs/windows_support.rst+9-3| ... | @@ -56,11 +56,17 @@ Module-definition file | ... | @@ -56,11 +56,17 @@ Module-definition file |
| 56 | ``EXPORTS``, ``HEAPSIZE``, ``STACKSIZE``, ``NAME``, and ``VERSION``. | 56 | ``EXPORTS``, ``HEAPSIZE``, ``STACKSIZE``, ``NAME``, and ``VERSION``. |
| 57 | 57 | ||
| 58 | Debug info | 58 | Debug info |
| 59 | :none:`No progress has been made`. Microsoft linker can interpret the CodeGen | 59 | :good:`Done`. LLD can emit PDBs that are at parity with those generated by |
| 60 | debug info (old-style debug info) and PDB to emit an .pdb file. LLD doesn't | 60 | link.exe. However, LLD does not support /DEBUG:FASTLINK. |
| 61 | support neither. | ||
| 62 | 61 | ||
| 63 | 62 | ||
| 63 | Downloading LLD | ||
| 64 | =============== | ||
| 65 | |||
| 66 | The Windows version of LLD is included in the `pre-built binaries of LLVM's | ||
| 67 | releases <https://releases.llvm.org/download.html>`_ and in the `LLVM Snapshot | ||
| 68 | Builds <https://llvm.org/builds/>`_. | ||
| 69 | |||
| 64 | Building LLD | 70 | Building LLD |
| 65 | ============ | 71 | ============ |
| 66 | 72 |
deps/lld/include/lld/Common/Driver.h+1-1| ... | @@ -30,7 +30,7 @@ bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, | ... | @@ -30,7 +30,7 @@ bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | namespace mach_o { | 32 | namespace mach_o { |
| 33 | bool link(llvm::ArrayRef<const char *> Args, | 33 | bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, |
| 34 | llvm::raw_ostream &Diag = llvm::errs()); | 34 | llvm::raw_ostream &Diag = llvm::errs()); |
| 35 | } | 35 | } |
| 36 | 36 |
deps/lld/include/lld/Common/ErrorHandler.h+59-11| ... | @@ -7,21 +7,62 @@ | ... | @@ -7,21 +7,62 @@ |
| 7 | // | 7 | // |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | // | 9 | // |
| 10 | // In LLD, we have three levels of errors: fatal, error or warn. | 10 | // We designed lld's error handlers with the following goals in mind: |
| 11 | // | 11 | // |
| 12 | // Fatal makes the program exit immediately with an error message. | 12 | // - Errors can occur at any place where we handle user input, but we don't |
| 13 | // You shouldn't use it except for reporting a corrupted input file. | 13 | // want them to affect the normal execution path too much. Ideally, |
| 14 | // handling errors should be as simple as reporting them and exit (but | ||
| 15 | // without actually doing exit). | ||
| 14 | // | 16 | // |
| 15 | // Error prints out an error message and increment a global variable | 17 | // In particular, the design to wrap all functions that could fail with |
| 16 | // ErrorCount to record the fact that we met an error condition. It does | 18 | // ErrorOr<T> is rejected because otherwise we would have to wrap a large |
| 17 | // not exit, so it is safe for a lld-as-a-library use case. It is generally | 19 | // number of functions in lld with ErrorOr. With that approach, if some |
| 18 | // useful because it can report more than one error in a single run. | 20 | // function F can fail, not only F but all functions that transitively call |
| 21 | // F have to be wrapped with ErrorOr. That seemed too much. | ||
| 19 | // | 22 | // |
| 20 | // Warn doesn't do anything but printing out a given message. | 23 | // - Finding only one error at a time is not sufficient. We want to find as |
| 24 | // many errors as possible with one execution of the linker. That means the | ||
| 25 | // linker needs to keep running after a first error and give up at some | ||
| 26 | // checkpoint (beyond which it would find cascading, false errors caused by | ||
| 27 | // the previous errors). | ||
| 21 | // | 28 | // |
| 22 | // It is not recommended to use llvm::outs() or llvm::errs() directly | 29 | // - We want a simple interface to report errors. Unlike Clang, the data we |
| 23 | // in LLD because they are not thread-safe. The functions declared in | 30 | // handle is compiled binary, so we don't need an error reporting mechanism |
| 24 | // this file are mutually excluded, so you want to use them instead. | 31 | // that's as sophisticated as the one that Clang has. |
| 32 | // | ||
| 33 | // The current lld's error handling mechanism is simple: | ||
| 34 | // | ||
| 35 | // - When you find an error, report it using error() and continue as far as | ||
| 36 | // you can. An internal error counter is incremented by one every time you | ||
| 37 | // call error(). | ||
| 38 | // | ||
| 39 | // A common idiom to handle an error is calling error() and then returning | ||
| 40 | // a reasonable default value. For example, if your function handles a | ||
| 41 | // user-supplied alignment value, and if you find an invalid alignment | ||
| 42 | // (e.g. 17 which is not 2^n), you may report it using error() and continue | ||
| 43 | // as if it were alignment 1 (which is the simplest reasonable value). | ||
| 44 | // | ||
| 45 | // Note that you should not continue with an invalid value; that breaks the | ||
| 46 | // internal consistency. You need to maintain all variables have some sane | ||
| 47 | // value even after an error occurred. So, when you have to continue with | ||
| 48 | // some value, always use a dummy value. | ||
| 49 | // | ||
| 50 | // - Find a reasonable checkpoint at where you want to stop the linker, and | ||
| 51 | // add code to return from the function if errorCount() > 0. In most cases, | ||
| 52 | // a checkpoint already exists, so you don't need to do anything for this. | ||
| 53 | // | ||
| 54 | // This interface satisfies all the goals that we mentioned above. | ||
| 55 | // | ||
| 56 | // You should never call fatal() except for reporting a corrupted input file. | ||
| 57 | // fatal() immediately terminates the linker, so the function is not desirable | ||
| 58 | // if you are using lld as a subroutine in other program, and with that you | ||
| 59 | // can find only one error at a time. | ||
| 60 | // | ||
| 61 | // warn() doesn't do anything but printing out a given message. | ||
| 62 | // | ||
| 63 | // It is not recommended to use llvm::outs() or llvm::errs() directly in lld | ||
| 64 | // because they are not thread-safe. The functions declared in this file are | ||
| 65 | // thread-safe. | ||
| 25 | // | 66 | // |
| 26 | //===----------------------------------------------------------------------===// | 67 | //===----------------------------------------------------------------------===// |
| 27 | 68 | ||
| ... | @@ -34,6 +75,10 @@ | ... | @@ -34,6 +75,10 @@ |
| 34 | #include "llvm/Support/Error.h" | 75 | #include "llvm/Support/Error.h" |
| 35 | #include "llvm/Support/FileOutputBuffer.h" | 76 | #include "llvm/Support/FileOutputBuffer.h" |
| 36 | 77 | ||
| 78 | namespace llvm { | ||
| 79 | class DiagnosticInfo; | ||
| 80 | } | ||
| 81 | |||
| 37 | namespace lld { | 82 | namespace lld { |
| 38 | 83 | ||
| 39 | class ErrorHandler { | 84 | class ErrorHandler { |
| ... | @@ -74,6 +119,9 @@ inline uint64_t errorCount() { return errorHandler().ErrorCount; } | ... | @@ -74,6 +119,9 @@ inline uint64_t errorCount() { return errorHandler().ErrorCount; } |
| 74 | 119 | ||
| 75 | LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); | 120 | LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); |
| 76 | 121 | ||
| 122 | void diagnosticHandler(const llvm::DiagnosticInfo &DI); | ||
| 123 | void checkError(Error E); | ||
| 124 | |||
| 77 | // check functions are convenient functions to strip errors | 125 | // check functions are convenient functions to strip errors |
| 78 | // from error-or-value objects. | 126 | // from error-or-value objects. |
| 79 | template <class T> T check(ErrorOr<T> E) { | 127 | template <class T> T check(ErrorOr<T> E) { |
deps/lld/include/lld/Common/Strings.h+26| ... | @@ -10,14 +10,40 @@ | ... | @@ -10,14 +10,40 @@ |
| 10 | #ifndef LLD_STRINGS_H | 10 | #ifndef LLD_STRINGS_H |
| 11 | #define LLD_STRINGS_H | 11 | #define LLD_STRINGS_H |
| 12 | 12 | ||
| 13 | #include "llvm/ADT/ArrayRef.h" | ||
| 13 | #include "llvm/ADT/Optional.h" | 14 | #include "llvm/ADT/Optional.h" |
| 14 | #include "llvm/ADT/StringRef.h" | 15 | #include "llvm/ADT/StringRef.h" |
| 16 | #include "llvm/Support/GlobPattern.h" | ||
| 15 | #include <string> | 17 | #include <string> |
| 18 | #include <vector> | ||
| 16 | 19 | ||
| 17 | namespace lld { | 20 | namespace lld { |
| 18 | // Returns a demangled C++ symbol name. If Name is not a mangled | 21 | // Returns a demangled C++ symbol name. If Name is not a mangled |
| 19 | // name, it returns Optional::None. | 22 | // name, it returns Optional::None. |
| 20 | llvm::Optional<std::string> demangleItanium(llvm::StringRef Name); | 23 | llvm::Optional<std::string> demangleItanium(llvm::StringRef Name); |
| 24 | llvm::Optional<std::string> demangleMSVC(llvm::StringRef S); | ||
| 25 | |||
| 26 | std::vector<uint8_t> parseHex(llvm::StringRef S); | ||
| 27 | bool isValidCIdentifier(llvm::StringRef S); | ||
| 28 | |||
| 29 | // Write the contents of the a buffer to a file | ||
| 30 | void saveBuffer(llvm::StringRef Buffer, const llvm::Twine &Path); | ||
| 31 | |||
| 32 | // This class represents multiple glob patterns. | ||
| 33 | class StringMatcher { | ||
| 34 | public: | ||
| 35 | StringMatcher() = default; | ||
| 36 | explicit StringMatcher(llvm::ArrayRef<llvm::StringRef> Pat); | ||
| 37 | |||
| 38 | bool match(llvm::StringRef S) const; | ||
| 39 | |||
| 40 | private: | ||
| 41 | std::vector<llvm::GlobPattern> Patterns; | ||
| 42 | }; | ||
| 43 | |||
| 44 | inline llvm::ArrayRef<uint8_t> toArrayRef(llvm::StringRef S) { | ||
| 45 | return {reinterpret_cast<const uint8_t *>(S.data()), S.size()}; | ||
| 21 | } | 46 | } |
| 47 | } // namespace lld | ||
| 22 | 48 | ||
| 23 | #endif | 49 | #endif |
deps/lld/include/lld/Common/TargetOptionsCommandFlags.h+1| ... | @@ -18,4 +18,5 @@ | ... | @@ -18,4 +18,5 @@ |
| 18 | namespace lld { | 18 | namespace lld { |
| 19 | llvm::TargetOptions InitTargetOptionsFromCodeGenFlags(); | 19 | llvm::TargetOptions InitTargetOptionsFromCodeGenFlags(); |
| 20 | llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel(); | 20 | llvm::Optional<llvm::CodeModel::Model> GetCodeModelFromCMModel(); |
| 21 | std::string GetCPUStr(); | ||
| 21 | } | 22 | } |
deps/lld/include/lld/Common/Timer.h created+59| ... | @@ -0,0 +1,59 @@ | ||
| 1 | //===- Timer.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_COMMON_TIMER_H | ||
| 11 | #define LLD_COMMON_TIMER_H | ||
| 12 | |||
| 13 | #include "llvm/ADT/DenseMap.h" | ||
| 14 | #include "llvm/ADT/StringRef.h" | ||
| 15 | #include <assert.h> | ||
| 16 | #include <chrono> | ||
| 17 | #include <map> | ||
| 18 | #include <memory> | ||
| 19 | |||
| 20 | namespace lld { | ||
| 21 | |||
| 22 | class Timer; | ||
| 23 | |||
| 24 | struct ScopedTimer { | ||
| 25 | explicit ScopedTimer(Timer &T); | ||
| 26 | |||
| 27 | ~ScopedTimer(); | ||
| 28 | |||
| 29 | void stop(); | ||
| 30 | |||
| 31 | Timer *T = nullptr; | ||
| 32 | }; | ||
| 33 | |||
| 34 | class Timer { | ||
| 35 | public: | ||
| 36 | Timer(llvm::StringRef Name, Timer &Parent); | ||
| 37 | |||
| 38 | static Timer &root(); | ||
| 39 | |||
| 40 | void start(); | ||
| 41 | void stop(); | ||
| 42 | void print(); | ||
| 43 | |||
| 44 | double millis() const; | ||
| 45 | |||
| 46 | private: | ||
| 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; | ||
| 55 | }; | ||
| 56 | |||
| 57 | } // namespace lld | ||
| 58 | |||
| 59 | #endif | ||
deps/lld/include/lld/Common/Version.h+1-1| ... | @@ -18,7 +18,7 @@ | ... | @@ -18,7 +18,7 @@ |
| 18 | #include "llvm/ADT/StringRef.h" | 18 | #include "llvm/ADT/StringRef.h" |
| 19 | 19 | ||
| 20 | namespace lld { | 20 | namespace lld { |
| 21 | /// \brief Retrieves a string representing the complete lld version. | 21 | /// Retrieves a string representing the complete lld version. |
| 22 | std::string getLLDVersion(); | 22 | std::string getLLDVersion(); |
| 23 | } | 23 | } |
| 24 | 24 |
deps/lld/include/lld/Core/DefinedAtom.h+22-22| ... | @@ -18,7 +18,7 @@ | ... | @@ -18,7 +18,7 @@ |
| 18 | namespace lld { | 18 | namespace lld { |
| 19 | class File; | 19 | class File; |
| 20 | 20 | ||
| 21 | /// \brief The fundamental unit of linking. | 21 | /// The fundamental unit of linking. |
| 22 | /// | 22 | /// |
| 23 | /// A C function or global variable is an atom. An atom has content and | 23 | /// A C function or global variable is an atom. An atom has content and |
| 24 | /// attributes. The content of a function atom is the instructions that | 24 | /// attributes. The content of a function atom is the instructions that |
| ... | @@ -179,10 +179,10 @@ public: | ... | @@ -179,10 +179,10 @@ public: |
| 179 | }; | 179 | }; |
| 180 | 180 | ||
| 181 | enum DynamicExport { | 181 | enum DynamicExport { |
| 182 | /// \brief The linker may or may not export this atom dynamically depending | 182 | /// The linker may or may not export this atom dynamically depending |
| 183 | /// on the output type and other context of the link. | 183 | /// on the output type and other context of the link. |
| 184 | dynamicExportNormal, | 184 | dynamicExportNormal, |
| 185 | /// \brief The linker will always export this atom dynamically. | 185 | /// The linker will always export this atom dynamically. |
| 186 | dynamicExportAlways, | 186 | dynamicExportAlways, |
| 187 | }; | 187 | }; |
| 188 | 188 | ||
| ... | @@ -212,26 +212,26 @@ public: | ... | @@ -212,26 +212,26 @@ public: |
| 212 | } | 212 | } |
| 213 | }; | 213 | }; |
| 214 | 214 | ||
| 215 | /// \brief returns a value for the order of this Atom within its file. | 215 | /// returns a value for the order of this Atom within its file. |
| 216 | /// | 216 | /// |
| 217 | /// This is used by the linker to order the layout of Atoms so that the | 217 | /// This is used by the linker to order the layout of Atoms so that the |
| 218 | /// resulting image is stable and reproducible. | 218 | /// resulting image is stable and reproducible. |
| 219 | virtual uint64_t ordinal() const = 0; | 219 | virtual uint64_t ordinal() const = 0; |
| 220 | 220 | ||
| 221 | /// \brief the number of bytes of space this atom's content will occupy in the | 221 | /// the number of bytes of space this atom's content will occupy in the |
| 222 | /// final linked image. | 222 | /// final linked image. |
| 223 | /// | 223 | /// |
| 224 | /// For a function atom, it is the number of bytes of code in the function. | 224 | /// For a function atom, it is the number of bytes of code in the function. |
| 225 | virtual uint64_t size() const = 0; | 225 | virtual uint64_t size() const = 0; |
| 226 | 226 | ||
| 227 | /// \brief The size of the section from which the atom is instantiated. | 227 | /// The size of the section from which the atom is instantiated. |
| 228 | /// | 228 | /// |
| 229 | /// Merge::mergeByLargestSection is defined in terms of section size | 229 | /// Merge::mergeByLargestSection is defined in terms of section size |
| 230 | /// and not in terms of atom size, so we need this function separate | 230 | /// and not in terms of atom size, so we need this function separate |
| 231 | /// from size(). | 231 | /// from size(). |
| 232 | virtual uint64_t sectionSize() const { return 0; } | 232 | virtual uint64_t sectionSize() const { return 0; } |
| 233 | 233 | ||
| 234 | /// \brief The visibility of this atom to other atoms. | 234 | /// The visibility of this atom to other atoms. |
| 235 | /// | 235 | /// |
| 236 | /// C static functions have scope scopeTranslationUnit. Regular C functions | 236 | /// C static functions have scope scopeTranslationUnit. Regular C functions |
| 237 | /// have scope scopeGlobal. Functions compiled with visibility=hidden have | 237 | /// have scope scopeGlobal. Functions compiled with visibility=hidden have |
| ... | @@ -239,48 +239,48 @@ public: | ... | @@ -239,48 +239,48 @@ public: |
| 239 | /// not by the OS loader. | 239 | /// not by the OS loader. |
| 240 | virtual Scope scope() const = 0; | 240 | virtual Scope scope() const = 0; |
| 241 | 241 | ||
| 242 | /// \brief Whether the linker should use direct or indirect access to this | 242 | /// Whether the linker should use direct or indirect access to this |
| 243 | /// atom. | 243 | /// atom. |
| 244 | virtual Interposable interposable() const = 0; | 244 | virtual Interposable interposable() const = 0; |
| 245 | 245 | ||
| 246 | /// \brief how the linker should handle if multiple atoms have the same name. | 246 | /// how the linker should handle if multiple atoms have the same name. |
| 247 | virtual Merge merge() const = 0; | 247 | virtual Merge merge() const = 0; |
| 248 | 248 | ||
| 249 | /// \brief The type of this atom, such as code or data. | 249 | /// The type of this atom, such as code or data. |
| 250 | virtual ContentType contentType() const = 0; | 250 | virtual ContentType contentType() const = 0; |
| 251 | 251 | ||
| 252 | /// \brief The alignment constraints on how this atom must be laid out in the | 252 | /// The alignment constraints on how this atom must be laid out in the |
| 253 | /// final linked image (e.g. 16-byte aligned). | 253 | /// final linked image (e.g. 16-byte aligned). |
| 254 | virtual Alignment alignment() const = 0; | 254 | virtual Alignment alignment() const = 0; |
| 255 | 255 | ||
| 256 | /// \brief Whether this atom must be in a specially named section in the final | 256 | /// Whether this atom must be in a specially named section in the final |
| 257 | /// linked image, or if the linker can infer the section based on the | 257 | /// linked image, or if the linker can infer the section based on the |
| 258 | /// contentType(). | 258 | /// contentType(). |
| 259 | virtual SectionChoice sectionChoice() const = 0; | 259 | virtual SectionChoice sectionChoice() const = 0; |
| 260 | 260 | ||
| 261 | /// \brief If sectionChoice() != sectionBasedOnContent, then this return the | 261 | /// If sectionChoice() != sectionBasedOnContent, then this return the |
| 262 | /// name of the section the atom should be placed into. | 262 | /// name of the section the atom should be placed into. |
| 263 | virtual StringRef customSectionName() const = 0; | 263 | virtual StringRef customSectionName() const = 0; |
| 264 | 264 | ||
| 265 | /// \brief constraints on whether the linker may dead strip away this atom. | 265 | /// constraints on whether the linker may dead strip away this atom. |
| 266 | virtual DeadStripKind deadStrip() const = 0; | 266 | virtual DeadStripKind deadStrip() const = 0; |
| 267 | 267 | ||
| 268 | /// \brief Under which conditions should this atom be dynamically exported. | 268 | /// Under which conditions should this atom be dynamically exported. |
| 269 | virtual DynamicExport dynamicExport() const { | 269 | virtual DynamicExport dynamicExport() const { |
| 270 | return dynamicExportNormal; | 270 | return dynamicExportNormal; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | /// \brief Code model used by the atom. | 273 | /// Code model used by the atom. |
| 274 | virtual CodeModel codeModel() const { return codeNA; } | 274 | virtual CodeModel codeModel() const { return codeNA; } |
| 275 | 275 | ||
| 276 | /// \brief Returns the OS memory protections required for this atom's content | 276 | /// Returns the OS memory protections required for this atom's content |
| 277 | /// at runtime. | 277 | /// at runtime. |
| 278 | /// | 278 | /// |
| 279 | /// A function atom is R_X, a global variable is RW_, and a read-only constant | 279 | /// A function atom is R_X, a global variable is RW_, and a read-only constant |
| 280 | /// is R__. | 280 | /// is R__. |
| 281 | virtual ContentPermissions permissions() const; | 281 | virtual ContentPermissions permissions() const; |
| 282 | 282 | ||
| 283 | /// \brief returns a reference to the raw (unrelocated) bytes of this Atom's | 283 | /// returns a reference to the raw (unrelocated) bytes of this Atom's |
| 284 | /// content. | 284 | /// content. |
| 285 | virtual ArrayRef<uint8_t> rawContent() const = 0; | 285 | virtual ArrayRef<uint8_t> rawContent() const = 0; |
| 286 | 286 | ||
| ... | @@ -317,10 +317,10 @@ public: | ... | @@ -317,10 +317,10 @@ public: |
| 317 | const void *_it; | 317 | const void *_it; |
| 318 | }; | 318 | }; |
| 319 | 319 | ||
| 320 | /// \brief Returns an iterator to the beginning of this Atom's References. | 320 | /// Returns an iterator to the beginning of this Atom's References. |
| 321 | virtual reference_iterator begin() const = 0; | 321 | virtual reference_iterator begin() const = 0; |
| 322 | 322 | ||
| 323 | /// \brief Returns an iterator to the end of this Atom's References. | 323 | /// Returns an iterator to the end of this Atom's References. |
| 324 | virtual reference_iterator end() const = 0; | 324 | virtual reference_iterator end() const = 0; |
| 325 | 325 | ||
| 326 | /// Adds a reference to this atom. | 326 | /// Adds a reference to this atom. |
| ... | @@ -361,11 +361,11 @@ protected: | ... | @@ -361,11 +361,11 @@ protected: |
| 361 | 361 | ||
| 362 | ~DefinedAtom() override = default; | 362 | ~DefinedAtom() override = default; |
| 363 | 363 | ||
| 364 | /// \brief Returns a pointer to the Reference object that the abstract | 364 | /// Returns a pointer to the Reference object that the abstract |
| 365 | /// iterator "points" to. | 365 | /// iterator "points" to. |
| 366 | virtual const Reference *derefIterator(const void *iter) const = 0; | 366 | virtual const Reference *derefIterator(const void *iter) const = 0; |
| 367 | 367 | ||
| 368 | /// \brief Adjusts the abstract iterator to "point" to the next Reference | 368 | /// Adjusts the abstract iterator to "point" to the next Reference |
| 369 | /// object for this Atom. | 369 | /// object for this Atom. |
| 370 | virtual void incrementIterator(const void *&iter) const = 0; | 370 | virtual void incrementIterator(const void *&iter) const = 0; |
| 371 | }; | 371 | }; |
deps/lld/include/lld/Core/File.h+11-13| ... | @@ -43,7 +43,7 @@ class File { | ... | @@ -43,7 +43,7 @@ class File { |
| 43 | public: | 43 | public: |
| 44 | virtual ~File(); | 44 | virtual ~File(); |
| 45 | 45 | ||
| 46 | /// \brief Kinds of files that are supported. | 46 | /// Kinds of files that are supported. |
| 47 | enum Kind { | 47 | enum Kind { |
| 48 | kindErrorObject, ///< a error object file (.o) | 48 | kindErrorObject, ///< a error object file (.o) |
| 49 | kindNormalizedObject, ///< a normalized file (.o) | 49 | kindNormalizedObject, ///< a normalized file (.o) |
| ... | @@ -59,7 +59,7 @@ public: | ... | @@ -59,7 +59,7 @@ public: |
| 59 | kindArchiveLibrary ///< archive (.a) | 59 | kindArchiveLibrary ///< archive (.a) |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | /// \brief Returns file kind. Need for dyn_cast<> on File objects. | 62 | /// Returns file kind. Need for dyn_cast<> on File objects. |
| 63 | Kind kind() const { | 63 | Kind kind() const { |
| 64 | return _kind; | 64 | return _kind; |
| 65 | } | 65 | } |
| ... | @@ -114,10 +114,8 @@ public: | ... | @@ -114,10 +114,8 @@ public: |
| 114 | AtomRange(AtomVector<T> &v) : _v(v) {} | 114 | AtomRange(AtomVector<T> &v) : _v(v) {} |
| 115 | AtomRange(const AtomVector<T> &v) : _v(const_cast<AtomVector<T> &>(v)) {} | 115 | AtomRange(const AtomVector<T> &v) : _v(const_cast<AtomVector<T> &>(v)) {} |
| 116 | 116 | ||
| 117 | typedef std::pointer_to_unary_function<const OwningAtomPtr<T>&, | 117 | using ConstDerefFn = const T* (*)(const OwningAtomPtr<T>&); |
| 118 | const T*> ConstDerefFn; | 118 | using DerefFn = T* (*)(OwningAtomPtr<T>&); |
| 119 | |||
| 120 | typedef std::pointer_to_unary_function<OwningAtomPtr<T>&, T*> DerefFn; | ||
| 121 | 119 | ||
| 122 | typedef llvm::mapped_iterator<typename AtomVector<T>::const_iterator, | 120 | typedef llvm::mapped_iterator<typename AtomVector<T>::const_iterator, |
| 123 | ConstDerefFn> ConstItTy; | 121 | ConstDerefFn> ConstItTy; |
| ... | @@ -174,19 +172,19 @@ public: | ... | @@ -174,19 +172,19 @@ public: |
| 174 | AtomVector<T> &_v; | 172 | AtomVector<T> &_v; |
| 175 | }; | 173 | }; |
| 176 | 174 | ||
| 177 | /// \brief Must be implemented to return the AtomVector object for | 175 | /// Must be implemented to return the AtomVector object for |
| 178 | /// all DefinedAtoms in this File. | 176 | /// all DefinedAtoms in this File. |
| 179 | virtual const AtomRange<DefinedAtom> defined() const = 0; | 177 | virtual const AtomRange<DefinedAtom> defined() const = 0; |
| 180 | 178 | ||
| 181 | /// \brief Must be implemented to return the AtomVector object for | 179 | /// Must be implemented to return the AtomVector object for |
| 182 | /// all UndefinedAtomw in this File. | 180 | /// all UndefinedAtomw in this File. |
| 183 | virtual const AtomRange<UndefinedAtom> undefined() const = 0; | 181 | virtual const AtomRange<UndefinedAtom> undefined() const = 0; |
| 184 | 182 | ||
| 185 | /// \brief Must be implemented to return the AtomVector object for | 183 | /// Must be implemented to return the AtomVector object for |
| 186 | /// all SharedLibraryAtoms in this File. | 184 | /// all SharedLibraryAtoms in this File. |
| 187 | virtual const AtomRange<SharedLibraryAtom> sharedLibrary() const = 0; | 185 | virtual const AtomRange<SharedLibraryAtom> sharedLibrary() const = 0; |
| 188 | 186 | ||
| 189 | /// \brief Must be implemented to return the AtomVector object for | 187 | /// Must be implemented to return the AtomVector object for |
| 190 | /// all AbsoluteAtoms in this File. | 188 | /// all AbsoluteAtoms in this File. |
| 191 | virtual const AtomRange<AbsoluteAtom> absolute() const = 0; | 189 | virtual const AtomRange<AbsoluteAtom> absolute() const = 0; |
| 192 | 190 | ||
| ... | @@ -196,7 +194,7 @@ public: | ... | @@ -196,7 +194,7 @@ public: |
| 196 | /// of a different file. We need to destruct all atoms before any files. | 194 | /// of a different file. We need to destruct all atoms before any files. |
| 197 | virtual void clearAtoms() = 0; | 195 | virtual void clearAtoms() = 0; |
| 198 | 196 | ||
| 199 | /// \brief If a file is parsed using a different method than doParse(), | 197 | /// If a file is parsed using a different method than doParse(), |
| 200 | /// one must use this method to set the last error status, so that | 198 | /// one must use this method to set the last error status, so that |
| 201 | /// doParse will not be called twice. Only YAML reader uses this | 199 | /// doParse will not be called twice. Only YAML reader uses this |
| 202 | /// (because YAML reader does not read blobs but structured data). | 200 | /// (because YAML reader does not read blobs but structured data). |
| ... | @@ -214,12 +212,12 @@ public: | ... | @@ -214,12 +212,12 @@ public: |
| 214 | } | 212 | } |
| 215 | 213 | ||
| 216 | protected: | 214 | protected: |
| 217 | /// \brief only subclasses of File can be instantiated | 215 | /// only subclasses of File can be instantiated |
| 218 | File(StringRef p, Kind kind) | 216 | File(StringRef p, Kind kind) |
| 219 | : _path(p), _kind(kind), _ordinal(UINT64_MAX), | 217 | : _path(p), _kind(kind), _ordinal(UINT64_MAX), |
| 220 | _nextAtomOrdinal(0) {} | 218 | _nextAtomOrdinal(0) {} |
| 221 | 219 | ||
| 222 | /// \brief Subclasses should override this method to parse the | 220 | /// Subclasses should override this method to parse the |
| 223 | /// memory buffer passed to this file's constructor. | 221 | /// memory buffer passed to this file's constructor. |
| 224 | virtual std::error_code doParse() { return std::error_code(); } | 222 | virtual std::error_code doParse() { return std::error_code(); } |
| 225 | 223 |
deps/lld/include/lld/Core/Instrumentation.h+7-7| ... | @@ -8,7 +8,7 @@ | ... | @@ -8,7 +8,7 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | /// | 9 | /// |
| 10 | /// \file | 10 | /// \file |
| 11 | /// \brief Provide an Instrumentation API that optionally uses VTune interfaces. | 11 | /// Provide an Instrumentation API that optionally uses VTune interfaces. |
| 12 | /// | 12 | /// |
| 13 | //===----------------------------------------------------------------------===// | 13 | //===----------------------------------------------------------------------===// |
| 14 | 14 | ||
| ... | @@ -24,7 +24,7 @@ | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | ||
| 25 | namespace lld { | 25 | namespace lld { |
| 26 | #ifdef LLD_HAS_VTUNE | 26 | #ifdef LLD_HAS_VTUNE |
| 27 | /// \brief A unique global scope for instrumentation data. | 27 | /// A unique global scope for instrumentation data. |
| 28 | /// | 28 | /// |
| 29 | /// Domains last for the lifetime of the application and cannot be destroyed. | 29 | /// Domains last for the lifetime of the application and cannot be destroyed. |
| 30 | /// Multiple Domains created with the same name represent the same domain. | 30 | /// Multiple Domains created with the same name represent the same domain. |
| ... | @@ -38,7 +38,7 @@ public: | ... | @@ -38,7 +38,7 @@ public: |
| 38 | __itt_domain *operator->() const { return _domain; } | 38 | __itt_domain *operator->() const { return _domain; } |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | /// \brief A global reference to a string constant. | 41 | /// A global reference to a string constant. |
| 42 | /// | 42 | /// |
| 43 | /// These are uniqued by the ITT runtime and cannot be deleted. They are not | 43 | /// These are uniqued by the ITT runtime and cannot be deleted. They are not |
| 44 | /// specific to a domain. | 44 | /// specific to a domain. |
| ... | @@ -54,7 +54,7 @@ public: | ... | @@ -54,7 +54,7 @@ public: |
| 54 | operator __itt_string_handle *() const { return _handle; } | 54 | operator __itt_string_handle *() const { return _handle; } |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | /// \brief A task on a single thread. Nests within other tasks. | 57 | /// A task on a single thread. Nests within other tasks. |
| 58 | /// | 58 | /// |
| 59 | /// Each thread has its own task stack and tasks nest recursively on that stack. | 59 | /// Each thread has its own task stack and tasks nest recursively on that stack. |
| 60 | /// A task cannot transfer threads. | 60 | /// A task cannot transfer threads. |
| ... | @@ -68,7 +68,7 @@ class ScopedTask { | ... | @@ -68,7 +68,7 @@ class ScopedTask { |
| 68 | ScopedTask &operator=(const ScopedTask &) = delete; | 68 | ScopedTask &operator=(const ScopedTask &) = delete; |
| 69 | 69 | ||
| 70 | public: | 70 | public: |
| 71 | /// \brief Create a task in Domain \p d named \p s. | 71 | /// Create a task in Domain \p d named \p s. |
| 72 | ScopedTask(const Domain &d, const StringHandle &s) : _domain(d) { | 72 | ScopedTask(const Domain &d, const StringHandle &s) : _domain(d) { |
| 73 | __itt_task_begin(d, __itt_null, __itt_null, s); | 73 | __itt_task_begin(d, __itt_null, __itt_null, s); |
| 74 | } | 74 | } |
| ... | @@ -83,7 +83,7 @@ public: | ... | @@ -83,7 +83,7 @@ public: |
| 83 | return *this; | 83 | return *this; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | /// \brief Prematurely end this task. | 86 | /// Prematurely end this task. |
| 87 | void end() { | 87 | void end() { |
| 88 | if (_domain) | 88 | if (_domain) |
| 89 | __itt_task_end(_domain); | 89 | __itt_task_end(_domain); |
| ... | @@ -93,7 +93,7 @@ public: | ... | @@ -93,7 +93,7 @@ public: |
| 93 | ~ScopedTask() { end(); } | 93 | ~ScopedTask() { end(); } |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | /// \brief A specific point in time. Allows metadata to be associated. | 96 | /// A specific point in time. Allows metadata to be associated. |
| 97 | class Marker { | 97 | class Marker { |
| 98 | public: | 98 | public: |
| 99 | Marker(const Domain &d, const StringHandle &s) { | 99 | Marker(const Domain &d, const StringHandle &s) { |
deps/lld/include/lld/Core/LinkingContext.h+4-5| ... | @@ -16,7 +16,6 @@ | ... | @@ -16,7 +16,6 @@ |
| 16 | #include "llvm/ADT/StringRef.h" | 16 | #include "llvm/ADT/StringRef.h" |
| 17 | #include "llvm/Support/Allocator.h" | 17 | #include "llvm/Support/Allocator.h" |
| 18 | #include "llvm/Support/Error.h" | 18 | #include "llvm/Support/Error.h" |
| 19 | #include "llvm/Support/raw_ostream.h" | ||
| 20 | #include <cassert> | 19 | #include <cassert> |
| 21 | #include <cstdint> | 20 | #include <cstdint> |
| 22 | #include <memory> | 21 | #include <memory> |
| ... | @@ -31,7 +30,7 @@ class Writer; | ... | @@ -31,7 +30,7 @@ class Writer; |
| 31 | class Node; | 30 | class Node; |
| 32 | class SharedLibraryFile; | 31 | class SharedLibraryFile; |
| 33 | 32 | ||
| 34 | /// \brief The LinkingContext class encapsulates "what and how" to link. | 33 | /// The LinkingContext class encapsulates "what and how" to link. |
| 35 | /// | 34 | /// |
| 36 | /// The base class LinkingContext contains the options needed by core linking. | 35 | /// The base class LinkingContext contains the options needed by core linking. |
| 37 | /// Subclasses of LinkingContext have additional options needed by specific | 36 | /// Subclasses of LinkingContext have additional options needed by specific |
| ... | @@ -167,10 +166,10 @@ public: | ... | @@ -167,10 +166,10 @@ public: |
| 167 | /// After all set* methods are called, the Driver calls this method | 166 | /// After all set* methods are called, the Driver calls this method |
| 168 | /// to validate that there are no missing options or invalid combinations | 167 | /// to validate that there are no missing options or invalid combinations |
| 169 | /// of options. If there is a problem, a description of the problem | 168 | /// of options. If there is a problem, a description of the problem |
| 170 | /// is written to the supplied stream. | 169 | /// is written to the global error handler. |
| 171 | /// | 170 | /// |
| 172 | /// \returns true if there is an error with the current settings. | 171 | /// \returns true if there is an error with the current settings. |
| 173 | bool validate(raw_ostream &diagnostics); | 172 | bool validate(); |
| 174 | 173 | ||
| 175 | /// Formats symbol name for use in error messages. | 174 | /// Formats symbol name for use in error messages. |
| 176 | virtual std::string demangle(StringRef symbolName) const = 0; | 175 | virtual std::string demangle(StringRef symbolName) const = 0; |
| ... | @@ -250,7 +249,7 @@ protected: | ... | @@ -250,7 +249,7 @@ protected: |
| 250 | 249 | ||
| 251 | private: | 250 | private: |
| 252 | /// Validate the subclass bits. Only called by validate. | 251 | /// Validate the subclass bits. Only called by validate. |
| 253 | virtual bool validateImpl(raw_ostream &diagnostics) = 0; | 252 | virtual bool validateImpl() = 0; |
| 254 | }; | 253 | }; |
| 255 | 254 | ||
| 256 | } // end namespace lld | 255 | } // end namespace lld |
deps/lld/include/lld/Core/PassManager.h+2-2| ... | @@ -20,7 +20,7 @@ namespace lld { | ... | @@ -20,7 +20,7 @@ namespace lld { |
| 20 | class SimpleFile; | 20 | class SimpleFile; |
| 21 | class Pass; | 21 | class Pass; |
| 22 | 22 | ||
| 23 | /// \brief Owns and runs a collection of passes. | 23 | /// Owns and runs a collection of passes. |
| 24 | /// | 24 | /// |
| 25 | /// This class is currently just a container for passes and a way to run them. | 25 | /// This class is currently just a container for passes and a way to run them. |
| 26 | /// | 26 | /// |
| ... | @@ -40,7 +40,7 @@ public: | ... | @@ -40,7 +40,7 @@ public: |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | private: | 42 | private: |
| 43 | /// \brief Passes in the order they should run. | 43 | /// Passes in the order they should run. |
| 44 | std::vector<std::unique_ptr<Pass>> _passes; | 44 | std::vector<std::unique_ptr<Pass>> _passes; |
| 45 | }; | 45 | }; |
| 46 | } // end namespace lld | 46 | } // end namespace lld |
deps/lld/include/lld/Core/Reader.h+3-3| ... | @@ -32,7 +32,7 @@ class File; | ... | @@ -32,7 +32,7 @@ class File; |
| 32 | class LinkingContext; | 32 | class LinkingContext; |
| 33 | class MachOLinkingContext; | 33 | class MachOLinkingContext; |
| 34 | 34 | ||
| 35 | /// \brief An abstract class for reading object files, library files, and | 35 | /// An abstract class for reading object files, library files, and |
| 36 | /// executable files. | 36 | /// executable files. |
| 37 | /// | 37 | /// |
| 38 | /// Each file format (e.g. mach-o, etc) has a concrete subclass of Reader. | 38 | /// Each file format (e.g. mach-o, etc) has a concrete subclass of Reader. |
| ... | @@ -46,14 +46,14 @@ public: | ... | @@ -46,14 +46,14 @@ public: |
| 46 | /// 2) the whole file content buffer if the above is not enough. | 46 | /// 2) the whole file content buffer if the above is not enough. |
| 47 | virtual bool canParse(llvm::file_magic magic, MemoryBufferRef mb) const = 0; | 47 | virtual bool canParse(llvm::file_magic magic, MemoryBufferRef mb) const = 0; |
| 48 | 48 | ||
| 49 | /// \brief Parse a supplied buffer (already filled with the contents of a | 49 | /// Parse a supplied buffer (already filled with the contents of a |
| 50 | /// file) and create a File object. | 50 | /// file) and create a File object. |
| 51 | /// The resulting File object takes ownership of the MemoryBuffer. | 51 | /// The resulting File object takes ownership of the MemoryBuffer. |
| 52 | virtual ErrorOr<std::unique_ptr<File>> | 52 | virtual ErrorOr<std::unique_ptr<File>> |
| 53 | loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &) const = 0; | 53 | loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &) const = 0; |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | /// \brief An abstract class for handling alternate yaml representations | 56 | /// An abstract class for handling alternate yaml representations |
| 57 | /// of object files. | 57 | /// of object files. |
| 58 | /// | 58 | /// |
| 59 | /// The YAML syntax allows "tags" which are used to specify the type of | 59 | /// The YAML syntax allows "tags" which are used to specify the type of |
deps/lld/include/lld/Core/Resolver.h+3-3| ... | @@ -28,7 +28,7 @@ namespace lld { | ... | @@ -28,7 +28,7 @@ namespace lld { |
| 28 | class Atom; | 28 | class Atom; |
| 29 | class LinkingContext; | 29 | class LinkingContext; |
| 30 | 30 | ||
| 31 | /// \brief The Resolver is responsible for merging all input object files | 31 | /// The Resolver is responsible for merging all input object files |
| 32 | /// and producing a merged graph. | 32 | /// and producing a merged graph. |
| 33 | class Resolver { | 33 | class Resolver { |
| 34 | public: | 34 | public: |
| ... | @@ -50,7 +50,7 @@ public: | ... | @@ -50,7 +50,7 @@ public: |
| 50 | // Handle a shared library file. | 50 | // Handle a shared library file. |
| 51 | llvm::Error handleSharedLibrary(File &); | 51 | llvm::Error handleSharedLibrary(File &); |
| 52 | 52 | ||
| 53 | /// @brief do work of merging and resolving and return list | 53 | /// do work of merging and resolving and return list |
| 54 | bool resolve(); | 54 | bool resolve(); |
| 55 | 55 | ||
| 56 | std::unique_ptr<SimpleFile> resultFile() { return std::move(_result); } | 56 | std::unique_ptr<SimpleFile> resultFile() { return std::move(_result); } |
| ... | @@ -61,7 +61,7 @@ private: | ... | @@ -61,7 +61,7 @@ private: |
| 61 | bool undefinesAdded(int begin, int end); | 61 | bool undefinesAdded(int begin, int end); |
| 62 | File *getFile(int &index); | 62 | File *getFile(int &index); |
| 63 | 63 | ||
| 64 | /// \brief The main function that iterates over the files to resolve | 64 | /// The main function that iterates over the files to resolve |
| 65 | bool resolveUndefines(); | 65 | bool resolveUndefines(); |
| 66 | void updateReferences(); | 66 | void updateReferences(); |
| 67 | void deadStripOptimize(); | 67 | void deadStripOptimize(); |
deps/lld/include/lld/Core/Simple.h+1-1| ... | @@ -8,7 +8,7 @@ | ... | @@ -8,7 +8,7 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | /// | 9 | /// |
| 10 | /// \file | 10 | /// \file |
| 11 | /// \brief Provide simple implementations for Atoms and File. | 11 | /// Provide simple implementations for Atoms and File. |
| 12 | /// | 12 | /// |
| 13 | //===----------------------------------------------------------------------===// | 13 | //===----------------------------------------------------------------------===// |
| 14 | 14 |
deps/lld/include/lld/Core/SymbolTable.h+11-11| ... | @@ -12,7 +12,7 @@ | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | ||
| 13 | #include "lld/Common/LLVM.h" | 13 | #include "lld/Common/LLVM.h" |
| 14 | #include "llvm/ADT/DenseSet.h" | 14 | #include "llvm/ADT/DenseSet.h" |
| 15 | #include "llvm/ADT/StringExtras.h" | 15 | #include "llvm/Support/DJB.h" |
| 16 | #include <cstring> | 16 | #include <cstring> |
| 17 | #include <map> | 17 | #include <map> |
| 18 | #include <vector> | 18 | #include <vector> |
| ... | @@ -27,35 +27,35 @@ class ResolverOptions; | ... | @@ -27,35 +27,35 @@ class ResolverOptions; |
| 27 | class SharedLibraryAtom; | 27 | class SharedLibraryAtom; |
| 28 | class UndefinedAtom; | 28 | class UndefinedAtom; |
| 29 | 29 | ||
| 30 | /// \brief The SymbolTable class is responsible for coalescing atoms. | 30 | /// The SymbolTable class is responsible for coalescing atoms. |
| 31 | /// | 31 | /// |
| 32 | /// All atoms coalescable by-name or by-content should be added. | 32 | /// All atoms coalescable by-name or by-content should be added. |
| 33 | /// The method replacement() can be used to find the replacement atom | 33 | /// The method replacement() can be used to find the replacement atom |
| 34 | /// if an atom has been coalesced away. | 34 | /// if an atom has been coalesced away. |
| 35 | class SymbolTable { | 35 | class SymbolTable { |
| 36 | public: | 36 | public: |
| 37 | /// @brief add atom to symbol table | 37 | /// add atom to symbol table |
| 38 | bool add(const DefinedAtom &); | 38 | bool add(const DefinedAtom &); |
| 39 | 39 | ||
| 40 | /// @brief add atom to symbol table | 40 | /// add atom to symbol table |
| 41 | bool add(const UndefinedAtom &); | 41 | bool add(const UndefinedAtom &); |
| 42 | 42 | ||
| 43 | /// @brief add atom to symbol table | 43 | /// add atom to symbol table |
| 44 | bool add(const SharedLibraryAtom &); | 44 | bool add(const SharedLibraryAtom &); |
| 45 | 45 | ||
| 46 | /// @brief add atom to symbol table | 46 | /// add atom to symbol table |
| 47 | bool add(const AbsoluteAtom &); | 47 | bool add(const AbsoluteAtom &); |
| 48 | 48 | ||
| 49 | /// @brief returns atom in symbol table for specified name (or nullptr) | 49 | /// returns atom in symbol table for specified name (or nullptr) |
| 50 | const Atom *findByName(StringRef sym); | 50 | const Atom *findByName(StringRef sym); |
| 51 | 51 | ||
| 52 | /// @brief returns vector of remaining UndefinedAtoms | 52 | /// returns vector of remaining UndefinedAtoms |
| 53 | std::vector<const UndefinedAtom *> undefines(); | 53 | std::vector<const UndefinedAtom *> undefines(); |
| 54 | 54 | ||
| 55 | /// @brief if atom has been coalesced away, return replacement, else return atom | 55 | /// if atom has been coalesced away, return replacement, else return atom |
| 56 | const Atom *replacement(const Atom *); | 56 | const Atom *replacement(const Atom *); |
| 57 | 57 | ||
| 58 | /// @brief if atom has been coalesced away, return true | 58 | /// if atom has been coalesced away, return true |
| 59 | bool isCoalescedAway(const Atom *); | 59 | bool isCoalescedAway(const Atom *); |
| 60 | 60 | ||
| 61 | private: | 61 | private: |
| ... | @@ -65,7 +65,7 @@ private: | ... | @@ -65,7 +65,7 @@ private: |
| 65 | static StringRef getEmptyKey() { return StringRef(); } | 65 | static StringRef getEmptyKey() { return StringRef(); } |
| 66 | static StringRef getTombstoneKey() { return StringRef(" ", 1); } | 66 | static StringRef getTombstoneKey() { return StringRef(" ", 1); } |
| 67 | static unsigned getHashValue(StringRef const val) { | 67 | static unsigned getHashValue(StringRef const val) { |
| 68 | return llvm::HashString(val); | 68 | return llvm::djbHash(val, 0); |
| 69 | } | 69 | } |
| 70 | static bool isEqual(StringRef const lhs, StringRef const rhs) { | 70 | static bool isEqual(StringRef const lhs, StringRef const rhs) { |
| 71 | return lhs.equals(rhs); | 71 | return lhs.equals(rhs); |
deps/lld/include/lld/Core/TODO.txt-3| ... | @@ -6,9 +6,6 @@ include/lld/Core | ... | @@ -6,9 +6,6 @@ include/lld/Core |
| 6 | abstraction only works for returning low level OS errors. It does not | 6 | abstraction only works for returning low level OS errors. It does not |
| 7 | work for describing formatting issues. | 7 | work for describing formatting issues. |
| 8 | 8 | ||
| 9 | * We need to design a diagnostics interface. It would be nice to share code | ||
| 10 | with Clang_ where possible. | ||
| 11 | |||
| 12 | * We need to add more attributes to File. In particular, we need cpu | 9 | * We need to add more attributes to File. In particular, we need cpu |
| 13 | and OS information (like target triples). We should also provide explicit | 10 | and OS information (like target triples). We should also provide explicit |
| 14 | support for `LLVM IR module flags metadata`__. | 11 | support for `LLVM IR module flags metadata`__. |
deps/lld/include/lld/Core/Writer.h+3-3| ... | @@ -20,17 +20,17 @@ class File; | ... | @@ -20,17 +20,17 @@ class File; |
| 20 | class LinkingContext; | 20 | class LinkingContext; |
| 21 | class MachOLinkingContext; | 21 | class MachOLinkingContext; |
| 22 | 22 | ||
| 23 | /// \brief The Writer is an abstract class for writing object files, shared | 23 | /// The Writer is an abstract class for writing object files, shared |
| 24 | /// library files, and executable files. Each file format (e.g. mach-o, etc) | 24 | /// library files, and executable files. Each file format (e.g. mach-o, etc) |
| 25 | /// has a concrete subclass of Writer. | 25 | /// has a concrete subclass of Writer. |
| 26 | class Writer { | 26 | class Writer { |
| 27 | public: | 27 | public: |
| 28 | virtual ~Writer(); | 28 | virtual ~Writer(); |
| 29 | 29 | ||
| 30 | /// \brief Write a file from the supplied File object | 30 | /// Write a file from the supplied File object |
| 31 | virtual llvm::Error writeFile(const File &linkedFile, StringRef path) = 0; | 31 | virtual llvm::Error writeFile(const File &linkedFile, StringRef path) = 0; |
| 32 | 32 | ||
| 33 | /// \brief This method is called by Core Linking to give the Writer a chance | 33 | /// This method is called by Core Linking to give the Writer a chance |
| 34 | /// to add file format specific "files" to set of files to be linked. This is | 34 | /// to add file format specific "files" to set of files to be linked. This is |
| 35 | /// how file format specific atoms can be added to the link. | 35 | /// how file format specific atoms can be added to the link. |
| 36 | virtual void createImplicitFiles(std::vector<std::unique_ptr<File>> &) {} | 36 | virtual void createImplicitFiles(std::vector<std::unique_ptr<File>> &) {} |
deps/lld/include/lld/ReaderWriter/MachOLinkingContext.h+14-14| ... | @@ -89,7 +89,7 @@ public: | ... | @@ -89,7 +89,7 @@ public: |
| 89 | bool exportDynamicSymbols); | 89 | bool exportDynamicSymbols); |
| 90 | 90 | ||
| 91 | void addPasses(PassManager &pm) override; | 91 | void addPasses(PassManager &pm) override; |
| 92 | bool validateImpl(raw_ostream &diagnostics) override; | 92 | bool validateImpl() override; |
| 93 | std::string demangle(StringRef symbolName) const override; | 93 | std::string demangle(StringRef symbolName) const override; |
| 94 | 94 | ||
| 95 | void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override; | 95 | void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override; |
| ... | @@ -201,7 +201,7 @@ public: | ... | @@ -201,7 +201,7 @@ public: |
| 201 | 201 | ||
| 202 | uint32_t swiftVersion() const { return _swiftVersion; } | 202 | uint32_t swiftVersion() const { return _swiftVersion; } |
| 203 | 203 | ||
| 204 | /// \brief Checks whether a given path on the filesystem exists. | 204 | /// Checks whether a given path on the filesystem exists. |
| 205 | /// | 205 | /// |
| 206 | /// When running in -test_file_usage mode, this method consults an | 206 | /// When running in -test_file_usage mode, this method consults an |
| 207 | /// internally maintained list of files that exist (provided by -path_exists) | 207 | /// internally maintained list of files that exist (provided by -path_exists) |
| ... | @@ -211,7 +211,7 @@ public: | ... | @@ -211,7 +211,7 @@ public: |
| 211 | /// Like pathExists() but only used on files - not directories. | 211 | /// Like pathExists() but only used on files - not directories. |
| 212 | bool fileExists(StringRef path) const; | 212 | bool fileExists(StringRef path) const; |
| 213 | 213 | ||
| 214 | /// \brief Adds any library search paths derived from the given base, possibly | 214 | /// Adds any library search paths derived from the given base, possibly |
| 215 | /// modified by -syslibroots. | 215 | /// modified by -syslibroots. |
| 216 | /// | 216 | /// |
| 217 | /// The set of paths added consists of approximately all syslibroot-prepended | 217 | /// The set of paths added consists of approximately all syslibroot-prepended |
| ... | @@ -219,7 +219,7 @@ public: | ... | @@ -219,7 +219,7 @@ public: |
| 219 | /// for whatever reason. With various edge-cases for compatibility. | 219 | /// for whatever reason. With various edge-cases for compatibility. |
| 220 | void addModifiedSearchDir(StringRef libPath, bool isSystemPath = false); | 220 | void addModifiedSearchDir(StringRef libPath, bool isSystemPath = false); |
| 221 | 221 | ||
| 222 | /// \brief Determine whether -lFoo can be resolve within the given path, and | 222 | /// Determine whether -lFoo can be resolve within the given path, and |
| 223 | /// return the filename if so. | 223 | /// return the filename if so. |
| 224 | /// | 224 | /// |
| 225 | /// The -lFoo option is documented to search for libFoo.dylib and libFoo.a in | 225 | /// The -lFoo option is documented to search for libFoo.dylib and libFoo.a in |
| ... | @@ -228,7 +228,7 @@ public: | ... | @@ -228,7 +228,7 @@ public: |
| 228 | llvm::Optional<StringRef> searchDirForLibrary(StringRef path, | 228 | llvm::Optional<StringRef> searchDirForLibrary(StringRef path, |
| 229 | StringRef libName) const; | 229 | StringRef libName) const; |
| 230 | 230 | ||
| 231 | /// \brief Iterates through all search path entries looking for libName (as | 231 | /// Iterates through all search path entries looking for libName (as |
| 232 | /// specified by -lFoo). | 232 | /// specified by -lFoo). |
| 233 | llvm::Optional<StringRef> searchLibrary(StringRef libName) const; | 233 | llvm::Optional<StringRef> searchLibrary(StringRef libName) const; |
| 234 | 234 | ||
| ... | @@ -236,11 +236,11 @@ public: | ... | @@ -236,11 +236,11 @@ public: |
| 236 | /// the path with syslibroot. | 236 | /// the path with syslibroot. |
| 237 | void addFrameworkSearchDir(StringRef fwPath, bool isSystemPath = false); | 237 | void addFrameworkSearchDir(StringRef fwPath, bool isSystemPath = false); |
| 238 | 238 | ||
| 239 | /// \brief Iterates through all framework directories looking for | 239 | /// Iterates through all framework directories looking for |
| 240 | /// Foo.framework/Foo (when fwName = "Foo"). | 240 | /// Foo.framework/Foo (when fwName = "Foo"). |
| 241 | llvm::Optional<StringRef> findPathForFramework(StringRef fwName) const; | 241 | llvm::Optional<StringRef> findPathForFramework(StringRef fwName) const; |
| 242 | 242 | ||
| 243 | /// \brief The dylib's binary compatibility version, in the raw uint32 format. | 243 | /// The dylib's binary compatibility version, in the raw uint32 format. |
| 244 | /// | 244 | /// |
| 245 | /// When building a dynamic library, this is the compatibility version that | 245 | /// When building a dynamic library, this is the compatibility version that |
| 246 | /// gets embedded into the result. Other Mach-O binaries that link against | 246 | /// gets embedded into the result. Other Mach-O binaries that link against |
| ... | @@ -249,28 +249,28 @@ public: | ... | @@ -249,28 +249,28 @@ public: |
| 249 | /// installed dynamic library. | 249 | /// installed dynamic library. |
| 250 | uint32_t compatibilityVersion() const { return _compatibilityVersion; } | 250 | uint32_t compatibilityVersion() const { return _compatibilityVersion; } |
| 251 | 251 | ||
| 252 | /// \brief The dylib's current version, in the the raw uint32 format. | 252 | /// The dylib's current version, in the the raw uint32 format. |
| 253 | /// | 253 | /// |
| 254 | /// When building a dynamic library, this is the current version that gets | 254 | /// When building a dynamic library, this is the current version that gets |
| 255 | /// embedded into the result. Other Mach-O binaries that link against | 255 | /// embedded into the result. Other Mach-O binaries that link against |
| 256 | /// this library will store the compatibility version in its load command. | 256 | /// this library will store the compatibility version in its load command. |
| 257 | uint32_t currentVersion() const { return _currentVersion; } | 257 | uint32_t currentVersion() const { return _currentVersion; } |
| 258 | 258 | ||
| 259 | /// \brief The dylib's install name. | 259 | /// The dylib's install name. |
| 260 | /// | 260 | /// |
| 261 | /// Binaries that link against the dylib will embed this path into the dylib | 261 | /// Binaries that link against the dylib will embed this path into the dylib |
| 262 | /// load command. When loading the binaries at runtime, this is the location | 262 | /// load command. When loading the binaries at runtime, this is the location |
| 263 | /// on disk that the loader will look for the dylib. | 263 | /// on disk that the loader will look for the dylib. |
| 264 | StringRef installName() const { return _installName; } | 264 | StringRef installName() const { return _installName; } |
| 265 | 265 | ||
| 266 | /// \brief Whether or not the dylib has side effects during initialization. | 266 | /// Whether or not the dylib has side effects during initialization. |
| 267 | /// | 267 | /// |
| 268 | /// Dylibs marked as being dead strippable provide the guarantee that loading | 268 | /// Dylibs marked as being dead strippable provide the guarantee that loading |
| 269 | /// the dylib has no side effects, allowing the linker to strip out the dylib | 269 | /// the dylib has no side effects, allowing the linker to strip out the dylib |
| 270 | /// when linking a binary that does not use any of its symbols. | 270 | /// when linking a binary that does not use any of its symbols. |
| 271 | bool deadStrippableDylib() const { return _deadStrippableDylib; } | 271 | bool deadStrippableDylib() const { return _deadStrippableDylib; } |
| 272 | 272 | ||
| 273 | /// \brief Whether or not to use flat namespace. | 273 | /// Whether or not to use flat namespace. |
| 274 | /// | 274 | /// |
| 275 | /// MachO usually uses a two-level namespace, where each external symbol | 275 | /// MachO usually uses a two-level namespace, where each external symbol |
| 276 | /// referenced by the target is associated with the dylib that will provide | 276 | /// referenced by the target is associated with the dylib that will provide |
| ... | @@ -282,7 +282,7 @@ public: | ... | @@ -282,7 +282,7 @@ public: |
| 282 | /// loaded flat_namespace dylibs must be resolvable at build time. | 282 | /// loaded flat_namespace dylibs must be resolvable at build time. |
| 283 | bool useFlatNamespace() const { return _flatNamespace; } | 283 | bool useFlatNamespace() const { return _flatNamespace; } |
| 284 | 284 | ||
| 285 | /// \brief How to handle undefined symbols. | 285 | /// How to handle undefined symbols. |
| 286 | /// | 286 | /// |
| 287 | /// Options are: | 287 | /// Options are: |
| 288 | /// * error: Report an error and terminate linking. | 288 | /// * error: Report an error and terminate linking. |
| ... | @@ -294,7 +294,7 @@ public: | ... | @@ -294,7 +294,7 @@ public: |
| 294 | /// runtime. | 294 | /// runtime. |
| 295 | UndefinedMode undefinedMode() const { return _undefinedMode; } | 295 | UndefinedMode undefinedMode() const { return _undefinedMode; } |
| 296 | 296 | ||
| 297 | /// \brief The path to the executable that will load the bundle at runtime. | 297 | /// The path to the executable that will load the bundle at runtime. |
| 298 | /// | 298 | /// |
| 299 | /// When building a Mach-O bundle, this executable will be examined if there | 299 | /// When building a Mach-O bundle, this executable will be examined if there |
| 300 | /// are undefined symbols after the main link phase. It is expected that this | 300 | /// are undefined symbols after the main link phase. It is expected that this |
| ... | @@ -331,7 +331,7 @@ public: | ... | @@ -331,7 +331,7 @@ public: |
| 331 | /// Add section alignment constraint on final layout. | 331 | /// Add section alignment constraint on final layout. |
| 332 | void addSectionAlignment(StringRef seg, StringRef sect, uint16_t align); | 332 | void addSectionAlignment(StringRef seg, StringRef sect, uint16_t align); |
| 333 | 333 | ||
| 334 | /// \brief Add a section based on a command-line sectcreate option. | 334 | /// Add a section based on a command-line sectcreate option. |
| 335 | void addSectCreateSection(StringRef seg, StringRef sect, | 335 | void addSectCreateSection(StringRef seg, StringRef sect, |
| 336 | std::unique_ptr<MemoryBuffer> content); | 336 | std::unique_ptr<MemoryBuffer> content); |
| 337 | 337 |
deps/lld/lib/Core/LinkingContext.cpp+2-2| ... | @@ -20,8 +20,8 @@ LinkingContext::LinkingContext() = default; | ... | @@ -20,8 +20,8 @@ LinkingContext::LinkingContext() = default; |
| 20 | 20 | ||
| 21 | LinkingContext::~LinkingContext() = default; | 21 | LinkingContext::~LinkingContext() = default; |
| 22 | 22 | ||
| 23 | bool LinkingContext::validate(raw_ostream &diagnostics) { | 23 | bool LinkingContext::validate() { |
| 24 | return validateImpl(diagnostics); | 24 | return validateImpl(); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | llvm::Error LinkingContext::writeFile(const File &linkedFile) const { | 27 | llvm::Error LinkingContext::writeFile(const File &linkedFile) const { |
deps/lld/lib/Driver/CMakeLists.txt+1| ... | @@ -13,6 +13,7 @@ add_lld_library(lldDriver | ... | @@ -13,6 +13,7 @@ add_lld_library(lldDriver |
| 13 | Support | 13 | Support |
| 14 | 14 | ||
| 15 | LINK_LIBS | 15 | LINK_LIBS |
| 16 | lldCommon | ||
| 16 | lldCore | 17 | lldCore |
| 17 | lldMachO | 18 | lldMachO |
| 18 | lldReaderWriter | 19 | lldReaderWriter |
deps/lld/lib/Driver/DarwinLdDriver.cpp+150-162| ... | @@ -13,6 +13,8 @@ | ... | @@ -13,6 +13,8 @@ |
| 13 | /// | 13 | /// |
| 14 | //===----------------------------------------------------------------------===// | 14 | //===----------------------------------------------------------------------===// |
| 15 | 15 | ||
| 16 | #include "lld/Common/Args.h" | ||
| 17 | #include "lld/Common/ErrorHandler.h" | ||
| 16 | #include "lld/Common/LLVM.h" | 18 | #include "lld/Common/LLVM.h" |
| 17 | #include "lld/Core/ArchiveLibraryFile.h" | 19 | #include "lld/Core/ArchiveLibraryFile.h" |
| 18 | #include "lld/Core/Error.h" | 20 | #include "lld/Core/Error.h" |
| ... | @@ -110,11 +112,11 @@ parseMemberFiles(std::unique_ptr<File> file) { | ... | @@ -110,11 +112,11 @@ parseMemberFiles(std::unique_ptr<File> file) { |
| 110 | return members; | 112 | return members; |
| 111 | } | 113 | } |
| 112 | 114 | ||
| 113 | std::vector<std::unique_ptr<File>> | 115 | std::vector<std::unique_ptr<File>> loadFile(MachOLinkingContext &ctx, |
| 114 | loadFile(MachOLinkingContext &ctx, StringRef path, | 116 | StringRef path, bool wholeArchive, |
| 115 | raw_ostream &diag, bool wholeArchive, bool upwardDylib) { | 117 | bool upwardDylib) { |
| 116 | if (ctx.logInputFiles()) | 118 | if (ctx.logInputFiles()) |
| 117 | diag << path << "\n"; | 119 | message(path); |
| 118 | 120 | ||
| 119 | ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = ctx.getMemoryBuffer(path); | 121 | ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = ctx.getMemoryBuffer(path); |
| 120 | if (std::error_code ec = mbOrErr.getError()) | 122 | if (std::error_code ec = mbOrErr.getError()) |
| ... | @@ -155,10 +157,9 @@ static std::string canonicalizePath(StringRef path) { | ... | @@ -155,10 +157,9 @@ static std::string canonicalizePath(StringRef path) { |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 157 | static void addFile(StringRef path, MachOLinkingContext &ctx, | 159 | static void addFile(StringRef path, MachOLinkingContext &ctx, |
| 158 | bool loadWholeArchive, | 160 | bool loadWholeArchive, bool upwardDylib) { |
| 159 | bool upwardDylib, raw_ostream &diag) { | ||
| 160 | std::vector<std::unique_ptr<File>> files = | 161 | std::vector<std::unique_ptr<File>> files = |
| 161 | loadFile(ctx, path, diag, loadWholeArchive, upwardDylib); | 162 | loadFile(ctx, path, loadWholeArchive, upwardDylib); |
| 162 | for (std::unique_ptr<File> &file : files) | 163 | for (std::unique_ptr<File> &file : files) |
| 163 | ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file))); | 164 | ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file))); |
| 164 | } | 165 | } |
| ... | @@ -166,8 +167,7 @@ static void addFile(StringRef path, MachOLinkingContext &ctx, | ... | @@ -166,8 +167,7 @@ static void addFile(StringRef path, MachOLinkingContext &ctx, |
| 166 | // Export lists are one symbol per line. Blank lines are ignored. | 167 | // Export lists are one symbol per line. Blank lines are ignored. |
| 167 | // Trailing comments start with #. | 168 | // Trailing comments start with #. |
| 168 | static std::error_code parseExportsList(StringRef exportFilePath, | 169 | static std::error_code parseExportsList(StringRef exportFilePath, |
| 169 | MachOLinkingContext &ctx, | 170 | MachOLinkingContext &ctx) { |
| 170 | raw_ostream &diagnostics) { | ||
| 171 | // Map in export list file. | 171 | // Map in export list file. |
| 172 | ErrorOr<std::unique_ptr<MemoryBuffer>> mb = | 172 | ErrorOr<std::unique_ptr<MemoryBuffer>> mb = |
| 173 | MemoryBuffer::getFileOrSTDIN(exportFilePath); | 173 | MemoryBuffer::getFileOrSTDIN(exportFilePath); |
| ... | @@ -197,8 +197,7 @@ static std::error_code parseExportsList(StringRef exportFilePath, | ... | @@ -197,8 +197,7 @@ static std::error_code parseExportsList(StringRef exportFilePath, |
| 197 | /// libfrob.a(bar.o):_bar | 197 | /// libfrob.a(bar.o):_bar |
| 198 | /// x86_64:_foo64 | 198 | /// x86_64:_foo64 |
| 199 | static std::error_code parseOrderFile(StringRef orderFilePath, | 199 | static std::error_code parseOrderFile(StringRef orderFilePath, |
| 200 | MachOLinkingContext &ctx, | 200 | MachOLinkingContext &ctx) { |
| 201 | raw_ostream &diagnostics) { | ||
| 202 | // Map in order file. | 201 | // Map in order file. |
| 203 | ErrorOr<std::unique_ptr<MemoryBuffer>> mb = | 202 | ErrorOr<std::unique_ptr<MemoryBuffer>> mb = |
| 204 | MemoryBuffer::getFileOrSTDIN(orderFilePath); | 203 | MemoryBuffer::getFileOrSTDIN(orderFilePath); |
| ... | @@ -252,8 +251,7 @@ static std::error_code parseOrderFile(StringRef orderFilePath, | ... | @@ -252,8 +251,7 @@ static std::error_code parseOrderFile(StringRef orderFilePath, |
| 252 | // per line. The <dir> prefix is prepended to each partial path. | 251 | // per line. The <dir> prefix is prepended to each partial path. |
| 253 | // | 252 | // |
| 254 | static llvm::Error loadFileList(StringRef fileListPath, | 253 | static llvm::Error loadFileList(StringRef fileListPath, |
| 255 | MachOLinkingContext &ctx, bool forceLoad, | 254 | MachOLinkingContext &ctx, bool forceLoad) { |
| 256 | raw_ostream &diagnostics) { | ||
| 257 | // If there is a comma, split off <dir>. | 255 | // If there is a comma, split off <dir>. |
| 258 | std::pair<StringRef, StringRef> opt = fileListPath.split(','); | 256 | std::pair<StringRef, StringRef> opt = fileListPath.split(','); |
| 259 | StringRef filePath = opt.first; | 257 | StringRef filePath = opt.first; |
| ... | @@ -286,9 +284,9 @@ static llvm::Error loadFileList(StringRef fileListPath, | ... | @@ -286,9 +284,9 @@ static llvm::Error loadFileList(StringRef fileListPath, |
| 286 | + "'"); | 284 | + "'"); |
| 287 | } | 285 | } |
| 288 | if (ctx.testingFileUsage()) { | 286 | if (ctx.testingFileUsage()) { |
| 289 | diagnostics << "Found filelist entry " << canonicalizePath(path) << '\n'; | 287 | message("Found filelist entry " + canonicalizePath(path)); |
| 290 | } | 288 | } |
| 291 | addFile(path, ctx, forceLoad, false, diagnostics); | 289 | addFile(path, ctx, forceLoad, false); |
| 292 | buffer = lineAndRest.second; | 290 | buffer = lineAndRest.second; |
| 293 | } | 291 | } |
| 294 | return llvm::Error::success(); | 292 | return llvm::Error::success(); |
| ... | @@ -317,8 +315,7 @@ static void parseLLVMOptions(const LinkingContext &ctx) { | ... | @@ -317,8 +315,7 @@ static void parseLLVMOptions(const LinkingContext &ctx) { |
| 317 | namespace lld { | 315 | namespace lld { |
| 318 | namespace mach_o { | 316 | namespace mach_o { |
| 319 | 317 | ||
| 320 | bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | 318 | bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx) { |
| 321 | raw_ostream &diagnostics) { | ||
| 322 | // Parse command line options using DarwinLdOptions.td | 319 | // Parse command line options using DarwinLdOptions.td |
| 323 | DarwinLdOptTable table; | 320 | DarwinLdOptTable table; |
| 324 | unsigned missingIndex; | 321 | unsigned missingIndex; |
| ... | @@ -326,17 +323,20 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -326,17 +323,20 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 326 | llvm::opt::InputArgList parsedArgs = | 323 | llvm::opt::InputArgList parsedArgs = |
| 327 | table.ParseArgs(args.slice(1), missingIndex, missingCount); | 324 | table.ParseArgs(args.slice(1), missingIndex, missingCount); |
| 328 | if (missingCount) { | 325 | if (missingCount) { |
| 329 | diagnostics << "error: missing arg value for '" | 326 | error("missing arg value for '" + |
| 330 | << parsedArgs.getArgString(missingIndex) << "' expected " | 327 | Twine(parsedArgs.getArgString(missingIndex)) + "' expected " + |
| 331 | << missingCount << " argument(s).\n"; | 328 | Twine(missingCount) + " argument(s)."); |
| 332 | return false; | 329 | return false; |
| 333 | } | 330 | } |
| 334 | 331 | ||
| 335 | for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN)) { | 332 | for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN)) { |
| 336 | diagnostics << "warning: ignoring unknown argument: " | 333 | warn("ignoring unknown argument: " + |
| 337 | << unknownArg->getAsString(parsedArgs) << "\n"; | 334 | Twine(unknownArg->getAsString(parsedArgs))); |
| 338 | } | 335 | } |
| 339 | 336 | ||
| 337 | errorHandler().Verbose = parsedArgs.hasArg(OPT_v); | ||
| 338 | errorHandler().ErrorLimit = args::getInteger(parsedArgs, OPT_error_limit, 20); | ||
| 339 | |||
| 340 | // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static ) | 340 | // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static ) |
| 341 | llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE; | 341 | llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE; |
| 342 | bool isStaticExecutable = false; | 342 | bool isStaticExecutable = false; |
| ... | @@ -367,8 +367,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -367,8 +367,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 367 | if (llvm::opt::Arg *archStr = parsedArgs.getLastArg(OPT_arch)) { | 367 | if (llvm::opt::Arg *archStr = parsedArgs.getLastArg(OPT_arch)) { |
| 368 | arch = MachOLinkingContext::archFromName(archStr->getValue()); | 368 | arch = MachOLinkingContext::archFromName(archStr->getValue()); |
| 369 | if (arch == MachOLinkingContext::arch_unknown) { | 369 | if (arch == MachOLinkingContext::arch_unknown) { |
| 370 | diagnostics << "error: unknown arch named '" << archStr->getValue() | 370 | error("unknown arch named '" + Twine(archStr->getValue()) + "'"); |
| 371 | << "'\n"; | ||
| 372 | return false; | 371 | return false; |
| 373 | } | 372 | } |
| 374 | } | 373 | } |
| ... | @@ -386,7 +385,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -386,7 +385,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 386 | if (parsedArgs.size() == 0) | 385 | if (parsedArgs.size() == 0) |
| 387 | table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false); | 386 | table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false); |
| 388 | else | 387 | else |
| 389 | diagnostics << "error: -arch not specified and could not be inferred\n"; | 388 | error("-arch not specified and could not be inferred"); |
| 390 | return false; | 389 | return false; |
| 391 | } | 390 | } |
| 392 | } | 391 | } |
| ... | @@ -402,7 +401,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -402,7 +401,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 402 | os = MachOLinkingContext::OS::macOSX; | 401 | os = MachOLinkingContext::OS::macOSX; |
| 403 | if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), | 402 | if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), |
| 404 | minOSVersion)) { | 403 | minOSVersion)) { |
| 405 | diagnostics << "error: malformed macosx_version_min value\n"; | 404 | error("malformed macosx_version_min value"); |
| 406 | return false; | 405 | return false; |
| 407 | } | 406 | } |
| 408 | break; | 407 | break; |
| ... | @@ -410,7 +409,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -410,7 +409,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 410 | os = MachOLinkingContext::OS::iOS; | 409 | os = MachOLinkingContext::OS::iOS; |
| 411 | if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), | 410 | if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), |
| 412 | minOSVersion)) { | 411 | minOSVersion)) { |
| 413 | diagnostics << "error: malformed ios_version_min value\n"; | 412 | error("malformed ios_version_min value"); |
| 414 | return false; | 413 | return false; |
| 415 | } | 414 | } |
| 416 | break; | 415 | break; |
| ... | @@ -418,7 +417,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -418,7 +417,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 418 | os = MachOLinkingContext::OS::iOS_simulator; | 417 | os = MachOLinkingContext::OS::iOS_simulator; |
| 419 | if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), | 418 | if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), |
| 420 | minOSVersion)) { | 419 | minOSVersion)) { |
| 421 | diagnostics << "error: malformed ios_simulator_version_min value\n"; | 420 | error("malformed ios_simulator_version_min value"); |
| 422 | return false; | 421 | return false; |
| 423 | } | 422 | } |
| 424 | break; | 423 | break; |
| ... | @@ -452,14 +451,14 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -452,14 +451,14 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 452 | if (llvm::opt::Arg *imageBase = parsedArgs.getLastArg(OPT_image_base)) { | 451 | if (llvm::opt::Arg *imageBase = parsedArgs.getLastArg(OPT_image_base)) { |
| 453 | uint64_t baseAddress; | 452 | uint64_t baseAddress; |
| 454 | if (parseNumberBase16(imageBase->getValue(), baseAddress)) { | 453 | if (parseNumberBase16(imageBase->getValue(), baseAddress)) { |
| 455 | diagnostics << "error: image_base expects a hex number\n"; | 454 | error("image_base expects a hex number"); |
| 456 | return false; | 455 | return false; |
| 457 | } else if (baseAddress < ctx.pageZeroSize()) { | 456 | } else if (baseAddress < ctx.pageZeroSize()) { |
| 458 | diagnostics << "error: image_base overlaps with __PAGEZERO\n"; | 457 | error("image_base overlaps with __PAGEZERO"); |
| 459 | return false; | 458 | return false; |
| 460 | } else if (baseAddress % ctx.pageSize()) { | 459 | } else if (baseAddress % ctx.pageSize()) { |
| 461 | diagnostics << "error: image_base must be a multiple of page size (" | 460 | error("image_base must be a multiple of page size (0x" + |
| 462 | << "0x" << llvm::utohexstr(ctx.pageSize()) << ")\n"; | 461 | llvm::utohexstr(ctx.pageSize()) + ")"); |
| 463 | return false; | 462 | return false; |
| 464 | } | 463 | } |
| 465 | 464 | ||
| ... | @@ -488,13 +487,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -488,13 +487,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 488 | // Handle -compatibility_version and -current_version | 487 | // Handle -compatibility_version and -current_version |
| 489 | if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_compatibility_version)) { | 488 | if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_compatibility_version)) { |
| 490 | if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) { | 489 | if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) { |
| 491 | diagnostics | 490 | error("-compatibility_version can only be used with -dylib"); |
| 492 | << "error: -compatibility_version can only be used with -dylib\n"; | ||
| 493 | return false; | 491 | return false; |
| 494 | } | 492 | } |
| 495 | uint32_t parsedVers; | 493 | uint32_t parsedVers; |
| 496 | if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) { | 494 | if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) { |
| 497 | diagnostics << "error: -compatibility_version value is malformed\n"; | 495 | error("-compatibility_version value is malformed"); |
| 498 | return false; | 496 | return false; |
| 499 | } | 497 | } |
| 500 | ctx.setCompatibilityVersion(parsedVers); | 498 | ctx.setCompatibilityVersion(parsedVers); |
| ... | @@ -502,12 +500,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -502,12 +500,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 502 | 500 | ||
| 503 | if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_current_version)) { | 501 | if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_current_version)) { |
| 504 | if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) { | 502 | if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) { |
| 505 | diagnostics << "-current_version can only be used with -dylib\n"; | 503 | error("-current_version can only be used with -dylib"); |
| 506 | return false; | 504 | return false; |
| 507 | } | 505 | } |
| 508 | uint32_t parsedVers; | 506 | uint32_t parsedVers; |
| 509 | if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) { | 507 | if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) { |
| 510 | diagnostics << "error: -current_version value is malformed\n"; | 508 | error("-current_version value is malformed"); |
| 511 | return false; | 509 | return false; |
| 512 | } | 510 | } |
| 513 | ctx.setCurrentVersion(parsedVers); | 511 | ctx.setCurrentVersion(parsedVers); |
| ... | @@ -526,17 +524,19 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -526,17 +524,19 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 526 | alignStr += 2; | 524 | alignStr += 2; |
| 527 | unsigned long long alignValue; | 525 | unsigned long long alignValue; |
| 528 | if (llvm::getAsUnsignedInteger(alignStr, 16, alignValue)) { | 526 | if (llvm::getAsUnsignedInteger(alignStr, 16, alignValue)) { |
| 529 | diagnostics << "error: -sectalign alignment value '" | 527 | error("-sectalign alignment value '" + Twine(alignStr) + |
| 530 | << alignStr << "' not a valid number\n"; | 528 | "' not a valid number"); |
| 531 | return false; | 529 | return false; |
| 532 | } | 530 | } |
| 533 | uint16_t align = 1 << llvm::countTrailingZeros(alignValue); | 531 | uint16_t align = 1 << llvm::countTrailingZeros(alignValue); |
| 534 | if (!llvm::isPowerOf2_64(alignValue)) { | 532 | if (!llvm::isPowerOf2_64(alignValue)) { |
| 535 | diagnostics << "warning: alignment for '-sectalign " | 533 | std::string Msg; |
| 536 | << segName << " " << sectName | 534 | llvm::raw_string_ostream OS(Msg); |
| 537 | << llvm::format(" 0x%llX", alignValue) | 535 | OS << "alignment for '-sectalign " << segName << " " << sectName |
| 538 | << "' is not a power of two, using " | 536 | << llvm::format(" 0x%llX", alignValue) |
| 539 | << llvm::format("0x%08X", align) << "\n"; | 537 | << "' is not a power of two, using " << llvm::format("0x%08X", align); |
| 538 | OS.flush(); | ||
| 539 | warn(Msg); | ||
| 540 | } | 540 | } |
| 541 | ctx.addSectionAlignment(segName, sectName, align); | 541 | ctx.addSectionAlignment(segName, sectName, align); |
| 542 | } | 542 | } |
| ... | @@ -562,18 +562,14 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -562,18 +562,14 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 562 | if (parsedArgs.getLastArg(OPT_keep_private_externs)) { | 562 | if (parsedArgs.getLastArg(OPT_keep_private_externs)) { |
| 563 | ctx.setKeepPrivateExterns(true); | 563 | ctx.setKeepPrivateExterns(true); |
| 564 | if (ctx.outputMachOType() != llvm::MachO::MH_OBJECT) | 564 | if (ctx.outputMachOType() != llvm::MachO::MH_OBJECT) |
| 565 | diagnostics << "warning: -keep_private_externs only used in -r mode\n"; | 565 | warn("-keep_private_externs only used in -r mode"); |
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | // Handle -dependency_info <path> used by Xcode. | 568 | // Handle -dependency_info <path> used by Xcode. |
| 569 | if (llvm::opt::Arg *depInfo = parsedArgs.getLastArg(OPT_dependency_info)) { | 569 | if (llvm::opt::Arg *depInfo = parsedArgs.getLastArg(OPT_dependency_info)) |
| 570 | if (std::error_code ec = ctx.createDependencyFile(depInfo->getValue())) { | 570 | if (std::error_code ec = ctx.createDependencyFile(depInfo->getValue())) |
| 571 | diagnostics << "warning: " << ec.message() | 571 | warn(ec.message() + ", processing '-dependency_info " + |
| 572 | << ", processing '-dependency_info " | 572 | depInfo->getValue()); |
| 573 | << depInfo->getValue() | ||
| 574 | << "'\n"; | ||
| 575 | } | ||
| 576 | } | ||
| 577 | 573 | ||
| 578 | // In -test_file_usage mode, we'll be given an explicit list of paths that | 574 | // In -test_file_usage mode, we'll be given an explicit list of paths that |
| 579 | // exist. We'll also be expected to print out information about how we located | 575 | // exist. We'll also be expected to print out information about how we located |
| ... | @@ -639,31 +635,28 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -639,31 +635,28 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 639 | 635 | ||
| 640 | // Now that we've constructed the final set of search paths, print out those | 636 | // Now that we've constructed the final set of search paths, print out those |
| 641 | // search paths in verbose mode. | 637 | // search paths in verbose mode. |
| 642 | if (parsedArgs.getLastArg(OPT_v)) { | 638 | if (errorHandler().Verbose) { |
| 643 | diagnostics << "Library search paths:\n"; | 639 | message("Library search paths:"); |
| 644 | for (auto path : ctx.searchDirs()) { | 640 | for (auto path : ctx.searchDirs()) { |
| 645 | diagnostics << " " << path << '\n'; | 641 | message(" " + path); |
| 646 | } | 642 | } |
| 647 | diagnostics << "Framework search paths:\n"; | 643 | message("Framework search paths:"); |
| 648 | for (auto path : ctx.frameworkDirs()) { | 644 | for (auto path : ctx.frameworkDirs()) { |
| 649 | diagnostics << " " << path << '\n'; | 645 | message(" " + path); |
| 650 | } | 646 | } |
| 651 | } | 647 | } |
| 652 | 648 | ||
| 653 | // Handle -exported_symbols_list <file> | 649 | // Handle -exported_symbols_list <file> |
| 654 | for (auto expFile : parsedArgs.filtered(OPT_exported_symbols_list)) { | 650 | for (auto expFile : parsedArgs.filtered(OPT_exported_symbols_list)) { |
| 655 | if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) { | 651 | if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) { |
| 656 | diagnostics << "error: -exported_symbols_list cannot be combined " | 652 | error("-exported_symbols_list cannot be combined with " |
| 657 | << "with -unexported_symbol[s_list]\n"; | 653 | "-unexported_symbol[s_list]"); |
| 658 | return false; | 654 | return false; |
| 659 | } | 655 | } |
| 660 | ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList); | 656 | ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList); |
| 661 | if (std::error_code ec = parseExportsList(expFile->getValue(), ctx, | 657 | if (std::error_code ec = parseExportsList(expFile->getValue(), ctx)) { |
| 662 | diagnostics)) { | 658 | error(ec.message() + ", processing '-exported_symbols_list " + |
| 663 | diagnostics << "error: " << ec.message() | 659 | expFile->getValue()); |
| 664 | << ", processing '-exported_symbols_list " | ||
| 665 | << expFile->getValue() | ||
| 666 | << "'\n"; | ||
| 667 | return false; | 660 | return false; |
| 668 | } | 661 | } |
| 669 | } | 662 | } |
| ... | @@ -671,9 +664,9 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -671,9 +664,9 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 671 | // Handle -exported_symbol <symbol> | 664 | // Handle -exported_symbol <symbol> |
| 672 | for (auto symbol : parsedArgs.filtered(OPT_exported_symbol)) { | 665 | for (auto symbol : parsedArgs.filtered(OPT_exported_symbol)) { |
| 673 | if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) { | 666 | if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) { |
| 674 | diagnostics << "error: -exported_symbol cannot be combined " | 667 | error("-exported_symbol cannot be combined with " |
| 675 | << "with -unexported_symbol[s_list]\n"; | 668 | "-unexported_symbol[s_list]"); |
| 676 | return false; | 669 | return false; |
| 677 | } | 670 | } |
| 678 | ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList); | 671 | ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList); |
| 679 | ctx.addExportSymbol(symbol->getValue()); | 672 | ctx.addExportSymbol(symbol->getValue()); |
| ... | @@ -682,17 +675,14 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -682,17 +675,14 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 682 | // Handle -unexported_symbols_list <file> | 675 | // Handle -unexported_symbols_list <file> |
| 683 | for (auto expFile : parsedArgs.filtered(OPT_unexported_symbols_list)) { | 676 | for (auto expFile : parsedArgs.filtered(OPT_unexported_symbols_list)) { |
| 684 | if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) { | 677 | if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) { |
| 685 | diagnostics << "error: -unexported_symbols_list cannot be combined " | 678 | error("-unexported_symbols_list cannot be combined with " |
| 686 | << "with -exported_symbol[s_list]\n"; | 679 | "-exported_symbol[s_list]"); |
| 687 | return false; | 680 | return false; |
| 688 | } | 681 | } |
| 689 | ctx.setExportMode(MachOLinkingContext::ExportMode::blackList); | 682 | ctx.setExportMode(MachOLinkingContext::ExportMode::blackList); |
| 690 | if (std::error_code ec = parseExportsList(expFile->getValue(), ctx, | 683 | if (std::error_code ec = parseExportsList(expFile->getValue(), ctx)) { |
| 691 | diagnostics)) { | 684 | error(ec.message() + ", processing '-unexported_symbols_list " + |
| 692 | diagnostics << "error: " << ec.message() | 685 | expFile->getValue()); |
| 693 | << ", processing '-unexported_symbols_list " | ||
| 694 | << expFile->getValue() | ||
| 695 | << "'\n"; | ||
| 696 | return false; | 686 | return false; |
| 697 | } | 687 | } |
| 698 | } | 688 | } |
| ... | @@ -700,9 +690,9 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -700,9 +690,9 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 700 | // Handle -unexported_symbol <symbol> | 690 | // Handle -unexported_symbol <symbol> |
| 701 | for (auto symbol : parsedArgs.filtered(OPT_unexported_symbol)) { | 691 | for (auto symbol : parsedArgs.filtered(OPT_unexported_symbol)) { |
| 702 | if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) { | 692 | if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) { |
| 703 | diagnostics << "error: -unexported_symbol cannot be combined " | 693 | error("-unexported_symbol cannot be combined with " |
| 704 | << "with -exported_symbol[s_list]\n"; | 694 | "-exported_symbol[s_list]"); |
| 705 | return false; | 695 | return false; |
| 706 | } | 696 | } |
| 707 | ctx.setExportMode(MachOLinkingContext::ExportMode::blackList); | 697 | ctx.setExportMode(MachOLinkingContext::ExportMode::blackList); |
| 708 | ctx.addExportSymbol(symbol->getValue()); | 698 | ctx.addExportSymbol(symbol->getValue()); |
| ... | @@ -711,30 +701,26 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -711,30 +701,26 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 711 | // Handle obosolete -multi_module and -single_module | 701 | // Handle obosolete -multi_module and -single_module |
| 712 | if (llvm::opt::Arg *mod = | 702 | if (llvm::opt::Arg *mod = |
| 713 | parsedArgs.getLastArg(OPT_multi_module, OPT_single_module)) { | 703 | parsedArgs.getLastArg(OPT_multi_module, OPT_single_module)) { |
| 714 | if (mod->getOption().getID() == OPT_multi_module) { | 704 | if (mod->getOption().getID() == OPT_multi_module) |
| 715 | diagnostics << "warning: -multi_module is obsolete and being ignored\n"; | 705 | warn("-multi_module is obsolete and being ignored"); |
| 716 | } | 706 | else if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) |
| 717 | else { | 707 | warn("-single_module being ignored. It is only for use when producing a " |
| 718 | if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) { | 708 | "dylib"); |
| 719 | diagnostics << "warning: -single_module being ignored. " | ||
| 720 | "It is only for use when producing a dylib\n"; | ||
| 721 | } | ||
| 722 | } | ||
| 723 | } | 709 | } |
| 724 | 710 | ||
| 725 | // Handle obsolete ObjC options: -objc_gc_compaction, -objc_gc, -objc_gc_only | 711 | // Handle obsolete ObjC options: -objc_gc_compaction, -objc_gc, -objc_gc_only |
| 726 | if (parsedArgs.getLastArg(OPT_objc_gc_compaction)) { | 712 | if (parsedArgs.getLastArg(OPT_objc_gc_compaction)) { |
| 727 | diagnostics << "error: -objc_gc_compaction is not supported\n"; | 713 | error("-objc_gc_compaction is not supported"); |
| 728 | return false; | 714 | return false; |
| 729 | } | 715 | } |
| 730 | 716 | ||
| 731 | if (parsedArgs.getLastArg(OPT_objc_gc)) { | 717 | if (parsedArgs.getLastArg(OPT_objc_gc)) { |
| 732 | diagnostics << "error: -objc_gc is not supported\n"; | 718 | error("-objc_gc is not supported"); |
| 733 | return false; | 719 | return false; |
| 734 | } | 720 | } |
| 735 | 721 | ||
| 736 | if (parsedArgs.getLastArg(OPT_objc_gc_only)) { | 722 | if (parsedArgs.getLastArg(OPT_objc_gc_only)) { |
| 737 | diagnostics << "error: -objc_gc_only is not supported\n"; | 723 | error("-objc_gc_only is not supported"); |
| 738 | return false; | 724 | return false; |
| 739 | } | 725 | } |
| 740 | 726 | ||
| ... | @@ -746,22 +732,20 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -746,22 +732,20 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 746 | case MachOLinkingContext::OS::macOSX: | 732 | case MachOLinkingContext::OS::macOSX: |
| 747 | if ((minOSVersion < 0x000A0500) && | 733 | if ((minOSVersion < 0x000A0500) && |
| 748 | (pie->getOption().getID() == OPT_pie)) { | 734 | (pie->getOption().getID() == OPT_pie)) { |
| 749 | diagnostics << "-pie can only be used when targeting " | 735 | error("-pie can only be used when targeting Mac OS X 10.5 or later"); |
| 750 | "Mac OS X 10.5 or later\n"; | ||
| 751 | return false; | 736 | return false; |
| 752 | } | 737 | } |
| 753 | break; | 738 | break; |
| 754 | case MachOLinkingContext::OS::iOS: | 739 | case MachOLinkingContext::OS::iOS: |
| 755 | if ((minOSVersion < 0x00040200) && | 740 | if ((minOSVersion < 0x00040200) && |
| 756 | (pie->getOption().getID() == OPT_pie)) { | 741 | (pie->getOption().getID() == OPT_pie)) { |
| 757 | diagnostics << "-pie can only be used when targeting " | 742 | error("-pie can only be used when targeting iOS 4.2 or later"); |
| 758 | "iOS 4.2 or later\n"; | ||
| 759 | return false; | 743 | return false; |
| 760 | } | 744 | } |
| 761 | break; | 745 | break; |
| 762 | case MachOLinkingContext::OS::iOS_simulator: | 746 | case MachOLinkingContext::OS::iOS_simulator: |
| 763 | if (pie->getOption().getID() == OPT_no_pie) { | 747 | if (pie->getOption().getID() == OPT_no_pie) { |
| 764 | diagnostics << "iOS simulator programs must be built PIE\n"; | 748 | error("iOS simulator programs must be built PIE"); |
| 765 | return false; | 749 | return false; |
| 766 | } | 750 | } |
| 767 | break; | 751 | break; |
| ... | @@ -774,12 +758,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -774,12 +758,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 774 | break; | 758 | break; |
| 775 | case llvm::MachO::MH_DYLIB: | 759 | case llvm::MachO::MH_DYLIB: |
| 776 | case llvm::MachO::MH_BUNDLE: | 760 | case llvm::MachO::MH_BUNDLE: |
| 777 | diagnostics << "warning: " << pie->getSpelling() << " being ignored. " | 761 | warn(pie->getSpelling() + |
| 778 | << "It is only used when linking main executables\n"; | 762 | " being ignored. It is only used when linking main executables"); |
| 779 | break; | 763 | break; |
| 780 | default: | 764 | default: |
| 781 | diagnostics << pie->getSpelling() | 765 | error(pie->getSpelling() + |
| 782 | << " can only used when linking main executables\n"; | 766 | " can only used when linking main executables"); |
| 783 | return false; | 767 | return false; |
| 784 | } | 768 | } |
| 785 | } | 769 | } |
| ... | @@ -934,7 +918,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -934,7 +918,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 934 | uint32_t sdkVersion = 0; | 918 | uint32_t sdkVersion = 0; |
| 935 | if (MachOLinkingContext::parsePackedVersion(arg->getValue(), | 919 | if (MachOLinkingContext::parsePackedVersion(arg->getValue(), |
| 936 | sdkVersion)) { | 920 | sdkVersion)) { |
| 937 | diagnostics << "error: malformed sdkVersion value\n"; | 921 | error("malformed sdkVersion value"); |
| 938 | return false; | 922 | return false; |
| 939 | } | 923 | } |
| 940 | ctx.setSdkVersion(sdkVersion); | 924 | ctx.setSdkVersion(sdkVersion); |
| ... | @@ -943,9 +927,8 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -943,9 +927,8 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 943 | // with min_version, then we need to give an warning as we have no sdk | 927 | // with min_version, then we need to give an warning as we have no sdk |
| 944 | // version to put in that command. | 928 | // version to put in that command. |
| 945 | // FIXME: We need to decide whether to make this an error. | 929 | // FIXME: We need to decide whether to make this an error. |
| 946 | diagnostics << "warning: -sdk_version is required when emitting " | 930 | warn("-sdk_version is required when emitting min version load command. " |
| 947 | "min version load command. " | 931 | "Setting sdk version to match provided min version"); |
| 948 | "Setting sdk version to match provided min version\n"; | ||
| 949 | ctx.setSdkVersion(ctx.osMinVersion()); | 932 | ctx.setSdkVersion(ctx.osMinVersion()); |
| 950 | } | 933 | } |
| 951 | 934 | ||
| ... | @@ -954,7 +937,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -954,7 +937,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 954 | uint64_t version = 0; | 937 | uint64_t version = 0; |
| 955 | if (MachOLinkingContext::parsePackedVersion(arg->getValue(), | 938 | if (MachOLinkingContext::parsePackedVersion(arg->getValue(), |
| 956 | version)) { | 939 | version)) { |
| 957 | diagnostics << "error: malformed source_version value\n"; | 940 | error("malformed source_version value"); |
| 958 | return false; | 941 | return false; |
| 959 | } | 942 | } |
| 960 | ctx.setSourceVersion(version); | 943 | ctx.setSourceVersion(version); |
| ... | @@ -964,12 +947,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -964,12 +947,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 964 | if (llvm::opt::Arg *stackSize = parsedArgs.getLastArg(OPT_stack_size)) { | 947 | if (llvm::opt::Arg *stackSize = parsedArgs.getLastArg(OPT_stack_size)) { |
| 965 | uint64_t stackSizeVal; | 948 | uint64_t stackSizeVal; |
| 966 | if (parseNumberBase16(stackSize->getValue(), stackSizeVal)) { | 949 | if (parseNumberBase16(stackSize->getValue(), stackSizeVal)) { |
| 967 | diagnostics << "error: stack_size expects a hex number\n"; | 950 | error("stack_size expects a hex number"); |
| 968 | return false; | 951 | return false; |
| 969 | } | 952 | } |
| 970 | if ((stackSizeVal % ctx.pageSize()) != 0) { | 953 | if ((stackSizeVal % ctx.pageSize()) != 0) { |
| 971 | diagnostics << "error: stack_size must be a multiple of page size (" | 954 | error("stack_size must be a multiple of page size (0x" + |
| 972 | << "0x" << llvm::utohexstr(ctx.pageSize()) << ")\n"; | 955 | llvm::utohexstr(ctx.pageSize()) + ")"); |
| 973 | return false; | 956 | return false; |
| 974 | } | 957 | } |
| 975 | 958 | ||
| ... | @@ -982,12 +965,9 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -982,12 +965,9 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 982 | 965 | ||
| 983 | // Handle -order_file <file> | 966 | // Handle -order_file <file> |
| 984 | for (auto orderFile : parsedArgs.filtered(OPT_order_file)) { | 967 | for (auto orderFile : parsedArgs.filtered(OPT_order_file)) { |
| 985 | if (std::error_code ec = parseOrderFile(orderFile->getValue(), ctx, | 968 | if (std::error_code ec = parseOrderFile(orderFile->getValue(), ctx)) { |
| 986 | diagnostics)) { | 969 | error(ec.message() + ", processing '-order_file " + orderFile->getValue() |
| 987 | diagnostics << "error: " << ec.message() | 970 | + "'"); |
| 988 | << ", processing '-order_file " | ||
| 989 | << orderFile->getValue() | ||
| 990 | << "'\n"; | ||
| 991 | return false; | 971 | return false; |
| 992 | } | 972 | } |
| 993 | } | 973 | } |
| ... | @@ -1011,8 +991,8 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -1011,8 +991,8 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 1011 | else if (StringRef(undef->getValue()).equals("dynamic_lookup")) | 991 | else if (StringRef(undef->getValue()).equals("dynamic_lookup")) |
| 1012 | UndefMode = MachOLinkingContext::UndefinedMode::dynamicLookup; | 992 | UndefMode = MachOLinkingContext::UndefinedMode::dynamicLookup; |
| 1013 | else { | 993 | else { |
| 1014 | diagnostics << "error: invalid option to -undefined " | 994 | error("invalid option to -undefined [ warning | error | suppress | " |
| 1015 | "[ warning | error | suppress | dynamic_lookup ]\n"; | 995 | "dynamic_lookup ]"); |
| 1016 | return false; | 996 | return false; |
| 1017 | } | 997 | } |
| 1018 | 998 | ||
| ... | @@ -1026,8 +1006,8 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -1026,8 +1006,8 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 1026 | // illegal. Emit a diagnostic if they've been (mis)used. | 1006 | // illegal. Emit a diagnostic if they've been (mis)used. |
| 1027 | if (UndefMode == MachOLinkingContext::UndefinedMode::warning || | 1007 | if (UndefMode == MachOLinkingContext::UndefinedMode::warning || |
| 1028 | UndefMode == MachOLinkingContext::UndefinedMode::suppress) { | 1008 | UndefMode == MachOLinkingContext::UndefinedMode::suppress) { |
| 1029 | diagnostics << "error: can't use -undefined warning or suppress with " | 1009 | error("can't use -undefined warning or suppress with " |
| 1030 | "-twolevel_namespace\n"; | 1010 | "-twolevel_namespace"); |
| 1031 | return false; | 1011 | return false; |
| 1032 | } | 1012 | } |
| 1033 | } | 1013 | } |
| ... | @@ -1046,19 +1026,16 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -1046,19 +1026,16 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 1046 | case llvm::MachO::MH_DYLIB: | 1026 | case llvm::MachO::MH_DYLIB: |
| 1047 | case llvm::MachO::MH_BUNDLE: | 1027 | case llvm::MachO::MH_BUNDLE: |
| 1048 | if (!ctx.minOS("10.5", "2.0")) { | 1028 | if (!ctx.minOS("10.5", "2.0")) { |
| 1049 | if (ctx.os() == MachOLinkingContext::OS::macOSX) { | 1029 | if (ctx.os() == MachOLinkingContext::OS::macOSX) |
| 1050 | diagnostics << "error: -rpath can only be used when targeting " | 1030 | error("-rpath can only be used when targeting OS X 10.5 or later"); |
| 1051 | "OS X 10.5 or later\n"; | 1031 | else |
| 1052 | } else { | 1032 | error("-rpath can only be used when targeting iOS 2.0 or later"); |
| 1053 | diagnostics << "error: -rpath can only be used when targeting " | ||
| 1054 | "iOS 2.0 or later\n"; | ||
| 1055 | } | ||
| 1056 | return false; | 1033 | return false; |
| 1057 | } | 1034 | } |
| 1058 | break; | 1035 | break; |
| 1059 | default: | 1036 | default: |
| 1060 | diagnostics << "error: -rpath can only be used when creating " | 1037 | error("-rpath can only be used when creating a dynamic final linked " |
| 1061 | "a dynamic final linked image\n"; | 1038 | "image"); |
| 1062 | return false; | 1039 | return false; |
| 1063 | } | 1040 | } |
| 1064 | 1041 | ||
| ... | @@ -1068,7 +1045,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -1068,7 +1045,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 1068 | } | 1045 | } |
| 1069 | 1046 | ||
| 1070 | // Parse the LLVM options before we process files in case the file handling | 1047 | // Parse the LLVM options before we process files in case the file handling |
| 1071 | // makes use of things like DEBUG(). | 1048 | // makes use of things like LLVM_DEBUG(). |
| 1072 | parseLLVMOptions(ctx); | 1049 | parseLLVMOptions(ctx); |
| 1073 | 1050 | ||
| 1074 | // Handle input files and sectcreate. | 1051 | // Handle input files and sectcreate. |
| ... | @@ -1079,52 +1056,46 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -1079,52 +1056,46 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 1079 | default: | 1056 | default: |
| 1080 | continue; | 1057 | continue; |
| 1081 | case OPT_INPUT: | 1058 | case OPT_INPUT: |
| 1082 | addFile(arg->getValue(), ctx, globalWholeArchive, false, diagnostics); | 1059 | addFile(arg->getValue(), ctx, globalWholeArchive, false); |
| 1083 | break; | 1060 | break; |
| 1084 | case OPT_upward_library: | 1061 | case OPT_upward_library: |
| 1085 | addFile(arg->getValue(), ctx, false, true, diagnostics); | 1062 | addFile(arg->getValue(), ctx, false, true); |
| 1086 | break; | 1063 | break; |
| 1087 | case OPT_force_load: | 1064 | case OPT_force_load: |
| 1088 | addFile(arg->getValue(), ctx, true, false, diagnostics); | 1065 | addFile(arg->getValue(), ctx, true, false); |
| 1089 | break; | 1066 | break; |
| 1090 | case OPT_l: | 1067 | case OPT_l: |
| 1091 | case OPT_upward_l: | 1068 | case OPT_upward_l: |
| 1092 | upward = (arg->getOption().getID() == OPT_upward_l); | 1069 | upward = (arg->getOption().getID() == OPT_upward_l); |
| 1093 | resolvedPath = ctx.searchLibrary(arg->getValue()); | 1070 | resolvedPath = ctx.searchLibrary(arg->getValue()); |
| 1094 | if (!resolvedPath) { | 1071 | if (!resolvedPath) { |
| 1095 | diagnostics << "Unable to find library for " << arg->getSpelling() | 1072 | error("Unable to find library for " + arg->getSpelling() + |
| 1096 | << arg->getValue() << "\n"; | 1073 | arg->getValue()); |
| 1097 | return false; | 1074 | return false; |
| 1098 | } else if (ctx.testingFileUsage()) { | 1075 | } else if (ctx.testingFileUsage()) { |
| 1099 | diagnostics << "Found " << (upward ? "upward " : " ") << "library " | 1076 | message(Twine("Found ") + (upward ? "upward " : " ") + "library " + |
| 1100 | << canonicalizePath(resolvedPath.getValue()) << '\n'; | 1077 | canonicalizePath(resolvedPath.getValue())); |
| 1101 | } | 1078 | } |
| 1102 | addFile(resolvedPath.getValue(), ctx, globalWholeArchive, | 1079 | addFile(resolvedPath.getValue(), ctx, globalWholeArchive, upward); |
| 1103 | upward, diagnostics); | ||
| 1104 | break; | 1080 | break; |
| 1105 | case OPT_framework: | 1081 | case OPT_framework: |
| 1106 | case OPT_upward_framework: | 1082 | case OPT_upward_framework: |
| 1107 | upward = (arg->getOption().getID() == OPT_upward_framework); | 1083 | upward = (arg->getOption().getID() == OPT_upward_framework); |
| 1108 | resolvedPath = ctx.findPathForFramework(arg->getValue()); | 1084 | resolvedPath = ctx.findPathForFramework(arg->getValue()); |
| 1109 | if (!resolvedPath) { | 1085 | if (!resolvedPath) { |
| 1110 | diagnostics << "Unable to find framework for " | 1086 | error("Unable to find framework for " + arg->getSpelling() + " " + |
| 1111 | << arg->getSpelling() << " " << arg->getValue() << "\n"; | 1087 | arg->getValue()); |
| 1112 | return false; | 1088 | return false; |
| 1113 | } else if (ctx.testingFileUsage()) { | 1089 | } else if (ctx.testingFileUsage()) { |
| 1114 | diagnostics << "Found " << (upward ? "upward " : " ") << "framework " | 1090 | message(Twine("Found ") + (upward ? "upward " : " ") + "framework " + |
| 1115 | << canonicalizePath(resolvedPath.getValue()) << '\n'; | 1091 | canonicalizePath(resolvedPath.getValue())); |
| 1116 | } | 1092 | } |
| 1117 | addFile(resolvedPath.getValue(), ctx, globalWholeArchive, | 1093 | addFile(resolvedPath.getValue(), ctx, globalWholeArchive, upward); |
| 1118 | upward, diagnostics); | ||
| 1119 | break; | 1094 | break; |
| 1120 | case OPT_filelist: | 1095 | case OPT_filelist: |
| 1121 | if (auto ec = loadFileList(arg->getValue(), | 1096 | if (auto ec = loadFileList(arg->getValue(), ctx, globalWholeArchive)) { |
| 1122 | ctx, globalWholeArchive, | ||
| 1123 | diagnostics)) { | ||
| 1124 | handleAllErrors(std::move(ec), [&](const llvm::ErrorInfoBase &EI) { | 1097 | handleAllErrors(std::move(ec), [&](const llvm::ErrorInfoBase &EI) { |
| 1125 | diagnostics << "error: "; | 1098 | error(EI.message() + ", processing '-filelist " + arg->getValue()); |
| 1126 | EI.log(diagnostics); | ||
| 1127 | diagnostics << ", processing '-filelist " << arg->getValue() << "'\n"; | ||
| 1128 | }); | 1099 | }); |
| 1129 | return false; | 1100 | return false; |
| 1130 | } | 1101 | } |
| ... | @@ -1138,7 +1109,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -1138,7 +1109,7 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 1138 | MemoryBuffer::getFile(fileName); | 1109 | MemoryBuffer::getFile(fileName); |
| 1139 | 1110 | ||
| 1140 | if (!contentOrErr) { | 1111 | if (!contentOrErr) { |
| 1141 | diagnostics << "error: can't open -sectcreate file " << fileName << "\n"; | 1112 | error("can't open -sectcreate file " + Twine(fileName)); |
| 1142 | return false; | 1113 | return false; |
| 1143 | } | 1114 | } |
| 1144 | 1115 | ||
| ... | @@ -1149,12 +1120,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | ... | @@ -1149,12 +1120,12 @@ bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, |
| 1149 | } | 1120 | } |
| 1150 | 1121 | ||
| 1151 | if (ctx.getNodes().empty()) { | 1122 | if (ctx.getNodes().empty()) { |
| 1152 | diagnostics << "No input files\n"; | 1123 | error("No input files"); |
| 1153 | return false; | 1124 | return false; |
| 1154 | } | 1125 | } |
| 1155 | 1126 | ||
| 1156 | // Validate the combination of options used. | 1127 | // Validate the combination of options used. |
| 1157 | return ctx.validate(diagnostics); | 1128 | return ctx.validate(); |
| 1158 | } | 1129 | } |
| 1159 | 1130 | ||
| 1160 | static void createFiles(MachOLinkingContext &ctx, bool Implicit) { | 1131 | static void createFiles(MachOLinkingContext &ctx, bool Implicit) { |
| ... | @@ -1170,9 +1141,18 @@ static void createFiles(MachOLinkingContext &ctx, bool Implicit) { | ... | @@ -1170,9 +1141,18 @@ static void createFiles(MachOLinkingContext &ctx, bool Implicit) { |
| 1170 | } | 1141 | } |
| 1171 | 1142 | ||
| 1172 | /// This is where the link is actually performed. | 1143 | /// This is where the link is actually performed. |
| 1173 | bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) { | 1144 | bool link(llvm::ArrayRef<const char *> args, bool CanExitEarly, |
| 1145 | raw_ostream &Error) { | ||
| 1146 | errorHandler().LogName = llvm::sys::path::filename(args[0]); | ||
| 1147 | errorHandler().ErrorLimitExceededMsg = | ||
| 1148 | "too many errors emitted, stopping now (use " | ||
| 1149 | "'-error-limit 0' to see all errors)"; | ||
| 1150 | errorHandler().ErrorOS = &Error; | ||
| 1151 | errorHandler().ExitEarly = CanExitEarly; | ||
| 1152 | errorHandler().ColorDiagnostics = Error.has_colors(); | ||
| 1153 | |||
| 1174 | MachOLinkingContext ctx; | 1154 | MachOLinkingContext ctx; |
| 1175 | if (!parse(args, ctx, diagnostics)) | 1155 | if (!parse(args, ctx)) |
| 1176 | return false; | 1156 | return false; |
| 1177 | if (ctx.doNothing()) | 1157 | if (ctx.doNothing()) |
| 1178 | return true; | 1158 | return true; |
| ... | @@ -1214,9 +1194,10 @@ bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) { | ... | @@ -1214,9 +1194,10 @@ bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) { |
| 1214 | if (auto ec = pm.runOnFile(*merged)) { | 1194 | if (auto ec = pm.runOnFile(*merged)) { |
| 1215 | // FIXME: This should be passed to logAllUnhandledErrors but it needs | 1195 | // FIXME: This should be passed to logAllUnhandledErrors but it needs |
| 1216 | // to be passed a Twine instead of a string. | 1196 | // to be passed a Twine instead of a string. |
| 1217 | diagnostics << "Failed to run passes on file '" << ctx.outputPath() | 1197 | *errorHandler().ErrorOS << "Failed to run passes on file '" |
| 1218 | << "': "; | 1198 | << ctx.outputPath() << "': "; |
| 1219 | logAllUnhandledErrors(std::move(ec), diagnostics, std::string()); | 1199 | logAllUnhandledErrors(std::move(ec), *errorHandler().ErrorOS, |
| 1200 | std::string()); | ||
| 1220 | return false; | 1201 | return false; |
| 1221 | } | 1202 | } |
| 1222 | 1203 | ||
| ... | @@ -1227,11 +1208,18 @@ bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) { | ... | @@ -1227,11 +1208,18 @@ bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) { |
| 1227 | if (auto ec = ctx.writeFile(*merged)) { | 1208 | if (auto ec = ctx.writeFile(*merged)) { |
| 1228 | // FIXME: This should be passed to logAllUnhandledErrors but it needs | 1209 | // FIXME: This should be passed to logAllUnhandledErrors but it needs |
| 1229 | // to be passed a Twine instead of a string. | 1210 | // to be passed a Twine instead of a string. |
| 1230 | diagnostics << "Failed to write file '" << ctx.outputPath() << "': "; | 1211 | *errorHandler().ErrorOS << "Failed to write file '" << ctx.outputPath() |
| 1231 | logAllUnhandledErrors(std::move(ec), diagnostics, std::string()); | 1212 | << "': "; |
| 1213 | logAllUnhandledErrors(std::move(ec), *errorHandler().ErrorOS, | ||
| 1214 | std::string()); | ||
| 1232 | return false; | 1215 | return false; |
| 1233 | } | 1216 | } |
| 1234 | 1217 | ||
| 1218 | // Call exit() if we can to avoid calling destructors. | ||
| 1219 | if (CanExitEarly) | ||
| 1220 | exitLld(errorCount() ? 1 : 0); | ||
| 1221 | |||
| 1222 | |||
| 1235 | return true; | 1223 | return true; |
| 1236 | } | 1224 | } |
| 1237 | 1225 |
deps/lld/lib/Driver/DarwinLdOptions.td+8| ... | @@ -227,6 +227,14 @@ def t : Flag<["-"], "t">, | ... | @@ -227,6 +227,14 @@ def t : Flag<["-"], "t">, |
| 227 | HelpText<"Print the names of the input files as ld processes them">; | 227 | HelpText<"Print the names of the input files as ld processes them">; |
| 228 | def v : Flag<["-"], "v">, | 228 | def v : Flag<["-"], "v">, |
| 229 | HelpText<"Print linker information">; | 229 | HelpText<"Print linker information">; |
| 230 | def error_limit : Separate<["-", "--"], "error-limit">, | ||
| 231 | MetaVarName<"<number>">, | ||
| 232 | HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">; | ||
| 233 | |||
| 234 | // Ignored options | ||
| 235 | def lto_library : Separate<["-"], "lto_library">, | ||
| 236 | MetaVarName<"<path>">, | ||
| 237 | HelpText<"Ignored for compatibility with other linkers">; | ||
| 230 | 238 | ||
| 231 | // Obsolete options | 239 | // Obsolete options |
| 232 | def grp_obsolete : OptionGroup<"obsolete">, HelpText<"OBSOLETE OPTIONS">; | 240 | def grp_obsolete : OptionGroup<"obsolete">, HelpText<"OBSOLETE OPTIONS">; |
deps/lld/lib/ReaderWriter/FileArchive.cpp+3-3| ... | @@ -38,7 +38,7 @@ namespace lld { | ... | @@ -38,7 +38,7 @@ namespace lld { |
| 38 | 38 | ||
| 39 | namespace { | 39 | namespace { |
| 40 | 40 | ||
| 41 | /// \brief The FileArchive class represents an Archive Library file | 41 | /// The FileArchive class represents an Archive Library file |
| 42 | class FileArchive : public lld::ArchiveLibraryFile { | 42 | class FileArchive : public lld::ArchiveLibraryFile { |
| 43 | public: | 43 | public: |
| 44 | FileArchive(std::unique_ptr<MemoryBuffer> mb, const Registry &reg, | 44 | FileArchive(std::unique_ptr<MemoryBuffer> mb, const Registry &reg, |
| ... | @@ -46,7 +46,7 @@ public: | ... | @@ -46,7 +46,7 @@ public: |
| 46 | : ArchiveLibraryFile(path), _mb(std::shared_ptr<MemoryBuffer>(mb.release())), | 46 | : ArchiveLibraryFile(path), _mb(std::shared_ptr<MemoryBuffer>(mb.release())), |
| 47 | _registry(reg), _logLoading(logLoading) {} | 47 | _registry(reg), _logLoading(logLoading) {} |
| 48 | 48 | ||
| 49 | /// \brief Check if any member of the archive contains an Atom with the | 49 | /// Check if any member of the archive contains an Atom with the |
| 50 | /// specified name and return the File object for that member, or nullptr. | 50 | /// specified name and return the File object for that member, or nullptr. |
| 51 | File *find(StringRef name) override { | 51 | File *find(StringRef name) override { |
| 52 | auto member = _symbolMemberMap.find(name); | 52 | auto member = _symbolMemberMap.find(name); |
| ... | @@ -77,7 +77,7 @@ public: | ... | @@ -77,7 +77,7 @@ public: |
| 77 | return file; | 77 | return file; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | /// \brief parse each member | 80 | /// parse each member |
| 81 | std::error_code | 81 | std::error_code |
| 82 | parseAllMembers(std::vector<std::unique_ptr<File>> &result) override { | 82 | parseAllMembers(std::vector<std::unique_ptr<File>> &result) override { |
| 83 | if (std::error_code ec = parse()) | 83 | if (std::error_code ec = parse()) |
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp+3-2| ... | @@ -621,6 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal( | ... | @@ -621,6 +621,7 @@ void ArchHandler_x86_64::applyFixupFinal( |
| 621 | // Fall into llvm_unreachable(). | 621 | // Fall into llvm_unreachable(). |
| 622 | break; | 622 | break; |
| 623 | } | 623 | } |
| 624 | llvm_unreachable("invalid x86_64 Reference Kind"); | ||
| 624 | } | 625 | } |
| 625 | 626 | ||
| 626 | void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, | 627 | void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, |
| ... | @@ -673,7 +674,7 @@ void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, | ... | @@ -673,7 +674,7 @@ void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, |
| 673 | *loc32 = ref.addend() + inAtomAddress - fixupAddress; | 674 | *loc32 = ref.addend() + inAtomAddress - fixupAddress; |
| 674 | return; | 675 | return; |
| 675 | case delta32Anon: | 676 | case delta32Anon: |
| 676 | // The value we write here should be the the delta to the target | 677 | // The value we write here should be the delta to the target |
| 677 | // after taking in to account the difference from the fixup back to the | 678 | // after taking in to account the difference from the fixup back to the |
| 678 | // last defined label | 679 | // last defined label |
| 679 | // ie, if we have: | 680 | // ie, if we have: |
| ... | @@ -689,7 +690,7 @@ void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, | ... | @@ -689,7 +690,7 @@ void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref, |
| 689 | *loc64 = ref.addend() + inAtomAddress - fixupAddress; | 690 | *loc64 = ref.addend() + inAtomAddress - fixupAddress; |
| 690 | return; | 691 | return; |
| 691 | case delta64Anon: | 692 | case delta64Anon: |
| 692 | // The value we write here should be the the delta to the target | 693 | // The value we write here should be the delta to the target |
| 693 | // after taking in to account the difference from the fixup back to the | 694 | // after taking in to account the difference from the fixup back to the |
| 694 | // last defined label | 695 | // last defined label |
| 695 | // ie, if we have: | 696 | // ie, if we have: |
deps/lld/lib/ReaderWriter/MachO/CMakeLists.txt+1| ... | @@ -26,6 +26,7 @@ add_lld_library(lldMachO | ... | @@ -26,6 +26,7 @@ add_lld_library(lldMachO |
| 26 | Support | 26 | Support |
| 27 | 27 | ||
| 28 | LINK_LIBS | 28 | LINK_LIBS |
| 29 | lldCommon | ||
| 29 | lldCore | 30 | lldCore |
| 30 | lldYAML | 31 | lldYAML |
| 31 | ${LLVM_PTHREAD_LIB} | 32 | ${LLVM_PTHREAD_LIB} |
deps/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp+23-20| ... | @@ -282,7 +282,7 @@ public: | ... | @@ -282,7 +282,7 @@ public: |
| 282 | 282 | ||
| 283 | private: | 283 | private: |
| 284 | llvm::Error perform(SimpleFile &mergedFile) override { | 284 | llvm::Error perform(SimpleFile &mergedFile) override { |
| 285 | DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n"); | 285 | LLVM_DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n"); |
| 286 | 286 | ||
| 287 | std::map<const Atom *, CompactUnwindEntry> unwindLocs; | 287 | std::map<const Atom *, CompactUnwindEntry> unwindLocs; |
| 288 | std::map<const Atom *, const Atom *> dwarfFrames; | 288 | std::map<const Atom *, const Atom *> dwarfFrames; |
| ... | @@ -319,7 +319,7 @@ private: | ... | @@ -319,7 +319,7 @@ private: |
| 319 | 319 | ||
| 320 | // Finally, we can start creating pages based on these entries. | 320 | // Finally, we can start creating pages based on these entries. |
| 321 | 321 | ||
| 322 | DEBUG(llvm::dbgs() << " Splitting entries into pages\n"); | 322 | LLVM_DEBUG(llvm::dbgs() << " Splitting entries into pages\n"); |
| 323 | // FIXME: we split the entries into pages naively: lots of 4k pages followed | 323 | // FIXME: we split the entries into pages naively: lots of 4k pages followed |
| 324 | // by a small one. ld64 tried to minimize space and align them to real 4k | 324 | // by a small one. ld64 tried to minimize space and align them to real 4k |
| 325 | // boundaries. That might be worth doing, or perhaps we could perform some | 325 | // boundaries. That might be worth doing, or perhaps we could perform some |
| ... | @@ -336,11 +336,13 @@ private: | ... | @@ -336,11 +336,13 @@ private: |
| 336 | pages.back().entries = remainingInfos.slice(0, entriesInPage); | 336 | pages.back().entries = remainingInfos.slice(0, entriesInPage); |
| 337 | remainingInfos = remainingInfos.slice(entriesInPage); | 337 | remainingInfos = remainingInfos.slice(entriesInPage); |
| 338 | 338 | ||
| 339 | DEBUG(llvm::dbgs() | 339 | LLVM_DEBUG(llvm::dbgs() |
| 340 | << " Page from " << pages.back().entries[0].rangeStart->name() | 340 | << " Page from " |
| 341 | << " to " << pages.back().entries.back().rangeStart->name() << " + " | 341 | << pages.back().entries[0].rangeStart->name() << " to " |
| 342 | << llvm::format("0x%x", pages.back().entries.back().rangeLength) | 342 | << pages.back().entries.back().rangeStart->name() << " + " |
| 343 | << " has " << entriesInPage << " entries\n"); | 343 | << llvm::format("0x%x", |
| 344 | pages.back().entries.back().rangeLength) | ||
| 345 | << " has " << entriesInPage << " entries\n"); | ||
| 344 | } while (!remainingInfos.empty()); | 346 | } while (!remainingInfos.empty()); |
| 345 | 347 | ||
| 346 | auto *unwind = new (_file.allocator()) | 348 | auto *unwind = new (_file.allocator()) |
| ... | @@ -360,7 +362,7 @@ private: | ... | @@ -360,7 +362,7 @@ private: |
| 360 | const SimpleFile &mergedFile, | 362 | const SimpleFile &mergedFile, |
| 361 | std::map<const Atom *, CompactUnwindEntry> &unwindLocs, | 363 | std::map<const Atom *, CompactUnwindEntry> &unwindLocs, |
| 362 | std::vector<const Atom *> &personalities, uint32_t &numLSDAs) { | 364 | std::vector<const Atom *> &personalities, uint32_t &numLSDAs) { |
| 363 | DEBUG(llvm::dbgs() << " Collecting __compact_unwind entries\n"); | 365 | LLVM_DEBUG(llvm::dbgs() << " Collecting __compact_unwind entries\n"); |
| 364 | 366 | ||
| 365 | for (const DefinedAtom *atom : mergedFile.defined()) { | 367 | for (const DefinedAtom *atom : mergedFile.defined()) { |
| 366 | if (atom->contentType() != DefinedAtom::typeCompactUnwindInfo) | 368 | if (atom->contentType() != DefinedAtom::typeCompactUnwindInfo) |
| ... | @@ -369,14 +371,15 @@ private: | ... | @@ -369,14 +371,15 @@ private: |
| 369 | auto unwindEntry = extractCompactUnwindEntry(atom); | 371 | auto unwindEntry = extractCompactUnwindEntry(atom); |
| 370 | unwindLocs.insert(std::make_pair(unwindEntry.rangeStart, unwindEntry)); | 372 | unwindLocs.insert(std::make_pair(unwindEntry.rangeStart, unwindEntry)); |
| 371 | 373 | ||
| 372 | DEBUG(llvm::dbgs() << " Entry for " << unwindEntry.rangeStart->name() | 374 | LLVM_DEBUG(llvm::dbgs() << " Entry for " |
| 373 | << ", encoding=" | 375 | << unwindEntry.rangeStart->name() << ", encoding=" |
| 374 | << llvm::format("0x%08x", unwindEntry.encoding)); | 376 | << llvm::format("0x%08x", unwindEntry.encoding)); |
| 375 | if (unwindEntry.personalityFunction) | 377 | if (unwindEntry.personalityFunction) |
| 376 | DEBUG(llvm::dbgs() << ", personality=" | 378 | LLVM_DEBUG(llvm::dbgs() |
| 377 | << unwindEntry.personalityFunction->name() | 379 | << ", personality=" |
| 378 | << ", lsdaLoc=" << unwindEntry.lsdaLocation->name()); | 380 | << unwindEntry.personalityFunction->name() |
| 379 | DEBUG(llvm::dbgs() << '\n'); | 381 | << ", lsdaLoc=" << unwindEntry.lsdaLocation->name()); |
| 382 | LLVM_DEBUG(llvm::dbgs() << '\n'); | ||
| 380 | 383 | ||
| 381 | // Count number of LSDAs we see, since we need to know how big the index | 384 | // Count number of LSDAs we see, since we need to know how big the index |
| 382 | // will be while laying out the section. | 385 | // will be while laying out the section. |
| ... | @@ -454,7 +457,7 @@ private: | ... | @@ -454,7 +457,7 @@ private: |
| 454 | const std::map<const Atom *, const Atom *> &dwarfFrames) { | 457 | const std::map<const Atom *, const Atom *> &dwarfFrames) { |
| 455 | std::vector<CompactUnwindEntry> unwindInfos; | 458 | std::vector<CompactUnwindEntry> unwindInfos; |
| 456 | 459 | ||
| 457 | DEBUG(llvm::dbgs() << " Creating __unwind_info entries\n"); | 460 | LLVM_DEBUG(llvm::dbgs() << " Creating __unwind_info entries\n"); |
| 458 | // The final order in the __unwind_info section must be derived from the | 461 | // The final order in the __unwind_info section must be derived from the |
| 459 | // order of typeCode atoms, since that's how they'll be put into the object | 462 | // order of typeCode atoms, since that's how they'll be put into the object |
| 460 | // file eventually (yuck!). | 463 | // file eventually (yuck!). |
| ... | @@ -465,10 +468,10 @@ private: | ... | @@ -465,10 +468,10 @@ private: |
| 465 | unwindInfos.push_back(finalizeUnwindInfoEntryForAtom( | 468 | unwindInfos.push_back(finalizeUnwindInfoEntryForAtom( |
| 466 | atom, unwindLocs, personalities, dwarfFrames)); | 469 | atom, unwindLocs, personalities, dwarfFrames)); |
| 467 | 470 | ||
| 468 | DEBUG(llvm::dbgs() << " Entry for " << atom->name() | 471 | LLVM_DEBUG(llvm::dbgs() |
| 469 | << ", final encoding=" | 472 | << " Entry for " << atom->name() << ", final encoding=" |
| 470 | << llvm::format("0x%08x", unwindInfos.back().encoding) | 473 | << llvm::format("0x%08x", unwindInfos.back().encoding) |
| 471 | << '\n'); | 474 | << '\n'); |
| 472 | } | 475 | } |
| 473 | 476 | ||
| 474 | return unwindInfos; | 477 | return unwindInfos; |
deps/lld/lib/ReaderWriter/MachO/LayoutPass.cpp+16-15| ... | @@ -191,7 +191,7 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, | ... | @@ -191,7 +191,7 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, |
| 191 | // Sort atoms by their ordinal overrides only if they fall in the same | 191 | // Sort atoms by their ordinal overrides only if they fall in the same |
| 192 | // chain. | 192 | // chain. |
| 193 | if (leftRoot == rightRoot) { | 193 | if (leftRoot == rightRoot) { |
| 194 | DEBUG(reason = formatReason("override", lc._override, rc._override)); | 194 | LLVM_DEBUG(reason = formatReason("override", lc._override, rc._override)); |
| 195 | return lc._override < rc._override; | 195 | return lc._override < rc._override; |
| 196 | } | 196 | } |
| 197 | 197 | ||
| ... | @@ -200,8 +200,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, | ... | @@ -200,8 +200,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, |
| 200 | DefinedAtom::ContentPermissions rightPerms = rightRoot->permissions(); | 200 | DefinedAtom::ContentPermissions rightPerms = rightRoot->permissions(); |
| 201 | 201 | ||
| 202 | if (leftPerms != rightPerms) { | 202 | if (leftPerms != rightPerms) { |
| 203 | DEBUG(reason = | 203 | LLVM_DEBUG( |
| 204 | formatReason("contentPerms", (int)leftPerms, (int)rightPerms)); | 204 | reason = formatReason("contentPerms", (int)leftPerms, (int)rightPerms)); |
| 205 | return leftPerms < rightPerms; | 205 | return leftPerms < rightPerms; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| ... | @@ -210,7 +210,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, | ... | @@ -210,7 +210,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, |
| 210 | DefinedAtom::ContentType rightType = rightRoot->contentType(); | 210 | DefinedAtom::ContentType rightType = rightRoot->contentType(); |
| 211 | 211 | ||
| 212 | if (leftType != rightType) { | 212 | if (leftType != rightType) { |
| 213 | DEBUG(reason = formatReason("contentType", (int)leftType, (int)rightType)); | 213 | LLVM_DEBUG(reason = |
| 214 | formatReason("contentType", (int)leftType, (int)rightType)); | ||
| 214 | return leftType < rightType; | 215 | return leftType < rightType; |
| 215 | } | 216 | } |
| 216 | 217 | ||
| ... | @@ -226,8 +227,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, | ... | @@ -226,8 +227,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, |
| 226 | const File *rightFile = &rightRoot->file(); | 227 | const File *rightFile = &rightRoot->file(); |
| 227 | 228 | ||
| 228 | if (leftFile != rightFile) { | 229 | if (leftFile != rightFile) { |
| 229 | DEBUG(reason = formatReason(".o order", (int)leftFile->ordinal(), | 230 | LLVM_DEBUG(reason = formatReason(".o order", (int)leftFile->ordinal(), |
| 230 | (int)rightFile->ordinal())); | 231 | (int)rightFile->ordinal())); |
| 231 | return leftFile->ordinal() < rightFile->ordinal(); | 232 | return leftFile->ordinal() < rightFile->ordinal(); |
| 232 | } | 233 | } |
| 233 | 234 | ||
| ... | @@ -236,8 +237,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, | ... | @@ -236,8 +237,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, |
| 236 | uint64_t rightOrdinal = rightRoot->ordinal(); | 237 | uint64_t rightOrdinal = rightRoot->ordinal(); |
| 237 | 238 | ||
| 238 | if (leftOrdinal != rightOrdinal) { | 239 | if (leftOrdinal != rightOrdinal) { |
| 239 | DEBUG(reason = formatReason("ordinal", (int)leftRoot->ordinal(), | 240 | LLVM_DEBUG(reason = formatReason("ordinal", (int)leftRoot->ordinal(), |
| 240 | (int)rightRoot->ordinal())); | 241 | (int)rightRoot->ordinal())); |
| 241 | return leftOrdinal < rightOrdinal; | 242 | return leftOrdinal < rightOrdinal; |
| 242 | } | 243 | } |
| 243 | 244 | ||
| ... | @@ -251,7 +252,7 @@ static bool compareAtoms(const LayoutPass::SortKey &lc, | ... | @@ -251,7 +252,7 @@ static bool compareAtoms(const LayoutPass::SortKey &lc, |
| 251 | LayoutPass::SortOverride customSorter) { | 252 | LayoutPass::SortOverride customSorter) { |
| 252 | std::string reason; | 253 | std::string reason; |
| 253 | bool result = compareAtomsSub(lc, rc, customSorter, reason); | 254 | bool result = compareAtomsSub(lc, rc, customSorter, reason); |
| 254 | DEBUG({ | 255 | LLVM_DEBUG({ |
| 255 | StringRef comp = result ? "<" : ">="; | 256 | StringRef comp = result ? "<" : ">="; |
| 256 | llvm::dbgs() << "Layout: '" << lc._atom.get()->name() | 257 | llvm::dbgs() << "Layout: '" << lc._atom.get()->name() |
| 257 | << "' " << comp << " '" | 258 | << "' " << comp << " '" |
| ... | @@ -441,7 +442,7 @@ void LayoutPass::undecorate(File::AtomRange<DefinedAtom> &atomRange, | ... | @@ -441,7 +442,7 @@ void LayoutPass::undecorate(File::AtomRange<DefinedAtom> &atomRange, |
| 441 | 442 | ||
| 442 | /// Perform the actual pass | 443 | /// Perform the actual pass |
| 443 | llvm::Error LayoutPass::perform(SimpleFile &mergedFile) { | 444 | llvm::Error LayoutPass::perform(SimpleFile &mergedFile) { |
| 444 | DEBUG(llvm::dbgs() << "******** Laying out atoms:\n"); | 445 | LLVM_DEBUG(llvm::dbgs() << "******** Laying out atoms:\n"); |
| 445 | // sort the atoms | 446 | // sort the atoms |
| 446 | ScopedTask task(getDefaultDomain(), "LayoutPass"); | 447 | ScopedTask task(getDefaultDomain(), "LayoutPass"); |
| 447 | File::AtomRange<DefinedAtom> atomRange = mergedFile.defined(); | 448 | File::AtomRange<DefinedAtom> atomRange = mergedFile.defined(); |
| ... | @@ -450,12 +451,12 @@ llvm::Error LayoutPass::perform(SimpleFile &mergedFile) { | ... | @@ -450,12 +451,12 @@ llvm::Error LayoutPass::perform(SimpleFile &mergedFile) { |
| 450 | buildFollowOnTable(atomRange); | 451 | buildFollowOnTable(atomRange); |
| 451 | 452 | ||
| 452 | // Check the structure of followon graph if running in debug mode. | 453 | // Check the structure of followon graph if running in debug mode. |
| 453 | DEBUG(checkFollowonChain(atomRange)); | 454 | LLVM_DEBUG(checkFollowonChain(atomRange)); |
| 454 | 455 | ||
| 455 | // Build override maps | 456 | // Build override maps |
| 456 | buildOrdinalOverrideMap(atomRange); | 457 | buildOrdinalOverrideMap(atomRange); |
| 457 | 458 | ||
| 458 | DEBUG({ | 459 | LLVM_DEBUG({ |
| 459 | llvm::dbgs() << "unsorted atoms:\n"; | 460 | llvm::dbgs() << "unsorted atoms:\n"; |
| 460 | printDefinedAtoms(atomRange); | 461 | printDefinedAtoms(atomRange); |
| 461 | }); | 462 | }); |
| ... | @@ -465,15 +466,15 @@ llvm::Error LayoutPass::perform(SimpleFile &mergedFile) { | ... | @@ -465,15 +466,15 @@ llvm::Error LayoutPass::perform(SimpleFile &mergedFile) { |
| 465 | [&](const LayoutPass::SortKey &l, const LayoutPass::SortKey &r) -> bool { | 466 | [&](const LayoutPass::SortKey &l, const LayoutPass::SortKey &r) -> bool { |
| 466 | return compareAtoms(l, r, _customSorter); | 467 | return compareAtoms(l, r, _customSorter); |
| 467 | }); | 468 | }); |
| 468 | DEBUG(checkTransitivity(vec, _customSorter)); | 469 | LLVM_DEBUG(checkTransitivity(vec, _customSorter)); |
| 469 | undecorate(atomRange, vec); | 470 | undecorate(atomRange, vec); |
| 470 | 471 | ||
| 471 | DEBUG({ | 472 | LLVM_DEBUG({ |
| 472 | llvm::dbgs() << "sorted atoms:\n"; | 473 | llvm::dbgs() << "sorted atoms:\n"; |
| 473 | printDefinedAtoms(atomRange); | 474 | printDefinedAtoms(atomRange); |
| 474 | }); | 475 | }); |
| 475 | 476 | ||
| 476 | DEBUG(llvm::dbgs() << "******** Finished laying out atoms\n"); | 477 | LLVM_DEBUG(llvm::dbgs() << "******** Finished laying out atoms\n"); |
| 477 | return llvm::Error::success(); | 478 | return llvm::Error::success(); |
| 478 | } | 479 | } |
| 479 | 480 |
deps/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp+6-8| ... | @@ -7,6 +7,7 @@ | ... | @@ -7,6 +7,7 @@ |
| 7 | // | 7 | // |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | ||
| 10 | #include "lld/Common/ErrorHandler.h" | ||
| 10 | #include "lld/ReaderWriter/MachOLinkingContext.h" | 11 | #include "lld/ReaderWriter/MachOLinkingContext.h" |
| 11 | #include "ArchHandler.h" | 12 | #include "ArchHandler.h" |
| 12 | #include "File.h" | 13 | #include "File.h" |
| ... | @@ -579,29 +580,26 @@ MachOLinkingContext::findPathForFramework(StringRef fwName) const{ | ... | @@ -579,29 +580,26 @@ MachOLinkingContext::findPathForFramework(StringRef fwName) const{ |
| 579 | return llvm::None; | 580 | return llvm::None; |
| 580 | } | 581 | } |
| 581 | 582 | ||
| 582 | bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) { | 583 | bool MachOLinkingContext::validateImpl() { |
| 583 | // TODO: if -arch not specified, look at arch of first .o file. | 584 | // TODO: if -arch not specified, look at arch of first .o file. |
| 584 | 585 | ||
| 585 | if (_currentVersion && _outputMachOType != MH_DYLIB) { | 586 | if (_currentVersion && _outputMachOType != MH_DYLIB) { |
| 586 | diagnostics << "error: -current_version can only be used with dylibs\n"; | 587 | error("-current_version can only be used with dylibs"); |
| 587 | return false; | 588 | return false; |
| 588 | } | 589 | } |
| 589 | 590 | ||
| 590 | if (_compatibilityVersion && _outputMachOType != MH_DYLIB) { | 591 | if (_compatibilityVersion && _outputMachOType != MH_DYLIB) { |
| 591 | diagnostics | 592 | error("-compatibility_version can only be used with dylibs"); |
| 592 | << "error: -compatibility_version can only be used with dylibs\n"; | ||
| 593 | return false; | 593 | return false; |
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) { | 596 | if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) { |
| 597 | diagnostics | 597 | error("-mark_dead_strippable_dylib can only be used with dylibs"); |
| 598 | << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n"; | ||
| 599 | return false; | 598 | return false; |
| 600 | } | 599 | } |
| 601 | 600 | ||
| 602 | if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) { | 601 | if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) { |
| 603 | diagnostics | 602 | error("-bundle_loader can only be used with Mach-O bundles"); |
| 604 | << "error: -bundle_loader can only be used with Mach-O bundles\n"; | ||
| 605 | return false; | 603 | return false; |
| 606 | } | 604 | } |
| 607 | 605 |
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp+3-3| ... | @@ -906,7 +906,7 @@ readCompUnit(const NormalizedFile &normalizedFile, | ... | @@ -906,7 +906,7 @@ readCompUnit(const NormalizedFile &normalizedFile, |
| 906 | abbrevData.getU8(&abbrevOffset); | 906 | abbrevData.getU8(&abbrevOffset); |
| 907 | uint32_t name; | 907 | uint32_t name; |
| 908 | llvm::dwarf::Form form; | 908 | llvm::dwarf::Form form; |
| 909 | llvm::DWARFFormParams formParams = {version, addrSize, Format}; | 909 | llvm::dwarf::FormParams formParams = {version, addrSize, Format}; |
| 910 | TranslationUnitSource tu; | 910 | TranslationUnitSource tu; |
| 911 | while ((name = abbrevData.getULEB128(&abbrevOffset)) | | 911 | while ((name = abbrevData.getULEB128(&abbrevOffset)) | |
| 912 | (form = static_cast<llvm::dwarf::Form>( | 912 | (form = static_cast<llvm::dwarf::Form>( |
| ... | @@ -1431,8 +1431,8 @@ llvm::Error | ... | @@ -1431,8 +1431,8 @@ llvm::Error |
| 1431 | normalizedObjectToAtoms(MachOFile *file, | 1431 | normalizedObjectToAtoms(MachOFile *file, |
| 1432 | const NormalizedFile &normalizedFile, | 1432 | const NormalizedFile &normalizedFile, |
| 1433 | bool copyRefs) { | 1433 | bool copyRefs) { |
| 1434 | DEBUG(llvm::dbgs() << "******** Normalizing file to atoms: " | 1434 | LLVM_DEBUG(llvm::dbgs() << "******** Normalizing file to atoms: " |
| 1435 | << file->path() << "\n"); | 1435 | << file->path() << "\n"); |
| 1436 | bool scatterable = ((normalizedFile.flags & MH_SUBSECTIONS_VIA_SYMBOLS) != 0); | 1436 | bool scatterable = ((normalizedFile.flags & MH_SUBSECTIONS_VIA_SYMBOLS) != 0); |
| 1437 | 1437 | ||
| 1438 | // Create atoms from each section. | 1438 | // Create atoms from each section. |
deps/lld/test/CMakeLists.txt+9-3| ... | @@ -32,9 +32,9 @@ configure_lit_site_cfg( | ... | @@ -32,9 +32,9 @@ configure_lit_site_cfg( |
| 32 | set(LLD_TEST_DEPS lld) | 32 | set(LLD_TEST_DEPS lld) |
| 33 | if (NOT LLD_BUILT_STANDALONE) | 33 | if (NOT LLD_BUILT_STANDALONE) |
| 34 | list(APPEND LLD_TEST_DEPS | 34 | list(APPEND LLD_TEST_DEPS |
| 35 | FileCheck count not llvm-ar llvm-as llvm-dis llvm-dwarfdump llvm-nm | 35 | FileCheck count llc llvm-ar llvm-as llvm-bcanalyzer llvm-config llvm-dis |
| 36 | llc llvm-config llvm-objdump llvm-readelf llvm-readobj yaml2obj obj2yaml | 36 | llvm-dwarfdump llvm-lib llvm-mc llvm-nm llvm-objcopy llvm-objdump |
| 37 | llvm-mc llvm-lib llvm-pdbutil opt | 37 | llvm-pdbutil llvm-readelf llvm-readobj not obj2yaml opt yaml2obj |
| 38 | ) | 38 | ) |
| 39 | endif() | 39 | endif() |
| 40 | 40 | ||
| ... | @@ -53,6 +53,12 @@ add_lit_testsuite(check-lld "Running lld test suite" | ... | @@ -53,6 +53,12 @@ add_lit_testsuite(check-lld "Running lld test suite" |
| 53 | DEPENDS ${LLD_TEST_DEPS} | 53 | DEPENDS ${LLD_TEST_DEPS} |
| 54 | ) | 54 | ) |
| 55 | 55 | ||
| 56 | add_lit_testsuites(LLD ${CMAKE_CURRENT_SOURCE_DIR} | ||
| 57 | PARAMS lld_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg | ||
| 58 | lld_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg | ||
| 59 | DEPENDS ${LLD_TEST_DEPS} | ||
| 60 | ) | ||
| 61 | |||
| 56 | set_target_properties(check-lld PROPERTIES FOLDER "lld tests") | 62 | set_target_properties(check-lld PROPERTIES FOLDER "lld tests") |
| 57 | 63 | ||
| 58 | # Add a legacy target spelling: lld-test | 64 | # Add a legacy target spelling: lld-test |
deps/lld/test/COFF/Inputs/far-arm64-abs.s created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | .global too_far26 | ||
| 2 | .global too_far19 | ||
| 3 | .global too_far14 | ||
| 4 | too_far26 = 0x08011000 | ||
| 5 | too_far19 = 0x00111000 | ||
| 6 | too_far14 = 0x00021000 | ||
deps/lld/test/COFF/Inputs/generic.yaml created+282| ... | @@ -0,0 +1,282 @@ | ||
| 1 | --- !COFF | ||
| 2 | header: | ||
| 3 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 4 | Characteristics: [ ] | ||
| 5 | sections: | ||
| 6 | - Name: .text | ||
| 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 8 | Alignment: 16 | ||
| 9 | SectionData: 4883EC1831C0C7442414000000004889542408894C24044883C418C3 | ||
| 10 | - Name: .data | ||
| 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 12 | Alignment: 4 | ||
| 13 | SectionData: '' | ||
| 14 | - Name: .bss | ||
| 15 | Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 16 | Alignment: 4 | ||
| 17 | SectionData: '' | ||
| 18 | - Name: .xdata | ||
| 19 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 20 | Alignment: 4 | ||
| 21 | SectionData: '0104010004220000' | ||
| 22 | - Name: .drectve | ||
| 23 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | ||
| 24 | Alignment: 1 | ||
| 25 | SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 | ||
| 26 | - Name: '.debug$S' | ||
| 27 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 28 | Alignment: 4 | ||
| 29 | SectionData: 04000000F10000002F0000002D003C1101000000D0000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F1000000760000002A0047110000000000000000000000001C000000000000000000000003100000000000000000006D61696E000D003E117400000001006172676300120045114F0100000400000017000000000005000D003E110010000001006172677600120045114F01000008000000170000000000050002004F110000F20000002800000000000000000000001C00000000000000020000001C00000000000000020000001700000003000000F40000001800000001000000100139E9A066A1995A99DD01F5A392F26D7C0000F30000003000000000443A5C7372635C6C6C766D6275696C645C636C5C52656C656173655C7836345C67656E657269632E63707000000000 | ||
| 30 | Subsections: | ||
| 31 | - !Symbols | ||
| 32 | Records: | ||
| 33 | - Kind: S_COMPILE3 | ||
| 34 | Compile3Sym: | ||
| 35 | Flags: [ ] | ||
| 36 | Machine: X64 | ||
| 37 | FrontendMajor: 7 | ||
| 38 | FrontendMinor: 0 | ||
| 39 | FrontendBuild: 0 | ||
| 40 | FrontendQFE: 0 | ||
| 41 | BackendMajor: 7000 | ||
| 42 | BackendMinor: 0 | ||
| 43 | BackendBuild: 0 | ||
| 44 | BackendQFE: 0 | ||
| 45 | Version: 'clang version 7.0.0 ' | ||
| 46 | - !Symbols | ||
| 47 | Records: | ||
| 48 | - Kind: S_GPROC32_ID | ||
| 49 | ProcSym: | ||
| 50 | CodeSize: 28 | ||
| 51 | DbgStart: 0 | ||
| 52 | DbgEnd: 0 | ||
| 53 | FunctionType: 4099 | ||
| 54 | Flags: [ ] | ||
| 55 | DisplayName: main | ||
| 56 | - Kind: S_LOCAL | ||
| 57 | LocalSym: | ||
| 58 | Type: 116 | ||
| 59 | Flags: [ IsParameter ] | ||
| 60 | VarName: argc | ||
| 61 | - Kind: S_DEFRANGE_REGISTER_REL | ||
| 62 | DefRangeRegisterRelSym: | ||
| 63 | Register: 335 | ||
| 64 | Flags: 0 | ||
| 65 | BasePointerOffset: 4 | ||
| 66 | Range: | ||
| 67 | OffsetStart: 23 | ||
| 68 | ISectStart: 0 | ||
| 69 | Range: 5 | ||
| 70 | Gaps: | ||
| 71 | - Kind: S_LOCAL | ||
| 72 | LocalSym: | ||
| 73 | Type: 4096 | ||
| 74 | Flags: [ IsParameter ] | ||
| 75 | VarName: argv | ||
| 76 | - Kind: S_DEFRANGE_REGISTER_REL | ||
| 77 | DefRangeRegisterRelSym: | ||
| 78 | Register: 335 | ||
| 79 | Flags: 0 | ||
| 80 | BasePointerOffset: 8 | ||
| 81 | Range: | ||
| 82 | OffsetStart: 23 | ||
| 83 | ISectStart: 0 | ||
| 84 | Range: 5 | ||
| 85 | Gaps: | ||
| 86 | - Kind: S_PROC_ID_END | ||
| 87 | ScopeEndSym: | ||
| 88 | - !Lines | ||
| 89 | CodeSize: 28 | ||
| 90 | Flags: [ ] | ||
| 91 | RelocOffset: 0 | ||
| 92 | RelocSegment: 0 | ||
| 93 | Blocks: | ||
| 94 | - FileName: 'D:\src\llvmbuild\cl\Release\x64\generic.cpp' | ||
| 95 | Lines: | ||
| 96 | - Offset: 0 | ||
| 97 | LineStart: 2 | ||
| 98 | IsStatement: false | ||
| 99 | EndDelta: 0 | ||
| 100 | - Offset: 23 | ||
| 101 | LineStart: 3 | ||
| 102 | IsStatement: false | ||
| 103 | EndDelta: 0 | ||
| 104 | Columns: | ||
| 105 | - !FileChecksums | ||
| 106 | Checksums: | ||
| 107 | - FileName: 'D:\src\llvmbuild\cl\Release\x64\generic.cpp' | ||
| 108 | Kind: MD5 | ||
| 109 | Checksum: 39E9A066A1995A99DD01F5A392F26D7C | ||
| 110 | - !StringTable | ||
| 111 | Strings: | ||
| 112 | - 'D:\src\llvmbuild\cl\Release\x64\generic.cpp' | ||
| 113 | - '' | ||
| 114 | - '' | ||
| 115 | - '' | ||
| 116 | Relocations: | ||
| 117 | - VirtualAddress: 100 | ||
| 118 | SymbolName: main | ||
| 119 | Type: IMAGE_REL_AMD64_SECREL | ||
| 120 | - VirtualAddress: 104 | ||
| 121 | SymbolName: main | ||
| 122 | Type: IMAGE_REL_AMD64_SECTION | ||
| 123 | - VirtualAddress: 139 | ||
| 124 | SymbolName: .text | ||
| 125 | Type: IMAGE_REL_AMD64_SECREL | ||
| 126 | - VirtualAddress: 143 | ||
| 127 | SymbolName: .text | ||
| 128 | Type: IMAGE_REL_AMD64_SECTION | ||
| 129 | - VirtualAddress: 174 | ||
| 130 | SymbolName: .text | ||
| 131 | Type: IMAGE_REL_AMD64_SECREL | ||
| 132 | - VirtualAddress: 178 | ||
| 133 | SymbolName: .text | ||
| 134 | Type: IMAGE_REL_AMD64_SECTION | ||
| 135 | - VirtualAddress: 196 | ||
| 136 | SymbolName: main | ||
| 137 | Type: IMAGE_REL_AMD64_SECREL | ||
| 138 | - VirtualAddress: 200 | ||
| 139 | SymbolName: main | ||
| 140 | Type: IMAGE_REL_AMD64_SECTION | ||
| 141 | - Name: '.debug$T' | ||
| 142 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 143 | Alignment: 4 | ||
| 144 | SectionData: 040000000A000210700600000C0001000E0001120200000074000000001000000E0008107400000000000200011000001200011600000000021000006D61696E00F3F2F1 | ||
| 145 | Types: | ||
| 146 | - Kind: LF_POINTER | ||
| 147 | Pointer: | ||
| 148 | ReferentType: 1648 | ||
| 149 | Attrs: 65548 | ||
| 150 | - Kind: LF_ARGLIST | ||
| 151 | ArgList: | ||
| 152 | ArgIndices: [ 116, 4096 ] | ||
| 153 | - Kind: LF_PROCEDURE | ||
| 154 | Procedure: | ||
| 155 | ReturnType: 116 | ||
| 156 | CallConv: NearC | ||
| 157 | Options: [ None ] | ||
| 158 | ParameterCount: 2 | ||
| 159 | ArgumentList: 4097 | ||
| 160 | - Kind: LF_FUNC_ID | ||
| 161 | FuncId: | ||
| 162 | ParentScope: 0 | ||
| 163 | FunctionType: 4098 | ||
| 164 | Name: main | ||
| 165 | - Name: .pdata | ||
| 166 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 167 | Alignment: 4 | ||
| 168 | SectionData: 000000001C00000000000000 | ||
| 169 | Relocations: | ||
| 170 | - VirtualAddress: 0 | ||
| 171 | SymbolName: main | ||
| 172 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 173 | - VirtualAddress: 4 | ||
| 174 | SymbolName: main | ||
| 175 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 176 | - VirtualAddress: 8 | ||
| 177 | SymbolName: .xdata | ||
| 178 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 179 | symbols: | ||
| 180 | - Name: .text | ||
| 181 | Value: 0 | ||
| 182 | SectionNumber: 1 | ||
| 183 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 184 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 185 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 186 | SectionDefinition: | ||
| 187 | Length: 28 | ||
| 188 | NumberOfRelocations: 0 | ||
| 189 | NumberOfLinenumbers: 0 | ||
| 190 | CheckSum: 594448369 | ||
| 191 | Number: 1 | ||
| 192 | - Name: .data | ||
| 193 | Value: 0 | ||
| 194 | SectionNumber: 2 | ||
| 195 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 196 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 197 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 198 | SectionDefinition: | ||
| 199 | Length: 0 | ||
| 200 | NumberOfRelocations: 0 | ||
| 201 | NumberOfLinenumbers: 0 | ||
| 202 | CheckSum: 0 | ||
| 203 | Number: 2 | ||
| 204 | - Name: .bss | ||
| 205 | Value: 0 | ||
| 206 | SectionNumber: 3 | ||
| 207 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 208 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 209 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 210 | SectionDefinition: | ||
| 211 | Length: 0 | ||
| 212 | NumberOfRelocations: 0 | ||
| 213 | NumberOfLinenumbers: 0 | ||
| 214 | CheckSum: 0 | ||
| 215 | Number: 3 | ||
| 216 | - Name: .xdata | ||
| 217 | Value: 0 | ||
| 218 | SectionNumber: 4 | ||
| 219 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 220 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 221 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 222 | SectionDefinition: | ||
| 223 | Length: 8 | ||
| 224 | NumberOfRelocations: 0 | ||
| 225 | NumberOfLinenumbers: 0 | ||
| 226 | CheckSum: 1192424177 | ||
| 227 | Number: 4 | ||
| 228 | - Name: .drectve | ||
| 229 | Value: 0 | ||
| 230 | SectionNumber: 5 | ||
| 231 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 232 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 233 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 234 | SectionDefinition: | ||
| 235 | Length: 48 | ||
| 236 | NumberOfRelocations: 0 | ||
| 237 | NumberOfLinenumbers: 0 | ||
| 238 | CheckSum: 149686238 | ||
| 239 | Number: 5 | ||
| 240 | - Name: '.debug$S' | ||
| 241 | Value: 0 | ||
| 242 | SectionNumber: 6 | ||
| 243 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 244 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 245 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 246 | SectionDefinition: | ||
| 247 | Length: 324 | ||
| 248 | NumberOfRelocations: 8 | ||
| 249 | NumberOfLinenumbers: 0 | ||
| 250 | CheckSum: 4196717433 | ||
| 251 | Number: 6 | ||
| 252 | - Name: '.debug$T' | ||
| 253 | Value: 0 | ||
| 254 | SectionNumber: 7 | ||
| 255 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 256 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 257 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 258 | SectionDefinition: | ||
| 259 | Length: 68 | ||
| 260 | NumberOfRelocations: 0 | ||
| 261 | NumberOfLinenumbers: 0 | ||
| 262 | CheckSum: 485351071 | ||
| 263 | Number: 7 | ||
| 264 | - Name: .pdata | ||
| 265 | Value: 0 | ||
| 266 | SectionNumber: 8 | ||
| 267 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 268 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 269 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 270 | SectionDefinition: | ||
| 271 | Length: 12 | ||
| 272 | NumberOfRelocations: 3 | ||
| 273 | NumberOfLinenumbers: 0 | ||
| 274 | CheckSum: 722740324 | ||
| 275 | Number: 8 | ||
| 276 | - Name: main | ||
| 277 | Value: 0 | ||
| 278 | SectionNumber: 1 | ||
| 279 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 280 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 281 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 282 | ... | ||
deps/lld/test/COFF/Inputs/globals-dia-func-collision3.obj created| Binary files /dev/null and b/deps/lld/test/COFF/Inputs/globals-dia-func-collision3.obj differ | |||
deps/lld/test/COFF/Inputs/globals-dia-vfunc-collision.obj created| Binary files /dev/null and b/deps/lld/test/COFF/Inputs/globals-dia-vfunc-collision.obj differ | |||
deps/lld/test/COFF/Inputs/globals-dia-vfunc-collision2.obj created| Binary files /dev/null and b/deps/lld/test/COFF/Inputs/globals-dia-vfunc-collision2.obj differ | |||
deps/lld/test/COFF/Inputs/globals-dia-vfunc-simple.obj created| Binary files /dev/null and b/deps/lld/test/COFF/Inputs/globals-dia-vfunc-simple.obj differ | |||
deps/lld/test/COFF/Inputs/guardcf-align-foobar.yaml created+51| ... | @@ -0,0 +1,51 @@ | ||
| 1 | --- !COFF | ||
| 2 | header: | ||
| 3 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 4 | Characteristics: [ ] | ||
| 5 | sections: | ||
| 6 | - Name: .text.foo | ||
| 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 8 | Alignment: 1 | ||
| 9 | SectionData: 31C0C3 | ||
| 10 | - Name: .text.bar | ||
| 11 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 12 | Alignment: 1 | ||
| 13 | SectionData: FFE1 | ||
| 14 | symbols: | ||
| 15 | - Name: .text.foo | ||
| 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: 3 | ||
| 23 | NumberOfRelocations: 0 | ||
| 24 | NumberOfLinenumbers: 0 | ||
| 25 | CheckSum: 3963538403 | ||
| 26 | Number: 1 | ||
| 27 | - Name: .text.bar | ||
| 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: 2 | ||
| 35 | NumberOfRelocations: 0 | ||
| 36 | NumberOfLinenumbers: 0 | ||
| 37 | CheckSum: 1143549852 | ||
| 38 | Number: 2 | ||
| 39 | - Name: foo | ||
| 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: bar | ||
| 46 | Value: 0 | ||
| 47 | SectionNumber: 2 | ||
| 48 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 49 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 50 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 51 | ... | ||
deps/lld/test/COFF/Inputs/loadconfig-cfg-x64.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # This is the _load_config_used definition needed for /guard:cf tests. | ||
| 2 | |||
| 3 | .section .rdata,"dr" | ||
| 4 | .globl _load_config_used | ||
| 5 | _load_config_used: | ||
| 6 | .long 256 | ||
| 7 | .fill 124, 1, 0 | ||
| 8 | .quad __guard_fids_table | ||
| 9 | .quad __guard_fids_count | ||
| 10 | .long __guard_flags | ||
| 11 | .fill 128, 1, 0 | ||
deps/lld/test/COFF/Inputs/natvis-1.natvis created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | 1st Natvis Test | ||
deps/lld/test/COFF/Inputs/natvis-2.natvis created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | Second Natvis Test | ||
deps/lld/test/COFF/Inputs/natvis-3.natvis created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | Third Natvis Test | ||
deps/lld/test/COFF/Inputs/order.yaml created+76| ... | @@ -0,0 +1,76 @@ | ||
| 1 | --- !COFF | ||
| 2 | header: | ||
| 3 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 4 | Characteristics: [ ] | ||
| 5 | sections: | ||
| 6 | - Name: .text | ||
| 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 8 | Alignment: 16 | ||
| 9 | SectionData: C3 | ||
| 10 | - Name: .text | ||
| 11 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 12 | Alignment: 16 | ||
| 13 | SectionData: C3 | ||
| 14 | - Name: .text | ||
| 15 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 16 | Alignment: 16 | ||
| 17 | SectionData: C3 | ||
| 18 | symbols: | ||
| 19 | - Name: .text | ||
| 20 | Value: 0 | ||
| 21 | SectionNumber: 1 | ||
| 22 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 23 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 24 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 25 | SectionDefinition: | ||
| 26 | Length: 1 | ||
| 27 | NumberOfRelocations: 0 | ||
| 28 | NumberOfLinenumbers: 0 | ||
| 29 | CheckSum: 0 | ||
| 30 | Number: 1 | ||
| 31 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 32 | - Name: unrelated2 | ||
| 33 | Value: 0 | ||
| 34 | SectionNumber: 1 | ||
| 35 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 36 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 37 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 38 | - Name: .text | ||
| 39 | Value: 0 | ||
| 40 | SectionNumber: 2 | ||
| 41 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 42 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 43 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 44 | SectionDefinition: | ||
| 45 | Length: 2 | ||
| 46 | NumberOfRelocations: 0 | ||
| 47 | NumberOfLinenumbers: 0 | ||
| 48 | CheckSum: 0 | ||
| 49 | Number: 1 | ||
| 50 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 51 | - Name: fn4 | ||
| 52 | Value: 0 | ||
| 53 | SectionNumber: 2 | ||
| 54 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 55 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 56 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 57 | - Name: .text | ||
| 58 | Value: 0 | ||
| 59 | SectionNumber: 3 | ||
| 60 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 61 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 62 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 63 | SectionDefinition: | ||
| 64 | Length: 1 | ||
| 65 | NumberOfRelocations: 0 | ||
| 66 | NumberOfLinenumbers: 0 | ||
| 67 | CheckSum: 0 | ||
| 68 | Number: 3 | ||
| 69 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 70 | - Name: fn1 | ||
| 71 | Value: 0 | ||
| 72 | SectionNumber: 3 | ||
| 73 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 74 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 75 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 76 | ... | ||
deps/lld/test/COFF/Inputs/otherFunc.s created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | .global otherFunc | ||
| 2 | .global MessageBoxA | ||
| 3 | .text | ||
| 4 | otherFunc: | ||
| 5 | ret | ||
| 6 | MessageBoxA: | ||
| 7 | ret | ||
deps/lld/test/COFF/Inputs/pdb-file-statics-a.yaml created+1866| ... | @@ -0,0 +1,1866 @@ | ||
| 1 | --- !COFF | ||
| 2 | header: | ||
| 3 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 4 | Characteristics: [ ] | ||
| 5 | sections: | ||
| 6 | - Name: .drectve | ||
| 7 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | ||
| 8 | Alignment: 1 | ||
| 9 | SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220 | ||
| 10 | - Name: '.debug$S' | ||
| 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 12 | Alignment: 1 | ||
| 13 | Subsections: | ||
| 14 | - !Symbols | ||
| 15 | Records: | ||
| 16 | - Kind: S_OBJNAME | ||
| 17 | ObjNameSym: | ||
| 18 | Signature: 0 | ||
| 19 | ObjectName: 'D:\src\llvmbuild\cl\Debug\x64\a.obj' | ||
| 20 | - Kind: S_COMPILE3 | ||
| 21 | Compile3Sym: | ||
| 22 | Flags: [ SecurityChecks, HotPatch ] | ||
| 23 | Machine: X64 | ||
| 24 | FrontendMajor: 19 | ||
| 25 | FrontendMinor: 11 | ||
| 26 | FrontendBuild: 25547 | ||
| 27 | FrontendQFE: 0 | ||
| 28 | BackendMajor: 19 | ||
| 29 | BackendMinor: 11 | ||
| 30 | BackendBuild: 25547 | ||
| 31 | BackendQFE: 0 | ||
| 32 | Version: 'Microsoft (R) Optimizing Compiler' | ||
| 33 | - !Symbols | ||
| 34 | Records: | ||
| 35 | - Kind: S_LDATA32 | ||
| 36 | DataSym: | ||
| 37 | Type: 116 | ||
| 38 | DisplayName: x | ||
| 39 | - Kind: S_UDT | ||
| 40 | UDTSym: | ||
| 41 | Type: 4193 | ||
| 42 | UDTName: '__vc_attributes::event_sourceAttribute' | ||
| 43 | - Kind: S_UDT | ||
| 44 | UDTSym: | ||
| 45 | Type: 4185 | ||
| 46 | UDTName: '__vc_attributes::event_sourceAttribute::optimize_e' | ||
| 47 | - Kind: S_UDT | ||
| 48 | UDTSym: | ||
| 49 | Type: 4182 | ||
| 50 | UDTName: '__vc_attributes::event_sourceAttribute::type_e' | ||
| 51 | - Kind: S_UDT | ||
| 52 | UDTSym: | ||
| 53 | Type: 4178 | ||
| 54 | UDTName: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | ||
| 55 | - Kind: S_UDT | ||
| 56 | UDTSym: | ||
| 57 | Type: 4172 | ||
| 58 | UDTName: '__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e' | ||
| 59 | - Kind: S_UDT | ||
| 60 | UDTSym: | ||
| 61 | Type: 4168 | ||
| 62 | UDTName: '__vc_attributes::helper_attributes::usageAttribute' | ||
| 63 | - Kind: S_UDT | ||
| 64 | UDTSym: | ||
| 65 | Type: 4162 | ||
| 66 | UDTName: '__vc_attributes::helper_attributes::usageAttribute::usage_e' | ||
| 67 | - Kind: S_UDT | ||
| 68 | UDTSym: | ||
| 69 | Type: 4158 | ||
| 70 | UDTName: '__vc_attributes::threadingAttribute' | ||
| 71 | - Kind: S_UDT | ||
| 72 | UDTSym: | ||
| 73 | Type: 4150 | ||
| 74 | UDTName: '__vc_attributes::threadingAttribute::threading_e' | ||
| 75 | - Kind: S_UDT | ||
| 76 | UDTSym: | ||
| 77 | Type: 4146 | ||
| 78 | UDTName: '__vc_attributes::aggregatableAttribute' | ||
| 79 | - Kind: S_UDT | ||
| 80 | UDTSym: | ||
| 81 | Type: 4138 | ||
| 82 | UDTName: '__vc_attributes::aggregatableAttribute::type_e' | ||
| 83 | - Kind: S_UDT | ||
| 84 | UDTSym: | ||
| 85 | Type: 4134 | ||
| 86 | UDTName: '__vc_attributes::event_receiverAttribute' | ||
| 87 | - Kind: S_UDT | ||
| 88 | UDTSym: | ||
| 89 | Type: 4124 | ||
| 90 | UDTName: '__vc_attributes::event_receiverAttribute::type_e' | ||
| 91 | - Kind: S_UDT | ||
| 92 | UDTSym: | ||
| 93 | Type: 4120 | ||
| 94 | UDTName: '__vc_attributes::moduleAttribute' | ||
| 95 | - Kind: S_UDT | ||
| 96 | UDTSym: | ||
| 97 | Type: 4106 | ||
| 98 | UDTName: '__vc_attributes::moduleAttribute::type_e' | ||
| 99 | - !FileChecksums | ||
| 100 | Checksums: | ||
| 101 | - FileName: 'd:\src\llvmbuild\cl\debug\x64\a.cpp' | ||
| 102 | Kind: MD5 | ||
| 103 | Checksum: 70DD90BF2C1A2E8D7C450DFA55E3062D | ||
| 104 | - !InlineeLines | ||
| 105 | HasExtraFiles: false | ||
| 106 | Sites: | ||
| 107 | - FileName: 'd:\src\llvmbuild\cl\debug\x64\a.cpp' | ||
| 108 | LineNum: 8 | ||
| 109 | Inlinee: 4099 | ||
| 110 | - !StringTable | ||
| 111 | Strings: | ||
| 112 | - 'd:\src\llvmbuild\cl\debug\x64\a.cpp' | ||
| 113 | - 'D:\src\llvmbuild\cl\Debug\x64\a.obj' | ||
| 114 | - !Symbols | ||
| 115 | Records: | ||
| 116 | - Kind: S_BUILDINFO | ||
| 117 | BuildInfoSym: | ||
| 118 | BuildId: 4203 | ||
| 119 | Relocations: | ||
| 120 | - VirtualAddress: 132 | ||
| 121 | SymbolName: '?x@@3HA' | ||
| 122 | Type: IMAGE_REL_AMD64_SECREL | ||
| 123 | - VirtualAddress: 136 | ||
| 124 | SymbolName: '?x@@3HA' | ||
| 125 | Type: IMAGE_REL_AMD64_SECTION | ||
| 126 | - Name: '.debug$T' | ||
| 127 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 128 | Alignment: 1 | ||
| 129 | Types: | ||
| 130 | - Kind: LF_ARGLIST | ||
| 131 | ArgList: | ||
| 132 | ArgIndices: [ 116 ] | ||
| 133 | - Kind: LF_PROCEDURE | ||
| 134 | Procedure: | ||
| 135 | ReturnType: 3 | ||
| 136 | CallConv: NearC | ||
| 137 | Options: [ None ] | ||
| 138 | ParameterCount: 1 | ||
| 139 | ArgumentList: 4096 | ||
| 140 | - Kind: LF_POINTER | ||
| 141 | Pointer: | ||
| 142 | ReferentType: 1648 | ||
| 143 | Attrs: 65548 | ||
| 144 | - Kind: LF_FUNC_ID | ||
| 145 | FuncId: | ||
| 146 | ParentScope: 0 | ||
| 147 | FunctionType: 4097 | ||
| 148 | Name: a | ||
| 149 | - Kind: LF_ARGLIST | ||
| 150 | ArgList: | ||
| 151 | ArgIndices: [ 116, 4098 ] | ||
| 152 | - Kind: LF_PROCEDURE | ||
| 153 | Procedure: | ||
| 154 | ReturnType: 116 | ||
| 155 | CallConv: NearC | ||
| 156 | Options: [ None ] | ||
| 157 | ParameterCount: 2 | ||
| 158 | ArgumentList: 4100 | ||
| 159 | - Kind: LF_FUNC_ID | ||
| 160 | FuncId: | ||
| 161 | ParentScope: 0 | ||
| 162 | FunctionType: 4101 | ||
| 163 | Name: main | ||
| 164 | - Kind: LF_FUNC_ID | ||
| 165 | FuncId: | ||
| 166 | ParentScope: 0 | ||
| 167 | FunctionType: 4097 | ||
| 168 | Name: b | ||
| 169 | - Kind: LF_STRUCTURE | ||
| 170 | Class: | ||
| 171 | MemberCount: 0 | ||
| 172 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 173 | FieldList: 0 | ||
| 174 | Name: '__vc_attributes::moduleAttribute' | ||
| 175 | UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' | ||
| 176 | DerivationList: 0 | ||
| 177 | VTableShape: 0 | ||
| 178 | Size: 0 | ||
| 179 | - Kind: LF_FIELDLIST | ||
| 180 | FieldList: | ||
| 181 | - Kind: LF_ENUMERATE | ||
| 182 | Enumerator: | ||
| 183 | Attrs: 3 | ||
| 184 | Value: 1 | ||
| 185 | Name: dll | ||
| 186 | - Kind: LF_ENUMERATE | ||
| 187 | Enumerator: | ||
| 188 | Attrs: 3 | ||
| 189 | Value: 2 | ||
| 190 | Name: exe | ||
| 191 | - Kind: LF_ENUMERATE | ||
| 192 | Enumerator: | ||
| 193 | Attrs: 3 | ||
| 194 | Value: 3 | ||
| 195 | Name: service | ||
| 196 | - Kind: LF_ENUMERATE | ||
| 197 | Enumerator: | ||
| 198 | Attrs: 3 | ||
| 199 | Value: 4 | ||
| 200 | Name: unspecified | ||
| 201 | - Kind: LF_ENUMERATE | ||
| 202 | Enumerator: | ||
| 203 | Attrs: 3 | ||
| 204 | Value: 2 | ||
| 205 | Name: EXE | ||
| 206 | - Kind: LF_ENUMERATE | ||
| 207 | Enumerator: | ||
| 208 | Attrs: 3 | ||
| 209 | Value: 3 | ||
| 210 | Name: SERVICE | ||
| 211 | - Kind: LF_ENUM | ||
| 212 | Enum: | ||
| 213 | NumEnumerators: 6 | ||
| 214 | Options: [ None, Nested, HasUniqueName ] | ||
| 215 | FieldList: 4105 | ||
| 216 | Name: '__vc_attributes::moduleAttribute::type_e' | ||
| 217 | UniqueName: '.?AW4type_e@moduleAttribute@__vc_attributes@@' | ||
| 218 | UnderlyingType: 116 | ||
| 219 | - Kind: LF_STRING_ID | ||
| 220 | StringId: | ||
| 221 | Id: 0 | ||
| 222 | String: 'd:\src\llvmbuild\cl\debug\x64\predefined c++ attributes (compiler internal)' | ||
| 223 | - Kind: LF_UDT_SRC_LINE | ||
| 224 | UdtSourceLine: | ||
| 225 | UDT: 4106 | ||
| 226 | SourceFile: 4107 | ||
| 227 | LineNumber: 482 | ||
| 228 | - Kind: LF_MODIFIER | ||
| 229 | Modifier: | ||
| 230 | ModifiedType: 112 | ||
| 231 | Modifiers: [ None, Const ] | ||
| 232 | - Kind: LF_POINTER | ||
| 233 | Pointer: | ||
| 234 | ReferentType: 4109 | ||
| 235 | Attrs: 65548 | ||
| 236 | - Kind: LF_ARGLIST | ||
| 237 | ArgList: | ||
| 238 | ArgIndices: [ 4106, 4110, 4110, 4110, 116, 48, 4110, 116, | ||
| 239 | 4110, 4110, 116, 48, 48, 4110, 4110 ] | ||
| 240 | - Kind: LF_POINTER | ||
| 241 | Pointer: | ||
| 242 | ReferentType: 4104 | ||
| 243 | Attrs: 66572 | ||
| 244 | - Kind: LF_MFUNCTION | ||
| 245 | MemberFunction: | ||
| 246 | ReturnType: 3 | ||
| 247 | ClassType: 4104 | ||
| 248 | ThisType: 4112 | ||
| 249 | CallConv: NearC | ||
| 250 | Options: [ None, Constructor ] | ||
| 251 | ParameterCount: 15 | ||
| 252 | ArgumentList: 4111 | ||
| 253 | ThisPointerAdjustment: 0 | ||
| 254 | - Kind: LF_ARGLIST | ||
| 255 | ArgList: | ||
| 256 | ArgIndices: [ 4106 ] | ||
| 257 | - Kind: LF_MFUNCTION | ||
| 258 | MemberFunction: | ||
| 259 | ReturnType: 3 | ||
| 260 | ClassType: 4104 | ||
| 261 | ThisType: 4112 | ||
| 262 | CallConv: NearC | ||
| 263 | Options: [ None, Constructor ] | ||
| 264 | ParameterCount: 1 | ||
| 265 | ArgumentList: 4114 | ||
| 266 | ThisPointerAdjustment: 0 | ||
| 267 | - Kind: LF_ARGLIST | ||
| 268 | ArgList: | ||
| 269 | ArgIndices: [ ] | ||
| 270 | - Kind: LF_MFUNCTION | ||
| 271 | MemberFunction: | ||
| 272 | ReturnType: 3 | ||
| 273 | ClassType: 4104 | ||
| 274 | ThisType: 4112 | ||
| 275 | CallConv: NearC | ||
| 276 | Options: [ None, Constructor ] | ||
| 277 | ParameterCount: 0 | ||
| 278 | ArgumentList: 4116 | ||
| 279 | ThisPointerAdjustment: 0 | ||
| 280 | - Kind: LF_METHODLIST | ||
| 281 | MethodOverloadList: | ||
| 282 | Methods: | ||
| 283 | - Type: 4113 | ||
| 284 | Attrs: 3 | ||
| 285 | VFTableOffset: -1 | ||
| 286 | Name: '' | ||
| 287 | - Type: 4115 | ||
| 288 | Attrs: 3 | ||
| 289 | VFTableOffset: -1 | ||
| 290 | Name: '' | ||
| 291 | - Type: 4117 | ||
| 292 | Attrs: 3 | ||
| 293 | VFTableOffset: -1 | ||
| 294 | Name: '' | ||
| 295 | - Kind: LF_FIELDLIST | ||
| 296 | FieldList: | ||
| 297 | - Kind: LF_NESTTYPE | ||
| 298 | NestedType: | ||
| 299 | Type: 4106 | ||
| 300 | Name: type_e | ||
| 301 | - Kind: LF_METHOD | ||
| 302 | OverloadedMethod: | ||
| 303 | NumOverloads: 3 | ||
| 304 | MethodList: 4118 | ||
| 305 | Name: moduleAttribute | ||
| 306 | - Kind: LF_MEMBER | ||
| 307 | DataMember: | ||
| 308 | Attrs: 3 | ||
| 309 | Type: 4106 | ||
| 310 | FieldOffset: 0 | ||
| 311 | Name: type | ||
| 312 | - Kind: LF_MEMBER | ||
| 313 | DataMember: | ||
| 314 | Attrs: 3 | ||
| 315 | Type: 4110 | ||
| 316 | FieldOffset: 8 | ||
| 317 | Name: name | ||
| 318 | - Kind: LF_MEMBER | ||
| 319 | DataMember: | ||
| 320 | Attrs: 3 | ||
| 321 | Type: 4110 | ||
| 322 | FieldOffset: 16 | ||
| 323 | Name: version | ||
| 324 | - Kind: LF_MEMBER | ||
| 325 | DataMember: | ||
| 326 | Attrs: 3 | ||
| 327 | Type: 4110 | ||
| 328 | FieldOffset: 24 | ||
| 329 | Name: uuid | ||
| 330 | - Kind: LF_MEMBER | ||
| 331 | DataMember: | ||
| 332 | Attrs: 3 | ||
| 333 | Type: 116 | ||
| 334 | FieldOffset: 32 | ||
| 335 | Name: lcid | ||
| 336 | - Kind: LF_MEMBER | ||
| 337 | DataMember: | ||
| 338 | Attrs: 3 | ||
| 339 | Type: 48 | ||
| 340 | FieldOffset: 36 | ||
| 341 | Name: control | ||
| 342 | - Kind: LF_MEMBER | ||
| 343 | DataMember: | ||
| 344 | Attrs: 3 | ||
| 345 | Type: 4110 | ||
| 346 | FieldOffset: 40 | ||
| 347 | Name: helpstring | ||
| 348 | - Kind: LF_MEMBER | ||
| 349 | DataMember: | ||
| 350 | Attrs: 3 | ||
| 351 | Type: 116 | ||
| 352 | FieldOffset: 48 | ||
| 353 | Name: helpstringcontext | ||
| 354 | - Kind: LF_MEMBER | ||
| 355 | DataMember: | ||
| 356 | Attrs: 3 | ||
| 357 | Type: 4110 | ||
| 358 | FieldOffset: 56 | ||
| 359 | Name: helpstringdll | ||
| 360 | - Kind: LF_MEMBER | ||
| 361 | DataMember: | ||
| 362 | Attrs: 3 | ||
| 363 | Type: 4110 | ||
| 364 | FieldOffset: 64 | ||
| 365 | Name: helpfile | ||
| 366 | - Kind: LF_MEMBER | ||
| 367 | DataMember: | ||
| 368 | Attrs: 3 | ||
| 369 | Type: 116 | ||
| 370 | FieldOffset: 72 | ||
| 371 | Name: helpcontext | ||
| 372 | - Kind: LF_MEMBER | ||
| 373 | DataMember: | ||
| 374 | Attrs: 3 | ||
| 375 | Type: 48 | ||
| 376 | FieldOffset: 76 | ||
| 377 | Name: hidden | ||
| 378 | - Kind: LF_MEMBER | ||
| 379 | DataMember: | ||
| 380 | Attrs: 3 | ||
| 381 | Type: 48 | ||
| 382 | FieldOffset: 77 | ||
| 383 | Name: restricted | ||
| 384 | - Kind: LF_MEMBER | ||
| 385 | DataMember: | ||
| 386 | Attrs: 3 | ||
| 387 | Type: 4110 | ||
| 388 | FieldOffset: 80 | ||
| 389 | Name: custom | ||
| 390 | - Kind: LF_MEMBER | ||
| 391 | DataMember: | ||
| 392 | Attrs: 3 | ||
| 393 | Type: 4110 | ||
| 394 | FieldOffset: 88 | ||
| 395 | Name: resource_name | ||
| 396 | - Kind: LF_STRUCTURE | ||
| 397 | Class: | ||
| 398 | MemberCount: 19 | ||
| 399 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 400 | FieldList: 4119 | ||
| 401 | Name: '__vc_attributes::moduleAttribute' | ||
| 402 | UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' | ||
| 403 | DerivationList: 0 | ||
| 404 | VTableShape: 0 | ||
| 405 | Size: 96 | ||
| 406 | - Kind: LF_UDT_SRC_LINE | ||
| 407 | UdtSourceLine: | ||
| 408 | UDT: 4120 | ||
| 409 | SourceFile: 4107 | ||
| 410 | LineNumber: 481 | ||
| 411 | - Kind: LF_STRUCTURE | ||
| 412 | Class: | ||
| 413 | MemberCount: 0 | ||
| 414 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 415 | FieldList: 0 | ||
| 416 | Name: '__vc_attributes::event_receiverAttribute' | ||
| 417 | UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' | ||
| 418 | DerivationList: 0 | ||
| 419 | VTableShape: 0 | ||
| 420 | Size: 0 | ||
| 421 | - Kind: LF_FIELDLIST | ||
| 422 | FieldList: | ||
| 423 | - Kind: LF_ENUMERATE | ||
| 424 | Enumerator: | ||
| 425 | Attrs: 3 | ||
| 426 | Value: 0 | ||
| 427 | Name: native | ||
| 428 | - Kind: LF_ENUMERATE | ||
| 429 | Enumerator: | ||
| 430 | Attrs: 3 | ||
| 431 | Value: 1 | ||
| 432 | Name: com | ||
| 433 | - Kind: LF_ENUMERATE | ||
| 434 | Enumerator: | ||
| 435 | Attrs: 3 | ||
| 436 | Value: 2 | ||
| 437 | Name: managed | ||
| 438 | - Kind: LF_ENUM | ||
| 439 | Enum: | ||
| 440 | NumEnumerators: 3 | ||
| 441 | Options: [ None, Nested, HasUniqueName ] | ||
| 442 | FieldList: 4123 | ||
| 443 | Name: '__vc_attributes::event_receiverAttribute::type_e' | ||
| 444 | UniqueName: '.?AW4type_e@event_receiverAttribute@__vc_attributes@@' | ||
| 445 | UnderlyingType: 116 | ||
| 446 | - Kind: LF_UDT_SRC_LINE | ||
| 447 | UdtSourceLine: | ||
| 448 | UDT: 4124 | ||
| 449 | SourceFile: 4107 | ||
| 450 | LineNumber: 136 | ||
| 451 | - Kind: LF_ARGLIST | ||
| 452 | ArgList: | ||
| 453 | ArgIndices: [ 4124, 48 ] | ||
| 454 | - Kind: LF_POINTER | ||
| 455 | Pointer: | ||
| 456 | ReferentType: 4122 | ||
| 457 | Attrs: 66572 | ||
| 458 | - Kind: LF_MFUNCTION | ||
| 459 | MemberFunction: | ||
| 460 | ReturnType: 3 | ||
| 461 | ClassType: 4122 | ||
| 462 | ThisType: 4127 | ||
| 463 | CallConv: NearC | ||
| 464 | Options: [ None, Constructor ] | ||
| 465 | ParameterCount: 2 | ||
| 466 | ArgumentList: 4126 | ||
| 467 | ThisPointerAdjustment: 0 | ||
| 468 | - Kind: LF_ARGLIST | ||
| 469 | ArgList: | ||
| 470 | ArgIndices: [ 4124 ] | ||
| 471 | - Kind: LF_MFUNCTION | ||
| 472 | MemberFunction: | ||
| 473 | ReturnType: 3 | ||
| 474 | ClassType: 4122 | ||
| 475 | ThisType: 4127 | ||
| 476 | CallConv: NearC | ||
| 477 | Options: [ None, Constructor ] | ||
| 478 | ParameterCount: 1 | ||
| 479 | ArgumentList: 4129 | ||
| 480 | ThisPointerAdjustment: 0 | ||
| 481 | - Kind: LF_MFUNCTION | ||
| 482 | MemberFunction: | ||
| 483 | ReturnType: 3 | ||
| 484 | ClassType: 4122 | ||
| 485 | ThisType: 4127 | ||
| 486 | CallConv: NearC | ||
| 487 | Options: [ None, Constructor ] | ||
| 488 | ParameterCount: 0 | ||
| 489 | ArgumentList: 4116 | ||
| 490 | ThisPointerAdjustment: 0 | ||
| 491 | - Kind: LF_METHODLIST | ||
| 492 | MethodOverloadList: | ||
| 493 | Methods: | ||
| 494 | - Type: 4128 | ||
| 495 | Attrs: 3 | ||
| 496 | VFTableOffset: -1 | ||
| 497 | Name: '' | ||
| 498 | - Type: 4130 | ||
| 499 | Attrs: 3 | ||
| 500 | VFTableOffset: -1 | ||
| 501 | Name: '' | ||
| 502 | - Type: 4131 | ||
| 503 | Attrs: 3 | ||
| 504 | VFTableOffset: -1 | ||
| 505 | Name: '' | ||
| 506 | - Kind: LF_FIELDLIST | ||
| 507 | FieldList: | ||
| 508 | - Kind: LF_NESTTYPE | ||
| 509 | NestedType: | ||
| 510 | Type: 4124 | ||
| 511 | Name: type_e | ||
| 512 | - Kind: LF_METHOD | ||
| 513 | OverloadedMethod: | ||
| 514 | NumOverloads: 3 | ||
| 515 | MethodList: 4132 | ||
| 516 | Name: event_receiverAttribute | ||
| 517 | - Kind: LF_MEMBER | ||
| 518 | DataMember: | ||
| 519 | Attrs: 3 | ||
| 520 | Type: 4124 | ||
| 521 | FieldOffset: 0 | ||
| 522 | Name: type | ||
| 523 | - Kind: LF_MEMBER | ||
| 524 | DataMember: | ||
| 525 | Attrs: 3 | ||
| 526 | Type: 48 | ||
| 527 | FieldOffset: 4 | ||
| 528 | Name: layout_dependent | ||
| 529 | - Kind: LF_STRUCTURE | ||
| 530 | Class: | ||
| 531 | MemberCount: 6 | ||
| 532 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 533 | FieldList: 4133 | ||
| 534 | Name: '__vc_attributes::event_receiverAttribute' | ||
| 535 | UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' | ||
| 536 | DerivationList: 0 | ||
| 537 | VTableShape: 0 | ||
| 538 | Size: 8 | ||
| 539 | - Kind: LF_UDT_SRC_LINE | ||
| 540 | UdtSourceLine: | ||
| 541 | UDT: 4134 | ||
| 542 | SourceFile: 4107 | ||
| 543 | LineNumber: 135 | ||
| 544 | - Kind: LF_STRUCTURE | ||
| 545 | Class: | ||
| 546 | MemberCount: 0 | ||
| 547 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 548 | FieldList: 0 | ||
| 549 | Name: '__vc_attributes::aggregatableAttribute' | ||
| 550 | UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' | ||
| 551 | DerivationList: 0 | ||
| 552 | VTableShape: 0 | ||
| 553 | Size: 0 | ||
| 554 | - Kind: LF_FIELDLIST | ||
| 555 | FieldList: | ||
| 556 | - Kind: LF_ENUMERATE | ||
| 557 | Enumerator: | ||
| 558 | Attrs: 3 | ||
| 559 | Value: 0 | ||
| 560 | Name: never | ||
| 561 | - Kind: LF_ENUMERATE | ||
| 562 | Enumerator: | ||
| 563 | Attrs: 3 | ||
| 564 | Value: 1 | ||
| 565 | Name: allowed | ||
| 566 | - Kind: LF_ENUMERATE | ||
| 567 | Enumerator: | ||
| 568 | Attrs: 3 | ||
| 569 | Value: 2 | ||
| 570 | Name: always | ||
| 571 | - Kind: LF_ENUM | ||
| 572 | Enum: | ||
| 573 | NumEnumerators: 3 | ||
| 574 | Options: [ None, Nested, HasUniqueName ] | ||
| 575 | FieldList: 4137 | ||
| 576 | Name: '__vc_attributes::aggregatableAttribute::type_e' | ||
| 577 | UniqueName: '.?AW4type_e@aggregatableAttribute@__vc_attributes@@' | ||
| 578 | UnderlyingType: 116 | ||
| 579 | - Kind: LF_UDT_SRC_LINE | ||
| 580 | UdtSourceLine: | ||
| 581 | UDT: 4138 | ||
| 582 | SourceFile: 4107 | ||
| 583 | LineNumber: 545 | ||
| 584 | - Kind: LF_ARGLIST | ||
| 585 | ArgList: | ||
| 586 | ArgIndices: [ 4138 ] | ||
| 587 | - Kind: LF_POINTER | ||
| 588 | Pointer: | ||
| 589 | ReferentType: 4136 | ||
| 590 | Attrs: 66572 | ||
| 591 | - Kind: LF_MFUNCTION | ||
| 592 | MemberFunction: | ||
| 593 | ReturnType: 3 | ||
| 594 | ClassType: 4136 | ||
| 595 | ThisType: 4141 | ||
| 596 | CallConv: NearC | ||
| 597 | Options: [ None, Constructor ] | ||
| 598 | ParameterCount: 1 | ||
| 599 | ArgumentList: 4140 | ||
| 600 | ThisPointerAdjustment: 0 | ||
| 601 | - Kind: LF_MFUNCTION | ||
| 602 | MemberFunction: | ||
| 603 | ReturnType: 3 | ||
| 604 | ClassType: 4136 | ||
| 605 | ThisType: 4141 | ||
| 606 | CallConv: NearC | ||
| 607 | Options: [ None, Constructor ] | ||
| 608 | ParameterCount: 0 | ||
| 609 | ArgumentList: 4116 | ||
| 610 | ThisPointerAdjustment: 0 | ||
| 611 | - Kind: LF_METHODLIST | ||
| 612 | MethodOverloadList: | ||
| 613 | Methods: | ||
| 614 | - Type: 4142 | ||
| 615 | Attrs: 3 | ||
| 616 | VFTableOffset: -1 | ||
| 617 | Name: '' | ||
| 618 | - Type: 4143 | ||
| 619 | Attrs: 3 | ||
| 620 | VFTableOffset: -1 | ||
| 621 | Name: '' | ||
| 622 | - Kind: LF_FIELDLIST | ||
| 623 | FieldList: | ||
| 624 | - Kind: LF_NESTTYPE | ||
| 625 | NestedType: | ||
| 626 | Type: 4138 | ||
| 627 | Name: type_e | ||
| 628 | - Kind: LF_METHOD | ||
| 629 | OverloadedMethod: | ||
| 630 | NumOverloads: 2 | ||
| 631 | MethodList: 4144 | ||
| 632 | Name: aggregatableAttribute | ||
| 633 | - Kind: LF_MEMBER | ||
| 634 | DataMember: | ||
| 635 | Attrs: 3 | ||
| 636 | Type: 4138 | ||
| 637 | FieldOffset: 0 | ||
| 638 | Name: type | ||
| 639 | - Kind: LF_STRUCTURE | ||
| 640 | Class: | ||
| 641 | MemberCount: 4 | ||
| 642 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 643 | FieldList: 4145 | ||
| 644 | Name: '__vc_attributes::aggregatableAttribute' | ||
| 645 | UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' | ||
| 646 | DerivationList: 0 | ||
| 647 | VTableShape: 0 | ||
| 648 | Size: 4 | ||
| 649 | - Kind: LF_UDT_SRC_LINE | ||
| 650 | UdtSourceLine: | ||
| 651 | UDT: 4146 | ||
| 652 | SourceFile: 4107 | ||
| 653 | LineNumber: 544 | ||
| 654 | - Kind: LF_STRUCTURE | ||
| 655 | Class: | ||
| 656 | MemberCount: 0 | ||
| 657 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 658 | FieldList: 0 | ||
| 659 | Name: '__vc_attributes::threadingAttribute' | ||
| 660 | UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' | ||
| 661 | DerivationList: 0 | ||
| 662 | VTableShape: 0 | ||
| 663 | Size: 0 | ||
| 664 | - Kind: LF_FIELDLIST | ||
| 665 | FieldList: | ||
| 666 | - Kind: LF_ENUMERATE | ||
| 667 | Enumerator: | ||
| 668 | Attrs: 3 | ||
| 669 | Value: 1 | ||
| 670 | Name: apartment | ||
| 671 | - Kind: LF_ENUMERATE | ||
| 672 | Enumerator: | ||
| 673 | Attrs: 3 | ||
| 674 | Value: 2 | ||
| 675 | Name: single | ||
| 676 | - Kind: LF_ENUMERATE | ||
| 677 | Enumerator: | ||
| 678 | Attrs: 3 | ||
| 679 | Value: 3 | ||
| 680 | Name: free | ||
| 681 | - Kind: LF_ENUMERATE | ||
| 682 | Enumerator: | ||
| 683 | Attrs: 3 | ||
| 684 | Value: 4 | ||
| 685 | Name: neutral | ||
| 686 | - Kind: LF_ENUMERATE | ||
| 687 | Enumerator: | ||
| 688 | Attrs: 3 | ||
| 689 | Value: 5 | ||
| 690 | Name: both | ||
| 691 | - Kind: LF_ENUM | ||
| 692 | Enum: | ||
| 693 | NumEnumerators: 5 | ||
| 694 | Options: [ None, Nested, HasUniqueName ] | ||
| 695 | FieldList: 4149 | ||
| 696 | Name: '__vc_attributes::threadingAttribute::threading_e' | ||
| 697 | UniqueName: '.?AW4threading_e@threadingAttribute@__vc_attributes@@' | ||
| 698 | UnderlyingType: 116 | ||
| 699 | - Kind: LF_UDT_SRC_LINE | ||
| 700 | UdtSourceLine: | ||
| 701 | UDT: 4150 | ||
| 702 | SourceFile: 4107 | ||
| 703 | LineNumber: 423 | ||
| 704 | - Kind: LF_ARGLIST | ||
| 705 | ArgList: | ||
| 706 | ArgIndices: [ 4150 ] | ||
| 707 | - Kind: LF_POINTER | ||
| 708 | Pointer: | ||
| 709 | ReferentType: 4148 | ||
| 710 | Attrs: 66572 | ||
| 711 | - Kind: LF_MFUNCTION | ||
| 712 | MemberFunction: | ||
| 713 | ReturnType: 3 | ||
| 714 | ClassType: 4148 | ||
| 715 | ThisType: 4153 | ||
| 716 | CallConv: NearC | ||
| 717 | Options: [ None, Constructor ] | ||
| 718 | ParameterCount: 1 | ||
| 719 | ArgumentList: 4152 | ||
| 720 | ThisPointerAdjustment: 0 | ||
| 721 | - Kind: LF_MFUNCTION | ||
| 722 | MemberFunction: | ||
| 723 | ReturnType: 3 | ||
| 724 | ClassType: 4148 | ||
| 725 | ThisType: 4153 | ||
| 726 | CallConv: NearC | ||
| 727 | Options: [ None, Constructor ] | ||
| 728 | ParameterCount: 0 | ||
| 729 | ArgumentList: 4116 | ||
| 730 | ThisPointerAdjustment: 0 | ||
| 731 | - Kind: LF_METHODLIST | ||
| 732 | MethodOverloadList: | ||
| 733 | Methods: | ||
| 734 | - Type: 4154 | ||
| 735 | Attrs: 3 | ||
| 736 | VFTableOffset: -1 | ||
| 737 | Name: '' | ||
| 738 | - Type: 4155 | ||
| 739 | Attrs: 3 | ||
| 740 | VFTableOffset: -1 | ||
| 741 | Name: '' | ||
| 742 | - Kind: LF_FIELDLIST | ||
| 743 | FieldList: | ||
| 744 | - Kind: LF_NESTTYPE | ||
| 745 | NestedType: | ||
| 746 | Type: 4150 | ||
| 747 | Name: threading_e | ||
| 748 | - Kind: LF_METHOD | ||
| 749 | OverloadedMethod: | ||
| 750 | NumOverloads: 2 | ||
| 751 | MethodList: 4156 | ||
| 752 | Name: threadingAttribute | ||
| 753 | - Kind: LF_MEMBER | ||
| 754 | DataMember: | ||
| 755 | Attrs: 3 | ||
| 756 | Type: 4150 | ||
| 757 | FieldOffset: 0 | ||
| 758 | Name: value | ||
| 759 | - Kind: LF_STRUCTURE | ||
| 760 | Class: | ||
| 761 | MemberCount: 4 | ||
| 762 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 763 | FieldList: 4157 | ||
| 764 | Name: '__vc_attributes::threadingAttribute' | ||
| 765 | UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' | ||
| 766 | DerivationList: 0 | ||
| 767 | VTableShape: 0 | ||
| 768 | Size: 4 | ||
| 769 | - Kind: LF_UDT_SRC_LINE | ||
| 770 | UdtSourceLine: | ||
| 771 | UDT: 4158 | ||
| 772 | SourceFile: 4107 | ||
| 773 | LineNumber: 422 | ||
| 774 | - Kind: LF_STRUCTURE | ||
| 775 | Class: | ||
| 776 | MemberCount: 0 | ||
| 777 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 778 | FieldList: 0 | ||
| 779 | Name: '__vc_attributes::helper_attributes::usageAttribute' | ||
| 780 | UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' | ||
| 781 | DerivationList: 0 | ||
| 782 | VTableShape: 0 | ||
| 783 | Size: 0 | ||
| 784 | - Kind: LF_FIELDLIST | ||
| 785 | FieldList: | ||
| 786 | - Kind: LF_ENUMERATE | ||
| 787 | Enumerator: | ||
| 788 | Attrs: 3 | ||
| 789 | Value: 0 | ||
| 790 | Name: eAnyUsage | ||
| 791 | - Kind: LF_ENUMERATE | ||
| 792 | Enumerator: | ||
| 793 | Attrs: 3 | ||
| 794 | Value: 1 | ||
| 795 | Name: eCoClassUsage | ||
| 796 | - Kind: LF_ENUMERATE | ||
| 797 | Enumerator: | ||
| 798 | Attrs: 3 | ||
| 799 | Value: 2 | ||
| 800 | Name: eCOMInterfaceUsage | ||
| 801 | - Kind: LF_ENUMERATE | ||
| 802 | Enumerator: | ||
| 803 | Attrs: 3 | ||
| 804 | Value: 6 | ||
| 805 | Name: eInterfaceUsage | ||
| 806 | - Kind: LF_ENUMERATE | ||
| 807 | Enumerator: | ||
| 808 | Attrs: 3 | ||
| 809 | Value: 8 | ||
| 810 | Name: eMemberUsage | ||
| 811 | - Kind: LF_ENUMERATE | ||
| 812 | Enumerator: | ||
| 813 | Attrs: 3 | ||
| 814 | Value: 16 | ||
| 815 | Name: eMethodUsage | ||
| 816 | - Kind: LF_ENUMERATE | ||
| 817 | Enumerator: | ||
| 818 | Attrs: 3 | ||
| 819 | Value: 32 | ||
| 820 | Name: eInterfaceMethodUsage | ||
| 821 | - Kind: LF_ENUMERATE | ||
| 822 | Enumerator: | ||
| 823 | Attrs: 3 | ||
| 824 | Value: 64 | ||
| 825 | Name: eInterfaceMemberUsage | ||
| 826 | - Kind: LF_ENUMERATE | ||
| 827 | Enumerator: | ||
| 828 | Attrs: 3 | ||
| 829 | Value: 128 | ||
| 830 | Name: eCoClassMemberUsage | ||
| 831 | - Kind: LF_ENUMERATE | ||
| 832 | Enumerator: | ||
| 833 | Attrs: 3 | ||
| 834 | Value: 256 | ||
| 835 | Name: eCoClassMethodUsage | ||
| 836 | - Kind: LF_ENUMERATE | ||
| 837 | Enumerator: | ||
| 838 | Attrs: 3 | ||
| 839 | Value: 768 | ||
| 840 | Name: eGlobalMethodUsage | ||
| 841 | - Kind: LF_ENUMERATE | ||
| 842 | Enumerator: | ||
| 843 | Attrs: 3 | ||
| 844 | Value: 1024 | ||
| 845 | Name: eGlobalDataUsage | ||
| 846 | - Kind: LF_ENUMERATE | ||
| 847 | Enumerator: | ||
| 848 | Attrs: 3 | ||
| 849 | Value: 2048 | ||
| 850 | Name: eClassUsage | ||
| 851 | - Kind: LF_ENUMERATE | ||
| 852 | Enumerator: | ||
| 853 | Attrs: 3 | ||
| 854 | Value: 4096 | ||
| 855 | Name: eInterfaceParameterUsage | ||
| 856 | - Kind: LF_ENUMERATE | ||
| 857 | Enumerator: | ||
| 858 | Attrs: 3 | ||
| 859 | Value: 12288 | ||
| 860 | Name: eMethodParameterUsage | ||
| 861 | - Kind: LF_ENUMERATE | ||
| 862 | Enumerator: | ||
| 863 | Attrs: 3 | ||
| 864 | Value: 16384 | ||
| 865 | Name: eIDLModuleUsage | ||
| 866 | - Kind: LF_ENUMERATE | ||
| 867 | Enumerator: | ||
| 868 | Attrs: 3 | ||
| 869 | Value: 32768 | ||
| 870 | Name: eAnonymousUsage | ||
| 871 | - Kind: LF_ENUMERATE | ||
| 872 | Enumerator: | ||
| 873 | Attrs: 3 | ||
| 874 | Value: 65536 | ||
| 875 | Name: eTypedefUsage | ||
| 876 | - Kind: LF_ENUMERATE | ||
| 877 | Enumerator: | ||
| 878 | Attrs: 3 | ||
| 879 | Value: 131072 | ||
| 880 | Name: eUnionUsage | ||
| 881 | - Kind: LF_ENUMERATE | ||
| 882 | Enumerator: | ||
| 883 | Attrs: 3 | ||
| 884 | Value: 262144 | ||
| 885 | Name: eEnumUsage | ||
| 886 | - Kind: LF_ENUMERATE | ||
| 887 | Enumerator: | ||
| 888 | Attrs: 3 | ||
| 889 | Value: 524288 | ||
| 890 | Name: eDefineTagUsage | ||
| 891 | - Kind: LF_ENUMERATE | ||
| 892 | Enumerator: | ||
| 893 | Attrs: 3 | ||
| 894 | Value: 1048576 | ||
| 895 | Name: eStructUsage | ||
| 896 | - Kind: LF_ENUMERATE | ||
| 897 | Enumerator: | ||
| 898 | Attrs: 3 | ||
| 899 | Value: 2097152 | ||
| 900 | Name: eLocalUsage | ||
| 901 | - Kind: LF_ENUMERATE | ||
| 902 | Enumerator: | ||
| 903 | Attrs: 3 | ||
| 904 | Value: 4194304 | ||
| 905 | Name: ePropertyUsage | ||
| 906 | - Kind: LF_ENUMERATE | ||
| 907 | Enumerator: | ||
| 908 | Attrs: 3 | ||
| 909 | Value: 8388608 | ||
| 910 | Name: eEventUsage | ||
| 911 | - Kind: LF_ENUMERATE | ||
| 912 | Enumerator: | ||
| 913 | Attrs: 3 | ||
| 914 | Value: 16777216 | ||
| 915 | Name: eTemplateUsage | ||
| 916 | - Kind: LF_ENUMERATE | ||
| 917 | Enumerator: | ||
| 918 | Attrs: 3 | ||
| 919 | Value: 16777216 | ||
| 920 | Name: eModuleUsage | ||
| 921 | - Kind: LF_ENUMERATE | ||
| 922 | Enumerator: | ||
| 923 | Attrs: 3 | ||
| 924 | Value: 33554432 | ||
| 925 | Name: eIllegalUsage | ||
| 926 | - Kind: LF_ENUMERATE | ||
| 927 | Enumerator: | ||
| 928 | Attrs: 3 | ||
| 929 | Value: 67108864 | ||
| 930 | Name: eAsynchronousUsage | ||
| 931 | - Kind: LF_ENUMERATE | ||
| 932 | Enumerator: | ||
| 933 | Attrs: 3 | ||
| 934 | Value: 4161535 | ||
| 935 | Name: eAnyIDLUsage | ||
| 936 | - Kind: LF_ENUM | ||
| 937 | Enum: | ||
| 938 | NumEnumerators: 30 | ||
| 939 | Options: [ None, Nested, HasUniqueName ] | ||
| 940 | FieldList: 4161 | ||
| 941 | Name: '__vc_attributes::helper_attributes::usageAttribute::usage_e' | ||
| 942 | UniqueName: '.?AW4usage_e@usageAttribute@helper_attributes@__vc_attributes@@' | ||
| 943 | UnderlyingType: 116 | ||
| 944 | - Kind: LF_UDT_SRC_LINE | ||
| 945 | UdtSourceLine: | ||
| 946 | UDT: 4162 | ||
| 947 | SourceFile: 4107 | ||
| 948 | LineNumber: 51 | ||
| 949 | - Kind: LF_ARGLIST | ||
| 950 | ArgList: | ||
| 951 | ArgIndices: [ 117 ] | ||
| 952 | - Kind: LF_POINTER | ||
| 953 | Pointer: | ||
| 954 | ReferentType: 4160 | ||
| 955 | Attrs: 66572 | ||
| 956 | - Kind: LF_MFUNCTION | ||
| 957 | MemberFunction: | ||
| 958 | ReturnType: 3 | ||
| 959 | ClassType: 4160 | ||
| 960 | ThisType: 4165 | ||
| 961 | CallConv: NearC | ||
| 962 | Options: [ None, Constructor ] | ||
| 963 | ParameterCount: 1 | ||
| 964 | ArgumentList: 4164 | ||
| 965 | ThisPointerAdjustment: 0 | ||
| 966 | - Kind: LF_FIELDLIST | ||
| 967 | FieldList: | ||
| 968 | - Kind: LF_NESTTYPE | ||
| 969 | NestedType: | ||
| 970 | Type: 4162 | ||
| 971 | Name: usage_e | ||
| 972 | - Kind: LF_ONEMETHOD | ||
| 973 | OneMethod: | ||
| 974 | Type: 4166 | ||
| 975 | Attrs: 3 | ||
| 976 | VFTableOffset: -1 | ||
| 977 | Name: usageAttribute | ||
| 978 | - Kind: LF_MEMBER | ||
| 979 | DataMember: | ||
| 980 | Attrs: 3 | ||
| 981 | Type: 117 | ||
| 982 | FieldOffset: 0 | ||
| 983 | Name: value | ||
| 984 | - Kind: LF_STRUCTURE | ||
| 985 | Class: | ||
| 986 | MemberCount: 3 | ||
| 987 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 988 | FieldList: 4167 | ||
| 989 | Name: '__vc_attributes::helper_attributes::usageAttribute' | ||
| 990 | UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' | ||
| 991 | DerivationList: 0 | ||
| 992 | VTableShape: 0 | ||
| 993 | Size: 4 | ||
| 994 | - Kind: LF_UDT_SRC_LINE | ||
| 995 | UdtSourceLine: | ||
| 996 | UDT: 4168 | ||
| 997 | SourceFile: 4107 | ||
| 998 | LineNumber: 49 | ||
| 999 | - Kind: LF_STRUCTURE | ||
| 1000 | Class: | ||
| 1001 | MemberCount: 0 | ||
| 1002 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 1003 | FieldList: 0 | ||
| 1004 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | ||
| 1005 | UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' | ||
| 1006 | DerivationList: 0 | ||
| 1007 | VTableShape: 0 | ||
| 1008 | Size: 0 | ||
| 1009 | - Kind: LF_FIELDLIST | ||
| 1010 | FieldList: | ||
| 1011 | - Kind: LF_ENUMERATE | ||
| 1012 | Enumerator: | ||
| 1013 | Attrs: 3 | ||
| 1014 | Value: 0 | ||
| 1015 | Name: eBoolean | ||
| 1016 | - Kind: LF_ENUMERATE | ||
| 1017 | Enumerator: | ||
| 1018 | Attrs: 3 | ||
| 1019 | Value: 1 | ||
| 1020 | Name: eInteger | ||
| 1021 | - Kind: LF_ENUMERATE | ||
| 1022 | Enumerator: | ||
| 1023 | Attrs: 3 | ||
| 1024 | Value: 2 | ||
| 1025 | Name: eFloat | ||
| 1026 | - Kind: LF_ENUMERATE | ||
| 1027 | Enumerator: | ||
| 1028 | Attrs: 3 | ||
| 1029 | Value: 3 | ||
| 1030 | Name: eDouble | ||
| 1031 | - Kind: LF_ENUM | ||
| 1032 | Enum: | ||
| 1033 | NumEnumerators: 4 | ||
| 1034 | Options: [ None, Nested, HasUniqueName ] | ||
| 1035 | FieldList: 4171 | ||
| 1036 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e' | ||
| 1037 | UniqueName: '.?AW4type_e@v1_alttypeAttribute@helper_attributes@__vc_attributes@@' | ||
| 1038 | UnderlyingType: 116 | ||
| 1039 | - Kind: LF_UDT_SRC_LINE | ||
| 1040 | UdtSourceLine: | ||
| 1041 | UDT: 4172 | ||
| 1042 | SourceFile: 4107 | ||
| 1043 | LineNumber: 38 | ||
| 1044 | - Kind: LF_ARGLIST | ||
| 1045 | ArgList: | ||
| 1046 | ArgIndices: [ 4172 ] | ||
| 1047 | - Kind: LF_POINTER | ||
| 1048 | Pointer: | ||
| 1049 | ReferentType: 4170 | ||
| 1050 | Attrs: 66572 | ||
| 1051 | - Kind: LF_MFUNCTION | ||
| 1052 | MemberFunction: | ||
| 1053 | ReturnType: 3 | ||
| 1054 | ClassType: 4170 | ||
| 1055 | ThisType: 4175 | ||
| 1056 | CallConv: NearC | ||
| 1057 | Options: [ None, Constructor ] | ||
| 1058 | ParameterCount: 1 | ||
| 1059 | ArgumentList: 4174 | ||
| 1060 | ThisPointerAdjustment: 0 | ||
| 1061 | - Kind: LF_FIELDLIST | ||
| 1062 | FieldList: | ||
| 1063 | - Kind: LF_NESTTYPE | ||
| 1064 | NestedType: | ||
| 1065 | Type: 4172 | ||
| 1066 | Name: type_e | ||
| 1067 | - Kind: LF_ONEMETHOD | ||
| 1068 | OneMethod: | ||
| 1069 | Type: 4176 | ||
| 1070 | Attrs: 3 | ||
| 1071 | VFTableOffset: -1 | ||
| 1072 | Name: v1_alttypeAttribute | ||
| 1073 | - Kind: LF_MEMBER | ||
| 1074 | DataMember: | ||
| 1075 | Attrs: 3 | ||
| 1076 | Type: 4172 | ||
| 1077 | FieldOffset: 0 | ||
| 1078 | Name: type | ||
| 1079 | - Kind: LF_STRUCTURE | ||
| 1080 | Class: | ||
| 1081 | MemberCount: 3 | ||
| 1082 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 1083 | FieldList: 4177 | ||
| 1084 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | ||
| 1085 | UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' | ||
| 1086 | DerivationList: 0 | ||
| 1087 | VTableShape: 0 | ||
| 1088 | Size: 4 | ||
| 1089 | - Kind: LF_UDT_SRC_LINE | ||
| 1090 | UdtSourceLine: | ||
| 1091 | UDT: 4178 | ||
| 1092 | SourceFile: 4107 | ||
| 1093 | LineNumber: 37 | ||
| 1094 | - Kind: LF_STRUCTURE | ||
| 1095 | Class: | ||
| 1096 | MemberCount: 0 | ||
| 1097 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 1098 | FieldList: 0 | ||
| 1099 | Name: '__vc_attributes::event_sourceAttribute' | ||
| 1100 | UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' | ||
| 1101 | DerivationList: 0 | ||
| 1102 | VTableShape: 0 | ||
| 1103 | Size: 0 | ||
| 1104 | - Kind: LF_FIELDLIST | ||
| 1105 | FieldList: | ||
| 1106 | - Kind: LF_ENUMERATE | ||
| 1107 | Enumerator: | ||
| 1108 | Attrs: 3 | ||
| 1109 | Value: 0 | ||
| 1110 | Name: native | ||
| 1111 | - Kind: LF_ENUMERATE | ||
| 1112 | Enumerator: | ||
| 1113 | Attrs: 3 | ||
| 1114 | Value: 1 | ||
| 1115 | Name: com | ||
| 1116 | - Kind: LF_ENUMERATE | ||
| 1117 | Enumerator: | ||
| 1118 | Attrs: 3 | ||
| 1119 | Value: 2 | ||
| 1120 | Name: managed | ||
| 1121 | - Kind: LF_ENUM | ||
| 1122 | Enum: | ||
| 1123 | NumEnumerators: 3 | ||
| 1124 | Options: [ None, Nested, HasUniqueName ] | ||
| 1125 | FieldList: 4181 | ||
| 1126 | Name: '__vc_attributes::event_sourceAttribute::type_e' | ||
| 1127 | UniqueName: '.?AW4type_e@event_sourceAttribute@__vc_attributes@@' | ||
| 1128 | UnderlyingType: 116 | ||
| 1129 | - Kind: LF_UDT_SRC_LINE | ||
| 1130 | UdtSourceLine: | ||
| 1131 | UDT: 4182 | ||
| 1132 | SourceFile: 4107 | ||
| 1133 | LineNumber: 1142 | ||
| 1134 | - Kind: LF_FIELDLIST | ||
| 1135 | FieldList: | ||
| 1136 | - Kind: LF_ENUMERATE | ||
| 1137 | Enumerator: | ||
| 1138 | Attrs: 3 | ||
| 1139 | Value: 0 | ||
| 1140 | Name: speed | ||
| 1141 | - Kind: LF_ENUMERATE | ||
| 1142 | Enumerator: | ||
| 1143 | Attrs: 3 | ||
| 1144 | Value: 1 | ||
| 1145 | Name: size | ||
| 1146 | - Kind: LF_ENUM | ||
| 1147 | Enum: | ||
| 1148 | NumEnumerators: 2 | ||
| 1149 | Options: [ None, Nested, HasUniqueName ] | ||
| 1150 | FieldList: 4184 | ||
| 1151 | Name: '__vc_attributes::event_sourceAttribute::optimize_e' | ||
| 1152 | UniqueName: '.?AW4optimize_e@event_sourceAttribute@__vc_attributes@@' | ||
| 1153 | UnderlyingType: 116 | ||
| 1154 | - Kind: LF_UDT_SRC_LINE | ||
| 1155 | UdtSourceLine: | ||
| 1156 | UDT: 4185 | ||
| 1157 | SourceFile: 4107 | ||
| 1158 | LineNumber: 1145 | ||
| 1159 | - Kind: LF_ARGLIST | ||
| 1160 | ArgList: | ||
| 1161 | ArgIndices: [ 4182 ] | ||
| 1162 | - Kind: LF_POINTER | ||
| 1163 | Pointer: | ||
| 1164 | ReferentType: 4180 | ||
| 1165 | Attrs: 66572 | ||
| 1166 | - Kind: LF_MFUNCTION | ||
| 1167 | MemberFunction: | ||
| 1168 | ReturnType: 3 | ||
| 1169 | ClassType: 4180 | ||
| 1170 | ThisType: 4188 | ||
| 1171 | CallConv: NearC | ||
| 1172 | Options: [ None, Constructor ] | ||
| 1173 | ParameterCount: 1 | ||
| 1174 | ArgumentList: 4187 | ||
| 1175 | ThisPointerAdjustment: 0 | ||
| 1176 | - Kind: LF_MFUNCTION | ||
| 1177 | MemberFunction: | ||
| 1178 | ReturnType: 3 | ||
| 1179 | ClassType: 4180 | ||
| 1180 | ThisType: 4188 | ||
| 1181 | CallConv: NearC | ||
| 1182 | Options: [ None, Constructor ] | ||
| 1183 | ParameterCount: 0 | ||
| 1184 | ArgumentList: 4116 | ||
| 1185 | ThisPointerAdjustment: 0 | ||
| 1186 | - Kind: LF_METHODLIST | ||
| 1187 | MethodOverloadList: | ||
| 1188 | Methods: | ||
| 1189 | - Type: 4189 | ||
| 1190 | Attrs: 3 | ||
| 1191 | VFTableOffset: -1 | ||
| 1192 | Name: '' | ||
| 1193 | - Type: 4190 | ||
| 1194 | Attrs: 3 | ||
| 1195 | VFTableOffset: -1 | ||
| 1196 | Name: '' | ||
| 1197 | - Kind: LF_FIELDLIST | ||
| 1198 | FieldList: | ||
| 1199 | - Kind: LF_NESTTYPE | ||
| 1200 | NestedType: | ||
| 1201 | Type: 4182 | ||
| 1202 | Name: type_e | ||
| 1203 | - Kind: LF_NESTTYPE | ||
| 1204 | NestedType: | ||
| 1205 | Type: 4185 | ||
| 1206 | Name: optimize_e | ||
| 1207 | - Kind: LF_METHOD | ||
| 1208 | OverloadedMethod: | ||
| 1209 | NumOverloads: 2 | ||
| 1210 | MethodList: 4191 | ||
| 1211 | Name: event_sourceAttribute | ||
| 1212 | - Kind: LF_MEMBER | ||
| 1213 | DataMember: | ||
| 1214 | Attrs: 3 | ||
| 1215 | Type: 4182 | ||
| 1216 | FieldOffset: 0 | ||
| 1217 | Name: type | ||
| 1218 | - Kind: LF_MEMBER | ||
| 1219 | DataMember: | ||
| 1220 | Attrs: 3 | ||
| 1221 | Type: 4185 | ||
| 1222 | FieldOffset: 4 | ||
| 1223 | Name: optimize | ||
| 1224 | - Kind: LF_MEMBER | ||
| 1225 | DataMember: | ||
| 1226 | Attrs: 3 | ||
| 1227 | Type: 48 | ||
| 1228 | FieldOffset: 8 | ||
| 1229 | Name: decorate | ||
| 1230 | - Kind: LF_STRUCTURE | ||
| 1231 | Class: | ||
| 1232 | MemberCount: 7 | ||
| 1233 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 1234 | FieldList: 4192 | ||
| 1235 | Name: '__vc_attributes::event_sourceAttribute' | ||
| 1236 | UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' | ||
| 1237 | DerivationList: 0 | ||
| 1238 | VTableShape: 0 | ||
| 1239 | Size: 12 | ||
| 1240 | - Kind: LF_UDT_SRC_LINE | ||
| 1241 | UdtSourceLine: | ||
| 1242 | UDT: 4193 | ||
| 1243 | SourceFile: 4107 | ||
| 1244 | LineNumber: 1141 | ||
| 1245 | - Kind: LF_STRING_ID | ||
| 1246 | StringId: | ||
| 1247 | Id: 0 | ||
| 1248 | String: 'D:\src\llvmbuild\cl\Debug\x64' | ||
| 1249 | - Kind: LF_STRING_ID | ||
| 1250 | StringId: | ||
| 1251 | Id: 0 | ||
| 1252 | String: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64\cl.exe' | ||
| 1253 | - Kind: LF_STRING_ID | ||
| 1254 | StringId: | ||
| 1255 | Id: 0 | ||
| 1256 | String: '-Z7 -O1 -c -MT -I"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\ATLMFC\include" -I"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\include" -I"C:\Program' | ||
| 1257 | - Kind: LF_STRING_ID | ||
| 1258 | StringId: | ||
| 1259 | Id: 0 | ||
| 1260 | String: ' Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\um"' | ||
| 1261 | - Kind: LF_SUBSTR_LIST | ||
| 1262 | StringList: | ||
| 1263 | StringIndices: [ 4197, 4198 ] | ||
| 1264 | - Kind: LF_STRING_ID | ||
| 1265 | StringId: | ||
| 1266 | Id: 4199 | ||
| 1267 | String: ' -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\winrt" -TP -X' | ||
| 1268 | - Kind: LF_STRING_ID | ||
| 1269 | StringId: | ||
| 1270 | Id: 0 | ||
| 1271 | String: a.cpp | ||
| 1272 | - Kind: LF_STRING_ID | ||
| 1273 | StringId: | ||
| 1274 | Id: 0 | ||
| 1275 | String: 'D:\src\llvmbuild\cl\Debug\x64\vc140.pdb' | ||
| 1276 | - Kind: LF_BUILDINFO | ||
| 1277 | BuildInfo: | ||
| 1278 | ArgIndices: [ 4195, 4196, 4201, 4202, 4200 ] | ||
| 1279 | - Name: .bss | ||
| 1280 | Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 1281 | Alignment: 4 | ||
| 1282 | SectionData: '' | ||
| 1283 | - Name: '.text$mn' | ||
| 1284 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 1285 | Alignment: 4 | ||
| 1286 | SectionData: 4883EC288B0D0000000085C97405E8000000004883C428C3 | ||
| 1287 | Relocations: | ||
| 1288 | - VirtualAddress: 6 | ||
| 1289 | SymbolName: '?x@@3HA' | ||
| 1290 | Type: IMAGE_REL_AMD64_REL32 | ||
| 1291 | - VirtualAddress: 15 | ||
| 1292 | SymbolName: '?b@@YAXH@Z' | ||
| 1293 | Type: IMAGE_REL_AMD64_REL32 | ||
| 1294 | - Name: '.debug$S' | ||
| 1295 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 1296 | Alignment: 1 | ||
| 1297 | Subsections: | ||
| 1298 | - !Symbols | ||
| 1299 | Records: | ||
| 1300 | - Kind: S_GPROC32_ID | ||
| 1301 | ProcSym: | ||
| 1302 | CodeSize: 24 | ||
| 1303 | DbgStart: 4 | ||
| 1304 | DbgEnd: 19 | ||
| 1305 | FunctionType: 4099 | ||
| 1306 | Flags: [ HasOptimizedDebugInfo ] | ||
| 1307 | DisplayName: a | ||
| 1308 | - Kind: S_LOCAL | ||
| 1309 | LocalSym: | ||
| 1310 | Type: 116 | ||
| 1311 | Flags: [ IsParameter ] | ||
| 1312 | VarName: __formal | ||
| 1313 | - Kind: S_DEFRANGE_REGISTER | ||
| 1314 | DefRangeRegisterSym: | ||
| 1315 | Register: 18 | ||
| 1316 | MayHaveNoName: 0 | ||
| 1317 | Range: | ||
| 1318 | OffsetStart: 0 | ||
| 1319 | ISectStart: 0 | ||
| 1320 | Range: 10 | ||
| 1321 | Gaps: | ||
| 1322 | - Kind: S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE | ||
| 1323 | DefRangeFramePointerRelFullScopeSym: | ||
| 1324 | Register: 48 | ||
| 1325 | - Kind: S_CALLEES | ||
| 1326 | CallerSym: | ||
| 1327 | FuncID: [ 4103 ] | ||
| 1328 | - Kind: S_FILESTATIC | ||
| 1329 | FileStaticSym: | ||
| 1330 | Index: 116 | ||
| 1331 | ModFilenameOffset: 37 | ||
| 1332 | Flags: [ IsEnregisteredGlobal, IsEnregisteredStatic ] | ||
| 1333 | Name: x | ||
| 1334 | - Kind: S_DEFRANGE_REGISTER | ||
| 1335 | DefRangeRegisterSym: | ||
| 1336 | Register: 18 | ||
| 1337 | MayHaveNoName: 0 | ||
| 1338 | Range: | ||
| 1339 | OffsetStart: 10 | ||
| 1340 | ISectStart: 0 | ||
| 1341 | Range: 9 | ||
| 1342 | Gaps: | ||
| 1343 | - Kind: S_FRAMEPROC | ||
| 1344 | FrameProcSym: | ||
| 1345 | TotalFrameBytes: 40 | ||
| 1346 | PaddingFrameBytes: 0 | ||
| 1347 | OffsetToPadding: 0 | ||
| 1348 | BytesOfCalleeSavedRegisters: 0 | ||
| 1349 | OffsetOfExceptionHandler: 0 | ||
| 1350 | SectionIdOfExceptionHandler: 0 | ||
| 1351 | Flags: [ AsynchronousExceptionHandling, Inlined ] | ||
| 1352 | - Kind: S_REGREL32 | ||
| 1353 | RegRelativeSym: | ||
| 1354 | Offset: 48 | ||
| 1355 | Type: 116 | ||
| 1356 | Register: CVRegRSP | ||
| 1357 | VarName: __formal | ||
| 1358 | - Kind: S_PROC_ID_END | ||
| 1359 | ScopeEndSym: | ||
| 1360 | - !Lines | ||
| 1361 | CodeSize: 24 | ||
| 1362 | Flags: [ ] | ||
| 1363 | RelocOffset: 0 | ||
| 1364 | RelocSegment: 0 | ||
| 1365 | Blocks: | ||
| 1366 | - FileName: 'd:\src\llvmbuild\cl\debug\x64\a.cpp' | ||
| 1367 | Lines: | ||
| 1368 | - Offset: 0 | ||
| 1369 | LineStart: 7 | ||
| 1370 | IsStatement: true | ||
| 1371 | EndDelta: 0 | ||
| 1372 | - Offset: 4 | ||
| 1373 | LineStart: 8 | ||
| 1374 | IsStatement: true | ||
| 1375 | EndDelta: 0 | ||
| 1376 | - Offset: 14 | ||
| 1377 | LineStart: 9 | ||
| 1378 | IsStatement: true | ||
| 1379 | EndDelta: 0 | ||
| 1380 | - Offset: 19 | ||
| 1381 | LineStart: 10 | ||
| 1382 | IsStatement: true | ||
| 1383 | EndDelta: 0 | ||
| 1384 | Columns: | ||
| 1385 | Relocations: | ||
| 1386 | - VirtualAddress: 44 | ||
| 1387 | SymbolName: '?a@@YAXH@Z' | ||
| 1388 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1389 | - VirtualAddress: 48 | ||
| 1390 | SymbolName: '?a@@YAXH@Z' | ||
| 1391 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1392 | - VirtualAddress: 80 | ||
| 1393 | SymbolName: '?a@@YAXH@Z' | ||
| 1394 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1395 | - VirtualAddress: 84 | ||
| 1396 | SymbolName: '?a@@YAXH@Z' | ||
| 1397 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1398 | - VirtualAddress: 132 | ||
| 1399 | SymbolName: '?a@@YAXH@Z' | ||
| 1400 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1401 | - VirtualAddress: 136 | ||
| 1402 | SymbolName: '?a@@YAXH@Z' | ||
| 1403 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1404 | - VirtualAddress: 208 | ||
| 1405 | SymbolName: '?a@@YAXH@Z' | ||
| 1406 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1407 | - VirtualAddress: 212 | ||
| 1408 | SymbolName: '?a@@YAXH@Z' | ||
| 1409 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1410 | - Name: '.text$mn' | ||
| 1411 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 1412 | Alignment: 4 | ||
| 1413 | SectionData: 4883EC288B050000000085C0740D8BC8E8000000008B05000000004883C428C3 | ||
| 1414 | Relocations: | ||
| 1415 | - VirtualAddress: 6 | ||
| 1416 | SymbolName: '?x@@3HA' | ||
| 1417 | Type: IMAGE_REL_AMD64_REL32 | ||
| 1418 | - VirtualAddress: 17 | ||
| 1419 | SymbolName: '?b@@YAXH@Z' | ||
| 1420 | Type: IMAGE_REL_AMD64_REL32 | ||
| 1421 | - VirtualAddress: 23 | ||
| 1422 | SymbolName: '?x@@3HA' | ||
| 1423 | Type: IMAGE_REL_AMD64_REL32 | ||
| 1424 | - Name: '.debug$S' | ||
| 1425 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 1426 | Alignment: 1 | ||
| 1427 | Subsections: | ||
| 1428 | - !Symbols | ||
| 1429 | Records: | ||
| 1430 | - Kind: S_GPROC32_ID | ||
| 1431 | ProcSym: | ||
| 1432 | CodeSize: 32 | ||
| 1433 | DbgStart: 4 | ||
| 1434 | DbgEnd: 27 | ||
| 1435 | FunctionType: 4102 | ||
| 1436 | Flags: [ HasOptimizedDebugInfo ] | ||
| 1437 | DisplayName: main | ||
| 1438 | - Kind: S_LOCAL | ||
| 1439 | LocalSym: | ||
| 1440 | Type: 116 | ||
| 1441 | Flags: [ IsParameter ] | ||
| 1442 | VarName: argc | ||
| 1443 | - Kind: S_DEFRANGE_REGISTER | ||
| 1444 | DefRangeRegisterSym: | ||
| 1445 | Register: 18 | ||
| 1446 | MayHaveNoName: 0 | ||
| 1447 | Range: | ||
| 1448 | OffsetStart: 0 | ||
| 1449 | ISectStart: 0 | ||
| 1450 | Range: 16 | ||
| 1451 | Gaps: | ||
| 1452 | - Kind: S_DEFRANGE_REGISTER | ||
| 1453 | DefRangeRegisterSym: | ||
| 1454 | Register: 18 | ||
| 1455 | MayHaveNoName: 1 | ||
| 1456 | Range: | ||
| 1457 | OffsetStart: 27 | ||
| 1458 | ISectStart: 0 | ||
| 1459 | Range: 5 | ||
| 1460 | Gaps: | ||
| 1461 | - Kind: S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE | ||
| 1462 | DefRangeFramePointerRelFullScopeSym: | ||
| 1463 | Register: 48 | ||
| 1464 | - Kind: S_LOCAL | ||
| 1465 | LocalSym: | ||
| 1466 | Type: 4098 | ||
| 1467 | Flags: [ IsParameter ] | ||
| 1468 | VarName: argv | ||
| 1469 | - Kind: S_DEFRANGE_REGISTER | ||
| 1470 | DefRangeRegisterSym: | ||
| 1471 | Register: 331 | ||
| 1472 | MayHaveNoName: 0 | ||
| 1473 | Range: | ||
| 1474 | OffsetStart: 0 | ||
| 1475 | ISectStart: 0 | ||
| 1476 | Range: 21 | ||
| 1477 | Gaps: | ||
| 1478 | - Kind: S_DEFRANGE_REGISTER | ||
| 1479 | DefRangeRegisterSym: | ||
| 1480 | Register: 331 | ||
| 1481 | MayHaveNoName: 1 | ||
| 1482 | Range: | ||
| 1483 | OffsetStart: 27 | ||
| 1484 | ISectStart: 0 | ||
| 1485 | Range: 5 | ||
| 1486 | Gaps: | ||
| 1487 | - Kind: S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE | ||
| 1488 | DefRangeFramePointerRelFullScopeSym: | ||
| 1489 | Register: 56 | ||
| 1490 | - Kind: S_INLINESITE | ||
| 1491 | InlineSiteSym: | ||
| 1492 | Inlinee: 4099 | ||
| 1493 | - Kind: S_CALLEES | ||
| 1494 | CallerSym: | ||
| 1495 | FuncID: [ 4103 ] | ||
| 1496 | - Kind: S_INLINESITE_END | ||
| 1497 | ScopeEndSym: | ||
| 1498 | - Kind: S_FILESTATIC | ||
| 1499 | FileStaticSym: | ||
| 1500 | Index: 116 | ||
| 1501 | ModFilenameOffset: 37 | ||
| 1502 | Flags: [ IsEnregisteredGlobal, IsEnregisteredStatic ] | ||
| 1503 | Name: x | ||
| 1504 | - Kind: S_DEFRANGE_REGISTER | ||
| 1505 | DefRangeRegisterSym: | ||
| 1506 | Register: 17 | ||
| 1507 | MayHaveNoName: 0 | ||
| 1508 | Range: | ||
| 1509 | OffsetStart: 10 | ||
| 1510 | ISectStart: 0 | ||
| 1511 | Range: 22 | ||
| 1512 | Gaps: | ||
| 1513 | - GapStartOffset: 11 | ||
| 1514 | Range: 6 | ||
| 1515 | - Kind: S_FRAMEPROC | ||
| 1516 | FrameProcSym: | ||
| 1517 | TotalFrameBytes: 40 | ||
| 1518 | PaddingFrameBytes: 0 | ||
| 1519 | OffsetToPadding: 0 | ||
| 1520 | BytesOfCalleeSavedRegisters: 0 | ||
| 1521 | OffsetOfExceptionHandler: 0 | ||
| 1522 | SectionIdOfExceptionHandler: 0 | ||
| 1523 | Flags: [ AsynchronousExceptionHandling ] | ||
| 1524 | - Kind: S_INLINEES | ||
| 1525 | CallerSym: | ||
| 1526 | FuncID: [ 4099 ] | ||
| 1527 | - Kind: S_REGREL32 | ||
| 1528 | RegRelativeSym: | ||
| 1529 | Offset: 48 | ||
| 1530 | Type: 116 | ||
| 1531 | Register: CVRegRSP | ||
| 1532 | VarName: argc | ||
| 1533 | - Kind: S_REGREL32 | ||
| 1534 | RegRelativeSym: | ||
| 1535 | Offset: 56 | ||
| 1536 | Type: 4098 | ||
| 1537 | Register: CVRegRSP | ||
| 1538 | VarName: argv | ||
| 1539 | - Kind: S_PROC_ID_END | ||
| 1540 | ScopeEndSym: | ||
| 1541 | - !Lines | ||
| 1542 | CodeSize: 32 | ||
| 1543 | Flags: [ ] | ||
| 1544 | RelocOffset: 0 | ||
| 1545 | RelocSegment: 0 | ||
| 1546 | Blocks: | ||
| 1547 | - FileName: 'd:\src\llvmbuild\cl\debug\x64\a.cpp' | ||
| 1548 | Lines: | ||
| 1549 | - Offset: 0 | ||
| 1550 | LineStart: 12 | ||
| 1551 | IsStatement: true | ||
| 1552 | EndDelta: 0 | ||
| 1553 | - Offset: 4 | ||
| 1554 | LineStart: 13 | ||
| 1555 | IsStatement: true | ||
| 1556 | EndDelta: 0 | ||
| 1557 | - Offset: 27 | ||
| 1558 | LineStart: 15 | ||
| 1559 | IsStatement: true | ||
| 1560 | EndDelta: 0 | ||
| 1561 | Columns: | ||
| 1562 | Relocations: | ||
| 1563 | - VirtualAddress: 44 | ||
| 1564 | SymbolName: main | ||
| 1565 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1566 | - VirtualAddress: 48 | ||
| 1567 | SymbolName: main | ||
| 1568 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1569 | - VirtualAddress: 79 | ||
| 1570 | SymbolName: main | ||
| 1571 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1572 | - VirtualAddress: 83 | ||
| 1573 | SymbolName: main | ||
| 1574 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1575 | - VirtualAddress: 95 | ||
| 1576 | SymbolName: main | ||
| 1577 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1578 | - VirtualAddress: 99 | ||
| 1579 | SymbolName: main | ||
| 1580 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1581 | - VirtualAddress: 134 | ||
| 1582 | SymbolName: main | ||
| 1583 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1584 | - VirtualAddress: 138 | ||
| 1585 | SymbolName: main | ||
| 1586 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1587 | - VirtualAddress: 150 | ||
| 1588 | SymbolName: main | ||
| 1589 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1590 | - VirtualAddress: 154 | ||
| 1591 | SymbolName: main | ||
| 1592 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1593 | - VirtualAddress: 229 | ||
| 1594 | SymbolName: main | ||
| 1595 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1596 | - VirtualAddress: 233 | ||
| 1597 | SymbolName: main | ||
| 1598 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1599 | - VirtualAddress: 336 | ||
| 1600 | SymbolName: main | ||
| 1601 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1602 | - VirtualAddress: 340 | ||
| 1603 | SymbolName: main | ||
| 1604 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1605 | - Name: .xdata | ||
| 1606 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | ||
| 1607 | Alignment: 4 | ||
| 1608 | SectionData: '0104010004420000' | ||
| 1609 | - Name: .pdata | ||
| 1610 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | ||
| 1611 | Alignment: 4 | ||
| 1612 | SectionData: '000000001800000000000000' | ||
| 1613 | Relocations: | ||
| 1614 | - VirtualAddress: 0 | ||
| 1615 | SymbolName: '$LN5' | ||
| 1616 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1617 | - VirtualAddress: 4 | ||
| 1618 | SymbolName: '$LN5' | ||
| 1619 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1620 | - VirtualAddress: 8 | ||
| 1621 | SymbolName: '$unwind$?a@@YAXH@Z' | ||
| 1622 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1623 | - Name: .xdata | ||
| 1624 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | ||
| 1625 | Alignment: 4 | ||
| 1626 | SectionData: '0104010004420000' | ||
| 1627 | - Name: .pdata | ||
| 1628 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | ||
| 1629 | Alignment: 4 | ||
| 1630 | SectionData: '000000002000000000000000' | ||
| 1631 | Relocations: | ||
| 1632 | - VirtualAddress: 0 | ||
| 1633 | SymbolName: '$LN7' | ||
| 1634 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1635 | - VirtualAddress: 4 | ||
| 1636 | SymbolName: '$LN7' | ||
| 1637 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1638 | - VirtualAddress: 8 | ||
| 1639 | SymbolName: '$unwind$main' | ||
| 1640 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1641 | symbols: | ||
| 1642 | - Name: '@comp.id' | ||
| 1643 | Value: 17130443 | ||
| 1644 | SectionNumber: -1 | ||
| 1645 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1646 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1647 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1648 | - Name: '@feat.00' | ||
| 1649 | Value: 2147484048 | ||
| 1650 | SectionNumber: -1 | ||
| 1651 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1652 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1653 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1654 | - Name: .drectve | ||
| 1655 | Value: 0 | ||
| 1656 | SectionNumber: 1 | ||
| 1657 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1658 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1659 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1660 | SectionDefinition: | ||
| 1661 | Length: 47 | ||
| 1662 | NumberOfRelocations: 0 | ||
| 1663 | NumberOfLinenumbers: 0 | ||
| 1664 | CheckSum: 0 | ||
| 1665 | Number: 0 | ||
| 1666 | - Name: '.debug$S' | ||
| 1667 | Value: 0 | ||
| 1668 | SectionNumber: 2 | ||
| 1669 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1670 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1671 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1672 | SectionDefinition: | ||
| 1673 | Length: 1120 | ||
| 1674 | NumberOfRelocations: 2 | ||
| 1675 | NumberOfLinenumbers: 0 | ||
| 1676 | CheckSum: 0 | ||
| 1677 | Number: 0 | ||
| 1678 | - Name: '.debug$T' | ||
| 1679 | Value: 0 | ||
| 1680 | SectionNumber: 3 | ||
| 1681 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1682 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1683 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1684 | SectionDefinition: | ||
| 1685 | Length: 6700 | ||
| 1686 | NumberOfRelocations: 0 | ||
| 1687 | NumberOfLinenumbers: 0 | ||
| 1688 | CheckSum: 0 | ||
| 1689 | Number: 0 | ||
| 1690 | - Name: .bss | ||
| 1691 | Value: 0 | ||
| 1692 | SectionNumber: 4 | ||
| 1693 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1694 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1695 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1696 | SectionDefinition: | ||
| 1697 | Length: 4 | ||
| 1698 | NumberOfRelocations: 0 | ||
| 1699 | NumberOfLinenumbers: 0 | ||
| 1700 | CheckSum: 0 | ||
| 1701 | Number: 0 | ||
| 1702 | - Name: '?x@@3HA' | ||
| 1703 | Value: 0 | ||
| 1704 | SectionNumber: 4 | ||
| 1705 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1706 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1707 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1708 | - Name: '.text$mn' | ||
| 1709 | Value: 0 | ||
| 1710 | SectionNumber: 5 | ||
| 1711 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1712 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1713 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1714 | SectionDefinition: | ||
| 1715 | Length: 24 | ||
| 1716 | NumberOfRelocations: 2 | ||
| 1717 | NumberOfLinenumbers: 0 | ||
| 1718 | CheckSum: 211387054 | ||
| 1719 | Number: 0 | ||
| 1720 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 1721 | - Name: '.debug$S' | ||
| 1722 | Value: 0 | ||
| 1723 | SectionNumber: 6 | ||
| 1724 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1725 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1726 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1727 | SectionDefinition: | ||
| 1728 | Length: 264 | ||
| 1729 | NumberOfRelocations: 8 | ||
| 1730 | NumberOfLinenumbers: 0 | ||
| 1731 | CheckSum: 0 | ||
| 1732 | Number: 5 | ||
| 1733 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1734 | - Name: '.text$mn' | ||
| 1735 | Value: 0 | ||
| 1736 | SectionNumber: 7 | ||
| 1737 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1738 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1739 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1740 | SectionDefinition: | ||
| 1741 | Length: 32 | ||
| 1742 | NumberOfRelocations: 3 | ||
| 1743 | NumberOfLinenumbers: 0 | ||
| 1744 | CheckSum: 3834856183 | ||
| 1745 | Number: 0 | ||
| 1746 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 1747 | - Name: '.debug$S' | ||
| 1748 | Value: 0 | ||
| 1749 | SectionNumber: 8 | ||
| 1750 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1751 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1752 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1753 | SectionDefinition: | ||
| 1754 | Length: 384 | ||
| 1755 | NumberOfRelocations: 14 | ||
| 1756 | NumberOfLinenumbers: 0 | ||
| 1757 | CheckSum: 0 | ||
| 1758 | Number: 7 | ||
| 1759 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1760 | - Name: '?b@@YAXH@Z' | ||
| 1761 | Value: 0 | ||
| 1762 | SectionNumber: 0 | ||
| 1763 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1764 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 1765 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 1766 | - Name: '?a@@YAXH@Z' | ||
| 1767 | Value: 0 | ||
| 1768 | SectionNumber: 5 | ||
| 1769 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1770 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 1771 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 1772 | - Name: main | ||
| 1773 | Value: 0 | ||
| 1774 | SectionNumber: 7 | ||
| 1775 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1776 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 1777 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 1778 | - Name: '$LN5' | ||
| 1779 | Value: 0 | ||
| 1780 | SectionNumber: 5 | ||
| 1781 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1782 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1783 | StorageClass: IMAGE_SYM_CLASS_LABEL | ||
| 1784 | - Name: '$LN7' | ||
| 1785 | Value: 0 | ||
| 1786 | SectionNumber: 7 | ||
| 1787 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1788 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1789 | StorageClass: IMAGE_SYM_CLASS_LABEL | ||
| 1790 | - Name: .xdata | ||
| 1791 | Value: 0 | ||
| 1792 | SectionNumber: 9 | ||
| 1793 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1794 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1795 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1796 | SectionDefinition: | ||
| 1797 | Length: 8 | ||
| 1798 | NumberOfRelocations: 0 | ||
| 1799 | NumberOfLinenumbers: 0 | ||
| 1800 | CheckSum: 264583633 | ||
| 1801 | Number: 5 | ||
| 1802 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1803 | - Name: '$unwind$?a@@YAXH@Z' | ||
| 1804 | Value: 0 | ||
| 1805 | SectionNumber: 9 | ||
| 1806 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1807 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1808 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1809 | - Name: .pdata | ||
| 1810 | Value: 0 | ||
| 1811 | SectionNumber: 10 | ||
| 1812 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1813 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1814 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1815 | SectionDefinition: | ||
| 1816 | Length: 12 | ||
| 1817 | NumberOfRelocations: 3 | ||
| 1818 | NumberOfLinenumbers: 0 | ||
| 1819 | CheckSum: 2942184094 | ||
| 1820 | Number: 5 | ||
| 1821 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1822 | - Name: '$pdata$?a@@YAXH@Z' | ||
| 1823 | Value: 0 | ||
| 1824 | SectionNumber: 10 | ||
| 1825 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1826 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1827 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1828 | - Name: .xdata | ||
| 1829 | Value: 0 | ||
| 1830 | SectionNumber: 11 | ||
| 1831 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1832 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1833 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1834 | SectionDefinition: | ||
| 1835 | Length: 8 | ||
| 1836 | NumberOfRelocations: 0 | ||
| 1837 | NumberOfLinenumbers: 0 | ||
| 1838 | CheckSum: 264583633 | ||
| 1839 | Number: 7 | ||
| 1840 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1841 | - Name: '$unwind$main' | ||
| 1842 | Value: 0 | ||
| 1843 | SectionNumber: 11 | ||
| 1844 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1845 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1846 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1847 | - Name: .pdata | ||
| 1848 | Value: 0 | ||
| 1849 | SectionNumber: 12 | ||
| 1850 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1851 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1852 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1853 | SectionDefinition: | ||
| 1854 | Length: 12 | ||
| 1855 | NumberOfRelocations: 3 | ||
| 1856 | NumberOfLinenumbers: 0 | ||
| 1857 | CheckSum: 4185285206 | ||
| 1858 | Number: 7 | ||
| 1859 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1860 | - Name: '$pdata$main' | ||
| 1861 | Value: 0 | ||
| 1862 | SectionNumber: 12 | ||
| 1863 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1864 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1865 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1866 | ... | ||
deps/lld/test/COFF/Inputs/pdb-file-statics-b.yaml created+1552| ... | @@ -0,0 +1,1552 @@ | ||
| 1 | --- !COFF | ||
| 2 | header: | ||
| 3 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 4 | Characteristics: [ ] | ||
| 5 | sections: | ||
| 6 | - Name: .drectve | ||
| 7 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | ||
| 8 | Alignment: 1 | ||
| 9 | SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220 | ||
| 10 | - Name: '.debug$S' | ||
| 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 12 | Alignment: 1 | ||
| 13 | Subsections: | ||
| 14 | - !Symbols | ||
| 15 | Records: | ||
| 16 | - Kind: S_OBJNAME | ||
| 17 | ObjNameSym: | ||
| 18 | Signature: 0 | ||
| 19 | ObjectName: 'D:\src\llvmbuild\cl\Debug\x64\b.obj' | ||
| 20 | - Kind: S_COMPILE3 | ||
| 21 | Compile3Sym: | ||
| 22 | Flags: [ SecurityChecks, HotPatch ] | ||
| 23 | Machine: X64 | ||
| 24 | FrontendMajor: 19 | ||
| 25 | FrontendMinor: 11 | ||
| 26 | FrontendBuild: 25547 | ||
| 27 | FrontendQFE: 0 | ||
| 28 | BackendMajor: 19 | ||
| 29 | BackendMinor: 11 | ||
| 30 | BackendBuild: 25547 | ||
| 31 | BackendQFE: 0 | ||
| 32 | Version: 'Microsoft (R) Optimizing Compiler' | ||
| 33 | - !Symbols | ||
| 34 | Records: | ||
| 35 | - Kind: S_LDATA32 | ||
| 36 | DataSym: | ||
| 37 | Type: 116 | ||
| 38 | DisplayName: y | ||
| 39 | - Kind: S_UDT | ||
| 40 | UDTSym: | ||
| 41 | Type: 4189 | ||
| 42 | UDTName: '__vc_attributes::event_sourceAttribute' | ||
| 43 | - Kind: S_UDT | ||
| 44 | UDTSym: | ||
| 45 | Type: 4181 | ||
| 46 | UDTName: '__vc_attributes::event_sourceAttribute::optimize_e' | ||
| 47 | - Kind: S_UDT | ||
| 48 | UDTSym: | ||
| 49 | Type: 4178 | ||
| 50 | UDTName: '__vc_attributes::event_sourceAttribute::type_e' | ||
| 51 | - Kind: S_UDT | ||
| 52 | UDTSym: | ||
| 53 | Type: 4174 | ||
| 54 | UDTName: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | ||
| 55 | - Kind: S_UDT | ||
| 56 | UDTSym: | ||
| 57 | Type: 4168 | ||
| 58 | UDTName: '__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e' | ||
| 59 | - Kind: S_UDT | ||
| 60 | UDTSym: | ||
| 61 | Type: 4164 | ||
| 62 | UDTName: '__vc_attributes::helper_attributes::usageAttribute' | ||
| 63 | - Kind: S_UDT | ||
| 64 | UDTSym: | ||
| 65 | Type: 4158 | ||
| 66 | UDTName: '__vc_attributes::helper_attributes::usageAttribute::usage_e' | ||
| 67 | - Kind: S_UDT | ||
| 68 | UDTSym: | ||
| 69 | Type: 4154 | ||
| 70 | UDTName: '__vc_attributes::threadingAttribute' | ||
| 71 | - Kind: S_UDT | ||
| 72 | UDTSym: | ||
| 73 | Type: 4146 | ||
| 74 | UDTName: '__vc_attributes::threadingAttribute::threading_e' | ||
| 75 | - Kind: S_UDT | ||
| 76 | UDTSym: | ||
| 77 | Type: 4142 | ||
| 78 | UDTName: '__vc_attributes::aggregatableAttribute' | ||
| 79 | - Kind: S_UDT | ||
| 80 | UDTSym: | ||
| 81 | Type: 4134 | ||
| 82 | UDTName: '__vc_attributes::aggregatableAttribute::type_e' | ||
| 83 | - Kind: S_UDT | ||
| 84 | UDTSym: | ||
| 85 | Type: 4130 | ||
| 86 | UDTName: '__vc_attributes::event_receiverAttribute' | ||
| 87 | - Kind: S_UDT | ||
| 88 | UDTSym: | ||
| 89 | Type: 4120 | ||
| 90 | UDTName: '__vc_attributes::event_receiverAttribute::type_e' | ||
| 91 | - Kind: S_UDT | ||
| 92 | UDTSym: | ||
| 93 | Type: 4116 | ||
| 94 | UDTName: '__vc_attributes::moduleAttribute' | ||
| 95 | - Kind: S_UDT | ||
| 96 | UDTSym: | ||
| 97 | Type: 4102 | ||
| 98 | UDTName: '__vc_attributes::moduleAttribute::type_e' | ||
| 99 | - !FileChecksums | ||
| 100 | Checksums: | ||
| 101 | - FileName: 'd:\src\llvmbuild\cl\debug\x64\b.cpp' | ||
| 102 | Kind: MD5 | ||
| 103 | Checksum: 8B4E383DAF442E63771294D52BF55155 | ||
| 104 | - !StringTable | ||
| 105 | Strings: | ||
| 106 | - 'd:\src\llvmbuild\cl\debug\x64\b.cpp' | ||
| 107 | - 'D:\src\llvmbuild\cl\Debug\x64\b.obj' | ||
| 108 | - !Symbols | ||
| 109 | Records: | ||
| 110 | - Kind: S_BUILDINFO | ||
| 111 | BuildInfoSym: | ||
| 112 | BuildId: 4199 | ||
| 113 | Relocations: | ||
| 114 | - VirtualAddress: 132 | ||
| 115 | SymbolName: '?y@@3HA' | ||
| 116 | Type: IMAGE_REL_AMD64_SECREL | ||
| 117 | - VirtualAddress: 136 | ||
| 118 | SymbolName: '?y@@3HA' | ||
| 119 | Type: IMAGE_REL_AMD64_SECTION | ||
| 120 | - Name: '.debug$T' | ||
| 121 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 122 | Alignment: 1 | ||
| 123 | Types: | ||
| 124 | - Kind: LF_ARGLIST | ||
| 125 | ArgList: | ||
| 126 | ArgIndices: [ 116 ] | ||
| 127 | - Kind: LF_PROCEDURE | ||
| 128 | Procedure: | ||
| 129 | ReturnType: 3 | ||
| 130 | CallConv: NearC | ||
| 131 | Options: [ None ] | ||
| 132 | ParameterCount: 1 | ||
| 133 | ArgumentList: 4096 | ||
| 134 | - Kind: LF_FUNC_ID | ||
| 135 | FuncId: | ||
| 136 | ParentScope: 0 | ||
| 137 | FunctionType: 4097 | ||
| 138 | Name: b | ||
| 139 | - Kind: LF_FUNC_ID | ||
| 140 | FuncId: | ||
| 141 | ParentScope: 0 | ||
| 142 | FunctionType: 4097 | ||
| 143 | Name: a | ||
| 144 | - Kind: LF_STRUCTURE | ||
| 145 | Class: | ||
| 146 | MemberCount: 0 | ||
| 147 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 148 | FieldList: 0 | ||
| 149 | Name: '__vc_attributes::moduleAttribute' | ||
| 150 | UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' | ||
| 151 | DerivationList: 0 | ||
| 152 | VTableShape: 0 | ||
| 153 | Size: 0 | ||
| 154 | - Kind: LF_FIELDLIST | ||
| 155 | FieldList: | ||
| 156 | - Kind: LF_ENUMERATE | ||
| 157 | Enumerator: | ||
| 158 | Attrs: 3 | ||
| 159 | Value: 1 | ||
| 160 | Name: dll | ||
| 161 | - Kind: LF_ENUMERATE | ||
| 162 | Enumerator: | ||
| 163 | Attrs: 3 | ||
| 164 | Value: 2 | ||
| 165 | Name: exe | ||
| 166 | - Kind: LF_ENUMERATE | ||
| 167 | Enumerator: | ||
| 168 | Attrs: 3 | ||
| 169 | Value: 3 | ||
| 170 | Name: service | ||
| 171 | - Kind: LF_ENUMERATE | ||
| 172 | Enumerator: | ||
| 173 | Attrs: 3 | ||
| 174 | Value: 4 | ||
| 175 | Name: unspecified | ||
| 176 | - Kind: LF_ENUMERATE | ||
| 177 | Enumerator: | ||
| 178 | Attrs: 3 | ||
| 179 | Value: 2 | ||
| 180 | Name: EXE | ||
| 181 | - Kind: LF_ENUMERATE | ||
| 182 | Enumerator: | ||
| 183 | Attrs: 3 | ||
| 184 | Value: 3 | ||
| 185 | Name: SERVICE | ||
| 186 | - Kind: LF_ENUM | ||
| 187 | Enum: | ||
| 188 | NumEnumerators: 6 | ||
| 189 | Options: [ None, Nested, HasUniqueName ] | ||
| 190 | FieldList: 4101 | ||
| 191 | Name: '__vc_attributes::moduleAttribute::type_e' | ||
| 192 | UniqueName: '.?AW4type_e@moduleAttribute@__vc_attributes@@' | ||
| 193 | UnderlyingType: 116 | ||
| 194 | - Kind: LF_STRING_ID | ||
| 195 | StringId: | ||
| 196 | Id: 0 | ||
| 197 | String: 'd:\src\llvmbuild\cl\debug\x64\predefined c++ attributes (compiler internal)' | ||
| 198 | - Kind: LF_UDT_SRC_LINE | ||
| 199 | UdtSourceLine: | ||
| 200 | UDT: 4102 | ||
| 201 | SourceFile: 4103 | ||
| 202 | LineNumber: 482 | ||
| 203 | - Kind: LF_MODIFIER | ||
| 204 | Modifier: | ||
| 205 | ModifiedType: 112 | ||
| 206 | Modifiers: [ None, Const ] | ||
| 207 | - Kind: LF_POINTER | ||
| 208 | Pointer: | ||
| 209 | ReferentType: 4105 | ||
| 210 | Attrs: 65548 | ||
| 211 | - Kind: LF_ARGLIST | ||
| 212 | ArgList: | ||
| 213 | ArgIndices: [ 4102, 4106, 4106, 4106, 116, 48, 4106, 116, | ||
| 214 | 4106, 4106, 116, 48, 48, 4106, 4106 ] | ||
| 215 | - Kind: LF_POINTER | ||
| 216 | Pointer: | ||
| 217 | ReferentType: 4100 | ||
| 218 | Attrs: 66572 | ||
| 219 | - Kind: LF_MFUNCTION | ||
| 220 | MemberFunction: | ||
| 221 | ReturnType: 3 | ||
| 222 | ClassType: 4100 | ||
| 223 | ThisType: 4108 | ||
| 224 | CallConv: NearC | ||
| 225 | Options: [ None, Constructor ] | ||
| 226 | ParameterCount: 15 | ||
| 227 | ArgumentList: 4107 | ||
| 228 | ThisPointerAdjustment: 0 | ||
| 229 | - Kind: LF_ARGLIST | ||
| 230 | ArgList: | ||
| 231 | ArgIndices: [ 4102 ] | ||
| 232 | - Kind: LF_MFUNCTION | ||
| 233 | MemberFunction: | ||
| 234 | ReturnType: 3 | ||
| 235 | ClassType: 4100 | ||
| 236 | ThisType: 4108 | ||
| 237 | CallConv: NearC | ||
| 238 | Options: [ None, Constructor ] | ||
| 239 | ParameterCount: 1 | ||
| 240 | ArgumentList: 4110 | ||
| 241 | ThisPointerAdjustment: 0 | ||
| 242 | - Kind: LF_ARGLIST | ||
| 243 | ArgList: | ||
| 244 | ArgIndices: [ ] | ||
| 245 | - Kind: LF_MFUNCTION | ||
| 246 | MemberFunction: | ||
| 247 | ReturnType: 3 | ||
| 248 | ClassType: 4100 | ||
| 249 | ThisType: 4108 | ||
| 250 | CallConv: NearC | ||
| 251 | Options: [ None, Constructor ] | ||
| 252 | ParameterCount: 0 | ||
| 253 | ArgumentList: 4112 | ||
| 254 | ThisPointerAdjustment: 0 | ||
| 255 | - Kind: LF_METHODLIST | ||
| 256 | MethodOverloadList: | ||
| 257 | Methods: | ||
| 258 | - Type: 4109 | ||
| 259 | Attrs: 3 | ||
| 260 | VFTableOffset: -1 | ||
| 261 | Name: '' | ||
| 262 | - Type: 4111 | ||
| 263 | Attrs: 3 | ||
| 264 | VFTableOffset: -1 | ||
| 265 | Name: '' | ||
| 266 | - Type: 4113 | ||
| 267 | Attrs: 3 | ||
| 268 | VFTableOffset: -1 | ||
| 269 | Name: '' | ||
| 270 | - Kind: LF_FIELDLIST | ||
| 271 | FieldList: | ||
| 272 | - Kind: LF_NESTTYPE | ||
| 273 | NestedType: | ||
| 274 | Type: 4102 | ||
| 275 | Name: type_e | ||
| 276 | - Kind: LF_METHOD | ||
| 277 | OverloadedMethod: | ||
| 278 | NumOverloads: 3 | ||
| 279 | MethodList: 4114 | ||
| 280 | Name: moduleAttribute | ||
| 281 | - Kind: LF_MEMBER | ||
| 282 | DataMember: | ||
| 283 | Attrs: 3 | ||
| 284 | Type: 4102 | ||
| 285 | FieldOffset: 0 | ||
| 286 | Name: type | ||
| 287 | - Kind: LF_MEMBER | ||
| 288 | DataMember: | ||
| 289 | Attrs: 3 | ||
| 290 | Type: 4106 | ||
| 291 | FieldOffset: 8 | ||
| 292 | Name: name | ||
| 293 | - Kind: LF_MEMBER | ||
| 294 | DataMember: | ||
| 295 | Attrs: 3 | ||
| 296 | Type: 4106 | ||
| 297 | FieldOffset: 16 | ||
| 298 | Name: version | ||
| 299 | - Kind: LF_MEMBER | ||
| 300 | DataMember: | ||
| 301 | Attrs: 3 | ||
| 302 | Type: 4106 | ||
| 303 | FieldOffset: 24 | ||
| 304 | Name: uuid | ||
| 305 | - Kind: LF_MEMBER | ||
| 306 | DataMember: | ||
| 307 | Attrs: 3 | ||
| 308 | Type: 116 | ||
| 309 | FieldOffset: 32 | ||
| 310 | Name: lcid | ||
| 311 | - Kind: LF_MEMBER | ||
| 312 | DataMember: | ||
| 313 | Attrs: 3 | ||
| 314 | Type: 48 | ||
| 315 | FieldOffset: 36 | ||
| 316 | Name: control | ||
| 317 | - Kind: LF_MEMBER | ||
| 318 | DataMember: | ||
| 319 | Attrs: 3 | ||
| 320 | Type: 4106 | ||
| 321 | FieldOffset: 40 | ||
| 322 | Name: helpstring | ||
| 323 | - Kind: LF_MEMBER | ||
| 324 | DataMember: | ||
| 325 | Attrs: 3 | ||
| 326 | Type: 116 | ||
| 327 | FieldOffset: 48 | ||
| 328 | Name: helpstringcontext | ||
| 329 | - Kind: LF_MEMBER | ||
| 330 | DataMember: | ||
| 331 | Attrs: 3 | ||
| 332 | Type: 4106 | ||
| 333 | FieldOffset: 56 | ||
| 334 | Name: helpstringdll | ||
| 335 | - Kind: LF_MEMBER | ||
| 336 | DataMember: | ||
| 337 | Attrs: 3 | ||
| 338 | Type: 4106 | ||
| 339 | FieldOffset: 64 | ||
| 340 | Name: helpfile | ||
| 341 | - Kind: LF_MEMBER | ||
| 342 | DataMember: | ||
| 343 | Attrs: 3 | ||
| 344 | Type: 116 | ||
| 345 | FieldOffset: 72 | ||
| 346 | Name: helpcontext | ||
| 347 | - Kind: LF_MEMBER | ||
| 348 | DataMember: | ||
| 349 | Attrs: 3 | ||
| 350 | Type: 48 | ||
| 351 | FieldOffset: 76 | ||
| 352 | Name: hidden | ||
| 353 | - Kind: LF_MEMBER | ||
| 354 | DataMember: | ||
| 355 | Attrs: 3 | ||
| 356 | Type: 48 | ||
| 357 | FieldOffset: 77 | ||
| 358 | Name: restricted | ||
| 359 | - Kind: LF_MEMBER | ||
| 360 | DataMember: | ||
| 361 | Attrs: 3 | ||
| 362 | Type: 4106 | ||
| 363 | FieldOffset: 80 | ||
| 364 | Name: custom | ||
| 365 | - Kind: LF_MEMBER | ||
| 366 | DataMember: | ||
| 367 | Attrs: 3 | ||
| 368 | Type: 4106 | ||
| 369 | FieldOffset: 88 | ||
| 370 | Name: resource_name | ||
| 371 | - Kind: LF_STRUCTURE | ||
| 372 | Class: | ||
| 373 | MemberCount: 19 | ||
| 374 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 375 | FieldList: 4115 | ||
| 376 | Name: '__vc_attributes::moduleAttribute' | ||
| 377 | UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' | ||
| 378 | DerivationList: 0 | ||
| 379 | VTableShape: 0 | ||
| 380 | Size: 96 | ||
| 381 | - Kind: LF_UDT_SRC_LINE | ||
| 382 | UdtSourceLine: | ||
| 383 | UDT: 4116 | ||
| 384 | SourceFile: 4103 | ||
| 385 | LineNumber: 481 | ||
| 386 | - Kind: LF_STRUCTURE | ||
| 387 | Class: | ||
| 388 | MemberCount: 0 | ||
| 389 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 390 | FieldList: 0 | ||
| 391 | Name: '__vc_attributes::event_receiverAttribute' | ||
| 392 | UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' | ||
| 393 | DerivationList: 0 | ||
| 394 | VTableShape: 0 | ||
| 395 | Size: 0 | ||
| 396 | - Kind: LF_FIELDLIST | ||
| 397 | FieldList: | ||
| 398 | - Kind: LF_ENUMERATE | ||
| 399 | Enumerator: | ||
| 400 | Attrs: 3 | ||
| 401 | Value: 0 | ||
| 402 | Name: native | ||
| 403 | - Kind: LF_ENUMERATE | ||
| 404 | Enumerator: | ||
| 405 | Attrs: 3 | ||
| 406 | Value: 1 | ||
| 407 | Name: com | ||
| 408 | - Kind: LF_ENUMERATE | ||
| 409 | Enumerator: | ||
| 410 | Attrs: 3 | ||
| 411 | Value: 2 | ||
| 412 | Name: managed | ||
| 413 | - Kind: LF_ENUM | ||
| 414 | Enum: | ||
| 415 | NumEnumerators: 3 | ||
| 416 | Options: [ None, Nested, HasUniqueName ] | ||
| 417 | FieldList: 4119 | ||
| 418 | Name: '__vc_attributes::event_receiverAttribute::type_e' | ||
| 419 | UniqueName: '.?AW4type_e@event_receiverAttribute@__vc_attributes@@' | ||
| 420 | UnderlyingType: 116 | ||
| 421 | - Kind: LF_UDT_SRC_LINE | ||
| 422 | UdtSourceLine: | ||
| 423 | UDT: 4120 | ||
| 424 | SourceFile: 4103 | ||
| 425 | LineNumber: 136 | ||
| 426 | - Kind: LF_ARGLIST | ||
| 427 | ArgList: | ||
| 428 | ArgIndices: [ 4120, 48 ] | ||
| 429 | - Kind: LF_POINTER | ||
| 430 | Pointer: | ||
| 431 | ReferentType: 4118 | ||
| 432 | Attrs: 66572 | ||
| 433 | - Kind: LF_MFUNCTION | ||
| 434 | MemberFunction: | ||
| 435 | ReturnType: 3 | ||
| 436 | ClassType: 4118 | ||
| 437 | ThisType: 4123 | ||
| 438 | CallConv: NearC | ||
| 439 | Options: [ None, Constructor ] | ||
| 440 | ParameterCount: 2 | ||
| 441 | ArgumentList: 4122 | ||
| 442 | ThisPointerAdjustment: 0 | ||
| 443 | - Kind: LF_ARGLIST | ||
| 444 | ArgList: | ||
| 445 | ArgIndices: [ 4120 ] | ||
| 446 | - Kind: LF_MFUNCTION | ||
| 447 | MemberFunction: | ||
| 448 | ReturnType: 3 | ||
| 449 | ClassType: 4118 | ||
| 450 | ThisType: 4123 | ||
| 451 | CallConv: NearC | ||
| 452 | Options: [ None, Constructor ] | ||
| 453 | ParameterCount: 1 | ||
| 454 | ArgumentList: 4125 | ||
| 455 | ThisPointerAdjustment: 0 | ||
| 456 | - Kind: LF_MFUNCTION | ||
| 457 | MemberFunction: | ||
| 458 | ReturnType: 3 | ||
| 459 | ClassType: 4118 | ||
| 460 | ThisType: 4123 | ||
| 461 | CallConv: NearC | ||
| 462 | Options: [ None, Constructor ] | ||
| 463 | ParameterCount: 0 | ||
| 464 | ArgumentList: 4112 | ||
| 465 | ThisPointerAdjustment: 0 | ||
| 466 | - Kind: LF_METHODLIST | ||
| 467 | MethodOverloadList: | ||
| 468 | Methods: | ||
| 469 | - Type: 4124 | ||
| 470 | Attrs: 3 | ||
| 471 | VFTableOffset: -1 | ||
| 472 | Name: '' | ||
| 473 | - Type: 4126 | ||
| 474 | Attrs: 3 | ||
| 475 | VFTableOffset: -1 | ||
| 476 | Name: '' | ||
| 477 | - Type: 4127 | ||
| 478 | Attrs: 3 | ||
| 479 | VFTableOffset: -1 | ||
| 480 | Name: '' | ||
| 481 | - Kind: LF_FIELDLIST | ||
| 482 | FieldList: | ||
| 483 | - Kind: LF_NESTTYPE | ||
| 484 | NestedType: | ||
| 485 | Type: 4120 | ||
| 486 | Name: type_e | ||
| 487 | - Kind: LF_METHOD | ||
| 488 | OverloadedMethod: | ||
| 489 | NumOverloads: 3 | ||
| 490 | MethodList: 4128 | ||
| 491 | Name: event_receiverAttribute | ||
| 492 | - Kind: LF_MEMBER | ||
| 493 | DataMember: | ||
| 494 | Attrs: 3 | ||
| 495 | Type: 4120 | ||
| 496 | FieldOffset: 0 | ||
| 497 | Name: type | ||
| 498 | - Kind: LF_MEMBER | ||
| 499 | DataMember: | ||
| 500 | Attrs: 3 | ||
| 501 | Type: 48 | ||
| 502 | FieldOffset: 4 | ||
| 503 | Name: layout_dependent | ||
| 504 | - Kind: LF_STRUCTURE | ||
| 505 | Class: | ||
| 506 | MemberCount: 6 | ||
| 507 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 508 | FieldList: 4129 | ||
| 509 | Name: '__vc_attributes::event_receiverAttribute' | ||
| 510 | UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' | ||
| 511 | DerivationList: 0 | ||
| 512 | VTableShape: 0 | ||
| 513 | Size: 8 | ||
| 514 | - Kind: LF_UDT_SRC_LINE | ||
| 515 | UdtSourceLine: | ||
| 516 | UDT: 4130 | ||
| 517 | SourceFile: 4103 | ||
| 518 | LineNumber: 135 | ||
| 519 | - Kind: LF_STRUCTURE | ||
| 520 | Class: | ||
| 521 | MemberCount: 0 | ||
| 522 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 523 | FieldList: 0 | ||
| 524 | Name: '__vc_attributes::aggregatableAttribute' | ||
| 525 | UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' | ||
| 526 | DerivationList: 0 | ||
| 527 | VTableShape: 0 | ||
| 528 | Size: 0 | ||
| 529 | - Kind: LF_FIELDLIST | ||
| 530 | FieldList: | ||
| 531 | - Kind: LF_ENUMERATE | ||
| 532 | Enumerator: | ||
| 533 | Attrs: 3 | ||
| 534 | Value: 0 | ||
| 535 | Name: never | ||
| 536 | - Kind: LF_ENUMERATE | ||
| 537 | Enumerator: | ||
| 538 | Attrs: 3 | ||
| 539 | Value: 1 | ||
| 540 | Name: allowed | ||
| 541 | - Kind: LF_ENUMERATE | ||
| 542 | Enumerator: | ||
| 543 | Attrs: 3 | ||
| 544 | Value: 2 | ||
| 545 | Name: always | ||
| 546 | - Kind: LF_ENUM | ||
| 547 | Enum: | ||
| 548 | NumEnumerators: 3 | ||
| 549 | Options: [ None, Nested, HasUniqueName ] | ||
| 550 | FieldList: 4133 | ||
| 551 | Name: '__vc_attributes::aggregatableAttribute::type_e' | ||
| 552 | UniqueName: '.?AW4type_e@aggregatableAttribute@__vc_attributes@@' | ||
| 553 | UnderlyingType: 116 | ||
| 554 | - Kind: LF_UDT_SRC_LINE | ||
| 555 | UdtSourceLine: | ||
| 556 | UDT: 4134 | ||
| 557 | SourceFile: 4103 | ||
| 558 | LineNumber: 545 | ||
| 559 | - Kind: LF_ARGLIST | ||
| 560 | ArgList: | ||
| 561 | ArgIndices: [ 4134 ] | ||
| 562 | - Kind: LF_POINTER | ||
| 563 | Pointer: | ||
| 564 | ReferentType: 4132 | ||
| 565 | Attrs: 66572 | ||
| 566 | - Kind: LF_MFUNCTION | ||
| 567 | MemberFunction: | ||
| 568 | ReturnType: 3 | ||
| 569 | ClassType: 4132 | ||
| 570 | ThisType: 4137 | ||
| 571 | CallConv: NearC | ||
| 572 | Options: [ None, Constructor ] | ||
| 573 | ParameterCount: 1 | ||
| 574 | ArgumentList: 4136 | ||
| 575 | ThisPointerAdjustment: 0 | ||
| 576 | - Kind: LF_MFUNCTION | ||
| 577 | MemberFunction: | ||
| 578 | ReturnType: 3 | ||
| 579 | ClassType: 4132 | ||
| 580 | ThisType: 4137 | ||
| 581 | CallConv: NearC | ||
| 582 | Options: [ None, Constructor ] | ||
| 583 | ParameterCount: 0 | ||
| 584 | ArgumentList: 4112 | ||
| 585 | ThisPointerAdjustment: 0 | ||
| 586 | - Kind: LF_METHODLIST | ||
| 587 | MethodOverloadList: | ||
| 588 | Methods: | ||
| 589 | - Type: 4138 | ||
| 590 | Attrs: 3 | ||
| 591 | VFTableOffset: -1 | ||
| 592 | Name: '' | ||
| 593 | - Type: 4139 | ||
| 594 | Attrs: 3 | ||
| 595 | VFTableOffset: -1 | ||
| 596 | Name: '' | ||
| 597 | - Kind: LF_FIELDLIST | ||
| 598 | FieldList: | ||
| 599 | - Kind: LF_NESTTYPE | ||
| 600 | NestedType: | ||
| 601 | Type: 4134 | ||
| 602 | Name: type_e | ||
| 603 | - Kind: LF_METHOD | ||
| 604 | OverloadedMethod: | ||
| 605 | NumOverloads: 2 | ||
| 606 | MethodList: 4140 | ||
| 607 | Name: aggregatableAttribute | ||
| 608 | - Kind: LF_MEMBER | ||
| 609 | DataMember: | ||
| 610 | Attrs: 3 | ||
| 611 | Type: 4134 | ||
| 612 | FieldOffset: 0 | ||
| 613 | Name: type | ||
| 614 | - Kind: LF_STRUCTURE | ||
| 615 | Class: | ||
| 616 | MemberCount: 4 | ||
| 617 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 618 | FieldList: 4141 | ||
| 619 | Name: '__vc_attributes::aggregatableAttribute' | ||
| 620 | UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' | ||
| 621 | DerivationList: 0 | ||
| 622 | VTableShape: 0 | ||
| 623 | Size: 4 | ||
| 624 | - Kind: LF_UDT_SRC_LINE | ||
| 625 | UdtSourceLine: | ||
| 626 | UDT: 4142 | ||
| 627 | SourceFile: 4103 | ||
| 628 | LineNumber: 544 | ||
| 629 | - Kind: LF_STRUCTURE | ||
| 630 | Class: | ||
| 631 | MemberCount: 0 | ||
| 632 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 633 | FieldList: 0 | ||
| 634 | Name: '__vc_attributes::threadingAttribute' | ||
| 635 | UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' | ||
| 636 | DerivationList: 0 | ||
| 637 | VTableShape: 0 | ||
| 638 | Size: 0 | ||
| 639 | - Kind: LF_FIELDLIST | ||
| 640 | FieldList: | ||
| 641 | - Kind: LF_ENUMERATE | ||
| 642 | Enumerator: | ||
| 643 | Attrs: 3 | ||
| 644 | Value: 1 | ||
| 645 | Name: apartment | ||
| 646 | - Kind: LF_ENUMERATE | ||
| 647 | Enumerator: | ||
| 648 | Attrs: 3 | ||
| 649 | Value: 2 | ||
| 650 | Name: single | ||
| 651 | - Kind: LF_ENUMERATE | ||
| 652 | Enumerator: | ||
| 653 | Attrs: 3 | ||
| 654 | Value: 3 | ||
| 655 | Name: free | ||
| 656 | - Kind: LF_ENUMERATE | ||
| 657 | Enumerator: | ||
| 658 | Attrs: 3 | ||
| 659 | Value: 4 | ||
| 660 | Name: neutral | ||
| 661 | - Kind: LF_ENUMERATE | ||
| 662 | Enumerator: | ||
| 663 | Attrs: 3 | ||
| 664 | Value: 5 | ||
| 665 | Name: both | ||
| 666 | - Kind: LF_ENUM | ||
| 667 | Enum: | ||
| 668 | NumEnumerators: 5 | ||
| 669 | Options: [ None, Nested, HasUniqueName ] | ||
| 670 | FieldList: 4145 | ||
| 671 | Name: '__vc_attributes::threadingAttribute::threading_e' | ||
| 672 | UniqueName: '.?AW4threading_e@threadingAttribute@__vc_attributes@@' | ||
| 673 | UnderlyingType: 116 | ||
| 674 | - Kind: LF_UDT_SRC_LINE | ||
| 675 | UdtSourceLine: | ||
| 676 | UDT: 4146 | ||
| 677 | SourceFile: 4103 | ||
| 678 | LineNumber: 423 | ||
| 679 | - Kind: LF_ARGLIST | ||
| 680 | ArgList: | ||
| 681 | ArgIndices: [ 4146 ] | ||
| 682 | - Kind: LF_POINTER | ||
| 683 | Pointer: | ||
| 684 | ReferentType: 4144 | ||
| 685 | Attrs: 66572 | ||
| 686 | - Kind: LF_MFUNCTION | ||
| 687 | MemberFunction: | ||
| 688 | ReturnType: 3 | ||
| 689 | ClassType: 4144 | ||
| 690 | ThisType: 4149 | ||
| 691 | CallConv: NearC | ||
| 692 | Options: [ None, Constructor ] | ||
| 693 | ParameterCount: 1 | ||
| 694 | ArgumentList: 4148 | ||
| 695 | ThisPointerAdjustment: 0 | ||
| 696 | - Kind: LF_MFUNCTION | ||
| 697 | MemberFunction: | ||
| 698 | ReturnType: 3 | ||
| 699 | ClassType: 4144 | ||
| 700 | ThisType: 4149 | ||
| 701 | CallConv: NearC | ||
| 702 | Options: [ None, Constructor ] | ||
| 703 | ParameterCount: 0 | ||
| 704 | ArgumentList: 4112 | ||
| 705 | ThisPointerAdjustment: 0 | ||
| 706 | - Kind: LF_METHODLIST | ||
| 707 | MethodOverloadList: | ||
| 708 | Methods: | ||
| 709 | - Type: 4150 | ||
| 710 | Attrs: 3 | ||
| 711 | VFTableOffset: -1 | ||
| 712 | Name: '' | ||
| 713 | - Type: 4151 | ||
| 714 | Attrs: 3 | ||
| 715 | VFTableOffset: -1 | ||
| 716 | Name: '' | ||
| 717 | - Kind: LF_FIELDLIST | ||
| 718 | FieldList: | ||
| 719 | - Kind: LF_NESTTYPE | ||
| 720 | NestedType: | ||
| 721 | Type: 4146 | ||
| 722 | Name: threading_e | ||
| 723 | - Kind: LF_METHOD | ||
| 724 | OverloadedMethod: | ||
| 725 | NumOverloads: 2 | ||
| 726 | MethodList: 4152 | ||
| 727 | Name: threadingAttribute | ||
| 728 | - Kind: LF_MEMBER | ||
| 729 | DataMember: | ||
| 730 | Attrs: 3 | ||
| 731 | Type: 4146 | ||
| 732 | FieldOffset: 0 | ||
| 733 | Name: value | ||
| 734 | - Kind: LF_STRUCTURE | ||
| 735 | Class: | ||
| 736 | MemberCount: 4 | ||
| 737 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 738 | FieldList: 4153 | ||
| 739 | Name: '__vc_attributes::threadingAttribute' | ||
| 740 | UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' | ||
| 741 | DerivationList: 0 | ||
| 742 | VTableShape: 0 | ||
| 743 | Size: 4 | ||
| 744 | - Kind: LF_UDT_SRC_LINE | ||
| 745 | UdtSourceLine: | ||
| 746 | UDT: 4154 | ||
| 747 | SourceFile: 4103 | ||
| 748 | LineNumber: 422 | ||
| 749 | - Kind: LF_STRUCTURE | ||
| 750 | Class: | ||
| 751 | MemberCount: 0 | ||
| 752 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 753 | FieldList: 0 | ||
| 754 | Name: '__vc_attributes::helper_attributes::usageAttribute' | ||
| 755 | UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' | ||
| 756 | DerivationList: 0 | ||
| 757 | VTableShape: 0 | ||
| 758 | Size: 0 | ||
| 759 | - Kind: LF_FIELDLIST | ||
| 760 | FieldList: | ||
| 761 | - Kind: LF_ENUMERATE | ||
| 762 | Enumerator: | ||
| 763 | Attrs: 3 | ||
| 764 | Value: 0 | ||
| 765 | Name: eAnyUsage | ||
| 766 | - Kind: LF_ENUMERATE | ||
| 767 | Enumerator: | ||
| 768 | Attrs: 3 | ||
| 769 | Value: 1 | ||
| 770 | Name: eCoClassUsage | ||
| 771 | - Kind: LF_ENUMERATE | ||
| 772 | Enumerator: | ||
| 773 | Attrs: 3 | ||
| 774 | Value: 2 | ||
| 775 | Name: eCOMInterfaceUsage | ||
| 776 | - Kind: LF_ENUMERATE | ||
| 777 | Enumerator: | ||
| 778 | Attrs: 3 | ||
| 779 | Value: 6 | ||
| 780 | Name: eInterfaceUsage | ||
| 781 | - Kind: LF_ENUMERATE | ||
| 782 | Enumerator: | ||
| 783 | Attrs: 3 | ||
| 784 | Value: 8 | ||
| 785 | Name: eMemberUsage | ||
| 786 | - Kind: LF_ENUMERATE | ||
| 787 | Enumerator: | ||
| 788 | Attrs: 3 | ||
| 789 | Value: 16 | ||
| 790 | Name: eMethodUsage | ||
| 791 | - Kind: LF_ENUMERATE | ||
| 792 | Enumerator: | ||
| 793 | Attrs: 3 | ||
| 794 | Value: 32 | ||
| 795 | Name: eInterfaceMethodUsage | ||
| 796 | - Kind: LF_ENUMERATE | ||
| 797 | Enumerator: | ||
| 798 | Attrs: 3 | ||
| 799 | Value: 64 | ||
| 800 | Name: eInterfaceMemberUsage | ||
| 801 | - Kind: LF_ENUMERATE | ||
| 802 | Enumerator: | ||
| 803 | Attrs: 3 | ||
| 804 | Value: 128 | ||
| 805 | Name: eCoClassMemberUsage | ||
| 806 | - Kind: LF_ENUMERATE | ||
| 807 | Enumerator: | ||
| 808 | Attrs: 3 | ||
| 809 | Value: 256 | ||
| 810 | Name: eCoClassMethodUsage | ||
| 811 | - Kind: LF_ENUMERATE | ||
| 812 | Enumerator: | ||
| 813 | Attrs: 3 | ||
| 814 | Value: 768 | ||
| 815 | Name: eGlobalMethodUsage | ||
| 816 | - Kind: LF_ENUMERATE | ||
| 817 | Enumerator: | ||
| 818 | Attrs: 3 | ||
| 819 | Value: 1024 | ||
| 820 | Name: eGlobalDataUsage | ||
| 821 | - Kind: LF_ENUMERATE | ||
| 822 | Enumerator: | ||
| 823 | Attrs: 3 | ||
| 824 | Value: 2048 | ||
| 825 | Name: eClassUsage | ||
| 826 | - Kind: LF_ENUMERATE | ||
| 827 | Enumerator: | ||
| 828 | Attrs: 3 | ||
| 829 | Value: 4096 | ||
| 830 | Name: eInterfaceParameterUsage | ||
| 831 | - Kind: LF_ENUMERATE | ||
| 832 | Enumerator: | ||
| 833 | Attrs: 3 | ||
| 834 | Value: 12288 | ||
| 835 | Name: eMethodParameterUsage | ||
| 836 | - Kind: LF_ENUMERATE | ||
| 837 | Enumerator: | ||
| 838 | Attrs: 3 | ||
| 839 | Value: 16384 | ||
| 840 | Name: eIDLModuleUsage | ||
| 841 | - Kind: LF_ENUMERATE | ||
| 842 | Enumerator: | ||
| 843 | Attrs: 3 | ||
| 844 | Value: 32768 | ||
| 845 | Name: eAnonymousUsage | ||
| 846 | - Kind: LF_ENUMERATE | ||
| 847 | Enumerator: | ||
| 848 | Attrs: 3 | ||
| 849 | Value: 65536 | ||
| 850 | Name: eTypedefUsage | ||
| 851 | - Kind: LF_ENUMERATE | ||
| 852 | Enumerator: | ||
| 853 | Attrs: 3 | ||
| 854 | Value: 131072 | ||
| 855 | Name: eUnionUsage | ||
| 856 | - Kind: LF_ENUMERATE | ||
| 857 | Enumerator: | ||
| 858 | Attrs: 3 | ||
| 859 | Value: 262144 | ||
| 860 | Name: eEnumUsage | ||
| 861 | - Kind: LF_ENUMERATE | ||
| 862 | Enumerator: | ||
| 863 | Attrs: 3 | ||
| 864 | Value: 524288 | ||
| 865 | Name: eDefineTagUsage | ||
| 866 | - Kind: LF_ENUMERATE | ||
| 867 | Enumerator: | ||
| 868 | Attrs: 3 | ||
| 869 | Value: 1048576 | ||
| 870 | Name: eStructUsage | ||
| 871 | - Kind: LF_ENUMERATE | ||
| 872 | Enumerator: | ||
| 873 | Attrs: 3 | ||
| 874 | Value: 2097152 | ||
| 875 | Name: eLocalUsage | ||
| 876 | - Kind: LF_ENUMERATE | ||
| 877 | Enumerator: | ||
| 878 | Attrs: 3 | ||
| 879 | Value: 4194304 | ||
| 880 | Name: ePropertyUsage | ||
| 881 | - Kind: LF_ENUMERATE | ||
| 882 | Enumerator: | ||
| 883 | Attrs: 3 | ||
| 884 | Value: 8388608 | ||
| 885 | Name: eEventUsage | ||
| 886 | - Kind: LF_ENUMERATE | ||
| 887 | Enumerator: | ||
| 888 | Attrs: 3 | ||
| 889 | Value: 16777216 | ||
| 890 | Name: eTemplateUsage | ||
| 891 | - Kind: LF_ENUMERATE | ||
| 892 | Enumerator: | ||
| 893 | Attrs: 3 | ||
| 894 | Value: 16777216 | ||
| 895 | Name: eModuleUsage | ||
| 896 | - Kind: LF_ENUMERATE | ||
| 897 | Enumerator: | ||
| 898 | Attrs: 3 | ||
| 899 | Value: 33554432 | ||
| 900 | Name: eIllegalUsage | ||
| 901 | - Kind: LF_ENUMERATE | ||
| 902 | Enumerator: | ||
| 903 | Attrs: 3 | ||
| 904 | Value: 67108864 | ||
| 905 | Name: eAsynchronousUsage | ||
| 906 | - Kind: LF_ENUMERATE | ||
| 907 | Enumerator: | ||
| 908 | Attrs: 3 | ||
| 909 | Value: 4161535 | ||
| 910 | Name: eAnyIDLUsage | ||
| 911 | - Kind: LF_ENUM | ||
| 912 | Enum: | ||
| 913 | NumEnumerators: 30 | ||
| 914 | Options: [ None, Nested, HasUniqueName ] | ||
| 915 | FieldList: 4157 | ||
| 916 | Name: '__vc_attributes::helper_attributes::usageAttribute::usage_e' | ||
| 917 | UniqueName: '.?AW4usage_e@usageAttribute@helper_attributes@__vc_attributes@@' | ||
| 918 | UnderlyingType: 116 | ||
| 919 | - Kind: LF_UDT_SRC_LINE | ||
| 920 | UdtSourceLine: | ||
| 921 | UDT: 4158 | ||
| 922 | SourceFile: 4103 | ||
| 923 | LineNumber: 51 | ||
| 924 | - Kind: LF_ARGLIST | ||
| 925 | ArgList: | ||
| 926 | ArgIndices: [ 117 ] | ||
| 927 | - Kind: LF_POINTER | ||
| 928 | Pointer: | ||
| 929 | ReferentType: 4156 | ||
| 930 | Attrs: 66572 | ||
| 931 | - Kind: LF_MFUNCTION | ||
| 932 | MemberFunction: | ||
| 933 | ReturnType: 3 | ||
| 934 | ClassType: 4156 | ||
| 935 | ThisType: 4161 | ||
| 936 | CallConv: NearC | ||
| 937 | Options: [ None, Constructor ] | ||
| 938 | ParameterCount: 1 | ||
| 939 | ArgumentList: 4160 | ||
| 940 | ThisPointerAdjustment: 0 | ||
| 941 | - Kind: LF_FIELDLIST | ||
| 942 | FieldList: | ||
| 943 | - Kind: LF_NESTTYPE | ||
| 944 | NestedType: | ||
| 945 | Type: 4158 | ||
| 946 | Name: usage_e | ||
| 947 | - Kind: LF_ONEMETHOD | ||
| 948 | OneMethod: | ||
| 949 | Type: 4162 | ||
| 950 | Attrs: 3 | ||
| 951 | VFTableOffset: -1 | ||
| 952 | Name: usageAttribute | ||
| 953 | - Kind: LF_MEMBER | ||
| 954 | DataMember: | ||
| 955 | Attrs: 3 | ||
| 956 | Type: 117 | ||
| 957 | FieldOffset: 0 | ||
| 958 | Name: value | ||
| 959 | - Kind: LF_STRUCTURE | ||
| 960 | Class: | ||
| 961 | MemberCount: 3 | ||
| 962 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 963 | FieldList: 4163 | ||
| 964 | Name: '__vc_attributes::helper_attributes::usageAttribute' | ||
| 965 | UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' | ||
| 966 | DerivationList: 0 | ||
| 967 | VTableShape: 0 | ||
| 968 | Size: 4 | ||
| 969 | - Kind: LF_UDT_SRC_LINE | ||
| 970 | UdtSourceLine: | ||
| 971 | UDT: 4164 | ||
| 972 | SourceFile: 4103 | ||
| 973 | LineNumber: 49 | ||
| 974 | - Kind: LF_STRUCTURE | ||
| 975 | Class: | ||
| 976 | MemberCount: 0 | ||
| 977 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 978 | FieldList: 0 | ||
| 979 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | ||
| 980 | UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' | ||
| 981 | DerivationList: 0 | ||
| 982 | VTableShape: 0 | ||
| 983 | Size: 0 | ||
| 984 | - Kind: LF_FIELDLIST | ||
| 985 | FieldList: | ||
| 986 | - Kind: LF_ENUMERATE | ||
| 987 | Enumerator: | ||
| 988 | Attrs: 3 | ||
| 989 | Value: 0 | ||
| 990 | Name: eBoolean | ||
| 991 | - Kind: LF_ENUMERATE | ||
| 992 | Enumerator: | ||
| 993 | Attrs: 3 | ||
| 994 | Value: 1 | ||
| 995 | Name: eInteger | ||
| 996 | - Kind: LF_ENUMERATE | ||
| 997 | Enumerator: | ||
| 998 | Attrs: 3 | ||
| 999 | Value: 2 | ||
| 1000 | Name: eFloat | ||
| 1001 | - Kind: LF_ENUMERATE | ||
| 1002 | Enumerator: | ||
| 1003 | Attrs: 3 | ||
| 1004 | Value: 3 | ||
| 1005 | Name: eDouble | ||
| 1006 | - Kind: LF_ENUM | ||
| 1007 | Enum: | ||
| 1008 | NumEnumerators: 4 | ||
| 1009 | Options: [ None, Nested, HasUniqueName ] | ||
| 1010 | FieldList: 4167 | ||
| 1011 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e' | ||
| 1012 | UniqueName: '.?AW4type_e@v1_alttypeAttribute@helper_attributes@__vc_attributes@@' | ||
| 1013 | UnderlyingType: 116 | ||
| 1014 | - Kind: LF_UDT_SRC_LINE | ||
| 1015 | UdtSourceLine: | ||
| 1016 | UDT: 4168 | ||
| 1017 | SourceFile: 4103 | ||
| 1018 | LineNumber: 38 | ||
| 1019 | - Kind: LF_ARGLIST | ||
| 1020 | ArgList: | ||
| 1021 | ArgIndices: [ 4168 ] | ||
| 1022 | - Kind: LF_POINTER | ||
| 1023 | Pointer: | ||
| 1024 | ReferentType: 4166 | ||
| 1025 | Attrs: 66572 | ||
| 1026 | - Kind: LF_MFUNCTION | ||
| 1027 | MemberFunction: | ||
| 1028 | ReturnType: 3 | ||
| 1029 | ClassType: 4166 | ||
| 1030 | ThisType: 4171 | ||
| 1031 | CallConv: NearC | ||
| 1032 | Options: [ None, Constructor ] | ||
| 1033 | ParameterCount: 1 | ||
| 1034 | ArgumentList: 4170 | ||
| 1035 | ThisPointerAdjustment: 0 | ||
| 1036 | - Kind: LF_FIELDLIST | ||
| 1037 | FieldList: | ||
| 1038 | - Kind: LF_NESTTYPE | ||
| 1039 | NestedType: | ||
| 1040 | Type: 4168 | ||
| 1041 | Name: type_e | ||
| 1042 | - Kind: LF_ONEMETHOD | ||
| 1043 | OneMethod: | ||
| 1044 | Type: 4172 | ||
| 1045 | Attrs: 3 | ||
| 1046 | VFTableOffset: -1 | ||
| 1047 | Name: v1_alttypeAttribute | ||
| 1048 | - Kind: LF_MEMBER | ||
| 1049 | DataMember: | ||
| 1050 | Attrs: 3 | ||
| 1051 | Type: 4168 | ||
| 1052 | FieldOffset: 0 | ||
| 1053 | Name: type | ||
| 1054 | - Kind: LF_STRUCTURE | ||
| 1055 | Class: | ||
| 1056 | MemberCount: 3 | ||
| 1057 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 1058 | FieldList: 4173 | ||
| 1059 | Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' | ||
| 1060 | UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' | ||
| 1061 | DerivationList: 0 | ||
| 1062 | VTableShape: 0 | ||
| 1063 | Size: 4 | ||
| 1064 | - Kind: LF_UDT_SRC_LINE | ||
| 1065 | UdtSourceLine: | ||
| 1066 | UDT: 4174 | ||
| 1067 | SourceFile: 4103 | ||
| 1068 | LineNumber: 37 | ||
| 1069 | - Kind: LF_STRUCTURE | ||
| 1070 | Class: | ||
| 1071 | MemberCount: 0 | ||
| 1072 | Options: [ None, ForwardReference, HasUniqueName ] | ||
| 1073 | FieldList: 0 | ||
| 1074 | Name: '__vc_attributes::event_sourceAttribute' | ||
| 1075 | UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' | ||
| 1076 | DerivationList: 0 | ||
| 1077 | VTableShape: 0 | ||
| 1078 | Size: 0 | ||
| 1079 | - Kind: LF_FIELDLIST | ||
| 1080 | FieldList: | ||
| 1081 | - Kind: LF_ENUMERATE | ||
| 1082 | Enumerator: | ||
| 1083 | Attrs: 3 | ||
| 1084 | Value: 0 | ||
| 1085 | Name: native | ||
| 1086 | - Kind: LF_ENUMERATE | ||
| 1087 | Enumerator: | ||
| 1088 | Attrs: 3 | ||
| 1089 | Value: 1 | ||
| 1090 | Name: com | ||
| 1091 | - Kind: LF_ENUMERATE | ||
| 1092 | Enumerator: | ||
| 1093 | Attrs: 3 | ||
| 1094 | Value: 2 | ||
| 1095 | Name: managed | ||
| 1096 | - Kind: LF_ENUM | ||
| 1097 | Enum: | ||
| 1098 | NumEnumerators: 3 | ||
| 1099 | Options: [ None, Nested, HasUniqueName ] | ||
| 1100 | FieldList: 4177 | ||
| 1101 | Name: '__vc_attributes::event_sourceAttribute::type_e' | ||
| 1102 | UniqueName: '.?AW4type_e@event_sourceAttribute@__vc_attributes@@' | ||
| 1103 | UnderlyingType: 116 | ||
| 1104 | - Kind: LF_UDT_SRC_LINE | ||
| 1105 | UdtSourceLine: | ||
| 1106 | UDT: 4178 | ||
| 1107 | SourceFile: 4103 | ||
| 1108 | LineNumber: 1142 | ||
| 1109 | - Kind: LF_FIELDLIST | ||
| 1110 | FieldList: | ||
| 1111 | - Kind: LF_ENUMERATE | ||
| 1112 | Enumerator: | ||
| 1113 | Attrs: 3 | ||
| 1114 | Value: 0 | ||
| 1115 | Name: speed | ||
| 1116 | - Kind: LF_ENUMERATE | ||
| 1117 | Enumerator: | ||
| 1118 | Attrs: 3 | ||
| 1119 | Value: 1 | ||
| 1120 | Name: size | ||
| 1121 | - Kind: LF_ENUM | ||
| 1122 | Enum: | ||
| 1123 | NumEnumerators: 2 | ||
| 1124 | Options: [ None, Nested, HasUniqueName ] | ||
| 1125 | FieldList: 4180 | ||
| 1126 | Name: '__vc_attributes::event_sourceAttribute::optimize_e' | ||
| 1127 | UniqueName: '.?AW4optimize_e@event_sourceAttribute@__vc_attributes@@' | ||
| 1128 | UnderlyingType: 116 | ||
| 1129 | - Kind: LF_UDT_SRC_LINE | ||
| 1130 | UdtSourceLine: | ||
| 1131 | UDT: 4181 | ||
| 1132 | SourceFile: 4103 | ||
| 1133 | LineNumber: 1145 | ||
| 1134 | - Kind: LF_ARGLIST | ||
| 1135 | ArgList: | ||
| 1136 | ArgIndices: [ 4178 ] | ||
| 1137 | - Kind: LF_POINTER | ||
| 1138 | Pointer: | ||
| 1139 | ReferentType: 4176 | ||
| 1140 | Attrs: 66572 | ||
| 1141 | - Kind: LF_MFUNCTION | ||
| 1142 | MemberFunction: | ||
| 1143 | ReturnType: 3 | ||
| 1144 | ClassType: 4176 | ||
| 1145 | ThisType: 4184 | ||
| 1146 | CallConv: NearC | ||
| 1147 | Options: [ None, Constructor ] | ||
| 1148 | ParameterCount: 1 | ||
| 1149 | ArgumentList: 4183 | ||
| 1150 | ThisPointerAdjustment: 0 | ||
| 1151 | - Kind: LF_MFUNCTION | ||
| 1152 | MemberFunction: | ||
| 1153 | ReturnType: 3 | ||
| 1154 | ClassType: 4176 | ||
| 1155 | ThisType: 4184 | ||
| 1156 | CallConv: NearC | ||
| 1157 | Options: [ None, Constructor ] | ||
| 1158 | ParameterCount: 0 | ||
| 1159 | ArgumentList: 4112 | ||
| 1160 | ThisPointerAdjustment: 0 | ||
| 1161 | - Kind: LF_METHODLIST | ||
| 1162 | MethodOverloadList: | ||
| 1163 | Methods: | ||
| 1164 | - Type: 4185 | ||
| 1165 | Attrs: 3 | ||
| 1166 | VFTableOffset: -1 | ||
| 1167 | Name: '' | ||
| 1168 | - Type: 4186 | ||
| 1169 | Attrs: 3 | ||
| 1170 | VFTableOffset: -1 | ||
| 1171 | Name: '' | ||
| 1172 | - Kind: LF_FIELDLIST | ||
| 1173 | FieldList: | ||
| 1174 | - Kind: LF_NESTTYPE | ||
| 1175 | NestedType: | ||
| 1176 | Type: 4178 | ||
| 1177 | Name: type_e | ||
| 1178 | - Kind: LF_NESTTYPE | ||
| 1179 | NestedType: | ||
| 1180 | Type: 4181 | ||
| 1181 | Name: optimize_e | ||
| 1182 | - Kind: LF_METHOD | ||
| 1183 | OverloadedMethod: | ||
| 1184 | NumOverloads: 2 | ||
| 1185 | MethodList: 4187 | ||
| 1186 | Name: event_sourceAttribute | ||
| 1187 | - Kind: LF_MEMBER | ||
| 1188 | DataMember: | ||
| 1189 | Attrs: 3 | ||
| 1190 | Type: 4178 | ||
| 1191 | FieldOffset: 0 | ||
| 1192 | Name: type | ||
| 1193 | - Kind: LF_MEMBER | ||
| 1194 | DataMember: | ||
| 1195 | Attrs: 3 | ||
| 1196 | Type: 4181 | ||
| 1197 | FieldOffset: 4 | ||
| 1198 | Name: optimize | ||
| 1199 | - Kind: LF_MEMBER | ||
| 1200 | DataMember: | ||
| 1201 | Attrs: 3 | ||
| 1202 | Type: 48 | ||
| 1203 | FieldOffset: 8 | ||
| 1204 | Name: decorate | ||
| 1205 | - Kind: LF_STRUCTURE | ||
| 1206 | Class: | ||
| 1207 | MemberCount: 7 | ||
| 1208 | Options: [ None, HasConstructorOrDestructor, ContainsNestedClass, HasUniqueName ] | ||
| 1209 | FieldList: 4188 | ||
| 1210 | Name: '__vc_attributes::event_sourceAttribute' | ||
| 1211 | UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' | ||
| 1212 | DerivationList: 0 | ||
| 1213 | VTableShape: 0 | ||
| 1214 | Size: 12 | ||
| 1215 | - Kind: LF_UDT_SRC_LINE | ||
| 1216 | UdtSourceLine: | ||
| 1217 | UDT: 4189 | ||
| 1218 | SourceFile: 4103 | ||
| 1219 | LineNumber: 1141 | ||
| 1220 | - Kind: LF_STRING_ID | ||
| 1221 | StringId: | ||
| 1222 | Id: 0 | ||
| 1223 | String: 'D:\src\llvmbuild\cl\Debug\x64' | ||
| 1224 | - Kind: LF_STRING_ID | ||
| 1225 | StringId: | ||
| 1226 | Id: 0 | ||
| 1227 | String: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64\cl.exe' | ||
| 1228 | - Kind: LF_STRING_ID | ||
| 1229 | StringId: | ||
| 1230 | Id: 0 | ||
| 1231 | String: '-Z7 -O1 -c -MT -I"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\ATLMFC\include" -I"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\include" -I"C:\Program' | ||
| 1232 | - Kind: LF_STRING_ID | ||
| 1233 | StringId: | ||
| 1234 | Id: 0 | ||
| 1235 | String: ' Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\um"' | ||
| 1236 | - Kind: LF_SUBSTR_LIST | ||
| 1237 | StringList: | ||
| 1238 | StringIndices: [ 4193, 4194 ] | ||
| 1239 | - Kind: LF_STRING_ID | ||
| 1240 | StringId: | ||
| 1241 | Id: 4195 | ||
| 1242 | String: ' -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.16299.0\winrt" -TP -X' | ||
| 1243 | - Kind: LF_STRING_ID | ||
| 1244 | StringId: | ||
| 1245 | Id: 0 | ||
| 1246 | String: b.cpp | ||
| 1247 | - Kind: LF_STRING_ID | ||
| 1248 | StringId: | ||
| 1249 | Id: 0 | ||
| 1250 | String: 'D:\src\llvmbuild\cl\Debug\x64\vc140.pdb' | ||
| 1251 | - Kind: LF_BUILDINFO | ||
| 1252 | BuildInfo: | ||
| 1253 | ArgIndices: [ 4191, 4192, 4197, 4198, 4196 ] | ||
| 1254 | - Name: .bss | ||
| 1255 | Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 1256 | Alignment: 4 | ||
| 1257 | SectionData: '' | ||
| 1258 | - Name: '.text$mn' | ||
| 1259 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 1260 | Alignment: 4 | ||
| 1261 | SectionData: 4883EC288B0D0000000085C97405E8000000004883C428C3 | ||
| 1262 | Relocations: | ||
| 1263 | - VirtualAddress: 6 | ||
| 1264 | SymbolName: '?y@@3HA' | ||
| 1265 | Type: IMAGE_REL_AMD64_REL32 | ||
| 1266 | - VirtualAddress: 15 | ||
| 1267 | SymbolName: '?a@@YAXH@Z' | ||
| 1268 | Type: IMAGE_REL_AMD64_REL32 | ||
| 1269 | - Name: '.debug$S' | ||
| 1270 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 1271 | Alignment: 1 | ||
| 1272 | Subsections: | ||
| 1273 | - !Symbols | ||
| 1274 | Records: | ||
| 1275 | - Kind: S_GPROC32_ID | ||
| 1276 | ProcSym: | ||
| 1277 | CodeSize: 24 | ||
| 1278 | DbgStart: 4 | ||
| 1279 | DbgEnd: 19 | ||
| 1280 | FunctionType: 4098 | ||
| 1281 | Flags: [ HasOptimizedDebugInfo ] | ||
| 1282 | DisplayName: b | ||
| 1283 | - Kind: S_LOCAL | ||
| 1284 | LocalSym: | ||
| 1285 | Type: 116 | ||
| 1286 | Flags: [ IsParameter ] | ||
| 1287 | VarName: __formal | ||
| 1288 | - Kind: S_DEFRANGE_REGISTER | ||
| 1289 | DefRangeRegisterSym: | ||
| 1290 | Register: 18 | ||
| 1291 | MayHaveNoName: 0 | ||
| 1292 | Range: | ||
| 1293 | OffsetStart: 0 | ||
| 1294 | ISectStart: 0 | ||
| 1295 | Range: 10 | ||
| 1296 | Gaps: | ||
| 1297 | - Kind: S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE | ||
| 1298 | DefRangeFramePointerRelFullScopeSym: | ||
| 1299 | Register: 48 | ||
| 1300 | - Kind: S_CALLEES | ||
| 1301 | CallerSym: | ||
| 1302 | FuncID: [ 4099 ] | ||
| 1303 | - Kind: S_FILESTATIC | ||
| 1304 | FileStaticSym: | ||
| 1305 | Index: 116 | ||
| 1306 | ModFilenameOffset: 37 | ||
| 1307 | Flags: [ IsEnregisteredGlobal, IsEnregisteredStatic ] | ||
| 1308 | Name: y | ||
| 1309 | - Kind: S_DEFRANGE_REGISTER | ||
| 1310 | DefRangeRegisterSym: | ||
| 1311 | Register: 18 | ||
| 1312 | MayHaveNoName: 0 | ||
| 1313 | Range: | ||
| 1314 | OffsetStart: 10 | ||
| 1315 | ISectStart: 0 | ||
| 1316 | Range: 9 | ||
| 1317 | Gaps: | ||
| 1318 | - Kind: S_FRAMEPROC | ||
| 1319 | FrameProcSym: | ||
| 1320 | TotalFrameBytes: 40 | ||
| 1321 | PaddingFrameBytes: 0 | ||
| 1322 | OffsetToPadding: 0 | ||
| 1323 | BytesOfCalleeSavedRegisters: 0 | ||
| 1324 | OffsetOfExceptionHandler: 0 | ||
| 1325 | SectionIdOfExceptionHandler: 0 | ||
| 1326 | Flags: [ AsynchronousExceptionHandling ] | ||
| 1327 | - Kind: S_REGREL32 | ||
| 1328 | RegRelativeSym: | ||
| 1329 | Offset: 48 | ||
| 1330 | Type: 116 | ||
| 1331 | Register: CVRegRSP | ||
| 1332 | VarName: __formal | ||
| 1333 | - Kind: S_PROC_ID_END | ||
| 1334 | ScopeEndSym: | ||
| 1335 | - !Lines | ||
| 1336 | CodeSize: 24 | ||
| 1337 | Flags: [ ] | ||
| 1338 | RelocOffset: 0 | ||
| 1339 | RelocSegment: 0 | ||
| 1340 | Blocks: | ||
| 1341 | - FileName: 'd:\src\llvmbuild\cl\debug\x64\b.cpp' | ||
| 1342 | Lines: | ||
| 1343 | - Offset: 0 | ||
| 1344 | LineStart: 7 | ||
| 1345 | IsStatement: true | ||
| 1346 | EndDelta: 0 | ||
| 1347 | - Offset: 4 | ||
| 1348 | LineStart: 8 | ||
| 1349 | IsStatement: true | ||
| 1350 | EndDelta: 0 | ||
| 1351 | - Offset: 14 | ||
| 1352 | LineStart: 9 | ||
| 1353 | IsStatement: true | ||
| 1354 | EndDelta: 0 | ||
| 1355 | - Offset: 19 | ||
| 1356 | LineStart: 10 | ||
| 1357 | IsStatement: true | ||
| 1358 | EndDelta: 0 | ||
| 1359 | Columns: | ||
| 1360 | Relocations: | ||
| 1361 | - VirtualAddress: 44 | ||
| 1362 | SymbolName: '?b@@YAXH@Z' | ||
| 1363 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1364 | - VirtualAddress: 48 | ||
| 1365 | SymbolName: '?b@@YAXH@Z' | ||
| 1366 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1367 | - VirtualAddress: 80 | ||
| 1368 | SymbolName: '?b@@YAXH@Z' | ||
| 1369 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1370 | - VirtualAddress: 84 | ||
| 1371 | SymbolName: '?b@@YAXH@Z' | ||
| 1372 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1373 | - VirtualAddress: 132 | ||
| 1374 | SymbolName: '?b@@YAXH@Z' | ||
| 1375 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1376 | - VirtualAddress: 136 | ||
| 1377 | SymbolName: '?b@@YAXH@Z' | ||
| 1378 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1379 | - VirtualAddress: 208 | ||
| 1380 | SymbolName: '?b@@YAXH@Z' | ||
| 1381 | Type: IMAGE_REL_AMD64_SECREL | ||
| 1382 | - VirtualAddress: 212 | ||
| 1383 | SymbolName: '?b@@YAXH@Z' | ||
| 1384 | Type: IMAGE_REL_AMD64_SECTION | ||
| 1385 | - Name: .xdata | ||
| 1386 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | ||
| 1387 | Alignment: 4 | ||
| 1388 | SectionData: '0104010004420000' | ||
| 1389 | - Name: .pdata | ||
| 1390 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | ||
| 1391 | Alignment: 4 | ||
| 1392 | SectionData: '000000001800000000000000' | ||
| 1393 | Relocations: | ||
| 1394 | - VirtualAddress: 0 | ||
| 1395 | SymbolName: '$LN5' | ||
| 1396 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1397 | - VirtualAddress: 4 | ||
| 1398 | SymbolName: '$LN5' | ||
| 1399 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1400 | - VirtualAddress: 8 | ||
| 1401 | SymbolName: '$unwind$?b@@YAXH@Z' | ||
| 1402 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 1403 | symbols: | ||
| 1404 | - Name: '@comp.id' | ||
| 1405 | Value: 17130443 | ||
| 1406 | SectionNumber: -1 | ||
| 1407 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1408 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1409 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1410 | - Name: '@feat.00' | ||
| 1411 | Value: 2147484048 | ||
| 1412 | SectionNumber: -1 | ||
| 1413 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1414 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1415 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1416 | - Name: .drectve | ||
| 1417 | Value: 0 | ||
| 1418 | SectionNumber: 1 | ||
| 1419 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1420 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1421 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1422 | SectionDefinition: | ||
| 1423 | Length: 47 | ||
| 1424 | NumberOfRelocations: 0 | ||
| 1425 | NumberOfLinenumbers: 0 | ||
| 1426 | CheckSum: 0 | ||
| 1427 | Number: 0 | ||
| 1428 | - Name: '.debug$S' | ||
| 1429 | Value: 0 | ||
| 1430 | SectionNumber: 2 | ||
| 1431 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1432 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1433 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1434 | SectionDefinition: | ||
| 1435 | Length: 1096 | ||
| 1436 | NumberOfRelocations: 2 | ||
| 1437 | NumberOfLinenumbers: 0 | ||
| 1438 | CheckSum: 0 | ||
| 1439 | Number: 0 | ||
| 1440 | - Name: '.debug$T' | ||
| 1441 | Value: 0 | ||
| 1442 | SectionNumber: 3 | ||
| 1443 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1444 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1445 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1446 | SectionDefinition: | ||
| 1447 | Length: 6636 | ||
| 1448 | NumberOfRelocations: 0 | ||
| 1449 | NumberOfLinenumbers: 0 | ||
| 1450 | CheckSum: 0 | ||
| 1451 | Number: 0 | ||
| 1452 | - Name: .bss | ||
| 1453 | Value: 0 | ||
| 1454 | SectionNumber: 4 | ||
| 1455 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1456 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1457 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1458 | SectionDefinition: | ||
| 1459 | Length: 4 | ||
| 1460 | NumberOfRelocations: 0 | ||
| 1461 | NumberOfLinenumbers: 0 | ||
| 1462 | CheckSum: 0 | ||
| 1463 | Number: 0 | ||
| 1464 | - Name: '?y@@3HA' | ||
| 1465 | Value: 0 | ||
| 1466 | SectionNumber: 4 | ||
| 1467 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1468 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1469 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1470 | - Name: '.text$mn' | ||
| 1471 | Value: 0 | ||
| 1472 | SectionNumber: 5 | ||
| 1473 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1474 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1475 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1476 | SectionDefinition: | ||
| 1477 | Length: 24 | ||
| 1478 | NumberOfRelocations: 2 | ||
| 1479 | NumberOfLinenumbers: 0 | ||
| 1480 | CheckSum: 211387054 | ||
| 1481 | Number: 0 | ||
| 1482 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 1483 | - Name: '.debug$S' | ||
| 1484 | Value: 0 | ||
| 1485 | SectionNumber: 6 | ||
| 1486 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1487 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1488 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1489 | SectionDefinition: | ||
| 1490 | Length: 264 | ||
| 1491 | NumberOfRelocations: 8 | ||
| 1492 | NumberOfLinenumbers: 0 | ||
| 1493 | CheckSum: 0 | ||
| 1494 | Number: 5 | ||
| 1495 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1496 | - Name: '?a@@YAXH@Z' | ||
| 1497 | Value: 0 | ||
| 1498 | SectionNumber: 0 | ||
| 1499 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1500 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 1501 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 1502 | - Name: '?b@@YAXH@Z' | ||
| 1503 | Value: 0 | ||
| 1504 | SectionNumber: 5 | ||
| 1505 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1506 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 1507 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 1508 | - Name: '$LN5' | ||
| 1509 | Value: 0 | ||
| 1510 | SectionNumber: 5 | ||
| 1511 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1512 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1513 | StorageClass: IMAGE_SYM_CLASS_LABEL | ||
| 1514 | - Name: .xdata | ||
| 1515 | Value: 0 | ||
| 1516 | SectionNumber: 7 | ||
| 1517 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1518 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1519 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1520 | SectionDefinition: | ||
| 1521 | Length: 8 | ||
| 1522 | NumberOfRelocations: 0 | ||
| 1523 | NumberOfLinenumbers: 0 | ||
| 1524 | CheckSum: 264583633 | ||
| 1525 | Number: 5 | ||
| 1526 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1527 | - Name: '$unwind$?b@@YAXH@Z' | ||
| 1528 | Value: 0 | ||
| 1529 | SectionNumber: 7 | ||
| 1530 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1531 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1532 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1533 | - Name: .pdata | ||
| 1534 | Value: 0 | ||
| 1535 | SectionNumber: 8 | ||
| 1536 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1537 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1538 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1539 | SectionDefinition: | ||
| 1540 | Length: 12 | ||
| 1541 | NumberOfRelocations: 3 | ||
| 1542 | NumberOfLinenumbers: 0 | ||
| 1543 | CheckSum: 2942184094 | ||
| 1544 | Number: 5 | ||
| 1545 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 1546 | - Name: '$pdata$?b@@YAXH@Z' | ||
| 1547 | Value: 0 | ||
| 1548 | SectionNumber: 8 | ||
| 1549 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 1550 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 1551 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 1552 | ... | ||
deps/lld/test/COFF/Inputs/pdb-globals.yaml-10| ... | @@ -125,29 +125,21 @@ sections: | ... | @@ -125,29 +125,21 @@ sections: |
| 125 | Type: 116 | 125 | Type: 116 |
| 126 | Flags: [ IsParameter ] | 126 | Flags: [ IsParameter ] |
| 127 | VarName: argc | 127 | VarName: argc |
| 128 | - Kind: S_DEFRANGE_REGISTER_REL | ||
| 129 | DefRangeRegisterRelSym: | ||
| 130 | - Kind: S_LOCAL | 128 | - Kind: S_LOCAL |
| 131 | LocalSym: | 129 | LocalSym: |
| 132 | Type: 4099 | 130 | Type: 4099 |
| 133 | Flags: [ IsParameter ] | 131 | Flags: [ IsParameter ] |
| 134 | VarName: argv | 132 | VarName: argv |
| 135 | - Kind: S_DEFRANGE_REGISTER_REL | ||
| 136 | DefRangeRegisterRelSym: | ||
| 137 | - Kind: S_LOCAL | 133 | - Kind: S_LOCAL |
| 138 | LocalSym: | 134 | LocalSym: |
| 139 | Type: 4103 | 135 | Type: 4103 |
| 140 | Flags: [ ] | 136 | Flags: [ ] |
| 141 | VarName: P | 137 | VarName: P |
| 142 | - Kind: S_DEFRANGE_REGISTER_REL | ||
| 143 | DefRangeRegisterRelSym: | ||
| 144 | - Kind: S_LOCAL | 138 | - Kind: S_LOCAL |
| 145 | LocalSym: | 139 | LocalSym: |
| 146 | Type: 116 | 140 | Type: 116 |
| 147 | Flags: [ ] | 141 | Flags: [ ] |
| 148 | VarName: N | 142 | VarName: N |
| 149 | - Kind: S_DEFRANGE_REGISTER_REL | ||
| 150 | DefRangeRegisterRelSym: | ||
| 151 | - Kind: S_PROC_ID_END | 143 | - Kind: S_PROC_ID_END |
| 152 | ScopeEndSym: | 144 | ScopeEndSym: |
| 153 | - Kind: S_LPROC32_ID | 145 | - Kind: S_LPROC32_ID |
| ... | @@ -408,8 +400,6 @@ sections: | ... | @@ -408,8 +400,6 @@ sections: |
| 408 | Type: 4108 | 400 | Type: 4108 |
| 409 | Flags: [ IsParameter ] | 401 | Flags: [ IsParameter ] |
| 410 | VarName: this | 402 | VarName: this |
| 411 | - Kind: S_DEFRANGE_REGISTER_REL | ||
| 412 | DefRangeRegisterRelSym: | ||
| 413 | - Kind: S_PROC_ID_END | 403 | - Kind: S_PROC_ID_END |
| 414 | ScopeEndSym: | 404 | ScopeEndSym: |
| 415 | Relocations: | 405 | Relocations: |
deps/lld/test/COFF/Inputs/pdb-hashes-1.yaml+132-92| ... | @@ -1,13 +1,13 @@ | ... | @@ -1,13 +1,13 @@ |
| 1 | --- !COFF | 1 | --- !COFF |
| 2 | header: | 2 | header: |
| 3 | Machine: IMAGE_FILE_MACHINE_I386 | 3 | Machine: IMAGE_FILE_MACHINE_I386 |
| 4 | Characteristics: [ ] | 4 | Characteristics: [ ] |
| 5 | sections: | 5 | sections: |
| 6 | - Name: .text | 6 | - Name: .text |
| 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 8 | Alignment: 16 | 8 | Alignment: 16 |
| 9 | SectionData: 5589E55683EC188B450C8B4D088D55F4C745F8000000008B7508894DF089D18934248945ECE80000000083EC048D4DF4890C248945E8E80000000083C4185E5DC3 | 9 | SectionData: 5589E55683EC188B450C8B4D08C745F8000000008B55088D75F4894DF089F18914248945ECE80000000083EC048D4DF4890C248945E8E80000000083C4185E5DC3 |
| 10 | Relocations: | 10 | Relocations: |
| 11 | - VirtualAddress: 38 | 11 | - VirtualAddress: 38 |
| 12 | SymbolName: '??0Foo@NS@@QAE@H@Z' | 12 | SymbolName: '??0Foo@NS@@QAE@H@Z' |
| 13 | Type: IMAGE_REL_I386_REL32 | 13 | Type: IMAGE_REL_I386_REL32 |
| ... | @@ -33,25 +33,25 @@ sections: | ... | @@ -33,25 +33,25 @@ sections: |
| 33 | - Name: '.debug$S' | 33 | - Name: '.debug$S' |
| 34 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 34 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 35 | Alignment: 4 | 35 | Alignment: 4 |
| 36 | SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F50000008400000000000000000000004100000000000000080000000000000052000000070000000400000001000000400000000000000008000000000000007F0000000600040000000000030000003E000000000000000800000000000000BD0000000400040000000000040000003D000000000000000800000000000000FA0000000300080000000000F1000000960000002A00471100000000000000000000000041000000000000000000000003100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001700000000002A000D003E11001000000100617267760012004511160000000C0000001700000000002A000A003E1109100000000066001200451116000000F4FFFFFF1700000000002A0002004F110000F200000030000000000000000000000041000000000000000300000024000000000000000300000017000000040000003000000005000000F1000000100000000E000811091000004E533A3A466F6F00F40000003000000001000000100165C9E387F88362A8EB2B49539DD5A65500002B00000010019303CF100D518DAF59C31DA01FEF4AFC0000F30000004801000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A312E63707000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D2024657369202454302038202D205E203D2000 | 36 | SectionData: 04000000F10000002F0000002D003C110100000007000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F50000008400000000000000000000004100000000000000080000000000000052000000070000000400000001000000400000000000000008000000000000007F0000000600040000000000030000003E000000000000000800000000000000BD0000000400040000000000040000003D000000000000000800000000000000FA0000000300080000000000F1000000960000002A00471100000000000000000000000041000000000000000000000003100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001400000000002D000D003E11001000000100617267760012004511160000000C0000001400000000002D000A003E1109100000000066001200451116000000F4FFFFFF1400000000002D0002004F110000F200000030000000000000000000000041000000000000000300000024000000000000000300000014000000040000002D00000005000000F1000000100000000E000811091000004E533A3A466F6F00F40000003000000001000000100165C9E387F88362A8EB2B49539DD5A65500002B0000001001D3AE9D06B0C1F06ABE75A0557053ED6B0000F30000004801000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A312E63707000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D2024657369202454302038202D205E203D2000 |
| 37 | Subsections: | 37 | Subsections: |
| 38 | - !Symbols | 38 | - !Symbols |
| 39 | Records: | 39 | Records: |
| 40 | - Kind: S_COMPILE3 | 40 | - Kind: S_COMPILE3 |
| 41 | Compile3Sym: | 41 | Compile3Sym: |
| 42 | Flags: [ ] | 42 | Flags: [ ] |
| 43 | Machine: Pentium3 | 43 | Machine: Pentium3 |
| 44 | FrontendMajor: 6 | 44 | FrontendMajor: 7 |
| 45 | FrontendMinor: 0 | 45 | FrontendMinor: 0 |
| 46 | FrontendBuild: 0 | 46 | FrontendBuild: 0 |
| 47 | FrontendQFE: 0 | 47 | FrontendQFE: 0 |
| 48 | BackendMajor: 6000 | 48 | BackendMajor: 7000 |
| 49 | BackendMinor: 0 | 49 | BackendMinor: 0 |
| 50 | BackendBuild: 0 | 50 | BackendBuild: 0 |
| 51 | BackendQFE: 0 | 51 | BackendQFE: 0 |
| 52 | Version: 'clang version 6.0.0 ' | 52 | Version: 'clang version 7.0.0 ' |
| 53 | - !FrameData | 53 | - !FrameData |
| 54 | Frames: | 54 | Frames: |
| 55 | - CodeSize: 65 | 55 | - CodeSize: 65 |
| 56 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | 56 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' |
| 57 | LocalSize: 0 | 57 | LocalSize: 0 |
| ... | @@ -85,9 +85,9 @@ sections: | ... | @@ -85,9 +85,9 @@ sections: |
| 85 | RvaStart: 4 | 85 | RvaStart: 4 |
| 86 | SavedRegsSize: 8 | 86 | SavedRegsSize: 8 |
| 87 | - !Symbols | 87 | - !Symbols |
| 88 | Records: | 88 | Records: |
| 89 | - Kind: S_GPROC32_ID | 89 | - Kind: S_GPROC32_ID |
| 90 | ProcSym: | 90 | ProcSym: |
| 91 | CodeSize: 65 | 91 | CodeSize: 65 |
| 92 | DbgStart: 0 | 92 | DbgStart: 0 |
| 93 | DbgEnd: 0 | 93 | DbgEnd: 0 |
| ... | @@ -95,72 +95,96 @@ sections: | ... | @@ -95,72 +95,96 @@ sections: |
| 95 | Flags: [ ] | 95 | Flags: [ ] |
| 96 | DisplayName: main | 96 | DisplayName: main |
| 97 | - Kind: S_LOCAL | 97 | - Kind: S_LOCAL |
| 98 | LocalSym: | 98 | LocalSym: |
| 99 | Type: 116 | 99 | Type: 116 |
| 100 | Flags: [ IsParameter ] | 100 | Flags: [ IsParameter ] |
| 101 | VarName: argc | 101 | VarName: argc |
| 102 | - Kind: S_DEFRANGE_REGISTER_REL | 102 | - Kind: S_DEFRANGE_REGISTER_REL |
| 103 | DefRangeRegisterRelSym: | 103 | DefRangeRegisterRelSym: |
| 104 | Register: 22 | ||
| 105 | Flags: 0 | ||
| 106 | BasePointerOffset: 8 | ||
| 107 | Range: | ||
| 108 | OffsetStart: 20 | ||
| 109 | ISectStart: 0 | ||
| 110 | Range: 45 | ||
| 111 | Gaps: | ||
| 104 | - Kind: S_LOCAL | 112 | - Kind: S_LOCAL |
| 105 | LocalSym: | 113 | LocalSym: |
| 106 | Type: 4096 | 114 | Type: 4096 |
| 107 | Flags: [ IsParameter ] | 115 | Flags: [ IsParameter ] |
| 108 | VarName: argv | 116 | VarName: argv |
| 109 | - Kind: S_DEFRANGE_REGISTER_REL | 117 | - Kind: S_DEFRANGE_REGISTER_REL |
| 110 | DefRangeRegisterRelSym: | 118 | DefRangeRegisterRelSym: |
| 119 | Register: 22 | ||
| 120 | Flags: 0 | ||
| 121 | BasePointerOffset: 12 | ||
| 122 | Range: | ||
| 123 | OffsetStart: 20 | ||
| 124 | ISectStart: 0 | ||
| 125 | Range: 45 | ||
| 126 | Gaps: | ||
| 111 | - Kind: S_LOCAL | 127 | - Kind: S_LOCAL |
| 112 | LocalSym: | 128 | LocalSym: |
| 113 | Type: 4105 | 129 | Type: 4105 |
| 114 | Flags: [ ] | 130 | Flags: [ ] |
| 115 | VarName: f | 131 | VarName: f |
| 116 | - Kind: S_DEFRANGE_REGISTER_REL | 132 | - Kind: S_DEFRANGE_REGISTER_REL |
| 117 | DefRangeRegisterRelSym: | 133 | DefRangeRegisterRelSym: |
| 134 | Register: 22 | ||
| 135 | Flags: 0 | ||
| 136 | BasePointerOffset: -12 | ||
| 137 | Range: | ||
| 138 | OffsetStart: 20 | ||
| 139 | ISectStart: 0 | ||
| 140 | Range: 45 | ||
| 141 | Gaps: | ||
| 118 | - Kind: S_PROC_ID_END | 142 | - Kind: S_PROC_ID_END |
| 119 | ScopeEndSym: | 143 | ScopeEndSym: |
| 120 | - !Lines | 144 | - !Lines |
| 121 | CodeSize: 65 | 145 | CodeSize: 65 |
| 122 | Flags: [ ] | 146 | Flags: [ ] |
| 123 | RelocOffset: 0 | 147 | RelocOffset: 0 |
| 124 | RelocSegment: 0 | 148 | RelocSegment: 0 |
| 125 | Blocks: | 149 | Blocks: |
| 126 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' | 150 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' |
| 127 | Lines: | 151 | Lines: |
| 128 | - Offset: 0 | 152 | - Offset: 0 |
| 129 | LineStart: 3 | 153 | LineStart: 3 |
| 130 | IsStatement: false | 154 | IsStatement: false |
| 131 | EndDelta: 0 | 155 | EndDelta: 0 |
| 132 | - Offset: 23 | 156 | - Offset: 20 |
| 133 | LineStart: 4 | 157 | LineStart: 4 |
| 134 | IsStatement: false | 158 | IsStatement: false |
| 135 | EndDelta: 0 | 159 | EndDelta: 0 |
| 136 | - Offset: 48 | 160 | - Offset: 45 |
| 137 | LineStart: 5 | 161 | LineStart: 5 |
| 138 | IsStatement: false | 162 | IsStatement: false |
| 139 | EndDelta: 0 | 163 | EndDelta: 0 |
| 140 | Columns: | 164 | Columns: |
| 141 | - !Symbols | 165 | - !Symbols |
| 142 | Records: | 166 | Records: |
| 143 | - Kind: S_UDT | 167 | - Kind: S_UDT |
| 144 | UDTSym: | 168 | UDTSym: |
| 145 | Type: 4105 | 169 | Type: 4105 |
| 146 | UDTName: 'NS::Foo' | 170 | UDTName: 'NS::Foo' |
| 147 | - !FileChecksums | 171 | - !FileChecksums |
| 148 | Checksums: | 172 | Checksums: |
| 149 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' | 173 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' |
| 150 | Kind: MD5 | 174 | Kind: MD5 |
| 151 | Checksum: 65C9E387F88362A8EB2B49539DD5A655 | 175 | Checksum: 65C9E387F88362A8EB2B49539DD5A655 |
| 152 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | 176 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' |
| 153 | Kind: MD5 | 177 | Kind: MD5 |
| 154 | Checksum: 9303CF100D518DAF59C31DA01FEF4AFC | 178 | Checksum: D3AE9D06B0C1F06ABE75A0557053ED6B |
| 155 | - !StringTable | 179 | - !StringTable |
| 156 | Strings: | 180 | Strings: |
| 157 | - 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' | 181 | - 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' |
| 158 | - 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | 182 | - 'D:\src\llvmbuild\clang\Debug\x86\obj.h' |
| 159 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | 183 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' |
| 160 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | 184 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' |
| 161 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | 185 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' |
| 162 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = ' | 186 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = ' |
| 163 | Relocations: | 187 | Relocations: |
| 164 | - VirtualAddress: 68 | 188 | - VirtualAddress: 68 |
| 165 | SymbolName: _main | 189 | SymbolName: _main |
| 166 | Type: IMAGE_REL_I386_DIR32NB | 190 | Type: IMAGE_REL_I386_DIR32NB |
| ... | @@ -198,28 +222,28 @@ sections: | ... | @@ -198,28 +222,28 @@ sections: |
| 198 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 222 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 199 | Alignment: 4 | 223 | Alignment: 4 |
| 200 | SectionData: 040000000A000210700400000A8000000E0001120200000074000000001000000E0008107400000000000200011000001200011600000000021000006D61696E00F3F2F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000210041000000A8000000A00011201000000740000001A0009100300000004100000051000000B00010006100000000000001A0003120D15030074000000000058001115030007100000466F6F002A0005150200000208100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E000616091000000A100000020000000E0002160410000007100000466F6F00 | 224 | SectionData: 040000000A000210700400000A8000000E0001120200000074000000001000000E0008107400000000000200011000001200011600000000021000006D61696E00F3F2F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000210041000000A8000000A00011201000000740000001A0009100300000004100000051000000B00010006100000000000001A0003120D15030074000000000058001115030007100000466F6F002A0005150200000208100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E000616091000000A100000020000000E0002160410000007100000466F6F00 |
| 201 | Types: | 225 | Types: |
| 202 | - Kind: LF_POINTER | 226 | - Kind: LF_POINTER |
| 203 | Pointer: | 227 | Pointer: |
| 204 | ReferentType: 1136 | 228 | ReferentType: 1136 |
| 205 | Attrs: 32778 | 229 | Attrs: 32778 |
| 206 | - Kind: LF_ARGLIST | 230 | - Kind: LF_ARGLIST |
| 207 | ArgList: | 231 | ArgList: |
| 208 | ArgIndices: [ 116, 4096 ] | 232 | ArgIndices: [ 116, 4096 ] |
| 209 | - Kind: LF_PROCEDURE | 233 | - Kind: LF_PROCEDURE |
| 210 | Procedure: | 234 | Procedure: |
| 211 | ReturnType: 116 | 235 | ReturnType: 116 |
| 212 | CallConv: NearC | 236 | CallConv: NearC |
| 213 | Options: [ None ] | 237 | Options: [ None ] |
| 214 | ParameterCount: 2 | 238 | ParameterCount: 2 |
| 215 | ArgumentList: 4097 | 239 | ArgumentList: 4097 |
| 216 | - Kind: LF_FUNC_ID | 240 | - Kind: LF_FUNC_ID |
| 217 | FuncId: | 241 | FuncId: |
| 218 | ParentScope: 0 | 242 | ParentScope: 0 |
| 219 | FunctionType: 4098 | 243 | FunctionType: 4098 |
| 220 | Name: main | 244 | Name: main |
| 221 | - Kind: LF_STRUCTURE | 245 | - Kind: LF_STRUCTURE |
| 222 | Class: | 246 | Class: |
| 223 | MemberCount: 0 | 247 | MemberCount: 0 |
| 224 | Options: [ None, ForwardReference, HasUniqueName ] | 248 | Options: [ None, ForwardReference, HasUniqueName ] |
| 225 | FieldList: 0 | 249 | FieldList: 0 |
| ... | @@ -229,14 +253,14 @@ sections: | ... | @@ -229,14 +253,14 @@ sections: |
| 229 | VTableShape: 0 | 253 | VTableShape: 0 |
| 230 | Size: 0 | 254 | Size: 0 |
| 231 | - Kind: LF_POINTER | 255 | - Kind: LF_POINTER |
| 232 | Pointer: | 256 | Pointer: |
| 233 | ReferentType: 4100 | 257 | ReferentType: 4100 |
| 234 | Attrs: 32778 | 258 | Attrs: 32778 |
| 235 | - Kind: LF_ARGLIST | 259 | - Kind: LF_ARGLIST |
| 236 | ArgList: | 260 | ArgList: |
| 237 | ArgIndices: [ 116 ] | 261 | ArgIndices: [ 116 ] |
| 238 | - Kind: LF_MFUNCTION | 262 | - Kind: LF_MFUNCTION |
| 239 | MemberFunction: | 263 | MemberFunction: |
| 240 | ReturnType: 3 | 264 | ReturnType: 3 |
| 241 | ClassType: 4100 | 265 | ClassType: 4100 |
| 242 | ThisType: 4101 | 266 | ThisType: 4101 |
| ... | @@ -246,21 +270,21 @@ sections: | ... | @@ -246,21 +270,21 @@ sections: |
| 246 | ArgumentList: 4102 | 270 | ArgumentList: 4102 |
| 247 | ThisPointerAdjustment: 0 | 271 | ThisPointerAdjustment: 0 |
| 248 | - Kind: LF_FIELDLIST | 272 | - Kind: LF_FIELDLIST |
| 249 | FieldList: | 273 | FieldList: |
| 250 | - Kind: LF_MEMBER | 274 | - Kind: LF_MEMBER |
| 251 | DataMember: | 275 | DataMember: |
| 252 | Attrs: 3 | 276 | Attrs: 3 |
| 253 | Type: 116 | 277 | Type: 116 |
| 254 | FieldOffset: 0 | 278 | FieldOffset: 0 |
| 255 | Name: X | 279 | Name: X |
| 256 | - Kind: LF_ONEMETHOD | 280 | - Kind: LF_ONEMETHOD |
| 257 | OneMethod: | 281 | OneMethod: |
| 258 | Type: 4103 | 282 | Type: 4103 |
| 259 | Attrs: 3 | 283 | Attrs: 3 |
| 260 | VFTableOffset: -1 | 284 | VFTableOffset: -1 |
| 261 | Name: Foo | 285 | Name: Foo |
| 262 | - Kind: LF_STRUCTURE | 286 | - Kind: LF_STRUCTURE |
| 263 | Class: | 287 | Class: |
| 264 | MemberCount: 2 | 288 | MemberCount: 2 |
| 265 | Options: [ None, HasUniqueName ] | 289 | Options: [ None, HasUniqueName ] |
| 266 | FieldList: 4104 | 290 | FieldList: 4104 |
| ... | @@ -270,47 +294,47 @@ sections: | ... | @@ -270,47 +294,47 @@ sections: |
| 270 | VTableShape: 0 | 294 | VTableShape: 0 |
| 271 | Size: 4 | 295 | Size: 4 |
| 272 | - Kind: LF_STRING_ID | 296 | - Kind: LF_STRING_ID |
| 273 | StringId: | 297 | StringId: |
| 274 | Id: 0 | 298 | Id: 0 |
| 275 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | 299 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' |
| 276 | - Kind: LF_UDT_SRC_LINE | 300 | - Kind: LF_UDT_SRC_LINE |
| 277 | UdtSourceLine: | 301 | UdtSourceLine: |
| 278 | UDT: 4105 | 302 | UDT: 4105 |
| 279 | SourceFile: 4106 | 303 | SourceFile: 4106 |
| 280 | LineNumber: 2 | 304 | LineNumber: 2 |
| 281 | - Kind: LF_MFUNC_ID | 305 | - Kind: LF_MFUNC_ID |
| 282 | MemberFuncId: | 306 | MemberFuncId: |
| 283 | ClassType: 4100 | 307 | ClassType: 4100 |
| 284 | FunctionType: 4103 | 308 | FunctionType: 4103 |
| 285 | Name: Foo | 309 | Name: Foo |
| 286 | - Name: '.debug$H' | 310 | - Name: '.debug$H' |
| 287 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 311 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 288 | Alignment: 4 | 312 | Alignment: 4 |
| 289 | SectionData: C5C93301000000009E56666824DC4B12E25261D4E09E6E9DA0F4EE31FDEC3D2D96287486127C66070B248ED52E421F55074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E99E616EF06A14EA74A2420F9062A1FB04917E5975E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D894CEAE81AEF8680D723D403D9A4481F0E28683A98 | 313 | SectionData: C5C9330100000100800309EE1ED8BB5B5397319F1CC14E2CDF04AA3125BBC50E95CEBA304A2C449323ADA4E788EB7A90B5DECADF1A832BA46632585CDC7606E4B97B86241E5F45B0BCD2406E22465E11A528BEF0A7F589C76079F1186C40C2165091EFEBD5B5446B26FFBFD620CFB362 |
| 290 | GlobalHashes: | 314 | GlobalHashes: |
| 291 | Version: 0 | 315 | Version: 0 |
| 292 | HashAlgorithm: 0 | 316 | HashAlgorithm: 1 |
| 293 | HashValues: | 317 | HashValues: |
| 294 | - 9E56666824DC4B12E25261D4E09E6E9DA0F4EE31 | 318 | - 800309EE1ED8BB5B |
| 295 | - FDEC3D2D96287486127C66070B248ED52E421F55 | 319 | - 5397319F1CC14E2C |
| 296 | - 074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84 | 320 | - DF04AA3125BBC50E |
| 297 | - BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E9 | 321 | - 95CEBA304A2C4493 |
| 298 | - 9E616EF06A14EA74A2420F9062A1FB04917E5975 | 322 | - 23ADA4E788EB7A90 |
| 299 | - E3A50EABE5E8FE3945468547C19DC681D0BFB3B7 | 323 | - B5DECADF1A832BA4 |
| 300 | - 97DD91CA4D7F1953C314442D5549419E78044E38 | 324 | - 6632585CDC7606E4 |
| 301 | - A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0 | 325 | - B97B86241E5F45B0 |
| 302 | - C0A9021B711ACC4F67008974EBF441031BDD653F | 326 | - BCD2406E22465E11 |
| 303 | - 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA | 327 | - A528BEF0A7F589C7 |
| 304 | - 0AF6C1846743F43D846BB19517E12E8873BBA90C | 328 | - 6079F1186C40C216 |
| 305 | - C41DD1BEAC89CBA8897AC1BA46762E2557A82D89 | 329 | - 5091EFEBD5B5446B |
| 306 | - 4CEAE81AEF8680D723D403D9A4481F0E28683A98 | 330 | - 26FFBFD620CFB362 |
| 307 | - Name: '.debug$S' | 331 | - Name: '.debug$S' |
| 308 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 332 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 309 | Alignment: 4 | 333 | Alignment: 4 |
| 310 | SectionData: 04000000F500000064000000000000000000000020000000000000000400000000000000520000000600000004000000010000001F0000000000000004000000000000007F0000000500040000000000030000001D000000000000000400000000000000BD0000000300040000000000F10000007B000000320047110000000000000000000000002000000000000000000000000C100000000000000000004E533A3A466F6F3A3A466F6F000D003E1105100000010074686973001200451116000000FCFFFFFF0F000000000011000A003E1174000000010078001200451116000000080000000F0000000000110002004F1100F2000000200000000000000000000000200000001800000001000000140000000000000003000000 | 334 | SectionData: 04000000F500000064000000000000000000000020000000000000000400000000000000520000000600000004000000010000001F0000000000000004000000000000007F0000000500040000000000030000001D000000000000000400000000000000BD0000000300040000000000F10000007B000000320047110000000000000000000000002000000000000000000000000C100000000000000000004E533A3A466F6F3A3A466F6F000D003E1105100000010074686973001200451116000000FCFFFFFF0F000000000011000A003E1174000000010078001200451116000000080000000F0000000000110002004F1100F2000000200000000000000000000000200000001800000001000000140000000000000003000000 |
| 311 | Subsections: | 335 | Subsections: |
| 312 | - !FrameData | 336 | - !FrameData |
| 313 | Frames: | 337 | Frames: |
| 314 | - CodeSize: 32 | 338 | - CodeSize: 32 |
| 315 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | 339 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' |
| 316 | LocalSize: 0 | 340 | LocalSize: 0 |
| ... | @@ -336,9 +360,9 @@ sections: | ... | @@ -336,9 +360,9 @@ sections: |
| 336 | RvaStart: 3 | 360 | RvaStart: 3 |
| 337 | SavedRegsSize: 4 | 361 | SavedRegsSize: 4 |
| 338 | - !Symbols | 362 | - !Symbols |
| 339 | Records: | 363 | Records: |
| 340 | - Kind: S_GPROC32_ID | 364 | - Kind: S_GPROC32_ID |
| 341 | ProcSym: | 365 | ProcSym: |
| 342 | CodeSize: 32 | 366 | CodeSize: 32 |
| 343 | DbgStart: 0 | 367 | DbgStart: 0 |
| 344 | DbgEnd: 0 | 368 | DbgEnd: 0 |
| ... | @@ -346,35 +370,51 @@ sections: | ... | @@ -346,35 +370,51 @@ sections: |
| 346 | Flags: [ ] | 370 | Flags: [ ] |
| 347 | DisplayName: 'NS::Foo::Foo' | 371 | DisplayName: 'NS::Foo::Foo' |
| 348 | - Kind: S_LOCAL | 372 | - Kind: S_LOCAL |
| 349 | LocalSym: | 373 | LocalSym: |
| 350 | Type: 4101 | 374 | Type: 4101 |
| 351 | Flags: [ IsParameter ] | 375 | Flags: [ IsParameter ] |
| 352 | VarName: this | 376 | VarName: this |
| 353 | - Kind: S_DEFRANGE_REGISTER_REL | 377 | - Kind: S_DEFRANGE_REGISTER_REL |
| 354 | DefRangeRegisterRelSym: | 378 | DefRangeRegisterRelSym: |
| 379 | Register: 22 | ||
| 380 | Flags: 0 | ||
| 381 | BasePointerOffset: -4 | ||
| 382 | Range: | ||
| 383 | OffsetStart: 15 | ||
| 384 | ISectStart: 0 | ||
| 385 | Range: 17 | ||
| 386 | Gaps: | ||
| 355 | - Kind: S_LOCAL | 387 | - Kind: S_LOCAL |
| 356 | LocalSym: | 388 | LocalSym: |
| 357 | Type: 116 | 389 | Type: 116 |
| 358 | Flags: [ IsParameter ] | 390 | Flags: [ IsParameter ] |
| 359 | VarName: x | 391 | VarName: x |
| 360 | - Kind: S_DEFRANGE_REGISTER_REL | 392 | - Kind: S_DEFRANGE_REGISTER_REL |
| 361 | DefRangeRegisterRelSym: | 393 | DefRangeRegisterRelSym: |
| 394 | Register: 22 | ||
| 395 | Flags: 0 | ||
| 396 | BasePointerOffset: 8 | ||
| 397 | Range: | ||
| 398 | OffsetStart: 15 | ||
| 399 | ISectStart: 0 | ||
| 400 | Range: 17 | ||
| 401 | Gaps: | ||
| 362 | - Kind: S_PROC_ID_END | 402 | - Kind: S_PROC_ID_END |
| 363 | ScopeEndSym: | 403 | ScopeEndSym: |
| 364 | - !Lines | 404 | - !Lines |
| 365 | CodeSize: 32 | 405 | CodeSize: 32 |
| 366 | Flags: [ ] | 406 | Flags: [ ] |
| 367 | RelocOffset: 0 | 407 | RelocOffset: 0 |
| 368 | RelocSegment: 0 | 408 | RelocSegment: 0 |
| 369 | Blocks: | 409 | Blocks: |
| 370 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | 410 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' |
| 371 | Lines: | 411 | Lines: |
| 372 | - Offset: 0 | 412 | - Offset: 0 |
| 373 | LineStart: 3 | 413 | LineStart: 3 |
| 374 | IsStatement: false | 414 | IsStatement: false |
| 375 | EndDelta: 0 | 415 | EndDelta: 0 |
| 376 | Columns: | 416 | Columns: |
| 377 | Relocations: | 417 | Relocations: |
| 378 | - VirtualAddress: 12 | 418 | - VirtualAddress: 12 |
| 379 | SymbolName: '??0Foo@NS@@QAE@H@Z' | 419 | SymbolName: '??0Foo@NS@@QAE@H@Z' |
| 380 | Type: IMAGE_REL_I386_DIR32NB | 420 | Type: IMAGE_REL_I386_DIR32NB |
| ... | @@ -402,18 +442,18 @@ sections: | ... | @@ -402,18 +442,18 @@ sections: |
| 402 | - VirtualAddress: 256 | 442 | - VirtualAddress: 256 |
| 403 | SymbolName: '??0Foo@NS@@QAE@H@Z' | 443 | SymbolName: '??0Foo@NS@@QAE@H@Z' |
| 404 | Type: IMAGE_REL_I386_SECTION | 444 | Type: IMAGE_REL_I386_SECTION |
| 405 | symbols: | 445 | symbols: |
| 406 | - Name: .text | 446 | - Name: .text |
| 407 | Value: 0 | 447 | Value: 0 |
| 408 | SectionNumber: 1 | 448 | SectionNumber: 1 |
| 409 | SimpleType: IMAGE_SYM_TYPE_NULL | 449 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 410 | ComplexType: IMAGE_SYM_DTYPE_NULL | 450 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 411 | StorageClass: IMAGE_SYM_CLASS_STATIC | 451 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 412 | SectionDefinition: | 452 | SectionDefinition: |
| 413 | Length: 65 | 453 | Length: 65 |
| 414 | NumberOfRelocations: 2 | 454 | NumberOfRelocations: 2 |
| 415 | NumberOfLinenumbers: 0 | 455 | NumberOfLinenumbers: 0 |
| 416 | CheckSum: 4176946275 | 456 | CheckSum: 1827148029 |
| 417 | Number: 1 | 457 | Number: 1 |
| 418 | - Name: .data | 458 | - Name: .data |
| 419 | Value: 0 | 459 | Value: 0 |
| ... | @@ -421,7 +461,7 @@ symbols: | ... | @@ -421,7 +461,7 @@ symbols: |
| 421 | SimpleType: IMAGE_SYM_TYPE_NULL | 461 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 422 | ComplexType: IMAGE_SYM_DTYPE_NULL | 462 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 423 | StorageClass: IMAGE_SYM_CLASS_STATIC | 463 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 424 | SectionDefinition: | 464 | SectionDefinition: |
| 425 | Length: 0 | 465 | Length: 0 |
| 426 | NumberOfRelocations: 0 | 466 | NumberOfRelocations: 0 |
| 427 | NumberOfLinenumbers: 0 | 467 | NumberOfLinenumbers: 0 |
| ... | @@ -433,7 +473,7 @@ symbols: | ... | @@ -433,7 +473,7 @@ symbols: |
| 433 | SimpleType: IMAGE_SYM_TYPE_NULL | 473 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 434 | ComplexType: IMAGE_SYM_DTYPE_NULL | 474 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 435 | StorageClass: IMAGE_SYM_CLASS_STATIC | 475 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 436 | SectionDefinition: | 476 | SectionDefinition: |
| 437 | Length: 0 | 477 | Length: 0 |
| 438 | NumberOfRelocations: 0 | 478 | NumberOfRelocations: 0 |
| 439 | NumberOfLinenumbers: 0 | 479 | NumberOfLinenumbers: 0 |
| ... | @@ -445,7 +485,7 @@ symbols: | ... | @@ -445,7 +485,7 @@ symbols: |
| 445 | SimpleType: IMAGE_SYM_TYPE_NULL | 485 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 446 | ComplexType: IMAGE_SYM_DTYPE_NULL | 486 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 447 | StorageClass: IMAGE_SYM_CLASS_STATIC | 487 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 448 | SectionDefinition: | 488 | SectionDefinition: |
| 449 | Length: 32 | 489 | Length: 32 |
| 450 | NumberOfRelocations: 0 | 490 | NumberOfRelocations: 0 |
| 451 | NumberOfLinenumbers: 0 | 491 | NumberOfLinenumbers: 0 |
| ... | @@ -464,7 +504,7 @@ symbols: | ... | @@ -464,7 +504,7 @@ symbols: |
| 464 | SimpleType: IMAGE_SYM_TYPE_NULL | 504 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 465 | ComplexType: IMAGE_SYM_DTYPE_NULL | 505 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 466 | StorageClass: IMAGE_SYM_CLASS_STATIC | 506 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 467 | SectionDefinition: | 507 | SectionDefinition: |
| 468 | Length: 48 | 508 | Length: 48 |
| 469 | NumberOfRelocations: 0 | 509 | NumberOfRelocations: 0 |
| 470 | NumberOfLinenumbers: 0 | 510 | NumberOfLinenumbers: 0 |
| ... | @@ -476,11 +516,11 @@ symbols: | ... | @@ -476,11 +516,11 @@ symbols: |
| 476 | SimpleType: IMAGE_SYM_TYPE_NULL | 516 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 477 | ComplexType: IMAGE_SYM_DTYPE_NULL | 517 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 478 | StorageClass: IMAGE_SYM_CLASS_STATIC | 518 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 479 | SectionDefinition: | 519 | SectionDefinition: |
| 480 | Length: 832 | 520 | Length: 832 |
| 481 | NumberOfRelocations: 11 | 521 | NumberOfRelocations: 11 |
| 482 | NumberOfLinenumbers: 0 | 522 | NumberOfLinenumbers: 0 |
| 483 | CheckSum: 4106171226 | 523 | CheckSum: 372945565 |
| 484 | Number: 6 | 524 | Number: 6 |
| 485 | - Name: '.debug$S' | 525 | - Name: '.debug$S' |
| 486 | Value: 0 | 526 | Value: 0 |
| ... | @@ -488,7 +528,7 @@ symbols: | ... | @@ -488,7 +528,7 @@ symbols: |
| 488 | SimpleType: IMAGE_SYM_TYPE_NULL | 528 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 489 | ComplexType: IMAGE_SYM_DTYPE_NULL | 529 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 490 | StorageClass: IMAGE_SYM_CLASS_STATIC | 530 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 491 | SectionDefinition: | 531 | SectionDefinition: |
| 492 | Length: 284 | 532 | Length: 284 |
| 493 | NumberOfRelocations: 9 | 533 | NumberOfRelocations: 9 |
| 494 | NumberOfLinenumbers: 0 | 534 | NumberOfLinenumbers: 0 |
| ... | @@ -501,7 +541,7 @@ symbols: | ... | @@ -501,7 +541,7 @@ symbols: |
| 501 | SimpleType: IMAGE_SYM_TYPE_NULL | 541 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 502 | ComplexType: IMAGE_SYM_DTYPE_NULL | 542 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 503 | StorageClass: IMAGE_SYM_CLASS_STATIC | 543 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 504 | SectionDefinition: | 544 | SectionDefinition: |
| 505 | Length: 316 | 545 | Length: 316 |
| 506 | NumberOfRelocations: 0 | 546 | NumberOfRelocations: 0 |
| 507 | NumberOfLinenumbers: 0 | 547 | NumberOfLinenumbers: 0 |
| ... | @@ -513,11 +553,11 @@ symbols: | ... | @@ -513,11 +553,11 @@ symbols: |
| 513 | SimpleType: IMAGE_SYM_TYPE_NULL | 553 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 514 | ComplexType: IMAGE_SYM_DTYPE_NULL | 554 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 515 | StorageClass: IMAGE_SYM_CLASS_STATIC | 555 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 516 | SectionDefinition: | 556 | SectionDefinition: |
| 517 | Length: 268 | 557 | Length: 112 |
| 518 | NumberOfRelocations: 0 | 558 | NumberOfRelocations: 0 |
| 519 | NumberOfLinenumbers: 0 | 559 | NumberOfLinenumbers: 0 |
| 520 | CheckSum: 3965031229 | 560 | CheckSum: 1535721080 |
| 521 | Number: 8 | 561 | Number: 8 |
| 522 | - Name: '@feat.00' | 562 | - Name: '@feat.00' |
| 523 | Value: 1 | 563 | Value: 1 |
deps/lld/test/COFF/Inputs/pdb-hashes-2-missing.yaml+56-48| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | --- !COFF | 1 | --- !COFF |
| 2 | header: | 2 | header: |
| 3 | Machine: IMAGE_FILE_MACHINE_I386 | 3 | Machine: IMAGE_FILE_MACHINE_I386 |
| 4 | Characteristics: [ ] | 4 | Characteristics: [ ] |
| 5 | sections: | 5 | sections: |
| 6 | - Name: .text | 6 | - Name: .text |
| 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 8 | Alignment: 16 | 8 | Alignment: 16 |
| ... | @@ -22,25 +22,25 @@ sections: | ... | @@ -22,25 +22,25 @@ sections: |
| 22 | - Name: '.debug$S' | 22 | - Name: '.debug$S' |
| 23 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 23 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 24 | Alignment: 4 | 24 | Alignment: 4 |
| 25 | SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000 | 25 | SectionData: 04000000F10000002F0000002D003C110100000007000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000 |
| 26 | Subsections: | 26 | Subsections: |
| 27 | - !Symbols | 27 | - !Symbols |
| 28 | Records: | 28 | Records: |
| 29 | - Kind: S_COMPILE3 | 29 | - Kind: S_COMPILE3 |
| 30 | Compile3Sym: | 30 | Compile3Sym: |
| 31 | Flags: [ ] | 31 | Flags: [ ] |
| 32 | Machine: Pentium3 | 32 | Machine: Pentium3 |
| 33 | FrontendMajor: 6 | 33 | FrontendMajor: 7 |
| 34 | FrontendMinor: 0 | 34 | FrontendMinor: 0 |
| 35 | FrontendBuild: 0 | 35 | FrontendBuild: 0 |
| 36 | FrontendQFE: 0 | 36 | FrontendQFE: 0 |
| 37 | BackendMajor: 6000 | 37 | BackendMajor: 7000 |
| 38 | BackendMinor: 0 | 38 | BackendMinor: 0 |
| 39 | BackendBuild: 0 | 39 | BackendBuild: 0 |
| 40 | BackendQFE: 0 | 40 | BackendQFE: 0 |
| 41 | Version: 'clang version 6.0.0 ' | 41 | Version: 'clang version 7.0.0 ' |
| 42 | - !FrameData | 42 | - !FrameData |
| 43 | Frames: | 43 | Frames: |
| 44 | - CodeSize: 25 | 44 | - CodeSize: 25 |
| 45 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | 45 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' |
| 46 | LocalSize: 0 | 46 | LocalSize: 0 |
| ... | @@ -66,9 +66,9 @@ sections: | ... | @@ -66,9 +66,9 @@ sections: |
| 66 | RvaStart: 3 | 66 | RvaStart: 3 |
| 67 | SavedRegsSize: 4 | 67 | SavedRegsSize: 4 |
| 68 | - !Symbols | 68 | - !Symbols |
| 69 | Records: | 69 | Records: |
| 70 | - Kind: S_GPROC32_ID | 70 | - Kind: S_GPROC32_ID |
| 71 | ProcSym: | 71 | ProcSym: |
| 72 | CodeSize: 25 | 72 | CodeSize: 25 |
| 73 | DbgStart: 0 | 73 | DbgStart: 0 |
| 74 | DbgEnd: 0 | 74 | DbgEnd: 0 |
| ... | @@ -76,22 +76,30 @@ sections: | ... | @@ -76,22 +76,30 @@ sections: |
| 76 | Flags: [ ] | 76 | Flags: [ ] |
| 77 | DisplayName: 'NS::func' | 77 | DisplayName: 'NS::func' |
| 78 | - Kind: S_LOCAL | 78 | - Kind: S_LOCAL |
| 79 | LocalSym: | 79 | LocalSym: |
| 80 | Type: 4099 | 80 | Type: 4099 |
| 81 | Flags: [ IsParameter ] | 81 | Flags: [ IsParameter ] |
| 82 | VarName: f | 82 | VarName: f |
| 83 | - Kind: S_DEFRANGE_REGISTER_REL | 83 | - Kind: S_DEFRANGE_REGISTER_REL |
| 84 | DefRangeRegisterRelSym: | 84 | DefRangeRegisterRelSym: |
| 85 | Register: 22 | ||
| 86 | Flags: 0 | ||
| 87 | BasePointerOffset: 8 | ||
| 88 | Range: | ||
| 89 | OffsetStart: 7 | ||
| 90 | ISectStart: 0 | ||
| 91 | Range: 18 | ||
| 92 | Gaps: | ||
| 85 | - Kind: S_PROC_ID_END | 93 | - Kind: S_PROC_ID_END |
| 86 | ScopeEndSym: | 94 | ScopeEndSym: |
| 87 | - !Lines | 95 | - !Lines |
| 88 | CodeSize: 25 | 96 | CodeSize: 25 |
| 89 | Flags: [ ] | 97 | Flags: [ ] |
| 90 | RelocOffset: 0 | 98 | RelocOffset: 0 |
| 91 | RelocSegment: 0 | 99 | RelocSegment: 0 |
| 92 | Blocks: | 100 | Blocks: |
| 93 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | 101 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' |
| 94 | Lines: | 102 | Lines: |
| 95 | - Offset: 0 | 103 | - Offset: 0 |
| 96 | LineStart: 3 | 104 | LineStart: 3 |
| 97 | IsStatement: false | 105 | IsStatement: false |
| ... | @@ -100,26 +108,26 @@ sections: | ... | @@ -100,26 +108,26 @@ sections: |
| 100 | LineStart: 4 | 108 | LineStart: 4 |
| 101 | IsStatement: false | 109 | IsStatement: false |
| 102 | EndDelta: 0 | 110 | EndDelta: 0 |
| 103 | Columns: | 111 | Columns: |
| 104 | - !Symbols | 112 | - !Symbols |
| 105 | Records: | 113 | Records: |
| 106 | - Kind: S_UDT | 114 | - Kind: S_UDT |
| 107 | UDTSym: | 115 | UDTSym: |
| 108 | Type: 4106 | 116 | Type: 4106 |
| 109 | UDTName: 'NS::Foo' | 117 | UDTName: 'NS::Foo' |
| 110 | - !FileChecksums | 118 | - !FileChecksums |
| 111 | Checksums: | 119 | Checksums: |
| 112 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | 120 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' |
| 113 | Kind: MD5 | 121 | Kind: MD5 |
| 114 | Checksum: 59DFAC75D18675AED1AD169FE316317E | 122 | Checksum: 59DFAC75D18675AED1AD169FE316317E |
| 115 | - !StringTable | 123 | - !StringTable |
| 116 | Strings: | 124 | Strings: |
| 117 | - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | 125 | - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' |
| 118 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | 126 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' |
| 119 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | 127 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' |
| 120 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | 128 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' |
| 121 | - '' | 129 | - '' |
| 122 | Relocations: | 130 | Relocations: |
| 123 | - VirtualAddress: 68 | 131 | - VirtualAddress: 68 |
| 124 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | 132 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' |
| 125 | Type: IMAGE_REL_I386_DIR32NB | 133 | Type: IMAGE_REL_I386_DIR32NB |
| ... | @@ -145,13 +153,13 @@ sections: | ... | @@ -145,13 +153,13 @@ sections: |
| 145 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 153 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 146 | Alignment: 4 | 154 | Alignment: 4 |
| 147 | SectionData: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1 | 155 | SectionData: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1 |
| 148 | Types: | 156 | Types: |
| 149 | - Kind: LF_STRING_ID | 157 | - Kind: LF_STRING_ID |
| 150 | StringId: | 158 | StringId: |
| 151 | Id: 0 | 159 | Id: 0 |
| 152 | String: NS | 160 | String: NS |
| 153 | - Kind: LF_STRUCTURE | 161 | - Kind: LF_STRUCTURE |
| 154 | Class: | 162 | Class: |
| 155 | MemberCount: 0 | 163 | MemberCount: 0 |
| 156 | Options: [ None, ForwardReference, HasUniqueName ] | 164 | Options: [ None, ForwardReference, HasUniqueName ] |
| 157 | FieldList: 0 | 165 | FieldList: 0 |
| ... | @@ -161,32 +169,32 @@ sections: | ... | @@ -161,32 +169,32 @@ sections: |
| 161 | VTableShape: 0 | 169 | VTableShape: 0 |
| 162 | Size: 0 | 170 | Size: 0 |
| 163 | - Kind: LF_MODIFIER | 171 | - Kind: LF_MODIFIER |
| 164 | Modifier: | 172 | Modifier: |
| 165 | ModifiedType: 4097 | 173 | ModifiedType: 4097 |
| 166 | Modifiers: [ None, Const ] | 174 | Modifiers: [ None, Const ] |
| 167 | - Kind: LF_POINTER | 175 | - Kind: LF_POINTER |
| 168 | Pointer: | 176 | Pointer: |
| 169 | ReferentType: 4098 | 177 | ReferentType: 4098 |
| 170 | Attrs: 32810 | 178 | Attrs: 32810 |
| 171 | - Kind: LF_ARGLIST | 179 | - Kind: LF_ARGLIST |
| 172 | ArgList: | 180 | ArgList: |
| 173 | ArgIndices: [ 4099 ] | 181 | ArgIndices: [ 4099 ] |
| 174 | - Kind: LF_PROCEDURE | 182 | - Kind: LF_PROCEDURE |
| 175 | Procedure: | 183 | Procedure: |
| 176 | ReturnType: 116 | 184 | ReturnType: 116 |
| 177 | CallConv: NearC | 185 | CallConv: NearC |
| 178 | Options: [ None ] | 186 | Options: [ None ] |
| 179 | ParameterCount: 1 | 187 | ParameterCount: 1 |
| 180 | ArgumentList: 4100 | 188 | ArgumentList: 4100 |
| 181 | - Kind: LF_POINTER | 189 | - Kind: LF_POINTER |
| 182 | Pointer: | 190 | Pointer: |
| 183 | ReferentType: 4097 | 191 | ReferentType: 4097 |
| 184 | Attrs: 32778 | 192 | Attrs: 32778 |
| 185 | - Kind: LF_ARGLIST | 193 | - Kind: LF_ARGLIST |
| 186 | ArgList: | 194 | ArgList: |
| 187 | ArgIndices: [ 116 ] | 195 | ArgIndices: [ 116 ] |
| 188 | - Kind: LF_MFUNCTION | 196 | - Kind: LF_MFUNCTION |
| 189 | MemberFunction: | 197 | MemberFunction: |
| 190 | ReturnType: 3 | 198 | ReturnType: 3 |
| 191 | ClassType: 4097 | 199 | ClassType: 4097 |
| 192 | ThisType: 4102 | 200 | ThisType: 4102 |
| ... | @@ -196,21 +204,21 @@ sections: | ... | @@ -196,21 +204,21 @@ sections: |
| 196 | ArgumentList: 4103 | 204 | ArgumentList: 4103 |
| 197 | ThisPointerAdjustment: 0 | 205 | ThisPointerAdjustment: 0 |
| 198 | - Kind: LF_FIELDLIST | 206 | - Kind: LF_FIELDLIST |
| 199 | FieldList: | 207 | FieldList: |
| 200 | - Kind: LF_MEMBER | 208 | - Kind: LF_MEMBER |
| 201 | DataMember: | 209 | DataMember: |
| 202 | Attrs: 3 | 210 | Attrs: 3 |
| 203 | Type: 116 | 211 | Type: 116 |
| 204 | FieldOffset: 0 | 212 | FieldOffset: 0 |
| 205 | Name: X | 213 | Name: X |
| 206 | - Kind: LF_ONEMETHOD | 214 | - Kind: LF_ONEMETHOD |
| 207 | OneMethod: | 215 | OneMethod: |
| 208 | Type: 4104 | 216 | Type: 4104 |
| 209 | Attrs: 3 | 217 | Attrs: 3 |
| 210 | VFTableOffset: -1 | 218 | VFTableOffset: -1 |
| 211 | Name: Foo | 219 | Name: Foo |
| 212 | - Kind: LF_STRUCTURE | 220 | - Kind: LF_STRUCTURE |
| 213 | Class: | 221 | Class: |
| 214 | MemberCount: 2 | 222 | MemberCount: 2 |
| 215 | Options: [ None, HasUniqueName ] | 223 | Options: [ None, HasUniqueName ] |
| 216 | FieldList: 4105 | 224 | FieldList: 4105 |
| ... | @@ -220,27 +228,27 @@ sections: | ... | @@ -220,27 +228,27 @@ sections: |
| 220 | VTableShape: 0 | 228 | VTableShape: 0 |
| 221 | Size: 4 | 229 | Size: 4 |
| 222 | - Kind: LF_STRING_ID | 230 | - Kind: LF_STRING_ID |
| 223 | StringId: | 231 | StringId: |
| 224 | Id: 0 | 232 | Id: 0 |
| 225 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | 233 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' |
| 226 | - Kind: LF_UDT_SRC_LINE | 234 | - Kind: LF_UDT_SRC_LINE |
| 227 | UdtSourceLine: | 235 | UdtSourceLine: |
| 228 | UDT: 4106 | 236 | UDT: 4106 |
| 229 | SourceFile: 4107 | 237 | SourceFile: 4107 |
| 230 | LineNumber: 2 | 238 | LineNumber: 2 |
| 231 | - Kind: LF_FUNC_ID | 239 | - Kind: LF_FUNC_ID |
| 232 | FuncId: | 240 | FuncId: |
| 233 | ParentScope: 4096 | 241 | ParentScope: 4096 |
| 234 | FunctionType: 4101 | 242 | FunctionType: 4101 |
| 235 | Name: func | 243 | Name: func |
| 236 | symbols: | 244 | symbols: |
| 237 | - Name: .text | 245 | - Name: .text |
| 238 | Value: 0 | 246 | Value: 0 |
| 239 | SectionNumber: 1 | 247 | SectionNumber: 1 |
| 240 | SimpleType: IMAGE_SYM_TYPE_NULL | 248 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 241 | ComplexType: IMAGE_SYM_DTYPE_NULL | 249 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 242 | StorageClass: IMAGE_SYM_CLASS_STATIC | 250 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 243 | SectionDefinition: | 251 | SectionDefinition: |
| 244 | Length: 25 | 252 | Length: 25 |
| 245 | NumberOfRelocations: 0 | 253 | NumberOfRelocations: 0 |
| 246 | NumberOfLinenumbers: 0 | 254 | NumberOfLinenumbers: 0 |
| ... | @@ -252,7 +260,7 @@ symbols: | ... | @@ -252,7 +260,7 @@ symbols: |
| 252 | SimpleType: IMAGE_SYM_TYPE_NULL | 260 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 253 | ComplexType: IMAGE_SYM_DTYPE_NULL | 261 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 254 | StorageClass: IMAGE_SYM_CLASS_STATIC | 262 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 255 | SectionDefinition: | 263 | SectionDefinition: |
| 256 | Length: 0 | 264 | Length: 0 |
| 257 | NumberOfRelocations: 0 | 265 | NumberOfRelocations: 0 |
| 258 | NumberOfLinenumbers: 0 | 266 | NumberOfLinenumbers: 0 |
| ... | @@ -264,7 +272,7 @@ symbols: | ... | @@ -264,7 +272,7 @@ symbols: |
| 264 | SimpleType: IMAGE_SYM_TYPE_NULL | 272 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 265 | ComplexType: IMAGE_SYM_DTYPE_NULL | 273 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 266 | StorageClass: IMAGE_SYM_CLASS_STATIC | 274 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 267 | SectionDefinition: | 275 | SectionDefinition: |
| 268 | Length: 0 | 276 | Length: 0 |
| 269 | NumberOfRelocations: 0 | 277 | NumberOfRelocations: 0 |
| 270 | NumberOfLinenumbers: 0 | 278 | NumberOfLinenumbers: 0 |
| ... | @@ -276,7 +284,7 @@ symbols: | ... | @@ -276,7 +284,7 @@ symbols: |
| 276 | SimpleType: IMAGE_SYM_TYPE_NULL | 284 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 277 | ComplexType: IMAGE_SYM_DTYPE_NULL | 285 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 278 | StorageClass: IMAGE_SYM_CLASS_STATIC | 286 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 279 | SectionDefinition: | 287 | SectionDefinition: |
| 280 | Length: 48 | 288 | Length: 48 |
| 281 | NumberOfRelocations: 0 | 289 | NumberOfRelocations: 0 |
| 282 | NumberOfLinenumbers: 0 | 290 | NumberOfLinenumbers: 0 |
| ... | @@ -288,11 +296,11 @@ symbols: | ... | @@ -288,11 +296,11 @@ symbols: |
| 288 | SimpleType: IMAGE_SYM_TYPE_NULL | 296 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 289 | ComplexType: IMAGE_SYM_DTYPE_NULL | 297 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 290 | StorageClass: IMAGE_SYM_CLASS_STATIC | 298 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 291 | SectionDefinition: | 299 | SectionDefinition: |
| 292 | Length: 584 | 300 | Length: 584 |
| 293 | NumberOfRelocations: 7 | 301 | NumberOfRelocations: 7 |
| 294 | NumberOfLinenumbers: 0 | 302 | NumberOfLinenumbers: 0 |
| 295 | CheckSum: 2847177244 | 303 | CheckSum: 917356735 |
| 296 | Number: 5 | 304 | Number: 5 |
| 297 | - Name: '.debug$T' | 305 | - Name: '.debug$T' |
| 298 | Value: 0 | 306 | Value: 0 |
| ... | @@ -300,7 +308,7 @@ symbols: | ... | @@ -300,7 +308,7 @@ symbols: |
| 300 | SimpleType: IMAGE_SYM_TYPE_NULL | 308 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 301 | ComplexType: IMAGE_SYM_DTYPE_NULL | 309 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 302 | StorageClass: IMAGE_SYM_CLASS_STATIC | 310 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 303 | SectionDefinition: | 311 | SectionDefinition: |
| 304 | Length: 320 | 312 | Length: 320 |
| 305 | NumberOfRelocations: 0 | 313 | NumberOfRelocations: 0 |
| 306 | NumberOfLinenumbers: 0 | 314 | NumberOfLinenumbers: 0 |
deps/lld/test/COFF/Inputs/pdb-hashes-2.yaml+77-69| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | --- !COFF | 1 | --- !COFF |
| 2 | header: | 2 | header: |
| 3 | Machine: IMAGE_FILE_MACHINE_I386 | 3 | Machine: IMAGE_FILE_MACHINE_I386 |
| 4 | Characteristics: [ ] | 4 | Characteristics: [ ] |
| 5 | sections: | 5 | sections: |
| 6 | - Name: .text | 6 | - Name: .text |
| 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 8 | Alignment: 16 | 8 | Alignment: 16 |
| ... | @@ -22,25 +22,25 @@ sections: | ... | @@ -22,25 +22,25 @@ sections: |
| 22 | - Name: '.debug$S' | 22 | - Name: '.debug$S' |
| 23 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 23 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 24 | Alignment: 4 | 24 | Alignment: 4 |
| 25 | SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000 | 25 | SectionData: 04000000F10000002F0000002D003C110100000007000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000 |
| 26 | Subsections: | 26 | Subsections: |
| 27 | - !Symbols | 27 | - !Symbols |
| 28 | Records: | 28 | Records: |
| 29 | - Kind: S_COMPILE3 | 29 | - Kind: S_COMPILE3 |
| 30 | Compile3Sym: | 30 | Compile3Sym: |
| 31 | Flags: [ ] | 31 | Flags: [ ] |
| 32 | Machine: Pentium3 | 32 | Machine: Pentium3 |
| 33 | FrontendMajor: 6 | 33 | FrontendMajor: 7 |
| 34 | FrontendMinor: 0 | 34 | FrontendMinor: 0 |
| 35 | FrontendBuild: 0 | 35 | FrontendBuild: 0 |
| 36 | FrontendQFE: 0 | 36 | FrontendQFE: 0 |
| 37 | BackendMajor: 6000 | 37 | BackendMajor: 7000 |
| 38 | BackendMinor: 0 | 38 | BackendMinor: 0 |
| 39 | BackendBuild: 0 | 39 | BackendBuild: 0 |
| 40 | BackendQFE: 0 | 40 | BackendQFE: 0 |
| 41 | Version: 'clang version 6.0.0 ' | 41 | Version: 'clang version 7.0.0 ' |
| 42 | - !FrameData | 42 | - !FrameData |
| 43 | Frames: | 43 | Frames: |
| 44 | - CodeSize: 25 | 44 | - CodeSize: 25 |
| 45 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | 45 | FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' |
| 46 | LocalSize: 0 | 46 | LocalSize: 0 |
| ... | @@ -66,9 +66,9 @@ sections: | ... | @@ -66,9 +66,9 @@ sections: |
| 66 | RvaStart: 3 | 66 | RvaStart: 3 |
| 67 | SavedRegsSize: 4 | 67 | SavedRegsSize: 4 |
| 68 | - !Symbols | 68 | - !Symbols |
| 69 | Records: | 69 | Records: |
| 70 | - Kind: S_GPROC32_ID | 70 | - Kind: S_GPROC32_ID |
| 71 | ProcSym: | 71 | ProcSym: |
| 72 | CodeSize: 25 | 72 | CodeSize: 25 |
| 73 | DbgStart: 0 | 73 | DbgStart: 0 |
| 74 | DbgEnd: 0 | 74 | DbgEnd: 0 |
| ... | @@ -76,22 +76,30 @@ sections: | ... | @@ -76,22 +76,30 @@ sections: |
| 76 | Flags: [ ] | 76 | Flags: [ ] |
| 77 | DisplayName: 'NS::func' | 77 | DisplayName: 'NS::func' |
| 78 | - Kind: S_LOCAL | 78 | - Kind: S_LOCAL |
| 79 | LocalSym: | 79 | LocalSym: |
| 80 | Type: 4099 | 80 | Type: 4099 |
| 81 | Flags: [ IsParameter ] | 81 | Flags: [ IsParameter ] |
| 82 | VarName: f | 82 | VarName: f |
| 83 | - Kind: S_DEFRANGE_REGISTER_REL | 83 | - Kind: S_DEFRANGE_REGISTER_REL |
| 84 | DefRangeRegisterRelSym: | 84 | DefRangeRegisterRelSym: |
| 85 | Register: 22 | ||
| 86 | Flags: 0 | ||
| 87 | BasePointerOffset: 8 | ||
| 88 | Range: | ||
| 89 | OffsetStart: 7 | ||
| 90 | ISectStart: 0 | ||
| 91 | Range: 18 | ||
| 92 | Gaps: | ||
| 85 | - Kind: S_PROC_ID_END | 93 | - Kind: S_PROC_ID_END |
| 86 | ScopeEndSym: | 94 | ScopeEndSym: |
| 87 | - !Lines | 95 | - !Lines |
| 88 | CodeSize: 25 | 96 | CodeSize: 25 |
| 89 | Flags: [ ] | 97 | Flags: [ ] |
| 90 | RelocOffset: 0 | 98 | RelocOffset: 0 |
| 91 | RelocSegment: 0 | 99 | RelocSegment: 0 |
| 92 | Blocks: | 100 | Blocks: |
| 93 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | 101 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' |
| 94 | Lines: | 102 | Lines: |
| 95 | - Offset: 0 | 103 | - Offset: 0 |
| 96 | LineStart: 3 | 104 | LineStart: 3 |
| 97 | IsStatement: false | 105 | IsStatement: false |
| ... | @@ -100,26 +108,26 @@ sections: | ... | @@ -100,26 +108,26 @@ sections: |
| 100 | LineStart: 4 | 108 | LineStart: 4 |
| 101 | IsStatement: false | 109 | IsStatement: false |
| 102 | EndDelta: 0 | 110 | EndDelta: 0 |
| 103 | Columns: | 111 | Columns: |
| 104 | - !Symbols | 112 | - !Symbols |
| 105 | Records: | 113 | Records: |
| 106 | - Kind: S_UDT | 114 | - Kind: S_UDT |
| 107 | UDTSym: | 115 | UDTSym: |
| 108 | Type: 4106 | 116 | Type: 4106 |
| 109 | UDTName: 'NS::Foo' | 117 | UDTName: 'NS::Foo' |
| 110 | - !FileChecksums | 118 | - !FileChecksums |
| 111 | Checksums: | 119 | Checksums: |
| 112 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | 120 | - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' |
| 113 | Kind: MD5 | 121 | Kind: MD5 |
| 114 | Checksum: 59DFAC75D18675AED1AD169FE316317E | 122 | Checksum: 59DFAC75D18675AED1AD169FE316317E |
| 115 | - !StringTable | 123 | - !StringTable |
| 116 | Strings: | 124 | Strings: |
| 117 | - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' | 125 | - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' |
| 118 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' | 126 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' |
| 119 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | 127 | - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' |
| 120 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' | 128 | - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' |
| 121 | - '' | 129 | - '' |
| 122 | Relocations: | 130 | Relocations: |
| 123 | - VirtualAddress: 68 | 131 | - VirtualAddress: 68 |
| 124 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' | 132 | SymbolName: '?func@NS@@YAHABUFoo@1@@Z' |
| 125 | Type: IMAGE_REL_I386_DIR32NB | 133 | Type: IMAGE_REL_I386_DIR32NB |
| ... | @@ -145,13 +153,13 @@ sections: | ... | @@ -145,13 +153,13 @@ sections: |
| 145 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 153 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 146 | Alignment: 4 | 154 | Alignment: 4 |
| 147 | SectionData: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1 | 155 | SectionData: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1 |
| 148 | Types: | 156 | Types: |
| 149 | - Kind: LF_STRING_ID | 157 | - Kind: LF_STRING_ID |
| 150 | StringId: | 158 | StringId: |
| 151 | Id: 0 | 159 | Id: 0 |
| 152 | String: NS | 160 | String: NS |
| 153 | - Kind: LF_STRUCTURE | 161 | - Kind: LF_STRUCTURE |
| 154 | Class: | 162 | Class: |
| 155 | MemberCount: 0 | 163 | MemberCount: 0 |
| 156 | Options: [ None, ForwardReference, HasUniqueName ] | 164 | Options: [ None, ForwardReference, HasUniqueName ] |
| 157 | FieldList: 0 | 165 | FieldList: 0 |
| ... | @@ -161,32 +169,32 @@ sections: | ... | @@ -161,32 +169,32 @@ sections: |
| 161 | VTableShape: 0 | 169 | VTableShape: 0 |
| 162 | Size: 0 | 170 | Size: 0 |
| 163 | - Kind: LF_MODIFIER | 171 | - Kind: LF_MODIFIER |
| 164 | Modifier: | 172 | Modifier: |
| 165 | ModifiedType: 4097 | 173 | ModifiedType: 4097 |
| 166 | Modifiers: [ None, Const ] | 174 | Modifiers: [ None, Const ] |
| 167 | - Kind: LF_POINTER | 175 | - Kind: LF_POINTER |
| 168 | Pointer: | 176 | Pointer: |
| 169 | ReferentType: 4098 | 177 | ReferentType: 4098 |
| 170 | Attrs: 32810 | 178 | Attrs: 32810 |
| 171 | - Kind: LF_ARGLIST | 179 | - Kind: LF_ARGLIST |
| 172 | ArgList: | 180 | ArgList: |
| 173 | ArgIndices: [ 4099 ] | 181 | ArgIndices: [ 4099 ] |
| 174 | - Kind: LF_PROCEDURE | 182 | - Kind: LF_PROCEDURE |
| 175 | Procedure: | 183 | Procedure: |
| 176 | ReturnType: 116 | 184 | ReturnType: 116 |
| 177 | CallConv: NearC | 185 | CallConv: NearC |
| 178 | Options: [ None ] | 186 | Options: [ None ] |
| 179 | ParameterCount: 1 | 187 | ParameterCount: 1 |
| 180 | ArgumentList: 4100 | 188 | ArgumentList: 4100 |
| 181 | - Kind: LF_POINTER | 189 | - Kind: LF_POINTER |
| 182 | Pointer: | 190 | Pointer: |
| 183 | ReferentType: 4097 | 191 | ReferentType: 4097 |
| 184 | Attrs: 32778 | 192 | Attrs: 32778 |
| 185 | - Kind: LF_ARGLIST | 193 | - Kind: LF_ARGLIST |
| 186 | ArgList: | 194 | ArgList: |
| 187 | ArgIndices: [ 116 ] | 195 | ArgIndices: [ 116 ] |
| 188 | - Kind: LF_MFUNCTION | 196 | - Kind: LF_MFUNCTION |
| 189 | MemberFunction: | 197 | MemberFunction: |
| 190 | ReturnType: 3 | 198 | ReturnType: 3 |
| 191 | ClassType: 4097 | 199 | ClassType: 4097 |
| 192 | ThisType: 4102 | 200 | ThisType: 4102 |
| ... | @@ -196,21 +204,21 @@ sections: | ... | @@ -196,21 +204,21 @@ sections: |
| 196 | ArgumentList: 4103 | 204 | ArgumentList: 4103 |
| 197 | ThisPointerAdjustment: 0 | 205 | ThisPointerAdjustment: 0 |
| 198 | - Kind: LF_FIELDLIST | 206 | - Kind: LF_FIELDLIST |
| 199 | FieldList: | 207 | FieldList: |
| 200 | - Kind: LF_MEMBER | 208 | - Kind: LF_MEMBER |
| 201 | DataMember: | 209 | DataMember: |
| 202 | Attrs: 3 | 210 | Attrs: 3 |
| 203 | Type: 116 | 211 | Type: 116 |
| 204 | FieldOffset: 0 | 212 | FieldOffset: 0 |
| 205 | Name: X | 213 | Name: X |
| 206 | - Kind: LF_ONEMETHOD | 214 | - Kind: LF_ONEMETHOD |
| 207 | OneMethod: | 215 | OneMethod: |
| 208 | Type: 4104 | 216 | Type: 4104 |
| 209 | Attrs: 3 | 217 | Attrs: 3 |
| 210 | VFTableOffset: -1 | 218 | VFTableOffset: -1 |
| 211 | Name: Foo | 219 | Name: Foo |
| 212 | - Kind: LF_STRUCTURE | 220 | - Kind: LF_STRUCTURE |
| 213 | Class: | 221 | Class: |
| 214 | MemberCount: 2 | 222 | MemberCount: 2 |
| 215 | Options: [ None, HasUniqueName ] | 223 | Options: [ None, HasUniqueName ] |
| 216 | FieldList: 4105 | 224 | FieldList: 4105 |
| ... | @@ -220,49 +228,49 @@ sections: | ... | @@ -220,49 +228,49 @@ sections: |
| 220 | VTableShape: 0 | 228 | VTableShape: 0 |
| 221 | Size: 4 | 229 | Size: 4 |
| 222 | - Kind: LF_STRING_ID | 230 | - Kind: LF_STRING_ID |
| 223 | StringId: | 231 | StringId: |
| 224 | Id: 0 | 232 | Id: 0 |
| 225 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' | 233 | String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' |
| 226 | - Kind: LF_UDT_SRC_LINE | 234 | - Kind: LF_UDT_SRC_LINE |
| 227 | UdtSourceLine: | 235 | UdtSourceLine: |
| 228 | UDT: 4106 | 236 | UDT: 4106 |
| 229 | SourceFile: 4107 | 237 | SourceFile: 4107 |
| 230 | LineNumber: 2 | 238 | LineNumber: 2 |
| 231 | - Kind: LF_FUNC_ID | 239 | - Kind: LF_FUNC_ID |
| 232 | FuncId: | 240 | FuncId: |
| 233 | ParentScope: 4096 | 241 | ParentScope: 4096 |
| 234 | FunctionType: 4101 | 242 | FunctionType: 4101 |
| 235 | Name: func | 243 | Name: func |
| 236 | - Name: '.debug$H' | 244 | - Name: '.debug$H' |
| 237 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | 245 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] |
| 238 | Alignment: 4 | 246 | Alignment: 4 |
| 239 | SectionData: C5C9330100000000EC145CD76AEFE74E78880D531132B3BB8FFACEF79E616EF06A14EA74A2420F9062A1FB04917E59759949E334BA18509ED692F3C65CE242D8450EBC78B81B63AF8316DC324562EB9F0D4A0D708E8A25C263DB05943C19B84A36719E1E414DDA3EDBDF005322238D70F9058EEDC5C50EF11BC849618B51FD89E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D89DCBC783AF285D9DBB672F67A81E36906B2038B57 | 247 | SectionData: C5C93301000001004A061540B751965F23ADA4E788EB7A9032673B3BABE3CA5356B1521BDAE4BEA70661C95750D0206E896FB09488EE8E1BB5DECADF1A832BA46632585CDC7606E4B97B86241E5F45B0BCD2406E22465E11A528BEF0A7F589C76079F1186C40C2165091EFEBD5B5446B5AAD8721C21DF3E6 |
| 240 | GlobalHashes: | 248 | GlobalHashes: |
| 241 | Version: 0 | 249 | Version: 0 |
| 242 | HashAlgorithm: 0 | 250 | HashAlgorithm: 1 |
| 243 | HashValues: | 251 | HashValues: |
| 244 | - EC145CD76AEFE74E78880D531132B3BB8FFACEF7 | 252 | - 4A061540B751965F |
| 245 | - 9E616EF06A14EA74A2420F9062A1FB04917E5975 | 253 | - 23ADA4E788EB7A90 |
| 246 | - 9949E334BA18509ED692F3C65CE242D8450EBC78 | 254 | - 32673B3BABE3CA53 |
| 247 | - B81B63AF8316DC324562EB9F0D4A0D708E8A25C2 | 255 | - 56B1521BDAE4BEA7 |
| 248 | - 63DB05943C19B84A36719E1E414DDA3EDBDF0053 | 256 | - 0661C95750D0206E |
| 249 | - 22238D70F9058EEDC5C50EF11BC849618B51FD89 | 257 | - 896FB09488EE8E1B |
| 250 | - E3A50EABE5E8FE3945468547C19DC681D0BFB3B7 | 258 | - B5DECADF1A832BA4 |
| 251 | - 97DD91CA4D7F1953C314442D5549419E78044E38 | 259 | - 6632585CDC7606E4 |
| 252 | - A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0 | 260 | - B97B86241E5F45B0 |
| 253 | - C0A9021B711ACC4F67008974EBF441031BDD653F | 261 | - BCD2406E22465E11 |
| 254 | - 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA | 262 | - A528BEF0A7F589C7 |
| 255 | - 0AF6C1846743F43D846BB19517E12E8873BBA90C | 263 | - 6079F1186C40C216 |
| 256 | - C41DD1BEAC89CBA8897AC1BA46762E2557A82D89 | 264 | - 5091EFEBD5B5446B |
| 257 | - DCBC783AF285D9DBB672F67A81E36906B2038B57 | 265 | - 5AAD8721C21DF3E6 |
| 258 | symbols: | 266 | symbols: |
| 259 | - Name: .text | 267 | - Name: .text |
| 260 | Value: 0 | 268 | Value: 0 |
| 261 | SectionNumber: 1 | 269 | SectionNumber: 1 |
| 262 | SimpleType: IMAGE_SYM_TYPE_NULL | 270 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 263 | ComplexType: IMAGE_SYM_DTYPE_NULL | 271 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 264 | StorageClass: IMAGE_SYM_CLASS_STATIC | 272 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 265 | SectionDefinition: | 273 | SectionDefinition: |
| 266 | Length: 25 | 274 | Length: 25 |
| 267 | NumberOfRelocations: 0 | 275 | NumberOfRelocations: 0 |
| 268 | NumberOfLinenumbers: 0 | 276 | NumberOfLinenumbers: 0 |
| ... | @@ -274,7 +282,7 @@ symbols: | ... | @@ -274,7 +282,7 @@ symbols: |
| 274 | SimpleType: IMAGE_SYM_TYPE_NULL | 282 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 275 | ComplexType: IMAGE_SYM_DTYPE_NULL | 283 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 276 | StorageClass: IMAGE_SYM_CLASS_STATIC | 284 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 277 | SectionDefinition: | 285 | SectionDefinition: |
| 278 | Length: 0 | 286 | Length: 0 |
| 279 | NumberOfRelocations: 0 | 287 | NumberOfRelocations: 0 |
| 280 | NumberOfLinenumbers: 0 | 288 | NumberOfLinenumbers: 0 |
| ... | @@ -286,7 +294,7 @@ symbols: | ... | @@ -286,7 +294,7 @@ symbols: |
| 286 | SimpleType: IMAGE_SYM_TYPE_NULL | 294 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 287 | ComplexType: IMAGE_SYM_DTYPE_NULL | 295 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 288 | StorageClass: IMAGE_SYM_CLASS_STATIC | 296 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 289 | SectionDefinition: | 297 | SectionDefinition: |
| 290 | Length: 0 | 298 | Length: 0 |
| 291 | NumberOfRelocations: 0 | 299 | NumberOfRelocations: 0 |
| 292 | NumberOfLinenumbers: 0 | 300 | NumberOfLinenumbers: 0 |
| ... | @@ -298,7 +306,7 @@ symbols: | ... | @@ -298,7 +306,7 @@ symbols: |
| 298 | SimpleType: IMAGE_SYM_TYPE_NULL | 306 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 299 | ComplexType: IMAGE_SYM_DTYPE_NULL | 307 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 300 | StorageClass: IMAGE_SYM_CLASS_STATIC | 308 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 301 | SectionDefinition: | 309 | SectionDefinition: |
| 302 | Length: 48 | 310 | Length: 48 |
| 303 | NumberOfRelocations: 0 | 311 | NumberOfRelocations: 0 |
| 304 | NumberOfLinenumbers: 0 | 312 | NumberOfLinenumbers: 0 |
| ... | @@ -310,11 +318,11 @@ symbols: | ... | @@ -310,11 +318,11 @@ symbols: |
| 310 | SimpleType: IMAGE_SYM_TYPE_NULL | 318 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 311 | ComplexType: IMAGE_SYM_DTYPE_NULL | 319 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 312 | StorageClass: IMAGE_SYM_CLASS_STATIC | 320 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 313 | SectionDefinition: | 321 | SectionDefinition: |
| 314 | Length: 584 | 322 | Length: 584 |
| 315 | NumberOfRelocations: 7 | 323 | NumberOfRelocations: 7 |
| 316 | NumberOfLinenumbers: 0 | 324 | NumberOfLinenumbers: 0 |
| 317 | CheckSum: 2847177244 | 325 | CheckSum: 917356735 |
| 318 | Number: 5 | 326 | Number: 5 |
| 319 | - Name: '.debug$T' | 327 | - Name: '.debug$T' |
| 320 | Value: 0 | 328 | Value: 0 |
| ... | @@ -322,7 +330,7 @@ symbols: | ... | @@ -322,7 +330,7 @@ symbols: |
| 322 | SimpleType: IMAGE_SYM_TYPE_NULL | 330 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 323 | ComplexType: IMAGE_SYM_DTYPE_NULL | 331 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 324 | StorageClass: IMAGE_SYM_CLASS_STATIC | 332 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 325 | SectionDefinition: | 333 | SectionDefinition: |
| 326 | Length: 320 | 334 | Length: 320 |
| 327 | NumberOfRelocations: 0 | 335 | NumberOfRelocations: 0 |
| 328 | NumberOfLinenumbers: 0 | 336 | NumberOfLinenumbers: 0 |
| ... | @@ -334,11 +342,11 @@ symbols: | ... | @@ -334,11 +342,11 @@ symbols: |
| 334 | SimpleType: IMAGE_SYM_TYPE_NULL | 342 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 335 | ComplexType: IMAGE_SYM_DTYPE_NULL | 343 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 336 | StorageClass: IMAGE_SYM_CLASS_STATIC | 344 | StorageClass: IMAGE_SYM_CLASS_STATIC |
| 337 | SectionDefinition: | 345 | SectionDefinition: |
| 338 | Length: 288 | 346 | Length: 120 |
| 339 | NumberOfRelocations: 0 | 347 | NumberOfRelocations: 0 |
| 340 | NumberOfLinenumbers: 0 | 348 | NumberOfLinenumbers: 0 |
| 341 | CheckSum: 2348181452 | 349 | CheckSum: 358820662 |
| 342 | Number: 7 | 350 | Number: 7 |
| 343 | - Name: '@feat.00' | 351 | - Name: '@feat.00' |
| 344 | Value: 1 | 352 | Value: 1 |
deps/lld/test/COFF/Inputs/pdb-scopes-a.yaml+4-4| ... | @@ -53,7 +53,7 @@ sections: | ... | @@ -53,7 +53,7 @@ sections: |
| 53 | RegRelativeSym: | 53 | RegRelativeSym: |
| 54 | Offset: 8 | 54 | Offset: 8 |
| 55 | Type: 116 | 55 | Type: 116 |
| 56 | Register: RSP | 56 | Register: CVRegRSP |
| 57 | VarName: x | 57 | VarName: x |
| 58 | - Kind: S_PROC_ID_END | 58 | - Kind: S_PROC_ID_END |
| 59 | ScopeEndSym: | 59 | ScopeEndSym: |
| ... | @@ -93,7 +93,7 @@ sections: | ... | @@ -93,7 +93,7 @@ sections: |
| 93 | RegRelativeSym: | 93 | RegRelativeSym: |
| 94 | Offset: 64 | 94 | Offset: 64 |
| 95 | Type: 116 | 95 | Type: 116 |
| 96 | Register: RSP | 96 | Register: CVRegRSP |
| 97 | VarName: argc | 97 | VarName: argc |
| 98 | - Kind: S_BLOCK32 | 98 | - Kind: S_BLOCK32 |
| 99 | BlockSym: | 99 | BlockSym: |
| ... | @@ -104,7 +104,7 @@ sections: | ... | @@ -104,7 +104,7 @@ sections: |
| 104 | RegRelativeSym: | 104 | RegRelativeSym: |
| 105 | Offset: 32 | 105 | Offset: 32 |
| 106 | Type: 116 | 106 | Type: 116 |
| 107 | Register: RSP | 107 | Register: CVRegRSP |
| 108 | VarName: x | 108 | VarName: x |
| 109 | - Kind: S_END | 109 | - Kind: S_END |
| 110 | ScopeEndSym: | 110 | ScopeEndSym: |
| ... | @@ -117,7 +117,7 @@ sections: | ... | @@ -117,7 +117,7 @@ sections: |
| 117 | RegRelativeSym: | 117 | RegRelativeSym: |
| 118 | Offset: 36 | 118 | Offset: 36 |
| 119 | Type: 116 | 119 | Type: 116 |
| 120 | Register: RSP | 120 | Register: CVRegRSP |
| 121 | VarName: y | 121 | VarName: y |
| 122 | - Kind: S_END | 122 | - Kind: S_END |
| 123 | ScopeEndSym: | 123 | ScopeEndSym: |
deps/lld/test/COFF/Inputs/pdb-scopes-b.yaml+3-3| ... | @@ -53,7 +53,7 @@ sections: | ... | @@ -53,7 +53,7 @@ sections: |
| 53 | RegRelativeSym: | 53 | RegRelativeSym: |
| 54 | Offset: 64 | 54 | Offset: 64 |
| 55 | Type: 116 | 55 | Type: 116 |
| 56 | Register: RSP | 56 | Register: CVRegRSP |
| 57 | VarName: x | 57 | VarName: x |
| 58 | - Kind: S_BLOCK32 | 58 | - Kind: S_BLOCK32 |
| 59 | BlockSym: | 59 | BlockSym: |
| ... | @@ -64,7 +64,7 @@ sections: | ... | @@ -64,7 +64,7 @@ sections: |
| 64 | RegRelativeSym: | 64 | RegRelativeSym: |
| 65 | Offset: 32 | 65 | Offset: 32 |
| 66 | Type: 116 | 66 | Type: 116 |
| 67 | Register: RSP | 67 | Register: CVRegRSP |
| 68 | VarName: y | 68 | VarName: y |
| 69 | - Kind: S_END | 69 | - Kind: S_END |
| 70 | ScopeEndSym: | 70 | ScopeEndSym: |
| ... | @@ -77,7 +77,7 @@ sections: | ... | @@ -77,7 +77,7 @@ sections: |
| 77 | RegRelativeSym: | 77 | RegRelativeSym: |
| 78 | Offset: 36 | 78 | Offset: 36 |
| 79 | Type: 116 | 79 | Type: 116 |
| 80 | Register: RSP | 80 | Register: CVRegRSP |
| 81 | VarName: w | 81 | VarName: w |
| 82 | - Kind: S_END | 82 | - Kind: S_END |
| 83 | ScopeEndSym: | 83 | ScopeEndSym: |
deps/lld/test/COFF/Inputs/pdb-type-server-simple-a.yaml+1-1| ... | @@ -53,7 +53,7 @@ sections: | ... | @@ -53,7 +53,7 @@ sections: |
| 53 | RegRelativeSym: | 53 | RegRelativeSym: |
| 54 | Offset: 32 | 54 | Offset: 32 |
| 55 | Type: 4102 | 55 | Type: 4102 |
| 56 | Register: RSP | 56 | Register: CVRegRSP |
| 57 | VarName: f | 57 | VarName: f |
| 58 | - Kind: S_PROC_ID_END | 58 | - Kind: S_PROC_ID_END |
| 59 | ScopeEndSym: | 59 | ScopeEndSym: |
deps/lld/test/COFF/Inputs/pdb-type-server-simple-b.yaml+1-1| ... | @@ -53,7 +53,7 @@ sections: | ... | @@ -53,7 +53,7 @@ sections: |
| 53 | RegRelativeSym: | 53 | RegRelativeSym: |
| 54 | Offset: 8 | 54 | Offset: 8 |
| 55 | Type: 4097 | 55 | Type: 4097 |
| 56 | Register: RSP | 56 | Register: CVRegRSP |
| 57 | VarName: p | 57 | VarName: p |
| 58 | - Kind: S_PROC_ID_END | 58 | - Kind: S_PROC_ID_END |
| 59 | ScopeEndSym: | 59 | ScopeEndSym: |
deps/lld/test/COFF/Inputs/pdb_lines_1_relative.yaml created+401| ... | @@ -0,0 +1,401 @@ | ||
| 1 | --- !COFF | ||
| 2 | header: | ||
| 3 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 4 | Characteristics: [ ] | ||
| 5 | sections: | ||
| 6 | - Name: .text | ||
| 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 8 | Alignment: 16 | ||
| 9 | SectionData: 4883EC28C744242400000000E800000000B82A0000004883C428C3 | ||
| 10 | Relocations: | ||
| 11 | - VirtualAddress: 13 | ||
| 12 | SymbolName: foo | ||
| 13 | Type: IMAGE_REL_AMD64_REL32 | ||
| 14 | - Name: .data | ||
| 15 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 16 | Alignment: 4 | ||
| 17 | SectionData: '' | ||
| 18 | - Name: .bss | ||
| 19 | Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 20 | Alignment: 4 | ||
| 21 | SectionData: '' | ||
| 22 | - Name: .xdata | ||
| 23 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 24 | Alignment: 4 | ||
| 25 | SectionData: '0104010004420000' | ||
| 26 | - Name: .text | ||
| 27 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 28 | Alignment: 16 | ||
| 29 | SectionData: 4883EC28E800000000904883C428C3 | ||
| 30 | Relocations: | ||
| 31 | - VirtualAddress: 5 | ||
| 32 | SymbolName: bar | ||
| 33 | Type: IMAGE_REL_AMD64_REL32 | ||
| 34 | - Name: .drectve | ||
| 35 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | ||
| 36 | Alignment: 1 | ||
| 37 | SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 | ||
| 38 | - Name: '.debug$S' | ||
| 39 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 40 | Alignment: 4 | ||
| 41 | SectionData: 04000000F10000002F0000002D003C1100000000D0000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F1000000300000002A0047110000000000000000000000001B000000000000000000000002100000000000000000006D61696E0002004F11F20000003000000000000000000000001B00000000000000030000002400000000000000020000000C000000030000001100000004000000F400000030000000010000001001EA6429BCE282CCF3F0E3CD93B216EB410000110000001001061EB73ABB642532857A4F1D9CBAC3230000F30000001C000000002E5C7064625F6C696E65735F312E63002E5C666F6F2E6800000000 | ||
| 42 | Subsections: | ||
| 43 | - !Symbols | ||
| 44 | Records: | ||
| 45 | - Kind: S_COMPILE3 | ||
| 46 | Compile3Sym: | ||
| 47 | Flags: [ ] | ||
| 48 | Machine: X64 | ||
| 49 | FrontendMajor: 7 | ||
| 50 | FrontendMinor: 0 | ||
| 51 | FrontendBuild: 0 | ||
| 52 | FrontendQFE: 0 | ||
| 53 | BackendMajor: 7000 | ||
| 54 | BackendMinor: 0 | ||
| 55 | BackendBuild: 0 | ||
| 56 | BackendQFE: 0 | ||
| 57 | Version: 'clang version 7.0.0 ' | ||
| 58 | - !Symbols | ||
| 59 | Records: | ||
| 60 | - Kind: S_GPROC32_ID | ||
| 61 | ProcSym: | ||
| 62 | CodeSize: 27 | ||
| 63 | DbgStart: 0 | ||
| 64 | DbgEnd: 0 | ||
| 65 | FunctionType: 4098 | ||
| 66 | Flags: [ ] | ||
| 67 | DisplayName: main | ||
| 68 | - Kind: S_PROC_ID_END | ||
| 69 | ScopeEndSym: | ||
| 70 | - !Lines | ||
| 71 | CodeSize: 27 | ||
| 72 | Flags: [ ] | ||
| 73 | RelocOffset: 0 | ||
| 74 | RelocSegment: 0 | ||
| 75 | Blocks: | ||
| 76 | - FileName: '.\pdb_lines_1.c' | ||
| 77 | Lines: | ||
| 78 | - Offset: 0 | ||
| 79 | LineStart: 2 | ||
| 80 | IsStatement: false | ||
| 81 | EndDelta: 0 | ||
| 82 | - Offset: 12 | ||
| 83 | LineStart: 3 | ||
| 84 | IsStatement: false | ||
| 85 | EndDelta: 0 | ||
| 86 | - Offset: 17 | ||
| 87 | LineStart: 4 | ||
| 88 | IsStatement: false | ||
| 89 | EndDelta: 0 | ||
| 90 | Columns: | ||
| 91 | - !FileChecksums | ||
| 92 | Checksums: | ||
| 93 | - FileName: '.\pdb_lines_1.c' | ||
| 94 | Kind: MD5 | ||
| 95 | Checksum: EA6429BCE282CCF3F0E3CD93B216EB41 | ||
| 96 | - FileName: '.\foo.h' | ||
| 97 | Kind: MD5 | ||
| 98 | Checksum: 061EB73ABB642532857A4F1D9CBAC323 | ||
| 99 | - !StringTable | ||
| 100 | Strings: | ||
| 101 | - '.\pdb_lines_1.c' | ||
| 102 | - '.\foo.h' | ||
| 103 | - '' | ||
| 104 | - '' | ||
| 105 | - '' | ||
| 106 | Relocations: | ||
| 107 | - VirtualAddress: 100 | ||
| 108 | SymbolName: main | ||
| 109 | Type: IMAGE_REL_AMD64_SECREL | ||
| 110 | - VirtualAddress: 104 | ||
| 111 | SymbolName: main | ||
| 112 | Type: IMAGE_REL_AMD64_SECTION | ||
| 113 | - VirtualAddress: 124 | ||
| 114 | SymbolName: main | ||
| 115 | Type: IMAGE_REL_AMD64_SECREL | ||
| 116 | - VirtualAddress: 128 | ||
| 117 | SymbolName: main | ||
| 118 | Type: IMAGE_REL_AMD64_SECTION | ||
| 119 | - Name: '.debug$T' | ||
| 120 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 121 | Alignment: 4 | ||
| 122 | SectionData: 0400000006000112000000000E0008107400000000000000001000001200011600000000011000006D61696E00F3F2F10E0008100300000000000000001000000E0001160000000003100000666F6F00 | ||
| 123 | Types: | ||
| 124 | - Kind: LF_ARGLIST | ||
| 125 | ArgList: | ||
| 126 | ArgIndices: [ ] | ||
| 127 | - Kind: LF_PROCEDURE | ||
| 128 | Procedure: | ||
| 129 | ReturnType: 116 | ||
| 130 | CallConv: NearC | ||
| 131 | Options: [ None ] | ||
| 132 | ParameterCount: 0 | ||
| 133 | ArgumentList: 4096 | ||
| 134 | - Kind: LF_FUNC_ID | ||
| 135 | FuncId: | ||
| 136 | ParentScope: 0 | ||
| 137 | FunctionType: 4097 | ||
| 138 | Name: main | ||
| 139 | - Kind: LF_PROCEDURE | ||
| 140 | Procedure: | ||
| 141 | ReturnType: 3 | ||
| 142 | CallConv: NearC | ||
| 143 | Options: [ None ] | ||
| 144 | ParameterCount: 0 | ||
| 145 | ArgumentList: 4096 | ||
| 146 | - Kind: LF_FUNC_ID | ||
| 147 | FuncId: | ||
| 148 | ParentScope: 0 | ||
| 149 | FunctionType: 4099 | ||
| 150 | Name: foo | ||
| 151 | - Name: .pdata | ||
| 152 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 153 | Alignment: 4 | ||
| 154 | SectionData: 000000001B00000000000000 | ||
| 155 | Relocations: | ||
| 156 | - VirtualAddress: 0 | ||
| 157 | SymbolName: main | ||
| 158 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 159 | - VirtualAddress: 4 | ||
| 160 | SymbolName: main | ||
| 161 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 162 | - VirtualAddress: 8 | ||
| 163 | SymbolName: .xdata | ||
| 164 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 165 | - Name: .xdata | ||
| 166 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | ||
| 167 | Alignment: 4 | ||
| 168 | SectionData: '0104010004420000' | ||
| 169 | - Name: '.debug$S' | ||
| 170 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 171 | Alignment: 4 | ||
| 172 | SectionData: 04000000F10000002F000000290047110000000000000000000000000F00000000000000000000000410000000000000000000666F6F0002004F1100F20000003000000000000000000000000F000000180000000300000024000000000000000200000004000000030000000900000004000000 | ||
| 173 | Subsections: | ||
| 174 | - !Symbols | ||
| 175 | Records: | ||
| 176 | - Kind: S_GPROC32_ID | ||
| 177 | ProcSym: | ||
| 178 | CodeSize: 15 | ||
| 179 | DbgStart: 0 | ||
| 180 | DbgEnd: 0 | ||
| 181 | FunctionType: 4100 | ||
| 182 | Flags: [ ] | ||
| 183 | DisplayName: foo | ||
| 184 | - Kind: S_PROC_ID_END | ||
| 185 | ScopeEndSym: | ||
| 186 | - !Lines | ||
| 187 | CodeSize: 15 | ||
| 188 | Flags: [ ] | ||
| 189 | RelocOffset: 0 | ||
| 190 | RelocSegment: 0 | ||
| 191 | Blocks: | ||
| 192 | - FileName: '.\foo.h' | ||
| 193 | Lines: | ||
| 194 | - Offset: 0 | ||
| 195 | LineStart: 2 | ||
| 196 | IsStatement: false | ||
| 197 | EndDelta: 0 | ||
| 198 | - Offset: 4 | ||
| 199 | LineStart: 3 | ||
| 200 | IsStatement: false | ||
| 201 | EndDelta: 0 | ||
| 202 | - Offset: 9 | ||
| 203 | LineStart: 4 | ||
| 204 | IsStatement: false | ||
| 205 | EndDelta: 0 | ||
| 206 | Columns: | ||
| 207 | Relocations: | ||
| 208 | - VirtualAddress: 44 | ||
| 209 | SymbolName: foo | ||
| 210 | Type: IMAGE_REL_AMD64_SECREL | ||
| 211 | - VirtualAddress: 48 | ||
| 212 | SymbolName: foo | ||
| 213 | Type: IMAGE_REL_AMD64_SECTION | ||
| 214 | - VirtualAddress: 68 | ||
| 215 | SymbolName: foo | ||
| 216 | Type: IMAGE_REL_AMD64_SECREL | ||
| 217 | - VirtualAddress: 72 | ||
| 218 | SymbolName: foo | ||
| 219 | Type: IMAGE_REL_AMD64_SECTION | ||
| 220 | - Name: .pdata | ||
| 221 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] | ||
| 222 | Alignment: 4 | ||
| 223 | SectionData: 000000000F00000000000000 | ||
| 224 | Relocations: | ||
| 225 | - VirtualAddress: 0 | ||
| 226 | SymbolName: foo | ||
| 227 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 228 | - VirtualAddress: 4 | ||
| 229 | SymbolName: foo | ||
| 230 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 231 | - VirtualAddress: 8 | ||
| 232 | SymbolName: .xdata | ||
| 233 | Type: IMAGE_REL_AMD64_ADDR32NB | ||
| 234 | symbols: | ||
| 235 | - Name: .text | ||
| 236 | Value: 0 | ||
| 237 | SectionNumber: 1 | ||
| 238 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 239 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 240 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 241 | SectionDefinition: | ||
| 242 | Length: 27 | ||
| 243 | NumberOfRelocations: 1 | ||
| 244 | NumberOfLinenumbers: 0 | ||
| 245 | CheckSum: 3051916600 | ||
| 246 | Number: 1 | ||
| 247 | - Name: .data | ||
| 248 | Value: 0 | ||
| 249 | SectionNumber: 2 | ||
| 250 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 251 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 252 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 253 | SectionDefinition: | ||
| 254 | Length: 0 | ||
| 255 | NumberOfRelocations: 0 | ||
| 256 | NumberOfLinenumbers: 0 | ||
| 257 | CheckSum: 0 | ||
| 258 | Number: 2 | ||
| 259 | - Name: .bss | ||
| 260 | Value: 0 | ||
| 261 | SectionNumber: 3 | ||
| 262 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 263 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 264 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 265 | SectionDefinition: | ||
| 266 | Length: 0 | ||
| 267 | NumberOfRelocations: 0 | ||
| 268 | NumberOfLinenumbers: 0 | ||
| 269 | CheckSum: 0 | ||
| 270 | Number: 3 | ||
| 271 | - Name: .xdata | ||
| 272 | Value: 0 | ||
| 273 | SectionNumber: 4 | ||
| 274 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 275 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 276 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 277 | SectionDefinition: | ||
| 278 | Length: 8 | ||
| 279 | NumberOfRelocations: 0 | ||
| 280 | NumberOfLinenumbers: 0 | ||
| 281 | CheckSum: 264583633 | ||
| 282 | Number: 4 | ||
| 283 | - Name: .text | ||
| 284 | Value: 0 | ||
| 285 | SectionNumber: 5 | ||
| 286 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 287 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 288 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 289 | SectionDefinition: | ||
| 290 | Length: 15 | ||
| 291 | NumberOfRelocations: 1 | ||
| 292 | NumberOfLinenumbers: 0 | ||
| 293 | CheckSum: 236440503 | ||
| 294 | Number: 5 | ||
| 295 | Selection: IMAGE_COMDAT_SELECT_ANY | ||
| 296 | - Name: foo | ||
| 297 | Value: 0 | ||
| 298 | SectionNumber: 5 | ||
| 299 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 300 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 301 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 302 | - Name: .xdata | ||
| 303 | Value: 0 | ||
| 304 | SectionNumber: 10 | ||
| 305 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 306 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 307 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 308 | SectionDefinition: | ||
| 309 | Length: 8 | ||
| 310 | NumberOfRelocations: 0 | ||
| 311 | NumberOfLinenumbers: 0 | ||
| 312 | CheckSum: 264583633 | ||
| 313 | Number: 5 | ||
| 314 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 315 | - Name: .drectve | ||
| 316 | Value: 0 | ||
| 317 | SectionNumber: 6 | ||
| 318 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 319 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 320 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 321 | SectionDefinition: | ||
| 322 | Length: 48 | ||
| 323 | NumberOfRelocations: 0 | ||
| 324 | NumberOfLinenumbers: 0 | ||
| 325 | CheckSum: 149686238 | ||
| 326 | Number: 6 | ||
| 327 | - Name: '.debug$S' | ||
| 328 | Value: 0 | ||
| 329 | SectionNumber: 7 | ||
| 330 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 331 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 332 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 333 | SectionDefinition: | ||
| 334 | Length: 264 | ||
| 335 | NumberOfRelocations: 4 | ||
| 336 | NumberOfLinenumbers: 0 | ||
| 337 | CheckSum: 2204933783 | ||
| 338 | Number: 7 | ||
| 339 | - Name: '.debug$S' | ||
| 340 | Value: 0 | ||
| 341 | SectionNumber: 11 | ||
| 342 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 343 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 344 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 345 | SectionDefinition: | ||
| 346 | Length: 116 | ||
| 347 | NumberOfRelocations: 4 | ||
| 348 | NumberOfLinenumbers: 0 | ||
| 349 | CheckSum: 2691661839 | ||
| 350 | Number: 5 | ||
| 351 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 352 | - Name: '.debug$T' | ||
| 353 | Value: 0 | ||
| 354 | SectionNumber: 8 | ||
| 355 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 356 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 357 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 358 | SectionDefinition: | ||
| 359 | Length: 80 | ||
| 360 | NumberOfRelocations: 0 | ||
| 361 | NumberOfLinenumbers: 0 | ||
| 362 | CheckSum: 3541780432 | ||
| 363 | Number: 8 | ||
| 364 | - Name: .pdata | ||
| 365 | Value: 0 | ||
| 366 | SectionNumber: 9 | ||
| 367 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 368 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 369 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 370 | SectionDefinition: | ||
| 371 | Length: 12 | ||
| 372 | NumberOfRelocations: 3 | ||
| 373 | NumberOfLinenumbers: 0 | ||
| 374 | CheckSum: 567356797 | ||
| 375 | Number: 9 | ||
| 376 | - Name: .pdata | ||
| 377 | Value: 0 | ||
| 378 | SectionNumber: 12 | ||
| 379 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 380 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 381 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 382 | SectionDefinition: | ||
| 383 | Length: 12 | ||
| 384 | NumberOfRelocations: 3 | ||
| 385 | NumberOfLinenumbers: 0 | ||
| 386 | CheckSum: 3642757804 | ||
| 387 | Number: 5 | ||
| 388 | Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE | ||
| 389 | - Name: main | ||
| 390 | Value: 0 | ||
| 391 | SectionNumber: 1 | ||
| 392 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 393 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 394 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 395 | - Name: bar | ||
| 396 | Value: 0 | ||
| 397 | SectionNumber: 0 | ||
| 398 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 399 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 400 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 401 | ... | ||
deps/lld/test/COFF/Inputs/pdb_lines_2_relative.yaml created+190| ... | @@ -0,0 +1,190 @@ | ||
| 1 | --- !COFF | ||
| 2 | header: | ||
| 3 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 4 | Characteristics: [ ] | ||
| 5 | sections: | ||
| 6 | - Name: .text | ||
| 7 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 8 | Alignment: 16 | ||
| 9 | SectionData: C3 | ||
| 10 | - Name: .data | ||
| 11 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 12 | Alignment: 4 | ||
| 13 | SectionData: '' | ||
| 14 | - Name: .bss | ||
| 15 | Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 16 | Alignment: 4 | ||
| 17 | SectionData: '' | ||
| 18 | - Name: .drectve | ||
| 19 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | ||
| 20 | Alignment: 1 | ||
| 21 | SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 | ||
| 22 | - Name: '.debug$S' | ||
| 23 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 24 | Alignment: 4 | ||
| 25 | SectionData: 04000000F10000002F0000002D003C1100000000D0000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F10000002F0000002900471100000000000000000000000001000000000000000000000002100000000000000000006261720002004F1100F2000000200000000000000000000000010000000000000001000000140000000000000002000000F400000018000000010000001001DF91CB3A2B8D917486574BB50CAC4CC70000F300000014000000002E5C7064625F6C696E65735F322E6300000000 | ||
| 26 | Subsections: | ||
| 27 | - !Symbols | ||
| 28 | Records: | ||
| 29 | - Kind: S_COMPILE3 | ||
| 30 | Compile3Sym: | ||
| 31 | Flags: [ ] | ||
| 32 | Machine: X64 | ||
| 33 | FrontendMajor: 7 | ||
| 34 | FrontendMinor: 0 | ||
| 35 | FrontendBuild: 0 | ||
| 36 | FrontendQFE: 0 | ||
| 37 | BackendMajor: 7000 | ||
| 38 | BackendMinor: 0 | ||
| 39 | BackendBuild: 0 | ||
| 40 | BackendQFE: 0 | ||
| 41 | Version: 'clang version 7.0.0 ' | ||
| 42 | - !Symbols | ||
| 43 | Records: | ||
| 44 | - Kind: S_GPROC32_ID | ||
| 45 | ProcSym: | ||
| 46 | CodeSize: 1 | ||
| 47 | DbgStart: 0 | ||
| 48 | DbgEnd: 0 | ||
| 49 | FunctionType: 4098 | ||
| 50 | Flags: [ ] | ||
| 51 | DisplayName: bar | ||
| 52 | - Kind: S_PROC_ID_END | ||
| 53 | ScopeEndSym: | ||
| 54 | - !Lines | ||
| 55 | CodeSize: 1 | ||
| 56 | Flags: [ ] | ||
| 57 | RelocOffset: 0 | ||
| 58 | RelocSegment: 0 | ||
| 59 | Blocks: | ||
| 60 | - FileName: '.\pdb_lines_2.c' | ||
| 61 | Lines: | ||
| 62 | - Offset: 0 | ||
| 63 | LineStart: 2 | ||
| 64 | IsStatement: false | ||
| 65 | EndDelta: 0 | ||
| 66 | Columns: | ||
| 67 | - !FileChecksums | ||
| 68 | Checksums: | ||
| 69 | - FileName: '.\pdb_lines_2.c' | ||
| 70 | Kind: MD5 | ||
| 71 | Checksum: DF91CB3A2B8D917486574BB50CAC4CC7 | ||
| 72 | - !StringTable | ||
| 73 | Strings: | ||
| 74 | - '.\pdb_lines_2.c' | ||
| 75 | - '' | ||
| 76 | - '' | ||
| 77 | - '' | ||
| 78 | Relocations: | ||
| 79 | - VirtualAddress: 100 | ||
| 80 | SymbolName: bar | ||
| 81 | Type: IMAGE_REL_AMD64_SECREL | ||
| 82 | - VirtualAddress: 104 | ||
| 83 | SymbolName: bar | ||
| 84 | Type: IMAGE_REL_AMD64_SECTION | ||
| 85 | - VirtualAddress: 124 | ||
| 86 | SymbolName: bar | ||
| 87 | Type: IMAGE_REL_AMD64_SECREL | ||
| 88 | - VirtualAddress: 128 | ||
| 89 | SymbolName: bar | ||
| 90 | Type: IMAGE_REL_AMD64_SECTION | ||
| 91 | - Name: '.debug$T' | ||
| 92 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] | ||
| 93 | Alignment: 4 | ||
| 94 | SectionData: 0400000006000112000000000E0008100300000000000000001000000E000116000000000110000062617200 | ||
| 95 | Types: | ||
| 96 | - Kind: LF_ARGLIST | ||
| 97 | ArgList: | ||
| 98 | ArgIndices: [ ] | ||
| 99 | - Kind: LF_PROCEDURE | ||
| 100 | Procedure: | ||
| 101 | ReturnType: 3 | ||
| 102 | CallConv: NearC | ||
| 103 | Options: [ None ] | ||
| 104 | ParameterCount: 0 | ||
| 105 | ArgumentList: 4096 | ||
| 106 | - Kind: LF_FUNC_ID | ||
| 107 | FuncId: | ||
| 108 | ParentScope: 0 | ||
| 109 | FunctionType: 4097 | ||
| 110 | Name: bar | ||
| 111 | symbols: | ||
| 112 | - Name: .text | ||
| 113 | Value: 0 | ||
| 114 | SectionNumber: 1 | ||
| 115 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 116 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 117 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 118 | SectionDefinition: | ||
| 119 | Length: 1 | ||
| 120 | NumberOfRelocations: 0 | ||
| 121 | NumberOfLinenumbers: 0 | ||
| 122 | CheckSum: 40735498 | ||
| 123 | Number: 1 | ||
| 124 | - Name: .data | ||
| 125 | Value: 0 | ||
| 126 | SectionNumber: 2 | ||
| 127 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 128 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 129 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 130 | SectionDefinition: | ||
| 131 | Length: 0 | ||
| 132 | NumberOfRelocations: 0 | ||
| 133 | NumberOfLinenumbers: 0 | ||
| 134 | CheckSum: 0 | ||
| 135 | Number: 2 | ||
| 136 | - Name: .bss | ||
| 137 | Value: 0 | ||
| 138 | SectionNumber: 3 | ||
| 139 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 140 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 141 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 142 | SectionDefinition: | ||
| 143 | Length: 0 | ||
| 144 | NumberOfRelocations: 0 | ||
| 145 | NumberOfLinenumbers: 0 | ||
| 146 | CheckSum: 0 | ||
| 147 | Number: 3 | ||
| 148 | - Name: .drectve | ||
| 149 | Value: 0 | ||
| 150 | SectionNumber: 4 | ||
| 151 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 152 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 153 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 154 | SectionDefinition: | ||
| 155 | Length: 48 | ||
| 156 | NumberOfRelocations: 0 | ||
| 157 | NumberOfLinenumbers: 0 | ||
| 158 | CheckSum: 149686238 | ||
| 159 | Number: 4 | ||
| 160 | - Name: '.debug$S' | ||
| 161 | Value: 0 | ||
| 162 | SectionNumber: 5 | ||
| 163 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 164 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 165 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 166 | SectionDefinition: | ||
| 167 | Length: 216 | ||
| 168 | NumberOfRelocations: 4 | ||
| 169 | NumberOfLinenumbers: 0 | ||
| 170 | CheckSum: 2383431754 | ||
| 171 | Number: 5 | ||
| 172 | - Name: '.debug$T' | ||
| 173 | Value: 0 | ||
| 174 | SectionNumber: 6 | ||
| 175 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 176 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 177 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 178 | SectionDefinition: | ||
| 179 | Length: 44 | ||
| 180 | NumberOfRelocations: 0 | ||
| 181 | NumberOfLinenumbers: 0 | ||
| 182 | CheckSum: 179171995 | ||
| 183 | Number: 6 | ||
| 184 | - Name: bar | ||
| 185 | Value: 0 | ||
| 186 | SectionNumber: 1 | ||
| 187 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 188 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 189 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 190 | ... | ||
deps/lld/test/COFF/arm64-branch-range.test created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | // REQUIRES: aarch64 | ||
| 2 | |||
| 3 | // RUN: echo -e '.globl _start\n _start:\n bl too_far26\n' > %t.main26.s | ||
| 4 | // RUN: echo -e '.globl _start\n _start:\n b.ne too_far19\n' > %t.main19.s | ||
| 5 | // RUN: echo -e '.globl _start\n _start:\n tbz x0, #0, too_far14\n' > %t.main14.s | ||
| 6 | |||
| 7 | // RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main26.s -o %t.main26.obj | ||
| 8 | // RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main19.s -o %t.main19.obj | ||
| 9 | // RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main14.s -o %t.main14.obj | ||
| 10 | // RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/far-arm64-abs.s -o %t.far.obj | ||
| 11 | |||
| 12 | // RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main26.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s | ||
| 13 | // RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main19.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s | ||
| 14 | // RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main14.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s | ||
| 15 | |||
| 16 | // CHECK: relocation out of range | ||
deps/lld/test/COFF/arm64-relocs-imports.test+77-36| ... | @@ -38,43 +38,57 @@ | ... | @@ -38,43 +38,57 @@ |
| 38 | # BEFORE: 74: 00 00 00 00 <unknown> | 38 | # BEFORE: 74: 00 00 00 00 <unknown> |
| 39 | # BEFORE: 78: 01 00 00 00 <unknown> | 39 | # BEFORE: 78: 01 00 00 00 <unknown> |
| 40 | # BEFORE: 7c: 01 00 00 00 <unknown> | 40 | # BEFORE: 7c: 01 00 00 00 <unknown> |
| 41 | # BEFORE: 80: 00 00 00 91 add x0, x0, #0 | ||
| 42 | # BEFORE: 84: 00 00 40 91 add x0, x0, #0, lsl #12 | ||
| 43 | # BEFORE: 88: 00 00 40 f9 ldr x0, [x0] | ||
| 44 | # BEFORE: 8c: 01 00 00 00 <unknown> | ||
| 45 | # BEFORE: 90: 20 1a 09 30 adr x0, #74565 | ||
| 46 | # BEFORE: 94: 01 00 00 54 b.ne #0 | ||
| 47 | # BEFORE: 98: 00 00 00 36 tbz w0, #0, #0 | ||
| 41 | 48 | ||
| 42 | # AFTER: Disassembly of section .text: | 49 | # AFTER: Disassembly of section .text: |
| 43 | # AFTER: 140002000: fe 0f 1f f8 str x30, [sp, #-16]! | 50 | # AFTER: 140001000: fe 0f 1f f8 str x30, [sp, #-16]! |
| 44 | # AFTER: 140002004: e0 ff ff f0 adrp x0, #-4096 | 51 | # AFTER: 140001004: 00 00 00 b0 adrp x0, #4096 |
| 45 | # AFTER: 140002008: 00 18 00 91 add x0, x0, #6 | 52 | # AFTER: 140001008: 00 18 00 91 add x0, x0, #6 |
| 46 | # AFTER: 14000200c: 1d 00 00 94 bl #116 | 53 | # AFTER: 14000100c: 24 00 00 94 bl #144 |
| 47 | # AFTER: 140002010: 00 21 40 39 ldrb w0, [x8, #8] | 54 | # AFTER: 140001010: 00 21 40 39 ldrb w0, [x8, #8] |
| 48 | # AFTER: 140002014: 00 11 40 79 ldrh w0, [x8, #8] | 55 | # AFTER: 140001014: 00 11 40 79 ldrh w0, [x8, #8] |
| 49 | # AFTER: 140002018: 00 09 40 b9 ldr w0, [x8, #8] | 56 | # AFTER: 140001018: 00 09 40 b9 ldr w0, [x8, #8] |
| 50 | # AFTER: 14000201c: 00 05 40 f9 ldr x0, [x8, #8] | 57 | # AFTER: 14000101c: 00 05 40 f9 ldr x0, [x8, #8] |
| 51 | # AFTER: 140002020: 00 21 00 39 strb w0, [x8, #8] | 58 | # AFTER: 140001020: 00 21 00 39 strb w0, [x8, #8] |
| 52 | # AFTER: 140002024: 00 11 00 79 strh w0, [x8, #8] | 59 | # AFTER: 140001024: 00 11 00 79 strh w0, [x8, #8] |
| 53 | # AFTER: 140002028: 00 09 00 b9 str w0, [x8, #8] | 60 | # AFTER: 140001028: 00 09 00 b9 str w0, [x8, #8] |
| 54 | # AFTER: 14000202c: 00 05 00 f9 str x0, [x8, #8] | 61 | # AFTER: 14000102c: 00 05 00 f9 str x0, [x8, #8] |
| 55 | # AFTER: 140002030: 00 41 40 3d ldr b0, [x8, #16] | 62 | # AFTER: 140001030: 00 41 40 3d ldr b0, [x8, #16] |
| 56 | # AFTER: 140002034: 00 21 40 7d ldr h0, [x8, #16] | 63 | # AFTER: 140001034: 00 21 40 7d ldr h0, [x8, #16] |
| 57 | # AFTER: 140002038: 00 11 40 bd ldr s0, [x8, #16] | 64 | # AFTER: 140001038: 00 11 40 bd ldr s0, [x8, #16] |
| 58 | # AFTER: 14000203c: 00 09 40 fd ldr d0, [x8, #16] | 65 | # AFTER: 14000103c: 00 09 40 fd ldr d0, [x8, #16] |
| 59 | # AFTER: 140002040: 00 05 c0 3d ldr q0, [x8, #16] | 66 | # AFTER: 140001040: 00 05 c0 3d ldr q0, [x8, #16] |
| 60 | # AFTER: 140002044: 00 41 00 3d str b0, [x8, #16] | 67 | # AFTER: 140001044: 00 41 00 3d str b0, [x8, #16] |
| 61 | # AFTER: 140002048: 00 21 00 7d str h0, [x8, #16] | 68 | # AFTER: 140001048: 00 21 00 7d str h0, [x8, #16] |
| 62 | # AFTER: 14000204c: 00 11 00 bd str s0, [x8, #16] | 69 | # AFTER: 14000104c: 00 11 00 bd str s0, [x8, #16] |
| 63 | # AFTER: 140002050: 00 09 00 fd str d0, [x8, #16] | 70 | # AFTER: 140001050: 00 09 00 fd str d0, [x8, #16] |
| 64 | # AFTER: 140002054: 00 05 80 3d str q0, [x8, #16] | 71 | # AFTER: 140001054: 00 05 80 3d str q0, [x8, #16] |
| 65 | # AFTER: 140002058: 00 09 40 f9 ldr x0, [x8, #16] | 72 | # AFTER: 140001058: 00 09 40 f9 ldr x0, [x8, #16] |
| 66 | # AFTER: 14000205c: 00 00 00 b0 adrp x0, #4096 | 73 | # AFTER: 14000105c: 00 00 00 f0 adrp x0, #12288 |
| 67 | # AFTER: 140002060: 00 fc 47 f9 ldr x0, [x0, #4088] | 74 | # AFTER: 140001060: 00 fc 47 f9 ldr x0, [x0, #4088] |
| 68 | # AFTER: 140002064: e0 03 1f 2a mov w0, wzr | 75 | # AFTER: 140001064: e0 03 1f 2a mov w0, wzr |
| 69 | # AFTER: 140002068: fe 07 41 f8 ldr x30, [sp], #16 | 76 | # AFTER: 140001068: fe 07 41 f8 ldr x30, [sp], #16 |
| 70 | # AFTER: 14000206c: c0 03 5f d6 ret | 77 | # AFTER: 14000106c: c0 03 5f d6 ret |
| 71 | # AFTER: 140002070: 10 10 00 40 <unknown> | 78 | # AFTER: 140001070: 10 20 00 40 <unknown> |
| 72 | # AFTER: 140002074: 01 00 00 00 <unknown> | 79 | # AFTER: 140001074: 01 00 00 00 <unknown> |
| 73 | # AFTER: 140002078: 09 10 00 00 <unknown> | 80 | # AFTER: 140001078: 09 20 00 00 <unknown> |
| 74 | # AFTER: 14000207c: 09 00 00 00 <unknown> | 81 | # AFTER: 14000107c: 09 00 00 00 <unknown> |
| 75 | # AFTER: 140002080: 10 00 00 b0 adrp x16, #4096 | 82 | # AFTER: 140001080: 00 20 0e 91 add x0, x0, #904 |
| 76 | # AFTER: 140002084: 10 1e 40 f9 ldr x16, [x16, #56] | 83 | # AFTER: 140001084: 00 04 40 91 add x0, x0, #1, lsl #12 |
| 77 | # AFTER: 140002088: 00 02 1f d6 br x16 | 84 | # AFTER: 140001088: 00 c4 41 f9 ldr x0, [x0, #904] |
| 85 | # AFTER: 14000108c: 03 00 00 00 <unknown> | ||
| 86 | # 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 | ||
| 78 | 92 | ||
| 79 | --- !COFF | 93 | --- !COFF |
| 80 | header: | 94 | header: |
| ... | @@ -84,7 +98,7 @@ sections: | ... | @@ -84,7 +98,7 @@ sections: |
| 84 | - Name: .text | 98 | - Name: .text |
| 85 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | 99 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 86 | Alignment: 4 | 100 | Alignment: 4 |
| 87 | SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD608000000000000000100000001000000 | 101 | SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a09300100005400000036 |
| 88 | Relocations: | 102 | Relocations: |
| 89 | - VirtualAddress: 4 | 103 | - VirtualAddress: 4 |
| 90 | SymbolName: .Lstr | 104 | SymbolName: .Lstr |
| ... | @@ -167,6 +181,27 @@ sections: | ... | @@ -167,6 +181,27 @@ sections: |
| 167 | - VirtualAddress: 124 | 181 | - VirtualAddress: 124 |
| 168 | SymbolName: .Lglobal | 182 | SymbolName: .Lglobal |
| 169 | Type: IMAGE_REL_ARM64_SECREL | 183 | Type: IMAGE_REL_ARM64_SECREL |
| 184 | - VirtualAddress: 128 | ||
| 185 | SymbolName: .Lglobal5000 | ||
| 186 | Type: IMAGE_REL_ARM64_SECREL_LOW12A | ||
| 187 | - VirtualAddress: 132 | ||
| 188 | SymbolName: .Lglobal5000 | ||
| 189 | Type: IMAGE_REL_ARM64_SECREL_HIGH12A | ||
| 190 | - VirtualAddress: 136 | ||
| 191 | SymbolName: .Lglobal5000 | ||
| 192 | Type: IMAGE_REL_ARM64_SECREL_LOW12L | ||
| 193 | - VirtualAddress: 140 | ||
| 194 | SymbolName: .Lglobal | ||
| 195 | Type: IMAGE_REL_ARM64_SECTION | ||
| 196 | - VirtualAddress: 144 | ||
| 197 | SymbolName: .Lglobal | ||
| 198 | Type: IMAGE_REL_ARM64_REL21 | ||
| 199 | - VirtualAddress: 148 | ||
| 200 | SymbolName: function | ||
| 201 | Type: IMAGE_REL_ARM64_BRANCH19 | ||
| 202 | - VirtualAddress: 152 | ||
| 203 | SymbolName: function | ||
| 204 | Type: IMAGE_REL_ARM64_BRANCH14 | ||
| 170 | - Name: .data | 205 | - Name: .data |
| 171 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | 206 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] |
| 172 | Alignment: 4 | 207 | Alignment: 4 |
| ... | @@ -240,4 +275,10 @@ symbols: | ... | @@ -240,4 +275,10 @@ symbols: |
| 240 | SimpleType: IMAGE_SYM_TYPE_NULL | 275 | SimpleType: IMAGE_SYM_TYPE_NULL |
| 241 | ComplexType: IMAGE_SYM_DTYPE_NULL | 276 | ComplexType: IMAGE_SYM_DTYPE_NULL |
| 242 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | 277 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL |
| 278 | - Name: .Lglobal5000 | ||
| 279 | Value: 5000 | ||
| 280 | SectionNumber: 4 | ||
| 281 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 282 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 283 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 243 | ... | 284 | ... |
deps/lld/test/COFF/armnt-movt32t.test+1-1| ... | @@ -11,7 +11,7 @@ | ... | @@ -11,7 +11,7 @@ |
| 11 | # BEFORE: 8: 70 47 bx lr | 11 | # BEFORE: 8: 70 47 bx lr |
| 12 | 12 | ||
| 13 | # AFTER: Disassembly of section .text: | 13 | # AFTER: Disassembly of section .text: |
| 14 | # AFTER: 0: 41 f2 00 00 movw r0, #4096 | 14 | # AFTER: 0: 42 f2 00 00 movw r0, #8192 |
| 15 | # AFTER: 4: c0 f2 40 00 movt r0, #64 | 15 | # AFTER: 4: c0 f2 40 00 movt r0, #64 |
| 16 | # AFTER: 8: 70 47 bx lr | 16 | # AFTER: 8: 70 47 bx lr |
| 17 | 17 |
deps/lld/test/COFF/associative-comdat.s+6-4| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t1.obj | 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t1.obj |
| 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc %S/Inputs/associative-comdat-2.s -filetype=obj -o %t2.obj | 3 | # RUN: llvm-mc -triple=x86_64-windows-msvc %S/Inputs/associative-comdat-2.s -filetype=obj -o %t2.obj |
| 3 | 4 | ||
| ... | @@ -9,14 +10,15 @@ | ... | @@ -9,14 +10,15 @@ |
| 9 | 10 | ||
| 10 | # CHECK: Sections [ | 11 | # CHECK: Sections [ |
| 11 | # CHECK: Section { | 12 | # CHECK: Section { |
| 12 | # CHECK: Number: 1 | 13 | # CHECK: Number: 2 |
| 13 | # CHECK-LABEL: Name: .data (2E 64 61 74 61 00 00 00) | ||
| 14 | # CHECK-NEXT: VirtualSize: 0x4 | ||
| 15 | # CHECK: Section { | ||
| 16 | # CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00) | 14 | # CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00) |
| 17 | # This is the critical check to show that only *one* definition of | 15 | # This is the critical check to show that only *one* definition of |
| 18 | # foo_assoc was retained. This *must* be 8, not 16. | 16 | # foo_assoc was retained. This *must* be 8, not 16. |
| 19 | # CHECK-NEXT: VirtualSize: 0x8 | 17 | # CHECK-NEXT: VirtualSize: 0x8 |
| 18 | # CHECK: Section { | ||
| 19 | # CHECK: Number: 3 | ||
| 20 | # CHECK-LABEL: Name: .data (2E 64 61 74 61 00 00 00) | ||
| 21 | # CHECK-NEXT: VirtualSize: 0x4 | ||
| 20 | 22 | ||
| 21 | .text | 23 | .text |
| 22 | .def main; | 24 | .def main; |
deps/lld/test/COFF/baserel.test+8-8| ... | @@ -9,35 +9,35 @@ | ... | @@ -9,35 +9,35 @@ |
| 9 | # BASEREL: BaseReloc [ | 9 | # BASEREL: BaseReloc [ |
| 10 | # BASEREL-NEXT: Entry { | 10 | # BASEREL-NEXT: Entry { |
| 11 | # BASEREL-NEXT: Type: DIR64 | 11 | # BASEREL-NEXT: Type: DIR64 |
| 12 | # BASEREL-NEXT: Address: 0x2007 | 12 | # BASEREL-NEXT: Address: 0x1007 |
| 13 | # BASEREL-NEXT: } | 13 | # BASEREL-NEXT: } |
| 14 | # BASEREL-NEXT: Entry { | 14 | # BASEREL-NEXT: Entry { |
| 15 | # BASEREL-NEXT: Type: DIR64 | 15 | # BASEREL-NEXT: Type: DIR64 |
| 16 | # BASEREL-NEXT: Address: 0x200C | 16 | # BASEREL-NEXT: Address: 0x100C |
| 17 | # BASEREL-NEXT: } | 17 | # BASEREL-NEXT: } |
| 18 | # BASEREL-NEXT: Entry { | 18 | # BASEREL-NEXT: Entry { |
| 19 | # BASEREL-NEXT: Type: DIR64 | 19 | # BASEREL-NEXT: Type: DIR64 |
| 20 | # BASEREL-NEXT: Address: 0x201E | 20 | # BASEREL-NEXT: Address: 0x101E |
| 21 | # BASEREL-NEXT: } | 21 | # BASEREL-NEXT: } |
| 22 | # BASEREL-NEXT: Entry { | 22 | # BASEREL-NEXT: Entry { |
| 23 | # BASEREL-NEXT: Type: ABSOLUTE | 23 | # BASEREL-NEXT: Type: ABSOLUTE |
| 24 | # BASEREL-NEXT: Address: 0x2000 | 24 | # BASEREL-NEXT: Address: 0x1000 |
| 25 | # BASEREL-NEXT: } | 25 | # BASEREL-NEXT: } |
| 26 | # BASEREL-NEXT: Entry { | 26 | # BASEREL-NEXT: Entry { |
| 27 | # BASEREL-NEXT: Type: DIR64 | 27 | # BASEREL-NEXT: Type: DIR64 |
| 28 | # BASEREL-NEXT: Address: 0x3007 | 28 | # BASEREL-NEXT: Address: 0x4007 |
| 29 | # BASEREL-NEXT: } | 29 | # BASEREL-NEXT: } |
| 30 | # BASEREL-NEXT: Entry { | 30 | # BASEREL-NEXT: Entry { |
| 31 | # BASEREL-NEXT: Type: DIR64 | 31 | # BASEREL-NEXT: Type: DIR64 |
| 32 | # BASEREL-NEXT: Address: 0x300C | 32 | # BASEREL-NEXT: Address: 0x400C |
| 33 | # BASEREL-NEXT: } | 33 | # BASEREL-NEXT: } |
| 34 | # BASEREL-NEXT: Entry { | 34 | # BASEREL-NEXT: Entry { |
| 35 | # BASEREL-NEXT: Type: DIR64 | 35 | # BASEREL-NEXT: Type: DIR64 |
| 36 | # BASEREL-NEXT: Address: 0x301E | 36 | # BASEREL-NEXT: Address: 0x401E |
| 37 | # BASEREL-NEXT: } | 37 | # BASEREL-NEXT: } |
| 38 | # BASEREL-NEXT: Entry { | 38 | # BASEREL-NEXT: Entry { |
| 39 | # BASEREL-NEXT: Type: ABSOLUTE | 39 | # BASEREL-NEXT: Type: ABSOLUTE |
| 40 | # BASEREL-NEXT: Address: 0x3000 | 40 | # BASEREL-NEXT: Address: 0x4000 |
| 41 | # BASEREL-NEXT: } | 41 | # BASEREL-NEXT: } |
| 42 | # | 42 | # |
| 43 | # NOBASEREL: BaseReloc [ | 43 | # NOBASEREL: BaseReloc [ |
deps/lld/test/COFF/combined-resources.test+109-109| ... | @@ -11,8 +11,8 @@ | ... | @@ -11,8 +11,8 @@ |
| 11 | # RUN: llvm-readobj -coff-resources -file-headers -section-data %t.exe | \ | 11 | # RUN: llvm-readobj -coff-resources -file-headers -section-data %t.exe | \ |
| 12 | # RUN: FileCheck %s | 12 | # RUN: FileCheck %s |
| 13 | 13 | ||
| 14 | CHECK: ResourceTableRVA: 0x1000 | 14 | CHECK: ResourceTableRVA: 0x2000 |
| 15 | CHECK-NEXT: ResourceTableSize: 0xC1C | 15 | CHECK-NEXT: ResourceTableSize: 0xC20 |
| 16 | CHECK-DAG: Resources [ | 16 | CHECK-DAG: Resources [ |
| 17 | CHECK-NEXT: Total Number of Resources: 13 | 17 | CHECK-NEXT: Total Number of Resources: 13 |
| 18 | CHECK-DAG: .rsrc Data ( | 18 | CHECK-DAG: .rsrc Data ( |
| ... | @@ -49,19 +49,19 @@ CHECK-NEXT: 01D0: 00000000 00000000 00000000 00000100 |................| | ... | @@ -49,19 +49,19 @@ CHECK-NEXT: 01D0: 00000000 00000000 00000000 00000100 |................| |
| 49 | CHECK-NEXT: 01E0: 09040000 A0020000 00000000 00000000 |................| | 49 | CHECK-NEXT: 01E0: 09040000 A0020000 00000000 00000000 |................| |
| 50 | CHECK-NEXT: 01F0: 00000000 00000300 09040000 B0020000 |................| | 50 | CHECK-NEXT: 01F0: 00000000 00000300 09040000 B0020000 |................| |
| 51 | CHECK-NEXT: 0200: 04080000 C0020000 07100000 D0020000 |................| | 51 | CHECK-NEXT: 0200: 04080000 C0020000 07100000 D0020000 |................| |
| 52 | CHECK-NEXT: 0210: FC1A0000 39000000 00000000 00000000 |....9...........| | 52 | CHECK-NEXT: 0210: 002B0000 39000000 00000000 00000000 |.+..9...........| |
| 53 | CHECK-NEXT: 0220: C4130000 28030000 00000000 00000000 |....(...........| | 53 | CHECK-NEXT: 0220: C8230000 28030000 00000000 00000000 |.#..(...........| |
| 54 | CHECK-NEXT: 0230: EC160000 28030000 00000000 00000000 |....(...........| | 54 | CHECK-NEXT: 0230: F0260000 28030000 00000000 00000000 |.&..(...........| |
| 55 | CHECK-NEXT: 0240: CC1A0000 30000000 00000000 00000000 |....0...........| | 55 | CHECK-NEXT: 0240: D02A0000 30000000 00000000 00000000 |.*..0...........| |
| 56 | CHECK-NEXT: 0250: 141A0000 2E000000 00000000 00000000 |................| | 56 | CHECK-NEXT: 0250: 182A0000 2E000000 00000000 00000000 |.*..............| |
| 57 | CHECK-NEXT: 0260: 441A0000 6C000000 00000000 00000000 |D...l...........| | 57 | CHECK-NEXT: 0260: 482A0000 6C000000 00000000 00000000 |H*..l...........| |
| 58 | CHECK-NEXT: 0270: 7C130000 2A000000 00000000 00000000 ||...*...........| | 58 | CHECK-NEXT: 0270: 80230000 2A000000 00000000 00000000 |.#..*...........| |
| 59 | CHECK-NEXT: 0280: AC130000 18000000 00000000 00000000 |................| | 59 | CHECK-NEXT: 0280: B0230000 18000000 00000000 00000000 |.#..............| |
| 60 | CHECK-NEXT: 0290: 041C0000 18000000 00000000 00000000 |................| | 60 | CHECK-NEXT: 0290: 082C0000 18000000 00000000 00000000 |.,..............| |
| 61 | CHECK-NEXT: 02A0: B41A0000 18000000 00000000 00000000 |................| | 61 | CHECK-NEXT: 02A0: B82A0000 18000000 00000000 00000000 |.*..............| |
| 62 | CHECK-NEXT: 02B0: 3C1B0000 36000000 00000000 00000000 |<...6...........| | 62 | CHECK-NEXT: 02B0: 402B0000 36000000 00000000 00000000 |@+..6...........| |
| 63 | CHECK-NEXT: 02C0: 741B0000 43000000 00000000 00000000 |t...C...........| | 63 | CHECK-NEXT: 02C0: 782B0000 43000000 00000000 00000000 |x+..C...........| |
| 64 | CHECK-NEXT: 02D0: BC1B0000 42000000 00000000 00000000 |....B...........| | 64 | CHECK-NEXT: 02D0: C02B0000 42000000 00000000 00000000 |.+..B...........| |
| 65 | CHECK-NEXT: 02E0: 0E004D00 59004100 43004300 45004C00 |..M.Y.A.C.C.E.L.| | 65 | CHECK-NEXT: 02E0: 0E004D00 59004100 43004300 45004C00 |..M.Y.A.C.C.E.L.| |
| 66 | CHECK-NEXT: 02F0: 45005200 41005400 4F005200 53000600 |E.R.A.T.O.R.S...| | 66 | CHECK-NEXT: 02F0: 45005200 41005400 4F005200 53000600 |E.R.A.T.O.R.S...| |
| 67 | CHECK-NEXT: 0300: 43005500 52005300 4F005200 04004F00 |C.U.R.S.O.R...O.| | 67 | CHECK-NEXT: 0300: 43005500 52005300 4F005200 04004F00 |C.U.R.S.O.R...O.| |
| ... | @@ -71,14 +71,14 @@ CHECK-NEXT: 0330: 45004100 54002200 0B005300 54005200 |E.A.T."...S.T.R.| | ... | @@ -71,14 +71,14 @@ CHECK-NEXT: 0330: 45004100 54002200 0B005300 54005200 |E.A.T."...S.T.R.| |
| 71 | CHECK-NEXT: 0340: 49004E00 47004100 52005200 41005900 |I.N.G.A.R.R.A.Y.| | 71 | CHECK-NEXT: 0340: 49004E00 47004100 52005200 41005900 |I.N.G.A.R.R.A.Y.| |
| 72 | CHECK-NEXT: 0350: 0A004D00 59005200 45005300 4F005500 |..M.Y.R.E.S.O.U.| | 72 | CHECK-NEXT: 0350: 0A004D00 59005200 45005300 4F005500 |..M.Y.R.E.S.O.U.| |
| 73 | CHECK-NEXT: 0360: 52004300 45000900 52004100 4E004400 |R.C.E...R.A.N.D.| | 73 | CHECK-NEXT: 0360: 52004300 45000900 52004100 4E004400 |R.C.E...R.A.N.D.| |
| 74 | CHECK-NEXT: 0370: 4F004D00 44004100 54000000 00000500 |O.M.D.A.T.......| | 74 | CHECK-NEXT: 0370: 4F004D00 44004100 54000000 00000000 |O.M.D.A.T.......| |
| 75 | CHECK-NEXT: 0380: 48006500 6C006C00 6F000000 00000000 |H.e.l.l.o.......| | 75 | CHECK-NEXT: 0380: 00000500 48006500 6C006C00 6F000000 |....H.e.l.l.o...| |
| 76 | CHECK-NEXT: 0390: 00000000 00000000 00000000 00000000 |................| | 76 | CHECK-NEXT: 0390: 00000000 00000000 00000000 00000000 |................| |
| 77 | CHECK-NEXT: 03A0: 00000000 00000000 00000000 11000300 |................| | 77 | CHECK-NEXT: 03A0: 00000000 00000000 00000000 00000000 |................| |
| 78 | CHECK-NEXT: 03B0: E7030000 0D004400 4C040000 82001200 |......D.L.......| | 78 | CHECK-NEXT: 03B0: 11000300 E7030000 0D004400 4C040000 |..........D.L...| |
| 79 | CHECK-NEXT: 03C0: BC010000 28000000 10000000 10000000 |....(...........| | 79 | CHECK-NEXT: 03C0: 82001200 BC010000 28000000 10000000 |........(.......| |
| 80 | CHECK-NEXT: 03D0: 01001800 00000000 00030000 C40E0000 |................| | 80 | CHECK-NEXT: 03D0: 10000000 01001800 00000000 00030000 |................| |
| 81 | CHECK-NEXT: 03E0: C40E0000 00000000 00000000 FFFFFFFF |................| | 81 | CHECK-NEXT: 03E0: C40E0000 C40E0000 00000000 00000000 |................| |
| 82 | CHECK-NEXT: 03F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 82 | CHECK-NEXT: 03F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 83 | CHECK-NEXT: 0400: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 83 | CHECK-NEXT: 0400: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 84 | CHECK-NEXT: 0410: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 84 | CHECK-NEXT: 0410: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| ... | @@ -86,50 +86,50 @@ CHECK-NEXT: 0420: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | ... | @@ -86,50 +86,50 @@ CHECK-NEXT: 0420: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 86 | CHECK-NEXT: 0430: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 86 | CHECK-NEXT: 0430: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 87 | CHECK-NEXT: 0440: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 87 | CHECK-NEXT: 0440: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 88 | CHECK-NEXT: 0450: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 88 | CHECK-NEXT: 0450: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 89 | CHECK-NEXT: 0460: FF7F7F7F 7C7C7C78 78787575 75FFFFFF |....|||xxxuuu...| | 89 | CHECK-NEXT: 0460: FFFFFFFF FF7F7F7F 7C7C7C78 78787575 |........|||xxxuu| |
| 90 | CHECK-NEXT: 0470: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 90 | CHECK-NEXT: 0470: 75FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |u...............| |
| 91 | CHECK-NEXT: 0480: FFFFFFFF FFFFFFFF 979797FF FFFFFFFF |................| | 91 | CHECK-NEXT: 0480: FFFFFFFF FFFFFFFF FFFFFFFF 979797FF |................| |
| 92 | CHECK-NEXT: 0490: FF838383 AAAAAADB DBDB7979 79757575 |..........yyyuuu| | 92 | CHECK-NEXT: 0490: FFFFFFFF FF838383 AAAAAADB DBDB7979 |..............yy| |
| 93 | CHECK-NEXT: 04A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 93 | CHECK-NEXT: 04A0: 79757575 FFFFFFFF FFFFFFFF FFFFFFFF |yuuu............| |
| 94 | CHECK-NEXT: 04B0: FFFFFFFF FFFFFFFF 9C9C9C98 9898FFFF |................| | 94 | CHECK-NEXT: 04B0: FFFFFFFF FFFFFFFF FFFFFFFF 9C9C9C98 |................| |
| 95 | CHECK-NEXT: 04C0: FF888888 DBDBDBB7 B7B77D7D 7DFFFFFF |..........}}}...| | 95 | CHECK-NEXT: 04C0: 9898FFFF FF888888 DBDBDBB7 B7B77D7D |..............}}| |
| 96 | CHECK-NEXT: 04D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 96 | CHECK-NEXT: 04D0: 7DFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |}...............| |
| 97 | CHECK-NEXT: 04E0: FFFFFFFF FFFFFFFF A0A0A09C 9C9C9393 |................| | 97 | CHECK-NEXT: 04E0: FFFFFFFF FFFFFFFF FFFFFFFF A0A0A09C |................| |
| 98 | CHECK-NEXT: 04F0: 93ADADAD F2F2F284 84848181 81FFFFFF |................| | 98 | CHECK-NEXT: 04F0: 9C9C9393 93ADADAD F2F2F284 84848181 |................| |
| 99 | CHECK-NEXT: 0500: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 99 | CHECK-NEXT: 0500: 81FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 100 | CHECK-NEXT: 0510: FFFFFFFF FFFFFFFF A4A4A4D7 D7D79D9D |................| | 100 | CHECK-NEXT: 0510: FFFFFFFF FFFFFFFF FFFFFFFF A4A4A4D7 |................| |
| 101 | CHECK-NEXT: 0520: 9DD0D0D0 EEEEEE91 91918D8D 8DFFFFFF |................| | 101 | CHECK-NEXT: 0520: D7D79D9D 9DD0D0D0 EEEEEE91 91918D8D |................| |
| 102 | CHECK-NEXT: 0530: FFFFFF81 81817E7E 7EFFFFFF FFFFFFFF |......~~~.......| | 102 | CHECK-NEXT: 0530: 8DFFFFFF FFFFFF81 81817E7E 7EFFFFFF |..........~~~...| |
| 103 | CHECK-NEXT: 0540: FFFFFFFF FFFFFFFF A9A9A9F2 F2F2E5E5 |................| | 103 | CHECK-NEXT: 0540: FFFFFFFF FFFFFFFF FFFFFFFF A9A9A9F2 |................| |
| 104 | CHECK-NEXT: 0550: E5E2E2E2 95959591 91918D8D 8D898989 |................| | 104 | CHECK-NEXT: 0550: F2F2E5E5 E5E2E2E2 95959591 91918D8D |................| |
| 105 | CHECK-NEXT: 0560: 868686FF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 105 | CHECK-NEXT: 0560: 8D898989 868686FF FFFFFFFF FFFFFFFF |................| |
| 106 | CHECK-NEXT: 0570: FFFFFFFF FFFFFFFF ADADADF2 F2F2E1E1 |................| | 106 | CHECK-NEXT: 0570: FFFFFFFF FFFFFFFF FFFFFFFF ADADADF2 |................| |
| 107 | CHECK-NEXT: 0580: E1DFDFDF E7E7E7E4 E4E4BBBB BB8E8E8E |................| | 107 | CHECK-NEXT: 0580: F2F2E1E1 E1DFDFDF E7E7E7E4 E4E4BBBB |................| |
| 108 | CHECK-NEXT: 0590: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 108 | CHECK-NEXT: 0590: BB8E8E8E FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 109 | CHECK-NEXT: 05A0: FFFFFFFF FFFFFFFF B5B5B5F2 F2F2E8E8 |................| | 109 | CHECK-NEXT: 05A0: FFFFFFFF FFFFFFFF FFFFFFFF B5B5B5F2 |................| |
| 110 | CHECK-NEXT: 05B0: E8E7E7E7 EAEAEAC6 C6C69E9E 9EFFFFFF |................| | 110 | CHECK-NEXT: 05B0: F2F2E8E8 E8E7E7E7 EAEAEAC6 C6C69E9E |................| |
| 111 | CHECK-NEXT: 05C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 111 | CHECK-NEXT: 05C0: 9EFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 112 | CHECK-NEXT: 05D0: FFFFFFFF FFFFFFFF B9B9B9F4 F4F4ECEC |................| | 112 | CHECK-NEXT: 05D0: FFFFFFFF FFFFFFFF FFFFFFFF B9B9B9F4 |................| |
| 113 | CHECK-NEXT: 05E0: ECEDEDED CBCBCBA7 A7A7FFFF FFFFFFFF |................| | 113 | CHECK-NEXT: 05E0: F4F4ECEC ECEDEDED CBCBCBA7 A7A7FFFF |................| |
| 114 | CHECK-NEXT: 05F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 114 | CHECK-NEXT: 05F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 115 | CHECK-NEXT: 0600: FFFFFFFF FFFFFFFF BDBDBDF7 F7F7EFEF |................| | 115 | CHECK-NEXT: 0600: FFFFFFFF FFFFFFFF FFFFFFFF BDBDBDF7 |................| |
| 116 | CHECK-NEXT: 0610: EFD0D0D0 AFAFAFFF FFFFFFFF FFFFFFFF |................| | 116 | CHECK-NEXT: 0610: F7F7EFEF EFD0D0D0 AFAFAFFF FFFFFFFF |................| |
| 117 | CHECK-NEXT: 0620: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 117 | CHECK-NEXT: 0620: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 118 | CHECK-NEXT: 0630: FFFFFFFF FFFFFFFF C1C1C1F7 F7F7D5D5 |................| | 118 | CHECK-NEXT: 0630: FFFFFFFF FFFFFFFF FFFFFFFF C1C1C1F7 |................| |
| 119 | CHECK-NEXT: 0640: D5B6B6B6 FFFFFFFF FFFFFFFF FFFFFFFF |................| | 119 | CHECK-NEXT: 0640: F7F7D5D5 D5B6B6B6 FFFFFFFF FFFFFFFF |................| |
| 120 | CHECK-NEXT: 0650: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 120 | CHECK-NEXT: 0650: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 121 | CHECK-NEXT: 0660: FFFFFFFF FFFFFFFF C4C4C4D9 D9D9BEBE |................| | 121 | CHECK-NEXT: 0660: FFFFFFFF FFFFFFFF FFFFFFFF C4C4C4D9 |................| |
| 122 | CHECK-NEXT: 0670: BEFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 122 | CHECK-NEXT: 0670: D9D9BEBE BEFFFFFF FFFFFFFF FFFFFFFF |................| |
| 123 | CHECK-NEXT: 0680: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 123 | CHECK-NEXT: 0680: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 124 | CHECK-NEXT: 0690: FFFFFFFF FFFFFFFF C8C8C8C5 C5C5FFFF |................| | 124 | CHECK-NEXT: 0690: FFFFFFFF FFFFFFFF FFFFFFFF C8C8C8C5 |................| |
| 125 | CHECK-NEXT: 06A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 125 | CHECK-NEXT: 06A0: C5C5FFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 126 | CHECK-NEXT: 06B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 126 | CHECK-NEXT: 06B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 127 | CHECK-NEXT: 06C0: FFFFFFFF FFFFFFFF CBCBCBFF FFFFFFFF |................| | 127 | CHECK-NEXT: 06C0: FFFFFFFF FFFFFFFF FFFFFFFF CBCBCBFF |................| |
| 128 | CHECK-NEXT: 06D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 128 | CHECK-NEXT: 06D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 129 | CHECK-NEXT: 06E0: FFFFFFFF FFFFFFFF FFFFFFFF 28000000 |............(...| | 129 | CHECK-NEXT: 06E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 130 | CHECK-NEXT: 06F0: 10000000 10000000 01001800 00000000 |................| | 130 | CHECK-NEXT: 06F0: 28000000 10000000 10000000 01001800 |(...............| |
| 131 | CHECK-NEXT: 0700: 00030000 C40E0000 C40E0000 00000000 |................| | 131 | CHECK-NEXT: 0700: 00000000 00030000 C40E0000 C40E0000 |................| |
| 132 | CHECK-NEXT: 0710: 00000000 FFFFFFFF FFFFFFFF FFFFFFFF |................| | 132 | CHECK-NEXT: 0710: 00000000 00000000 FFFFFFFF FFFFFFFF |................| |
| 133 | CHECK-NEXT: 0720: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 133 | CHECK-NEXT: 0720: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 134 | CHECK-NEXT: 0730: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 134 | CHECK-NEXT: 0730: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 135 | CHECK-NEXT: 0740: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 135 | CHECK-NEXT: 0740: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| ... | @@ -142,29 +142,29 @@ CHECK-NEXT: 07A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | ... | @@ -142,29 +142,29 @@ CHECK-NEXT: 07A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 142 | CHECK-NEXT: 07B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 142 | CHECK-NEXT: 07B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 143 | CHECK-NEXT: 07C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 143 | CHECK-NEXT: 07C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 144 | CHECK-NEXT: 07D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 144 | CHECK-NEXT: 07D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 145 | CHECK-NEXT: 07E0: A0E3A901 B31801B3 1801B318 01B31801 |................| | 145 | CHECK-NEXT: 07E0: FFFFFFFF A0E3A901 B31801B3 1801B318 |................| |
| 146 | CHECK-NEXT: 07F0: B31801B3 1861D06F FFFFFFFF FFFFFFFF |.....a.o........| | 146 | CHECK-NEXT: 07F0: 01B31801 B31801B3 1861D06F FFFFFFFF |.........a.o....| |
| 147 | CHECK-NEXT: 0800: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 147 | CHECK-NEXT: 0800: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 148 | CHECK-NEXT: 0810: 01B31800 D7331CDB 49DBF9E2 9BEFAF00 |.....3..I.......| | 148 | CHECK-NEXT: 0810: FFFFFFFF 01B31800 D7331CDB 49DBF9E2 |.........3..I...| |
| 149 | CHECK-NEXT: 0820: D73300D7 3301B318 FFFFFFFF FFFFFFFF |.3..3...........| | 149 | CHECK-NEXT: 0820: 9BEFAF00 D73300D7 3301B318 FFFFFFFF |.....3..3.......| |
| 150 | CHECK-NEXT: 0830: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 150 | CHECK-NEXT: 0830: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 151 | CHECK-NEXT: 0840: 01B31800 DE55F6FE F9DBFAE7 FEFFFE86 |.....U..........| | 151 | CHECK-NEXT: 0840: FFFFFFFF 01B31800 DE55F6FE F9DBFAE7 |.........U......| |
| 152 | CHECK-NEXT: 0850: EFAE00DE 5501B318 FFFFFFFF FFFFFFFF |....U...........| | 152 | CHECK-NEXT: 0850: FEFFFE86 EFAE00DE 5501B318 FFFFFFFF |........U.......| |
| 153 | CHECK-NEXT: 0860: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 153 | CHECK-NEXT: 0860: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 154 | CHECK-NEXT: 0870: 01B31800 E676DBFB EC00E676 57EFA5FB |.....v.....vW...| | 154 | CHECK-NEXT: 0870: FFFFFFFF 01B31800 E676DBFB EC00E676 |.........v.....v| |
| 155 | CHECK-NEXT: 0880: FFFD55EE A401B318 FFFFFFFF FFFFFFFF |..U.............| | 155 | CHECK-NEXT: 0880: 57EFA5FB FFFD55EE A401B318 FFFFFFFF |W.....U.........| |
| 156 | CHECK-NEXT: 0890: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 156 | CHECK-NEXT: 0890: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 157 | CHECK-NEXT: 08A0: 01B31800 ED9800ED 9800ED98 00ED9887 |................| | 157 | CHECK-NEXT: 08A0: FFFFFFFF 01B31800 ED9800ED 9800ED98 |................| |
| 158 | CHECK-NEXT: 08B0: F7CFFEFF FF01B318 FFFFFFFF FFFFFFFF |................| | 158 | CHECK-NEXT: 08B0: 00ED9887 F7CFFEFF FF01B318 FFFFFFFF |................| |
| 159 | CHECK-NEXT: 08C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 159 | CHECK-NEXT: 08C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 160 | CHECK-NEXT: 08D0: 01B31800 F4BA00F4 BA00F4BA 00F4BA00 |................| | 160 | CHECK-NEXT: 08D0: FFFFFFFF 01B31800 F4BA00F4 BA00F4BA |................| |
| 161 | CHECK-NEXT: 08E0: F4BA9CFB E401B318 FFFFFFFF FFFFFFFF |................| | 161 | CHECK-NEXT: 08E0: 00F4BA00 F4BA9CFB E401B318 FFFFFFFF |................| |
| 162 | CHECK-NEXT: 08F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 162 | CHECK-NEXT: 08F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 163 | CHECK-NEXT: 0900: 01B31800 FBDB00FB DB00FBDB 00FBDB00 |................| | 163 | CHECK-NEXT: 0900: FFFFFFFF 01B31800 FBDB00FB DB00FBDB |................| |
| 164 | CHECK-NEXT: 0910: FBDB00FB DB01B318 FFFFFFFF FFFFFFFF |................| | 164 | CHECK-NEXT: 0910: 00FBDB00 FBDB00FB DB01B318 FFFFFFFF |................| |
| 165 | CHECK-NEXT: 0920: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 165 | CHECK-NEXT: 0920: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 166 | CHECK-NEXT: 0930: 9FE2A801 B31801B3 1801B318 01B31801 |................| | 166 | CHECK-NEXT: 0930: FFFFFFFF 9FE2A801 B31801B3 1801B318 |................| |
| 167 | CHECK-NEXT: 0940: B31801B3 1861D06F FFFFFFFF FFFFFFFF |.....a.o........| | 167 | CHECK-NEXT: 0940: 01B31801 B31801B3 1861D06F FFFFFFFF |.........a.o....| |
| 168 | CHECK-NEXT: 0950: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 168 | CHECK-NEXT: 0950: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 169 | CHECK-NEXT: 0960: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 169 | CHECK-NEXT: 0960: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 170 | CHECK-NEXT: 0970: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 170 | CHECK-NEXT: 0970: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| ... | @@ -177,37 +177,37 @@ CHECK-NEXT: 09D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | ... | @@ -177,37 +177,37 @@ CHECK-NEXT: 09D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 177 | CHECK-NEXT: 09E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 177 | CHECK-NEXT: 09E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 178 | CHECK-NEXT: 09F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 178 | CHECK-NEXT: 09F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 179 | CHECK-NEXT: 0A00: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| | 179 | CHECK-NEXT: 0A00: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................| |
| 180 | CHECK-NEXT: 0A10: FFFFFFFF 00000000 00006400 79007500 |..........d.y.u.| | 180 | CHECK-NEXT: 0A10: FFFFFFFF FFFFFFFF 00000000 00006400 |..............d.| |
| 181 | CHECK-NEXT: 0A20: 00000000 65007300 68006100 6C006100 |....e.s.h.a.l.a.| | 181 | CHECK-NEXT: 0A20: 79007500 00000000 65007300 68006100 |y.u.....e.s.h.a.| |
| 182 | CHECK-NEXT: 0A30: 00008000 66006B00 61006F00 79006100 |....f.k.a.o.y.a.| | 182 | CHECK-NEXT: 0A30: 6C006100 00008000 66006B00 61006F00 |l.a.....f.k.a.o.| |
| 183 | CHECK-NEXT: 0A40: 00000000 0000C080 00000000 02000A00 |................| | 183 | CHECK-NEXT: 0A40: 79006100 00000000 0000C080 00000000 |y.a.............| |
| 184 | CHECK-NEXT: 0A50: 0A00C800 2C010000 00005400 65007300 |....,.....T.e.s.| | 184 | CHECK-NEXT: 0A50: 02000A00 0A00C800 2C010000 00005400 |........,.....T.| |
| 185 | CHECK-NEXT: 0A60: 74000000 01000250 00000000 0A000A00 |t......P........| | 185 | CHECK-NEXT: 0A60: 65007300 74000000 01000250 00000000 |e.s.t......P....| |
| 186 | CHECK-NEXT: 0A70: E6000E00 0100FFFF 82004300 6F006E00 |..........C.o.n.| | 186 | CHECK-NEXT: 0A70: 0A000A00 E6000E00 0100FFFF 82004300 |..............C.| |
| 187 | CHECK-NEXT: 0A80: 74006900 6E007500 65003A00 00000000 |t.i.n.u.e.:.....| | 187 | CHECK-NEXT: 0A80: 6F006E00 74006900 6E007500 65003A00 |o.n.t.i.n.u.e.:.| |
| 188 | CHECK-NEXT: 0A90: 00000150 00000000 42008600 A1000D00 |...P....B.......| | 188 | CHECK-NEXT: 0A90: 00000000 00000150 00000000 42008600 |.......P....B...| |
| 189 | CHECK-NEXT: 0AA0: 0200FFFF 80002600 4F004B00 00000000 |......&.O.K.....| | 189 | CHECK-NEXT: 0AA0: A1000D00 0200FFFF 80002600 4F004B00 |..........&.O.K.| |
| 190 | CHECK-NEXT: 0AB0: 00000000 11005800 A4000000 0D004800 |......X.......H.| | 190 | CHECK-NEXT: 0AB0: 00000000 00000000 11005800 A4000000 |..........X.....| |
| 191 | CHECK-NEXT: 0AC0: 2E160000 82001200 BC010000 00000000 |................| | 191 | CHECK-NEXT: 0AC0: 0D004800 2E160000 82001200 BC010000 |..H.............| |
| 192 | CHECK-NEXT: 0AD0: 00006400 66006900 73006800 00000000 |..d.f.i.s.h.....| | 192 | CHECK-NEXT: 0AD0: 00000000 00006400 66006900 73006800 |......d.f.i.s.h.| |
| 193 | CHECK-NEXT: 0AE0: 65007300 61006C00 61006400 00008000 |e.s.a.l.a.d.....| | 193 | CHECK-NEXT: 0AE0: 00000000 65007300 61006C00 61006400 |....e.s.a.l.a.d.| |
| 194 | CHECK-NEXT: 0AF0: 66006400 75006300 6B000000 74686973 |f.d.u.c.k...this| | 194 | CHECK-NEXT: 0AF0: 00008000 66006400 75006300 6B000000 |....f.d.u.c.k...| |
| 195 | CHECK-NEXT: 0B00: 20697320 61207573 65722064 6566696E | is a user defin| | 195 | CHECK-NEXT: 0B00: 74686973 20697320 61207573 65722064 |this is a user d| |
| 196 | CHECK-NEXT: 0B10: 65642072 65736F75 72636500 69742063 |ed resource.it c| | 196 | CHECK-NEXT: 0B10: 6566696E 65642072 65736F75 72636500 |efined resource.| |
| 197 | CHECK-NEXT: 0B20: 6F6E7461 696E7320 6D616E79 20737472 |ontains many str| | 197 | CHECK-NEXT: 0B20: 69742063 6F6E7461 696E7320 6D616E79 |it contains many| |
| 198 | CHECK-NEXT: 0B30: 696E6773 00000000 00000000 74686973 |ings........this| | 198 | CHECK-NEXT: 0B30: 20737472 696E6773 00000000 00000000 | strings........| |
| 199 | CHECK-NEXT: 0B40: 20697320 61207261 6E646F6D 20626974 | is a random bit| | 199 | CHECK-NEXT: 0B40: 74686973 20697320 61207261 6E646F6D |this is a random| |
| 200 | CHECK-NEXT: 0B50: 206F6620 64617461 20746861 74206D65 | of data that me| | 200 | CHECK-NEXT: 0B50: 20626974 206F6620 64617461 20746861 | bit of data tha| |
| 201 | CHECK-NEXT: 0B60: 616E7320 6E6F7468 696E6700 A9230E14 |ans nothing..#..| | 201 | CHECK-NEXT: 0B60: 74206D65 616E7320 6E6F7468 696E6700 |t means nothing.| |
| 202 | CHECK-NEXT: 0B70: F4F60000 7A686534 20736869 34207969 |....zhe4 shi4 yi| | 202 | CHECK-NEXT: 0B70: A9230E14 F4F60000 7A686534 20736869 |.#......zhe4 shi| |
| 203 | CHECK-NEXT: 0B80: 31676534 20737569 326A6931 20646520 |1ge4 sui2ji1 de | | 203 | CHECK-NEXT: 0B80: 34207969 31676534 20737569 326A6931 |4 yi1ge4 sui2ji1| |
| 204 | CHECK-NEXT: 0B90: 73687534 6A75342C 207A6865 34207969 |shu4ju4, zhe4 yi| | 204 | CHECK-NEXT: 0B90: 20646520 73687534 6A75342C 207A6865 | de shu4ju4, zhe| |
| 205 | CHECK-NEXT: 0BA0: 34776569 347A6865 20736865 6E326D65 |4wei4zhe shen2me| | 205 | CHECK-NEXT: 0BA0: 34207969 34776569 347A6865 20736865 |4 yi4wei4zhe she| |
| 206 | CHECK-NEXT: 0BB0: 00A9230E 14F4F600 00000000 44696573 |..#.........Dies| | 206 | CHECK-NEXT: 0BB0: 6E326D65 00A9230E 14F4F600 00000000 |n2me..#.........| |
| 207 | CHECK-NEXT: 0BC0: 20697374 2065696E 207A7566 C3A46C6C | ist ein zuf..ll| | 207 | CHECK-NEXT: 0BC0: 44696573 20697374 2065696E 207A7566 |Dies ist ein zuf| |
| 208 | CHECK-NEXT: 0BD0: 69676573 20426974 20766F6E 20446174 |iges Bit von Dat| | 208 | CHECK-NEXT: 0BD0: C3A46C6C 69676573 20426974 20766F6E |..lliges Bit von| |
| 209 | CHECK-NEXT: 0BE0: 656E2C20 64696520 6E696368 74732062 |en, die nichts b| | 209 | CHECK-NEXT: 0BE0: 20446174 656E2C20 64696520 6E696368 | Daten, die nich| |
| 210 | CHECK-NEXT: 0BF0: 65646575 74657400 A9230E14 F4F60000 |edeutet..#......| | 210 | CHECK-NEXT: 0BF0: 74732062 65646575 74657400 A9230E14 |ts bedeutet..#..| |
| 211 | CHECK-NEXT: 0C00: 00000000 11000300 E7030000 0D004400 |..............D.| | 211 | CHECK-NEXT: 0C00: F4F60000 00000000 11000300 E7030000 |................| |
| 212 | CHECK-NEXT: 0C10: 4C040000 82001200 BC010000 |L...........| | 212 | CHECK-NEXT: 0C10: 0D004400 4C040000 82001200 BC010000 |..D.L...........| |
| 213 | CHECK-NEXT: ) | 213 | CHECK-NEXT: ) |
deps/lld/test/COFF/common-alignment.test+2-18| ... | @@ -4,8 +4,8 @@ | ... | @@ -4,8 +4,8 @@ |
| 4 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | 4 | # RUN: llvm-objdump -d %t.exe | FileCheck %s |
| 5 | 5 | ||
| 6 | # Operands of B8 (MOV EAX) are common symbols | 6 | # Operands of B8 (MOV EAX) are common symbols |
| 7 | # CHECK: 3000: b8 00 10 00 40 | 7 | # CHECK: 1000: b8 00 20 00 40 |
| 8 | # CHECK: 3005: b8 10 10 00 40 | 8 | # CHECK: 1005: b8 10 20 00 40 |
| 9 | 9 | ||
| 10 | --- !COFF | 10 | --- !COFF |
| 11 | header: | 11 | header: |
| ... | @@ -23,10 +23,6 @@ sections: | ... | @@ -23,10 +23,6 @@ sections: |
| 23 | - VirtualAddress: 6 | 23 | - VirtualAddress: 6 |
| 24 | SymbolName: bssdata4_align16 | 24 | SymbolName: bssdata4_align16 |
| 25 | Type: IMAGE_REL_AMD64_ADDR32 | 25 | Type: IMAGE_REL_AMD64_ADDR32 |
| 26 | - Name: .data | ||
| 27 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 28 | Alignment: 4 | ||
| 29 | SectionData: 03000000 | ||
| 30 | - Name: .drectve | 26 | - Name: .drectve |
| 31 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] | 27 | Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] |
| 32 | Alignment: 1 | 28 | Alignment: 1 |
| ... | @@ -45,18 +41,6 @@ symbols: | ... | @@ -45,18 +41,6 @@ symbols: |
| 45 | NumberOfLinenumbers: 0 | 41 | NumberOfLinenumbers: 0 |
| 46 | CheckSum: 0 | 42 | CheckSum: 0 |
| 47 | Number: 0 | 43 | Number: 0 |
| 48 | - Name: .data | ||
| 49 | Value: 0 | ||
| 50 | SectionNumber: 2 | ||
| 51 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 52 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 53 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 54 | SectionDefinition: | ||
| 55 | Length: 4 | ||
| 56 | NumberOfRelocations: 0 | ||
| 57 | NumberOfLinenumbers: 0 | ||
| 58 | CheckSum: 0 | ||
| 59 | Number: 0 | ||
| 60 | - Name: main | 44 | - Name: main |
| 61 | Value: 0 | 45 | Value: 0 |
| 62 | SectionNumber: 1 | 46 | SectionNumber: 1 |
deps/lld/test/COFF/common.test+5-21| ... | @@ -4,11 +4,11 @@ | ... | @@ -4,11 +4,11 @@ |
| 4 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | 4 | # RUN: llvm-objdump -d %t.exe | FileCheck %s |
| 5 | 5 | ||
| 6 | # Operands of B8 (MOV EAX) are common symbols | 6 | # Operands of B8 (MOV EAX) are common symbols |
| 7 | # CHECK: 3000: b8 00 10 00 40 | 7 | # CHECK: 1000: b8 00 20 00 40 |
| 8 | # CHECK: 3005: b8 04 10 00 40 | 8 | # CHECK: 1005: b8 04 20 00 40 |
| 9 | # CHECK: 300a: b8 20 10 00 40 | 9 | # CHECK: 100a: b8 20 20 00 40 |
| 10 | # CHECK: 300f: b8 60 10 00 40 | 10 | # CHECK: 100f: b8 60 20 00 40 |
| 11 | # CHECK: 3014: b8 70 10 00 40 | 11 | # CHECK: 1014: b8 70 20 00 40 |
| 12 | 12 | ||
| 13 | --- !COFF | 13 | --- !COFF |
| 14 | header: | 14 | header: |
| ... | @@ -35,10 +35,6 @@ sections: | ... | @@ -35,10 +35,6 @@ sections: |
| 35 | - VirtualAddress: 21 | 35 | - VirtualAddress: 21 |
| 36 | SymbolName: bssdata16 | 36 | SymbolName: bssdata16 |
| 37 | Type: IMAGE_REL_AMD64_ADDR32 | 37 | Type: IMAGE_REL_AMD64_ADDR32 |
| 38 | - Name: .data | ||
| 39 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 40 | Alignment: 4 | ||
| 41 | SectionData: 03000000 | ||
| 42 | symbols: | 38 | symbols: |
| 43 | - Name: .text | 39 | - Name: .text |
| 44 | Value: 0 | 40 | Value: 0 |
| ... | @@ -52,18 +48,6 @@ symbols: | ... | @@ -52,18 +48,6 @@ symbols: |
| 52 | NumberOfLinenumbers: 0 | 48 | NumberOfLinenumbers: 0 |
| 53 | CheckSum: 0 | 49 | CheckSum: 0 |
| 54 | Number: 0 | 50 | Number: 0 |
| 55 | - Name: .data | ||
| 56 | Value: 0 | ||
| 57 | SectionNumber: 2 | ||
| 58 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 59 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 60 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 61 | SectionDefinition: | ||
| 62 | Length: 4 | ||
| 63 | NumberOfRelocations: 0 | ||
| 64 | NumberOfLinenumbers: 0 | ||
| 65 | CheckSum: 0 | ||
| 66 | Number: 0 | ||
| 67 | - Name: main | 51 | - Name: main |
| 68 | Value: 0 | 52 | Value: 0 |
| 69 | SectionNumber: 1 | 53 | SectionNumber: 1 |
deps/lld/test/COFF/crt-chars.test created+32| ... | @@ -0,0 +1,32 @@ | ||
| 1 | # RUN: yaml2obj %s > %t.obj | ||
| 2 | # RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj | ||
| 3 | # RUN: llvm-readobj -sections -section-data %t.dll | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: Name: .CRT | ||
| 6 | # CHECK: Characteristics [ | ||
| 7 | # CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 8 | # CHECK-NEXT: IMAGE_SCN_MEM_READ | ||
| 9 | # CHECK-NEXT: ] | ||
| 10 | # CHECK-NEXT: SectionData ( | ||
| 11 | # CHECK-NEXT: 010203 | ||
| 12 | # CHECK-NEXT: ) | ||
| 13 | |||
| 14 | --- !COFF | ||
| 15 | header: | ||
| 16 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 17 | Characteristics: [ ] | ||
| 18 | sections: | ||
| 19 | - Name: .CRT$XCZ | ||
| 20 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 21 | Alignment: 1 | ||
| 22 | SectionData: 03 | ||
| 23 | - Name: .CRT$XCU | ||
| 24 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 25 | Alignment: 1 | ||
| 26 | SectionData: 02 | ||
| 27 | - Name: .CRT$XCA | ||
| 28 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 29 | Alignment: 1 | ||
| 30 | SectionData: 01 | ||
| 31 | symbols: | ||
| 32 | ... | ||
deps/lld/test/COFF/ctors_dtors_priority.s+4-4| ... | @@ -22,9 +22,9 @@ main: | ... | @@ -22,9 +22,9 @@ main: |
| 22 | .quad 2 | 22 | .quad 2 |
| 23 | 23 | ||
| 24 | # CHECK: Contents of section .ctors: | 24 | # CHECK: Contents of section .ctors: |
| 25 | # CHECK-NEXT: 140001000 01000000 00000000 02000000 00000000 | ||
| 26 | # CHECK-NEXT: 140001010 03000000 00000000 | ||
| 27 | |||
| 28 | # CHECK: Contents of section .dtors: | ||
| 29 | # CHECK-NEXT: 140002000 01000000 00000000 02000000 00000000 | 25 | # CHECK-NEXT: 140002000 01000000 00000000 02000000 00000000 |
| 30 | # CHECK-NEXT: 140002010 03000000 00000000 | 26 | # CHECK-NEXT: 140002010 03000000 00000000 |
| 27 | |||
| 28 | # CHECK: Contents of section .dtors: | ||
| 29 | # CHECK-NEXT: 140003000 01000000 00000000 02000000 00000000 | ||
| 30 | # CHECK-NEXT: 140003010 03000000 00000000 |
deps/lld/test/COFF/debug-reloc.s created+58| ... | @@ -0,0 +1,58 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj | ||
| 4 | |||
| 5 | # 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 | ||
| 10 | |||
| 11 | # SECTIONS: Number: 2 | ||
| 12 | # SECTIONS-NEXT: Name: .buildid (2E 62 75 69 6C 64 69 64) | ||
| 13 | # SECTIONS-NEXT: VirtualSize: 0x35 | ||
| 14 | # SECTIONS-NEXT: VirtualAddress: 0x2000 | ||
| 15 | # SECTIONS: Number: 3 | ||
| 16 | # SECTIONS-NEXT: Name: .data (2E 64 61 74 61 00 00 00) | ||
| 17 | # SECTIONS-NEXT: VirtualSize: 0x8 | ||
| 18 | # SECTIONS-NEXT: VirtualAddress: 0x3000 | ||
| 19 | |||
| 20 | # RELOCS: BaseReloc [ | ||
| 21 | # RELOCS-NEXT: Entry { | ||
| 22 | # RELOCS-NEXT: Type: DIR64 | ||
| 23 | # RELOCS-NEXT: Address: 0x3000 | ||
| 24 | # RELOCS-NEXT: } | ||
| 25 | # RELOCS-NEXT: Entry { | ||
| 26 | # RELOCS-NEXT: Type: ABSOLUTE | ||
| 27 | # RELOCS-NEXT: Address: 0x3000 | ||
| 28 | # RELOCS-NEXT: } | ||
| 29 | # RELOCS-NEXT: ] | ||
| 30 | |||
| 31 | # HEADERS: DebugRVA: 0x2000 | ||
| 32 | # HEADERS: DebugSize: 0x1C | ||
| 33 | |||
| 34 | # DEBUG: DebugDirectory [ | ||
| 35 | # DEBUG: DebugEntry { | ||
| 36 | # DEBUG: Type: CodeView (0x2) | ||
| 37 | # DEBUG: SizeOfData: 0x19 | ||
| 38 | # DEBUG: AddressOfRawData: 0x201C | ||
| 39 | # DEBUG: PointerToRawData: 0x61C | ||
| 40 | |||
| 41 | 	.text | ||
| 42 | 	.def	 mainfunc; | ||
| 43 | 	.scl	2; | ||
| 44 | 	.type	32; | ||
| 45 | 	.endef | ||
| 46 | 	.globl	mainfunc | ||
| 47 | mainfunc: | ||
| 48 | .Lfunc_begin0: | ||
| 49 | 	xorl	%eax, %eax | ||
| 50 | 	retq | ||
| 51 | |||
| 52 | 	.data | ||
| 53 | 	.globl	ptr | ||
| 54 | ptr: | ||
| 55 | 	.quad	mainfunc | ||
| 56 | |||
| 57 | 	.section	.debug_info,"dr" | ||
| 58 | 	.quad	.Lfunc_begin0 | ||
deps/lld/test/COFF/def-export-stdcall.s+34-5| ... | @@ -32,8 +32,7 @@ | ... | @@ -32,8 +32,7 @@ |
| 32 | # DECORATED-IMPLIB: Name type: name | 32 | # DECORATED-IMPLIB: Name type: name |
| 33 | # DECORATED-IMPLIB-NEXT: __imp_@fastcall@8 | 33 | # DECORATED-IMPLIB-NEXT: __imp_@fastcall@8 |
| 34 | # DECORATED-IMPLIB-NEXT: @fastcall@8 | 34 | # DECORATED-IMPLIB-NEXT: @fastcall@8 |
| 35 | # TODO: To match link.exe, this one should also be Name type: name. | 35 | # DECORATED-IMPLIB: Name type: name |
| 36 | # DECORATED-IMPLIB: Name type: noprefix | ||
| 37 | # DECORATED-IMPLIB-NEXT: __imp__stdcall@8 | 36 | # DECORATED-IMPLIB-NEXT: __imp__stdcall@8 |
| 38 | # DECORATED-IMPLIB-NEXT: _stdcall@8 | 37 | # DECORATED-IMPLIB-NEXT: _stdcall@8 |
| 39 | # DECORATED-IMPLIB: Name type: name | 38 | # DECORATED-IMPLIB: Name type: name |
| ... | @@ -41,12 +40,12 @@ | ... | @@ -41,12 +40,12 @@ |
| 41 | # DECORATED-IMPLIB-NEXT: vectorcall@@8 | 40 | # DECORATED-IMPLIB-NEXT: vectorcall@@8 |
| 42 | 41 | ||
| 43 | # DECORATED-EXPORTS: Name: @fastcall@8 | 42 | # DECORATED-EXPORTS: Name: @fastcall@8 |
| 44 | # TODO: To match link.exe, this one should actually be _stdcall@8 | 43 | # DECORATED-EXPORTS: Name: _stdcall@8 |
| 45 | # DECORATED-EXPORTS: Name: stdcall@8 | ||
| 46 | # DECORATED-EXPORTS: Name: vectorcall@@8 | 44 | # DECORATED-EXPORTS: Name: vectorcall@@8 |
| 47 | 45 | ||
| 48 | 46 | ||
| 49 | # RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall@8\n @fastcall@8" > %t.def | 47 | # GNU tools don't support vectorcall at the moment, but test it for completeness. |
| 48 | # RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall@8\n @fastcall@8\n vectorcall@@8" > %t.def | ||
| 50 | # RUN: lld-link -lldmingw -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib | 49 | # RUN: lld-link -lldmingw -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib |
| 51 | # RUN: llvm-readobj %t.lib | FileCheck -check-prefix DECORATED-MINGW-IMPLIB %s | 50 | # RUN: llvm-readobj %t.lib | FileCheck -check-prefix DECORATED-MINGW-IMPLIB %s |
| 52 | # 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 |
| ... | @@ -57,9 +56,39 @@ | ... | @@ -57,9 +56,39 @@ |
| 57 | # DECORATED-MINGW-IMPLIB: Name type: noprefix | 56 | # DECORATED-MINGW-IMPLIB: Name type: noprefix |
| 58 | # DECORATED-MINGW-IMPLIB-NEXT: __imp__stdcall@8 | 57 | # DECORATED-MINGW-IMPLIB-NEXT: __imp__stdcall@8 |
| 59 | # DECORATED-MINGW-IMPLIB-NEXT: _stdcall@8 | 58 | # DECORATED-MINGW-IMPLIB-NEXT: _stdcall@8 |
| 59 | # GNU tools don't support vectorcall, but this test is just to track that | ||
| 60 | # lld's behaviour remains consistent over time. | ||
| 61 | # DECORATED-MINGW-IMPLIB: Name type: name | ||
| 62 | # DECORATED-MINGW-IMPLIB-NEXT: __imp_vectorcall@@8 | ||
| 63 | # DECORATED-MINGW-IMPLIB-NEXT: vectorcall@@8 | ||
| 60 | 64 | ||
| 61 | # DECORATED-MINGW-EXPORTS: Name: @fastcall@8 | 65 | # DECORATED-MINGW-EXPORTS: Name: @fastcall@8 |
| 62 | # DECORATED-MINGW-EXPORTS: Name: stdcall@8 | 66 | # DECORATED-MINGW-EXPORTS: Name: stdcall@8 |
| 67 | # DECORATED-MINGW-EXPORTS: Name: vectorcall@@8 | ||
| 68 | |||
| 69 | # RUN: lld-link -lldmingw -kill-at -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib | ||
| 70 | # 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 | ||
| 72 | |||
| 73 | # RUN: lld-link -lldmingw -kill-at -entry:dllmain -dll %t.obj -out:%t.dll -implib:%t.lib | ||
| 74 | # 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 | ||
| 76 | |||
| 77 | # MINGW-KILL-AT-IMPLIB: Name type: noprefix | ||
| 78 | # MINGW-KILL-AT-IMPLIB: __imp__fastcall | ||
| 79 | # MINGW-KILL-AT-IMPLIB-NEXT: _fastcall | ||
| 80 | # MINGW-KILL-AT-IMPLIB: Name type: noprefix | ||
| 81 | # MINGW-KILL-AT-IMPLIB-NEXT: __imp__stdcall | ||
| 82 | # MINGW-KILL-AT-IMPLIB-NEXT: _stdcall | ||
| 83 | # GNU tools don't support vectorcall, but this test is just to track that | ||
| 84 | # lld's behaviour remains consistent over time. | ||
| 85 | # MINGW-KILL-AT-IMPLIB: Name type: noprefix | ||
| 86 | # MINGW-KILL-AT-IMPLIB-NEXT: __imp__vectorcall | ||
| 87 | # MINGW-KILL-AT-IMPLIB-NEXT: _vectorcall | ||
| 88 | |||
| 89 | # MINGW-KILL-AT-EXPORTS: Name: fastcall | ||
| 90 | # MINGW-KILL-AT-EXPORTS: Name: stdcall | ||
| 91 | # MINGW-KILL-AT-EXPORTS: Name: vectorcall | ||
| 63 | 92 | ||
| 64 | 93 | ||
| 65 | .def _stdcall@8; | 94 | .def _stdcall@8; |
deps/lld/test/COFF/default-alignment.test created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # RUN: yaml2obj < %s > %t.obj | ||
| 2 | # RUN: lld-link /out:%t.exe %t.obj /entry:__ImageBase /subsystem:console | ||
| 3 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: Contents of section .rdata: | ||
| 6 | # CHECK-NEXT: 01000000 00000000 00000000 00000000 | ||
| 7 | # CHECK-NEXT: 02 | ||
| 8 | |||
| 9 | --- !COFF | ||
| 10 | header: | ||
| 11 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 12 | Characteristics: [] | ||
| 13 | sections: | ||
| 14 | - Name: .rdata | ||
| 15 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 16 | SectionData: 01 | ||
| 17 | - Name: .rdata | ||
| 18 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 19 | SectionData: 02 | ||
| 20 | symbols: | ||
| 21 | ... | ||
deps/lld/test/COFF/delayimports-armnt.yaml+17-17| ... | @@ -20,7 +20,7 @@ | ... | @@ -20,7 +20,7 @@ |
| 20 | # IMPORT-NEXT: UnloadDelayImportTable: 0x0 | 20 | # IMPORT-NEXT: UnloadDelayImportTable: 0x0 |
| 21 | # IMPORT-NEXT: Import { | 21 | # IMPORT-NEXT: Import { |
| 22 | # IMPORT-NEXT: Symbol: function (0) | 22 | # IMPORT-NEXT: Symbol: function (0) |
| 23 | # IMPORT-NEXT: Address: 0x401019 | 23 | # IMPORT-NEXT: Address: 0x40100D |
| 24 | # IMPORT-NEXT: } | 24 | # IMPORT-NEXT: } |
| 25 | # IMPORT-NEXT: } | 25 | # IMPORT-NEXT: } |
| 26 | # | 26 | # |
| ... | @@ -35,11 +35,11 @@ | ... | @@ -35,11 +35,11 @@ |
| 35 | # BASEREL-NEXT: } | 35 | # BASEREL-NEXT: } |
| 36 | # BASEREL-NEXT: Entry { | 36 | # BASEREL-NEXT: Entry { |
| 37 | # BASEREL-NEXT: Type: ARM_MOV32(T) | 37 | # BASEREL-NEXT: Type: ARM_MOV32(T) |
| 38 | # BASEREL-NEXT: Address: 0x1018 | 38 | # BASEREL-NEXT: Address: 0x1022 |
| 39 | # BASEREL-NEXT: } | 39 | # BASEREL-NEXT: } |
| 40 | # BASEREL-NEXT: Entry { | 40 | # BASEREL-NEXT: Entry { |
| 41 | # BASEREL-NEXT: Type: ARM_MOV32(T) | 41 | # BASEREL-NEXT: Type: ABSOLUTE |
| 42 | # BASEREL-NEXT: Address: 0x102E | 42 | # BASEREL-NEXT: Address: 0x1000 |
| 43 | # BASEREL-NEXT: } | 43 | # BASEREL-NEXT: } |
| 44 | # BASEREL-NEXT: Entry { | 44 | # BASEREL-NEXT: Entry { |
| 45 | # BASEREL-NEXT: Type: HIGHLOW | 45 | # BASEREL-NEXT: Type: HIGHLOW |
| ... | @@ -51,19 +51,19 @@ | ... | @@ -51,19 +51,19 @@ |
| 51 | # BASEREL-NEXT: } | 51 | # BASEREL-NEXT: } |
| 52 | # BASEREL-NEXT: ] | 52 | # BASEREL-NEXT: ] |
| 53 | # | 53 | # |
| 54 | # DISASM: 401018: 43 f2 08 0c movw r12, #12296 | 54 | # DISASM: 40100c: 43 f2 08 0c movw r12, #12296 |
| 55 | # DISASM-NEXT: 40101c: c0 f2 40 0c movt r12, #64 | 55 | # DISASM-NEXT: c0 f2 40 0c movt r12, #64 |
| 56 | # DISASM-NEXT: 401020: 2d e9 0f 48 push.w {r0, r1, r2, r3, r11, lr} | 56 | # DISASM-NEXT: 2d e9 0f 48 push.w {r0, r1, r2, r3, r11, lr} |
| 57 | # DISASM-NEXT: 401024: 0d f2 10 0b addw r11, sp, #16 | 57 | # DISASM-NEXT: 0d f2 10 0b addw r11, sp, #16 |
| 58 | # DISASM-NEXT: 401028: 2d ed 10 0b vpush {d0, d1, d2, d3, d4, d5, d6, d7} | 58 | # DISASM-NEXT: 2d ed 10 0b vpush {d0, d1, d2, d3, d4, d5, d6, d7} |
| 59 | # DISASM-NEXT: 40102c: 61 46 mov r1, r12 | 59 | # DISASM-NEXT: 61 46 mov r1, r12 |
| 60 | # DISASM-NEXT: 40102e: 42 f2 00 00 movw r0, #8192 | 60 | # DISASM-NEXT: 42 f2 00 00 movw r0, #8192 |
| 61 | # DISASM-NEXT: 401032: c0 f2 40 00 movt r0, #64 | 61 | # DISASM-NEXT: c0 f2 40 00 movt r0, #64 |
| 62 | # DISASM-NEXT: 401036: ff f7 e3 ff bl #-58 | 62 | # DISASM-NEXT: ff f7 e9 ff bl #-46 |
| 63 | # DISASM-NEXT: 40103a: 84 46 mov r12, r0 | 63 | # DISASM-NEXT: 84 46 mov r12, r0 |
| 64 | # DISASM-NEXT: 40103c: bd ec 10 0b vpop {d0, d1, d2, d3, d4, d5, d6, d7} | 64 | # DISASM-NEXT: bd ec 10 0b vpop {d0, d1, d2, d3, d4, d5, d6, d7} |
| 65 | # DISASM-NEXT: 401040: bd e8 0f 48 pop.w {r0, r1, r2, r3, r11, lr} | 65 | # DISASM-NEXT: bd e8 0f 48 pop.w {r0, r1, r2, r3, r11, lr} |
| 66 | # DISASM-NEXT: 401044: 60 47 bx r12 | 66 | # DISASM-NEXT: 60 47 bx r12 |
| 67 | 67 | ||
| 68 | --- !COFF | 68 | --- !COFF |
| 69 | header: | 69 | header: |
deps/lld/test/COFF/delayimports.test+9-9| ... | @@ -7,35 +7,35 @@ | ... | @@ -7,35 +7,35 @@ |
| 7 | IMPORT: DelayImport { | 7 | IMPORT: DelayImport { |
| 8 | IMPORT-NEXT: Name: std64.dll | 8 | IMPORT-NEXT: Name: std64.dll |
| 9 | IMPORT-NEXT: Attributes: 0x1 | 9 | IMPORT-NEXT: Attributes: 0x1 |
| 10 | IMPORT-NEXT: ModuleHandle: 0x1018 | 10 | IMPORT-NEXT: ModuleHandle: 0x3018 |
| 11 | IMPORT-NEXT: ImportAddressTable: 0x1020 | 11 | IMPORT-NEXT: ImportAddressTable: 0x3020 |
| 12 | IMPORT-NEXT: ImportNameTable: 0x3040 | 12 | IMPORT-NEXT: ImportNameTable: 0x2040 |
| 13 | IMPORT-NEXT: BoundDelayImportTable: 0x0 | 13 | IMPORT-NEXT: BoundDelayImportTable: 0x0 |
| 14 | IMPORT-NEXT: UnloadDelayImportTable: 0x0 | 14 | IMPORT-NEXT: UnloadDelayImportTable: 0x0 |
| 15 | IMPORT-NEXT: Import { | 15 | IMPORT-NEXT: Import { |
| 16 | IMPORT-NEXT: Symbol: ExitProcess (0) | 16 | IMPORT-NEXT: Symbol: ExitProcess (0) |
| 17 | IMPORT-NEXT: Address: 0x140002066 | 17 | IMPORT-NEXT: Address: 0x140001066 |
| 18 | IMPORT-NEXT: } | 18 | IMPORT-NEXT: } |
| 19 | IMPORT-NEXT: Import { | 19 | IMPORT-NEXT: Import { |
| 20 | IMPORT-NEXT: Symbol: (50) | 20 | IMPORT-NEXT: Symbol: (50) |
| 21 | IMPORT-NEXT: Address: 0x1400020BD | 21 | IMPORT-NEXT: Address: 0x1400010BD |
| 22 | IMPORT-NEXT: } | 22 | IMPORT-NEXT: } |
| 23 | IMPORT-NEXT: Import { | 23 | IMPORT-NEXT: Import { |
| 24 | IMPORT-NEXT: Symbol: MessageBoxA (0) | 24 | IMPORT-NEXT: Symbol: MessageBoxA (0) |
| 25 | IMPORT-NEXT: Address: 0x140002114 | 25 | IMPORT-NEXT: Address: 0x140001114 |
| 26 | IMPORT-NEXT: } | 26 | IMPORT-NEXT: } |
| 27 | IMPORT-NEXT: } | 27 | IMPORT-NEXT: } |
| 28 | 28 | ||
| 29 | BASEREL: BaseReloc [ | 29 | BASEREL: BaseReloc [ |
| 30 | BASEREL-NEXT: Entry { | 30 | BASEREL-NEXT: Entry { |
| 31 | BASEREL-NEXT: Type: DIR64 | 31 | BASEREL-NEXT: Type: DIR64 |
| 32 | BASEREL-NEXT: Address: 0x1020 | 32 | BASEREL-NEXT: Address: 0x3020 |
| 33 | BASEREL-NEXT: } | 33 | BASEREL-NEXT: } |
| 34 | BASEREL-NEXT: Entry { | 34 | BASEREL-NEXT: Entry { |
| 35 | BASEREL-NEXT: Type: DIR64 | 35 | BASEREL-NEXT: Type: DIR64 |
| 36 | BASEREL-NEXT: Address: 0x1028 | 36 | BASEREL-NEXT: Address: 0x3028 |
| 37 | BASEREL-NEXT: } | 37 | BASEREL-NEXT: } |
| 38 | BASEREL-NEXT: Entry { | 38 | BASEREL-NEXT: Entry { |
| 39 | BASEREL-NEXT: Type: DIR64 | 39 | BASEREL-NEXT: Type: DIR64 |
| 40 | BASEREL-NEXT: Address: 0x1030 | 40 | BASEREL-NEXT: Address: 0x3030 |
| 41 | BASEREL-NEXT: } | 41 | BASEREL-NEXT: } |
deps/lld/test/COFF/delayimports32.test+30-30| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj | 2 | # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj |
| 3 | # RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \ | 3 | # RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \ |
| 4 | # RUN: /entry:main@0 /alternatename:___delayLoadHelper2@8=_main@0 \ | 4 | # RUN: /entry:main@0 /alternatename:___delayLoadHelper2@8=_main@0 \ |
| 5 | # RUN: /debug /delayload:std32.dll /out:%t.exe | 5 | # RUN: /delayload:std32.dll /out:%t.exe |
| 6 | # RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %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 | 7 | # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s |
| 8 | # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s | 8 | # RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s |
| ... | @@ -13,75 +13,75 @@ IMPORT-NEXT: AddressSize: 32bit | ... | @@ -13,75 +13,75 @@ IMPORT-NEXT: AddressSize: 32bit |
| 13 | IMPORT-NEXT: DelayImport { | 13 | IMPORT-NEXT: DelayImport { |
| 14 | IMPORT-NEXT: Name: std32.dll | 14 | IMPORT-NEXT: Name: std32.dll |
| 15 | IMPORT-NEXT: Attributes: 0x1 | 15 | IMPORT-NEXT: Attributes: 0x1 |
| 16 | IMPORT-NEXT: ModuleHandle: 0x1018 | 16 | IMPORT-NEXT: ModuleHandle: 0x3018 |
| 17 | IMPORT-NEXT: ImportAddressTable: 0x1020 | 17 | IMPORT-NEXT: ImportAddressTable: 0x3020 |
| 18 | IMPORT-NEXT: ImportNameTable: 0x4040 | 18 | IMPORT-NEXT: ImportNameTable: 0x2040 |
| 19 | IMPORT-NEXT: BoundDelayImportTable: 0x0 | 19 | IMPORT-NEXT: BoundDelayImportTable: 0x0 |
| 20 | IMPORT-NEXT: UnloadDelayImportTable: 0x0 | 20 | IMPORT-NEXT: UnloadDelayImportTable: 0x0 |
| 21 | IMPORT-NEXT: Import { | 21 | IMPORT-NEXT: Import { |
| 22 | IMPORT-NEXT: Symbol: ExitProcess (0) | 22 | IMPORT-NEXT: Symbol: ExitProcess (0) |
| 23 | IMPORT-NEXT: Address: 0x402029 | 23 | IMPORT-NEXT: Address: 0x401029 |
| 24 | IMPORT-NEXT: } | 24 | IMPORT-NEXT: } |
| 25 | IMPORT-NEXT: Import { | 25 | IMPORT-NEXT: Import { |
| 26 | IMPORT-NEXT: Symbol: MessageBoxA (0) | 26 | IMPORT-NEXT: Symbol: MessageBoxA (0) |
| 27 | IMPORT-NEXT: Address: 0x40203E | 27 | IMPORT-NEXT: Address: 0x40103E |
| 28 | IMPORT-NEXT: } | 28 | IMPORT-NEXT: } |
| 29 | IMPORT-NEXT: } | 29 | IMPORT-NEXT: } |
| 30 | 30 | ||
| 31 | BASEREL: BaseReloc [ | 31 | BASEREL: BaseReloc [ |
| 32 | BASEREL-NEXT: Entry { | 32 | BASEREL-NEXT: Entry { |
| 33 | BASEREL-NEXT: Type: HIGHLOW | 33 | BASEREL-NEXT: Type: HIGHLOW |
| 34 | BASEREL-NEXT: Address: 0x1020 | 34 | BASEREL-NEXT: Address: 0x1005 |
| 35 | BASEREL-NEXT: } | 35 | BASEREL-NEXT: } |
| 36 | BASEREL-NEXT: Entry { | 36 | BASEREL-NEXT: Entry { |
| 37 | BASEREL-NEXT: Type: HIGHLOW | 37 | BASEREL-NEXT: Type: HIGHLOW |
| 38 | BASEREL-NEXT: Address: 0x1024 | 38 | BASEREL-NEXT: Address: 0x100C |
| 39 | BASEREL-NEXT: } | 39 | BASEREL-NEXT: } |
| 40 | BASEREL-NEXT: Entry { | 40 | BASEREL-NEXT: Entry { |
| 41 | BASEREL-NEXT: Type: HIGHLOW | 41 | BASEREL-NEXT: Type: HIGHLOW |
| 42 | BASEREL-NEXT: Address: 0x2005 | 42 | BASEREL-NEXT: Address: 0x101F |
| 43 | BASEREL-NEXT: } | 43 | BASEREL-NEXT: } |
| 44 | BASEREL-NEXT: Entry { | 44 | BASEREL-NEXT: Entry { |
| 45 | BASEREL-NEXT: Type: HIGHLOW | 45 | BASEREL-NEXT: Type: HIGHLOW |
| 46 | BASEREL-NEXT: Address: 0x200C | 46 | BASEREL-NEXT: Address: 0x1025 |
| 47 | BASEREL-NEXT: } | 47 | BASEREL-NEXT: } |
| 48 | BASEREL-NEXT: Entry { | 48 | BASEREL-NEXT: Entry { |
| 49 | BASEREL-NEXT: Type: HIGHLOW | 49 | BASEREL-NEXT: Type: HIGHLOW |
| 50 | BASEREL-NEXT: Address: 0x201F | 50 | BASEREL-NEXT: Address: 0x102C |
| 51 | BASEREL-NEXT: } | 51 | BASEREL-NEXT: } |
| 52 | BASEREL-NEXT: Entry { | 52 | BASEREL-NEXT: Entry { |
| 53 | BASEREL-NEXT: Type: HIGHLOW | 53 | BASEREL-NEXT: Type: HIGHLOW |
| 54 | BASEREL-NEXT: Address: 0x2025 | 54 | BASEREL-NEXT: Address: 0x1031 |
| 55 | BASEREL-NEXT: } | 55 | BASEREL-NEXT: } |
| 56 | BASEREL-NEXT: Entry { | 56 | BASEREL-NEXT: Entry { |
| 57 | BASEREL-NEXT: Type: HIGHLOW | 57 | BASEREL-NEXT: Type: HIGHLOW |
| 58 | BASEREL-NEXT: Address: 0x202C | 58 | BASEREL-NEXT: Address: 0x1041 |
| 59 | BASEREL-NEXT: } | 59 | BASEREL-NEXT: } |
| 60 | BASEREL-NEXT: Entry { | 60 | BASEREL-NEXT: Entry { |
| 61 | BASEREL-NEXT: Type: HIGHLOW | 61 | BASEREL-NEXT: Type: HIGHLOW |
| 62 | BASEREL-NEXT: Address: 0x2031 | 62 | BASEREL-NEXT: Address: 0x1046 |
| 63 | BASEREL-NEXT: } | 63 | BASEREL-NEXT: } |
| 64 | BASEREL-NEXT: Entry { | 64 | BASEREL-NEXT: Entry { |
| 65 | BASEREL-NEXT: Type: HIGHLOW | 65 | BASEREL-NEXT: Type: HIGHLOW |
| 66 | BASEREL-NEXT: Address: 0x2041 | 66 | BASEREL-NEXT: Address: 0x3020 |
| 67 | BASEREL-NEXT: } | 67 | BASEREL-NEXT: } |
| 68 | BASEREL-NEXT: Entry { | 68 | BASEREL-NEXT: Entry { |
| 69 | BASEREL-NEXT: Type: HIGHLOW | 69 | BASEREL-NEXT: Type: HIGHLOW |
| 70 | BASEREL-NEXT: Address: 0x2046 | 70 | BASEREL-NEXT: Address: 0x3024 |
| 71 | BASEREL-NEXT: } | 71 | BASEREL-NEXT: } |
| 72 | BASEREL-NEXT: ] | 72 | BASEREL-NEXT: ] |
| 73 | 73 | ||
| 74 | DISASM: 202b: 68 20 10 40 00 pushl $4198432 | 74 | DISASM: 102b: 68 20 30 40 00 pushl $4206624 |
| 75 | DISASM-NEXT: 2030: 68 00 40 40 00 pushl $4210688 | 75 | DISASM-NEXT: 1030: 68 00 20 40 00 pushl $4202496 |
| 76 | DISASM-NEXT: 2035: e8 c6 ff ff ff calll -58 <.text> | 76 | DISASM-NEXT: 1035: e8 c6 ff ff ff calll -58 <.text> |
| 77 | DISASM-NEXT: 203a: 5a popl %edx | 77 | DISASM-NEXT: 103a: 5a popl %edx |
| 78 | DISASM-NEXT: 203b: 59 popl %ecx | 78 | DISASM-NEXT: 103b: 59 popl %ecx |
| 79 | DISASM-NEXT: 203c: ff e0 jmpl *%eax | 79 | DISASM-NEXT: 103c: ff e0 jmpl *%eax |
| 80 | DISASM-NEXT: 203e: 51 pushl %ecx | 80 | DISASM-NEXT: 103e: 51 pushl %ecx |
| 81 | DISASM-NEXT: 203f: 52 pushl %edx | 81 | DISASM-NEXT: 103f: 52 pushl %edx |
| 82 | DISASM-NEXT: 2040: 68 24 10 40 00 pushl $4198436 | 82 | DISASM-NEXT: 1040: 68 24 30 40 00 pushl $4206628 |
| 83 | DISASM-NEXT: 2045: 68 00 40 40 00 pushl $4210688 | 83 | DISASM-NEXT: 1045: 68 00 20 40 00 pushl $4202496 |
| 84 | DISASM-NEXT: 204a: e8 b1 ff ff ff calll -79 <.text> | 84 | DISASM-NEXT: 104a: e8 b1 ff ff ff calll -79 <.text> |
| 85 | DISASM-NEXT: 204f: 5a popl %edx | 85 | DISASM-NEXT: 104f: 5a popl %edx |
| 86 | DISASM-NEXT: 2050: 59 popl %ecx | 86 | DISASM-NEXT: 1050: 59 popl %ecx |
| 87 | DISASM-NEXT: 2051: ff e0 jmpl *%eax | 87 | DISASM-NEXT: 1051: ff e0 jmpl *%eax |
deps/lld/test/COFF/dll.test+2-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj | 2 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj |
| 2 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ | 3 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \ |
| 3 | # RUN: /export:mangled | 4 | # RUN: /export:mangled |
| ... | @@ -26,7 +27,7 @@ EXPORT2-NEXT: 1 0x1010 exportfn3 | ... | @@ -26,7 +27,7 @@ EXPORT2-NEXT: 1 0x1010 exportfn3 |
| 26 | EXPORT2-NEXT: 2 0x101c mangled2 | 27 | EXPORT2-NEXT: 2 0x101c mangled2 |
| 27 | 28 | ||
| 28 | # RUN: llvm-as -o %t.lto.obj %p/Inputs/export.ll | 29 | # RUN: llvm-as -o %t.lto.obj %p/Inputs/export.ll |
| 29 | # RUN: lld-link /out:%t.lto.dll /dll %t.lto.obj /export:exportfn1 /export:exportfn2 | 30 | # RUN: lld-link -opt:noicf /out:%t.lto.dll /dll %t.lto.obj /export:exportfn1 /export:exportfn2 |
| 30 | # RUN: llvm-objdump -p %t.lto.dll | FileCheck -check-prefix=EXPORT-LTO %s | 31 | # RUN: llvm-objdump -p %t.lto.dll | FileCheck -check-prefix=EXPORT-LTO %s |
| 31 | 32 | ||
| 32 | EXPORT-LTO: Export Table: | 33 | EXPORT-LTO: Export Table: |
deps/lld/test/COFF/dllexport-mingw.s+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # REQEUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj | 3 | # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj |
| 4 | 4 |
deps/lld/test/COFF/dllexport.s created+58| ... | @@ -0,0 +1,58 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o %t.obj | ||
| 3 | |||
| 4 | # RUN: lld-link -entry:dllmain -dll %t.obj -out:%t.dll -implib:%t.lib | ||
| 5 | # 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 | ||
| 7 | |||
| 8 | # DECORATED-IMPLIB: Name type: name | ||
| 9 | # DECORATED-IMPLIB-NEXT: __imp_@fastcall@8 | ||
| 10 | # DECORATED-IMPLIB-NEXT: @fastcall@8 | ||
| 11 | # DECORATED-IMPLIB: Name type: name | ||
| 12 | # DECORATED-IMPLIB-NEXT: __imp__stdcall@8 | ||
| 13 | # DECORATED-IMPLIB-NEXT: _stdcall@8 | ||
| 14 | # DECORATED-IMPLIB: Name type: noprefix | ||
| 15 | # DECORATED-IMPLIB-NEXT: __imp___underscored | ||
| 16 | # DECORATED-IMPLIB-NEXT: __underscored | ||
| 17 | # DECORATED-IMPLIB: Name type: name | ||
| 18 | # DECORATED-IMPLIB-NEXT: __imp_vectorcall@@8 | ||
| 19 | # DECORATED-IMPLIB-NEXT: vectorcall@@8 | ||
| 20 | |||
| 21 | # DECORATED-EXPORTS: Name: @fastcall@8 | ||
| 22 | # DECORATED-EXPORTS: Name: _stdcall@8 | ||
| 23 | # DECORATED-EXPORTS: Name: _underscored | ||
| 24 | # DECORATED-EXPORTS: Name: vectorcall@@8 | ||
| 25 | |||
| 26 | .def _stdcall@8; | ||
| 27 | .scl 2; | ||
| 28 | .type 32; | ||
| 29 | .endef | ||
| 30 | .globl _stdcall@8 | ||
| 31 | .globl @fastcall@8 | ||
| 32 | .globl vectorcall@@8 | ||
| 33 | .globl __underscored | ||
| 34 | _stdcall@8: | ||
| 35 | movl 8(%esp), %eax | ||
| 36 | addl 4(%esp), %eax | ||
| 37 | retl $8 | ||
| 38 | @fastcall@8: | ||
| 39 | movl 8(%esp), %eax | ||
| 40 | addl 4(%esp), %eax | ||
| 41 | retl $8 | ||
| 42 | vectorcall@@8: | ||
| 43 | movl 8(%esp), %eax | ||
| 44 | addl 4(%esp), %eax | ||
| 45 | retl $8 | ||
| 46 | __underscored: | ||
| 47 | ret | ||
| 48 | |||
| 49 | .def _dllmain; | ||
| 50 | .scl 2; | ||
| 51 | .type 32; | ||
| 52 | .endef | ||
| 53 | .globl _dllmain | ||
| 54 | _dllmain: | ||
| 55 | retl | ||
| 56 | |||
| 57 | .section .drectve | ||
| 58 | .ascii "-export:__underscored -export:_stdcall@8 -export:@fastcall@8 -export:vectorcall@@8" | ||
deps/lld/test/COFF/driver.test+11| ... | @@ -4,3 +4,14 @@ MISSING: nosuchfile.obj: {{[Nn]}}o such file or directory | ... | @@ -4,3 +4,14 @@ MISSING: nosuchfile.obj: {{[Nn]}}o such file or directory |
| 4 | 4 | ||
| 5 | # RUN: lld-link --version | FileCheck -check-prefix=VERSION %s | 5 | # RUN: lld-link --version | FileCheck -check-prefix=VERSION %s |
| 6 | VERSION: {{LLD [0-9]+\.[0-9]+}} | 6 | VERSION: {{LLD [0-9]+\.[0-9]+}} |
| 7 | |||
| 8 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj | ||
| 9 | # RUN: lld-link /out:%t.dll /dll %t.obj | ||
| 10 | # RUN: not lld-link /out:%t.exe %t.dll 2>&1 | FileCheck -check-prefix=BADFILE %s | ||
| 11 | BADFILE: bad file type. Did you specify a DLL instead of an import library? | ||
| 12 | |||
| 13 | # RUN: lld-link /lib /help | FileCheck -check-prefix=LIBHELP %s | ||
| 14 | LIBHELP: OVERVIEW: LLVM Lib | ||
| 15 | |||
| 16 | # RUN: not lld-link /WX /lib 2>&1 | FileCheck -check-prefix=LIBBAD %s | ||
| 17 | LIBBAD: ignoring /lib since it's not the first argument |
deps/lld/test/COFF/duplicate.test+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o alpha.obj %S/Inputs/alpha.ll | 2 | RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o alpha.obj %S/Inputs/alpha.ll |
| 2 | RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o beta.obj %S/Inputs/beta.ll | 3 | RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o beta.obj %S/Inputs/beta.ll |
| 3 | RUN: lld-link /out:alpha.dll /dll alpha.obj /implib:alpha.lib | 4 | RUN: lld-link /out:alpha.dll /dll alpha.obj /implib:alpha.lib |
deps/lld/test/COFF/entry-inference3.test created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | # RUN: yaml2obj < %s > %t.obj | ||
| 2 | # RUN: not lld-link /out:%t.exe %t.obj /verbose /nodefaultlib > %t.log 2>&1 | ||
| 3 | # RUN: FileCheck %s < %t.log | ||
| 4 | |||
| 5 | # CHECK: Entry name inferred: mainCRTStartup | ||
| 6 | |||
| 7 | --- !COFF | ||
| 8 | header: | ||
| 9 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 10 | Characteristics: [] | ||
| 11 | sections: | ||
| 12 | - Name: .text | ||
| 13 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 14 | Alignment: 4 | ||
| 15 | SectionData: B82A000000C3 | ||
| 16 | symbols: | ||
| 17 | - Name: .text | ||
| 18 | Value: 0 | ||
| 19 | SectionNumber: 1 | ||
| 20 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 21 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 22 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 23 | SectionDefinition: | ||
| 24 | Length: 6 | ||
| 25 | NumberOfRelocations: 0 | ||
| 26 | NumberOfLinenumbers: 0 | ||
| 27 | CheckSum: 0 | ||
| 28 | Number: 0 | ||
| 29 | - Name: mainCRTStartup | ||
| 30 | Value: 0 | ||
| 31 | SectionNumber: 1 | ||
| 32 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 33 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 34 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 35 | ... | ||
deps/lld/test/COFF/error-limit.test+7-7| ... | @@ -3,27 +3,27 @@ RUN: 21 22 2>&1 | FileCheck -check-prefix=DEFAULT %s | ... | @@ -3,27 +3,27 @@ RUN: 21 22 2>&1 | FileCheck -check-prefix=DEFAULT %s |
| 3 | 3 | ||
| 4 | DEFAULT: could not open 01 | 4 | DEFAULT: could not open 01 |
| 5 | DEFAULT: could not open 20 | 5 | DEFAULT: could not open 20 |
| 6 | DEFAULT-NEXT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors) | 6 | DEFAULT-NEXT: too many errors emitted, stopping now (use /errorlimit:0 to see all errors) |
| 7 | DEFAULT-NOT: could not open 21 | 7 | DEFAULT-NOT: could not open 21 |
| 8 | 8 | ||
| 9 | RUN: not lld-link /ERRORLIMIT:5 01 02 03 04 05 06 07 08 09 10 2>&1 \ | 9 | RUN: not lld-link /errorlimit:5 01 02 03 04 05 06 07 08 09 10 2>&1 \ |
| 10 | RUN: | FileCheck -check-prefix=LIMIT5 %s | 10 | RUN: | FileCheck -check-prefix=LIMIT5 %s |
| 11 | 11 | ||
| 12 | LIMIT5: could not open 01 | 12 | LIMIT5: could not open 01 |
| 13 | LIMIT5: could not open 05 | 13 | LIMIT5: could not open 05 |
| 14 | LIMIT5-NEXT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors) | 14 | LIMIT5-NEXT: too many errors emitted, stopping now (use /errorlimit:0 to see all errors) |
| 15 | LIMIT5-NOT: could not open 06 | 15 | LIMIT5-NOT: could not open 06 |
| 16 | 16 | ||
| 17 | RUN: not lld-link /ERRORLIMIT:0 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \ | 17 | RUN: not lld-link /errorlimit:0 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \ |
| 18 | RUN: 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=UNLIMITED %s | 18 | RUN: 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=UNLIMITED %s |
| 19 | 19 | ||
| 20 | UNLIMITED: could not open 01 | 20 | UNLIMITED: could not open 01 |
| 21 | UNLIMITED: could not open 20 | 21 | UNLIMITED: could not open 20 |
| 22 | UNLIMITED: could not open 21 | 22 | UNLIMITED: could not open 21 |
| 23 | UNLIMITED: could not open 22 | 23 | UNLIMITED: could not open 22 |
| 24 | UNLIMITED-NOT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors) | 24 | UNLIMITED-NOT: too many errors emitted, stopping now (use /errorlimit:0 to see all errors) |
| 25 | 25 | ||
| 26 | RUN: not lld-link /ERRORLIMIT:XYZ 01 02 03 04 05 06 07 08 09 10 11 12 13 14 \ | 26 | RUN: not lld-link /errorlimit:XYZ 01 02 03 04 05 06 07 08 09 10 11 12 13 14 \ |
| 27 | RUN: 15 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=WRONG %s | 27 | RUN: 15 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=WRONG %s |
| 28 | 28 | ||
| 29 | WRONG: /ERRORLIMIT: number expected, but got XYZ | 29 | WRONG: /errorlimit: number expected, but got XYZ |
deps/lld/test/COFF/export-all.s+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # REQEUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj | 3 | # RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj |
| 4 | 4 |
deps/lld/test/COFF/export-armnt.yaml+4-4| ... | @@ -9,10 +9,10 @@ | ... | @@ -9,10 +9,10 @@ |
| 9 | # CHECK: DLL name: export-armnt.yaml.tmp.dll | 9 | # CHECK: DLL name: export-armnt.yaml.tmp.dll |
| 10 | # CHECK: Ordinal RVA Name | 10 | # CHECK: Ordinal RVA Name |
| 11 | # CHECK-NEXT: 0 0 | 11 | # CHECK-NEXT: 0 0 |
| 12 | # CHECK-NEXT: 1 0x1000 exportdata | 12 | # CHECK-NEXT: 1 0x3000 exportdata |
| 13 | # CHECK-NEXT: 2 0x2005 exportfn1 | 13 | # CHECK-NEXT: 2 0x1005 exportfn1 |
| 14 | # CHECK-NEXT: 3 0x2009 exportfn2 | 14 | # CHECK-NEXT: 3 0x1009 exportfn2 |
| 15 | # CHECK-NEXT: 4 0x2009 exportfn3 | 15 | # CHECK-NEXT: 4 0x1009 exportfn3 |
| 16 | 16 | ||
| 17 | --- !COFF | 17 | --- !COFF |
| 18 | header: | 18 | header: |
deps/lld/test/COFF/export.test+4| ... | @@ -86,6 +86,10 @@ SYMTAB: exportfn3 in export.test.tmp.DLL | ... | @@ -86,6 +86,10 @@ SYMTAB: exportfn3 in export.test.tmp.DLL |
| 86 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:foo=kernel32.foobar | 86 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:foo=kernel32.foobar |
| 87 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=FORWARDER %s | 87 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=FORWARDER %s |
| 88 | 88 | ||
| 89 | # RUN: echo "EXPORTS foo=kernel32.foobar" > %t.def | ||
| 90 | # RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def | ||
| 91 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=FORWARDER %s | ||
| 92 | |||
| 89 | FORWARDER: Export Table: | 93 | FORWARDER: Export Table: |
| 90 | FORWARDER: DLL name: export.test.tmp.dll | 94 | FORWARDER: DLL name: export.test.tmp.dll |
| 91 | FORWARDER: Ordinal base: 0 | 95 | FORWARDER: Ordinal base: 0 |
deps/lld/test/COFF/export32.test+10| ... | @@ -2,6 +2,10 @@ | ... | @@ -2,6 +2,10 @@ |
| 2 | # | 2 | # |
| 3 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 | 3 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 |
| 4 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s | 4 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s |
| 5 | # | ||
| 6 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 /merge:.edata=.rdata | ||
| 7 | # 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 | ||
| 5 | 9 | ||
| 6 | # CHECK1: Export Table: | 10 | # CHECK1: Export Table: |
| 7 | # CHECK1: DLL name: export32.test.tmp.dll | 11 | # CHECK1: DLL name: export32.test.tmp.dll |
| ... | @@ -10,6 +14,12 @@ | ... | @@ -10,6 +14,12 @@ |
| 10 | # CHECK1-NEXT: 1 0x1008 exportfn1 | 14 | # CHECK1-NEXT: 1 0x1008 exportfn1 |
| 11 | # CHECK1-NEXT: 2 0x1010 exportfn2 | 15 | # CHECK1-NEXT: 2 0x1010 exportfn2 |
| 12 | 16 | ||
| 17 | # HEADER-MERGE: ExportTableRVA: 0x2000 | ||
| 18 | # HEADER-MERGE-NEXT: ExportTableSize: 0x7E | ||
| 19 | # HEADER-MERGE: Name: .rdata | ||
| 20 | # HEADER-MERGE-NEXT: VirtualSize: 0x7E | ||
| 21 | # HEADER-MERGE-NEXT: VirtualAddress: 0x2000 | ||
| 22 | |||
| 13 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5 \ | 23 | # RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5 \ |
| 14 | # RUN: /export:exportfn2 /export:mangled | 24 | # RUN: /export:exportfn2 /export:mangled |
| 15 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s | 25 | # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s |
deps/lld/test/COFF/filename-casing.s+4-2| ... | @@ -6,8 +6,10 @@ | ... | @@ -6,8 +6,10 @@ |
| 6 | # RUN: llvm-lib /out:%T/MixedCase.lib %T/MixedCase.obj | 6 | # RUN: llvm-lib /out:%T/MixedCase.lib %T/MixedCase.obj |
| 7 | # RUN: not lld-link /machine:x64 /entry:main %T/MixedCase.lib 2>&1 | FileCheck -check-prefix=ARCHIVE %s | 7 | # RUN: not lld-link /machine:x64 /entry:main %T/MixedCase.lib 2>&1 | FileCheck -check-prefix=ARCHIVE %s |
| 8 | 8 | ||
| 9 | # OBJECT: MixedCase.obj: undefined symbol: f | 9 | # OBJECT: undefined symbol: f |
| 10 | # ARCHIVE: MixedCase.lib(MixedCase.obj): undefined symbol: f | 10 | # OBJECT-NEXT: >>> referenced by {{.*}}MixedCase.obj:(main) |
| 11 | # ARCHIVE: undefined symbol: f | ||
| 12 | # ARCHIVE-NEXT: >>> referenced by {{.*}}MixedCase.lib(MixedCase.obj):(main) | ||
| 11 | 13 | ||
| 12 | .globl main | 14 | .globl main |
| 13 | main: | 15 | main: |
deps/lld/test/COFF/fixed.test created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj | ||
| 3 | # | ||
| 4 | # RUN: lld-link %t.obj /fixed %p/Inputs/std32.lib /subsystem:console \ | ||
| 5 | # RUN: /entry:main@0 /debug /out:%t.fixed.exe | ||
| 6 | # RUN: llvm-readobj -file-headers %t.fixed.exe | \ | ||
| 7 | # RUN: FileCheck -check-prefix=EXEFIXED %s | ||
| 8 | # | ||
| 9 | # RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \ | ||
| 10 | # RUN: /entry:main@0 /debug /out:%t.exe | ||
| 11 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=EXEREL %s | ||
| 12 | # | ||
| 13 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj | ||
| 14 | # | ||
| 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 | ||
| 17 | # | ||
| 18 | # RUN: lld-link %t.obj /dll /debug /out:%t.dll | ||
| 19 | # RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=DLLREL %s | ||
| 20 | |||
| 21 | EXEFIXED-NOT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | ||
| 22 | DLLFIXED-NOT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | ||
| 23 | EXEREL: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | ||
| 24 | DLLREL: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE | ||
deps/lld/test/COFF/force.test+4-2| ... | @@ -4,8 +4,10 @@ | ... | @@ -4,8 +4,10 @@ |
| 4 | # RUN: lld-link /out:%t.exe /entry:main %t.obj /force >& %t.log | 4 | # RUN: lld-link /out:%t.exe /entry:main %t.obj /force >& %t.log |
| 5 | # RUN: FileCheck -check-prefix=WARN %s < %t.log | 5 | # RUN: FileCheck -check-prefix=WARN %s < %t.log |
| 6 | 6 | ||
| 7 | # ERROR: error: {{.*}}.obj: undefined symbol: foo | 7 | # ERROR: error: undefined symbol: foo |
| 8 | # WARN: warning: {{.*}}.obj: undefined symbol: foo | 8 | # ERROR-NEXT: >>> referenced by {{.*}}.obj |
| 9 | # WARN: warning: undefined symbol: foo | ||
| 10 | # WARN-NEXT: >>> referenced by {{.*}}.obj | ||
| 9 | 11 | ||
| 10 | --- !COFF | 12 | --- !COFF |
| 11 | header: | 13 | header: |
deps/lld/test/COFF/gfids-corrupt.s created+84| ... | @@ -0,0 +1,84 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj | ||
| 3 | # 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 | ||
| 5 | |||
| 6 | # ERRS: warning: ignoring .gfids$y symbol table index section in object {{.*}}gfids-corrupt{{.*}} | ||
| 7 | # ERRS: warning: ignoring invalid symbol table index in section .gfids$y in object {{.*}}gfids-corrupt{{.*}} | ||
| 8 | |||
| 9 | # The table is arbitrary, really. | ||
| 10 | # CHECK: ImageBase: 0x140000000 | ||
| 11 | # CHECK: LoadConfig [ | ||
| 12 | # CHECK: SEHandlerTable: 0x0 | ||
| 13 | # CHECK: SEHandlerCount: 0 | ||
| 14 | # CHECK: GuardCFCheckFunction: 0x0 | ||
| 15 | # CHECK: GuardCFCheckDispatch: 0x0 | ||
| 16 | # CHECK: GuardCFFunctionTable: 0x14000{{.*}} | ||
| 17 | # CHECK: GuardCFFunctionCount: 2 | ||
| 18 | # CHECK: GuardFlags: 0x500 | ||
| 19 | # CHECK: GuardAddressTakenIatEntryTable: 0x0 | ||
| 20 | # CHECK: GuardAddressTakenIatEntryCount: 0 | ||
| 21 | # CHECK: GuardLongJumpTargetTable: 0x0 | ||
| 22 | # CHECK: GuardLongJumpTargetCount: 0 | ||
| 23 | # CHECK: ] | ||
| 24 | # CHECK: GuardFidTable [ | ||
| 25 | # CHECK-NEXT: 0x14000{{.*}} | ||
| 26 | # CHECK-NEXT: 0x14000{{.*}} | ||
| 27 | # CHECK-NEXT: ] | ||
| 28 | |||
| 29 | |||
| 30 | # Indicate that gfids are present. | ||
| 31 | .def @feat.00; .scl 3; .type 0; .endef | ||
| 32 | .globl @feat.00 | ||
| 33 | @feat.00 = 0x800 | ||
| 34 | |||
| 35 | .def f1; .scl 2; .type 32; .endef | ||
| 36 | .section .text,"xr",one_only,f1 | ||
| 37 | .global f1 | ||
| 38 | f1: | ||
| 39 | movl $42, %eax | ||
| 40 | retq | ||
| 41 | |||
| 42 | .def f2; .scl 2; .type 32; .endef | ||
| 43 | .section .text,"xr",one_only,f2 | ||
| 44 | .global f2 | ||
| 45 | f2: | ||
| 46 | movl $13, %eax | ||
| 47 | retq | ||
| 48 | |||
| 49 | .section .data,"dw",one_only,fp1 | ||
| 50 | .globl fp1 | ||
| 51 | fp1: | ||
| 52 | .quad f1 | ||
| 53 | |||
| 54 | .section .data,"dw",one_only,fp2 | ||
| 55 | .globl fp2 | ||
| 56 | fp2: | ||
| 57 | .quad f2 | ||
| 58 | |||
| 59 | .section .gfids$y,"dr",associative,fp1 | ||
| 60 | .symidx f1 | ||
| 61 | .byte 0 | ||
| 62 | |||
| 63 | .section .gfids$y,"dr",associative,fp2 | ||
| 64 | .symidx f2 | ||
| 65 | .long 0x400 | ||
| 66 | |||
| 67 | .def main; .scl 2; .type 32; .endef | ||
| 68 | .section .text,"xr",one_only,main | ||
| 69 | .globl main | ||
| 70 | main: | ||
| 71 | callq *fp1(%rip) | ||
| 72 | callq *fp2(%rip) | ||
| 73 | xor %eax, %eax | ||
| 74 | retq | ||
| 75 | |||
| 76 | .section .rdata,"dr" | ||
| 77 | .globl _load_config_used | ||
| 78 | _load_config_used: | ||
| 79 | .long 256 | ||
| 80 | .fill 124, 1, 0 | ||
| 81 | .quad __guard_fids_table | ||
| 82 | .quad __guard_fids_count | ||
| 83 | .long __guard_flags | ||
| 84 | .fill 128, 1, 0 | ||
deps/lld/test/COFF/gfids-fallback.s created+97| ... | @@ -0,0 +1,97 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: grep -B99999 [S]PLITMARKER %s | llvm-mc -triple x86_64-windows-msvc -filetype=obj -o %t1.obj | ||
| 3 | # RUN: grep -A99999 [S]PLITMARKER %s | llvm-mc -triple x86_64-windows-msvc -filetype=obj -o %t2.obj | ||
| 4 | # 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 | ||
| 6 | |||
| 7 | # CHECK: ImageBase: 0x140000000 | ||
| 8 | # CHECK: LoadConfig [ | ||
| 9 | # CHECK: SEHandlerTable: 0x0 | ||
| 10 | # CHECK: SEHandlerCount: 0 | ||
| 11 | # CHECK: GuardCFCheckFunction: 0x0 | ||
| 12 | # CHECK: GuardCFCheckDispatch: 0x0 | ||
| 13 | # CHECK: GuardCFFunctionTable: 0x14000{{.*}} | ||
| 14 | # CHECK: GuardCFFunctionCount: 3 | ||
| 15 | # CHECK: GuardFlags: 0x500 | ||
| 16 | # CHECK: GuardAddressTakenIatEntryTable: 0x0 | ||
| 17 | # CHECK: GuardAddressTakenIatEntryCount: 0 | ||
| 18 | # CHECK: GuardLongJumpTargetTable: 0x0 | ||
| 19 | # CHECK: GuardLongJumpTargetCount: 0 | ||
| 20 | # CHECK: ] | ||
| 21 | # CHECK: GuardFidTable [ | ||
| 22 | # CHECK-NEXT: 0x14000{{.*}} | ||
| 23 | # CHECK-NEXT: 0x14000{{.*}} | ||
| 24 | # CHECK-NEXT: 0x14000{{.*}} | ||
| 25 | # CHECK-NEXT: ] | ||
| 26 | |||
| 27 | |||
| 28 | # Indicate that no gfids are present. All symbols used by relocations in this | ||
| 29 | # file will be considered address-taken. | ||
| 30 | .def @feat.00; .scl 3; .type 0; .endef | ||
| 31 | .globl @feat.00 | ||
| 32 | @feat.00 = 0 | ||
| 33 | |||
| 34 | .def main; .scl 2; .type 32; .endef | ||
| 35 | .section .text,"xr",one_only,main | ||
| 36 | .globl main | ||
| 37 | main: | ||
| 38 | subq $8, %rsp | ||
| 39 | leaq foo(%rip), %rdx | ||
| 40 | callq bar | ||
| 41 | movl $0, %eax | ||
| 42 | addq $8, %rsp | ||
| 43 | retq | ||
| 44 | |||
| 45 | # Should not appear in gfids table. | ||
| 46 | .def baz; .scl 2; .type 32; .endef | ||
| 47 | .section .text,"xr",one_only,baz | ||
| 48 | .globl baz | ||
| 49 | baz: | ||
| 50 | mov $1, %eax | ||
| 51 | retq | ||
| 52 | |||
| 53 | .def qux; .scl 2; .type 32; .endef | ||
| 54 | .section .text,"xr",one_only,qux | ||
| 55 | .globl qux | ||
| 56 | qux: | ||
| 57 | mov $2, %eax | ||
| 58 | retq | ||
| 59 | |||
| 60 | .def quxx; .scl 2; .type 32; .endef | ||
| 61 | .section .text,"xr",one_only,quxx | ||
| 62 | .globl quxx | ||
| 63 | quxx: | ||
| 64 | mov $3, %eax | ||
| 65 | retq | ||
| 66 | |||
| 67 | # Load config. | ||
| 68 | .section .rdata,"dr" | ||
| 69 | .globl _load_config_used | ||
| 70 | _load_config_used: | ||
| 71 | .long 256 | ||
| 72 | .fill 124, 1, 0 | ||
| 73 | .quad __guard_fids_table | ||
| 74 | .quad __guard_fids_count | ||
| 75 | .long __guard_flags | ||
| 76 | .fill 128, 1, 0 | ||
| 77 | |||
| 78 | # SPLITMARKER | ||
| 79 | |||
| 80 | # Indicate that gfids are present. This file does not take any addresses. | ||
| 81 | .def @feat.00; .scl 3; .type 0; .endef | ||
| 82 | .globl @feat.00 | ||
| 83 | @feat.00 = 0x800 | ||
| 84 | |||
| 85 | .def foo; .scl 2; .type 32; .endef | ||
| 86 | .section .text,"xr",one_only,foo | ||
| 87 | .global foo | ||
| 88 | foo: | ||
| 89 | movl $42, %eax | ||
| 90 | retq | ||
| 91 | |||
| 92 | .def bar; .scl 2; .type 32; .endef | ||
| 93 | .section .text,"xr",one_only,bar | ||
| 94 | .global bar | ||
| 95 | bar: | ||
| 96 | movl $13, %eax | ||
| 97 | retq | ||
deps/lld/test/COFF/gfids-gc.s created+131| ... | @@ -0,0 +1,131 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj | ||
| 3 | # 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 | ||
| 5 | # 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 | ||
| 7 | # 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 | ||
| 9 | |||
| 10 | # This assembly is meant to mimic what CL emits for this kind of C code when | ||
| 11 | # /Gw (-fdata-sections) is enabled: | ||
| 12 | # int f() { return 42; } | ||
| 13 | # int g() { return 13; } | ||
| 14 | # int (*fp1)() = &f; | ||
| 15 | # int (*fp2)() = &g; | ||
| 16 | # int main() { | ||
| 17 | # return fp1(); | ||
| 18 | # } | ||
| 19 | # Compile with 'cl -c -guard:cf -Gw -O1' and note the two associative .gfids$y | ||
| 20 | # sections. | ||
| 21 | |||
| 22 | # Expect 3 entries: main, f, and g. | ||
| 23 | |||
| 24 | # CHECK-NOGC: ImageBase: 0x140000000 | ||
| 25 | # CHECK-NOGC: LoadConfig [ | ||
| 26 | # CHECK-NOGC: SEHandlerTable: 0x0 | ||
| 27 | # CHECK-NOGC: SEHandlerCount: 0 | ||
| 28 | # CHECK-NOGC: GuardCFCheckFunction: 0x0 | ||
| 29 | # CHECK-NOGC: GuardCFCheckDispatch: 0x0 | ||
| 30 | # CHECK-NOGC: GuardCFFunctionTable: 0x14000{{.*}} | ||
| 31 | # CHECK-NOGC: GuardCFFunctionCount: 3 | ||
| 32 | # CHECK-NOGC: GuardFlags: 0x500 | ||
| 33 | # CHECK-NOGC: GuardAddressTakenIatEntryTable: 0x0 | ||
| 34 | # CHECK-NOGC: GuardAddressTakenIatEntryCount: 0 | ||
| 35 | # CHECK-NOGC: GuardLongJumpTargetTable: 0x0 | ||
| 36 | # CHECK-NOGC: GuardLongJumpTargetCount: 0 | ||
| 37 | # CHECK-NOGC: ] | ||
| 38 | # CHECK-NOGC: GuardFidTable [ | ||
| 39 | # CHECK-NOGC-NEXT: 0x14000{{.*}} | ||
| 40 | # CHECK-NOGC-NEXT: 0x14000{{.*}} | ||
| 41 | # CHECK-NOGC-NEXT: 0x14000{{.*}} | ||
| 42 | # CHECK-NOGC-NEXT: ] | ||
| 43 | |||
| 44 | # Expect 2 entries: main and f. fp2 was discarded, so g was only used as a | ||
| 45 | # direct call target. | ||
| 46 | |||
| 47 | # CHECK-GC: ImageBase: 0x140000000 | ||
| 48 | # CHECK-GC: LoadConfig [ | ||
| 49 | # CHECK-GC: SEHandlerTable: 0x0 | ||
| 50 | # CHECK-GC: SEHandlerCount: 0 | ||
| 51 | # CHECK-GC: GuardCFCheckFunction: 0x0 | ||
| 52 | # CHECK-GC: GuardCFCheckDispatch: 0x0 | ||
| 53 | # CHECK-GC: GuardCFFunctionTable: 0x14000{{.*}} | ||
| 54 | # CHECK-GC: GuardCFFunctionCount: 2 | ||
| 55 | # CHECK-GC: GuardFlags: 0x500 | ||
| 56 | # CHECK-GC: GuardAddressTakenIatEntryTable: 0x0 | ||
| 57 | # CHECK-GC: GuardAddressTakenIatEntryCount: 0 | ||
| 58 | # CHECK-GC: GuardLongJumpTargetTable: 0x0 | ||
| 59 | # CHECK-GC: GuardLongJumpTargetCount: 0 | ||
| 60 | # CHECK-GC: ] | ||
| 61 | # CHECK-GC: GuardFidTable [ | ||
| 62 | # CHECK-GC-NEXT: 0x14000{{.*}} | ||
| 63 | # CHECK-GC-NEXT: 0x14000{{.*}} | ||
| 64 | # CHECK-GC-NEXT: ] | ||
| 65 | |||
| 66 | |||
| 67 | # We need @feat.00 to have 0x800 to indicate .gfids are present. | ||
| 68 | .def @feat.00; | ||
| 69 | .scl 3; | ||
| 70 | .type 0; | ||
| 71 | .endef | ||
| 72 | .globl @feat.00 | ||
| 73 | @feat.00 = 0x801 | ||
| 74 | |||
| 75 | .def main; | ||
| 76 | .scl 2; | ||
| 77 | .type 32; | ||
| 78 | .endef | ||
| 79 | .section .text,"xr",one_only,main | ||
| 80 | .globl main | ||
| 81 | main: | ||
| 82 | # Call g directly so that it is not dead stripped. | ||
| 83 | callq g | ||
| 84 | rex64 jmpq *fp1(%rip) | ||
| 85 | |||
| 86 | .def f; | ||
| 87 | .scl 3; | ||
| 88 | .type 32; | ||
| 89 | .endef | ||
| 90 | .section .text,"xr",one_only,f | ||
| 91 | f: | ||
| 92 | movl $42, %eax | ||
| 93 | retq | ||
| 94 | |||
| 95 | .section .data,"dw",one_only,fp1 | ||
| 96 | .globl fp1 | ||
| 97 | fp1: | ||
| 98 | .quad f | ||
| 99 | |||
| 100 | .section .gfids$y,"dr",associative,fp1 | ||
| 101 | .symidx f | ||
| 102 | |||
| 103 | # Section GC will remove the following, so 'g' should not be present in the | ||
| 104 | # guard fid table. | ||
| 105 | |||
| 106 | .def g; | ||
| 107 | .scl 3; | ||
| 108 | .type 32; | ||
| 109 | .endef | ||
| 110 | .section .text,"xr",one_only,g | ||
| 111 | g: | ||
| 112 | movl $13, %eax | ||
| 113 | retq | ||
| 114 | |||
| 115 | .section .data,"dw",one_only,fp2 | ||
| 116 | .globl fp2 | ||
| 117 | fp2: | ||
| 118 | .quad g | ||
| 119 | |||
| 120 | .section .gfids$y,"dr",associative,fp2 | ||
| 121 | .symidx g | ||
| 122 | |||
| 123 | .section .rdata,"dr" | ||
| 124 | .globl _load_config_used | ||
| 125 | _load_config_used: | ||
| 126 | .long 256 | ||
| 127 | .fill 124, 1, 0 | ||
| 128 | .quad __guard_fids_table | ||
| 129 | .quad __guard_fids_count | ||
| 130 | .long __guard_flags | ||
| 131 | .fill 128, 1, 0 | ||
deps/lld/test/COFF/gfids-icf.s created+88| ... | @@ -0,0 +1,88 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj | ||
| 3 | # 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 | ||
| 5 | |||
| 6 | # This assembly is meant to mimic what CL emits for this kind of C code: | ||
| 7 | # int icf1() { return 42; } | ||
| 8 | # int icf2() { return 42; } | ||
| 9 | # int (*fp1)() = &icf1; | ||
| 10 | # int (*fp2)() = &icf2; | ||
| 11 | # int main() { | ||
| 12 | # return fp1(); | ||
| 13 | # return fp2(); | ||
| 14 | # } | ||
| 15 | |||
| 16 | # 'icf1' and 'icf2' are address taken, but should be merged into one entry. | ||
| 17 | # There are two entries in the table because 'main' is included. | ||
| 18 | |||
| 19 | # CHECK: ImageBase: 0x140000000 | ||
| 20 | # CHECK: LoadConfig [ | ||
| 21 | # CHECK: SEHandlerTable: 0x0 | ||
| 22 | # CHECK: SEHandlerCount: 0 | ||
| 23 | # CHECK: GuardCFCheckFunction: 0x0 | ||
| 24 | # CHECK: GuardCFCheckDispatch: 0x0 | ||
| 25 | # CHECK: GuardCFFunctionTable: 0x14000{{.*}} | ||
| 26 | # CHECK: GuardCFFunctionCount: 2 | ||
| 27 | # CHECK: GuardFlags: 0x500 | ||
| 28 | # CHECK: GuardAddressTakenIatEntryTable: 0x0 | ||
| 29 | # CHECK: GuardAddressTakenIatEntryCount: 0 | ||
| 30 | # CHECK: GuardLongJumpTargetTable: 0x0 | ||
| 31 | # CHECK: GuardLongJumpTargetCount: 0 | ||
| 32 | # CHECK: ] | ||
| 33 | # CHECK: GuardFidTable [ | ||
| 34 | # CHECK-NEXT: 0x14000{{.*}} | ||
| 35 | # CHECK-NEXT: 0x14000{{.*}} | ||
| 36 | # CHECK-NEXT: ] | ||
| 37 | |||
| 38 | |||
| 39 | # Indicate that gfids are present. | ||
| 40 | .def @feat.00; .scl 3; .type 0; .endef | ||
| 41 | .globl @feat.00 | ||
| 42 | @feat.00 = 0x800 | ||
| 43 | |||
| 44 | .def icf1; .scl 2; .type 32; .endef | ||
| 45 | .section .text,"xr",one_only,icf1 | ||
| 46 | .global icf1 | ||
| 47 | icf1: | ||
| 48 | movl $42, %eax | ||
| 49 | retq | ||
| 50 | |||
| 51 | .def icf2; .scl 2; .type 32; .endef | ||
| 52 | .section .text,"xr",one_only,icf2 | ||
| 53 | .global icf2 | ||
| 54 | icf2: | ||
| 55 | movl $42, %eax | ||
| 56 | retq | ||
| 57 | |||
| 58 | # Take their two addresses. | ||
| 59 | .data | ||
| 60 | .globl fp1 | ||
| 61 | fp1: | ||
| 62 | .quad icf1 | ||
| 63 | .globl fp2 | ||
| 64 | fp2: | ||
| 65 | .quad icf2 | ||
| 66 | |||
| 67 | .section .gfids$y,"dr" | ||
| 68 | .symidx icf1 | ||
| 69 | .symidx icf2 | ||
| 70 | |||
| 71 | .def main; .scl 2; .type 32; .endef | ||
| 72 | .section .text,"xr",one_only,main | ||
| 73 | .globl main | ||
| 74 | main: | ||
| 75 | callq *fp1(%rip) | ||
| 76 | callq *fp2(%rip) | ||
| 77 | xor %eax, %eax | ||
| 78 | retq | ||
| 79 | |||
| 80 | .section .rdata,"dr" | ||
| 81 | .globl _load_config_used | ||
| 82 | _load_config_used: | ||
| 83 | .long 256 | ||
| 84 | .fill 124, 1, 0 | ||
| 85 | .quad __guard_fids_table | ||
| 86 | .quad __guard_fids_count | ||
| 87 | .long __guard_flags | ||
| 88 | .fill 128, 1, 0 | ||
deps/lld/test/COFF/guard-longjmp.s created+104| ... | @@ -0,0 +1,104 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj | ||
| 3 | # 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 | ||
| 5 | |||
| 6 | # CHECK: ImageBase: 0x140000000 | ||
| 7 | # CHECK: LoadConfig [ | ||
| 8 | # CHECK: SEHandlerTable: 0x0 | ||
| 9 | # CHECK: SEHandlerCount: 0 | ||
| 10 | # CHECK: GuardCFCheckFunction: 0x0 | ||
| 11 | # CHECK: GuardCFCheckDispatch: 0x0 | ||
| 12 | # CHECK: GuardCFFunctionTable: 0x14000{{.*}} | ||
| 13 | # CHECK: GuardCFFunctionCount: 1 | ||
| 14 | # CHECK: GuardFlags: 0x10500 | ||
| 15 | # CHECK: GuardAddressTakenIatEntryTable: 0x0 | ||
| 16 | # CHECK: GuardAddressTakenIatEntryCount: 0 | ||
| 17 | # CHECK: GuardLongJumpTargetTable: 0x14000{{.*}} | ||
| 18 | # CHECK: GuardLongJumpTargetCount: 1 | ||
| 19 | # CHECK: ] | ||
| 20 | # CHECK: GuardLJmpTable [ | ||
| 21 | # CHECK-NEXT: 0x14000{{.*}} | ||
| 22 | # CHECK-NEXT: ] | ||
| 23 | |||
| 24 | |||
| 25 | # This assembly is reduced from C code like: | ||
| 26 | # #include <setjmp.h> | ||
| 27 | # jmp_buf buf; | ||
| 28 | # void g() { longjmp(buf, 1); } | ||
| 29 | # void f() { | ||
| 30 | # if (setjmp(buf)) | ||
| 31 | # return; | ||
| 32 | # g(); | ||
| 33 | # } | ||
| 34 | # int main() { f(); } | ||
| 35 | |||
| 36 | # We need @feat.00 to have 0x800 to indicate /guard:cf. | ||
| 37 | .def @feat.00; | ||
| 38 | .scl 3; | ||
| 39 | .type 0; | ||
| 40 | .endef | ||
| 41 | .globl @feat.00 | ||
| 42 | @feat.00 = 0x801 | ||
| 43 | .def f; .scl 2; .type 32; .endef | ||
| 44 | .globl f | ||
| 45 | f: | ||
| 46 | pushq %rbp | ||
| 47 | subq $32, %rsp | ||
| 48 | leaq 32(%rsp), %rbp | ||
| 49 | leaq buf(%rip), %rcx | ||
| 50 | leaq -32(%rbp), %rdx | ||
| 51 | callq _setjmp | ||
| 52 | .Lljmp1: | ||
| 53 | testl %eax, %eax | ||
| 54 | je .LBB1_1 | ||
| 55 | addq $32, %rsp | ||
| 56 | popq %rbp | ||
| 57 | retq | ||
| 58 | .LBB1_1: # %if.end | ||
| 59 | leaq buf(%rip), %rcx | ||
| 60 | movl $1, %edx | ||
| 61 | callq longjmp | ||
| 62 | ud2 | ||
| 63 | |||
| 64 | # Record the longjmp target. | ||
| 65 | .section .gljmp$y,"dr" | ||
| 66 | .symidx .Lljmp1 | ||
| 67 | .text | ||
| 68 | |||
| 69 | # Provide setjmp/longjmp stubs. | ||
| 70 | .def _setjmp; .scl 2; .type 32; .endef | ||
| 71 | .globl _setjmp | ||
| 72 | _setjmp: | ||
| 73 | retq | ||
| 74 | |||
| 75 | .def longjmp; .scl 2; .type 32; .endef | ||
| 76 | .globl longjmp | ||
| 77 | longjmp: | ||
| 78 | retq | ||
| 79 | |||
| 80 | .def main; .scl 2; .type 32; .endef | ||
| 81 | .globl main # -- Begin function main | ||
| 82 | main: # @main | ||
| 83 | subq $40, %rsp | ||
| 84 | callq f | ||
| 85 | xorl %eax, %eax | ||
| 86 | addq $40, %rsp | ||
| 87 | retq | ||
| 88 | |||
| 89 | .comm buf,256,4 # @buf | ||
| 90 | |||
| 91 | .section .rdata,"dr" | ||
| 92 | .globl _load_config_used | ||
| 93 | _load_config_used: | ||
| 94 | .long 256 | ||
| 95 | .fill 124, 1, 0 | ||
| 96 | .quad __guard_fids_table | ||
| 97 | .quad __guard_fids_count | ||
| 98 | .long __guard_flags | ||
| 99 | .fill 12, 1, 0 | ||
| 100 | .quad __guard_iat_table | ||
| 101 | .quad __guard_iat_count | ||
| 102 | .quad __guard_longjmp_table | ||
| 103 | .quad __guard_fids_count | ||
| 104 | .fill 84, 1, 0 | ||
deps/lld/test/COFF/guardcf-align.s created+45| ... | @@ -0,0 +1,45 @@ | ||
| 1 | # RUN: llvm-mc -triple x86_64-windows-msvc -filetype=obj -o %t.obj %s | ||
| 2 | # RUN: yaml2obj < %p/Inputs/guardcf-align-foobar.yaml \ | ||
| 3 | # RUN: > %T/guardcf-align-foobar.obj | ||
| 4 | # RUN: lld-link -out:%T/guardcf-align.exe -entry:main -guard:cf \ | ||
| 5 | # RUN: %t.obj %T/guardcf-align-foobar.obj | ||
| 6 | # RUN: llvm-readobj -coff-load-config %T/guardcf-align.exe | FileCheck %s | ||
| 7 | |||
| 8 | # Check that the gfids table contains at least one entry that ends in 0 | ||
| 9 | # and no entries that end in something other than 0. | ||
| 10 | # CHECK: GuardFidTable [ | ||
| 11 | # CHECK-NOT: 0x{{[0-9A-Fa-f]+[^0]$}} | ||
| 12 | # CHECK: 0x{{[0-9A-Fa-f]+0$}} | ||
| 13 | # CHECK-NOT: 0x{{[0-9A-Fa-f]+[^0]$}} | ||
| 14 | # CHECK: ] | ||
| 15 | |||
| 16 | # @feat.00 and _load_config_used to indicate we have gfids. | ||
| 17 | .def @feat.00; | ||
| 18 | .scl 3; | ||
| 19 | .type 0; | ||
| 20 | .endef | ||
| 21 | .globl @feat.00 | ||
| 22 | @feat.00 = 0x801 | ||
| 23 | |||
| 24 | .section .rdata,"dr" | ||
| 25 | .globl _load_config_used | ||
| 26 | _load_config_used: | ||
| 27 | .long 256 | ||
| 28 | .fill 124, 1, 0 | ||
| 29 | .quad __guard_fids_table | ||
| 30 | .quad __guard_fids_count | ||
| 31 | .long __guard_flags | ||
| 32 | .fill 128, 1, 0 | ||
| 33 | |||
| 34 | # Functions that are called indirectly. | ||
| 35 | .section .gfids$y,"dr" | ||
| 36 | .symidx foo | ||
| 37 | |||
| 38 | |||
| 39 | .section .text,"rx" | ||
| 40 | .global main | ||
| 41 | main: | ||
| 42 | movq foo, %rcx | ||
| 43 | xorq %rax, %rax | ||
| 44 | callq bar | ||
| 45 | retq | ||
deps/lld/test/COFF/guardcf-lto.ll created+40| ... | @@ -0,0 +1,40 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; Set up an import library for a DLL that will do the indirect call. | ||
| 3 | ; RUN: echo -e 'LIBRARY library\nEXPORTS\n do_indirect_call\n' > %t.def | ||
| 4 | ; RUN: lld-link -lib -def:%t.def -out:%t.lib -machine:x64 | ||
| 5 | |||
| 6 | ; Generate an object that will have the load configuration normally provided by | ||
| 7 | ; the CRT. | ||
| 8 | ; RUN: llvm-mc -triple x86_64-windows-msvc -filetype=obj %S/Inputs/loadconfig-cfg-x64.s -o %t.ldcfg.obj | ||
| 9 | |||
| 10 | ; RUN: llvm-as %s -o %t.bc | ||
| 11 | ; 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 | ||
| 13 | |||
| 14 | ; There must be *two* entries in the table: DLL entry point, and my_handler. | ||
| 15 | |||
| 16 | ; CHECK: LoadConfig [ | ||
| 17 | ; CHECK: GuardCFFunctionTable: 0x{{[^0].*}} | ||
| 18 | ; CHECK-NEXT: GuardCFFunctionCount: 2 | ||
| 19 | ; CHECK-NEXT: GuardFlags: 0x10500 | ||
| 20 | ; CHECK: ] | ||
| 21 | ; CHECK: GuardFidTable [ | ||
| 22 | ; CHECK-NEXT: 0x180{{.*}} | ||
| 23 | ; CHECK-NEXT: 0x180{{.*}} | ||
| 24 | ; CHECK-NEXT: ] | ||
| 25 | |||
| 26 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" | ||
| 27 | target triple = "x86_64-pc-windows-msvc19.12.25835" | ||
| 28 | |||
| 29 | declare dllimport void @do_indirect_call(void ()*) | ||
| 30 | |||
| 31 | define dso_local i32 @main() local_unnamed_addr { | ||
| 32 | entry: | ||
| 33 | tail call void @do_indirect_call(void ()* nonnull @my_handler) | ||
| 34 | ret i32 0 | ||
| 35 | } | ||
| 36 | |||
| 37 | define dso_local void @my_handler() { | ||
| 38 | entry: | ||
| 39 | ret void | ||
| 40 | } | ||
deps/lld/test/COFF/hello32.test+14-14| ... | @@ -11,7 +11,7 @@ HEADER-NEXT: AddressSize: 32bit | ... | @@ -11,7 +11,7 @@ HEADER-NEXT: AddressSize: 32bit |
| 11 | HEADER-NEXT: ImageFileHeader { | 11 | HEADER-NEXT: ImageFileHeader { |
| 12 | HEADER-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C) | 12 | HEADER-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C) |
| 13 | HEADER-NEXT: SectionCount: 4 | 13 | HEADER-NEXT: SectionCount: 4 |
| 14 | HEADER-NEXT: TimeDateStamp: 1970-01-01 00:00:00 (0x0) | 14 | HEADER-NEXT: TimeDateStamp: |
| 15 | HEADER-NEXT: PointerToSymbolTable: 0x0 | 15 | HEADER-NEXT: PointerToSymbolTable: 0x0 |
| 16 | HEADER-NEXT: SymbolCount: 0 | 16 | HEADER-NEXT: SymbolCount: 0 |
| 17 | HEADER-NEXT: OptionalHeaderSize: 224 | 17 | HEADER-NEXT: OptionalHeaderSize: 224 |
| ... | @@ -27,8 +27,8 @@ HEADER-NEXT: MinorLinkerVersion: 0 | ... | @@ -27,8 +27,8 @@ HEADER-NEXT: MinorLinkerVersion: 0 |
| 27 | HEADER-NEXT: SizeOfCode: 512 | 27 | HEADER-NEXT: SizeOfCode: 512 |
| 28 | HEADER-NEXT: SizeOfInitializedData: 1536 | 28 | HEADER-NEXT: SizeOfInitializedData: 1536 |
| 29 | HEADER-NEXT: SizeOfUninitializedData: 0 | 29 | HEADER-NEXT: SizeOfUninitializedData: 0 |
| 30 | HEADER-NEXT: AddressOfEntryPoint: 0x2000 | 30 | HEADER-NEXT: AddressOfEntryPoint: 0x1000 |
| 31 | HEADER-NEXT: BaseOfCode: 0x2000 | 31 | HEADER-NEXT: BaseOfCode: 0x1000 |
| 32 | HEADER-NEXT: BaseOfData: 0x0 | 32 | HEADER-NEXT: BaseOfData: 0x0 |
| 33 | HEADER-NEXT: ImageBase: 0x400000 | 33 | HEADER-NEXT: ImageBase: 0x400000 |
| 34 | HEADER-NEXT: SectionAlignment: 4096 | 34 | HEADER-NEXT: SectionAlignment: 4096 |
| ... | @@ -40,7 +40,7 @@ HEADER-NEXT: MinorImageVersion: 0 | ... | @@ -40,7 +40,7 @@ HEADER-NEXT: MinorImageVersion: 0 |
| 40 | HEADER-NEXT: MajorSubsystemVersion: 6 | 40 | HEADER-NEXT: MajorSubsystemVersion: 6 |
| 41 | HEADER-NEXT: MinorSubsystemVersion: 0 | 41 | HEADER-NEXT: MinorSubsystemVersion: 0 |
| 42 | HEADER-NEXT: SizeOfImage: 20480 | 42 | HEADER-NEXT: SizeOfImage: 20480 |
| 43 | HEADER-NEXT: SizeOfHeaders: 512 | 43 | HEADER-NEXT: SizeOfHeaders: 1024 |
| 44 | HEADER-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3) | 44 | HEADER-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3) |
| 45 | HEADER-NEXT: Characteristics [ (0x9540) | 45 | HEADER-NEXT: Characteristics [ (0x9540) |
| 46 | HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_APPCONTAINER (0x1000) | 46 | HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_APPCONTAINER (0x1000) |
| ... | @@ -57,7 +57,7 @@ HEADER-NEXT: NumberOfRvaAndSize: 16 | ... | @@ -57,7 +57,7 @@ HEADER-NEXT: NumberOfRvaAndSize: 16 |
| 57 | HEADER-NEXT: DataDirectory { | 57 | HEADER-NEXT: DataDirectory { |
| 58 | HEADER-NEXT: ExportTableRVA: 0x0 | 58 | HEADER-NEXT: ExportTableRVA: 0x0 |
| 59 | HEADER-NEXT: ExportTableSize: 0x0 | 59 | HEADER-NEXT: ExportTableSize: 0x0 |
| 60 | HEADER-NEXT: ImportTableRVA: 0x3000 | 60 | HEADER-NEXT: ImportTableRVA: 0x2000 |
| 61 | HEADER-NEXT: ImportTableSize: 0x28 | 61 | HEADER-NEXT: ImportTableSize: 0x28 |
| 62 | HEADER-NEXT: ResourceTableRVA: 0x0 | 62 | HEADER-NEXT: ResourceTableRVA: 0x0 |
| 63 | HEADER-NEXT: ResourceTableSize: 0x0 | 63 | HEADER-NEXT: ResourceTableSize: 0x0 |
| ... | @@ -79,7 +79,7 @@ HEADER-NEXT: LoadConfigTableRVA: 0x0 | ... | @@ -79,7 +79,7 @@ HEADER-NEXT: LoadConfigTableRVA: 0x0 |
| 79 | HEADER-NEXT: LoadConfigTableSize: 0x0 | 79 | HEADER-NEXT: LoadConfigTableSize: 0x0 |
| 80 | HEADER-NEXT: BoundImportRVA: 0x0 | 80 | HEADER-NEXT: BoundImportRVA: 0x0 |
| 81 | HEADER-NEXT: BoundImportSize: 0x0 | 81 | HEADER-NEXT: BoundImportSize: 0x0 |
| 82 | HEADER-NEXT: IATRVA: 0x3034 | 82 | HEADER-NEXT: IATRVA: 0x2034 |
| 83 | HEADER-NEXT: IATSize: 0xC | 83 | HEADER-NEXT: IATSize: 0xC |
| 84 | HEADER-NEXT: DelayImportDescriptorRVA: 0x0 | 84 | HEADER-NEXT: DelayImportDescriptorRVA: 0x0 |
| 85 | HEADER-NEXT: DelayImportDescriptorSize: 0x0 | 85 | HEADER-NEXT: DelayImportDescriptorSize: 0x0 |
| ... | @@ -91,10 +91,10 @@ HEADER-NEXT: } | ... | @@ -91,10 +91,10 @@ HEADER-NEXT: } |
| 91 | HEADER-NEXT: } | 91 | HEADER-NEXT: } |
| 92 | HEADER-NEXT: DOSHeader { | 92 | HEADER-NEXT: DOSHeader { |
| 93 | HEADER-NEXT: Magic: MZ | 93 | HEADER-NEXT: Magic: MZ |
| 94 | HEADER-NEXT: UsedBytesInTheLastPage: 0 | 94 | HEADER-NEXT: UsedBytesInTheLastPage: 120 |
| 95 | HEADER-NEXT: FileSizeInPages: 0 | 95 | HEADER-NEXT: FileSizeInPages: 1 |
| 96 | HEADER-NEXT: NumberOfRelocationItems: 0 | 96 | HEADER-NEXT: NumberOfRelocationItems: 0 |
| 97 | HEADER-NEXT: HeaderSizeInParagraphs: 0 | 97 | HEADER-NEXT: HeaderSizeInParagraphs: 4 |
| 98 | HEADER-NEXT: MinimumExtraParagraphs: 0 | 98 | HEADER-NEXT: MinimumExtraParagraphs: 0 |
| 99 | HEADER-NEXT: MaximumExtraParagraphs: 0 | 99 | HEADER-NEXT: MaximumExtraParagraphs: 0 |
| 100 | HEADER-NEXT: InitialRelativeSS: 0 | 100 | HEADER-NEXT: InitialRelativeSS: 0 |
| ... | @@ -106,7 +106,7 @@ HEADER-NEXT: AddressOfRelocationTable: 64 | ... | @@ -106,7 +106,7 @@ HEADER-NEXT: AddressOfRelocationTable: 64 |
| 106 | HEADER-NEXT: OverlayNumber: 0 | 106 | HEADER-NEXT: OverlayNumber: 0 |
| 107 | HEADER-NEXT: OEMid: 0 | 107 | HEADER-NEXT: OEMid: 0 |
| 108 | HEADER-NEXT: OEMinfo: 0 | 108 | HEADER-NEXT: OEMinfo: 0 |
| 109 | HEADER-NEXT: AddressOfNewExeHeader: 64 | 109 | HEADER-NEXT: AddressOfNewExeHeader: 120 |
| 110 | HEADER-NEXT: } | 110 | HEADER-NEXT: } |
| 111 | 111 | ||
| 112 | IMPORTS: Format: COFF-i386 | 112 | IMPORTS: Format: COFF-i386 |
| ... | @@ -114,8 +114,8 @@ IMPORTS: Arch: i386 | ... | @@ -114,8 +114,8 @@ IMPORTS: Arch: i386 |
| 114 | IMPORTS: AddressSize: 32bit | 114 | IMPORTS: AddressSize: 32bit |
| 115 | IMPORTS: Import { | 115 | IMPORTS: Import { |
| 116 | IMPORTS: Name: std32.dll | 116 | IMPORTS: Name: std32.dll |
| 117 | IMPORTS: ImportLookupTableRVA: 0x3028 | 117 | IMPORTS: ImportLookupTableRVA: 0x2028 |
| 118 | IMPORTS: ImportAddressTableRVA: 0x3034 | 118 | IMPORTS: ImportAddressTableRVA: 0x2034 |
| 119 | IMPORTS: Symbol: ExitProcess (0) | 119 | IMPORTS: Symbol: ExitProcess (0) |
| 120 | IMPORTS: Symbol: MessageBoxA (1) | 120 | IMPORTS: Symbol: MessageBoxA (1) |
| 121 | IMPORTS: } | 121 | IMPORTS: } |
| ... | @@ -123,10 +123,10 @@ IMPORTS: } | ... | @@ -123,10 +123,10 @@ IMPORTS: } |
| 123 | BASEREL: BaseReloc [ | 123 | BASEREL: BaseReloc [ |
| 124 | BASEREL: Entry { | 124 | BASEREL: Entry { |
| 125 | BASEREL: Type: HIGHLOW | 125 | BASEREL: Type: HIGHLOW |
| 126 | BASEREL: Address: 0x2005 | 126 | BASEREL: Address: 0x1005 |
| 127 | BASEREL: } | 127 | BASEREL: } |
| 128 | BASEREL: Entry { | 128 | BASEREL: Entry { |
| 129 | BASEREL: Type: HIGHLOW | 129 | BASEREL: Type: HIGHLOW |
| 130 | BASEREL: Address: 0x200C | 130 | BASEREL: Address: 0x100C |
| 131 | BASEREL: } | 131 | BASEREL: } |
| 132 | BASEREL: ] | 132 | BASEREL: ] |
deps/lld/test/COFF/icf-different-align.test+11-2| ... | @@ -2,9 +2,14 @@ | ... | @@ -2,9 +2,14 @@ |
| 2 | # RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \ | 2 | # RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \ |
| 3 | # RUN: /verbose %t.obj > %t.log 2>&1 | 3 | # RUN: /verbose %t.obj > %t.log 2>&1 |
| 4 | # RUN: FileCheck %s < %t.log | 4 | # RUN: FileCheck %s < %t.log |
| 5 | # RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=OBJDUMP %s | ||
| 5 | 6 | ||
| 6 | # CHECK-NOT: Selected foo | 7 | # CHECK: Selected foo |
| 7 | # CHECK-NOT: Removed bar | 8 | # CHECK: Removed bar |
| 9 | |||
| 10 | # OBJDUMP: Contents of section .text: | ||
| 11 | # OBJDUMP-NEXT: 140001000 00cccccc cccccccc cccccccc cccccccc | ||
| 12 | # OBJDUMP-NEXT: 140001010 4883ec28 e8000000 004883c4 28c3 | ||
| 8 | 13 | ||
| 9 | --- !COFF | 14 | --- !COFF |
| 10 | header: | 15 | header: |
| ... | @@ -19,6 +24,10 @@ sections: | ... | @@ -19,6 +24,10 @@ sections: |
| 19 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | 24 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] |
| 20 | Alignment: 16 | 25 | Alignment: 16 |
| 21 | SectionData: 4883EC28E8000000004883C428C3 | 26 | SectionData: 4883EC28E8000000004883C428C3 |
| 27 | - Name: '.text' | ||
| 28 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 29 | Alignment: 1 | ||
| 30 | SectionData: 00 | ||
| 22 | symbols: | 31 | symbols: |
| 23 | - Name: '.text$mn' | 32 | - Name: '.text$mn' |
| 24 | Value: 0 | 33 | Value: 0 |
deps/lld/test/COFF/icf-executable.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.obj | 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.obj |
| 2 | # RUN: lld-link -entry:main %t.obj -out:%t.exe -verbose 2>&1 | FileCheck %s | 3 | # RUN: lld-link -entry:main %t.obj -out:%t.exe -verbose 2>&1 | FileCheck %s |
| 3 | 4 |
deps/lld/test/COFF/icf-pdata.s created+98| ... | @@ -0,0 +1,98 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj | ||
| 3 | # RUN: lld-link %t.obj -dll -noentry -out:%t.dll -merge:.xdata=.xdata | ||
| 4 | # RUN: llvm-readobj -sections -coff-exports %t.dll | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: Name: .pdata | ||
| 7 | # CHECK-NEXT: VirtualSize: 0x18 | ||
| 8 | # CHECK: Name: .xdata | ||
| 9 | # CHECK-NEXT: VirtualSize: 0x10 | ||
| 10 | |||
| 11 | # CHECK: Name: xdata1 | ||
| 12 | # CHECK-NEXT: RVA: 0x1010 | ||
| 13 | # CHECK: Name: xdata1a | ||
| 14 | # CHECK-NEXT: RVA: 0x1010 | ||
| 15 | # CHECK: Name: xdata1b | ||
| 16 | # CHECK-NEXT: RVA: 0x1030 | ||
| 17 | |||
| 18 | 	.text | ||
| 19 | callee: | ||
| 20 | 	ret | ||
| 21 | |||
| 22 | 	.def	 xdata1; | ||
| 23 | 	.scl	2; | ||
| 24 | 	.type	32; | ||
| 25 | 	.endef | ||
| 26 | 	.section	.text,"xr",one_only,xdata1 | ||
| 27 | 	.globl	xdata1 # -- Begin function xdata1 | ||
| 28 | 	.p2align	4, 0x90 | ||
| 29 | xdata1: # @xdata1 | ||
| 30 | .seh_proc xdata1 | ||
| 31 | # BB#0: # %entry | ||
| 32 | 	subq	$40, %rsp | ||
| 33 | 	.seh_stackalloc 40 | ||
| 34 | 	.seh_endprologue | ||
| 35 | 	callq	callee | ||
| 36 | 	nop | ||
| 37 | 	addq	$40, %rsp | ||
| 38 | 	jmp	callee # TAILCALL | ||
| 39 | 	.seh_handlerdata | ||
| 40 | 	.section	.text,"xr",one_only,xdata1 | ||
| 41 | 	.seh_endproc | ||
| 42 | # -- End function | ||
| 43 | |||
| 44 | # xdata1a is identical to xdata1, so it should be ICFd, and so should its pdata. | ||
| 45 | # It also has associative debug and CFG sections which should be ignored by ICF. | ||
| 46 | 	.def	 xdata1a; | ||
| 47 | 	.scl	2; | ||
| 48 | 	.type	32; | ||
| 49 | 	.endef | ||
| 50 | 	.section	.text,"xr",one_only,xdata1a | ||
| 51 | 	.globl	xdata1a # -- Begin function xdata1a | ||
| 52 | 	.p2align	4, 0x90 | ||
| 53 | xdata1a: # @xdata1a | ||
| 54 | .seh_proc xdata1a | ||
| 55 | # BB#0: # %entry | ||
| 56 | 	subq	$40, %rsp | ||
| 57 | 	.seh_stackalloc 40 | ||
| 58 | 	.seh_endprologue | ||
| 59 | 	callq	callee | ||
| 60 | 	nop | ||
| 61 | 	addq	$40, %rsp | ||
| 62 | 	jmp	callee # TAILCALL | ||
| 63 | 	.seh_handlerdata | ||
| 64 | 	.section	.text,"xr",one_only,xdata1a | ||
| 65 | 	.seh_endproc | ||
| 66 | |||
| 67 | 	.section .debug$S,"r",associative,xdata1a | ||
| 68 | 	.section .gfids$y,"r",associative,xdata1a | ||
| 69 | 	.section .gljmp$y,"r",associative,xdata1a | ||
| 70 | |||
| 71 | # xdata1b's text is identical to xdata1, but its xdata specifies a different | ||
| 72 | # stack size, so it cannot be ICFd with xdata1. | ||
| 73 | 	.def	 xdata1b; | ||
| 74 | 	.scl	2; | ||
| 75 | 	.type	32; | ||
| 76 | 	.endef | ||
| 77 | 	.section	.text,"xr",one_only,xdata1b | ||
| 78 | 	.globl	xdata1b # -- Begin function xdata1b | ||
| 79 | 	.p2align	4, 0x90 | ||
| 80 | xdata1b: # @xdata1b | ||
| 81 | .seh_proc xdata1b | ||
| 82 | # BB#0: # %entry | ||
| 83 | 	subq	$40, %rsp | ||
| 84 | 	.seh_stackalloc 48 | ||
| 85 | 	.seh_endprologue | ||
| 86 | 	callq	callee | ||
| 87 | 	nop | ||
| 88 | 	addq	$40, %rsp | ||
| 89 | 	jmp	callee # TAILCALL | ||
| 90 | 	.seh_handlerdata | ||
| 91 | 	.section	.text,"xr",one_only,xdata1b | ||
| 92 | 	.seh_endproc | ||
| 93 | # -- End function | ||
| 94 | |||
| 95 | 	.section	.drectve,"yn" | ||
| 96 | 	.ascii	" -export:xdata1" | ||
| 97 | 	.ascii	" -export:xdata1a" | ||
| 98 | 	.ascii	" -export:xdata1b" | ||
deps/lld/test/COFF/icf-simple.test+5| ... | @@ -23,6 +23,11 @@ | ... | @@ -23,6 +23,11 @@ |
| 23 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 | 23 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 |
| 24 | # RUN: FileCheck -check-prefix=NOICF %s < %t.log | 24 | # RUN: FileCheck -check-prefix=NOICF %s < %t.log |
| 25 | 25 | ||
| 26 | # /profile disables ICF. | ||
| 27 | # RUN: lld-link /profile /entry:foo /out:%t.exe /subsystem:console \ | ||
| 28 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 | ||
| 29 | # RUN: FileCheck -check-prefix=NOICF %s < %t.log | ||
| 30 | |||
| 26 | # /opt:noref disables ICF. | 31 | # /opt:noref disables ICF. |
| 27 | # RUN: lld-link /opt:noref /entry:foo /out:%t.exe /subsystem:console \ | 32 | # RUN: lld-link /opt:noref /entry:foo /out:%t.exe /subsystem:console \ |
| 28 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 | 33 | # RUN: /include:bar /verbose %t.obj > %t.log 2>&1 |
deps/lld/test/COFF/icf-vtables.s created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s | ||
| 3 | # RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console | ||
| 4 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: Contents of section .text: | ||
| 7 | .globl main | ||
| 8 | main: | ||
| 9 | # CHECK-NEXT: 140001000 00200040 01000000 01200040 01000000 | ||
| 10 | .8byte "??_" | ||
| 11 | .8byte "??_7" | ||
| 12 | # CHECK-NEXT: 140001010 01200040 01000000 | ||
| 13 | .8byte "??_7a" | ||
| 14 | |||
| 15 | .section .rdata,"dr",discard,"??_" | ||
| 16 | .globl "??_" | ||
| 17 | "??_": | ||
| 18 | .byte 42 | ||
| 19 | |||
| 20 | .section .rdata,"dr",discard,"??_7" | ||
| 21 | .globl "??_7" | ||
| 22 | "??_7": | ||
| 23 | .byte 42 | ||
| 24 | |||
| 25 | .section .rdata,"dr",discard,"??_7a" | ||
| 26 | .globl "??_7a" | ||
| 27 | "??_7a": | ||
| 28 | .byte 42 | ||
deps/lld/test/COFF/icf-xdata.s+18-5| ... | @@ -1,13 +1,26 @@ | ... | @@ -1,13 +1,26 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj | 2 | # RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj |
| 3 | # RUN: lld-link %t.obj -dll -noentry -out:%t.dll -merge:.xdata=.xdata 2>&1 \ | ||
| 4 | # RUN: | FileCheck %s --check-prefix=WARN | ||
| 5 | # RUN: llvm-readobj -sections %t.dll | FileCheck %s --check-prefix=XDATA | ||
| 2 | # RUN: lld-link %t.obj -dll -noentry -out:%t.dll | 6 | # RUN: lld-link %t.obj -dll -noentry -out:%t.dll |
| 3 | # RUN: llvm-readobj -sections %t.dll | FileCheck %s | 7 | # RUN: llvm-readobj -sections %t.dll | FileCheck %s --check-prefix=RDATA |
| 4 | 8 | ||
| 5 | # There shouldn't be much xdata, because all three .pdata entries (12 bytes | 9 | # There shouldn't be much xdata, because all three .pdata entries (12 bytes |
| 6 | # each) should use the same .xdata unwind info. | 10 | # each) should use the same .xdata unwind info. |
| 7 | # CHECK: Name: .pdata | 11 | # XDATA: Name: .rdata |
| 8 | # CHECK-NEXT: VirtualSize: 0x24 | 12 | # XDATA-NEXT: VirtualSize: 0x73 |
| 9 | # CHECK: Name: .xdata | 13 | # XDATA: Name: .pdata |
| 10 | # CHECK-NEXT: VirtualSize: 0x8 | 14 | # XDATA-NEXT: VirtualSize: 0x24 |
| 15 | # XDATA: Name: .xdata | ||
| 16 | # XDATA-NEXT: VirtualSize: 0x8 | ||
| 17 | # | ||
| 18 | # WARN: warning: .xdata=.rdata: already merged into .xdata | ||
| 19 | # | ||
| 20 | # RDATA: Name: .rdata | ||
| 21 | # RDATA-NEXT: VirtualSize: 0x7C | ||
| 22 | # RDATA: Name: .pdata | ||
| 23 | # RDATA-NEXT: VirtualSize: 0x24 | ||
| 11 | 24 | ||
| 12 | 	.text | 25 | 	.text |
| 13 | callee: | 26 | callee: |
deps/lld/test/COFF/implib-name.test+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: mkdir -p %T | 2 | # RUN: mkdir -p %T |
| 2 | # RUN: llvm-mc -triple x86_64-unknown-windows-msvc -filetype obj -o %T/object.obj %S/Inputs/object.s | 3 | # RUN: llvm-mc -triple x86_64-unknown-windows-msvc -filetype obj -o %T/object.obj %S/Inputs/object.s |
| 3 | 4 |
deps/lld/test/COFF/imports.test+4-4| ... | @@ -15,8 +15,8 @@ TEXT: Disassembly of section .text: | ... | @@ -15,8 +15,8 @@ TEXT: Disassembly of section .text: |
| 15 | TEXT-NEXT: .text: | 15 | TEXT-NEXT: .text: |
| 16 | TEXT-NEXT: subq $40, %rsp | 16 | TEXT-NEXT: subq $40, %rsp |
| 17 | TEXT-NEXT: movq $0, %rcx | 17 | TEXT-NEXT: movq $0, %rcx |
| 18 | TEXT-NEXT: leaq -4108(%rip), %rdx | 18 | TEXT-NEXT: leaq 8180(%rip), %rdx |
| 19 | TEXT-NEXT: leaq -4121(%rip), %r8 | 19 | TEXT-NEXT: leaq 8167(%rip), %r8 |
| 20 | TEXT-NEXT: movl $0, %r9d | 20 | TEXT-NEXT: movl $0, %r9d |
| 21 | TEXT-NEXT: callq 60 | 21 | TEXT-NEXT: callq 60 |
| 22 | TEXT-NEXT: movl $0, %ecx | 22 | TEXT-NEXT: movl $0, %ecx |
| ... | @@ -28,8 +28,8 @@ TEXT: jmpq *4082(%rip) | ... | @@ -28,8 +28,8 @@ TEXT: jmpq *4082(%rip) |
| 28 | 28 | ||
| 29 | IMPORT: Import { | 29 | IMPORT: Import { |
| 30 | IMPORT-NEXT: Name: std64.dll | 30 | IMPORT-NEXT: Name: std64.dll |
| 31 | IMPORT-NEXT: ImportLookupTableRVA: 0x3028 | 31 | IMPORT-NEXT: ImportLookupTableRVA: 0x2028 |
| 32 | IMPORT-NEXT: ImportAddressTableRVA: 0x3048 | 32 | IMPORT-NEXT: ImportAddressTableRVA: 0x2048 |
| 33 | IMPORT-NEXT: Symbol: ExitProcess (0) | 33 | IMPORT-NEXT: Symbol: ExitProcess (0) |
| 34 | IMPORT-NEXT: Symbol: (50) | 34 | IMPORT-NEXT: Symbol: (50) |
| 35 | IMPORT-NEXT: Symbol: MessageBoxA (1) | 35 | IMPORT-NEXT: Symbol: MessageBoxA (1) |
deps/lld/test/COFF/incremental.test created+100| ... | @@ -0,0 +1,100 @@ | ||
| 1 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj | ||
| 2 | |||
| 3 | # RUN: lld-link -out:%t.dll -dll %t.obj 2>&1 \ | ||
| 4 | # RUN: | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 5 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 6 | # RUN: lld-link -out:%t.dll -dll %t.obj | ||
| 7 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 8 | |||
| 9 | # RUN: lld-link -out:%t.dll -dll -incremental %t.obj 2>&1 \ | ||
| 10 | # RUN: | FileCheck -allow-empty -check-prefix=WARN-REF %s | ||
| 11 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 12 | # RUN: lld-link -out:%t.dll -dll -incremental %t.obj | ||
| 13 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 14 | |||
| 15 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:noref,noicf %t.obj 2>&1 \ | ||
| 16 | # RUN: | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 17 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 18 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:noref,noicf %t.obj | ||
| 19 | # RUN: ls -l %t.lib | FileCheck -check-prefix=KEEP %s | ||
| 20 | |||
| 21 | # RUN: lld-link -out:%t.dll -dll -debug %t.obj 2>&1 \ | ||
| 22 | # RUN: | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 23 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 24 | # RUN: lld-link -out:%t.dll -dll -debug %t.obj | ||
| 25 | # RUN: ls -l %t.lib | FileCheck -check-prefix=KEEP %s | ||
| 26 | |||
| 27 | # RUN: lld-link -out:%t.dll -dll -debug -incremental:no %t.obj 2>&1 \ | ||
| 28 | # RUN: | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 29 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 30 | # RUN: lld-link -out:%t.dll -dll -debug -incremental:no %t.obj | ||
| 31 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 32 | |||
| 33 | # RUN: lld-link -out:%t.dll -dll -opt:icf %t.obj 2>&1 \ | ||
| 34 | # RUN: | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 35 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 36 | # RUN: lld-link -out:%t.dll -dll -opt:icf %t.obj | ||
| 37 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 38 | |||
| 39 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:noref,icf %t.obj 2>&1 \ | ||
| 40 | # RUN: | FileCheck -check-prefix=WARN-ICF %s | ||
| 41 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 42 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:noref,icf %t.obj | ||
| 43 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 44 | |||
| 45 | # RUN: lld-link -out:%t.dll -dll -debug -opt:icf %t.obj 2>&1 \ | ||
| 46 | # RUN: | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 47 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 48 | # RUN: lld-link -out:%t.dll -dll -debug -opt:icf %t.obj | ||
| 49 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 50 | |||
| 51 | # RUN: lld-link -out:%t.dll -dll -opt:ref %t.obj 2>&1 \ | ||
| 52 | # RUN: | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 53 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 54 | # RUN: lld-link -out:%t.dll -dll -opt:ref %t.obj | ||
| 55 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 56 | |||
| 57 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:ref %t.obj 2>&1 \ | ||
| 58 | # RUN: | FileCheck -check-prefix=WARN-REF %s | ||
| 59 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 60 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:ref %t.obj | ||
| 61 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 62 | |||
| 63 | # RUN: touch %t.order | ||
| 64 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:noref,noicf %t.obj \ | ||
| 65 | # RUN: -order:@%t.order 2>&1 | FileCheck -check-prefix=WARN-ORDER %s | ||
| 66 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 67 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:noref,noicf -order:@%t.order %t.obj | ||
| 68 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 69 | |||
| 70 | # RUN: lld-link -out:%t.dll -dll -opt:noref,noicf %t.obj \ | ||
| 71 | # RUN: -order:@%t.order 2>&1 | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 72 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 73 | # RUN: lld-link -out:%t.dll -dll -opt:noref,noicf -order:@%t.order %t.obj | ||
| 74 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 75 | |||
| 76 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:noref,noicf %t.obj \ | ||
| 77 | # RUN: -profile 2>&1 | FileCheck -check-prefix=WARN-PROFILE %s | ||
| 78 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 79 | # RUN: lld-link -out:%t.dll -dll -incremental -opt:noref,noicf -profile %t.obj | ||
| 80 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 81 | |||
| 82 | # RUN: lld-link -out:%t.dll -dll -opt:noref,noicf %t.obj \ | ||
| 83 | # RUN: -profile 2>&1 | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 84 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 85 | # RUN: lld-link -out:%t.dll -dll -opt:noref,noicf -profile %t.obj | ||
| 86 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 87 | |||
| 88 | # RUN: lld-link -out:%t.dll -dll -debug -opt:ref %t.obj 2>&1 \ | ||
| 89 | # RUN: | FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 90 | # RUN: touch -t 198002011200.00 %t.lib | ||
| 91 | # RUN: lld-link -out:%t.dll -dll -debug -opt:ref %t.obj | ||
| 92 | # RUN: ls -l %t.lib | FileCheck -check-prefix=NOKEEP %s | ||
| 93 | |||
| 94 | # NOWARN-NOT: ignoring '/incremental' | ||
| 95 | # WARN-ICF: ignoring '/incremental' because ICF is enabled; use '/opt:noicf' to disable | ||
| 96 | # WARN-REF: ignoring '/incremental' because REF is enabled; use '/opt:noref' to disable | ||
| 97 | # WARN-ORDER: ignoring '/incremental' due to '/order' specification | ||
| 98 | # WARN-PROFILE: ignoring '/incremental' due to '/profile' specification | ||
| 99 | # KEEP: {{Feb 1 1980|1980-02-01}} | ||
| 100 | # NOKEEP-NOT: {{Feb 1 1980|1980-02-01}} | ||
deps/lld/test/COFF/invalid-section-number.test created+34| ... | @@ -0,0 +1,34 @@ | ||
| 1 | # RUN: yaml2obj %s > %t.obj | ||
| 2 | # RUN: not lld-link %t.obj 2>&1 | FileCheck %s | ||
| 3 | |||
| 4 | # CHECK: foo should not refer to special section -10 | ||
| 5 | |||
| 6 | --- !COFF | ||
| 7 | header: | ||
| 8 | Machine: IMAGE_FILE_MACHINE_I386 | ||
| 9 | Characteristics: [] | ||
| 10 | sections: | ||
| 11 | - Name: .text | ||
| 12 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 13 | Alignment: 4 | ||
| 14 | SectionData: B82A000000C3 | ||
| 15 | symbols: | ||
| 16 | - Name: .text | ||
| 17 | Value: 0 | ||
| 18 | SectionNumber: 1 | ||
| 19 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 20 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 21 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 22 | SectionDefinition: | ||
| 23 | Length: 6 | ||
| 24 | NumberOfRelocations: 0 | ||
| 25 | NumberOfLinenumbers: 0 | ||
| 26 | CheckSum: 0 | ||
| 27 | Number: 0 | ||
| 28 | - Name: foo | ||
| 29 | Value: 0 | ||
| 30 | SectionNumber: -10 | ||
| 31 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 32 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 33 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 34 | ... | ||
deps/lld/test/COFF/largeaddressaware.test+1-1| ... | @@ -9,7 +9,7 @@ HEADER-NEXT: AddressSize: 32bit | ... | @@ -9,7 +9,7 @@ HEADER-NEXT: AddressSize: 32bit |
| 9 | HEADER-NEXT: ImageFileHeader { | 9 | HEADER-NEXT: ImageFileHeader { |
| 10 | HEADER-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C) | 10 | HEADER-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C) |
| 11 | HEADER-NEXT: SectionCount: 4 | 11 | HEADER-NEXT: SectionCount: 4 |
| 12 | HEADER-NEXT: TimeDateStamp: 1970-01-01 00:00:00 (0x0) | 12 | HEADER-NEXT: TimeDateStamp: |
| 13 | HEADER-NEXT: PointerToSymbolTable: 0x0 | 13 | HEADER-NEXT: PointerToSymbolTable: 0x0 |
| 14 | HEADER-NEXT: SymbolCount: 0 | 14 | HEADER-NEXT: SymbolCount: 0 |
| 15 | HEADER-NEXT: OptionalHeaderSize: 224 | 15 | HEADER-NEXT: OptionalHeaderSize: 224 |
deps/lld/test/COFF/loadcfg.ll+2-1| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %t.obj %s | 2 | ; RUN: llvm-as -o %t.obj %s |
| 2 | ; RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console | 3 | ; RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console |
| 3 | ; RUN: llvm-readobj -file-headers %t.exe | FileCheck %s | 4 | ; RUN: llvm-readobj -file-headers %t.exe | FileCheck %s |
| 4 | 5 | ||
| 5 | ; CHECK: LoadConfigTableRVA: 0x1000 | 6 | ; CHECK: LoadConfigTableRVA: 0x2000 |
| 6 | ; CHECK: LoadConfigTableSize: 0x70 | 7 | ; CHECK: LoadConfigTableSize: 0x70 |
| 7 | 8 | ||
| 8 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" | 9 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/COFF/loadcfg.test+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | # RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console | 2 | # 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 |
| 4 | 4 | ||
| 5 | # CHECK: LoadConfigTableRVA: 0x1000 | 5 | # CHECK: LoadConfigTableRVA: 0x2000 |
| 6 | # CHECK: LoadConfigTableSize: 0x70 | 6 | # CHECK: LoadConfigTableSize: 0x70 |
| 7 | 7 | ||
| 8 | --- !COFF | 8 | --- !COFF |
deps/lld/test/COFF/loadcfg32.test+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | # RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console | 2 | # 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 |
| 4 | 4 | ||
| 5 | # CHECK: LoadConfigTableRVA: 0x1000 | 5 | # CHECK: LoadConfigTableRVA: 0x2000 |
| 6 | # CHECK: LoadConfigTableSize: 0x40 | 6 | # CHECK: LoadConfigTableSize: 0x40 |
| 7 | 7 | ||
| 8 | --- !COFF | 8 | --- !COFF |
deps/lld/test/COFF/lto-chkstk.ll+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %t.obj %s | 2 | ; RUN: llvm-as -o %t.obj %s |
| 2 | ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-foo.obj %S/Inputs/lto-chkstk-foo.s | 3 | ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-foo.obj %S/Inputs/lto-chkstk-foo.s |
| 3 | ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-chkstk.obj %S/Inputs/lto-chkstk-chkstk.s | 4 | ; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-chkstk.obj %S/Inputs/lto-chkstk-chkstk.s |
deps/lld/test/COFF/lto-comdat.ll+8-8| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %T/comdat-main.lto.obj %s | 2 | ; RUN: llvm-as -o %T/comdat-main.lto.obj %s |
| 2 | ; RUN: llvm-as -o %T/comdat1.lto.obj %S/Inputs/lto-comdat1.ll | 3 | ; RUN: llvm-as -o %T/comdat1.lto.obj %S/Inputs/lto-comdat1.ll |
| 3 | ; RUN: llvm-as -o %T/comdat2.lto.obj %S/Inputs/lto-comdat2.ll | 4 | ; RUN: llvm-as -o %T/comdat2.lto.obj %S/Inputs/lto-comdat2.ll |
| ... | @@ -45,25 +46,24 @@ | ... | @@ -45,25 +46,24 @@ |
| 45 | ; TEXT-11-NEXT: xorl	%eax, %eax | 46 | ; TEXT-11-NEXT: xorl	%eax, %eax |
| 46 | ; TEXT-11-NEXT: retq | 47 | ; TEXT-11-NEXT: retq |
| 47 | 48 | ||
| 48 | ; HEADERS-01: AddressOfEntryPoint: 0x2000 | 49 | ; HEADERS-01: AddressOfEntryPoint: 0x1000 |
| 49 | ; TEXT-01: Disassembly of section .text: | 50 | ; TEXT-01: Disassembly of section .text: |
| 50 | ; TEXT-01-NEXT: .text: | 51 | ; TEXT-01-NEXT: .text: |
| 51 | ; TEXT-01-NEXT: subq	$40, %rsp | 52 | ; TEXT-01-NEXT: subq	$40, %rsp |
| 52 | ; TEXT-01-NEXT: callq	39 | 53 | ; TEXT-01-NEXT: callq	23 |
| 53 | ; TEXT-01-NEXT: callq	50 | 54 | ; TEXT-01-NEXT: callq	18 |
| 54 | ; TEXT-01-NEXT: callq	13 | 55 | ; TEXT-01-NEXT: callq	13 |
| 55 | ; TEXT-01-NEXT: xorl	%eax, %eax | 56 | ; TEXT-01-NEXT: xorl	%eax, %eax |
| 56 | ; TEXT-01-NEXT: addq	$40, %rsp | 57 | ; TEXT-01-NEXT: addq	$40, %rsp |
| 57 | ; TEXT-01: retq | 58 | ; TEXT-01: retq |
| 58 | ; TEXT-01-NOT: callq | 59 | ; TEXT-01-NOT: callq |
| 59 | ; TEXT-01: retq | 60 | ; TEXT-01: retq |
| 60 | ; TEXT-01-NOT: callq | 61 | ; TEXT-01: int3 |
| 61 | ; TEXT-01: retq | 62 | ; TEXT-01: int3 |
| 62 | ; TEXT-01-NOT: callq | 63 | ; TEXT-01: int3 |
| 63 | ; TEXT-01: retq | ||
| 64 | ; TEXT-01-NOT: {{.}} | 64 | ; TEXT-01-NOT: {{.}} |
| 65 | 65 | ||
| 66 | ; HEADERS-10: AddressOfEntryPoint: 0x2020 | 66 | ; HEADERS-10: AddressOfEntryPoint: 0x1020 |
| 67 | ; TEXT-10: Disassembly of section .text: | 67 | ; TEXT-10: Disassembly of section .text: |
| 68 | ; TEXT-10-NEXT: .text: | 68 | ; TEXT-10-NEXT: .text: |
| 69 | ; TEXT-10-NEXT: subq	$40, %rsp | 69 | ; TEXT-10-NEXT: subq	$40, %rsp |
deps/lld/test/COFF/lto-icf.ll created+27| ... | @@ -0,0 +1,27 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; Test that ICF works after LTO, i.e. both functions have the same address. | ||
| 3 | ; Previously, when we didn't enable function sections, ICF didn't work. | ||
| 4 | |||
| 5 | ; RUN: llvm-as %s -o %t.bc | ||
| 6 | ; RUN: lld-link -opt:icf -dll -noentry %t.bc -out:%t.dll | ||
| 7 | ; RUN: llvm-readobj -coff-exports %t.dll | FileCheck %s | ||
| 8 | |||
| 9 | ; CHECK: Export { | ||
| 10 | ; CHECK: Export { | ||
| 11 | ; CHECK: RVA: 0x[[RVA:.*]] | ||
| 12 | ; CHECK: Export { | ||
| 13 | ; CHECK: RVA: 0x[[RVA]] | ||
| 14 | ; CHECK-NOT: Export | ||
| 15 | |||
| 16 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" | ||
| 17 | target triple = "x86_64-pc-windows-msvc19.12.25835" | ||
| 18 | |||
| 19 | define dllexport i8* @icf_ptr() { | ||
| 20 | entry: | ||
| 21 | ret i8* null | ||
| 22 | } | ||
| 23 | |||
| 24 | define dllexport i64 @icf_int() { | ||
| 25 | entry: | ||
| 26 | ret i64 0 | ||
| 27 | } | ||
deps/lld/test/COFF/lto-lazy-reference.ll+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llc -mtriple=i686-pc-windows-msvc -filetype=obj -o %T/lto-lazy-reference-quadruple.obj %S/Inputs/lto-lazy-reference-quadruple.ll | 2 | ; RUN: llc -mtriple=i686-pc-windows-msvc -filetype=obj -o %T/lto-lazy-reference-quadruple.obj %S/Inputs/lto-lazy-reference-quadruple.ll |
| 2 | ; RUN: llvm-as -o %T/lto-lazy-reference-dummy.bc %S/Inputs/lto-lazy-reference-dummy.ll | 3 | ; RUN: llvm-as -o %T/lto-lazy-reference-dummy.bc %S/Inputs/lto-lazy-reference-dummy.ll |
| 3 | ; RUN: rm -f %t.lib | 4 | ; RUN: rm -f %t.lib |
deps/lld/test/COFF/lto-linker-opts.ll+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %T/lto-linker-opts.obj %s | 2 | ; RUN: llvm-as -o %T/lto-linker-opts.obj %s |
| 2 | ; RUN: env LIB=%S/Inputs lld-link /out:%T/lto-linker-opts.exe /entry:main /subsystem:console %T/lto-linker-opts.obj | 3 | ; RUN: env LIB=%S/Inputs lld-link /out:%T/lto-linker-opts.exe /entry:main /subsystem:console %T/lto-linker-opts.obj |
| 3 | 4 |
deps/lld/test/COFF/lto-new-symbol.ll+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %t.obj %s | 2 | ; RUN: llvm-as -o %t.obj %s |
| 2 | ; RUN: lld-link /out:%t.exe /entry:foo /subsystem:console %t.obj | 3 | ; RUN: lld-link /out:%t.exe /entry:foo /subsystem:console %t.obj |
| 3 | 4 |
deps/lld/test/COFF/lto-opt-level.ll+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %t.obj %s | 2 | ; RUN: llvm-as -o %t.obj %s |
| 2 | ; RUN: lld-link /out:%t0.exe /entry:main /subsystem:console /opt:lldlto=0 /lldmap:%t0.map %t.obj | 3 | ; RUN: lld-link /out:%t0.exe /entry:main /subsystem:console /opt:lldlto=0 /lldmap:%t0.map %t.obj |
| 3 | ; RUN: FileCheck --check-prefix=CHECK-O0 %s < %t0.map | 4 | ; RUN: FileCheck --check-prefix=CHECK-O0 %s < %t0.map |
deps/lld/test/COFF/lto-parallel.ll+4-1| ... | @@ -1,10 +1,12 @@ | ... | @@ -1,10 +1,12 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %t.obj %s | 2 | ; RUN: llvm-as -o %t.obj %s |
| 2 | ; RUN: lld-link /out:%t.exe /entry:foo /include:bar /opt:lldltopartitions=2 /subsystem:console /lldmap:%t.map %t.obj | 3 | ; RUN: lld-link -opt:noicf /out:%t.exe /entry:foo /include:bar /opt:lldltopartitions=2 /subsystem:console /lldmap:%t.map %t.obj |
| 3 | ; RUN: FileCheck %s < %t.map | 4 | ; RUN: FileCheck %s < %t.map |
| 4 | 5 | ||
| 5 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" |
| 6 | target triple = "x86_64-pc-windows-msvc" | 7 | target triple = "x86_64-pc-windows-msvc" |
| 7 | 8 | ||
| 9 | ; CHECK: lto.tmp | ||
| 8 | ; CHECK: lto.tmp | 10 | ; CHECK: lto.tmp |
| 9 | ; CHECK-NEXT: foo | 11 | ; CHECK-NEXT: foo |
| 10 | define void @foo() { | 12 | define void @foo() { |
| ... | @@ -12,6 +14,7 @@ define void @foo() { | ... | @@ -12,6 +14,7 @@ define void @foo() { |
| 12 | ret void | 14 | ret void |
| 13 | } | 15 | } |
| 14 | 16 | ||
| 17 | ; CHECK: lto.tmp | ||
| 15 | ; CHECK: lto.tmp | 18 | ; CHECK: lto.tmp |
| 16 | ; CHECK: bar | 19 | ; CHECK: bar |
| 17 | define void @bar() { | 20 | define void @bar() { |
deps/lld/test/COFF/lto-reloc-model.ll+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %t %s | 2 | ; RUN: llvm-as -o %t %s |
| 2 | ; RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t | 3 | ; RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t |
| 3 | ; RUN: llvm-objdump -d %t.exe | FileCheck %s | 4 | ; RUN: llvm-objdump -d %t.exe | FileCheck %s |
deps/lld/test/COFF/lto.ll+3-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | ; REQUIRES: x86 | ||
| 1 | ; RUN: llvm-as -o %T/main.lto.obj %s | 2 | ; RUN: llvm-as -o %T/main.lto.obj %s |
| 2 | ; RUN: llvm-as -o %T/foo.lto.obj %S/Inputs/lto-dep.ll | 3 | ; RUN: llvm-as -o %T/foo.lto.obj %S/Inputs/lto-dep.ll |
| 3 | ; RUN: rm -f %T/foo.lto.lib | 4 | ; RUN: rm -f %T/foo.lto.lib |
| ... | @@ -52,7 +53,7 @@ | ... | @@ -52,7 +53,7 @@ |
| 52 | ; TEXT-11-NEXT: movl	$2, %eax | 53 | ; TEXT-11-NEXT: movl	$2, %eax |
| 53 | ; TEXT-11-NEXT: retq | 54 | ; TEXT-11-NEXT: retq |
| 54 | 55 | ||
| 55 | ; HEADERS-01: AddressOfEntryPoint: 0x2000 | 56 | ; HEADERS-01: AddressOfEntryPoint: 0x1000 |
| 56 | ; TEXT-01: Disassembly of section .text: | 57 | ; TEXT-01: Disassembly of section .text: |
| 57 | ; TEXT-01-NEXT: .text: | 58 | ; TEXT-01-NEXT: .text: |
| 58 | ; TEXT-01-NEXT: subq	$40, %rsp | 59 | ; TEXT-01-NEXT: subq	$40, %rsp |
| ... | @@ -78,7 +79,7 @@ | ... | @@ -78,7 +79,7 @@ |
| 78 | ; TEXT-01-NEXT: int3 | 79 | ; TEXT-01-NEXT: int3 |
| 79 | ; TEXT-01-NEXT: retq | 80 | ; TEXT-01-NEXT: retq |
| 80 | 81 | ||
| 81 | ; HEADERS-10: AddressOfEntryPoint: 0x2020 | 82 | ; HEADERS-10: AddressOfEntryPoint: 0x1020 |
| 82 | ; TEXT-10: Disassembly of section .text: | 83 | ; TEXT-10: Disassembly of section .text: |
| 83 | ; TEXT-10-NEXT: .text: | 84 | ; TEXT-10-NEXT: .text: |
| 84 | ; TEXT-10-NEXT: retq | 85 | ; TEXT-10-NEXT: retq |
deps/lld/test/COFF/manifestinput-error.test+1-1| ... | @@ -7,4 +7,4 @@ | ... | @@ -7,4 +7,4 @@ |
| 7 | # RUN: /manifestuac:"level='requireAdministrator'" \ | 7 | # RUN: /manifestuac:"level='requireAdministrator'" \ |
| 8 | # RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj 2>&1 | FileCheck %s | 8 | # RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj 2>&1 | FileCheck %s |
| 9 | 9 | ||
| 10 | # CHECK: error: unable to find mt.exe in PATH: No such file or directory | 10 | # CHECK: error: unable to find mt.exe in PATH: {{[Nn]}}o such file or directory |
deps/lld/test/COFF/manifestinput.test+2-2| ... | @@ -8,8 +8,8 @@ | ... | @@ -8,8 +8,8 @@ |
| 8 | # RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \ | 8 | # RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \ |
| 9 | # RUN: -check-prefix TEST_EMBED | 9 | # RUN: -check-prefix TEST_EMBED |
| 10 | 10 | ||
| 11 | TEST_EMBED: ResourceTableRVA: 0x1000 | 11 | TEST_EMBED: ResourceTableRVA: 0x2000 |
| 12 | TEST_EMBED-NEXT: ResourceTableSize: 0x298 | 12 | TEST_EMBED-NEXT: ResourceTableSize: 0x2A0 |
| 13 | TEST_EMBED-DAG: Resources [ | 13 | TEST_EMBED-DAG: Resources [ |
| 14 | TEST_EMBED-NEXT: Total Number of Resources: 1 | 14 | TEST_EMBED-NEXT: Total Number of Resources: 1 |
| 15 | TEST_EMBED-DAG: Number of String Entries: 0 | 15 | TEST_EMBED-DAG: Number of String Entries: 0 |
deps/lld/test/COFF/merge.test+26| ... | @@ -3,9 +3,35 @@ | ... | @@ -3,9 +3,35 @@ |
| 3 | # RUN: /merge:.foo=.abc /merge:.bar=.def %t.obj /debug | 3 | # 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 |
| 5 | 5 | ||
| 6 | # RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \ | ||
| 7 | # RUN: /merge:.foo=.bar /merge:.bar=.abc %t.obj /debug | ||
| 8 | # RUN: llvm-readobj -sections %t.exe | FileCheck --check-prefix=CHECK2 %s | ||
| 9 | |||
| 10 | # RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \ | ||
| 11 | # RUN: /merge:.rsrc=.foo %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RSRC %s | ||
| 12 | # RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \ | ||
| 13 | # RUN: /merge:.foo=.rsrc %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RSRC %s | ||
| 14 | # RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \ | ||
| 15 | # RUN: /merge:.reloc=.foo %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RELOC %s | ||
| 16 | # RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \ | ||
| 17 | # RUN: /merge:.foo=.reloc %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-RELOC %s | ||
| 18 | # RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \ | ||
| 19 | # RUN: /merge:.foo=.foo1 /merge:.foo1=.foo %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-CYCLE %s | ||
| 20 | # RUN: not lld-link /out:%t.exe /entry:main /subsystem:console /force \ | ||
| 21 | # RUN: /merge:.foo=.foo1 /merge:.foo1=.foo2 /merge:.foo2=.foo1 %t.obj /debug 2>&1 | FileCheck --check-prefix=NO-CYCLE %s | ||
| 22 | |||
| 6 | # CHECK: Name: .def | 23 | # CHECK: Name: .def |
| 7 | # CHECK: Name: .abc | 24 | # CHECK: Name: .abc |
| 8 | 25 | ||
| 26 | # CHECK2-NOT: Name: .bar | ||
| 27 | # CHECK2: Name: .abc | ||
| 28 | # CHECK2-NOT: Name: .bar | ||
| 29 | |||
| 30 | # NO-RSRC: /merge: cannot merge '.rsrc' with any section | ||
| 31 | # NO-RELOC: /merge: cannot merge '.reloc' with any section | ||
| 32 | |||
| 33 | # NO-CYCLE: /merge: cycle found for section '.foo' | ||
| 34 | |||
| 9 | --- !COFF | 35 | --- !COFF |
| 10 | header: | 36 | header: |
| 11 | Machine: IMAGE_FILE_MACHINE_AMD64 | 37 | Machine: IMAGE_FILE_MACHINE_AMD64 |
deps/lld/test/COFF/nodefaultlib.test+2-1| ... | @@ -21,7 +21,8 @@ | ... | @@ -21,7 +21,8 @@ |
| 21 | 21 | ||
| 22 | CHECK1: error: could not open hello64.obj: {{[Nn]}}o such file or directory | 22 | CHECK1: error: could not open hello64.obj: {{[Nn]}}o such file or directory |
| 23 | CHECK2: error: could not open hello64: {{[Nn]}}o such file or directory | 23 | CHECK2: error: could not open hello64: {{[Nn]}}o such file or directory |
| 24 | CHECK3: error: {{.*}}hello64.obj: undefined symbol: MessageBoxA | 24 | CHECK3: error: undefined symbol: MessageBoxA |
| 25 | CHECK3-NEXT: >>> referenced by {{.*}}hello64.obj:(main) | ||
| 25 | 26 | ||
| 26 | # RUN: lld-link /libpath:%T /out:%t.exe /entry:main \ | 27 | # RUN: lld-link /libpath:%T /out:%t.exe /entry:main \ |
| 27 | # RUN: /subsystem:console hello64.obj /defaultlib:std64.lib | 28 | # RUN: /subsystem:console hello64.obj /defaultlib:std64.lib |
deps/lld/test/COFF/opt.test+15-9| ... | @@ -1,18 +1,24 @@ | ... | @@ -1,18 +1,24 @@ |
| 1 | # RUN: yaml2obj < %s > %t.obj | 1 | # RUN: yaml2obj < %s > %t.obj |
| 2 | 2 | ||
| 3 | # RUN: lld-link /out:%t.exe /entry:main %t.obj \ | 3 | # RUN: lld-link /out:%t.exe /entry:main %t.obj \ |
| 4 | # RUN: /verbose >& %t.log | 4 | # RUN: /verbose 2>&1 | FileCheck -check-prefix=REF %s |
| 5 | ### FileCheck doesn't like empty input, so write something. | 5 | |
| 6 | # RUN: echo dummy >> %t.log | 6 | # /debug disables the /opt:ref default... |
| 7 | # RUN: FileCheck -check-prefix=CHECK1 %s < %t.log | 7 | # RUN: lld-link /out:%t.exe /debug /entry:main %t.obj \ |
| 8 | # RUN: /verbose 2>&1 | FileCheck -check-prefix=NOREF %s | ||
| 9 | |||
| 10 | # ...unless /profile is passed as well. | ||
| 11 | # RUN: lld-link /out:%t.exe /profile /debug /entry:main %t.obj \ | ||
| 12 | # RUN: /verbose 2>&1 | FileCheck -check-prefix=REF %s | ||
| 13 | |||
| 14 | # RUN: lld-link /out:%t.exe /opt:ref /debug /entry:main %t.obj \ | ||
| 15 | # RUN: /verbose 2>&1 | FileCheck -check-prefix=REF %s | ||
| 8 | 16 | ||
| 9 | # RUN: lld-link /out:%t.exe /entry:main %t.obj \ | 17 | # RUN: lld-link /out:%t.exe /entry:main %t.obj \ |
| 10 | # RUN: /verbose /opt:noref >& %t.log | 18 | # RUN: /verbose /opt:noref /profile 2>&1 | FileCheck -check-prefix=NOREF %s |
| 11 | # RUN: echo dummy >> %t.log | ||
| 12 | # RUN: FileCheck -check-prefix=CHECK2 %s < %t.log | ||
| 13 | 19 | ||
| 14 | # CHECK1: Discarded unused | 20 | # REF: Discarded unused |
| 15 | # CHECK2-NOT: Discarded unused | 21 | # NOREF-NOT: Discarded unused |
| 16 | 22 | ||
| 17 | --- !COFF | 23 | --- !COFF |
| 18 | header: | 24 | header: |
deps/lld/test/COFF/options.test+14| ... | @@ -30,6 +30,16 @@ ENT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA | ... | @@ -30,6 +30,16 @@ ENT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA |
| 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 |
| 31 | NOENT-NOT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA | 31 | NOENT-NOT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA |
| 32 | 32 | ||
| 33 | # RUN: lld-link /out:%t.exe /entry:main /integritycheck %t.obj | ||
| 34 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=INT %s | ||
| 35 | INT: IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY | ||
| 36 | |||
| 37 | # RUN: lld-link /out:%t.exe /entry:main %t.obj | ||
| 38 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOINT %s | ||
| 39 | # 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 | ||
| 41 | NOINT-NOT: IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY | ||
| 42 | |||
| 33 | # RUN: lld-link /out:%t.exe /entry:main %t.obj | 43 | # RUN: lld-link /out:%t.exe /entry:main %t.obj |
| 34 | # 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 |
| 35 | # RUN: lld-link /out:%t.exe /entry:main /nxcompat %t.obj | 45 | # RUN: lld-link /out:%t.exe /entry:main /nxcompat %t.obj |
| ... | @@ -48,4 +58,8 @@ TSAWARE: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE | ... | @@ -48,4 +58,8 @@ TSAWARE: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE |
| 48 | 58 | ||
| 49 | # RUN: lld-link /tsaware:no /out:%t.exe /entry:main %t.obj | 59 | # RUN: lld-link /tsaware:no /out:%t.exe /entry:main %t.obj |
| 50 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOTSAWARE %s | 60 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOTSAWARE %s |
| 61 | # RUN: lld-link /dll /out:%t.dll /entry:main %t.obj | ||
| 62 | # RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOTSAWARE %s | ||
| 63 | # 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 | ||
| 51 | NOTSAWARE-NOT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE | 65 | NOTSAWARE-NOT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE |
deps/lld/test/COFF/order-i386.test created+69| ... | @@ -0,0 +1,69 @@ | ||
| 1 | # RUN: yaml2obj < %s > %t.obj | ||
| 2 | |||
| 3 | # RUN: echo fn1 > %t.order | ||
| 4 | # RUN: echo fn2 >> %t.order | ||
| 5 | |||
| 6 | # RUN: lld-link -entry:fn1 -subsystem:console -opt:noref %t.obj \ | ||
| 7 | # RUN: -lldmap:- -out:%t.exe -order:@%t.order | FileCheck %s | ||
| 8 | # CHECK: fn1 | ||
| 9 | # CHECK: fn2 | ||
| 10 | |||
| 11 | # RUN: lld-link -entry:fn1 -subsystem:console -opt:noref %t.obj \ | ||
| 12 | # RUN: -lldmap:- -out:%t.exe | FileCheck -check-prefix=DEFAULT %s | ||
| 13 | # DEFAULT: fn2 | ||
| 14 | # DEFAULT: fn1 | ||
| 15 | |||
| 16 | --- !COFF | ||
| 17 | header: | ||
| 18 | Machine: IMAGE_FILE_MACHINE_I386 | ||
| 19 | Characteristics: [ ] | ||
| 20 | sections: | ||
| 21 | - Name: '.text' | ||
| 22 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 23 | Alignment: 16 | ||
| 24 | SectionData: CC | ||
| 25 | - Name: '.text' | ||
| 26 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 27 | Alignment: 16 | ||
| 28 | SectionData: CC | ||
| 29 | symbols: | ||
| 30 | - Name: '.text' | ||
| 31 | Value: 0 | ||
| 32 | SectionNumber: 1 | ||
| 33 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 34 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 35 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 36 | SectionDefinition: | ||
| 37 | Length: 1 | ||
| 38 | NumberOfRelocations: 0 | ||
| 39 | NumberOfLinenumbers: 0 | ||
| 40 | CheckSum: 0 | ||
| 41 | Number: 0 | ||
| 42 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 43 | - Name: '.text' | ||
| 44 | Value: 0 | ||
| 45 | SectionNumber: 2 | ||
| 46 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 47 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 48 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 49 | SectionDefinition: | ||
| 50 | Length: 1 | ||
| 51 | NumberOfRelocations: 0 | ||
| 52 | NumberOfLinenumbers: 0 | ||
| 53 | CheckSum: 0 | ||
| 54 | Number: 0 | ||
| 55 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 56 | - Name: _fn2 | ||
| 57 | Value: 0 | ||
| 58 | SectionNumber: 1 | ||
| 59 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 60 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 61 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 62 | - Name: _fn1 | ||
| 63 | Value: 0 | ||
| 64 | SectionNumber: 2 | ||
| 65 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 66 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 67 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 68 | ... | ||
| 69 | |||
deps/lld/test/COFF/order.test+121-15| ... | @@ -1,15 +1,121 @@ | ... | @@ -1,15 +1,121 @@ |
| 1 | # RUN: yaml2obj < %p/Inputs/include1a.yaml > %t1.obj | 1 | # RUN: yaml2obj < %s > %t1.obj |
| 2 | # RUN: yaml2obj < %p/Inputs/include1b.yaml > %t2.obj | 2 | # RUN: yaml2obj < %p/Inputs/order.yaml > %t2.obj |
| 3 | # RUN: yaml2obj < %p/Inputs/include1c.yaml > %t3.obj | 3 | |
| 4 | # RUN: rm -f %t2.lib %t3.lib | 4 | # RUN: echo fn1 > %t.order |
| 5 | # RUN: llvm-ar cru %t2.lib %t2.obj | 5 | # RUN: echo fn2 >> %t.order |
| 6 | # RUN: llvm-ar cru %t3.lib %t3.obj | 6 | # RUN: echo fn3 >> %t.order |
| 7 | # RUN: lld-link /out:%t.exe /entry:main \ | 7 | # RUN: echo fn4 >> %t.order |
| 8 | # RUN: %t1.obj %t2.lib %t3.obj %t3.lib /verbose >& %t.log | 8 | |
| 9 | # RUN: FileCheck %s < %t.log | 9 | # RUN: lld-link -entry:fn1 -subsystem:console -opt:noref -debug %t1.obj %t2.obj \ |
| 10 | 10 | # RUN: -lldmap:- -out:%t.exe -order:@%t.order | FileCheck %s | |
| 11 | CHECK: order.test.tmp1.obj | 11 | # CHECK: fn1 |
| 12 | CHECK: order.test.tmp2.lib | 12 | # CHECK: fn2 |
| 13 | CHECK: order.test.tmp3.obj | 13 | # CHECK: fn3 |
| 14 | CHECK: order.test.tmp3.lib | 14 | # CHECK: fn4 |
| 15 | CHECK: order.test.tmp2.lib(order.test.tmp2.obj) for foo | 15 | # CHECK: unrelated1 |
| 16 | # CHECK: unrelated2 | ||
| 17 | |||
| 18 | # RUN: lld-link -entry:fn1 -subsystem:console -opt:noref -debug %t1.obj %t2.obj \ | ||
| 19 | # RUN: -lldmap:- -ignore:4037 -out:%t.exe | FileCheck -check-prefix=DEFAULT %s | ||
| 20 | # DEFAULT: fn2 | ||
| 21 | # DEFAULT: fn3 | ||
| 22 | # DEFAULT: unrelated1 | ||
| 23 | # DEFAULT: unrelated2 | ||
| 24 | # DEFAULT: fn4 | ||
| 25 | # DEFAULT: fn1 | ||
| 26 | |||
| 27 | # RUN: echo fn1 > %t2.order | ||
| 28 | # RUN: echo fn2 >> %t2.order | ||
| 29 | # RUN: echo fn3 >> %t2.order | ||
| 30 | # RUN: echo fn4 >> %t2.order | ||
| 31 | # RUN: echo foo >> %t2.order | ||
| 32 | # RUN: lld-link -entry:fn1 -subsystem:console -debug %t1.obj %t2.obj \ | ||
| 33 | # RUN: -out:%t.exe -order:@%t2.order 2>&1 | FileCheck -check-prefix=WARN %s | ||
| 34 | # WARN: warning: /order:{{.*}} missing symbol: foo | ||
| 35 | # WARN-NOT: f2 | ||
| 36 | # WARN-NOT: f3 | ||
| 37 | # WARN-NOT: f4 | ||
| 38 | # RUN: lld-link -entry:fn1 -subsystem:console -debug %t1.obj %t2.obj \ | ||
| 39 | # RUN: -out:%t.exe -order:@%t2.order -ignore:4037 2>&1 | \ | ||
| 40 | # RUN: FileCheck -allow-empty -check-prefix=NOWARN %s | ||
| 41 | # NOWARN-NOT: warning: /order:{{.*}} missing symbol: foo | ||
| 42 | # NOWARN-NOT: f2 | ||
| 43 | # NOWARN-NOT: f3 | ||
| 44 | # NOWARN-NOT: f4 | ||
| 45 | |||
| 46 | --- !COFF | ||
| 47 | header: | ||
| 48 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 49 | Characteristics: [ ] | ||
| 50 | sections: | ||
| 51 | - Name: .text | ||
| 52 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 53 | Alignment: 16 | ||
| 54 | SectionData: C3 | ||
| 55 | - Name: .text | ||
| 56 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 57 | Alignment: 16 | ||
| 58 | SectionData: C3 | ||
| 59 | - Name: .text | ||
| 60 | Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] | ||
| 61 | Alignment: 16 | ||
| 62 | SectionData: C3 | ||
| 63 | symbols: | ||
| 64 | - Name: .text | ||
| 65 | Value: 0 | ||
| 66 | SectionNumber: 1 | ||
| 67 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 68 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 69 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 70 | SectionDefinition: | ||
| 71 | Length: 1 | ||
| 72 | NumberOfRelocations: 0 | ||
| 73 | NumberOfLinenumbers: 0 | ||
| 74 | CheckSum: 0 | ||
| 75 | Number: 1 | ||
| 76 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 77 | - Name: fn2 | ||
| 78 | Value: 0 | ||
| 79 | SectionNumber: 1 | ||
| 80 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 81 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 82 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 83 | - Name: .text | ||
| 84 | Value: 0 | ||
| 85 | SectionNumber: 2 | ||
| 86 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 87 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 88 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 89 | SectionDefinition: | ||
| 90 | Length: 1 | ||
| 91 | NumberOfRelocations: 0 | ||
| 92 | NumberOfLinenumbers: 0 | ||
| 93 | CheckSum: 0 | ||
| 94 | Number: 2 | ||
| 95 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 96 | - Name: fn3 | ||
| 97 | Value: 0 | ||
| 98 | SectionNumber: 2 | ||
| 99 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 100 | ComplexType: IMAGE_SYM_DTYPE_FUNCTION | ||
| 101 | StorageClass: IMAGE_SYM_CLASS_EXTERNAL | ||
| 102 | - Name: .text | ||
| 103 | Value: 0 | ||
| 104 | SectionNumber: 3 | ||
| 105 | SimpleType: IMAGE_SYM_TYPE_NULL | ||
| 106 | ComplexType: IMAGE_SYM_DTYPE_NULL | ||
| 107 | StorageClass: IMAGE_SYM_CLASS_STATIC | ||
| 108 | SectionDefinition: | ||
| 109 | Length: 1 | ||
| 110 | NumberOfRelocations: 0 | ||
| 111 | NumberOfLinenumbers: 0 | ||
| 112 | CheckSum: 0 | ||
| 113 | Number: 3 | ||
| 114 | Selection: IMAGE_COMDAT_SELECT_NODUPLICATES | ||
| 115 | - Name: unrelated1 | ||
| 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/output-chars.test created+109| ... | @@ -0,0 +1,109 @@ | ||
| 1 | # RUN: yaml2obj %s > %t.obj | ||
| 2 | # RUN: lld-link /out:%t.dll /entry:__ImageBase /dll %t.obj | ||
| 3 | # RUN: llvm-readobj -sections %t.dll | FileCheck %s | ||
| 4 | # 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 | ||
| 6 | # 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 | ||
| 8 | # 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 | ||
| 10 | |||
| 11 | # CHECK: Name: .foo | ||
| 12 | # CHECK: Characteristics [ | ||
| 13 | # CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 14 | # CHECK-NEXT: IMAGE_SCN_MEM_READ | ||
| 15 | # CHECK-NEXT: ] | ||
| 16 | |||
| 17 | # CHECK: Name: .foo | ||
| 18 | # CHECK: Characteristics [ | ||
| 19 | # CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 20 | # CHECK-NEXT: IMAGE_SCN_MEM_READ | ||
| 21 | # CHECK-NEXT: IMAGE_SCN_MEM_WRITE | ||
| 22 | # CHECK-NEXT: ] | ||
| 23 | |||
| 24 | # SECTION: Name: .foo | ||
| 25 | # SECTION: Characteristics [ | ||
| 26 | # SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 27 | # SECTION-NEXT: IMAGE_SCN_MEM_EXECUTE | ||
| 28 | # SECTION-NEXT: IMAGE_SCN_MEM_READ | ||
| 29 | # SECTION-NEXT: IMAGE_SCN_MEM_WRITE | ||
| 30 | # SECTION-NEXT: ] | ||
| 31 | |||
| 32 | # SECTION: Name: .foo | ||
| 33 | # SECTION: Characteristics [ | ||
| 34 | # SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 35 | # SECTION-NEXT: IMAGE_SCN_MEM_EXECUTE | ||
| 36 | # SECTION-NEXT: IMAGE_SCN_MEM_READ | ||
| 37 | # SECTION-NEXT: IMAGE_SCN_MEM_WRITE | ||
| 38 | # SECTION-NEXT: ] | ||
| 39 | |||
| 40 | # MERGE: Name: .bar | ||
| 41 | # MERGE: Characteristics [ | ||
| 42 | # MERGE-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 43 | # MERGE-NEXT: IMAGE_SCN_MEM_READ | ||
| 44 | # MERGE-NEXT: ] | ||
| 45 | # MERGE-NEXT: SectionData ( | ||
| 46 | # MERGE-NEXT: 0000: 0301 | ||
| 47 | |||
| 48 | # MERGE: Name: .bar | ||
| 49 | # MERGE: Characteristics [ | ||
| 50 | # MERGE-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 51 | # MERGE-NEXT: IMAGE_SCN_MEM_READ | ||
| 52 | # MERGE-NEXT: IMAGE_SCN_MEM_WRITE | ||
| 53 | # MERGE-NEXT: ] | ||
| 54 | # MERGE-NEXT: SectionData ( | ||
| 55 | # MERGE-NEXT: 0000: 04 | ||
| 56 | |||
| 57 | # MERGE: Name: .foo | ||
| 58 | # MERGE: Characteristics [ | ||
| 59 | # MERGE-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 60 | # MERGE-NEXT: IMAGE_SCN_MEM_READ | ||
| 61 | # MERGE-NEXT: IMAGE_SCN_MEM_WRITE | ||
| 62 | # MERGE-NEXT: ] | ||
| 63 | # MERGE-NEXT: SectionData ( | ||
| 64 | # MERGE-NEXT: 0000: 02 | ||
| 65 | |||
| 66 | # MERGE-SECTION: Name: .bar | ||
| 67 | # MERGE-SECTION: Characteristics [ | ||
| 68 | # MERGE-SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 69 | # MERGE-SECTION-NEXT: IMAGE_SCN_MEM_READ | ||
| 70 | # MERGE-SECTION-NEXT: ] | ||
| 71 | |||
| 72 | # MERGE-SECTION: Name: .bar | ||
| 73 | # MERGE-SECTION: Characteristics [ | ||
| 74 | # MERGE-SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 75 | # MERGE-SECTION-NEXT: IMAGE_SCN_MEM_READ | ||
| 76 | # MERGE-SECTION-NEXT: IMAGE_SCN_MEM_WRITE | ||
| 77 | # MERGE-SECTION-NEXT: ] | ||
| 78 | |||
| 79 | # MERGE-SECTION: Name: .foo | ||
| 80 | # MERGE-SECTION: Characteristics [ | ||
| 81 | # MERGE-SECTION-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 82 | # MERGE-SECTION-NEXT: IMAGE_SCN_MEM_EXECUTE | ||
| 83 | # MERGE-SECTION-NEXT: IMAGE_SCN_MEM_READ | ||
| 84 | # MERGE-SECTION-NEXT: IMAGE_SCN_MEM_WRITE | ||
| 85 | # MERGE-SECTION-NEXT: ] | ||
| 86 | |||
| 87 | --- !COFF | ||
| 88 | header: | ||
| 89 | Machine: IMAGE_FILE_MACHINE_AMD64 | ||
| 90 | Characteristics: [ ] | ||
| 91 | sections: | ||
| 92 | - Name: .foo | ||
| 93 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 94 | Alignment: 1 | ||
| 95 | SectionData: 01 | ||
| 96 | - Name: .foo | ||
| 97 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 98 | Alignment: 1 | ||
| 99 | SectionData: 02 | ||
| 100 | - Name: .bar | ||
| 101 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 102 | Alignment: 1 | ||
| 103 | SectionData: 03 | ||
| 104 | - Name: .bar | ||
| 105 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] | ||
| 106 | Alignment: 1 | ||
| 107 | SectionData: 04 | ||
| 108 | symbols: | ||
| 109 | ... | ||
deps/lld/test/COFF/pdata-arm64.yaml+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | # RUN: lld-link /out:%t.exe /entry:func1 /subsystem:console %t.obj | 3 | # RUN: lld-link /out:%t.exe /entry:func1 /subsystem:console %t.obj |
| 4 | # RUN: llvm-objdump -s -section=.pdata %t.exe | FileCheck -check-prefix=PDATA %s | 4 | # RUN: llvm-objdump -s -section=.pdata %t.exe | FileCheck -check-prefix=PDATA %s |
| 5 | 5 | ||
| 6 | # PDATA: 00200000 2500a100 24200000 31002201 | 6 | # PDATA: 00100000 2500a100 24100000 31002201 |
| 7 | 7 | ||
| 8 | --- !COFF | 8 | --- !COFF |
| 9 | header: | 9 | header: |
deps/lld/test/COFF/pdb-comdat.test+5-5| ... | @@ -43,10 +43,10 @@ CHECK-NEXT: ============================================================ | ... | @@ -43,10 +43,10 @@ CHECK-NEXT: ============================================================ |
| 43 | CHECK-NEXT: Records | 43 | CHECK-NEXT: Records |
| 44 | CHECK-NEXT: 84 | S_PROCREF [size = 20] `main` | 44 | CHECK-NEXT: 84 | S_PROCREF [size = 20] `main` |
| 45 | CHECK-NEXT: module = 1, sum name = 0, offset = 120 | 45 | CHECK-NEXT: module = 1, sum name = 0, offset = 120 |
| 46 | CHECK-NEXT: 128 | S_PROCREF [size = 20] `foo` | ||
| 47 | CHECK-NEXT: module = 1, sum name = 0, offset = 208 | ||
| 48 | CHECK-NEXT: 148 | S_PROCREF [size = 20] `bar` | 46 | CHECK-NEXT: 148 | S_PROCREF [size = 20] `bar` |
| 49 | CHECK-NEXT: module = 2, sum name = 0, offset = 120 | 47 | CHECK-NEXT: module = 2, sum name = 0, offset = 120 |
| 48 | CHECK-NEXT: 128 | S_PROCREF [size = 20] `foo` | ||
| 49 | CHECK-NEXT: module = 1, sum name = 0, offset = 208 | ||
| 50 | CHECK-NEXT: 104 | S_GDATA32 [size = 24] `global` | 50 | CHECK-NEXT: 104 | S_GDATA32 [size = 24] `global` |
| 51 | CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000 | 51 | CHECK-NEXT: type = 0x0074 (int), addr = 0000:0000 |
| 52 | CHECK-NEXT: 168 | S_GDATA32 [size = 24] `global` | 52 | CHECK-NEXT: 168 | S_GDATA32 [size = 24] `global` |
| ... | @@ -61,7 +61,7 @@ CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, | ... | @@ -61,7 +61,7 @@ CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, |
| 61 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 | 61 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 |
| 62 | CHECK: flags = security checks | hot patchable | 62 | CHECK: flags = security checks | hot patchable |
| 63 | CHECK: 120 | S_GPROC32 [size = 44] `main` | 63 | CHECK: 120 | S_GPROC32 [size = 44] `main` |
| 64 | CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 24 | 64 | CHECK: parent = 0, end = 196, addr = 0001:0000, code size = 24 |
| 65 | CHECK: debug start = 4, debug end = 19, flags = none | 65 | CHECK: debug start = 4, debug end = 19, flags = none |
| 66 | CHECK: 164 | S_FRAMEPROC [size = 32] | 66 | CHECK: 164 | S_FRAMEPROC [size = 32] |
| 67 | CHECK: size = 40, padding size = 0, offset to padding = 0 | 67 | CHECK: size = 40, padding size = 0, offset to padding = 0 |
| ... | @@ -70,7 +70,7 @@ CHECK: flags = has async eh | opt speed | ... | @@ -70,7 +70,7 @@ CHECK: flags = has async eh | opt speed |
| 70 | CHECK: 196 | S_END [size = 4] | 70 | CHECK: 196 | S_END [size = 4] |
| 71 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `0x100A` | 71 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `0x100A` |
| 72 | CHECK: 208 | S_GPROC32 [size = 44] `foo` | 72 | CHECK: 208 | S_GPROC32 [size = 44] `foo` |
| 73 | CHECK: parent = 0, end = 284, addr = 0002:0032, code size = 15 | 73 | CHECK: parent = 0, end = 284, addr = 0001:0032, code size = 15 |
| 74 | CHECK: debug start = 0, debug end = 14, flags = none | 74 | CHECK: debug start = 0, debug end = 14, flags = none |
| 75 | CHECK: 252 | S_FRAMEPROC [size = 32] | 75 | CHECK: 252 | S_FRAMEPROC [size = 32] |
| 76 | CHECK: size = 0, padding size = 0, offset to padding = 0 | 76 | CHECK: size = 0, padding size = 0, offset to padding = 0 |
| ... | @@ -84,7 +84,7 @@ CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, l | ... | @@ -84,7 +84,7 @@ CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, l |
| 84 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 | 84 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 |
| 85 | CHECK: flags = security checks | hot patchable | 85 | CHECK: flags = security checks | hot patchable |
| 86 | CHECK: 120 | S_GPROC32 [size = 44] `bar` | 86 | CHECK: 120 | S_GPROC32 [size = 44] `bar` |
| 87 | CHECK: parent = 0, end = 196, addr = 0002:0048, code size = 14 | 87 | CHECK: parent = 0, end = 196, addr = 0001:0048, code size = 14 |
| 88 | CHECK: debug start = 4, debug end = 9, flags = none | 88 | CHECK: debug start = 4, debug end = 9, flags = none |
| 89 | CHECK: 164 | S_FRAMEPROC [size = 32] | 89 | CHECK: 164 | S_FRAMEPROC [size = 32] |
| 90 | CHECK: size = 40, padding size = 0, offset to padding = 0 | 90 | CHECK: size = 40, padding size = 0, offset to padding = 0 |
deps/lld/test/COFF/pdb-diff.test deleted-215| ... | @@ -1,215 +0,0 @@ | ||
| 1 | This test verifies that we produce PDBs compatible with MSVC in various ways. | ||
| 2 | We check in a cl-generated object file, PDB, and original source which serve | ||
| 3 | as the "baseline" for us to measure against. Then we link the same object | ||
| 4 | file with LLD and compare the two PDBs. Since the baseline object file and | ||
| 5 | PDB are already checked in, we just run LLD on the object file. | ||
| 6 | |||
| 7 | RUN: rm -f %T/pdb-diff-lld.pdb %T/pdb-diff-lld.exe | ||
| 8 | RUN: lld-link /debug /pdb:%T/pdb-diff-lld.pdb /out:%T/pdb-diff-lld.exe /nodefaultlib \ | ||
| 9 | RUN: /entry:main %S/Inputs/pdb-diff.obj | ||
| 10 | RUN: llvm-pdbutil diff -result -values=false -left-bin-root=%S -right-bin-root=D:/src/llvm-mono/lld/test/COFF/ \ | ||
| 11 | RUN: %T/pdb-diff-lld.pdb %S/Inputs/pdb-diff-cl.pdb | FileCheck %s | ||
| 12 | |||
| 13 | CHECK: ---------------------- | ||
| 14 | CHECK-NEXT: | MSF Super Block | | ||
| 15 | CHECK-NEXT: |----------------+---| | ||
| 16 | CHECK-NEXT: | File | | | ||
| 17 | CHECK-NEXT: |----------------+---| | ||
| 18 | CHECK-NEXT: | Block Size | I | | ||
| 19 | CHECK-NEXT: |----------------+---| | ||
| 20 | CHECK-NEXT: | Block Count | | ||
| 21 | CHECK-NEXT: |----------------+---| | ||
| 22 | CHECK-NEXT: | Unknown 1 | I | | ||
| 23 | CHECK-NEXT: |----------------+---| | ||
| 24 | CHECK-NEXT: | Directory Size | | ||
| 25 | CHECK-NEXT: |----------------+---| | ||
| 26 | CHECK-NEXT: ------------------------------------ | ||
| 27 | CHECK-NEXT: | Stream Directory | | ||
| 28 | CHECK-NEXT: |------------------------------+---| | ||
| 29 | CHECK-NEXT: | File | | | ||
| 30 | CHECK-NEXT: |------------------------------+---| | ||
| 31 | CHECK-NEXT: | Stream Count | I | | ||
| 32 | CHECK-NEXT: |------------------------------+---| | ||
| 33 | CHECK-NEXT: | Old MSF Directory | I | | ||
| 34 | CHECK-NEXT: |------------------------------+---| | ||
| 35 | CHECK-NEXT: | PDB Stream | I | | ||
| 36 | CHECK-NEXT: |------------------------------+---| | ||
| 37 | CHECK-NEXT: | TPI Stream | I | | ||
| 38 | CHECK-NEXT: |------------------------------+---| | ||
| 39 | CHECK-NEXT: | DBI Stream | I | | ||
| 40 | CHECK-NEXT: |------------------------------+---| | ||
| 41 | CHECK-NEXT: | IPI Stream | I | | ||
| 42 | CHECK-NEXT: |------------------------------+---| | ||
| 43 | CHECK-NEXT: | New FPO Data | {{[EI]}} | | ||
| 44 | CHECK-NEXT: |------------------------------+---| | ||
| 45 | CHECK-NEXT: | Section Header Data | {{[EI]}} | | ||
| 46 | CHECK-NEXT: |------------------------------+---| | ||
| 47 | CHECK-NEXT: | Named Stream "/names" | {{[EI]}} | | ||
| 48 | CHECK-NEXT: |------------------------------+---| | ||
| 49 | CHECK-NEXT: | Named Stream "/LinkInfo" | {{[EI]}} | | ||
| 50 | CHECK-NEXT: |------------------------------+---| | ||
| 51 | CHECK-NEXT: | Module "Inputs\pdb-diff.obj" | {{[EI]}} | | ||
| 52 | CHECK-NEXT: |------------------------------+---| | ||
| 53 | CHECK-NEXT: | Module "* Linker *" | {{[EI]}} | | ||
| 54 | CHECK-NEXT: |------------------------------+---| | ||
| 55 | CHECK-NEXT: | TPI Hash | {{[EI]}} | | ||
| 56 | CHECK-NEXT: |------------------------------+---| | ||
| 57 | CHECK-NEXT: | IPI Hash | {{[EI]}} | | ||
| 58 | CHECK-NEXT: |------------------------------+---| | ||
| 59 | CHECK-NEXT: | Public Symbol Hash | {{[EI]}} | | ||
| 60 | CHECK-NEXT: |------------------------------+---| | ||
| 61 | CHECK-NEXT: | Global Symbol Hash | {{[EI]}} | | ||
| 62 | CHECK-NEXT: |------------------------------+---| | ||
| 63 | CHECK-NEXT: | Symbol Records | {{[EI]}} | | ||
| 64 | CHECK-NEXT: |------------------------------+---| | ||
| 65 | CHECK-NEXT: ------------------------------------ | ||
| 66 | CHECK-NEXT: | String Table | | ||
| 67 | CHECK-NEXT: |------------------------------+---| | ||
| 68 | CHECK-NEXT: | File | | | ||
| 69 | CHECK-NEXT: |------------------------------+---| | ||
| 70 | CHECK-NEXT: | Number of Strings | D | | ||
| 71 | CHECK-NEXT: |------------------------------+---| | ||
| 72 | CHECK-NEXT: | Hash Version | I | | ||
| 73 | CHECK-NEXT: |------------------------------+---| | ||
| 74 | CHECK-NEXT: | Byte Size | | ||
| 75 | CHECK-NEXT: |------------------------------+---| | ||
| 76 | CHECK-NEXT: | Signature | I | | ||
| 77 | CHECK-NEXT: |------------------------------+---| | ||
| 78 | CHECK-NEXT: | Empty Strings | | ||
| 79 | CHECK-NEXT: |------------------------------+---| | ||
| 80 | CHECK-NEXT: | {{.*}}pdb-diff.cpp | {{[EI]}} | | ||
| 81 | CHECK-NEXT: |------------------------------+---| | ||
| 82 | CHECK-NEXT: | $T0 $ebp = $...p $T0 8 + = | D | | ||
| 83 | CHECK-NEXT: |------------------------------+---| | ||
| 84 | CHECK-NEXT: | d:\src\llvm-...er internal) | D | | ||
| 85 | CHECK-NEXT: |------------------------------+---| | ||
| 86 | CHECK-NEXT: ---------------------------- | ||
| 87 | CHECK-NEXT: | PDB Stream | | ||
| 88 | CHECK-NEXT: |----------------------+---| | ||
| 89 | CHECK-NEXT: | File | | | ||
| 90 | CHECK-NEXT: |----------------------+---| | ||
| 91 | CHECK-NEXT: | Stream Size | | ||
| 92 | CHECK-NEXT: |----------------------+---| | ||
| 93 | CHECK-NEXT: | Age | I | | ||
| 94 | CHECK-NEXT: |----------------------+---| | ||
| 95 | CHECK-NEXT: | Guid | D | | ||
| 96 | CHECK-NEXT: |----------------------+---| | ||
| 97 | CHECK-NEXT: | Signature | D | | ||
| 98 | CHECK-NEXT: |----------------------+---| | ||
| 99 | CHECK-NEXT: | Version | I | | ||
| 100 | CHECK-NEXT: |----------------------+---| | ||
| 101 | CHECK-NEXT: | Features (set) | I | | ||
| 102 | CHECK-NEXT: |----------------------+---| | ||
| 103 | CHECK-NEXT: | Feature | I | | ||
| 104 | CHECK-NEXT: |----------------------+---| | ||
| 105 | CHECK-NEXT: | Named Stream Size | | ||
| 106 | CHECK-NEXT: |----------------------+---| | ||
| 107 | CHECK-NEXT: | Named Streams (map) | {{[EI]}} | | ||
| 108 | CHECK-NEXT: |----------------------+---| | ||
| 109 | CHECK-NEXT: | /names | {{[EI]}} | | ||
| 110 | CHECK-NEXT: |----------------------+---| | ||
| 111 | CHECK-NEXT: | /LinkInfo | {{[EI]}} | | ||
| 112 | CHECK-NEXT: |----------------------+---| | ||
| 113 | CHECK-NEXT: ---------------------------------------------- | ||
| 114 | CHECK-NEXT: | DBI Stream | | ||
| 115 | CHECK-NEXT: |----------------------------------------+---| | ||
| 116 | CHECK-NEXT: | File | | | ||
| 117 | CHECK-NEXT: |----------------------------------------+---| | ||
| 118 | CHECK-NEXT: | Dbi Version | I | | ||
| 119 | CHECK-NEXT: |----------------------------------------+---| | ||
| 120 | CHECK-NEXT: | Age | I | | ||
| 121 | CHECK-NEXT: |----------------------------------------+---| | ||
| 122 | CHECK-NEXT: | Machine | I | | ||
| 123 | CHECK-NEXT: |----------------------------------------+---| | ||
| 124 | CHECK-NEXT: | Flags | D | | ||
| 125 | CHECK-NEXT: |----------------------------------------+---| | ||
| 126 | CHECK-NEXT: | Build Major | D | | ||
| 127 | CHECK-NEXT: |----------------------------------------+---| | ||
| 128 | CHECK-NEXT: | Build Minor | D | | ||
| 129 | CHECK-NEXT: |----------------------------------------+---| | ||
| 130 | CHECK-NEXT: | Build Number | D | | ||
| 131 | CHECK-NEXT: |----------------------------------------+---| | ||
| 132 | CHECK-NEXT: | PDB DLL Version | D | | ||
| 133 | CHECK-NEXT: |----------------------------------------+---| | ||
| 134 | CHECK-NEXT: | PDB DLL RBLD | I | | ||
| 135 | CHECK-NEXT: |----------------------------------------+---| | ||
| 136 | CHECK-NEXT: | DBG (FPO) | I | | ||
| 137 | CHECK-NEXT: |----------------------------------------+---| | ||
| 138 | CHECK-NEXT: | DBG (Exception) | I | | ||
| 139 | CHECK-NEXT: |----------------------------------------+---| | ||
| 140 | CHECK-NEXT: | DBG (Fixup) | I | | ||
| 141 | CHECK-NEXT: |----------------------------------------+---| | ||
| 142 | CHECK-NEXT: | DBG (OmapToSrc) | I | | ||
| 143 | CHECK-NEXT: |----------------------------------------+---| | ||
| 144 | CHECK-NEXT: | DBG (OmapFromSrc) | I | | ||
| 145 | CHECK-NEXT: |----------------------------------------+---| | ||
| 146 | CHECK-NEXT: | DBG (SectionHdr) | {{[EI]}} | | ||
| 147 | CHECK-NEXT: |----------------------------------------+---| | ||
| 148 | CHECK-NEXT: | DBG (TokenRidMap) | I | | ||
| 149 | CHECK-NEXT: |----------------------------------------+---| | ||
| 150 | CHECK-NEXT: | DBG (Xdata) | I | | ||
| 151 | CHECK-NEXT: |----------------------------------------+---| | ||
| 152 | CHECK-NEXT: | DBG (Pdata) | I | | ||
| 153 | CHECK-NEXT: |----------------------------------------+---| | ||
| 154 | CHECK-NEXT: | DBG (NewFPO) | {{[EI]}} | | ||
| 155 | CHECK-NEXT: |----------------------------------------+---| | ||
| 156 | CHECK-NEXT: | DBG (SectionHdrOrig) | I | | ||
| 157 | CHECK-NEXT: |----------------------------------------+---| | ||
| 158 | CHECK-NEXT: | Globals Stream | {{[EI]}} | | ||
| 159 | CHECK-NEXT: |----------------------------------------+---| | ||
| 160 | CHECK-NEXT: | Publics Stream | {{[EI]}} | | ||
| 161 | CHECK-NEXT: |----------------------------------------+---| | ||
| 162 | CHECK-NEXT: | Symbol Records | {{[EI]}} | | ||
| 163 | CHECK-NEXT: |----------------------------------------+---| | ||
| 164 | CHECK-NEXT: | Has CTypes | I | | ||
| 165 | CHECK-NEXT: |----------------------------------------+---| | ||
| 166 | CHECK-NEXT: | Is Incrementally Linked | D | | ||
| 167 | CHECK-NEXT: |----------------------------------------+---| | ||
| 168 | CHECK-NEXT: | Is Stripped | I | | ||
| 169 | CHECK-NEXT: |----------------------------------------+---| | ||
| 170 | CHECK-NEXT: | Module Count | I | | ||
| 171 | CHECK-NEXT: |----------------------------------------+---| | ||
| 172 | CHECK-NEXT: | Source File Count | I | | ||
| 173 | CHECK-NEXT: |----------------------------------------+---| | ||
| 174 | CHECK-NEXT: | Module "Inputs\pdb-diff.obj" | | ||
| 175 | CHECK-NEXT: |----------------------------------------+---| | ||
| 176 | CHECK-NEXT: | - Modi | I | | ||
| 177 | CHECK-NEXT: |----------------------------------------+---| | ||
| 178 | CHECK-NEXT: | - Obj File Name | {{[EI]}} | | ||
| 179 | CHECK-NEXT: |----------------------------------------+---| | ||
| 180 | CHECK-NEXT: | - Debug Stream | {{[EI]}} | | ||
| 181 | CHECK-NEXT: |----------------------------------------+---| | ||
| 182 | CHECK-NEXT: | - C11 Byte Size | I | | ||
| 183 | CHECK-NEXT: |----------------------------------------+---| | ||
| 184 | CHECK-NEXT: | - C13 Byte Size | I | | ||
| 185 | CHECK-NEXT: |----------------------------------------+---| | ||
| 186 | CHECK-NEXT: | - # of files | I | | ||
| 187 | CHECK-NEXT: |----------------------------------------+---| | ||
| 188 | CHECK-NEXT: | - Pdb File Path Index | I | | ||
| 189 | CHECK-NEXT: |----------------------------------------+---| | ||
| 190 | CHECK-NEXT: | - Source File Name Index | I | | ||
| 191 | CHECK-NEXT: |----------------------------------------+---| | ||
| 192 | CHECK-NEXT: | - Symbol Byte Size | | ||
| 193 | CHECK-NEXT: |----------------------------------------+---| | ||
| 194 | CHECK-NEXT: | Module "* Linker *" | | ||
| 195 | CHECK-NEXT: |----------------------------------------+---| | ||
| 196 | CHECK-NEXT: | - Modi | I | | ||
| 197 | CHECK-NEXT: |----------------------------------------+---| | ||
| 198 | CHECK-NEXT: | - Obj File Name | I | | ||
| 199 | CHECK-NEXT: |----------------------------------------+---| | ||
| 200 | CHECK-NEXT: | - Debug Stream | {{[EI]}} | | ||
| 201 | CHECK-NEXT: |----------------------------------------+---| | ||
| 202 | CHECK-NEXT: | - C11 Byte Size | I | | ||
| 203 | CHECK-NEXT: |----------------------------------------+---| | ||
| 204 | CHECK-NEXT: | - C13 Byte Size | I | | ||
| 205 | CHECK-NEXT: |----------------------------------------+---| | ||
| 206 | CHECK-NEXT: | - # of files | I | | ||
| 207 | CHECK-NEXT: |----------------------------------------+---| | ||
| 208 | CHECK-NEXT: | - Pdb File Path Index | {{[EI]}} | | ||
| 209 | CHECK-NEXT: |----------------------------------------+---| | ||
| 210 | CHECK-NEXT: | - Source File Name Index | {{[EI]}} | | ||
| 211 | CHECK-NEXT: |----------------------------------------+---| | ||
| 212 | CHECK-NEXT: | - Symbol Byte Size | | ||
| 213 | CHECK-NEXT: |----------------------------------------+---| | ||
| 214 | |||
| 215 | |||
deps/lld/test/COFF/pdb-exe-path-dots.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 -rf %t | ||
| 4 | RUN: mkdir %t | ||
| 5 | RUN: mkdir %t/foo | ||
| 6 | RUN: lld-link /debug /pdb:%t/foo/./out.pdb /out:%t/out.exe /entry:main /nodefaultlib \ | ||
| 7 | RUN: %t1.obj %t2.obj | ||
| 8 | RUN: llvm-readobj -coff-debug-directory %t/out.exe | FileCheck %s | ||
| 9 | |||
| 10 | CHECK: PDBFileName: {{.*}}tmp{{/|\\}}foo{{/|\\}}out.pdb | ||
| \ No newline at end of file | |||
deps/lld/test/COFF/pdb-file-static.test created+51| ... | @@ -0,0 +1,51 @@ | ||
| 1 | # RUN: yaml2obj %S/Inputs/pdb-file-statics-a.yaml > %t.a.obj | ||
| 2 | # RUN: yaml2obj %S/Inputs/pdb-file-statics-b.yaml > %t.b.obj | ||
| 3 | # RUN: lld-link %t.a.obj %t.b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb | ||
| 4 | # RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | ||
| 5 | |||
| 6 | # S_FILESTATIC records are unique in that they refer to the string table, but | ||
| 7 | # they do *not* go through the file checksums table. They refer directly to | ||
| 8 | # the string table. This makes for special handling in the linker, so it | ||
| 9 | # deserves a custom test. | ||
| 10 | |||
| 11 | # Clang doesn't currently generate these records, but MSVC does, so we have to | ||
| 12 | # be able to correctly link them. These records are only generated when | ||
| 13 | # optimizations are turned on. | ||
| 14 | |||
| 15 | # // a.cpp | ||
| 16 | # // cl.exe /Z7 /O1 /c a.cpp | ||
| 17 | # static int x = 0; | ||
| 18 | # | ||
| 19 | # void b(int); | ||
| 20 | # | ||
| 21 | # void a(int) { | ||
| 22 | # if (x) | ||
| 23 | # b(x); | ||
| 24 | # } | ||
| 25 | # | ||
| 26 | # int main(int argc, char **argv) { | ||
| 27 | # a(argc); | ||
| 28 | # return x; | ||
| 29 | # } | ||
| 30 | # | ||
| 31 | # // b.cpp | ||
| 32 | # // cl.exe /Z7 /O1 /c a.cpp | ||
| 33 | # void a(int); | ||
| 34 | # | ||
| 35 | # static int y = 0; | ||
| 36 | # | ||
| 37 | # void b(int) { | ||
| 38 | # if (y) | ||
| 39 | # a(y); | ||
| 40 | # } | ||
| 41 | |||
| 42 | # CHECK: Symbols | ||
| 43 | # CHECK: ============================================================ | ||
| 44 | # CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`: | ||
| 45 | # CHECK: 232 | S_FILESTATIC [size = 16] `x` | ||
| 46 | # CHECK-NEXT: type = 0x0074 (int), file name = 2 (D:\src\llvmbuild\cl\Debug\x64\a.obj), flags = enreg global | enreg static | ||
| 47 | # CHECK: Mod 0001 | `{{.*}}b.obj`: | ||
| 48 | # CHECK: 232 | S_FILESTATIC [size = 16] `y` | ||
| 49 | # CHECK-NEXT: type = 0x0074 (int), file name = 74 (D:\src\llvmbuild\cl\Debug\x64\b.obj), flags = enreg global | enreg static | ||
| 50 | # CHECK-LABEL: Mod 0002 | `* Linker *`: | ||
| 51 | |||
deps/lld/test/COFF/pdb-global-gc.yaml+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: yaml2obj %s -o %t.obj | 2 | # RUN: yaml2obj %s -o %t.obj |
| 2 | # RUN: llvm-mc %S/Inputs/pdb-global-gc.s -triple x86_64-windows-msvc -filetype=obj -o %t2.obj | 3 | # RUN: llvm-mc %S/Inputs/pdb-global-gc.s -triple x86_64-windows-msvc -filetype=obj -o %t2.obj |
| 3 | # RUN: lld-link %t.obj %t2.obj -debug -entry:main \ | 4 | # RUN: lld-link %t.obj %t2.obj -debug -entry:main \ |
deps/lld/test/COFF/pdb-global-hashes.test+1-1| ... | @@ -83,7 +83,7 @@ CHECK-NEXT: ============================================================ | ... | @@ -83,7 +83,7 @@ CHECK-NEXT: ============================================================ |
| 83 | CHECK-NEXT: Showing 6 records | 83 | CHECK-NEXT: Showing 6 records |
| 84 | CHECK-NEXT: 0x1000 | LF_FUNC_ID [size = 20] | 84 | CHECK-NEXT: 0x1000 | LF_FUNC_ID [size = 20] |
| 85 | CHECK-NEXT: name = main, type = 0x1002, parent scope = <no type> | 85 | CHECK-NEXT: name = main, type = 0x1002, parent scope = <no type> |
| 86 | CHECK-NEXT: 0x1001 | LF_STRING_ID [size = 48] ID: <no type>, String: D:\src\llvmbuild\clang\Debug\x86\obj.h | 86 | CHECK-NEXT: 0x1001 | LF_STRING_ID [size = {{.*}}] ID: <no type>, String: {{.*}}obj.h |
| 87 | CHECK-NEXT: 0x1002 | LF_UDT_SRC_LINE [size = 16] | 87 | CHECK-NEXT: 0x1002 | LF_UDT_SRC_LINE [size = 16] |
| 88 | CHECK-NEXT: udt = 0x1008, file = 4097, line = 2 | 88 | CHECK-NEXT: udt = 0x1008, file = 4097, line = 2 |
| 89 | CHECK-NEXT: 0x1003 | LF_MFUNC_ID [size = 16] | 89 | CHECK-NEXT: 0x1003 | LF_MFUNC_ID [size = 16] |
deps/lld/test/COFF/pdb-globals-dia-func-collision3.test created+81| ... | @@ -0,0 +1,81 @@ | ||
| 1 | REQUIRES: diasdk | ||
| 2 | |||
| 3 | Input object file reconstruction: | ||
| 4 | |||
| 5 | ; // foo.cpp | ||
| 6 | ; void LJPwNRh() {} | ||
| 7 | ; void HGfxvKdQO() {} | ||
| 8 | ; void wuN() {} | ||
| 9 | ; void tEo() {} | ||
| 10 | ; void VUo() {} | ||
| 11 | ; void teO() {} | ||
| 12 | ; void bqSuLGQgWa() {} | ||
| 13 | ; void SyJYcL() {} | ||
| 14 | ; void OUV() {} | ||
| 15 | ; void quH() {} | ||
| 16 | ; void rbEaPKrlrRwk() {} | ||
| 17 | ; void oet() {} | ||
| 18 | ; void tuM() {} | ||
| 19 | ; void LuU() {} | ||
| 20 | ; void loxueqJLH() {} | ||
| 21 | ; void QplRJuDs() {} | ||
| 22 | ; void rWDokkLG() {} | ||
| 23 | ; void sEH() {} | ||
| 24 | ; void pui() {} | ||
| 25 | ; void xoZvxw() {} | ||
| 26 | ; | ||
| 27 | ; int main(int argc, char **argv) { | ||
| 28 | ; return 0; | ||
| 29 | ; } | ||
| 30 | |||
| 31 | clang-cl /Z7 /GS- /GR- /c main.cpp /Foglobals-dia-func-collision3.obj | ||
| 32 | |||
| 33 | RUN: lld-link /debug /nodefaultlib /incremental:no /entry:main /out:%t.exe %S/Inputs/globals-dia-func-collision3.obj | ||
| 34 | RUN: llvm-pdbutil pretty -with-name=LuU -with-name=oet -with-name=OUV -with-name=pui \ | ||
| 35 | RUN: -with-name=quH -with-name=sEH -with-name=teO -with-name=tEo \ | ||
| 36 | RUN: -with-name=tuM -with-name=VUo -with-name=wuN -with-name=SyJYcL \ | ||
| 37 | RUN: -with-name=xoZvxw -with-name=LJPwNRh -with-name=QplRJuDs -with-name=rWDokkLG \ | ||
| 38 | RUN: -with-name=HGfxvKdQO -with-name=loxueqJLH -with-name=bqSuLGQgWa -with-name=rbEaPKrlrRwk \ | ||
| 39 | RUN: %t.pdb | FileCheck %s | ||
| 40 | |||
| 41 | |||
| 42 | CHECK: [1 occurrences] - LuU | ||
| 43 | CHECK-NEXT: func [0x000010d0+ 0 - 0x000010d1- 1 | sizeof= 1] (FPO) void __cdecl LuU() | ||
| 44 | CHECK-NEXT: [1 occurrences] - oet | ||
| 45 | CHECK-NEXT: func [0x000010b0+ 0 - 0x000010b1- 1 | sizeof= 1] (FPO) void __cdecl oet() | ||
| 46 | CHECK-NEXT: [1 occurrences] - OUV | ||
| 47 | CHECK-NEXT: func [0x00001080+ 0 - 0x00001081- 1 | sizeof= 1] (FPO) void __cdecl OUV() | ||
| 48 | CHECK-NEXT: [1 occurrences] - pui | ||
| 49 | CHECK-NEXT: func [0x00001120+ 0 - 0x00001121- 1 | sizeof= 1] (FPO) void __cdecl pui() | ||
| 50 | CHECK-NEXT: [1 occurrences] - quH | ||
| 51 | CHECK-NEXT: func [0x00001090+ 0 - 0x00001091- 1 | sizeof= 1] (FPO) void __cdecl quH() | ||
| 52 | CHECK-NEXT: [1 occurrences] - sEH | ||
| 53 | CHECK-NEXT: func [0x00001110+ 0 - 0x00001111- 1 | sizeof= 1] (FPO) void __cdecl sEH() | ||
| 54 | CHECK-NEXT: [1 occurrences] - teO | ||
| 55 | CHECK-NEXT: func [0x00001050+ 0 - 0x00001051- 1 | sizeof= 1] (FPO) void __cdecl teO() | ||
| 56 | CHECK-NEXT: [1 occurrences] - tEo | ||
| 57 | CHECK-NEXT: func [0x00001030+ 0 - 0x00001031- 1 | sizeof= 1] (FPO) void __cdecl tEo() | ||
| 58 | CHECK-NEXT: [1 occurrences] - tuM | ||
| 59 | CHECK-NEXT: func [0x000010c0+ 0 - 0x000010c1- 1 | sizeof= 1] (FPO) void __cdecl tuM() | ||
| 60 | CHECK-NEXT: [1 occurrences] - VUo | ||
| 61 | CHECK-NEXT: func [0x00001040+ 0 - 0x00001041- 1 | sizeof= 1] (FPO) void __cdecl VUo() | ||
| 62 | CHECK-NEXT: [1 occurrences] - wuN | ||
| 63 | CHECK-NEXT: func [0x00001020+ 0 - 0x00001021- 1 | sizeof= 1] (FPO) void __cdecl wuN() | ||
| 64 | CHECK-NEXT: [1 occurrences] - SyJYcL | ||
| 65 | CHECK-NEXT: func [0x00001070+ 0 - 0x00001071- 1 | sizeof= 1] (FPO) void __cdecl SyJYcL() | ||
| 66 | CHECK-NEXT: [1 occurrences] - xoZvxw | ||
| 67 | CHECK-NEXT: func [0x00001130+ 0 - 0x00001131- 1 | sizeof= 1] (FPO) void __cdecl xoZvxw() | ||
| 68 | CHECK-NEXT: [1 occurrences] - LJPwNRh | ||
| 69 | CHECK-NEXT: func [0x00001000+ 0 - 0x00001001- 1 | sizeof= 1] (FPO) void __cdecl LJPwNRh() | ||
| 70 | CHECK-NEXT: [1 occurrences] - QplRJuDs | ||
| 71 | CHECK-NEXT: func [0x000010f0+ 0 - 0x000010f1- 1 | sizeof= 1] (FPO) void __cdecl QplRJuDs() | ||
| 72 | CHECK-NEXT: [1 occurrences] - rWDokkLG | ||
| 73 | CHECK-NEXT: func [0x00001100+ 0 - 0x00001101- 1 | sizeof= 1] (FPO) void __cdecl rWDokkLG() | ||
| 74 | CHECK-NEXT: [1 occurrences] - HGfxvKdQO | ||
| 75 | CHECK-NEXT: func [0x00001010+ 0 - 0x00001011- 1 | sizeof= 1] (FPO) void __cdecl HGfxvKdQO() | ||
| 76 | CHECK-NEXT: [1 occurrences] - loxueqJLH | ||
| 77 | CHECK-NEXT: func [0x000010e0+ 0 - 0x000010e1- 1 | sizeof= 1] (FPO) void __cdecl loxueqJLH() | ||
| 78 | CHECK-NEXT: [1 occurrences] - bqSuLGQgWa | ||
| 79 | CHECK-NEXT: func [0x00001060+ 0 - 0x00001061- 1 | sizeof= 1] (FPO) void __cdecl bqSuLGQgWa() | ||
| 80 | CHECK-NEXT: [1 occurrences] - rbEaPKrlrRwk | ||
| 81 | CHECK-NEXT: func [0x000010a0+ 0 - 0x000010a1- 1 | sizeof= 1] (FPO) void __cdecl rbEaPKrlrRwk() | ||
deps/lld/test/COFF/pdb-globals-dia-vfunc-collision.test created+42| ... | @@ -0,0 +1,42 @@ | ||
| 1 | REQUIRES: diasdk | ||
| 2 | |||
| 3 | Input object file reconstruction: | ||
| 4 | |||
| 5 | ; // main.cpp | ||
| 6 | ; struct S { | ||
| 7 | ; // Function names are chosen specifically to generate hash collisions in the | ||
| 8 | ; // GSI hash table. | ||
| 9 | ; virtual int A307() { return 102; } | ||
| 10 | ; virtual int A400() { return 12; } | ||
| 11 | ; virtual int A206() { return 201; } | ||
| 12 | ; virtual int A105() { return 300; } | ||
| 13 | ; }; | ||
| 14 | ; | ||
| 15 | ; struct T : public S { | ||
| 16 | ; int A105() override { return 300; } | ||
| 17 | ; int A307() override { return 102; } | ||
| 18 | ; int A206() override { return 201; } | ||
| 19 | ; int A400() override { return 12; } | ||
| 20 | ; }; | ||
| 21 | ; | ||
| 22 | ; int main(int argc, char **argv) { | ||
| 23 | ; T s; | ||
| 24 | ; return s.A105() + s.A206() + s.A307() + s.A400(); | ||
| 25 | ; } | ||
| 26 | |||
| 27 | clang-cl /Z7 /GS- /GR- /c main.cpp /Foglobals-dia-vfunc-collision.obj | ||
| 28 | |||
| 29 | RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe %S/Inputs/globals-dia-vfunc-collision.obj | ||
| 30 | RUN: llvm-pdbutil pretty -classes %t.pdb | FileCheck %s | ||
| 31 | |||
| 32 | CHECK: struct T | ||
| 33 | CHECK: func [0x000010c0+ 0 - 0x000010dd-29 | sizeof= 29] (FPO) virtual {{.*}}A105() | ||
| 34 | CHECK: func [0x00001100+ 0 - 0x0000111b-27 | sizeof= 27] (FPO) virtual {{.*}}A307() | ||
| 35 | CHECK: func [0x000010e0+ 0 - 0x000010fd-29 | sizeof= 29] (FPO) virtual {{.*}}A206() | ||
| 36 | CHECK: func [0x00001120+ 0 - 0x0000113b-27 | sizeof= 27] (FPO) virtual {{.*}}A400() | ||
| 37 | |||
| 38 | CHECK: struct S | ||
| 39 | CHECK: func [0x00001160+ 0 - 0x0000116c-12 | sizeof= 12] (FPO) virtual {{.*}}A307() | ||
| 40 | CHECK: func [0x00001170+ 0 - 0x0000117c-12 | sizeof= 12] (FPO) virtual {{.*}}A400() | ||
| 41 | CHECK: func [0x00001180+ 0 - 0x0000118c-12 | sizeof= 12] (FPO) virtual {{.*}}A206() | ||
| 42 | CHECK: func [0x00001190+ 0 - 0x0000119c-12 | sizeof= 12] (FPO) virtual {{.*}}A105() | ||
deps/lld/test/COFF/pdb-globals-dia-vfunc-collision2.test created+25| ... | @@ -0,0 +1,25 @@ | ||
| 1 | REQUIRES: diasdk | ||
| 2 | |||
| 3 | Input object file reconstruction: | ||
| 4 | |||
| 5 | ; // main.cpp | ||
| 6 | ; struct S { | ||
| 7 | ; // Function names are chosen specifically to generate hash collisions in the | ||
| 8 | ; // GSI hash table. | ||
| 9 | ; virtual int A132() { return 102; } | ||
| 10 | ; virtual int A1001() { return 300; } | ||
| 11 | ; }; | ||
| 12 | ; | ||
| 13 | ; int main(int argc, char **argv) { | ||
| 14 | ; S s; | ||
| 15 | ; return s.A132(); | ||
| 16 | ; } | ||
| 17 | |||
| 18 | clang-cl /Z7 /GS- /GR- /c main.cpp /Foglobals-dia-vfunc-collision2.obj | ||
| 19 | |||
| 20 | RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe %S/Inputs/globals-dia-vfunc-collision2.obj | ||
| 21 | RUN: llvm-pdbutil pretty -classes %t.pdb | FileCheck %s | ||
| 22 | |||
| 23 | CHECK: struct S | ||
| 24 | CHECK: func [0x00001060+ 0 - 0x0000106c-12 | sizeof= 12] (FPO) virtual {{.*}}A132() | ||
| 25 | CHECK: func [0x00001070+ 0 - 0x0000107c-12 | sizeof= 12] (FPO) virtual {{.*}}A1001() | ||
deps/lld/test/COFF/pdb-globals-dia-vfunc-simple.test created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | REQUIRES: diasdk | ||
| 2 | |||
| 3 | Input object file reconstruction: | ||
| 4 | |||
| 5 | ; // main.cpp | ||
| 6 | ; struct Base { | ||
| 7 | ; virtual int V2() { return 42; } | ||
| 8 | ; }; | ||
| 9 | ; | ||
| 10 | ; struct Derived : public Base { | ||
| 11 | ; int V2() override { return 42; } | ||
| 12 | ; }; | ||
| 13 | ; | ||
| 14 | ; int main() | ||
| 15 | ; { | ||
| 16 | ; Derived D; | ||
| 17 | ; return D.V2(); | ||
| 18 | ; } | ||
| 19 | |||
| 20 | clang-cl /Z7 /GS- /GR- /c main.cpp /Foglobals-dia-vfunc-simple.obj | ||
| 21 | |||
| 22 | RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe %S/Inputs/globals-dia-vfunc-simple.obj | ||
| 23 | RUN: llvm-pdbutil pretty -classes %t.pdb | FileCheck %s | ||
| 24 | |||
| 25 | CHECK: func [0x00001070+ 0 - 0x0000107c-12 | sizeof= 12] (FPO) virtual {{.*}}V2() | ||
| 26 | CHECK: func [0x000010a0+ 0 - 0x000010ac-12 | sizeof= 12] (FPO) virtual {{.*}}V2() | ||
deps/lld/test/COFF/pdb-globals.test+6-6| ... | @@ -15,20 +15,20 @@ RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s | ... | @@ -15,20 +15,20 @@ RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s |
| 15 | CHECK-LABEL: Global Symbols | 15 | CHECK-LABEL: Global Symbols |
| 16 | CHECK-NEXT: ============================================================ | 16 | CHECK-NEXT: ============================================================ |
| 17 | CHECK-NEXT: Records | 17 | CHECK-NEXT: Records |
| 18 | CHECK-NEXT: 208 | S_LPROCREF [size = 24] `LocalFunc` | ||
| 19 | CHECK-NEXT: module = 1, sum name = 0, offset = 292 | ||
| 18 | CHECK-NEXT: 160 | S_PROCREF [size = 28] `GlobalFunc` | 20 | CHECK-NEXT: 160 | S_PROCREF [size = 28] `GlobalFunc` |
| 19 | CHECK-NEXT: module = 1, sum name = 0, offset = 52 | 21 | CHECK-NEXT: module = 1, sum name = 0, offset = 52 |
| 20 | CHECK-NEXT: 188 | S_PROCREF [size = 20] `main` | 22 | CHECK-NEXT: 188 | S_PROCREF [size = 20] `main` |
| 21 | CHECK-NEXT: module = 1, sum name = 0, offset = 108 | 23 | CHECK-NEXT: module = 1, sum name = 0, offset = 108 |
| 22 | CHECK-NEXT: 208 | S_LPROCREF [size = 24] `LocalFunc` | ||
| 23 | CHECK-NEXT: module = 1, sum name = 0, offset = 292 | ||
| 24 | CHECK-NEXT: 312 | S_PROCREF [size = 40] `HelloPoint::HelloPoint` | ||
| 25 | CHECK-NEXT: module = 1, sum name = 0, offset = 376 | ||
| 26 | CHECK-NEXT: 232 | S_GDATA32 [size = 28] `__purecall` | 24 | CHECK-NEXT: 232 | S_GDATA32 [size = 28] `__purecall` |
| 27 | CHECK-NEXT: type = 0x0403 (void*), addr = 0000:0000 | 25 | CHECK-NEXT: type = 0x0403 (void*), addr = 0003:0004 |
| 28 | CHECK-NEXT: 260 | S_GDATA32 [size = 24] `GlobalVar` | 26 | CHECK-NEXT: 260 | S_GDATA32 [size = 24] `GlobalVar` |
| 29 | CHECK-NEXT: type = 0x100B (const int*), addr = 0001:0000 | 27 | CHECK-NEXT: type = 0x100B (const int*), addr = 0003:0000 |
| 30 | CHECK-NEXT: 284 | S_LDATA32 [size = 28] `ConstantVar` | 28 | CHECK-NEXT: 284 | S_LDATA32 [size = 28] `ConstantVar` |
| 31 | CHECK-NEXT: type = 0x100A (const int), addr = 0002:0000 | 29 | CHECK-NEXT: type = 0x100A (const int), addr = 0002:0000 |
| 30 | CHECK-NEXT: 312 | S_PROCREF [size = 40] `HelloPoint::HelloPoint` | ||
| 31 | CHECK-NEXT: module = 1, sum name = 0, offset = 376 | ||
| 32 | 32 | ||
| 33 | CHECK-LABEL: Symbols | 33 | CHECK-LABEL: Symbols |
| 34 | CHECK-NEXT: ============================================================ | 34 | CHECK-NEXT: ============================================================ |
deps/lld/test/COFF/pdb-heapsite.yaml+1-1| ... | @@ -69,7 +69,7 @@ sections: | ... | @@ -69,7 +69,7 @@ sections: |
| 69 | RegRelativeSym: | 69 | RegRelativeSym: |
| 70 | Offset: 8 | 70 | Offset: 8 |
| 71 | Type: 35 | 71 | Type: 35 |
| 72 | Register: RSP | 72 | Register: CVRegRSP |
| 73 | VarName: __formal | 73 | VarName: __formal |
| 74 | - Kind: S_PROC_ID_END | 74 | - Kind: S_PROC_ID_END |
| 75 | ScopeEndSym: | 75 | ScopeEndSym: |
deps/lld/test/COFF/pdb-lib.s+3-3| ... | @@ -13,15 +13,15 @@ | ... | @@ -13,15 +13,15 @@ |
| 13 | # CHECK-NEXT: ============================================================ | 13 | # CHECK-NEXT: ============================================================ |
| 14 | # CHECK-NEXT: Mod 0000 | `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: | 14 | # CHECK-NEXT: Mod 0000 | `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: |
| 15 | # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: | 15 | # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: |
| 16 | # CHECK-NEXT: debug stream: 9, # files: 0, has ec info: false | 16 | # CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false |
| 17 | # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` | 17 | # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 18 | # CHECK-NEXT: Mod 0001 | `bar.obj`: | 18 | # CHECK-NEXT: Mod 0001 | `bar.obj`: |
| 19 | # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`: | 19 | # CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`: |
| 20 | # CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false | 20 | # CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false |
| 21 | # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` | 21 | # CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 22 | # CHECK-NEXT: Mod 0002 | `* Linker *`: | 22 | # CHECK-NEXT: Mod 0002 | `* Linker *`: |
| 23 | # CHECK-NEXT: Obj: ``: | 23 | # CHECK-NEXT: Obj: ``: |
| 24 | # CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false | 24 | # CHECK-NEXT: debug stream: 12, # files: 0, has ec info: false |
| 25 | # CHECK-NEXT: pdb file ni: 1 `{{.*foo.pdb}}`, src file ni: 0 `` | 25 | # CHECK-NEXT: pdb file ni: 1 `{{.*foo.pdb}}`, src file ni: 0 `` |
| 26 | 26 | ||
| 27 | .def _main; | 27 | .def _main; |
deps/lld/test/COFF/pdb-linker-module.test+3-2| ... | @@ -1,10 +1,11 @@ | ... | @@ -1,10 +1,11 @@ |
| 1 | RUN: lld-link /debug /pdb:%t.pdb /nodefaultlib /entry:main %S/Inputs/pdb-diff.obj | 1 | RUN: echo "/nodefaultlib" > %t.rsp |
| 2 | RUN: lld-link /debug /pdb:%t.pdb @%t.rsp /entry:main %S/Inputs/pdb-diff.obj | ||
| 2 | RUN: llvm-pdbutil dump -modules %t.pdb | FileCheck --check-prefix=MODS %s | 3 | RUN: llvm-pdbutil dump -modules %t.pdb | FileCheck --check-prefix=MODS %s |
| 3 | RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck --check-prefix=SYMS %s | 4 | RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck --check-prefix=SYMS %s |
| 4 | 5 | ||
| 5 | MODS: Mod 0001 | `* Linker *` | 6 | MODS: Mod 0001 | `* Linker *` |
| 6 | MODS-NEXT: Obj: ``: | 7 | MODS-NEXT: Obj: ``: |
| 7 | MODS-NEXT: debug stream: 10, # files: 0, has ec info: false | 8 | MODS-NEXT: debug stream: 12, # files: 0, has ec info: false |
| 8 | MODS-NEXT: pdb file ni: 1 `{{.*}}pdb-linker-module.test.tmp.pdb`, src file ni: 0 `` | 9 | MODS-NEXT: pdb file ni: 1 `{{.*}}pdb-linker-module.test.tmp.pdb`, src file ni: 0 `` |
| 9 | 10 | ||
| 10 | SYMS: Mod 0001 | `* Linker *` | 11 | SYMS: Mod 0001 | `* Linker *` |
deps/lld/test/COFF/pdb-natvis.test created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | REQUIRES: diasdk | ||
| 2 | |||
| 3 | RUN: yaml2obj %p/Inputs/generic.yaml > %t.obj | ||
| 4 | RUN: lld-link /DEBUG %t.obj /nodefaultlib /entry:main /NATVIS:%p/Inputs/natvis-1.natvis \ | ||
| 5 | RUN: /NATVIS:%p/Inputs/natvis-2.natvis /NATVIS:%p/Inputs/natvis-3.natvis /OUT:%t.exe \ | ||
| 6 | RUN: /PDB:%t.pdb | ||
| 7 | RUN: llvm-pdbutil pretty -injected-sources -injected-source-content %t.pdb | FileCheck \ | ||
| 8 | RUN: --check-prefix=CHECK-FIRST %s | ||
| 9 | RUN: llvm-pdbutil pretty -injected-sources -injected-source-content %t.pdb | FileCheck \ | ||
| 10 | RUN: --check-prefix=CHECK-SECOND %s | ||
| 11 | RUN: llvm-pdbutil pretty -injected-sources -injected-source-content %t.pdb | FileCheck \ | ||
| 12 | RUN: --check-prefix=CHECK-THIRD %s | ||
| 13 | |||
| 14 | RUN: lld-link /DEBUG %t.obj /nodefaultlib /entry:main /NATVIS:%p/Inputs/test2.natvis \ | ||
| 15 | RUN: /OUT:%t.exe /PDB:%t.pdb 2>&1 | FileCheck --check-prefix=CHECK-MISSING %s | ||
| 16 | |||
| 17 | CHECK-FIRST: {{.*}}natvis-1.natvis (16 bytes): obj=<null>, vname={{.*}}natvis-1.natvis, crc=355285096, compression=None | ||
| 18 | CHECK-FIRST-NEXT: 1st Natvis Test | ||
| 19 | |||
| 20 | CHECK-SECOND: {{.*}}natvis-2.natvis (19 bytes): obj=<null>, vname={{.*}}natvis-2.natvis, crc=4252640062, compression=None | ||
| 21 | CHECK-SECOND-NEXT: Second Natvis Test | ||
| 22 | |||
| 23 | CHECK-THIRD: {{.*}}natvis-3.natvis (18 bytes): obj=<null>, vname={{.*}}natvis-3.natvis, crc=2069719849, compression=None | ||
| 24 | CHECK-THIRD-NEXT: Third Natvis Test | ||
| 25 | |||
| 26 | CHECK-MISSING: Cannot open input file: {{.*}}test2.natvis | ||
| \ No newline at end of file | |||
deps/lld/test/COFF/pdb-procid-remapping.test+2-2| ... | @@ -9,7 +9,7 @@ CHECK: Symbols | ... | @@ -9,7 +9,7 @@ CHECK: Symbols |
| 9 | CHECK-NEXT: ============================================================ | 9 | CHECK-NEXT: ============================================================ |
| 10 | CHECK-LABEL: Mod 0000 | | 10 | CHECK-LABEL: Mod 0000 | |
| 11 | CHECK: 92 | S_GPROC32 [size = 44] `main` | 11 | CHECK: 92 | S_GPROC32 [size = 44] `main` |
| 12 | CHECK-NEXT: parent = 0, end = 168, addr = 0002:0000, code size = 14 | 12 | CHECK-NEXT: parent = 0, end = 168, addr = 0001:0000, code size = 14 |
| 13 | CHECK-NEXT: type = `0x1004 (int (<no type>))`, debug start = 4, debug end = 9, flags = none | 13 | CHECK-NEXT: type = `0x1004 (int (<no type>))`, debug start = 4, debug end = 9, flags = none |
| 14 | CHECK-NEXT: 136 | S_FRAMEPROC [size = 32] | 14 | CHECK-NEXT: 136 | S_FRAMEPROC [size = 32] |
| 15 | CHECK-NEXT: size = 40, padding size = 0, offset to padding = 0 | 15 | CHECK-NEXT: size = 40, padding size = 0, offset to padding = 0 |
| ... | @@ -18,7 +18,7 @@ CHECK-NEXT: flags = has async eh | opt speed | ... | @@ -18,7 +18,7 @@ CHECK-NEXT: flags = has async eh | opt speed |
| 18 | CHECK-NEXT: 168 | S_END [size = 4] | 18 | CHECK-NEXT: 168 | S_END [size = 4] |
| 19 | CHECK-LABEL: Mod 0001 | | 19 | CHECK-LABEL: Mod 0001 | |
| 20 | CHECK: 92 | S_GPROC32 [size = 44] `foo` | 20 | CHECK: 92 | S_GPROC32 [size = 44] `foo` |
| 21 | CHECK-NEXT: parent = 0, end = 168, addr = 0002:0016, code size = 6 | 21 | CHECK-NEXT: parent = 0, end = 168, addr = 0001:0016, code size = 6 |
| 22 | CHECK-NEXT: type = `0x1001 (int ())`, debug start = 0, debug end = 5, flags = none | 22 | CHECK-NEXT: type = `0x1001 (int ())`, debug start = 0, debug end = 5, flags = none |
| 23 | CHECK-NEXT: 136 | S_FRAMEPROC [size = 32] | 23 | CHECK-NEXT: 136 | S_FRAMEPROC [size = 32] |
| 24 | CHECK-NEXT: size = 0, padding size = 0, offset to padding = 0 | 24 | CHECK-NEXT: size = 0, padding size = 0, offset to padding = 0 |
deps/lld/test/COFF/pdb-publics-import.test+5-4| ... | @@ -6,7 +6,8 @@ RUN: yaml2obj < %p/Inputs/export.yaml > %t1.obj | ... | @@ -6,7 +6,8 @@ RUN: yaml2obj < %p/Inputs/export.yaml > %t1.obj |
| 6 | RUN: lld-link /out:%t1.dll /dll %t1.obj /implib:%t1.lib \ | 6 | RUN: lld-link /out:%t1.dll /dll %t1.obj /implib:%t1.lib \ |
| 7 | RUN: /export:exportfn1 /export:exportfn2 | 7 | RUN: /export:exportfn1 /export:exportfn2 |
| 8 | RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj | 8 | RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj |
| 9 | RUN: lld-link /out:%t2.exe /pdb:%t2.pdb /debug /entry:main %t2.obj %t1.lib | 9 | RUN: lld-link /out:%t2.exe /pdb:%t2.pdb /pdbaltpath:test.pdb \ |
| 10 | RUN: /debug /entry:main %t2.obj %t1.lib | ||
| 10 | RUN: llvm-pdbutil dump %t2.pdb -publics -section-contribs | FileCheck %s | 11 | RUN: llvm-pdbutil dump %t2.pdb -publics -section-contribs | FileCheck %s |
| 11 | 12 | ||
| 12 | CHECK: Public Symbols | 13 | CHECK: Public Symbols |
| ... | @@ -19,9 +20,9 @@ CHECK-NEXT: flags = function, addr = 0001:0016 | ... | @@ -19,9 +20,9 @@ CHECK-NEXT: flags = function, addr = 0001:0016 |
| 19 | CHECK-NEXT: 88 | S_PUB32 [size = 24] `exportfn2` | 20 | CHECK-NEXT: 88 | S_PUB32 [size = 24] `exportfn2` |
| 20 | CHECK-NEXT: flags = function, addr = 0001:0032 | 21 | CHECK-NEXT: flags = function, addr = 0001:0032 |
| 21 | CHECK-NEXT: 32 | S_PUB32 [size = 32] `__imp_exportfn2` | 22 | CHECK-NEXT: 32 | S_PUB32 [size = 32] `__imp_exportfn2` |
| 22 | CHECK-NEXT: flags = none, addr = 0003:0072 | 23 | CHECK-NEXT: flags = none, addr = 0002:0136 |
| 23 | CHECK-NEXT: 0 | S_PUB32 [size = 32] `__imp_exportfn1` | 24 | CHECK-NEXT: 0 | S_PUB32 [size = 32] `__imp_exportfn1` |
| 24 | CHECK-NEXT: flags = none, addr = 0003:0064 | 25 | CHECK-NEXT: flags = none, addr = 0002:0128 |
| 25 | 26 | ||
| 26 | CHECK: Section Contributions | 27 | CHECK: Section Contributions |
| 27 | CHECK-NEXT: ============================================================ | 28 | CHECK-NEXT: ============================================================ |
| ... | @@ -38,5 +39,5 @@ CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_S | ... | @@ -38,5 +39,5 @@ CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_S |
| 38 | .rdata debug directory data chunks | 39 | .rdata debug directory data chunks |
| 39 | CHECK-NEXT: SC[.rdata] | mod = 1, 0002:0000, size = 28, data crc = 0, reloc crc = 0 | 40 | CHECK-NEXT: SC[.rdata] | mod = 1, 0002:0000, size = 28, data crc = 0, reloc crc = 0 |
| 40 | CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | 41 | CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
| 41 | CHECK-NEXT: SC[.rdata] | mod = 1, 0002:0028, size = {{.*}}, data crc = 0, reloc crc = 0 | 42 | CHECK-NEXT: SC[.rdata] | mod = 1, 0002:0028, size = 33, data crc = 0, reloc crc = 0 |
| 42 | CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | 43 | CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
deps/lld/test/COFF/pdb-relative-source-lines.test created+45| ... | @@ -0,0 +1,45 @@ | ||
| 1 | Test the linker line tables on roughly the following example: | ||
| 2 | |||
| 3 | ==> foo.h <== | ||
| 4 | void bar(void); | ||
| 5 | inline void foo(void) { | ||
| 6 | bar(); | ||
| 7 | } | ||
| 8 | ==> pdb_lines_1.c <== | ||
| 9 | #include "foo.h" | ||
| 10 | int main(void) { | ||
| 11 | foo(); | ||
| 12 | return 42; | ||
| 13 | } | ||
| 14 | ==> pdb_lines_2.c <== | ||
| 15 | void bar(void) { | ||
| 16 | } | ||
| 17 | |||
| 18 | $ clang-cl -Xclang -fdebug-compilation-dir -Xclang . -c -Z7 pdb_lines*.c | ||
| 19 | |||
| 20 | RUN: yaml2obj %S/Inputs/pdb_lines_1_relative.yaml -o %t.pdb_lines_1_relative.obj | ||
| 21 | RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t.pdb_lines_2_relative.obj | ||
| 22 | RUN: rm -f %t.exe %t.pdb | ||
| 23 | RUN: lld-link -debug -pdbsourcepath:c:\\src -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1_relative.obj %t.pdb_lines_2_relative.obj | ||
| 24 | RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s | ||
| 25 | |||
| 26 | CHECK-LABEL: - Module: {{.*}}pdb_lines_1_relative.obj | ||
| 27 | CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1_relative.obj | ||
| 28 | CHECK: SourceFiles: | ||
| 29 | CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c' | ||
| 30 | CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}foo.h' | ||
| 31 | CHECK: Subsections: | ||
| 32 | CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c' | ||
| 33 | CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}foo.h' | ||
| 34 | CHECK: - !FileChecksums | ||
| 35 | CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_1.c' | ||
| 36 | CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}foo.h' | ||
| 37 | |||
| 38 | CHECK-LABEL: - Module: {{.*}}pdb_lines_2_relative.obj | ||
| 39 | CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2_relative.obj | ||
| 40 | CHECK: SourceFiles: | ||
| 41 | CHECK-NEXT: - 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c' | ||
| 42 | CHECK: Subsections: | ||
| 43 | CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c' | ||
| 44 | CHECK: - !FileChecksums | ||
| 45 | CHECK: - FileName: 'c:{{[\\/]}}src{{[\\/]}}pdb_lines_2.c' | ||
deps/lld/test/COFF/pdb-same-name.test+2-2| ... | @@ -15,9 +15,9 @@ RAW: Modules | ... | @@ -15,9 +15,9 @@ RAW: Modules |
| 15 | RAW-NEXT: ============================================================ | 15 | RAW-NEXT: ============================================================ |
| 16 | RAW-NEXT: Mod 0000 | `foo.obj`: | 16 | RAW-NEXT: Mod 0000 | `foo.obj`: |
| 17 | RAW-NEXT: Obj: `{{.*}}1\foo.lib`: | 17 | RAW-NEXT: Obj: `{{.*}}1\foo.lib`: |
| 18 | RAW-NEXT: debug stream: 9, # files: 1, has ec info: false | 18 | RAW-NEXT: debug stream: 11, # files: 1, has ec info: false |
| 19 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` | 19 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 20 | RAW-NEXT: Mod 0001 | `foo.obj`: | 20 | RAW-NEXT: Mod 0001 | `foo.obj`: |
| 21 | RAW-NEXT: Obj: `{{.*}}2\foo.lib`: | 21 | RAW-NEXT: Obj: `{{.*}}2\foo.lib`: |
| 22 | RAW-NEXT: debug stream: 10, # files: 1, has ec info: false | 22 | RAW-NEXT: debug stream: 12, # files: 1, has ec info: false |
| 23 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` | 23 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
deps/lld/test/COFF/pdb-scopes.test+7-7| ... | @@ -35,39 +35,39 @@ RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s | ... | @@ -35,39 +35,39 @@ RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s |
| 35 | 35 | ||
| 36 | CHECK-LABEL: Mod 0000 | `{{.*}}pdb-scopes.test.tmp-a.obj`: | 36 | CHECK-LABEL: Mod 0000 | `{{.*}}pdb-scopes.test.tmp-a.obj`: |
| 37 | CHECK: 104 | S_GPROC32 [size = 44] `g` | 37 | CHECK: 104 | S_GPROC32 [size = 44] `g` |
| 38 | CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 5 | 38 | CHECK: parent = 0, end = 196, addr = 0001:0000, code size = 5 |
| 39 | CHECK: debug start = 4, debug end = 4, flags = none | 39 | CHECK: debug start = 4, debug end = 4, flags = none |
| 40 | CHECK: 180 | S_REGREL32 [size = 16] `x` | 40 | CHECK: 180 | S_REGREL32 [size = 16] `x` |
| 41 | CHECK: 196 | S_END [size = 4] | 41 | CHECK: 196 | S_END [size = 4] |
| 42 | CHECK: 200 | S_GPROC32 [size = 44] `main` | 42 | CHECK: 200 | S_GPROC32 [size = 44] `main` |
| 43 | CHECK: parent = 0, end = 384, addr = 0002:0016, code size = 58 | 43 | CHECK: parent = 0, end = 384, addr = 0001:0016, code size = 58 |
| 44 | CHECK: debug start = 8, debug end = 53, flags = none | 44 | CHECK: debug start = 8, debug end = 53, flags = none |
| 45 | CHECK: 276 | S_REGREL32 [size = 20] `argc` | 45 | CHECK: 276 | S_REGREL32 [size = 20] `argc` |
| 46 | CHECK: 296 | S_BLOCK32 [size = 24] `` | 46 | CHECK: 296 | S_BLOCK32 [size = 24] `` |
| 47 | CHECK: parent = 200, end = 336 | 47 | CHECK: parent = 200, end = 336 |
| 48 | CHECK: code size = 17, addr = 0002:0031 | 48 | CHECK: code size = 17, addr = 0001:0031 |
| 49 | CHECK: 320 | S_REGREL32 [size = 16] `x` | 49 | CHECK: 320 | S_REGREL32 [size = 16] `x` |
| 50 | CHECK: 336 | S_END [size = 4] | 50 | CHECK: 336 | S_END [size = 4] |
| 51 | CHECK: 340 | S_BLOCK32 [size = 24] `` | 51 | CHECK: 340 | S_BLOCK32 [size = 24] `` |
| 52 | CHECK: parent = 200, end = 380 | 52 | CHECK: parent = 200, end = 380 |
| 53 | CHECK: code size = 17, addr = 0002:0050 | 53 | CHECK: code size = 17, addr = 0001:0050 |
| 54 | CHECK: 364 | S_REGREL32 [size = 16] `y` | 54 | CHECK: 364 | S_REGREL32 [size = 16] `y` |
| 55 | CHECK: 380 | S_END [size = 4] | 55 | CHECK: 380 | S_END [size = 4] |
| 56 | CHECK: 384 | S_END [size = 4] | 56 | CHECK: 384 | S_END [size = 4] |
| 57 | 57 | ||
| 58 | CHECK-LABEL: Mod 0001 | `{{.*}}pdb-scopes.test.tmp-b.obj`: | 58 | CHECK-LABEL: Mod 0001 | `{{.*}}pdb-scopes.test.tmp-b.obj`: |
| 59 | CHECK: 104 | S_GPROC32 [size = 44] `f` | 59 | CHECK: 104 | S_GPROC32 [size = 44] `f` |
| 60 | CHECK: parent = 0, end = 284, addr = 0002:0080, code size = 62 | 60 | CHECK: parent = 0, end = 284, addr = 0001:0080, code size = 62 |
| 61 | CHECK: debug start = 8, debug end = 57, flags = none | 61 | CHECK: debug start = 8, debug end = 57, flags = none |
| 62 | CHECK: 180 | S_REGREL32 [size = 16] `x` | 62 | CHECK: 180 | S_REGREL32 [size = 16] `x` |
| 63 | CHECK: 196 | S_BLOCK32 [size = 24] `` | 63 | CHECK: 196 | S_BLOCK32 [size = 24] `` |
| 64 | CHECK: parent = 104, end = 236 | 64 | CHECK: parent = 104, end = 236 |
| 65 | CHECK: code size = 20, addr = 0002:0095 | 65 | CHECK: code size = 20, addr = 0001:0095 |
| 66 | CHECK: 220 | S_REGREL32 [size = 16] `y` | 66 | CHECK: 220 | S_REGREL32 [size = 16] `y` |
| 67 | CHECK: 236 | S_END [size = 4] | 67 | CHECK: 236 | S_END [size = 4] |
| 68 | CHECK: 240 | S_BLOCK32 [size = 24] `` | 68 | CHECK: 240 | S_BLOCK32 [size = 24] `` |
| 69 | CHECK: parent = 104, end = 280 | 69 | CHECK: parent = 104, end = 280 |
| 70 | CHECK: code size = 20, addr = 0002:0117 | 70 | CHECK: code size = 20, addr = 0001:0117 |
| 71 | CHECK: 264 | S_REGREL32 [size = 16] `w` | 71 | CHECK: 264 | S_REGREL32 [size = 16] `w` |
| 72 | CHECK: 280 | S_END [size = 4] | 72 | CHECK: 280 | S_END [size = 4] |
| 73 | CHECK: 284 | S_END [size = 4] | 73 | CHECK: 284 | S_END [size = 4] |
deps/lld/test/COFF/pdb-source-lines.test+13-13| ... | @@ -26,11 +26,11 @@ RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | | ... | @@ -26,11 +26,11 @@ RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | |
| 26 | CHECK-LABEL: DbiStream: | 26 | CHECK-LABEL: DbiStream: |
| 27 | CHECK-NEXT: VerHeader: V70 | 27 | CHECK-NEXT: VerHeader: V70 |
| 28 | CHECK-NEXT: Age: 1 | 28 | CHECK-NEXT: Age: 1 |
| 29 | CHECK-NEXT: BuildNumber: 0 | 29 | CHECK-NEXT: BuildNumber: 36363 |
| 30 | CHECK-NEXT: PdbDllVersion: 0 | 30 | CHECK-NEXT: PdbDllVersion: 0 |
| 31 | CHECK-NEXT: PdbDllRbld: 0 | 31 | CHECK-NEXT: PdbDllRbld: 0 |
| 32 | CHECK-NEXT: Flags: 0 | 32 | CHECK-NEXT: Flags: 0 |
| 33 | CHECK-NEXT: MachineType: x86 | 33 | CHECK-NEXT: MachineType: Amd64 |
| 34 | CHECK-NEXT: Modules: | 34 | CHECK-NEXT: Modules: |
| 35 | 35 | ||
| 36 | CHECK-LABEL: - Module: {{.*}}pdb_lines_1.obj | 36 | CHECK-LABEL: - Module: {{.*}}pdb_lines_1.obj |
| ... | @@ -43,7 +43,7 @@ CHECK-NEXT: - !Lines | ... | @@ -43,7 +43,7 @@ CHECK-NEXT: - !Lines |
| 43 | CHECK-NEXT: CodeSize: 19 | 43 | CHECK-NEXT: CodeSize: 19 |
| 44 | CHECK-NEXT: Flags: [ ] | 44 | CHECK-NEXT: Flags: [ ] |
| 45 | CHECK-NEXT: RelocOffset: 0 | 45 | CHECK-NEXT: RelocOffset: 0 |
| 46 | CHECK-NEXT: RelocSegment: 2 | 46 | CHECK-NEXT: RelocSegment: 1 |
| 47 | CHECK-NEXT: Blocks: | 47 | CHECK-NEXT: Blocks: |
| 48 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c' | 48 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c' |
| 49 | CHECK-NEXT: Lines: | 49 | CHECK-NEXT: Lines: |
| ... | @@ -64,19 +64,11 @@ CHECK-NEXT: LineStart: 5 | ... | @@ -64,19 +64,11 @@ CHECK-NEXT: LineStart: 5 |
| 64 | CHECK-NEXT: IsStatement: true | 64 | CHECK-NEXT: IsStatement: true |
| 65 | CHECK-NEXT: EndDelta: 0 | 65 | CHECK-NEXT: EndDelta: 0 |
| 66 | CHECK-NEXT: Columns: | 66 | CHECK-NEXT: Columns: |
| 67 | CHECK-NEXT: - !FileChecksums | ||
| 68 | CHECK-NEXT: Checksums: | ||
| 69 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c' | ||
| 70 | CHECK-NEXT: Kind: MD5 | ||
| 71 | CHECK-NEXT: Checksum: 4EB19DCD86C3BA2238A255C718572E7B | ||
| 72 | CHECK-NEXT: - FileName: '{{.*}}foo.h' | ||
| 73 | CHECK-NEXT: Kind: MD5 | ||
| 74 | CHECK-NEXT: Checksum: 061EB73ABB642532857A4F1D9CBAC323 | ||
| 75 | CHECK-NEXT: - !Lines | 67 | CHECK-NEXT: - !Lines |
| 76 | CHECK-NEXT: CodeSize: 14 | 68 | CHECK-NEXT: CodeSize: 14 |
| 77 | CHECK-NEXT: Flags: [ ] | 69 | CHECK-NEXT: Flags: [ ] |
| 78 | CHECK-NEXT: RelocOffset: 32 | 70 | CHECK-NEXT: RelocOffset: 32 |
| 79 | CHECK-NEXT: RelocSegment: 2 | 71 | CHECK-NEXT: RelocSegment: 1 |
| 80 | CHECK-NEXT: Blocks: | 72 | CHECK-NEXT: Blocks: |
| 81 | CHECK-NEXT: - FileName: '{{.*}}foo.h' | 73 | CHECK-NEXT: - FileName: '{{.*}}foo.h' |
| 82 | CHECK-NEXT: Lines: | 74 | CHECK-NEXT: Lines: |
| ... | @@ -93,6 +85,14 @@ CHECK-NEXT: LineStart: 4 | ... | @@ -93,6 +85,14 @@ CHECK-NEXT: LineStart: 4 |
| 93 | CHECK-NEXT: IsStatement: true | 85 | CHECK-NEXT: IsStatement: true |
| 94 | CHECK-NEXT: EndDelta: 0 | 86 | CHECK-NEXT: EndDelta: 0 |
| 95 | CHECK-NEXT: Columns: | 87 | CHECK-NEXT: Columns: |
| 88 | CHECK-NEXT: - !FileChecksums | ||
| 89 | CHECK-NEXT: Checksums: | ||
| 90 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c' | ||
| 91 | CHECK-NEXT: Kind: MD5 | ||
| 92 | CHECK-NEXT: Checksum: 4EB19DCD86C3BA2238A255C718572E7B | ||
| 93 | CHECK-NEXT: - FileName: '{{.*}}foo.h' | ||
| 94 | CHECK-NEXT: Kind: MD5 | ||
| 95 | CHECK-NEXT: Checksum: 061EB73ABB642532857A4F1D9CBAC323 | ||
| 96 | 96 | ||
| 97 | CHECK-LABEL: - Module: {{.*}}pdb_lines_2.obj | 97 | CHECK-LABEL: - Module: {{.*}}pdb_lines_2.obj |
| 98 | CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2.obj | 98 | CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2.obj |
| ... | @@ -103,7 +103,7 @@ CHECK-NEXT: - !Lines | ... | @@ -103,7 +103,7 @@ CHECK-NEXT: - !Lines |
| 103 | CHECK-NEXT: CodeSize: 1 | 103 | CHECK-NEXT: CodeSize: 1 |
| 104 | CHECK-NEXT: Flags: [ ] | 104 | CHECK-NEXT: Flags: [ ] |
| 105 | CHECK-NEXT: RelocOffset: 48 | 105 | CHECK-NEXT: RelocOffset: 48 |
| 106 | CHECK-NEXT: RelocSegment: 2 | 106 | CHECK-NEXT: RelocSegment: 1 |
| 107 | CHECK-NEXT: Blocks: | 107 | CHECK-NEXT: Blocks: |
| 108 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c' | 108 | CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c' |
| 109 | CHECK-NEXT: Lines: | 109 | CHECK-NEXT: Lines: |
deps/lld/test/COFF/pdb-symbol-types.yaml+2-2| ... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
| 19 | # CHECK-NEXT: 48 | S_PROCREF [size = 20] `main` | 19 | # CHECK-NEXT: 48 | S_PROCREF [size = 20] `main` |
| 20 | # CHECK-NEXT: module = 1, sum name = 0, offset = 116 | 20 | # CHECK-NEXT: module = 1, sum name = 0, offset = 116 |
| 21 | # CHECK-NEXT: 68 | S_GDATA32 [size = 28] `global_foo` | 21 | # CHECK-NEXT: 68 | S_GDATA32 [size = 28] `global_foo` |
| 22 | # CHECK-NEXT: type = 0x1004 (Foo), addr = 0001:0000 | 22 | # CHECK-NEXT: type = 0x1004 (Foo), addr = 0003:0000 |
| 23 | 23 | ||
| 24 | # CHECK: Symbols | 24 | # CHECK: Symbols |
| 25 | # CHECK: ============================================================ | 25 | # CHECK: ============================================================ |
| ... | @@ -30,7 +30,7 @@ | ... | @@ -30,7 +30,7 @@ |
| 30 | # CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 | 30 | # CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 |
| 31 | # CHECK: flags = security checks | hot patchable | 31 | # CHECK: flags = security checks | hot patchable |
| 32 | # CHECK: 116 | S_GPROC32 [size = 44] `main` | 32 | # CHECK: 116 | S_GPROC32 [size = 44] `main` |
| 33 | # CHECK: parent = 0, end = 192, addr = 0002:0000, code size = 7 | 33 | # CHECK: parent = 0, end = 192, addr = 0001:0000, code size = 7 |
| 34 | # CHECK: debug start = 0, debug end = 6, flags = none | 34 | # CHECK: debug start = 0, debug end = 6, flags = none |
| 35 | # CHECK: 160 | S_FRAMEPROC [size = 32] | 35 | # CHECK: 160 | S_FRAMEPROC [size = 32] |
| 36 | # CHECK: size = 0, padding size = 0, offset to padding = 0 | 36 | # CHECK: size = 0, padding size = 0, offset to padding = 0 |
deps/lld/test/COFF/pdb-thunk.yaml+6-6| ... | @@ -84,7 +84,7 @@ sections: | ... | @@ -84,7 +84,7 @@ sections: |
| 84 | RegRelativeSym: | 84 | RegRelativeSym: |
| 85 | Offset: 8 | 85 | Offset: 8 |
| 86 | Type: 4097 | 86 | Type: 4097 |
| 87 | Register: RSP | 87 | Register: CVRegRSP |
| 88 | VarName: this | 88 | VarName: this |
| 89 | - Kind: S_PROC_ID_END | 89 | - Kind: S_PROC_ID_END |
| 90 | ScopeEndSym: | 90 | ScopeEndSym: |
| ... | @@ -124,7 +124,7 @@ sections: | ... | @@ -124,7 +124,7 @@ sections: |
| 124 | RegRelativeSym: | 124 | RegRelativeSym: |
| 125 | Offset: 8 | 125 | Offset: 8 |
| 126 | Type: 4121 | 126 | Type: 4121 |
| 127 | Register: RSP | 127 | Register: CVRegRSP |
| 128 | VarName: this | 128 | VarName: this |
| 129 | - Kind: S_PROC_ID_END | 129 | - Kind: S_PROC_ID_END |
| 130 | ScopeEndSym: | 130 | ScopeEndSym: |
| ... | @@ -164,7 +164,7 @@ sections: | ... | @@ -164,7 +164,7 @@ sections: |
| 164 | RegRelativeSym: | 164 | RegRelativeSym: |
| 165 | Offset: 48 | 165 | Offset: 48 |
| 166 | Type: 4143 | 166 | Type: 4143 |
| 167 | Register: RSP | 167 | Register: CVRegRSP |
| 168 | VarName: this | 168 | VarName: this |
| 169 | - Kind: S_PROC_ID_END | 169 | - Kind: S_PROC_ID_END |
| 170 | ScopeEndSym: | 170 | ScopeEndSym: |
| ... | @@ -208,7 +208,7 @@ sections: | ... | @@ -208,7 +208,7 @@ sections: |
| 208 | RegRelativeSym: | 208 | RegRelativeSym: |
| 209 | Offset: 8 | 209 | Offset: 8 |
| 210 | Type: 4143 | 210 | Type: 4143 |
| 211 | Register: RSP | 211 | Register: CVRegRSP |
| 212 | VarName: this | 212 | VarName: this |
| 213 | - Kind: S_PROC_ID_END | 213 | - Kind: S_PROC_ID_END |
| 214 | ScopeEndSym: | 214 | ScopeEndSym: |
| ... | @@ -2176,7 +2176,7 @@ sections: | ... | @@ -2176,7 +2176,7 @@ sections: |
| 2176 | RegRelativeSym: | 2176 | RegRelativeSym: |
| 2177 | Offset: 8 | 2177 | Offset: 8 |
| 2178 | Type: 4097 | 2178 | Type: 4097 |
| 2179 | Register: RSP | 2179 | Register: CVRegRSP |
| 2180 | VarName: this | 2180 | VarName: this |
| 2181 | - Kind: S_PROC_ID_END | 2181 | - Kind: S_PROC_ID_END |
| 2182 | ScopeEndSym: | 2182 | ScopeEndSym: |
| ... | @@ -2222,7 +2222,7 @@ sections: | ... | @@ -2222,7 +2222,7 @@ sections: |
| 2222 | RegRelativeSym: | 2222 | RegRelativeSym: |
| 2223 | Offset: 8 | 2223 | Offset: 8 |
| 2224 | Type: 4121 | 2224 | Type: 4121 |
| 2225 | Register: RSP | 2225 | Register: CVRegRSP |
| 2226 | VarName: this | 2226 | VarName: this |
| 2227 | - Kind: S_PROC_ID_END | 2227 | - Kind: S_PROC_ID_END |
| 2228 | ScopeEndSym: | 2228 | ScopeEndSym: |
deps/lld/test/COFF/pdb-type-server-simple.test+3-3| ... | @@ -72,7 +72,7 @@ CHECK: ============================================================ | ... | @@ -72,7 +72,7 @@ CHECK: ============================================================ |
| 72 | CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`: | 72 | CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`: |
| 73 | CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj` | 73 | CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj` |
| 74 | CHECK: 104 | S_GPROC32 [size = 44] `main` | 74 | CHECK: 104 | S_GPROC32 [size = 44] `main` |
| 75 | CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 27 | 75 | CHECK: parent = 0, end = 196, addr = 0001:0000, code size = 27 |
| 76 | CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none | 76 | CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none |
| 77 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` | 77 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]` |
| 78 | CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`: | 78 | CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`: |
| ... | @@ -82,14 +82,14 @@ CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compil | ... | @@ -82,14 +82,14 @@ CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compil |
| 82 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 | 82 | CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1 |
| 83 | CHECK: flags = security checks | hot patchable | 83 | CHECK: flags = security checks | hot patchable |
| 84 | CHECK: 104 | S_GPROC32 [size = 44] `g` | 84 | CHECK: 104 | S_GPROC32 [size = 44] `g` |
| 85 | CHECK: parent = 0, end = 196, addr = 0002:0032, code size = 13 | 85 | CHECK: parent = 0, end = 196, addr = 0001:0032, code size = 13 |
| 86 | CHECK: type = {{.*}}, debug start = 5, debug end = 12, flags = none | 86 | CHECK: type = {{.*}}, debug start = 5, debug end = 12, flags = none |
| 87 | CHECK: 148 | S_FRAMEPROC [size = 32] | 87 | CHECK: 148 | S_FRAMEPROC [size = 32] |
| 88 | CHECK: size = 0, padding size = 0, offset to padding = 0 | 88 | CHECK: size = 0, padding size = 0, offset to padding = 0 |
| 89 | CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 | 89 | CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000 |
| 90 | CHECK: flags = has async eh | opt speed | 90 | CHECK: flags = has async eh | opt speed |
| 91 | CHECK: 180 | S_REGREL32 [size = 16] `p` | 91 | CHECK: 180 | S_REGREL32 [size = 16] `p` |
| 92 | CHECK: type = [[FOO_PTR]] (Foo*), register = RSP, offset = 8 | 92 | CHECK: type = [[FOO_PTR]] (Foo*), register = CVRegRSP, offset = 8 |
| 93 | CHECK: 196 | S_END [size = 4] | 93 | CHECK: 196 | S_END [size = 4] |
| 94 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` | 94 | CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]` |
| 95 | CHECK-LABEL: Mod 0002 | `* Linker *`: | 95 | CHECK-LABEL: Mod 0002 | `* Linker *`: |
deps/lld/test/COFF/pdb.test+88-74| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj | 1 | # RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj |
| 2 | # RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj | 2 | # RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj |
| 3 | # RUN: rm -f %t.dll %t.pdb | 3 | # RUN: rm -f %t.dll %t.pdb |
| 4 | # RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \ | 4 | # RUN: lld-link /debug /pdb:%t.pdb /pdbaltpath:test.pdb /dll /out:%t.dll \ |
| 5 | # RUN: %t1.obj %t2.obj | 5 | # RUN: /entry:main /nodefaultlib %t1.obj %t2.obj |
| 6 | 6 | ||
| 7 | # RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \ | 7 | # RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \ |
| 8 | # RUN: -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s | 8 | # RUN: -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s |
| ... | @@ -14,7 +14,7 @@ | ... | @@ -14,7 +14,7 @@ |
| 14 | # CHECK: MSF: | 14 | # CHECK: MSF: |
| 15 | # CHECK-NEXT: SuperBlock: | 15 | # CHECK-NEXT: SuperBlock: |
| 16 | # CHECK-NEXT: BlockSize: 4096 | 16 | # CHECK-NEXT: BlockSize: 4096 |
| 17 | # CHECK-NEXT: FreeBlockMap: 1 | 17 | # CHECK-NEXT: FreeBlockMap: 2 |
| 18 | # CHECK-NEXT: NumBlocks: | 18 | # CHECK-NEXT: NumBlocks: |
| 19 | # CHECK-NEXT: NumDirectoryBytes: | 19 | # CHECK-NEXT: NumDirectoryBytes: |
| 20 | # CHECK-NEXT: Unknown1: 0 | 20 | # CHECK-NEXT: Unknown1: 0 |
| ... | @@ -34,11 +34,11 @@ | ... | @@ -34,11 +34,11 @@ |
| 34 | # CHECK-NEXT: DbiStream: | 34 | # CHECK-NEXT: DbiStream: |
| 35 | # CHECK-NEXT: VerHeader: V70 | 35 | # CHECK-NEXT: VerHeader: V70 |
| 36 | # CHECK-NEXT: Age: 1 | 36 | # CHECK-NEXT: Age: 1 |
| 37 | # CHECK-NEXT: BuildNumber: 0 | 37 | # CHECK-NEXT: BuildNumber: 36363 |
| 38 | # CHECK-NEXT: PdbDllVersion: 0 | 38 | # CHECK-NEXT: PdbDllVersion: 0 |
| 39 | # CHECK-NEXT: PdbDllRbld: 0 | 39 | # CHECK-NEXT: PdbDllRbld: 0 |
| 40 | # CHECK-NEXT: Flags: 0 | 40 | # CHECK-NEXT: Flags: 0 |
| 41 | # CHECK-NEXT: MachineType: x86 | 41 | # CHECK-NEXT: MachineType: Amd64 |
| 42 | # CHECK-NEXT: TpiStream: | 42 | # CHECK-NEXT: TpiStream: |
| 43 | # CHECK-NEXT: Version: VC80 | 43 | # CHECK-NEXT: Version: VC80 |
| 44 | # CHECK-NEXT: Records: | 44 | # CHECK-NEXT: Records: |
| ... | @@ -120,16 +120,24 @@ | ... | @@ -120,16 +120,24 @@ |
| 120 | RAW: Modules | 120 | RAW: Modules |
| 121 | RAW-NEXT: ============================================================ | 121 | RAW-NEXT: ============================================================ |
| 122 | RAW-NEXT: Mod 0000 | `{{.*}}pdb.test.tmp1.obj`: | 122 | RAW-NEXT: Mod 0000 | `{{.*}}pdb.test.tmp1.obj`: |
| 123 | RAW-NEXT: SC[.text] | mod = 0, 0001:0000, size = 14, data crc = 1682752513, reloc crc = 0 | ||
| 124 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | | ||
| 125 | RAW-NEXT: IMAGE_SCN_MEM_READ | ||
| 123 | RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`: | 126 | RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`: |
| 124 | RAW-NEXT: debug stream: 9, # files: 1, has ec info: false | 127 | RAW-NEXT: debug stream: 11, # files: 1, has ec info: false |
| 125 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` | 128 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 126 | RAW-NEXT: Mod 0001 | `{{.*}}pdb.test.tmp2.obj`: | 129 | RAW-NEXT: Mod 0001 | `{{.*}}pdb.test.tmp2.obj`: |
| 130 | RAW-NEXT: SC[.text] | mod = 1, 0001:0016, size = 6, data crc = 2139436471, reloc crc = 0 | ||
| 131 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | | ||
| 132 | RAW-NEXT: IMAGE_SCN_MEM_READ | ||
| 127 | RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`: | 133 | RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`: |
| 128 | RAW-NEXT: debug stream: 10, # files: 1, has ec info: false | 134 | RAW-NEXT: debug stream: 12, # files: 1, has ec info: false |
| 129 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` | 135 | RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` |
| 130 | RAW-NEXT: Mod 0002 | `* Linker *`: | 136 | RAW-NEXT: Mod 0002 | `* Linker *`: |
| 137 | RAW-NEXT: SC[???] | mod = 2, 0000:0000, size = 0, data crc = 0, reloc crc = 0 | ||
| 138 | RAW-NEXT: none | ||
| 131 | RAW-NEXT: Obj: ``: | 139 | RAW-NEXT: Obj: ``: |
| 132 | RAW-NEXT: debug stream: 11, # files: 0, has ec info: false | 140 | RAW-NEXT: debug stream: 13, # files: 0, has ec info: false |
| 133 | RAW-NEXT: pdb file ni: 1 `{{.*pdb.test.tmp.pdb}}`, src file ni: 0 `` | 141 | RAW-NEXT: pdb file ni: 1 `{{.*pdb.test.tmp.pdb}}`, src file ni: 0 `` |
| 134 | RAW: Types (TPI Stream) | 142 | RAW: Types (TPI Stream) |
| 135 | RAW-NEXT: ============================================================ | 143 | RAW-NEXT: ============================================================ |
| ... | @@ -181,10 +189,29 @@ RAW-NEXT: GSI Header | ... | @@ -181,10 +189,29 @@ RAW-NEXT: GSI Header |
| 181 | RAW-NEXT: sig = 0xFFFFFFFF, hdr = 0xF12F091A, hr size = 16, num buckets = 524 | 189 | RAW-NEXT: sig = 0xFFFFFFFF, hdr = 0xF12F091A, hr size = 16, num buckets = 524 |
| 182 | RAW-NEXT: Records | 190 | RAW-NEXT: Records |
| 183 | RAW-NEXT: 20 | S_PUB32 [size = 20] `main` | 191 | RAW-NEXT: 20 | S_PUB32 [size = 20] `main` |
| 184 | RAW-NEXT: flags = function, addr = 0002:0000 | 192 | RAW-NEXT: flags = function, addr = 0001:0000 |
| 185 | RAW-NEXT: 0 | S_PUB32 [size = 20] `foo` | 193 | RAW-NEXT: 0 | S_PUB32 [size = 20] `foo` |
| 186 | RAW-NEXT: flags = function, addr = 0002:0016 | 194 | RAW-NEXT: flags = function, addr = 0001:0016 |
| 187 | RAW-NOT: S_PUB32 | 195 | RAW-NOT: S_PUB32 |
| 196 | RAW-NEXT: Hash Bitmap ( | ||
| 197 | RAW-NEXT: 0000: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 198 | RAW-NEXT: 0020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 199 | RAW-NEXT: 0040: 00000000 20000000 00000000 00000000 00000000 00000000 00000000 00000000 |.... ...........................| | ||
| 200 | RAW-NEXT: 0060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 201 | RAW-NEXT: 0080: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 202 | RAW-NEXT: 00A0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 203 | RAW-NEXT: 00C0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 204 | RAW-NEXT: 00E0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 205 | RAW-NEXT: 0100: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 206 | RAW-NEXT: 0120: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 207 | RAW-NEXT: 0140: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 208 | RAW-NEXT: 0160: 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 209 | RAW-NEXT: 0180: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 210 | RAW-NEXT: 01A0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 211 | RAW-NEXT: 01C0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 212 | RAW-NEXT: 01E0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| | ||
| 213 | RAW-NEXT: 0200: 00000000 |....| | ||
| 214 | RAW-NEXT: ) | ||
| 188 | RAW-NEXT: Hash Entries | 215 | RAW-NEXT: Hash Entries |
| 189 | RAW-NEXT: off = 21, refcnt = 1 | 216 | RAW-NEXT: off = 21, refcnt = 1 |
| 190 | RAW-NEXT: off = 1, refcnt = 1 | 217 | RAW-NEXT: off = 1, refcnt = 1 |
| ... | @@ -196,93 +223,80 @@ RAW-NEXT: off = 20 | ... | @@ -196,93 +223,80 @@ RAW-NEXT: off = 20 |
| 196 | RAW-NEXT: off = 0 | 223 | RAW-NEXT: off = 0 |
| 197 | RAW: Section Headers | 224 | RAW: Section Headers |
| 198 | RAW-NEXT: ============================================================ | 225 | RAW-NEXT: ============================================================ |
| 226 | |||
| 199 | RAW: SECTION HEADER #1 | 227 | RAW: SECTION HEADER #1 |
| 200 | RAW-NEXT: .pdata name | 228 | RAW-NEXT: .text name |
| 201 | RAW-NEXT: virtual size | 229 | RAW-NEXT: 16 virtual size |
| 202 | RAW-NEXT: 1000 virtual address | 230 | RAW-NEXT: 1000 virtual address |
| 203 | RAW-NEXT: 200 size of raw data | 231 | RAW-NEXT: 200 size of raw data |
| 204 | RAW-NEXT: 400 file pointer to raw data | 232 | RAW-NEXT: 400 file pointer to raw data |
| 205 | RAW-NEXT: 0 file pointer to relocation table | 233 | RAW-NEXT: 0 file pointer to relocation table |
| 206 | RAW-NEXT: 0 file pointer to line numbers | 234 | RAW-NEXT: 0 file pointer to line numbers |
| 207 | RAW-NEXT: 0 number of relocations | 235 | RAW-NEXT: 0 number of relocations |
| 208 | RAW-NEXT: 0 number of line numbers | 236 | RAW-NEXT: 0 number of line numbers |
| 209 | RAW-NEXT: 40000040 flags | 237 | RAW-NEXT: 60000020 flags |
| 210 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | 238 | RAW-NEXT: IMAGE_SCN_CNT_CODE |
| 211 | RAW-NEXT: IMAGE_SCN_MEM_READ | 239 | RAW-NEXT: IMAGE_SCN_MEM_EXECUTE |
| 240 | RAW-NEXT: IMAGE_SCN_MEM_READ | ||
| 212 | RAW: SECTION HEADER #2 | 241 | RAW: SECTION HEADER #2 |
| 213 | RAW-NEXT: .text name | 242 | RAW-NEXT: .rdata name |
| 214 | RAW-NEXT: virtual size | 243 | RAW-NEXT: virtual size |
| 215 | RAW-NEXT: 2000 virtual address | 244 | RAW-NEXT: 2000 virtual address |
| 216 | RAW-NEXT: 200 size of raw data | 245 | RAW-NEXT: 200 size of raw data |
| 217 | RAW-NEXT: 600 file pointer to raw data | 246 | RAW-NEXT: 600 file pointer to raw data |
| 218 | RAW-NEXT: 0 file pointer to relocation table | 247 | RAW-NEXT: 0 file pointer to relocation table |
| 219 | RAW-NEXT: 0 file pointer to line numbers | 248 | RAW-NEXT: 0 file pointer to line numbers |
| 220 | RAW-NEXT: 0 number of relocations | 249 | RAW-NEXT: 0 number of relocations |
| 221 | RAW-NEXT: 0 number of line numbers | 250 | RAW-NEXT: 0 number of line numbers |
| 222 | RAW-NEXT: 60000020 flags | 251 | RAW-NEXT: 40000040 flags |
| 223 | RAW-NEXT: IMAGE_SCN_CNT_CODE | 252 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA |
| 224 | RAW-NEXT: IMAGE_SCN_MEM_EXECUTE | 253 | RAW-NEXT: IMAGE_SCN_MEM_READ |
| 225 | RAW-NEXT: IMAGE_SCN_MEM_READ | ||
| 226 | RAW: SECTION HEADER #3 | 254 | RAW: SECTION HEADER #3 |
| 227 | RAW-NEXT: .xdata name | 255 | RAW-NEXT: .pdata name |
| 228 | RAW-NEXT: virtual size | 256 | RAW-NEXT: C virtual size |
| 229 | RAW-NEXT: 3000 virtual address | 257 | RAW-NEXT: 3000 virtual address |
| 230 | RAW-NEXT: 200 size of raw data | 258 | RAW-NEXT: 200 size of raw data |
| 231 | RAW-NEXT: 800 file pointer to raw data | 259 | RAW-NEXT: 800 file pointer to raw data |
| 232 | RAW-NEXT: 0 file pointer to relocation table | 260 | RAW-NEXT: 0 file pointer to relocation table |
| 233 | RAW-NEXT: 0 file pointer to line numbers | 261 | RAW-NEXT: 0 file pointer to line numbers |
| 234 | RAW-NEXT: 0 number of relocations | 262 | RAW-NEXT: 0 number of relocations |
| 235 | RAW-NEXT: 0 number of line numbers | 263 | RAW-NEXT: 0 number of line numbers |
| 236 | RAW-NEXT: 40000040 flags | 264 | RAW-NEXT: 40000040 flags |
| 237 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | 265 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA |
| 238 | RAW-NEXT: IMAGE_SCN_MEM_READ | 266 | RAW-NEXT: IMAGE_SCN_MEM_READ |
| 239 | RAW: SECTION HEADER #4 | ||
| 240 | RAW-NEXT: .rdata name | ||
| 241 | RAW-NEXT: virtual size | ||
| 242 | RAW-NEXT: 4000 virtual address | ||
| 243 | RAW-NEXT: 200 size of raw data | ||
| 244 | RAW-NEXT: A00 file pointer to raw data | ||
| 245 | RAW-NEXT: 0 file pointer to relocation table | ||
| 246 | RAW-NEXT: 0 file pointer to line numbers | ||
| 247 | RAW-NEXT: 0 number of relocations | ||
| 248 | RAW-NEXT: 0 number of line numbers | ||
| 249 | RAW-NEXT: 40000040 flags | ||
| 250 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 251 | RAW-NEXT: IMAGE_SCN_MEM_READ | ||
| 252 | RAW: Original Section Headers | 267 | RAW: Original Section Headers |
| 253 | RAW-NEXT: ============================================================ | 268 | RAW-NEXT: ============================================================ |
| 254 | RAW-NEXT: PDB does not contain the requested image section header type | 269 | RAW-NEXT: PDB does not contain the requested image section header type |
| 255 | RAW: Section Contributions | 270 | RAW: Section Contributions |
| 256 | RAW-NEXT: ============================================================ | 271 | RAW-NEXT: ============================================================ |
| 257 | RAW-NEXT: SC[.pdata] | mod = 0, 0001:0000, size = 12, data crc = 361370162, reloc crc = 0 | 272 | |
| 258 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | 273 | RAW-NEXT: SC[.text] | mod = 0, 0001:0000, size = 14, data crc = 1682752513, reloc crc = 0 |
| 259 | RAW-NEXT: SC[.text] | mod = 0, 0002:0000, size = 14, data crc = 1682752513, reloc crc = 0 | ||
| 260 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | | 274 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | |
| 261 | RAW-NEXT: IMAGE_SCN_MEM_READ | 275 | RAW-NEXT: IMAGE_SCN_MEM_READ |
| 262 | RAW-NEXT: SC[.text] | mod = 1, 0002:0016, size = 6, data crc = 2139436471, reloc crc = 0 | 276 | RAW-NEXT: SC[.text] | mod = 1, 0001:0016, size = 6, data crc = 2139436471, reloc crc = 0 |
| 263 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | | 277 | RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | |
| 264 | RAW-NEXT: IMAGE_SCN_MEM_READ | 278 | RAW-NEXT: IMAGE_SCN_MEM_READ |
| 265 | RAW-NEXT: SC[.xdata] | mod = 0, 0003:0000, size = 8, data crc = 264583633, reloc crc = 0 | 279 | RAW-NEXT: SC[.rdata] | mod = 2, 0002:0000, size = {{[0-9]+}}, data crc = 0, reloc crc = 0 |
| 266 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | ||
| 267 | RAW-NEXT: SC[???] | mod = 2, 0004:0000, size = {{[0-9]+}}, data crc = 0, reloc crc = 0 | ||
| 268 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | 280 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
| 269 | RAW-NEXT: SC[???] | mod = 2, 0004:0028, size = {{[0-9]+}}, data crc = 0, reloc crc = 0 | 281 | RAW-NEXT: SC[.rdata] | mod = 2, 0002:0028, size = {{[0-9]+}}, data crc = 0, reloc crc = 0 |
| 270 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | 282 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
| 283 | RAW-NEXT: SC[.rdata] | mod = 0, 0002:0064, size = {{[0-9]+}}, data crc = 264583633, reloc crc = 0 | ||
| 284 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | ||
| 285 | RAW-NEXT: SC[.pdata] | mod = 0, 0003:0000, size = 12, data crc = 361370162, reloc crc = 0 | ||
| 286 | RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ | ||
| 271 | RAW-NOT: SC[ | 287 | RAW-NOT: SC[ |
| 272 | RAW: Section Map | 288 | RAW: Section Map |
| 273 | RAW-NEXT: ============================================================ | 289 | RAW-NEXT: ============================================================ |
| 290 | |||
| 274 | RAW-NEXT: Section 0000 | ovl = 0, group = 0, frame = 1, name = 65535 | 291 | RAW-NEXT: Section 0000 | ovl = 0, group = 0, frame = 1, name = 65535 |
| 275 | RAW-NEXT: class = 65535, offset = 0, size = | 292 | RAW-NEXT: class = 65535, offset = 0, size = |
| 276 | RAW-NEXT: flags = read | 32 bit addr | selector | 293 | RAW-NEXT: flags = read | execute | 32 bit addr | selector |
| 277 | RAW-NEXT: Section 0001 | ovl = 0, group = 0, frame = 2, name = 65535 | 294 | RAW-NEXT: Section 0001 | ovl = 0, group = 0, frame = 2, name = 65535 |
| 278 | RAW-NEXT: class = 65535, offset = 0, size = | 295 | RAW-NEXT: class = 65535, offset = 0, size = |
| 279 | RAW-NEXT: flags = read | execute | 32 bit addr | selector | 296 | RAW-NEXT: flags = read | 32 bit addr | selector |
| 280 | RAW-NEXT: Section 0002 | ovl = 0, group = 0, frame = 3, name = 65535 | 297 | RAW-NEXT: Section 0002 | ovl = 0, group = 0, frame = 3, name = 65535 |
| 281 | RAW-NEXT: class = 65535, offset = 0, size = | 298 | RAW-NEXT: class = 65535, offset = 0, size = |
| 282 | RAW-NEXT: flags = read | 32 bit addr | selector | 299 | RAW-NEXT: flags = read | 32 bit addr | selector |
| 283 | RAW-NEXT: Section 0003 | ovl = 0, group = 0, frame = 4, name = 65535 | 300 | RAW-NEXT: Section 0003 | ovl = 0, group = 0, frame = 4, name = 65535 |
| 284 | RAW-NEXT: class = 65535, offset = 0, size = | 301 | RAW-NEXT: class = 65535, offset = 0, size = 4294967295 |
| 285 | RAW-NEXT: flags = read | 32 bit addr | selector | ||
| 286 | RAW-NEXT: Section 0004 | ovl = 0, group = 0, frame = 5, name = 65535 | ||
| 287 | RAW-NEXT: class = 65535, offset = 0, size = | ||
| 288 | RAW-NEXT: flags = 32 bit addr | absolute addr | 302 | RAW-NEXT: flags = 32 bit addr | absolute addr |
deps/lld/test/COFF/pending-comdat.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.obj | ||
| 4 | |||
| 5 | # RUN: not lld-link -lldmingw -out:%t.exe -entry:main -subsystem:console %t.obj 2>&1 | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: error: undefined symbol: other | ||
| 8 | |||
| 9 | # Check that the comdat section without a symbol isn't left pending once we iterate symbols | ||
| 10 | # to print source of the undefined symbol. | ||
| 11 | |||
| 12 | 	.text | ||
| 13 | 	.globl main | ||
| 14 | main: | ||
| 15 | 	call other | ||
| 16 | 	ret | ||
| 17 | |||
| 18 | 	.section	.data$pending,"w" | ||
| 19 | 	.linkonce	discard | ||
| 20 | .Llocal: | ||
| 21 | 	.byte	0 | ||
deps/lld/test/COFF/reloc-arm.test+8-8| ... | @@ -3,14 +3,14 @@ | ... | @@ -3,14 +3,14 @@ |
| 3 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | 3 | # RUN: llvm-objdump -s %t.exe | FileCheck %s |
| 4 | 4 | ||
| 5 | # CHECK: .text: | 5 | # CHECK: .text: |
| 6 | # CHECK: 402000 01104000 00000000 00000000 00000000 | 6 | # CHECK: 401000 01204000 00000000 00000000 00000000 |
| 7 | # CHECK: 402010 01100000 00000000 00000000 00000000 | 7 | # CHECK: 401010 01200000 00000000 00000000 00000000 |
| 8 | # CHECK: 402020 41f20009 c0f24009 00000000 00000000 | 8 | # CHECK: 401020 42f20009 c0f24009 00000000 00000000 |
| 9 | # CHECK: 402030 fe07e62f 00000000 00000000 00000000 | 9 | # CHECK: 401030 0000e62f 00000000 00000000 00000000 |
| 10 | # CHECK: 402040 3e04de2f 00000000 00000000 00000000 | 10 | # CHECK: 401040 0000de07 00000000 00000000 00000000 |
| 11 | # CHECK: 402050 fe07d62f 00000000 00000000 00000000 | 11 | # CHECK: 401050 0000d62f 00000000 00000000 00000000 |
| 12 | # CHECK: 402060 fef0cef7 00000000 00000000 00000000 | 12 | # CHECK: 401060 00f1cef7 00000000 00000000 00000000 |
| 13 | # CHECK: 402070 00005000 00000000 00000000 00000000 | 13 | # CHECK: 401070 00005000 00000000 00000000 00000000 |
| 14 | 14 | ||
| 15 | --- !COFF | 15 | --- !COFF |
| 16 | header: | 16 | header: |
deps/lld/test/COFF/reloc-discarded-dwarf.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t1.obj %s | 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t1.obj %s |
| 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t2.obj %s | 3 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t2.obj %s |
| 3 | 4 |
deps/lld/test/COFF/reloc-discarded-early.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s | 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s |
| 2 | # RUN: lld-link -entry:__ImageBase -subsystem:console -debug %t.obj | 3 | # RUN: lld-link -entry:__ImageBase -subsystem:console -debug %t.obj |
| 3 | 4 |
deps/lld/test/COFF/reloc-discarded-early2.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s | 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s |
| 2 | # RUN: not lld-link -entry:__ImageBase -subsystem:console %t.obj 2>&1 | FileCheck %s | 3 | # RUN: not lld-link -entry:__ImageBase -subsystem:console %t.obj 2>&1 | FileCheck %s |
| 3 | 4 |
deps/lld/test/COFF/reloc-discarded.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: echo -e '.section .bss,"bw",discard,main_global\n.global main_global\n main_global:\n .long 0' | \ | 2 | # RUN: echo -e '.section .bss,"bw",discard,main_global\n.global main_global\n main_global:\n .long 0' | \ |
| 2 | # RUN: llvm-mc - -filetype=obj -o %t1.obj -triple x86_64-windows-msvc | 3 | # RUN: llvm-mc - -filetype=obj -o %t1.obj -triple x86_64-windows-msvc |
| 3 | # RUN: llvm-mc %s -filetype=obj -o %t2.obj -triple x86_64-windows-msvc | 4 | # RUN: llvm-mc %s -filetype=obj -o %t2.obj -triple x86_64-windows-msvc |
deps/lld/test/COFF/reloc-x64.test+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: yaml2obj < %s > %t.obj | 2 | # RUN: yaml2obj < %s > %t.obj |
| 2 | # RUN: lld-link /out:%t.exe /entry:main %t.obj | 3 | # RUN: lld-link /out:%t.exe /entry:main %t.obj |
| 3 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | 4 | # RUN: llvm-objdump -d %t.exe | FileCheck %s |
deps/lld/test/COFF/reloc-x86.test+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: yaml2obj < %s > %t.obj | 2 | # RUN: yaml2obj < %s > %t.obj |
| 2 | # RUN: lld-link /out:%t.exe /entry:main /base:0x400000 %t.obj | 3 | # RUN: lld-link /out:%t.exe /entry:main /base:0x400000 %t.obj |
| 3 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | 4 | # RUN: llvm-objdump -d %t.exe | FileCheck %s |
deps/lld/test/COFF/resource.test+7-7| ... | @@ -10,11 +10,11 @@ EXE: {{H.e.l.l.o}} | ... | @@ -10,11 +10,11 @@ EXE: {{H.e.l.l.o}} |
| 10 | # RUN: llvm-readobj -file-headers -coff-resources -section-data %t.exe | \ | 10 | # RUN: llvm-readobj -file-headers -coff-resources -section-data %t.exe | \ |
| 11 | # RUN: FileCheck --check-prefix=RESOURCE_INFO %s | 11 | # RUN: FileCheck --check-prefix=RESOURCE_INFO %s |
| 12 | 12 | ||
| 13 | RESOURCE_INFO: ResourceTableRVA: 0x1000 | 13 | RESOURCE_INFO: ResourceTableRVA: 0x2000 |
| 14 | RESOURCE_INFO-NEXT: ResourceTableSize: 0x88 | 14 | RESOURCE_INFO-NEXT: ResourceTableSize: 0x90 |
| 15 | RESOURCE_INFO-DAG: Resources [ | 15 | RESOURCE_INFO-DAG: Resources [ |
| 16 | RESOURCE_INFO-NEXT: Total Number of Resources: 1 | 16 | RESOURCE_INFO-NEXT: Total Number of Resources: 1 |
| 17 | RESOURCE_INFO-NEXT: Base Table Address: 0x400 | 17 | RESOURCE_INFO-NEXT: Base Table Address: 0x600 |
| 18 | RESOURCE_INFO-DAG: Number of String Entries: 0 | 18 | RESOURCE_INFO-DAG: Number of String Entries: 0 |
| 19 | RESOURCE_INFO-NEXT: Number of ID Entries: 1 | 19 | RESOURCE_INFO-NEXT: Number of ID Entries: 1 |
| 20 | RESOURCE_INFO-NEXT: Type: kRT_STRING (ID 6) [ | 20 | RESOURCE_INFO-NEXT: Type: kRT_STRING (ID 6) [ |
| ... | @@ -36,9 +36,9 @@ RESOURCE_INFO-NEXT: 0000: 00000000 00000000 00000000 00000100 |................ | ... | @@ -36,9 +36,9 @@ RESOURCE_INFO-NEXT: 0000: 00000000 00000000 00000000 00000100 |................ |
| 36 | RESOURCE_INFO-NEXT: 0010: 06000000 18000080 00000000 00000000 |................| | 36 | RESOURCE_INFO-NEXT: 0010: 06000000 18000080 00000000 00000000 |................| |
| 37 | RESOURCE_INFO-NEXT: 0020: 00000000 00000100 01000000 30000080 |............0...| | 37 | RESOURCE_INFO-NEXT: 0020: 00000000 00000100 01000000 30000080 |............0...| |
| 38 | RESOURCE_INFO-NEXT: 0030: 00000000 00000000 00000000 00000100 |................| | 38 | RESOURCE_INFO-NEXT: 0030: 00000000 00000000 00000000 00000100 |................| |
| 39 | RESOURCE_INFO-NEXT: 0040: 09040000 48000000 58100000 2A000000 |....H...X...*...| | 39 | RESOURCE_INFO-NEXT: 0040: 09040000 48000000 60200000 2A000000 |....H...` ..*...| |
| 40 | RESOURCE_INFO-NEXT: 0050: 00000000 00000000 00000500 48006500 |............H.e.| | 40 | RESOURCE_INFO-NEXT: 0050: 00000000 00000000 00000000 00000000 |................| |
| 41 | RESOURCE_INFO-NEXT: 0060: 6C006C00 6F000000 00000000 00000000 |l.l.o...........| | 41 | RESOURCE_INFO-NEXT: 0060: 00000500 48006500 6C006C00 6F000000 |....H.e.l.l.o...| |
| 42 | RESOURCE_INFO-NEXT: 0070: 00000000 00000000 00000000 00000000 |................| | 42 | RESOURCE_INFO-NEXT: 0070: 00000000 00000000 00000000 00000000 |................| |
| 43 | RESOURCE_INFO-NEXT: 0080: 00000000 00000000 |........| | 43 | RESOURCE_INFO-NEXT: 0080: 00000000 00000000 00000000 00000000 |................| |
| 44 | RESOURCE_INFO-NEXT: ) | 44 | RESOURCE_INFO-NEXT: ) |
deps/lld/test/COFF/rsds.test+8-8| ... | @@ -1,16 +1,16 @@ | ... | @@ -1,16 +1,16 @@ |
| 1 | # RUN: yaml2obj %s > %t.obj | 1 | # RUN: yaml2obj %s > %t.obj |
| 2 | 2 | ||
| 3 | # RUN: rm -f %t.dll %t.pdb | 3 | # RUN: rm -f %t.dll %t.pdb |
| 4 | # RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj | 4 | # RUN: lld-link /debug /pdbaltpath:test1.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 |
| 6 | # RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj | 6 | # RUN: lld-link /debug /pdbaltpath:test2.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 |
| 8 | # RUN: cat %t.1.txt %t.2.txt | FileCheck %s | 8 | # RUN: cat %t.1.txt %t.2.txt | FileCheck %s |
| 9 | 9 | ||
| 10 | # RUN: rm -f %t.dll %t.pdb | 10 | # RUN: rm -f %t.dll %t.pdb |
| 11 | # RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj | 11 | # 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 |
| 13 | # RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj | 13 | # 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 |
| 15 | # RUN: cat %t.3.txt %t.4.txt | FileCheck %s | 15 | # RUN: cat %t.3.txt %t.4.txt | FileCheck %s |
| 16 | 16 | ||
| ... | @@ -18,7 +18,7 @@ | ... | @@ -18,7 +18,7 @@ |
| 18 | # CHECK: DebugDirectory [ | 18 | # CHECK: DebugDirectory [ |
| 19 | # CHECK: DebugEntry { | 19 | # CHECK: DebugEntry { |
| 20 | # CHECK: Characteristics: 0x0 | 20 | # CHECK: Characteristics: 0x0 |
| 21 | # CHECK: TimeDateStamp: 1970-01-01 00:00:00 (0x0) | 21 | # CHECK: TimeDateStamp: |
| 22 | # CHECK: MajorVersion: 0x0 | 22 | # CHECK: MajorVersion: 0x0 |
| 23 | # CHECK: MinorVersion: 0x0 | 23 | # CHECK: MinorVersion: 0x0 |
| 24 | # CHECK: Type: CodeView (0x2) | 24 | # CHECK: Type: CodeView (0x2) |
| ... | @@ -29,7 +29,7 @@ | ... | @@ -29,7 +29,7 @@ |
| 29 | # CHECK: PDBSignature: 0x53445352 | 29 | # CHECK: PDBSignature: 0x53445352 |
| 30 | # CHECK: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]] | 30 | # CHECK: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]] |
| 31 | # CHECK: PDBAge: 1 | 31 | # CHECK: PDBAge: 1 |
| 32 | # CHECK: PDBFileName: {{.*}}.pdb | 32 | # CHECK: PDBFileName: {{.*}}1.pdb |
| 33 | # CHECK: } | 33 | # CHECK: } |
| 34 | # CHECK: } | 34 | # CHECK: } |
| 35 | # CHECK: ] | 35 | # CHECK: ] |
| ... | @@ -37,7 +37,7 @@ | ... | @@ -37,7 +37,7 @@ |
| 37 | # CHECK: DebugDirectory [ | 37 | # CHECK: DebugDirectory [ |
| 38 | # CHECK: DebugEntry { | 38 | # CHECK: DebugEntry { |
| 39 | # CHECK: Characteristics: 0x0 | 39 | # CHECK: Characteristics: 0x0 |
| 40 | # CHECK: TimeDateStamp: 1970-01-01 00:00:00 (0x0) | 40 | # CHECK: TimeDateStamp: |
| 41 | # CHECK: MajorVersion: 0x0 | 41 | # CHECK: MajorVersion: 0x0 |
| 42 | # CHECK: MinorVersion: 0x0 | 42 | # CHECK: MinorVersion: 0x0 |
| 43 | # CHECK: Type: CodeView (0x2) | 43 | # CHECK: Type: CodeView (0x2) |
| ... | @@ -48,7 +48,7 @@ | ... | @@ -48,7 +48,7 @@ |
| 48 | # CHECK: PDBSignature: 0x53445352 | 48 | # CHECK: PDBSignature: 0x53445352 |
| 49 | # CHECK: PDBGUID: [[GUID]] | 49 | # CHECK: PDBGUID: [[GUID]] |
| 50 | # CHECK: PDBAge: 2 | 50 | # CHECK: PDBAge: 2 |
| 51 | # CHECK: PDBFileName: {{.*}}.pdb | 51 | # CHECK: PDBFileName: {{.*}}2.pdb |
| 52 | # CHECK: } | 52 | # CHECK: } |
| 53 | # CHECK: } | 53 | # CHECK: } |
| 54 | # CHECK: ] | 54 | # CHECK: ] |
deps/lld/test/COFF/safeseh-md.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj | 2 | # RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj |
| 2 | # RUN: lld-link %t.obj %S/Inputs/except_handler3.lib -safeseh -out:%t.exe -opt:noref -entry:main | 3 | # RUN: lld-link %t.obj %S/Inputs/except_handler3.lib -safeseh -out:%t.exe -opt:noref -entry:main |
| 3 | # RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s | 4 | # RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s |
deps/lld/test/COFF/safeseh-notable.s created+44| ... | @@ -0,0 +1,44 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj | ||
| 3 | # RUN: lld-link %t.obj -safeseh -out:%t.exe -entry:main | ||
| 4 | # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s | ||
| 5 | |||
| 6 | # This object lacks a _load_config_used global, so we set | ||
| 7 | # IMAGE_DLL_CHARACTERISTICS_NO_SEH even though there is an exception handler. | ||
| 8 | # This is a more secure default. If someone wants to use a CRT without a load | ||
| 9 | # config and they want to use 32-bit SEH, they will need to provide a | ||
| 10 | # safeseh-compatible load config. | ||
| 11 | |||
| 12 | # CHECK-LABEL: Characteristics [ | ||
| 13 | # CHECK: IMAGE_DLL_CHARACTERISTICS_NO_SEH | ||
| 14 | # CHECK: ] | ||
| 15 | |||
| 16 | # CHECK-LABEL: DataDirectory { | ||
| 17 | # CHECK: LoadConfigTableRVA: 0x0 | ||
| 18 | # CHECK: LoadConfigTableSize: 0x0 | ||
| 19 | # CHECK: } | ||
| 20 | |||
| 21 | # CHECK-NOT: LoadConfig | ||
| 22 | # CHECK-NOT: SEHTable | ||
| 23 | |||
| 24 | .def @feat.00; | ||
| 25 | .scl 3; | ||
| 26 | .type 0; | ||
| 27 | .endef | ||
| 28 | .globl @feat.00 | ||
| 29 | @feat.00 = 1 | ||
| 30 | |||
| 31 | .text | ||
| 32 | .def _main; .scl 2; .type 32; .endef | ||
| 33 | .globl _main | ||
| 34 | _main: | ||
| 35 | pushl $_my_handler | ||
| 36 | movl $42, %eax | ||
| 37 | popl %ecx | ||
| 38 | ret | ||
| 39 | |||
| 40 | .def _my_handler; .scl 3; .type 32; .endef | ||
| 41 | _my_handler: | ||
| 42 | ret | ||
| 43 | |||
| 44 | .safeseh _my_handler | ||
deps/lld/test/COFF/safeseh.s+14-5| ... | @@ -1,27 +1,36 @@ | ... | @@ -1,27 +1,36 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj | 2 | # RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj |
| 2 | # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main | 3 | # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main |
| 3 | # 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 |
| 5 | # 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 | ||
| 4 | # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main | 7 | # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main |
| 5 | # 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 |
| 6 | 9 | ||
| 7 | # __safe_se_handler_table needs to be relocated against ImageBase. | 10 | # __safe_se_handler_table needs to be relocated against ImageBase. |
| 8 | # check that the relocation is present. | 11 | # check that the relocation is present. |
| 12 | # | ||
| 9 | # CHECK-NOGC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH | 13 | # CHECK-NOGC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH |
| 10 | # CHECK-NOGC: BaseReloc [ | 14 | # CHECK-NOGC: BaseReloc [ |
| 11 | # CHECK-NOGC: Entry { | 15 | # CHECK-NOGC: Entry { |
| 12 | # CHECK-NOGC: Type: HIGHLOW | 16 | # CHECK-NOGC: Type: HIGHLOW |
| 13 | # CHECK-NOGC: LoadConfig [ | 17 | # CHECK-NOGC: LoadConfig [ |
| 14 | # CHECK-NOGC: Size: 0x48 | 18 | # CHECK-NOGC: Size: 0x48 |
| 15 | # CHECK-NOGC: SEHandlerTable: 0x401048 | 19 | # CHECK-NOGC: SEHandlerTable: 0x |
| 16 | # CHECK-NOGC: SEHandlerCount: 1 | 20 | # CHECK-NOGC: SEHandlerCount: 1 |
| 17 | # CHECK-NOGC: ] | 21 | # CHECK-NOGC: ] |
| 18 | # CHECK-NOGC: SEHTable [ | 22 | # CHECK-NOGC: SEHTable [ |
| 19 | # CHECK-NOGC-NEXT: 0x402006 | 23 | # CHECK-NOGC-NEXT: 0x401006 |
| 20 | # CHECK-NOGC-NEXT: ] | 24 | # CHECK-NOGC-NEXT: ] |
| 21 | 25 | ||
| 22 | # Without the SEH table, the address is absolute, so check that we do | 26 | # If we enable GC, the exception handler should be removed, and we should add |
| 23 | # not have a relocation for it. | 27 | # the DLL characteristic flag that indicates that there are no exception |
| 24 | # CHECK-GC-NOT: IMAGE_DLL_CHARACTERISTICS_NO_SEH | 28 | # handlers in this DLL. The exception handler table in the load config should |
| 29 | # be empty and there should be no relocations for it. | ||
| 30 | # | ||
| 31 | # CHECK-GC: Characteristics [ | ||
| 32 | # CHECK-GC: IMAGE_DLL_CHARACTERISTICS_NO_SEH | ||
| 33 | # CHECK-GC: ] | ||
| 25 | # CHECK-GC: BaseReloc [ | 34 | # CHECK-GC: BaseReloc [ |
| 26 | # CHECK-GC-NEXT: ] | 35 | # CHECK-GC-NEXT: ] |
| 27 | # CHECK-GC: LoadConfig [ | 36 | # CHECK-GC: LoadConfig [ |
deps/lld/test/COFF/secidx-absolute.s+6-5| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj | 2 | # RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj |
| 2 | # RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe | 3 | # RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe |
| 3 | # RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s | 4 | # RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s |
| ... | @@ -16,17 +17,17 @@ ret | ... | @@ -16,17 +17,17 @@ ret |
| 16 | # CHECK: Sections [ | 17 | # CHECK: Sections [ |
| 17 | # CHECK: Section { | 18 | # CHECK: Section { |
| 18 | # CHECK: Number: 1 | 19 | # CHECK: Number: 1 |
| 19 | # CHECK: Name: .rdata (2E 72 64 61 74 61 00 00) | 20 | # CHECK: Name: .text (2E 74 65 78 74 00 00 00) |
| 21 | # CHECK: VirtualSize: 0x1 | ||
| 20 | # CHECK: SectionData ( | 22 | # CHECK: SectionData ( |
| 21 | # CHECK: 0000: 0300 |..| | 23 | # CHECK: 0000: C3 |.| |
| 22 | # CHECK: ) | 24 | # CHECK: ) |
| 23 | # CHECK: } | 25 | # CHECK: } |
| 24 | # CHECK: Section { | 26 | # CHECK: Section { |
| 25 | # CHECK: Number: 2 | 27 | # CHECK: Number: 2 |
| 26 | # CHECK: Name: .text (2E 74 65 78 74 00 00 00) | 28 | # CHECK: Name: .rdata (2E 72 64 61 74 61 00 00) |
| 27 | # CHECK: VirtualSize: 0x1 | ||
| 28 | # CHECK: SectionData ( | 29 | # CHECK: SectionData ( |
| 29 | # CHECK: 0000: C3 |.| | 30 | # CHECK: 0000: 0300 |..| |
| 30 | # CHECK: ) | 31 | # CHECK: ) |
| 31 | # CHECK: } | 32 | # CHECK: } |
| 32 | # CHECK-NOT: Section | 33 | # CHECK-NOT: Section |
deps/lld/test/COFF/secrel-absolute.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj | 2 | # RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj |
| 2 | # RUN: not lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe 2>&1 | FileCheck %s | 3 | # RUN: not lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe 2>&1 | FileCheck %s |
| 3 | 4 |
deps/lld/test/COFF/secrel-common.s+14-9| ... | @@ -1,29 +1,31 @@ | ... | @@ -1,29 +1,31 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj | 2 | # RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj |
| 2 | # RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe | 3 | # RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe |
| 3 | # RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s | 4 | # RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s |
| 4 | 5 | ||
| 5 | # Section relocations against common symbols resolve to .bss. | 6 | # Section relocations against common symbols resolve to .bss (merged into .data). |
| 6 | 7 | ||
| 7 | # CHECK: Sections [ | 8 | # CHECK: Sections [ |
| 8 | # CHECK: Section { | 9 | # CHECK: Section { |
| 9 | # CHECK: Number: 1 | 10 | # CHECK: Number: 1 |
| 10 | # CHECK: Name: .bss (2E 62 73 73 00 00 00 00) | 11 | # CHECK: Name: .text (2E 74 65 78 74 00 00 00) |
| 11 | # CHECK: VirtualSize: 0x4 | 12 | # CHECK: VirtualSize: 0x1 |
| 13 | # CHECK: SectionData ( | ||
| 14 | # CHECK: 0000: C3 |.| | ||
| 15 | # CHECK: ) | ||
| 12 | # CHECK: } | 16 | # CHECK: } |
| 13 | # CHECK: Section { | 17 | # CHECK: Section { |
| 14 | # CHECK: Number: 2 | 18 | # CHECK: Number: 2 |
| 15 | # CHECK: Name: .rdata (2E 72 64 61 74 61 00 00) | 19 | # CHECK: Name: .rdata (2E 72 64 61 74 61 00 00) |
| 16 | # CHECK: SectionData ( | 20 | # CHECK: SectionData ( |
| 17 | # CHECK: 0000: 00000000 01000000 |........| | 21 | # CHECK: 0000: 00020000 03000000 |........| |
| 18 | # CHECK: ) | 22 | # CHECK: ) |
| 19 | # CHECK: } | 23 | # CHECK: } |
| 20 | # CHECK: Section { | 24 | # CHECK: Section { |
| 21 | # CHECK: Number: 3 | 25 | # CHECK: Number: 3 |
| 22 | # CHECK: Name: .text (2E 74 65 78 74 00 00 00) | 26 | # CHECK: Name: .data (2E 64 61 74 61 00 00 00) |
| 23 | # CHECK: VirtualSize: 0x1 | 27 | # CHECK: VirtualSize: 0x204 |
| 24 | # CHECK: SectionData ( | 28 | # CHECK: RawDataSize: 512 |
| 25 | # CHECK: 0000: C3 |.| | ||
| 26 | # CHECK: ) | ||
| 27 | # CHECK: } | 29 | # CHECK: } |
| 28 | # CHECK-NOT: Section | 30 | # CHECK-NOT: Section |
| 29 | # CHECK: ] | 31 | # CHECK: ] |
| ... | @@ -39,3 +41,6 @@ ret | ... | @@ -39,3 +41,6 @@ ret |
| 39 | .secrel32 common_global | 41 | .secrel32 common_global |
| 40 | .secidx common_global | 42 | .secidx common_global |
| 41 | .short 0 | 43 | .short 0 |
| 44 | |||
| 45 | .section .data,"drw" | ||
| 46 | .zero 512 |
deps/lld/test/COFF/section-order.test created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # RUN: yaml2obj < %p/Inputs/include1a.yaml > %t1.obj | ||
| 2 | # RUN: yaml2obj < %p/Inputs/include1b.yaml > %t2.obj | ||
| 3 | # RUN: yaml2obj < %p/Inputs/include1c.yaml > %t3.obj | ||
| 4 | # RUN: rm -f %t2.lib %t3.lib | ||
| 5 | # RUN: llvm-ar cru %t2.lib %t2.obj | ||
| 6 | # RUN: llvm-ar cru %t3.lib %t3.obj | ||
| 7 | # RUN: lld-link /out:%t.exe /entry:main \ | ||
| 8 | # RUN: %t1.obj %t2.lib %t3.obj %t3.lib /verbose >& %t.log | ||
| 9 | # RUN: FileCheck %s < %t.log | ||
| 10 | |||
| 11 | CHECK: section-order.test.tmp1.obj | ||
| 12 | CHECK: section-order.test.tmp2.lib | ||
| 13 | CHECK: section-order.test.tmp3.obj | ||
| 14 | CHECK: section-order.test.tmp3.lib | ||
| 15 | CHECK: section-order.test.tmp2.lib(section-order.test.tmp2.obj) for foo | ||
deps/lld/test/COFF/section-size.s+1-1| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | # Run: lld-link -entry:main %tmain.obj %t3.obj -out:%t.exe | 7 | # Run: lld-link -entry:main %tmain.obj %t3.obj -out:%t.exe |
| 8 | 8 | ||
| 9 | # RUN: not lld-link -entry:main %tmain.obj %t1.obj %t2.obj -out:%t.exe 2>&1 | FileCheck %s | 9 | # RUN: not lld-link -entry:main %tmain.obj %t1.obj %t2.obj -out:%t.exe 2>&1 | FileCheck %s |
| 10 | # CHECK: error: section larger than 4 GiB: .bss | 10 | # CHECK: error: section larger than 4 GiB: .data |
| 11 | 11 | ||
| 12 | .globl main | 12 | .globl main |
| 13 | main: | 13 | main: |
deps/lld/test/COFF/section.test+4| ... | @@ -16,18 +16,22 @@ | ... | @@ -16,18 +16,22 @@ |
| 16 | # RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=S %s | 16 | # RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=S %s |
| 17 | 17 | ||
| 18 | # R: Characteristics [ | 18 | # R: Characteristics [ |
| 19 | # R-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 19 | # R-NEXT: IMAGE_SCN_MEM_READ | 20 | # R-NEXT: IMAGE_SCN_MEM_READ |
| 20 | # R-NEXT: ] | 21 | # R-NEXT: ] |
| 21 | 22 | ||
| 22 | # W: Characteristics [ | 23 | # W: Characteristics [ |
| 24 | # W-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 23 | # W-NEXT: IMAGE_SCN_MEM_WRITE | 25 | # W-NEXT: IMAGE_SCN_MEM_WRITE |
| 24 | # W-NEXT: ] | 26 | # W-NEXT: ] |
| 25 | 27 | ||
| 26 | # E: Characteristics [ | 28 | # E: Characteristics [ |
| 29 | # E-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 27 | # E-NEXT: IMAGE_SCN_MEM_EXECUTE | 30 | # E-NEXT: IMAGE_SCN_MEM_EXECUTE |
| 28 | # E-NEXT: ] | 31 | # E-NEXT: ] |
| 29 | 32 | ||
| 30 | # S: Characteristics [ | 33 | # S: Characteristics [ |
| 34 | # S-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | ||
| 31 | # S-NEXT: IMAGE_SCN_MEM_SHARED | 35 | # S-NEXT: IMAGE_SCN_MEM_SHARED |
| 32 | # S-NEXT: ] | 36 | # S-NEXT: ] |
| 33 | 37 |
deps/lld/test/COFF/sort-debug.test+14-1| ... | @@ -1,15 +1,28 @@ | ... | @@ -1,15 +1,28 @@ |
| 1 | # RUN: yaml2obj < %s > %t.obj | 1 | # RUN: yaml2obj < %s > %t.obj |
| 2 | # RUN: lld-link /debug /out:%t.exe /entry:main %t.obj | 2 | # 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 |
| 4 | # RUN: lld-link /debug:dwarf /out:%t.exe /entry:main %t.obj | ||
| 5 | # RUN: llvm-readobj -sections %t.exe | FileCheck %s | ||
| 6 | # RUN: lld-link /out:%t.exe /entry:main %t.obj | ||
| 7 | # RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=NODEBUG %s | ||
| 8 | # RUN: lld-link /debug:symtab /out:%t.exe /entry:main %t.obj | ||
| 9 | # RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=NODEBUG %s | ||
| 4 | 10 | ||
| 5 | # CHECK: Name: .text | 11 | # CHECK: Name: .text |
| 12 | # CHECK: Name: .reloc | ||
| 6 | # CHECK: Name: .debug_abbrev | 13 | # CHECK: Name: .debug_abbrev |
| 7 | # CHECK: Name: .debug_info | 14 | # CHECK: Name: .debug_info |
| 8 | # CHECK: Name: .debug_line | 15 | # CHECK: Name: .debug_line |
| 9 | # CHECK: Name: .debug_pubnames | 16 | # CHECK: Name: .debug_pubnames |
| 10 | # CHECK: Name: .debug_pubtypes | 17 | # CHECK: Name: .debug_pubtypes |
| 11 | # CHECK: Name: .reloc | ||
| 12 | 18 | ||
| 19 | # NODEBUG: Name: .text | ||
| 20 | # NODEBUG: Name: .reloc | ||
| 21 | # NODEBUG-NOT: Name: .debug_abbrev | ||
| 22 | # NODEBUG-NOT: Name: .debug_info | ||
| 23 | # NODEBUG-NOT: Name: .debug_line | ||
| 24 | # NODEBUG-NOT: Name: .debug_pubnames | ||
| 25 | # NODEBUG-NOT: Name: .debug_pubtypes | ||
| 13 | 26 | ||
| 14 | --- !COFF | 27 | --- !COFF |
| 15 | header: | 28 | header: |
deps/lld/test/COFF/string-tail-merge.s created+106| ... | @@ -0,0 +1,106 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s | ||
| 3 | # RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console | ||
| 4 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | ||
| 5 | # RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:noicf /opt:lldtailmerge | ||
| 6 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | ||
| 7 | # RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:noicf | ||
| 8 | # RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=NOSTM %s | ||
| 9 | # RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:nolldtailmerge | ||
| 10 | # RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=NOSTM %s | ||
| 11 | |||
| 12 | # CHECK: Contents of section .text: | ||
| 13 | # NOSTM: Contents of section .text: | ||
| 14 | .globl main | ||
| 15 | main: | ||
| 16 | # CHECK-NEXT: 140001000 11200040 01000000 17200040 01000000 | ||
| 17 | # NOSTM-NEXT: 140001000 00200040 01000000 0c200040 01000000 | ||
| 18 | .8byte "??_C@_0M@LACCCNMM@hello?5world?$AA@" | ||
| 19 | .8byte "??_C@_05MCBCHHEJ@world?$AA@" | ||
| 20 | # CHECK-NEXT: 140001010 2a200040 01000000 36200040 01000000 | ||
| 21 | # NOSTM-NEXT: 140001010 12200040 01000000 2a200040 01000000 | ||
| 22 | .8byte "??_C@_1BI@HHJHKLLN@?$AAh?$AAe?$AAl?$AAl?$AAo?$AA?5?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@" | ||
| 23 | .8byte "??_C@_1M@NBBDDHIO@?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@" | ||
| 24 | # CHECK-NEXT: 140001020 00200040 01000000 0c200040 01000000 | ||
| 25 | # NOSTM-NEXT: 140001020 36200040 01000000 42200040 01000000 | ||
| 26 | .8byte "??_D@not_a_string_literal" | ||
| 27 | .8byte "??_C@string_literal_with_relocs" | ||
| 28 | # CHECK-NEXT: 140001030 00300040 01000000 1e200040 01000000 | ||
| 29 | # NOSTM-NEXT: 140001030 00300040 01000000 48200040 01000000 | ||
| 30 | .8byte "??_C@string_literal_in_wrong_section" | ||
| 31 | .8byte "??_C@overaligned_string_literal" | ||
| 32 | |||
| 33 | # CHECK: Contents of section .rdata: | ||
| 34 | # CHECK-NEXT: 140002000 68656c6c 6f20776f 726c6400 6f826ca4 hello world.o.l. | ||
| 35 | # CHECK-NEXT: 140002010 0068656c 6c6f2077 6f726c64 00006865 .hello world..he | ||
| 36 | # CHECK-NEXT: 140002020 6c6c6f20 776f726c 64006800 65006c00 llo world.h.e.l. | ||
| 37 | # CHECK-NEXT: 140002030 6c006f00 20007700 6f007200 6c006400 l.o. .w.o.r.l.d. | ||
| 38 | # CHECK-NEXT: 140002040 0000 .. | ||
| 39 | |||
| 40 | # NOSTM: Contents of section .rdata: | ||
| 41 | # NOSTM-NEXT: 140002000 68656c6c 6f20776f 726c6400 776f726c hello world.worl | ||
| 42 | # NOSTM-NEXT: 140002010 64006800 65006c00 6c006f00 20007700 d.h.e.l.l.o. .w. | ||
| 43 | # NOSTM-NEXT: 140002020 6f007200 6c006400 00007700 6f007200 o.r.l.d...w.o.r. | ||
| 44 | # NOSTM-NEXT: 140002030 6c006400 00006865 6c6c6f20 776f726c l.d...hello worl | ||
| 45 | # NOSTM-NEXT: 140002040 64006f82 6ca40000 68656c6c 6f20776f d.o.l...hello wo | ||
| 46 | # NOSTM-NEXT: 140002050 726c6400 rld. | ||
| 47 | |||
| 48 | .section .rdata,"dr",discard,"??_C@_0M@LACCCNMM@hello?5world?$AA@" | ||
| 49 | .globl "??_C@_0M@LACCCNMM@hello?5world?$AA@" | ||
| 50 | "??_C@_0M@LACCCNMM@hello?5world?$AA@": | ||
| 51 | .asciz "hello world" | ||
| 52 | |||
| 53 | .section .rdata,"dr",discard,"??_C@_05MCBCHHEJ@world?$AA@" | ||
| 54 | .globl "??_C@_05MCBCHHEJ@world?$AA@" | ||
| 55 | "??_C@_05MCBCHHEJ@world?$AA@": | ||
| 56 | .asciz "world" | ||
| 57 | |||
| 58 | .section .rdata,"dr",discard,"??_C@_1BI@HHJHKLLN@?$AAh?$AAe?$AAl?$AAl?$AAo?$AA?5?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@" | ||
| 59 | .globl "??_C@_1BI@HHJHKLLN@?$AAh?$AAe?$AAl?$AAl?$AAo?$AA?5?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@" | ||
| 60 | .p2align 1 | ||
| 61 | "??_C@_1BI@HHJHKLLN@?$AAh?$AAe?$AAl?$AAl?$AAo?$AA?5?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@": | ||
| 62 | .short 104 | ||
| 63 | .short 101 | ||
| 64 | .short 108 | ||
| 65 | .short 108 | ||
| 66 | .short 111 | ||
| 67 | .short 32 | ||
| 68 | .short 119 | ||
| 69 | .short 111 | ||
| 70 | .short 114 | ||
| 71 | .short 108 | ||
| 72 | .short 100 | ||
| 73 | .short 0 | ||
| 74 | |||
| 75 | .section .rdata,"dr",discard,"??_C@_1M@NBBDDHIO@?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@" | ||
| 76 | .globl "??_C@_1M@NBBDDHIO@?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@" | ||
| 77 | .p2align 1 | ||
| 78 | "??_C@_1M@NBBDDHIO@?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@": | ||
| 79 | .short 119 | ||
| 80 | .short 111 | ||
| 81 | .short 114 | ||
| 82 | .short 108 | ||
| 83 | .short 100 | ||
| 84 | .short 0 | ||
| 85 | |||
| 86 | .section .data,"drw",discard,"??_C@string_literal_in_wrong_section" | ||
| 87 | .globl "??_C@string_literal_in_wrong_section" | ||
| 88 | "??_C@string_literal_in_wrong_section": | ||
| 89 | .asciz "hello world" | ||
| 90 | |||
| 91 | .section .rdata,"dr",discard,"??_D@not_a_string_literal" | ||
| 92 | .globl "??_D@not_a_string_literal" | ||
| 93 | "??_D@not_a_string_literal": | ||
| 94 | .asciz "hello world" | ||
| 95 | |||
| 96 | .section .rdata,"dr",discard,"??_C@string_literal_with_relocs" | ||
| 97 | .globl "??_C@string_literal_with_relocs" | ||
| 98 | "??_C@string_literal_with_relocs": | ||
| 99 | .4byte main + 111 + (114 << 8) + (108 << 16) + (100 << 24) # main + "orld" | ||
| 100 | .byte 0 | ||
| 101 | |||
| 102 | .section .rdata,"dr",discard,"??_C@overaligned_string_literal" | ||
| 103 | .globl "??_C@overaligned_string_literal" | ||
| 104 | .p2align 1 | ||
| 105 | "??_C@overaligned_string_literal": | ||
| 106 | .asciz "hello world" | ||
deps/lld/test/COFF/symtab-gc.s created+27| ... | @@ -0,0 +1,27 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %tobject.obj %S/Inputs/object.s | ||
| 4 | # RUN: lld-link -dll -entry:f -out:%t.dll -implib:%t.lib %tobject.obj | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %tmain.obj %s | ||
| 6 | # 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 | ||
| 8 | |||
| 9 | # CHECK-NOT: Symbol: f | ||
| 10 | |||
| 11 | 	.def	 main; | ||
| 12 | 	.scl	2; | ||
| 13 | 	.type	32; | ||
| 14 | 	.endef | ||
| 15 | 	.section	.text,"xr",one_only,main | ||
| 16 | 	.globl	main | ||
| 17 | main: | ||
| 18 | 	retq | ||
| 19 | |||
| 20 | 	.def	 stripped; | ||
| 21 | 	.scl	3; | ||
| 22 | 	.type	32; | ||
| 23 | 	.endef | ||
| 24 | 	.section	.text,"xr",one_only,stripped | ||
| 25 | stripped: | ||
| 26 | 	callq	__imp_f | ||
| 27 | 	retq | ||
deps/lld/test/COFF/symtab.test+10-8| ... | @@ -3,6 +3,8 @@ | ... | @@ -3,6 +3,8 @@ |
| 3 | # RUN: llvm-readobj -symbols %t.exe | FileCheck %s | 3 | # RUN: llvm-readobj -symbols %t.exe | FileCheck %s |
| 4 | # RUN: lld-link /debug:dwarf /opt:noref /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib | 4 | # 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 |
| 6 | # 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 | ||
| 6 | 8 | ||
| 7 | # RUN: lld-link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib | 9 | # RUN: lld-link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib |
| 8 | # RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=NO %s | 10 | # RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=NO %s |
| ... | @@ -11,7 +13,7 @@ | ... | @@ -11,7 +13,7 @@ |
| 11 | # CHECK-NEXT: Symbol { | 13 | # CHECK-NEXT: Symbol { |
| 12 | # CHECK-NEXT: Name: .text | 14 | # CHECK-NEXT: Name: .text |
| 13 | # CHECK-NEXT: Value: 0 | 15 | # CHECK-NEXT: Value: 0 |
| 14 | # CHECK-NEXT: Section: .text (2) | 16 | # CHECK-NEXT: Section: .text (1) |
| 15 | # CHECK-NEXT: BaseType: Null (0x0) | 17 | # CHECK-NEXT: BaseType: Null (0x0) |
| 16 | # CHECK-NEXT: ComplexType: Null (0x0) | 18 | # CHECK-NEXT: ComplexType: Null (0x0) |
| 17 | # CHECK-NEXT: StorageClass: Static (0x3) | 19 | # CHECK-NEXT: StorageClass: Static (0x3) |
| ... | @@ -20,7 +22,7 @@ | ... | @@ -20,7 +22,7 @@ |
| 20 | # CHECK-NEXT: Symbol { | 22 | # CHECK-NEXT: Symbol { |
| 21 | # CHECK-NEXT: Name: .text2 | 23 | # CHECK-NEXT: Name: .text2 |
| 22 | # CHECK-NEXT: Value: 0 | 24 | # CHECK-NEXT: Value: 0 |
| 23 | # CHECK-NEXT: Section: .text (2) | 25 | # CHECK-NEXT: Section: .text (1) |
| 24 | # CHECK-NEXT: BaseType: Null (0x0) | 26 | # CHECK-NEXT: BaseType: Null (0x0) |
| 25 | # CHECK-NEXT: ComplexType: Null (0x0) | 27 | # CHECK-NEXT: ComplexType: Null (0x0) |
| 26 | # CHECK-NEXT: StorageClass: Static (0x3) | 28 | # CHECK-NEXT: StorageClass: Static (0x3) |
| ... | @@ -29,7 +31,7 @@ | ... | @@ -29,7 +31,7 @@ |
| 29 | # CHECK-NEXT: Symbol { | 31 | # CHECK-NEXT: Symbol { |
| 30 | # CHECK-NEXT: Name: .data | 32 | # CHECK-NEXT: Name: .data |
| 31 | # CHECK-NEXT: Value: 0 | 33 | # CHECK-NEXT: Value: 0 |
| 32 | # CHECK-NEXT: Section: .data (1) | 34 | # CHECK-NEXT: Section: .data (3) |
| 33 | # CHECK-NEXT: BaseType: Null (0x0) | 35 | # CHECK-NEXT: BaseType: Null (0x0) |
| 34 | # CHECK-NEXT: ComplexType: Null (0x0) | 36 | # CHECK-NEXT: ComplexType: Null (0x0) |
| 35 | # CHECK-NEXT: StorageClass: Static (0x3) | 37 | # CHECK-NEXT: StorageClass: Static (0x3) |
| ... | @@ -38,7 +40,7 @@ | ... | @@ -38,7 +40,7 @@ |
| 38 | # CHECK-NEXT: Symbol { | 40 | # CHECK-NEXT: Symbol { |
| 39 | # CHECK-NEXT: Name: MessageBoxA | 41 | # CHECK-NEXT: Name: MessageBoxA |
| 40 | # CHECK-NEXT: Value: 80 | 42 | # CHECK-NEXT: Value: 80 |
| 41 | # CHECK-NEXT: Section: .text (2) | 43 | # CHECK-NEXT: Section: .text (1) |
| 42 | # CHECK-NEXT: BaseType: Null (0x0) | 44 | # CHECK-NEXT: BaseType: Null (0x0) |
| 43 | # CHECK-NEXT: ComplexType: Null (0x0) | 45 | # CHECK-NEXT: ComplexType: Null (0x0) |
| 44 | # CHECK-NEXT: StorageClass: External (0x2) | 46 | # CHECK-NEXT: StorageClass: External (0x2) |
| ... | @@ -47,7 +49,7 @@ | ... | @@ -47,7 +49,7 @@ |
| 47 | # CHECK-NEXT: Symbol { | 49 | # CHECK-NEXT: Symbol { |
| 48 | # CHECK-NEXT: Name: ExitProcess | 50 | # CHECK-NEXT: Name: ExitProcess |
| 49 | # CHECK-NEXT: Value: 64 | 51 | # CHECK-NEXT: Value: 64 |
| 50 | # CHECK-NEXT: Section: .text (2) | 52 | # CHECK-NEXT: Section: .text (1) |
| 51 | # CHECK-NEXT: BaseType: Null (0x0) | 53 | # CHECK-NEXT: BaseType: Null (0x0) |
| 52 | # CHECK-NEXT: ComplexType: Null (0x0) | 54 | # CHECK-NEXT: ComplexType: Null (0x0) |
| 53 | # CHECK-NEXT: StorageClass: External (0x2) | 55 | # CHECK-NEXT: StorageClass: External (0x2) |
| ... | @@ -56,7 +58,7 @@ | ... | @@ -56,7 +58,7 @@ |
| 56 | # CHECK-NEXT: Symbol { | 58 | # CHECK-NEXT: Symbol { |
| 57 | # CHECK-NEXT: Name: message | 59 | # CHECK-NEXT: Name: message |
| 58 | # CHECK-NEXT: Value: 6 | 60 | # CHECK-NEXT: Value: 6 |
| 59 | # CHECK-NEXT: Section: .text2 (3) | 61 | # CHECK-NEXT: Section: .text2 |
| 60 | # CHECK-NEXT: BaseType: Null (0x0) | 62 | # CHECK-NEXT: BaseType: Null (0x0) |
| 61 | # CHECK-NEXT: ComplexType: Null (0x0) | 63 | # CHECK-NEXT: ComplexType: Null (0x0) |
| 62 | # CHECK-NEXT: StorageClass: Static (0x3) | 64 | # CHECK-NEXT: StorageClass: Static (0x3) |
| ... | @@ -65,7 +67,7 @@ | ... | @@ -65,7 +67,7 @@ |
| 65 | # CHECK-NEXT: Symbol { | 67 | # CHECK-NEXT: Symbol { |
| 66 | # CHECK-NEXT: Name: main | 68 | # CHECK-NEXT: Name: main |
| 67 | # CHECK-NEXT: Value: 0 | 69 | # CHECK-NEXT: Value: 0 |
| 68 | # CHECK-NEXT: Section: .text (2) | 70 | # CHECK-NEXT: Section: .text (1) |
| 69 | # CHECK-NEXT: BaseType: Null (0x0) | 71 | # CHECK-NEXT: BaseType: Null (0x0) |
| 70 | # CHECK-NEXT: ComplexType: Null (0x0) | 72 | # CHECK-NEXT: ComplexType: Null (0x0) |
| 71 | # CHECK-NEXT: StorageClass: External (0x2) | 73 | # CHECK-NEXT: StorageClass: External (0x2) |
| ... | @@ -74,7 +76,7 @@ | ... | @@ -74,7 +76,7 @@ |
| 74 | # CHECK-NEXT: Symbol { | 76 | # CHECK-NEXT: Symbol { |
| 75 | # CHECK-NEXT: Name: caption | 77 | # CHECK-NEXT: Name: caption |
| 76 | # CHECK-NEXT: Value: 0 | 78 | # CHECK-NEXT: Value: 0 |
| 77 | # CHECK-NEXT: Section: .text2 (3) | 79 | # CHECK-NEXT: Section: .text2 |
| 78 | # CHECK-NEXT: BaseType: Null (0x0) | 80 | # CHECK-NEXT: BaseType: Null (0x0) |
| 79 | # CHECK-NEXT: ComplexType: Null (0x0) | 81 | # CHECK-NEXT: ComplexType: Null (0x0) |
| 80 | # CHECK-NEXT: StorageClass: Static (0x3) | 82 | # CHECK-NEXT: StorageClass: Static (0x3) |
deps/lld/test/COFF/thunk-replace.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -triple=x86_64-win32 %s -filetype=obj -o %t.main.obj | ||
| 4 | # RUN: llvm-mc -triple=x86_64-win32 %p/Inputs/otherFunc.s -filetype=obj -o %t.other.obj | ||
| 5 | # RUN: llvm-ar rcs %t.other.lib %t.other.obj | ||
| 6 | # RUN: not lld-link -out:%t.exe -entry:main %t.main.obj %p/Inputs/std64.lib %t.other.lib -opt:noref 2>&1 | FileCheck %s | ||
| 7 | # CHECK: MessageBoxA was replaced | ||
| 8 | |||
| 9 | .global main | ||
| 10 | .text | ||
| 11 | main: | ||
| 12 | callq MessageBoxA | ||
| 13 | callq ExitProcess | ||
| 14 | callq otherFunc | ||
| 15 | ret | ||
deps/lld/test/COFF/timestamp.test created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | rm %t.*.exe | ||
| 2 | RUN: yaml2obj %p/Inputs/generic.yaml > %t.obj | ||
| 3 | RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.1.exe | ||
| 4 | RUN: lld-link %t.obj /debug /Brepro /entry:main /nodefaultlib /out:%t.2.exe | ||
| 5 | RUN: lld-link %t.obj /debug /timestamp:0 /entry:main /nodefaultlib /out:%t.3.exe | ||
| 6 | RUN: llvm-readobj -file-headers -coff-debug-directory %t.1.exe | FileCheck %s --check-prefix=HASH | ||
| 7 | RUN: llvm-readobj -file-headers -coff-debug-directory %t.2.exe | FileCheck %s --check-prefix=HASH | ||
| 8 | RUN: llvm-readobj -file-headers -coff-debug-directory %t.3.exe | FileCheck %s --check-prefix=ZERO | ||
| 9 | |||
| 10 | HASH: ImageFileHeader { | ||
| 11 | HASH: TimeDateStamp: [[STAMP:.*]] | ||
| 12 | HASH: DebugDirectory [ | ||
| 13 | HASH: TimeDateStamp: [[STAMP]] | ||
| 14 | |||
| 15 | ZERO: ImageFileHeader { | ||
| 16 | ZERO: TimeDateStamp: 1970-01-01 00:00:00 (0x0) | ||
| 17 | ZERO: DebugDirectory [ | ||
| 18 | ZERO: TimeDateStamp: 1970-01-01 00:00:00 (0x0) | ||
deps/lld/test/COFF/undefined-symbol-cv.s created+62| ... | @@ -0,0 +1,62 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s | ||
| 3 | # RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: error: undefined symbol: ?foo@@YAHXZ | ||
| 6 | # CHECK-NEXT: >>> referenced by file1.cpp:1 | ||
| 7 | # CHECK-NEXT: >>> {{.*}}.obj:(main) | ||
| 8 | # CHECK-NEXT: >>> referenced by file1.cpp:2 | ||
| 9 | # CHECK-NEXT: >>> {{.*}}.obj:(main) | ||
| 10 | |||
| 11 | # CHECK: error: undefined symbol: ?bar@@YAHXZ | ||
| 12 | # CHECK-NEXT: >>> referenced by file2.cpp:3 | ||
| 13 | # CHECK-NEXT: >>> {{.*}}.obj:(main) | ||
| 14 | # CHECK-NEXT: >>> referenced by file1.cpp:4 | ||
| 15 | # CHECK-NEXT: >>> {{.*}}.obj:(f1) | ||
| 16 | |||
| 17 | # CHECK: error: undefined symbol: ?baz@@YAHXZ | ||
| 18 | # CHECK-NEXT: >>> referenced by file1.cpp:5 | ||
| 19 | # CHECK-NEXT: >>> {{.*}}.obj:(f2) | ||
| 20 | |||
| 21 | 	.cv_file	1 "file1.cpp" "EDA15C78BB573E49E685D8549286F33C" 1 | ||
| 22 | 	.cv_file	2 "file2.cpp" "EDA15C78BB573E49E685D8549286F33D" 1 | ||
| 23 | |||
| 24 | .section .text,"xr",one_only,main | ||
| 25 | .globl main | ||
| 26 | main: | ||
| 27 | 	.cv_func_id 0 | ||
| 28 | 	.cv_loc	0 1 1 0 is_stmt 0 | ||
| 29 | 	call	"?foo@@YAHXZ" | ||
| 30 | 	.cv_loc	0 1 2 0 | ||
| 31 | 	call	"?foo@@YAHXZ" | ||
| 32 | 	.cv_loc	0 2 3 0 | ||
| 33 | 	call	"?bar@@YAHXZ" | ||
| 34 | .Lfunc_end0: | ||
| 35 | |||
| 36 | f1: | ||
| 37 | 	.cv_func_id 1 | ||
| 38 | 	.cv_loc	1 1 4 0 is_stmt 0 | ||
| 39 | 	call	"?bar@@YAHXZ" | ||
| 40 | .Lfunc_end1: | ||
| 41 | |||
| 42 | .section .text,"xr",one_only,f2 | ||
| 43 | .globl f2 | ||
| 44 | f2: | ||
| 45 | 	.cv_func_id 2 | ||
| 46 | 	.cv_loc	2 1 5 0 is_stmt 0 | ||
| 47 | 	call	"?baz@@YAHXZ" | ||
| 48 | .Lfunc_end2: | ||
| 49 | |||
| 50 | 	.section	.debug$S,"dr",associative,main | ||
| 51 | 	.long	4 | ||
| 52 | 	.cv_linetable	0, main, .Lfunc_end0 | ||
| 53 | 	.cv_linetable	1, f1, .Lfunc_end1 | ||
| 54 | |||
| 55 | 	.section	.debug$S,"dr",associative,f2 | ||
| 56 | 	.long	4 | ||
| 57 | 	.cv_linetable	2, f2, .Lfunc_end2 | ||
| 58 | |||
| 59 | 	.section	.debug$S,"dr" | ||
| 60 | 	.long	4 | ||
| 61 | 	.cv_filechecksums | ||
| 62 | 	.cv_stringtable | ||
deps/lld/test/COFF/undefined-symbol.s created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s | ||
| 3 | # RUN: not lld-link /out:%t.exe %t.obj 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: error: undefined symbol: ?foo@@YAHXZ | ||
| 6 | # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main) | ||
| 7 | # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main) | ||
| 8 | |||
| 9 | # CHECK: error: undefined symbol: ?bar@@YAHXZ | ||
| 10 | # CHECK-NEXT: >>> referenced by {{.*}}.obj:(main) | ||
| 11 | # CHECK-NEXT: >>> referenced by {{.*}}.obj:(f1) | ||
| 12 | |||
| 13 | # CHECK: error: undefined symbol: ?baz@@YAHXZ | ||
| 14 | # CHECK-NEXT: >>> referenced by {{.*}}.obj:(f2) | ||
| 15 | |||
| 16 | .section .text,"xr",one_only,main | ||
| 17 | .globl main | ||
| 18 | main: | ||
| 19 | 	call	"?foo@@YAHXZ" | ||
| 20 | 	call	"?foo@@YAHXZ" | ||
| 21 | 	call	"?bar@@YAHXZ" | ||
| 22 | |||
| 23 | f1: | ||
| 24 | 	call	"?bar@@YAHXZ" | ||
| 25 | .Lfunc_end1: | ||
| 26 | |||
| 27 | .section .text,"xr",one_only,f2 | ||
| 28 | .globl f2 | ||
| 29 | f2: | ||
| 30 | 	call	"?baz@@YAHXZ" | ||
deps/lld/test/COFF/unwind.test+29-13| ... | @@ -4,12 +4,24 @@ | ... | @@ -4,12 +4,24 @@ |
| 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 |
| 5 | # RUN: llvm-objdump -unwind-info %t.exe | FileCheck -check-prefix=UNWIND %s | 5 | # RUN: llvm-objdump -unwind-info %t.exe | FileCheck -check-prefix=UNWIND %s |
| 6 | # | 6 | # |
| 7 | # HEADER: ExceptionTableRVA: 0x1000 | 7 | # 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 | ||
| 9 | # | ||
| 10 | # HEADER: ExceptionTableRVA: 0x3000 | ||
| 11 | # | ||
| 12 | # FIXME: llvm-readobj currently does not understand files with .pdata merged | ||
| 13 | # into .rdata. But we can at least check that the section headers look correct. | ||
| 14 | # | ||
| 15 | # HEADER-MERGE: ExceptionTableRVA: 0x2004 | ||
| 16 | # HEADER-MERGE-NEXT: ExceptionTableSize: 0x30 | ||
| 17 | # HEADER-MERGE: Name: .rdata | ||
| 18 | # HEADER-MERGE-NEXT: VirtualSize: 0x78 | ||
| 19 | # HEADER-MERGE-NEXT: VirtualAddress: 0x2000 | ||
| 8 | # | 20 | # |
| 9 | # UNWIND: Function Table: | 21 | # UNWIND: Function Table: |
| 10 | # UNWIND: Start Address: 0x2000 | 22 | # UNWIND: Start Address: 0x1000 |
| 11 | # UNWIND: End Address: 0x201b | 23 | # UNWIND: End Address: 0x101b |
| 12 | # UNWIND: Unwind Info Address: 0x3000 | 24 | # UNWIND: Unwind Info Address: 0x2004 |
| 13 | # UNWIND: Version: 1 | 25 | # UNWIND: Version: 1 |
| 14 | # UNWIND: Flags: 1 UNW_ExceptionHandler | 26 | # UNWIND: Flags: 1 UNW_ExceptionHandler |
| 15 | # UNWIND: Size of prolog: 18 | 27 | # UNWIND: Size of prolog: 18 |
| ... | @@ -24,27 +36,27 @@ | ... | @@ -24,27 +36,27 @@ |
| 24 | # UNWIND: 0x04: UOP_AllocSmall 24 | 36 | # UNWIND: 0x04: UOP_AllocSmall 24 |
| 25 | # UNWIND: 0x00: UOP_PushMachFrame w/o error code | 37 | # UNWIND: 0x00: UOP_PushMachFrame w/o error code |
| 26 | # UNWIND: Function Table: | 38 | # UNWIND: Function Table: |
| 27 | # UNWIND: Start Address: 0x2012 | 39 | # UNWIND: Start Address: 0x1012 |
| 28 | # UNWIND: End Address: 0x2012 | 40 | # UNWIND: End Address: 0x1012 |
| 29 | # UNWIND: Unwind Info Address: 0x301c | 41 | # UNWIND: Unwind Info Address: 0x2020 |
| 30 | # UNWIND: Version: 1 | 42 | # UNWIND: Version: 1 |
| 31 | # UNWIND: Flags: 4 UNW_ChainInfo | 43 | # UNWIND: Flags: 4 UNW_ChainInfo |
| 32 | # UNWIND: Size of prolog: 0 | 44 | # UNWIND: Size of prolog: 0 |
| 33 | # UNWIND: Number of Codes: 0 | 45 | # UNWIND: Number of Codes: 0 |
| 34 | # UNWIND: No frame pointer used | 46 | # UNWIND: No frame pointer used |
| 35 | # UNWIND: Function Table: | 47 | # UNWIND: Function Table: |
| 36 | # UNWIND: Start Address: 0x201b | 48 | # UNWIND: Start Address: 0x101b |
| 37 | # UNWIND: End Address: 0x201c | 49 | # UNWIND: End Address: 0x101c |
| 38 | # UNWIND: Unwind Info Address: 0x302c | 50 | # UNWIND: Unwind Info Address: 0x2030 |
| 39 | # UNWIND: Version: 1 | 51 | # UNWIND: Version: 1 |
| 40 | # UNWIND: Flags: 0 | 52 | # UNWIND: Flags: 0 |
| 41 | # UNWIND: Size of prolog: 0 | 53 | # UNWIND: Size of prolog: 0 |
| 42 | # UNWIND: Number of Codes: 0 | 54 | # UNWIND: Number of Codes: 0 |
| 43 | # UNWIND: No frame pointer used | 55 | # UNWIND: No frame pointer used |
| 44 | # UNWIND: Function Table: | 56 | # UNWIND: Function Table: |
| 45 | # UNWIND: Start Address: 0x201c | 57 | # UNWIND: Start Address: 0x101c |
| 46 | # UNWIND: End Address: 0x2039 | 58 | # UNWIND: End Address: 0x1039 |
| 47 | # UNWIND: Unwind Info Address: 0x3034 | 59 | # UNWIND: Unwind Info Address: 0x2038 |
| 48 | # UNWIND: Version: 1 | 60 | # UNWIND: Version: 1 |
| 49 | # UNWIND: Flags: 0 | 61 | # UNWIND: Flags: 0 |
| 50 | # UNWIND: Size of prolog: 14 | 62 | # UNWIND: Size of prolog: 14 |
| ... | @@ -122,6 +134,10 @@ sections: | ... | @@ -122,6 +134,10 @@ sections: |
| 122 | - VirtualAddress: 44 | 134 | - VirtualAddress: 44 |
| 123 | SymbolName: .xdata | 135 | SymbolName: .xdata |
| 124 | Type: IMAGE_REL_AMD64_ADDR32NB | 136 | Type: IMAGE_REL_AMD64_ADDR32NB |
| 137 | - Name: .rdata | ||
| 138 | Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] | ||
| 139 | Alignment: 4 | ||
| 140 | SectionData: 00000000 | ||
| 125 | symbols: | 141 | symbols: |
| 126 | - Name: .text | 142 | - Name: .text |
| 127 | Value: 0 | 143 | Value: 0 |
deps/lld/test/COFF/weak-external.test+2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: yaml2obj %s > %t.obj | 2 | # RUN: yaml2obj %s > %t.obj |
| 2 | # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external.ll | 3 | # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external.ll |
| 3 | # RUN: lld-link /out:%t1.exe /entry:g /subsystem:console %t.obj | 4 | # RUN: lld-link /out:%t1.exe /entry:g /subsystem:console %t.obj |
| ... | @@ -5,6 +6,7 @@ | ... | @@ -5,6 +6,7 @@ |
| 5 | # RUN: FileCheck %s < %t2.map | 6 | # RUN: FileCheck %s < %t2.map |
| 6 | 7 | ||
| 7 | # CHECK: lto.tmp | 8 | # CHECK: lto.tmp |
| 9 | # CHECK-NEXT: lto.tmp | ||
| 8 | # CHECK-NEXT: 0 g | 10 | # CHECK-NEXT: 0 g |
| 9 | 11 | ||
| 10 | --- !COFF | 12 | --- !COFF |
deps/lld/test/COFF/weak-external2.test+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: yaml2obj %s > %t.obj | 2 | # RUN: yaml2obj %s > %t.obj |
| 2 | # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external2.ll | 3 | # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external2.ll |
| 3 | # RUN: lld-link /out:%t.exe /entry:g /subsystem:console %t.obj %t.lto.obj | 4 | # RUN: lld-link /out:%t.exe /entry:g /subsystem:console %t.obj %t.lto.obj |
deps/lld/test/COFF/weak-external3.test+2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: yaml2obj %s > %t.obj | 2 | # RUN: yaml2obj %s > %t.obj |
| 2 | # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external3.ll | 3 | # RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external3.ll |
| 3 | # RUN: lld-link /out:%t1.exe /entry:f /subsystem:console /lldmap:%t1.map %t.lto.obj | 4 | # RUN: lld-link /out:%t1.exe /entry:f /subsystem:console /lldmap:%t1.map %t.lto.obj |
| ... | @@ -5,6 +6,7 @@ | ... | @@ -5,6 +6,7 @@ |
| 5 | # RUN: lld-link /out:%t2.exe /entry:f /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj | 6 | # RUN: lld-link /out:%t2.exe /entry:f /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj |
| 6 | # RUN: FileCheck --check-prefix=CHECK2 %s < %t2.map | 7 | # RUN: FileCheck --check-prefix=CHECK2 %s < %t2.map |
| 7 | 8 | ||
| 9 | # CHECK1: lto.tmp | ||
| 8 | # CHECK1: lto.tmp | 10 | # CHECK1: lto.tmp |
| 9 | # CHECK1-NEXT: 0 g | 11 | # CHECK1-NEXT: 0 g |
| 10 | 12 |
deps/lld/test/COFF/wholearchive.s+9-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # REQEUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.archive.obj | 3 | # RUN: yaml2obj < %p/Inputs/export.yaml > %t.archive.obj |
| 4 | # RUN: llvm-ar rcs %t.archive.lib %t.archive.obj | 4 | # RUN: llvm-ar rcs %t.archive.lib %t.archive.obj |
| ... | @@ -10,6 +10,14 @@ | ... | @@ -10,6 +10,14 @@ |
| 10 | # RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj -wholearchive %t.archive.lib -implib:%t.lib | 10 | # RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj -wholearchive %t.archive.lib -implib:%t.lib |
| 11 | # RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB | 11 | # RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB |
| 12 | 12 | ||
| 13 | # RUN: lld-link -dll -out:%t.dll -entry:main %t.main.obj %t.archive.lib -wholearchive:%t.archive.lib -implib:%t.lib | ||
| 14 | # RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB | ||
| 15 | |||
| 16 | # RUN: mkdir -p %t.dir | ||
| 17 | # RUN: cp %t.archive.lib %t.dir/foo.lib | ||
| 18 | # RUN: lld-link -dll -out:%t.dll -entry:main -libpath:%t.dir %t.main.obj %t.dir/./foo.lib -wholearchive:foo.lib -implib:%t.lib | ||
| 19 | # RUN: llvm-readobj %t.lib | FileCheck %s -check-prefix CHECK-IMPLIB | ||
| 20 | |||
| 13 | # CHECK-IMPLIB: Symbol: __imp_exportfn3 | 21 | # CHECK-IMPLIB: Symbol: __imp_exportfn3 |
| 14 | # CHECK-IMPLIB: Symbol: exportfn3 | 22 | # CHECK-IMPLIB: Symbol: exportfn3 |
| 15 | 23 |
deps/lld/test/ELF/Inputs/amdgpu-kernel-2.o deleted| Binary files a/deps/lld/test/ELF/Inputs/amdgpu-kernel-2.o and /dev/null differ | |||
deps/lld/test/ELF/Inputs/arm-long-thunk-converge.lds created+4| ... | @@ -0,0 +1,4 @@ | ||
| 1 | SECTIONS { | ||
| 2 | .foo : { *(.foo) } | ||
| 3 | .bar 0x2000000 : { *(.bar) } | ||
| 4 | } | ||
deps/lld/test/ELF/Inputs/arm-vfp-arg-base.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | 	.arch armv7-a | ||
| 2 | 	.eabi_attribute 20, 1 | ||
| 3 | 	.eabi_attribute 21, 1 | ||
| 4 | 	.eabi_attribute 23, 3 | ||
| 5 | 	.eabi_attribute 24, 1 | ||
| 6 | 	.eabi_attribute 25, 1 | ||
| 7 | 	.eabi_attribute 26, 2 | ||
| 8 | 	.eabi_attribute 30, 6 | ||
| 9 | 	.eabi_attribute 34, 1 | ||
| 10 | 	.eabi_attribute 18, 4 | ||
| 11 | .eabi_attribute 28, 0 // Tag_ABI_VFP_args = 0 (AAPCS, Base variant) | ||
| 12 | |||
| 13 | .syntax unified | ||
| 14 | .global f0 | ||
| 15 | .type f0, %function | ||
| 16 | f0: bx lr | ||
deps/lld/test/ELF/Inputs/arm-vfp-arg-compat.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | 	.arch armv7-a | ||
| 2 | 	.eabi_attribute 20, 1 | ||
| 3 | 	.eabi_attribute 21, 1 | ||
| 4 | 	.eabi_attribute 23, 3 | ||
| 5 | 	.eabi_attribute 24, 1 | ||
| 6 | 	.eabi_attribute 25, 1 | ||
| 7 | 	.eabi_attribute 26, 2 | ||
| 8 | 	.eabi_attribute 30, 6 | ||
| 9 | 	.eabi_attribute 34, 1 | ||
| 10 | 	.eabi_attribute 18, 4 | ||
| 11 | .eabi_attribute 28, 3 // Tag_ABI_VFP_args = 3 (Compatible with all) | ||
| 12 | |||
| 13 | .syntax unified | ||
| 14 | .global f3 | ||
| 15 | .type f3, %function | ||
| 16 | f3: bx lr | ||
deps/lld/test/ELF/Inputs/arm-vfp-arg-toolchain.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | 	.arch armv7-a | ||
| 2 | 	.eabi_attribute 20, 1 | ||
| 3 | 	.eabi_attribute 21, 1 | ||
| 4 | 	.eabi_attribute 23, 3 | ||
| 5 | 	.eabi_attribute 24, 1 | ||
| 6 | 	.eabi_attribute 25, 1 | ||
| 7 | 	.eabi_attribute 26, 2 | ||
| 8 | 	.eabi_attribute 30, 6 | ||
| 9 | 	.eabi_attribute 34, 1 | ||
| 10 | 	.eabi_attribute 18, 4 | ||
| 11 | 	.eabi_attribute 28, 2 // Tag_ABI_VFP_args = 2 (Toolchain specific) | ||
| 12 | .syntax unified | ||
| 13 | .global f2 | ||
| 14 | .type f1, %function | ||
| 15 | f2: bx lr | ||
deps/lld/test/ELF/Inputs/arm-vfp-arg-vfp.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | 	.arch armv7-a | ||
| 2 | 	.eabi_attribute 20, 1 | ||
| 3 | 	.eabi_attribute 21, 1 | ||
| 4 | 	.eabi_attribute 23, 3 | ||
| 5 | 	.eabi_attribute 24, 1 | ||
| 6 | 	.eabi_attribute 25, 1 | ||
| 7 | 	.eabi_attribute 26, 2 | ||
| 8 | 	.eabi_attribute 30, 6 | ||
| 9 | 	.eabi_attribute 34, 1 | ||
| 10 | 	.eabi_attribute 18, 4 | ||
| 11 | 	.eabi_attribute 28, 1 // Tag_ABI_VFP_args = 1 (AAPCS, VFP variant) | ||
| 12 | .syntax unified | ||
| 13 | .global f1 | ||
| 14 | .type f1, %function | ||
| 15 | f1: bx lr | ||
deps/lld/test/ELF/Inputs/comdat-discarded-reloc.s created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | .section .text.bar1,"aG",@progbits,group,comdat | ||
| 2 | |||
| 3 | .section .text.bar2 | ||
| 4 | .global bar | ||
| 5 | bar: | ||
| 6 | .quad .text.bar1 | ||
deps/lld/test/ELF/Inputs/conflict-debug.s+21| ... | @@ -3,3 +3,24 @@ | ... | @@ -3,3 +3,24 @@ |
| 3 | .loc 1 4 | 3 | .loc 1 4 |
| 4 | zed: | 4 | zed: |
| 5 | nop | 5 | nop |
| 6 | |||
| 7 | 	.section	.debug_abbrev,"",@progbits | ||
| 8 | 	.byte	1 # Abbreviation Code | ||
| 9 | 	.byte	17 # DW_TAG_compile_unit | ||
| 10 | 	.byte	0 # DW_CHILDREN_no | ||
| 11 | 	.byte	16 # DW_AT_stmt_list | ||
| 12 | 	.byte	23 # DW_FORM_sec_offset | ||
| 13 | 	.byte	0 # EOM(1) | ||
| 14 | 	.byte	0 # EOM(2) | ||
| 15 | 	.byte	0 # EOM(3) | ||
| 16 | |||
| 17 | .section	.debug_info,"",@progbits | ||
| 18 | 	.long	.Lend0 - .Lbegin0 # Length of Unit | ||
| 19 | .Lbegin0: | ||
| 20 | 	.short	4 # DWARF version number | ||
| 21 | 	.long	.debug_abbrev # Offset Into Abbrev. Section | ||
| 22 | 	.byte	8 # Address Size (in bytes) | ||
| 23 | 	.byte	1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit | ||
| 24 | 	.long	.debug_line # DW_AT_stmt_list | ||
| 25 | .Lend0: | ||
| 26 | 	.section	.debug_line,"",@progbits |
deps/lld/test/ELF/Inputs/copy-rel-version.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | .data | ||
| 2 | .global foo@v1 | ||
| 3 | .type foo@v1, @object | ||
| 4 | .size foo@v1, 4 | ||
| 5 | .global foo@@v2 | ||
| 6 | .type foo@@v2, @object | ||
| 7 | .size foo@@v2, 8 | ||
| 8 | foo@v1: | ||
| 9 | foo@@v2: | ||
| 10 | .int 0 | ||
| 11 | .int 0 | ||
deps/lld/test/ELF/Inputs/copy-relocation-zero-abs-addr.s created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | .globl ver1 | ||
| 2 | .globl ver2 | ||
| 3 | ver1 = 0x0 | ||
| 4 | ver2 = 0x0 | ||
| 5 | |||
| 6 | .type foo,@object | ||
| 7 | .comm foo,16,16 | ||
deps/lld/test/ELF/Inputs/copy-relocation-zero-nonabs-addr.s created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | .balign 1024 | ||
| 2 | .type foo,@object | ||
| 3 | .globl foo | ||
| 4 | goo: | ||
| 5 | foo: | ||
| 6 | .long 0 | ||
| 7 | .size foo,4 | ||
deps/lld/test/ELF/Inputs/copy-relocation-zero-nonabs-addr.script created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | SECTIONS { | ||
| 2 | goo = 0; | ||
| 3 | }; | ||
deps/lld/test/ELF/Inputs/eh-frame-pcrel-overflow.s created+25| ... | @@ -0,0 +1,25 @@ | ||
| 1 | .text | ||
| 2 | .global foo | ||
| 3 | foo: | ||
| 4 | ret | ||
| 5 | |||
| 6 | .section .eh_frame, "a" | ||
| 7 | .long 12 # Size | ||
| 8 | .long 0x00 # ID | ||
| 9 | .byte 0x01 # Version. | ||
| 10 | |||
| 11 | .byte 0x52 # Augmentation string: 'R','\0' | ||
| 12 | .byte 0x00 | ||
| 13 | |||
| 14 | .byte 0x01 | ||
| 15 | |||
| 16 | .byte 0x01 # LEB128 | ||
| 17 | .byte 0x01 # LEB128 | ||
| 18 | |||
| 19 | .byte 0x00 # DW_EH_PE_absptr | ||
| 20 | |||
| 21 | .byte 0xFF | ||
| 22 | |||
| 23 | .long 12 # Size | ||
| 24 | .long 0x14 # ID | ||
| 25 | .quad foo + 0x90000000 | ||
deps/lld/test/ELF/Inputs/exclude-libs.ll created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | @fn2 = global void()* null; | ||
| 2 | |||
| 3 | target triple = "x86_64-unknown-linux" | ||
deps/lld/test/ELF/Inputs/exclude-libs.s+2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | .globl fn | 1 | .globl fn |
| 2 | fn: | 2 | fn: |
| 3 | nop | 3 | nop |
| 4 | |||
| 5 | .globl foo |
deps/lld/test/ELF/Inputs/far-long-arm-abs.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | .global far | ||
| 2 | .type far,%function | ||
| 3 | far = 0x201001c | ||
| 4 | |||
| 5 | .global too_far1 | ||
| 6 | .type too_far1,%function | ||
| 7 | too_far1 = 0x2020014 | ||
| 8 | .global too_far2 | ||
| 9 | .type too_far2,%function | ||
| 10 | too_far2 = 0x2020020 | ||
| 11 | .global too_far3 | ||
| 12 | .type too_far3,%function | ||
| 13 | too_far3 = 0x202002c | ||
deps/lld/test/ELF/Inputs/gdb-index.s+4-4| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | .text | 1 | .text |
| 2 | .Ltext0: | 2 | .Ltext0: |
| 3 | .globl main2 | 3 | .globl aaaaaaaaaaaaaaaa |
| 4 | .type main2, @function | 4 | .type aaaaaaaaaaaaaaaa, @function |
| 5 | main2: | 5 | aaaaaaaaaaaaaaaa: |
| 6 | nop | 6 | nop |
| 7 | nop | 7 | nop |
| 8 | .Letext0: | 8 | .Letext0: |
| ... | @@ -59,7 +59,7 @@ main2: | ... | @@ -59,7 +59,7 @@ main2: |
| 59 | .long 0x33 | 59 | .long 0x33 |
| 60 | .long 0x18 | 60 | .long 0x18 |
| 61 | .byte 0x30 | 61 | .byte 0x30 |
| 62 | .string "main2" | 62 | .string "aaaaaaaaaaaaaaaa" |
| 63 | .long 0 | 63 | .long 0 |
| 64 | 64 | ||
| 65 | .section .debug_gnu_pubtypes,"",@progbits | 65 | .section .debug_gnu_pubtypes,"",@progbits |
deps/lld/test/ELF/Inputs/hexagon.s created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | .global _start | ||
| 2 | _start: | ||
| 3 | nop | ||
| 4 | .global foo | ||
| 5 | foo: | ||
| 6 | jumpr lr | ||
deps/lld/test/ELF/Inputs/hidden-shared-err.s created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | .global foo | ||
| 2 | foo: | ||
deps/lld/test/ELF/Inputs/hidden-shared-err2.s created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | .quad foo | ||
deps/lld/test/ELF/Inputs/i386-pic-plt.s created+4| ... | @@ -0,0 +1,4 @@ | ||
| 1 | .global foo | ||
| 2 | .type foo, @function | ||
| 3 | foo: | ||
| 4 | nop | ||
deps/lld/test/ELF/Inputs/icf-absolute2.s created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | .globl a1, a2 | ||
| 2 | a1 = 1 | ||
| 3 | a2 = 2 | ||
deps/lld/test/ELF/Inputs/icf-safe.s created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | .section .text.non_addrsig1,"ax",@progbits | ||
| 2 | .globl non_addrsig1 | ||
| 3 | non_addrsig1: | ||
| 4 | ret | ||
| 5 | |||
| 6 | .section .text.non_addrsig2,"ax",@progbits | ||
| 7 | .globl non_addrsig2 | ||
| 8 | non_addrsig2: | ||
| 9 | ret | ||
deps/lld/test/ELF/Inputs/map-file2.s+2| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | foo: | 1 | foo: |
| 2 | .cfi_startproc | ||
| 2 | nop | 3 | nop |
| 4 | .cfi_endproc | ||
| 3 | .global bar | 5 | .global bar |
| 4 | bar: | 6 | bar: |
| 5 | nop | 7 | nop |
deps/lld/test/ELF/Inputs/mips-64-got-load.s created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | .text | ||
| 2 | .global foo1 | ||
| 3 | foo1: | ||
| 4 | ld $2, %got_disp(local1)($gp) | ||
| 5 | |||
| 6 | .bss | ||
| 7 | local1: | ||
| 8 | .word 0 | ||
deps/lld/test/ELF/Inputs/mips-mgot-1.s created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | .text | ||
| 2 | .global foo1 | ||
| 3 | foo1: | ||
| 4 | addiu $2, $2, %gottprel(tls0) # tls got entry | ||
| 5 | addiu $2, $2, %gottprel(tls1) # tls got entry | ||
| 6 | |||
| 7 | .section .tdata,"awT",%progbits | ||
| 8 | .global tls1 | ||
| 9 | tls1: | ||
| 10 | .word 0 | ||
deps/lld/test/ELF/Inputs/mips-mgot-2.s created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | .text | ||
| 2 | .global foo2 | ||
| 3 | foo2: | ||
| 4 | lw $2, %got(.data)($gp) # page entry | ||
| 5 | addi $2, $2, %lo(.data) | ||
| 6 | lw $2, %call16(foo0)($gp) # global entry | ||
| 7 | lw $2, %call16(foo2)($gp) # global entry | ||
| 8 | addiu $2, $2, %tlsgd(tls0) # tls gd entry | ||
| 9 | addiu $2, $2, %gottprel(tls0) # tls got entry | ||
| 10 | |||
| 11 | .data | ||
| 12 | .space 0x20000 | ||
| 13 | |||
| 14 | .section .tdata,"awT",%progbits | ||
| 15 | .global tls2 | ||
| 16 | tls2: | ||
| 17 | .word 0 | ||
deps/lld/test/ELF/Inputs/mips-micro-gp0-non-zero.o created| Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-micro-gp0-non-zero.o differ | |||
deps/lld/test/ELF/Inputs/mips-n32-rels.o deleted| Binary files a/deps/lld/test/ELF/Inputs/mips-n32-rels.o and /dev/null differ | |||
deps/lld/test/ELF/Inputs/mips-n64-gp0-non-zero.o created| Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-n64-gp0-non-zero.o differ | |||
deps/lld/test/ELF/Inputs/multiple-cu.s created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | .file 1 "test2.c" | ||
| 2 | .loc 1 2 0 | ||
| 3 | jmp bar | ||
| 4 | |||
| 5 | .section .debug_abbrev,"",@progbits | ||
| 6 | .byte 1 # Abbreviation Code | ||
| 7 | .byte 17 # DW_TAG_compile_unit | ||
| 8 | .byte 0 # DW_CHILDREN_no | ||
| 9 | .byte 16 # DW_AT_stmt_list | ||
| 10 | .byte 23 # DW_FORM_sec_offset | ||
| 11 | .byte 0 # EOM(1) | ||
| 12 | .byte 0 # EOM(2) | ||
| 13 | .byte 0 # EOM(3) | ||
| 14 | |||
| 15 | .section .debug_info,"",@progbits | ||
| 16 | .long .Lend0 - .Lbegin0 # Length of Unit | ||
| 17 | .Lbegin0: | ||
| 18 | .short 4 # DWARF version number | ||
| 19 | .long .debug_abbrev # Offset Into Abbrev. Section | ||
| 20 | .byte 8 # Address Size (in bytes) | ||
| 21 | .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit | ||
| 22 | .long .debug_line # DW_AT_stmt_list | ||
| 23 | .Lend0: | ||
| 24 | .section .debug_line,"",@progbits | ||
deps/lld/test/ELF/Inputs/ppc64-func-global-entry.s created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | 	.text | ||
| 2 | 	.abiversion 2 | ||
| 3 | 	.globl	foo_external_diff # -- Begin function foo_external_diff | ||
| 4 | 	.p2align	4 | ||
| 5 | 	.type	foo_external_diff,@function | ||
| 6 | foo_external_diff: # @foo_external_diff | ||
| 7 | .Lfunc_begin0: | ||
| 8 | .Lfunc_gep0: | ||
| 9 | 	addis 2, 12, .TOC.-.Lfunc_gep0@ha | ||
| 10 | 	addi 2, 2, .TOC.-.Lfunc_gep0@l | ||
| 11 | .Lfunc_lep0: | ||
| 12 | 	.localentry	foo_external_diff, .Lfunc_lep0-.Lfunc_gep0 | ||
| 13 | # %bb.0: # %entry | ||
| 14 | 	addis 5, 2, .LC0@toc@ha | ||
| 15 | 	add 3, 4, 3 | ||
| 16 | 	ld 5, .LC0@toc@l(5) | ||
| 17 | 	lwz 5, 0(5) | ||
| 18 | 	add 3, 3, 5 | ||
| 19 | 	extsw 3, 3 | ||
| 20 | 	blr | ||
| 21 | 	.long	0 | ||
| 22 | 	.quad	0 | ||
| 23 | .Lfunc_end0: | ||
| 24 | 	.size	foo_external_diff, .Lfunc_end0-.Lfunc_begin0 | ||
| 25 | # -- End function | ||
| 26 | 	.section	.toc,"aw",@progbits | ||
| 27 | .LC0: | ||
| 28 | 	.tc glob2[TC],glob2 | ||
| 29 | 	.type	glob2,@object # @glob2 | ||
| 30 | 	.data | ||
| 31 | 	.globl	glob2 | ||
| 32 | 	.p2align	2 | ||
| 33 | glob2: | ||
| 34 | 	.long	10 # 0xa | ||
| 35 | 	.size	glob2, 4 | ||
deps/lld/test/ELF/Inputs/ppc64-func-local-entry.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | 	.text | ||
| 2 | 	.abiversion 2 | ||
| 3 | 	.globl	foo_external_same # -- Begin function foo_external_same | ||
| 4 | 	.p2align	4 | ||
| 5 | 	.type	foo_external_same,@function | ||
| 6 | foo_external_same: # @foo_external_same | ||
| 7 | .Lfunc_begin0: | ||
| 8 | # %bb.0: # %entry | ||
| 9 | 	add 3, 4, 3 | ||
| 10 | 	extsw 3, 3 | ||
| 11 | 	blr | ||
| 12 | 	.long	0 | ||
| 13 | 	.quad	0 | ||
| 14 | .Lfunc_end0: | ||
| 15 | 	.size	foo_external_same, .Lfunc_end0-.Lfunc_begin0 | ||
| 16 | # -- End function | ||
deps/lld/test/ELF/Inputs/ppc64-func.s created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | .text | ||
| 2 | .abiversion 2 | ||
| 3 | .globl foo_not_shared | ||
| 4 | .p2align 4 | ||
| 5 | .type foo_not_shared,@function | ||
| 6 | |||
| 7 | foo_not_shared: | ||
| 8 | .Lfunc_begin0: | ||
| 9 | li 3, 55 | ||
| 10 | blr | ||
| 11 | .long 0 | ||
| 12 | .quad 0 | ||
| 13 | .Lfunc_end0: | ||
| 14 | .size foo_not_shared, .Lfunc_end0-.Lfunc_begin0 | ||
deps/lld/test/ELF/Inputs/ppc64-tls.s created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | 	.text | ||
| 2 | 	.abiversion 2 | ||
| 3 | 	.type	a,@object # @a | ||
| 4 | 	.type	b,@object # @a | ||
| 5 | 	.type	c,@object # @a | ||
| 6 | 	.section	.tdata,"awT",@progbits | ||
| 7 | 	.globl	a | ||
| 8 | a: | ||
| 9 | 	.long	10 # 0xa | ||
| 10 | 	.size	a, 4 | ||
| 11 | |||
| 12 | 	.globl	b | ||
| 13 | b: | ||
| 14 | 	.long	10 # 0xa | ||
| 15 | 	.size	b, 4 | ||
| 16 | |||
| 17 | 	.globl	c | ||
| 18 | c: | ||
| 19 | 	.long	10 # 0xa | ||
| 20 | 	.size	c, 4 | ||
deps/lld/test/ELF/Inputs/print-icf.s created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | .section .text.f6, "ax" | ||
| 2 | f6: | ||
| 3 | mov $60, %rax | ||
| 4 | mov $42, %rdi | ||
| 5 | syscall | ||
| 6 | |||
| 7 | .section .text.f7, "ax" | ||
| 8 | f7: | ||
| 9 | mov $0, %rax | ||
deps/lld/test/ELF/Inputs/protected-data-access.s created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | .section .rodata,"a" | ||
| 2 | .global foo | ||
| 3 | .protected foo | ||
| 4 | .type foo, @object | ||
| 5 | .size foo, 8 | ||
| 6 | foo: | ||
| 7 | .quad 42 | ||
deps/lld/test/ELF/Inputs/protected-function-access.s created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | .global foo | ||
| 2 | .protected foo | ||
| 3 | .type foo, @function | ||
| 4 | foo: | ||
| 5 | ret | ||
deps/lld/test/ELF/Inputs/shared-ppc64.s+13-8| ... | @@ -1,9 +1,14 @@ | ... | @@ -1,9 +1,14 @@ |
| 1 | .section ".opd","aw" | 1 | .text |
| 2 | .global bar | 2 | .abiversion 2 |
| 3 | bar: | 3 | .globl foo |
| 4 | .quad .Lbar,.TOC.@tocbase,0 | 4 | .p2align 4 |
| 5 | .quad .Lbar,0,0 | 5 | .type foo,@function |
| 6 | 6 | ||
| 7 | .text | 7 | foo: |
| 8 | .Lbar: | 8 | .Lfunc_begin0: |
| 9 | blr | 9 | li 3, 55 |
| 10 | blr | ||
| 11 | .long 0 | ||
| 12 | .quad 0 | ||
| 13 | .Lfunc_end0: | ||
| 14 | .size foo, .Lfunc_end0-.Lfunc_begin0 |
deps/lld/test/ELF/Inputs/symbol-ordering-file-warnings1.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # This is a "bad" (absolute) instance of the symbol | ||
| 2 | multi = 1234 | ||
| 3 | |||
| 4 | .text | ||
| 5 | .global shared | ||
| 6 | .type shared, @function | ||
| 7 | shared: | ||
| 8 | movq %rax, multi | ||
| 9 | ret | ||
| 10 | |||
| 11 | .section .text.comdat,"axG",@progbits,comdat,comdat | ||
| 12 | .weak comdat | ||
| 13 | comdat: | ||
| 14 | ret | ||
| 15 | |||
| 16 | .section .text.glob_or_wk,"ax",@progbits | ||
| 17 | .global glob_or_wk | ||
| 18 | glob_or_wk: | ||
| 19 | ret | ||
deps/lld/test/ELF/Inputs/symbol-ordering-file-warnings2.s created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | .text | ||
| 2 | .global missing | ||
| 3 | missing: | ||
| 4 | callq undefined | ||
| 5 | # This is a "bad" (undefined) instance of the symbol | ||
| 6 | callq multi | ||
deps/lld/test/ELF/Inputs/undef-bad-debug.s created+134| ... | @@ -0,0 +1,134 @@ | ||
| 1 | .section .text,"ax" | ||
| 2 | sym: | ||
| 3 | .quad zed6 | ||
| 4 | sym2: | ||
| 5 | .quad zed7 | ||
| 6 | |||
| 7 | .section .debug_line,"",@progbits | ||
| 8 | .Lunit: | ||
| 9 | .long .Lunit_end - .Lunit_start # unit length | ||
| 10 | .Lunit_start: | ||
| 11 | .short 4 # version | ||
| 12 | .long .Lprologue_end - .Lprologue_start # prologue length | ||
| 13 | .Lprologue_start: | ||
| 14 | .byte 1 # minimum instruction length | ||
| 15 | .byte 1 # maximum operatiosn per instruction | ||
| 16 | .byte 1 # default is_stmt | ||
| 17 | .byte -5 # line base | ||
| 18 | .byte 14 # line range | ||
| 19 | .byte 13 # opcode base | ||
| 20 | .byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # standard opcode lengths | ||
| 21 | .asciz "dir" # include directories | ||
| 22 | .byte 0 | ||
| 23 | .asciz "undef-bad-debug.s" # file names | ||
| 24 | .byte 1, 0, 0 | ||
| 25 | .byte 0 | ||
| 26 | .byte 0 # extraneous byte | ||
| 27 | .Lprologue_end: | ||
| 28 | .byte 0, 9, 2 # DW_LNE_set_address | ||
| 29 | .quad sym | ||
| 30 | .byte 3 # DW_LNS_advance_line | ||
| 31 | .byte 10 | ||
| 32 | .byte 1 # DW_LNS_copy | ||
| 33 | .byte 2 # DW_LNS_advance_pc | ||
| 34 | .byte 8 | ||
| 35 | .byte 0, 1, 1 # DW_LNE_end_sequence | ||
| 36 | .Lunit_end: | ||
| 37 | |||
| 38 | .Lunit2: | ||
| 39 | .long .Lunit2_end - .Lunit2_start # unit length | ||
| 40 | .Lunit2_start: | ||
| 41 | .short 4 # version | ||
| 42 | .long .Lprologue2_end - .Lprologue2_start # prologue length | ||
| 43 | .Lprologue2_start: | ||
| 44 | .byte 1 # minimum instruction length | ||
| 45 | .byte 1 # maximum operatiosn per instruction | ||
| 46 | .byte 1 # default is_stmt | ||
| 47 | .byte -5 # line base | ||
| 48 | .byte 14 # line range | ||
| 49 | .byte 13 # opcode base | ||
| 50 | .byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # standard opcode lengths | ||
| 51 | .asciz "dir2" # include directories | ||
| 52 | .byte 0 | ||
| 53 | .asciz "undef-bad-debug2.s" # file names | ||
| 54 | .byte 1, 0, 0 | ||
| 55 | .byte 0 | ||
| 56 | .Lprologue2_end: | ||
| 57 | .byte 0, 9, 2 # DW_LNE_set_address | ||
| 58 | .quad sym2 | ||
| 59 | .byte 3 # DW_LNS_advance_line | ||
| 60 | .byte 10 | ||
| 61 | .byte 1 # DW_LNS_copy | ||
| 62 | .byte 2 # DW_LNS_advance_pc | ||
| 63 | .byte 8 | ||
| 64 | .byte 0, 1, 1 # DW_LNE_end_sequence | ||
| 65 | .byte 0, 9, 2 # DW_LNE_set_address | ||
| 66 | .quad 0x0badbeef | ||
| 67 | .byte 3 # DW_LNS_advance_line | ||
| 68 | .byte 99 | ||
| 69 | .byte 1 # DW_LNS_copy | ||
| 70 | .byte 99 # DW_LNS_advance_pc | ||
| 71 | .byte 119 | ||
| 72 | # Missing end of sequence. | ||
| 73 | .Lunit2_end: | ||
| 74 | |||
| 75 | .section .debug_info,"",@progbits | ||
| 76 | .long .Lcu_end - .Lcu_start # Length of Unit | ||
| 77 | .Lcu_start: | ||
| 78 | .short 4 # DWARF version number | ||
| 79 | .long .Lsection_abbrev # Offset Into Abbrev. Section | ||
| 80 | .byte 8 # Address Size (in bytes) | ||
| 81 | .byte 1 # Abbrev [1] 0xb:0x79 DW_TAG_compile_unit | ||
| 82 | .long .Lunit # DW_AT_stmt_list | ||
| 83 | .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_variable | ||
| 84 | .long .Linfo_string # DW_AT_name | ||
| 85 | # DW_AT_external | ||
| 86 | .byte 1 # DW_AT_decl_file | ||
| 87 | .byte 3 # DW_AT_decl_line | ||
| 88 | .byte 0 # End Of Children Mark | ||
| 89 | .Lcu_end: | ||
| 90 | |||
| 91 | .long .Lcu2_end - .Lcu2_start # Length of Unit | ||
| 92 | .Lcu2_start: | ||
| 93 | .short 4 # DWARF version number | ||
| 94 | .long .Lsection_abbrev # Offset Into Abbrev. Section | ||
| 95 | .byte 8 # Address Size (in bytes) | ||
| 96 | .byte 1 # Abbrev [1] 0xb:0x79 DW_TAG_compile_unit | ||
| 97 | .long .Lunit2 # DW_AT_stmt_list | ||
| 98 | .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_variable | ||
| 99 | .long .Linfo2_string # DW_AT_name | ||
| 100 | # DW_AT_external | ||
| 101 | .byte 1 # DW_AT_decl_file | ||
| 102 | .byte 3 # DW_AT_decl_line | ||
| 103 | .byte 0 # End Of Children Mark | ||
| 104 | .Lcu2_end: | ||
| 105 | |||
| 106 | .section .debug_abbrev,"",@progbits | ||
| 107 | .Lsection_abbrev: | ||
| 108 | .byte 1 # Abbreviation Code | ||
| 109 | .byte 17 # DW_TAG_compile_unit | ||
| 110 | .byte 1 # DW_CHILDREN_yes | ||
| 111 | .byte 16 # DW_AT_stmt_list | ||
| 112 | .byte 23 # DW_FORM_sec_offset | ||
| 113 | .byte 0 # EOM(1) | ||
| 114 | .byte 0 # EOM(2) | ||
| 115 | .byte 2 # Abbreviation Code | ||
| 116 | .byte 52 # DW_TAG_variable | ||
| 117 | .byte 0 # DW_CHILDREN_no | ||
| 118 | .byte 3 # DW_AT_name | ||
| 119 | .byte 14 # DW_FORM_strp | ||
| 120 | .byte 63 # DW_AT_external | ||
| 121 | .byte 25 # DW_FORM_flag_present | ||
| 122 | .byte 58 # DW_AT_decl_file | ||
| 123 | .byte 11 # DW_FORM_data1 | ||
| 124 | .byte 59 # DW_AT_decl_line | ||
| 125 | .byte 11 # DW_FORM_data1 | ||
| 126 | .byte 0 # EOM(1) | ||
| 127 | .byte 0 # EOM(2) | ||
| 128 | .byte 0 # EOM(3) | ||
| 129 | |||
| 130 | .section .debug_str,"MS",@progbits,1 | ||
| 131 | .Linfo_string: | ||
| 132 | .asciz "sym" | ||
| 133 | .Linfo2_string: | ||
| 134 | .asciz "sym2" | ||
deps/lld/test/ELF/Inputs/undef-debug.s+21| ... | @@ -9,3 +9,24 @@ | ... | @@ -9,3 +9,24 @@ |
| 9 | .section .text.2,"ax" | 9 | .section .text.2,"ax" |
| 10 | .loc 1 11 | 10 | .loc 1 11 |
| 11 | .quad zed5 | 11 | .quad zed5 |
| 12 | |||
| 13 | 	.section	.debug_abbrev,"",@progbits | ||
| 14 | 	.byte	1 # Abbreviation Code | ||
| 15 | 	.byte	17 # DW_TAG_compile_unit | ||
| 16 | 	.byte	0 # DW_CHILDREN_no | ||
| 17 | 	.byte	16 # DW_AT_stmt_list | ||
| 18 | 	.byte	23 # DW_FORM_sec_offset | ||
| 19 | 	.byte	0 # EOM(1) | ||
| 20 | 	.byte	0 # EOM(2) | ||
| 21 | 	.byte	0 # EOM(3) | ||
| 22 | |||
| 23 | .section	.debug_info,"",@progbits | ||
| 24 | 	.long	.Lend0 - .Lbegin0 # Length of Unit | ||
| 25 | .Lbegin0: | ||
| 26 | 	.short	4 # DWARF version number | ||
| 27 | 	.long	.debug_abbrev # Offset Into Abbrev. Section | ||
| 28 | 	.byte	8 # Address Size (in bytes) | ||
| 29 | 	.byte	1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit | ||
| 30 | 	.long	.debug_line # DW_AT_stmt_list | ||
| 31 | .Lend0: | ||
| 32 | 	.section	.debug_line,"",@progbits |
deps/lld/test/ELF/Inputs/undef-shared2.s created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | .data | ||
| 2 | .quad foo | ||
deps/lld/test/ELF/Inputs/versiondef.s created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | .text | ||
| 2 | .globl func_impl | ||
| 3 | func_impl: | ||
| 4 | ret | ||
| 5 | .globl func_impl2 | ||
| 6 | func_impl2: | ||
| 7 | ret | ||
| 8 | .symver func_impl, func@@VER2 | ||
| 9 | .symver func_impl2, func@VER | ||
deps/lld/test/ELF/Inputs/weak-and-strong-undef.s deleted-1| ... | @@ -1 +0,0 @@ | ||
| 1 | .weak foo | ||
deps/lld/test/ELF/Inputs/x86-64-split-stack-main.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | 	.text | ||
| 2 | |||
| 3 | 	.global	non_split | ||
| 4 | 	.type	non_split,@function | ||
| 5 | non_split: | ||
| 6 | 	retq | ||
| 7 | 	.size	non_split,. - non_split | ||
| 8 | |||
| 9 | 	.global non_function_text_symbol | ||
| 10 | non_function_text_symbol: | ||
| 11 | 	.byte 0x01 | ||
| 12 | 	.type	non_function_text_symbol,@STT_OBJECT | ||
| 13 | 	.size	non_function_text_symbol, 1 | ||
| 14 | |||
| 15 | |||
| 16 | 	.section	.note.GNU-stack,"",@progbits | ||
deps/lld/test/ELF/Inputs/ztext-text-notext.s deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | .global bar | ||
| 2 | .type bar, @object | ||
| 3 | .size bar, 8 | ||
| 4 | bar: | ||
| 5 | .quad 0 | ||
| 6 | |||
| 7 | .global zed | ||
| 8 | .type zed, @function | ||
| 9 | zed: | ||
| 10 | nop | ||
deps/lld/test/ELF/Inputs/ztext.s created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | .global bar | ||
| 2 | .type bar, @object | ||
| 3 | .size bar, 8 | ||
| 4 | bar: | ||
| 5 | .quad 0 | ||
| 6 | |||
| 7 | .global zed | ||
| 8 | .type zed, @function | ||
| 9 | zed: | ||
| 10 | nop | ||
deps/lld/test/ELF/aarch64-call26-thunk.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t |
| 3 | // RUN: ld.lld %t %tabs -o %t2 2>&1 | 4 | // RUN: ld.lld %t %tabs -o %t2 2>&1 |
| 4 | // RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s | 5 | // RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s |
| 5 | // REQUIRES: aarch64 | ||
| 6 | 6 | ||
| 7 | .text | 7 | .text |
| 8 | .globl _start | 8 | .globl _start |
deps/lld/test/ELF/aarch64-condb-reloc.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: aarch64 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-condb-reloc.s -o %t1 | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-condb-reloc.s -o %t1 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t2 | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t2 |
| 3 | # RUN: ld.lld %t1 %t2 -o %t | 4 | # RUN: ld.lld %t1 %t2 -o %t |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | # RUN: ld.lld -shared %t1 %t2 -o %t3 | 6 | # RUN: ld.lld -shared %t1 %t2 -o %t3 |
| 6 | # RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=DSO %s | 7 | # RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=DSO %s |
| 7 | # RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s | 8 | # RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s |
| 8 | # REQUIRES: aarch64 | ||
| 9 | 9 | ||
| 10 | # 0x11024 - 36 = 0x11000 | 10 | # 0x11024 - 36 = 0x11000 |
| 11 | # 0x11028 - 24 = 0x11010 | 11 | # 0x11028 - 24 = 0x11010 |
deps/lld/test/ELF/aarch64-copy.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o |
| 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/relocation-copy.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/relocation-copy.s -o %t2.o |
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -soname fixed-length-string.so -o %t2.so |
| 5 | // RUN: ld.lld %t.o %t2.so -o %t3 | 5 | // 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 |
| 7 | // RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s | 7 | // RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s |
| ... | @@ -90,4 +90,4 @@ _start: | ... | @@ -90,4 +90,4 @@ _start: |
| 90 | 90 | ||
| 91 | // RODATA: Contents of section .rodata: | 91 | // RODATA: Contents of section .rodata: |
| 92 | // S(z) = 0x40014 | 92 | // S(z) = 0x40014 |
| 93 | // RODATA-NEXT: 101c8 14000400 | 93 | // RODATA-NEXT: 102e0 14000400 |
deps/lld/test/ELF/aarch64-cortex-a53-843419-address.s+2-1| ... | @@ -4,7 +4,8 @@ | ... | @@ -4,7 +4,8 @@ |
| 4 | // RUN: .text : { *(.text) *(.text.*) *(.newisd) } \ | 4 | // RUN: .text : { *(.text) *(.text.*) *(.newisd) } \ |
| 5 | // RUN: .text2 : { *.(newos) } \ | 5 | // RUN: .text2 : { *.(newos) } \ |
| 6 | // RUN: .data : { *(.data) } }" > %t.script | 6 | // RUN: .data : { *(.data) } }" > %t.script |
| 7 | // RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix=CHECK-PRINT %s | 7 | // RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 2>&1 \ |
| 8 | // RUN: | FileCheck -check-prefix=CHECK-PRINT %s | ||
| 8 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s | 9 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s |
| 9 | 10 | ||
| 10 | // Test cases for Cortex-A53 Erratum 843419 that involve interactions | 11 | // Test cases for Cortex-A53 Erratum 843419 that involve interactions |
deps/lld/test/ELF/aarch64-cortex-a53-843419-cli.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | // RUN: not ld.lld %t -fix-cortex-a53-843419 -o %t2 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t -fix-cortex-a53-843419 -o /dev/null 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | // CHECK: --fix-cortex-a53-843419 is only supported on AArch64 targets. | 5 | // CHECK: --fix-cortex-a53-843419 is only supported on AArch64 targets. |
| 6 | .globl entry | 6 | .globl entry |
deps/lld/test/ELF/aarch64-cortex-a53-843419-nopatch.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o |
| 3 | // RUN: ld.lld -fix-cortex-a53-843419 -verbose -t %t.o -o %t2 | FileCheck %s | 3 | // RUN: ld.lld -fix-cortex-a53-843419 -verbose -t %t.o -o /dev/null | FileCheck %s |
| 4 | // Test cases for Cortex-A53 Erratum 843419 that we don't expect to recognize | 4 | // Test cases for Cortex-A53 Erratum 843419 that we don't expect to recognize |
| 5 | // as needing a patch as one or more of the conditions isn't satisfied. | 5 | // as needing a patch as one or more of the conditions isn't satisfied. |
| 6 | // See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf | 6 | // See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf |
deps/lld/test/ELF/aarch64-cortex-a53-843419-recognize.s+125-80| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o |
| 3 | // RUN: ld.lld -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix CHECK-PRINT %s | 3 | // RUN: ld.lld -fix-cortex-a53-843419 -verbose %t.o -o %t2 2>&1 | FileCheck -check-prefix CHECK-PRINT %s |
| 4 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s -check-prefixes=CHECK,CHECK-FIX | 4 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s -check-prefixes=CHECK,CHECK-FIX |
| 5 | // RUN: ld.lld -verbose %t.o -o %t3 | 5 | // RUN: ld.lld %t.o -o %t3 |
| 6 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t3 | FileCheck %s -check-prefixes=CHECK,CHECK-NOFIX | 6 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t3 | FileCheck %s -check-prefixes=CHECK,CHECK-NOFIX |
| 7 | // Test cases for Cortex-A53 Erratum 843419 | 7 | // Test cases for Cortex-A53 Erratum 843419 |
| 8 | // See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf | 8 | // See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf |
| ... | @@ -30,7 +30,7 @@ | ... | @@ -30,7 +30,7 @@ |
| 30 | // CHECK: t3_ff8_ldr: | 30 | // CHECK: t3_ff8_ldr: |
| 31 | // CHECK-NEXT: 21ff8: e0 01 00 f0 adrp x0, #258048 | 31 | // CHECK-NEXT: 21ff8: e0 01 00 f0 adrp x0, #258048 |
| 32 | // CHECK-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1] | 32 | // CHECK-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1] |
| 33 | // CHECK-FIX: 22000: 03 b8 00 14 b #188428 | 33 | // CHECK-FIX: 22000: 03 c8 00 14 b #204812 |
| 34 | // CHECK-NOFIX: 22000: 00 00 40 f9 ldr x0, [x0] | 34 | // CHECK-NOFIX: 22000: 00 00 40 f9 ldr x0, [x0] |
| 35 | // CHECK-NEXT: 22004: c0 03 5f d6 ret | 35 | // CHECK-NEXT: 22004: c0 03 5f d6 ret |
| 36 | .section .text.01, "ax", %progbits | 36 | .section .text.01, "ax", %progbits |
| ... | @@ -48,7 +48,7 @@ t3_ff8_ldr: | ... | @@ -48,7 +48,7 @@ t3_ff8_ldr: |
| 48 | // CHECK: t3_ff8_ldrsimd: | 48 | // CHECK: t3_ff8_ldrsimd: |
| 49 | // CHECK-NEXT: 23ff8: e0 01 00 b0 adrp x0, #249856 | 49 | // CHECK-NEXT: 23ff8: e0 01 00 b0 adrp x0, #249856 |
| 50 | // CHECK-NEXT: 23ffc: 21 00 40 bd ldr s1, [x1] | 50 | // CHECK-NEXT: 23ffc: 21 00 40 bd ldr s1, [x1] |
| 51 | // CHECK-FIX: 24000: 05 b0 00 14 b #180244 | 51 | // CHECK-FIX: 24000: 05 c0 00 14 b #196628 |
| 52 | // CHECK-NOFIX: 24000: 02 04 40 f9 ldr x2, [x0, #8] | 52 | // CHECK-NOFIX: 24000: 02 04 40 f9 ldr x2, [x0, #8] |
| 53 | // CHECK-NEXT: 24004: c0 03 5f d6 ret | 53 | // CHECK-NEXT: 24004: c0 03 5f d6 ret |
| 54 | .section .text.02, "ax", %progbits | 54 | .section .text.02, "ax", %progbits |
| ... | @@ -66,7 +66,7 @@ t3_ff8_ldrsimd: | ... | @@ -66,7 +66,7 @@ t3_ff8_ldrsimd: |
| 66 | // CHECK: t3_ffc_ldrpost: | 66 | // CHECK: t3_ffc_ldrpost: |
| 67 | // CHECK-NEXT: 25ffc: c0 01 00 f0 adrp x0, #241664 | 67 | // CHECK-NEXT: 25ffc: c0 01 00 f0 adrp x0, #241664 |
| 68 | // CHECK-NEXT: 26000: 21 84 40 bc ldr s1, [x1], #8 | 68 | // CHECK-NEXT: 26000: 21 84 40 bc ldr s1, [x1], #8 |
| 69 | // CHECK-FIX: 26004: 06 a8 00 14 b #172056 | 69 | // CHECK-FIX: 26004: 06 b8 00 14 b #188440 |
| 70 | // CHECK-NOFIX: 26004: 03 08 40 f9 ldr x3, [x0, #16] | 70 | // CHECK-NOFIX: 26004: 03 08 40 f9 ldr x3, [x0, #16] |
| 71 | // CHECK-NEXT: 26008: c0 03 5f d6 ret | 71 | // CHECK-NEXT: 26008: c0 03 5f d6 ret |
| 72 | .section .text.03, "ax", %progbits | 72 | .section .text.03, "ax", %progbits |
| ... | @@ -84,7 +84,7 @@ t3_ffc_ldrpost: | ... | @@ -84,7 +84,7 @@ t3_ffc_ldrpost: |
| 84 | // CHECK: t3_ff8_strpre: | 84 | // CHECK: t3_ff8_strpre: |
| 85 | // CHECK-NEXT: 27ff8: c0 01 00 b0 adrp x0, #233472 | 85 | // CHECK-NEXT: 27ff8: c0 01 00 b0 adrp x0, #233472 |
| 86 | // CHECK-NEXT: 27ffc: 21 8c 00 bc str s1, [x1, #8]! | 86 | // CHECK-NEXT: 27ffc: 21 8c 00 bc str s1, [x1, #8]! |
| 87 | // CHECK-FIX: 28000: 09 a0 00 14 b #163876 | 87 | // CHECK-FIX: 28000: 09 b0 00 14 b #180260 |
| 88 | // CHECK-NOFIX: 28000: 02 00 40 f9 ldr x2, [x0] | 88 | // CHECK-NOFIX: 28000: 02 00 40 f9 ldr x2, [x0] |
| 89 | // CHECK-NEXT: 28004: c0 03 5f d6 ret | 89 | // CHECK-NEXT: 28004: c0 03 5f d6 ret |
| 90 | .section .text.04, "ax", %progbits | 90 | .section .text.04, "ax", %progbits |
| ... | @@ -102,7 +102,7 @@ t3_ff8_strpre: | ... | @@ -102,7 +102,7 @@ t3_ff8_strpre: |
| 102 | // CHECK: t3_ffc_str: | 102 | // CHECK: t3_ffc_str: |
| 103 | // CHECK-NEXT: 29ffc: bc 01 00 f0 adrp x28, #225280 | 103 | // CHECK-NEXT: 29ffc: bc 01 00 f0 adrp x28, #225280 |
| 104 | // CHECK-NEXT: 2a000: 42 00 00 f9 str x2, [x2] | 104 | // CHECK-NEXT: 2a000: 42 00 00 f9 str x2, [x2] |
| 105 | // CHECK-FIX: 2a004: 0a 98 00 14 b #155688 | 105 | // CHECK-FIX: 2a004: 0a a8 00 14 b #172072 |
| 106 | // CHECK-NOFIX: 2a004: 9c 07 00 f9 str x28, [x28, #8] | 106 | // CHECK-NOFIX: 2a004: 9c 07 00 f9 str x28, [x28, #8] |
| 107 | // CHECK-NEXT: 2a008: c0 03 5f d6 ret | 107 | // CHECK-NEXT: 2a008: c0 03 5f d6 ret |
| 108 | .section .text.05, "ax", %progbits | 108 | .section .text.05, "ax", %progbits |
| ... | @@ -120,7 +120,7 @@ t3_ffc_str: | ... | @@ -120,7 +120,7 @@ t3_ffc_str: |
| 120 | // CHECK: t3_ffc_strsimd: | 120 | // CHECK: t3_ffc_strsimd: |
| 121 | // CHECK-NEXT: 2bffc: bc 01 00 b0 adrp x28, #217088 | 121 | // CHECK-NEXT: 2bffc: bc 01 00 b0 adrp x28, #217088 |
| 122 | // CHECK-NEXT: 2c000: 44 00 00 b9 str w4, [x2] | 122 | // CHECK-NEXT: 2c000: 44 00 00 b9 str w4, [x2] |
| 123 | // CHECK-FIX: 2c004: 0c 90 00 14 b #147504 | 123 | // CHECK-FIX: 2c004: 0c a0 00 14 b #163888 |
| 124 | // CHECK-NOFIX: 2c004: 84 0b 00 f9 str x4, [x28, #16] | 124 | // CHECK-NOFIX: 2c004: 84 0b 00 f9 str x4, [x28, #16] |
| 125 | // CHECK-NEXT: 2c008: c0 03 5f d6 ret | 125 | // CHECK-NEXT: 2c008: c0 03 5f d6 ret |
| 126 | .section .text.06, "ax", %progbits | 126 | .section .text.06, "ax", %progbits |
| ... | @@ -138,7 +138,7 @@ t3_ffc_strsimd: | ... | @@ -138,7 +138,7 @@ t3_ffc_strsimd: |
| 138 | // CHECK: t3_ff8_ldrunpriv: | 138 | // CHECK: t3_ff8_ldrunpriv: |
| 139 | // CHECK-NEXT: 2dff8: 9d 01 00 f0 adrp x29, #208896 | 139 | // CHECK-NEXT: 2dff8: 9d 01 00 f0 adrp x29, #208896 |
| 140 | // CHECK-NEXT: 2dffc: 41 08 40 38 ldtrb w1, [x2] | 140 | // CHECK-NEXT: 2dffc: 41 08 40 38 ldtrb w1, [x2] |
| 141 | // CHECK-FIX: 2e000: 0f 88 00 14 b #139324 | 141 | // CHECK-FIX: 2e000: 0f 98 00 14 b #155708 |
| 142 | // CHECK-NOFIX: 2e000: bd 03 40 f9 ldr x29, [x29] | 142 | // CHECK-NOFIX: 2e000: bd 03 40 f9 ldr x29, [x29] |
| 143 | // CHECK-NEXT: 2e004: c0 03 5f d6 ret | 143 | // CHECK-NEXT: 2e004: c0 03 5f d6 ret |
| 144 | .section .text.07, "ax", %progbits | 144 | .section .text.07, "ax", %progbits |
| ... | @@ -156,7 +156,7 @@ t3_ff8_ldrunpriv: | ... | @@ -156,7 +156,7 @@ t3_ff8_ldrunpriv: |
| 156 | // CHECK: t3_ffc_ldur: | 156 | // CHECK: t3_ffc_ldur: |
| 157 | // CHECK-NEXT: 2fffc: 9d 01 00 b0 adrp x29, #200704 | 157 | // CHECK-NEXT: 2fffc: 9d 01 00 b0 adrp x29, #200704 |
| 158 | // CHECK-NEXT: 30000: 42 40 40 b8 ldur w2, [x2, #4] | 158 | // CHECK-NEXT: 30000: 42 40 40 b8 ldur w2, [x2, #4] |
| 159 | // CHECK-FIX: 30004: 10 80 00 14 b #131136 | 159 | // CHECK-FIX: 30004: 10 90 00 14 b #147520 |
| 160 | // CHECK-NOFIX: 30004: bd 07 40 f9 ldr x29, [x29, #8] | 160 | // CHECK-NOFIX: 30004: bd 07 40 f9 ldr x29, [x29, #8] |
| 161 | // CHECK-NEXT: 30008: c0 03 5f d6 ret | 161 | // CHECK-NEXT: 30008: c0 03 5f d6 ret |
| 162 | .balign 4096 | 162 | .balign 4096 |
| ... | @@ -173,8 +173,8 @@ t3_ffc_ldur: | ... | @@ -173,8 +173,8 @@ t3_ffc_ldur: |
| 173 | // CHECK: t3_ffc_sturh: | 173 | // CHECK: t3_ffc_sturh: |
| 174 | // CHECK-NEXT: 31ffc: 72 01 00 f0 adrp x18, #192512 | 174 | // CHECK-NEXT: 31ffc: 72 01 00 f0 adrp x18, #192512 |
| 175 | // CHECK-NEXT: 32000: 43 40 00 78 sturh w3, [x2, #4] | 175 | // CHECK-NEXT: 32000: 43 40 00 78 sturh w3, [x2, #4] |
| 176 | // CHECK-FIX: 32004: 12 78 00 14 b #122952 | 176 | // CHECK-FIX: 32004: 12 88 00 14 b #139336 |
| 177 | // CHECK-NOFIX: 32004: 41 0a 40 f9 ldr x1, [x18, #16] | 177 | // CHECK-NOFIX: 32004: 41 0a 40 f9 ldr x1, [x18, #16] |
| 178 | // CHECK-NEXT: 32008: c0 03 5f d6 ret | 178 | // CHECK-NEXT: 32008: c0 03 5f d6 ret |
| 179 | .section .text.09, "ax", %progbits | 179 | .section .text.09, "ax", %progbits |
| 180 | .balign 4096 | 180 | .balign 4096 |
| ... | @@ -191,7 +191,7 @@ t3_ffc_sturh: | ... | @@ -191,7 +191,7 @@ t3_ffc_sturh: |
| 191 | // CHECK: t3_ff8_literal: | 191 | // CHECK: t3_ff8_literal: |
| 192 | // CHECK-NEXT: 33ff8: 72 01 00 b0 adrp x18, #184320 | 192 | // CHECK-NEXT: 33ff8: 72 01 00 b0 adrp x18, #184320 |
| 193 | // CHECK-NEXT: 33ffc: e3 ff ff 58 ldr x3, #-4 | 193 | // CHECK-NEXT: 33ffc: e3 ff ff 58 ldr x3, #-4 |
| 194 | // CHECK-FIX: 34000: 15 70 00 14 b #114772 | 194 | // CHECK-FIX: 34000: 15 80 00 14 b #131156 |
| 195 | // CHECK-NOFIX: 34000: 52 02 40 f9 ldr x18, [x18] | 195 | // CHECK-NOFIX: 34000: 52 02 40 f9 ldr x18, [x18] |
| 196 | // CHECK-NEXT: 34004: c0 03 5f d6 ret | 196 | // CHECK-NEXT: 34004: c0 03 5f d6 ret |
| 197 | .section .text.10, "ax", %progbits | 197 | .section .text.10, "ax", %progbits |
| ... | @@ -209,7 +209,7 @@ t3_ff8_literal: | ... | @@ -209,7 +209,7 @@ t3_ff8_literal: |
| 209 | // CHECK: t3_ffc_register: | 209 | // CHECK: t3_ffc_register: |
| 210 | // CHECK-NEXT: 35ffc: 4f 01 00 f0 adrp x15, #176128 | 210 | // CHECK-NEXT: 35ffc: 4f 01 00 f0 adrp x15, #176128 |
| 211 | // CHECK-NEXT: 36000: 43 68 61 f8 ldr x3, [x2, x1] | 211 | // CHECK-NEXT: 36000: 43 68 61 f8 ldr x3, [x2, x1] |
| 212 | // CHECK-FIX: 36004: 16 68 00 14 b #106584 | 212 | // CHECK-FIX: 36004: 16 78 00 14 b #122968 |
| 213 | // CHECK-NOFIX: 36004: ea 05 40 f9 ldr x10, [x15, #8] | 213 | // CHECK-NOFIX: 36004: ea 05 40 f9 ldr x10, [x15, #8] |
| 214 | // CHECK-NEXT: 36008: c0 03 5f d6 ret | 214 | // CHECK-NEXT: 36008: c0 03 5f d6 ret |
| 215 | .section .text.11, "ax", %progbits | 215 | .section .text.11, "ax", %progbits |
| ... | @@ -227,7 +227,7 @@ t3_ffc_register: | ... | @@ -227,7 +227,7 @@ t3_ffc_register: |
| 227 | // CHECK: t3_ff8_stp: | 227 | // CHECK: t3_ff8_stp: |
| 228 | // CHECK-NEXT: 37ff8: 50 01 00 b0 adrp x16, #167936 | 228 | // CHECK-NEXT: 37ff8: 50 01 00 b0 adrp x16, #167936 |
| 229 | // CHECK-NEXT: 37ffc: 61 08 00 a9 stp x1, x2, [x3] | 229 | // CHECK-NEXT: 37ffc: 61 08 00 a9 stp x1, x2, [x3] |
| 230 | // CHECK-FIX: 38000: 19 60 00 14 b #98404 | 230 | // CHECK-FIX: 38000: 19 70 00 14 b #114788 |
| 231 | // CHECK-NOFIX: 38000: 0d 0a 40 f9 ldr x13, [x16, #16] | 231 | // CHECK-NOFIX: 38000: 0d 0a 40 f9 ldr x13, [x16, #16] |
| 232 | // CHECK-NEXT: 38004: c0 03 5f d6 ret | 232 | // CHECK-NEXT: 38004: c0 03 5f d6 ret |
| 233 | .section .text.12, "ax", %progbits | 233 | .section .text.12, "ax", %progbits |
| ... | @@ -245,7 +245,7 @@ t3_ff8_stp: | ... | @@ -245,7 +245,7 @@ t3_ff8_stp: |
| 245 | // CHECK: t3_ffc_stnp: | 245 | // CHECK: t3_ffc_stnp: |
| 246 | // CHECK-NEXT: 39ffc: 27 01 00 f0 adrp x7, #159744 | 246 | // CHECK-NEXT: 39ffc: 27 01 00 f0 adrp x7, #159744 |
| 247 | // CHECK-NEXT: 3a000: 61 08 00 a8 stnp x1, x2, [x3] | 247 | // CHECK-NEXT: 3a000: 61 08 00 a8 stnp x1, x2, [x3] |
| 248 | // CHECK-FIX: 3a004: 1a 58 00 14 b #90216 | 248 | // CHECK-FIX: 3a004: 1a 68 00 14 b #106600 |
| 249 | // CHECK-NOFIX: 3a004: e9 00 40 f9 ldr x9, [x7] | 249 | // CHECK-NOFIX: 3a004: e9 00 40 f9 ldr x9, [x7] |
| 250 | // CHECK-NEXT: 3a008: c0 03 5f d6 ret | 250 | // CHECK-NEXT: 3a008: c0 03 5f d6 ret |
| 251 | .section .text.13, "ax", %progbits | 251 | .section .text.13, "ax", %progbits |
| ... | @@ -262,8 +262,8 @@ t3_ffc_stnp: | ... | @@ -262,8 +262,8 @@ t3_ffc_stnp: |
| 262 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3BFFC in unpatched output. | 262 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3BFFC in unpatched output. |
| 263 | // CHECK: t3_ffc_st1singlepost: | 263 | // CHECK: t3_ffc_st1singlepost: |
| 264 | // CHECK-NEXT: 3bffc: 37 01 00 b0 adrp x23, #151552 | 264 | // CHECK-NEXT: 3bffc: 37 01 00 b0 adrp x23, #151552 |
| 265 | // CHECK-NEXT: 3c000: 20 70 82 4c st1 { v0.16b }, [x1], x2 | 265 | // CHECK-NEXT: 3c000: 20 04 82 0d st1 { v0.b }[1], [x1], x2 |
| 266 | // CHECK-FIX: 3c004: 1c 50 00 14 b #82032 | 266 | // CHECK-FIX: 3c004: 1c 60 00 14 b #98416 |
| 267 | // CHECK-NOFIX: 3c004: f6 06 40 f9 ldr x22, [x23, #8] | 267 | // CHECK-NOFIX: 3c004: f6 06 40 f9 ldr x22, [x23, #8] |
| 268 | // CHECK-NEXT: 3c008: c0 03 5f d6 ret | 268 | // CHECK-NEXT: 3c008: c0 03 5f d6 ret |
| 269 | .section .text.14, "ax", %progbits | 269 | .section .text.14, "ax", %progbits |
| ... | @@ -273,7 +273,7 @@ t3_ffc_stnp: | ... | @@ -273,7 +273,7 @@ t3_ffc_stnp: |
| 273 | .space 4096 - 4 | 273 | .space 4096 - 4 |
| 274 | t3_ffc_st1singlepost: | 274 | t3_ffc_st1singlepost: |
| 275 | adrp x23, dat2 | 275 | adrp x23, dat2 |
| 276 | st1 { v0.16b }, [x1], x2 | 276 | st1 { v0.b }[1], [x1], x2 |
| 277 | ldr x22, [x23, :lo12:dat2] | 277 | ldr x22, [x23, :lo12:dat2] |
| 278 | ret | 278 | ret |
| 279 | 279 | ||
| ... | @@ -281,7 +281,7 @@ t3_ffc_st1singlepost: | ... | @@ -281,7 +281,7 @@ t3_ffc_st1singlepost: |
| 281 | // CHECK: t3_ff8_st1multiple: | 281 | // CHECK: t3_ff8_st1multiple: |
| 282 | // CHECK-NEXT: 3dff8: 17 01 00 f0 adrp x23, #143360 | 282 | // CHECK-NEXT: 3dff8: 17 01 00 f0 adrp x23, #143360 |
| 283 | // CHECK-NEXT: 3dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1] | 283 | // CHECK-NEXT: 3dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1] |
| 284 | // CHECK-FIX: 3e000: 1f 48 00 14 b #73852 | 284 | // CHECK-FIX: 3e000: 1f 58 00 14 b #90236 |
| 285 | // CHECK-NOFIX: 3e000: f8 0a 40 f9 ldr x24, [x23, #16] | 285 | // CHECK-NOFIX: 3e000: f8 0a 40 f9 ldr x24, [x23, #16] |
| 286 | // CHECK-NEXT: 3e004: c0 03 5f d6 ret | 286 | // CHECK-NEXT: 3e004: c0 03 5f d6 ret |
| 287 | .section .text.15, "ax", %progbits | 287 | .section .text.15, "ax", %progbits |
| ... | @@ -300,7 +300,7 @@ t3_ff8_st1multiple: | ... | @@ -300,7 +300,7 @@ t3_ff8_st1multiple: |
| 300 | // CHECK-NEXT: 3fff8: 00 01 00 b0 adrp x0, #135168 | 300 | // CHECK-NEXT: 3fff8: 00 01 00 b0 adrp x0, #135168 |
| 301 | // CHECK-NEXT: 3fffc: 21 00 40 f9 ldr x1, [x1] | 301 | // CHECK-NEXT: 3fffc: 21 00 40 f9 ldr x1, [x1] |
| 302 | // CHECK-NEXT: 40000: 42 00 00 8b add x2, x2, x0 | 302 | // CHECK-NEXT: 40000: 42 00 00 8b add x2, x2, x0 |
| 303 | // CHECK-FIX: 40004: 20 40 00 14 b #65664 | 303 | // CHECK-FIX: 40004: 20 50 00 14 b #82048 |
| 304 | // CHECK-NOFIX: 40004: 02 00 40 f9 ldr x2, [x0] | 304 | // CHECK-NOFIX: 40004: 02 00 40 f9 ldr x2, [x0] |
| 305 | // CHECK-NEXT: 40008: c0 03 5f d6 ret | 305 | // CHECK-NEXT: 40008: c0 03 5f d6 ret |
| 306 | .section .text.16, "ax", %progbits | 306 | .section .text.16, "ax", %progbits |
| ... | @@ -320,7 +320,7 @@ t4_ff8_ldr: | ... | @@ -320,7 +320,7 @@ t4_ff8_ldr: |
| 320 | // CHECK-NEXT: 41ffc: fc 00 00 f0 adrp x28, #126976 | 320 | // CHECK-NEXT: 41ffc: fc 00 00 f0 adrp x28, #126976 |
| 321 | // CHECK-NEXT: 42000: 42 00 00 f9 str x2, [x2] | 321 | // CHECK-NEXT: 42000: 42 00 00 f9 str x2, [x2] |
| 322 | // CHECK-NEXT: 42004: 20 00 02 cb sub x0, x1, x2 | 322 | // CHECK-NEXT: 42004: 20 00 02 cb sub x0, x1, x2 |
| 323 | // CHECK-FIX: 42008: 21 38 00 14 b #57476 | 323 | // CHECK-FIX: 42008: 21 48 00 14 b #73860 |
| 324 | // CHECK-NOFIX: 42008: 9b 07 00 f9 str x27, [x28, #8] | 324 | // CHECK-NOFIX: 42008: 9b 07 00 f9 str x27, [x28, #8] |
| 325 | // CHECK-NEXT: 4200c: c0 03 5f d6 ret | 325 | // CHECK-NEXT: 4200c: c0 03 5f d6 ret |
| 326 | .section .text.17, "ax", %progbits | 326 | .section .text.17, "ax", %progbits |
| ... | @@ -340,7 +340,7 @@ t4_ffc_str: | ... | @@ -340,7 +340,7 @@ t4_ffc_str: |
| 340 | // CHECK-NEXT: 43ff8: f0 00 00 b0 adrp x16, #118784 | 340 | // CHECK-NEXT: 43ff8: f0 00 00 b0 adrp x16, #118784 |
| 341 | // CHECK-NEXT: 43ffc: 61 08 00 a9 stp x1, x2, [x3] | 341 | // CHECK-NEXT: 43ffc: 61 08 00 a9 stp x1, x2, [x3] |
| 342 | // CHECK-NEXT: 44000: 03 7e 10 9b mul x3, x16, x16 | 342 | // CHECK-NEXT: 44000: 03 7e 10 9b mul x3, x16, x16 |
| 343 | // CHECK-FIX: 44004: 24 30 00 14 b #49296 | 343 | // CHECK-FIX: 44004: 24 40 00 14 b #65680 |
| 344 | // CHECK-NOFIX: 44004: 0e 0a 40 f9 ldr x14, [x16, #16] | 344 | // CHECK-NOFIX: 44004: 0e 0a 40 f9 ldr x14, [x16, #16] |
| 345 | // CHECK-NEXT: 44008: c0 03 5f d6 ret | 345 | // CHECK-NEXT: 44008: c0 03 5f d6 ret |
| 346 | .section .text.18, "ax", %progbits | 346 | .section .text.18, "ax", %progbits |
| ... | @@ -360,7 +360,7 @@ t4_ff8_stp: | ... | @@ -360,7 +360,7 @@ t4_ff8_stp: |
| 360 | // CHECK-NEXT: 45ff8: d0 00 00 f0 adrp x16, #110592 | 360 | // CHECK-NEXT: 45ff8: d0 00 00 f0 adrp x16, #110592 |
| 361 | // CHECK-NEXT: 45ffc: 61 08 81 a9 stp x1, x2, [x3, #16]! | 361 | // CHECK-NEXT: 45ffc: 61 08 81 a9 stp x1, x2, [x3, #16]! |
| 362 | // CHECK-NEXT: 46000: 03 7e 10 9b mul x3, x16, x16 | 362 | // CHECK-NEXT: 46000: 03 7e 10 9b mul x3, x16, x16 |
| 363 | // CHECK-FIX: 46004: 26 28 00 14 b #41112 | 363 | // CHECK-FIX: 46004: 26 38 00 14 b #57496 |
| 364 | // CHECK-NOFIX: 46004: 0e 06 40 f9 ldr x14, [x16, #8] | 364 | // CHECK-NOFIX: 46004: 0e 06 40 f9 ldr x14, [x16, #8] |
| 365 | // CHECK-NEXT: 46008: c0 03 5f d6 ret | 365 | // CHECK-NEXT: 46008: c0 03 5f d6 ret |
| 366 | .section .text.19, "ax", %progbits | 366 | .section .text.19, "ax", %progbits |
| ... | @@ -380,7 +380,7 @@ t4_ff8_stppre: | ... | @@ -380,7 +380,7 @@ t4_ff8_stppre: |
| 380 | // CHECK-NEXT: 47ff8: d0 00 00 b0 adrp x16, #102400 | 380 | // CHECK-NEXT: 47ff8: d0 00 00 b0 adrp x16, #102400 |
| 381 | // CHECK-NEXT: 47ffc: 61 08 81 a8 stp x1, x2, [x3], #16 | 381 | // CHECK-NEXT: 47ffc: 61 08 81 a8 stp x1, x2, [x3], #16 |
| 382 | // CHECK-NEXT: 48000: 03 7e 10 9b mul x3, x16, x16 | 382 | // CHECK-NEXT: 48000: 03 7e 10 9b mul x3, x16, x16 |
| 383 | // CHECK-FIX: 48004: 28 20 00 14 b #32928 | 383 | // CHECK-FIX: 48004: 28 30 00 14 b #49312 |
| 384 | // CHECK-NOFIX: 48004: 0e 06 40 f9 ldr x14, [x16, #8] | 384 | // CHECK-NOFIX: 48004: 0e 06 40 f9 ldr x14, [x16, #8] |
| 385 | // CHECK-NEXT: 48008: c0 03 5f d6 ret | 385 | // CHECK-NEXT: 48008: c0 03 5f d6 ret |
| 386 | .section .text.20, "ax", %progbits | 386 | .section .text.20, "ax", %progbits |
| ... | @@ -400,7 +400,7 @@ t4_ff8_stppost: | ... | @@ -400,7 +400,7 @@ t4_ff8_stppost: |
| 400 | // CHECK-NEXT: 49ffc: b0 00 00 f0 adrp x16, #94208 | 400 | // CHECK-NEXT: 49ffc: b0 00 00 f0 adrp x16, #94208 |
| 401 | // CHECK-NEXT: 4a000: 61 08 00 ad stp q1, q2, [x3] | 401 | // CHECK-NEXT: 4a000: 61 08 00 ad stp q1, q2, [x3] |
| 402 | // CHECK-NEXT: 4a004: 03 7e 10 9b mul x3, x16, x16 | 402 | // CHECK-NEXT: 4a004: 03 7e 10 9b mul x3, x16, x16 |
| 403 | // CHECK-FIX: 4a008: 29 18 00 14 b #24740 | 403 | // CHECK-FIX: 4a008: 29 28 00 14 b #41124 |
| 404 | // CHECK-NOFIX: 4a008: 0e 06 40 f9 ldr x14, [x16, #8] | 404 | // CHECK-NOFIX: 4a008: 0e 06 40 f9 ldr x14, [x16, #8] |
| 405 | // CHECK-NEXT: 4a00c: c0 03 5f d6 ret | 405 | // CHECK-NEXT: 4a00c: c0 03 5f d6 ret |
| 406 | .section .text.21, "ax", %progbits | 406 | .section .text.21, "ax", %progbits |
| ... | @@ -420,7 +420,7 @@ t4_ffc_stpsimd: | ... | @@ -420,7 +420,7 @@ t4_ffc_stpsimd: |
| 420 | // CHECK-NEXT: 4bffc: a7 00 00 b0 adrp x7, #86016 | 420 | // CHECK-NEXT: 4bffc: a7 00 00 b0 adrp x7, #86016 |
| 421 | // CHECK-NEXT: 4c000: 61 08 00 a8 stnp x1, x2, [x3] | 421 | // CHECK-NEXT: 4c000: 61 08 00 a8 stnp x1, x2, [x3] |
| 422 | // CHECK-NEXT: 4c004: 1f 20 03 d5 nop | 422 | // CHECK-NEXT: 4c004: 1f 20 03 d5 nop |
| 423 | // CHECK-FIX: 4c008: 2b 10 00 14 b #16556 | 423 | // CHECK-FIX: 4c008: 2b 20 00 14 b #32940 |
| 424 | // CHECK-NOFIX: 4c008: ea 00 40 f9 ldr x10, [x7] | 424 | // CHECK-NOFIX: 4c008: ea 00 40 f9 ldr x10, [x7] |
| 425 | // CHECK-NEXT: 4c00c: c0 03 5f d6 ret | 425 | // CHECK-NEXT: 4c00c: c0 03 5f d6 ret |
| 426 | .section .text.22, "ax", %progbits | 426 | .section .text.22, "ax", %progbits |
| ... | @@ -438,9 +438,9 @@ t4_ffc_stnp: | ... | @@ -438,9 +438,9 @@ t4_ffc_stnp: |
| 438 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4DFFC in unpatched output. | 438 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4DFFC in unpatched output. |
| 439 | // CHECK: t4_ffc_st1: | 439 | // CHECK: t4_ffc_st1: |
| 440 | // CHECK-NEXT: 4dffc: 98 00 00 f0 adrp x24, #77824 | 440 | // CHECK-NEXT: 4dffc: 98 00 00 f0 adrp x24, #77824 |
| 441 | // CHECK-NEXT: 4e000: 20 70 00 4c st1 { v0.16b }, [x1] | 441 | // CHECK-NEXT: 4e000: 20 80 00 4d st1 { v0.s }[2], [x1] |
| 442 | // CHECK-NEXT: 4e004: f6 06 40 f9 ldr x22, [x23, #8] | 442 | // CHECK-NEXT: 4e004: f6 06 40 f9 ldr x22, [x23, #8] |
| 443 | // CHECK-FIX: 4e008: 2d 08 00 14 b #8372 | 443 | // CHECK-FIX: 4e008: 2d 18 00 14 b #24756 |
| 444 | // CHECK-NOFIX: 4e008: 18 ff 3f f9 str x24, [x24, #32760] | 444 | // CHECK-NOFIX: 4e008: 18 ff 3f f9 str x24, [x24, #32760] |
| 445 | // CHECK-NEXT: 4e00c: c0 03 5f d6 ret | 445 | // CHECK-NEXT: 4e00c: c0 03 5f d6 ret |
| 446 | .section .text.23, "ax", %progbits | 446 | .section .text.23, "ax", %progbits |
| ... | @@ -450,7 +450,7 @@ t4_ffc_stnp: | ... | @@ -450,7 +450,7 @@ t4_ffc_stnp: |
| 450 | .space 4096 - 4 | 450 | .space 4096 - 4 |
| 451 | t4_ffc_st1: | 451 | t4_ffc_st1: |
| 452 | adrp x24, dat2 | 452 | adrp x24, dat2 |
| 453 | st1 { v0.16b }, [x1] | 453 | st1 { v0.s }[2], [x1] |
| 454 | ldr x22, [x23, :got_lo12:dat2] | 454 | ldr x22, [x23, :got_lo12:dat2] |
| 455 | str x24, [x24, #32760] | 455 | str x24, [x24, #32760] |
| 456 | ret | 456 | ret |
| ... | @@ -459,7 +459,7 @@ t4_ffc_st1: | ... | @@ -459,7 +459,7 @@ t4_ffc_st1: |
| 459 | // CHECK: t3_ff8_ldr_once: | 459 | // CHECK: t3_ff8_ldr_once: |
| 460 | // CHECK-NEXT: 4fff8: 80 00 00 b0 adrp x0, #69632 | 460 | // CHECK-NEXT: 4fff8: 80 00 00 b0 adrp x0, #69632 |
| 461 | // CHECK-NEXT: 4fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2 | 461 | // CHECK-NEXT: 4fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2 |
| 462 | // CHECK-FIX: 50000: 31 00 00 14 b #196 | 462 | // CHECK-FIX: 50000: 31 10 00 14 b #16580 |
| 463 | // CHECK-NOFIX: 50000: 01 08 40 f9 ldr x1, [x0, #16] | 463 | // CHECK-NOFIX: 50000: 01 08 40 f9 ldr x1, [x0, #16] |
| 464 | // CHECK-NEXT: 50004: 02 08 40 f9 ldr x2, [x0, #16] | 464 | // CHECK-NEXT: 50004: 02 08 40 f9 ldr x2, [x0, #16] |
| 465 | // CHECK-NEXT: 50008: c0 03 5f d6 ret | 465 | // CHECK-NEXT: 50008: c0 03 5f d6 ret |
| ... | @@ -475,6 +475,46 @@ t3_ff8_ldr_once: | ... | @@ -475,6 +475,46 @@ t3_ff8_ldr_once: |
| 475 | ldr x2, [x0, #16] | 475 | ldr x2, [x0, #16] |
| 476 | ret | 476 | ret |
| 477 | 477 | ||
| 478 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 51FF8 in unpatched output. | ||
| 479 | // CHECK: t3_ff8_ldxr: | ||
| 480 | // CHECK-NEXT: 51ff8: 60 00 00 f0 adrp x0, #61440 | ||
| 481 | // CHECK-NEXT: 51ffc: 03 7c 5f c8 ldxr x3, [x0] | ||
| 482 | // CHECK-FIX: 52000: 33 08 00 14 b #8396 | ||
| 483 | // CHECK-NOFIX: 52000: 01 08 40 f9 ldr x1, [x0, #16] | ||
| 484 | // CHECK: 52004: 02 08 40 f9 ldr x2, [x0, #16] | ||
| 485 | // CHECK-NEXT: 52008: c0 03 5f d6 ret | ||
| 486 | .section .text.25, "ax", %progbits | ||
| 487 | .balign 4096 | ||
| 488 | .globl t3_ff8_ldxr | ||
| 489 | .type t3_ff8_ldxr, %function | ||
| 490 | .space 4096 - 8 | ||
| 491 | t3_ff8_ldxr: | ||
| 492 | adrp x0, dat3 | ||
| 493 | ldxr x3, [x0] | ||
| 494 | ldr x1, [x0, #16] | ||
| 495 | ldr x2, [x0, #16] | ||
| 496 | ret | ||
| 497 | |||
| 498 | // CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 53FF8 in unpatched output. | ||
| 499 | // CHECK: t3_ff8_stxr: | ||
| 500 | // CHECK-NEXT: 53ff8: 60 00 00 b0 adrp x0, #53248 | ||
| 501 | // CHECK-NEXT: 53ffc: 03 7c 04 c8 stxr w4, x3, [x0] | ||
| 502 | // CHECK-FIX: 54000: 35 00 00 14 b #212 | ||
| 503 | // CHECK-NOFIX: 54000: 01 08 40 f9 ldr x1, [x0, #16] | ||
| 504 | // CHECK: 54004: 02 08 40 f9 ldr x2, [x0, #16] | ||
| 505 | // CHECK-NEXT: 54008: c0 03 5f d6 ret | ||
| 506 | .section .text.26, "ax", %progbits | ||
| 507 | .balign 4096 | ||
| 508 | .globl t3_ff8_stxr | ||
| 509 | .type t3_ff8_stxr, %function | ||
| 510 | .space 4096 - 8 | ||
| 511 | t3_ff8_stxr: | ||
| 512 | adrp x0, dat3 | ||
| 513 | stxr w4, x3, [x0] | ||
| 514 | ldr x1, [x0, #16] | ||
| 515 | ldr x2, [x0, #16] | ||
| 516 | ret | ||
| 517 | |||
| 478 | .text | 518 | .text |
| 479 | .globl _start | 519 | .globl _start |
| 480 | .type _start, %function | 520 | .type _start, %function |
| ... | @@ -482,78 +522,83 @@ _start: | ... | @@ -482,78 +522,83 @@ _start: |
| 482 | ret | 522 | ret |
| 483 | 523 | ||
| 484 | // CHECK-FIX: __CortexA53843419_22000: | 524 | // CHECK-FIX: __CortexA53843419_22000: |
| 485 | // CHECK-FIX-NEXT: 5000c: 00 00 40 f9 ldr x0, [x0] | 525 | // CHECK-FIX-NEXT: 5400c: 00 00 40 f9 ldr x0, [x0] |
| 486 | // CHECK-FIX-NEXT: 50010: fd 47 ff 17 b #-188428 | 526 | // CHECK-FIX-NEXT: 54010: fd 37 ff 17 b #-204812 |
| 487 | // CHECK-FIX: __CortexA53843419_24000: | 527 | // CHECK-FIX: __CortexA53843419_24000: |
| 488 | // CHECK-FIX-NEXT: 50014: 02 04 40 f9 ldr x2, [x0, #8] | 528 | // CHECK-FIX-NEXT: 54014: 02 04 40 f9 ldr x2, [x0, #8] |
| 489 | // CHECK-FIX-NEXT: 50018: fb 4f ff 17 b #-180244 | 529 | // CHECK-FIX-NEXT: 54018: fb 3f ff 17 b #-196628 |
| 490 | // CHECK-FIX: __CortexA53843419_26004: | 530 | // CHECK-FIX: __CortexA53843419_26004: |
| 491 | // CHECK-FIX-NEXT: 5001c: 03 08 40 f9 ldr x3, [x0, #16] | 531 | // CHECK-FIX-NEXT: 5401c: 03 08 40 f9 ldr x3, [x0, #16] |
| 492 | // CHECK-FIX-NEXT: 50020: fa 57 ff 17 b #-172056 | 532 | // CHECK-FIX-NEXT: 54020: fa 47 ff 17 b #-188440 |
| 493 | // CHECK-FIX: __CortexA53843419_28000: | 533 | // CHECK-FIX: __CortexA53843419_28000: |
| 494 | // CHECK-FIX-NEXT: 50024: 02 00 40 f9 ldr x2, [x0] | 534 | // CHECK-FIX-NEXT: 54024: 02 00 40 f9 ldr x2, [x0] |
| 495 | // CHECK-FIX-NEXT: 50028: f7 5f ff 17 b #-163876 | 535 | // CHECK-FIX-NEXT: 54028: f7 4f ff 17 b #-180260 |
| 496 | // CHECK-FIX: __CortexA53843419_2A004: | 536 | // CHECK-FIX: __CortexA53843419_2A004: |
| 497 | // CHECK-FIX-NEXT: 5002c: 9c 07 00 f9 str x28, [x28, #8] | 537 | // CHECK-FIX-NEXT: 5402c: 9c 07 00 f9 str x28, [x28, #8] |
| 498 | // CHECK-FIX-NEXT: 50030: f6 67 ff 17 b #-155688 | 538 | // CHECK-FIX-NEXT: 54030: f6 57 ff 17 b #-172072 |
| 499 | // CHECK-FIX: __CortexA53843419_2C004: | 539 | // CHECK-FIX: __CortexA53843419_2C004: |
| 500 | // CHECK-FIX-NEXT: 50034: 84 0b 00 f9 str x4, [x28, #16] | 540 | // CHECK-FIX-NEXT: 54034: 84 0b 00 f9 str x4, [x28, #16] |
| 501 | // CHECK-FIX-NEXT: 50038: f4 6f ff 17 b #-147504 | 541 | // CHECK-FIX-NEXT: 54038: f4 5f ff 17 b #-163888 |
| 502 | // CHECK-FIX: __CortexA53843419_2E000: | 542 | // CHECK-FIX: __CortexA53843419_2E000: |
| 503 | // CHECK-FIX-NEXT: 5003c: bd 03 40 f9 ldr x29, [x29] | 543 | // CHECK-FIX-NEXT: 5403c: bd 03 40 f9 ldr x29, [x29] |
| 504 | // CHECK-FIX-NEXT: 50040: f1 77 ff 17 b #-139324 | 544 | // CHECK-FIX-NEXT: 54040: f1 67 ff 17 b #-155708 |
| 505 | // CHECK-FIX: __CortexA53843419_30004: | 545 | // CHECK-FIX: __CortexA53843419_30004: |
| 506 | // CHECK-FIX-NEXT: 50044: bd 07 40 f9 ldr x29, [x29, #8] | 546 | // CHECK-FIX-NEXT: 54044: bd 07 40 f9 ldr x29, [x29, #8] |
| 507 | // CHECK-FIX-NEXT: 50048: f0 7f ff 17 b #-131136 | 547 | // CHECK-FIX-NEXT: 54048: f0 6f ff 17 b #-147520 |
| 508 | // CHECK-FIX: __CortexA53843419_32004: | 548 | // CHECK-FIX: __CortexA53843419_32004: |
| 509 | // CHECK-FIX-NEXT: 5004c: 41 0a 40 f9 ldr x1, [x18, #16] | 549 | // CHECK-FIX-NEXT: 5404c: 41 0a 40 f9 ldr x1, [x18, #16] |
| 510 | // CHECK-FIX-NEXT: 50050: ee 87 ff 17 b #-122952 | 550 | // CHECK-FIX-NEXT: 54050: ee 77 ff 17 b #-139336 |
| 511 | // CHECK-FIX: __CortexA53843419_34000: | 551 | // CHECK-FIX: __CortexA53843419_34000: |
| 512 | // CHECK-FIX-NEXT: 50054: 52 02 40 f9 ldr x18, [x18] | 552 | // CHECK-FIX-NEXT: 54054: 52 02 40 f9 ldr x18, [x18] |
| 513 | // CHECK-FIX-NEXT: 50058: eb 8f ff 17 b #-114772 | 553 | // CHECK-FIX-NEXT: 54058: eb 7f ff 17 b #-131156 |
| 514 | // CHECK-FIX: __CortexA53843419_36004: | 554 | // CHECK-FIX: __CortexA53843419_36004: |
| 515 | // CHECK-FIX-NEXT: 5005c: ea 05 40 f9 ldr x10, [x15, #8] | 555 | // CHECK-FIX-NEXT: 5405c: ea 05 40 f9 ldr x10, [x15, #8] |
| 516 | // CHECK-FIX-NEXT: 50060: ea 97 ff 17 b #-106584 | 556 | // CHECK-FIX-NEXT: 54060: ea 87 ff 17 b #-122968 |
| 517 | // CHECK-FIX: __CortexA53843419_38000: | 557 | // CHECK-FIX: __CortexA53843419_38000: |
| 518 | // CHECK-FIX-NEXT: 50064: 0d 0a 40 f9 ldr x13, [x16, #16] | 558 | // CHECK-FIX-NEXT: 54064: 0d 0a 40 f9 ldr x13, [x16, #16] |
| 519 | // CHECK-FIX-NEXT: 50068: e7 9f ff 17 b #-98404 | 559 | // CHECK-FIX-NEXT: 54068: e7 8f ff 17 b #-114788 |
| 520 | // CHECK-FIX: __CortexA53843419_3A004: | 560 | // CHECK-FIX: __CortexA53843419_3A004: |
| 521 | // CHECK-FIX-NEXT: 5006c: e9 00 40 f9 ldr x9, [x7] | 561 | // CHECK-FIX-NEXT: 5406c: e9 00 40 f9 ldr x9, [x7] |
| 522 | // CHECK-FIX-NEXT: 50070: e6 a7 ff 17 b #-90216 | 562 | // CHECK-FIX-NEXT: 54070: e6 97 ff 17 b #-106600 |
| 523 | // CHECK-FIX: __CortexA53843419_3C004: | 563 | // CHECK-FIX: __CortexA53843419_3C004: |
| 524 | // CHECK-FIX-NEXT: 50074: f6 06 40 f9 ldr x22, [x23, #8] | 564 | // CHECK-FIX-NEXT: 54074: f6 06 40 f9 ldr x22, [x23, #8] |
| 525 | // CHECK-FIX-NEXT: 50078: e4 af ff 17 b #-82032 | 565 | // CHECK-FIX-NEXT: 54078: e4 9f ff 17 b #-98416 |
| 526 | // CHECK-FIX: __CortexA53843419_3E000: | 566 | // CHECK-FIX: __CortexA53843419_3E000: |
| 527 | // CHECK-FIX-NEXT: 5007c: f8 0a 40 f9 ldr x24, [x23, #16] | 567 | // CHECK-FIX-NEXT: 5407c: f8 0a 40 f9 ldr x24, [x23, #16] |
| 528 | // CHECK-FIX-NEXT: 50080: e1 b7 ff 17 b #-73852 | 568 | // CHECK-FIX-NEXT: 54080: e1 a7 ff 17 b #-90236 |
| 529 | // CHECK-FIX: __CortexA53843419_40004: | 569 | // CHECK-FIX: __CortexA53843419_40004: |
| 530 | // CHECK-FIX-NEXT: 50084: 02 00 40 f9 ldr x2, [x0] | 570 | // CHECK-FIX-NEXT: 54084: 02 00 40 f9 ldr x2, [x0] |
| 531 | // CHECK-FIX-NEXT: 50088: e0 bf ff 17 b #-65664 | 571 | // CHECK-FIX-NEXT: 54088: e0 af ff 17 b #-82048 |
| 532 | // CHECK-FIX: __CortexA53843419_42008: | 572 | // CHECK-FIX: __CortexA53843419_42008: |
| 533 | // CHECK-FIX-NEXT: 5008c: 9b 07 00 f9 str x27, [x28, #8] | 573 | // CHECK-FIX-NEXT: 5408c: 9b 07 00 f9 str x27, [x28, #8] |
| 534 | // CHECK-FIX-NEXT: 50090: df c7 ff 17 b #-57476 | 574 | // CHECK-FIX-NEXT: 54090: df b7 ff 17 b #-73860 |
| 535 | // CHECK-FIX: __CortexA53843419_44004: | 575 | // CHECK-FIX: __CortexA53843419_44004: |
| 536 | // CHECK-FIX-NEXT: 50094: 0e 0a 40 f9 ldr x14, [x16, #16] | 576 | // CHECK-FIX-NEXT: 54094: 0e 0a 40 f9 ldr x14, [x16, #16] |
| 537 | // CHECK-FIX-NEXT: 50098: dc cf ff 17 b #-49296 | 577 | // CHECK-FIX-NEXT: 54098: dc bf ff 17 b #-65680 |
| 538 | // CHECK-FIX: __CortexA53843419_46004: | 578 | // CHECK-FIX: __CortexA53843419_46004: |
| 539 | // CHECK-FIX-NEXT: 5009c: 0e 06 40 f9 ldr x14, [x16, #8] | 579 | // CHECK-FIX-NEXT: 5409c: 0e 06 40 f9 ldr x14, [x16, #8] |
| 540 | // CHECK-FIX-NEXT: 500a0: da d7 ff 17 b #-41112 | 580 | // CHECK-FIX-NEXT: 540a0: da c7 ff 17 b #-57496 |
| 541 | // CHECK-FIX: __CortexA53843419_48004: | 581 | // CHECK-FIX: __CortexA53843419_48004: |
| 542 | // CHECK-FIX-NEXT: 500a4: 0e 06 40 f9 ldr x14, [x16, #8] | 582 | // CHECK-FIX-NEXT: 540a4: 0e 06 40 f9 ldr x14, [x16, #8] |
| 543 | // CHECK-FIX-NEXT: 500a8: d8 df ff 17 b #-32928 | 583 | // CHECK-FIX-NEXT: 540a8: d8 cf ff 17 b #-49312 |
| 544 | // CHECK-FIX: __CortexA53843419_4A008: | 584 | // CHECK-FIX: __CortexA53843419_4A008: |
| 545 | // CHECK-FIX-NEXT: 500ac: 0e 06 40 f9 ldr x14, [x16, #8] | 585 | // CHECK-FIX-NEXT: 540ac: 0e 06 40 f9 ldr x14, [x16, #8] |
| 546 | // CHECK-FIX-NEXT: 500b0: d7 e7 ff 17 b #-24740 | 586 | // CHECK-FIX-NEXT: 540b0: d7 d7 ff 17 b #-41124 |
| 547 | // CHECK-FIX: __CortexA53843419_4C008: | 587 | // CHECK-FIX: __CortexA53843419_4C008: |
| 548 | // CHECK-FIX-NEXT: 500b4: ea 00 40 f9 ldr x10, [x7] | 588 | // CHECK-FIX-NEXT: 540b4: ea 00 40 f9 ldr x10, [x7] |
| 549 | // CHECK-FIX-NEXT: 500b8: d5 ef ff 17 b #-16556 | 589 | // CHECK-FIX-NEXT: 540b8: d5 df ff 17 b #-32940 |
| 550 | // CHECK-FIX: __CortexA53843419_4E008: | 590 | // CHECK-FIX: __CortexA53843419_4E008: |
| 551 | // CHECK-FIX-NEXT: 500bc: 18 ff 3f f9 str x24, [x24, #32760] | 591 | // CHECK-FIX-NEXT: 540bc: 18 ff 3f f9 str x24, [x24, #32760] |
| 552 | // CHECK-FIX-NEXT: 500c0: d3 f7 ff 17 b #-8372 | 592 | // CHECK-FIX-NEXT: 540c0: d3 e7 ff 17 b #-24756 |
| 553 | // CHECK-FIX: __CortexA53843419_50000: | 593 | // CHECK-FIX: __CortexA53843419_50000: |
| 554 | // CHECK-FIX-NEXT: 500c4: 01 08 40 f9 ldr x1, [x0, #16] | 594 | // CHECK-FIX-NEXT: 540c4: 01 08 40 f9 ldr x1, [x0, #16] |
| 555 | // CHECK-FIX-NEXT: 500c8: cf ff ff 17 b #-196 | 595 | // CHECK-FIX-NEXT: 540c8: cf ef ff 17 b #-16580 |
| 556 | 596 | // CHECK-FIX: __CortexA53843419_52000: | |
| 597 | // CHECK-FIX-NEXT: 540cc: 01 08 40 f9 ldr x1, [x0, #16] | ||
| 598 | // CHECK-FIX-NEXT: 540d0: cd f7 ff 17 b #-8396 | ||
| 599 | // CHECK-FIX: __CortexA53843419_54000: | ||
| 600 | // CHECK-FIX-NEXT: 540d4: 01 08 40 f9 ldr x1, [x0, #16] | ||
| 601 | // CHECK-FIX-NEXT: 540d8: cb ff ff 17 b #-212 | ||
| 557 | .data | 602 | .data |
| 558 | .globl dat | 603 | .globl dat |
| 559 | .globl dat2 | 604 | .globl dat2 |
deps/lld/test/ELF/aarch64-cortex-a53-843419-thunk.s+2-1| ... | @@ -3,7 +3,8 @@ | ... | @@ -3,7 +3,8 @@ |
| 3 | // RUN: echo "SECTIONS { \ | 3 | // RUN: echo "SECTIONS { \ |
| 4 | // RUN: .text1 0x10000 : { *(.text.01) *(.text.02) *(.text.03) } \ | 4 | // RUN: .text1 0x10000 : { *(.text.01) *(.text.02) *(.text.03) } \ |
| 5 | // RUN: .text2 0x8010000 : { *(.text.04) } } " > %t.script | 5 | // RUN: .text2 0x8010000 : { *(.text.04) } } " > %t.script |
| 6 | // RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix=CHECK-PRINT %s | 6 | // RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 2>&1 \ |
| 7 | // RUN: | FileCheck -check-prefix=CHECK-PRINT %s | ||
| 7 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s | 8 | // RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s |
| 8 | 9 | ||
| 9 | // %t2 is 128 Megabytes, so delete it early. | 10 | // %t2 is 128 Megabytes, so delete it early. |
deps/lld/test/ELF/aarch64-data-relocs.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs256.s -o %t256.o | 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs256.s -o %t256.o |
| 3 | // RUN: ld.lld %t %t256.o -o %t2 | 4 | // RUN: ld.lld %t %t256.o -o %t2 |
| 4 | // RUN: llvm-objdump -s %t2 | FileCheck %s | 5 | // RUN: llvm-objdump -s %t2 | FileCheck %s |
| 5 | // REQUIRES: aarch64 | ||
| 6 | 6 | ||
| 7 | .globl _start | 7 | .globl _start |
| 8 | _start: | 8 | _start: |
deps/lld/test/ELF/aarch64-fpic-abs16.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: relocation R_AARCH64_ABS16 cannot be used against shared object; recompile with -fPIC | 4 | // CHECK: relocation R_AARCH64_ABS16 cannot be used against symbol foo; recompile with -fPIC |
| 5 | // CHECK-NEXT: >>> defined in {{.*}}.o | 5 | // CHECK-NEXT: >>> defined in {{.*}}.o |
| 6 | // CHECK-NEXT: >>> referenced by {{.*}}.o:(.data+0x0) | 6 | // CHECK-NEXT: >>> referenced by {{.*}}.o:(.data+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-add_abs_lo12_nc.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: can't create dynamic relocation R_AARCH64_ADD_ABS_LO12_NC against symbol: dat | 4 | // CHECK: can't create dynamic relocation R_AARCH64_ADD_ABS_LO12_NC against symbol: dat in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 5 | // CHECK: >>> defined in {{.*}}.o | 5 | // CHECK: >>> defined in {{.*}}.o |
| 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-adr_prel_lo21.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: can't create dynamic relocation R_AARCH64_ADR_PREL_LO21 against symbol: dat | 4 | // CHECK: relocation R_AARCH64_ADR_PREL_LO21 cannot be used against symbol dat; recompile with -fPIC |
| 5 | // CHECK: >>> defined in {{.*}}.o | 5 | // CHECK: >>> defined in {{.*}}.o |
| 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: can't create dynamic relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol: dat | 4 | // CHECK: relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used against symbol dat; recompile with -fPIC |
| 5 | // CHECK: >>> defined in {{.*}}.o | 5 | // CHECK: >>> defined in {{.*}}.o |
| 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: can't create dynamic relocation R_AARCH64_LDST32_ABS_LO12_NC against symbol: dat | 4 | // CHECK: can't create dynamic relocation R_AARCH64_LDST32_ABS_LO12_NC against symbol: dat in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 5 | // CHECK: >>> defined in {{.*}}.o | 5 | // CHECK: >>> defined in {{.*}}.o |
| 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: can't create dynamic relocation R_AARCH64_LDST64_ABS_LO12_NC against symbol: dat | 4 | // CHECK: can't create dynamic relocation R_AARCH64_LDST64_ABS_LO12_NC against symbol: dat in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 5 | // CHECK: >>> defined in {{.*}}.o | 5 | // CHECK: >>> defined in {{.*}}.o |
| 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: can't create dynamic relocation R_AARCH64_LDST8_ABS_LO12_NC against symbol: dat | 4 | // CHECK: can't create dynamic relocation R_AARCH64_LDST8_ABS_LO12_NC against symbol: dat in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 5 | // CHECK: >>> defined in {{.*}}.o | 5 | // CHECK: >>> defined in {{.*}}.o |
| 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | 6 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-prel16.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: R_AARCH64_PREL16 cannot be used against shared object; recompile with -fPIC | 4 | // CHECK: R_AARCH64_PREL16 cannot be used against symbol foo; recompile with -fPIC |
| 5 | // CHECK: >>> defined in {{.*}} | 5 | // CHECK: >>> defined in {{.*}} |
| 6 | // CHECK: >>> referenced by {{.*}}:(.data+0x0) | 6 | // CHECK: >>> referenced by {{.*}}:(.data+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-prel32.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: relocation R_AARCH64_PREL32 cannot be used against shared object; recompile with -fPIC | 4 | // CHECK: relocation R_AARCH64_PREL32 cannot be used against symbol foo; recompile with -fPIC |
| 5 | // CHECK: >>> defined in {{.*}} | 5 | // CHECK: >>> defined in {{.*}} |
| 6 | // CHECK: >>> referenced by {{.*}}:(.data+0x0) | 6 | // CHECK: >>> referenced by {{.*}}:(.data+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-fpic-prel64.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o |
| 3 | // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: relocation R_AARCH64_PREL64 cannot be used against shared object; recompile with -fPIC | 4 | // CHECK: relocation R_AARCH64_PREL64 cannot be used against symbol foo; recompile with -fPIC |
| 5 | // CHECK: >>> defined in {{.*}} | 5 | // CHECK: >>> defined in {{.*}} |
| 6 | // CHECK: >>> referenced by {{.*}}:(.data+0x0) | 6 | // CHECK: >>> referenced by {{.*}}:(.data+0x0) |
| 7 | 7 |
deps/lld/test/ELF/aarch64-gnu-ifunc-nosym.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-readobj -symbols %tout | FileCheck %s | 4 | // RUN: llvm-readobj -symbols %tout | FileCheck %s |
| 4 | // REQUIRES: aarch64 | ||
| 5 | 5 | ||
| 6 | // Check that no __rela_iplt_end/__rela_iplt_start | 6 | // Check that no __rela_iplt_end/__rela_iplt_start |
| 7 | // appear in symtab if there is no references to them. | 7 | // appear in symtab if there is no references to them. |
deps/lld/test/ELF/aarch64-gnu-ifunc-plt.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %S/Inputs/shared2.s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %S/Inputs/shared2.s -o %t1.o |
| 2 | // RUN: ld.lld %t1.o --shared -o %t.so | 3 | // RUN: ld.lld %t1.o --shared -o %t.so |
| 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o | 4 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM | 6 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 6 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT | 7 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT |
| 7 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s | 8 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s |
| 8 | // REQUIRES: aarch64 | ||
| 9 | 9 | ||
| 10 | // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt | 10 | // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt |
| 11 | // CHECK: Relocations [ | 11 | // CHECK: Relocations [ |
deps/lld/test/ELF/aarch64-gnu-ifunc.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM | 4 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 4 | // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s | 5 | // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s |
| 5 | // REQUIRES: aarch64 | ||
| 6 | 6 | ||
| 7 | // CHECK: Sections [ | 7 | // CHECK: Sections [ |
| 8 | // CHECK: Section { | 8 | // CHECK: Section { |
deps/lld/test/ELF/aarch64-hi21-error.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t |
| 3 | // RUN: not ld.lld %tabs %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %tabs %t -o /dev/null 2>&1 | FileCheck %s |
| 4 | // REQUIRES: aarch64 | ||
| 5 | 5 | ||
| 6 | .globl _start | 6 | .globl _start |
| 7 | _start: | 7 | _start: |
deps/lld/test/ELF/aarch64-jump26-thunk.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t |
| 3 | // RUN: ld.lld %t %tabs -o %t2 2>&1 | 4 | // RUN: ld.lld %t %tabs -o %t2 2>&1 |
| 4 | // RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s | 5 | // RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s |
| 5 | // REQUIRES: aarch64 | ||
| 6 | 6 | ||
| 7 | .text | 7 | .text |
| 8 | .globl _start | 8 | .globl _start |
deps/lld/test/ELF/aarch64-ldprel-lo19-invalid.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: aarch64 | 1 | # REQUIRES: aarch64 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o |
| 4 | # RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s | 4 | # RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 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: 2065536 is not in [-1048576, 1048575] |
| 7 | 7 |
deps/lld/test/ELF/aarch64-lo12-alignment.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t |
| 3 | // RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | // Test derived from a typical ODR violation where a global is declared | 5 | // Test derived from a typical ODR violation where a global is declared |
| 6 | // extern int but defined as a half or byte sized type. | 6 | // extern int but defined as a half or byte sized type. |
deps/lld/test/ELF/aarch64-lo21-error.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t |
| 3 | // RUN: not ld.lld %tabs %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %tabs %t -o /dev/null 2>&1 | FileCheck %s |
| 4 | // REQUIRES: aarch64 | ||
| 5 | 5 | ||
| 6 | .globl _start | 6 | .globl _start |
| 7 | _start: | 7 | _start: |
deps/lld/test/ELF/aarch64-load-alignment.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: aarch64 | 1 | # REQUIRES: aarch64 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o |
| 4 | # RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s | 4 | # RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 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: 0x10005 is not aligned to 4 bytes |
| 7 | 7 |
deps/lld/test/ELF/aarch64-relocs.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # REQUIRES: aarch64 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t |
| 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/uabs_label.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/uabs_label.s -o %t2.o |
| 3 | # RUN: ld.lld %t %t2.o -o %t2 | 4 | # RUN: ld.lld %t %t2.o -o %t2 |
| 4 | # RUN: llvm-objdump -d %t2 | FileCheck %s | 5 | # RUN: llvm-objdump -d %t2 | FileCheck %s |
| 5 | # REQUIRES: aarch64 | ||
| 6 | 6 | ||
| 7 | .section .R_AARCH64_ADR_PREL_LO21,"ax",@progbits | 7 | .section .R_AARCH64_ADR_PREL_LO21,"ax",@progbits |
| 8 | .globl _start | 8 | .globl _start |
deps/lld/test/ELF/aarch64-thunk-pi.s+29-29| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t |
| 2 | // RUN: echo "SECTIONS { \ | 3 | // RUN: echo "SECTIONS { \ |
| 3 | // RUN: .text_low : { *(.text_low) } \ | 4 | // RUN: .text_low : { *(.text_low) } \ |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | // RUN: } " > %t.script | 6 | // RUN: } " > %t.script |
| 6 | // RUN: ld.lld --script %t.script --shared %t -o %t2 2>&1 | 7 | // RUN: ld.lld --script %t.script --shared %t -o %t2 2>&1 |
| 7 | // RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s | 8 | // RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s |
| 8 | // REQUIRES: aarch64 | ||
| 9 | 9 | ||
| 10 | // Check that Position Independent thunks are generated for shared libraries. | 10 | // Check that Position Independent thunks are generated for shared libraries. |
| 11 | .section .text_low, "ax", %progbits | 11 | .section .text_low, "ax", %progbits |
| ... | @@ -16,8 +16,8 @@ low_target: | ... | @@ -16,8 +16,8 @@ low_target: |
| 16 | bl high_target | 16 | bl high_target |
| 17 | ret | 17 | ret |
| 18 | // CHECK: low_target: | 18 | // CHECK: low_target: |
| 19 | // CHECK-NEXT: 0: 04 00 00 94 bl #16 | 19 | // CHECK-NEXT: 8: 04 00 00 94 bl #16 |
| 20 | // CHECK-NEXT: 4: c0 03 5f d6 ret | 20 | // CHECK-NEXT: c: c0 03 5f d6 ret |
| 21 | 21 | ||
| 22 | .hidden low_target2 | 22 | .hidden low_target2 |
| 23 | .globl low_target2 | 23 | .globl low_target2 |
| ... | @@ -27,19 +27,19 @@ low_target2: | ... | @@ -27,19 +27,19 @@ low_target2: |
| 27 | bl high_target2 | 27 | bl high_target2 |
| 28 | ret | 28 | ret |
| 29 | // CHECK: low_target2: | 29 | // CHECK: low_target2: |
| 30 | // CHECK-NEXT: 8: 05 00 00 94 bl #20 | 30 | // CHECK-NEXT: 0: 05 00 00 94 bl #20 |
| 31 | // CHECK-NEXT: c: c0 03 5f d6 ret | 31 | // CHECK-NEXT: 4: c0 03 5f d6 ret |
| 32 | 32 | ||
| 33 | // Expect range extension thunks for .text_low | 33 | // Expect range extension thunks for .text_low |
| 34 | // adrp calculation is (PC + signed immediate) & (!0xfff) | 34 | // adrp calculation is (PC + signed immediate) & (!0xfff) |
| 35 | // CHECK: __AArch64ADRPThunk_high_target: | 35 | // CHECK: __AArch64ADRPThunk_high_target: |
| 36 | // CHECK-NEXT: 10: 10 00 08 90 adrp x16, #268435456 | 36 | // CHECK-NEXT: e8: 10 00 08 90 adrp x16, #268435456 |
| 37 | // CHECK-NEXT: 14: 10 82 04 91 add x16, x16, #288 | 37 | // CHECK-NEXT: ec: 10 02 01 91 add x16, x16, #64 |
| 38 | // CHECK-NEXT: 18: 00 02 1f d6 br x16 | 38 | // CHECK-NEXT: f0: 00 02 1f d6 br x16 |
| 39 | // CHECK: __AArch64ADRPThunk_high_target2: | 39 | // CHECK: __AArch64ADRPThunk_high_target2: |
| 40 | // CHECK-NEXT: 1c: 10 00 08 90 adrp x16, #268435456 | 40 | // CHECK-NEXT: f4: 10 00 08 90 adrp x16, #268435456 |
| 41 | // CHECK-NEXT: 20: 10 22 00 91 add x16, x16, #8 | 41 | // CHECK-NEXT: f8: 10 22 00 91 add x16, x16, #8 |
| 42 | // CHECK-NEXT: 24: 00 02 1f d6 br x16 | 42 | // CHECK-NEXT: fc: 00 02 1f d6 br x16 |
| 43 | 43 | ||
| 44 | 44 | ||
| 45 | .section .text_high, "ax", %progbits | 45 | .section .text_high, "ax", %progbits |
| ... | @@ -50,7 +50,7 @@ high_target: | ... | @@ -50,7 +50,7 @@ high_target: |
| 50 | bl low_target | 50 | bl low_target |
| 51 | ret | 51 | ret |
| 52 | // CHECK: high_target: | 52 | // CHECK: high_target: |
| 53 | // CHECK-NEXT: 10000000: 4c 00 00 94 bl #304 | 53 | // CHECK-NEXT: 10000000: 14 00 00 94 bl #80 |
| 54 | // CHECK-NEXT: 10000004: c0 03 5f d6 ret | 54 | // CHECK-NEXT: 10000004: c0 03 5f d6 ret |
| 55 | 55 | ||
| 56 | .hidden high_target2 | 56 | .hidden high_target2 |
| ... | @@ -68,24 +68,24 @@ high_target2: | ... | @@ -68,24 +68,24 @@ high_target2: |
| 68 | 68 | ||
| 69 | // CHECK: __AArch64ADRPThunk_low_target2: | 69 | // CHECK: __AArch64ADRPThunk_low_target2: |
| 70 | // CHECK-NEXT: 10000010:	10 00 f8 90 	adrp	x16, #-268435456 | 70 | // CHECK-NEXT: 10000010:	10 00 f8 90 	adrp	x16, #-268435456 |
| 71 | // CHECK-NEXT: 10000014:	10 22 00 91 	add	x16, x16, #8 | 71 | // CHECK-NEXT: 10000014:	10 82 03 91 	add	x16, x16, #224 |
| 72 | // CHECK-NEXT: 10000018:	00 02 1f d6 	br	x16 | 72 | // CHECK-NEXT: 10000018:	00 02 1f d6 	br	x16 |
| 73 | 73 | ||
| 74 | // CHECK: Disassembly of section .plt: | 74 | // CHECK: Disassembly of section .plt: |
| 75 | // CHECK-NEXT: .plt: | 75 | // CHECK-NEXT: .plt: |
| 76 | // CHECK-NEXT: 10000100: f0 7b bf a9 stp x16, x30, [sp, #-16]! | 76 | // CHECK-NEXT: 10000020: f0 7b bf a9 stp x16, x30, [sp, #-16]! |
| 77 | // CHECK-NEXT: 10000104: 10 00 00 90 adrp x16, #0 | 77 | // CHECK-NEXT: 10000024: 10 00 00 90 adrp x16, #0 |
| 78 | // CHECK-NEXT: 10000108: 11 aa 40 f9 ldr x17, [x16, #336] | 78 | // CHECK-NEXT: 10000028: 11 3a 40 f9 ldr x17, [x16, #112] |
| 79 | // CHECK-NEXT: 1000010c: 10 42 05 91 add x16, x16, #336 | 79 | // CHECK-NEXT: 1000002c: 10 c2 01 91 add x16, x16, #112 |
| 80 | // CHECK-NEXT: 10000110: 20 02 1f d6 br x17 | 80 | // CHECK-NEXT: 10000030: 20 02 1f d6 br x17 |
| 81 | // CHECK-NEXT: 10000114: 1f 20 03 d5 nop | 81 | // CHECK-NEXT: 10000034: 1f 20 03 d5 nop |
| 82 | // CHECK-NEXT: 10000118: 1f 20 03 d5 nop | 82 | // CHECK-NEXT: 10000038: 1f 20 03 d5 nop |
| 83 | // CHECK-NEXT: 1000011c: 1f 20 03 d5 nop | 83 | // CHECK-NEXT: 1000003c: 1f 20 03 d5 nop |
| 84 | // CHECK-NEXT: 10000120: 10 00 00 90 adrp x16, #0 | 84 | // CHECK-NEXT: 10000040: 10 00 00 90 adrp x16, #0 |
| 85 | // CHECK-NEXT: 10000124: 11 ae 40 f9 ldr x17, [x16, #344] | 85 | // CHECK-NEXT: 10000044: 11 3e 40 f9 ldr x17, [x16, #120] |
| 86 | // CHECK-NEXT: 10000128: 10 62 05 91 add x16, x16, #344 | 86 | // CHECK-NEXT: 10000048: 10 e2 01 91 add x16, x16, #120 |
| 87 | // CHECK-NEXT: 1000012c: 20 02 1f d6 br x17 | 87 | // CHECK-NEXT: 1000004c: 20 02 1f d6 br x17 |
| 88 | // CHECK-NEXT: 10000130: 10 00 00 90 adrp x16, #0 | 88 | // CHECK-NEXT: 10000050: 10 00 00 90 adrp x16, #0 |
| 89 | // CHECK-NEXT: 10000134: 11 b2 40 f9 ldr x17, [x16, #352] | 89 | // CHECK-NEXT: 10000054: 11 42 40 f9 ldr x17, [x16, #128] |
| 90 | // CHECK-NEXT: 10000138: 10 82 05 91 add x16, x16, #352 | 90 | // CHECK-NEXT: 10000058: 10 02 02 91 add x16, x16, #128 |
| 91 | // CHECK-NEXT: 1000013c: 20 02 1f d6 br x17 | 91 | // CHECK-NEXT: 1000005c: 20 02 1f d6 br x17 |
deps/lld/test/ELF/aarch64-thunk-script.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t |
| 2 | // RUN: echo "SECTIONS { \ | 3 | // RUN: echo "SECTIONS { \ |
| 3 | // RUN: .text_low 0x2000: { *(.text_low) } \ | 4 | // RUN: .text_low 0x2000: { *(.text_low) } \ |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | // RUN: } " > %t.script | 6 | // RUN: } " > %t.script |
| 6 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | 7 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 |
| 7 | // RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s | 8 | // RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s |
| 8 | // REQUIRES: aarch64 | ||
| 9 | 9 | ||
| 10 | // Check that we have the out of branch range calculation right. The immediate | 10 | // Check that we have the out of branch range calculation right. The immediate |
| 11 | // field is signed so we have a slightly higher negative displacement. | 11 | // field is signed so we have a slightly higher negative displacement. |
deps/lld/test/ELF/aarch64-thunk-section-location.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-objdump -d -start-address=134086664 -stop-address=134086676 -triple=aarch64-linux-gnu %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -d -start-address=134086664 -stop-address=134086676 -triple=aarch64-linux-gnu %t2 | FileCheck %s |
| 4 | // REQUIRES: aarch64 | ||
| 5 | // Check that the range extension thunks are dumped close to the aarch64 branch | 5 | // Check that the range extension thunks are dumped close to the aarch64 branch |
| 6 | // range of 128 MiB | 6 | // range of 128 MiB |
| 7 | .section .text.1, "ax", %progbits | 7 | .section .text.1, "ax", %progbits |
deps/lld/test/ELF/aarch64-tls-gdle.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | # REQUIRES: aarch64 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o |
| 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o |
| 3 | # RUN: ld.lld %tmain.o %ttlsie.o -o %tout | 4 | # RUN: ld.lld %tmain.o %ttlsie.o -o %tout |
| 4 | # RUN: llvm-objdump -d %tout | FileCheck %s | 5 | # RUN: llvm-objdump -d %tout | FileCheck %s |
| 5 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s | 6 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s |
| 6 | # REQUIRES: aarch64 | ||
| 7 | 7 | ||
| 8 | #Local-Dynamic to Initial-Exec relax creates no | 8 | #Local-Dynamic to Initial-Exec relax creates no |
| 9 | #RELOC: Relocations [ | 9 | #RELOC: Relocations [ |
deps/lld/test/ELF/aarch64-tls-ie.s+1-1| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | // REQUIRES: aarch64 | 1 | // REQUIRES: aarch64 |
| 2 | # REQUIRES: aarch64 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tls-ie.s -o %tdso.o | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tls-ie.s -o %tdso.o |
| 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o | 4 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o |
| 4 | # RUN: ld.lld -shared %tdso.o -o %tdso.so | 5 | # RUN: ld.lld -shared %tdso.o -o %tdso.so |
| 5 | # RUN: ld.lld --hash-style=sysv %tmain.o %tdso.so -o %tout | 6 | # RUN: ld.lld --hash-style=sysv %tmain.o %tdso.so -o %tout |
| 6 | # RUN: llvm-objdump -d %tout | FileCheck %s | 7 | # RUN: llvm-objdump -d %tout | FileCheck %s |
| 7 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s | 8 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s |
| 8 | # REQUIRES: aarch64 | ||
| 9 | 9 | ||
| 10 | #RELOC: Section { | 10 | #RELOC: Section { |
| 11 | #RELOC: Index: | 11 | #RELOC: Index: |
deps/lld/test/ELF/aarch64-tls-iele.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | # REQUIRES: aarch64 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o |
| 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o |
| 3 | # RUN: ld.lld %tmain.o %ttlsie.o -o %tout | 4 | # RUN: ld.lld %tmain.o %ttlsie.o -o %tout |
| 4 | # RUN: llvm-objdump -d %tout | FileCheck %s | 5 | # RUN: llvm-objdump -d %tout | FileCheck %s |
| 5 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s | 6 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s |
| 6 | # REQUIRES: aarch64 | ||
| 7 | 7 | ||
| 8 | # Initial-Exec to Local-Exec relax creates no dynamic relocations. | 8 | # Initial-Exec to Local-Exec relax creates no dynamic relocations. |
| 9 | # RELOC: Relocations [ | 9 | # RELOC: Relocations [ |
deps/lld/test/ELF/aarch64-tls-le.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # REQUIRES: aarch64 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o |
| 2 | # RUN: ld.lld %tmain.o -o %tout | 3 | # RUN: ld.lld %tmain.o -o %tout |
| 3 | # RUN: llvm-objdump -d %tout | FileCheck %s | 4 | # RUN: llvm-objdump -d %tout | FileCheck %s |
| 4 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s | 5 | # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s |
| 5 | # REQUIRES: aarch64 | ||
| 6 | 6 | ||
| 7 | #Local-Dynamic to Initial-Exec relax creates no | 7 | #Local-Dynamic to Initial-Exec relax creates no |
| 8 | #RELOC: Relocations [ | 8 | #RELOC: Relocations [ |
deps/lld/test/ELF/aarch64-tlsld-ldst.s created+85| ... | @@ -0,0 +1,85 @@ | ||
| 1 | // REQUIRES: aarch64 | ||
| 2 | // RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj %s -o %t.o | ||
| 3 | // RUN: ld.lld %t.o -o %t | ||
| 4 | // RUN: llvm-objdump -d %t | FileCheck %s | ||
| 5 | // RUN: llvm-readelf --symbols %t | FileCheck -check-prefix CHECK-SYMS %s | ||
| 6 | |||
| 7 | .text | ||
| 8 | .globl _start | ||
| 9 | .type _start, %function | ||
| 10 | _start: mrs x8, TPIDR_EL0 | ||
| 11 | |||
| 12 | add x8, x8, :tprel_hi12:var0 | ||
| 13 | ldr q20, [x8, :tprel_lo12_nc:var0] | ||
| 14 | |||
| 15 | add x8, x8, :tprel_hi12:var1 | ||
| 16 | ldr x0, [x8, :tprel_lo12_nc:var1] | ||
| 17 | |||
| 18 | add x8, x8, :tprel_hi12:var2 | ||
| 19 | ldr w0, [x8, :tprel_lo12_nc:var2] | ||
| 20 | |||
| 21 | add x8, x8, :tprel_hi12:var3 | ||
| 22 | ldrh w0, [x8, :tprel_lo12_nc:var3] | ||
| 23 | |||
| 24 | add x8, x8, :tprel_hi12:var4 | ||
| 25 | ldrb w0, [x8, :tprel_lo12_nc:var4] | ||
| 26 | |||
| 27 | // CHECK: _start: | ||
| 28 | // CHECK-NEXT: 20000: 48 d0 3b d5 mrs x8, TPIDR_EL0 | ||
| 29 | // 0x0 + c10 = 0xc10 = tcb (16-bytes) + var0 | ||
| 30 | // CHECK-NEXT: 20004: 08 01 40 91 add x8, x8, #0, lsl #12 | ||
| 31 | // CHECK-NEXT: 20008: 14 05 c3 3d ldr q20, [x8, #3088] | ||
| 32 | // 0x1000 + 0x820 = 0x1820 = tcb + var1 | ||
| 33 | // CHECK-NEXT: 2000c: 08 05 40 91 add x8, x8, #1, lsl #12 | ||
| 34 | // CHECK-NEXT: 20010: 00 11 44 f9 ldr x0, [x8, #2080] | ||
| 35 | // 0x2000 + 0x428 = 0x2428 = tcb + var2 | ||
| 36 | // CHECK-NEXT: 20014: 08 09 40 91 add x8, x8, #2, lsl #12 | ||
| 37 | // CHECK-NEXT: 20018: 00 29 44 b9 ldr w0, [x8, #1064] | ||
| 38 | // 0x3000 + 0x2c = 0x302c = tcb + var3 | ||
| 39 | // CHECK-NEXT: 2001c: 08 0d 40 91 add x8, x8, #3, lsl #12 | ||
| 40 | // CHECK-NEXT: 20020: 00 59 40 79 ldrh w0, [x8, #44] | ||
| 41 | // 0x3000 + 0xc2e = 0x32ce = tcb + var4 | ||
| 42 | // CHECK-NEXT: 20024: 08 0d 40 91 add x8, x8, #3, lsl #12 | ||
| 43 | // CHECK-NEXT: 20028: 00 b9 70 39 ldrb w0, [x8, #3118] | ||
| 44 | |||
| 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 | ||
| 50 | |||
| 51 | .globl var0 | ||
| 52 | .globl var1 | ||
| 53 | .globl var2 | ||
| 54 | .globl var3 | ||
| 55 | .globl var4 | ||
| 56 | .type var0,@object | ||
| 57 | .type var1,@object | ||
| 58 | .type var2,@object | ||
| 59 | .type var3,@object | ||
| 60 | |||
| 61 | .section .tbss,"awT",@nobits | ||
| 62 | .balign 16 | ||
| 63 | .space 1024 * 3 | ||
| 64 | var0: | ||
| 65 | .quad 0 | ||
| 66 | .quad 0 | ||
| 67 | .size var1, 16 | ||
| 68 | .space 1024 * 3 | ||
| 69 | var1: | ||
| 70 | .quad 0 | ||
| 71 | .size var1, 8 | ||
| 72 | .space 1024 * 3 | ||
| 73 | var2: | ||
| 74 | .word 0 | ||
| 75 | .size var1, 4 | ||
| 76 | |||
| 77 | .space 1024 * 3 | ||
| 78 | var3: | ||
| 79 | .hword 0 | ||
| 80 | .size var2, 2 | ||
| 81 | .space 1024 * 3 | ||
| 82 | var4: | ||
| 83 | .byte 0 | ||
| 84 | .size var3, 1 | ||
| 85 | .space 1024 * 3 | ||
deps/lld/test/ELF/aarch64-tstbr14-reloc.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: aarch64 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tstbr14-reloc.s -o %t1 | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tstbr14-reloc.s -o %t1 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t2 | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t2 |
| 3 | # RUN: ld.lld %t1 %t2 -o %t | 4 | # RUN: ld.lld %t1 %t2 -o %t |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | # RUN: ld.lld -shared %t1 %t2 -o %t3 | 6 | # RUN: ld.lld -shared %t1 %t2 -o %t3 |
| 6 | # RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=DSO %s | 7 | # RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=DSO %s |
| 7 | # RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s | 8 | # RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s |
| 8 | # REQUIRES: aarch64 | ||
| 9 | 9 | ||
| 10 | # 0x1101c - 28 = 0x20000 | 10 | # 0x1101c - 28 = 0x20000 |
| 11 | # 0x11020 - 16 = 0x20010 | 11 | # 0x11020 - 16 = 0x20010 |
deps/lld/test/ELF/aarch64-undefined-weak.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-objdump -triple=aarch64-none-linux -d %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -triple=aarch64-none-linux -d %t2 | FileCheck %s |
| 4 | // REQUIRES: aarch64 | ||
| 5 | 5 | ||
| 6 | // Check that the ARM 64-bit ABI rules for undefined weak symbols are applied. | 6 | // Check that the ARM 64-bit ABI rules for undefined weak symbols are applied. |
| 7 | // Branch instructions are resolved to the next instruction. Undefined | 7 | // Branch instructions are resolved to the next instruction. Undefined |
deps/lld/test/ELF/abs-conflict.s+1-1| ... | @@ -15,4 +15,4 @@ foo = 0x123 | ... | @@ -15,4 +15,4 @@ foo = 0x123 |
| 15 | 15 | ||
| 16 | // DUP: duplicate symbol: foo | 16 | // DUP: duplicate symbol: foo |
| 17 | // DUP-NEXT: >>> defined in {{.*}}.o | 17 | // DUP-NEXT: >>> defined in {{.*}}.o |
| 18 | // DUP-NEXT: >>> defined in <internal> | 18 | // DUP-NEXT: >>> defined in {{.*}}2.o |
deps/lld/test/ELF/allow-multiple-definition.s+5-4| ... | @@ -3,13 +3,14 @@ | ... | @@ -3,13 +3,14 @@ |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/allow-multiple-definition.s -o %t2 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/allow-multiple-definition.s -o %t2 |
| 5 | # RUN: not ld.lld %t1 %t2 -o %t3 | 5 | # RUN: not ld.lld %t1 %t2 -o %t3 |
| 6 | # RUN: ld.lld --allow-multiple-definition %t1 %t2 -o %t3 | 6 | # RUN: not ld.lld --allow-multiple-definition --no-allow-multiple-definition %t1 %t2 -o %t3 |
| 7 | # RUN: ld.lld --allow-multiple-definition %t2 %t1 -o %t4 | 7 | # RUN: ld.lld --allow-multiple-definition --fatal-warnings %t1 %t2 -o %t3 |
| 8 | # RUN: ld.lld --allow-multiple-definition --fatal-warnings %t2 %t1 -o %t4 | ||
| 8 | # RUN: llvm-objdump -d %t3 | FileCheck %s | 9 | # RUN: llvm-objdump -d %t3 | FileCheck %s |
| 9 | # RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s | 10 | # RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s |
| 10 | 11 | ||
| 11 | # RUN: ld.lld -z muldefs %t1 %t2 -o %t3 | 12 | # RUN: ld.lld -z muldefs --fatal-warnings %t1 %t2 -o %t3 |
| 12 | # RUN: ld.lld -z muldefs %t2 %t1 -o %t4 | 13 | # RUN: ld.lld -z muldefs --fatal-warnings %t2 %t1 -o %t4 |
| 13 | # RUN: llvm-objdump -d %t3 | FileCheck %s | 14 | # RUN: llvm-objdump -d %t3 | FileCheck %s |
| 14 | # RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s | 15 | # RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s |
| 15 | 16 |
deps/lld/test/ELF/amdgpu-elf-flags-err.s+4-5| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | # RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o | ||
| 2 | # RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o | ||
| 3 | # RUN: not ld.lld -shared %t-0.o %t-1.o %S/Inputs/amdgpu-kernel-2.o -o %t.so 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | # REQUIRES: amdgpu | 1 | # REQUIRES: amdgpu |
| 2 | # RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx802 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o | ||
| 3 | # RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o | ||
| 4 | # RUN: not ld.lld -shared %t-0.o %t-1.o -o /dev/null 2>&1 | FileCheck %s | ||
| 6 | 5 | ||
| 7 | # CHECK: error: incompatible e_flags: {{.*}}amdgpu-kernel-2.o | 6 | # CHECK: error: incompatible e_flags: {{.*}}-1.o |
deps/lld/test/ELF/amdgpu-elf-flags.s+3-4| ... | @@ -1,10 +1,9 @@ | ... | @@ -1,10 +1,9 @@ |
| 1 | # REQUIRES: amdgpu | ||
| 1 | # RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o | 2 | # RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o |
| 2 | # RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o | 3 | # RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o |
| 3 | # RUN: ld.lld -shared %t-0.o %t-1.o -o %t.so | 4 | # RUN: ld.lld -shared %t-0.o %t-1.o -o %t.so |
| 4 | # RUN: llvm-readobj -file-headers %t.so | FileCheck %s | 5 | # RUN: llvm-readobj -file-headers %t.so | FileCheck %s |
| 5 | 6 | ||
| 6 | # REQUIRES: amdgpu | 7 | # CHECK: Flags [ |
| 7 | 8 | # CHECK: EF_AMDGPU_MACH_AMDGCN_GFX803 (0x2A) | |
| 8 | # CHECK: Flags [ (0x2) | ||
| 9 | # CHECK: EF_AMDGPU_ARCH_GCN (0x2) | ||
| 10 | # CHECK: ] | 9 | # CHECK: ] |
deps/lld/test/ELF/amdgpu-globals.s+1-2| ... | @@ -1,9 +1,8 @@ | ... | @@ -1,9 +1,8 @@ |
| 1 | # REQUIRES: amdgpu | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o |
| 2 | # RUN: ld.lld -shared %t.o -o %t | 3 | # RUN: ld.lld -shared %t.o -o %t |
| 3 | # RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s | 4 | # RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s |
| 4 | 5 | ||
| 5 | # REQUIRES: amdgpu | ||
| 6 | |||
| 7 | .type glob0, @object | 6 | .type glob0, @object |
| 8 | .data | 7 | .data |
| 9 | .globl glob0 | 8 | .globl glob0 |
deps/lld/test/ELF/amdgpu-kernels.s+1-2| ... | @@ -1,9 +1,8 @@ | ... | @@ -1,9 +1,8 @@ |
| 1 | # REQUIRES: amdgpu | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o |
| 2 | # RUN: ld.lld -shared %t.o -o %t | 3 | # RUN: ld.lld -shared %t.o -o %t |
| 3 | # RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s | 4 | # RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s |
| 4 | 5 | ||
| 5 | # REQUIRES: amdgpu | ||
| 6 | |||
| 7 | .hsa_code_object_version 1,0 | 6 | .hsa_code_object_version 1,0 |
| 8 | .hsa_code_object_isa 7,0,0,"AMD","AMDGPU" | 7 | .hsa_code_object_isa 7,0,0,"AMD","AMDGPU" |
| 9 | 8 |
deps/lld/test/ELF/amdgpu-relocs.s+13-2| ... | @@ -1,10 +1,9 @@ | ... | @@ -1,10 +1,9 @@ |
| 1 | # REQUIRES: amdgpu | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=amdgcn--amdhsa -mcpu=fiji %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=amdgcn--amdhsa -mcpu=fiji %s -o %t.o |
| 2 | # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so | 3 | # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so |
| 3 | # RUN: llvm-readobj -r %t.so | FileCheck %s | 4 | # RUN: llvm-readobj -r %t.so | FileCheck %s |
| 4 | # RUN: llvm-objdump -s %t.so | FileCheck %s --check-prefix=OBJDUMP | 5 | # RUN: llvm-objdump -s %t.so | FileCheck %s --check-prefix=OBJDUMP |
| 5 | 6 | ||
| 6 | # REQUIRES: amdgpu | ||
| 7 | |||
| 8 | .text | 7 | .text |
| 9 | 8 | ||
| 10 | kernel0: | 9 | kernel0: |
| ... | @@ -77,6 +76,15 @@ ptr: | ... | @@ -77,6 +76,15 @@ ptr: |
| 77 | ptr2: | 76 | ptr2: |
| 78 | .quad temp2 | 77 | .quad temp2 |
| 79 | 78 | ||
| 79 | # R_AMDGPU_REL64: | ||
| 80 | .type foo, @object | ||
| 81 | .rodata | ||
| 82 | .globl foo | ||
| 83 | .p2align 3 | ||
| 84 | foo: | ||
| 85 | .quad temp2@rel64 | ||
| 86 | .size foo, 8 | ||
| 87 | |||
| 80 | # The relocation for local_var{0, 1, 2} and var should be resolved by the | 88 | # The relocation for local_var{0, 1, 2} and var should be resolved by the |
| 81 | # linker. | 89 | # linker. |
| 82 | # CHECK: Relocations [ | 90 | # CHECK: Relocations [ |
| ... | @@ -101,6 +109,9 @@ ptr2: | ... | @@ -101,6 +109,9 @@ ptr2: |
| 101 | # CHECK-NEXT: } | 109 | # CHECK-NEXT: } |
| 102 | # CHECK-NEXT: ] | 110 | # CHECK-NEXT: ] |
| 103 | 111 | ||
| 112 | # OBJDUMP: Contents of section .rodata: | ||
| 113 | # OBJDUMP: d0f8ffff ffffffff | ||
| 114 | |||
| 104 | # OBJDUMP: Contents of section nonalloc: | 115 | # OBJDUMP: Contents of section nonalloc: |
| 105 | # OBJDUMP-NEXT: 0000 00000000 04480000 00000000 08440000 | 116 | # OBJDUMP-NEXT: 0000 00000000 04480000 00000000 08440000 |
| 106 | # OBJDUMP-NEXT: 00000000 0c400000 | 117 | # OBJDUMP-NEXT: 00000000 0c400000 |
deps/lld/test/ELF/archive.s+15-10| ... | @@ -1,16 +1,21 @@ | ... | @@ -1,16 +1,21 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive.s -o %t2 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive.s -o %t2 |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive2.s -o %t3 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive2.s -o %t3 |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive3.s -o %t4 | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive3.s -o %t4 |
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive4.s -o %t5 | 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive4.s -o %t5 |
| 6 | # RUN: llvm-ar rcs %tar %t2 %t3 %t4 | 7 | |
| 7 | # RUN: ld.lld %t %tar %t5 -o %tout | 8 | # RUN: rm -f %t.a |
| 8 | # RUN: llvm-nm %tout | FileCheck %s | 9 | # RUN: llvm-ar rcs %t.a %t2 %t3 %t4 |
| 9 | # RUN: rm -f %tarthin | 10 | |
| 10 | # RUN: llvm-ar --format=gnu rcsT %tarthin %t2 %t3 %t4 | 11 | # RUN: ld.lld %t %t.a %t5 -o %t.out |
| 11 | # RUN: ld.lld %t %tarthin %t5 -o %tout | 12 | # RUN: llvm-nm %t.out | FileCheck %s |
| 12 | # RUN: llvm-nm %tout | FileCheck %s | 13 | |
| 13 | # REQUIRES: x86 | 14 | # RUN: rm -f %t.thin |
| 15 | # RUN: llvm-ar --format=gnu rcsT %t.thin %t2 %t3 %t4 | ||
| 16 | |||
| 17 | # RUN: ld.lld %t %t.thin %t5 -o %t.out | ||
| 18 | # RUN: llvm-nm %t.out | FileCheck %s | ||
| 14 | 19 | ||
| 15 | # Nothing here. Just needed for the linker to create a undefined _start symbol. | 20 | # Nothing here. Just needed for the linker to create a undefined _start symbol. |
| 16 | 21 | ||
| ... | @@ -31,8 +36,8 @@ | ... | @@ -31,8 +36,8 @@ |
| 31 | 36 | ||
| 32 | # Test that the hitting the first object file after having a lazy symbol for | 37 | # Test that the hitting the first object file after having a lazy symbol for |
| 33 | # _start is handled correctly. | 38 | # _start is handled correctly. |
| 34 | # RUN: ld.lld %tar %t -o %tout | 39 | # RUN: ld.lld %t.a %t -o %t.out |
| 35 | # RUN: llvm-nm %tout | FileCheck --check-prefix=AR-FIRST %s | 40 | # RUN: llvm-nm %t.out | FileCheck --check-prefix=AR-FIRST %s |
| 36 | 41 | ||
| 37 | # AR-FIRST: T _start | 42 | # AR-FIRST: T _start |
| 38 | # AR-FIRST-NEXT: w bar | 43 | # AR-FIRST-NEXT: w bar |
deps/lld/test/ELF/arm-attributes.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-attributes1.s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-attributes1.s -o %t1.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2.o |
| 3 | 4 | ||
| ... | @@ -7,7 +8,6 @@ | ... | @@ -7,7 +8,6 @@ |
| 7 | // RUN: llvm-readobj -arm-attributes %t2 | FileCheck %s | 8 | // RUN: llvm-readobj -arm-attributes %t2 | FileCheck %s |
| 8 | // RUN: ld.lld %t1.o %t2.o -r -o %t3 | 9 | // RUN: ld.lld %t1.o %t2.o -r -o %t3 |
| 9 | // RUN: llvm-readobj -arm-attributes %t3 | FileCheck %s | 10 | // RUN: llvm-readobj -arm-attributes %t3 | FileCheck %s |
| 10 | // REQUIRES: arm | ||
| 11 | 11 | ||
| 12 | // Check that we retain only 1 SHT_ARM_ATTRIBUTES section. At present we do not | 12 | // Check that we retain only 1 SHT_ARM_ATTRIBUTES section. At present we do not |
| 13 | // try and merge or use the contents of SHT_ARM_ATTRIBUTES sections. We just | 13 | // try and merge or use the contents of SHT_ARM_ATTRIBUTES sections. We just |
deps/lld/test/ELF/arm-bl-v6.s+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t | ||
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | FileCheck %s | ||
| 3 | // REQUIRES: arm | 1 | // REQUIRES: arm |
| 2 | // RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t | ||
| 3 | // RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | 4 | ||
| 5 | // On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the | 5 | // On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the |
| 6 | // extended range encoding is not supported. The following example has a Thumb | 6 | // extended range encoding is not supported. The following example has a Thumb |
deps/lld/test/ELF/arm-blx-v4t.s+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t | ||
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | FileCheck %s | ||
| 3 | // REQUIRES: arm | 1 | // REQUIRES: arm |
| 2 | // RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t | ||
| 3 | // RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | 4 | ||
| 5 | // On Arm v4t there is no blx instruction so all interworking must go via | 5 | // On Arm v4t there is no blx instruction so all interworking must go via |
| 6 | // a thunk. At present we don't support v4t so we give a warning for unsupported | 6 | // a thunk. At present we don't support v4t so we give a warning for unsupported |
deps/lld/test/ELF/arm-blx.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar |
| 3 | // RUN: echo "SECTIONS { \ | 4 | // RUN: echo "SECTIONS { \ |
| ... | @@ -10,7 +11,6 @@ | ... | @@ -10,7 +11,6 @@ |
| 10 | // RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 | 11 | // RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 |
| 11 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s | 12 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s |
| 12 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s | 13 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s |
| 13 | // REQUIRES: arm | ||
| 14 | 14 | ||
| 15 | // Test BLX instruction is chosen for ARM BL/BLX instruction and Thumb callee | 15 | // Test BLX instruction is chosen for ARM BL/BLX instruction and Thumb callee |
| 16 | // Using two callees to ensure at least one has 2-byte alignment. | 16 | // Using two callees to ensure at least one has 2-byte alignment. |
deps/lld/test/ELF/arm-branch-rangethunk.s+34-19| ... | @@ -1,8 +1,11 @@ | ... | @@ -1,8 +1,11 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar |
| 3 | // RUN: ld.lld %t %tfar -o %t2 2>&1 | 4 | // RUN: ld.lld %t %tfar -o %t2 2>&1 |
| 4 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s | 5 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck --check-prefix=SHORT %s |
| 5 | // REQUIRES: arm | 6 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong |
| 7 | // RUN: ld.lld %t %tfarlong -o %t3 2>&1 | ||
| 8 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=LONG %s | ||
| 6 | .syntax unified | 9 | .syntax unified |
| 7 | .section .text, "ax",%progbits | 10 | .section .text, "ax",%progbits |
| 8 | .globl _start | 11 | .globl _start |
| ... | @@ -15,20 +18,32 @@ _start: | ... | @@ -15,20 +18,32 @@ _start: |
| 15 | b too_far2 | 18 | b too_far2 |
| 16 | beq too_far3 | 19 | beq too_far3 |
| 17 | 20 | ||
| 18 | // CHECK: Disassembly of section .text: | 21 | // SHORT: Disassembly of section .text: |
| 19 | // CHECK-NEXT: _start: | 22 | // SHORT-NEXT: _start: |
| 20 | // CHECK-NEXT: 20000: 01 00 00 eb bl #4 <__ARMv7ABSLongThunk_too_far1> | 23 | // SHORT-NEXT: 20000: 01 00 00 eb bl #4 <__ARMv7ABSLongThunk_too_far1> |
| 21 | // CHECK-NEXT: 20004: 03 00 00 ea b #12 <__ARMv7ABSLongThunk_too_far2> | 24 | // SHORT-NEXT: 20004: 01 00 00 ea b #4 <__ARMv7ABSLongThunk_too_far2> |
| 22 | // CHECK-NEXT: 20008: 05 00 00 0a beq #20 <__ARMv7ABSLongThunk_too_far3> | 25 | // SHORT-NEXT: 20008: 01 00 00 0a beq #4 <__ARMv7ABSLongThunk_too_far3> |
| 23 | // CHECK: __ARMv7ABSLongThunk_too_far1: | 26 | // SHORT: __ARMv7ABSLongThunk_too_far1: |
| 24 | // CHECK-NEXT: 2000c: 08 c0 00 e3 movw r12, #8 | 27 | // SHORT-NEXT: 2000c: fd ff 7f ea b #33554420 <__ARMv7ABSLongThunk_too_far3+0x1fffff4> |
| 25 | // CHECK-NEXT: 20010: 02 c2 40 e3 movt r12, #514 | 28 | // SHORT: __ARMv7ABSLongThunk_too_far2: |
| 26 | // CHECK-NEXT: 20014: 1c ff 2f e1 bx r12 | 29 | // SHORT-NEXT: 20010: fd ff 7f ea b #33554420 <__ARMv7ABSLongThunk_too_far3+0x1fffff8> |
| 27 | // CHECK: __ARMv7ABSLongThunk_too_far2: | 30 | // SHORT: __ARMv7ABSLongThunk_too_far3: |
| 28 | // CHECK-NEXT: 20018: 0c c0 00 e3 movw r12, #12 | 31 | // SHORT-NEXT: 20014: fd ff 7f ea b #33554420 <__ARMv7ABSLongThunk_too_far3+0x1fffffc> |
| 29 | // CHECK-NEXT: 2001c: 02 c2 40 e3 movt r12, #514 | 32 | |
| 30 | // CHECK-NEXT: 20020: 1c ff 2f e1 bx r12 | 33 | // LONG: Disassembly of section .text: |
| 31 | // CHECK: __ARMv7ABSLongThunk_too_far3: | 34 | // LONG-NEXT: _start: |
| 32 | // CHECK-NEXT: 20024: 10 c0 00 e3 movw r12, #16 | 35 | // LONG-NEXT: 20000: 01 00 00 eb bl #4 <__ARMv7ABSLongThunk_too_far1> |
| 33 | // CHECK-NEXT: 20028: 02 c2 40 e3 movt r12, #514 | 36 | // LONG-NEXT: 20004: 03 00 00 ea b #12 <__ARMv7ABSLongThunk_too_far2> |
| 34 | // CHECK-NEXT: 2002c: 1c ff 2f e1 bx r12 | 37 | // LONG-NEXT: 20008: 05 00 00 0a beq #20 <__ARMv7ABSLongThunk_too_far3> |
| 38 | // LONG: __ARMv7ABSLongThunk_too_far1: | ||
| 39 | // LONG-NEXT: 2000c: 14 c0 00 e3 movw r12, #20 | ||
| 40 | // LONG-NEXT: 20010: 02 c2 40 e3 movt r12, #514 | ||
| 41 | // LONG-NEXT: 20014: 1c ff 2f e1 bx r12 | ||
| 42 | // LONG: __ARMv7ABSLongThunk_too_far2: | ||
| 43 | // LONG-NEXT: 20018: 20 c0 00 e3 movw r12, #32 | ||
| 44 | // LONG-NEXT: 2001c: 02 c2 40 e3 movt r12, #514 | ||
| 45 | // LONG-NEXT: 20020: 1c ff 2f e1 bx r12 | ||
| 46 | // LONG: __ARMv7ABSLongThunk_too_far3: | ||
| 47 | // LONG-NEXT: 20024: 2c c0 00 e3 movw r12, #44 | ||
| 48 | // LONG-NEXT: 20028: 02 c2 40 e3 movt r12, #514 | ||
| 49 | // LONG-NEXT: 2002c: 1c ff 2f e1 bx r12 |
deps/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t |
| 2 | // RUN: ld.lld %t --shared -o %t.so | 3 | // RUN: ld.lld %t --shared -o %t.so |
| 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 | 4 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 |
| 4 | // RUN: ld.lld %t2 %t.so -o %t3 | 5 | // RUN: ld.lld %t2 %t.so -o %t3 |
| 5 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi -start-address=69632 -stop-address=69664 %t3 | FileCheck %s | 6 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi -start-address=69632 -stop-address=69664 %t3 | FileCheck %s |
| 6 | // REQUIRES: arm | ||
| 7 | 7 | ||
| 8 | // When we are dynamic linking, undefined weak references have a PLT entry so | 8 | // When we are dynamic linking, undefined weak references have a PLT entry so |
| 9 | // we must create a thunk for the branch to the PLT entry. | 9 | // we must create a thunk for the branch to the PLT entry. |
deps/lld/test/ELF/arm-branch.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar |
| 3 | // RUN: echo "SECTIONS { \ | 4 | // RUN: echo "SECTIONS { \ |
| ... | @@ -7,7 +8,6 @@ | ... | @@ -7,7 +8,6 @@ |
| 7 | // RUN: .callee2 : { *(.callee_high) } } " > %t.script | 8 | // RUN: .callee2 : { *(.callee_high) } } " > %t.script |
| 8 | // RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 | 9 | // RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 |
| 9 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s | 10 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 10 | // REQUIRES: arm | ||
| 11 | .syntax unified | 11 | .syntax unified |
| 12 | .section .callee_low, "ax",%progbits | 12 | .section .callee_low, "ax",%progbits |
| 13 | .align 2 | 13 | .align 2 |
deps/lld/test/ELF/arm-copy.s+3-3| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | 1 | // REQUIRES: arm |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/relocation-copy-arm.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/relocation-copy-arm.s -o %t2.o |
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -soname fixed-length-string.so -o %t2.so |
| 5 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t3 | 5 | // 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 |
| 7 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CODE %s | 7 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CODE %s |
| ... | @@ -33,7 +33,7 @@ _start: | ... | @@ -33,7 +33,7 @@ _start: |
| 33 | // CHECK-NEXT: AddressAlignment: 16 | 33 | // CHECK-NEXT: AddressAlignment: 16 |
| 34 | 34 | ||
| 35 | // CHECK: Relocations [ | 35 | // CHECK: Relocations [ |
| 36 | // CHECK-NEXT: Section (5) .rel.dyn { | 36 | // CHECK-NEXT: Section {{.*}} .rel.dyn { |
| 37 | // CHECK-NEXT: Relocation { | 37 | // CHECK-NEXT: Relocation { |
| 38 | // CHECK-NEXT: Offset: 0x13000 | 38 | // CHECK-NEXT: Offset: 0x13000 |
| 39 | // CHECK-NEXT: Type: R_ARM_COPY | 39 | // CHECK-NEXT: Type: R_ARM_COPY |
| ... | @@ -78,4 +78,4 @@ _start: | ... | @@ -78,4 +78,4 @@ _start: |
| 78 | 78 | ||
| 79 | // RODATA: Contents of section .rodata: | 79 | // RODATA: Contents of section .rodata: |
| 80 | // S(z) = 0x13004 | 80 | // S(z) = 0x13004 |
| 81 | // RODATA-NEXT: 10114 04300100 | 81 | // RODATA-NEXT: 10190 04300100 |
deps/lld/test/ELF/arm-data-prel.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // 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 -o %t.o |
| 2 | // RUN: echo "SECTIONS { \ | 3 | // RUN: echo "SECTIONS { \ |
| 3 | // RUN: .text : { *(.text) } \ | 4 | // RUN: .text : { *(.text) } \ |
| ... | @@ -6,7 +7,6 @@ | ... | @@ -6,7 +7,6 @@ |
| 6 | // RUN: .TEST1 : { *(.TEST1) } } " > %t.script | 7 | // RUN: .TEST1 : { *(.TEST1) } } " > %t.script |
| 7 | // RUN: ld.lld --script %t.script %t.o -o %t | 8 | // RUN: ld.lld --script %t.script %t.o -o %t |
| 8 | // RUN: llvm-readobj -s -sd %t | FileCheck --check-prefix=CHECK %s | 9 | // RUN: llvm-readobj -s -sd %t | FileCheck --check-prefix=CHECK %s |
| 9 | // REQUIRES: arm | ||
| 10 | 10 | ||
| 11 | // The R_ARM_PREL31 relocation is used in by the .ARM.exidx exception tables | 11 | // The R_ARM_PREL31 relocation is used in by the .ARM.exidx exception tables |
| 12 | // bit31 of the place denotes whether the field is an inline table entry | 12 | // bit31 of the place denotes whether the field is an inline table entry |
deps/lld/test/ELF/arm-data-relocs.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/abs256.s -o %t256.o | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/abs256.s -o %t256.o |
| 3 | // RUN: ld.lld %t %t256.o -o %t2 | 4 | // RUN: ld.lld %t %t256.o -o %t2 |
| 4 | // RUN: llvm-objdump -d %t2 | FileCheck %s | 5 | // RUN: llvm-objdump -d %t2 | FileCheck %s |
| 5 | // REQUIRES: arm | ||
| 6 | .syntax unified | 6 | .syntax unified |
| 7 | .globl _start | 7 | .globl _start |
| 8 | _start: | 8 | _start: |
deps/lld/test/ELF/arm-eabi-version.s+2-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-readobj -file-headers %tout | FileCheck %s | 4 | // RUN: llvm-readobj -file-headers %tout | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | .syntax unified | 5 | .syntax unified |
| 6 | .text | 6 | .text |
| 7 | .globl _start | 7 | .globl _start |
| ... | @@ -9,6 +9,7 @@ _start: | ... | @@ -9,6 +9,7 @@ _start: |
| 9 | bx lr | 9 | bx lr |
| 10 | 10 | ||
| 11 | // CHECK: Flags [ | 11 | // CHECK: Flags [ |
| 12 | // CHECK-NEXT: 0x200 | ||
| 12 | // CHECK-NEXT: 0x1000000 | 13 | // CHECK-NEXT: 0x1000000 |
| 13 | // CHECK-NEXT: 0x4000000 | 14 | // CHECK-NEXT: 0x4000000 |
| 14 | // CHECK-NEXT: ] | 15 | // CHECK-NEXT: ] |
deps/lld/test/ELF/arm-execute-only.s created+40| ... | @@ -0,0 +1,40 @@ | ||
| 1 | // REQUIRES: arm | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=armv7-pc-linux %s -o %t.o | ||
| 4 | // RUN: ld.lld %t.o -o %t.so -shared | ||
| 5 | // RUN: llvm-readelf -l %t.so | FileCheck %s | ||
| 6 | |||
| 7 | // RUN: ld.lld %t.o %t.o -o %t.so -shared | ||
| 8 | // RUN: llvm-readelf -l %t.so | FileCheck %s | ||
| 9 | |||
| 10 | // RUN: echo ".section .foo,\"ax\"; \ | ||
| 11 | // RUN: bx lr" > %t.s | ||
| 12 | // RUN: llvm-mc -filetype=obj -triple=armv7-pc-linux %t.s -o %t2.o | ||
| 13 | // RUN: ld.lld %t.o %t2.o -o %t.so -shared | ||
| 14 | // RUN: llvm-readelf -l %t.so | FileCheck --check-prefix=DIFF %s | ||
| 15 | |||
| 16 | // CHECK-NOT: LOAD | ||
| 17 | // CHECK: LOAD 0x000000 0x00000000 0x00000000 0x0016d 0x0016d R 0x1000 | ||
| 18 | // CHECK: LOAD 0x001000 0x00001000 0x00001000 0x{{.*}} 0x{{.*}} R E 0x1000 | ||
| 19 | // CHECK: LOAD 0x002000 0x00002000 0x00002000 0x{{.*}} 0x{{.*}} E 0x1000 | ||
| 20 | // CHECK: LOAD 0x003000 0x00003000 0x00003000 0x00038 0x00038 RW 0x1000 | ||
| 21 | // CHECK-NOT: LOAD | ||
| 22 | |||
| 23 | // CHECK: 01 .dynsym .gnu.hash .hash .dynstr | ||
| 24 | // CHECK: 02 .text | ||
| 25 | // CHECK: 03 .foo | ||
| 26 | // CHECK: 04 .dynamic | ||
| 27 | |||
| 28 | // DIFF-NOT: LOAD | ||
| 29 | // DIFF: LOAD 0x000000 0x00000000 0x00000000 0x0014d 0x0014d R 0x1000 | ||
| 30 | // DIFF: LOAD 0x001000 0x00001000 0x00001000 0x0000c 0x0000c R E 0x1000 | ||
| 31 | // DIFF: LOAD 0x002000 0x00002000 0x00002000 0x00038 0x00038 RW 0x1000 | ||
| 32 | // DIFF-NOT: LOAD | ||
| 33 | |||
| 34 | // DIFF: 01 .dynsym .gnu.hash .hash .dynstr | ||
| 35 | // DIFF: 02 .text .foo | ||
| 36 | // DIFF: 03 .dynamic | ||
| 37 | |||
| 38 | bx lr | ||
| 39 | .section .foo,"axy" | ||
| 40 | bx lr | ||
deps/lld/test/ELF/arm-exidx-canunwind.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 4 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s | 5 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s |
| 5 | // RUN: llvm-readobj --program-headers --sections %t2 | FileCheck -check-prefix=CHECK-PT %s | 6 | // RUN: llvm-readobj --program-headers --sections %t2 | FileCheck -check-prefix=CHECK-PT %s |
| 6 | // REQUIRES: arm | ||
| 7 | 7 | ||
| 8 | // Test that inline unwinding table entries and references to .ARM.extab | 8 | // Test that inline unwinding table entries and references to .ARM.extab |
| 9 | // entries survive the re-ordering of the .ARM.exidx section | 9 | // entries survive the re-ordering of the .ARM.exidx section |
deps/lld/test/ELF/arm-exidx-dedup.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t --no-merge-exidx-entries -o %t2 | 3 | // RUN: ld.lld %t --no-merge-exidx-entries -o %t2 |
| 3 | // RUN: llvm-objdump -s %t2 | FileCheck --check-prefix CHECK-DUPS %s | 4 | // RUN: llvm-objdump -s %t2 | FileCheck --check-prefix CHECK-DUPS %s |
| 4 | // RUN: ld.lld %t -o %t3 | 5 | // RUN: ld.lld %t -o %t3 |
| 5 | // RUN: llvm-objdump -s %t3 | FileCheck %s | 6 | // RUN: llvm-objdump -s %t3 | FileCheck %s |
| 6 | // REQUIRES: arm | ||
| 7 | // Test that lld can at least remove duplicate .ARM.exidx sections. A more | 7 | // Test that lld can at least remove duplicate .ARM.exidx sections. A more |
| 8 | // fine grained implementation will be able to remove duplicate entries within | 8 | // fine grained implementation will be able to remove duplicate entries within |
| 9 | // a .ARM.exidx section. | 9 | // a .ARM.exidx section. |
deps/lld/test/ELF/arm-exidx-discard.s created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | // REQUIRES: arm | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple arm-gnu-linux-eabi -mcpu cortex-a7 -arm-add-build-attributes %s -o %t.o | ||
| 3 | // RUN: echo "ENTRY(__entrypoint) SECTIONS { . = 0x10000; .text : { *(.text .text.*) } /DISCARD/ : { *(.ARM.exidx*) *(.gnu.linkonce.armexidx.*) } }" > %t.script | ||
| 4 | // RUN: ld.lld -T %t.script %t.o -o %t.elf 2>&1 | ||
| 5 | // RUN: llvm-readobj -sections %t.elf | FileCheck %s | ||
| 6 | |||
| 7 | .globl __entrypoint | ||
| 8 | __entrypoint: | ||
| 9 | bx lr | ||
| 10 | |||
| 11 | // Check that .ARM.exidx/.gnu.linkonce.armexidx | ||
| 12 | // are correctly removed if they were added. | ||
| 13 | // CHECK-NOT: .ARM.exidx | ||
| 14 | // CHECK-NOT: .gnu.linkonce.armexidx. | ||
deps/lld/test/ELF/arm-exidx-gc.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t --no-merge-exidx-entries -o %t2 --gc-sections 2>&1 | 3 | // RUN: ld.lld %t --no-merge-exidx-entries -o %t2 --gc-sections 2>&1 |
| 3 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 4 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s | 5 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s |
| 5 | // REQUIRES: arm | ||
| 6 | 6 | ||
| 7 | // Test the behavior of .ARM.exidx sections under garbage collection | 7 | // Test the behavior of .ARM.exidx sections under garbage collection |
| 8 | // A .ARM.exidx section is live if it has a relocation to a live executable | 8 | // A .ARM.exidx section is live if it has a relocation to a live executable |
deps/lld/test/ELF/arm-exidx-order.s+19-19| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind |
| 3 | // RUN: ld.lld --no-merge-exidx-entries %t %tcantunwind -o %t2 2>&1 | 4 | // RUN: ld.lld --no-merge-exidx-entries %t %tcantunwind -o %t2 2>&1 |
| ... | @@ -11,7 +12,6 @@ | ... | @@ -11,7 +12,6 @@ |
| 11 | // RUN: ld.lld --no-merge-exidx-entries --script %t.script %tcantunwind %t -o %t3 2>&1 | 12 | // RUN: ld.lld --no-merge-exidx-entries --script %t.script %tcantunwind %t -o %t3 2>&1 |
| 12 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT %s | 13 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT %s |
| 13 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT-EXIDX %s | 14 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT-EXIDX %s |
| 14 | // REQUIRES: arm | ||
| 15 | 15 | ||
| 16 | // Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set | 16 | // Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set |
| 17 | // with the sh_link containing the section index of the executable section | 17 | // with the sh_link containing the section index of the executable section |
| ... | @@ -142,28 +142,28 @@ f3: | ... | @@ -142,28 +142,28 @@ f3: |
| 142 | // CHECK-SCRIPT-NEXT: 11014: 1e ff 2f e1 bx lr | 142 | // CHECK-SCRIPT-NEXT: 11014: 1e ff 2f e1 bx lr |
| 143 | // CHECK-SCRIPT-NEXT: Disassembly of section .func1: | 143 | // CHECK-SCRIPT-NEXT: Disassembly of section .func1: |
| 144 | // CHECK-SCRIPT-NEXT: func1: | 144 | // CHECK-SCRIPT-NEXT: func1: |
| 145 | // CHECK-SCRIPT-NEXT: 11068: 1e ff 2f e1 bx lr | 145 | // CHECK-SCRIPT-NEXT: 11018: 1e ff 2f e1 bx lr |
| 146 | // CHECK-SCRIPT-NEXT: Disassembly of section .func2: | 146 | // CHECK-SCRIPT-NEXT: Disassembly of section .func2: |
| 147 | // CHECK-SCRIPT-NEXT: func2: | 147 | // CHECK-SCRIPT-NEXT: func2: |
| 148 | // CHECK-SCRIPT-NEXT: 1106c: 1e ff 2f e1 bx lr | 148 | // CHECK-SCRIPT-NEXT: 1101c: 1e ff 2f e1 bx lr |
| 149 | // CHECK-SCRIPT-NEXT: Disassembly of section .func3: | 149 | // CHECK-SCRIPT-NEXT: Disassembly of section .func3: |
| 150 | // CHECK-SCRIPT-NEXT: func3: | 150 | // CHECK-SCRIPT-NEXT: func3: |
| 151 | // CHECK-SCRIPT-NEXT: 11070: 1e ff 2f e1 bx lr | 151 | // CHECK-SCRIPT-NEXT: 11020: 1e ff 2f e1 bx lr |
| 152 | 152 | ||
| 153 | // Check that the .ARM.exidx section is sorted in order as the functions | 153 | // Check that the .ARM.exidx section is sorted in order as the functions |
| 154 | // The offset in field 1, is 32-bit so in the binary the most significant bit | 154 | // The offset in field 1, is 32-bit so in the binary the most significant bit |
| 155 | // 11018 - 18 = 11000 func4 | 155 | // 11024 - 24 = 11000 func4 |
| 156 | // 11020 - 1c = 11004 func5 | 156 | // 1102c - 28 = 11004 func5 |
| 157 | // CHECK-SCRIPT-EXIDX: 11018 e8ffff7f 01000000 e4ffff7f 01000000 | 157 | // CHECK-SCRIPT-EXIDX: 11024 dcffff7f 01000000 d8ffff7f 01000000 |
| 158 | // 11028 - 20 = 11008 _start | 158 | // 11034 - 2c = 11008 _start |
| 159 | // 11030 - 24 = 1100c f1 | 159 | // 1103c - 30 = 1100c f1 |
| 160 | // CHECK-SCRIPT-EXIDX-NEXT: 11028 e0ffff7f 01000000 dcffff7f 01000000 | 160 | // CHECK-SCRIPT-EXIDX-NEXT: 11034 d4ffff7f 01000000 d0ffff7f 01000000 |
| 161 | // 11038 - 28 = 11010 f2 | 161 | // 11044 - 34 = 11010 f2 |
| 162 | // 11040 - 2c = 11014 f3 | 162 | // 1104c - 38 = 11014 f3 |
| 163 | // CHECK-SCRIPT-EXIDX-NEXT: 11038 d8ffff7f 01000000 d4ffff7f 01000000 | 163 | // CHECK-SCRIPT-EXIDX-NEXT: 11044 ccffff7f 01000000 c8ffff7f 01000000 |
| 164 | // 11048 + 20 = 11068 func1 | 164 | // 11054 - 3c = 11018 func1 |
| 165 | // 11050 + 1c = 1106c func2 | 165 | // 1105c - 40 = 1101c func2 |
| 166 | // CHECK-SCRIPT-EXIDX-NEXT: 11048 20000000 01000000 1c000000 01000000 | 166 | // CHECK-SCRIPT-EXIDX-NEXT: 11054 c4ffff7f 01000000 c0ffff7f 01000000 |
| 167 | // 11058 + 18 = 11070 func3 | 167 | // 11064 - 44 = 11020 func3 |
| 168 | // 11060 + 14 = 11074 func3 + sizeof(func3) | 168 | // 11068 - 48 = 11024 func3 + sizeof(func3) |
| 169 | // CHECK-SCRIPT-EXIDX-NEXT: 11058 18000000 01000000 14000000 01000000 | 169 | // CHECK-SCRIPT-EXIDX-NEXT: 11064 bcffff7f 01000000 b8ffff7f 01000000 |
deps/lld/test/ELF/arm-exidx-output.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-readobj -sections %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -sections %t2 | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | 5 | ||
| 6 | // Check that only a single .ARM.exidx output section is created when | 6 | // Check that only a single .ARM.exidx output section is created when |
| 7 | // there are input sections of the form .ARM.exidx.<section-name>. The | 7 | // there are input sections of the form .ARM.exidx.<section-name>. The |
deps/lld/test/ELF/arm-exidx-relocatable.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind |
| 3 | // Check that relocatable link maintains SHF_LINK_ORDER | 4 | // Check that relocatable link maintains SHF_LINK_ORDER |
| 4 | // RUN: ld.lld -r %t %tcantunwind -o %t4 2>&1 | 5 | // RUN: ld.lld -r %t %tcantunwind -o %t4 2>&1 |
| 5 | // RUN: llvm-readobj -s %t4 | FileCheck %s | 6 | // RUN: llvm-readobj -s %t4 | FileCheck %s |
| 6 | // REQUIRES: arm | ||
| 7 | 7 | ||
| 8 | // Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set | 8 | // Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set |
| 9 | // with the sh_link containing the section index of the executable section | 9 | // with the sh_link containing the section index of the executable section |
deps/lld/test/ELF/arm-exidx-sentinel-norelocatable.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // 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 -o %t.o |
| 2 | // RUN: ld.lld -r %t.o -o %t | 3 | // RUN: ld.lld -r %t.o -o %t |
| 3 | // REQUIRES: arm | ||
| 4 | // RUN: llvm-readobj -s %t | FileCheck %s | 4 | // RUN: llvm-readobj -s %t | FileCheck %s |
| 5 | // Check that when doing a relocatable link we don't add a terminating entry | 5 | // Check that when doing a relocatable link we don't add a terminating entry |
| 6 | // to the .ARM.exidx section | 6 | // to the .ARM.exidx section |
deps/lld/test/ELF/arm-exidx-sentinel-orphan.s+2-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // Use Linker script without .ARM.exidx Output Section so it is treated as | 3 | // Use Linker script without .ARM.exidx Output Section so it is treated as |
| 3 | // an orphan. We must still add the sentinel table entry | 4 | // an orphan. We must still add the sentinel table entry |
| ... | @@ -6,7 +7,6 @@ | ... | @@ -6,7 +7,6 @@ |
| 6 | // RUN: } " > %t.script | 7 | // RUN: } " > %t.script |
| 7 | // RUN: ld.lld --no-merge-exidx-entries --script %t.script %t -o %t2 | 8 | // RUN: ld.lld --no-merge-exidx-entries --script %t.script %t -o %t2 |
| 8 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s | 9 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 9 | // REQUIRES: arm | ||
| 10 | 10 | ||
| 11 | .syntax unified | 11 | .syntax unified |
| 12 | .text | 12 | .text |
| ... | @@ -20,4 +20,4 @@ _start: | ... | @@ -20,4 +20,4 @@ _start: |
| 20 | // CHECK: Contents of section .ARM.exidx: | 20 | // CHECK: Contents of section .ARM.exidx: |
| 21 | // 11004 - 4 = 0x11000 = _start | 21 | // 11004 - 4 = 0x11000 = _start |
| 22 | // 1100c - 8 = 0x11004 = _start + sizeof(_start) | 22 | // 1100c - 8 = 0x11004 = _start + sizeof(_start) |
| 23 | // CHECK-NEXT: 11004 fcffff7f 01000000 f8ffff7f 01000000 | 23 | // CHECK-NEXT: 0000 00100100 01000000 fc0f0100 01000000 |
deps/lld/test/ELF/arm-exidx-shared.s+4-4| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld --hash-style=sysv %t --shared -o %t2 2>&1 | 3 | // RUN: ld.lld --hash-style=sysv %t --shared -o %t2 2>&1 |
| 3 | // RUN: llvm-readobj --relocations %t2 | FileCheck %s | 4 | // RUN: llvm-readobj --relocations %t2 | FileCheck %s |
| 4 | // 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 %s |
| 5 | // REQUIRES: arm | ||
| 6 | 6 | ||
| 7 | // Check that the relative R_ARM_PREL31 relocation can access a PLT entry | 7 | // Check that the relative R_ARM_PREL31 relocation can access a PLT entry |
| 8 | // for when the personality routine is referenced from a shared library. | 8 | // for when the personality routine is referenced from a shared library. |
| ... | @@ -37,9 +37,9 @@ __aeabi_unwind_cpp_pr0: | ... | @@ -37,9 +37,9 @@ __aeabi_unwind_cpp_pr0: |
| 37 | bx lr | 37 | bx lr |
| 38 | 38 | ||
| 39 | // CHECK: Relocations [ | 39 | // CHECK: Relocations [ |
| 40 | // CHECK-NEXT: Section (6) .rel.plt { | 40 | // CHECK-NEXT: Section {{.*}} .rel.plt { |
| 41 | // CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0 | 41 | // CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0 |
| 42 | 42 | ||
| 43 | // CHECK-EXTAB: Contents of section .ARM.extab: | 43 | // CHECK-EXTAB: Contents of section .ARM.extab: |
| 44 | // 014c + 0ee4 = 0x1030 = __gxx_personality_v0(PLT) | 44 | // 0x0210 + 0x0e20 = 0x1030 = __gxx_personality_v0(PLT) |
| 45 | // CHECK-EXTAB-NEXT: 014c e40e0000 b0b0b000 00000000 | 45 | // CHECK-EXTAB-NEXT: 0210 200e0000 b0b0b000 00000000 |
deps/lld/test/ELF/arm-gnu-ifunc-nosym.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-readobj -symbols %tout | FileCheck %s | 4 | // RUN: llvm-readobj -symbols %tout | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | 5 | ||
| 6 | // Check that no __rel_iplt_end/__rel_iplt_start | 6 | // Check that no __rel_iplt_end/__rel_iplt_start |
| 7 | // appear in symtab if there are no references to them. | 7 | // appear in symtab if there are no references to them. |
deps/lld/test/ELF/arm-gnu-ifunc-plt.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %S/Inputs/arm-shared.s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %S/Inputs/arm-shared.s -o %t1.o |
| 2 | // RUN: ld.lld %t1.o --shared -o %t.so | 3 | // RUN: ld.lld %t1.o --shared -o %t.so |
| 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t.o | 4 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t.o |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | // RUN: llvm-objdump -triple=armv7a-linux-gnueabihf -d %tout | FileCheck %s --check-prefix=DISASM | 6 | // RUN: llvm-objdump -triple=armv7a-linux-gnueabihf -d %tout | FileCheck %s --check-prefix=DISASM |
| 6 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT | 7 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT |
| 7 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s | 8 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s |
| 8 | // REQUIRES: arm | ||
| 9 | 9 | ||
| 10 | // Check that the IRELATIVE relocations are last in the .got | 10 | // Check that the IRELATIVE relocations are last in the .got |
| 11 | // CHECK: Relocations [ | 11 | // CHECK: Relocations [ |
deps/lld/test/ELF/arm-gnu-ifunc.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-objdump -triple armv7a-none-linux-gnueabi -d %tout | FileCheck %s --check-prefix=DISASM | 4 | // RUN: llvm-objdump -triple armv7a-none-linux-gnueabi -d %tout | FileCheck %s --check-prefix=DISASM |
| 4 | // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s | 5 | // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s |
| 5 | // REQUIRES: arm | ||
| 6 | .syntax unified | 6 | .syntax unified |
| 7 | .text | 7 | .text |
| 8 | .type foo STT_GNU_IFUNC | 8 | .type foo STT_GNU_IFUNC |
deps/lld/test/ELF/arm-gotoff.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t | 3 | // RUN: ld.lld %t.o -o %t |
| 3 | // RUN: llvm-readobj -s -r -t %t | FileCheck %s | 4 | // RUN: llvm-readobj -s -r -t %t | FileCheck %s |
| 4 | // RUN: llvm-objdump -triple=armv7a-linux-gnueabi -d %t | FileCheck --check-prefix=DISASM %s | 5 | // RUN: llvm-objdump -triple=armv7a-linux-gnueabi -d %t | FileCheck --check-prefix=DISASM %s |
| 5 | // REQUIRES: arm | ||
| 6 | 6 | ||
| 7 | // Test the R_ARM_GOTOFF32 relocation | 7 | // Test the R_ARM_GOTOFF32 relocation |
| 8 | 8 |
deps/lld/test/ELF/arm-long-thunk-converge.s created+29| ... | @@ -0,0 +1,29 @@ | ||
| 1 | // REQUIRES: arm | ||
| 2 | // RUN: llvm-mc -triple armv7-unknown-gnu -filetype=obj -o %t %s | ||
| 3 | // RUN: ld.lld %t %S/Inputs/arm-long-thunk-converge.lds -o %t2 | ||
| 4 | // RUN: llvm-objdump -d -start-address=0x00000000 -stop-address=0x00000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK1 %s | ||
| 5 | // RUN: llvm-objdump -d -start-address=0x02000000 -stop-address=0x02000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK2 %s | ||
| 6 | // RUN: rm -f %t2 | ||
| 7 | |||
| 8 | // CHECK1: __ARMv7ABSLongThunk_bar: | ||
| 9 | // CHECK1-NEXT: 0: 0c c0 00 e3 movw r12, #12 | ||
| 10 | // CHECK1-NEXT: 4: 00 c2 40 e3 movt r12, #512 | ||
| 11 | // CHECK1-NEXT: 8: 1c ff 2f e1 bx r12 | ||
| 12 | // CHECK1: foo: | ||
| 13 | // CHECK1-NEXT: c: fb ff ff eb bl #-20 | ||
| 14 | |||
| 15 | .section .foo,"ax",%progbits,unique,1 | ||
| 16 | foo: | ||
| 17 | bl bar | ||
| 18 | |||
| 19 | // CHECK2: __ARMv7ABSLongThunk_foo: | ||
| 20 | // CHECK2-NEXT: 2000000: 0c c0 00 e3 movw r12, #12 | ||
| 21 | // CHECK2-NEXT: 2000004: 00 c0 40 e3 movt r12, #0 | ||
| 22 | // CHECK2-NEXT: 2000008: 1c ff 2f e1 bx r12 | ||
| 23 | // CHECK2: bar: | ||
| 24 | // CHECK2-NEXT: 200000c: fb ff ff eb bl #-20 <__ARMv7ABSLongThunk_foo> | ||
| 25 | |||
| 26 | .section .bar,"ax",%progbits,unique,1 | ||
| 27 | bar: | ||
| 28 | bl foo | ||
| 29 | .zero 0x1000000 | ||
deps/lld/test/ELF/arm-mov-relocs.s+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-unknown-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-unknown-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 | 3 | // RUN: ld.lld %t -o %t2 |
| 3 | // RUN: llvm-objdump -d %t2 -triple=armv7a-unknown-linux-gnueabi | FileCheck %s | 4 | // RUN: llvm-objdump -d %t2 -triple=armv7a-unknown-linux-gnueabi | FileCheck %s |
| 4 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-unknown-linux-gnueabi %s -o %t3 | 5 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-unknown-linux-gnueabi %s -o %t3 |
| 5 | // RUN: ld.lld %t3 -o %t4 | 6 | // RUN: ld.lld %t3 -o %t4 |
| 6 | // RUN: llvm-objdump -d %t4 -triple=thumbv7a-unknown-linux-gnueabi | FileCheck %s | 7 | // RUN: llvm-objdump -d %t4 -triple=thumbv7a-unknown-linux-gnueabi | FileCheck %s |
| 7 | // REQUIRES: arm | ||
| 8 | 8 | ||
| 9 | // Test the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocations as well as | 9 | // Test the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocations as well as |
| 10 | // the R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS relocations. | 10 | // the R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS relocations. |
deps/lld/test/ELF/arm-pie-relative.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld --hash-style=sysv %t --pie -o %t2 | 3 | // RUN: ld.lld --hash-style=sysv %t --pie -o %t2 |
| 3 | // RUN: llvm-readobj -r %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -r %t2 | FileCheck %s |
| 4 | // RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=GOT | 5 | // RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=GOT |
| 5 | // REQUIRES: arm | ||
| 6 | 6 | ||
| 7 | // Test that a R_ARM_GOT_BREL relocation with PIE results in a R_ARM_RELATIVE | 7 | // Test that a R_ARM_GOT_BREL relocation with PIE results in a R_ARM_RELATIVE |
| 8 | // dynamic relocation | 8 | // dynamic relocation |
deps/lld/test/ELF/arm-plt-reloc.s+5-5| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 |
| 3 | // RUN: ld.lld %t1 %t2 -o %t | 4 | // RUN: ld.lld %t1 %t2 -o %t |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | // RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3 | 6 | // RUN: ld.lld --hash-style=sysv -shared %t1 %t2 -o %t3 |
| 6 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSO %s | 7 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSO %s |
| 7 | // RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s | 8 | // RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s |
| 8 | // REQUIRES: arm | ||
| 9 | // | 9 | // |
| 10 | // Test PLT entry generation | 10 | // Test PLT entry generation |
| 11 | .syntax unified | 11 | .syntax unified |
| ... | @@ -96,7 +96,7 @@ _start: | ... | @@ -96,7 +96,7 @@ _start: |
| 96 | // DSOREL-NEXT: AddressAlignment: 4 | 96 | // DSOREL-NEXT: AddressAlignment: 4 |
| 97 | // DSOREL-NEXT: EntrySize: | 97 | // DSOREL-NEXT: EntrySize: |
| 98 | // DSOREL: Relocations [ | 98 | // DSOREL: Relocations [ |
| 99 | // DSOREL-NEXT: Section (4) .rel.plt { | 99 | // DSOREL-NEXT: Section {{.*}} .rel.plt { |
| 100 | // DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0 | 100 | // DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0 |
| 101 | // DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0 | 101 | // DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0 |
| 102 | // DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0 | 102 | // DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0 |
| ... | @@ -162,7 +162,7 @@ _start: | ... | @@ -162,7 +162,7 @@ _start: |
| 162 | // DSORELHIGH-NEXT: ] | 162 | // DSORELHIGH-NEXT: ] |
| 163 | // DSORELHIGH-NEXT: Address: 0x1100000 | 163 | // DSORELHIGH-NEXT: Address: 0x1100000 |
| 164 | // DSORELHIGH: Relocations [ | 164 | // DSORELHIGH: Relocations [ |
| 165 | // DSORELHIGH-NEXT: Section (6) .rel.plt { | 165 | // DSORELHIGH-NEXT: Section {{.*}} .rel.plt { |
| 166 | // DSORELHIGH-NEXT: 0x110000C R_ARM_JUMP_SLOT func1 0x0 | 166 | // DSORELHIGH-NEXT: 0x110000C R_ARM_JUMP_SLOT func1 0x0 |
| 167 | // DSORELHIGH-NEXT: 0x1100010 R_ARM_JUMP_SLOT func2 0x0 | 167 | // DSORELHIGH-NEXT: 0x1100010 R_ARM_JUMP_SLOT func2 0x0 |
| 168 | // DSORELHIGH-NEXT: 0x1100014 R_ARM_JUMP_SLOT func3 0x0 | 168 | // DSORELHIGH-NEXT: 0x1100014 R_ARM_JUMP_SLOT func3 0x0 |
| ... | @@ -227,7 +227,7 @@ _start: | ... | @@ -227,7 +227,7 @@ _start: |
| 227 | // DSORELLONG-NEXT: ] | 227 | // DSORELLONG-NEXT: ] |
| 228 | // DSORELLONG-NEXT: Address: 0x11111100 | 228 | // DSORELLONG-NEXT: Address: 0x11111100 |
| 229 | // DSORELLONG: Relocations [ | 229 | // DSORELLONG: Relocations [ |
| 230 | // DSORELLONG-NEXT: Section (6) .rel.plt { | 230 | // DSORELLONG-NEXT: Section {{.*}} .rel.plt { |
| 231 | // DSORELLONG-NEXT: 0x1111110C R_ARM_JUMP_SLOT func1 0x0 | 231 | // DSORELLONG-NEXT: 0x1111110C R_ARM_JUMP_SLOT func1 0x0 |
| 232 | // DSORELLONG-NEXT: 0x11111110 R_ARM_JUMP_SLOT func2 0x0 | 232 | // DSORELLONG-NEXT: 0x11111110 R_ARM_JUMP_SLOT func2 0x0 |
| 233 | // DSORELLONG-NEXT: 0x11111114 R_ARM_JUMP_SLOT func3 0x0 | 233 | // DSORELLONG-NEXT: 0x11111114 R_ARM_JUMP_SLOT func3 0x0 |
| ... | @@ -292,7 +292,7 @@ _start: | ... | @@ -292,7 +292,7 @@ _start: |
| 292 | // DSORELMIX-NEXT: SHF_WRITE | 292 | // DSORELMIX-NEXT: SHF_WRITE |
| 293 | // DSORELMIX-NEXT: ] | 293 | // DSORELMIX-NEXT: ] |
| 294 | // DSORELMIX-NEXT: Address: 0x8002020 | 294 | // DSORELMIX-NEXT: Address: 0x8002020 |
| 295 | // DSORELMIX: Section (6) .rel.plt { | 295 | // DSORELMIX: Section {{.*}} .rel.plt { |
| 296 | // DSORELMIX-NEXT: 0x800202C R_ARM_JUMP_SLOT func1 0x0 | 296 | // DSORELMIX-NEXT: 0x800202C R_ARM_JUMP_SLOT func1 0x0 |
| 297 | // DSORELMIX-NEXT: 0x8002030 R_ARM_JUMP_SLOT func2 0x0 | 297 | // DSORELMIX-NEXT: 0x8002030 R_ARM_JUMP_SLOT func2 0x0 |
| 298 | // DSORELMIX-NEXT: 0x8002034 R_ARM_JUMP_SLOT func3 0x0 | 298 | // DSORELMIX-NEXT: 0x8002034 R_ARM_JUMP_SLOT func3 0x0 |
deps/lld/test/ELF/arm-sbrel32.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | 5 | ||
| 6 | // Test the R_ARM_SBREL32 relocation which calculates the offset of the Symbol | 6 | // Test the R_ARM_SBREL32 relocation which calculates the offset of the Symbol |
| 7 | // from the static base. We define the static base to be the address of the | 7 | // from the static base. We define the static base to be the address of the |
deps/lld/test/ELF/arm-static-defines.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld --no-merge-exidx-entries %t --static -o %t2 2>&1 | 3 | // RUN: ld.lld --no-merge-exidx-entries %t --static -o %t2 2>&1 |
| 3 | // RUN: llvm-readobj --symbols %t2 | FileCheck %s | 4 | // RUN: llvm-readobj --symbols %t2 | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | 5 | ||
| 6 | // Check that on ARM we don't get a multiply defined symbol for __tls_get_addr | 6 | // Check that on ARM we don't get a multiply defined symbol for __tls_get_addr |
| 7 | // and undefined symbols for references to __exidx_start and __exidx_end | 7 | // and undefined symbols for references to __exidx_start and __exidx_end |
deps/lld/test/ELF/arm-symbol-ordering-file.s created+32| ... | @@ -0,0 +1,32 @@ | ||
| 1 | # REQUIRES: arm | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=armv7-unknown-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo ordered > %t_order.txt | ||
| 5 | # RUN: ld.lld --symbol-ordering-file %t_order.txt %t.o -o %t2.out | ||
| 6 | # RUN: llvm-nm -n %t2.out | FileCheck %s | ||
| 7 | |||
| 8 | # CHECK: unordered1 | ||
| 9 | # CHECK-NEXT: unordered2 | ||
| 10 | # CHECK-NEXT: unordered3 | ||
| 11 | # CHECK-NEXT: ordered | ||
| 12 | # CHECK-NEXT: unordered4 | ||
| 13 | |||
| 14 | .section .foo,"ax",%progbits,unique,1 | ||
| 15 | unordered1: | ||
| 16 | .zero 1 | ||
| 17 | |||
| 18 | .section .foo,"ax",%progbits,unique,2 | ||
| 19 | unordered2: | ||
| 20 | .zero 1 | ||
| 21 | |||
| 22 | .section .foo,"ax",%progbits,unique,3 | ||
| 23 | unordered3: | ||
| 24 | .zero 2 | ||
| 25 | |||
| 26 | .section .foo,"ax",%progbits,unique,4 | ||
| 27 | unordered4: | ||
| 28 | .zero 4 | ||
| 29 | |||
| 30 | .section .foo,"ax",%progbits,unique,5 | ||
| 31 | ordered: | ||
| 32 | .zero 1 | ||
deps/lld/test/ELF/arm-tag-vfp-args-errs.s created+29| ... | @@ -0,0 +1,29 @@ | ||
| 1 | // REQUIRES:arm | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-base.s -o %tbase.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-vfp.s -o %tvfp.o | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-toolchain.s -o %ttoolchain.o | ||
| 5 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | ||
| 6 | // RUN: not ld.lld %t.o %tbase.o %tvfp.o -o%t 2>&1 | FileCheck %s | ||
| 7 | // RUN: not ld.lld %t.o %tbase.o %ttoolchain.o -o%t 2>&1 | FileCheck %s | ||
| 8 | // RUN: not ld.lld %t.o %tvfp.o %tbase.o -o%t 2>&1 | FileCheck %s | ||
| 9 | // RUN: not ld.lld %t.o %tvfp.o %ttoolchain.o -o%t 2>&1 | FileCheck %s | ||
| 10 | // RUN: not ld.lld %t.o %ttoolchain.o %tbase.o -o%t 2>&1 | FileCheck %s | ||
| 11 | // RUN: not ld.lld %t.o %ttoolchain.o %tvfp.o -o%t 2>&1 | FileCheck %s | ||
| 12 | |||
| 13 | // CHECK: incompatible Tag_ABI_VFP_args | ||
| 14 | 	.arch armv7-a | ||
| 15 | 	.eabi_attribute 20, 1 | ||
| 16 | 	.eabi_attribute 21, 1 | ||
| 17 | 	.eabi_attribute 23, 3 | ||
| 18 | 	.eabi_attribute 24, 1 | ||
| 19 | 	.eabi_attribute 25, 1 | ||
| 20 | 	.eabi_attribute 26, 2 | ||
| 21 | 	.eabi_attribute 30, 6 | ||
| 22 | 	.eabi_attribute 34, 1 | ||
| 23 | 	.eabi_attribute 18, 4 | ||
| 24 | .eabi_attribute 28, 3 // Tag_ABI_VFP_args = 3 (Compatible with all) | ||
| 25 | |||
| 26 | .syntax unified | ||
| 27 | .globl _start | ||
| 28 | .type _start, %function | ||
| 29 | _start: bx lr | ||
deps/lld/test/ELF/arm-tag-vfp-args-illegal.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | // REQUIRES:arm | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | ||
| 3 | // RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | // CHECK: arm-tag-vfp-args-illegal.s.tmp.o: unknown Tag_ABI_VFP_args value: 5 | ||
| 6 | .arch armv7-a | ||
| 7 | .eabi_attribute 20, 1 | ||
| 8 | .eabi_attribute 21, 1 | ||
| 9 | .eabi_attribute 23, 3 | ||
| 10 | .eabi_attribute 24, 1 | ||
| 11 | .eabi_attribute 25, 1 | ||
| 12 | .eabi_attribute 26, 2 | ||
| 13 | .eabi_attribute 30, 6 | ||
| 14 | .eabi_attribute 34, 1 | ||
| 15 | .eabi_attribute 18, 4 | ||
| 16 | .eabi_attribute 28, 5 // Tag_ABI_VFP_args = 5 (Illegal value) | ||
| 17 | |||
| 18 | .syntax unified | ||
| 19 | .globl _start | ||
| 20 | .type _start, %function | ||
| 21 | _start: bx lr | ||
deps/lld/test/ELF/arm-tag-vfp-args.s created+72| ... | @@ -0,0 +1,72 @@ | ||
| 1 | // REQUIRES:arm | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-base.s -o %tbase.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-vfp.s -o %tvfp.o | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-toolchain.s -o %ttoolchain.o | ||
| 5 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-compat.s -o %tcompat.o | ||
| 6 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | ||
| 7 | |||
| 8 | // The default for this file is 0 (Base AAPCS) | ||
| 9 | // RUN: ld.lld %t.o -o %tdefault | ||
| 10 | // RUN: llvm-readobj -file-headers %tdefault | FileCheck -check-prefix=CHECK-BASE %s | ||
| 11 | |||
| 12 | // Expect explicit Base AAPCS. | ||
| 13 | // RUN: ld.lld %t.o %tbase.o -o %tbase | ||
| 14 | // RUN: llvm-readobj -file-headers %tbase | FileCheck -check-prefix=CHECK-BASE %s | ||
| 15 | |||
| 16 | // Expect explicit Base AAPCS when linking Base and Compatible. | ||
| 17 | // RUN: ld.lld %t.o %tbase.o %tcompat.o -o %tbasecompat | ||
| 18 | // RUN: llvm-readobj -file-headers %tbasecompat | FileCheck -check-prefix=CHECK-BASE %s | ||
| 19 | |||
| 20 | // CHECK-BASE: Flags [ (0x5000200) | ||
| 21 | // CHECK-BASE-NEXT: 0x200 | ||
| 22 | // CHECK-BASE-NEXT: 0x1000000 | ||
| 23 | // CHECK-BASE-NEXT: 0x4000000 | ||
| 24 | // CHECK-BASE-NEXT: ] | ||
| 25 | |||
| 26 | // Expect Hard float VFP AAPCS | ||
| 27 | // RUN: ld.lld %t.o %tvfp.o -o %tvfp | ||
| 28 | // RUN: llvm-readobj -file-headers %tvfp | FileCheck -check-prefix=CHECK-VFP %s | ||
| 29 | |||
| 30 | // Expect Hard float VFP AAPCS when linking VFP and Compatible | ||
| 31 | // RUN: ld.lld %t.o %tvfp.o %tcompat.o -o %tvfpcompat | ||
| 32 | // RUN: llvm-readobj -file-headers %tvfpcompat | FileCheck -check-prefix=CHECK-VFP %s | ||
| 33 | |||
| 34 | // CHECK-VFP: Flags [ (0x5000400) | ||
| 35 | // CHECK-VFP-NEXT: 0x400 | ||
| 36 | // CHECK-VFP-NEXT: 0x1000000 | ||
| 37 | // CHECK-VFP-NEXT: 0x4000000 | ||
| 38 | // CHECK-VFP-NEXT: ] | ||
| 39 | |||
| 40 | // Expect Toolchain specifc to not use either Base or VFP AAPCS | ||
| 41 | // RUN: ld.lld %t.o %ttoolchain.o -o %ttoolchain | ||
| 42 | // RUN: llvm-readobj -file-headers %ttoolchain | FileCheck -check-prefix=CHECK-TOOLCHAIN %s | ||
| 43 | |||
| 44 | // Expect Toolchain and Compatible to have same affect as Toolchain. | ||
| 45 | // RUN: ld.lld %t.o %ttoolchain.o %tcompat.o -o %ttoolchaincompat | ||
| 46 | // RUN: llvm-readobj -file-headers %ttoolchaincompat | FileCheck -check-prefix=CHECK-TOOLCHAIN %s | ||
| 47 | |||
| 48 | // CHECK-TOOLCHAIN: Flags [ (0x5000000) | ||
| 49 | // CHECK-TOOLCHAIN-NEXT: 0x1000000 | ||
| 50 | // CHECK-TOOLCHAIN-NEXT: 0x4000000 | ||
| 51 | // CHECK-TOOLCHAIN-NEXT: ] | ||
| 52 | |||
| 53 | .arch armv7-a | ||
| 54 | .eabi_attribute 20, 1 | ||
| 55 | .eabi_attribute 21, 1 | ||
| 56 | .eabi_attribute 23, 3 | ||
| 57 | .eabi_attribute 24, 1 | ||
| 58 | .eabi_attribute 25, 1 | ||
| 59 | .eabi_attribute 26, 2 | ||
| 60 | .eabi_attribute 30, 6 | ||
| 61 | .eabi_attribute 34, 1 | ||
| 62 | .eabi_attribute 18, 4 | ||
| 63 | // We do not specify Tag_ABI_VFP_args (.eabi_attribute 28) in this file. | ||
| 64 | // When omitted the value of the tag defaults to 0, however if there | ||
| 65 | // are other files with explicit Tag_ABI_VFP_args we use that in | ||
| 66 | // preference. | ||
| 67 | |||
| 68 | |||
| 69 | .syntax unified | ||
| 70 | .globl _start | ||
| 71 | .type _start, %function | ||
| 72 | _start: bx lr | ||
deps/lld/test/ELF/arm-target1.s+1-1| ... | @@ -31,6 +31,6 @@ | ... | @@ -31,6 +31,6 @@ |
| 31 | // RELATIVE: SYMBOL TABLE: | 31 | // RELATIVE: SYMBOL TABLE: |
| 32 | // RELATIVE: 00001004 .text 00000000 patatino | 32 | // RELATIVE: 00001004 .text 00000000 patatino |
| 33 | 33 | ||
| 34 | // ABS: can't create dynamic relocation R_ARM_TARGET1 against symbol: patatino | 34 | // ABS: can't create dynamic relocation R_ARM_TARGET1 against symbol: patatino in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 35 | // ABS: >>> defined in {{.*}}.o | 35 | // ABS: >>> defined in {{.*}}.o |
| 36 | // ABS: >>> referenced by {{.*}}.o:(.text+0x0) | 36 | // ABS: >>> referenced by {{.*}}.o:(.text+0x0) |
deps/lld/test/ELF/arm-target2.s+7-7| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t 2>&1 | 3 | // RUN: ld.lld %t.o -o %t 2>&1 |
| 3 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t | FileCheck %s | 4 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t | FileCheck %s |
| ... | @@ -7,7 +8,6 @@ | ... | @@ -7,7 +8,6 @@ |
| 7 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-ABS %s | 8 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-ABS %s |
| 8 | // RUN: ld.lld %t.o --target2=rel -o %t4 2>&1 | 9 | // RUN: ld.lld %t.o --target2=rel -o %t4 2>&1 |
| 9 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-REL %s | 10 | // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-REL %s |
| 10 | // REQUIRES: arm | ||
| 11 | 11 | ||
| 12 | // The R_ARM_TARGET2 is present in .ARM.extab sections. It can be handled as | 12 | // The R_ARM_TARGET2 is present in .ARM.extab sections. It can be handled as |
| 13 | // either R_ARM_ABS32, R_ARM_REL32 or R_ARM_GOT_PREL. For ARM linux the default | 13 | // either R_ARM_ABS32, R_ARM_REL32 or R_ARM_GOT_PREL. For ARM linux the default |
| ... | @@ -35,16 +35,16 @@ __gxx_personality_v0: | ... | @@ -35,16 +35,16 @@ __gxx_personality_v0: |
| 35 | _ZTIi: .word 0 | 35 | _ZTIi: .word 0 |
| 36 | 36 | ||
| 37 | // CHECK: Contents of section .ARM.extab: | 37 | // CHECK: Contents of section .ARM.extab: |
| 38 | // 1011c + 1ee4 = 12000 = .got | 38 | // 0x1012c + 0x1ed4 = 0x12000 = .got |
| 39 | // CHECK-NEXT: 10114 f00e0000 b0b0b000 e41e0000 | 39 | // CHECK-NEXT: 10124 e00e0000 b0b0b000 d41e0000 |
| 40 | 40 | ||
| 41 | // CHECK-ABS: Contents of section .ARM.extab: | 41 | // CHECK-ABS: Contents of section .ARM.extab: |
| 42 | // 100f0 = .rodata | 42 | // 0x100f0 = .rodata |
| 43 | // CHECK-ABS-NEXT: 100d4 300f0000 b0b0b000 f0000100 | 43 | // CHECK-ABS-NEXT: 100e4 200f0000 b0b0b000 f0000100 |
| 44 | 44 | ||
| 45 | // CHECK-REL: Contents of section .ARM.extab: | 45 | // CHECK-REL: Contents of section .ARM.extab: |
| 46 | // 100dc + c = 100e8 = .rodata | 46 | // 0x100ec + 4 = 0x100f0 = .rodata |
| 47 | // CHECK-REL-NEXT: 100d4 300f0000 b0b0b000 14000000 | 47 | // CHECK-REL-NEXT: 100e4 200f0000 b0b0b000 04000000 |
| 48 | 48 | ||
| 49 | // CHECK: Contents of section .rodata: | 49 | // CHECK: Contents of section .rodata: |
| 50 | // CHECK-NEXT: 10130 00000000 | 50 | // CHECK-NEXT: 10130 00000000 |
deps/lld/test/ELF/arm-thumb-blx.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/arm-thumb-blx-targets.s -o %ttarget | 3 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/arm-thumb-blx-targets.s -o %ttarget |
| 3 | // RUN: echo "SECTIONS { \ | 4 | // RUN: echo "SECTIONS { \ |
| ... | @@ -9,7 +10,6 @@ | ... | @@ -9,7 +10,6 @@ |
| 9 | // RUN: ld.lld --script %t.script %t %ttarget -o %t2 2>&1 | 10 | // RUN: ld.lld --script %t.script %t %ttarget -o %t2 2>&1 |
| 10 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s | 11 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s |
| 11 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s | 12 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s |
| 12 | // REQUIRES: arm | ||
| 13 | // Test BLX instruction is chosen for Thumb BL/BLX instruction and ARM callee | 13 | // Test BLX instruction is chosen for Thumb BL/BLX instruction and ARM callee |
| 14 | // 2 byte nops are used to test the pc-rounding behaviour. As a BLX from a | 14 | // 2 byte nops are used to test the pc-rounding behaviour. As a BLX from a |
| 15 | // 2 byte aligned destination is defined as Align(PC,4) + immediate:00 | 15 | // 2 byte aligned destination is defined as Align(PC,4) + immediate:00 |
deps/lld/test/ELF/arm-thumb-branch-rangethunk.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar | 3 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar |
| 3 | // RUN: ld.lld %t %tfar -o %t2 2>&1 | 4 | // RUN: ld.lld %t %tfar -o %t2 2>&1 |
| 4 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | 5 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 |
| 5 | // REQUIRES: arm | ||
| 6 | .syntax unified | 6 | .syntax unified |
| 7 | .thumb | 7 | .thumb |
| 8 | .section .text, "ax",%progbits | 8 | .section .text, "ax",%progbits |
deps/lld/test/ELF/arm-thumb-branch.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar | 3 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar |
| 3 | // RUN: echo "SECTIONS { \ | 4 | // RUN: echo "SECTIONS { \ |
| ... | @@ -7,7 +8,6 @@ | ... | @@ -7,7 +8,6 @@ |
| 7 | // RUN: .callee2 : { *(.callee_high) } } " > %t.script | 8 | // RUN: .callee2 : { *(.callee_high) } } " > %t.script |
| 8 | // RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 | 9 | // RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 |
| 9 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s | 10 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 10 | // REQUIRES: arm | ||
| 11 | 11 | ||
| 12 | .syntax unified | 12 | .syntax unified |
| 13 | .thumb | 13 | .thumb |
deps/lld/test/ELF/arm-thumb-condbranch-thunk.s+7-17| ... | @@ -38,13 +38,9 @@ _start: | ... | @@ -38,13 +38,9 @@ _start: |
| 38 | // CHECK1-NEXT: 80000: 70 47 bx lr | 38 | // CHECK1-NEXT: 80000: 70 47 bx lr |
| 39 | // CHECK1-NEXT: 80002: 7f f3 ff d7 bl #16252926 | 39 | // CHECK1-NEXT: 80002: 7f f3 ff d7 bl #16252926 |
| 40 | // CHECK1: __Thumbv7ABSLongThunk_tfunc05: | 40 | // CHECK1: __Thumbv7ABSLongThunk_tfunc05: |
| 41 | // CHECK1-NEXT: 80008: 40 f2 01 0c movw r12, #1 | 41 | // CHECK1-NEXT: 80008: 7f f2 fa bf b.w #2621428 <tfunc05> |
| 42 | // CHECK1-NEXT: 8000c: c0 f2 30 0c movt r12, #48 | ||
| 43 | // CHECK1-NEXT: 80010: 60 47 bx r12 | ||
| 44 | // CHECK1: __Thumbv7ABSLongThunk_tfunc00: | 42 | // CHECK1: __Thumbv7ABSLongThunk_tfunc00: |
| 45 | // CHECK1-NEXT: 80012: 40 f2 01 0c movw r12, #1 | 43 | // CHECK1-NEXT: 8000c: ff f7 f8 bf b.w #-16 <tfunc00> |
| 46 | // CHECK1-NEXT: 80016: c0 f2 08 0c movt r12, #8 | ||
| 47 | // CHECK1-NEXT: 8001a: 60 47 bx r12 | ||
| 48 | FUNCTION 01 | 44 | FUNCTION 01 |
| 49 | // tfunc02 is within range of tfunc02 | 45 | // tfunc02 is within range of tfunc02 |
| 50 | beq.w tfunc02 | 46 | beq.w tfunc02 |
| ... | @@ -61,7 +57,7 @@ _start: | ... | @@ -61,7 +57,7 @@ _start: |
| 61 | beq.w tfunc00 | 57 | beq.w tfunc00 |
| 62 | // CHECK3: 180000: 70 47 bx lr | 58 | // CHECK3: 180000: 70 47 bx lr |
| 63 | // CHECK3-NEXT: 180002: 40 f4 01 80 bne.w #-1048574 <__Thumbv7ABSLongThunk_tfunc05> | 59 | // CHECK3-NEXT: 180002: 40 f4 01 80 bne.w #-1048574 <__Thumbv7ABSLongThunk_tfunc05> |
| 64 | // CHECK3-NEXT: 180006: 00 f4 04 80 beq.w #-1048568 <__Thumbv7ABSLongThunk_tfunc00> | 60 | // CHECK3-NEXT: 180006: 00 f4 01 80 beq.w #-1048574 <__Thumbv7ABSLongThunk_tfunc00> |
| 65 | FUNCTION 03 | 61 | FUNCTION 03 |
| 66 | FUNCTION 04 | 62 | FUNCTION 04 |
| 67 | FUNCTION 05 | 63 | FUNCTION 05 |
| ... | @@ -70,9 +66,7 @@ _start: | ... | @@ -70,9 +66,7 @@ _start: |
| 70 | FUNCTION 08 | 66 | FUNCTION 08 |
| 71 | FUNCTION 09 | 67 | FUNCTION 09 |
| 72 | // CHECK4: __Thumbv7ABSLongThunk_tfunc03: | 68 | // CHECK4: __Thumbv7ABSLongThunk_tfunc03: |
| 73 | // CHECK4-NEXT: 500004: 40 f2 01 0c movw r12, #1 | 69 | // CHECK4-NEXT: 500004: ff f4 fc bf b.w #-3145736 <tfunc03> |
| 74 | // CHECK4-NEXT: 500008: c0 f2 20 0c movt r12, #32 | ||
| 75 | // CHECK4-NEXT: 50000c: 60 47 bx r12 | ||
| 76 | FUNCTION 10 | 70 | FUNCTION 10 |
| 77 | // We can't reach any Thunk Section, create a new one | 71 | // We can't reach any Thunk Section, create a new one |
| 78 | beq.w tfunc03 | 72 | beq.w tfunc03 |
| ... | @@ -101,17 +95,13 @@ _start: | ... | @@ -101,17 +95,13 @@ _start: |
| 101 | FUNCTION 30 | 95 | FUNCTION 30 |
| 102 | FUNCTION 31 | 96 | FUNCTION 31 |
| 103 | // CHECK6: __Thumbv7ABSLongThunk_tfunc33: | 97 | // CHECK6: __Thumbv7ABSLongThunk_tfunc33: |
| 104 | // CHECK6-NEXT: 1000004: 40 f2 01 0c movw r12, #1 | 98 | // CHECK6-NEXT: 1000004: ff f0 fc bf b.w #1048568 <tfunc33> |
| 105 | // CHECK6-NEXT: 1000008: c0 f2 10 1c movt r12, #272 | ||
| 106 | // CHECK6-NEXT: 100000c: 60 47 bx r12 | ||
| 107 | // CHECK6: __Thumbv7ABSLongThunk_tfunc00: | 99 | // CHECK6: __Thumbv7ABSLongThunk_tfunc00: |
| 108 | // CHECK6-NEXT: 100000e: 40 f2 01 0c movw r12, #1 | 100 | // CHECK6-NEXT: 1000008: 7f f4 fa 97 b.w #-16252940 <tfunc00> |
| 109 | // CHECK6-NEXT: 1000012: c0 f2 08 0c movt r12, #8 | ||
| 110 | // CHECK6-NEXT: 1000016: 60 47 bx r12 | ||
| 111 | FUNCTION 32 | 101 | FUNCTION 32 |
| 112 | FUNCTION 33 | 102 | FUNCTION 33 |
| 113 | // We should be able to reach an existing ThunkSection. | 103 | // We should be able to reach an existing ThunkSection. |
| 114 | b.w tfunc00 | 104 | b.w tfunc00 |
| 115 | // CHECK7: tfunc33: | 105 | // CHECK7: tfunc33: |
| 116 | // CHECK7-NEXT: 1100000: 70 47 bx lr | 106 | // CHECK7-NEXT: 1100000: 70 47 bx lr |
| 117 | // CHECK7-NEXT: 1100002: 00 f7 04 b8 b.w #-1048568 <__Thumbv7ABSLongThunk_tfunc00> | 107 | // CHECK7-NEXT: 1100002: 00 f7 01 b8 b.w #-1048574 <__Thumbv7ABSLongThunk_tfunc00> |
deps/lld/test/ELF/arm-thumb-interwork-shared.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t --shared -o %t.so | 3 | // RUN: ld.lld %t --shared -o %t.so |
| 3 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s | 4 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s |
| 4 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s -check-prefix=PLT | 5 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s -check-prefix=PLT |
| 5 | // REQUIRES: arm | ||
| 6 | .syntax unified | 6 | .syntax unified |
| 7 | .global sym1 | 7 | .global sym1 |
| 8 | .global elsewhere | 8 | .global elsewhere |
deps/lld/test/ELF/arm-thumb-interwork-thunk-range.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: arm | 1 | // REQUIRES: arm |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 3 | // RUN: ld.lld %t.o -o %t -image-base=0x80000000 | 3 | // RUN: ld.lld %t.o -o /dev/null -image-base=0x80000000 |
| 4 | 4 | ||
| 5 | // Test that when the thunk is at a high address we don't get confused with it | 5 | // Test that when the thunk is at a high address we don't get confused with it |
| 6 | // being out of range. | 6 | // being out of range. |
deps/lld/test/ELF/arm-thumb-interwork-thunk.s+10-10| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: echo "SECTIONS { \ | 3 | // RUN: echo "SECTIONS { \ |
| 3 | // RUN: . = SIZEOF_HEADERS; \ | 4 | // RUN: . = SIZEOF_HEADERS; \ |
| ... | @@ -8,7 +9,7 @@ | ... | @@ -8,7 +9,7 @@ |
| 8 | // RUN: .thumb_caller : { *(.thumb_caller) } \ | 9 | // RUN: .thumb_caller : { *(.thumb_caller) } \ |
| 9 | // RUN: .R_ARM_JUMP24_callee_2 : { *(.R_ARM_JUMP24_callee_high) } \ | 10 | // RUN: .R_ARM_JUMP24_callee_2 : { *(.R_ARM_JUMP24_callee_high) } \ |
| 10 | // RUN: .R_ARM_THM_JUMP_callee_2 : { *(.R_ARM_THM_JUMP_callee_high) } \ | 11 | // RUN: .R_ARM_THM_JUMP_callee_2 : { *(.R_ARM_THM_JUMP_callee_high) } \ |
| 11 | // RUN: .got.plt 0x1894 : { } } " > %t.script | 12 | // RUN: .got.plt 0x18b4 : { } } " > %t.script |
| 12 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | 13 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 |
| 13 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-ABS-THUMB %s | 14 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-ABS-THUMB %s |
| 14 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-ABS-ARM %s | 15 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-ABS-ARM %s |
| ... | @@ -19,7 +20,6 @@ | ... | @@ -19,7 +20,6 @@ |
| 19 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-PLT-THUMB %s | 20 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-PLT-THUMB %s |
| 20 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-PLT-ARM %s | 21 | // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-PLT-ARM %s |
| 21 | // 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 |
| 22 | // REQUIRES: arm | ||
| 23 | 23 | ||
| 24 | // Test ARM Thumb Interworking | 24 | // Test ARM Thumb Interworking |
| 25 | // The file is linked and checked 3 times to check the following contexts | 25 | // The file is linked and checked 3 times to check the following contexts |
| ... | @@ -368,11 +368,11 @@ _start: | ... | @@ -368,11 +368,11 @@ _start: |
| 368 | // CHECK-PI-ARM-PLT-NEXT: 183c: 00 f0 9c e5 ldr pc, [r12] | 368 | // CHECK-PI-ARM-PLT-NEXT: 183c: 00 f0 9c e5 ldr pc, [r12] |
| 369 | // CHECK-PI-ARM-PLT-NEXT: 1840: 7c 00 00 00 | 369 | // CHECK-PI-ARM-PLT-NEXT: 1840: 7c 00 00 00 |
| 370 | 370 | ||
| 371 | // CHECK-DSO-REL: 0x18A0 R_ARM_JUMP_SLOT arm_caller | 371 | // CHECK-DSO-REL: 0x18C0 R_ARM_JUMP_SLOT arm_caller |
| 372 | // CHECK-DSO-REL-NEXT: 0x18A4 R_ARM_JUMP_SLOT thumb_caller | 372 | // CHECK-DSO-REL-NEXT: 0x18C4 R_ARM_JUMP_SLOT thumb_caller |
| 373 | // CHECK-DSO-REL-NEXT: 0x18A8 R_ARM_JUMP_SLOT thumb_callee1 | 373 | // CHECK-DSO-REL-NEXT: 0x18C8 R_ARM_JUMP_SLOT thumb_callee1 |
| 374 | // CHECK-DSO-REL-NEXT: 0x18AC R_ARM_JUMP_SLOT thumb_callee2 | 374 | // CHECK-DSO-REL-NEXT: 0x18CC R_ARM_JUMP_SLOT thumb_callee2 |
| 375 | // CHECK-DSO-REL-NEXT: 0x18B0 R_ARM_JUMP_SLOT thumb_callee3 | 375 | // CHECK-DSO-REL-NEXT: 0x18D0 R_ARM_JUMP_SLOT thumb_callee3 |
| 376 | // CHECK-DSO-REL-NEXT: 0x18B4 R_ARM_JUMP_SLOT arm_callee1 | 376 | // CHECK-DSO-REL-NEXT: 0x18D4 R_ARM_JUMP_SLOT arm_callee1 |
| 377 | // CHECK-DSO-REL-NEXT: 0x18B8 R_ARM_JUMP_SLOT arm_callee2 | 377 | // CHECK-DSO-REL-NEXT: 0x18D8 R_ARM_JUMP_SLOT arm_callee2 |
| 378 | // CHECK-DSO-REL-NEXT: 0x18BC R_ARM_JUMP_SLOT arm_callee3 | 378 | // CHECK-DSO-REL-NEXT: 0x18DC R_ARM_JUMP_SLOT arm_callee3 |
deps/lld/test/ELF/arm-thumb-mix-range-thunk-os.s+10-12| ... | @@ -11,7 +11,7 @@ | ... | @@ -11,7 +11,7 @@ |
| 11 | // RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651590 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s | 11 | // RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651590 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s |
| 12 | // RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700168 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s | 12 | // RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700168 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s |
| 13 | // RUN: llvm-objdump -d %t2 -start-address=48234500 -stop-address=48234512 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s | 13 | // RUN: llvm-objdump -d %t2 -start-address=48234500 -stop-address=48234512 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s |
| 14 | // RUN: llvm-objdump -d %t2 -start-address=63963140 -stop-address=63963160 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s | 14 | // RUN: llvm-objdump -d %t2 -start-address=53477380 -stop-address=53477392 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s |
| 15 | // RUN: llvm-objdump -d %t2 -start-address=68157440 -stop-address=68157452 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s | 15 | // RUN: llvm-objdump -d %t2 -start-address=68157440 -stop-address=68157452 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s |
| 16 | // RUN: llvm-objdump -d %t2 -start-address=69206016 -stop-address=69206024 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK11 %s | 16 | // RUN: llvm-objdump -d %t2 -start-address=69206016 -stop-address=69206024 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK11 %s |
| 17 | 17 | ||
| ... | @@ -155,6 +155,13 @@ _start: | ... | @@ -155,6 +155,13 @@ _start: |
| 155 | ARMFUNCTION 48 | 155 | ARMFUNCTION 48 |
| 156 | THUMBFUNCTION 49 | 156 | THUMBFUNCTION 49 |
| 157 | ARMFUNCTION 50 | 157 | ARMFUNCTION 50 |
| 158 | // Expect precreated Thunk Section here | ||
| 159 | // CHECK9: __Thumbv7ABSLongThunk_afunc34: | ||
| 160 | // CHECK9-NEXT: 3300004: 40 f2 00 0c movw r12, #0 | ||
| 161 | // CHECK9-NEXT: 3300008: c0 f2 30 2c movt r12, #560 | ||
| 162 | // CHECK9-NEXT: 330000c: 60 47 bx r12 | ||
| 163 | // CHECK9: __Thumbv7ABSLongThunk_tfunc35: | ||
| 164 | // CHECK9-NEXT: 330000e: ff f4 f7 97 b.w #-15728658 <tfunc35> | ||
| 158 | THUMBFUNCTION 51 | 165 | THUMBFUNCTION 51 |
| 159 | ARMFUNCTION 52 | 166 | ARMFUNCTION 52 |
| 160 | THUMBFUNCTION 53 | 167 | THUMBFUNCTION 53 |
| ... | @@ -165,15 +172,6 @@ _start: | ... | @@ -165,15 +172,6 @@ _start: |
| 165 | ARMFUNCTION 58 | 172 | ARMFUNCTION 58 |
| 166 | THUMBFUNCTION 59 | 173 | THUMBFUNCTION 59 |
| 167 | ARMFUNCTION 60 | 174 | ARMFUNCTION 60 |
| 168 | // Expect precreated Thunk Section here | ||
| 169 | // CHECK9: __Thumbv7ABSLongThunk_afunc34: | ||
| 170 | // CHECK9-NEXT: 3d00004: 40 f2 00 0c movw r12, #0 | ||
| 171 | // CHECK9-NEXT: 3d00008: c0 f2 30 2c movt r12, #560 | ||
| 172 | // CHECK9-NEXT: 3d0000c: 60 47 bx r12 | ||
| 173 | // CHECK9: __Thumbv7ABSLongThunk_tfunc35: | ||
| 174 | // CHECK9-NEXT: 3d0000e: 40 f2 01 0c movw r12, #1 | ||
| 175 | // CHECK9-NEXT: 3d00012: c0 f2 40 2c movt r12, #576 | ||
| 176 | // CHECK9-NEXT: 3d00016: 60 47 bx r12 | ||
| 177 | THUMBFUNCTION 61 | 175 | THUMBFUNCTION 61 |
| 178 | ARMFUNCTION 62 | 176 | ARMFUNCTION 62 |
| 179 | THUMBFUNCTION 63 | 177 | THUMBFUNCTION 63 |
| ... | @@ -191,5 +189,5 @@ _start: | ... | @@ -191,5 +189,5 @@ _start: |
| 191 | bl tfunc35 | 189 | bl tfunc35 |
| 192 | // CHECK11: tfunc65: | 190 | // CHECK11: tfunc65: |
| 193 | // CHECK11: 4200000: 70 47 bx lr | 191 | // CHECK11: 4200000: 70 47 bx lr |
| 194 | // CHECK11-NEXT: 4200002: ff f6 ff f7 bl #-5242882 | 192 | // CHECK11-NEXT: 4200002: ff f4 ff d7 bl #-15728642 |
| 195 | // CHECK11-NEXT: 4200006: 00 f7 02 f0 bl #-5242876 | 193 | // CHECK11-NEXT: 4200006: 00 f5 02 d0 bl #-15728636 |
deps/lld/test/ELF/arm-thumb-narrow-branch-check.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: echo "SECTIONS { \ | 3 | // RUN: echo "SECTIONS { \ |
| 3 | // RUN: . = SIZEOF_HEADERS; \ | 4 | // RUN: . = SIZEOF_HEADERS; \ |
| ... | @@ -7,7 +8,6 @@ | ... | @@ -7,7 +8,6 @@ |
| 7 | // RUN: .text : { *(.text) } } " > %t.script | 8 | // RUN: .text : { *(.text) } } " > %t.script |
| 8 | // RUN: ld.lld --script %t.script %t %S/Inputs/arm-thumb-narrow-branch.o -o %t2 2>&1 | 9 | // RUN: ld.lld --script %t.script %t %S/Inputs/arm-thumb-narrow-branch.o -o %t2 2>&1 |
| 9 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s | 10 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 10 | // REQUIRES: arm | ||
| 11 | 11 | ||
| 12 | // Test the R_ARM_PC11 relocation which is used with the narrow encoding of B.N | 12 | // Test the R_ARM_PC11 relocation which is used with the narrow encoding of B.N |
| 13 | // the source of these relocations is a binary file arm-thumb-narrow-branch.o | 13 | // the source of these relocations is a binary file arm-thumb-narrow-branch.o |
deps/lld/test/ELF/arm-thumb-no-undefined-thunk.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t2 | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | 5 | ||
| 6 | // Check that no thunks are created for an undefined weak symbol | 6 | // Check that no thunks are created for an undefined weak symbol |
| 7 | .syntax unified | 7 | .syntax unified |
deps/lld/test/ELF/arm-thumb-plt-range-thunk-os.s+66-44| ... | @@ -1,12 +1,12 @@ | ... | @@ -1,12 +1,12 @@ |
| 1 | // REQUIRES: arm | 1 | // REQUIRES: arm |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 3 | // RUN: ld.lld %t --shared -o %t.so | 3 | // RUN: ld.lld %t --shared --icf=all -o %t.so |
| 4 | // The output file is large, most of it zeroes. We dissassemble only the | 4 | // The output file is large, most of it zeroes. We dissassemble only the |
| 5 | // parts we need to speed up the test and avoid a large output file | 5 | // parts we need to speed up the test and avoid a large output file |
| 6 | // RUN: llvm-objdump -d %t.so -start-address=8388608 -stop-address=8388624 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | 6 | // RUN: llvm-objdump -d %t.so -start-address=0x2000000 -stop-address=0x2000018 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s |
| 7 | // RUN: llvm-objdump -d %t.so -start-address=16777216 -stop-address=16777256 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | 7 | // RUN: llvm-objdump -d %t.so -start-address=0x2800004 -stop-address=0x2800034 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s |
| 8 | // RUN: llvm-objdump -d %t.so -start-address=25165824 -stop-address=25165828 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s | 8 | // RUN: llvm-objdump -d %t.so -start-address=0x4000000 -stop-address=0x4000010 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s |
| 9 | // RUN: llvm-objdump -d %t.so -start-address=25165828 -stop-address=25165924 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s | 9 | // RUN: llvm-objdump -d %t.so -start-address=0x4000010 -stop-address=0x4000100 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s |
| 10 | .syntax unified | 10 | .syntax unified |
| 11 | .thumb | 11 | .thumb |
| 12 | 12 | ||
| ... | @@ -19,74 +19,96 @@ | ... | @@ -19,74 +19,96 @@ |
| 19 | .type preemptible, %function | 19 | .type preemptible, %function |
| 20 | .global far_preemptible | 20 | .global far_preemptible |
| 21 | .type far_preemptible, %function | 21 | .type far_preemptible, %function |
| 22 | .global far_nonpreemptible | ||
| 23 | .hidden far_nonpreemptible | ||
| 24 | .type far_nonpreemptible, %function | ||
| 25 | .global far_nonpreemptible_alias | ||
| 26 | .hidden far_nonpreemptible_alias | ||
| 27 | .type far_nonpreemptible_alias, %function | ||
| 22 | sym1: | 28 | sym1: |
| 23 | bl elsewhere | 29 | bl elsewhere |
| 24 | bl preemptible | 30 | bl preemptible |
| 25 | bx lr | 31 | bx lr |
| 26 | preemptible: | 32 | preemptible: |
| 27 | bl far_preemptible | 33 | bl far_preemptible |
| 34 | bl far_nonpreemptible | ||
| 35 | bl far_nonpreemptible_alias | ||
| 28 | bx lr | 36 | bx lr |
| 29 | // CHECK1: Disassembly of section .text: | 37 | // CHECK1: Disassembly of section .text: |
| 30 | // CHECK1-NEXT: sym1: | 38 | // CHECK1-NEXT: sym1: |
| 31 | // CHECK1-NEXT: 800000: 00 f0 00 d8 bl #8388608 | 39 | // CHECK1-NEXT: 2000000: 00 f0 00 d8 bl #8388608 |
| 32 | // CHECK1-NEXT: 800004: 00 f0 04 d8 bl #8388616 | 40 | // CHECK1-NEXT: 2000004: 00 f0 04 d8 bl #8388616 |
| 33 | // CHECK1-NEXT: 800008: 70 47 bx lr | 41 | // CHECK1-NEXT: 2000008: 70 47 bx lr |
| 34 | // CHECK1: preemptible: | 42 | // CHECK1: preemptible: |
| 35 | // CHECK1-NEXT: 80000a: 00 f0 07 d8 bl #8388622 | 43 | // CHECK1-NEXT: 200000a: 00 f0 07 d8 bl #8388622 |
| 36 | // CHECK1-NEXT: 80000e: 70 47 bx lr | 44 | // CHECK1-NEXT: 200000e: 00 f0 0b d8 bl #8388630 |
| 45 | // CHECK1-NEXT: 2000012: 00 f0 09 d8 bl #8388626 | ||
| 46 | // CHECK1-NEXT: 2000016: 70 47 bx lr | ||
| 37 | 47 | ||
| 38 | .section .text.2, "ax", %progbits | 48 | .section .text.2, "ax", %progbits |
| 39 | .balign 0x0800000 | 49 | .balign 0x0800000 |
| 40 | bx lr | 50 | bx lr |
| 41 | // CHECK2: __ThumbV7PILongThunk_elsewhere: | 51 | // CHECK2: __ThumbV7PILongThunk_elsewhere: |
| 42 | // CHECK2-NEXT: 1000004: 40 f2 20 0c movw r12, #32 | 52 | // CHECK2-NEXT: 2800004: 40 f2 20 0c movw r12, #32 |
| 43 | // CHECK2-NEXT: 1000008: c0 f2 80 0c movt r12, #128 | 53 | // CHECK2-NEXT: 2800008: c0 f2 80 1c movt r12, #384 |
| 44 | // CHECK2-NEXT: 100000c: fc 44 add r12, pc | 54 | // CHECK2-NEXT: 280000c: fc 44 add r12, pc |
| 45 | // CHECK2-NEXT: 100000e: 60 47 bx r12 | 55 | // CHECK2-NEXT: 280000e: 60 47 bx r12 |
| 46 | // CHECK2: __ThumbV7PILongThunk_preemptible: | 56 | // CHECK2: __ThumbV7PILongThunk_preemptible: |
| 47 | // CHECK2-NEXT: 1000010: 40 f2 24 0c movw r12, #36 | 57 | // CHECK2-NEXT: 2800010: 40 f2 24 0c movw r12, #36 |
| 48 | // CHECK2-NEXT: 1000014: c0 f2 80 0c movt r12, #128 | 58 | // CHECK2-NEXT: 2800014: c0 f2 80 1c movt r12, #384 |
| 49 | // CHECK2-NEXT: 1000018: fc 44 add r12, pc | 59 | // CHECK2-NEXT: 2800018: fc 44 add r12, pc |
| 50 | // CHECK2-NEXT: 100001a: 60 47 bx r12 | 60 | // CHECK2-NEXT: 280001a: 60 47 bx r12 |
| 51 | // CHECK2: __ThumbV7PILongThunk_far_preemptible: | 61 | // CHECK2: __ThumbV7PILongThunk_far_preemptible: |
| 52 | // CHECK2-NEXT: 100001c: 40 f2 28 0c movw r12, #40 | 62 | // CHECK2-NEXT: 280001c: 40 f2 28 0c movw r12, #40 |
| 53 | // CHECK2-NEXT: 1000020: c0 f2 80 0c movt r12, #128 | 63 | // CHECK2-NEXT: 2800020: c0 f2 80 1c movt r12, #384 |
| 54 | // CHECK2-NEXT: 1000024: fc 44 add r12, pc | 64 | // CHECK2-NEXT: 2800024: fc 44 add r12, pc |
| 55 | // CHECK2-NEXT: 1000026: 60 47 bx r12 | 65 | // CHECK2-NEXT: 2800026: 60 47 bx r12 |
| 66 | // CHECK2: __ThumbV7PILongThunk_far_nonpreemptible: | ||
| 67 | // CHECK2-NEXT: 2800028: 4f f6 cd 7c movw r12, #65485 | ||
| 68 | // CHECK2-NEXT: 280002c: c0 f2 7f 1c movt r12, #383 | ||
| 69 | // CHECK2-NEXT: 2800030: fc 44 add r12, pc | ||
| 70 | // CHECK2-NEXT: 2800032: 60 47 bx r12 | ||
| 56 | 71 | ||
| 57 | .section .text.3, "ax", %progbits | 72 | .section .text.3, "ax", %progbits |
| 58 | .balign 0x0800000 | 73 | .balign 0x2000000 |
| 59 | far_preemptible: | 74 | far_preemptible: |
| 75 | far_nonpreemptible: | ||
| 60 | bl elsewhere | 76 | bl elsewhere |
| 77 | |||
| 78 | .section .text.4, "ax", %progbits | ||
| 79 | .balign 0x2000000 | ||
| 80 | far_nonpreemptible_alias: | ||
| 81 | bl elsewhere | ||
| 82 | |||
| 61 | // CHECK3: far_preemptible: | 83 | // CHECK3: far_preemptible: |
| 62 | // CHECK3: 1800000: 00 f0 16 e8 blx #44 | 84 | // CHECK3: 4000000: 00 f0 16 e8 blx #44 |
| 63 | 85 | ||
| 64 | // CHECK4: Disassembly of section .plt: | 86 | // CHECK4: Disassembly of section .plt: |
| 65 | // CHECK4-NEXT: $a: | 87 | // CHECK4-NEXT: $a: |
| 66 | // CHECK4-NEXT: 1800010:	04 e0 2d e5 	str	lr, [sp, #-4]! | 88 | // CHECK4-NEXT: 4000010:	04 e0 2d e5 	str	lr, [sp, #-4]! |
| 67 | // CHECK4-NEXT: 1800014:	00 e6 8f e2 	add	lr, pc, #0, #12 | 89 | // CHECK4-NEXT: 4000014:	00 e6 8f e2 	add	lr, pc, #0, #12 |
| 68 | // CHECK4-NEXT: 1800018:	00 ea 8e e2 	add	lr, lr, #0, #20 | 90 | // CHECK4-NEXT: 4000018:	00 ea 8e e2 	add	lr, lr, #0, #20 |
| 69 | // CHECK4-NEXT: 180001c:	ec ff be e5 	ldr	pc, [lr, #4076]! | 91 | // CHECK4-NEXT: 400001c:	ec ff be e5 	ldr	pc, [lr, #4076]! |
| 70 | // CHECK4: $d: | 92 | // CHECK4: $d: |
| 71 | // CHECK4-NEXT: 1800020:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | 93 | // CHECK4-NEXT: 4000020:	d4 d4 d4 d4 	.word	0xd4d4d4d4 |
| 72 | // CHECK4-NEXT: 1800024:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | 94 | // CHECK4-NEXT: 4000024:	d4 d4 d4 d4 	.word	0xd4d4d4d4 |
| 73 | // CHECK4-NEXT: 1800028:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | 95 | // CHECK4-NEXT: 4000028:	d4 d4 d4 d4 	.word	0xd4d4d4d4 |
| 74 | // CHECK4-NEXT: 180002c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | 96 | // CHECK4-NEXT: 400002c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 |
| 75 | // CHECK4: $a: | 97 | // CHECK4: $a: |
| 76 | // CHECK4-NEXT: 1800030:	00 c6 8f e2 	add	r12, pc, #0, #12 | 98 | // CHECK4-NEXT: 4000030:	00 c6 8f e2 	add	r12, pc, #0, #12 |
| 77 | // CHECK4-NEXT: 1800034:	00 ca 8c e2 	add	r12, r12, #0, #20 | 99 | // CHECK4-NEXT: 4000034:	00 ca 8c e2 	add	r12, r12, #0, #20 |
| 78 | // CHECK4-NEXT: 1800038:	d4 ff bc e5 	ldr	pc, [r12, #4052]! | 100 | // CHECK4-NEXT: 4000038:	d4 ff bc e5 	ldr	pc, [r12, #4052]! |
| 79 | // CHECK4: $d: | 101 | // CHECK4: $d: |
| 80 | // CHECK4-NEXT: 180003c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | 102 | // CHECK4-NEXT: 400003c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 |
| 81 | // CHECK4: $a: | 103 | // CHECK4: $a: |
| 82 | // CHECK4-NEXT: 1800040:	00 c6 8f e2 	add	r12, pc, #0, #12 | 104 | // CHECK4-NEXT: 4000040:	00 c6 8f e2 	add	r12, pc, #0, #12 |
| 83 | // CHECK4-NEXT: 1800044:	00 ca 8c e2 	add	r12, r12, #0, #20 | 105 | // CHECK4-NEXT: 4000044:	00 ca 8c e2 	add	r12, r12, #0, #20 |
| 84 | // CHECK4-NEXT: 1800048:	c8 ff bc e5 	ldr	pc, [r12, #4040]! | 106 | // CHECK4-NEXT: 4000048:	c8 ff bc e5 	ldr	pc, [r12, #4040]! |
| 85 | // CHECK4: $d: | 107 | // CHECK4: $d: |
| 86 | // CHECK4-NEXT: 180004c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | 108 | // CHECK4-NEXT: 400004c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 |
| 87 | // CHECK4: $a: | 109 | // CHECK4: $a: |
| 88 | // CHECK4-NEXT: 1800050:	00 c6 8f e2 	add	r12, pc, #0, #12 | 110 | // CHECK4-NEXT: 4000050:	00 c6 8f e2 	add	r12, pc, #0, #12 |
| 89 | // CHECK4-NEXT: 1800054:	00 ca 8c e2 	add	r12, r12, #0, #20 | 111 | // CHECK4-NEXT: 4000054:	00 ca 8c e2 	add	r12, r12, #0, #20 |
| 90 | // CHECK4-NEXT: 1800058:	bc ff bc e5 	ldr	pc, [r12, #4028]! | 112 | // CHECK4-NEXT: 4000058:	bc ff bc e5 	ldr	pc, [r12, #4028]! |
| 91 | // CHECK4: $d: | 113 | // CHECK4: $d: |
| 92 | // CHECK4-NEXT: 180005c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 | 114 | // CHECK4-NEXT: 400005c:	d4 d4 d4 d4 	.word	0xd4d4d4d4 |
deps/lld/test/ELF/arm-thumb-plt-reloc.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2 |
| 3 | // RUN: ld.lld %t1 %t2 -o %t | 4 | // RUN: ld.lld %t1 %t2 -o %t |
| ... | @@ -6,7 +7,6 @@ | ... | @@ -6,7 +7,6 @@ |
| 6 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s | 7 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s |
| 7 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s | 8 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s |
| 8 | // RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s | 9 | // RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s |
| 9 | // REQUIRES: arm | ||
| 10 | // | 10 | // |
| 11 | // Test PLT entry generation | 11 | // Test PLT entry generation |
| 12 | .syntax unified | 12 | .syntax unified |
deps/lld/test/ELF/arm-thumb-range-thunk-os.s+26-36| ... | @@ -9,8 +9,8 @@ | ... | @@ -9,8 +9,8 @@ |
| 9 | // RUN: llvm-objdump -d %t2 -start-address=4194304 -stop-address=4194310 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s | 9 | // RUN: llvm-objdump -d %t2 -start-address=4194304 -stop-address=4194310 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s |
| 10 | // RUN: llvm-objdump -d %t2 -start-address=16777216 -stop-address=16777270 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s | 10 | // RUN: llvm-objdump -d %t2 -start-address=16777216 -stop-address=16777270 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s |
| 11 | // RUN: llvm-objdump -d %t2 -start-address=17825792 -stop-address=17825808 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s | 11 | // RUN: llvm-objdump -d %t2 -start-address=17825792 -stop-address=17825808 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s |
| 12 | // RUN: llvm-objdump -d %t2 -start-address=31457280 -stop-address=31457286 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s | 12 | // RUN: llvm-objdump -d %t2 -start-address=20971524 -stop-address=20971532 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s |
| 13 | // RUN: llvm-objdump -d %t2 -start-address=32505860 -stop-address=32505880 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s | 13 | // RUN: llvm-objdump -d %t2 -start-address=31457280 -stop-address=31457286 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s |
| 14 | // RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651594 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s | 14 | // RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651594 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s |
| 15 | // RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700170 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s | 15 | // RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700170 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s |
| 16 | 16 | ||
| ... | @@ -60,7 +60,7 @@ _start: | ... | @@ -60,7 +60,7 @@ _start: |
| 60 | b.w tfunc28 | 60 | b.w tfunc28 |
| 61 | // CHECK4: tfunc02: | 61 | // CHECK4: tfunc02: |
| 62 | // CHECK4-NEXT: 400000: 70 47 bx lr | 62 | // CHECK4-NEXT: 400000: 70 47 bx lr |
| 63 | // CHECK4-NEXT: 400002: 00 f0 04 90 b.w #12582920 <__Thumbv7ABSLongThunk_tfunc28> | 63 | // CHECK4-NEXT: 400002: 00 f0 01 90 b.w #12582914 <__Thumbv7ABSLongThunk_tfunc28> |
| 64 | FUNCTION 03 | 64 | FUNCTION 03 |
| 65 | FUNCTION 04 | 65 | FUNCTION 04 |
| 66 | FUNCTION 05 | 66 | FUNCTION 05 |
| ... | @@ -75,25 +75,19 @@ _start: | ... | @@ -75,25 +75,19 @@ _start: |
| 75 | FUNCTION 14 | 75 | FUNCTION 14 |
| 76 | // Expect precreated ThunkSection here | 76 | // Expect precreated ThunkSection here |
| 77 | // CHECK5: __Thumbv7ABSLongThunk_tfunc16: | 77 | // CHECK5: __Thumbv7ABSLongThunk_tfunc16: |
| 78 | // CHECK5-NEXT: 1000004: 40 f2 01 0c movw r12, #1 | 78 | // CHECK5-NEXT: 1000004: ff f1 fc bf b.w #2097144 <tfunc16> |
| 79 | // CHECK5-NEXT: 1000008: c0 f2 20 1c movt r12, #288 | ||
| 80 | // CHECK5-NEXT: 100000c: 60 47 bx r12 | ||
| 81 | // CHECK5: __Thumbv7ABSLongThunk_tfunc28: | 79 | // CHECK5: __Thumbv7ABSLongThunk_tfunc28: |
| 82 | // CHECK5-NEXT: 100000e: 40 f2 01 0c movw r12, #1 | 80 | // CHECK5-NEXT: 1000008: ff f1 fa 97 b.w #14680052 <tfunc28> |
| 83 | // CHECK5-NEXT: 1000012: c0 f2 e0 1c movt r12, #480 | ||
| 84 | // CHECK5-NEXT: 1000016: 60 47 bx r12 | ||
| 85 | // CHECK5: __Thumbv7ABSLongThunk_tfunc32: | 81 | // CHECK5: __Thumbv7ABSLongThunk_tfunc32: |
| 86 | // CHECK5-NEXT: 1000018: 40 f2 01 0c movw r12, #1 | 82 | // CHECK5-NEXT: 100000c: 40 f2 01 0c movw r12, #1 |
| 87 | // CHECK5-NEXT: 100001c: c0 f2 20 2c movt r12, #544 | 83 | // CHECK5-NEXT: 1000010: c0 f2 20 2c movt r12, #544 |
| 88 | // CHECK5-NEXT: 1000020: 60 47 bx r12 | 84 | // CHECK5-NEXT: 1000014: 60 47 bx r12 |
| 89 | // CHECK5: __Thumbv7ABSLongThunk_tfunc33: | 85 | // CHECK5: __Thumbv7ABSLongThunk_tfunc33: |
| 90 | // CHECK5-NEXT: 1000022: 40 f2 01 0c movw r12, #1 | 86 | // CHECK5-NEXT: 1000016: 40 f2 01 0c movw r12, #1 |
| 91 | // CHECK5-NEXT: 1000026: c0 f2 30 2c movt r12, #560 | 87 | // CHECK5-NEXT: 100001a: c0 f2 30 2c movt r12, #560 |
| 92 | // CHECK5-NEXT: 100002a: 60 47 bx r12 | 88 | // CHECK5-NEXT: 100001e: 60 47 bx r12 |
| 93 | // CHECK5: __Thumbv7ABSLongThunk_tfunc02: | 89 | // CHECK5: __Thumbv7ABSLongThunk_tfunc02: |
| 94 | // CHECK5-NEXT: 100002c: 40 f2 01 0c movw r12, #1 | 90 | // CHECK5-NEXT: 1000020: ff f7 ee 97 b.w #-12582948 <tfunc02> |
| 95 | // CHECK5-NEXT: 1000030: c0 f2 40 0c movt r12, #64 | ||
| 96 | // CHECK5-NEXT: 1000034: 60 47 bx r12 | ||
| 97 | FUNCTION 15 | 91 | FUNCTION 15 |
| 98 | // tfunc00 and tfunc01 are < 16Mb away, expect no range extension thunks | 92 | // tfunc00 and tfunc01 are < 16Mb away, expect no range extension thunks |
| 99 | bl tfunc00 | 93 | bl tfunc00 |
| ... | @@ -106,11 +100,16 @@ _start: | ... | @@ -106,11 +100,16 @@ _start: |
| 106 | // CHECK6-NEXT: 1100000: 70 47 bx lr | 100 | // CHECK6-NEXT: 1100000: 70 47 bx lr |
| 107 | // CHECK6-NEXT: 1100002: ff f4 fd d7 bl #-15728646 | 101 | // CHECK6-NEXT: 1100002: ff f4 fd d7 bl #-15728646 |
| 108 | // CHECK6-NEXT: 1100006: ff f5 fb d7 bl #-14680074 | 102 | // CHECK6-NEXT: 1100006: ff f5 fb d7 bl #-14680074 |
| 109 | // CHECK6-NEXT: 110000a: 00 f7 05 f8 bl #-1048566 | 103 | // CHECK6-NEXT: 110000a: ff f6 ff ff bl #-1048578 |
| 110 | // CHECK6-NEXT: 110000e: 00 f7 08 f8 bl #-1048560 | 104 | // CHECK6-NEXT: 110000e: 00 f7 02 f8 bl #-1048572 |
| 111 | FUNCTION 16 | 105 | FUNCTION 16 |
| 112 | FUNCTION 17 | 106 | FUNCTION 17 |
| 113 | FUNCTION 18 | 107 | FUNCTION 18 |
| 108 | // Expect another precreated thunk section here | ||
| 109 | // CHECK7: __Thumbv7ABSLongThunk_tfunc15: | ||
| 110 | // CHECK7-NEXT: 1400004: ff f4 fc bf b.w #-3145736 <tfunc15> | ||
| 111 | // CHECK7: __Thumbv7ABSLongThunk_tfunc16: | ||
| 112 | // CHECK7-NEXT: 1400008: ff f5 fa bf b.w #-2097164 <tfunc16> | ||
| 114 | FUNCTION 19 | 113 | FUNCTION 19 |
| 115 | FUNCTION 20 | 114 | FUNCTION 20 |
| 116 | FUNCTION 21 | 115 | FUNCTION 21 |
| ... | @@ -123,21 +122,12 @@ _start: | ... | @@ -123,21 +122,12 @@ _start: |
| 123 | FUNCTION 28 | 122 | FUNCTION 28 |
| 124 | // tfunc02 is > 16Mb away, expect range extension thunks in precreated thunk | 123 | // tfunc02 is > 16Mb away, expect range extension thunks in precreated thunk |
| 125 | // section | 124 | // section |
| 126 | // CHECK7: tfunc28: | 125 | // CHECK8: tfunc28: |
| 127 | // CHECK7-NEXT: 1e00000: 70 47 bx lr | 126 | // CHECK8-NEXT: 1e00000: 70 47 bx lr |
| 128 | // CHECK7-NEXT: 1e00002: 00 f6 13 90 b.w #-14680026 <__Thumbv7ABSLongThunk_tfunc02> | 127 | // CHECK8-NEXT: 1e00002: 00 f6 0d 90 b.w #-14680038 <__Thumbv7ABSLongThunk_tfunc02> |
| 129 | 128 | ||
| 130 | b.w tfunc02 | 129 | b.w tfunc02 |
| 131 | FUNCTION 29 | 130 | FUNCTION 29 |
| 132 | // Expect another precreated thunk section here | ||
| 133 | // CHECK8: __Thumbv7ABSLongThunk_tfunc15: | ||
| 134 | // CHECK8-NEXT: 1f00004: 40 f2 01 0c movw r12, #1 | ||
| 135 | // CHECK8-NEXT: 1f00008: c0 f2 10 1c movt r12, #272 | ||
| 136 | // CHECK8-NEXT: 1f0000c: 60 47 bx r12 | ||
| 137 | // CHECK8: __Thumbv7ABSLongThunk_tfunc16: | ||
| 138 | // CHECK8-NEXT: 1f0000e: 40 f2 01 0c movw r12, #1 | ||
| 139 | // CHECK8-NEXT: 1f00012: c0 f2 20 1c movt r12, #288 | ||
| 140 | // CHECK8-NEXT: 1f00016: 60 47 bx r12 | ||
| 141 | FUNCTION 30 | 131 | FUNCTION 30 |
| 142 | FUNCTION 31 | 132 | FUNCTION 31 |
| 143 | FUNCTION 32 | 133 | FUNCTION 32 |
| ... | @@ -147,13 +137,13 @@ _start: | ... | @@ -147,13 +137,13 @@ _start: |
| 147 | bl tfunc16 | 137 | bl tfunc16 |
| 148 | // CHECK9: tfunc32: | 138 | // CHECK9: tfunc32: |
| 149 | // CHECK9: 2200000: 70 47 bx lr | 139 | // CHECK9: 2200000: 70 47 bx lr |
| 150 | // CHECK9-NEXT: 2200002: ff f4 ff ff bl #-3145730 | 140 | // CHECK9-NEXT: 2200002: ff f5 ff d7 bl #-14680066 |
| 151 | // CHECK9-NEXT: 2200006: 00 f5 02 f8 bl #-3145724 | 141 | // CHECK9-NEXT: 2200006: ff f5 ff d7 bl #-14680066 |
| 152 | 142 | ||
| 153 | FUNCTION 33 | 143 | FUNCTION 33 |
| 154 | bl tfunc15 | 144 | bl tfunc15 |
| 155 | bl tfunc16 | 145 | bl tfunc16 |
| 156 | // CHECK10: tfunc33: | 146 | // CHECK10: tfunc33: |
| 157 | // CHECK10: 2300000: 70 47 bx lr | 147 | // CHECK10: 2300000: 70 47 bx lr |
| 158 | // CHECK10-NEXT: 2300002: ff f7 ff f7 bl #-4194306 | 148 | // CHECK10-NEXT: 2300002: ff f4 ff d7 bl #-15728642 |
| 159 | // CHECK10-NEXT: 2300006: 00 f4 02 f8 bl #-4194300 | 149 | // CHECK10-NEXT: 2300006: ff f4 ff d7 bl #-15728642 |
deps/lld/test/ELF/arm-thumb-thunk-empty-pass.s+6-8| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 3 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 4 | // RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | 4 | // RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s |
| 5 | // RUN: llvm-objdump -d %t2 -start-address=16846860 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | 5 | // RUN: llvm-objdump -d %t2 -start-address=16846856 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s |
| 6 | .syntax unified | 6 | .syntax unified |
| 7 | .global _start, foo | 7 | .global _start, foo |
| 8 | .type _start, %function | 8 | .type _start, %function |
| ... | @@ -20,13 +20,11 @@ foo: | ... | @@ -20,13 +20,11 @@ foo: |
| 20 | // CHECK1-NEXT: _start: | 20 | // CHECK1-NEXT: _start: |
| 21 | // CHECK1-NEXT: 11000: ff f7 fe ff bl #-4 | 21 | // CHECK1-NEXT: 11000: ff f7 fe ff bl #-4 |
| 22 | // CHECK1: __Thumbv7ABSLongThunk__start: | 22 | // CHECK1: __Thumbv7ABSLongThunk__start: |
| 23 | // CHECK1-NEXT: 11004: 41 f2 01 0c movw r12, #4097 | 23 | // CHECK1-NEXT: 11004: ff f7 fc bf b.w #-8 <_start> |
| 24 | // CHECK1-NEXT: 11008: c0 f2 01 0c movt r12, #1 | ||
| 25 | // CHECK1-NEXT: 1100c: 60 47 bx r12 | ||
| 26 | 24 | ||
| 27 | // CHECK2: __Thumbv7ABSLongThunk__start: | 25 | // CHECK2: __Thumbv7ABSLongThunk__start: |
| 28 | // CHECK2: 101100c: 41 f2 01 0c movw r12, #4097 | 26 | // CHECK2: 1011008: 41 f2 01 0c movw r12, #4097 |
| 29 | // CHECK2-NEXT: 1011010: c0 f2 01 0c movt r12, #1 | 27 | // CHECK2-NEXT: 101100c: c0 f2 01 0c movt r12, #1 |
| 30 | // CHECK2-NEXT: 1011014: 60 47 bx r12 | 28 | // CHECK2-NEXT: 1011010: 60 47 bx r12 |
| 31 | // CHECK2: foo: | 29 | // CHECK2: foo: |
| 32 | // CHECK2-NEXT: 1011016: ff f7 f9 ff bl #-14 | 30 | // CHECK2-NEXT: 1011012: ff f7 f9 ff bl #-14 |
deps/lld/test/ELF/arm-thumb-thunk-symbols.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-readobj --symbols %t2 | FileCheck %s | 4 | // RUN: llvm-readobj --symbols %t2 | FileCheck %s |
| 4 | // RUN: ld.lld --shared %t -o %t3 2>&1 | 5 | // RUN: ld.lld --shared %t -o %t3 2>&1 |
| 5 | // RUN: llvm-readobj --symbols %t3 | FileCheck -check-prefix=CHECK-PI %s | 6 | // RUN: llvm-readobj --symbols %t3 | FileCheck -check-prefix=CHECK-PI %s |
| 6 | // REQUIRES: arm | ||
| 7 | 7 | ||
| 8 | // Check that the symbols generated for Thunks have the correct symbol type | 8 | // Check that the symbols generated for Thunks have the correct symbol type |
| 9 | // of STT_FUNC and the correct value of bit 0 (0 for ARM 1 for Thumb) | 9 | // of STT_FUNC and the correct value of bit 0 (0 for ARM 1 for Thumb) |
deps/lld/test/ELF/arm-thumb-undefined-weak.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t2 | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | 5 | ||
| 6 | // Check that the ARM ABI rules for undefined weak symbols are applied. | 6 | // Check that the ARM ABI rules for undefined weak symbols are applied. |
| 7 | // Branch instructions are resolved to the next instruction. Relative | 7 | // Branch instructions are resolved to the next instruction. Relative |
deps/lld/test/ELF/arm-thunk-largesection.s+10-12| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s | 4 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s |
| 4 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=73732 -stop-address=73742 %t2 | FileCheck -check-prefix=CHECK2 %s | 5 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=73732 -stop-address=73742 %t2 | FileCheck -check-prefix=CHECK2 %s |
| 5 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=16850944 -stop-address=16850948 %t2 | FileCheck -check-prefix=CHECK3 %s | 6 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=16850936 -stop-address=16850940 %t2 | FileCheck -check-prefix=CHECK3 %s |
| 6 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=33628160 -stop-address=33628164 %t2 | FileCheck -check-prefix=CHECK4 %s | 7 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=33628152 -stop-address=33628156 %t2 | FileCheck -check-prefix=CHECK4 %s |
| 7 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=50405364 -stop-address=50405376 %t2 | FileCheck -check-prefix=CHECK5 %s | 8 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=50405356 -stop-address=50405376 %t2 | FileCheck -check-prefix=CHECK5 %s |
| 8 | // REQUIRES: arm | ||
| 9 | .syntax unified | 9 | .syntax unified |
| 10 | .balign 0x1000 | 10 | .balign 0x1000 |
| 11 | .thumb | 11 | .thumb |
| ... | @@ -21,9 +21,7 @@ _start: | ... | @@ -21,9 +21,7 @@ _start: |
| 21 | // CHECK1-NEXT: 11002: 00 00 movs r0, r0 | 21 | // CHECK1-NEXT: 11002: 00 00 movs r0, r0 |
| 22 | 22 | ||
| 23 | // CHECK2: __Thumbv7ABSLongThunk__start: | 23 | // CHECK2: __Thumbv7ABSLongThunk__start: |
| 24 | // CHECK2-NEXT: 12004: 41 f2 01 0c movw r12, #4097 | 24 | // CHECK2-NEXT: 12004: fe f7 fc bf b.w #-4104 <_start> |
| 25 | // CHECK2-NEXT: 12008: c0 f2 01 0c movt r12, #1 | ||
| 26 | // CHECK2-NEXT: 1200c: 60 47 bx r12 | ||
| 27 | 25 | ||
| 28 | // Gigantic section where we need a ThunkSection either side of it | 26 | // Gigantic section where we need a ThunkSection either side of it |
| 29 | .section .text.large1, "ax", %progbits | 27 | .section .text.large1, "ax", %progbits |
| ... | @@ -33,10 +31,10 @@ _start: | ... | @@ -33,10 +31,10 @@ _start: |
| 33 | .space (16 * 1024 * 1024) - 4 | 31 | .space (16 * 1024 * 1024) - 4 |
| 34 | bl _start | 32 | bl _start |
| 35 | .space (16 * 1024 * 1024) - 16 | 33 | .space (16 * 1024 * 1024) - 16 |
| 36 | // CHECK3: 1012000: 00 f4 00 d0 bl #-16777216 | 34 | // CHECK3: 1011ff8: 00 f4 04 d0 bl #-16777208 |
| 37 | // CHECK4: 2012000: ff f3 f8 d7 bl #16777200 | 35 | // CHECK4: 2011ff8: ff f3 f8 d7 bl #16777200 |
| 38 | 36 | ||
| 39 | // CHECK5: __Thumbv7ABSLongThunk__start: | 37 | // CHECK5: __Thumbv7ABSLongThunk__start: |
| 40 | // CHECK5-NEXT: 3011ff4: 41 f2 01 0c movw r12, #4097 | 38 | // CHECK5-NEXT: 3011fec: 41 f2 01 0c movw r12, #4097 |
| 41 | // CHECK5-NEXT: 3011ff8: c0 f2 01 0c movt r12, #1 | 39 | // CHECK5-NEXT: 3011ff0: c0 f2 01 0c movt r12, #1 |
| 42 | // CHECK5-NEXT: 3011ffc: 60 47 bx r12 | 40 | // CHECK5-NEXT: 3011ff4: 60 47 bx r12 |
deps/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: echo "SECTIONS { \ | 3 | // RUN: echo "SECTIONS { \ |
| 3 | // RUN: . = SIZEOF_HEADERS; \ | 4 | // RUN: . = SIZEOF_HEADERS; \ |
| ... | @@ -6,7 +7,6 @@ | ... | @@ -6,7 +7,6 @@ |
| 6 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | 7 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 |
| 7 | // RUN: llvm-objdump -d %t2 -start-address=148 -stop-address=188 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | 8 | // RUN: llvm-objdump -d %t2 -start-address=148 -stop-address=188 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s |
| 8 | // RUN: llvm-objdump -d %t2 -start-address=33554620 -stop-address=33554654 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | 9 | // RUN: llvm-objdump -d %t2 -start-address=33554620 -stop-address=33554654 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s |
| 9 | // REQUIRES: arm | ||
| 10 | // Test that range extension thunks can handle location expressions within | 10 | // Test that range extension thunks can handle location expressions within |
| 11 | // a Section Description | 11 | // a Section Description |
| 12 | .syntax unified | 12 | .syntax unified |
deps/lld/test/ELF/arm-thunk-linkerscript-large.s+1-3| ... | @@ -79,9 +79,7 @@ _start: | ... | @@ -79,9 +79,7 @@ _start: |
| 79 | FUNCTIONL 08 | 79 | FUNCTIONL 08 |
| 80 | FUNCTIONL 09 | 80 | FUNCTIONL 09 |
| 81 | // CHECK3: __Thumbv7ABSLongThunk_tfuncl24: | 81 | // CHECK3: __Thumbv7ABSLongThunk_tfuncl24: |
| 82 | // CHECK3-NEXT: b00004:	40 f2 01 0c 	movw	r12, #1 | 82 | // CHECK3-NEXT: b00004: ff f2 fc 97 b.w #15728632 <tfuncl24> |
| 83 | // CHECK3-NEXT: b00008:	c0 f2 a0 1c 	movt	r12, #416 | ||
| 84 | // CHECK3-NEXT: b0000c:	60 47 	bx	r12 | ||
| 85 | FUNCTIONL 10 | 83 | FUNCTIONL 10 |
| 86 | FUNCTIONL 11 | 84 | FUNCTIONL 11 |
| 87 | FUNCTIONL 12 | 85 | FUNCTIONL 12 |
deps/lld/test/ELF/arm-thunk-linkerscript-sort.s+1-3| ... | @@ -41,9 +41,7 @@ tfunc\suff\(): | ... | @@ -41,9 +41,7 @@ tfunc\suff\(): |
| 41 | FUNCTION 16 | 41 | FUNCTION 16 |
| 42 | FUNCTION 15 | 42 | FUNCTION 15 |
| 43 | // CHECK2: __Thumbv7ABSLongThunk_tfunc31: | 43 | // CHECK2: __Thumbv7ABSLongThunk_tfunc31: |
| 44 | // CHECK2-NEXT: 1000004: 40 f2 01 0c movw r12, #1 | 44 | // CHECK2-NEXT: 1000004: ff f3 fc 97 b.w #16777208 <tfunc31> |
| 45 | // CHECK2-NEXT: 1000008: c0 f2 00 2c movt r12, #512 | ||
| 46 | // CHECK2-NEXT: 100000c: 60 47 bx r12 | ||
| 47 | FUNCTION 14 | 45 | FUNCTION 14 |
| 48 | FUNCTION 13 | 46 | FUNCTION 13 |
| 49 | FUNCTION 12 | 47 | FUNCTION 12 |
deps/lld/test/ELF/arm-thunk-linkerscript.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: echo "SECTIONS { \ | 3 | // RUN: echo "SECTIONS { \ |
| 3 | // RUN: . = SIZEOF_HEADERS; \ | 4 | // RUN: . = SIZEOF_HEADERS; \ |
| ... | @@ -6,7 +7,6 @@ | ... | @@ -6,7 +7,6 @@ |
| 6 | // RUN: } " > %t.script | 7 | // RUN: } " > %t.script |
| 7 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | 8 | // RUN: ld.lld --script %t.script %t -o %t2 2>&1 |
| 8 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s | 9 | // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s |
| 9 | // REQUIRES: arm | ||
| 10 | // Simple test that we can support range extension thunks with linker scripts | 10 | // Simple test that we can support range extension thunks with linker scripts |
| 11 | .syntax unified | 11 | .syntax unified |
| 12 | .section .text_low, "ax", %progbits | 12 | .section .text_low, "ax", %progbits |
deps/lld/test/ELF/arm-thunk-multipass.s+8-12| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | // parts we need to speed up the test and avoid a large output file | 5 | // parts we need to speed up the test and avoid a large output file |
| 6 | // RUN: llvm-objdump -d %t2 -start-address=1048578 -stop-address=1048586 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s | 6 | // RUN: llvm-objdump -d %t2 -start-address=1048578 -stop-address=1048586 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s |
| 7 | // RUN: llvm-objdump -d %t2 -start-address=16777224 -stop-address=16777254 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s | 7 | // RUN: llvm-objdump -d %t2 -start-address=16777224 -stop-address=16777254 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s |
| 8 | // RUN: llvm-objdump -d %t2 -start-address=17825818 -stop-address=17825828 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s | 8 | // RUN: llvm-objdump -d %t2 -start-address=17825812 -stop-address=17825826 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s |
| 9 | // In this test case a branch that is in range and does not need its range | 9 | // In this test case a branch that is in range and does not need its range |
| 10 | // extended can be pushed out of range by another Thunk, necessitating another | 10 | // extended can be pushed out of range by another Thunk, necessitating another |
| 11 | // pass | 11 | // pass |
| ... | @@ -64,19 +64,15 @@ arm_target: | ... | @@ -64,19 +64,15 @@ arm_target: |
| 64 | // CHECK2-NEXT: 100000c: c0 f2 00 1c movt r12, #256 | 64 | // CHECK2-NEXT: 100000c: c0 f2 00 1c movt r12, #256 |
| 65 | // CHECK2-NEXT: 1000010: 60 47 bx r12 | 65 | // CHECK2-NEXT: 1000010: 60 47 bx r12 |
| 66 | // CHECK2: __Thumbv7ABSLongThunk_target: | 66 | // CHECK2: __Thumbv7ABSLongThunk_target: |
| 67 | // CHECK2-NEXT: 1000012: 40 f2 1b 0c movw r12, #27 | 67 | // CHECK2-NEXT: 1000012: ff f0 ff bf b.w #1048574 <target> |
| 68 | // CHECK2-NEXT: 1000016: c0 f2 10 1c movt r12, #272 | ||
| 69 | // CHECK2-NEXT: 100001a: 60 47 bx r12 | ||
| 70 | // CHECK2: __Thumbv7ABSLongThunk_target2: | 68 | // CHECK2: __Thumbv7ABSLongThunk_target2: |
| 71 | // CHECK2-NEXT: 100001c: 40 f2 13 0c movw r12, #19 | 69 | // CHECK2-NEXT: 1000016: ff f4 fc 97 b.w #-15728648 <target2> |
| 72 | // CHECK2-NEXT: 1000020: c0 f2 10 0c movt r12, #16 | ||
| 73 | // CHECK2-NEXT: 1000024: 60 47 bx r12 | ||
| 74 | 70 | ||
| 75 | .section .text.17, "ax", %progbits | 71 | .section .text.17, "ax", %progbits |
| 76 | // Just enough space so that bl target is in range if no extension thunks are | 72 | // Just enough space so that bl target is in range if no extension thunks are |
| 77 | // generated. | 73 | // generated. |
| 78 | 74 | ||
| 79 | .space 0x100000 - 12 | 75 | .space 0x100000 - 6 |
| 80 | 76 | ||
| 81 | .section .text.18, "ax", %progbits | 77 | .section .text.18, "ax", %progbits |
| 82 | .thumb | 78 | .thumb |
| ... | @@ -90,7 +86,7 @@ target: | ... | @@ -90,7 +86,7 @@ target: |
| 90 | nop | 86 | nop |
| 91 | bx lr | 87 | bx lr |
| 92 | // CHECK3: target: | 88 | // CHECK3: target: |
| 93 | // CHECK3-NEXT: 110001a: ff f6 ff ff bl #-1048578 | 89 | // CHECK3-NEXT: 1100014: ff f6 ff ff bl #-1048578 |
| 94 | // CHECK3-NEXT: 110001e: 00 bf nop | 90 | // CHECK3-NEXT: 1100018: 00 bf nop |
| 95 | // CHECK3-NEXT: 1100020: 00 bf nop | 91 | // CHECK3-NEXT: 110001a: 00 bf nop |
| 96 | // CHECK3-NEXT: 1100022: 70 47 bx lr | 92 | // CHECK3-NEXT: 110001c: 70 47 bx lr |
deps/lld/test/ELF/arm-thunk-nosuitable.s created+33| ... | @@ -0,0 +1,33 @@ | ||
| 1 | // REQUIRES: ARM | ||
| 2 | // RUN: llvm-mc %s --arm-add-build-attributes --triple=armv7a-linux-gnueabihf --filetype=obj -o %t.o | ||
| 3 | // RUN: ld.lld %t.o -o %t | ||
| 4 | // RUN: llvm-objdump -triple=thumbv7a-linux-gnueabihf -d -start-address=2166784 -stop-address=2166794 %t | FileCheck %s | ||
| 5 | |||
| 6 | // Create a conditional branch too far away from a precreated thunk | ||
| 7 | // section. This will need a thunk section created within range. | ||
| 8 | .syntax unified | ||
| 9 | .thumb | ||
| 10 | |||
| 11 | .section .text.0, "ax", %progbits | ||
| 12 | .space 2 * 1024 * 1024 | ||
| 13 | .globl _start | ||
| 14 | .type _start, %function | ||
| 15 | _start: | ||
| 16 | // Range of +/- 1 Megabyte, new ThunkSection will need creating after | ||
| 17 | // .text.1 | ||
| 18 | beq.w target | ||
| 19 | .section .text.1, "ax", %progbits | ||
| 20 | bx lr | ||
| 21 | |||
| 22 | // CHECK: _start: | ||
| 23 | // CHECK-NEXT: 211000: 00 f0 00 80 beq.w #0 | ||
| 24 | // CHECK: __Thumbv7ABSLongThunk_target: | ||
| 25 | // CHECK-NEXT: 211004: 00 f0 01 90 b.w #12582914 | ||
| 26 | // CHECK: $t.1: | ||
| 27 | // CHECK-NEXT: 211008: 70 47 bx lr | ||
| 28 | |||
| 29 | .section .text.2, "ax", %progbits | ||
| 30 | .space 12 * 1024 * 1024 | ||
| 31 | .globl target | ||
| 32 | .type target, %function | ||
| 33 | target: bx lr | ||
deps/lld/test/ELF/arm-thunk-section-too-large.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | // REQUIRES: ARM | ||
| 2 | // RUN: llvm-mc %s -triple=armv7a-linux-gnueabihf -arm-add-build-attributes -filetype=obj -o %t.o | ||
| 3 | // RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | // CHECK: InputSection too large for range extension thunk | ||
| 6 | .syntax unified | ||
| 7 | .thumb | ||
| 8 | .text | ||
| 9 | .globl _start | ||
| 10 | .type _start, %function | ||
| 11 | _start: | ||
| 12 | .space 2 * 1024 * 1024 | ||
| 13 | // conditional branch has range of 1 Mb expect error as we can't place | ||
| 14 | // a thunk in range of the branch. | ||
| 15 | beq target | ||
| 16 | .space 2 * 1024 * 1024 | ||
| 17 | |||
| 18 | .section .text.2, "ax", %progbits | ||
| 19 | .globl target | ||
| 20 | .type target, %function | ||
| 21 | target: bx lr | ||
deps/lld/test/ELF/arm-thunk-toolargesection.s+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | ||
| 2 | // RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s | ||
| 3 | // REQUIRES: arm | 1 | // REQUIRES: arm |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t | ||
| 3 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | .syntax unified | 4 | .syntax unified |
| 5 | .balign 0x1000 | 5 | .balign 0x1000 |
| 6 | .thumb | 6 | .thumb |
deps/lld/test/ELF/arm-tls-gd-nonpreemptible.s+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 | 3 | // RUN: ld.lld %t -o %t2 |
| 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 4 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: llvm-objdump -s %t2 | FileCheck %s | 5 | // RUN: llvm-objdump -s %t2 | FileCheck %s |
| 5 | // RUN: ld.lld --hash-style=sysv %t --shared -o %t3.so | 6 | // RUN: ld.lld --hash-style=sysv %t --shared -o %t3.so |
| 6 | // RUN: llvm-objdump -s %t3.so | FileCheck -check-prefix=CHECK-SHARED %s | 7 | // RUN: llvm-objdump -s %t3.so | FileCheck -check-prefix=CHECK-SHARED %s |
| 7 | // REQUIRES: arm | ||
| 8 | 8 | ||
| 9 | // For an executable, we write the module index 1 and the offset into the TLS | 9 | // For an executable, we write the module index 1 and the offset into the TLS |
| 10 | // directly into the GOT. For a shared library we can only write the offset | 10 | // directly into the GOT. For a shared library we can only write the offset |
deps/lld/test/ELF/arm-tls-gd32.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared |
| 3 | // 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 |
| 4 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s | 5 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s |
| 5 | // REQUIRES: arm | ||
| 6 | 6 | ||
| 7 | // Test the handling of the global-dynamic TLS model. Dynamic Loader finds | 7 | // Test the handling of the global-dynamic TLS model. Dynamic Loader finds |
| 8 | // module index R_ARM_TLS_DTPMOD32 and the offset within the module | 8 | // module index R_ARM_TLS_DTPMOD32 and the offset within the module |
deps/lld/test/ELF/arm-tls-ie32.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared |
| 3 | // 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 |
| 4 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s | 5 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s |
| 5 | // REQUIRES: arm | ||
| 6 | 6 | ||
| 7 | // Test the handling of the initial-exec TLS model. Relative location within | 7 | // Test the handling of the initial-exec TLS model. Relative location within |
| 8 | // static TLS is a run-time constant computed by dynamic loader as a result | 8 | // static TLS is a run-time constant computed by dynamic loader as a result |
deps/lld/test/ELF/arm-tls-ldm32.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared |
| 3 | // 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 |
| 4 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s | 5 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s |
| 5 | // REQUIRES: arm | ||
| 6 | 6 | ||
| 7 | // Test the handling of the local-dynamic TLS model. Dynamic loader finds | 7 | // Test the handling of the local-dynamic TLS model. Dynamic loader finds |
| 8 | // module index R_ARM_TLS_DTPMOD32. The offset in the next GOT slot is 0 | 8 | // module index R_ARM_TLS_DTPMOD32. The offset in the next GOT slot is 0 |
deps/lld/test/ELF/arm-tls-le32.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 2 | // RUN: ld.lld %t.o -o %t | 3 | // RUN: ld.lld %t.o -o %t |
| 3 | // 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 |
| 4 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t | FileCheck %s | 5 | // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t | FileCheck %s |
| 5 | // REQUIRES: arm | ||
| 6 | 6 | ||
| 7 | // Test the handling of the local exec TLS model. TLS can be resolved | 7 | // Test the handling of the local exec TLS model. TLS can be resolved |
| 8 | // statically for an application. The code sequences assume a thread pointer | 8 | // statically for an application. The code sequences assume a thread pointer |
deps/lld/test/ELF/arm-tls-norelax-gd-ie.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 |
| 2 | // RUN: ld.lld %t1 --shared -o %t1.so | 3 | // RUN: ld.lld %t1 --shared -o %t1.so |
| 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 4 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t | 5 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t |
| 5 | // RUN: llvm-readobj -s -dyn-relocations %t | FileCheck %s | 6 | // RUN: llvm-readobj -s -dyn-relocations %t | FileCheck %s |
| 6 | // REQUIRES: arm | ||
| 7 | 7 | ||
| 8 | // This tls global-dynamic sequence is with respect to a preemptible symbol but | 8 | // This tls global-dynamic sequence is with respect to a preemptible symbol but |
| 9 | // is in an application so a relaxation to Initial Exec would normally be | 9 | // is in an application so a relaxation to Initial Exec would normally be |
deps/lld/test/ELF/arm-tls-norelax-gd-le.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 |
| 2 | // RUN: ld.lld %t1 --shared -o %t1.so | 3 | // RUN: ld.lld %t1 --shared -o %t1.so |
| 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 4 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t | 5 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t |
| 5 | // RUN: llvm-objdump -s %t | FileCheck %s | 6 | // RUN: llvm-objdump -s %t | FileCheck %s |
| 6 | // REQUIRES: arm | ||
| 7 | 7 | ||
| 8 | // This tls global-dynamic sequence is with respect to a non-preemptible | 8 | // This tls global-dynamic sequence is with respect to a non-preemptible |
| 9 | // symbol in an application so a relaxation to Local Exec would normally be | 9 | // symbol in an application so a relaxation to Local Exec would normally be |
deps/lld/test/ELF/arm-tls-norelax-ie-le.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 |
| 2 | // RUN: ld.lld %t1 --shared -o %t1.so | 3 | // RUN: ld.lld %t1 --shared -o %t1.so |
| 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 4 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t | 5 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t |
| 5 | // RUN: llvm-objdump -s -triple=armv7a-linux-gnueabi %t | FileCheck %s | 6 | // RUN: llvm-objdump -s -triple=armv7a-linux-gnueabi %t | FileCheck %s |
| 6 | // REQUIRES: arm | ||
| 7 | 7 | ||
| 8 | // This tls Initial Exec sequence is with respect to a non-preemptible symbol | 8 | // This tls Initial Exec sequence is with respect to a non-preemptible symbol |
| 9 | // so a relaxation would normally be possible. This would result in an assertion | 9 | // so a relaxation would normally be possible. This would result in an assertion |
deps/lld/test/ELF/arm-tls-norelax-ld-le.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 |
| 2 | // RUN: ld.lld %t1 --shared -o %t1.so | 3 | // RUN: ld.lld %t1 --shared -o %t1.so |
| 3 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi | 4 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi |
| 4 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t | 5 | // RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t |
| 5 | // RUN: llvm-objdump -s %t | FileCheck %s | 6 | // RUN: llvm-objdump -s %t | FileCheck %s |
| 6 | // REQUIRES: arm | ||
| 7 | 7 | ||
| 8 | .global __tls_get_addr | 8 | .global __tls_get_addr |
| 9 | .text | 9 | .text |
deps/lld/test/ELF/arm-undefined-weak.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 2>&1 | 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 3 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t2 | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | 5 | ||
| 6 | // Check that the ARM ABI rules for undefined weak symbols are applied. | 6 | // Check that the ARM ABI rules for undefined weak symbols are applied. |
| 7 | // Branch instructions are resolved to the next instruction. Undefined | 7 | // Branch instructions are resolved to the next instruction. Undefined |
deps/lld/test/ELF/arm-use-r-output.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | 1 | // REQUIRES: arm |
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o |
| 3 | // RUN: ld.lld -r %t.o -o %t2.o | 3 | // RUN: ld.lld -r %t.o -o %t2.o |
| 4 | // RUN: ld.lld -shared %t2.o -o %t.so | 4 | // RUN: ld.lld -shared %t2.o -o /dev/null |
| 5 | 5 | ||
| 6 | // We used to crash using the output of -r because of the relative order of | 6 | // We used to crash using the output of -r because of the relative order of |
| 7 | // SHF_LINK_ORDER sections. | 7 | // SHF_LINK_ORDER sections. |
deps/lld/test/ELF/as-needed-weak.s created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: echo '.globl foo; .type foo, @function; foo:' | \ | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t1.o | ||
| 5 | # RUN: ld.lld -shared -o %t1.so -soname libfoo %t1.o | ||
| 6 | |||
| 7 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o | ||
| 8 | # RUN: ld.lld -o %t.exe %t2.o --as-needed %t1.so | ||
| 9 | # RUN: llvm-readelf -dynamic-table -dyn-symbols %t.exe | FileCheck %s | ||
| 10 | |||
| 11 | # CHECK-NOT: libfoo | ||
| 12 | |||
| 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@ | ||
| 16 | |||
| 17 | .globl _start | ||
| 18 | .weak foo | ||
| 19 | |||
| 20 | _start: | ||
| 21 | mov $foo, %eax | ||
| 22 | callq foo | ||
deps/lld/test/ELF/as-needed.s+1-1| ... | @@ -22,7 +22,7 @@ | ... | @@ -22,7 +22,7 @@ |
| 22 | // RUN: ld.lld --as-needed %t.o %t2.so --no-as-needed %t3.so %t4.so -o %t2 | 22 | // 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 |
| 24 | 24 | ||
| 25 | /// GROUP directive is the same as --as-needed. | 25 | /// GROUP command is the same as listing the files on the command line. |
| 26 | 26 | ||
| 27 | // RUN: echo "GROUP(\"%t2.so\" \"%t3.so\" \"%t4.so\")" > %t.script | 27 | // RUN: echo "GROUP(\"%t2.so\" \"%t3.so\" \"%t4.so\")" > %t.script |
| 28 | // RUN: ld.lld %t.o %t.script -o %t2 | 28 | // RUN: ld.lld %t.o %t.script -o %t2 |
deps/lld/test/ELF/auxiliary.s+2| ... | @@ -2,6 +2,8 @@ | ... | @@ -2,6 +2,8 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: ld.lld %t.o -shared -f aaa --auxiliary bbb -o %t | 3 | # RUN: ld.lld %t.o -shared -f aaa --auxiliary bbb -o %t |
| 4 | # RUN: llvm-readobj --dynamic-table %t | FileCheck %s | 4 | # RUN: llvm-readobj --dynamic-table %t | FileCheck %s |
| 5 | # RUN: ld.lld %t.o -shared -f aaa --auxiliary=bbb -o %t | ||
| 6 | # RUN: llvm-readobj --dynamic-table %t | FileCheck %s | ||
| 5 | 7 | ||
| 6 | # CHECK: DynamicSection [ | 8 | # CHECK: DynamicSection [ |
| 7 | # CHECK-NEXT: Tag Type Name/Value | 9 | # CHECK-NEXT: Tag Type Name/Value |
deps/lld/test/ELF/basic-aarch64.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # REQUIRES: aarch64 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t |
| 2 | # RUN: ld.lld %t -o %t2 | 3 | # RUN: ld.lld %t -o %t2 |
| 3 | # RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \ | 4 | # RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \ |
| 4 | # RUN: | FileCheck %s | 5 | # RUN: | FileCheck %s |
| 5 | # REQUIRES: aarch64 | ||
| 6 | 6 | ||
| 7 | # exits with return code 42 on FreeBSD/AArch64 | 7 | # exits with return code 42 on FreeBSD/AArch64 |
| 8 | .globl _start | 8 | .globl _start |
deps/lld/test/ELF/basic-freebsd.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # Verify that OSABI is set to the correct value. | 2 | # Verify that OSABI is set to the correct value. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 | 5 | # RUN: ld.lld %t -o %t2 |
| 5 | # RUN: llvm-readobj -file-headers %t2 | FileCheck %s | 6 | # RUN: llvm-readobj -file-headers %t2 | FileCheck %s |
| 6 | # REQUIRES: x86 | ||
| 7 | 7 | ||
| 8 | .globl _start | 8 | .globl _start |
| 9 | _start: | 9 | _start: |
deps/lld/test/ELF/basic-mips.s+2-3| ... | @@ -1,10 +1,9 @@ | ... | @@ -1,10 +1,9 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t.o |
| 2 | # RUN: ld.lld %t.o -o %t.exe | 3 | # RUN: ld.lld %t.o -o %t.exe |
| 3 | # RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t.exe \ | 4 | # RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t.exe \ |
| 4 | # RUN: | FileCheck %s | 5 | # RUN: | FileCheck %s |
| 5 | 6 | ||
| 6 | # REQUIRES: mips | ||
| 7 | |||
| 8 | # Exits with return code 1 on Linux. | 7 | # Exits with return code 1 on Linux. |
| 9 | .globl __start | 8 | .globl __start |
| 10 | __start: | 9 | __start: |
| ... | @@ -19,7 +18,7 @@ __start: | ... | @@ -19,7 +18,7 @@ __start: |
| 19 | # CHECK-NEXT: DataEncoding: LittleEndian (0x1) | 18 | # CHECK-NEXT: DataEncoding: LittleEndian (0x1) |
| 20 | # CHECK-NEXT: FileVersion: 1 | 19 | # CHECK-NEXT: FileVersion: 1 |
| 21 | # CHECK-NEXT: OS/ABI: SystemV (0x0) | 20 | # CHECK-NEXT: OS/ABI: SystemV (0x0) |
| 22 | # CHECK-NEXT: ABIVersion: 0 | 21 | # CHECK-NEXT: ABIVersion: 1 |
| 23 | # CHECK-NEXT: Unused: (00 00 00 00 00 00 00) | 22 | # CHECK-NEXT: Unused: (00 00 00 00 00 00 00) |
| 24 | # CHECK-NEXT: } | 23 | # CHECK-NEXT: } |
| 25 | # CHECK-NEXT: Type: Executable (0x2) | 24 | # CHECK-NEXT: Type: Executable (0x2) |
deps/lld/test/ELF/basic-ppc.s+6-6| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: ppc | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t |
| 2 | # RUN: ld.lld --hash-style=sysv -discard-all -shared %t -o %t2 | 3 | # RUN: ld.lld --hash-style=sysv -discard-all -shared %t -o %t2 |
| 3 | # RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s | 4 | # RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s |
| 4 | # REQUIRES: ppc | ||
| 5 | 5 | ||
| 6 | # exits with return code 42 on FreeBSD | 6 | # exits with return code 42 on FreeBSD |
| 7 | .text | 7 | .text |
| ... | @@ -144,9 +144,9 @@ | ... | @@ -144,9 +144,9 @@ |
| 144 | // CHECK-NEXT: AddressAlignment: 4 | 144 | // CHECK-NEXT: AddressAlignment: 4 |
| 145 | // CHECK-NEXT: EntrySize: 8 | 145 | // CHECK-NEXT: EntrySize: 8 |
| 146 | // CHECK-NEXT: SectionData ( | 146 | // CHECK-NEXT: SectionData ( |
| 147 | // CHECK-NEXT: 0000: 00000006 00000114 0000000B 00000010 |................| | 147 | // CHECK-NEXT: 0000: 00000006 00000114 0000000B 00000010 |
| 148 | // CHECK-NEXT: 0010: 00000005 00000134 0000000A 00000001 |.......4........| | 148 | // CHECK-NEXT: 0010: 00000005 00000134 0000000A 00000001 |
| 149 | // CHECK-NEXT: 0020: 00000004 00000124 00000000 00000000 |.......$........| | 149 | // CHECK-NEXT: 0020: 00000004 00000124 00000000 00000000 |
| 150 | // CHECK-NEXT: ) | 150 | // CHECK-NEXT: ) |
| 151 | // CHECK-NEXT: } | 151 | // CHECK-NEXT: } |
| 152 | // CHECK-NEXT: Section { | 152 | // CHECK-NEXT: Section { |
| ... | @@ -165,7 +165,7 @@ | ... | @@ -165,7 +165,7 @@ |
| 165 | // CHECK-NEXT: AddressAlignment: 1 | 165 | // CHECK-NEXT: AddressAlignment: 1 |
| 166 | // CHECK-NEXT: EntrySize: 1 | 166 | // CHECK-NEXT: EntrySize: 1 |
| 167 | // CHECK-NEXT: SectionData ( | 167 | // CHECK-NEXT: SectionData ( |
| 168 | // CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.| | 168 | // CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.| |
| 169 | // CHECK-NEXT: ) | 169 | // CHECK-NEXT: ) |
| 170 | // CHECK-NEXT: } | 170 | // CHECK-NEXT: } |
| 171 | // CHECK-NEXT: Section { | 171 | // CHECK-NEXT: Section { |
| ... | @@ -215,7 +215,7 @@ | ... | @@ -215,7 +215,7 @@ |
| 215 | // CHECK-NEXT: ] | 215 | // CHECK-NEXT: ] |
| 216 | // CHECK-NEXT: Address: 0x0 | 216 | // CHECK-NEXT: Address: 0x0 |
| 217 | // CHECK-NEXT: Offset: 0x20A1 | 217 | // CHECK-NEXT: Offset: 0x20A1 |
| 218 | // CHECK-NEXT: Size: 1 | 218 | // CHECK-NEXT: Size: 10 |
| 219 | // CHECK-NEXT: Link: 0 | 219 | // CHECK-NEXT: Link: 0 |
| 220 | // CHECK-NEXT: Info: 0 | 220 | // CHECK-NEXT: Info: 0 |
| 221 | // CHECK-NEXT: AddressAlignment: 1 | 221 | // CHECK-NEXT: AddressAlignment: 1 |
deps/lld/test/ELF/basic-ppc64.s created+323| ... | @@ -0,0 +1,323 @@ | ||
| 1 | # 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 | ||
| 5 | .abiversion 2 | ||
| 6 | # Exits with return code 55 on linux. | ||
| 7 | .text | ||
| 8 | li 0,1 | ||
| 9 | li 3,55 | ||
| 10 | sc | ||
| 11 | |||
| 12 | // CHECK:Format: ELF64-ppc64 | ||
| 13 | // CHECK-NEXT:Arch: powerpc64le | ||
| 14 | // CHECK-NEXT:AddressSize: 64bit | ||
| 15 | // CHECK-NEXT:LoadName: | ||
| 16 | // CHECK-NEXT:ElfHeader { | ||
| 17 | // CHECK-NEXT: Ident { | ||
| 18 | // CHECK-NEXT: Magic: (7F 45 4C 46) | ||
| 19 | // CHECK-NEXT: Class: 64-bit (0x2) | ||
| 20 | // CHECK-NEXT: DataEncoding: LittleEndian (0x1) | ||
| 21 | // CHECK-NEXT: FileVersion: 1 | ||
| 22 | // CHECK-NEXT: OS/ABI: SystemV (0x0) | ||
| 23 | // CHECK-NEXT: ABIVersion: 0 | ||
| 24 | // CHECK-NEXT: Unused: (00 00 00 00 00 00 00) | ||
| 25 | // CHECK-NEXT: } | ||
| 26 | // CHECK-NEXT: Type: SharedObject (0x3) | ||
| 27 | // CHECK-NEXT: Machine: EM_PPC64 (0x15) | ||
| 28 | // CHECK-NEXT: Version: 1 | ||
| 29 | // CHECK-NEXT: Entry: 0x10000 | ||
| 30 | // CHECK-NEXT: ProgramHeaderOffset: 0x40 | ||
| 31 | // CHECK-NEXT: SectionHeaderOffset: | ||
| 32 | // CHECK-NEXT: Flags [ (0x2) | ||
| 33 | // CHECK-NEXT: 0x2 | ||
| 34 | // CHECK-NEXT: ] | ||
| 35 | // CHECK-NEXT: HeaderSize: 64 | ||
| 36 | // CHECK-NEXT: ProgramHeaderEntrySize: 56 | ||
| 37 | // CHECK-NEXT: ProgramHeaderCount: 7 | ||
| 38 | // CHECK-NEXT: SectionHeaderEntrySize: 64 | ||
| 39 | // CHECK-NEXT: SectionHeaderCount: 10 | ||
| 40 | // CHECK-NEXT: StringTableSectionIndex: 8 | ||
| 41 | // CHECK-NEXT:} | ||
| 42 | // CHECK-NEXT:Sections [ | ||
| 43 | // CHECK-NEXT: Section { | ||
| 44 | // CHECK-NEXT: Index: 0 | ||
| 45 | // CHECK-NEXT: Name: (0) | ||
| 46 | // CHECK-NEXT: Type: SHT_NULL (0x0) | ||
| 47 | // CHECK-NEXT: Flags [ (0x0) | ||
| 48 | // CHECK-NEXT: ] | ||
| 49 | // CHECK-NEXT: Address: 0x0 | ||
| 50 | // CHECK-NEXT: Offset: 0x0 | ||
| 51 | // CHECK-NEXT: Size: 0 | ||
| 52 | // CHECK-NEXT: Link: 0 | ||
| 53 | // CHECK-NEXT: Info: 0 | ||
| 54 | // CHECK-NEXT: AddressAlignment: 0 | ||
| 55 | // CHECK-NEXT: EntrySize: 0 | ||
| 56 | // CHECK-NEXT: SectionData ( | ||
| 57 | // CHECK-NEXT: ) | ||
| 58 | // CHECK-NEXT: } | ||
| 59 | // CHECK-NEXT: Section { | ||
| 60 | // CHECK-NEXT: Index: 1 | ||
| 61 | // CHECK-NEXT: Name: .dynsym (1) | ||
| 62 | // CHECK-NEXT: Type: SHT_DYNSYM (0xB) | ||
| 63 | // CHECK-NEXT: Flags [ (0x2) | ||
| 64 | // CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 65 | // CHECK-NEXT: ] | ||
| 66 | // CHECK-NEXT: Address: 0x1C8 | ||
| 67 | // CHECK-NEXT: Offset: 0x1C8 | ||
| 68 | // CHECK-NEXT: Size: 24 | ||
| 69 | // CHECK-NEXT: Link: 3 | ||
| 70 | // CHECK-NEXT: Info: 1 | ||
| 71 | // CHECK-NEXT: AddressAlignment: 8 | ||
| 72 | // CHECK-NEXT: EntrySize: 24 | ||
| 73 | // CHECK-NEXT: SectionData ( | ||
| 74 | // CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................| | ||
| 75 | // CHECK-NEXT: 0010: 00000000 00000000 |........| | ||
| 76 | // CHECK-NEXT: ) | ||
| 77 | // CHECK-NEXT: } | ||
| 78 | // CHECK-NEXT: Section { | ||
| 79 | // CHECK-NEXT: Index: 2 | ||
| 80 | // CHECK-NEXT: Name: .hash (9) | ||
| 81 | // CHECK-NEXT: Type: SHT_HASH (0x5) | ||
| 82 | // CHECK-NEXT: Flags [ (0x2) | ||
| 83 | // CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 84 | // CHECK-NEXT: ] | ||
| 85 | // CHECK-NEXT: Address: 0x1E0 | ||
| 86 | // CHECK-NEXT: Offset: 0x1E0 | ||
| 87 | // CHECK-NEXT: Size: 16 | ||
| 88 | // CHECK-NEXT: Link: 1 | ||
| 89 | // CHECK-NEXT: Info: 0 | ||
| 90 | // CHECK-NEXT: AddressAlignment: 4 | ||
| 91 | // CHECK-NEXT: EntrySize: 4 | ||
| 92 | // CHECK-NEXT: SectionData ( | ||
| 93 | // CHECK-NEXT: 0000: 01000000 01000000 00000000 00000000 |................| | ||
| 94 | // CHECK-NEXT: ) | ||
| 95 | // CHECK-NEXT: } | ||
| 96 | // CHECK-NEXT: Section { | ||
| 97 | // CHECK-NEXT: Index: 3 | ||
| 98 | // CHECK-NEXT: Name: .dynstr (15) | ||
| 99 | // CHECK-NEXT: Type: SHT_STRTAB (0x3) | ||
| 100 | // CHECK-NEXT: Flags [ (0x2) | ||
| 101 | // CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 102 | // CHECK-NEXT: ] | ||
| 103 | // CHECK-NEXT: Address: 0x1F0 | ||
| 104 | // CHECK-NEXT: Offset: 0x1F0 | ||
| 105 | // CHECK-NEXT: Size: 1 | ||
| 106 | // CHECK-NEXT: Link: 0 | ||
| 107 | // CHECK-NEXT: Info: 0 | ||
| 108 | // CHECK-NEXT: AddressAlignment: 1 | ||
| 109 | // CHECK-NEXT: EntrySize: 0 | ||
| 110 | // CHECK-NEXT: SectionData ( | ||
| 111 | // CHECK-NEXT: 0000: 00 |.| | ||
| 112 | // CHECK-NEXT: ) | ||
| 113 | // CHECK-NEXT: } | ||
| 114 | // CHECK-NEXT: Section { | ||
| 115 | // CHECK-NEXT: Index: 4 | ||
| 116 | // CHECK-NEXT: Name: .text (23) | ||
| 117 | // CHECK-NEXT: Type: SHT_PROGBITS (0x1) | ||
| 118 | // CHECK-NEXT: Flags [ (0x6) | ||
| 119 | // CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 120 | // CHECK-NEXT: SHF_EXECINSTR (0x4) | ||
| 121 | // CHECK-NEXT: ] | ||
| 122 | // CHECK-NEXT: Address: 0x10000 | ||
| 123 | // CHECK-NEXT: Offset: 0x10000 | ||
| 124 | // CHECK-NEXT: Size: 12 | ||
| 125 | // CHECK-NEXT: Link: 0 | ||
| 126 | // CHECK-NEXT: Info: 0 | ||
| 127 | // CHECK-NEXT: AddressAlignment: 4 | ||
| 128 | // CHECK-NEXT: EntrySize: 0 | ||
| 129 | // CHECK-NEXT: SectionData ( | ||
| 130 | // CHECK-NEXT: 0000: 01000038 37006038 02000044 |...87.`8...D| | ||
| 131 | // CHECK-NEXT: ) | ||
| 132 | // CHECK-NEXT: } | ||
| 133 | // CHECK-NEXT: Section { | ||
| 134 | // CHECK-NEXT: Index: 5 | ||
| 135 | // CHECK-NEXT: Name: .dynamic (29) | ||
| 136 | // CHECK-NEXT: Type: SHT_DYNAMIC (0x6) | ||
| 137 | // CHECK-NEXT: Flags [ (0x3) | ||
| 138 | // CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 139 | // CHECK-NEXT: SHF_WRITE (0x1) | ||
| 140 | // CHECK-NEXT: ] | ||
| 141 | // CHECK-NEXT: Address: 0x20000 | ||
| 142 | // CHECK-NEXT: Offset: 0x20000 | ||
| 143 | // CHECK-NEXT: Size: 96 | ||
| 144 | // CHECK-NEXT: Link: 3 | ||
| 145 | // CHECK-NEXT: Info: 0 | ||
| 146 | // CHECK-NEXT: AddressAlignment: 8 | ||
| 147 | // CHECK-NEXT: EntrySize: 16 | ||
| 148 | // 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 |................| | ||
| 155 | // CHECK-NEXT: ) | ||
| 156 | // CHECK-NEXT: } | ||
| 157 | // CHECK-NEXT: Section { | ||
| 158 | // CHECK-NEXT: Index: 6 | ||
| 159 | // CHECK-NEXT: Name: .comment (38) | ||
| 160 | // CHECK-NEXT: Type: SHT_PROGBITS (0x1) | ||
| 161 | // CHECK-NEXT: Flags [ (0x30) | ||
| 162 | // CHECK-NEXT: SHF_MERGE (0x10) | ||
| 163 | // CHECK-NEXT: SHF_STRINGS (0x20) | ||
| 164 | // CHECK-NEXT: ] | ||
| 165 | // CHECK-NEXT: Address: 0x0 | ||
| 166 | // CHECK-NEXT: Offset: 0x20060 | ||
| 167 | // CHECK-NEXT: Size: 8 | ||
| 168 | // CHECK-NEXT: Link: 0 | ||
| 169 | // CHECK-NEXT: Info: 0 | ||
| 170 | // CHECK-NEXT: AddressAlignment: 1 | ||
| 171 | // CHECK-NEXT: EntrySize: 1 | ||
| 172 | // CHECK-NEXT: SectionData ( | ||
| 173 | // CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.| | ||
| 174 | // CHECK-NEXT: ) | ||
| 175 | // CHECK-NEXT: } | ||
| 176 | // CHECK-NEXT: Section { | ||
| 177 | // CHECK-NEXT: Index: 7 | ||
| 178 | // CHECK-NEXT: Name: .symtab (47) | ||
| 179 | // CHECK-NEXT: Type: SHT_SYMTAB (0x2) | ||
| 180 | // CHECK-NEXT: Flags [ (0x0) | ||
| 181 | // CHECK-NEXT: ] | ||
| 182 | // CHECK-NEXT: Address: 0x0 | ||
| 183 | // CHECK-NEXT: Offset: 0x20068 | ||
| 184 | // CHECK-NEXT: Size: 48 | ||
| 185 | // CHECK-NEXT: Link: 9 | ||
| 186 | // CHECK-NEXT: Info: 2 | ||
| 187 | // CHECK-NEXT: AddressAlignment: 8 | ||
| 188 | // CHECK-NEXT: EntrySize: 24 | ||
| 189 | // CHECK-NEXT: SectionData ( | ||
| 190 | // CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................| | ||
| 191 | // CHECK-NEXT: 0010: 00000000 00000000 01000000 00020500 |................| | ||
| 192 | // CHECK-NEXT: 0020: 00000200 00000000 00000000 00000000 |................| | ||
| 193 | // CHECK-NEXT: ) | ||
| 194 | // CHECK-NEXT: } | ||
| 195 | // CHECK-NEXT: Section { | ||
| 196 | // CHECK-NEXT: Index: 8 | ||
| 197 | // CHECK-NEXT: Name: .shstrtab (55) | ||
| 198 | // CHECK-NEXT: Type: SHT_STRTAB (0x3) | ||
| 199 | // CHECK-NEXT: Flags [ (0x0) | ||
| 200 | // CHECK-NEXT: ] | ||
| 201 | // CHECK-NEXT: Address: 0x0 | ||
| 202 | // CHECK-NEXT: Offset: 0x20098 | ||
| 203 | // CHECK-NEXT: Size: 73 | ||
| 204 | // CHECK-NEXT: Link: 0 | ||
| 205 | // CHECK-NEXT: Info: 0 | ||
| 206 | // CHECK-NEXT: AddressAlignment: 1 | ||
| 207 | // CHECK-NEXT: EntrySize: 0 | ||
| 208 | // CHECK-NEXT: SectionData ( | ||
| 209 | // CHECK-NEXT: 0000: 002E6479 6E73796D 002E6861 7368002E |..dynsym..hash..| | ||
| 210 | // CHECK-NEXT: 0010: 64796E73 7472002E 74657874 002E6479 |dynstr..text..dy| | ||
| 211 | // CHECK-NEXT: 0020: 6E616D69 63002E63 6F6D6D65 6E74002E |namic..comment..| | ||
| 212 | // CHECK-NEXT: 0030: 73796D74 6162002E 73687374 72746162 |symtab..shstrtab| | ||
| 213 | // CHECK-NEXT: 0040: 002E7374 72746162 00 |..strtab.| | ||
| 214 | // CHECK-NEXT: ) | ||
| 215 | // CHECK-NEXT: } | ||
| 216 | // CHECK-NEXT: Section { | ||
| 217 | // CHECK-NEXT: Index: 9 | ||
| 218 | // CHECK-NEXT: Name: .strtab (65) | ||
| 219 | // CHECK-NEXT: Type: SHT_STRTAB (0x3) | ||
| 220 | // CHECK-NEXT: Flags [ (0x0) | ||
| 221 | // CHECK-NEXT: ] | ||
| 222 | // CHECK-NEXT: Address: 0x0 | ||
| 223 | // CHECK-NEXT: Offset: 0x200E1 | ||
| 224 | // CHECK-NEXT: Size: 10 | ||
| 225 | // CHECK-NEXT: Link: 0 | ||
| 226 | // CHECK-NEXT: Info: 0 | ||
| 227 | // CHECK-NEXT: AddressAlignment: 1 | ||
| 228 | // CHECK-NEXT: EntrySize: 0 | ||
| 229 | // CHECK-NEXT: SectionData ( | ||
| 230 | // CHECK-NEXT: 0000: 005F4459 4E414D49 4300 |._DYNAMIC.| | ||
| 231 | // CHECK-NEXT: ) | ||
| 232 | // CHECK-NEXT: } | ||
| 233 | // CHECK-NEXT:] | ||
| 234 | // CHECK-NEXT:ProgramHeaders [ | ||
| 235 | // CHECK-NEXT: ProgramHeader { | ||
| 236 | // CHECK-NEXT: Type: PT_PHDR (0x6) | ||
| 237 | // CHECK-NEXT: Offset: 0x40 | ||
| 238 | // CHECK-NEXT: VirtualAddress: 0x40 | ||
| 239 | // CHECK-NEXT: PhysicalAddress: 0x40 | ||
| 240 | // CHECK-NEXT: FileSize: 392 | ||
| 241 | // CHECK-NEXT: MemSize: 392 | ||
| 242 | // CHECK-NEXT: Flags [ (0x4) | ||
| 243 | // CHECK-NEXT: PF_R (0x4) | ||
| 244 | // CHECK-NEXT: ] | ||
| 245 | // CHECK-NEXT: Alignment: 8 | ||
| 246 | // CHECK-NEXT: } | ||
| 247 | // CHECK-NEXT: ProgramHeader { | ||
| 248 | // CHECK-NEXT: Type: PT_LOAD (0x1) | ||
| 249 | // CHECK-NEXT: Offset: 0x0 | ||
| 250 | // CHECK-NEXT: VirtualAddress: 0x0 | ||
| 251 | // CHECK-NEXT: PhysicalAddress: 0x0 | ||
| 252 | // CHECK-NEXT: FileSize: 497 | ||
| 253 | // CHECK-NEXT: MemSize: 497 | ||
| 254 | // CHECK-NEXT: Flags [ (0x4) | ||
| 255 | // CHECK-NEXT: PF_R (0x4) | ||
| 256 | // CHECK-NEXT: ] | ||
| 257 | // CHECK-NEXT: Alignment: 65536 | ||
| 258 | // CHECK-NEXT: } | ||
| 259 | // CHECK-NEXT: ProgramHeader { | ||
| 260 | // CHECK-NEXT: Type: PT_LOAD (0x1) | ||
| 261 | // CHECK-NEXT: Offset: 0x10000 | ||
| 262 | // CHECK-NEXT: VirtualAddress: 0x10000 | ||
| 263 | // CHECK-NEXT: PhysicalAddress: 0x10000 | ||
| 264 | // CHECK-NEXT: FileSize: 12 | ||
| 265 | // CHECK-NEXT: MemSize: 12 | ||
| 266 | // CHECK-NEXT: Flags [ (0x5) | ||
| 267 | // CHECK-NEXT: PF_R (0x4) | ||
| 268 | // CHECK-NEXT: PF_X (0x1) | ||
| 269 | // CHECK-NEXT: ] | ||
| 270 | // CHECK-NEXT: Alignment: 65536 | ||
| 271 | // CHECK-NEXT: } | ||
| 272 | // CHECK-NEXT: ProgramHeader { | ||
| 273 | // CHECK-NEXT: Type: PT_LOAD (0x1) | ||
| 274 | // CHECK-NEXT: Offset: 0x20000 | ||
| 275 | // CHECK-NEXT: VirtualAddress: 0x20000 | ||
| 276 | // CHECK-NEXT: PhysicalAddress: 0x20000 | ||
| 277 | // CHECK-NEXT: FileSize: 96 | ||
| 278 | // CHECK-NEXT: MemSize: 96 | ||
| 279 | // CHECK-NEXT: Flags [ (0x6) | ||
| 280 | // CHECK-NEXT: PF_R (0x4) | ||
| 281 | // CHECK-NEXT: PF_W (0x2) | ||
| 282 | // CHECK-NEXT: ] | ||
| 283 | // CHECK-NEXT: Alignment: 65536 | ||
| 284 | // CHECK-NEXT: } | ||
| 285 | // CHECK-NEXT: ProgramHeader { | ||
| 286 | // CHECK-NEXT: Type: PT_DYNAMIC (0x2) | ||
| 287 | // CHECK-NEXT: Offset: 0x20000 | ||
| 288 | // CHECK-NEXT: VirtualAddress: 0x20000 | ||
| 289 | // CHECK-NEXT: PhysicalAddress: 0x20000 | ||
| 290 | // CHECK-NEXT: FileSize: 96 | ||
| 291 | // CHECK-NEXT: MemSize: 96 | ||
| 292 | // CHECK-NEXT: Flags [ (0x6) | ||
| 293 | // CHECK-NEXT: PF_R (0x4) | ||
| 294 | // CHECK-NEXT: PF_W (0x2) | ||
| 295 | // CHECK-NEXT: ] | ||
| 296 | // CHECK-NEXT: Alignment: 8 | ||
| 297 | // CHECK-NEXT: } | ||
| 298 | // CHECK-NEXT: ProgramHeader { | ||
| 299 | // CHECK-NEXT: Type: PT_GNU_RELRO (0x6474E552) | ||
| 300 | // CHECK-NEXT: Offset: 0x20000 | ||
| 301 | // CHECK-NEXT: VirtualAddress: 0x20000 | ||
| 302 | // CHECK-NEXT: PhysicalAddress: 0x20000 | ||
| 303 | // CHECK-NEXT: FileSize: 96 | ||
| 304 | // CHECK-NEXT: MemSize: 4096 | ||
| 305 | // CHECK-NEXT: Flags [ (0x4) | ||
| 306 | // CHECK-NEXT: PF_R (0x4) | ||
| 307 | // CHECK-NEXT: ] | ||
| 308 | // CHECK-NEXT: Alignment: 1 | ||
| 309 | // CHECK-NEXT: } | ||
| 310 | // CHECK-NEXT: ProgramHeader { | ||
| 311 | // CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) | ||
| 312 | // CHECK-NEXT: Offset: 0x0 | ||
| 313 | // CHECK-NEXT: VirtualAddress: 0x0 | ||
| 314 | // CHECK-NEXT: PhysicalAddress: 0x0 | ||
| 315 | // CHECK-NEXT: FileSize: 0 | ||
| 316 | // CHECK-NEXT: MemSize: 0 | ||
| 317 | // CHECK-NEXT: Flags [ (0x6) | ||
| 318 | // CHECK-NEXT: PF_R (0x4) | ||
| 319 | // CHECK-NEXT: PF_W (0x2) | ||
| 320 | // CHECK-NEXT: ] | ||
| 321 | // CHECK-NEXT: Alignment: 0 | ||
| 322 | // CHECK-NEXT: } | ||
| 323 | // CHECK-NEXT:] | ||
deps/lld/test/ELF/basic-sparcv9.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # REQUIRES: sparc | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=sparc64-unknown-openbsd %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=sparc64-unknown-openbsd %s -o %t |
| 2 | # RUN: ld.lld %t -o %t2 | 3 | # RUN: ld.lld %t -o %t2 |
| 3 | # RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \ | 4 | # RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \ |
| 4 | # RUN: | FileCheck %s | 5 | # RUN: | FileCheck %s |
| 5 | # REQUIRES: sparc | ||
| 6 | 6 | ||
| 7 | # exits with return code 42 on OpenBSD/sparc64 | 7 | # exits with return code 42 on OpenBSD/sparc64 |
| 8 | .global _start | 8 | .global _start |
deps/lld/test/ELF/basic32.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t |
| 2 | # RUN: ld.lld %t -o %t2 | 3 | # RUN: ld.lld %t -o %t2 |
| 3 | # RUN: llvm-readobj -file-headers -sections -program-headers %t2 | FileCheck %s | 4 | # RUN: llvm-readobj -file-headers -sections -program-headers %t2 | FileCheck %s |
| 4 | # REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | # exits with return code 42 on linux | 6 | # exits with return code 42 on linux |
| 7 | .globl _start | 7 | .globl _start |
deps/lld/test/ELF/basic64be.s+81-192| ... | @@ -1,29 +1,14 @@ | ... | @@ -1,29 +1,14 @@ |
| 1 | # REQUIRES: ppc | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t |
| 2 | # RUN: ld.lld -discard-all %t -o %t2 | 3 | # RUN: ld.lld -discard-all %t -o %t2 |
| 3 | # RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s | 4 | # RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s |
| 4 | # REQUIRES: ppc | ||
| 5 | 5 | ||
| 6 | # exits with return code 42 on linux | 6 | # exits with return code 42 on linux |
| 7 | .section ".opd","aw" | ||
| 8 | .global _start | ||
| 9 | _start: | ||
| 10 | .quad .Lfoo,.TOC.@tocbase,0 | ||
| 11 | |||
| 12 | # generate .toc and .toc1 sections to make sure that the ordering is as | ||
| 13 | # intended (.toc before .toc1, and both before .opd). | ||
| 14 | .section ".toc1","aw" | ||
| 15 | .quad 22, 37, 89, 47 | ||
| 16 | |||
| 17 | .section ".toc","aw" | ||
| 18 | .quad 45, 86, 72, 24 | ||
| 19 | |||
| 20 | .text | 7 | .text |
| 21 | .Lfoo: | ||
| 22 | 	li 0,1 | 8 | 	li 0,1 |
| 23 | 	li 3,42 | 9 | 	li 3,42 |
| 24 | 	sc | 10 | 	sc |
| 25 | 11 | # CHECK: ElfHeader { | |
| 26 | # CHECK: ElfHeader { | ||
| 27 | # CHECK-NEXT: Ident { | 12 | # CHECK-NEXT: Ident { |
| 28 | # CHECK-NEXT: Magic: (7F 45 4C 46) | 13 | # CHECK-NEXT: Magic: (7F 45 4C 46) |
| 29 | # CHECK-NEXT: Class: 64-bit (0x2) | 14 | # CHECK-NEXT: Class: 64-bit (0x2) |
| ... | @@ -36,17 +21,18 @@ _start: | ... | @@ -36,17 +21,18 @@ _start: |
| 36 | # CHECK-NEXT: Type: Executable (0x2) | 21 | # CHECK-NEXT: Type: Executable (0x2) |
| 37 | # CHECK-NEXT: Machine: EM_PPC64 (0x15) | 22 | # CHECK-NEXT: Machine: EM_PPC64 (0x15) |
| 38 | # CHECK-NEXT: Version: 1 | 23 | # CHECK-NEXT: Version: 1 |
| 39 | # CHECK-NEXT: Entry: 0x10020040 | 24 | # CHECK-NEXT: Entry: 0x10010000 |
| 40 | # CHECK-NEXT: ProgramHeaderOffset: 0x40 | 25 | # CHECK-NEXT: ProgramHeaderOffset: 0x40 |
| 41 | # CHECK-NEXT: SectionHeaderOffset: 0x30080 | 26 | # CHECK-NEXT: SectionHeaderOffset: 0x11050 |
| 42 | # CHECK-NEXT: Flags [ (0x0) | 27 | # CHECK-NEXT: Flags [ (0x2) |
| 28 | # CHECK-NEXT: 0x2 | ||
| 43 | # CHECK-NEXT: ] | 29 | # CHECK-NEXT: ] |
| 44 | # CHECK-NEXT: HeaderSize: 64 | 30 | # CHECK-NEXT: HeaderSize: 64 |
| 45 | # CHECK-NEXT: ProgramHeaderEntrySize: 56 | 31 | # CHECK-NEXT: ProgramHeaderEntrySize: 56 |
| 46 | # CHECK-NEXT: ProgramHeaderCount: 6 | 32 | # CHECK-NEXT: ProgramHeaderCount: 4 |
| 47 | # CHECK-NEXT: SectionHeaderEntrySize: 64 | 33 | # CHECK-NEXT: SectionHeaderEntrySize: 64 |
| 48 | # CHECK-NEXT: SectionHeaderCount: 10 | 34 | # CHECK-NEXT: SectionHeaderCount: 6 |
| 49 | # CHECK-NEXT: StringTableSectionIndex: 8 | 35 | # CHECK-NEXT: StringTableSectionIndex: 4 |
| 50 | # CHECK-NEXT: } | 36 | # CHECK-NEXT: } |
| 51 | # CHECK-NEXT: Sections [ | 37 | # CHECK-NEXT: Sections [ |
| 52 | # CHECK-NEXT: Section { | 38 | # CHECK-NEXT: Section { |
| ... | @@ -67,7 +53,7 @@ _start: | ... | @@ -67,7 +53,7 @@ _start: |
| 67 | # CHECK-NEXT: } | 53 | # CHECK-NEXT: } |
| 68 | # CHECK-NEXT: Section { | 54 | # CHECK-NEXT: Section { |
| 69 | # CHECK-NEXT: Index: 1 | 55 | # CHECK-NEXT: Index: 1 |
| 70 | # CHECK-NEXT: Name: .text | 56 | # CHECK-NEXT: Name: .text (1) |
| 71 | # CHECK-NEXT: Type: SHT_PROGBITS (0x1) | 57 | # CHECK-NEXT: Type: SHT_PROGBITS (0x1) |
| 72 | # CHECK-NEXT: Flags [ (0x6) | 58 | # CHECK-NEXT: Flags [ (0x6) |
| 73 | # CHECK-NEXT: SHF_ALLOC (0x2) | 59 | # CHECK-NEXT: SHF_ALLOC (0x2) |
| ... | @@ -81,152 +67,80 @@ _start: | ... | @@ -81,152 +67,80 @@ _start: |
| 81 | # CHECK-NEXT: AddressAlignment: 4 | 67 | # CHECK-NEXT: AddressAlignment: 4 |
| 82 | # CHECK-NEXT: EntrySize: 0 | 68 | # CHECK-NEXT: EntrySize: 0 |
| 83 | # CHECK-NEXT: SectionData ( | 69 | # CHECK-NEXT: SectionData ( |
| 84 | # CHECK: ) | 70 | # CHECK-NEXT: 0000: 38000001 3860002A 44000002 |8...8`.*D...| |
| 85 | # CHECK-NEXT: } | ||
| 86 | # CHECK-NEXT: Section { | ||
| 87 | # CHECK-NEXT: Index: 2 | ||
| 88 | # CHECK-NEXT: Name: .toc | ||
| 89 | # CHECK-NEXT: Type: SHT_PROGBITS (0x1) | ||
| 90 | # CHECK-NEXT: Flags [ (0x3) | ||
| 91 | # CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 92 | # CHECK-NEXT: SHF_WRITE (0x1) | ||
| 93 | # CHECK-NEXT: ] | ||
| 94 | # CHECK-NEXT: Address: 0x10020000 | ||
| 95 | # CHECK-NEXT: Offset: 0x20000 | ||
| 96 | # CHECK-NEXT: Size: 32 | ||
| 97 | # CHECK-NEXT: Link: 0 | ||
| 98 | # CHECK-NEXT: Info: 0 | ||
| 99 | # CHECK-NEXT: AddressAlignment: 1 | ||
| 100 | # CHECK-NEXT: EntrySize: 0 | ||
| 101 | # CHECK-NEXT: SectionData ( | ||
| 102 | # CHECK-NEXT: 0000: 00000000 0000002D 00000000 00000056 |.......-.......V| | ||
| 103 | # CHECK-NEXT: 0010: 00000000 00000048 00000000 00000018 |.......H........| | ||
| 104 | # CHECK-NEXT: ) | ||
| 105 | # CHECK-NEXT: } | ||
| 106 | # CHECK-NEXT: Section { | ||
| 107 | # CHECK-NEXT: Index: 3 | ||
| 108 | # CHECK-NEXT: Name: .toc1 | ||
| 109 | # CHECK-NEXT: Type: SHT_PROGBITS (0x1) | ||
| 110 | # CHECK-NEXT: Flags [ (0x3) | ||
| 111 | # CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 112 | # CHECK-NEXT: SHF_WRITE (0x1) | ||
| 113 | # CHECK-NEXT: ] | ||
| 114 | # CHECK-NEXT: Address: 0x10020020 | ||
| 115 | # CHECK-NEXT: Offset: 0x20020 | ||
| 116 | # CHECK-NEXT: Size: 32 | ||
| 117 | # CHECK-NEXT: Link: 0 | ||
| 118 | # CHECK-NEXT: Info: 0 | ||
| 119 | # CHECK-NEXT: AddressAlignment: 1 | ||
| 120 | # CHECK-NEXT: EntrySize: 0 | ||
| 121 | # CHECK-NEXT: SectionData ( | ||
| 122 | # CHECK-NEXT: 0000: 00000000 00000016 00000000 00000025 |...............%| | ||
| 123 | # CHECK-NEXT: 0010: 00000000 00000059 00000000 0000002F |.......Y......./| | ||
| 124 | # CHECK-NEXT: ) | 71 | # CHECK-NEXT: ) |
| 125 | # CHECK-NEXT: } | 72 | # CHECK-NEXT: } |
| 126 | # CHECK-NEXT: Section { | 73 | # CHECK-NEXT: Section { |
| 127 | # CHECK-NEXT: Index: 4 | 74 | # CHECK-NEXT: Index: 2 |
| 128 | # CHECK-NEXT: Name: .opd | 75 | # CHECK-NEXT: Name: .comment (7) |
| 129 | # CHECK-NEXT: Type: SHT_PROGBITS (0x1) | ||
| 130 | # CHECK-NEXT: Flags [ (0x3) | ||
| 131 | # CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 132 | # CHECK-NEXT: SHF_WRITE (0x1) | ||
| 133 | # CHECK-NEXT: ] | ||
| 134 | # CHECK-NEXT: Address: 0x10020040 | ||
| 135 | # CHECK-NEXT: Offset: 0x20040 | ||
| 136 | # CHECK-NEXT: Size: 24 | ||
| 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: 00000000 10010000 00000000 10038000 |................| | ||
| 143 | # CHECK-NEXT: 0010: 00000000 00000000 |........| | ||
| 144 | # CHECK-NEXT: ) | ||
| 145 | # CHECK-NEXT: } | ||
| 146 | # CHECK-NEXT: Section { | ||
| 147 | # CHECK-NEXT: Index: 5 | ||
| 148 | # CHECK-NEXT: Name: .got | ||
| 149 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 150 | # CHECK-NEXT: Flags [ | ||
| 151 | # CHECK-NEXT: SHF_ALLOC | ||
| 152 | # CHECK-NEXT: SHF_WRITE | ||
| 153 | # CHECK-NEXT: ] | ||
| 154 | # CHECK-NEXT: Address: 0x10030000 | ||
| 155 | # CHECK-NEXT: Offset: 0x30000 | ||
| 156 | # CHECK-NEXT: Size: 0 | ||
| 157 | # CHECK-NEXT: Link: 0 | ||
| 158 | # CHECK-NEXT: Info: 0 | ||
| 159 | # CHECK-NEXT: AddressAlignment: 8 | ||
| 160 | # CHECK-NEXT: EntrySize: 0 | ||
| 161 | # CHECK-NEXT: SectionData ( | ||
| 162 | # CHECK-NEXT: ) | ||
| 163 | # CHECK-NEXT: } | ||
| 164 | # CHECK-NEXT: Section { | ||
| 165 | # CHECK-NEXT: Index: 6 | ||
| 166 | # CHECK-NEXT: Name: .comment | ||
| 167 | # CHECK-NEXT: Type: SHT_PROGBITS (0x1) | 76 | # CHECK-NEXT: Type: SHT_PROGBITS (0x1) |
| 168 | # CHECK-NEXT: Flags [ (0x30) | 77 | # CHECK-NEXT: Flags [ (0x30) |
| 169 | # CHECK-NEXT: SHF_MERGE (0x10) | 78 | # CHECK-NEXT: SHF_MERGE (0x10) |
| 170 | # CHECK-NEXT: SHF_STRINGS (0x20) | 79 | # CHECK-NEXT: SHF_STRINGS (0x20) |
| 171 | # CHECK-NEXT: ] | 80 | # CHECK-NEXT: ] |
| 172 | # CHECK-NEXT: Address: 0x0 | 81 | # CHECK-NEXT: Address: 0x0 |
| 173 | # CHECK-NEXT: Offset: 0x30000 | 82 | # CHECK-NEXT: Offset: 0x11000 |
| 174 | # CHECK-NEXT: Size: 8 | 83 | # CHECK-NEXT: Size: 8 |
| 175 | # CHECK-NEXT: Link: 0 | 84 | # CHECK-NEXT: Link: 0 |
| 176 | # CHECK-NEXT: Info: 0 | 85 | # CHECK-NEXT: Info: 0 |
| 177 | # CHECK-NEXT: AddressAlignment: 1 | 86 | # CHECK-NEXT: AddressAlignment: 1 |
| 178 | # CHECK-NEXT: EntrySize: 1 | 87 | # CHECK-NEXT: EntrySize: 1 |
| 179 | # CHECK-NEXT: SectionData ( | 88 | # CHECK-NEXT: SectionData ( |
| 180 | # CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.| | 89 | # CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.| |
| 181 | # CHECK-NEXT: ) | 90 | # CHECK-NEXT: ) |
| 182 | # CHECK-NEXT: } | 91 | # CHECK-NEXT: } |
| 183 | # CHECK-NEXT: Section { | 92 | # CHECK-NEXT: Section { |
| 184 | # CHECK-NEXT: Index: 7 | 93 | # CHECK-NEXT: Index: 3 |
| 185 | # CHECK-NEXT: Name: .symtab | 94 | # CHECK-NEXT: Name: .symtab (16) |
| 186 | # CHECK-NEXT: Type: SHT_SYMTAB (0x2) | 95 | # CHECK-NEXT: Type: SHT_SYMTAB (0x2) |
| 187 | # CHECK-NEXT: Flags [ (0x0) | 96 | # CHECK-NEXT: Flags [ (0x0) |
| 188 | # CHECK-NEXT: ] | 97 | # CHECK-NEXT: ] |
| 189 | # CHECK-NEXT: Address: 0x0 | 98 | # CHECK-NEXT: Address: 0x0 |
| 190 | # CHECK-NEXT: Offset: 0x30008 | 99 | # CHECK-NEXT: Offset: 0x11008 |
| 191 | # CHECK-NEXT: Size: 48 | 100 | # CHECK-NEXT: Size: 24 |
| 192 | # CHECK-NEXT: Link: 9 | 101 | # CHECK-NEXT: Link: 5 |
| 193 | # CHECK-NEXT: Info: 1 | 102 | # CHECK-NEXT: Info: 1 |
| 194 | # CHECK-NEXT: AddressAlignment: 8 | 103 | # CHECK-NEXT: AddressAlignment: 8 |
| 195 | # CHECK-NEXT: EntrySize: 24 | 104 | # CHECK-NEXT: EntrySize: 24 |
| 196 | # CHECK-NEXT: SectionData ( | 105 | # CHECK-NEXT: SectionData ( |
| 197 | # CHECK: ) | 106 | # CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................| |
| 107 | # CHECK-NEXT: 0010: 00000000 00000000 |........| | ||
| 108 | # CHECK-NEXT: ) | ||
| 198 | # CHECK-NEXT: } | 109 | # CHECK-NEXT: } |
| 199 | # CHECK-NEXT: Section { | 110 | # CHECK-NEXT: Section { |
| 200 | # CHECK-NEXT: Index: 8 | 111 | # CHECK-NEXT: Index: 4 |
| 201 | # CHECK-NEXT: Name: .shstrtab | 112 | # CHECK-NEXT: Name: .shstrtab (24) |
| 202 | # CHECK-NEXT: Type: SHT_STRTAB | 113 | # CHECK-NEXT: Type: SHT_STRTAB (0x3) |
| 203 | # CHECK-NEXT: Flags [ | 114 | # CHECK-NEXT: Flags [ (0x0) |
| 204 | # CHECK-NEXT: ] | 115 | # CHECK-NEXT: ] |
| 205 | # CHECK-NEXT: Address: 0x0 | 116 | # CHECK-NEXT: Address: 0x0 |
| 206 | # CHECK-NEXT: Offset: 0x30038 | 117 | # CHECK-NEXT: Offset: 0x11020 |
| 207 | # CHECK-NEXT: Size: 63 | 118 | # CHECK-NEXT: Size: 42 |
| 208 | # CHECK-NEXT: Link: 0 | 119 | # CHECK-NEXT: Link: 0 |
| 209 | # CHECK-NEXT: Info: 0 | 120 | # CHECK-NEXT: Info: 0 |
| 210 | # CHECK-NEXT: AddressAlignment: 1 | 121 | # CHECK-NEXT: AddressAlignment: 1 |
| 211 | # CHECK-NEXT: EntrySize: 0 | 122 | # CHECK-NEXT: EntrySize: 0 |
| 212 | # CHECK-NEXT: SectionData ( | 123 | # CHECK-NEXT: SectionData ( |
| 213 | # CHECK: ) | 124 | # CHECK-NEXT: 0000: 002E7465 7874002E 636F6D6D 656E7400 |..text..comment.| |
| 125 | # CHECK-NEXT: 0010: 2E73796D 74616200 2E736873 74727461 |.symtab..shstrta| | ||
| 126 | # CHECK-NEXT: 0020: 62002E73 74727461 6200 |b..strtab.| | ||
| 127 | # CHECK-NEXT: ) | ||
| 214 | # CHECK-NEXT: } | 128 | # CHECK-NEXT: } |
| 215 | # CHECK-NEXT: Section { | 129 | # CHECK-NEXT: Section { |
| 216 | # CHECK-NEXT: Index: 9 | 130 | # CHECK-NEXT: Index: 5 |
| 217 | # CHECK-NEXT: Name: .strtab | 131 | # CHECK-NEXT: Name: .strtab (34) |
| 218 | # CHECK-NEXT: Type: SHT_STRTAB | 132 | # CHECK-NEXT: Type: SHT_STRTAB (0x3) |
| 219 | # CHECK-NEXT: Flags [ (0x0) | 133 | # CHECK-NEXT: Flags [ (0x0) |
| 220 | # CHECK-NEXT: ] | 134 | # CHECK-NEXT: ] |
| 221 | # CHECK-NEXT: Address: 0x0 | 135 | # CHECK-NEXT: Address: 0x0 |
| 222 | # CHECK-NEXT: Offset: 0x30077 | 136 | # CHECK-NEXT: Offset: 0x1104A |
| 223 | # CHECK-NEXT: Size: 8 | 137 | # CHECK-NEXT: Size: 1 |
| 224 | # CHECK-NEXT: Link: 0 | 138 | # CHECK-NEXT: Link: 0 |
| 225 | # CHECK-NEXT: Info: 0 | 139 | # CHECK-NEXT: Info: 0 |
| 226 | # CHECK-NEXT: AddressAlignment: 1 | 140 | # CHECK-NEXT: AddressAlignment: 1 |
| 227 | # CHECK-NEXT: EntrySize: 0 | 141 | # CHECK-NEXT: EntrySize: 0 |
| 228 | # CHECK-NEXT: SectionData ( | 142 | # CHECK-NEXT: SectionData ( |
| 229 | # CHECK-NEXT: 0000: 005F7374 61727400 |._start.| | 143 | # CHECK-NEXT: 0000: 00 |.| |
| 230 | # CHECK-NEXT: ) | 144 | # CHECK-NEXT: ) |
| 231 | # CHECK-NEXT: } | 145 | # CHECK-NEXT: } |
| 232 | # CHECK-NEXT: ] | 146 | # CHECK-NEXT: ] |
| ... | @@ -236,74 +150,49 @@ _start: | ... | @@ -236,74 +150,49 @@ _start: |
| 236 | # CHECK-NEXT: Offset: 0x40 | 150 | # CHECK-NEXT: Offset: 0x40 |
| 237 | # CHECK-NEXT: VirtualAddress: 0x10000040 | 151 | # CHECK-NEXT: VirtualAddress: 0x10000040 |
| 238 | # CHECK-NEXT: PhysicalAddress: 0x10000040 | 152 | # CHECK-NEXT: PhysicalAddress: 0x10000040 |
| 239 | # CHECK-NEXT: FileSize: 336 | 153 | # CHECK-NEXT: FileSize: 224 |
| 240 | # CHECK-NEXT: MemSize: 336 | 154 | # CHECK-NEXT: MemSize: 224 |
| 241 | # CHECK-NEXT: Flags [ | 155 | # CHECK-NEXT: Flags [ (0x4) |
| 242 | # CHECK-NEXT: PF_R | 156 | # CHECK-NEXT: PF_R (0x4) |
| 243 | # CHECK-NEXT: ] | 157 | # CHECK-NEXT: ] |
| 244 | # CHECK-NEXT: Alignment: 8 | 158 | # CHECK-NEXT: Alignment: 8 |
| 245 | # CHECK-NEXT: } | 159 | # CHECK-NEXT: } |
| 246 | # CHECK-NEXT: ProgramHeader { | 160 | # CHECK-NEXT: ProgramHeader { |
| 247 | # CHECK-NEXT: Type: PT_LOAD (0x1) | 161 | # CHECK-NEXT: Type: PT_LOAD (0x1) |
| 248 | # CHECK-NEXT: Offset: 0x0 | 162 | # CHECK-NEXT: Offset: 0x0 |
| 249 | # CHECK-NEXT: VirtualAddress: 0x10000000 | 163 | # CHECK-NEXT: VirtualAddress: 0x10000000 |
| 250 | # CHECK-NEXT: PhysicalAddress: 0x10000000 | 164 | # CHECK-NEXT: PhysicalAddress: 0x10000000 |
| 251 | # CHECK-NEXT: FileSize: 400 | 165 | # CHECK-NEXT: FileSize: 288 |
| 252 | # CHECK-NEXT: MemSize: 400 | 166 | # CHECK-NEXT: MemSize: 288 |
| 253 | # CHECK-NEXT: Flags [ | 167 | # CHECK-NEXT: Flags [ (0x4) |
| 254 | # CHECK-NEXT: PF_R | 168 | # CHECK-NEXT: PF_R (0x4) |
| 255 | # CHECK-NEXT: ] | 169 | # CHECK-NEXT: ] |
| 256 | # CHECK-NEXT: Alignment: 65536 | 170 | # CHECK-NEXT: Alignment: 65536 |
| 257 | # CHECK-NEXT: } | 171 | # CHECK-NEXT: } |
| 258 | # CHECK-NEXT: ProgramHeader { | 172 | # CHECK-NEXT: ProgramHeader { |
| 259 | # CHECK-NEXT: Type: PT_LOAD (0x1) | 173 | # CHECK-NEXT: Type: PT_LOAD (0x1) |
| 260 | # CHECK-NEXT: Offset: 0x10000 | 174 | # CHECK-NEXT: Offset: 0x10000 |
| 261 | # CHECK-NEXT: VirtualAddress: 0x10010000 | 175 | # CHECK-NEXT: VirtualAddress: 0x10010000 |
| 262 | # CHECK-NEXT: PhysicalAddress: 0x10010000 | 176 | # CHECK-NEXT: PhysicalAddress: 0x10010000 |
| 263 | # CHECK-NEXT: FileSize: 12 | 177 | # CHECK-NEXT: FileSize: 4096 |
| 264 | # CHECK-NEXT: MemSize: 12 | 178 | # CHECK-NEXT: MemSize: 4096 |
| 265 | # CHECK-NEXT: Flags [ (0x5) | 179 | # CHECK-NEXT: Flags [ (0x5) |
| 266 | # CHECK-NEXT: PF_R (0x4) | 180 | # CHECK-NEXT: PF_R (0x4) |
| 267 | # CHECK-NEXT: PF_X (0x1) | 181 | # CHECK-NEXT: PF_X (0x1) |
| 268 | # CHECK-NEXT: ] | 182 | # CHECK-NEXT: ] |
| 269 | # CHECK-NEXT: Alignment: 65536 | 183 | # CHECK-NEXT: Alignment: 65536 |
| 270 | # CHECK-NEXT: } | 184 | # CHECK-NEXT: } |
| 271 | # CHECK-NEXT: ProgramHeader { | 185 | # CHECK-NEXT: ProgramHeader { |
| 272 | # CHECK-NEXT: Type: PT_LOAD (0x1) | 186 | # CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) |
| 273 | # CHECK-NEXT: Offset: 0x20000 | 187 | # CHECK-NEXT: Offset: 0x0 |
| 274 | # CHECK-NEXT: VirtualAddress: 0x10020000 | 188 | # CHECK-NEXT: VirtualAddress: 0x0 |
| 275 | # CHECK-NEXT: PhysicalAddress: 0x10020000 | 189 | # CHECK-NEXT: PhysicalAddress: 0x0 |
| 276 | # CHECK-NEXT: FileSize: 65536 | 190 | # CHECK-NEXT: FileSize: 0 |
| 277 | # CHECK-NEXT: MemSize: 65536 | 191 | # CHECK-NEXT: MemSize: 0 |
| 278 | # CHECK-NEXT: Flags [ (0x6) | 192 | # CHECK-NEXT: Flags [ (0x6) |
| 279 | # CHECK-NEXT: PF_R (0x4) | 193 | # CHECK-NEXT: PF_R (0x4) |
| 280 | # CHECK-NEXT: PF_W (0x2) | 194 | # CHECK-NEXT: PF_W (0x2) |
| 281 | # CHECK-NEXT: ] | 195 | # CHECK-NEXT: ] |
| 282 | # CHECK-NEXT: Alignment: 65536 | 196 | # CHECK-NEXT: Alignment: 0 |
| 283 | # CHECK-NEXT: } | 197 | # CHECK-NEXT: } |
| 284 | # CHECK-NEXT: ProgramHeader { | ||
| 285 | # CHECK-NEXT: Type: PT_GNU_RELRO | ||
| 286 | # CHECK-NEXT: Offset: 0x30000 | ||
| 287 | # CHECK-NEXT: VirtualAddress: 0x10030000 | ||
| 288 | # CHECK-NEXT: PhysicalAddress: 0x10030000 | ||
| 289 | # CHECK-NEXT: FileSize: 0 | ||
| 290 | # CHECK-NEXT: MemSize: 0 | ||
| 291 | # CHECK-NEXT: Flags [ (0x4) | ||
| 292 | # CHECK-NEXT: PF_R (0x4) | ||
| 293 | # CHECK-NEXT: ] | ||
| 294 | # CHECK-NEXT: Alignment: 1 | ||
| 295 | # CHECK-NEXT: } | ||
| 296 | # CHECK-NEXT: ProgramHeader { | ||
| 297 | # CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) | ||
| 298 | # CHECK-NEXT: Offset: 0x0 | ||
| 299 | # CHECK-NEXT: VirtualAddress: 0x0 | ||
| 300 | # CHECK-NEXT: PhysicalAddress: 0x0 | ||
| 301 | # CHECK-NEXT: FileSize: 0 | ||
| 302 | # CHECK-NEXT: MemSize: 0 | ||
| 303 | # CHECK-NEXT: Flags [ (0x6) | ||
| 304 | # CHECK-NEXT: PF_R (0x4) | ||
| 305 | # CHECK-NEXT: PF_W (0x2) | ||
| 306 | # CHECK-NEXT: ] | ||
| 307 | # CHECK-NEXT: Alignment: 0 | ||
| 308 | # CHECK-NEXT: } | ||
| 309 | # CHECK-NEXT: ] | 198 | # CHECK-NEXT: ] |
deps/lld/test/ELF/bss.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 | 3 | // RUN: ld.lld %t -o %t2 |
| 3 | // RUN: llvm-readobj -sections %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -sections %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | // Test that bss takes no space on disk. | 6 | // Test that bss takes no space on disk. |
| 7 | 7 |
deps/lld/test/ELF/bsymbolic-undef.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | # RUN: ld.lld -shared -Bsymbolic %t.o -o %t.so | 3 | # RUN: ld.lld -shared -Bsymbolic %t.o -o %t.so |
| 3 | # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s | 4 | # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s |
deps/lld/test/ELF/bsymbolic.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld -shared %t.o -o %t0.so | 3 | // RUN: ld.lld -shared %t.o -o %t0.so |
| 3 | // RUN: ld.lld -shared -Bsymbolic %t.o -o %t1.so | 4 | // RUN: ld.lld -shared -Bsymbolic %t.o -o %t1.so |
deps/lld/test/ELF/build-id.s+2| ... | @@ -7,6 +7,8 @@ | ... | @@ -7,6 +7,8 @@ |
| 7 | 7 | ||
| 8 | # RUN: ld.lld --build-id %t -o %t2 -threads | 8 | # RUN: ld.lld --build-id %t -o %t2 -threads |
| 9 | # RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s | 9 | # RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s |
| 10 | # RUN: ld.lld --build-id=fast %t -o %t2 -threads | ||
| 11 | # RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s | ||
| 10 | # RUN: ld.lld --build-id %t -o %t2 -no-threads | 12 | # RUN: ld.lld --build-id %t -o %t2 -no-threads |
| 11 | # RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s | 13 | # RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s |
| 12 | 14 |
deps/lld/test/ELF/cgprofile-bad-clusters.s created+70| ... | @@ -0,0 +1,70 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # This test checks that CallGraphSort ignores edges that would form "bad" | ||
| 3 | # clusters. | ||
| 4 | |||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 6 | # RUN: echo "A C 1" > %t.call_graph | ||
| 7 | # RUN: echo "E B 4" >> %t.call_graph | ||
| 8 | # RUN: echo "C D 2" >> %t.call_graph | ||
| 9 | # RUN: echo "B D 1" >> %t.call_graph | ||
| 10 | # RUN: echo "F G 6" >> %t.call_graph | ||
| 11 | # RUN: echo "G H 5" >> %t.call_graph | ||
| 12 | # RUN: echo "H I 4" >> %t.call_graph | ||
| 13 | # RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2 | ||
| 14 | # RUN: llvm-readobj -symbols %t2 | FileCheck %s | ||
| 15 | |||
| 16 | .section .text.A,"ax",@progbits | ||
| 17 | .globl A | ||
| 18 | A: | ||
| 19 | retq | ||
| 20 | |||
| 21 | .section .text.D,"ax",@progbits | ||
| 22 | D: | ||
| 23 | .fill 1000, 1, 0 | ||
| 24 | |||
| 25 | .section .text.E,"ax",@progbits | ||
| 26 | E: | ||
| 27 | retq | ||
| 28 | |||
| 29 | .section .text.C,"ax",@progbits | ||
| 30 | C: | ||
| 31 | retq | ||
| 32 | |||
| 33 | .section .text.B,"ax",@progbits | ||
| 34 | B: | ||
| 35 | .fill 1000, 1, 0 | ||
| 36 | |||
| 37 | .section .text.F,"ax",@progbits | ||
| 38 | F: | ||
| 39 | .fill (1024 * 1024) - 1, 1, 0 | ||
| 40 | |||
| 41 | .section .text.G,"ax",@progbits | ||
| 42 | G: | ||
| 43 | retq | ||
| 44 | |||
| 45 | .section .text.H,"ax",@progbits | ||
| 46 | H: | ||
| 47 | retq | ||
| 48 | |||
| 49 | .section .text.I,"ax",@progbits | ||
| 50 | I: | ||
| 51 | .fill 13, 1, 0 | ||
| 52 | |||
| 53 | # CHECK: Name: B | ||
| 54 | # CHECK-NEXT: Value: 0x201011 | ||
| 55 | # CHECK: Name: C | ||
| 56 | # CHECK-NEXT: Value: 0x20100F | ||
| 57 | # CHECK: Name: D | ||
| 58 | # CHECK-NEXT: Value: 0x2013F9 | ||
| 59 | # CHECK: Name: E | ||
| 60 | # CHECK-NEXT: Value: 0x201010 | ||
| 61 | # CHECK: Name: F | ||
| 62 | # CHECK-NEXT: Value: 0x2017E1 | ||
| 63 | # CHECK: Name: G | ||
| 64 | # CHECK-NEXT: Value: 0x3017E0 | ||
| 65 | # CHECK: Name: H | ||
| 66 | # CHECK-NEXT: Value: 0x201000 | ||
| 67 | # CHECK: Name: I | ||
| 68 | # CHECK-NEXT: Value: 0x201001 | ||
| 69 | # CHECK: Name: A | ||
| 70 | # CHECK-NEXT: Value: 0x20100E | ||
deps/lld/test/ELF/cgprofile-err.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 4 | |||
| 5 | # RUN: echo "A B C 100" > %t.call_graph | ||
| 6 | # RUN: not ld.lld %t --call-graph-ordering-file \ | ||
| 7 | # RUN: %t.call_graph -o /dev/null 2>&1 | FileCheck %s | ||
| 8 | |||
| 9 | # CHECK: {{.*}}.call_graph: parse error | ||
| 10 | |||
| 11 | # RUN: echo "A B C" > %t.call_graph | ||
| 12 | # RUN: not ld.lld %t --call-graph-ordering-file \ | ||
| 13 | # RUN: %t.call_graph -o /dev/null 2>&1 | FileCheck %s | ||
deps/lld/test/ELF/cgprofile-icf.s created+53| ... | @@ -0,0 +1,53 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 4 | |||
| 5 | # RUN: echo "A B 100" > %t.call_graph | ||
| 6 | # RUN: echo "A C 40" >> %t.call_graph | ||
| 7 | # RUN: echo "C D 61" >> %t.call_graph | ||
| 8 | # 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 | ||
| 10 | # 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 | ||
| 12 | |||
| 13 | .section .text.D,"ax",@progbits | ||
| 14 | .globl D | ||
| 15 | D: | ||
| 16 | mov $60, %rax | ||
| 17 | retq | ||
| 18 | |||
| 19 | .section .text.C,"ax",@progbits | ||
| 20 | .globl C | ||
| 21 | C: | ||
| 22 | mov $60, %rax | ||
| 23 | retq | ||
| 24 | |||
| 25 | .section .text.B,"ax",@progbits | ||
| 26 | .globl B | ||
| 27 | B: | ||
| 28 | mov $2, %rax | ||
| 29 | retq | ||
| 30 | |||
| 31 | .section .text.A,"ax",@progbits | ||
| 32 | .globl A | ||
| 33 | A: | ||
| 34 | mov $42, %rax | ||
| 35 | retq | ||
| 36 | |||
| 37 | # CHECK: Name: A | ||
| 38 | # CHECK-NEXT: Value: 0x201000 | ||
| 39 | # CHECK: Name: B | ||
| 40 | # CHECK-NEXT: Value: 0x201010 | ||
| 41 | # CHECK: Name: C | ||
| 42 | # CHECK-NEXT: Value: 0x201008 | ||
| 43 | # CHECK: Name: D | ||
| 44 | # CHECK-NEXT: Value: 0x201008 | ||
| 45 | |||
| 46 | # NOICF: Name: A | ||
| 47 | # NOICF-NEXT: Value: 0x201000 | ||
| 48 | # NOICF: Name: B | ||
| 49 | # NOICF-NEXT: Value: 0x201008 | ||
| 50 | # NOICF: Name: C | ||
| 51 | # NOICF-NEXT: Value: 0x201010 | ||
| 52 | # NOICF: Name: D | ||
| 53 | # NOICF-NEXT: Value: 0x201018 | ||
deps/lld/test/ELF/cgprofile-txt.s created+185| ... | @@ -0,0 +1,185 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 4 | # RUN: ld.lld -e A %t -o %t2 | ||
| 5 | # RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=NOSORT | ||
| 6 | |||
| 7 | # RUN: echo "A B 10" > %t.call_graph | ||
| 8 | # RUN: echo "A B 10" >> %t.call_graph | ||
| 9 | # RUN: echo "Aa B 80" >> %t.call_graph | ||
| 10 | # RUN: echo "A C 40" >> %t.call_graph | ||
| 11 | # RUN: echo "B C 30" >> %t.call_graph | ||
| 12 | # RUN: echo "C D 90" >> %t.call_graph | ||
| 13 | # RUN: echo "PP TS 100" >> %t.call_graph | ||
| 14 | # RUN: echo "_init2 _init 24567837" >> %t.call_graph | ||
| 15 | # RUN: echo "TS QC 9001" >> %t.call_graph | ||
| 16 | # RUN: echo "TooManyPreds0 TooManyPreds 10" >> %t.call_graph | ||
| 17 | # RUN: echo "TooManyPreds1 TooManyPreds 10" >> %t.call_graph | ||
| 18 | # RUN: echo "TooManyPreds2 TooManyPreds 10" >> %t.call_graph | ||
| 19 | # RUN: echo "TooManyPreds3 TooManyPreds 10" >> %t.call_graph | ||
| 20 | # RUN: echo "TooManyPreds4 TooManyPreds 10" >> %t.call_graph | ||
| 21 | # RUN: echo "TooManyPreds5 TooManyPreds 10" >> %t.call_graph | ||
| 22 | # RUN: echo "TooManyPreds6 TooManyPreds 10" >> %t.call_graph | ||
| 23 | # RUN: echo "TooManyPreds7 TooManyPreds 10" >> %t.call_graph | ||
| 24 | # RUN: echo "TooManyPreds8 TooManyPreds 10" >> %t.call_graph | ||
| 25 | # RUN: echo "TooManyPreds9 TooManyPreds 10" >> %t.call_graph | ||
| 26 | # RUN: echo "TooManyPreds10 TooManyPreds 11" >> %t.call_graph | ||
| 27 | # RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2 | ||
| 28 | # RUN: llvm-readobj -symbols %t2 | FileCheck %s | ||
| 29 | |||
| 30 | .section .text.D,"ax",@progbits | ||
| 31 | D: | ||
| 32 | retq | ||
| 33 | |||
| 34 | .section .text.C,"ax",@progbits | ||
| 35 | .globl C | ||
| 36 | C: | ||
| 37 | retq | ||
| 38 | |||
| 39 | .section .text.B,"ax",@progbits | ||
| 40 | .globl B | ||
| 41 | B: | ||
| 42 | retq | ||
| 43 | |||
| 44 | .section .text.A,"ax",@progbits | ||
| 45 | .globl A | ||
| 46 | A: | ||
| 47 | Aa: | ||
| 48 | retq | ||
| 49 | |||
| 50 | .section .ponies,"ax",@progbits,unique,1 | ||
| 51 | .globl TS | ||
| 52 | TS: | ||
| 53 | retq | ||
| 54 | |||
| 55 | .section .ponies,"ax",@progbits,unique,2 | ||
| 56 | .globl PP | ||
| 57 | PP: | ||
| 58 | retq | ||
| 59 | |||
| 60 | .section .other,"ax",@progbits,unique,1 | ||
| 61 | .globl QC | ||
| 62 | QC: | ||
| 63 | retq | ||
| 64 | |||
| 65 | .section .other,"ax",@progbits,unique,2 | ||
| 66 | .globl GB | ||
| 67 | GB: | ||
| 68 | retq | ||
| 69 | |||
| 70 | .section .init,"ax",@progbits,unique,1 | ||
| 71 | .globl _init | ||
| 72 | _init: | ||
| 73 | retq | ||
| 74 | |||
| 75 | .section .init,"ax",@progbits,unique,2 | ||
| 76 | .globl _init2 | ||
| 77 | _init2: | ||
| 78 | retq | ||
| 79 | |||
| 80 | .section .text.TooManyPreds,"ax",@progbits | ||
| 81 | TooManyPreds: | ||
| 82 | retq | ||
| 83 | 	retq | ||
| 84 | 	retq | ||
| 85 | 	retq | ||
| 86 | 	retq | ||
| 87 | 	retq | ||
| 88 | 	retq | ||
| 89 | 	retq | ||
| 90 | 	retq | ||
| 91 | 	retq | ||
| 92 | |||
| 93 | .section .text.TooManyPreds0,"ax",@progbits | ||
| 94 | TooManyPreds0: | ||
| 95 | retq | ||
| 96 | |||
| 97 | .section .text.TooManyPreds1,"ax",@progbits | ||
| 98 | TooManyPreds1: | ||
| 99 | retq | ||
| 100 | |||
| 101 | .section .text.TooManyPreds2,"ax",@progbits | ||
| 102 | TooManyPreds2: | ||
| 103 | retq | ||
| 104 | |||
| 105 | .section .text.TooManyPreds3,"ax",@progbits | ||
| 106 | TooManyPreds3: | ||
| 107 | retq | ||
| 108 | |||
| 109 | .section .text.TooManyPreds4,"ax",@progbits | ||
| 110 | TooManyPreds4: | ||
| 111 | retq | ||
| 112 | |||
| 113 | .section .text.TooManyPreds5,"ax",@progbits | ||
| 114 | TooManyPreds5: | ||
| 115 | retq | ||
| 116 | |||
| 117 | .section .text.TooManyPreds6,"ax",@progbits | ||
| 118 | TooManyPreds6: | ||
| 119 | retq | ||
| 120 | |||
| 121 | .section .text.TooManyPreds7,"ax",@progbits | ||
| 122 | TooManyPreds7: | ||
| 123 | retq | ||
| 124 | |||
| 125 | .section .text.TooManyPreds8,"ax",@progbits | ||
| 126 | TooManyPreds8: | ||
| 127 | retq | ||
| 128 | |||
| 129 | .section .text.TooManyPreds9,"ax",@progbits | ||
| 130 | TooManyPreds9: | ||
| 131 | retq | ||
| 132 | |||
| 133 | .section .text.TooManyPreds10,"ax",@progbits | ||
| 134 | TooManyPreds10: | ||
| 135 | retq | ||
| 136 | |||
| 137 | # CHECK: Name: D | ||
| 138 | # CHECK-NEXT: Value: 0x201003 | ||
| 139 | # CHECK: Name: TooManyPreds | ||
| 140 | # CHECK-NEXT: Value: 0x201004 | ||
| 141 | # CHECK: Name: TooManyPreds10 | ||
| 142 | # CHECK-NEXT: Value: 0x201018 | ||
| 143 | # CHECK: Name: A | ||
| 144 | # CHECK-NEXT: Value: 0x201000 | ||
| 145 | # CHECK: Name: B | ||
| 146 | # CHECK-NEXT: Value: 0x201001 | ||
| 147 | # CHECK: Name: C | ||
| 148 | # CHECK-NEXT: Value: 0x201002 | ||
| 149 | # CHECK: Name: GB | ||
| 150 | # CHECK-NEXT: Value: 0x20101F | ||
| 151 | # CHECK: Name: PP | ||
| 152 | # CHECK-NEXT: Value: 0x20101C | ||
| 153 | # CHECK: Name: QC | ||
| 154 | # CHECK-NEXT: Value: 0x20101E | ||
| 155 | # CHECK: Name: TS | ||
| 156 | # CHECK-NEXT: Value: 0x20101D | ||
| 157 | # CHECK: Name: _init | ||
| 158 | # CHECK-NEXT: Value: 0x201020 | ||
| 159 | # CHECK: Name: _init2 | ||
| 160 | # CHECK-NEXT: Value: 0x201021 | ||
| 161 | |||
| 162 | # NOSORT: Name: D | ||
| 163 | # NOSORT-NEXT: Value: 0x201000 | ||
| 164 | # NOSORT: Name: TooManyPreds | ||
| 165 | # NOSORT-NEXT: Value: 0x201004 | ||
| 166 | # NOSORT: Name: TooManyPreds10 | ||
| 167 | # NOSORT-NEXT: Value: 0x201018 | ||
| 168 | # NOSORT: Name: A | ||
| 169 | # NOSORT-NEXT: Value: 0x201003 | ||
| 170 | # NOSORT: Name: B | ||
| 171 | # NOSORT-NEXT: Value: 0x201002 | ||
| 172 | # NOSORT: Name: C | ||
| 173 | # NOSORT-NEXT: Value: 0x201001 | ||
| 174 | # NOSORT: Name: GB | ||
| 175 | # NOSORT-NEXT: Value: 0x20101C | ||
| 176 | # NOSORT: Name: PP | ||
| 177 | # NOSORT-NEXT: Value: 0x20101A | ||
| 178 | # NOSORT: Name: QC | ||
| 179 | # NOSORT-NEXT: Value: 0x20101B | ||
| 180 | # NOSORT: Name: TS | ||
| 181 | # NOSORT-NEXT: Value: 0x201019 | ||
| 182 | # NOSORT: Name: _init | ||
| 183 | # NOSORT-NEXT: Value: 0x20101D | ||
| 184 | # NOSORT: Name: _init2 | ||
| 185 | # NOSORT-NEXT: Value: 0x20101E | ||
deps/lld/test/ELF/cgprofile-warn.s created+36| ... | @@ -0,0 +1,36 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 4 | |||
| 5 | # RUN: echo "A B 100" > %t.call_graph | ||
| 6 | # RUN: echo "A C 40" >> %t.call_graph | ||
| 7 | # RUN: echo "B C 30" >> %t.call_graph | ||
| 8 | # RUN: echo "adena1 A 30" >> %t.call_graph | ||
| 9 | # RUN: echo "A adena2 30" >> %t.call_graph | ||
| 10 | # RUN: echo "poppy A 30" >> %t.call_graph | ||
| 11 | # RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o /dev/null \ | ||
| 12 | # RUN: -noinhibit-exec -icf=all 2>&1 | FileCheck %s | ||
| 13 | |||
| 14 | .section .text.C,"ax",@progbits | ||
| 15 | .globl C | ||
| 16 | C: | ||
| 17 | mov poppy, %rax | ||
| 18 | retq | ||
| 19 | |||
| 20 | B = 0x1234 | ||
| 21 | |||
| 22 | .section .text.A,"ax",@progbits | ||
| 23 | .globl A | ||
| 24 | A: | ||
| 25 | mov poppy, %rax | ||
| 26 | retq | ||
| 27 | |||
| 28 | # CHECK: unable to order absolute symbol: B | ||
| 29 | # CHECK: {{.*}}.call_graph: no such symbol: adena1 | ||
| 30 | # CHECK: {{.*}}.call_graph: no such symbol: adena2 | ||
| 31 | # CHECK: unable to order undefined symbol: poppy | ||
| 32 | |||
| 33 | # RUN: ld.lld %t --call-graph-ordering-file %t.call_graph -o /dev/null \ | ||
| 34 | # RUN: -noinhibit-exec -icf=all --no-warn-symbol-ordering 2>&1 \ | ||
| 35 | # RUN: | FileCheck %s --check-prefix=NOWARN | ||
| 36 | # NOWARN-NOT: unable to order | ||
deps/lld/test/ELF/color-diagnostics.test+3| ... | @@ -9,6 +9,9 @@ | ... | @@ -9,6 +9,9 @@ |
| 9 | # COLOR: {{ld.lld: .\[0;1;31merror: .\[0munknown argument: -xyz}} | 9 | # COLOR: {{ld.lld: .\[0;1;31merror: .\[0munknown argument: -xyz}} |
| 10 | # COLOR: {{ld.lld: .\[0;1;31merror: .\[0mcannot open /nosuchfile}} | 10 | # COLOR: {{ld.lld: .\[0;1;31merror: .\[0mcannot open /nosuchfile}} |
| 11 | 11 | ||
| 12 | # RUN: not ld.lld -color-diagnostics=foobar 2>&1 | FileCheck -check-prefix=ERR %s | ||
| 13 | # ERR: unknown option: --color-diagnostics=foobar | ||
| 14 | |||
| 12 | # RUN: not ld.lld /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s | 15 | # RUN: not ld.lld /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s |
| 13 | # RUN: not ld.lld -color-diagnostics=never /nosuchfile 2>&1 \ | 16 | # RUN: not ld.lld -color-diagnostics=never /nosuchfile 2>&1 \ |
| 14 | # RUN: | FileCheck -check-prefix=NOCOLOR %s | 17 | # RUN: | FileCheck -check-prefix=NOCOLOR %s |
deps/lld/test/ELF/combrelocs.s+3| ... | @@ -4,6 +4,9 @@ | ... | @@ -4,6 +4,9 @@ |
| 4 | # RUN: ld.lld -shared %t.o -o %t.out | 4 | # RUN: ld.lld -shared %t.o -o %t.out |
| 5 | # RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s | 5 | # RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s |
| 6 | 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 | |||
| 7 | # CHECK: Relocations [ | 10 | # CHECK: Relocations [ |
| 8 | # CHECK-NEXT: Section ({{.*}}) .rela.dyn { | 11 | # CHECK-NEXT: Section ({{.*}}) .rela.dyn { |
| 9 | # CHECK-NEXT: Relocation { | 12 | # CHECK-NEXT: Relocation { |
deps/lld/test/ELF/comdat-discarded-reloc.s created+17| ... | @@ -0,0 +1,17 @@ | ||
| 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/comdat-discarded-reloc.s -o %t2.o | ||
| 4 | # RUN: ld.lld -gc-sections %t.o %t2.o -o %t | ||
| 5 | |||
| 6 | ## ELF spec doesn't allow a relocation to point to a deduplicated | ||
| 7 | ## COMDAT section. Unfortunately this happens in practice (e.g. .eh_frame) | ||
| 8 | ## Test case checks we do not crash. | ||
| 9 | |||
| 10 | .global bar, _start | ||
| 11 | |||
| 12 | .section .text.foo,"aG",@progbits,group,comdat | ||
| 13 | |||
| 14 | .section .text | ||
| 15 | _start: | ||
| 16 | .quad .text.foo | ||
| 17 | .quad bar | ||
deps/lld/test/ELF/comdat-linkonce.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t.o %t2.o -o %t | 4 | // RUN: ld.lld -shared %t.o %t2.o -o %t |
deps/lld/test/ELF/comdat.s+5-5| ... | @@ -1,18 +1,18 @@ | ... | @@ -1,18 +1,18 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t.o %t.o %t2.o -o %t | 4 | // RUN: ld.lld -shared %t.o %t.o %t2.o -o %t |
| 4 | // RUN: llvm-objdump -d %t | FileCheck %s | 5 | // RUN: llvm-objdump -d %t | FileCheck %s |
| 5 | // RUN: llvm-readobj -s -t %t | FileCheck --check-prefix=READ %s | 6 | // RUN: llvm-readobj -s -t %t | FileCheck --check-prefix=READ %s |
| 6 | // REQUIRES: x86 | ||
| 7 | 7 | ||
| 8 | // Check that we don't crash with --gc-section and that we print a list of | 8 | // Check that we don't crash with --gc-section and that we print a list of |
| 9 | // reclaimed sections on stderr. | 9 | // reclaimed sections on stderr. |
| 10 | // RUN: ld.lld --gc-sections --print-gc-sections -shared %t.o %t.o %t2.o -o %t \ | 10 | // RUN: ld.lld --gc-sections --print-gc-sections -shared %t.o %t.o %t2.o -o %t \ |
| 11 | // RUN: 2>&1 | FileCheck --check-prefix=GC %s | 11 | // RUN: 2>&1 | FileCheck --check-prefix=GC %s |
| 12 | // GC: removing unused section from '.text' in file | 12 | // GC: removing unused section {{.*}}.o:(.text) |
| 13 | // GC: removing unused section from '.text3' in file | 13 | // GC: removing unused section {{.*}}.o:(.text3) |
| 14 | // GC: removing unused section from '.text' in file | 14 | // GC: removing unused section {{.*}}.o:(.text) |
| 15 | // GC: removing unused section from '.text' in file | 15 | // GC: removing unused section {{.*}}.o:(.text) |
| 16 | 16 | ||
| 17 | .section	.text2,"axG",@progbits,foo,comdat,unique,0 | 17 | .section	.text2,"axG",@progbits,foo,comdat,unique,0 |
| 18 | foo: | 18 | foo: |
deps/lld/test/ELF/common.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2 |
| 3 | // RUN: ld.lld %t %t2 -o %t3 | 4 | // RUN: ld.lld %t %t2 -o %t3 |
| 4 | // RUN: llvm-readobj -t -s %t3 | FileCheck %s | 5 | // RUN: llvm-readobj -t -s %t3 | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // CHECK: Name: .bss | 7 | // CHECK: Name: .bss |
| 8 | // CHECK-NEXT: Type: SHT_NOBITS | 8 | // CHECK-NEXT: Type: SHT_NOBITS |
deps/lld/test/ELF/compatible-section-types.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld -shared %t.o -o %t | 3 | // RUN: ld.lld -shared %t.o -o %t |
| 3 | // RUN: llvm-objdump -section-headers %t | FileCheck %s | 4 | // RUN: llvm-objdump -section-headers %t | FileCheck %s |
deps/lld/test/ELF/compressed-debug-conflict.s+27-6| ... | @@ -1,15 +1,15 @@ | ... | @@ -1,15 +1,15 @@ |
| 1 | # REQUIRES: x86, zlib | 1 | # REQUIRES: x86, zlib |
| 2 | # RUN: llvm-mc -filetype=obj -triple i686-linux-gnu -compress-debug-sections=zlib %s -o %t.o | 2 | # 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 |
| 4 | # RUN: not ld.lld %t.o %t.o -o %tout 2>&1 | FileCheck -check-prefix=ERROR %s | 4 | # RUN: not ld.lld %t.o %t.o -o /dev/null 2>&1 | FileCheck -check-prefix=ERROR %s |
| 5 | 5 | ||
| 6 | # OBJ: Sections [ | 6 | # OBJ: Sections [ |
| 7 | # OBJ: Section { | 7 | # OBJ: Section { |
| 8 | # OBJ: Index: 3 | 8 | # OBJ: Index: |
| 9 | # OBJ-NEXT: Name: .debug_line (16) | 9 | # OBJ: Name: .debug_line |
| 10 | # OBJ-NEXT: Type: SHT_PROGBITS (0x1) | 10 | # OBJ-NEXT: Type: SHT_PROGBITS |
| 11 | # OBJ-NEXT: Flags [ (0x800) | 11 | # OBJ-NEXT: Flags [ |
| 12 | # OBJ-NEXT: SHF_COMPRESSED (0x800) | 12 | # OBJ-NEXT: SHF_COMPRESSED |
| 13 | # OBJ-NEXT: ] | 13 | # OBJ-NEXT: ] |
| 14 | 14 | ||
| 15 | # ERROR: error: duplicate symbol: main | 15 | # ERROR: error: duplicate symbol: main |
| ... | @@ -27,3 +27,24 @@ main: | ... | @@ -27,3 +27,24 @@ main: |
| 27 | 	xorl	%eax, %eax | 27 | 	xorl	%eax, %eax |
| 28 | 	retl | 28 | 	retl |
| 29 | 	.file	2 "/tmp/repeat/repeat/repeat/repeat" "repeat.h" | 29 | 	.file	2 "/tmp/repeat/repeat/repeat/repeat" "repeat.h" |
| 30 | |||
| 31 | 	.section	.debug_abbrev,"",@progbits | ||
| 32 | 	.byte	1 # Abbreviation Code | ||
| 33 | 	.byte	17 # DW_TAG_compile_unit | ||
| 34 | 	.byte	0 # DW_CHILDREN_no | ||
| 35 | 	.byte	16 # DW_AT_stmt_list | ||
| 36 | 	.byte	23 # DW_FORM_sec_offset | ||
| 37 | 	.byte	0 # EOM(1) | ||
| 38 | 	.byte	0 # EOM(2) | ||
| 39 | 	.byte	0 # EOM(3) | ||
| 40 | |||
| 41 | .section	.debug_info,"",@progbits | ||
| 42 | 	.long	.Lend0 - .Lbegin0 # Length of Unit | ||
| 43 | .Lbegin0: | ||
| 44 | 	.short	4 # DWARF version number | ||
| 45 | 	.long	.debug_abbrev # Offset Into Abbrev. Section | ||
| 46 | 	.byte	4 # Address Size (in bytes) | ||
| 47 | 	.byte	1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit | ||
| 48 | 	.long	.debug_line # DW_AT_stmt_list | ||
| 49 | .Lend0: | ||
| 50 | 	.section	.debug_line,"",@progbits |
deps/lld/test/ELF/compressed-debug-input-err.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # REQUIRES: zlib, 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 %t.so -shared 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | ## Check we are able to report zlib decompressor errors. | ||
| 7 | # CHECK: error: {{.*}}.o:(.zdebug_str): decompress failed: zlib error: Z_DATA_ERROR | ||
| 8 | |||
| 9 | .section .zdebug_str,"MS",@progbits,1 | ||
| 10 | .ascii "ZLIB" | ||
| 11 | .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1 | ||
deps/lld/test/ELF/conflict-debug-variable-file-index.s created+103| ... | @@ -0,0 +1,103 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o %t.o -o %t 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | ## Check we are able to report errors even if DW_AT_decl_file | ||
| 6 | ## contains invalid file name index. | ||
| 7 | ## We did not try to support this intentionally but have | ||
| 8 | ## an error handling and reporting logic that can take care | ||
| 9 | ## of that and hence needs a test. | ||
| 10 | |||
| 11 | # CHECK: duplicate symbol: foo | ||
| 12 | # CHECK-NEXT: >>> defined at {{.*}}.o:(foo) | ||
| 13 | # CHECK-NEXT: >>> {{.*}}.o:(.bss+0x0) | ||
| 14 | |||
| 15 | # Used modified output from the following code and gcc 7.1.0: | ||
| 16 | # Source (1.c): | ||
| 17 | # int foo = 0; | ||
| 18 | # Invocation: g++ -g -S 1.c | ||
| 19 | |||
| 20 | .bss | ||
| 21 | .globl foo | ||
| 22 | .type foo, @object | ||
| 23 | .size foo, 4 | ||
| 24 | foo: | ||
| 25 | |||
| 26 | .text | ||
| 27 | .file 1 "1.c" | ||
| 28 | |||
| 29 | .section .debug_info,"",@progbits | ||
| 30 | .long 0x35 # Compile Unit: length = 0x0000004b) | ||
| 31 | .value 0x4 # version = 0x0004 | ||
| 32 | .long 0 # abbr_offset = 0x0 | ||
| 33 | .byte 0x8 # addr_size = 0x08 | ||
| 34 | |||
| 35 | .uleb128 0x1 # DW_TAG_compile_unit [1] * | ||
| 36 | .long 0 # DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000000] = ) | ||
| 37 | .byte 0x4 # DW_AT_language [DW_FORM_data1] (DW_LANG_C_plus_plus) | ||
| 38 | .string "1.c" # DW_AT_name [DW_FORM_string] ("1.c") | ||
| 39 | .long 0 # DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000000] = ) | ||
| 40 | .long 0 # DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000) | ||
| 41 | |||
| 42 | .uleb128 0x2 # DW_TAG_variable [2] | ||
| 43 | .string "foo" # DW_AT_name [DW_FORM_string] ("foo") | ||
| 44 | .byte 0xFE # DW_AT_decl_file [DW_FORM_data1] <broken file> | ||
| 45 | .byte 0x1 # DW_AT_decl_line [DW_FORM_data1] (1) | ||
| 46 | .long 0x32 # DW_AT_type [DW_FORM_ref4] (cu + 0x0032 => {0x00000032}) | ||
| 47 | .uleb128 0x9 # DW_AT_external [DW_FORM_flag_present] (true) | ||
| 48 | .byte 0x3 | ||
| 49 | .quad foo # DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) | ||
| 50 | |||
| 51 | .uleb128 0x3 # DW_TAG_base_type [3] | ||
| 52 | .byte 0x4 # DW_AT_byte_size [DW_FORM_data1] (0x04) | ||
| 53 | .byte 0x5 # DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed) | ||
| 54 | .string "int" # DW_AT_name [DW_FORM_string] ("int") | ||
| 55 | |||
| 56 | .section .debug_abbrev,"",@progbits | ||
| 57 | .uleb128 0x1 # Abbreviation code. | ||
| 58 | .uleb128 0x11 # DW_TAG_compile_unit | ||
| 59 | |||
| 60 | .byte 0x1 # ID | ||
| 61 | .uleb128 0x25 # DW_AT_producer, DW_FORM_strp | ||
| 62 | .uleb128 0xe | ||
| 63 | .uleb128 0x13 # DW_AT_language, DW_FORM_data1 | ||
| 64 | .uleb128 0xb | ||
| 65 | .uleb128 0x3 # DW_AT_name, DW_FORM_string | ||
| 66 | .uleb128 0x8 | ||
| 67 | .uleb128 0x1b # DW_AT_comp_dir, DW_FORM_strp | ||
| 68 | .uleb128 0xe | ||
| 69 | .uleb128 0x10 # DW_AT_stmt_list, DW_FORM_sec_offset | ||
| 70 | .uleb128 0x17 | ||
| 71 | .byte 0 | ||
| 72 | .byte 0 | ||
| 73 | |||
| 74 | .uleb128 0x2 # ID | ||
| 75 | .uleb128 0x34 # DW_TAG_variable, DW_CHILDREN_no | ||
| 76 | .byte 0 | ||
| 77 | .uleb128 0x3 # DW_AT_name, DW_FORM_string | ||
| 78 | .uleb128 0x8 | ||
| 79 | .uleb128 0x3a # DW_AT_decl_file, DW_FORM_data1 | ||
| 80 | .uleb128 0xb | ||
| 81 | .uleb128 0x3b # DW_AT_decl_line, DW_FORM_data1 | ||
| 82 | .uleb128 0xb | ||
| 83 | .uleb128 0x49 # DW_AT_type, DW_FORM_ref4 | ||
| 84 | .uleb128 0x13 | ||
| 85 | .uleb128 0x3f # DW_AT_external, DW_FORM_flag_present | ||
| 86 | .uleb128 0x19 | ||
| 87 | .uleb128 0x2 # DW_AT_location, DW_FORM_exprloc | ||
| 88 | .uleb128 0x18 | ||
| 89 | .byte 0 | ||
| 90 | .byte 0 | ||
| 91 | |||
| 92 | .uleb128 0x3 # ID | ||
| 93 | .uleb128 0x24 # DW_TAG_base_type, DW_CHILDREN_no | ||
| 94 | .byte 0 | ||
| 95 | .uleb128 0xb # DW_AT_byte_size, DW_FORM_data1 | ||
| 96 | .uleb128 0xb | ||
| 97 | .uleb128 0x3e # DW_AT_encoding, DW_FORM_data1 | ||
| 98 | .uleb128 0xb | ||
| 99 | .uleb128 0x3 # DW_AT_name, DW_FORM_string | ||
| 100 | .uleb128 0x8 | ||
| 101 | .byte 0 | ||
| 102 | .byte 0 | ||
| 103 | .byte 0 | ||
deps/lld/test/ELF/conflict-debug-variable.s+33-3| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | # RUN: llvm-dwarfdump %t.o | FileCheck -check-prefix=INPUT %s | 3 | # RUN: llvm-dwarfdump %t.o | FileCheck -check-prefix=INPUT %s |
| 3 | # RUN: not ld.lld %t.o %t.o -o %t 2>&1 | FileCheck %s | 4 | # RUN: not ld.lld %t.o %t.o -o %t 2>&1 | FileCheck %s |
| ... | @@ -7,14 +8,14 @@ | ... | @@ -7,14 +8,14 @@ |
| 7 | # INPUT-NEXT: DW_AT_name ("foo") | 8 | # INPUT-NEXT: DW_AT_name ("foo") |
| 8 | # INPUT-NEXT: DW_AT_decl_file ("1.c") | 9 | # INPUT-NEXT: DW_AT_decl_file ("1.c") |
| 9 | # INPUT-NEXT: DW_AT_decl_line (1) | 10 | # INPUT-NEXT: DW_AT_decl_line (1) |
| 10 | # INPUT-NEXT: DW_AT_type (cu + 0x0032 "int") | 11 | # INPUT-NEXT: DW_AT_type (0x00000032 "int") |
| 11 | # INPUT-NEXT: DW_AT_external (true) | 12 | # INPUT-NEXT: DW_AT_external (true) |
| 12 | # INPUT-NEXT: DW_AT_location (DW_OP_addr 0x0) | 13 | # INPUT-NEXT: DW_AT_location (DW_OP_addr 0x0) |
| 13 | # INPUT: DW_TAG_variable | 14 | # INPUT: DW_TAG_variable |
| 14 | # INPUT-NEXT: DW_AT_name ("bar") | 15 | # INPUT-NEXT: DW_AT_name ("bar") |
| 15 | # INPUT-NEXT: DW_AT_decl_file ("1.c") | 16 | # INPUT-NEXT: DW_AT_decl_file ("1.c") |
| 16 | # INPUT-NEXT: DW_AT_decl_line (2) | 17 | # INPUT-NEXT: DW_AT_decl_line (2) |
| 17 | # INPUT-NEXT: DW_AT_type (cu + 0x0032 "int") | 18 | # INPUT-NEXT: DW_AT_type (0x00000032 "int") |
| 18 | # INPUT-NEXT: DW_AT_external (true) | 19 | # INPUT-NEXT: DW_AT_external (true) |
| 19 | # INPUT-NEXT: DW_AT_location (DW_OP_addr 0x0) | 20 | # INPUT-NEXT: DW_AT_location (DW_OP_addr 0x0) |
| 20 | 21 | ||
| ... | @@ -38,6 +39,7 @@ | ... | @@ -38,6 +39,7 @@ |
| 38 | # Source (1.c): | 39 | # Source (1.c): |
| 39 | # int foo = 0; | 40 | # int foo = 0; |
| 40 | # int bar = 1; | 41 | # int bar = 1; |
| 42 | # static int zed = 3; | ||
| 41 | # Invocation: g++ -g -S 1.c | 43 | # Invocation: g++ -g -S 1.c |
| 42 | 44 | ||
| 43 | .bss | 45 | .bss |
| ... | @@ -51,12 +53,16 @@ foo: | ... | @@ -51,12 +53,16 @@ foo: |
| 51 | .type bar, @object | 53 | .type bar, @object |
| 52 | .size bar, 4 | 54 | .size bar, 4 |
| 53 | bar: | 55 | bar: |
| 56 | .byte 0 | ||
| 57 | |||
| 58 | .local zed | ||
| 59 | zed: | ||
| 54 | 60 | ||
| 55 | .text | 61 | .text |
| 56 | .file 1 "1.c" | 62 | .file 1 "1.c" |
| 57 | 63 | ||
| 58 | .section .debug_info,"",@progbits | 64 | .section .debug_info,"",@progbits |
| 59 | .long 0x4b # Compile Unit: length = 0x0000004b) | 65 | .long 0x5a # Compile Unit: length = 0x0000004b) |
| 60 | .value 0x4 # version = 0x0004 | 66 | .value 0x4 # version = 0x0004 |
| 61 | .long 0 # abbr_offset = 0x0 | 67 | .long 0 # abbr_offset = 0x0 |
| 62 | .byte 0x8 # addr_size = 0x08 | 68 | .byte 0x8 # addr_size = 0x08 |
| ... | @@ -90,6 +96,14 @@ bar: | ... | @@ -90,6 +96,14 @@ bar: |
| 90 | .uleb128 0x9 # DW_AT_external [DW_FORM_flag_present] (true) | 96 | .uleb128 0x9 # DW_AT_external [DW_FORM_flag_present] (true) |
| 91 | .byte 0x3 | 97 | .byte 0x3 |
| 92 | .quad bar # DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) | 98 | .quad bar # DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) |
| 99 | |||
| 100 | .uleb128 0x4 # DW_TAG_variable [2] | ||
| 101 | .string "zed" # DW_AT_name [DW_FORM_string] ("zed") | ||
| 102 | .byte 0x1 # DW_AT_decl_file [DW_FORM_data1] ("1.c") | ||
| 103 | .byte 0x3 # DW_AT_decl_line [DW_FORM_data1] (2) | ||
| 104 | .long 0x32 # DW_AT_type [DW_FORM_ref4] (cu + 0x0032 => {0x00000032}) | ||
| 105 | .quad zed # DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) | ||
| 106 | |||
| 93 | .byte 0 # END | 107 | .byte 0 # END |
| 94 | 108 | ||
| 95 | 109 | ||
| ... | @@ -140,5 +154,21 @@ bar: | ... | @@ -140,5 +154,21 @@ bar: |
| 140 | .uleb128 0x8 | 154 | .uleb128 0x8 |
| 141 | .byte 0 | 155 | .byte 0 |
| 142 | .byte 0 | 156 | .byte 0 |
| 157 | |||
| 158 | .uleb128 0x4 # ID | ||
| 159 | .uleb128 0x34 # DW_TAG_variable, DW_CHILDREN_no | ||
| 160 | .byte 0 | ||
| 161 | .uleb128 0x3 # DW_AT_name, DW_FORM_string | ||
| 162 | .uleb128 0x8 | ||
| 163 | .uleb128 0x3a # DW_AT_decl_file, DW_FORM_data1 | ||
| 164 | .uleb128 0xb | ||
| 165 | .uleb128 0x3b # DW_AT_decl_line, DW_FORM_data1 | ||
| 166 | .uleb128 0xb | ||
| 167 | .uleb128 0x49 # DW_AT_type, DW_FORM_ref4 | ||
| 168 | .uleb128 0x13 | ||
| 169 | .uleb128 0x2 # DW_AT_location, DW_FORM_exprloc | ||
| 170 | .uleb128 0x18 | ||
| 171 | .byte 0 | ||
| 143 | .byte 0 | 172 | .byte 0 |
| 144 | 173 | ||
| 174 | .byte 0 |
deps/lld/test/ELF/conflict-debug-variable2.s+2-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | 3 | ||
| 3 | # RUN: llvm-dwarfdump -v %t.o | FileCheck -check-prefix=INPUT %s | 4 | # RUN: llvm-dwarfdump -v %t.o | FileCheck -check-prefix=INPUT %s |
| ... | @@ -18,7 +19,7 @@ | ... | @@ -18,7 +19,7 @@ |
| 18 | # INPUT-NEXT: DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) | 19 | # INPUT-NEXT: DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) |
| 19 | 20 | ||
| 20 | ## Check we use information from .debug_info in messages. | 21 | ## Check we use information from .debug_info in messages. |
| 21 | # RUN: not ld.lld %t.o %t.o -o %t 2>&1 | FileCheck %s | 22 | # RUN: not ld.lld %t.o %t.o -o /dev/null 2>&1 | FileCheck %s |
| 22 | # CHECK: duplicate symbol: bar | 23 | # CHECK: duplicate symbol: bar |
| 23 | # CHECK-NEXT: >>> defined at test.c:2 | 24 | # CHECK-NEXT: >>> defined at test.c:2 |
| 24 | # CHECK-NEXT: >>> {{.*}}:(bar) | 25 | # CHECK-NEXT: >>> {{.*}}:(bar) |
deps/lld/test/ELF/conflict-variable-linkage-name.s created+176| ... | @@ -0,0 +1,176 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | ## Check we can report the locations of 2 different "bar" variables. | ||
| 6 | # CHECK: duplicate symbol: A::bar | ||
| 7 | # CHECK-NEXT: >>> defined at 1.cpp:2 | ||
| 8 | # CHECK-NEXT: >>> {{.*}}:(A::bar) | ||
| 9 | # CHECK-NEXT: >>> defined at 1.cpp:2 | ||
| 10 | # CHECK-NEXT: >>> {{.*}}:(.bss+0x0) | ||
| 11 | # CHECK: duplicate symbol: Z::bar | ||
| 12 | # CHECK-NEXT: >>> defined at 1.cpp:6 | ||
| 13 | # CHECK-NEXT: >>> {{.*}}:(Z::bar) | ||
| 14 | # CHECK-NEXT: >>> defined at 1.cpp:6 | ||
| 15 | # CHECK-NEXT: >>> {{.*}}:(.data+0x0) | ||
| 16 | |||
| 17 | # Used reduced output from following code and clang version 7.0.0 (trunk 332701) | ||
| 18 | # to produce this input file: | ||
| 19 | # Source (1.cpp): | ||
| 20 | # namespace A { | ||
| 21 | # int bar; | ||
| 22 | # } | ||
| 23 | # | ||
| 24 | # namespace Z { | ||
| 25 | # int bar; | ||
| 26 | # } | ||
| 27 | # Invocation: clang-7 -g -S 1.cpp | ||
| 28 | |||
| 29 | .text | ||
| 30 | .file "1.cpp" | ||
| 31 | .file 1 "/path" "1.cpp" | ||
| 32 | |||
| 33 | .type _ZN1A3barE,@object | ||
| 34 | .bss | ||
| 35 | .globl _ZN1A3barE | ||
| 36 | _ZN1A3barE: | ||
| 37 | .long 0 | ||
| 38 | .size _ZN1A3barE, 4 | ||
| 39 | |||
| 40 | .type _ZN1Z3barE,@object | ||
| 41 | .data | ||
| 42 | .globl _ZN1Z3barE | ||
| 43 | _ZN1Z3barE: | ||
| 44 | .long 1 | ||
| 45 | .size _ZN1Z3barE, 4 | ||
| 46 | |||
| 47 | .section .debug_str,"MS",@progbits,1 | ||
| 48 | .Linfo_string0: | ||
| 49 | .asciz "clang version 7.0.0 (trunk 332701)" # string offset=0 | ||
| 50 | .Linfo_string1: | ||
| 51 | .asciz "1.cpp" # string offset=35 | ||
| 52 | .Linfo_string2: | ||
| 53 | .asciz "/path" # string offset=41 | ||
| 54 | .Linfo_string3: | ||
| 55 | .asciz "A" # string offset=87 | ||
| 56 | .Linfo_string4: | ||
| 57 | .asciz "bar" # string offset=89 | ||
| 58 | .Linfo_string5: | ||
| 59 | .asciz "int" # string offset=93 | ||
| 60 | .Linfo_string6: | ||
| 61 | .asciz "_ZN1A3barE" # string offset=97 | ||
| 62 | .Linfo_string7: | ||
| 63 | .asciz "Z" # string offset=108 | ||
| 64 | .Linfo_string8: | ||
| 65 | .asciz "_ZN1Z3barE" # string offset=110 | ||
| 66 | |||
| 67 | .section .debug_abbrev,"",@progbits | ||
| 68 | .byte 1 # Abbreviation Code | ||
| 69 | .byte 17 # DW_TAG_compile_unit | ||
| 70 | .byte 1 # DW_CHILDREN_yes | ||
| 71 | .byte 37 # DW_AT_producer | ||
| 72 | .byte 14 # DW_FORM_strp | ||
| 73 | .byte 19 # DW_AT_language | ||
| 74 | .byte 5 # DW_FORM_data2 | ||
| 75 | .byte 3 # DW_AT_name | ||
| 76 | .byte 14 # DW_FORM_strp | ||
| 77 | .byte 16 # DW_AT_stmt_list | ||
| 78 | .byte 23 # DW_FORM_sec_offset | ||
| 79 | .byte 27 # DW_AT_comp_dir | ||
| 80 | .byte 14 # DW_FORM_strp | ||
| 81 | .ascii "\264B" # DW_AT_GNU_pubnames | ||
| 82 | .byte 25 # DW_FORM_flag_present | ||
| 83 | .byte 0 # EOM(1) | ||
| 84 | .byte 0 # EOM(2) | ||
| 85 | |||
| 86 | .byte 2 # Abbreviation Code | ||
| 87 | .byte 57 # DW_TAG_namespace | ||
| 88 | .byte 1 # DW_CHILDREN_yes | ||
| 89 | .byte 3 # DW_AT_name | ||
| 90 | .byte 14 # DW_FORM_strp | ||
| 91 | .byte 0 # EOM(1) | ||
| 92 | .byte 0 # EOM(2) | ||
| 93 | |||
| 94 | .byte 3 # Abbreviation Code | ||
| 95 | .byte 52 # DW_TAG_variable | ||
| 96 | .byte 0 # DW_CHILDREN_no | ||
| 97 | .byte 3 # DW_AT_name | ||
| 98 | .byte 14 # DW_FORM_strp | ||
| 99 | .byte 73 # DW_AT_type | ||
| 100 | .byte 19 # DW_FORM_ref4 | ||
| 101 | .byte 63 # DW_AT_external | ||
| 102 | .byte 25 # DW_FORM_flag_present | ||
| 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 2 # DW_AT_location | ||
| 108 | .byte 24 # DW_FORM_exprloc | ||
| 109 | .byte 110 # DW_AT_linkage_name | ||
| 110 | .byte 14 # DW_FORM_strp | ||
| 111 | .byte 0 # EOM(1) | ||
| 112 | .byte 0 # EOM(2) | ||
| 113 | |||
| 114 | .byte 4 # Abbreviation Code | ||
| 115 | .byte 36 # DW_TAG_base_type | ||
| 116 | .byte 0 # DW_CHILDREN_no | ||
| 117 | .byte 3 # DW_AT_name | ||
| 118 | .byte 14 # DW_FORM_strp | ||
| 119 | .byte 62 # DW_AT_encoding | ||
| 120 | .byte 11 # DW_FORM_data1 | ||
| 121 | .byte 11 # DW_AT_byte_size | ||
| 122 | .byte 11 # DW_FORM_data1 | ||
| 123 | .byte 0 # EOM(1) | ||
| 124 | .byte 0 # EOM(2) | ||
| 125 | .byte 0 # EOM(3) | ||
| 126 | |||
| 127 | .section .debug_info,"",@progbits | ||
| 128 | .long 96 # Length of Unit | ||
| 129 | .short 4 # DWARF version number | ||
| 130 | .long .debug_abbrev # Offset Into Abbrev. Section | ||
| 131 | .byte 8 # Address Size (in bytes) | ||
| 132 | |||
| 133 | .byte 1 # Abbrev [1] 0xb:0x59 DW_TAG_compile_unit | ||
| 134 | .long .Linfo_string0 # DW_AT_producer | ||
| 135 | .short 4 # DW_AT_language | ||
| 136 | .long .Linfo_string1 # DW_AT_name | ||
| 137 | .long 0 # DW_AT_stmt_list | ||
| 138 | .long .Linfo_string2 # DW_AT_comp_dir | ||
| 139 | # DW_AT_GNU_pubnames | ||
| 140 | |||
| 141 | .byte 2 # Abbrev [2] 0x1e:0x1f DW_TAG_namespace | ||
| 142 | .long .Linfo_string3 # DW_AT_name | ||
| 143 | |||
| 144 | .byte 3 # Abbrev [3] 0x23:0x19 DW_TAG_variable | ||
| 145 | .long .Linfo_string4 # DW_AT_name | ||
| 146 | .long 61 # DW_AT_type | ||
| 147 | # DW_AT_external | ||
| 148 | .byte 1 # DW_AT_decl_file | ||
| 149 | .byte 2 # DW_AT_decl_line | ||
| 150 | .byte 9 # DW_AT_location | ||
| 151 | .byte 3 | ||
| 152 | .quad _ZN1A3barE | ||
| 153 | .long .Linfo_string6 # DW_AT_linkage_name | ||
| 154 | .byte 0 # End Of Children Mark | ||
| 155 | |||
| 156 | .byte 4 # Abbrev [4] 0x3d:0x7 DW_TAG_base_type | ||
| 157 | .long .Linfo_string5 # DW_AT_name | ||
| 158 | .byte 5 # DW_AT_encoding | ||
| 159 | .byte 4 # DW_AT_byte_size | ||
| 160 | |||
| 161 | .byte 2 # Abbrev [2] 0x44:0x1f DW_TAG_namespace | ||
| 162 | .long .Linfo_string7 # DW_AT_name | ||
| 163 | |||
| 164 | .byte 3 # Abbrev [3] 0x49:0x19 DW_TAG_variable | ||
| 165 | .long .Linfo_string4 # DW_AT_name | ||
| 166 | .long 61 # DW_AT_type | ||
| 167 | # DW_AT_external | ||
| 168 | .byte 1 # DW_AT_decl_file | ||
| 169 | .byte 6 # DW_AT_decl_line | ||
| 170 | .byte 9 # DW_AT_location | ||
| 171 | .byte 3 | ||
| 172 | .quad _ZN1Z3barE | ||
| 173 | .long .Linfo_string8 # DW_AT_linkage_name | ||
| 174 | |||
| 175 | .byte 0 # End Of Children Mark | ||
| 176 | .byte 0 # End Of Children Mark | ||
deps/lld/test/ELF/conflict.s+1-1| ... | @@ -34,7 +34,7 @@ | ... | @@ -34,7 +34,7 @@ |
| 34 | # ARCHIVE-NEXT: >>> defined at {{.*}}:(.text+0x0) in archive {{.*}}.a | 34 | # ARCHIVE-NEXT: >>> defined at {{.*}}:(.text+0x0) in archive {{.*}}.a |
| 35 | 35 | ||
| 36 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/conflict-debug.s -o %t-dbg.o | 36 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/conflict-debug.s -o %t-dbg.o |
| 37 | # RUN: not ld.lld %t-dbg.o %t-dbg.o -o %t-dbg 2>&1 | FileCheck -check-prefix=DBGINFO %s | 37 | # RUN: not ld.lld %t-dbg.o %t-dbg.o -o /dev/null 2>&1 | FileCheck -check-prefix=DBGINFO %s |
| 38 | 38 | ||
| 39 | # DBGINFO: duplicate symbol: zed | 39 | # DBGINFO: duplicate symbol: zed |
| 40 | # DBGINFO-NEXT: >>> defined at conflict-debug.s:4 | 40 | # DBGINFO-NEXT: >>> defined at conflict-debug.s:4 |
deps/lld/test/ELF/copy-errors.s+11-4| ... | @@ -7,12 +7,19 @@ | ... | @@ -7,12 +7,19 @@ |
| 7 | // CHECK: cannot preempt symbol: bar | 7 | // CHECK: cannot preempt symbol: bar |
| 8 | // CHECK: >>> defined in {{.*}}.so | 8 | // CHECK: >>> defined in {{.*}}.so |
| 9 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x1) | 9 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x1) |
| 10 | // CHECK: symbol 'zed' defined in {{.*}}.so has no type | 10 | |
| 11 | // CHECK: error: symbol 'zed' has no type | ||
| 12 | // CHECK-NEXT: >>> defined in {{.*}}.so | ||
| 13 | // CHECK-NEXT: >>> referenced by {{.*}}.o:(.text+0x6) | ||
| 11 | 14 | ||
| 12 | // RUN: not ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s --check-prefix=NOINHIBIT | 15 | // RUN: not ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s --check-prefix=NOINHIBIT |
| 13 | // NOINHIBIT: warning: symbol 'zed' defined in {{.*}}.so has no type | 16 | // NOINHIBIT: warning: symbol 'zed' has no type |
| 17 | // NOINHIBIT-NEXT: >>> defined in {{.*}}.so | ||
| 18 | // NOINHIBIT-NEXT: >>> referenced by {{.*}}.o:(.text+0x6) | ||
| 14 | 19 | ||
| 15 | .global _start | 20 | .global _start |
| 16 | _start: | 21 | _start: |
| 17 | call bar | 22 | .byte 0xe8 |
| 18 | call zed | 23 | .long bar - . |
| 24 | .byte 0xe8 | ||
| 25 | .long zed - . |
deps/lld/test/ELF/copy-in-shared.s+2-2| ... | @@ -2,9 +2,9 @@ | ... | @@ -2,9 +2,9 @@ |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-in-shared.s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-in-shared.s -o %t1.o |
| 3 | // RUN: ld.lld -shared %t1.o -o %t1.so | 3 | // RUN: ld.lld -shared %t1.o -o %t1.so |
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o |
| 5 | // RUN: not ld.lld %t2.o %t1.so -o %t2.so -shared 2>&1 | FileCheck %s | 5 | // RUN: not ld.lld %t2.o %t1.so -o /dev/null -shared 2>&1 | FileCheck %s |
| 6 | 6 | ||
| 7 | // CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo in readonly segment | 7 | // CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 8 | // CHECK: >>> defined in {{.*}}.so | 8 | // CHECK: >>> defined in {{.*}}.so |
| 9 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | 9 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) |
| 10 | 10 |
deps/lld/test/ELF/copy-rel-corrupted.s+3-2| ... | @@ -1,10 +1,11 @@ | ... | @@ -1,10 +1,11 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: llvm-mc %p/Inputs/copy-rel-corrupted.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux | 3 | // RUN: llvm-mc %p/Inputs/copy-rel-corrupted.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | // RUN: ld.lld %t2.o -o %t2.so -shared | 4 | // RUN: ld.lld %t2.o -o %t2.so -shared |
| 4 | // RUN: not ld.lld %t.o %t2.so -o %t.exe 2>&1 | FileCheck %s | 5 | // RUN: not ld.lld %t.o %t2.so -o /dev/null 2>&1 | FileCheck %s |
| 5 | 6 | ||
| 6 | // CHECK: error: cannot create a copy relocation for symbol x | 7 | // CHECK: error: cannot create a copy relocation for symbol x |
| 7 | 8 | ||
| 8 | .global _start | 9 | .global _start |
| 9 | _start: | 10 | _start: |
| 10 | call x | 11 | .long x - . |
deps/lld/test/ELF/copy-rel-pie-error.s+4-3| ... | @@ -1,13 +1,14 @@ | ... | @@ -1,13 +1,14 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux | 3 | // RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | // RUN: ld.lld %t2.o -o %t2.so -shared | 4 | // RUN: ld.lld %t2.o -o %t2.so -shared |
| 4 | // RUN: not ld.lld %t.o %t2.so -o %t.exe -pie 2>&1 | FileCheck %s | 5 | // RUN: not ld.lld %t.o %t2.so -o /dev/null -pie 2>&1 | FileCheck %s |
| 5 | 6 | ||
| 6 | // CHECK: can't create dynamic relocation R_X86_64_64 against symbol: bar | 7 | // CHECK: can't create dynamic relocation R_X86_64_64 against symbol: bar in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 7 | // CHECK: >>> defined in {{.*}}.so | 8 | // CHECK: >>> defined in {{.*}}.so |
| 8 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) | 9 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x0) |
| 9 | 10 | ||
| 10 | // CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo | 11 | // CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 11 | // CHECK: >>> defined in {{.*}}.so | 12 | // CHECK: >>> defined in {{.*}}.so |
| 12 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x8) | 13 | // CHECK: >>> referenced by {{.*}}.o:(.text+0x8) |
| 13 | 14 |
deps/lld/test/ELF/copy-rel-pie.s+5-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux | 3 | // RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | // RUN: ld.lld %t2.o -o %t2.so -shared | 4 | // RUN: ld.lld %t2.o -o %t2.so -shared |
| ... | @@ -7,8 +8,10 @@ | ... | @@ -7,8 +8,10 @@ |
| 7 | 8 | ||
| 8 | .global _start | 9 | .global _start |
| 9 | _start: | 10 | _start: |
| 10 | call bar | 11 | .byte 0xe8 |
| 11 | call foo | 12 | .long bar - . -4 |
| 13 | .byte 0xe8 | ||
| 14 | .long foo - . -4 | ||
| 12 | 15 | ||
| 13 | // CHECK: Name: .plt | 16 | // CHECK: Name: .plt |
| 14 | // CHECK-NEXT: Type: SHT_PROGBITS | 17 | // CHECK-NEXT: Type: SHT_PROGBITS |
deps/lld/test/ELF/copy-rel-version.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-version.s -o %t1.o | ||
| 4 | // RUN: echo "v1 {}; v2 {};" > %t.ver | ||
| 5 | // RUN: ld.lld %t1.o -shared -soname t1.so --version-script=%t.ver -o %t1.so | ||
| 6 | // RUN: ld.lld %t.o %t1.so -o %t | ||
| 7 | // RUN: llvm-readobj -t %t | FileCheck %s | ||
| 8 | |||
| 9 | .global _start | ||
| 10 | _start: | ||
| 11 | leaq foo, %rax | ||
| 12 | |||
| 13 | // CHECK: Name: foo ( | ||
| 14 | // CHECK-NEXT: Value: | ||
| 15 | // CHECK-NEXT: Size: 8 | ||
deps/lld/test/ELF/copy-relocation-zero-abs-addr.s created+44| ... | @@ -0,0 +1,44 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-relocation-zero-abs-addr.s -o %t.o | ||
| 3 | // RUN: ld.lld -shared -o %t2.so %t.o | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t3.o | ||
| 5 | // 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 | ||
| 8 | |||
| 9 | // This tests that symbols with absolute addresses are properly | ||
| 10 | // handled. Normal DSO symbols are handled as usual. | ||
| 11 | |||
| 12 | .text | ||
| 13 | .globl _start | ||
| 14 | _start: | ||
| 15 | movl $5, foo | ||
| 16 | |||
| 17 | // ABSADDR: Name: ver1 | ||
| 18 | // ABSADDR-NEXT: Value: 0x0 | ||
| 19 | // ABSADDR-NEXT: Size: 0 | ||
| 20 | // ABSADDR-NEXT: Binding: Global | ||
| 21 | // ABSADDR-NEXT: Type: None | ||
| 22 | // ABSADDR-NEXT: Other: 0 | ||
| 23 | // ABSADDR-NEXT: Section: Absolute (0xFFF1) | ||
| 24 | // ABSADDR-NEXT: } | ||
| 25 | // ABSADDR-NEXT: Symbol { | ||
| 26 | // ABSADDR-NEXT: Name: ver2 | ||
| 27 | // ABSADDR-NEXT: Value: 0x0 | ||
| 28 | // ABSADDR-NEXT: Size: 0 | ||
| 29 | // ABSADDR-NEXT: Binding: Global | ||
| 30 | // ABSADDR-NEXT: Type: None | ||
| 31 | // ABSADDR-NEXT: Other: 0 | ||
| 32 | // ABSADDR-NEXT: Section: Absolute (0xFFF1) | ||
| 33 | // ABSADDR-NEXT: } | ||
| 34 | |||
| 35 | // CHECK: Relocations [ | ||
| 36 | // CHECK-NEXT: Section (5) .rela.dyn { | ||
| 37 | // CHECK-NEXT: Relocation { | ||
| 38 | // CHECK-NEXT: Offset: | ||
| 39 | // CHECK-NEXT: Type: R_X86_64_COPY | ||
| 40 | // CHECK-NEXT: Symbol: foo | ||
| 41 | // CHECK-NEXT: Addend: | ||
| 42 | // CHECK-NEXT: } | ||
| 43 | // CHECK-NEXT: } | ||
| 44 | // CHECK-NEXT: ] | ||
deps/lld/test/ELF/copy-relocation-zero-nonabs-addr.s created+29| ... | @@ -0,0 +1,29 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-relocation-zero-nonabs-addr.s -o %t1.o | ||
| 3 | // RUN: ld.lld -Ttext=0 -o %t2.so --script=%p/Inputs/copy-relocation-zero-nonabs-addr.script %t1.o -shared | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t3.o | ||
| 5 | // RUN: ld.lld %t2.so %t3.o -o %t4 | ||
| 6 | // RUN: llvm-readobj --symbols %t2.so | FileCheck --check-prefix=CHECKSO %s | ||
| 7 | // RUN: llvm-readobj --symbols %t4 | FileCheck %s | ||
| 8 | |||
| 9 | .text | ||
| 10 | .globl _start | ||
| 11 | _start: | ||
| 12 | movl $5, foo | ||
| 13 | |||
| 14 | // Make sure foo has st_value == 0. | ||
| 15 | // CHECKSO: Name: foo | ||
| 16 | // CHECKSO-NEXT: Value: 0x0 | ||
| 17 | // CHECKSO-NEXT: Size: 4 | ||
| 18 | // CHECKSO-NEXT: Binding: Global | ||
| 19 | // CHECKSO-NEXT: Type: Object | ||
| 20 | // CHECKSO-NEXT: Other: 0 | ||
| 21 | // CHECKSO-NEXT: Section: .text | ||
| 22 | |||
| 23 | // When foo has st_value == 0, it carries the section alignment. | ||
| 24 | // In this case, section alignment is 2^10, 0x202400 meets the requirement. | ||
| 25 | // CHECK: Name: foo | ||
| 26 | // CHECK-NEXT: Value: 0x202400 | ||
| 27 | // CHECK-NEXT: Size: 4 | ||
| 28 | // CHECK-NEXT: Binding: Global | ||
| 29 | // CHECK-NEXT: Type: Object | ||
deps/lld/test/ELF/corrupted-version-reference.s+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: llvm-mc -triple=mips64-unknown-freebsd %s -filetype=obj -o %t.o | ||
| 2 | # RUN: not ld.lld %t.o %S/Inputs/corrupt-version-reference.so -o %t.exe 2>&1 | FileCheck %s | ||
| 3 | # REQUIRES: mips | 1 | # REQUIRES: mips |
| 2 | # RUN: llvm-mc -triple=mips64-unknown-freebsd %s -filetype=obj -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o %S/Inputs/corrupt-version-reference.so -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | 4 | ||
| 5 | # CHECK: error: corrupt input file: version definition index 9 for symbol __cxa_finalize is out of bounds | 5 | # CHECK: error: corrupt input file: version definition index 9 for symbol __cxa_finalize is out of bounds |
| 6 | # CHECK: >>> defined in {{.+}}/corrupt-version-reference.so | 6 | # CHECK: >>> defined in {{.+}}/corrupt-version-reference.so |
deps/lld/test/ELF/cref.s created+33| ... | @@ -0,0 +1,33 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | |||
| 3 | // RUN: echo '.global foo; foo:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t1.o | ||
| 4 | // RUN: echo '.global foo, bar; bar:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o | ||
| 5 | // RUN: echo '.global zed; zed:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %ta.o | ||
| 6 | // RUN: rm -f %t.a | ||
| 7 | // RUN: llvm-ar rcs %t.a %ta.o | ||
| 8 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t3.o | ||
| 9 | // RUN: ld.lld -shared -o %t1.so %t1.o | ||
| 10 | // RUN: ld.lld -o /dev/null %t1.so %t2.o %t3.o %t.a -gc-sections -cref | FileCheck -strict-whitespace %s | ||
| 11 | |||
| 12 | // CHECK: Symbol File | ||
| 13 | // CHECK-NEXT: bar {{.*}}2.o | ||
| 14 | // CHECK-NEXT: {{.*}}3.o | ||
| 15 | // CHECK-NEXT: foo {{.*}}1.so | ||
| 16 | // CHECK-NEXT: {{.*}}2.o | ||
| 17 | // CHECK-NEXT: {{.*}}3.o | ||
| 18 | // CHECK-NEXT: _start {{.*}}3.o | ||
| 19 | // CHECK-NEXT: baz {{.*}}3.o | ||
| 20 | // CHECK-NEXT: zed {{.*}}.a({{.*}}a.o) | ||
| 21 | // CHECK-NEXT: {{.*}}3.o | ||
| 22 | // CHECK-NOT: discarded | ||
| 23 | |||
| 24 | .global _start, foo, bar, baz, discarded | ||
| 25 | _start: | ||
| 26 | call foo | ||
| 27 | call bar | ||
| 28 | call zed | ||
| 29 | localsym: | ||
| 30 | baz: | ||
| 31 | |||
| 32 | .section .text.a,"ax",@progbits | ||
| 33 | discarded: | ||
deps/lld/test/ELF/ctors_dtors_priority.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 3 | // RUN: %p/Inputs/ctors_dtors_priority1.s -o %t-crtbegin.o | 4 | // RUN: %p/Inputs/ctors_dtors_priority1.s -o %t-crtbegin.o |
| ... | @@ -7,7 +8,6 @@ | ... | @@ -7,7 +8,6 @@ |
| 7 | // RUN: %p/Inputs/ctors_dtors_priority3.s -o %t-crtend.o | 8 | // RUN: %p/Inputs/ctors_dtors_priority3.s -o %t-crtend.o |
| 8 | // RUN: ld.lld %t1 %t2 %t-crtend.o %t-crtbegin.o -o %t.exe | 9 | // RUN: ld.lld %t1 %t2 %t-crtend.o %t-crtbegin.o -o %t.exe |
| 9 | // RUN: llvm-objdump -s %t.exe | FileCheck %s | 10 | // RUN: llvm-objdump -s %t.exe | FileCheck %s |
| 10 | // REQUIRES: x86 | ||
| 11 | 11 | ||
| 12 | .globl _start | 12 | .globl _start |
| 13 | _start: | 13 | _start: |
deps/lld/test/ELF/defined-tls_get_addr.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj | 2 | // RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj |
| 2 | // RUN: ld.lld %t.o -o %t | 3 | // RUN: ld.lld %t.o -o /dev/null |
| 3 | 4 | ||
| 4 | // Don't error if __tls_get_addr is defined. | 5 | // Don't error if __tls_get_addr is defined. |
| 5 | 6 |
deps/lld/test/ELF/defsym-reserved-syms.s created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t %t.o --defsym=foo2=etext | ||
| 4 | # RUN: llvm-readobj -t -s %t | FileCheck %s | ||
| 5 | |||
| 6 | ## Check 'foo2' value is equal to value of 'etext'. | ||
| 7 | # CHECK: Symbol { | ||
| 8 | # CHECK: Name: foo2 | ||
| 9 | # CHECK-NEXT: Value: 0x[[VAL:.*]] | ||
| 10 | # CHECK: Symbol { | ||
| 11 | # CHECK: Name: etext | ||
| 12 | # CHECK-NEXT: Value: 0x[[VAL]] | ||
| 13 | |||
| 14 | ## Check 'foo2' value set correctly when using | ||
| 15 | ## reserved symbol 'etext' in expression. | ||
| 16 | # RUN: ld.lld -o %t %t.o --defsym=foo2=etext+2 | ||
| 17 | # RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=EXPR | ||
| 18 | # EXPR: Symbol { | ||
| 19 | # EXPR: Name: foo2 | ||
| 20 | # EXPR-NEXT: Value: 0x201007 | ||
| 21 | # EXPR: Symbol { | ||
| 22 | # EXPR: Name: etext | ||
| 23 | # EXPR-NEXT: Value: 0x201005 | ||
| 24 | |||
| 25 | .globl foo1 | ||
| 26 | foo1 = 0x123 | ||
| 27 | |||
| 28 | .global _start | ||
| 29 | _start: | ||
| 30 | movl $foo2, %edx | ||
deps/lld/test/ELF/discard-locals.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t |
| 2 | // RUN: ld.lld -discard-locals %t -o %t2 | 3 | // RUN: ld.lld -discard-locals %t -o %t2 |
| 3 | // RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | .global _start | 6 | .global _start |
| 7 | _start: | 7 | _start: |
deps/lld/test/ELF/discard-merge-locals.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 -shared | 3 | // RUN: ld.lld %t -o %t2 -shared |
| 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | 	leaq	.L.str(%rip), %rdi | 6 | 	leaq	.L.str(%rip), %rdi |
| 7 | 7 |
deps/lld/test/ELF/discard-none.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t |
| 2 | // RUN: ld.lld -discard-none -shared %t -o %t2 | 3 | // RUN: ld.lld -discard-none -shared %t -o %t2 |
| 3 | // RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | .text | 6 | .text |
| 7 | .Lmyvar: | 7 | .Lmyvar: |
deps/lld/test/ELF/dont-export-hidden.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %p/Inputs/shared.s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %p/Inputs/shared.s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux | 3 | // RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | // RUN: ld.lld %t.o -o %t.so -shared | 4 | // RUN: ld.lld %t.o -o %t.so -shared |
deps/lld/test/ELF/driver.test+20-10| ... | @@ -35,25 +35,35 @@ | ... | @@ -35,25 +35,35 @@ |
| 35 | # RUN: not ld.lld -r --gc-sections %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR3 %s | 35 | # RUN: not ld.lld -r --gc-sections %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR3 %s |
| 36 | # ERR3: -r and --gc-sections may not be used together | 36 | # ERR3: -r and --gc-sections may not be used together |
| 37 | 37 | ||
| 38 | ## Attempt to use -r and --gdb-index together | ||
| 39 | # RUN: not ld.lld -r --gdb-index %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR4 %s | ||
| 40 | # ERR4: -r and --gdb-index may not be used together | ||
| 41 | |||
| 38 | ## Attempt to use -r and --icf together | 42 | ## Attempt to use -r and --icf together |
| 39 | # RUN: not ld.lld -r --icf=all %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR4 %s | 43 | # RUN: not ld.lld -r --icf=all %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR5 %s |
| 40 | # ERR4: -r and --icf may not be used together | 44 | # ERR5: -r and --icf may not be used together |
| 41 | 45 | ||
| 42 | ## Attempt to use -r and -pie together | 46 | ## Attempt to use -r and -pie together |
| 43 | # RUN: not ld.lld -r -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR5 %s | 47 | # RUN: not ld.lld -r -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR6 %s |
| 44 | # ERR5: -r and -pie may not be used together | 48 | # ERR6: -r and -pie may not be used together |
| 45 | 49 | ||
| 46 | ## Attempt to use -shared and -pie together | 50 | ## Attempt to use -shared and -pie together |
| 47 | # RUN: not ld.lld -shared -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR6 %s | 51 | # RUN: not ld.lld -shared -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR7 %s |
| 48 | # ERR6: -shared and -pie may not be used together | 52 | # ERR7: -shared and -pie may not be used together |
| 49 | 53 | ||
| 50 | ## "--output=foo" is equivalent to "-o foo". | 54 | ## "--output=foo" is equivalent to "-o foo". |
| 51 | # RUN: not ld.lld %t --output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR7 %s | 55 | # RUN: not ld.lld %t --output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR8 %s |
| 52 | # ERR7: cannot open output file /no/such/file | 56 | # ERR8: cannot open output file /no/such/file |
| 53 | 57 | ||
| 54 | ## "-output=foo" is equivalent to "-o utput=foo". | 58 | ## "-output=foo" is equivalent to "-o utput=foo". |
| 55 | # RUN: not ld.lld %t -output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR8 %s | 59 | # RUN: not ld.lld %t -output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR9 %s |
| 56 | # ERR8: cannot open output file utput=/no/such/file | 60 | # ERR9: cannot open output file utput=/no/such/file |
| 61 | |||
| 62 | # RUN: not ld.lld %t -z foo 2>&1 | FileCheck -check-prefix=ERR10 %s | ||
| 63 | # ERR10: unknown -z value: foo | ||
| 64 | |||
| 65 | # RUN: not ld.lld %t -z max-page-size 2>&1 | FileCheck -check-prefix=ERR11 %s | ||
| 66 | # ERR11: unknown -z value: max-page-size | ||
| 57 | 67 | ||
| 58 | .globl _start | 68 | .globl _start |
| 59 | _start: | 69 | _start: |
deps/lld/test/ELF/dt_flags.s+10-5| ... | @@ -2,19 +2,24 @@ | ... | @@ -2,19 +2,24 @@ |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld -shared %t -o %t.so | 4 | # RUN: ld.lld -shared %t -o %t.so |
| 5 | # RUN: ld.lld -z now -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1 | 5 | |
| 6 | # RUN: ld.lld %t %t.so -o %t2 | 6 | # RUN: ld.lld -z initfirst -z now -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1 |
| 7 | # RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s | 7 | # RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s |
| 8 | |||
| 9 | # RUN: ld.lld %t %t.so -o %t2 | ||
| 10 | # RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s | ||
| 11 | |||
| 12 | # RUN: ld.lld -z lazy %t %t.so -o %t2 | ||
| 8 | # RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s | 13 | # RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s |
| 9 | 14 | ||
| 10 | # FLAGS: DynamicSection [ | 15 | # FLAGS: DynamicSection [ |
| 11 | # FLAGS: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW | 16 | # FLAGS: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW |
| 12 | # FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW NODELETE NOOPEN ORIGIN | 17 | # FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW NODELETE INITFIRST NOOPEN ORIGIN |
| 13 | # FLAGS: ] | 18 | # FLAGS: ] |
| 14 | 19 | ||
| 15 | # CHECK: DynamicSection [ | 20 | # CHECK: DynamicSection [ |
| 16 | # CHECK-NOT: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW | 21 | # CHECK-NOT: FLAGS |
| 17 | # CHECK-NOT: 0x000000006FFFFFFB FLAGS_1 NOW NODELETE NOOPEN ORIGIN | 22 | # CHECK-NOT: FLAGS_1 |
| 18 | # CHECK: ] | 23 | # CHECK: ] |
| 19 | 24 | ||
| 20 | .globl _start | 25 | .globl _start |
deps/lld/test/ELF/duplicated-synthetic-sym.s+14-8| ... | @@ -1,11 +1,17 @@ | ... | @@ -1,11 +1,17 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: cd %S | 3 | // RUN: rm -rf %t.dir |
| 3 | // RUN: not ld.lld %t.o --format=binary duplicated-synthetic-sym.s -o %t.elf 2>&1 | FileCheck %s | 4 | // RUN: mkdir %t.dir |
| 4 | // RUN: not ld.lld %t.o --format binary duplicated-synthetic-sym.s -o %t.elf 2>&1 | FileCheck %s | 5 | // RUN: cd %t.dir |
| 6 | // RUN: echo > file.bin | ||
| 5 | 7 | ||
| 6 | // CHECK: duplicate symbol: _binary_duplicated_synthetic_sym_s_start | 8 | // RUN: not ld.lld %t.o --format=binary file.bin -o %t.elf 2>&1 | FileCheck %s |
| 7 | // CHECK: defined at <internal>:(.data+0x0) | 9 | // RUN: not ld.lld %t.o --format binary file.bin -o %t.elf 2>&1 | FileCheck %s |
| 8 | 10 | ||
| 9 | .globl _binary_duplicated_synthetic_sym_s_start | 11 | // CHECK: duplicate symbol: _binary_file_bin_start |
| 10 | _binary_duplicated_synthetic_sym_s_start: | 12 | // CHECK-NEXT: defined at {{.*}}.o:(.text+0x0) |
| 11 | .long 0 | 13 | // CHECK-NEXT: defined at file.bin:(.data+0x0) |
| 14 | |||
| 15 | .globl _binary_file_bin_start | ||
| 16 | _binary_file_bin_start: | ||
| 17 | .long 0 |
deps/lld/test/ELF/dynamic-got-rela.s+39-18| ... | @@ -1,24 +1,45 @@ | ... | @@ -1,24 +1,45 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o -o %t.so -shared | 3 | // RUN: ld.lld %t.o -o %t.so -shared --apply-dynamic-relocs |
| 4 | // RUN: llvm-readobj -r -s -l -section-data %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -r -s -l -section-data %t.so | FileCheck -check-prefix CHECK -check-prefix APPLYDYNREL %s |
| 5 | // 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 | ||
| 7 | // 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 | ||
| 5 | 9 | ||
| 6 | // CHECK: Name: .got | 10 | // APPLYDYNREL: Name: .got |
| 7 | // CHECK-NEXT: Type: SHT_PROGBITS | 11 | // APPLYDYNREL-NEXT: Type: SHT_PROGBITS |
| 8 | // CHECK-NEXT: Flags [ | 12 | // APPLYDYNREL-NEXT: Flags [ |
| 9 | // CHECK-NEXT: SHF_ALLOC | 13 | // APPLYDYNREL-NEXT: SHF_ALLOC |
| 10 | // CHECK-NEXT: SHF_WRITE | 14 | // APPLYDYNREL-NEXT: SHF_WRITE |
| 11 | // CHECK-NEXT: ] | 15 | // APPLYDYNREL-NEXT: ] |
| 12 | // CHECK-NEXT: Address: 0x[[GOT:.*]] | 16 | // APPLYDYNREL-NEXT: Address: 0x[[GOT:.*]] |
| 13 | // CHECK-NEXT: Offset: | 17 | // APPLYDYNREL-NEXT: Offset: |
| 14 | // CHECK-NEXT: Size: | 18 | // APPLYDYNREL-NEXT: Size: |
| 15 | // CHECK-NEXT: Link: | 19 | // APPLYDYNREL-NEXT: Link: |
| 16 | // CHECK-NEXT: Info: | 20 | // APPLYDYNREL-NEXT: Info: |
| 17 | // CHECK-NEXT: AddressAlignment: | 21 | // APPLYDYNREL-NEXT: AddressAlignment: |
| 18 | // CHECK-NEXT: EntrySize: | 22 | // APPLYDYNREL-NEXT: EntrySize: |
| 19 | // CHECK-NEXT: SectionData ( | 23 | // APPLYDYNREL-NEXT: SectionData ( |
| 20 | // CHECK-NEXT: 0000: 00000000 00000000 | | 24 | // APPLYDYNREL-NEXT: 0000: 00200000 00000000 | |
| 21 | // CHECK-NEXT: ) | 25 | // APPLYDYNREL-NEXT: ) |
| 26 | |||
| 27 | // NOAPPLYDYNREL: Name: .got | ||
| 28 | // NOAPPLYDYNREL-NEXT: Type: SHT_PROGBITS | ||
| 29 | // NOAPPLYDYNREL-NEXT: Flags [ | ||
| 30 | // NOAPPLYDYNREL-NEXT: SHF_ALLOC | ||
| 31 | // NOAPPLYDYNREL-NEXT: SHF_WRITE | ||
| 32 | // NOAPPLYDYNREL-NEXT: ] | ||
| 33 | // NOAPPLYDYNREL-NEXT: Address: 0x[[GOT:.*]] | ||
| 34 | // NOAPPLYDYNREL-NEXT: Offset: | ||
| 35 | // NOAPPLYDYNREL-NEXT: Size: | ||
| 36 | // NOAPPLYDYNREL-NEXT: Link: | ||
| 37 | // NOAPPLYDYNREL-NEXT: Info: | ||
| 38 | // NOAPPLYDYNREL-NEXT: AddressAlignment: | ||
| 39 | // NOAPPLYDYNREL-NEXT: EntrySize: | ||
| 40 | // NOAPPLYDYNREL-NEXT: SectionData ( | ||
| 41 | // NOAPPLYDYNREL-NEXT: 0000: 00000000 00000000 | | ||
| 42 | // NOAPPLYDYNREL-NEXT: ) | ||
| 22 | 43 | ||
| 23 | // CHECK: Relocations [ | 44 | // CHECK: Relocations [ |
| 24 | // CHECK-NEXT: Section ({{.*}}) .rela.dyn { | 45 | // CHECK-NEXT: Section ({{.*}}) .rela.dyn { |
deps/lld/test/ELF/dynamic-got.s+22-5| ... | @@ -3,6 +3,23 @@ | ... | @@ -3,6 +3,23 @@ |
| 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared | 3 | // 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 | 4 | // RUN: llvm-readobj -s -l -section-data -r %t.so | FileCheck %s |
| 5 | 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: ) | ||
| 22 | |||
| 6 | // CHECK: Name: .got | 23 | // CHECK: Name: .got |
| 7 | // CHECK-NEXT: Type: SHT_PROGBITS | 24 | // CHECK-NEXT: Type: SHT_PROGBITS |
| 8 | // CHECK-NEXT: Flags [ | 25 | // CHECK-NEXT: Flags [ |
| ... | @@ -17,19 +34,19 @@ | ... | @@ -17,19 +34,19 @@ |
| 17 | // CHECK-NEXT: AddressAlignment: | 34 | // CHECK-NEXT: AddressAlignment: |
| 18 | // CHECK-NEXT: EntrySize: | 35 | // CHECK-NEXT: EntrySize: |
| 19 | // CHECK-NEXT: SectionData ( | 36 | // CHECK-NEXT: SectionData ( |
| 20 | // CHECK-NEXT: 0000: 00200000 | | 37 | // CHECK-NEXT: 0000: 00300000 |
| 21 | // CHECK-NEXT: ) | 38 | // CHECK-NEXT: ) |
| 22 | 39 | ||
| 23 | // CHECK: Relocations [ | 40 | // CHECK: Relocations [ |
| 24 | // CHECK-NEXT: Section ({{.*}}) .rel.dyn { | 41 | // CHECK-NEXT: Section ({{.*}}) .rel.dyn { |
| 25 | // CHECK-NEXT: 0x2050 R_386_RELATIVE - 0x0 | 42 | // CHECK-NEXT: 0x3050 R_386_RELATIVE - 0x0 |
| 26 | // CHECK-NEXT: } | 43 | // CHECK-NEXT: } |
| 27 | // CHECK-NEXT: ] | 44 | // CHECK-NEXT: ] |
| 28 | 45 | ||
| 29 | // CHECK: Type: PT_DYNAMIC | 46 | // CHECK: Type: PT_DYNAMIC |
| 30 | // CHECK-NEXT: Offset: 0x2000 | 47 | // CHECK-NEXT: Offset: 0x3000 |
| 31 | // CHECK-NEXT: VirtualAddress: 0x2000 | 48 | // CHECK-NEXT: VirtualAddress: 0x3000 |
| 32 | // CHECK-NEXT: PhysicalAddress: 0x2000 | 49 | // CHECK-NEXT: PhysicalAddress: 0x3000 |
| 33 | 50 | ||
| 34 | calll .L0$pb | 51 | calll .L0$pb |
| 35 | .L0$pb: | 52 | .L0$pb: |
deps/lld/test/ELF/dynamic-linker.s created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t1.o | ||
| 3 | # RUN: ld.lld -shared %t1.o -o %t.so | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 5 | |||
| 6 | # RUN: ld.lld --dynamic-linker foo %t.o %t.so -o %t | ||
| 7 | # RUN: llvm-readelf -program-headers %t | FileCheck %s | ||
| 8 | |||
| 9 | # RUN: ld.lld --dynamic-linker=foo %t.o %t.so -o %t | ||
| 10 | # RUN: llvm-readelf -program-headers %t | FileCheck %s | ||
| 11 | |||
| 12 | # CHECK: [Requesting program interpreter: foo] | ||
| 13 | |||
| 14 | # RUN: ld.lld %t.o %t.so -o %t | ||
| 15 | # RUN: llvm-readelf -program-headers %t | FileCheck --check-prefix=NO %s | ||
| 16 | |||
| 17 | # RUN: ld.lld --dynamic-linker foo --no-dynamic-linker %t.o %t.so -o %t | ||
| 18 | # RUN: llvm-readelf -program-headers %t | FileCheck --check-prefix=NO %s | ||
| 19 | |||
| 20 | # NO-NOT: PT_INTERP | ||
| 21 | |||
| 22 | .globl _start | ||
| 23 | _start: | ||
| 24 | nop | ||
deps/lld/test/ELF/dynamic-list-archive.s created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: rm -f %t.a | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive2.s -o %t1.o | ||
| 5 | # RUN: llvm-ar rcs %t.a %t1.o | ||
| 6 | |||
| 7 | # RUN: echo "{ foo; };" > %t.list | ||
| 8 | |||
| 9 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o | ||
| 10 | # RUN: ld.lld -shared -o %t.so --dynamic-list %t.list %t.a %t2.o | ||
| 11 | |||
| 12 | # RUN: llvm-readelf -dyn-symbols %t.so | FileCheck %s | ||
| 13 | # CHECK-NOT: foo | ||
| 14 | |||
| 15 | .global _start | ||
| 16 | _start: | ||
| 17 | nop | ||
deps/lld/test/ELF/dynamic-list-extern.s+4-8| ... | @@ -4,12 +4,8 @@ | ... | @@ -4,12 +4,8 @@ |
| 4 | 4 | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 6 | 6 | ||
| 7 | # RUN: echo '{ \ | 7 | # RUN: echo '{ extern "C" { foo; }; extern "C++" { bar; }; };' > %t.list |
| 8 | # RUN: extern "C" { \ | 8 | # RUN: ld.lld --dynamic-list %t.list %t.o -shared -o %t.so |
| 9 | # RUN: foo; \ | 9 | |
| 10 | # RUN: }; \ | 10 | # RUN: echo '{ extern "C" { foo }; extern "C++" { bar }; };' > %t.list |
| 11 | # RUN: extern "C++" { \ | ||
| 12 | # RUN: bar; \ | ||
| 13 | # RUN: }; \ | ||
| 14 | # RUN: };' > %t.list | ||
| 15 | # RUN: ld.lld --dynamic-list %t.list %t.o -shared -o %t.so | 11 | # RUN: ld.lld --dynamic-list %t.list %t.o -shared -o %t.so |
deps/lld/test/ELF/dynamic-no-rosegment.s+2-2| ... | @@ -7,9 +7,9 @@ | ... | @@ -7,9 +7,9 @@ |
| 7 | # CHECK-NEXT: Tag Type Name/Value | 7 | # CHECK-NEXT: Tag Type Name/Value |
| 8 | # CHECK-NEXT: 0x0000000000000006 SYMTAB 0x120 | 8 | # CHECK-NEXT: 0x0000000000000006 SYMTAB 0x120 |
| 9 | # CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes) | 9 | # CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes) |
| 10 | # CHECK-NEXT: 0x0000000000000005 STRTAB 0x1D0 | 10 | # CHECK-NEXT: 0x0000000000000005 STRTAB 0x1D8 |
| 11 | # CHECK-NEXT: 0x000000000000000A STRSZ 1 (bytes) | 11 | # CHECK-NEXT: 0x000000000000000A STRSZ 1 (bytes) |
| 12 | # CHECK-NEXT: 0x000000006FFFFEF5 GNU_HASH 0x138 | 12 | # CHECK-NEXT: 0x000000006FFFFEF5 GNU_HASH 0x138 |
| 13 | # CHECK-NEXT: 0x0000000000000004 HASH 0x150 | 13 | # CHECK-NEXT: 0x0000000000000004 HASH 0x154 |
| 14 | # CHECK-NEXT: 0x0000000000000000 NULL 0x0 | 14 | # CHECK-NEXT: 0x0000000000000000 NULL 0x0 |
| 15 | # CHECK-NEXT: ] | 15 | # CHECK-NEXT: ] |
deps/lld/test/ELF/dynamic-reloc-in-ro.s+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | // CHECK: can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment; recompile object files with -fPIC | 5 | // CHECK: 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 | 6 | // CHECK-NEXT: >>> defined in {{.*}}.o |
| 7 | // CHECK-NEXT: >>> referenced by {{.*}}.o:(.text+0x0) | 7 | // CHECK-NEXT: >>> referenced by {{.*}}.o:(.text+0x0) |
| 8 | 8 |
deps/lld/test/ELF/dynamic-reloc-index.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
deps/lld/test/ELF/dynamic-reloc-weak.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc-weak.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc-weak.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld %t.o %t2.so -o %t | 5 | // RUN: ld.lld %t.o %t2.so -o %t |
| 5 | // RUN: llvm-readobj -r %t | FileCheck %s | 6 | // RUN: llvm-readobj -r %t | FileCheck %s |
| 6 | // REQUIRES: x86 | ||
| 7 | 7 | ||
| 8 | .globl _start | 8 | .globl _start |
| 9 | _start: | 9 | _start: |
deps/lld/test/ELF/dynamic-reloc.s+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc.s -o %t3.o | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc.s -o %t3.o |
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | 5 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 5 | // RUN: ld.lld --hash-style=sysv %t.o %t3.o %t2.so -o %t | 6 | // RUN: ld.lld --hash-style=sysv %t.o %t3.o %t2.so -o %t |
| 6 | // 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 |
| 7 | // REQUIRES: x86 | ||
| 8 | 8 | ||
| 9 | // CHECK: Index: 1 | 9 | // CHECK: Index: 1 |
| 10 | // CHECK-NEXT: Name: .dynsym | 10 | // CHECK-NEXT: Name: .dynsym |
deps/lld/test/ELF/dynstr-no-rosegment.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # Verify that a .dynstr in the .text segment has null byte terminators | 2 | # Verify that a .dynstr in the .text segment has null byte terminators |
| 2 | 3 | ||
| 3 | # REQUIRES: x86 | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 5 | # RUN: ld.lld %t.o -no-rosegment -o %t.so -shared | 5 | # RUN: ld.lld %t.o -no-rosegment -o %t.so -shared |
| 6 | # RUN: llvm-objdump %t.so -s -j .dynstr | FileCheck %s | 6 | # RUN: llvm-objdump %t.so -s -j .dynstr | FileCheck %s |
deps/lld/test/ELF/edata-etext.s+6-2| ... | @@ -10,10 +10,11 @@ | ... | @@ -10,10 +10,11 @@ |
| 10 | ## greater than the address of _etext, the address of _end is same as the address | 10 | ## greater than the address of _etext, the address of _end is same as the address |
| 11 | ## of _edata." (https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html). | 11 | ## of _edata." (https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html). |
| 12 | ## 3) Address of _end is different from _edata because of 2. | 12 | ## 3) Address of _end is different from _edata because of 2. |
| 13 | ## 4) Addresses of _edata == edata, _end == end and _etext == etext. | ||
| 13 | # CHECK: Sections: | 14 | # CHECK: Sections: |
| 14 | # CHECK-NEXT: Idx Name Size Address Type | 15 | # CHECK-NEXT: Idx Name Size Address Type |
| 15 | # CHECK-NEXT: 0 00000000 0000000000000000 | 16 | # CHECK-NEXT: 0 00000000 0000000000000000 |
| 16 | # CHECK-NEXT: 1 .text 00000001 0000000000201000 TEXT DATA | 17 | # CHECK-NEXT: 1 .text 00000001 0000000000201000 TEXT |
| 17 | # CHECK-NEXT: 2 .data 00000002 0000000000202000 DATA | 18 | # CHECK-NEXT: 2 .data 00000002 0000000000202000 DATA |
| 18 | # CHECK-NEXT: 3 .bss 00000006 0000000000202004 BSS | 19 | # CHECK-NEXT: 3 .bss 00000006 0000000000202004 BSS |
| 19 | # CHECK: SYMBOL TABLE: | 20 | # CHECK: SYMBOL TABLE: |
| ... | @@ -22,6 +23,9 @@ | ... | @@ -22,6 +23,9 @@ |
| 22 | # CHECK-NEXT: 000000000020200a .bss 00000000 _end | 23 | # CHECK-NEXT: 000000000020200a .bss 00000000 _end |
| 23 | # CHECK-NEXT: 0000000000201001 .text 00000000 _etext | 24 | # CHECK-NEXT: 0000000000201001 .text 00000000 _etext |
| 24 | # CHECK-NEXT: 0000000000201000 .text 00000000 _start | 25 | # CHECK-NEXT: 0000000000201000 .text 00000000 _start |
| 26 | # CHECK-NEXT: 0000000000202002 .data 00000000 edata | ||
| 27 | # CHECK-NEXT: 000000000020200a .bss 00000000 end | ||
| 28 | # CHECK-NEXT: 0000000000201001 .text 00000000 etext | ||
| 25 | 29 | ||
| 26 | # RUN: ld.lld -r %t.o -o %t2 | 30 | # RUN: ld.lld -r %t.o -o %t2 |
| 27 | # RUN: llvm-objdump -t %t2 | FileCheck %s --check-prefix=RELOCATABLE | 31 | # RUN: llvm-objdump -t %t2 | FileCheck %s --check-prefix=RELOCATABLE |
| ... | @@ -29,7 +33,7 @@ | ... | @@ -29,7 +33,7 @@ |
| 29 | # RELOCATABLE-NEXT: 0000000000000000 *UND* 00000000 _end | 33 | # RELOCATABLE-NEXT: 0000000000000000 *UND* 00000000 _end |
| 30 | # RELOCATABLE-NEXT: 0000000000000000 *UND* 00000000 _etext | 34 | # RELOCATABLE-NEXT: 0000000000000000 *UND* 00000000 _etext |
| 31 | 35 | ||
| 32 | .global _start,_end,_etext,_edata | 36 | .global _start,_end,_etext,_edata,end,etext,edata |
| 33 | .text | 37 | .text |
| 34 | _start: | 38 | _start: |
| 35 | nop | 39 | nop |
deps/lld/test/ELF/eh-frame-dyn-rel.s+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: not ld.lld %t.o %t.o -o %t -shared 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o %t.o -o /dev/null -shared 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | // CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo | 5 | // CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 6 | // CHECK: >>> defined in {{.*}}.o | 6 | // CHECK: >>> defined in {{.*}}.o |
| 7 | // CHECK: >>> referenced by {{.*}}.o:(.eh_frame+0x12) | 7 | // CHECK: >>> referenced by {{.*}}.o:(.eh_frame+0x12) |
| 8 | 8 |
deps/lld/test/ELF/eh-frame-hdr-abs-fde.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check reading PC values of FDEs and writing lookup table in the .eh_frame_hdr | 2 | # Check reading PC values of FDEs and writing lookup table in the .eh_frame_hdr |
| 2 | # if CIE augmentation string has 'L' token and PC values are encoded using | 3 | # if CIE augmentation string has 'L' token and PC values are encoded using |
| 3 | # absolute (not relative) format. | 4 | # absolute (not relative) format. |
| ... | @@ -6,8 +7,6 @@ | ... | @@ -6,8 +7,6 @@ |
| 6 | # RUN: ld.lld --eh-frame-hdr %t.o -o %t | 7 | # RUN: ld.lld --eh-frame-hdr %t.o -o %t |
| 7 | # RUN: llvm-objdump -s -dwarf=frames %t | FileCheck %s | 8 | # RUN: llvm-objdump -s -dwarf=frames %t | FileCheck %s |
| 8 | 9 | ||
| 9 | # REQUIRES: mips | ||
| 10 | |||
| 11 | # CHECK: Contents of section .eh_frame_hdr: | 10 | # CHECK: Contents of section .eh_frame_hdr: |
| 12 | # CHECK-NEXT: 10128 011b033b 00000010 00000001 0000fed8 | 11 | # CHECK-NEXT: 10128 011b033b 00000010 00000001 0000fed8 |
| 13 | # ^-- 0x20000 - 0x10138 | 12 | # ^-- 0x20000 - 0x10138 |
deps/lld/test/ELF/eh-frame-hdr-augmentation.s+2| ... | @@ -11,6 +11,7 @@ | ... | @@ -11,6 +11,7 @@ |
| 11 | // CHECK-NEXT: Code alignment factor: 1 | 11 | // CHECK-NEXT: Code alignment factor: 1 |
| 12 | // CHECK-NEXT: Data alignment factor: -8 | 12 | // CHECK-NEXT: Data alignment factor: -8 |
| 13 | // CHECK-NEXT: Return address column: 16 | 13 | // CHECK-NEXT: Return address column: 16 |
| 14 | // CHECK-NEXT: Personality Address: 00000dad | ||
| 14 | // CHECK-NEXT: Augmentation data: | 15 | // CHECK-NEXT: Augmentation data: |
| 15 | 16 | ||
| 16 | // CHECK: DW_CFA_def_cfa: reg7 +8 | 17 | // CHECK: DW_CFA_def_cfa: reg7 +8 |
| ... | @@ -19,6 +20,7 @@ | ... | @@ -19,6 +20,7 @@ |
| 19 | // CHECK-NEXT: DW_CFA_nop: | 20 | // CHECK-NEXT: DW_CFA_nop: |
| 20 | 21 | ||
| 21 | // CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000d98...00000d98 | 22 | // CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000d98...00000d98 |
| 23 | // CHECK-NEXT: LSDA Address: 00000d8f | ||
| 22 | // CHECK-NEXT: DW_CFA_nop: | 24 | // CHECK-NEXT: DW_CFA_nop: |
| 23 | // CHECK-NEXT: DW_CFA_nop: | 25 | // CHECK-NEXT: DW_CFA_nop: |
| 24 | // CHECK-NEXT: DW_CFA_nop: | 26 | // CHECK-NEXT: DW_CFA_nop: |
deps/lld/test/ELF/eh-frame-hdr-icf-fde.s+2-2| ... | @@ -52,7 +52,7 @@ | ... | @@ -52,7 +52,7 @@ |
| 52 | # CHECK-NEXT: ] | 52 | # CHECK-NEXT: ] |
| 53 | # CHECK-NEXT: Address: 0x200178 | 53 | # CHECK-NEXT: Address: 0x200178 |
| 54 | # CHECK-NEXT: Offset: 0x178 | 54 | # CHECK-NEXT: Offset: 0x178 |
| 55 | # CHECK-NEXT: Size: 72 | 55 | # CHECK-NEXT: Size: 76 |
| 56 | # CHECK-NEXT: Link: 0 | 56 | # CHECK-NEXT: Link: 0 |
| 57 | # CHECK-NEXT: Info: 0 | 57 | # CHECK-NEXT: Info: 0 |
| 58 | # CHECK-NEXT: AddressAlignment: 8 | 58 | # CHECK-NEXT: AddressAlignment: 8 |
| ... | @@ -62,7 +62,7 @@ | ... | @@ -62,7 +62,7 @@ |
| 62 | # CHECK-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 | 62 | # CHECK-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 |
| 63 | # CHECK-NEXT: 0020: 680E0000 01000000 00000000 00000000 | 63 | # CHECK-NEXT: 0020: 680E0000 01000000 00000000 00000000 |
| 64 | # CHECK-NEXT: 0030: 14000000 34000000 520E0000 01000000 | 64 | # CHECK-NEXT: 0030: 14000000 34000000 520E0000 01000000 |
| 65 | # CHECK-NEXT: 0040: 00000000 00000000 | 65 | # CHECK-NEXT: 0040: 00000000 00000000 00000000 |
| 66 | # CHECK-NEXT: ) | 66 | # CHECK-NEXT: ) |
| 67 | # CHECK-NEXT: } | 67 | # CHECK-NEXT: } |
| 68 | 68 |
deps/lld/test/ELF/eh-frame-hdr.s+4-3| ... | @@ -60,7 +60,7 @@ _start: | ... | @@ -60,7 +60,7 @@ _start: |
| 60 | // HDR-NEXT: Size: 36 | 60 | // HDR-NEXT: Size: 36 |
| 61 | // HDR-NEXT: Link: 0 | 61 | // HDR-NEXT: Link: 0 |
| 62 | // HDR-NEXT: Info: 0 | 62 | // HDR-NEXT: Info: 0 |
| 63 | // HDR-NEXT: AddressAlignment: 1 | 63 | // HDR-NEXT: AddressAlignment: 4 |
| 64 | // HDR-NEXT: EntrySize: 0 | 64 | // HDR-NEXT: EntrySize: 0 |
| 65 | // HDR-NEXT: SectionData ( | 65 | // HDR-NEXT: SectionData ( |
| 66 | // HDR-NEXT: 0000: 011B033B 24000000 03000000 A80E0000 | 66 | // HDR-NEXT: 0000: 011B033B 24000000 03000000 A80E0000 |
| ... | @@ -92,7 +92,7 @@ _start: | ... | @@ -92,7 +92,7 @@ _start: |
| 92 | // HDR-NEXT: ] | 92 | // HDR-NEXT: ] |
| 93 | // HDR-NEXT: Address: 0x200180 | 93 | // HDR-NEXT: Address: 0x200180 |
| 94 | // HDR-NEXT: Offset: 0x180 | 94 | // HDR-NEXT: Offset: 0x180 |
| 95 | // HDR-NEXT: Size: 96 | 95 | // HDR-NEXT: Size: 100 |
| 96 | // HDR-NEXT: Link: 0 | 96 | // HDR-NEXT: Link: 0 |
| 97 | // HDR-NEXT: Info: 0 | 97 | // HDR-NEXT: Info: 0 |
| 98 | // HDR-NEXT: AddressAlignment: 8 | 98 | // HDR-NEXT: AddressAlignment: 8 |
| ... | @@ -104,6 +104,7 @@ _start: | ... | @@ -104,6 +104,7 @@ _start: |
| 104 | // HDR-NEXT: 0030: 14000000 34000000 490E0000 01000000 | 104 | // HDR-NEXT: 0030: 14000000 34000000 490E0000 01000000 |
| 105 | // HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000 | 105 | // HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000 |
| 106 | // HDR-NEXT: 0050: 320E0000 01000000 00000000 00000000 | 106 | // HDR-NEXT: 0050: 320E0000 01000000 00000000 00000000 |
| 107 | // HDR-NEXT: 0060: 00000000 | ||
| 107 | // HDR-NEXT: ) | 108 | // HDR-NEXT: ) |
| 108 | // CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000 | 109 | // CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000 |
| 109 | // FDE(1): 14000000 1C000000 600E0000 01000000 00000000 00000000 | 110 | // FDE(1): 14000000 1C000000 600E0000 01000000 00000000 00000000 |
| ... | @@ -130,5 +131,5 @@ _start: | ... | @@ -130,5 +131,5 @@ _start: |
| 130 | // HDR-NEXT: Flags [ | 131 | // HDR-NEXT: Flags [ |
| 131 | // HDR-NEXT: PF_R | 132 | // HDR-NEXT: PF_R |
| 132 | // HDR-NEXT: ] | 133 | // HDR-NEXT: ] |
| 133 | // HDR-NEXT: Alignment: 1 | 134 | // HDR-NEXT: Alignment: 4 |
| 134 | // HDR-NEXT: } | 135 | // HDR-NEXT: } |
deps/lld/test/ELF/eh-frame-marker.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared | 3 | // RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared |
| 3 | // RUN: llvm-readobj -t -s %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -t -s %t.so | FileCheck %s |
deps/lld/test/ELF/eh-frame-merge.s+2-1| ... | @@ -27,7 +27,7 @@ | ... | @@ -27,7 +27,7 @@ |
| 27 | // CHECK-NEXT: ] | 27 | // CHECK-NEXT: ] |
| 28 | // CHECK-NEXT: Address: | 28 | // CHECK-NEXT: Address: |
| 29 | // CHECK-NEXT: Offset: | 29 | // CHECK-NEXT: Offset: |
| 30 | // CHECK-NEXT: Size: 96 | 30 | // CHECK-NEXT: Size: 100 |
| 31 | // CHECK-NEXT: Link: 0 | 31 | // CHECK-NEXT: Link: 0 |
| 32 | // CHECK-NEXT: Info: 0 | 32 | // CHECK-NEXT: Info: 0 |
| 33 | // CHECK-NEXT: AddressAlignment: 8 | 33 | // CHECK-NEXT: AddressAlignment: 8 |
| ... | @@ -39,6 +39,7 @@ | ... | @@ -39,6 +39,7 @@ |
| 39 | // CHECK-NEXT: 0030: 14000000 34000000 D20D0000 02000000 | | 39 | // CHECK-NEXT: 0030: 14000000 34000000 D20D0000 02000000 | |
| 40 | // CHECK-NEXT: 0040: 00000000 00000000 14000000 4C000000 | | 40 | // CHECK-NEXT: 0040: 00000000 00000000 14000000 4C000000 | |
| 41 | // CHECK-NEXT: 0050: B90D0000 01000000 00000000 00000000 | | 41 | // CHECK-NEXT: 0050: B90D0000 01000000 00000000 00000000 | |
| 42 | // CHECK-NEXT: 0060: 00000000 | ||
| 42 | // CHECK-NEXT: ) | 43 | // CHECK-NEXT: ) |
| 43 | 44 | ||
| 44 | // CHECK: Name: foo | 45 | // CHECK: Name: foo |
deps/lld/test/ELF/eh-frame-multilpe-cie.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared | 3 | // RUN: ld.lld --eh-frame-hdr %t.o -o /dev/null -shared |
| 3 | // We would fail to parse multiple cies in the same file. | 4 | // We would fail to parse multiple cies in the same file. |
| 4 | 5 | ||
| 5 | .cfi_startproc | 6 | .cfi_startproc |
deps/lld/test/ELF/eh-frame-negative-pcrel-sdata2.s created+85| ... | @@ -0,0 +1,85 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # Test handling of FDE pc negative relative addressing with DW_EH_PE_sdata2. | ||
| 4 | # This situation can arise when .eh_frame is placed after .text. | ||
| 5 | |||
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 7 | # RUN: echo "SECTIONS { .text : { *(.text) } .eh_frame : { *(.eh_frame) } }" > %t.script | ||
| 8 | # 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 | ||
| 10 | |||
| 11 | # CHECK: Section { | ||
| 12 | # CHECK: Index: | ||
| 13 | # CHECK: Name: .eh_frame | ||
| 14 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 15 | # CHECK-NEXT: Flags [ | ||
| 16 | # CHECK-NEXT: SHF_ALLOC | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | # CHECK-NEXT: Address: 0x1001 | ||
| 19 | # CHECK-NEXT: Offset: 0x1001 | ||
| 20 | # CHECK-NEXT: Size: | ||
| 21 | # CHECK-NEXT: Link: | ||
| 22 | # CHECK-NEXT: Info: | ||
| 23 | # CHECK-NEXT: AddressAlignment: | ||
| 24 | # CHECK-NEXT: EntrySize: | ||
| 25 | # CHECK-NEXT: SectionData ( | ||
| 26 | # CHECK-NEXT: 0000: 14000000 00000000 017A5200 01010101 | ||
| 27 | # CHECK-NEXT: 0010: 1A000000 00000000 0C000000 1C000000 | ||
| 28 | # CHECK-NEXT: 0020: DFFFFFFF | ||
| 29 | # ^ | ||
| 30 | # DFFFFFFF = _start(0x1000) - PC(.eh_frame(0x1001) + 0x20) | ||
| 31 | |||
| 32 | # CHECK: Section { | ||
| 33 | # CHECK: Index: | ||
| 34 | # CHECK: Name: .eh_frame_hdr | ||
| 35 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 36 | # CHECK-NEXT: Flags [ | ||
| 37 | # CHECK-NEXT: SHF_ALLOC | ||
| 38 | # CHECK-NEXT: ] | ||
| 39 | # CHECK-NEXT: Address: 0x1030 | ||
| 40 | # CHECK-NEXT: Offset: 0x1030 | ||
| 41 | # CHECK-NEXT: Size: 20 | ||
| 42 | # CHECK-NEXT: Link: 0 | ||
| 43 | # CHECK-NEXT: Info: 0 | ||
| 44 | # CHECK-NEXT: AddressAlignment: 4 | ||
| 45 | # CHECK-NEXT: EntrySize: 0 | ||
| 46 | # CHECK-NEXT: SectionData ( | ||
| 47 | # CHECK-NEXT: 0000: 011B033B CDFFFFFF 01000000 D0FFFFFF | ||
| 48 | # CHECK-NEXT: 0010: E9FFFFFF | ||
| 49 | # Header (always 4 bytes): 011B033B | ||
| 50 | # CDFFFFFF = .eh_frame(0x1001) - .eh_frame_hdr(0x1030) - 4 | ||
| 51 | # 01000000 = 1 = the number of FDE pointers in the table. | ||
| 52 | # D0FFFFFF = _start(0x1000) - .eh_frame_hdr(0x1030) | ||
| 53 | # E9FFFFFF = FDE(.eh_frame(0x1001) + 0x18) - .eh_frame_hdr(0x1030) | ||
| 54 | |||
| 55 | .text | ||
| 56 | .global _start | ||
| 57 | _start: | ||
| 58 | nop | ||
| 59 | |||
| 60 | .section .eh_frame, "a" | ||
| 61 | .long 16 # Size | ||
| 62 | .long 0x00 # ID | ||
| 63 | .byte 0x01 # Version. | ||
| 64 | |||
| 65 | .byte 0x7A # Augmentation string: "zR" | ||
| 66 | .byte 0x52 | ||
| 67 | .byte 0x00 | ||
| 68 | |||
| 69 | .byte 0x01 | ||
| 70 | |||
| 71 | .byte 0x01 # LEB128 | ||
| 72 | .byte 0x01 # LEB128 | ||
| 73 | |||
| 74 | .byte 0x01 # LEB128 | ||
| 75 | .byte 0x1A # DW_EH_PE_pcrel | DW_EH_PE_sdata2 | ||
| 76 | |||
| 77 | .byte 0x00 | ||
| 78 | .byte 0x00 | ||
| 79 | .byte 0x00 | ||
| 80 | |||
| 81 | .long 10 # Size | ||
| 82 | .long 24 # ID | ||
| 83 | fde: | ||
| 84 | .long _start - fde | ||
| 85 | .word 0 | ||
deps/lld/test/ELF/eh-frame-negative-pcrel-sdata4.s created+85| ... | @@ -0,0 +1,85 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # Test handling of FDE pc negative relative addressing with DW_EH_PE_sdata4. | ||
| 4 | # This situation can arise when .eh_frame is placed after .text. | ||
| 5 | |||
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 7 | # RUN: echo "SECTIONS { .text : { *(.text) } .eh_frame : { *(.eh_frame) } }" > %t.script | ||
| 8 | # 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 | ||
| 10 | |||
| 11 | # CHECK: Section { | ||
| 12 | # CHECK: Index: | ||
| 13 | # CHECK: Name: .eh_frame | ||
| 14 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 15 | # CHECK-NEXT: Flags [ | ||
| 16 | # CHECK-NEXT: SHF_ALLOC | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | # CHECK-NEXT: Address: 0x1001 | ||
| 19 | # CHECK-NEXT: Offset: 0x1001 | ||
| 20 | # CHECK-NEXT: Size: | ||
| 21 | # CHECK-NEXT: Link: | ||
| 22 | # CHECK-NEXT: Info: | ||
| 23 | # CHECK-NEXT: AddressAlignment: | ||
| 24 | # CHECK-NEXT: EntrySize: | ||
| 25 | # CHECK-NEXT: SectionData ( | ||
| 26 | # CHECK-NEXT: 0000: 14000000 00000000 017A5200 01010101 | ||
| 27 | # CHECK-NEXT: 0010: 1B000000 00000000 0C000000 1C000000 | ||
| 28 | # CHECK-NEXT: 0020: DFFFFFFF | ||
| 29 | # ^ | ||
| 30 | # DFFFFFFF = _start(0x1000) - PC(.eh_frame(0x1001) + 0x20) | ||
| 31 | |||
| 32 | # CHECK: Section { | ||
| 33 | # CHECK: Index: | ||
| 34 | # CHECK: Name: .eh_frame_hdr | ||
| 35 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 36 | # CHECK-NEXT: Flags [ | ||
| 37 | # CHECK-NEXT: SHF_ALLOC | ||
| 38 | # CHECK-NEXT: ] | ||
| 39 | # CHECK-NEXT: Address: 0x1030 | ||
| 40 | # CHECK-NEXT: Offset: 0x1030 | ||
| 41 | # CHECK-NEXT: Size: 20 | ||
| 42 | # CHECK-NEXT: Link: 0 | ||
| 43 | # CHECK-NEXT: Info: 0 | ||
| 44 | # CHECK-NEXT: AddressAlignment: 4 | ||
| 45 | # CHECK-NEXT: EntrySize: 0 | ||
| 46 | # CHECK-NEXT: SectionData ( | ||
| 47 | # CHECK-NEXT: 0000: 011B033B CDFFFFFF 01000000 D0FFFFFF | ||
| 48 | # CHECK-NEXT: 0010: E9FFFFFF | ||
| 49 | # Header (always 4 bytes): 011B033B | ||
| 50 | # CDFFFFFF = .eh_frame(0x1001) - .eh_frame_hdr(0x1030) - 4 | ||
| 51 | # 01000000 = 1 = the number of FDE pointers in the table. | ||
| 52 | # D0FFFFFF = _start(0x1000) - .eh_frame_hdr(0x1030) | ||
| 53 | # E9FFFFFF = FDE(.eh_frame(0x1001) + 0x18) - .eh_frame_hdr(0x1030) | ||
| 54 | |||
| 55 | .text | ||
| 56 | .global _start | ||
| 57 | _start: | ||
| 58 | nop | ||
| 59 | |||
| 60 | .section .eh_frame, "a" | ||
| 61 | .long 16 # Size | ||
| 62 | .long 0x00 # ID | ||
| 63 | .byte 0x01 # Version. | ||
| 64 | |||
| 65 | .byte 0x7A # Augmentation string: "zR" | ||
| 66 | .byte 0x52 | ||
| 67 | .byte 0x00 | ||
| 68 | |||
| 69 | .byte 0x01 | ||
| 70 | |||
| 71 | .byte 0x01 # LEB128 | ||
| 72 | .byte 0x01 # LEB128 | ||
| 73 | |||
| 74 | .byte 0x01 # LEB128 | ||
| 75 | .byte 0x1B # DW_EH_PE_pcrel | DW_EH_PE_sdata4 | ||
| 76 | |||
| 77 | .byte 0x00 | ||
| 78 | .byte 0x00 | ||
| 79 | .byte 0x00 | ||
| 80 | |||
| 81 | .long 12 # Size | ||
| 82 | .long 24 # ID | ||
| 83 | fde: | ||
| 84 | .long _start - fde | ||
| 85 | .long 0 | ||
deps/lld/test/ELF/eh-frame-negative-pcrel-sdata8.s created+85| ... | @@ -0,0 +1,85 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # Test handling of FDE pc negative relative addressing with DW_EH_PE_sdata8. | ||
| 4 | # This situation can arise when .eh_frame is placed after .text. | ||
| 5 | |||
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 7 | # RUN: echo "SECTIONS { .text : { *(.text) } .eh_frame : { *(.eh_frame) } }" > %t.script | ||
| 8 | # 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 | ||
| 10 | |||
| 11 | # CHECK: Section { | ||
| 12 | # CHECK: Index: | ||
| 13 | # CHECK: Name: .eh_frame | ||
| 14 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 15 | # CHECK-NEXT: Flags [ | ||
| 16 | # CHECK-NEXT: SHF_ALLOC | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | # CHECK-NEXT: Address: 0x1001 | ||
| 19 | # CHECK-NEXT: Offset: 0x1001 | ||
| 20 | # CHECK-NEXT: Size: | ||
| 21 | # CHECK-NEXT: Link: | ||
| 22 | # CHECK-NEXT: Info: | ||
| 23 | # CHECK-NEXT: AddressAlignment: | ||
| 24 | # CHECK-NEXT: EntrySize: | ||
| 25 | # CHECK-NEXT: SectionData ( | ||
| 26 | # CHECK-NEXT: 0000: 14000000 00000000 017A5200 01010101 | ||
| 27 | # CHECK-NEXT: 0010: 1C000000 00000000 14000000 1C000000 | ||
| 28 | # CHECK-NEXT: 0020: DFFFFFFF FFFFFFFF | ||
| 29 | # ^ | ||
| 30 | # DFFFFFFF FFFFFFFF = _start(0x1000) - PC(.eh_frame(0x1001) + 0x20) | ||
| 31 | |||
| 32 | # CHECK: Section { | ||
| 33 | # CHECK: Index: | ||
| 34 | # CHECK: Name: .eh_frame_hdr | ||
| 35 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 36 | # CHECK-NEXT: Flags [ | ||
| 37 | # CHECK-NEXT: SHF_ALLOC | ||
| 38 | # CHECK-NEXT: ] | ||
| 39 | # CHECK-NEXT: Address: 0x1038 | ||
| 40 | # CHECK-NEXT: Offset: 0x1038 | ||
| 41 | # CHECK-NEXT: Size: 20 | ||
| 42 | # CHECK-NEXT: Link: 0 | ||
| 43 | # CHECK-NEXT: Info: 0 | ||
| 44 | # CHECK-NEXT: AddressAlignment: 4 | ||
| 45 | # CHECK-NEXT: EntrySize: 0 | ||
| 46 | # CHECK-NEXT: SectionData ( | ||
| 47 | # CHECK-NEXT: 0000: 011B033B C5FFFFFF 01000000 C8FFFFFF | ||
| 48 | # CHECK-NEXT: 0010: E1FFFFFF | ||
| 49 | # Header (always 4 bytes): 011B033B | ||
| 50 | # C5FFFFFF = .eh_frame(0x1001) - .eh_frame_hdr(0x1038) - 4 | ||
| 51 | # 01000000 = 1 = the number of FDE pointers in the table. | ||
| 52 | # C8FFFFFF = _start(0x1000) - .eh_frame_hdr(0x1038) | ||
| 53 | # E1FFFFFF = FDE(.eh_frame(0x1001) + 0x18) - .eh_frame_hdr(0x1038) | ||
| 54 | |||
| 55 | .text | ||
| 56 | .global _start | ||
| 57 | _start: | ||
| 58 | nop | ||
| 59 | |||
| 60 | .section .eh_frame, "a" | ||
| 61 | .long 16 # Size | ||
| 62 | .long 0x00 # ID | ||
| 63 | .byte 0x01 # Version. | ||
| 64 | |||
| 65 | .byte 0x7A # Augmentation string: "zR" | ||
| 66 | .byte 0x52 | ||
| 67 | .byte 0x00 | ||
| 68 | |||
| 69 | .byte 0x01 | ||
| 70 | |||
| 71 | .byte 0x01 # LEB128 | ||
| 72 | .byte 0x01 # LEB128 | ||
| 73 | |||
| 74 | .byte 0x01 # LEB128 | ||
| 75 | .byte 0x1C # DW_EH_PE_pcrel | DW_EH_PE_sdata8 | ||
| 76 | |||
| 77 | .byte 0x00 | ||
| 78 | .byte 0x00 | ||
| 79 | .byte 0x00 | ||
| 80 | |||
| 81 | .long 16 # Size | ||
| 82 | .long 24 # ID | ||
| 83 | fde: | ||
| 84 | .quad _start - fde | ||
| 85 | .long 0 | ||
deps/lld/test/ELF/eh-frame-padding-no-rosegment.s+4-4| ... | @@ -7,6 +7,7 @@ | ... | @@ -7,6 +7,7 @@ |
| 7 | .global bar | 7 | .global bar |
| 8 | .hidden bar | 8 | .hidden bar |
| 9 | bar: | 9 | bar: |
| 10 | ret | ||
| 10 | 11 | ||
| 11 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 12 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 12 | 13 | ||
| ... | @@ -37,8 +38,7 @@ bar: | ... | @@ -37,8 +38,7 @@ bar: |
| 37 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=PHDR %s | 38 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=PHDR %s |
| 38 | 39 | ||
| 39 | // PHDR: Segment Sections | 40 | // PHDR: Segment Sections |
| 40 | // PHDR: .text | 41 | // PHDR: .eh_frame {{.*}}.text |
| 41 | // PHDR-SAME: .eh_frame | ||
| 42 | 42 | ||
| 43 | // Check that the CIE and FDE are padded with 0x00 and not 0xCC when the | 43 | // Check that the CIE and FDE are padded with 0x00 and not 0xCC when the |
| 44 | // .eh_frame section is placed in the executable segment | 44 | // .eh_frame section is placed in the executable segment |
| ... | @@ -58,7 +58,7 @@ bar: | ... | @@ -58,7 +58,7 @@ bar: |
| 58 | // CHECK-NEXT: EntrySize: | 58 | // CHECK-NEXT: EntrySize: |
| 59 | // CHECK-NEXT: SectionData ( | 59 | // CHECK-NEXT: SectionData ( |
| 60 | // CHECK-NEXT: 0000: 1C000000 00000000 017A5052 00017810 | 60 | // CHECK-NEXT: 0000: 1C000000 00000000 017A5052 00017810 |
| 61 | // CHECK-NEXT: 0010: 061BBEFF FFFF1B0C 07089001 00000000 | 61 | // CHECK-NEXT: 0010: 061B2A00 00001B0C 07089001 00000000 |
| 62 | // CHECK-NEXT: 0020: 14000000 24000000 A8FFFFFF 00000000 | 62 | // CHECK-NEXT: 0020: 14000000 24000000 14000000 00000000 |
| 63 | // CHECK-NEXT: 0030: 00000000 00000000 | 63 | // CHECK-NEXT: 0030: 00000000 00000000 |
| 64 | // CHECK-NEXT: ) | 64 | // CHECK-NEXT: ) |
deps/lld/test/ELF/eh-frame-pcrel-overflow.s created+33| ... | @@ -0,0 +1,33 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/eh-frame-pcrel-overflow.s -o %t1.o | ||
| 5 | # RUN: ld.lld --eh-frame-hdr -Ttext=0x90000000 %t.o -o /dev/null | ||
| 6 | # RUN: not ld.lld --eh-frame-hdr %t.o %t1.o -o /dev/null 2>&1 | FileCheck %s | ||
| 7 | # CHECK: error: {{.*}}.o:(.eh_frame): PC offset is too large: 0x90000eac | ||
| 8 | |||
| 9 | .text | ||
| 10 | .global _start | ||
| 11 | _start: | ||
| 12 | ret | ||
| 13 | |||
| 14 | .section .eh_frame, "a" | ||
| 15 | .long 12 # Size | ||
| 16 | .long 0x00 # ID | ||
| 17 | .byte 0x01 # Version. | ||
| 18 | |||
| 19 | .byte 0x52 # Augmentation string: 'R','\0' | ||
| 20 | .byte 0x00 | ||
| 21 | |||
| 22 | .byte 0x01 | ||
| 23 | |||
| 24 | .byte 0x01 # LEB128 | ||
| 25 | .byte 0x01 # LEB128 | ||
| 26 | |||
| 27 | .byte 0x00 # DW_EH_PE_absptr | ||
| 28 | |||
| 29 | .byte 0xFF | ||
| 30 | |||
| 31 | .long 12 # Size | ||
| 32 | .long 0x14 # ID | ||
| 33 | .quad _start + 0x70000000 | ||
deps/lld/test/ELF/eh-frame-rel.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o %t.o -o %t -shared | 3 | // RUN: ld.lld %t.o %t.o -o /dev/null -shared |
| 4 | // We used to try to read the relocations as RELA and error out | 4 | // We used to try to read the relocations as RELA and error out |
| 5 | 5 | ||
| 6 | 	.cfi_startproc | 6 | 	.cfi_startproc |
deps/lld/test/ELF/eh-frame-value-format1.s created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: ld.lld --eh-frame-hdr %t -o /dev/null | ||
| 5 | |||
| 6 | .section .eh_frame | ||
| 7 | .byte 0x14 | ||
| 8 | .byte 0x00 | ||
| 9 | .byte 0x00 | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x01 | ||
| 16 | |||
| 17 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 18 | .byte 0x00 | ||
| 19 | |||
| 20 | .byte 0x01 | ||
| 21 | |||
| 22 | .byte 0x01 # LEB128 | ||
| 23 | .byte 0x01 # LEB128 | ||
| 24 | |||
| 25 | .byte 0x04 # DW_EH_PE_udata8 | ||
| 26 | .byte 0xFF | ||
| 27 | .byte 0xFF | ||
| 28 | .byte 0xFF | ||
| 29 | .byte 0xFF | ||
| 30 | .byte 0xFF | ||
| 31 | .byte 0xFF | ||
| 32 | .byte 0xFF | ||
| 33 | .byte 0xFF | ||
| 34 | |||
| 35 | .byte 0xFF | ||
deps/lld/test/ELF/eh-frame-value-format2.s created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: ld.lld --eh-frame-hdr %t -o /dev/null | ||
| 5 | |||
| 6 | .section .eh_frame | ||
| 7 | .byte 0x14 | ||
| 8 | .byte 0x00 | ||
| 9 | .byte 0x00 | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x01 | ||
| 16 | |||
| 17 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 18 | .byte 0x00 | ||
| 19 | |||
| 20 | .byte 0x01 | ||
| 21 | |||
| 22 | .byte 0x01 # LEB128 | ||
| 23 | .byte 0x01 # LEB128 | ||
| 24 | |||
| 25 | .byte 0x0C # DW_EH_PE_sdata8 | ||
| 26 | .byte 0xFF | ||
| 27 | .byte 0xFF | ||
| 28 | .byte 0xFF | ||
| 29 | .byte 0xFF | ||
| 30 | .byte 0xFF | ||
| 31 | .byte 0xFF | ||
| 32 | .byte 0xFF | ||
| 33 | .byte 0xFF | ||
| 34 | |||
| 35 | .byte 0xFF | ||
deps/lld/test/ELF/eh-frame-value-format3.s created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: ld.lld --eh-frame-hdr %t -o /dev/null | ||
| 5 | |||
| 6 | .section .eh_frame | ||
| 7 | .byte 0x0E | ||
| 8 | .byte 0x00 | ||
| 9 | .byte 0x00 | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x01 | ||
| 16 | |||
| 17 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 18 | .byte 0x00 | ||
| 19 | |||
| 20 | .byte 0x01 | ||
| 21 | |||
| 22 | .byte 0x01 # LEB128 | ||
| 23 | .byte 0x01 # LEB128 | ||
| 24 | |||
| 25 | .byte 0x0A # DW_EH_PE_sdata2 | ||
| 26 | .byte 0xFF | ||
| 27 | .byte 0xFF | ||
| 28 | .byte 0xFF | ||
deps/lld/test/ELF/eh-frame-value-format4.s created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: ld.lld --eh-frame-hdr %t -o /dev/null | ||
| 5 | |||
| 6 | .section .eh_frame | ||
| 7 | .byte 0x0E | ||
| 8 | .byte 0x00 | ||
| 9 | .byte 0x00 | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x01 | ||
| 16 | |||
| 17 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 18 | .byte 0x00 | ||
| 19 | |||
| 20 | .byte 0x01 | ||
| 21 | |||
| 22 | .byte 0x01 # LEB128 | ||
| 23 | .byte 0x01 # LEB128 | ||
| 24 | |||
| 25 | .byte 0x02 # DW_EH_PE_udata2 | ||
| 26 | .byte 0xFF | ||
| 27 | .byte 0xFF | ||
| 28 | .byte 0xFF | ||
deps/lld/test/ELF/eh-frame-value-format5.s created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: ld.lld --eh-frame-hdr %t -o /dev/null | ||
| 5 | |||
| 6 | .section .eh_frame | ||
| 7 | .byte 0x14 | ||
| 8 | .byte 0x00 | ||
| 9 | .byte 0x00 | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x01 | ||
| 16 | |||
| 17 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 18 | .byte 0x00 | ||
| 19 | |||
| 20 | .byte 0x01 | ||
| 21 | |||
| 22 | .byte 0x01 # LEB128 | ||
| 23 | .byte 0x01 # LEB128 | ||
| 24 | |||
| 25 | .byte 0x08 # DW_EH_PE_signed | ||
| 26 | .byte 0xFF | ||
| 27 | .byte 0xFF | ||
| 28 | .byte 0xFF | ||
| 29 | .byte 0xFF | ||
| 30 | .byte 0xFF | ||
| 31 | .byte 0xFF | ||
| 32 | .byte 0xFF | ||
| 33 | .byte 0xFF | ||
| 34 | |||
| 35 | .byte 0xFF | ||
deps/lld/test/ELF/eh-frame-value-format6.s created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: ld.lld --eh-frame-hdr %t -o /dev/null | ||
| 5 | |||
| 6 | .section .eh_frame | ||
| 7 | .byte 0x14 | ||
| 8 | .byte 0x00 | ||
| 9 | .byte 0x00 | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x01 | ||
| 16 | |||
| 17 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 18 | .byte 0x00 | ||
| 19 | |||
| 20 | .byte 0x01 | ||
| 21 | |||
| 22 | .byte 0x01 # LEB128 | ||
| 23 | .byte 0x01 # LEB128 | ||
| 24 | |||
| 25 | .byte 0x00 # DW_EH_PE_absptr | ||
| 26 | .byte 0xFF | ||
| 27 | .byte 0xFF | ||
| 28 | .byte 0xFF | ||
| 29 | .byte 0xFF | ||
| 30 | .byte 0xFF | ||
| 31 | .byte 0xFF | ||
| 32 | .byte 0xFF | ||
| 33 | .byte 0xFF | ||
| 34 | |||
| 35 | .byte 0xFF | ||
deps/lld/test/ELF/eh-frame-value-format7.s created+75| ... | @@ -0,0 +1,75 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: ld.lld --eh-frame-hdr --section-start .text=0x1000 %t.o -o %t | ||
| 5 | # RUN: llvm-readobj -s -section-data %t | FileCheck %s | ||
| 6 | |||
| 7 | ## Check we are able to handle DW_EH_PE_udata2 encoding. | ||
| 8 | |||
| 9 | # CHECK: Section { | ||
| 10 | # CHECK: Index: | ||
| 11 | # CHECK: Name: .eh_frame_hdr | ||
| 12 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 13 | # CHECK-NEXT: Flags [ | ||
| 14 | # CHECK-NEXT: SHF_ALLOC | ||
| 15 | # CHECK-NEXT: ] | ||
| 16 | # CHECK-NEXT: Address: 0x2000 | ||
| 17 | # CHECK-NEXT: Offset: 0x2000 | ||
| 18 | # CHECK-NEXT: Size: 20 | ||
| 19 | # CHECK-NEXT: Link: 0 | ||
| 20 | # CHECK-NEXT: Info: 0 | ||
| 21 | # CHECK-NEXT: AddressAlignment: 4 | ||
| 22 | # CHECK-NEXT: EntrySize: 0 | ||
| 23 | # CHECK-NEXT: SectionData ( | ||
| 24 | # CHECK-NEXT: 0000: 011B033B 10000000 01000000 34F2FFFF | ||
| 25 | # CHECK-NEXT: 0010: 24000000 | ||
| 26 | # Header (always 4 bytes): 011B033B | ||
| 27 | # 10000000 = .eh_frame(0x2014) - .eh_frame_hdr(0x2000) - 4 | ||
| 28 | # 01000000 = 1 = the number of FDE pointers in the table. | ||
| 29 | # 34F2FFFF = foo(0x1000) - 0x234(addend) - .eh_frame_hdr(0x2000) | ||
| 30 | |||
| 31 | # CHECK: Section { | ||
| 32 | # CHECK: Index: | ||
| 33 | # CHECK: Name: .eh_frame | ||
| 34 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 35 | # CHECK-NEXT: Flags [ | ||
| 36 | # CHECK-NEXT: SHF_ALLOC | ||
| 37 | # CHECK-NEXT: ] | ||
| 38 | # CHECK-NEXT: Address: 0x2014 | ||
| 39 | # CHECK-NEXT: Offset: 0x2014 | ||
| 40 | # CHECK-NEXT: Size: | ||
| 41 | # CHECK-NEXT: Link: | ||
| 42 | # CHECK-NEXT: Info: | ||
| 43 | # CHECK-NEXT: AddressAlignment: | ||
| 44 | # CHECK-NEXT: EntrySize: | ||
| 45 | # CHECK-NEXT: SectionData ( | ||
| 46 | # CHECK-NEXT: 0000: 0C000000 00000000 01520001 010102FF | ||
| 47 | # CHECK-NEXT: 0010: 0C000000 14000000 34120000 00000000 | ||
| 48 | # ^ | ||
| 49 | # ---> ADDR(foo) + 0x234 = 0x1234 | ||
| 50 | |||
| 51 | .text | ||
| 52 | .global foo | ||
| 53 | foo: | ||
| 54 | nop | ||
| 55 | |||
| 56 | .section .eh_frame | ||
| 57 | .long 12 # Size | ||
| 58 | .long 0x00 # ID | ||
| 59 | .byte 0x01 # Version. | ||
| 60 | |||
| 61 | .byte 0x52 # Augmentation string: 'R','\0' | ||
| 62 | .byte 0x00 | ||
| 63 | |||
| 64 | .byte 0x01 | ||
| 65 | |||
| 66 | .byte 0x01 # LEB128 | ||
| 67 | .byte 0x01 # LEB128 | ||
| 68 | |||
| 69 | .byte 0x02 # DW_EH_PE_udata2 | ||
| 70 | |||
| 71 | .byte 0xFF | ||
| 72 | |||
| 73 | .long 0x6 # Size | ||
| 74 | .long 0x14 # ID | ||
| 75 | .short foo + 0x234 | ||
deps/lld/test/ELF/eh-frame-value-format8.s created+74| ... | @@ -0,0 +1,74 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: ld.lld --eh-frame-hdr --section-start .text=0x1000 %t.o -o %t | ||
| 5 | # RUN: llvm-readobj -s -section-data %t | FileCheck %s | ||
| 6 | |||
| 7 | ## Check we are able to handle DW_EH_PE_absptr encoding. | ||
| 8 | |||
| 9 | # CHECK: Section { | ||
| 10 | # CHECK: Index: | ||
| 11 | # CHECK: Name: .eh_frame_hdr | ||
| 12 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 13 | # CHECK-NEXT: Flags [ | ||
| 14 | # CHECK-NEXT: SHF_ALLOC | ||
| 15 | # CHECK-NEXT: ] | ||
| 16 | # CHECK-NEXT: Address: 0x2000 | ||
| 17 | # CHECK-NEXT: Offset: 0x2000 | ||
| 18 | # CHECK-NEXT: Size: 20 | ||
| 19 | # CHECK-NEXT: Link: 0 | ||
| 20 | # CHECK-NEXT: Info: 0 | ||
| 21 | # CHECK-NEXT: AddressAlignment: 4 | ||
| 22 | # CHECK-NEXT: EntrySize: 0 | ||
| 23 | # CHECK-NEXT: SectionData ( | ||
| 24 | # CHECK-NEXT: 0000: 011B033B 10000000 01000000 34F2FFFF | ||
| 25 | # CHECK-NEXT: 0010: 24000000 | ||
| 26 | # Header (always 4 bytes): 011B033B | ||
| 27 | # 10000000 = .eh_frame(0x2014) - .eh_frame_hdr(0x2000) - 4 | ||
| 28 | # 01000000 = 1 = the number of FDE pointers in the table. | ||
| 29 | # 34F2FFFF = foo(0x1000) - 0x234(addend) - .eh_frame_hdr(0x2000) | ||
| 30 | |||
| 31 | # CHECK: Section { | ||
| 32 | # CHECK: Index: | ||
| 33 | # CHECK: Name: .eh_frame | ||
| 34 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 35 | # CHECK-NEXT: Flags [ | ||
| 36 | # CHECK-NEXT: SHF_ALLOC | ||
| 37 | # CHECK-NEXT: ] | ||
| 38 | # CHECK-NEXT: Address: 0x2014 | ||
| 39 | # CHECK-NEXT: Offset: 0x2014 | ||
| 40 | # CHECK-NEXT: Size: | ||
| 41 | # CHECK-NEXT: Link: | ||
| 42 | # CHECK-NEXT: Info: | ||
| 43 | # CHECK-NEXT: AddressAlignment: | ||
| 44 | # CHECK-NEXT: EntrySize: | ||
| 45 | # CHECK-NEXT: SectionData ( | ||
| 46 | # CHECK-NEXT: 0000: 0C000000 00000000 01520001 010100FF | ||
| 47 | # CHECK-NEXT: 0010: 0C000000 14000000 34120000 00000000 | ||
| 48 | # ^ | ||
| 49 | # ---> ADDR(foo) + 0x234 = 0x1234 | ||
| 50 | .text | ||
| 51 | .global foo | ||
| 52 | foo: | ||
| 53 | nop | ||
| 54 | |||
| 55 | .section .eh_frame, "ax" | ||
| 56 | .long 12 # Size | ||
| 57 | .long 0x00 # ID | ||
| 58 | .byte 0x01 # Version. | ||
| 59 | |||
| 60 | .byte 0x52 # Augmentation string: 'R','\0' | ||
| 61 | .byte 0x00 | ||
| 62 | |||
| 63 | .byte 0x01 | ||
| 64 | |||
| 65 | .byte 0x01 # LEB128 | ||
| 66 | .byte 0x01 # LEB128 | ||
| 67 | |||
| 68 | .byte 0x00 # DW_EH_PE_absptr | ||
| 69 | |||
| 70 | .byte 0xFF | ||
| 71 | |||
| 72 | .long 12 # Size | ||
| 73 | .long 0x14 # ID | ||
| 74 | .quad foo + 0x234 | ||
deps/lld/test/ELF/eh-frame-value-format9.s created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t.o -o %t 2>&1 | FileCheck %s | ||
| 5 | # CHECK: error: unknown FDE size encoding | ||
| 6 | |||
| 7 | .section .eh_frame, "ax" | ||
| 8 | .long 12 # Size | ||
| 9 | .long 0x00 # ID | ||
| 10 | .byte 0x01 # Version. | ||
| 11 | |||
| 12 | .byte 0x52 # Augmentation string: 'R','\0' | ||
| 13 | .byte 0x00 | ||
| 14 | |||
| 15 | # Code and data alignment factors. | ||
| 16 | .byte 0x01 # LEB128 | ||
| 17 | .byte 0x01 # LEB128 | ||
| 18 | |||
| 19 | # Return address register. | ||
| 20 | .byte 0x01 # LEB128 | ||
| 21 | |||
| 22 | .byte 0xFE # 'R' value: invalid <0xFE> | ||
| 23 | |||
| 24 | .byte 0xFF | ||
| 25 | |||
| 26 | .long 12 # Size | ||
| 27 | .long 0x14 # ID | ||
| 28 | .quad .eh_frame | ||
deps/lld/test/ELF/ehframe-relocation.s+1-1| ... | @@ -12,7 +12,7 @@ | ... | @@ -12,7 +12,7 @@ |
| 12 | // CHECK-NEXT: ] | 12 | // CHECK-NEXT: ] |
| 13 | // CHECK-NEXT: Address: 0x200120 | 13 | // CHECK-NEXT: Address: 0x200120 |
| 14 | // CHECK-NEXT: Offset: | 14 | // CHECK-NEXT: Offset: |
| 15 | // CHECK-NEXT: Size: 48 | 15 | // CHECK-NEXT: Size: 52 |
| 16 | // CHECK-NOT: .eh_frame | 16 | // CHECK-NOT: .eh_frame |
| 17 | 17 | ||
| 18 | // 0x200120 = 2097440 | 18 | // 0x200120 = 2097440 |
deps/lld/test/ELF/elf-header.s created+18| ... | @@ -0,0 +1,18 @@ | ||
| 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 %t1 | ||
| 4 | # RUN: llvm-readobj -file-headers %t1 | FileCheck %s | ||
| 5 | |||
| 6 | # RUN: ld.lld %t.o -no-rosegment -o %t2 | ||
| 7 | # RUN: llvm-readobj -file-headers %t2 | FileCheck %s | ||
| 8 | |||
| 9 | # CHECK: ElfHeader { | ||
| 10 | # CHECK-NEXT: Ident { | ||
| 11 | # CHECK-NEXT: Magic: (7F 45 4C 46) | ||
| 12 | # CHECK-NEXT: Class: 64-bit (0x2) | ||
| 13 | # CHECK-NEXT: DataEncoding: LittleEndian (0x1) | ||
| 14 | # CHECK-NEXT: FileVersion: 1 | ||
| 15 | # CHECK-NEXT: OS/ABI: SystemV (0x0) | ||
| 16 | # CHECK-NEXT: ABIVersion: 0 | ||
| 17 | # CHECK-NEXT: Unused: (00 00 00 00 00 00 00) | ||
| 18 | # CHECK-NEXT: } | ||
deps/lld/test/ELF/emit-relocs-eh-frame.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 3 | # RUN: ld.lld --emit-relocs %t1.o -o %t | ||
| 4 | # RUN: llvm-readobj -r %t | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: Relocations [ | ||
| 7 | # CHECK-NEXT: Section {{.*}} .rela.eh_frame { | ||
| 8 | # CHECK-NEXT: 0x{{.*}} R_X86_64_PC32 .text 0x0 | ||
| 9 | # CHECK-NEXT: } | ||
| 10 | # CHECK-NEXT: ] | ||
| 11 | |||
| 12 | .text | ||
| 13 | .globl foo | ||
| 14 | foo: | ||
| 15 | .cfi_startproc | ||
| 16 | .cfi_endproc | ||
deps/lld/test/ELF/emit-relocs-gc.s+2-2| ... | @@ -11,8 +11,8 @@ | ... | @@ -11,8 +11,8 @@ |
| 11 | ## .rela.text because we keep .text. | 11 | ## .rela.text because we keep .text. |
| 12 | # RUN: ld.lld --gc-sections --emit-relocs --print-gc-sections %t.o -o %t \ | 12 | # RUN: ld.lld --gc-sections --emit-relocs --print-gc-sections %t.o -o %t \ |
| 13 | # RUN: | FileCheck --check-prefix=MSG %s | 13 | # RUN: | FileCheck --check-prefix=MSG %s |
| 14 | # MSG: removing unused section from '.bar' in file | 14 | # MSG: removing unused section {{.*}}.o:(.bar) |
| 15 | # MSG: removing unused section from '.rela.bar' in file | 15 | # MSG: removing unused section {{.*}}.o:(.rela.bar) |
| 16 | # RUN: llvm-objdump %t -section-headers | FileCheck %s --check-prefix=GC | 16 | # RUN: llvm-objdump %t -section-headers | FileCheck %s --check-prefix=GC |
| 17 | # GC-NOT: rela.bar | 17 | # GC-NOT: rela.bar |
| 18 | # GC: rela.text | 18 | # GC: rela.text |
deps/lld/test/ELF/emit-relocs-icf.s created+33| ... | @@ -0,0 +1,33 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 3 | # RUN: ld.lld --emit-relocs --icf=all %t1.o -o %t | ||
| 4 | # RUN: llvm-readobj -r %t | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: Relocations [ | ||
| 7 | # CHECK-NEXT: Section {{.*}} .rela.text { | ||
| 8 | # CHECK-NEXT: R_X86_64_32 .text 0x1 | ||
| 9 | # CHECK-NEXT: R_X86_64_PLT32 fn 0xFFFFFFFFFFFFFFFC | ||
| 10 | # CHECK-NEXT: } | ||
| 11 | # CHECK-NEXT: ] | ||
| 12 | |||
| 13 | .section .text.fn,"ax",@progbits,unique,0 | ||
| 14 | .globl fn | ||
| 15 | .type fn,@function | ||
| 16 | fn: | ||
| 17 | nop | ||
| 18 | |||
| 19 | bar: | ||
| 20 | movl $bar, %edx | ||
| 21 | callq fn@PLT | ||
| 22 | nop | ||
| 23 | |||
| 24 | .section .text.fn2,"ax",@progbits,unique,1 | ||
| 25 | .globl fn2 | ||
| 26 | .type fn2,@function | ||
| 27 | fn2: | ||
| 28 | nop | ||
| 29 | |||
| 30 | foo: | ||
| 31 | movl $foo, %edx | ||
| 32 | callq fn2@PLT | ||
| 33 | nop | ||
deps/lld/test/ELF/emit-relocs-shared.s+2-2| ... | @@ -7,10 +7,10 @@ | ... | @@ -7,10 +7,10 @@ |
| 7 | .quad foo | 7 | .quad foo |
| 8 | 8 | ||
| 9 | # CHECK: Relocations [ | 9 | # CHECK: Relocations [ |
| 10 | # CHECK-NEXT: Section (4) .rela.dyn { | 10 | # CHECK-NEXT: Section {{.*}} .rela.dyn { |
| 11 | # CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0 | 11 | # CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0 |
| 12 | # CHECK-NEXT: } | 12 | # CHECK-NEXT: } |
| 13 | # CHECK-NEXT: Section (8) .rela.data { | 13 | # CHECK-NEXT: Section {{.*}} .rela.data { |
| 14 | # CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0 | 14 | # CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0 |
| 15 | # CHECK-NEXT: } | 15 | # CHECK-NEXT: } |
| 16 | # CHECK-NEXT: ] | 16 | # CHECK-NEXT: ] |
deps/lld/test/ELF/emit-relocs.s+1-1| ... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | ||
| 14 | # CHECK: Section { | 14 | # CHECK: Section { |
| 15 | # CHECK: Index: 2 | 15 | # CHECK: Index: 2 |
| 16 | # CHECK-NEXT: Name: .rela.text | 16 | # CHECK: Name: .rela.text |
| 17 | # CHECK-NEXT: Type: SHT_RELA | 17 | # CHECK-NEXT: Type: SHT_RELA |
| 18 | # CHECK-NEXT: Flags [ | 18 | # CHECK-NEXT: Flags [ |
| 19 | # CHECK-NEXT: SHF_INFO_LINK | 19 | # CHECK-NEXT: SHF_INFO_LINK |
deps/lld/test/ELF/empty-archive.s+2-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-ar rc %t.a | 2 | // RUN: llvm-ar rc %t.a |
| 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 -o %t.o |
| 3 | // RUN: ld.lld -shared %t.o %t.a -o t | 4 | // RUN: ld.lld -shared %t.o %t.a -o /dev/null |
deps/lld/test/ELF/empty-ver2.s created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: mkdir -p %t.dir | ||
| 3 | # RUN: cd %t.dir | ||
| 4 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | ||
| 5 | # 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 | ||
| 7 | |||
| 8 | # CHECK: Symbols [ | ||
| 9 | # CHECK-NEXT: Symbol { | ||
| 10 | # CHECK-NEXT: Version: 0 | ||
| 11 | # CHECK-NEXT: Name: @ | ||
| 12 | # CHECK-NEXT: } | ||
| 13 | # CHECK-NEXT: Symbol { | ||
| 14 | # CHECK-NEXT: Version: 1 | ||
| 15 | # CHECK-NEXT: Name: bar@@ | ||
| 16 | # CHECK-NEXT: } | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | |||
| 19 | .global bar@ | ||
| 20 | bar@: | ||
deps/lld/test/ELF/emulation.s+42-6| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86,ppc,mips,aarch64 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %tx64 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %tx64 |
| 2 | # RUN: ld.lld -m elf_amd64_fbsd %tx64 -o %t2x64 | 3 | # RUN: ld.lld -m elf_amd64_fbsd %tx64 -o %t2x64 |
| 3 | # RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=AMD64 %s | 4 | # RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=AMD64 %s |
| ... | @@ -208,7 +209,8 @@ | ... | @@ -208,7 +209,8 @@ |
| 208 | # PPC64-NEXT: Entry: | 209 | # PPC64-NEXT: Entry: |
| 209 | # PPC64-NEXT: ProgramHeaderOffset: 0x40 | 210 | # PPC64-NEXT: ProgramHeaderOffset: 0x40 |
| 210 | # PPC64-NEXT: SectionHeaderOffset: | 211 | # PPC64-NEXT: SectionHeaderOffset: |
| 211 | # PPC64-NEXT: Flags [ (0x0) | 212 | # PPC64-NEXT: Flags [ (0x2) |
| 213 | # PPC64-NEXT: 0x2 | ||
| 212 | # PPC64-NEXT: ] | 214 | # PPC64-NEXT: ] |
| 213 | # PPC64-NEXT: HeaderSize: 64 | 215 | # PPC64-NEXT: HeaderSize: 64 |
| 214 | # PPC64-NEXT: ProgramHeaderEntrySize: 56 | 216 | # PPC64-NEXT: ProgramHeaderEntrySize: 56 |
| ... | @@ -218,6 +220,38 @@ | ... | @@ -218,6 +220,38 @@ |
| 218 | # PPC64-NEXT: StringTableSectionIndex: | 220 | # PPC64-NEXT: StringTableSectionIndex: |
| 219 | # PPC64-NEXT: } | 221 | # PPC64-NEXT: } |
| 220 | 222 | ||
| 223 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le | ||
| 224 | # RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le | ||
| 225 | # RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s | ||
| 226 | # RUN: ld.lld %tppc64le -o %t3ppc64le | ||
| 227 | # RUN: llvm-readobj -file-headers %t3ppc64le | FileCheck --check-prefix=PPC64LE %s | ||
| 228 | # PPC64LE: ElfHeader { | ||
| 229 | # PPC64LE-NEXT: Ident { | ||
| 230 | # PPC64LE-NEXT: Magic: (7F 45 4C 46) | ||
| 231 | # PPC64LE-NEXT: Class: 64-bit (0x2) | ||
| 232 | # PPC64LE-NEXT: DataEncoding: LittleEndian (0x1) | ||
| 233 | # PPC64LE-NEXT: FileVersion: 1 | ||
| 234 | # PPC64LE-NEXT: OS/ABI: SystemV (0x0) | ||
| 235 | # PPC64LE-NEXT: ABIVersion: 0 | ||
| 236 | # PPC64LE-NEXT: Unused: (00 00 00 00 00 00 00) | ||
| 237 | # PPC64LE-NEXT: } | ||
| 238 | # PPC64LE-NEXT: Type: Executable (0x2) | ||
| 239 | # PPC64LE-NEXT: Machine: EM_PPC64 (0x15) | ||
| 240 | # PPC64LE-NEXT: Version: 1 | ||
| 241 | # PPC64LE-NEXT: Entry: | ||
| 242 | # PPC64LE-NEXT: ProgramHeaderOffset: 0x40 | ||
| 243 | # PPC64LE-NEXT: SectionHeaderOffset: | ||
| 244 | # PPC64LE-NEXT: Flags [ (0x2) | ||
| 245 | # PPC64LE-NEXT: 0x2 | ||
| 246 | # PPC64LE-NEXT: ] | ||
| 247 | # PPC64LE-NEXT: HeaderSize: 64 | ||
| 248 | # PPC64LE-NEXT: ProgramHeaderEntrySize: 56 | ||
| 249 | # PPC64LE-NEXT: ProgramHeaderCount: | ||
| 250 | # PPC64LE-NEXT: SectionHeaderEntrySize: 64 | ||
| 251 | # PPC64LE-NEXT: SectionHeaderCount: | ||
| 252 | # PPC64LE-NEXT: StringTableSectionIndex: | ||
| 253 | # PPC64LE-NEXT: } | ||
| 254 | |||
| 221 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %tmips | 255 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %tmips |
| 222 | # RUN: ld.lld -m elf32btsmip -e _start %tmips -o %t2mips | 256 | # RUN: ld.lld -m elf32btsmip -e _start %tmips -o %t2mips |
| 223 | # RUN: llvm-readobj -file-headers %t2mips | FileCheck --check-prefix=MIPS %s | 257 | # RUN: llvm-readobj -file-headers %t2mips | FileCheck --check-prefix=MIPS %s |
| ... | @@ -230,7 +264,7 @@ | ... | @@ -230,7 +264,7 @@ |
| 230 | # MIPS-NEXT: DataEncoding: BigEndian (0x2) | 264 | # MIPS-NEXT: DataEncoding: BigEndian (0x2) |
| 231 | # MIPS-NEXT: FileVersion: 1 | 265 | # MIPS-NEXT: FileVersion: 1 |
| 232 | # MIPS-NEXT: OS/ABI: SystemV (0x0) | 266 | # MIPS-NEXT: OS/ABI: SystemV (0x0) |
| 233 | # MIPS-NEXT: ABIVersion: 0 | 267 | # MIPS-NEXT: ABIVersion: 1 |
| 234 | # MIPS-NEXT: Unused: (00 00 00 00 00 00 00) | 268 | # MIPS-NEXT: Unused: (00 00 00 00 00 00 00) |
| 235 | # MIPS-NEXT: } | 269 | # MIPS-NEXT: } |
| 236 | # MIPS-NEXT: Type: Executable (0x2) | 270 | # MIPS-NEXT: Type: Executable (0x2) |
| ... | @@ -259,7 +293,7 @@ | ... | @@ -259,7 +293,7 @@ |
| 259 | # MIPSEL-NEXT: DataEncoding: LittleEndian (0x1) | 293 | # MIPSEL-NEXT: DataEncoding: LittleEndian (0x1) |
| 260 | # MIPSEL-NEXT: FileVersion: 1 | 294 | # MIPSEL-NEXT: FileVersion: 1 |
| 261 | # MIPSEL-NEXT: OS/ABI: SystemV (0x0) | 295 | # MIPSEL-NEXT: OS/ABI: SystemV (0x0) |
| 262 | # MIPSEL-NEXT: ABIVersion: 0 | 296 | # MIPSEL-NEXT: ABIVersion: 1 |
| 263 | # MIPSEL-NEXT: Unused: (00 00 00 00 00 00 00) | 297 | # MIPSEL-NEXT: Unused: (00 00 00 00 00 00 00) |
| 264 | # MIPSEL-NEXT: } | 298 | # MIPSEL-NEXT: } |
| 265 | # MIPSEL-NEXT: Type: Executable (0x2) | 299 | # MIPSEL-NEXT: Type: Executable (0x2) |
| ... | @@ -333,8 +367,12 @@ | ... | @@ -333,8 +367,12 @@ |
| 333 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64 | 367 | # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64 |
| 334 | # RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64 | 368 | # RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64 |
| 335 | # RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s | 369 | # RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s |
| 336 | # RUN: ld.lld %taarch64 -o %t3aarch64 | 370 | # RUN: ld.lld -m aarch64elf %taarch64 -o %t3aarch64 |
| 337 | # RUN: llvm-readobj -file-headers %t3aarch64 | FileCheck --check-prefix=AARCH64 %s | 371 | # RUN: llvm-readobj -file-headers %t3aarch64 | FileCheck --check-prefix=AARCH64 %s |
| 372 | # RUN: ld.lld -m aarch64_elf64_le_vec %taarch64 -o %t4aarch64 | ||
| 373 | # RUN: llvm-readobj -file-headers %t4aarch64 | FileCheck --check-prefix=AARCH64 %s | ||
| 374 | # RUN: ld.lld %taarch64 -o %t5aarch64 | ||
| 375 | # RUN: llvm-readobj -file-headers %t5aarch64 | FileCheck --check-prefix=AARCH64 %s | ||
| 338 | # AARCH64: ElfHeader { | 376 | # AARCH64: ElfHeader { |
| 339 | # AARCH64-NEXT: Ident { | 377 | # AARCH64-NEXT: Ident { |
| 340 | # AARCH64-NEXT: Magic: (7F 45 4C 46) | 378 | # AARCH64-NEXT: Magic: (7F 45 4C 46) |
| ... | @@ -354,7 +392,5 @@ | ... | @@ -354,7 +392,5 @@ |
| 354 | # AARCH64-NEXT: Flags [ (0x0) | 392 | # AARCH64-NEXT: Flags [ (0x0) |
| 355 | # AARCH64-NEXT: ] | 393 | # AARCH64-NEXT: ] |
| 356 | 394 | ||
| 357 | # REQUIRES: x86,ppc,mips,aarch64 | ||
| 358 | |||
| 359 | .globl _start | 395 | .globl _start |
| 360 | _start: | 396 | _start: |
deps/lld/test/ELF/end-preserve.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | // Should preserve the value of the "end" symbol if it is defined. | ||
| 2 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // Should preserve the value of the "end" symbol if it is defined. | ||
| 3 | 3 | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 5 | // RUN: ld.lld %t.o -o %t | 5 | // RUN: ld.lld %t.o -o %t |
deps/lld/test/ELF/end-update.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | // Should set the value of the "end" symbol if it is undefined. | ||
| 2 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // Should set the value of the "end" symbol if it is undefined. | ||
| 3 | 3 | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 5 | // RUN: ld.lld %t.o -o %t | 5 | // RUN: ld.lld %t.o -o %t |
deps/lld/test/ELF/end.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | // Should set the value of the "_end" symbol to the end of the data segment. | ||
| 2 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // Should set the value of the "_end" symbol to the end of the data segment. | ||
| 3 | 3 | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 5 | 5 |
deps/lld/test/ELF/entry.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 2 | 3 | ||
| 3 | # RUN: ld.lld -e foobar %t1 -o %t2 2>&1 | FileCheck -check-prefix=WARN1 %s | 4 | # RUN: ld.lld -e foobar %t1 -o %t2 2>&1 | FileCheck -check-prefix=WARN1 %s |
deps/lld/test/ELF/exclude-libs.s+11-2| ... | @@ -3,9 +3,10 @@ | ... | @@ -3,9 +3,10 @@ |
| 3 | // 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 %s -o %t.o |
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 5 | // RUN: %p/Inputs/exclude-libs.s -o %t2.o | 5 | // RUN: %p/Inputs/exclude-libs.s -o %t2.o |
| 6 | // RUN: llvm-as --data-layout=elf %p/Inputs/exclude-libs.ll -o %t3.o | ||
| 6 | // RUN: mkdir -p %t.dir | 7 | // RUN: mkdir -p %t.dir |
| 7 | // RUN: rm -f %t.dir/exc.a | 8 | // RUN: rm -f %t.dir/exc.a |
| 8 | // RUN: llvm-ar rcs %t.dir/exc.a %t2.o | 9 | // RUN: llvm-ar rcs %t.dir/exc.a %t2.o %t3.o |
| 9 | 10 | ||
| 10 | // RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe | 11 | // RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe |
| 11 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s | 12 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s |
| ... | @@ -22,6 +23,9 @@ | ... | @@ -22,6 +23,9 @@ |
| 22 | // RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL | 23 | // RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL |
| 23 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s | 24 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s |
| 24 | 25 | ||
| 26 | // 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 | ||
| 28 | |||
| 25 | // RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a | 29 | // RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a |
| 26 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s | 30 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s |
| 27 | 31 | ||
| ... | @@ -29,8 +33,13 @@ | ... | @@ -29,8 +33,13 @@ |
| 29 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s | 33 | // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s |
| 30 | 34 | ||
| 31 | // DEFAULT: Name: fn | 35 | // DEFAULT: Name: fn |
| 36 | // DEFAULT: Name: fn2 | ||
| 37 | // DEFAULT: Name: foo | ||
| 32 | // EXCLUDE-NOT: Name: fn | 38 | // EXCLUDE-NOT: Name: fn |
| 39 | // EXCLUDE-NOT: Name: fn2 | ||
| 40 | // EXCLUDE: Name: foo | ||
| 33 | 41 | ||
| 34 | .globl fn | 42 | .globl fn, fn2, foo |
| 35 | foo: | 43 | foo: |
| 36 | call fn@PLT | 44 | call fn@PLT |
| 45 | call fn2@PLT |
deps/lld/test/ELF/executable-undefined-protected-ignoreall.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | # RUN: not ld.lld %t -o %tout --unresolved-symbols=ignore-all -pie 2>&1 | FileCheck %s | 3 | # 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 symbol: foo |
| 5 | 5 | ||
| 6 | .protected foo | 6 | .protected foo |
deps/lld/test/ELF/execute-only-mixed-data.s created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | // REQUIRES: aarch64 | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o | ||
| 4 | |||
| 5 | // RUN: echo "SECTIONS \ | ||
| 6 | // RUN: { \ | ||
| 7 | // RUN: .text : { *(.text) *(.rodata.foo) } \ | ||
| 8 | // RUN: .rodata : { *(.rodata.bar) } \ | ||
| 9 | // RUN: }" > %t.lds | ||
| 10 | // RUN: not ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1 | FileCheck %s | ||
| 11 | |||
| 12 | // RUN: echo "SECTIONS \ | ||
| 13 | // RUN: { \ | ||
| 14 | // RUN: .text : { *(.text) } \ | ||
| 15 | // RUN: .rodata : { *(.rodata.bar) *(.rodata.foo) } \ | ||
| 16 | // RUN: }" > %t.lds | ||
| 17 | // RUN: ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1 | ||
| 18 | |||
| 19 | // CHECK: -execute-only does not support intermingling data and code | ||
| 20 | |||
| 21 | br lr | ||
| 22 | |||
| 23 | .section .rodata.foo | ||
| 24 | .word 0x1 | ||
| 25 | .section .rodata.bar | ||
| 26 | .word 0x2 | ||
deps/lld/test/ELF/execute-only.s created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | // REQUIRES: aarch64 | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o | ||
| 4 | // RUN: ld.lld -Ttext=0xcafe0000 %t.o -o %t.so -shared -execute-only | ||
| 5 | // RUN: llvm-readelf -l %t.so | FileCheck %s | ||
| 6 | |||
| 7 | // CHECK: LOAD {{.*}} 0x00000000cafe0000 0x000004 0x000004 E 0x{{.*}} | ||
| 8 | // CHECK-NOT: LOAD {{.*}} 0x00000000cafe0000 0x000004 0x000004 R E 0x{{.*}} | ||
| 9 | |||
| 10 | br lr | ||
deps/lld/test/ELF/export-dynamic-symbol.s created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: rm -f %t.a | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive2.s -o %t1.o | ||
| 5 | # RUN: llvm-ar rcs %t.a %t1.o | ||
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o | ||
| 7 | |||
| 8 | # RUN: ld.lld -shared -o %t.so --export-dynamic-symbol foo %t.a %t2.o | ||
| 9 | # RUN: llvm-readelf -dyn-symbols %t.so | FileCheck %s | ||
| 10 | |||
| 11 | # RUN: ld.lld -shared -o %t.so --export-dynamic --export-dynamic-symbol foo %t.a %t2.o | ||
| 12 | # RUN: llvm-readelf -dyn-symbols %t.so | FileCheck %s | ||
| 13 | |||
| 14 | # CHECK: foo | ||
| 15 | |||
| 16 | .global _start | ||
| 17 | _start: | ||
| 18 | nop | ||
deps/lld/test/ELF/fatal-warnings.s+2-2| ... | @@ -2,11 +2,11 @@ | ... | @@ -2,11 +2,11 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common.s -o %t2.o |
| 4 | 4 | ||
| 5 | # RUN: ld.lld --warn-common %t1.o %t2.o -o %t1.out 2>&1 | \ | 5 | # RUN: ld.lld --warn-common %t1.o %t2.o -o /dev/null 2>&1 | \ |
| 6 | # RUN: FileCheck -check-prefix=ERR %s | 6 | # RUN: FileCheck -check-prefix=ERR %s |
| 7 | # ERR: multiple common of | 7 | # ERR: multiple common of |
| 8 | 8 | ||
| 9 | # RUN: not ld.lld --warn-common --fatal-warnings %t1.o %t2.o -o %t2.out 2>&1 | \ | 9 | # RUN: not ld.lld --warn-common --fatal-warnings %t1.o %t2.o -o /dev/null 2>&1 | \ |
| 10 | # RUN: FileCheck -check-prefix=ERR %s | 10 | # RUN: FileCheck -check-prefix=ERR %s |
| 11 | 11 | ||
| 12 | .globl _start | 12 | .globl _start |
deps/lld/test/ELF/file-sym.s deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | # Check that we do not keep STT_FILE symbols in the symbol table | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 4 | # RUN: ld.lld %t.o -shared -o %t.so | ||
| 5 | # RUN: llvm-readobj -symbols %t.so | FileCheck %s | ||
| 6 | |||
| 7 | # REQUIRES: x86 | ||
| 8 | |||
| 9 | # CHECK-NOT: xxx | ||
| 10 | |||
| 11 | .file "xxx" | ||
| 12 | .file "" | ||
deps/lld/test/ELF/fill-trap-ppc.s created+31| ... | @@ -0,0 +1,31 @@ | ||
| 1 | # REQUIRES: ppc | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-linux %s -o %t.o | ||
| 4 | # RUN: ld.lld %t.o -o %t.ppc64le | ||
| 5 | # RUN: llvm-readobj -program-headers %t.ppc64le | FileCheck %s | ||
| 6 | # RUN: od -Ax -t x1 -N16 -j0x10ff0 %t.ppc64le | FileCheck %s -check-prefix=LE | ||
| 7 | |||
| 8 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-linux %s -o %t.o | ||
| 9 | # RUN: ld.lld %t.o -o %t.ppc64 | ||
| 10 | # RUN: llvm-readobj -program-headers %t.ppc64 | FileCheck %s | ||
| 11 | # RUN: od -Ax -t x1 -N16 -j0x10ff0 %t.ppc64 | FileCheck %s -check-prefix=BE | ||
| 12 | |||
| 13 | # CHECK: ProgramHeader { | ||
| 14 | # CHECK: Type: PT_LOAD | ||
| 15 | # CHECK: Offset: 0x10000{{$}} | ||
| 16 | # CHECK-NEXT: VirtualAddress: | ||
| 17 | # CHECK-NEXT: PhysicalAddress: | ||
| 18 | # CHECK-NEXT: FileSize: 4096 | ||
| 19 | # CHECK-NEXT: MemSize: | ||
| 20 | # CHECK-NEXT: Flags [ | ||
| 21 | # CHECK-NEXT: PF_R | ||
| 22 | # CHECK-NEXT: PF_X | ||
| 23 | # CHECK-NEXT: ] | ||
| 24 | |||
| 25 | ## Check that executable page is filled with traps at its end. | ||
| 26 | # LE: 010ff0 08 00 e0 7f 08 00 e0 7f 08 00 e0 7f 08 00 e0 7f | ||
| 27 | # BE: 010ff0 7f e0 00 08 7f e0 00 08 7f e0 00 08 7f e0 00 08 | ||
| 28 | |||
| 29 | .globl _start | ||
| 30 | _start: | ||
| 31 | nop | ||
deps/lld/test/ELF/filter.s+2-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | # RUN: ld.lld %t.o -shared -F foo.so -F boo.so -o %t1 | 3 | # RUN: ld.lld %t.o -shared -F foo.so -F boo.so -o %t1 |
| 3 | # RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s | 4 | # RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s |
| ... | @@ -15,5 +16,5 @@ | ... | @@ -15,5 +16,5 @@ |
| 15 | # CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [foo.so] | 16 | # CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [foo.so] |
| 16 | # CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [boo.so] | 17 | # CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [boo.so] |
| 17 | 18 | ||
| 18 | # RUN: not ld.lld %t.o -F x -o %t 2>&1 | FileCheck -check-prefix=ERR %s | 19 | # RUN: not ld.lld %t.o -F x -o /dev/null 2>&1 | FileCheck -check-prefix=ERR %s |
| 19 | # ERR: -F may not be used without -shared | 20 | # ERR: -F may not be used without -shared |
deps/lld/test/ELF/format-binary-non-ascii.s+3-3| ... | @@ -4,9 +4,9 @@ | ... | @@ -4,9 +4,9 @@ |
| 4 | # RUN: ld.lld -o %t.elf %t£.o --format=binary %t£.o | 4 | # 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 |
| 6 | 6 | ||
| 7 | # CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_start | 7 | # CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp_{{[_]+}}o_start |
| 8 | # CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_end | 8 | # CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp_{{[_]+}}o_end |
| 9 | # CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_size | 9 | # CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp_{{[_]+}}o_size |
| 10 | 10 | ||
| 11 | .text | 11 | .text |
| 12 | .align 4 | 12 | .align 4 |
deps/lld/test/ELF/gc-absolute.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 -shared --gc-sections | 4 | # RUN: ld.lld %t -o /dev/null -shared --gc-sections |
| 5 | 5 | ||
| 6 | .global foo | 6 | .global foo |
| 7 | foo = 0x123 | 7 | foo = 0x123 |
deps/lld/test/ELF/gc-debuginfo-tls.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | # RUN: ld.lld %t.o --gc-sections -shared -o %t1 | 3 | # RUN: ld.lld %t.o --gc-sections -shared -o %t1 |
| 3 | # RUN: ld.lld %t.o -shared -o %t2 | 4 | # RUN: ld.lld %t.o -shared -o %t2 |
deps/lld/test/ELF/gc-merge-local-sym.s+2-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared -O3 --gc-sections | 3 | // RUN: ld.lld %t.o -o %t.so -shared -O3 --gc-sections |
| 3 | // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s |
| ... | @@ -9,7 +10,7 @@ | ... | @@ -9,7 +10,7 @@ |
| 9 | // CHECK-NEXT: SHF_MERGE | 10 | // CHECK-NEXT: SHF_MERGE |
| 10 | // CHECK-NEXT: SHF_STRINGS | 11 | // CHECK-NEXT: SHF_STRINGS |
| 11 | // CHECK-NEXT: ] | 12 | // CHECK-NEXT: ] |
| 12 | // CHECK-NEXT: Address: 0x1C8 | 13 | // CHECK-NEXT: Address: 0x235 |
| 13 | // CHECK-NEXT: Offset: | 14 | // CHECK-NEXT: Offset: |
| 14 | // CHECK-NEXT: Size: 4 | 15 | // CHECK-NEXT: Size: 4 |
| 15 | // CHECK-NEXT: Link: 0 | 16 | // CHECK-NEXT: Link: 0 |
deps/lld/test/ELF/gc-sections-local-sym.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 -shared --gc-sections | 3 | // RUN: ld.lld %t -o %t2 -shared --gc-sections |
| 3 | // RUN: llvm-readobj -t -s -section-data %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t -s -section-data %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | .global foo | 6 | .global foo |
| 7 | foo: | 7 | foo: |
deps/lld/test/ELF/gc-sections-merge-addend.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared --gc-sections | 3 | // RUN: ld.lld %t.o -o %t.so -shared --gc-sections |
| 3 | // RUN: llvm-readobj -s -section-data %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -s -section-data %t.so | FileCheck %s |
deps/lld/test/ELF/gc-sections-merge-implicit-addend.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared --gc-sections | 3 | // RUN: ld.lld %t.o -o %t.so -shared --gc-sections |
| 3 | // RUN: llvm-readobj -s -section-data %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -s -section-data %t.so | FileCheck %s |
deps/lld/test/ELF/gc-sections-merge.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared | 3 | // RUN: ld.lld %t.o -o %t.so -shared |
| 3 | // RUN: ld.lld %t.o -o %t.gc.so -shared --gc-sections | 4 | // RUN: ld.lld %t.o -o %t.gc.so -shared --gc-sections |
deps/lld/test/ELF/gc-sections-metadata-startstop.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # LINK_ORDER cnamed sections are not kept alive by the __start_* reference. | ||
| 2 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # LINK_ORDER cnamed sections are not kept alive by the __start_* reference. | ||
| 3 | 3 | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 5 | # RUN: ld.lld --gc-sections %t.o -o %t | 5 | # RUN: ld.lld --gc-sections %t.o -o %t |
deps/lld/test/ELF/gc-sections-no-undef-error.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | |||
| 5 | # Sanity check that the link will fail with the undefined error without | ||
| 6 | # gc-sections. | ||
| 7 | # RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s | ||
| 8 | # CHECK: error: undefined symbol: undefined | ||
| 9 | |||
| 10 | # RUN: ld.lld %t.o --gc-sections -o %t | ||
| 11 | |||
| 12 | .section .text.unused,"ax",@progbits | ||
| 13 | unused: | ||
| 14 | callq undefined | ||
| 15 | |||
| 16 | .text | ||
| 17 | .global _start | ||
| 18 | _start: | ||
| 19 | nop | ||
deps/lld/test/ELF/gc-sections-print.s+2-2| ... | @@ -2,8 +2,8 @@ | ... | @@ -2,8 +2,8 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | # RUN: ld.lld %t --gc-sections --print-gc-sections -o %t2 2>&1 | FileCheck -check-prefix=PRINT %s | 3 | # RUN: ld.lld %t --gc-sections --print-gc-sections -o %t2 2>&1 | FileCheck -check-prefix=PRINT %s |
| 4 | 4 | ||
| 5 | # PRINT: removing unused section from '.text.x' in file | 5 | # PRINT: removing unused section {{.*}}:(.text.x) |
| 6 | # PRINT-NEXT: removing unused section from '.text.y' in file | 6 | # PRINT-NEXT: removing unused section {{.*}}:(.text.y) |
| 7 | 7 | ||
| 8 | # RUN: ld.lld %t --gc-sections --print-gc-sections --no-print-gc-sections -o %t2 >& %t.log | 8 | # RUN: ld.lld %t --gc-sections --print-gc-sections --no-print-gc-sections -o %t2 >& %t.log |
| 9 | # RUN: echo >> %t.log | 9 | # RUN: echo >> %t.log |
deps/lld/test/ELF/gc-sections-protected.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared --gc-sections | 3 | // RUN: ld.lld %t.o -o %t.so -shared --gc-sections |
| 3 | // RUN: llvm-readobj -s %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -s %t.so | FileCheck %s |
deps/lld/test/ELF/gc-sections-shared.s+14-66| ... | @@ -25,6 +25,15 @@ | ... | @@ -25,6 +25,15 @@ |
| 25 | # CHECK-NEXT: Section: Undefined (0x0) | 25 | # CHECK-NEXT: Section: Undefined (0x0) |
| 26 | # CHECK-NEXT: } | 26 | # CHECK-NEXT: } |
| 27 | # CHECK-NEXT: Symbol { | 27 | # CHECK-NEXT: Symbol { |
| 28 | # CHECK-NEXT: Name: qux | ||
| 29 | # CHECK-NEXT: Value: | ||
| 30 | # CHECK-NEXT: Size: | ||
| 31 | # CHECK-NEXT: Binding: Weak | ||
| 32 | # CHECK-NEXT: Type: | ||
| 33 | # CHECK-NEXT: Other: | ||
| 34 | # CHECK-NEXT: Section: Undefined | ||
| 35 | # CHECK-NEXT: } | ||
| 36 | # CHECK-NEXT: Symbol { | ||
| 28 | # CHECK-NEXT: Name: bar | 37 | # CHECK-NEXT: Name: bar |
| 29 | # CHECK-NEXT: Value: | 38 | # CHECK-NEXT: Value: |
| 30 | # CHECK-NEXT: Size: | 39 | # CHECK-NEXT: Size: |
| ... | @@ -51,15 +60,6 @@ | ... | @@ -51,15 +60,6 @@ |
| 51 | # CHECK-NEXT: Other: | 60 | # CHECK-NEXT: Other: |
| 52 | # CHECK-NEXT: Section: .text | 61 | # CHECK-NEXT: Section: .text |
| 53 | # CHECK-NEXT: } | 62 | # CHECK-NEXT: } |
| 54 | # CHECK-NEXT: Symbol { | ||
| 55 | # CHECK-NEXT: Name: qux | ||
| 56 | # CHECK-NEXT: Value: | ||
| 57 | # CHECK-NEXT: Size: | ||
| 58 | # CHECK-NEXT: Binding: Weak | ||
| 59 | # CHECK-NEXT: Type: | ||
| 60 | # CHECK-NEXT: Other: | ||
| 61 | # CHECK-NEXT: Section: Undefined | ||
| 62 | # CHECK-NEXT: } | ||
| 63 | # CHECK-NEXT: ] | 63 | # CHECK-NEXT: ] |
| 64 | 64 | ||
| 65 | # CHECK-NOT: NEEDED | 65 | # CHECK-NOT: NEEDED |
| ... | @@ -68,64 +68,12 @@ | ... | @@ -68,64 +68,12 @@ |
| 68 | 68 | ||
| 69 | # Test with %t.o at the end too. | 69 | # Test with %t.o at the end too. |
| 70 | # RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t --as-needed %t2.so %t3.so %t4.so %t.o | 70 | # RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t --as-needed %t2.so %t3.so %t4.so %t.o |
| 71 | # RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck --check-prefix=CHECK2 %s | 71 | # RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck --check-prefix=CHECK %s |
| 72 | |||
| 73 | # CHECK2: DynamicSymbols [ | ||
| 74 | # CHECK2-NEXT: Symbol { | ||
| 75 | # CHECK2-NEXT: Name: | ||
| 76 | # CHECK2-NEXT: Value: | ||
| 77 | # CHECK2-NEXT: Size: | ||
| 78 | # CHECK2-NEXT: Binding: Local | ||
| 79 | # CHECK2-NEXT: Type: | ||
| 80 | # CHECK2-NEXT: Other: | ||
| 81 | # CHECK2-NEXT: Section: Undefined (0x0) | ||
| 82 | # CHECK2-NEXT: } | ||
| 83 | # CHECK2-NEXT: Symbol { | ||
| 84 | # CHECK2-NEXT: Name: bar | ||
| 85 | # CHECK2-NEXT: Value: | ||
| 86 | # CHECK2-NEXT: Size: | ||
| 87 | # CHECK2-NEXT: Binding: Global | ||
| 88 | # CHECK2-NEXT: Type: | ||
| 89 | # CHECK2-NEXT: Other: | ||
| 90 | # CHECK2-NEXT: Section: .text | ||
| 91 | # CHECK2-NEXT: } | ||
| 92 | # CHECK2-NEXT: Symbol { | ||
| 93 | # CHECK2-NEXT: Name: baz | ||
| 94 | # CHECK2-NEXT: Value: | ||
| 95 | # CHECK2-NEXT: Size: | ||
| 96 | # CHECK2-NEXT: Binding: Global | ||
| 97 | # CHECK2-NEXT: Type: | ||
| 98 | # CHECK2-NEXT: Other: | ||
| 99 | # CHECK2-NEXT: Section: Undefined | ||
| 100 | # CHECK2-NEXT: } | ||
| 101 | # CHECK2-NEXT: Symbol { | ||
| 102 | # CHECK2-NEXT: Name: qux | ||
| 103 | # CHECK2-NEXT: Value: | ||
| 104 | # CHECK2-NEXT: Size: | ||
| 105 | # CHECK2-NEXT: Binding: Weak | ||
| 106 | # CHECK2-NEXT: Type: | ||
| 107 | # CHECK2-NEXT: Other: | ||
| 108 | # CHECK2-NEXT: Section: Undefined | ||
| 109 | # CHECK2-NEXT: } | ||
| 110 | # CHECK2-NEXT: Symbol { | ||
| 111 | # CHECK2-NEXT: Name: foo | ||
| 112 | # CHECK2-NEXT: Value: | ||
| 113 | # CHECK2-NEXT: Size: | ||
| 114 | # CHECK2-NEXT: Binding: Global | ||
| 115 | # CHECK2-NEXT: Type: | ||
| 116 | # CHECK2-NEXT: Other: | ||
| 117 | # CHECK2-NEXT: Section: .text | ||
| 118 | # CHECK2-NEXT: } | ||
| 119 | # CHECK2-NEXT: ] | ||
| 120 | |||
| 121 | # CHECK2-NOT: NEEDED | ||
| 122 | # CHECK2: NEEDED Shared library: [{{.*}}3.so] | ||
| 123 | # CHECK2-NOT: NEEDED | ||
| 124 | 72 | ||
| 125 | .section .text.foo, "ax" | 73 | .section .text.foo, "ax" |
| 126 | .globl foo | 74 | .globl foo |
| 127 | foo: | 75 | foo: |
| 128 | call bar | 76 | .long bar - . |
| 129 | 77 | ||
| 130 | .section .text.bar, "ax" | 78 | .section .text.bar, "ax" |
| 131 | .globl bar | 79 | .globl bar |
| ... | @@ -136,9 +84,9 @@ ret | ... | @@ -136,9 +84,9 @@ ret |
| 136 | .globl _start | 84 | .globl _start |
| 137 | .weak qux | 85 | .weak qux |
| 138 | _start: | 86 | _start: |
| 139 | call baz | 87 | .long baz - . |
| 140 | call qux | 88 | .long qux - . |
| 141 | ret | 89 | ret |
| 142 | 90 | ||
| 143 | .section .text.unused, "ax" | 91 | .section .text.unused, "ax" |
| 144 | call bar2 | 92 | .long bar2 - . |
deps/lld/test/ELF/gdb-index-dup-types.s deleted-60| ... | @@ -1,60 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: ld.lld --gdb-index %t.o -o %t | ||
| 4 | # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s | ||
| 5 | |||
| 6 | ## Testcase is based on output produced by gcc version 5.4.1 20160904 | ||
| 7 | ## it has duplicate entries in .debug_gnu_pubtypes which seems to be | ||
| 8 | ## compiler bug. In that case it is useless to have them in .gdb_index | ||
| 9 | ## and we filter such entries out to reduce size of .gdb_index. | ||
| 10 | |||
| 11 | ## CHECK: Constant pool offset = {{.*}}, has 1 CU vectors: | ||
| 12 | ## CHECK-NOT: 0(0x0): 0x90000000 0x90000000 | ||
| 13 | |||
| 14 | .section .debug_abbrev,"",@progbits | ||
| 15 | .byte 1 # Abbreviation Code | ||
| 16 | .byte 17 # DW_TAG_compile_unit | ||
| 17 | .byte 0 # DW_CHILDREN_no | ||
| 18 | .byte 16 # DW_AT_stmt_list | ||
| 19 | .byte 23 # DW_FORM_sec_offset | ||
| 20 | .ascii "\260B" # DW_AT_GNU_dwo_name | ||
| 21 | .byte 14 # DW_FORM_strp | ||
| 22 | .byte 27 # DW_AT_comp_dir | ||
| 23 | .byte 14 # DW_FORM_strp | ||
| 24 | .ascii "\264B" # DW_AT_GNU_pubnames | ||
| 25 | .byte 25 # DW_FORM_flag_present | ||
| 26 | .ascii "\261B" # DW_AT_GNU_dwo_id | ||
| 27 | .byte 7 # DW_FORM_data8 | ||
| 28 | .ascii "\263B" # DW_AT_GNU_addr_base | ||
| 29 | .byte 23 # DW_FORM_sec_offset | ||
| 30 | .byte 0 # EOM(1) | ||
| 31 | .byte 0 # EOM(2) | ||
| 32 | .byte 0 # EOM(3) | ||
| 33 | |||
| 34 | .section .debug_info,"",@progbits | ||
| 35 | .Lcu_begin0: | ||
| 36 | .long 32 # Length of Unit | ||
| 37 | .short 4 # DWARF version number | ||
| 38 | .long .debug_abbrev # Offset Into Abbrev. Section | ||
| 39 | .byte 8 # Address Size (in bytes) | ||
| 40 | .byte 1 # Abbrev [1] 0xb:0x19 DW_TAG_compile_unit | ||
| 41 | .long 0 # DW_AT_stmt_list | ||
| 42 | .long 0 # DW_AT_GNU_dwo_name | ||
| 43 | .long 0 # DW_AT_comp_dir | ||
| 44 | .quad 0 # DW_AT_GNU_dwo_id | ||
| 45 | .long 0 # DW_AT_GNU_addr_base | ||
| 46 | |||
| 47 | .section .debug_gnu_pubtypes,"",@progbits | ||
| 48 | .long .LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info | ||
| 49 | .LpubTypes_begin0: | ||
| 50 | .short 2 # DWARF Version | ||
| 51 | .long .Lcu_begin0 # Offset of Compilation Unit Info | ||
| 52 | .long 36 # Compilation Unit Length | ||
| 53 | .long 36 # DIE offset | ||
| 54 | .byte 144 # Kind: TYPE, STATIC | ||
| 55 | .asciz "int" # External Name | ||
| 56 | .long 36 # DIE offset | ||
| 57 | .byte 144 # Kind: TYPE, STATIC | ||
| 58 | .asciz "int" # External Name | ||
| 59 | .long 0 # End Mark | ||
| 60 | .LpubTypes_end0: | ||
deps/lld/test/ELF/gdb-index-noranges.s+1-1| ... | @@ -10,7 +10,7 @@ | ... | @@ -10,7 +10,7 @@ |
| 10 | ## | 10 | ## |
| 11 | ## Debug information does not contain any address ranges. | 11 | ## Debug information does not contain any address ranges. |
| 12 | ## We crashed in that case. Check we don't. | 12 | ## We crashed in that case. Check we don't. |
| 13 | # RUN: ld.lld --gdb-index %t1.o -o %t | 13 | # RUN: ld.lld --gdb-index %t1.o -o /dev/null |
| 14 | 14 | ||
| 15 | .section .debug_str,"MS",@progbits,1 | 15 | .section .debug_str,"MS",@progbits,1 |
| 16 | .Lskel_string0: | 16 | .Lskel_string0: |
deps/lld/test/ELF/gdb-index-tls.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: ld.lld --gdb-index -shared %t.o -o %t | 3 | # RUN: ld.lld --gdb-index -shared %t.o -o /dev/null |
| 4 | 4 | ||
| 5 | # This used to fail trying to compute R_X86_64_DTPOFF64 | 5 | # This used to fail trying to compute R_X86_64_DTPOFF64 |
| 6 | 6 |
deps/lld/test/ELF/gdb-index.s+34-22| ... | @@ -1,9 +1,19 @@ | ... | @@ -1,9 +1,19 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86, zlib |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index.s -o %t2.o |
| 4 | # RUN: ld.lld --gdb-index %t1.o %t2.o -o %t | 4 | # RUN: ld.lld --gdb-index %t1.o %t2.o -o %t |
| 5 | # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s | 5 | |
| 6 | # RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM | ||
| 7 | # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s --check-prefix=DWARF | ||
| 8 | # RUN: llvm-readelf -sections %t | FileCheck %s --check-prefix=SECTION | ||
| 9 | |||
| 10 | # RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-pc-linux \ | ||
| 11 | # RUN: %p/Inputs/gdb-index.s -o %t2.o | ||
| 12 | # RUN: ld.lld --gdb-index %t1.o %t2.o -o %t | ||
| 13 | |||
| 6 | # RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM | 14 | # RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM |
| 15 | # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s --check-prefix=DWARF | ||
| 16 | # RUN: llvm-readelf -sections %t | FileCheck %s --check-prefix=SECTION | ||
| 7 | 17 | ||
| 8 | # DISASM: Disassembly of section .text: | 18 | # DISASM: Disassembly of section .text: |
| 9 | # DISASM: entrypoint: | 19 | # DISASM: entrypoint: |
| ... | @@ -11,29 +21,31 @@ | ... | @@ -11,29 +21,31 @@ |
| 11 | # DISASM-CHECK: 201001: cc int3 | 21 | # DISASM-CHECK: 201001: cc int3 |
| 12 | # DISASM-CHECK: 201002: cc int3 | 22 | # DISASM-CHECK: 201002: cc int3 |
| 13 | # DISASM-CHECK: 201003: cc int3 | 23 | # DISASM-CHECK: 201003: cc int3 |
| 14 | # DISASM: main2: | 24 | # DISASM: aaaaaaaaaaaaaaaa: |
| 15 | # DISASM-CHECK: 201004: 90 nop | 25 | # DISASM-CHECK: 201004: 90 nop |
| 16 | # DISASM-CHECK: 201005: 90 nop | 26 | # DISASM-CHECK: 201005: 90 nop |
| 17 | 27 | ||
| 18 | # CHECK: .gnu_index contents: | 28 | # DWARF: .gnu_index contents: |
| 19 | # CHECK-NEXT: Version = 7 | 29 | # DWARF-NEXT: Version = 7 |
| 20 | # CHECK: CU list offset = 0x18, has 2 entries: | 30 | # DWARF: CU list offset = 0x18, has 2 entries: |
| 21 | # CHECK-NEXT: 0: Offset = 0x0, Length = 0x34 | 31 | # DWARF-NEXT: 0: Offset = 0x0, Length = 0x34 |
| 22 | # CHECK-NEXT: 1: Offset = 0x34, Length = 0x34 | 32 | # DWARF-NEXT: 1: Offset = 0x34, Length = 0x34 |
| 23 | # CHECK: Address area offset = 0x38, has 2 entries: | 33 | # DWARF: Address area offset = 0x38, has 2 entries: |
| 24 | # CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 | 34 | # DWARF-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 |
| 25 | # CHECK-NEXT: Low/High address = [0x201004, 0x201006) (Size: 0x2), CU id = 1 | 35 | # DWARF-NEXT: Low/High address = [0x201004, 0x201006) (Size: 0x2), CU id = 1 |
| 26 | # CHECK: Symbol table offset = 0x60, size = 1024, filled slots: | 36 | # DWARF: Symbol table offset = 0x60, size = 1024, filled slots: |
| 27 | # CHECK-NEXT: 754: Name offset = 0x27, CU vector offset = 0x8 | 37 | # DWARF-NEXT: 512: Name offset = 0x1c, CU vector offset = 0x0 |
| 28 | # CHECK-NEXT:	 String name: int, CU vector index: 1 | 38 | # DWARF-NEXT: String name: aaaaaaaaaaaaaaaa, CU vector index: 0 |
| 29 | # CHECK-NEXT: 822: Name offset = 0x1c, CU vector offset = 0x0 | 39 | # DWARF-NEXT: 754: Name offset = 0x38, CU vector offset = 0x10 |
| 30 | # CHECK-NEXT:	 String name: entrypoint, CU vector index: 0 | 40 | # DWARF-NEXT: String name: int, CU vector index: 2 |
| 31 | # CHECK-NEXT: 956: Name offset = 0x2b, CU vector offset = 0x14 | 41 | # DWARF-NEXT: 822: Name offset = 0x2d, CU vector offset = 0x8 |
| 32 | # CHECK-NEXT: String name: main2, CU vector index: 2 | 42 | # DWARF-NEXT: String name: entrypoint, CU vector index: 1 |
| 33 | # CHECK: Constant pool offset = 0x2060, has 3 CU vectors: | 43 | # DWARF: Constant pool offset = 0x2060, has 3 CU vectors: |
| 34 | # CHECK-NEXT: 0(0x0): 0x30000000 | 44 | # DWARF-NEXT: 0(0x0): 0x30000001 |
| 35 | # CHECK-NEXT: 1(0x8): 0x90000000 0x90000001 | 45 | # DWARF-NEXT: 1(0x8): 0x30000000 |
| 36 | # CHECK-NEXT: 2(0x14): 0x30000001 | 46 | # DWARF-NEXT: 2(0x10): 0x90000000 0x90000001 |
| 47 | |||
| 48 | # SECTION-NOT: debug_gnu_pubnames | ||
| 37 | 49 | ||
| 38 | # RUN: ld.lld --gdb-index --no-gdb-index %t1.o %t2.o -o %t2 | 50 | # RUN: ld.lld --gdb-index --no-gdb-index %t1.o %t2.o -o %t2 |
| 39 | # RUN: llvm-readobj -sections %t2 | FileCheck -check-prefix=NOGDB %s | 51 | # RUN: llvm-readobj -sections %t2 | FileCheck -check-prefix=NOGDB %s |
deps/lld/test/ELF/global-offset-table-position-aarch64.s+3-3| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | 3 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 |
| 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | // REQUIRES: aarch64 | ||
| 5 | .globl a | 5 | .globl a |
| 6 | .type a,@object | 6 | .type a,@object |
| 7 | .comm a,4,4 | 7 | .comm a,4,4 |
| ... | @@ -20,11 +20,11 @@ _start: | ... | @@ -20,11 +20,11 @@ _start: |
| 20 | .long _GLOBAL_OFFSET_TABLE_ - . | 20 | .long _GLOBAL_OFFSET_TABLE_ - . |
| 21 | 21 | ||
| 22 | // CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11) | 22 | // CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11) |
| 23 | // CHECK-NEXT: Value: 0x30090 | 23 | // CHECK-NEXT: Value: 0x20008 |
| 24 | // CHECK-NEXT: Size: 0 | 24 | // CHECK-NEXT: Size: 0 |
| 25 | // CHECK-NEXT: Binding: Local (0x0) | 25 | // CHECK-NEXT: Binding: Local (0x0) |
| 26 | // CHECK-NEXT: Type: None (0x0) | 26 | // CHECK-NEXT: Type: None (0x0) |
| 27 | // CHECK-NEXT: Other [ (0x2) | 27 | // CHECK-NEXT: Other [ (0x2) |
| 28 | // CHECK-NEXT: STV_HIDDEN (0x2) | 28 | // CHECK-NEXT: STV_HIDDEN (0x2) |
| 29 | // CHECK-NEXT: ] | 29 | // CHECK-NEXT: ] |
| 30 | // CHECK-NEXT: Section: .got | 30 | // CHECK-NEXT: Section: .got.plt |
deps/lld/test/ELF/global-offset-table-position-arm.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: arm | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | 3 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 |
| 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | // REQUIRES: arm | ||
| 5 | 5 | ||
| 6 | // The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got | 6 | // The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got |
| 7 | .globl a | 7 | .globl a |
deps/lld/test/ELF/global-offset-table-position-i386.s+5-4| ... | @@ -1,9 +1,10 @@ | ... | @@ -1,9 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | 3 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 |
| 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | // The X86 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section. | 6 | // The X86 _GLOBAL_OFFSET_TABLE_ is defined at the start of the .got.plt |
| 7 | // section. | ||
| 7 | .globl a | 8 | .globl a |
| 8 | .type a,@object | 9 | .type a,@object |
| 9 | .comm a,4,4 | 10 | .comm a,4,4 |
| ... | @@ -21,11 +22,11 @@ addl $_GLOBAL_OFFSET_TABLE_, %eax | ... | @@ -21,11 +22,11 @@ addl $_GLOBAL_OFFSET_TABLE_, %eax |
| 21 | calll f@PLT | 22 | calll f@PLT |
| 22 | 23 | ||
| 23 | // CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1) | 24 | // CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1) |
| 24 | // CHECK-NEXT: Value: 0x306C | 25 | // CHECK-NEXT: Value: 0x2000 |
| 25 | // CHECK-NEXT: Size: 0 | 26 | // CHECK-NEXT: Size: 0 |
| 26 | // CHECK-NEXT: Binding: Local (0x0) | 27 | // CHECK-NEXT: Binding: Local (0x0) |
| 27 | // CHECK-NEXT: Type: None (0x0) | 28 | // CHECK-NEXT: Type: None (0x0) |
| 28 | // CHECK-NEXT: Other [ (0x2) | 29 | // CHECK-NEXT: Other [ (0x2) |
| 29 | // CHECK-NEXT: STV_HIDDEN (0x2) | 30 | // CHECK-NEXT: STV_HIDDEN (0x2) |
| 30 | // CHECK-NEXT: ] | 31 | // CHECK-NEXT: ] |
| 31 | // CHECK-NEXT: Section: .got (0xA) | 32 | // CHECK-NEXT: Section: .got.plt |
deps/lld/test/ELF/global-offset-table-position-mips.s+1-2| ... | @@ -1,9 +1,8 @@ | ... | @@ -1,9 +1,8 @@ |
| 1 | // REQUIRES: mips | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t |
| 2 | // RUN: ld.lld -shared %t -o %t2 | 3 | // RUN: ld.lld -shared %t -o %t2 |
| 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | 5 | ||
| 5 | // REQUIRES: mips | ||
| 6 | |||
| 7 | // The Mips _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got | 6 | // The Mips _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got |
| 8 | 7 | ||
| 9 | .globl a | 8 | .globl a |
deps/lld/test/ELF/global-offset-table-position.s+5-4| ... | @@ -1,9 +1,10 @@ | ... | @@ -1,9 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | 3 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 |
| 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | // The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section. | 6 | // The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the start of the .got.plt |
| 7 | // section. | ||
| 7 | .globl a | 8 | .globl a |
| 8 | .type a,@object | 9 | .type a,@object |
| 9 | .comm a,4,4 | 10 | .comm a,4,4 |
| ... | @@ -21,11 +22,11 @@ callq	f@PLT | ... | @@ -21,11 +22,11 @@ callq	f@PLT |
| 21 | .long _GLOBAL_OFFSET_TABLE_ - . | 22 | .long _GLOBAL_OFFSET_TABLE_ - . |
| 22 | 23 | ||
| 23 | // CHECK: Name: _GLOBAL_OFFSET_TABLE_ | 24 | // CHECK: Name: _GLOBAL_OFFSET_TABLE_ |
| 24 | // CHECK-NEXT: Value: 0x30D8 | 25 | // CHECK-NEXT: Value: 0x2008 |
| 25 | // CHECK-NEXT: Size: 0 | 26 | // CHECK-NEXT: Size: 0 |
| 26 | // CHECK-NEXT: Binding: Local | 27 | // CHECK-NEXT: Binding: Local |
| 27 | // CHECK-NEXT: Type: None (0x0) | 28 | // CHECK-NEXT: Type: None (0x0) |
| 28 | // CHECK-NEXT: Other [ | 29 | // CHECK-NEXT: Other [ |
| 29 | // CHECK-NEXT: STV_HIDDEN | 30 | // CHECK-NEXT: STV_HIDDEN |
| 30 | // CHECK-NEXT: ] | 31 | // CHECK-NEXT: ] |
| 31 | // CHECK-NEXT: Section: .got | 32 | // CHECK-NEXT: Section: .got.plt |
deps/lld/test/ELF/global_offset_table.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 | 3 | // RUN: ld.lld %t -o /dev/null |
| 3 | .global _start | 4 | .global _start |
| 4 | _start: | 5 | _start: |
| 5 | .long _GLOBAL_OFFSET_TABLE_ | 6 | .long _GLOBAL_OFFSET_TABLE_ |
deps/lld/test/ELF/global_offset_table_shared.s+3-2| ... | @@ -1,14 +1,15 @@ | ... | @@ -1,14 +1,15 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 | 3 | // RUN: ld.lld --hash-style=sysv -shared %t -o %t2 |
| 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | .long _GLOBAL_OFFSET_TABLE_ - . | 5 | .long _GLOBAL_OFFSET_TABLE_ - . |
| 5 | 6 | ||
| 6 | // CHECK: Name: _GLOBAL_OFFSET_TABLE_ | 7 | // CHECK: Name: _GLOBAL_OFFSET_TABLE_ |
| 7 | // CHECK-NEXT: Value: 0x2060 | 8 | // CHECK-NEXT: Value: 0x2000 |
| 8 | // CHECK-NEXT: Size: 0 | 9 | // CHECK-NEXT: Size: 0 |
| 9 | // CHECK-NEXT: Binding: Local | 10 | // CHECK-NEXT: Binding: Local |
| 10 | // CHECK-NEXT: Type: None | 11 | // CHECK-NEXT: Type: None |
| 11 | // CHECK-NEXT: Other [ (0x2) | 12 | // CHECK-NEXT: Other [ (0x2) |
| 12 | // CHECK-NEXT: STV_HIDDEN (0x2) | 13 | // CHECK-NEXT: STV_HIDDEN (0x2) |
| 13 | // CHECK-NEXT: ] | 14 | // CHECK-NEXT: ] |
| 14 | // CHECK-NEXT: Section: .got | 15 | // CHECK-NEXT: Section: .got.plt |
deps/lld/test/ELF/gnu-hash-table.s+16-8| ... | @@ -4,30 +4,36 @@ | ... | @@ -4,30 +4,36 @@ |
| 4 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %te.s -o %te-i386.o | 4 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %te.s -o %te-i386.o |
| 5 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t-i386.o | 5 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t-i386.o |
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t-x86_64.o | 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t-x86_64.o |
| 7 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %s -o %t-ppc64.o | 7 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t-ppc64le.o |
| 8 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t-ppc64.o | ||
| 8 | 9 | ||
| 9 | # RUN: echo ".global zed; zed:" > %t2.s | 10 | # RUN: echo ".global zed; zed:" > %t2.s |
| 10 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t2.s -o %t2-i386.o | 11 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t2.s -o %t2-i386.o |
| 11 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2-x86_64.o | 12 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2-x86_64.o |
| 12 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t2.s -o %t2-ppc64.o | 13 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t2.s -o %t2-ppc64le.o |
| 14 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %t2.s -o %t2-ppc64.o | ||
| 13 | 15 | ||
| 14 | # RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a | 16 | # RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a |
| 15 | # RUN: llvm-ar rc %t2-i386.a %t2-i386.o | 17 | # RUN: llvm-ar rc %t2-i386.a %t2-i386.o |
| 16 | # RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o | 18 | # RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o |
| 19 | # RUN: llvm-ar rc %t2-ppc64le.a %t2-ppc64le.o | ||
| 17 | # RUN: llvm-ar rc %t2-ppc64.a %t2-ppc64.o | 20 | # RUN: llvm-ar rc %t2-ppc64.a %t2-ppc64.o |
| 18 | 21 | ||
| 19 | # RUN: echo ".global xyz; xyz:" > %t3.s | 22 | # RUN: echo ".global xyz; xyz:" > %t3.s |
| 20 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t3.s -o %t3-i386.o | 23 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t3.s -o %t3-i386.o |
| 21 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t3.s -o %t3-x86_64.o | 24 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t3.s -o %t3-x86_64.o |
| 22 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t3.s -o %t3-ppc64.o | 25 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t3.s -o %t3-ppc64le.o |
| 26 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %t3.s -o %t3-ppc64.o | ||
| 23 | 27 | ||
| 24 | # RUN: ld.lld -shared %t3-i386.o -o %t3-i386.so | 28 | # RUN: ld.lld -shared %t3-i386.o -o %t3-i386.so |
| 25 | # RUN: ld.lld -shared %t3-x86_64.o -o %t3-x86_64.so | 29 | # RUN: ld.lld -shared %t3-x86_64.o -o %t3-x86_64.so |
| 30 | # RUN: ld.lld -shared %t3-ppc64le.o -o %t3-ppc64le.so | ||
| 26 | # RUN: ld.lld -shared %t3-ppc64.o -o %t3-ppc64.so | 31 | # RUN: ld.lld -shared %t3-ppc64.o -o %t3-ppc64.so |
| 27 | 32 | ||
| 28 | # RUN: ld.lld -shared --hash-style=gnu -o %te-i386.so %te-i386.o | 33 | # RUN: ld.lld -shared --hash-style=gnu -o %te-i386.so %te-i386.o |
| 29 | # RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o %t2-i386.a %t3-i386.so | 34 | # RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o %t2-i386.a %t3-i386.so |
| 30 | # RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o %t2-x86_64.a %t3-x86_64.so | 35 | # RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o %t2-x86_64.a %t3-x86_64.so |
| 36 | # RUN: ld.lld -shared --hash-style both -o %t-ppc64le.so %t-ppc64le.o %t2-ppc64le.a %t3-ppc64le.so | ||
| 31 | # RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o %t2-ppc64.a %t3-ppc64.so | 37 | # RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o %t2-ppc64.a %t3-ppc64.so |
| 32 | 38 | ||
| 33 | # RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \ | 39 | # RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \ |
| ... | @@ -36,6 +42,8 @@ | ... | @@ -36,6 +42,8 @@ |
| 36 | # RUN: | FileCheck %s -check-prefix=I386 | 42 | # RUN: | FileCheck %s -check-prefix=I386 |
| 37 | # RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-x86_64.so \ | 43 | # RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-x86_64.so \ |
| 38 | # RUN: | FileCheck %s -check-prefix=X86_64 | 44 | # RUN: | FileCheck %s -check-prefix=X86_64 |
| 45 | # RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64le.so \ | ||
| 46 | # RUN: | FileCheck %s -check-prefix=PPC64 | ||
| 39 | # RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64.so \ | 47 | # RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64.so \ |
| 40 | # RUN: | FileCheck %s -check-prefix=PPC64 | 48 | # RUN: | FileCheck %s -check-prefix=PPC64 |
| 41 | 49 | ||
| ... | @@ -51,12 +59,12 @@ | ... | @@ -51,12 +59,12 @@ |
| 51 | # EMPTY-NEXT: } | 59 | # EMPTY-NEXT: } |
| 52 | # EMPTY-NEXT: ] | 60 | # EMPTY-NEXT: ] |
| 53 | # EMPTY: GnuHashTable { | 61 | # EMPTY: GnuHashTable { |
| 54 | # EMPTY-NEXT: Num Buckets: 0 | 62 | # EMPTY-NEXT: Num Buckets: 1 |
| 55 | # EMPTY-NEXT: First Hashed Symbol Index: 2 | 63 | # EMPTY-NEXT: First Hashed Symbol Index: 2 |
| 56 | # EMPTY-NEXT: Num Mask Words: 1 | 64 | # EMPTY-NEXT: Num Mask Words: 1 |
| 57 | # EMPTY-NEXT: Shift Count: 5 | 65 | # EMPTY-NEXT: Shift Count: 6 |
| 58 | # EMPTY-NEXT: Bloom Filter: [0x0] | 66 | # EMPTY-NEXT: Bloom Filter: [0x0] |
| 59 | # EMPTY-NEXT: Buckets: [] | 67 | # EMPTY-NEXT: Buckets: [0] |
| 60 | # EMPTY-NEXT: Values: [] | 68 | # EMPTY-NEXT: Values: [] |
| 61 | # EMPTY-NEXT: } | 69 | # EMPTY-NEXT: } |
| 62 | 70 | ||
| ... | @@ -113,8 +121,8 @@ | ... | @@ -113,8 +121,8 @@ |
| 113 | # I386-NEXT: Num Buckets: 1 | 121 | # I386-NEXT: Num Buckets: 1 |
| 114 | # I386-NEXT: First Hashed Symbol Index: 4 | 122 | # I386-NEXT: First Hashed Symbol Index: 4 |
| 115 | # I386-NEXT: Num Mask Words: 1 | 123 | # I386-NEXT: Num Mask Words: 1 |
| 116 | # I386-NEXT: Shift Count: 5 | 124 | # I386-NEXT: Shift Count: 6 |
| 117 | # I386-NEXT: Bloom Filter: [0x14000220] | 125 | # I386-NEXT: Bloom Filter: [0x4004204] |
| 118 | # I386-NEXT: Buckets: [4] | 126 | # I386-NEXT: Buckets: [4] |
| 119 | # I386-NEXT: Values: [0xB8860BA, 0xB887389] | 127 | # I386-NEXT: Values: [0xB8860BA, 0xB887389] |
| 120 | # I386-NEXT: } | 128 | # I386-NEXT: } |
deps/lld/test/ELF/gnu-ifunc-dynsym.s+5-1| ... | @@ -1,7 +1,11 @@ | ... | @@ -1,7 +1,11 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | |||
| 2 | // RUN: ld.lld -static -export-dynamic %t.o -o %tout | 4 | // RUN: ld.lld -static -export-dynamic %t.o -o %tout |
| 3 | // RUN: llvm-nm -U %tout | FileCheck %s | 5 | // RUN: llvm-nm -U %tout | FileCheck %s |
| 4 | // REQUIRES: x86 | 6 | |
| 7 | // RUN: ld.lld -export-dynamic %t.o -o %tout | ||
| 8 | // RUN: llvm-nm -U %tout | FileCheck %s | ||
| 5 | 9 | ||
| 6 | // CHECK: __rela_iplt_end | 10 | // CHECK: __rela_iplt_end |
| 7 | // CHECK: __rela_iplt_start | 11 | // CHECK: __rela_iplt_start |
deps/lld/test/ELF/gnu-ifunc-i386.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM | 4 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 4 | // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s | 5 | // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // CHECK: Sections [ | 7 | // CHECK: Sections [ |
| 8 | // CHECK: Section { | 8 | // CHECK: Section { |
deps/lld/test/ELF/gnu-ifunc-nosym-i386.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-readobj -symbols %tout | FileCheck %s | 4 | // RUN: llvm-readobj -symbols %tout | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | // Check that no __rel_iplt_end/__rel_iplt_start | 6 | // Check that no __rel_iplt_end/__rel_iplt_start |
| 7 | // appear in symtab if there is no references to them. | 7 | // appear in symtab if there is no references to them. |
deps/lld/test/ELF/gnu-ifunc-nosym.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-readobj -symbols %tout | FileCheck %s | 4 | // RUN: llvm-readobj -symbols %tout | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | // Check that no __rela_iplt_end/__rela_iplt_start | 6 | // Check that no __rela_iplt_end/__rela_iplt_start |
| 7 | // appear in symtab if there is no references to them. | 7 | // appear in symtab if there is no references to them. |
deps/lld/test/ELF/gnu-ifunc-plt-i386.s+5-5| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o |
| 2 | // RUN: ld.lld %t1.o --shared -o %t.so | 3 | // RUN: ld.lld %t1.o --shared -o %t.so |
| 3 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | 4 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM | 6 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 6 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT | 7 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT |
| 7 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s | 8 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s |
| 8 | // REQUIRES: x86 | ||
| 9 | 9 | ||
| 10 | // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt | 10 | // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt |
| 11 | // CHECK: Relocations [ | 11 | // CHECK: Relocations [ |
| ... | @@ -70,7 +70,7 @@ bar: | ... | @@ -70,7 +70,7 @@ bar: |
| 70 | 70 | ||
| 71 | .globl _start | 71 | .globl _start |
| 72 | _start: | 72 | _start: |
| 73 | call foo | 73 | call foo@plt |
| 74 | call bar | 74 | call bar@plt |
| 75 | call bar2 | 75 | call bar2@plt |
| 76 | call zed2 | 76 | call zed2@plt |
deps/lld/test/ELF/gnu-ifunc-plt.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o |
| 2 | // RUN: ld.lld %t1.o --shared -o %t.so | 3 | // RUN: ld.lld %t1.o --shared -o %t.so |
| 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 %s -o %t.o |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM | 6 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 6 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT | 7 | // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT |
| 7 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s | 8 | // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s |
| 8 | // REQUIRES: x86 | ||
| 9 | 9 | ||
| 10 | // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt | 10 | // Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt |
| 11 | // CHECK: Relocations [ | 11 | // CHECK: Relocations [ |
deps/lld/test/ELF/gnu-ifunc-relative.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-readobj -r -t %tout | FileCheck %s | 4 | // RUN: llvm-readobj -r -t %tout | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | .type foo STT_GNU_IFUNC | 6 | .type foo STT_GNU_IFUNC |
| 7 | .globl foo | 7 | .globl foo |
deps/lld/test/ELF/gnu-ifunc.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld -static %t.o -o %tout | 3 | // RUN: ld.lld -static %t.o -o %tout |
| 3 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM | 4 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM |
| 4 | // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s | 5 | // RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // CHECK: Sections [ | 7 | // CHECK: Sections [ |
| 8 | // CHECK: Section { | 8 | // CHECK: Section { |
deps/lld/test/ELF/gnu-unique.s+2| ... | @@ -3,6 +3,8 @@ | ... | @@ -3,6 +3,8 @@ |
| 3 | // | 3 | // |
| 4 | // RUN: ld.lld %t -shared -o %tout.so | 4 | // 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-symbols %tout.so | FileCheck -check-prefix=GNU %s |
| 6 | // RUN: ld.lld %t -shared -o %tout.so --gnu-unique | ||
| 7 | // RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=GNU %s | ||
| 6 | // | 8 | // |
| 7 | // RUN: ld.lld %t -shared -o %tout.so --no-gnu-unique | 9 | // RUN: ld.lld %t -shared -o %tout.so --no-gnu-unique |
| 8 | // RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=NO %s | 10 | // RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=NO %s |
deps/lld/test/ELF/gnustack.s+5| ... | @@ -1,10 +1,15 @@ | ... | @@ -1,10 +1,15 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 3 | |||
| 3 | # RUN: ld.lld %t1 -z execstack -o %t | 4 | # RUN: ld.lld %t1 -z execstack -o %t |
| 4 | # 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 |
| 6 | |||
| 5 | # RUN: ld.lld %t1 -o %t | 7 | # RUN: ld.lld %t1 -o %t |
| 6 | # 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 |
| 7 | 9 | ||
| 10 | # RUN: ld.lld %t1 -o %t -z noexecstack | ||
| 11 | # RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s | ||
| 12 | |||
| 8 | # RW: Type: PT_GNU_STACK | 13 | # RW: Type: PT_GNU_STACK |
| 9 | # RW-NEXT: Offset: 0x0 | 14 | # RW-NEXT: Offset: 0x0 |
| 10 | # RW-NEXT: VirtualAddress: 0x0 | 15 | # RW-NEXT: VirtualAddress: 0x0 |
deps/lld/test/ELF/got-aarch64.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so | 3 | // RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so |
| 3 | // RUN: llvm-readobj -s -r %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -s -r %t.so | FileCheck %s |
| 4 | // RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s | 5 | // RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s |
| 5 | // REQUIRES: aarch64 | ||
| 6 | 6 | ||
| 7 | // CHECK: Name: .got | 7 | // CHECK: Name: .got |
| 8 | // CHECK-NEXT: Type: SHT_PROGBITS | 8 | // CHECK-NEXT: Type: SHT_PROGBITS |
deps/lld/test/ELF/got-i386.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t | 3 | // RUN: ld.lld %t.o -o %t |
| 3 | // RUN: llvm-readobj -s -r -t %t | FileCheck %s | 4 | // RUN: llvm-readobj -s -r -t %t | FileCheck %s |
| 4 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s | 5 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // CHECK: Name: .got | 7 | // CHECK: Name: .got |
| 8 | // CHECK-NEXT: Type: SHT_PROGBITS | 8 | // CHECK-NEXT: Type: SHT_PROGBITS |
deps/lld/test/ELF/got-plt-header.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | // RUN: ld.lld %t.o -o %t.so -shared | 3 | // RUN: ld.lld %t.o -o %t.so -shared |
| 3 | // RUN: llvm-readobj -s -section-data %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -s -section-data %t.so | FileCheck %s |
deps/lld/test/ELF/got.s+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t | 5 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t |
| 5 | // RUN: llvm-readobj -s -r %t | FileCheck %s | 6 | // RUN: llvm-readobj -s -r %t | FileCheck %s |
| 6 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s | 7 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s |
| 7 | // REQUIRES: x86 | ||
| 8 | 8 | ||
| 9 | // CHECK: Name: .got | 9 | // CHECK: Name: .got |
| 10 | // CHECK-NEXT: Type: SHT_PROGBITS | 10 | // CHECK-NEXT: Type: SHT_PROGBITS |
deps/lld/test/ELF/got32-i386-pie-rw.s+2-2| ... | @@ -7,8 +7,8 @@ | ... | @@ -7,8 +7,8 @@ |
| 7 | 7 | ||
| 8 | # CHECK: .foobar PROGBITS 00001000 | 8 | # CHECK: .foobar PROGBITS 00001000 |
| 9 | # CHECK: .got PROGBITS [[GOT:[0-9a-z]*]] | 9 | # CHECK: .got PROGBITS [[GOT:[0-9a-z]*]] |
| 10 | # CHECK: [[GOT]] 00000008 R_386_RELATIVE | 10 | # CHECK-DAG: 00001002 00000008 R_386_RELATIVE |
| 11 | # CHECK: 00001002 00000008 R_386_RELATIVE | 11 | # CHECK-DAG: [[GOT]] 00000008 R_386_RELATIVE |
| 12 | foo: | 12 | foo: |
| 13 | 13 | ||
| 14 | .section .foobar, "awx" | 14 | .section .foobar, "awx" |
deps/lld/test/ELF/got32-i386.s+1-1| ... | @@ -20,4 +20,4 @@ _start: | ... | @@ -20,4 +20,4 @@ _start: |
| 20 | # CHECK: .got 00000004 0000000000012000 | 20 | # CHECK: .got 00000004 0000000000012000 |
| 21 | 21 | ||
| 22 | # RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR | 22 | # RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR |
| 23 | # ERR: error: can't create dynamic relocation R_386_GOT32 against symbol: foo in readonly segment; recompile object files with -fPIC | 23 | # ERR: error: can't create dynamic relocation R_386_GOT32 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
deps/lld/test/ELF/got32x-i386.s+5-5| ... | @@ -33,15 +33,15 @@ | ... | @@ -33,15 +33,15 @@ |
| 33 | 33 | ||
| 34 | ## 73728 == 0x12000 == ADDR(.got) | 34 | ## 73728 == 0x12000 == ADDR(.got) |
| 35 | # CHECK: _start: | 35 | # CHECK: _start: |
| 36 | # CHECK-NEXT: 11001: 8b 05 {{.*}} movl 73728, %eax | 36 | # CHECK-NEXT: 11001: 8b 05 {{.*}} movl 77824, %eax |
| 37 | # CHECK-NEXT: 11007: 8b 1d {{.*}} movl 73728, %ebx | 37 | # CHECK-NEXT: 11007: 8b 1d {{.*}} movl 77824, %ebx |
| 38 | # CHECK-NEXT: 1100d: 8b 80 {{.*}} movl -4(%eax), %eax | 38 | # CHECK-NEXT: 1100d: 8b 80 {{.*}} movl -4(%eax), %eax |
| 39 | # CHECK-NEXT: 11013: 8b 83 {{.*}} movl -4(%ebx), %eax | 39 | # CHECK-NEXT: 11013: 8b 83 {{.*}} movl -4(%ebx), %eax |
| 40 | # CHECK: Sections: | 40 | # CHECK: Sections: |
| 41 | # CHECK: Name Size Address | 41 | # CHECK: Name Size Address |
| 42 | # CHECK: .got 00000004 0000000000012000 | 42 | # CHECK: .got 00000004 0000000000013000 |
| 43 | 43 | ||
| 44 | # RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \ | 44 | # RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \ |
| 45 | # RUN: FileCheck %s --check-prefix=ERR | 45 | # RUN: FileCheck %s --check-prefix=ERR |
| 46 | # ERR: error: can't create dynamic relocation R_386_GOT32X against symbol: foo in readonly segment; recompile object files with -fPIC | 46 | # ERR: error: can't create dynamic relocation R_386_GOT32X against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 47 | # ERR: error: can't create dynamic relocation R_386_GOT32X against symbol: foo in readonly segment; recompile object files with -fPIC | 47 | # ERR: error: can't create dynamic relocation R_386_GOT32X against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
deps/lld/test/ELF/gotpcrelx.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux-gnu \ | 2 | // RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux-gnu \ |
| 2 | // RUN: %s -o %t.o | 3 | // RUN: %s -o %t.o |
| 3 | // RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELS %s | 4 | // RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELS %s |
deps/lld/test/ELF/help.s+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: ld.lld --help 2>&1 | FileCheck %s | 1 | # RUN: ld.lld --help 2>&1 | FileCheck %s |
| 2 | # CHECK: OPTIONS: | 2 | # CHECK: OPTIONS: |
| 3 | # CHECK: --output=<value> Path to file to write output | 3 | # CHECK: --output=<value> Alias for -o |
| 4 | # CHECK: --output <value> Path to file to write output | 4 | # CHECK: --output <value> Alias for -o |
| 5 | # CHECK: -o <path> Path to file to write output | 5 | # CHECK: -o <path> Path to file to write output |
deps/lld/test/ELF/hexagon.s created+31| ... | @@ -0,0 +1,31 @@ | ||
| 1 | # REQUIRES: hexagon | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %S/Inputs/hexagon.s -o %t2 | ||
| 4 | # RUN: ld.lld %t2 %t -o %t3 | ||
| 5 | # RUN: llvm-objdump -d %t3 | FileCheck %s | ||
| 6 | |||
| 7 | # Note: 69632 == 0x11000 | ||
| 8 | # R_HEX_32_6_X | ||
| 9 | # R_HEX_12_X | ||
| 10 | if (p0) r0 = ##_start | ||
| 11 | # CHECK: immext(#69632) | ||
| 12 | # CHECK: if (p0) r0 = ##69632 | ||
| 13 | |||
| 14 | # R_HEX_B15_PCREL | ||
| 15 | if (p0) jump:nt #_start | ||
| 16 | # CHECK: if (p0) jump:nt 0x11000 | ||
| 17 | |||
| 18 | # R_HEX_B32_PCREL_X | ||
| 19 | # R_HEX_B15_PCREL_X | ||
| 20 | if (p0) jump:nt ##_start | ||
| 21 | # CHECK: if (p0) jump:nt 0x11000 | ||
| 22 | |||
| 23 | # R_HEX_B22_PCREL | ||
| 24 | call #_start | ||
| 25 | # CHECK: call 0x11000 | ||
| 26 | |||
| 27 | # R_HEX_B32_PCREL_X | ||
| 28 | # R_HEX_B22_PCREL_X | ||
| 29 | call ##_start | ||
| 30 | # CHECK: immext(#4294967232) | ||
| 31 | # CHECK: call 0x11000 | ||
deps/lld/test/ELF/hidden-shared-err.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/hidden-shared-err.s -o %t2.o | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/hidden-shared-err2.s -o %t3.o | ||
| 6 | |||
| 7 | # RUN: ld.lld -shared -o %t2.so %t2.o | ||
| 8 | # RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s | ||
| 9 | # RUN: not ld.lld %t2.so %t.o -o %t 2>&1 | FileCheck %s | ||
| 10 | |||
| 11 | # RUN: not ld.lld %t.o %t3.o %t2.so -o %t 2>&1 | FileCheck %s | ||
| 12 | # RUN: not ld.lld %t3.o %t.o %t2.so -o %t 2>&1 | FileCheck %s | ||
| 13 | |||
| 14 | # CHECK: undefined symbol: foo | ||
| 15 | |||
| 16 | .global _start | ||
| 17 | _start: | ||
| 18 | .quad foo | ||
| 19 | .hidden foo | ||
deps/lld/test/ELF/i386-debug-noabs.test+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: yaml2obj %s -o %t.o | 3 | # RUN: yaml2obj %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -o %t.exe | 4 | # RUN: ld.lld %t.o -o /dev/null --entry 0 --fatal-warnings |
| 5 | 5 | ||
| 6 | ## This is for https://bugs.llvm.org//show_bug.cgi?id=34852. GCC 8.0 or | 6 | ## This is for https://bugs.llvm.org//show_bug.cgi?id=34852. GCC 8.0 or |
| 7 | ## earlier have a bug which creates non-absolute R_386_GOTPC relocations | 7 | ## earlier have a bug which creates non-absolute R_386_GOTPC relocations |
deps/lld/test/ELF/i386-got-and-copy.s+1| ... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
| 15 | # CHECK: Relocations [ | 15 | # CHECK: Relocations [ |
| 16 | # CHECK-NEXT: Section (4) .rel.dyn { | 16 | # CHECK-NEXT: Section (4) .rel.dyn { |
| 17 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_COPY foo | 17 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_COPY foo |
| 18 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_GLOB_DAT foo | ||
| 18 | # CHECK-NEXT: } | 19 | # CHECK-NEXT: } |
| 19 | # CHECK-NEXT: ] | 20 | # CHECK-NEXT: ] |
| 20 | 21 |
deps/lld/test/ELF/i386-got-value.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux | 2 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux |
| 2 | # RUN: ld.lld %t.o -o %t.so -shared | 3 | # RUN: ld.lld %t.o -o %t.so -shared |
| 3 | # RUN: llvm-readobj --relocations --sections --section-data %t.so | FileCheck %s | 4 | # RUN: llvm-readobj --relocations --sections --section-data %t.so | FileCheck %s |
deps/lld/test/ELF/i386-gotpc.s+11-3| ... | @@ -6,15 +6,23 @@ | ... | @@ -6,15 +6,23 @@ |
| 6 | 6 | ||
| 7 | movl $_GLOBAL_OFFSET_TABLE_, %eax | 7 | movl $_GLOBAL_OFFSET_TABLE_, %eax |
| 8 | 8 | ||
| 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 | |||
| 9 | // CHECK: Name: .got | 17 | // CHECK: Name: .got |
| 10 | // CHECK-NEXT: Type: SHT_PROGBITS | 18 | // CHECK-NEXT: Type: SHT_PROGBITS |
| 11 | // CHECK-NEXT: Flags [ | 19 | // CHECK-NEXT: Flags [ |
| 12 | // CHECK-NEXT: SHF_ALLOC | 20 | // CHECK-NEXT: SHF_ALLOC |
| 13 | // CHECK-NEXT: SHF_WRITE | 21 | // CHECK-NEXT: SHF_WRITE |
| 14 | // CHECK-NEXT: ] | 22 | // CHECK-NEXT: ] |
| 15 | // CHECK-NEXT: Address: 0x2030 | 23 | // CHECK-NEXT: Address: 0x3030 |
| 16 | 24 | ||
| 17 | // DISASM: Disassembly of section .text: | 25 | // DISASM: Disassembly of section .text: |
| 18 | // DISASM-NEXT: .text: | 26 | // DISASM-NEXT: .text: |
| 19 | // DISASM-NEXT: 1000: {{.*}} movl $4144, %eax | 27 | // DISASM-NEXT: 1000: {{.*}} movl $8240, %eax |
| 20 | // 0x2030 - 0x1000 = 4144 | 28 | // 0x3030 - 0x1000 = 0x2030 |
deps/lld/test/ELF/i386-merge.s+3-4| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | // CHECK-NEXT: SHF_ALLOC | 9 | // CHECK-NEXT: SHF_ALLOC |
| 10 | // CHECK-NEXT: SHF_MERGE | 10 | // CHECK-NEXT: SHF_MERGE |
| 11 | // CHECK-NEXT: ] | 11 | // CHECK-NEXT: ] |
| 12 | // CHECK-NEXT: Address: 0x114 | 12 | // CHECK-NEXT: Address: 0x158 |
| 13 | // CHECK-NEXT: Offset: | 13 | // CHECK-NEXT: Offset: |
| 14 | // CHECK-NEXT: Size: | 14 | // CHECK-NEXT: Size: |
| 15 | // CHECK-NEXT: Link: | 15 | // CHECK-NEXT: Link: |
| ... | @@ -35,11 +35,10 @@ | ... | @@ -35,11 +35,10 @@ |
| 35 | // CHECK-NEXT: AddressAlignment: 1 | 35 | // CHECK-NEXT: AddressAlignment: 1 |
| 36 | // CHECK-NEXT: EntrySize: 0 | 36 | // CHECK-NEXT: EntrySize: 0 |
| 37 | // CHECK-NEXT: SectionData ( | 37 | // CHECK-NEXT: SectionData ( |
| 38 | // CHECK-NEXT: 0000: 14010000 | | 38 | // CHECK-NEXT: 0000: 58010000 | |
| 39 | // CHECK-NEXT: ) | 39 | // CHECK-NEXT: ) |
| 40 | 40 | ||
| 41 | // The content of .data should be the address of .mysec. 14010000 is 0x114 in | 41 | // The content of .data should be the address of .mysec. |
| 42 | // little endian. | ||
| 43 | 42 | ||
| 44 | .data | 43 | .data |
| 45 | .long .mysec+4 | 44 | .long .mysec+4 |
deps/lld/test/ELF/i386-pic-plt.s created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %p/Inputs/i386-pic-plt.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | // RUN: ld.lld %t.o %t2.so -o %t | ||
| 6 | // RUN: not ld.lld %t.o %t2.so -o %t -pie 2>&1 | FileCheck %s | ||
| 7 | |||
| 8 | // CHECK: error: symbol 'foo' cannot be preempted; recompile with -fPIE | ||
| 9 | |||
| 10 | .global _start | ||
| 11 | _start: | ||
| 12 | call foo | ||
deps/lld/test/ELF/i386-reloc-16-large-addend.s created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t | ||
| 3 | # RUN: ld.lld -Ttext 0x7c00 %t -o %t2 | ||
| 4 | # RUN: llvm-objdump -s %t2 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: Contents of section .text: | ||
| 7 | # CHECK-NEXT: 7c00 b800ff | ||
| 8 | |||
| 9 | .code16 | ||
| 10 | .global _start | ||
| 11 | _start: | ||
| 12 | movw $_start+0x8300,%ax | ||
deps/lld/test/ELF/i386-reloc-16.s+4-3| ... | @@ -4,11 +4,12 @@ | ... | @@ -4,11 +4,12 @@ |
| 4 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/x86-64-reloc-16-error.s -o %t2 | 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 | 5 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t |
| 6 | // RUN: ld.lld -shared %t %t1 -o %t3 | 6 | // RUN: ld.lld -shared %t %t1 -o %t3 |
| 7 | // RUN: llvm-objdump -s %t3 | FileCheck %s | ||
| 7 | 8 | ||
| 8 | // CHECK: Contents of section .text: | 9 | // CHECK: Contents of section .text: |
| 9 | // CHECK-NEXT: 200000 42 | 10 | // CHECK-NEXT: 1000 42 |
| 10 | 11 | ||
| 11 | // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s | 12 | // RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s |
| 12 | // ERROR: relocation R_386_16 out of range: 65536 is not in [0, 65535] | 13 | // ERROR: relocation R_386_16 out of range: 65536 is not in [-32768, 32767] |
| 13 | 14 | ||
| 14 | .short foo | 15 | .short foo |
deps/lld/test/ELF/i386-reloc-8-large-addend.s created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t | ||
| 3 | # RUN: ld.lld -Ttext 0x7c %t -o %t2 | ||
| 4 | # RUN: llvm-objdump -s %t2 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: Contents of section .text: | ||
| 7 | # CHECK-NEXT: 007c b4ff | ||
| 8 | |||
| 9 | .code16 | ||
| 10 | .global _start | ||
| 11 | _start: | ||
| 12 | movb $_start+0x83,%ah | ||
deps/lld/test/ELF/i386-reloc-8.s+4-3| ... | @@ -4,11 +4,12 @@ | ... | @@ -4,11 +4,12 @@ |
| 4 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-reloc-8-error.s -o %t2 | 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 | 5 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t |
| 6 | // RUN: ld.lld -shared %t %t1 -o %t3 | 6 | // RUN: ld.lld -shared %t %t1 -o %t3 |
| 7 | // RUN: llvm-objdump -s %t3 | FileCheck %s | ||
| 7 | 8 | ||
| 8 | // CHECK: Contents of section .text: | 9 | // CHECK: Contents of section .text: |
| 9 | // CHECK-NEXT: 200000 42 | 10 | // CHECK-NEXT: 1000 ff |
| 10 | 11 | ||
| 11 | // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s | 12 | // RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s |
| 12 | // ERROR: relocation R_386_8 out of range: 256 is not in [0, 255] | 13 | // ERROR: relocation R_386_8 out of range: 256 is not in [-128, 127] |
| 13 | 14 | ||
| 14 | .byte foo | 15 | .byte foo |
deps/lld/test/ELF/i386-reloc-range.s+1-1| ... | @@ -14,7 +14,7 @@ | ... | @@ -14,7 +14,7 @@ |
| 14 | // CHECK-NEXT: 200: {{.*}} jmp -1 | 14 | // CHECK-NEXT: 200: {{.*}} jmp -1 |
| 15 | // 0x10202 - 0x203 == 0xffff | 15 | // 0x10202 - 0x203 == 0xffff |
| 16 | 16 | ||
| 17 | // RUN: not ld.lld -Ttext 0x200 %t.o %t2.o -o %t2 2>&1 | FileCheck --check-prefix=ERR %s | 17 | // RUN: not ld.lld -Ttext 0x200 %t.o %t2.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s |
| 18 | 18 | ||
| 19 | // ERR: {{.*}}:(.text+0x1): relocation R_386_PC16 out of range: 65536 is not in [-65536, 65535] | 19 | // ERR: {{.*}}:(.text+0x1): relocation R_386_PC16 out of range: 65536 is not in [-65536, 65535] |
| 20 | 20 |
deps/lld/test/ELF/i386-retpoline-nopic-linkerscript.s created+67| ... | @@ -0,0 +1,67 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t1.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/shared.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | // RUN: echo "SECTIONS { \ | ||
| 7 | // RUN: .text : { *(.text) } \ | ||
| 8 | // RUN: .plt : { *(.plt) } \ | ||
| 9 | // RUN: .got.plt : { *(.got.plt) } \ | ||
| 10 | // RUN: .dynstr : { *(.dynstr) } \ | ||
| 11 | // RUN: }" > %t.script | ||
| 12 | // RUN: ld.lld %t1.o %t2.so -o %t.exe -z retpolineplt --script %t.script | ||
| 13 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | ||
| 14 | |||
| 15 | // CHECK: Disassembly of section .plt: | ||
| 16 | // CHECK-NEXT: .plt: | ||
| 17 | // CHECK-NEXT: 10: ff 35 84 00 00 00 pushl 132 | ||
| 18 | // CHECK-NEXT: 16: 50 pushl %eax | ||
| 19 | // CHECK-NEXT: 17: a1 88 00 00 00 movl 136, %eax | ||
| 20 | // CHECK-NEXT: 1c: e8 0f 00 00 00 calll 15 <.plt+0x20> | ||
| 21 | // CHECK-NEXT: 21: f3 90 pause | ||
| 22 | // CHECK-NEXT: 23: 0f ae e8 lfence | ||
| 23 | // CHECK-NEXT: 26: eb f9 jmp -7 <.plt+0x11> | ||
| 24 | // CHECK-NEXT: 28: cc int3 | ||
| 25 | // CHECK-NEXT: 29: cc int3 | ||
| 26 | // CHECK-NEXT: 2a: cc int3 | ||
| 27 | // CHECK-NEXT: 2b: cc int3 | ||
| 28 | // CHECK-NEXT: 2c: cc int3 | ||
| 29 | // CHECK-NEXT: 2d: cc int3 | ||
| 30 | // CHECK-NEXT: 2e: cc int3 | ||
| 31 | // CHECK-NEXT: 2f: cc int3 | ||
| 32 | // CHECK-NEXT: 30: 89 0c 24 movl %ecx, (%esp) | ||
| 33 | // CHECK-NEXT: 33: 8b 4c 24 04 movl 4(%esp), %ecx | ||
| 34 | // CHECK-NEXT: 37: 89 44 24 04 movl %eax, 4(%esp) | ||
| 35 | // CHECK-NEXT: 3b: 89 c8 movl %ecx, %eax | ||
| 36 | // CHECK-NEXT: 3d: 59 popl %ecx | ||
| 37 | // CHECK-NEXT: 3e: c3 retl | ||
| 38 | // CHECK-NEXT: 3f: cc int3 | ||
| 39 | // CHECK-NEXT: 40: 50 pushl %eax | ||
| 40 | // CHECK-NEXT: 41: a1 8c 00 00 00 movl 140, %eax | ||
| 41 | // CHECK-NEXT: 46: e8 e5 ff ff ff calll -27 <.plt+0x20> | ||
| 42 | // CHECK-NEXT: 4b: e9 d1 ff ff ff jmp -47 <.plt+0x11> | ||
| 43 | // CHECK-NEXT: 50: 68 00 00 00 00 pushl $0 | ||
| 44 | // CHECK-NEXT: 55: e9 b6 ff ff ff jmp -74 <.plt> | ||
| 45 | // CHECK-NEXT: 5a: cc int3 | ||
| 46 | // CHECK-NEXT: 5b: cc int3 | ||
| 47 | // CHECK-NEXT: 5c: cc int3 | ||
| 48 | // CHECK-NEXT: 5d: cc int3 | ||
| 49 | // CHECK-NEXT: 5e: cc int3 | ||
| 50 | // CHECK-NEXT: 5f: cc int3 | ||
| 51 | // CHECK-NEXT: 60: 50 pushl %eax | ||
| 52 | // CHECK-NEXT: 61: a1 90 00 00 00 movl 144, %eax | ||
| 53 | // CHECK-NEXT: 66: e8 c5 ff ff ff calll -59 <.plt+0x20> | ||
| 54 | // CHECK-NEXT: 6b: e9 b1 ff ff ff jmp -79 <.plt+0x11> | ||
| 55 | // CHECK-NEXT: 70: 68 08 00 00 00 pushl $8 | ||
| 56 | // CHECK-NEXT: 75: e9 96 ff ff ff jmp -106 <.plt> | ||
| 57 | // CHECK-NEXT: 7a: cc int3 | ||
| 58 | // CHECK-NEXT: 7b: cc int3 | ||
| 59 | // CHECK-NEXT: 7c: cc int3 | ||
| 60 | // CHECK-NEXT: 7d: cc int3 | ||
| 61 | // CHECK-NEXT: 7e: cc int3 | ||
| 62 | // CHECK-NEXT: 7f: cc int3 | ||
| 63 | |||
| 64 | .global _start | ||
| 65 | _start: | ||
| 66 | jmp bar@PLT | ||
| 67 | jmp zed@PLT | ||
deps/lld/test/ELF/i386-retpoline-pic-linkerscript.s created+64| ... | @@ -0,0 +1,64 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux -position-independent %s -o %t1.o | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux -position-independent %p/Inputs/shared.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | // RUN: echo "SECTIONS { \ | ||
| 7 | // RUN: .text : { *(.text) } \ | ||
| 8 | // RUN: .plt : { *(.plt) } \ | ||
| 9 | // RUN: .got.plt : { *(.got.plt) } \ | ||
| 10 | // RUN: .dynstr : { *(.dynstr) } \ | ||
| 11 | // RUN: }" > %t.script | ||
| 12 | // RUN: ld.lld %t1.o %t2.so -o %t.exe -z retpolineplt -pie --script %t.script | ||
| 13 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | ||
| 14 | |||
| 15 | // CHECK: Disassembly of section .plt: | ||
| 16 | // CHECK-NEXT: .plt: | ||
| 17 | // CHECK-NEXT: 10: ff b3 84 00 00 00 pushl 132(%ebx) | ||
| 18 | // CHECK-NEXT: 16: 50 pushl %eax | ||
| 19 | // CHECK-NEXT: 17: 8b 83 88 00 00 00 movl 136(%ebx), %eax | ||
| 20 | // CHECK-NEXT: 1d: e8 0e 00 00 00 calll 14 <.plt+0x20> | ||
| 21 | // CHECK-NEXT: 22: f3 90 pause | ||
| 22 | // CHECK-NEXT: 24: 0f ae e8 lfence | ||
| 23 | // CHECK-NEXT: 27: eb f9 jmp -7 <.plt+0x12> | ||
| 24 | // CHECK-NEXT: 29: cc int3 | ||
| 25 | // CHECK-NEXT: 2a: cc int3 | ||
| 26 | // CHECK-NEXT: 2b: cc int3 | ||
| 27 | // CHECK-NEXT: 2c: cc int3 | ||
| 28 | // CHECK-NEXT: 2d: cc int3 | ||
| 29 | // CHECK-NEXT: 2e: cc int3 | ||
| 30 | // CHECK-NEXT: 2f: cc int3 | ||
| 31 | // CHECK-NEXT: 30: 89 0c 24 movl %ecx, (%esp) | ||
| 32 | // CHECK-NEXT: 33: 8b 4c 24 04 movl 4(%esp), %ecx | ||
| 33 | // CHECK-NEXT: 37: 89 44 24 04 movl %eax, 4(%esp) | ||
| 34 | // CHECK-NEXT: 3b: 89 c8 movl %ecx, %eax | ||
| 35 | // CHECK-NEXT: 3d: 59 popl %ecx | ||
| 36 | // CHECK-NEXT: 3e: c3 retl | ||
| 37 | // CHECK-NEXT: 3f: cc int3 | ||
| 38 | // CHECK-NEXT: 40: 50 pushl %eax | ||
| 39 | // CHECK-NEXT: 41: 8b 83 8c 00 00 00 movl 140(%ebx), %eax | ||
| 40 | // CHECK-NEXT: 47: e8 e4 ff ff ff calll -28 <.plt+0x20> | ||
| 41 | // CHECK-NEXT: 4c: e9 d1 ff ff ff jmp -47 <.plt+0x12> | ||
| 42 | // CHECK-NEXT: 51: 68 00 00 00 00 pushl $0 | ||
| 43 | // CHECK-NEXT: 56: e9 b5 ff ff ff jmp -75 <.plt> | ||
| 44 | // CHECK-NEXT: 5b: cc int3 | ||
| 45 | // CHECK-NEXT: 5c: cc int3 | ||
| 46 | // CHECK-NEXT: 5d: cc int3 | ||
| 47 | // CHECK-NEXT: 5e: cc int3 | ||
| 48 | // CHECK-NEXT: 5f: cc int3 | ||
| 49 | // CHECK-NEXT: 60: 50 pushl %eax | ||
| 50 | // CHECK-NEXT: 61: 8b 83 90 00 00 00 movl 144(%ebx), %eax | ||
| 51 | // CHECK-NEXT: 67: e8 c4 ff ff ff calll -60 <.plt+0x20> | ||
| 52 | // CHECK-NEXT: 6c: e9 b1 ff ff ff jmp -79 <.plt+0x12> | ||
| 53 | // CHECK-NEXT: 71: 68 08 00 00 00 pushl $8 | ||
| 54 | // CHECK-NEXT: 76: e9 95 ff ff ff jmp -107 <.plt> | ||
| 55 | // CHECK-NEXT: 7b: cc int3 | ||
| 56 | // CHECK-NEXT: 7c: cc int3 | ||
| 57 | // CHECK-NEXT: 7d: cc int3 | ||
| 58 | // CHECK-NEXT: 7e: cc int3 | ||
| 59 | // CHECK-NEXT: 7f: cc int3 | ||
| 60 | |||
| 61 | .global _start | ||
| 62 | _start: | ||
| 63 | jmp bar@PLT | ||
| 64 | jmp zed@PLT | ||
deps/lld/test/ELF/i386-tls-got.s+1-1| ... | @@ -2,6 +2,6 @@ | ... | @@ -2,6 +2,6 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-tls-got.s -o %t1.o | 2 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-tls-got.s -o %t1.o |
| 3 | # RUN: ld.lld %t1.o -o %t1.so -shared | 3 | # RUN: ld.lld %t1.o -o %t1.so -shared |
| 4 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t2.o | 4 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t2.o |
| 5 | # RUN: ld.lld %t2.o %t1.so -o %t | 5 | # RUN: ld.lld %t2.o %t1.so -o /dev/null |
| 6 | 6 | ||
| 7 | 	addl	foobar@INDNTPOFF, %eax | 7 | 	addl	foobar@INDNTPOFF, %eax |
deps/lld/test/ELF/i386-tls-ie-shared.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o | 3 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o |
| 3 | // RUN: ld.lld -shared %tso.o -o %tso | 4 | // RUN: ld.lld -shared %tso.o -o %tso |
deps/lld/test/ELF/icf-absolute.s+3-3| ... | @@ -2,10 +2,10 @@ | ... | @@ -2,10 +2,10 @@ |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-absolute.s -o %t2 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-absolute.s -o %t2 |
| 5 | # RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s | 5 | # RUN: ld.lld %t %t2 -o /dev/null --icf=all --print-icf-sections | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: selected .text.f1 | 7 | # CHECK: selected section {{.*}}:(.text.f1) |
| 8 | # CHECK: removed .text.f2 | 8 | # CHECK: removing identical section {{.*}}:(.text.f2) |
| 9 | 9 | ||
| 10 | .globl _start, f1, f2 | 10 | .globl _start, f1, f2 |
| 11 | _start: | 11 | _start: |
deps/lld/test/ELF/icf-absolute2.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-absolute2.s -o %t2 | ||
| 5 | # RUN: ld.lld %t %t2 -o /dev/null --icf=all --print-icf-sections | FileCheck -allow-empty %s | ||
| 6 | |||
| 7 | ## Test we do not crash and do not fold sections which relocations reffering to | ||
| 8 | ## absolute symbols with a different values. | ||
| 9 | # CHECK-NOT: selected | ||
| 10 | |||
| 11 | .globl _start, f1, f2 | ||
| 12 | _start: | ||
| 13 | ret | ||
| 14 | |||
| 15 | .section .text.f1, "ax" | ||
| 16 | f1: | ||
| 17 | .byte a1 | ||
| 18 | |||
| 19 | .section .text.f2, "ax" | ||
| 20 | f2: | ||
| 21 | .byte a2 | ||
deps/lld/test/ELF/icf-c-identifier.s created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: ld.lld %t -o /dev/null --icf=all --print-icf-sections | count 0 | ||
| 4 | |||
| 5 | .section foo,"ax",@progbits,unique,0 | ||
| 6 | .byte 42 | ||
| 7 | |||
| 8 | .section foo,"ax",@progbits,unique,1 | ||
| 9 | .byte 42 | ||
deps/lld/test/ELF/icf-comdat.s+3-3| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | 4 | # RUN: ld.lld %t -o /dev/null --icf=all --print-icf-sections | FileCheck %s |
| 5 | 5 | ||
| 6 | # CHECK: selected .text.f1 | 6 | # CHECK: selected section {{.*}}:(.text.f1) |
| 7 | # CHECK: removed .text.f2 | 7 | # CHECK: removing identical section {{.*}}:(.text.f2) |
| 8 | 8 | ||
| 9 | .globl _start, f1, f2 | 9 | .globl _start, f1, f2 |
| 10 | _start: | 10 | _start: |
deps/lld/test/ELF/icf-different-output-sections.s created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: ld.lld %t -o /dev/null --icf=all --print-icf-sections | count 0 | ||
| 4 | |||
| 5 | .section .foo,"ax" | ||
| 6 | .byte 42 | ||
| 7 | |||
| 8 | .section .bar,"ax" | ||
| 9 | .byte 42 | ||
deps/lld/test/ELF/icf-i386.s+4-4| ... | @@ -2,11 +2,11 @@ | ... | @@ -2,11 +2,11 @@ |
| 2 | # This test is to make sure that we can handle implicit addends properly. | 2 | # This test is to make sure that we can handle implicit addends properly. |
| 3 | 3 | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t | 4 | # RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t |
| 5 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | 5 | # RUN: ld.lld %t -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: selected .text.f1 | 7 | # CHECK: selected section {{.*}}:(.text.f1) |
| 8 | # CHECK: removed .text.f2 | 8 | # CHECK: removing identical section {{.*}}:(.text.f2) |
| 9 | # CHECK-NOT: removed .text.f3 | 9 | # CHECK-NOT: removing identical section {{.*}}:(.text.f3) |
| 10 | 10 | ||
| 11 | .globl _start, f1, f2, f3 | 11 | .globl _start, f1, f2, f3 |
| 12 | _start: | 12 | _start: |
deps/lld/test/ELF/icf-keep-unique.s created+43| ... | @@ -0,0 +1,43 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections | FileCheck %s | ||
| 5 | # RUN: ld.lld %t -o %t2 --keep-unique f2 --keep-unique f4 --keep-unique f5 --icf=all --print-icf-sections 2>&1 | FileCheck %s -check-prefix=CHECK-KEEP | ||
| 6 | |||
| 7 | // Base case, expect only .text.f1 to be kept | ||
| 8 | // CHECK: selected section {{.*}}:(.text.f1) | ||
| 9 | // CHECK-NEXT: removing identical section {{.*}}:(.text.f2) | ||
| 10 | // CHECK-NEXT: removing identical section {{.*}}:(.text.f3) | ||
| 11 | // CHECK-NEXT: removing identical section {{.*}}:(.text.f4) | ||
| 12 | // CHECK-NEXT: removing identical section {{.*}}:(.text.f5) | ||
| 13 | |||
| 14 | // With --keep-unique f2, f4 and f5 we expect only f3 and f5 to be removed. | ||
| 15 | // f5 is not matched by --keep-unique as it is a local symbol. | ||
| 16 | // CHECK-KEEP: warning: could not find symbol f5 to keep unique | ||
| 17 | // CHECK-KEEP: selected section {{.*}}:(.text.f1) | ||
| 18 | // CHECK-KEEP-NEXT: removing identical section {{.*}}:(.text.f3) | ||
| 19 | // CHECK-KEEP-NEXT: removing identical section {{.*}}:(.text.f5) | ||
| 20 | .globl _start, f1, f2, f3, f4 | ||
| 21 | _start: | ||
| 22 | ret | ||
| 23 | |||
| 24 | .section .text.f1, "ax" | ||
| 25 | f1: | ||
| 26 | nop | ||
| 27 | |||
| 28 | .section .text.f2, "ax" | ||
| 29 | f2: | ||
| 30 | nop | ||
| 31 | |||
| 32 | .section .text.f3, "ax" | ||
| 33 | f3: | ||
| 34 | nop | ||
| 35 | |||
| 36 | .section .text.f4, "ax" | ||
| 37 | f4: | ||
| 38 | nop | ||
| 39 | |||
| 40 | # f5 is local, not found by --keep-unique f5 | ||
| 41 | .section .text.f5, "ax" | ||
| 42 | f5: | ||
| 43 | nop | ||
deps/lld/test/ELF/icf-link-order.s created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: ld.lld %t.o -o %t --icf=all --print-icf-sections | count 0 | ||
| 5 | |||
| 6 | .section .foo,"a",@progbits,unique,1 | ||
| 7 | foo1: | ||
| 8 | .byte 1 | ||
| 9 | |||
| 10 | .section .foo,"a",@progbits,unique,2 | ||
| 11 | foo2: | ||
| 12 | .byte 2 | ||
| 13 | |||
| 14 | .section .bar,"ao",@progbits,foo1,unique,1 | ||
| 15 | .byte 3 | ||
| 16 | |||
| 17 | .section .bar,"ao",@progbits,foo2,unique,2 | ||
| 18 | .byte 3 | ||
deps/lld/test/ELF/icf-many-sections.s created+62| ... | @@ -0,0 +1,62 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t | ||
| 3 | # RUN: ld.lld --icf=all --print-icf-sections %t -o /dev/null | FileCheck %s -allow-empty | ||
| 4 | |||
| 5 | # CHECK-NOT: selected | ||
| 6 | |||
| 7 | .macro gen_sections4 z | ||
| 8 | .section .a\z,"ax" | ||
| 9 | .section .b\z,"ax" | ||
| 10 | .section .c\z,"ax" | ||
| 11 | .section .d\z,"ax" | ||
| 12 | .endm | ||
| 13 | |||
| 14 | .macro gen_sections8 z | ||
| 15 | gen_sections4 a\z | ||
| 16 | gen_sections4 b\z | ||
| 17 | .endm | ||
| 18 | |||
| 19 | .macro gen_sections16 z | ||
| 20 | gen_sections8 a\z | ||
| 21 | gen_sections8 b\z | ||
| 22 | .endm | ||
| 23 | |||
| 24 | .macro gen_sections32 x | ||
| 25 | gen_sections16 a\x | ||
| 26 | gen_sections16 b\x | ||
| 27 | .endm | ||
| 28 | |||
| 29 | .macro gen_sections64 z | ||
| 30 | gen_sections32 a\z | ||
| 31 | gen_sections32 b\z | ||
| 32 | .endm | ||
| 33 | |||
| 34 | .macro gen_sections128 z | ||
| 35 | gen_sections64 a\z | ||
| 36 | gen_sections64 b\z | ||
| 37 | .endm | ||
| 38 | |||
| 39 | .macro gen_sections256 z | ||
| 40 | gen_sections128 a\z | ||
| 41 | gen_sections128 b\z | ||
| 42 | .endm | ||
| 43 | |||
| 44 | .macro gen_sections512 z | ||
| 45 | gen_sections256 a\z | ||
| 46 | gen_sections256 b\z | ||
| 47 | .endm | ||
| 48 | |||
| 49 | .macro gen_sections1024 z | ||
| 50 | gen_sections512 a\z | ||
| 51 | gen_sections512 b\z | ||
| 52 | .endm | ||
| 53 | |||
| 54 | .macro gen_sections2048 z | ||
| 55 | gen_sections1024 a\z | ||
| 56 | gen_sections1024 b\z | ||
| 57 | .endm | ||
| 58 | |||
| 59 | gen_sections2048 a | ||
| 60 | |||
| 61 | .global _start | ||
| 62 | _start: | ||
deps/lld/test/ELF/icf-merge-sec.s+3-3| ... | @@ -2,10 +2,10 @@ | ... | @@ -2,10 +2,10 @@ |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge-sec.s -o %t2 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge-sec.s -o %t2 |
| 5 | # RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s | 5 | # RUN: ld.lld %t %t2 -o /dev/null --icf=all --print-icf-sections | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: selected .text.f1 | 7 | # CHECK: selected section {{.*}}:(.text.f1) |
| 8 | # CHECK: removed .text.f2 | 8 | # CHECK: removing identical section {{.*}}:(.text.f2) |
| 9 | 9 | ||
| 10 | .section .rodata.str,"aMS",@progbits,1 | 10 | .section .rodata.str,"aMS",@progbits,1 |
| 11 | .asciz "foo" | 11 | .asciz "foo" |
deps/lld/test/ELF/icf-merge.s+6-6| ... | @@ -2,18 +2,18 @@ | ... | @@ -2,18 +2,18 @@ |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge.s -o %t1 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge.s -o %t1 |
| 5 | # RUN: ld.lld %t %t1 -o %t1.out --icf=all --verbose 2>&1 | FileCheck %s | 5 | # RUN: ld.lld %t %t1 -o /dev/null --icf=all --print-icf-sections | FileCheck %s |
| 6 | 6 | ||
| 7 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge2.s -o %t2 | 7 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge2.s -o %t2 |
| 8 | # RUN: ld.lld %t %t2 -o %t3.out --icf=all --verbose 2>&1 | FileCheck --check-prefix=NOMERGE %s | 8 | # RUN: ld.lld %t %t2 -o %t3.out --icf=all --print-icf-sections | FileCheck --check-prefix=NOMERGE %s |
| 9 | 9 | ||
| 10 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge3.s -o %t3 | 10 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge3.s -o %t3 |
| 11 | # RUN: ld.lld %t %t3 -o %t3.out --icf=all --verbose 2>&1 | FileCheck --check-prefix=NOMERGE %s | 11 | # RUN: ld.lld %t %t3 -o %t3.out --icf=all --print-icf-sections | FileCheck --check-prefix=NOMERGE %s |
| 12 | 12 | ||
| 13 | # CHECK: selected .text.f1 | 13 | # CHECK: selected section {{.*}}:(.text.f1) |
| 14 | # CHECK: removed .text.f2 | 14 | # CHECK: removing identical section {{.*}}:(.text.f2) |
| 15 | 15 | ||
| 16 | # NOMERGE-NOT: selected .text.f | 16 | # NOMERGE-NOT: selected section {{.*}}:(.text.f) |
| 17 | 17 | ||
| 18 | .section .rodata.str,"aMS",@progbits,1 | 18 | .section .rodata.str,"aMS",@progbits,1 |
| 19 | foo: | 19 | foo: |
deps/lld/test/ELF/icf-merge2.s created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: ld.lld %t.o -o %t --icf=all | ||
| 5 | # RUN: llvm-objdump -d %t | FileCheck %s | ||
| 6 | |||
| 7 | # Test that we don't merge these. | ||
| 8 | # CHECK: leaq | ||
| 9 | # CHECK: leaq | ||
| 10 | |||
| 11 | .section .merge1, "aM", @progbits, 8 | ||
| 12 | .Lfoo: | ||
| 13 | .quad 42 | ||
| 14 | |||
| 15 | .section .merge2, "aM", @progbits, 4 | ||
| 16 | .Lbar: | ||
| 17 | .long 41 | ||
| 18 | |||
| 19 | .section .text.foo, "ax", @progbits | ||
| 20 | leaq .Lfoo(%rip), %rax | ||
| 21 | |||
| 22 | .section .text.bar, "ax", @progbits | ||
| 23 | leaq .Lbar(%rip), %rax | ||
deps/lld/test/ELF/icf-merged-sections.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.o | ||
| 4 | # 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 | ||
| 6 | |||
| 7 | # Check that merge synthetic sections are not merged by ICF. | ||
| 8 | |||
| 9 | # NOICF-NOT: selected section <internal>:(.rodata) | ||
| 10 | |||
| 11 | # CHECK: Name: .rodata | ||
| 12 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 13 | # CHECK-NEXT: Flags [ | ||
| 14 | # CHECK-NEXT: SHF_ALLOC | ||
| 15 | # CHECK-NEXT: SHF_MERGE | ||
| 16 | # CHECK-NEXT: ] | ||
| 17 | # CHECK-NEXT: Address: | ||
| 18 | # CHECK-NEXT: Offset: | ||
| 19 | # CHECK-NEXT: Size: 16 | ||
| 20 | # CHECK-NEXT: Link: | ||
| 21 | # CHECK-NEXT: Info: | ||
| 22 | # CHECK-NEXT: AddressAlignment: 8 | ||
| 23 | # CHECK-NEXT: EntrySize: 0 | ||
| 24 | # CHECK-NEXT: SectionData ( | ||
| 25 | # CHECK-NEXT: 0000: 67452301 10325476 67452301 10325476 | ||
| 26 | |||
| 27 | .section .rodata.cst4,"aM",@progbits,4 | ||
| 28 | rodata4: | ||
| 29 | .long 0x01234567 | ||
| 30 | .long 0x76543210 | ||
| 31 | .long 0x01234567 | ||
| 32 | .long 0x76543210 | ||
| 33 | |||
| 34 | .section .rodata.cst8,"aM",@progbits,8 | ||
| 35 | rodata8: | ||
| 36 | .long 0x01234567 | ||
| 37 | .long 0x76543210 | ||
deps/lld/test/ELF/icf-non-mergeable.s+3-3| ... | @@ -8,10 +8,10 @@ | ... | @@ -8,10 +8,10 @@ |
| 8 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | 8 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 9 | // RUN: %p/Inputs/icf-non-mergeable.s -o %t2 | 9 | // RUN: %p/Inputs/icf-non-mergeable.s -o %t2 |
| 10 | 10 | ||
| 11 | // RUN: ld.lld %t1 %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s | 11 | // RUN: ld.lld %t1 %t2 -o /dev/null --icf=all --verbose 2>&1 | FileCheck %s |
| 12 | 12 | ||
| 13 | // CHECK-NOT: selected .text.f1 | 13 | // CHECK-NOT: selected section '.text.f1' |
| 14 | // CHECK-NOT: removed .text.f2 | 14 | // CHECK-NOT: removing identical section '.text.f2' |
| 15 | 15 | ||
| 16 | .globl _start, f1, f2, d1, d2 | 16 | .globl _start, f1, f2, d1, d2 |
| 17 | _start: | 17 | _start: |
deps/lld/test/ELF/icf-none.s+2-2| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --icf=none --verbose 2>&1 | FileCheck %s | 4 | # RUN: ld.lld %t -o /dev/null --icf=all --icf=none --verbose 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | # CHECK-NOT: selected .text.f1 | 6 | # CHECK-NOT: selected section '.text.f1' |
| 7 | 7 | ||
| 8 | .globl _start, f1, f2 | 8 | .globl _start, f1, f2 |
| 9 | _start: | 9 | _start: |
deps/lld/test/ELF/icf-relro.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: ld.lld %t -o /dev/null --icf=all --ignore-data-address-equality --print-icf-sections | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: selected section {{.*}}:(.data.rel.ro) | ||
| 6 | # CHECK: removing identical section {{.*}}:(.data.rel.ro.foo) | ||
| 7 | |||
| 8 | .section .data.rel.ro,"aw" | ||
| 9 | .quad foo | ||
| 10 | |||
| 11 | .section .data.rel.ro.foo,"aw" | ||
| 12 | foo: | ||
| 13 | .quad foo | ||
deps/lld/test/ELF/icf-safe.s created+182| ... | @@ -0,0 +1,182 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 4 | # RUN: llvm-objcopy %t1.o %t1copy.o | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-safe.s -o %t2.o | ||
| 6 | # RUN: ld.lld %t1.o %t2.o -o %t2 --icf=safe --print-icf-sections | FileCheck %s | ||
| 7 | # RUN: ld.lld %t1.o %t2.o -o %t3 --icf=safe --print-icf-sections -shared | FileCheck --check-prefix=EXPORT %s | ||
| 8 | # RUN: ld.lld %t1.o %t2.o -o %t3 --icf=safe --print-icf-sections --export-dynamic | FileCheck --check-prefix=EXPORT %s | ||
| 9 | # RUN: ld.lld %t1.o %t2.o -o %t2 --icf=all --print-icf-sections | FileCheck --check-prefix=ALL %s | ||
| 10 | # RUN: ld.lld %t1.o %t2.o -o %t2 --icf=all --print-icf-sections --export-dynamic | FileCheck --check-prefix=ALL-EXPORT %s | ||
| 11 | # RUN: ld.lld %t1copy.o -o %t4 --icf=safe 2>&1 | FileCheck --check-prefix=OBJCOPY %s | ||
| 12 | |||
| 13 | # CHECK-NOT: selected section {{.*}}:(.text.f1) | ||
| 14 | # CHECK: selected section {{.*}}:(.text.f3) | ||
| 15 | # CHECK: removing identical section {{.*}}:(.text.f4) | ||
| 16 | |||
| 17 | # CHECK-NOT: selected section {{.*}}:(.rodata.h1) | ||
| 18 | # CHECK: selected section {{.*}}:(.rodata.h3) | ||
| 19 | # CHECK: removing identical section {{.*}}:(.rodata.h4) | ||
| 20 | |||
| 21 | # CHECK-NOT: selected section {{.*}}:(.rodata.l1) | ||
| 22 | # CHECK: selected section {{.*}}:(.rodata.l3) | ||
| 23 | # CHECK: removing identical section {{.*}}:(.rodata.l4) | ||
| 24 | |||
| 25 | # CHECK-NOT: selected section {{.*}}:(.rodata.g1) | ||
| 26 | # CHECK: selected section {{.*}}:(.rodata.g3) | ||
| 27 | # CHECK: removing identical section {{.*}}:(.rodata.g4) | ||
| 28 | |||
| 29 | # CHECK-NOT: selected section {{.*}}:(.text.non_addrsig{{.}}) | ||
| 30 | |||
| 31 | # With --icf=all address-significance implies keep-unique only for rodata, not | ||
| 32 | # text. | ||
| 33 | # ALL: selected section {{.*}}:(.text.f3) | ||
| 34 | # ALL: removing identical section {{.*}}:(.text.f4) | ||
| 35 | |||
| 36 | # ALL-NOT: selected section {{.*}}:(.rodata.h1) | ||
| 37 | # ALL: selected section {{.*}}:(.rodata.h3) | ||
| 38 | # ALL: removing identical section {{.*}}:(.rodata.h4) | ||
| 39 | |||
| 40 | # ALL-NOT: selected section {{.*}}:(.rodata.l1) | ||
| 41 | # ALL: selected section {{.*}}:(.rodata.l3) | ||
| 42 | # ALL: removing identical section {{.*}}:(.rodata.l4) | ||
| 43 | |||
| 44 | # ALL-NOT: selected section {{.*}}:(.rodata.g1) | ||
| 45 | # ALL: selected section {{.*}}:(.rodata.g3) | ||
| 46 | # ALL: removing identical section {{.*}}:(.rodata.g4) | ||
| 47 | |||
| 48 | # ALL: selected section {{.*}}:(.text.f1) | ||
| 49 | # ALL: removing identical section {{.*}}:(.text.f2) | ||
| 50 | # ALL: removing identical section {{.*}}:(.text.non_addrsig1) | ||
| 51 | # ALL: removing identical section {{.*}}:(.text.non_addrsig2) | ||
| 52 | |||
| 53 | # llvm-mc normally emits an empty .text section into every object file. Since | ||
| 54 | # nothing actually refers to it via a relocation, it doesn't have any associated | ||
| 55 | # symbols (thus nor can anything refer to it via a relocation, making it safe to | ||
| 56 | # merge with the empty section in the other input file). Here we check that the | ||
| 57 | # only two sections merged are the two empty sections and the sections with only | ||
| 58 | # STB_LOCAL or STV_HIDDEN symbols. The dynsym entries should have prevented | ||
| 59 | # anything else from being merged. | ||
| 60 | # EXPORT-NOT: selected section | ||
| 61 | # EXPORT: selected section {{.*}}:(.rodata.h3) | ||
| 62 | # EXPORT: removing identical section {{.*}}:(.rodata.h4) | ||
| 63 | # EXPORT-NOT: selected section | ||
| 64 | # EXPORT: selected section {{.*}}:(.text) | ||
| 65 | # EXPORT: removing identical section {{.*}}:(.text) | ||
| 66 | # EXPORT-NOT: selected section | ||
| 67 | # EXPORT: selected section {{.*}}:(.rodata.l3) | ||
| 68 | # EXPORT: removing identical section {{.*}}:(.rodata.l4) | ||
| 69 | # EXPORT-NOT: selected section | ||
| 70 | |||
| 71 | # If --icf=all is specified when exporting we can also merge the exported text | ||
| 72 | # sections, but not the exported rodata. | ||
| 73 | # ALL-EXPORT-NOT: selected section | ||
| 74 | # ALL-EXPORT: selected section {{.*}}:(.text.f3) | ||
| 75 | # ALL-EXPORT: removing identical section {{.*}}:(.text.f4) | ||
| 76 | # ALL-EXPORT-NOT: selected section | ||
| 77 | # ALL-EXPORT: selected section {{.*}}:(.rodata.h3) | ||
| 78 | # ALL-EXPORT: removing identical section {{.*}}:(.rodata.h4) | ||
| 79 | # ALL-EXPORT-NOT: selected section | ||
| 80 | # ALL-EXPORT: selected section {{.*}}:(.text) | ||
| 81 | # ALL-EXPORT: removing identical section {{.*}}:(.text) | ||
| 82 | # ALL-EXPORT-NOT: selected section | ||
| 83 | # ALL-EXPORT: selected section {{.*}}:(.rodata.l3) | ||
| 84 | # ALL-EXPORT: removing identical section {{.*}}:(.rodata.l4) | ||
| 85 | # ALL-EXPORT-NOT: selected section | ||
| 86 | # ALL-EXPORT: selected section {{.*}}:(.text.f1) | ||
| 87 | # ALL-EXPORT: removing identical section {{.*}}:(.text.f2) | ||
| 88 | # ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig1) | ||
| 89 | # ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig2) | ||
| 90 | # ALL-EXPORT-NOT: selected section | ||
| 91 | |||
| 92 | # OBJCOPY: --icf=safe is incompatible with object files created using objcopy or ld -r | ||
| 93 | |||
| 94 | .section .text.f1,"ax",@progbits | ||
| 95 | .globl f1 | ||
| 96 | f1: | ||
| 97 | ret | ||
| 98 | |||
| 99 | .section .text.f2,"ax",@progbits | ||
| 100 | .globl f2 | ||
| 101 | f2: | ||
| 102 | ret | ||
| 103 | |||
| 104 | .section .text.f3,"ax",@progbits | ||
| 105 | .globl f3 | ||
| 106 | f3: | ||
| 107 | ud2 | ||
| 108 | |||
| 109 | .section .text.f4,"ax",@progbits | ||
| 110 | .globl f4 | ||
| 111 | f4: | ||
| 112 | ud2 | ||
| 113 | |||
| 114 | .section .rodata.g1,"a",@progbits | ||
| 115 | .globl g1 | ||
| 116 | g1: | ||
| 117 | .byte 1 | ||
| 118 | |||
| 119 | .section .rodata.g2,"a",@progbits | ||
| 120 | .globl g2 | ||
| 121 | g2: | ||
| 122 | .byte 1 | ||
| 123 | |||
| 124 | .section .rodata.g3,"a",@progbits | ||
| 125 | .globl g3 | ||
| 126 | g3: | ||
| 127 | .byte 2 | ||
| 128 | |||
| 129 | .section .rodata.g4,"a",@progbits | ||
| 130 | .globl g4 | ||
| 131 | g4: | ||
| 132 | .byte 2 | ||
| 133 | |||
| 134 | .section .rodata.l1,"a",@progbits | ||
| 135 | l1: | ||
| 136 | .byte 3 | ||
| 137 | |||
| 138 | .section .rodata.l2,"a",@progbits | ||
| 139 | l2: | ||
| 140 | .byte 3 | ||
| 141 | |||
| 142 | .section .rodata.l3,"a",@progbits | ||
| 143 | l3: | ||
| 144 | .byte 4 | ||
| 145 | |||
| 146 | .section .rodata.l4,"a",@progbits | ||
| 147 | l4: | ||
| 148 | .byte 4 | ||
| 149 | |||
| 150 | .section .rodata.h1,"a",@progbits | ||
| 151 | .globl h1 | ||
| 152 | .hidden h1 | ||
| 153 | h1: | ||
| 154 | .byte 5 | ||
| 155 | |||
| 156 | .section .rodata.h2,"a",@progbits | ||
| 157 | .globl h2 | ||
| 158 | .hidden h2 | ||
| 159 | h2: | ||
| 160 | .byte 5 | ||
| 161 | |||
| 162 | .section .rodata.h3,"a",@progbits | ||
| 163 | .globl h3 | ||
| 164 | .hidden h3 | ||
| 165 | h3: | ||
| 166 | .byte 6 | ||
| 167 | |||
| 168 | .section .rodata.h4,"a",@progbits | ||
| 169 | .globl h4 | ||
| 170 | .hidden h4 | ||
| 171 | h4: | ||
| 172 | .byte 6 | ||
| 173 | |||
| 174 | .addrsig | ||
| 175 | .addrsig_sym f1 | ||
| 176 | .addrsig_sym f2 | ||
| 177 | .addrsig_sym g1 | ||
| 178 | .addrsig_sym g2 | ||
| 179 | .addrsig_sym l1 | ||
| 180 | .addrsig_sym l2 | ||
| 181 | .addrsig_sym h1 | ||
| 182 | .addrsig_sym h2 | ||
deps/lld/test/ELF/icf1.s+3-3| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | 4 | # RUN: ld.lld %t -o /dev/null --icf=all --print-icf-sections | FileCheck %s |
| 5 | 5 | ||
| 6 | # CHECK: selected .text.f1 | 6 | # CHECK: selected section {{.*}}:(.text.f1) |
| 7 | # CHECK: removed .text.f2 | 7 | # CHECK: removing identical section {{.*}}:(.text.f2) |
| 8 | 8 | ||
| 9 | .globl _start, f1, f2 | 9 | .globl _start, f1, f2 |
| 10 | _start: | 10 | _start: |
deps/lld/test/ELF/icf10.test created+40| ... | @@ -0,0 +1,40 @@ | ||
| 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 | ||
| 10 | FileHeader: | ||
| 11 | Class: ELFCLASS64 | ||
| 12 | Data: ELFDATA2LSB | ||
| 13 | OSABI: ELFOSABI_FREEBSD | ||
| 14 | Type: ET_REL | ||
| 15 | Machine: EM_X86_64 | ||
| 16 | Sections: | ||
| 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 created+52| ... | @@ -0,0 +1,52 @@ | ||
| 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 type of | ||
| 5 | # the relocations of which differ. | ||
| 6 | |||
| 7 | # CHECK-NOT: selected | ||
| 8 | |||
| 9 | !ELF | ||
| 10 | FileHeader: | ||
| 11 | Class: ELFCLASS64 | ||
| 12 | Data: ELFDATA2LSB | ||
| 13 | OSABI: ELFOSABI_FREEBSD | ||
| 14 | Type: ET_REL | ||
| 15 | Machine: EM_X86_64 | ||
| 16 | Sections: | ||
| 17 | - Type: SHT_PROGBITS | ||
| 18 | Name: .text | ||
| 19 | Flags: [ SHF_ALLOC, SHF_EXECINSTR ] | ||
| 20 | AddressAlign: 0x04 | ||
| 21 | Content: "0000000000000000" | ||
| 22 | - Name: .text.foo | ||
| 23 | Type: SHT_PROGBITS | ||
| 24 | Flags: [ SHF_ALLOC, SHF_EXECINSTR] | ||
| 25 | Content: "FFFFFFFFFFFFFFFF" | ||
| 26 | - Name: .text.bar | ||
| 27 | Type: SHT_PROGBITS | ||
| 28 | Flags: [ SHF_ALLOC, SHF_EXECINSTR] | ||
| 29 | Content: "FFFFFFFFFFFFFFFF" | ||
| 30 | - Name: .rela.text.foo | ||
| 31 | Type: SHT_RELA | ||
| 32 | Link: .symtab | ||
| 33 | Info: .text.foo | ||
| 34 | Relocations: | ||
| 35 | - Offset: 0x0000000000000000 | ||
| 36 | Symbol: '' | ||
| 37 | Type: R_X86_64_NONE | ||
| 38 | - Name: .rela.text.bar | ||
| 39 | Type: SHT_RELA | ||
| 40 | Link: .symtab | ||
| 41 | Info: .text.bar | ||
| 42 | Relocations: | ||
| 43 | - Offset: 0 | ||
| 44 | Symbol: zed | ||
| 45 | Type: R_X86_64_64 | ||
| 46 | Symbols: | ||
| 47 | Global: | ||
| 48 | - Name: zed | ||
| 49 | Type: STT_FUNC | ||
| 50 | Section: .text | ||
| 51 | Value: 0x0 | ||
| 52 | Size: 8 | ||
deps/lld/test/ELF/icf12.s created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | ||
| 4 | # RUN: ld.lld %t1 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s | ||
| 5 | |||
| 6 | # Check that ICF does not merge 2 sections which relocations | ||
| 7 | # differs in addend only. | ||
| 8 | |||
| 9 | # CHECK-NOT: selected | ||
| 10 | |||
| 11 | .section .text | ||
| 12 | .globl _start | ||
| 13 | _start: | ||
| 14 | ret | ||
| 15 | |||
| 16 | .section .text.foo, "ax" | ||
| 17 | .quad _start + 1 | ||
| 18 | |||
| 19 | .section .text.bar, "ax" | ||
| 20 | .quad _start + 2 | ||
deps/lld/test/ELF/icf13.s created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | ||
| 2 | # RUN: ld.lld -shared -z notext %t1 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s | ||
| 3 | |||
| 4 | ## Check that ICF does not merge sections which relocations point to symbols | ||
| 5 | ## that are not of the regular defined kind. | ||
| 6 | |||
| 7 | # CHECK-NOT: selected | ||
| 8 | |||
| 9 | .globl und | ||
| 10 | |||
| 11 | .section .text | ||
| 12 | .globl _start | ||
| 13 | _start: | ||
| 14 | ret | ||
| 15 | |||
| 16 | .section .text.foo, "ax" | ||
| 17 | .quad _start | ||
| 18 | |||
| 19 | .section .text.bar, "ax" | ||
| 20 | .quad und | ||
deps/lld/test/ELF/icf14.s created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | ||
| 4 | # RUN: ld.lld %t1 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s | ||
| 5 | |||
| 6 | # Check that ICF does not merge 2 sections which relocations | ||
| 7 | # refer to symbols that live in sections of the different types | ||
| 8 | # (regular input section and mergeable input sections in this case). | ||
| 9 | |||
| 10 | # CHECK-NOT: selected | ||
| 11 | |||
| 12 | .section .text | ||
| 13 | .globl _start | ||
| 14 | _start: | ||
| 15 | ret | ||
| 16 | |||
| 17 | .section .rodata.str,"aMS",@progbits,1 | ||
| 18 | .globl rodata | ||
| 19 | rodata: | ||
| 20 | .asciz "foo" | ||
| 21 | |||
| 22 | .section .text.foo, "ax" | ||
| 23 | .quad rodata | ||
| 24 | |||
| 25 | .section .text.bar, "ax" | ||
| 26 | .quad _start | ||
deps/lld/test/ELF/icf15.s created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | ||
| 2 | # RUN: ld.lld %t1 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s | ||
| 3 | |||
| 4 | ## Check that ICF does not merge sections which relocations have equal addends, | ||
| 5 | ## but different target values. | ||
| 6 | |||
| 7 | # CHECK-NOT: selected | ||
| 8 | |||
| 9 | .globl und | ||
| 10 | |||
| 11 | .section .text | ||
| 12 | .globl foo | ||
| 13 | foo: | ||
| 14 | .byte 0 | ||
| 15 | .globl bar | ||
| 16 | bar: | ||
| 17 | .byte 0 | ||
| 18 | |||
| 19 | .section .text.foo, "ax" | ||
| 20 | .quad foo | ||
| 21 | |||
| 22 | .section .text.bar, "ax" | ||
| 23 | .quad bar | ||
deps/lld/test/ELF/icf16.s created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | ||
| 2 | # RUN: ld.lld -shared -z notext %t1 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s | ||
| 3 | |||
| 4 | ## ICF is able to merge sections which relocations referring regular input sections | ||
| 5 | ## or mergeable sections. .eh_frame is represented with a different kind of section, | ||
| 6 | ## here we check that ICF code is able to handle and will not merge sections which | ||
| 7 | ## relocations referring .eh_frame. | ||
| 8 | |||
| 9 | # CHECK-NOT: selected | ||
| 10 | |||
| 11 | .section ".eh_frame", "a", @progbits | ||
| 12 | .globl foo | ||
| 13 | foo: | ||
| 14 | .quad 0 | ||
| 15 | .globl bar | ||
| 16 | bar: | ||
| 17 | .quad 0 | ||
| 18 | |||
| 19 | .section .text.foo, "ax" | ||
| 20 | .quad foo | ||
| 21 | |||
| 22 | .section .text.bar, "ax" | ||
| 23 | .quad bar | ||
deps/lld/test/ELF/icf17.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | ||
| 2 | # RUN: ld.lld %t1 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s | ||
| 3 | |||
| 4 | # CHECK-NOT: selected | ||
| 5 | |||
| 6 | .section .text | ||
| 7 | .globl _start | ||
| 8 | _start: | ||
| 9 | ret | ||
| 10 | |||
| 11 | .section .aaa, "ax",%progbits,unique,1 | ||
| 12 | .quad _start | ||
| 13 | |||
| 14 | .section .aaa, "axS",%progbits,unique,2 | ||
| 15 | .quad _start | ||
deps/lld/test/ELF/icf2.s+3-3| ... | @@ -2,10 +2,10 @@ | ... | @@ -2,10 +2,10 @@ |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2 |
| 5 | # RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose 2>&1 | FileCheck %s | 5 | # RUN: ld.lld %t1 %t2 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: selected .text.f1 | 7 | # CHECK: selected section {{.*}}:(.text.f1) |
| 8 | # CHECK: removed .text.f2 | 8 | # CHECK: removing identical section {{.*}}:(.text.f2) |
| 9 | 9 | ||
| 10 | .globl _start, f1, f2 | 10 | .globl _start, f1, f2 |
| 11 | _start: | 11 | _start: |
deps/lld/test/ELF/icf3.s+3-3| ... | @@ -2,10 +2,10 @@ | ... | @@ -2,10 +2,10 @@ |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2 | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2 |
| 5 | # RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose 2>&1 | FileCheck %s | 5 | # RUN: ld.lld %t1 %t2 -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s |
| 6 | 6 | ||
| 7 | # CHECK-NOT: Selected .text.f1 | 7 | # CHECK-NOT: selected section '.text.f1' from file |
| 8 | # CHECK-NOT: Selected .text.f2 | 8 | # CHECK-NOT: selected section '.text.f2' from file |
| 9 | 9 | ||
| 10 | .globl _start, f1, f2 | 10 | .globl _start, f1, f2 |
| 11 | _start: | 11 | _start: |
deps/lld/test/ELF/icf4.s+3-3| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | 4 | # RUN: ld.lld %t -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s |
| 5 | 5 | ||
| 6 | # CHECK-NOT: Selected .text.f1 | 6 | # CHECK-NOT: selected section '.text.f1' |
| 7 | # CHECK-NOT: Selected .text.f2 | 7 | # CHECK-NOT: selected section '.text.f2' |
| 8 | 8 | ||
| 9 | .globl _start, f1, f2 | 9 | .globl _start, f1, f2 |
| 10 | _start: | 10 | _start: |
deps/lld/test/ELF/icf5.s+3-3| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | 4 | # RUN: ld.lld %t -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s |
| 5 | 5 | ||
| 6 | # CHECK-NOT: Selected .text.f1 | 6 | # CHECK-NOT: selected section '.text.f1' |
| 7 | # CHECK-NOT: Selected .text.f2 | 7 | # CHECK-NOT: selected section '.text.f2' |
| 8 | 8 | ||
| 9 | .globl _start, f1, f2 | 9 | .globl _start, f1, f2 |
| 10 | _start: | 10 | _start: |
deps/lld/test/ELF/icf6.s+3-3| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | 4 | # RUN: ld.lld %t -o /dev/null --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s |
| 5 | 5 | ||
| 6 | # CHECK-NOT: Selected .text.f1 | 6 | # CHECK-NOT: selected section '.text.f1' |
| 7 | # CHECK-NOT: Selected .text.f2 | 7 | # CHECK-NOT: selected section '.text.f2' |
| 8 | 8 | ||
| 9 | .globl _start, f1, f2 | 9 | .globl _start, f1, f2 |
| 10 | _start: | 10 | _start: |
deps/lld/test/ELF/icf7.s+3-3| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | 4 | # RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections | FileCheck %s |
| 5 | # RUN: llvm-objdump -t %t2 | FileCheck -check-prefix=ALIGN %s | 5 | # RUN: llvm-objdump -t %t2 | FileCheck -check-prefix=ALIGN %s |
| 6 | 6 | ||
| 7 | # CHECK: selected .text.f1 | 7 | # CHECK: selected section {{.*}}:(.text.f1) |
| 8 | # CHECK: removed .text.f2 | 8 | # CHECK: removing identical section {{.*}}:(.text.f2) |
| 9 | 9 | ||
| 10 | # ALIGN: 0000000000201000 .text 00000000 _start | 10 | # ALIGN: 0000000000201000 .text 00000000 _start |
| 11 | # ALIGN: 0000000000201100 .text 00000000 f1 | 11 | # ALIGN: 0000000000201100 .text 00000000 f1 |
deps/lld/test/ELF/icf9.s+7-6| ... | @@ -2,20 +2,21 @@ | ... | @@ -2,20 +2,21 @@ |
| 2 | 2 | ||
| 3 | ### Make sure that we do not merge data. | 3 | ### Make sure that we do not merge data. |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 5 | # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s | 5 | # RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections 2>&1 | FileCheck -allow-empty %s |
| 6 | # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=SEC %s | 6 | # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=SEC %s |
| 7 | 7 | ||
| 8 | # SEC: .rodata PROGBITS 0000000000200120 000120 000002 00 A 0 0 1 | 8 | # SEC: .rodata PROGBITS 0000000000200120 000120 000002 00 A 0 0 1 |
| 9 | 9 | ||
| 10 | # CHECK-NOT: selected .rodata.d1 | 10 | # CHECK-NOT: selected section {{.*}}:(.rodata.d1) |
| 11 | # CHECK-NOT: selected .rodata.d2 | 11 | # CHECK-NOT: selected section {{.*}}:(.rodata.d2) |
| 12 | 12 | ||
| 13 | # We do merge rodata if passed --icf-data | 13 | # We do merge rodata if passed --icf-data |
| 14 | # RUN: ld.lld %t -o %t2 --icf=all --verbose --icf-data 2>&1 | FileCheck --check-prefix=DATA %s | 14 | # RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections --ignore-data-address-equality | \ |
| 15 | # RUN: FileCheck --check-prefix=DATA %s | ||
| 15 | # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=DATA-SEC %s | 16 | # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=DATA-SEC %s |
| 16 | 17 | ||
| 17 | # DATA: selected .rodata.d1 | 18 | # DATA: selected section {{.*}}:(.rodata.d1) |
| 18 | # DATA: removed .rodata.d2 | 19 | # DATA: removing identical section {{.*}}:(.rodata.d2) |
| 19 | 20 | ||
| 20 | # DATA-SEC: .rodata PROGBITS 0000000000200120 000120 000001 00 A 0 0 1 | 21 | # DATA-SEC: .rodata PROGBITS 0000000000200120 000120 000001 00 A 0 0 1 |
| 21 | 22 |
deps/lld/test/ELF/ignore-plugin.test created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | RUN: not ld.lld --plugin foo 2>&1 | FileCheck %s | ||
| 2 | CHECK: no input files | ||
deps/lld/test/ELF/incompatible-ar-first.s+2-2| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive.s -o %ta.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive.s -o %ta.o |
| 2 | // RUN: llvm-ar rc %t.a %ta.o | 3 | // RUN: llvm-ar rc %t.a %ta.o |
| 3 | // RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o | 4 | // RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o |
| 4 | // RUN: not ld.lld %t.a %tb.o 2>&1 | FileCheck %s | 5 | // RUN: not ld.lld %t.a %tb.o -o /dev/null 2>&1 | FileCheck %s |
| 5 | 6 | ||
| 6 | // We used to crash when | 7 | // We used to crash when |
| 7 | // * The first object seen by the symbol table is from an archive. | 8 | // * The first object seen by the symbol table is from an archive. |
| 8 | // * -m was not used. | 9 | // * -m was not used. |
| 9 | // CHECK: .a({{.*}}a.o) is incompatible with {{.*}}b.o | 10 | // CHECK: .a({{.*}}a.o) is incompatible with {{.*}}b.o |
| 10 | 11 | ||
| 11 | // REQUIRES: x86 |
deps/lld/test/ELF/incompatible-section-flags.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 3 | 4 | ||
| 4 | // CHECK: error: incompatible section flags for .foo | 5 | // CHECK: error: incompatible section flags for .foo |
| 5 | // CHECK-NEXT: >>> {{.*}}incompatible-section-flags.s.tmp.o:(.foo): 0x3 | 6 | // CHECK-NEXT: >>> {{.*}}incompatible-section-flags.s.tmp.o:(.foo): 0x3 |
deps/lld/test/ELF/incompatible-section-types2.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s |
| 3 | 4 | ||
| 4 | // CHECK: error: section type mismatch for .shstrtab | 5 | // CHECK: error: section type mismatch for .shstrtab |
| 5 | // CHECK-NEXT: >>> <internal>:(.shstrtab): SHT_STRTAB | 6 | // CHECK-NEXT: >>> <internal>:(.shstrtab): SHT_STRTAB |
deps/lld/test/ELF/incompatible.s+2-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86,aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %ta.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %ta.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tb.o | 3 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tb.o |
| 3 | // RUN: ld.lld -shared %tb.o -o %ti686.so | 4 | // RUN: ld.lld -shared %tb.o -o %ti686.so |
| ... | @@ -49,11 +50,10 @@ | ... | @@ -49,11 +50,10 @@ |
| 49 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive2.s -o %ta.o | 50 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive2.s -o %ta.o |
| 50 | // RUN: llvm-ar rc %t.a %ta.o | 51 | // RUN: llvm-ar rc %t.a %ta.o |
| 51 | // RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o | 52 | // RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o |
| 52 | // RUN: not ld.lld %t.a %tb.o 2>&1 | FileCheck --check-prefix=ARCHIVE %s | 53 | // RUN: not ld.lld %t.a %tb.o 2>&1 -o %t | FileCheck --check-prefix=ARCHIVE %s |
| 53 | // ARCHIVE: .a({{.*}}a.o) is incompatible with {{.*}}b.o | 54 | // ARCHIVE: .a({{.*}}a.o) is incompatible with {{.*}}b.o |
| 54 | .global _start | 55 | .global _start |
| 55 | _start: | 56 | _start: |
| 56 | .data | 57 | .data |
| 57 | .long foo | 58 | .long foo |
| 58 | 59 | ||
| 59 | // REQUIRES: x86,aarch64 |
deps/lld/test/ELF/init_fini_priority.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | // RUN: llvm-objdump -section-headers %t | FileCheck %s --check-prefix=OBJ | 3 | // RUN: llvm-objdump -section-headers %t | FileCheck %s --check-prefix=OBJ |
| 3 | // RUN: ld.lld %t -o %t.exe | 4 | // RUN: ld.lld %t -o %t.exe |
| 4 | // RUN: llvm-objdump -s %t.exe | FileCheck %s | 5 | // RUN: llvm-objdump -s %t.exe | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // OBJ: 3 .init_array | 7 | // OBJ: 3 .init_array |
| 8 | // OBJ-NEXT: 4 .init_array.100 | 8 | // OBJ-NEXT: 4 .init_array.100 |
deps/lld/test/ELF/invalid-cie-length.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | 2 | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 4 | // RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | .section .eh_frame | 6 | .section .eh_frame |
| 7 | .byte 0 | 7 | .byte 0 |
deps/lld/test/ELF/invalid-cie-length2.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | 2 | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 4 | // RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | .section .eh_frame | 6 | .section .eh_frame |
| 7 | .long 42 | 7 | .long 42 |
deps/lld/test/ELF/invalid-cie-length3.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | 2 | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 4 | // RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | .section .eh_frame | 6 | .section .eh_frame |
| 7 | .long 0xFFFFFFFC | 7 | .long 0xFFFFFFFC |
deps/lld/test/ELF/invalid-cie-length4.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | 2 | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 4 | // RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | .section .eh_frame | 6 | .section .eh_frame |
| 7 | .long 0xFFFFFFFF | 7 | .long 0xFFFFFFFF |
deps/lld/test/ELF/invalid-cie-length5.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | 2 | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 4 | // RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | .section .eh_frame | 6 | .section .eh_frame |
| 7 | .long 0xFFFFFFFF | 7 | .long 0xFFFFFFFF |
deps/lld/test/ELF/invalid-cie-reference.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | 2 | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 4 | // RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | .section .eh_frame | 6 | .section .eh_frame |
| 7 | .long 0x14 | 7 | .long 0x14 |
deps/lld/test/ELF/invalid-eh-frame.s created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: corrupted .eh_frame: unexpected end of CIE | ||
| 7 | # CHECK-NEXT: >>> defined in {{.*}}:(.eh_frame+0x8) | ||
| 8 | |||
| 9 | .section .eh_frame | ||
| 10 | .byte 0x04 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x00 | ||
| 17 | .byte 0x00 | ||
deps/lld/test/ELF/invalid-eh-frame2.s created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: corrupted .eh_frame: corrupted CIE (failed to read string) | ||
| 7 | # CHECK-NEXT: >>> defined in {{.*}}:(.eh_frame+0x9) | ||
| 8 | |||
| 9 | .section .eh_frame | ||
| 10 | .align 1 | ||
| 11 | .byte 0x08 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x00 | ||
| 17 | .byte 0x00 | ||
| 18 | .byte 0x00 | ||
| 19 | .byte 0x01 | ||
| 20 | .byte 0x01 | ||
| 21 | .byte 0x01 | ||
| 22 | .byte 0x01 | ||
deps/lld/test/ELF/invalid-eh-frame3.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: corrupted .eh_frame: corrupted CIE (failed to read LEB128) | ||
| 7 | # CHECK-NEXT: >>> defined in {{.*}}:(.eh_frame+0xC) | ||
| 8 | |||
| 9 | .section .eh_frame | ||
| 10 | .byte 0x08 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x00 | ||
| 17 | .byte 0x00 | ||
| 18 | .byte 0x01 | ||
| 19 | .byte 0x01 | ||
| 20 | .byte 0x00 | ||
| 21 | .byte 0x01 | ||
deps/lld/test/ELF/invalid-eh-frame4.s created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: corrupted .eh_frame: unknown .eh_frame augmentation string: | ||
| 7 | |||
| 8 | .section .eh_frame | ||
| 9 | .byte 0x0E | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x00 | ||
| 17 | .byte 0x01 | ||
| 18 | .byte 0x01 | ||
| 19 | .byte 0x00 | ||
| 20 | .byte 0x01 | ||
| 21 | |||
| 22 | .byte 0x01 # LEB128 | ||
| 23 | .byte 0x01 # LEB128 | ||
| 24 | |||
| 25 | .byte 0x01 | ||
| 26 | .byte 0x01 | ||
| 27 | .byte 0x01 | ||
| 28 | .byte 0x01 | ||
deps/lld/test/ELF/invalid-eh-frame5.s created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: corrupted .eh_frame: unknown .eh_frame augmentation string: | ||
| 7 | |||
| 8 | .section .eh_frame | ||
| 9 | .byte 0x0E | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x00 | ||
| 17 | .byte 0x03 | ||
| 18 | .byte 0x01 | ||
| 19 | .byte 0x00 | ||
| 20 | .byte 0x01 | ||
| 21 | |||
| 22 | .byte 0x01 # LEB128 | ||
| 23 | .byte 0x01 # LEB128 | ||
| 24 | |||
| 25 | .byte 0x01 | ||
| 26 | .byte 0x01 | ||
| 27 | .byte 0x01 | ||
| 28 | .byte 0x01 | ||
deps/lld/test/ELF/invalid-eh-frame6.s created+31| ... | @@ -0,0 +1,31 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: corrupted .eh_frame: unknown FDE encoding | ||
| 7 | # CHECK-NEXT: >>> defined in {{.*}}:(.eh_frame+0xE) | ||
| 8 | |||
| 9 | .section .eh_frame | ||
| 10 | .byte 0x0E | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x00 | ||
| 17 | .byte 0x00 | ||
| 18 | .byte 0x01 | ||
| 19 | |||
| 20 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 21 | .byte 0x00 | ||
| 22 | |||
| 23 | .byte 0x01 | ||
| 24 | |||
| 25 | .byte 0x01 # LEB128 | ||
| 26 | .byte 0x01 # LEB128 | ||
| 27 | |||
| 28 | .byte 0x01 | ||
| 29 | .byte 0x01 | ||
| 30 | .byte 0x01 | ||
| 31 | .byte 0x01 | ||
deps/lld/test/ELF/invalid-eh-frame7.s created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: corrupted .eh_frame: DW_EH_PE_aligned encoding is not supported | ||
| 7 | |||
| 8 | .section .eh_frame | ||
| 9 | .byte 0x0E | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x00 | ||
| 17 | .byte 0x01 | ||
| 18 | |||
| 19 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 20 | .byte 0x00 | ||
| 21 | |||
| 22 | .byte 0x01 | ||
| 23 | |||
| 24 | .byte 0x01 # LEB128 | ||
| 25 | .byte 0x01 # LEB128 | ||
| 26 | |||
| 27 | .byte 0x51 | ||
| 28 | .byte 0x01 | ||
| 29 | .byte 0x01 | ||
| 30 | .byte 0x01 | ||
deps/lld/test/ELF/invalid-eh-frame8.s created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: corrupted .eh_frame: corrupted CIE | ||
| 7 | |||
| 8 | .section .eh_frame | ||
| 9 | .byte 0x0E | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x00 | ||
| 17 | .byte 0x01 | ||
| 18 | |||
| 19 | .byte 0x50 # Augmentation string: 'P','\0' | ||
| 20 | .byte 0x00 | ||
| 21 | |||
| 22 | .byte 0x01 | ||
| 23 | |||
| 24 | .byte 0x01 # LEB128 | ||
| 25 | .byte 0x01 # LEB128 | ||
| 26 | |||
| 27 | .byte 0x03 | ||
| 28 | .byte 0x01 | ||
| 29 | .byte 0x01 | ||
| 30 | .byte 0x01 | ||
deps/lld/test/ELF/invalid-eh-frame9.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: corrupted .eh_frame: CIE is too small | ||
| 7 | |||
| 8 | .section .eh_frame | ||
| 9 | .byte 0x03 | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
deps/lld/test/ELF/invalid-fde-rel.s+1-1| ... | @@ -33,4 +33,4 @@ | ... | @@ -33,4 +33,4 @@ |
| 33 | .long 0x0 | 33 | .long 0x0 |
| 34 | .long 0x0 | 34 | .long 0x0 |
| 35 | 35 | ||
| 36 | // CHECK: 1 .eh_frame 00000018 | 36 | // CHECK: 1 .eh_frame 0000001c |
deps/lld/test/ELF/invalid-relocations.test+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: yaml2obj %s -o %t | 1 | # RUN: yaml2obj %s -o %t |
| 2 | # RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s | 2 | # RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 3 | 3 | ||
| 4 | !ELF | 4 | !ELF |
| 5 | FileHeader: | 5 | FileHeader: |
deps/lld/test/ELF/invalid-undef-section-symbol.test+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: yaml2obj %s -o %t.o | 1 | # RUN: yaml2obj %s -o %t.o |
| 2 | # RUN: not ld.lld -r %t.o -o %2.o 2>&1 | FileCheck %s | 2 | # RUN: not ld.lld -r %t.o -o /dev/null 2>&1 | FileCheck %s |
| 3 | 3 | ||
| 4 | # We used to crash at this. | 4 | # We used to crash at this. |
| 5 | # CHECK: STT_SECTION symbol should be defined | 5 | # CHECK: STT_SECTION symbol should be defined |
deps/lld/test/ELF/invalid-z.s deleted-9| ... | @@ -1,9 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o -o %t -z max-page-size 2>&1 | FileCheck %s | ||
| 4 | # CHECK: invalid max-page-size | ||
| 5 | # CHECK-NOT: error | ||
| 6 | |||
| 7 | .global _start | ||
| 8 | _start: | ||
| 9 | nop | ||
deps/lld/test/ELF/invalid/Inputs/cie-version2.elf deleted| Binary files a/deps/lld/test/ELF/invalid/Inputs/cie-version2.elf and /dev/null differ | |||
deps/lld/test/ELF/invalid/Inputs/too-short.elf deleted| Binary files a/deps/lld/test/ELF/invalid/Inputs/too-short.elf and /dev/null differ | |||
deps/lld/test/ELF/invalid/dynamic-section-size.s+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | ## dynamic-section-sh_size.elf has incorrect sh_size of dynamic section. | 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 %t2 2>&1 | \ | 2 | # RUN: not ld.lld %p/Inputs/dynamic-section-sh_size.elf -o /dev/null 2>&1 | \ |
| 3 | # RUN: FileCheck %s | 3 | # RUN: FileCheck %s |
| 4 | # CHECK: error: {{.*}}: invalid sh_entsize | 4 | # CHECK: error: {{.*}}: invalid sh_entsize |
deps/lld/test/ELF/invalid/eh-frame-hdr-no-out.s+17-4| ... | @@ -1,6 +1,19 @@ | ... | @@ -1,6 +1,19 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: not ld.lld --eh-frame-hdr %p/Inputs/cie-version2.elf -o %t >& %t.log | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | // RUN: FileCheck %s < %t.log | 3 | // RUN: not ld.lld --eh-frame-hdr %t -o /dev/null 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | // cie-version2.elf contains unsupported version of CIE = 2. | 5 | // CHECK: error: corrupted .eh_frame: FDE version 1 or 3 expected, but got 2 |
| 6 | // CHECK: FDE version 1 or 3 expected, but got 2 | 6 | |
| 7 | .section .eh_frame | ||
| 8 | .byte 0x08 | ||
| 9 | .byte 0x00 | ||
| 10 | .byte 0x00 | ||
| 11 | .byte 0x00 | ||
| 12 | .byte 0x00 | ||
| 13 | .byte 0x00 | ||
| 14 | .byte 0x00 | ||
| 15 | .byte 0x00 | ||
| 16 | .byte 0x02 | ||
| 17 | .byte 0x00 | ||
| 18 | .byte 0x00 | ||
| 19 | .byte 0x00 |
deps/lld/test/ELF/invalid/executable.s created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t1.exe %t.o | ||
| 4 | # RUN: not ld.lld -o /dev/null %t1.exe 2>&1 | FileCheck %s | ||
| 5 | # CHECK: unknown file type | ||
| 6 | |||
| 7 | .global _start | ||
| 8 | _start: | ||
| 9 | ret | ||
deps/lld/test/ELF/invalid/invalid-e_shnum.s+1-1| ... | @@ -1,3 +1,3 @@ | ... | @@ -1,3 +1,3 @@ |
| 1 | ## Spec says that "If a file has no section header table, e_shnum holds the value zero.", though | 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. | 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 %t2 | 3 | # RUN: ld.lld %p/Inputs/invalid-e_shnum.elf -o /dev/null |
deps/lld/test/ELF/invalid/invalid-elf.test+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc %s -o %t -filetype=obj -triple x86_64-pc-linux | 2 | # RUN: llvm-mc %s -o %t -filetype=obj -triple x86_64-pc-linux |
| 2 | 3 | ||
| 3 | # RUN: not ld.lld %t %p/Inputs/data-encoding.a -o %t2 2>&1 | \ | 4 | # RUN: not ld.lld %t %p/Inputs/data-encoding.a -o %t2 2>&1 | \ |
deps/lld/test/ELF/invalid/merge-invalid-size.s+2-2| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | // RUN: not ld.lld %t.o -o %t.so 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: SHF_MERGE section size must be a multiple of sh_entsize | 4 | // CHECK: SHF_MERGE section size must be a multiple of sh_entsize |
| 5 | 5 | ||
| 6 | // Test that we accept a zero sh_entsize. | 6 | // Test that we accept a zero sh_entsize. |
| 7 | // RUN: ld.lld %p/Inputs/shentsize-zero.elf -o %t2 | 7 | // RUN: ld.lld %p/Inputs/shentsize-zero.elf -o /dev/null |
| 8 | 8 | ||
| 9 | .section .foo,"aM",@progbits,4 | 9 | .section .foo,"aM",@progbits,4 |
| 10 | .short 42 | 10 | .short 42 |
deps/lld/test/ELF/invalid/mips-invalid-options-descriptor.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | ## mips-invalid-options-descriptor.elf has option descriptor in | 1 | ## mips-invalid-options-descriptor.elf has option descriptor in |
| 2 | ## .MIPS.options with size of zero. | 2 | ## .MIPS.options with size of zero. |
| 3 | # RUN: not ld.lld %p/Inputs/mips-invalid-options-descriptor.elf -o %t2 2>&1 | \ | 3 | # RUN: not ld.lld %p/Inputs/mips-invalid-options-descriptor.elf -o /dev/null 2>&1 | \ |
| 4 | # RUN: FileCheck %s | 4 | # RUN: FileCheck %s |
| 5 | # CHECK: error: {{.*}}: invalid section offset | 5 | # CHECK: error: {{.*}}: invalid section offset |
deps/lld/test/ELF/invalid/reloc-section-reordered.test created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: yaml2obj %s -o %t.o | ||
| 4 | # RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s | ||
| 5 | # CHECK: unsupported relocation reference | ||
| 6 | |||
| 7 | ## YAML below lists .rela.text before .text, we do not support it. | ||
| 8 | |||
| 9 | !ELF | ||
| 10 | FileHeader: | ||
| 11 | Class: ELFCLASS64 | ||
| 12 | Data: ELFDATA2LSB | ||
| 13 | OSABI: ELFOSABI_FREEBSD | ||
| 14 | Type: ET_REL | ||
| 15 | Machine: EM_X86_64 | ||
| 16 | Sections: | ||
| 17 | - Type: SHT_REL | ||
| 18 | Name: .rela.text | ||
| 19 | Link: .symtab | ||
| 20 | Info: .text | ||
| 21 | AddressAlign: 0x04 | ||
| 22 | Relocations: | ||
| 23 | - Offset: 0 | ||
| 24 | Symbol: .text | ||
| 25 | Type: R_X86_64_NONE | ||
| 26 | - Type: SHT_PROGBITS | ||
| 27 | Name: .text | ||
| 28 | Flags: [ SHF_ALLOC, SHF_EXECINSTR ] | ||
| 29 | AddressAlign: 0x04 | ||
| 30 | Content: "FFFFFFFFFFFFFFFF" | ||
deps/lld/test/ELF/invalid/section-alignment2.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | ## section-alignment-notpow2.elf has section alignment | 1 | ## section-alignment-notpow2.elf has section alignment |
| 2 | ## 0xFFFFFFFF which is not a power of 2. | 2 | ## 0xFFFFFFFF which is not a power of 2. |
| 3 | # RUN: not ld.lld %p/Inputs/section-alignment-notpow2.elf -o %t2 2>&1 | \ | 3 | # RUN: not ld.lld %p/Inputs/section-alignment-notpow2.elf -o /dev/null 2>&1 | \ |
| 4 | # RUN: FileCheck %s | 4 | # RUN: FileCheck %s |
| 5 | # CHECK: section sh_addralign is not a power of 2 | 5 | # CHECK: section sh_addralign is not a power of 2 |
deps/lld/test/ELF/invalid/sht-group.s+1-1| ... | @@ -1,3 +1,3 @@ | ... | @@ -1,3 +1,3 @@ |
| 1 | ## sht-group.elf contains SHT_GROUP section with invalid sh_info. | 1 | ## sht-group.elf contains SHT_GROUP section with invalid sh_info. |
| 2 | # RUN: not ld.lld %p/Inputs/sht-group.elf -o %t2 2>&1 | FileCheck %s | 2 | # RUN: not ld.lld %p/Inputs/sht-group.elf -o /dev/null 2>&1 | FileCheck %s |
| 3 | # CHECK: invalid symbol index | 3 | # CHECK: invalid symbol index |
deps/lld/test/ELF/invalid/symbol-index.s+1-1| ... | @@ -5,6 +5,6 @@ | ... | @@ -5,6 +5,6 @@ |
| 5 | ## [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 | 5 | ## [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 |
| 6 | ## ... | 6 | ## ... |
| 7 | ## [ 4] .symtab RELA 0000000000000000 000048 000030 18 1 2 8 | 7 | ## [ 4] .symtab RELA 0000000000000000 000048 000030 18 1 2 8 |
| 8 | # RUN: not ld.lld %p/Inputs/symbol-index.elf -o %t2 2>&1 | \ | 8 | # RUN: not ld.lld %p/Inputs/symbol-index.elf -o /dev/null 2>&1 | \ |
| 9 | # RUN: FileCheck --check-prefix=INVALID-SYMBOL-INDEX %s | 9 | # RUN: FileCheck --check-prefix=INVALID-SYMBOL-INDEX %s |
| 10 | # INVALID-SYMBOL-INDEX: invalid symbol index | 10 | # INVALID-SYMBOL-INDEX: invalid symbol index |
deps/lld/test/ELF/invalid/symbol-name.s+1-1| ... | @@ -3,5 +3,5 @@ | ... | @@ -3,5 +3,5 @@ |
| 3 | ## symbol-name-offset.elf contains symbol with invalid (too large) | 3 | ## symbol-name-offset.elf contains symbol with invalid (too large) |
| 4 | ## st_name value. | 4 | ## st_name value. |
| 5 | # RUN: not ld.lld %S/Inputs/symbol-name-offset.elf \ | 5 | # RUN: not ld.lld %S/Inputs/symbol-name-offset.elf \ |
| 6 | # RUN: -o %t 2>&1 | FileCheck %s | 6 | # RUN: -o /dev/null 2>&1 | FileCheck %s |
| 7 | # CHECK: invalid symbol name offset | 7 | # CHECK: invalid symbol name offset |
deps/lld/test/ELF/invalid/tls-symbol.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | ## The test file contains an STT_TLS symbol but has no TLS section. | 3 | ## The test file contains an STT_TLS symbol but has no TLS section. |
| 4 | # RUN: not ld.lld %S/Inputs/tls-symbol.elf -o %t 2>&1 | FileCheck %s | 4 | # RUN: not ld.lld %S/Inputs/tls-symbol.elf -o /dev/null 2>&1 | FileCheck %s |
| 5 | # CHECK: has an STT_TLS symbol but doesn't have an SHF_TLS section | 5 | # CHECK: has an STT_TLS symbol but doesn't have an SHF_TLS section |
deps/lld/test/ELF/invalid/too-short.s deleted-5| ... | @@ -1,5 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | ## too-short.elf file is a truncated ELF. | ||
| 4 | # RUN: not ld.lld %S/Inputs/too-short.elf -o %t 2>&1 | FileCheck %s | ||
| 5 | # CHECK: file is too short | ||
deps/lld/test/ELF/just-symbols-cref.s created+20| ... | @@ -0,0 +1,20 @@ | ||
| 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.exe -Ttext=0x10000 | ||
| 5 | |||
| 6 | # RUN: ld.lld -just-symbols=%t1.exe -o %t2.exe -cref | FileCheck %s | ||
| 7 | |||
| 8 | # CHECK: Symbol File | ||
| 9 | # CHECK-NEXT: bar {{.*exe}} | ||
| 10 | # CHECK-NEXT: foo {{.*exe}} | ||
| 11 | |||
| 12 | .globl foo, bar | ||
| 13 | foo: | ||
| 14 | ret | ||
| 15 | |||
| 16 | .section .data | ||
| 17 | .type bar, @object | ||
| 18 | .size bar, 40 | ||
| 19 | bar: | ||
| 20 | .zero 40 | ||
deps/lld/test/ELF/just-symbols.s created+20| ... | @@ -0,0 +1,20 @@ | ||
| 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.exe -Ttext=0x10000 | ||
| 5 | |||
| 6 | # RUN: ld.lld -just-symbols=%t1.exe -o %t2.exe | ||
| 7 | # RUN: llvm-readelf -symbols %t2.exe | FileCheck %s | ||
| 8 | |||
| 9 | # CHECK: 0000000000011000 40 OBJECT GLOBAL DEFAULT ABS bar | ||
| 10 | # CHECK: 0000000000010000 0 NOTYPE GLOBAL DEFAULT ABS foo | ||
| 11 | |||
| 12 | .globl foo, bar | ||
| 13 | foo: | ||
| 14 | ret | ||
| 15 | |||
| 16 | .section .data | ||
| 17 | .type bar, @object | ||
| 18 | .size bar, 40 | ||
| 19 | bar: | ||
| 20 | .zero 40 | ||
deps/lld/test/ELF/libsearch.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 3 | // RUN: %p/Inputs/libsearch-dyn.s -o %tdyn.o | 4 | // RUN: %p/Inputs/libsearch-dyn.s -o %tdyn.o |
| ... | @@ -10,7 +11,6 @@ | ... | @@ -10,7 +11,6 @@ |
| 10 | // RUN: cp -f %t.dir/libls.so %t.dir/libls2.so | 11 | // RUN: cp -f %t.dir/libls.so %t.dir/libls2.so |
| 11 | // RUN: rm -f %t.dir/libls.a | 12 | // RUN: rm -f %t.dir/libls.a |
| 12 | // RUN: llvm-ar rcs %t.dir/libls.a %tst.o | 13 | // RUN: llvm-ar rcs %t.dir/libls.a %tst.o |
| 13 | // REQUIRES: x86 | ||
| 14 | 14 | ||
| 15 | // Should fail if no library specified | 15 | // Should fail if no library specified |
| 16 | // RUN: not ld.lld -l 2>&1 \ | 16 | // RUN: not ld.lld -l 2>&1 \ |
deps/lld/test/ELF/linkerscript/Inputs/addr.s created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | .text | ||
| 2 | .globl _start | ||
| 3 | _start: | ||
| 4 | |||
| 5 | .section .foo.1,"a" | ||
| 6 | .quad 1 | ||
| 7 | |||
| 8 | .section .foo.2,"a" | ||
| 9 | .quad 2 | ||
| 10 | |||
| 11 | .section .foo.3,"a" | ||
| 12 | .quad 3 | ||
deps/lld/test/ELF/linkerscript/Inputs/align.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | .global _start | ||
| 2 | _start: | ||
| 3 | nop | ||
| 4 | |||
| 5 | .section .aaa, "a" | ||
| 6 | .quad 0 | ||
| 7 | |||
| 8 | .section .bbb, "a" | ||
| 9 | .quad 0 | ||
| 10 | |||
| 11 | .section .ccc, "a" | ||
| 12 | .quad 0 | ||
| 13 | |||
deps/lld/test/ELF/linkerscript/Inputs/alignof.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | .global _start | ||
| 2 | _start: | ||
| 3 | nop | ||
| 4 | |||
| 5 | .section .aaa,"a" | ||
| 6 | .align 8 | ||
| 7 | .quad 0 | ||
| 8 | |||
| 9 | .section .bbb,"a" | ||
| 10 | .align 16 | ||
| 11 | .quad 0 | ||
| 12 | |||
| 13 | .section .ccc,"a" | ||
| 14 | .align 32 | ||
| 15 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/Inputs/at2.s created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | .section .foo1, "ax" | ||
| 2 | .quad 0 | ||
| 3 | |||
| 4 | .section .foo2, "ax" | ||
| 5 | .quad 0 | ||
| 6 | |||
| 7 | .section .bar1, "aw" | ||
| 8 | .quad 0 | ||
| 9 | |||
| 10 | .section .bar2, "aw" | ||
| 11 | .quad 0 | ||
| 12 | |||
| 13 | .section .bar3, "aw" | ||
| 14 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/Inputs/at3.s created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | .section .foo1, "a" | ||
| 2 | .quad 0 | ||
| 3 | |||
| 4 | .section .foo2, "ax" | ||
| 5 | .quad 0 | ||
| 6 | |||
| 7 | .section .foo3, "ax" | ||
| 8 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/Inputs/data-commands.s created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | .global a | ||
| 2 | a = 0x11 | ||
| 3 | |||
| 4 | .global b | ||
| 5 | b = 0x1122 | ||
| 6 | |||
| 7 | .global c | ||
| 8 | c = 0x11223344 | ||
| 9 | |||
| 10 | .global d | ||
| 11 | d = 0x1122334455667788 | ||
| 12 | |||
| 13 | .section .foo.1, "a" | ||
| 14 | .byte 0xFF | ||
| 15 | |||
| 16 | .section .foo.2, "a" | ||
| 17 | .byte 0xFF | ||
| 18 | |||
| 19 | .section .foo.3, "a" | ||
| 20 | .byte 0xFF | ||
| 21 | |||
| 22 | .section .foo.4, "a" | ||
| 23 | .byte 0xFF | ||
| 24 | |||
| 25 | .section .bar.1, "a" | ||
| 26 | .byte 0xFF | ||
| 27 | |||
| 28 | .section .bar.2, "a" | ||
| 29 | .byte 0xFF | ||
| 30 | |||
| 31 | .section .bar.3, "a" | ||
| 32 | .byte 0xFF | ||
| 33 | |||
| 34 | .section .bar.4, "a" | ||
| 35 | .byte 0xFF | ||
deps/lld/test/ELF/linkerscript/Inputs/data-segment-relro.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | .global _start | ||
| 2 | _start: | ||
| 3 | .long bar | ||
| 4 | jmp *bar2@GOTPCREL(%rip) | ||
| 5 | |||
| 6 | .section .data,"aw" | ||
| 7 | .quad 0 | ||
| 8 | |||
| 9 | .zero 4 | ||
| 10 | .section .foo,"aw" | ||
| 11 | .section .bss,"",@nobits | ||
deps/lld/test/ELF/linkerscript/Inputs/define.s created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | .global defined | ||
| 2 | defined = 0 | ||
| 3 | |||
| 4 | .section .foo,"a" | ||
| 5 | .quad 1 | ||
| 6 | |||
| 7 | .section .bar,"a" | ||
| 8 | .quad 1 | ||
deps/lld/test/ELF/linkerscript/Inputs/eh-frame-reloc-out-of-range.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | .text | ||
| 2 | .globl _start | ||
| 3 | _start: | ||
| 4 | .cfi_startproc | ||
| 5 | .cfi_lsda 0, _ex | ||
| 6 | nop | ||
| 7 | .cfi_endproc | ||
| 8 | |||
| 9 | .data | ||
| 10 | _ex: | ||
| 11 | .word 0 | ||
deps/lld/test/ELF/linkerscript/Inputs/extend-pt-load.s created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | nop | ||
| 2 | .section .data.rel.ro, "aw" | ||
| 3 | .byte 0 | ||
deps/lld/test/ELF/linkerscript/Inputs/fill.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | .text | ||
| 2 | .globl _start | ||
| 3 | _start: | ||
| 4 | |||
| 5 | .section .aaa, "a" | ||
| 6 | .align 1 | ||
| 7 | .byte 0xAA | ||
| 8 | |||
| 9 | .section .bbb, "a" | ||
| 10 | .align 1 | ||
| 11 | .byte 0xBB | ||
deps/lld/test/ELF/linkerscript/Inputs/implicit-program-header.script deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | PHDRS | ||
| 2 | { | ||
| 3 | 	ph_write PT_LOAD FLAGS(2); | ||
| 4 | 	ph_exec PT_LOAD FLAGS(1); | ||
| 5 | } | ||
| 6 | |||
| 7 | SECTIONS | ||
| 8 | { | ||
| 9 | .bar : { *(.bar) } : ph_exec | ||
| 10 | .foo : { *(.foo) } | ||
| 11 | .text : { *(.text) } : ph_write | ||
| 12 | } | ||
deps/lld/test/ELF/linkerscript/Inputs/insert-after.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | .section .foo.text,"ax" | ||
| 2 | .quad 0 | ||
| 3 | |||
| 4 | .section .foo.data,"aw" | ||
| 5 | .quad 0 | ||
| 6 | |||
| 7 | .section .text.1,"ax" | ||
| 8 | .quad 0 | ||
| 9 | |||
| 10 | .section .data.1,"aw" | ||
| 11 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/Inputs/insert-after.script created+4| ... | @@ -0,0 +1,4 @@ | ||
| 1 | SECTIONS { | ||
| 2 | .text : { *(.text.*) } | ||
| 3 | .data : { *(.data.*) } | ||
| 4 | } | ||
deps/lld/test/ELF/linkerscript/Inputs/map-file2.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | .global _start | ||
| 2 | _start: | ||
| 3 | .global _Z1fi | ||
| 4 | _Z1fi: | ||
| 5 | .cfi_startproc | ||
| 6 | nop | ||
| 7 | .cfi_endproc | ||
| 8 | |||
| 9 | .section .aaa, "a"; | ||
| 10 | .quad 1; | ||
| 11 | |||
| 12 | .section .bbb, "a"; | ||
| 13 | .quad 2; | ||
| 14 | |||
| 15 | .section .ccc, "a"; | ||
| 16 | .quad 3; | ||
| 17 | |||
| 18 | .section .ddd, "a"; | ||
| 19 | .quad 4 | ||
deps/lld/test/ELF/linkerscript/Inputs/provide-shared2.s created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | .global foo | ||
| 2 | .data | ||
| 3 | .dc.a foo | ||
deps/lld/test/ELF/linkerscript/Inputs/sections-va-overflow.s created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | .global _start | ||
| 2 | _start: | ||
| 3 | retq | ||
| 4 | |||
| 5 | .bss | ||
| 6 | .space 0x2000 | ||
deps/lld/test/ELF/linkerscript/Inputs/synthetic-symbols.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | .global _start | ||
| 2 | _start: | ||
| 3 | nop | ||
| 4 | |||
| 5 | .section .foo,"a" | ||
| 6 | .quad 0 | ||
| 7 | |||
| 8 | .section .bar,"a" | ||
| 9 | .long 0 | ||
| 10 | |||
| 11 | .section .dah,"ax",@progbits | ||
| 12 | .cfi_startproc | ||
| 13 | nop | ||
| 14 | .cfi_endproc | ||
| 15 | |||
| 16 | .global _begin_sec, _end_sec, _end_sec_abs | ||
deps/lld/test/ELF/linkerscript/absolute-expr.s deleted-82| ... | @@ -1,82 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: .text : { \ | ||
| 5 | # RUN: bar1 = ALIGNOF(.text); \ | ||
| 6 | # RUN: bar2 = CONSTANT (MAXPAGESIZE); \ | ||
| 7 | # RUN: bar3 = SIZEOF (.text); \ | ||
| 8 | # RUN: bar4 = SIZEOF_HEADERS; \ | ||
| 9 | # RUN: bar5 = 0x42; \ | ||
| 10 | # RUN: bar6 = foo + 1; \ | ||
| 11 | # RUN: *(.text) \ | ||
| 12 | # RUN: } \ | ||
| 13 | # RUN: };" > %t.script | ||
| 14 | # RUN: ld.lld -o %t.so --script %t.script %t.o -shared | ||
| 15 | # RUN: llvm-readobj -t %t.so | FileCheck %s | ||
| 16 | |||
| 17 | .global foo | ||
| 18 | foo = 0x123 | ||
| 19 | |||
| 20 | # CHECK: Symbol { | ||
| 21 | # CHECK: Name: foo | ||
| 22 | # CHECK-NEXT: Value: 0x123 | ||
| 23 | # CHECK-NEXT: Size: 0 | ||
| 24 | # CHECK-NEXT: Binding: Global | ||
| 25 | # CHECK-NEXT: Type: None | ||
| 26 | # CHECK-NEXT: Other: 0 | ||
| 27 | # CHECK-NEXT: Section: Absolute (0xFFF1) | ||
| 28 | # CHECK-NEXT: } | ||
| 29 | # CHECK-NEXT: Symbol { | ||
| 30 | # CHECK-NEXT: Name: bar1 | ||
| 31 | # CHECK-NEXT: Value: 0x4 | ||
| 32 | # CHECK-NEXT: Size: 0 | ||
| 33 | # CHECK-NEXT: Binding: Global | ||
| 34 | # CHECK-NEXT: Type: None | ||
| 35 | # CHECK-NEXT: Other: 0 | ||
| 36 | # CHECK-NEXT: Section: Absolute | ||
| 37 | # CHECK-NEXT: } | ||
| 38 | # CHECK-NEXT: Symbol { | ||
| 39 | # CHECK-NEXT: Name: bar2 | ||
| 40 | # CHECK-NEXT: Value: 0x1000 | ||
| 41 | # CHECK-NEXT: Size: 0 | ||
| 42 | # CHECK-NEXT: Binding: Global | ||
| 43 | # CHECK-NEXT: Type: None | ||
| 44 | # CHECK-NEXT: Other: 0 | ||
| 45 | # CHECK-NEXT: Section: Absolute | ||
| 46 | # CHECK-NEXT: } | ||
| 47 | # CHECK-NEXT: Symbol { | ||
| 48 | # CHECK-NEXT: Name: bar3 | ||
| 49 | # CHECK-NEXT: Value: 0x0 | ||
| 50 | # CHECK-NEXT: Size: 0 | ||
| 51 | # CHECK-NEXT: Binding: Global | ||
| 52 | # CHECK-NEXT: Type: None | ||
| 53 | # CHECK-NEXT: Other: 0 | ||
| 54 | # CHECK-NEXT: Section: Absolute | ||
| 55 | # CHECK-NEXT: } | ||
| 56 | # CHECK-NEXT: Symbol { | ||
| 57 | # CHECK-NEXT: Name: bar4 | ||
| 58 | # CHECK-NEXT: Value: 0x190 | ||
| 59 | # CHECK-NEXT: Size: 0 | ||
| 60 | # CHECK-NEXT: Binding: Global | ||
| 61 | # CHECK-NEXT: Type: None | ||
| 62 | # CHECK-NEXT: Other: 0 | ||
| 63 | # CHECK-NEXT: Section: Absolute | ||
| 64 | # CHECK-NEXT: } | ||
| 65 | # CHECK-NEXT: Symbol { | ||
| 66 | # CHECK-NEXT: Name: bar5 | ||
| 67 | # CHECK-NEXT: Value: 0x42 | ||
| 68 | # CHECK-NEXT: Size: 0 | ||
| 69 | # CHECK-NEXT: Binding: Global | ||
| 70 | # CHECK-NEXT: Type: None | ||
| 71 | # CHECK-NEXT: Other: 0 | ||
| 72 | # CHECK-NEXT: Section: Absolute | ||
| 73 | # CHECK-NEXT: } | ||
| 74 | # CHECK-NEXT: Symbol { | ||
| 75 | # CHECK-NEXT: Name: bar6 | ||
| 76 | # CHECK-NEXT: Value: 0x124 | ||
| 77 | # CHECK-NEXT: Size: 0 | ||
| 78 | # CHECK-NEXT: Binding: Global (0x1) | ||
| 79 | # CHECK-NEXT: Type: None (0x0) | ||
| 80 | # CHECK-NEXT: Other: 0 | ||
| 81 | # CHECK-NEXT: Section: Absolute (0xFFF1) | ||
| 82 | # CHECK-NEXT: } | ||
deps/lld/test/ELF/linkerscript/absolute-expr.test created+80| ... | @@ -0,0 +1,80 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo ".global foo; foo = 0x123" | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o | ||
| 3 | # RUN: ld.lld -o %t.so --script %s %t.o -shared | ||
| 4 | # RUN: llvm-readobj -t %t.so | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .text : { | ||
| 8 | bar1 = ALIGNOF(.text); | ||
| 9 | bar2 = CONSTANT (MAXPAGESIZE); | ||
| 10 | bar3 = SIZEOF (.text); | ||
| 11 | bar4 = SIZEOF_HEADERS; | ||
| 12 | bar5 = 0x42; | ||
| 13 | bar6 = foo + 1; | ||
| 14 | *(.text) | ||
| 15 | } | ||
| 16 | } | ||
| 17 | |||
| 18 | # CHECK: Symbol { | ||
| 19 | # CHECK: Name: foo | ||
| 20 | # CHECK-NEXT: Value: 0x123 | ||
| 21 | # CHECK-NEXT: Size: 0 | ||
| 22 | # CHECK-NEXT: Binding: Global | ||
| 23 | # CHECK-NEXT: Type: None | ||
| 24 | # CHECK-NEXT: Other: 0 | ||
| 25 | # CHECK-NEXT: Section: Absolute (0xFFF1) | ||
| 26 | # CHECK-NEXT: } | ||
| 27 | # CHECK-NEXT: Symbol { | ||
| 28 | # CHECK-NEXT: Name: bar1 | ||
| 29 | # CHECK-NEXT: Value: 0x4 | ||
| 30 | # CHECK-NEXT: Size: 0 | ||
| 31 | # CHECK-NEXT: Binding: Global | ||
| 32 | # CHECK-NEXT: Type: None | ||
| 33 | # CHECK-NEXT: Other: 0 | ||
| 34 | # CHECK-NEXT: Section: Absolute | ||
| 35 | # CHECK-NEXT: } | ||
| 36 | # CHECK-NEXT: Symbol { | ||
| 37 | # CHECK-NEXT: Name: bar2 | ||
| 38 | # CHECK-NEXT: Value: 0x1000 | ||
| 39 | # CHECK-NEXT: Size: 0 | ||
| 40 | # CHECK-NEXT: Binding: Global | ||
| 41 | # CHECK-NEXT: Type: None | ||
| 42 | # CHECK-NEXT: Other: 0 | ||
| 43 | # CHECK-NEXT: Section: Absolute | ||
| 44 | # CHECK-NEXT: } | ||
| 45 | # CHECK-NEXT: Symbol { | ||
| 46 | # CHECK-NEXT: Name: bar3 | ||
| 47 | # CHECK-NEXT: Value: 0x0 | ||
| 48 | # CHECK-NEXT: Size: 0 | ||
| 49 | # CHECK-NEXT: Binding: Global | ||
| 50 | # CHECK-NEXT: Type: None | ||
| 51 | # CHECK-NEXT: Other: 0 | ||
| 52 | # CHECK-NEXT: Section: Absolute | ||
| 53 | # CHECK-NEXT: } | ||
| 54 | # CHECK-NEXT: Symbol { | ||
| 55 | # CHECK-NEXT: Name: bar4 | ||
| 56 | # CHECK-NEXT: Value: 0x190 | ||
| 57 | # CHECK-NEXT: Size: 0 | ||
| 58 | # CHECK-NEXT: Binding: Global | ||
| 59 | # CHECK-NEXT: Type: None | ||
| 60 | # CHECK-NEXT: Other: 0 | ||
| 61 | # CHECK-NEXT: Section: Absolute | ||
| 62 | # CHECK-NEXT: } | ||
| 63 | # CHECK-NEXT: Symbol { | ||
| 64 | # CHECK-NEXT: Name: bar5 | ||
| 65 | # CHECK-NEXT: Value: 0x42 | ||
| 66 | # CHECK-NEXT: Size: 0 | ||
| 67 | # CHECK-NEXT: Binding: Global | ||
| 68 | # CHECK-NEXT: Type: None | ||
| 69 | # CHECK-NEXT: Other: 0 | ||
| 70 | # CHECK-NEXT: Section: Absolute | ||
| 71 | # CHECK-NEXT: } | ||
| 72 | # CHECK-NEXT: Symbol { | ||
| 73 | # CHECK-NEXT: Name: bar6 | ||
| 74 | # CHECK-NEXT: Value: 0x124 | ||
| 75 | # CHECK-NEXT: Size: 0 | ||
| 76 | # CHECK-NEXT: Binding: Global (0x1) | ||
| 77 | # CHECK-NEXT: Type: None (0x0) | ||
| 78 | # CHECK-NEXT: Other: 0 | ||
| 79 | # CHECK-NEXT: Section: Absolute (0xFFF1) | ||
| 80 | # CHECK-NEXT: } | ||
deps/lld/test/ELF/linkerscript/addr-zero.s deleted-18| ... | @@ -1,18 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { foo = ADDR(.text) - ABSOLUTE(ADDR(.text)); };" > %t.script | ||
| 4 | # RUN: ld.lld -o %t.so --script %t.script %t.o -shared | ||
| 5 | # RUN: llvm-readobj --symbols %t.so | FileCheck %s | ||
| 6 | |||
| 7 | # Test that the script creates a non absolute symbol with value | ||
| 8 | # 0 I.E., a symbol that refers to the load address. | ||
| 9 | |||
| 10 | # CHECK: Symbol { | ||
| 11 | # CHECK: Name: foo | ||
| 12 | # CHECK-NEXT: Value: 0x0 | ||
| 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: } | ||
deps/lld/test/ELF/linkerscript/addr-zero.test created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld -o %t.so --script %s %t.o -shared | ||
| 4 | # RUN: llvm-readobj --symbols %t.so | FileCheck %s | ||
| 5 | |||
| 6 | # Test that the script creates a non absolute symbol with value | ||
| 7 | # 0 I.E., a symbol that refers to the load address. | ||
| 8 | |||
| 9 | # CHECK: Symbol { | ||
| 10 | # CHECK: Name: foo | ||
| 11 | # CHECK-NEXT: Value: 0x70 | ||
| 12 | # CHECK-NEXT: Size: 0 | ||
| 13 | # CHECK-NEXT: Binding: Global | ||
| 14 | # CHECK-NEXT: Type: None | ||
| 15 | # CHECK-NEXT: Other: 0 | ||
| 16 | # CHECK-NEXT: Section: .text | ||
| 17 | # CHECK-NEXT: } | ||
| 18 | |||
| 19 | SECTIONS { | ||
| 20 | foo = ADDR(.text) - ABSOLUTE(ADDR(.text)); | ||
| 21 | }; | ||
deps/lld/test/ELF/linkerscript/addr.s deleted-32| ... | @@ -1,32 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: . = 0x1000; \ | ||
| 5 | # RUN: .text : { *(.text*) } \ | ||
| 6 | # RUN: .foo.1 : { *(.foo.1) } \ | ||
| 7 | # RUN: .foo.2 ADDR(.foo.1) + 0x100 : { *(.foo.2) } \ | ||
| 8 | # RUN: .foo.3 : { *(.foo.3) } \ | ||
| 9 | # RUN: }" > %t.script | ||
| 10 | # RUN: ld.lld %t --script %t.script -o %t1 | ||
| 11 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 12 | |||
| 13 | # CHECK: Sections: | ||
| 14 | # CHECK-NEXT: Idx Name Size Address Type | ||
| 15 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 16 | # CHECK-NEXT: 1 .text 00000000 0000000000001000 TEXT DATA | ||
| 17 | # CHECK-NEXT: 2 .foo.1 00000008 0000000000001000 DATA | ||
| 18 | # CHECK-NEXT: 3 .foo.2 00000008 0000000000001100 DATA | ||
| 19 | # CHECK-NEXT: 4 .foo.3 00000008 0000000000001108 DATA | ||
| 20 | |||
| 21 | .text | ||
| 22 | .globl _start | ||
| 23 | _start: | ||
| 24 | |||
| 25 | .section .foo.1,"a" | ||
| 26 | .quad 1 | ||
| 27 | |||
| 28 | .section .foo.2,"a" | ||
| 29 | .quad 2 | ||
| 30 | |||
| 31 | .section .foo.3,"a" | ||
| 32 | .quad 3 | ||
deps/lld/test/ELF/linkerscript/addr.test created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/addr.s -o %t | ||
| 3 | # RUN: ld.lld %t --script %s -o %t1 | ||
| 4 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: Sections: | ||
| 7 | # CHECK-NEXT: Idx Name Size Address Type | ||
| 8 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 9 | # CHECK-NEXT: 1 .text 00000000 0000000000001000 TEXT | ||
| 10 | # CHECK-NEXT: 2 .foo.1 00000008 0000000000001000 DATA | ||
| 11 | # CHECK-NEXT: 3 .foo.2 00000008 0000000000001100 DATA | ||
| 12 | # CHECK-NEXT: 4 .foo.3 00000008 0000000000001108 DATA | ||
| 13 | |||
| 14 | SECTIONS { | ||
| 15 | . = 0x1000; | ||
| 16 | .text : { *(.text*) } | ||
| 17 | .foo.1 : { *(.foo.1) } | ||
| 18 | .foo.2 ADDR(.foo.1) + 0x100 : { *(.foo.2) } | ||
| 19 | .foo.3 : { *(.foo.3) } | ||
| 20 | } | ||
deps/lld/test/ELF/linkerscript/address-expr-symbols.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { .bar (foo) : { } };" > %t.script | ||
| 5 | # RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s | ||
| 6 | # CHECK: symbol not found: foo | ||
| 7 | |||
| 8 | # RUN: echo "SECTIONS { .bar : AT(foo) { } };" > %t.script | ||
| 9 | # RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s | ||
| 10 | |||
| 11 | # RUN: echo "SECTIONS { .bar : ALIGN(foo) { } };" > %t.script | ||
| 12 | # RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s | ||
| 13 | |||
| 14 | # RUN: echo "SECTIONS { .bar : SUBALIGN(foo) { } };" > %t.script | ||
| 15 | # RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s | ||
deps/lld/test/ELF/linkerscript/align-empty.s deleted-18| ... | @@ -1,18 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { \ | ||
| 5 | # RUN: . = SIZEOF_HEADERS; \ | ||
| 6 | # RUN: abc : { } \ | ||
| 7 | # RUN: . = ALIGN(0x1000); \ | ||
| 8 | # RUN: foo : { *(foo) } \ | ||
| 9 | # RUN: }" > %t.script | ||
| 10 | # RUN: ld.lld -o %t1 --script %t.script %t -shared | ||
| 11 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 12 | # CHECK: Sections: | ||
| 13 | # CHECK-NEXT: Idx Name Size Address | ||
| 14 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 15 | # CHECK-NEXT: 1 foo 00000001 0000000000001000 | ||
| 16 | |||
| 17 | .section foo, "a" | ||
| 18 | .byte 0 | ||
deps/lld/test/ELF/linkerscript/align-empty.test created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section foo, "a"; .byte 0' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | |||
| 5 | # RUN: ld.lld -o %t1 --script %s %t.o -shared | ||
| 6 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 7 | |||
| 8 | SECTIONS { | ||
| 9 | . = SIZEOF_HEADERS; | ||
| 10 | abc : {} | ||
| 11 | . = ALIGN(0x1000); | ||
| 12 | foo : { *(foo) } | ||
| 13 | } | ||
| 14 | |||
| 15 | # CHECK: Sections: | ||
| 16 | # CHECK-NEXT: Idx Name Size Address | ||
| 17 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 18 | # CHECK-NEXT: 1 .dynsym 00000018 0000000000000190 | ||
| 19 | # CHECK-NEXT: 2 .gnu.hash 0000001c 00000000000001a8 | ||
| 20 | # CHECK-NEXT: 3 .hash 00000010 00000000000001c4 | ||
| 21 | # CHECK-NEXT: 4 .dynstr 00000001 00000000000001d4 | ||
| 22 | # CHECK-NEXT: 5 foo 00000001 0000000000001000 | ||
deps/lld/test/ELF/linkerscript/align-r.test created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | ## Check output section ALIGN modifier with -r | ||
| 4 | |||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t1.o | ||
| 6 | # RUN: ld.lld -r -o %t2.o --script %s %t1.o | ||
| 7 | # RUN: llvm-readelf -s %t2.o | FileCheck %s | ||
| 8 | |||
| 9 | # CHECK: Section Headers: | ||
| 10 | # CHECK-NEXT: Name Type Address Off Size ES Flg Lk Inf Al | ||
| 11 | # CHECK-NEXT: NULL 0000000000000000 000000 000000 00 | ||
| 12 | # CHECK-NEXT: .aaa PROGBITS 0000000000000000 000040 000008 00 A 0 0 1 | ||
| 13 | # CHECK-NEXT: .bbb PROGBITS 0000000000000000 001000 000008 00 A 0 0 4096 | ||
| 14 | # CHECK-NEXT: .ccc PROGBITS 0000000000000000 004000 000008 00 A 0 0 16384 | ||
| 15 | |||
| 16 | SECTIONS { | ||
| 17 | . = 0x10000; | ||
| 18 | .aaa : { *(.aaa) } | ||
| 19 | .bbb : ALIGN(4096) { *(.bbb) } | ||
| 20 | .ccc : ALIGN(4096 * 4) { *(.ccc) } | ||
| 21 | } | ||
deps/lld/test/ELF/linkerscript/align-section-offset.s deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { .foo : ALIGN(2M) { *(.foo) } }" > %t.script | ||
| 4 | # RUN: ld.lld -o %t --script %t.script %t.o -shared | ||
| 5 | # RUN: llvm-readelf -S -l %t | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: .foo PROGBITS 0000000000200000 200000 000008 00 WA 0 0 2097152 | ||
| 8 | # CHECK: LOAD 0x200000 0x0000000000200000 0x0000000000200000 {{.*}} RW 0x200000 | ||
| 9 | |||
| 10 | .section .foo, "aw" | ||
| 11 | .quad 42 | ||
deps/lld/test/ELF/linkerscript/align-section-offset.test created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .foo, "aw"; .quad 42' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o | ||
| 4 | # RUN: ld.lld -o %t --script %s %t.o -shared | ||
| 5 | # RUN: llvm-readelf -S -l %t | FileCheck %s | ||
| 6 | |||
| 7 | SECTIONS { | ||
| 8 | .foo : ALIGN(2M) { *(.foo) } | ||
| 9 | } | ||
| 10 | |||
| 11 | # CHECK: .foo PROGBITS 0000000000200000 200000 000008 00 WA 0 0 2097152 | ||
| 12 | # CHECK: LOAD 0x200000 0x0000000000200000 0x0000000000200000 {{.*}} RW 0x200000 | ||
deps/lld/test/ELF/linkerscript/align-section.s deleted-6| ... | @@ -1,6 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { .foo : ALIGN(2M) { } }" > %t.script | ||
| 4 | # RUN: ld.lld -o %t --script %t.script %t.o -shared | ||
| 5 | |||
| 6 | # We would crash if an empty section had an ALIGN. | ||
deps/lld/test/ELF/linkerscript/align-section.test created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --script %s %t.o -shared | ||
| 4 | |||
| 5 | # lld shouldn't crash. | ||
| 6 | |||
| 7 | SECTIONS { .foo : ALIGN(2M) {} } | ||
deps/lld/test/ELF/linkerscript/align.s deleted-125| ... | @@ -1,125 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | ## Check that ALIGN command workable using location counter | ||
| 5 | # RUN: echo "SECTIONS { \ | ||
| 6 | # RUN: . = 0x10000; \ | ||
| 7 | # RUN: .aaa : { *(.aaa) } \ | ||
| 8 | # RUN: . = ALIGN(4096); \ | ||
| 9 | # RUN: .bbb : { *(.bbb) } \ | ||
| 10 | # RUN: . = ALIGN(4096 * 4); \ | ||
| 11 | # RUN: .ccc : { *(.ccc) } \ | ||
| 12 | # RUN: }" > %t.script | ||
| 13 | # RUN: ld.lld -o %t1 --script %t.script %t | ||
| 14 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 15 | |||
| 16 | ## Check that the two argument version of ALIGN command works | ||
| 17 | # RUN: echo "SECTIONS { \ | ||
| 18 | # RUN: . = ALIGN(0x1234, 0x10000); \ | ||
| 19 | # RUN: .aaa : { *(.aaa) } \ | ||
| 20 | # RUN: . = ALIGN(., 4096); \ | ||
| 21 | # RUN: .bbb : { *(.bbb) } \ | ||
| 22 | # RUN: . = ALIGN(., 4096 * 4); \ | ||
| 23 | # RUN: .ccc : { *(.ccc) } \ | ||
| 24 | # RUN: }" > %t.script | ||
| 25 | # RUN: ld.lld -o %t1 --script %t.script %t | ||
| 26 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 27 | |||
| 28 | # CHECK: Sections: | ||
| 29 | # CHECK-NEXT: Idx Name Size Address Type | ||
| 30 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 31 | # CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA | ||
| 32 | # CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA | ||
| 33 | # CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA | ||
| 34 | |||
| 35 | ## Check output sections ALIGN modificator | ||
| 36 | # RUN: echo "SECTIONS { \ | ||
| 37 | # RUN: . = 0x10000; \ | ||
| 38 | # RUN: .aaa : { *(.aaa) } \ | ||
| 39 | # RUN: .bbb : ALIGN(4096) { *(.bbb) } \ | ||
| 40 | # RUN: .ccc : ALIGN(4096 * 4) { *(.ccc) } \ | ||
| 41 | # RUN: }" > %t2.script | ||
| 42 | # RUN: ld.lld -o %t2 --script %t2.script %t | ||
| 43 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s | ||
| 44 | |||
| 45 | ## Check use of variables in align expressions: | ||
| 46 | # RUN: echo "VAR = 0x1000; \ | ||
| 47 | # RUN: __code_base__ = 0x10000; \ | ||
| 48 | # RUN: SECTIONS { \ | ||
| 49 | # RUN: . = __code_base__; \ | ||
| 50 | # RUN: .aaa : { *(.aaa) } \ | ||
| 51 | # RUN: .bbb : ALIGN(VAR) { *(.bbb) } \ | ||
| 52 | # RUN: . = ALIGN(., VAR * 4); \ | ||
| 53 | # RUN: .ccc : { *(.ccc) } \ | ||
| 54 | # RUN: __start_bbb = ADDR(.bbb); \ | ||
| 55 | # RUN: __end_bbb = ALIGN(__start_bbb + SIZEOF(.bbb), VAR); \ | ||
| 56 | # RUN: }" > %t3.script | ||
| 57 | # RUN: ld.lld -o %t3 --script %t3.script %t | ||
| 58 | # RUN: llvm-objdump -section-headers %t3 | FileCheck %s | ||
| 59 | # RUN: llvm-objdump -t %t3 | FileCheck -check-prefix SYMBOLS %s | ||
| 60 | |||
| 61 | # SYMBOLS-LABEL: SYMBOL TABLE: | ||
| 62 | # SYMBOLS-NEXT: 0000000000000000 *UND* 00000000 | ||
| 63 | # SYMBOLS-NEXT: 0000000000014008 .text 00000000 _start | ||
| 64 | # SYMBOLS-NEXT: 0000000000010000 *ABS* 00000000 __code_base__ | ||
| 65 | # SYMBOLS-NEXT: 0000000000001000 *ABS* 00000000 VAR | ||
| 66 | # SYMBOLS-NEXT: 0000000000011000 .bbb 00000000 __start_bbb | ||
| 67 | # SYMBOLS-NEXT: 0000000000012000 .bbb 00000000 __end_bbb | ||
| 68 | |||
| 69 | ## Check that ALIGN zero do nothing and does not crash #1. | ||
| 70 | # RUN: echo "SECTIONS { . = ALIGN(0x123, 0); .aaa : { *(.aaa) } }" > %t.script | ||
| 71 | # RUN: ld.lld -o %t4 --script %t.script %t | ||
| 72 | # RUN: llvm-objdump -section-headers %t4 | FileCheck %s -check-prefix=ZERO | ||
| 73 | |||
| 74 | # ZERO: Sections: | ||
| 75 | # ZERO-NEXT: Idx Name Size Address Type | ||
| 76 | # ZERO-NEXT: 0 00000000 0000000000000000 | ||
| 77 | # ZERO-NEXT: 1 .aaa 00000008 0000000000000123 DATA | ||
| 78 | |||
| 79 | ## Check that ALIGN zero do nothing and does not crash #2. | ||
| 80 | # RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0); .aaa : { *(.aaa) } }" > %t.script | ||
| 81 | # RUN: ld.lld -o %t5 --script %t.script %t | ||
| 82 | # RUN: llvm-objdump -section-headers %t5 | FileCheck %s -check-prefix=ZERO | ||
| 83 | |||
| 84 | ## Test we fail gracefuly when alignment value is not a power of 2 (#1). | ||
| 85 | # RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0x123, 3); .aaa : { *(.aaa) } }" > %t.script | ||
| 86 | # RUN: not ld.lld -o %t6 --script %t.script %t 2>&1 | FileCheck -check-prefix=ERR %s | ||
| 87 | # ERR: {{.*}}.script:1: alignment must be power of 2 | ||
| 88 | |||
| 89 | ## Test we fail gracefuly when alignment value is not a power of 2 (#2). | ||
| 90 | # RUN: echo "SECTIONS { . = 0x123; . = ALIGN(3); .aaa : { *(.aaa) } }" > %t.script | ||
| 91 | # RUN: not ld.lld -o %t7 --script %t.script %t 2>&1 | FileCheck -check-prefix=ERR %s | ||
| 92 | |||
| 93 | # RUN: echo "SECTIONS { \ | ||
| 94 | # RUN: . = 0xff8; \ | ||
| 95 | # RUN: .aaa : { \ | ||
| 96 | # RUN: *(.aaa) \ | ||
| 97 | # RUN: foo = ALIGN(., 0x100); \ | ||
| 98 | # RUN: bar = .; \ | ||
| 99 | # RUN: zed1 = ALIGN(., 0x100) + 1; \ | ||
| 100 | # RUN: zed2 = ALIGN(., 0x100) - 1; \ | ||
| 101 | # RUN: } \ | ||
| 102 | # RUN: .bbb : { *(.bbb); } \ | ||
| 103 | # RUN: .ccc : { *(.ccc); } \ | ||
| 104 | # RUN: .text : { *(.text); } \ | ||
| 105 | # RUN: }" > %t.script | ||
| 106 | # RUN: ld.lld -o %t1 --script %t.script %t | ||
| 107 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=OFFSET %s | ||
| 108 | |||
| 109 | # OFFSET: 0000000000001000 .aaa 00000000 foo | ||
| 110 | # OFFSET: 0000000000001000 .aaa 00000000 bar | ||
| 111 | # OFFSET: 0000000000001001 .aaa 00000000 zed1 | ||
| 112 | # OFFSET: 0000000000000fff .aaa 00000000 zed2 | ||
| 113 | |||
| 114 | .global _start | ||
| 115 | _start: | ||
| 116 | nop | ||
| 117 | |||
| 118 | .section .aaa, "a" | ||
| 119 | .quad 0 | ||
| 120 | |||
| 121 | .section .bbb, "a" | ||
| 122 | .quad 0 | ||
| 123 | |||
| 124 | .section .ccc, "a" | ||
| 125 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/align1.test created+44| ... | @@ -0,0 +1,44 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 4 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = 0x10000; | ||
| 8 | .aaa : { *(.aaa) } | ||
| 9 | . = ALIGN(4096); | ||
| 10 | .bbb : { *(.bbb) } | ||
| 11 | . = ALIGN(4096 * 4); | ||
| 12 | .ccc : { *(.ccc) } | ||
| 13 | } | ||
| 14 | |||
| 15 | # CHECK: Sections: | ||
| 16 | # CHECK-NEXT: Idx Name Size Address Type | ||
| 17 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 18 | # CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA | ||
| 19 | # CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA | ||
| 20 | # CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA | ||
| 21 | |||
| 22 | ## Check that ALIGN zero do nothing and does not crash #1. | ||
| 23 | # RUN: echo "SECTIONS { . = ALIGN(0x123, 0); .aaa : { *(.aaa) } }" > %t.script | ||
| 24 | # RUN: ld.lld -o %t4 --script %t.script %t.o | ||
| 25 | # RUN: llvm-objdump -section-headers %t4 | FileCheck %s -check-prefix=ZERO | ||
| 26 | |||
| 27 | # ZERO: Sections: | ||
| 28 | # ZERO-NEXT: Idx Name Size Address Type | ||
| 29 | # ZERO-NEXT: 0 00000000 0000000000000000 | ||
| 30 | # ZERO-NEXT: 1 .aaa 00000008 0000000000000123 DATA | ||
| 31 | |||
| 32 | ## Check that ALIGN zero do nothing and does not crash #2. | ||
| 33 | # RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0); .aaa : { *(.aaa) } }" > %t.script | ||
| 34 | # RUN: ld.lld -o %t5 --script %t.script %t.o | ||
| 35 | # RUN: llvm-objdump -section-headers %t5 | FileCheck %s -check-prefix=ZERO | ||
| 36 | |||
| 37 | ## Test we fail gracefuly when alignment value is not a power of 2 (#1). | ||
| 38 | # RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0x123, 3); .aaa : { *(.aaa) } }" > %t.script | ||
| 39 | # RUN: not ld.lld -o %t6 --script %t.script %t.o 2>&1 | FileCheck -check-prefix=ERR %s | ||
| 40 | |||
| 41 | # RUN: echo "SECTIONS { . = 0x123; . = ALIGN(3); .aaa : { *(.aaa) } }" > %t.script | ||
| 42 | # RUN: not ld.lld -o %t7 --script %t.script %t.o 2>&1 | FileCheck -check-prefix=ERR %s | ||
| 43 | |||
| 44 | # ERR: {{.*}}.script:1: alignment must be power of 2 | ||
deps/lld/test/ELF/linkerscript/align2.test created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 4 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = ALIGN(0x1234, 0x10000); | ||
| 8 | .aaa : { *(.aaa) } | ||
| 9 | . = ALIGN(., 4096); | ||
| 10 | .bbb : { *(.bbb) } | ||
| 11 | . = ALIGN(., 4096 * 4); | ||
| 12 | .ccc : { *(.ccc) } | ||
| 13 | } | ||
| 14 | |||
| 15 | # CHECK: Sections: | ||
| 16 | # CHECK-NEXT: Idx Name Size Address Type | ||
| 17 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 18 | # CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA | ||
| 19 | # CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA | ||
| 20 | # CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA | ||
deps/lld/test/ELF/linkerscript/align3.test created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 4 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = 0x10000; | ||
| 8 | .aaa : { *(.aaa) } | ||
| 9 | .bbb : ALIGN(4096) { *(.bbb) } | ||
| 10 | .ccc : ALIGN(4096 * 4) { *(.ccc) } | ||
| 11 | } | ||
| 12 | |||
| 13 | # CHECK: Sections: | ||
| 14 | # CHECK-NEXT: Idx Name Size Address Type | ||
| 15 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 16 | # CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA | ||
| 17 | # CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA | ||
| 18 | # CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA | ||
deps/lld/test/ELF/linkerscript/align4.test created+25| ... | @@ -0,0 +1,25 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 4 | # RUN: llvm-objdump -t %t | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK-LABEL: SYMBOL TABLE: | ||
| 7 | # CHECK-NEXT: 0000000000000000 *UND* 00000000 | ||
| 8 | # CHECK-NEXT: 0000000000014008 .text 00000000 _start | ||
| 9 | # CHECK-NEXT: 0000000000010000 *ABS* 00000000 __code_base__ | ||
| 10 | # CHECK-NEXT: 0000000000001000 *ABS* 00000000 VAR | ||
| 11 | # CHECK-NEXT: 0000000000011000 .bbb 00000000 __start_bbb | ||
| 12 | # CHECK-NEXT: 0000000000012000 .bbb 00000000 __end_bbb | ||
| 13 | |||
| 14 | VAR = 0x1000; | ||
| 15 | __code_base__ = 0x10000; | ||
| 16 | |||
| 17 | SECTIONS { | ||
| 18 | . = __code_base__; | ||
| 19 | .aaa : { *(.aaa) } | ||
| 20 | .bbb : ALIGN(VAR) { *(.bbb) } | ||
| 21 | . = ALIGN(., VAR * 4); | ||
| 22 | .ccc : { *(.ccc) } | ||
| 23 | __start_bbb = ADDR(.bbb); | ||
| 24 | __end_bbb = ALIGN(__start_bbb + SIZEOF(.bbb), VAR); | ||
| 25 | } | ||
deps/lld/test/ELF/linkerscript/align5.test created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/align.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 4 | # RUN: llvm-objdump -t %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = 0xff8; | ||
| 8 | .aaa : { | ||
| 9 | *(.aaa) | ||
| 10 | foo = ALIGN(., 0x100); | ||
| 11 | bar = .; | ||
| 12 | zed1 = ALIGN(., 0x100) + 1; | ||
| 13 | zed2 = ALIGN(., 0x100) - 1; | ||
| 14 | } | ||
| 15 | .bbb : { *(.bbb); } | ||
| 16 | .ccc : { *(.ccc); } | ||
| 17 | .text : { *(.text); } | ||
| 18 | } | ||
| 19 | |||
| 20 | # CHECK: 0000000000001000 .aaa 00000000 foo | ||
| 21 | # CHECK: 0000000000001000 .aaa 00000000 bar | ||
| 22 | # CHECK: 0000000000001001 .aaa 00000000 zed1 | ||
| 23 | # CHECK: 0000000000000fff .aaa 00000000 zed2 | ||
deps/lld/test/ELF/linkerscript/alignof.s deleted-41| ... | @@ -1,41 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { \ | ||
| 5 | # RUN: .aaa : { *(.aaa) } \ | ||
| 6 | # RUN: .bbb : { *(.bbb) } \ | ||
| 7 | # RUN: .ccc : { *(.ccc) } \ | ||
| 8 | # RUN: _aaa = ALIGNOF(.aaa); \ | ||
| 9 | # RUN: _bbb = ALIGNOF(.bbb); \ | ||
| 10 | # RUN: _ccc = ALIGNOF(.ccc); \ | ||
| 11 | # RUN: }" > %t.script | ||
| 12 | # RUN: ld.lld -o %t1 --script %t.script %t | ||
| 13 | # RUN: llvm-objdump -t %t1 | FileCheck %s | ||
| 14 | # CHECK: SYMBOL TABLE: | ||
| 15 | # CHECK: 0000000000000008 *ABS* 00000000 _aaa | ||
| 16 | # CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb | ||
| 17 | # CHECK-NEXT: 0000000000000020 *ABS* 00000000 _ccc | ||
| 18 | |||
| 19 | ## Check that we error out if trying to get alignment of | ||
| 20 | ## section that does not exist. | ||
| 21 | # RUN: echo "SECTIONS { \ | ||
| 22 | # RUN: _aaa = ALIGNOF(.foo); \ | ||
| 23 | # RUN: }" > %t.script | ||
| 24 | # RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \ | ||
| 25 | # RUN: | FileCheck -check-prefix=ERR %s | ||
| 26 | # ERR: {{.*}}.script:1: undefined section .foo | ||
| 27 | .global _start | ||
| 28 | _start: | ||
| 29 | nop | ||
| 30 | |||
| 31 | .section .aaa,"a" | ||
| 32 | .align 8 | ||
| 33 | .quad 0 | ||
| 34 | |||
| 35 | .section .bbb,"a" | ||
| 36 | .align 16 | ||
| 37 | .quad 0 | ||
| 38 | |||
| 39 | .section .ccc,"a" | ||
| 40 | .align 32 | ||
| 41 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/alignof.test created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/alignof.s -o %t | ||
| 3 | # RUN: ld.lld -o %t1 --script %s %t | ||
| 4 | # RUN: llvm-objdump -t %t1 | FileCheck %s | ||
| 5 | # CHECK: SYMBOL TABLE: | ||
| 6 | # CHECK: 0000000000000008 *ABS* 00000000 _aaa | ||
| 7 | # CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb | ||
| 8 | # CHECK-NEXT: 0000000000000020 *ABS* 00000000 _ccc | ||
| 9 | |||
| 10 | SECTIONS { | ||
| 11 | .aaa : { *(.aaa) } | ||
| 12 | .bbb : { *(.bbb) } | ||
| 13 | .ccc : { *(.ccc) } | ||
| 14 | _aaa = ALIGNOF(.aaa); | ||
| 15 | _bbb = ALIGNOF(.bbb); | ||
| 16 | _ccc = ALIGNOF(.ccc); | ||
| 17 | } | ||
| 18 | |||
| 19 | ## Check that we error out if trying to get alignment of | ||
| 20 | ## section that does not exist. | ||
| 21 | # RUN: echo "SECTIONS { _aaa = ALIGNOF(.foo); }" > %t.script | ||
| 22 | # RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \ | ||
| 23 | # RUN: | FileCheck -check-prefix=ERR %s | ||
| 24 | # ERR: {{.*}}.script:1: undefined section .foo | ||
deps/lld/test/ELF/linkerscript/arm-exidx-order.s deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | # REQUIRES: arm | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \ | ||
| 4 | # RUN: .ARM.exidx : { *(.ARM.exidx*) } \ | ||
| 5 | # RUN: .foo : { _foo = 0; } }" > %t.script | ||
| 6 | # RUN: ld.lld -T %t.script %t.o -shared -o %t.so | ||
| 7 | # RUN: llvm-readobj -s %t.so | FileCheck %s | ||
| 8 | |||
| 9 | # CHECK: Section { | ||
| 10 | # CHECK: Index: | ||
| 11 | # CHECK: Name: .foo | ||
| 12 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 13 | # CHECK-NEXT: Flags [ | ||
| 14 | # CHECK-NEXT: SHF_ALLOC | ||
| 15 | # CHECK-NEXT: ] | ||
| 16 | |||
| 17 | .fnstart | ||
| 18 | .cantunwind | ||
| 19 | .fnend | ||
deps/lld/test/ELF/linkerscript/arm-exidx-order.test created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: arm | ||
| 2 | # RUN: echo ".fnstart; .cantunwind; .fnend" \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi - -o %t.o | ||
| 4 | # RUN: ld.lld -T %s %t.o -shared -o %t.so | ||
| 5 | # RUN: llvm-readobj -s %t.so | FileCheck %s | ||
| 6 | |||
| 7 | SECTIONS { | ||
| 8 | . = SIZEOF_HEADERS; | ||
| 9 | .ARM.exidx : { *(.ARM.exidx*) } | ||
| 10 | .foo : { _foo = 0; } | ||
| 11 | } | ||
| 12 | |||
| 13 | # CHECK: Section { | ||
| 14 | # CHECK: Index: | ||
| 15 | # CHECK: Name: .foo | ||
| 16 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 17 | # CHECK-NEXT: Flags [ | ||
| 18 | # CHECK-NEXT: SHF_ALLOC | ||
| 19 | # CHECK-NEXT: ] | ||
deps/lld/test/ELF/linkerscript/arm-exidx-phdrs.s deleted-16| ... | @@ -1,16 +0,0 @@ | ||
| 1 | // REQUIRES: arm | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | ||
| 3 | // RUN: echo "PHDRS { ph_text PT_LOAD; } \ | ||
| 4 | // RUN: SECTIONS { \ | ||
| 5 | // RUN: . = SIZEOF_HEADERS; \ | ||
| 6 | // RUN: .text : { *(.text) } : ph_text \ | ||
| 7 | // RUN: }" > %t.script | ||
| 8 | // RUN: ld.lld -T %t.script %t.o -shared -o %t.so | ||
| 9 | // RUN: llvm-readobj --program-headers %t.so | FileCheck %s | ||
| 10 | |||
| 11 | // CHECK: Type: PT_ARM_EXIDX | ||
| 12 | |||
| 13 | .fnstart | ||
| 14 | bx lr | ||
| 15 | .cantunwind | ||
| 16 | .fnend | ||
deps/lld/test/ELF/linkerscript/arm-exidx-phdrs.test created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: arm | ||
| 2 | # RUN: echo ".fnstart; bx lr; .cantunwind; .fnend" \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi - -o %t.o | ||
| 4 | # RUN: ld.lld -T %s %t.o -shared -o %t.so | ||
| 5 | # RUN: llvm-readobj --program-headers %t.so | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: Type: PT_ARM_EXIDX | ||
| 8 | |||
| 9 | PHDRS { ph_text PT_LOAD; } | ||
| 10 | SECTIONS { | ||
| 11 | . = SIZEOF_HEADERS; | ||
| 12 | .text : { *(.text) } : ph_text | ||
| 13 | } | ||
deps/lld/test/ELF/linkerscript/arm-lscript.s deleted-9| ... | @@ -1,9 +0,0 @@ | ||
| 1 | // REQUIRES: arm | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | ||
| 3 | // RUN: echo "SECTIONS { \ | ||
| 4 | // RUN: .rel.dyn : { } \ | ||
| 5 | // RUN: .zed : { PROVIDE_HIDDEN (foobar = .); } \ | ||
| 6 | // RUN: }" > %t.script | ||
| 7 | // This is a test case for PR33029. Making sure that linker can digest | ||
| 8 | // the above script without dumping core. | ||
| 9 | // RUN: ld.lld -emit-relocs -T %t.script %t.o -shared -o %t.so | ||
deps/lld/test/ELF/linkerscript/arm-lscript.test created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # REQUIRES: arm | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi /dev/null -o %t.o | ||
| 3 | |||
| 4 | # This is a test case for PR33029. Making sure that linker can digest | ||
| 5 | # the above script without dumping core. | ||
| 6 | # RUN: ld.lld -emit-relocs -T %s %t.o -shared -o %t.so | ||
| 7 | |||
| 8 | SECTIONS { | ||
| 9 | .rel.dyn : {} | ||
| 10 | .zed : { PROVIDE_HIDDEN (foobar = .); } | ||
| 11 | } | ||
deps/lld/test/ELF/linkerscript/assert.s+5-4| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | # RUN: llvm-readobj %t1 > /dev/null | 6 | # RUN: llvm-readobj %t1 > /dev/null |
| 7 | 7 | ||
| 8 | # RUN: echo "SECTIONS { ASSERT(0, fail) }" > %t3.script | 8 | # RUN: echo "SECTIONS { ASSERT(0, fail) }" > %t3.script |
| 9 | # RUN: not ld.lld -shared -o %t3 --script %t3.script %t1.o > %t.log 2>&1 | 9 | # RUN: not ld.lld -shared -o /dev/null --script %t3.script %t1.o > %t.log 2>&1 |
| 10 | # RUN: FileCheck %s -check-prefix=FAIL < %t.log | 10 | # RUN: FileCheck %s -check-prefix=FAIL < %t.log |
| 11 | # FAIL: fail | 11 | # FAIL: fail |
| 12 | 12 | ||
| ... | @@ -30,10 +30,11 @@ | ... | @@ -30,10 +30,11 @@ |
| 30 | # RUN: ld.lld -shared -o %t6 --script %t6.script %t1.o | 30 | # RUN: ld.lld -shared -o %t6 --script %t6.script %t1.o |
| 31 | # RUN: llvm-readobj %t6 > /dev/null | 31 | # RUN: llvm-readobj %t6 > /dev/null |
| 32 | 32 | ||
| 33 | ## Unlike the GNU ld, we accept the ASSERT without the semicolon. | ||
| 34 | ## It is consistent with how ASSERT can be written outside of the | ||
| 35 | ## output section declaration. | ||
| 33 | # RUN: echo "SECTIONS { .foo : { ASSERT(1, \"true\") } }" > %t7.script | 36 | # RUN: echo "SECTIONS { .foo : { ASSERT(1, \"true\") } }" > %t7.script |
| 34 | # RUN: not ld.lld -shared -o %t7 --script %t7.script %t1.o > %t.log 2>&1 | 37 | # RUN: ld.lld -shared -o /dev/null --script %t7.script %t1.o |
| 35 | # RUN: FileCheck %s -check-prefix=CHECK-SEMI < %t.log | ||
| 36 | # CHECK-SEMI: error: {{.*}}.script:1: ; expected, but got } | ||
| 37 | 38 | ||
| 38 | .section .foo, "a" | 39 | .section .foo, "a" |
| 39 | .quad 0 | 40 | .quad 0 |
deps/lld/test/ELF/linkerscript/at2.s deleted-81| ... | @@ -1,81 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: echo "MEMORY { \ | ||
| 4 | # RUN: AX (ax) : ORIGIN = 0x2000, LENGTH = 0x100 \ | ||
| 5 | # RUN: AW (aw) : ORIGIN = 0x3000, LENGTH = 0x100 \ | ||
| 6 | # RUN: FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x100 \ | ||
| 7 | # RUN: RAM (aw) : ORIGIN = 0x7000, LENGTH = 0x100 } \ | ||
| 8 | # RUN: SECTIONS { \ | ||
| 9 | # RUN: .foo1 : { *(.foo1) } > AX AT>FLASH \ | ||
| 10 | # RUN: .foo2 : { *(.foo2) } > AX \ | ||
| 11 | # RUN: .bar1 : { *(.bar1) } > AW AT> RAM \ | ||
| 12 | # RUN: .bar2 : { *(.bar2) } > AW AT > RAM \ | ||
| 13 | # RUN: .bar3 : { *(.bar3) } > AW AT >RAM \ | ||
| 14 | # RUN: }" > %t.script | ||
| 15 | # RUN: ld.lld %t --script %t.script -o %t2 | ||
| 16 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s | ||
| 17 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=SECTIONS | ||
| 18 | |||
| 19 | # CHECK: ProgramHeaders [ | ||
| 20 | # CHECK-NEXT: ProgramHeader { | ||
| 21 | # CHECK-NEXT: Type: PT_LOAD | ||
| 22 | # CHECK-NEXT: Offset: 0x1000 | ||
| 23 | # CHECK-NEXT: VirtualAddress: 0x2000 | ||
| 24 | # CHECK-NEXT: PhysicalAddress: 0x6000 | ||
| 25 | # CHECK-NEXT: FileSize: 16 | ||
| 26 | # CHECK-NEXT: MemSize: 16 | ||
| 27 | # CHECK-NEXT: Flags [ | ||
| 28 | # CHECK-NEXT: PF_R | ||
| 29 | # CHECK-NEXT: PF_X | ||
| 30 | # CHECK-NEXT: ] | ||
| 31 | # CHECK-NEXT: Alignment: | ||
| 32 | # CHECK-NEXT: } | ||
| 33 | # CHECK-NEXT: ProgramHeader { | ||
| 34 | # CHECK-NEXT: Type: PT_LOAD | ||
| 35 | # CHECK-NEXT: Offset: 0x2000 | ||
| 36 | # CHECK-NEXT: VirtualAddress: 0x3000 | ||
| 37 | # CHECK-NEXT: PhysicalAddress: 0x7000 | ||
| 38 | # CHECK-NEXT: FileSize: 24 | ||
| 39 | # CHECK-NEXT: MemSize: 24 | ||
| 40 | # CHECK-NEXT: Flags [ | ||
| 41 | # CHECK-NEXT: PF_R | ||
| 42 | # CHECK-NEXT: PF_W | ||
| 43 | # CHECK-NEXT: ] | ||
| 44 | # CHECK-NEXT: Alignment: 4096 | ||
| 45 | # CHECK-NEXT: } | ||
| 46 | |||
| 47 | # SECTIONS: Sections: | ||
| 48 | # SECTIONS-NEXT: Idx Name Size Address | ||
| 49 | # SECTIONS-NEXT: 0 00000000 0000000000000000 | ||
| 50 | # SECTIONS-NEXT: 1 .foo1 00000008 0000000000002000 | ||
| 51 | # SECTIONS-NEXT: 2 .foo2 00000008 0000000000002008 | ||
| 52 | # SECTIONS-NEXT: 3 .text 00000000 0000000000002010 | ||
| 53 | # SECTIONS-NEXT: 4 .bar1 00000008 0000000000003000 | ||
| 54 | # SECTIONS-NEXT: 5 .bar2 00000008 0000000000003008 | ||
| 55 | # SECTIONS-NEXT: 6 .bar3 00000008 0000000000003010 | ||
| 56 | |||
| 57 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 58 | # RUN: echo "MEMORY { \ | ||
| 59 | # RUN: FLASH (ax) : ORIGIN = 0x2000, LENGTH = 0x100 \ | ||
| 60 | # RUN: RAM (aw) : ORIGIN = 0x5000, LENGTH = 0x100 } \ | ||
| 61 | # RUN: SECTIONS { \ | ||
| 62 | # RUN: .foo1 : AT(0x500) { *(.foo1) } > FLASH AT>FLASH \ | ||
| 63 | # RUN: }" > %t2.script | ||
| 64 | # RUN: not ld.lld %t --script %t2.script -o %t2 2>&1 | \ | ||
| 65 | # RUN: FileCheck %s --check-prefix=ERR | ||
| 66 | # ERR: error: section can't have both LMA and a load region | ||
| 67 | |||
| 68 | .section .foo1, "ax" | ||
| 69 | .quad 0 | ||
| 70 | |||
| 71 | .section .foo2, "ax" | ||
| 72 | .quad 0 | ||
| 73 | |||
| 74 | .section .bar1, "aw" | ||
| 75 | .quad 0 | ||
| 76 | |||
| 77 | .section .bar2, "aw" | ||
| 78 | .quad 0 | ||
| 79 | |||
| 80 | .section .bar3, "aw" | ||
| 81 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/at2.test created+58| ... | @@ -0,0 +1,58 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/at2.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t.exe %t.o --script %s | ||
| 4 | # RUN: llvm-readobj -program-headers %t.exe | FileCheck %s | ||
| 5 | # RUN: llvm-objdump -section-headers %t.exe | FileCheck %s --check-prefix=SECTIONS | ||
| 6 | |||
| 7 | MEMORY { | ||
| 8 | AX (ax) : ORIGIN = 0x2000, LENGTH = 0x100 | ||
| 9 | AW (aw) : ORIGIN = 0x3000, LENGTH = 0x100 | ||
| 10 | FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x100 | ||
| 11 | RAM (aw) : ORIGIN = 0x7000, LENGTH = 0x100 | ||
| 12 | } | ||
| 13 | |||
| 14 | SECTIONS { | ||
| 15 | .foo1 : { *(.foo1) } > AX AT>FLASH | ||
| 16 | .foo2 : { *(.foo2) } > AX | ||
| 17 | .bar1 : { *(.bar1) } > AW AT> RAM | ||
| 18 | .bar2 : { *(.bar2) } > AW AT > RAM | ||
| 19 | .bar3 : { *(.bar3) } > AW AT >RAM | ||
| 20 | } | ||
| 21 | |||
| 22 | # CHECK: ProgramHeaders [ | ||
| 23 | # CHECK-NEXT: ProgramHeader { | ||
| 24 | # CHECK-NEXT: Type: PT_LOAD | ||
| 25 | # CHECK-NEXT: Offset: 0x1000 | ||
| 26 | # CHECK-NEXT: VirtualAddress: 0x2000 | ||
| 27 | # CHECK-NEXT: PhysicalAddress: 0x6000 | ||
| 28 | # CHECK-NEXT: FileSize: 16 | ||
| 29 | # CHECK-NEXT: MemSize: 16 | ||
| 30 | # CHECK-NEXT: Flags [ | ||
| 31 | # CHECK-NEXT: PF_R | ||
| 32 | # CHECK-NEXT: PF_X | ||
| 33 | # CHECK-NEXT: ] | ||
| 34 | # CHECK-NEXT: Alignment: | ||
| 35 | # CHECK-NEXT: } | ||
| 36 | # CHECK-NEXT: ProgramHeader { | ||
| 37 | # CHECK-NEXT: Type: PT_LOAD | ||
| 38 | # CHECK-NEXT: Offset: 0x2000 | ||
| 39 | # CHECK-NEXT: VirtualAddress: 0x3000 | ||
| 40 | # CHECK-NEXT: PhysicalAddress: 0x7000 | ||
| 41 | # CHECK-NEXT: FileSize: 24 | ||
| 42 | # CHECK-NEXT: MemSize: 24 | ||
| 43 | # CHECK-NEXT: Flags [ | ||
| 44 | # CHECK-NEXT: PF_R | ||
| 45 | # CHECK-NEXT: PF_W | ||
| 46 | # CHECK-NEXT: ] | ||
| 47 | # CHECK-NEXT: Alignment: 4096 | ||
| 48 | # CHECK-NEXT: } | ||
| 49 | |||
| 50 | # SECTIONS: Sections: | ||
| 51 | # SECTIONS-NEXT: Idx Name Size Address | ||
| 52 | # SECTIONS-NEXT: 0 00000000 0000000000000000 | ||
| 53 | # SECTIONS-NEXT: 1 .foo1 00000008 0000000000002000 | ||
| 54 | # SECTIONS-NEXT: 2 .foo2 00000008 0000000000002008 | ||
| 55 | # SECTIONS-NEXT: 3 .text 00000000 0000000000002010 | ||
| 56 | # SECTIONS-NEXT: 4 .bar1 00000008 0000000000003000 | ||
| 57 | # SECTIONS-NEXT: 5 .bar2 00000008 0000000000003008 | ||
| 58 | # SECTIONS-NEXT: 6 .bar3 00000008 0000000000003010 | ||
deps/lld/test/ELF/linkerscript/at3.s deleted-38| ... | @@ -1,38 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "MEMORY { \ | ||
| 4 | # RUN: FOO (ax) : ORIGIN = 0x1000, LENGTH = 0x100 \ | ||
| 5 | # RUN: BAR (ax) : ORIGIN = 0x2000, LENGTH = 0x100 \ | ||
| 6 | # RUN: ZED (ax) : ORIGIN = 0x3000, LENGTH = 0x100 \ | ||
| 7 | # RUN: FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x200 \ | ||
| 8 | # RUN: } \ | ||
| 9 | # RUN: SECTIONS { \ | ||
| 10 | # RUN: .foo1 : { *(.foo1) } > FOO AT>FLASH \ | ||
| 11 | # RUN: .foo2 : { *(.foo2) BYTE(0x42) } > BAR AT>FLASH \ | ||
| 12 | # RUN: .foo3 : { *(.foo3) } > ZED AT>FLASH \ | ||
| 13 | # RUN: }" > %t.script | ||
| 14 | # RUN: ld.lld %t.o --script %t.script -o %t | ||
| 15 | # RUN: llvm-readelf -sections -program-headers %t | FileCheck %s | ||
| 16 | |||
| 17 | # CHECK: .foo1 PROGBITS 0000000000001000 001000 | ||
| 18 | # CHECK: .foo2 PROGBITS 0000000000002000 002000 | ||
| 19 | # CHECK: .foo3 PROGBITS 0000000000003000 003000 | ||
| 20 | |||
| 21 | # CHECK: Program Headers: | ||
| 22 | # CHECK-NOT: LOAD | ||
| 23 | |||
| 24 | # CHECK: Type Offset VirtAddr PhysAddr | ||
| 25 | # CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000006000 | ||
| 26 | # CHECK-NEXT: LOAD 0x002000 0x0000000000002000 0x0000000000006008 | ||
| 27 | # CHECK-NEXT: LOAD 0x003000 0x0000000000003000 0x0000000000006011 | ||
| 28 | |||
| 29 | # CHECK-NOT: LOAD | ||
| 30 | |||
| 31 | .section .foo1, "a" | ||
| 32 | .quad 0 | ||
| 33 | |||
| 34 | .section .foo2, "ax" | ||
| 35 | .quad 0 | ||
| 36 | |||
| 37 | .section .foo3, "ax" | ||
| 38 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/at3.test created+31| ... | @@ -0,0 +1,31 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/at3.s -o %t.o | ||
| 3 | # RUN: ld.lld %t.o --script %s -o %t | ||
| 4 | # RUN: llvm-readelf -sections -program-headers %t | FileCheck %s | ||
| 5 | |||
| 6 | MEMORY { | ||
| 7 | FOO (ax) : ORIGIN = 0x1000, LENGTH = 0x100 | ||
| 8 | BAR (ax) : ORIGIN = 0x2000, LENGTH = 0x100 | ||
| 9 | ZED (ax) : ORIGIN = 0x3000, LENGTH = 0x100 | ||
| 10 | FLASH (ax) : ORIGIN = 0x6000, LENGTH = 0x200 | ||
| 11 | } | ||
| 12 | |||
| 13 | SECTIONS { | ||
| 14 | .foo1 : { *(.foo1) } > FOO AT>FLASH | ||
| 15 | .foo2 : { *(.foo2) BYTE(0x42) } > BAR AT>FLASH | ||
| 16 | .foo3 : { *(.foo3) } > ZED AT>FLASH | ||
| 17 | } | ||
| 18 | |||
| 19 | # CHECK: .foo1 PROGBITS 0000000000001000 001000 | ||
| 20 | # CHECK: .foo2 PROGBITS 0000000000002000 002000 | ||
| 21 | # CHECK: .foo3 PROGBITS 0000000000003000 003000 | ||
| 22 | |||
| 23 | # CHECK: Program Headers: | ||
| 24 | # CHECK-NOT: LOAD | ||
| 25 | |||
| 26 | # CHECK: Type Offset VirtAddr PhysAddr | ||
| 27 | # CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000006000 | ||
| 28 | # CHECK-NEXT: LOAD 0x002000 0x0000000000002000 0x0000000000006008 | ||
| 29 | # CHECK-NEXT: LOAD 0x003000 0x0000000000003000 0x0000000000006011 | ||
| 30 | |||
| 31 | # CHECK-NOT: LOAD | ||
deps/lld/test/ELF/linkerscript/at4.s created+36| ... | @@ -0,0 +1,36 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: . = 0x1000; \ | ||
| 5 | # RUN: .aaa : { *(.aaa) } \ | ||
| 6 | # RUN: .bbb : AT(0x2008) { *(.bbb) } \ | ||
| 7 | # RUN: .ccc : { *(.ccc) } \ | ||
| 8 | # RUN: }" > %t.script | ||
| 9 | # RUN: ld.lld %t --script %t.script -o %t2 | ||
| 10 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s | ||
| 11 | |||
| 12 | # CHECK: Type: PT_LOAD | ||
| 13 | # CHECK-NEXT: Offset: 0x1000 | ||
| 14 | # CHECK-NEXT: VirtualAddress: 0x1000 | ||
| 15 | # CHECK-NEXT: PhysicalAddress: 0x1000 | ||
| 16 | # CHECK-NEXT: FileSize: 8 | ||
| 17 | # CHECK-NEXT: MemSize: 8 | ||
| 18 | # CHECK: Type: PT_LOAD | ||
| 19 | # CHECK-NEXT: Offset: 0x1008 | ||
| 20 | # CHECK-NEXT: VirtualAddress: 0x1008 | ||
| 21 | # CHECK-NEXT: PhysicalAddress: 0x2008 | ||
| 22 | # CHECK-NEXT: FileSize: 17 | ||
| 23 | # CHECK-NEXT: MemSize: 17 | ||
| 24 | |||
| 25 | .global _start | ||
| 26 | _start: | ||
| 27 | nop | ||
| 28 | |||
| 29 | .section .aaa, "a" | ||
| 30 | .quad 0 | ||
| 31 | |||
| 32 | .section .bbb, "a" | ||
| 33 | .quad 0 | ||
| 34 | |||
| 35 | .section .ccc, "a" | ||
| 36 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/at5.test created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: not ld.lld -o %t.exe %t.o --script %s 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | MEMORY { | ||
| 6 | FLASH (ax) : ORIGIN = 0x2000, LENGTH = 0x100 | ||
| 7 | RAM (aw) : ORIGIN = 0x5000, LENGTH = 0x100 | ||
| 8 | } | ||
| 9 | |||
| 10 | SECTIONS { | ||
| 11 | .foo1 : AT(0x500) { *(.foo1) } > FLASH AT>FLASH | ||
| 12 | } | ||
| 13 | |||
| 14 | # CHECK: error: section can't have both LMA and a load region | ||
deps/lld/test/ELF/linkerscript/broken-memory-declaration.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | ## Check we do not crash. | ||
| 4 | |||
| 5 | # RUN: echo "MEMORY { FLASH (rx) : ORIGIN = 0x1000< LENGTH" > %t.script | ||
| 6 | # RUN: not ld.lld -o %t --script %t.script 2>&1 | FileCheck %s | ||
| 7 | # CHECK: unexpected EOF | ||
| 8 | |||
| 9 | # RUN: echo "MEMORY { FLASH (rx) : ORIGIN = 0x1000< ORIGIN" > %t.script | ||
| 10 | # RUN: not ld.lld -o %t --script %t.script 2>&1 | FileCheck %s | ||
| 11 | |||
| 12 | # RUN: echo "MEMORY { FLASH (rx) : ORIGIN = 0x1000, LENGTH = CONSTANT" > %t.script | ||
| 13 | # RUN: not ld.lld -o %t --script %t.script 2>&1 | FileCheck %s | ||
deps/lld/test/ELF/linkerscript/bss-fill.s deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { .bss : { . += 0x10000; *(.bss) } =0xFF };" > %t.script | ||
| 4 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 5 | |||
| 6 | .section .bss,"",@nobits | ||
| 7 | .short 0 | ||
deps/lld/test/ELF/linkerscript/bss-fill.test created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .bss,"",@nobits; .short 0' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 5 | |||
| 6 | ## Check we do not crash. | ||
| 7 | |||
| 8 | SECTIONS { | ||
| 9 | .bss : { | ||
| 10 | . += 0x10000; | ||
| 11 | *(.bss) | ||
| 12 | } =0xFF | ||
| 13 | } | ||
deps/lld/test/ELF/linkerscript/common-filespec.s deleted-105| ... | @@ -1,105 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfile0.o | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec1.s -o %tfile1.o | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec2.s -o %tfile2.o | ||
| 5 | # RUN: echo "SECTIONS { .common_0 : { *file0.o(COMMON) } .common_1 : { *file1.o(COMMON) } .common_2 : { *file2.o(COMMON) } }" > %t.script | ||
| 6 | # RUN: ld.lld -o %t1 --script %t.script %tfile0.o %tfile1.o %tfile2.o | ||
| 7 | # RUN: llvm-readobj -s -t %t1 | FileCheck %s | ||
| 8 | |||
| 9 | # Make sure all 3 sections are allocated and they have sizes and alignments | ||
| 10 | # corresponding to the commons assigned to them | ||
| 11 | # CHECK: Section { | ||
| 12 | # CHECK: Index: | ||
| 13 | # CHECK: Name: .common_0 | ||
| 14 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 15 | # CHECK-NEXT: Flags [ | ||
| 16 | # CHECK-NEXT: SHF_ALLOC | ||
| 17 | # CHECK-NEXT: SHF_WRITE | ||
| 18 | # CHECK-NEXT: ] | ||
| 19 | # CHECK-NEXT: Address: 0x4 | ||
| 20 | # CHECK-NEXT: Offset: 0x | ||
| 21 | # CHECK-NEXT: Size: 4 | ||
| 22 | # CHECK-NEXT: Link: 0 | ||
| 23 | # CHECK-NEXT: Info: 0 | ||
| 24 | # CHECK-NEXT: AddressAlignment: 4 | ||
| 25 | # CHECK-NEXT: EntrySize: 0 | ||
| 26 | # CHECK-NEXT: } | ||
| 27 | # CHECK: Section { | ||
| 28 | # CHECK: Index: | ||
| 29 | # CHECK: Name: .common_1 | ||
| 30 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 31 | # CHECK-NEXT: Flags [ | ||
| 32 | # CHECK-NEXT: SHF_ALLOC | ||
| 33 | # CHECK-NEXT: SHF_WRITE | ||
| 34 | # CHECK-NEXT: ] | ||
| 35 | # CHECK-NEXT: Address: 0x8 | ||
| 36 | # CHECK-NEXT: Offset: 0x | ||
| 37 | # CHECK-NEXT: Size: 8 | ||
| 38 | # CHECK-NEXT: Link: 0 | ||
| 39 | # CHECK-NEXT: Info: 0 | ||
| 40 | # CHECK-NEXT: AddressAlignment: 8 | ||
| 41 | # CHECK-NEXT: EntrySize: 0 | ||
| 42 | # CHECK-NEXT: } | ||
| 43 | # CHECK: Section { | ||
| 44 | # CHECK: Index: | ||
| 45 | # CHECK: Name: .common_2 | ||
| 46 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 47 | # CHECK-NEXT: Flags [ | ||
| 48 | # CHECK-NEXT: SHF_ALLOC | ||
| 49 | # CHECK-NEXT: SHF_WRITE | ||
| 50 | # CHECK-NEXT: ] | ||
| 51 | # CHECK-NEXT: Address: 0x10 | ||
| 52 | # CHECK-NEXT: Offset: 0x | ||
| 53 | # CHECK-NEXT: Size: 48 | ||
| 54 | # CHECK-NEXT: Link: 0 | ||
| 55 | # CHECK-NEXT: Info: 0 | ||
| 56 | # CHECK-NEXT: AddressAlignment: 16 | ||
| 57 | # CHECK-NEXT: EntrySize: 0 | ||
| 58 | # CHECK-NEXT: } | ||
| 59 | |||
| 60 | # Commons with unique name in each file must be assigned to that file's section. | ||
| 61 | # For a common with multiple definitions, the largest one wins and it must be | ||
| 62 | # assigned to the section from the file which provided the winning def | ||
| 63 | # CHECK: Symbol { | ||
| 64 | # CHECK: Name: common_multiple | ||
| 65 | # CHECK-NEXT: Value: 0x10 | ||
| 66 | # CHECK-NEXT: Size: 32 | ||
| 67 | # CHECK-NEXT: Binding: Global | ||
| 68 | # CHECK-NEXT: Type: Object | ||
| 69 | # CHECK-NEXT: Other: 0 | ||
| 70 | # CHECK-NEXT: Section: .common_2 | ||
| 71 | # CHECK-NEXT: } | ||
| 72 | # CHECK: Symbol { | ||
| 73 | # CHECK: Name: common_uniq_0 | ||
| 74 | # CHECK-NEXT: Value: 0x4 | ||
| 75 | # CHECK-NEXT: Size: 4 | ||
| 76 | # CHECK-NEXT: Binding: Global | ||
| 77 | # CHECK-NEXT: Type: Object | ||
| 78 | # CHECK-NEXT: Other: 0 | ||
| 79 | # CHECK-NEXT: Section: .common_0 | ||
| 80 | # CHECK-NEXT: } | ||
| 81 | # CHECK: Symbol { | ||
| 82 | # CHECK: Name: common_uniq_1 | ||
| 83 | # CHECK-NEXT: Value: 0x8 | ||
| 84 | # CHECK-NEXT: Size: 8 | ||
| 85 | # CHECK-NEXT: Binding: Global | ||
| 86 | # CHECK-NEXT: Type: Object | ||
| 87 | # CHECK-NEXT: Other: 0 | ||
| 88 | # CHECK-NEXT: Section: .common_1 | ||
| 89 | # CHECK-NEXT: } | ||
| 90 | # CHECK: Symbol { | ||
| 91 | # CHECK: Name: common_uniq_2 | ||
| 92 | # CHECK-NEXT: Value: 0x30 | ||
| 93 | # CHECK-NEXT: Size: 16 | ||
| 94 | # CHECK-NEXT: Binding: Global | ||
| 95 | # CHECK-NEXT: Type: Object | ||
| 96 | # CHECK-NEXT: Other: 0 | ||
| 97 | # CHECK-NEXT: Section: .common_2 | ||
| 98 | # CHECK-NEXT: } | ||
| 99 | |||
| 100 | .globl _start | ||
| 101 | _start: | ||
| 102 | jmp _start | ||
| 103 | |||
| 104 | .comm common_uniq_0,4,4 | ||
| 105 | .comm common_multiple,8,8 | ||
deps/lld/test/ELF/linkerscript/common-filespec.test created+104| ... | @@ -0,0 +1,104 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.long 0; .comm common_uniq_0,4,4; .comm common_multiple,8,8' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tfile0.o | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec1.s -o %tfile1.o | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec2.s -o %tfile2.o | ||
| 6 | # RUN: ld.lld -o %t1 --script %s %tfile0.o %tfile1.o %tfile2.o | ||
| 7 | # RUN: llvm-readobj -s -t %t1 | FileCheck %s | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | .common_0 : { *file0.o(COMMON) } | ||
| 11 | .common_1 : { *file1.o(COMMON) } | ||
| 12 | .common_2 : { *file2.o(COMMON) } | ||
| 13 | } | ||
| 14 | |||
| 15 | # Make sure all 3 sections are allocated and they have sizes and alignments | ||
| 16 | # corresponding to the commons assigned to them | ||
| 17 | # CHECK: Section { | ||
| 18 | # CHECK: Index: | ||
| 19 | # CHECK: Name: .common_0 | ||
| 20 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 21 | # CHECK-NEXT: Flags [ | ||
| 22 | # CHECK-NEXT: SHF_ALLOC | ||
| 23 | # CHECK-NEXT: SHF_WRITE | ||
| 24 | # CHECK-NEXT: ] | ||
| 25 | # CHECK-NEXT: Address: 0x4 | ||
| 26 | # CHECK-NEXT: Offset: 0x | ||
| 27 | # CHECK-NEXT: Size: 4 | ||
| 28 | # CHECK-NEXT: Link: 0 | ||
| 29 | # CHECK-NEXT: Info: 0 | ||
| 30 | # CHECK-NEXT: AddressAlignment: 4 | ||
| 31 | # CHECK-NEXT: EntrySize: 0 | ||
| 32 | # CHECK-NEXT: } | ||
| 33 | # CHECK: Section { | ||
| 34 | # CHECK: Index: | ||
| 35 | # CHECK: Name: .common_1 | ||
| 36 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 37 | # CHECK-NEXT: Flags [ | ||
| 38 | # CHECK-NEXT: SHF_ALLOC | ||
| 39 | # CHECK-NEXT: SHF_WRITE | ||
| 40 | # CHECK-NEXT: ] | ||
| 41 | # CHECK-NEXT: Address: 0x8 | ||
| 42 | # CHECK-NEXT: Offset: 0x | ||
| 43 | # CHECK-NEXT: Size: 8 | ||
| 44 | # CHECK-NEXT: Link: 0 | ||
| 45 | # CHECK-NEXT: Info: 0 | ||
| 46 | # CHECK-NEXT: AddressAlignment: 8 | ||
| 47 | # CHECK-NEXT: EntrySize: 0 | ||
| 48 | # CHECK-NEXT: } | ||
| 49 | # CHECK: Section { | ||
| 50 | # CHECK: Index: | ||
| 51 | # CHECK: Name: .common_2 | ||
| 52 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 53 | # CHECK-NEXT: Flags [ | ||
| 54 | # CHECK-NEXT: SHF_ALLOC | ||
| 55 | # CHECK-NEXT: SHF_WRITE | ||
| 56 | # CHECK-NEXT: ] | ||
| 57 | # CHECK-NEXT: Address: 0x10 | ||
| 58 | # CHECK-NEXT: Offset: 0x | ||
| 59 | # CHECK-NEXT: Size: 48 | ||
| 60 | # CHECK-NEXT: Link: 0 | ||
| 61 | # CHECK-NEXT: Info: 0 | ||
| 62 | # CHECK-NEXT: AddressAlignment: 16 | ||
| 63 | # CHECK-NEXT: EntrySize: 0 | ||
| 64 | # CHECK-NEXT: } | ||
| 65 | |||
| 66 | # Commons with unique name in each file must be assigned to that file's section. | ||
| 67 | # For a common with multiple definitions, the largest one wins and it must be | ||
| 68 | # assigned to the section from the file which provided the winning def | ||
| 69 | # CHECK: Symbol { | ||
| 70 | # CHECK: Name: common_multiple | ||
| 71 | # CHECK-NEXT: Value: 0x10 | ||
| 72 | # CHECK-NEXT: Size: 32 | ||
| 73 | # CHECK-NEXT: Binding: Global | ||
| 74 | # CHECK-NEXT: Type: Object | ||
| 75 | # CHECK-NEXT: Other: 0 | ||
| 76 | # CHECK-NEXT: Section: .common_2 | ||
| 77 | # CHECK-NEXT: } | ||
| 78 | # CHECK: Symbol { | ||
| 79 | # CHECK: Name: common_uniq_0 | ||
| 80 | # CHECK-NEXT: Value: 0x4 | ||
| 81 | # CHECK-NEXT: Size: 4 | ||
| 82 | # CHECK-NEXT: Binding: Global | ||
| 83 | # CHECK-NEXT: Type: Object | ||
| 84 | # CHECK-NEXT: Other: 0 | ||
| 85 | # CHECK-NEXT: Section: .common_0 | ||
| 86 | # CHECK-NEXT: } | ||
| 87 | # CHECK: Symbol { | ||
| 88 | # CHECK: Name: common_uniq_1 | ||
| 89 | # CHECK-NEXT: Value: 0x8 | ||
| 90 | # CHECK-NEXT: Size: 8 | ||
| 91 | # CHECK-NEXT: Binding: Global | ||
| 92 | # CHECK-NEXT: Type: Object | ||
| 93 | # CHECK-NEXT: Other: 0 | ||
| 94 | # CHECK-NEXT: Section: .common_1 | ||
| 95 | # CHECK-NEXT: } | ||
| 96 | # CHECK: Symbol { | ||
| 97 | # CHECK: Name: common_uniq_2 | ||
| 98 | # CHECK-NEXT: Value: 0x30 | ||
| 99 | # CHECK-NEXT: Size: 16 | ||
| 100 | # CHECK-NEXT: Binding: Global | ||
| 101 | # CHECK-NEXT: Type: Object | ||
| 102 | # CHECK-NEXT: Other: 0 | ||
| 103 | # CHECK-NEXT: Section: .common_2 | ||
| 104 | # CHECK-NEXT: } | ||
deps/lld/test/ELF/linkerscript/constructor.s deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { foo : { *(.foo) CONSTRUCTORS } }" > %t.script | ||
| 4 | # RUN: ld.lld -o %t1 --script %t.script %t.o | ||
| 5 | |||
| 6 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 7 | # CHECK: Sections: | ||
| 8 | # CHECK-NEXT: Idx Name Size | ||
| 9 | # CHECK-NEXT: 0 00000000 | ||
| 10 | # CHECK-NEXT: 1 foo 00000001 | ||
| 11 | |||
| 12 | .section foo, "a" | ||
| 13 | .byte 0 | ||
deps/lld/test/ELF/linkerscript/constructor.test created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section foo, "a"; .byte 0' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | # RUN: ld.lld -o %t1 --script %s %t.o | ||
| 5 | |||
| 6 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 7 | # CHECK: Sections: | ||
| 8 | # CHECK-NEXT: Idx Name Size | ||
| 9 | # CHECK-NEXT: 0 00000000 | ||
| 10 | # CHECK-NEXT: 1 foo 00000001 | ||
| 11 | |||
| 12 | SECTIONS { | ||
| 13 | foo : { | ||
| 14 | *(.foo) | ||
| 15 | CONSTRUCTORS | ||
| 16 | } | ||
| 17 | } | ||
deps/lld/test/ELF/linkerscript/copy-rel-symbol-value-err.s+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-symbol-value.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-symbol-value.s -o %t2.o |
| 4 | # RUN: ld.lld %t2.o -o %t2.so -shared | 4 | # RUN: ld.lld %t2.o -o %t2.so -shared |
| 5 | # RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; foo = bar; }" > %t.script | 5 | # RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; foo = bar; }" > %t.script |
| 6 | # RUN: not ld.lld %t.o %t2.so --script %t.script -o %t 2>&1 | FileCheck %s | 6 | # RUN: not ld.lld %t.o %t2.so --script %t.script -o /dev/null 2>&1 | FileCheck %s |
| 7 | 7 | ||
| 8 | # CHECK: symbol not found: bar | 8 | # CHECK: symbol not found: bar |
| 9 | 9 |
deps/lld/test/ELF/linkerscript/data-commands-gc.s+1-1| ... | @@ -4,7 +4,7 @@ | ... | @@ -4,7 +4,7 @@ |
| 4 | # RUN: ld.lld --gc-sections -o %t %t.o --script %t.script | 4 | # RUN: ld.lld --gc-sections -o %t %t.o --script %t.script |
| 5 | # RUN: llvm-objdump -t %t | FileCheck %s | 5 | # RUN: llvm-objdump -t %t | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: 0000000000000011 .rodata 00000000 bar | 7 | # CHECK: 0000000000000008 .rodata 00000000 bar |
| 8 | 8 | ||
| 9 | .section .rodata.bar | 9 | .section .rodata.bar |
| 10 | .quad 0x1122334455667788 | 10 | .quad 0x1122334455667788 |
deps/lld/test/ELF/linkerscript/data-commands.s deleted-117| ... | @@ -1,117 +0,0 @@ | ||
| 1 | # REQUIRES: x86,mips | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS \ | ||
| 4 | # RUN: { \ | ||
| 5 | # RUN: .foo : { \ | ||
| 6 | # RUN: *(.foo.1) \ | ||
| 7 | # RUN: BYTE(0x11) \ | ||
| 8 | # RUN: *(.foo.2) \ | ||
| 9 | # RUN: SHORT(0x1122) \ | ||
| 10 | # RUN: *(.foo.3) \ | ||
| 11 | # RUN: LONG(0x11223344) \ | ||
| 12 | # RUN: *(.foo.4) \ | ||
| 13 | # RUN: QUAD(0x1122334455667788) \ | ||
| 14 | # RUN: } \ | ||
| 15 | # RUN: .bar : { \ | ||
| 16 | # RUN: *(.bar.1) \ | ||
| 17 | # RUN: BYTE(a + 1) \ | ||
| 18 | # RUN: *(.bar.2) \ | ||
| 19 | # RUN: SHORT(b) \ | ||
| 20 | # RUN: *(.bar.3) \ | ||
| 21 | # RUN: LONG(c + 2) \ | ||
| 22 | # RUN: *(.bar.4) \ | ||
| 23 | # RUN: QUAD(d) \ | ||
| 24 | # RUN: } \ | ||
| 25 | # RUN: }" > %t.script | ||
| 26 | # RUN: ld.lld -o %t %t.o --script %t.script | ||
| 27 | # RUN: llvm-objdump -s %t | FileCheck %s | ||
| 28 | |||
| 29 | # CHECK: Contents of section .foo: | ||
| 30 | # CHECK-NEXT: ff11ff22 11ff4433 2211ff88 77665544 | ||
| 31 | # CHECK-NEXT: 332211 | ||
| 32 | |||
| 33 | # CHECK: Contents of section .bar: | ||
| 34 | # CHECK-NEXT: ff12ff22 11ff4633 2211ff88 77665544 | ||
| 35 | # CHECK-NEXT: 332211 | ||
| 36 | |||
| 37 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %tmips64be | ||
| 38 | # RUN: ld.lld --script %t.script %tmips64be -o %t2 | ||
| 39 | # RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=BE | ||
| 40 | # BE: Contents of section .foo: | ||
| 41 | # BE-NEXT: ff11ff11 22ff1122 3344ff11 22334455 | ||
| 42 | # BE-NEXT: 667788 | ||
| 43 | # BE-NEXT: Contents of section .bar: | ||
| 44 | # BE-NEXT: ff12ff11 22ff1122 3346ff11 22334455 | ||
| 45 | # BE-NEXT: 667788 | ||
| 46 | |||
| 47 | # RUN: echo "MEMORY { \ | ||
| 48 | # RUN: rom (rwx) : ORIGIN = 0x00, LENGTH = 2K \ | ||
| 49 | # RUN: } \ | ||
| 50 | # RUN: SECTIONS { \ | ||
| 51 | # RUN: .foo : { \ | ||
| 52 | # RUN: *(.foo.1) \ | ||
| 53 | # RUN: BYTE(0x11) \ | ||
| 54 | # RUN: *(.foo.2) \ | ||
| 55 | # RUN: SHORT(0x1122) \ | ||
| 56 | # RUN: *(.foo.3) \ | ||
| 57 | # RUN: LONG(0x11223344) \ | ||
| 58 | # RUN: *(.foo.4) \ | ||
| 59 | # RUN: QUAD(0x1122334455667788) \ | ||
| 60 | # RUN: } > rom \ | ||
| 61 | # RUN: .bar : { \ | ||
| 62 | # RUN: *(.bar.1) \ | ||
| 63 | # RUN: BYTE(a + 1) \ | ||
| 64 | # RUN: *(.bar.2) \ | ||
| 65 | # RUN: SHORT(b) \ | ||
| 66 | # RUN: *(.bar.3) \ | ||
| 67 | # RUN: LONG(c + 2) \ | ||
| 68 | # RUN: *(.bar.4) \ | ||
| 69 | # RUN: QUAD(d) \ | ||
| 70 | # RUN: } > rom \ | ||
| 71 | # RUN: }" > %t-memory.script | ||
| 72 | # RUN: ld.lld -o %t-memory %t.o --script %t-memory.script | ||
| 73 | # RUN: llvm-objdump -s %t-memory | FileCheck %s --check-prefix=MEM | ||
| 74 | |||
| 75 | # MEM: Contents of section .foo: | ||
| 76 | # MEM-NEXT: 0000 ff11ff22 11ff4433 2211ff88 77665544 | ||
| 77 | # MEM-NEXT: 0010 332211 | ||
| 78 | |||
| 79 | # MEM: Contents of section .bar: | ||
| 80 | # MEM-NEXT: 0013 ff12ff22 11ff4633 2211ff88 77665544 | ||
| 81 | # MEM-NEXT: 0023 332211 | ||
| 82 | |||
| 83 | .global a | ||
| 84 | a = 0x11 | ||
| 85 | |||
| 86 | .global b | ||
| 87 | b = 0x1122 | ||
| 88 | |||
| 89 | .global c | ||
| 90 | c = 0x11223344 | ||
| 91 | |||
| 92 | .global d | ||
| 93 | d = 0x1122334455667788 | ||
| 94 | |||
| 95 | .section .foo.1, "a" | ||
| 96 | .byte 0xFF | ||
| 97 | |||
| 98 | .section .foo.2, "a" | ||
| 99 | .byte 0xFF | ||
| 100 | |||
| 101 | .section .foo.3, "a" | ||
| 102 | .byte 0xFF | ||
| 103 | |||
| 104 | .section .foo.4, "a" | ||
| 105 | .byte 0xFF | ||
| 106 | |||
| 107 | .section .bar.1, "a" | ||
| 108 | .byte 0xFF | ||
| 109 | |||
| 110 | .section .bar.2, "a" | ||
| 111 | .byte 0xFF | ||
| 112 | |||
| 113 | .section .bar.3, "a" | ||
| 114 | .byte 0xFF | ||
| 115 | |||
| 116 | .section .bar.4, "a" | ||
| 117 | .byte 0xFF | ||
deps/lld/test/ELF/linkerscript/data-commands1.test created+45| ... | @@ -0,0 +1,45 @@ | ||
| 1 | # REQUIRES: x86,mips | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/data-commands.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t %t.o --script %s | ||
| 4 | # RUN: llvm-objdump -s %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .foo : { | ||
| 8 | *(.foo.1) | ||
| 9 | BYTE(0x11) | ||
| 10 | *(.foo.2) | ||
| 11 | SHORT(0x1122) | ||
| 12 | *(.foo.3) | ||
| 13 | LONG(0x11223344) | ||
| 14 | *(.foo.4) | ||
| 15 | QUAD(0x1122334455667788) | ||
| 16 | } | ||
| 17 | .bar : { | ||
| 18 | *(.bar.1) | ||
| 19 | BYTE(a + 1) | ||
| 20 | *(.bar.2) | ||
| 21 | SHORT(b) | ||
| 22 | *(.bar.3) | ||
| 23 | LONG(c + 2) | ||
| 24 | *(.bar.4) | ||
| 25 | QUAD(d) | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | # CHECK: Contents of section .foo: | ||
| 30 | # CHECK-NEXT: ff11ff22 11ff4433 2211ff88 77665544 | ||
| 31 | # CHECK-NEXT: 332211 | ||
| 32 | |||
| 33 | # CHECK: Contents of section .bar: | ||
| 34 | # CHECK-NEXT: ff12ff22 11ff4633 2211ff88 77665544 | ||
| 35 | # CHECK-NEXT: 332211 | ||
| 36 | |||
| 37 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %p/Inputs/data-commands.s -o %t2.o | ||
| 38 | # RUN: ld.lld --script %s %t2.o -o %t2 | ||
| 39 | # RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=BIGENDIAN %s | ||
| 40 | # BIGENDIAN: Contents of section .foo: | ||
| 41 | # BIGENDIAN-NEXT: ff11ff11 22ff1122 3344ff11 22334455 | ||
| 42 | # BIGENDIAN-NEXT: 667788 | ||
| 43 | # BIGENDIAN-NEXT: Contents of section .bar: | ||
| 44 | # BIGENDIAN-NEXT: ff12ff11 22ff1122 3346ff11 22334455 | ||
| 45 | # BIGENDIAN-NEXT: 667788 | ||
deps/lld/test/ELF/linkerscript/data-commands2.test created+40| ... | @@ -0,0 +1,40 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/data-commands.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t %t.o --script %s | ||
| 4 | # RUN: llvm-objdump -s %t | FileCheck %s | ||
| 5 | |||
| 6 | MEMORY { | ||
| 7 | rom (rwx) : ORIGIN = 0x00, LENGTH = 2K | ||
| 8 | } | ||
| 9 | |||
| 10 | SECTIONS { | ||
| 11 | .foo : { | ||
| 12 | *(.foo.1) | ||
| 13 | BYTE(0x11) | ||
| 14 | *(.foo.2) | ||
| 15 | SHORT(0x1122) | ||
| 16 | *(.foo.3) | ||
| 17 | LONG(0x11223344) | ||
| 18 | *(.foo.4) | ||
| 19 | QUAD(0x1122334455667788) | ||
| 20 | } > rom | ||
| 21 | |||
| 22 | .bar : { | ||
| 23 | *(.bar.1) | ||
| 24 | BYTE(a + 1) | ||
| 25 | *(.bar.2) | ||
| 26 | SHORT(b) | ||
| 27 | *(.bar.3) | ||
| 28 | LONG(c + 2) | ||
| 29 | *(.bar.4) | ||
| 30 | QUAD(d) | ||
| 31 | } > rom | ||
| 32 | } | ||
| 33 | |||
| 34 | # CHECK: Contents of section .foo: | ||
| 35 | # CHECK-NEXT: 0000 ff11ff22 11ff4433 2211ff88 77665544 | ||
| 36 | # CHECK-NEXT: 0010 332211 | ||
| 37 | |||
| 38 | # CHECK: Contents of section .bar: | ||
| 39 | # CHECK-NEXT: 0013 ff12ff22 11ff4633 2211ff88 77665544 | ||
| 40 | # CHECK-NEXT: 0023 332211 | ||
deps/lld/test/ELF/linkerscript/data-segment-relro.s deleted-70| ... | @@ -1,70 +0,0 @@ | ||
| 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 %p/Inputs/shared.s -o %t2.o | ||
| 4 | # RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | # RUN: echo "SECTIONS { \ | ||
| 7 | # RUN: . = SIZEOF_HEADERS; \ | ||
| 8 | # RUN: .plt : { *(.plt) } \ | ||
| 9 | # RUN: .text : { *(.text) } \ | ||
| 10 | # RUN: . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); \ | ||
| 11 | # RUN: .dynamic : { *(.dynamic) } \ | ||
| 12 | # RUN: .got : { *(.got) } \ | ||
| 13 | # RUN: . = DATA_SEGMENT_RELRO_END (1 ? 24 : 0, .); \ | ||
| 14 | # RUN: .got.plt : { *(.got.plt) } \ | ||
| 15 | # RUN: .data : { *(.data) } \ | ||
| 16 | # RUN: .bss : { *(.bss) } \ | ||
| 17 | # RUN: . = DATA_SEGMENT_END (.); \ | ||
| 18 | # RUN: }" > %t.script | ||
| 19 | |||
| 20 | ## With relro or without DATA_SEGMENT_RELRO_END just aligns to | ||
| 21 | ## page boundary. | ||
| 22 | # RUN: ld.lld --hash-style=sysv -z norelro %t1.o %t2.so --script %t.script -o %t | ||
| 23 | # RUN: llvm-readobj -s %t | FileCheck %s | ||
| 24 | # RUN: ld.lld --hash-style=sysv -z relro %t1.o %t2.so --script %t.script -o %t2 | ||
| 25 | # RUN: llvm-readobj -s %t2 | FileCheck %s | ||
| 26 | |||
| 27 | # CHECK: Section { | ||
| 28 | # CHECK: Index: | ||
| 29 | # CHECK: Name: .got | ||
| 30 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 31 | # CHECK-NEXT: Flags [ | ||
| 32 | # CHECK-NEXT: SHF_ALLOC | ||
| 33 | # CHECK-NEXT: SHF_WRITE | ||
| 34 | # CHECK-NEXT: ] | ||
| 35 | # CHECK-NEXT: Address: 0x10F0 | ||
| 36 | # CHECK-NEXT: Offset: 0x10F0 | ||
| 37 | # CHECK-NEXT: Size: | ||
| 38 | # CHECK-NEXT: Link: | ||
| 39 | # CHECK-NEXT: Info: | ||
| 40 | # CHECK-NEXT: AddressAlignment: | ||
| 41 | # CHECK-NEXT: EntrySize: | ||
| 42 | # CHECK-NEXT: } | ||
| 43 | # CHECK-NEXT: Section { | ||
| 44 | # CHECK-NEXT: Index: | ||
| 45 | # CHECK-NEXT: Name: .got.plt | ||
| 46 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 47 | # CHECK-NEXT: Flags [ | ||
| 48 | # CHECK-NEXT: SHF_ALLOC | ||
| 49 | # CHECK-NEXT: SHF_WRITE | ||
| 50 | # CHECK-NEXT: ] | ||
| 51 | # CHECK-NEXT: Address: 0x2000 | ||
| 52 | # CHECK-NEXT: Offset: 0x2000 | ||
| 53 | # CHECK-NEXT: Size: | ||
| 54 | # CHECK-NEXT: Link: | ||
| 55 | # CHECK-NEXT: Info: | ||
| 56 | # CHECK-NEXT: AddressAlignment: | ||
| 57 | # CHECK-NEXT: EntrySize: | ||
| 58 | # CHECK-NEXT: } | ||
| 59 | |||
| 60 | .global _start | ||
| 61 | _start: | ||
| 62 | .long bar | ||
| 63 | jmp *bar2@GOTPCREL(%rip) | ||
| 64 | |||
| 65 | .section .data,"aw" | ||
| 66 | .quad 0 | ||
| 67 | |||
| 68 | .zero 4 | ||
| 69 | .section .foo,"aw" | ||
| 70 | .section .bss,"",@nobits | ||
deps/lld/test/ELF/linkerscript/data-segment-relro.test created+66| ... | @@ -0,0 +1,66 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/data-segment-relro.s -o %t1.o | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | ||
| 4 | # RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | ## With relro or without DATA_SEGMENT_RELRO_END just aligns to | ||
| 7 | ## page boundary. | ||
| 8 | |||
| 9 | # RUN: ld.lld --hash-style=sysv -z norelro %t1.o %t2.so --script %s -o %t | ||
| 10 | # RUN: llvm-readobj -s %t | FileCheck %s | ||
| 11 | |||
| 12 | # RUN: ld.lld --hash-style=sysv -z relro %t1.o %t2.so --script %s -o %t2 | ||
| 13 | # RUN: llvm-readobj -s %t2 | FileCheck %s | ||
| 14 | |||
| 15 | SECTIONS { | ||
| 16 | . = SIZEOF_HEADERS; | ||
| 17 | |||
| 18 | .plt : { *(.plt) } | ||
| 19 | .text : { *(.text) } | ||
| 20 | |||
| 21 | . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); | ||
| 22 | |||
| 23 | .dynamic : { *(.dynamic) } | ||
| 24 | .got : { *(.got) } | ||
| 25 | |||
| 26 | . = DATA_SEGMENT_RELRO_END (1 ? 24 : 0, .); | ||
| 27 | |||
| 28 | .got.plt : { *(.got.plt) } | ||
| 29 | .data : { *(.data) } | ||
| 30 | .bss : { *(.bss) } | ||
| 31 | |||
| 32 | . = DATA_SEGMENT_END (.); | ||
| 33 | } | ||
| 34 | |||
| 35 | # CHECK: Section { | ||
| 36 | # CHECK: Index: | ||
| 37 | # CHECK: Name: .got | ||
| 38 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 39 | # CHECK-NEXT: Flags [ | ||
| 40 | # CHECK-NEXT: SHF_ALLOC | ||
| 41 | # CHECK-NEXT: SHF_WRITE | ||
| 42 | # CHECK-NEXT: ] | ||
| 43 | # CHECK-NEXT: Address: 0x10F0 | ||
| 44 | # CHECK-NEXT: Offset: 0x10F0 | ||
| 45 | # CHECK-NEXT: Size: | ||
| 46 | # CHECK-NEXT: Link: | ||
| 47 | # CHECK-NEXT: Info: | ||
| 48 | # CHECK-NEXT: AddressAlignment: | ||
| 49 | # CHECK-NEXT: EntrySize: | ||
| 50 | # CHECK-NEXT: } | ||
| 51 | # CHECK-NEXT: Section { | ||
| 52 | # CHECK-NEXT: Index: | ||
| 53 | # CHECK-NEXT: Name: .got.plt | ||
| 54 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 55 | # CHECK-NEXT: Flags [ | ||
| 56 | # CHECK-NEXT: SHF_ALLOC | ||
| 57 | # CHECK-NEXT: SHF_WRITE | ||
| 58 | # CHECK-NEXT: ] | ||
| 59 | # CHECK-NEXT: Address: 0x2000 | ||
| 60 | # CHECK-NEXT: Offset: 0x2000 | ||
| 61 | # CHECK-NEXT: Size: | ||
| 62 | # CHECK-NEXT: Link: | ||
| 63 | # CHECK-NEXT: Info: | ||
| 64 | # CHECK-NEXT: AddressAlignment: | ||
| 65 | # CHECK-NEXT: EntrySize: | ||
| 66 | # CHECK-NEXT: } | ||
deps/lld/test/ELF/linkerscript/define.s deleted-25| ... | @@ -1,25 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS \ | ||
| 5 | # RUN: { \ | ||
| 6 | # RUN: . = DEFINED(defined) ? 0x11000 : .; \ | ||
| 7 | # RUN: .foo : { *(.foo*) } \ | ||
| 8 | # RUN: . = DEFINED(notdefined) ? 0x12000 : 0x13000; \ | ||
| 9 | # RUN: .bar : { *(.bar*) } \ | ||
| 10 | # RUN: }" > %t.script | ||
| 11 | # RUN: ld.lld -o %t1 --script %t.script %t | ||
| 12 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 13 | |||
| 14 | # CHECK: 1 .foo 00000008 0000000000011000 DATA | ||
| 15 | # CHECK: 2 .bar 00000008 0000000000013000 DATA | ||
| 16 | # CHECK: 3 .text 00000000 0000000000013008 TEXT DATA | ||
| 17 | |||
| 18 | .global defined | ||
| 19 | defined = 0 | ||
| 20 | |||
| 21 | .section .foo,"a" | ||
| 22 | .quad 1 | ||
| 23 | |||
| 24 | .section .bar,"a" | ||
| 25 | .quad 1 | ||
deps/lld/test/ELF/linkerscript/define.test created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/define.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 4 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = DEFINED(defined) ? 0x11000 : .; | ||
| 8 | .foo : { *(.foo*) } | ||
| 9 | . = DEFINED(notdefined) ? 0x12000 : 0x13000; | ||
| 10 | .bar : { *(.bar*) } | ||
| 11 | } | ||
| 12 | |||
| 13 | # CHECK: 1 .foo 00000008 0000000000011000 DATA | ||
| 14 | # CHECK: 2 .bar 00000008 0000000000013000 DATA | ||
| 15 | # CHECK: 3 .text 00000000 0000000000013008 TEXT | ||
deps/lld/test/ELF/linkerscript/defsym.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "foo = 0x22;" > %t.script | ||
| 4 | |||
| 5 | ## This testcase checks that we apply -defsym and linker script | ||
| 6 | ## in the same order are they specified in a command line. | ||
| 7 | |||
| 8 | ## Check that linker script can override -defsym assignments. | ||
| 9 | # RUN: ld.lld %t.o -defsym=foo=0x11 -script %t.script -o %t | ||
| 10 | # RUN: llvm-readobj -t %t | FileCheck %s | ||
| 11 | # CHECK: Name: foo | ||
| 12 | # CHECK-NEXT: Value: 0x22 | ||
| 13 | |||
| 14 | ## Check that -defsym can override linker script. Check that multiple | ||
| 15 | ## -defsym commands for the same symbol are allowed. | ||
| 16 | # 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 | ||
| 18 | # REORDER: Name: foo | ||
| 19 | # REORDER-NEXT: Value: 0x33 | ||
deps/lld/test/ELF/linkerscript/diag1.test created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: not ld.lld -shared %t.o -o %t --script %s 2>&1 | FileCheck -strict-whitespace %s | ||
| 4 | |||
| 5 | SECTIONS { | ||
| 6 | .text + { *(.text) } | ||
| 7 | .keep : { *(.keep) } /* | ||
| 8 | comment line 1 | ||
| 9 | comment line 2 */ | ||
| 10 | .temp : { *(.temp) } | ||
| 11 | } | ||
| 12 | |||
| 13 | CHECK: 6: malformed number: + | ||
| 14 | CHECK-NEXT: >>> .text + { *(.text) } | ||
| 15 | CHECK-NEXT: >>> ^ | ||
deps/lld/test/ELF/linkerscript/diag2.test created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: not ld.lld -shared %t.o -o %t --script %s 2>&1 | FileCheck -strict-whitespace %s | ||
| 4 | |||
| 5 | UNKNOWN_TAG { | ||
| 6 | .text : { *(.text) } | ||
| 7 | .keep : { *(.keep) } | ||
| 8 | .temp : { *(.temp) } | ||
| 9 | } | ||
| 10 | |||
| 11 | CHECK: 5: unknown directive: UNKNOWN_TAG | ||
| 12 | CHECK-NEXT: >>> UNKNOWN_TAG { | ||
| 13 | CHECK-NEXT: >>> ^ | ||
deps/lld/test/ELF/linkerscript/diag3.test created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: not ld.lld -shared %t.o -o %t --script %s 2>&1 | FileCheck -strict-whitespace %s | ||
| 4 | |||
| 5 | SECTIONS { | ||
| 6 | .text : { *(.text) } | ||
| 7 | .keep : { *(.keep) } | ||
| 8 | boom .temp : { *(.temp) } | ||
| 9 | } | ||
| 10 | |||
| 11 | # CHECK: 8: malformed number: .temp | ||
| 12 | # CHECK-NEXT: >>> boom .temp : { *(.temp) } | ||
| 13 | # CHECK-NEXT: >>> ^ | ||
deps/lld/test/ELF/linkerscript/diag4.test created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: echo "INCLUDE \"%s\"" > %t.script | ||
| 4 | # RUN: not ld.lld -shared %t.o -o %t --script %t.script 2>&1 | FileCheck -strict-whitespace %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .text : { *(.text) } | ||
| 8 | .keep : { *(.keep) } | ||
| 9 | boom .temp : { *(.temp) } | ||
| 10 | } | ||
| 11 | |||
| 12 | # CHECK: 9: malformed number: .temp | ||
| 13 | # CHECK-NEXT: >>> boom .temp : { *(.temp) } | ||
| 14 | # CHECK-NEXT: >>> ^ | ||
| \ No newline at end of file | |||
deps/lld/test/ELF/linkerscript/diag5.test created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: echo "INCLUDE \"%s\"" > %t.script | ||
| 4 | # RUN: not ld.lld -shared %t.o -o %t --script %t.script 2>&1 | FileCheck -strict-whitespace %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .text : { *(.text) } | ||
| 8 | .keep : { *(.keep) } | ||
| 9 | boom .temp : { *(.temp) } | ||
| 10 | } | ||
| 11 | |||
| 12 | # CHECK: 9: malformed number: .temp | ||
| 13 | # CHECK-NEXT: >>> boom .temp : { *(.temp) } | ||
| 14 | # CHECK-NEXT: >>> ^ | ||
deps/lld/test/ELF/linkerscript/diag6.test created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: not ld.lld -shared %t.o -o %t --script %s 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | SECTIONS /* | ||
| 6 | |||
| 7 | CHECK: error: unclosed comment in a linker script | ||
deps/lld/test/ELF/linkerscript/diagnostic.s deleted-106| ... | @@ -1,106 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | ## Take some valid script with multiline comments | ||
| 5 | ## and check it actually works: | ||
| 6 | # RUN: echo "SECTIONS {" > %t.script | ||
| 7 | # RUN: echo ".text : { *(.text) }" >> %t.script | ||
| 8 | # RUN: echo ".keep : { *(.keep) } /*" >> %t.script | ||
| 9 | # RUN: echo "comment line 1" >> %t.script | ||
| 10 | # RUN: echo "comment line 2 */" >> %t.script | ||
| 11 | # RUN: echo ".temp : { *(.temp) } }" >> %t.script | ||
| 12 | # RUN: ld.lld -shared %t -o %t1 --script %t.script | ||
| 13 | |||
| 14 | ## Change ":" to "+" at line 2, check that error | ||
| 15 | ## message starts from correct line number: | ||
| 16 | # RUN: echo "SECTIONS {" > %t.script | ||
| 17 | # RUN: echo ".text + { *(.text) }" >> %t.script | ||
| 18 | # RUN: echo ".keep : { *(.keep) } /*" >> %t.script | ||
| 19 | # RUN: echo "comment line 1" >> %t.script | ||
| 20 | # RUN: echo "comment line 2 */" >> %t.script | ||
| 21 | # RUN: echo ".temp : { *(.temp) } }" >> %t.script | ||
| 22 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR1 %s | ||
| 23 | # ERR1: {{.*}}.script:2: | ||
| 24 | |||
| 25 | ## Change ":" to "+" at line 3 now, check correct error line number: | ||
| 26 | # RUN: echo "SECTIONS {" > %t.script | ||
| 27 | # RUN: echo ".text : { *(.text) }" >> %t.script | ||
| 28 | # RUN: echo ".keep + { *(.keep) } /*" >> %t.script | ||
| 29 | # RUN: echo "comment line 1" >> %t.script | ||
| 30 | # RUN: echo "comment line 2 */" >> %t.script | ||
| 31 | # RUN: echo ".temp : { *(.temp) } }" >> %t.script | ||
| 32 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR2 %s | ||
| 33 | # ERR2: {{.*}}.script:3: | ||
| 34 | |||
| 35 | ## Change ":" to "+" at line 6, after multiline comment, | ||
| 36 | ## check correct error line number: | ||
| 37 | # RUN: echo "SECTIONS {" > %t.script | ||
| 38 | # RUN: echo ".text : { *(.text) }" >> %t.script | ||
| 39 | # RUN: echo ".keep : { *(.keep) } /*" >> %t.script | ||
| 40 | # RUN: echo "comment line 1" >> %t.script | ||
| 41 | # RUN: echo "comment line 2 */" >> %t.script | ||
| 42 | # RUN: echo ".temp + { *(.temp) } }" >> %t.script | ||
| 43 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR5 %s | ||
| 44 | # ERR5: {{.*}}.script:6: | ||
| 45 | |||
| 46 | ## Check that text of lines and pointer to 'bad' token are working ok. | ||
| 47 | # RUN: echo "UNKNOWN_TAG {" > %t.script | ||
| 48 | # RUN: echo ".text : { *(.text) }" >> %t.script | ||
| 49 | # RUN: echo ".keep : { *(.keep) }" >> %t.script | ||
| 50 | # RUN: echo ".temp : { *(.temp) } }" >> %t.script | ||
| 51 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ | ||
| 52 | # RUN: FileCheck -check-prefix=ERR6 -strict-whitespace %s | ||
| 53 | # ERR6: error: {{.*}}.script:1: unknown directive: UNKNOWN_TAG | ||
| 54 | # ERR6-NEXT: >>> UNKNOWN_TAG { | ||
| 55 | # ERR6-NEXT: >>> ^ | ||
| 56 | |||
| 57 | ## One more check that text of lines and pointer to 'bad' token are working ok. | ||
| 58 | # RUN: echo "SECTIONS {" > %t.script | ||
| 59 | # RUN: echo ".text : { *(.text) }" >> %t.script | ||
| 60 | # RUN: echo ".keep : { *(.keep) }" >> %t.script | ||
| 61 | # RUN: echo "boom .temp : { *(.temp) } }" >> %t.script | ||
| 62 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ | ||
| 63 | # RUN: FileCheck -check-prefix=ERR7 -strict-whitespace %s | ||
| 64 | # ERR7: error: {{.*}}.script:4: malformed number: .temp | ||
| 65 | # ERR7-NEXT: >>> boom .temp : { *(.temp) } } | ||
| 66 | # ERR7-NEXT: >>> ^ | ||
| 67 | |||
| 68 | ## Check tokenize() error | ||
| 69 | # RUN: echo "SECTIONS {}" > %t.script | ||
| 70 | # RUN: echo "\"" >> %t.script | ||
| 71 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ | ||
| 72 | # RUN: FileCheck -check-prefix=ERR8 -strict-whitespace %s | ||
| 73 | # ERR8: {{.*}}.script:2: unclosed quote | ||
| 74 | |||
| 75 | ## Check tokenize() error in included script file | ||
| 76 | # RUN: echo "SECTIONS {}" > %t.script.inc | ||
| 77 | # RUN: echo "\"" >> %t.script.inc | ||
| 78 | # RUN: echo "INCLUDE \"%t.script.inc\"" > %t.script | ||
| 79 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ | ||
| 80 | # RUN: FileCheck -check-prefix=ERR9 -strict-whitespace %s | ||
| 81 | # ERR9: {{.*}}.script.inc:2: unclosed quote | ||
| 82 | |||
| 83 | ## Check error reporting correctness for included files. | ||
| 84 | # RUN: echo "SECTIONS {" > %t.script.inc | ||
| 85 | # RUN: echo ".text : { *(.text) }" >> %t.script.inc | ||
| 86 | # RUN: echo ".keep : { *(.keep) }" >> %t.script.inc | ||
| 87 | # RUN: echo "boom .temp : { *(.temp) } }" >> %t.script.inc | ||
| 88 | # RUN: echo "INCLUDE \"%t.script.inc\"" > %t.script | ||
| 89 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ | ||
| 90 | # RUN: FileCheck -check-prefix=ERR10 -strict-whitespace %s | ||
| 91 | # ERR10: error: {{.*}}.script.inc:4: malformed number: .temp | ||
| 92 | # ERR10-NEXT: >>> boom .temp : { *(.temp) } } | ||
| 93 | # ERR10-NEXT: >>> ^ | ||
| 94 | |||
| 95 | ## Check error reporting in script with INCLUDE directive. | ||
| 96 | # RUN: echo "SECTIONS {" > %t.script.inc | ||
| 97 | # RUN: echo ".text : { *(.text) }" >> %t.script.inc | ||
| 98 | # RUN: echo ".keep : { *(.keep) }" >> %t.script.inc | ||
| 99 | # RUN: echo ".temp : { *(.temp) } }" >> %t.script.inc | ||
| 100 | # RUN: echo "/* One line before INCLUDE */" > %t.script | ||
| 101 | # RUN: echo "INCLUDE \"%t.script.inc\"" >> %t.script | ||
| 102 | # RUN: echo "/* One line ater INCLUDE */" >> %t.script | ||
| 103 | # RUN: echo "Error" >> %t.script | ||
| 104 | # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ | ||
| 105 | # RUN: FileCheck -check-prefix=ERR11 -strict-whitespace %s | ||
| 106 | # ERR11: error: {{.*}}.script:4: unexpected EOF | ||
deps/lld/test/ELF/linkerscript/discard-gnu-hash.s created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | # RUN: ld.lld --hash-style both -shared -o %t1 %t | ||
| 5 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 6 | # CHECK: .gnu.hash | ||
| 7 | # CHECK: .hash | ||
| 8 | |||
| 9 | # RUN: echo "SECTIONS { /DISCARD/ : { *(.hash) } }" > %t.script | ||
| 10 | # RUN: ld.lld --hash-style both -shared -o %t1 --script %t.script %t | ||
| 11 | # RUN: llvm-objdump -section-headers %t1 \ | ||
| 12 | # RUN: | FileCheck %s --check-prefix=HASH | ||
| 13 | # HASH-NOT: .hash | ||
| 14 | # HASH: .gnu.hash | ||
| 15 | # HASH-NOT: .hash | ||
| 16 | |||
| 17 | # RUN: echo "SECTIONS { /DISCARD/ : { *(.gnu.hash) } }" > %t.script | ||
| 18 | # RUN: ld.lld --hash-style both -shared -o %t1 --script %t.script %t | ||
| 19 | # RUN: llvm-objdump -section-headers %t1 \ | ||
| 20 | # RUN: | FileCheck %s --check-prefix=GNUHASH | ||
| 21 | # GNUHASH-NOT: .gnu.hash | ||
| 22 | # GNUHASH: .hash | ||
| 23 | # GNUHASH-NOT: .gnu.hash | ||
deps/lld/test/ELF/linkerscript/discard-interp.s deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/../Inputs/shared.s -o %t2.o | ||
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 4 | // RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; } \ | ||
| 5 | // RUN: SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } : text }" > %t.script | ||
| 6 | // RUN: ld.lld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --script %t.script --export-dynamic %t.o %t2.so -o %t | ||
| 7 | // RUN: llvm-readobj -s %t | FileCheck %s | ||
| 8 | |||
| 9 | // CHECK-NOT: Name: .interp | ||
| 10 | |||
| 11 | .global _start | ||
| 12 | _start: | ||
deps/lld/test/ELF/linkerscript/discard-interp.test created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/../Inputs/shared.s -o %t2.o | ||
| 4 | # RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | # 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 | ||
| 7 | |||
| 8 | # CHECK-NOT: Name: .interp | ||
| 9 | |||
| 10 | PHDRS { text PT_LOAD FILEHDR PHDRS; } | ||
| 11 | SECTIONS { | ||
| 12 | . = SIZEOF_HEADERS; | ||
| 13 | .text : { *(.text) } : text | ||
| 14 | } | ||
deps/lld/test/ELF/linkerscript/discard-print-gc.s+2-2| ... | @@ -15,5 +15,5 @@ | ... | @@ -15,5 +15,5 @@ |
| 15 | .section .foo,"a" | 15 | .section .foo,"a" |
| 16 | .quad 0 | 16 | .quad 0 |
| 17 | 17 | ||
| 18 | # CHECK: removing unused section from '.foo' | 18 | # CHECK: removing unused section {{.*}}:(.foo) |
| 19 | # QUIET-NOT: removing unused section from '.foo' | 19 | # QUIET-NOT: removing unused section {{.*}}:(.foo) |
deps/lld/test/ELF/linkerscript/discard-section-err.s+10| ... | @@ -22,4 +22,14 @@ | ... | @@ -22,4 +22,14 @@ |
| 22 | # RUN: FileCheck -check-prefix=DYNSTR %s | 22 | # RUN: FileCheck -check-prefix=DYNSTR %s |
| 23 | # DYNSTR: discarding .dynstr section is not allowed | 23 | # DYNSTR: discarding .dynstr section is not allowed |
| 24 | 24 | ||
| 25 | # RUN: echo "SECTIONS { /DISCARD/ : { *(.rela.plt) } }" > %t.script | ||
| 26 | # RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \ | ||
| 27 | # RUN: FileCheck -check-prefix=RELAPLT %s | ||
| 28 | # RELAPLT: discarding .rela.plt section is not allowed | ||
| 29 | |||
| 30 | # RUN: echo "SECTIONS { /DISCARD/ : { *(.rela.dyn) } }" > %t.script | ||
| 31 | # RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \ | ||
| 32 | # RUN: FileCheck -check-prefix=RELADYN %s | ||
| 33 | # RELADYN: discarding .rela.dyn section is not allowed | ||
| 34 | |||
| 25 | .comm foo,4,4 | 35 | .comm foo,4,4 |
deps/lld/test/ELF/linkerscript/dot-is-not-abs.s+1-3| ... | @@ -1,9 +1,7 @@ | ... | @@ -1,9 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | ||
| 4 | # RUN: echo "SECTIONS { .text : { *(.text) } \ | 4 | # RUN: echo "SECTIONS { .text : { *(.text) } foo = .; .bar : { *(.bar) } }" > %t1.script |
| 5 | # RUN: foo = .; \ | ||
| 6 | # RUN: .bar : { *(.bar) } }" > %t1.script | ||
| 7 | # RUN: ld.lld -o %t1 --script %t1.script %t.o -shared | 5 | # RUN: ld.lld -o %t1 --script %t1.script %t.o -shared |
| 8 | # RUN: llvm-readobj -t -s -section-data %t1 | FileCheck %s | 6 | # RUN: llvm-readobj -t -s -section-data %t1 | FileCheck %s |
| 9 | 7 |
deps/lld/test/ELF/linkerscript/double-bss.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: echo "SECTIONS { . = SIZEOF_HEADERS; " > %t.script | ||
| 4 | # RUN: echo ".text : { *(.text*) }" >> %t.script | ||
| 5 | # RUN: echo ".bss1 : { *(.bss) }" >> %t.script | ||
| 6 | # RUN: echo ".bss2 : { *(COMMON) }" >> %t.script | ||
| 7 | # RUN: echo "}" >> %t.script | ||
| 8 | |||
| 9 | # RUN: ld.lld -o %t1 --script %t.script %t | ||
| 10 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 11 | # CHECK: .bss1 00000004 0000000000000122 BSS | ||
| 12 | # CHECK-NEXT: .bss2 00000080 0000000000000128 BSS | ||
| 13 | |||
| 14 | .globl _start | ||
| 15 | _start: | ||
| 16 | jmp _start | ||
| 17 | |||
| 18 | .bss | ||
| 19 | .zero 4 | ||
| 20 | |||
| 21 | .comm q,128,8 | ||
deps/lld/test/ELF/linkerscript/double-bss.test created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.short 0; .bss; .zero 4; .comm q,128,8' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t | ||
| 4 | # RUN: ld.lld -o %t1 --script %s %t | ||
| 5 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 6 | # CHECK: .bss1 00000004 0000000000000122 BSS | ||
| 7 | # CHECK-NEXT: .bss2 00000080 0000000000000128 BSS | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | . = SIZEOF_HEADERS; | ||
| 11 | .text : { *(.text*) } | ||
| 12 | .bss1 : { *(.bss) } | ||
| 13 | .bss2 : { *(COMMON) } | ||
| 14 | } | ||
deps/lld/test/ELF/linkerscript/edata-etext.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: echo "SECTIONS { }" > %t.script | 3 | # RUN: echo "SECTIONS { }" > %t.script |
| 4 | # RUN: not ld.lld %t.o -script %t.script -o %t 2>&1 | FileCheck %s | 4 | # RUN: not ld.lld %t.o -script %t.script -o /dev/null 2>&1 | FileCheck %s |
| 5 | # CHECK: error: undefined symbol: _edata | 5 | # CHECK: error: undefined symbol: _edata |
| 6 | # CHECK: >>> referenced by {{.*}}:(.text+0x0) | 6 | # CHECK: >>> referenced by {{.*}}:(.text+0x0) |
| 7 | # CHECK: error: undefined symbol: _etext | 7 | # CHECK: error: undefined symbol: _etext |
deps/lld/test/ELF/linkerscript/eh-frame-emit-relocs.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo "SECTIONS { .foo : { *(.eh_frame) } }" > %t.script | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 4 | # RUN: ld.lld --emit-relocs %t.o -T %t.script -o %t | ||
| 5 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK-NOT: eh_frame | ||
| 8 | # CHECK: .rela.foo | ||
| 9 | # CHECK-NOT: eh_frame | ||
| 10 | |||
| 11 | .text | ||
| 12 | .cfi_startproc | ||
| 13 | .cfi_endproc | ||
deps/lld/test/ELF/linkerscript/eh-frame-hdr.s+2-5| ... | @@ -1,13 +1,10 @@ | ... | @@ -1,13 +1,10 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | # RUN: echo "SECTIONS { \ | 3 | # RUN: echo "SECTIONS { .eh_frame_hdr : {} .eh_frame : {} }" > %t.script |
| 4 | # RUN: .eh_frame_hdr : {} \ | ||
| 5 | # RUN: .eh_frame : {} \ | ||
| 6 | # RUN: }" > %t.script | ||
| 7 | # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t | 4 | # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t |
| 8 | # RUN: llvm-objdump -s -section=".eh_frame_hdr" %t1 | FileCheck %s | 5 | # RUN: llvm-objdump -s -section=".eh_frame_hdr" %t1 | FileCheck %s |
| 9 | 6 | ||
| 10 | # CHECK: 011b033b 14000000 01000000 49000000 | 7 | # CHECK: 011b033b 14000000 01000000 4d000000 |
| 11 | # CHECK-NEXT: 30000000 | 8 | # CHECK-NEXT: 30000000 |
| 12 | 9 | ||
| 13 | .global _start | 10 | .global _start |
deps/lld/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s deleted-27| ... | @@ -1,27 +0,0 @@ | ||
| 1 | ## Check that error is correctly reported when .eh_frame reloc | ||
| 2 | ## is out of range | ||
| 3 | |||
| 4 | # REQUIRES: x86 | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 6 | # RUN: echo "PHDRS { eh PT_LOAD; text PT_LOAD; } \ | ||
| 7 | # RUN: SECTIONS { . = 0x10000; \ | ||
| 8 | # RUN: .eh_frame_hdr : { *(.eh_frame_hdr*) } : eh \ | ||
| 9 | # RUN: .eh_frame : { *(.eh_frame) } : eh \ | ||
| 10 | # RUN: . = 0xF00000000; \ | ||
| 11 | # RUN: .text : { *(.text*) } : text \ | ||
| 12 | # RUN: }" > %t.script | ||
| 13 | # RUN: not ld.lld %t.o -T %t.script -o %t 2>&1 | FileCheck %s | ||
| 14 | |||
| 15 | # CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range: 64424443872 is not in [-2147483648, 2147483647] | ||
| 16 | |||
| 17 | 	.text | ||
| 18 | .globl _start | ||
| 19 | _start: | ||
| 20 | 	.cfi_startproc | ||
| 21 | .cfi_lsda 0, _ex | ||
| 22 | nop | ||
| 23 | 	.cfi_endproc | ||
| 24 | |||
| 25 | .data | ||
| 26 | _ex: | ||
| 27 | .word 0 | ||
deps/lld/test/ELF/linkerscript/eh-frame-reloc-out-of-range.test created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/eh-frame-reloc-out-of-range.s -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o -T %s -o %t 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | PHDRS { eh PT_LOAD; text PT_LOAD; } | ||
| 6 | SECTIONS { . = 0x10000; | ||
| 7 | .eh_frame_hdr : { *(.eh_frame_hdr*) } : eh | ||
| 8 | .eh_frame : { *(.eh_frame) } : eh | ||
| 9 | . = 0xF00000000; | ||
| 10 | .text : { *(.text*) } : text | ||
| 11 | } | ||
| 12 | |||
| 13 | # CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range: 64424443872 is not in [-2147483648, 2147483647] | ||
deps/lld/test/ELF/linkerscript/eh-frame.s+1-3| ... | @@ -1,8 +1,6 @@ | ... | @@ -1,8 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | # RUN: echo "SECTIONS { \ | 3 | # RUN: echo "SECTIONS { .eh_frame : { *(.eh_frame) } }" > %t.script |
| 4 | # RUN: .eh_frame : { *(.eh_frame) } \ | ||
| 5 | # RUN: }" > %t.script | ||
| 6 | # RUN: ld.lld -o %t1 --script %t.script %t | 4 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 7 | # RUN: llvm-objdump -s -section=".eh_frame" %t1 | FileCheck %s | 5 | # RUN: llvm-objdump -s -section=".eh_frame" %t1 | FileCheck %s |
| 8 | 6 |
deps/lld/test/ELF/linkerscript/emit-reloc-section-names.s+1-2| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: echo "SECTIONS { .text.zed : { *(.text.foo) } \ | 3 | # RUN: echo "SECTIONS { .text.zed : { *(.text.foo) } .text.qux : { *(.text.bar) } }" > %t.script |
| 4 | # RUN: .text.qux : { *(.text.bar) } }" > %t.script | ||
| 5 | # RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t | 4 | # RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t |
| 6 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | 5 | # RUN: llvm-objdump -section-headers %t | FileCheck %s |
| 7 | 6 |
deps/lld/test/ELF/linkerscript/emit-reloc.s+2-2| ... | @@ -9,9 +9,9 @@ | ... | @@ -9,9 +9,9 @@ |
| 9 | 9 | ||
| 10 | # CHECK: Relocations [ | 10 | # CHECK: Relocations [ |
| 11 | # CHECK-NEXT: Section ({{.*}}) .rela.dyn { | 11 | # CHECK-NEXT: Section ({{.*}}) .rela.dyn { |
| 12 | # CHECK-NEXT: 0x66 R_X86_64_64 .foo 0x0 | 12 | # CHECK-NEXT: 0x68 R_X86_64_64 .foo 0x0 |
| 13 | # CHECK-NEXT: } | 13 | # CHECK-NEXT: } |
| 14 | # CHECK-NEXT: Section ({{.*}}) .rela.data { | 14 | # CHECK-NEXT: Section ({{.*}}) .rela.data { |
| 15 | # CHECK-NEXT: 0x66 R_X86_64_64 .foo 0x0 | 15 | # CHECK-NEXT: 0x68 R_X86_64_64 .foo 0x0 |
| 16 | # CHECK-NEXT: } | 16 | # CHECK-NEXT: } |
| 17 | # CHECK-NEXT: ] | 17 | # CHECK-NEXT: ] |
deps/lld/test/ELF/linkerscript/empty-link-order.test created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: arm | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=arm-arm-none-eabi -o %t.o < /dev/null | ||
| 3 | |||
| 4 | SECTIONS { | ||
| 5 | .foo : { | ||
| 6 | bar = .; | ||
| 7 | *(.ARM.exidx*) | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | # RUN: ld.lld %t.o -o %t --script %s | ||
| 12 | |||
| 13 | ## Check we do not crash and do not set SHF_LINK_ORDER flag for .foo | ||
| 14 | # RUN: llvm-readobj -s %t | FileCheck %s | ||
| 15 | # CHECK: Section { | ||
| 16 | # CHECK: Index: | ||
| 17 | # CHECK: Name: .foo | ||
| 18 | # CHECK-NEXT: Type: SHT_ARM_EXIDX | ||
| 19 | # CHECK-NEXT: Flags [ | ||
| 20 | # CHECK-NEXT: SHF_ALLOC | ||
| 21 | # CHECK-NEXT: ] | ||
deps/lld/test/ELF/linkerscript/empty-load.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | # RUN: echo "SECTIONS { .rw : { *(.rw) } .text : { *(.text) } }" > %t.script | 3 | # RUN: echo "SECTIONS { .rw : { *(.rw) } .text : { *(.text) } }" > %t.script |
| 4 | # RUN: ld.lld -o %t1 --script %t.script %t | 4 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 5 | # RUN: llvm-objdump -private-headers %t1 | FileCheck %s | 5 | # RUN: llvm-objdump -private-headers %t1 | FileCheck %s |
| 6 | 6 |
deps/lld/test/ELF/linkerscript/empty-section-size.test created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld %t.o --script %s -o %t1 | ||
| 4 | # RUN: llvm-readobj -symbols %t1 | FileCheck %s | ||
| 5 | |||
| 6 | ## We had a bug when LLD increased the size of the output section even | ||
| 7 | ## if it was empty. That happened because of empty synthetic sections included. | ||
| 8 | ## Here we check that size of empty output section is zero. | ||
| 9 | |||
| 10 | # CHECK: Name: foo | ||
| 11 | # CHECK-NEXT: Value: 0x0 | ||
| 12 | |||
| 13 | SECTIONS { | ||
| 14 | . = 0x1000; | ||
| 15 | .bss : { *(.bss*) *(COMMON) } | ||
| 16 | foo = SIZEOF(.bss); | ||
| 17 | } | ||
deps/lld/test/ELF/linkerscript/empty-sections-expressions.s created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | |||
| 4 | ## We remove empty sections that do not reference symbols in address, | ||
| 5 | ## LMA, align and subalign expressions. Here we check that. | ||
| 6 | |||
| 7 | # RUN: echo "SECTIONS { .debug_info 0 : { *(.debug_info) } }" > %t.script | ||
| 8 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 9 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | ||
| 10 | # CHECK-NOT: .debug_info | ||
| 11 | |||
| 12 | # RUN: echo "SECTIONS { .debug_info foo : { *(.debug_info) } }" > %t2.script | ||
| 13 | # RUN: ld.lld -o %t2 --script %t2.script %t.o | ||
| 14 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=SEC | ||
| 15 | # SEC: .debug_info | ||
| 16 | |||
| 17 | .globl foo | ||
| 18 | foo: | ||
deps/lld/test/ELF/linkerscript/empty-synthetic-removed-flags.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 "SECTIONS { .foo : { *(.foo) } .bar : { *(.got.plt) BYTE(0x11) }}" > %t.script | ||
| 4 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 5 | # RUN: llvm-readobj -s %t | FileCheck %s | ||
| 6 | |||
| 7 | ## We have ".got.plt" synthetic section with SHF_ALLOC|SHF_WRITE flags. | ||
| 8 | ## It is empty, so linker removes it, but it has to keep ".got.plt" output | ||
| 9 | ## section because of the BYTE command. Here we check that the output section | ||
| 10 | ## still remembers what the flags of .got.plt are. | ||
| 11 | |||
| 12 | # CHECK: Section { | ||
| 13 | # CHECK: Index: 2 | ||
| 14 | # CHECK: Name: .bar | ||
| 15 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 16 | # CHECK-NEXT: Flags [ | ||
| 17 | # CHECK-NEXT: SHF_ALLOC | ||
| 18 | # CHECK-NEXT: SHF_WRITE | ||
| 19 | # CHECK-NEXT: ] | ||
| 20 | |||
| 21 | ## Check flags are not the same if we omit empty synthetic section in script. | ||
| 22 | # RUN: echo "SECTIONS { .foo : { *(.foo) } .bar : { BYTE(0x11) }}" > %t.script | ||
| 23 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 24 | # RUN: llvm-readobj -s %t | FileCheck --check-prefix=EMPTY %s | ||
| 25 | |||
| 26 | # EMPTY: Section { | ||
| 27 | # EMPTY: Index: 2 | ||
| 28 | # EMPTY: Name: .bar | ||
| 29 | # EMPTY-NEXT: Type: SHT_PROGBITS | ||
| 30 | # EMPTY-NEXT: Flags [ | ||
| 31 | # EMPTY-NEXT: SHF_ALLOC | ||
| 32 | # EMPTY-NEXT: SHF_EXECINSTR | ||
| 33 | # EMPTY-NEXT: ] | ||
| 34 | |||
| 35 | .section .foo,"ax" | ||
| 36 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/empty-tls.s deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | // RUN: echo "PHDRS { ph_tls PT_TLS; }" > %t.script | ||
| 4 | // RUN: ld.lld -o %t.so -T %t.script %t.o -shared | ||
| 5 | // RUN: llvm-readobj -l %t.so | FileCheck %s | ||
| 6 | |||
| 7 | // test that we don't crash with an empty PT_TLS | ||
| 8 | |||
| 9 | // CHECK: Type: PT_TLS | ||
| 10 | // CHECK-NEXT: Offset: 0x0 | ||
| 11 | // CHECK-NEXT: VirtualAddress: 0x0 | ||
| 12 | // CHECK-NEXT: PhysicalAddress: 0x0 | ||
| 13 | // CHECK-NEXT: FileSize: 0 | ||
| 14 | // CHECK-NEXT: MemSize: 0 | ||
deps/lld/test/ELF/linkerscript/empty-tls.test created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld -o %t.so -T %s %t.o -shared | ||
| 4 | # RUN: llvm-readobj -l %t.so | FileCheck %s | ||
| 5 | |||
| 6 | PHDRS { | ||
| 7 | ph_tls PT_TLS; | ||
| 8 | } | ||
| 9 | |||
| 10 | # Test that we don't crash with an empty PT_TLS | ||
| 11 | |||
| 12 | # CHECK: Type: PT_TLS | ||
| 13 | # CHECK-NEXT: Offset: 0x0 | ||
| 14 | # CHECK-NEXT: VirtualAddress: 0x0 | ||
| 15 | # CHECK-NEXT: PhysicalAddress: 0x0 | ||
| 16 | # CHECK-NEXT: FileSize: 0 | ||
| 17 | # CHECK-NEXT: MemSize: 0 | ||
deps/lld/test/ELF/linkerscript/exidx-crash.s deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | # REQUIRES: aarch64 | ||
| 2 | |||
| 3 | # We used to crash on this. | ||
| 4 | |||
| 5 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux | ||
| 6 | # RUN: echo "SECTIONS { .ARM.exidx : { *(.foo) } }" > %t.script | ||
| 7 | # RUN: ld.lld -T %t.script %t.o -o %t | ||
deps/lld/test/ELF/linkerscript/exidx-crash.test created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | # REQUIRES: aarch64 | ||
| 2 | |||
| 3 | # We used to crash on this. | ||
| 4 | |||
| 5 | # RUN: llvm-mc /dev/null -o %t.o -filetype=obj -triple=aarch64-pc-linux | ||
| 6 | # RUN: ld.lld -T %s %t.o -o %t | ||
| 7 | |||
| 8 | SECTIONS { | ||
| 9 | .ARM.exidx : { *(.foo) } | ||
| 10 | } | ||
deps/lld/test/ELF/linkerscript/expr-invalid-sec.s deleted-6| ... | @@ -1,6 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { foo = ADDR(.text) + ADDR(.text); };" > %t.script | ||
| 4 | # RUN: not ld.lld -o %t.so --script %t.script %t.o -shared 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: {{.*}}.script:1: at least one side of the expression must be absolute | ||
deps/lld/test/ELF/linkerscript/expr-invalid-sec.test created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: not ld.lld -o %t.so --script %s %t.o -shared 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: error: {{.*}}.test:8: at least one side of the expression must be absolute | ||
| 6 | |||
| 7 | SECTIONS { | ||
| 8 | foo = ADDR(.text) + ADDR(.text); | ||
| 9 | }; | ||
deps/lld/test/ELF/linkerscript/expr-sections.s deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: . = . + 4; \ | ||
| 5 | # RUN: .text : { \ | ||
| 6 | # RUN: *(.text) \ | ||
| 7 | # RUN: foo1 = ADDR(.text) + 1; bar1 = 1 + ADDR(.text); \ | ||
| 8 | # RUN: foo2 = ADDR(.text) & 1; bar2 = 1 & ADDR(.text); \ | ||
| 9 | # RUN: foo3 = ADDR(.text) | 1; bar3 = 1 | ADDR(.text); \ | ||
| 10 | # RUN: } \ | ||
| 11 | # RUN: };" > %t.script | ||
| 12 | # RUN: ld.lld -o %t.so --script %t.script %t.o -shared | ||
| 13 | # RUN: llvm-objdump -t -h %t.so | FileCheck %s | ||
| 14 | |||
| 15 | # CHECK: 1 .text 00000000 0000000000000004 TEXT DATA | ||
| 16 | |||
| 17 | # CHECK: 0000000000000005 .text		 00000000 foo1 | ||
| 18 | # CHECK: 0000000000000005 .text		 00000000 bar1 | ||
| 19 | # CHECK: 0000000000000000 .text		 00000000 foo2 | ||
| 20 | # CHECK: 0000000000000000 .text		 00000000 bar2 | ||
| 21 | # CHECK: 0000000000000005 .text		 00000000 foo3 | ||
| 22 | # CHECK: 0000000000000005 .text		 00000000 bar3 | ||
deps/lld/test/ELF/linkerscript/expr-sections.test created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld -o %t.so --script %s %t.o -shared | ||
| 4 | # RUN: llvm-objdump -t -h %t.so | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = . + 4; | ||
| 8 | .text : { | ||
| 9 | *(.text) | ||
| 10 | foo1 = ADDR(.text) + 1; bar1 = 1 + ADDR(.text); | ||
| 11 | foo2 = ADDR(.text) & 1; bar2 = 1 & ADDR(.text); | ||
| 12 | foo3 = ADDR(.text) | 1; bar3 = 1 | ADDR(.text); | ||
| 13 | } | ||
| 14 | }; | ||
| 15 | |||
| 16 | # CHECK: 5 .text 00000000 000000000000014c | ||
| 17 | |||
| 18 | # CHECK: 000000000000014d .text		 00000000 foo1 | ||
| 19 | # CHECK: 000000000000014d .text		 00000000 bar1 | ||
| 20 | # CHECK: 0000000000000000 .text		 00000000 foo2 | ||
| 21 | # CHECK: 0000000000000000 .text		 00000000 bar2 | ||
| 22 | # CHECK: 000000000000014d .text		 00000000 foo3 | ||
| 23 | # CHECK: 000000000000014d .text		 00000000 bar3 | ||
deps/lld/test/ELF/linkerscript/extend-pt-load.s deleted-68| ... | @@ -1,68 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | |||
| 4 | # This test demonstrates an odd consequence of the way we handle sections with just symbol | ||
| 5 | # assignments. | ||
| 6 | |||
| 7 | # First, run a test with no such section. | ||
| 8 | |||
| 9 | # RUN: echo "SECTIONS { \ | ||
| 10 | # RUN: . = SIZEOF_HEADERS; \ | ||
| 11 | # RUN:	.dynsym : { } \ | ||
| 12 | # RUN:	.hash : { } \ | ||
| 13 | # RUN:	.dynstr : { } \ | ||
| 14 | # RUN: .text : { *(.text) } \ | ||
| 15 | # RUN: . = ALIGN(0x1000); \ | ||
| 16 | # RUN: .data.rel.ro : { *(.data.rel.ro) } \ | ||
| 17 | # RUN: }" > %t.script | ||
| 18 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t.o -shared | ||
| 19 | # RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck --check-prefix=CHECK1 %s | ||
| 20 | |||
| 21 | # CHECK1: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX | ||
| 22 | # CHECK1-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA | ||
| 23 | |||
| 24 | # CHECK1: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x0001bd R E | ||
| 25 | # CHECK1-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW | ||
| 26 | |||
| 27 | # Then add the section bar. Note how bar is given AX flags, which causes the PT_LOAD to now | ||
| 28 | # cover the padding bits created by ALIGN. | ||
| 29 | |||
| 30 | # RUN: echo "SECTIONS { \ | ||
| 31 | # RUN: . = SIZEOF_HEADERS; \ | ||
| 32 | # RUN:	.dynsym : { } \ | ||
| 33 | # RUN:	.hash : { } \ | ||
| 34 | # RUN:	.dynstr : { } \ | ||
| 35 | # RUN: .text : { *(.text) } \ | ||
| 36 | # RUN: bar : { . = ALIGN(0x1000); } \ | ||
| 37 | # RUN: .data.rel.ro : { *(.data.rel.ro) } \ | ||
| 38 | # RUN: }" > %t.script | ||
| 39 | # RUN: ld.lld --hash-style=sysv -o %t2 --script %t.script %t.o -shared | ||
| 40 | # RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck --check-prefix=CHECK2 %s | ||
| 41 | |||
| 42 | # CHECK2: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX | ||
| 43 | # CHECK2-NEXT: bar NOBITS 00000000000001bd 0001bd 000e43 00 AX | ||
| 44 | # CHECK2-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA | ||
| 45 | |||
| 46 | # CHECK2: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x001000 R E | ||
| 47 | # CHECK2-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW | ||
| 48 | |||
| 49 | # If the current behavior becomes a problem we should consider just moving the commands out | ||
| 50 | # of the section. That is, handle the above like the following test. | ||
| 51 | |||
| 52 | # RUN: echo "SECTIONS { \ | ||
| 53 | # RUN: . = SIZEOF_HEADERS; \ | ||
| 54 | # RUN:	.dynsym : { } \ | ||
| 55 | # RUN:	.hash : { } \ | ||
| 56 | # RUN:	.dynstr : { } \ | ||
| 57 | # RUN: .text : { *(.text) } \ | ||
| 58 | # RUN: . = ALIGN(0x1000); \ | ||
| 59 | # RUN: HIDDEN(bar_sym = .); \ | ||
| 60 | # RUN: .data.rel.ro : { *(.data.rel.ro) } \ | ||
| 61 | # RUN: }" > %t.script | ||
| 62 | # RUN: ld.lld --hash-style=sysv -o %t3 --script %t.script %t.o -shared | ||
| 63 | # RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck --check-prefix=CHECK1 %s | ||
| 64 | |||
| 65 | nop | ||
| 66 | |||
| 67 | .section .data.rel.ro, "aw" | ||
| 68 | .byte 0 | ||
deps/lld/test/ELF/linkerscript/extend-pt-load1.test created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o | ||
| 3 | # 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 | ||
| 5 | |||
| 6 | # This test demonstrates an odd consequence of the way we handle sections with just symbol | ||
| 7 | # assignments. | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | . = SIZEOF_HEADERS; | ||
| 11 | .dynsym : {} | ||
| 12 | .hash : {} | ||
| 13 | .dynstr : {} | ||
| 14 | .text : { *(.text) } | ||
| 15 | . = ALIGN(0x1000); | ||
| 16 | .data.rel.ro : { *(.data.rel.ro) } | ||
| 17 | } | ||
| 18 | |||
| 19 | # CHECK: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX | ||
| 20 | # CHECK-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA | ||
| 21 | |||
| 22 | # CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x0001bd R E | ||
| 23 | # CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW | ||
deps/lld/test/ELF/linkerscript/extend-pt-load2.test created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o | ||
| 3 | # 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 | ||
| 5 | |||
| 6 | # Then add the section bar. Note how bar is given AX flags, which causes the PT_LOAD to now | ||
| 7 | # cover the padding bits created by ALIGN. | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | . = SIZEOF_HEADERS; | ||
| 11 | .dynsym : {} | ||
| 12 | .hash : {} | ||
| 13 | .dynstr : {} | ||
| 14 | .text : { *(.text) } | ||
| 15 | bar : { . = ALIGN(0x1000); } | ||
| 16 | .data.rel.ro : { *(.data.rel.ro) } | ||
| 17 | } | ||
| 18 | |||
| 19 | # CHECK: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX | ||
| 20 | # CHECK-NEXT: bar NOBITS 00000000000001bd 0001bd 000e43 00 AX | ||
| 21 | # CHECK-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA | ||
| 22 | |||
| 23 | # CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x001000 R E | ||
| 24 | # CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW | ||
deps/lld/test/ELF/linkerscript/extend-pt-load3.test created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/extend-pt-load.s -o %t.o | ||
| 3 | # 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 | ||
| 5 | |||
| 6 | # If the current behavior becomes a problem we should consider just moving the commands out | ||
| 7 | # of the section. That is, handle the above like the following test. | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | . = SIZEOF_HEADERS; | ||
| 11 | .dynsym : {} | ||
| 12 | .hash : {} | ||
| 13 | .dynstr : {} | ||
| 14 | .text : { *(.text) } | ||
| 15 | . = ALIGN(0x1000); | ||
| 16 | HIDDEN(bar_sym = .); | ||
| 17 | .data.rel.ro : { *(.data.rel.ro) } | ||
| 18 | } | ||
| 19 | |||
| 20 | # CHECK: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX | ||
| 21 | # CHECK-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA | ||
| 22 | |||
| 23 | # CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x0001bd R E | ||
| 24 | # CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW | ||
| \ No newline at end of file | |||
deps/lld/test/ELF/linkerscript/filename-spec.s+25-45| ... | @@ -1,55 +1,43 @@ | ... | @@ -1,55 +1,43 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfirst.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tx.o |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 4 | # RUN: %p/Inputs/filename-spec.s -o %tsecond.o | 4 | # RUN: %p/Inputs/filename-spec.s -o %ty.o |
| 5 | 5 | ||
| 6 | # RUN: echo "SECTIONS { .foo : { \ | 6 | # RUN: echo "SECTIONS{.foo :{ KEEP(*x.o(.foo)) KEEP(*y.o(.foo)) }}" > %t1.script |
| 7 | # RUN: KEEP(*first.o(.foo)) \ | 7 | # RUN: ld.lld -o %t1 --script %t1.script %tx.o %ty.o |
| 8 | # RUN: KEEP(*second.o(.foo)) } }" > %t1.script | 8 | # RUN: llvm-objdump -s %t1 | FileCheck --check-prefix=FIRSTY %s |
| 9 | # RUN: ld.lld -o %t1 --script %t1.script %tfirst.o %tsecond.o | 9 | # FIRSTY: Contents of section .foo: |
| 10 | # RUN: llvm-objdump -s %t1 | FileCheck --check-prefix=FIRSTSECOND %s | 10 | # FIRSTY-NEXT: 01000000 00000000 11000000 00000000 |
| 11 | # FIRSTSECOND: Contents of section .foo: | ||
| 12 | # FIRSTSECOND-NEXT: 01000000 00000000 11000000 00000000 | ||
| 13 | 11 | ||
| 14 | # RUN: echo "SECTIONS { .foo : { \ | 12 | # RUN: echo "SECTIONS{.foo :{ KEEP(*y.o(.foo)) KEEP(*x.o(.foo)) }}" > %t2.script |
| 15 | # RUN: KEEP(*second.o(.foo)) \ | 13 | # RUN: ld.lld -o %t2 --script %t2.script %tx.o %ty.o |
| 16 | # RUN: KEEP(*first.o(.foo)) } }" > %t2.script | ||
| 17 | # RUN: ld.lld -o %t2 --script %t2.script %tfirst.o %tsecond.o | ||
| 18 | # RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=SECONDFIRST %s | 14 | # RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=SECONDFIRST %s |
| 19 | # SECONDFIRST: Contents of section .foo: | 15 | # SECONDFIRST: Contents of section .foo: |
| 20 | # SECONDFIRST-NEXT: 11000000 00000000 01000000 00000000 | 16 | # SECONDFIRST-NEXT: 11000000 00000000 01000000 00000000 |
| 21 | 17 | ||
| 22 | ## Now the same tests but without KEEP. Checking that file name inside | 18 | ## Now the same tests but without KEEP. Checking that file name inside |
| 23 | ## KEEP is parsed fine. | 19 | ## KEEP is parsed fine. |
| 24 | # RUN: echo "SECTIONS { .foo : { \ | 20 | # RUN: echo "SECTIONS{.foo :{ *x.o(.foo) *y.o(.foo) }}" > %t3.script |
| 25 | # RUN: *first.o(.foo) \ | 21 | # RUN: ld.lld -o %t3 --script %t3.script %tx.o %ty.o |
| 26 | # RUN: *second.o(.foo) } }" > %t3.script | 22 | # RUN: llvm-objdump -s %t3 | FileCheck --check-prefix=FIRSTY %s |
| 27 | # RUN: ld.lld -o %t3 --script %t3.script %tfirst.o %tsecond.o | ||
| 28 | # RUN: llvm-objdump -s %t3 | FileCheck --check-prefix=FIRSTSECOND %s | ||
| 29 | 23 | ||
| 30 | # RUN: echo "SECTIONS { .foo : { \ | 24 | # RUN: echo "SECTIONS{.foo :{ *y.o(.foo) *x.o(.foo) }}" > %t4.script |
| 31 | # RUN: *second.o(.foo) \ | 25 | # RUN: ld.lld -o %t4 --script %t4.script %tx.o %ty.o |
| 32 | # RUN: *first.o(.foo) } }" > %t4.script | ||
| 33 | # RUN: ld.lld -o %t4 --script %t4.script %tfirst.o %tsecond.o | ||
| 34 | # RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=SECONDFIRST %s | 26 | # RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=SECONDFIRST %s |
| 35 | 27 | ||
| 36 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o filename-spec1.o | 28 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %T/filename-spec1.o |
| 37 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | 29 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 38 | # RUN: %p/Inputs/filename-spec.s -o filename-spec2.o | 30 | # RUN: %p/Inputs/filename-spec.s -o %T/filename-spec2.o |
| 39 | 31 | ||
| 40 | # RUN: echo "SECTIONS { .foo : { \ | 32 | # RUN: echo "SECTIONS{.foo :{ %T/filename-spec2.o(.foo) %T/filename-spec1.o(.foo) }}" > %t5.script |
| 41 | # RUN: filename-spec2.o(.foo) \ | ||
| 42 | # RUN: filename-spec1.o(.foo) } }" > %t5.script | ||
| 43 | # RUN: ld.lld -o %t5 --script %t5.script \ | 33 | # RUN: ld.lld -o %t5 --script %t5.script \ |
| 44 | # RUN: filename-spec1.o filename-spec2.o | 34 | # RUN: %T/filename-spec1.o %T/filename-spec2.o |
| 45 | # RUN: llvm-objdump -s %t5 | FileCheck --check-prefix=SECONDFIRST %s | 35 | # RUN: llvm-objdump -s %t5 | FileCheck --check-prefix=SECONDFIRST %s |
| 46 | 36 | ||
| 47 | # RUN: echo "SECTIONS { .foo : { \ | 37 | # RUN: echo "SECTIONS{.foo :{ %T/filename-spec1.o(.foo) %T/filename-spec2.o(.foo) }}" > %t6.script |
| 48 | # RUN: filename-spec1.o(.foo) \ | ||
| 49 | # RUN: filename-spec2.o(.foo) } }" > %t6.script | ||
| 50 | # RUN: ld.lld -o %t6 --script %t6.script \ | 38 | # RUN: ld.lld -o %t6 --script %t6.script \ |
| 51 | # RUN: filename-spec1.o filename-spec2.o | 39 | # RUN: %T/filename-spec1.o %T/filename-spec2.o |
| 52 | # RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTSECOND %s | 40 | # RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTY %s |
| 53 | 41 | ||
| 54 | # RUN: mkdir -p %t.testdir1 %t.testdir2 | 42 | # RUN: mkdir -p %t.testdir1 %t.testdir2 |
| 55 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.testdir1/filename-spec1.o | 43 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.testdir1/filename-spec1.o |
| ... | @@ -59,33 +47,25 @@ | ... | @@ -59,33 +47,25 @@ |
| 59 | # RUN: llvm-ar rsc %t.testdir2/lib2.a %t.testdir2/filename-spec2.o | 47 | # RUN: llvm-ar rsc %t.testdir2/lib2.a %t.testdir2/filename-spec2.o |
| 60 | 48 | ||
| 61 | # Verify matching of archive library names. | 49 | # Verify matching of archive library names. |
| 62 | # RUN: echo "SECTIONS { .foo : { \ | 50 | # RUN: echo "SECTIONS{.foo :{ *lib2*(.foo) *lib1*(.foo) }}" > %t7.script |
| 63 | # RUN: *lib2*(.foo) \ | ||
| 64 | # RUN: *lib1*(.foo) } }" > %t7.script | ||
| 65 | # RUN: ld.lld -o %t7 --script %t7.script --whole-archive \ | 51 | # RUN: ld.lld -o %t7 --script %t7.script --whole-archive \ |
| 66 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a | 52 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a |
| 67 | # RUN: llvm-objdump -s %t7 | FileCheck --check-prefix=SECONDFIRST %s | 53 | # RUN: llvm-objdump -s %t7 | FileCheck --check-prefix=SECONDFIRST %s |
| 68 | 54 | ||
| 69 | # Verify matching directories. | 55 | # Verify matching directories. |
| 70 | # RUN: echo "SECTIONS { .foo : { \ | 56 | # RUN: echo "SECTIONS{.foo :{ *testdir2*(.foo) *testdir1*(.foo) }}" > %t8.script |
| 71 | # RUN: *testdir2*(.foo) \ | ||
| 72 | # RUN: *testdir1*(.foo) } }" > %t8.script | ||
| 73 | # RUN: ld.lld -o %t8 --script %t8.script --whole-archive \ | 57 | # RUN: ld.lld -o %t8 --script %t8.script --whole-archive \ |
| 74 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a | 58 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a |
| 75 | # RUN: llvm-objdump -s %t8 | FileCheck --check-prefix=SECONDFIRST %s | 59 | # RUN: llvm-objdump -s %t8 | FileCheck --check-prefix=SECONDFIRST %s |
| 76 | 60 | ||
| 77 | # Verify matching of archive library names in KEEP. | 61 | # Verify matching of archive library names in KEEP. |
| 78 | # RUN: echo "SECTIONS { .foo : { \ | 62 | # RUN: echo "SECTIONS{.foo :{ KEEP(*lib2*(.foo)) KEEP(*lib1*(.foo)) }}" > %t9.script |
| 79 | # RUN: KEEP(*lib2*(.foo)) \ | ||
| 80 | # RUN: KEEP(*lib1*(.foo)) } }" > %t9.script | ||
| 81 | # RUN: ld.lld -o %t9 --script %t9.script --whole-archive \ | 63 | # RUN: ld.lld -o %t9 --script %t9.script --whole-archive \ |
| 82 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a | 64 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a |
| 83 | # RUN: llvm-objdump -s %t9 | FileCheck --check-prefix=SECONDFIRST %s | 65 | # RUN: llvm-objdump -s %t9 | FileCheck --check-prefix=SECONDFIRST %s |
| 84 | 66 | ||
| 85 | # Verify matching directories in KEEP. | 67 | # Verify matching directories in KEEP. |
| 86 | # RUN: echo "SECTIONS { .foo : { \ | 68 | # RUN: echo "SECTIONS{.foo :{ KEEP(*testdir2*(.foo)) KEEP(*testdir1*(.foo)) }}" > %t10.script |
| 87 | # RUN: KEEP(*testdir2*(.foo)) \ | ||
| 88 | # RUN: KEEP(*testdir1*(.foo)) } }" > %t10.script | ||
| 89 | # RUN: ld.lld -o %t10 --script %t10.script --whole-archive \ | 69 | # RUN: ld.lld -o %t10 --script %t10.script --whole-archive \ |
| 90 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a | 70 | # RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a |
| 91 | # RUN: llvm-objdump -s %t10 | FileCheck --check-prefix=SECONDFIRST %s | 71 | # RUN: llvm-objdump -s %t10 | FileCheck --check-prefix=SECONDFIRST %s |
deps/lld/test/ELF/linkerscript/fill.s deleted-31| ... | @@ -1,31 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: .out : { \ | ||
| 5 | # RUN: FILL(0x11111111) \ | ||
| 6 | # RUN: . += 2; \ | ||
| 7 | # RUN: *(.aaa) \ | ||
| 8 | # RUN: . += 4; \ | ||
| 9 | # RUN: *(.bbb) \ | ||
| 10 | # RUN: . += 4; \ | ||
| 11 | # RUN: FILL(0x22222222); \ | ||
| 12 | # RUN: . += 4; \ | ||
| 13 | # RUN: } \ | ||
| 14 | # RUN: }; " > %t.script | ||
| 15 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 16 | # RUN: llvm-objdump -s %t | FileCheck %s | ||
| 17 | |||
| 18 | # CHECK: Contents of section .out: | ||
| 19 | # CHECK-NEXT: 2222aa22 222222bb 22222222 22222222 | ||
| 20 | |||
| 21 | .text | ||
| 22 | .globl _start | ||
| 23 | _start: | ||
| 24 | |||
| 25 | .section .aaa, "a" | ||
| 26 | .align 1 | ||
| 27 | .byte 0xAA | ||
| 28 | |||
| 29 | .section .bbb, "a" | ||
| 30 | .align 1 | ||
| 31 | .byte 0xBB | ||
deps/lld/test/ELF/linkerscript/fill.test created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/fill.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 4 | # RUN: llvm-objdump -s %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .out : { | ||
| 8 | FILL(0x11111111) | ||
| 9 | . += 2; | ||
| 10 | *(.aaa) | ||
| 11 | . += 4; | ||
| 12 | *(.bbb) | ||
| 13 | . += 4; | ||
| 14 | FILL(0x22222222); | ||
| 15 | . += 4; | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | # CHECK: Contents of section .out: | ||
| 20 | # CHECK-NEXT: 2222aa22 222222bb 22222222 22222222 | ||
deps/lld/test/ELF/linkerscript/header-addr.s deleted-47| ... | @@ -1,47 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "PHDRS {all PT_LOAD PHDRS;} \ | ||
| 4 | # RUN: SECTIONS { \ | ||
| 5 | # RUN: . = 0x2000 + SIZEOF_HEADERS; \ | ||
| 6 | # RUN: .text : {*(.text)} :all \ | ||
| 7 | # RUN: }" > %t.script | ||
| 8 | # RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared | ||
| 9 | # RUN: llvm-readobj -program-headers %t.so | FileCheck %s | ||
| 10 | |||
| 11 | # CHECK: ProgramHeaders [ | ||
| 12 | # CHECK-NEXT: ProgramHeader { | ||
| 13 | # CHECK-NEXT: Type: PT_LOAD | ||
| 14 | # CHECK-NEXT: Offset: 0x40 | ||
| 15 | # CHECK-NEXT: VirtualAddress: 0x2040 | ||
| 16 | # CHECK-NEXT: PhysicalAddress: 0x2040 | ||
| 17 | # CHECK-NEXT: FileSize: 200 | ||
| 18 | # CHECK-NEXT: MemSize: 200 | ||
| 19 | # CHECK-NEXT: Flags [ | ||
| 20 | # CHECK-NEXT: PF_R (0x4) | ||
| 21 | # CHECK-NEXT: PF_W (0x2) | ||
| 22 | # CHECK-NEXT: PF_X (0x1) | ||
| 23 | # CHECK-NEXT: ] | ||
| 24 | # CHECK-NEXT: Alignment: 4096 | ||
| 25 | # CHECK-NEXT: } | ||
| 26 | # CHECK-NEXT: ] | ||
| 27 | |||
| 28 | # RUN: ld.lld --hash-style=sysv -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000 | ||
| 29 | # RUN: llvm-readobj -program-headers %t2.so \ | ||
| 30 | # RUN: | FileCheck --check-prefix=MAXPAGE %s | ||
| 31 | |||
| 32 | # MAXPAGE: ProgramHeaders [ | ||
| 33 | # MAXPAGE-NEXT: ProgramHeader { | ||
| 34 | # MAXPAGE-NEXT: Type: PT_LOAD | ||
| 35 | # MAXPAGE-NEXT: Offset: 0x40 | ||
| 36 | # MAXPAGE-NEXT: VirtualAddress: 0x2040 | ||
| 37 | # MAXPAGE-NEXT: PhysicalAddress: 0x2040 | ||
| 38 | # MAXPAGE-NEXT: FileSize: 200 | ||
| 39 | # MAXPAGE-NEXT: MemSize: 200 | ||
| 40 | # MAXPAGE-NEXT: Flags [ | ||
| 41 | # MAXPAGE-NEXT: PF_R | ||
| 42 | # MAXPAGE-NEXT: PF_W | ||
| 43 | # MAXPAGE-NEXT: PF_X | ||
| 44 | # MAXPAGE-NEXT: ] | ||
| 45 | # MAXPAGE-NEXT: Alignment: 8192 | ||
| 46 | # MAXPAGE-NEXT: } | ||
| 47 | # MAXPAGE-NEXT: ] | ||
deps/lld/test/ELF/linkerscript/header-addr.test created+49| ... | @@ -0,0 +1,49 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld --hash-style=sysv -o %t.so --script %s %t.o -shared | ||
| 4 | # RUN: llvm-readobj -program-headers %t.so | FileCheck %s | ||
| 5 | |||
| 6 | PHDRS { all PT_LOAD PHDRS; } | ||
| 7 | |||
| 8 | SECTIONS { | ||
| 9 | . = 0x2000 + SIZEOF_HEADERS; | ||
| 10 | .text : {*(.text)} :all | ||
| 11 | } | ||
| 12 | |||
| 13 | # CHECK: ProgramHeaders [ | ||
| 14 | # CHECK-NEXT: ProgramHeader { | ||
| 15 | # CHECK-NEXT: Type: PT_LOAD | ||
| 16 | # CHECK-NEXT: Offset: 0x40 | ||
| 17 | # CHECK-NEXT: VirtualAddress: 0x2040 | ||
| 18 | # CHECK-NEXT: PhysicalAddress: 0x2040 | ||
| 19 | # CHECK-NEXT: FileSize: 200 | ||
| 20 | # CHECK-NEXT: MemSize: 200 | ||
| 21 | # CHECK-NEXT: Flags [ | ||
| 22 | # CHECK-NEXT: PF_R (0x4) | ||
| 23 | # CHECK-NEXT: PF_W (0x2) | ||
| 24 | # CHECK-NEXT: PF_X (0x1) | ||
| 25 | # CHECK-NEXT: ] | ||
| 26 | # CHECK-NEXT: Alignment: 4096 | ||
| 27 | # CHECK-NEXT: } | ||
| 28 | # CHECK-NEXT: ] | ||
| 29 | |||
| 30 | # 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 \ | ||
| 32 | # RUN: | FileCheck --check-prefix=MAXPAGE %s | ||
| 33 | |||
| 34 | # MAXPAGE: ProgramHeaders [ | ||
| 35 | # MAXPAGE-NEXT: ProgramHeader { | ||
| 36 | # MAXPAGE-NEXT: Type: PT_LOAD | ||
| 37 | # MAXPAGE-NEXT: Offset: 0x40 | ||
| 38 | # MAXPAGE-NEXT: VirtualAddress: 0x2040 | ||
| 39 | # MAXPAGE-NEXT: PhysicalAddress: 0x2040 | ||
| 40 | # MAXPAGE-NEXT: FileSize: 200 | ||
| 41 | # MAXPAGE-NEXT: MemSize: 200 | ||
| 42 | # MAXPAGE-NEXT: Flags [ | ||
| 43 | # MAXPAGE-NEXT: PF_R | ||
| 44 | # MAXPAGE-NEXT: PF_W | ||
| 45 | # MAXPAGE-NEXT: PF_X | ||
| 46 | # MAXPAGE-NEXT: ] | ||
| 47 | # MAXPAGE-NEXT: Alignment: 8192 | ||
| 48 | # MAXPAGE-NEXT: } | ||
| 49 | # MAXPAGE-NEXT: ] | ||
deps/lld/test/ELF/linkerscript/header-phdr.s deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "PHDRS { foobar PT_LOAD FILEHDR PHDRS; } \ | ||
| 4 | # RUN: SECTIONS { . = 0x1000; .abc : { *(.zed) } : foobar }" > %t.script | ||
| 5 | # RUN: ld.lld --script %t.script %t.o -o %t | ||
| 6 | # RUN: llvm-readelf -l -S -W %t | FileCheck %s | ||
| 7 | |||
| 8 | .section .zed, "a" | ||
| 9 | .zero 4 | ||
| 10 | |||
| 11 | |||
| 12 | # CHECK: [ 1] .abc PROGBITS 0000000000001000 001000 000004 00 A 0 0 1 | ||
| 13 | # CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001004 0x001004 R E 0x1000 | ||
deps/lld/test/ELF/linkerscript/header-phdr.test created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .zed, "a"; .zero 4' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | # RUN: ld.lld --script %s %t.o -o %t | ||
| 5 | # RUN: llvm-readelf -l -S -W %t | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: [ 1] .abc PROGBITS 0000000000001000 001000 000004 00 A 0 0 1 | ||
| 8 | # CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001004 0x001004 R E 0x1000 | ||
| 9 | |||
| 10 | PHDRS { foobar PT_LOAD FILEHDR PHDRS; } | ||
| 11 | |||
| 12 | SECTIONS { | ||
| 13 | . = 0x1000; | ||
| 14 | .abc : { *(.zed) } : foobar | ||
| 15 | } | ||
deps/lld/test/ELF/linkerscript/header-phdr2.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "PHDRS { foobar PT_LOAD FILEHDR PHDRS; }" > %t.script | ||
| 4 | # RUN: echo "SECTIONS { .text : { *(.text) } : foobar }" >> %t.script | ||
| 5 | # RUN: not ld.lld --script %t.script %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: could not allocate headers | ||
| 8 | |||
| 9 | .global _start | ||
| 10 | _start: | ||
| 11 | retq | ||
deps/lld/test/ELF/linkerscript/huge-temporary-file.s+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | # RUN: echo "SECTIONS { .text 0x2000 : {. = 0x10 ; *(.text) } }" > %t.script | 3 | # RUN: echo "SECTIONS { .text 0x2000 : {. = 0x10 ; *(.text) } }" > %t.script |
| 4 | # RUN: not ld.lld %t --script %t.script -o %t1 | 4 | # RUN: not ld.lld %t --script %t.script -o %t1 |
| 5 | 5 | ||
| 6 | ## This inputs previously created a 4gb temporarily fine under 32 bit | 6 | ## This inputs previously created a 4gb temporarily file under 32 bit |
| 7 | ## configuration. Issue was fixed. There is no clean way to check that from here. | 7 | ## configuration. Issue was fixed. There is no clean way to check that from here. |
| 8 | ## This testcase added for documentation purposes. | 8 | ## This testcase added for documentation purposes. |
| 9 | 9 |
deps/lld/test/ELF/linkerscript/i386-sections-max-va-overflow.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { . = 0xfffffff1;" > %t.script | ||
| 5 | # RUN: echo " .bar : { *(.bar*) } }" >> %t.script | ||
| 6 | # RUN: not ld.lld -o /dev/null --script %t.script %t.o 2>&1 | FileCheck %s -check-prefix=ERR | ||
| 7 | |||
| 8 | ## .bar section has data in [0xfffffff1, 0xfffffff1 + 0x10] == [0xffffff1, 0x1]. | ||
| 9 | ## Check we can catch this overflow. | ||
| 10 | # ERR: error: section .bar at 0xFFFFFFF1 of size 0x10 exceeds available address space | ||
| 11 | |||
| 12 | .section .bar,"ax",@progbits | ||
| 13 | .zero 0x10 | ||
deps/lld/test/ELF/linkerscript/image-base.s+18-18| ... | @@ -1,18 +1,18 @@ | ... | @@ -1,18 +1,18 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # 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 -o %t.o |
| 4 | # RUN: echo "SECTIONS { mysym = .; }" > %t.script | 4 | # RUN: echo "SECTIONS { mysym = .; }" > %t.script |
| 5 | 5 | ||
| 6 | # RUN: ld.lld %t.o -o %t-default.elf -T %t.script | 6 | # RUN: ld.lld %t.o -o %t-default.elf -T %t.script |
| 7 | # RUN: llvm-readobj --symbols %t-default.elf | FileCheck %s --check-prefix=DEFAULT | 7 | # RUN: llvm-readobj --symbols %t-default.elf | FileCheck %s --check-prefix=DEFAULT |
| 8 | # DEFAULT: Name: mysym | 8 | # DEFAULT: Name: mysym |
| 9 | # DEFAULT-NEXT: Value: 0x0 | 9 | # DEFAULT-NEXT: Value: 0x0 |
| 10 | 10 | ||
| 11 | # RUN: ld.lld %t.o -o %t-switch.elf -T %t.script --image-base=0x100000 | 11 | # RUN: ld.lld %t.o -o %t-switch.elf -T %t.script --image-base=0x100000 |
| 12 | # RUN: llvm-readobj --symbols %t-switch.elf | FileCheck %s --check-prefix=SWITCH | 12 | # RUN: llvm-readobj --symbols %t-switch.elf | FileCheck %s --check-prefix=SWITCH |
| 13 | # SWITCH: Name: mysym | 13 | # SWITCH: Name: mysym |
| 14 | # SWITCH-NEXT: Value: 0x100000 | 14 | # SWITCH-NEXT: Value: 0x100000 |
| 15 | 15 | ||
| 16 | .global _start | 16 | .global _start |
| 17 | _start: | 17 | _start: |
| 18 | nop | 18 | nop |
deps/lld/test/ELF/linkerscript/implicit-program-header.s deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %S/Inputs/implicit-program-header.script \ | ||
| 4 | # RUN: %t.o -shared | ||
| 5 | # RUN: llvm-readobj -elf-output-style=GNU -l %t1 | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: Segment Sections... | ||
| 8 | # CHECK-NEXT: 00 .text .dynsym .hash .dynstr .dynamic | ||
| 9 | # CHECK-NEXT: 01 .foo | ||
| 10 | |||
| 11 | .quad 0 | ||
| 12 | .section .foo,"ax" | ||
| 13 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/implicit-program-header.test created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: echo '.section .text,"ax"; .quad 0' > %t.s | ||
| 4 | # RUN: echo '.section .foo,"ax"; .quad 0' >> %t.s | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t.o | ||
| 6 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %s %t.o -shared | ||
| 7 | # RUN: llvm-readelf -l %t1 | FileCheck %s | ||
| 8 | |||
| 9 | # CHECK: Segment Sections... | ||
| 10 | # CHECK-NEXT: 00 .dynsym .hash .dynstr .bar .foo .text .dynamic | ||
| 11 | # CHECK-NEXT: 01 .bar .foo | ||
| 12 | |||
| 13 | PHDRS { | ||
| 14 | ph_write PT_LOAD FLAGS(2); | ||
| 15 | ph_exec PT_LOAD FLAGS(1); | ||
| 16 | } | ||
| 17 | |||
| 18 | SECTIONS { | ||
| 19 | .bar : { *(.bar) } : ph_exec | ||
| 20 | .foo : { *(.foo) } | ||
| 21 | .text : { *(.text) } : ph_write | ||
| 22 | } | ||
deps/lld/test/ELF/linkerscript/info-section-type.s created+33| ... | @@ -0,0 +1,33 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | |||
| 4 | ## In this test we check that output section types such as | ||
| 5 | ## COPY, INFO and OVERLAY marks output section as non-allocatable. | ||
| 6 | |||
| 7 | # RUN: echo "SECTIONS { .bar : { *(.foo) } };" > %t.script | ||
| 8 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 9 | # RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=DEFAULT | ||
| 10 | # DEFAULT: Name: .bar | ||
| 11 | # DEFAULT: Type: SHT_PROGBITS | ||
| 12 | # DEFAULT-NEXT: Flags [ | ||
| 13 | # DEFAULT-NEXT: SHF_ALLOC | ||
| 14 | # DEFAULT-NEXT: ] | ||
| 15 | |||
| 16 | # RUN: echo "SECTIONS { .bar (COPY) : { *(.foo) } };" > %t.script | ||
| 17 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 18 | # RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC | ||
| 19 | # NONALLOC: Name: .bar | ||
| 20 | # NONALLOC: Type: SHT_PROGBITS | ||
| 21 | # NONALLOC-NEXT: Flags [ | ||
| 22 | # NONALLOC-NEXT: ] | ||
| 23 | |||
| 24 | # RUN: echo "SECTIONS { .bar (INFO) : { *(.foo) } };" > %t.script | ||
| 25 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 26 | # RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC | ||
| 27 | |||
| 28 | # RUN: echo "SECTIONS { .bar (OVERLAY) : { *(.foo) } };" > %t.script | ||
| 29 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 30 | # RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC | ||
| 31 | |||
| 32 | .section .foo,"a",@progbits | ||
| 33 | .zero 1 | ||
deps/lld/test/ELF/linkerscript/insert-after.test created+29| ... | @@ -0,0 +1,29 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/insert-after.s -o %t1.o | ||
| 3 | |||
| 4 | ## Main linker script contains .text and .data sections. Here | ||
| 5 | ## we check that can use INSERT AFTER to insert sections .foo.data | ||
| 6 | ## and .foo.text at the right places. | ||
| 7 | |||
| 8 | SECTIONS { | ||
| 9 | .foo.data : { *(.foo.data) } | ||
| 10 | } INSERT AFTER .data; | ||
| 11 | |||
| 12 | SECTIONS { | ||
| 13 | .foo.text : { *(.foo.text) } | ||
| 14 | } INSERT AFTER .text; | ||
| 15 | |||
| 16 | # RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s | ||
| 17 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 18 | # CHECK: Sections: | ||
| 19 | # CHECK-NEXT: Idx Name Size Address Type | ||
| 20 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 21 | # CHECK-NEXT: 1 .text 00000008 0000000000000000 TEXT | ||
| 22 | # CHECK-NEXT: 2 .foo.text 00000008 0000000000000008 TEXT | ||
| 23 | # CHECK-NEXT: 3 .data 00000008 0000000000000010 DATA | ||
| 24 | # CHECK-NEXT: 4 .foo.data 00000008 0000000000000018 DATA | ||
| 25 | |||
| 26 | # RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \ | ||
| 27 | # RUN: | FileCheck %s --check-prefix=ERR | ||
| 28 | # ERR-DAG: error: unable to INSERT AFTER/BEFORE .text: section not defined | ||
| 29 | # ERR-DAG: error: unable to INSERT AFTER/BEFORE .data: section not defined | ||
deps/lld/test/ELF/linkerscript/insert-before.test created+29| ... | @@ -0,0 +1,29 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/insert-after.s -o %t1.o | ||
| 3 | |||
| 4 | ## Main linker script contains .text and .data sections. Here | ||
| 5 | ## we check that can use INSERT BEFORE to insert sections .foo.data | ||
| 6 | ## and .foo.text at the right places. | ||
| 7 | |||
| 8 | SECTIONS { | ||
| 9 | .foo.data : { *(.foo.data) } | ||
| 10 | } INSERT BEFORE .data; | ||
| 11 | |||
| 12 | SECTIONS { | ||
| 13 | .foo.text : { *(.foo.text) } | ||
| 14 | } INSERT BEFORE .text; | ||
| 15 | |||
| 16 | # RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s | ||
| 17 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | ||
| 18 | # CHECK: Sections: | ||
| 19 | # CHECK-NEXT: Idx Name Size Address Type | ||
| 20 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 21 | # CHECK-NEXT: 1 .foo.text 00000008 0000000000000000 TEXT | ||
| 22 | # CHECK-NEXT: 2 .text 00000008 0000000000000008 TEXT | ||
| 23 | # CHECK-NEXT: 3 .foo.data 00000008 0000000000000010 DATA | ||
| 24 | # CHECK-NEXT: 4 .data 00000008 0000000000000018 DATA | ||
| 25 | |||
| 26 | # RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \ | ||
| 27 | # RUN: | FileCheck %s --check-prefix=ERR | ||
| 28 | # ERR-DAG: error: unable to INSERT AFTER/BEFORE .text: section not defined | ||
| 29 | # ERR-DAG: error: unable to INSERT AFTER/BEFORE .data: section not defined | ||
deps/lld/test/ELF/linkerscript/insert-broken.test created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | SECTIONS { | ||
| 2 | .foo : { *(.bar) } | ||
| 3 | } INSERT .data; | ||
| 4 | |||
| 5 | # RUN: not ld.lld -o %t1 --script %s 2>&1 | FileCheck %s | ||
| 6 | # CHECK: {{.*}}:3: expected AFTER/BEFORE, but got '.data' | ||
deps/lld/test/ELF/linkerscript/lazy-symbols.s deleted-13| ... | @@ -1,13 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1 | ||
| 3 | # RUN: llvm-ar rcs %tar %t1 | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2 | ||
| 5 | # RUN: echo "foo = 1;" > %t.script | ||
| 6 | # RUN: ld.lld %t2 %tar --script %t.script -o %tout | ||
| 7 | # RUN: llvm-readobj -symbols %tout | FileCheck %s | ||
| 8 | |||
| 9 | # This test is to ensure a linker script can define a symbol which have the same | ||
| 10 | # name as a lazy symbol. | ||
| 11 | |||
| 12 | # CHECK: Name: foo | ||
| 13 | # CHECK-NEXT: Value: 0x1 | ||
deps/lld/test/ELF/linkerscript/lazy-symbols.test created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1 | ||
| 3 | # RUN: llvm-ar rcs %tar %t1 | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t2 | ||
| 5 | # RUN: ld.lld %t2 %tar --script %s -o %tout | ||
| 6 | # RUN: llvm-readobj -symbols %tout | FileCheck %s | ||
| 7 | |||
| 8 | foo = 1; | ||
| 9 | |||
| 10 | # This test is to ensure a linker script can define a symbol which have the same | ||
| 11 | # name as a lazy symbol. | ||
| 12 | |||
| 13 | # CHECK: Name: foo | ||
| 14 | # CHECK-NEXT: Value: 0x1 | ||
deps/lld/test/ELF/linkerscript/linker-script-in-search-path.s+5-5| ... | @@ -4,16 +4,16 @@ | ... | @@ -4,16 +4,16 @@ |
| 4 | 4 | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 6 | # RUN: mkdir -p %T/searchpath | 6 | # RUN: mkdir -p %T/searchpath |
| 7 | # RUN: echo "OUTPUT(\"%t.out\")" > %T/searchpath/foo.script | 7 | # RUN: echo 'OUTPUT("%t.out")' > %T/searchpath/%basename_t.script |
| 8 | # RUN: ld.lld -T%T/searchpath/foo.script %t.o | 8 | # RUN: ld.lld -T%T/searchpath/%basename_t.script %t.o |
| 9 | # RUN: llvm-readobj %t.out | FileCheck %s | 9 | # RUN: llvm-readobj %t.out | FileCheck %s |
| 10 | # CHECK: Format: ELF64-x86-64 | 10 | # CHECK: Format: ELF64-x86-64 |
| 11 | 11 | ||
| 12 | # If the linker script specified with -T is missing we should emit an error | 12 | # If the linker script specified with -T is missing we should emit an error |
| 13 | # RUN: not ld.lld -Tfoo.script %t.o 2>&1 | FileCheck %s -check-prefix ERROR | 13 | # RUN: not ld.lld -T%basename_t.script %t.o 2>&1 | FileCheck %s -check-prefix ERROR |
| 14 | # ERROR: error: cannot find linker script foo.script | 14 | # ERROR: error: cannot find linker script {{.*}}.script |
| 15 | 15 | ||
| 16 | # But if it exists in the search path we should fall back to that instead: | 16 | # But if it exists in the search path we should fall back to that instead: |
| 17 | # RUN: rm %t.out | 17 | # RUN: rm %t.out |
| 18 | # RUN: ld.lld -L %T/searchpath -Tfoo.script %t.o | 18 | # RUN: ld.lld -L %T/searchpath -T%basename_t.script %t.o |
| 19 | # RUN: llvm-readobj %t.out | FileCheck %s | 19 | # RUN: llvm-readobj %t.out | FileCheck %s |
deps/lld/test/ELF/linkerscript/linkerscript.s+6-6| ... | @@ -17,32 +17,32 @@ | ... | @@ -17,32 +17,32 @@ |
| 17 | # RUN: llvm-readobj %t.out > /dev/null | 17 | # RUN: llvm-readobj %t.out > /dev/null |
| 18 | 18 | ||
| 19 | # RUN: echo "SEARCH_DIR(/lib/foo/blah)" > %t.script | 19 | # RUN: echo "SEARCH_DIR(/lib/foo/blah)" > %t.script |
| 20 | # RUN: ld.lld %t.script %t | 20 | # RUN: ld.lld %t.script %t -o %t.out |
| 21 | # RUN: llvm-readobj %t.out > /dev/null | 21 | # RUN: llvm-readobj %t.out > /dev/null |
| 22 | 22 | ||
| 23 | # RUN: echo ";SEARCH_DIR(x);SEARCH_DIR(y);" > %t.script | 23 | # RUN: echo ";SEARCH_DIR(x);SEARCH_DIR(y);" > %t.script |
| 24 | # RUN: ld.lld %t.script %t | 24 | # RUN: ld.lld %t.script %t -o %t.out |
| 25 | # RUN: llvm-readobj %t.out > /dev/null | 25 | # RUN: llvm-readobj %t.out > /dev/null |
| 26 | 26 | ||
| 27 | # RUN: echo ";" > %t.script | 27 | # RUN: echo ";" > %t.script |
| 28 | # RUN: ld.lld %t.script %t | 28 | # RUN: ld.lld %t.script %t -o %t.out |
| 29 | # RUN: llvm-readobj %t.out > /dev/null | 29 | # RUN: llvm-readobj %t.out > /dev/null |
| 30 | 30 | ||
| 31 | # RUN: echo "INCLUDE \"%t.script2\" OUTPUT(\"%t.out\")" > %t.script1 | 31 | # RUN: echo "INCLUDE \"%t.script2\" OUTPUT(\"%t.out\")" > %t.script1 |
| 32 | # RUN: echo "GROUP(\"%t\")" > %t.script2 | 32 | # RUN: echo "GROUP(\"%t\")" > %t.script2 |
| 33 | # RUN: ld.lld %t.script1 | 33 | # RUN: ld.lld %t.script1 -o %t.out |
| 34 | # RUN: llvm-readobj %t2 > /dev/null | 34 | # RUN: llvm-readobj %t2 > /dev/null |
| 35 | 35 | ||
| 36 | # RUN: echo "INCLUDE \"foo.script\"" > %t.script | 36 | # RUN: echo "INCLUDE \"foo.script\"" > %t.script |
| 37 | # RUN: echo "OUTPUT(\"%t.out\")" > %T/foo.script | 37 | # RUN: echo "OUTPUT(\"%t.out\")" > %T/foo.script |
| 38 | # RUN: not ld.lld %t.script > %t.log 2>&1 | 38 | # RUN: not ld.lld %t.script -o %t.out > %t.log 2>&1 |
| 39 | # RUN: FileCheck -check-prefix=INCLUDE_ERR %s < %t.log | 39 | # RUN: FileCheck -check-prefix=INCLUDE_ERR %s < %t.log |
| 40 | # INCLUDE_ERR: error: {{.+}}.script:1: cannot find linker script foo.script | 40 | # INCLUDE_ERR: error: {{.+}}.script:1: cannot find linker script foo.script |
| 41 | # INCLUDE_ERR-NEXT: INCLUDE "foo.script" | 41 | # INCLUDE_ERR-NEXT: INCLUDE "foo.script" |
| 42 | # RUN: ld.lld -L %T %t.script %t | 42 | # RUN: ld.lld -L %T %t.script %t |
| 43 | 43 | ||
| 44 | # RUN: echo "FOO(BAR)" > %t.script | 44 | # RUN: echo "FOO(BAR)" > %t.script |
| 45 | # RUN: not ld.lld -o foo %t.script > %t.log 2>&1 | 45 | # RUN: not ld.lld -o %t.out %t.script > %t.log 2>&1 |
| 46 | # RUN: FileCheck -check-prefix=ERR1 %s < %t.log | 46 | # RUN: FileCheck -check-prefix=ERR1 %s < %t.log |
| 47 | 47 | ||
| 48 | # ERR1: unknown directive: FOO | 48 | # ERR1: unknown directive: FOO |
deps/lld/test/ELF/linkerscript/lma-overflow.test created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: echo '.section .foo,"a"; .quad 1' | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | # RUN: not ld.lld -o %t %t.o --script %s 2>&1 | FileCheck %s | ||
| 5 | # CHECK: error: section '.foo' will not fit in region 'flash': overflowed by 264 bytes | ||
| 6 | |||
| 7 | MEMORY { | ||
| 8 | ram (rwx) : org = 0x1000, len = 0x300 | ||
| 9 | flash (rwx) : org = 0x1000, len = 0x100 | ||
| 10 | } | ||
| 11 | SECTIONS { | ||
| 12 | .foo : { | ||
| 13 | *(.foo) | ||
| 14 | . += 0x200; | ||
| 15 | } > ram AT>flash | ||
| 16 | } | ||
deps/lld/test/ELF/linkerscript/locationcountererr.s deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS {" > %t.script | ||
| 5 | # RUN: echo ".text 0x2000 : {. = 0x10 ; *(.text) } }" >> %t.script | ||
| 6 | # RUN: not ld.lld %t --script %t.script -o %t1 2>&1 | FileCheck %s | ||
| 7 | # CHECK: {{.*}}.script:2: unable to move location counter backward for: .text | ||
| 8 | |||
| 9 | .globl _start | ||
| 10 | _start: | ||
| 11 | nop | ||
deps/lld/test/ELF/linkerscript/locationcountererr.test created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t | ||
| 3 | # RUN: not ld.lld %t --script %s -o %t1 2>&1 | FileCheck %s | ||
| 4 | # CHECK: {{.*}}.test:8: unable to move location counter backward for: .text | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .text 0x2000 : { | ||
| 8 | . = 0x10; | ||
| 9 | *(.text) | ||
| 10 | } | ||
| 11 | } | ||
deps/lld/test/ELF/linkerscript/locationcountererr2.s+3-3| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: echo "SECTIONS {" > %t.script | 3 | # RUN: echo "SECTIONS {" > %t.script |
| 4 | # RUN: echo ". = 0x20; . = 0x10; .text : {} }" >> %t.script | 4 | # RUN: echo ". = 0x150; . = 0x10; .text : {} }" >> %t.script |
| 5 | # RUN: ld.lld %t.o --script %t.script -o %t -shared | 5 | # RUN: ld.lld %t.o --script %t.script -o %t -shared |
| 6 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | 6 | # RUN: llvm-objdump -section-headers %t | FileCheck %s |
| 7 | # CHECK: Idx Name Size Address | 7 | # CHECK: Name Size Address |
| 8 | # CHECK: 1 .text 00000000 0000000000000010 | 8 | # CHECK: .text 00000000 0000000000000010 |
| 9 | 9 | ||
| 10 | # RUN: echo "SECTIONS { . = 0x20; . = ASSERT(0x1, "foo"); }" > %t2.script | 10 | # RUN: echo "SECTIONS { . = 0x20; . = ASSERT(0x1, "foo"); }" > %t2.script |
| 11 | # RUN: ld.lld %t.o --script %t2.script -o %t -shared | 11 | # RUN: ld.lld %t.o --script %t2.script -o %t -shared |
deps/lld/test/ELF/linkerscript/map-file.test created+60| ... | @@ -0,0 +1,60 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: echo '.quad sym3; .quad sym4; .section .foo.1, "a"; .quad 1' > %t.s | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o | ||
| 5 | |||
| 6 | # RUN: ld.lld -o %t %t.o -Map=%t.map --script %s | ||
| 7 | # RUN: FileCheck -strict-whitespace %s < %t.map | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | . = 0x1000; | ||
| 11 | .foo : { | ||
| 12 | BYTE(0x11) | ||
| 13 | SHORT(0x1122) | ||
| 14 | LONG(0x11223344) | ||
| 15 | QUAD(0x1122334455667788) | ||
| 16 | PROVIDE_HIDDEN(sym4 = .); | ||
| 17 | . += 0x1000; | ||
| 18 | *(.foo.1) | ||
| 19 | PROVIDE(unused1 = 0xff); | ||
| 20 | HIDDEN(sym6 = .); | ||
| 21 | . += 0x123 * | ||
| 22 | (1 + 1); | ||
| 23 | foo = .; | ||
| 24 | bar = 0x42 - 0x26; | ||
| 25 | } | ||
| 26 | sym1 = .; | ||
| 27 | . += 0x500; | ||
| 28 | sym2 = .; | ||
| 29 | PROVIDE(unused2 = 0xff); | ||
| 30 | PROVIDE(sym3 = 42); | ||
| 31 | } | ||
| 32 | |||
| 33 | # CHECK: VMA LMA Size Align Out In Symbol | ||
| 34 | # CHECK-NEXT: 0 0 1000 1 . = 0x1000 | ||
| 35 | # CHECK-NEXT: 1000 1000 125d 1 .foo | ||
| 36 | # CHECK-NEXT: 1000 1000 1 1 BYTE ( 0x11 ) | ||
| 37 | # CHECK-NEXT: 1001 1001 2 1 SHORT ( 0x1122 ) | ||
| 38 | # CHECK-NEXT: 1003 1003 4 1 LONG ( 0x11223344 ) | ||
| 39 | # CHECK-NEXT: 1007 1007 8 1 QUAD ( 0x1122334455667788 ) | ||
| 40 | # CHECK-NEXT: 100f 100f 0 1 PROVIDE_HIDDEN ( sym4 = . ) | ||
| 41 | # CHECK-NEXT: 100f 100f 1000 1 . += 0x1000 | ||
| 42 | # CHECK-NEXT: 200f 200f 8 1 {{.*}}{{/|\\}}map-file.test.tmp.o:(.foo.1) | ||
| 43 | # CHECK-NEXT: 2017 2017 0 1 HIDDEN ( sym6 = . ) | ||
| 44 | # CHECK-NEXT: 2017 2017 246 1 . += 0x123 * ( 1 + 1 ) | ||
| 45 | # CHECK-NEXT: 225d 225d 0 1 foo = . | ||
| 46 | # CHECK-NEXT: 225d 225d 0 1 bar = 0x42 - 0x26 | ||
| 47 | # CHECK-NEXT: 225d 0 0 1 sym1 = . | ||
| 48 | # CHECK-NEXT: 225d 0 500 1 . += 0x500 | ||
| 49 | # CHECK-NEXT: 275d 0 0 1 sym2 = . | ||
| 50 | # CHECK-NEXT: 275d 0 0 1 PROVIDE ( sym3 = 42 ) | ||
| 51 | # CHECK-NEXT: 2760 2760 10 4 .text | ||
| 52 | # CHECK-NEXT: 2760 2760 10 4 {{.*}}{{/|\\}}map-file.test.tmp.o:(.text) | ||
| 53 | # CHECK-NEXT: 0 0 8 1 .comment | ||
| 54 | # CHECK-NEXT: 0 0 8 1 <internal>:(.comment) | ||
| 55 | # CHECK-NEXT: 0 0 c0 8 .symtab | ||
| 56 | # CHECK-NEXT: 0 0 c0 8 <internal>:(.symtab) | ||
| 57 | # CHECK-NEXT: 0 0 2f 1 .shstrtab | ||
| 58 | # CHECK-NEXT: 0 0 2f 1 <internal>:(.shstrtab) | ||
| 59 | # CHECK-NEXT: 0 0 22 1 .strtab | ||
| 60 | # CHECK-NEXT: 0 0 22 1 <internal>:(.strtab) | ||
deps/lld/test/ELF/linkerscript/map-file2.test created+44| ... | @@ -0,0 +1,44 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file2.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t %t.o -Map=%t.map --script %s | ||
| 4 | # RUN: FileCheck -strict-whitespace %s < %t.map | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = 0x1000; | ||
| 8 | .aaa : { *(.aaa.*) } | ||
| 9 | .bbb : AT(0x2000) { *(.bbb.*) } | ||
| 10 | .ccc : AT(0x3000) { *(.ccc.*) } | ||
| 11 | .ddd : { | ||
| 12 | BYTE(0x11) | ||
| 13 | . += 0x100; | ||
| 14 | *(.ddd.*) | ||
| 15 | } | ||
| 16 | .text : { *(.text.*) } | ||
| 17 | } | ||
| 18 | |||
| 19 | # CHECK: VMA LMA Size Align Out In Symbol | ||
| 20 | # CHECK-NEXT: 0 0 1000 1 . = 0x1000 | ||
| 21 | # CHECK-NEXT: 1000 1000 8 1 .aaa | ||
| 22 | # CHECK-NEXT: 1000 1000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.aaa) | ||
| 23 | # CHECK-NEXT: 1008 2000 8 1 .bbb | ||
| 24 | # CHECK-NEXT: 1008 2000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.bbb) | ||
| 25 | # CHECK-NEXT: 1010 3000 8 1 .ccc | ||
| 26 | # CHECK-NEXT: 1010 3000 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ccc) | ||
| 27 | # CHECK-NEXT: 1018 3008 109 1 .ddd | ||
| 28 | # CHECK-NEXT: 1018 3008 1 1 BYTE ( 0x11 ) | ||
| 29 | # CHECK-NEXT: 1019 3009 100 1 . += 0x100 | ||
| 30 | # CHECK-NEXT: 1119 3109 8 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.ddd) | ||
| 31 | # CHECK-NEXT: 1128 3118 34 8 .eh_frame | ||
| 32 | # CHECK-NEXT: 1128 3118 30 1 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.eh_frame+0x0) | ||
| 33 | # CHECK-NEXT: 115c 314c 1 4 .text | ||
| 34 | # CHECK-NEXT: 115c 314c 1 4 {{.*}}{{/|\\}}map-file2.test.tmp.o:(.text) | ||
| 35 | # CHECK-NEXT: 115c 314c 0 1 f(int) | ||
| 36 | # CHECK-NEXT: 115c 314c 0 1 _start | ||
| 37 | # CHECK-NEXT: 0 0 8 1 .comment | ||
| 38 | # CHECK-NEXT: 0 0 8 1 <internal>:(.comment) | ||
| 39 | # CHECK-NEXT: 0 0 48 8 .symtab | ||
| 40 | # CHECK-NEXT: 0 0 48 8 <internal>:(.symtab) | ||
| 41 | # CHECK-NEXT: 0 0 48 1 .shstrtab | ||
| 42 | # CHECK-NEXT: 0 0 48 1 <internal>:(.shstrtab) | ||
| 43 | # CHECK-NEXT: 0 0 e 1 .strtab | ||
| 44 | # CHECK-NEXT: 0 0 e 1 <internal>:(.strtab) | ||
deps/lld/test/ELF/linkerscript/memory-at.s deleted-46| ... | @@ -1,46 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: echo "MEMORY { \ | ||
| 4 | # RUN: FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0x100 \ | ||
| 5 | # RUN: RAM (rwx) : ORIGIN = 0x2000, LENGTH = 0x100 } \ | ||
| 6 | # RUN: SECTIONS { \ | ||
| 7 | # RUN: .text : { *(.text*) } > FLASH \ | ||
| 8 | # RUN: __etext = .; \ | ||
| 9 | # RUN: .data : AT (__etext) { *(.data*) } > RAM \ | ||
| 10 | # RUN: }" > %t.script | ||
| 11 | # RUN: ld.lld %t --script %t.script -o %t2 | ||
| 12 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s | ||
| 13 | |||
| 14 | # CHECK: ProgramHeaders [ | ||
| 15 | # CHECK-NEXT: ProgramHeader { | ||
| 16 | # CHECK-NEXT: Type: PT_LOAD | ||
| 17 | # CHECK-NEXT: Offset: 0x1000 | ||
| 18 | # CHECK-NEXT: VirtualAddress: 0x1000 | ||
| 19 | # CHECK-NEXT: PhysicalAddress: 0x1000 | ||
| 20 | # CHECK-NEXT: FileSize: 8 | ||
| 21 | # CHECK-NEXT: MemSize: 8 | ||
| 22 | # CHECK-NEXT: Flags [ | ||
| 23 | # CHECK-NEXT: PF_R | ||
| 24 | # CHECK-NEXT: PF_X | ||
| 25 | # CHECK-NEXT: ] | ||
| 26 | # CHECK-NEXT: Alignment: | ||
| 27 | # CHECK-NEXT: } | ||
| 28 | # CHECK-NEXT: ProgramHeader { | ||
| 29 | # CHECK-NEXT: Type: PT_LOAD | ||
| 30 | # CHECK-NEXT: Offset: 0x2000 | ||
| 31 | # CHECK-NEXT: VirtualAddress: 0x2000 | ||
| 32 | # CHECK-NEXT: PhysicalAddress: 0x1008 | ||
| 33 | # CHECK-NEXT: FileSize: 8 | ||
| 34 | # CHECK-NEXT: MemSize: 8 | ||
| 35 | # CHECK-NEXT: Flags [ | ||
| 36 | # CHECK-NEXT: PF_R | ||
| 37 | # CHECK-NEXT: PF_W | ||
| 38 | # CHECK-NEXT: ] | ||
| 39 | # CHECK-NEXT: Alignment: | ||
| 40 | # CHECK-NEXT: } | ||
| 41 | |||
| 42 | .section .text, "ax" | ||
| 43 | .quad 0 | ||
| 44 | |||
| 45 | .section .data, "aw" | ||
| 46 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/memory-at.test created+45| ... | @@ -0,0 +1,45 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .text,"ax"; .quad 0' > %t.s | ||
| 3 | # RUN: echo '.section .data,"aw"; .quad 0' >> %t.s | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t | ||
| 5 | # RUN: ld.lld %t --script %s -o %t2 | ||
| 6 | # RUN: llvm-readobj -program-headers %t2 | FileCheck %s | ||
| 7 | |||
| 8 | MEMORY { | ||
| 9 | FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0x100 | ||
| 10 | RAM (rwx) : ORIGIN = 0x2000, LENGTH = 0x100 | ||
| 11 | } | ||
| 12 | |||
| 13 | SECTIONS { | ||
| 14 | .text : { *(.text*) } > FLASH | ||
| 15 | __etext = .; | ||
| 16 | .data : AT (__etext) { *(.data*) } > RAM | ||
| 17 | } | ||
| 18 | |||
| 19 | # CHECK: ProgramHeaders [ | ||
| 20 | # CHECK-NEXT: ProgramHeader { | ||
| 21 | # CHECK-NEXT: Type: PT_LOAD | ||
| 22 | # CHECK-NEXT: Offset: 0x1000 | ||
| 23 | # CHECK-NEXT: VirtualAddress: 0x1000 | ||
| 24 | # CHECK-NEXT: PhysicalAddress: 0x1000 | ||
| 25 | # CHECK-NEXT: FileSize: 8 | ||
| 26 | # CHECK-NEXT: MemSize: 8 | ||
| 27 | # CHECK-NEXT: Flags [ | ||
| 28 | # CHECK-NEXT: PF_R | ||
| 29 | # CHECK-NEXT: PF_X | ||
| 30 | # CHECK-NEXT: ] | ||
| 31 | # CHECK-NEXT: Alignment: | ||
| 32 | # CHECK-NEXT: } | ||
| 33 | # CHECK-NEXT: ProgramHeader { | ||
| 34 | # CHECK-NEXT: Type: PT_LOAD | ||
| 35 | # CHECK-NEXT: Offset: 0x2000 | ||
| 36 | # CHECK-NEXT: VirtualAddress: 0x2000 | ||
| 37 | # CHECK-NEXT: PhysicalAddress: 0x1008 | ||
| 38 | # CHECK-NEXT: FileSize: 8 | ||
| 39 | # CHECK-NEXT: MemSize: 8 | ||
| 40 | # CHECK-NEXT: Flags [ | ||
| 41 | # CHECK-NEXT: PF_R | ||
| 42 | # CHECK-NEXT: PF_W | ||
| 43 | # CHECK-NEXT: ] | ||
| 44 | # CHECK-NEXT: Alignment: | ||
| 45 | # CHECK-NEXT: } | ||
deps/lld/test/ELF/linkerscript/memory-data-commands.test created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: echo ".section .foo,\"a\"" > %t.s | ||
| 4 | # RUN: echo ".quad 1" >> %t.s | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o | ||
| 6 | |||
| 7 | # RUN: not ld.lld -o %t %t.o --script %s 2>&1 | FileCheck %s | ||
| 8 | |||
| 9 | # Check we are able to catch 'ram' overflow caused by BYTE command. | ||
| 10 | # CHECK: error: section '.foo' will not fit in region 'ram': overflowed by 1 bytes | ||
| 11 | |||
| 12 | MEMORY { | ||
| 13 | text (rwx): org = 0x0, len = 0x1000 | ||
| 14 | ram (rwx): org = 0x1000, len = 8 | ||
| 15 | } | ||
| 16 | SECTIONS { | ||
| 17 | .text : { *(.text) } > text | ||
| 18 | .foo : { | ||
| 19 | *(.foo) | ||
| 20 | BYTE(0x1) | ||
| 21 | } > ram | ||
| 22 | } | ||
deps/lld/test/ELF/linkerscript/memory-loc-counter.test created+37| ... | @@ -0,0 +1,37 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: echo ".section .foo,\"a\"" > %t.s | ||
| 4 | # RUN: echo ".quad 1" >> %t.s | ||
| 5 | # RUN: echo ".section .bar,\"a\"" >> %t.s | ||
| 6 | # RUN: echo ".quad 1" >> %t.s | ||
| 7 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o | ||
| 8 | |||
| 9 | # RUN: ld.lld -o %t %t.o --script %s | ||
| 10 | # RUN: llvm-readelf -sections -program-headers %t | FileCheck %s | ||
| 11 | |||
| 12 | ## Check that we can produce output without errors, | ||
| 13 | ## and .foo section has proper size. | ||
| 14 | # CHECK: Section Headers: | ||
| 15 | # CHECK-NEXT: [Nr] Name Type Address Off Size | ||
| 16 | # CHECK-NEXT: [ 0] NULL 0000000000000000 000000 000000 | ||
| 17 | # CHECK-NEXT: [ 1] .foo PROGBITS 0000000000001000 001000 000108 | ||
| 18 | # CHECK-NEXT: [ 2] .bar PROGBITS 0000000000001108 001108 000008 | ||
| 19 | |||
| 20 | ## Check that load address is correct. | ||
| 21 | # CHECK: Program Headers: | ||
| 22 | # CHECK-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz | ||
| 23 | # CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000002000 0x000110 0x000110 | ||
| 24 | |||
| 25 | MEMORY { | ||
| 26 | ram (rwx) : org = 0x1000, len = 0x200 | ||
| 27 | flash (rwx) : org = 0x2000, len = 0x200 | ||
| 28 | } | ||
| 29 | SECTIONS { | ||
| 30 | .foo : { | ||
| 31 | *(.foo) | ||
| 32 | . += 0x100; | ||
| 33 | } > ram AT>flash | ||
| 34 | .bar : { | ||
| 35 | *(.bar) | ||
| 36 | } > ram AT>flash | ||
| 37 | } | ||
deps/lld/test/ELF/linkerscript/memory-region-alignment.test created+58| ... | @@ -0,0 +1,58 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .foo,"a"; .quad 0; .section .zed,"M",@progbits,1; .byte 0' > %t.s | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t.o | ||
| 4 | |||
| 5 | MEMORY { | ||
| 6 | ram (rwx): org = 0x1, len = 96K | ||
| 7 | } | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | .foo : ALIGN(8) { | ||
| 11 | *(.foo) | ||
| 12 | } > ram | ||
| 13 | |||
| 14 | .zed : { | ||
| 15 | *(.zed) | ||
| 16 | } > ram | ||
| 17 | } | ||
| 18 | |||
| 19 | # RUN: ld.lld %t.o -o %t --script %s | ||
| 20 | # RUN: llvm-readobj -sections %t | FileCheck %s | ||
| 21 | |||
| 22 | # CHECK: Name: .foo | ||
| 23 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 24 | # CHECK-NEXT: Flags [ | ||
| 25 | # CHECK-NEXT: SHF_ALLOC | ||
| 26 | # CHECK-NEXT: ] | ||
| 27 | # CHECK-NEXT: Address: 0x8 | ||
| 28 | # CHECK-NEXT: Offset: 0x1008 | ||
| 29 | # CHECK-NEXT: Size: 8 | ||
| 30 | |||
| 31 | # CHECK: Name: .text | ||
| 32 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 33 | # CHECK-NEXT: Flags [ | ||
| 34 | # CHECK-NEXT: SHF_ALLOC | ||
| 35 | # CHECK-NEXT: SHF_EXECINSTR | ||
| 36 | # CHECK-NEXT: ] | ||
| 37 | # CHECK-NEXT: Address: 0x10 | ||
| 38 | # CHECK-NEXT: Offset: 0x1010 | ||
| 39 | # CHECK-NEXT: Size: 0 | ||
| 40 | |||
| 41 | # CHECK: Name: .zed | ||
| 42 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 43 | # CHECK-NEXT: Flags [ | ||
| 44 | # CHECK-NEXT: SHF_MERGE | ||
| 45 | # CHECK-NEXT: ] | ||
| 46 | # CHECK-NEXT: Address: 0x10 | ||
| 47 | # CHECK-NEXT: Offset: 0x1010 | ||
| 48 | # CHECK-NEXT: Size: 1 | ||
| 49 | |||
| 50 | # CHECK: Name: .comment | ||
| 51 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 52 | # CHECK-NEXT: Flags [ | ||
| 53 | # CHECK-NEXT: SHF_MERGE | ||
| 54 | # CHECK-NEXT: SHF_STRINGS | ||
| 55 | # CHECK-NEXT: ] | ||
| 56 | # CHECK-NEXT: Address: 0x0 | ||
| 57 | # CHECK-NEXT: Offset: 0x1011 | ||
| 58 | # CHECK-NEXT: Size: 8 | ||
deps/lld/test/ELF/linkerscript/memory.s+3-3| ... | @@ -11,7 +11,7 @@ | ... | @@ -11,7 +11,7 @@ |
| 11 | # RUN: ld.lld -o %t1 --script %t.script %t | 11 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 12 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAM %s | 12 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAM %s |
| 13 | 13 | ||
| 14 | # RAM: 1 .text 00000001 0000000000008000 TEXT DATA | 14 | # RAM: 1 .text 00000001 0000000000008000 TEXT |
| 15 | # RAM-NEXT: 2 .data 00001000 0000000000008001 DATA | 15 | # RAM-NEXT: 2 .data 00001000 0000000000008001 DATA |
| 16 | 16 | ||
| 17 | ## Check RAM and ROM memory regions. | 17 | ## Check RAM and ROM memory regions. |
| ... | @@ -27,7 +27,7 @@ | ... | @@ -27,7 +27,7 @@ |
| 27 | # RUN: ld.lld -o %t1 --script %t.script %t | 27 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 28 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAMROM %s | 28 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAMROM %s |
| 29 | 29 | ||
| 30 | # RAMROM: 1 .text 00000001 0000000080000000 TEXT DATA | 30 | # RAMROM: 1 .text 00000001 0000000080000000 TEXT |
| 31 | # RAMROM-NEXT: 2 .data 00001000 0000000000000000 DATA | 31 | # RAMROM-NEXT: 2 .data 00001000 0000000000000000 DATA |
| 32 | 32 | ||
| 33 | ## Check memory region placement by attributes. | 33 | ## Check memory region placement by attributes. |
| ... | @@ -43,7 +43,7 @@ | ... | @@ -43,7 +43,7 @@ |
| 43 | # RUN: ld.lld -o %t1 --script %t.script %t | 43 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 44 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=ATTRS %s | 44 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=ATTRS %s |
| 45 | 45 | ||
| 46 | # ATTRS: 1 .text 00000001 0000000080000000 TEXT DATA | 46 | # ATTRS: 1 .text 00000001 0000000080000000 TEXT |
| 47 | # ATTRS: 2 .data 00001000 0000000000000000 DATA | 47 | # ATTRS: 2 .data 00001000 0000000000000000 DATA |
| 48 | 48 | ||
| 49 | ## Check bad `ORIGIN`. | 49 | ## Check bad `ORIGIN`. |
deps/lld/test/ELF/linkerscript/memory2.s+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | # RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0, LENGTH = 2K } \ | 3 | # RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0, LENGTH = 2K } \ |
| 4 | # RUN: SECTIONS { .text : { *(.text*) } > ram }" > %t.script | 4 | # RUN: SECTIONS { .text : { *(.text*) } > ram }" > %t.script |
| 5 | # RUN: ld.lld -o %t2 --script %t.script %t | 5 | # RUN: ld.lld -o /dev/null --script %t.script %t |
| 6 | 6 | ||
| 7 | .text | 7 | .text |
| 8 | .global _start | 8 | .global _start |
deps/lld/test/ELF/linkerscript/memory4.test created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo ".section .text,\"ax\"; nop; .section .data,\"aw\"; nop;" \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o | ||
| 4 | # RUN: ld.lld -o %t.so --script %s %t.o | ||
| 5 | # RUN: llvm-objdump -section-headers %t.so | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: 1 .text 00000001 0000000000042000 | ||
| 8 | # CHECK-NEXT: 2 .data 00000001 0000000000042400 | ||
| 9 | |||
| 10 | ## Test that address expressions changes the position in a memory region. | ||
| 11 | |||
| 12 | MEMORY { | ||
| 13 | ram (wxa) : ORIGIN = 0x42000, LENGTH = 0x100000 | ||
| 14 | } | ||
| 15 | SECTIONS { | ||
| 16 | .text : { *(.text*) } | ||
| 17 | data_addr = ALIGN(1024); | ||
| 18 | .data data_addr : { *(.data*) } | ||
| 19 | } | ||
deps/lld/test/ELF/linkerscript/memory5.test created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo ".section .text,\"ax\"; nop; .section .data,\"aw\"; nop;" \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t.o | ||
| 4 | # RUN: ld.lld -o %t.so --script %s %t.o | ||
| 5 | # RUN: llvm-objdump -section-headers %t.so | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: 1 .text 00000001 0000000000042000 | ||
| 8 | # CHECK-NEXT: 2 .data 00000001 0000000000044001 | ||
| 9 | |||
| 10 | ## Test that assign to Dot changes the position in a memory region. | ||
| 11 | |||
| 12 | MEMORY { | ||
| 13 | ram (wxa) : ORIGIN = 0x42000, LENGTH = 0x100000 | ||
| 14 | } | ||
| 15 | SECTIONS { | ||
| 16 | .text : { *(.text*) } | ||
| 17 | . += 0x2000; | ||
| 18 | .data : { *(.data*) } | ||
| 19 | } | ||
deps/lld/test/ELF/linkerscript/merge-sections-syms.s+2-2| ... | @@ -20,7 +20,7 @@ | ... | @@ -20,7 +20,7 @@ |
| 20 | # CHECK-NEXT: } | 20 | # CHECK-NEXT: } |
| 21 | # CHECK-NEXT: Symbol { | 21 | # CHECK-NEXT: Symbol { |
| 22 | # CHECK-NEXT: Name: A | 22 | # CHECK-NEXT: Name: A |
| 23 | # CHECK-NEXT: Value: 0x195 | 23 | # CHECK-NEXT: Value: 0x226 |
| 24 | # CHECK-NEXT: Size: | 24 | # CHECK-NEXT: Size: |
| 25 | # CHECK-NEXT: Binding: | 25 | # CHECK-NEXT: Binding: |
| 26 | # CHECK-NEXT: Type: | 26 | # CHECK-NEXT: Type: |
| ... | @@ -29,7 +29,7 @@ | ... | @@ -29,7 +29,7 @@ |
| 29 | # CHECK-NEXT: } | 29 | # CHECK-NEXT: } |
| 30 | # CHECK-NEXT: Symbol { | 30 | # CHECK-NEXT: Symbol { |
| 31 | # CHECK-NEXT: Name: B | 31 | # CHECK-NEXT: Name: B |
| 32 | # CHECK-NEXT: Value: 0x196 | 32 | # CHECK-NEXT: Value: 0x227 |
| 33 | # CHECK-NEXT: Size: | 33 | # CHECK-NEXT: Size: |
| 34 | # CHECK-NEXT: Binding: | 34 | # CHECK-NEXT: Binding: |
| 35 | # CHECK-NEXT: Type: | 35 | # CHECK-NEXT: Type: |
deps/lld/test/ELF/linkerscript/merge-sections.s+1-2| ... | @@ -28,8 +28,7 @@ | ... | @@ -28,8 +28,7 @@ |
| 28 | # CHECK-NEXT: Value: 0x[[ADDR1]] | 28 | # CHECK-NEXT: Value: 0x[[ADDR1]] |
| 29 | 29 | ||
| 30 | # CHECK: Name: end | 30 | # CHECK: Name: end |
| 31 | # 0x19E = begin + sizeof(.foo) = 0x190 + 0xE | 31 | # CHECK-NEXT: Value: 0x236 |
| 32 | # CHECK-NEXT: Value: 0x19E | ||
| 33 | 32 | ||
| 34 | # Check that we don't crash with --gc-sections | 33 | # Check that we don't crash with --gc-sections |
| 35 | # RUN: ld.lld --gc-sections -o %t2 --script %t.script %t -shared | 34 | # RUN: ld.lld --gc-sections -o %t2 --script %t.script %t -shared |
deps/lld/test/ELF/linkerscript/no-pt-load.s deleted-5| ... | @@ -1,5 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "PHDRS {foo PT_DYNAMIC ;} " \ | ||
| 4 | # RUN: "SECTIONS { .text : { *(.text) } : foo }" > %t.script | ||
| 5 | # RUN: ld.lld -o %t1 --script %t.script %t.o | ||
deps/lld/test/ELF/linkerscript/no-pt-load.test created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld -o %t1 --script %s %t.o | ||
| 4 | |||
| 5 | ## Check we do not crash. | ||
| 6 | |||
| 7 | PHDRS { foo PT_DYNAMIC; } | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | .text : { *(.text) } : foo | ||
| 11 | } | ||
deps/lld/test/ELF/linkerscript/no-space.s+5-5| ... | @@ -1,13 +1,13 @@ | ... | @@ -1,13 +1,13 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | ||
| 4 | # RUN: echo "SECTIONS {foo 0 : {*(foo*)} }" > %t.script | 4 | # RUN: echo "SECTIONS {foo 0 : {*(foo*)} .dynsym : {*(.dynsym)} .dynstr : {*(.dynstr)} }" > %t.script |
| 5 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared | 5 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared |
| 6 | # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s | 6 | # RUN: llvm-readelf -l %t | FileCheck %s |
| 7 | 7 | ||
| 8 | # RUN: echo "SECTIONS {foo : {*(foo*)} }" > %t.script | 8 | # RUN: echo "SECTIONS {foo : {*(foo*)} .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } }" > %t.script |
| 9 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared | 9 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared |
| 10 | # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s | 10 | # RUN: llvm-readelf -l %t | FileCheck %s |
| 11 | 11 | ||
| 12 | # There is not enough address space available for the header, so just start the PT_LOAD | 12 | # There is not enough address space available for the header, so just start the PT_LOAD |
| 13 | # after it. Don't create a PT_PHDR as the header is not allocated. | 13 | # after it. Don't create a PT_PHDR as the header is not allocated. |
| ... | @@ -18,7 +18,7 @@ | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | ||
| 19 | # CHECK: Section to Segment mapping: | 19 | # CHECK: Section to Segment mapping: |
| 20 | # CHECK-NEXT: Segment Sections... | 20 | # CHECK-NEXT: Segment Sections... |
| 21 | # CHECK-NEXT: 00 foo .text .dynsym .hash .dynstr | 21 | # CHECK-NEXT: 00 foo .dynsym .dynstr .hash |
| 22 | 22 | ||
| 23 | .section foo, "a" | 23 | .section foo, "a" |
| 24 | .quad 0 | 24 | .quad 0 |
deps/lld/test/ELF/linkerscript/noload.s+23-6| ... | @@ -2,12 +2,13 @@ | ... | @@ -2,12 +2,13 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | # RUN: echo "SECTIONS { \ | 3 | # RUN: echo "SECTIONS { \ |
| 4 | # RUN: .data_noload_a (NOLOAD) : { *(.data_noload_a) } \ | 4 | # RUN: .data_noload_a (NOLOAD) : { *(.data_noload_a) } \ |
| 5 | # RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } };" > %t.script | 5 | # RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } \ |
| 6 | # RUN: .text (0x20000) : { *(.text) } };" > %t.script | ||
| 6 | # RUN: ld.lld -o %t --script %t.script %t.o | 7 | # RUN: ld.lld -o %t --script %t.script %t.o |
| 7 | # RUN: llvm-readobj --symbols -sections %t | FileCheck %s | 8 | # RUN: llvm-readobj -sections -program-headers %t | FileCheck %s |
| 8 | 9 | ||
| 9 | # CHECK: Section { | 10 | # CHECK: Section { |
| 10 | # CHECK: Index: 2 | 11 | # CHECK: Index: 1 |
| 11 | # CHECK-NEXT: Name: .data_noload_a | 12 | # CHECK-NEXT: Name: .data_noload_a |
| 12 | # CHECK-NEXT: Type: SHT_NOBITS | 13 | # CHECK-NEXT: Type: SHT_NOBITS |
| 13 | # CHECK-NEXT: Flags [ | 14 | # CHECK-NEXT: Flags [ |
| ... | @@ -15,7 +16,7 @@ | ... | @@ -15,7 +16,7 @@ |
| 15 | # CHECK-NEXT: SHF_WRITE | 16 | # CHECK-NEXT: SHF_WRITE |
| 16 | # CHECK-NEXT: ] | 17 | # CHECK-NEXT: ] |
| 17 | # CHECK-NEXT: Address: 0x0 | 18 | # CHECK-NEXT: Address: 0x0 |
| 18 | # CHECK-NEXT: Offset: 0x1000 | 19 | # CHECK-NEXT: Offset: 0xE8 |
| 19 | # CHECK-NEXT: Size: 4096 | 20 | # CHECK-NEXT: Size: 4096 |
| 20 | # CHECK-NEXT: Link: 0 | 21 | # CHECK-NEXT: Link: 0 |
| 21 | # CHECK-NEXT: Info: 0 | 22 | # CHECK-NEXT: Info: 0 |
| ... | @@ -23,7 +24,7 @@ | ... | @@ -23,7 +24,7 @@ |
| 23 | # CHECK-NEXT: EntrySize: 0 | 24 | # CHECK-NEXT: EntrySize: 0 |
| 24 | # CHECK-NEXT: } | 25 | # CHECK-NEXT: } |
| 25 | # CHECK-NEXT: Section { | 26 | # CHECK-NEXT: Section { |
| 26 | # CHECK-NEXT: Index: 3 | 27 | # CHECK-NEXT: Index: 2 |
| 27 | # CHECK-NEXT: Name: .data_noload_b | 28 | # CHECK-NEXT: Name: .data_noload_b |
| 28 | # CHECK-NEXT: Type: SHT_NOBITS | 29 | # CHECK-NEXT: Type: SHT_NOBITS |
| 29 | # CHECK-NEXT: Flags [ | 30 | # CHECK-NEXT: Flags [ |
| ... | @@ -31,13 +32,29 @@ | ... | @@ -31,13 +32,29 @@ |
| 31 | # CHECK-NEXT: SHF_WRITE | 32 | # CHECK-NEXT: SHF_WRITE |
| 32 | # CHECK-NEXT: ] | 33 | # CHECK-NEXT: ] |
| 33 | # CHECK-NEXT: Address: 0x10000 | 34 | # CHECK-NEXT: Address: 0x10000 |
| 34 | # CHECK-NEXT: Offset: 0x1000 | 35 | # CHECK-NEXT: Offset: 0xE8 |
| 35 | # CHECK-NEXT: Size: 4096 | 36 | # CHECK-NEXT: Size: 4096 |
| 36 | # CHECK-NEXT: Link: 0 | 37 | # CHECK-NEXT: Link: 0 |
| 37 | # CHECK-NEXT: Info: 0 | 38 | # CHECK-NEXT: Info: 0 |
| 38 | # CHECK-NEXT: AddressAlignment: 1 | 39 | # CHECK-NEXT: AddressAlignment: 1 |
| 39 | # CHECK-NEXT: EntrySize: 0 | 40 | # CHECK-NEXT: EntrySize: 0 |
| 40 | # CHECK-NEXT: } | 41 | # CHECK-NEXT: } |
| 42 | # CHECK: ProgramHeader { | ||
| 43 | # CHECK-NEXT: Type: PT_LOAD (0x1) | ||
| 44 | # CHECK-NEXT: Offset: 0x1000 | ||
| 45 | # CHECK-NEXT: VirtualAddress: 0x20000 | ||
| 46 | # CHECK-NEXT: PhysicalAddress: 0x20000 | ||
| 47 | # CHECK-NEXT: FileSize: 1 | ||
| 48 | # CHECK-NEXT: MemSize: 1 | ||
| 49 | # CHECK-NEXT: Flags [ (0x5) | ||
| 50 | # CHECK-NEXT: PF_R (0x4) | ||
| 51 | # CHECK-NEXT: PF_X (0x1) | ||
| 52 | # CHECK-NEXT: ] | ||
| 53 | # CHECK-NEXT: Alignment: 4096 | ||
| 54 | # CHECK-NEXT: } | ||
| 55 | |||
| 56 | .section .text,"ax",@progbits | ||
| 57 | nop | ||
| 41 | 58 | ||
| 42 | .section .data_noload_a,"aw",@progbits | 59 | .section .data_noload_a,"aw",@progbits |
| 43 | .zero 4096 | 60 | .zero 4096 |
deps/lld/test/ELF/linkerscript/non-absolute.s+4-2| ... | @@ -5,9 +5,11 @@ | ... | @@ -5,9 +5,11 @@ |
| 5 | # RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DUMP | 5 | # 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 -t %t | FileCheck %s --check-prefix=SYMBOL |
| 7 | 7 | ||
| 8 | # B = A + 0x1 = -0x10 + 0x1 = -0xf -> 0xFFFFFFFFFFFFFFF1 | ||
| 9 | # B - (0x94+6) = -0xf - (0x94+6) = -169 | ||
| 8 | # DUMP: Disassembly of section .text: | 10 | # DUMP: Disassembly of section .text: |
| 9 | # DUMP-NEXT: foo: | 11 | # DUMP-NEXT: foo: |
| 10 | # DUMP-NEXT: 0: {{.*}} -21(%rip), %eax | 12 | # DUMP-NEXT: 94: {{.*}} -169(%rip), %eax |
| 11 | 13 | ||
| 12 | # SYMBOL: Symbol { | 14 | # SYMBOL: Symbol { |
| 13 | # SYMBOL: Name: B | 15 | # SYMBOL: Name: B |
| ... | @@ -18,7 +20,7 @@ | ... | @@ -18,7 +20,7 @@ |
| 18 | # SYMBOL-NEXT: Other [ | 20 | # SYMBOL-NEXT: Other [ |
| 19 | # SYMBOL-NEXT: STV_HIDDEN | 21 | # SYMBOL-NEXT: STV_HIDDEN |
| 20 | # SYMBOL-NEXT: ] | 22 | # SYMBOL-NEXT: ] |
| 21 | # SYMBOL-NEXT: Section: .text | 23 | # SYMBOL-NEXT: Section: .dynsym |
| 22 | # SYMBOL-NEXT: } | 24 | # SYMBOL-NEXT: } |
| 23 | 25 | ||
| 24 | .text | 26 | .text |
deps/lld/test/ELF/linkerscript/non-absolute2.s deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | ||
| 3 | # RUN: echo "SECTIONS { A = . + 0x1; . += 0x1000; }" > %t.script | ||
| 4 | # RUN: ld.lld -shared %t1.o --script %t.script -o %t | ||
| 5 | # RUN: llvm-objdump -section-headers -t %t | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: Sections: | ||
| 8 | # CHECK-NEXT: Idx Name Size Address | ||
| 9 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 10 | # CHECK-NEXT: 1 .text 00000000 0000000000001000 | ||
| 11 | |||
| 12 | # CHECK: 0000000000000001 .text 00000000 A | ||
deps/lld/test/ELF/linkerscript/non-absolute2.test created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t1.o | ||
| 3 | # RUN: ld.lld -shared %t1.o --script %s -o %t | ||
| 4 | # RUN: llvm-objdump -section-headers -t %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | A = . + 0x1; | ||
| 8 | . += 0x1000; | ||
| 9 | } | ||
| 10 | |||
| 11 | # CHECK: Sections: | ||
| 12 | # CHECK-NEXT: Idx Name Size Address | ||
| 13 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 14 | # CHECK-NEXT: 1 .dynsym 00000030 0000000000001000 | ||
| 15 | # CHECK: 5 .text 00000000 000000000000106c | ||
| 16 | |||
| 17 | # CHECK: 0000000000000001 .dynsym 00000000 A | ||
deps/lld/test/ELF/linkerscript/non-alloc-segment.s+1-1| ... | @@ -16,7 +16,7 @@ | ... | @@ -16,7 +16,7 @@ |
| 16 | # RUN: .foo : {*(.foo)} :foo \ | 16 | # RUN: .foo : {*(.foo)} :foo \ |
| 17 | # RUN: }" > %t.script | 17 | # RUN: }" > %t.script |
| 18 | # RUN: ld.lld -o %t --script %t.script %t.o | 18 | # RUN: ld.lld -o %t --script %t.script %t.o |
| 19 | # RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s | 19 | # RUN: llvm-readelf -s -l %t | FileCheck %s |
| 20 | # RUN: llvm-readobj -l %t | FileCheck --check-prefix=PHDR %s | 20 | # RUN: llvm-readobj -l %t | FileCheck --check-prefix=PHDR %s |
| 21 | 21 | ||
| 22 | # CHECK: Program Headers: | 22 | # CHECK: Program Headers: |
deps/lld/test/ELF/linkerscript/non-alloc.s+4-4| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | ||
| 4 | # RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script | 4 | # RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script |
| 5 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared | 5 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared |
| 6 | # RUN: llvm-readobj -elf-output-style=GNU -s -l %t1 | FileCheck %s | 6 | # RUN: llvm-readelf -s -l %t | FileCheck %s |
| 7 | 7 | ||
| 8 | # Test that we create all necessary PT_LOAD. We use to stop at the first | 8 | # Test that we create all necessary PT_LOAD. We use to stop at the first |
| 9 | # non-alloc, causing us to not create PT_LOAD for linker generated sections. | 9 | # non-alloc, causing us to not create PT_LOAD for linker generated sections. |
| ... | @@ -15,7 +15,7 @@ | ... | @@ -15,7 +15,7 @@ |
| 15 | 15 | ||
| 16 | # CHECK: Section to Segment mapping: | 16 | # CHECK: Section to Segment mapping: |
| 17 | # CHECK-NEXT: Segment Sections... | 17 | # CHECK-NEXT: Segment Sections... |
| 18 | # CHECK-NEXT: 00 .text .dynsym .hash .dynstr | 18 | # CHECK-NEXT: 00 .dynsym .hash .dynstr .text |
| 19 | # CHECK-NEXT: 01 .dynamic | 19 | # CHECK-NEXT: 01 .dynamic |
| 20 | 20 | ||
| 21 | nop | 21 | nop |
deps/lld/test/ELF/linkerscript/numbers.s+19-4| ... | @@ -29,12 +29,12 @@ | ... | @@ -29,12 +29,12 @@ |
| 29 | 29 | ||
| 30 | ## Mailformed number errors. | 30 | ## Mailformed number errors. |
| 31 | # RUN: echo "SECTIONS { . = 0x11h; }" > %t2.script | 31 | # RUN: echo "SECTIONS { . = 0x11h; }" > %t2.script |
| 32 | # RUN: not ld.lld %t --script %t2.script -o %t3 2>&1 | \ | 32 | # RUN: not ld.lld %t --script %t2.script -o /dev/null 2>&1 | \ |
| 33 | # RUN: FileCheck --check-prefix=ERR1 %s | 33 | # RUN: FileCheck --check-prefix=ERR1 %s |
| 34 | # ERR1: malformed number: 0x11h | 34 | # ERR1: malformed number: 0x11h |
| 35 | 35 | ||
| 36 | # RUN: echo "SECTIONS { . = 0x11k; }" > %t3.script | 36 | # RUN: echo "SECTIONS { . = 0x11k; }" > %t3.script |
| 37 | # RUN: not ld.lld %t --script %t3.script -o %t4 2>&1 | \ | 37 | # RUN: not ld.lld %t --script %t3.script -o /dev/null 2>&1 | \ |
| 38 | # RUN: FileCheck --check-prefix=ERR2 %s | 38 | # RUN: FileCheck --check-prefix=ERR2 %s |
| 39 | # ERR2: malformed number: 0x11k | 39 | # ERR2: malformed number: 0x11k |
| 40 | 40 | ||
| ... | @@ -43,13 +43,28 @@ | ... | @@ -43,13 +43,28 @@ |
| 43 | # RUN: FileCheck --check-prefix=ERR3 %s | 43 | # RUN: FileCheck --check-prefix=ERR3 %s |
| 44 | # ERR3: malformed number: 0x11m | 44 | # ERR3: malformed number: 0x11m |
| 45 | 45 | ||
| 46 | # RUN: echo "SECTIONS { . = 1zh; }" > %t5.script | ||
| 47 | # RUN: not ld.lld %t --script %t5.script -o %t5 2>&1 | \ | ||
| 48 | # RUN: FileCheck --check-prefix=ERR4 %s | ||
| 49 | # ERR4: malformed number: 1zh | ||
| 50 | |||
| 51 | # RUN: echo "SECTIONS { . = 1zk; }" > %t6.script | ||
| 52 | # RUN: not ld.lld %t --script %t6.script -o %t6 2>&1 | \ | ||
| 53 | # RUN: FileCheck --check-prefix=ERR5 %s | ||
| 54 | # ERR5: malformed number: 1zk | ||
| 55 | |||
| 56 | # RUN: echo "SECTIONS { . = 1zm; }" > %t7.script | ||
| 57 | # RUN: not ld.lld %t --script %t7.script -o /dev/null 2>&1 | \ | ||
| 58 | # RUN: FileCheck --check-prefix=ERR6 %s | ||
| 59 | # ERR6: malformed number: 1zm | ||
| 60 | |||
| 46 | ## Make sure that numbers can be followed by a ":" with and without a space, | 61 | ## Make sure that numbers can be followed by a ":" with and without a space, |
| 47 | ## e.g. "0x100 :" or "0x100:" | 62 | ## e.g. "0x100 :" or "0x100:" |
| 48 | # RUN: echo "SECTIONS { \ | 63 | # RUN: echo "SECTIONS { \ |
| 49 | # RUN: .hex1 0x400 : { *(.hex.1) } \ | 64 | # RUN: .hex1 0x400 : { *(.hex.1) } \ |
| 50 | # RUN: .hex2 0x500:{ *(.hex.2) } \ | 65 | # RUN: .hex2 0x500:{ *(.hex.2) } \ |
| 51 | # RUN: }" > %t5.script | 66 | # RUN: }" > %t8.script |
| 52 | # RUN: ld.lld %t --script %t5.script -o %t6 | 67 | # RUN: ld.lld %t --script %t8.script -o %t6 |
| 53 | # RUN: llvm-objdump -section-headers %t6 | FileCheck -check-prefix=SECADDR %s | 68 | # RUN: llvm-objdump -section-headers %t6 | FileCheck -check-prefix=SECADDR %s |
| 54 | # SECADDR: Sections: | 69 | # SECADDR: Sections: |
| 55 | # SECADDR-NEXT: Idx Name Size Address | 70 | # SECADDR-NEXT: Idx Name Size Address |
deps/lld/test/ELF/linkerscript/openbsd-bootdata.s deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o | ||
| 2 | # RUN: echo "PHDRS { boot PT_OPENBSD_BOOTDATA; }" > %t.script | ||
| 3 | # RUN: ld.lld --script %t.script %t.o -o %t | ||
| 4 | # RUN: llvm-readobj --program-headers -s %t | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: ProgramHeader { | ||
| 7 | # CHECK: Type: PT_OPENBSD_BOOTDATA (0x65A41BE6) | ||
deps/lld/test/ELF/linkerscript/openbsd-bootdata.test created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld --script %s %t.o -o %t | ||
| 4 | # RUN: llvm-readobj --program-headers -s %t | FileCheck %s | ||
| 5 | |||
| 6 | PHDRS { boot PT_OPENBSD_BOOTDATA; } | ||
| 7 | |||
| 8 | # CHECK: ProgramHeader { | ||
| 9 | # CHECK: Type: PT_OPENBSD_BOOTDATA (0x65A41BE6) | ||
deps/lld/test/ELF/linkerscript/openbsd-randomize.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o |
| 2 | # RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; rand PT_OPENBSD_RANDOMIZE; } \ | 3 | # RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; rand PT_OPENBSD_RANDOMIZE; } \ |
| 3 | # RUN: SECTIONS { . = SIZEOF_HEADERS; \ | 4 | # RUN: SECTIONS { . = SIZEOF_HEADERS; \ |
deps/lld/test/ELF/linkerscript/openbsd-wxneeded.s deleted-17| ... | @@ -1,17 +0,0 @@ | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o | ||
| 2 | # RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; wxneeded PT_OPENBSD_WXNEEDED; }" > %t.script | ||
| 3 | # RUN: ld.lld -z wxneeded --script %t.script %t.o -o %t | ||
| 4 | # RUN: llvm-readobj --program-headers %t | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: ProgramHeader { | ||
| 7 | # CHECK: Type: PT_OPENBSD_WXNEEDED (0x65A3DBE7) | ||
| 8 | # CHECK-NEXT: Offset: 0x0 | ||
| 9 | # CHECK-NEXT: VirtualAddress: 0x0 | ||
| 10 | # CHECK-NEXT: PhysicalAddress: 0x0 | ||
| 11 | # CHECK-NEXT: FileSize: 0 | ||
| 12 | # CHECK-NEXT: MemSize: 0 | ||
| 13 | # CHECK-NEXT: Flags [ | ||
| 14 | # CHECK-NEXT: PF_R | ||
| 15 | # CHECK-NEXT: ] | ||
| 16 | # CHECK-NEXT: Alignment: 0 | ||
| 17 | # CHECK-NEXT: } | ||
deps/lld/test/ELF/linkerscript/openbsd-wxneeded.test created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld -z wxneeded --script %s %t.o -o %t | ||
| 4 | # RUN: llvm-readobj --program-headers %t | FileCheck %s | ||
| 5 | |||
| 6 | PHDRS { text PT_LOAD FILEHDR PHDRS; wxneeded PT_OPENBSD_WXNEEDED; } | ||
| 7 | |||
| 8 | # CHECK: ProgramHeader { | ||
| 9 | # CHECK: Type: PT_OPENBSD_WXNEEDED (0x65A3DBE7) | ||
| 10 | # CHECK-NEXT: Offset: 0x0 | ||
| 11 | # CHECK-NEXT: VirtualAddress: 0x0 | ||
| 12 | # CHECK-NEXT: PhysicalAddress: 0x0 | ||
| 13 | # CHECK-NEXT: FileSize: 0 | ||
| 14 | # CHECK-NEXT: MemSize: 0 | ||
| 15 | # CHECK-NEXT: Flags [ | ||
| 16 | # CHECK-NEXT: PF_R | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | # CHECK-NEXT: Alignment: 0 | ||
| 19 | # CHECK-NEXT: } | ||
deps/lld/test/ELF/linkerscript/operators.s deleted-101| ... | @@ -1,101 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: _start = .; \ | ||
| 5 | # RUN: plus = 1 + 2 + 3; \ | ||
| 6 | # RUN: minus = 5 - 1; \ | ||
| 7 | # RUN: div = 6 / 2; \ | ||
| 8 | # RUN: mul = 1 + 2 * 3; \ | ||
| 9 | # RUN: nospace = 1+2*6/3; \ | ||
| 10 | # RUN: braces = 1 + (2 + 3) * 4; \ | ||
| 11 | # RUN: and = 0xbb & 0xee; \ | ||
| 12 | # RUN: ternary1 = 1 ? 1 : 2; \ | ||
| 13 | # RUN: ternary2 = 0 ? 1 : 2; \ | ||
| 14 | # RUN: less = 1 < 0 ? 1 : 2; \ | ||
| 15 | # RUN: lesseq = 1 <= 1 ? 1 : 2; \ | ||
| 16 | # RUN: greater = 0 > 1 ? 1 : 2; \ | ||
| 17 | # RUN: greatereq = 1 >= 1 ? 1 : 2; \ | ||
| 18 | # RUN: eq = 1 == 1 ? 1 : 2; \ | ||
| 19 | # RUN: neq = 1 != 1 ? 1 : 2; \ | ||
| 20 | # RUN: plusassign = 1; \ | ||
| 21 | # RUN: plusassign += 2; \ | ||
| 22 | # RUN: unary = -1 + 3; \ | ||
| 23 | # RUN: lshift = 1 << 5; \ | ||
| 24 | # RUN: rshift = 0xff >> 3; \ | ||
| 25 | # RUN: maxpagesize = CONSTANT (MAXPAGESIZE); \ | ||
| 26 | # RUN: commonpagesize = CONSTANT (COMMONPAGESIZE); \ | ||
| 27 | # RUN: . = 0xfff0; \ | ||
| 28 | # RUN: datasegmentalign = DATA_SEGMENT_ALIGN (0xffff, 0); \ | ||
| 29 | # RUN: datasegmentalign2 = DATA_SEGMENT_ALIGN (0, 0); \ | ||
| 30 | # RUN: _end = .; \ | ||
| 31 | # RUN: minus_rel = _end - 0x10; \ | ||
| 32 | # RUN: minus_abs = _end - _start; \ | ||
| 33 | # RUN: }" > %t.script | ||
| 34 | # RUN: ld.lld %t --script %t.script -o %t2 | ||
| 35 | # RUN: llvm-objdump -t %t2 | FileCheck %s | ||
| 36 | |||
| 37 | # CHECK: 00000000000006 *ABS* 00000000 plus | ||
| 38 | # CHECK: 00000000000004 *ABS* 00000000 minus | ||
| 39 | # CHECK: 00000000000003 *ABS* 00000000 div | ||
| 40 | # CHECK: 00000000000007 *ABS* 00000000 mul | ||
| 41 | # CHECK: 00000000000005 *ABS* 00000000 nospace | ||
| 42 | # CHECK: 00000000000015 *ABS* 00000000 braces | ||
| 43 | # CHECK: 000000000000aa *ABS* 00000000 and | ||
| 44 | # CHECK: 00000000000001 *ABS* 00000000 ternary1 | ||
| 45 | # CHECK: 00000000000002 *ABS* 00000000 ternary2 | ||
| 46 | # CHECK: 00000000000002 *ABS* 00000000 less | ||
| 47 | # CHECK: 00000000000001 *ABS* 00000000 lesseq | ||
| 48 | # CHECK: 00000000000002 *ABS* 00000000 greater | ||
| 49 | # CHECK: 00000000000001 *ABS* 00000000 greatereq | ||
| 50 | # CHECK: 00000000000001 *ABS* 00000000 eq | ||
| 51 | # CHECK: 00000000000002 *ABS* 00000000 neq | ||
| 52 | # CHECK: 00000000000003 *ABS* 00000000 plusassign | ||
| 53 | # CHECK: 00000000000002 *ABS* 00000000 unary | ||
| 54 | # CHECK: 00000000000020 *ABS* 00000000 lshift | ||
| 55 | # CHECK: 0000000000001f *ABS* 00000000 rshift | ||
| 56 | # CHECK: 00000000001000 *ABS* 00000000 maxpagesize | ||
| 57 | # CHECK: 00000000001000 *ABS* 00000000 commonpagesize | ||
| 58 | # CHECK: 0000000000ffff *ABS* 00000000 datasegmentalign | ||
| 59 | # CHECK: 0000000000fff0 *ABS* 00000000 datasegmentalign2 | ||
| 60 | # CHECK: 0000000000ffe0 .text 00000000 minus_rel | ||
| 61 | # CHECK: 0000000000fff0 *ABS* 00000000 minus_abs | ||
| 62 | |||
| 63 | ## Mailformed number error. | ||
| 64 | # RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script | ||
| 65 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 66 | # RUN: FileCheck --check-prefix=NUMERR %s | ||
| 67 | # NUMERR: malformed number: 0x12Q41 | ||
| 68 | |||
| 69 | ## Missing closing bracket. | ||
| 70 | # RUN: echo "SECTIONS { . = (1; }" > %t.script | ||
| 71 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 72 | # RUN: FileCheck --check-prefix=BRACKETERR %s | ||
| 73 | # BRACKETERR: ) expected, but got ; | ||
| 74 | |||
| 75 | ## Missing opening bracket. | ||
| 76 | # RUN: echo "SECTIONS { . = 1); }" > %t.script | ||
| 77 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 78 | # RUN: FileCheck --check-prefix=BRACKETERR2 %s | ||
| 79 | # BRACKETERR2: ; expected, but got ) | ||
| 80 | |||
| 81 | ## Empty expression. | ||
| 82 | # RUN: echo "SECTIONS { . = ; }" > %t.script | ||
| 83 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 84 | # RUN: FileCheck --check-prefix=ERREXPR %s | ||
| 85 | # ERREXPR: malformed number: ; | ||
| 86 | |||
| 87 | ## Div by zero error. | ||
| 88 | # RUN: echo "SECTIONS { . = 1 / 0; }" > %t.script | ||
| 89 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 90 | # RUN: FileCheck --check-prefix=DIVZERO %s | ||
| 91 | # DIVZERO: division by zero | ||
| 92 | |||
| 93 | ## Broken ternary operator expression. | ||
| 94 | # RUN: echo "SECTIONS { . = 1 ? 2; }" > %t.script | ||
| 95 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 96 | # RUN: FileCheck --check-prefix=TERNERR %s | ||
| 97 | # TERNERR: : expected, but got ; | ||
| 98 | |||
| 99 | .globl _start | ||
| 100 | _start: | ||
| 101 | nop | ||
deps/lld/test/ELF/linkerscript/operators.test created+130| ... | @@ -0,0 +1,130 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t | ||
| 3 | # RUN: ld.lld %t --script %s -o %t2 | ||
| 4 | # RUN: llvm-objdump -t %t2 | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | _start = .; | ||
| 8 | plus = 1 + 2 + 3; | ||
| 9 | minus = 5 - 1; | ||
| 10 | div = 6 / 2; | ||
| 11 | mod = 20 % 7; | ||
| 12 | mul = 1 + 2 * 3; | ||
| 13 | nospace = 1+2*6/3; | ||
| 14 | braces = 1 + (2 + 3) * 4; | ||
| 15 | and = 0xbb & 0xee; | ||
| 16 | ternary1 = 1 ? 1 : 2; | ||
| 17 | ternary2 = 0 ? 1 : 2; | ||
| 18 | less = 1 < 0 ? 1 : 2; | ||
| 19 | lesseq = 1 <= 1 ? 1 : 2; | ||
| 20 | greater = 0 > 1 ? 1 : 2; | ||
| 21 | greatereq = 1 >= 1 ? 1 : 2; | ||
| 22 | eq = 1 == 1 ? 1 : 2; | ||
| 23 | neq = 1 != 1 ? 1 : 2; | ||
| 24 | plusassign = 1; | ||
| 25 | plusassign += 2; | ||
| 26 | unary = -1 + 3; | ||
| 27 | lshift = 1 << 5; | ||
| 28 | rshift = 0xff >> 3; | ||
| 29 | precedence1 = 1 | 0xff & 1 << 1 + 1 * 2; | ||
| 30 | precedence2 = (1 | (0xff & (1 << (1 + (1 * 2))))); | ||
| 31 | maxpagesize = CONSTANT (MAXPAGESIZE); | ||
| 32 | commonpagesize = CONSTANT (COMMONPAGESIZE); | ||
| 33 | . = 0xfff0; | ||
| 34 | datasegmentalign = DATA_SEGMENT_ALIGN (0xffff, 0); | ||
| 35 | datasegmentalign2 = DATA_SEGMENT_ALIGN (0, 0); | ||
| 36 | _end = .; | ||
| 37 | minus_rel = _end - 0x10; | ||
| 38 | minus_abs = _end - _start; | ||
| 39 | max = MAX(11, 22); | ||
| 40 | min = MIN(11, 22); | ||
| 41 | logicaland1 = 0 && 0; | ||
| 42 | logicaland2 = 0 && 1; | ||
| 43 | logicaland3 = 1 && 0; | ||
| 44 | logicaland4 = 1 && 1; | ||
| 45 | logicalor1 = 0 || 0; | ||
| 46 | logicalor2 = 0 || 1; | ||
| 47 | logicalor3 = 1 || 0; | ||
| 48 | logicalor4 = 1 || 1; | ||
| 49 | } | ||
| 50 | |||
| 51 | # CHECK: 00000000000006 *ABS* 00000000 plus | ||
| 52 | # CHECK: 00000000000004 *ABS* 00000000 minus | ||
| 53 | # CHECK: 00000000000003 *ABS* 00000000 div | ||
| 54 | # CHECK: 00000000000006 *ABS* 00000000 mod | ||
| 55 | # CHECK: 00000000000007 *ABS* 00000000 mul | ||
| 56 | # CHECK: 00000000000005 *ABS* 00000000 nospace | ||
| 57 | # CHECK: 00000000000015 *ABS* 00000000 braces | ||
| 58 | # CHECK: 000000000000aa *ABS* 00000000 and | ||
| 59 | # CHECK: 00000000000001 *ABS* 00000000 ternary1 | ||
| 60 | # CHECK: 00000000000002 *ABS* 00000000 ternary2 | ||
| 61 | # CHECK: 00000000000002 *ABS* 00000000 less | ||
| 62 | # CHECK: 00000000000001 *ABS* 00000000 lesseq | ||
| 63 | # CHECK: 00000000000002 *ABS* 00000000 greater | ||
| 64 | # CHECK: 00000000000001 *ABS* 00000000 greatereq | ||
| 65 | # CHECK: 00000000000001 *ABS* 00000000 eq | ||
| 66 | # CHECK: 00000000000002 *ABS* 00000000 neq | ||
| 67 | # CHECK: 00000000000003 *ABS* 00000000 plusassign | ||
| 68 | # CHECK: 00000000000002 *ABS* 00000000 unary | ||
| 69 | # CHECK: 00000000000020 *ABS* 00000000 lshift | ||
| 70 | # CHECK: 0000000000001f *ABS* 00000000 rshift | ||
| 71 | # CHECK: 00000000000009 *ABS* 00000000 precedence1 | ||
| 72 | # CHECK: 00000000000009 *ABS* 00000000 precedence2 | ||
| 73 | # CHECK: 00000000001000 *ABS* 00000000 maxpagesize | ||
| 74 | # CHECK: 00000000001000 *ABS* 00000000 commonpagesize | ||
| 75 | # CHECK: 0000000000ffff *ABS* 00000000 datasegmentalign | ||
| 76 | # CHECK: 0000000000fff0 *ABS* 00000000 datasegmentalign2 | ||
| 77 | # CHECK: 0000000000ffe0 .text 00000000 minus_rel | ||
| 78 | # CHECK: 0000000000fff0 *ABS* 00000000 minus_abs | ||
| 79 | # CHECK: 00000000000016 *ABS* 00000000 max | ||
| 80 | # CHECK: 0000000000000b *ABS* 00000000 min | ||
| 81 | # CHECK: 00000000000000 *ABS* 00000000 logicaland1 | ||
| 82 | # CHECK: 00000000000000 *ABS* 00000000 logicaland2 | ||
| 83 | # CHECK: 00000000000000 *ABS* 00000000 logicaland3 | ||
| 84 | # CHECK: 00000000000001 *ABS* 00000000 logicaland4 | ||
| 85 | # CHECK: 00000000000000 *ABS* 00000000 logicalor1 | ||
| 86 | # CHECK: 00000000000001 *ABS* 00000000 logicalor2 | ||
| 87 | # CHECK: 00000000000001 *ABS* 00000000 logicalor3 | ||
| 88 | # CHECK: 00000000000001 *ABS* 00000000 logicalor4 | ||
| 89 | |||
| 90 | ## Mailformed number error. | ||
| 91 | # RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script | ||
| 92 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 93 | # RUN: FileCheck --check-prefix=NUMERR %s | ||
| 94 | # NUMERR: malformed number: 0x12Q41 | ||
| 95 | |||
| 96 | ## Missing closing bracket. | ||
| 97 | # RUN: echo "SECTIONS { . = (1; }" > %t.script | ||
| 98 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 99 | # RUN: FileCheck --check-prefix=BRACKETERR %s | ||
| 100 | # BRACKETERR: ) expected, but got ; | ||
| 101 | |||
| 102 | ## Missing opening bracket. | ||
| 103 | # RUN: echo "SECTIONS { . = 1); }" > %t.script | ||
| 104 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 105 | # RUN: FileCheck --check-prefix=BRACKETERR2 %s | ||
| 106 | # BRACKETERR2: ; expected, but got ) | ||
| 107 | |||
| 108 | ## Empty expression. | ||
| 109 | # RUN: echo "SECTIONS { . = ; }" > %t.script | ||
| 110 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 111 | # RUN: FileCheck --check-prefix=ERREXPR %s | ||
| 112 | # ERREXPR: malformed number: ; | ||
| 113 | |||
| 114 | ## Div by zero error. | ||
| 115 | # RUN: echo "SECTIONS { . = 1 / 0; }" > %t.script | ||
| 116 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 117 | # RUN: FileCheck --check-prefix=DIVZERO %s | ||
| 118 | # DIVZERO: {{.*}}.script:1: division by zero | ||
| 119 | |||
| 120 | ## Mod by zero error. | ||
| 121 | # RUN: echo "SECTIONS { . = 1 % 0; }" > %t.script | ||
| 122 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 123 | # RUN: FileCheck --check-prefix=MODZERO %s | ||
| 124 | # MODZERO: {{.*}}.script:1: modulo by zero | ||
| 125 | |||
| 126 | ## Broken ternary operator expression. | ||
| 127 | # RUN: echo "SECTIONS { . = 1 ? 2; }" > %t.script | ||
| 128 | # RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ | ||
| 129 | # RUN: FileCheck --check-prefix=TERNERR %s | ||
| 130 | # TERNERR: : expected, but got ; | ||
deps/lld/test/ELF/linkerscript/orphan-first-cmd.s deleted-20| ... | @@ -1,20 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: foo = 123; \ | ||
| 5 | # RUN: . = 0x1000; \ | ||
| 6 | # RUN: . = 0x2000; \ | ||
| 7 | # RUN: .bar : { *(.bar) } \ | ||
| 8 | # RUN: }" > %t.script | ||
| 9 | # RUN: ld.lld -o %t -T %t.script %t.o -shared | ||
| 10 | # RUN: llvm-readobj -s %t | FileCheck %s | ||
| 11 | |||
| 12 | # CHECK: Name: .text | ||
| 13 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 14 | # CHECK-NEXT: Flags [ | ||
| 15 | # CHECK-NEXT: SHF_ALLOC | ||
| 16 | # CHECK-NEXT: SHF_EXECINSTR | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | # CHECK-NEXT: Address: 0x1000 | ||
| 19 | |||
| 20 | .section .bar, "aw" | ||
deps/lld/test/ELF/linkerscript/orphan-first-cmd.test created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .bar, "aw"' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | # RUN: ld.lld -o %t -T %s %t.o -shared | ||
| 5 | # RUN: llvm-readobj -s %t | FileCheck %s | ||
| 6 | |||
| 7 | SECTIONS { | ||
| 8 | foo = 123; | ||
| 9 | . = 0x1000; | ||
| 10 | . = 0x2000; | ||
| 11 | .bar : { *(.bar) } | ||
| 12 | } | ||
| 13 | |||
| 14 | # CHECK: Name: .text | ||
| 15 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 16 | # CHECK-NEXT: Flags [ | ||
| 17 | # CHECK-NEXT: SHF_ALLOC | ||
| 18 | # CHECK-NEXT: SHF_EXECINSTR | ||
| 19 | # CHECK-NEXT: ] | ||
| 20 | # CHECK-NEXT: Address: 0x1070 | ||
deps/lld/test/ELF/linkerscript/orphan-phdrs.s+2-1| ... | @@ -10,7 +10,7 @@ | ... | @@ -10,7 +10,7 @@ |
| 10 | # RUN: .rw : { *(.rw) } \ | 10 | # RUN: .rw : { *(.rw) } \ |
| 11 | # RUN: }" > %t.script | 11 | # RUN: }" > %t.script |
| 12 | # RUN: ld.lld -o %t --script %t.script %t.o | 12 | # RUN: ld.lld -o %t --script %t.script %t.o |
| 13 | # RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s | 13 | # RUN: llvm-readelf -s -l %t | FileCheck %s |
| 14 | 14 | ||
| 15 | ## Check that the orphan section is placed correctly and belongs to | 15 | ## Check that the orphan section is placed correctly and belongs to |
| 16 | ## the correct segment. | 16 | ## the correct segment. |
| ... | @@ -18,6 +18,7 @@ | ... | @@ -18,6 +18,7 @@ |
| 18 | # CHECK: Section Headers | 18 | # CHECK: Section Headers |
| 19 | # CHECK: .text | 19 | # CHECK: .text |
| 20 | # CHECK-NEXT: .orphan | 20 | # CHECK-NEXT: .orphan |
| 21 | # CHECK-NEXT: .empty | ||
| 21 | # CHECK-NEXT: .rw | 22 | # CHECK-NEXT: .rw |
| 22 | 23 | ||
| 23 | # CHECK: Segment Sections | 24 | # CHECK: Segment Sections |
deps/lld/test/ELF/linkerscript/orphan-report.s+1| ... | @@ -36,6 +36,7 @@ | ... | @@ -36,6 +36,7 @@ |
| 36 | # REPORT-NEXT: <internal>:(.plt) is being placed in '.plt' | 36 | # REPORT-NEXT: <internal>:(.plt) is being placed in '.plt' |
| 37 | # REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame' | 37 | # REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame' |
| 38 | # REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab' | 38 | # 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>:(.shstrtab) is being placed in '.shstrtab' | 40 | # REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab' |
| 40 | # REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab' | 41 | # REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab' |
| 41 | 42 |
deps/lld/test/ELF/linkerscript/orphan.s+1-1| ... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
| 13 | ## .bss is SHT_NOBITS section and should be last RW section, so some space | 13 | ## .bss is SHT_NOBITS section and should be last RW section, so some space |
| 14 | ## in ELF file could be saved. | 14 | ## in ELF file could be saved. |
| 15 | # CHECK: 0 00000000 0000000000000000 | 15 | # CHECK: 0 00000000 0000000000000000 |
| 16 | # CHECK-NEXT: 1 .text 00000000 0000000000000000 TEXT DATA | 16 | # CHECK-NEXT: 1 .text 00000000 0000000000000000 TEXT |
| 17 | # CHECK-NEXT: 2 .rw1 00000008 0000000000000000 DATA | 17 | # CHECK-NEXT: 2 .rw1 00000008 0000000000000000 DATA |
| 18 | # CHECK-NEXT: 3 .rw2 00000008 0000000000000008 DATA | 18 | # CHECK-NEXT: 3 .rw2 00000008 0000000000000008 DATA |
| 19 | # CHECK-NEXT: 4 .rw3 00000008 0000000000000010 DATA | 19 | # CHECK-NEXT: 4 .rw3 00000008 0000000000000010 DATA |
deps/lld/test/ELF/linkerscript/out-of-order.s+24-6| ... | @@ -1,19 +1,37 @@ | ... | @@ -1,19 +1,37 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-linux %s -o %t.o |
| 3 | # RUN: echo "SECTIONS { .data 0x4000 : { *(.data) } .text 0x2000 : { *(.text) } }" > %t.script | 3 | # RUN: echo "SECTIONS { .data 0x4000 : {*(.data)} .dynsym 0x2000 : {*(.dynsym)} .dynstr : {*(.dynstr)} }" > %t.script |
| 4 | # RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared | 4 | # RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared |
| 5 | # RUN: llvm-objdump -section-headers %t.so | FileCheck %s | 5 | # RUN: llvm-objdump -section-headers %t.so | FileCheck %s |
| 6 | 6 | ||
| 7 | # Note: how the layout is done: | ||
| 8 | # we need to layout 2 segments, each contains sections: | ||
| 9 | # seg1: .data .dynamic | ||
| 10 | # seg2: .dynsym .dynstr .text .hash | ||
| 11 | # for each segment, we start from the first section, regardless | ||
| 12 | # whether it is an orphan or not (sections that are not listed in the | ||
| 13 | # linkerscript are orphans): | ||
| 14 | # for seg1, we assign address: .data(0x4000), .dynamic(0x4008) | ||
| 15 | # for seg2, we assign address: .dynsym(0x2000), .dynstr(0x2018) ... | ||
| 16 | # .dynsym is not an orphan, so we take address from script, we assign | ||
| 17 | # .dynstr current address cursor, which is the end # of .dynsym and so | ||
| 18 | # on for later sections. | ||
| 19 | |||
| 20 | # Also note, it is absolutely *illegal* to have section addresses of | ||
| 21 | # the same segment in none-increasing order, authors of linker scripts | ||
| 22 | # must take responsibility to make sure this does not happen. | ||
| 23 | |||
| 7 | # CHECK: Sections: | 24 | # CHECK: Sections: |
| 8 | # CHECK-NEXT: Idx Name Size Address Type | 25 | # CHECK-NEXT: Idx Name Size Address Type |
| 9 | # CHECK-NEXT: 0 00000000 0000000000000000 | 26 | # CHECK-NEXT: 0 00000000 0000000000000000 |
| 10 | # CHECK-NEXT: 1 .data 00000008 0000000000004000 DATA | 27 | # CHECK-NEXT: 1 .data 00000008 0000000000004000 |
| 11 | # CHECK-NEXT: 2 .dynamic 00000060 0000000000004008 | 28 | # CHECK-NEXT: 2 .dynamic 00000060 0000000000004008 |
| 12 | # CHECK-NEXT: 3 .text 00000008 0000000000002000 TEXT DATA | 29 | # CHECK-NEXT: 3 .dynsym 00000018 0000000000002000 |
| 13 | # CHECK-NEXT: 4 .dynsym 00000018 0000000000002008 | 30 | # CHECK-NEXT: 4 .dynstr 00000001 0000000000002018 |
| 14 | # CHECK-NEXT: 5 .hash 00000010 0000000000002020 | 31 | # CHECK-NEXT: 5 .hash 00000010 000000000000201c |
| 15 | # CHECK-NEXT: 6 .dynstr 00000001 0000000000002030 | 32 | # CHECK-NEXT: 6 .text 00000008 000000000000202c |
| 16 | 33 | ||
| 17 | .quad 0 | 34 | .quad 0 |
| 18 | .data | 35 | .data |
| 19 | .quad 0 | 36 | .quad 0 |
| 37 |
deps/lld/test/ELF/linkerscript/output-too-large.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o |
| 3 | # RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script | 3 | # RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script |
| 4 | # RUN: not ld.lld --script %t.script %t.o -o %t 2>&1 | FileCheck %s | 4 | # RUN: not ld.lld --no-check-sections --script %t.script %t.o -o /dev/null 2>&1 | FileCheck %s |
| 5 | # CHECK: error: output file too large | 5 | # CHECK: error: output file too large |
| 6 | 6 | ||
| 7 | .global _start | 7 | .global _start |
deps/lld/test/ELF/linkerscript/outputarch.s deleted-4| ... | @@ -1,4 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo "OUTPUT_ARCH(All data written here is ignored)" > %t.script | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1 | ||
| 4 | # RUN: ld.lld -shared -o %t2 %t1 %t.script | ||
deps/lld/test/ELF/linkerscript/outputarch.test created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd /dev/null -o %t1 | ||
| 3 | # RUN: ld.lld -shared -o %t2 %t1 %s | ||
| 4 | |||
| 5 | OUTPUT_ARCH(All data written here is ignored) | ||
deps/lld/test/ELF/linkerscript/overlapping-sections.s created+113| ... | @@ -0,0 +1,113 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { \ | ||
| 5 | # RUN: .sec1 0x8000 : AT(0x8000) { sec1_start = .; *(.first_sec) sec1_end = .;} \ | ||
| 6 | # RUN: .sec2 0x8800 : AT(0x8080) { sec2_start = .; *(.second_sec) sec2_end = .;} \ | ||
| 7 | # RUN: }" > %t-lma.script | ||
| 8 | # RUN: not ld.lld -o %t.so --script %t-lma.script %t.o -shared 2>&1 | FileCheck %s -check-prefix LMA-OVERLAP-ERR | ||
| 9 | # LMA-OVERLAP-ERR: error: section .sec1 load address range overlaps with .sec2 | ||
| 10 | # LMA-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000, 0x80FF] | ||
| 11 | # LMA-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8080, 0x817F] | ||
| 12 | |||
| 13 | # Check that we create the expected binary with --noinhibit-exec or --no-check-sections: | ||
| 14 | # RUN: ld.lld -o %t.so --script %t-lma.script %t.o -shared --noinhibit-exec | ||
| 15 | # RUN: ld.lld -o %t.so --script %t-lma.script %t.o -shared --no-check-sections -fatal-warnings | ||
| 16 | # RUN: ld.lld -o %t.so --script %t-lma.script %t.o -shared --check-sections --no-check-sections -fatal-warnings | ||
| 17 | |||
| 18 | # Verify that the .sec2 was indeed placed in a PT_LOAD where the PhysAddr | ||
| 19 | # 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 | ||
| 21 | # BAD-LMA-LABEL: Section Headers: | ||
| 22 | # BAD-LMA: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1 | ||
| 23 | # BAD-LMA: .sec2 PROGBITS 0000000000008800 002800 000100 00 WA 0 0 1 | ||
| 24 | # BAD-LMA-LABEL: Program Headers: | ||
| 25 | # BAD-LMA-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align | ||
| 26 | # BAD-LMA-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000 | ||
| 27 | # BAD-LMA-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW 0x1000 | ||
| 28 | # BAD-LMA-NEXT: LOAD 0x002800 0x0000000000008800 0x0000000000008080 0x000170 0x000170 RW 0x1000 | ||
| 29 | # BAD-LMA-LABEL: Section to Segment mapping: | ||
| 30 | # BAD-LMA: 01 .sec1 | ||
| 31 | # BAD-LMA: 02 .sec2 .dynamic | ||
| 32 | |||
| 33 | # Now try a script where the virtual memory addresses overlap but ensure that the | ||
| 34 | # load addresses don't: | ||
| 35 | # RUN: echo "SECTIONS { \ | ||
| 36 | # RUN: .sec1 0x8000 : AT(0x8000) { sec1_start = .; *(.first_sec) sec1_end = .;} \ | ||
| 37 | # RUN: .sec2 0x8020 : AT(0x8800) { sec2_start = .; *(.second_sec) sec2_end = .;} \ | ||
| 38 | # RUN: }" > %t-vaddr.script | ||
| 39 | # RUN: not ld.lld -o %t.so --script %t-vaddr.script %t.o -shared 2>&1 | FileCheck %s -check-prefix VADDR-OVERLAP-ERR | ||
| 40 | # VADDR-OVERLAP-ERR: error: section .sec1 virtual address range overlaps with .sec2 | ||
| 41 | # VADDR-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000, 0x80FF] | ||
| 42 | # VADDR-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8020, 0x811F] | ||
| 43 | |||
| 44 | # Check that the expected binary was created with --noinhibit-exec: | ||
| 45 | # 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 | ||
| 47 | # BAD-VADDR-LABEL: Section Headers: | ||
| 48 | # BAD-VADDR: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1 | ||
| 49 | # BAD-VADDR: .sec2 PROGBITS 0000000000008020 003020 000100 00 WA 0 0 1 | ||
| 50 | # BAD-VADDR-LABEL: Program Headers: | ||
| 51 | # BAD-VADDR-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align | ||
| 52 | # BAD-VADDR-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000 | ||
| 53 | # BAD-VADDR-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW 0x1000 | ||
| 54 | # BAD-VADDR-NEXT: LOAD 0x003020 0x0000000000008020 0x0000000000008800 0x000170 0x000170 RW 0x1000 | ||
| 55 | # BAD-VADDR-LABEL: Section to Segment mapping: | ||
| 56 | # BAD-VADDR: 01 .sec1 | ||
| 57 | # BAD-VADDR: 02 .sec2 .dynamic | ||
| 58 | |||
| 59 | # Finally check the case where both LMA and vaddr overlap | ||
| 60 | |||
| 61 | # RUN: echo "SECTIONS { \ | ||
| 62 | # RUN: .sec1 0x8000 : { sec1_start = .; *(.first_sec) sec1_end = .;} \ | ||
| 63 | # RUN: .sec2 0x8040 : { sec2_start = .; *(.second_sec) sec2_end = .;} \ | ||
| 64 | # RUN: }" > %t-both-overlap.script | ||
| 65 | |||
| 66 | # RUN: not ld.lld -o %t.so --script %t-both-overlap.script %t.o -shared 2>&1 | FileCheck %s -check-prefix BOTH-OVERLAP-ERR | ||
| 67 | |||
| 68 | # BOTH-OVERLAP-ERR: error: section .sec1 file range overlaps with .sec2 | ||
| 69 | # BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x2000, 0x20FF] | ||
| 70 | # BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x2040, 0x213F] | ||
| 71 | # BOTH-OVERLAP-ERR: error: section .sec1 virtual address range overlaps with .sec2 | ||
| 72 | # BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000, 0x80FF] | ||
| 73 | # BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8040, 0x813F] | ||
| 74 | # BOTH-OVERLAP-ERR: error: section .sec1 load address range overlaps with .sec2 | ||
| 75 | # BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000, 0x80FF] | ||
| 76 | # BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8040, 0x813F] | ||
| 77 | |||
| 78 | # RUN: ld.lld -o %t.so --script %t-both-overlap.script %t.o -shared --noinhibit-exec | ||
| 79 | # Note: In case everything overlaps we create a binary with overlapping file | ||
| 80 | # offsets. ld.bfd seems to place .sec1 to file offset 18000 and .sec2 | ||
| 81 | # at 18100 so that only virtual addr and LMA overlap | ||
| 82 | # However, in order to create such a broken binary the user has to ignore a | ||
| 83 | # fatal error by passing --noinhibit-exec, so this behaviour is fine. | ||
| 84 | |||
| 85 | # RUN: llvm-objdump -s %t.so | FileCheck %s -check-prefix BROKEN-OUTPUT-FILE | ||
| 86 | # BROKEN-OUTPUT-FILE-LABEL: Contents of section .sec1: | ||
| 87 | # BROKEN-OUTPUT-FILE-NEXT: 8000 01010101 01010101 01010101 01010101 | ||
| 88 | # BROKEN-OUTPUT-FILE-NEXT: 8010 01010101 01010101 01010101 01010101 | ||
| 89 | # BROKEN-OUTPUT-FILE-NEXT: 8020 01010101 01010101 01010101 01010101 | ||
| 90 | # BROKEN-OUTPUT-FILE-NEXT: 8030 01010101 01010101 01010101 01010101 | ||
| 91 | # Starting here the contents of .sec2 overwrites .sec1: | ||
| 92 | # BROKEN-OUTPUT-FILE-NEXT: 8040 02020202 02020202 02020202 02020202 | ||
| 93 | |||
| 94 | # RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-BOTH | ||
| 95 | # BAD-BOTH-LABEL: Section Headers: | ||
| 96 | # BAD-BOTH: .sec1 PROGBITS 0000000000008000 002000 000100 00 WA 0 0 1 | ||
| 97 | # BAD-BOTH: .sec2 PROGBITS 0000000000008040 002040 000100 00 WA 0 0 1 | ||
| 98 | # BAD-BOTH-LABEL: Program Headers: | ||
| 99 | # BAD-BOTH-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align | ||
| 100 | # BAD-BOTH-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000100 0x000100 R E 0x1000 | ||
| 101 | # BAD-BOTH-NEXT: LOAD 0x002000 0x0000000000008000 0x0000000000008000 0x0001b0 0x0001b0 RW 0x1000 | ||
| 102 | # BAD-BOTH-LABEL: Section to Segment mapping: | ||
| 103 | # BAD-BOTH: 01 .sec1 .sec2 .dynamic | ||
| 104 | |||
| 105 | .section .first_sec,"aw",@progbits | ||
| 106 | .rept 0x100 | ||
| 107 | .byte 1 | ||
| 108 | .endr | ||
| 109 | |||
| 110 | .section .second_sec,"aw",@progbits | ||
| 111 | .rept 0x100 | ||
| 112 | .byte 2 | ||
| 113 | .endr | ||
deps/lld/test/ELF/linkerscript/overlay-reject.test created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o --script %s -o %t 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: {{.*}}.test:{{.*}}: { expected, but got 0x3000 | ||
| 6 | # CHECK-NEXT: >>> .out.aaa 0x3000 : { *(.aaa) } | ||
| 7 | # CHECK-NEXT: >>> ^ | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | OVERLAY 0x1000 : AT ( 0x2000 ) { | ||
| 11 | .out.aaa 0x3000 : { *(.aaa) } | ||
| 12 | } | ||
| 13 | } | ||
deps/lld/test/ELF/linkerscript/overlay-reject2.test created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o --script %s -o %t 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: {{.*}}.test:{{.*}}: { expected, but got AX | ||
| 6 | # CHECK-NEXT: >>> .out.aaa { *(.aaa) } > AX AT>FLASH | ||
| 7 | # CHECK-NEXT: >>> ^ | ||
| 8 | |||
| 9 | MEMORY { | ||
| 10 | AX (ax) : ORIGIN = 0x3000, LENGTH = 0x4000 | ||
| 11 | } | ||
| 12 | |||
| 13 | SECTIONS { | ||
| 14 | OVERLAY 0x1000 : AT ( 0x2000 ) { | ||
| 15 | .out.aaa { *(.aaa) } > AX AT>FLASH | ||
| 16 | } | ||
| 17 | } | ||
deps/lld/test/ELF/linkerscript/overlay.test created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo 'nop; .section .small, "a"; .long 0; .section .big, "a"; .quad 1;' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | # RUN: ld.lld %t.o --script %s -o %t | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | OVERLAY 0x1000 : AT ( 0x4000 ) { | ||
| 8 | .out.big { *(.big) } | ||
| 9 | .out.small { *(.small) } | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | ## Here we check that can handle OVERLAY which will produce sections | ||
| 14 | ## .out.big and .out.small with the same starting VAs, but different LMAs. | ||
| 15 | ## Section .big is larger than .small, we check that placing of section | ||
| 16 | ## .text does not cause overlapping error and that | ||
| 17 | ## .text's VA is 0x1000 + max(sizeof(.out.big), sizeof(.out.small)). | ||
| 18 | |||
| 19 | # RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t | FileCheck %s | ||
| 20 | |||
| 21 | # CHECK: Section Headers: | ||
| 22 | # CHECK: Name Type Address Off Size | ||
| 23 | # CHECK: .out.big PROGBITS 0000000000001000 001000 000008 | ||
| 24 | # CHECK: .out.small PROGBITS 0000000000001000 002000 000004 | ||
| 25 | # CHECK: .text PROGBITS 0000000000001008 002008 000001 | ||
| 26 | |||
| 27 | # CHECK: Program Headers: | ||
| 28 | # CHECK: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align | ||
| 29 | # CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000004000 0x000008 0x000008 R E 0x1000 | ||
| 30 | # CHECK-NEXT: LOAD 0x002000 0x0000000000001000 0x0000000000004008 0x000009 0x000009 R E 0x1000 | ||
deps/lld/test/ELF/linkerscript/page-size-align.s deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { \ | ||
| 5 | # RUN: . = SIZEOF_HEADERS; \ | ||
| 6 | # RUN: .text : { *(.text) } \ | ||
| 7 | # RUN: . = ALIGN(CONSTANT(MAXPAGESIZE)); \ | ||
| 8 | # RUN: . = . + 0x3000; \ | ||
| 9 | # RUN: .dynamic : { *(.dynamic) } \ | ||
| 10 | # RUN: }" > %t.script | ||
| 11 | |||
| 12 | # RUN: ld.lld -T %t.script -z max-page-size=0x4000 %t.o -o %t.so -shared | ||
| 13 | # RUN: llvm-readobj -s %t.so | FileCheck %s | ||
| 14 | |||
| 15 | # CHECK: Name: .dynamic | ||
| 16 | # CHECK-NEXT: Type: SHT_DYNAMIC | ||
| 17 | # CHECK-NEXT: Flags [ | ||
| 18 | # CHECK-NEXT: SHF_ALLOC | ||
| 19 | # CHECK-NEXT: SHF_WRITE | ||
| 20 | # CHECK-NEXT: ] | ||
| 21 | # CHECK-NEXT: Address: 0x7000 | ||
| 22 | # CHECK-NEXT: Offset: 0x3000 | ||
deps/lld/test/ELF/linkerscript/page-size-align.test created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o | ||
| 3 | # 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 | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = SIZEOF_HEADERS; | ||
| 8 | .text : { *(.text) } | ||
| 9 | . = ALIGN(CONSTANT(MAXPAGESIZE)); | ||
| 10 | . = . + 0x3000; | ||
| 11 | .dynamic : { *(.dynamic) } | ||
| 12 | } | ||
| 13 | |||
| 14 | # CHECK: Name: .dynamic | ||
| 15 | # CHECK-NEXT: Type: SHT_DYNAMIC | ||
| 16 | # CHECK-NEXT: Flags [ | ||
| 17 | # CHECK-NEXT: SHF_ALLOC | ||
| 18 | # CHECK-NEXT: SHF_WRITE | ||
| 19 | # CHECK-NEXT: ] | ||
| 20 | # CHECK-NEXT: Address: 0x7000 | ||
| 21 | # CHECK-NEXT: Offset: 0x3000 | ||
deps/lld/test/ELF/linkerscript/parse-section-in-addr.s deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { \ | ||
| 5 | # RUN: .foo-bar : AT(ADDR(.foo-bar)) { *(.text) } \ | ||
| 6 | # RUN: }" > %t.script | ||
| 7 | # RUN: ld.lld -o %t.so --script %t.script %t.o -shared | ||
| 8 | # RUN: llvm-readelf -S %t.so | FileCheck %s | ||
| 9 | |||
| 10 | # CHECK: .foo-bar | ||
deps/lld/test/ELF/linkerscript/parse-section-in-addr.test created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld -o %t.so --script %s %t.o -shared | ||
| 4 | # RUN: llvm-readelf -S %t.so | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .foo-bar : AT(ADDR(.foo-bar)) { *(.text) } | ||
| 8 | } | ||
| 9 | |||
| 10 | # CHECK: .foo-bar | ||
deps/lld/test/ELF/linkerscript/provide-empty-section.s created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tundefined.o | ||
| 4 | # RUN: echo "foo=42" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tdefined.o | ||
| 5 | # RUN: echo "call foo" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %treference.o | ||
| 6 | |||
| 7 | # RUN: echo "SECTIONS { .bar : { PROVIDE(foo = .); } }" > %t.script | ||
| 8 | |||
| 9 | # Case 1: Provided symbol is undefined and not referenced - empty section should be removed. | ||
| 10 | # RUN: ld.lld %tundefined.o -T %t.script -o %t1.elf | ||
| 11 | # RUN: llvm-readobj -sections %t1.elf | FileCheck %s --check-prefix=NOSECTION | ||
| 12 | |||
| 13 | # Case 2: Provided symbol is undefined and referenced - empty section should not be removed. | ||
| 14 | # 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 | ||
| 16 | |||
| 17 | # Case 3: Provided symbol is defined and not referenced - empty section should be removed. | ||
| 18 | # RUN: ld.lld %tdefined.o -T %t.script -o %t3.elf | ||
| 19 | # RUN: llvm-readobj -sections %t3.elf | FileCheck %s --check-prefix=NOSECTION | ||
| 20 | |||
| 21 | # Case 4: Provided symbol is defined and referenced - empty section should not be removed. | ||
| 22 | # 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 | ||
| 24 | |||
| 25 | .global _start | ||
| 26 | _start: | ||
| 27 | ret | ||
| 28 | |||
| 29 | # SECTION: .bar | ||
| 30 | # NOSECTION-NOT: .bar | ||
deps/lld/test/ELF/linkerscript/provide-shared2.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/provide-shared2.s -o %t2.o | ||
| 4 | # RUN: ld.lld %t2.o -o %t2.so -shared | ||
| 5 | # RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; PROVIDE(foo = 42); }" > %t.script | ||
| 6 | # RUN: ld.lld -o %t --script %t.script %t.o %t2.so | ||
| 7 | # RUN: llvm-readelf --dyn-symbols %t | FileCheck %s | ||
| 8 | |||
| 9 | # CHECK: 1 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo@ | ||
| 10 | |||
| 11 | .global _start | ||
| 12 | _start: | ||
| 13 | nop | ||
deps/lld/test/ELF/linkerscript/pt-interp.test created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o | ||
| 3 | # RUN: ld.lld -o %t.so -shared %t.o | ||
| 4 | |||
| 5 | ## Check we create PT_INTERP program header when it is specified in PHDRS. | ||
| 6 | # RUN: echo "PHDRS { interp PT_INTERP; }" > %t1.script | ||
| 7 | # RUN: ld.lld -o %t1 --script %t1.script %t.o %t.so --dynamic-linker foo | ||
| 8 | # RUN: llvm-readobj -program-headers %t1 | FileCheck %s | ||
| 9 | # CHECK: PT_INTERP | ||
| 10 | |||
| 11 | ## Check we do not create it if it is not specified, | ||
| 12 | ## but only if PHDRS is not empty by itself. | ||
| 13 | # RUN: echo "PHDRS { ph_text PT_LOAD; }" > %t2.script | ||
| 14 | # 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 | ||
| 16 | # NOINTERP-NOT: PT_INTERP | ||
| 17 | |||
| 18 | ## Otherwise, if PHDRS is empty, we create PT_INTERP header. | ||
| 19 | # RUN: echo "PHDRS {}" > %t3.script | ||
| 20 | # RUN: ld.lld -o %t1 --script %t3.script %t.o %t.so --dynamic-linker foo | ||
| 21 | # RUN: llvm-readobj -program-headers %t1 | FileCheck %s | ||
deps/lld/test/ELF/linkerscript/pt_gnu_eh_frame.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | # RUN: echo "SECTIONS { /DISCARD/ : { *(.eh_frame*) *(.eh_frame_hdr*) } }" > %t.script | 3 | # RUN: echo "SECTIONS { /DISCARD/ : { *(.eh_frame*) *(.eh_frame_hdr*) } }" > %t.script |
| 4 | # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t | 4 | # RUN: ld.lld -o /dev/null --eh-frame-hdr --script %t.script %t |
| 5 | 5 | ||
| 6 | .global _start | 6 | .global _start |
| 7 | _start: | 7 | _start: |
deps/lld/test/ELF/linkerscript/region-alias.s+2-2| ... | @@ -15,7 +15,7 @@ | ... | @@ -15,7 +15,7 @@ |
| 15 | # RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", RAM);" >> %t.script.inc | 15 | # RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", RAM);" >> %t.script.inc |
| 16 | # RUN: ld.lld %t --script %t.script -o %t2 | 16 | # RUN: ld.lld %t --script %t.script -o %t2 |
| 17 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s | 17 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s |
| 18 | # CHECK: .text 00000001 0000000000001000 TEXT DATA | 18 | # CHECK: .text 00000001 0000000000001000 TEXT |
| 19 | # CHECK: .data 00000008 0000000000002000 DATA | 19 | # CHECK: .data 00000008 0000000000002000 DATA |
| 20 | 20 | ||
| 21 | ## All to ROM. | 21 | ## All to ROM. |
| ... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
| 23 | # RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", ROM);" >> %t.script.inc | 23 | # RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", ROM);" >> %t.script.inc |
| 24 | # RUN: ld.lld %t --script %t.script -o %t2 | 24 | # RUN: ld.lld %t --script %t.script -o %t2 |
| 25 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=RAM | 25 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=RAM |
| 26 | # RAM: .text 00000001 0000000000001000 TEXT DATA | 26 | # RAM: .text 00000001 0000000000001000 TEXT |
| 27 | # RAM: .data 00000008 0000000000001001 DATA | 27 | # RAM: .data 00000008 0000000000001001 DATA |
| 28 | 28 | ||
| 29 | ## Redefinition of region. | 29 | ## Redefinition of region. |
deps/lld/test/ELF/linkerscript/rosegment.s deleted-24| ... | @@ -1,24 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | # Test that with linker scripts we don't create a RO PT_LOAD. | ||
| 5 | |||
| 6 | # RUN: echo "SECTIONS {}" > %t.script | ||
| 7 | # RUN: ld.lld -o %t1 --script %t.script %t -shared | ||
| 8 | # RUN: llvm-readobj -l %t1 | FileCheck %s | ||
| 9 | |||
| 10 | # CHECK-NOT: Type: PT_LOAD | ||
| 11 | |||
| 12 | # CHECK: Type: PT_LOAD | ||
| 13 | # CHECK: Flags [ | ||
| 14 | # CHECK-NEXT: PF_R | ||
| 15 | # CHECK-NEXT: PF_X | ||
| 16 | # CHECK-NEXT: ] | ||
| 17 | |||
| 18 | # CHECK: Type: PT_LOAD | ||
| 19 | # CHECK: Flags [ | ||
| 20 | # CHECK-NEXT: PF_R | ||
| 21 | # CHECK-NEXT: PF_W | ||
| 22 | # CHECK-NEXT: ] | ||
| 23 | |||
| 24 | # CHECK-NOT: Type: PT_LOAD | ||
deps/lld/test/ELF/linkerscript/rosegment.test created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t | ||
| 3 | |||
| 4 | # Test that with linker scripts we don't create a RO PT_LOAD. | ||
| 5 | |||
| 6 | # RUN: ld.lld -o %t1 --script %s %t -shared | ||
| 7 | # RUN: llvm-readobj -l %t1 | FileCheck %s | ||
| 8 | |||
| 9 | SECTIONS { | ||
| 10 | } | ||
| 11 | |||
| 12 | # CHECK-NOT: Type: PT_LOAD | ||
| 13 | |||
| 14 | # CHECK: Type: PT_LOAD | ||
| 15 | # CHECK: Flags [ | ||
| 16 | # CHECK-NEXT: PF_R | ||
| 17 | # CHECK-NEXT: PF_X | ||
| 18 | # CHECK-NEXT: ] | ||
| 19 | |||
| 20 | # CHECK: Type: PT_LOAD | ||
| 21 | # CHECK: Flags [ | ||
| 22 | # CHECK-NEXT: PF_R | ||
| 23 | # CHECK-NEXT: PF_W | ||
| 24 | # CHECK-NEXT: ] | ||
| 25 | |||
| 26 | # CHECK-NOT: Type: PT_LOAD | ||
deps/lld/test/ELF/linkerscript/section-metadata.s+4-4| ... | @@ -10,15 +10,15 @@ | ... | @@ -10,15 +10,15 @@ |
| 10 | # RUN: llvm-objdump -s %t | FileCheck --check-prefix=INV %s | 10 | # RUN: llvm-objdump -s %t | FileCheck --check-prefix=INV %s |
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | # CHECK: Contents of section .text: | ||
| 14 | # CHECK-NEXT: 02000000 00000000 01000000 00000000 | ||
| 15 | # CHECK: Contents of section .rodata: | 13 | # CHECK: Contents of section .rodata: |
| 16 | # CHECK-NEXT: 02000000 00000000 01000000 00000000 | 14 | # CHECK-NEXT: 02000000 00000000 01000000 00000000 |
| 15 | # CHECK: Contents of section .text: | ||
| 16 | # CHECK-NEXT: 02000000 00000000 01000000 00000000 | ||
| 17 | 17 | ||
| 18 | # INV: Contents of section .text: | ||
| 19 | # INV-NEXT: 01000000 00000000 02000000 00000000 | ||
| 20 | # INV: Contents of section .rodata: | 18 | # INV: Contents of section .rodata: |
| 21 | # INV-NEXT: 01000000 00000000 02000000 00000000 | 19 | # INV-NEXT: 01000000 00000000 02000000 00000000 |
| 20 | # INV: Contents of section .text: | ||
| 21 | # INV-NEXT: 01000000 00000000 02000000 00000000 | ||
| 22 | 22 | ||
| 23 | .global _start | 23 | .global _start |
| 24 | _start: | 24 | _start: |
deps/lld/test/ELF/linkerscript/section-metadata2.s created+37| ... | @@ -0,0 +1,37 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { .text : { *(.text.*) } }" > %t.script | ||
| 4 | |||
| 5 | # RUN: echo "_bar" > %t.ord | ||
| 6 | # RUN: echo "_foo" >> %t.ord | ||
| 7 | # RUN: ld.lld --symbol-ordering-file %t.ord -o %t --script %t.script %t.o | ||
| 8 | # RUN: llvm-objdump -s %t | FileCheck %s | ||
| 9 | |||
| 10 | # CHECK: Contents of section .rodata: | ||
| 11 | # CHECK-NEXT: 02000000 00000000 01000000 00000000 | ||
| 12 | # CHECK: Contents of section .text: | ||
| 13 | # CHECK-NEXT: 02000000 00000000 01000000 00000000 | ||
| 14 | |||
| 15 | # RUN: echo "_foo" > %t.ord | ||
| 16 | # RUN: echo "_bar" >> %t.ord | ||
| 17 | # RUN: ld.lld --symbol-ordering-file %t.ord -o %t --script %t.script %t.o | ||
| 18 | # RUN: llvm-objdump -s %t | FileCheck %s --check-prefix=INV | ||
| 19 | |||
| 20 | # INV: Contents of section .rodata: | ||
| 21 | # INV-NEXT: 01000000 00000000 02000000 00000000 | ||
| 22 | # INV: Contents of section .text: | ||
| 23 | # INV-NEXT: 01000000 00000000 02000000 00000000 | ||
| 24 | |||
| 25 | .section .text.foo,"a",@progbits | ||
| 26 | _foo: | ||
| 27 | .quad 1 | ||
| 28 | |||
| 29 | .section .text.bar,"a",@progbits | ||
| 30 | _bar: | ||
| 31 | .quad 2 | ||
| 32 | |||
| 33 | .section .rodata.foo,"ao",@progbits,.text.foo | ||
| 34 | .quad 1 | ||
| 35 | |||
| 36 | .section .rodata.bar,"ao",@progbits,.text.bar | ||
| 37 | .quad 2 | ||
deps/lld/test/ELF/linkerscript/sections-keep.s+18-18| ... | @@ -1,14 +1,14 @@ | ... | @@ -1,14 +1,14 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 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/keep.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/keep.s -o %t1.o |
| 4 | 4 | ||
| 5 | ## First check that section "keep" is garbage collected without using KEEP | 5 | ## First check that section "keep" is garbage collected without using KEEP |
| 6 | # RUN: echo "SECTIONS { \ | 6 | # RUN: echo "SECTIONS { \ |
| 7 | # RUN: .text : { *(.text) } \ | 7 | # RUN: .text : { *(.text) } \ |
| 8 | # RUN: .keep : { *(.keep) } \ | 8 | # RUN: .keep : { *(.keep) } \ |
| 9 | # RUN: .temp : { *(.temp) }}" > %t.script | 9 | # RUN: .temp : { *(.temp) }}" > %t.script |
| 10 | # RUN: ld.lld --gc-sections -o %t1 --script %t.script %t | 10 | # RUN: ld.lld --gc-sections -o %t --script %t.script %t.o |
| 11 | # RUN: llvm-objdump -section-headers %t1 | \ | 11 | # RUN: llvm-objdump -section-headers %t | \ |
| 12 | # RUN: FileCheck -check-prefix=SECGC %s | 12 | # RUN: FileCheck -check-prefix=SECGC %s |
| 13 | # SECGC: Sections: | 13 | # SECGC: Sections: |
| 14 | # SECGC-NEXT: Idx Name Size | 14 | # SECGC-NEXT: Idx Name Size |
| ... | @@ -21,8 +21,8 @@ | ... | @@ -21,8 +21,8 @@ |
| 21 | # RUN: .text : { *(.text) } \ | 21 | # RUN: .text : { *(.text) } \ |
| 22 | # RUN: .keep : { KEEP(*(.keep)) } \ | 22 | # RUN: .keep : { KEEP(*(.keep)) } \ |
| 23 | # RUN: .temp : { *(.temp) }}" > %t.script | 23 | # RUN: .temp : { *(.temp) }}" > %t.script |
| 24 | # RUN: ld.lld --gc-sections -o %t1 --script %t.script %t | 24 | # RUN: ld.lld --gc-sections -o %t --script %t.script %t.o |
| 25 | # RUN: llvm-objdump -section-headers %t1 | \ | 25 | # RUN: llvm-objdump -section-headers %t | \ |
| 26 | # RUN: FileCheck -check-prefix=SECNOGC %s | 26 | # RUN: FileCheck -check-prefix=SECNOGC %s |
| 27 | # SECNOGC: Sections: | 27 | # SECNOGC: Sections: |
| 28 | # SECNOGC-NEXT: Idx Name Size | 28 | # SECNOGC-NEXT: Idx Name Size |
| ... | @@ -38,14 +38,14 @@ | ... | @@ -38,14 +38,14 @@ |
| 38 | # RUN: . = SIZEOF_HEADERS; \ | 38 | # RUN: . = SIZEOF_HEADERS; \ |
| 39 | # RUN: .keep : { KEEP(*(.keep)) } \ | 39 | # RUN: .keep : { KEEP(*(.keep)) } \ |
| 40 | # RUN: .nokeep : { *(.keep) }}" > %t.script | 40 | # RUN: .nokeep : { *(.keep) }}" > %t.script |
| 41 | # RUN: ld.lld --gc-sections -o %t1 --script %t.script %t | 41 | # RUN: ld.lld --gc-sections -o %t --script %t.script %t.o |
| 42 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED1 %s | 42 | # RUN: llvm-objdump -section-headers %t | FileCheck -check-prefix=MIXED1 %s |
| 43 | # MIXED1: Sections: | 43 | # MIXED1: Sections: |
| 44 | # MIXED1-NEXT: Idx Name Size | 44 | # MIXED1-NEXT: Idx Name Size |
| 45 | # MIXED1-NEXT: 0 00000000 | 45 | # MIXED1-NEXT: 0 00000000 |
| 46 | # MIXED1-NEXT: 1 .keep 00000004 | 46 | # MIXED1-NEXT: 1 .keep 00000004 |
| 47 | # MIXED1-NEXT: 2 .text 00000007 00000000000000ec TEXT DATA | 47 | # MIXED1-NEXT: 2 .temp 00000004 00000000000000ec |
| 48 | # MIXED1-NEXT: 3 .temp 00000004 00000000000000f3 DATA | 48 | # MIXED1-NEXT: 3 .text 00000007 00000000000000f0 |
| 49 | # MIXED1-NEXT: 4 .comment 00000008 0000000000000000 | 49 | # MIXED1-NEXT: 4 .comment 00000008 0000000000000000 |
| 50 | # MIXED1-NEXT: 5 .symtab 00000060 0000000000000000 | 50 | # MIXED1-NEXT: 5 .symtab 00000060 0000000000000000 |
| 51 | # MIXED1-NEXT: 6 .shstrtab 00000036 0000000000000000 | 51 | # MIXED1-NEXT: 6 .shstrtab 00000036 0000000000000000 |
| ... | @@ -59,14 +59,14 @@ | ... | @@ -59,14 +59,14 @@ |
| 59 | # RUN: . = SIZEOF_HEADERS; \ | 59 | # RUN: . = SIZEOF_HEADERS; \ |
| 60 | # RUN: .nokeep : { *(.keep) } \ | 60 | # RUN: .nokeep : { *(.keep) } \ |
| 61 | # RUN: .keep : { KEEP(*(.keep)) }}" > %t.script | 61 | # RUN: .keep : { KEEP(*(.keep)) }}" > %t.script |
| 62 | # RUN: ld.lld --gc-sections -o %t1 --script %t.script %t | 62 | # RUN: ld.lld --gc-sections -o %t --script %t.script %t.o |
| 63 | # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED2 %s | 63 | # RUN: llvm-objdump -section-headers %t | FileCheck -check-prefix=MIXED2 %s |
| 64 | # MIXED2: Sections: | 64 | # MIXED2: Sections: |
| 65 | # MIXED2-NEXT: Idx Name Size | 65 | # MIXED2-NEXT: Idx Name Size |
| 66 | # MIXED2-NEXT: 0 00000000 | 66 | # MIXED2-NEXT: 0 00000000 |
| 67 | # MIXED2-NEXT: 1 .nokeep 00000004 00000000000000e8 DATA | 67 | # MIXED2-NEXT: 1 .nokeep 00000004 00000000000000e8 |
| 68 | # MIXED2-NEXT: 2 .text 00000007 00000000000000ec TEXT DATA | 68 | # MIXED2-NEXT: 2 .temp 00000004 00000000000000ec |
| 69 | # MIXED2-NEXT: 3 .temp 00000004 00000000000000f3 DATA | 69 | # MIXED2-NEXT: 3 .text 00000007 00000000000000f0 |
| 70 | # MIXED2-NEXT: 4 .comment 00000008 0000000000000000 | 70 | # MIXED2-NEXT: 4 .comment 00000008 0000000000000000 |
| 71 | # MIXED2-NEXT: 5 .symtab 00000060 0000000000000000 | 71 | # MIXED2-NEXT: 5 .symtab 00000060 0000000000000000 |
| 72 | # MIXED2-NEXT: 6 .shstrtab 00000038 0000000000000000 | 72 | # MIXED2-NEXT: 6 .shstrtab 00000038 0000000000000000 |
| ... | @@ -75,10 +75,10 @@ | ... | @@ -75,10 +75,10 @@ |
| 75 | # Check file pattern for kept sections. | 75 | # Check file pattern for kept sections. |
| 76 | # RUN: echo "SECTIONS { \ | 76 | # RUN: echo "SECTIONS { \ |
| 77 | # RUN: . = SIZEOF_HEADERS; \ | 77 | # RUN: . = SIZEOF_HEADERS; \ |
| 78 | # RUN: .keep : { KEEP(*2.o(.keep)) } \ | 78 | # RUN: .keep : { KEEP(*1.o(.keep)) } \ |
| 79 | # RUN: }" > %t.script | 79 | # RUN: }" > %t.script |
| 80 | # RUN: ld.lld --gc-sections -o %t1 --script %t.script %t2.o %t | 80 | # RUN: ld.lld --gc-sections -o %t --script %t.script %t1.o %t.o |
| 81 | # RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=FILEMATCH %s | 81 | # RUN: llvm-objdump -s %t | FileCheck -check-prefix=FILEMATCH %s |
| 82 | # FILEMATCH: Contents of section .keep: | 82 | # FILEMATCH: Contents of section .keep: |
| 83 | # FILEMATCH-NEXT: 00e8 41414141 AAAA | 83 | # FILEMATCH-NEXT: 00e8 41414141 AAAA |
| 84 | 84 |
deps/lld/test/ELF/linkerscript/sections-max-va-overflow.s created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { . = 0xfffffffffffffff1;" > %t.script | ||
| 5 | # RUN: echo " .bar : { *(.bar*) } }" >> %t.script | ||
| 6 | # RUN: not ld.lld -o /dev/null --script %t.script %t.o 2>&1 | FileCheck %s -check-prefix=ERR | ||
| 7 | |||
| 8 | ## .bar section has data in [0xfffffffffffffff1, 0xfffffffffffffff1 + 0x10] == | ||
| 9 | ## [0xfffffffffffffff1, 0x1]. Check we can catch this overflow. | ||
| 10 | # ERR: error: section .bar at 0xFFFFFFFFFFFFFFF1 of size 0x10 exceeds available address space | ||
| 11 | |||
| 12 | .section .bar,"ax",@progbits | ||
| 13 | .zero 0x10 | ||
deps/lld/test/ELF/linkerscript/sections-sort.s+5-5| ... | @@ -13,13 +13,13 @@ nop | ... | @@ -13,13 +13,13 @@ nop |
| 13 | .section foo, "a" | 13 | .section foo, "a" |
| 14 | .byte 0 | 14 | .byte 0 |
| 15 | 15 | ||
| 16 | # CHECK: Id | 16 | # CHECK: Idx |
| 17 | # CHECK-NEXT: 0 | 17 | # CHECK-NEXT: 0 |
| 18 | # CHECK-NEXT: 1 .text | 18 | # CHECK-NEXT: 1 .text |
| 19 | # CHECK-NEXT: 2 foo | 19 | # CHECK-NEXT: 2 .dynsym |
| 20 | # CHECK-NEXT: 3 .dynsym | 20 | # CHECK-NEXT: 3 .hash |
| 21 | # CHECK-NEXT: 4 .hash | 21 | # CHECK-NEXT: 4 .dynstr |
| 22 | # CHECK-NEXT: 5 .dynstr | 22 | # CHECK-NEXT: 5 foo |
| 23 | # CHECK-NEXT: 6 .dynamic | 23 | # CHECK-NEXT: 6 .dynamic |
| 24 | # CHECK-NEXT: 7 .comment | 24 | # CHECK-NEXT: 7 .comment |
| 25 | # CHECK-NEXT: 8 .symtab | 25 | # CHECK-NEXT: 8 .symtab |
deps/lld/test/ELF/linkerscript/sections-va-overflow.test created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/sections-va-overflow.s -o %t.o | ||
| 3 | # RUN: not ld.lld -o /dev/null --script %s %t.o 2>&1 | FileCheck %s -check-prefix=ERR | ||
| 4 | |||
| 5 | PHDRS { | ||
| 6 | ph_headers PT_PHDR PHDRS; | ||
| 7 | ph_text PT_LOAD FILEHDR PHDRS FLAGS (0x1 | 0x4); | ||
| 8 | } | ||
| 9 | |||
| 10 | SECTIONS { | ||
| 11 | . = 0xffffffff20000000; | ||
| 12 | .text : { *(.text*) } : ph_text | ||
| 13 | .test 0x1000 : { BYTE(0) } | ||
| 14 | .bss : { *(.bss*) } | ||
| 15 | } | ||
| 16 | |||
| 17 | ## Section .test has VA 0x1000 and placed in the same segment as section .text | ||
| 18 | ## with VA 0xffffffff20000000. That might be technically correct, but most probably | ||
| 19 | ## is a result of a broken script file and causes file offset calculation overflow. | ||
| 20 | ## It seems we do not have to support it, so we don't and we report an error in this case. | ||
| 21 | # ERR: error: unable to place section .text at file offset [0xFFFFFFFF20000000, 0xFFFFFFFE40000000]; check your linker script for overflows | ||
| 22 | # ERR-NOT: unable to place section .bss | ||
deps/lld/test/ELF/linkerscript/sections.s+4-4| ... | @@ -16,7 +16,7 @@ | ... | @@ -16,7 +16,7 @@ |
| 16 | # RUN: FileCheck -check-prefix=SEC-DEFAULT %s | 16 | # RUN: FileCheck -check-prefix=SEC-DEFAULT %s |
| 17 | 17 | ||
| 18 | # Idx Name Size | 18 | # Idx Name Size |
| 19 | # SEC-DEFAULT: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA | 19 | # SEC-DEFAULT: 1 .text 0000000e {{[0-9a-f]*}} TEXT |
| 20 | # SEC-DEFAULT: 2 .data 00000020 {{[0-9a-f]*}} DATA | 20 | # SEC-DEFAULT: 2 .data 00000020 {{[0-9a-f]*}} DATA |
| 21 | # SEC-DEFAULT: 3 other 00000003 {{[0-9a-f]*}} DATA | 21 | # SEC-DEFAULT: 3 other 00000003 {{[0-9a-f]*}} DATA |
| 22 | # SEC-DEFAULT: 4 .bss 00000002 {{[0-9a-f]*}} BSS | 22 | # SEC-DEFAULT: 4 .bss 00000002 {{[0-9a-f]*}} BSS |
| ... | @@ -47,7 +47,7 @@ | ... | @@ -47,7 +47,7 @@ |
| 47 | # SEC-ORDER: 5 .strtab 00000008 {{[0-9a-f]*}} | 47 | # SEC-ORDER: 5 .strtab 00000008 {{[0-9a-f]*}} |
| 48 | # SEC-ORDER: 6 .comment 00000008 {{[0-9a-f]*}} | 48 | # SEC-ORDER: 6 .comment 00000008 {{[0-9a-f]*}} |
| 49 | # SEC-ORDER: 7 .data 00000020 {{[0-9a-f]*}} DATA | 49 | # SEC-ORDER: 7 .data 00000020 {{[0-9a-f]*}} DATA |
| 50 | # SEC-ORDER: 8 .text 0000000e {{[0-9a-f]*}} TEXT DATA | 50 | # SEC-ORDER: 8 .text 0000000e {{[0-9a-f]*}} TEXT |
| 51 | 51 | ||
| 52 | # .text and .data have swapped names but proper sizes and types. | 52 | # .text and .data have swapped names but proper sizes and types. |
| 53 | # RUN: echo "SECTIONS { \ | 53 | # RUN: echo "SECTIONS { \ |
| ... | @@ -58,7 +58,7 @@ | ... | @@ -58,7 +58,7 @@ |
| 58 | # RUN: FileCheck -check-prefix=SEC-SWAP-NAMES %s | 58 | # RUN: FileCheck -check-prefix=SEC-SWAP-NAMES %s |
| 59 | 59 | ||
| 60 | # Idx Name Size | 60 | # Idx Name Size |
| 61 | # SEC-SWAP-NAMES: 1 .data 0000000e {{[0-9a-f]*}} TEXT DATA | 61 | # SEC-SWAP-NAMES: 1 .data 0000000e {{[0-9a-f]*}} TEXT |
| 62 | # SEC-SWAP-NAMES: 2 .text 00000020 {{[0-9a-f]*}} DATA | 62 | # SEC-SWAP-NAMES: 2 .text 00000020 {{[0-9a-f]*}} DATA |
| 63 | # SEC-SWAP-NAMES: 3 other 00000003 {{[0-9a-f]*}} DATA | 63 | # SEC-SWAP-NAMES: 3 other 00000003 {{[0-9a-f]*}} DATA |
| 64 | # SEC-SWAP-NAMES: 4 .bss 00000002 {{[0-9a-f]*}} BSS | 64 | # SEC-SWAP-NAMES: 4 .bss 00000002 {{[0-9a-f]*}} BSS |
| ... | @@ -80,7 +80,7 @@ | ... | @@ -80,7 +80,7 @@ |
| 80 | # RUN: FileCheck -check-prefix=SEC-MULTI %s | 80 | # RUN: FileCheck -check-prefix=SEC-MULTI %s |
| 81 | 81 | ||
| 82 | # Idx Name Size | 82 | # Idx Name Size |
| 83 | # SEC-MULTI: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA | 83 | # SEC-MULTI: 1 .text 0000000e {{[0-9a-f]*}} TEXT |
| 84 | # SEC-MULTI-NEXT: .data 00000020 {{[0-9a-f]*}} DATA | 84 | # SEC-MULTI-NEXT: .data 00000020 {{[0-9a-f]*}} DATA |
| 85 | # SEC-MULTI-NEXT: .data 00000003 {{[0-9a-f]*}} DATA | 85 | # SEC-MULTI-NEXT: .data 00000003 {{[0-9a-f]*}} DATA |
| 86 | # SEC-MULTI-NEXT: .bss 00000002 {{[0-9a-f]*}} BSS | 86 | # SEC-MULTI-NEXT: .bss 00000002 {{[0-9a-f]*}} BSS |
deps/lld/test/ELF/linkerscript/segment-none.s+2-2| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | # RUN: .foo : {*(.foo)} :NONE \ | 9 | # RUN: .foo : {*(.foo)} :NONE \ |
| 10 | # RUN: }" > %t.script | 10 | # RUN: }" > %t.script |
| 11 | # RUN: ld.lld -o %t --script %t.script %t.o | 11 | # RUN: ld.lld -o %t --script %t.script %t.o |
| 12 | # RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s | 12 | # RUN: llvm-readelf -s -l %t | FileCheck %s |
| 13 | 13 | ||
| 14 | ## Test that section .foo is placed in segment NONE when assigned to segment | 14 | ## Test that section .foo is placed in segment NONE when assigned to segment |
| 15 | ## NONE in the linker script and segment NONE is defined. | 15 | ## NONE in the linker script and segment NONE is defined. |
| ... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
| 19 | # RUN: .foo : {*(.foo)} :NONE \ | 19 | # RUN: .foo : {*(.foo)} :NONE \ |
| 20 | # RUN: }" > %t.script | 20 | # RUN: }" > %t.script |
| 21 | # RUN: ld.lld -o %t --script %t.script %t.o | 21 | # RUN: ld.lld -o %t --script %t.script %t.o |
| 22 | # RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s | 22 | # RUN: llvm-readelf -s -l %t | FileCheck --check-prefix=DEFINED %s |
| 23 | 23 | ||
| 24 | # CHECK: Section to Segment mapping: | 24 | # CHECK: Section to Segment mapping: |
| 25 | # CHECK-NEXT: Segment Sections... | 25 | # CHECK-NEXT: Segment Sections... |
deps/lld/test/ELF/linkerscript/segment-start.s+1-1| ... | @@ -22,6 +22,6 @@ | ... | @@ -22,6 +22,6 @@ |
| 22 | .quad foobar4 | 22 | .quad foobar4 |
| 23 | 23 | ||
| 24 | // RUN: echo "SECTIONS { . = SEGMENT_START(\"foobar\", foo); }" > %t.script | 24 | // RUN: echo "SECTIONS { . = SEGMENT_START(\"foobar\", foo); }" > %t.script |
| 25 | // RUN: not ld.lld %t.o %t.script -shared -o %t2.so 2>&1 \ | 25 | // RUN: not ld.lld %t.o %t.script -shared -o /dev/null 2>&1 \ |
| 26 | // RUN: | FileCheck --check-prefix=ERR %s | 26 | // RUN: | FileCheck --check-prefix=ERR %s |
| 27 | // ERR: {{.*}}.script:1: symbol not found: foo | 27 | // ERR: {{.*}}.script:1: symbol not found: foo |
deps/lld/test/ELF/linkerscript/sort-constructors.s deleted-5| ... | @@ -1,5 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 3 | # RUN: echo "SECTIONS { .aaa : { SORT(CONSTRUCTORS) } }" > %t1.script | ||
| 4 | # RUN: ld.lld -shared -o %t1 --script %t1.script %t1.o | ||
| 5 | # RUN: llvm-readobj %t1 > /dev/null | ||
deps/lld/test/ELF/linkerscript/sort-constructors.test created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux /dev/null -o %t1.o | ||
| 3 | # RUN: ld.lld -shared -o %t1 --script %s %t1.o | ||
| 4 | # RUN: llvm-readobj %t1 > /dev/null | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .aaa : { SORT(CONSTRUCTORS) } | ||
| 8 | } | ||
deps/lld/test/ELF/linkerscript/sort-non-script.s+5-5| ... | @@ -1,14 +1,14 @@ | ... | @@ -1,14 +1,14 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | ||
| 4 | # RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script | 4 | # RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script |
| 5 | # RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared | 5 | # RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared |
| 6 | # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s | 6 | # RUN: llvm-readelf -s %t | FileCheck %s |
| 7 | 7 | ||
| 8 | # CHECK: .text {{.*}} AX | 8 | # CHECK: .dynsym {{.*}} A |
| 9 | # CHECK-NEXT: .dynsym {{.*}} A | ||
| 10 | # CHECK-NEXT: .hash {{.*}} A | 9 | # CHECK-NEXT: .hash {{.*}} A |
| 11 | # CHECK-NEXT: .dynstr {{.*}} A | 10 | # CHECK-NEXT: .dynstr {{.*}} A |
| 11 | # CHECK-NEXT: .text {{.*}} AX | ||
| 12 | # CHECK-NEXT: foo {{.*}} WA | 12 | # CHECK-NEXT: foo {{.*}} WA |
| 13 | # CHECK-NEXT: .dynamic {{.*}} WA | 13 | # CHECK-NEXT: .dynamic {{.*}} WA |
| 14 | 14 |
deps/lld/test/ELF/linkerscript/start-end.s deleted-16| ... | @@ -1,16 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { \ | ||
| 4 | # RUN: .init_array : { \ | ||
| 5 | # RUN: __init_array_start = .; \ | ||
| 6 | # RUN: *(.init_array) \ | ||
| 7 | # RUN: __init_array_end = .; } }" > %t.script | ||
| 8 | # RUN: ld.lld %t.o -script %t.script -o %t 2>&1 | ||
| 9 | |||
| 10 | .globl _start | ||
| 11 | .text | ||
| 12 | _start: | ||
| 13 | nop | ||
| 14 | |||
| 15 | .section .init_array, "aw" | ||
| 16 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/start-end.test created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .init_array, "aw"; .quad 0' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | # RUN: ld.lld %t.o -script %s -o %t 2>&1 | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | .init_array : { | ||
| 8 | __init_array_start = .; | ||
| 9 | *(.init_array) | ||
| 10 | __init_array_end = .; | ||
| 11 | } | ||
| 12 | } | ||
deps/lld/test/ELF/linkerscript/subalign.s+1-1| ... | @@ -36,7 +36,7 @@ | ... | @@ -36,7 +36,7 @@ |
| 36 | 36 | ||
| 37 | ## Test we fail gracefuly when alignment value is not a power of 2. | 37 | ## Test we fail gracefuly when alignment value is not a power of 2. |
| 38 | # RUN: echo "SECTIONS { .aaa : SUBALIGN(3) { *(.aaa*) } }" > %t5.script | 38 | # RUN: echo "SECTIONS { .aaa : SUBALIGN(3) { *(.aaa*) } }" > %t5.script |
| 39 | # RUN: not ld.lld %t1.o --script %t5.script -o %t5 2>&1 | FileCheck -check-prefix=ERR %s | 39 | # RUN: not ld.lld %t1.o --script %t5.script -o /dev/null 2>&1 | FileCheck -check-prefix=ERR %s |
| 40 | # ERR: {{.*}}.script:1: alignment must be power of 2 | 40 | # ERR: {{.*}}.script:1: alignment must be power of 2 |
| 41 | 41 | ||
| 42 | .global _start | 42 | .global _start |
deps/lld/test/ELF/linkerscript/symbol-assignexpr.s+1-1| ... | @@ -47,7 +47,7 @@ | ... | @@ -47,7 +47,7 @@ |
| 47 | # CHECK-NEXT: 0000000000000001 *ABS* 00000000 symbol15 | 47 | # CHECK-NEXT: 0000000000000001 *ABS* 00000000 symbol15 |
| 48 | 48 | ||
| 49 | # RUN: echo "SECTIONS { symbol2 = symbol; }" > %t2.script | 49 | # RUN: echo "SECTIONS { symbol2 = symbol; }" > %t2.script |
| 50 | # RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \ | 50 | # RUN: not ld.lld -o /dev/null --script %t2.script %t 2>&1 \ |
| 51 | # RUN: | FileCheck -check-prefix=ERR %s | 51 | # RUN: | FileCheck -check-prefix=ERR %s |
| 52 | # ERR: {{.*}}.script:1: symbol not found: symbol | 52 | # ERR: {{.*}}.script:1: symbol not found: symbol |
| 53 | 53 |
deps/lld/test/ELF/linkerscript/symbol-memoryexpr.s+1-1| ... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
| 23 | # RUN: no_exist_origin = ORIGIN(ram); \ | 23 | # RUN: no_exist_origin = ORIGIN(ram); \ |
| 24 | # RUN: no_exist_length = LENGTH(ram); \ | 24 | # RUN: no_exist_length = LENGTH(ram); \ |
| 25 | # RUN: }" > %t2.script | 25 | # RUN: }" > %t2.script |
| 26 | # RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \ | 26 | # RUN: not ld.lld -o /dev/null --script %t2.script %t 2>&1 \ |
| 27 | # RUN: | FileCheck -check-prefix=ERR %s | 27 | # RUN: | FileCheck -check-prefix=ERR %s |
| 28 | # ERR: {{.*}}.script:1: memory region not defined: ram | 28 | # ERR: {{.*}}.script:1: memory region not defined: ram |
| 29 | 29 |
deps/lld/test/ELF/linkerscript/symbol-only-flags.s deleted-20| ... | @@ -1,20 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \ | ||
| 4 | # RUN: .tbss : { *(.tbss) } \ | ||
| 5 | # RUN: .foo : { bar = .; } }" > %t.script | ||
| 6 | # RUN: ld.lld -o %t --script %t.script %t.o | ||
| 7 | # RUN: llvm-readobj -s %t | FileCheck %s | ||
| 8 | |||
| 9 | ## Check .foo does not get SHF_TLS flag. | ||
| 10 | # CHECK: Section { | ||
| 11 | # CHECK: Index: | ||
| 12 | # CHECK: Name: .foo | ||
| 13 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 14 | # CHECK-NEXT: Flags [ | ||
| 15 | # CHECK-NEXT: SHF_ALLOC | ||
| 16 | # CHECK-NEXT: SHF_WRITE | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | |||
| 19 | .section .tbss,"awT",@nobits | ||
| 20 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/symbol-only-flags.test created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .tbss,"awT",@nobits; .quad 0' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t.o | ||
| 4 | # RUN: ld.lld -o %t --script %s %t.o | ||
| 5 | # RUN: llvm-readobj -s %t | FileCheck %s | ||
| 6 | |||
| 7 | SECTIONS { | ||
| 8 | . = SIZEOF_HEADERS; | ||
| 9 | .tbss : { *(.tbss) } | ||
| 10 | .foo : { bar = .; } | ||
| 11 | } | ||
| 12 | |||
| 13 | ## Check .foo does not get SHF_TLS flag. | ||
| 14 | # CHECK: Section { | ||
| 15 | # CHECK: Index: | ||
| 16 | # CHECK: Name: .foo | ||
| 17 | # CHECK-NEXT: Type: SHT_NOBITS | ||
| 18 | # CHECK-NEXT: Flags [ | ||
| 19 | # CHECK-NEXT: SHF_ALLOC | ||
| 20 | # CHECK-NEXT: SHF_WRITE | ||
| 21 | # CHECK-NEXT: ] | ||
deps/lld/test/ELF/linkerscript/symbol-only.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 | |||
| 4 | # RUN: echo "SECTIONS { \ | ||
| 5 | # RUN: . = SIZEOF_HEADERS; \ | ||
| 6 | # RUN: abc : { foo = .; } \ | ||
| 7 | # RUN: . = ALIGN(0x1000); \ | ||
| 8 | # RUN: bar : { *(bar) } \ | ||
| 9 | # RUN: }" > %t.script | ||
| 10 | # RUN: ld.lld -o %t1 --script %t.script %t -shared | ||
| 11 | # RUN: llvm-objdump -section-headers -t %t1 | FileCheck %s | ||
| 12 | # CHECK: Sections: | ||
| 13 | # CHECK-NEXT: Idx Name Size Address | ||
| 14 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 15 | # CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] BSS | ||
| 16 | # CHECK-NEXT: bar 00000000 0000000000001000 DATA | ||
| 17 | |||
| 18 | # CHECK: SYMBOL TABLE: | ||
| 19 | # CHECK: [[ADDR]] abc 00000000 foo | ||
| 20 | |||
| 21 | .section bar, "a" | ||
deps/lld/test/ELF/linkerscript/symbol-only.test created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section bar, "a"' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t | ||
| 4 | # RUN: ld.lld -o %t1 --script %s %t -shared | ||
| 5 | # RUN: llvm-objdump -section-headers -t %t1 | FileCheck %s | ||
| 6 | |||
| 7 | SECTIONS { | ||
| 8 | . = SIZEOF_HEADERS; | ||
| 9 | abc : { foo = .; } | ||
| 10 | . = ALIGN(0x1000); | ||
| 11 | bar : { *(bar) } | ||
| 12 | } | ||
| 13 | |||
| 14 | # CHECK: Sections: | ||
| 15 | # CHECK-NEXT: Idx Name Size Address | ||
| 16 | # CHECK-NEXT: 0 00000000 0000000000000000 | ||
| 17 | # CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] | ||
| 18 | # CHECK: bar 00000000 0000000000001000 | ||
| 19 | |||
| 20 | # CHECK: SYMBOL TABLE: | ||
| 21 | # CHECK: [[ADDR]] abc 00000000 foo | ||
deps/lld/test/ELF/linkerscript/symbol-ordering-file.s+10| ... | @@ -14,6 +14,16 @@ | ... | @@ -14,6 +14,16 @@ |
| 14 | # AFTER: Contents of section .foo: | 14 | # AFTER: Contents of section .foo: |
| 15 | # AFTER-NEXT: 2211 | 15 | # AFTER-NEXT: 2211 |
| 16 | 16 | ||
| 17 | # RUN: echo "SECTIONS { .text : { *(.text) } }" > %t2.script | ||
| 18 | # RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t2.script -o %t3.out | ||
| 19 | # RUN: llvm-objdump -s %t3.out| FileCheck %s --check-prefix=AFTER | ||
| 20 | |||
| 21 | # RUN: echo "SECTIONS { .foo : { BYTE(0x33); *(.foo); BYTE(0x44) } }" > %t3.script | ||
| 22 | # RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t3.script -o %t4.out | ||
| 23 | # RUN: llvm-objdump -s %t4.out| FileCheck %s --check-prefix=COMMANDS | ||
| 24 | # COMMANDS: Contents of section .foo: | ||
| 25 | # COMMANDS-NEXT: 33221144 | ||
| 26 | |||
| 17 | .section .foo,"ax",@progbits,unique,1 | 27 | .section .foo,"ax",@progbits,unique,1 |
| 18 | _foo1: | 28 | _foo1: |
| 19 | .byte 0x11 | 29 | .byte 0x11 |
deps/lld/test/ELF/linkerscript/symbol-ordering-file2.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | |||
| 4 | ## Check we do not crash when trying to order linker script symbol. | ||
| 5 | |||
| 6 | # RUN: echo "bar" > %t.ord | ||
| 7 | # RUN: echo "SECTIONS { bar = 1; }" > %t.script | ||
| 8 | # RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t.script \ | ||
| 9 | # RUN: -o %t.out 2>&1 | FileCheck %s | ||
| 10 | # CHECK: warning: <internal>: unable to order absolute symbol: bar | ||
| 11 | |||
| 12 | ## Check we do not crash when trying to order --defsym symbol. | ||
| 13 | |||
| 14 | # RUN: echo "bar" > %t.ord | ||
| 15 | # RUN: ld.lld --symbol-ordering-file %t.ord %t.o -defsym=bar=1 \ | ||
| 16 | # RUN: -o %t.out 2>&1 | FileCheck %s | ||
deps/lld/test/ELF/linkerscript/symbols-non-alloc.s deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | |||
| 4 | # RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \ | ||
| 5 | # RUN: .text : { *(.text) } \ | ||
| 6 | # RUN: .nonalloc : { *(.nonalloc) } \ | ||
| 7 | # RUN: Sym = .; \ | ||
| 8 | # RUN: }" > %t.script | ||
| 9 | # RUN: ld.lld -o %t2 --script %t.script %t | ||
| 10 | # RUN: llvm-objdump -section-headers -t %t2 | FileCheck %s | ||
| 11 | |||
| 12 | # CHECK: Sections: | ||
| 13 | # CHECK: .nonalloc 00000008 0000000000000000 | ||
| 14 | |||
| 15 | # CHECK: SYMBOL TABLE: | ||
| 16 | # CHECK: 0000000000000008 .nonalloc 00000000 Sym | ||
| 17 | |||
| 18 | .section .nonalloc,"" | ||
| 19 | .quad 0 | ||
deps/lld/test/ELF/linkerscript/symbols-non-alloc.test created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: echo '.section .nonalloc,""; .quad 0' \ | ||
| 3 | # RUN: | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t | ||
| 4 | # RUN: ld.lld -o %t2 --script %s %t | ||
| 5 | # RUN: llvm-objdump -section-headers -t %t2 | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: Sections: | ||
| 8 | # CHECK: .nonalloc 00000008 0000000000000000 | ||
| 9 | |||
| 10 | # CHECK: SYMBOL TABLE: | ||
| 11 | # CHECK: 0000000000000008 .nonalloc 00000000 Sym | ||
| 12 | |||
| 13 | SECTIONS { | ||
| 14 | . = SIZEOF_HEADERS; | ||
| 15 | .text : { *(.text) } | ||
| 16 | .nonalloc : { *(.nonalloc) } | ||
| 17 | Sym = .; | ||
| 18 | } | ||
deps/lld/test/ELF/linkerscript/symbols-synthetic.s deleted-98| ... | @@ -1,98 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # Simple symbol assignment within input section list. The '.' symbol | ||
| 4 | # is not location counter but offset from the beginning of output | ||
| 5 | # section .foo | ||
| 6 | # RUN: echo "SECTIONS { \ | ||
| 7 | # RUN: . = SIZEOF_HEADERS; \ | ||
| 8 | # RUN: .foo : { \ | ||
| 9 | # RUN: begin_foo = .; \ | ||
| 10 | # RUN: PROVIDE(_begin_sec = .); \ | ||
| 11 | # RUN: *(.foo) \ | ||
| 12 | # RUN: end_foo = .; \ | ||
| 13 | # RUN: PROVIDE_HIDDEN(_end_sec = .); \ | ||
| 14 | # RUN: PROVIDE(_end_sec_abs = ABSOLUTE(.)); \ | ||
| 15 | # RUN: size_foo_1 = SIZEOF(.foo); \ | ||
| 16 | # RUN: size_foo_1_abs = ABSOLUTE(SIZEOF(.foo)); \ | ||
| 17 | # RUN: . = ALIGN(0x1000); \ | ||
| 18 | # RUN: begin_bar = .; \ | ||
| 19 | # RUN: *(.bar) \ | ||
| 20 | # RUN: end_bar = .; \ | ||
| 21 | # RUN: size_foo_2 = SIZEOF(.foo); } \ | ||
| 22 | # RUN: size_foo_3 = SIZEOF(.foo); \ | ||
| 23 | # RUN: .eh_frame_hdr : { \ | ||
| 24 | # RUN: __eh_frame_hdr_start = .; \ | ||
| 25 | # RUN: __eh_frame_hdr_start2 = ABSOLUTE(ALIGN(0x10)); \ | ||
| 26 | # RUN: *(.eh_frame_hdr) \ | ||
| 27 | # RUN: __eh_frame_hdr_end = .; \ | ||
| 28 | # RUN: __eh_frame_hdr_end2 = ABSOLUTE(ALIGN(0x10)); } \ | ||
| 29 | # RUN: .eh_frame : { } \ | ||
| 30 | # RUN: }" > %t.script | ||
| 31 | # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t | ||
| 32 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=SIMPLE %s | ||
| 33 | |||
| 34 | # Check that the following script is processed without errors | ||
| 35 | # RUN: echo "SECTIONS { \ | ||
| 36 | # RUN: .eh_frame_hdr : { \ | ||
| 37 | # RUN: PROVIDE_HIDDEN(_begin_sec = .); \ | ||
| 38 | # RUN: *(.eh_frame_hdr) \ | ||
| 39 | # RUN: *(.eh_frame_hdr) \ | ||
| 40 | # RUN: PROVIDE_HIDDEN(_end_sec_abs = ABSOLUTE(.)); \ | ||
| 41 | # RUN: PROVIDE_HIDDEN(_end_sec = .); } \ | ||
| 42 | # RUN: }" > %t.script | ||
| 43 | # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t | ||
| 44 | |||
| 45 | # Check that we can specify synthetic symbols without defining SECTIONS. | ||
| 46 | # RUN: echo "PROVIDE_HIDDEN(_begin_sec = _start); \ | ||
| 47 | # RUN: PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text));" > %t.script | ||
| 48 | # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t | ||
| 49 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=NO-SEC %s | ||
| 50 | |||
| 51 | # Check that we can do the same as above inside SECTIONS block. | ||
| 52 | # RUN: echo "SECTIONS { \ | ||
| 53 | # RUN: . = 0x201000; \ | ||
| 54 | # RUN: .text : { *(.text) } \ | ||
| 55 | # RUN: PROVIDE_HIDDEN(_begin_sec = ADDR(.text)); \ | ||
| 56 | # RUN: PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text)); }" > %t.script | ||
| 57 | # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t | ||
| 58 | # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=IN-SEC %s | ||
| 59 | |||
| 60 | # SIMPLE: 0000000000000128 .foo 00000000 .hidden _end_sec | ||
| 61 | # SIMPLE-NEXT: 0000000000000120 .foo 00000000 _begin_sec | ||
| 62 | # SIMPLE-NEXT: 0000000000000128 *ABS* 00000000 _end_sec_abs | ||
| 63 | # SIMPLE-NEXT: 0000000000001048 .text 00000000 _start | ||
| 64 | # SIMPLE-NEXT: 0000000000000120 .foo 00000000 begin_foo | ||
| 65 | # SIMPLE-NEXT: 0000000000000128 .foo 00000000 end_foo | ||
| 66 | # SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1 | ||
| 67 | # SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1_abs | ||
| 68 | # SIMPLE-NEXT: 0000000000001000 .foo 00000000 begin_bar | ||
| 69 | # SIMPLE-NEXT: 0000000000001004 .foo 00000000 end_bar | ||
| 70 | # SIMPLE-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_2 | ||
| 71 | # SIMPLE-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_3 | ||
| 72 | # SIMPLE-NEXT: 0000000000001004 .eh_frame_hdr 00000000 __eh_frame_hdr_start | ||
| 73 | # SIMPLE-NEXT: 0000000000001010 *ABS* 00000000 __eh_frame_hdr_start2 | ||
| 74 | # SIMPLE-NEXT: 0000000000001018 .eh_frame_hdr 00000000 __eh_frame_hdr_end | ||
| 75 | # SIMPLE-NEXT: 0000000000001020 *ABS* 00000000 __eh_frame_hdr_end2 | ||
| 76 | |||
| 77 | # NO-SEC: 0000000000201000 .text 00000000 .hidden _begin_sec | ||
| 78 | # NO-SEC-NEXT: 0000000000201001 .text 00000000 .hidden _end_sec | ||
| 79 | |||
| 80 | # IN-SEC: 0000000000201000 .text 00000000 .hidden _begin_sec | ||
| 81 | # IN-SEC-NEXT: 0000000000201001 .text 00000000 .hidden _end_sec | ||
| 82 | |||
| 83 | .global _start | ||
| 84 | _start: | ||
| 85 | nop | ||
| 86 | |||
| 87 | .section .foo,"a" | ||
| 88 | .quad 0 | ||
| 89 | |||
| 90 | .section .bar,"a" | ||
| 91 | .long 0 | ||
| 92 | |||
| 93 | .section .dah,"ax",@progbits | ||
| 94 | .cfi_startproc | ||
| 95 | nop | ||
| 96 | .cfi_endproc | ||
| 97 | |||
| 98 | .global _begin_sec, _end_sec, _end_sec_abs | ||
deps/lld/test/ELF/linkerscript/synthetic-relsec-layout.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "SECTIONS { .foo : { *(.rela.dyn) } }" > %t.script | ||
| 4 | # RUN: ld.lld -T %t.script %t.o -o %t.so -shared | ||
| 5 | # RUN: llvm-readobj -r %t.so | FileCheck %s | ||
| 6 | |||
| 7 | # Check we are able to do custom layout for synthetic sections. | ||
| 8 | # (here we check we can place synthetic .rela.dyn into .foo). | ||
| 9 | |||
| 10 | # CHECK: Relocations [ | ||
| 11 | # CHECK: Section ({{.*}}) .foo { | ||
| 12 | # CHECK: R_X86_64_64 .foo 0x0 | ||
| 13 | # CHECK: } | ||
| 14 | |||
| 15 | .data | ||
| 16 | .quad .foo | ||
deps/lld/test/ELF/linkerscript/synthetic-symbols1.test created+56| ... | @@ -0,0 +1,56 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/synthetic-symbols.s -o %t | ||
| 3 | # RUN: ld.lld -o %t.exe --eh-frame-hdr --script %s %t | ||
| 4 | # RUN: llvm-objdump -t %t.exe | FileCheck %s | ||
| 5 | |||
| 6 | # Simple symbol assignment within input section list. The '.' symbol | ||
| 7 | # is not location counter but offset from the beginning of output | ||
| 8 | # section .foo | ||
| 9 | |||
| 10 | SECTIONS { | ||
| 11 | . = SIZEOF_HEADERS; | ||
| 12 | .foo : { | ||
| 13 | begin_foo = .; | ||
| 14 | PROVIDE(_begin_sec = .); | ||
| 15 | *(.foo) | ||
| 16 | end_foo = .; | ||
| 17 | PROVIDE_HIDDEN(_end_sec = .); | ||
| 18 | PROVIDE(_end_sec_abs = ABSOLUTE(.)); | ||
| 19 | size_foo_1 = SIZEOF(.foo); | ||
| 20 | size_foo_1_abs = ABSOLUTE(SIZEOF(.foo)); | ||
| 21 | . = ALIGN(0x1000); | ||
| 22 | begin_bar = .; | ||
| 23 | *(.bar) | ||
| 24 | end_bar = .; | ||
| 25 | size_foo_2 = SIZEOF(.foo); | ||
| 26 | } | ||
| 27 | |||
| 28 | size_foo_3 = SIZEOF(.foo); | ||
| 29 | |||
| 30 | .eh_frame_hdr : { | ||
| 31 | __eh_frame_hdr_start = .; | ||
| 32 | __eh_frame_hdr_start2 = ABSOLUTE(ALIGN(0x10)); | ||
| 33 | *(.eh_frame_hdr) | ||
| 34 | __eh_frame_hdr_end = .; | ||
| 35 | __eh_frame_hdr_end2 = ABSOLUTE(ALIGN(0x10)); | ||
| 36 | } | ||
| 37 | |||
| 38 | .eh_frame : {} | ||
| 39 | } | ||
| 40 | |||
| 41 | # CHECK: 0000000000000128 .foo 00000000 .hidden _end_sec | ||
| 42 | # CHECK-NEXT: 0000000000000120 .foo 00000000 _begin_sec | ||
| 43 | # CHECK-NEXT: 0000000000000128 *ABS* 00000000 _end_sec_abs | ||
| 44 | # CHECK-NEXT: 000000000000104c .text 00000000 _start | ||
| 45 | # CHECK-NEXT: 0000000000000120 .foo 00000000 begin_foo | ||
| 46 | # CHECK-NEXT: 0000000000000128 .foo 00000000 end_foo | ||
| 47 | # CHECK-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1 | ||
| 48 | # CHECK-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1_abs | ||
| 49 | # CHECK-NEXT: 0000000000001000 .foo 00000000 begin_bar | ||
| 50 | # CHECK-NEXT: 0000000000001004 .foo 00000000 end_bar | ||
| 51 | # CHECK-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_2 | ||
| 52 | # CHECK-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_3 | ||
| 53 | # CHECK-NEXT: 0000000000001004 .eh_frame_hdr 00000000 __eh_frame_hdr_start | ||
| 54 | # CHECK-NEXT: 0000000000001010 *ABS* 00000000 __eh_frame_hdr_start2 | ||
| 55 | # CHECK-NEXT: 0000000000001018 .eh_frame_hdr 00000000 __eh_frame_hdr_end | ||
| 56 | # CHECK-NEXT: 0000000000001020 *ABS* 00000000 __eh_frame_hdr_end2 | ||
deps/lld/test/ELF/linkerscript/synthetic-symbols2.test created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/synthetic-symbols.s -o %t | ||
| 3 | # RUN: ld.lld -o %t.exe --eh-frame-hdr --script %s %t | ||
| 4 | |||
| 5 | SECTIONS { | ||
| 6 | .eh_frame_hdr : { | ||
| 7 | PROVIDE_HIDDEN(_begin_sec = .); | ||
| 8 | *(.eh_frame_hdr) | ||
| 9 | *(.eh_frame_hdr) | ||
| 10 | PROVIDE_HIDDEN(_end_sec_abs = ABSOLUTE(.)); | ||
| 11 | PROVIDE_HIDDEN(_end_sec = .); | ||
| 12 | } | ||
| 13 | } | ||
deps/lld/test/ELF/linkerscript/synthetic-symbols3.test created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/synthetic-symbols.s -o %t | ||
| 3 | # RUN: ld.lld -o %t.exe --eh-frame-hdr --script %s %t | ||
| 4 | # RUN: llvm-objdump -t %t.exe | FileCheck %s | ||
| 5 | |||
| 6 | # Check that we can specify synthetic symbols without defining SECTIONS. | ||
| 7 | PROVIDE_HIDDEN(_begin_sec = _start); | ||
| 8 | PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text)); | ||
| 9 | |||
| 10 | # CHECK: 0000000000201000 .text 00000000 .hidden _begin_sec | ||
| 11 | # CHECK-NEXT: 0000000000201001 .text 00000000 .hidden _end_sec | ||
deps/lld/test/ELF/linkerscript/synthetic-symbols4.test created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/synthetic-symbols.s -o %t.o | ||
| 3 | # RUN: ld.lld -o %t --eh-frame-hdr --script %s %t.o | ||
| 4 | # RUN: llvm-objdump -t %t | FileCheck %s | ||
| 5 | |||
| 6 | SECTIONS { | ||
| 7 | . = 0x201000; | ||
| 8 | .text : { *(.text) } | ||
| 9 | PROVIDE_HIDDEN(_begin_sec = ADDR(.text)); | ||
| 10 | PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text)); | ||
| 11 | } | ||
| 12 | |||
| 13 | # CHECK: 0000000000201054 .text 00000000 .hidden _begin_sec | ||
| 14 | # CHECK-NEXT: 0000000000201055 .text 00000000 .hidden _end_sec | ||
deps/lld/test/ELF/linkerscript/unused-synthetic.s+3-3| ... | @@ -1,17 +1,17 @@ | ... | @@ -1,17 +1,17 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | # RUN: echo "SECTIONS { \ | 3 | # RUN: echo "SECTIONS { \ |
| 4 | # RUN: .got : { *(.got) } \ | 4 | # RUN: .got : { *(.got) *(.got) } \ |
| 5 | # RUN: .plt : { *(.plt) } \ | 5 | # RUN: .plt : { *(.plt) } \ |
| 6 | # RUN: .text : { *(.text) } \ | 6 | # RUN: .text : { *(.text) } \ |
| 7 | # RUN: }" > %t.script | 7 | # RUN: }" > %t.script |
| 8 | # RUN: ld.lld -shared -o %t.so --script %t.script %t.o | 8 | # RUN: ld.lld -shared -o %t.so --script %t.script %t.o |
| 9 | 9 | ||
| 10 | # RUN: llvm-objdump -section-headers %t.so | FileCheck %s | 10 | # RUN: llvm-readelf -s %t.so | FileCheck %s |
| 11 | # CHECK-NOT: .got | 11 | # CHECK-NOT: .got |
| 12 | # CHECK-NOT: .plt | 12 | # CHECK-NOT: .plt |
| 13 | # CHECK: .dynsym | ||
| 13 | # CHECK: .text | 14 | # CHECK: .text |
| 14 | # CHECK-NEXT: .dynsym | ||
| 15 | 15 | ||
| 16 | # Test that the size of a removed unused synthetic input section is not added | 16 | # Test that the size of a removed unused synthetic input section is not added |
| 17 | # to the output section size. Adding a symbol assignment prevents removal of | 17 | # to the output section size. Adding a symbol assignment prevents removal of |
deps/lld/test/ELF/linkerscript/unused-synthetic2.test created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | # REQUIRES: arm | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=armv7-unknown-linux-gnueabi /dev/null -o %t.o | ||
| 3 | |||
| 4 | ## We incorrectly removed unused synthetic sections and crashed before. | ||
| 5 | ## Check we do not crash and do not produce .trap output section. | ||
| 6 | # RUN: ld.lld -shared -o %t.so --script %s %t.o | ||
| 7 | # RUN: llvm-objdump -section-headers %t.so | FileCheck %s | ||
| 8 | # CHECK-NOT: .trap | ||
| 9 | |||
| 10 | SECTIONS { | ||
| 11 | .trap : { *(.ARM.exidx) *(.dummy) } | ||
| 12 | } | ||
deps/lld/test/ELF/linkerscript/va.s+4-4| ... | @@ -5,11 +5,11 @@ | ... | @@ -5,11 +5,11 @@ |
| 5 | # RUN: ld.lld -o %t1 --script %t.script %t | 5 | # RUN: ld.lld -o %t1 --script %t.script %t |
| 6 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s | 6 | # RUN: llvm-objdump -section-headers %t1 | FileCheck %s |
| 7 | # CHECK: Sections: | 7 | # CHECK: Sections: |
| 8 | # CHECK-NEXT: Idx Name Size Address Type | 8 | # CHECK-NEXT: Idx Name Size Address |
| 9 | # CHECK-NEXT: 0 00000000 0000000000000000 | 9 | # CHECK-NEXT: 0 00000000 0000000000000000 |
| 10 | # CHECK-NEXT: 1 .text 00000001 0000000000000000 TEXT DATA | 10 | # CHECK-NEXT: 1 .foo 00000004 0000000000000000 |
| 11 | # CHECK-NEXT: 2 .foo 00000004 0000000000000001 DATA | 11 | # CHECK-NEXT: 2 .boo 00000004 0000000000000004 |
| 12 | # CHECK-NEXT: 3 .boo 00000004 0000000000000005 DATA | 12 | # CHECK-NEXT: 3 .text 00000001 0000000000000008 |
| 13 | 13 | ||
| 14 | .global _start | 14 | .global _start |
| 15 | _start: | 15 | _start: |
deps/lld/test/ELF/linkerscript/version-script.s created+57| ... | @@ -0,0 +1,57 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | |||
| 4 | # RUN: echo "bar = foo; VERSION { V { global: foo; bar; local: *; }; }" > %t.script | ||
| 5 | # RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so | ||
| 6 | # RUN: llvm-readobj -V %t.so | FileCheck %s | ||
| 7 | |||
| 8 | # RUN: echo "SECTIONS { .text : { bar = foo; *(.text) } }" > %t.script | ||
| 9 | # RUN: echo "VERSION { V { global: foo; bar; local: *; }; }" >> %t.script | ||
| 10 | # RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so | ||
| 11 | # RUN: llvm-readobj -V %t.so | FileCheck %s | ||
| 12 | |||
| 13 | ## Check that we are able to version symbols defined in script. | ||
| 14 | # CHECK: Symbols [ | ||
| 15 | # CHECK-NEXT: Symbol { | ||
| 16 | # CHECK-NEXT: Version: 0 | ||
| 17 | # CHECK-NEXT: Name: @ | ||
| 18 | # CHECK-NEXT: } | ||
| 19 | # CHECK-NEXT: Symbol { | ||
| 20 | # CHECK-NEXT: Version: 0 | ||
| 21 | # CHECK-NEXT: Name: und@ | ||
| 22 | # CHECK-NEXT: } | ||
| 23 | # CHECK-NEXT: Symbol { | ||
| 24 | # CHECK-NEXT: Version: 2 | ||
| 25 | # CHECK-NEXT: Name: foo@@V | ||
| 26 | # CHECK-NEXT: } | ||
| 27 | # CHECK-NEXT: Symbol { | ||
| 28 | # CHECK-NEXT: Version: 2 | ||
| 29 | # CHECK-NEXT: Name: bar@@V | ||
| 30 | # CHECK-NEXT: } | ||
| 31 | # CHECK-NEXT: ] | ||
| 32 | |||
| 33 | # RUN: echo "bar = und; VERSION { V { global: foo; bar; local: *; }; }" > %t.script | ||
| 34 | # RUN: not ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so \ | ||
| 35 | # RUN: 2>&1 | FileCheck --check-prefix=ERR %s | ||
| 36 | # ERR: symbol not found: und | ||
| 37 | |||
| 38 | # RUN: echo "und = 0x1; VERSION { V { global: und; local: *; }; }" > %t.script | ||
| 39 | # RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so | ||
| 40 | # RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=UNDEF | ||
| 41 | # UNDEF: Symbols [ | ||
| 42 | # UNDEF-NEXT: Symbol { | ||
| 43 | # UNDEF-NEXT: Version: 0 | ||
| 44 | # UNDEF-NEXT: Name: @ | ||
| 45 | # UNDEF-NEXT: } | ||
| 46 | # UNDEF-NEXT: Symbol { | ||
| 47 | # UNDEF-NEXT: Version: 2 | ||
| 48 | # UNDEF-NEXT: Name: und@@V | ||
| 49 | # UNDEF-NEXT: } | ||
| 50 | # UNDEF-NEXT: ] | ||
| 51 | |||
| 52 | .global und | ||
| 53 | |||
| 54 | .text | ||
| 55 | .globl foo | ||
| 56 | .type foo,@function | ||
| 57 | foo: | ||
deps/lld/test/ELF/llvm33-rela-outside-group.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // Input file generated with: | 1 | // Input file generated with: |
| 2 | // llvm33/llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %S/Inputs/llvm33-rela-outside-group.o | 2 | // llvm33/llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %S/Inputs/llvm33-rela-outside-group.o |
| 3 | // | 3 | // |
| 4 | // RUN: ld.lld -shared %S/Inputs/llvm33-rela-outside-group.o %S/Inputs/llvm33-rela-outside-group.o | 4 | // RUN: ld.lld -shared %S/Inputs/llvm33-rela-outside-group.o %S/Inputs/llvm33-rela-outside-group.o -o /dev/null |
| 5 | 5 | ||
| 6 | 	.global bar | 6 | 	.global bar |
| 7 | 	.weak	_Z3fooIiEvv | 7 | 	.weak	_Z3fooIiEvv |
deps/lld/test/ELF/local-dynamic.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // Check that local symbols are not inserted into dynamic table. | 2 | // Check that local symbols are not inserted into dynamic table. |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | // RUN: ld.lld %t -shared -o %t1.so | 4 | // RUN: ld.lld %t -shared -o %t1.so |
| 4 | // RUN: llvm-readobj -t -dyn-symbols %t1.so | FileCheck %s | 5 | // RUN: llvm-readobj -t -dyn-symbols %t1.so | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // CHECK: Symbols [ | 7 | // CHECK: Symbols [ |
| 8 | // CHECK-NEXT: Symbol { | 8 | // CHECK-NEXT: Symbol { |
deps/lld/test/ELF/local-got-pie.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t -pie | 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t -pie |
| 3 | // RUN: llvm-readobj -s -r -d %t | FileCheck %s | 4 | // RUN: llvm-readobj -s -r -d %t | FileCheck %s |
deps/lld/test/ELF/local-got-shared.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld --hash-style=sysv %t.o -o %t -shared | 3 | // RUN: ld.lld --hash-style=sysv %t.o -o %t -shared |
| 3 | // RUN: llvm-readobj -s -r -d %t | FileCheck %s | 4 | // RUN: llvm-readobj -s -r -d %t | FileCheck %s |
deps/lld/test/ELF/local-got.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
deps/lld/test/ELF/local-symbols-order.s created+37| ... | @@ -0,0 +1,37 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: echo '.data; .file "file2"; foo2:; .global bar2; .hidden bar2; bar2:' > %t2.s | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 6 | |||
| 7 | # RUN: ld.lld -o %t %t1.o %t2.o --emit-relocs | ||
| 8 | # RUN: llvm-readobj -symbols -sections -elf-output-style=GNU %t | FileCheck %s | ||
| 9 | |||
| 10 | ## Check we sort local symbols to match the following order: | ||
| 11 | ## file1, local1, section1, hidden1, file2, local2, section2, hidden2 ... | ||
| 12 | |||
| 13 | # CHECK: Section Headers: | ||
| 14 | # CHECK: [Nr] Name | ||
| 15 | # CHECK: [ [[ST:.*]]] .text | ||
| 16 | # CHECK: [ [[SD:.*]]] .data | ||
| 17 | # CHECK: [ [[SC:.*]]] .comment | ||
| 18 | |||
| 19 | # CHECK: Num: Value Size Type Bind Vis Ndx Name | ||
| 20 | # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND | ||
| 21 | # CHECK-NEXT: 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS file1 | ||
| 22 | # CHECK-NEXT: 2: 0000000000201000 0 NOTYPE LOCAL DEFAULT 1 foo1 | ||
| 23 | # CHECK-NEXT: 3: 0000000000201000 0 SECTION LOCAL DEFAULT [[ST]] | ||
| 24 | # CHECK-NEXT: 4: 0000000000201000 0 NOTYPE LOCAL HIDDEN 1 bar1 | ||
| 25 | # CHECK-NEXT: 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS file2 | ||
| 26 | # CHECK-NEXT: 6: 0000000000201000 0 NOTYPE LOCAL DEFAULT 2 foo2 | ||
| 27 | # CHECK-NEXT: 7: 0000000000201000 0 SECTION LOCAL DEFAULT [[SD]] | ||
| 28 | # CHECK-NEXT: 8: 0000000000201000 0 NOTYPE LOCAL HIDDEN 2 bar2 | ||
| 29 | # CHECK-NEXT: 9: 0000000000000000 0 SECTION LOCAL DEFAULT [[SC]] | ||
| 30 | |||
| 31 | foo1: | ||
| 32 | |||
| 33 | .global bar1 | ||
| 34 | .hidden bar1 | ||
| 35 | bar1: | ||
| 36 | |||
| 37 | .file "file1" | ||
deps/lld/test/ELF/local.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // Check that symbol table is correctly populated with local symbols. | 2 | // Check that symbol table is correctly populated with local symbols. |
| 2 | // RUN: llvm-mc -save-temp-labels -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -save-temp-labels -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | // RUN: ld.lld %t -o %t1 | 4 | // RUN: ld.lld %t -o %t1 |
| 4 | // RUN: llvm-readobj -t -s %t1 | FileCheck %s | 5 | // RUN: llvm-readobj -t -s %t1 | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // Check that Info is equal to the number of local symbols. | 7 | // Check that Info is equal to the number of local symbols. |
| 8 | // CHECK: Section { | 8 | // CHECK: Section { |
deps/lld/test/ELF/lto-plugin-ignore.s+4-5| ... | @@ -3,9 +3,8 @@ | ... | @@ -3,9 +3,8 @@ |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 4 | # RUN: ld.lld %t -plugin-opt=/foo/bar -plugin-opt=-fresolution=zed \ | 4 | # RUN: ld.lld %t -plugin-opt=/foo/bar -plugin-opt=-fresolution=zed \ |
| 5 | # RUN: -plugin-opt=-pass-through=-lgcc -plugin-opt=-function-sections \ | 5 | # RUN: -plugin-opt=-pass-through=-lgcc -plugin-opt=-function-sections \ |
| 6 | # RUN: -plugin-opt=-data-sections -o /dev/null | 6 | # RUN: -plugin-opt=-data-sections -plugin-opt=thinlto -o /dev/null |
| 7 | 7 | ||
| 8 | # RUN: not ld.lld %t -plugin-opt=-data-sectionssss \ | 8 | # RUN: not ld.lld %t -plugin-opt=-abc -plugin-opt=-xyz 2>&1 | FileCheck %s |
| 9 | # RUN: -plugin-opt=-function-sectionsss 2>&1 | FileCheck %s | 9 | # CHECK: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-abc' |
| 10 | # CHECK: unknown option: -data-sectionsss | 10 | # CHECK: error: --plugin-opt: ld.lld{{.*}}: Unknown command line argument '-xyz' |
| 11 | # CHECK: unknown option: -function-sectionsss |
deps/lld/test/ELF/lto/Inputs/absolute.s created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | .globl blah | ||
| 2 | blah = 0xdeadbeef | ||
deps/lld/test/ELF/lto/Inputs/archive-3.ll+1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 2 | target triple = "x86_64-unknown-linux-gnu" | 2 | target triple = "x86_64-unknown-linux-gnu" |
| 3 | |||
| 3 | define void @foo() { | 4 | define void @foo() { |
| 4 | ret void | 5 | ret void |
| 5 | } | 6 | } |
deps/lld/test/ELF/lto/Inputs/asmundef.ll created+4| ... | @@ -0,0 +1,4 @@ | ||
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 2 | target triple = "x86_64-unknown-linux-gnu" | ||
| 3 | |||
| 4 | declare void @patatino() | ||
deps/lld/test/ELF/lto/Inputs/common3.ll+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 2 | target triple = "x86_64-unknown-linux-gnu" | 2 | target triple = "x86_64-unknown-linux-gnu" |
| 3 | |||
| 3 | @a = common hidden global i64 0, align 4 | 4 | @a = common hidden global i64 0, align 4 |
deps/lld/test/ELF/lto/Inputs/i386-empty.ll created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 2 | target triple = "i686-linux-gnu" | ||
deps/lld/test/ELF/lto/Inputs/lazy-internal.ll created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 2 | target triple = "x86_64-unknown-linux-gnu" | ||
| 3 | |||
| 4 | define hidden void @bar() { | ||
| 5 | ret void | ||
| 6 | } | ||
deps/lld/test/ELF/lto/Inputs/libcall-archive.ll created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 2 | target triple = "x86_64-unknown-linux-gnu" | ||
| 3 | |||
| 4 | define void @memcpy() { | ||
| 5 | ret void | ||
| 6 | } | ||
deps/lld/test/ELF/lto/Inputs/sample-profile.prof created+1| ... | @@ -0,0 +1 @@ | ||
| 1 | f:0:0 | ||
deps/lld/test/ELF/lto/Inputs/thinlto_empty.ll created+2| ... | @@ -0,0 +1,2 @@ | ||
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 2 | target triple = "x86_64-unknown-linux-gnu" | ||
deps/lld/test/ELF/lto/Inputs/weakodr-visibility.ll created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 2 | target triple = "x86_64-unknown-linux-gnu" | ||
| 3 | |||
| 4 | define weak_odr protected i32 @foo(i8* %this) { | ||
| 5 | ret i32 42 | ||
| 6 | } | ||
deps/lld/test/ELF/lto/abs-resol.ll created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | |||
| 3 | ; RUN: llvm-as %s -o %t.o | ||
| 4 | ; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/absolute.s -o %t2.o -filetype=obj | ||
| 5 | ; RUN: ld.lld %t.o %t2.o -o %t3.out -pie | ||
| 6 | |||
| 7 | ; RUN: echo "blah = 0xdeadfeef;" > %t.script | ||
| 8 | ; RUN: ld.lld %t.o -T%t.script -o %t4.out -pie | ||
| 9 | |||
| 10 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 11 | target triple = "x86_64-unknown-linux-gnu" | ||
| 12 | |||
| 13 | @blah = external global i8, align 1 | ||
| 14 | |||
| 15 | define i8* @_start() { | ||
| 16 | ret i8* @blah | ||
| 17 | } | ||
deps/lld/test/ELF/lto/archive-2.ll+2-2| ... | @@ -3,9 +3,9 @@ | ... | @@ -3,9 +3,9 @@ |
| 3 | ; RUN: rm -f %t.a | 3 | ; RUN: rm -f %t.a |
| 4 | ; RUN: llvm-ar rcs %t.a %t1.o | 4 | ; RUN: llvm-ar rcs %t.a %t1.o |
| 5 | ; RUN: llvm-as %s -o %t2.o | 5 | ; RUN: llvm-as %s -o %t2.o |
| 6 | ; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3 | 6 | ; RUN: ld.lld %t2.o %t.a -o %t3 |
| 7 | ; RUN: llvm-readobj -t %t3 | FileCheck %s | 7 | ; RUN: llvm-readobj -t %t3 | FileCheck %s |
| 8 | ; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared | 8 | ; RUN: ld.lld %t2.o --whole-archive %t.a -o %t3 -shared |
| 9 | ; RUN: llvm-readobj -t %t3 | FileCheck %s | 9 | ; RUN: llvm-readobj -t %t3 | FileCheck %s |
| 10 | 10 | ||
| 11 | ; CHECK: Name: _start ( | 11 | ; CHECK: Name: _start ( |
deps/lld/test/ELF/lto/archive-3.ll+2-2| ... | @@ -2,12 +2,12 @@ | ... | @@ -2,12 +2,12 @@ |
| 2 | ; RUN: llvm-as %S/Inputs/archive-3.ll -o %t1.o | 2 | ; RUN: llvm-as %S/Inputs/archive-3.ll -o %t1.o |
| 3 | ; RUN: llvm-as %s -o %t2.o | 3 | ; RUN: llvm-as %s -o %t2.o |
| 4 | 4 | ||
| 5 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps | 5 | ; RUN: ld.lld %t1.o %t2.o -o %t3 -save-temps |
| 6 | ; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s | 6 | ; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s |
| 7 | 7 | ||
| 8 | ; RUN: rm -f %t.a | 8 | ; RUN: rm -f %t.a |
| 9 | ; RUN: llvm-ar rcs %t.a %t1.o | 9 | ; RUN: llvm-ar rcs %t.a %t1.o |
| 10 | ; RUN: ld.lld -m elf_x86_64 %t.a %t1.o %t2.o -o %t3 -save-temps | 10 | ; RUN: ld.lld %t.a %t1.o %t2.o -o %t3 -save-temps |
| 11 | ; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s | 11 | ; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s |
| 12 | 12 | ||
| 13 | ; CHECK: define internal void @foo() { | 13 | ; CHECK: define internal void @foo() { |
deps/lld/test/ELF/lto/archive-no-index.ll+2-2| ... | @@ -11,8 +11,8 @@ | ... | @@ -11,8 +11,8 @@ |
| 11 | ; RUN: llvm-ar crS %t1.a %t2.o | 11 | ; RUN: llvm-ar crS %t1.a %t2.o |
| 12 | ; RUN: llvm-ar crs %t2.a %t2.o | 12 | ; RUN: llvm-ar crs %t2.a %t2.o |
| 13 | 13 | ||
| 14 | ; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t1.a | 14 | ; RUN: ld.lld -o %t -emain %t1.o %t1.a |
| 15 | ; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t2.a | 15 | ; RUN: ld.lld -o %t -emain %t1.o %t2.a |
| 16 | 16 | ||
| 17 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 17 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 18 | target triple = "x86_64-unknown-linux-gnu" | 18 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/archive.ll+2-2| ... | @@ -3,9 +3,9 @@ | ... | @@ -3,9 +3,9 @@ |
| 3 | ; RUN: rm -f %t.a | 3 | ; RUN: rm -f %t.a |
| 4 | ; RUN: llvm-ar rcs %t.a %t1.o | 4 | ; RUN: llvm-ar rcs %t.a %t1.o |
| 5 | ; RUN: llvm-as %s -o %t2.o | 5 | ; RUN: llvm-as %s -o %t2.o |
| 6 | ; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3 -shared | 6 | ; RUN: ld.lld %t2.o %t.a -o %t3 -shared |
| 7 | ; RUN: llvm-readobj -t %t3 | FileCheck %s | 7 | ; RUN: llvm-readobj -t %t3 | FileCheck %s |
| 8 | ; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared | 8 | ; RUN: ld.lld %t2.o --whole-archive %t.a -o %t3 -shared |
| 9 | ; RUN: llvm-readobj -t %t3 | FileCheck %s | 9 | ; RUN: llvm-readobj -t %t3 | FileCheck %s |
| 10 | 10 | ||
| 11 | ; CHECK: Name: g ( | 11 | ; CHECK: Name: g ( |
deps/lld/test/ELF/lto/asmundef.ll+3-2| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t -save-temps | 3 | ; RUN: llvm-as %S/Inputs/asmundef.ll -o %t2.o |
| 4 | ; RUN: ld.lld %t.o %t2.o -o %t -save-temps | ||
| 4 | ; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s | 5 | ; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s |
| 5 | 6 | ||
| 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| ... | @@ -20,5 +21,5 @@ define void @_start() { | ... | @@ -20,5 +21,5 @@ define void @_start() { |
| 20 | ret void | 21 | ret void |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 23 | ; CHECK: define void @foo | 24 | ; CHECK: define dso_local void @foo |
| 24 | 25 |
deps/lld/test/ELF/lto/available-externally.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t1.o | 2 | ; RUN: llvm-as %s -o %t1.o |
| 3 | ; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o | 3 | ; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o |
| 4 | ; RUN: ld.lld %t1.o %t2.o -m elf_x86_64 -o %t.so -shared -save-temps | 4 | ; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps |
| 5 | ; RUN: llvm-dis < %t.so.0.2.internalize.bc | FileCheck %s | 5 | ; RUN: llvm-dis < %t.so.0.2.internalize.bc | FileCheck %s |
| 6 | 6 | ||
| 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/bitcode-nodatalayout.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: not ld.lld -m elf_x86_64 %t.o -o %t 2>&1 | FileCheck %s | 3 | ; RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | ; CHECK: input module has no datalayout | 5 | ; CHECK: input module has no datalayout |
| 6 | 6 |
deps/lld/test/ELF/lto/cache.ll+1-1| ... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
| 13 | ; RUN: ls %t.cache | count 4 | 13 | ; RUN: ls %t.cache | count 4 |
| 14 | 14 | ||
| 15 | ; Create a file of size 64KB. | 15 | ; Create a file of size 64KB. |
| 16 | ; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo | 16 | ; RUN: "%python" -c "print(' ' * 65536)" > %t.cache/llvmcache-foo |
| 17 | 17 | ||
| 18 | ; This should leave the file in place. | 18 | ; This should leave the file in place. |
| 19 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t3 %t2.o %t.o | 19 | ; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t3 %t2.o %t.o |
deps/lld/test/ELF/lto/codemodel.ll+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %ts -mllvm -code-model=small | 3 | ; RUN: ld.lld %t.o -o %ts -mllvm -code-model=small |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %tl -mllvm -code-model=large | 4 | ; RUN: ld.lld %t.o -o %tl -mllvm -code-model=large |
| 5 | ; RUN: llvm-objdump -d %ts | FileCheck %s --check-prefix=CHECK-SMALL | 5 | ; RUN: llvm-objdump -d %ts | FileCheck %s --check-prefix=CHECK-SMALL |
| 6 | ; RUN: llvm-objdump -d %tl | FileCheck %s --check-prefix=CHECK-LARGE | 6 | ; RUN: llvm-objdump -d %tl | FileCheck %s --check-prefix=CHECK-LARGE |
| 7 | 7 |
deps/lld/test/ELF/lto/combined-lto-object-name.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2 2>&1 | FileCheck %s | 3 | ; RUN: not ld.lld %t.o -o %t2 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | target triple = "x86_64-unknown-linux-gnu" | 5 | target triple = "x86_64-unknown-linux-gnu" |
| 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/comdat.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared | 3 | ; RUN: ld.lld %t.o %t.o -o %t.so -shared |
| 4 | ; RUN: llvm-readobj -t %t.so | FileCheck %s | 4 | ; RUN: llvm-readobj -t %t.so | FileCheck %s |
| 5 | 5 | ||
| 6 | ; CHECK: Name: foo | 6 | ; CHECK: Name: foo |
deps/lld/test/ELF/lto/comdat2.ll+2-2| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj | 3 | ; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared | 4 | ; RUN: ld.lld %t.o %t2.o -o %t.so -shared |
| 5 | ; RUN: llvm-readobj -t %t.so | FileCheck %s | 5 | ; RUN: llvm-readobj -t %t.so | FileCheck %s |
| 6 | ; RUN: ld.lld -m elf_x86_64 %t2.o %t.o -o %t2.so -shared | 6 | ; 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 -t %t2.so | FileCheck %s --check-prefix=OTHER |
| 8 | 8 | ||
| 9 | 9 |
deps/lld/test/ELF/lto/common2.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t1.o | 2 | ; RUN: llvm-as %s -o %t1.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t1.o -o %t -shared -save-temps | 3 | ; RUN: ld.lld %t1.o -o %t -shared -save-temps |
| 4 | ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s | 4 | ; 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 -t %t | FileCheck %s --check-prefix=SHARED |
| 6 | 6 |
deps/lld/test/ELF/lto/common3.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t1.o | 2 | ; RUN: llvm-as %s -o %t1.o |
| 3 | ; RUN: llvm-as %S/Inputs/common3.ll -o %t2.o | 3 | ; RUN: llvm-as %S/Inputs/common3.ll -o %t2.o |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t -shared -save-temps | 4 | ; RUN: ld.lld %t1.o %t2.o -o %t -shared -save-temps |
| 5 | ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s | 5 | ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s |
| 6 | 6 | ||
| 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/cpu-string.ll created+25| ... | @@ -0,0 +1,25 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: llvm-as %s -o %t.o | ||
| 3 | |||
| 4 | ; RUN: ld.lld %t.o -o %t.so -shared | ||
| 5 | ; RUN: llvm-objdump -d -section=".text" -no-leading-addr -no-show-raw-insn %t.so | FileCheck %s | ||
| 6 | ; CHECK: nop{{$}} | ||
| 7 | |||
| 8 | ; RUN: ld.lld -mllvm -mcpu=znver1 %t.o -o %t.znver1.so -shared | ||
| 9 | ; RUN: llvm-objdump -d -section=".text" -no-leading-addr -no-show-raw-insn %t.znver1.so | FileCheck -check-prefix=ZNVER1 %s | ||
| 10 | ; ZNVER1: nopw | ||
| 11 | |||
| 12 | ; Check we are able to use -plugin-opt=mcpu=<CPU> to set CPU string. | ||
| 13 | ; RUN: ld.lld -plugin-opt=mcpu=znver1 %t.o -o %t.znver1.so -shared | ||
| 14 | ; RUN: llvm-objdump -d -section=".text" -no-leading-addr -no-show-raw-insn %t.znver1.so | FileCheck -check-prefix=ZNVER1 %s | ||
| 15 | |||
| 16 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 17 | target triple = "x86_64-unknown-linux-gnu" | ||
| 18 | |||
| 19 | define void @foo() #0 { | ||
| 20 | entry: | ||
| 21 | call void asm sideeffect ".p2align 4, 0x90", "~{dirflag},~{fpsr},~{flags}"() | ||
| 22 | ret void | ||
| 23 | } | ||
| 24 | |||
| 25 | attributes #0 = { "no-frame-pointer-elim"="true" } | ||
deps/lld/test/ELF/lto/ctors.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared | 3 | ; 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 |
| 5 | 5 | ||
| 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/data-ordering-lto.s+7-6| ... | @@ -8,17 +8,18 @@ | ... | @@ -8,17 +8,18 @@ |
| 8 | # RUN: echo "pat " >> %t_order_lto.txt | 8 | # RUN: echo "pat " >> %t_order_lto.txt |
| 9 | 9 | ||
| 10 | # RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out | 10 | # RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out |
| 11 | # RUN: llvm-readobj -elf-output-style=GNU -t %t2.out| FileCheck %s | 11 | # RUN: llvm-readelf -t %t2.out| FileCheck %s |
| 12 | 12 | ||
| 13 | # Check that the order is tin -> dipsy -> pat. | 13 | # Check that the order is tin -> dipsy -> pat. |
| 14 | 14 | ||
| 15 | # CHECK: Symbol table '.symtab' contains 5 entries: | 15 | # CHECK: Symbol table '.symtab' contains 6 entries: |
| 16 | # CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name | 16 | # CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name |
| 17 | # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND | 17 | # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND |
| 18 | # CHECK-NEXT: 1: 0000000000201000 0 NOTYPE GLOBAL DEFAULT 1 _start | 18 | # CHECK-NEXT: 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS {{.*}}.o |
| 19 | # CHECK-NEXT: 2: 0000000000202004 4 OBJECT GLOBAL DEFAULT 2 dipsy | 19 | # CHECK-NEXT: 2: 0000000000201000 0 NOTYPE GLOBAL DEFAULT 1 _start |
| 20 | # CHECK-NEXT: 3: 0000000000202008 4 OBJECT GLOBAL DEFAULT 2 pat | 20 | # CHECK-NEXT: 3: 0000000000202004 4 OBJECT GLOBAL DEFAULT 2 dipsy |
| 21 | # CHECK-NEXT: 4: 0000000000202000 4 OBJECT GLOBAL DEFAULT 2 tin | 21 | # CHECK-NEXT: 4: 0000000000202008 4 OBJECT GLOBAL DEFAULT 2 pat |
| 22 | # CHECK-NEXT: 5: 0000000000202000 4 OBJECT GLOBAL DEFAULT 2 tin | ||
| 22 | 23 | ||
| 23 | .globl _start | 24 | .globl _start |
| 24 | _start: | 25 | _start: |
deps/lld/test/ELF/lto/debugger-tune.ll created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: llvm-as %s -o %t.o | ||
| 3 | |||
| 4 | ; Here we verify that -debugger-tune=<value> option is | ||
| 5 | ; handled by LLD. DWARF linkage name attributes are optional, | ||
| 6 | ; they normally present, but are missing for SCE debugger tune. | ||
| 7 | |||
| 8 | ; RUN: ld.lld %t.o -o %t.exe | ||
| 9 | ; RUN: llvm-dwarfdump %t.exe | FileCheck %s | ||
| 10 | ; CHECK: DW_AT_linkage_name ("name_of_foo") | ||
| 11 | |||
| 12 | ; RUN: ld.lld -plugin-opt=-debugger-tune=sce %t.o -o %t.exe | ||
| 13 | ; RUN: llvm-dwarfdump %t.exe | FileCheck --check-prefix=SCE %s | ||
| 14 | ; SCE-NOT: name_of_foo | ||
| 15 | |||
| 16 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 17 | target triple = "x86_64-unknown-linux-gnu" | ||
| 18 | |||
| 19 | @foo = global i32 0, align 4, !dbg !0 | ||
| 20 | |||
| 21 | !llvm.dbg.cu = !{!5} | ||
| 22 | !llvm.module.flags = !{!8, !9} | ||
| 23 | |||
| 24 | !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) | ||
| 25 | !1 = distinct !DIGlobalVariable(name: "global_foo", linkageName: "name_of_foo", scope: !2, | ||
| 26 | file: !3, line: 2, type: !4, isLocal: false, isDefinition: true) | ||
| 27 | !2 = !DINamespace(name: "test", scope: null) | ||
| 28 | !3 = !DIFile(filename: "test.cpp", directory: "/home/tests") | ||
| 29 | !4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) | ||
| 30 | !5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang", | ||
| 31 | isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !6, globals: !7) | ||
| 32 | !6 = !{} | ||
| 33 | !7 = !{!0} | ||
| 34 | !8 = !{i32 2, !"Dwarf Version", i32 4} | ||
| 35 | !9 = !{i32 2, !"Debug Info Version", i32 3} | ||
deps/lld/test/ELF/lto/defsym.ll+7-3| ... | @@ -2,14 +2,18 @@ | ... | @@ -2,14 +2,18 @@ |
| 2 | ; LTO | 2 | ; LTO |
| 3 | ; RUN: llvm-as %s -o %t.o | 3 | ; RUN: llvm-as %s -o %t.o |
| 4 | ; RUN: llvm-as %S/Inputs/defsym-bar.ll -o %t1.o | 4 | ; RUN: llvm-as %S/Inputs/defsym-bar.ll -o %t1.o |
| 5 | ; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3 | 5 | ; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3 -save-temps |
| 6 | ; RUN: llvm-readelf -t %t.so.lto.o | FileCheck --check-prefix=OBJ %s | ||
| 6 | ; RUN: llvm-objdump -d %t.so | FileCheck %s | 7 | ; RUN: llvm-objdump -d %t.so | FileCheck %s |
| 7 | 8 | ||
| 8 | ; ThinLTO | 9 | ; ThinLTO |
| 9 | ; RUN: opt -module-summary %s -o %t.o | 10 | ; RUN: opt -module-summary %s -o %t.o |
| 10 | ; RUN: opt -module-summary %S/Inputs/defsym-bar.ll -o %t1.o | 11 | ; RUN: opt -module-summary %S/Inputs/defsym-bar.ll -o %t1.o |
| 11 | ; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3 | 12 | ; RUN: ld.lld %t.o %t1.o -shared -o %t2.so -defsym=bar2=bar3 -save-temps |
| 12 | ; RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=THIN | 13 | ; RUN: llvm-readelf -t %t2.so1.lto.o | FileCheck --check-prefix=OBJ %s |
| 14 | ; RUN: llvm-objdump -d %t2.so | FileCheck %s --check-prefix=THIN | ||
| 15 | |||
| 16 | ; OBJ: UND bar2 | ||
| 13 | 17 | ||
| 14 | ; Call to bar2() should not be inlined and should be routed to bar3() | 18 | ; Call to bar2() should not be inlined and should be routed to bar3() |
| 15 | ; Symbol bar3 should not be eliminated | 19 | ; Symbol bar3 should not be eliminated |
deps/lld/test/ELF/lto/discard-value-names.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | 3 | ||
| 4 | ; RUN: ld.lld -m elf_x86_64 -shared -save-temps %t.o -o %t2.o | 4 | ; RUN: ld.lld -shared -save-temps %t.o -o %t2.o |
| 5 | ; RUN: llvm-dis < %t2.o.0.0.preopt.bc | FileCheck %s | 5 | ; RUN: llvm-dis < %t2.o.0.0.preopt.bc | FileCheck %s |
| 6 | 6 | ||
| 7 | ; CHECK: @GlobalValueName | 7 | ; CHECK: @GlobalValueName |
deps/lld/test/ELF/lto/drop-debug-info.ll+2-2| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | ; drop-debug-info.bc was created from "void f(void) {}" with clang 3.5 and | 3 | ; drop-debug-info.bc was created from "void f(void) {}" with clang 3.5 and |
| 4 | ; -gline-tables-only, so it contains old debug info. | 4 | ; -gline-tables-only, so it contains old debug info. |
| 5 | ; | 5 | ; |
| 6 | ; RUN: ld.lld -m elf_x86_64 -shared %p/Inputs/drop-debug-info.bc \ | 6 | ; RUN: ld.lld -shared %p/Inputs/drop-debug-info.bc \ |
| 7 | ; RUN: -disable-verify 2>&1 | FileCheck %s | 7 | ; RUN: -disable-verify -o %t 2>&1 | FileCheck %s |
| 8 | ; CHECK: ignoring debug info with an invalid version (1) in {{.*}}drop-debug-info.bc | 8 | ; CHECK: ignoring debug info with an invalid version (1) in {{.*}}drop-debug-info.bc |
| 9 | 9 |
deps/lld/test/ELF/lto/drop-linkage.ll+3-3| ... | @@ -1,12 +1,12 @@ | ... | @@ -1,12 +1,12 @@ |
| 1 | target triple = "x86_64-unknown-linux-gnu" | ||
| 2 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 3 | |||
| 4 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 5 | ; RUN: llc %s -o %t.o -filetype=obj | 2 | ; RUN: llc %s -o %t.o -filetype=obj |
| 6 | ; RUN: llvm-as %p/Inputs/drop-linkage.ll -o %t2.o | 3 | ; RUN: llvm-as %p/Inputs/drop-linkage.ll -o %t2.o |
| 7 | ; RUN: ld.lld %t.o %t2.o -o %t.so -save-temps -shared | 4 | ; RUN: ld.lld %t.o %t2.o -o %t.so -save-temps -shared |
| 8 | ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s | 5 | ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s |
| 9 | 6 | ||
| 7 | target triple = "x86_64-unknown-linux-gnu" | ||
| 8 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 9 | |||
| 10 | define void @foo() { | 10 | define void @foo() { |
| 11 | ret void | 11 | ret void |
| 12 | } | 12 | } |
deps/lld/test/ELF/lto/duplicated.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: not ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | ; RUN: not ld.lld %t.o %t.o -o %t.so -shared 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | ; CHECK: duplicate symbol: f | 5 | ; CHECK: duplicate symbol: f |
| 6 | ; CHECK-NEXT: >>> defined in {{.*}}.o | 6 | ; CHECK-NEXT: >>> defined in {{.*}}.o |
deps/lld/test/ELF/lto/dynamic-list.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: echo "{ foo; };" > %t.list | 3 | ; RUN: echo "{ foo; };" > %t.list |
| 4 | ; RUN: ld.lld -m elf_x86_64 -o %t --dynamic-list %t.list -pie %t.o | 4 | ; 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-symbols %t | FileCheck %s |
| 6 | 6 | ||
| 7 | ; CHECK: Name: foo@ | 7 | ; CHECK: Name: foo@ |
deps/lld/test/ELF/lto/dynsym.ll+3-3| ... | @@ -1,12 +1,12 @@ | ... | @@ -1,12 +1,12 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t.o %p/Inputs/dynsym.s | 2 | ; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t.o %p/Inputs/dynsym.s |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared | 3 | ; RUN: ld.lld %t.o -o %t.so -shared |
| 4 | ; RUN: llvm-as %s -o %t2.o | 4 | ; RUN: llvm-as %s -o %t2.o |
| 5 | ; RUN: ld.lld -m elf_x86_64 %t2.o %t.so -o %t | 5 | ; RUN: ld.lld %t2.o %t.so -o %t |
| 6 | ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s | 6 | ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s |
| 7 | 7 | ||
| 8 | ; Check that we don't crash when gc'ing sections and printing the result. | 8 | ; Check that we don't crash when gc'ing sections and printing the result. |
| 9 | ; RUN: ld.lld -m elf_x86_64 %t2.o %t.so --gc-sections --print-gc-sections \ | 9 | ; RUN: ld.lld %t2.o %t.so --gc-sections --print-gc-sections \ |
| 10 | ; RUN: -o %t | 10 | ; RUN: -o %t |
| 11 | ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s | 11 | ; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s |
| 12 | 12 |
deps/lld/test/ELF/lto/inline-asm.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared | 3 | ; RUN: ld.lld %t.o -o %t.so -shared |
| 4 | 4 | ||
| 5 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 5 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 6 | target triple = "x86_64-unknown-linux-gnu" | 6 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/internalize-basic.ll+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps | 3 | ; RUN: ld.lld %t.o -o %t2 -save-temps |
| 4 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s | 4 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s |
| 5 | 5 | ||
| 6 | target triple = "x86_64-unknown-linux-gnu" | 6 | target triple = "x86_64-unknown-linux-gnu" |
| ... | @@ -15,7 +15,7 @@ define hidden void @foo() { | ... | @@ -15,7 +15,7 @@ define hidden void @foo() { |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | ; Check that _start is not internalized. | 17 | ; Check that _start is not internalized. |
| 18 | ; CHECK: define void @_start() | 18 | ; CHECK: define dso_local void @_start() |
| 19 | 19 | ||
| 20 | ; Check that foo function is correctly internalized. | 20 | ; Check that foo function is correctly internalized. |
| 21 | ; CHECK: define internal void @foo() | 21 | ; CHECK: define internal void @foo() |
deps/lld/test/ELF/lto/internalize-exportdyn.ll+5-5| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: llvm-as %p/Inputs/internalize-exportdyn.ll -o %t2.o | 3 | ; RUN: llvm-as %p/Inputs/internalize-exportdyn.ll -o %t2.o |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t2 --export-dynamic -save-temps | 4 | ; RUN: ld.lld %t.o %t2.o -o %t2 --export-dynamic -save-temps |
| 5 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s | 5 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s |
| 6 | 6 | ||
| 7 | target triple = "x86_64-unknown-linux-gnu" | 7 | target triple = "x86_64-unknown-linux-gnu" |
| ... | @@ -38,10 +38,10 @@ define linkonce_odr void @baz() { | ... | @@ -38,10 +38,10 @@ define linkonce_odr void @baz() { |
| 38 | @use_baz = global void ()* @baz | 38 | @use_baz = global void ()* @baz |
| 39 | 39 | ||
| 40 | ; Check what gets internalized. | 40 | ; Check what gets internalized. |
| 41 | ; CHECK: define void @_start() | 41 | ; CHECK: define dso_local void @_start() |
| 42 | ; CHECK: define void @foo() | 42 | ; CHECK: define dso_local void @foo() |
| 43 | ; CHECK: define internal void @bar() | 43 | ; CHECK: define internal void @bar() |
| 44 | ; CHECK: define internal void @zed() | 44 | ; CHECK: define internal void @zed() |
| 45 | ; CHECK: define internal void @zed2() | 45 | ; CHECK: define internal void @zed2() |
| 46 | ; CHECK: define weak_odr void @bah() | 46 | ; CHECK: define weak_odr dso_local void @bah() |
| 47 | ; CHECK: define weak_odr void @baz() | 47 | ; CHECK: define weak_odr dso_local void @baz() |
deps/lld/test/ELF/lto/internalize-llvmused.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps | 3 | ; RUN: ld.lld %t.o -o %t2 -save-temps |
| 4 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s | 4 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s |
| 5 | 5 | ||
| 6 | target triple = "x86_64-unknown-linux-gnu" | 6 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/internalize-undef.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: llvm-as %p/Inputs/internalize-undef.ll -o %t2.o | 3 | ; RUN: llvm-as %p/Inputs/internalize-undef.ll -o %t2.o |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -save-temps | 4 | ; RUN: ld.lld %t.o %t2.o -o %t -save-temps |
| 5 | ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s | 5 | ; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s |
| 6 | 6 | ||
| 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/internalize-version-script.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: echo "{ global: foo; local: *; };" > %t.script | 3 | ; RUN: echo "{ global: foo; local: *; };" > %t.script |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps | 4 | ; RUN: ld.lld %t.o -o %t2 -shared --version-script %t.script -save-temps |
| 5 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s | 5 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s |
| 6 | 6 | ||
| 7 | target triple = "x86_64-unknown-linux-gnu" | 7 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/irmover-error.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; RUN: llvm-as -o %t1.bc %s | 1 | ; RUN: llvm-as -o %t1.bc %s |
| 2 | ; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-error.ll | 2 | ; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-error.ll |
| 3 | ; RUN: not ld.lld -m elf_x86_64 %t1.bc %t2.bc -o %t 2>&1 | FileCheck %s | 3 | ; RUN: not ld.lld %t1.bc %t2.bc -o %t 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | ; CHECK: linking module flags 'foo': IDs have conflicting values | 5 | ; CHECK: linking module flags 'foo': IDs have conflicting values |
| 6 | 6 |
deps/lld/test/ELF/lto/keep-undefined.ll+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | ; This test checks that symbols which are specified in "-u" switches | 2 | ; This test checks that symbols which are specified in "-u" switches |
| 3 | ; are kept over LTO if we link an executable. | 3 | ; are kept over LTO if we link an executable. |
| 4 | ; RUN: llvm-as %s -o %t.o | 4 | ; RUN: llvm-as %s -o %t.o |
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %tout -u foo | 5 | ; RUN: ld.lld %t.o -o %tout -u foo |
| 6 | ; RUN: llvm-nm %tout | FileCheck %s | 6 | ; RUN: llvm-nm %tout | FileCheck %s |
| 7 | 7 | ||
| 8 | ; CHECK: T foo | 8 | ; CHECK: T foo |
deps/lld/test/ELF/lto/lazy-internal.ll created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: llvm-as %s -o %t1.o | ||
| 3 | ; RUN: llvm-as %p/Inputs/lazy-internal.ll -o %t2.o | ||
| 4 | ; RUN: rm -f %t2.a | ||
| 5 | ; RUN: llvm-ar rc %t2.a %t2.o | ||
| 6 | ; RUN: ld.lld %t2.a %t1.o -o %t.so -shared -save-temps | ||
| 7 | ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s | ||
| 8 | |||
| 9 | ; CHECK: define internal void @foo() | ||
| 10 | ; CHECK: define internal void @bar() | ||
| 11 | |||
| 12 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 13 | target triple = "x86_64-unknown-linux-gnu" | ||
| 14 | |||
| 15 | define hidden void @foo() { | ||
| 16 | call void @bar() | ||
| 17 | ret void | ||
| 18 | } | ||
| 19 | declare void @bar() | ||
deps/lld/test/ELF/lto/libcall-archive.ll created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | ; RUN: rm -f %t.a | ||
| 2 | ; RUN: llvm-as -o %t.o %s | ||
| 3 | ; RUN: llvm-as -o %t2.o %S/Inputs/libcall-archive.ll | ||
| 4 | ; RUN: llvm-ar rcs %t.a %t2.o | ||
| 5 | ; RUN: ld.lld -o %t %t.o %t.a | ||
| 6 | ; RUN: llvm-nm %t | FileCheck %s | ||
| 7 | |||
| 8 | ; CHECK: T _start | ||
| 9 | ; CHECK: T memcpy | ||
| 10 | |||
| 11 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 12 | target triple = "x86_64-unknown-linux-gnu" | ||
| 13 | |||
| 14 | define void @_start(i8* %a, i8* %b) { | ||
| 15 | entry: | ||
| 16 | call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 1024, i1 false) | ||
| 17 | ret void | ||
| 18 | } | ||
| 19 | |||
| 20 | declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) | ||
deps/lld/test/ELF/lto/linkage.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t1.o | 2 | ; RUN: llvm-as %s -o %t1.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared | 3 | ; RUN: ld.lld %t1.o %t1.o -o %t.so -shared |
| 4 | ; RUN: llvm-nm %t.so | FileCheck %s | 4 | ; RUN: llvm-nm %t.so | FileCheck %s |
| 5 | 5 | ||
| 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/linker-script-symbols-assign.ll+3-12| ... | @@ -2,20 +2,11 @@ | ... | @@ -2,20 +2,11 @@ |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | 3 | ||
| 4 | ; RUN: echo "foo = 1;" > %t.script | 4 | ; RUN: echo "foo = 1;" > %t.script |
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps | 5 | ; 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 |
| 7 | 7 | ||
| 8 | ; CHECK-NOT: bar | 8 | ; CHECK-NOT: bar |
| 9 | ; CHECK: Symbol { | 9 | ; CHECK-NOT: foo |
| 10 | ; CHECK: Name: foo | ||
| 11 | ; CHECK-NEXT: Value: 0x0 | ||
| 12 | ; CHECK-NEXT: Size: 4 | ||
| 13 | ; CHECK-NEXT: Binding: Weak | ||
| 14 | ; CHECK-NEXT: Type: Object | ||
| 15 | ; CHECK-NEXT: Other: 0 | ||
| 16 | ; CHECK-NEXT: Section: .bss.foo | ||
| 17 | ; CHECK-NEXT: } | ||
| 18 | ; CHECK-NEXT:] | ||
| 19 | 10 | ||
| 20 | ; RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=VAL | 11 | ; RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=VAL |
| 21 | ; VAL: Symbol { | 12 | ; VAL: Symbol { |
| ... | @@ -29,7 +20,7 @@ | ... | @@ -29,7 +20,7 @@ |
| 29 | ; VAL-NEXT: } | 20 | ; VAL-NEXT: } |
| 30 | 21 | ||
| 31 | ; RUN: echo "zed = 1;" > %t2.script | 22 | ; RUN: echo "zed = 1;" > %t2.script |
| 32 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t3 --script %t2.script | 23 | ; RUN: ld.lld %t.o -o %t3 --script %t2.script |
| 33 | ; RUN: llvm-readobj -symbols %t3 | FileCheck %s --check-prefix=ABS | 24 | ; RUN: llvm-readobj -symbols %t3 | FileCheck %s --check-prefix=ABS |
| 34 | ; ABS: Symbol { | 25 | ; ABS: Symbol { |
| 35 | ; ABS: Name: zed | 26 | ; ABS: Name: zed |
deps/lld/test/ELF/lto/linker-script-symbols-ipo.ll+4-4| ... | @@ -4,7 +4,7 @@ | ... | @@ -4,7 +4,7 @@ |
| 4 | ; RUN: echo "bar = foo;" > %t.script | 4 | ; RUN: echo "bar = foo;" > %t.script |
| 5 | 5 | ||
| 6 | ;; Check that without linkerscript bar is inlined. | 6 | ;; Check that without linkerscript bar is inlined. |
| 7 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps | 7 | ; RUN: ld.lld %t1.o %t2.o -o %t3 -save-temps |
| 8 | ; RUN: llvm-objdump -d %t3 | FileCheck %s --check-prefix=IPO | 8 | ; RUN: llvm-objdump -d %t3 | FileCheck %s --check-prefix=IPO |
| 9 | ; IPO: Disassembly of section .text: | 9 | ; IPO: Disassembly of section .text: |
| 10 | ; IPO: _start: | 10 | ; IPO: _start: |
| ... | @@ -12,13 +12,13 @@ | ... | @@ -12,13 +12,13 @@ |
| 12 | ; IPO-NEXT: 201005: {{.*}} retq | 12 | ; IPO-NEXT: 201005: {{.*}} retq |
| 13 | 13 | ||
| 14 | ;; Check that LTO does not do IPO for symbols assigned by script. | 14 | ;; Check that LTO does not do IPO for symbols assigned by script. |
| 15 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t4 --script %t.script -save-temps | 15 | ; RUN: ld.lld %t1.o %t2.o -o %t4 --script %t.script -save-temps |
| 16 | ; RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=NOIPO | 16 | ; RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=NOIPO |
| 17 | ; NOIPO: Disassembly of section .text: | 17 | ; NOIPO: Disassembly of section .text: |
| 18 | ; NOIPO: foo: | 18 | ; NOIPO: foo: |
| 19 | ; NOIPO-NEXT: 201010: {{.*}} movl $2, %eax | 19 | ; NOIPO-NEXT: {{.*}} movl $2, %eax |
| 20 | ; NOIPO: _start: | 20 | ; NOIPO: _start: |
| 21 | ; NOIPO-NEXT: 201020: {{.*}} jmp -21 <foo> | 21 | ; NOIPO-NEXT: {{.*}} jmp -21 <foo> |
| 22 | 22 | ||
| 23 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 23 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 24 | target triple = "x86_64-unknown-linux-gnu" | 24 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/linker-script-symbols.ll+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: echo "foo = bar;" > %t.script | 3 | ; RUN: echo "foo = bar;" > %t.script |
| 4 | 4 | ||
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps | 5 | ; 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 |
| 7 | 7 | ||
| 8 | ; CHECK-NOT: zed | 8 | ; CHECK-NOT: zed |
deps/lld/test/ELF/lto/lto-start.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 | 3 | ; RUN: ld.lld %t.o -o %t2 |
| 4 | ; RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | ; RUN: llvm-readobj -t %t2 | FileCheck %s |
| 5 | 5 | ||
| 6 | ; CHECK: Format: ELF64-x86-64 | 6 | ; CHECK: Format: ELF64-x86-64 |
deps/lld/test/ELF/lto/ltopasses-basic.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -mllvm -debug-pass=Arguments -shared 2>&1 | FileCheck %s --check-prefix=MLLVM | 3 | ; RUN: ld.lld %t.o -o %t.so -save-temps -mllvm -debug-pass=Arguments -shared 2>&1 | FileCheck %s --check-prefix=MLLVM |
| 4 | ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s | 4 | ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s |
| 5 | 5 | ||
| 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/ltopasses-custom.ll+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps --lto-aa-pipeline=basic-aa \ | 3 | ; RUN: ld.lld %t.o -o %t.so -save-temps --lto-aa-pipeline=basic-aa \ |
| 4 | ; RUN: --lto-newpm-passes=ipsccp -shared | 4 | ; RUN: --lto-newpm-passes=ipsccp -shared |
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2.so -save-temps --lto-newpm-passes=loweratomic -shared | 5 | ; RUN: ld.lld %t.o -o %t2.so -save-temps --lto-newpm-passes=loweratomic -shared |
| 6 | ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s | 6 | ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s |
| 7 | ; RUN: llvm-dis %t2.so.0.4.opt.bc -o - | FileCheck %s --check-prefix=ATOMIC | 7 | ; RUN: llvm-dis %t2.so.0.4.opt.bc -o - | FileCheck %s --check-prefix=ATOMIC |
| 8 | 8 |
deps/lld/test/ELF/lto/metadata.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t1.o | 2 | ; RUN: llvm-as %s -o %t1.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared | 3 | ; RUN: ld.lld %t1.o %t1.o -o %t.so -shared |
| 4 | 4 | ||
| 5 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 5 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 6 | target triple = "x86_64-unknown-linux-gnu" | 6 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/mix-platforms2.ll created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: llvm-as %s -o %tx64.o | ||
| 3 | ; RUN: llvm-as %S/Inputs/i386-empty.ll -o %ti386.o | ||
| 4 | ; RUN: not ld.lld %ti386.o %tx64.o -o %t.out 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | ; CHECK: {{.*}}x64.o is incompatible with {{.*}}i386.o | ||
| 7 | |||
| 8 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 9 | target triple = "x86_64-unknown-linux-gnu" | ||
deps/lld/test/ELF/lto/module-asm.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t | 3 | ; RUN: ld.lld %t.o -o %t |
| 4 | ; RUN: llvm-nm %t | FileCheck %s | 4 | ; RUN: llvm-nm %t | FileCheck %s |
| 5 | 5 | ||
| 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/new-pass-manager.ll created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: opt -module-summary %s -o %t.o | ||
| 3 | |||
| 4 | ; Test new-pass-manager and debug-pass-manager option | ||
| 5 | ; RUN: ld.lld --plugin-opt=new-pass-manager --plugin-opt=debug-pass-manager -o %t2.o %t.o 2>&1 | FileCheck %s | ||
| 6 | ; RUN: ld.lld --plugin-opt=new-pass-manager --lto-debug-pass-manager -o %t2.o %t.o 2>&1 | FileCheck %s | ||
| 7 | ; RUN: ld.lld --lto-new-pass-manager --plugin-opt=debug-pass-manager -o %t2.o %t.o 2>&1 | FileCheck %s | ||
| 8 | ; RUN: ld.lld --lto-new-pass-manager --lto-debug-pass-manager -o %t2.o %t.o 2>&1 | FileCheck %s | ||
| 9 | |||
| 10 | ; CHECK: Starting llvm::Module pass manager run | ||
| 11 | ; CHECK: Finished llvm::Module pass manager run | ||
| 12 | |||
| 13 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 14 | target triple = "x86_64-unknown-linux-gnu" | ||
deps/lld/test/ELF/lto/opt-level.ll+11-11| ... | @@ -1,30 +1,30 @@ | ... | @@ -1,30 +1,30 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as -o %t.o %s | 2 | ; RUN: llvm-as -o %t.o %s |
| 3 | ; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o | 3 | ; RUN: ld.lld -o %t0 -e main --lto-O0 %t.o |
| 4 | ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s | 4 | ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s |
| 5 | ; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --plugin-opt=O0 %t.o | 5 | ; RUN: ld.lld -o %t0 -e main --plugin-opt=O0 %t.o |
| 6 | ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s | 6 | ; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s |
| 7 | ; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --lto-O2 %t.o | 7 | ; RUN: ld.lld -o %t2 -e main --lto-O2 %t.o |
| 8 | ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s | 8 | ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s |
| 9 | ; RUN: ld.lld -o %t2a -m elf_x86_64 -e main %t.o | 9 | ; RUN: ld.lld -o %t2a -e main %t.o |
| 10 | ; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s | 10 | ; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s |
| 11 | ; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --plugin-opt=O2 %t.o | 11 | ; RUN: ld.lld -o %t2 -e main %t.o --plugin-opt O2 |
| 12 | ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s | 12 | ; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s |
| 13 | 13 | ||
| 14 | ; Reject invalid optimization levels. | 14 | ; Reject invalid optimization levels. |
| 15 | ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O6 %t.o 2>&1 | \ | 15 | ; RUN: not ld.lld -o %t3 -e main --lto-O6 %t.o 2>&1 | \ |
| 16 | ; RUN: FileCheck --check-prefix=INVALID1 %s | 16 | ; RUN: FileCheck --check-prefix=INVALID1 %s |
| 17 | ; INVALID1: invalid optimization level for LTO: 6 | 17 | ; INVALID1: invalid optimization level for LTO: 6 |
| 18 | ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=O6 %t.o 2>&1 | \ | 18 | ; RUN: not ld.lld -o %t3 -e main --plugin-opt=O6 %t.o 2>&1 | \ |
| 19 | ; RUN: FileCheck --check-prefix=INVALID1 %s | 19 | ; RUN: FileCheck --check-prefix=INVALID1 %s |
| 20 | ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=Ofoo %t.o 2>&1 | \ | 20 | ; RUN: not ld.lld -o %t3 -e main --plugin-opt=Ofoo %t.o 2>&1 | \ |
| 21 | ; RUN: FileCheck --check-prefix=INVALID2 %s | 21 | ; RUN: FileCheck --check-prefix=INVALID2 %s |
| 22 | ; INVALID2: --plugin-opt: number expected, but got 'foo' | 22 | ; INVALID2: --plugin-opt=Ofoo: number expected, but got 'foo' |
| 23 | 23 | ||
| 24 | ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \ | 24 | ; RUN: not ld.lld -o %t3 -e main --lto-O-1 %t.o 2>&1 | \ |
| 25 | ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s | 25 | ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s |
| 26 | ; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 | 26 | ; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 |
| 27 | ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=O-1 %t.o 2>&1 | \ | 27 | ; RUN: not ld.lld -o %t3 -e main --plugin-opt=O-1 %t.o 2>&1 | \ |
| 28 | ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s | 28 | ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s |
| 29 | ; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 | 29 | ; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 |
| 30 | 30 |
deps/lld/test/ELF/lto/parallel-internalize.ll+19-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as -o %t.bc %s | 2 | ; RUN: llvm-as -o %t.bc %s |
| 3 | ; RUN: rm -f %t.lto.o %t1.lto.o | 3 | ; RUN: rm -f %t.lto.o %t1.lto.o |
| 4 | ; RUN: ld.lld -m elf_x86_64 --lto-partitions=2 -save-temps -o %t %t.bc \ | 4 | ; RUN: ld.lld --lto-partitions=2 -save-temps -o %t %t.bc \ |
| 5 | ; RUN: -e foo --lto-O0 | 5 | ; RUN: -e foo --lto-O0 |
| 6 | ; RUN: llvm-readobj -t -dyn-symbols %t | FileCheck %s | 6 | ; RUN: llvm-readobj -t -dyn-symbols %t | FileCheck %s |
| 7 | ; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s | 7 | ; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s |
| ... | @@ -18,6 +18,24 @@ | ... | @@ -18,6 +18,24 @@ |
| 18 | ; CHECK-NEXT: Section: Undefined (0x0) | 18 | ; CHECK-NEXT: Section: Undefined (0x0) |
| 19 | ; CHECK-NEXT: } | 19 | ; CHECK-NEXT: } |
| 20 | ; CHECK-NEXT: Symbol { | 20 | ; CHECK-NEXT: Symbol { |
| 21 | ; CHECK-NEXT: Name: {{.*}}.o | ||
| 22 | ; CHECK-NEXT: Value: 0x0 | ||
| 23 | ; CHECK-NEXT: Size: 0 | ||
| 24 | ; CHECK-NEXT: Binding: Local | ||
| 25 | ; CHECK-NEXT: Type: File | ||
| 26 | ; CHECK-NEXT: Other: 0 | ||
| 27 | ; CHECK-NEXT: Section: Absolute | ||
| 28 | ; CHECK-NEXT: } | ||
| 29 | ; CHECK-NEXT: Symbol { | ||
| 30 | ; CHECK-NEXT: Name: {{.*}}.o | ||
| 31 | ; CHECK-NEXT: Value: 0x0 | ||
| 32 | ; CHECK-NEXT: Size: 0 | ||
| 33 | ; CHECK-NEXT: Binding: Local | ||
| 34 | ; CHECK-NEXT: Type: File | ||
| 35 | ; CHECK-NEXT: Other: 0 | ||
| 36 | ; CHECK-NEXT: Section: Absolute | ||
| 37 | ; CHECK-NEXT: } | ||
| 38 | ; CHECK-NEXT: Symbol { | ||
| 21 | ; CHECK-NEXT: Name: bar | 39 | ; CHECK-NEXT: Name: bar |
| 22 | ; CHECK-NEXT: Value: 0x201010 | 40 | ; CHECK-NEXT: Value: 0x201010 |
| 23 | ; CHECK-NEXT: Size: 8 | 41 | ; CHECK-NEXT: Size: 8 |
deps/lld/test/ELF/lto/parallel.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as -o %t.bc %s | 2 | ; RUN: llvm-as -o %t.bc %s |
| 3 | ; RUN: rm -f %t.lto.o %t1.lto.o | 3 | ; RUN: rm -f %t.lto.o %t1.lto.o |
| 4 | ; RUN: ld.lld -m elf_x86_64 --lto-partitions=2 -save-temps -o %t %t.bc -shared | 4 | ; RUN: ld.lld --lto-partitions=2 -save-temps -o %t %t.bc -shared |
| 5 | ; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s | 5 | ; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s |
| 6 | ; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s | 6 | ; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s |
| 7 | 7 |
deps/lld/test/ELF/lto/relax-relocs.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 -save-temps -shared %t.o -o %t.so | 3 | ; RUN: ld.lld -save-temps -shared %t.o -o %t.so |
| 4 | ; RUN: llvm-readobj -r %t.so.lto.o | FileCheck %s | 4 | ; RUN: llvm-readobj -r %t.so.lto.o | FileCheck %s |
| 5 | 5 | ||
| 6 | ; Test that we produce R_X86_64_REX_GOTPCRELX instead of R_X86_64_GOTPCREL | 6 | ; Test that we produce R_X86_64_REX_GOTPCRELX instead of R_X86_64_GOTPCREL |
deps/lld/test/ELF/lto/relocatable.ll+9| ... | @@ -14,6 +14,15 @@ | ... | @@ -14,6 +14,15 @@ |
| 14 | ; CHECK-NEXT: Section: Undefined | 14 | ; CHECK-NEXT: Section: Undefined |
| 15 | ; CHECK-NEXT: } | 15 | ; CHECK-NEXT: } |
| 16 | ; CHECK-NEXT: Symbol { | 16 | ; CHECK-NEXT: Symbol { |
| 17 | ; CHECK-NEXT: Name: {{.*}}.o | ||
| 18 | ; CHECK-NEXT: Value: 0x0 | ||
| 19 | ; CHECK-NEXT: Size: 0 | ||
| 20 | ; CHECK-NEXT: Binding: Local | ||
| 21 | ; CHECK-NEXT: Type: File | ||
| 22 | ; CHECK-NEXT: Other: 0 | ||
| 23 | ; CHECK-NEXT: Section: Absolute | ||
| 24 | ; CHECK-NEXT: } | ||
| 25 | ; CHECK-NEXT: Symbol { | ||
| 17 | ; CHECK-NEXT: Name: | 26 | ; CHECK-NEXT: Name: |
| 18 | ; CHECK-NEXT: Value: 0x0 | 27 | ; CHECK-NEXT: Value: 0x0 |
| 19 | ; CHECK-NEXT: Size: 0 | 28 | ; CHECK-NEXT: Size: 0 |
deps/lld/test/ELF/lto/sample-profile.ll created+25| ... | @@ -0,0 +1,25 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: opt -module-summary %s -o %t1.o | ||
| 3 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | ||
| 4 | |||
| 5 | ; RUN: rm -f %t1.lto.o %t2.lto.o | ||
| 6 | ; RUN: ld.lld --lto-sample-profile=%p/Inputs/sample-profile.prof %t1.o %t2.o -o %t3 | ||
| 7 | ; RUN opt -S %t3.lto.o | FileCheck %s | ||
| 8 | |||
| 9 | ; RUN: rm -f %t1.lto.o %t2.lto.o | ||
| 10 | ; RUN: ld.lld --plugin-opt=sample-profile=%p/Inputs/sample-profile.prof %t1.o %t2.o -o %t3 | ||
| 11 | ; RUN opt -S %t3.lto.o | FileCheck %s | ||
| 12 | |||
| 13 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 14 | target triple = "x86_64-unknown-linux-gnu" | ||
| 15 | |||
| 16 | ; CHECK: ProfileSummary | ||
| 17 | declare void @g(...) | ||
| 18 | declare void @h(...) | ||
| 19 | |||
| 20 | define void @f() { | ||
| 21 | entry: | ||
| 22 | call void (...) @g() | ||
| 23 | call void (...) @h() | ||
| 24 | ret void | ||
| 25 | } | ||
deps/lld/test/ELF/lto/save-temps.ll+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | ; RUN: rm -f a.out a.out.lto.bc a.out.lto.o | 3 | ; RUN: rm -f a.out a.out.lto.bc a.out.lto.o |
| 4 | ; RUN: llvm-as %s -o %t.o | 4 | ; RUN: llvm-as %s -o %t.o |
| 5 | ; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o | 5 | ; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o |
| 6 | ; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o -save-temps | 6 | ; RUN: ld.lld -shared %t.o %t2.o -save-temps |
| 7 | ; RUN: llvm-nm a.out | FileCheck %s | 7 | ; RUN: llvm-nm a.out | FileCheck %s |
| 8 | ; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s | 8 | ; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s |
| 9 | ; RUN: llvm-nm a.out.lto.o | FileCheck %s | 9 | ; RUN: llvm-nm a.out.lto.o | FileCheck %s |
deps/lld/test/ELF/lto/setting-dso-local.ll created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: llvm-as %s -o %t1.o | ||
| 3 | ; RUN: not ld.lld -o %t %t1.o 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | ; CHECK: undefined symbol: foobar | ||
| 6 | |||
| 7 | ; We used to crash setting foobar to non-dso_local | ||
| 8 | |||
| 9 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 10 | target triple = "x86_64-unknown-linux-gnu" | ||
| 11 | |||
| 12 | @foobar = external hidden global i32 | ||
| 13 | define i32* @_start() { | ||
| 14 | ret i32* @foobar | ||
| 15 | } | ||
deps/lld/test/ELF/lto/start-lib.ll+3-3| ... | @@ -4,17 +4,17 @@ | ... | @@ -4,17 +4,17 @@ |
| 4 | ; RUN: llvm-as %p/Inputs/start-lib1.ll -o %t2.o | 4 | ; RUN: llvm-as %p/Inputs/start-lib1.ll -o %t2.o |
| 5 | ; RUN: llvm-as %p/Inputs/start-lib2.ll -o %t3.o | 5 | ; RUN: llvm-as %p/Inputs/start-lib2.ll -o %t3.o |
| 6 | ; | 6 | ; |
| 7 | ; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o %t2.o %t3.o | 7 | ; RUN: ld.lld -shared -o %t3 %t1.o %t2.o %t3.o |
| 8 | ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s | 8 | ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s |
| 9 | ; TEST1: Name: bar | 9 | ; TEST1: Name: bar |
| 10 | ; TEST1: Name: foo | 10 | ; TEST1: Name: foo |
| 11 | ; | 11 | ; |
| 12 | ; RUN: ld.lld -m elf_x86_64 -shared -o %t3 -u bar %t1.o --start-lib %t2.o %t3.o | 12 | ; RUN: ld.lld -shared -o %t3 -u bar %t1.o --start-lib %t2.o %t3.o |
| 13 | ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s | 13 | ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s |
| 14 | ; TEST2: Name: bar | 14 | ; TEST2: Name: bar |
| 15 | ; TEST2-NOT: Name: foo | 15 | ; TEST2-NOT: Name: foo |
| 16 | ; | 16 | ; |
| 17 | ; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o --start-lib %t2.o %t3.o | 17 | ; RUN: ld.lld -shared -o %t3 %t1.o --start-lib %t2.o %t3.o |
| 18 | ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s | 18 | ; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s |
| 19 | ; TEST3-NOT: Name: bar | 19 | ; TEST3-NOT: Name: bar |
| 20 | ; TEST3-NOT: Name: foo | 20 | ; TEST3-NOT: Name: foo |
deps/lld/test/ELF/lto/symbol-ordering-lto.s+6-5| ... | @@ -8,16 +8,17 @@ | ... | @@ -8,16 +8,17 @@ |
| 8 | # RUN: echo "pat " >> %t_order_lto.txt | 8 | # RUN: echo "pat " >> %t_order_lto.txt |
| 9 | 9 | ||
| 10 | # RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out | 10 | # RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out |
| 11 | # RUN: llvm-readobj -elf-output-style=GNU -t %t2.out| FileCheck %s | 11 | # RUN: llvm-readelf -t %t2.out| FileCheck %s |
| 12 | 12 | ||
| 13 | # Check that the order is tin -> _start -> pat. | 13 | # Check that the order is tin -> _start -> pat. |
| 14 | 14 | ||
| 15 | # CHECK: Symbol table '.symtab' contains 4 entries: | 15 | # CHECK: Symbol table '.symtab' contains 5 entries: |
| 16 | # CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name | 16 | # CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name |
| 17 | # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND | 17 | # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND |
| 18 | # CHECK-NEXT: 1: 0000000000201008 0 NOTYPE GLOBAL DEFAULT 1 _start | 18 | # CHECK-NEXT: 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS {{.*}}.o |
| 19 | # CHECK-NEXT: 2: 0000000000201020 6 FUNC GLOBAL DEFAULT 1 pat | 19 | # CHECK-NEXT: 2: 0000000000201008 0 NOTYPE GLOBAL DEFAULT 1 _start |
| 20 | # CHECK-NEXT: 3: 0000000000201000 6 FUNC GLOBAL DEFAULT 1 tin | 20 | # CHECK-NEXT: 3: 0000000000201020 6 FUNC GLOBAL DEFAULT 1 pat |
| 21 | # CHECK-NEXT: 4: 0000000000201000 6 FUNC GLOBAL DEFAULT 1 tin | ||
| 21 | 22 | ||
| 22 | .globl _start | 23 | .globl _start |
| 23 | _start: | 24 | _start: |
deps/lld/test/ELF/lto/thinlto-cant-write-index.ll created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | |||
| 3 | ; Basic ThinLTO tests. | ||
| 4 | ; RUN: opt -module-summary %s -o %t1.o | ||
| 5 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | ||
| 6 | |||
| 7 | ; Ensure lld generates error if unable to write to index files | ||
| 8 | ; RUN: rm -f %t2.o.thinlto.bc | ||
| 9 | ; RUN: touch %t2.o.thinlto.bc | ||
| 10 | ; RUN: chmod 400 %t2.o.thinlto.bc | ||
| 11 | ; RUN: not ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t2.o -o %t3 2>&1 | FileCheck %s | ||
| 12 | ; CHECK: cannot open {{.*}}2.o.thinlto.bc: {{P|p}}ermission denied | ||
| 13 | |||
| 14 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 15 | target triple = "x86_64-unknown-linux-gnu" | ||
| 16 | |||
| 17 | declare void @g(...) | ||
| 18 | |||
| 19 | define void @f() { | ||
| 20 | entry: | ||
| 21 | call void (...) @g() | ||
| 22 | ret void | ||
| 23 | } | ||
deps/lld/test/ELF/lto/thinlto-debug-fission.ll created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | |||
| 3 | ; RUN: opt %s -o %t1.o | ||
| 4 | ; RUN: rm -rf %T/dwo | ||
| 5 | |||
| 6 | ; Test to ensure that --plugin-opt=dwo_dir=$DIR creates .dwo files under $DIR | ||
| 7 | ; RUN: ld.lld --plugin-opt=dwo_dir=%T/dwo -shared %t1.o -o /dev/null | ||
| 8 | ; RUN: llvm-readobj -h %T/dwo/0.dwo | FileCheck %s | ||
| 9 | |||
| 10 | ; CHECK: Format: ELF64-x86-64 | ||
| 11 | |||
| 12 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 13 | target triple = "x86_64-unknown-linux-gnu" | ||
| 14 | |||
| 15 | declare void @g(...) | ||
| 16 | |||
| 17 | define void @f() { | ||
| 18 | entry: | ||
| 19 | call void (...) @g() | ||
| 20 | ret void | ||
| 21 | } | ||
deps/lld/test/ELF/lto/thinlto-emit-imports.ll created+55| ... | @@ -0,0 +1,55 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | |||
| 3 | ; Generate summary sections and test lld handling. | ||
| 4 | ; RUN: opt -module-summary %s -o %t1.o | ||
| 5 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | ||
| 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.o | ||
| 10 | |||
| 11 | ; Ensure lld generates imports files if requested for distributed backends. | ||
| 12 | ; RUN: rm -f %t3.o.imports %t3.o.thinlto.bc | ||
| 13 | ; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4 | ||
| 14 | |||
| 15 | ; The imports file for this module contains the bitcode file for | ||
| 16 | ; Inputs/thinlto.ll | ||
| 17 | ; RUN: cat %t1.o.imports | count 1 | ||
| 18 | ; RUN: cat %t1.o.imports | FileCheck %s --check-prefix=IMPORTS1 | ||
| 19 | ; IMPORTS1: thinlto-emit-imports.ll.tmp2.o | ||
| 20 | |||
| 21 | ; The imports file for Input/thinlto.ll is empty as it does not import anything. | ||
| 22 | ; RUN: cat %t2.o.imports | count 0 | ||
| 23 | |||
| 24 | ; The imports file for Input/thinlto_empty.ll is empty but should exist. | ||
| 25 | ; RUN: cat %t3.o.imports | count 0 | ||
| 26 | |||
| 27 | ; The index file should be created even for the input with an empty summary. | ||
| 28 | ; RUN: ls %t3.o.thinlto.bc | ||
| 29 | |||
| 30 | ; Ensure lld generates error if unable to write to imports file. | ||
| 31 | ; RUN: rm -f %t3.o.imports | ||
| 32 | ; RUN: touch %t3.o.imports | ||
| 33 | ; RUN: chmod 400 %t3.o.imports | ||
| 34 | ; RUN: not ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4 2>&1 | FileCheck %s --check-prefix=ERR | ||
| 35 | ; ERR: cannot open {{.*}}3.o.imports: {{P|p}}ermission denied | ||
| 36 | |||
| 37 | ; Ensure lld doesn't generate import files when thinlto-index-only is not enabled | ||
| 38 | ; RUN: rm -f %t1.o.imports | ||
| 39 | ; RUN: rm -f %t2.o.imports | ||
| 40 | ; RUN: rm -f %t3.o.imports | ||
| 41 | ; RUN: ld.lld --plugin-opt=thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4 | ||
| 42 | ; RUN: not ls %t1.o.imports | ||
| 43 | ; RUN: not ls %t2.o.imports | ||
| 44 | ; RUN: not ls %t3.o.imports | ||
| 45 | |||
| 46 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 47 | target triple = "x86_64-unknown-linux-gnu" | ||
| 48 | |||
| 49 | declare void @g(...) | ||
| 50 | |||
| 51 | define void @f() { | ||
| 52 | entry: | ||
| 53 | call void (...) @g() | ||
| 54 | ret void | ||
| 55 | } | ||
deps/lld/test/ELF/lto/thinlto-index-file.ll created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | |||
| 3 | ; Basic ThinLTO tests. | ||
| 4 | ; RUN: opt -module-summary %s -o %t1.o | ||
| 5 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | ||
| 6 | ; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t3.o | ||
| 7 | |||
| 8 | ; Ensure lld writes linked files to linked objects file | ||
| 9 | ; RUN: ld.lld --plugin-opt=thinlto-index-only=%t.idx -shared %t1.o %t2.o %t3.o -o %t4 | ||
| 10 | ; RUN: FileCheck %s < %t.idx | ||
| 11 | ; CHECK: {{.*}}thinlto-index-file.ll.tmp1.o | ||
| 12 | ; CHECK: {{.*}}thinlto-index-file.ll.tmp2.o | ||
| 13 | ; CHECK: {{.*}}thinlto-index-file.ll.tmp3.o | ||
| 14 | |||
| 15 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 16 | target triple = "x86_64-unknown-linux-gnu" | ||
| 17 | |||
| 18 | declare void @g(...) | ||
| 19 | |||
| 20 | define void @f() { | ||
| 21 | entry: | ||
| 22 | call void (...) @g() | ||
| 23 | ret void | ||
| 24 | } | ||
deps/lld/test/ELF/lto/thinlto-index-only.ll created+89| ... | @@ -0,0 +1,89 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | |||
| 3 | ; First ensure that the ThinLTO handling in lld handles | ||
| 4 | ; bitcode without summary sections gracefully and generates index file. | ||
| 5 | ; RUN: llvm-as %s -o %t1.o | ||
| 6 | ; RUN: llvm-as %p/Inputs/thinlto.ll -o %t2.o | ||
| 7 | ; RUN: rm -f %t3 | ||
| 8 | ; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t2.o -o %t3 | ||
| 9 | ; RUN: ls %t2.o.thinlto.bc | ||
| 10 | ; RUN: not test -e %t3 | ||
| 11 | ; RUN: ld.lld -shared %t1.o %t2.o -o %t3 | ||
| 12 | ; RUN: llvm-nm %t3 | FileCheck %s --check-prefix=NM | ||
| 13 | |||
| 14 | ; Basic ThinLTO tests. | ||
| 15 | ; RUN: opt -module-summary %s -o %t1.o | ||
| 16 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | ||
| 17 | ; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t3.o | ||
| 18 | |||
| 19 | ; Ensure lld generates an index and not a binary if requested. | ||
| 20 | ; RUN: rm -f %t4 | ||
| 21 | ; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t2.o -o %t4 | ||
| 22 | ; RUN: llvm-bcanalyzer -dump %t1.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND1 | ||
| 23 | ; RUN: llvm-bcanalyzer -dump %t2.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND2 | ||
| 24 | ; RUN: not test -e %t4 | ||
| 25 | |||
| 26 | ; Ensure lld generates an index even if the file is wrapped in --start-lib/--end-lib | ||
| 27 | ; RUN: rm -f %t2.o.thinlto.bc %t4 | ||
| 28 | ; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t3.o --start-lib %t2.o --end-lib -o %t4 | ||
| 29 | ; RUN: ls %t2.o.thinlto.bc | ||
| 30 | ; RUN: not test -e %t4 | ||
| 31 | |||
| 32 | ; Test that LLD generates an empty index even for lazy object file that is not added to link. | ||
| 33 | ; Test LLD generates empty imports file either because of thinlto-emit-imports-files option. | ||
| 34 | ; RUN: rm -f %t1.o.thinlto.bc | ||
| 35 | ; RUN: rm -f %t1.o.imports | ||
| 36 | ; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t2.o --start-lib %t1.o --end-lib \ | ||
| 37 | ; RUN: --plugin-opt=thinlto-emit-imports-files -o %t3 | ||
| 38 | ; RUN: ls %t1.o.thinlto.bc | ||
| 39 | ; RUN: ls %t1.o.imports | ||
| 40 | |||
| 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 | ||
| 49 | ; RUN: rm -f %t1.o.thinlto.bc | ||
| 50 | |||
| 51 | ; NM: T f | ||
| 52 | |||
| 53 | ; The backend index for this module contains summaries from itself and | ||
| 54 | ; Inputs/thinlto.ll, as it imports from the latter. | ||
| 55 | ; BACKEND1: <MODULE_STRTAB_BLOCK | ||
| 56 | ; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp{{.*}}.o' | ||
| 57 | ; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp{{.*}}.o' | ||
| 58 | ; BACKEND1-NEXT: </MODULE_STRTAB_BLOCK | ||
| 59 | ; BACKEND1: <GLOBALVAL_SUMMARY_BLOCK | ||
| 60 | ; BACKEND1: <VERSION | ||
| 61 | ; BACKEND1: <FLAGS | ||
| 62 | ; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-5300342847281564238}} | ||
| 63 | ; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-5300342847281564238}} | ||
| 64 | ; BACKEND1: <COMBINED | ||
| 65 | ; BACKEND1: <COMBINED | ||
| 66 | ; BACKEND1: </GLOBALVAL_SUMMARY_BLOCK | ||
| 67 | |||
| 68 | ; The backend index for Input/thinlto.ll contains summaries from itself only, | ||
| 69 | ; as it does not import anything. | ||
| 70 | ; BACKEND2: <MODULE_STRTAB_BLOCK | ||
| 71 | ; BACKEND2-NEXT: <ENTRY {{.*}} record string = '{{.*}}thinlto-index-only.ll.tmp2.o' | ||
| 72 | ; BACKEND2-NEXT: </MODULE_STRTAB_BLOCK | ||
| 73 | ; BACKEND2-NEXT: <GLOBALVAL_SUMMARY_BLOCK | ||
| 74 | ; BACKEND2-NEXT: <VERSION | ||
| 75 | ; BACKEND2-NEXT: <FLAGS | ||
| 76 | ; BACKEND2-NEXT: <VALUE_GUID op0=1 op1=-5300342847281564238 | ||
| 77 | ; BACKEND2-NEXT: <COMBINED | ||
| 78 | ; BACKEND2-NEXT: </GLOBALVAL_SUMMARY_BLOCK | ||
| 79 | |||
| 80 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 81 | target triple = "x86_64-unknown-linux-gnu" | ||
| 82 | |||
| 83 | declare void @g(...) | ||
| 84 | |||
| 85 | define void @f() { | ||
| 86 | entry: | ||
| 87 | call void (...) @g() | ||
| 88 | ret void | ||
| 89 | } | ||
deps/lld/test/ELF/lto/thinlto-no-index.ll created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | |||
| 3 | ; Basic ThinLTO tests. | ||
| 4 | ; RUN: opt -module-summary %s -o %t1.o | ||
| 5 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | ||
| 6 | ; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t3.o | ||
| 7 | |||
| 8 | ; Ensure lld doesn't generates index files when thinlto-index-only is not enabled | ||
| 9 | ; RUN: rm -f %t1.o.thinlto.bc %t2.o.thinlto.bc %t3.o.thinlto.bc | ||
| 10 | ; RUN: ld.lld -shared %t1.o %t2.o %t3.o -o %t4 | ||
| 11 | ; RUN: not ls %t1.o.thinlto.bc | ||
| 12 | ; RUN: not ls %t2.o.thinlto.bc | ||
| 13 | ; RUN: not ls %t3.o.thinlto.bc | ||
| 14 | |||
| 15 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 16 | target triple = "x86_64-unknown-linux-gnu" | ||
| 17 | |||
| 18 | declare void @g(...) | ||
| 19 | |||
| 20 | define void @f() { | ||
| 21 | entry: | ||
| 22 | call void (...) @g() | ||
| 23 | ret void | ||
| 24 | } | ||
deps/lld/test/ELF/lto/thinlto-obj-path.ll created+23| ... | @@ -0,0 +1,23 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | |||
| 3 | ; RUN: opt -module-summary %s -o %t1.o | ||
| 4 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | ||
| 5 | |||
| 6 | ; Test to ensure that thinlto-index-only with obj-path creates the file. | ||
| 7 | ; RUN: rm -f %t4.o | ||
| 8 | ; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=obj-path=%t4.o -shared %t1.o %t2.o -o %t3 | ||
| 9 | ; RUN: llvm-readobj -h %t4.o | FileCheck %s | ||
| 10 | ; RUN: llvm-nm %t4.o | count 0 | ||
| 11 | |||
| 12 | ; CHECK: Format: ELF64-x86-64 | ||
| 13 | |||
| 14 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 15 | target triple = "x86_64-unknown-linux-gnu" | ||
| 16 | |||
| 17 | declare void @g(...) | ||
| 18 | |||
| 19 | define void @f() { | ||
| 20 | entry: | ||
| 21 | call void (...) @g() | ||
| 22 | ret void | ||
| 23 | } | ||
deps/lld/test/ELF/lto/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.o | ||
| 9 | |||
| 10 | ; First perform the thin link on the normal bitcode file, and save the | ||
| 11 | ; resulting index. | ||
| 12 | ; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %t1.o -o %t3 | ||
| 13 | ; RUN: cp %t1.o.thinlto.bc %t1.o.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.o.thinlto.bc | ||
| 18 | ; Make sure it isn't inadvertently using the regular bitcode file. | ||
| 19 | ; RUN: rm -f %t1.o | ||
| 20 | ; RUN: ld.lld --plugin-opt=thinlto-index-only \ | ||
| 21 | ; RUN: --plugin-opt=thinlto-object-suffix-replace=".thinlink.bc;.o" \ | ||
| 22 | ; RUN: -shared %t1.thinlink.bc -o %t3 | ||
| 23 | ; RUN: diff %t1.o.thinlto.bc.orig %t1.o.thinlto.bc | ||
| 24 | |||
| 25 | ; Ensure lld generates error if object suffix replace option does not have 'old;new' format | ||
| 26 | ; RUN: rm -f %t1.o.thinlto.bc | ||
| 27 | ; RUN: not ld.lld --plugin-opt=thinlto-index-only \ | ||
| 28 | ; RUN: --plugin-opt=thinlto-object-suffix-replace="abc:def" -shared %t1.thinlink.bc \ | ||
| 29 | ; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR1 | ||
| 30 | ; ERR1: --plugin-opt=thinlto-object-suffix-replace= expects 'old;new' format, but got abc:def | ||
| 31 | |||
| 32 | ; Ensure lld generates error if old suffix doesn't exist in file name | ||
| 33 | ; RUN: rm -f %t1.o | ||
| 34 | ; RUN: not ld.lld --plugin-opt=thinlto-index-only \ | ||
| 35 | ; RUN: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc \ | ||
| 36 | ; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR2 | ||
| 37 | ; ERR2: error: -thinlto-object-suffix-replace=.abc;.o was given, but {{.*}} does not end with the suffix | ||
| 38 | |||
| 39 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 40 | target triple = "x86_64-unknown-linux-gnu" | ||
| 41 | |||
| 42 | define void @f() { | ||
| 43 | entry: | ||
| 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/ELF/lto/thinlto-prefix-replace.ll created+23| ... | @@ -0,0 +1,23 @@ | ||
| 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/thinlto_prefix_replace.o | ||
| 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/thinlto_prefix_replace.o.thinlto.bc | ||
| 9 | ; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-prefix-replace="%t/oldpath/;%t/newpath/" -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace | ||
| 10 | ; RUN: ls %t/newpath/thinlto_prefix_replace.o.thinlto.bc | ||
| 11 | |||
| 12 | ; Ensure that lld generates error if prefix replace option does not have 'old;new' format | ||
| 13 | ; RUN: rm -f %t/newpath/thinlto_prefix_replace.o.thinlto.bc | ||
| 14 | ; RUN: not ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-prefix-replace=abc:def -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace 2>&1 | FileCheck %s --check-prefix=ERR | ||
| 15 | ; ERR: --plugin-opt=thinlto-prefix-replace= expects 'old;new' format, but got abc:def | ||
| 16 | |||
| 17 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 18 | target triple = "x86_64-unknown-linux-gnu" | ||
| 19 | |||
| 20 | define void @f() { | ||
| 21 | entry: | ||
| 22 | ret void | ||
| 23 | } | ||
deps/lld/test/ELF/lto/thinlto.ll+15-16| ... | @@ -1,30 +1,29 @@ | ... | @@ -1,30 +1,29 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | |||
| 2 | ; Basic ThinLTO tests. | 3 | ; Basic ThinLTO tests. |
| 3 | ; RUN: opt -module-summary %s -o %t.o | 4 | ; RUN: opt -module-summary %s -o %t1.o |
| 4 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | 5 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o |
| 5 | 6 | ||
| 6 | ; First force single-threaded mode | 7 | ; First force single-threaded mode |
| 7 | ; RUN: rm -f %t.lto.o %t1.lto.o | 8 | ; RUN: rm -f %t31.lto.o %t32.lto.o |
| 8 | ; RUN: ld.lld -save-temps --thinlto-jobs=1 -shared %t.o %t2.o -o %t | 9 | ; RUN: ld.lld -save-temps --thinlto-jobs=1 -shared %t1.o %t2.o -o %t3 |
| 9 | ; RUN: llvm-nm %t1.lto.o | FileCheck %s --check-prefix=NM1 | 10 | ; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1 |
| 10 | ; RUN: llvm-nm %t2.lto.o | FileCheck %s --check-prefix=NM2 | 11 | ; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2 |
| 11 | 12 | ||
| 12 | ; Next force multi-threaded mode | 13 | ; Next force multi-threaded mode |
| 13 | ; RUN: rm -f %t2.lto.o %t21.lto.o | 14 | ; RUN: rm -f %t31.lto.o %t32.lto.o |
| 14 | ; RUN: ld.lld -save-temps --thinlto-jobs=2 -shared %t.o %t2.o -o %t2 | 15 | ; RUN: ld.lld -save-temps --thinlto-jobs=2 -shared %t1.o %t2.o -o %t3 |
| 15 | ; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM1 | 16 | ; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1 |
| 16 | ; RUN: llvm-nm %t22.lto.o | FileCheck %s --check-prefix=NM2 | 17 | ; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2 |
| 17 | 18 | ||
| 18 | ; NM1: T f | 19 | ; Then check without --thinlto-jobs (which currently default to hardware_concurrency) |
| 19 | ; NM1-NOT: U g | 20 | ; RUN: ld.lld -shared %t1.o %t2.o -o %t3 |
| 21 | ; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1 | ||
| 22 | ; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2 | ||
| 20 | 23 | ||
| 24 | ; NM1: T f | ||
| 21 | ; NM2: T g | 25 | ; NM2: T g |
| 22 | 26 | ||
| 23 | ; Then check without --thinlto-jobs (which currently default to hardware_concurrency) | ||
| 24 | ; We just check that we don't crash or fail (as it's not sure which tests are | ||
| 25 | ; stable on the final output file itself. | ||
| 26 | ; RUN: ld.lld -shared %t.o %t2.o -o %t2 | ||
| 27 | |||
| 28 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 27 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 29 | target triple = "x86_64-unknown-linux-gnu" | 28 | target triple = "x86_64-unknown-linux-gnu" |
| 30 | 29 |
deps/lld/test/ELF/lto/timepasses.ll+3-4| ... | @@ -1,8 +1,7 @@ | ... | @@ -1,8 +1,7 @@ |
| 1 | ; We use lld -flavor gnu because llvm-lit will append --full-shutdown to | ||
| 2 | ; the ld.lld invocation. | ||
| 3 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 4 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 5 | ; RUN: lld -flavor gnu %t.o -o %t.so -shared -mllvm -time-passes 2>&1 | FileCheck %s | 3 | ; RUN: env LLD_IN_TEST=0 ld.lld %t.o -o %t.so -shared -mllvm \ |
| 4 | ; RUN: -time-passes 2>&1 | FileCheck %s | ||
| 6 | 5 | ||
| 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 8 | target triple = "x86_64-unknown-linux-gnu" | 7 | target triple = "x86_64-unknown-linux-gnu" |
| ... | @@ -11,5 +10,5 @@ define void @patatino() { | ... | @@ -11,5 +10,5 @@ define void @patatino() { |
| 11 | ret void | 10 | ret void |
| 12 | } | 11 | } |
| 13 | 12 | ||
| 14 | ; We should get the output of -time-passes even when --full-shutdown is not specified. | 13 | ; We should get the output of -time-passes even when full shutdown is not specified. |
| 15 | ; CHECK: Total Execution Time | 14 | ; CHECK: Total Execution Time |
deps/lld/test/ELF/lto/tls-mixed.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t1.o | 2 | ; RUN: llvm-as %s -o %t1.o |
| 3 | ; RUN: llvm-mc %p/Inputs/tls-mixed.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux | 3 | ; RUN: llvm-mc %p/Inputs/tls-mixed.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -shared | 4 | ; RUN: ld.lld %t1.o %t2.o -o %t.so -shared |
| 5 | 5 | ||
| 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 7 | target triple = "x86_64-unknown-linux-gnu" | 7 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/tls-preserve.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; TLS attribute needs to be preserved. | 1 | ; TLS attribute needs to be preserved. |
| 2 | ; REQUIRES: x86 | 2 | ; REQUIRES: x86 |
| 3 | ; RUN: llvm-as %s -o %t1.o | 3 | ; RUN: llvm-as %s -o %t1.o |
| 4 | ; RUN: ld.lld -shared %t1.o -m elf_x86_64 -o %t1 | 4 | ; RUN: ld.lld -shared %t1.o -o %t1 |
| 5 | ; RUN: llvm-readobj -t %t1 | FileCheck %s | 5 | ; RUN: llvm-readobj -t %t1 | FileCheck %s |
| 6 | 6 | ||
| 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/type-merge.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: llvm-as %p/Inputs/type-merge.ll -o %t2.o | 3 | ; RUN: llvm-as %p/Inputs/type-merge.ll -o %t2.o |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -shared -save-temps | 4 | ; RUN: ld.lld %t.o %t2.o -o %t -shared -save-temps |
| 5 | ; RUN: llvm-dis < %t.0.0.preopt.bc | FileCheck %s | 5 | ; RUN: llvm-dis < %t.0.0.preopt.bc | FileCheck %s |
| 6 | 6 | ||
| 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 7 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/type-merge2.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o | 3 | ; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared -save-temps | 4 | ; RUN: ld.lld %t.o %t2.o -o %t.so -shared -save-temps |
| 5 | ; RUN: llvm-dis %t.so.0.0.preopt.bc -o - | FileCheck %s | 5 | ; RUN: llvm-dis %t.so.0.0.preopt.bc -o - | FileCheck %s |
| 6 | 6 | ||
| 7 | target triple = "x86_64-unknown-linux-gnu" | 7 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/undef-weak.ll+2-3| ... | @@ -1,13 +1,12 @@ | ... | @@ -1,13 +1,12 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | |||
| 3 | ; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o | 2 | ; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o |
| 4 | ; RUN: rm -f %t.a | 3 | ; RUN: rm -f %t.a |
| 5 | ; RUN: llvm-ar rcs %t.a %t1.o | 4 | ; RUN: llvm-ar rcs %t.a %t1.o |
| 6 | 5 | ||
| 7 | |||
| 8 | ; RUN: llvm-as %s -o %t2.o | 6 | ; RUN: llvm-as %s -o %t2.o |
| 9 | ; RUN: ld.lld -m elf_x86_64 %t2.o -o %t2.so %t.a -shared | 7 | ; RUN: ld.lld %t2.o -o %t2.so %t.a -shared |
| 10 | ; RUN: llvm-readobj -t %t2.so | FileCheck %s | 8 | ; RUN: llvm-readobj -t %t2.so | FileCheck %s |
| 9 | |||
| 11 | target triple = "x86_64-unknown-linux-gnu" | 10 | target triple = "x86_64-unknown-linux-gnu" |
| 12 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 11 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 13 | 12 |
deps/lld/test/ELF/lto/undef.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared | 3 | ; RUN: ld.lld %t.o -o %t.so -shared |
| 4 | ; RUN: llvm-readobj -t %t.so | FileCheck %s | 4 | ; RUN: llvm-readobj -t %t.so | FileCheck %s |
| 5 | target triple = "x86_64-unknown-linux-gnu" | 5 | target triple = "x86_64-unknown-linux-gnu" |
| 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 6 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/undefined-puts.ll+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | ; RUN: llvm-mc %p/Inputs/shared.s -o %t1.o -filetype=obj -triple=x86_64-unknown-linux | 2 | ; RUN: llvm-mc %p/Inputs/shared.s -o %t1.o -filetype=obj -triple=x86_64-unknown-linux |
| 3 | ; RUN: ld.lld %t1.o -o %t1.so -shared | 3 | ; RUN: ld.lld %t1.o -o %t1.so -shared |
| 4 | ; RUN: llvm-as %s -o %t2.o | 4 | ; RUN: llvm-as %s -o %t2.o |
| 5 | ; RUN: ld.lld %t1.so %t2.o -m elf_x86_64 -o %t | 5 | ; 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-symbols -dyn-relocations %t | FileCheck %s |
| 7 | 7 | ||
| 8 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 8 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
deps/lld/test/ELF/lto/unnamed-addr-comdat.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -save-temps -shared | 3 | ; RUN: ld.lld %t.o %t.o -o %t.so -save-temps -shared |
| 4 | ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s | 4 | ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s |
| 5 | 5 | ||
| 6 | target triple = "x86_64-unknown-linux-gnu" | 6 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/unnamed-addr-drop.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t1.o | 2 | ; RUN: llvm-as %s -o %t1.o |
| 3 | ; RUN: llvm-as %S/Inputs/unnamed-addr-drop.ll -o %t2.o | 3 | ; RUN: llvm-as %S/Inputs/unnamed-addr-drop.ll -o %t2.o |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -save-temps -shared | 4 | ; RUN: ld.lld %t1.o %t2.o -o %t.so -save-temps -shared |
| 5 | ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s | 5 | ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s |
| 6 | 6 | ||
| 7 | target triple = "x86_64-unknown-linux-gnu" | 7 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/unnamed-addr-lib.ll+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: llvm-mc %p/Inputs/unnamed-addr-lib.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux | 3 | ; RUN: llvm-mc %p/Inputs/unnamed-addr-lib.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux |
| 4 | ; RUN: ld.lld %t2.o -shared -o %t2.so | 4 | ; RUN: ld.lld %t2.o -shared -o %t2.so |
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o %t2.so -o %t.so -save-temps -shared | 5 | ; RUN: ld.lld %t.o %t2.so -o %t.so -save-temps -shared |
| 6 | ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s | 6 | ; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s |
| 7 | 7 | ||
| 8 | ; This documents a small limitation of lld's internalization logic. We decide | 8 | ; This documents a small limitation of lld's internalization logic. We decide |
deps/lld/test/ELF/lto/unnamed-addr.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -shared | 3 | ; RUN: ld.lld %t.o -o %t.so -save-temps -shared |
| 4 | ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s | 4 | ; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s |
| 5 | 5 | ||
| 6 | target triple = "x86_64-unknown-linux-gnu" | 6 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/verify-invalid.ll+3-3| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ | 3 | ; RUN: ld.lld %t.o -o %t2 -mllvm -debug-pass=Arguments \ |
| 4 | ; RUN: 2>&1 | FileCheck -check-prefix=DEFAULT %s | 4 | ; RUN: 2>&1 | FileCheck -check-prefix=DEFAULT %s |
| 5 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ | 5 | ; RUN: ld.lld %t.o -o %t2 -mllvm -debug-pass=Arguments \ |
| 6 | ; RUN: -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s | 6 | ; RUN: -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s |
| 7 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ | 7 | ; RUN: ld.lld %t.o -o %t2 -mllvm -debug-pass=Arguments \ |
| 8 | ; RUN: --plugin-opt=disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s | 8 | ; RUN: --plugin-opt=disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s |
| 9 | 9 | ||
| 10 | target triple = "x86_64-unknown-linux-gnu" | 10 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/version-script.ll+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: echo "VERSION_1.0{ global: foo; local: *; }; VERSION_2.0{ global: bar; local: *; };" > %t.script | 3 | ; RUN: echo "VERSION_1.0{ global: foo; local: *; }; VERSION_2.0{ global: bar; local: *; };" > %t.script |
| 4 | ; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps | 4 | ; RUN: ld.lld %t.o -o %t2 -shared --version-script %t.script -save-temps |
| 5 | ; RUN: llvm-dis < %t2.0.0.preopt.bc | FileCheck %s | 5 | ; 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-symbols %t2 | FileCheck --check-prefix=DSO %s |
| 7 | 7 |
deps/lld/test/ELF/lto/version-script2.ll created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: llvm-as %s -o %t.o | ||
| 3 | ; RUN: echo "VER1 {};" > %t.script | ||
| 4 | ; RUN: ld.lld %t.o -o %t.so -shared --version-script %t.script | ||
| 5 | ; RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s | ||
| 6 | |||
| 7 | ; test that we have the correct version. | ||
| 8 | ; CHECK: Name: foo@@VER1 ( | ||
| 9 | |||
| 10 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 11 | target triple = "x86_64-unknown-linux-gnu" | ||
| 12 | |||
| 13 | module asm ".global foo" | ||
| 14 | module asm "foo:" | ||
| 15 | module asm ".symver foo,foo@@@VER1" | ||
deps/lld/test/ELF/lto/visibility.ll+4-1| ... | @@ -1,7 +1,8 @@ | ... | @@ -1,7 +1,8 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t1.o | 2 | ; RUN: llvm-as %s -o %t1.o |
| 3 | ; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2.o -filetype=obj | 3 | ; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2.o -filetype=obj |
| 4 | ; RUN: ld.lld %t1.o %t2.o -o %t.so -shared | 4 | ; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps |
| 5 | ; RUN: llvm-dis < %t.so.0.2.internalize.bc | FileCheck --check-prefix=IR %s | ||
| 5 | ; RUN: llvm-readobj -t %t.so | FileCheck %s | 6 | ; RUN: llvm-readobj -t %t.so | FileCheck %s |
| 6 | 7 | ||
| 7 | ; CHECK: Name: g | 8 | ; CHECK: Name: g |
| ... | @@ -28,6 +29,8 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ... | @@ -28,6 +29,8 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 28 | target triple = "x86_64-unknown-linux-gnu" | 29 | target triple = "x86_64-unknown-linux-gnu" |
| 29 | 30 | ||
| 30 | declare hidden void @g() | 31 | declare hidden void @g() |
| 32 | ; IR: declare hidden void @g() | ||
| 33 | |||
| 31 | define void @f() { | 34 | define void @f() { |
| 32 | call void @g() | 35 | call void @g() |
| 33 | ret void | 36 | ret void |
deps/lld/test/ELF/lto/weak.ll+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; REQUIRES: x86 | 1 | ; REQUIRES: x86 |
| 2 | ; RUN: llvm-as %s -o %t.o | 2 | ; RUN: llvm-as %s -o %t.o |
| 3 | ; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared | 3 | ; RUN: ld.lld %t.o %t.o -o %t.so -shared |
| 4 | ; RUN: llvm-readobj -t %t.so | FileCheck %s | 4 | ; RUN: llvm-readobj -t %t.so | FileCheck %s |
| 5 | 5 | ||
| 6 | target triple = "x86_64-unknown-linux-gnu" | 6 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/lto/weakodr-visibility.ll created+40| ... | @@ -0,0 +1,40 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: llvm-as %s -o %t1.o | ||
| 3 | ; RUN: llvm-as %p/Inputs/weakodr-visibility.ll -o %t2.o | ||
| 4 | |||
| 5 | ; Testcase checks we keep desired visibility of weak | ||
| 6 | ; symbol in a library even if select different definition. | ||
| 7 | ; We change the order of input files in command line and | ||
| 8 | ; check that linker selects different symbol definitions, | ||
| 9 | ; but keeps `protected` visibility. | ||
| 10 | |||
| 11 | ; RUN: ld.lld %t1.o %t2.o -o %t.so -shared | ||
| 12 | ; RUN: llvm-readobj -t %t.so | FileCheck %s | ||
| 13 | ; RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=FIRST | ||
| 14 | ; CHECK: Symbol { | ||
| 15 | ; CHECK: Name: foo | ||
| 16 | ; CHECK-NEXT: Value: | ||
| 17 | ; CHECK-NEXT: Size: | ||
| 18 | ; CHECK-NEXT: Binding: Weak | ||
| 19 | ; CHECK-NEXT: Type: Function | ||
| 20 | ; CHECK-NEXT: Other [ | ||
| 21 | ; CHECK-NEXT: STV_PROTECTED | ||
| 22 | ; CHECK-NEXT: ] | ||
| 23 | ; CHECK-NEXT: Section: | ||
| 24 | ; CHECK-NEXT: } | ||
| 25 | ; FIRST: foo: | ||
| 26 | ; FIRST-NEXT: movl $41, %eax | ||
| 27 | |||
| 28 | ; Now swap the files order. | ||
| 29 | ; RUN: ld.lld %t2.o %t1.o -o %t.so -shared | ||
| 30 | ; RUN: llvm-readobj -t %t.so | FileCheck %s | ||
| 31 | ; RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=SECOND | ||
| 32 | ; SECOND: foo: | ||
| 33 | ; SECOND-NEXT: movl $42, %eax | ||
| 34 | |||
| 35 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 36 | target triple = "x86_64-unknown-linux-gnu" | ||
| 37 | |||
| 38 | define weak_odr i32 @foo(i8* %this) { | ||
| 39 | ret i32 41 | ||
| 40 | } | ||
deps/lld/test/ELF/lto/wrap-1.ll+2-2| ... | @@ -20,8 +20,8 @@ | ... | @@ -20,8 +20,8 @@ |
| 20 | ; Make sure that the 'r' (linker redefined) bit is set for bar and __wrap_bar | 20 | ; Make sure that the 'r' (linker redefined) bit is set for bar and __wrap_bar |
| 21 | ; in the resolutions file. | 21 | ; in the resolutions file. |
| 22 | ; RESOLS: ,bar,xr | 22 | ; RESOLS: ,bar,xr |
| 23 | ; RESOLS: ,__wrap_bar,px | 23 | ; RESOLS: ,__wrap_bar,plx |
| 24 | ; RESOLS: ,__real_bar,pxr | 24 | ; RESOLS: ,__real_bar,plxr |
| 25 | 25 | ||
| 26 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 26 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 27 | target triple = "x86_64-unknown-linux-gnu" | 27 | target triple = "x86_64-unknown-linux-gnu" |
deps/lld/test/ELF/map-file-i686.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t1.o | ||
| 4 | // RUN: ld.lld %t1.o -o /dev/null -M | FileCheck -strict-whitespace %s | ||
| 5 | |||
| 6 | .global _start | ||
| 7 | _start: | ||
| 8 | nop | ||
| 9 | |||
| 10 | // CHECK: VMA LMA Size Align Out In Symbol | ||
| 11 | // CHECK-NEXT: 11000 11000 1 4 .text | ||
| 12 | // CHECK-NEXT: 11000 11000 1 4 {{.*}}{{/|\\}}map-file-i686.s.tmp1.o:(.text) | ||
| 13 | // CHECK-NEXT: 11000 11000 0 1 _start | ||
| 14 | // CHECK-NEXT: 0 0 8 1 .comment | ||
| 15 | // CHECK-NEXT: 0 0 8 1 <internal>:(.comment) | ||
| 16 | // CHECK-NEXT: 0 0 20 4 .symtab | ||
| 17 | // CHECK-NEXT: 0 0 20 4 <internal>:(.symtab) | ||
| 18 | // CHECK-NEXT: 0 0 2a 1 .shstrtab | ||
| 19 | // CHECK-NEXT: 0 0 2a 1 <internal>:(.shstrtab) | ||
| 20 | // CHECK-NEXT: 0 0 8 1 .strtab | ||
| 21 | // CHECK-NEXT: 0 0 8 1 <internal>:(.strtab) | ||
deps/lld/test/ELF/map-file.s+64-56| ... | @@ -15,16 +15,21 @@ | ... | @@ -15,16 +15,21 @@ |
| 15 | 15 | ||
| 16 | .global _start | 16 | .global _start |
| 17 | _start: | 17 | _start: |
| 18 | .cfi_startproc | ||
| 19 | .cfi_endproc | ||
| 18 | .quad sharedFoo | 20 | .quad sharedFoo |
| 19 | .quad sharedBar | 21 | .quad sharedBar |
| 20 | callq sharedFunc1 | 22 | .byte 0xe8 |
| 21 | callq sharedFunc2 | 23 | .long sharedFunc1 - . |
| 22 | call baz | 24 | .byte 0xe8 |
| 25 | .long sharedFunc2 - . | ||
| 26 | .byte 0xe8 | ||
| 27 | .long baz - . | ||
| 23 | .global _Z1fi | 28 | .global _Z1fi |
| 24 | _Z1fi: | 29 | _Z1fi: |
| 25 | .cfi_startproc | 30 | .cfi_startproc |
| 26 | .cfi_endproc | ||
| 27 | nop | 31 | nop |
| 32 | .cfi_endproc | ||
| 28 | .weak bar | 33 | .weak bar |
| 29 | bar: | 34 | bar: |
| 30 | .long bar - . | 35 | .long bar - . |
| ... | @@ -35,58 +40,61 @@ local: | ... | @@ -35,58 +40,61 @@ local: |
| 35 | abs = 0xAB5 | 40 | abs = 0xAB5 |
| 36 | labs = 0x1AB5 | 41 | labs = 0x1AB5 |
| 37 | 42 | ||
| 38 | // CHECK: Address Size Align Out In Symbol | 43 | // CHECK: VMA LMA Size Align Out In Symbol |
| 39 | // CHECK-NEXT: 00000000002001c8 0000000000000078 8 .dynsym | 44 | // CHECK-NEXT: 2001c8 2001c8 78 8 .dynsym |
| 40 | // CHECK-NEXT: 00000000002001c8 0000000000000078 8 <internal>:(.dynsym) | 45 | // CHECK-NEXT: 2001c8 2001c8 78 8 <internal>:(.dynsym) |
| 41 | // CHECK-NEXT: 0000000000200240 000000000000002c 8 .gnu.hash | 46 | // CHECK-NEXT: 200240 200240 2c 8 .gnu.hash |
| 42 | // CHECK-NEXT: 0000000000200240 000000000000002c 8 <internal>:(.gnu.hash) | 47 | // CHECK-NEXT: 200240 200240 2c 8 <internal>:(.gnu.hash) |
| 43 | // CHECK-NEXT: 000000000020026c 0000000000000030 4 .hash | 48 | // CHECK-NEXT: 20026c 20026c 30 4 .hash |
| 44 | // CHECK-NEXT: 000000000020026c 0000000000000030 4 <internal>:(.hash) | 49 | // CHECK-NEXT: 20026c 20026c 30 4 <internal>:(.hash) |
| 45 | // CHECK-NEXT: 000000000020029c 0000000000000031 1 .dynstr | 50 | // CHECK-NEXT: 20029c 20029c 31 1 .dynstr |
| 46 | // CHECK-NEXT: 000000000020029c 0000000000000031 1 <internal>:(.dynstr) | 51 | // CHECK-NEXT: 20029c 20029c 31 1 <internal>:(.dynstr) |
| 47 | // CHECK-NEXT: 00000000002002d0 0000000000000030 8 .rela.dyn | 52 | // CHECK-NEXT: 2002d0 2002d0 30 8 .rela.dyn |
| 48 | // CHECK-NEXT: 00000000002002d0 0000000000000030 8 <internal>:(.rela.dyn) | 53 | // CHECK-NEXT: 2002d0 2002d0 30 8 <internal>:(.rela.dyn) |
| 49 | // CHECK-NEXT: 0000000000200300 0000000000000030 8 .rela.plt | 54 | // CHECK-NEXT: 200300 200300 30 8 .rela.plt |
| 50 | // CHECK-NEXT: 0000000000200300 0000000000000030 8 <internal>:(.rela.plt) | 55 | // CHECK-NEXT: 200300 200300 30 8 <internal>:(.rela.plt) |
| 51 | // CHECK-NEXT: 0000000000200330 0000000000000030 8 .eh_frame | 56 | // CHECK-NEXT: 200330 200330 64 8 .eh_frame |
| 52 | // CHECK-NEXT: 0000000000200330 0000000000000030 8 <internal>:(.eh_frame) | 57 | // CHECK-NEXT: 200330 200330 2c 1 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x0) |
| 53 | // CHECK-NEXT: 0000000000201000 000000000000002d 4 .text | 58 | // CHECK-NEXT: 200360 200360 14 1 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.eh_frame+0x2c) |
| 54 | // CHECK-NEXT: 0000000000201000 0000000000000028 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text) | 59 | // CHECK-NEXT: 200378 200378 18 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.eh_frame+0x18) |
| 55 | // CHECK-NEXT: 0000000000201000 0000000000000000 0 _start | 60 | // CHECK-NEXT: 201000 201000 2d 4 .text |
| 56 | // CHECK-NEXT: 000000000020101f 0000000000000000 0 f(int) | 61 | // CHECK-NEXT: 201000 201000 28 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text) |
| 57 | // CHECK-NEXT: 0000000000201028 0000000000000000 0 local | 62 | // CHECK-NEXT: 201000 201000 0 1 _start |
| 58 | // CHECK-NEXT: 0000000000201028 0000000000000002 4 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text) | 63 | // CHECK-NEXT: 20101f 20101f 0 1 f(int) |
| 59 | // CHECK-NEXT: 0000000000201028 0000000000000000 0 foo | 64 | // CHECK-NEXT: 201028 201028 0 1 local |
| 60 | // CHECK-NEXT: 0000000000201029 0000000000000000 0 bar | 65 | // CHECK-NEXT: 201028 201028 2 4 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text) |
| 61 | // CHECK-NEXT: 000000000020102a 0000000000000000 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed) | 66 | // CHECK-NEXT: 201028 201028 0 1 foo |
| 62 | // CHECK-NEXT: 000000000020102a 0000000000000000 0 zed | 67 | // CHECK-NEXT: 201029 201029 0 1 bar |
| 63 | // CHECK-NEXT: 000000000020102c 0000000000000000 4 {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text) | 68 | // CHECK-NEXT: 20102a 20102a 0 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed) |
| 64 | // CHECK-NEXT: 000000000020102c 0000000000000000 0 bah | 69 | // CHECK-NEXT: 20102a 20102a 0 1 zed |
| 65 | // CHECK-NEXT: 000000000020102c 0000000000000001 4 {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text) | 70 | // CHECK-NEXT: 20102c 20102c 0 4 {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text) |
| 66 | // CHECK-NEXT: 000000000020102c 0000000000000000 0 baz | 71 | // CHECK-NEXT: 20102c 20102c 0 1 bah |
| 67 | // CHECK-NEXT: 0000000000201030 0000000000000030 16 .plt | 72 | // CHECK-NEXT: 20102c 20102c 1 4 {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text) |
| 68 | // CHECK-NEXT: 0000000000201030 0000000000000030 16 <internal>:(.plt) | 73 | // CHECK-NEXT: 20102c 20102c 0 1 baz |
| 69 | // CHECK-NEXT: 0000000000201040 0000000000000000 0 sharedFunc1 | 74 | // CHECK-NEXT: 201030 201030 30 16 .plt |
| 70 | // CHECK-NEXT: 0000000000201050 0000000000000000 0 sharedFunc2 | 75 | // CHECK-NEXT: 201030 201030 30 16 <internal>:(.plt) |
| 71 | // CHECK-NEXT: 0000000000202000 0000000000000028 8 .got.plt | 76 | // CHECK-NEXT: 201040 201040 0 1 sharedFunc1 |
| 72 | // CHECK-NEXT: 0000000000202000 0000000000000028 8 <internal>:(.got.plt) | 77 | // CHECK-NEXT: 201050 201050 0 1 sharedFunc2 |
| 73 | // CHECK-NEXT: 0000000000203000 0000000000000100 8 .dynamic | 78 | // CHECK-NEXT: 202000 202000 28 8 .got.plt |
| 74 | // CHECK-NEXT: 0000000000203000 0000000000000100 8 <internal>:(.dynamic) | 79 | // CHECK-NEXT: 202000 202000 28 8 <internal>:(.got.plt) |
| 75 | // CHECK-NEXT: 0000000000204000 0000000000000010 16 .bss | 80 | // CHECK-NEXT: 203000 203000 100 8 .dynamic |
| 76 | // CHECK-NEXT: 0000000000204000 0000000000000004 16 {{.*}}{{/|\\}}map-file.s.tmp1.o:(COMMON) | 81 | // CHECK-NEXT: 203000 203000 100 8 <internal>:(.dynamic) |
| 77 | // CHECK-NEXT: 0000000000204000 0000000000000004 0 common | 82 | // CHECK-NEXT: 204000 204000 10 16 .bss |
| 78 | // CHECK-NEXT: 0000000000204004 0000000000000004 1 <internal>:(.bss) | 83 | // CHECK-NEXT: 204000 204000 4 16 {{.*}}{{/|\\}}map-file.s.tmp1.o:(COMMON) |
| 79 | // CHECK-NEXT: 0000000000204004 0000000000000004 0 sharedFoo | 84 | // CHECK-NEXT: 204000 204000 4 1 common |
| 80 | // CHECK-NEXT: 0000000000204008 0000000000000008 1 <internal>:(.bss) | 85 | // CHECK-NEXT: 204004 204004 4 1 <internal>:(.bss) |
| 81 | // CHECK-NEXT: 0000000000204008 0000000000000008 0 sharedBar | 86 | // CHECK-NEXT: 204004 204004 4 1 sharedFoo |
| 82 | // CHECK-NEXT: 0000000000000000 0000000000000008 1 .comment | 87 | // CHECK-NEXT: 204008 204008 8 1 <internal>:(.bss) |
| 83 | // CHECK-NEXT: 0000000000000000 0000000000000008 1 <internal>:(.comment) | 88 | // CHECK-NEXT: 204008 204008 8 1 sharedBar |
| 84 | // CHECK-NEXT: 0000000000000000 0000000000000198 8 .symtab | 89 | // CHECK-NEXT: 0 0 8 1 .comment |
| 85 | // CHECK-NEXT: 0000000000000000 0000000000000198 8 <internal>:(.symtab) | 90 | // CHECK-NEXT: 0 0 8 1 <internal>:(.comment) |
| 86 | // CHECK-NEXT: 0000000000000000 0000000000000084 1 .shstrtab | 91 | // CHECK-NEXT: 0 0 198 8 .symtab |
| 87 | // CHECK-NEXT: 0000000000000000 0000000000000084 1 <internal>:(.shstrtab) | 92 | // CHECK-NEXT: 0 0 198 8 <internal>:(.symtab) |
| 88 | // CHECK-NEXT: 0000000000000000 000000000000006d 1 .strtab | 93 | // CHECK-NEXT: 0 0 84 1 .shstrtab |
| 89 | // CHECK-NEXT: 0000000000000000 000000000000006d 1 <internal>:(.strtab) | 94 | // CHECK-NEXT: 0 0 84 1 <internal>:(.shstrtab) |
| 95 | // CHECK-NEXT: 0 0 6d 1 .strtab | ||
| 96 | // CHECK-NEXT: 0 0 6d 1 <internal>:(.strtab) | ||
| 97 | |||
| 90 | 98 | ||
| 91 | // RUN: not ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=/ 2>&1 \ | 99 | // RUN: not ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=/ 2>&1 \ |
| 92 | // RUN: | FileCheck -check-prefix=FAIL %s | 100 | // RUN: | FileCheck -check-prefix=FAIL %s |
deps/lld/test/ELF/map-gc-sections.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t -Map=- --gc-sections | FileCheck %s | 3 | // RUN: ld.lld %t.o -o /dev/null -Map=- --gc-sections | FileCheck %s |
| 3 | 4 | ||
| 4 | .section .tbss,"awT",@nobits | 5 | .section .tbss,"awT",@nobits |
| 5 | // CHECK-NOT: foo | 6 | // CHECK-NOT: foo |
deps/lld/test/ELF/merge-gc-piece.s created+38| ... | @@ -0,0 +1,38 @@ | ||
| 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.so -shared --gc-sections | ||
| 4 | # RUN: llvm-readobj -s -section-data %t.so | FileCheck %s | ||
| 5 | |||
| 6 | |||
| 7 | # CHECK: Name: .foo | ||
| 8 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 9 | # CHECK-NEXT: Flags [ | ||
| 10 | # CHECK-NEXT: SHF_ALLOC | ||
| 11 | # CHECK-NEXT: SHF_MERGE | ||
| 12 | # CHECK-NEXT: ] | ||
| 13 | # CHECK-NEXT: Address: 0x200 | ||
| 14 | |||
| 15 | # CHECK: Name: .bar | ||
| 16 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 17 | # CHECK-NEXT: Flags [ | ||
| 18 | # CHECK-NEXT: ] | ||
| 19 | # CHECK-NEXT: Address: | ||
| 20 | # CHECK-NEXT: Offset: | ||
| 21 | # CHECK-NEXT: Size: 16 | ||
| 22 | # CHECK-NEXT: Link: | ||
| 23 | # CHECK-NEXT: Info: | ||
| 24 | # CHECK-NEXT: AddressAlignment: | ||
| 25 | # CHECK-NEXT: EntrySize: | ||
| 26 | # CHECK-NEXT: SectionData ( | ||
| 27 | # CHECK-NEXT: 0000: 01020000 00000000 02020000 00000000 | ||
| 28 | # CHECK-NEXT: ) | ||
| 29 | |||
| 30 | .section .foo,"aM",@progbits,8 | ||
| 31 | .quad 42 | ||
| 32 | .global sym | ||
| 33 | sym: | ||
| 34 | .quad 43 | ||
| 35 | |||
| 36 | .section .bar | ||
| 37 | .quad .foo + 1 | ||
| 38 | .quad .foo + 2 | ||
deps/lld/test/ELF/merge-gc-piece2.s created+27| ... | @@ -0,0 +1,27 @@ | ||
| 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.so -shared --gc-sections | ||
| 4 | # RUN: llvm-readobj -s -section-data %t.so | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: Name: .bar | ||
| 7 | # CHECK-NEXT: Type: SHT_PROGBITS | ||
| 8 | # CHECK-NEXT: Flags [ | ||
| 9 | # CHECK-NEXT: ] | ||
| 10 | # CHECK-NEXT: Address: | ||
| 11 | # CHECK-NEXT: Offset: | ||
| 12 | # CHECK-NEXT: Size: 16 | ||
| 13 | # CHECK-NEXT: Link: | ||
| 14 | # CHECK-NEXT: Info: | ||
| 15 | # CHECK-NEXT: AddressAlignment: | ||
| 16 | # CHECK-NEXT: EntrySize: | ||
| 17 | # CHECK-NEXT: SectionData ( | ||
| 18 | # CHECK-NEXT: 0000: 01000000 00000000 02000000 00000000 | ||
| 19 | # CHECK-NEXT: ) | ||
| 20 | |||
| 21 | .section .foo,"aM",@progbits,8 | ||
| 22 | .quad 42 | ||
| 23 | .quad 43 | ||
| 24 | |||
| 25 | .section .bar | ||
| 26 | .quad .foo + 1 | ||
| 27 | .quad .foo + 2 | ||
deps/lld/test/ELF/merge-reloc-O0.s created+48| ... | @@ -0,0 +1,48 @@ | ||
| 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-shared-str.s+2-2| ... | @@ -19,10 +19,10 @@ | ... | @@ -19,10 +19,10 @@ |
| 19 | // CHECK-NEXT: SHF_MERGE | 19 | // CHECK-NEXT: SHF_MERGE |
| 20 | // CHECK-NEXT: SHF_STRINGS | 20 | // CHECK-NEXT: SHF_STRINGS |
| 21 | // CHECK-NEXT: ] | 21 | // CHECK-NEXT: ] |
| 22 | // CHECK-NEXT: Address: 0x1C8 | 22 | // CHECK-NEXT: Address: 0x228 |
| 23 | 23 | ||
| 24 | // CHECK: Relocations [ | 24 | // CHECK: Relocations [ |
| 25 | // CHECK-NEXT: Section ({{.*}}) .rela.dyn { | 25 | // CHECK-NEXT: Section ({{.*}}) .rela.dyn { |
| 26 | // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x1C9 | 26 | // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x229 |
| 27 | // CHECK-NEXT: } | 27 | // CHECK-NEXT: } |
| 28 | // CHECK-NEXT: ] | 28 | // CHECK-NEXT: ] |
deps/lld/test/ELF/merge-shared.s+2-2| ... | @@ -17,10 +17,10 @@ | ... | @@ -17,10 +17,10 @@ |
| 17 | // CHECK-NEXT: SHF_ALLOC | 17 | // CHECK-NEXT: SHF_ALLOC |
| 18 | // CHECK-NEXT: SHF_MERGE | 18 | // CHECK-NEXT: SHF_MERGE |
| 19 | // CHECK-NEXT: ] | 19 | // CHECK-NEXT: ] |
| 20 | // CHECK-NEXT: Address: 0x1C8 | 20 | // CHECK-NEXT: Address: 0x228 |
| 21 | 21 | ||
| 22 | // CHECK: Relocations [ | 22 | // CHECK: Relocations [ |
| 23 | // CHECK-NEXT: Section ({{.*}}) .rela.dyn { | 23 | // CHECK-NEXT: Section ({{.*}}) .rela.dyn { |
| 24 | // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x1CA | 24 | // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x22A |
| 25 | // CHECK-NEXT: } | 25 | // CHECK-NEXT: } |
| 26 | // CHECK-NEXT: ] | 26 | // CHECK-NEXT: ] |
deps/lld/test/ELF/merge-string-empty.s+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // Ensure that a mergeable string with size 0 does not cause any issue. | 2 | // Ensure that a mergeable string with size 0 does not cause any issue. |
| 2 | 3 | ||
| 3 | // REQUIRES: x86 | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 5 | // RUN: ld.lld %t.o -o %t | 5 | // RUN: ld.lld %t.o -o /dev/null |
| 6 | 6 | ||
| 7 | .globl _start, s | 7 | .globl _start, s |
| 8 | .section .rodata.str1.1,"aMS",@progbits,1 | 8 | .section .rodata.str1.1,"aMS",@progbits,1 |
deps/lld/test/ELF/merge-string-error.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | .section	.rodata.str1.1,"aMS",@progbits,1 | 5 | .section	.rodata.str1.1,"aMS",@progbits,1 |
| 6 | 	.asciz	"abc" | 6 | 	.asciz	"abc" |
deps/lld/test/ELF/merge-string-no-null.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | 	.section	.rodata.str1.1,"aMS",@progbits,1 | 5 | 	.section	.rodata.str1.1,"aMS",@progbits,1 |
| 6 | 	.ascii	"abc" | 6 | 	.ascii	"abc" |
deps/lld/test/ELF/merge-string.s+11-11| ... | @@ -28,8 +28,8 @@ zed: | ... | @@ -28,8 +28,8 @@ zed: |
| 28 | // CHECK-NEXT: SHF_MERGE | 28 | // CHECK-NEXT: SHF_MERGE |
| 29 | // CHECK-NEXT: SHF_STRINGS | 29 | // CHECK-NEXT: SHF_STRINGS |
| 30 | // CHECK-NEXT: ] | 30 | // CHECK-NEXT: ] |
| 31 | // CHECK-NEXT: Address: 0x1C8 | 31 | // CHECK-NEXT: Address: 0x20D |
| 32 | // CHECK-NEXT: Offset: 0x1C8 | 32 | // CHECK-NEXT: Offset: 0x20D |
| 33 | // CHECK-NEXT: Size: 4 | 33 | // CHECK-NEXT: Size: 4 |
| 34 | // CHECK-NEXT: Link: 0 | 34 | // CHECK-NEXT: Link: 0 |
| 35 | // CHECK-NEXT: Info: 0 | 35 | // CHECK-NEXT: Info: 0 |
| ... | @@ -46,8 +46,8 @@ zed: | ... | @@ -46,8 +46,8 @@ zed: |
| 46 | // NOTAIL-NEXT: SHF_MERGE | 46 | // NOTAIL-NEXT: SHF_MERGE |
| 47 | // NOTAIL-NEXT: SHF_STRINGS | 47 | // NOTAIL-NEXT: SHF_STRINGS |
| 48 | // NOTAIL-NEXT: ] | 48 | // NOTAIL-NEXT: ] |
| 49 | // NOTAIL-NEXT: Address: 0x1C8 | 49 | // NOTAIL-NEXT: Address: 0x20D |
| 50 | // NOTAIL-NEXT: Offset: 0x1C8 | 50 | // NOTAIL-NEXT: Offset: 0x20D |
| 51 | // NOTAIL-NEXT: Size: 7 | 51 | // NOTAIL-NEXT: Size: 7 |
| 52 | // NOTAIL-NEXT: Link: 0 | 52 | // NOTAIL-NEXT: Link: 0 |
| 53 | // NOTAIL-NEXT: Info: 0 | 53 | // NOTAIL-NEXT: Info: 0 |
| ... | @@ -64,8 +64,8 @@ zed: | ... | @@ -64,8 +64,8 @@ zed: |
| 64 | // NOMERGE-NEXT: SHF_MERGE | 64 | // NOMERGE-NEXT: SHF_MERGE |
| 65 | // NOMERGE-NEXT: SHF_STRINGS | 65 | // NOMERGE-NEXT: SHF_STRINGS |
| 66 | // NOMERGE-NEXT: ] | 66 | // NOMERGE-NEXT: ] |
| 67 | // NOMERGE-NEXT: Address: 0x1C8 | 67 | // NOMERGE-NEXT: Address: 0x20D |
| 68 | // NOMERGE-NEXT: Offset: 0x1C8 | 68 | // NOMERGE-NEXT: Offset: 0x20D |
| 69 | // NOMERGE-NEXT: Size: 11 | 69 | // NOMERGE-NEXT: Size: 11 |
| 70 | // NOMERGE-NEXT: Link: 0 | 70 | // NOMERGE-NEXT: Link: 0 |
| 71 | // NOMERGE-NEXT: Info: 0 | 71 | // NOMERGE-NEXT: Info: 0 |
| ... | @@ -82,8 +82,8 @@ zed: | ... | @@ -82,8 +82,8 @@ zed: |
| 82 | // CHECK-NEXT: SHF_MERGE | 82 | // CHECK-NEXT: SHF_MERGE |
| 83 | // CHECK-NEXT: SHF_STRINGS | 83 | // CHECK-NEXT: SHF_STRINGS |
| 84 | // CHECK-NEXT: ] | 84 | // CHECK-NEXT: ] |
| 85 | // CHECK-NEXT: Address: 0x1CC | 85 | // CHECK-NEXT: Address: 0x212 |
| 86 | // CHECK-NEXT: Offset: 0x1CC | 86 | // CHECK-NEXT: Offset: 0x212 |
| 87 | // CHECK-NEXT: Size: 4 | 87 | // CHECK-NEXT: Size: 4 |
| 88 | // CHECK-NEXT: Link: 0 | 88 | // CHECK-NEXT: Link: 0 |
| 89 | // CHECK-NEXT: Info: 0 | 89 | // CHECK-NEXT: Info: 0 |
| ... | @@ -95,11 +95,11 @@ zed: | ... | @@ -95,11 +95,11 @@ zed: |
| 95 | 95 | ||
| 96 | 96 | ||
| 97 | // CHECK: Name: bar | 97 | // CHECK: Name: bar |
| 98 | // CHECK-NEXT: Value: 0x1C9 | 98 | // CHECK-NEXT: Value: 0x20E |
| 99 | 99 | ||
| 100 | // CHECK: Name: foo | 100 | // CHECK: Name: foo |
| 101 | // CHECK-NEXT: Value: 0x1C8 | 101 | // CHECK-NEXT: Value: 0x20D |
| 102 | 102 | ||
| 103 | // CHECK: Name: zed | 103 | // CHECK: Name: zed |
| 104 | // CHECK-NEXT: Value: 0x1CC | 104 | // CHECK-NEXT: Value: 0x212 |
| 105 | // CHECK-NEXT: Size: 0 | 105 | // CHECK-NEXT: Size: 0 |
deps/lld/test/ELF/merge-sym.s+2-2| ... | @@ -15,7 +15,7 @@ foo: | ... | @@ -15,7 +15,7 @@ foo: |
| 15 | // CHECK-NEXT: SHF_ALLOC | 15 | // CHECK-NEXT: SHF_ALLOC |
| 16 | // CHECK-NEXT: SHF_MERGE | 16 | // CHECK-NEXT: SHF_MERGE |
| 17 | // CHECK-NEXT: ] | 17 | // CHECK-NEXT: ] |
| 18 | // CHECK-NEXT: Address: 0x1C8 | 18 | // CHECK-NEXT: Address: 0x210 |
| 19 | 19 | ||
| 20 | // CHECK: Name: foo | 20 | // CHECK: Name: foo |
| 21 | // CHECK-NEXT: Value: 0x1CA | 21 | // CHECK-NEXT: Value: 0x212 |
deps/lld/test/ELF/merge-to-non-alloc.s created+33| ... | @@ -0,0 +1,33 @@ | ||
| 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.so -shared | ||
| 4 | // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s | ||
| 5 | |||
| 6 | // CHECK: Name: .bar | ||
| 7 | // CHECK-NEXT: Type: SHT_PROGBITS | ||
| 8 | // CHECK-NEXT: Flags [ | ||
| 9 | // CHECK-NEXT: ] | ||
| 10 | // CHECK-NEXT: Address: | ||
| 11 | // CHECK-NEXT: Offset: | ||
| 12 | // CHECK-NEXT: Size: 16 | ||
| 13 | // CHECK-NEXT: Link: | ||
| 14 | // CHECK-NEXT: Info: | ||
| 15 | // CHECK-NEXT: AddressAlignment: | ||
| 16 | // CHECK-NEXT: EntrySize: | ||
| 17 | // CHECK-NEXT: SectionData ( | ||
| 18 | // CHECK-NEXT: 0000: 10020000 00000000 18020000 00000000 | | ||
| 19 | // CHECK-NEXT: ) | ||
| 20 | |||
| 21 | // CHECK: Name: foo | ||
| 22 | // CHECK-NEXT: Value: 0x210 | ||
| 23 | |||
| 24 | .section .foo,"aM",@progbits,4 | ||
| 25 | .align 4 | ||
| 26 | .global foo | ||
| 27 | .hidden foo | ||
| 28 | foo: | ||
| 29 | .long 0x42 | ||
| 30 | |||
| 31 | .section .bar | ||
| 32 | .quad foo | ||
| 33 | .quad foo + 8 | ||
deps/lld/test/ELF/mips-26-mask.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check reading/writing implicit addend for R_MIPS_26 relocation. | 2 | # Check reading/writing implicit addend for R_MIPS_26 relocation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -o %t.exe | 5 | # RUN: ld.lld %t.o -o %t.exe |
| 5 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | 6 | # RUN: llvm-objdump -d %t.exe | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | # CHECK: Disassembly of section .text: | 8 | # CHECK: Disassembly of section .text: |
| 10 | # CHECK: __start: | 9 | # CHECK: __start: |
| 11 | # CHECK-NEXT: 20000: 0e 00 80 00 jal 134348800 | 10 | # CHECK-NEXT: 20000: 0e 00 80 00 jal 134348800 |
deps/lld/test/ELF/mips-26-n32-n64.s+9-4| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_26 relocation handling in case of N64 ABIs. | 2 | # Check R_MIPS_26 relocation handling in case of N64 ABIs. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ |
| ... | @@ -5,9 +6,11 @@ | ... | @@ -5,9 +6,11 @@ |
| 5 | # RUN: ld.lld %t-so.o -shared -o %t.so | 6 | # RUN: ld.lld %t-so.o -shared -o %t.so |
| 6 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o | 7 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o |
| 7 | # RUN: ld.lld %t.o %t.so -o %t.exe | 8 | # RUN: ld.lld %t.o %t.so -o %t.exe |
| 8 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | 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 | ||
| 9 | 13 | ||
| 10 | # REQUIRES: mips | ||
| 11 | 14 | ||
| 12 | # CHECK: Disassembly of section .text: | 15 | # CHECK: Disassembly of section .text: |
| 13 | # CHECK-NEXT: __start: | 16 | # CHECK-NEXT: __start: |
| ... | @@ -21,11 +24,13 @@ | ... | @@ -21,11 +24,13 @@ |
| 21 | # CHECK-NEXT: 2001c: 03 0e c0 23 subu $24, $24, $14 | 24 | # CHECK-NEXT: 2001c: 03 0e c0 23 subu $24, $24, $14 |
| 22 | # CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra | 25 | # CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra |
| 23 | # CHECK-NEXT: 20024: 00 18 c0 c2 srl $24, $24, 3 | 26 | # CHECK-NEXT: 20024: 00 18 c0 c2 srl $24, $24, 3 |
| 24 | # CHECK-NEXT: 20028: 03 20 f8 09 jalr $25 | 27 | # DEFAULT: 20028: 03 20 f8 09 jalr $25 |
| 28 | # HAZARDPLT: 20028: 03 20 fc 09 jalr.hb $25 | ||
| 25 | # CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2 | 29 | # CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2 |
| 26 | # CHECK-NEXT: 20030: 3c 0f 00 03 lui $15, 3 | 30 | # CHECK-NEXT: 20030: 3c 0f 00 03 lui $15, 3 |
| 27 | # CHECK-NEXT: 20034: 8d f9 00 18 lw $25, 24($15) | 31 | # CHECK-NEXT: 20034: 8d f9 00 18 lw $25, 24($15) |
| 28 | # CHECK-NEXT: 20038: 03 20 00 08 jr $25 | 32 | # DEFAULT: 20038: 03 20 00 08 jr $25 |
| 33 | # HAZARDPLT: 20038: 03 20 04 08 jr.hb $25 | ||
| 29 | # CHECK-NEXT: 2003c: 25 f8 00 18 addiu $24, $15, 24 | 34 | # CHECK-NEXT: 2003c: 25 f8 00 18 addiu $24, $15, 24 |
| 30 | 35 | ||
| 31 | .text | 36 | .text |
deps/lld/test/ELF/mips-26.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_26 relocation handling. | 2 | # Check R_MIPS_26 relocation handling. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o |
| ... | @@ -9,8 +10,6 @@ | ... | @@ -9,8 +10,6 @@ |
| 9 | # 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 \ |
| 10 | # RUN: | FileCheck -check-prefix=REL %s | 11 | # RUN: | FileCheck -check-prefix=REL %s |
| 11 | 12 | ||
| 12 | # REQUIRES: mips | ||
| 13 | |||
| 14 | # CHECK: Disassembly of section .text: | 13 | # CHECK: Disassembly of section .text: |
| 15 | # CHECK-NEXT: bar: | 14 | # CHECK-NEXT: bar: |
| 16 | # CHECK-NEXT: 20000: 0c 00 80 06 jal 131096 <loc> | 15 | # CHECK-NEXT: 20000: 0c 00 80 06 jal 131096 <loc> |
deps/lld/test/ELF/mips-32.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_32 relocation calculation. | 2 | # Check R_MIPS_32 relocation calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o |
| ... | @@ -14,8 +15,6 @@ | ... | @@ -14,8 +15,6 @@ |
| 14 | # RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-el.so \ | 15 | # RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-el.so \ |
| 15 | # RUN: | FileCheck -check-prefix=REL %s | 16 | # RUN: | FileCheck -check-prefix=REL %s |
| 16 | 17 | ||
| 17 | # REQUIRES: mips | ||
| 18 | |||
| 19 | .globl __start | 18 | .globl __start |
| 20 | __start: | 19 | __start: |
| 21 | nop | 20 | nop |
deps/lld/test/ELF/mips-64-disp.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_GOT_DISP relocations against various kind of symbols. | 2 | # Check R_MIPS_GOT_DISP relocations against various kind of symbols. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ |
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s | 9 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s |
| 9 | # RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s | 10 | # RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | # CHECK: __start: | 12 | # CHECK: __start: |
| 14 | # CHECK-NEXT: 20000: 24 42 80 40 addiu $2, $2, -32704 | 13 | # CHECK-NEXT: 20000: 24 42 80 40 addiu $2, $2, -32704 |
| 15 | # CHECK-NEXT: 20004: 24 42 80 20 addiu $2, $2, -32736 | 14 | # CHECK-NEXT: 20004: 24 42 80 20 addiu $2, $2, -32736 |
deps/lld/test/ELF/mips-64-got-overflow.s created+80| ... | @@ -0,0 +1,80 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | # Check the primary GOT cannot be made to overflow | ||
| 3 | |||
| 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | ||
| 5 | # RUN: %p/Inputs/mips-64-got-load.s -o %t1.so.o | ||
| 6 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t2.so.o | ||
| 7 | # RUN: ld.lld -shared -mips-got-size 32 %t1.so.o %t2.so.o -o %t-sgot.so | ||
| 8 | # 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 | ||
| 11 | |||
| 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: } | ||
| 44 | |||
| 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: } | ||
| 72 | |||
| 73 | .text | ||
| 74 | .global foo2 | ||
| 75 | foo2: | ||
| 76 | ld $2, %got_disp(local2)($gp) | ||
| 77 | |||
| 78 | .bss | ||
| 79 | local2: | ||
| 80 | .word 0 | ||
deps/lld/test/ELF/mips-64-got.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check MIPS N64 ABI GOT relocations | 2 | # Check MIPS N64 ABI GOT relocations |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ |
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s | 9 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s |
| 9 | # RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s | 10 | # RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | # CHECK: __start: | 12 | # CHECK: __start: |
| 14 | 13 | ||
| 15 | # CHECK-NEXT: 20000: df 82 80 20 ld $2, -32736($gp) | 14 | # CHECK-NEXT: 20000: df 82 80 20 ld $2, -32736($gp) |
deps/lld/test/ELF/mips-64-gprel-so.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check setup of GP relative offsets in a function's prologue. | 2 | # Check setup of GP relative offsets in a function's prologue. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -shared -o %t.so | 5 | # RUN: ld.lld %t.o -shared -o %t.so |
| 5 | # RUN: llvm-objdump -d -t %t.so | FileCheck %s | 6 | # RUN: llvm-objdump -d -t %t.so | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | # CHECK: Disassembly of section .text: | 8 | # CHECK: Disassembly of section .text: |
| 10 | # CHECK-NEXT: foo: | 9 | # CHECK-NEXT: foo: |
| 11 | # CHECK-NEXT: 10000: 3c 1c 00 01 lui $gp, 1 | 10 | # CHECK-NEXT: 10000: 3c 1c 00 01 lui $gp, 1 |
deps/lld/test/ELF/mips-64-rels.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check handling multiple MIPS N64 ABI relocations packed | 2 | # Check handling multiple MIPS N64 ABI relocations packed |
| 2 | # into the single relocation record. | 3 | # into the single relocation record. |
| 3 | 4 | ||
| ... | @@ -6,8 +7,6 @@ | ... | @@ -6,8 +7,6 @@ |
| 6 | # RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s | 7 | # RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s |
| 7 | # RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s | 8 | # RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s |
| 8 | 9 | ||
| 9 | # REQUIRES: mips | ||
| 10 | |||
| 11 | # CHECK: __start: | 10 | # CHECK: __start: |
| 12 | # CHECK-NEXT: 20000: 3c 1c 00 01 lui $gp, 1 | 11 | # CHECK-NEXT: 20000: 3c 1c 00 01 lui $gp, 1 |
| 13 | # ^-- 0x20000 - 0x37ff0 | 12 | # ^-- 0x20000 - 0x37ff0 |
deps/lld/test/ELF/mips-64.s+6-8| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_64 relocation calculation. | 2 | # Check R_MIPS_64 relocation calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o |
| ... | @@ -5,8 +6,6 @@ | ... | @@ -5,8 +6,6 @@ |
| 5 | # RUN: llvm-objdump -t %t.so | FileCheck -check-prefix=SYM %s | 6 | # RUN: llvm-objdump -t %t.so | FileCheck -check-prefix=SYM %s |
| 6 | # 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 |
| 7 | 8 | ||
| 8 | # REQUIRES: mips | ||
| 9 | |||
| 10 | .global __start | 9 | .global __start |
| 11 | __start: | 10 | __start: |
| 12 | nop | 11 | nop |
| ... | @@ -30,17 +29,16 @@ v2: | ... | @@ -30,17 +29,16 @@ v2: |
| 30 | # SYM: 00020008 g .data 00000008 v2 | 29 | # SYM: 00020008 g .data 00000008 v2 |
| 31 | 30 | ||
| 32 | # CHECK: Relocations [ | 31 | # CHECK: Relocations [ |
| 33 | # CHECK-NEXT: Section (7) .rela.dyn { | 32 | # CHECK-NEXT: Section (7) .rel.dyn { |
| 34 | # CHECK-NEXT: 0x20010 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x20000 | 33 | # CHECK-NEXT: 0x20010 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x0 |
| 35 | # ^-- v1 | 34 | # CHECK-NEXT: 0x20008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE v2 0x0 |
| 36 | # CHECK-NEXT: 0x20008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE v2 0x8 | ||
| 37 | # CHECK-NEXT: } | 35 | # CHECK-NEXT: } |
| 38 | # CHECK-NEXT: ] | 36 | # CHECK-NEXT: ] |
| 39 | 37 | ||
| 40 | # CHECK: DynamicSection [ | 38 | # CHECK: DynamicSection [ |
| 41 | # CHECK: Tag Type Name/Value | 39 | # CHECK: Tag Type Name/Value |
| 42 | # CHECK: 0x0000000000000008 RELASZ 48 (bytes) | 40 | # CHECK: 0x0000000000000012 RELSZ 32 (bytes) |
| 43 | # CHECK: 0x0000000000000009 RELAENT 24 (bytes) | 41 | # CHECK: 0x0000000000000013 RELENT 16 (bytes) |
| 44 | 42 | ||
| 45 | # CHECK: Primary GOT { | 43 | # CHECK: Primary GOT { |
| 46 | # CHECK-NEXT: Canonical gp value: | 44 | # CHECK-NEXT: Canonical gp value: |
deps/lld/test/ELF/mips-abs-got.s created+36| ... | @@ -0,0 +1,36 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | |||
| 3 | # Check GOT relocations against absolute symbols. | ||
| 4 | |||
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -o %t.o %s | ||
| 6 | # RUN: echo "SECTIONS { \ | ||
| 7 | # RUN: zero = 0; foo = 0x11004; bar = 0x22000; }" > %t.script | ||
| 8 | # RUN: ld.lld --script %t.script -o %t.exe %t.o | ||
| 9 | # RUN: llvm-readobj -mips-plt-got %t.exe | FileCheck %s | ||
| 10 | |||
| 11 | # CHECK: Static GOT { | ||
| 12 | # CHECK: Local entries [ | ||
| 13 | # CHECK-NEXT: Entry { | ||
| 14 | # CHECK-NEXT: Address: | ||
| 15 | # CHECK-NEXT: Access: -32736 | ||
| 16 | # CHECK-NEXT: Initial: 0x0 | ||
| 17 | # CHECK-NEXT: } | ||
| 18 | # CHECK-NEXT: Entry { | ||
| 19 | # CHECK-NEXT: Address: | ||
| 20 | # CHECK-NEXT: Access: -32728 | ||
| 21 | # CHECK-NEXT: Initial: 0x10000 | ||
| 22 | # CHECK-NEXT: } | ||
| 23 | # CHECK-NEXT: Entry { | ||
| 24 | # CHECK-NEXT: Address: | ||
| 25 | # CHECK-NEXT: Access: -32720 | ||
| 26 | # CHECK-NEXT: Initial: 0x30000 | ||
| 27 | # CHECK-NEXT: } | ||
| 28 | # CHECK-NEXT: ] | ||
| 29 | # CHECK-NEXT: } | ||
| 30 | |||
| 31 | .text | ||
| 32 | nop | ||
| 33 | .reloc 0, R_MIPS_GOT_PAGE, 0 | ||
| 34 | ld $v0, %got_page(zero)($gp) | ||
| 35 | ld $v0, %got_page(foo)($gp) | ||
| 36 | ld $v0, %got_page(bar+0x10008)($gp) | ||
deps/lld/test/ELF/mips-align-err.s+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | # RUN: -mcpu=mips32r6 | 3 | # RUN: -mcpu=mips32r6 |
| 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| 5 | # RUN: -mcpu=mips32r6 %S/Inputs/mips-align-err.s -o %t2.o | 5 | # RUN: -mcpu=mips32r6 %S/Inputs/mips-align-err.s -o %t2.o |
| 6 | # RUN: not ld.lld %t.o %t2.o -o %t.exe 2>&1 | FileCheck %s | 6 | # RUN: not ld.lld %t.o %t2.o -o /dev/null 2>&1 | FileCheck %s |
| 7 | # CHECK: {{.*}}:(.text+0x1): improper alignment for relocation R_MIPS_PC16: 0xB is not aligned to 4 bytes | 7 | # CHECK: {{.*}}:(.text+0x1): improper alignment for relocation R_MIPS_PC16: 0xB is not aligned to 4 bytes |
| 8 | 8 | ||
| 9 | .globl __start | 9 | .globl __start |
deps/lld/test/ELF/mips-call-hilo.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_CALL_HI16 / R_MIPS_CALL_LO16 relocations calculation. | 2 | # Check R_MIPS_CALL_HI16 / R_MIPS_CALL_LO16 relocations calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| ... | @@ -5,8 +6,6 @@ | ... | @@ -5,8 +6,6 @@ |
| 5 | # RUN: llvm-objdump -d %t.so | FileCheck %s | 6 | # RUN: llvm-objdump -d %t.so | FileCheck %s |
| 6 | # 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 |
| 7 | 8 | ||
| 8 | # REQUIRES: mips | ||
| 9 | |||
| 10 | # CHECK: Disassembly of section .text: | 9 | # CHECK: Disassembly of section .text: |
| 11 | # CHECK-NEXT: foo: | 10 | # CHECK-NEXT: foo: |
| 12 | # CHECK-NEXT: 10000: 3c 02 00 00 lui $2, 0 | 11 | # CHECK-NEXT: 10000: 3c 02 00 00 lui $2, 0 |
deps/lld/test/ELF/mips-call16.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_CALL16 relocation calculation. | 2 | # Check R_MIPS_CALL16 relocation calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| ... | @@ -6,8 +7,6 @@ | ... | @@ -6,8 +7,6 @@ |
| 6 | # RUN: llvm-readobj -mips-plt-got -symbols %t.exe \ | 7 | # RUN: llvm-readobj -mips-plt-got -symbols %t.exe \ |
| 7 | # RUN: | FileCheck -check-prefix=GOT %s | 8 | # RUN: | FileCheck -check-prefix=GOT %s |
| 8 | 9 | ||
| 9 | # REQUIRES: mips | ||
| 10 | |||
| 11 | .text | 10 | .text |
| 12 | .globl __start | 11 | .globl __start |
| 13 | __start: | 12 | __start: |
deps/lld/test/ELF/mips-dynamic.s+35-14| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check MIPS specific .dynamic section entries. | 2 | # Check MIPS specific .dynamic section entries. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| ... | @@ -6,7 +7,11 @@ | ... | @@ -6,7 +7,11 @@ |
| 6 | 7 | ||
| 7 | # RUN: ld.lld %t.o %td.so -o %t.exe | 8 | # RUN: ld.lld %t.o %td.so -o %t.exe |
| 8 | # RUN: llvm-readobj -sections -dynamic-table %t.exe \ | 9 | # RUN: llvm-readobj -sections -dynamic-table %t.exe \ |
| 9 | # RUN: | FileCheck -check-prefix=EXE %s | 10 | # RUN: | FileCheck -check-prefixes=EXE,NOPIE %s |
| 11 | |||
| 12 | # RUN: ld.lld -pie %t.o %td.so -o %t.so | ||
| 13 | # RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \ | ||
| 14 | # RUN: | FileCheck -check-prefixes=EXE,PIE %s | ||
| 10 | 15 | ||
| 11 | # RUN: ld.lld %t.o --image-base=0x123000 %td.so -o %t.exe | 16 | # RUN: ld.lld %t.o --image-base=0x123000 %td.so -o %t.exe |
| 12 | # RUN: llvm-readobj -sections -dynamic-table %t.exe \ | 17 | # RUN: llvm-readobj -sections -dynamic-table %t.exe \ |
| ... | @@ -16,8 +21,6 @@ | ... | @@ -16,8 +21,6 @@ |
| 16 | # RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \ | 21 | # RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \ |
| 17 | # RUN: | FileCheck -check-prefix=DSO %s | 22 | # RUN: | FileCheck -check-prefix=DSO %s |
| 18 | 23 | ||
| 19 | # REQUIRES: mips | ||
| 20 | |||
| 21 | # EXE: Sections [ | 24 | # EXE: Sections [ |
| 22 | # EXE: Name: .dynamic | 25 | # EXE: Name: .dynamic |
| 23 | # EXE-NEXT: Type: SHT_DYNAMIC | 26 | # EXE-NEXT: Type: SHT_DYNAMIC |
| ... | @@ -44,17 +47,35 @@ | ... | @@ -44,17 +47,35 @@ |
| 44 | # EXE-NEXT: Offset: | 47 | # EXE-NEXT: Offset: |
| 45 | # EXE-NEXT: Size: 8 | 48 | # EXE-NEXT: Size: 8 |
| 46 | # EXE: ] | 49 | # EXE: ] |
| 47 | # EXE: DynamicSection [ | 50 | |
| 48 | # EXE-NEXT: Tag Type Name/Value | 51 | # PIE: DynamicSection [ |
| 49 | # EXE-DAG: 0x00000003 PLTGOT [[GOTADDR]] | 52 | # PIE-NEXT: Tag Type Name/Value |
| 50 | # EXE-DAG: 0x70000001 MIPS_RLD_VERSION 1 | 53 | # PIE: 0x00000004 HASH 0x{{[0-9A-F]+}} |
| 51 | # EXE-DAG: 0x70000005 MIPS_FLAGS NOTPOT | 54 | # PIE-NEXT: 0x70000001 MIPS_RLD_VERSION 1 |
| 52 | # EXE-DAG: 0x70000006 MIPS_BASE_ADDRESS 0x10000 | 55 | # PIE-NEXT: 0x70000005 MIPS_FLAGS NOTPOT |
| 53 | # EXE-DAG: 0x7000000A MIPS_LOCAL_GOTNO 2 | 56 | # PIE-NEXT: 0x70000006 MIPS_BASE_ADDRESS 0x0 |
| 54 | # EXE-DAG: 0x70000011 MIPS_SYMTABNO 2 | 57 | # PIE-NEXT: 0x70000011 MIPS_SYMTABNO 2 |
| 55 | # EXE-DAG: 0x70000013 MIPS_GOTSYM 0x2 | 58 | # PIE-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 2 |
| 56 | # EXE-DAG: 0x70000016 MIPS_RLD_MAP [[RLDMAPADDR]] | 59 | # PIE-NEXT: 0x70000013 MIPS_GOTSYM 0x2 |
| 57 | # EXE: ] | 60 | # PIE-NEXT: 0x00000003 PLTGOT [[GOTADDR]] |
| 61 | # PIE-NEXT: 0x70000035 MIPS_RLD_MAP_REL 0x{{[0-9A-F]+}} | ||
| 62 | # PIE-NEXT: 0x00000000 NULL 0x0 | ||
| 63 | # PIE-NEXT: ] | ||
| 64 | |||
| 65 | # NOPIE: DynamicSection [ | ||
| 66 | # NOPIE-NEXT: Tag Type Name/Value | ||
| 67 | # NOPIE: 0x00000004 HASH 0x{{[0-9A-F]+}} | ||
| 68 | # NOPIE-NEXT: 0x70000001 MIPS_RLD_VERSION 1 | ||
| 69 | # NOPIE-NEXT: 0x70000005 MIPS_FLAGS NOTPOT | ||
| 70 | # NOPIE-NEXT: 0x70000006 MIPS_BASE_ADDRESS 0x10000 | ||
| 71 | # NOPIE-NEXT: 0x70000011 MIPS_SYMTABNO 2 | ||
| 72 | # NOPIE-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 2 | ||
| 73 | # NOPIE-NEXT: 0x70000013 MIPS_GOTSYM 0x2 | ||
| 74 | # NOPIE-NEXT: 0x00000003 PLTGOT [[GOTADDR]] | ||
| 75 | # NOPIE-NEXT: 0x70000016 MIPS_RLD_MAP [[RLDMAPADDR]] | ||
| 76 | # NOPIE-NEXT: 0x70000035 MIPS_RLD_MAP_REL 0x{{[0-9A-F]+}} | ||
| 77 | # NOPIE-NEXT: 0x00000000 NULL 0x0 | ||
| 78 | # NOPIE-NEXT: ] | ||
| 58 | 79 | ||
| 59 | # IMAGE_BASE: 0x70000006 MIPS_BASE_ADDRESS 0x123000 | 80 | # IMAGE_BASE: 0x70000006 MIPS_BASE_ADDRESS 0x123000 |
| 60 | 81 |
deps/lld/test/ELF/mips-dynsym-sort.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check the order of dynamic symbols for the MIPS target. | 2 | # Check the order of dynamic symbols for the MIPS target. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o |
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | # RUN: ld.lld -shared %t-el.o -o %t-el.so | 9 | # RUN: ld.lld -shared %t-el.o -o %t-el.so |
| 9 | # RUN: llvm-readobj -symbols -dyn-symbols %t-el.so | FileCheck %s | 10 | # RUN: llvm-readobj -symbols -dyn-symbols %t-el.so | FileCheck %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | .data | 12 | .data |
| 14 | .globl v1,v2,v3 | 13 | .globl v1,v2,v3 |
| 15 | v1: | 14 | v1: |
deps/lld/test/ELF/mips-elf-abi.s created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | # Check EI_ABIVERSION flags | ||
| 3 | |||
| 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | ||
| 5 | # RUN: ld.lld -shared -o %t.so %t.o | ||
| 6 | # RUN: llvm-readobj -h %t.so | FileCheck -check-prefix=DSO %s | ||
| 7 | # RUN: ld.lld -o %t.exe %t.o | ||
| 8 | # RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=EXE %s | ||
| 9 | # RUN: ld.lld -pie -o %t.pie %t.o | ||
| 10 | # RUN: llvm-readobj -h %t.pie | FileCheck -check-prefix=PIE %s | ||
| 11 | # RUN: ld.lld -r -o %t.rel %t.o | ||
| 12 | # RUN: llvm-readobj -h %t.rel | FileCheck -check-prefix=REL %s | ||
| 13 | |||
| 14 | # DSO: ABIVersion: 0 | ||
| 15 | # EXE: ABIVersion: 1 | ||
| 16 | # PIE: ABIVersion: 0 | ||
| 17 | # REL: ABIVersion: 0 | ||
| 18 | |||
| 19 | .global __start | ||
| 20 | .text | ||
| 21 | __start: | ||
| 22 | nop | ||
deps/lld/test/ELF/mips-elf-flags-err.s+1-32| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check MIPS ELF ISA flag calculation if input files have different ISAs. | 2 | # Check MIPS ELF ISA flag calculation if input files have different ISAs. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -24,14 +25,6 @@ | ... | @@ -24,14 +25,6 @@ |
| 24 | # RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 \ | 25 | # RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 \ |
| 25 | # RUN: | FileCheck -check-prefix=R6OCTEON %s | 26 | # RUN: | FileCheck -check-prefix=R6OCTEON %s |
| 26 | 27 | ||
| 27 | # Check that lld does not allow to link incompatible floating point ABI. | ||
| 28 | |||
| 29 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 30 | # RUN: -mcpu=mips32 %S/Inputs/mips-dynamic.s -o %t1.o | ||
| 31 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 32 | # RUN: -mcpu=mips32 -mattr=+fp64 %s -o %t2.o | ||
| 33 | # RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=FPABI %s | ||
| 34 | |||
| 35 | # Check that lld take in account EF_MIPS_MACH_XXX ISA flags | 28 | # Check that lld take in account EF_MIPS_MACH_XXX ISA flags |
| 36 | 29 | ||
| 37 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | 30 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ |
| ... | @@ -41,24 +34,6 @@ | ... | @@ -41,24 +34,6 @@ |
| 41 | # RUN: ld.lld %t1.o %t2.o -o %t.exe | 34 | # RUN: ld.lld %t1.o %t2.o -o %t.exe |
| 42 | # RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=OCTEON %s | 35 | # RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=OCTEON %s |
| 43 | 36 | ||
| 44 | # Check that lld does not allow to link incompatible ABIs. | ||
| 45 | |||
| 46 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 47 | # RUN: -target-abi n32 %S/Inputs/mips-dynamic.s -o %t1.o | ||
| 48 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 49 | # RUN: -target-abi o32 %s -o %t2.o | ||
| 50 | # RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=N32O32 %s | ||
| 51 | |||
| 52 | # Check that lld does not allow to link modules with incompatible NAN flags. | ||
| 53 | |||
| 54 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 55 | # RUN: -mattr=+nan2008 %S/Inputs/mips-dynamic.s -o %t1.o | ||
| 56 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 57 | # RUN: %s -o %t2.o | ||
| 58 | # RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=NAN %s | ||
| 59 | |||
| 60 | # REQUIRES: mips | ||
| 61 | |||
| 62 | .option pic0 | 37 | .option pic0 |
| 63 | .text | 38 | .text |
| 64 | .global __start | 39 | .global __start |
| ... | @@ -79,14 +54,8 @@ __start: | ... | @@ -79,14 +54,8 @@ __start: |
| 79 | # R6OCTEON-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp1.o: mips64r6 | 54 | # R6OCTEON-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp1.o: mips64r6 |
| 80 | # R6OCTEON-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp2.o: mips64r2 (octeon) | 55 | # R6OCTEON-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp2.o: mips64r2 (octeon) |
| 81 | 56 | ||
| 82 | # FPABI: target floating point ABI '-mdouble-float' is incompatible with '-mgp32 -mfp64': {{.*}}mips-elf-flags-err.s.tmp2.o | ||
| 83 | |||
| 84 | # OCTEON: Flags [ | 57 | # OCTEON: Flags [ |
| 85 | # OCTEON-NEXT: EF_MIPS_ARCH_64R2 | 58 | # OCTEON-NEXT: EF_MIPS_ARCH_64R2 |
| 86 | # OCTEON-NEXT: EF_MIPS_CPIC | 59 | # OCTEON-NEXT: EF_MIPS_CPIC |
| 87 | # OCTEON-NEXT: EF_MIPS_MACH_OCTEON | 60 | # OCTEON-NEXT: EF_MIPS_MACH_OCTEON |
| 88 | # OCTEON: ] | 61 | # OCTEON: ] |
| 89 | |||
| 90 | # N32O32: error: {{.*}}mips-elf-flags-err.s.tmp2.o is incompatible with {{.*}}mips-elf-flags-err.s.tmp1.o | ||
| 91 | |||
| 92 | # NAN: target -mnan=2008 is incompatible with -mnan=legacy: {{.*}}mips-elf-flags-err.s.tmp2.o |
deps/lld/test/ELF/mips-elf-flags-err.test created+89| ... | @@ -0,0 +1,89 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | # | ||
| 3 | # Check warning and errors in case of input | ||
| 4 | # files with incompatible ELF header flags. | ||
| 5 | |||
| 6 | # RUN: yaml2obj -docnum 1 %s -o %t-n64.o | ||
| 7 | # RUN: yaml2obj -docnum 2 %s -o %t-o64.o | ||
| 8 | # RUN: yaml2obj -docnum 3 %s -o %t-n32.o | ||
| 9 | # RUN: yaml2obj -docnum 4 %s -o %t-o32.o | ||
| 10 | # RUN: yaml2obj -docnum 5 %s -o %t-eabi64.o | ||
| 11 | # RUN: yaml2obj -docnum 6 %s -o %t-eabi32.o | ||
| 12 | |||
| 13 | # RUN: not ld.lld %t-n64.o %t-eabi64.o -shared -o /dev/null 2>&1 \ | ||
| 14 | # RUN: | FileCheck -check-prefixes=MM64,N64EABI64 %s | ||
| 15 | # | ||
| 16 | # RUN: not ld.lld %t-n64.o %t-o64.o -shared -o /dev/null 2>&1 \ | ||
| 17 | # RUN: | FileCheck -check-prefixes=MM64,N64O64 %s | ||
| 18 | |||
| 19 | # RUN: not ld.lld %t-o32.o %t-eabi32.o -shared -o /dev/null 2>&1 \ | ||
| 20 | # RUN: | FileCheck -check-prefixes=O32EABI32,FP64,CPIC1 %s | ||
| 21 | |||
| 22 | # RUN: not ld.lld %t-eabi32.o %t-o32.o -shared -o /dev/null 2>&1 \ | ||
| 23 | # RUN: | FileCheck -check-prefix=CPIC2 %s | ||
| 24 | |||
| 25 | # MM64: {{.*}}n64.o: microMIPS 64-bit is not supported | ||
| 26 | |||
| 27 | # N64EABI64: {{.*}}eabi64.o: ABI 'eabi64' is incompatible with target ABI 'n64' | ||
| 28 | # N64O64: {{.*}}o64.o: ABI 'o64' is incompatible with target ABI 'n64' | ||
| 29 | # O32EABI32: {{.*}}eabi32.o: ABI 'eabi32' is incompatible with target ABI 'o32' | ||
| 30 | |||
| 31 | # NAN: {{.*}}o32.o: -mnan=legacy is incompatible with target -mnan=2008 | ||
| 32 | # FP64: {{.*}}eabi32.o: -mfp64 is incompatible with target -mfp32 | ||
| 33 | |||
| 34 | # CPIC1: {{.*}}tmp-eabi32.o: linking non-abicalls code with abicalls code {{.*}}o32.o | ||
| 35 | # CPIC2: {{.*}}tmp-o32.o: linking abicalls code with non-abicalls code {{.*}}eabi32.o | ||
| 36 | |||
| 37 | # n64.o | ||
| 38 | --- !ELF | ||
| 39 | FileHeader: | ||
| 40 | Class: ELFCLASS64 | ||
| 41 | Data: ELFDATA2MSB | ||
| 42 | Type: ET_REL | ||
| 43 | Machine: EM_MIPS | ||
| 44 | Flags: [ EF_MIPS_ARCH_64, EF_MIPS_MICROMIPS ] | ||
| 45 | |||
| 46 | # o64.o | ||
| 47 | --- !ELF | ||
| 48 | FileHeader: | ||
| 49 | Class: ELFCLASS64 | ||
| 50 | Data: ELFDATA2MSB | ||
| 51 | Type: ET_REL | ||
| 52 | Machine: EM_MIPS | ||
| 53 | Flags: [ EF_MIPS_ABI_O64, EF_MIPS_ARCH_64 ] | ||
| 54 | |||
| 55 | # n32.o | ||
| 56 | --- !ELF | ||
| 57 | FileHeader: | ||
| 58 | Class: ELFCLASS32 | ||
| 59 | Data: ELFDATA2MSB | ||
| 60 | Type: ET_REL | ||
| 61 | Machine: EM_MIPS | ||
| 62 | Flags: [ EF_MIPS_ARCH_64, EF_MIPS_ABI2, EF_MIPS_NAN2008 ] | ||
| 63 | |||
| 64 | # o32.o | ||
| 65 | --- !ELF | ||
| 66 | FileHeader: | ||
| 67 | Class: ELFCLASS32 | ||
| 68 | Data: ELFDATA2MSB | ||
| 69 | Type: ET_REL | ||
| 70 | Machine: EM_MIPS | ||
| 71 | Flags: [ EF_MIPS_ARCH_32, EF_MIPS_ABI_O32, EF_MIPS_CPIC ] | ||
| 72 | |||
| 73 | # eabi64.o | ||
| 74 | --- !ELF | ||
| 75 | FileHeader: | ||
| 76 | Class: ELFCLASS64 | ||
| 77 | Data: ELFDATA2MSB | ||
| 78 | Type: ET_REL | ||
| 79 | Machine: EM_MIPS | ||
| 80 | Flags: [ EF_MIPS_ARCH_64, EF_MIPS_ABI_EABI64 ] | ||
| 81 | |||
| 82 | # eabi32.o | ||
| 83 | --- !ELF | ||
| 84 | FileHeader: | ||
| 85 | Class: ELFCLASS32 | ||
| 86 | Data: ELFDATA2MSB | ||
| 87 | Type: ET_REL | ||
| 88 | Machine: EM_MIPS | ||
| 89 | Flags: [ EF_MIPS_ARCH_32, EF_MIPS_ABI_EABI32, EF_MIPS_FP64 ] | ||
deps/lld/test/ELF/mips-elf-flags.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check generation of MIPS specific ELF header flags. | 2 | # Check generation of MIPS specific ELF header flags. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -41,8 +42,6 @@ | ... | @@ -41,8 +42,6 @@ |
| 41 | # RUN: ld.lld %t.o %t-mm.o -o %t.exe | 42 | # RUN: ld.lld %t.o %t-mm.o -o %t.exe |
| 42 | # 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 |
| 43 | 44 | ||
| 44 | # REQUIRES: mips | ||
| 45 | |||
| 46 | .text | 45 | .text |
| 47 | .globl __start | 46 | .globl __start |
| 48 | __start: | 47 | __start: |
deps/lld/test/ELF/mips-fp-flags-err.test created+162| ... | @@ -0,0 +1,162 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | # | ||
| 3 | # Check warning and errors in case of input | ||
| 4 | # files with incompatible floating point ABI flags. | ||
| 5 | |||
| 6 | # RUN: yaml2obj -docnum 1 %s -o %t-dbl.o | ||
| 7 | # RUN: yaml2obj -docnum 2 %s -o %t-sgl.o | ||
| 8 | # RUN: yaml2obj -docnum 3 %s -o %t-soft.o | ||
| 9 | # RUN: yaml2obj -docnum 4 %s -o %t-fp64.o | ||
| 10 | # RUN: yaml2obj -docnum 5 %s -o %t-fp64old.o | ||
| 11 | # RUN: yaml2obj -docnum 6 %s -o %t-fp64a.o | ||
| 12 | # RUN: yaml2obj -docnum 7 %s -o %t-fpxx.o | ||
| 13 | |||
| 14 | # RUN: not ld.lld %t-dbl.o %t-fp64.o -shared -o /dev/null 2>&1 \ | ||
| 15 | # RUN: | FileCheck -check-prefixes=DBLFP64 %s | ||
| 16 | |||
| 17 | # RUN: not ld.lld %t-sgl.o %t-fp64old.o -shared -o /dev/null 2>&1 \ | ||
| 18 | # RUN: | FileCheck -check-prefixes=SGLFP64OLD %s | ||
| 19 | |||
| 20 | # RUN: not ld.lld %t-soft.o %t-fp64a.o -shared -o /dev/null 2>&1 \ | ||
| 21 | # RUN: | FileCheck -check-prefixes=SOFTFP64A %s | ||
| 22 | |||
| 23 | # RUN: not ld.lld %t-sgl.o %t-fpxx.o -shared -o /dev/null 2>&1 \ | ||
| 24 | # RUN: | FileCheck -check-prefixes=SGLFPXX %s | ||
| 25 | |||
| 26 | # DBLFP64: {{.*}}fp64.o: floating point ABI '-mgp32 -mfp64' is incompatible with target floating point ABI '-mdouble-float' | ||
| 27 | # SGLFP64OLD: {{.*}}fp64old.o: floating point ABI '-mgp32 -mfp64 (old)' is incompatible with target floating point ABI '-msingle-float' | ||
| 28 | # SOFTFP64A: {{.*}}fp64a.o: floating point ABI '-mgp32 -mfp64 -mno-odd-spreg' is incompatible with target floating point ABI '-msoft-float' | ||
| 29 | # SGLFPXX: {{.*}}fpxx.o: floating point ABI '-mfpxx' is incompatible with target floating point ABI '-msingle-float' | ||
| 30 | |||
| 31 | # dbl.o | ||
| 32 | --- !ELF | ||
| 33 | FileHeader: | ||
| 34 | Class: ELFCLASS64 | ||
| 35 | Data: ELFDATA2MSB | ||
| 36 | Type: ET_REL | ||
| 37 | Machine: EM_MIPS | ||
| 38 | Flags: [ EF_MIPS_ARCH_64 ] | ||
| 39 | |||
| 40 | Sections: | ||
| 41 | - Name: .MIPS.abiflags | ||
| 42 | Type: SHT_MIPS_ABIFLAGS | ||
| 43 | ISA: MIPS64 | ||
| 44 | ASEs: [] | ||
| 45 | FpABI: FP_DOUBLE | ||
| 46 | GPRSize: REG_64 | ||
| 47 | CPR1Size: REG_64 | ||
| 48 | CPR2Size: REG_NONE | ||
| 49 | |||
| 50 | # sgl.o | ||
| 51 | --- !ELF | ||
| 52 | FileHeader: | ||
| 53 | Class: ELFCLASS64 | ||
| 54 | Data: ELFDATA2MSB | ||
| 55 | Type: ET_REL | ||
| 56 | Machine: EM_MIPS | ||
| 57 | Flags: [ EF_MIPS_ARCH_64 ] | ||
| 58 | |||
| 59 | Sections: | ||
| 60 | - Name: .MIPS.abiflags | ||
| 61 | Type: SHT_MIPS_ABIFLAGS | ||
| 62 | ISA: MIPS64 | ||
| 63 | ASEs: [] | ||
| 64 | FpABI: FP_SINGLE | ||
| 65 | GPRSize: REG_64 | ||
| 66 | CPR1Size: REG_64 | ||
| 67 | CPR2Size: REG_NONE | ||
| 68 | |||
| 69 | # soft.o | ||
| 70 | --- !ELF | ||
| 71 | FileHeader: | ||
| 72 | Class: ELFCLASS64 | ||
| 73 | Data: ELFDATA2MSB | ||
| 74 | Type: ET_REL | ||
| 75 | Machine: EM_MIPS | ||
| 76 | Flags: [ EF_MIPS_ARCH_64 ] | ||
| 77 | |||
| 78 | Sections: | ||
| 79 | - Name: .MIPS.abiflags | ||
| 80 | Type: SHT_MIPS_ABIFLAGS | ||
| 81 | ISA: MIPS64 | ||
| 82 | ASEs: [] | ||
| 83 | FpABI: FP_SOFT | ||
| 84 | GPRSize: REG_64 | ||
| 85 | CPR1Size: REG_64 | ||
| 86 | CPR2Size: REG_NONE | ||
| 87 | |||
| 88 | # fp64.o | ||
| 89 | --- !ELF | ||
| 90 | FileHeader: | ||
| 91 | Class: ELFCLASS64 | ||
| 92 | Data: ELFDATA2MSB | ||
| 93 | Type: ET_REL | ||
| 94 | Machine: EM_MIPS | ||
| 95 | Flags: [ EF_MIPS_ARCH_64 ] | ||
| 96 | |||
| 97 | Sections: | ||
| 98 | - Name: .MIPS.abiflags | ||
| 99 | Type: SHT_MIPS_ABIFLAGS | ||
| 100 | ISA: MIPS64 | ||
| 101 | ASEs: [] | ||
| 102 | FpABI: FP_64 | ||
| 103 | GPRSize: REG_64 | ||
| 104 | CPR1Size: REG_64 | ||
| 105 | CPR2Size: REG_NONE | ||
| 106 | |||
| 107 | # fp64old.o | ||
| 108 | --- !ELF | ||
| 109 | FileHeader: | ||
| 110 | Class: ELFCLASS64 | ||
| 111 | Data: ELFDATA2MSB | ||
| 112 | Type: ET_REL | ||
| 113 | Machine: EM_MIPS | ||
| 114 | Flags: [ EF_MIPS_ARCH_64 ] | ||
| 115 | |||
| 116 | Sections: | ||
| 117 | - Name: .MIPS.abiflags | ||
| 118 | Type: SHT_MIPS_ABIFLAGS | ||
| 119 | ISA: MIPS64 | ||
| 120 | ASEs: [] | ||
| 121 | FpABI: FP_OLD_64 | ||
| 122 | GPRSize: REG_64 | ||
| 123 | CPR1Size: REG_64 | ||
| 124 | CPR2Size: REG_NONE | ||
| 125 | |||
| 126 | # fp64a.o | ||
| 127 | --- !ELF | ||
| 128 | FileHeader: | ||
| 129 | Class: ELFCLASS64 | ||
| 130 | Data: ELFDATA2MSB | ||
| 131 | Type: ET_REL | ||
| 132 | Machine: EM_MIPS | ||
| 133 | Flags: [ EF_MIPS_ARCH_64 ] | ||
| 134 | |||
| 135 | Sections: | ||
| 136 | - Name: .MIPS.abiflags | ||
| 137 | Type: SHT_MIPS_ABIFLAGS | ||
| 138 | ISA: MIPS64 | ||
| 139 | ASEs: [] | ||
| 140 | FpABI: FP_64A | ||
| 141 | GPRSize: REG_64 | ||
| 142 | CPR1Size: REG_64 | ||
| 143 | CPR2Size: REG_NONE | ||
| 144 | |||
| 145 | # fpxx.o | ||
| 146 | --- !ELF | ||
| 147 | FileHeader: | ||
| 148 | Class: ELFCLASS64 | ||
| 149 | Data: ELFDATA2MSB | ||
| 150 | Type: ET_REL | ||
| 151 | Machine: EM_MIPS | ||
| 152 | Flags: [ EF_MIPS_ARCH_64 ] | ||
| 153 | |||
| 154 | Sections: | ||
| 155 | - Name: .MIPS.abiflags | ||
| 156 | Type: SHT_MIPS_ABIFLAGS | ||
| 157 | ISA: MIPS64 | ||
| 158 | ASEs: [] | ||
| 159 | FpABI: FP_XX | ||
| 160 | GPRSize: REG_64 | ||
| 161 | CPR1Size: REG_64 | ||
| 162 | CPR2Size: REG_NONE | ||
deps/lld/test/ELF/mips-gnu-hash.s+3-4| ... | @@ -1,15 +1,14 @@ | ... | @@ -1,15 +1,14 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Shouldn't allow the GNU hash style to be selected with the MIPS target. | 2 | # Shouldn't allow the GNU hash style to be selected with the MIPS target. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o |
| 4 | # RUN: not ld.lld -shared -hash-style=gnu %t-be.o -o %t-be.so 2>&1 | FileCheck %s | 5 | # RUN: not ld.lld -shared -hash-style=gnu %t-be.o -o /dev/null 2>&1 | FileCheck %s |
| 5 | 6 | ||
| 6 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o | 7 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o |
| 7 | # RUN: not ld.lld -shared -hash-style=gnu %t-el.o -o %t-el.so 2>&1 | FileCheck %s | 8 | # RUN: not ld.lld -shared -hash-style=gnu %t-el.o -o /dev/null 2>&1 | FileCheck %s |
| 8 | 9 | ||
| 9 | # CHECK: the .gnu.hash section is not compatible with the MIPS target. | 10 | # CHECK: the .gnu.hash section is not compatible with the MIPS target. |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | .globl __start | 12 | .globl __start |
| 14 | __start: | 13 | __start: |
| 15 | nop | 14 | nop |
deps/lld/test/ELF/mips-got-and-copy.s+6-2| ... | @@ -23,13 +23,17 @@ | ... | @@ -23,13 +23,17 @@ |
| 23 | # CHECK-NEXT: Reserved entries [ | 23 | # CHECK-NEXT: Reserved entries [ |
| 24 | # CHECK: ] | 24 | # CHECK: ] |
| 25 | # CHECK-NEXT: Local entries [ | 25 | # CHECK-NEXT: Local entries [ |
| 26 | # CHECK-NEXT: ] | ||
| 27 | # CHECK-NEXT: Global entries [ | ||
| 26 | # CHECK-NEXT: Entry { | 28 | # CHECK-NEXT: Entry { |
| 27 | # CHECK-NEXT: Address: | 29 | # CHECK-NEXT: Address: |
| 28 | # CHECK-NEXT: Access: -32744 | 30 | # CHECK-NEXT: Access: -32744 |
| 29 | # CHECK-NEXT: Initial: 0x[[DATA0]] | 31 | # CHECK-NEXT: Initial: 0x[[DATA0]] |
| 32 | # CHECK-NEXT: Value: 0x[[DATA0]] | ||
| 33 | # CHECK-NEXT: Type: Object | ||
| 34 | # CHECK-NEXT: Section: .bss | ||
| 35 | # CHECK-NEXT: Name: data0@ | ||
| 30 | # CHECK-NEXT: } | 36 | # CHECK-NEXT: } |
| 31 | # CHECK-NEXT: ] | ||
| 32 | # CHECK-NEXT: Global entries [ | ||
| 33 | # CHECK-NEXT: Entry { | 37 | # CHECK-NEXT: Entry { |
| 34 | # CHECK-NEXT: Address: | 38 | # CHECK-NEXT: Address: |
| 35 | # CHECK-NEXT: Access: -32740 | 39 | # CHECK-NEXT: Access: -32740 |
deps/lld/test/ELF/mips-got-extsym.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check creation of GOT entries for global symbols in case of executable | 2 | # Check creation of GOT entries for global symbols in case of executable |
| 2 | # file linking. Symbols defined in DSO should get entries in the global part | 3 | # file linking. Symbols defined in DSO should get entries in the global part |
| 3 | # of the GOT. Symbols defined in the executable itself should get local GOT | 4 | # of the GOT. Symbols defined in the executable itself should get local GOT |
| ... | @@ -10,8 +11,6 @@ | ... | @@ -10,8 +11,6 @@ |
| 10 | # RUN: ld.lld %t.o %t.so -o %t.exe | 11 | # RUN: ld.lld %t.o %t.so -o %t.exe |
| 11 | # RUN: llvm-readobj -dt -t -mips-plt-got %t.exe | FileCheck %s | 12 | # RUN: llvm-readobj -dt -t -mips-plt-got %t.exe | FileCheck %s |
| 12 | 13 | ||
| 13 | # REQUIRES: mips | ||
| 14 | |||
| 15 | # CHECK: Symbols [ | 14 | # CHECK: Symbols [ |
| 16 | # CHECK: Symbol { | 15 | # CHECK: Symbol { |
| 17 | # CHECK: Name: _foo | 16 | # CHECK: Name: _foo |
deps/lld/test/ELF/mips-got-hilo.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_GOT_HI16 / R_MIPS_GOT_LO16 relocations calculation. | 2 | # Check R_MIPS_GOT_HI16 / R_MIPS_GOT_LO16 relocations calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| ... | @@ -5,8 +6,6 @@ | ... | @@ -5,8 +6,6 @@ |
| 5 | # RUN: llvm-objdump -d %t.so | FileCheck %s | 6 | # RUN: llvm-objdump -d %t.so | FileCheck %s |
| 6 | # 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 |
| 7 | 8 | ||
| 8 | # REQUIRES: mips | ||
| 9 | |||
| 10 | # CHECK: Disassembly of section .text: | 9 | # CHECK: Disassembly of section .text: |
| 11 | # CHECK-NEXT: foo: | 10 | # CHECK-NEXT: foo: |
| 12 | # CHECK-NEXT: 10000: 3c 02 00 00 lui $2, 0 | 11 | # CHECK-NEXT: 10000: 3c 02 00 00 lui $2, 0 |
deps/lld/test/ELF/mips-got-page-script.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check calculation of MIPS GOT page address entries number | 2 | # Check calculation of MIPS GOT page address entries number |
| 2 | # when a linker script is provided. | 3 | # when a linker script is provided. |
| 3 | 4 | ||
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | # RUN: ld.lld -shared --script %t.script -o %t.so %t.o | 9 | # RUN: ld.lld -shared --script %t.script -o %t.so %t.o |
| 9 | # RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s | 10 | # RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | # CHECK: Name: foo1 | 12 | # CHECK: Name: foo1 |
| 14 | # CHECK-NEXT: Value: 0x10000 | 13 | # CHECK-NEXT: Value: 0x10000 |
| 15 | # CHECK: Name: foo2 | 14 | # CHECK: Name: foo2 |
deps/lld/test/ELF/mips-got-page.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check the case when small section (less that 0x10000 bytes) occupies | 2 | # Check the case when small section (less that 0x10000 bytes) occupies |
| 2 | # two adjacent 0xffff-bytes pages. We need to create two GOT entries | 3 | # two adjacent 0xffff-bytes pages. We need to create two GOT entries |
| 3 | # for R_MIPS_GOT_PAGE relocations. | 4 | # for R_MIPS_GOT_PAGE relocations. |
| ... | @@ -6,8 +7,6 @@ | ... | @@ -6,8 +7,6 @@ |
| 6 | # RUN: ld.lld --section-start .rodata=0x27FFC -shared -o %t.so %t.o | 7 | # RUN: ld.lld --section-start .rodata=0x27FFC -shared -o %t.so %t.o |
| 7 | # RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s | 8 | # RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s |
| 8 | 9 | ||
| 9 | # REQUIRES: mips | ||
| 10 | |||
| 11 | # CHECK: Name: bar | 10 | # CHECK: Name: bar |
| 12 | # CHECK-NEXT: Value: 0x28000 | 11 | # CHECK-NEXT: Value: 0x28000 |
| 13 | # ^ page-address = (0x28000 + 0x8000) & ~0xffff = 0x30000 | 12 | # ^ page-address = (0x28000 + 0x8000) & ~0xffff = 0x30000 |
deps/lld/test/ELF/mips-got-redundant.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check number of redundant entries in the local part of MIPS GOT. | 2 | # Check number of redundant entries in the local part of MIPS GOT. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -shared -o %t.so | 5 | # RUN: ld.lld %t.o -shared -o %t.so |
| 5 | # RUN: llvm-readobj -mips-plt-got %t.so | FileCheck %s | 6 | # RUN: llvm-readobj -mips-plt-got %t.so | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | # CHECK: Local entries [ | 8 | # CHECK: Local entries [ |
| 10 | # CHECK-NEXT: Entry { | 9 | # CHECK-NEXT: Entry { |
| 11 | # CHECK-NEXT: Address: | 10 | # CHECK-NEXT: Address: |
deps/lld/test/ELF/mips-got-relocs.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_GOT16 relocation calculation. | 2 | # Check R_MIPS_GOT16 relocation calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o |
| ... | @@ -30,8 +31,6 @@ | ... | @@ -30,8 +31,6 @@ |
| 30 | # RUN: llvm-readobj -relocations %t-el.so | FileCheck -check-prefix=NORELOC %s | 31 | # RUN: llvm-readobj -relocations %t-el.so | FileCheck -check-prefix=NORELOC %s |
| 31 | # RUN: llvm-readobj -sections %t-el.so | FileCheck -check-prefix=SHFLAGS %s | 32 | # RUN: llvm-readobj -sections %t-el.so | FileCheck -check-prefix=SHFLAGS %s |
| 32 | 33 | ||
| 33 | # REQUIRES: mips | ||
| 34 | |||
| 35 | .text | 34 | .text |
| 36 | .globl __start | 35 | .globl __start |
| 37 | __start: | 36 | __start: |
deps/lld/test/ELF/mips-got-script.s+3-10| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check number of got entries is adjusted for linker script-added space. | 2 | # Check number of got entries is adjusted for linker script-added space. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| ... | @@ -5,10 +6,8 @@ | ... | @@ -5,10 +6,8 @@ |
| 5 | # RUN: ld.lld %t.o -shared -o %t.so -T %t.script | 6 | # RUN: ld.lld %t.o -shared -o %t.so -T %t.script |
| 6 | # 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 |
| 7 | 8 | ||
| 8 | # REQUIRES: mips | 9 | # CHECK: 0x7000000A MIPS_LOCAL_GOTNO 4 |
| 9 | 10 | # ^-- 2 * header + 2 local entries | |
| 10 | # CHECK: 0x7000000A MIPS_LOCAL_GOTNO 5 | ||
| 11 | # ^-- 2 * header + 3 local entries | ||
| 12 | # CHECK: Local entries [ | 11 | # CHECK: Local entries [ |
| 13 | # CHECK-NEXT: Entry { | 12 | # CHECK-NEXT: Entry { |
| 14 | # CHECK-NEXT: Address: | 13 | # CHECK-NEXT: Address: |
| ... | @@ -22,12 +21,6 @@ | ... | @@ -22,12 +21,6 @@ |
| 22 | # CHECK-NEXT: Initial: 0x10000 | 21 | # CHECK-NEXT: Initial: 0x10000 |
| 23 | # ^-- loc2 | 22 | # ^-- loc2 |
| 24 | # CHECK-NEXT: } | 23 | # CHECK-NEXT: } |
| 25 | # CHECK-NEXT: Entry { | ||
| 26 | # CHECK-NEXT: Address: | ||
| 27 | # CHECK-NEXT: Access: -32736 | ||
| 28 | # CHECK-NEXT: Initial: 0x20000 | ||
| 29 | # ^-- redundant | ||
| 30 | # CHECK-NEXT: } | ||
| 31 | # CHECK-NEXT: ] | 24 | # CHECK-NEXT: ] |
| 32 | 25 | ||
| 33 | .text | 26 | .text |
deps/lld/test/ELF/mips-got-string.s+2-3| ... | @@ -1,14 +1,13 @@ | ... | @@ -1,14 +1,13 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_GOT16 relocation against merge section. | 2 | # Check R_MIPS_GOT16 relocation against merge section. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -o %t.o %s | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -o %t.o %s |
| 4 | # RUN: ld.lld -shared -o %t.so %t.o | 5 | # RUN: ld.lld -shared -o %t.so %t.o |
| 5 | # RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s | 6 | # RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | # CHECK: Symbol { | 8 | # CHECK: Symbol { |
| 10 | # CHECK: Name: $.str | 9 | # CHECK: Name: $.str |
| 11 | # CHECK-NEXT: Value: 0xF4 | 10 | # CHECK-NEXT: Value: 0x1B1 |
| 12 | # CHECK: } | 11 | # CHECK: } |
| 13 | 12 | ||
| 14 | # CHECK: Local entries [ | 13 | # CHECK: Local entries [ |
deps/lld/test/ELF/mips-got-weak.s+60-100| ... | @@ -1,17 +1,16 @@ | ... | @@ -1,17 +1,16 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_GOT16 relocation against weak symbols. | 2 | # Check R_MIPS_GOT16 relocation against weak symbols. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -shared -o %t1.so | 5 | # RUN: ld.lld %t.o -shared -o %t1.so |
| 5 | # RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t1.so \ | 6 | # RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t1.so \ |
| 6 | # RUN: | FileCheck -check-prefix=NOSYM %s | 7 | # RUN: | FileCheck -check-prefixes=CHECK,NOSYM %s |
| 7 | # RUN: ld.lld %t.o -shared -Bsymbolic -o %t2.so | 8 | # RUN: ld.lld %t.o -shared -Bsymbolic -o %t2.so |
| 8 | # RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t2.so \ | 9 | # RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t2.so \ |
| 9 | # RUN: | FileCheck -check-prefix=SYM %s | 10 | # RUN: | FileCheck -check-prefixes=CHECK,SYM %s |
| 10 | |||
| 11 | # REQUIRES: mips | ||
| 12 | 11 | ||
| 13 | # NOSYM: Relocations [ | 12 | # CHECK: Relocations [ |
| 14 | # NOSYM-NEXT: ] | 13 | # CHECK-NEXT: ] |
| 15 | 14 | ||
| 16 | # NOSYM: Symbol { | 15 | # NOSYM: Symbol { |
| 17 | # NOSYM: Name: foo | 16 | # NOSYM: Name: foo |
| ... | @@ -22,17 +21,19 @@ | ... | @@ -22,17 +21,19 @@ |
| 22 | # NOSYM-NEXT: Other: 0 | 21 | # NOSYM-NEXT: Other: 0 |
| 23 | # NOSYM-NEXT: Section: .data | 22 | # NOSYM-NEXT: Section: .data |
| 24 | # NOSYM-NEXT: } | 23 | # NOSYM-NEXT: } |
| 25 | # NOSYM-NEXT: Symbol { | 24 | |
| 26 | # NOSYM-NEXT: Name: bar | 25 | # CHECK: Symbol { |
| 27 | # NOSYM-NEXT: Value: 0x0 | 26 | # CHECK: Name: bar |
| 28 | # NOSYM-NEXT: Size: 0 | 27 | # CHECK-NEXT: Value: 0x0 |
| 29 | # NOSYM-NEXT: Binding: Weak | 28 | # CHECK-NEXT: Size: 0 |
| 30 | # NOSYM-NEXT: Type: None | 29 | # CHECK-NEXT: Binding: Weak |
| 31 | # NOSYM-NEXT: Other: 0 | 30 | # CHECK-NEXT: Type: None |
| 32 | # NOSYM-NEXT: Section: Undefined | 31 | # CHECK-NEXT: Other: 0 |
| 33 | # NOSYM-NEXT: } | 32 | # CHECK-NEXT: Section: Undefined |
| 34 | # NOSYM-NEXT: Symbol { | 33 | # CHECK-NEXT: } |
| 35 | # NOSYM-NEXT: Name: sym | 34 | |
| 35 | # NOSYM: Symbol { | ||
| 36 | # NOSYM: Name: sym | ||
| 36 | # NOSYM-NEXT: Value: 0x20004 | 37 | # NOSYM-NEXT: Value: 0x20004 |
| 37 | # NOSYM-NEXT: Size: 0 | 38 | # NOSYM-NEXT: Size: 0 |
| 38 | # NOSYM-NEXT: Binding: Global | 39 | # NOSYM-NEXT: Binding: Global |
| ... | @@ -40,30 +41,48 @@ | ... | @@ -40,30 +41,48 @@ |
| 40 | # NOSYM-NEXT: Other: 0 | 41 | # NOSYM-NEXT: Other: 0 |
| 41 | # NOSYM-NEXT: Section: .data | 42 | # NOSYM-NEXT: Section: .data |
| 42 | # NOSYM-NEXT: } | 43 | # NOSYM-NEXT: } |
| 43 | # NOSYM-NEXT: ] | ||
| 44 | 44 | ||
| 45 | # NOSYM: 0x70000011 MIPS_SYMTABNO 4 | 45 | # CHECK: 0x70000011 MIPS_SYMTABNO 4 |
| 46 | # NOSYM-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 2 | ||
| 47 | # NOSYM-NEXT: 0x70000013 MIPS_GOTSYM 0x1 | ||
| 48 | 46 | ||
| 49 | # NOSYM: Primary GOT { | 47 | # SYM: 0x7000000A MIPS_LOCAL_GOTNO 4 |
| 50 | # NOSYM-NEXT: Canonical gp value: | 48 | # SYM: 0x70000013 MIPS_GOTSYM 0x3 |
| 51 | # NOSYM-NEXT: Reserved entries [ | 49 | |
| 52 | # NOSYM-NEXT: Entry { | 50 | # NOSYM: 0x7000000A MIPS_LOCAL_GOTNO 2 |
| 53 | # NOSYM-NEXT: Address: | 51 | # NOSYM: 0x70000013 MIPS_GOTSYM 0x1 |
| 54 | # NOSYM-NEXT: Access: -32752 | 52 | |
| 55 | # NOSYM-NEXT: Initial: 0x0 | 53 | # CHECK: Primary GOT { |
| 56 | # NOSYM-NEXT: Purpose: Lazy resolver | 54 | # CHECK-NEXT: Canonical gp value: |
| 57 | # NOSYM-NEXT: } | 55 | # CHECK-NEXT: Reserved entries [ |
| 58 | # NOSYM-NEXT: Entry { | 56 | # CHECK: ] |
| 59 | # NOSYM-NEXT: Address: | 57 | |
| 60 | # NOSYM-NEXT: Access: -32748 | 58 | # SYM: Local entries [ |
| 61 | # NOSYM-NEXT: Initial: 0x80000000 | 59 | # SYM-NEXT: Entry { |
| 62 | # NOSYM-NEXT: Purpose: Module pointer (GNU extension) | 60 | # SYM-NEXT: Address: |
| 63 | # NOSYM-NEXT: } | 61 | # SYM-NEXT: Access: -32744 |
| 64 | # NOSYM-NEXT: ] | 62 | # SYM-NEXT: Initial: 0x20000 |
| 65 | # NOSYM-NEXT: Local entries [ | 63 | # SYM-NEXT: } |
| 64 | # SYM-NEXT: Entry { | ||
| 65 | # SYM-NEXT: Address: | ||
| 66 | # SYM-NEXT: Access: -32740 | ||
| 67 | # SYM-NEXT: Initial: 0x20004 | ||
| 68 | # SYM-NEXT: } | ||
| 69 | # SYM-NEXT: ] | ||
| 70 | |||
| 71 | # NOSYM: Local entries [ | ||
| 66 | # NOSYM-NEXT: ] | 72 | # NOSYM-NEXT: ] |
| 73 | |||
| 74 | # SYM-NEXT: Global entries [ | ||
| 75 | # SYM-NEXT: Entry { | ||
| 76 | # SYM-NEXT: Address: | ||
| 77 | # SYM-NEXT: Access: -32736 | ||
| 78 | # SYM-NEXT: Initial: 0x0 | ||
| 79 | # SYM-NEXT: Value: 0x0 | ||
| 80 | # SYM-NEXT: Type: None | ||
| 81 | # SYM-NEXT: Section: Undefined | ||
| 82 | # SYM-NEXT: Name: bar | ||
| 83 | # SYM-NEXT: } | ||
| 84 | # SYM-NEXT: ] | ||
| 85 | |||
| 67 | # NOSYM-NEXT: Global entries [ | 86 | # NOSYM-NEXT: Global entries [ |
| 68 | # NOSYM-NEXT: Entry { | 87 | # NOSYM-NEXT: Entry { |
| 69 | # NOSYM-NEXT: Address: | 88 | # NOSYM-NEXT: Address: |
| ... | @@ -93,68 +112,9 @@ | ... | @@ -93,68 +112,9 @@ |
| 93 | # NOSYM-NEXT: Name: sym | 112 | # NOSYM-NEXT: Name: sym |
| 94 | # NOSYM-NEXT: } | 113 | # NOSYM-NEXT: } |
| 95 | # NOSYM-NEXT: ] | 114 | # NOSYM-NEXT: ] |
| 96 | # NOSYM-NEXT: Number of TLS and multi-GOT entries: 0 | 115 | |
| 97 | # NOSYM-NEXT: } | 116 | # CHECK: Number of TLS and multi-GOT entries: 0 |
| 98 | 117 | # CHECK-NEXT: } | |
| 99 | # SYM: Relocations [ | ||
| 100 | # SYM-NEXT: ] | ||
| 101 | |||
| 102 | # SYM: Symbol { | ||
| 103 | # SYM: Name: bar | ||
| 104 | # SYM-NEXT: Value: 0x0 | ||
| 105 | # SYM-NEXT: Size: 0 | ||
| 106 | # SYM-NEXT: Binding: Weak | ||
| 107 | # SYM-NEXT: Type: None | ||
| 108 | # SYM-NEXT: Other: 0 | ||
| 109 | # SYM-NEXT: Section: Undefined | ||
| 110 | # SYM-NEXT: } | ||
| 111 | # SYM-NEXT: ] | ||
| 112 | |||
| 113 | # SYM: 0x70000011 MIPS_SYMTABNO 4 | ||
| 114 | # SYM-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 4 | ||
| 115 | # SYM-NEXT: 0x70000013 MIPS_GOTSYM 0x3 | ||
| 116 | |||
| 117 | # SYM: Primary GOT { | ||
| 118 | # SYM-NEXT: Canonical gp value: | ||
| 119 | # SYM-NEXT: Reserved entries [ | ||
| 120 | # SYM-NEXT: Entry { | ||
| 121 | # SYM-NEXT: Address: | ||
| 122 | # SYM-NEXT: Access: -32752 | ||
| 123 | # SYM-NEXT: Initial: 0x0 | ||
| 124 | # SYM-NEXT: Purpose: Lazy resolver | ||
| 125 | # SYM-NEXT: } | ||
| 126 | # SYM-NEXT: Entry { | ||
| 127 | # SYM-NEXT: Address: | ||
| 128 | # SYM-NEXT: Access: -32748 | ||
| 129 | # SYM-NEXT: Initial: 0x80000000 | ||
| 130 | # SYM-NEXT: Purpose: Module pointer (GNU extension) | ||
| 131 | # SYM-NEXT: } | ||
| 132 | # SYM-NEXT: ] | ||
| 133 | # SYM-NEXT: Local entries [ | ||
| 134 | # SYM-NEXT: Entry { | ||
| 135 | # SYM-NEXT: Address: | ||
| 136 | # SYM-NEXT: Access: -32744 | ||
| 137 | # SYM-NEXT: Initial: 0x20000 | ||
| 138 | # SYM-NEXT: } | ||
| 139 | # SYM-NEXT: Entry { | ||
| 140 | # SYM-NEXT: Address: | ||
| 141 | # SYM-NEXT: Access: -32740 | ||
| 142 | # SYM-NEXT: Initial: 0x20004 | ||
| 143 | # SYM-NEXT: } | ||
| 144 | # SYM-NEXT: ] | ||
| 145 | # SYM-NEXT: Global entries [ | ||
| 146 | # SYM-NEXT: Entry { | ||
| 147 | # SYM-NEXT: Address: | ||
| 148 | # SYM-NEXT: Access: -32736 | ||
| 149 | # SYM-NEXT: Initial: 0x0 | ||
| 150 | # SYM-NEXT: Value: 0x0 | ||
| 151 | # SYM-NEXT: Type: None | ||
| 152 | # SYM-NEXT: Section: Undefined | ||
| 153 | # SYM-NEXT: Name: bar | ||
| 154 | # SYM-NEXT: } | ||
| 155 | # SYM-NEXT: ] | ||
| 156 | # SYM-NEXT: Number of TLS and multi-GOT entries: 0 | ||
| 157 | # SYM-NEXT: } | ||
| 158 | 118 | ||
| 159 | .text | 119 | .text |
| 160 | .global sym | 120 | .global sym |
deps/lld/test/ELF/mips-got16-relocatable.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check writing updated addend for R_MIPS_GOT16 relocation, | 2 | # Check writing updated addend for R_MIPS_GOT16 relocation, |
| 2 | # when produce a relocatable output. | 3 | # when produce a relocatable output. |
| 3 | 4 | ||
| ... | @@ -7,8 +8,6 @@ | ... | @@ -7,8 +8,6 @@ |
| 7 | # RUN: ld.lld -shared -o %t.so %t | 8 | # RUN: ld.lld -shared -o %t.so %t |
| 8 | # RUN: llvm-objdump -d %t.so | FileCheck -check-prefix=SO %s | 9 | # RUN: llvm-objdump -d %t.so | FileCheck -check-prefix=SO %s |
| 9 | 10 | ||
| 10 | # REQUIRES: mips | ||
| 11 | |||
| 12 | # OBJ: Disassembly of section .text: | 11 | # OBJ: Disassembly of section .text: |
| 13 | # OBJ-NEXT: .text: | 12 | # OBJ-NEXT: .text: |
| 14 | # OBJ-NEXT: 0: 8f 99 00 00 lw $25, 0($gp) | 13 | # OBJ-NEXT: 0: 8f 99 00 00 lw $25, 0($gp) |
deps/lld/test/ELF/mips-got16.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_GOT16 relocation calculation. | 2 | # Check R_MIPS_GOT16 relocation calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| ... | @@ -5,8 +6,6 @@ | ... | @@ -5,8 +6,6 @@ |
| 5 | # RUN: llvm-objdump -d -t %t.so | FileCheck %s | 6 | # RUN: llvm-objdump -d -t %t.so | FileCheck %s |
| 6 | # 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 |
| 7 | 8 | ||
| 8 | # REQUIRES: mips | ||
| 9 | |||
| 10 | # CHECK: Disassembly of section .text: | 9 | # CHECK: Disassembly of section .text: |
| 11 | # CHECK-NEXT: __start: | 10 | # CHECK-NEXT: __start: |
| 12 | # CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744($gp) | 11 | # CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744($gp) |
deps/lld/test/ELF/mips-gp-disp-ver.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # MIPS BFD linker puts _gp_disp symbol into DSO files and assigns zero | 2 | # MIPS BFD linker puts _gp_disp symbol into DSO files and assigns zero |
| 2 | # version definition index to it. This value means 'unversioned local symbol' | 3 | # version definition index to it. This value means 'unversioned local symbol' |
| 3 | # while _gp_disp is a section global symbol. We have to handle this bug | 4 | # while _gp_disp is a section global symbol. We have to handle this bug |
| ... | @@ -7,8 +8,6 @@ | ... | @@ -7,8 +8,6 @@ |
| 7 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 8 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 8 | # RUN: ld.lld %t.o %S/Inputs/mips-gp-dips-corrupt-ver.so | 9 | # RUN: ld.lld %t.o %S/Inputs/mips-gp-dips-corrupt-ver.so |
| 9 | 10 | ||
| 10 | # REQUIRES: mips | ||
| 11 | |||
| 12 | .global __start | 11 | .global __start |
| 13 | .text | 12 | .text |
| 14 | __start: | 13 | __start: |
deps/lld/test/ELF/mips-gp-disp.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check that even if _gp_disp symbol is defined in the shared library | 2 | # Check that even if _gp_disp symbol is defined in the shared library |
| 2 | # we use our own value. | 3 | # we use our own value. |
| 3 | 4 | ||
| ... | @@ -9,8 +10,6 @@ | ... | @@ -9,8 +10,6 @@ |
| 9 | # RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=DIS %s | 10 | # RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=DIS %s |
| 10 | # RUN: llvm-readobj -relocations %t.so | FileCheck -check-prefix=REL %s | 11 | # RUN: llvm-readobj -relocations %t.so | FileCheck -check-prefix=REL %s |
| 11 | 12 | ||
| 12 | # REQUIRES: mips | ||
| 13 | |||
| 14 | # INT-SO: Name: _gp_disp | 13 | # INT-SO: Name: _gp_disp |
| 15 | # INT-SO-NEXT: Value: | 14 | # INT-SO-NEXT: Value: |
| 16 | # INT-SO-NEXT: Size: | 15 | # INT-SO-NEXT: Size: |
deps/lld/test/ELF/mips-gp-ext.s+21-20| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check that the linker use a value of _gp symbol defined | 2 | # Check that the linker use a value of _gp symbol defined |
| 2 | # in a linker script to calculate GOT relocations. | 3 | # in a linker script to calculate GOT relocations. |
| 3 | 4 | ||
| ... | @@ -24,45 +25,45 @@ | ... | @@ -24,45 +25,45 @@ |
| 24 | # RUN: ld.lld -shared -o %t.abs.so --script %t.abs.script %t.o | 25 | # RUN: ld.lld -shared -o %t.abs.so --script %t.abs.script %t.o |
| 25 | # RUN: llvm-objdump -s -t %t.abs.so | FileCheck --check-prefix=ABS %s | 26 | # RUN: llvm-objdump -s -t %t.abs.so | FileCheck --check-prefix=ABS %s |
| 26 | 27 | ||
| 27 | # REQUIRES: mips | 28 | # REL: Contents of section .reginfo: |
| 29 | # REL-NEXT: 0018 10000104 00000000 00000000 00000000 | ||
| 30 | # REL-NEXT: 0028 00000000 000001ec | ||
| 31 | # ^-- _gp | ||
| 28 | 32 | ||
| 29 | # REL: Contents of section .text: | 33 | # REL: Contents of section .text: |
| 30 | # REL-NEXT: 0000 3c080000 2108010c 8f82fffc | 34 | # REL-NEXT: 00e0 3c080000 2108010c 8f82ff1c |
| 31 | # ^-- %hi(_gp_disp) | 35 | # ^-- %hi(_gp_disp) |
| 32 | # ^-- %lo(_gp_disp) | 36 | # ^-- %lo(_gp_disp) |
| 33 | # ^-- 8 - (0x10c - 0x100) | 37 | # ^-- 8 - (0x1ec - 0x100) |
| 34 | # G - (GP - .got) | 38 | # G - (GP - .got) |
| 35 | 39 | ||
| 36 | # REL: Contents of section .reginfo: | ||
| 37 | # REL-NEXT: 0028 10000104 00000000 00000000 00000000 | ||
| 38 | # REL-NEXT: 0038 00000000 0000010c | ||
| 39 | # ^-- _gp | ||
| 40 | |||
| 41 | # REL: Contents of section .data: | 40 | # REL: Contents of section .data: |
| 42 | # REL-NEXT: 00f0 fffffef4 | 41 | # REL-NEXT: 00f0 fffffef4 |
| 43 | # ^-- 0-0x10c | 42 | # ^-- 0x30-0x1ec |
| 43 | # foo - GP | ||
| 44 | 44 | ||
| 45 | # REL: 00000000 .text 00000000 foo | 45 | # REL: 000000e0 .text 00000000 foo |
| 46 | # REL: 00000000 *ABS* 00000000 .hidden _gp_disp | 46 | # REL: 00000000 *ABS* 00000000 .hidden _gp_disp |
| 47 | # REL: 0000010c *ABS* 00000000 .hidden _gp | 47 | # REL: 000001ec *ABS* 00000000 .hidden _gp |
| 48 | |||
| 49 | # ABS: Contents of section .reginfo: | ||
| 50 | # ABS-NEXT: 0018 10000104 00000000 00000000 00000000 | ||
| 51 | # ABS-NEXT: 0028 00000000 00000200 | ||
| 52 | # ^-- _gp | ||
| 48 | 53 | ||
| 49 | # ABS: Contents of section .text: | 54 | # ABS: Contents of section .text: |
| 50 | # ABS-NEXT: 0000 3c080000 21080200 8f82ff08 | 55 | # ABS-NEXT: 00e0 3c080000 21080120 8f82ff08 |
| 51 | # ^-- %hi(_gp_disp) | 56 | # ^-- %hi(_gp_disp) |
| 52 | # ^-- %lo(_gp_disp) | 57 | # ^-- %lo(_gp_disp) |
| 53 | # ^-- 8 - (0x200 - 0x100) | 58 | # ^-- 8 - (0x200 - 0x100) |
| 54 | # G - (GP - .got) | 59 | # G - (GP - .got) |
| 55 | 60 | ||
| 56 | # ABS: Contents of section .reginfo: | ||
| 57 | # ABS-NEXT: 0028 10000104 00000000 00000000 00000000 | ||
| 58 | # ABS-NEXT: 0038 00000000 00000200 | ||
| 59 | # ^-- _gp | ||
| 60 | |||
| 61 | # ABS: Contents of section .data: | 61 | # ABS: Contents of section .data: |
| 62 | # ABS-NEXT: 00f0 fffffe00 | 62 | # ABS-NEXT: 00f0 fffffee0 |
| 63 | # ^-- 0-0x200 | 63 | # ^-- 0xe0-0x200 |
| 64 | # foo - GP | ||
| 64 | 65 | ||
| 65 | # ABS: 00000000 .text 00000000 foo | 66 | # ABS: 000000e0 .text 00000000 foo |
| 66 | # ABS: 00000000 *ABS* 00000000 .hidden _gp_disp | 67 | # ABS: 00000000 *ABS* 00000000 .hidden _gp_disp |
| 67 | # ABS: 00000200 *ABS* 00000000 .hidden _gp | 68 | # ABS: 00000200 *ABS* 00000000 .hidden _gp |
| 68 | 69 |
deps/lld/test/ELF/mips-gp-local.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check handling of relocations against __gnu_local_gp symbol. | 2 | # Check handling of relocations against __gnu_local_gp symbol. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld -o %t.exe %t.o | 5 | # RUN: ld.lld -o %t.exe %t.o |
| 5 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s | 6 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | # CHECK: Disassembly of section .text: | 8 | # CHECK: Disassembly of section .text: |
| 10 | # CHECK-NEXT: __start: | 9 | # CHECK-NEXT: __start: |
| 11 | # CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 | 10 | # CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 |
deps/lld/test/ELF/mips-gp-lowest.s+5-6| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check that default _gp value is calculated relative | 2 | # Check that default _gp value is calculated relative |
| 2 | # to the GP-relative section with the lowest address. | 3 | # to the GP-relative section with the lowest address. |
| 3 | 4 | ||
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | # RUN: ld.lld %t.o --script %t.rel.script -shared -o %t.so | 9 | # RUN: ld.lld %t.o --script %t.rel.script -shared -o %t.so |
| 9 | # RUN: llvm-readobj -s -t %t.so | FileCheck %s | 10 | # RUN: llvm-readobj -s -t %t.so | FileCheck %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | .text | 12 | .text |
| 14 | .global foo | 13 | .global foo |
| 15 | foo: | 14 | foo: |
| ... | @@ -26,7 +25,7 @@ foo: | ... | @@ -26,7 +25,7 @@ foo: |
| 26 | # CHECK-NEXT: SHF_MIPS_GPREL | 25 | # CHECK-NEXT: SHF_MIPS_GPREL |
| 27 | # CHECK-NEXT: SHF_WRITE | 26 | # CHECK-NEXT: SHF_WRITE |
| 28 | # CHECK-NEXT: ] | 27 | # CHECK-NEXT: ] |
| 29 | # CHECK-NEXT: Address: 0xE0 | 28 | # CHECK-NEXT: Address: 0xF0 |
| 30 | # CHECK: } | 29 | # CHECK: } |
| 31 | # CHECK: Section { | 30 | # CHECK: Section { |
| 32 | # CHECK: Name: .got | 31 | # CHECK: Name: .got |
| ... | @@ -36,9 +35,9 @@ foo: | ... | @@ -36,9 +35,9 @@ foo: |
| 36 | # CHECK-NEXT: SHF_MIPS_GPREL | 35 | # CHECK-NEXT: SHF_MIPS_GPREL |
| 37 | # CHECK-NEXT: SHF_WRITE | 36 | # CHECK-NEXT: SHF_WRITE |
| 38 | # CHECK-NEXT: ] | 37 | # CHECK-NEXT: ] |
| 39 | # CHECK-NEXT: Address: 0xF0 | 38 | # CHECK-NEXT: Address: 0x100 |
| 40 | # CHECK: } | 39 | # CHECK: } |
| 41 | 40 | ||
| 42 | # CHECK: Name: _gp (5) | 41 | # CHECK: Name: _gp (5) |
| 43 | # CHECK-NEXT: Value: 0x80D0 | 42 | # CHECK-NEXT: Value: 0x80E0 |
| 44 | # ^-- 0xE0 + 0x7ff0 | 43 | # ^-- 0xF0 + 0x7ff0 |
deps/lld/test/ELF/mips-gprel-sec.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check order of gp-relative sections, i.e. sections with SHF_MIPS_GPREL flag. | 2 | # Check order of gp-relative sections, i.e. sections with SHF_MIPS_GPREL flag. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -shared -o %t.so | 5 | # RUN: ld.lld %t.o -shared -o %t.so |
| 5 | # RUN: llvm-readobj -s %t.so | FileCheck %s | 6 | # RUN: llvm-readobj -s %t.so | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | .text | 8 | .text |
| 10 | nop | 9 | nop |
| 11 | 10 |
deps/lld/test/ELF/mips-gprel32-relocs-gp0.s+1-11| ... | @@ -1,8 +1,5 @@ | ... | @@ -1,8 +1,5 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check that relocatable object produced by LLD has zero gp0 value. | 2 | # Check that relocatable object produced by LLD has zero gp0 value. |
| 2 | # Also check an error message if input object file has non-zero gp0 value | ||
| 3 | # and the linker generates a relocatable object. | ||
| 4 | # mips-gp0-non-zero.o is a relocatable object produced from the asm code | ||
| 5 | # below and linked by GNU bfd linker. | ||
| 6 | 3 | ||
| 7 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 8 | # RUN: ld.lld -r -o %t-rel.o %t.o | 5 | # RUN: ld.lld -r -o %t-rel.o %t.o |
| ... | @@ -12,11 +9,6 @@ | ... | @@ -12,11 +9,6 @@ |
| 12 | # 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 |
| 13 | # RUN: llvm-objdump -s -t %t.so | FileCheck --check-prefix=DUMP %s | 10 | # RUN: llvm-objdump -s -t %t.so | FileCheck --check-prefix=DUMP %s |
| 14 | 11 | ||
| 15 | # RUN: not ld.lld -r -o %t-rel.o %S/Inputs/mips-gp0-non-zero.o 2>&1 \ | ||
| 16 | # RUN: | FileCheck --check-prefix=ERR %s | ||
| 17 | |||
| 18 | # REQUIRES: mips | ||
| 19 | |||
| 20 | # REL: GP: 0x0 | 12 | # REL: GP: 0x0 |
| 21 | 13 | ||
| 22 | # DSO: GP: 0x27FF0 | 14 | # DSO: GP: 0x27FF0 |
| ... | @@ -31,8 +23,6 @@ | ... | @@ -31,8 +23,6 @@ |
| 31 | # DUMP: 00010004 .text 00000000 foo | 23 | # DUMP: 00010004 .text 00000000 foo |
| 32 | # DUMP: 00027ff0 .got 00000000 .hidden _gp | 24 | # DUMP: 00027ff0 .got 00000000 .hidden _gp |
| 33 | 25 | ||
| 34 | # ERR: error: {{.*}}mips-gp0-non-zero.o: unsupported non-zero ri_gp_value | ||
| 35 | |||
| 36 | .text | 26 | .text |
| 37 | .global __start | 27 | .global __start |
| 38 | __start: | 28 | __start: |
deps/lld/test/ELF/mips-gprel32-relocs.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_GPREL32 relocation calculation. | 2 | # Check R_MIPS_GPREL32 relocation calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld -shared -o %t.so %t.o | 5 | # RUN: ld.lld -shared -o %t.so %t.o |
| 5 | # RUN: llvm-objdump -s -section=.rodata -t %t.so | FileCheck %s | 6 | # RUN: llvm-objdump -s -section=.rodata -t %t.so | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | .text | 8 | .text |
| 10 | .globl __start | 9 | .globl __start |
| 11 | __start: | 10 | __start: |
deps/lld/test/ELF/mips-higher-highest.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_HIGHER / R_MIPS_HIGHEST relocations calculation. | 2 | # Check R_MIPS_HIGHER / R_MIPS_HIGHEST relocations calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o |
| ... | @@ -6,8 +7,6 @@ | ... | @@ -6,8 +7,6 @@ |
| 6 | # RUN: ld.lld %t1.o %t2.o -o %t.exe | 7 | # RUN: ld.lld %t1.o %t2.o -o %t.exe |
| 7 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | 8 | # RUN: llvm-objdump -d %t.exe | FileCheck %s |
| 8 | 9 | ||
| 9 | # REQUIRES: mips | ||
| 10 | |||
| 11 | .global __start | 10 | .global __start |
| 12 | __start: | 11 | __start: |
| 13 | lui $6, %highest(_foo+0x300047FFF7FF7) | 12 | lui $6, %highest(_foo+0x300047FFF7FF7) |
deps/lld/test/ELF/mips-hilo-gp-disp.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_HI16 / LO16 relocations calculation against _gp_disp. | 2 | # Check R_MIPS_HI16 / LO16 relocations calculation against _gp_disp. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o |
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | # RUN: ld.lld %t1.o %t2.o -shared -o %t.so | 9 | # RUN: ld.lld %t1.o %t2.o -shared -o %t.so |
| 9 | # RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=SO %s | 10 | # RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=SO %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | .text | 12 | .text |
| 14 | .globl __start | 13 | .globl __start |
| 15 | __start: | 14 | __start: |
deps/lld/test/ELF/mips-hilo-hi-only.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check warning on orphaned R_MIPS_HI16 relocations. | 2 | # Check warning on orphaned R_MIPS_HI16 relocations. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -o %t.exe 2>&1 | FileCheck -check-prefix=WARN %s | 5 | # RUN: ld.lld %t.o -o %t.exe 2>&1 | FileCheck -check-prefix=WARN %s |
| 5 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s | 6 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | .text | 8 | .text |
| 10 | .globl __start | 9 | .globl __start |
| 11 | __start: | 10 | __start: |
deps/lld/test/ELF/mips-hilo.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_HI16 / LO16 relocations calculation. | 2 | # Check R_MIPS_HI16 / LO16 relocations calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -o %t.exe | 5 | # RUN: ld.lld %t.o -o %t.exe |
| 5 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s | 6 | # RUN: llvm-objdump -d -t %t.exe | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | .text | 8 | .text |
| 10 | .globl __start | 9 | .globl __start |
| 11 | __start: | 10 | __start: |
deps/lld/test/ELF/mips-lo16-not-relative.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check that R_MIPS_LO16 relocation is handled as non-relative, | 2 | # Check that R_MIPS_LO16 relocation is handled as non-relative, |
| 2 | # and if a target symbol is a DSO data symbol, LLD create a copy | 3 | # and if a target symbol is a DSO data symbol, LLD create a copy |
| 3 | # relocation. | 4 | # relocation. |
| ... | @@ -9,8 +10,6 @@ | ... | @@ -9,8 +10,6 @@ |
| 9 | # RUN: ld.lld %t.o %t.so -o %t.exe | 10 | # RUN: ld.lld %t.o %t.so -o %t.exe |
| 10 | # RUN: llvm-readobj -r %t.exe | FileCheck %s | 11 | # RUN: llvm-readobj -r %t.exe | FileCheck %s |
| 11 | 12 | ||
| 12 | # REQUIRES: mips | ||
| 13 | |||
| 14 | # CHECK: Relocations [ | 13 | # CHECK: Relocations [ |
| 15 | # CHECK-NEXT: Section (7) .rel.dyn { | 14 | # CHECK-NEXT: Section (7) .rel.dyn { |
| 16 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0 | 15 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0 |
deps/lld/test/ELF/mips-merge-abiflags.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Test that lld handles input files with concatenated .MIPS.abiflags sections | 2 | # Test that lld handles input files with concatenated .MIPS.abiflags sections |
| 2 | # This happens e.g. with the FreeBSD BFD (BFD 2.17.50 [FreeBSD] 2007-07-03) | 3 | # This happens e.g. with the FreeBSD BFD (BFD 2.17.50 [FreeBSD] 2007-07-03) |
| 3 | 4 | ||
| ... | @@ -8,7 +9,6 @@ | ... | @@ -8,7 +9,6 @@ |
| 8 | # RUN: %p/Inputs/mips-concatenated-abiflags.o | \ | 9 | # RUN: %p/Inputs/mips-concatenated-abiflags.o | \ |
| 9 | # RUN: FileCheck --check-prefix=INPUT-OBJECT %s | 10 | # RUN: FileCheck --check-prefix=INPUT-OBJECT %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | .globl __start | 12 | .globl __start |
| 13 | __start: | 13 | __start: |
| 14 | nop | 14 | nop |
deps/lld/test/ELF/mips-mgot.s created+117| ... | @@ -0,0 +1,117 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | # Check MIPS multi-GOT layout. | ||
| 3 | |||
| 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t0.o | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 6 | # RUN: %p/Inputs/mips-mgot-1.s -o %t1.o | ||
| 7 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 8 | # RUN: %p/Inputs/mips-mgot-2.s -o %t2.o | ||
| 9 | # RUN: ld.lld -shared -mips-got-size 52 %t0.o %t1.o %t2.o -o %t.so | ||
| 10 | # 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 | ||
| 12 | |||
| 13 | # 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 | ||
| 19 | |||
| 20 | # CHECK: SYMBOL TABLE: | ||
| 21 | # CHECK: 00000000 l .tdata 00000000 loc0 | ||
| 22 | # CHECK: 00010000 .text 00000000 foo0 | ||
| 23 | # CHECK: 00000000 g .tdata 00000000 tls0 | ||
| 24 | # CHECK: 00010020 .text 00000000 foo1 | ||
| 25 | # CHECK: 00000004 g .tdata 00000000 tls1 | ||
| 26 | # CHECK: 00010030 .text 00000000 foo2 | ||
| 27 | # CHECK: 00000008 g .tdata 00000000 tls2 | ||
| 28 | |||
| 29 | # GOT: Relocations [ | ||
| 30 | # 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 | ||
| 45 | # GOT-NEXT: } | ||
| 46 | # GOT-NEXT: ] | ||
| 47 | |||
| 48 | # GOT: DynamicSymbols [ | ||
| 49 | # GOT: Symbol { | ||
| 50 | # GOT: Name: foo0 | ||
| 51 | # GOT-NEXT: Value: 0x10000 | ||
| 52 | # GOT: } | ||
| 53 | # GOT-NEXT: Symbol { | ||
| 54 | # GOT-NEXT: Name: foo2 | ||
| 55 | # GOT-NEXT: Value: 0x10030 | ||
| 56 | # GOT: } | ||
| 57 | # GOT-NEXT: ] | ||
| 58 | |||
| 59 | # GOT: Primary GOT { | ||
| 60 | # GOT-NEXT: Canonical gp value: 0x67FF0 | ||
| 61 | # GOT-NEXT: Reserved entries [ | ||
| 62 | # GOT-NEXT: Entry { | ||
| 63 | # GOT-NEXT: Address: | ||
| 64 | # GOT-NEXT: Access: -32752 | ||
| 65 | # GOT-NEXT: Initial: 0x0 | ||
| 66 | # GOT-NEXT: Purpose: Lazy resolver | ||
| 67 | # GOT-NEXT: } | ||
| 68 | # GOT-NEXT: Entry { | ||
| 69 | # GOT-NEXT: Address: | ||
| 70 | # GOT-NEXT: Access: -32748 | ||
| 71 | # GOT-NEXT: Initial: 0x80000000 | ||
| 72 | # GOT-NEXT: Purpose: Module pointer (GNU extension) | ||
| 73 | # GOT-NEXT: } | ||
| 74 | # GOT-NEXT: ] | ||
| 75 | # GOT-NEXT: Local entries [ | ||
| 76 | # GOT-NEXT: ] | ||
| 77 | # GOT-NEXT: Global entries [ | ||
| 78 | # GOT-NEXT: Entry { | ||
| 79 | # GOT-NEXT: Address: | ||
| 80 | # GOT-NEXT: Access: -32744 | ||
| 81 | # GOT-NEXT: Initial: 0x10000 | ||
| 82 | # GOT-NEXT: Value: 0x10000 | ||
| 83 | # GOT-NEXT: Type: None | ||
| 84 | # GOT-NEXT: Section: .text | ||
| 85 | # GOT-NEXT: Name: foo0 | ||
| 86 | # GOT-NEXT: } | ||
| 87 | # GOT-NEXT: Entry { | ||
| 88 | # GOT-NEXT: Address: | ||
| 89 | # GOT-NEXT: Access: -32740 | ||
| 90 | # GOT-NEXT: Initial: 0x10030 | ||
| 91 | # GOT-NEXT: Value: 0x10030 | ||
| 92 | # GOT-NEXT: Type: None | ||
| 93 | # GOT-NEXT: Section: .text | ||
| 94 | # GOT-NEXT: Name: foo2 | ||
| 95 | # GOT-NEXT: } | ||
| 96 | # GOT-NEXT: ] | ||
| 97 | # GOT-NEXT: Number of TLS and multi-GOT entries: 15 | ||
| 98 | # GOT-NEXT: } | ||
| 99 | |||
| 100 | .text | ||
| 101 | .global foo0 | ||
| 102 | foo0: | ||
| 103 | lw $2, %got(.data)($gp) # page entry | ||
| 104 | addi $2, $2, %lo(.data) | ||
| 105 | lw $2, %call16(foo0)($gp) # global entry | ||
| 106 | addiu $2, $2, %tlsgd(tls0) # tls gd entry | ||
| 107 | addiu $2, $2, %gottprel(tls0) # tls got entry | ||
| 108 | addiu $2, $2, %tlsldm(loc0) # tls ld entry | ||
| 109 | |||
| 110 | .data | ||
| 111 | .space 0x20000 | ||
| 112 | |||
| 113 | .section .tdata,"awT",%progbits | ||
| 114 | .global tls0 | ||
| 115 | tls0: | ||
| 116 | loc0: | ||
| 117 | .word 0 | ||
deps/lld/test/ELF/mips-micro-got.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check microMIPS GOT relocations for O32 ABI. | 2 | # Check microMIPS GOT relocations for O32 ABI. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mattr=micromips \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mattr=micromips \ |
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | # RUN: ld.lld %t1.o %t.so -o %t.exe | 9 | # RUN: ld.lld %t1.o %t.so -o %t.exe |
| 9 | # RUN: llvm-readobj -mips-plt-got %t.exe | FileCheck %s | 10 | # RUN: llvm-readobj -mips-plt-got %t.exe | FileCheck %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | # CHECK: Local entries [ | 12 | # CHECK: Local entries [ |
| 14 | # CHECK-NEXT: Entry { | 13 | # CHECK-NEXT: Entry { |
| 15 | # CHECK-NEXT: Address: | 14 | # CHECK-NEXT: Address: |
deps/lld/test/ELF/mips-micro-got64.s deleted-48| ... | @@ -1,48 +0,0 @@ | ||
| 1 | # Check microMIPS GOT relocations for N64 ABI. | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -mattr=micromips \ | ||
| 4 | # RUN: %s -o %t1.o | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -mattr=micromips \ | ||
| 6 | # RUN: %S/Inputs/mips-dynamic.s -o %t2.o | ||
| 7 | # RUN: ld.lld %t2.o -shared -o %t.so | ||
| 8 | # RUN: ld.lld %t1.o %t.so -o %t.exe | ||
| 9 | # RUN: llvm-readobj -mips-plt-got %t.exe | FileCheck %s | ||
| 10 | |||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | # CHECK: Local entries [ | ||
| 14 | # CHECK-NEXT: Entry { | ||
| 15 | # CHECK-NEXT: Address: | ||
| 16 | # CHECK-NEXT: Access: -32736 | ||
| 17 | # CHECK-NEXT: Initial: 0x30000 | ||
| 18 | # CHECK-NEXT: } | ||
| 19 | # CHECK-NEXT: Entry { | ||
| 20 | # CHECK-NEXT: Address: | ||
| 21 | # CHECK-NEXT: Access: -32728 | ||
| 22 | # CHECK-NEXT: Initial: 0x40000 | ||
| 23 | # CHECK-NEXT: } | ||
| 24 | # CHECK-NEXT: ] | ||
| 25 | # CHECK-NEXT: Global entries [ | ||
| 26 | # CHECK-NEXT: Entry { | ||
| 27 | # CHECK-NEXT: Address: | ||
| 28 | # CHECK-NEXT: Access: -32720 | ||
| 29 | # CHECK-NEXT: Initial: 0x0 | ||
| 30 | # CHECK-NEXT: Value: 0x0 | ||
| 31 | # CHECK-NEXT: Type: Function | ||
| 32 | # CHECK-NEXT: Section: Undefined | ||
| 33 | # CHECK-NEXT: Name: foo0 | ||
| 34 | # CHECK-NEXT: } | ||
| 35 | # CHECK-NEXT: ] | ||
| 36 | |||
| 37 | .text | ||
| 38 | .global __start | ||
| 39 | __start: | ||
| 40 | lui $28, %hi(%neg(%gp_rel(foo0))) | ||
| 41 | addiu $28, $28, %lo(%neg(%gp_rel(foo0))) | ||
| 42 | lw $4, %got_page(data)($28) | ||
| 43 | addiu $4, $4, %got_ofst(data) | ||
| 44 | lw $25, %call16(foo0)($28) | ||
| 45 | |||
| 46 | .data | ||
| 47 | data: | ||
| 48 | .word 0 | ||
deps/lld/test/ELF/mips-micro-jal.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check PLT creation for microMIPS to microMIPS calls. | 2 | # Check PLT creation for microMIPS to microMIPS calls. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -45,8 +46,6 @@ | ... | @@ -45,8 +46,6 @@ |
| 45 | # RUN: llvm-objdump -d -mattr=micromips %teb.exe \ | 46 | # RUN: llvm-objdump -d -mattr=micromips %teb.exe \ |
| 46 | # RUN: | FileCheck --check-prefix=MIXED %s | 47 | # RUN: | FileCheck --check-prefix=MIXED %s |
| 47 | 48 | ||
| 48 | # REQUIRES: mips | ||
| 49 | |||
| 50 | # EB: Disassembly of section .plt: | 49 | # EB: Disassembly of section .plt: |
| 51 | # EB-NEXT: .plt: | 50 | # EB-NEXT: .plt: |
| 52 | # EB-NEXT: 20010: 79 80 3f fd addiupc $3, 65524 | 51 | # EB-NEXT: 20010: 79 80 3f fd addiupc $3, 65524 |
deps/lld/test/ELF/mips-micro-plt.s+27-10| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check less-significant bit setup for microMIPS PLT. | 2 | # Check less-significant bit setup for microMIPS PLT. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -7,13 +8,12 @@ | ... | @@ -7,13 +8,12 @@ |
| 7 | # RUN: -mattr=micromips %s -o %t-exe.o | 8 | # RUN: -mattr=micromips %s -o %t-exe.o |
| 8 | # RUN: ld.lld %t-exe.o %t.so -o %t.exe | 9 | # RUN: ld.lld %t-exe.o %t.so -o %t.exe |
| 9 | # RUN: llvm-readobj -t -dt -mips-plt-got %t.exe | FileCheck %s | 10 | # RUN: llvm-readobj -t -dt -mips-plt-got %t.exe | FileCheck %s |
| 10 | 11 | # RUN: llvm-objdump -d -mattr=micromips %t.exe | FileCheck --check-prefix=ASM %s | |
| 11 | # REQUIRES: mips | ||
| 12 | 12 | ||
| 13 | # CHECK: Symbols [ | 13 | # CHECK: Symbols [ |
| 14 | # CHECK: Symbol { | 14 | # CHECK: Symbol { |
| 15 | # CHECK: Name: foo | 15 | # CHECK: Name: foo |
| 16 | # CHECK-NEXT: Value: 0x20008 | 16 | # CHECK-NEXT: Value: 0x20010 |
| 17 | # CHECK-NEXT: Size: | 17 | # CHECK-NEXT: Size: |
| 18 | # CHECK-NEXT: Binding: Local | 18 | # CHECK-NEXT: Binding: Local |
| 19 | # CHECK-NEXT: Type: None | 19 | # CHECK-NEXT: Type: None |
| ... | @@ -36,22 +36,28 @@ | ... | @@ -36,22 +36,28 @@ |
| 36 | # CHECK-NEXT: } | 36 | # CHECK-NEXT: } |
| 37 | # CHECK: Symbol { | 37 | # CHECK: Symbol { |
| 38 | # CHECK: Name: foo0 | 38 | # CHECK: Name: foo0 |
| 39 | # CHECK-NEXT: Value: 0x0 | 39 | # CHECK-NEXT: Value: 0x20040 |
| 40 | # CHECK-NEXT: Size: | 40 | # CHECK-NEXT: Size: |
| 41 | # CHECK-NEXT: Binding: Global | 41 | # CHECK-NEXT: Binding: Global |
| 42 | # CHECK-NEXT: Type: Function | 42 | # CHECK-NEXT: Type: Function |
| 43 | # CHECK-NEXT: Other: 0 | 43 | # CHECK-NEXT: Other [ |
| 44 | # CHECK-NEXT: STO_MIPS_MICROMIPS | ||
| 45 | # CHECK-NEXT: STO_MIPS_PLT | ||
| 46 | # CHECK-NEXT: ] | ||
| 44 | # CHECK-NEXT: Section: Undefined | 47 | # CHECK-NEXT: Section: Undefined |
| 45 | # CHECK-NEXT: } | 48 | # CHECK-NEXT: } |
| 46 | # CHECK-NEXT: ] | 49 | # CHECK-NEXT: ] |
| 47 | # CHECK: DynamicSymbols [ | 50 | # CHECK: DynamicSymbols [ |
| 48 | # CHECK: Symbol { | 51 | # CHECK: Symbol { |
| 49 | # CHECK: Name: foo0 | 52 | # CHECK: Name: foo0 |
| 50 | # CHECK-NEXT: Value: 0x0 | 53 | # CHECK-NEXT: Value: 0x20041 |
| 51 | # CHECK-NEXT: Size: | 54 | # CHECK-NEXT: Size: |
| 52 | # CHECK-NEXT: Binding: Global | 55 | # CHECK-NEXT: Binding: Global |
| 53 | # CHECK-NEXT: Type: Function | 56 | # CHECK-NEXT: Type: Function |
| 54 | # CHECK-NEXT: Other: 0 | 57 | # CHECK-NEXT: Other [ |
| 58 | # CHECK-NEXT: STO_MIPS_MICROMIPS | ||
| 59 | # CHECK-NEXT: STO_MIPS_PLT | ||
| 60 | # CHECK-NEXT: ] | ||
| 55 | # CHECK-NEXT: Section: Undefined | 61 | # CHECK-NEXT: Section: Undefined |
| 56 | # CHECK-NEXT: } | 62 | # CHECK-NEXT: } |
| 57 | # CHECK-NEXT: ] | 63 | # CHECK-NEXT: ] |
| ... | @@ -61,7 +67,7 @@ | ... | @@ -61,7 +67,7 @@ |
| 61 | # CHECK-NEXT: Entry { | 67 | # CHECK-NEXT: Entry { |
| 62 | # CHECK-NEXT: Address: | 68 | # CHECK-NEXT: Address: |
| 63 | # CHECK-NEXT: Access: | 69 | # CHECK-NEXT: Access: |
| 64 | # CHECK-NEXT: Initial: 0x20009 | 70 | # CHECK-NEXT: Initial: 0x20011 |
| 65 | # CHECK-NEXT: } | 71 | # CHECK-NEXT: } |
| 66 | # CHECK: ] | 72 | # CHECK: ] |
| 67 | # CHECK: } | 73 | # CHECK: } |
| ... | @@ -70,8 +76,8 @@ | ... | @@ -70,8 +76,8 @@ |
| 70 | # CHECK: Entries [ | 76 | # CHECK: Entries [ |
| 71 | # CHECK-NEXT: Entry { | 77 | # CHECK-NEXT: Entry { |
| 72 | # CHECK-NEXT: Address: | 78 | # CHECK-NEXT: Address: |
| 73 | # CHECK-NEXT: Initial: 0x20011 | 79 | # CHECK-NEXT: Initial: 0x20021 |
| 74 | # CHECK-NEXT: Value: 0x0 | 80 | # CHECK-NEXT: Value: 0x20041 |
| 75 | # CHECK-NEXT: Type: Function | 81 | # CHECK-NEXT: Type: Function |
| 76 | # CHECK-NEXT: Section: Undefined | 82 | # CHECK-NEXT: Section: Undefined |
| 77 | # CHECK-NEXT: Name: foo0@ | 83 | # CHECK-NEXT: Name: foo0@ |
| ... | @@ -79,6 +85,15 @@ | ... | @@ -79,6 +85,15 @@ |
| 79 | # CHECK-NEXT: ] | 85 | # CHECK-NEXT: ] |
| 80 | # CHECK-NEXT: } | 86 | # CHECK-NEXT: } |
| 81 | 87 | ||
| 88 | # ASM: __start: | ||
| 89 | # ASM-NEXT: 20000: fd 1c 80 18 lw $8, -32744($gp) | ||
| 90 | # ASM-NEXT: 20004: 11 08 00 10 addi $8, $8, 16 | ||
| 91 | # ASM-NEXT: 20008: 41 a8 00 02 lui $8, 2 | ||
| 92 | # ASM-NEXT: 2000c: 11 08 00 40 addi $8, $8, 64 | ||
| 93 | # | ||
| 94 | # ASM: foo: | ||
| 95 | # ASM-NEXT: 20010: f4 01 00 20 jal 131136 | ||
| 96 | |||
| 82 | .text | 97 | .text |
| 83 | .set micromips | 98 | .set micromips |
| 84 | .global foo | 99 | .global foo |
| ... | @@ -87,5 +102,7 @@ | ... | @@ -87,5 +102,7 @@ |
| 87 | __start: | 102 | __start: |
| 88 | lw $t0,%got(foo)($gp) | 103 | lw $t0,%got(foo)($gp) |
| 89 | addi $t0,$t0,%lo(foo) | 104 | addi $t0,$t0,%lo(foo) |
| 105 | lui $t0,%hi(foo0) | ||
| 106 | addi $t0,$t0,%lo(foo0) | ||
| 90 | foo: | 107 | foo: |
| 91 | jal foo0 | 108 | jal foo0 |
deps/lld/test/ELF/mips-micro-relocs.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check handling of microMIPS relocations. | 2 | # Check handling of microMIPS relocations. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -16,8 +17,6 @@ | ... | @@ -16,8 +17,6 @@ |
| 16 | # RUN: llvm-objdump -d -t -mattr=micromips %tel.exe \ | 17 | # RUN: llvm-objdump -d -t -mattr=micromips %tel.exe \ |
| 17 | # RUN: | FileCheck --check-prefixes=EL,SYM %s | 18 | # RUN: | FileCheck --check-prefixes=EL,SYM %s |
| 18 | 19 | ||
| 19 | # REQUIRES: mips | ||
| 20 | |||
| 21 | # EB: __start: | 20 | # EB: __start: |
| 22 | # EB-NEXT: 20010: 41 a3 00 01 lui $3, 1 | 21 | # EB-NEXT: 20010: 41 a3 00 01 lui $3, 1 |
| 23 | # EB-NEXT: 20014: 30 63 7f df addiu $3, $3, 32735 | 22 | # EB-NEXT: 20014: 30 63 7f df addiu $3, $3, 32735 |
deps/lld/test/ELF/mips-micro-thunks.s+59-26| ... | @@ -1,44 +1,77 @@ | ... | @@ -1,44 +1,77 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check microMIPS thunk generation. | 2 | # Check microMIPS thunk generation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| 4 | # RUN: -mattr=micromips %s -o %t-eb.o | 5 | # RUN: -mcpu=mips32r2 -mattr=micromips %s -o %t-eb.o |
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 6 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| 6 | # RUN: -position-independent -mattr=micromips \ | 7 | # RUN: -position-independent -mcpu=mips32r2 -mattr=micromips \ |
| 7 | # RUN: %S/Inputs/mips-micro.s -o %t-eb-pic.o | 8 | # RUN: %S/Inputs/mips-micro.s -o %t-eb-pic.o |
| 8 | # RUN: ld.lld -o %t-eb.exe %t-eb.o %t-eb-pic.o | 9 | # RUN: ld.lld -o %t-eb.exe %t-eb.o %t-eb-pic.o |
| 9 | # RUN: llvm-objdump -d -mattr=+micromips %t-eb.exe \ | 10 | # RUN: llvm-objdump -d -mattr=+micromips %t-eb.exe \ |
| 10 | # RUN: | FileCheck --check-prefix=EB %s | 11 | # RUN: | FileCheck --check-prefix=EB-R2 %s |
| 11 | 12 | ||
| 12 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | 13 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ |
| 13 | # RUN: -mattr=micromips %s -o %t-el.o | 14 | # RUN: -mcpu=mips32r2 -mattr=micromips %s -o %t-el.o |
| 14 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | 15 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ |
| 15 | # RUN: -position-independent -mattr=micromips \ | 16 | # RUN: -position-independent -mcpu=mips32r2 -mattr=micromips \ |
| 16 | # RUN: %S/Inputs/mips-micro.s -o %t-el-pic.o | 17 | # RUN: %S/Inputs/mips-micro.s -o %t-el-pic.o |
| 17 | # RUN: ld.lld -o %t-el.exe %t-el.o %t-el-pic.o | 18 | # RUN: ld.lld -o %t-el.exe %t-el.o %t-el-pic.o |
| 18 | # RUN: llvm-objdump -d -mattr=+micromips %t-el.exe \ | 19 | # RUN: llvm-objdump -d -mattr=+micromips %t-el.exe \ |
| 19 | # RUN: | FileCheck --check-prefix=EL %s | 20 | # RUN: | FileCheck --check-prefix=EL-R2 %s |
| 20 | 21 | ||
| 21 | # REQUIRES: mips | 22 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| 23 | # RUN: -mcpu=mips32r6 -mattr=micromips %s -o %t-eb-r6.o | ||
| 24 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | ||
| 25 | # RUN: -position-independent -mcpu=mips32r6 -mattr=micromips \ | ||
| 26 | # RUN: %S/Inputs/mips-micro.s -o %t-eb-pic-r6.o | ||
| 27 | # RUN: ld.lld -o %t-eb-r6.exe %t-eb-r6.o %t-eb-pic-r6.o | ||
| 28 | # RUN: llvm-objdump -d -mattr=+micromips %t-eb-r6.exe \ | ||
| 29 | # RUN: | FileCheck --check-prefix=EB-R6 %s | ||
| 30 | |||
| 31 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | ||
| 32 | # RUN: -mcpu=mips32r6 -mattr=micromips %s -o %t-el-r6.o | ||
| 33 | # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ | ||
| 34 | # RUN: -position-independent -mcpu=mips32r6 -mattr=micromips \ | ||
| 35 | # RUN: %S/Inputs/mips-micro.s -o %t-el-pic-r6.o | ||
| 36 | # RUN: ld.lld -o %t-el-r6.exe %t-el-r6.o %t-el-pic-r6.o | ||
| 37 | # RUN: llvm-objdump -d -mattr=+micromips %t-el-r6.exe \ | ||
| 38 | # RUN: | FileCheck --check-prefix=EL-R6 %s | ||
| 39 | |||
| 40 | # EB-R2: __start: | ||
| 41 | # EB-R2-NEXT: 20000: f4 01 00 04 jal 131080 <__microLA25Thunk_foo> | ||
| 42 | # EB-R2-NEXT: 20004: 00 00 00 00 nop | ||
| 43 | |||
| 44 | # EB-R2: __microLA25Thunk_foo: | ||
| 45 | # EB-R2-NEXT: 20008: 41 b9 00 02 lui $25, 2 | ||
| 46 | # EB-R2-NEXT: 2000c: d4 01 00 10 j 131104 | ||
| 47 | # EB-R2-NEXT: 20010: 33 39 00 21 addiu $25, $25, 33 | ||
| 48 | # EB-R2-NEXT: 20014: 0c 00 nop | ||
| 49 | |||
| 50 | # EL-R2: __start: | ||
| 51 | # EL-R2-NEXT: 20000: 01 f4 04 00 jal 131080 <__microLA25Thunk_foo> | ||
| 52 | # EL-R2-NEXT: 20004: 00 00 00 00 nop | ||
| 53 | |||
| 54 | # EL-R2: __microLA25Thunk_foo: | ||
| 55 | # EL-R2-NEXT: 20008: b9 41 02 00 lui $25, 2 | ||
| 56 | # EL-R2-NEXT: 2000c: 01 d4 10 00 j 131104 | ||
| 57 | # EL-R2-NEXT: 20010: 39 33 21 00 addiu $25, $25, 33 | ||
| 58 | # EL-R2-NEXT: 20014: 00 0c nop | ||
| 59 | |||
| 60 | # EB-R6: __start: | ||
| 61 | # EB-R6-NEXT: 20000: b4 00 00 00 balc 0 <__start> | ||
| 62 | |||
| 63 | # EB-R6: __microLA25Thunk_foo: | ||
| 64 | # EB-R6-NEXT: 20004: 13 20 00 02 lui $25, 2 | ||
| 65 | # EB-R6-NEXT: 20008: 33 39 00 11 addiu $25, $25, 17 | ||
| 66 | # EB-R6-NEXT: 2000c: 94 00 00 00 bc 0 <__microLA25Thunk_foo+0x8> | ||
| 67 | |||
| 68 | # EL-R6: __start: | ||
| 69 | # EL-R6-NEXT: 20000: 00 b4 00 00 balc 0 <__start> | ||
| 22 | 70 | ||
| 23 | # EB: __start: | 71 | # EL-R6: __microLA25Thunk_foo: |
| 24 | # EB-NEXT: 20000: f4 01 00 04 jal 131080 <__microLA25Thunk_foo> | 72 | # EL-R6-NEXT: 20004: 20 13 02 00 lui $25, 2 |
| 25 | # EB-NEXT: 20004: 00 00 00 00 nop | 73 | # EL-R6-NEXT: 20008: 39 33 11 00 addiu $25, $25, 17 |
| 26 | 74 | # EL-R6-NEXT: 2000c: 00 94 00 00 bc 0 <__microLA25Thunk_foo+0x8> | |
| 27 | # EB: __microLA25Thunk_foo: | ||
| 28 | # EB-NEXT: 20008: 41 b9 00 02 lui $25, 2 | ||
| 29 | # EB-NEXT: 2000c: d4 01 00 10 j 131104 | ||
| 30 | # EB-NEXT: 20010: 33 39 00 21 addiu $25, $25, 33 | ||
| 31 | # EB-NEXT: 20014: 0c 00 nop | ||
| 32 | |||
| 33 | # EL: __start: | ||
| 34 | # EL-NEXT: 20000: 01 f4 04 00 jal 131080 <__microLA25Thunk_foo> | ||
| 35 | # EL-NEXT: 20004: 00 00 00 00 nop | ||
| 36 | |||
| 37 | # EL: __microLA25Thunk_foo: | ||
| 38 | # EL-NEXT: 20008: b9 41 02 00 lui $25, 2 | ||
| 39 | # EL-NEXT: 2000c: 01 d4 10 00 j 131104 | ||
| 40 | # EL-NEXT: 20010: 39 33 21 00 addiu $25, $25, 33 | ||
| 41 | # EL-NEXT: 20014: 00 0c nop | ||
| 42 | 75 | ||
| 43 | .text | 76 | .text |
| 44 | .set micromips | 77 | .set micromips |
deps/lld/test/ELF/mips-micror6-relocs.s created+38| ... | @@ -0,0 +1,38 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | |||
| 3 | # Check handling of microMIPS R6 relocations. | ||
| 4 | |||
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips -mcpu=mips32r6 \ | ||
| 6 | # RUN: %S/Inputs/mips-micro.s -o %t1eb.o | ||
| 7 | # RUN: llvm-mc -filetype=obj -triple=mips -mcpu=mips32r6 %s -o %t2eb.o | ||
| 8 | # RUN: ld.lld -o %teb.exe %t1eb.o %t2eb.o | ||
| 9 | # RUN: llvm-objdump -d -t -mattr=micromips %teb.exe \ | ||
| 10 | # RUN: | FileCheck --check-prefixes=EB,SYM %s | ||
| 11 | |||
| 12 | # RUN: llvm-mc -filetype=obj -triple=mipsel -mcpu=mips32r6 \ | ||
| 13 | # RUN: %S/Inputs/mips-micro.s -o %t1el.o | ||
| 14 | # RUN: llvm-mc -filetype=obj -triple=mipsel -mcpu=mips32r6 %s -o %t2el.o | ||
| 15 | # RUN: ld.lld -o %tel.exe %t1el.o %t2el.o | ||
| 16 | # RUN: llvm-objdump -d -t -mattr=micromips %tel.exe \ | ||
| 17 | # RUN: | FileCheck --check-prefixes=EL,SYM %s | ||
| 18 | |||
| 19 | # EB: __start: | ||
| 20 | # EB-NEXT: 20010: 78 47 ff fd lapc $2, -12 | ||
| 21 | # EB-NEXT: 20014: 80 7f ff f6 beqzc $3, -36 | ||
| 22 | # EB-NEXT: 20018: b7 ff ff f4 balc -24 <foo> | ||
| 23 | |||
| 24 | # EL: __start: | ||
| 25 | # EL-NEXT: 20010: 47 78 fd ff lapc $2, -12 | ||
| 26 | # EL-NEXT: 20014: 7f 80 f6 ff beqzc $3, -36 | ||
| 27 | # EL-NEXT: 20018: ff b7 f4 ff balc -24 <foo> | ||
| 28 | |||
| 29 | # SYM: 00020000 g F .text 00000000 foo | ||
| 30 | # SYM: 00020010 .text 00000000 __start | ||
| 31 | |||
| 32 | .text | ||
| 33 | .set micromips | ||
| 34 | .global __start | ||
| 35 | __start: | ||
| 36 | addiupc $2, foo+4 # R_MICROMIPS_PC19_S2 | ||
| 37 | beqzc $3, foo+4 # R_MICROMIPS_PC21_S1 | ||
| 38 | balc foo+4 # R_MICROMIPS_PC26_S1 | ||
deps/lld/test/ELF/mips-n32-emul.s+2-3| ... | @@ -1,10 +1,9 @@ | ... | @@ -1,10 +1,9 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check that LLD shows an error when N32 ABI emulation argument | 2 | # Check that LLD shows an error when N32 ABI emulation argument |
| 2 | # is combined with non-N32 ABI object files. | 3 | # is combined with non-N32 ABI object files. |
| 3 | 4 | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 5 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 5 | # RUN: not ld.lld -m elf32btsmipn32 %t.o -o %t.exe 2>&1 | FileCheck %s | 6 | # RUN: not ld.lld -m elf32btsmipn32 %t.o -o /dev/null 2>&1 | FileCheck %s |
| 6 | |||
| 7 | # REQUIRES: mips | ||
| 8 | 7 | ||
| 9 | .text | 8 | .text |
| 10 | .global __start | 9 | .global __start |
deps/lld/test/ELF/mips-n32-rels.s+23-23| ... | @@ -1,29 +1,27 @@ | ... | @@ -1,29 +1,27 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check handling of N32 ABI relocation records. | 2 | # Check handling of N32 ABI relocation records. |
| 2 | 3 | ||
| 3 | # For now llvm-mc generates incorrect object files for N32 ABI. | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ |
| 4 | # We use the binary input file generated by GNU tool. | 5 | # RUN: -target-abi n32 -o %t.o %s |
| 5 | # llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | 6 | # RUN: ld.lld %t.o -o %t.exe |
| 6 | # -target-abi n32 %s -o %t.o | ||
| 7 | # RUN: ld.lld %S/Inputs/mips-n32-rels.o -o %t.exe | ||
| 8 | # RUN: llvm-objdump -t -d -s %t.exe | FileCheck %s | 7 | # RUN: llvm-objdump -t -d -s %t.exe | FileCheck %s |
| 9 | # RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=ELF %s | 8 | # RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=ELF %s |
| 10 | 9 | ||
| 11 | # REQUIRES: mips | 10 | .option pic2 |
| 11 | .text | ||
| 12 | .type __start, @function | ||
| 13 | .global __start | ||
| 14 | __start: | ||
| 15 | lui $gp,%hi(%neg(%gp_rel(__start))) # R_MIPS_GPREL16 | ||
| 16 | # R_MIPS_SUB | ||
| 17 | # R_MIPS_HI16 | ||
| 18 | loc: | ||
| 19 | daddiu $gp,$gp,%lo(%neg(%gp_rel(__start))) # R_MIPS_GPREL16 | ||
| 20 | # R_MIPS_SUB | ||
| 21 | # R_MIPS_LO16 | ||
| 12 | 22 | ||
| 13 | # .text | 23 | .section .rodata,"a",@progbits |
| 14 | # .type __start, @function | 24 | .gpword(loc) # R_MIPS_GPREL32 |
| 15 | # .global __start | ||
| 16 | # __start: | ||
| 17 | # lui $gp,%hi(%neg(%gp_rel(__start))) # R_MIPS_GPREL16 | ||
| 18 | # # R_MIPS_SUB | ||
| 19 | # # R_MIPS_HI16 | ||
| 20 | # loc: | ||
| 21 | # daddiu $gp,$gp,%lo(%neg(%gp_rel(__start))) # R_MIPS_GPREL16 | ||
| 22 | # # R_MIPS_SUB | ||
| 23 | # # R_MIPS_LO16 | ||
| 24 | # | ||
| 25 | # .section .rodata,"a",@progbits | ||
| 26 | # .gpword(loc) # R_MIPS_32 | ||
| 27 | 25 | ||
| 28 | # CHECK: Disassembly of section .text: | 26 | # CHECK: Disassembly of section .text: |
| 29 | # CHECK-NEXT: __start: | 27 | # CHECK-NEXT: __start: |
| ... | @@ -38,8 +36,8 @@ | ... | @@ -38,8 +36,8 @@ |
| 38 | # ^-- %lo(0x17ff0) | 36 | # ^-- %lo(0x17ff0) |
| 39 | 37 | ||
| 40 | # CHECK: Contents of section .rodata: | 38 | # CHECK: Contents of section .rodata: |
| 41 | # CHECK-NEXT: {{[0-9a-f]+}} 00020004 | 39 | # CHECK-NEXT: {{[0-9a-f]+}} fffe8014 |
| 42 | # ^-- loc | 40 | # ^-- loc - _gp |
| 43 | 41 | ||
| 44 | # CHECK: 00020004 .text 00000000 loc | 42 | # CHECK: 00020004 .text 00000000 loc |
| 45 | # CHECK: 00037ff0 .got 00000000 .hidden _gp | 43 | # CHECK: 00037ff0 .got 00000000 .hidden _gp |
| ... | @@ -67,5 +65,7 @@ | ... | @@ -67,5 +65,7 @@ |
| 67 | # ELF-NEXT: SectionHeaderOffset: | 65 | # ELF-NEXT: SectionHeaderOffset: |
| 68 | # ELF-NEXT: Flags [ | 66 | # ELF-NEXT: Flags [ |
| 69 | # ELF-NEXT: EF_MIPS_ABI2 | 67 | # ELF-NEXT: EF_MIPS_ABI2 |
| 70 | # ELF-NEXT: EF_MIPS_ARCH_64R2 | 68 | # ELF-NEXT: EF_MIPS_ARCH_64 |
| 69 | # ELF-NEXT: EF_MIPS_CPIC | ||
| 70 | # ELF-NEXT: EF_MIPS_PIC | ||
| 71 | # ELF-NEXT: ] | 71 | # ELF-NEXT: ] |
deps/lld/test/ELF/mips-non-zero-gp0.s created+54| ... | @@ -0,0 +1,54 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | |||
| 3 | # Check addend adjustment in case of generating a relocatable object | ||
| 4 | # if some input files have non-zero GP0 value. | ||
| 5 | |||
| 6 | # We have to use GNU as and ld.bfd 2.28 to generate relocatable object | ||
| 7 | # files with non-zero GP0 value using the following command lines: | ||
| 8 | # | ||
| 9 | # as -mips32 -o test.o \ | ||
| 10 | # && ld.bfd -m elf32btsmip -r test.o -o mips-gp0-non-zero.o | ||
| 11 | # as -mips64 -o test.o \ | ||
| 12 | # && ld.bfd -m elf64btsmip -r test.o -o mips-n64-gp0-non-zero.o | ||
| 13 | |||
| 14 | # Source code for mips-gp0-non-zero.o: | ||
| 15 | # .text | ||
| 16 | # .global __start | ||
| 17 | # __start: | ||
| 18 | # lw $t0,%call16(__start)($gp) | ||
| 19 | # foo: | ||
| 20 | # nop | ||
| 21 | # bar: | ||
| 22 | # nop | ||
| 23 | # | ||
| 24 | # .section .rodata, "a" | ||
| 25 | # v: | ||
| 26 | # .gpword foo | ||
| 27 | # .gpword bar | ||
| 28 | |||
| 29 | # Source code for mips-n64-gp0-non-zero.o and mips-micro-gp0-non-zero.o: | ||
| 30 | # .text | ||
| 31 | # .global __start | ||
| 32 | # __start: | ||
| 33 | # foo: | ||
| 34 | # lui $gp,%hi(%neg(%gp_rel(foo))) | ||
| 35 | |||
| 36 | # 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 | ||
| 38 | # RUN: llvm-objdump -s %t-32.r | FileCheck --check-prefix=ADDEND32 %s | ||
| 39 | |||
| 40 | # 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 | ||
| 42 | # RUN: llvm-readobj -r %S/Inputs/mips-n64-gp0-non-zero.o %t-64.r \ | ||
| 43 | # RUN: | FileCheck --check-prefix=ADDEND64 %s | ||
| 44 | |||
| 45 | # GPVAL: GP: 0x0 | ||
| 46 | |||
| 47 | # ADDEND32: Contents of section .rodata: | ||
| 48 | # ADDEND32-NEXT: 0000 00007ff4 00007ff8 | ||
| 49 | # ^ 4+GP0 ^ 8+GP0 | ||
| 50 | |||
| 51 | # ADDEND64: File: {{.*}}{{/|\\}}mips-n64-gp0-non-zero.o | ||
| 52 | # ADDEND64: .text 0xFFFFFFFFFFFF8011 | ||
| 53 | # ADDEND64: File: {{.*}}{{/|\\}}mips-non-zero-gp0.s.tmp-64.r | ||
| 54 | # ADDEND64: .text 0x0 | ||
deps/lld/test/ELF/mips-nonalloc.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check reading addends for relocations in non-allocatable sections. | 2 | # Check reading addends for relocations in non-allocatable sections. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o |
| ... | @@ -6,8 +7,6 @@ | ... | @@ -6,8 +7,6 @@ |
| 6 | # RUN: ld.lld %t1.o %t2.o -o %t.exe | 7 | # RUN: ld.lld %t1.o %t2.o -o %t.exe |
| 7 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | 8 | # RUN: llvm-objdump -s %t.exe | FileCheck %s |
| 8 | 9 | ||
| 9 | # REQUIRES: mips | ||
| 10 | |||
| 11 | # CHECK: Contents of section .debug_info: | 10 | # CHECK: Contents of section .debug_info: |
| 12 | # CHECK-NEXT: 0000 ffffffff 00020000 00020000 | 11 | # CHECK-NEXT: 0000 ffffffff 00020000 00020000 |
| 13 | # ^--------^-- __start | 12 | # ^--------^-- __start |
deps/lld/test/ELF/mips-options.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check MIPS .MIPS.options section generation. | 2 | # Check MIPS .MIPS.options section generation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o |
| ... | @@ -9,8 +10,6 @@ | ... | @@ -9,8 +10,6 @@ |
| 9 | # RUN: ld.lld %t1.o %t2.o --gc-sections --script %t.rel.script -shared -o %t.so | 10 | # RUN: ld.lld %t1.o %t2.o --gc-sections --script %t.rel.script -shared -o %t.so |
| 10 | # RUN: llvm-readobj -symbols -mips-options %t.so | FileCheck %s | 11 | # RUN: llvm-readobj -symbols -mips-options %t.so | FileCheck %s |
| 11 | 12 | ||
| 12 | # REQUIRES: mips | ||
| 13 | |||
| 14 | .text | 13 | .text |
| 15 | .globl __start | 14 | .globl __start |
| 16 | __start: | 15 | __start: |
deps/lld/test/ELF/mips-out-of-bounds-call16-reloc.s+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check that we create an error on an out-of-bounds R_MIPS_CALL_16 | 2 | # Check that we create an error on an out-of-bounds R_MIPS_CALL_16 |
| 2 | 3 | ||
| 3 | # REQUIRES: mips | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o |
| 5 | # RUN: not ld.lld %t1.o -o %t.exe 2>&1 | FileCheck %s | 5 | # RUN: not ld.lld %t1.o -o /dev/null 2>&1 | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: relocation R_MIPS_CALL16 out of range: 32768 is not in [-32768, 32767] | 7 | # CHECK: relocation R_MIPS_CALL16 out of range: 32768 is not in [-32768, 32767] |
| 8 | 8 |
deps/lld/test/ELF/mips-pc-relocs.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check R_MIPS_PCxxx relocations calculation. | 2 | # Check R_MIPS_PCxxx relocations calculation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -7,8 +8,6 @@ | ... | @@ -7,8 +8,6 @@ |
| 7 | # RUN: ld.lld %t1.o %t2.o -o %t.exe | 8 | # RUN: ld.lld %t1.o %t2.o -o %t.exe |
| 8 | # RUN: llvm-objdump -mcpu=mips32r6 -d -t -s %t.exe | FileCheck %s | 9 | # RUN: llvm-objdump -mcpu=mips32r6 -d -t -s %t.exe | FileCheck %s |
| 9 | 10 | ||
| 10 | # REQUIRES: mips | ||
| 11 | |||
| 12 | .text | 11 | .text |
| 13 | .globl __start | 12 | .globl __start |
| 14 | __start: | 13 | __start: |
deps/lld/test/ELF/mips-plt-copy.s+5-6| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check creating of R_MIPS_COPY and R_MIPS_JUMP_SLOT dynamic relocations | 2 | # Check creating of R_MIPS_COPY and R_MIPS_JUMP_SLOT dynamic relocations |
| 2 | # and corresponding PLT entries. | 3 | # and corresponding PLT entries. |
| 3 | 4 | ||
| ... | @@ -8,16 +9,14 @@ | ... | @@ -8,16 +9,14 @@ |
| 8 | # RUN: ld.lld %t.o %t.so -o %t.exe | 9 | # RUN: ld.lld %t.o %t.so -o %t.exe |
| 9 | # RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s | 10 | # RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | # CHECK: Relocations [ | 12 | # CHECK: Relocations [ |
| 14 | # CHECK-NEXT: Section ({{.*}}) .rel.dyn { | 13 | # CHECK-NEXT: Section ({{.*}}) .rel.dyn { |
| 15 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0 | 14 | # CHECK-DAG: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0 |
| 16 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data1 0x0 | 15 | # CHECK-DAG: 0x{{[0-9A-F]+}} R_MIPS_COPY data1 0x0 |
| 17 | # CHECK-NEXT: } | 16 | # CHECK-NEXT: } |
| 18 | # CHECK-NEXT: Section ({{.*}}) .rel.plt { | 17 | # CHECK-NEXT: Section ({{.*}}) .rel.plt { |
| 19 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo0 0x0 | 18 | # CHECK-DAG: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo0 0x0 |
| 20 | # CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo1 0x0 | 19 | # CHECK-DAG: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo1 0x0 |
| 21 | # CHECK-NEXT: } | 20 | # CHECK-NEXT: } |
| 22 | # CHECK-NEXT: ] | 21 | # CHECK-NEXT: ] |
| 23 | 22 |
deps/lld/test/ELF/mips-plt-n32.s created+43| ... | @@ -0,0 +1,43 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | |||
| 3 | # Check PLT entries generation in case of using N32 ABI. | ||
| 4 | |||
| 5 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | ||
| 6 | # RUN: -target-abi n32 %s -o %t1.o | ||
| 7 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | ||
| 8 | # RUN: -target-abi n32 %S/Inputs/mips-dynamic.s -o %t2.o | ||
| 9 | # RUN: ld.lld %t2.o -shared -o %t.so | ||
| 10 | # RUN: ld.lld %t1.o %t.so -o %t.exe | ||
| 11 | # RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=DEFAULT,CHECK | ||
| 12 | # RUN: ld.lld %t2.o -shared -o %t.so -z hazardplt | ||
| 13 | # RUN: ld.lld %t1.o %t.so -o %t.exe -z hazardplt | ||
| 14 | # RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=HAZARDPLT,CHECK | ||
| 15 | |||
| 16 | # CHECK: Disassembly of section .text: | ||
| 17 | # CHECK-NEXT: __start: | ||
| 18 | # CHECK-NEXT: 20000: 0c 00 80 0c jal 131120 | ||
| 19 | # ^-- 0x20030 gotplt[foo0] | ||
| 20 | # CHECK-NEXT: 20004: 00 00 00 00 nop | ||
| 21 | # | ||
| 22 | # CHECK-NEXT: Disassembly of section .plt: | ||
| 23 | # CHECK-NEXT: .plt: | ||
| 24 | # CHECK-NEXT: 20010: 3c 0e 00 03 lui $14, 3 | ||
| 25 | # CHECK-NEXT: 20014: 8d d9 00 04 lw $25, 4($14) | ||
| 26 | # CHECK-NEXT: 20018: 25 ce 00 04 addiu $14, $14, 4 | ||
| 27 | # CHECK-NEXT: 2001c: 03 0e c0 23 subu $24, $24, $14 | ||
| 28 | # CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra | ||
| 29 | # CHECK-NEXT: 20024: 00 18 c0 82 srl $24, $24, 2 | ||
| 30 | # DEFAULT: 20028: 03 20 f8 09 jalr $25 | ||
| 31 | # HAZARDPLT: 20028: 03 20 fc 09 jalr.hb $25 | ||
| 32 | # CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2 | ||
| 33 | |||
| 34 | # CHECK-NEXT: 20030: 3c 0f 00 03 lui $15, 3 | ||
| 35 | # CHECK-NEXT: 20034: 8d f9 00 0c lw $25, 12($15) | ||
| 36 | # DEFAULT: 20038: 03 20 00 08 jr $25 | ||
| 37 | # HAZARDPLT: 20038: 03 20 04 08 jr.hb $25 | ||
| 38 | # CHECK-NEXT: 2003c: 25 f8 00 0c addiu $24, $15, 12 | ||
| 39 | |||
| 40 | .text | ||
| 41 | .global __start | ||
| 42 | __start: | ||
| 43 | jal foo0 # R_MIPS_26 against 'foo0' from DSO | ||
deps/lld/test/ELF/mips-plt-r6.s+9-5| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check PLT entries generation in case of R6 ABI version. | 2 | # Check PLT entries generation in case of R6 ABI version. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -6,9 +7,10 @@ | ... | @@ -6,9 +7,10 @@ |
| 6 | # RUN: -mcpu=mips32r6 %S/Inputs/mips-dynamic.s -o %t2.o | 7 | # RUN: -mcpu=mips32r6 %S/Inputs/mips-dynamic.s -o %t2.o |
| 7 | # RUN: ld.lld %t2.o -shared -o %t.so | 8 | # RUN: ld.lld %t2.o -shared -o %t.so |
| 8 | # RUN: ld.lld %t1.o %t.so -o %t.exe | 9 | # RUN: ld.lld %t1.o %t.so -o %t.exe |
| 9 | # RUN: llvm-objdump -d %t.exe | FileCheck %s | 10 | # RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=DEFAULT,CHECK |
| 10 | 11 | # RUN: ld.lld %t2.o -shared -o %t.so -z hazardplt | |
| 11 | # REQUIRES: mips | 12 | # RUN: ld.lld %t1.o %t.so -o %t.exe -z hazardplt |
| 13 | # RUN: llvm-objdump -d %t.exe | FileCheck %s --check-prefixes=HAZARDPLT,CHECK | ||
| 12 | 14 | ||
| 13 | # CHECK: Disassembly of section .text: | 15 | # CHECK: Disassembly of section .text: |
| 14 | # CHECK-NEXT: __start: | 16 | # CHECK-NEXT: __start: |
| ... | @@ -24,12 +26,14 @@ | ... | @@ -24,12 +26,14 @@ |
| 24 | # CHECK-NEXT: 2001c: 03 1c c0 23 subu $24, $24, $gp | 26 | # CHECK-NEXT: 2001c: 03 1c c0 23 subu $24, $24, $gp |
| 25 | # CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra | 27 | # CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra |
| 26 | # CHECK-NEXT: 20024: 00 18 c0 82 srl $24, $24, 2 | 28 | # CHECK-NEXT: 20024: 00 18 c0 82 srl $24, $24, 2 |
| 27 | # CHECK-NEXT: 20028: 03 20 f8 09 jalr $25 | 29 | # DEFAULT: 20028: 03 20 f8 09 jalr $25 |
| 30 | # HAZARDPLT: 20028: 03 20 fc 09 jalr.hb $25 | ||
| 28 | # CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2 | 31 | # CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2 |
| 29 | 32 | ||
| 30 | # CHECK-NEXT: 20030: 3c 0f 00 03 aui $15, $zero, 3 | 33 | # CHECK-NEXT: 20030: 3c 0f 00 03 aui $15, $zero, 3 |
| 31 | # CHECK-NEXT: 20034: 8d f9 00 0c lw $25, 12($15) | 34 | # CHECK-NEXT: 20034: 8d f9 00 0c lw $25, 12($15) |
| 32 | # CHECK-NEXT: 20038: 03 20 00 09 jr $25 | 35 | # DEFAULT: 20038: 03 20 00 09 jr $25 |
| 36 | # HAZARDPLT: 20038: 03 20 04 09 jr.hb $25 | ||
| 33 | # CHECK-NEXT: 2003c: 25 f8 00 0c addiu $24, $15, 12 | 37 | # CHECK-NEXT: 2003c: 25 f8 00 0c addiu $24, $15, 12 |
| 34 | 38 | ||
| 35 | .text | 39 | .text |
deps/lld/test/ELF/mips-reginfo.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check MIPS .reginfo section generation. | 2 | # Check MIPS .reginfo section generation. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o |
| ... | @@ -6,8 +7,6 @@ | ... | @@ -6,8 +7,6 @@ |
| 6 | # RUN: ld.lld %t1.o %t2.o --gc-sections -shared -o %t.so | 7 | # RUN: ld.lld %t1.o %t2.o --gc-sections -shared -o %t.so |
| 7 | # RUN: llvm-readobj -symbols -mips-reginfo %t.so | FileCheck %s | 8 | # RUN: llvm-readobj -symbols -mips-reginfo %t.so | FileCheck %s |
| 8 | 9 | ||
| 9 | # REQUIRES: mips | ||
| 10 | |||
| 11 | .text | 10 | .text |
| 12 | .globl __start | 11 | .globl __start |
| 13 | __start: | 12 | __start: |
deps/lld/test/ELF/mips-relocatable.s+1-2| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check linking MIPS code in case of -r linker's option. | 2 | # Check linking MIPS code in case of -r linker's option. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o |
| 4 | # RUN: ld.lld -r -o %t-r.o %t.o | 5 | # RUN: ld.lld -r -o %t-r.o %t.o |
| 5 | # RUN: llvm-objdump -s -t %t-r.o | FileCheck %s | 6 | # RUN: llvm-objdump -s -t %t-r.o | FileCheck %s |
| 6 | 7 | ||
| 7 | # REQUIRES: mips | ||
| 8 | |||
| 9 | .text | 8 | .text |
| 10 | .global __start | 9 | .global __start |
| 11 | __start: | 10 | __start: |
deps/lld/test/ELF/mips-sto-pic-flag.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # In case of linking PIC and non-PIC code together and generation | 2 | # In case of linking PIC and non-PIC code together and generation |
| 2 | # of a relocatable object, all PIC symbols should have STO_MIPS_PIC | 3 | # of a relocatable object, all PIC symbols should have STO_MIPS_PIC |
| 3 | # flag in the symbol table of the ouput file. | 4 | # flag in the symbol table of the ouput file. |
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | # RUN: ld.lld -r %t-npic.o %t-pic.o -o %t-rel.o | 9 | # RUN: ld.lld -r %t-npic.o %t-pic.o -o %t-rel.o |
| 9 | # RUN: llvm-readobj -t %t-rel.o | FileCheck %s | 10 | # RUN: llvm-readobj -t %t-rel.o | FileCheck %s |
| 10 | 11 | ||
| 11 | # REQUIRES: mips | ||
| 12 | |||
| 13 | # CHECK: Symbol { | 12 | # CHECK: Symbol { |
| 14 | # CHECK: Name: main | 13 | # CHECK: Name: main |
| 15 | # CHECK-NEXT: Value: | 14 | # CHECK-NEXT: Value: |
deps/lld/test/ELF/mips-sto-plt.s+5-6| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check assigning STO_MIPS_PLT flag to symbol needs a pointer equality. | 2 | # Check assigning STO_MIPS_PLT flag to symbol needs a pointer equality. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -7,8 +8,6 @@ | ... | @@ -7,8 +8,6 @@ |
| 7 | # RUN: ld.lld %t.o %t.so -o %t.exe | 8 | # RUN: ld.lld %t.o %t.so -o %t.exe |
| 8 | # RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s | 9 | # RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s |
| 9 | 10 | ||
| 10 | # REQUIRES: mips | ||
| 11 | |||
| 12 | # CHECK: Symbol { | 11 | # CHECK: Symbol { |
| 13 | # CHECK: Name: foo0@ | 12 | # CHECK: Name: foo0@ |
| 14 | # CHECK-NEXT: Value: 0x0 | 13 | # CHECK-NEXT: Value: 0x0 |
| ... | @@ -18,9 +17,9 @@ | ... | @@ -18,9 +17,9 @@ |
| 18 | # CHECK-NEXT: Other: 0 | 17 | # CHECK-NEXT: Other: 0 |
| 19 | # CHECK-NEXT: Section: Undefined | 18 | # CHECK-NEXT: Section: Undefined |
| 20 | # CHECK-NEXT: } | 19 | # CHECK-NEXT: } |
| 21 | # CHECK: Symbol { | 20 | # CHECK-NEXT: Symbol { |
| 22 | # CHECK: Name: foo1@ | 21 | # CHECK-NEXT: Name: foo1@ |
| 23 | # CHECK-NEXT: Value: 0x20050 | 22 | # CHECK-NEXT: Value: 0x[[FOO1:[0-9A-F]+]] |
| 24 | # CHECK-NEXT: Size: 0 | 23 | # CHECK-NEXT: Size: 0 |
| 25 | # CHECK-NEXT: Binding: Global | 24 | # CHECK-NEXT: Binding: Global |
| 26 | # CHECK-NEXT: Type: Function | 25 | # CHECK-NEXT: Type: Function |
| ... | @@ -48,7 +47,7 @@ | ... | @@ -48,7 +47,7 @@ |
| 48 | # CHECK-NEXT: Entry { | 47 | # CHECK-NEXT: Entry { |
| 49 | # CHECK-NEXT: Address: | 48 | # CHECK-NEXT: Address: |
| 50 | # CHECK-NEXT: Initial: | 49 | # CHECK-NEXT: Initial: |
| 51 | # CHECK-NEXT: Value: 0x20050 | 50 | # CHECK-NEXT: Value: 0x[[FOO1]] |
| 52 | # CHECK-NEXT: Type: Function | 51 | # CHECK-NEXT: Type: Function |
| 53 | # CHECK-NEXT: Section: Undefined | 52 | # CHECK-NEXT: Section: Undefined |
| 54 | # CHECK-NEXT: Name: foo1 | 53 | # CHECK-NEXT: Name: foo1 |
deps/lld/test/ELF/mips-tls-64-pic-local-variable.s created+49| ... | @@ -0,0 +1,49 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | # MIPS TLS variables that are marked as local by a version script were previously | ||
| 3 | # writing values to the GOT that caused runtime crashes. This was happending when | ||
| 4 | # linking jemalloc_tsd.c in FreeBSD libc. Check that we do the right thing now: | ||
| 5 | |||
| 6 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o | ||
| 7 | # RUN: echo "{ global: foo; local: *; };" > %t.script | ||
| 8 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so | ||
| 9 | # RUN: llvm-objdump --section=.got -s %t.so | FileCheck %s -check-prefix GOT | ||
| 10 | # RUN: llvm-readobj -r %t.so | FileCheck %s -check-prefix RELOCS | ||
| 11 | |||
| 12 | # GOT: Contents of section .got: | ||
| 13 | # GOT-NEXT: 20000 00000000 00000000 80000000 00000000 | ||
| 14 | # GOT-NEXT: 20010 00000000 00000000 00000000 00000000 | ||
| 15 | # GOT-NEXT: 20020 ffffffff ffff8000 | ||
| 16 | |||
| 17 | # RELOCS: Section ({{.+}}) .rel.dyn { | ||
| 18 | # RELOCS-NEXT: 0x20018 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE | ||
| 19 | # RELOCS-NEXT: } | ||
| 20 | |||
| 21 | # Test case generated using clang -mcpu=mips4 -target mips64-unknown-freebsd12.0 -fpic -O -G0 -EB -mabi=n64 -msoft-float -std=gnu99 -S %s -o %t.s | ||
| 22 | # from the following source: | ||
| 23 | # | ||
| 24 | # _Thread_local int x; | ||
| 25 | # int foo() { return x; } | ||
| 26 | # | ||
| 27 | .text | ||
| 28 | .globl foo | ||
| 29 | .p2align 3 | ||
| 30 | .type foo,@function | ||
| 31 | .ent foo | ||
| 32 | foo: | ||
| 33 | lui $1, %hi(%neg(%gp_rel(foo))) | ||
| 34 | daddu $1, $1, $25 | ||
| 35 | daddiu $gp, $1, %lo(%neg(%gp_rel(foo))) | ||
| 36 | ld $25, %call16(__tls_get_addr)($gp) | ||
| 37 | jalr $25 | ||
| 38 | daddiu $4, $gp, %tlsgd(x) | ||
| 39 | .end foo | ||
| 40 | |||
| 41 | .type x,@object | ||
| 42 | .section .tbss,"awT",@nobits | ||
| 43 | .globl x | ||
| 44 | .p2align 2 | ||
| 45 | x: | ||
| 46 | .4byte 0 | ||
| 47 | .size x, 4 | ||
| 48 | |||
| 49 | |||
deps/lld/test/ELF/mips-tls-64.s+39-40| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check MIPS TLS 64-bit relocations handling. | 2 | # Check MIPS TLS 64-bit relocations handling. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ |
| ... | @@ -13,31 +14,29 @@ | ... | @@ -13,31 +14,29 @@ |
| 13 | # RUN: llvm-objdump -d -s -t %t-out.so | FileCheck -check-prefix=DIS-SO %s | 14 | # RUN: llvm-objdump -d -s -t %t-out.so | FileCheck -check-prefix=DIS-SO %s |
| 14 | # 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 |
| 15 | 16 | ||
| 16 | # REQUIRES: mips | ||
| 17 | |||
| 18 | # DIS: __start: | 17 | # DIS: __start: |
| 19 | # DIS-NEXT: 20000: 24 62 80 20 addiu $2, $3, -32736 | 18 | # DIS-NEXT: 20000: 24 62 80 30 addiu $2, $3, -32720 |
| 20 | # DIS-NEXT: 20004: 24 62 80 30 addiu $2, $3, -32720 | 19 | # DIS-NEXT: 20004: 24 62 80 20 addiu $2, $3, -32736 |
| 21 | # DIS-NEXT: 20008: 24 62 80 38 addiu $2, $3, -32712 | 20 | # DIS-NEXT: 20008: 24 62 80 40 addiu $2, $3, -32704 |
| 22 | # DIS-NEXT: 2000c: 24 62 80 48 addiu $2, $3, -32696 | 21 | # DIS-NEXT: 2000c: 24 62 80 50 addiu $2, $3, -32688 |
| 23 | # DIS-NEXT: 20010: 24 62 80 58 addiu $2, $3, -32680 | 22 | # DIS-NEXT: 20010: 24 62 80 28 addiu $2, $3, -32728 |
| 24 | 23 | ||
| 25 | # DIS: Contents of section .got: | 24 | # DIS: Contents of section .got: |
| 26 | # DIS-NEXT: 30010 00000000 00000000 80000000 00000000 | 25 | # DIS-NEXT: 30010 00000000 00000000 80000000 00000000 |
| 27 | # DIS-NEXT: 30020 00000000 00000000 00000000 00000000 | 26 | # DIS-NEXT: 30020 00000000 00000000 ffffffff ffff9004 |
| 28 | # DIS-NEXT: 30030 00000000 00000000 00000000 00000001 | 27 | # DIS-NEXT: 30030 00000000 00000000 00000000 00000000 |
| 29 | # DIS-NEXT: 30040 00000000 00000000 00000000 00000001 | 28 | # DIS-NEXT: 30040 00000000 00000001 00000000 00000000 |
| 30 | # DIS-NEXT: 30050 ffffffff ffff8004 ffffffff ffff9004 | 29 | # DIS-NEXT: 30050 00000000 00000001 ffffffff ffff8004 |
| 31 | 30 | ||
| 32 | # DIS: 0000000000000000 l .tdata 00000000 loc | 31 | # DIS: 0000000000000000 l .tdata 00000000 loc |
| 33 | # DIS: 0000000000000004 g .tdata 00000000 bar | 32 | # DIS: 0000000000000004 g .tdata 00000000 bar |
| 34 | # DIS: 0000000000000000 g *UND* 00000000 foo | 33 | # DIS: 0000000000000000 g *UND* 00000000 foo |
| 35 | 34 | ||
| 36 | # CHECK: Relocations [ | 35 | # CHECK: Relocations [ |
| 37 | # CHECK-NEXT: Section (7) .rela.dyn { | 36 | # CHECK-NEXT: Section (7) .rel.dyn { |
| 38 | # CHECK-NEXT: 0x30020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 | 37 | # CHECK-NEXT: 0x30020 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 |
| 39 | # CHECK-NEXT: 0x30028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 | 38 | # CHECK-NEXT: 0x30030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 |
| 40 | # CHECK-NEXT: 0x30030 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 | 39 | # CHECK-NEXT: 0x30038 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 |
| 41 | # CHECK-NEXT: } | 40 | # CHECK-NEXT: } |
| 42 | # CHECK-NEXT: ] | 41 | # CHECK-NEXT: ] |
| 43 | # CHECK-NEXT: Primary GOT { | 42 | # CHECK-NEXT: Primary GOT { |
| ... | @@ -49,31 +48,31 @@ | ... | @@ -49,31 +48,31 @@ |
| 49 | # CHECK-NEXT: Global entries [ | 48 | # CHECK-NEXT: Global entries [ |
| 50 | # CHECK-NEXT: ] | 49 | # CHECK-NEXT: ] |
| 51 | # CHECK-NEXT: Number of TLS and multi-GOT entries: 8 | 50 | # CHECK-NEXT: Number of TLS and multi-GOT entries: 8 |
| 52 | # ^-- -32736 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 foo | 51 | # ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 foo |
| 53 | # ^-- -32728 R_MIPS_TLS_DTPREL64 foo | 52 | # ^-- -32728 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar |
| 54 | # ^-- -32720 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 foo | 53 | # ^-- -32720 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 foo |
| 55 | # ^-- -32712 R_MIPS_TLS_LDM 1 loc | 54 | # ^-- -32712 R_MIPS_TLS_DTPREL64 foo |
| 56 | # ^-- -32704 0 loc | 55 | # ^-- -32704 R_MIPS_TLS_LDM 1 loc |
| 57 | # ^-- -32696 R_MIPS_TLS_GD 1 bar | 56 | # ^-- -32696 0 loc |
| 58 | # ^-- -32688 VA - 0x8000 bar | 57 | # ^-- -32688 R_MIPS_TLS_GD 1 bar |
| 59 | # ^-- -32680 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar | 58 | # ^-- -32680 VA - 0x8000 bar |
| 60 | 59 | ||
| 61 | # DIS-SO: Contents of section .got: | 60 | # DIS-SO: Contents of section .got: |
| 62 | # DIS-SO-NEXT: 20000 00000000 00000000 80000000 00000000 | 61 | # DIS-SO-NEXT: 20000 00000000 00000000 80000000 00000000 |
| 63 | # DIS-SO-NEXT: 20010 00000000 00000000 00000000 00000000 | 62 | # DIS-SO-NEXT: 20010 00000000 00000000 00000000 00000004 |
| 64 | # DIS-SO-NEXT: 20020 00000000 00000000 00000000 00000000 | 63 | # DIS-SO-NEXT: 20020 00000000 00000000 00000000 00000000 |
| 65 | # DIS-SO-NEXT: 20030 00000000 00000000 00000000 00000000 | 64 | # DIS-SO-NEXT: 20030 00000000 00000000 00000000 00000000 |
| 66 | # DIS-SO-NEXT: 20040 00000000 00000000 00000000 00000000 | 65 | # DIS-SO-NEXT: 20040 00000000 00000000 00000000 00000000 |
| 67 | 66 | ||
| 68 | # SO: Relocations [ | 67 | # SO: Relocations [ |
| 69 | # SO-NEXT: Section (7) .rela.dyn { | 68 | # SO-NEXT: Section (7) .rel.dyn { |
| 70 | # SO-NEXT: 0x20028 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0 | 69 | # SO-NEXT: 0x20030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0 |
| 71 | # SO-NEXT: 0x20038 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE bar 0x0 | 70 | # SO-NEXT: 0x20018 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0 |
| 72 | # SO-NEXT: 0x20040 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0 | 71 | # SO-NEXT: 0x20040 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE bar 0x0 |
| 73 | # SO-NEXT: 0x20048 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0 | 72 | # SO-NEXT: 0x20048 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0 |
| 74 | # SO-NEXT: 0x20010 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 | 73 | # SO-NEXT: 0x20010 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 |
| 75 | # SO-NEXT: 0x20018 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 | 74 | # SO-NEXT: 0x20020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 |
| 76 | # SO-NEXT: 0x20020 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 | 75 | # SO-NEXT: 0x20028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0 |
| 77 | # SO-NEXT: } | 76 | # SO-NEXT: } |
| 78 | # SO-NEXT: ] | 77 | # SO-NEXT: ] |
| 79 | # SO-NEXT: Primary GOT { | 78 | # SO-NEXT: Primary GOT { |
| ... | @@ -85,14 +84,14 @@ | ... | @@ -85,14 +84,14 @@ |
| 85 | # SO-NEXT: Global entries [ | 84 | # SO-NEXT: Global entries [ |
| 86 | # SO-NEXT: ] | 85 | # SO-NEXT: ] |
| 87 | # SO-NEXT: Number of TLS and multi-GOT entries: 8 | 86 | # SO-NEXT: Number of TLS and multi-GOT entries: 8 |
| 88 | # ^-- -32736 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 foo | 87 | # ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 foo |
| 89 | # ^-- -32728 R_MIPS_TLS_DTPREL64 foo | 88 | # ^-- -32728 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 bar |
| 90 | # ^-- -32720 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 foo | 89 | # ^-- -32720 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 foo |
| 91 | # ^-- -32712 R_MIPS_TLS_LDM R_MIPS_TLS_DTPMOD64 loc | 90 | # ^-- -32712 R_MIPS_TLS_DTPREL64 foo |
| 92 | # ^-- -32704 0 loc | 91 | # ^-- -32704 R_MIPS_TLS_LDM R_MIPS_TLS_DTPMOD64 loc |
| 93 | # ^-- -32696 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 bar | 92 | # ^-- -32696 0 loc |
| 94 | # ^-- -32688 R_MIPS_TLS_DTPREL64 bar | 93 | # ^-- -32688 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 bar |
| 95 | # ^-- -32680 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 bar | 94 | # ^-- -32680 R_MIPS_TLS_DTPREL64 bar |
| 96 | 95 | ||
| 97 | .text | 96 | .text |
| 98 | .global __start | 97 | .global __start |
deps/lld/test/ELF/mips-tls-hilo.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check MIPS R_MIPS_TLS_DTPREL_HI16/LO16 and R_MIPS_TLS_TPREL_HI16/LO16 | 2 | # Check MIPS R_MIPS_TLS_DTPREL_HI16/LO16 and R_MIPS_TLS_TPREL_HI16/LO16 |
| 2 | # relocations handling. | 3 | # relocations handling. |
| 3 | 4 | ||
| ... | @@ -9,8 +10,6 @@ | ... | @@ -9,8 +10,6 @@ |
| 9 | # RUN: ld.lld %t.o -shared -o %t.so | 10 | # RUN: ld.lld %t.o -shared -o %t.so |
| 10 | # 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 |
| 11 | 12 | ||
| 12 | # REQUIRES: mips | ||
| 13 | |||
| 14 | # DIS: __start: | 13 | # DIS: __start: |
| 15 | # DIS-NEXT: 20000: 24 62 00 00 addiu $2, $3, 0 | 14 | # DIS-NEXT: 20000: 24 62 00 00 addiu $2, $3, 0 |
| 16 | # %hi(loc0 - .tdata - 0x8000) --^ | 15 | # %hi(loc0 - .tdata - 0x8000) --^ |
deps/lld/test/ELF/mips-tls-static-64.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check handling TLS related relocations and symbols when linking | 2 | # Check handling TLS related relocations and symbols when linking |
| 2 | # a 64-bit static executable. | 3 | # a 64-bit static executable. |
| 3 | 4 | ||
| ... | @@ -5,8 +6,6 @@ | ... | @@ -5,8 +6,6 @@ |
| 5 | # RUN: ld.lld -static %t -o %t.exe | 6 | # RUN: ld.lld -static %t -o %t.exe |
| 6 | # RUN: llvm-objdump -s -t %t.exe | FileCheck %s | 7 | # RUN: llvm-objdump -s -t %t.exe | FileCheck %s |
| 7 | 8 | ||
| 8 | # REQUIRES: mips | ||
| 9 | |||
| 10 | # CHECK: Contents of section .data: | 9 | # CHECK: Contents of section .data: |
| 11 | # CHECK-NEXT: 30000 00020004 ffffffff ffff8004 ffffffff | 10 | # CHECK-NEXT: 30000 00020004 ffffffff ffff8004 ffffffff |
| 12 | # CHECK-NEXT: 30010 ffff9004 | 11 | # CHECK-NEXT: 30010 ffff9004 |
deps/lld/test/ELF/mips-tls-static.s+3-4| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check handling TLS related relocations and symbols when linking | 2 | # Check handling TLS related relocations and symbols when linking |
| 2 | # a static executable. | 3 | # a static executable. |
| 3 | 4 | ||
| ... | @@ -5,13 +6,11 @@ | ... | @@ -5,13 +6,11 @@ |
| 5 | # RUN: ld.lld -static %t -o %t.exe | 6 | # RUN: ld.lld -static %t -o %t.exe |
| 6 | # RUN: llvm-objdump -s -t %t.exe | FileCheck %s | 7 | # RUN: llvm-objdump -s -t %t.exe | FileCheck %s |
| 7 | 8 | ||
| 8 | # REQUIRES: mips | ||
| 9 | |||
| 10 | # CHECK: Contents of section .data: | 9 | # CHECK: Contents of section .data: |
| 11 | # CHECK-NEXT: 30000 0002000c ffff8004 ffff9004 | 10 | # CHECK-NEXT: 30000 0002000c ffff8004 ffff9004 |
| 12 | # CHECK: Contents of section .got: | 11 | # CHECK: Contents of section .got: |
| 13 | # CHECK-NEXT: 30010 00000000 80000000 00000001 ffff8000 | 12 | # CHECK-NEXT: 30010 00000000 80000000 ffff9000 00000001 |
| 14 | # CHECK-NEXT: 30020 00000001 00000000 ffff9000 | 13 | # CHECK-NEXT: 30020 ffff8000 00000001 00000000 |
| 15 | # | 14 | # |
| 16 | # CHECK: SYMBOL TABLE: | 15 | # CHECK: SYMBOL TABLE: |
| 17 | # CHECK: 0002000c .text 00000000 __tls_get_addr | 16 | # CHECK: 0002000c .text 00000000 __tls_get_addr |
deps/lld/test/ELF/mips-tls.s+36-37| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check MIPS TLS relocations handling. | 2 | # Check MIPS TLS relocations handling. |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ | 4 | # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ |
| ... | @@ -13,19 +14,17 @@ | ... | @@ -13,19 +14,17 @@ |
| 13 | # RUN: llvm-objdump -d -s -t %t-out.so | FileCheck -check-prefix=DIS-SO %s | 14 | # RUN: llvm-objdump -d -s -t %t-out.so | FileCheck -check-prefix=DIS-SO %s |
| 14 | # 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 |
| 15 | 16 | ||
| 16 | # REQUIRES: mips | ||
| 17 | |||
| 18 | # DIS: __start: | 17 | # DIS: __start: |
| 19 | # DIS-NEXT: 20000: 24 62 80 18 addiu $2, $3, -32744 | 18 | # DIS-NEXT: 20000: 24 62 80 20 addiu $2, $3, -32736 |
| 20 | # DIS-NEXT: 20004: 24 62 80 20 addiu $2, $3, -32736 | 19 | # DIS-NEXT: 20004: 24 62 80 18 addiu $2, $3, -32744 |
| 21 | # DIS-NEXT: 20008: 24 62 80 24 addiu $2, $3, -32732 | 20 | # DIS-NEXT: 20008: 24 62 80 28 addiu $2, $3, -32728 |
| 22 | # DIS-NEXT: 2000c: 24 62 80 2c addiu $2, $3, -32724 | 21 | # DIS-NEXT: 2000c: 24 62 80 30 addiu $2, $3, -32720 |
| 23 | # DIS-NEXT: 20010: 24 62 80 34 addiu $2, $3, -32716 | 22 | # DIS-NEXT: 20010: 24 62 80 1c addiu $2, $3, -32740 |
| 24 | 23 | ||
| 25 | # DIS: Contents of section .got: | 24 | # DIS: Contents of section .got: |
| 26 | # DIS-NEXT: 30010 00000000 80000000 00000000 00000000 | 25 | # DIS-NEXT: 30010 00000000 80000000 00000000 ffff9004 |
| 27 | # DIS-NEXT: 30020 00000000 00000001 00000000 00000001 | 26 | # DIS-NEXT: 30020 00000000 00000000 00000001 00000000 |
| 28 | # DIS-NEXT: 30030 ffff8004 ffff9004 | 27 | # DIS-NEXT: 30030 00000001 ffff8004 |
| 29 | 28 | ||
| 30 | # DIS: 00000000 l .tdata 00000000 loc | 29 | # DIS: 00000000 l .tdata 00000000 loc |
| 31 | # DIS: 00000004 g .tdata 00000000 bar | 30 | # DIS: 00000004 g .tdata 00000000 bar |
| ... | @@ -33,9 +32,9 @@ | ... | @@ -33,9 +32,9 @@ |
| 33 | 32 | ||
| 34 | # CHECK: Relocations [ | 33 | # CHECK: Relocations [ |
| 35 | # CHECK-NEXT: Section (7) .rel.dyn { | 34 | # CHECK-NEXT: Section (7) .rel.dyn { |
| 36 | # CHECK-NEXT: 0x30018 R_MIPS_TLS_DTPMOD32 foo 0x0 | 35 | # CHECK-NEXT: 0x30018 R_MIPS_TLS_TPREL32 foo 0x0 |
| 37 | # CHECK-NEXT: 0x3001C R_MIPS_TLS_DTPREL32 foo 0x0 | 36 | # CHECK-NEXT: 0x30020 R_MIPS_TLS_DTPMOD32 foo 0x0 |
| 38 | # CHECK-NEXT: 0x30020 R_MIPS_TLS_TPREL32 foo 0x0 | 37 | # CHECK-NEXT: 0x30024 R_MIPS_TLS_DTPREL32 foo 0x0 |
| 39 | # CHECK-NEXT: } | 38 | # CHECK-NEXT: } |
| 40 | # CHECK-NEXT: ] | 39 | # CHECK-NEXT: ] |
| 41 | # CHECK-NEXT: Primary GOT { | 40 | # CHECK-NEXT: Primary GOT { |
| ... | @@ -47,29 +46,29 @@ | ... | @@ -47,29 +46,29 @@ |
| 47 | # CHECK-NEXT: Global entries [ | 46 | # CHECK-NEXT: Global entries [ |
| 48 | # CHECK-NEXT: ] | 47 | # CHECK-NEXT: ] |
| 49 | # CHECK-NEXT: Number of TLS and multi-GOT entries: 8 | 48 | # CHECK-NEXT: Number of TLS and multi-GOT entries: 8 |
| 50 | # ^-- -32744 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 foo | 49 | # ^-- -32744 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 foo |
| 51 | # ^-- -32740 R_MIPS_TLS_DTPREL32 foo | 50 | # ^-- -32740 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar |
| 52 | # ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 foo | 51 | # ^-- -32736 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 foo |
| 53 | # ^-- -32732 R_MIPS_TLS_LDM 1 loc | 52 | # ^-- -32732 R_MIPS_TLS_DTPREL32 foo |
| 54 | # ^-- -32728 0 loc | 53 | # ^-- -32728 R_MIPS_TLS_LDM 1 loc |
| 55 | # ^-- -32724 R_MIPS_TLS_GD 1 bar | 54 | # ^-- -32724 0 loc |
| 56 | # ^-- -32720 VA - 0x8000 bar | 55 | # ^-- -32720 R_MIPS_TLS_GD 1 bar |
| 57 | # ^-- -32716 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar | 56 | # ^-- -32716 VA - 0x8000 bar |
| 58 | 57 | ||
| 59 | # DIS-SO: Contents of section .got: | 58 | # DIS-SO: Contents of section .got: |
| 60 | # DIS-SO-NEXT: 20000 00000000 80000000 00000000 00000000 | 59 | # DIS-SO-NEXT: 20000 00000000 80000000 00000000 00000004 |
| 61 | # DIS-SO-NEXT: 20010 00000000 00000000 00000000 00000000 | 60 | # DIS-SO-NEXT: 20010 00000000 00000000 00000000 00000000 |
| 62 | # DIS-SO-NEXT: 20020 00000000 00000000 | 61 | # DIS-SO-NEXT: 20020 00000000 00000000 |
| 63 | 62 | ||
| 64 | # SO: Relocations [ | 63 | # SO: Relocations [ |
| 65 | # SO-NEXT: Section (7) .rel.dyn { | 64 | # SO-NEXT: Section (7) .rel.dyn { |
| 66 | # SO-NEXT: 0x20014 R_MIPS_TLS_DTPMOD32 - 0x0 | 65 | # SO-NEXT: 0x20018 R_MIPS_TLS_DTPMOD32 - 0x0 |
| 67 | # SO-NEXT: 0x2001C R_MIPS_TLS_DTPMOD32 bar 0x0 | 66 | # SO-NEXT: 0x2000C R_MIPS_TLS_TPREL32 bar 0x0 |
| 68 | # SO-NEXT: 0x20020 R_MIPS_TLS_DTPREL32 bar 0x0 | 67 | # SO-NEXT: 0x20020 R_MIPS_TLS_DTPMOD32 bar 0x0 |
| 69 | # SO-NEXT: 0x20024 R_MIPS_TLS_TPREL32 bar 0x0 | 68 | # SO-NEXT: 0x20024 R_MIPS_TLS_DTPREL32 bar 0x0 |
| 70 | # SO-NEXT: 0x20008 R_MIPS_TLS_DTPMOD32 foo 0x0 | 69 | # SO-NEXT: 0x20008 R_MIPS_TLS_TPREL32 foo 0x0 |
| 71 | # SO-NEXT: 0x2000C R_MIPS_TLS_DTPREL32 foo 0x0 | 70 | # SO-NEXT: 0x20010 R_MIPS_TLS_DTPMOD32 foo 0x0 |
| 72 | # SO-NEXT: 0x20010 R_MIPS_TLS_TPREL32 foo 0x0 | 71 | # SO-NEXT: 0x20014 R_MIPS_TLS_DTPREL32 foo 0x0 |
| 73 | # SO-NEXT: } | 72 | # SO-NEXT: } |
| 74 | # SO-NEXT: ] | 73 | # SO-NEXT: ] |
| 75 | # SO-NEXT: Primary GOT { | 74 | # SO-NEXT: Primary GOT { |
| ... | @@ -81,14 +80,14 @@ | ... | @@ -81,14 +80,14 @@ |
| 81 | # SO-NEXT: Global entries [ | 80 | # SO-NEXT: Global entries [ |
| 82 | # SO-NEXT: ] | 81 | # SO-NEXT: ] |
| 83 | # SO-NEXT: Number of TLS and multi-GOT entries: 8 | 82 | # SO-NEXT: Number of TLS and multi-GOT entries: 8 |
| 84 | # ^-- -32744 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 foo | 83 | # ^-- -32744 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 foo |
| 85 | # ^-- -32740 R_MIPS_TLS_DTPREL32 foo | 84 | # ^-- -32740 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 bar |
| 86 | # ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 foo | 85 | # ^-- -32736 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 foo |
| 87 | # ^-- -32732 R_MIPS_TLS_LDM R_MIPS_TLS_DTPMOD32 loc | 86 | # ^-- -32732 R_MIPS_TLS_DTPREL32 foo |
| 88 | # ^-- -32728 0 loc | 87 | # ^-- -32728 R_MIPS_TLS_LDM R_MIPS_TLS_DTPMOD32 loc |
| 89 | # ^-- -32724 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 bar | 88 | # ^-- -32724 0 loc |
| 90 | # ^-- -32720 R_MIPS_TLS_DTPREL32 bar | 89 | # ^-- -32720 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 bar |
| 91 | # ^-- -32716 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 bar | 90 | # ^-- -32716 R_MIPS_TLS_DTPREL32 bar |
| 92 | 91 | ||
| 93 | .text | 92 | .text |
| 94 | .global __start | 93 | .global __start |
deps/lld/test/ELF/mips-xgot-order.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: mips | ||
| 1 | # Check that GOT entries accessed via 16-bit indexing are allocated | 2 | # Check that GOT entries accessed via 16-bit indexing are allocated |
| 2 | # in the beginning of the GOT. | 3 | # in the beginning of the GOT. |
| 3 | 4 | ||
| ... | @@ -5,8 +6,6 @@ | ... | @@ -5,8 +6,6 @@ |
| 5 | # RUN: ld.lld %t.o -o %t.exe | 6 | # RUN: ld.lld %t.o -o %t.exe |
| 6 | # RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s | 7 | # RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s |
| 7 | 8 | ||
| 8 | # REQUIRES: mips | ||
| 9 | |||
| 10 | # CHECK: Disassembly of section .text: | 9 | # CHECK: Disassembly of section .text: |
| 11 | # CHECK-NEXT: __start: | 10 | # CHECK-NEXT: __start: |
| 12 | # CHECK-NEXT: 20000: 3c 02 00 00 lui $2, 0 | 11 | # CHECK-NEXT: 20000: 3c 02 00 00 lui $2, 0 |
deps/lld/test/ELF/mips64-eh-abs-reloc.s+3-3| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # Having an R_MIPS_64 relocation in eh_frame would previously crash LLD | ||
| 2 | # REQUIRES: mips | 1 | # REQUIRES: mips |
| 2 | # Having an R_MIPS_64 relocation in eh_frame would previously crash LLD | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o | 3 | # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o |
| 4 | # RUN: llvm-readobj -r %t.o | FileCheck %s -check-prefix OBJ | 4 | # RUN: llvm-readobj -r %t.o | FileCheck %s -check-prefix OBJ |
| 5 | # RUN: ld.lld --eh-frame-hdr -shared -z notext -o %t.so %t.o | 5 | # RUN: ld.lld --eh-frame-hdr -shared -z notext -o %t.so %t.o |
| ... | @@ -20,8 +20,8 @@ | ... | @@ -20,8 +20,8 @@ |
| 20 | # OBJ-NEXT: } | 20 | # OBJ-NEXT: } |
| 21 | 21 | ||
| 22 | # PIC-RELOCS: Relocations [ | 22 | # PIC-RELOCS: Relocations [ |
| 23 | # PIC-RELOCS-NEXT: Section (7) .rela.dyn { | 23 | # PIC-RELOCS-NEXT: Section (7) .rel.dyn { |
| 24 | # PIC-RELOCS-NEXT: {{0x.+}} R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x10000 | 24 | # PIC-RELOCS-NEXT: {{0x.+}} R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x0 |
| 25 | # PIC-RELOCS-NEXT: } | 25 | # PIC-RELOCS-NEXT: } |
| 26 | # PIC-RELOCS-NEXT:] | 26 | # PIC-RELOCS-NEXT:] |
| 27 | 27 |
deps/lld/test/ELF/multiple-cu.s created+38| ... | @@ -0,0 +1,38 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/multiple-cu.s -o %t2.o | ||
| 4 | # RUN: ld.lld -r -o %t.o %t1.o %t2.o | ||
| 5 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: error: undefined symbol: foo | ||
| 8 | # CHECK-NEXT: referenced by test1.c:2 | ||
| 9 | |||
| 10 | # CHECK: error: undefined symbol: bar | ||
| 11 | # CHECK-NEXT: referenced by test2.c:2 | ||
| 12 | |||
| 13 | .globl _start | ||
| 14 | _start: | ||
| 15 | .file 1 "test1.c" | ||
| 16 | .loc 1 2 0 | ||
| 17 | jmp foo | ||
| 18 | |||
| 19 | .section .debug_abbrev,"",@progbits | ||
| 20 | .byte 1 # Abbreviation Code | ||
| 21 | .byte 17 # DW_TAG_compile_unit | ||
| 22 | .byte 0 # DW_CHILDREN_no | ||
| 23 | .byte 16 # DW_AT_stmt_list | ||
| 24 | .byte 23 # DW_FORM_sec_offset | ||
| 25 | .byte 0 # EOM(1) | ||
| 26 | .byte 0 # EOM(2) | ||
| 27 | .byte 0 # EOM(3) | ||
| 28 | |||
| 29 | .section .debug_info,"",@progbits | ||
| 30 | .long .Lend0 - .Lbegin0 # Length of Unit | ||
| 31 | .Lbegin0: | ||
| 32 | .short 4 # DWARF version number | ||
| 33 | .long .debug_abbrev # Offset Into Abbrev. Section | ||
| 34 | .byte 8 # Address Size (in bytes) | ||
| 35 | .byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit | ||
| 36 | .long .debug_line # DW_AT_stmt_list | ||
| 37 | .Lend0: | ||
| 38 | .section .debug_line,"",@progbits | ||
deps/lld/test/ELF/new-dtags.test+5-1| ... | @@ -1,8 +1,12 @@ | ... | @@ -1,8 +1,12 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o -rpath=/somepath -shared --disable-new-dtags -o %t | 3 | // RUN: ld.lld %t.o -rpath=/somepath -shared --disable-new-dtags -o %t |
| 4 | // RUN: ld.lld %t.o -rpath=/somepath -shared --enable-new-dtags -o %t2 | ||
| 5 | // RUN: llvm-readobj --dynamic-table %t | FileCheck --check-prefix=DISABLE %s | 4 | // RUN: llvm-readobj --dynamic-table %t | FileCheck --check-prefix=DISABLE %s |
| 5 | |||
| 6 | // RUN: ld.lld %t.o -rpath=/somepath -shared --enable-new-dtags -o %t2 | ||
| 7 | // RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=ENABLE %s | ||
| 8 | |||
| 9 | // RUN: ld.lld %t.o -rpath=/somepath -shared --disable-new-dtags --enable-new-dtags -o %t2 | ||
| 6 | // RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=ENABLE %s | 10 | // RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=ENABLE %s |
| 7 | 11 | ||
| 8 | // DISABLE: DynamicSection [ | 12 | // DISABLE: DynamicSection [ |
deps/lld/test/ELF/no-augmentation.s+2-3| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | // RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o | ||
| 2 | // RUN: ld.lld --eh-frame-hdr %t.o -o %t | FileCheck -allow-empty %s | ||
| 3 | |||
| 4 | // REQUIRES: mips | 1 | // REQUIRES: mips |
| 2 | // RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o | ||
| 3 | // RUN: ld.lld --eh-frame-hdr %t.o -o /dev/null | FileCheck -allow-empty %s | ||
| 5 | 4 | ||
| 6 | // CHECK-NOT: corrupted or unsupported CIE information | 5 | // CHECK-NOT: corrupted or unsupported CIE information |
| 7 | // CHECK-NOT: corrupted CIE | 6 | // CHECK-NOT: corrupted CIE |
deps/lld/test/ELF/no-dynamic-linker.s deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %tso.o | ||
| 3 | # RUN: ld.lld -shared %tso.o -o %t.so | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 5 | |||
| 6 | # RUN: ld.lld -dynamic-linker foo --no-dynamic-linker %t.o %t.so -o %t | ||
| 7 | # RUN: llvm-readobj --program-headers %t | FileCheck %s --check-prefix=NODL | ||
| 8 | # NODL-NOT: PT_INTERP | ||
| 9 | |||
| 10 | # RUN: ld.lld --no-dynamic-linker -dynamic-linker foo %t.o %t.so -o %t | ||
| 11 | # RUN: llvm-readobj --program-headers %t | FileCheck %s --check-prefix=WITHDL | ||
| 12 | # WITHDL: PT_INTERP | ||
deps/lld/test/ELF/no-inhibit-exec.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | # RUN: not ld.lld %t -o %t2 | 3 | # RUN: not ld.lld %t -o %t2 |
| 3 | # RUN: ld.lld %t --noinhibit-exec -o %t2 | 4 | # RUN: ld.lld %t --noinhibit-exec -o %t2 |
| 4 | # RUN: llvm-objdump -d %t2 | FileCheck %s | 5 | # RUN: llvm-objdump -d %t2 | FileCheck %s |
| 5 | # RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=RELOC | 6 | # RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=RELOC |
| 6 | # REQUIRES: x86 | ||
| 7 | 7 | ||
| 8 | # CHECK: Disassembly of section .text: | 8 | # CHECK: Disassembly of section .text: |
| 9 | # CHECK-NEXT: _start | 9 | # CHECK-NEXT: _start |
deps/lld/test/ELF/no-line-parser-errors-if-empty-section.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # LLD uses the debug data to get information for error messages, if possible. | ||
| 4 | # However, if the debug line section is empty, we should not attempt to parse | ||
| 5 | # it, as that would result in errors from the parser. | ||
| 6 | |||
| 7 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 8 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 9 | |||
| 10 | # CHECK-NOT: warning: | ||
| 11 | # CHECK-NOT: error: | ||
| 12 | # CHECK: error: undefined symbol: undefined | ||
| 13 | # CHECK-NEXT: {{.*}}.o:(.text+0x1) | ||
| 14 | # CHECK-NOT: warning: | ||
| 15 | # CHECK-NOT: error: | ||
| 16 | |||
| 17 | .globl _start | ||
| 18 | _start: | ||
| 19 | callq undefined | ||
| 20 | |||
| 21 | .section .debug_line,"",@progbits | ||
deps/lld/test/ELF/no-line-parser-errors-if-no-section.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # LLD uses the debug data to get information for error messages, if possible. | ||
| 4 | # However, if there is no debug line section, we should not attempt to parse | ||
| 5 | # it, as that would result in errors from the parser. | ||
| 6 | |||
| 7 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 8 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 9 | |||
| 10 | # CHECK-NOT: warning: | ||
| 11 | # CHECK-NOT: error: | ||
| 12 | # CHECK: error: undefined symbol: undefined | ||
| 13 | # CHECK-NEXT: {{.*}}.o:(.text+0x1) | ||
| 14 | # CHECK-NOT: warning: | ||
| 15 | # CHECK-NOT: error: | ||
| 16 | |||
| 17 | .globl _start | ||
| 18 | _start: | ||
| 19 | callq undefined | ||
deps/lld/test/ELF/no-obj.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: llvm-ar rcs %t.a %t.o | 3 | // RUN: llvm-ar rcs %t.a %t.o |
| 4 | // RUN: not ld.lld -o %t2 -u _start %t.a 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld -o /dev/null -u _start %t.a 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | // CHECK: target emulation unknown: -m or at least one .o file required | 6 | // CHECK: target emulation unknown: -m or at least one .o file required |
| 7 | 7 |
deps/lld/test/ELF/no-symtab.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld %t.o %p/Inputs/no-symtab.o -o %t | 3 | // RUN: ld.lld %t.o %p/Inputs/no-symtab.o -o /dev/null |
| 4 | .global _start | 4 | .global _start |
| 5 | _start: | 5 | _start: |
deps/lld/test/ELF/no-undefined.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | # RUN: not ld.lld --no-undefined -shared %t -o %t.so | 3 | # RUN: not ld.lld --no-undefined -shared %t -o /dev/null |
| 4 | # RUN: ld.lld -shared %t -o %t1.so | 4 | # RUN: ld.lld -shared %t -o /dev/null |
| 5 | 5 | ||
| 6 | .globl _shared | 6 | .globl _shared |
| 7 | _shared: | 7 | _shared: |
deps/lld/test/ELF/non-abs-reloc.s+14-4| ... | @@ -1,11 +1,21 @@ | ... | @@ -1,11 +1,21 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | // RUN: ld.lld %t.o -o %t 2>&1 | FileCheck %s |
| 4 | // CHECK: {{.*}}:(.dummy+0x0): has non-ABS relocation R_X86_64_GOTPCREL against symbol 'foo' | 4 | // CHECK: (.nonalloc+0x1): has non-ABS relocation R_X86_64_PC32 against symbol '_start' |
| 5 | // CHECK: (.nonalloc+0x6): has non-ABS relocation R_X86_64_PC32 against symbol '_start' | ||
| 6 | |||
| 7 | // RUN: llvm-objdump -D %t | FileCheck --check-prefix=DISASM %s | ||
| 8 | // DISASM: Disassembly of section .nonalloc: | ||
| 9 | // DISASM-NEXT: .nonalloc: | ||
| 10 | // DISASM-NEXT: 0: {{.*}} callq {{.*}} <_start> | ||
| 11 | // DISASM-NEXT: 5: {{.*}} callq {{.*}} <_start> | ||
| 5 | 12 | ||
| 6 | .globl _start | 13 | .globl _start |
| 7 | _start: | 14 | _start: |
| 8 | nop | 15 | nop |
| 9 | 16 | ||
| 10 | .section .dummy | 17 | .section .nonalloc |
| 11 | .long foo@gotpcrel | 18 | .byte 0xe8 |
| 19 | .long _start - . - 4 | ||
| 20 | .byte 0xe8 | ||
| 21 | .long _start - . - 4 |
deps/lld/test/ELF/non-alloc-link-order-gc.s created+34| ... | @@ -0,0 +1,34 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: ld.lld %t.o -o %t1 --gc-sections | ||
| 4 | # RUN: llvm-objdump -section-headers -D %t1 | FileCheck %s | ||
| 5 | |||
| 6 | ## Check that we are able to GC non-allocatable metadata sections without crash. | ||
| 7 | |||
| 8 | # CHECK: Disassembly of section .stack_sizes: | ||
| 9 | # CHECK-NEXT: .stack_sizes: | ||
| 10 | # CHECK-NEXT: 01 | ||
| 11 | |||
| 12 | # CHECK: Name Size | ||
| 13 | # CHECK: .stack_sizes 00000001 | ||
| 14 | |||
| 15 | .section .text.live,"ax",@progbits | ||
| 16 | .globl live | ||
| 17 | live: | ||
| 18 | nop | ||
| 19 | |||
| 20 | .section .stack_sizes,"o",@progbits,.text.live,unique,0 | ||
| 21 | .byte 1 | ||
| 22 | |||
| 23 | .section .text.dead,"ax",@progbits | ||
| 24 | .globl dead | ||
| 25 | dead: | ||
| 26 | nop | ||
| 27 | |||
| 28 | .section .stack_sizes,"o",@progbits,.text.dead,unique,1 | ||
| 29 | .byte 2 | ||
| 30 | |||
| 31 | .section .text.main,"ax",@progbits | ||
| 32 | .globl _start | ||
| 33 | _start: | ||
| 34 | callq live@PLT | ||
deps/lld/test/ELF/note-contiguous.s+27-9| ... | @@ -1,24 +1,42 @@ | ... | @@ -1,24 +1,42 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: echo "SECTIONS { \ | 3 | |
| 4 | // RUN: .note : { *(.note.a) *(.note.b) } \ | 4 | // RUN: ld.lld %t.o -o %t1 |
| 5 | // RUN: }" > %t.script | 5 | // RUN: llvm-readobj -program-headers %t1 | FileCheck %s |
| 6 | // RUN: ld.lld %t.o --script %t.script -o %t | ||
| 7 | // RUN: llvm-readobj -program-headers %t | FileCheck %s | ||
| 8 | 6 | ||
| 9 | // CHECK: Type: PT_NOTE | 7 | // CHECK: Type: PT_NOTE |
| 10 | // CHECK-NEXT: Offset: 0x1000 | 8 | // CHECK-NEXT: Offset: |
| 11 | // CHECK-NEXT: VirtualAddress: 0x0 | 9 | // CHECK-NEXT: VirtualAddress: |
| 12 | // CHECK-NEXT: PhysicalAddress: 0x0 | 10 | // CHECK-NEXT: PhysicalAddress: |
| 13 | // CHECK-NEXT: FileSize: 16 | 11 | // CHECK-NEXT: FileSize: 16 |
| 14 | // CHECK-NEXT: MemSize: 16 | 12 | // CHECK-NEXT: MemSize: 16 |
| 15 | // CHECK-NEXT: Flags [ | 13 | // CHECK-NEXT: Flags [ |
| 16 | // CHECK-NEXT: PF_R | 14 | // CHECK-NEXT: PF_R |
| 17 | // CHECK-NEXT: ] | 15 | // CHECK-NEXT: ] |
| 18 | // CHECK-NEXT: Alignment: 1 | 16 | // CHECK-NEXT: Alignment: 1 |
| 17 | // CHECK-NOT: Type: PT_NOTE | ||
| 18 | |||
| 19 | // RUN: echo "SECTIONS { .note : { *(.note.a) *(.note.b) } }" > %t.script | ||
| 20 | // RUN: ld.lld %t.o --script %t.script -o %t2 | ||
| 21 | // RUN: llvm-readobj -program-headers %t2 | FileCheck -check-prefix=SCRIPT %s | ||
| 22 | |||
| 23 | // SCRIPT: Type: PT_NOTE | ||
| 24 | // SCRIPT-NEXT: Offset: | ||
| 25 | // SCRIPT-NEXT: VirtualAddress: | ||
| 26 | // SCRIPT-NEXT: PhysicalAddress: | ||
| 27 | // SCRIPT-NEXT: FileSize: 16 | ||
| 28 | // SCRIPT-NEXT: MemSize: 16 | ||
| 29 | // SCRIPT-NEXT: Flags [ | ||
| 30 | // SCRIPT-NEXT: PF_R | ||
| 31 | // SCRIPT-NEXT: ] | ||
| 32 | // SCRIPT-NEXT: Alignment: 1 | ||
| 33 | // SCRIPT-NOT: Type: PT_NOTE | ||
| 19 | 34 | ||
| 20 | .section .note.a, "a", @note | 35 | .section .note.a, "a", @note |
| 21 | .quad 0 | 36 | .quad 0 |
| 22 | 37 | ||
| 38 | .section .foo, "a" | ||
| 39 | .quad 0 | ||
| 40 | |||
| 23 | .section .note.b, "a", @note | 41 | .section .note.b, "a", @note |
| 24 | .quad 0 | 42 | .quad 0 |
deps/lld/test/ELF/note-loadaddr.c deleted-35| ... | @@ -1,35 +0,0 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | // RUN: echo "SECTIONS { \ | ||
| 4 | // RUN: .note.a : AT(0x1000) { *(.note.a) } \ | ||
| 5 | // RUN: .note.b : AT(0x2000) { *(.note.b) } \ | ||
| 6 | // RUN: }" > %t.script | ||
| 7 | // RUN: ld.lld %t.o --script %t.script -o %t | ||
| 8 | // RUN: llvm-readobj -program-headers %t | FileCheck %s | ||
| 9 | |||
| 10 | // CHECK: Type: PT_NOTE | ||
| 11 | // CHECK-NEXT: Offset: 0x1000 | ||
| 12 | // CHECK-NEXT: VirtualAddress: 0x0 | ||
| 13 | // CHECK-NEXT: PhysicalAddress: 0x1000 | ||
| 14 | // CHECK-NEXT: FileSize: 8 | ||
| 15 | // CHECK-NEXT: MemSize: 8 | ||
| 16 | // CHECK-NEXT: Flags [ | ||
| 17 | // CHECK-NEXT: PF_R | ||
| 18 | // CHECK-NEXT: ] | ||
| 19 | // CHECK-NEXT: Alignment: 1 | ||
| 20 | // CHECK: Type: PT_NOTE | ||
| 21 | // CHECK-NEXT: Offset: 0x1008 | ||
| 22 | // CHECK-NEXT: VirtualAddress: 0x8 | ||
| 23 | // CHECK-NEXT: PhysicalAddress: 0x2000 | ||
| 24 | // CHECK-NEXT: FileSize: 8 | ||
| 25 | // CHECK-NEXT: MemSize: 8 | ||
| 26 | // CHECK-NEXT: Flags [ | ||
| 27 | // CHECK-NEXT: PF_R | ||
| 28 | // CHECK-NEXT: ] | ||
| 29 | // CHECK-NEXT: Alignment: 1 | ||
| 30 | |||
| 31 | .section .note.a, "a", @note | ||
| 32 | .quad 0 | ||
| 33 | |||
| 34 | .section .note.b, "a", @note | ||
| 35 | .quad 0 | ||
deps/lld/test/ELF/note-loadaddr.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: echo "SECTIONS { \ | ||
| 4 | // RUN: .note.a : AT(0x1000) { *(.note.a) } \ | ||
| 5 | // RUN: .note.b : AT(0x2000) { *(.note.b) } \ | ||
| 6 | // RUN: }" > %t.script | ||
| 7 | // RUN: ld.lld %t.o --script %t.script -o %t | ||
| 8 | // RUN: llvm-readobj -program-headers %t | FileCheck %s | ||
| 9 | |||
| 10 | // CHECK: Type: PT_NOTE | ||
| 11 | // CHECK-NEXT: Offset: 0x1000 | ||
| 12 | // CHECK-NEXT: VirtualAddress: 0x0 | ||
| 13 | // CHECK-NEXT: PhysicalAddress: 0x1000 | ||
| 14 | // CHECK-NEXT: FileSize: 8 | ||
| 15 | // CHECK-NEXT: MemSize: 8 | ||
| 16 | // CHECK-NEXT: Flags [ | ||
| 17 | // CHECK-NEXT: PF_R | ||
| 18 | // CHECK-NEXT: ] | ||
| 19 | // CHECK-NEXT: Alignment: 1 | ||
| 20 | // CHECK: Type: PT_NOTE | ||
| 21 | // CHECK-NEXT: Offset: 0x1008 | ||
| 22 | // CHECK-NEXT: VirtualAddress: 0x8 | ||
| 23 | // CHECK-NEXT: PhysicalAddress: 0x2000 | ||
| 24 | // CHECK-NEXT: FileSize: 8 | ||
| 25 | // CHECK-NEXT: MemSize: 8 | ||
| 26 | // CHECK-NEXT: Flags [ | ||
| 27 | // CHECK-NEXT: PF_R | ||
| 28 | // CHECK-NEXT: ] | ||
| 29 | // CHECK-NEXT: Alignment: 1 | ||
| 30 | |||
| 31 | .section .note.a, "a", @note | ||
| 32 | .quad 0 | ||
| 33 | |||
| 34 | .section .note.b, "a", @note | ||
| 35 | .quad 0 | ||
deps/lld/test/ELF/note-noalloc.s created+38| ... | @@ -0,0 +1,38 @@ | ||
| 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 -shared | ||
| 4 | // RUN: llvm-readobj -program-headers -sections %t | FileCheck %s | ||
| 5 | |||
| 6 | // PR37361: A note without SHF_ALLOC should not be included into a PT_NOTE program header. | ||
| 7 | |||
| 8 | // CHECK: Section { | ||
| 9 | // CHECK: Index: | ||
| 10 | // CHECK: Name: .note.a | ||
| 11 | // CHECK-NEXT: Type: SHT_NOTE | ||
| 12 | // CHECK-NEXT: Flags [ | ||
| 13 | // CHECK-NEXT: SHF_ALLOC | ||
| 14 | // CHECK-NEXT: ] | ||
| 15 | // CHECK-NEXT: Address: 0x[[ADDR:.*]] | ||
| 16 | |||
| 17 | // Check we still emit the non-alloc SHT_NOTE section and keep its type. | ||
| 18 | |||
| 19 | // CHECK: Name: .note.b | ||
| 20 | // CHECK-NEXT: Type: SHT_NOTE | ||
| 21 | // CHECK-NEXT: Flags [ | ||
| 22 | // CHECK-NEXT: ] | ||
| 23 | |||
| 24 | // CHECK: ProgramHeader { | ||
| 25 | // CHECK: Type: PT_NOTE | ||
| 26 | // CHECK-NEXT: Offset: | ||
| 27 | // CHECK-NEXT: VirtualAddress: 0x[[ADDR]] | ||
| 28 | // CHECK-NEXT: PhysicalAddress: 0x[[ADDR]] | ||
| 29 | // CHECK-NEXT: FileSize: 16 | ||
| 30 | // CHECK-NEXT: MemSize: 16 | ||
| 31 | // CHECK-NOT: PT_NOTE | ||
| 32 | |||
| 33 | .section .note.a,"a",@note | ||
| 34 | .quad 1 | ||
| 35 | .quad 2 | ||
| 36 | |||
| 37 | .section .note.b,"",@note | ||
| 38 | .quad 3 | ||
deps/lld/test/ELF/note-noalloc2.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 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-readobj -program-headers %t | FileCheck %s | ||
| 5 | |||
| 6 | ## Check we do not create a PT_NOTE segment for non-allocatable note section. | ||
| 7 | |||
| 8 | # CHECK-NOT: PT_NOTE | ||
| 9 | |||
| 10 | .section .note,"",@note | ||
| 11 | .quad 0 | ||
deps/lld/test/ELF/oformat-binary.s+3-1| ... | @@ -15,10 +15,12 @@ | ... | @@ -15,10 +15,12 @@ |
| 15 | # RUN: ld.lld -o %t2.out --script %t.script %t --oformat binary | 15 | # RUN: ld.lld -o %t2.out --script %t.script %t --oformat binary |
| 16 | # RUN: od -t x1 -v %t2.out | FileCheck %s | 16 | # RUN: od -t x1 -v %t2.out | FileCheck %s |
| 17 | 17 | ||
| 18 | # RUN: not ld.lld -o %t3.out %t --oformat foo 2>&1 \ | 18 | # RUN: not ld.lld -o /dev/null %t --oformat foo 2>&1 \ |
| 19 | # RUN: | FileCheck %s --check-prefix ERR | 19 | # RUN: | FileCheck %s --check-prefix ERR |
| 20 | # ERR: unknown --oformat value: foo | 20 | # ERR: unknown --oformat value: foo |
| 21 | 21 | ||
| 22 | # RUN: ld.lld -o /dev/null %t --oformat elf | ||
| 23 | |||
| 22 | .text | 24 | .text |
| 23 | .align 4 | 25 | .align 4 |
| 24 | .globl _start | 26 | .globl _start |
deps/lld/test/ELF/output-section.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 | 3 | // RUN: ld.lld %t -o %t2 |
| 3 | // RUN: llvm-readobj -t %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -t %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | // CHECK: Symbol { | 6 | // CHECK: Symbol { |
| 7 | // CHECK: Name: bar_sym | 7 | // CHECK: Name: bar_sym |
deps/lld/test/ELF/pack-dyn-relocs.s+258-103| ... | @@ -5,12 +5,10 @@ | ... | @@ -5,12 +5,10 @@ |
| 5 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.a32 | 5 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.a32 |
| 6 | // RUN: ld.lld -pie --pack-dyn-relocs=none %t.a32 %t.a32.so -o %t2.a32 | 6 | // 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 -relocations %t2.a32 | FileCheck --check-prefix=UNPACKED32 %s |
| 8 | // RUN: ld.lld -pie --pack-dyn-relocs=android %t.a32 %t.a32.so -o %t3.a32 | ||
| 9 | // RUN: llvm-readobj -s -dynamic-table %t3.a32 | FileCheck --check-prefix=PACKED32-HEADERS %s | ||
| 10 | // RUN: llvm-readobj -relocations %t3.a32 | FileCheck --check-prefix=PACKED32 %s | ||
| 11 | 8 | ||
| 12 | // Unpacked should have the relative relocations in their natural order. | 9 | // Unpacked should have the relative relocations in their natural order. |
| 13 | // UNPACKED32: 0x1000 R_ARM_RELATIVE - 0x0 | 10 | // UNPACKED32: Section ({{.+}}) .rel.dyn { |
| 11 | // UNPACKED32-NEXT: 0x1000 R_ARM_RELATIVE - 0x0 | ||
| 14 | // UNPACKED32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0 | 12 | // UNPACKED32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0 |
| 15 | // UNPACKED32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0 | 13 | // UNPACKED32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0 |
| 16 | // UNPACKED32-NEXT: 0x100C R_ARM_RELATIVE - 0x0 | 14 | // UNPACKED32-NEXT: 0x100C R_ARM_RELATIVE - 0x0 |
| ... | @@ -37,70 +35,146 @@ | ... | @@ -37,70 +35,146 @@ |
| 37 | // UNPACKED32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0 | 35 | // UNPACKED32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0 |
| 38 | // UNPACKED32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0 | 36 | // UNPACKED32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0 |
| 39 | 37 | ||
| 38 | // UNPACKED32-NEXT: 0x1069 R_ARM_RELATIVE - 0x0 | ||
| 40 | // UNPACKED32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0 | 39 | // UNPACKED32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0 |
| 41 | // UNPACKED32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0 | 40 | // UNPACKED32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0 |
| 41 | // UNPACKED32-NEXT: } | ||
| 42 | |||
| 43 | // 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 | ||
| 46 | |||
| 47 | // ANDROID32-HEADERS: Index: 1 | ||
| 48 | // ANDROID32-HEADERS-NEXT: Name: .dynsym | ||
| 49 | |||
| 50 | // ANDROID32-HEADERS: Name: .rel.dyn | ||
| 51 | // ANDROID32-HEADERS-NEXT: Type: SHT_ANDROID_REL | ||
| 52 | // ANDROID32-HEADERS-NEXT: Flags [ (0x2) | ||
| 53 | // ANDROID32-HEADERS-NEXT: SHF_ALLOC (0x2) | ||
| 54 | // ANDROID32-HEADERS-NEXT: ] | ||
| 55 | // ANDROID32-HEADERS-NEXT: Address: [[ADDR:.*]] | ||
| 56 | // ANDROID32-HEADERS-NEXT: Offset: [[ADDR]] | ||
| 57 | // ANDROID32-HEADERS-NEXT: Size: [[SIZE:.*]] | ||
| 58 | // ANDROID32-HEADERS-NEXT: Link: 1 | ||
| 59 | // ANDROID32-HEADERS-NEXT: Info: 0 | ||
| 60 | // ANDROID32-HEADERS-NEXT: AddressAlignment: 4 | ||
| 61 | // ANDROID32-HEADERS-NEXT: EntrySize: 1 | ||
| 42 | 62 | ||
| 43 | // PACKED32-HEADERS: Index: 1 | 63 | // ANDROID32-HEADERS: 0x6000000F ANDROID_REL [[ADDR]] |
| 44 | // PACKED32-HEADERS-NEXT: Name: .dynsym | 64 | // ANDROID32-HEADERS: 0x60000010 ANDROID_RELSZ [[SIZE]] |
| 45 | |||
| 46 | // PACKED32-HEADERS: Name: .rel.dyn | ||
| 47 | // PACKED32-HEADERS-NEXT: Type: SHT_ANDROID_REL | ||
| 48 | // PACKED32-HEADERS-NEXT: Flags [ (0x2) | ||
| 49 | // PACKED32-HEADERS-NEXT: SHF_ALLOC (0x2) | ||
| 50 | // PACKED32-HEADERS-NEXT: ] | ||
| 51 | // PACKED32-HEADERS-NEXT: Address: [[ADDR:.*]] | ||
| 52 | // PACKED32-HEADERS-NEXT: Offset: [[ADDR]] | ||
| 53 | // PACKED32-HEADERS-NEXT: Size: [[SIZE:.*]] | ||
| 54 | // PACKED32-HEADERS-NEXT: Link: 1 | ||
| 55 | // PACKED32-HEADERS-NEXT: Info: 0 | ||
| 56 | // PACKED32-HEADERS-NEXT: AddressAlignment: 4 | ||
| 57 | // PACKED32-HEADERS-NEXT: EntrySize: 1 | ||
| 58 | |||
| 59 | // PACKED32-HEADERS: 0x6000000F ANDROID_REL [[ADDR]] | ||
| 60 | // PACKED32-HEADERS: 0x60000010 ANDROID_RELSZ [[SIZE]] | ||
| 61 | 65 | ||
| 62 | // Packed should have the larger groups of relative relocations first, | 66 | // Packed should have the larger groups of relative relocations first, |
| 63 | // i.e. the 8 and 9 followed by the 7. | 67 | // i.e. the 8 and 9 followed by the 7. |
| 64 | // PACKED32: 0x1000 R_ARM_RELATIVE - 0x0 | 68 | // ANDROID32: Section ({{.+}}) .rel.dyn { |
| 65 | // PACKED32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0 | 69 | // ANDROID32-NEXT: 0x1000 R_ARM_RELATIVE - 0x0 |
| 66 | // PACKED32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0 | 70 | // ANDROID32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0 |
| 67 | // PACKED32-NEXT: 0x100C R_ARM_RELATIVE - 0x0 | 71 | // ANDROID32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0 |
| 68 | // PACKED32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0 | 72 | // ANDROID32-NEXT: 0x100C R_ARM_RELATIVE - 0x0 |
| 69 | // PACKED32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0 | 73 | // ANDROID32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0 |
| 70 | // PACKED32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0 | 74 | // ANDROID32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0 |
| 71 | // PACKED32-NEXT: 0x101C R_ARM_RELATIVE - 0x0 | 75 | // ANDROID32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0 |
| 72 | 76 | // ANDROID32-NEXT: 0x101C R_ARM_RELATIVE - 0x0 | |
| 73 | // PACKED32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0 | 77 | |
| 74 | // PACKED32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0 | 78 | // ANDROID32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0 |
| 75 | // PACKED32-NEXT: 0x104C R_ARM_RELATIVE - 0x0 | 79 | // ANDROID32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0 |
| 76 | // PACKED32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0 | 80 | // ANDROID32-NEXT: 0x104C R_ARM_RELATIVE - 0x0 |
| 77 | // PACKED32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0 | 81 | // ANDROID32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0 |
| 78 | // PACKED32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0 | 82 | // ANDROID32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0 |
| 79 | // PACKED32-NEXT: 0x105C R_ARM_RELATIVE - 0x0 | 83 | // ANDROID32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0 |
| 80 | // PACKED32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0 | 84 | // ANDROID32-NEXT: 0x105C R_ARM_RELATIVE - 0x0 |
| 81 | // PACKED32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0 | 85 | // ANDROID32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0 |
| 82 | 86 | // ANDROID32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0 | |
| 83 | // PACKED32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0 | 87 | |
| 84 | // PACKED32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0 | 88 | // ANDROID32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0 |
| 85 | // PACKED32-NEXT: 0x102C R_ARM_RELATIVE - 0x0 | 89 | // ANDROID32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0 |
| 86 | // PACKED32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0 | 90 | // ANDROID32-NEXT: 0x102C R_ARM_RELATIVE - 0x0 |
| 87 | // PACKED32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0 | 91 | // ANDROID32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0 |
| 88 | // PACKED32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0 | 92 | // ANDROID32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0 |
| 89 | // PACKED32-NEXT: 0x103C R_ARM_RELATIVE - 0x0 | 93 | // ANDROID32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0 |
| 90 | 94 | // ANDROID32-NEXT: 0x103C R_ARM_RELATIVE - 0x0 | |
| 91 | // PACKED32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0 | 95 | |
| 92 | // PACKED32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0 | 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 | ||
| 99 | // ANDROID32-NEXT: } | ||
| 100 | |||
| 101 | // 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 | ||
| 105 | |||
| 106 | // RELR32-HEADERS: Index: 1 | ||
| 107 | // RELR32-HEADERS-NEXT: Name: .dynsym | ||
| 108 | |||
| 109 | // RELR32-HEADERS: Name: .relr.dyn | ||
| 110 | // RELR32-HEADERS-NEXT: Type: SHT_RELR | ||
| 111 | // RELR32-HEADERS-NEXT: Flags [ (0x2) | ||
| 112 | // RELR32-HEADERS-NEXT: SHF_ALLOC (0x2) | ||
| 113 | // RELR32-HEADERS-NEXT: ] | ||
| 114 | // RELR32-HEADERS-NEXT: Address: [[ADDR:.*]] | ||
| 115 | // RELR32-HEADERS-NEXT: Offset: [[ADDR]] | ||
| 116 | // RELR32-HEADERS-NEXT: Size: 8 | ||
| 117 | // RELR32-HEADERS-NEXT: Link: 0 | ||
| 118 | // RELR32-HEADERS-NEXT: Info: 0 | ||
| 119 | // RELR32-HEADERS-NEXT: AddressAlignment: 4 | ||
| 120 | // RELR32-HEADERS-NEXT: EntrySize: 4 | ||
| 121 | |||
| 122 | // RELR32-HEADERS: 0x00000024 RELR [[ADDR]] | ||
| 123 | // RELR32-HEADERS: 0x00000023 RELRSZ 0x8 | ||
| 124 | // RELR32-HEADERS: 0x00000025 RELRENT 0x4 | ||
| 125 | |||
| 126 | // SHT_RELR section contains address/bitmap entries | ||
| 127 | // encoding the offsets for relative relocation. | ||
| 128 | // RAW-RELR32: Section ({{.+}}) .relr.dyn { | ||
| 129 | // RAW-RELR32-NEXT: 0x1000 | ||
| 130 | // RAW-RELR32-NEXT: 0x3FEFEFF | ||
| 131 | // RAW-RELR32-NEXT: } | ||
| 132 | |||
| 133 | // Decoded SHT_RELR section is same as UNPACKED, | ||
| 134 | // but contains only the relative relocations. | ||
| 135 | // Any relative relocations with odd offset stay in SHT_REL. | ||
| 136 | // 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 | ||
| 140 | // RELR32-NEXT: } | ||
| 141 | // 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 | ||
| 168 | // RELR32-NEXT: } | ||
| 93 | 169 | ||
| 94 | // RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/shared2.s -o %t.a64.so.o | 170 | // RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/shared2.s -o %t.a64.so.o |
| 95 | // RUN: ld.lld -shared %t.a64.so.o -o %t.a64.so | 171 | // RUN: ld.lld -shared %t.a64.so.o -o %t.a64.so |
| 96 | // RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.a64 | 172 | // RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.a64 |
| 97 | // RUN: ld.lld -pie --pack-dyn-relocs=none %t.a64 %t.a64.so -o %t2.a64 | 173 | // RUN: ld.lld -pie --pack-dyn-relocs=none %t.a64 %t.a64.so -o %t2.a64 |
| 98 | // RUN: llvm-readobj -relocations %t2.a64 | FileCheck --check-prefix=UNPACKED64 %s | 174 | // RUN: llvm-readobj -relocations %t2.a64 | FileCheck --check-prefix=UNPACKED64 %s |
| 99 | // RUN: ld.lld -pie --pack-dyn-relocs=android %t.a64 %t.a64.so -o %t3.a64 | ||
| 100 | // RUN: llvm-readobj -s -dynamic-table %t3.a64 | FileCheck --check-prefix=PACKED64-HEADERS %s | ||
| 101 | // RUN: llvm-readobj -relocations %t3.a64 | FileCheck --check-prefix=PACKED64 %s | ||
| 102 | 175 | ||
| 103 | // UNPACKED64: 0x10000 R_AARCH64_RELATIVE - 0x1 | 176 | // UNPACKED64: Section ({{.+}}) .rela.dyn { |
| 177 | // UNPACKED64-NEXT: 0x10000 R_AARCH64_RELATIVE - 0x1 | ||
| 104 | // UNPACKED64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2 | 178 | // UNPACKED64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2 |
| 105 | // UNPACKED64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3 | 179 | // UNPACKED64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3 |
| 106 | // UNPACKED64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4 | 180 | // UNPACKED64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4 |
| ... | @@ -127,59 +201,138 @@ | ... | @@ -127,59 +201,138 @@ |
| 127 | // UNPACKED64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x8 | 201 | // UNPACKED64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x8 |
| 128 | // UNPACKED64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x9 | 202 | // UNPACKED64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x9 |
| 129 | 203 | ||
| 204 | // UNPACKED64-NEXT: 0x100D1 R_AARCH64_RELATIVE - 0xA | ||
| 130 | // UNPACKED64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1 | 205 | // UNPACKED64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1 |
| 131 | // UNPACKED64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0 | 206 | // UNPACKED64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0 |
| 207 | // UNPACKED64-NEXT: } | ||
| 208 | |||
| 209 | // 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 | ||
| 212 | |||
| 213 | // ANDROID64-HEADERS: Index: 1 | ||
| 214 | // ANDROID64-HEADERS-NEXT: Name: .dynsym | ||
| 215 | |||
| 216 | // ANDROID64-HEADERS: Name: .rela.dyn | ||
| 217 | // ANDROID64-HEADERS-NEXT: Type: SHT_ANDROID_RELA | ||
| 218 | // ANDROID64-HEADERS-NEXT: Flags [ (0x2) | ||
| 219 | // ANDROID64-HEADERS-NEXT: SHF_ALLOC (0x2) | ||
| 220 | // ANDROID64-HEADERS-NEXT: ] | ||
| 221 | // ANDROID64-HEADERS-NEXT: Address: [[ADDR:.*]] | ||
| 222 | // ANDROID64-HEADERS-NEXT: Offset: [[ADDR]] | ||
| 223 | // ANDROID64-HEADERS-NEXT: Size: [[SIZE:.*]] | ||
| 224 | // ANDROID64-HEADERS-NEXT: Link: 1 | ||
| 225 | // ANDROID64-HEADERS-NEXT: Info: 0 | ||
| 226 | // ANDROID64-HEADERS-NEXT: AddressAlignment: 8 | ||
| 227 | // ANDROID64-HEADERS-NEXT: EntrySize: 1 | ||
| 228 | |||
| 229 | // ANDROID64-HEADERS: 0x0000000060000011 ANDROID_RELA [[ADDR]] | ||
| 230 | // ANDROID64-HEADERS: 0x0000000060000012 ANDROID_RELASZ [[SIZE]] | ||
| 231 | |||
| 232 | // 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 | ||
| 263 | // ANDROID64-NEXT: } | ||
| 264 | |||
| 265 | // 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 | ||
| 269 | |||
| 270 | // RELR64-HEADERS: Index: 1 | ||
| 271 | // RELR64-HEADERS-NEXT: Name: .dynsym | ||
| 272 | |||
| 273 | // RELR64-HEADERS: Name: .relr.dyn | ||
| 274 | // RELR64-HEADERS-NEXT: Type: SHT_RELR | ||
| 275 | // RELR64-HEADERS-NEXT: Flags [ (0x2) | ||
| 276 | // RELR64-HEADERS-NEXT: SHF_ALLOC (0x2) | ||
| 277 | // RELR64-HEADERS-NEXT: ] | ||
| 278 | // RELR64-HEADERS-NEXT: Address: [[ADDR:.*]] | ||
| 279 | // RELR64-HEADERS-NEXT: Offset: [[ADDR]] | ||
| 280 | // RELR64-HEADERS-NEXT: Size: 16 | ||
| 281 | // RELR64-HEADERS-NEXT: Link: 0 | ||
| 282 | // RELR64-HEADERS-NEXT: Info: 0 | ||
| 283 | // RELR64-HEADERS-NEXT: AddressAlignment: 8 | ||
| 284 | // RELR64-HEADERS-NEXT: EntrySize: 8 | ||
| 285 | |||
| 286 | // RELR64-HEADERS: 0x0000000000000024 RELR [[ADDR]] | ||
| 287 | // RELR64-HEADERS: 0x0000000000000023 RELRSZ 0x10 | ||
| 288 | // RELR64-HEADERS: 0x0000000000000025 RELRENT 0x8 | ||
| 289 | |||
| 290 | // SHT_RELR section contains address/bitmap entries | ||
| 291 | // encoding the offsets for relative relocation. | ||
| 292 | // RAW-RELR64: Section ({{.+}}) .relr.dyn { | ||
| 293 | // RAW-RELR64-NEXT: 0x10000 | ||
| 294 | // RAW-RELR64-NEXT: 0x3FEFEFF | ||
| 295 | // RAW-RELR64-NEXT: } | ||
| 296 | |||
| 297 | // Decoded SHT_RELR section is same as UNPACKED, | ||
| 298 | // but contains only the relative relocations. | ||
| 299 | // Any relative relocations with odd offset stay in SHT_RELA. | ||
| 300 | // 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 | ||
| 304 | // RELR64-NEXT: } | ||
| 305 | // 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 | ||
| 132 | 322 | ||
| 133 | // PACKED64: 0x10000 R_AARCH64_RELATIVE - 0x1 | 323 | // RELR64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x0 |
| 134 | // PACKED64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2 | 324 | // RELR64-NEXT: 0x10090 R_AARCH64_RELATIVE - 0x0 |
| 135 | // PACKED64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3 | 325 | // RELR64-NEXT: 0x10098 R_AARCH64_RELATIVE - 0x0 |
| 136 | // PACKED64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4 | 326 | // RELR64-NEXT: 0x100A0 R_AARCH64_RELATIVE - 0x0 |
| 137 | // PACKED64-NEXT: 0x10020 R_AARCH64_RELATIVE - 0x5 | 327 | // RELR64-NEXT: 0x100A8 R_AARCH64_RELATIVE - 0x0 |
| 138 | // PACKED64-NEXT: 0x10028 R_AARCH64_RELATIVE - 0x6 | 328 | // RELR64-NEXT: 0x100B0 R_AARCH64_RELATIVE - 0x0 |
| 139 | // PACKED64-NEXT: 0x10030 R_AARCH64_RELATIVE - 0x7 | 329 | // RELR64-NEXT: 0x100B8 R_AARCH64_RELATIVE - 0x0 |
| 140 | // PACKED64-NEXT: 0x10038 R_AARCH64_RELATIVE - 0x8 | 330 | // RELR64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x0 |
| 141 | 331 | // RELR64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x0 | |
| 142 | // PACKED64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x1 | 332 | // RELR64-NEXT: } |
| 143 | // PACKED64-NEXT: 0x10090 R_AARCH64_RELATIVE - 0x2 | ||
| 144 | // PACKED64-NEXT: 0x10098 R_AARCH64_RELATIVE - 0x3 | ||
| 145 | // PACKED64-NEXT: 0x100A0 R_AARCH64_RELATIVE - 0x4 | ||
| 146 | // PACKED64-NEXT: 0x100A8 R_AARCH64_RELATIVE - 0x5 | ||
| 147 | // PACKED64-NEXT: 0x100B0 R_AARCH64_RELATIVE - 0x6 | ||
| 148 | // PACKED64-NEXT: 0x100B8 R_AARCH64_RELATIVE - 0x7 | ||
| 149 | // PACKED64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x8 | ||
| 150 | // PACKED64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x9 | ||
| 151 | |||
| 152 | // PACKED64-NEXT: 0x10048 R_AARCH64_RELATIVE - 0x1 | ||
| 153 | // PACKED64-NEXT: 0x10050 R_AARCH64_RELATIVE - 0x2 | ||
| 154 | // PACKED64-NEXT: 0x10058 R_AARCH64_RELATIVE - 0x3 | ||
| 155 | // PACKED64-NEXT: 0x10060 R_AARCH64_RELATIVE - 0x4 | ||
| 156 | // PACKED64-NEXT: 0x10068 R_AARCH64_RELATIVE - 0x5 | ||
| 157 | // PACKED64-NEXT: 0x10070 R_AARCH64_RELATIVE - 0x6 | ||
| 158 | // PACKED64-NEXT: 0x10078 R_AARCH64_RELATIVE - 0x7 | ||
| 159 | |||
| 160 | // PACKED64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1 | ||
| 161 | // PACKED64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0 | ||
| 162 | |||
| 163 | // PACKED64-HEADERS: Index: 1 | ||
| 164 | // PACKED64-HEADERS-NEXT: Name: .dynsym | ||
| 165 | |||
| 166 | // PACKED64-HEADERS: Name: .rela.dyn | ||
| 167 | // PACKED64-HEADERS-NEXT: Type: SHT_ANDROID_RELA | ||
| 168 | // PACKED64-HEADERS-NEXT: Flags [ (0x2) | ||
| 169 | // PACKED64-HEADERS-NEXT: SHF_ALLOC (0x2) | ||
| 170 | // PACKED64-HEADERS-NEXT: ] | ||
| 171 | // PACKED64-HEADERS-NEXT: Address: [[ADDR:.*]] | ||
| 172 | // PACKED64-HEADERS-NEXT: Offset: [[ADDR]] | ||
| 173 | // PACKED64-HEADERS-NEXT: Size: [[SIZE:.*]] | ||
| 174 | // PACKED64-HEADERS-NEXT: Link: 1 | ||
| 175 | // PACKED64-HEADERS-NEXT: Info: 0 | ||
| 176 | // PACKED64-HEADERS-NEXT: AddressAlignment: 8 | ||
| 177 | // PACKED64-HEADERS-NEXT: EntrySize: 1 | ||
| 178 | |||
| 179 | // PACKED64-HEADERS: 0x0000000060000011 ANDROID_RELA [[ADDR]] | ||
| 180 | // PACKED64-HEADERS: 0x0000000060000012 ANDROID_RELASZ [[SIZE]] | ||
| 181 | 333 | ||
| 182 | .data | 334 | .data |
| 335 | .align 2 | ||
| 183 | .dc.a __ehdr_start + 1 | 336 | .dc.a __ehdr_start + 1 |
| 184 | .dc.a __ehdr_start + 2 | 337 | .dc.a __ehdr_start + 2 |
| 185 | .dc.a __ehdr_start + 3 | 338 | .dc.a __ehdr_start + 3 |
| ... | @@ -208,3 +361,5 @@ | ... | @@ -208,3 +361,5 @@ |
| 208 | .dc.a __ehdr_start + 7 | 361 | .dc.a __ehdr_start + 7 |
| 209 | .dc.a __ehdr_start + 8 | 362 | .dc.a __ehdr_start + 8 |
| 210 | .dc.a __ehdr_start + 9 | 363 | .dc.a __ehdr_start + 9 |
| 364 | .byte 00 | ||
| 365 | .dc.a __ehdr_start + 10 |
deps/lld/test/ELF/pack-dyn-relocs2.s created+85| ... | @@ -0,0 +1,85 @@ | ||
| 1 | // REQUIRES: arm, aarch64 | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-shared.s -o %t.so.o | ||
| 4 | // RUN: ld.lld -shared %t.so.o -o %t.so | ||
| 5 | |||
| 6 | // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o | ||
| 7 | // RUN: ld.lld -pie --pack-dyn-relocs=relr %t.o %t.so -o %t.exe | ||
| 8 | // RUN: llvm-readobj -relocations %t.exe | FileCheck %s | ||
| 9 | |||
| 10 | // 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 | ||
| 45 | // CHECK-NEXT: } | ||
| 46 | |||
| 47 | // RUN: llvm-readobj -s -dynamic-table %t.exe | FileCheck --check-prefix=HEADER %s | ||
| 48 | // HEADER: 0x00000023 RELRSZ 0xC | ||
| 49 | |||
| 50 | .data | ||
| 51 | .align 2 | ||
| 52 | .dc.a __ehdr_start | ||
| 53 | .dc.a __ehdr_start | ||
| 54 | .dc.a __ehdr_start | ||
| 55 | .dc.a __ehdr_start | ||
| 56 | .dc.a __ehdr_start | ||
| 57 | .dc.a __ehdr_start | ||
| 58 | .dc.a __ehdr_start | ||
| 59 | .dc.a __ehdr_start | ||
| 60 | .dc.a __ehdr_start | ||
| 61 | .dc.a __ehdr_start | ||
| 62 | .dc.a __ehdr_start | ||
| 63 | .dc.a __ehdr_start | ||
| 64 | .dc.a __ehdr_start | ||
| 65 | .dc.a __ehdr_start | ||
| 66 | .dc.a __ehdr_start | ||
| 67 | .dc.a __ehdr_start | ||
| 68 | .dc.a __ehdr_start | ||
| 69 | .dc.a __ehdr_start | ||
| 70 | .dc.a __ehdr_start | ||
| 71 | .dc.a __ehdr_start | ||
| 72 | .dc.a __ehdr_start | ||
| 73 | .dc.a __ehdr_start | ||
| 74 | .dc.a __ehdr_start | ||
| 75 | .dc.a __ehdr_start | ||
| 76 | .dc.a __ehdr_start | ||
| 77 | .dc.a __ehdr_start | ||
| 78 | .dc.a __ehdr_start | ||
| 79 | .dc.a __ehdr_start | ||
| 80 | .dc.a __ehdr_start | ||
| 81 | .dc.a __ehdr_start | ||
| 82 | .dc.a __ehdr_start | ||
| 83 | .dc.a __ehdr_start | ||
| 84 | .dc.a __ehdr_start | ||
| 85 | .dc.a __ehdr_start | ||
deps/lld/test/ELF/pie.s+3-1| ... | @@ -48,7 +48,9 @@ | ... | @@ -48,7 +48,9 @@ |
| 48 | # CHECK: Type: PT_DYNAMIC | 48 | # CHECK: Type: PT_DYNAMIC |
| 49 | 49 | ||
| 50 | ## Check -nopie | 50 | ## Check -nopie |
| 51 | # RUN: ld.lld -nopie %t1.o -o %t2 | 51 | # RUN: ld.lld -no-pie %t1.o -o %t2 |
| 52 | # RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE | ||
| 53 | # RUN: ld.lld -no-pic-executable %t1.o -o %t2 | ||
| 52 | # 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 |
| 53 | # NOPIE-NOT: Type: SharedObject | 55 | # NOPIE-NOT: Type: SharedObject |
| 54 | 56 |
deps/lld/test/ELF/plt-aarch64.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: aarch64 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/plt-aarch64.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/plt-aarch64.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| ... | @@ -10,8 +11,6 @@ | ... | @@ -10,8 +11,6 @@ |
| 10 | // RUN: llvm-objdump -s -section=.got.plt %t.exe | FileCheck --check-prefix=DUMPEXE %s | 11 | // RUN: llvm-objdump -s -section=.got.plt %t.exe | FileCheck --check-prefix=DUMPEXE %s |
| 11 | // RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASMEXE %s | 12 | // RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASMEXE %s |
| 12 | 13 | ||
| 13 | // REQUIRES: aarch64 | ||
| 14 | |||
| 15 | // CHECKDSO: Name: .plt | 14 | // CHECKDSO: Name: .plt |
| 16 | // CHECKDSO-NEXT: Type: SHT_PROGBITS | 15 | // CHECKDSO-NEXT: Type: SHT_PROGBITS |
| 17 | // CHECKDSO-NEXT: Flags [ | 16 | // CHECKDSO-NEXT: Flags [ |
deps/lld/test/ELF/plt-i686.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| ... | @@ -9,7 +10,6 @@ | ... | @@ -9,7 +10,6 @@ |
| 9 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMSHARED %s | 10 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMSHARED %s |
| 10 | // RUN: ld.lld -pie %t.o %t2.so -o %t | 11 | // RUN: ld.lld -pie %t.o %t2.so -o %t |
| 11 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMPIE %s | 12 | // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMPIE %s |
| 12 | // REQUIRES: x86 | ||
| 13 | 13 | ||
| 14 | // CHECK: Name: .plt | 14 | // CHECK: Name: .plt |
| 15 | // CHECK-NEXT: Type: SHT_PROGBITS | 15 | // CHECK-NEXT: Type: SHT_PROGBITS |
deps/lld/test/ELF/plt.s+1-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| ... | @@ -8,8 +9,6 @@ | ... | @@ -8,8 +9,6 @@ |
| 8 | // RUN: llvm-readobj -s -r %t3 | FileCheck --check-prefix=CHECK2 %s | 9 | // RUN: llvm-readobj -s -r %t3 | FileCheck --check-prefix=CHECK2 %s |
| 9 | // RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM2 %s | 10 | // RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM2 %s |
| 10 | 11 | ||
| 11 | // REQUIRES: x86 | ||
| 12 | |||
| 13 | // CHECK: Name: .plt | 12 | // CHECK: Name: .plt |
| 14 | // CHECK-NEXT: Type: SHT_PROGBITS | 13 | // CHECK-NEXT: Type: SHT_PROGBITS |
| 15 | // CHECK-NEXT: Flags [ | 14 | // CHECK-NEXT: Flags [ |
deps/lld/test/ELF/ppc-rela.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # REQUIRES: ppc | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t | ||
| 3 | # RUN: ld.lld %t -o %t2 -shared | ||
| 4 | # RUN: llvm-readobj -r %t2 | FileCheck %s | ||
| 5 | |||
| 6 | .data | ||
| 7 | .long foo | ||
| 8 | |||
| 9 | // CHECK: Section ({{.*}}) .rela.dyn { | ||
| 10 | // CHECK-NEXT: 0x1000 R_PPC_ADDR32 foo 0x0 | ||
| 11 | // CHECK-NEXT: } | ||
deps/lld/test/ELF/ppc-relocs.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: ppc | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t |
| 2 | # RUN: ld.lld %t -o %t2 | 3 | # RUN: ld.lld %t -o %t2 |
| 3 | # RUN: llvm-objdump -d %t2 | FileCheck %s | 4 | # RUN: llvm-objdump -d %t2 | FileCheck %s |
| 4 | # REQUIRES: ppc | ||
| 5 | 5 | ||
| 6 | .section .R_PPC_ADDR16_HA,"ax",@progbits | 6 | .section .R_PPC_ADDR16_HA,"ax",@progbits |
| 7 | .globl _start | 7 | .globl _start |
deps/lld/test/ELF/ppc64-abi-version.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # REQUIRES: ppc | ||
| 2 | |||
| 3 | # RUN: echo '.abiversion 1' | llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux - -o %t1.o | ||
| 4 | # RUN: not ld.lld -o /dev/null %t1.o 2>&1 | FileCheck -check-prefix=ERR1 %s | ||
| 5 | |||
| 6 | # ERR1: ABI version 1 is not supported | ||
| 7 | |||
| 8 | # RUN: echo '.abiversion 3' | llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux - -o %t1.o | ||
| 9 | # RUN: not ld.lld -o /dev/null %t1.o 2>&1 | FileCheck -check-prefix=ERR2 %s | ||
| 10 | |||
| 11 | # ERR2: unrecognized e_flags: 3 | ||
deps/lld/test/ELF/ppc64-addr16-error.s+7-2| ... | @@ -1,7 +1,12 @@ | ... | @@ -1,7 +1,12 @@ |
| 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 | |||
| 1 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t | 7 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2 | 8 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2 |
| 3 | // RUN: not ld.lld -shared %t %t2 -o %t3 2>&1 | FileCheck %s | 9 | // RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck %s |
| 4 | // REQUIRES: ppc | ||
| 5 | 10 | ||
| 6 | .short sym+65539 | 11 | .short sym+65539 |
| 7 | 12 |
deps/lld/test/ELF/ppc64-dtprel.s created+204| ... | @@ -0,0 +1,204 @@ | ||
| 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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 6 | // RUN: llvm-readelf -relocations --wide %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 | ||
| 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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 13 | // RUN: llvm-readelf -relocations --wide %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 | ||
| 16 | |||
| 17 | .text | ||
| 18 | .abiversion 2 | ||
| 19 | .globl test | ||
| 20 | .p2align 4 | ||
| 21 | .type test,@function | ||
| 22 | test: | ||
| 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 0, 16(1) | ||
| 30 | stdu 1, -32(1) | ||
| 31 | addis 3, 2, i@got@tlsld@ha | ||
| 32 | addi 3, 3, i@got@tlsld@l | ||
| 33 | bl __tls_get_addr(i@tlsld) | ||
| 34 | nop | ||
| 35 | addi 4, 3, i@dtprel | ||
| 36 | lwa 4, i@dtprel(3) | ||
| 37 | ld 0, 16(1) | ||
| 38 | mtlr 0 | ||
| 39 | blr | ||
| 40 | |||
| 41 | .globl test_64 | ||
| 42 | .p2align 4 | ||
| 43 | .type test_64,@function | ||
| 44 | |||
| 45 | .globl test_adjusted | ||
| 46 | .p2align 4 | ||
| 47 | .type test_adjusted,@function | ||
| 48 | test_adjusted: | ||
| 49 | .Lfunc_gep1: | ||
| 50 | addis 2, 12, .TOC.-.Lfunc_gep1@ha | ||
| 51 | addi 2, 2, .TOC.-.Lfunc_gep1@l | ||
| 52 | .Lfunc_lep1: | ||
| 53 | .localentry test_adjusted, .Lfunc_lep1-.Lfunc_gep1 | ||
| 54 | mflr 0 | ||
| 55 | std 0, 16(1) | ||
| 56 | stdu 1, -32(1) | ||
| 57 | addis 3, 2, k@got@tlsld@ha | ||
| 58 | addi 3, 3, k@got@tlsld@l | ||
| 59 | bl __tls_get_addr(k@tlsld) | ||
| 60 | nop | ||
| 61 | lis 4, k@dtprel@highesta | ||
| 62 | ori 4, 4, k@dtprel@highera | ||
| 63 | lis 5, k@dtprel@ha | ||
| 64 | addi 5, 5, k@dtprel@l | ||
| 65 | sldi 4, 4, 32 | ||
| 66 | or 4, 4, 5 | ||
| 67 | add 3, 3, 4 | ||
| 68 | addi 1, 1, 32 | ||
| 69 | ld 0, 16(1) | ||
| 70 | mtlr 0 | ||
| 71 | blr | ||
| 72 | |||
| 73 | .globl test_not_adjusted | ||
| 74 | .p2align 4 | ||
| 75 | .type test_not_adjusted,@function | ||
| 76 | test_not_adjusted: | ||
| 77 | .Lfunc_gep2: | ||
| 78 | addis 2, 12, .TOC.-.Lfunc_gep2@ha | ||
| 79 | addi 2, 2, .TOC.-.Lfunc_gep2@l | ||
| 80 | .Lfunc_lep2: | ||
| 81 | .localentry test_not_adjusted, .Lfunc_lep2-.Lfunc_gep2 | ||
| 82 | mflr 0 | ||
| 83 | std 0, 16(1) | ||
| 84 | stdu 1, -32(1) | ||
| 85 | addis 3, 2, i@got@tlsld@ha | ||
| 86 | addi 3, 3, i@got@tlsld@l | ||
| 87 | bl __tls_get_addr(k@tlsld) | ||
| 88 | nop | ||
| 89 | lis 4, k@dtprel@highest | ||
| 90 | ori 4, 4, k@dtprel@higher | ||
| 91 | sldi 4, 4, 32 | ||
| 92 | oris 4, 4, k@dtprel@h | ||
| 93 | ori 4, 4, k@dtprel@l | ||
| 94 | add 3, 3, 4 | ||
| 95 | addi 1, 1, 32 | ||
| 96 | ld 0, 16(1) | ||
| 97 | mtlr 0 | ||
| 98 | blr | ||
| 99 | |||
| 100 | .globl test_got_dtprel | ||
| 101 | .p2align 4 | ||
| 102 | .type test_got_dtprel,@function | ||
| 103 | test_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 | |||
| 109 | .section .debug_addr,"",@progbits | ||
| 110 | .quad i@dtprel+32768 | ||
| 111 | |||
| 112 | .type i,@object | ||
| 113 | .section .tdata,"awT",@progbits | ||
| 114 | .space 1024 | ||
| 115 | .p2align 2 | ||
| 116 | i: | ||
| 117 | .long 55 | ||
| 118 | .size i, 4 | ||
| 119 | |||
| 120 | .space 1024 * 1024 * 4 | ||
| 121 | .type k,@object | ||
| 122 | .p2align 2 | ||
| 123 | k: | ||
| 124 | .long 128 | ||
| 125 | .size k,4 | ||
| 126 | |||
| 127 | // Verify the input has all the remaining DTPREL based relocations we want to | ||
| 128 | // test. | ||
| 129 | // InputRelocs: Relocation section '.rela.text' | ||
| 130 | // InputRelocs: R_PPC64_DTPREL16 {{[0-9a-f]+}} i + 0 | ||
| 131 | // InputRelocs: R_PPC64_DTPREL16_DS {{[0-9a-f]+}} i + 0 | ||
| 132 | // InputRelocs: R_PPC64_DTPREL16_HIGHESTA {{[0-9a-f]+}} k + 0 | ||
| 133 | // InputRelocs: R_PPC64_DTPREL16_HIGHERA {{[0-9a-f]+}} k + 0 | ||
| 134 | // InputRelocs: R_PPC64_DTPREL16_HA {{[0-9a-f]+}} k + 0 | ||
| 135 | // InputRelocs: R_PPC64_DTPREL16_LO {{[0-9a-f]+}} k + 0 | ||
| 136 | // InputRelocs: R_PPC64_DTPREL16_HIGHEST {{[0-9a-f]+}} k + 0 | ||
| 137 | // InputRelocs: R_PPC64_DTPREL16_HIGHER {{[0-9a-f]+}} k + 0 | ||
| 138 | // InputRelocs: R_PPC64_DTPREL16_HI {{[0-9a-f]+}} k + 0 | ||
| 139 | // 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 | ||
| 144 | // InputRelocs: Relocation section '.rela.debug_addr' | ||
| 145 | // InputRelocs: R_PPC64_DTPREL64 {{[0-9a-f]+}} i + 8000 | ||
| 146 | |||
| 147 | // Expect a single dynamic relocation in the '.rela.dyn section for the module id. | ||
| 148 | // OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 1 entries: | ||
| 149 | // OutputRelocs-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend | ||
| 150 | // OutputRelocs-NEXT: R_PPC64_DTPMOD64 | ||
| 151 | |||
| 152 | |||
| 153 | // i@dtprel --> (1024 - 0x8000) = -31744 | ||
| 154 | // Dis: test: | ||
| 155 | // Dis: addi 4, 3, -31744 | ||
| 156 | // Dis: lwa 4, -31744(3) | ||
| 157 | |||
| 158 | // #k@dtprel(1024 + 4 + 1024 * 1024 * 4) = 0x400404 | ||
| 159 | |||
| 160 | // #highesta(k@dtprel) --> ((0x400404 - 0x8000 + 0x8000) >> 48) & 0xffff = 0 | ||
| 161 | // #highera(k@dtprel) --> ((0x400404 - 0x8000 + 0x8000) >> 32) & 0xffff = 0 | ||
| 162 | // #ha(k@dtprel) --> ((0x400404 - 0x8000 + 0x8000) >> 16) & 0xffff = 64 | ||
| 163 | // #lo(k@dtprel) --> ((0x400404 - 0x8000) & 0xffff = -31740 | ||
| 164 | // Dis: test_adjusted: | ||
| 165 | // Dis: lis 4, 0 | ||
| 166 | // Dis: ori 4, 4, 0 | ||
| 167 | // Dis: lis 5, 64 | ||
| 168 | // Dis: addi 5, 5, -31740 | ||
| 169 | |||
| 170 | // #highest(k@dtprel) --> ((0x400404 - 0x8000) >> 48) & 0xffff = 0 | ||
| 171 | // #higher(k@dtprel) --> ((0x400404 - 0x8000) >> 32) & 0xffff = 0 | ||
| 172 | // #hi(k@dtprel) --> ((0x400404 - 0x8000) >> 16) & 0xffff = 63 | ||
| 173 | // #lo(k@dtprel) --> ((0x400404 - 0x8000) & 0xffff = 33796 | ||
| 174 | // Dis: test_not_adjusted: | ||
| 175 | // Dis: lis 4, 0 | ||
| 176 | // Dis: ori 4, 4, 0 | ||
| 177 | // Dis: oris 4, 4, 63 | ||
| 178 | // Dis: ori 4, 4, 33796 | ||
| 179 | |||
| 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 created+50| ... | @@ -0,0 +1,50 @@ | ||
| 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-error-toc-restore.s created+20| ... | @@ -0,0 +1,20 @@ | ||
| 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: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s | ||
| 7 | |||
| 8 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | ||
| 9 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o | ||
| 10 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 11 | // RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s | ||
| 12 | |||
| 13 | # Calling external function bar needs a nop | ||
| 14 | // CHECK: call lacks nop, can't restore toc | ||
| 15 | .text | ||
| 16 | .abiversion 2 | ||
| 17 | |||
| 18 | .global _start | ||
| 19 | _start: | ||
| 20 | bl foo | ||
deps/lld/test/ELF/ppc64-error-toc-tail-call.s created+20| ... | @@ -0,0 +1,20 @@ | ||
| 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: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s | ||
| 7 | |||
| 8 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | ||
| 9 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o | ||
| 10 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 11 | // RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s | ||
| 12 | |||
| 13 | # A tail call to an external function without a nop should issue an error. | ||
| 14 | // CHECK: call lacks nop, can't restore toc | ||
| 15 | .text | ||
| 16 | .abiversion 2 | ||
| 17 | |||
| 18 | .global _start | ||
| 19 | _start: | ||
| 20 | b foo | ||
deps/lld/test/ELF/ppc64-func-entry-points.s created+80| ... | @@ -0,0 +1,80 @@ | ||
| 1 | // REQUIRES: ppc | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o | ||
| 5 | // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o | ||
| 6 | // RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -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/ppc64-func-global-entry.s -o %t2.o | ||
| 11 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o | ||
| 12 | // RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -o %t | ||
| 13 | // RUN: llvm-objdump -d %t | FileCheck %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 0, 16(1) | ||
| 30 | 	stdu 1, -48(1) | ||
| 31 | 	li 3, 1 | ||
| 32 | 	li 4, 1 | ||
| 33 | 	std 30, 32(1) # 8-byte Folded Spill | ||
| 34 | 	bl foo_external_same | ||
| 35 | 	nop | ||
| 36 | 	mr 30, 3 | ||
| 37 | 	li 3, 2 | ||
| 38 | 	li 4, 2 | ||
| 39 | 	bl foo_external_diff | ||
| 40 | 	nop | ||
| 41 | 	addis 4, 2, .LC0@toc@ha | ||
| 42 | 	add 3, 3, 30 | ||
| 43 | 	ld 30, 32(1) # 8-byte Folded Reload | ||
| 44 | 	ld 4, .LC0@toc@l(4) | ||
| 45 | 	lwz 4, 0(4) | ||
| 46 | 	add 3, 3, 4 | ||
| 47 | 	extsw 3, 3 | ||
| 48 | 	addi 1, 1, 48 | ||
| 49 | 	ld 0, 16(1) | ||
| 50 | 	li 0, 1 | ||
| 51 | 	sc | ||
| 52 | 	.long	0 | ||
| 53 | 	.quad	0 | ||
| 54 | .Lfunc_end0: | ||
| 55 | 	.size	_start, .Lfunc_end0-.Lfunc_begin0 | ||
| 56 | # -- End function | ||
| 57 | 	.section	.toc,"aw",@progbits | ||
| 58 | .LC0: | ||
| 59 | 	.tc glob[TC],glob | ||
| 60 | 	.type	glob,@object # @glob | ||
| 61 | 	.data | ||
| 62 | 	.globl	glob | ||
| 63 | 	.p2align	2 | ||
| 64 | glob: | ||
| 65 | 	.long	10 # 0xa | ||
| 66 | 	.size	glob, 4 | ||
| 67 | |||
| 68 | # Check that foo_external_diff has a global entry point and we branch to | ||
| 69 | # foo_external_diff+8. Also check that foo_external_same has no global entry | ||
| 70 | # point and we branch to start of foo_external_same. | ||
| 71 | |||
| 72 | // CHECK: _start: | ||
| 73 | // CHECK: 10010020: {{.*}} bl .+144 | ||
| 74 | // CHECK: 10010034: {{.*}} bl .+84 | ||
| 75 | // CHECK: foo_external_diff: | ||
| 76 | // CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 2 | ||
| 77 | // CHECK-NEXT: 10010084: {{.*}} addi 2, 2, 32640 | ||
| 78 | // CHECK-NEXT: 10010088: {{.*}} addis 5, 2, 0 | ||
| 79 | // CHECK: foo_external_same: | ||
| 80 | // CHECK-NEXT: 100100b0: {{.*}} add 3, 4, 3 | ||
deps/lld/test/ELF/ppc64-gd-to-ie.s created+104| ... | @@ -0,0 +1,104 @@ | ||
| 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 -relocations --wide %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 -relocations --wide %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 | ||
| 47 | other_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 created+112| ... | @@ -0,0 +1,112 @@ | ||
| 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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 6 | // RUN: llvm-readelf -relocations --wide %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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 13 | // RUN: llvm-readelf -relocations --wide %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 | ||
| 22 | test: | ||
| 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 | |||
| 48 | test_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 | |||
| 57 | test_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 created+115| ... | @@ -0,0 +1,115 @@ | ||
| 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 | ||
| 49 | glob: | ||
| 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: {{.*}} addis 3, 2, 0 | ||
| 87 | # CHECK-NEXT: 1001000c: {{.*}} ld 3, -32760(3) | ||
| 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 created+87| ... | @@ -0,0 +1,87 @@ | ||
| 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 | # RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s | ||
| 9 | # RUN: llvm-readelf -dyn-relocations %t | FileCheck --check-prefix=DYNREL %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-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 | ||
| 18 | |||
| 19 | # CHECK: Disassembly of section .text: | ||
| 20 | |||
| 21 | # Tocbase + (0 << 16) + 32560 | ||
| 22 | # 0x100280e0 + 0 + 32560 = 0x10030010 (.plt[2]) | ||
| 23 | # CHECK: __plt_foo: | ||
| 24 | # CHECK-NEXT: std 2, 24(1) | ||
| 25 | # CHECK-NEXT: addis 12, 2, 0 | ||
| 26 | # CHECK-NEXT: ld 12, 32560(12) | ||
| 27 | # CHECK-NEXT: mtctr 12 | ||
| 28 | # CHECK-NEXT: bctr | ||
| 29 | |||
| 30 | # Tocbase + (0 << 16) + 32568 | ||
| 31 | # 0x100280e0 + 0 + 32568 = 0x1003018 (.plt[3]) | ||
| 32 | # CHECK: __plt_ifunc: | ||
| 33 | # CHECK-NEXT: std 2, 24(1) | ||
| 34 | # CHECK-NEXT: addis 12, 2, 0 | ||
| 35 | # CHECK-NEXT: ld 12, 32568(12) | ||
| 36 | # CHECK-NEXT: mtctr 12 | ||
| 37 | # CHECK-NEXT: bctr | ||
| 38 | |||
| 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 | ||
| 69 | |||
| 70 | .type ifunc STT_GNU_IFUNC | ||
| 71 | .globl ifunc | ||
| 72 | ifunc: | ||
| 73 | nop | ||
| 74 | |||
| 75 | .global _start | ||
| 76 | .type _start,@function | ||
| 77 | |||
| 78 | _start: | ||
| 79 | .Lfunc_gep0: | ||
| 80 | addis 2, 12, .TOC.-.Lfunc_gep0@ha | ||
| 81 | addi 2, 2, .TOC.-.Lfunc_gep0@l | ||
| 82 | .Lfunc_lep0: | ||
| 83 | .localentry _start, .Lfunc_lep0-.Lfunc_gep0 | ||
| 84 | bl foo | ||
| 85 | nop | ||
| 86 | bl ifunc | ||
| 87 | nop | ||
deps/lld/test/ELF/ppc64-initial-exec-tls.s created+102| ... | @@ -0,0 +1,102 @@ | ||
| 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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 8 | // RUN: llvm-readelf -relocations --wide %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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 17 | // RUN: llvm-readelf -relocations --wide %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 | ||
| 27 | test_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 | |||
| 44 | test_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 | |||
| 53 | test_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-local-dynamic.s created+128| ... | @@ -0,0 +1,128 @@ | ||
| 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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 6 | // RUN: llvm-readelf -relocations --wide %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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 13 | // RUN: llvm-readelf -relocations --wide %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 | ||
| 22 | test: | ||
| 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 0, 16(1) | ||
| 30 | stdu 1, -32(1) | ||
| 31 | addis 3, 2, i@got@tlsld@ha | ||
| 32 | addi 3, 3, i@got@tlsld@l | ||
| 33 | bl __tls_get_addr(i@tlsld) | ||
| 34 | nop | ||
| 35 | addis 3, 3, i@dtprel@ha | ||
| 36 | lwa 3, i@dtprel@l(3) | ||
| 37 | ld 0, 16(1) | ||
| 38 | mtlr 0 | ||
| 39 | blr | ||
| 40 | |||
| 41 | .globl test_hi | ||
| 42 | .p2align 4 | ||
| 43 | .type test_hi,@function | ||
| 44 | test_hi: | ||
| 45 | lis 3, j@got@tlsld@h | ||
| 46 | blr | ||
| 47 | |||
| 48 | .globl test_16 | ||
| 49 | .p2align 4 | ||
| 50 | .type test_16,@function | ||
| 51 | test_16: | ||
| 52 | li 3, k@got@tlsld | ||
| 53 | blr | ||
| 54 | |||
| 55 | .type i,@object | ||
| 56 | .section .tdata,"awT",@progbits | ||
| 57 | .p2align 2 | ||
| 58 | i: | ||
| 59 | .long 55 | ||
| 60 | .size i, 4 | ||
| 61 | |||
| 62 | .type j,@object | ||
| 63 | .section .tbss,"awT",@nobits | ||
| 64 | .p2align 2 | ||
| 65 | j: | ||
| 66 | .long 0 | ||
| 67 | .size j, 4 | ||
| 68 | |||
| 69 | .type k,@object | ||
| 70 | .section .tdata,"awT",@progbits | ||
| 71 | .p2align 3 | ||
| 72 | k: | ||
| 73 | .quad 66 | ||
| 74 | .size k, 8 | ||
| 75 | |||
| 76 | // Verify that the input contains all the R_PPC64_GOT_TLSLD16* relocations, as | ||
| 77 | // well as the DTPREL relocations used in a typical medium code model | ||
| 78 | // local-dynamic variable access. | ||
| 79 | // InputRelocs: Relocation section '.rela.text' | ||
| 80 | // InputRelocs: R_PPC64_GOT_TLSLD16_HA {{[0-9a-f]+}} i + 0 | ||
| 81 | // InputRelocs: R_PPC64_GOT_TLSLD16_LO {{[0-9a-f]+}} i + 0 | ||
| 82 | // InputRelocs: R_PPC64_TLSLD {{[0-9a-f]+}} i + 0 | ||
| 83 | // InputRelocs: R_PPC64_DTPREL16_HA {{[0-9a-f]+}} i + 0 | ||
| 84 | // InputRelocs: R_PPC64_DTPREL16_LO_DS {{[0-9a-f]+}} i + 0 | ||
| 85 | // InputRelocs: R_PPC64_GOT_TLSLD16_HI {{[0-9a-f]+}} j + 0 | ||
| 86 | // InputRelocs: R_PPC64_GOT_TLSLD16 {{[0-9a-f]+}} k + 0 | ||
| 87 | |||
| 88 | // The local dynamic version of tls needs to use the same mechanism to look up | ||
| 89 | // a variables address as general-dynamic. ie a call to __tls_get_addr with the | ||
| 90 | // address of a tls_index struct as the argument. However for local-dynamic | ||
| 91 | // variables all will have the same ti_module, and the offset field is left as | ||
| 92 | // as 0, so the same struct can be used for every local-dynamic variable | ||
| 93 | // used in the shared-object. | ||
| 94 | // OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 1 entries: | ||
| 95 | // OutputRelocs-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend | ||
| 96 | // OutputRelocs-NEXT: R_PPC64_DTPMOD64 | ||
| 97 | |||
| 98 | // Check that the got has 3 entries, 1 for the TOC and 1 stucture of 2 entries | ||
| 99 | // for the tls variables. Also verify the address so we can check the offsets | ||
| 100 | // we calculate for each relocation type. | ||
| 101 | // CheckGot: got 00000018 0000000000020100 | ||
| 102 | |||
| 103 | // got starts at 0x20100 so .TOC. will be 0x28100, and the tls_index struct is | ||
| 104 | // at 0x20108. | ||
| 105 | |||
| 106 | // #ha(i@got@tlsld) --> (0x20108 - 0x28100 + 0x8000) >> 16 = 0 | ||
| 107 | // #lo(i@got@tlsld) --> (0x20108 - 0x28100) = -7ff8 = -32760 | ||
| 108 | // When calculating offset relative to the dynamic thread pointer we have to | ||
| 109 | // adjust by 0x8000 since each DTV pointer points 0x8000 bytes past the start of | ||
| 110 | // its TLS block. | ||
| 111 | // #ha(i@dtprel) --> (0x0 -0x8000 + 0x8000) >> 16 = 0 | ||
| 112 | // #lo(i@dtprel) --> (0x0 -0x8000) = -0x8000 = -32768 | ||
| 113 | // Dis: test: | ||
| 114 | // Dis: addis 3, 2, 0 | ||
| 115 | // Dis-NEXT: addi 3, 3, -32760 | ||
| 116 | // Dis-NEXT: bl .+67108804 | ||
| 117 | // Dis-NEXT: ld 2, 24(1) | ||
| 118 | // Dis-NEXT: addis 3, 3, 0 | ||
| 119 | // Dis-NEXT: lwa 3, -32768(3) | ||
| 120 | |||
| 121 | |||
| 122 | // #hi(j@got@tlsld) --> (0x20108 - 0x28100 ) > 16 = -1 | ||
| 123 | // Dis: test_hi: | ||
| 124 | // Dis: lis 3, -1 | ||
| 125 | |||
| 126 | // k@got@tlsld --> (0x20108 - 0x28100) = -7ff8 = -32760 | ||
| 127 | // Dis: test_16: | ||
| 128 | // Dis: li 3, -32760 | ||
deps/lld/test/ELF/ppc64-local-exec-tls.s created+163| ... | @@ -0,0 +1,163 @@ | ||
| 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 -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 5 | // RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s | ||
| 6 | |||
| 7 | 	.text | ||
| 8 | 	.abiversion 2 | ||
| 9 | 	.globl	test_local_exec # -- Begin function test_local_exec | ||
| 10 | 	.p2align	4 | ||
| 11 | 	.type	test_local_exec,@function | ||
| 12 | test_local_exec: # @test_local_exec | ||
| 13 | .Lfunc_begin0: | ||
| 14 | # %bb.0: # %entry | ||
| 15 | 	li 3, 0 | ||
| 16 | 	stw 3, -12(1) | ||
| 17 | 	addis 3, 13, a@tprel@ha | ||
| 18 | 	addi 3, 3, a@tprel@l | ||
| 19 | 	ld 3, 0(3) | ||
| 20 | 	mr 4, 3 | ||
| 21 | 	extsw 3, 4 | ||
| 22 | 	blr | ||
| 23 | 	.long	0 | ||
| 24 | 	.quad	0 | ||
| 25 | .Lfunc_end0: | ||
| 26 | 	.size	test_local_exec, .Lfunc_end0-.Lfunc_begin0 | ||
| 27 | # -- End function | ||
| 28 | test_tprel: | ||
| 29 | .Lfunc_gep1: | ||
| 30 | addis 2, 12, .TOC.-.Lfunc_gep1@ha | ||
| 31 | addi 2, 2, .TOC.-.Lfunc_gep1@l | ||
| 32 | .Lfunc_lep1: | ||
| 33 | .localentry test_tprel, .Lfunc_lep1-.Lfunc_gep1 | ||
| 34 | addi 3, 13, b@tprel | ||
| 35 | blr | ||
| 36 | |||
| 37 | |||
| 38 | test_hi: | ||
| 39 | .Lfunc_gep2: | ||
| 40 | addis 2, 12, .TOC.-.Lfunc_gep2@ha | ||
| 41 | addi 2, 2, .TOC.-.Lfunc_gep2@l | ||
| 42 | .Lfunc_lep2: | ||
| 43 | .localentry test_hi, .Lfunc_lep2-.Lfunc_gep2 | ||
| 44 | addis 3, 13, b@tprel@h | ||
| 45 | blr | ||
| 46 | |||
| 47 | test_ds: | ||
| 48 | .Lfunc_gep3: | ||
| 49 | addis 2, 12, .TOC.-.Lfunc_gep3@ha | ||
| 50 | addi 2, 2, .TOC.-.Lfunc_gep3@l | ||
| 51 | .Lfunc_lep3: | ||
| 52 | .localentry test_ds, .Lfunc_lep3-.Lfunc_gep3 | ||
| 53 | ld 3, b@tprel, 13 | ||
| 54 | blr | ||
| 55 | |||
| 56 | test_lo_ds: | ||
| 57 | .Lfunc_gep4: | ||
| 58 | addis 2, 12, .TOC.-.Lfunc_gep4@ha | ||
| 59 | addi 2, 2, .TOC.-.Lfunc_gep4@l | ||
| 60 | .Lfunc_lep4: | ||
| 61 | .localentry test_lo_ds, .Lfunc_lep4-.Lfunc_gep4 | ||
| 62 | ld 3, b@tprel@l, 13 | ||
| 63 | blr | ||
| 64 | |||
| 65 | test_highest_a: | ||
| 66 | .Lfunc_gep5: | ||
| 67 | addis 2, 12, .TOC.-.Lfunc_gep5@ha | ||
| 68 | addi 2, 2, .TOC.-.Lfunc_gep5@l | ||
| 69 | .Lfunc_lep5: | ||
| 70 | .localentry test_highest_a, .Lfunc_lep5-.Lfunc_gep5 | ||
| 71 | lis 4, b@tprel@highesta | ||
| 72 | ori 4, 4, b@tprel@highera | ||
| 73 | lis 5, b@tprel@ha | ||
| 74 | addi 5, 5, b@tprel@l | ||
| 75 | sldi 4, 4, 32 | ||
| 76 | or 4, 4, 5 | ||
| 77 | add 3, 13, 4 | ||
| 78 | blr | ||
| 79 | |||
| 80 | test_highest: | ||
| 81 | .Lfunc_gep6: | ||
| 82 | addis 2, 12, .TOC.-.Lfunc_gep6@ha | ||
| 83 | addi 2, 2, .TOC.-.Lfunc_gep6@l | ||
| 84 | .Lfunc_lep6: | ||
| 85 | .localentry test_highest, .Lfunc_lep6-.Lfunc_gep6 | ||
| 86 | lis 4, b@tprel@highest | ||
| 87 | ori 4, 4, b@tprel@higher | ||
| 88 | sldi 4, 4, 32 | ||
| 89 | oris 4, 4, b@tprel@h | ||
| 90 | ori 4, 4, b@tprel@l | ||
| 91 | add 3, 13, 4 | ||
| 92 | blr | ||
| 93 | |||
| 94 | 	.type	a,@object # @a | ||
| 95 | 	.type	b,@object # @b | ||
| 96 | 	.section	.tdata,"awT",@progbits | ||
| 97 | 	.p2align	3 | ||
| 98 | a: | ||
| 99 | 	.quad	55 # 0x37 | ||
| 100 | 	.size	a, 8 | ||
| 101 | |||
| 102 | b: | ||
| 103 | 	.quad	55 # 0x37 | ||
| 104 | 	.size	b, 8 | ||
| 105 | |||
| 106 | // Verify that the input has every initial-exec tls relocation type. | ||
| 107 | // InputRelocs: Relocation section '.rela.text' | ||
| 108 | // InputRelocs: R_PPC64_TPREL16_HA {{0+}} a + 0 | ||
| 109 | // InputRelocs: R_PPC64_TPREL16_LO {{0+}} a + 0 | ||
| 110 | // InputRelocs: R_PPC64_TPREL16 {{0+8}} b + 0 | ||
| 111 | // InputRelocs: R_PPC64_TPREL16_HI {{0+8}} b + 0 | ||
| 112 | // InputRelocs: R_PPC64_TPREL16_DS {{0+8}} b + 0 | ||
| 113 | // InputRelocs: R_PPC64_TPREL16_LO_DS {{0+8}} b + 0 | ||
| 114 | // InputRelocs: R_PPC64_TPREL16_HIGHESTA {{0+8}} b + 0 | ||
| 115 | // InputRelocs: R_PPC64_TPREL16_HIGHERA {{0+8}} b + 0 | ||
| 116 | // InputRelocs: R_PPC64_TPREL16_HIGHEST {{0+8}} b + 0 | ||
| 117 | // InputRelocs: R_PPC64_TPREL16_HIGHER {{0+8}} b + 0 | ||
| 118 | |||
| 119 | // The start of the TLS storage area is 0x7000 bytes before the thread pointer (r13). | ||
| 120 | // We are building the address of the first TLS variable, relative to the thread pointer. | ||
| 121 | // #ha(a@tprel) --> (0 - 0x7000 + 0x8000) >> 16 = 0 | ||
| 122 | // #lo(a@tprel)) --> (0 - 0x7000) & 0xFFFF = -0x7000 = -28672 | ||
| 123 | // Dis: test_local_exec: | ||
| 124 | // Dis: addis 3, 13, 0 | ||
| 125 | // Dis: addi 3, 3, -28672 | ||
| 126 | |||
| 127 | // We are building the offset for the second TLS variable | ||
| 128 | // Offset within tls storage - 0x7000 | ||
| 129 | // b@tprel = 8 - 0x7000 = 28664 | ||
| 130 | // Dis: test_tprel: | ||
| 131 | // Dis: addi 3, 13, -28664 | ||
| 132 | |||
| 133 | // #hi(b@tprel) --> (8 - 0x7000) >> 16 = -1 | ||
| 134 | // Dis: test_hi: | ||
| 135 | // Dis: addis 3, 13, -1 | ||
| 136 | |||
| 137 | // b@tprel = 8 - 0x7000 = -28664 | ||
| 138 | // Dis: test_ds: | ||
| 139 | // Dis: ld 3, -28664(13) | ||
| 140 | |||
| 141 | // #lo(b@tprel) --> (8 - 0x7000) & 0xFFFF = -28664 | ||
| 142 | // Dis: test_lo_ds: | ||
| 143 | // Dis: ld 3, -28664(13) | ||
| 144 | |||
| 145 | // #highesta(b@tprel) --> ((0x8 - 0x7000 + 0x8000) >> 48) & 0xFFFF = 0 | ||
| 146 | // #highera(b@tprel) --> ((0x8 - 0x7000 + 0x8000) >> 32) & 0xFFFF = 0 | ||
| 147 | // #ha(k@dtprel) --> ((0x8 - 0x7000 + 0x8000) >> 16) & 0xFFFF = 0 | ||
| 148 | // #lo(k@dtprel) --> ((0x8 - 0x7000) & 0xFFFF = -28664 | ||
| 149 | // Dis: test_highest_a: | ||
| 150 | // Dis: lis 4, 0 | ||
| 151 | // Dis: ori 4, 4, 0 | ||
| 152 | // Dis: lis 5, 0 | ||
| 153 | // Dis: addi 5, 5, -28664 | ||
| 154 | |||
| 155 | // #highest(b@tprel) --> ((0x8 - 0x7000) >> 48) & 0xFFFF = 0xFFFF = -1 | ||
| 156 | // #higher(b@tprel) --> ((0x8 - 0x7000) >> 32) & 0xFFFF = 0xFFFF = 65535 | ||
| 157 | // #hi(k@dtprel) --> ((0x8 - 0x7000) >> 16) & 0xFFFF = 0xFFFF = 65535 | ||
| 158 | // #lo(k@dtprel) --> ((0x8 - 0x7000) & 0xFFFF = 33796 | ||
| 159 | // Dis: test_highest: | ||
| 160 | // Dis: lis 4, -1 | ||
| 161 | // Dis: ori 4, 4, 65535 | ||
| 162 | // Dis: oris 4, 4, 65535 | ||
| 163 | // Dis: ori 4, 4, 36872 | ||
deps/lld/test/ELF/ppc64-plt-stub.s created+42| ... | @@ -0,0 +1,42 @@ | ||
| 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 | ||
| 26 | .text | ||
| 27 | .abiversion 2 | ||
| 28 | .globl _start | ||
| 29 | .p2align 4 | ||
| 30 | .type _start,@function | ||
| 31 | _start: | ||
| 32 | .Lfunc_begin0: | ||
| 33 | .Lfunc_gep0: | ||
| 34 | addis 2, 12, .TOC.-.Lfunc_gep0@ha | ||
| 35 | addi 2, 2, .TOC.-.Lfunc_gep0@l | ||
| 36 | .Lfunc_lep0: | ||
| 37 | .localentry _start, .Lfunc_lep0-.Lfunc_gep0 | ||
| 38 | bl foo | ||
| 39 | nop | ||
| 40 | li 0, 1 | ||
| 41 | sc | ||
| 42 | .size _start, .-.Lfunc_begin0 | ||
deps/lld/test/ELF/ppc64-rel-calls.s+15-19| ... | @@ -1,32 +1,29 @@ | ... | @@ -1,32 +1,29 @@ |
| 1 | # REQUIRES: ppc | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t | ||
| 4 | # RUN: ld.lld %t -o %t2 | ||
| 5 | # RUN: llvm-objdump -d %t2 | FileCheck %s | ||
| 6 | |||
| 1 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t | 7 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t |
| 2 | # RUN: ld.lld %t -o %t2 | 8 | # RUN: ld.lld %t -o %t2 |
| 3 | # RUN: llvm-objdump -d %t2 | FileCheck %s | 9 | # RUN: llvm-objdump -d %t2 | FileCheck %s |
| 4 | # REQUIRES: ppc | ||
| 5 | 10 | ||
| 6 | # CHECK: Disassembly of section .text: | 11 | # CHECK: Disassembly of section .text: |
| 7 | 12 | ||
| 8 | .section ".opd","aw" | 13 | .text |
| 9 | .global _start | 14 | .global _start |
| 10 | _start: | 15 | _start: |
| 11 | .quad .Lfoo,.TOC.@tocbase,0 | ||
| 12 | |||
| 13 | .text | ||
| 14 | .Lfoo: | 16 | .Lfoo: |
| 15 | li 0,1 | 17 | li 0,1 |
| 16 | li 3,42 | 18 | li 3,42 |
| 17 | sc | 19 | sc |
| 18 | 20 | ||
| 19 | # CHECK: 10010000: 38 00 00 01 li 0, 1 | 21 | # CHECK: 10010000: {{.*}} li 0, 1 |
| 20 | # CHECK: 10010004: 38 60 00 2a li 3, 42 | 22 | # CHECK: 10010004: {{.*}} li 3, 42 |
| 21 | # CHECK: 10010008: 44 00 00 02 sc | 23 | # CHECK: 10010008: {{.*}} sc |
| 22 | 24 | ||
| 23 | .section ".opd","aw" | ||
| 24 | .global bar | 25 | .global bar |
| 25 | bar: | 26 | bar: |
| 26 | .quad .Lbar,.TOC.@tocbase,0 | ||
| 27 | |||
| 28 | .text | ||
| 29 | .Lbar: | ||
| 30 | bl _start | 27 | bl _start |
| 31 | nop | 28 | nop |
| 32 | bl .Lfoo | 29 | bl .Lfoo |
| ... | @@ -34,9 +31,8 @@ bar: | ... | @@ -34,9 +31,8 @@ bar: |
| 34 | blr | 31 | blr |
| 35 | 32 | ||
| 36 | # FIXME: The printing here is misleading, the branch offset here is negative. | 33 | # FIXME: The printing here is misleading, the branch offset here is negative. |
| 37 | # CHECK: 1001000c: 4b ff ff f5 bl .+67108852 | 34 | # CHECK: 1001000c: {{.*}} bl .+67108852 |
| 38 | # CHECK: 10010010: 60 00 00 00 nop | 35 | # CHECK: 10010010: {{.*}} nop |
| 39 | # CHECK: 10010014: 4b ff ff ed bl .+67108844 | 36 | # CHECK: 10010014: {{.*}} bl .+67108844 |
| 40 | # CHECK: 10010018: 60 00 00 00 nop | 37 | # CHECK: 10010018: {{.*}} nop |
| 41 | # CHECK: 1001001c: 4e 80 00 20 blr | 38 | # CHECK: 1001001c: {{.*}} blr |
| 42 |
deps/lld/test/ELF/ppc64-rel-so-local-calls.s created+87| ... | @@ -0,0 +1,87 @@ | ||
| 1 | // REQUIRES: ppc | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o | ||
| 4 | // RUN: ld.lld -shared -z notext %t.o -o %t.so | ||
| 5 | // RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s | ||
| 6 | |||
| 7 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | ||
| 8 | // RUN: ld.lld -shared -z notext %t.o -o %t.so | ||
| 9 | // RUN: llvm-readelf -dyn-relocations %t.so | FileCheck %s | ||
| 10 | |||
| 11 | |||
| 12 | // CHECK-NOT: foo | ||
| 13 | // CHECK-NOT: bar | ||
| 14 | |||
| 15 | 	.text | ||
| 16 | 	.abiversion 2 | ||
| 17 | 	.globl	baz | ||
| 18 | 	.p2align	4 | ||
| 19 | 	.type	baz,@function | ||
| 20 | baz: | ||
| 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	baz, .Lfunc_lep0-.Lfunc_gep0 | ||
| 27 | 	mflr 0 | ||
| 28 | 	std 0, 16(1) | ||
| 29 | 	stdu 1, -64(1) | ||
| 30 | 	std 30, 48(1) | ||
| 31 | 	std 29, 40(1) | ||
| 32 | 	mr 30, 3 | ||
| 33 | 	bl foo | ||
| 34 | 	mr 29, 3 | ||
| 35 | 	mr 3, 30 | ||
| 36 | 	bl bar | ||
| 37 | 	mullw 3, 3, 29 | ||
| 38 | 	ld 30, 48(1) | ||
| 39 | 	ld 29, 40(1) | ||
| 40 | 	extsw 3, 3 | ||
| 41 | 	addi 1, 1, 64 | ||
| 42 | 	ld 0, 16(1) | ||
| 43 | 	mtlr 0 | ||
| 44 | 	blr | ||
| 45 | 	.long	0 | ||
| 46 | 	.quad	0 | ||
| 47 | .Lfunc_end0: | ||
| 48 | 	.size	baz, .Lfunc_end0-.Lfunc_begin0 | ||
| 49 | |||
| 50 | 	.p2align	4 | ||
| 51 | 	.type	foo,@function | ||
| 52 | foo: | ||
| 53 | .Lfunc_begin1: | ||
| 54 | 	mullw 3, 3, 3 | ||
| 55 | 	extsw 3, 3 | ||
| 56 | 	blr | ||
| 57 | 	.long	0 | ||
| 58 | 	.quad	0 | ||
| 59 | .Lfunc_end1: | ||
| 60 | 	.size	foo, .Lfunc_end1-.Lfunc_begin1 | ||
| 61 | |||
| 62 | .p2align	4 | ||
| 63 | 	.type	bar,@function | ||
| 64 | bar: | ||
| 65 | .Lfunc_begin2: | ||
| 66 | .Lfunc_gep2: | ||
| 67 | 	addis 2, 12, .TOC.-.Lfunc_gep2@ha | ||
| 68 | 	addi 2, 2, .TOC.-.Lfunc_gep2@l | ||
| 69 | .Lfunc_lep2: | ||
| 70 | 	.localentry	bar, .Lfunc_lep2-.Lfunc_gep2 | ||
| 71 | 	mflr 0 | ||
| 72 | 	std 0, 16(1) | ||
| 73 | 	stdu 1, -48(1) | ||
| 74 | 	std 30, 32(1) | ||
| 75 | 	mr 30, 3 | ||
| 76 | 	bl foo | ||
| 77 | 	mullw 3, 3, 30 | ||
| 78 | 	ld 30, 32(1) | ||
| 79 | 	extsw 3, 3 | ||
| 80 | 	addi 1, 1, 48 | ||
| 81 | 	ld 0, 16(1) | ||
| 82 | 	mtlr 0 | ||
| 83 | 	blr | ||
| 84 | 	.long	0 | ||
| 85 | 	.quad	0 | ||
| 86 | .Lfunc_end2: | ||
| 87 | 	.size	bar, .Lfunc_end2-.Lfunc_begin2 | ||
deps/lld/test/ELF/ppc64-relocs.s+83-20| ... | @@ -1,22 +1,33 @@ | ... | @@ -1,22 +1,33 @@ |
| 1 | # REQUIRES: ppc | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t | ||
| 4 | # RUN: ld.lld %t -o %t2 | ||
| 5 | # RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=DATALE | ||
| 6 | # RUN: llvm-objdump -D %t2 | FileCheck %s | ||
| 7 | |||
| 1 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t | 8 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t |
| 2 | # RUN: ld.lld %t -o %t2 | 9 | # RUN: ld.lld %t -o %t2 |
| 3 | # RUN: llvm-objdump -d %t2 | FileCheck %s | 10 | # RUN: llvm-objdump -D %t2 | FileCheck %s --check-prefix=DATABE |
| 4 | # REQUIRES: ppc | 11 | # RUN: llvm-objdump -D %t2 | FileCheck %s |
| 5 | 12 | ||
| 6 | .section ".opd","aw" | 13 | .text |
| 7 | .global _start | 14 | .global _start |
| 8 | _start: | 15 | _start: |
| 9 | .quad .Lfoo,.TOC.@tocbase,0 | ||
| 10 | |||
| 11 | .text | ||
| 12 | .Lfoo: | 16 | .Lfoo: |
| 13 | 	li 0,1 | 17 | 	li 0,1 |
| 14 | 	li 3,42 | 18 | 	li 3,42 |
| 15 | 	sc | 19 | 	sc |
| 16 | 20 | ||
| 17 | .section ".toc","aw" | 21 | .section .rodata,"a",@progbits |
| 22 | .p2align 2 | ||
| 23 | .LJTI0_0: | ||
| 24 | .long .LBB0_2-.LJTI0_0 | ||
| 25 | |||
| 26 | .section .toc,"aw",@progbits | ||
| 18 | .L1: | 27 | .L1: |
| 19 | .quad 22, 37, 89, 47 | 28 | .quad 22, 37, 89, 47 |
| 29 | .LC0: | ||
| 30 | .tc .LJTI0_0[TC],.LJTI0_0 | ||
| 20 | 31 | ||
| 21 | .section .R_PPC64_TOC16_LO_DS,"ax",@progbits | 32 | .section .R_PPC64_TOC16_LO_DS,"ax",@progbits |
| 22 | .globl .FR_PPC64_TOC16_LO_DS | 33 | .globl .FR_PPC64_TOC16_LO_DS |
| ... | @@ -25,7 +36,7 @@ _start: | ... | @@ -25,7 +36,7 @@ _start: |
| 25 | 36 | ||
| 26 | # CHECK: Disassembly of section .R_PPC64_TOC16_LO_DS: | 37 | # CHECK: Disassembly of section .R_PPC64_TOC16_LO_DS: |
| 27 | # CHECK: .FR_PPC64_TOC16_LO_DS: | 38 | # CHECK: .FR_PPC64_TOC16_LO_DS: |
| 28 | # CHECK: 1001000c: e8 22 80 00 ld 1, -32768(2) | 39 | # CHECK: 1001000c: {{.*}} ld 1, -32768(2) |
| 29 | 40 | ||
| 30 | .section .R_PPC64_TOC16_LO,"ax",@progbits | 41 | .section .R_PPC64_TOC16_LO,"ax",@progbits |
| 31 | .globl .FR_PPC64_TOC16_LO | 42 | .globl .FR_PPC64_TOC16_LO |
| ... | @@ -34,7 +45,7 @@ _start: | ... | @@ -34,7 +45,7 @@ _start: |
| 34 | 45 | ||
| 35 | # CHECK: Disassembly of section .R_PPC64_TOC16_LO: | 46 | # CHECK: Disassembly of section .R_PPC64_TOC16_LO: |
| 36 | # CHECK: .FR_PPC64_TOC16_LO: | 47 | # CHECK: .FR_PPC64_TOC16_LO: |
| 37 | # CHECK: 10010010: 38 22 80 00 addi 1, 2, -32768 | 48 | # CHECK: 10010010: {{.*}} addi 1, 2, -32768 |
| 38 | 49 | ||
| 39 | .section .R_PPC64_TOC16_HI,"ax",@progbits | 50 | .section .R_PPC64_TOC16_HI,"ax",@progbits |
| 40 | .globl .FR_PPC64_TOC16_HI | 51 | .globl .FR_PPC64_TOC16_HI |
| ... | @@ -43,7 +54,7 @@ _start: | ... | @@ -43,7 +54,7 @@ _start: |
| 43 | 54 | ||
| 44 | # CHECK: Disassembly of section .R_PPC64_TOC16_HI: | 55 | # CHECK: Disassembly of section .R_PPC64_TOC16_HI: |
| 45 | # CHECK: .FR_PPC64_TOC16_HI: | 56 | # CHECK: .FR_PPC64_TOC16_HI: |
| 46 | # CHECK: 10010014: 3c 22 ff fe addis 1, 2, -2 | 57 | # CHECK: 10010014: {{.*}} addis 1, 2, -1 |
| 47 | 58 | ||
| 48 | .section .R_PPC64_TOC16_HA,"ax",@progbits | 59 | .section .R_PPC64_TOC16_HA,"ax",@progbits |
| 49 | .globl .FR_PPC64_TOC16_HA | 60 | .globl .FR_PPC64_TOC16_HA |
| ... | @@ -52,7 +63,7 @@ _start: | ... | @@ -52,7 +63,7 @@ _start: |
| 52 | 63 | ||
| 53 | # CHECK: Disassembly of section .R_PPC64_TOC16_HA: | 64 | # CHECK: Disassembly of section .R_PPC64_TOC16_HA: |
| 54 | # CHECK: .FR_PPC64_TOC16_HA: | 65 | # CHECK: .FR_PPC64_TOC16_HA: |
| 55 | # CHECK: 10010018: 3c 22 ff ff addis 1, 2, -1 | 66 | # CHECK: 10010018: {{.*}} addis 1, 2, 0 |
| 56 | 67 | ||
| 57 | .section .R_PPC64_REL24,"ax",@progbits | 68 | .section .R_PPC64_REL24,"ax",@progbits |
| 58 | .globl .FR_PPC64_REL24 | 69 | .globl .FR_PPC64_REL24 |
| ... | @@ -63,7 +74,7 @@ _start: | ... | @@ -63,7 +74,7 @@ _start: |
| 63 | 74 | ||
| 64 | # CHECK: Disassembly of section .R_PPC64_REL24: | 75 | # CHECK: Disassembly of section .R_PPC64_REL24: |
| 65 | # CHECK: .FR_PPC64_REL24: | 76 | # CHECK: .FR_PPC64_REL24: |
| 66 | # CHECK: 1001001c: 48 00 00 04 b .+4 | 77 | # CHECK: 1001001c: {{.*}} b .+4 |
| 67 | 78 | ||
| 68 | .section .R_PPC64_ADDR16_LO,"ax",@progbits | 79 | .section .R_PPC64_ADDR16_LO,"ax",@progbits |
| 69 | .globl .FR_PPC64_ADDR16_LO | 80 | .globl .FR_PPC64_ADDR16_LO |
| ... | @@ -72,7 +83,7 @@ _start: | ... | @@ -72,7 +83,7 @@ _start: |
| 72 | 83 | ||
| 73 | # CHECK: Disassembly of section .R_PPC64_ADDR16_LO: | 84 | # CHECK: Disassembly of section .R_PPC64_ADDR16_LO: |
| 74 | # CHECK: .FR_PPC64_ADDR16_LO: | 85 | # CHECK: .FR_PPC64_ADDR16_LO: |
| 75 | # CHECK: 10010020: 38 20 00 00 li 1, 0 | 86 | # CHECK: 10010020: {{.*}} li 1, 0 |
| 76 | 87 | ||
| 77 | .section .R_PPC64_ADDR16_HI,"ax",@progbits | 88 | .section .R_PPC64_ADDR16_HI,"ax",@progbits |
| 78 | .globl .FR_PPC64_ADDR16_HI | 89 | .globl .FR_PPC64_ADDR16_HI |
| ... | @@ -81,7 +92,7 @@ _start: | ... | @@ -81,7 +92,7 @@ _start: |
| 81 | 92 | ||
| 82 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HI: | 93 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HI: |
| 83 | # CHECK: .FR_PPC64_ADDR16_HI: | 94 | # CHECK: .FR_PPC64_ADDR16_HI: |
| 84 | # CHECK: 10010024: 38 20 10 01 li 1, 4097 | 95 | # CHECK: 10010024: {{.*}} li 1, 4097 |
| 85 | 96 | ||
| 86 | .section .R_PPC64_ADDR16_HA,"ax",@progbits | 97 | .section .R_PPC64_ADDR16_HA,"ax",@progbits |
| 87 | .globl .FR_PPC64_ADDR16_HA | 98 | .globl .FR_PPC64_ADDR16_HA |
| ... | @@ -90,7 +101,7 @@ _start: | ... | @@ -90,7 +101,7 @@ _start: |
| 90 | 101 | ||
| 91 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HA: | 102 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HA: |
| 92 | # CHECK: .FR_PPC64_ADDR16_HA: | 103 | # CHECK: .FR_PPC64_ADDR16_HA: |
| 93 | # CHECK: 10010028: 38 20 10 01 li 1, 4097 | 104 | # CHECK: 10010028: {{.*}} li 1, 4097 |
| 94 | 105 | ||
| 95 | .section .R_PPC64_ADDR16_HIGHER,"ax",@progbits | 106 | .section .R_PPC64_ADDR16_HIGHER,"ax",@progbits |
| 96 | .globl .FR_PPC64_ADDR16_HIGHER | 107 | .globl .FR_PPC64_ADDR16_HIGHER |
| ... | @@ -99,7 +110,7 @@ _start: | ... | @@ -99,7 +110,7 @@ _start: |
| 99 | 110 | ||
| 100 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER: | 111 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER: |
| 101 | # CHECK: .FR_PPC64_ADDR16_HIGHER: | 112 | # CHECK: .FR_PPC64_ADDR16_HIGHER: |
| 102 | # CHECK: 1001002c: 38 20 00 00 li 1, 0 | 113 | # CHECK: 1001002c: {{.*}} li 1, 0 |
| 103 | 114 | ||
| 104 | .section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits | 115 | .section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits |
| 105 | .globl .FR_PPC64_ADDR16_HIGHERA | 116 | .globl .FR_PPC64_ADDR16_HIGHERA |
| ... | @@ -108,7 +119,7 @@ _start: | ... | @@ -108,7 +119,7 @@ _start: |
| 108 | 119 | ||
| 109 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA: | 120 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA: |
| 110 | # CHECK: .FR_PPC64_ADDR16_HIGHERA: | 121 | # CHECK: .FR_PPC64_ADDR16_HIGHERA: |
| 111 | # CHECK: 10010030: 38 20 00 00 li 1, 0 | 122 | # CHECK: 10010030: {{.*}} li 1, 0 |
| 112 | 123 | ||
| 113 | .section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits | 124 | .section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits |
| 114 | .globl .FR_PPC64_ADDR16_HIGHEST | 125 | .globl .FR_PPC64_ADDR16_HIGHEST |
| ... | @@ -117,7 +128,7 @@ _start: | ... | @@ -117,7 +128,7 @@ _start: |
| 117 | 128 | ||
| 118 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST: | 129 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST: |
| 119 | # CHECK: .FR_PPC64_ADDR16_HIGHEST: | 130 | # CHECK: .FR_PPC64_ADDR16_HIGHEST: |
| 120 | # CHECK: 10010034: 38 20 00 00 li 1, 0 | 131 | # CHECK: 10010034: {{.*}} li 1, 0 |
| 121 | 132 | ||
| 122 | .section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits | 133 | .section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits |
| 123 | .globl .FR_PPC64_ADDR16_HIGHESTA | 134 | .globl .FR_PPC64_ADDR16_HIGHESTA |
| ... | @@ -126,5 +137,57 @@ _start: | ... | @@ -126,5 +137,57 @@ _start: |
| 126 | 137 | ||
| 127 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA: | 138 | # CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA: |
| 128 | # CHECK: .FR_PPC64_ADDR16_HIGHESTA: | 139 | # CHECK: .FR_PPC64_ADDR16_HIGHESTA: |
| 129 | # CHECK: 10010038: 38 20 00 00 li 1, 0 | 140 | # CHECK: 10010038: {{.*}} li 1, 0 |
| 130 | 141 | ||
| 142 | .section .R_PPC64_REL32, "ax",@progbits | ||
| 143 | .globl .FR_PPC64_REL32 | ||
| 144 | .FR_PPC64_REL32: | ||
| 145 | addis 5, 2, .LC0@toc@ha | ||
| 146 | ld 5, .LC0@toc@l(5) | ||
| 147 | .LBB0_2: | ||
| 148 | add 3, 3, 4 | ||
| 149 | |||
| 150 | # DATALE: Disassembly of section .rodata: | ||
| 151 | # DATALE: .rodata: | ||
| 152 | # DATALE: 10000190: b4 fe 00 00 | ||
| 153 | |||
| 154 | # DATABE: Disassembly of section .rodata: | ||
| 155 | # DATABE: .rodata: | ||
| 156 | # DATABE: 10000190: 00 00 fe b4 | ||
| 157 | |||
| 158 | # Address of rodata + value stored at rodata entry | ||
| 159 | # should equal address of LBB0_2. | ||
| 160 | # 0x10000190 + 0xfeb4 = 0x10010044 | ||
| 161 | # CHECK: Disassembly of section .R_PPC64_REL32: | ||
| 162 | # CHECK: .FR_PPC64_REL32: | ||
| 163 | # CHECK: 1001003c: {{.*}} addis 5, 2, 0 | ||
| 164 | # CHECK: 10010040: {{.*}} ld 5, -32736(5) | ||
| 165 | # CHECK: 10010044: {{.*}} add 3, 3, 4 | ||
| 166 | |||
| 167 | .section .R_PPC64_REL64, "ax",@progbits | ||
| 168 | .globl .FR_PPC64_REL64 | ||
| 169 | .FR_PPC64_REL64: | ||
| 170 | .cfi_startproc | ||
| 171 | .cfi_personality 148, __foo | ||
| 172 | li 0, 1 | ||
| 173 | li 3, 55 | ||
| 174 | sc | ||
| 175 | .cfi_endproc | ||
| 176 | __foo: | ||
| 177 | li 3,0 | ||
| 178 | |||
| 179 | # Check that address of eh_frame entry + value stored | ||
| 180 | # should equal the address of foo. Since it is not aligned, | ||
| 181 | # the entry is not stored exactly at 100001a8. It starts at | ||
| 182 | # address 0x100001aa and has the value 0xfeaa. | ||
| 183 | # 0x100001aa + 0xfeaa = 0x10010054 | ||
| 184 | # DATALE: Disassembly of section .eh_frame: | ||
| 185 | # DATALE: .eh_frame: | ||
| 186 | # DATALE: 100001a8: {{.*}} aa fe | ||
| 187 | |||
| 188 | # DATABE: Disassembly of section .eh_frame: | ||
| 189 | # DATABE: .eh_frame: | ||
| 190 | # DATABE: 100001b0: fe aa {{.*}} | ||
| 191 | |||
| 192 | # CHECK: __foo | ||
| 193 | # CHECK-NEXT: 10010054: {{.*}} li 3, 0 |
deps/lld/test/ELF/ppc64-shared-rel-toc.s deleted-27| ... | @@ -1,27 +0,0 @@ | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | ||
| 2 | // RUN: ld.lld -shared %t.o -o %t.so | ||
| 3 | // RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s | ||
| 4 | // REQUIRES: ppc | ||
| 5 | |||
| 6 | // When we create the TOC reference in the shared library, make sure that the | ||
| 7 | // R_PPC64_RELATIVE relocation uses the correct (non-zero) offset. | ||
| 8 | |||
| 9 | .globl foo | ||
| 10 | .align 2 | ||
| 11 | .type foo,@function | ||
| 12 | .section .opd,"aw",@progbits | ||
| 13 | foo: # @foo | ||
| 14 | .align 3 | ||
| 15 | .quad .Lfunc_begin0 | ||
| 16 | .quad .TOC.@tocbase | ||
| 17 | .quad 0 | ||
| 18 | .text | ||
| 19 | .Lfunc_begin0: | ||
| 20 | blr | ||
| 21 | |||
| 22 | // CHECK: 0x20000 R_PPC64_RELATIVE - 0x10000 | ||
| 23 | // CHECK: 0x20008 R_PPC64_RELATIVE - 0x8000 | ||
| 24 | |||
| 25 | // CHECK: Name: foo | ||
| 26 | // CHECK-NEXT: Value: 0x20000 | ||
| 27 | |||
deps/lld/test/ELF/ppc64-tls-gd-le.s created+83| ... | @@ -0,0 +1,83 @@ | ||
| 1 | // REQUIRES: ppc | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o | ||
| 4 | // RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 5 | // RUN: ld.lld %t.o -o %t | ||
| 6 | // RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s | ||
| 7 | // RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s | ||
| 8 | |||
| 9 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | ||
| 10 | // RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 11 | // RUN: ld.lld %t.o -o %t | ||
| 12 | // RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s | ||
| 13 | // RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s | ||
| 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 | ||
| 62 | a: | ||
| 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-ld-le.s created+84| ... | @@ -0,0 +1,84 @@ | ||
| 1 | // REQUIRES: ppc | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o | ||
| 4 | // RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 5 | // RUN: ld.lld %t.o -o %t | ||
| 6 | // RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s | ||
| 7 | // RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s | ||
| 8 | |||
| 9 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | ||
| 10 | // RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | ||
| 11 | // RUN: ld.lld %t.o -o %t | ||
| 12 | // RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s | ||
| 13 | // RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s | ||
| 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@tlsld@ha | ||
| 37 | 	addi 3, 3, a@got@tlsld@l | ||
| 38 | 	bl __tls_get_addr(a@tlsld) | ||
| 39 | 	nop | ||
| 40 | 	addis 3, 3, a@dtprel@ha | ||
| 41 | 	addi 3, 3, a@dtprel@l | ||
| 42 | 	lwz 30, 0(3) | ||
| 43 | 	extsw 3, 30 | ||
| 44 | 	ld 30, 48(31) # 8-byte Folded Reload | ||
| 45 | 	addi 1, 1, 64 | ||
| 46 | 	ld 0, 16(1) | ||
| 47 | 	ld 31, -8(1) | ||
| 48 | 	mtlr 0 | ||
| 49 | 	blr | ||
| 50 | 	.long	0 | ||
| 51 | 	.quad	0 | ||
| 52 | .Lfunc_end0: | ||
| 53 | 	.size	_start, .Lfunc_end0-.Lfunc_begin0 | ||
| 54 | # -- End function | ||
| 55 | .globl __tls_get_addr | ||
| 56 | .type __tls_get_addr,@function | ||
| 57 | __tls_get_addr: | ||
| 58 | 	.type	a,@object # @a | ||
| 59 | 	.section	.tdata,"awT",@progbits | ||
| 60 | 	.p2align	2 | ||
| 61 | a: | ||
| 62 | 	.long	2 # 0x2 | ||
| 63 | 	.size	a, 4 | ||
| 64 | |||
| 65 | // Verify that the input has local-dynamic tls relocation types | ||
| 66 | // InputRelocs: Relocation section '.rela.text' | ||
| 67 | // InputRelocs: R_PPC64_GOT_TLSLD16_HA {{0+}} a + 0 | ||
| 68 | // InputRelocs: R_PPC64_GOT_TLSLD16_LO {{0+}} a + 0 | ||
| 69 | // InputRelocs: R_PPC64_TLSLD {{0+}} a + 0 | ||
| 70 | |||
| 71 | // Verify that the local-dynamic sequence is relaxed to local exec. | ||
| 72 | // Dis: _start: | ||
| 73 | // Dis: nop | ||
| 74 | // Dis: addis 3, 13, 0 | ||
| 75 | // Dis: nop | ||
| 76 | // Dis: addi 3, 3, 4096 | ||
| 77 | |||
| 78 | // #ha(a@dtprel) --> (0x0 -0x8000 + 0x8000) >> 16 = 0 | ||
| 79 | // #lo(a@dtprel) --> (0x0 -0x8000) = -0x8000 = -32768 | ||
| 80 | // Dis: addis 3, 3, 0 | ||
| 81 | // Dis: addi 3, 3, -32768 | ||
| 82 | |||
| 83 | // Verify that no local-dynamic relocations exist for the dynamic linker. | ||
| 84 | // OutputRelocs-NOT: R_PPC64_DTPMOD64 | ||
deps/lld/test/ELF/ppc64-toc-rel.s created+90| ... | @@ -0,0 +1,90 @@ | ||
| 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 %s | ||
| 5 | # RUN: ld.lld %t.o -o %t2 | ||
| 6 | # RUN: llvm-objdump -D %t2 | FileCheck %s | ||
| 7 | |||
| 8 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | ||
| 9 | # RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s | ||
| 10 | # RUN: ld.lld %t.o -o %t2 | ||
| 11 | # RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s | ||
| 12 | |||
| 13 | # Make sure we calculate the offset correctly for a toc-relative access to a | ||
| 14 | # global variable as described by the PPC64 Elf V2 abi. | ||
| 15 | .abiversion 2 | ||
| 16 | |||
| 17 | # int global_a = 55 | ||
| 18 | .globl global_a | ||
| 19 | .section ".data" | ||
| 20 | .align 2 | ||
| 21 | .type global_a, @object | ||
| 22 | .size global_a, 4 | ||
| 23 | .p2align 2 | ||
| 24 | global_a: | ||
| 25 | .long 41 | ||
| 26 | |||
| 27 | |||
| 28 | .section ".text" | ||
| 29 | .align 2 | ||
| 30 | .global _start | ||
| 31 | .type _start, @function | ||
| 32 | _start: | ||
| 33 | .Lfunc_gep0: | ||
| 34 | addis 2, 12, .TOC.-.Lfunc_gep0@ha | ||
| 35 | addi 2, 2, .TOC.-.Lfunc_gep0@l | ||
| 36 | .Lfunc_lep0: | ||
| 37 | .localentry _start, .Lfunc_lep0-.Lfunc_gep0 | ||
| 38 | |||
| 39 | addis 3, 2, global_a@toc@ha | ||
| 40 | addi 3, 3, global_a@toc@l | ||
| 41 | li 0,1 | ||
| 42 | lwa 3, 0(3) | ||
| 43 | sc | ||
| 44 | .size _start,.-_start | ||
| 45 | |||
| 46 | # Verify the relocations that get emitted for the global variable are the | ||
| 47 | # expected ones. | ||
| 48 | # RELOCS: Relocations [ | ||
| 49 | # RELOCS-NEXT: .rela.text { | ||
| 50 | # RELOCS: 0x8 R_PPC64_TOC16_HA global_a 0x0 | ||
| 51 | # RELOCS: 0xC R_PPC64_TOC16_LO global_a 0x0 | ||
| 52 | |||
| 53 | # RELOCS-BE: Relocations [ | ||
| 54 | # RELOCS-BE-NEXT: .rela.text { | ||
| 55 | # RELOCS-BE: 0xA R_PPC64_TOC16_HA global_a 0x0 | ||
| 56 | # RELOCS-NE: 0xE R_PPC64_TOC16_LO global_a 0x0 | ||
| 57 | |||
| 58 | # Want to check _start for the values used to build the offset from the TOC base | ||
| 59 | # to global_a. The .TOC. symbol is expected at address 0x10030000, and the | ||
| 60 | # TOC base is address-of(.TOC.) + 0x8000. The expected offset is: | ||
| 61 | # 0x10020000(global_a) - 0x10038000(Toc base) = -0x18000(Offset) | ||
| 62 | # which gets materialized into r3 as ((-1 << 16) - 32768). | ||
| 63 | |||
| 64 | # CHECK: Disassembly of section .text: | ||
| 65 | # CHECK-NEXT: _start: | ||
| 66 | # CHECK: 10010008: {{.*}} addis 3, 2, -1 | ||
| 67 | # CHECK-NEXT: 1001000c: {{.*}} addi 3, 3, -32768 | ||
| 68 | |||
| 69 | # CHECK: Disassembly of section .data: | ||
| 70 | # CHECK-NEXT: global_a: | ||
| 71 | # CHECK-NEXT: 10020000: {{.*}} | ||
| 72 | |||
| 73 | # CHECK: Disassembly of section .got: | ||
| 74 | # CHECK-NEXT: .got: | ||
| 75 | # CHECK-NEXT: 10030000: 00 80 03 10 | ||
| 76 | |||
| 77 | |||
| 78 | # CHECK-BE: Disassembly of section .text: | ||
| 79 | # CHECK-BE-NEXT: _start: | ||
| 80 | # CHECK-BE: 10010008: {{.*}} addis 3, 2, -1 | ||
| 81 | # CHECK-BE-NEXT: 1001000c: {{.*}} addi 3, 3, -32768 | ||
| 82 | |||
| 83 | # CHECK-BE: Disassembly of section .data: | ||
| 84 | # CHECK-BE-NEXT: global_a: | ||
| 85 | # CHECK-BE-NEXT: 10020000: {{.*}} | ||
| 86 | |||
| 87 | # CHECK-BE: Disassembly of section .got: | ||
| 88 | # CHECK-BE-NEXT: .got: | ||
| 89 | # CHECK-BE-NEXT: 10030000: 00 00 00 00 | ||
| 90 | # CHECK-BE-NEXT: 10030004: 10 03 80 00 | ||
deps/lld/test/ELF/ppc64-toc-restore.s+52-42| ... | @@ -1,62 +1,72 @@ | ... | @@ -1,62 +1,72 @@ |
| 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: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o | ||
| 6 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 7 | // RUN: ld.lld %t.o %t2.so %t3.o -o %t | ||
| 8 | // RUN: llvm-objdump -d %t | FileCheck %s | ||
| 9 | |||
| 1 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | 10 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o | 11 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o |
| 12 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o | ||
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 13 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld %t.o %t2.so -o %t | 14 | // RUN: ld.lld %t.o %t2.so %t3.o -o %t |
| 5 | // RUN: llvm-objdump -d %t | FileCheck %s | 15 | // RUN: llvm-objdump -d %t | FileCheck %s |
| 6 | // REQUIRES: ppc | ||
| 7 | 16 | ||
| 8 | // CHECK: Disassembly of section .text: | 17 | .text |
| 18 | .abiversion 2 | ||
| 19 | .global bar_local | ||
| 20 | bar_local: | ||
| 21 | li 3, 2 | ||
| 22 | blr | ||
| 9 | 23 | ||
| 24 | # Calling external function foo in a shared object needs a nop. | ||
| 25 | # Calling local function bar_local doe snot need a nop. | ||
| 10 | .global _start | 26 | .global _start |
| 11 | _start: | 27 | _start: |
| 12 | bl bar | 28 | bl foo |
| 13 | nop | 29 | nop |
| 30 | bl bar_local | ||
| 14 | 31 | ||
| 15 | // CHECK: _start: | ||
| 16 | // CHECK: 10010000: 48 00 00 21 bl .+32 | ||
| 17 | // CHECK-NOT: 10010004: 60 00 00 00 nop | ||
| 18 | // CHECK: 10010004: e8 41 00 28 ld 2, 40(1) | ||
| 19 | |||
| 20 | .global noret | ||
| 21 | noret: | ||
| 22 | bl bar | ||
| 23 | li 5, 7 | ||
| 24 | 32 | ||
| 25 | // CHECK: noret: | 33 | // CHECK: Disassembly of section .text: |
| 26 | // CHECK: 10010008: 48 00 00 19 bl .+24 | 34 | // CHECK: _start: |
| 27 | // CHECK: 1001000c: 38 a0 00 07 li 5, 7 | 35 | // CHECK: 1001001c: {{.*}} bl .+67108836 |
| 28 | 36 | // CHECK-NOT: 10010020: {{.*}} nop | |
| 29 | .global noretend | 37 | // CHECK: 10010020: {{.*}} ld 2, 24(1) |
| 30 | noretend: | 38 | // CHECK: 10010024: {{.*}} bl .+67108848 |
| 31 | bl bar | 39 | // CHECK-NOT: 10010028: {{.*}} nop |
| 40 | // CHECK-NOT: 10010028: {{.*}} ld 2, 24(1) | ||
| 32 | 41 | ||
| 33 | // CHECK: noretend: | 42 | # Calling a function in another object file which will have same |
| 34 | // CHECK: 10010010: 48 00 00 11 bl .+16 | 43 | # TOC base does not need a nop. If nop present, do not rewrite to |
| 44 | # a toc restore | ||
| 45 | .global diff_object | ||
| 46 | _diff_object: | ||
| 47 | bl foo_not_shared | ||
| 48 | bl foo_not_shared | ||
| 49 | nop | ||
| 35 | 50 | ||
| 36 | .global noretb | 51 | // CHECK: _diff_object: |
| 37 | noretb: | 52 | // CHECK-NEXT: 10010028: {{.*}} bl .+24 |
| 38 | b bar | 53 | // CHECK-NEXT: 1001002c: {{.*}} bl .+20 |
| 54 | // CHECK-NEXT: 10010030: {{.*}} nop | ||
| 39 | 55 | ||
| 40 | // CHECK: noretb: | 56 | # Branching to a local function does not need a nop |
| 41 | // CHECK: 10010014: 48 00 00 0c b .+12 | 57 | .global noretbranch |
| 58 | noretbranch: | ||
| 59 | b bar_local | ||
| 60 | // CHECK: noretbranch: | ||
| 61 | // CHECK: 10010034: {{.*}} b .+67108832 | ||
| 62 | // CHECK-NOT: 10010038: {{.*}} nop | ||
| 63 | // CHECK-NOT: 1001003c: {{.*}} ld 2, 24(1) | ||
| 42 | 64 | ||
| 43 | // This should come last to check the end-of-buffer condition. | 65 | // This should come last to check the end-of-buffer condition. |
| 44 | .global last | 66 | .global last |
| 45 | last: | 67 | last: |
| 46 | bl bar | 68 | bl foo |
| 47 | nop | 69 | nop |
| 48 | |||
| 49 | // CHECK: last: | 70 | // CHECK: last: |
| 50 | // CHECK: 10010018: 48 00 00 09 bl .+8 | 71 | // CHECK: 10010038: {{.*}} bl .+67108808 |
| 51 | // CHECK: 1001001c: e8 41 00 28 ld 2, 40(1) | 72 | // CHECK-NEXT: 1001003c: {{.*}} ld 2, 24(1) |
| 52 | |||
| 53 | // CHECK: Disassembly of section .plt: | ||
| 54 | // CHECK: .plt: | ||
| 55 | // CHECK: 10010020: f8 41 00 28 std 2, 40(1) | ||
| 56 | // CHECK: 10010024: 3d 62 10 02 addis 11, 2, 4098 | ||
| 57 | // CHECK: 10010028: e9 8b 80 18 ld 12, -32744(11) | ||
| 58 | // CHECK: 1001002c: e9 6c 00 00 ld 11, 0(12) | ||
| 59 | // CHECK: 10010030: 7d 69 03 a6 mtctr 11 | ||
| 60 | // CHECK: 10010034: e8 4c 00 08 ld 2, 8(12) | ||
| 61 | // CHECK: 10010038: e9 6c 00 10 ld 11, 16(12) | ||
| 62 | // CHECK: 1001003c: 4e 80 04 20 bctr |
deps/lld/test/ELF/ppc64-weak-undef-call-shared.s+7-2| ... | @@ -1,7 +1,12 @@ | ... | @@ -1,7 +1,12 @@ |
| 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-readobj -t -r -dyn-symbols %t.so | FileCheck %s | ||
| 6 | |||
| 1 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | 7 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o |
| 2 | # RUN: ld.lld -shared %t.o -o %t.so | 8 | # RUN: ld.lld -shared %t.o -o %t.so |
| 3 | # RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s | 9 | # RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s |
| 4 | # REQUIRES: ppc | ||
| 5 | 10 | ||
| 6 | .section ".toc","aw" | 11 | .section ".toc","aw" |
| 7 | .quad weakfunc | 12 | .quad weakfunc |
| ... | @@ -10,7 +15,7 @@ | ... | @@ -10,7 +15,7 @@ |
| 10 | .text | 15 | .text |
| 11 | .Lfoo: | 16 | .Lfoo: |
| 12 | bl weakfunc | 17 | bl weakfunc |
| 18 | nop | ||
| 13 | // CHECK-NOT: R_PPC64_REL24 | 19 | // CHECK-NOT: R_PPC64_REL24 |
| 14 | 20 | ||
| 15 | .weak weakfunc | 21 | .weak weakfunc |
| 16 |
deps/lld/test/ELF/ppc64-weak-undef-call.s+10-9| ... | @@ -1,17 +1,18 @@ | ... | @@ -1,17 +1,18 @@ |
| 1 | # REQUIRES: ppc | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t | ||
| 4 | # RUN: ld.lld %t -o %t2 | ||
| 5 | # RUN: llvm-objdump -d %t2 | FileCheck %s | ||
| 6 | |||
| 1 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t | 7 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t |
| 2 | # RUN: ld.lld %t -o %t2 | 8 | # RUN: ld.lld %t -o %t2 |
| 3 | # RUN: llvm-objdump -d %t2 | FileCheck %s | 9 | # RUN: llvm-objdump -d %t2 | FileCheck %s |
| 4 | # REQUIRES: ppc | ||
| 5 | 10 | ||
| 6 | # CHECK: Disassembly of section .text: | 11 | # CHECK: Disassembly of section .text: |
| 7 | 12 | ||
| 8 | .section ".opd","aw" | 13 | .text |
| 9 | .global _start | 14 | .global _start |
| 10 | _start: | 15 | _start: |
| 11 | .quad .Lfoo,.TOC.@tocbase,0 | ||
| 12 | |||
| 13 | .text | ||
| 14 | .Lfoo: | ||
| 15 | bl weakfunc | 16 | bl weakfunc |
| 16 | nop | 17 | nop |
| 17 | blr | 18 | blr |
| ... | @@ -22,6 +23,6 @@ _start: | ... | @@ -22,6 +23,6 @@ _start: |
| 22 | # be unreachable. But, we should link successfully. We should not, however, | 23 | # be unreachable. But, we should link successfully. We should not, however, |
| 23 | # generate a .plt entry (this would be wasted space). For now, we do nothing | 24 | # generate a .plt entry (this would be wasted space). For now, we do nothing |
| 24 | # (leaving the zero relative offset present in the input). | 25 | # (leaving the zero relative offset present in the input). |
| 25 | # CHECK: 10010000: 48 00 00 01 bl .+0 | 26 | # CHECK: 10010000: {{.*}} bl .+0 |
| 26 | # CHECK: 10010004: 60 00 00 00 nop | 27 | # CHECK: 10010004: {{.*}} nop |
| 27 | # CHECK: 10010008: 4e 80 00 20 blr | 28 | # CHECK: 10010008: {{.*}} blr |
deps/lld/test/ELF/ppc64_entry_point.s created+50| ... | @@ -0,0 +1,50 @@ | ||
| 1 | # REQUIRES: ppc | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t | ||
| 4 | # RUN: ld.lld %t -o %t2 | ||
| 5 | # RUN: llvm-objdump -D %t2 | FileCheck %s | ||
| 6 | |||
| 7 | # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t | ||
| 8 | # RUN: ld.lld %t -o %t2 | ||
| 9 | # RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s | ||
| 10 | |||
| 11 | .text | ||
| 12 | .abiversion 2 | ||
| 13 | .globl _start | ||
| 14 | .p2align 4 | ||
| 15 | .type _start,@function | ||
| 16 | |||
| 17 | _start: | ||
| 18 | .Lfunc_begin0: | ||
| 19 | .Lfunc_gep0: | ||
| 20 | lis 4, .Lfunc_gep0@ha | ||
| 21 | addi 4, 4, .Lfunc_gep0@l | ||
| 22 | # now r4 should contain the address of _start | ||
| 23 | |||
| 24 | lis 5, .TOC.-.Lfunc_gep0@ha | ||
| 25 | addi 5, 5, .TOC.-.Lfunc_gep0@l | ||
| 26 | # now r5 should contain the offset s.t. r4 + r5 = TOC base | ||
| 27 | |||
| 28 | # exit 55 | ||
| 29 | li 0, 1 | ||
| 30 | li 3, 55 | ||
| 31 | sc | ||
| 32 | .Lfunc_end0: | ||
| 33 | .size _start, .Lfunc_end0-.Lfunc_begin0 | ||
| 34 | |||
| 35 | // CHECK: 10010000: {{.*}} lis 4, 4097 | ||
| 36 | // CHECK-NEXT: 10010004: {{.*}} addi 4, 4, 0 | ||
| 37 | // CHECK-NEXT: 10010008: {{.*}} lis 5, 2 | ||
| 38 | // CHECK-NEXT: 1001000c: {{.*}} addi 5, 5, -32768 | ||
| 39 | // CHECK: Disassembly of section .got: | ||
| 40 | // CHECK-NEXT: .got: | ||
| 41 | // CHECK-NEXT: 10020000: 00 80 02 10 | ||
| 42 | |||
| 43 | // CHECK-BE: 10010000: {{.*}} lis 4, 4097 | ||
| 44 | // CHECK-BE-NEXT: 10010004: {{.*}} addi 4, 4, 0 | ||
| 45 | // CHECK-BE-NEXT: 10010008: {{.*}} lis 5, 2 | ||
| 46 | // CHECK-BE-NEXT: 1001000c: {{.*}} addi 5, 5, -32768 | ||
| 47 | // CHECK-BE: Disassembly of section .got: | ||
| 48 | // CHECK-BE-NEXT: .got: | ||
| 49 | // CHECK-BE-NEXT: 10020000: 00 00 00 00 {{.*}} | ||
| 50 | // CHECK-BE-NEXT: 10020004: 10 02 80 00 {{.*}} | ||
deps/lld/test/ELF/pr34660.s+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o | 3 | # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o |
| 4 | # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t | 4 | # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t |
| 5 | # RUN: llvm-objdump %t -d | FileCheck %s --check-prefix=DISASM | 5 | # RUN: llvm-objdump %t -d | FileCheck %s --check-prefix=DISASM |
| 6 | # RUN: llvm-readobj -elf-output-style=GNU %t -t | FileCheck %s --check-prefix=SYM | 6 | # RUN: llvm-readelf %t -t | FileCheck %s --check-prefix=SYM |
| 7 | 7 | ||
| 8 | # It would be much easier to understand/read this test if llvm-objdump would print | 8 | # It would be much easier to understand/read this test if llvm-objdump would print |
| 9 | # the immediates in hex. | 9 | # the immediates in hex. |
deps/lld/test/ELF/pr34872.s+2-1| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t.o | 2 | # RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t.o |
| 2 | # RUN: llvm-mc %p/Inputs/undefined-error.s -filetype=obj \ | 3 | # RUN: llvm-mc %p/Inputs/undefined-error.s -filetype=obj \ |
| 3 | # RUN: -triple=x86_64-pc-linux -o %t2.o | 4 | # RUN: -triple=x86_64-pc-linux -o %t2.o |
| 4 | # RUN: ld.lld -shared %t2.o -o %t2.so | 5 | # RUN: ld.lld -shared %t2.o -o %t2.so |
| 5 | # RUN: not ld.lld %t2.so %t.o 2>&1 | FileCheck %s | 6 | # RUN: not ld.lld %t2.so %t.o -o /dev/null 2>&1 | FileCheck %s |
| 6 | 7 | ||
| 7 | # CHECK: undefined symbol: fmod | 8 | # CHECK: undefined symbol: fmod |
| 8 | # Check we're not emitting other diagnostics for this symbol. | 9 | # Check we're not emitting other diagnostics for this symbol. |
deps/lld/test/ELF/pr36475.s created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "PHDRS {" > %t.script | ||
| 4 | # RUN: echo " ph_text PT_LOAD FLAGS (0x1 | 0x4);" >> %t.script | ||
| 5 | # RUN: echo " ph_data PT_LOAD FLAGS (0x2 | 0x4);" >> %t.script | ||
| 6 | # RUN: echo "}" >> %t.script | ||
| 7 | # RUN: echo "SECTIONS {" >> %t.script | ||
| 8 | # RUN: echo " .text : { *(.text*) } : ph_text" >> %t.script | ||
| 9 | # RUN: echo " . = ALIGN(0x4000);" >> %t.script | ||
| 10 | # RUN: echo " .got.plt : { BYTE(42); *(.got); } : ph_data" >> %t.script | ||
| 11 | # RUN: echo "}" >> %t.script | ||
| 12 | # RUN: ld.lld -T %t.script %t.o -o %t.elf | ||
| 13 | # RUN: llvm-readobj -l -elf-output-style=GNU %t.elf | FileCheck %s | ||
| 14 | |||
| 15 | # CHECK: Section to Segment mapping: | ||
| 16 | # CHECK-NEXT: Segment Sections... | ||
| 17 | # CHECK-NEXT: 00 .text executable | ||
| 18 | # CHECK-NEXT: 01 .got.plt | ||
| 19 | |||
| 20 | .text | ||
| 21 | .globl _start | ||
| 22 | .type _start,@function | ||
| 23 | _start: | ||
| 24 | callq custom_func | ||
| 25 | ret | ||
| 26 | |||
| 27 | .section executable,"ax",@progbits | ||
| 28 | .type custom_func,@function | ||
| 29 | custom_func: | ||
| 30 | ret | ||
deps/lld/test/ELF/pr37735.s created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux-gnu %s -o %t.o | ||
| 3 | # RUN: ld.lld -r %t.o %t.o -o %t1.o | ||
| 4 | # RUN: llvm-objdump -s -section=.bar %t1.o | FileCheck %s | ||
| 5 | |||
| 6 | .section .foo | ||
| 7 | 	.byte 0 | ||
| 8 | |||
| 9 | # CHECK: Contents of section .bar: | ||
| 10 | # CHECK-NEXT: 0000 00000000 01000000 | ||
| 11 | .section .bar | ||
| 12 | 	.dc.a .foo | ||
deps/lld/test/ELF/pre_init_fini_array.s+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2 |
| 3 | // RUN: ld.lld %t2 -o %t2.so -shared | 4 | // RUN: ld.lld %t2 -o %t2.so -shared |
| 4 | // RUN: ld.lld %t %t2.so -o %t2 | 5 | // RUN: ld.lld %t %t2.so -o %t2 |
| 5 | // RUN: llvm-readobj -r -symbols -sections -dynamic-table %t2 | FileCheck %s | 6 | // RUN: llvm-readobj -r -symbols -sections -dynamic-table %t2 | FileCheck %s |
| 6 | // RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s | 7 | // RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s |
| 7 | // REQUIRES: x86 | ||
| 8 | 8 | ||
| 9 | .globl _start | 9 | .globl _start |
| 10 | _start: | 10 | _start: |
deps/lld/test/ELF/pre_init_fini_array_missing.s+18-21| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 | 3 | // RUN: ld.lld %t -o %t2 |
| 3 | // RUN: llvm-objdump -d %t2 | FileCheck %s | 4 | // RUN: llvm-objdump -d %t2 | FileCheck %s |
| 4 | // RUN: ld.lld -pie %t -o %t3 | 5 | // RUN: ld.lld -pie %t -o %t3 |
| 5 | // RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=PIE %s | 6 | // RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=PIE %s |
| 6 | // REQUIRES: x86 | ||
| 7 | 7 | ||
| 8 | .globl _start | 8 | .globl _start |
| 9 | _start: | 9 | _start: |
| ... | @@ -14,30 +14,27 @@ _start: | ... | @@ -14,30 +14,27 @@ _start: |
| 14 | call __fini_array_start | 14 | call __fini_array_start |
| 15 | call __fini_array_end | 15 | call __fini_array_end |
| 16 | 16 | ||
| 17 | // With no .init_array section the symbols resolve to 0 | 17 | // With no .init_array section the symbols resolve to .text. |
| 18 | // 0 - (0x201000 + 5) = -2101253 | 18 | // 0x201000 - (0x201000 + 5) = -5 |
| 19 | // 0 - (0x201005 + 5) = -2101258 | 19 | // 0x201000 - (0x201005 + 5) = -10 |
| 20 | // 0 - (0x20100a + 5) = -2101263 | 20 | // ... |
| 21 | // 0 - (0x20100f + 5) = -2101268 | ||
| 22 | // 0 - (0x201014 + 5) = -2101273 | ||
| 23 | // 0 - (0x201019 + 5) = -2101278 | ||
| 24 | 21 | ||
| 25 | // CHECK: Disassembly of section .text: | 22 | // CHECK: Disassembly of section .text: |
| 26 | // CHECK-NEXT: _start: | 23 | // CHECK-NEXT: _start: |
| 27 | // CHECK-NEXT: 201000: e8 fb ef df ff callq -2101253 | 24 | // CHECK-NEXT: 201000: e8 fb ff ff ff callq -5 |
| 28 | // CHECK-NEXT: 201005: e8 f6 ef df ff callq -2101258 | 25 | // CHECK-NEXT: 201005: e8 f6 ff ff ff callq -10 |
| 29 | // CHECK-NEXT: 20100a: e8 f1 ef df ff callq -2101263 | 26 | // CHECK-NEXT: 20100a: e8 f1 ff ff ff callq -15 |
| 30 | // CHECK-NEXT: 20100f: e8 ec ef df ff callq -2101268 | 27 | // CHECK-NEXT: 20100f: e8 ec ff ff ff callq -20 |
| 31 | // CHECK-NEXT: 201014: e8 e7 ef df ff callq -2101273 | 28 | // CHECK-NEXT: 201014: e8 e7 ff ff ff callq -25 |
| 32 | // CHECK-NEXT: 201019: e8 e2 ef df ff callq -2101278 | 29 | // CHECK-NEXT: 201019: e8 e2 ff ff ff callq -30 |
| 33 | 30 | ||
| 34 | // In position-independent binaries, they resolve to the image base. | 31 | // In position-independent binaries, they resolve to .text too. |
| 35 | 32 | ||
| 36 | // PIE: Disassembly of section .text: | 33 | // PIE: Disassembly of section .text: |
| 37 | // PIE-NEXT: _start: | 34 | // PIE-NEXT: _start: |
| 38 | // PIE-NEXT: 1000:	e8 fb ef ff ff 	callq	-4101 | 35 | // PIE-NEXT: 1000: e8 fb ff ff ff callq -5 |
| 39 | // PIE-NEXT: 1005:	e8 f6 ef ff ff 	callq	-4106 | 36 | // PIE-NEXT: 1005: e8 f6 ff ff ff callq -10 |
| 40 | // PIE-NEXT: 100a:	e8 f1 ef ff ff 	callq	-4111 | 37 | // PIE-NEXT: 100a: e8 f1 ff ff ff callq -15 |
| 41 | // PIE-NEXT: 100f:	e8 ec ef ff ff 	callq	-4116 | 38 | // PIE-NEXT: 100f: e8 ec ff ff ff callq -20 |
| 42 | // PIE-NEXT: 1014:	e8 e7 ef ff ff 	callq	-4121 | 39 | // PIE-NEXT: 1014: e8 e7 ff ff ff callq -25 |
| 43 | // PIE-NEXT: 1019:	e8 e2 ef ff ff 	callq	-4126 | 40 | // PIE-NEXT: 1019: e8 e2 ff ff ff callq -30 |
deps/lld/test/ELF/print-icf.s created+48| ... | @@ -0,0 +1,48 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/print-icf.s -o %t1 | ||
| 5 | # RUN: ld.lld %t %t1 -o %t2 --icf=all --print-icf-sections | FileCheck %s | ||
| 6 | # RUN: ld.lld %t %t1 -o %t2 --icf=all --no-print-icf-sections --print-icf-sections | FileCheck %s | ||
| 7 | # RUN: ld.lld %t %t1 -o %t2 --icf=all --print-icf-sections --no-print-icf-sections | FileCheck -allow-empty -check-prefix=PRINT %s | ||
| 8 | |||
| 9 | # CHECK: selected section {{.*}}:(.text.f2) | ||
| 10 | # CHECK: removing identical section {{.*}}:(.text.f4) | ||
| 11 | # CHECK: removing identical section {{.*}}:(.text.f7) | ||
| 12 | # CHECK: selected section {{.*}}:(.text.f1) | ||
| 13 | # CHECK: removing identical section {{.*}}:(.text.f3) | ||
| 14 | # CHECK: removing identical section {{.*}}:(.text.f5) | ||
| 15 | # CHECK: removing identical section {{.*}}:(.text.f6) | ||
| 16 | |||
| 17 | # PRINT-NOT: selected | ||
| 18 | # PRINT-NOT: removing | ||
| 19 | |||
| 20 | .globl _start, f1, f2 | ||
| 21 | _start: | ||
| 22 | ret | ||
| 23 | |||
| 24 | .section .text.f1, "ax" | ||
| 25 | f1: | ||
| 26 | mov $60, %rax | ||
| 27 | mov $42, %rdi | ||
| 28 | syscall | ||
| 29 | |||
| 30 | .section .text.f2, "ax" | ||
| 31 | f2: | ||
| 32 | mov $0, %rax | ||
| 33 | |||
| 34 | .section .text.f3, "ax" | ||
| 35 | f3: | ||
| 36 | mov $60, %rax | ||
| 37 | mov $42, %rdi | ||
| 38 | syscall | ||
| 39 | |||
| 40 | .section .text.f4, "ax" | ||
| 41 | f4: | ||
| 42 | mov $0, %rax | ||
| 43 | |||
| 44 | .section .text.f5, "ax" | ||
| 45 | f5: | ||
| 46 | mov $60, %rax | ||
| 47 | mov $42, %rdi | ||
| 48 | syscall | ||
deps/lld/test/ELF/program-header-layout.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | # RUN: ld.lld %t -o %t2 | 3 | # RUN: ld.lld %t -o %t2 |
| 3 | # RUN: llvm-readobj -sections -program-headers %t2 | FileCheck %s | 4 | # RUN: llvm-readobj -sections -program-headers %t2 | FileCheck %s |
| 4 | # REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | # Check that different output sections with the same flags are merged into a | 6 | # Check that different output sections with the same flags are merged into a |
| 7 | # single Read/Write PT_LOAD. | 7 | # single Read/Write PT_LOAD. |
deps/lld/test/ELF/protected-data-access.s created+27| ... | @@ -0,0 +1,27 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %p/Inputs/protected-data-access.s -o %t2.o | ||
| 3 | # RUN: ld.lld %t2.o -o %t2.so -shared | ||
| 4 | # RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t.o | ||
| 5 | |||
| 6 | # RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck --check-prefix=ERR %s | ||
| 7 | # ERR: error: cannot preempt symbol: foo | ||
| 8 | |||
| 9 | # RUN: ld.lld --ignore-data-address-equality %t.o %t2.so -o %t | ||
| 10 | # RUN: llvm-readobj --dyn-symbols --relocations %t | FileCheck %s | ||
| 11 | |||
| 12 | # Check that we have a copy relocation. | ||
| 13 | |||
| 14 | # CHECK: R_X86_64_COPY foo 0x0 | ||
| 15 | |||
| 16 | # CHECK: Name: foo | ||
| 17 | # CHECK-NEXT: Value: | ||
| 18 | # CHECK-NEXT: Size: 8 | ||
| 19 | # CHECK-NEXT: Binding: Global | ||
| 20 | # CHECK-NEXT: Type: Object | ||
| 21 | # CHECK-NEXT: Other: | ||
| 22 | # CHECK-NEXT: Section: .bss.rel.ro | ||
| 23 | |||
| 24 | .global _start | ||
| 25 | _start: | ||
| 26 | .quad foo | ||
| 27 | |||
deps/lld/test/ELF/protected-function-access.s created+27| ... | @@ -0,0 +1,27 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %p/Inputs/protected-function-access.s -o %t2.o | ||
| 3 | # RUN: ld.lld %t2.o -o %t2.so -shared | ||
| 4 | # RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t.o | ||
| 5 | |||
| 6 | # RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck --check-prefix=ERR %s | ||
| 7 | # ERR: error: cannot preempt symbol: foo | ||
| 8 | |||
| 9 | # RUN: ld.lld --ignore-function-address-equality %t.o %t2.so -o %t | ||
| 10 | # RUN: llvm-readobj --dyn-symbols --relocations %t | FileCheck %s | ||
| 11 | |||
| 12 | # Check that we have a relocation and an undefined symbol with a non zero address | ||
| 13 | |||
| 14 | # CHECK: R_X86_64_JUMP_SLOT foo 0x0 | ||
| 15 | |||
| 16 | # CHECK: Name: foo | ||
| 17 | # CHECK-NEXT: Value: 0x201020 | ||
| 18 | # CHECK-NEXT: Size: | ||
| 19 | # CHECK-NEXT: Binding: Global | ||
| 20 | # CHECK-NEXT: Type: Function | ||
| 21 | # CHECK-NEXT: Other: | ||
| 22 | # CHECK-NEXT: Section: Undefined | ||
| 23 | |||
| 24 | .global _start | ||
| 25 | _start: | ||
| 26 | .quad foo | ||
| 27 | |||
deps/lld/test/ELF/push-state.s created+36| ... | @@ -0,0 +1,36 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | ||
| 5 | // RUN: %p/Inputs/whole-archive.s -o %t2.o | ||
| 6 | // RUN: rm -f %t.a | ||
| 7 | // RUN: llvm-ar rcs %t.a %t2.o | ||
| 8 | |||
| 9 | // RUN: ld.lld -o %t.exe -push-state -whole-archive %t.a %t1.o -M | \ | ||
| 10 | // RUN: FileCheck -check-prefix=WHOLE %s | ||
| 11 | // WHOLE: _bar | ||
| 12 | |||
| 13 | // RUN: ld.lld -o %t.exe -push-state -whole-archive -pop-state %t.a %t1.o -M | \ | ||
| 14 | // RUN: FileCheck -check-prefix=NO-WHOLE %s | ||
| 15 | // NO-WHOLE-NOT: _bar | ||
| 16 | |||
| 17 | |||
| 18 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t3.o | ||
| 19 | // RUN: ld.lld -shared %t3.o -soname libfoo -o %t.so | ||
| 20 | |||
| 21 | // 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 | ||
| 23 | // AS-NEEDED-NOT: NEEDED Shared library: [libfoo] | ||
| 24 | |||
| 25 | // 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 | ||
| 27 | // NO-AS-NEEDED: NEEDED Shared library: [libfoo] | ||
| 28 | |||
| 29 | |||
| 30 | // RUN: mkdir -p %t.dir | ||
| 31 | // RUN: cp %t.so %t.dir/libfoo.so | ||
| 32 | // RUN: ld.lld -o %t.exe -L%t.dir -push-state -static -pop-state %t1.o -lfoo | ||
| 33 | // RUN: not ld.lld -o %t.exe -L%t.dir -push-state -static %t1.o -lfoo | ||
| 34 | |||
| 35 | .globl _start | ||
| 36 | _start: | ||
deps/lld/test/ELF/rel-addend-with-rela-input.s created+43| ... | @@ -0,0 +1,43 @@ | ||
| 1 | # REQUIRES: mips | ||
| 2 | # Check that we correctly write addends if the output use Elf_Rel but the input | ||
| 3 | # uses Elf_Rela | ||
| 4 | |||
| 5 | # 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 | ||
| 7 | # INPUT-RELA: ElfHeader { | ||
| 8 | # INPUT-RELA: Class: 64-bit | ||
| 9 | # INPUT-RELA: DataEncoding: BigEndian | ||
| 10 | # INPUT-RELA: Section { | ||
| 11 | # INPUT-RELA: Name: .data | ||
| 12 | # INPUT-RELA: SectionData ( | ||
| 13 | # INPUT-RELA-NEXT: 0000: 00000000 00000000 ABCDEF00 12345678 |.............4Vx| | ||
| 14 | # ^--- No addend here since it uses RELA | ||
| 15 | # INPUT-RELA: Relocations [ | ||
| 16 | # INPUT-RELA-NEXT: Section ({{.+}}) .rela.data { | ||
| 17 | # INPUT-RELA-NEXT: 0x0 R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE foo 0x5544 | ||
| 18 | # INPUT-RELA-NEXT: } | ||
| 19 | # INPUT-RELA-NEXT: ] | ||
| 20 | |||
| 21 | # Previously the addend to the dynamic relocation in the .data section was not copied if | ||
| 22 | # the input file used RELA and the output uses REL. Check that it works now: | ||
| 23 | # 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 | ||
| 25 | # RELA-TO-REL: ElfHeader { | ||
| 26 | # RELA-TO-REL: Class: 64-bit | ||
| 27 | # RELA-TO-REL: DataEncoding: BigEndian | ||
| 28 | # RELA-TO-REL: Section { | ||
| 29 | # RELA-TO-REL: Name: .data | ||
| 30 | # RELA-TO-REL: SectionData ( | ||
| 31 | # RELA-TO-REL-NEXT: 0000: 00000000 00005544 ABCDEF00 12345678 |......UD.....4Vx| | ||
| 32 | # ^--- Addend for relocation in .rel.dyn | ||
| 33 | # RELA-TO-REL: Relocations [ | ||
| 34 | # RELA-TO-REL-NEXT: Section ({{.+}}) .rel.dyn { | ||
| 35 | # RELA-TO-REL-NEXT: 0x10000 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE foo 0x0 | ||
| 36 | # RELA-TO-REL-NEXT: } | ||
| 37 | # RELA-TO-REL-NEXT: ] | ||
| 38 | |||
| 39 | .extern foo | ||
| 40 | |||
| 41 | .data | ||
| 42 | .quad foo + 0x5544 | ||
| 43 | .quad 0xabcdef0012345678 | ||
deps/lld/test/ELF/relative-dynamic-reloc-ppc64.s+5-1| ... | @@ -1,7 +1,11 @@ | ... | @@ -1,7 +1,11 @@ |
| 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 | |||
| 1 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | 6 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld -shared %t.o -o %t.so | 7 | // RUN: ld.lld -shared %t.o -o %t.so |
| 3 | // RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s | 8 | // RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s |
| 4 | // REQUIRES: ppc | ||
| 5 | 9 | ||
| 6 | // Test that we create R_PPC64_RELATIVE relocations but don't put any | 10 | // Test that we create R_PPC64_RELATIVE relocations but don't put any |
| 7 | // symbols in the dynamic symbol table. | 11 | // symbols in the dynamic symbol table. |
deps/lld/test/ELF/relocatable-build-id.s created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 3 | # RUN: ld.lld --build-id=0xcafebabe -o %t2.o %t1.o -r | ||
| 4 | # RUN: ld.lld --build-id=0xdeadbeef -o %t.exe %t2.o | ||
| 5 | # RUN: llvm-objdump -s %t.exe | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK-NOT: cafebabe | ||
| 8 | # CHECK: deadbeef | ||
| 9 | |||
| 10 | .global _start | ||
| 11 | _start: | ||
| 12 | ret | ||
deps/lld/test/ELF/relocatable-comdat-multiple.s+4| ... | @@ -8,6 +8,8 @@ | ... | @@ -8,6 +8,8 @@ |
| 8 | # CHECK-NEXT: Group { | 8 | # CHECK-NEXT: Group { |
| 9 | # CHECK-NEXT: Name: .group | 9 | # CHECK-NEXT: Name: .group |
| 10 | # CHECK-NEXT: Index: 2 | 10 | # CHECK-NEXT: Index: 2 |
| 11 | # CHECK-NEXT: Link: 8 | ||
| 12 | # CHECK-NEXT: Info: 1 | ||
| 11 | # CHECK-NEXT: Type: COMDAT | 13 | # CHECK-NEXT: Type: COMDAT |
| 12 | # CHECK-NEXT: Signature: aaa | 14 | # CHECK-NEXT: Signature: aaa |
| 13 | # CHECK-NEXT: Section(s) in group [ | 15 | # CHECK-NEXT: Section(s) in group [ |
| ... | @@ -18,6 +20,8 @@ | ... | @@ -18,6 +20,8 @@ |
| 18 | # CHECK-NEXT: Group { | 20 | # CHECK-NEXT: Group { |
| 19 | # CHECK-NEXT: Name: .group | 21 | # CHECK-NEXT: Name: .group |
| 20 | # CHECK-NEXT: Index: 5 | 22 | # CHECK-NEXT: Index: 5 |
| 23 | # CHECK-NEXT: Link: 8 | ||
| 24 | # CHECK-NEXT: Info: 6 | ||
| 21 | # CHECK-NEXT: Type: COMDAT | 25 | # CHECK-NEXT: Type: COMDAT |
| 22 | # CHECK-NEXT: Signature: bbb | 26 | # CHECK-NEXT: Signature: bbb |
| 23 | # CHECK-NEXT: Section(s) in group [ | 27 | # CHECK-NEXT: Section(s) in group [ |
deps/lld/test/ELF/relocatable-comdat.s+2| ... | @@ -30,6 +30,8 @@ | ... | @@ -30,6 +30,8 @@ |
| 30 | # CHECK-NEXT: Group { | 30 | # CHECK-NEXT: Group { |
| 31 | # CHECK-NEXT: Name: .group | 31 | # CHECK-NEXT: Name: .group |
| 32 | # CHECK-NEXT: Index: 2 | 32 | # CHECK-NEXT: Index: 2 |
| 33 | # CHECK-NEXT: Link: 5 | ||
| 34 | # CHECK-NEXT: Info: 1 | ||
| 33 | # CHECK-NEXT: Type: COMDAT | 35 | # CHECK-NEXT: Type: COMDAT |
| 34 | # CHECK-NEXT: Signature: abc | 36 | # CHECK-NEXT: Signature: abc |
| 35 | # CHECK-NEXT: Section(s) in group [ | 37 | # CHECK-NEXT: Section(s) in group [ |
deps/lld/test/ELF/relocatable-comdat2.s+4| ... | @@ -13,6 +13,8 @@ | ... | @@ -13,6 +13,8 @@ |
| 13 | # CHECK-NEXT: Group { | 13 | # CHECK-NEXT: Group { |
| 14 | # CHECK-NEXT: Name: .group | 14 | # CHECK-NEXT: Name: .group |
| 15 | # CHECK-NEXT: Index: 2 | 15 | # CHECK-NEXT: Index: 2 |
| 16 | # CHECK-NEXT: Link: 7 | ||
| 17 | # CHECK-NEXT: Info: 1 | ||
| 16 | # CHECK-NEXT: Type: COMDAT | 18 | # CHECK-NEXT: Type: COMDAT |
| 17 | # CHECK-NEXT: Signature: bar | 19 | # CHECK-NEXT: Signature: bar |
| 18 | # CHECK-NEXT: Section(s) in group [ | 20 | # CHECK-NEXT: Section(s) in group [ |
| ... | @@ -22,6 +24,8 @@ | ... | @@ -22,6 +24,8 @@ |
| 22 | # CHECK-NEXT: Group { | 24 | # CHECK-NEXT: Group { |
| 23 | # CHECK-NEXT: Name: .group | 25 | # CHECK-NEXT: Name: .group |
| 24 | # CHECK-NEXT: Index: 4 | 26 | # CHECK-NEXT: Index: 4 |
| 27 | # CHECK-NEXT: Link: 7 | ||
| 28 | # CHECK-NEXT: Info: 2 | ||
| 25 | # CHECK-NEXT: Type: COMDAT | 29 | # CHECK-NEXT: Type: COMDAT |
| 26 | # CHECK-NEXT: Signature: zed | 30 | # CHECK-NEXT: Signature: zed |
| 27 | # CHECK-NEXT: Section(s) in group [ | 31 | # CHECK-NEXT: Section(s) in group [ |
deps/lld/test/ELF/relocatable-eh-frame.s+1-1| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | # RUN: ld.lld %t -o %t.so -shared | 5 | # RUN: ld.lld %t -o %t.so -shared |
| 6 | # RUN: llvm-objdump -h %t.so | FileCheck --check-prefix=DSO %s | 6 | # RUN: llvm-objdump -h %t.so | FileCheck --check-prefix=DSO %s |
| 7 | 7 | ||
| 8 | # DSO: .eh_frame 00000030 | 8 | # DSO: .eh_frame 00000034 |
| 9 | 9 | ||
| 10 | # CHECK: Relocations [ | 10 | # CHECK: Relocations [ |
| 11 | # CHECK-NEXT: Section ({{.*}}) .rela.eh_frame { | 11 | # CHECK-NEXT: Section ({{.*}}) .rela.eh_frame { |
deps/lld/test/ELF/relocatable-many-sections.s created+109| ... | @@ -0,0 +1,109 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o | ||
| 3 | # RUN: ld.lld -r %t.o -o %t | ||
| 4 | |||
| 5 | ## Check we are able to link against relocatable file produced. | ||
| 6 | # RUN: ld.lld %t -o %t.out | ||
| 7 | |||
| 8 | ## Check we emit a valid ELF header when | ||
| 9 | ## sections amount is greater than SHN_LORESERVE. | ||
| 10 | # RUN: llvm-readobj -file-headers %t | FileCheck %s --check-prefix=HDR | ||
| 11 | # HDR: ElfHeader { | ||
| 12 | # HDR: SectionHeaderCount: 0 (65543) | ||
| 13 | # HDR-NEXT: StringTableSectionIndex: 65535 (65541) | ||
| 14 | |||
| 15 | ## Check that: | ||
| 16 | ## 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 | ||
| 21 | # RUN: llvm-readelf -sections -symbols %t | FileCheck %s | ||
| 22 | ## [Nr] Name Type Address Off Size ES Flg Lk Inf Al | ||
| 23 | # CHECK: [65538] .bar | ||
| 24 | # CHECK-NEXT: [65539] .symtab SYMTAB 0000000000000000 000040 180078 18 65542 65539 8 | ||
| 25 | # CHECK-NEXT: [65540] .symtab_shndxr SYMTAB SECTION INDICES 0000000000000000 1800b8 040014 04 65539 0 4 | ||
| 26 | # CHECK-NEXT: [65541] .shstrtab STRTAB 0000000000000000 1c00cc 0f0035 00 0 0 1 | ||
| 27 | # CHECK-NEXT: [65542] .strtab STRTAB 0000000000000000 2b0101 00000c 00 | ||
| 28 | # 5) Check we are able to represent symbol foo with section (.bar) index > 0xFF00 (SHN_LORESERVE). | ||
| 29 | # CHECK: GLOBAL DEFAULT 65538 foo | ||
| 30 | |||
| 31 | .macro gen_sections4 x | ||
| 32 | .section a\x | ||
| 33 | .section b\x | ||
| 34 | .section c\x | ||
| 35 | .section d\x | ||
| 36 | .endm | ||
| 37 | |||
| 38 | .macro gen_sections8 x | ||
| 39 | gen_sections4 a\x | ||
| 40 | gen_sections4 b\x | ||
| 41 | .endm | ||
| 42 | |||
| 43 | .macro gen_sections16 x | ||
| 44 | gen_sections8 a\x | ||
| 45 | gen_sections8 b\x | ||
| 46 | .endm | ||
| 47 | |||
| 48 | .macro gen_sections32 x | ||
| 49 | gen_sections16 a\x | ||
| 50 | gen_sections16 b\x | ||
| 51 | .endm | ||
| 52 | |||
| 53 | .macro gen_sections64 x | ||
| 54 | gen_sections32 a\x | ||
| 55 | gen_sections32 b\x | ||
| 56 | .endm | ||
| 57 | |||
| 58 | .macro gen_sections128 x | ||
| 59 | gen_sections64 a\x | ||
| 60 | gen_sections64 b\x | ||
| 61 | .endm | ||
| 62 | |||
| 63 | .macro gen_sections256 x | ||
| 64 | gen_sections128 a\x | ||
| 65 | gen_sections128 b\x | ||
| 66 | .endm | ||
| 67 | |||
| 68 | .macro gen_sections512 x | ||
| 69 | gen_sections256 a\x | ||
| 70 | gen_sections256 b\x | ||
| 71 | .endm | ||
| 72 | |||
| 73 | .macro gen_sections1024 x | ||
| 74 | gen_sections512 a\x | ||
| 75 | gen_sections512 b\x | ||
| 76 | .endm | ||
| 77 | |||
| 78 | .macro gen_sections2048 x | ||
| 79 | gen_sections1024 a\x | ||
| 80 | gen_sections1024 b\x | ||
| 81 | .endm | ||
| 82 | |||
| 83 | .macro gen_sections4096 x | ||
| 84 | gen_sections2048 a\x | ||
| 85 | gen_sections2048 b\x | ||
| 86 | .endm | ||
| 87 | |||
| 88 | .macro gen_sections8192 x | ||
| 89 | gen_sections4096 a\x | ||
| 90 | gen_sections4096 b\x | ||
| 91 | .endm | ||
| 92 | |||
| 93 | .macro gen_sections16384 x | ||
| 94 | gen_sections8192 a\x | ||
| 95 | gen_sections8192 b\x | ||
| 96 | .endm | ||
| 97 | |||
| 98 | gen_sections16384 a | ||
| 99 | gen_sections16384 b | ||
| 100 | gen_sections16384 c | ||
| 101 | gen_sections16384 d | ||
| 102 | |||
| 103 | .section .bar | ||
| 104 | .global foo | ||
| 105 | foo: | ||
| 106 | |||
| 107 | .section .text, "ax" | ||
| 108 | .global _start | ||
| 109 | _start: | ||
deps/lld/test/ELF/relocatable-symbols.s+24-12| ... | @@ -174,21 +174,33 @@ | ... | @@ -174,21 +174,33 @@ |
| 174 | .global _start | 174 | .global _start |
| 175 | .text | 175 | .text |
| 176 | _start: | 176 | _start: |
| 177 | call __start_foo | 177 | .byte 0xe8 |
| 178 | call __stop_foo | 178 | .long __start_foo - . -4 |
| 179 | .byte 0xe8 | ||
| 180 | .long __stop_foo - . -4 | ||
| 179 | 181 | ||
| 180 | call __start_bar | 182 | .byte 0xe8 |
| 181 | call __stop_bar | 183 | .long __start_bar - . -4 |
| 184 | .byte 0xe8 | ||
| 185 | .long __stop_bar - . -4 | ||
| 182 | 186 | ||
| 183 | call __start_doo | 187 | .byte 0xe8 |
| 184 | call __stop_doo | 188 | .long __start_doo - . -4 |
| 189 | .byte 0xe8 | ||
| 190 | .long __stop_doo - . -4 | ||
| 185 | 191 | ||
| 186 | call __preinit_array_start | 192 | .byte 0xe8 |
| 187 | call __preinit_array_end | 193 | .long __preinit_array_start - . -4 |
| 188 | call __init_array_start | 194 | .byte 0xe8 |
| 189 | call __init_array_end | 195 | .long __preinit_array_end - . -4 |
| 190 | call __fini_array_start | 196 | .byte 0xe8 |
| 191 | call __fini_array_end | 197 | .long __init_array_start - . -4 |
| 198 | .byte 0xe8 | ||
| 199 | .long __init_array_end - . -4 | ||
| 200 | .byte 0xe8 | ||
| 201 | .long __fini_array_start - . -4 | ||
| 202 | .byte 0xe8 | ||
| 203 | .long __fini_array_end - . -4 | ||
| 192 | 204 | ||
| 193 | .section foo,"ax" | 205 | .section foo,"ax" |
| 194 | nop | 206 | nop |
deps/lld/test/ELF/relocation-absolute.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/abs.s -o %tabs | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/abs.s -o %tabs |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | // RUN: ld.lld %tabs %t -o %tout | 4 | // RUN: ld.lld %tabs %t -o %tout |
| 4 | // RUN: llvm-objdump -d %tout | FileCheck %s | 5 | // RUN: llvm-objdump -d %tout | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | .global _start | 7 | .global _start |
| 8 | _start: | 8 | _start: |
deps/lld/test/ELF/relocation-common.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %tout | 3 | // RUN: ld.lld %t -o %tout |
| 3 | // RUN: llvm-objdump -t -d %tout | FileCheck %s | 4 | // RUN: llvm-objdump -t -d %tout | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | .global _start | 6 | .global _start |
| 7 | _start: | 7 | _start: |
deps/lld/test/ELF/relocation-dtrace.test+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: yaml2obj %s -o %t.o | 1 | # RUN: yaml2obj %s -o %t.o |
| 2 | # RUN: ld.lld -shared %t.o -o %t.so | 2 | # RUN: ld.lld -shared %t.o -o /dev/null |
| 3 | 3 | ||
| 4 | # Test that we can handle R_X86_64_NONE as produced by dtrace. | 4 | # Test that we can handle R_X86_64_NONE as produced by dtrace. |
| 5 | 5 |
deps/lld/test/ELF/relocation-i686.s+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld --hash-style=sysv %t %t2.so -o %t2 | 5 | // RUN: ld.lld --hash-style=sysv %t %t2.so -o %t2 |
| 5 | // RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=ADDR %s | 6 | // RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=ADDR %s |
| 6 | // RUN: llvm-objdump -d %t2 | FileCheck %s | 7 | // RUN: llvm-objdump -d %t2 | FileCheck %s |
| 7 | // REQUIRES: x86 | ||
| 8 | 8 | ||
| 9 | .global _start | 9 | .global _start |
| 10 | _start: | 10 | _start: |
deps/lld/test/ELF/relocation-local.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // Test that relocation of local symbols is working. | 2 | // Test that relocation of local symbols is working. |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | // RUN: ld.lld %t -o %t2 | 4 | // RUN: ld.lld %t -o %t2 |
| 4 | // RUN: llvm-objdump -s -d %t2 | FileCheck %s | 5 | // RUN: llvm-objdump -s -d %t2 | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | .global _start | 8 | .global _start |
deps/lld/test/ELF/relocation-nocopy.s+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 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/relocation-copy.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o |
| 4 | // RUN: ld.lld -shared %t2.o -o %t.so | 4 | // RUN: ld.lld -shared %t2.o -o %t.so |
| 5 | // RUN: not ld.lld -z nocopyreloc %t.o %t.so -o %t3 2>&1 | FileCheck %s | 5 | // RUN: not ld.lld -z nocopyreloc %t.o %t.so -o /dev/null 2>&1 | FileCheck %s |
| 6 | 6 | ||
| 7 | // CHECK: unresolvable relocation R_X86_64_32S against symbol 'x' | 7 | // CHECK: unresolvable relocation R_X86_64_32S against symbol 'x' |
| 8 | // CHECK: unresolvable relocation R_X86_64_32S against symbol 'y' | 8 | // CHECK: unresolvable relocation R_X86_64_32S against symbol 'y' |
deps/lld/test/ELF/relocation-non-alloc.s+39-17| ... | @@ -1,25 +1,47 @@ | ... | @@ -1,25 +1,47 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | 2 | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 4 | // 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 | ||
| 6 | |||
| 4 | // RUN: ld.lld %t -o %t2 -shared | 7 | // RUN: ld.lld %t -o %t2 -shared |
| 5 | // RUN: llvm-readobj -s -section-data -r %t2 | FileCheck %s | 8 | // RUN: llvm-readobj -s -section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s |
| 9 | // 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 | ||
| 6 | 11 | ||
| 7 | // CHECK: Name: .data | 12 | // APPLYDYNREL: Name: .data |
| 8 | // CHECK-NEXT: Type: SHT_PROGBITS | 13 | // APPLYDYNREL-NEXT: Type: SHT_PROGBITS |
| 9 | // CHECK-NEXT: Flags [ | 14 | // APPLYDYNREL-NEXT: Flags [ |
| 10 | // CHECK-NEXT: SHF_ALLOC | 15 | // APPLYDYNREL-NEXT: SHF_ALLOC |
| 11 | // CHECK-NEXT: SHF_WRITE | 16 | // APPLYDYNREL-NEXT: SHF_WRITE |
| 12 | // CHECK-NEXT: ] | 17 | // APPLYDYNREL-NEXT: ] |
| 13 | // CHECK-NEXT: Address: 0x1000 | 18 | // APPLYDYNREL-NEXT: Address: 0x1000 |
| 14 | // CHECK-NEXT: Offset: 0x1000 | 19 | // APPLYDYNREL-NEXT: Offset: 0x1000 |
| 15 | // CHECK-NEXT: Size: 16 | 20 | // APPLYDYNREL-NEXT: Size: 16 |
| 16 | // CHECK-NEXT: Link: 0 | 21 | // APPLYDYNREL-NEXT: Link: 0 |
| 17 | // CHECK-NEXT: Info: 0 | 22 | // APPLYDYNREL-NEXT: Info: 0 |
| 18 | // CHECK-NEXT: AddressAlignment: 1 | 23 | // APPLYDYNREL-NEXT: AddressAlignment: 1 |
| 19 | // CHECK-NEXT: EntrySize: 0 | 24 | // APPLYDYNREL-NEXT: EntrySize: 0 |
| 20 | // CHECK-NEXT: SectionData ( | 25 | // APPLYDYNREL-NEXT: SectionData ( |
| 21 | // CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 | 26 | // APPLYDYNREL-NEXT: 0000: 00100000 00000000 00000000 00000000 |
| 22 | // CHECK-NEXT: ) | 27 | // APPLYDYNREL-NEXT: ) |
| 28 | |||
| 29 | // NOAPPLYDYNREL: Name: .data | ||
| 30 | // NOAPPLYDYNREL-NEXT: Type: SHT_PROGBITS | ||
| 31 | // NOAPPLYDYNREL-NEXT: Flags [ | ||
| 32 | // NOAPPLYDYNREL-NEXT: SHF_ALLOC | ||
| 33 | // NOAPPLYDYNREL-NEXT: SHF_WRITE | ||
| 34 | // NOAPPLYDYNREL-NEXT: ] | ||
| 35 | // NOAPPLYDYNREL-NEXT: Address: 0x1000 | ||
| 36 | // NOAPPLYDYNREL-NEXT: Offset: 0x1000 | ||
| 37 | // NOAPPLYDYNREL-NEXT: Size: 16 | ||
| 38 | // NOAPPLYDYNREL-NEXT: Link: 0 | ||
| 39 | // NOAPPLYDYNREL-NEXT: Info: 0 | ||
| 40 | // NOAPPLYDYNREL-NEXT: AddressAlignment: 1 | ||
| 41 | // NOAPPLYDYNREL-NEXT: EntrySize: 0 | ||
| 42 | // NOAPPLYDYNREL-NEXT: SectionData ( | ||
| 43 | // NOAPPLYDYNREL-NEXT: 0000: 00000000 00000000 00000000 00000000 | ||
| 44 | // NOAPPLYDYNREL-NEXT: ) | ||
| 23 | 45 | ||
| 24 | // CHECK: Name: foo | 46 | // CHECK: Name: foo |
| 25 | // CHECK-NEXT: Type: SHT_PROGBITS | 47 | // CHECK-NEXT: Type: SHT_PROGBITS |
deps/lld/test/ELF/relocation-none-aarch64.test+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: aarch64 | 1 | # REQUIRES: aarch64 |
| 2 | 2 | ||
| 3 | # RUN: yaml2obj %s -o %t.o | 3 | # RUN: yaml2obj %s -o %t.o |
| 4 | # RUN: ld.lld %t.o -o %t.out | 4 | # RUN: ld.lld %t.o -o /dev/null |
| 5 | 5 | ||
| 6 | !ELF | 6 | !ELF |
| 7 | FileHeader: | 7 | FileHeader: |
deps/lld/test/ELF/relocation-none-i686.test+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: yaml2obj %s -o %t.o | 1 | # RUN: yaml2obj %s -o %t.o |
| 2 | # RUN: ld.lld %t.o -o %t.out | 2 | # RUN: ld.lld %t.o -o /dev/null |
| 3 | 3 | ||
| 4 | # Test that we can handle R_386_NONE. | 4 | # Test that we can handle R_386_NONE. |
| 5 | 5 |
deps/lld/test/ELF/relocation-past-merge-end.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s |
| 4 | // CHECK: relocation-past-merge-end.s.tmp.o:(.foo): entry is past the end of the section | 4 | // CHECK: relocation-past-merge-end.s.tmp.o:(.foo): entry is past the end of the section |
| 5 | 5 | ||
| 6 | .data | 6 | .data |
deps/lld/test/ELF/relocation-relative-absolute.s+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %tinput1.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %tinput1.o |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \ | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \ |
| 4 | # RUN: %S/Inputs/relocation-relative-absolute.s -o %tinput2.o | 4 | # RUN: %S/Inputs/relocation-relative-absolute.s -o %tinput2.o |
| 5 | # RUN: not ld.lld %tinput1.o %tinput2.o -o %t -pie 2>&1 | FileCheck %s | 5 | # RUN: not ld.lld %tinput1.o %tinput2.o -o /dev/null -pie 2>&1 | FileCheck %s |
| 6 | 6 | ||
| 7 | .globl _start | 7 | .globl _start |
| 8 | _start: | 8 | _start: |
deps/lld/test/ELF/relocation-shared.s+3-3| ... | @@ -8,7 +8,7 @@ | ... | @@ -8,7 +8,7 @@ |
| 8 | // CHECK-NEXT: Flags [ | 8 | // CHECK-NEXT: Flags [ |
| 9 | // CHECK-NEXT: SHF_ALLOC | 9 | // CHECK-NEXT: SHF_ALLOC |
| 10 | // CHECK-NEXT: ] | 10 | // CHECK-NEXT: ] |
| 11 | // CHECK-NEXT: Address: 0x1C8 | 11 | // CHECK-NEXT: Address: 0x20D |
| 12 | // CHECK-NEXT: Offset: | 12 | // CHECK-NEXT: Offset: |
| 13 | // CHECK-NEXT: Size: 8 | 13 | // CHECK-NEXT: Size: 8 |
| 14 | // CHECK-NEXT: Link: 0 | 14 | // CHECK-NEXT: Link: 0 |
| ... | @@ -16,8 +16,8 @@ | ... | @@ -16,8 +16,8 @@ |
| 16 | // CHECK-NEXT: AddressAlignment: 1 | 16 | // CHECK-NEXT: AddressAlignment: 1 |
| 17 | // CHECK-NEXT: EntrySize: 0 | 17 | // CHECK-NEXT: EntrySize: 0 |
| 18 | // CHECK-NEXT: SectionData ( | 18 | // CHECK-NEXT: SectionData ( |
| 19 | // CHECK-NEXT: 0000: 380E0000 00000000 | 19 | // CHECK-NEXT: 0000: F30D0000 00000000 |
| 20 | // 0x1000 - 0x1C8 = 0xE38 | 20 | // 0x1000 - 0x20D = 0xDF3 |
| 21 | // CHECK-NEXT: ) | 21 | // CHECK-NEXT: ) |
| 22 | 22 | ||
| 23 | // CHECK: Name: .text | 23 | // CHECK: Name: .text |
deps/lld/test/ELF/relocation-size-err.s+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | // CHECK: error: can't create dynamic relocation R_X86_64_SIZE64 against symbol: foo in readonly segment; recompile object files with -fPIC | 5 | // CHECK: error: can't create dynamic relocation R_X86_64_SIZE64 against symbol: foo in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output |
| 6 | 6 | ||
| 7 | .global foo | 7 | .global foo |
| 8 | foo: | 8 | foo: |
deps/lld/test/ELF/relocation-size-shared.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocation-size-shared.s -o %tso.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocation-size-shared.s -o %tso.o |
| 3 | // RUN: ld.lld -shared %tso.o -o %tso | 4 | // RUN: ld.lld -shared %tso.o -o %tso |
deps/lld/test/ELF/relocation-size.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t1 | 3 | // RUN: ld.lld %t.o -o %t1 |
| 3 | // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s | 4 | // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s |
deps/lld/test/ELF/relocation-undefined-weak.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %tout | 3 | // RUN: ld.lld %t -o %tout |
| 3 | // RUN: llvm-readobj -sections %tout | FileCheck %s | 4 | // RUN: llvm-readobj -sections %tout | FileCheck %s |
| 4 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix DISASM | 5 | // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix DISASM |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // Check that undefined weak symbols are treated as having a VA of 0. | 7 | // Check that undefined weak symbols are treated as having a VA of 0. |
| 8 | 8 |
deps/lld/test/ELF/relocation.s+5-6| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2 |
| 3 | // RUN: ld.lld %t2 -o %t2.so -shared | 4 | // RUN: ld.lld %t2 -soname fixed-length-string.so -o %t2.so -shared |
| 4 | // RUN: ld.lld --hash-style=sysv %t %t2.so -o %t3 | 5 | // RUN: ld.lld --hash-style=sysv %t %t2.so -o %t3 |
| 5 | // RUN: llvm-readobj -s %t3 | FileCheck --check-prefix=SEC %s | 6 | // RUN: llvm-readobj -s %t3 | FileCheck --check-prefix=SEC %s |
| 6 | // RUN: llvm-objdump -s -d %t3 | FileCheck %s | 7 | // RUN: llvm-objdump -s -d %t3 | FileCheck %s |
| 7 | // REQUIRES: x86 | ||
| 8 | 8 | ||
| 9 | // SEC: Name: .plt | 9 | // SEC: Name: .plt |
| 10 | // SEC-NEXT: Type: SHT_PROGBITS | 10 | // SEC-NEXT: Type: SHT_PROGBITS |
| ... | @@ -113,17 +113,16 @@ R_X86_64_64: | ... | @@ -113,17 +113,16 @@ R_X86_64_64: |
| 113 | .quad R_X86_64_64 | 113 | .quad R_X86_64_64 |
| 114 | 114 | ||
| 115 | // CHECK: Contents of section .R_X86_64_64: | 115 | // CHECK: Contents of section .R_X86_64_64: |
| 116 | // CHECK-NEXT: 2001c8 c8012000 00000000 | 116 | // CHECK-NEXT: 2002c0 c0022000 00000000 |
| 117 | 117 | ||
| 118 | .section .R_X86_64_GOTPCREL,"a",@progbits | 118 | .section .R_X86_64_GOTPCREL,"a",@progbits |
| 119 | .global R_X86_64_GOTPCREL | 119 | .global R_X86_64_GOTPCREL |
| 120 | R_X86_64_GOTPCREL: | 120 | R_X86_64_GOTPCREL: |
| 121 | .long zed@gotpcrel | 121 | .long zed@gotpcrel |
| 122 | 122 | ||
| 123 | // 0x2020F8 - 0x2001D8 = 7952 | 123 | // 0x2030F0(.got) - 0x2002c8(.R_X86_64_GOTPCREL) = 0x2e28 |
| 124 | // 7952 = 0x101f0000 in little endian | ||
| 125 | // CHECK: Contents of section .R_X86_64_GOTPCREL | 124 | // CHECK: Contents of section .R_X86_64_GOTPCREL |
| 126 | // CHECK-NEXT: 2001d0 202f0000 | 125 | // CHECK-NEXT: 2002c8 282e0000 |
| 127 | 126 | ||
| 128 | .section .R_X86_64_GOT32,"a",@progbits | 127 | .section .R_X86_64_GOT32,"a",@progbits |
| 129 | .global R_X86_64_GOT32 | 128 | .global R_X86_64_GOT32 |
deps/lld/test/ELF/relro-non-contiguous.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t.o %t2.o -o %t.so | 4 | // RUN: ld.lld -shared %t.o %t2.o -o %t.so |
| ... | @@ -15,7 +16,6 @@ | ... | @@ -15,7 +16,6 @@ |
| 15 | // RUN: not ld.lld %t3.o %t.so -z relro -o %t --script=%t.script 2>&1 | FileCheck %s | 16 | // RUN: not ld.lld %t3.o %t.so -z relro -o %t --script=%t.script 2>&1 | FileCheck %s |
| 16 | // No error when we do not request relro. | 17 | // No error when we do not request relro. |
| 17 | // RUN: ld.lld %t3.o %t.so -z norelro -o %t --script=%t.script | 18 | // RUN: ld.lld %t3.o %t.so -z norelro -o %t --script=%t.script |
| 18 | // REQUIRES: x86 | ||
| 19 | 19 | ||
| 20 | // CHECK: error: section: .bss.rel.ro is not contiguous with other relro sections | 20 | // CHECK: error: section: .bss.rel.ro is not contiguous with other relro sections |
| 21 | .section .text, "ax", @progbits | 21 | .section .text, "ax", @progbits |
deps/lld/test/ELF/relro-omagic.s+3-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | # RUN: ld.lld -shared %t2.o -o %t2.so -soname relro-omagic.s.tmp2.so | 4 | # RUN: ld.lld -shared %t2.o -o %t2.so -soname relro-omagic.s.tmp2.so |
| ... | @@ -13,8 +14,8 @@ | ... | @@ -13,8 +14,8 @@ |
| 13 | # NORELRO-NEXT: 3 .dynstr 00000021 0000000000200188 | 14 | # NORELRO-NEXT: 3 .dynstr 00000021 0000000000200188 |
| 14 | # NORELRO-NEXT: 4 .rela.dyn 00000018 00000000002001b0 | 15 | # NORELRO-NEXT: 4 .rela.dyn 00000018 00000000002001b0 |
| 15 | # NORELRO-NEXT: 5 .rela.plt 00000018 00000000002001c8 | 16 | # NORELRO-NEXT: 5 .rela.plt 00000018 00000000002001c8 |
| 16 | # NORELRO-NEXT: 6 .text 0000000a 00000000002001e0 TEXT DATA | 17 | # NORELRO-NEXT: 6 .text 0000000a 00000000002001e0 TEXT |
| 17 | # NORELRO-NEXT: 7 .plt 00000020 00000000002001f0 TEXT DATA | 18 | # NORELRO-NEXT: 7 .plt 00000020 00000000002001f0 TEXT |
| 18 | # NORELRO-NEXT: 8 .data 00000008 0000000000200210 DATA | 19 | # NORELRO-NEXT: 8 .data 00000008 0000000000200210 DATA |
| 19 | # NORELRO-NEXT: 9 .foo 00000004 0000000000200218 DATA | 20 | # NORELRO-NEXT: 9 .foo 00000004 0000000000200218 DATA |
| 20 | # NORELRO-NEXT: 10 .dynamic 000000f0 0000000000200220 | 21 | # NORELRO-NEXT: 10 .dynamic 000000f0 0000000000200220 |
deps/lld/test/ELF/relro-script.s+1-1| ... | @@ -16,7 +16,7 @@ | ... | @@ -16,7 +16,7 @@ |
| 16 | // RUN: .got.plt : { *(.got.plt) } \ | 16 | // RUN: .got.plt : { *(.got.plt) } \ |
| 17 | // RUN: } " > %t.script | 17 | // RUN: } " > %t.script |
| 18 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o | 18 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o |
| 19 | // RUN: ld.lld %t3.o %t.so -o %t --script=%t.script --print-map | FileCheck %s | 19 | // RUN: ld.lld %t3.o %t.so -o /dev/null --script=%t.script --print-map | FileCheck %s |
| 20 | 20 | ||
| 21 | // CHECK: .data.rel.ro | 21 | // CHECK: .data.rel.ro |
| 22 | // CHECK-NEXT: <internal>:(.bss.rel.ro) | 22 | // CHECK-NEXT: <internal>:(.bss.rel.ro) |
deps/lld/test/ELF/relro.s+7-3| ... | @@ -1,13 +1,17 @@ | ... | @@ -1,13 +1,17 @@ |
| 1 | // REQUIRES: x86 | ||
| 2 | |||
| 1 | // 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 %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 5 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| 4 | // RUN: ld.lld %t.o %t2.so -z now -z relro -o %t | 6 | |
| 7 | // RUN: ld.lld %t.o %t2.so -z now -z norelro -z relro -o %t | ||
| 5 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=FULLRELRO %s | 8 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=FULLRELRO %s |
| 6 | // RUN: ld.lld %t.o %t2.so -z relro -o %t | 9 | |
| 10 | // RUN: ld.lld %t.o %t2.so -z norelro -z relro -o %t | ||
| 7 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=PARTRELRO %s | 11 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=PARTRELRO %s |
| 12 | |||
| 8 | // RUN: ld.lld %t.o %t2.so -z norelro -o %t | 13 | // RUN: ld.lld %t.o %t2.so -z norelro -o %t |
| 9 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=NORELRO %s | 14 | // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=NORELRO %s |
| 10 | // REQUIRES: x86 | ||
| 11 | 15 | ||
| 12 | // CHECK: Program Headers: | 16 | // CHECK: Program Headers: |
| 13 | // CHECK-NEXT: Type | 17 | // CHECK-NEXT: Type |
deps/lld/test/ELF/reproduce-backslash.s+3-3| ... | @@ -2,8 +2,8 @@ | ... | @@ -2,8 +2,8 @@ |
| 2 | 2 | ||
| 3 | # Test that we don't erroneously replace \ with / on UNIX, as it's | 3 | # Test that we don't erroneously replace \ with / on UNIX, as it's |
| 4 | # legal for a filename to contain backslashes. | 4 | # legal for a filename to contain backslashes. |
| 5 | # RUN: llvm-mc %s -o foo\\.o -filetype=obj -triple=x86_64-pc-linux | 5 | # RUN: llvm-mc %s -o %T/foo\\.o -filetype=obj -triple=x86_64-pc-linux |
| 6 | # RUN: ld.lld foo\\.o --reproduce repro.tar | 6 | # RUN: ld.lld %T/foo\\.o --reproduce %T/repro.tar -o /dev/null |
| 7 | # RUN: tar tf repro.tar | FileCheck %s | 7 | # RUN: tar tf %T/repro.tar | FileCheck %s |
| 8 | 8 | ||
| 9 | # CHECK: repro/{{.*}}/foo\\.o | 9 | # CHECK: repro/{{.*}}/foo\\.o |
deps/lld/test/ELF/reproduce-error.s+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # Extracting the tar archive can get over the path limit on windows. | ||
| 2 | # REQUIRES: shell | 1 | # REQUIRES: shell |
| 2 | # Extracting the tar archive can get over the path limit on windows. | ||
| 3 | 3 | ||
| 4 | # RUN: rm -rf %t.dir | 4 | # RUN: rm -rf %t.dir |
| 5 | # RUN: mkdir -p %t.dir | 5 | # RUN: mkdir -p %t.dir |
deps/lld/test/ELF/reproduce.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # REQUIRES: shell | ||
| 2 | 3 | ||
| 3 | # Extracting the tar archive can get over the path limit on windows. | 4 | # Extracting the tar archive can get over the path limit on windows. |
| 4 | # REQUIRES: shell | ||
| 5 | 5 | ||
| 6 | # RUN: rm -rf %t.dir | 6 | # RUN: rm -rf %t.dir |
| 7 | # RUN: mkdir -p %t.dir/build1 | 7 | # RUN: mkdir -p %t.dir/build1 |
deps/lld/test/ELF/resolution-end.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-end.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-end.s -o %t2.o |
| 3 | # RUN: ld.lld -shared -o %t2.so %t2.o | 4 | # RUN: ld.lld -shared -o %t2.so %t2.o |
| 4 | # RUN: ld.lld --hash-style=sysv %t1.o %t2.so -o %t | 5 | # RUN: ld.lld --hash-style=sysv %t1.o %t2.so -o %t |
| 5 | # RUN: llvm-readobj -t -s -section-data %t | FileCheck %s | 6 | # RUN: llvm-readobj -t -s -section-data %t | FileCheck %s |
| 6 | # REQUIRES: x86 | ||
| 7 | 7 | ||
| 8 | # Test that we resolve _end to the this executable. | 8 | # Test that we resolve _end to the this executable. |
| 9 | 9 |
deps/lld/test/ELF/resolution-shared.s+1-1| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-shared.s -o %t2.o |
| 3 | // RUN: ld.lld %t2.o -o %t2.so -shared | 4 | // RUN: ld.lld %t2.o -o %t2.so -shared |
| 4 | // RUN: ld.lld %t.o %t2.so -o %t3 -shared | 5 | // RUN: ld.lld %t.o %t2.so -o %t3 -shared |
| 5 | // RUN: llvm-readobj -t %t3 | FileCheck %s | 6 | // RUN: llvm-readobj -t %t3 | FileCheck %s |
| 6 | // REQUIRES: x86 | ||
| 7 | 7 | ||
| 8 | .weak foo | 8 | .weak foo |
| 9 | foo: | 9 | foo: |
deps/lld/test/ELF/resolution.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2 |
| 3 | // RUN: ld.lld -discard-all %t %t2 -o %t3 | 4 | // RUN: ld.lld -discard-all %t %t2 -o %t3 |
| 4 | // RUN: llvm-readobj -t %t3 | FileCheck %s | 5 | // RUN: llvm-readobj -t %t3 | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // This is an exhaustive test for checking which symbol is kept when two | 7 | // This is an exhaustive test for checking which symbol is kept when two |
| 8 | // have the same name. Each symbol has a different size which is used | 8 | // have the same name. Each symbol has a different size which is used |
deps/lld/test/ELF/rodynamic.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | # RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 2 | # RUN: llvm-mc %p/Inputs/rodynamic.s -o %t.so.o -filetype=obj -triple=x86_64-pc-linux | 3 | # RUN: llvm-mc %p/Inputs/rodynamic.s -o %t.so.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | 4 |
deps/lld/test/ELF/section-align-0.test+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: yaml2obj %s -o %t | 1 | # RUN: yaml2obj %s -o %t |
| 2 | # RUN: ld.lld %t -o %tout | 2 | # RUN: ld.lld %t -o /dev/null |
| 3 | 3 | ||
| 4 | # Verify that lld can handle sections with an alignment of zero. | 4 | # Verify that lld can handle sections with an alignment of zero. |
| 5 | 5 |
deps/lld/test/ELF/section-layout.s+4-3| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | # RUN: ld.lld %t -o %tout | 3 | # RUN: ld.lld %t -o %tout |
| 3 | # RUN: llvm-readobj -sections %tout | FileCheck %s | 4 | # RUN: llvm-readobj -sections %tout | FileCheck %s |
| 4 | # REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | # Check that sections are laid out in the correct order. | 6 | # Check that sections are laid out in the correct order. |
| 7 | 7 | ||
| ... | @@ -26,9 +26,10 @@ _start: | ... | @@ -26,9 +26,10 @@ _start: |
| 26 | .section e,"awT" | 26 | .section e,"awT" |
| 27 | .section d,"ax",@nobits | 27 | .section d,"ax",@nobits |
| 28 | .section c,"ax" | 28 | .section c,"ax" |
| 29 | .section b,"a",@nobits | 29 | .section a,"a",@nobits |
| 30 | .section a,"a" | 30 | .section b,"a" |
| 31 | 31 | ||
| 32 | // For non-executable and non-writable sections, PROGBITS appear after others. | ||
| 32 | // CHECK: Name: a | 33 | // CHECK: Name: a |
| 33 | // CHECK: Name: b | 34 | // CHECK: Name: b |
| 34 | // CHECK: Name: c | 35 | // CHECK: Name: c |
deps/lld/test/ELF/section-metadata-err.s+3-3| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # 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 -o %t.o |
| 4 | # RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s | 4 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | # CHECK: error: a section with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err.s.tmp.o:(.foo) | 6 | # CHECK: error: a section .bar with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err.s.tmp.o:(.foo) |
| 7 | 7 | ||
| 8 | .global _start | 8 | .global _start |
| 9 | _start: | 9 | _start: |
| ... | @@ -12,4 +12,4 @@ _start: | ... | @@ -12,4 +12,4 @@ _start: |
| 12 | .section .foo,"aM",@progbits,8 | 12 | .section .foo,"aM",@progbits,8 |
| 13 | .quad 0 | 13 | .quad 0 |
| 14 | 14 | ||
| 15 | .section bar,"ao",@progbits,.foo | 15 | .section .bar,"ao",@progbits,.foo |
deps/lld/test/ELF/section-metadata-err2.s created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | ## Check we do not crash and report proper errors. | ||
| 7 | # CHECK: error: a section .bar with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err2.s.tmp.o:(.foo) | ||
| 8 | # CHECK: error: a section .bar with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err2.s.tmp.o:(.foo) | ||
| 9 | |||
| 10 | .section .foo,"aM",@progbits,8 | ||
| 11 | .quad 0 | ||
| 12 | |||
| 13 | .section .bar,"ao",@progbits,.foo,unique,1 | ||
| 14 | .quad 0 | ||
| 15 | |||
| 16 | .section .bar,"ao",@progbits,.foo,unique,2 | ||
| 17 | .quad 1 | ||
deps/lld/test/ELF/section-metadata-err3.s created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: error: incompatible section flags for .bar | ||
| 7 | # CHECK-NEXT: >>> {{.*}}section-metadata-err3.s.tmp.o:(.bar): 0x2 | ||
| 8 | # CHECK-NEXT: >>> output section .bar: 0x82 | ||
| 9 | |||
| 10 | .section .foo,"a",@progbits | ||
| 11 | .quad 0 | ||
| 12 | |||
| 13 | .section .bar,"ao",@progbits,.foo,unique,1 | ||
| 14 | .quad 0 | ||
| 15 | |||
| 16 | .section .bar,"a",@progbits,unique,2 | ||
| 17 | .quad 1 | ||
deps/lld/test/ELF/section-name.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | # RUN: ld.lld %t -o %tout | 3 | # RUN: ld.lld %t -o %tout |
| 3 | # RUN: llvm-objdump --section-headers %tout | FileCheck %s | 4 | # RUN: llvm-objdump --section-headers %tout | FileCheck %s |
| 4 | # REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | .global _start | 6 | .global _start |
| 7 | .text | 7 | .text |
deps/lld/test/ELF/section-symbol.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t.so -shared -discard-none | 3 | // RUN: ld.lld %t -o %t.so -shared -discard-none |
| 3 | // RUN: llvm-readobj -t %t.so | FileCheck %s | 4 | // RUN: llvm-readobj -t %t.so | FileCheck %s |
deps/lld/test/ELF/section-symbols.test+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: yaml2obj %s -o %t | 1 | # RUN: yaml2obj %s -o %t |
| 2 | # RUN: ld.lld -shared %t -o %tout | 2 | # RUN: ld.lld -shared %t -o /dev/null |
| 3 | 3 | ||
| 4 | # Verify that lld can handle STT_SECTION symbols associated | 4 | # Verify that lld can handle STT_SECTION symbols associated |
| 5 | # with SHT_REL[A]/SHT_SYMTAB/SHT_STRTAB sections. | 5 | # with SHT_REL[A]/SHT_SYMTAB/SHT_STRTAB sections. |
deps/lld/test/ELF/sectionstart-noallochdr.s+1-1| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | # CHECK: Sections: | 7 | # CHECK: Sections: |
| 8 | # CHECK-NEXT: Idx Name Size Address Type | 8 | # CHECK-NEXT: Idx Name Size Address Type |
| 9 | # CHECK-NEXT: 0 00000000 0000000000000000 | 9 | # CHECK-NEXT: 0 00000000 0000000000000000 |
| 10 | # CHECK-NEXT: 1 .text 00000001 0000000000000010 TEXT DATA | 10 | # CHECK-NEXT: 1 .text 00000001 0000000000000010 TEXT |
| 11 | # CHECK-NEXT: 2 .data 00000004 0000000000000020 DATA | 11 | # CHECK-NEXT: 2 .data 00000004 0000000000000020 DATA |
| 12 | # CHECK-NEXT: 3 .bss 00000004 0000000000000030 BSS | 12 | # CHECK-NEXT: 3 .bss 00000004 0000000000000030 BSS |
| 13 | 13 |
deps/lld/test/ELF/sectionstart.s+4-4| ... | @@ -1,13 +1,13 @@ | ... | @@ -1,13 +1,13 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: ld.lld %t.o --section-start .text=0x100000 \ | 3 | # RUN: ld.lld %t.o --section-start .text=0x100000 \ |
| 4 | # RUN: --section-start .data=0x110000 --section-start .bss=0x200000 -o %t | 4 | # RUN: --section-start=.data=0x110000 --section-start .bss=0x200000 -o %t |
| 5 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | 5 | # RUN: llvm-objdump -section-headers %t | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: Sections: | 7 | # CHECK: Sections: |
| 8 | # CHECK-NEXT: Idx Name Size Address Type | 8 | # CHECK-NEXT: Idx Name Size Address Type |
| 9 | # CHECK-NEXT: 0 00000000 0000000000000000 | 9 | # CHECK-NEXT: 0 00000000 0000000000000000 |
| 10 | # CHECK-NEXT: 1 .text 00000001 0000000000100000 TEXT DATA | 10 | # CHECK-NEXT: 1 .text 00000001 0000000000100000 TEXT |
| 11 | # CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA | 11 | # CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA |
| 12 | # CHECK-NEXT: 3 .bss 00000004 0000000000200000 BSS | 12 | # CHECK-NEXT: 3 .bss 00000004 0000000000200000 BSS |
| 13 | 13 | ||
| ... | @@ -35,11 +35,11 @@ | ... | @@ -35,11 +35,11 @@ |
| 35 | # RUN: llvm-objdump -section-headers %t4 | FileCheck %s | 35 | # RUN: llvm-objdump -section-headers %t4 | FileCheck %s |
| 36 | 36 | ||
| 37 | ## Errors: | 37 | ## Errors: |
| 38 | # RUN: not ld.lld %t.o --section-start .text100000 -o %t2 2>&1 \ | 38 | # RUN: not ld.lld %t.o --section-start .text100000 -o /dev/null 2>&1 \ |
| 39 | # RUN: | FileCheck -check-prefix=ERR1 %s | 39 | # RUN: | FileCheck -check-prefix=ERR1 %s |
| 40 | # ERR1: invalid argument: --section-start .text100000 | 40 | # ERR1: invalid argument: --section-start .text100000 |
| 41 | 41 | ||
| 42 | # RUN: not ld.lld %t.o --section-start .text=1Q0000 -o %t3 2>&1 \ | 42 | # RUN: not ld.lld %t.o --section-start .text=1Q0000 -o /dev/null 2>&1 \ |
| 43 | # RUN: | FileCheck -check-prefix=ERR2 %s | 43 | # RUN: | FileCheck -check-prefix=ERR2 %s |
| 44 | # ERR2: invalid argument: --section-start .text=1Q0000 | 44 | # ERR2: invalid argument: --section-start .text=1Q0000 |
| 45 | 45 |
deps/lld/test/ELF/shared-be.s deleted-37| ... | @@ -1,37 +0,0 @@ | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared.s -o %t2.o | ||
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 4 | // RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t | ||
| 5 | // RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s | ||
| 6 | // REQUIRES: ppc | ||
| 7 | |||
| 8 | // CHECK: Name: .rela.dyn | ||
| 9 | // CHECK-NEXT: Type: SHT_REL | ||
| 10 | // CHECK-NEXT: Flags [ | ||
| 11 | // CHECK-NEXT: SHF_ALLOC | ||
| 12 | // CHECK-NEXT: ] | ||
| 13 | // CHECK-NEXT: Address: [[RELADDR:.*]] | ||
| 14 | // CHECK-NEXT: Offset: | ||
| 15 | // CHECK-NEXT: Size: [[RELSIZE:.*]] | ||
| 16 | // CHECK-NEXT: Link: | ||
| 17 | // CHECK-NEXT: Info: | ||
| 18 | // CHECK-NEXT: AddressAlignment: | ||
| 19 | // CHECK-NEXT: EntrySize: [[RELENT:.*]] | ||
| 20 | |||
| 21 | // CHECK: DynamicSection [ | ||
| 22 | // CHECK-NEXT: Tag Type Name/Value | ||
| 23 | // CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar | ||
| 24 | // CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so] | ||
| 25 | // CHECK-NEXT: 0x0000000000000015 DEBUG 0x0 | ||
| 26 | // CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]] | ||
| 27 | // CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes) | ||
| 28 | // CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes) | ||
| 29 | // CHECK: 0x0000000000000000 NULL 0x0 | ||
| 30 | // CHECK-NEXT: ] | ||
| 31 | |||
| 32 | .global _start | ||
| 33 | _start: | ||
| 34 | .data | ||
| 35 | .long bar | ||
| 36 | .long zed | ||
| 37 | |||
deps/lld/test/ELF/shared-lazy.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o |
| 2 | // RUN: rm -f %t1.a | 3 | // RUN: rm -f %t1.a |
| 3 | // RUN: llvm-ar rc %t1.a %t1.o | 4 | // RUN: llvm-ar rc %t1.a %t1.o |
deps/lld/test/ELF/shared-ppc64.s created+44| ... | @@ -0,0 +1,44 @@ | ||
| 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.s -o %t2.o | ||
| 5 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 6 | // 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 | ||
| 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.s -o %t2.o | ||
| 11 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 12 | // 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 | ||
| 14 | |||
| 15 | // CHECK: Name: .rela.dyn | ||
| 16 | // CHECK-NEXT: Type: SHT_REL | ||
| 17 | // CHECK-NEXT: Flags [ | ||
| 18 | // CHECK-NEXT: SHF_ALLOC | ||
| 19 | // CHECK-NEXT: ] | ||
| 20 | // CHECK-NEXT: Address: [[RELADDR:.*]] | ||
| 21 | // CHECK-NEXT: Offset: | ||
| 22 | // CHECK-NEXT: Size: [[RELSIZE:.*]] | ||
| 23 | // CHECK-NEXT: Link: | ||
| 24 | // CHECK-NEXT: Info: | ||
| 25 | // CHECK-NEXT: AddressAlignment: | ||
| 26 | // CHECK-NEXT: EntrySize: [[RELENT:.*]] | ||
| 27 | |||
| 28 | // CHECK: DynamicSection [ | ||
| 29 | // CHECK-NEXT: Tag Type Name/Value | ||
| 30 | // CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar | ||
| 31 | // CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so] | ||
| 32 | // CHECK-NEXT: 0x0000000000000015 DEBUG 0x0 | ||
| 33 | // CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]] | ||
| 34 | // CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes) | ||
| 35 | // CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes) | ||
| 36 | // CHECK: 0x0000000000000000 NULL 0x0 | ||
| 37 | // CHECK-NEXT: ] | ||
| 38 | |||
| 39 | .global _start | ||
| 40 | _start: | ||
| 41 | .data | ||
| 42 | .long bar | ||
| 43 | .long zed | ||
| 44 | |||
deps/lld/test/ELF/shared.s+3-6| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o |
| 3 | // RUN: ld.lld --hash-style=sysv -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld --hash-style=sysv -shared %t2.o -o %t2.so |
| ... | @@ -6,7 +7,6 @@ | ... | @@ -6,7 +7,6 @@ |
| 6 | // 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 -t -s -dyn-symbols -section-data -hash-table %t | FileCheck %s |
| 7 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so %t2.so -o %t2 | 8 | // RUN: ld.lld --hash-style=sysv %t.o %t2.so %t2.so -o %t2 |
| 8 | // RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s | 9 | // RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s |
| 9 | // REQUIRES: x86 | ||
| 10 | 10 | ||
| 11 | // Make sure .symtab is properly aligned. | 11 | // Make sure .symtab is properly aligned. |
| 12 | // SO: Name: .symtab | 12 | // SO: Name: .symtab |
| ... | @@ -73,8 +73,8 @@ | ... | @@ -73,8 +73,8 @@ |
| 73 | // CHECK-NEXT: Info: 0 | 73 | // CHECK-NEXT: Info: 0 |
| 74 | // CHECK-NEXT: AddressAlignment: 4 | 74 | // CHECK-NEXT: AddressAlignment: 4 |
| 75 | // CHECK-NEXT: EntrySize: 4 | 75 | // CHECK-NEXT: EntrySize: 4 |
| 76 | 76 | // CHECK: Section { | |
| 77 | // CHECK: Index: [[DYNSTR]] | 77 | // CHECK-NEXT: Index: [[DYNSTR]] |
| 78 | // CHECK-NEXT: Name: .dynstr | 78 | // CHECK-NEXT: Name: .dynstr |
| 79 | // CHECK-NEXT: Type: SHT_STRTAB | 79 | // CHECK-NEXT: Type: SHT_STRTAB |
| 80 | // CHECK-NEXT: Flags [ | 80 | // CHECK-NEXT: Flags [ |
| ... | @@ -87,9 +87,6 @@ | ... | @@ -87,9 +87,6 @@ |
| 87 | // CHECK-NEXT: Info: 0 | 87 | // CHECK-NEXT: Info: 0 |
| 88 | // CHECK-NEXT: AddressAlignment: 1 | 88 | // CHECK-NEXT: AddressAlignment: 1 |
| 89 | // CHECK-NEXT: EntrySize: 0 | 89 | // CHECK-NEXT: EntrySize: 0 |
| 90 | // CHECK-NEXT: SectionData ( | ||
| 91 | // CHECK: ) | ||
| 92 | // CHECK-NEXT: } | ||
| 93 | 90 | ||
| 94 | // CHECK: Name: .rel.dyn | 91 | // CHECK: Name: .rel.dyn |
| 95 | // CHECK-NEXT: Type: SHT_REL | 92 | // CHECK-NEXT: Type: SHT_REL |
deps/lld/test/ELF/shlib-undefined-archive.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # Undefined symbols in a DSO should pull out object files from archives | ||
| 4 | # to resolve them. | ||
| 5 | |||
| 6 | # RUN: echo '.globl foo' | llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t1.o - | ||
| 7 | # RUN: ld.lld -shared -o %t.so %t1.o | ||
| 8 | |||
| 9 | # RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t2.o %s | ||
| 10 | # RUN: rm -f %t.a | ||
| 11 | # RUN: llvm-ar cru %t.a %t2.o | ||
| 12 | # RUN: ld.lld -o %t.exe %t.so %t.a | ||
| 13 | # RUN: llvm-nm -D %t.exe | FileCheck %s | ||
| 14 | |||
| 15 | # CHECK: T foo | ||
| 16 | |||
| 17 | .globl foo | ||
| 18 | foo: | ||
| 19 | ret | ||
deps/lld/test/ELF/shlib-undefined-local.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t1.o %S/Inputs/shlib-undefined-ref.s | ||
| 4 | # RUN: ld.lld -shared -o %t.so %t1.o | ||
| 5 | |||
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t2.o %s | ||
| 7 | # RUN: echo "{ local: *; };" > %t.script | ||
| 8 | # RUN: ld.lld -version-script %t.script -o %t %t2.o %t.so | ||
| 9 | # RUN: llvm-nm -g %t | FileCheck -allow-empty %s | ||
| 10 | |||
| 11 | # CHECK-NOT: should_not_be_exported | ||
| 12 | |||
| 13 | .globl should_not_be_exported | ||
| 14 | should_not_be_exported: | ||
| 15 | 	ret | ||
| 16 | |||
| 17 | .globl _start | ||
| 18 | _start: | ||
| 19 | 	ret | ||
deps/lld/test/ELF/sht-group-gold-r.test+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # GNU gold 1.14 (the newest version as of July 2017) seems to create | 2 | # GNU gold 1.14 (the newest version as of July 2017) seems to create |
| 2 | # non-standard-compliant SHT_GROUP sections when the -r option is given. | 3 | # non-standard-compliant SHT_GROUP sections when the -r option is given. |
| 3 | # | 4 | # |
deps/lld/test/ELF/silent-ignore.test-1| ... | @@ -1,6 +1,5 @@ | ... | @@ -1,6 +1,5 @@ |
| 1 | RUN: ld.lld --version \ | 1 | RUN: ld.lld --version \ |
| 2 | RUN: -allow-shlib-undefined \ | 2 | RUN: -allow-shlib-undefined \ |
| 3 | RUN: -cref \ | ||
| 4 | RUN: -g \ | 3 | RUN: -g \ |
| 5 | RUN: -no-add-needed \ | 4 | RUN: -no-add-needed \ |
| 6 | RUN: -no-allow-shlib-undefined \ | 5 | RUN: -no-allow-shlib-undefined \ |
deps/lld/test/ELF/soname.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -shared -soname=bar -o %t.so | 3 | // RUN: ld.lld %t.o -shared -soname=bar -o %t.so |
| 3 | // RUN: ld.lld %t.o -shared --soname=bar -o %t2.so | 4 | // RUN: ld.lld %t.o -shared --soname=bar -o %t2.so |
deps/lld/test/ELF/soname2.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -shared -soname=foo.so -o %t | 3 | // RUN: ld.lld %t.o -shared -soname=foo.so -o %t |
| 3 | // RUN: llvm-readobj --dynamic-table %t | FileCheck %s | 4 | // RUN: llvm-readobj --dynamic-table %t | FileCheck %s |
deps/lld/test/ELF/sort-norosegment.s+5-5| ... | @@ -1,13 +1,13 @@ | ... | @@ -1,13 +1,13 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | 3 | ||
| 4 | # RUN: ld.lld --hash-style=sysv -no-rosegment -o %t1 %t -shared | 4 | # RUN: ld.lld --hash-style=sysv -no-rosegment -o %t %t.o -shared |
| 5 | # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s | 5 | # RUN: llvm-readelf -s %t | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: .text {{.*}} AX | 7 | # CHECK: .dynsym {{.*}} A |
| 8 | # CHECK-NEXT: .dynsym {{.*}} A | ||
| 9 | # CHECK-NEXT: .hash {{.*}} A | 8 | # CHECK-NEXT: .hash {{.*}} A |
| 10 | # CHECK-NEXT: .dynstr {{.*}} A | 9 | # CHECK-NEXT: .dynstr {{.*}} A |
| 10 | # CHECK-NEXT: .text {{.*}} AX | ||
| 11 | # CHECK-NEXT: foo {{.*}} WA | 11 | # CHECK-NEXT: foo {{.*}} WA |
| 12 | # CHECK-NEXT: .dynamic {{.*}} WA | 12 | # CHECK-NEXT: .dynamic {{.*}} WA |
| 13 | 13 |
deps/lld/test/ELF/splitstacks.s deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 3 | |||
| 4 | # RUN: not ld.lld %t1.o -o %t 2>&1 | FileCheck %s | ||
| 5 | # CHECK: .o: object file compiled with -fsplit-stack is not supported | ||
| 6 | |||
| 7 | .globl _start | ||
| 8 | _start: | ||
| 9 | nop | ||
| 10 | |||
| 11 | .section .note.GNU-split-stack,"",@progbits | ||
deps/lld/test/ELF/start-lib.s+9| ... | @@ -21,5 +21,14 @@ | ... | @@ -21,5 +21,14 @@ |
| 21 | // TEST3-NOT: Name: bar | 21 | // TEST3-NOT: Name: bar |
| 22 | // TEST3-NOT: Name: foo | 22 | // TEST3-NOT: Name: foo |
| 23 | 23 | ||
| 24 | // RUN: not ld.lld %t1.o --start-lib --start-lib 2>&1 | FileCheck -check-prefix=NESTED-LIB %s | ||
| 25 | // NESTED-LIB: nested --start-lib | ||
| 26 | |||
| 27 | // RUN: not ld.lld %t1.o --start-group --start-lib 2>&1 | FileCheck -check-prefix=LIB-IN-GROUP %s | ||
| 28 | // LIB-IN-GROUP: may not nest --start-lib in --start-group | ||
| 29 | |||
| 30 | // RUN: not ld.lld --end-lib 2>&1 | FileCheck -check-prefix=END %s | ||
| 31 | // END: stray --end-lib | ||
| 32 | |||
| 24 | .globl _start | 33 | .globl _start |
| 25 | _start: | 34 | _start: |
deps/lld/test/ELF/startstop-shared.s+17-5| ... | @@ -11,18 +11,30 @@ | ... | @@ -11,18 +11,30 @@ |
| 11 | .quad __start_bar | 11 | .quad __start_bar |
| 12 | .section bar,"a" | 12 | .section bar,"a" |
| 13 | 13 | ||
| 14 | // Test that we are able to hide the symbol. | 14 | // CHECK: Relocations [ |
| 15 | // CHECK: R_X86_64_RELATIVE - 0x[[ADDR:.*]] | 15 | // CHECK-NEXT: Section {{.*}} .rela.dyn { |
| 16 | // CHECK-NEXT: R_X86_64_RELATIVE | ||
| 17 | // CHECK-NEXT: R_X86_64_RELATIVE | ||
| 18 | // CHECK-NEXT: } | ||
| 19 | // CHECK-NEXT: ] | ||
| 16 | 20 | ||
| 17 | // By default the symbol is visible and we need a dynamic reloc. | 21 | // Test that we are able to hide the symbol. |
| 18 | // CHECK: R_X86_64_64 __start_foo 0x0 | 22 | // By default the symbol is protected. |
| 19 | 23 | ||
| 20 | // CHECK: Name: __start_bar | 24 | // CHECK: Name: __start_bar |
| 21 | // CHECK-NEXT: Value: 0x[[ADDR]] | 25 | // CHECK-NEXT: Value: |
| 22 | // CHECK-NEXT: Size: | 26 | // CHECK-NEXT: Size: |
| 23 | // CHECK-NEXT: Binding: Local | 27 | // CHECK-NEXT: Binding: Local |
| 28 | // CHECK-NEXT: Type: None | ||
| 29 | // CHECK-NEXT: Other [ | ||
| 30 | // CHECK-NEXT: STV_HIDDEN | ||
| 31 | // CHECK-NEXT: ] | ||
| 24 | 32 | ||
| 25 | // CHECK: Name: __start_foo | 33 | // CHECK: Name: __start_foo |
| 26 | // CHECK-NEXT: Value: | 34 | // CHECK-NEXT: Value: |
| 27 | // CHECK-NEXT: Size: | 35 | // CHECK-NEXT: Size: |
| 28 | // CHECK-NEXT: Binding: Global | 36 | // CHECK-NEXT: Binding: Global |
| 37 | // CHECK-NEXT: Type: None | ||
| 38 | // CHECK-NEXT: Other [ | ||
| 39 | // CHECK-NEXT: STV_PROTECTED | ||
| 40 | // CHECK-NEXT: ] |
deps/lld/test/ELF/startstop.s+7-8| ... | @@ -19,13 +19,12 @@ | ... | @@ -19,13 +19,12 @@ |
| 19 | // DISASM: 1013: 90 nop | 19 | // DISASM: 1013: 90 nop |
| 20 | // DISASM: 1014: 90 nop | 20 | // DISASM: 1014: 90 nop |
| 21 | 21 | ||
| 22 | |||
| 23 | // SYMBOL: Relocations [ | 22 | // SYMBOL: Relocations [ |
| 24 | // SYMBOL-NEXT: Section ({{.*}}) .rela.dyn { | 23 | // SYMBOL-NEXT: Section ({{.*}}) .rela.dyn { |
| 25 | // SYMBOL-NEXT: 0x2010 R_X86_64_64 __stop_zed1 0x0 | 24 | // SYMBOL-NEXT: R_X86_64_RELATIVE |
| 26 | // SYMBOL-NEXT: 0x2018 R_X86_64_64 __stop_zed1 0x1 | 25 | // SYMBOL-NEXT: R_X86_64_RELATIVE |
| 27 | // SYMBOL-NEXT: 0x2000 R_X86_64_64 __stop_zed2 0x0 | 26 | // SYMBOL-NEXT: R_X86_64_RELATIVE |
| 28 | // SYMBOL-NEXT: 0x2008 R_X86_64_64 __stop_zed2 0x1 | 27 | // SYMBOL-NEXT: R_X86_64_RELATIVE |
| 29 | // SYMBOL-NEXT: } | 28 | // SYMBOL-NEXT: } |
| 30 | // SYMBOL-NEXT: ] | 29 | // SYMBOL-NEXT: ] |
| 31 | 30 | ||
| ... | @@ -45,20 +44,20 @@ | ... | @@ -45,20 +44,20 @@ |
| 45 | // SYMBOL: Symbol { | 44 | // SYMBOL: Symbol { |
| 46 | // SYMBOL: Name: __stop_foo | 45 | // SYMBOL: Name: __stop_foo |
| 47 | // SYMBOL: Value: 0x1012 | 46 | // SYMBOL: Value: 0x1012 |
| 48 | // STMBOL: STV_HIDDEN | 47 | // SYMBOL: STV_HIDDEN |
| 49 | // SYMBOL: Section: foo | 48 | // SYMBOL: Section: foo |
| 50 | // SYMBOL: } | 49 | // SYMBOL: } |
| 51 | 50 | ||
| 52 | // SYMBOL: Symbol { | 51 | // SYMBOL: Symbol { |
| 53 | // SYMBOL: Name: __stop_zed1 | 52 | // SYMBOL: Name: __stop_zed1 |
| 54 | // SYMBOL: Value: 0x2010 | 53 | // SYMBOL: Value: 0x2010 |
| 55 | // STMBOL: Other: 0 | 54 | // SYMBOL: STV_PROTECTED |
| 56 | // SYMBOL: Section: zed1 | 55 | // SYMBOL: Section: zed1 |
| 57 | // SYMBOL: } | 56 | // SYMBOL: } |
| 58 | // SYMBOL: Symbol { | 57 | // SYMBOL: Symbol { |
| 59 | // SYMBOL: Name: __stop_zed2 | 58 | // SYMBOL: Name: __stop_zed2 |
| 60 | // SYMBOL: Value: 0x2020 | 59 | // SYMBOL: Value: 0x2020 |
| 61 | // STMBOL: Other: 0 | 60 | // SYMBOL: STV_PROTECTED |
| 62 | // SYMBOL: Section: zed2 | 61 | // SYMBOL: Section: zed2 |
| 63 | // SYMBOL: } | 62 | // SYMBOL: } |
| 64 | 63 |
deps/lld/test/ELF/static-with-export-dynamic.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-cloudabi %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-unknown-cloudabi %s -o %t.o |
| 2 | // RUN: ld.lld --export-dynamic %t.o -o %t | 3 | // RUN: ld.lld --export-dynamic %t.o -o %t |
| 3 | // RUN: llvm-readobj -dyn-symbols %t | FileCheck %s | 4 | // RUN: llvm-readobj -dyn-symbols %t | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | // Ensure that a dynamic symbol table is present when --export-dynamic | 6 | // Ensure that a dynamic symbol table is present when --export-dynamic |
| 7 | // is passed in, even when creating statically linked executables. | 7 | // is passed in, even when creating statically linked executables. |
deps/lld/test/ELF/string-gc.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t --gc-sections | 3 | // RUN: ld.lld %t.o -o %t --gc-sections |
| 3 | // RUN: llvm-readobj -symbols %t | FileCheck %s | 4 | // RUN: llvm-readobj -symbols %t | FileCheck %s |
deps/lld/test/ELF/string-table.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 | 3 | // RUN: ld.lld %t -o %t2 |
| 3 | // RUN: llvm-readobj -sections %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -sections %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | .global _start | 6 | .global _start |
| 7 | _start: | 7 | _start: |
deps/lld/test/ELF/symbol-ordering-file-icf.s created+32| ... | @@ -0,0 +1,32 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: echo "zed" > %t.order | ||
| 4 | # RUN: echo "bar" >> %t.order | ||
| 5 | # RUN: echo "foo" >> %t.order | ||
| 6 | # RUN: ld.lld --icf=all --symbol-ordering-file %t.order -shared %t.o -o %t.so | ||
| 7 | # RUN: llvm-nm %t.so | FileCheck %s | ||
| 8 | |||
| 9 | ## Check that after ICF merges 'foo' and 'zed' we still | ||
| 10 | ## place them before 'bar', in according to ordering file. | ||
| 11 | # CHECK-DAG: 0000000000001000 T foo | ||
| 12 | # CHECK-DAG: 0000000000001000 T zed | ||
| 13 | # CHECK-DAG: 0000000000001004 T bar | ||
| 14 | |||
| 15 | .section .text.foo,"ax",@progbits | ||
| 16 | .align 4 | ||
| 17 | .global foo | ||
| 18 | foo: | ||
| 19 | retq | ||
| 20 | |||
| 21 | .section .text.bar,"ax",@progbits | ||
| 22 | .align 4 | ||
| 23 | .global bar | ||
| 24 | bar: | ||
| 25 | nop | ||
| 26 | retq | ||
| 27 | |||
| 28 | .section .text.zed,"ax",@progbits | ||
| 29 | .align 4 | ||
| 30 | .global zed | ||
| 31 | zed: | ||
| 32 | retq | ||
deps/lld/test/ELF/symbol-ordering-file-warnings.s created+165| ... | @@ -0,0 +1,165 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symbol-ordering-file-warnings1.s -o %t2.o | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symbol-ordering-file-warnings2.s -o %t3.o | ||
| 5 | # RUN: ld.lld -shared %t2.o -o %t.so | ||
| 6 | |||
| 7 | # Check that a warning is emitted for entries in the file that are not present in any used input. | ||
| 8 | # RUN: echo "missing" > %t-order-missing.txt | ||
| 9 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-missing.txt \ | ||
| 10 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,MISSING | ||
| 11 | |||
| 12 | # Check that the warning can be disabled. | ||
| 13 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-missing.txt \ | ||
| 14 | # RUN: --unresolved-symbols=ignore-all --no-warn-symbol-ordering 2>&1 | \ | ||
| 15 | # RUN: FileCheck %s --check-prefixes=WARN --allow-empty | ||
| 16 | |||
| 17 | # Check that the warning can be re-enabled | ||
| 18 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-missing.txt \ | ||
| 19 | # RUN: --unresolved-symbols=ignore-all --no-warn-symbol-ordering --warn-symbol-ordering 2>&1 | \ | ||
| 20 | # RUN: FileCheck %s --check-prefixes=WARN,MISSING | ||
| 21 | |||
| 22 | # Check that a warning is emitted for undefined symbols. | ||
| 23 | # RUN: echo "undefined" > %t-order-undef.txt | ||
| 24 | # RUN: ld.lld %t1.o %t3.o -o %t --symbol-ordering-file %t-order-undef.txt \ | ||
| 25 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,UNDEFINED | ||
| 26 | |||
| 27 | # Check that a warning is emitted for imported shared symbols. | ||
| 28 | # RUN: echo "shared" > %t-order-shared.txt | ||
| 29 | # RUN: ld.lld %t1.o %t.so -o %t --symbol-ordering-file %t-order-shared.txt \ | ||
| 30 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,SHARED | ||
| 31 | |||
| 32 | # Check that a warning is emitted for absolute symbols. | ||
| 33 | # RUN: echo "absolute" > %t-order-absolute.txt | ||
| 34 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-absolute.txt \ | ||
| 35 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,ABSOLUTE | ||
| 36 | |||
| 37 | # Check that a warning is emitted for symbols discarded due to --gc-sections. | ||
| 38 | # RUN: echo "gc" > %t-order-gc.txt | ||
| 39 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-gc.txt --gc-sections \ | ||
| 40 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,GC | ||
| 41 | |||
| 42 | # Check that a warning is not emitted for the symbol removed due to --icf. | ||
| 43 | # RUN: echo "icf1" > %t-order-icf.txt | ||
| 44 | # RUN: echo "icf2" >> %t-order-icf.txt | ||
| 45 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-icf.txt --icf=all \ | ||
| 46 | # RUN: --unresolved-symbols=ignore-all --fatal-warnings | ||
| 47 | |||
| 48 | # RUN: echo "_GLOBAL_OFFSET_TABLE_" > %t-order-synthetic.txt | ||
| 49 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-synthetic.txt --icf=all \ | ||
| 50 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,SYNTHETIC | ||
| 51 | |||
| 52 | # Check that a warning is emitted for symbols discarded due to a linker script /DISCARD/ section. | ||
| 53 | # RUN: echo "discard" > %t-order-discard.txt | ||
| 54 | # RUN: echo "SECTIONS { /DISCARD/ : { *(.text.discard) } }" > %t.script | ||
| 55 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-discard.txt -T %t.script \ | ||
| 56 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,DISCARD | ||
| 57 | |||
| 58 | # Check that LLD does not warn for discarded COMDAT symbols, if they are present in the kept instance. | ||
| 59 | # RUN: echo "comdat" > %t-order-comdat.txt | ||
| 60 | # RUN: ld.lld %t1.o %t2.o -o %t --symbol-ordering-file %t-order-comdat.txt \ | ||
| 61 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN --allow-empty | ||
| 62 | |||
| 63 | # Check that if a COMDAT was unused and discarded via --gc-sections, warn for each instance. | ||
| 64 | # RUN: ld.lld %t1.o %t2.o -o %t --symbol-ordering-file %t-order-comdat.txt --gc-sections \ | ||
| 65 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,COMDAT | ||
| 66 | |||
| 67 | # Check that if a weak symbol is not kept, because of an equivalent global symbol, no warning is emitted. | ||
| 68 | # RUN: echo "glob_or_wk" > %t-order-weak.txt | ||
| 69 | # RUN: ld.lld %t1.o %t2.o -o %t --symbol-ordering-file %t-order-weak.txt \ | ||
| 70 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN --allow-empty | ||
| 71 | |||
| 72 | # Check that symbols only in unused archive members result in a warning. | ||
| 73 | # RUN: rm -f %t.a | ||
| 74 | # RUN: llvm-ar rc %t.a %t3.o | ||
| 75 | # RUN: ld.lld %t1.o %t.a -o %t --symbol-ordering-file %t-order-missing.txt \ | ||
| 76 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,MISSING --allow-empty | ||
| 77 | |||
| 78 | # Check that a warning for each same-named symbol with an issue. | ||
| 79 | # RUN: echo "multi" > %t-order-same-name.txt | ||
| 80 | # RUN: ld.lld %t1.o %t2.o %t3.o -o %t --symbol-ordering-file %t-order-same-name.txt \ | ||
| 81 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,MULTI | ||
| 82 | |||
| 83 | # Check that a warning is emitted if the same symbol is mentioned multiple times in the ordering file. | ||
| 84 | # RUN: echo "_start" > %t-order-multiple-same.txt | ||
| 85 | # RUN: echo "_start" >> %t-order-multiple-same.txt | ||
| 86 | # RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-multiple-same.txt \ | ||
| 87 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,SAMESYM | ||
| 88 | |||
| 89 | # Check that all warnings can be emitted from the same input. | ||
| 90 | # RUN: echo "missing_sym" > %t-order-multi.txt | ||
| 91 | # RUN: echo "undefined" >> %t-order-multi.txt | ||
| 92 | # RUN: echo "_start" >> %t-order-multi.txt | ||
| 93 | # RUN: echo "shared" >> %t-order-multi.txt | ||
| 94 | # RUN: echo "absolute" >> %t-order-multi.txt | ||
| 95 | # RUN: echo "gc" >> %t-order-multi.txt | ||
| 96 | # RUN: echo "discard" >> %t-order-multi.txt | ||
| 97 | # RUN: echo "_GLOBAL_OFFSET_TABLE_" >> %t-order-multi.txt | ||
| 98 | # RUN: echo "_start" >> %t-order-multi.txt | ||
| 99 | # RUN: ld.lld %t1.o %t3.o %t.so -o %t --symbol-ordering-file %t-order-multi.txt --gc-sections -T %t.script \ | ||
| 100 | # RUN: --unresolved-symbols=ignore-all 2>&1 | FileCheck %s --check-prefixes=WARN,SAMESYM,ABSOLUTE,SHARED,UNDEFINED,GC,DISCARD,MISSING2,SYNTHETIC | ||
| 101 | |||
| 102 | # WARN-NOT: warning: | ||
| 103 | # SAMESYM: warning: {{.*}}.txt: duplicate ordered symbol: _start | ||
| 104 | # WARN-NOT: warning: | ||
| 105 | # SYNTHETIC: warning: <internal>: unable to order synthetic symbol: _GLOBAL_OFFSET_TABLE_ | ||
| 106 | # WARN-NOT: warning: | ||
| 107 | # DISCARD: warning: {{.*}}1.o: unable to order discarded symbol: discard | ||
| 108 | # WARN-NOT: warning: | ||
| 109 | # GC: warning: {{.*}}1.o: unable to order discarded symbol: gc | ||
| 110 | # WARN-NOT: warning: | ||
| 111 | # SHARED: warning: {{.*}}.so: unable to order shared symbol: shared | ||
| 112 | # WARN-NOT: warning: | ||
| 113 | # UNDEFINED: warning: {{.*}}3.o: unable to order undefined symbol: undefined | ||
| 114 | # WARN-NOT: warning: | ||
| 115 | # ABSOLUTE: warning: {{.*}}1.o: unable to order absolute symbol: absolute | ||
| 116 | # WARN-NOT: warning: | ||
| 117 | # MISSING: warning: symbol ordering file: no such symbol: missing | ||
| 118 | # MISSING2: warning: symbol ordering file: no such symbol: missing_sym | ||
| 119 | # COMDAT: warning: {{.*}}1.o: unable to order discarded symbol: comdat | ||
| 120 | # MULTI: warning: {{.*}}3.o: unable to order undefined symbol: multi | ||
| 121 | # MULTI-NEXT: warning: {{.*}}2.o: unable to order absolute symbol: multi | ||
| 122 | # WARN-NOT: warning: | ||
| 123 | |||
| 124 | absolute = 0x1234 | ||
| 125 | |||
| 126 | .section .text.gc,"ax",@progbits | ||
| 127 | .global gc | ||
| 128 | gc: | ||
| 129 | nop | ||
| 130 | |||
| 131 | .section .text.discard,"ax",@progbits | ||
| 132 | .global discard | ||
| 133 | discard: | ||
| 134 | nop | ||
| 135 | |||
| 136 | .section .text.comdat,"axG",@progbits,comdat,comdat | ||
| 137 | .weak comdat | ||
| 138 | comdat: | ||
| 139 | nop | ||
| 140 | |||
| 141 | .section .text.glob_or_wk,"ax",@progbits | ||
| 142 | .weak glob_or_wk | ||
| 143 | glob_or_wk: | ||
| 144 | nop | ||
| 145 | |||
| 146 | .section .text._start,"ax",@progbits | ||
| 147 | .global _start | ||
| 148 | _start: | ||
| 149 | movq %rax, absolute | ||
| 150 | callq shared | ||
| 151 | |||
| 152 | .section .text.icf1,"ax",@progbits | ||
| 153 | .global icf1 | ||
| 154 | icf1: | ||
| 155 | ret | ||
| 156 | |||
| 157 | .section .text.icf2,"ax",@progbits | ||
| 158 | .global icf2 | ||
| 159 | icf2: | ||
| 160 | ret | ||
| 161 | |||
| 162 | # This is a "good" instance of the symbol | ||
| 163 | .section .text.multi,"ax",@progbits | ||
| 164 | multi: | ||
| 165 | .quad _GLOBAL_OFFSET_TABLE_ | ||
deps/lld/test/ELF/symbol-ordering-file.s+16| ... | @@ -5,6 +5,8 @@ | ... | @@ -5,6 +5,8 @@ |
| 5 | 5 | ||
| 6 | # BEFORE: Contents of section .foo: | 6 | # BEFORE: Contents of section .foo: |
| 7 | # BEFORE-NEXT: 201000 11223344 5566 | 7 | # BEFORE-NEXT: 201000 11223344 5566 |
| 8 | # BEFORE: Contents of section .init: | ||
| 9 | # BEFORE-NEXT: 201006 1122 | ||
| 8 | 10 | ||
| 9 | # RUN: echo "_foo4 " > %t_order.txt | 11 | # RUN: echo "_foo4 " > %t_order.txt |
| 10 | # RUN: echo " _foo3" >> %t_order.txt | 12 | # RUN: echo " _foo3" >> %t_order.txt |
| ... | @@ -14,12 +16,18 @@ | ... | @@ -14,12 +16,18 @@ |
| 14 | # RUN: echo "_foo4" >> %t_order.txt | 16 | # RUN: echo "_foo4" >> %t_order.txt |
| 15 | # RUN: echo "_bar1" >> %t_order.txt | 17 | # RUN: echo "_bar1" >> %t_order.txt |
| 16 | # RUN: echo "_foo1" >> %t_order.txt | 18 | # RUN: echo "_foo1" >> %t_order.txt |
| 19 | # RUN: echo "_init2" >> %t_order.txt | ||
| 20 | # RUN: echo "_init1" >> %t_order.txt | ||
| 17 | 21 | ||
| 18 | # RUN: ld.lld --symbol-ordering-file %t_order.txt %t.o -o %t2.out | 22 | # RUN: ld.lld --symbol-ordering-file %t_order.txt %t.o -o %t2.out |
| 19 | # RUN: llvm-objdump -s %t2.out| FileCheck %s --check-prefix=AFTER | 23 | # RUN: llvm-objdump -s %t2.out| FileCheck %s --check-prefix=AFTER |
| 24 | # RUN: ld.lld --symbol-ordering-file=%t_order.txt %t.o -o %t2.out | ||
| 25 | # RUN: llvm-objdump -s %t2.out| FileCheck %s --check-prefix=AFTER | ||
| 20 | 26 | ||
| 21 | # AFTER: Contents of section .foo: | 27 | # AFTER: Contents of section .foo: |
| 22 | # AFTER-NEXT: 201000 44335566 2211 | 28 | # AFTER-NEXT: 201000 44335566 2211 |
| 29 | # AFTER: Contents of section .init: | ||
| 30 | # AFTER-NEXT: 201006 1122 | ||
| 23 | 31 | ||
| 24 | .section .foo,"ax",@progbits,unique,1 | 32 | .section .foo,"ax",@progbits,unique,1 |
| 25 | _foo1: | 33 | _foo1: |
| ... | @@ -42,3 +50,11 @@ _foo5: | ... | @@ -42,3 +50,11 @@ _foo5: |
| 42 | .byte 0x55 | 50 | .byte 0x55 |
| 43 | _bar1: | 51 | _bar1: |
| 44 | .byte 0x66 | 52 | .byte 0x66 |
| 53 | |||
| 54 | .section .init,"ax",@progbits,unique,1 | ||
| 55 | _init1: | ||
| 56 | .byte 0x11 | ||
| 57 | |||
| 58 | .section .init,"ax",@progbits,unique,2 | ||
| 59 | _init2: | ||
| 60 | .byte 0x22 |
deps/lld/test/ELF/symbol-override.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/symbol-override.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/symbol-override.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
deps/lld/test/ELF/symbols.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 2 | // RUN: ld.lld %t -o %t2 | 3 | // RUN: ld.lld %t -o %t2 |
| 3 | // RUN: llvm-readobj -symbols -sections %t2 | FileCheck %s | 4 | // RUN: llvm-readobj -symbols -sections %t2 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | .type _start, @function | 6 | .type _start, @function |
| 7 | .globl _start | 7 | .globl _start |
deps/lld/test/ELF/symver-archive.s+1-1| ... | @@ -4,7 +4,7 @@ | ... | @@ -4,7 +4,7 @@ |
| 4 | # RUN: llvm-ar rcs %t.a %t1 | 4 | # RUN: llvm-ar rcs %t.a %t1 |
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive1.s -o %t2.o | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive1.s -o %t2.o |
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive2.s -o %t3.o | 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive2.s -o %t3.o |
| 7 | # RUN: ld.lld -o %t.out %t2.o %t3.o %t.a | 7 | # RUN: ld.lld -o /dev/null %t2.o %t3.o %t.a |
| 8 | 8 | ||
| 9 | .text | 9 | .text |
| 10 | .globl x | 10 | .globl x |
deps/lld/test/ELF/sysroot.s+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: mkdir -p %t/lib | 2 | // RUN: mkdir -p %t/lib |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t/m.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t/m.o |
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 4 | // RUN: %p/Inputs/libsearch-st.s -o %t/st.o | 5 | // RUN: %p/Inputs/libsearch-st.s -o %t/st.o |
| 5 | // RUN: rm -f %t/lib/libls.a | 6 | // RUN: rm -f %t/lib/libls.a |
| 6 | // RUN: llvm-ar rcs %t/lib/libls.a %t/st.o | 7 | // RUN: llvm-ar rcs %t/lib/libls.a %t/st.o |
| 7 | // REQUIRES: x86 | ||
| 8 | 8 | ||
| 9 | // Should not link because of undefined symbol _bar | 9 | // Should not link because of undefined symbol _bar |
| 10 | // RUN: not ld.lld -o %t/r %t/m.o 2>&1 \ | 10 | // RUN: not ld.lld -o %t/r %t/m.o 2>&1 \ |
deps/lld/test/ELF/text-section-prefix.s created+39| ... | @@ -0,0 +1,39 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 3 | # RUN: ld.lld -z keep-text-section-prefix %t -o %t2 | ||
| 4 | # RUN: llvm-readelf -l %t2 | FileCheck %s | ||
| 5 | # RUN: ld.lld %t -o %t3 | ||
| 6 | # RUN: llvm-readelf -l %t3 | FileCheck --check-prefix=CHECKNO %s | ||
| 7 | # RUN: ld.lld -z nokeep-text-section-prefix %t -o %t4 | ||
| 8 | # RUN: llvm-readelf -l %t4 | FileCheck --check-prefix=CHECKNO %s | ||
| 9 | |||
| 10 | # CHECK: .text | ||
| 11 | # CHECK: .text.hot | ||
| 12 | # CHECK: .text.startup | ||
| 13 | # CHECK: .text.exit | ||
| 14 | # CHECK: .text.unlikely | ||
| 15 | # CHECKNO: .text | ||
| 16 | # CHECKNO-NOT: .text.hot | ||
| 17 | |||
| 18 | _start: | ||
| 19 | ret | ||
| 20 | |||
| 21 | .section .text.f,"ax" | ||
| 22 | f: | ||
| 23 | nop | ||
| 24 | |||
| 25 | .section .text.hot.f_hot,"ax" | ||
| 26 | f_hot: | ||
| 27 | nop | ||
| 28 | |||
| 29 | .section .text.startup.f_startup,"ax" | ||
| 30 | f_startup: | ||
| 31 | nop | ||
| 32 | |||
| 33 | .section .text.exit.f_exit,"ax" | ||
| 34 | f_exit: | ||
| 35 | nop | ||
| 36 | |||
| 37 | .section .text.unlikely.f_unlikely,"ax" | ||
| 38 | f_unlikely: | ||
| 39 | nop | ||
deps/lld/test/ELF/tls-archive.s+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2 |
| 4 | // RUN: rm -f %t.a | 4 | // RUN: rm -f %t.a |
| 5 | // RUN: llvm-ar cru %t.a %t2 | 5 | // RUN: llvm-ar cru %t.a %t2 |
| 6 | // RUN: ld.lld %t.a %t -o %t3 | 6 | // RUN: ld.lld %t.a %t -o /dev/null |
| 7 | 7 | ||
| 8 | .globl _start,tlsvar | 8 | .globl _start,tlsvar |
| 9 | _start: | 9 | _start: |
deps/lld/test/ELF/tls-error.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| 3 | // RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: R_X86_64_TPOFF32 out of range | 4 | // CHECK: R_X86_64_TPOFF32 out of range |
| 5 | 5 | ||
| 6 | .global _start | 6 | .global _start |
deps/lld/test/ELF/tls-got.s+5-4| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got.s -o %t2.o |
| 3 | // RUN: ld.lld -shared %t2.o -o %t2.so | 4 | // RUN: ld.lld -shared %t2.o -o %t2.so |
| ... | @@ -25,13 +26,13 @@ | ... | @@ -25,13 +26,13 @@ |
| 25 | // CHECK: Relocations [ | 26 | // CHECK: Relocations [ |
| 26 | // CHECK-NEXT: Section (4) .rela.dyn { | 27 | // CHECK-NEXT: Section (4) .rela.dyn { |
| 27 | // CHECK-NEXT: 0x2020B8 R_X86_64_TPOFF64 tls0 0x0 | 28 | // CHECK-NEXT: 0x2020B8 R_X86_64_TPOFF64 tls0 0x0 |
| 28 | // CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0 | 29 | // CHECK-NEXT: 0x2020B0 R_X86_64_TPOFF64 tls1 0x0 |
| 29 | // CHECK-NEXT: } | 30 | // CHECK-NEXT: } |
| 30 | // CHECK-NEXT: ] | 31 | // CHECK-NEXT: ] |
| 31 | 32 | ||
| 32 | //0x201000 + 4249 + 7 = 0x2020B0 | 33 | //0x201000 + 4265 + 7 = 0x2020B0 |
| 33 | //0x20100A + 4247 + 7 = 0x2020B8 | 34 | //0x20100A + 4263 + 7 = 0x2020B8 |
| 34 | //0x201014 + 4237 + 7 = 0x2020B8 | 35 | //0x201014 + 4253 + 7 = 0x2020B8 |
| 35 | //DISASM: Disassembly of section .text: | 36 | //DISASM: Disassembly of section .text: |
| 36 | //DISASM-NEXT: main: | 37 | //DISASM-NEXT: main: |
| 37 | //DISASM-NEXT: 201000: 48 8b 05 a9 10 00 00 movq 4265(%rip), %rax | 38 | //DISASM-NEXT: 201000: 48 8b 05 a9 10 00 00 movq 4265(%rip), %rax |
deps/lld/test/ELF/tls-in-archive.s+1-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-in-archive.s -o %t1.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-in-archive.s -o %t1.o |
| 3 | // RUN: llvm-ar cru %t.a %t1.o | 3 | // RUN: llvm-ar cru %t.a %t1.o |
| 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o | 4 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o |
| 5 | // RUN: ld.lld %t2.o %t.a -o %tout | 5 | // RUN: ld.lld %t2.o %t.a -o /dev/null |
| 6 | 6 | ||
| 7 | .globl _start | 7 | .globl _start |
| 8 | _start: | 8 | _start: |
deps/lld/test/ELF/tls-mismatch.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2 |
| 4 | // RUN: not ld.lld %t %t2 -o %t3 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld %t %t2 -o /dev/null 2>&1 | FileCheck %s |
| 5 | 5 | ||
| 6 | // CHECK: TLS attribute mismatch: tlsvar | 6 | // CHECK: TLS attribute mismatch: tlsvar |
| 7 | // CHECK: >>> defined in | 7 | // CHECK: >>> defined in |
deps/lld/test/ELF/tls-opt-gdie.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o |
| 3 | // RUN: ld.lld -shared %tso.o -o %t.so | 4 | // RUN: ld.lld -shared %tso.o -o %t.so |
deps/lld/test/ELF/tls-opt-gdiele-i686.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-gdiele-i686.s -o %tso.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-gdiele-i686.s -o %tso.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | 3 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 3 | // RUN: ld.lld -shared %tso.o -o %tso | 4 | // RUN: ld.lld -shared %tso.o -o %tso |
deps/lld/test/ELF/tls-opt-i686.s+3-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t1 | 3 | // RUN: ld.lld %t.o -o %t1 |
| 3 | // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s | 4 | // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s |
| ... | @@ -11,11 +12,11 @@ | ... | @@ -11,11 +12,11 @@ |
| 11 | // LD -> LE: | 12 | // LD -> LE: |
| 12 | // DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax | 13 | // DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax |
| 13 | // DISASM-NEXT: 11006: 90 nop | 14 | // DISASM-NEXT: 11006: 90 nop |
| 14 | // DISASM-NEXT: 11007: 8d 74 26 00 leal (%esi), %esi | 15 | // DISASM-NEXT: 11007: 8d 74 26 00 leal (%esi,%eiz), %esi |
| 15 | // DISASM-NEXT: 1100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx | 16 | // DISASM-NEXT: 1100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx |
| 16 | // DISASM-NEXT: 11011: 65 a1 00 00 00 00 movl %gs:0, %eax | 17 | // DISASM-NEXT: 11011: 65 a1 00 00 00 00 movl %gs:0, %eax |
| 17 | // DISASM-NEXT: 11017: 90 nop | 18 | // DISASM-NEXT: 11017: 90 nop |
| 18 | // DISASM-NEXT: 11018: 8d 74 26 00 leal (%esi), %esi | 19 | // DISASM-NEXT: 11018: 8d 74 26 00 leal (%esi,%eiz), %esi |
| 19 | // DISASM-NEXT: 1101c: 8d 90 fc ff ff ff leal -4(%eax), %edx | 20 | // DISASM-NEXT: 1101c: 8d 90 fc ff ff ff leal -4(%eax), %edx |
| 20 | // IE -> LE: | 21 | // IE -> LE: |
| 21 | // 4294967288 == 0xFFFFFFF8 | 22 | // 4294967288 == 0xFFFFFFF8 |
deps/lld/test/ELF/tls-opt-iele-i686-nopic.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o | 3 | // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o |
| 3 | // RUN: ld.lld -shared %tso.o -o %tso | 4 | // RUN: ld.lld -shared %tso.o -o %tso |
deps/lld/test/ELF/tls-opt-local.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t1 | 3 | // RUN: ld.lld %t.o -o %t1 |
| 3 | // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s | 4 | // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s |
deps/lld/test/ELF/tls-opt-no-plt.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-opt-gdie.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-opt-gdie.s -o %t2.o |
| 3 | // RUN: ld.lld %t2.o -o %t2.so -shared | 4 | // RUN: ld.lld %t2.o -o %t2.so -shared |
deps/lld/test/ELF/tls-opt.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t1 | 3 | // RUN: ld.lld %t.o -o %t1 |
| 3 | // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s | 4 | // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s |
deps/lld/test/ELF/tls-static.s+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared.s -o %tso | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared.s -o %tso |
| 3 | // RUN: ld.lld -static %t -o %tout | 4 | // RUN: ld.lld -static %t -o %tout |
| 4 | // RUN: ld.lld %t -o %tout | 5 | // RUN: ld.lld %t -o %tout |
| 5 | // RUN: ld.lld -shared %tso -o %tshared | 6 | // RUN: ld.lld -shared %tso -o %tshared |
| 6 | // RUN: ld.lld -static %t %tshared -o %tout | 7 | // RUN: ld.lld -static %t %tshared -o %tout |
| 7 | // REQUIRES: x86 | ||
| 8 | 8 | ||
| 9 | .global _start | 9 | .global _start |
| 10 | _start: | 10 | _start: |
deps/lld/test/ELF/trace-symbols.s+6-2| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # Test -y symbol and -trace-symbol=symbol | 2 | # Test -y symbol and -trace-symbol=symbol |
| 2 | 3 | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t |
| ... | @@ -28,7 +29,7 @@ | ... | @@ -28,7 +29,7 @@ |
| 28 | # RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \ | 29 | # RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \ |
| 29 | # RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s | 30 | # RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s |
| 30 | # RUN: ld.lld -y foo -y common --trace-symbol=hsymbol \ | 31 | # RUN: ld.lld -y foo -y common --trace-symbol=hsymbol \ |
| 31 | # RUN: %t %t2 %t1 -o %t4 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s | 32 | # RUN: %t %t2 %t1 -o /dev/null 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s |
| 32 | # RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \ | 33 | # RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \ |
| 33 | # RUN: FileCheck -check-prefix=OBJECTD2FOO %s | 34 | # RUN: FileCheck -check-prefix=OBJECTD2FOO %s |
| 34 | # OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo | 35 | # OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo |
| ... | @@ -69,12 +70,15 @@ | ... | @@ -69,12 +70,15 @@ |
| 69 | 70 | ||
| 70 | # RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \ | 71 | # RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \ |
| 71 | # RUN: FileCheck -check-prefix=SHLIBRBAR %s | 72 | # RUN: FileCheck -check-prefix=SHLIBRBAR %s |
| 72 | # SHLIBRBAR-NOT: trace-symbols.s.tmp1.so: reference to bar | 73 | # SHLIBRBAR: trace-symbols.s.tmp1.so: reference to bar |
| 73 | 74 | ||
| 74 | # RUN: ld.lld -y foo -y bar %t -u bar --start-lib %t1 %t2 --end-lib -o %t3 | \ | 75 | # RUN: ld.lld -y foo -y bar %t -u bar --start-lib %t1 %t2 --end-lib -o %t3 | \ |
| 75 | # RUN: FileCheck -check-prefix=STARTLIB %s | 76 | # RUN: FileCheck -check-prefix=STARTLIB %s |
| 76 | # STARTLIB: trace-symbols.s.tmp1: reference to bar | 77 | # STARTLIB: trace-symbols.s.tmp1: reference to bar |
| 77 | 78 | ||
| 79 | ## Check we do not crash when trying to trace special symbol. | ||
| 80 | # RUN: not ld.lld -trace-symbol=_end %t -o /dev/null | ||
| 81 | |||
| 78 | .hidden hsymbol | 82 | .hidden hsymbol |
| 79 | .globl	_start | 83 | .globl	_start |
| 80 | .type	_start, @function | 84 | .type	_start, @function |
deps/lld/test/ELF/typed-undef.s+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | # We used to crash on this, check that we don't | 3 | # We used to crash on this, check that we don't |
| 4 | 4 | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 6 | # RUN: ld.lld %t.o -o %t -pie --unresolved-symbols=ignore-all | 6 | # RUN: ld.lld %t.o -o /dev/null -pie --unresolved-symbols=ignore-all |
| 7 | 7 | ||
| 8 | .global _start | 8 | .global _start |
| 9 | _start: | 9 | _start: |
deps/lld/test/ELF/undef-broken-debug.test+22-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: yaml2obj %s -o %t.o | 2 | # RUN: yaml2obj %s -o %t.o |
| 3 | # RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s | 3 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | # The debug info has a broken relocation. Check that we don't crash | 5 | # The debug info has a broken relocation. Check that we don't crash |
| 6 | # and still report the undefined symbol. | 6 | # and still report the undefined symbol. |
| ... | @@ -40,6 +40,27 @@ Sections: | ... | @@ -40,6 +40,27 @@ Sections: |
| 40 | - Offset: 0x0000000000000029 | 40 | - Offset: 0x0000000000000029 |
| 41 | Symbol: bar | 41 | Symbol: bar |
| 42 | Type: R_X86_64_64 | 42 | Type: R_X86_64_64 |
| 43 | - Name: .debug_info | ||
| 44 | Type: SHT_PROGBITS | ||
| 45 | AddressAlign: 0x0000000000000001 | ||
| 46 | Content: 0C000000040000000000080100000000 | ||
| 47 | - Name: .rela.debug_info | ||
| 48 | Type: SHT_RELA | ||
| 49 | Link: .symtab | ||
| 50 | AddressAlign: 0x0000000000000008 | ||
| 51 | Info: .debug_info | ||
| 52 | Relocations: | ||
| 53 | - Offset: 0x0000000000000006 | ||
| 54 | Symbol: .debug_abbrev | ||
| 55 | Type: R_X86_64_32 | ||
| 56 | - Offset: 0x000000000000000C | ||
| 57 | Symbol: .debug_line | ||
| 58 | Type: R_X86_64_32 | ||
| 59 | - Name: .debug_abbrev | ||
| 60 | Type: SHT_PROGBITS | ||
| 61 | AddressAlign: 0x0000000000000001 | ||
| 62 | Content: '0111001017000000' | ||
| 63 | |||
| 43 | Symbols: | 64 | Symbols: |
| 44 | Global: | 65 | Global: |
| 45 | - Name: _start | 66 | - Name: _start |
deps/lld/test/ELF/undef-shared.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | # RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | # RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s |
| 3 | 4 | ||
| 4 | # CHECK: error: undefined symbol: hidden | 5 | # CHECK: error: undefined symbol: hidden |
| 5 | # CHECK: >>> referenced by {{.*}}:(.data+0x0) | 6 | # CHECK: >>> referenced by {{.*}}:(.data+0x0) |
deps/lld/test/ELF/undef-shared2.s created+11| ... | @@ -0,0 +1,11 @@ | ||
| 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-shared2.s -o %t2.o | ||
| 4 | # RUN: not ld.lld %t.o %t2.o -o %t.so -shared 2>&1 | FileCheck %s | ||
| 5 | # RUN: not ld.lld %t2.o %t.o -o %t.so -shared 2>&1 | FileCheck %s | ||
| 6 | |||
| 7 | # CHECK: error: undefined symbol: foo | ||
| 8 | |||
| 9 | .data | ||
| 10 | .quad foo | ||
| 11 | .protected foo | ||
deps/lld/test/ELF/undef-start.s+4-2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t | ||
| 2 | # RUN: ld.lld %t -o %t2 2>&1 | ||
| 3 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | # RUN: ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: warning: cannot find entry symbol _start |
deps/lld/test/ELF/undef-version-script.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | # RUN: echo "{ local: *; };" > %t.script | 3 | # RUN: echo "{ local: *; };" > %t.script |
| 3 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so | 4 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so |
deps/lld/test/ELF/undef.s+16-2| ... | @@ -2,9 +2,10 @@ | ... | @@ -2,9 +2,10 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 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 | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef.s -o %t2.o |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-debug.s -o %t3.o | 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-debug.s -o %t3.o |
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-bad-debug.s -o %t4.o | ||
| 5 | # RUN: llvm-ar rc %t2.a %t2.o | 6 | # RUN: llvm-ar rc %t2.a %t2.o |
| 6 | # RUN: not ld.lld %t.o %t2.a %t3.o -o %t.exe 2>&1 | FileCheck %s | 7 | # RUN: not ld.lld %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s |
| 7 | # RUN: not ld.lld -pie %t.o %t2.a %t3.o -o %t.exe 2>&1 | FileCheck %s | 8 | # RUN: not ld.lld -pie %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s |
| 8 | 9 | ||
| 9 | # CHECK: error: undefined symbol: foo | 10 | # CHECK: error: undefined symbol: foo |
| 10 | # CHECK: >>> referenced by undef.s | 11 | # CHECK: >>> referenced by undef.s |
| ... | @@ -33,6 +34,19 @@ | ... | @@ -33,6 +34,19 @@ |
| 33 | # CHECK: >>> referenced by undef-debug.s:11 (dir{{/|\\}}undef-debug.s:11) | 34 | # CHECK: >>> referenced by undef-debug.s:11 (dir{{/|\\}}undef-debug.s:11) |
| 34 | # CHECK: >>> {{.*}}.o:(.text.2+0x0) | 35 | # CHECK: >>> {{.*}}.o:(.text.2+0x0) |
| 35 | 36 | ||
| 37 | # Show that all line table problems are mentioned as soon as the object's line information | ||
| 38 | # is requested, even if that particular part of the line information is not currently required. | ||
| 39 | # CHECK: warning: parsing line table prologue at 0x00000000 should have ended at 0x00000038 but it ended at 0x00000037 | ||
| 40 | # CHECK: warning: last sequence in debug line table is not terminated! | ||
| 41 | # CHECK: error: undefined symbol: zed6 | ||
| 42 | # CHECK: >>> referenced by {{.*}}tmp4.o:(.text+0x0) | ||
| 43 | |||
| 44 | # Show that a problem with one line table's information doesn't affect getting information from | ||
| 45 | # a different one in the same object. | ||
| 46 | # CHECK: error: undefined symbol: zed7 | ||
| 47 | # CHECK: >>> referenced by undef-bad-debug2.s:11 (dir2{{/|\\}}undef-bad-debug2.s:11) | ||
| 48 | # CHECK: >>> {{.*}}tmp4.o:(.text+0x8) | ||
| 49 | |||
| 36 | # RUN: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \ | 50 | # RUN: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \ |
| 37 | # RUN: FileCheck -check-prefix=NO-DEMANGLE %s | 51 | # RUN: FileCheck -check-prefix=NO-DEMANGLE %s |
| 38 | # NO-DEMANGLE: error: undefined symbol: _Z3fooi | 52 | # NO-DEMANGLE: error: undefined symbol: _Z3fooi |
deps/lld/test/ELF/undefined-opt.s+1-1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ |
| 3 | # RUN: %p/Inputs/abs.s -o %tabs.o | 4 | # RUN: %p/Inputs/abs.s -o %tabs.o |
| ... | @@ -5,7 +6,6 @@ | ... | @@ -5,7 +6,6 @@ |
| 5 | # RUN: %p/Inputs/shared.s -o %tshared.o | 6 | # RUN: %p/Inputs/shared.s -o %tshared.o |
| 6 | # RUN: rm -f %tar.a | 7 | # RUN: rm -f %tar.a |
| 7 | # RUN: llvm-ar rcs %tar.a %tabs.o %tshared.o | 8 | # RUN: llvm-ar rcs %tar.a %tabs.o %tshared.o |
| 8 | # REQUIRES: x86 | ||
| 9 | 9 | ||
| 10 | # Symbols from the archive are not in if not needed | 10 | # Symbols from the archive are not in if not needed |
| 11 | # RUN: ld.lld -o %t1 %t.o %tar.a | 11 | # RUN: ld.lld -o %t1 %t.o %tar.a |
deps/lld/test/ELF/unresolved-symbols.s+5-5| ... | @@ -21,7 +21,7 @@ | ... | @@ -21,7 +21,7 @@ |
| 21 | ## case when --no-undefined specified. | 21 | ## case when --no-undefined specified. |
| 22 | # RUN: ld.lld %t2.o -o %t1_1 --unresolved-symbols=ignore-all | 22 | # RUN: ld.lld %t2.o -o %t1_1 --unresolved-symbols=ignore-all |
| 23 | # RUN: llvm-readobj %t1_1 > /dev/null 2>&1 | 23 | # RUN: llvm-readobj %t1_1 > /dev/null 2>&1 |
| 24 | # RUN: not ld.lld %t2.o -o %t1_2 --unresolved-symbols=ignore-all --no-undefined 2>&1 | \ | 24 | # RUN: not ld.lld %t2.o -o /dev/null --unresolved-symbols=ignore-all --no-undefined 2>&1 | \ |
| 25 | # RUN: FileCheck -check-prefix=ERRUND %s | 25 | # RUN: FileCheck -check-prefix=ERRUND %s |
| 26 | # ERRUND: error: undefined symbol: undef | 26 | # ERRUND: error: undefined symbol: undef |
| 27 | # ERRUND: >>> referenced by {{.*}}:(.text+0x1) | 27 | # ERRUND: >>> referenced by {{.*}}:(.text+0x1) |
| ... | @@ -34,11 +34,11 @@ | ... | @@ -34,11 +34,11 @@ |
| 34 | # RUN: ld.lld %t1.o %t2.o -o %t2 --unresolved-symbols=ignore-in-object-files | 34 | # RUN: ld.lld %t1.o %t2.o -o %t2 --unresolved-symbols=ignore-in-object-files |
| 35 | # RUN: llvm-readobj %t2 > /dev/null 2>&1 | 35 | # RUN: llvm-readobj %t2 > /dev/null 2>&1 |
| 36 | ## And still should not should produce for undefines from DSOs. | 36 | ## And still should not should produce for undefines from DSOs. |
| 37 | # RUN: ld.lld %t1.o %t.so -o %t2_1 --unresolved-symbols=ignore-in-object-files | 37 | # RUN: ld.lld %t1.o %t.so -o /dev/null --unresolved-symbols=ignore-in-object-files |
| 38 | # RUN: llvm-readobj %t2 > /dev/null 2>&1 | 38 | # RUN: llvm-readobj %t2 > /dev/null 2>&1 |
| 39 | 39 | ||
| 40 | ## Ignoring undefines in shared should produce error for symbol from object. | 40 | ## Ignoring undefines in shared should produce error for symbol from object. |
| 41 | # RUN: not ld.lld %t2.o -o %t3 --unresolved-symbols=ignore-in-shared-libs 2>&1 | \ | 41 | # RUN: not ld.lld %t2.o -o /dev/null --unresolved-symbols=ignore-in-shared-libs 2>&1 | \ |
| 42 | # RUN: FileCheck -check-prefix=ERRUND %s | 42 | # RUN: FileCheck -check-prefix=ERRUND %s |
| 43 | ## And should not produce errors for symbols from DSO. | 43 | ## 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 --unresolved-symbols=ignore-in-shared-libs |
| ... | @@ -60,9 +60,9 @@ | ... | @@ -60,9 +60,9 @@ |
| 60 | # RUN: llvm-readobj %t6 > /dev/null 2>&1 | 60 | # RUN: llvm-readobj %t6 > /dev/null 2>&1 |
| 61 | # RUN: ld.lld -shared %t1.o %t.so -o %t6_1 | 61 | # RUN: ld.lld -shared %t1.o %t.so -o %t6_1 |
| 62 | # RUN: llvm-readobj %t6_1 > /dev/null 2>&1 | 62 | # RUN: llvm-readobj %t6_1 > /dev/null 2>&1 |
| 63 | # RUN: not ld.lld %t2.o -o %t7 --unresolved-symbols=report-all 2>&1 | \ | 63 | # RUN: not ld.lld %t2.o -o /dev/null --unresolved-symbols=report-all 2>&1 | \ |
| 64 | # RUN: FileCheck -check-prefix=ERRUND %s | 64 | # RUN: FileCheck -check-prefix=ERRUND %s |
| 65 | # RUN: not ld.lld %t2.o -o %t7_1 2>&1 | FileCheck -check-prefix=ERRUND %s | 65 | # RUN: not ld.lld %t2.o -o /dev/null 2>&1 | FileCheck -check-prefix=ERRUND %s |
| 66 | 66 | ||
| 67 | .globl _start | 67 | .globl _start |
| 68 | _start: | 68 | _start: |
deps/lld/test/ELF/user_def_init_array_start.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 2 | // RUN: ld.lld %t.o -o %t2.so -shared | 3 | // RUN: ld.lld %t.o -o /dev/null -shared |
| 3 | // Allow user defined __init_array_start. This is used by musl because of the | 4 | // Allow user defined __init_array_start. This is used by musl because of the |
| 4 | // the bfd linker not handling these properly. We always create them as | 5 | // the bfd linker not handling these properly. We always create them as |
| 5 | // hidden, musl should not have problems with lld. | 6 | // hidden, musl should not have problems with lld. |
deps/lld/test/ELF/verdef-defaultver.s+3-3| ... | @@ -196,6 +196,6 @@ | ... | @@ -196,6 +196,6 @@ |
| 196 | 196 | ||
| 197 | .globl _start | 197 | .globl _start |
| 198 | _start: | 198 | _start: |
| 199 | callq a | 199 | .long a - . |
| 200 | callq b | 200 | .long b - . |
| 201 | callq c | 201 | .long c - . |
deps/lld/test/ELF/verneed-local.s+1-1| ... | @@ -4,7 +4,7 @@ | ... | @@ -4,7 +4,7 @@ |
| 4 | # RUN: ld.lld -shared %t1.o --version-script %t.script -o %t.so | 4 | # RUN: ld.lld -shared %t1.o --version-script %t.script -o %t.so |
| 5 | 5 | ||
| 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 6 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 7 | # RUN: not ld.lld %t.o %t.so -o %t 2>&1 | FileCheck %s | 7 | # RUN: not ld.lld %t.o %t.so -o /dev/null 2>&1 | FileCheck %s |
| 8 | 8 | ||
| 9 | # CHECK: error: undefined symbol: f3 | 9 | # CHECK: error: undefined symbol: f3 |
| 10 | # CHECK: >>> referenced by {{.*}}:(.text+0x1) | 10 | # CHECK: >>> referenced by {{.*}}:(.text+0x1) |
deps/lld/test/ELF/verneed.s+63-61| ... | @@ -10,67 +10,69 @@ | ... | @@ -10,67 +10,69 @@ |
| 10 | # RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s | 10 | # RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s |
| 11 | 11 | ||
| 12 | # CHECK: Section { | 12 | # CHECK: Section { |
| 13 | # CHECK: Index: 1 | 13 | # CHECK: Index: 1 |
| 14 | # CHECK-NEXT: Name: .dynsym | 14 | # CHECK-NEXT: Name: .dynsym |
| 15 | # CHECK-NEXT: Type: SHT_DYNSYM (0xB) | 15 | # CHECK-NEXT: Type: SHT_DYNSYM (0xB) |
| 16 | # CHECK-NEXT: Flags [ (0x2) | ||
| 17 | # CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 18 | # CHECK-NEXT: ] | ||
| 19 | # CHECK-NEXT: Address: 0x2001C8 | ||
| 20 | # CHECK-NEXT: Offset: 0x1C8 | ||
| 21 | # CHECK-NEXT: Size: 96 | ||
| 22 | # CHECK-NEXT: Link: [[DYNSTR:.*]] | ||
| 23 | # CHECK-NEXT: Info: 1 | ||
| 24 | # CHECK-NEXT: AddressAlignment: 8 | ||
| 25 | # CHECK-NEXT: EntrySize: 24 | ||
| 26 | |||
| 27 | # CHECK: Section { | ||
| 28 | # CHECK-NEXT: Index: 2 | ||
| 29 | # CHECK-NEXT: Name: .gnu.version | ||
| 30 | # CHECK-NEXT: Type: SHT_GNU_versym (0x6FFFFFFF) | ||
| 16 | # CHECK-NEXT: Flags [ (0x2) | 31 | # CHECK-NEXT: Flags [ (0x2) |
| 17 | # CHECK-NEXT: SHF_ALLOC (0x2) | 32 | # CHECK-NEXT: SHF_ALLOC (0x2) |
| 18 | # CHECK-NEXT: ] | 33 | # CHECK-NEXT: ] |
| 19 | # CHECK-NEXT: Address: 0x2001C8 | 34 | # CHECK-NEXT: Address: [[VERSYM:.*]] |
| 20 | # CHECK-NEXT: Offset: 0x1C8 | 35 | # CHECK-NEXT: Offset: [[VERSYM_OFFSET:.*]] |
| 21 | # CHECK-NEXT: Size: 96 | 36 | # CHECK-NEXT: Size: 8 |
| 22 | # CHECK-NEXT: Link: 5 | 37 | # CHECK-NEXT: Link: 1 |
| 23 | # CHECK-NEXT: Info: 1 | 38 | # CHECK-NEXT: Info: 0 |
| 24 | # CHECK-NEXT: AddressAlignment: 8 | 39 | # CHECK-NEXT: AddressAlignment: 2 |
| 25 | # CHECK-NEXT: EntrySize: 24 | 40 | # CHECK-NEXT: EntrySize: 2 |
| 26 | # CHECK: Section { | 41 | |
| 27 | # CHECK-NEXT: Index: 2 | ||
| 28 | # CHECK-NEXT: Name: .gnu.version | ||
| 29 | # CHECK-NEXT: Type: SHT_GNU_versym (0x6FFFFFFF) | ||
| 30 | # CHECK-NEXT: Flags [ (0x2) | ||
| 31 | # CHECK-NEXT: SHF_ALLOC (0x2) | ||
| 32 | # CHECK-NEXT: ] | ||
| 33 | # CHECK-NEXT: Address: 0x200228 | ||
| 34 | # CHECK-NEXT: Offset: 0x228 | ||
| 35 | # CHECK-NEXT: Size: 8 | ||
| 36 | # CHECK-NEXT: Link: 1 | ||
| 37 | # CHECK-NEXT: Info: 0 | ||
| 38 | # CHECK-NEXT: AddressAlignment: 2 | ||
| 39 | # CHECK-NEXT: EntrySize: 2 | ||
| 40 | # CHECK: Section { | 42 | # CHECK: Section { |
| 41 | # CHECK-NEXT: Index: 3 | 43 | # CHECK-NEXT: Index: 3 |
| 42 | # CHECK-NEXT: Name: .gnu.version_r | 44 | # CHECK-NEXT: Name: .gnu.version_r |
| 43 | # CHECK-NEXT: Type: SHT_GNU_verneed (0x6FFFFFFE) | 45 | # CHECK-NEXT: Type: SHT_GNU_verneed (0x6FFFFFFE) |
| 44 | # CHECK-NEXT: Flags [ (0x2) | 46 | # CHECK-NEXT: Flags [ (0x2) |
| 45 | # CHECK-NEXT: SHF_ALLOC (0x2) | 47 | # CHECK-NEXT: SHF_ALLOC (0x2) |
| 46 | # CHECK-NEXT: ] | 48 | # CHECK-NEXT: ] |
| 47 | # CHECK-NEXT: Address: 0x200230 | 49 | # CHECK-NEXT: Address: [[VERNEED:.*]] |
| 48 | # CHECK-NEXT: Offset: 0x230 | 50 | # CHECK-NEXT: Offset: 0x230 |
| 49 | # CHECK-NEXT: Size: 80 | 51 | # CHECK-NEXT: Size: 80 |
| 50 | # CHECK-NEXT: Link: 5 | 52 | # CHECK-NEXT: Link: 5 |
| 51 | # CHECK-NEXT: Info: 2 | 53 | # CHECK-NEXT: Info: 2 |
| 52 | # CHECK-NEXT: AddressAlignment: 4 | 54 | # CHECK-NEXT: AddressAlignment: 4 |
| 53 | # CHECK-NEXT: EntrySize: 0 | 55 | # CHECK-NEXT: EntrySize: 0 |
| 54 | # CHECK: Section { | 56 | |
| 55 | # CHECK: Index: 5 | 57 | # CHECK: Index: [[DYNSTR]] |
| 56 | # CHECK-NEXT: Name: .dynstr | 58 | # CHECK-NEXT: Name: .dynstr |
| 57 | # CHECK-NEXT: Type: SHT_STRTAB | 59 | # CHECK-NEXT: Type: SHT_STRTAB (0x3) |
| 58 | # CHECK-NEXT: Flags [ (0x2) | 60 | # CHECK-NEXT: Flags [ (0x2) |
| 59 | # CHECK-NEXT: SHF_ALLOC (0x2) | 61 | # CHECK-NEXT: SHF_ALLOC (0x2) |
| 60 | # CHECK-NEXT: ] | 62 | # CHECK-NEXT: ] |
| 61 | # CHECK-NEXT: Address: 0x2002A8 | 63 | # CHECK-NEXT: Address: 0x2002A8 |
| 62 | # CHECK-NEXT: Offset: 0x2A8 | 64 | # CHECK-NEXT: Offset: 0x2A8 |
| 63 | # CHECK-NEXT: Size: 47 | 65 | # CHECK-NEXT: Size: 47 |
| 64 | # CHECK-NEXT: Link: 0 | 66 | # CHECK-NEXT: Link: 0 |
| 65 | # CHECK-NEXT: Info: 0 | 67 | # CHECK-NEXT: Info: 0 |
| 66 | # CHECK-NEXT: AddressAlignment: 1 | 68 | # CHECK-NEXT: AddressAlignment: 1 |
| 67 | # CHECK-NEXT: EntrySize: 0 | 69 | # CHECK-NEXT: EntrySize: 0 |
| 68 | # CHECK-NEXT: SectionData ( | 70 | # CHECK-NEXT: SectionData ( |
| 69 | # CHECK-NEXT: 0000: 00766572 6E656564 312E736F 2E300076 |.verneed1.so.0.v| | 71 | # CHECK-NEXT: 0000: 00766572 6E656564 312E736F 2E300076 |.verneed1.so.0.v| |
| 70 | # CHECK-NEXT: 0010: 65726E65 6564322E 736F2E30 00663100 |erneed2.so.0.f1.| | 72 | # CHECK-NEXT: 0010: 65726E65 6564322E 736F2E30 00663100 |erneed2.so.0.f1.| |
| 71 | # CHECK-NEXT: 0020: 76330066 32007632 00673100 763100 |v3.f2.v2.g1.v1.| | 73 | # CHECK-NEXT: 0020: 76330066 32007632 00673100 763100 |v3.f2.v2.g1.v1.| |
| 72 | # CHECK-NEXT: ) | 74 | # CHECK-NEXT: ) |
| 73 | # CHECK-NEXT: } | 75 | # CHECK-NEXT: } |
| 74 | 76 | ||
| 75 | # CHECK: DynamicSymbols [ | 77 | # CHECK: DynamicSymbols [ |
| 76 | # CHECK-NEXT: Symbol { | 78 | # CHECK-NEXT: Symbol { |
| ... | @@ -111,14 +113,14 @@ | ... | @@ -111,14 +113,14 @@ |
| 111 | # CHECK-NEXT: } | 113 | # CHECK-NEXT: } |
| 112 | # CHECK-NEXT: ] | 114 | # CHECK-NEXT: ] |
| 113 | 115 | ||
| 114 | # CHECK: 0x000000006FFFFFF0 VERSYM 0x200228 | 116 | # CHECK: 0x000000006FFFFFF0 VERSYM [[VERSYM]] |
| 115 | # CHECK-NEXT: 0x000000006FFFFFFE VERNEED 0x200230 | 117 | # CHECK-NEXT: 0x000000006FFFFFFE VERNEED [[VERNEED]] |
| 116 | # CHECK-NEXT: 0x000000006FFFFFFF VERNEEDNUM 2 | 118 | # CHECK-NEXT: 0x000000006FFFFFFF VERNEEDNUM 2 |
| 117 | 119 | ||
| 118 | # CHECK: Version symbols { | 120 | # CHECK: Version symbols { |
| 119 | # CHECK-NEXT: Section Name: .gnu.version | 121 | # CHECK-NEXT: Section Name: .gnu.version |
| 120 | # CHECK-NEXT: Address: 0x200228 | 122 | # CHECK-NEXT: Address: [[VERSYM]] |
| 121 | # CHECK-NEXT: Offset: 0x228 | 123 | # CHECK-NEXT: Offset: [[VERSYM_OFFSET]] |
| 122 | # CHECK-NEXT: Link: 1 | 124 | # CHECK-NEXT: Link: 1 |
| 123 | # CHECK-NEXT: Symbols [ | 125 | # CHECK-NEXT: Symbols [ |
| 124 | # CHECK-NEXT: Symbol { | 126 | # CHECK-NEXT: Symbol { |
deps/lld/test/ELF/version-exclude-libs.s created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc %p/Inputs/versiondef.s -o %t.o -filetype=obj -triple=x86_64-pc-linux | ||
| 3 | // RUN: llvm-ar -r %t.a %t.o | ||
| 4 | // RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux | ||
| 5 | // RUN: ld.lld %t2.o %t.a --shared --exclude-libs ALL -o %t.so | ||
| 6 | // RUN: llvm-readobj -symbols %t.so | FileCheck %s | ||
| 7 | // RUN: llvm-readobj -dyn-symbols %t.so | FileCheck -check-prefix CHECK-DYN %s | ||
| 8 | // RUN: not ld.lld %t2.o %t.a --shared -o %t.so 2>&1 | FileCheck -check-prefix=CHECK-ERR %s | ||
| 9 | |||
| 10 | // Test that we do not give an error message for undefined versions when the | ||
| 11 | // symbol is not exported to the dynamic symbol table. | ||
| 12 | |||
| 13 | // CHECK: Name: func | ||
| 14 | // CHECK-NEXT: Value: | ||
| 15 | // CHECK-NEXT: Size: | ||
| 16 | // CHECK-NEXT: Binding: Local (0x0) | ||
| 17 | |||
| 18 | // CHECK-DYN-NOT: func | ||
| 19 | |||
| 20 | // CHECK-ERR: symbol func@@VER2 has undefined version VER2 | ||
| 21 | // CHECK-ERR-NEXT: symbol func@VER has undefined version VER | ||
| 22 | |||
| 23 | .text | ||
| 24 | .globl _start | ||
| 25 | .globl func | ||
| 26 | _start: | ||
| 27 | ret | ||
| 28 | |||
| 29 | .data | ||
| 30 | .quad func | ||
deps/lld/test/ELF/version-script-complex-wildcards.s+1-1| ... | @@ -46,7 +46,7 @@ | ... | @@ -46,7 +46,7 @@ |
| 46 | # RUN: llvm-readobj -V %t8.so | FileCheck %s --check-prefix=ABBABC | 46 | # RUN: llvm-readobj -V %t8.so | FileCheck %s --check-prefix=ABBABC |
| 47 | 47 | ||
| 48 | # RUN: echo "FOO { global: extern \"C++\" { a[; }; };" > %t9.script | 48 | # RUN: echo "FOO { global: extern \"C++\" { a[; }; };" > %t9.script |
| 49 | # RUN: not ld.lld --version-script %t9.script -shared %t.o -o %t9.so 2>&1 \ | 49 | # RUN: not ld.lld --version-script %t9.script -shared %t.o -o /dev/null 2>&1 \ |
| 50 | # RUN: | FileCheck %s --check-prefix=ERROR | 50 | # RUN: | FileCheck %s --check-prefix=ERROR |
| 51 | # ERROR: invalid glob pattern: a[ | 51 | # ERROR: invalid glob pattern: a[ |
| 52 | 52 |
deps/lld/test/ELF/version-script-extern-undefined.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: echo "FOO { global: extern \"C++\" { \"abb(int)\"; }; };" > %t.script | ||
| 5 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so | ||
| 6 | # RUN: llvm-readobj -V %t.so | FileCheck %s | ||
| 7 | |||
| 8 | # CHECK: Symbols [ | ||
| 9 | # CHECK-NEXT: Symbol { | ||
| 10 | # CHECK-NEXT: Version: 0 | ||
| 11 | # CHECK-NEXT: Name: @ | ||
| 12 | # CHECK-NEXT: } | ||
| 13 | # CHECK-NEXT: Symbol { | ||
| 14 | # CHECK-NEXT: Version: 1 | ||
| 15 | # CHECK-NEXT: Name: _Z3abbi@ | ||
| 16 | # CHECK-NEXT: } | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | |||
| 19 | .globl _Z3abbi | ||
deps/lld/test/ELF/version-script-extern.s+1-1| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | # RUN: echo "LIBSAMPLE_2.0 { global:" >> %t.script | 7 | # RUN: echo "LIBSAMPLE_2.0 { global:" >> %t.script |
| 8 | # RUN: echo ' extern "C" { _Z3bari; };' >> %t.script | 8 | # RUN: echo ' extern "C" { _Z3bari; };' >> %t.script |
| 9 | # RUN: echo "};" >> %t.script | 9 | # RUN: echo "};" >> %t.script |
| 10 | # RUN: ld.lld --hash-style=sysv --version-script %t.script -shared %t.o -o %t.so | 10 | # 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-symbols %t.so | FileCheck --check-prefix=DSO %s |
| 12 | 12 | ||
| 13 | # DSO: DynamicSymbols [ | 13 | # DSO: DynamicSymbols [ |
deps/lld/test/ELF/version-script-extern2.s created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 4 | # RUN: echo "FOO { global: extern \"C++\" { \"bar\"; }; };" > %t.script | ||
| 5 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so | ||
| 6 | # RUN: llvm-readobj -V %t.so | FileCheck %s | ||
| 7 | |||
| 8 | # CHECK: Symbols [ | ||
| 9 | # CHECK-NEXT: Symbol { | ||
| 10 | # CHECK-NEXT: Version: 0 | ||
| 11 | # CHECK-NEXT: Name: @ | ||
| 12 | # CHECK-NEXT: } | ||
| 13 | # CHECK-NEXT: Symbol { | ||
| 14 | # CHECK-NEXT: Version: 2 | ||
| 15 | # CHECK-NEXT: Name: bar@@FOO | ||
| 16 | # CHECK-NEXT: } | ||
| 17 | # CHECK-NEXT: ] | ||
| 18 | |||
| 19 | .globl bar | ||
| 20 | .type bar,@function | ||
| 21 | bar: | ||
| 22 | retq | ||
deps/lld/test/ELF/version-script-glob.s+1-1| ... | @@ -48,7 +48,7 @@ local: | ... | @@ -48,7 +48,7 @@ local: |
| 48 | # CHECK-NEXT: ] | 48 | # CHECK-NEXT: ] |
| 49 | 49 | ||
| 50 | # RUN: echo "{ global : local; local: *; };" > %t1.script | 50 | # RUN: echo "{ global : local; local: *; };" > %t1.script |
| 51 | # RUN: ld.lld -shared --version-script %t1.script %t.o -o %t1.so | 51 | # RUN: ld.lld -shared --version-script %t1.script %t.o -o /dev/null |
| 52 | 52 | ||
| 53 | # LOCAL: DynamicSymbols [ | 53 | # LOCAL: DynamicSymbols [ |
| 54 | # LOCAL-NEXT: Symbol { | 54 | # LOCAL-NEXT: Symbol { |
deps/lld/test/ELF/version-script-in-search-path.s created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # Check that we fall back to search paths if a version script was not found | ||
| 3 | # This behaviour matches ld.bfd. | ||
| 4 | |||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 6 | # RUN: mkdir -p %T/searchpath | ||
| 7 | # RUN: echo '{};' > %T/searchpath/%basename_t.script | ||
| 8 | # RUN: ld.lld -L%T/searchpath --version-script=%basename_t.script %t.o -o /dev/null | ||
| 9 | # RUN: not ld.lld --version-script=%basename_t.script %t.o 2>&1 | FileCheck -check-prefix ERROR %s | ||
| 10 | # ERROR: error: cannot find version script | ||
deps/lld/test/ELF/version-script-missing.s+1-1| ... | @@ -4,4 +4,4 @@ | ... | @@ -4,4 +4,4 @@ |
| 4 | 4 | ||
| 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 6 | # RUN: echo "{ foobar; };" > %t.script | 6 | # RUN: echo "{ foobar; };" > %t.script |
| 7 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so | 7 | # RUN: ld.lld --version-script %t.script -shared %t.o -o /dev/null |
deps/lld/test/ELF/version-script-no-warn.s+1-1| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | # RUN: ld.lld -shared %t2.o -soname shared -o %t2.so | 5 | # RUN: ld.lld -shared %t2.o -soname shared -o %t2.so |
| 6 | 6 | ||
| 7 | # RUN: echo "foo { global: bar; local: *; };" > %t.script | 7 | # RUN: echo "foo { global: bar; local: *; };" > %t.script |
| 8 | # RUN: ld.lld --fatal-warnings --shared --version-script %t.script %t.o %t2.so | 8 | # RUN: ld.lld --fatal-warnings --shared --version-script %t.script %t.o %t2.so -o /dev/null |
| 9 | 9 | ||
| 10 | .global bar | 10 | .global bar |
| 11 | bar: | 11 | bar: |
deps/lld/test/ELF/version-script-no-warn2.s+2-1| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/version-script-no-warn2.s -o %t1.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/version-script-no-warn2.s -o %t1.o |
| 2 | # RUN: ld.lld %t1.o -o %t1.so -shared | 3 | # RUN: ld.lld %t1.o -o %t1.so -shared |
| 3 | # RUN: echo "{ global: foo; local: *; };" > %t.script | 4 | # RUN: echo "{ global: foo; local: *; };" > %t.script |
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o | 5 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o |
| 5 | # RUN: ld.lld -shared --version-script %t.script %t2.o %t1.so -o %t2.so --fatal-warnings | 6 | # RUN: ld.lld -shared --version-script %t.script %t2.o %t1.so -o /dev/null --fatal-warnings |
| 6 | 7 | ||
| 7 | .global	foo | 8 | .global	foo |
| 8 | foo: | 9 | foo: |
deps/lld/test/ELF/version-script-noundef.s+2| ... | @@ -2,6 +2,8 @@ | ... | @@ -2,6 +2,8 @@ |
| 2 | 2 | ||
| 3 | # RUN: echo "VERSION_1.0 { global: bar; };" > %t.script | 3 | # RUN: echo "VERSION_1.0 { global: bar; };" > %t.script |
| 4 | # 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 %s -o %t.o |
| 5 | # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so | ||
| 6 | # RUN: ld.lld --version-script %t.script -shared --undefined-version %t.o -o %t.so | ||
| 5 | # RUN: not ld.lld --version-script %t.script -shared --no-undefined-version \ | 7 | # RUN: not ld.lld --version-script %t.script -shared --no-undefined-version \ |
| 6 | # RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR1 %s | 8 | # RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR1 %s |
| 7 | # ERR1: version script assignment of 'VERSION_1.0' to symbol 'bar' failed: symbol not defined | 9 | # ERR1: version script assignment of 'VERSION_1.0' to symbol 'bar' failed: symbol not defined |
deps/lld/test/ELF/version-script-symver.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | # RUN: ld.lld %t.o -o %t | 3 | # RUN: ld.lld %t.o -o /dev/null |
| 4 | 4 | ||
| 5 | .global _start | 5 | .global _start |
| 6 | .global bar | 6 | .global bar |
deps/lld/test/ELF/version-script.s+6-3| ... | @@ -34,9 +34,9 @@ | ... | @@ -34,9 +34,9 @@ |
| 34 | 34 | ||
| 35 | # RUN: echo "VERSION_1.0 { global: foo1; local: *; };" > %t6.script | 35 | # RUN: echo "VERSION_1.0 { global: foo1; local: *; };" > %t6.script |
| 36 | # RUN: echo "VERSION_2.0 { global: foo1; local: *; };" >> %t6.script | 36 | # RUN: echo "VERSION_2.0 { global: foo1; local: *; };" >> %t6.script |
| 37 | # RUN: ld.lld --version-script %t6.script -shared %t.o %t2.so -o %t6.so 2>&1 | \ | 37 | # RUN: not ld.lld --version-script %t6.script -shared %t.o %t2.so -o /dev/null 2>&1 | \ |
| 38 | # RUN: FileCheck -check-prefix=WARN2 %s | 38 | # RUN: FileCheck -check-prefix=ERR3 %s |
| 39 | # WARN2: duplicate symbol 'foo1' in version script | 39 | # ERR3: duplicate symbol 'foo1' in version script |
| 40 | 40 | ||
| 41 | # RUN: echo "{ foo1; foo2; };" > %t.list | 41 | # RUN: echo "{ foo1; foo2; };" > %t.list |
| 42 | # RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2 | 42 | # RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2 |
| ... | @@ -213,6 +213,9 @@ | ... | @@ -213,6 +213,9 @@ |
| 213 | # ALL-NEXT: } | 213 | # ALL-NEXT: } |
| 214 | # ALL-NEXT: ] | 214 | # ALL-NEXT: ] |
| 215 | 215 | ||
| 216 | # RUN: echo "VERSION_1.0 { global: foo1; foo1; local: *; };" > %t8.script | ||
| 217 | # RUN: ld.lld --version-script %t8.script -shared %t.o -o /dev/null --fatal-warnings | ||
| 218 | |||
| 216 | .globl foo1 | 219 | .globl foo1 |
| 217 | foo1: | 220 | foo1: |
| 218 | call bar@PLT | 221 | call bar@PLT |
deps/lld/test/ELF/version-symbol-error.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | // RUN: echo "V1 {};" > %t.script | 3 | // RUN: echo "V1 {};" > %t.script |
| 4 | // RUN: not ld.lld -shared -version-script=%t.script %t.o -o %t.so 2>&1 \ | 4 | // RUN: not ld.lld -shared -version-script=%t.script %t.o -o /dev/null 2>&1 \ |
| 5 | // RUN: | FileCheck %s | 5 | // RUN: | FileCheck %s |
| 6 | 6 | ||
| 7 | // CHECK: .o: symbol foo@V2 has undefined version V2 | 7 | // CHECK: .o: symbol foo@V2 has undefined version V2 |
deps/lld/test/ELF/version-undef-sym.s+1-1| ... | @@ -35,7 +35,7 @@ | ... | @@ -35,7 +35,7 @@ |
| 35 | // CHECK: Name: bar | 35 | // CHECK: Name: bar |
| 36 | 36 | ||
| 37 | // But now we can successfully find bar. | 37 | // But now we can successfully find bar. |
| 38 | // RUN: ld.lld %t.o %p/Inputs/version-undef-sym.so -o %t.exe | 38 | // RUN: ld.lld %t.o %p/Inputs/version-undef-sym.so -o /dev/null |
| 39 | 39 | ||
| 40 | .global _start | 40 | .global _start |
| 41 | _start: | 41 | _start: |
deps/lld/test/ELF/visibility.s+1-1| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2 | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2 |
| 3 | // RUN: ld.lld -shared %t %t2 -o %t3 | 4 | // RUN: ld.lld -shared %t %t2 -o %t3 |
| 4 | // RUN: llvm-readobj -t -dyn-symbols %t3 | FileCheck %s | 5 | // RUN: llvm-readobj -t -dyn-symbols %t3 | FileCheck %s |
| 5 | // REQUIRES: x86 | ||
| 6 | 6 | ||
| 7 | // CHECK: Symbols [ | 7 | // CHECK: Symbols [ |
| 8 | // CHECK-NEXT: Symbol { | 8 | // CHECK-NEXT: Symbol { |
deps/lld/test/ELF/warn-backrefs.s created+48| ... | @@ -0,0 +1,48 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | |||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o | ||
| 4 | # RUN: echo ".globl foo; foo:" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t2.o | ||
| 5 | # RUN: rm -f %t2.a | ||
| 6 | # RUN: llvm-ar rcs %t2.a %t2.o | ||
| 7 | |||
| 8 | # RUN: ld.lld --fatal-warnings -o %t.exe %t1.o %t2.a | ||
| 9 | # RUN: ld.lld --fatal-warnings -o %t.exe %t2.a %t1.o | ||
| 10 | # RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t1.o %t2.a | ||
| 11 | # RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t1.o --start-lib %t2.o --end-lib | ||
| 12 | |||
| 13 | # RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe --start-group %t2.a %t1.o --end-group | ||
| 14 | # RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe "-(" %t2.a %t1.o "-)" | ||
| 15 | |||
| 16 | # RUN: echo "INPUT(\"%t1.o\" \"%t2.a\")" > %t1.script | ||
| 17 | # RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t1.script | ||
| 18 | |||
| 19 | # RUN: echo "GROUP(\"%t2.a\" \"%t1.o\")" > %t2.script | ||
| 20 | # RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t2.script | ||
| 21 | |||
| 22 | # RUN: not ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t2.a %t1.o 2>&1 | FileCheck %s | ||
| 23 | # RUN: not ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t2.a "-(" %t1.o "-)" 2>&1 | FileCheck %s | ||
| 24 | # RUN: not ld.lld --fatal-warnings --warn-backrefs -o %t.exe --start-group %t2.a --end-group %t1.o 2>&1 | FileCheck %s | ||
| 25 | |||
| 26 | # RUN: echo "GROUP(\"%t2.a\")" > %t3.script | ||
| 27 | # RUN: not ld.lld --fatal-warnings --warn-backrefs -o %t.exe %t3.script %t1.o 2>&1 | FileCheck %s | ||
| 28 | # RUN: ld.lld --fatal-warnings --warn-backrefs -o %t.exe "-(" %t3.script %t1.o "-)" | ||
| 29 | |||
| 30 | # CHECK: backward reference detected: foo in {{.*}}1.o refers to {{.*}}2.a | ||
| 31 | |||
| 32 | # RUN: not ld.lld --fatal-warnings --start-group --start-group 2>&1 | FileCheck -check-prefix=START %s | ||
| 33 | # START: nested --start-group | ||
| 34 | |||
| 35 | # RUN: not ld.lld --fatal-warnings --end-group 2>&1 | FileCheck -check-prefix=END %s | ||
| 36 | # END: stray --end-group | ||
| 37 | |||
| 38 | # RUN: echo ".globl bar; bar:" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t3.o | ||
| 39 | # RUN: echo ".globl foo; foo: call bar" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t4.o | ||
| 40 | # RUN: ld.lld --fatal-warnings --warn-backrefs %t1.o --start-lib %t3.o %t4.o --end-lib -o /dev/null | ||
| 41 | |||
| 42 | # We don't report backward references to weak symbols as they can be overriden later. | ||
| 43 | # RUN: echo ".weak foo; foo:" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t5.o | ||
| 44 | # RUN: ld.lld --fatal-warnings --warn-backrefs --start-lib %t5.o --end-lib %t1.o %t2.o -o /dev/null | ||
| 45 | |||
| 46 | .globl _start, foo | ||
| 47 | _start: | ||
| 48 | call foo | ||
deps/lld/test/ELF/warn-common.s+1-3| ... | @@ -7,9 +7,7 @@ | ... | @@ -7,9 +7,7 @@ |
| 7 | # RUN: ld.lld --warn-common %t1.o %t2.o -o %t.out 2>&1 | FileCheck %s --check-prefix=WARN | 7 | # RUN: ld.lld --warn-common %t1.o %t2.o -o %t.out 2>&1 | FileCheck %s --check-prefix=WARN |
| 8 | # WARN: multiple common of arr | 8 | # WARN: multiple common of arr |
| 9 | 9 | ||
| 10 | ## no-warn-common is ignored | 10 | # RUN: ld.lld --fatal-warnings --warn-common --no-warn-common %t1.o %t2.o -o %t.out |
| 11 | # RUN: ld.lld --no-warn-common %t1.o %t2.o -o %t.out | ||
| 12 | # RUN: llvm-readobj %t.out > /dev/null | ||
| 13 | 11 | ||
| 14 | ## Report if common is overridden | 12 | ## Report if common is overridden |
| 15 | # RUN: ld.lld --warn-common %t1.o %t3.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER | 13 | # RUN: ld.lld --warn-common %t1.o %t3.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER |
deps/lld/test/ELF/warn-unresolved-symbols-hidden.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: not ld.lld -shared %t.o -o %t.so -z defs --warn-unresolved-symbols 2>&1| FileCheck %s | 3 | # RUN: not ld.lld -shared %t.o -o /dev/null -z defs --warn-unresolved-symbols 2>&1| FileCheck %s |
| 4 | 4 | ||
| 5 | # CHECK: warning: undefined symbol: foo | 5 | # CHECK: warning: undefined symbol: foo |
| 6 | # CHECK: error: undefined symbol: bar | 6 | # CHECK: error: undefined symbol: bar |
deps/lld/test/ELF/warn-unresolved-symbols.s+7-7| ... | @@ -2,11 +2,11 @@ | ... | @@ -2,11 +2,11 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o |
| 3 | 3 | ||
| 4 | ## The link should fail with an undef error by default | 4 | ## The link should fail with an undef error by default |
| 5 | # RUN: not ld.lld %t1.o -o %t3 2>&1 | \ | 5 | # RUN: not ld.lld %t1.o -o /dev/null 2>&1 | \ |
| 6 | # RUN: FileCheck -check-prefix=ERRUND %s | 6 | # RUN: FileCheck -check-prefix=ERRUND %s |
| 7 | 7 | ||
| 8 | ## --error-unresolved-symbols should generate an error | 8 | ## --error-unresolved-symbols should generate an error |
| 9 | # RUN: not ld.lld %t1.o -o %t4 --error-unresolved-symbols 2>&1 | \ | 9 | # RUN: not ld.lld %t1.o -o /dev/null --error-unresolved-symbols 2>&1 | \ |
| 10 | # RUN: FileCheck -check-prefix=ERRUND %s | 10 | # RUN: FileCheck -check-prefix=ERRUND %s |
| 11 | 11 | ||
| 12 | ## --warn-unresolved-symbols should generate a warning | 12 | ## --warn-unresolved-symbols should generate a warning |
| ... | @@ -16,19 +16,19 @@ | ... | @@ -16,19 +16,19 @@ |
| 16 | ## Test that the last option wins | 16 | ## Test that the last option wins |
| 17 | # RUN: ld.lld %t1.o -o %t5 --error-unresolved-symbols --warn-unresolved-symbols 2>&1 | \ | 17 | # RUN: ld.lld %t1.o -o %t5 --error-unresolved-symbols --warn-unresolved-symbols 2>&1 | \ |
| 18 | # RUN: FileCheck -check-prefix=WARNUND %s | 18 | # RUN: FileCheck -check-prefix=WARNUND %s |
| 19 | # RUN: not ld.lld %t1.o -o %t6 --warn-unresolved-symbols --error-unresolved-symbols 2>&1 | \ | 19 | # RUN: not ld.lld %t1.o -o /dev/null --warn-unresolved-symbols --error-unresolved-symbols 2>&1 | \ |
| 20 | # RUN: FileCheck -check-prefix=ERRUND %s | 20 | # RUN: FileCheck -check-prefix=ERRUND %s |
| 21 | 21 | ||
| 22 | ## Do not report undefines if linking relocatable or shared. | 22 | ## Do not report undefines if linking relocatable or shared. |
| 23 | ## And while we're at it, check that we can accept single - | 23 | ## And while we're at it, check that we can accept single - |
| 24 | ## variants of these options. | 24 | ## variants of these options. |
| 25 | # RUN: ld.lld -r %t1.o -o %t7 -error-unresolved-symbols 2>&1 | \ | 25 | # RUN: ld.lld -r %t1.o -o /dev/null -error-unresolved-symbols 2>&1 | \ |
| 26 | # RUN: FileCheck -allow-empty -check-prefix=NOERR %s | 26 | # RUN: FileCheck -allow-empty -check-prefix=NOERR %s |
| 27 | # RUN: ld.lld -shared %t1.o -o %t8.so --error-unresolved-symbols 2>&1 | \ | 27 | # RUN: ld.lld -shared %t1.o -o /dev/null --error-unresolved-symbols 2>&1 | \ |
| 28 | # RUN: FileCheck -allow-empty -check-prefix=NOERR %s | 28 | # RUN: FileCheck -allow-empty -check-prefix=NOERR %s |
| 29 | # RUN: ld.lld -r %t1.o -o %t9 -warn-unresolved-symbols 2>&1 | \ | 29 | # RUN: ld.lld -r %t1.o -o /dev/null -warn-unresolved-symbols 2>&1 | \ |
| 30 | # RUN: FileCheck -allow-empty -check-prefix=NOWARN %s | 30 | # RUN: FileCheck -allow-empty -check-prefix=NOWARN %s |
| 31 | # RUN: ld.lld -shared %t1.o -o %t10.so --warn-unresolved-symbols 2>&1 | \ | 31 | # RUN: ld.lld -shared %t1.o -o /dev/null --warn-unresolved-symbols 2>&1 | \ |
| 32 | # RUN: FileCheck -allow-empty -check-prefix=NOWARN %s | 32 | # RUN: FileCheck -allow-empty -check-prefix=NOWARN %s |
| 33 | 33 | ||
| 34 | # ERRUND: error: undefined symbol: undef | 34 | # ERRUND: error: undefined symbol: undef |
deps/lld/test/ELF/weak-and-strong-undef.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/weak-and-strong-undef.s -o %t2.o | 3 | # RUN: echo ".weak foo" | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o |
| 4 | # RUN: not ld.lld %t1.o %t2.o -o %t 2>&1 | FileCheck %s | 4 | # RUN: not ld.lld %t1.o %t2.o -o %t 2>&1 | FileCheck %s |
| 5 | # RUN: not ld.lld %t2.o %t1.o -o %t 2>&1 | FileCheck %s | 5 | # RUN: not ld.lld %t2.o %t1.o -o %t 2>&1 | FileCheck %s |
| 6 | 6 |
deps/lld/test/ELF/weak-shared-gc.s created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | ||
| 3 | # RUN: echo -e '.globl __cxa_finalize\n__cxa_finalize:' | \ | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o | ||
| 5 | # RUN: ld.lld %t2.o -o %t2.so -shared | ||
| 6 | # RUN: ld.lld %t1.o --as-needed --gc-sections %t2.so -o %t | ||
| 7 | # RUN: llvm-readelf -dynamic-table -dyn-symbols %t | FileCheck %s | ||
| 8 | |||
| 9 | # The crt files on linux have a weak reference to __cxa_finalize. It | ||
| 10 | # is important that a weak undefined reference is produced. Like | ||
| 11 | # other weak undefined references, the shared library is not marked as | ||
| 12 | # needed. | ||
| 13 | |||
| 14 | # CHECK-NOT: NEEDED | ||
| 15 | # CHECK: WEAK DEFAULT UND __cxa_finalize | ||
| 16 | # CHECK-NOT: NEEDED | ||
| 17 | |||
| 18 | .global _start | ||
| 19 | _start: | ||
| 20 | 	.weak	__cxa_finalize | ||
| 21 | 	call	__cxa_finalize@PLT | ||
deps/lld/test/ELF/weak-undef-lazy.s+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/weak-undef-lazy.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/weak-undef-lazy.s -o %t2.o |
| 4 | # RUN: rm -f %t2.a | 4 | # RUN: rm -f %t2.a |
| 5 | # RUN: llvm-ar rc %t2.a %t2.o | 5 | # RUN: llvm-ar rc %t2.a %t2.o |
| 6 | # RUN: ld.lld %t.o %t2.a -o %t --export-dynamic | 6 | # RUN: ld.lld %t.o %t2.a -o /dev/null --export-dynamic |
| 7 | 7 | ||
| 8 | .global _start | 8 | .global _start |
| 9 | _start: | 9 | _start: |
deps/lld/test/ELF/weak-undef-lib.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o | ||
| 3 | # RUN: echo -e '.globl foo\nfoo: ret' | \ | ||
| 4 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o | ||
| 5 | |||
| 6 | # RUN: ld.lld -shared -o %t.so %t1.o --start-lib %t2.o | ||
| 7 | # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s | ||
| 8 | |||
| 9 | # CHECK: Name: foo | ||
| 10 | # CHECK-NEXT: Value: 0x0 | ||
| 11 | # CHECK-NEXT: Size: 0 | ||
| 12 | # CHECK-NEXT: Binding: Weak | ||
| 13 | # CHECK-NEXT: Type: None | ||
| 14 | # CHECK-NEXT: Other: 0 | ||
| 15 | # CHECK-NEXT: Section: Undefined | ||
| 16 | |||
| 17 | .weak foo | ||
| 18 | .data | ||
| 19 | .quad foo | ||
deps/lld/test/ELF/whole-archive-name.s created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | ||
| 3 | // RUN: mkdir -p %t.dir | ||
| 4 | // RUN: rm -f %t.dir/liba.a | ||
| 5 | // RUN: llvm-ar rcs %t.dir/liba.a %t.o | ||
| 6 | // RUN: ld.lld -L%t.dir --whole-archive -la -o /dev/null -Map=- | FileCheck %s | ||
| 7 | |||
| 8 | .globl _start | ||
| 9 | _start: | ||
| 10 | nop | ||
| 11 | |||
| 12 | // There was a use after free of an archive name. | ||
| 13 | // Valgrind/asan would detect it. | ||
| 14 | // CHECK: liba.a(whole-archive-name.s.tmp.o):(.text) | ||
| 15 | // CHECK-NEXT: _start | ||
deps/lld/test/ELF/wrap.s+2| ... | @@ -6,6 +6,8 @@ | ... | @@ -6,6 +6,8 @@ |
| 6 | // RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s | 6 | // RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s |
| 7 | // RUN: ld.lld -o %t3 %t %t2 --wrap foo -wrap=nosuchsym | 7 | // RUN: ld.lld -o %t3 %t %t2 --wrap foo -wrap=nosuchsym |
| 8 | // RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s | 8 | // RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s |
| 9 | // RUN: ld.lld -o %t3 %t %t2 --wrap foo --wrap foo -wrap=nosuchsym | ||
| 10 | // RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s | ||
| 9 | 11 | ||
| 10 | // CHECK: _start: | 12 | // CHECK: _start: |
| 11 | // CHECK-NEXT: movl $0x11010, %edx | 13 | // CHECK-NEXT: movl $0x11010, %edx |
deps/lld/test/ELF/writable-merge.s+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | // REQUIRES: x86 | 1 | // REQUIRES: x86 |
| 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux |
| 3 | // RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | // CHECK: writable SHF_MERGE section is not supported | 4 | // CHECK: writable SHF_MERGE section is not supported |
| 5 | 5 | ||
| 6 | .section .foo,"awM",@progbits,4 | 6 | .section .foo,"awM",@progbits,4 |
deps/lld/test/ELF/writable-sec-plt-reloc.s+1-1| ... | @@ -11,4 +11,4 @@ | ... | @@ -11,4 +11,4 @@ |
| 11 | .section .bar,"awx" | 11 | .section .bar,"awx" |
| 12 | .global _start | 12 | .global _start |
| 13 | _start: | 13 | _start: |
| 14 | call foo | 14 | .long foo - . |
deps/lld/test/ELF/x86-64-dyn-rel-error.s+4-2| ... | @@ -9,6 +9,8 @@ _start: | ... | @@ -9,6 +9,8 @@ _start: |
| 9 | .data | 9 | .data |
| 10 | .long zed | 10 | .long zed |
| 11 | 11 | ||
| 12 | // CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC | 12 | // CHECK: relocation R_X86_64_32 cannot be used against symbol zed; recompile with -fPIC |
| 13 | 13 | ||
| 14 | // RUN: ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s | 14 | // RUN: ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck --check-prefix=WARN %s |
| 15 | |||
| 16 | // WARN: symbol 'zed' has no type |
deps/lld/test/ELF/x86-64-dyn-rel-error2.s+2-2| ... | @@ -2,9 +2,9 @@ | ... | @@ -2,9 +2,9 @@ |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 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/shared.s -o %t2.o | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o |
| 4 | // RUN: ld.lld %t2.o -shared -o %t2.so | 4 | // RUN: ld.lld %t2.o -shared -o %t2.so |
| 5 | // RUN: not ld.lld -shared %t.o %t2.so -o %t 2>&1 | FileCheck %s | 5 | // RUN: not ld.lld -shared %t.o %t2.so -o /dev/null 2>&1 | FileCheck %s |
| 6 | 6 | ||
| 7 | // CHECK: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC | 7 | // CHECK: relocation R_X86_64_PC32 cannot be used against symbol zed; recompile with -fPIC |
| 8 | // CHECK: >>> defined in {{.*}}.so | 8 | // CHECK: >>> defined in {{.*}}.so |
| 9 | // CHECK: >>> referenced by {{.*}}.o:(.data+0x0) | 9 | // CHECK: >>> referenced by {{.*}}.o:(.data+0x0) |
| 10 | 10 |
deps/lld/test/ELF/x86-64-dyn-rel-error3.s created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o -shared -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | # CHECK: relocation R_X86_64_8 cannot be used against symbol foo; recompile with -fPIC | ||
| 6 | # CHECK: relocation R_X86_64_16 cannot be used against symbol foo; recompile with -fPIC | ||
| 7 | # CHECK: relocation R_X86_64_PC8 cannot be used against symbol foo; recompile with -fPIC | ||
| 8 | # CHECK: relocation R_X86_64_PC16 cannot be used against symbol foo; recompile with -fPIC | ||
| 9 | |||
| 10 | .global foo | ||
| 11 | |||
| 12 | .data | ||
| 13 | .byte foo # R_X86_64_8 | ||
| 14 | .short foo # R_X86_64_16 | ||
| 15 | .byte foo - . # R_X86_64_PC8 | ||
| 16 | .short foo - . # R_X86_64_PC16 | ||
deps/lld/test/ELF/x86-64-plt-high-addr.s created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | |||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t1.o | ||
| 4 | // RUN: ld.lld -o %t.so -shared %t1.o | ||
| 5 | |||
| 6 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o | ||
| 7 | // RUN: ld.lld -o %t1.exe %t2.o %t.so -image-base=0xcafe00000000 | ||
| 8 | // RUN: llvm-objdump -s -j .got.plt %t1.exe | FileCheck %s | ||
| 9 | |||
| 10 | // CHECK: Contents of section .got.plt: | ||
| 11 | // CHECK-NEXT: cafe00002000 00300000 feca0000 00000000 00000000 | ||
| 12 | // CHECK-NEXT: cafe00002010 00000000 00000000 26100000 feca0000 | ||
| 13 | |||
| 14 | // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o | ||
| 15 | // RUN: ld.lld -o %t2.exe %t2.o %t.so -image-base=0xcafe00000000 -z retpolineplt | ||
| 16 | // RUN: llvm-objdump -s -j .got.plt %t2.exe | FileCheck -check-prefix=RETPOLINE %s | ||
| 17 | |||
| 18 | // RETPOLINE: Contents of section .got.plt: | ||
| 19 | // RETPOLINE-NEXT: cafe00002000 00300000 feca0000 00000000 00000000 | ||
| 20 | // RETPOLINE-NEXT: cafe00002010 00000000 00000000 51100000 feca0000 | ||
| 21 | |||
| 22 | .global _start | ||
| 23 | _start: | ||
| 24 | jmp bar@PLT | ||
deps/lld/test/ELF/x86-64-reloc-16.s+2-2| ... | @@ -3,12 +3,12 @@ | ... | @@ -3,12 +3,12 @@ |
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-16.s -o %t1 | 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 | 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 | 5 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 6 | // RUN: ld.lld -shared %t %t1 -o %t3 | 6 | // RUN: ld.lld -shared %t %t1 -o /dev/null |
| 7 | 7 | ||
| 8 | // CHECK: Contents of section .text: | 8 | // CHECK: Contents of section .text: |
| 9 | // CHECK-NEXT: 200000 42 | 9 | // CHECK-NEXT: 200000 42 |
| 10 | 10 | ||
| 11 | // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s | 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] | 12 | // ERROR: relocation R_X86_64_16 out of range: 65536 is not in [0, 65535] |
| 13 | 13 | ||
| 14 | .short foo | 14 | .short foo |
deps/lld/test/ELF/x86-64-reloc-32-fpic.s+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | # RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | # RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | # CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC | 5 | # CHECK: relocation R_X86_64_32 cannot be used against symbol _shared; recompile with -fPIC |
| 6 | # CHECK: >>> defined in {{.*}} | 6 | # CHECK: >>> defined in {{.*}} |
| 7 | # CHECK: >>> referenced by {{.*}}:(.data+0x0) | 7 | # CHECK: >>> referenced by {{.*}}:(.data+0x0) |
| 8 | 8 |
deps/lld/test/ELF/x86-64-reloc-8.s+2-2| ... | @@ -3,12 +3,12 @@ | ... | @@ -3,12 +3,12 @@ |
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-8.s -o %t1 | 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 | 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 | 5 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 6 | // RUN: ld.lld -shared %t %t1 -o %t3 | 6 | // RUN: ld.lld -shared %t %t1 -o /dev/null |
| 7 | 7 | ||
| 8 | // CHECK: Contents of section .text: | 8 | // CHECK: Contents of section .text: |
| 9 | // CHECK-NEXT: 200000 42 | 9 | // CHECK-NEXT: 200000 42 |
| 10 | 10 | ||
| 11 | // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s | 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] | 12 | // ERROR: relocation R_X86_64_8 out of range: 256 is not in [0, 255] |
| 13 | 13 | ||
| 14 | .byte foo | 14 | .byte foo |
deps/lld/test/ELF/x86-64-reloc-debug-overflow.s created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs | ||
| 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | # RUN: not ld.lld -shared %tabs %t -o /dev/null 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | # CHECK: (.debug_info+0x0): relocation R_X86_64_32 out of range: 281474976710656 is not in [0, 4294967295]; consider recompiling with -fdebug-types-section to reduce size of debug sections | ||
| 7 | |||
| 8 | .section .debug_info,"",@progbits | ||
| 9 | .long .debug_info + 0x1000000000000 | ||
deps/lld/test/ELF/x86-64-reloc-error-reporting.s created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs | ||
| 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | ||
| 4 | |||
| 5 | // We have some code in error reporting to check that | ||
| 6 | // section belongs to the output section. Without that | ||
| 7 | // check, the linker would crash, so it is useful to test it. | ||
| 8 | // And the easy way to do that is to trigger GC. That way .text.dumb | ||
| 9 | // be collected and mentioned check will execute. | ||
| 10 | |||
| 11 | // RUN: not ld.lld -gc-sections -shared %tabs %t -o /dev/null | ||
| 12 | |||
| 13 | .section .text.dumb,"ax" | ||
| 14 | nop | ||
| 15 | |||
| 16 | .section .text,"ax" | ||
| 17 | .globl _start | ||
| 18 | _start: | ||
| 19 | movl $big, %edx | ||
deps/lld/test/ELF/x86-64-reloc-error.s+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs | 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs |
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t | 3 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t |
| 3 | // RUN: not ld.lld -shared %tabs %t -o %t2 2>&1 | FileCheck %s | 4 | // RUN: not ld.lld -shared %tabs %t -o /dev/null 2>&1 | FileCheck %s |
| 4 | // REQUIRES: x86 | ||
| 5 | 5 | ||
| 6 | movl $big, %edx | 6 | movl $big, %edx |
| 7 | movq $foo - 0x1000000000000, %rdx | 7 | movq $foo - 0x1000000000000, %rdx |
deps/lld/test/ELF/x86-64-reloc-error2.s created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | ## Check we are able to find a function symbol that encloses | ||
| 6 | ## a given location when reporting error messages. | ||
| 7 | # CHECK: {{.*}}.o:(function func): relocation R_X86_64_32S out of range: -281474974609408 is not in [-2147483648, 2147483647] | ||
| 8 | |||
| 9 | .section .text.func, "ax", %progbits | ||
| 10 | .globl func | ||
| 11 | .type func,@function | ||
| 12 | .size func, 0x10 | ||
| 13 | func: | ||
| 14 | movq func - 0x1000000000000, %rdx | ||
deps/lld/test/ELF/x86-64-reloc-gotoff64.s created+32| ... | @@ -0,0 +1,32 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | // RUN: ld.lld %t.o -shared -o %t.so | ||
| 4 | // RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION | ||
| 5 | // RUN: llvm-objdump -d %t.so | FileCheck %s | ||
| 6 | |||
| 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_. | ||
| 15 | |||
| 16 | // The assembly is generated by | ||
| 17 | // gcc -O2 -S -mcmodel=medium -fPIC a.c | ||
| 18 | // This computes the pc-relative address (runtime address) of _DYNAMIC. | ||
| 19 | // | ||
| 20 | // extern long _DYNAMIC[] __attribute__((visibility("hidden"))); | ||
| 21 | // long* dynamic() { return _DYNAMIC; } | ||
| 22 | |||
| 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 | ||
| 27 | .global dynamic | ||
| 28 | dynamic: | ||
| 29 | leaq _GLOBAL_OFFSET_TABLE_(%rip), %rdx | ||
| 30 | movabsq $_DYNAMIC@GOTOFF, %rax | ||
| 31 | addq %rdx, %rax | ||
| 32 | ret | ||
deps/lld/test/ELF/x86-64-reloc-gotpc64.s created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | ||
| 3 | // RUN: ld.lld %t.o -shared -o %t.so | ||
| 4 | // RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION | ||
| 5 | // RUN: llvm-objdump -d %t.so | FileCheck %s | ||
| 6 | |||
| 7 | // SECTION: .got PROGBITS 0000000000003070 003070 000000 | ||
| 8 | |||
| 9 | // 0x3070 (.got end) - 0x1000 = 8304 | ||
| 10 | // CHECK: gotpc64: | ||
| 11 | // CHECK-NEXT: 1000: {{.*}} movabsq $8304, %r11 | ||
| 12 | .global gotpc64 | ||
| 13 | gotpc64: | ||
| 14 | movabsq $_GLOBAL_OFFSET_TABLE_-., %r11 | ||
deps/lld/test/ELF/x86-64-reloc-pc32-fpic.s+4-3| ... | @@ -1,10 +1,11 @@ | ... | @@ -1,10 +1,11 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 3 | # RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s | 3 | # RUN: not ld.lld -shared %t.o -o /dev/null 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | # CHECK: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC | 5 | # CHECK: relocation R_X86_64_PC32 cannot be used against symbol _shared; recompile with -fPIC |
| 6 | # CHECK: >>> defined in {{.*}} | 6 | # CHECK: >>> defined in {{.*}} |
| 7 | # CHECK: >>> referenced by {{.*}}:(.data+0x1) | 7 | # CHECK: >>> referenced by {{.*}}:(.data+0x1) |
| 8 | 8 | ||
| 9 | .data | 9 | .data |
| 10 | call _shared | 10 | .byte 0xe8 |
| 11 | .long _shared - . |
deps/lld/test/ELF/x86-64-reloc-range-debug-loc.s created+36| ... | @@ -0,0 +1,36 @@ | ||
| 1 | # REQUIRES: x86 | ||
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs | ||
| 3 | # RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj | ||
| 4 | # RUN: not ld.lld %tabs %t.o -o /dev/null -shared 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | ## Check we are able to report file and location from debug information | ||
| 7 | ## when reporting such kind of errors. | ||
| 8 | # CHECK: error: test.s:3: relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295] | ||
| 9 | |||
| 10 | .section .text,"ax",@progbits | ||
| 11 | foo: | ||
| 12 | .file 1 "test.s" | ||
| 13 | .loc 1 3 | ||
| 14 | movl $big, %edx | ||
| 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 | |||
| 36 | .section .debug_line,"",@progbits | ||
deps/lld/test/ELF/x86-64-reloc-range.s+2-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // REQUIRES: x86 | ||
| 1 | // RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj | 2 | // RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj |
| 2 | // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s | 3 | // RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s |
| 3 | 4 | ||
| 4 | // CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range: 2147483648 is not in [-2147483648, 2147483647] | 5 | // CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range: 2147483648 is not in [-2147483648, 2147483647] |
| 5 | // CHECK-NOT: relocation | 6 | // CHECK-NOT: relocation |
deps/lld/test/ELF/x86-64-reloc-tpoff32-fpic.s+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: not ld.lld %t.o -shared -o %t.so 2>&1 | FileCheck %s | 3 | # RUN: not ld.lld %t.o -shared -o /dev/null 2>&1 | FileCheck %s |
| 4 | 4 | ||
| 5 | # CHECK: relocation R_X86_64_TPOFF32 cannot be used against shared object; recompile with -fPIC | 5 | # CHECK: relocation R_X86_64_TPOFF32 cannot be used against symbol var; recompile with -fPIC |
| 6 | # CHECK: >>> defined in {{.*}}.o | 6 | # CHECK: >>> defined in {{.*}}.o |
| 7 | # CHECK: >>> referenced by {{.*}}.o:(.tdata+0xC) | 7 | # CHECK: >>> referenced by {{.*}}.o:(.tdata+0xC) |
| 8 | 8 |
deps/lld/test/ELF/x86-64-retpoline-linkerscript.s created+67| ... | @@ -0,0 +1,67 @@ | ||
| 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 %p/Inputs/shared.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | // RUN: echo "SECTIONS { \ | ||
| 7 | // RUN: .text : { *(.text) } \ | ||
| 8 | // RUN: .plt : { *(.plt) } \ | ||
| 9 | // RUN: .got.plt : { *(.got.plt) } \ | ||
| 10 | // RUN: .dynstr : { *(.dynstr) } \ | ||
| 11 | // RUN: }" > %t.script | ||
| 12 | // RUN: ld.lld -shared %t1.o %t2.so -o %t.exe -z retpolineplt --script %t.script | ||
| 13 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | ||
| 14 | |||
| 15 | // CHECK: Disassembly of section .plt: | ||
| 16 | // 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 | ||
| 19 | // CHECK-NEXT: 1d: e8 0e 00 00 00 callq 14 <.plt+0x20> | ||
| 20 | // CHECK-NEXT: 22: f3 90 pause | ||
| 21 | // CHECK-NEXT: 24: 0f ae e8 lfence | ||
| 22 | // CHECK-NEXT: 27: eb f9 jmp -7 <.plt+0x12> | ||
| 23 | // CHECK-NEXT: 29: cc int3 | ||
| 24 | // CHECK-NEXT: 2a: cc int3 | ||
| 25 | // CHECK-NEXT: 2b: cc int3 | ||
| 26 | // CHECK-NEXT: 2c: cc int3 | ||
| 27 | // CHECK-NEXT: 2d: cc int3 | ||
| 28 | // CHECK-NEXT: 2e: cc int3 | ||
| 29 | // CHECK-NEXT: 2f: cc int3 | ||
| 30 | // CHECK-NEXT: 30: 4c 89 1c 24 movq %r11, (%rsp) | ||
| 31 | // CHECK-NEXT: 34: c3 retq | ||
| 32 | // CHECK-NEXT: 35: cc int3 | ||
| 33 | // CHECK-NEXT: 36: cc int3 | ||
| 34 | // CHECK-NEXT: 37: cc int3 | ||
| 35 | // CHECK-NEXT: 38: cc int3 | ||
| 36 | // CHECK-NEXT: 39: cc int3 | ||
| 37 | // CHECK-NEXT: 3a: cc int3 | ||
| 38 | // CHECK-NEXT: 3b: cc int3 | ||
| 39 | // CHECK-NEXT: 3c: cc int3 | ||
| 40 | // CHECK-NEXT: 3d: cc int3 | ||
| 41 | // CHECK-NEXT: 3e: cc int3 | ||
| 42 | // CHECK-NEXT: 3f: cc int3 | ||
| 43 | // CHECK-NEXT: 40: 4c 8b 1d 51 00 00 00 movq 81(%rip), %r11 | ||
| 44 | // CHECK-NEXT: 47: e8 e4 ff ff ff callq -28 <.plt+0x20> | ||
| 45 | // CHECK-NEXT: 4c: e9 d1 ff ff ff jmp -47 <.plt+0x12> | ||
| 46 | // CHECK-NEXT: 51: 68 00 00 00 00 pushq $0 | ||
| 47 | // CHECK-NEXT: 56: e9 b5 ff ff ff jmp -75 <.plt> | ||
| 48 | // CHECK-NEXT: 5b: cc int3 | ||
| 49 | // CHECK-NEXT: 5c: cc int3 | ||
| 50 | // CHECK-NEXT: 5d: cc int3 | ||
| 51 | // CHECK-NEXT: 5e: cc int3 | ||
| 52 | // CHECK-NEXT: 5f: cc int3 | ||
| 53 | // CHECK-NEXT: 60: 4c 8b 1d 39 00 00 00 movq 57(%rip), %r11 | ||
| 54 | // CHECK-NEXT: 67: e8 c4 ff ff ff callq -60 <.plt+0x20> | ||
| 55 | // CHECK-NEXT: 6c: e9 b1 ff ff ff jmp -79 <.plt+0x12> | ||
| 56 | // CHECK-NEXT: 71: 68 01 00 00 00 pushq $1 | ||
| 57 | // CHECK-NEXT: 76: e9 95 ff ff ff jmp -107 <.plt> | ||
| 58 | // CHECK-NEXT: 7b: cc int3 | ||
| 59 | // CHECK-NEXT: 7c: cc int3 | ||
| 60 | // CHECK-NEXT: 7d: cc int3 | ||
| 61 | // CHECK-NEXT: 7e: cc int3 | ||
| 62 | // CHECK-NEXT: 7f: cc int3 | ||
| 63 | |||
| 64 | .global _start | ||
| 65 | _start: | ||
| 66 | jmp bar@PLT | ||
| 67 | jmp zed@PLT | ||
deps/lld/test/ELF/x86-64-retpoline-znow-linkerscript.s created+54| ... | @@ -0,0 +1,54 @@ | ||
| 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 %p/Inputs/shared.s -o %t2.o | ||
| 4 | // RUN: ld.lld -shared %t2.o -o %t2.so | ||
| 5 | |||
| 6 | // RUN: echo "SECTIONS { \ | ||
| 7 | // RUN: .text : { *(.text) } \ | ||
| 8 | // RUN: .plt : { *(.plt) } \ | ||
| 9 | // RUN: .got.plt : { *(.got.plt) } \ | ||
| 10 | // RUN: .dynstr : { *(.dynstr) } \ | ||
| 11 | // RUN: }" > %t.script | ||
| 12 | // RUN: ld.lld -shared %t1.o %t2.so -o %t.exe -z retpolineplt -z now --script %t.script | ||
| 13 | // RUN: llvm-objdump -d -s %t.exe | FileCheck %s | ||
| 14 | |||
| 15 | // CHECK: Disassembly of section .plt: | ||
| 16 | // CHECK-NEXT: .plt: | ||
| 17 | // CHECK-NEXT: 10:	e8 0b 00 00 00 	callq	11 <.plt+0x10> | ||
| 18 | // CHECK-NEXT: 15:	f3 90 	pause | ||
| 19 | // CHECK-NEXT: 17:	0f ae e8 	lfence | ||
| 20 | // CHECK-NEXT: 1a:	eb f9 	jmp	-7 <.plt+0x5> | ||
| 21 | // CHECK-NEXT: 1c:	cc 	int3 | ||
| 22 | // CHECK-NEXT: 1d:	cc 	int3 | ||
| 23 | // CHECK-NEXT: 1e:	cc 	int3 | ||
| 24 | // CHECK-NEXT: 1f:	cc 	int3 | ||
| 25 | // CHECK-NEXT: 20:	4c 89 1c 24 	movq	%r11, (%rsp) | ||
| 26 | // CHECK-NEXT: 24:	c3 	retq | ||
| 27 | // CHECK-NEXT: 25:	cc 	int3 | ||
| 28 | // CHECK-NEXT: 26:	cc 	int3 | ||
| 29 | // CHECK-NEXT: 27:	cc 	int3 | ||
| 30 | // CHECK-NEXT: 28:	cc 	int3 | ||
| 31 | // CHECK-NEXT: 29:	cc 	int3 | ||
| 32 | // CHECK-NEXT: 2a:	cc 	int3 | ||
| 33 | // CHECK-NEXT: 2b:	cc 	int3 | ||
| 34 | // CHECK-NEXT: 2c:	cc 	int3 | ||
| 35 | // CHECK-NEXT: 2d:	cc 	int3 | ||
| 36 | // CHECK-NEXT: 2e:	cc 	int3 | ||
| 37 | // CHECK-NEXT: 2f:	cc 	int3 | ||
| 38 | // CHECK-NEXT: 30:	4c 8b 1d 31 00 00 00 	movq	49(%rip), %r11 | ||
| 39 | // CHECK-NEXT: 37:	e9 d4 ff ff ff 	jmp	-44 <.plt> | ||
| 40 | // CHECK-NEXT: 3c:	cc 	int3 | ||
| 41 | // CHECK-NEXT: 3d:	cc 	int3 | ||
| 42 | // CHECK-NEXT: 3e:	cc 	int3 | ||
| 43 | // CHECK-NEXT: 3f:	cc 	int3 | ||
| 44 | // CHECK-NEXT: 40: 4c 8b 1d 29 00 00 00 	movq	41(%rip), %r11 | ||
| 45 | // CHECK-NEXT: 47:	e9 c4 ff ff ff 	jmp	-60 <.plt> | ||
| 46 | // CHECK-NEXT: 4c:	cc 	int3 | ||
| 47 | // CHECK-NEXT: 4d:	cc 	int3 | ||
| 48 | // CHECK-NEXT: 4e:	cc 	int3 | ||
| 49 | // CHECK-NEXT: 4f:	cc 	int3 | ||
| 50 | |||
| 51 | .global _start | ||
| 52 | _start: | ||
| 53 | jmp bar@PLT | ||
| 54 | jmp zed@PLT | ||
deps/lld/test/ELF/x86-64-split-stack-prologue-adjust-fail.s created+31| ... | @@ -0,0 +1,31 @@ | ||
| 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 %p/Inputs/x86-64-split-stack-main.s -o %t2.o | ||
| 4 | |||
| 5 | # RUN: not ld.lld --defsym __morestack=0x100 %t1.o %t2.o -o %t 2>&1 | FileCheck %s | ||
| 6 | |||
| 7 | # An unknown prologue gives a match failure | ||
| 8 | # CHECK: unable to adjust the enclosing function's | ||
| 9 | |||
| 10 | # RUN: not ld.lld -r --defsym __morestack=0x100 %t1.o %t2.o -o %t 2>&1 | FileCheck %s -check-prefix=RELOCATABLE | ||
| 11 | # RELOCATABLE: Cannot mix split-stack and non-split-stack in a relocatable link | ||
| 12 | |||
| 13 | 	.text | ||
| 14 | |||
| 15 | 	.global	unknown_prologue | ||
| 16 | 	.type	unknown_prologue,@function | ||
| 17 | unknown_prologue: | ||
| 18 | 	push	%rbp | ||
| 19 | 	mov	%rsp,%rbp | ||
| 20 | 	cmp	%fs:0x70,%rsp | ||
| 21 | 	jae	1f | ||
| 22 | 	callq	__morestack | ||
| 23 | 	retq | ||
| 24 | 1: | ||
| 25 | 	callq	non_split | ||
| 26 | 	leaveq | ||
| 27 | 	retq | ||
| 28 | |||
| 29 | 	.size	unknown_prologue,. - unknown_prologue | ||
| 30 | |||
| 31 | 	.section	.note.GNU-split-stack,"",@progbits | ||
deps/lld/test/ELF/x86-64-split-stack-prologue-adjust-silent.s created+32| ... | @@ -0,0 +1,32 @@ | ||
| 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 %p/Inputs/x86-64-split-stack-main.s -o %t2.o | ||
| 4 | |||
| 5 | # RUN: ld.lld --defsym __morestack=0x100 %t1.o %t2.o -o %t | ||
| 6 | # RUN: llvm-objdump -d %t 2>&1 | FileCheck %s | ||
| 7 | |||
| 8 | # An unknown prologue ordinarily gives a match failure, except that this | ||
| 9 | # object file includes a .note.GNU-no-split-stack section, which tells the | ||
| 10 | # linker to expect such prologues, and therefore not error. | ||
| 11 | |||
| 12 | # CHECK: __morestack | ||
| 13 | |||
| 14 | 	.text | ||
| 15 | |||
| 16 | 	.global	unknown_prologue | ||
| 17 | 	.type	unknown_prologue,@function | ||
| 18 | unknown_prologue: | ||
| 19 | 	push %rbp | ||
| 20 | 	mov %rsp,%rbp | ||
| 21 | 	cmp %fs:0x70,%rsp | ||
| 22 | 	jae 1f | ||
| 23 | 	callq __morestack | ||
| 24 | 	retq | ||
| 25 | 1: | ||
| 26 | 	callq non_split | ||
| 27 | 	leaveq | ||
| 28 | 	retq | ||
| 29 | |||
| 30 | 	.size unknown_prologue,. - unknown_prologue | ||
| 31 | 	.section .note.GNU-split-stack,"",@progbits | ||
| 32 | 	.section .note.GNU-no-split-stack,"",@progbits | ||
deps/lld/test/ELF/x86-64-split-stack-prologue-adjust-success.s created+124| ... | @@ -0,0 +1,124 @@ | ||
| 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 %p/Inputs/x86-64-split-stack-main.s -o %t2.o | ||
| 4 | |||
| 5 | # RUN: ld.lld --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 %t1.o %t2.o -o %t -z notext | ||
| 6 | # RUN: llvm-objdump -d %t | FileCheck %s | ||
| 7 | |||
| 8 | # Avoid duplicating the prologue for every test via macros. | ||
| 9 | |||
| 10 | .macro prologue1 function_to_call | ||
| 11 | 	.global	prologue1_calls_\function_to_call | ||
| 12 | 	.type	prologue1_calls_\function_to_call,@function | ||
| 13 | prologue1_calls_\function_to_call: | ||
| 14 | 	cmp %fs:0x70,%rsp | ||
| 15 | 	jae 1f | ||
| 16 | 	callq __morestack | ||
| 17 | 	retq | ||
| 18 | 1: | ||
| 19 | 	# Various and duplicate calls to ensure every code path is taken. | ||
| 20 | 	callq \function_to_call | ||
| 21 | 	callq \function_to_call | ||
| 22 | 	callq 1b | ||
| 23 | 	callq non_function_text_symbol | ||
| 24 | 	retq | ||
| 25 | 	.size	prologue1_calls_\function_to_call,. - prologue1_calls_\function_to_call | ||
| 26 | .endm | ||
| 27 | |||
| 28 | .macro prologue2 function_to_call register | ||
| 29 | 	.global	prologue2_calls_\function_to_call\register | ||
| 30 | 	.type	prologue2_calls_\function_to_call\register,@function | ||
| 31 | prologue2_calls_\function_to_call\register: | ||
| 32 | 	lea	-0x200(%rsp),%\register | ||
| 33 | 	cmp	%fs:0x70,%\register | ||
| 34 | 	jae	1f | ||
| 35 | 	callq	__morestack | ||
| 36 | 	retq | ||
| 37 | 1: | ||
| 38 | 	# Various and duplicate calls to ensure every code path is taken. | ||
| 39 | 	callq	\function_to_call | ||
| 40 | 	callq	\function_to_call | ||
| 41 | 	callq 1b | ||
| 42 | 	callq non_function_text_symbol | ||
| 43 | 	retq | ||
| 44 | 	.size	prologue2_calls_\function_to_call\register,. - prologue2_calls_\function_to_call\register | ||
| 45 | .endm | ||
| 46 | |||
| 47 | 	.local foo | ||
| 48 | foo: | ||
| 49 | 	.section .text,"ax",@progbits | ||
| 50 | 	.quad foo | ||
| 51 | |||
| 52 | 	.text | ||
| 53 | |||
| 54 | # For split-stack code calling split-stack code, ensure prologue v1 still | ||
| 55 | # calls plain __morestack, and that any raw bytes written to the prologue | ||
| 56 | # make sense. | ||
| 57 | # CHECK: prologue1_calls_split: | ||
| 58 | # CHECK-NEXT: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%rsp | ||
| 59 | # CHECK: jae{{.*$}} | ||
| 60 | # CHECK-NEXT: callq{{.*}}<__morestack> | ||
| 61 | |||
| 62 | prologue1 split | ||
| 63 | |||
| 64 | # For split-stack code calling split-stack code, ensure prologue v2 still | ||
| 65 | # calls plain __morestack, that any raw bytes written to the prologue | ||
| 66 | # make sense, and that the register number is preserved. | ||
| 67 | # CHECK: prologue2_calls_splitr10: | ||
| 68 | # CHECK-NEXT: lea{{.*}} -{{[0-9]+}}(%rsp),{{.*}}%r10 | ||
| 69 | # CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r{{[0-9]+}} | ||
| 70 | # CHECK: jae{{.*}} | ||
| 71 | # CHECK-NEXT: callq{{.*}}<__morestack> | ||
| 72 | |||
| 73 | prologue2 split r10 | ||
| 74 | |||
| 75 | # CHECK: prologue2_calls_splitr11: | ||
| 76 | # CHECK-NEXT: lea{{.*}} -{{[0-9]+}}(%rsp),{{.*}}%r11 | ||
| 77 | # CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r{{[0-9]+}} | ||
| 78 | # CHECK: jae{{.*}} | ||
| 79 | # CHECK-NEXT: callq{{.*}}<__morestack> | ||
| 80 | |||
| 81 | prologue2 split r11 | ||
| 82 | |||
| 83 | # For split-stack code calling non-split-stack code, ensure prologue v1 | ||
| 84 | # calls __morestack_non_split, and that any raw bytes written to the prologue | ||
| 85 | # make sense. | ||
| 86 | # CHECK: prologue1_calls_non_split: | ||
| 87 | # CHECK-NEXT: stc{{.*$}} | ||
| 88 | # CHECK-NEXT: nopl{{.*$}} | ||
| 89 | # CHECK: jae{{.*$}} | ||
| 90 | # CHECK-NEXT: callq{{.*}}<__morestack_non_split> | ||
| 91 | |||
| 92 | prologue1 non_split | ||
| 93 | |||
| 94 | # For split-stack code calling non-split-stack code, ensure prologue v2 | ||
| 95 | # calls __morestack_non_split, that any raw bytes written to the prologue | ||
| 96 | # make sense, and that the register number is preserved | ||
| 97 | # CHECK: prologue2_calls_non_splitr10: | ||
| 98 | # CHECK-NEXT: lea{{.*$}} | ||
| 99 | # CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r10 | ||
| 100 | # CHECK: jae{{.*$}} | ||
| 101 | # CHECK-NEXT: callq{{.*}}<__morestack_non_split> | ||
| 102 | |||
| 103 | prologue2 non_split r10 | ||
| 104 | |||
| 105 | # CHECK: prologue2_calls_non_splitr11: | ||
| 106 | # CHECK-NEXT: lea{{.*$}} | ||
| 107 | # CHECK: cmp{{.*}}%fs:{{[^,]*}},{{.*}}%r11 | ||
| 108 | # CHECK: jae{{.*$}} | ||
| 109 | # CHECK-NEXT: callq{{.*}}<__morestack_non_split> | ||
| 110 | |||
| 111 | prologue2 non_split r11 | ||
| 112 | #	call foo@plt # for code-coverage. | ||
| 113 | |||
| 114 | |||
| 115 | |||
| 116 | 	.global	split | ||
| 117 | 	.type	split,@function | ||
| 118 | split: | ||
| 119 | 	retq | ||
| 120 | |||
| 121 | 	.size	split,. - split | ||
| 122 | |||
| 123 | 	.section	.note.GNU-stack,"",@progbits | ||
| 124 | 	.section	.note.GNU-split-stack,"",@progbits | ||
deps/lld/test/ELF/x86-64-tls-ld-local.s created+29| ... | @@ -0,0 +1,29 @@ | ||
| 1 | // REQUIRES: x86 | ||
| 2 | // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux | ||
| 3 | // RUN: ld.lld %t.o -o %t.so -shared | ||
| 4 | // RUN: llvm-readobj -r -s %t.so | FileCheck %s | ||
| 5 | |||
| 6 | // CHECK: Relocations [ | ||
| 7 | // CHECK-NEXT: Section ({{.*}}) .rela.dyn { | ||
| 8 | // CHECK-NEXT: R_X86_64_DTPMOD64 - 0x0 | ||
| 9 | // CHECK-NEXT: R_X86_64_DTPMOD64 - 0x0 | ||
| 10 | // CHECK-NEXT: } | ||
| 11 | // CHECK-NEXT: Section ({{.*}}) .rela.plt { | ||
| 12 | // CHECK-NEXT: R_X86_64_JUMP_SLOT __tls_get_addr 0x0 | ||
| 13 | // CHECK-NEXT: } | ||
| 14 | // CHECK-NEXT: ] | ||
| 15 | |||
| 16 | 	data16 | ||
| 17 | 	leaq	bar@TLSGD(%rip), %rdi | ||
| 18 | 	data16 | ||
| 19 | 	data16 | ||
| 20 | 	rex64 | ||
| 21 | 	callq	__tls_get_addr@PLT | ||
| 22 | |||
| 23 | 	leaq	bar@TLSLD(%rip), %rdi | ||
| 24 | 	callq	__tls_get_addr@PLT | ||
| 25 | 	leaq	bar@DTPOFF(%rax), %rax | ||
| 26 | |||
| 27 | 	.section	.tdata,"awT",@progbits | ||
| 28 | bar: | ||
| 29 | 	.long	42 | ||
deps/lld/test/ELF/zdefs.s+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | # REQUIRES: x86 | ||
| 1 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
| 2 | # RUN: ld.lld -shared %t.o -o %t1.so | 3 | # RUN: ld.lld -shared %t.o -o %t1.so |
| 3 | 4 |
deps/lld/test/ELF/znotext-plt-relocations-protected.s+2-2| ... | @@ -2,10 +2,10 @@ | ... | @@ -2,10 +2,10 @@ |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 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/znotext-plt-relocations-protected.s -o %t2.o | 3 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/znotext-plt-relocations-protected.s -o %t2.o |
| 4 | # RUN: ld.lld %t2.o -o %t2.so -shared | 4 | # RUN: ld.lld %t2.o -o %t2.so -shared |
| 5 | # RUN: not ld.lld -z notext %t.o %t2.so -o %t 2>&1 | FileCheck %s | 5 | # RUN: not ld.lld -z notext %t.o %t2.so -o /dev/null 2>&1 | FileCheck %s |
| 6 | 6 | ||
| 7 | # CHECK: error: cannot preempt symbol: foo | 7 | # CHECK: error: cannot preempt symbol: foo |
| 8 | 8 | ||
| 9 | .global _start | 9 | .global _start |
| 10 | _start: | 10 | _start: |
| 11 | callq foo | 11 | .long foo - . |
deps/lld/test/ELF/znotext-weak-undef.s+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
| 3 | # RUN: not ld.lld -z notext -shared %t.o -o %t 2>&1 | FileCheck %s | 3 | # RUN: not ld.lld -z notext -shared %t.o -o %t 2>&1 | FileCheck %s |
| 4 | # CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC | 4 | # CHECK: relocation R_X86_64_32 cannot be used against symbol foo; recompile with -fPIC |
| 5 | 5 | ||
| 6 | # RUN: ld.lld -z notext %t.o -o %t | 6 | # RUN: ld.lld -z notext %t.o -o %t |
| 7 | # RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=EXE | 7 | # RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=EXE |
deps/lld/test/ELF/ztext-text-notext.s deleted-36| ... | @@ -1,36 +0,0 @@ | ||
| 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/ztext-text-notext.s -o %t2.o | ||
| 4 | # RUN: ld.lld %t2.o -o %t2.so -shared | ||
| 5 | # RUN: ld.lld -z notext %t.o %t2.so -o %t -shared | ||
| 6 | # RUN: llvm-readobj -dynamic-table -r %t | FileCheck %s | ||
| 7 | # RUN: ld.lld -z notext %t.o %t2.so -o %t2 -pie | ||
| 8 | # RUN: llvm-readobj -dynamic-table -r %t2 | FileCheck %s | ||
| 9 | # RUN: ld.lld -z notext %t.o %t2.so -o %t3 | ||
| 10 | # RUN: llvm-readobj -dynamic-table -r %t3 | FileCheck --check-prefix=STATIC %s | ||
| 11 | |||
| 12 | # If the preference is to have text relocations, don't create plt of copy relocations. | ||
| 13 | |||
| 14 | # CHECK: Relocations [ | ||
| 15 | # CHECK-NEXT: Section {{.*}} .rela.dyn { | ||
| 16 | # CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x1000 | ||
| 17 | # CHECK-NEXT: 0x1008 R_X86_64_64 bar 0x0 | ||
| 18 | # CHECK-NEXT: 0x1010 R_X86_64_PC64 zed 0x0 | ||
| 19 | # CHECK-NEXT: } | ||
| 20 | # CHECK-NEXT: ] | ||
| 21 | # CHECK: DynamicSection [ | ||
| 22 | # CHECK: 0x0000000000000016 TEXTREL 0x0 | ||
| 23 | |||
| 24 | # STATIC: Relocations [ | ||
| 25 | # STATIC-NEXT: Section {{.*}} .rela.dyn { | ||
| 26 | # STATIC-NEXT: 0x201008 R_X86_64_64 bar 0x0 | ||
| 27 | # STATIC-NEXT: 0x201010 R_X86_64_PC64 zed 0x0 | ||
| 28 | # STATIC-NEXT: } | ||
| 29 | # STATIC-NEXT: ] | ||
| 30 | # STATIC: DynamicSection [ | ||
| 31 | # STATIC: 0x0000000000000016 TEXTREL 0x0 | ||
| 32 | |||
| 33 | foo: | ||
| 34 | .quad foo | ||
| 35 | .quad bar | ||
| 36 | .quad zed - . | ||
deps/lld/test/ELF/ztext.s created+45| ... | @@ -0,0 +1,45 @@ | ||
| 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/ztext.s -o %t2.o | ||
| 4 | # RUN: ld.lld %t2.o -o %t2.so -shared | ||
| 5 | |||
| 6 | # RUN: ld.lld -z notext %t.o %t2.so -o %t -shared | ||
| 7 | # RUN: llvm-readobj -dynamic-table -r %t | FileCheck %s | ||
| 8 | # RUN: ld.lld -z notext %t.o %t2.so -o %t2 -pie | ||
| 9 | # RUN: llvm-readobj -dynamic-table -r %t2 | FileCheck %s | ||
| 10 | # RUN: ld.lld -z notext %t.o %t2.so -o %t3 | ||
| 11 | # RUN: llvm-readobj -dynamic-table -r %t3 | FileCheck --check-prefix=STATIC %s | ||
| 12 | |||
| 13 | # RUN: not ld.lld %t.o %t2.so -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s | ||
| 14 | # RUN: not ld.lld -z text %t.o %t2.so -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s | ||
| 15 | # ERR: error: can't create dynamic relocation | ||
| 16 | |||
| 17 | # If the preference is to have text relocations, don't create plt of copy relocations. | ||
| 18 | |||
| 19 | # CHECK: Relocations [ | ||
| 20 | # CHECK-NEXT: Section {{.*}} .rela.dyn { | ||
| 21 | # CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x1000 | ||
| 22 | # CHECK-NEXT: 0x1008 R_X86_64_64 bar 0x0 | ||
| 23 | # CHECK-NEXT: 0x1010 R_X86_64_PC64 zed 0x0 | ||
| 24 | # CHECK-NEXT: } | ||
| 25 | # CHECK-NEXT: ] | ||
| 26 | |||
| 27 | # CHECK: DynamicSection [ | ||
| 28 | # CHECK: FLAGS TEXTREL | ||
| 29 | # CHECK: TEXTREL 0x0 | ||
| 30 | |||
| 31 | # STATIC: Relocations [ | ||
| 32 | # STATIC-NEXT: Section {{.*}} .rela.dyn { | ||
| 33 | # STATIC-NEXT: 0x201008 R_X86_64_64 bar 0x0 | ||
| 34 | # STATIC-NEXT: 0x201010 R_X86_64_PC64 zed 0x0 | ||
| 35 | # STATIC-NEXT: } | ||
| 36 | # STATIC-NEXT: ] | ||
| 37 | |||
| 38 | # STATIC: DynamicSection [ | ||
| 39 | # STATIC: FLAGS TEXTREL | ||
| 40 | # STATIC: TEXTREL 0x0 | ||
| 41 | |||
| 42 | foo: | ||
| 43 | .quad foo | ||
| 44 | .quad bar | ||
| 45 | .quad zed - . | ||
deps/lld/test/MinGW/driver.test+21| ... | @@ -90,6 +90,15 @@ RUN: ld.lld -### -m i386pep foo.o -s | FileCheck -check-prefix STRIP %s | ... | @@ -90,6 +90,15 @@ RUN: ld.lld -### -m i386pep foo.o -s | FileCheck -check-prefix STRIP %s |
| 90 | RUN: ld.lld -### -m i386pep foo.o --strip-all | FileCheck -check-prefix STRIP %s | 90 | RUN: ld.lld -### -m i386pep foo.o --strip-all | FileCheck -check-prefix STRIP %s |
| 91 | STRIP-NOT: -debug:dwarf | 91 | STRIP-NOT: -debug:dwarf |
| 92 | 92 | ||
| 93 | RUN: ld.lld -### -m i386pep foo.o -S | FileCheck -check-prefix STRIP-DEBUG %s | ||
| 94 | RUN: ld.lld -### -m i386pep foo.o --strip-debug | FileCheck -check-prefix STRIP-DEBUG %s | ||
| 95 | STRIP-DEBUG: -debug:symtab | ||
| 96 | STRIP-DEBUG-NOT: -debug:dwarf | ||
| 97 | |||
| 98 | RUN: ld.lld -### -m i386pep foo.o -pdb out.pdb | FileCheck -check-prefix PDB %s | ||
| 99 | PDB: -debug -pdb:out.pdb | ||
| 100 | PDB-NOT: -debug:dwarf | ||
| 101 | |||
| 93 | RUN: ld.lld -### -m i386pep foo.o --large-address-aware | FileCheck -check-prefix LARGE-ADDRESS-AWARE %s | 102 | RUN: ld.lld -### -m i386pep foo.o --large-address-aware | FileCheck -check-prefix LARGE-ADDRESS-AWARE %s |
| 94 | LARGE-ADDRESS-AWARE: -largeaddressaware | 103 | LARGE-ADDRESS-AWARE: -largeaddressaware |
| 95 | 104 | ||
| ... | @@ -124,3 +133,15 @@ ICF-NONE: -opt:noicf | ... | @@ -124,3 +133,15 @@ ICF-NONE: -opt:noicf |
| 124 | RUN: ld.lld -### -m i386pep foo.o --icf=all | FileCheck -check-prefix ICF %s | 133 | RUN: ld.lld -### -m i386pep foo.o --icf=all | FileCheck -check-prefix ICF %s |
| 125 | RUN: ld.lld -### -m i386pep foo.o -icf=all | FileCheck -check-prefix ICF %s | 134 | RUN: ld.lld -### -m i386pep foo.o -icf=all | FileCheck -check-prefix ICF %s |
| 126 | ICF: -opt:icf | 135 | ICF: -opt:icf |
| 136 | |||
| 137 | RUN: ld.lld -### -m i386pep --start-group foo.o --end-group | ||
| 138 | |||
| 139 | RUN: ld.lld -### foo.o -m i386pe -shared --kill-at | FileCheck -check-prefix=KILL-AT %s | ||
| 140 | RUN: ld.lld -### foo.o -m i386pe -shared -kill-at | FileCheck -check-prefix=KILL-AT %s | ||
| 141 | KILL-AT: -kill-at | ||
| 142 | |||
| 143 | RUN: ld.lld -### foo.o -m i386pep -Map bar.map | FileCheck -check-prefix=MAP %s | ||
| 144 | RUN: ld.lld -### foo.o -m i386pep --Map bar.map | FileCheck -check-prefix=MAP %s | ||
| 145 | RUN: ld.lld -### foo.o -m i386pep -Map=bar.map | FileCheck -check-prefix=MAP %s | ||
| 146 | RUN: ld.lld -### foo.o -m i386pep --Map=bar.map | FileCheck -check-prefix=MAP %s | ||
| 147 | MAP: -lldmap:bar.map |
deps/lld/test/darwin/cmdline-lto_library.objtxt created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | # RUN: ld64.lld -arch x86_64 -lto_library %t -print-atoms -r %s 2>&1 | FileCheck %s | ||
| 2 | # | ||
| 3 | # Test that the -lto_library option does not result in an error. | ||
| 4 | # | ||
| 5 | |||
| 6 | # CHECK-NOT: -lto_library | ||
| 7 | |||
| 8 | --- !native | ||
| 9 | defined-atoms: | ||
| 10 | - name: _foo | ||
| 11 | ... | ||
deps/lld/test/darwin/cmdline-objc_gc.objtxt+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -objc_gc %s 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -objc_gc %s 2>&1 | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test that the -objc_gc is rejected. | 3 | # Test that the -objc_gc is rejected. |
| 4 | # | 4 | # |
deps/lld/test/darwin/cmdline-objc_gc_compaction.objtxt+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -objc_gc_compaction %s 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -objc_gc_compaction %s 2>&1 | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test that the -objc_gc_compaction is rejected. | 3 | # Test that the -objc_gc_compaction is rejected. |
| 4 | # | 4 | # |
deps/lld/test/darwin/cmdline-objc_gc_only.objtxt+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -objc_gc_only %s 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -objc_gc_only %s 2>&1 | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test that the -objc_gc_only is rejected. | 3 | # Test that the -objc_gc_only is rejected. |
| 4 | # | 4 | # |
deps/lld/test/darwin/native-and-mach-o.objtxt+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \ | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s \ |
| 2 | # RUN: %p/Inputs/native-and-mach-o.objtxt \ | 2 | # RUN: %p/Inputs/native-and-mach-o.objtxt \ |
| 3 | # RUN: %p/Inputs/native-and-mach-o2.objtxt -o %t && \ | 3 | # RUN: %p/Inputs/native-and-mach-o2.objtxt -o %t && \ |
| 4 | # RUN: llvm-nm %t | FileCheck %s | 4 | # RUN: llvm-nm %t | FileCheck %s |
deps/lld/test/lit.cfg.py+9-3| ... | @@ -39,8 +39,9 @@ llvm_config.use_default_substitutions() | ... | @@ -39,8 +39,9 @@ llvm_config.use_default_substitutions() |
| 39 | llvm_config.use_lld() | 39 | llvm_config.use_lld() |
| 40 | 40 | ||
| 41 | tool_patterns = [ | 41 | tool_patterns = [ |
| 42 | 'llc', 'llvm-as', 'llvm-mc', 'llvm-nm', | 42 | 'llc', 'llvm-as', 'llvm-mc', 'llvm-nm', 'llvm-objdump', 'llvm-pdbutil', |
| 43 | 'llvm-objdump', 'llvm-pdbutil', 'llvm-readobj', 'obj2yaml', 'yaml2obj'] | 43 | 'llvm-dwarfdump', 'llvm-readelf', 'llvm-readobj', 'obj2yaml', 'yaml2obj', |
| 44 | 'opt', 'llvm-dis'] | ||
| 44 | 45 | ||
| 45 | llvm_config.add_tool_substitutions(tool_patterns) | 46 | llvm_config.add_tool_substitutions(tool_patterns) |
| 46 | 47 | ||
| ... | @@ -64,6 +65,7 @@ llvm_config.feature_config( | ... | @@ -64,6 +65,7 @@ llvm_config.feature_config( |
| 64 | 'AMDGPU': 'amdgpu', | 65 | 'AMDGPU': 'amdgpu', |
| 65 | 'ARM': 'arm', | 66 | 'ARM': 'arm', |
| 66 | 'AVR': 'avr', | 67 | 'AVR': 'avr', |
| 68 | 'Hexagon': 'hexagon', | ||
| 67 | 'Mips': 'mips', | 69 | 'Mips': 'mips', |
| 68 | 'PowerPC': 'ppc', | 70 | 'PowerPC': 'ppc', |
| 69 | 'Sparc': 'sparc', | 71 | 'Sparc': 'sparc', |
| ... | @@ -71,8 +73,9 @@ llvm_config.feature_config( | ... | @@ -71,8 +73,9 @@ llvm_config.feature_config( |
| 71 | 'X86': 'x86'}) | 73 | 'X86': 'x86'}) |
| 72 | ]) | 74 | ]) |
| 73 | 75 | ||
| 74 | # Set a fake constant version so that we get consitent output. | 76 | # Set a fake constant version so that we get consistent output. |
| 75 | config.environment['LLD_VERSION'] = 'LLD 1.0' | 77 | config.environment['LLD_VERSION'] = 'LLD 1.0' |
| 78 | config.environment['LLD_IN_TEST'] = '1' | ||
| 76 | 79 | ||
| 77 | # Indirectly check if the mt.exe Microsoft utility exists by searching for | 80 | # Indirectly check if the mt.exe Microsoft utility exists by searching for |
| 78 | # cvtres, which always accompanies it. Alternatively, check if we can use | 81 | # cvtres, which always accompanies it. Alternatively, check if we can use |
| ... | @@ -84,6 +87,9 @@ if (lit.util.which('cvtres', config.environment['PATH'])) or \ | ... | @@ -84,6 +87,9 @@ if (lit.util.which('cvtres', config.environment['PATH'])) or \ |
| 84 | if (config.llvm_libxml2_enabled == '1'): | 87 | if (config.llvm_libxml2_enabled == '1'): |
| 85 | config.available_features.add('libxml2') | 88 | config.available_features.add('libxml2') |
| 86 | 89 | ||
| 90 | if config.have_dia_sdk: | ||
| 91 | config.available_features.add("diasdk") | ||
| 92 | |||
| 87 | tar_executable = lit.util.which('tar', config.environment['PATH']) | 93 | tar_executable = lit.util.which('tar', config.environment['PATH']) |
| 88 | if tar_executable: | 94 | if tar_executable: |
| 89 | tar_version = subprocess.Popen( | 95 | tar_version = subprocess.Popen( |
deps/lld/test/lit.site.cfg.py.in+3| ... | @@ -1,5 +1,8 @@ | ... | @@ -1,5 +1,8 @@ |
| 1 | @LIT_SITE_CFG_IN_HEADER@ | 1 | @LIT_SITE_CFG_IN_HEADER@ |
| 2 | 2 | ||
| 3 | import lit.util | ||
| 4 | |||
| 5 | config.have_dia_sdk = lit.util.pythonize_bool("@LLVM_ENABLE_DIA_SDK@") | ||
| 3 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" | 6 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" |
| 4 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" | 7 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" |
| 5 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" | 8 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" |
deps/lld/test/mach-o/Inputs/swift-version-1.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r %s %p/Inputs/hello-world-x86_64.yaml 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -r %s %p/Inputs/hello-world-x86_64.yaml 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !mach-o | 3 | --- !mach-o |
| 4 | arch: x86_64 | 4 | arch: x86_64 |
deps/lld/test/mach-o/Inputs/wrong-arch-error.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r %s 2> %t.err | 1 | # RUN: not ld64.lld -arch x86_64 -r %s 2> %t.err |
| 2 | # RUN: FileCheck %s < %t.err | 2 | # RUN: FileCheck %s < %t.err |
| 3 | 3 | ||
| 4 | --- !mach-o | 4 | --- !mach-o |
deps/lld/test/mach-o/PIE.yaml+3-3| ... | @@ -1,12 +1,12 @@ | ... | @@ -1,12 +1,12 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \ | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s \ |
| 2 | # RUN: %p/Inputs/PIE.yaml -o %t && \ | 2 | # RUN: %p/Inputs/PIE.yaml -o %t && \ |
| 3 | # RUN: llvm-objdump -macho -private-headers %t | FileCheck %s | 3 | # RUN: llvm-objdump -macho -private-headers %t | FileCheck %s |
| 4 | # | 4 | # |
| 5 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \ | 5 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s \ |
| 6 | # RUN: %p/Inputs/PIE.yaml -pie -o %t\ | 6 | # RUN: %p/Inputs/PIE.yaml -pie -o %t\ |
| 7 | # RUN: && llvm-objdump -macho -private-headers %t | FileCheck %s | 7 | # RUN: && llvm-objdump -macho -private-headers %t | FileCheck %s |
| 8 | # | 8 | # |
| 9 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \ | 9 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s \ |
| 10 | # RUN: %p/Inputs/PIE.yaml -no_pie -o %t\ | 10 | # RUN: %p/Inputs/PIE.yaml -no_pie -o %t\ |
| 11 | # RUN: && llvm-objdump -macho -private-headers %t \ | 11 | # RUN: && llvm-objdump -macho -private-headers %t \ |
| 12 | # RUN: | FileCheck --check-prefix=CHECK_NO_PIE %s | 12 | # RUN: | FileCheck --check-prefix=CHECK_NO_PIE %s |
deps/lld/test/mach-o/align_text.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -r %t -o %t2 -print_atoms | FileCheck %s | 2 | # RUN: ld64.lld -arch x86_64 -r %t -o %t2 -print_atoms | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that alignment info round trips through -r | 4 | # Test that alignment info round trips through -r |
| 5 | # | 5 | # |
deps/lld/test/mach-o/arm-interworking-movw.yaml+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: arm | 1 | # REQUIRES: arm |
| 2 | # RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s -o %t | FileCheck %s | 2 | # RUN: ld64.lld -arch armv7 -r -print_atoms %s -o %t | FileCheck %s |
| 3 | # RUN: lld -flavor darwin -arch armv7 -dylib -print_atoms %t -o %t2 \ | 3 | # RUN: ld64.lld -arch armv7 -dylib -print_atoms %t -o %t2 \ |
| 4 | # RUN: %p/Inputs/armv7/libSystem.yaml -sectalign __TEXT __text 0x1000 | FileCheck %s | 4 | # RUN: %p/Inputs/armv7/libSystem.yaml -sectalign __TEXT __text 0x1000 | FileCheck %s |
| 5 | # RUN: llvm-objdump -d -macho -no-symbolic-operands %t2 | FileCheck -check-prefix=CODE %s | 5 | # RUN: llvm-objdump -d -macho -no-symbolic-operands %t2 | FileCheck -check-prefix=CODE %s |
| 6 | # | 6 | # |
deps/lld/test/mach-o/arm-interworking.yaml+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s \ | 1 | # RUN: ld64.lld -arch armv7 -r -print_atoms %s \ |
| 2 | # RUN: %p/Inputs/arm-interworking.yaml -o %t | FileCheck %s \ | 2 | # RUN: %p/Inputs/arm-interworking.yaml -o %t | FileCheck %s \ |
| 3 | # RUN: && lld -flavor darwin -arch armv7 -dylib -print_atoms \ | 3 | # RUN: && ld64.lld -arch armv7 -dylib -print_atoms \ |
| 4 | # RUN: %p/Inputs/armv7/libSystem.yaml %t -o %t2 | FileCheck %s \ | 4 | # 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 -sd %t2 | FileCheck -check-prefix=CODE %s |
| 6 | # | 6 | # |
deps/lld/test/mach-o/arm-shims.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch armv7 %s %p/Inputs/arm-shims.yaml \ | 1 | # RUN: ld64.lld -arch armv7 %s %p/Inputs/arm-shims.yaml \ |
| 2 | # RUN: -dylib %p/Inputs/armv7/libSystem.yaml -o %t | 2 | # RUN: -dylib %p/Inputs/armv7/libSystem.yaml -o %t |
| 3 | # RUN: llvm-readobj -s -sd %t | FileCheck %s | 3 | # RUN: llvm-readobj -s -sd %t | FileCheck %s |
| 4 | # | 4 | # |
deps/lld/test/mach-o/arm-subsections-via-symbols.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch armv7 %s -r -print_atoms -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch armv7 %s -r -print_atoms -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test that assembly written without .subsections_via_symbols is parsed so | 3 | # Test that assembly written without .subsections_via_symbols is parsed so |
| 4 | # that atoms are non-dead-strip and there is a layout-after references | 4 | # that atoms are non-dead-strip and there is a layout-after references |
deps/lld/test/mach-o/arm64-reloc-negDelta32-fixup.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 -r %s -o %t | 1 | # RUN: ld64.lld -arch arm64 -r %s -o %t |
| 2 | # RUN: lld -flavor darwin -arch arm64 -r %t -o %t2 | 2 | # RUN: ld64.lld -arch arm64 -r %t -o %t2 |
| 3 | # RUN: llvm-objdump -s -section="__eh_frame" %t | FileCheck %s | 3 | # RUN: llvm-objdump -s -section="__eh_frame" %t | FileCheck %s |
| 4 | # RUN: llvm-objdump -s -section="__eh_frame" %t2 | FileCheck %s | 4 | # RUN: llvm-objdump -s -section="__eh_frame" %t2 | FileCheck %s |
| 5 | 5 |
deps/lld/test/mach-o/arm64-relocs-errors-delta64-offset.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch arm64 %s -r \ | 1 | # RUN: not ld64.lld -arch arm64 %s -r \ |
| 2 | # RUN: 2> %t.err | 2 | # RUN: 2> %t.err |
| 3 | # RUN: FileCheck %s < %t.err | 3 | # RUN: FileCheck %s < %t.err |
| 4 | 4 |
deps/lld/test/mach-o/arm64-section-order.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | 1 | # RUN: ld64.lld -arch arm64 -r -print_atoms %s -o %t |
| 2 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | 2 | # RUN: ld64.lld -arch arm64 -r -print_atoms %t -o %t2 |
| 3 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | 3 | # RUN: llvm-objdump -section-headers %t | FileCheck %s |
| 4 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s | 4 | # RUN: llvm-objdump -section-headers %t2 | FileCheck %s |
| 5 | 5 |
deps/lld/test/mach-o/bind-opcodes.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t | 1 | # RUN: ld64.lld -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t |
| 2 | # RUN: obj2yaml %t | FileCheck %s | 2 | # RUN: obj2yaml %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | 4 |
deps/lld/test/mach-o/cstring-sections.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test -keep_private_externs in -r mode. | 3 | # Test -keep_private_externs in -r mode. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/data-in-code-load-command.yaml+8-8| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s | 2 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO | 3 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO |
| 4 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -data_in_code_info -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO | 4 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -data_in_code_info -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO |
| 5 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO | 5 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO |
| 6 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r && llvm-objdump -private-headers %t | FileCheck %s | 6 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r && llvm-objdump -private-headers %t | FileCheck %s |
| 7 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r -data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s | 7 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r -data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s |
| 8 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO | 8 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO |
| 9 | 9 | ||
| 10 | --- !mach-o | 10 | --- !mach-o |
| 11 | arch: x86_64 | 11 | arch: x86_64 |
deps/lld/test/mach-o/data-only-dylib.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -dylib %s -o %t %p/Inputs/x86_64/libSystem.yaml | 1 | # RUN: ld64.lld -arch x86_64 -dylib %s -o %t %p/Inputs/x86_64/libSystem.yaml |
| 2 | # RUN: llvm-nm %t | FileCheck %s | 2 | # RUN: llvm-nm %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that a data-only dylib can be built. | 4 | # Test that a data-only dylib can be built. |
deps/lld/test/mach-o/dead-strip-globals.yaml+4-4| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -dead_strip -export_dynamic %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t.dylib -print_atoms | FileCheck -check-prefix=CHECK1 %s | 1 | # RUN: ld64.lld -arch x86_64 -dead_strip -export_dynamic %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t.dylib -print_atoms | FileCheck -check-prefix=CHECK1 %s |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -export_dynamic -dead_strip %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t.dylib -print_atoms | FileCheck -check-prefix=CHECK1 %s | 2 | # RUN: ld64.lld -arch x86_64 -export_dynamic -dead_strip %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t.dylib -print_atoms | FileCheck -check-prefix=CHECK1 %s |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -dead_strip %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t2.dylib -print_atoms | FileCheck -check-prefix=CHECK2 %s | 3 | # RUN: ld64.lld -arch x86_64 -dead_strip %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t2.dylib -print_atoms | FileCheck -check-prefix=CHECK2 %s |
| 4 | 4 | ||
| 5 | # RUN: lld -flavor darwin -arch x86_64 -r %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t3.o | 5 | # RUN: ld64.lld -arch x86_64 -r %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t3.o |
| 6 | # RUN: llvm-nm -m %t3.o | FileCheck -check-prefix=RELOCATABLE_SYMBOLS %s | 6 | # RUN: llvm-nm -m %t3.o | FileCheck -check-prefix=RELOCATABLE_SYMBOLS %s |
| 7 | 7 | ||
| 8 | # | 8 | # |
deps/lld/test/mach-o/debug-syms.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -o %t %s -dylib %p/Inputs/x86_64/libSystem.yaml && \ | 1 | # RUN: ld64.lld -arch x86_64 -o %t %s -dylib %p/Inputs/x86_64/libSystem.yaml && \ |
| 2 | # RUN: llvm-nm -no-sort -debug-syms %t | FileCheck %s | 2 | # RUN: llvm-nm -no-sort -debug-syms %t | FileCheck %s |
| 3 | 3 | ||
| 4 | # CHECK: 0000000000000000 - 00 0000 SO /Users/lhames/Projects/lld/lld-svn-tot/scratch/ | 4 | # CHECK: 0000000000000000 - 00 0000 SO /Users/lhames/Projects/lld/lld-svn-tot/scratch/ |
deps/lld/test/mach-o/demangle.yaml+2-2| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | # REQUIRES: system-linker-mach-o | 1 | # REQUIRES: system-linker-mach-o |
| 2 | # | 2 | # |
| 3 | # RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \ | 3 | # RUN: not ld64.lld -arch x86_64 -macosx_version_min 10.8 %s \ |
| 4 | # RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml 2> %t.err | 4 | # RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml 2> %t.err |
| 5 | # RUN: FileCheck %s < %t.err | 5 | # RUN: FileCheck %s < %t.err |
| 6 | # | 6 | # |
| 7 | # RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \ | 7 | # RUN: not ld64.lld -arch x86_64 -macosx_version_min 10.8 %s \ |
| 8 | # RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml -demangle 2> %t.err2 | 8 | # RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml -demangle 2> %t.err2 |
| 9 | # RUN: FileCheck %s --check-prefix=DCHECK < %t.err2 | 9 | # RUN: FileCheck %s --check-prefix=DCHECK < %t.err2 |
| 10 | # | 10 | # |
deps/lld/test/mach-o/dependency_info.yaml+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # Test -dependency_info option | 1 | # Test -dependency_info option |
| 2 | # | 2 | # |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -test_file_usage \ | 3 | # RUN: ld64.lld -arch x86_64 -test_file_usage \ |
| 4 | # RUN: -dependency_info %t.info \ | 4 | # RUN: -dependency_info %t.info \ |
| 5 | # RUN: -path_exists /System/Library/Frameworks \ | 5 | # RUN: -path_exists /System/Library/Frameworks \ |
| 6 | # RUN: -path_exists /System/Library/Frameworks/Foo.framework/Foo \ | 6 | # RUN: -path_exists /System/Library/Frameworks/Foo.framework/Foo \ |
| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | # RUN: -F/Custom/Frameworks \ | 9 | # RUN: -F/Custom/Frameworks \ |
| 10 | # RUN: -framework Bar \ | 10 | # RUN: -framework Bar \ |
| 11 | # RUN: -framework Foo | 11 | # RUN: -framework Foo |
| 12 | # RUN: %python %p/Inputs/DependencyDump.py %t.info | FileCheck %s | 12 | # RUN: '%python' %p/Inputs/DependencyDump.py %t.info | FileCheck %s |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | # CHECK: linker-vers: lld | 15 | # CHECK: linker-vers: lld |
deps/lld/test/mach-o/do-not-emit-unwind-fde-arm64.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch arm64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: ld64.lld -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t | FileCheck -check-prefix=CODE %s | 3 | # RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t | FileCheck -check-prefix=CODE %s |
| 4 | # RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t2 | FileCheck -check-prefix=CODE %s | 4 | # RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t2 | FileCheck -check-prefix=CODE %s |
| 5 | 5 |
deps/lld/test/mach-o/dso_handle.yaml+4-4| ... | @@ -1,13 +1,13 @@ | ... | @@ -1,13 +1,13 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -o %t1 | 1 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -o %t1 |
| 2 | # RUN: llvm-nm -m -n %t1 | FileCheck %s | 2 | # RUN: llvm-nm -m -n %t1 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -dead_strip -o %t2 | 4 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -dead_strip -o %t2 |
| 5 | # RUN: llvm-nm -m -n %t2 | FileCheck %s | 5 | # RUN: llvm-nm -m -n %t2 | FileCheck %s |
| 6 | # | 6 | # |
| 7 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -dylib -o %t3 | 7 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -dylib -o %t3 |
| 8 | # RUN: llvm-nm -m -n %t3 | FileCheck %s | 8 | # RUN: llvm-nm -m -n %t3 | FileCheck %s |
| 9 | # | 9 | # |
| 10 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -bundle -o %t4 | 10 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -bundle -o %t4 |
| 11 | # RUN: llvm-nm -m -n %t4 | FileCheck %s | 11 | # RUN: llvm-nm -m -n %t4 | FileCheck %s |
| 12 | # | 12 | # |
| 13 | # Test that ___dso_handle symbol is available for executables, bundles, and dylibs | 13 | # Test that ___dso_handle symbol is available for executables, bundles, and dylibs |
deps/lld/test/mach-o/dylib-install-names.yaml+4-4| ... | @@ -1,23 +1,23 @@ | ... | @@ -1,23 +1,23 @@ |
| 1 | # Check we accept -install_name correctly: | 1 | # Check we accept -install_name correctly: |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -install_name libwibble.dylib -dylib \ | 2 | # RUN: ld64.lld -arch x86_64 -install_name libwibble.dylib -dylib \ |
| 3 | # RUN: -compatibility_version 2.0 -current_version 5.3 \ | 3 | # RUN: -compatibility_version 2.0 -current_version 5.3 \ |
| 4 | # RUN: %p/Inputs/x86_64/libSystem.yaml %s -o %t.dylib | 4 | # RUN: %p/Inputs/x86_64/libSystem.yaml %s -o %t.dylib |
| 5 | # RUN: llvm-objdump -private-headers %t.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE | 5 | # RUN: llvm-objdump -private-headers %t.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE |
| 6 | 6 | ||
| 7 | # Check we read LC_ID_DYLIB correctly: | 7 | # Check we read LC_ID_DYLIB correctly: |
| 8 | # RUN: lld -flavor darwin -arch x86_64 %p/Inputs/use-dylib-install-names.yaml \ | 8 | # RUN: ld64.lld -arch x86_64 %p/Inputs/use-dylib-install-names.yaml \ |
| 9 | # RUN: %p/Inputs/x86_64/libSystem.yaml %t.dylib -dylib -o %t2.dylib | 9 | # RUN: %p/Inputs/x86_64/libSystem.yaml %t.dylib -dylib -o %t2.dylib |
| 10 | # RUN: llvm-objdump -private-headers %t2.dylib | FileCheck %s --check-prefix=CHECK-BINARY-READ | 10 | # RUN: llvm-objdump -private-headers %t2.dylib | FileCheck %s --check-prefix=CHECK-BINARY-READ |
| 11 | 11 | ||
| 12 | # Check we default the install-name to the output file: | 12 | # Check we default the install-name to the output file: |
| 13 | # RUN: lld -flavor darwin -arch x86_64 -dylib %s -o libwibble.dylib \ | 13 | # RUN: ld64.lld -arch x86_64 -dylib %s -o libwibble.dylib \ |
| 14 | # RUN: -compatibility_version 2.0 -current_version 5.3 \ | 14 | # RUN: -compatibility_version 2.0 -current_version 5.3 \ |
| 15 | # RUN: %p/Inputs/x86_64/libSystem.yaml | 15 | # RUN: %p/Inputs/x86_64/libSystem.yaml |
| 16 | # RUN: llvm-objdump -private-headers libwibble.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE | 16 | # RUN: llvm-objdump -private-headers libwibble.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE |
| 17 | # RUN: rm -f libwibble.dylib | 17 | # RUN: rm -f libwibble.dylib |
| 18 | 18 | ||
| 19 | # Check -single_module does nothing | 19 | # Check -single_module does nothing |
| 20 | # RUN: lld -flavor darwin -arch x86_64 -dylib %s -install_name libwibble.dylib \ | 20 | # RUN: ld64.lld -arch x86_64 -dylib %s -install_name libwibble.dylib \ |
| 21 | # RUN: -compatibility_version 2.0 -current_version 5.3 \ | 21 | # RUN: -compatibility_version 2.0 -current_version 5.3 \ |
| 22 | # RUN: -single_module -o %t2.dylib %p/Inputs/x86_64/libSystem.yaml | 22 | # RUN: -single_module -o %t2.dylib %p/Inputs/x86_64/libSystem.yaml |
| 23 | # RUN: llvm-objdump -private-headers %t2.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE | 23 | # RUN: llvm-objdump -private-headers %t2.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE |
deps/lld/test/mach-o/eh-frame-relocs-arm64.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch arm64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: ld64.lld -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t | FileCheck -check-prefix=CODE %s | 3 | # RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t | FileCheck -check-prefix=CODE %s |
| 4 | # RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t2 | FileCheck -check-prefix=CODE %s | 4 | # RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t2 | FileCheck -check-prefix=CODE %s |
| 5 | 5 |
deps/lld/test/mach-o/error-simulator-vs-macosx.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -macosx_version_min 10.8 %s %p/Inputs/hello-world-x86.yaml -o %t && llvm-nm -m %t | FileCheck %s | 1 | # RUN: ld64.lld -arch i386 -macosx_version_min 10.8 %s %p/Inputs/hello-world-x86.yaml -o %t && llvm-nm -m %t | FileCheck %s |
| 2 | # RUN: not lld -flavor darwin -arch i386 -ios_simulator_version_min 5.0 %s %p/Inputs/hello-world-x86.yaml -o %t 2>&1 | FileCheck %s --check-prefix=ERROR | 2 | # RUN: not ld64.lld -arch i386 -ios_simulator_version_min 5.0 %s %p/Inputs/hello-world-x86.yaml -o %t 2>&1 | FileCheck %s --check-prefix=ERROR |
| 3 | # | 3 | # |
| 4 | # Test that i386 can link with a macos version but gives an error with a simululator version. | 4 | # Test that i386 can link with a macos version but gives an error with a simululator version. |
| 5 | # | 5 | # |
deps/lld/test/mach-o/exe-offsets.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s -o %t -e start %p/Inputs/x86_64/libSystem.yaml | 1 | # 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 |
| 3 | 3 | ||
| 4 | # Make sure data gets put at offset | 4 | # Make sure data gets put at offset |
deps/lld/test/mach-o/exe-segment-overlap.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s -o %t %p/Inputs/x86_64/libSystem.yaml | 1 | # 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 |
| 3 | 3 | ||
| 4 | --- !native | 4 | --- !native |
deps/lld/test/mach-o/executable-exports.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 \ | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 \ |
| 2 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t && \ | 2 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t && \ |
| 3 | # RUN: llvm-objdump -exports-trie %t | FileCheck %s | 3 | # RUN: llvm-objdump -exports-trie %t | FileCheck %s |
| 4 | # | 4 | # |
deps/lld/test/mach-o/export-trie-order.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t | 1 | # 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 -exports-trie %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that the export trie is emitted in order. | 4 | # Test that the export trie is emitted in order. |
deps/lld/test/mach-o/exported_symbols_list-dylib.yaml+4-4| ... | @@ -1,19 +1,19 @@ | ... | @@ -1,19 +1,19 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \ | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 -dylib \ |
| 2 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t \ | 2 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t \ |
| 3 | # RUN: -exported_symbols_list %p/Inputs/exported_symbols_list.exp && \ | 3 | # RUN: -exported_symbols_list %p/Inputs/exported_symbols_list.exp && \ |
| 4 | # RUN: llvm-nm -m %t | FileCheck %s | 4 | # RUN: llvm-nm -m %t | FileCheck %s |
| 5 | # | 5 | # |
| 6 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \ | 6 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 -dylib \ |
| 7 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t2 \ | 7 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t2 \ |
| 8 | # RUN: -exported_symbol _foo -exported_symbol _b && \ | 8 | # RUN: -exported_symbol _foo -exported_symbol _b && \ |
| 9 | # RUN: llvm-nm -m %t2 | FileCheck %s | 9 | # RUN: llvm-nm -m %t2 | FileCheck %s |
| 10 | # | 10 | # |
| 11 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \ | 11 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 -dylib \ |
| 12 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t3 \ | 12 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t3 \ |
| 13 | # RUN: -unexported_symbol _bar -unexported_symbol _a && \ | 13 | # RUN: -unexported_symbol _bar -unexported_symbol _a && \ |
| 14 | # RUN: llvm-nm -m %t3 | FileCheck %s | 14 | # RUN: llvm-nm -m %t3 | FileCheck %s |
| 15 | # | 15 | # |
| 16 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \ | 16 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 -dylib \ |
| 17 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -dead_strip -o %t \ | 17 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -dead_strip -o %t \ |
| 18 | # RUN: -exported_symbols_list %p/Inputs/exported_symbols_list.exp && \ | 18 | # RUN: -exported_symbols_list %p/Inputs/exported_symbols_list.exp && \ |
| 19 | # RUN: llvm-nm -m %t | FileCheck -check-prefix=CHECK_DEAD %s | 19 | # RUN: llvm-nm -m %t | FileCheck -check-prefix=CHECK_DEAD %s |
deps/lld/test/mach-o/exported_symbols_list-obj.yaml+3-3| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -exported_symbol _bar \ | 1 | # RUN: ld64.lld -arch x86_64 -r %s -o %t -exported_symbol _bar \ |
| 2 | # RUN: && llvm-nm -m %t | FileCheck %s | 2 | # RUN: && llvm-nm -m %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # RUN: lld -flavor darwin -arch x86_64 -r %s -o %t2 -keep_private_externs \ | 4 | # RUN: ld64.lld -arch x86_64 -r %s -o %t2 -keep_private_externs \ |
| 5 | # RUN: -exported_symbol _bar && \ | 5 | # RUN: -exported_symbol _bar && \ |
| 6 | # RUN: llvm-nm -m %t2 | FileCheck -check-prefix=CHECK_KPE %s | 6 | # RUN: llvm-nm -m %t2 | FileCheck -check-prefix=CHECK_KPE %s |
| 7 | # | 7 | # |
| 8 | # RUN: not lld -flavor darwin -arch x86_64 -r %s -o %t3 \ | 8 | # RUN: not ld64.lld -arch x86_64 -r %s -o %t3 \ |
| 9 | # RUN: -exported_symbol _foo 2> %t4 | 9 | # RUN: -exported_symbol _foo 2> %t4 |
| 10 | 10 | ||
| 11 | # Test -exported_symbols_list properly changes visibility in -r mode. | 11 | # Test -exported_symbols_list properly changes visibility in -r mode. |
deps/lld/test/mach-o/exported_symbols_list-undef.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \ | 1 | # RUN: not ld64.lld -arch x86_64 -macosx_version_min 10.8 -dylib \ |
| 2 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t -exported_symbol _foobar 2> %t2 | 2 | # RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t -exported_symbol _foobar 2> %t2 |
| 3 | # | 3 | # |
| 4 | # Test -exported_symbol fails if exported symbol not found. | 4 | # Test -exported_symbol fails if exported symbol not found. |
deps/lld/test/mach-o/fat-archive.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t \ | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t \ |
| 2 | # RUN: -L %p/Inputs -lfoo %p/Inputs/x86_64/libSystem.yaml | 2 | # RUN: -L %p/Inputs -lfoo %p/Inputs/x86_64/libSystem.yaml |
| 3 | # RUN: llvm-nm -m -n %t | FileCheck %s | 3 | # RUN: llvm-nm -m -n %t | FileCheck %s |
| 4 | # | 4 | # |
deps/lld/test/mach-o/filelist.yaml+2-2| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | # RUN: lld -flavor darwin -test_file_usage \ | 1 | # RUN: ld64.lld -test_file_usage \ |
| 2 | # RUN: -filelist %p/Inputs/full.filelist \ | 2 | # RUN: -filelist %p/Inputs/full.filelist \ |
| 3 | # RUN: -path_exists /foo/bar/a.o \ | 3 | # RUN: -path_exists /foo/bar/a.o \ |
| 4 | # RUN: -path_exists /foo/bar/b.o \ | 4 | # RUN: -path_exists /foo/bar/b.o \ |
| 5 | # RUN: -path_exists /foo/x.a \ | 5 | # RUN: -path_exists /foo/x.a \ |
| 6 | # RUN: 2>&1 | FileCheck %s | 6 | # RUN: 2>&1 | FileCheck %s |
| 7 | # | 7 | # |
| 8 | # RUN: lld -flavor darwin -test_file_usage -t \ | 8 | # RUN: ld64.lld -test_file_usage -t \ |
| 9 | # RUN: -filelist %p/Inputs/partial.filelist,/foo \ | 9 | # RUN: -filelist %p/Inputs/partial.filelist,/foo \ |
| 10 | # RUN: -path_exists /foo/bar/a.o \ | 10 | # RUN: -path_exists /foo/bar/a.o \ |
| 11 | # RUN: -path_exists /foo/bar/b.o \ | 11 | # RUN: -path_exists /foo/bar/b.o \ |
deps/lld/test/mach-o/flat_namespace_undef_error.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -flat_namespace -undefined error %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -macosx_version_min 10.9 -flat_namespace -undefined error %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !native | 3 | --- !native |
| 4 | defined-atoms: | 4 | defined-atoms: |
deps/lld/test/mach-o/flat_namespace_undef_suppress.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -flat_namespace -undefined suppress %s -o %t %p/Inputs/x86_64/libSystem.yaml | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.9 -flat_namespace -undefined suppress %s -o %t %p/Inputs/x86_64/libSystem.yaml |
| 2 | # | 2 | # |
| 3 | # Sanity check '-flat_namespace -undefined suppress'. | 3 | # Sanity check '-flat_namespace -undefined suppress'. |
| 4 | # This should pass without error, even though '_bar' is undefined. | 4 | # This should pass without error, even though '_bar' is undefined. |
deps/lld/test/mach-o/force_load-dylib.yaml+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -dylib %p/Inputs/bar.yaml \ | 1 | # RUN: ld64.lld -arch x86_64 -dylib %p/Inputs/bar.yaml \ |
| 2 | # RUN: -install_name /usr/lib/libbar.dylib %p/Inputs/x86_64/libSystem.yaml -o %t1.dylib | 2 | # RUN: -install_name /usr/lib/libbar.dylib %p/Inputs/x86_64/libSystem.yaml -o %t1.dylib |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -dylib %s -all_load %t1.dylib \ | 3 | # RUN: ld64.lld -arch x86_64 -dylib %s -all_load %t1.dylib \ |
| 4 | # RUN: -install_name /usr/lib/libfoo.dylib %p/Inputs/x86_64/libSystem.yaml -o %t | 4 | # RUN: -install_name /usr/lib/libfoo.dylib %p/Inputs/x86_64/libSystem.yaml -o %t |
| 5 | # RUN: llvm-nm -m %t | FileCheck %s | 5 | # RUN: llvm-nm -m %t | FileCheck %s |
| 6 | # | 6 | # |
deps/lld/test/mach-o/force_load-x86_64.yaml+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \ | 1 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \ |
| 2 | # RUN: %p/Inputs/libfoo.a %p/Inputs/libbar.a -o %t1 | 2 | # RUN: %p/Inputs/libfoo.a %p/Inputs/libbar.a -o %t1 |
| 3 | # RUN: llvm-nm -m -n %t1 | FileCheck %s | 3 | # RUN: llvm-nm -m -n %t1 | FileCheck %s |
| 4 | # | 4 | # |
| 5 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \ | 5 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \ |
| 6 | # RUN: -force_load %p/Inputs/libfoo.a %p/Inputs/libbar.a -o %t2 | 6 | # RUN: -force_load %p/Inputs/libfoo.a %p/Inputs/libbar.a -o %t2 |
| 7 | # RUN: llvm-nm -m -n %t2 | FileCheck --check-prefix=CHECKF %s | 7 | # RUN: llvm-nm -m -n %t2 | FileCheck --check-prefix=CHECKF %s |
| 8 | # | 8 | # |
deps/lld/test/mach-o/framework-user-paths.yaml+1-1| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | # /opt/Frameworks should not be found in SDK | 5 | # /opt/Frameworks should not be found in SDK |
| 6 | # /System/Library/Frameworks is implicit and should be in SDK | 6 | # /System/Library/Frameworks is implicit and should be in SDK |
| 7 | # | 7 | # |
| 8 | # RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \ | 8 | # RUN: ld64.lld -arch x86_64 -r -test_file_usage -v \ |
| 9 | # RUN: -path_exists myFrameworks \ | 9 | # RUN: -path_exists myFrameworks \ |
| 10 | # RUN: -path_exists myFrameworks/my.framework/my \ | 10 | # RUN: -path_exists myFrameworks/my.framework/my \ |
| 11 | # RUN: -path_exists /opt/Frameworks \ | 11 | # RUN: -path_exists /opt/Frameworks \ |
deps/lld/test/mach-o/function-starts-load-command.yaml+5-5| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -function_starts && llvm-objdump -private-headers %t | FileCheck %s | 2 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -function_starts && llvm-objdump -private-headers %t | FileCheck %s |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_function_starts && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS | 3 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_function_starts && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS |
| 4 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -function_starts -no_function_starts && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS | 4 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -function_starts -no_function_starts && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS |
| 5 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS | 5 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS |
| 6 | 6 | ||
| 7 | --- !mach-o | 7 | --- !mach-o |
| 8 | arch: x86_64 | 8 | arch: x86_64 |
deps/lld/test/mach-o/gcc_except_tab-got-arm64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 %s \ | 1 | # RUN: ld64.lld -arch arm64 %s \ |
| 2 | # RUN: -dylib %p/Inputs/arm64/libSystem.yaml -o %t | 2 | # RUN: -dylib %p/Inputs/arm64/libSystem.yaml -o %t |
| 3 | # RUN: llvm-objdump -section-headers %t | FileCheck %s | 3 | # RUN: llvm-objdump -section-headers %t | FileCheck %s |
| 4 | 4 |
deps/lld/test/mach-o/got-order.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/got-order.yaml \ | 1 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/got-order.yaml \ |
| 2 | # RUN: %p/Inputs/got-order2.yaml -o %t %p/Inputs/x86_64/libSystem.yaml | 2 | # 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 -bind %t | FileCheck %s |
| 4 | # | 4 | # |
deps/lld/test/mach-o/hello-world-arm64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t | 1 | # RUN: ld64.lld -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t |
| 2 | # RUN: llvm-nm -m -n %t | FileCheck %s | 2 | # RUN: llvm-nm -m -n %t | FileCheck %s |
| 3 | # RUN: llvm-objdump -private-headers %t | FileCheck %s --check-prefix=CHECK-PRIVATE-HEADER | 3 | # RUN: llvm-objdump -private-headers %t | FileCheck %s --check-prefix=CHECK-PRIVATE-HEADER |
| 4 | # | 4 | # |
deps/lld/test/mach-o/hello-world-armv6.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch armv6 %s %p/Inputs/hello-world-armv6.yaml -o %t | 1 | # RUN: ld64.lld -arch armv6 %s %p/Inputs/hello-world-armv6.yaml -o %t |
| 2 | # RUN: llvm-nm -m %t | FileCheck %s | 2 | # RUN: llvm-nm -m %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that armv6 (arm) hello-world can be linked into a mach-o executable | 4 | # Test that armv6 (arm) hello-world can be linked into a mach-o executable |
deps/lld/test/mach-o/hello-world-armv7.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch armv7 %s %p/Inputs/hello-world-armv7.yaml -o %t | 1 | # RUN: ld64.lld -arch armv7 %s %p/Inputs/hello-world-armv7.yaml -o %t |
| 2 | # RUN: llvm-nm -m -n %t | FileCheck %s | 2 | # RUN: llvm-nm -m -n %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that armv7 (thumb) hello-world can be linked into a mach-o executable | 4 | # Test that armv7 (thumb) hello-world can be linked into a mach-o executable |
deps/lld/test/mach-o/hello-world-x86.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t | 1 | # RUN: ld64.lld -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t |
| 2 | # RUN: llvm-nm -m %t | FileCheck %s | 2 | # RUN: llvm-nm -m %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that i386 hello-world can be linked into a mach-o executable | 4 | # Test that i386 hello-world can be linked into a mach-o executable |
deps/lld/test/mach-o/hello-world-x86_64.yaml+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml \ | 1 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml \ |
| 2 | # RUN: -o %t | 2 | # RUN: -o %t |
| 3 | # RUN: llvm-nm -m -n %t | FileCheck %s | 3 | # RUN: llvm-nm -m -n %t | FileCheck %s |
| 4 | # | 4 | # |
| 5 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml \ | 5 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml \ |
| 6 | # RUN: -dead_strip -o %t2 | 6 | # RUN: -dead_strip -o %t2 |
| 7 | # RUN: llvm-nm -m -n %t2 | FileCheck %s | 7 | # RUN: llvm-nm -m -n %t2 | FileCheck %s |
| 8 | # | 8 | # |
deps/lld/test/mach-o/image-base.yaml+4-4| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 %s -o %t -image_base 31415926000 %p/Inputs/x86_64/libSystem.yaml | 1 | # 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 |
| 3 | # RUN: not lld -flavor darwin -arch x86_64 -image_base 0x31415926530 %s >/dev/null 2> %t | 3 | # RUN: not ld64.lld -arch x86_64 -image_base 0x31415926530 %s >/dev/null 2> %t |
| 4 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-MISPAGED | 4 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-MISPAGED |
| 5 | # RUN: not lld -flavor darwin -arch x86_64 -image_base 1000 %s >/dev/null 2> %t | 5 | # RUN: not ld64.lld -arch x86_64 -image_base 1000 %s >/dev/null 2> %t |
| 6 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-OVERLAP | 6 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-OVERLAP |
| 7 | # RUN: not lld -flavor darwin -arch x86_64 -image_base hithere %s >/dev/null 2> %t | 7 | # RUN: not ld64.lld -arch x86_64 -image_base hithere %s >/dev/null 2> %t |
| 8 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-NOTHEX | 8 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-NOTHEX |
| 9 | 9 | ||
| 10 | --- !native | 10 | --- !native |
deps/lld/test/mach-o/infer-arch.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -macosx_version_min 10.8 %s -r -o %t \ | 1 | # RUN: ld64.lld -arch i386 -macosx_version_min 10.8 %s -r -o %t \ |
| 2 | # RUN: && lld -flavor darwin -r %t -o %t2 -print_atoms | FileCheck %s | 2 | # RUN: && ld64.lld -r %t -o %t2 -print_atoms | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test linker can detect architecture without -arch option. | 4 | # Test linker can detect architecture without -arch option. |
| 5 | # | 5 | # |
deps/lld/test/mach-o/interposing-section.yaml+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/interposing-section.yaml \ | 1 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/interposing-section.yaml \ |
| 2 | # RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml | 2 | # RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml |
| 3 | # RUN: llvm-objdump -private-headers %t | FileCheck %s | 3 | # RUN: llvm-objdump -private-headers %t | FileCheck %s |
| 4 | # | 4 | # |
| 5 | # RUN: lld -flavor darwin -arch x86_64 %s -r -o %t1 | 5 | # RUN: ld64.lld -arch x86_64 %s -r -o %t1 |
| 6 | # RUN: llvm-objdump -private-headers %t1 | FileCheck %s | 6 | # RUN: llvm-objdump -private-headers %t1 | FileCheck %s |
| 7 | # | 7 | # |
| 8 | # Test that interposing section is preserved by linker. | 8 | # Test that interposing section is preserved by linker. |
deps/lld/test/mach-o/keep_private_externs.yaml+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r %s -o %t \ | 1 | # RUN: ld64.lld -arch x86_64 -r %s -o %t \ |
| 2 | # RUN: && llvm-nm -m %t | FileCheck %s | 2 | # RUN: && llvm-nm -m %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # RUN: lld -flavor darwin -arch x86_64 -r %s -o %t2 -keep_private_externs \ | 4 | # RUN: ld64.lld -arch x86_64 -r %s -o %t2 -keep_private_externs \ |
| 5 | # RUN: && llvm-nm -m %t2 | FileCheck -check-prefix=CHECK_KPE %s | 5 | # RUN: && llvm-nm -m %t2 | FileCheck -check-prefix=CHECK_KPE %s |
| 6 | # | 6 | # |
| 7 | # Test -keep_private_externs in -r mode. | 7 | # Test -keep_private_externs in -r mode. |
deps/lld/test/mach-o/lazy-bind-x86_64.yaml+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # REQUIRES: x86 | 1 | # REQUIRES: x86 |
| 2 | 2 | ||
| 3 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \ | 3 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s \ |
| 4 | # RUN: %p/Inputs/lazy-bind-x86_64.yaml %p/Inputs/lazy-bind-x86_64-2.yaml \ | 4 | # RUN: %p/Inputs/lazy-bind-x86_64.yaml %p/Inputs/lazy-bind-x86_64-2.yaml \ |
| 5 | # RUN: %p/Inputs/lazy-bind-x86_64-3.yaml -o %t \ | 5 | # RUN: %p/Inputs/lazy-bind-x86_64-3.yaml -o %t \ |
| 6 | # RUN: %p/Inputs/x86_64/libSystem.yaml | 6 | # RUN: %p/Inputs/x86_64/libSystem.yaml |
deps/lld/test/mach-o/lc_segment_filesize.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -o %t %s && llvm-objdump -private-headers %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -o %t %s && llvm-objdump -private-headers %t | FileCheck %s |
| 2 | 2 | ||
| 3 | # CHECK: filesize 19 | 3 | # CHECK: filesize 19 |
| 4 | 4 |
deps/lld/test/mach-o/lib-search-paths.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s -syslibroot %p/Inputs/lib-search-paths -lmyshared -lmystatic -lfile.o -r -print_atoms 2>&1 | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 %s -syslibroot %p/Inputs/lib-search-paths -lmyshared -lmystatic -lfile.o -r -print_atoms 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !native | 3 | --- !native |
| 4 | undefined-atoms: | 4 | undefined-atoms: |
deps/lld/test/mach-o/library-order.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %p/Inputs/libfoo.a %s -o %t \ | 1 | # RUN: ld64.lld -arch x86_64 %p/Inputs/libfoo.a %s -o %t \ |
| 2 | # RUN: %p/Inputs/x86_64/libSystem.yaml | 2 | # RUN: %p/Inputs/x86_64/libSystem.yaml |
| 3 | # RUN: llvm-nm -m -n %t | FileCheck %s | 3 | # RUN: llvm-nm -m -n %t | FileCheck %s |
| 4 | # | 4 | # |
deps/lld/test/mach-o/library-rescan.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %p/Inputs/libfoo.a %p/Inputs/libbar.a \ | 1 | # RUN: ld64.lld -arch x86_64 %p/Inputs/libfoo.a %p/Inputs/libbar.a \ |
| 2 | # RUN: %s -o %t %p/Inputs/x86_64/libSystem.yaml | 2 | # RUN: %s -o %t %p/Inputs/x86_64/libSystem.yaml |
| 3 | # RUN: llvm-nm -m -n %t | FileCheck %s | 3 | # RUN: llvm-nm -m -n %t | FileCheck %s |
| 4 | # | 4 | # |
deps/lld/test/mach-o/libresolve-bizarre-root-override.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -test_file_usage -v \ | 1 | # RUN: not ld64.lld -test_file_usage -v \ |
| 2 | # RUN: -path_exists /usr/lib \ | 2 | # RUN: -path_exists /usr/lib \ |
| 3 | # RUN: -path_exists /Applications/MySDK/usr/local/lib \ | 3 | # RUN: -path_exists /Applications/MySDK/usr/local/lib \ |
| 4 | # RUN: -path_exists /Applications/MySDK/usr/lib \ | 4 | # RUN: -path_exists /Applications/MySDK/usr/lib \ |
deps/lld/test/mach-o/libresolve-multiple-syslibroots.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -test_file_usage -v \ | 1 | # RUN: ld64.lld -test_file_usage -v \ |
| 2 | # RUN: -path_exists /usr/lib \ | 2 | # RUN: -path_exists /usr/lib \ |
| 3 | # RUN: -path_exists /Applications/MyFirstSDK/usr/local/lib \ | 3 | # RUN: -path_exists /Applications/MyFirstSDK/usr/local/lib \ |
| 4 | # RUN: -path_exists /Applications/MySecondSDK/usr/local/lib \ | 4 | # RUN: -path_exists /Applications/MySecondSDK/usr/local/lib \ |
deps/lld/test/mach-o/libresolve-one-syslibroot.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -test_file_usage -v \ | 1 | # RUN: ld64.lld -test_file_usage -v \ |
| 2 | # RUN: -path_exists /usr/lib \ | 2 | # RUN: -path_exists /usr/lib \ |
| 3 | # RUN: -path_exists /Applications/MySDK/usr/local/lib \ | 3 | # RUN: -path_exists /Applications/MySDK/usr/local/lib \ |
| 4 | # RUN: -path_exists /Applications/MySDK/usr/local/lib/libSystem.a \ | 4 | # RUN: -path_exists /Applications/MySDK/usr/local/lib/libSystem.a \ |
deps/lld/test/mach-o/libresolve-simple.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \ | 1 | # RUN: ld64.lld -arch x86_64 -r -test_file_usage -v \ |
| 2 | # RUN: -path_exists /usr/lib \ | 2 | # RUN: -path_exists /usr/lib \ |
| 3 | # RUN: -path_exists /usr/local/lib \ | 3 | # RUN: -path_exists /usr/local/lib \ |
| 4 | # RUN: -path_exists /usr/lib/libSystem.dylib \ | 4 | # RUN: -path_exists /usr/lib/libSystem.dylib \ |
deps/lld/test/mach-o/libresolve-user-paths.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \ | 1 | # RUN: ld64.lld -arch x86_64 -r -test_file_usage -v \ |
| 2 | # RUN: -path_exists hasFoo \ | 2 | # RUN: -path_exists hasFoo \ |
| 3 | # RUN: -path_exists hasFoo/libFoo.dylib \ | 3 | # RUN: -path_exists hasFoo/libFoo.dylib \ |
| 4 | # RUN: -path_exists /hasBar \ | 4 | # RUN: -path_exists /hasBar \ |
deps/lld/test/mach-o/libresolve-z.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \ | 1 | # RUN: ld64.lld -arch x86_64 -r -test_file_usage -v \ |
| 2 | # RUN: -path_exists /usr/lib \ | 2 | # RUN: -path_exists /usr/lib \ |
| 3 | # RUN: -path_exists /usr/local/lib \ | 3 | # RUN: -path_exists /usr/local/lib \ |
| 4 | # RUN: -path_exists /usr/lib/libSystem.dylib \ | 4 | # RUN: -path_exists /usr/lib/libSystem.dylib \ |
deps/lld/test/mach-o/mach_header-cpusubtype.yaml+3-3| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.4 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_LIB64 | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.4 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_LIB64 |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.5 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=LIB64 | 2 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.5 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=LIB64 |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -dylib -macosx_version_min 10.5 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=DYLIB | 3 | # RUN: ld64.lld -arch x86_64 -dylib -macosx_version_min 10.5 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=DYLIB |
| 4 | 4 | ||
| 5 | --- !mach-o | 5 | --- !mach-o |
| 6 | arch: x86_64 | 6 | arch: x86_64 |
deps/lld/test/mach-o/mh_bundle_header.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s -bundle -o %t %p/Inputs/x86_64/libSystem.yaml && llvm-nm -m -n %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 %s -bundle -o %t %p/Inputs/x86_64/libSystem.yaml && llvm-nm -m -n %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch x86_64 %s -bundle -dead_strip -o %t %p/Inputs/x86_64/libSystem.yaml && llvm-nm -m -n %t | FileCheck %s | 2 | # RUN: ld64.lld -arch x86_64 %s -bundle -dead_strip -o %t %p/Inputs/x86_64/libSystem.yaml && llvm-nm -m -n %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that __mh_bundle_header symbol is available for bundles | 4 | # Test that __mh_bundle_header symbol is available for bundles |
| 5 | # | 5 | # |
deps/lld/test/mach-o/mh_dylib_header.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s -dylib -o %t %p/Inputs/x86_64/libSystem.yaml | 1 | # RUN: ld64.lld -arch x86_64 %s -dylib -o %t %p/Inputs/x86_64/libSystem.yaml |
| 2 | # RUN: llvm-nm -m -n %t | FileCheck %s | 2 | # RUN: llvm-nm -m -n %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that __mh_dylib_header symbol is available for dylibs | 4 | # Test that __mh_dylib_header symbol is available for dylibs |
deps/lld/test/mach-o/objc-category-list-atom.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | 3 | ||
| 4 | 4 | ||
| 5 | --- !mach-o | 5 | --- !mach-o |
deps/lld/test/mach-o/objc-image-info-host-vs-simulator.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r %s 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -r %s 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | # The file is built for the host, but the objc image info flags are for | 3 | # The file is built for the host, but the objc image info flags are for |
| 4 | # the simulator. | 4 | # the simulator. |
deps/lld/test/mach-o/objc-image-info-invalid-size.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r %s 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -r %s 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !mach-o | 3 | --- !mach-o |
| 4 | arch: x86_64 | 4 | arch: x86_64 |
deps/lld/test/mach-o/objc-image-info-invalid-version.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r %s 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -r %s 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !mach-o | 3 | --- !mach-o |
| 4 | arch: x86_64 | 4 | arch: x86_64 |
deps/lld/test/mach-o/objc-image-info-mismatched-swift-version.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r %s %p/Inputs/swift-version-1.yaml 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -r %s %p/Inputs/swift-version-1.yaml 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !mach-o | 3 | --- !mach-o |
| 4 | arch: x86_64 | 4 | arch: x86_64 |
deps/lld/test/mach-o/objc-image-info-pass-output.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -ios_simulator_version_min 5.0 -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s | 1 | # RUN: ld64.lld -ios_simulator_version_min 5.0 -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s |
| 2 | 2 | ||
| 3 | # Make sure that we have an objc image info in the output. It should have | 3 | # Make sure that we have an objc image info in the output. It should have |
| 4 | # been generated by the objc pass. | 4 | # been generated by the objc pass. |
deps/lld/test/mach-o/objc-image-info-simulator-vs-host.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -ios_simulator_version_min 5.0 -arch x86_64 -r %s 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -ios_simulator_version_min 5.0 -arch x86_64 -r %s 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | # The file is built for the simulator, but the objc image info flags are for | 3 | # The file is built for the simulator, but the objc image info flags are for |
| 4 | # the host. | 4 | # the host. |
deps/lld/test/mach-o/objc-image-info-unsupported-gc.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r %s 2>&1 | FileCheck %s | 1 | # RUN: not ld64.lld -arch x86_64 -r %s 2>&1 | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !mach-o | 3 | --- !mach-o |
| 4 | arch: x86_64 | 4 | arch: x86_64 |
deps/lld/test/mach-o/objc_export_list.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -dylib %s -o %t \ | 1 | # RUN: ld64.lld -arch x86_64 -dylib %s -o %t \ |
| 2 | # RUN: -exported_symbol .objc_class_name_Foo %p/Inputs/x86_64/libSystem.yaml | 2 | # RUN: -exported_symbol .objc_class_name_Foo %p/Inputs/x86_64/libSystem.yaml |
| 3 | # RUN: llvm-nm -m %t | FileCheck %s | 3 | # RUN: llvm-nm -m %t | FileCheck %s |
| 4 | # | 4 | # |
deps/lld/test/mach-o/order_file-basic.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \ | 1 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \ |
| 2 | # RUN: -order_file %p/Inputs/order_file-basic.order \ | 2 | # RUN: -order_file %p/Inputs/order_file-basic.order \ |
| 3 | # RUN: -force_load %p/Inputs/libfoo.a -o %t | 3 | # RUN: -force_load %p/Inputs/libfoo.a -o %t |
| 4 | # RUN: llvm-nm -m -n %t | FileCheck %s | 4 | # RUN: llvm-nm -m -n %t | FileCheck %s |
deps/lld/test/mach-o/parse-aliases.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test multiple labels to same address parse into aliases. | 3 | # Test multiple labels to same address parse into aliases. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-arm-relocs.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch armv7 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch armv7 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: ld64.lld -arch armv7 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test parsing of armv7 relocations. | 4 | # Test parsing of armv7 relocations. |
| 5 | # | 5 | # |
deps/lld/test/mach-o/parse-cfstring32.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch i386 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of mach-o functions. | 3 | # Test parsing of mach-o functions. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-cfstring64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of CFString constants. | 3 | # Test parsing of CFString constants. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-compact-unwind32.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch i386 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of __LD/__compact_unwind (compact unwind) section. | 3 | # Test parsing of __LD/__compact_unwind (compact unwind) section. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-compact-unwind64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of __LD/__compact_unwind (compact unwind) section. | 3 | # Test parsing of __LD/__compact_unwind (compact unwind) section. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-data-in-code-armv7.yaml+3-3| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch armv7 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch armv7 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: ld64.lld -arch armv7 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # RUN: lld -flavor darwin -arch armv7 -dylib %s -o %t3.dylib %p/Inputs/armv7/libSystem.yaml \ | 3 | # RUN: ld64.lld -arch armv7 -dylib %s -o %t3.dylib %p/Inputs/armv7/libSystem.yaml \ |
| 4 | # RUN: && llvm-objdump -macho -private-headers %t3.dylib | FileCheck --check-prefix=CHECK2 %s | 4 | # RUN: && llvm-objdump -macho -private-headers %t3.dylib | FileCheck --check-prefix=CHECK2 %s |
| 5 | # | 5 | # |
| 6 | # Test parsing LC_DATA_IN_CODE | 6 | # Test parsing LC_DATA_IN_CODE |
deps/lld/test/mach-o/parse-data-in-code-x86.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s \ | 1 | # RUN: ld64.lld -arch i386 -r -print_atoms %s -o %t | FileCheck %s \ |
| 2 | # RUN: && lld -flavor darwin -arch i386 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: && ld64.lld -arch i386 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test parsing LC_DATA_IN_CODE | 4 | # Test parsing LC_DATA_IN_CODE |
| 5 | # | 5 | # |
deps/lld/test/mach-o/parse-data-relocs-arm64.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch arm64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: ld64.lld -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test parsing and writing of arm64 data relocations. | 4 | # Test parsing and writing of arm64 data relocations. |
| 5 | # | 5 | # |
deps/lld/test/mach-o/parse-data-relocs-x86_64.yaml+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | ||
| 2 | # RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s \ | 2 | # RUN: ld64.lld -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s \ |
| 3 | # RUN: && lld -flavor darwin -arch x86_64 %t -r -print_atoms -o %t2 | FileCheck %s | 3 | # RUN: && ld64.lld -arch x86_64 %t -r -print_atoms -o %t2 | FileCheck %s |
| 4 | # | 4 | # |
| 5 | # Test parsing and writing of x86_64 data relocations. | 5 | # Test parsing and writing of x86_64 data relocations. |
| 6 | # | 6 | # |
deps/lld/test/mach-o/parse-data.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of mach-o data symbols. | 3 | # Test parsing of mach-o data symbols. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-eh-frame-relocs-x86_64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of x86_64 __eh_frame (dwarf unwind) relocations. | 3 | # Test parsing of x86_64 __eh_frame (dwarf unwind) relocations. |
| 4 | 4 |
deps/lld/test/mach-o/parse-eh-frame-x86-anon.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch i386 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of new __eh_frame (dwarf unwind) section that has no .eh labels | 3 | # Test parsing of new __eh_frame (dwarf unwind) section that has no .eh labels |
| 4 | # and no relocations. | 4 | # and no relocations. |
deps/lld/test/mach-o/parse-eh-frame-x86-labeled.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch i386 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of old __eh_frame (dwarf unwind) section that has .eh labels | 3 | # Test parsing of old __eh_frame (dwarf unwind) section that has .eh labels |
| 4 | # and relocations. | 4 | # and relocations. |
deps/lld/test/mach-o/parse-eh-frame.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of __eh_frame (dwarf unwind) section. | 3 | # Test parsing of __eh_frame (dwarf unwind) section. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-function.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r %s -o %t | 1 | # RUN: ld64.lld -arch x86_64 -r %s -o %t |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -r %t -print_atoms -o %t2 | FileCheck %s | 2 | # RUN: ld64.lld -arch x86_64 -r %t -print_atoms -o %t2 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test parsing of mach-o functions. | 4 | # Test parsing of mach-o functions. |
| 5 | # | 5 | # |
deps/lld/test/mach-o/parse-initializers32.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch i386 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of literal sections. | 3 | # Test parsing of literal sections. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-initializers64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of literal sections. | 3 | # Test parsing of literal sections. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-literals-error.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t 2> %t.err | 1 | # RUN: not ld64.lld -arch x86_64 -r -print_atoms %s -o %t 2> %t.err |
| 2 | # RUN: FileCheck %s < %t.err | 2 | # RUN: FileCheck %s < %t.err |
| 3 | # | 3 | # |
| 4 | # Test for error if literal section is not correct size mulitple. | 4 | # Test for error if literal section is not correct size mulitple. |
deps/lld/test/mach-o/parse-literals.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of literal sections. | 3 | # Test parsing of literal sections. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-non-lazy-pointers.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch i386 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of non-lazy-pointer sections. | 3 | # Test parsing of non-lazy-pointer sections. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-relocs-x86.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s \ | 1 | # RUN: ld64.lld -arch i386 -r -print_atoms %s -o %t | FileCheck %s \ |
| 2 | # RUN: && lld -flavor darwin -arch i386 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: && ld64.lld -arch i386 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test parsing and writing of x86 relocations. | 4 | # Test parsing and writing of x86 relocations. |
| 5 | # | 5 | # |
deps/lld/test/mach-o/parse-section-no-symbol.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r %s -print_atoms -o %t2 | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r %s -print_atoms -o %t2 | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of mach-o functions with no symbols at all. | 3 | # Test parsing of mach-o functions with no symbols at all. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-tentative-defs.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test parsing of tentative definitions, including size, scope, and alignment. | 3 | # Test parsing of tentative definitions, including size, scope, and alignment. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/parse-text-relocs-arm64.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s \ | 1 | # RUN: ld64.lld -arch arm64 -r -print_atoms %s -o %t | FileCheck %s \ |
| 2 | # RUN: && lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: && ld64.lld -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test parsing and writing of arm64 text relocations. | 4 | # Test parsing and writing of arm64 text relocations. |
| 5 | # | 5 | # |
deps/lld/test/mach-o/parse-text-relocs-x86_64.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s \ | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s \ |
| 2 | # RUN: && lld -flavor darwin -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: && ld64.lld -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test parsing and writing of x86_64 text relocations. | 4 | # Test parsing and writing of x86_64 text relocations. |
| 5 | # | 5 | # |
deps/lld/test/mach-o/parse-tlv-relocs-x86-64.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s \ | 1 | # RUN: ld64.lld -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s \ |
| 2 | # RUN: && lld -flavor darwin -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s | 2 | # RUN: && ld64.lld -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test parsing of x86_64 tlv relocations. | 4 | # Test parsing of x86_64 tlv relocations. |
| 5 | 5 |
deps/lld/test/mach-o/re-exported-dylib-ordinal.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \ | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s \ |
| 2 | # RUN: %p/Inputs/re-exported-dylib-ordinal.yaml \ | 2 | # RUN: %p/Inputs/re-exported-dylib-ordinal.yaml \ |
| 3 | # RUN: %p/Inputs/re-exported-dylib-ordinal2.yaml \ | 3 | # RUN: %p/Inputs/re-exported-dylib-ordinal2.yaml \ |
| 4 | # RUN: %p/Inputs/re-exported-dylib-ordinal3.yaml -dylib -o %t \ | 4 | # RUN: %p/Inputs/re-exported-dylib-ordinal3.yaml -dylib -o %t \ |
deps/lld/test/mach-o/rpath.yaml+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # Check we handle -rpath correctly: | 1 | # Check we handle -rpath correctly: |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -rpath @loader_path/../Frameworks \ | 2 | # RUN: ld64.lld -arch x86_64 -rpath @loader_path/../Frameworks \ |
| 3 | # RUN: %p/Inputs/x86_64/libSystem.yaml %s -o %t | 3 | # RUN: %p/Inputs/x86_64/libSystem.yaml %s -o %t |
| 4 | # RUN: llvm-objdump -private-headers %t | FileCheck %s --check-prefix=CHECK-BINARY-WRITE | 4 | # RUN: llvm-objdump -private-headers %t | FileCheck %s --check-prefix=CHECK-BINARY-WRITE |
| 5 | 5 |
deps/lld/test/mach-o/run-tlv-pass-x86-64.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: lld -flavor darwin -macosx_version_min 10.7 -arch x86_64 -print_atoms %s -o %t | FileCheck %s | 1 | # RUN: ld64.lld -macosx_version_min 10.7 -arch x86_64 -print_atoms %s -o %t | FileCheck %s |
| 2 | # RUN: not lld -flavor darwin -macosx_version_min 10.6 -arch x86_64 -o %t %s 2> %t2 | 2 | # RUN: not ld64.lld -macosx_version_min 10.6 -arch x86_64 -o %t %s 2> %t2 |
| 3 | # RUN: FileCheck < %t2 %s --check-prefix=CHECK-ERROR | 3 | # RUN: FileCheck < %t2 %s --check-prefix=CHECK-ERROR |
| 4 | # RUN: llvm-objdump -macho -private-headers %t | FileCheck %s --check-prefix=CHECK-LOADCMDS | 4 | # RUN: llvm-objdump -macho -private-headers %t | FileCheck %s --check-prefix=CHECK-LOADCMDS |
| 5 | # | 5 | # |
deps/lld/test/mach-o/sdk-version-error.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -sdk_version 10.blah %s -o %t 2>&1 | FileCheck %s --check-prefix=ERROR | 1 | # RUN: not ld64.lld -arch x86_64 -sdk_version 10.blah %s -o %t 2>&1 | FileCheck %s --check-prefix=ERROR |
| 2 | 2 | ||
| 3 | --- !mach-o | 3 | --- !mach-o |
| 4 | arch: x86_64 | 4 | arch: x86_64 |
deps/lld/test/mach-o/sectalign.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -dylib \ | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -dylib \ |
| 2 | # RUN: -sectalign __DATA __custom 0x800 -sectalign __TEXT __text 0x400 \ | 2 | # RUN: -sectalign __DATA __custom 0x800 -sectalign __TEXT __text 0x400 \ |
| 3 | # RUN: %p/Inputs/x86_64/libSystem.yaml -o %t \ | 3 | # 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 |
deps/lld/test/mach-o/sectattrs.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -dylib \ | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -dylib \ |
| 2 | # RUN: %p/Inputs/x86_64/libSystem.yaml -o %t \ | 2 | # RUN: %p/Inputs/x86_64/libSystem.yaml -o %t \ |
| 3 | # RUN: && llvm-objdump -private-headers %t | FileCheck %s | 3 | # RUN: && llvm-objdump -private-headers %t | FileCheck %s |
| 4 | # | 4 | # |
deps/lld/test/mach-o/sectcreate.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -r -arch x86_64 -o %t -sectcreate __DATA __data \ | 1 | # RUN: ld64.lld -r -arch x86_64 -o %t -sectcreate __DATA __data \ |
| 2 | # RUN: %p/Inputs/hw.raw_bytes -print_atoms | FileCheck %s | 2 | # RUN: %p/Inputs/hw.raw_bytes -print_atoms | FileCheck %s |
| 3 | 3 | ||
| 4 | # CHECK: --- !native | 4 | # CHECK: --- !native |
deps/lld/test/mach-o/seg-protection-arm64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s | 1 | # RUN: ld64.lld -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !mach-o | 3 | --- !mach-o |
| 4 | arch: arm64 | 4 | arch: arm64 |
deps/lld/test/mach-o/seg-protection-x86_64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s |
| 2 | 2 | ||
| 3 | --- !mach-o | 3 | --- !mach-o |
| 4 | arch: x86_64 | 4 | arch: x86_64 |
deps/lld/test/mach-o/source-version.yaml+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -source_version 10.blah %s -o %t 2>&1 | FileCheck %s --check-prefix=ERROR | 1 | # RUN: not ld64.lld -arch x86_64 -source_version 10.blah %s -o %t 2>&1 | FileCheck %s --check-prefix=ERROR |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -source_version 10.1.2.3.4 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s | 2 | # RUN: ld64.lld -arch x86_64 -source_version 10.1.2.3.4 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s |
| 3 | 3 | ||
| 4 | --- !mach-o | 4 | --- !mach-o |
| 5 | arch: x86_64 | 5 | arch: x86_64 |
deps/lld/test/mach-o/stack-size.yaml+4-4| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 %s -o %t %p/Inputs/x86_64/libSystem.yaml | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.9 %s -o %t %p/Inputs/x86_64/libSystem.yaml |
| 2 | # RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-DEFAULT %s | 2 | # RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-DEFAULT %s |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 %s -o %t -stack_size 31415926000 %p/Inputs/x86_64/libSystem.yaml | 3 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.9 %s -o %t -stack_size 31415926000 %p/Inputs/x86_64/libSystem.yaml |
| 4 | # RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-EXPLICIT %s | 4 | # RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-EXPLICIT %s |
| 5 | # RUN: not lld -flavor darwin -arch x86_64 -stack_size 0x31415926530 %s >/dev/null 2> %t | 5 | # RUN: not ld64.lld -arch x86_64 -stack_size 0x31415926530 %s >/dev/null 2> %t |
| 6 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-MISPAGED | 6 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-MISPAGED |
| 7 | # RUN: not lld -flavor darwin -arch x86_64 -stack_size hithere %s >/dev/null 2> %t | 7 | # RUN: not ld64.lld -arch x86_64 -stack_size hithere %s >/dev/null 2> %t |
| 8 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-NOTHEX | 8 | # RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-NOTHEX |
| 9 | 9 | ||
| 10 | --- !native | 10 | --- !native |
deps/lld/test/mach-o/string-table.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t | 1 | # RUN: ld64.lld -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t |
| 2 | # RUN: obj2yaml %t | FileCheck %s | 2 | # RUN: obj2yaml %t | FileCheck %s |
| 3 | # | 3 | # |
| 4 | # Test that the string table contains a ' ' as its first symbol | 4 | # Test that the string table contains a ' ' as its first symbol |
deps/lld/test/mach-o/subsections-via-symbols-default.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -ios_simulator_version_min 5.0 -arch x86_64 -r %s -o %t | 1 | # 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 |
| 3 | 3 | ||
| 4 | # Make sure that we have an objc image info in the output. It should have | 4 | # Make sure that we have an objc image info in the output. It should have |
deps/lld/test/mach-o/twolevel_namespace_undef_dynamic_lookup.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined dynamic_lookup %s -o %t %p/Inputs/x86_64/libSystem.yaml | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined dynamic_lookup %s -o %t %p/Inputs/x86_64/libSystem.yaml |
| 2 | # | 2 | # |
| 3 | # Sanity check '-twolevel_namespace -undefined dynamic_lookup'. | 3 | # Sanity check '-twolevel_namespace -undefined dynamic_lookup'. |
| 4 | # This should pass without error, even though '_bar' is undefined. | 4 | # This should pass without error, even though '_bar' is undefined. |
deps/lld/test/mach-o/twolevel_namespace_undef_warning_suppress.yaml+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined warning %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | \ | 1 | # RUN: not ld64.lld -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined warning %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | \ |
| 2 | # RUN: FileCheck --check-prefix=CHECK-WARNING %s | 2 | # RUN: FileCheck --check-prefix=CHECK-WARNING %s |
| 3 | # RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined suppress %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | \ | 3 | # RUN: not ld64.lld -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined suppress %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | \ |
| 4 | # RUN: FileCheck --check-prefix=CHECK-SUPPRESS %s | 4 | # RUN: FileCheck --check-prefix=CHECK-SUPPRESS %s |
| 5 | 5 | ||
| 6 | --- !native | 6 | --- !native |
deps/lld/test/mach-o/unwind-info-simple-arm64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch arm64 -o %t %s \ | 1 | # RUN: ld64.lld -arch arm64 -o %t %s \ |
| 2 | # RUN: %p/Inputs/unwind-info-simple-arm64.yaml -e _main %p/Inputs/arm64/libSystem.yaml | 2 | # RUN: %p/Inputs/unwind-info-simple-arm64.yaml -e _main %p/Inputs/arm64/libSystem.yaml |
| 3 | # RUN: llvm-objdump -unwind-info %t | FileCheck %s | 3 | # RUN: llvm-objdump -unwind-info %t | FileCheck %s |
| 4 | 4 |
deps/lld/test/mach-o/unwind-info-simple-x86_64.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s -o %t -e _main %p/Inputs/x86_64/libSystem.yaml | 1 | # RUN: ld64.lld -arch x86_64 %s -o %t -e _main %p/Inputs/x86_64/libSystem.yaml |
| 2 | # RUN: llvm-objdump -unwind-info %t | FileCheck %s | 2 | # RUN: llvm-objdump -unwind-info %t | FileCheck %s |
| 3 | 3 | ||
| 4 | # CHECK: Contents of __unwind_info section: | 4 | # CHECK: Contents of __unwind_info section: |
deps/lld/test/mach-o/upward-dylib-load-command.yaml+2-2| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -dylib %p/Inputs/bar.yaml \ | 1 | # RUN: ld64.lld -arch x86_64 -dylib %p/Inputs/bar.yaml \ |
| 2 | # RUN: -install_name /usr/lib/libbar.dylib %p/Inputs/x86_64/libSystem.yaml -o %t1.dylib | 2 | # RUN: -install_name /usr/lib/libbar.dylib %p/Inputs/x86_64/libSystem.yaml -o %t1.dylib |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -dylib %s -upward_library %t1.dylib \ | 3 | # RUN: ld64.lld -arch x86_64 -dylib %s -upward_library %t1.dylib \ |
| 4 | # RUN: -install_name /usr/lib/libfoo.dylib %p/Inputs/x86_64/libSystem.yaml -o %t | 4 | # RUN: -install_name /usr/lib/libfoo.dylib %p/Inputs/x86_64/libSystem.yaml -o %t |
| 5 | # RUN: llvm-objdump -private-headers %t | FileCheck %s | 5 | # RUN: llvm-objdump -private-headers %t | FileCheck %s |
| 6 | # | 6 | # |
deps/lld/test/mach-o/upward-dylib-paths.yaml+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # | 1 | # |
| 2 | # | 2 | # |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \ | 3 | # RUN: ld64.lld -arch x86_64 -r -test_file_usage -v \ |
| 4 | # RUN: -path_exists /Custom/Frameworks \ | 4 | # RUN: -path_exists /Custom/Frameworks \ |
| 5 | # RUN: -path_exists /Custom/Frameworks/Bar.framework/Bar \ | 5 | # RUN: -path_exists /Custom/Frameworks/Bar.framework/Bar \ |
| 6 | # RUN: -path_exists /usr/lib \ | 6 | # RUN: -path_exists /usr/lib \ |
deps/lld/test/mach-o/usage.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin | FileCheck %s | 1 | # RUN: not ld64.lld | FileCheck %s |
| 2 | # | 2 | # |
| 3 | # Test that running darwin linker with no option prints out usage message. | 3 | # Test that running darwin linker with no option prints out usage message. |
| 4 | # | 4 | # |
deps/lld/test/mach-o/use-dylib.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s \ | 1 | # RUN: ld64.lld -arch x86_64 %s \ |
| 2 | # RUN: %p/Inputs/use-simple-dylib.yaml %p/Inputs/x86_64/libSystem.yaml -dylib -o %t.dylib | 2 | # RUN: %p/Inputs/use-simple-dylib.yaml %p/Inputs/x86_64/libSystem.yaml -dylib -o %t.dylib |
| 3 | # RUN: llvm-objdump -private-headers %t.dylib | FileCheck %s | 3 | # RUN: llvm-objdump -private-headers %t.dylib | FileCheck %s |
| 4 | 4 |
deps/lld/test/mach-o/use-simple-dylib.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -print_atoms -r %s \ | 1 | # RUN: ld64.lld -arch x86_64 -print_atoms -r %s \ |
| 2 | # RUN: %p/Inputs/use-simple-dylib.yaml -o %t | FileCheck %s | 2 | # RUN: %p/Inputs/use-simple-dylib.yaml -o %t | FileCheck %s |
| 3 | 3 | ||
| 4 | 4 |
deps/lld/test/mach-o/version-min-load-command-object.yaml+3-3| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s -o %t -r -macosx_version_min 10.8 && llvm-objdump -private-headers %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 %s -o %t -r -macosx_version_min 10.8 && llvm-objdump -private-headers %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch x86_64 %s -o %t -r && llvm-objdump -private-headers %t | FileCheck %s | 2 | # RUN: ld64.lld -arch x86_64 %s -o %t -r && llvm-objdump -private-headers %t | FileCheck %s |
| 3 | # RUN: lld -flavor darwin -arch x86_64 %s -o %t -r %p/Inputs/no-version-min-load-command-object.yaml && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN | 3 | # RUN: ld64.lld -arch x86_64 %s -o %t -r %p/Inputs/no-version-min-load-command-object.yaml && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN |
| 4 | 4 | ||
| 5 | # If we are emitting an object file, then we only emit a min version load command if the source object file(s) all have | 5 | # If we are emitting an object file, then we only emit a min version load command if the source object file(s) all have |
| 6 | # version(s) and either known platforms or contain min version load commands themselves. | 6 | # version(s) and either known platforms or contain min version load commands themselves. |
deps/lld/test/mach-o/version-min-load-command.yaml+7-7| ... | @@ -1,11 +1,11 @@ | ... | @@ -1,11 +1,11 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s | 1 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s |
| 2 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml 2>&1 | FileCheck %s --check-prefix=WARNING | 2 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml 2>&1 | FileCheck %s --check-prefix=WARNING |
| 3 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -version_load_command && llvm-objdump -private-headers %t | FileCheck %s | 3 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -version_load_command && llvm-objdump -private-headers %t | FileCheck %s |
| 4 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_version_load_command && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN | 4 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_version_load_command && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN |
| 5 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -version_load_command -no_version_load_command && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN | 5 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -version_load_command -no_version_load_command && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN |
| 6 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN | 6 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN |
| 7 | 7 | ||
| 8 | # RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -sdk_version 10.9 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=SDK_VERSION | 8 | # RUN: ld64.lld -arch x86_64 -macosx_version_min 10.8 -sdk_version 10.9 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=SDK_VERSION |
| 9 | 9 | ||
| 10 | --- !mach-o | 10 | --- !mach-o |
| 11 | arch: x86_64 | 11 | arch: x86_64 |
deps/lld/test/mach-o/write-final-sections.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/write-final-sections.yaml \ | 1 | # RUN: ld64.lld -arch x86_64 %s %p/Inputs/write-final-sections.yaml \ |
| 2 | # RUN: -o %t -e _foo | 2 | # 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 |
| 4 | 4 |
deps/lld/test/mach-o/wrong-arch-error.yaml+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | # RUN: not lld -flavor darwin -arch x86_64 -r %s \ | 1 | # RUN: not ld64.lld -arch x86_64 -r %s \ |
| 2 | # RUN: %p/Inputs/wrong-arch-error.yaml 2> %t.err | 2 | # RUN: %p/Inputs/wrong-arch-error.yaml 2> %t.err |
| 3 | # RUN: FileCheck %s < %t.err | 3 | # RUN: FileCheck %s < %t.err |
| 4 | 4 |
deps/lld/test/wasm/Inputs/archive1.ll+2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | declare i32 @bar() local_unnamed_addr #1 | 3 | declare i32 @bar() local_unnamed_addr #1 |
| 2 | 4 | ||
| 3 | define i32 @foo() local_unnamed_addr #0 { | 5 | define i32 @foo() local_unnamed_addr #0 { |
deps/lld/test/wasm/Inputs/archive2.ll+7| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | declare i32 @foo() local_unnamed_addr #1 | 3 | declare i32 @foo() local_unnamed_addr #1 |
| 2 | 4 | ||
| 3 | define i32 @bar() local_unnamed_addr #0 { | 5 | define i32 @bar() local_unnamed_addr #0 { |
| ... | @@ -5,3 +7,8 @@ entry: | ... | @@ -5,3 +7,8 @@ entry: |
| 5 | %call = tail call i32 @foo() #2 | 7 | %call = tail call i32 @foo() #2 |
| 6 | ret i32 %call | 8 | ret i32 %call |
| 7 | } | 9 | } |
| 10 | |||
| 11 | define void @archive2_symbol() local_unnamed_addr #0 { | ||
| 12 | entry: | ||
| 13 | ret void | ||
| 14 | } |
deps/lld/test/wasm/Inputs/archive3.ll created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | define i32 @bar() local_unnamed_addr #0 { | ||
| 4 | entry: | ||
| 5 | ret i32 1 | ||
| 6 | } | ||
| 7 | |||
| 8 | define void @archive3_symbol() local_unnamed_addr #0 { | ||
| 9 | entry: | ||
| 10 | ret void | ||
| 11 | } | ||
deps/lld/test/wasm/Inputs/call-indirect.ll+8-5| ... | @@ -1,17 +1,20 @@ | ... | @@ -1,17 +1,20 @@ |
| 1 | @indirect_bar = internal local_unnamed_addr global i32 ()* @bar, align 4 | 1 | target triple = "wasm32-unknown-unknown" |
| 2 | |||
| 3 | @indirect_bar = internal local_unnamed_addr global i64 ()* @bar, align 4 | ||
| 2 | @indirect_foo = internal local_unnamed_addr global i32 ()* @foo, align 4 | 4 | @indirect_foo = internal local_unnamed_addr global i32 ()* @foo, align 4 |
| 3 | 5 | ||
| 4 | declare i32 @foo() local_unnamed_addr | 6 | declare i32 @foo() local_unnamed_addr |
| 5 | 7 | ||
| 6 | define i32 @bar() { | 8 | define i64 @bar() { |
| 7 | entry: | 9 | entry: |
| 8 | ret i32 1 | 10 | ret i64 1 |
| 9 | } | 11 | } |
| 10 | 12 | ||
| 11 | define void @call_bar_indirect() local_unnamed_addr #1 { | 13 | define void @call_bar_indirect() local_unnamed_addr #1 { |
| 12 | entry: | 14 | entry: |
| 13 | %0 = load i32 ()*, i32 ()** @indirect_bar, align 4 | 15 | %0 = load i64 ()*, i64 ()** @indirect_bar, align 4 |
| 14 | %1 = load i32 ()*, i32 ()** @indirect_foo, align 4 | 16 | %1 = load i32 ()*, i32 ()** @indirect_foo, align 4 |
| 15 | %call = tail call i32 %0() #2 | 17 | %call0 = tail call i64 %0() #2 |
| 18 | %call1 = tail call i32 %1() #2 | ||
| 16 | ret void | 19 | ret void |
| 17 | } | 20 | } |
deps/lld/test/wasm/Inputs/comdat1.ll created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | $inlineFn = comdat any | ||
| 4 | @constantData = weak_odr constant [3 x i8] c"abc", comdat($inlineFn) | ||
| 5 | define linkonce_odr i32 @inlineFn() comdat { | ||
| 6 | entry: | ||
| 7 | ret i32 ptrtoint ([3 x i8]* @constantData to i32) | ||
| 8 | } | ||
| 9 | |||
| 10 | define i32 @callInline1() { | ||
| 11 | entry: | ||
| 12 | ret i32 ptrtoint (i32 ()* @inlineFn to i32) | ||
| 13 | } | ||
deps/lld/test/wasm/Inputs/comdat2.ll created+13| ... | @@ -0,0 +1,13 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | $inlineFn = comdat any | ||
| 4 | @constantData = weak_odr constant [3 x i8] c"abc", comdat($inlineFn) | ||
| 5 | define linkonce_odr i32 @inlineFn() comdat { | ||
| 6 | entry: | ||
| 7 | ret i32 ptrtoint ([3 x i8]* @constantData to i32) | ||
| 8 | } | ||
| 9 | |||
| 10 | define i32 @callInline2() { | ||
| 11 | entry: | ||
| 12 | ret i32 ptrtoint (i32 ()* @inlineFn to i32) | ||
| 13 | } | ||
deps/lld/test/wasm/Inputs/custom.ll created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | !0 = !{ !"red", !"foo" } | ||
| 4 | !1 = !{ !"green", !"bar" } | ||
| 5 | !2 = !{ !"green", !"qux" } | ||
| 6 | !wasm.custom_sections = !{ !0, !1, !2 } | ||
deps/lld/test/wasm/Inputs/debuginfo1.ll created+68| ... | @@ -0,0 +1,68 @@ | ||
| 1 | ; ModuleID = 'hi.c' | ||
| 2 | source_filename = "hi.c" | ||
| 3 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 4 | target triple = "wasm32-unknown-unknown" | ||
| 5 | |||
| 6 | ; // hi.c: | ||
| 7 | ; extern void foo(int); | ||
| 8 | ; | ||
| 9 | ; int test(int t) { | ||
| 10 | ; return t * t; | ||
| 11 | ; } | ||
| 12 | ; | ||
| 13 | ; int _start() { | ||
| 14 | ; foo(test(10)); | ||
| 15 | ; return 0; | ||
| 16 | ; } | ||
| 17 | |||
| 18 | ; Function Attrs: nounwind readnone | ||
| 19 | define hidden i32 @test(i32 %t) local_unnamed_addr #0 !dbg !7 { | ||
| 20 | entry: | ||
| 21 | call void @llvm.dbg.value(metadata i32 %t, metadata !12, metadata !DIExpression()), !dbg !13 | ||
| 22 | %mul = mul nsw i32 %t, %t, !dbg !14 | ||
| 23 | ret i32 %mul, !dbg !15 | ||
| 24 | } | ||
| 25 | |||
| 26 | ; Function Attrs: nounwind | ||
| 27 | define hidden i32 @_start() local_unnamed_addr #1 !dbg !16 { | ||
| 28 | entry: | ||
| 29 | tail call void @foo(i32 100) #4, !dbg !19 | ||
| 30 | ret i32 0, !dbg !20 | ||
| 31 | } | ||
| 32 | |||
| 33 | declare void @foo(i32) local_unnamed_addr #2 | ||
| 34 | |||
| 35 | ; Function Attrs: nounwind readnone speculatable | ||
| 36 | declare void @llvm.dbg.value(metadata, metadata, metadata) #3 | ||
| 37 | |||
| 38 | attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } | ||
| 39 | attributes #1 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } | ||
| 40 | attributes #2 = { "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"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } | ||
| 41 | attributes #3 = { nounwind readnone speculatable } | ||
| 42 | attributes #4 = { nounwind } | ||
| 43 | |||
| 44 | !llvm.dbg.cu = !{!0} | ||
| 45 | !llvm.module.flags = !{!3, !4, !5} | ||
| 46 | !llvm.ident = !{!6} | ||
| 47 | |||
| 48 | !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0 (trunk 331321)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) | ||
| 49 | !1 = !DIFile(filename: "hi.c", directory: "/Users/yury/llvmwasm") | ||
| 50 | !2 = !{} | ||
| 51 | !3 = !{i32 2, !"Dwarf Version", i32 4} | ||
| 52 | !4 = !{i32 2, !"Debug Info Version", i32 3} | ||
| 53 | !5 = !{i32 1, !"wchar_size", i32 4} | ||
| 54 | !6 = !{!"clang version 7.0.0 (trunk 331321)"} | ||
| 55 | !7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11) | ||
| 56 | !8 = !DISubroutineType(types: !9) | ||
| 57 | !9 = !{!10, !10} | ||
| 58 | !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) | ||
| 59 | !11 = !{!12} | ||
| 60 | !12 = !DILocalVariable(name: "t", arg: 1, scope: !7, file: !1, line: 3, type: !10) | ||
| 61 | !13 = !DILocation(line: 3, column: 14, scope: !7) | ||
| 62 | !14 = !DILocation(line: 4, column: 12, scope: !7) | ||
| 63 | !15 = !DILocation(line: 4, column: 3, scope: !7) | ||
| 64 | !16 = distinct !DISubprogram(name: "_start", scope: !1, file: !1, line: 7, type: !17, isLocal: false, isDefinition: true, scopeLine: 7, isOptimized: true, unit: !0, retainedNodes: !2) | ||
| 65 | !17 = !DISubroutineType(types: !18) | ||
| 66 | !18 = !{!10} | ||
| 67 | !19 = !DILocation(line: 8, column: 3, scope: !16) | ||
| 68 | !20 = !DILocation(line: 9, column: 3, scope: !16) | ||
deps/lld/test/wasm/Inputs/debuginfo2.ll created+70| ... | @@ -0,0 +1,70 @@ | ||
| 1 | ; ModuleID = 'hi_foo.c' | ||
| 2 | source_filename = "hi_foo.c" | ||
| 3 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 4 | target triple = "wasm32-unknown-unknown" | ||
| 5 | |||
| 6 | ; // hi_foo.c: | ||
| 7 | ; int y[2] = {23, 41}; | ||
| 8 | ; | ||
| 9 | ; void foo(int p) { | ||
| 10 | ; y[p & 1]++; | ||
| 11 | ; } | ||
| 12 | ; | ||
| 13 | ; // Will be GCed, but remain visible in debug info | ||
| 14 | ; int z[2] = {1, 2}; | ||
| 15 | |||
| 16 | @y = hidden local_unnamed_addr global [2 x i32] [i32 23, i32 41], align 4, !dbg !0 | ||
| 17 | @z = hidden local_unnamed_addr global [2 x i32] [i32 1, i32 2], align 4, !dbg !6 | ||
| 18 | |||
| 19 | ; Function Attrs: nounwind | ||
| 20 | define hidden void @foo(i32 %p) local_unnamed_addr #0 !dbg !16 { | ||
| 21 | entry: | ||
| 22 | call void @llvm.dbg.value(metadata i32 %p, metadata !20, metadata !DIExpression()), !dbg !21 | ||
| 23 | %and = and i32 %p, 1, !dbg !22 | ||
| 24 | %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* @y, i32 0, i32 %and, !dbg !23 | ||
| 25 | %0 = load i32, i32* %arrayidx, align 4, !dbg !24, !tbaa !25 | ||
| 26 | %inc = add nsw i32 %0, 1, !dbg !24 | ||
| 27 | store i32 %inc, i32* %arrayidx, align 4, !dbg !24, !tbaa !25 | ||
| 28 | ret void, !dbg !29 | ||
| 29 | } | ||
| 30 | |||
| 31 | ; Function Attrs: nounwind readnone speculatable | ||
| 32 | declare void @llvm.dbg.value(metadata, metadata, metadata) #1 | ||
| 33 | |||
| 34 | attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } | ||
| 35 | attributes #1 = { nounwind readnone speculatable } | ||
| 36 | |||
| 37 | !llvm.dbg.cu = !{!2} | ||
| 38 | !llvm.module.flags = !{!12, !13, !14} | ||
| 39 | !llvm.ident = !{!15} | ||
| 40 | |||
| 41 | !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) | ||
| 42 | !1 = distinct !DIGlobalVariable(name: "y", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true) | ||
| 43 | !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 7.0.0 (trunk 332913) (llvm/trunk 332919)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) | ||
| 44 | !3 = !DIFile(filename: "hi_foo.c", directory: "/usr/local/google/home/sbc/dev/wasm/llvm-build") | ||
| 45 | !4 = !{} | ||
| 46 | !5 = !{!0, !6} | ||
| 47 | !6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) | ||
| 48 | !7 = distinct !DIGlobalVariable(name: "z", scope: !2, file: !3, line: 8, type: !8, isLocal: false, isDefinition: true) | ||
| 49 | !8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 64, elements: !10) | ||
| 50 | !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) | ||
| 51 | !10 = !{!11} | ||
| 52 | !11 = !DISubrange(count: 2) | ||
| 53 | !12 = !{i32 2, !"Dwarf Version", i32 4} | ||
| 54 | !13 = !{i32 2, !"Debug Info Version", i32 3} | ||
| 55 | !14 = !{i32 1, !"wchar_size", i32 4} | ||
| 56 | !15 = !{!"clang version 7.0.0 (trunk 332913) (llvm/trunk 332919)"} | ||
| 57 | !16 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 3, type: !17, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !19) | ||
| 58 | !17 = !DISubroutineType(types: !18) | ||
| 59 | !18 = !{null, !9} | ||
| 60 | !19 = !{!20} | ||
| 61 | !20 = !DILocalVariable(name: "p", arg: 1, scope: !16, file: !3, line: 3, type: !9) | ||
| 62 | !21 = !DILocation(line: 3, column: 14, scope: !16) | ||
| 63 | !22 = !DILocation(line: 4, column: 7, scope: !16) | ||
| 64 | !23 = !DILocation(line: 4, column: 3, scope: !16) | ||
| 65 | !24 = !DILocation(line: 4, column: 11, scope: !16) | ||
| 66 | !25 = !{!26, !26, i64 0} | ||
| 67 | !26 = !{!"int", !27, i64 0} | ||
| 68 | !27 = !{!"omnipotent char", !28, i64 0} | ||
| 69 | !28 = !{!"Simple C/C++ TBAA"} | ||
| 70 | !29 = !DILocation(line: 5, column: 1, scope: !16) | ||
deps/lld/test/wasm/Inputs/global-ctor-dtor.ll+12-2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | define hidden void @myctor() { | 3 | define hidden void @myctor() { |
| 2 | entry: | 4 | entry: |
| 3 | ret void | 5 | ret void |
| ... | @@ -9,6 +11,14 @@ entry: | ... | @@ -9,6 +11,14 @@ entry: |
| 9 | ret void | 11 | ret void |
| 10 | } | 12 | } |
| 11 | 13 | ||
| 12 | @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @myctor, i8* null }] | 14 | @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [ |
| 15 | { i32, void ()*, i8* } { i32 2002, void ()* @myctor, i8* null }, | ||
| 16 | { i32, void ()*, i8* } { i32 101, void ()* @myctor, i8* null }, | ||
| 17 | { i32, void ()*, i8* } { i32 202, void ()* @myctor, i8* null } | ||
| 18 | ] | ||
| 13 | 19 | ||
| 14 | @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @mydtor, i8* null }] | 20 | @llvm.global_dtors = appending global [3 x { i32, void ()*, i8* }] [ |
| 21 | { i32, void ()*, i8* } { i32 2002, void ()* @mydtor, i8* null }, | ||
| 22 | { i32, void ()*, i8* } { i32 101, void ()* @mydtor, i8* null }, | ||
| 23 | { i32, void ()*, i8* } { i32 202, void ()* @mydtor, i8* null } | ||
| 24 | ] |
deps/lld/test/wasm/Inputs/globals.yaml created+54| ... | @@ -0,0 +1,54 @@ | ||
| 1 | --- !WASM | ||
| 2 | FileHeader: | ||
| 3 | Version: 0x00000001 | ||
| 4 | Sections: | ||
| 5 | - Type: TYPE | ||
| 6 | Signatures: | ||
| 7 | - Index: 0 | ||
| 8 | ReturnType: I64 | ||
| 9 | ParamTypes: | ||
| 10 | - Type: FUNCTION | ||
| 11 | FunctionTypes: [ 0 ] | ||
| 12 | - Type: GLOBAL | ||
| 13 | Globals: | ||
| 14 | - Index: 0 | ||
| 15 | Type: I64 | ||
| 16 | Mutable: true | ||
| 17 | InitExpr: | ||
| 18 | Opcode: I64_CONST | ||
| 19 | Value: 123 | ||
| 20 | - Index: 1 | ||
| 21 | Type: I64 | ||
| 22 | Mutable: true | ||
| 23 | InitExpr: | ||
| 24 | Opcode: I64_CONST | ||
| 25 | Value: 456 | ||
| 26 | - Type: CODE | ||
| 27 | Functions: | ||
| 28 | - Index: 0 | ||
| 29 | Locals: | ||
| 30 | Body: 2381808080000B | ||
| 31 | Relocations: | ||
| 32 | - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | ||
| 33 | Index: 1 | ||
| 34 | Offset: 0x00000004 | ||
| 35 | - Type: CUSTOM | ||
| 36 | Name: linking | ||
| 37 | Version: 1 | ||
| 38 | SymbolTable: | ||
| 39 | - Index: 0 | ||
| 40 | Kind: GLOBAL | ||
| 41 | Name: unused_global | ||
| 42 | Flags: [ VISIBILITY_HIDDEN ] | ||
| 43 | Global: 0 | ||
| 44 | - Index: 1 | ||
| 45 | Kind: GLOBAL | ||
| 46 | Name: used_global | ||
| 47 | Flags: [ VISIBILITY_HIDDEN ] | ||
| 48 | Global: 1 | ||
| 49 | - Index: 2 | ||
| 50 | Kind: FUNCTION | ||
| 51 | Name: use_global | ||
| 52 | Flags: [ VISIBILITY_HIDDEN ] | ||
| 53 | Function: 0 | ||
| 54 | ... | ||
deps/lld/test/wasm/Inputs/hello.ll+2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | ; Wasm module generated from the following C code: | 3 | ; Wasm module generated from the following C code: |
| 2 | ; void puts(const char*); | 4 | ; void puts(const char*); |
| 3 | ; void hello() { puts("hello\n"); } | 5 | ; void hello() { puts("hello\n"); } |
deps/lld/test/wasm/Inputs/hidden.ll+2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | ; Function Attrs: norecurse nounwind readnone | 3 | ; Function Attrs: norecurse nounwind readnone |
| 2 | define hidden i32 @archiveHidden() #0 { | 4 | define hidden i32 @archiveHidden() #0 { |
| 3 | entry: | 5 | entry: |
deps/lld/test/wasm/Inputs/locals-duplicate1.ll created+51| ... | @@ -0,0 +1,51 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | ; Will collide: local (internal linkage) with global (external) linkage | ||
| 4 | @colliding_global1 = internal default global i32 0, align 4 | ||
| 5 | ; Will collide: global with local | ||
| 6 | @colliding_global2 = default global i32 0, align 4 | ||
| 7 | ; Will collide: local with local | ||
| 8 | @colliding_global3 = internal default global i32 0, align 4 | ||
| 9 | |||
| 10 | ; Will collide: local with global | ||
| 11 | define internal i32 @colliding_func1() { | ||
| 12 | entry: | ||
| 13 | ret i32 2 | ||
| 14 | } | ||
| 15 | ; Will collide: global with local | ||
| 16 | define i32 @colliding_func2() { | ||
| 17 | entry: | ||
| 18 | ret i32 2 | ||
| 19 | } | ||
| 20 | ; Will collide: local with local | ||
| 21 | define internal i32 @colliding_func3() { | ||
| 22 | entry: | ||
| 23 | ret i32 2 | ||
| 24 | } | ||
| 25 | |||
| 26 | |||
| 27 | define i32* @get_global1A() { | ||
| 28 | entry: | ||
| 29 | ret i32* @colliding_global1 | ||
| 30 | } | ||
| 31 | define i32* @get_global2A() { | ||
| 32 | entry: | ||
| 33 | ret i32* @colliding_global2 | ||
| 34 | } | ||
| 35 | define i32* @get_global3A() { | ||
| 36 | entry: | ||
| 37 | ret i32* @colliding_global3 | ||
| 38 | } | ||
| 39 | |||
| 40 | define i32 ()* @get_func1A() { | ||
| 41 | entry: | ||
| 42 | ret i32 ()* @colliding_func1 | ||
| 43 | } | ||
| 44 | define i32 ()* @get_func2A() { | ||
| 45 | entry: | ||
| 46 | ret i32 ()* @colliding_func2 | ||
| 47 | } | ||
| 48 | define i32 ()* @get_func3A() { | ||
| 49 | entry: | ||
| 50 | ret i32 ()* @colliding_func3 | ||
| 51 | } | ||
deps/lld/test/wasm/Inputs/locals-duplicate2.ll created+51| ... | @@ -0,0 +1,51 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | ; Will collide: local (internal linkage) with global (external) linkage | ||
| 4 | @colliding_global1 = default global i32 0, align 4 | ||
| 5 | ; Will collide: global with local | ||
| 6 | @colliding_global2 = internal default global i32 0, align 4 | ||
| 7 | ; Will collide: local with local | ||
| 8 | @colliding_global3 = internal default global i32 0, align 4 | ||
| 9 | |||
| 10 | ; Will collide: local with global | ||
| 11 | define i32 @colliding_func1() { | ||
| 12 | entry: | ||
| 13 | ret i32 2 | ||
| 14 | } | ||
| 15 | ; Will collide: global with local | ||
| 16 | define internal i32 @colliding_func2() { | ||
| 17 | entry: | ||
| 18 | ret i32 2 | ||
| 19 | } | ||
| 20 | ; Will collide: local with local | ||
| 21 | define internal i32 @colliding_func3() { | ||
| 22 | entry: | ||
| 23 | ret i32 2 | ||
| 24 | } | ||
| 25 | |||
| 26 | |||
| 27 | define i32* @get_global1B() { | ||
| 28 | entry: | ||
| 29 | ret i32* @colliding_global1 | ||
| 30 | } | ||
| 31 | define i32* @get_global2B() { | ||
| 32 | entry: | ||
| 33 | ret i32* @colliding_global2 | ||
| 34 | } | ||
| 35 | define i32* @get_global3B() { | ||
| 36 | entry: | ||
| 37 | ret i32* @colliding_global3 | ||
| 38 | } | ||
| 39 | |||
| 40 | define i32 ()* @get_func1B() { | ||
| 41 | entry: | ||
| 42 | ret i32 ()* @colliding_func1 | ||
| 43 | } | ||
| 44 | define i32 ()* @get_func2B() { | ||
| 45 | entry: | ||
| 46 | ret i32 ()* @colliding_func2 | ||
| 47 | } | ||
| 48 | define i32 ()* @get_func3B() { | ||
| 49 | entry: | ||
| 50 | ret i32 ()* @colliding_func3 | ||
| 51 | } | ||
deps/lld/test/wasm/Inputs/many-funcs.ll+2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | @g0 = global i32 1, align 4 | 3 | @g0 = global i32 1, align 4 |
| 2 | @foo = global i32 1, align 4 | 4 | @foo = global i32 1, align 4 |
| 3 | 5 |
deps/lld/test/wasm/Inputs/ret32.ll+3-3| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; Function Attrs: norecurse nounwind readnone | 1 | target triple = "wasm32-unknown-unknown" |
| 2 | define i32 @ret32(float %arg) #0 { | 2 | |
| 3 | define hidden i32 @ret32(float %arg) { | ||
| 3 | entry: | 4 | entry: |
| 4 | ret i32 0 | 5 | ret i32 0 |
| 5 | ; ptrtoint (i32 (float)* @ret32 to i32) | ||
| 6 | } | 6 | } |
deps/lld/test/wasm/Inputs/ret64.ll+3-1| ... | @@ -1,4 +1,6 @@ | ... | @@ -1,4 +1,6 @@ |
| 1 | define i64 @ret64(double %arg) local_unnamed_addr #0 { | 1 | target triple = "wasm32-unknown-unknown" |
| 2 | |||
| 3 | define hidden i64 @ret64(double %arg) { | ||
| 2 | entry: | 4 | entry: |
| 3 | ret i64 1 | 5 | ret i64 1 |
| 4 | } | 6 | } |
deps/lld/test/wasm/Inputs/start.ll created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | define void @_start() local_unnamed_addr { | ||
| 4 | entry: | ||
| 5 | ret void | ||
| 6 | } | ||
deps/lld/test/wasm/Inputs/strong-symbol.ll created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | define i64 @weakFn() #0 { | ||
| 4 | entry: | ||
| 5 | ret i64 1 | ||
| 6 | } | ||
deps/lld/test/wasm/Inputs/undefined-globals.yaml created+52| ... | @@ -0,0 +1,52 @@ | ||
| 1 | --- !WASM | ||
| 2 | FileHeader: | ||
| 3 | Version: 0x00000001 | ||
| 4 | Sections: | ||
| 5 | - Type: TYPE | ||
| 6 | Signatures: | ||
| 7 | - Index: 0 | ||
| 8 | ReturnType: I64 | ||
| 9 | ParamTypes: | ||
| 10 | - Type: IMPORT | ||
| 11 | Imports: | ||
| 12 | - Module: env | ||
| 13 | Field: unused_undef_global | ||
| 14 | Kind: GLOBAL | ||
| 15 | GlobalType: I64 | ||
| 16 | GlobalMutable: true | ||
| 17 | - Module: env | ||
| 18 | Field: used_undef_global | ||
| 19 | Kind: GLOBAL | ||
| 20 | GlobalType: I64 | ||
| 21 | GlobalMutable: true | ||
| 22 | - Type: FUNCTION | ||
| 23 | FunctionTypes: [ 0 ] | ||
| 24 | - Type: CODE | ||
| 25 | Functions: | ||
| 26 | - Index: 0 | ||
| 27 | Locals: | ||
| 28 | Body: 2381808080000B | ||
| 29 | Relocations: | ||
| 30 | - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | ||
| 31 | Index: 1 | ||
| 32 | Offset: 0x00000004 | ||
| 33 | - Type: CUSTOM | ||
| 34 | Name: linking | ||
| 35 | Version: 1 | ||
| 36 | SymbolTable: | ||
| 37 | - Index: 0 | ||
| 38 | Kind: GLOBAL | ||
| 39 | Name: unused_undef_global | ||
| 40 | Flags: [ VISIBILITY_HIDDEN, UNDEFINED ] | ||
| 41 | Global: 0 | ||
| 42 | - Index: 1 | ||
| 43 | Kind: GLOBAL | ||
| 44 | Name: used_undef_global | ||
| 45 | Flags: [ VISIBILITY_HIDDEN, UNDEFINED ] | ||
| 46 | Global: 1 | ||
| 47 | - Index: 2 | ||
| 48 | Kind: FUNCTION | ||
| 49 | Name: use_undef_global | ||
| 50 | Flags: [ VISIBILITY_HIDDEN ] | ||
| 51 | Function: 0 | ||
| 52 | ... | ||
deps/lld/test/wasm/Inputs/weak-alias.ll+2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | ; Function Attrs: norecurse nounwind readnone | 3 | ; Function Attrs: norecurse nounwind readnone |
| 2 | define i32 @direct_fn() #0 { | 4 | define i32 @direct_fn() #0 { |
| 3 | entry: | 5 | entry: |
deps/lld/test/wasm/Inputs/weak-symbol1.ll+2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | define weak i32 @weakFn() #0 { | 3 | define weak i32 @weakFn() #0 { |
| 2 | entry: | 4 | entry: |
| 3 | ret i32 1 | 5 | ret i32 1 |
deps/lld/test/wasm/Inputs/weak-symbol2.ll+2| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 1 | define weak i32 @weakFn() #0 { | 3 | define weak i32 @weakFn() #0 { |
| 2 | entry: | 4 | entry: |
| 3 | ret i32 2 | 5 | ret i32 2 |
deps/lld/test/wasm/alias.ll created+88| ... | @@ -0,0 +1,88 @@ | ||
| 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 | target triple = "wasm32-unknown-unknown" | ||
| 6 | |||
| 7 | @start_alias = alias void (), void ()* @_start | ||
| 8 | |||
| 9 | ; Function Attrs: nounwind uwtable | ||
| 10 | define void @_start() local_unnamed_addr #1 { | ||
| 11 | entry: | ||
| 12 | ret void | ||
| 13 | } | ||
| 14 | |||
| 15 | ; CHECK: --- !WASM | ||
| 16 | ; CHECK-NEXT: FileHeader: | ||
| 17 | ; CHECK-NEXT: Version: 0x00000001 | ||
| 18 | ; CHECK-NEXT: Sections: | ||
| 19 | ; CHECK-NEXT: - Type: TYPE | ||
| 20 | ; CHECK-NEXT: Signatures: | ||
| 21 | ; CHECK-NEXT: - Index: 0 | ||
| 22 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 23 | ; CHECK-NEXT: ParamTypes: | ||
| 24 | ; CHECK-NEXT: - Type: FUNCTION | ||
| 25 | ; CHECK-NEXT: FunctionTypes: [ 0, 0 ] | ||
| 26 | ; CHECK-NEXT: - Type: TABLE | ||
| 27 | ; CHECK-NEXT: Tables: | ||
| 28 | ; CHECK-NEXT: - ElemType: ANYFUNC | ||
| 29 | ; CHECK-NEXT: Limits: | ||
| 30 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | ||
| 31 | ; CHECK-NEXT: Initial: 0x00000001 | ||
| 32 | ; CHECK-NEXT: Maximum: 0x00000001 | ||
| 33 | ; CHECK-NEXT: - Type: MEMORY | ||
| 34 | ; CHECK-NEXT: Memories: | ||
| 35 | ; CHECK-NEXT: - Initial: 0x00000002 | ||
| 36 | ; CHECK-NEXT: - Type: GLOBAL | ||
| 37 | ; CHECK-NEXT: Globals: | ||
| 38 | ; CHECK-NEXT: - Index: 0 | ||
| 39 | ; CHECK-NEXT: Type: I32 | ||
| 40 | ; CHECK-NEXT: Mutable: true | ||
| 41 | ; CHECK-NEXT: InitExpr: | ||
| 42 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 43 | ; 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 | ||
| 56 | ; CHECK-NEXT: - Type: EXPORT | ||
| 57 | ; CHECK-NEXT: Exports: | ||
| 58 | ; CHECK-NEXT: - Name: memory | ||
| 59 | ; CHECK-NEXT: Kind: MEMORY | ||
| 60 | ; 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 | ||
| 67 | ; CHECK-NEXT: - Name: _start | ||
| 68 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 69 | ; CHECK-NEXT: Index: 1 | ||
| 70 | ; CHECK-NEXT: - Name: start_alias | ||
| 71 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 72 | ; CHECK-NEXT: Index: 1 | ||
| 73 | ; CHECK-NEXT: - Type: CODE | ||
| 74 | ; CHECK-NEXT: Functions: | ||
| 75 | ; CHECK-NEXT: - Index: 0 | ||
| 76 | ; CHECK-NEXT: Locals: | ||
| 77 | ; CHECK-NEXT: Body: 0B | ||
| 78 | ; CHECK-NEXT: - Index: 1 | ||
| 79 | ; CHECK-NEXT: Locals: | ||
| 80 | ; CHECK-NEXT: Body: 0B | ||
| 81 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 82 | ; CHECK-NEXT: Name: name | ||
| 83 | ; CHECK-NEXT: FunctionNames: | ||
| 84 | ; CHECK-NEXT: - Index: 0 | ||
| 85 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 86 | ; CHECK-NEXT: - Index: 1 | ||
| 87 | ; CHECK-NEXT: Name: _start | ||
| 88 | ; CHECK-NEXT: ... | ||
deps/lld/test/wasm/archive.ll+38-18| ... | @@ -1,31 +1,51 @@ | ... | @@ -1,31 +1,51 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 1 | ; RUN: llc -filetype=obj %s -o %t.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/archive1.ll -o %t.a1.o | 2 | ; RUN: llc -filetype=obj %S/Inputs/archive1.ll -o %t.a1.o |
| 3 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/archive2.ll -o %t.a2.o | 3 | ; RUN: llc -filetype=obj %S/Inputs/archive2.ll -o %t.a2.o |
| 4 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/hello.ll -o %t.a3.o | 4 | ; RUN: llc -filetype=obj %S/Inputs/archive3.ll -o %t.a3.o |
| 5 | ; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o | 5 | ; RUN: llc -filetype=obj %S/Inputs/hello.ll -o %t.hello.o |
| 6 | ; RUN: lld -flavor wasm %t.a %t.o -o %t.wasm | 6 | ; RUN: llvm-ar rcs %t.a %t.a1.o %t.a2.o %t.a3.o %t.hello.o |
| 7 | ; RUN: rm -f %t.imports | ||
| 8 | ; RUN: not wasm-ld %t.a %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED %s | ||
| 9 | |||
| 10 | ; CHECK-UNDEFINED: undefined symbol: missing_func | ||
| 11 | |||
| 12 | ; RUN: echo 'missing_func' > %t.imports | ||
| 13 | ; RUN: wasm-ld -r %t.a %t.o -o %t.wasm | ||
| 14 | |||
| 7 | ; RUN: llvm-nm -a %t.wasm | FileCheck %s | 15 | ; RUN: llvm-nm -a %t.wasm | FileCheck %s |
| 8 | 16 | ||
| 17 | target triple = "wasm32-unknown-unknown" | ||
| 18 | |||
| 9 | declare i32 @foo() local_unnamed_addr #1 | 19 | declare i32 @foo() local_unnamed_addr #1 |
| 20 | declare i32 @missing_func() local_unnamed_addr #1 | ||
| 10 | 21 | ||
| 11 | define i32 @_start() local_unnamed_addr #0 { | 22 | define void @_start() local_unnamed_addr #0 { |
| 12 | entry: | 23 | entry: |
| 13 | %call = tail call i32 @foo() #2 | 24 | %call1 = call i32 @foo() #2 |
| 14 | ret i32 %call | 25 | %call2 = call i32 @missing_func() #2 |
| 26 | ret void | ||
| 15 | } | 27 | } |
| 16 | 28 | ||
| 17 | ; Verify that multually dependant object files in an archive is handled | 29 | ; Verify that mutually dependant object files in an archive is handled |
| 18 | ; correctly. | 30 | ; correctly. Since we're using llvm-nm, we must link with --relocatable. |
| 31 | ; | ||
| 32 | ; TODO(ncw): Update LLD so that the symbol table is written out for | ||
| 33 | ; non-relocatable output (with an option to strip it) | ||
| 19 | 34 | ||
| 20 | ; CHECK: 00000002 T _start | 35 | ; CHECK: 00000004 T _start |
| 21 | ; CHECK-NEXT: 00000002 T _start | 36 | ; CHECK-NEXT: 00000002 T archive2_symbol |
| 22 | ; CHECK-NEXT: 00000000 T bar | 37 | ; CHECK-NEXT: 00000001 T bar |
| 23 | ; CHECK-NEXT: 00000000 T bar | 38 | ; CHECK-NEXT: 00000003 T foo |
| 24 | ; CHECK-NEXT: 00000001 T foo | 39 | ; CHECK-NEXT: U missing_func |
| 25 | ; CHECK-NEXT: 00000001 T foo | ||
| 26 | 40 | ||
| 27 | ; Verify that symbols from unused objects don't appear in the symbol table | 41 | ; Verify that symbols from unused objects don't appear in the symbol table |
| 28 | ; CHECK-NOT: hello | 42 | ; CHECK-NOT: hello |
| 29 | 43 | ||
| 30 | ; Specifying the same archive twice is allowed. | 44 | ; Specifying the same archive twice is allowed. |
| 31 | ; RUN: lld -flavor wasm %t.a %t.a %t.o -o %t.wasm | 45 | ; RUN: wasm-ld %t.a %t.a %t.o -o %t.wasm |
| 46 | |||
| 47 | ; Verfiy errors include library name | ||
| 48 | ; 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 | ||
| 49 | ; CHECK-DUP: error: duplicate symbol: bar | ||
| 50 | ; CHECK-DUP: >>> defined in {{.*}}.a({{.*}}.a2.o) | ||
| 51 | ; CHECK-DUP: >>> defined in {{.*}}.a({{.*}}.a3.o) |
deps/lld/test/wasm/call-indirect.ll+82-37| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/call-indirect.ll -o %t2.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 2 | ; RUN: llc -filetype=obj %s -o %t.o |
| 3 | ; RUN: lld -flavor wasm -o %t.wasm %t2.o %t.o | 3 | ; RUN: wasm-ld -o %t.wasm %t2.o %t.o |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 5 | 5 | ||
| 6 | ; bitcode generated from the following C code: | 6 | ; bitcode generated from the following C code: |
| ... | @@ -8,6 +8,8 @@ | ... | @@ -8,6 +8,8 @@ |
| 8 | ; int (*indirect_func)(void) = &foo; | 8 | ; int (*indirect_func)(void) = &foo; |
| 9 | ; void _start(void) { indirect_func(); } | 9 | ; void _start(void) { indirect_func(); } |
| 10 | 10 | ||
| 11 | target triple = "wasm32-unknown-unknown" | ||
| 12 | |||
| 11 | @indirect_func = local_unnamed_addr global i32 ()* @foo, align 4 | 13 | @indirect_func = local_unnamed_addr global i32 ()* @foo, align 4 |
| 12 | 14 | ||
| 13 | ; Function Attrs: norecurse nounwind readnone | 15 | ; Function Attrs: norecurse nounwind readnone |
| ... | @@ -17,11 +19,11 @@ entry: | ... | @@ -17,11 +19,11 @@ entry: |
| 17 | } | 19 | } |
| 18 | 20 | ||
| 19 | ; Function Attrs: nounwind | 21 | ; Function Attrs: nounwind |
| 20 | define i32 @_start() local_unnamed_addr #1 { | 22 | define void @_start() local_unnamed_addr #1 { |
| 21 | entry: | 23 | entry: |
| 22 | %0 = load i32 ()*, i32 ()** @indirect_func, align 4 | 24 | %0 = load i32 ()*, i32 ()** @indirect_func, align 4 |
| 23 | %call = call i32 %0() #2 | 25 | %call = call i32 %0() #2 |
| 24 | ret i32 0 | 26 | ret void |
| 25 | } | 27 | } |
| 26 | 28 | ||
| 27 | ; Indirect function call where no function actually has this type. | 29 | ; Indirect function call where no function actually has this type. |
| ... | @@ -38,21 +40,24 @@ define void @call_ptr(i64 (i64)* %arg) { | ... | @@ -38,21 +40,24 @@ define void @call_ptr(i64 (i64)* %arg) { |
| 38 | ; CHECK-NEXT: - Type: TYPE | 40 | ; CHECK-NEXT: - Type: TYPE |
| 39 | ; CHECK-NEXT: Signatures: | 41 | ; CHECK-NEXT: Signatures: |
| 40 | ; CHECK-NEXT: - Index: 0 | 42 | ; CHECK-NEXT: - Index: 0 |
| 41 | ; CHECK-NEXT: ReturnType: I32 | 43 | ; CHECK-NEXT: ReturnType: I64 |
| 42 | ; CHECK-NEXT: ParamTypes: | 44 | ; CHECK-NEXT: ParamTypes: |
| 43 | ; CHECK-NEXT: - Index: 1 | 45 | ; CHECK-NEXT: - Index: 1 |
| 44 | ; CHECK-NEXT: ReturnType: NORESULT | 46 | ; CHECK-NEXT: ReturnType: I32 |
| 45 | ; CHECK-NEXT: ParamTypes: | 47 | ; CHECK-NEXT: ParamTypes: |
| 46 | ; CHECK-NEXT: - Index: 2 | 48 | ; CHECK-NEXT: - Index: 2 |
| 47 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 48 | ; CHECK-NEXT: ParamTypes: | ||
| 49 | ; CHECK-NEXT: - I32 | ||
| 50 | ; CHECK-NEXT: - Index: 3 | ||
| 51 | ; CHECK-NEXT: ReturnType: I64 | 49 | ; CHECK-NEXT: ReturnType: I64 |
| 52 | ; CHECK-NEXT: ParamTypes: | 50 | ; CHECK-NEXT: ParamTypes: |
| 53 | ; CHECK-NEXT: - I64 | 51 | ; CHECK-NEXT: - I64 |
| 52 | ; CHECK-NEXT: - Index: 3 | ||
| 53 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 54 | ; CHECK-NEXT: ParamTypes: | ||
| 55 | ; CHECK-NEXT: - Index: 4 | ||
| 56 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 57 | ; CHECK-NEXT: ParamTypes: | ||
| 58 | ; CHECK-NEXT: - I32 | ||
| 54 | ; CHECK-NEXT: - Type: FUNCTION | 59 | ; CHECK-NEXT: - Type: FUNCTION |
| 55 | ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0, 2 ] | 60 | ; CHECK-NEXT: FunctionTypes: [ 3, 0, 3, 1, 3, 4 ] |
| 56 | ; CHECK-NEXT: - Type: TABLE | 61 | ; CHECK-NEXT: - Type: TABLE |
| 57 | ; CHECK-NEXT: Tables: | 62 | ; CHECK-NEXT: Tables: |
| 58 | ; CHECK-NEXT: - ElemType: ANYFUNC | 63 | ; CHECK-NEXT: - ElemType: ANYFUNC |
| ... | @@ -65,49 +70,87 @@ define void @call_ptr(i64 (i64)* %arg) { | ... | @@ -65,49 +70,87 @@ define void @call_ptr(i64 (i64)* %arg) { |
| 65 | ; CHECK-NEXT: - Initial: 0x00000002 | 70 | ; CHECK-NEXT: - Initial: 0x00000002 |
| 66 | ; CHECK-NEXT: - Type: GLOBAL | 71 | ; CHECK-NEXT: - Type: GLOBAL |
| 67 | ; CHECK-NEXT: Globals: | 72 | ; CHECK-NEXT: Globals: |
| 68 | ; CHECK-NEXT: - Type: I32 | 73 | ; CHECK-NEXT: - Index: 0 |
| 74 | ; CHECK-NEXT: Type: I32 | ||
| 69 | ; CHECK-NEXT: Mutable: true | 75 | ; CHECK-NEXT: Mutable: true |
| 70 | ; CHECK-NEXT: InitExpr: | 76 | ; CHECK-NEXT: InitExpr: |
| 71 | ; CHECK-NEXT: Opcode: I32_CONST | 77 | ; CHECK-NEXT: Opcode: I32_CONST |
| 72 | ; CHECK-NEXT: Value: 66576 | 78 | ; CHECK-NEXT: Value: 66576 |
| 79 | ; CHECK-NEXT: - Index: 1 | ||
| 80 | ; CHECK-NEXT: Type: I32 | ||
| 81 | ; CHECK-NEXT: Mutable: false | ||
| 82 | ; CHECK-NEXT: InitExpr: | ||
| 83 | ; 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 | ||
| 96 | ; CHECK-NEXT: Value: 1032 | ||
| 73 | ; CHECK-NEXT: - Type: EXPORT | 97 | ; CHECK-NEXT: - Type: EXPORT |
| 74 | ; CHECK-NEXT: Exports: | 98 | ; CHECK-NEXT: Exports: |
| 75 | ; CHECK-NEXT: - Name: memory | 99 | ; CHECK-NEXT: - Name: memory |
| 76 | ; CHECK-NEXT: Kind: MEMORY | 100 | ; CHECK-NEXT: Kind: MEMORY |
| 77 | ; CHECK-NEXT: Index: 0 | 101 | ; 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 | ||
| 78 | ; CHECK-NEXT: - Name: _start | 108 | ; CHECK-NEXT: - Name: _start |
| 79 | ; CHECK-NEXT: Kind: FUNCTION | 109 | ; CHECK-NEXT: Kind: FUNCTION |
| 80 | ; CHECK-NEXT: Index: 3 | 110 | ; CHECK-NEXT: Index: 4 |
| 81 | ; CHECK-NEXT: - Name: foo | ||
| 82 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 83 | ; CHECK-NEXT: Index: 2 | ||
| 84 | ; CHECK-NEXT: - Name: bar | 111 | ; CHECK-NEXT: - Name: bar |
| 85 | ; CHECK-NEXT: Kind: FUNCTION | 112 | ; CHECK-NEXT: Kind: FUNCTION |
| 86 | ; CHECK-NEXT: Index: 0 | 113 | ; CHECK-NEXT: Index: 1 |
| 87 | ; CHECK-NEXT: - Name: call_bar_indirect | 114 | ; CHECK-NEXT: - Name: call_bar_indirect |
| 88 | ; CHECK-NEXT: Kind: FUNCTION | 115 | ; CHECK-NEXT: Kind: FUNCTION |
| 89 | ; CHECK-NEXT: Index: 1 | 116 | ; CHECK-NEXT: Index: 2 |
| 117 | ; CHECK-NEXT: - Name: foo | ||
| 118 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 119 | ; CHECK-NEXT: Index: 3 | ||
| 120 | ; CHECK-NEXT: - Name: indirect_func | ||
| 121 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 122 | ; CHECK-NEXT: Index: 3 | ||
| 90 | ; CHECK-NEXT: - Name: call_ptr | 123 | ; CHECK-NEXT: - Name: call_ptr |
| 91 | ; CHECK-NEXT: Kind: FUNCTION | 124 | ; CHECK-NEXT: Kind: FUNCTION |
| 92 | ; CHECK-NEXT: Index: 4 | 125 | ; CHECK-NEXT: Index: 5 |
| 93 | ; CHECK-NEXT: - Type: ELEM | 126 | ; CHECK-NEXT: - Type: ELEM |
| 94 | ; CHECK-NEXT: Segments: | 127 | ; CHECK-NEXT: Segments: |
| 95 | ; CHECK-NEXT: - Offset: | 128 | ; CHECK-NEXT: - Offset: |
| 96 | ; CHECK-NEXT: Opcode: I32_CONST | 129 | ; CHECK-NEXT: Opcode: I32_CONST |
| 97 | ; CHECK-NEXT: Value: 1 | 130 | ; CHECK-NEXT: Value: 1 |
| 98 | ; CHECK-NEXT: Functions: [ 0, 2 ] | 131 | ; CHECK-NEXT: Functions: [ 1, 3 ] |
| 99 | ; CHECK-NEXT: - Type: CODE | 132 | ; CHECK-NEXT: - Type: CODE |
| 100 | ; CHECK-NEXT: Functions: | 133 | ; CHECK-NEXT: Functions: |
| 101 | ; CHECK-NEXT: - Locals: | 134 | ; CHECK-NEXT: - Index: 0 |
| 102 | ; CHECK-NEXT: Body: 41010B | 135 | ; CHECK-NEXT: Locals: |
| 103 | ; CHECK-NEXT: - Locals: | 136 | ; CHECK-NEXT: Body: 0B |
| 104 | ; CHECK-NEXT: Body: 410028028088808000118080808000001A0B | 137 | ; CHECK-NEXT: - Index: 1 |
| 105 | ; CHECK-NEXT: - Locals: | 138 | ; CHECK-NEXT: Locals: |
| 139 | ; CHECK-NEXT: Body: 42010B | ||
| 140 | ; CHECK-NEXT: - Index: 2 | ||
| 141 | ; CHECK-NEXT: Locals: | ||
| 142 | ; CHECK-NEXT: - Type: I32 | ||
| 143 | ; CHECK-NEXT: Count: 1 | ||
| 144 | ; CHECK-NEXT: Body: 4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B | ||
| 145 | ; CHECK-NEXT: - Index: 3 | ||
| 146 | ; CHECK-NEXT: Locals: | ||
| 106 | ; CHECK-NEXT: Body: 41020B | 147 | ; CHECK-NEXT: Body: 41020B |
| 107 | ; CHECK-NEXT: - Locals: | 148 | ; CHECK-NEXT: - Index: 4 |
| 108 | ; CHECK-NEXT: Body: 410028028888808000118080808000001A41000B | 149 | ; CHECK-NEXT: Locals: |
| 109 | ; CHECK-NEXT: - Locals: | 150 | ; CHECK-NEXT: Body: 410028028888808000118180808000001A0B |
| 110 | ; CHECK-NEXT: Body: 42012000118380808000001A0B | 151 | ; CHECK-NEXT: - Index: 5 |
| 152 | ; CHECK-NEXT: Locals: | ||
| 153 | ; CHECK-NEXT: Body: 42012000118280808000001A0B | ||
| 111 | ; CHECK-NEXT: - Type: DATA | 154 | ; CHECK-NEXT: - Type: DATA |
| 112 | ; CHECK-NEXT: Segments: | 155 | ; CHECK-NEXT: Segments: |
| 113 | ; CHECK-NEXT: - SectionOffset: 7 | 156 | ; CHECK-NEXT: - SectionOffset: 7 |
| ... | @@ -117,16 +160,18 @@ define void @call_ptr(i64 (i64)* %arg) { | ... | @@ -117,16 +160,18 @@ define void @call_ptr(i64 (i64)* %arg) { |
| 117 | ; CHECK-NEXT: Value: 1024 | 160 | ; CHECK-NEXT: Value: 1024 |
| 118 | ; CHECK-NEXT: Content: '010000000200000002000000' | 161 | ; CHECK-NEXT: Content: '010000000200000002000000' |
| 119 | ; CHECK-NEXT: - Type: CUSTOM | 162 | ; CHECK-NEXT: - Type: CUSTOM |
| 120 | ; CHECK-NEXT: Name: linking | ||
| 121 | ; CHECK-NEXT: DataSize: 12 | ||
| 122 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 123 | ; CHECK-NEXT: Name: name | 163 | ; CHECK-NEXT: Name: name |
| 124 | ; CHECK-NEXT: FunctionNames: | 164 | ; CHECK-NEXT: FunctionNames: |
| 125 | ; CHECK-NEXT: - Index: 0 | 165 | ; CHECK-NEXT: - Index: 0 |
| 126 | ; CHECK-NEXT: Name: bar | 166 | ; CHECK-NEXT: Name: __wasm_call_ctors |
| 127 | ; CHECK-NEXT: - Index: 1 | 167 | ; CHECK-NEXT: - Index: 1 |
| 128 | ; CHECK-NEXT: Name: call_bar_indirect | 168 | ; CHECK-NEXT: Name: bar |
| 129 | ; CHECK-NEXT: - Index: 2 | 169 | ; CHECK-NEXT: - Index: 2 |
| 130 | ; CHECK-NEXT: Name: foo | 170 | ; CHECK-NEXT: Name: call_bar_indirect |
| 131 | ; CHECK-NEXT: - Index: 3 | 171 | ; CHECK-NEXT: - Index: 3 |
| 172 | ; CHECK-NEXT: Name: foo | ||
| 173 | ; CHECK-NEXT: - Index: 4 | ||
| 132 | ; CHECK-NEXT: Name: _start | 174 | ; CHECK-NEXT: Name: _start |
| 175 | ; CHECK-NEXT: - Index: 5 | ||
| 176 | ; CHECK-NEXT: Name: call_ptr | ||
| 177 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/comdats.ll created+99| ... | @@ -0,0 +1,99 @@ | ||
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat1.ll -o %t1.o | ||
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %p/Inputs/comdat2.ll -o %t2.o | ||
| 3 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %s -o %t.o | ||
| 4 | ; RUN: wasm-ld -o %t.wasm %t.o %t1.o %t2.o | ||
| 5 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 6 | |||
| 7 | target triple = "wasm32-unknown-unknown" | ||
| 8 | |||
| 9 | declare i32 @inlineFn() | ||
| 10 | |||
| 11 | define void @_start() local_unnamed_addr { | ||
| 12 | entry: | ||
| 13 | %call = call i32 @inlineFn() | ||
| 14 | ret void | ||
| 15 | } | ||
| 16 | |||
| 17 | ; CHECK: - Type: GLOBAL | ||
| 18 | ; CHECK-NEXT: Globals: | ||
| 19 | ; CHECK-NEXT: - Index: 0 | ||
| 20 | ; CHECK-NEXT: Type: I32 | ||
| 21 | ; CHECK-NEXT: Mutable: true | ||
| 22 | ; CHECK-NEXT: InitExpr: | ||
| 23 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 24 | ; CHECK-NEXT: Value: 66576 | ||
| 25 | ; CHECK-NEXT: - Index: 1 | ||
| 26 | ; CHECK-NEXT: Type: I32 | ||
| 27 | ; CHECK-NEXT: Mutable: false | ||
| 28 | ; CHECK-NEXT: InitExpr: | ||
| 29 | ; 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 | ||
| 42 | ; CHECK-NEXT: Value: 1024 | ||
| 43 | ; CHECK-NEXT: - Type: EXPORT | ||
| 44 | ; CHECK-NEXT: Exports: | ||
| 45 | ; CHECK-NEXT: - Name: memory | ||
| 46 | ; CHECK-NEXT: Kind: MEMORY | ||
| 47 | ; 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 | ||
| 54 | ; CHECK-NEXT: - Name: _start | ||
| 55 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 56 | ; CHECK-NEXT: Index: 1 | ||
| 57 | ; CHECK-NEXT: - Name: inlineFn | ||
| 58 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 59 | ; CHECK-NEXT: Index: 2 | ||
| 60 | ; CHECK-NEXT: - Name: constantData | ||
| 61 | ; 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 | ||
| 67 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 68 | ; CHECK-NEXT: Index: 4 | ||
| 69 | ; CHECK-NEXT: - Type: ELEM | ||
| 70 | ; CHECK-NEXT: Segments: | ||
| 71 | ; CHECK-NEXT: - Offset: | ||
| 72 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 73 | ; CHECK-NEXT: Value: 1 | ||
| 74 | ; CHECK-NEXT: Functions: [ 2 ] | ||
| 75 | ; CHECK-NEXT: - Type: CODE | ||
| 76 | ; CHECK-NEXT: Functions: | ||
| 77 | ; CHECK-NEXT: - Index: 0 | ||
| 78 | ; CHECK-NEXT: Locals: | ||
| 79 | ; CHECK-NEXT: Body: 0B | ||
| 80 | ; CHECK-NEXT: - Index: 1 | ||
| 81 | ; CHECK-NEXT: Locals: | ||
| 82 | ; CHECK-NEXT: Body: 1082808080001A0B | ||
| 83 | ; CHECK-NEXT: - Index: 2 | ||
| 84 | ; CHECK-NEXT: Locals: | ||
| 85 | ; CHECK-NEXT: Body: 4180888080000B | ||
| 86 | ; CHECK-NEXT: - Index: 3 | ||
| 87 | ; CHECK-NEXT: Locals: | ||
| 88 | ; CHECK-NEXT: Body: 4181808080000B | ||
| 89 | ; CHECK-NEXT: - Index: 4 | ||
| 90 | ; CHECK-NEXT: Locals: | ||
| 91 | ; CHECK-NEXT: Body: 4181808080000B | ||
| 92 | ; CHECK-NEXT: - Type: DATA | ||
| 93 | ; CHECK-NEXT: Segments: | ||
| 94 | ; CHECK-NEXT: - SectionOffset: 7 | ||
| 95 | ; CHECK-NEXT: MemoryIndex: 0 | ||
| 96 | ; CHECK-NEXT: Offset: | ||
| 97 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 98 | ; CHECK-NEXT: Value: 1024 | ||
| 99 | ; CHECK-NEXT: Content: '616263' | ||
deps/lld/test/wasm/compress-relocs.ll created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | ; RUN: llc -filetype=obj %p/Inputs/call-indirect.ll -o %t2.o | ||
| 2 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 3 | ; RUN: wasm-ld -o %t.wasm %t2.o %t.o | ||
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | ; RUN: wasm-ld -O2 -o %t-compressed.wasm %t2.o %t.o | ||
| 7 | ; RUN: obj2yaml %t-compressed.wasm | FileCheck %s -check-prefix=COMPRESS | ||
| 8 | |||
| 9 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 10 | |||
| 11 | define i32 @foo() { | ||
| 12 | entry: | ||
| 13 | ret i32 2 | ||
| 14 | } | ||
| 15 | |||
| 16 | define void @_start() local_unnamed_addr { | ||
| 17 | entry: | ||
| 18 | ret void | ||
| 19 | } | ||
| 20 | |||
| 21 | ; CHECK: Body: 4100280284888080002100410028028088808000118080808000001A2000118180808000001A0B | ||
| 22 | ; COMPRESS: Body: 41002802840821004100280280081100001A20001101001A0B | ||
deps/lld/test/wasm/conflict.test+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | # RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 1 | # RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o |
| 2 | # RUN: not lld -flavor wasm -o %t.wasm %t.ret32.o %t.ret32.o 2>&1 | FileCheck %s | 2 | # RUN: not wasm-ld -o %t.wasm %t.ret32.o %t.ret32.o 2>&1 | FileCheck %s |
| 3 | 3 | ||
| 4 | # CHECK: duplicate symbol: ret32 | 4 | # CHECK: duplicate symbol: ret32 |
| 5 | # CHECK-NEXT: >>> defined in {{.*}}conflict.test.tmp.ret32.o | 5 | # CHECK-NEXT: >>> defined in {{.*}}conflict.test.tmp.ret32.o |
deps/lld/test/wasm/custom-sections.ll created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t1.o | ||
| 2 | ; RUN: llc -filetype=obj %S/Inputs/custom.ll -o %t2.o | ||
| 3 | ; RUN: wasm-ld --relocatable -o %t.wasm %t1.o %t2.o | ||
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | target triple = "wasm32-unknown-unknown" | ||
| 7 | |||
| 8 | define i32 @_start() local_unnamed_addr { | ||
| 9 | entry: | ||
| 10 | %retval = alloca i32, align 4 | ||
| 11 | ret i32 0 | ||
| 12 | } | ||
| 13 | |||
| 14 | !0 = !{ !"red", !"extra" } | ||
| 15 | !wasm.custom_sections = !{ !0 } | ||
| 16 | |||
| 17 | ; CHECK: - Type: CUSTOM | ||
| 18 | ; CHECK-NEXT: Name: green | ||
| 19 | ; CHECK-NEXT: Payload: '626172717578' | ||
| 20 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 21 | ; CHECK-NEXT: Name: red | ||
| 22 | ; CHECK-NEXT: Payload: 6578747261666F6F | ||
deps/lld/test/wasm/cxx-mangling.ll created+66| ... | @@ -0,0 +1,66 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 2 | ; RUN: wasm-ld --demangle -o %t_demangle.wasm %t.o | ||
| 3 | ; RUN: obj2yaml %t_demangle.wasm | FileCheck %s | ||
| 4 | ; RUN: wasm-ld --no-demangle -o %t_nodemangle.wasm %t.o | ||
| 5 | ; RUN: obj2yaml %t_nodemangle.wasm | FileCheck %s | ||
| 6 | |||
| 7 | target triple = "wasm32-unknown-unknown" | ||
| 8 | |||
| 9 | ; Check that the EXPORT name is still mangled, but that the "name" custom | ||
| 10 | ; section contains the unmangled name. | ||
| 11 | |||
| 12 | define void @_Z3fooi(i32 %arg) { | ||
| 13 | ret void | ||
| 14 | } | ||
| 15 | |||
| 16 | declare extern_weak void @_Z3bari(i32 %arg) | ||
| 17 | |||
| 18 | define void @_start() { | ||
| 19 | call void @_Z3fooi(i32 1) | ||
| 20 | call void @_Z3bari(i32 1) | ||
| 21 | ret void | ||
| 22 | } | ||
| 23 | |||
| 24 | ; CHECK: - Type: EXPORT | ||
| 25 | ; CHECK-NEXT: Exports: | ||
| 26 | ; CHECK-NEXT: - Name: memory | ||
| 27 | ; CHECK-NEXT: Kind: MEMORY | ||
| 28 | ; 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 | ||
| 35 | ; CHECK-NEXT: - Name: _start | ||
| 36 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 37 | ; CHECK-NEXT: Index: 3 | ||
| 38 | ; CHECK-NEXT: - Name: _Z3fooi | ||
| 39 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 40 | ; CHECK-NEXT: Index: 2 | ||
| 41 | ; CHECK-NEXT: - Type: CODE | ||
| 42 | ; CHECK-NEXT: Functions: | ||
| 43 | ; CHECK-NEXT: - Index: 0 | ||
| 44 | ; CHECK-NEXT: Locals: | ||
| 45 | ; CHECK-NEXT: Body: 0B | ||
| 46 | ; CHECK-NEXT: - Index: 1 | ||
| 47 | ; CHECK-NEXT: Locals: | ||
| 48 | ; CHECK-NEXT: Body: 000B | ||
| 49 | ; CHECK-NEXT: - Index: 2 | ||
| 50 | ; CHECK-NEXT: Locals: | ||
| 51 | ; CHECK-NEXT: Body: 0B | ||
| 52 | ; CHECK-NEXT: - Index: 3 | ||
| 53 | ; CHECK-NEXT: Locals: | ||
| 54 | ; CHECK-NEXT: Body: 410110828080800041011081808080000B | ||
| 55 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 56 | ; CHECK-NEXT: Name: name | ||
| 57 | ; CHECK-NEXT: FunctionNames: | ||
| 58 | ; CHECK-NEXT: - Index: 0 | ||
| 59 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 60 | ; CHECK-NEXT: - Index: 1 | ||
| 61 | ; CHECK-NEXT: Name: 'undefined function bar(int)' | ||
| 62 | ; CHECK-NEXT: - Index: 2 | ||
| 63 | ; CHECK-NEXT: Name: 'foo(int)' | ||
| 64 | ; CHECK-NEXT: - Index: 3 | ||
| 65 | ; CHECK-NEXT: Name: _start | ||
| 66 | ; CHECK-NEXT: ... | ||
deps/lld/test/wasm/data-layout.ll+119-34| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/hello.ll -o %t.hello.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/hello.ll -o %t.hello.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 2 | ; RUN: llc -filetype=obj %s -o %t.o |
| 3 | ; RUN: lld -flavor wasm --emit-relocs --allow-undefined --no-entry -o %t.wasm %t.o %t.hello.o | 3 | |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 4 | target triple = "wasm32-unknown-unknown" |
| 5 | 5 | ||
| 6 | @foo = hidden global i32 1, align 4 | 6 | @foo = hidden global i32 1, align 4 |
| 7 | @aligned_bar = hidden global i32 3, align 16 | 7 | @aligned_bar = hidden global i32 3, align 16 |
| ... | @@ -9,53 +9,138 @@ | ... | @@ -9,53 +9,138 @@ |
| 9 | @hello_str = external global i8* | 9 | @hello_str = external global i8* |
| 10 | @external_ref = global i8** @hello_str, align 8 | 10 | @external_ref = global i8** @hello_str, align 8 |
| 11 | 11 | ||
| 12 | ; CHECK: - Type: GLOBAL | 12 | %struct.s = type { i32, i32 } |
| 13 | @local_struct = hidden global %struct.s zeroinitializer, align 4 | ||
| 14 | @local_struct_internal_ptr = hidden local_unnamed_addr global i32* getelementptr inbounds (%struct.s, %struct.s* @local_struct, i32 0, i32 1), align 4 | ||
| 15 | |||
| 16 | ; RUN: wasm-ld -no-gc-sections --allow-undefined --no-entry -o %t.wasm %t.o %t.hello.o | ||
| 17 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 18 | |||
| 19 | ; CHECK: - Type: MEMORY | ||
| 20 | ; CHECK-NEXT: Memories: | ||
| 21 | ; CHECK-NEXT: - Initial: 0x00000002 | ||
| 22 | ; CHECK-NEXT: - Type: GLOBAL | ||
| 13 | ; CHECK-NEXT: Globals: | 23 | ; CHECK-NEXT: Globals: |
| 14 | ; CHECK-NEXT: - Type: I32 | 24 | ; CHECK-NEXT: - Index: 0 |
| 25 | ; CHECK-NEXT: Type: I32 | ||
| 15 | ; CHECK-NEXT: Mutable: true | 26 | ; CHECK-NEXT: Mutable: true |
| 16 | ; CHECK-NEXT: InitExpr: | 27 | ; CHECK-NEXT: InitExpr: |
| 17 | ; CHECK-NEXT: Opcode: I32_CONST | 28 | ; CHECK-NEXT: Opcode: I32_CONST |
| 18 | ; CHECK-NEXT: Value: 66608 | 29 | ; CHECK-NEXT: Value: 66608 |
| 19 | ; CHECK-NEXT: - Type: I32 | 30 | ; CHECK-NEXT: - Index: 1 |
| 20 | ; CHECK-NEXT: Mutable: false | 31 | ; CHECK-NEXT: Type: I32 |
| 21 | ; CHECK-NEXT: InitExpr: | ||
| 22 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 23 | ; CHECK-NEXT: Value: 1024 | ||
| 24 | ; CHECK-NEXT: - Type: I32 | ||
| 25 | ; CHECK-NEXT: Mutable: false | ||
| 26 | ; CHECK-NEXT: InitExpr: | ||
| 27 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 28 | ; CHECK-NEXT: Value: 1040 | ||
| 29 | ; CHECK-NEXT: - Type: I32 | ||
| 30 | ; CHECK-NEXT: Mutable: false | 32 | ; CHECK-NEXT: Mutable: false |
| 31 | ; CHECK-NEXT: InitExpr: | 33 | ; CHECK-NEXT: InitExpr: |
| 32 | ; CHECK-NEXT: Opcode: I32_CONST | 34 | ; CHECK-NEXT: Opcode: I32_CONST |
| 33 | ; CHECK-NEXT: Value: 1048 | 35 | ; CHECK-NEXT: Value: 66608 |
| 34 | ; CHECK-NEXT: - Type: I32 | ||
| 35 | ; CHECK-NEXT: Mutable: false | ||
| 36 | ; CHECK-NEXT: InitExpr: | ||
| 37 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 38 | ; CHECK-NEXT: Value: 1052 | ||
| 39 | 36 | ||
| 40 | ; CHECK: - Type: DATA | 37 | ; CHECK: - Type: DATA |
| 41 | ; CHECK-NEXT: Relocations: | ||
| 42 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 | ||
| 43 | ; CHECK-NEXT: Index: 4 | ||
| 44 | ; CHECK-NEXT: Offset: 0x0000001F | ||
| 45 | ; CHECK-NEXT: Segments: | 38 | ; CHECK-NEXT: Segments: |
| 46 | ; CHECK-NEXT: - SectionOffset: 7 | 39 | ; CHECK-NEXT: - SectionOffset: 7 |
| 47 | ; CHECK-NEXT: MemoryIndex: 0 | 40 | ; CHECK-NEXT: MemoryIndex: 0 |
| 48 | ; CHECK-NEXT: Offset: | 41 | ; CHECK-NEXT: Offset: |
| 49 | ; CHECK-NEXT: Opcode: I32_CONST | 42 | ; CHECK-NEXT: Opcode: I32_CONST |
| 50 | ; CHECK-NEXT: Value: 1024 | 43 | ; CHECK-NEXT: Value: 1024 |
| 51 | ; CHECK-NEXT: Content: 0100000000000000000000000000000003000000000000001C040000 | 44 | ; CHECK-NEXT: Content: '0100000000000000000000000000000003000000000000002804000024040000' |
| 52 | ; CHECK-NEXT: - SectionOffset: 41 | 45 | ; CHECK-NEXT: - SectionOffset: 45 |
| 53 | ; CHECK-NEXT: MemoryIndex: 0 | 46 | ; CHECK-NEXT: MemoryIndex: 0 |
| 54 | ; CHECK-NEXT: Offset: | 47 | ; CHECK-NEXT: Offset: |
| 55 | ; CHECK-NEXT: Opcode: I32_CONST | 48 | ; CHECK-NEXT: Opcode: I32_CONST |
| 56 | ; CHECK-NEXT: Value: 1052 | 49 | ; CHECK-NEXT: Value: 1056 |
| 50 | ; CHECK-NEXT: Content: '0000000000000000' | ||
| 51 | ; CHECK-NEXT: - SectionOffset: 59 | ||
| 52 | ; CHECK-NEXT: MemoryIndex: 0 | ||
| 53 | ; CHECK-NEXT: Offset: | ||
| 54 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 55 | ; CHECK-NEXT: Value: 1064 | ||
| 57 | ; CHECK-NEXT: Content: 68656C6C6F0A00 | 56 | ; CHECK-NEXT: Content: 68656C6C6F0A00 |
| 57 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 58 | |||
| 59 | |||
| 60 | ; RUN: wasm-ld -no-gc-sections --allow-undefined --no-entry \ | ||
| 61 | ; RUN: --initial-memory=131072 --max-memory=131072 -o %t_max.wasm %t.o \ | ||
| 62 | ; RUN: %t.hello.o | ||
| 63 | ; RUN: obj2yaml %t_max.wasm | FileCheck %s -check-prefix=CHECK-MAX | ||
| 64 | |||
| 65 | ; CHECK-MAX: - Type: MEMORY | ||
| 66 | ; CHECK-MAX-NEXT: Memories: | ||
| 67 | ; CHECK-MAX-NEXT: - Flags: [ HAS_MAX ] | ||
| 68 | ; CHECK-MAX-NEXT: Initial: 0x00000002 | ||
| 69 | ; CHECK-MAX-NEXT: Maximum: 0x00000002 | ||
| 70 | |||
| 71 | |||
| 72 | ; RUN: wasm-ld --relocatable -o %t_reloc.wasm %t.o %t.hello.o | ||
| 73 | ; RUN: obj2yaml %t_reloc.wasm | FileCheck %s -check-prefix=RELOC | ||
| 74 | |||
| 75 | ; RELOC: - Type: DATA | ||
| 76 | ; RELOC-NEXT: Relocations: | ||
| 77 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 | ||
| 78 | ; RELOC-NEXT: Index: 6 | ||
| 79 | ; RELOC-NEXT: Offset: 0x00000018 | ||
| 80 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 | ||
| 81 | ; RELOC-NEXT: Index: 3 | ||
| 82 | ; RELOC-NEXT: Offset: 0x0000002E | ||
| 83 | ; RELOC-NEXT: Addend: 4 | ||
| 84 | ; RELOC-NEXT: Segments: | ||
| 85 | ; RELOC-NEXT: - SectionOffset: 6 | ||
| 86 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 87 | ; RELOC-NEXT: Offset: | ||
| 88 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 89 | ; RELOC-NEXT: Value: 0 | ||
| 90 | ; RELOC-NEXT: Content: '01000000' | ||
| 91 | ; RELOC-NEXT: - SectionOffset: 15 | ||
| 92 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 93 | ; RELOC-NEXT: Offset: | ||
| 94 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 95 | ; RELOC-NEXT: Value: 16 | ||
| 96 | ; RELOC-NEXT: Content: '03000000' | ||
| 97 | ; RELOC-NEXT: - SectionOffset: 24 | ||
| 98 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 99 | ; RELOC-NEXT: Offset: | ||
| 100 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 101 | ; RELOC-NEXT: Value: 24 | ||
| 102 | ; RELOC-NEXT: Content: '28000000' | ||
| 103 | ; RELOC-NEXT: - SectionOffset: 33 | ||
| 104 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 105 | ; RELOC-NEXT: Offset: | ||
| 106 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 107 | ; RELOC-NEXT: Value: 28 | ||
| 108 | ; RELOC-NEXT: Content: '0000000000000000' | ||
| 109 | ; RELOC-NEXT: - SectionOffset: 46 | ||
| 110 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 111 | ; RELOC-NEXT: Offset: | ||
| 112 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 113 | ; RELOC-NEXT: Value: 36 | ||
| 114 | ; RELOC-NEXT: Content: '20000000' | ||
| 115 | ; RELOC-NEXT: - SectionOffset: 55 | ||
| 116 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 117 | ; RELOC-NEXT: Offset: | ||
| 118 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 119 | ; RELOC-NEXT: Value: 40 | ||
| 120 | ; RELOC-NEXT: Content: 68656C6C6F0A00 | ||
| 58 | 121 | ||
| 59 | ; CHECK: - Type: CUSTOM | 122 | ; RELOC: SymbolTable: |
| 60 | ; CHECK-NEXT: Name: linking | 123 | ; RELOC-NEXT: - Index: 0 |
| 61 | ; CHECK-NEXT: DataSize: 35 | 124 | ; RELOC-NEXT: Kind: DATA |
| 125 | ; RELOC-NEXT: Name: foo | ||
| 126 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 127 | ; RELOC-NEXT: Segment: 0 | ||
| 128 | ; RELOC-NEXT: Size: 4 | ||
| 129 | ; RELOC-NEXT: - Index: 1 | ||
| 130 | ; RELOC-NEXT: Kind: DATA | ||
| 131 | ; RELOC-NEXT: Name: aligned_bar | ||
| 132 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 133 | ; RELOC-NEXT: Segment: 1 | ||
| 134 | ; RELOC-NEXT: Size: 4 | ||
| 135 | ; RELOC-NEXT: - Index: 2 | ||
| 136 | ; RELOC-NEXT: Kind: DATA | ||
| 137 | ; RELOC-NEXT: Name: external_ref | ||
| 138 | ; RELOC-NEXT: Flags: [ ] | ||
| 139 | ; RELOC-NEXT: Segment: 2 | ||
| 140 | ; RELOC-NEXT: Size: 4 | ||
| 141 | ; RELOC: - Index: 6 | ||
| 142 | ; RELOC-NEXT: Kind: DATA | ||
| 143 | ; RELOC-NEXT: Name: hello_str | ||
| 144 | ; RELOC-NEXT: Flags: [ ] | ||
| 145 | ; RELOC-NEXT: Segment: 5 | ||
| 146 | ; RELOC-NEXT: Size: 7 |
deps/lld/test/wasm/data-segment-merging.ll created+48| ... | @@ -0,0 +1,48 @@ | ||
| 1 | target triple = "wasm32-unknown-unknown" | ||
| 2 | |||
| 3 | @a = hidden global [6 x i8] c"hello\00", align 1 | ||
| 4 | @b = hidden global [8 x i8] c"goodbye\00", align 1 | ||
| 5 | @c = hidden global [9 x i8] c"whatever\00", align 1 | ||
| 6 | @d = hidden global i32 42, align 4 | ||
| 7 | |||
| 8 | ; RUN: llc -filetype=obj %s -o %t.data-segment-merging.o | ||
| 9 | |||
| 10 | ; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.data-segment-merging.o | ||
| 11 | ; RUN: obj2yaml %t.merged.wasm | FileCheck %s --check-prefix=MERGE | ||
| 12 | ; MERGE: - Type: DATA | ||
| 13 | ; MERGE-NEXT: Segments: | ||
| 14 | ; MERGE-NEXT: - SectionOffset: 7 | ||
| 15 | ; MERGE-NEXT: MemoryIndex: 0 | ||
| 16 | ; MERGE-NEXT: Offset: | ||
| 17 | ; MERGE-NEXT: Opcode: I32_CONST | ||
| 18 | ; MERGE-NEXT: Value: 1024 | ||
| 19 | ; MERGE-NEXT: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000 | ||
| 20 | |||
| 21 | ; RUN: wasm-ld -no-gc-sections --no-entry --no-merge-data-segments -o %t.separate.wasm %t.data-segment-merging.o | ||
| 22 | ; RUN: obj2yaml %t.separate.wasm | FileCheck %s --check-prefix=SEPARATE | ||
| 23 | ; SEPARATE: - Type: DATA | ||
| 24 | ; SEPARATE-NEXT: Segments: | ||
| 25 | ; SEPARATE-NEXT: - SectionOffset: 7 | ||
| 26 | ; SEPARATE-NEXT: MemoryIndex: 0 | ||
| 27 | ; SEPARATE-NEXT: Offset: | ||
| 28 | ; SEPARATE-NEXT: Opcode: I32_CONST | ||
| 29 | ; SEPARATE-NEXT: Value: 1024 | ||
| 30 | ; SEPARATE-NEXT: Content: 68656C6C6F00 | ||
| 31 | ; SEPARATE-NEXT: - SectionOffset: 19 | ||
| 32 | ; SEPARATE-NEXT: MemoryIndex: 0 | ||
| 33 | ; SEPARATE-NEXT: Offset: | ||
| 34 | ; SEPARATE-NEXT: Opcode: I32_CONST | ||
| 35 | ; SEPARATE-NEXT: Value: 1030 | ||
| 36 | ; SEPARATE-NEXT: Content: 676F6F6462796500 | ||
| 37 | ; SEPARATE-NEXT: - SectionOffset: 33 | ||
| 38 | ; SEPARATE-NEXT: MemoryIndex: 0 | ||
| 39 | ; SEPARATE-NEXT: Offset: | ||
| 40 | ; SEPARATE-NEXT: Opcode: I32_CONST | ||
| 41 | ; SEPARATE-NEXT: Value: 1038 | ||
| 42 | ; SEPARATE-NEXT: Content: '776861746576657200' | ||
| 43 | ; SEPARATE-NEXT: - SectionOffset: 48 | ||
| 44 | ; SEPARATE-NEXT: MemoryIndex: 0 | ||
| 45 | ; SEPARATE-NEXT: Offset: | ||
| 46 | ; SEPARATE-NEXT: Opcode: I32_CONST | ||
| 47 | ; SEPARATE-NEXT: Value: 1048 | ||
| 48 | ; SEPARATE-NEXT: Content: 2A000000 | ||
deps/lld/test/wasm/debuginfo.test created+85| ... | @@ -0,0 +1,85 @@ | ||
| 1 | RUN: llc -filetype=obj %p/Inputs/debuginfo1.ll -o %t.debuginfo1.o | ||
| 2 | RUN: llc -filetype=obj %p/Inputs/debuginfo2.ll -o %t.debuginfo2.o | ||
| 3 | RUN: wasm-ld -o %t.wasm %t.debuginfo1.o %t.debuginfo2.o | ||
| 4 | RUN: llvm-dwarfdump %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | CHECK: file format WASM | ||
| 7 | |||
| 8 | CHECK: .debug_info contents: | ||
| 9 | CHECK: DW_TAG_compile_unit | ||
| 10 | CHECK-NEXT: DW_AT_producer	("clang version 7.0.0 (trunk {{.*}})") | ||
| 11 | CHECK-NEXT: DW_AT_language	(DW_LANG_C99) | ||
| 12 | CHECK-NEXT: DW_AT_name	("hi.c") | ||
| 13 | |||
| 14 | CHECK: DW_TAG_subprogram | ||
| 15 | CHECK-NEXT: DW_AT_low_pc | ||
| 16 | CHECK-NEXT: DW_AT_high_pc | ||
| 17 | CHECK-NEXT: DW_AT_name	("test") | ||
| 18 | CHECK-NEXT: DW_AT_decl_file	("/Users/yury/llvmwasm{{(/|\\)}}hi.c") | ||
| 19 | CHECK-NEXT: DW_AT_decl_line	(3) | ||
| 20 | CHECK-NEXT: DW_AT_prototyped	(true) | ||
| 21 | |||
| 22 | CHECK: DW_TAG_formal_parameter | ||
| 23 | CHECK-NEXT: DW_AT_name	("t") | ||
| 24 | CHECK-NEXT: DW_AT_decl_file	("/Users/yury/llvmwasm{{(/|\\)}}hi.c") | ||
| 25 | CHECK-NEXT: DW_AT_decl_line	(3) | ||
| 26 | |||
| 27 | CHECK: DW_TAG_subprogram | ||
| 28 | CHECK-NEXT: DW_AT_low_pc | ||
| 29 | CHECK-NEXT: DW_AT_high_pc | ||
| 30 | CHECK-NEXT: DW_AT_name	("_start") | ||
| 31 | CHECK-NEXT: DW_AT_decl_file	("/Users/yury/llvmwasm{{(/|\\)}}hi.c") | ||
| 32 | CHECK-NEXT: DW_AT_decl_line	(7) | ||
| 33 | |||
| 34 | CHECK: DW_TAG_base_type | ||
| 35 | CHECK-NEXT: DW_AT_name	("int") | ||
| 36 | CHECK-NEXT: DW_AT_encoding	(DW_ATE_signed) | ||
| 37 | CHECK-NEXT: DW_AT_byte_size	(0x04) | ||
| 38 | |||
| 39 | CHECK: DW_TAG_compile_unit | ||
| 40 | CHECK-NEXT: DW_AT_producer	("clang version 7.0.0 (trunk {{.*}})") | ||
| 41 | CHECK-NEXT: DW_AT_language	(DW_LANG_C99) | ||
| 42 | CHECK-NEXT: DW_AT_name	("hi_foo.c") | ||
| 43 | |||
| 44 | CHECK: DW_TAG_variable | ||
| 45 | CHECK-NEXT: DW_AT_name	("y") | ||
| 46 | CHECK-NEXT: DW_AT_type	(0x00000097 "int[]") | ||
| 47 | CHECK-NEXT: DW_AT_external	(true) | ||
| 48 | CHECK-NEXT: DW_AT_decl_file	("{{.*}}hi_foo.c") | ||
| 49 | CHECK-NEXT: DW_AT_decl_line	(1) | ||
| 50 | CHECK: DW_AT_location	(DW_OP_addr 0x400) | ||
| 51 | |||
| 52 | CHECK: DW_TAG_array_type | ||
| 53 | |||
| 54 | CHECK: DW_TAG_subrange_type | ||
| 55 | |||
| 56 | CHECK: DW_TAG_base_type | ||
| 57 | CHECK-NEXT: DW_AT_name	("int") | ||
| 58 | CHECK-NEXT: DW_AT_encoding	(DW_ATE_signed) | ||
| 59 | CHECK-NEXT: DW_AT_byte_size	(0x04) | ||
| 60 | |||
| 61 | CHECK: DW_TAG_base_type | ||
| 62 | CHECK-NEXT: DW_AT_name	("__ARRAY_SIZE_TYPE__") | ||
| 63 | CHECK-NEXT: DW_AT_byte_size	(0x08) | ||
| 64 | CHECK-NEXT: DW_AT_encoding	(DW_ATE_unsigned) | ||
| 65 | |||
| 66 | CHECK: DW_TAG_variable | ||
| 67 | CHECK-NEXT: DW_AT_name	("z") | ||
| 68 | CHECK-NEXT: DW_AT_type	(0x00000097 "int[]") | ||
| 69 | CHECK-NEXT: DW_AT_external	(true) | ||
| 70 | CHECK-NEXT: DW_AT_decl_file	("{{.*}}hi_foo.c") | ||
| 71 | CHECK-NEXT: DW_AT_decl_line	(8) | ||
| 72 | CHECK-NEXT: DW_AT_location	(DW_OP_addr 0x0) | ||
| 73 | |||
| 74 | CHECK: DW_TAG_subprogram | ||
| 75 | CHECK-NEXT: DW_AT_low_pc	 | ||
| 76 | CHECK-NEXT: DW_AT_high_pc | ||
| 77 | CHECK-NEXT: DW_AT_name	("foo") | ||
| 78 | CHECK-NEXT: DW_AT_decl_file	("{{.*}}hi_foo.c") | ||
| 79 | CHECK-NEXT: DW_AT_decl_line	(3) | ||
| 80 | |||
| 81 | CHECK: DW_TAG_formal_parameter | ||
| 82 | CHECK-NEXT: DW_AT_name	("p") | ||
| 83 | CHECK-NEXT: DW_AT_decl_file	("{{.*}}hi_foo.c") | ||
| 84 | CHECK-NEXT: DW_AT_decl_line	(3) | ||
| 85 | |||
deps/lld/test/wasm/demangle.ll created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 2 | ; RUN: not wasm-ld --undefined _Z3fooi \ | ||
| 3 | ; RUN: -o %t.wasm %t.o 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | ; CHECK: error: undefined symbol: foo(int) | ||
| 6 | |||
| 7 | ; RUN: not wasm-ld --no-demangle --undefined _Z3fooi \ | ||
| 8 | ; RUN: -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-NODEMANGLE %s | ||
| 9 | |||
| 10 | ; CHECK-NODEMANGLE: error: undefined symbol: _Z3fooi | ||
| 11 | |||
| 12 | target triple = "wasm32-unknown-unknown" | ||
| 13 | |||
| 14 | define hidden void @_start() local_unnamed_addr { | ||
| 15 | entry: | ||
| 16 | ret void | ||
| 17 | } | ||
deps/lld/test/wasm/driver.ll created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 2 | |||
| 3 | target triple = "wasm32-unknown-unknown" | ||
| 4 | |||
| 5 | define hidden void @entry() local_unnamed_addr #0 { | ||
| 6 | entry: | ||
| 7 | ret void | ||
| 8 | } | ||
| 9 | |||
| 10 | ; RUN: not wasm-ld -o %t.exe 2>&1 | FileCheck -check-prefix=IN %s | ||
| 11 | ; IN: error: no input files | ||
| 12 | |||
| 13 | ; RUN: not wasm-ld %t.o 2>&1 | FileCheck -check-prefix=OUT %s | ||
| 14 | ; OUT: error: no output file specified | ||
| 15 | |||
| 16 | ; RUN: not wasm-ld 2>&1 | FileCheck -check-prefix=BOTH %s | ||
| 17 | ; BOTH: error: no input files | ||
| 18 | ; BOTH-NOT: error: no output file specified | ||
| 19 | |||
| 20 | ; RUN: not wasm-ld --export-table --import-table %t.o 2>&1 \ | ||
| 21 | ; RUN: | FileCheck -check-prefix=TABLE %s | ||
| 22 | ; TABLE: error: --import-table and --export-table may not be used together | ||
deps/lld/test/wasm/entry-signature.ll created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | ; Verify that the entry point signauture can be flexible. | ||
| 2 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 3 | ; RUN: wasm-ld -o %t1.wasm %t.o | ||
| 4 | |||
| 5 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 6 | |||
| 7 | define hidden i32 @_start(i32, i64) local_unnamed_addr #0 { | ||
| 8 | entry: | ||
| 9 | ret i32 0 | ||
| 10 | } | ||
deps/lld/test/wasm/entry.ll+45-14| ... | @@ -1,19 +1,50 @@ | ... | @@ -1,19 +1,50 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 1 | ; RUN: llc -filetype=obj %s -o %t.o |
| 2 | ; RUN: lld -flavor wasm -e entry -o %t.wasm %t.o | ||
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 4 | ; RUN: lld -flavor wasm --entry=entry -o %t.wasm %t.o | ||
| 5 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 6 | 2 | ||
| 7 | define void @entry() local_unnamed_addr #0 { | 3 | target triple = "wasm32-unknown-unknown" |
| 4 | |||
| 5 | define hidden void @entry() local_unnamed_addr #0 { | ||
| 8 | entry: | 6 | entry: |
| 9 | ret void | 7 | ret void |
| 10 | } | 8 | } |
| 11 | 9 | ||
| 12 | ; CHECK: - Type: EXPORT | 10 | ; RUN: wasm-ld -e entry -o %t1.wasm %t.o |
| 13 | ; CHECK: Exports: | 11 | ; RUN: obj2yaml %t1.wasm | FileCheck %s |
| 14 | ; CHECK: - Name: memory | 12 | ; RUN: wasm-ld --entry=entry -o %t2.wasm %t.o |
| 15 | ; CHECK: Kind: MEMORY | 13 | ; RUN: obj2yaml %t2.wasm | FileCheck %s |
| 16 | ; CHECK: Index: 0 | 14 | |
| 17 | ; CHECK: - Name: entry | 15 | ; CHECK: - Type: EXPORT |
| 18 | ; CHECK: Kind: FUNCTION | 16 | ; CHECK-NEXT: Exports: |
| 19 | ; CHECK: Index: 0 | 17 | ; CHECK-NEXT: - Name: memory |
| 18 | ; CHECK-NEXT: Kind: MEMORY | ||
| 19 | ; 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 | ||
| 26 | ; CHECK-NEXT: - Name: entry | ||
| 27 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 28 | ; CHECK-NEXT: Index: 1 | ||
| 29 | ; CHECK-NEXT: - Type: | ||
| 30 | |||
| 31 | ; The __wasm_call_ctors is somewhat special since its created by the linker. | ||
| 32 | ; Make sure we can use it as the entry point if we choose | ||
| 33 | ; RUN: wasm-ld --entry=__wasm_call_ctors -o %t3.wasm %t.o | ||
| 34 | ; RUN: obj2yaml %t3.wasm | FileCheck %s -check-prefix=CHECK-CTOR | ||
| 35 | |||
| 36 | ; CHECK-CTOR: - Type: EXPORT | ||
| 37 | ; CHECK-CTOR-NEXT: Exports: | ||
| 38 | ; CHECK-CTOR-NEXT: - Name: memory | ||
| 39 | ; CHECK-CTOR-NEXT: Kind: MEMORY | ||
| 40 | ; CHECK-CTOR-NEXT: Index: 0 | ||
| 41 | ; CHECK-CTOR-NEXT: - Name: __wasm_call_ctors | ||
| 42 | ; CHECK-CTOR-NEXT: Kind: FUNCTION | ||
| 43 | ; 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 | ||
| 50 | ; CHECK-CTOR-NEXT: - Type: |
deps/lld/test/wasm/export-all.ll created+48| ... | @@ -0,0 +1,48 @@ | ||
| 1 | ; RUN: llc -O0 -filetype=obj %s -o %t.o | ||
| 2 | |||
| 3 | ; RUN: wasm-ld -o %t.wasm %t.o | ||
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | ; RUN: wasm-ld --export-all -o %t.wasm %t.o | ||
| 7 | ; RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=EXPORT | ||
| 8 | |||
| 9 | ; RUN: wasm-ld --export-all --no-gc-sections -o %t.wasm %t.o | ||
| 10 | ; RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=EXPORT | ||
| 11 | |||
| 12 | ; Verify the --export-all flag exports hidden symbols | ||
| 13 | |||
| 14 | target triple = "wasm32-unknown-unknown" | ||
| 15 | |||
| 16 | define internal void @internal_func() local_unnamed_addr { | ||
| 17 | entry: | ||
| 18 | ret void | ||
| 19 | } | ||
| 20 | |||
| 21 | define hidden void @bar() local_unnamed_addr { | ||
| 22 | entry: | ||
| 23 | ret void | ||
| 24 | } | ||
| 25 | |||
| 26 | define hidden void @foo() local_unnamed_addr { | ||
| 27 | entry: | ||
| 28 | ret void | ||
| 29 | } | ||
| 30 | |||
| 31 | define hidden void @_start() local_unnamed_addr { | ||
| 32 | entry: | ||
| 33 | call void @foo() | ||
| 34 | call void @internal_func() | ||
| 35 | ret void | ||
| 36 | } | ||
| 37 | |||
| 38 | ; CHECK: - Type: EXPORT | ||
| 39 | ; CHECK: - Name: _start | ||
| 40 | ; CHECK-NOT: - Name: bar | ||
| 41 | ; CHECK-NOT: - Name: foo | ||
| 42 | ; CHECK-NOT: - Name: internal_func | ||
| 43 | |||
| 44 | ; EXPORT: - Type: EXPORT | ||
| 45 | ; EXPORT: - Name: _start | ||
| 46 | ; EXPORT: - Name: bar | ||
| 47 | ; EXPORT: - Name: foo | ||
| 48 | ; EXPORT-NOT: - Name: internal_func | ||
deps/lld/test/wasm/export-table.test created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | # RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o | ||
| 2 | # RUN: wasm-ld --export-table -o %t.wasm %t.start.o | ||
| 3 | # RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 4 | |||
| 5 | # Verify the --export-table flag creates a table export | ||
| 6 | |||
| 7 | # CHECK: - Type: TABLE | ||
| 8 | # CHECK-NEXT: Tables: | ||
| 9 | # CHECK-NEXT: - ElemType: ANYFUNC | ||
| 10 | # CHECK-NEXT: Limits: | ||
| 11 | # CHECK-NEXT: Flags: [ HAS_MAX ] | ||
| 12 | # CHECK-NEXT: Initial: 0x00000001 | ||
| 13 | # CHECK-NEXT: Maximum: 0x00000001 | ||
| 14 | # CHECK-NEXT: - Type: | ||
| 15 | # CHECK: - Type: EXPORT | ||
| 16 | # CHECK-NEXT: Exports: | ||
| 17 | # CHECK: - Name: __indirect_function_table | ||
| 18 | # CHECK-NEXT: Kind: TABLE | ||
| 19 | # CHECK-NEXT: Index: 0 | ||
deps/lld/test/wasm/export.ll created+37| ... | @@ -0,0 +1,37 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 2 | ; RUN: not wasm-ld --export=missing -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s | ||
| 3 | ; RUN: wasm-ld --export=hidden_function -o %t.wasm %t.o | ||
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | target triple = "wasm32-unknown-unknown" | ||
| 7 | |||
| 8 | define hidden i32 @hidden_function() local_unnamed_addr { | ||
| 9 | entry: | ||
| 10 | ret i32 0 | ||
| 11 | } | ||
| 12 | |||
| 13 | define void @_start() local_unnamed_addr { | ||
| 14 | entry: | ||
| 15 | ret void | ||
| 16 | } | ||
| 17 | |||
| 18 | ; CHECK-ERROR: error: symbol exported via --export not found: missing | ||
| 19 | |||
| 20 | ; CHECK: - Type: EXPORT | ||
| 21 | ; CHECK-NEXT: Exports: | ||
| 22 | ; CHECK-NEXT: - Name: memory | ||
| 23 | ; CHECK-NEXT: Kind: MEMORY | ||
| 24 | ; 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 | ||
| 31 | ; CHECK-NEXT: - Name: _start | ||
| 32 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 33 | ; CHECK-NEXT: Index: 2 | ||
| 34 | ; CHECK-NEXT: - Name: hidden_function | ||
| 35 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 36 | ; CHECK-NEXT: Index: 1 | ||
| 37 | ; CHECK-NEXT: - Type: CODE | ||
deps/lld/test/wasm/fatal-warnings.ll created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.main.o | ||
| 2 | ; 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 | ||
| 5 | |||
| 6 | ; CHECK-WARN: warning: function signature mismatch: ret32 | ||
| 7 | ; CHECK-FATAL: error: function signature mismatch: ret32 | ||
| 8 | |||
| 9 | target triple = "wasm32-unknown-unknown" | ||
| 10 | |||
| 11 | define hidden void @_start() local_unnamed_addr #0 { | ||
| 12 | entry: | ||
| 13 | %call = tail call i32 @ret32(i32 1, i64 2, i32 3) #2 | ||
| 14 | ret void | ||
| 15 | } | ||
| 16 | |||
| 17 | declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1 | ||
deps/lld/test/wasm/function-imports-first.ll+17-11| ... | @@ -1,8 +1,10 @@ | ... | @@ -1,8 +1,10 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 2 | ; RUN: llc -filetype=obj %s -o %t.o |
| 3 | ; RUN: lld -flavor wasm -o %t.wasm %t.o %t.ret32.o | 3 | ; RUN: wasm-ld -o %t.wasm %t.o %t.ret32.o |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 5 | 5 | ||
| 6 | target triple = "wasm32-unknown-unknown" | ||
| 7 | |||
| 6 | ; Function Attrs: nounwind | 8 | ; Function Attrs: nounwind |
| 7 | define hidden void @_start() local_unnamed_addr #0 { | 9 | define hidden void @_start() local_unnamed_addr #0 { |
| 8 | entry: | 10 | entry: |
| ... | @@ -22,21 +24,25 @@ declare i32 @ret32(float) local_unnamed_addr #1 | ... | @@ -22,21 +24,25 @@ declare i32 @ret32(float) local_unnamed_addr #1 |
| 22 | ; CHECK-NEXT: ParamTypes: | 24 | ; CHECK-NEXT: ParamTypes: |
| 23 | ; CHECK-NEXT: - F32 | 25 | ; CHECK-NEXT: - F32 |
| 24 | ; CHECK: - Type: FUNCTION | 26 | ; CHECK: - Type: FUNCTION |
| 25 | ; CHECK-NEXT: FunctionTypes: [ 0, 1 ] | 27 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 1 ] |
| 26 | ; CHECK: - Type: CODE | 28 | ; CHECK: - Type: CODE |
| 27 | ; CHECK-NEXT: Functions: | 29 | ; CHECK-NEXT: Functions: |
| 28 | ; CHECK-NEXT: - Locals: | 30 | ; CHECK-NEXT: - Index: 0 |
| 29 | ; CHECK-NEXT: Body: 43000000001081808080001A0B | 31 | ; CHECK-NEXT: Locals: |
| 30 | ; CHECK-NEXT: - Locals: | 32 | ; CHECK-NEXT: Body: 0B |
| 33 | ; CHECK-NEXT: - Index: 1 | ||
| 34 | ; CHECK-NEXT: Locals: | ||
| 35 | ; CHECK-NEXT: Body: 43000000001082808080001A0B | ||
| 36 | ; CHECK-NEXT: - Index: 2 | ||
| 37 | ; CHECK-NEXT: Locals: | ||
| 31 | ; CHECK-NEXT: Body: 41000B | 38 | ; CHECK-NEXT: Body: 41000B |
| 32 | ; CHECK-NEXT: - Type: CUSTOM | 39 | ; CHECK-NEXT: - Type: CUSTOM |
| 33 | ; CHECK-NEXT: Name: linking | ||
| 34 | ; CHECK-NEXT: DataSize: 0 | ||
| 35 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 36 | ; CHECK-NEXT: Name: name | 40 | ; CHECK-NEXT: Name: name |
| 37 | ; CHECK-NEXT: FunctionNames: | 41 | ; CHECK-NEXT: FunctionNames: |
| 38 | ; CHECK-NEXT: - Index: 0 | 42 | ; CHECK-NEXT: - Index: 0 |
| 39 | ; CHECK-NEXT: Name: _start | 43 | ; CHECK-NEXT: Name: __wasm_call_ctors |
| 40 | ; CHECK-NEXT: - Index: 1 | 44 | ; CHECK-NEXT: - Index: 1 |
| 45 | ; CHECK-NEXT: Name: _start | ||
| 46 | ; CHECK-NEXT: - Index: 2 | ||
| 41 | ; CHECK-NEXT: Name: ret32 | 47 | ; CHECK-NEXT: Name: ret32 |
| 42 | ; CHECK-NEXT: ... | 48 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/function-imports.ll+15-10| ... | @@ -1,8 +1,10 @@ | ... | @@ -1,8 +1,10 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 2 | ; RUN: llc -filetype=obj %s -o %t.o |
| 3 | ; RUN: lld -flavor wasm -o %t.wasm %t.ret32.o %t.o | 3 | ; RUN: wasm-ld -o %t.wasm %t.ret32.o %t.o |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 5 | 5 | ||
| 6 | target triple = "wasm32-unknown-unknown" | ||
| 7 | |||
| 6 | ; Function Attrs: nounwind | 8 | ; Function Attrs: nounwind |
| 7 | define hidden void @_start() local_unnamed_addr #0 { | 9 | define hidden void @_start() local_unnamed_addr #0 { |
| 8 | entry: | 10 | entry: |
| ... | @@ -16,22 +18,25 @@ declare i32 @ret32(float) local_unnamed_addr #1 | ... | @@ -16,22 +18,25 @@ declare i32 @ret32(float) local_unnamed_addr #1 |
| 16 | ; CHECK: - Type: TYPE | 18 | ; CHECK: - Type: TYPE |
| 17 | ; CHECK-NEXT: Signatures: | 19 | ; CHECK-NEXT: Signatures: |
| 18 | ; CHECK-NEXT: - Index: 0 | 20 | ; CHECK-NEXT: - Index: 0 |
| 19 | ; CHECK-NEXT: ReturnType: I32 | 21 | ; CHECK-NEXT: ReturnType: NORESULT |
| 20 | ; CHECK-NEXT: ParamTypes: | 22 | ; CHECK-NEXT: ParamTypes: |
| 21 | ; CHECK-NEXT: - F32 | ||
| 22 | ; CHECK-NEXT: - Index: 1 | 23 | ; CHECK-NEXT: - Index: 1 |
| 23 | ; CHECK-NEXT: ReturnType: NORESULT | 24 | ; CHECK-NEXT: ReturnType: I32 |
| 24 | ; CHECK-NEXT: ParamTypes: | 25 | ; CHECK-NEXT: ParamTypes: |
| 26 | ; CHECK-NEXT: - F32 | ||
| 25 | ; CHECK-NEXT: - Type: FUNCTION | 27 | ; CHECK-NEXT: - Type: FUNCTION |
| 26 | ; CHECK-NEXT: FunctionTypes: [ 0, 1 ] | 28 | ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0 ] |
| 27 | ; CHECK: - Type: CODE | 29 | ; CHECK: - Type: CODE |
| 28 | ; CHECK-NEXT: Functions: | 30 | ; CHECK-NEXT: Functions: |
| 29 | ; CHECK: - Locals: | 31 | ; CHECK: - Index: 0 |
| 30 | ; CHECK: - Locals: | 32 | ; CHECK: - Index: 1 |
| 33 | ; CHECK: - Index: 2 | ||
| 31 | ; CHECK: Name: name | 34 | ; CHECK: Name: name |
| 32 | ; CHECK-NEXT: FunctionNames: | 35 | ; CHECK-NEXT: FunctionNames: |
| 33 | ; CHECK-NEXT: - Index: 0 | 36 | ; CHECK-NEXT: - Index: 0 |
| 34 | ; CHECK-NEXT: Name: ret32 | 37 | ; CHECK-NEXT: Name: __wasm_call_ctors |
| 35 | ; CHECK-NEXT: - Index: 1 | 38 | ; CHECK-NEXT: - Index: 1 |
| 39 | ; CHECK-NEXT: Name: ret32 | ||
| 40 | ; CHECK-NEXT: - Index: 2 | ||
| 36 | ; CHECK-NEXT: Name: _start | 41 | ; CHECK-NEXT: Name: _start |
| 37 | ; CHECK-NEXT: ... | 42 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/function-index.test+3-3| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | # RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 1 | # RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o |
| 2 | # RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret64.ll -o %t.ret64.o | 2 | # RUN: llc -filetype=obj %p/Inputs/ret64.ll -o %t.ret64.o |
| 3 | # RUN: lld -flavor wasm -r -o %t.wasm %t.ret32.o %t.ret64.o | 3 | # RUN: wasm-ld -r -o %t.wasm %t.ret32.o %t.ret64.o |
| 4 | # RUN: obj2yaml %t.wasm | FileCheck %s | 4 | # RUN: obj2yaml %t.wasm | FileCheck %s |
| 5 | 5 | ||
| 6 | CHECK: Sections: | 6 | CHECK: Sections: |
deps/lld/test/wasm/gc-imports.ll created+93| ... | @@ -0,0 +1,93 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 2 | ; RUN: yaml2obj %S/Inputs/undefined-globals.yaml -o %t_globals.o | ||
| 3 | ; RUN: wasm-ld --allow-undefined -o %t1.wasm %t.o %t_globals.o | ||
| 4 | |||
| 5 | target triple = "wasm32-unknown-unknown" | ||
| 6 | |||
| 7 | declare i64 @unused_undef_function(i64 %arg) | ||
| 8 | |||
| 9 | declare i32 @used_undef_function() | ||
| 10 | |||
| 11 | declare i64 @use_undef_global() | ||
| 12 | |||
| 13 | define hidden void @foo() { | ||
| 14 | entry: | ||
| 15 | call i64 @unused_undef_function(i64 0) | ||
| 16 | ret void | ||
| 17 | } | ||
| 18 | |||
| 19 | define hidden void @_start() { | ||
| 20 | entry: | ||
| 21 | call i32 @used_undef_function() | ||
| 22 | call i64 @use_undef_global() | ||
| 23 | ret void | ||
| 24 | } | ||
| 25 | |||
| 26 | ; RUN: obj2yaml %t1.wasm | FileCheck %s | ||
| 27 | |||
| 28 | ; CHECK: - Type: IMPORT | ||
| 29 | ; CHECK-NEXT: Imports: | ||
| 30 | ; CHECK-NEXT: - Module: env | ||
| 31 | ; CHECK-NEXT: Field: used_undef_function | ||
| 32 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 33 | ; CHECK-NEXT: SigIndex: 0 | ||
| 34 | ; CHECK-NEXT: - Module: env | ||
| 35 | ; CHECK-NEXT: Field: used_undef_global | ||
| 36 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 37 | ; CHECK-NEXT: GlobalType: I64 | ||
| 38 | ; CHECK-NEXT: GlobalMutable: true | ||
| 39 | ; CHECK-NEXT: - Type: | ||
| 40 | ; CHECK: - Type: CUSTOM | ||
| 41 | ; CHECK-NEXT: Name: name | ||
| 42 | ; CHECK-NEXT: FunctionNames: | ||
| 43 | ; CHECK-NEXT: - Index: 0 | ||
| 44 | ; CHECK-NEXT: Name: used_undef_function | ||
| 45 | ; CHECK-NEXT: - Index: 1 | ||
| 46 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 47 | ; CHECK-NEXT: - Index: 2 | ||
| 48 | ; CHECK-NEXT: Name: _start | ||
| 49 | ; CHECK-NEXT: - Index: 3 | ||
| 50 | ; CHECK-NEXT: Name: use_undef_global | ||
| 51 | ; CHECK-NEXT: ... | ||
| 52 | |||
| 53 | ; RUN: wasm-ld --no-gc-sections --allow-undefined \ | ||
| 54 | ; RUN: -o %t1.no-gc.wasm %t.o %t_globals.o | ||
| 55 | ; RUN: obj2yaml %t1.no-gc.wasm | FileCheck %s -check-prefix=NO-GC | ||
| 56 | |||
| 57 | ; NO-GC: - Type: IMPORT | ||
| 58 | ; NO-GC-NEXT: Imports: | ||
| 59 | ; NO-GC-NEXT: - Module: env | ||
| 60 | ; NO-GC-NEXT: Field: unused_undef_function | ||
| 61 | ; NO-GC-NEXT: Kind: FUNCTION | ||
| 62 | ; NO-GC-NEXT: SigIndex: 0 | ||
| 63 | ; NO-GC-NEXT: - Module: env | ||
| 64 | ; NO-GC-NEXT: Field: used_undef_function | ||
| 65 | ; NO-GC-NEXT: Kind: FUNCTION | ||
| 66 | ; NO-GC-NEXT: SigIndex: 1 | ||
| 67 | ; NO-GC-NEXT: - Module: env | ||
| 68 | ; NO-GC-NEXT: Field: unused_undef_global | ||
| 69 | ; NO-GC-NEXT: Kind: GLOBAL | ||
| 70 | ; NO-GC-NEXT: GlobalType: I64 | ||
| 71 | ; NO-GC-NEXT: GlobalMutable: true | ||
| 72 | ; NO-GC-NEXT: - Module: env | ||
| 73 | ; NO-GC-NEXT: Field: used_undef_global | ||
| 74 | ; NO-GC-NEXT: Kind: GLOBAL | ||
| 75 | ; NO-GC-NEXT: GlobalType: I64 | ||
| 76 | ; NO-GC-NEXT: GlobalMutable: true | ||
| 77 | ; NO-GC-NEXT: - Type: | ||
| 78 | ; NO-GC: - Type: CUSTOM | ||
| 79 | ; NO-GC-NEXT: Name: name | ||
| 80 | ; NO-GC-NEXT: FunctionNames: | ||
| 81 | ; NO-GC-NEXT: - Index: 0 | ||
| 82 | ; NO-GC-NEXT: Name: unused_undef_function | ||
| 83 | ; NO-GC-NEXT: - Index: 1 | ||
| 84 | ; NO-GC-NEXT: Name: used_undef_function | ||
| 85 | ; NO-GC-NEXT: - Index: 2 | ||
| 86 | ; NO-GC-NEXT: Name: __wasm_call_ctors | ||
| 87 | ; NO-GC-NEXT: - Index: 3 | ||
| 88 | ; NO-GC-NEXT: Name: foo | ||
| 89 | ; NO-GC-NEXT: - Index: 4 | ||
| 90 | ; NO-GC-NEXT: Name: _start | ||
| 91 | ; NO-GC-NEXT: - Index: 5 | ||
| 92 | ; NO-GC-NEXT: Name: use_undef_global | ||
| 93 | ; NO-GC-NEXT: ... | ||
deps/lld/test/wasm/gc-sections.ll created+153| ... | @@ -0,0 +1,153 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 2 | ; RUN: yaml2obj %S/Inputs/globals.yaml -o %t_globals.o | ||
| 3 | ; RUN: wasm-ld -print-gc-sections -o %t1.wasm %t.o %t_globals.o | \ | ||
| 4 | ; RUN: FileCheck %s -check-prefix=PRINT-GC | ||
| 5 | ; PRINT-GC: removing unused section {{.*}}:(unused_function) | ||
| 6 | ; PRINT-GC-NOT: removing unused section {{.*}}:(used_function) | ||
| 7 | ; PRINT-GC: removing unused section {{.*}}:(.data.unused_data) | ||
| 8 | ; PRINT-GC-NOT: removing unused section {{.*}}:(.data.used_data) | ||
| 9 | ; PRINT-GC: removing unused section {{.*}}:(unused_global) | ||
| 10 | ; PRINT-GC-NOT: removing unused section {{.*}}:(used_global) | ||
| 11 | |||
| 12 | target triple = "wasm32-unknown-unknown" | ||
| 13 | |||
| 14 | @unused_data = hidden global i64 1, align 4 | ||
| 15 | @used_data = hidden global i32 2, align 4 | ||
| 16 | |||
| 17 | define hidden i64 @unused_function(i64 %arg) { | ||
| 18 | %1 = load i64, i64* @unused_data, align 4 | ||
| 19 | ret i64 %1 | ||
| 20 | } | ||
| 21 | |||
| 22 | define hidden i32 @used_function() { | ||
| 23 | %1 = load i32, i32* @used_data, align 4 | ||
| 24 | ret i32 %1 | ||
| 25 | } | ||
| 26 | |||
| 27 | declare i64 @use_global() | ||
| 28 | |||
| 29 | define hidden void @_start() { | ||
| 30 | entry: | ||
| 31 | call i32 @used_function() | ||
| 32 | call i64 @use_global() | ||
| 33 | ret void | ||
| 34 | } | ||
| 35 | |||
| 36 | ; RUN: obj2yaml %t1.wasm | FileCheck %s | ||
| 37 | |||
| 38 | ; CHECK: - Type: TYPE | ||
| 39 | ; CHECK-NEXT: Signatures: | ||
| 40 | ; CHECK-NEXT: - Index: 0 | ||
| 41 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 42 | ; CHECK-NEXT: ParamTypes: | ||
| 43 | ; CHECK-NEXT: - Index: 1 | ||
| 44 | ; CHECK-NEXT: ReturnType: I32 | ||
| 45 | ; CHECK-NEXT: ParamTypes: | ||
| 46 | ; CHECK-NEXT: - Index: 2 | ||
| 47 | ; CHECK-NEXT: ReturnType: I64 | ||
| 48 | ; CHECK-NEXT: ParamTypes: | ||
| 49 | ; CHECK-NEXT: - Type: FUNCTION | ||
| 50 | |||
| 51 | ; CHECK: - Type: GLOBAL | ||
| 52 | ; CHECK-NEXT: Globals: | ||
| 53 | ; CHECK-NEXT: - Index: 0 | ||
| 54 | ; CHECK-NEXT: Type: I32 | ||
| 55 | ; CHECK-NEXT: Mutable: true | ||
| 56 | ; CHECK-NEXT: InitExpr: | ||
| 57 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 58 | ; CHECK-NEXT: Value: 66576 | ||
| 59 | ; CHECK-NEXT: - Index: 1 | ||
| 60 | ; CHECK-NEXT: Type: I64 | ||
| 61 | ; CHECK-NEXT: Mutable: true | ||
| 62 | ; CHECK-NEXT: InitExpr: | ||
| 63 | ; CHECK-NEXT: Opcode: I64_CONST | ||
| 64 | ; CHECK-NEXT: Value: 456 | ||
| 65 | |||
| 66 | ; CHECK: - Type: DATA | ||
| 67 | ; CHECK-NEXT: Segments: | ||
| 68 | ; CHECK-NEXT: - SectionOffset: 7 | ||
| 69 | ; CHECK-NEXT: MemoryIndex: 0 | ||
| 70 | ; CHECK-NEXT: Offset: | ||
| 71 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 72 | ; CHECK-NEXT: Value: 1024 | ||
| 73 | ; CHECK-NEXT: Content: '02000000' | ||
| 74 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 75 | ; CHECK-NEXT: Name: name | ||
| 76 | ; CHECK-NEXT: FunctionNames: | ||
| 77 | ; CHECK-NEXT: - Index: 0 | ||
| 78 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 79 | ; CHECK-NEXT: - Index: 1 | ||
| 80 | ; CHECK-NEXT: Name: used_function | ||
| 81 | ; CHECK-NEXT: - Index: 2 | ||
| 82 | ; CHECK-NEXT: Name: _start | ||
| 83 | ; CHECK-NEXT: - Index: 3 | ||
| 84 | ; CHECK-NEXT: Name: use_global | ||
| 85 | ; CHECK-NEXT: ... | ||
| 86 | |||
| 87 | ; RUN: wasm-ld -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm \ | ||
| 88 | ; RUN: %t.o %t_globals.o | ||
| 89 | ; RUN: obj2yaml %t1.no-gc.wasm | FileCheck %s -check-prefix=NO-GC | ||
| 90 | |||
| 91 | ; NO-GC: - Type: TYPE | ||
| 92 | ; NO-GC-NEXT: Signatures: | ||
| 93 | ; NO-GC-NEXT: - Index: 0 | ||
| 94 | ; NO-GC-NEXT: ReturnType: NORESULT | ||
| 95 | ; NO-GC-NEXT: ParamTypes: | ||
| 96 | ; NO-GC-NEXT: - Index: 1 | ||
| 97 | ; NO-GC-NEXT: ReturnType: I64 | ||
| 98 | ; NO-GC-NEXT: ParamTypes: | ||
| 99 | ; NO-GC-NEXT: - I64 | ||
| 100 | ; NO-GC-NEXT: - Index: 2 | ||
| 101 | ; NO-GC-NEXT: ReturnType: I32 | ||
| 102 | ; NO-GC-NEXT: ParamTypes: | ||
| 103 | ; NO-GC-NEXT: - Index: 3 | ||
| 104 | ; NO-GC-NEXT: ReturnType: I64 | ||
| 105 | ; NO-GC-NEXT: ParamTypes: | ||
| 106 | ; NO-GC-NEXT: - Type: FUNCTION | ||
| 107 | |||
| 108 | ; NO-GC: - Type: GLOBAL | ||
| 109 | ; NO-GC-NEXT: Globals: | ||
| 110 | ; NO-GC-NEXT: - Index: 0 | ||
| 111 | ; NO-GC-NEXT: Type: I32 | ||
| 112 | ; NO-GC-NEXT: Mutable: true | ||
| 113 | ; NO-GC-NEXT: InitExpr: | ||
| 114 | ; NO-GC-NEXT: Opcode: I32_CONST | ||
| 115 | ; NO-GC-NEXT: Value: 66576 | ||
| 116 | ; NO-GC-NEXT: - Index: 1 | ||
| 117 | ; NO-GC-NEXT: Type: I64 | ||
| 118 | ; NO-GC-NEXT: Mutable: true | ||
| 119 | ; NO-GC-NEXT: InitExpr: | ||
| 120 | ; NO-GC-NEXT: Opcode: I64_CONST | ||
| 121 | ; NO-GC-NEXT: Value: 123 | ||
| 122 | ; NO-GC-NEXT: - Index: 2 | ||
| 123 | ; NO-GC-NEXT: Type: I64 | ||
| 124 | ; NO-GC-NEXT: Mutable: true | ||
| 125 | ; NO-GC-NEXT: InitExpr: | ||
| 126 | ; NO-GC-NEXT: Opcode: I64_CONST | ||
| 127 | ; NO-GC-NEXT: Value: 456 | ||
| 128 | |||
| 129 | ; NO-GC: - Type: DATA | ||
| 130 | ; NO-GC-NEXT: Segments: | ||
| 131 | ; NO-GC-NEXT: - SectionOffset: 7 | ||
| 132 | ; NO-GC-NEXT: MemoryIndex: 0 | ||
| 133 | ; NO-GC-NEXT: Offset: | ||
| 134 | ; NO-GC-NEXT: Opcode: I32_CONST | ||
| 135 | ; NO-GC-NEXT: Value: 1024 | ||
| 136 | ; NO-GC-NEXT: Content: '010000000000000002000000' | ||
| 137 | ; NO-GC-NEXT: - Type: CUSTOM | ||
| 138 | ; NO-GC-NEXT: Name: name | ||
| 139 | ; NO-GC-NEXT: FunctionNames: | ||
| 140 | ; NO-GC-NEXT: - Index: 0 | ||
| 141 | ; NO-GC-NEXT: Name: __wasm_call_ctors | ||
| 142 | ; NO-GC-NEXT: - Index: 1 | ||
| 143 | ; NO-GC-NEXT: Name: unused_function | ||
| 144 | ; NO-GC-NEXT: - Index: 2 | ||
| 145 | ; NO-GC-NEXT: Name: used_function | ||
| 146 | ; NO-GC-NEXT: - Index: 3 | ||
| 147 | ; NO-GC-NEXT: Name: _start | ||
| 148 | ; NO-GC-NEXT: - Index: 4 | ||
| 149 | ; NO-GC-NEXT: Name: use_global | ||
| 150 | ; NO-GC-NEXT: ... | ||
| 151 | |||
| 152 | ; RUN: not wasm-ld --gc-sections --relocatable -o %t1.no-gc.wasm %t.o 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR | ||
| 153 | ; CHECK-ERROR: error: -r and --gc-sections may not be used together | ||
deps/lld/test/wasm/import-memory.test+24-4| ... | @@ -1,13 +1,33 @@ | ... | @@ -1,13 +1,33 @@ |
| 1 | # RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 1 | # RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o |
| 2 | # RUN: lld -flavor wasm -entry ret32 --import-memory -o %t.wasm %t.ret32.o | 2 | # RUN: wasm-ld --import-memory -o %t.wasm %t.start.o |
| 3 | # RUN: obj2yaml %t.wasm | FileCheck %s | 3 | # RUN: obj2yaml %t.wasm | FileCheck %s |
| 4 | 4 | ||
| 5 | # Verify the --import-memory flag creates a memory import | 5 | # Verify the --import-memory flag creates a memory import |
| 6 | 6 | ||
| 7 | # CHECK: - Type: IMPORT | 7 | # CHECK: - Type: IMPORT |
| 8 | # CHECK-NEXT: Imports: | 8 | # CHECK-NEXT: Imports: |
| 9 | # CHECK-NEXT: - Module: env | 9 | # CHECK-NEXT: - Module: env |
| 10 | # CHECK-NEXT: Field: memory | 10 | # CHECK-NEXT: Field: memory |
| 11 | # CHECK-NEXT: Kind: MEMORY | 11 | # CHECK-NEXT: Kind: MEMORY |
| 12 | # CHECK-NEXT: Memory: | 12 | # CHECK-NEXT: Memory: |
| 13 | # CHECK-NEXT: Initial: 0x00000002 | 13 | # CHECK-NEXT: Initial: 0x00000002 |
| 14 | # CHECK-NEXT: - Type: | ||
| 15 | |||
| 16 | |||
| 17 | |||
| 18 | # RUN: wasm-ld --import-memory --initial-memory=262144 \ | ||
| 19 | # RUN: --max-memory=327680 -o %t.max.wasm %t.start.o | ||
| 20 | # RUN: obj2yaml %t.max.wasm | FileCheck -check-prefix=CHECK-MAX %s | ||
| 21 | |||
| 22 | # Verify the --initial-memory and --max-memory arguments work with imports | ||
| 23 | |||
| 24 | # CHECK-MAX: - Type: IMPORT | ||
| 25 | # CHECK-MAX-NEXT: Imports: | ||
| 26 | # CHECK-MAX-NEXT: - Module: env | ||
| 27 | # CHECK-MAX-NEXT: Field: memory | ||
| 28 | # CHECK-MAX-NEXT: Kind: MEMORY | ||
| 29 | # CHECK-MAX-NEXT: Memory: | ||
| 30 | # CHECK-MAX-NEXT: Flags: [ HAS_MAX ] | ||
| 31 | # CHECK-MAX-NEXT: Initial: 0x00000004 | ||
| 32 | # CHECK-MAX-NEXT: Maximum: 0x00000005 | ||
| 33 | # CHECK-MAX-NEXT: - Type: |
deps/lld/test/wasm/import-table.test created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | # RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o | ||
| 2 | # RUN: wasm-ld --import-table -o %t.wasm %t.start.o | ||
| 3 | # RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 4 | |||
| 5 | # Verify the --import-table flag creates a table import | ||
| 6 | |||
| 7 | # CHECK: - Type: IMPORT | ||
| 8 | # CHECK-NEXT: Imports: | ||
| 9 | # CHECK-NEXT: - Module: env | ||
| 10 | # CHECK-NEXT: Field: __indirect_function_table | ||
| 11 | # CHECK-NEXT: Kind: TABLE | ||
| 12 | # CHECK-NEXT: Table: | ||
| 13 | # CHECK-NEXT: ElemType: ANYFUNC | ||
| 14 | # CHECK-NEXT: Limits: | ||
| 15 | # CHECK-NEXT: Flags: [ HAS_MAX ] | ||
| 16 | # CHECK-NEXT: Initial: 0x00000001 | ||
| 17 | # CHECK-NEXT: Maximum: 0x00000001 | ||
| 18 | |||
deps/lld/test/wasm/init-fini.ll+272-43| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s | 1 | ; RUN: llc -filetype=obj -o %t.o %s |
| 2 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/global-ctor-dtor.ll -o %t.global-ctor-dtor.o | 2 | ; RUN: llc -filetype=obj %S/Inputs/global-ctor-dtor.ll -o %t.global-ctor-dtor.o |
| 3 | |||
| 4 | target triple = "wasm32-unknown-unknown" | ||
| 3 | 5 | ||
| 4 | define hidden void @func1() { | 6 | define hidden void @func1() { |
| 5 | entry: | 7 | entry: |
| ... | @@ -11,89 +13,316 @@ entry: | ... | @@ -11,89 +13,316 @@ entry: |
| 11 | ret void | 13 | ret void |
| 12 | } | 14 | } |
| 13 | 15 | ||
| 14 | define void @__cxa_atexit() { | 16 | define hidden void @func3() { |
| 17 | entry: | ||
| 15 | ret void | 18 | ret void |
| 16 | } | 19 | } |
| 17 | 20 | ||
| 21 | define hidden void @func4() { | ||
| 22 | entry: | ||
| 23 | ret void | ||
| 24 | } | ||
| 25 | |||
| 26 | declare hidden void @externCtor() | ||
| 27 | declare hidden void @externDtor() | ||
| 28 | |||
| 29 | define i32 @__cxa_atexit(i32 %func, i32 %arg, i32 %dso_handle) { | ||
| 30 | ret i32 0 | ||
| 31 | } | ||
| 32 | |||
| 18 | define hidden void @_start() { | 33 | define hidden void @_start() { |
| 19 | entry: | 34 | entry: |
| 20 | ret void | 35 | ret void |
| 21 | } | 36 | } |
| 22 | 37 | ||
| 23 | @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @func1, i8* null }] | 38 | @llvm.global_ctors = appending global [4 x { i32, void ()*, i8* }] [ |
| 39 | { i32, void ()*, i8* } { i32 1001, void ()* @func1, i8* null }, | ||
| 40 | { i32, void ()*, i8* } { i32 101, void ()* @func1, i8* null }, | ||
| 41 | { i32, void ()*, i8* } { i32 101, void ()* @func2, i8* null }, | ||
| 42 | { i32, void ()*, i8* } { i32 4000, void ()* @externCtor, i8* null } | ||
| 43 | ] | ||
| 24 | 44 | ||
| 25 | @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @func2, i8* null }] | 45 | @llvm.global_dtors = appending global [4 x { i32, void ()*, i8* }] [ |
| 46 | { i32, void ()*, i8* } { i32 1001, void ()* @func3, i8* null }, | ||
| 47 | { i32, void ()*, i8* } { i32 101, void ()* @func3, i8* null }, | ||
| 48 | { i32, void ()*, i8* } { i32 101, void ()* @func4, i8* null }, | ||
| 49 | { i32, void ()*, i8* } { i32 4000, void ()* @externDtor, i8* null } | ||
| 50 | ] | ||
| 26 | 51 | ||
| 27 | ; RUN: lld -flavor wasm %t.o %t.global-ctor-dtor.o -o %t.wasm | 52 | ; RUN: wasm-ld --allow-undefined %t.o %t.global-ctor-dtor.o -o %t.wasm |
| 28 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 53 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 29 | 54 | ||
| 30 | ; CHECK: Name: linking | 55 | ; CHECK: - Type: IMPORT |
| 31 | ; CHECK-NEXT: DataSize: 0 | 56 | ; CHECK-NEXT: Imports: |
| 57 | ; CHECK-NEXT: - Module: env | ||
| 58 | ; CHECK-NEXT: Field: externDtor | ||
| 59 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 60 | ; CHECK-NEXT: SigIndex: 0 | ||
| 61 | ; CHECK-NEXT: - Module: env | ||
| 62 | ; CHECK-NEXT: Field: externCtor | ||
| 63 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 64 | ; CHECK-NEXT: SigIndex: 0 | ||
| 65 | ; CHECK: - Type: ELEM | ||
| 66 | ; CHECK-NEXT: Segments: | ||
| 67 | ; CHECK-NEXT: - Offset: | ||
| 68 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 69 | ; CHECK-NEXT: Value: 1 | ||
| 70 | ; CHECK-NEXT: Functions: [ 9, 11, 13, 17, 19, 21 ] | ||
| 71 | ; CHECK-NEXT: - Type: CODE | ||
| 72 | ; CHECK-NEXT: Functions: | ||
| 73 | ; CHECK-NEXT: - Index: 2 | ||
| 74 | ; CHECK-NEXT: Locals: | ||
| 75 | ; CHECK-NEXT: Body: 10031004100A100F1012100F10141003100C100F10161001100E0B | ||
| 76 | ; CHECK: - Index: 22 | ||
| 77 | ; CHECK-NEXT: Locals: | ||
| 78 | ; CHECK-NEXT: Body: 024041868080800041004180888080001087808080000D000F0B00000B | ||
| 32 | ; CHECK-NEXT: - Type: CUSTOM | 79 | ; CHECK-NEXT: - Type: CUSTOM |
| 33 | ; CHECK-NEXT: Name: name | 80 | ; CHECK-NEXT: Name: name |
| 34 | ; CHECK-NEXT: FunctionNames: | 81 | ; CHECK-NEXT: FunctionNames: |
| 35 | ; CHECK-NEXT: - Index: 0 | 82 | ; CHECK-NEXT: - Index: 0 |
| 36 | ; CHECK-NEXT: Name: func1 | 83 | ; CHECK-NEXT: Name: externDtor |
| 37 | ; CHECK-NEXT: - Index: 1 | 84 | ; CHECK-NEXT: - Index: 1 |
| 38 | ; CHECK-NEXT: Name: func2 | 85 | ; CHECK-NEXT: Name: externCtor |
| 39 | ; CHECK-NEXT: - Index: 2 | 86 | ; CHECK-NEXT: - Index: 2 |
| 40 | ; CHECK-NEXT: Name: __cxa_atexit | 87 | ; CHECK-NEXT: Name: __wasm_call_ctors |
| 41 | ; CHECK-NEXT: - Index: 3 | 88 | ; CHECK-NEXT: - Index: 3 |
| 42 | ; CHECK-NEXT: Name: _start | 89 | ; CHECK-NEXT: Name: func1 |
| 43 | ; CHECK-NEXT: - Index: 4 | 90 | ; CHECK-NEXT: - Index: 4 |
| 44 | ; CHECK-NEXT: Name: .Lcall_dtors | 91 | ; CHECK-NEXT: Name: func2 |
| 45 | ; CHECK-NEXT: - Index: 5 | 92 | ; CHECK-NEXT: - Index: 5 |
| 46 | ; CHECK-NEXT: Name: .Lregister_call_dtors | 93 | ; CHECK-NEXT: Name: func3 |
| 47 | ; CHECK-NEXT: - Index: 6 | 94 | ; CHECK-NEXT: - Index: 6 |
| 48 | ; CHECK-NEXT: Name: .Lbitcast | 95 | ; CHECK-NEXT: Name: func4 |
| 49 | ; CHECK-NEXT: - Index: 7 | 96 | ; CHECK-NEXT: - Index: 7 |
| 50 | ; CHECK-NEXT: Name: myctor | 97 | ; CHECK-NEXT: Name: __cxa_atexit |
| 51 | ; CHECK-NEXT: - Index: 8 | 98 | ; CHECK-NEXT: - Index: 8 |
| 52 | ; CHECK-NEXT: Name: mydtor | 99 | ; CHECK-NEXT: Name: _start |
| 53 | ; CHECK-NEXT: - Index: 9 | 100 | ; CHECK-NEXT: - Index: 9 |
| 54 | ; CHECK-NEXT: Name: .Lcall_dtors | 101 | ; CHECK-NEXT: Name: .Lcall_dtors.101 |
| 55 | ; CHECK-NEXT: - Index: 10 | 102 | ; CHECK-NEXT: - Index: 10 |
| 56 | ; CHECK-NEXT: Name: .Lregister_call_dtors | 103 | ; CHECK-NEXT: Name: .Lregister_call_dtors.101 |
| 104 | ; CHECK-NEXT: - Index: 11 | ||
| 105 | ; CHECK-NEXT: Name: .Lcall_dtors.1001 | ||
| 106 | ; CHECK-NEXT: - Index: 12 | ||
| 107 | ; CHECK-NEXT: Name: .Lregister_call_dtors.1001 | ||
| 108 | ; CHECK-NEXT: - Index: 13 | ||
| 109 | ; CHECK-NEXT: Name: .Lcall_dtors.4000 | ||
| 110 | ; CHECK-NEXT: - Index: 14 | ||
| 111 | ; CHECK-NEXT: Name: .Lregister_call_dtors.4000 | ||
| 112 | ; CHECK-NEXT: - Index: 15 | ||
| 113 | ; CHECK-NEXT: Name: myctor | ||
| 114 | ; CHECK-NEXT: - Index: 16 | ||
| 115 | ; CHECK-NEXT: Name: mydtor | ||
| 116 | ; CHECK-NEXT: - Index: 17 | ||
| 117 | ; CHECK-NEXT: Name: .Lcall_dtors.101 | ||
| 118 | ; CHECK-NEXT: - Index: 18 | ||
| 119 | ; CHECK-NEXT: Name: .Lregister_call_dtors.101 | ||
| 120 | ; CHECK-NEXT: - Index: 19 | ||
| 121 | ; CHECK-NEXT: Name: .Lcall_dtors.202 | ||
| 122 | ; CHECK-NEXT: - Index: 20 | ||
| 123 | ; CHECK-NEXT: Name: .Lregister_call_dtors.202 | ||
| 124 | ; CHECK-NEXT: - Index: 21 | ||
| 125 | ; CHECK-NEXT: Name: .Lcall_dtors.2002 | ||
| 126 | ; CHECK-NEXT: - Index: 22 | ||
| 127 | ; CHECK-NEXT: Name: .Lregister_call_dtors.2002 | ||
| 57 | ; CHECK-NEXT: ... | 128 | ; CHECK-NEXT: ... |
| 58 | 129 | ||
| 59 | 130 | ||
| 60 | ; RUN: lld -flavor wasm -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm | 131 | ; RUN: wasm-ld -r %t.o %t.global-ctor-dtor.o -o %t.reloc.wasm |
| 61 | ; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s | 132 | ; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s |
| 62 | 133 | ||
| 63 | ; RELOC: Name: linking | 134 | ; RELOC: SymbolTable: |
| 64 | ; RELOC-NEXT: DataSize: 0 | ||
| 65 | ; RELOC-NEXT: InitFunctions: | ||
| 66 | ; RELOC-NEXT: - Priority: 65535 | ||
| 67 | ; RELOC-NEXT: FunctionIndex: 0 | ||
| 68 | ; RELOC-NEXT: - Priority: 65535 | ||
| 69 | ; RELOC-NEXT: FunctionIndex: 5 | ||
| 70 | ; RELOC-NEXT: - Priority: 65535 | ||
| 71 | ; RELOC-NEXT: FunctionIndex: 7 | ||
| 72 | ; RELOC-NEXT: - Priority: 65535 | ||
| 73 | ; RELOC-NEXT: FunctionIndex: 10 | ||
| 74 | ; RELOC-NEXT: - Type: CUSTOM | ||
| 75 | ; RELOC-NEXT: Name: name | ||
| 76 | ; RELOC-NEXT: FunctionNames: | ||
| 77 | ; RELOC-NEXT: - Index: 0 | 135 | ; RELOC-NEXT: - Index: 0 |
| 136 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 78 | ; RELOC-NEXT: Name: func1 | 137 | ; RELOC-NEXT: Name: func1 |
| 138 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 139 | ; RELOC-NEXT: Function: 2 | ||
| 79 | ; RELOC-NEXT: - Index: 1 | 140 | ; RELOC-NEXT: - Index: 1 |
| 141 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 80 | ; RELOC-NEXT: Name: func2 | 142 | ; RELOC-NEXT: Name: func2 |
| 143 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 144 | ; RELOC-NEXT: Function: 3 | ||
| 81 | ; RELOC-NEXT: - Index: 2 | 145 | ; RELOC-NEXT: - Index: 2 |
| 82 | ; RELOC-NEXT: Name: __cxa_atexit | 146 | ; RELOC-NEXT: Kind: FUNCTION |
| 147 | ; RELOC-NEXT: Name: func3 | ||
| 148 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 149 | ; RELOC-NEXT: Function: 4 | ||
| 83 | ; RELOC-NEXT: - Index: 3 | 150 | ; RELOC-NEXT: - Index: 3 |
| 84 | ; RELOC-NEXT: Name: _start | 151 | ; RELOC-NEXT: Kind: FUNCTION |
| 152 | ; RELOC-NEXT: Name: func4 | ||
| 153 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 154 | ; RELOC-NEXT: Function: 5 | ||
| 85 | ; RELOC-NEXT: - Index: 4 | 155 | ; RELOC-NEXT: - Index: 4 |
| 86 | ; RELOC-NEXT: Name: .Lcall_dtors | 156 | ; RELOC-NEXT: Kind: FUNCTION |
| 157 | ; RELOC-NEXT: Name: __cxa_atexit | ||
| 158 | ; RELOC-NEXT: Flags: [ ] | ||
| 159 | ; RELOC-NEXT: Function: 6 | ||
| 87 | ; RELOC-NEXT: - Index: 5 | 160 | ; RELOC-NEXT: - Index: 5 |
| 88 | ; RELOC-NEXT: Name: .Lregister_call_dtors | 161 | ; RELOC-NEXT: Kind: FUNCTION |
| 162 | ; RELOC-NEXT: Name: _start | ||
| 163 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 164 | ; RELOC-NEXT: Function: 7 | ||
| 89 | ; RELOC-NEXT: - Index: 6 | 165 | ; RELOC-NEXT: - Index: 6 |
| 90 | ; RELOC-NEXT: Name: .Lbitcast | 166 | ; RELOC-NEXT: Kind: FUNCTION |
| 167 | ; RELOC-NEXT: Name: .Lcall_dtors.101 | ||
| 168 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 169 | ; RELOC-NEXT: Function: 8 | ||
| 91 | ; RELOC-NEXT: - Index: 7 | 170 | ; RELOC-NEXT: - Index: 7 |
| 92 | ; RELOC-NEXT: Name: myctor | 171 | ; RELOC-NEXT: Kind: FUNCTION |
| 172 | ; RELOC-NEXT: Name: .Lregister_call_dtors.101 | ||
| 173 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 174 | ; RELOC-NEXT: Function: 9 | ||
| 93 | ; RELOC-NEXT: - Index: 8 | 175 | ; RELOC-NEXT: - Index: 8 |
| 176 | ; RELOC-NEXT: Kind: DATA | ||
| 177 | ; RELOC-NEXT: Name: __dso_handle | ||
| 178 | ; RELOC-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ] | ||
| 179 | ; RELOC-NEXT: - Index: 9 | ||
| 180 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 181 | ; RELOC-NEXT: Name: .Lcall_dtors.1001 | ||
| 182 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 183 | ; RELOC-NEXT: Function: 10 | ||
| 184 | ; RELOC-NEXT: - Index: 10 | ||
| 185 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 186 | ; RELOC-NEXT: Name: .Lregister_call_dtors.1001 | ||
| 187 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 188 | ; RELOC-NEXT: Function: 11 | ||
| 189 | ; RELOC-NEXT: - Index: 11 | ||
| 190 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 191 | ; RELOC-NEXT: Name: .Lcall_dtors.4000 | ||
| 192 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 193 | ; RELOC-NEXT: Function: 12 | ||
| 194 | ; RELOC-NEXT: - Index: 12 | ||
| 195 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 196 | ; RELOC-NEXT: Name: externDtor | ||
| 197 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ] | ||
| 198 | ; RELOC-NEXT: Function: 0 | ||
| 199 | ; RELOC-NEXT: - Index: 13 | ||
| 200 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 201 | ; RELOC-NEXT: Name: .Lregister_call_dtors.4000 | ||
| 202 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 203 | ; RELOC-NEXT: Function: 13 | ||
| 204 | ; RELOC-NEXT: - Index: 14 | ||
| 205 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 206 | ; RELOC-NEXT: Name: externCtor | ||
| 207 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ] | ||
| 208 | ; RELOC-NEXT: Function: 1 | ||
| 209 | ; RELOC-NEXT: - Index: 15 | ||
| 210 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 211 | ; RELOC-NEXT: Name: myctor | ||
| 212 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 213 | ; RELOC-NEXT: Function: 14 | ||
| 214 | ; RELOC-NEXT: - Index: 16 | ||
| 215 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 94 | ; RELOC-NEXT: Name: mydtor | 216 | ; RELOC-NEXT: Name: mydtor |
| 217 | ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 218 | ; RELOC-NEXT: Function: 15 | ||
| 219 | ; RELOC-NEXT: - Index: 17 | ||
| 220 | ; RELOC-NEXT: Kind: GLOBAL | ||
| 221 | ; RELOC-NEXT: Name: __stack_pointer | ||
| 222 | ; RELOC-NEXT: Flags: [ UNDEFINED ] | ||
| 223 | ; RELOC-NEXT: Global: 0 | ||
| 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: 7 | ||
| 261 | ; RELOC-NEXT: - Priority: 101 | ||
| 262 | ; RELOC-NEXT: Symbol: 15 | ||
| 263 | ; RELOC-NEXT: - Priority: 101 | ||
| 264 | ; RELOC-NEXT: Symbol: 19 | ||
| 265 | ; RELOC-NEXT: - Priority: 202 | ||
| 266 | ; RELOC-NEXT: Symbol: 15 | ||
| 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: 10 | ||
| 273 | ; RELOC-NEXT: - Priority: 2002 | ||
| 274 | ; RELOC-NEXT: Symbol: 15 | ||
| 275 | ; RELOC-NEXT: - Priority: 2002 | ||
| 276 | ; RELOC-NEXT: Symbol: 23 | ||
| 277 | ; RELOC-NEXT: - Priority: 4000 | ||
| 278 | ; RELOC-NEXT: Symbol: 14 | ||
| 279 | ; RELOC-NEXT: - Priority: 4000 | ||
| 280 | ; RELOC-NEXT: Symbol: 13 | ||
| 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 | ||
| 95 | ; RELOC-NEXT: - Index: 9 | 302 | ; RELOC-NEXT: - Index: 9 |
| 96 | ; RELOC-NEXT: Name: .Lcall_dtors | 303 | ; RELOC-NEXT: Name: .Lregister_call_dtors.101 |
| 97 | ; RELOC-NEXT: - Index: 10 | 304 | ; RELOC-NEXT: - Index: 10 |
| 98 | ; RELOC-NEXT: Name: .Lregister_call_dtors | 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 | ||
| 99 | ; RELOC-NEXT: ... | 328 | ; RELOC-NEXT: ... |
deps/lld/test/wasm/invalid-stack-size.test+2-7| ... | @@ -1,9 +1,4 @@ | ... | @@ -1,9 +1,4 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %s -o %t.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o |
| 2 | ; RUN: not lld -flavor wasm -o %t.wasm -z stack-size=1 %t.o 2>&1 | FileCheck %s | 2 | ; RUN: not wasm-ld -o %t.wasm -z stack-size=1 %t.o 2>&1 | FileCheck %s |
| 3 | |||
| 4 | define i32 @_start() local_unnamed_addr #1 { | ||
| 5 | entry: | ||
| 6 | ret i32 0 | ||
| 7 | } | ||
| 8 | 3 | ||
| 9 | ; CHECK: error: stack size must be 16-byte aligned | 4 | ; CHECK: error: stack size must be 16-byte aligned |
deps/lld/test/wasm/load-undefined.ll deleted-38| ... | @@ -1,38 +0,0 @@ | ||
| 1 | ; Verify that the -u / --undefined option is able to pull in symbols from | ||
| 2 | ; an archive, and doesn't error when uses to pull in a symbol already loaded. | ||
| 3 | ; | ||
| 4 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/ret64.ll -o %t.o | ||
| 5 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %S/Inputs/ret32.ll -o %t2.o | ||
| 6 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t3.o | ||
| 7 | ; RUN: llvm-ar rcs %t2.a %t2.o | ||
| 8 | ; RUN: lld -flavor wasm %t3.o %t2.a %t.o -o %t.wasm -u ret32 --undefined ret64 | ||
| 9 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 10 | |||
| 11 | define i32 @_start() local_unnamed_addr { | ||
| 12 | entry: | ||
| 13 | ret i32 1 | ||
| 14 | } | ||
| 15 | |||
| 16 | ; CHECK: - Type: EXPORT | ||
| 17 | ; CHECK-NEXT: Exports: | ||
| 18 | ; CHECK-NEXT: - Name: memory | ||
| 19 | ; CHECK-NEXT: Kind: MEMORY | ||
| 20 | ; CHECK-NEXT: Index: 0 | ||
| 21 | ; CHECK-NEXT: - Name: _start | ||
| 22 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 23 | ; CHECK-NEXT: Index: 0 | ||
| 24 | ; CHECK-NEXT: - Name: ret32 | ||
| 25 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 26 | ; CHECK-NEXT: Index: 1 | ||
| 27 | ; CHECK-NEXT: - Name: ret64 | ||
| 28 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 29 | ; CHECK-NEXT: Index: 2 | ||
| 30 | ; CHECK-NEXT: - Type: | ||
| 31 | |||
| 32 | |||
| 33 | ; Verify that referencing a symbol that doesn't exist won't work | ||
| 34 | ; RUN: not lld -flavor wasm %t3.o -o %t.wasm -u symboldoesnotexist 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED1 %s | ||
| 35 | ; CHECK-UNDEFINED1: error: undefined symbol: symboldoesnotexist | ||
| 36 | |||
| 37 | ; RUN: not lld -flavor wasm %t3.o -o %t.wasm --undefined symboldoesnotexist --allow-undefined 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED2 %s | ||
| 38 | ; CHECK-UNDEFINED2: function forced with --undefined not found: symboldoesnotexist | ||
deps/lld/test/wasm/load-undefined.test created+40| ... | @@ -0,0 +1,40 @@ | ||
| 1 | ; Verify that the -u / --undefined option is able to pull in symbols from | ||
| 2 | ; an archive, and doesn't error when uses to pull in a symbol already loaded. | ||
| 3 | ; | ||
| 4 | ; RUN: llc -filetype=obj %S/Inputs/ret64.ll -o %t.o | ||
| 5 | ; RUN: llc -filetype=obj %S/Inputs/ret32.ll -o %t2.o | ||
| 6 | ; RUN: llc -filetype=obj %S/Inputs/start.ll -o %t.start.o | ||
| 7 | ; RUN: llvm-ar rcs %t2.a %t2.o | ||
| 8 | ; RUN: wasm-ld %t.start.o --no-gc-sections %t2.a %t.o -o %t.wasm -u ret32 --undefined ret64 | ||
| 9 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 10 | ; RUN: wasm-ld %t.start.o --no-gc-sections %t2.a %t.o -o %t2.wasm | ||
| 11 | ; RUN: obj2yaml %t2.wasm | FileCheck %s -check-prefix=NO-LOAD | ||
| 12 | |||
| 13 | ; CHECK: Name: name | ||
| 14 | ; CHECK-NEXT: FunctionNames: | ||
| 15 | ; CHECK-NEXT: - Index: 0 | ||
| 16 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 17 | ; CHECK-NEXT: - Index: 1 | ||
| 18 | ; CHECK-NEXT: Name: _start | ||
| 19 | ; CHECK-NEXT: - Index: 2 | ||
| 20 | ; CHECK-NEXT: Name: ret32 | ||
| 21 | ; CHECK-NEXT: - Index: 3 | ||
| 22 | ; CHECK-NEXT: Name: ret64 | ||
| 23 | ; CHECK-NEXT: ... | ||
| 24 | |||
| 25 | ; NO-LOAD: Name: name | ||
| 26 | ; NO-LOAD-NEXT: FunctionNames: | ||
| 27 | ; NO-LOAD-NEXT: - Index: 0 | ||
| 28 | ; NO-LOAD-NEXT: Name: __wasm_call_ctors | ||
| 29 | ; NO-LOAD-NEXT: - Index: 1 | ||
| 30 | ; NO-LOAD-NEXT: Name: _start | ||
| 31 | ; NO-LOAD-NEXT: - Index: 2 | ||
| 32 | ; NO-LOAD-NEXT: Name: ret64 | ||
| 33 | ; NO-LOAD-NEXT: ... | ||
| 34 | |||
| 35 | ; Verify that referencing a symbol that doesn't exist won't work | ||
| 36 | ; RUN: not wasm-ld %t.start.o -o %t.wasm -u symboldoesnotexist 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED1 %s | ||
| 37 | ; CHECK-UNDEFINED1: error: undefined symbol: symboldoesnotexist | ||
| 38 | |||
| 39 | ; RUN: not wasm-ld %t.start.o -o %t.wasm --undefined symboldoesnotexist --allow-undefined 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED2 %s | ||
| 40 | ; CHECK-UNDEFINED2: symbol forced with --undefined not found: symboldoesnotexist | ||
deps/lld/test/wasm/local-symbols.ll+55-16| ... | @@ -1,18 +1,22 @@ | ... | @@ -1,18 +1,22 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 1 | ; RUN: llc -filetype=obj %s -o %t.o |
| 2 | ; RUN: lld -flavor wasm -o %t.wasm %t.o | 2 | ; RUN: wasm-ld -o %t.wasm %t.o |
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 4 | 4 | ||
| 5 | target triple = "wasm32-unknown-unknown" | ||
| 6 | |||
| 5 | @foo = default global i32 1, align 4 | 7 | @foo = default global i32 1, align 4 |
| 6 | @bar = internal default global i32 3, align 4 | 8 | @bar = internal default global i32 3, align 4 |
| 7 | 9 | ||
| 8 | define internal i32 @baz() local_unnamed_addr { | 10 | define internal i32 @baz() local_unnamed_addr { |
| 9 | entry: | 11 | entry: |
| 10 | ret i32 2 | 12 | %0 = load i32, i32* @bar, align 4 |
| 13 | ret i32 %0 | ||
| 11 | } | 14 | } |
| 12 | 15 | ||
| 13 | define i32 @_start() local_unnamed_addr { | 16 | define void @_start() local_unnamed_addr { |
| 14 | entry: | 17 | entry: |
| 15 | ret i32 1 | 18 | call i32 @baz() |
| 19 | ret void | ||
| 16 | } | 20 | } |
| 17 | 21 | ||
| 18 | ; CHECK: --- !WASM | 22 | ; CHECK: --- !WASM |
| ... | @@ -22,10 +26,13 @@ entry: | ... | @@ -22,10 +26,13 @@ entry: |
| 22 | ; CHECK-NEXT: - Type: TYPE | 26 | ; CHECK-NEXT: - Type: TYPE |
| 23 | ; CHECK-NEXT: Signatures: | 27 | ; CHECK-NEXT: Signatures: |
| 24 | ; CHECK-NEXT: - Index: 0 | 28 | ; CHECK-NEXT: - Index: 0 |
| 29 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 30 | ; CHECK-NEXT: ParamTypes: | ||
| 31 | ; CHECK-NEXT: - Index: 1 | ||
| 25 | ; CHECK-NEXT: ReturnType: I32 | 32 | ; CHECK-NEXT: ReturnType: I32 |
| 26 | ; CHECK-NEXT: ParamTypes: | 33 | ; CHECK-NEXT: ParamTypes: |
| 27 | ; CHECK-NEXT: - Type: FUNCTION | 34 | ; CHECK-NEXT: - Type: FUNCTION |
| 28 | ; CHECK-NEXT: FunctionTypes: [ 0, 0 ] | 35 | ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0 ] |
| 29 | ; CHECK-NEXT: - Type: TABLE | 36 | ; CHECK-NEXT: - Type: TABLE |
| 30 | ; CHECK-NEXT: Tables: | 37 | ; CHECK-NEXT: Tables: |
| 31 | ; CHECK-NEXT: - ElemType: ANYFUNC | 38 | ; CHECK-NEXT: - ElemType: ANYFUNC |
| ... | @@ -38,25 +45,58 @@ entry: | ... | @@ -38,25 +45,58 @@ entry: |
| 38 | ; CHECK-NEXT: - Initial: 0x00000002 | 45 | ; CHECK-NEXT: - Initial: 0x00000002 |
| 39 | ; CHECK-NEXT: - Type: GLOBAL | 46 | ; CHECK-NEXT: - Type: GLOBAL |
| 40 | ; CHECK-NEXT: Globals: | 47 | ; CHECK-NEXT: Globals: |
| 41 | ; CHECK-NEXT: - Type: I32 | 48 | ; CHECK-NEXT: - Index: 0 |
| 49 | ; CHECK-NEXT: Type: I32 | ||
| 42 | ; CHECK-NEXT: Mutable: true | 50 | ; CHECK-NEXT: Mutable: true |
| 43 | ; CHECK-NEXT: InitExpr: | 51 | ; CHECK-NEXT: InitExpr: |
| 44 | ; CHECK-NEXT: Opcode: I32_CONST | 52 | ; CHECK-NEXT: Opcode: I32_CONST |
| 45 | ; CHECK-NEXT: Value: 66576 | 53 | ; CHECK-NEXT: Value: 66576 |
| 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: 66576 | ||
| 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: 1032 | ||
| 66 | ; CHECK-NEXT: - Index: 3 | ||
| 67 | ; CHECK-NEXT: Type: I32 | ||
| 68 | ; CHECK-NEXT: Mutable: false | ||
| 69 | ; CHECK-NEXT: InitExpr: | ||
| 70 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 71 | ; CHECK-NEXT: Value: 1024 | ||
| 46 | ; CHECK-NEXT: - Type: EXPORT | 72 | ; CHECK-NEXT: - Type: EXPORT |
| 47 | ; CHECK-NEXT: Exports: | 73 | ; CHECK-NEXT: Exports: |
| 48 | ; CHECK-NEXT: - Name: memory | 74 | ; CHECK-NEXT: - Name: memory |
| 49 | ; CHECK-NEXT: Kind: MEMORY | 75 | ; CHECK-NEXT: Kind: MEMORY |
| 50 | ; CHECK-NEXT: Index: 0 | 76 | ; CHECK-NEXT: Index: 0 |
| 77 | ; CHECK-NEXT: - Name: __heap_base | ||
| 78 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 79 | ; CHECK-NEXT: Index: 1 | ||
| 80 | ; CHECK-NEXT: - Name: __data_end | ||
| 81 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 82 | ; CHECK-NEXT: Index: 2 | ||
| 51 | ; CHECK-NEXT: - Name: _start | 83 | ; CHECK-NEXT: - Name: _start |
| 52 | ; CHECK-NEXT: Kind: FUNCTION | 84 | ; CHECK-NEXT: Kind: FUNCTION |
| 53 | ; CHECK-NEXT: Index: 1 | 85 | ; CHECK-NEXT: Index: 2 |
| 86 | ; CHECK-NEXT: - Name: foo | ||
| 87 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 88 | ; CHECK-NEXT: Index: 3 | ||
| 54 | ; CHECK-NEXT: - Type: CODE | 89 | ; CHECK-NEXT: - Type: CODE |
| 55 | ; CHECK-NEXT: Functions: | 90 | ; CHECK-NEXT: Functions: |
| 56 | ; CHECK-NEXT: - Locals: | 91 | ; CHECK-NEXT: - Index: 0 |
| 57 | ; CHECK-NEXT: Body: 41020B | 92 | ; CHECK-NEXT: Locals: |
| 58 | ; CHECK-NEXT: - Locals: | 93 | ; CHECK-NEXT: Body: 0B |
| 59 | ; CHECK-NEXT: Body: 41010B | 94 | ; CHECK-NEXT: - Index: 1 |
| 95 | ; CHECK-NEXT: Locals: | ||
| 96 | ; CHECK-NEXT: Body: 4100280284888080000B | ||
| 97 | ; CHECK-NEXT: - Index: 2 | ||
| 98 | ; CHECK-NEXT: Locals: | ||
| 99 | ; CHECK-NEXT: Body: 1081808080001A0B | ||
| 60 | ; CHECK-NEXT: - Type: DATA | 100 | ; CHECK-NEXT: - Type: DATA |
| 61 | ; CHECK-NEXT: Segments: | 101 | ; CHECK-NEXT: Segments: |
| 62 | ; CHECK-NEXT: - SectionOffset: 7 | 102 | ; CHECK-NEXT: - SectionOffset: 7 |
| ... | @@ -66,13 +106,12 @@ entry: | ... | @@ -66,13 +106,12 @@ entry: |
| 66 | ; CHECK-NEXT: Value: 1024 | 106 | ; CHECK-NEXT: Value: 1024 |
| 67 | ; CHECK-NEXT: Content: '0100000003000000' | 107 | ; CHECK-NEXT: Content: '0100000003000000' |
| 68 | ; CHECK-NEXT: - Type: CUSTOM | 108 | ; CHECK-NEXT: - Type: CUSTOM |
| 69 | ; CHECK-NEXT: Name: linking | ||
| 70 | ; CHECK-NEXT: DataSize: 8 | ||
| 71 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 72 | ; CHECK-NEXT: Name: name | 109 | ; CHECK-NEXT: Name: name |
| 73 | ; CHECK-NEXT: FunctionNames: | 110 | ; CHECK-NEXT: FunctionNames: |
| 74 | ; CHECK-NEXT: - Index: 0 | 111 | ; CHECK-NEXT: - Index: 0 |
| 75 | ; CHECK-NEXT: Name: baz | 112 | ; CHECK-NEXT: Name: __wasm_call_ctors |
| 76 | ; CHECK-NEXT: - Index: 1 | 113 | ; CHECK-NEXT: - Index: 1 |
| 114 | ; CHECK-NEXT: Name: baz | ||
| 115 | ; CHECK-NEXT: - Index: 2 | ||
| 77 | ; CHECK-NEXT: Name: _start | 116 | ; CHECK-NEXT: Name: _start |
| 78 | ; CHECK-NEXT: ... | 117 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/locals-duplicate.test created+568| ... | @@ -0,0 +1,568 @@ | ||
| 1 | ; RUN: llc -filetype=obj %p/Inputs/locals-duplicate1.ll -o %t1.o | ||
| 2 | ; RUN: llc -filetype=obj %p/Inputs/locals-duplicate2.ll -o %t2.o | ||
| 3 | ; RUN: wasm-ld --no-entry -o %t.wasm %t1.o %t2.o | ||
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | ; CHECK: --- !WASM | ||
| 7 | ; CHECK-NEXT: FileHeader: | ||
| 8 | ; CHECK-NEXT: Version: 0x00000001 | ||
| 9 | ; CHECK-NEXT: Sections: | ||
| 10 | ; CHECK-NEXT: - Type: TYPE | ||
| 11 | ; CHECK-NEXT: Signatures: | ||
| 12 | ; CHECK-NEXT: - Index: 0 | ||
| 13 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 14 | ; CHECK-NEXT: ParamTypes: | ||
| 15 | ; CHECK-NEXT: - Index: 1 | ||
| 16 | ; CHECK-NEXT: ReturnType: I32 | ||
| 17 | ; CHECK-NEXT: ParamTypes: | ||
| 18 | ; 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 ] | ||
| 21 | ; CHECK-NEXT: - Type: TABLE | ||
| 22 | ; CHECK-NEXT: Tables: | ||
| 23 | ; CHECK-NEXT: - ElemType: ANYFUNC | ||
| 24 | ; CHECK-NEXT: Limits: | ||
| 25 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | ||
| 26 | ; CHECK-NEXT: Initial: 0x00000007 | ||
| 27 | ; CHECK-NEXT: Maximum: 0x00000007 | ||
| 28 | ; CHECK-NEXT: - Type: MEMORY | ||
| 29 | ; CHECK-NEXT: Memories: | ||
| 30 | ; CHECK-NEXT: - Initial: 0x00000002 | ||
| 31 | ; CHECK-NEXT: - Type: GLOBAL | ||
| 32 | ; CHECK-NEXT: Globals: | ||
| 33 | ; CHECK-NEXT: - Index: 0 | ||
| 34 | ; CHECK-NEXT: Type: I32 | ||
| 35 | ; CHECK-NEXT: Mutable: true | ||
| 36 | ; CHECK-NEXT: InitExpr: | ||
| 37 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 38 | ; CHECK-NEXT: Value: 66592 | ||
| 39 | ; CHECK-NEXT: - Index: 1 | ||
| 40 | ; CHECK-NEXT: Type: I32 | ||
| 41 | ; CHECK-NEXT: Mutable: false | ||
| 42 | ; CHECK-NEXT: InitExpr: | ||
| 43 | ; 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 | ||
| 56 | ; CHECK-NEXT: Value: 1028 | ||
| 57 | ; CHECK-NEXT: - Index: 4 | ||
| 58 | ; CHECK-NEXT: Type: I32 | ||
| 59 | ; CHECK-NEXT: Mutable: false | ||
| 60 | ; CHECK-NEXT: InitExpr: | ||
| 61 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 62 | ; CHECK-NEXT: Value: 1036 | ||
| 63 | ; CHECK-NEXT: - Type: EXPORT | ||
| 64 | ; CHECK-NEXT: Exports: | ||
| 65 | ; CHECK-NEXT: - Name: memory | ||
| 66 | ; CHECK-NEXT: Kind: MEMORY | ||
| 67 | ; 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 | ||
| 74 | ; CHECK-NEXT: - Name: colliding_func2 | ||
| 75 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 76 | ; CHECK-NEXT: Index: 2 | ||
| 77 | ; CHECK-NEXT: - Name: get_global1A | ||
| 78 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 79 | ; CHECK-NEXT: Index: 4 | ||
| 80 | ; CHECK-NEXT: - Name: get_global2A | ||
| 81 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 82 | ; CHECK-NEXT: Index: 5 | ||
| 83 | ; CHECK-NEXT: - Name: colliding_global2 | ||
| 84 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 85 | ; CHECK-NEXT: Index: 3 | ||
| 86 | ; CHECK-NEXT: - Name: get_global3A | ||
| 87 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 88 | ; CHECK-NEXT: Index: 6 | ||
| 89 | ; CHECK-NEXT: - Name: get_func1A | ||
| 90 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 91 | ; CHECK-NEXT: Index: 7 | ||
| 92 | ; CHECK-NEXT: - Name: get_func2A | ||
| 93 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 94 | ; CHECK-NEXT: Index: 8 | ||
| 95 | ; CHECK-NEXT: - Name: get_func3A | ||
| 96 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 97 | ; CHECK-NEXT: Index: 9 | ||
| 98 | ; CHECK-NEXT: - Name: colliding_func1 | ||
| 99 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 100 | ; CHECK-NEXT: Index: 10 | ||
| 101 | ; CHECK-NEXT: - Name: get_global1B | ||
| 102 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 103 | ; CHECK-NEXT: Index: 13 | ||
| 104 | ; CHECK-NEXT: - Name: colliding_global1 | ||
| 105 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 106 | ; CHECK-NEXT: Index: 4 | ||
| 107 | ; CHECK-NEXT: - Name: get_global2B | ||
| 108 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 109 | ; CHECK-NEXT: Index: 14 | ||
| 110 | ; CHECK-NEXT: - Name: get_global3B | ||
| 111 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 112 | ; CHECK-NEXT: Index: 15 | ||
| 113 | ; CHECK-NEXT: - Name: get_func1B | ||
| 114 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 115 | ; CHECK-NEXT: Index: 16 | ||
| 116 | ; CHECK-NEXT: - Name: get_func2B | ||
| 117 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 118 | ; CHECK-NEXT: Index: 17 | ||
| 119 | ; CHECK-NEXT: - Name: get_func3B | ||
| 120 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 121 | ; CHECK-NEXT: Index: 18 | ||
| 122 | ; CHECK-NEXT: - Type: ELEM | ||
| 123 | ; CHECK-NEXT: Segments: | ||
| 124 | ; CHECK-NEXT: - Offset: | ||
| 125 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 126 | ; CHECK-NEXT: Value: 1 | ||
| 127 | ; CHECK-NEXT: Functions: [ 1, 2, 3, 10, 11, 12 ] | ||
| 128 | ; CHECK-NEXT: - Type: CODE | ||
| 129 | ; CHECK-NEXT: Functions: | ||
| 130 | ; CHECK-NEXT: - Index: 0 | ||
| 131 | ; CHECK-NEXT: Locals: | ||
| 132 | ; CHECK-NEXT: Body: 0B | ||
| 133 | ; CHECK-NEXT: - Index: 1 | ||
| 134 | ; CHECK-NEXT: Locals: | ||
| 135 | ; CHECK-NEXT: Body: 41020B | ||
| 136 | ; CHECK-NEXT: - Index: 2 | ||
| 137 | ; CHECK-NEXT: Locals: | ||
| 138 | ; CHECK-NEXT: Body: 41020B | ||
| 139 | ; CHECK-NEXT: - Index: 3 | ||
| 140 | ; CHECK-NEXT: Locals: | ||
| 141 | ; CHECK-NEXT: Body: 41020B | ||
| 142 | ; CHECK-NEXT: - Index: 4 | ||
| 143 | ; CHECK-NEXT: Locals: | ||
| 144 | ; CHECK-NEXT: Body: 4180888080000B | ||
| 145 | ; CHECK-NEXT: - Index: 5 | ||
| 146 | ; CHECK-NEXT: Locals: | ||
| 147 | ; CHECK-NEXT: Body: 4184888080000B | ||
| 148 | ; CHECK-NEXT: - Index: 6 | ||
| 149 | ; CHECK-NEXT: Locals: | ||
| 150 | ; CHECK-NEXT: Body: 4188888080000B | ||
| 151 | ; CHECK-NEXT: - Index: 7 | ||
| 152 | ; CHECK-NEXT: Locals: | ||
| 153 | ; CHECK-NEXT: Body: 4181808080000B | ||
| 154 | ; CHECK-NEXT: - Index: 8 | ||
| 155 | ; CHECK-NEXT: Locals: | ||
| 156 | ; CHECK-NEXT: Body: 4182808080000B | ||
| 157 | ; CHECK-NEXT: - Index: 9 | ||
| 158 | ; CHECK-NEXT: Locals: | ||
| 159 | ; CHECK-NEXT: Body: 4183808080000B | ||
| 160 | ; CHECK-NEXT: - Index: 10 | ||
| 161 | ; CHECK-NEXT: Locals: | ||
| 162 | ; CHECK-NEXT: Body: 41020B | ||
| 163 | ; CHECK-NEXT: - Index: 11 | ||
| 164 | ; CHECK-NEXT: Locals: | ||
| 165 | ; CHECK-NEXT: Body: 41020B | ||
| 166 | ; CHECK-NEXT: - Index: 12 | ||
| 167 | ; CHECK-NEXT: Locals: | ||
| 168 | ; CHECK-NEXT: Body: 41020B | ||
| 169 | ; CHECK-NEXT: - Index: 13 | ||
| 170 | ; CHECK-NEXT: Locals: | ||
| 171 | ; CHECK-NEXT: Body: 418C888080000B | ||
| 172 | ; CHECK-NEXT: - Index: 14 | ||
| 173 | ; CHECK-NEXT: Locals: | ||
| 174 | ; CHECK-NEXT: Body: 4190888080000B | ||
| 175 | ; CHECK-NEXT: - Index: 15 | ||
| 176 | ; CHECK-NEXT: Locals: | ||
| 177 | ; CHECK-NEXT: Body: 4194888080000B | ||
| 178 | ; CHECK-NEXT: - Index: 16 | ||
| 179 | ; CHECK-NEXT: Locals: | ||
| 180 | ; CHECK-NEXT: Body: 4184808080000B | ||
| 181 | ; CHECK-NEXT: - Index: 17 | ||
| 182 | ; CHECK-NEXT: Locals: | ||
| 183 | ; CHECK-NEXT: Body: 4185808080000B | ||
| 184 | ; CHECK-NEXT: - Index: 18 | ||
| 185 | ; CHECK-NEXT: Locals: | ||
| 186 | ; CHECK-NEXT: Body: 4186808080000B | ||
| 187 | ; CHECK-NEXT: - Type: DATA | ||
| 188 | ; CHECK-NEXT: Segments: | ||
| 189 | ; CHECK-NEXT: - SectionOffset: 7 | ||
| 190 | ; CHECK-NEXT: MemoryIndex: 0 | ||
| 191 | ; CHECK-NEXT: Offset: | ||
| 192 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 193 | ; CHECK-NEXT: Value: 1024 | ||
| 194 | ; CHECK-NEXT: Content: '000000000000000000000000000000000000000000000000' | ||
| 195 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 196 | ; CHECK-NEXT: Name: name | ||
| 197 | ; CHECK-NEXT: FunctionNames: | ||
| 198 | ; CHECK-NEXT: - Index: 0 | ||
| 199 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 200 | ; CHECK-NEXT: - Index: 1 | ||
| 201 | ; CHECK-NEXT: Name: colliding_func1 | ||
| 202 | ; CHECK-NEXT: - Index: 2 | ||
| 203 | ; CHECK-NEXT: Name: colliding_func2 | ||
| 204 | ; CHECK-NEXT: - Index: 3 | ||
| 205 | ; CHECK-NEXT: Name: colliding_func3 | ||
| 206 | ; CHECK-NEXT: - Index: 4 | ||
| 207 | ; CHECK-NEXT: Name: get_global1A | ||
| 208 | ; CHECK-NEXT: - Index: 5 | ||
| 209 | ; CHECK-NEXT: Name: get_global2A | ||
| 210 | ; CHECK-NEXT: - Index: 6 | ||
| 211 | ; CHECK-NEXT: Name: get_global3A | ||
| 212 | ; CHECK-NEXT: - Index: 7 | ||
| 213 | ; CHECK-NEXT: Name: get_func1A | ||
| 214 | ; CHECK-NEXT: - Index: 8 | ||
| 215 | ; CHECK-NEXT: Name: get_func2A | ||
| 216 | ; CHECK-NEXT: - Index: 9 | ||
| 217 | ; CHECK-NEXT: Name: get_func3A | ||
| 218 | ; CHECK-NEXT: - Index: 10 | ||
| 219 | ; CHECK-NEXT: Name: colliding_func1 | ||
| 220 | ; CHECK-NEXT: - Index: 11 | ||
| 221 | ; CHECK-NEXT: Name: colliding_func2 | ||
| 222 | ; CHECK-NEXT: - Index: 12 | ||
| 223 | ; CHECK-NEXT: Name: colliding_func3 | ||
| 224 | ; CHECK-NEXT: - Index: 13 | ||
| 225 | ; CHECK-NEXT: Name: get_global1B | ||
| 226 | ; CHECK-NEXT: - Index: 14 | ||
| 227 | ; CHECK-NEXT: Name: get_global2B | ||
| 228 | ; CHECK-NEXT: - Index: 15 | ||
| 229 | ; CHECK-NEXT: Name: get_global3B | ||
| 230 | ; CHECK-NEXT: - Index: 16 | ||
| 231 | ; CHECK-NEXT: Name: get_func1B | ||
| 232 | ; CHECK-NEXT: - Index: 17 | ||
| 233 | ; CHECK-NEXT: Name: get_func2B | ||
| 234 | ; CHECK-NEXT: - Index: 18 | ||
| 235 | ; CHECK-NEXT: Name: get_func3B | ||
| 236 | ; CHECK-NEXT: ... | ||
| 237 | |||
| 238 | |||
| 239 | ; RUN: wasm-ld -r --no-entry -o %t.reloc.wasm %t1.o %t2.o | ||
| 240 | ; RUN: obj2yaml %t.reloc.wasm | FileCheck -check-prefix=RELOC %s | ||
| 241 | |||
| 242 | ; RELOC: --- !WASM | ||
| 243 | ; RELOC-NEXT: FileHeader: | ||
| 244 | ; RELOC-NEXT: Version: 0x00000001 | ||
| 245 | ; RELOC-NEXT: Sections: | ||
| 246 | ; RELOC-NEXT: - Type: TYPE | ||
| 247 | ; RELOC-NEXT: Signatures: | ||
| 248 | ; RELOC-NEXT: - Index: 0 | ||
| 249 | ; RELOC-NEXT: ReturnType: I32 | ||
| 250 | ; RELOC-NEXT: ParamTypes: | ||
| 251 | ; RELOC-NEXT: - Type: FUNCTION | ||
| 252 | ; RELOC-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 253 | ; RELOC-NEXT: 0, 0 ] | ||
| 254 | ; RELOC-NEXT: - Type: TABLE | ||
| 255 | ; RELOC-NEXT: Tables: | ||
| 256 | ; RELOC-NEXT: - ElemType: ANYFUNC | ||
| 257 | ; RELOC-NEXT: Limits: | ||
| 258 | ; RELOC-NEXT: Flags: [ HAS_MAX ] | ||
| 259 | ; RELOC-NEXT: Initial: 0x00000007 | ||
| 260 | ; RELOC-NEXT: Maximum: 0x00000007 | ||
| 261 | ; RELOC-NEXT: - Type: MEMORY | ||
| 262 | ; RELOC-NEXT: Memories: | ||
| 263 | ; RELOC-NEXT: - Initial: 0x00000001 | ||
| 264 | ; RELOC-NEXT: - Type: ELEM | ||
| 265 | ; RELOC-NEXT: Segments: | ||
| 266 | ; RELOC-NEXT: - Offset: | ||
| 267 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 268 | ; RELOC-NEXT: Value: 1 | ||
| 269 | ; RELOC-NEXT: Functions: [ 0, 1, 2, 9, 10, 11 ] | ||
| 270 | ; RELOC-NEXT: - Type: CODE | ||
| 271 | ; RELOC-NEXT: Relocations: | ||
| 272 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | ||
| 273 | ; RELOC-NEXT: Index: 4 | ||
| 274 | ; RELOC-NEXT: Offset: 0x00000013 | ||
| 275 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | ||
| 276 | ; RELOC-NEXT: Index: 6 | ||
| 277 | ; RELOC-NEXT: Offset: 0x0000001C | ||
| 278 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | ||
| 279 | ; RELOC-NEXT: Index: 8 | ||
| 280 | ; RELOC-NEXT: Offset: 0x00000025 | ||
| 281 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB | ||
| 282 | ; RELOC-NEXT: Index: 0 | ||
| 283 | ; RELOC-NEXT: Offset: 0x0000002E | ||
| 284 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB | ||
| 285 | ; RELOC-NEXT: Index: 1 | ||
| 286 | ; RELOC-NEXT: Offset: 0x00000037 | ||
| 287 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB | ||
| 288 | ; RELOC-NEXT: Index: 2 | ||
| 289 | ; RELOC-NEXT: Offset: 0x00000040 | ||
| 290 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | ||
| 291 | ; RELOC-NEXT: Index: 16 | ||
| 292 | ; RELOC-NEXT: Offset: 0x00000058 | ||
| 293 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | ||
| 294 | ; RELOC-NEXT: Index: 18 | ||
| 295 | ; RELOC-NEXT: Offset: 0x00000061 | ||
| 296 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | ||
| 297 | ; RELOC-NEXT: Index: 20 | ||
| 298 | ; RELOC-NEXT: Offset: 0x0000006A | ||
| 299 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB | ||
| 300 | ; RELOC-NEXT: Index: 12 | ||
| 301 | ; RELOC-NEXT: Offset: 0x00000073 | ||
| 302 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB | ||
| 303 | ; RELOC-NEXT: Index: 13 | ||
| 304 | ; RELOC-NEXT: Offset: 0x0000007C | ||
| 305 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB | ||
| 306 | ; RELOC-NEXT: Index: 14 | ||
| 307 | ; RELOC-NEXT: Offset: 0x00000085 | ||
| 308 | ; RELOC-NEXT: Functions: | ||
| 309 | ; RELOC-NEXT: - Index: 0 | ||
| 310 | ; RELOC-NEXT: Locals: | ||
| 311 | ; RELOC-NEXT: Body: 41020B | ||
| 312 | ; RELOC-NEXT: - Index: 1 | ||
| 313 | ; RELOC-NEXT: Locals: | ||
| 314 | ; RELOC-NEXT: Body: 41020B | ||
| 315 | ; RELOC-NEXT: - Index: 2 | ||
| 316 | ; RELOC-NEXT: Locals: | ||
| 317 | ; RELOC-NEXT: Body: 41020B | ||
| 318 | ; RELOC-NEXT: - Index: 3 | ||
| 319 | ; RELOC-NEXT: Locals: | ||
| 320 | ; RELOC-NEXT: Body: 4180808080000B | ||
| 321 | ; RELOC-NEXT: - Index: 4 | ||
| 322 | ; RELOC-NEXT: Locals: | ||
| 323 | ; RELOC-NEXT: Body: 4188808080000B | ||
| 324 | ; RELOC-NEXT: - Index: 5 | ||
| 325 | ; RELOC-NEXT: Locals: | ||
| 326 | ; RELOC-NEXT: Body: 4190808080000B | ||
| 327 | ; RELOC-NEXT: - Index: 6 | ||
| 328 | ; RELOC-NEXT: Locals: | ||
| 329 | ; RELOC-NEXT: Body: 4181808080000B | ||
| 330 | ; RELOC-NEXT: - Index: 7 | ||
| 331 | ; RELOC-NEXT: Locals: | ||
| 332 | ; RELOC-NEXT: Body: 4182808080000B | ||
| 333 | ; RELOC-NEXT: - Index: 8 | ||
| 334 | ; RELOC-NEXT: Locals: | ||
| 335 | ; RELOC-NEXT: Body: 4183808080000B | ||
| 336 | ; RELOC-NEXT: - Index: 9 | ||
| 337 | ; RELOC-NEXT: Locals: | ||
| 338 | ; RELOC-NEXT: Body: 41020B | ||
| 339 | ; RELOC-NEXT: - Index: 10 | ||
| 340 | ; RELOC-NEXT: Locals: | ||
| 341 | ; RELOC-NEXT: Body: 41020B | ||
| 342 | ; RELOC-NEXT: - Index: 11 | ||
| 343 | ; RELOC-NEXT: Locals: | ||
| 344 | ; RELOC-NEXT: Body: 41020B | ||
| 345 | ; RELOC-NEXT: - Index: 12 | ||
| 346 | ; RELOC-NEXT: Locals: | ||
| 347 | ; RELOC-NEXT: Body: 4184808080000B | ||
| 348 | ; RELOC-NEXT: - Index: 13 | ||
| 349 | ; RELOC-NEXT: Locals: | ||
| 350 | ; RELOC-NEXT: Body: 418C808080000B | ||
| 351 | ; RELOC-NEXT: - Index: 14 | ||
| 352 | ; RELOC-NEXT: Locals: | ||
| 353 | ; RELOC-NEXT: Body: 4194808080000B | ||
| 354 | ; RELOC-NEXT: - Index: 15 | ||
| 355 | ; RELOC-NEXT: Locals: | ||
| 356 | ; RELOC-NEXT: Body: 4184808080000B | ||
| 357 | ; RELOC-NEXT: - Index: 16 | ||
| 358 | ; RELOC-NEXT: Locals: | ||
| 359 | ; RELOC-NEXT: Body: 4185808080000B | ||
| 360 | ; RELOC-NEXT: - Index: 17 | ||
| 361 | ; RELOC-NEXT: Locals: | ||
| 362 | ; RELOC-NEXT: Body: 4186808080000B | ||
| 363 | ; RELOC-NEXT: - Type: DATA | ||
| 364 | ; RELOC-NEXT: Segments: | ||
| 365 | ; RELOC-NEXT: - SectionOffset: 6 | ||
| 366 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 367 | ; RELOC-NEXT: Offset: | ||
| 368 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 369 | ; RELOC-NEXT: Value: 0 | ||
| 370 | ; RELOC-NEXT: Content: '0000000000000000' | ||
| 371 | ; RELOC-NEXT: - SectionOffset: 19 | ||
| 372 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 373 | ; RELOC-NEXT: Offset: | ||
| 374 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 375 | ; RELOC-NEXT: Value: 8 | ||
| 376 | ; RELOC-NEXT: Content: '0000000000000000' | ||
| 377 | ; RELOC-NEXT: - SectionOffset: 32 | ||
| 378 | ; RELOC-NEXT: MemoryIndex: 0 | ||
| 379 | ; RELOC-NEXT: Offset: | ||
| 380 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 381 | ; RELOC-NEXT: Value: 16 | ||
| 382 | ; RELOC-NEXT: Content: '0000000000000000' | ||
| 383 | ; RELOC-NEXT: - Type: CUSTOM | ||
| 384 | ; RELOC-NEXT: Name: linking | ||
| 385 | ; RELOC-NEXT: Version: 1 | ||
| 386 | ; RELOC-NEXT: SymbolTable: | ||
| 387 | ; RELOC-NEXT: - Index: 0 | ||
| 388 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 389 | ; RELOC-NEXT: Name: colliding_func1 | ||
| 390 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 391 | ; RELOC-NEXT: Function: 0 | ||
| 392 | ; RELOC-NEXT: - Index: 1 | ||
| 393 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 394 | ; RELOC-NEXT: Name: colliding_func2 | ||
| 395 | ; RELOC-NEXT: Flags: [ ] | ||
| 396 | ; RELOC-NEXT: Function: 1 | ||
| 397 | ; RELOC-NEXT: - Index: 2 | ||
| 398 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 399 | ; RELOC-NEXT: Name: colliding_func3 | ||
| 400 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 401 | ; RELOC-NEXT: Function: 2 | ||
| 402 | ; RELOC-NEXT: - Index: 3 | ||
| 403 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 404 | ; RELOC-NEXT: Name: get_global1A | ||
| 405 | ; RELOC-NEXT: Flags: [ ] | ||
| 406 | ; RELOC-NEXT: Function: 3 | ||
| 407 | ; RELOC-NEXT: - Index: 4 | ||
| 408 | ; RELOC-NEXT: Kind: DATA | ||
| 409 | ; RELOC-NEXT: Name: colliding_global1 | ||
| 410 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 411 | ; RELOC-NEXT: Segment: 0 | ||
| 412 | ; RELOC-NEXT: Size: 4 | ||
| 413 | ; RELOC-NEXT: - Index: 5 | ||
| 414 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 415 | ; RELOC-NEXT: Name: get_global2A | ||
| 416 | ; RELOC-NEXT: Flags: [ ] | ||
| 417 | ; RELOC-NEXT: Function: 4 | ||
| 418 | ; RELOC-NEXT: - Index: 6 | ||
| 419 | ; RELOC-NEXT: Kind: DATA | ||
| 420 | ; RELOC-NEXT: Name: colliding_global2 | ||
| 421 | ; RELOC-NEXT: Flags: [ ] | ||
| 422 | ; RELOC-NEXT: Segment: 1 | ||
| 423 | ; RELOC-NEXT: Size: 4 | ||
| 424 | ; RELOC-NEXT: - Index: 7 | ||
| 425 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 426 | ; RELOC-NEXT: Name: get_global3A | ||
| 427 | ; RELOC-NEXT: Flags: [ ] | ||
| 428 | ; RELOC-NEXT: Function: 5 | ||
| 429 | ; RELOC-NEXT: - Index: 8 | ||
| 430 | ; RELOC-NEXT: Kind: DATA | ||
| 431 | ; RELOC-NEXT: Name: colliding_global3 | ||
| 432 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 433 | ; RELOC-NEXT: Segment: 2 | ||
| 434 | ; RELOC-NEXT: Size: 4 | ||
| 435 | ; RELOC-NEXT: - Index: 9 | ||
| 436 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 437 | ; RELOC-NEXT: Name: get_func1A | ||
| 438 | ; RELOC-NEXT: Flags: [ ] | ||
| 439 | ; RELOC-NEXT: Function: 6 | ||
| 440 | ; RELOC-NEXT: - Index: 10 | ||
| 441 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 442 | ; RELOC-NEXT: Name: get_func2A | ||
| 443 | ; RELOC-NEXT: Flags: [ ] | ||
| 444 | ; RELOC-NEXT: Function: 7 | ||
| 445 | ; RELOC-NEXT: - Index: 11 | ||
| 446 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 447 | ; RELOC-NEXT: Name: get_func3A | ||
| 448 | ; RELOC-NEXT: Flags: [ ] | ||
| 449 | ; RELOC-NEXT: Function: 8 | ||
| 450 | ; RELOC-NEXT: - Index: 12 | ||
| 451 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 452 | ; RELOC-NEXT: Name: colliding_func1 | ||
| 453 | ; RELOC-NEXT: Flags: [ ] | ||
| 454 | ; RELOC-NEXT: Function: 9 | ||
| 455 | ; RELOC-NEXT: - Index: 13 | ||
| 456 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 457 | ; RELOC-NEXT: Name: colliding_func2 | ||
| 458 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 459 | ; RELOC-NEXT: Function: 10 | ||
| 460 | ; RELOC-NEXT: - Index: 14 | ||
| 461 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 462 | ; RELOC-NEXT: Name: colliding_func3 | ||
| 463 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 464 | ; RELOC-NEXT: Function: 11 | ||
| 465 | ; RELOC-NEXT: - Index: 15 | ||
| 466 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 467 | ; RELOC-NEXT: Name: get_global1B | ||
| 468 | ; RELOC-NEXT: Flags: [ ] | ||
| 469 | ; RELOC-NEXT: Function: 12 | ||
| 470 | ; RELOC-NEXT: - Index: 16 | ||
| 471 | ; RELOC-NEXT: Kind: DATA | ||
| 472 | ; RELOC-NEXT: Name: colliding_global1 | ||
| 473 | ; RELOC-NEXT: Flags: [ ] | ||
| 474 | ; RELOC-NEXT: Segment: 0 | ||
| 475 | ; RELOC-NEXT: Offset: 4 | ||
| 476 | ; RELOC-NEXT: Size: 4 | ||
| 477 | ; RELOC-NEXT: - Index: 17 | ||
| 478 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 479 | ; RELOC-NEXT: Name: get_global2B | ||
| 480 | ; RELOC-NEXT: Flags: [ ] | ||
| 481 | ; RELOC-NEXT: Function: 13 | ||
| 482 | ; RELOC-NEXT: - Index: 18 | ||
| 483 | ; RELOC-NEXT: Kind: DATA | ||
| 484 | ; RELOC-NEXT: Name: colliding_global2 | ||
| 485 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 486 | ; RELOC-NEXT: Segment: 1 | ||
| 487 | ; RELOC-NEXT: Offset: 4 | ||
| 488 | ; RELOC-NEXT: Size: 4 | ||
| 489 | ; RELOC-NEXT: - Index: 19 | ||
| 490 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 491 | ; RELOC-NEXT: Name: get_global3B | ||
| 492 | ; RELOC-NEXT: Flags: [ ] | ||
| 493 | ; RELOC-NEXT: Function: 14 | ||
| 494 | ; RELOC-NEXT: - Index: 20 | ||
| 495 | ; RELOC-NEXT: Kind: DATA | ||
| 496 | ; RELOC-NEXT: Name: colliding_global3 | ||
| 497 | ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] | ||
| 498 | ; RELOC-NEXT: Segment: 2 | ||
| 499 | ; RELOC-NEXT: Offset: 4 | ||
| 500 | ; RELOC-NEXT: Size: 4 | ||
| 501 | ; RELOC-NEXT: - Index: 21 | ||
| 502 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 503 | ; RELOC-NEXT: Name: get_func1B | ||
| 504 | ; RELOC-NEXT: Flags: [ ] | ||
| 505 | ; RELOC-NEXT: Function: 15 | ||
| 506 | ; RELOC-NEXT: - Index: 22 | ||
| 507 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 508 | ; RELOC-NEXT: Name: get_func2B | ||
| 509 | ; RELOC-NEXT: Flags: [ ] | ||
| 510 | ; RELOC-NEXT: Function: 16 | ||
| 511 | ; RELOC-NEXT: - Index: 23 | ||
| 512 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 513 | ; RELOC-NEXT: Name: get_func3B | ||
| 514 | ; RELOC-NEXT: Flags: [ ] | ||
| 515 | ; RELOC-NEXT: Function: 17 | ||
| 516 | ; RELOC-NEXT: SegmentInfo: | ||
| 517 | ; RELOC-NEXT: - Index: 0 | ||
| 518 | ; RELOC-NEXT: Name: .bss.colliding_global1 | ||
| 519 | ; RELOC-NEXT: Alignment: 4 | ||
| 520 | ; RELOC-NEXT: Flags: [ ] | ||
| 521 | ; RELOC-NEXT: - Index: 1 | ||
| 522 | ; RELOC-NEXT: Name: .bss.colliding_global2 | ||
| 523 | ; RELOC-NEXT: Alignment: 4 | ||
| 524 | ; RELOC-NEXT: Flags: [ ] | ||
| 525 | ; RELOC-NEXT: - Index: 2 | ||
| 526 | ; RELOC-NEXT: Name: .bss.colliding_global3 | ||
| 527 | ; RELOC-NEXT: Alignment: 4 | ||
| 528 | ; RELOC-NEXT: Flags: [ ] | ||
| 529 | ; RELOC-NEXT: - Type: CUSTOM | ||
| 530 | ; RELOC-NEXT: Name: name | ||
| 531 | ; RELOC-NEXT: FunctionNames: | ||
| 532 | ; RELOC-NEXT: - Index: 0 | ||
| 533 | ; RELOC-NEXT: Name: colliding_func1 | ||
| 534 | ; RELOC-NEXT: - Index: 1 | ||
| 535 | ; RELOC-NEXT: Name: colliding_func2 | ||
| 536 | ; RELOC-NEXT: - Index: 2 | ||
| 537 | ; RELOC-NEXT: Name: colliding_func3 | ||
| 538 | ; RELOC-NEXT: - Index: 3 | ||
| 539 | ; RELOC-NEXT: Name: get_global1A | ||
| 540 | ; RELOC-NEXT: - Index: 4 | ||
| 541 | ; RELOC-NEXT: Name: get_global2A | ||
| 542 | ; RELOC-NEXT: - Index: 5 | ||
| 543 | ; RELOC-NEXT: Name: get_global3A | ||
| 544 | ; RELOC-NEXT: - Index: 6 | ||
| 545 | ; RELOC-NEXT: Name: get_func1A | ||
| 546 | ; RELOC-NEXT: - Index: 7 | ||
| 547 | ; RELOC-NEXT: Name: get_func2A | ||
| 548 | ; RELOC-NEXT: - Index: 8 | ||
| 549 | ; RELOC-NEXT: Name: get_func3A | ||
| 550 | ; RELOC-NEXT: - Index: 9 | ||
| 551 | ; RELOC-NEXT: Name: colliding_func1 | ||
| 552 | ; RELOC-NEXT: - Index: 10 | ||
| 553 | ; RELOC-NEXT: Name: colliding_func2 | ||
| 554 | ; RELOC-NEXT: - Index: 11 | ||
| 555 | ; RELOC-NEXT: Name: colliding_func3 | ||
| 556 | ; RELOC-NEXT: - Index: 12 | ||
| 557 | ; RELOC-NEXT: Name: get_global1B | ||
| 558 | ; RELOC-NEXT: - Index: 13 | ||
| 559 | ; RELOC-NEXT: Name: get_global2B | ||
| 560 | ; RELOC-NEXT: - Index: 14 | ||
| 561 | ; RELOC-NEXT: Name: get_global3B | ||
| 562 | ; RELOC-NEXT: - Index: 15 | ||
| 563 | ; RELOC-NEXT: Name: get_func1B | ||
| 564 | ; RELOC-NEXT: - Index: 16 | ||
| 565 | ; RELOC-NEXT: Name: get_func2B | ||
| 566 | ; RELOC-NEXT: - Index: 17 | ||
| 567 | ; RELOC-NEXT: Name: get_func3B | ||
| 568 | ; RELOC-NEXT: ... | ||
deps/lld/test/wasm/lto/Inputs/archive.ll created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 2 | target triple = "wasm32-unknown-unknown" | ||
| 3 | |||
| 4 | define void @f() { | ||
| 5 | ret void | ||
| 6 | } | ||
deps/lld/test/wasm/lto/Inputs/cache.ll created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 2 | target triple = "wasm32-unknown-unknown" | ||
| 3 | |||
| 4 | define i32 @_start() { | ||
| 5 | entry: | ||
| 6 | call void (...) @globalfunc() | ||
| 7 | ret i32 0 | ||
| 8 | } | ||
| 9 | |||
| 10 | declare void @globalfunc(...) | ||
deps/lld/test/wasm/lto/Inputs/save-temps.ll created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 2 | target triple = "wasm32-unknown-unknown" | ||
| 3 | |||
| 4 | define void @bar() { | ||
| 5 | ret void | ||
| 6 | } | ||
deps/lld/test/wasm/lto/Inputs/thinlto.ll created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 2 | target triple = "wasm32-unknown-unknown" | ||
| 3 | |||
| 4 | define void @g() { | ||
| 5 | entry: | ||
| 6 | ret void | ||
| 7 | } | ||
deps/lld/test/wasm/lto/Inputs/used.ll created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 2 | target triple = "wasm32-unknown-unknown" | ||
| 3 | |||
| 4 | @foo = hidden global i32 1 | ||
| 5 | |||
| 6 | define hidden void @bar() { | ||
| 7 | ret void | ||
| 8 | } | ||
deps/lld/test/wasm/lto/archive.ll created+25| ... | @@ -0,0 +1,25 @@ | ||
| 1 | ; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o | ||
| 2 | ; RUN: rm -f %t.a | ||
| 3 | ; RUN: llvm-ar rcs %t.a %t1.o | ||
| 4 | ; RUN: llvm-as %s -o %t2.o | ||
| 5 | ; RUN: wasm-ld %t2.o %t.a -o %t3 | ||
| 6 | ; RUN: obj2yaml %t3 | FileCheck %s | ||
| 7 | |||
| 8 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 9 | target triple = "wasm32-unknown-unknown" | ||
| 10 | |||
| 11 | define void @_start() { | ||
| 12 | call void @f() | ||
| 13 | ret void | ||
| 14 | } | ||
| 15 | |||
| 16 | declare void @f() | ||
| 17 | |||
| 18 | ; CHECK: Name: name | ||
| 19 | ; CHECK-NEXT: FunctionNames: | ||
| 20 | ; CHECK-NEXT: - Index: 0 | ||
| 21 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 22 | ; CHECK-NEXT: - Index: 1 | ||
| 23 | ; CHECK-NEXT: Name: _start | ||
| 24 | ; CHECK-NEXT: - Index: 2 | ||
| 25 | ; CHECK-NEXT: Name: f | ||
deps/lld/test/wasm/lto/atomics.ll created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | ; RUN: llvm-as %s -o %t.o | ||
| 2 | ; 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). | ||
| 5 | |||
| 6 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 7 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 8 | |||
| 9 | @foo = hidden global i32 1 | ||
| 10 | |||
| 11 | define void @_start() { | ||
| 12 | %1 = load atomic i32, i32* @foo unordered, align 4 | ||
| 13 | ret void | ||
| 14 | } | ||
deps/lld/test/wasm/lto/cache.ll created+38| ... | @@ -0,0 +1,38 @@ | ||
| 1 | ; RUN: opt -module-hash -module-summary %s -o %t.o | ||
| 2 | ; RUN: opt -module-hash -module-summary %p/Inputs/cache.ll -o %t2.o | ||
| 3 | |||
| 4 | ; RUN: rm -Rf %t.cache && mkdir %t.cache | ||
| 5 | ; Create two files that would be removed by cache pruning due to age. | ||
| 6 | ; We should only remove files matching the pattern "llvmcache-*". | ||
| 7 | ; RUN: touch -t 197001011200 %t.cache/llvmcache-foo %t.cache/foo | ||
| 8 | ; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=1h:prune_interval=0s -o %t.wasm %t2.o %t.o | ||
| 9 | |||
| 10 | ; Two cached objects, plus a timestamp file and "foo", minus the file we removed. | ||
| 11 | ; RUN: ls %t.cache | count 4 | ||
| 12 | |||
| 13 | ; Create a file of size 64KB. | ||
| 14 | ; RUN: "%python" -c "print(' ' * 65536)" > %t.cache/llvmcache-foo | ||
| 15 | |||
| 16 | ; This should leave the file in place. | ||
| 17 | ; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t.wasm %t2.o %t.o | ||
| 18 | ; RUN: ls %t.cache | count 5 | ||
| 19 | |||
| 20 | ; This should remove it. | ||
| 21 | ; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t.wasm %t2.o %t.o | ||
| 22 | ; RUN: ls %t.cache | count 4 | ||
| 23 | |||
| 24 | ; Setting max number of files to 0 should disable the limit, not delete everything. | ||
| 25 | ; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=0:prune_interval=0s -o %t.wasm %t2.o %t.o | ||
| 26 | ; RUN: ls %t.cache | count 4 | ||
| 27 | |||
| 28 | ; Delete everything except for the timestamp, "foo" and one cache file. | ||
| 29 | ; RUN: wasm-ld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=1:prune_interval=0s -o %t.wasm %t2.o %t.o | ||
| 30 | ; RUN: ls %t.cache | count 3 | ||
| 31 | |||
| 32 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 33 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 34 | |||
| 35 | define void @globalfunc() #0 { | ||
| 36 | entry: | ||
| 37 | ret void | ||
| 38 | } | ||
deps/lld/test/wasm/lto/diagnostics.ll created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | ; verify that errors in the LLVM backend during LTO manifest as lld | ||
| 2 | ; errors | ||
| 3 | |||
| 4 | ; RUN: llvm-as %s -o %t.o | ||
| 5 | ; RUN: not wasm-ld --lto-O0 %t.o -o %t2 2>&1 | FileCheck %s | ||
| 6 | |||
| 7 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 8 | target triple = "wasm32-unknown-unknown" | ||
| 9 | |||
| 10 | define void @_start() { | ||
| 11 | call i8* @foo() | ||
| 12 | ret void | ||
| 13 | } | ||
| 14 | |||
| 15 | define i8* @foo() { | ||
| 16 | %1 = call i8* @llvm.returnaddress(i32 0) | ||
| 17 | ret i8* %1 | ||
| 18 | } | ||
| 19 | |||
| 20 | declare i8* @llvm.returnaddress(i32) | ||
| 21 | |||
| 22 | ; CHECK: error: {{.*}} WebAssembly hasn't implemented __builtin_return_address | ||
deps/lld/test/wasm/lto/export.ll created+38| ... | @@ -0,0 +1,38 @@ | ||
| 1 | ; RUN: llvm-as -o %t.bc %s | ||
| 2 | ; RUN: not wasm-ld --export=missing -o %t.wasm %t.bc 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s | ||
| 3 | ; RUN: wasm-ld --export=hidden_function -o %t.wasm %t.bc | ||
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 7 | target triple = "wasm32-unknown-unknown" | ||
| 8 | |||
| 9 | define hidden i32 @hidden_function() local_unnamed_addr { | ||
| 10 | entry: | ||
| 11 | ret i32 0 | ||
| 12 | } | ||
| 13 | |||
| 14 | define void @_start() local_unnamed_addr { | ||
| 15 | entry: | ||
| 16 | ret void | ||
| 17 | } | ||
| 18 | |||
| 19 | ; CHECK-ERROR: error: symbol exported via --export not found: missing | ||
| 20 | |||
| 21 | ; CHECK: - Type: EXPORT | ||
| 22 | ; CHECK-NEXT: Exports: | ||
| 23 | ; CHECK-NEXT: - Name: memory | ||
| 24 | ; CHECK-NEXT: Kind: MEMORY | ||
| 25 | ; 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 | ||
| 32 | ; CHECK-NEXT: - Name: _start | ||
| 33 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 34 | ; CHECK-NEXT: Index: 2 | ||
| 35 | ; CHECK-NEXT: - Name: hidden_function | ||
| 36 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 37 | ; CHECK-NEXT: Index: 1 | ||
| 38 | ; CHECK-NEXT: - Type: CODE | ||
deps/lld/test/wasm/lto/incompatible.ll created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | ; REQUIRES: x86 | ||
| 2 | ; RUN: llvm-as %s -o %t.bc | ||
| 3 | ; RUN: not wasm-ld %t.bc -o out.wasm 2>&1 | FileCheck %s | ||
| 4 | |||
| 5 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
| 6 | target triple = "x86_64-unknown-linux-gnu" | ||
| 7 | |||
| 8 | ; CHECK: {{.*}}incompatible.ll.tmp.bc: machine type must be wasm32 | ||
deps/lld/test/wasm/lto/internalize-basic.ll created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | ; RUN: llvm-as %s -o %t.o | ||
| 2 | ; RUN: wasm-ld %t.o -o %t2 -save-temps | ||
| 3 | ; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s | ||
| 4 | |||
| 5 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 6 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 7 | |||
| 8 | define void @_start() { | ||
| 9 | ret void | ||
| 10 | } | ||
| 11 | |||
| 12 | define hidden void @foo() { | ||
| 13 | ret void | ||
| 14 | } | ||
| 15 | |||
| 16 | ; Check that _start is not internalized. | ||
| 17 | ; CHECK: define void @_start() | ||
| 18 | |||
| 19 | ; Check that foo function is correctly internalized. | ||
| 20 | ; CHECK: define internal void @foo() | ||
deps/lld/test/wasm/lto/lto-start.ll created+18| ... | @@ -0,0 +1,18 @@ | ||
| 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 | ; CHECK: - Type: CUSTOM | ||
| 6 | ; CHECK-NEXT: Name: name | ||
| 7 | ; CHECK-NEXT: FunctionNames: | ||
| 8 | ; CHECK-NEXT: - Index: 0 | ||
| 9 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 10 | ; CHECK-NEXT: - Index: 1 | ||
| 11 | ; CHECK-NEXT: Name: _start | ||
| 12 | |||
| 13 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 14 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 15 | |||
| 16 | define void @_start() { | ||
| 17 | ret void | ||
| 18 | } | ||
deps/lld/test/wasm/lto/opt-level.ll created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | ; RUN: llvm-as -o %t.o %s | ||
| 2 | ; RUN: wasm-ld -o %t0 -e main --lto-O0 %t.o | ||
| 3 | ; RUN: obj2yaml %t0 | FileCheck --check-prefix=CHECK-O0 %s | ||
| 4 | ; RUN: wasm-ld -o %t2 -e main --lto-O2 %t.o | ||
| 5 | ; RUN: obj2yaml %t2 | FileCheck --check-prefix=CHECK-O2 %s | ||
| 6 | ; RUN: wasm-ld -o %t2a -e main %t.o | ||
| 7 | ; RUN: obj2yaml %t2a | FileCheck --check-prefix=CHECK-O2 %s | ||
| 8 | |||
| 9 | ; Reject invalid optimization levels. | ||
| 10 | ; RUN: not ld.lld -o %t3 -e main --lto-O6 %t.o 2>&1 | \ | ||
| 11 | ; RUN: FileCheck --check-prefix=INVALID %s | ||
| 12 | ; INVALID: invalid optimization level for LTO: 6 | ||
| 13 | |||
| 14 | ; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \ | ||
| 15 | ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s | ||
| 16 | ; INVALIDNEGATIVE: invalid optimization level for LTO: 4294967295 | ||
| 17 | |||
| 18 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 19 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 20 | |||
| 21 | ; CHECK-O0: Name: foo | ||
| 22 | ; CHECK-O2-NOT: Name: foo | ||
| 23 | define internal void @foo() { | ||
| 24 | ret void | ||
| 25 | } | ||
| 26 | |||
| 27 | define void @main() { | ||
| 28 | call void @foo() | ||
| 29 | ret void | ||
| 30 | } | ||
deps/lld/test/wasm/lto/parallel.ll created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | ; RUN: llvm-as -o %t.bc %s | ||
| 2 | ; RUN: rm -f %t.lto.o %t1.lto.o | ||
| 3 | ; RUN: wasm-ld --lto-partitions=2 -save-temps -o %t %t.bc -r | ||
| 4 | ; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s | ||
| 5 | ; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s | ||
| 6 | |||
| 7 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 8 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 9 | |||
| 10 | ; CHECK0-NOT: bar | ||
| 11 | ; CHECK0: T foo | ||
| 12 | ; CHECK0-NOT: bar | ||
| 13 | define void @foo() { | ||
| 14 | call void @bar() | ||
| 15 | ret void | ||
| 16 | } | ||
| 17 | |||
| 18 | ; CHECK1-NOT: foo | ||
| 19 | ; CHECK1: T bar | ||
| 20 | ; CHECK1-NOT: foo | ||
| 21 | define void @bar() { | ||
| 22 | call void @foo() | ||
| 23 | ret void | ||
| 24 | } | ||
deps/lld/test/wasm/lto/save-temps.ll created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | ; RUN: cd %T | ||
| 2 | ; RUN: rm -f a.out a.out.lto.bc a.out.lto.o | ||
| 3 | ; RUN: llvm-as %s -o %t.o | ||
| 4 | ; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o | ||
| 5 | ; RUN: wasm-ld -r -o a.out %t.o %t2.o -save-temps | ||
| 6 | ; RUN: llvm-nm a.out | FileCheck %s | ||
| 7 | ; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s | ||
| 8 | ; RUN: llvm-nm a.out.lto.o | FileCheck %s | ||
| 9 | ; RUN: llvm-dis a.out.0.0.preopt.bc | ||
| 10 | |||
| 11 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 12 | target triple = "wasm32-unknown-unknown" | ||
| 13 | |||
| 14 | define void @foo() { | ||
| 15 | ret void | ||
| 16 | } | ||
| 17 | |||
| 18 | ; CHECK: T bar | ||
| 19 | ; CHECK: T foo | ||
deps/lld/test/wasm/lto/thinlto.ll created+34| ... | @@ -0,0 +1,34 @@ | ||
| 1 | ; Basic ThinLTO tests. | ||
| 2 | ; RUN: opt -module-summary %s -o %t1.o | ||
| 3 | ; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o | ||
| 4 | |||
| 5 | ; First force single-threaded mode | ||
| 6 | ; RUN: rm -f %t31.lto.o %t32.lto.o | ||
| 7 | ; RUN: wasm-ld -r -save-temps --thinlto-jobs=1 %t1.o %t2.o -o %t3 | ||
| 8 | ; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1 | ||
| 9 | ; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2 | ||
| 10 | |||
| 11 | ; Next force multi-threaded mode | ||
| 12 | ; RUN: rm -f %t31.lto.o %t32.lto.o | ||
| 13 | ; RUN: wasm-ld -r -save-temps --thinlto-jobs=2 %t1.o %t2.o -o %t3 | ||
| 14 | ; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1 | ||
| 15 | ; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2 | ||
| 16 | |||
| 17 | ; Check without --thinlto-jobs (which currently default to hardware_concurrency) | ||
| 18 | ; RUN: wasm-ld -r %t1.o %t2.o -o %t3 | ||
| 19 | ; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1 | ||
| 20 | ; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2 | ||
| 21 | |||
| 22 | ; NM1: T f | ||
| 23 | ; NM2: T g | ||
| 24 | |||
| 25 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 26 | target triple = "wasm32-unknown-unknown" | ||
| 27 | |||
| 28 | declare void @g(...) | ||
| 29 | |||
| 30 | define void @f() { | ||
| 31 | entry: | ||
| 32 | call void (...) @g() | ||
| 33 | ret void | ||
| 34 | } | ||
deps/lld/test/wasm/lto/undef.ll created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | ; RUN: llvm-as %s -o %t.o | ||
| 2 | ; RUN: wasm-ld %t.o -o %t.wasm --allow-undefined | ||
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 4 | |||
| 5 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 6 | target triple = "wasm32-unknown-unknown" | ||
| 7 | |||
| 8 | declare void @bar() | ||
| 9 | |||
| 10 | define void @_start() { | ||
| 11 | call void @bar() | ||
| 12 | ret void | ||
| 13 | } | ||
| 14 | |||
| 15 | ; CHECK: - Type: IMPORT | ||
| 16 | ; CHECK-NEXT: Imports: | ||
| 17 | ; CHECK-NEXT: - Module: env | ||
| 18 | ; CHECK-NEXT: Field: bar | ||
| 19 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 20 | ; CHECK-NEXT: SigIndex: 0 | ||
deps/lld/test/wasm/lto/used.ll created+45| ... | @@ -0,0 +1,45 @@ | ||
| 1 | ; RUN: llc %s -o %t.o -filetype=obj | ||
| 2 | ; RUN: llvm-as %S/Inputs/used.ll -o %t1.o | ||
| 3 | ; RUN: wasm-ld %t.o %t1.o -o %t.wasm | ||
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | ; Verify that symbols references from regular objects are preserved by LTO | ||
| 7 | |||
| 8 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 9 | target triple = "wasm32-unknown-unknown" | ||
| 10 | |||
| 11 | declare void @bar() | ||
| 12 | |||
| 13 | @foo = external global i32 | ||
| 14 | |||
| 15 | define void @_start() { | ||
| 16 | %val = load i32, i32* @foo, align 4 | ||
| 17 | %tobool = icmp ne i32 %val, 0 | ||
| 18 | br i1 %tobool, label %callbar, label %return | ||
| 19 | |||
| 20 | callbar: | ||
| 21 | call void @bar() | ||
| 22 | br label %return | ||
| 23 | |||
| 24 | return: | ||
| 25 | ret void | ||
| 26 | } | ||
| 27 | |||
| 28 | ; CHECK: - Type: DATA | ||
| 29 | ; CHECK-NEXT: Segments: | ||
| 30 | ; CHECK-NEXT: - SectionOffset: 7 | ||
| 31 | ; CHECK-NEXT: MemoryIndex: 0 | ||
| 32 | ; CHECK-NEXT: Offset: | ||
| 33 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 34 | ; CHECK-NEXT: Value: 1024 | ||
| 35 | ; CHECK-NEXT: Content: '01000000' | ||
| 36 | |||
| 37 | ; CHECK: - Type: CUSTOM | ||
| 38 | ; CHECK-NEXT: Name: name | ||
| 39 | ; CHECK-NEXT: FunctionNames: | ||
| 40 | ; CHECK-NEXT: - Index: 0 | ||
| 41 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 42 | ; CHECK-NEXT: - Index: 1 | ||
| 43 | ; CHECK-NEXT: Name: _start | ||
| 44 | ; CHECK-NEXT: - Index: 2 | ||
| 45 | ; CHECK-NEXT: Name: bar | ||
deps/lld/test/wasm/lto/verify-invalid.ll created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | ; RUN: llvm-as %s -o %t.o | ||
| 2 | ; RUN: wasm-ld %t.o -o %t2 -mllvm -debug-pass=Arguments \ | ||
| 3 | ; RUN: 2>&1 | FileCheck -check-prefix=DEFAULT %s | ||
| 4 | ; RUN: wasm-ld %t.o -o %t2 -mllvm -debug-pass=Arguments \ | ||
| 5 | ; RUN: -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s | ||
| 6 | |||
| 7 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 8 | target triple = "wasm32-unknown-unknown" | ||
| 9 | |||
| 10 | define void @_start() { | ||
| 11 | ret void | ||
| 12 | } | ||
| 13 | |||
| 14 | ; -disable-verify should disable the verification of bitcode. | ||
| 15 | ; DEFAULT: Pass Arguments: {{.*}} -verify {{.*}} -verify | ||
| 16 | ; DISABLE-NOT: Pass Arguments: {{.*}} -verify {{.*}} -verify | ||
deps/lld/test/wasm/lto/weak.ll created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | ; RUN: llvm-as %s -o %t.o | ||
| 2 | ; RUN: wasm-ld %t.o %t.o -o %t.wasm -r | ||
| 3 | ; RUN: llvm-readobj -t %t.wasm | FileCheck %s | ||
| 4 | |||
| 5 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" | ||
| 6 | target triple = "wasm32-unknown-unknown-wasm" | ||
| 7 | |||
| 8 | define weak void @f() { | ||
| 9 | ret void | ||
| 10 | } | ||
| 11 | |||
| 12 | ; CHECK: Symbol { | ||
| 13 | ; CHECK-NEXT: Name: f | ||
| 14 | ; CHECK-NEXT: Type: FUNCTION (0x0) | ||
| 15 | ; CHECK-NEXT: Flags: 0x1 | ||
| 16 | ; CHECK-NEXT: } | ||
deps/lld/test/wasm/many-functions.ll+1059-264| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/many-funcs.ll -o %t.many.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/many-funcs.ll -o %t.many.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 2 | ; RUN: llc -filetype=obj %s -o %t.o |
| 3 | ; RUN: lld -flavor wasm -r -o %t.wasm %t.many.o %t.o | 3 | ; RUN: wasm-ld -r -o %t.wasm %t.many.o %t.o |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 5 | 5 | ||
| 6 | ; Test that relocations within the CODE section correctly handle | 6 | ; Test that relocations within the CODE section correctly handle |
| ... | @@ -8,6 +8,8 @@ | ... | @@ -8,6 +8,8 @@ |
| 8 | ; 128 function and so the final output requires a 2-byte LEB in | 8 | ; 128 function and so the final output requires a 2-byte LEB in |
| 9 | ; the CODE section header to store the function count. | 9 | ; the CODE section header to store the function count. |
| 10 | 10 | ||
| 11 | target triple = "wasm32-unknown-unknown" | ||
| 12 | |||
| 11 | define i32 @func() { | 13 | define i32 @func() { |
| 12 | entry: | 14 | entry: |
| 13 | %call = tail call i32 @func() | 15 | %call = tail call i32 @func() |
| ... | @@ -17,655 +19,785 @@ entry: | ... | @@ -17,655 +19,785 @@ entry: |
| 17 | ; CHECK: - Type: CODE | 19 | ; CHECK: - Type: CODE |
| 18 | ; CHECK-NEXT: Relocations: | 20 | ; CHECK-NEXT: Relocations: |
| 19 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 21 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 20 | ; CHECK-NEXT: Index: 0 | 22 | ; CHECK-NEXT: Index: 1 |
| 21 | ; CHECK-NEXT: Offset: 0x00000008 | 23 | ; CHECK-NEXT: Offset: 0x00000008 |
| 22 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 24 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 23 | ; CHECK-NEXT: Index: 0 | 25 | ; CHECK-NEXT: Index: 1 |
| 24 | ; CHECK-NEXT: Offset: 0x00000014 | 26 | ; CHECK-NEXT: Offset: 0x00000014 |
| 25 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 27 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 26 | ; CHECK-NEXT: Index: 0 | 28 | ; CHECK-NEXT: Index: 1 |
| 27 | ; CHECK-NEXT: Offset: 0x00000020 | 29 | ; CHECK-NEXT: Offset: 0x00000020 |
| 28 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 30 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 29 | ; CHECK-NEXT: Index: 0 | 31 | ; CHECK-NEXT: Index: 1 |
| 30 | ; CHECK-NEXT: Offset: 0x0000002C | 32 | ; CHECK-NEXT: Offset: 0x0000002C |
| 31 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 33 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 32 | ; CHECK-NEXT: Index: 0 | 34 | ; CHECK-NEXT: Index: 1 |
| 33 | ; CHECK-NEXT: Offset: 0x00000038 | 35 | ; CHECK-NEXT: Offset: 0x00000038 |
| 34 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 36 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 35 | ; CHECK-NEXT: Index: 0 | 37 | ; CHECK-NEXT: Index: 1 |
| 36 | ; CHECK-NEXT: Offset: 0x00000044 | 38 | ; CHECK-NEXT: Offset: 0x00000044 |
| 37 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 39 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 38 | ; CHECK-NEXT: Index: 0 | 40 | ; CHECK-NEXT: Index: 1 |
| 39 | ; CHECK-NEXT: Offset: 0x00000050 | 41 | ; CHECK-NEXT: Offset: 0x00000050 |
| 40 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 42 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 41 | ; CHECK-NEXT: Index: 0 | 43 | ; CHECK-NEXT: Index: 1 |
| 42 | ; CHECK-NEXT: Offset: 0x0000005C | 44 | ; CHECK-NEXT: Offset: 0x0000005C |
| 43 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 45 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 44 | ; CHECK-NEXT: Index: 0 | 46 | ; CHECK-NEXT: Index: 1 |
| 45 | ; CHECK-NEXT: Offset: 0x00000068 | 47 | ; CHECK-NEXT: Offset: 0x00000068 |
| 46 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 48 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 47 | ; CHECK-NEXT: Index: 0 | 49 | ; CHECK-NEXT: Index: 1 |
| 48 | ; CHECK-NEXT: Offset: 0x00000074 | 50 | ; CHECK-NEXT: Offset: 0x00000074 |
| 49 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 51 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 50 | ; CHECK-NEXT: Index: 0 | 52 | ; CHECK-NEXT: Index: 1 |
| 51 | ; CHECK-NEXT: Offset: 0x00000080 | 53 | ; CHECK-NEXT: Offset: 0x00000080 |
| 52 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 54 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 53 | ; CHECK-NEXT: Index: 0 | 55 | ; CHECK-NEXT: Index: 1 |
| 54 | ; CHECK-NEXT: Offset: 0x0000008C | 56 | ; CHECK-NEXT: Offset: 0x0000008C |
| 55 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 57 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 56 | ; CHECK-NEXT: Index: 0 | 58 | ; CHECK-NEXT: Index: 1 |
| 57 | ; CHECK-NEXT: Offset: 0x00000098 | 59 | ; CHECK-NEXT: Offset: 0x00000098 |
| 58 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 60 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 59 | ; CHECK-NEXT: Index: 0 | 61 | ; CHECK-NEXT: Index: 1 |
| 60 | ; CHECK-NEXT: Offset: 0x000000A4 | 62 | ; CHECK-NEXT: Offset: 0x000000A4 |
| 61 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 63 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 62 | ; CHECK-NEXT: Index: 0 | 64 | ; CHECK-NEXT: Index: 1 |
| 63 | ; CHECK-NEXT: Offset: 0x000000B0 | 65 | ; CHECK-NEXT: Offset: 0x000000B0 |
| 64 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 66 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 65 | ; CHECK-NEXT: Index: 0 | 67 | ; CHECK-NEXT: Index: 1 |
| 66 | ; CHECK-NEXT: Offset: 0x000000BC | 68 | ; CHECK-NEXT: Offset: 0x000000BC |
| 67 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 69 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 68 | ; CHECK-NEXT: Index: 0 | 70 | ; CHECK-NEXT: Index: 1 |
| 69 | ; CHECK-NEXT: Offset: 0x000000C8 | 71 | ; CHECK-NEXT: Offset: 0x000000C8 |
| 70 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 72 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 71 | ; CHECK-NEXT: Index: 0 | 73 | ; CHECK-NEXT: Index: 1 |
| 72 | ; CHECK-NEXT: Offset: 0x000000D4 | 74 | ; CHECK-NEXT: Offset: 0x000000D4 |
| 73 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 75 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 74 | ; CHECK-NEXT: Index: 0 | 76 | ; CHECK-NEXT: Index: 1 |
| 75 | ; CHECK-NEXT: Offset: 0x000000E0 | 77 | ; CHECK-NEXT: Offset: 0x000000E0 |
| 76 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 78 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 77 | ; CHECK-NEXT: Index: 0 | 79 | ; CHECK-NEXT: Index: 1 |
| 78 | ; CHECK-NEXT: Offset: 0x000000EC | 80 | ; CHECK-NEXT: Offset: 0x000000EC |
| 79 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 81 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 80 | ; CHECK-NEXT: Index: 0 | 82 | ; CHECK-NEXT: Index: 1 |
| 81 | ; CHECK-NEXT: Offset: 0x000000F8 | 83 | ; CHECK-NEXT: Offset: 0x000000F8 |
| 82 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 84 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 83 | ; CHECK-NEXT: Index: 0 | 85 | ; CHECK-NEXT: Index: 1 |
| 84 | ; CHECK-NEXT: Offset: 0x00000104 | 86 | ; CHECK-NEXT: Offset: 0x00000104 |
| 85 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 87 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 86 | ; CHECK-NEXT: Index: 0 | 88 | ; CHECK-NEXT: Index: 1 |
| 87 | ; CHECK-NEXT: Offset: 0x00000110 | 89 | ; CHECK-NEXT: Offset: 0x00000110 |
| 88 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 90 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 89 | ; CHECK-NEXT: Index: 0 | 91 | ; CHECK-NEXT: Index: 1 |
| 90 | ; CHECK-NEXT: Offset: 0x0000011C | 92 | ; CHECK-NEXT: Offset: 0x0000011C |
| 91 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 93 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 92 | ; CHECK-NEXT: Index: 0 | 94 | ; CHECK-NEXT: Index: 1 |
| 93 | ; CHECK-NEXT: Offset: 0x00000128 | 95 | ; CHECK-NEXT: Offset: 0x00000128 |
| 94 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 96 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 95 | ; CHECK-NEXT: Index: 0 | 97 | ; CHECK-NEXT: Index: 1 |
| 96 | ; CHECK-NEXT: Offset: 0x00000134 | 98 | ; CHECK-NEXT: Offset: 0x00000134 |
| 97 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 99 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 98 | ; CHECK-NEXT: Index: 0 | 100 | ; CHECK-NEXT: Index: 1 |
| 99 | ; CHECK-NEXT: Offset: 0x00000140 | 101 | ; CHECK-NEXT: Offset: 0x00000140 |
| 100 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 102 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 101 | ; CHECK-NEXT: Index: 0 | 103 | ; CHECK-NEXT: Index: 1 |
| 102 | ; CHECK-NEXT: Offset: 0x0000014C | 104 | ; CHECK-NEXT: Offset: 0x0000014C |
| 103 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 105 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 104 | ; CHECK-NEXT: Index: 0 | 106 | ; CHECK-NEXT: Index: 1 |
| 105 | ; CHECK-NEXT: Offset: 0x00000158 | 107 | ; CHECK-NEXT: Offset: 0x00000158 |
| 106 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 108 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 107 | ; CHECK-NEXT: Index: 0 | 109 | ; CHECK-NEXT: Index: 1 |
| 108 | ; CHECK-NEXT: Offset: 0x00000164 | 110 | ; CHECK-NEXT: Offset: 0x00000164 |
| 109 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 111 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 110 | ; CHECK-NEXT: Index: 0 | 112 | ; CHECK-NEXT: Index: 1 |
| 111 | ; CHECK-NEXT: Offset: 0x00000170 | 113 | ; CHECK-NEXT: Offset: 0x00000170 |
| 112 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 114 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 113 | ; CHECK-NEXT: Index: 0 | 115 | ; CHECK-NEXT: Index: 1 |
| 114 | ; CHECK-NEXT: Offset: 0x0000017C | 116 | ; CHECK-NEXT: Offset: 0x0000017C |
| 115 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 117 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 116 | ; CHECK-NEXT: Index: 0 | 118 | ; CHECK-NEXT: Index: 1 |
| 117 | ; CHECK-NEXT: Offset: 0x00000188 | 119 | ; CHECK-NEXT: Offset: 0x00000188 |
| 118 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 120 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 119 | ; CHECK-NEXT: Index: 0 | 121 | ; CHECK-NEXT: Index: 1 |
| 120 | ; CHECK-NEXT: Offset: 0x00000194 | 122 | ; CHECK-NEXT: Offset: 0x00000194 |
| 121 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 123 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 122 | ; CHECK-NEXT: Index: 0 | 124 | ; CHECK-NEXT: Index: 1 |
| 123 | ; CHECK-NEXT: Offset: 0x000001A0 | 125 | ; CHECK-NEXT: Offset: 0x000001A0 |
| 124 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 126 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 125 | ; CHECK-NEXT: Index: 0 | 127 | ; CHECK-NEXT: Index: 1 |
| 126 | ; CHECK-NEXT: Offset: 0x000001AC | 128 | ; CHECK-NEXT: Offset: 0x000001AC |
| 127 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 129 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 128 | ; CHECK-NEXT: Index: 0 | 130 | ; CHECK-NEXT: Index: 1 |
| 129 | ; CHECK-NEXT: Offset: 0x000001B8 | 131 | ; CHECK-NEXT: Offset: 0x000001B8 |
| 130 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 132 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 131 | ; CHECK-NEXT: Index: 0 | 133 | ; CHECK-NEXT: Index: 1 |
| 132 | ; CHECK-NEXT: Offset: 0x000001C4 | 134 | ; CHECK-NEXT: Offset: 0x000001C4 |
| 133 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 135 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 134 | ; CHECK-NEXT: Index: 0 | 136 | ; CHECK-NEXT: Index: 1 |
| 135 | ; CHECK-NEXT: Offset: 0x000001D0 | 137 | ; CHECK-NEXT: Offset: 0x000001D0 |
| 136 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 138 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 137 | ; CHECK-NEXT: Index: 0 | 139 | ; CHECK-NEXT: Index: 1 |
| 138 | ; CHECK-NEXT: Offset: 0x000001DC | 140 | ; CHECK-NEXT: Offset: 0x000001DC |
| 139 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 141 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 140 | ; CHECK-NEXT: Index: 0 | 142 | ; CHECK-NEXT: Index: 1 |
| 141 | ; CHECK-NEXT: Offset: 0x000001E8 | 143 | ; CHECK-NEXT: Offset: 0x000001E8 |
| 142 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 144 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 143 | ; CHECK-NEXT: Index: 0 | 145 | ; CHECK-NEXT: Index: 1 |
| 144 | ; CHECK-NEXT: Offset: 0x000001F4 | 146 | ; CHECK-NEXT: Offset: 0x000001F4 |
| 145 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 147 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 146 | ; CHECK-NEXT: Index: 0 | 148 | ; CHECK-NEXT: Index: 1 |
| 147 | ; CHECK-NEXT: Offset: 0x00000200 | 149 | ; CHECK-NEXT: Offset: 0x00000200 |
| 148 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 150 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 149 | ; CHECK-NEXT: Index: 0 | 151 | ; CHECK-NEXT: Index: 1 |
| 150 | ; CHECK-NEXT: Offset: 0x0000020C | 152 | ; CHECK-NEXT: Offset: 0x0000020C |
| 151 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 153 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 152 | ; CHECK-NEXT: Index: 0 | 154 | ; CHECK-NEXT: Index: 1 |
| 153 | ; CHECK-NEXT: Offset: 0x00000218 | 155 | ; CHECK-NEXT: Offset: 0x00000218 |
| 154 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 156 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 155 | ; CHECK-NEXT: Index: 0 | 157 | ; CHECK-NEXT: Index: 1 |
| 156 | ; CHECK-NEXT: Offset: 0x00000224 | 158 | ; CHECK-NEXT: Offset: 0x00000224 |
| 157 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 159 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 158 | ; CHECK-NEXT: Index: 0 | 160 | ; CHECK-NEXT: Index: 1 |
| 159 | ; CHECK-NEXT: Offset: 0x00000230 | 161 | ; CHECK-NEXT: Offset: 0x00000230 |
| 160 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 162 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 161 | ; CHECK-NEXT: Index: 0 | 163 | ; CHECK-NEXT: Index: 1 |
| 162 | ; CHECK-NEXT: Offset: 0x0000023C | 164 | ; CHECK-NEXT: Offset: 0x0000023C |
| 163 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 165 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 164 | ; CHECK-NEXT: Index: 0 | 166 | ; CHECK-NEXT: Index: 1 |
| 165 | ; CHECK-NEXT: Offset: 0x00000248 | 167 | ; CHECK-NEXT: Offset: 0x00000248 |
| 166 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 168 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 167 | ; CHECK-NEXT: Index: 0 | 169 | ; CHECK-NEXT: Index: 1 |
| 168 | ; CHECK-NEXT: Offset: 0x00000254 | 170 | ; CHECK-NEXT: Offset: 0x00000254 |
| 169 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 171 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 170 | ; CHECK-NEXT: Index: 0 | 172 | ; CHECK-NEXT: Index: 1 |
| 171 | ; CHECK-NEXT: Offset: 0x00000260 | 173 | ; CHECK-NEXT: Offset: 0x00000260 |
| 172 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 174 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 173 | ; CHECK-NEXT: Index: 0 | 175 | ; CHECK-NEXT: Index: 1 |
| 174 | ; CHECK-NEXT: Offset: 0x0000026C | 176 | ; CHECK-NEXT: Offset: 0x0000026C |
| 175 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 177 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 176 | ; CHECK-NEXT: Index: 0 | 178 | ; CHECK-NEXT: Index: 1 |
| 177 | ; CHECK-NEXT: Offset: 0x00000278 | 179 | ; CHECK-NEXT: Offset: 0x00000278 |
| 178 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 180 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 179 | ; CHECK-NEXT: Index: 0 | 181 | ; CHECK-NEXT: Index: 1 |
| 180 | ; CHECK-NEXT: Offset: 0x00000284 | 182 | ; CHECK-NEXT: Offset: 0x00000284 |
| 181 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 183 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 182 | ; CHECK-NEXT: Index: 0 | 184 | ; CHECK-NEXT: Index: 1 |
| 183 | ; CHECK-NEXT: Offset: 0x00000290 | 185 | ; CHECK-NEXT: Offset: 0x00000290 |
| 184 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 186 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 185 | ; CHECK-NEXT: Index: 0 | 187 | ; CHECK-NEXT: Index: 1 |
| 186 | ; CHECK-NEXT: Offset: 0x0000029C | 188 | ; CHECK-NEXT: Offset: 0x0000029C |
| 187 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 189 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 188 | ; CHECK-NEXT: Index: 0 | 190 | ; CHECK-NEXT: Index: 1 |
| 189 | ; CHECK-NEXT: Offset: 0x000002A8 | 191 | ; CHECK-NEXT: Offset: 0x000002A8 |
| 190 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 192 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 191 | ; CHECK-NEXT: Index: 0 | 193 | ; CHECK-NEXT: Index: 1 |
| 192 | ; CHECK-NEXT: Offset: 0x000002B4 | 194 | ; CHECK-NEXT: Offset: 0x000002B4 |
| 193 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 195 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 194 | ; CHECK-NEXT: Index: 0 | 196 | ; CHECK-NEXT: Index: 1 |
| 195 | ; CHECK-NEXT: Offset: 0x000002C0 | 197 | ; CHECK-NEXT: Offset: 0x000002C0 |
| 196 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 198 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 197 | ; CHECK-NEXT: Index: 0 | 199 | ; CHECK-NEXT: Index: 1 |
| 198 | ; CHECK-NEXT: Offset: 0x000002CC | 200 | ; CHECK-NEXT: Offset: 0x000002CC |
| 199 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 201 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 200 | ; CHECK-NEXT: Index: 0 | 202 | ; CHECK-NEXT: Index: 1 |
| 201 | ; CHECK-NEXT: Offset: 0x000002D8 | 203 | ; CHECK-NEXT: Offset: 0x000002D8 |
| 202 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 204 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 203 | ; CHECK-NEXT: Index: 0 | 205 | ; CHECK-NEXT: Index: 1 |
| 204 | ; CHECK-NEXT: Offset: 0x000002E4 | 206 | ; CHECK-NEXT: Offset: 0x000002E4 |
| 205 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 207 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 206 | ; CHECK-NEXT: Index: 0 | 208 | ; CHECK-NEXT: Index: 1 |
| 207 | ; CHECK-NEXT: Offset: 0x000002F0 | 209 | ; CHECK-NEXT: Offset: 0x000002F0 |
| 208 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 210 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 209 | ; CHECK-NEXT: Index: 0 | 211 | ; CHECK-NEXT: Index: 1 |
| 210 | ; CHECK-NEXT: Offset: 0x000002FC | 212 | ; CHECK-NEXT: Offset: 0x000002FC |
| 211 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 213 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 212 | ; CHECK-NEXT: Index: 0 | 214 | ; CHECK-NEXT: Index: 1 |
| 213 | ; CHECK-NEXT: Offset: 0x00000308 | 215 | ; CHECK-NEXT: Offset: 0x00000308 |
| 214 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 216 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 215 | ; CHECK-NEXT: Index: 0 | 217 | ; CHECK-NEXT: Index: 1 |
| 216 | ; CHECK-NEXT: Offset: 0x00000314 | 218 | ; CHECK-NEXT: Offset: 0x00000314 |
| 217 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 219 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 218 | ; CHECK-NEXT: Index: 0 | 220 | ; CHECK-NEXT: Index: 1 |
| 219 | ; CHECK-NEXT: Offset: 0x00000320 | 221 | ; CHECK-NEXT: Offset: 0x00000320 |
| 220 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 222 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 221 | ; CHECK-NEXT: Index: 0 | 223 | ; CHECK-NEXT: Index: 1 |
| 222 | ; CHECK-NEXT: Offset: 0x0000032C | 224 | ; CHECK-NEXT: Offset: 0x0000032C |
| 223 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 225 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 224 | ; CHECK-NEXT: Index: 0 | 226 | ; CHECK-NEXT: Index: 1 |
| 225 | ; CHECK-NEXT: Offset: 0x00000338 | 227 | ; CHECK-NEXT: Offset: 0x00000338 |
| 226 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 228 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 227 | ; CHECK-NEXT: Index: 0 | 229 | ; CHECK-NEXT: Index: 1 |
| 228 | ; CHECK-NEXT: Offset: 0x00000344 | 230 | ; CHECK-NEXT: Offset: 0x00000344 |
| 229 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 231 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 230 | ; CHECK-NEXT: Index: 0 | 232 | ; CHECK-NEXT: Index: 1 |
| 231 | ; CHECK-NEXT: Offset: 0x00000350 | 233 | ; CHECK-NEXT: Offset: 0x00000350 |
| 232 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 234 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 233 | ; CHECK-NEXT: Index: 0 | 235 | ; CHECK-NEXT: Index: 1 |
| 234 | ; CHECK-NEXT: Offset: 0x0000035C | 236 | ; CHECK-NEXT: Offset: 0x0000035C |
| 235 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 237 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 236 | ; CHECK-NEXT: Index: 0 | 238 | ; CHECK-NEXT: Index: 1 |
| 237 | ; CHECK-NEXT: Offset: 0x00000368 | 239 | ; CHECK-NEXT: Offset: 0x00000368 |
| 238 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 240 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 239 | ; CHECK-NEXT: Index: 0 | 241 | ; CHECK-NEXT: Index: 1 |
| 240 | ; CHECK-NEXT: Offset: 0x00000374 | 242 | ; CHECK-NEXT: Offset: 0x00000374 |
| 241 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 243 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 242 | ; CHECK-NEXT: Index: 0 | 244 | ; CHECK-NEXT: Index: 1 |
| 243 | ; CHECK-NEXT: Offset: 0x00000380 | 245 | ; CHECK-NEXT: Offset: 0x00000380 |
| 244 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 246 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 245 | ; CHECK-NEXT: Index: 0 | 247 | ; CHECK-NEXT: Index: 1 |
| 246 | ; CHECK-NEXT: Offset: 0x0000038C | 248 | ; CHECK-NEXT: Offset: 0x0000038C |
| 247 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 249 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 248 | ; CHECK-NEXT: Index: 0 | 250 | ; CHECK-NEXT: Index: 1 |
| 249 | ; CHECK-NEXT: Offset: 0x00000398 | 251 | ; CHECK-NEXT: Offset: 0x00000398 |
| 250 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 252 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 251 | ; CHECK-NEXT: Index: 0 | 253 | ; CHECK-NEXT: Index: 1 |
| 252 | ; CHECK-NEXT: Offset: 0x000003A4 | 254 | ; CHECK-NEXT: Offset: 0x000003A4 |
| 253 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 255 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 254 | ; CHECK-NEXT: Index: 0 | 256 | ; CHECK-NEXT: Index: 1 |
| 255 | ; CHECK-NEXT: Offset: 0x000003B0 | 257 | ; CHECK-NEXT: Offset: 0x000003B0 |
| 256 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 258 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 257 | ; CHECK-NEXT: Index: 0 | 259 | ; CHECK-NEXT: Index: 1 |
| 258 | ; CHECK-NEXT: Offset: 0x000003BC | 260 | ; CHECK-NEXT: Offset: 0x000003BC |
| 259 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 261 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 260 | ; CHECK-NEXT: Index: 0 | 262 | ; CHECK-NEXT: Index: 1 |
| 261 | ; CHECK-NEXT: Offset: 0x000003C8 | 263 | ; CHECK-NEXT: Offset: 0x000003C8 |
| 262 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 264 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 263 | ; CHECK-NEXT: Index: 0 | 265 | ; CHECK-NEXT: Index: 1 |
| 264 | ; CHECK-NEXT: Offset: 0x000003D4 | 266 | ; CHECK-NEXT: Offset: 0x000003D4 |
| 265 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 267 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 266 | ; CHECK-NEXT: Index: 0 | 268 | ; CHECK-NEXT: Index: 1 |
| 267 | ; CHECK-NEXT: Offset: 0x000003E0 | 269 | ; CHECK-NEXT: Offset: 0x000003E0 |
| 268 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 270 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 269 | ; CHECK-NEXT: Index: 0 | 271 | ; CHECK-NEXT: Index: 1 |
| 270 | ; CHECK-NEXT: Offset: 0x000003EC | 272 | ; CHECK-NEXT: Offset: 0x000003EC |
| 271 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 273 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 272 | ; CHECK-NEXT: Index: 0 | 274 | ; CHECK-NEXT: Index: 1 |
| 273 | ; CHECK-NEXT: Offset: 0x000003F8 | 275 | ; CHECK-NEXT: Offset: 0x000003F8 |
| 274 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 276 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 275 | ; CHECK-NEXT: Index: 0 | 277 | ; CHECK-NEXT: Index: 1 |
| 276 | ; CHECK-NEXT: Offset: 0x00000404 | 278 | ; CHECK-NEXT: Offset: 0x00000404 |
| 277 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 279 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 278 | ; CHECK-NEXT: Index: 0 | 280 | ; CHECK-NEXT: Index: 1 |
| 279 | ; CHECK-NEXT: Offset: 0x00000410 | 281 | ; CHECK-NEXT: Offset: 0x00000410 |
| 280 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 282 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 281 | ; CHECK-NEXT: Index: 0 | 283 | ; CHECK-NEXT: Index: 1 |
| 282 | ; CHECK-NEXT: Offset: 0x0000041C | 284 | ; CHECK-NEXT: Offset: 0x0000041C |
| 283 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 285 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 284 | ; CHECK-NEXT: Index: 0 | 286 | ; CHECK-NEXT: Index: 1 |
| 285 | ; CHECK-NEXT: Offset: 0x00000428 | 287 | ; CHECK-NEXT: Offset: 0x00000428 |
| 286 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 288 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 287 | ; CHECK-NEXT: Index: 0 | 289 | ; CHECK-NEXT: Index: 1 |
| 288 | ; CHECK-NEXT: Offset: 0x00000434 | 290 | ; CHECK-NEXT: Offset: 0x00000434 |
| 289 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 291 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 290 | ; CHECK-NEXT: Index: 0 | 292 | ; CHECK-NEXT: Index: 1 |
| 291 | ; CHECK-NEXT: Offset: 0x00000440 | 293 | ; CHECK-NEXT: Offset: 0x00000440 |
| 292 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 294 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 293 | ; CHECK-NEXT: Index: 0 | 295 | ; CHECK-NEXT: Index: 1 |
| 294 | ; CHECK-NEXT: Offset: 0x0000044C | 296 | ; CHECK-NEXT: Offset: 0x0000044C |
| 295 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 297 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 296 | ; CHECK-NEXT: Index: 0 | 298 | ; CHECK-NEXT: Index: 1 |
| 297 | ; CHECK-NEXT: Offset: 0x00000458 | 299 | ; CHECK-NEXT: Offset: 0x00000458 |
| 298 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 300 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 299 | ; CHECK-NEXT: Index: 0 | 301 | ; CHECK-NEXT: Index: 1 |
| 300 | ; CHECK-NEXT: Offset: 0x00000464 | 302 | ; CHECK-NEXT: Offset: 0x00000464 |
| 301 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 303 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 302 | ; CHECK-NEXT: Index: 0 | 304 | ; CHECK-NEXT: Index: 1 |
| 303 | ; CHECK-NEXT: Offset: 0x00000470 | 305 | ; CHECK-NEXT: Offset: 0x00000470 |
| 304 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 306 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 305 | ; CHECK-NEXT: Index: 0 | 307 | ; CHECK-NEXT: Index: 1 |
| 306 | ; CHECK-NEXT: Offset: 0x0000047C | 308 | ; CHECK-NEXT: Offset: 0x0000047C |
| 307 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 309 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 308 | ; CHECK-NEXT: Index: 0 | 310 | ; CHECK-NEXT: Index: 1 |
| 309 | ; CHECK-NEXT: Offset: 0x00000488 | 311 | ; CHECK-NEXT: Offset: 0x00000488 |
| 310 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 312 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 311 | ; CHECK-NEXT: Index: 0 | 313 | ; CHECK-NEXT: Index: 1 |
| 312 | ; CHECK-NEXT: Offset: 0x00000494 | 314 | ; CHECK-NEXT: Offset: 0x00000494 |
| 313 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 315 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 314 | ; CHECK-NEXT: Index: 0 | 316 | ; CHECK-NEXT: Index: 1 |
| 315 | ; CHECK-NEXT: Offset: 0x000004A0 | 317 | ; CHECK-NEXT: Offset: 0x000004A0 |
| 316 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 318 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 317 | ; CHECK-NEXT: Index: 0 | 319 | ; CHECK-NEXT: Index: 1 |
| 318 | ; CHECK-NEXT: Offset: 0x000004AC | 320 | ; CHECK-NEXT: Offset: 0x000004AC |
| 319 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 321 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 320 | ; CHECK-NEXT: Index: 0 | 322 | ; CHECK-NEXT: Index: 1 |
| 321 | ; CHECK-NEXT: Offset: 0x000004B8 | 323 | ; CHECK-NEXT: Offset: 0x000004B8 |
| 322 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 324 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 323 | ; CHECK-NEXT: Index: 0 | 325 | ; CHECK-NEXT: Index: 1 |
| 324 | ; CHECK-NEXT: Offset: 0x000004C4 | 326 | ; CHECK-NEXT: Offset: 0x000004C4 |
| 325 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 327 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 326 | ; CHECK-NEXT: Index: 0 | 328 | ; CHECK-NEXT: Index: 1 |
| 327 | ; CHECK-NEXT: Offset: 0x000004D0 | 329 | ; CHECK-NEXT: Offset: 0x000004D0 |
| 328 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 330 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 329 | ; CHECK-NEXT: Index: 0 | 331 | ; CHECK-NEXT: Index: 1 |
| 330 | ; CHECK-NEXT: Offset: 0x000004DC | 332 | ; CHECK-NEXT: Offset: 0x000004DC |
| 331 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 333 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 332 | ; CHECK-NEXT: Index: 0 | 334 | ; CHECK-NEXT: Index: 1 |
| 333 | ; CHECK-NEXT: Offset: 0x000004E8 | 335 | ; CHECK-NEXT: Offset: 0x000004E8 |
| 334 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 336 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 335 | ; CHECK-NEXT: Index: 0 | 337 | ; CHECK-NEXT: Index: 1 |
| 336 | ; CHECK-NEXT: Offset: 0x000004F4 | 338 | ; CHECK-NEXT: Offset: 0x000004F4 |
| 337 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 339 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 338 | ; CHECK-NEXT: Index: 0 | 340 | ; CHECK-NEXT: Index: 1 |
| 339 | ; CHECK-NEXT: Offset: 0x00000500 | 341 | ; CHECK-NEXT: Offset: 0x00000500 |
| 340 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 342 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 341 | ; CHECK-NEXT: Index: 0 | 343 | ; CHECK-NEXT: Index: 1 |
| 342 | ; CHECK-NEXT: Offset: 0x0000050C | 344 | ; CHECK-NEXT: Offset: 0x0000050C |
| 343 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 345 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 344 | ; CHECK-NEXT: Index: 0 | 346 | ; CHECK-NEXT: Index: 1 |
| 345 | ; CHECK-NEXT: Offset: 0x00000518 | 347 | ; CHECK-NEXT: Offset: 0x00000518 |
| 346 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 348 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 347 | ; CHECK-NEXT: Index: 0 | 349 | ; CHECK-NEXT: Index: 1 |
| 348 | ; CHECK-NEXT: Offset: 0x00000524 | 350 | ; CHECK-NEXT: Offset: 0x00000524 |
| 349 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 351 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 350 | ; CHECK-NEXT: Index: 0 | 352 | ; CHECK-NEXT: Index: 1 |
| 351 | ; CHECK-NEXT: Offset: 0x00000530 | 353 | ; CHECK-NEXT: Offset: 0x00000530 |
| 352 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 354 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 353 | ; CHECK-NEXT: Index: 0 | 355 | ; CHECK-NEXT: Index: 1 |
| 354 | ; CHECK-NEXT: Offset: 0x0000053C | 356 | ; CHECK-NEXT: Offset: 0x0000053C |
| 355 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 357 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 356 | ; CHECK-NEXT: Index: 0 | 358 | ; CHECK-NEXT: Index: 1 |
| 357 | ; CHECK-NEXT: Offset: 0x00000548 | 359 | ; CHECK-NEXT: Offset: 0x00000548 |
| 358 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 360 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 359 | ; CHECK-NEXT: Index: 0 | 361 | ; CHECK-NEXT: Index: 1 |
| 360 | ; CHECK-NEXT: Offset: 0x00000554 | 362 | ; CHECK-NEXT: Offset: 0x00000554 |
| 361 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 363 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 362 | ; CHECK-NEXT: Index: 0 | 364 | ; CHECK-NEXT: Index: 1 |
| 363 | ; CHECK-NEXT: Offset: 0x00000560 | 365 | ; CHECK-NEXT: Offset: 0x00000560 |
| 364 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 366 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 365 | ; CHECK-NEXT: Index: 0 | 367 | ; CHECK-NEXT: Index: 1 |
| 366 | ; CHECK-NEXT: Offset: 0x0000056C | 368 | ; CHECK-NEXT: Offset: 0x0000056C |
| 367 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 369 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 368 | ; CHECK-NEXT: Index: 0 | 370 | ; CHECK-NEXT: Index: 1 |
| 369 | ; CHECK-NEXT: Offset: 0x00000578 | 371 | ; CHECK-NEXT: Offset: 0x00000578 |
| 370 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 372 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 371 | ; CHECK-NEXT: Index: 0 | 373 | ; CHECK-NEXT: Index: 1 |
| 372 | ; CHECK-NEXT: Offset: 0x00000584 | 374 | ; CHECK-NEXT: Offset: 0x00000584 |
| 373 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 375 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 374 | ; CHECK-NEXT: Index: 0 | 376 | ; CHECK-NEXT: Index: 1 |
| 375 | ; CHECK-NEXT: Offset: 0x00000590 | 377 | ; CHECK-NEXT: Offset: 0x00000590 |
| 376 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 378 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 377 | ; CHECK-NEXT: Index: 0 | 379 | ; CHECK-NEXT: Index: 1 |
| 378 | ; CHECK-NEXT: Offset: 0x0000059C | 380 | ; CHECK-NEXT: Offset: 0x0000059C |
| 379 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 381 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 380 | ; CHECK-NEXT: Index: 0 | 382 | ; CHECK-NEXT: Index: 1 |
| 381 | ; CHECK-NEXT: Offset: 0x000005A8 | 383 | ; CHECK-NEXT: Offset: 0x000005A8 |
| 382 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 384 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 383 | ; CHECK-NEXT: Index: 0 | 385 | ; CHECK-NEXT: Index: 1 |
| 384 | ; CHECK-NEXT: Offset: 0x000005B4 | 386 | ; CHECK-NEXT: Offset: 0x000005B4 |
| 385 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 387 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 386 | ; CHECK-NEXT: Index: 0 | 388 | ; CHECK-NEXT: Index: 1 |
| 387 | ; CHECK-NEXT: Offset: 0x000005C0 | 389 | ; CHECK-NEXT: Offset: 0x000005C0 |
| 388 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 390 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 389 | ; CHECK-NEXT: Index: 0 | 391 | ; CHECK-NEXT: Index: 1 |
| 390 | ; CHECK-NEXT: Offset: 0x000005CC | 392 | ; CHECK-NEXT: Offset: 0x000005CC |
| 391 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 393 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 392 | ; CHECK-NEXT: Index: 0 | 394 | ; CHECK-NEXT: Index: 1 |
| 393 | ; CHECK-NEXT: Offset: 0x000005D8 | 395 | ; CHECK-NEXT: Offset: 0x000005D8 |
| 394 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 396 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 395 | ; CHECK-NEXT: Index: 0 | 397 | ; CHECK-NEXT: Index: 1 |
| 396 | ; CHECK-NEXT: Offset: 0x000005E4 | 398 | ; CHECK-NEXT: Offset: 0x000005E4 |
| 397 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 399 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 398 | ; CHECK-NEXT: Index: 0 | 400 | ; CHECK-NEXT: Index: 1 |
| 399 | ; CHECK-NEXT: Offset: 0x000005F0 | 401 | ; CHECK-NEXT: Offset: 0x000005F0 |
| 400 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 402 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 401 | ; CHECK-NEXT: Index: 1 | 403 | ; CHECK-NEXT: Index: 129 |
| 402 | ; CHECK-NEXT: Offset: 0x000005FC | 404 | ; CHECK-NEXT: Offset: 0x000005FC |
| 403 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB | 405 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB |
| 404 | ; CHECK-NEXT: Index: 1 | 406 | ; CHECK-NEXT: Index: 129 |
| 405 | ; CHECK-NEXT: Offset: 0x00000608 | 407 | ; CHECK-NEXT: Offset: 0x00000608 |
| 406 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | 408 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB |
| 407 | ; CHECK-NEXT: Index: 129 | 409 | ; CHECK-NEXT: Index: 131 |
| 408 | ; CHECK-NEXT: Offset: 0x00000611 | 410 | ; CHECK-NEXT: Offset: 0x00000611 |
| 409 | ; CHECK-NEXT: Functions: | 411 | ; CHECK-NEXT: Functions: |
| 410 | ; CHECK-NEXT: - Locals: | 412 | ; CHECK-NEXT: - Index: 0 |
| 413 | ; CHECK-NEXT: Locals: | ||
| 411 | ; CHECK-NEXT: Body: 4100280284808080000B | 414 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 412 | ; CHECK-NEXT: - Locals: | 415 | ; CHECK-NEXT: - Index: 1 |
| 416 | ; CHECK-NEXT: Locals: | ||
| 413 | ; CHECK-NEXT: Body: 4100280284808080000B | 417 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 414 | ; CHECK-NEXT: - Locals: | 418 | ; CHECK-NEXT: - Index: 2 |
| 419 | ; CHECK-NEXT: Locals: | ||
| 415 | ; CHECK-NEXT: Body: 4100280284808080000B | 420 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 416 | ; CHECK-NEXT: - Locals: | 421 | ; CHECK-NEXT: - Index: 3 |
| 422 | ; CHECK-NEXT: Locals: | ||
| 417 | ; CHECK-NEXT: Body: 4100280284808080000B | 423 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 418 | ; CHECK-NEXT: - Locals: | 424 | ; CHECK-NEXT: - Index: 4 |
| 425 | ; CHECK-NEXT: Locals: | ||
| 419 | ; CHECK-NEXT: Body: 4100280284808080000B | 426 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 420 | ; CHECK-NEXT: - Locals: | 427 | ; CHECK-NEXT: - Index: 5 |
| 428 | ; CHECK-NEXT: Locals: | ||
| 421 | ; CHECK-NEXT: Body: 4100280284808080000B | 429 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 422 | ; CHECK-NEXT: - Locals: | 430 | ; CHECK-NEXT: - Index: 6 |
| 431 | ; CHECK-NEXT: Locals: | ||
| 423 | ; CHECK-NEXT: Body: 4100280284808080000B | 432 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 424 | ; CHECK-NEXT: - Locals: | 433 | ; CHECK-NEXT: - Index: 7 |
| 434 | ; CHECK-NEXT: Locals: | ||
| 425 | ; CHECK-NEXT: Body: 4100280284808080000B | 435 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 426 | ; CHECK-NEXT: - Locals: | 436 | ; CHECK-NEXT: - Index: 8 |
| 437 | ; CHECK-NEXT: Locals: | ||
| 427 | ; CHECK-NEXT: Body: 4100280284808080000B | 438 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 428 | ; CHECK-NEXT: - Locals: | 439 | ; CHECK-NEXT: - Index: 9 |
| 440 | ; CHECK-NEXT: Locals: | ||
| 429 | ; CHECK-NEXT: Body: 4100280284808080000B | 441 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 430 | ; CHECK-NEXT: - Locals: | 442 | ; CHECK-NEXT: - Index: 10 |
| 443 | ; CHECK-NEXT: Locals: | ||
| 431 | ; CHECK-NEXT: Body: 4100280284808080000B | 444 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 432 | ; CHECK-NEXT: - Locals: | 445 | ; CHECK-NEXT: - Index: 11 |
| 446 | ; CHECK-NEXT: Locals: | ||
| 433 | ; CHECK-NEXT: Body: 4100280284808080000B | 447 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 434 | ; CHECK-NEXT: - Locals: | 448 | ; CHECK-NEXT: - Index: 12 |
| 449 | ; CHECK-NEXT: Locals: | ||
| 435 | ; CHECK-NEXT: Body: 4100280284808080000B | 450 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 436 | ; CHECK-NEXT: - Locals: | 451 | ; CHECK-NEXT: - Index: 13 |
| 452 | ; CHECK-NEXT: Locals: | ||
| 437 | ; CHECK-NEXT: Body: 4100280284808080000B | 453 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 438 | ; CHECK-NEXT: - Locals: | 454 | ; CHECK-NEXT: - Index: 14 |
| 455 | ; CHECK-NEXT: Locals: | ||
| 439 | ; CHECK-NEXT: Body: 4100280284808080000B | 456 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 440 | ; CHECK-NEXT: - Locals: | 457 | ; CHECK-NEXT: - Index: 15 |
| 458 | ; CHECK-NEXT: Locals: | ||
| 441 | ; CHECK-NEXT: Body: 4100280284808080000B | 459 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 442 | ; CHECK-NEXT: - Locals: | 460 | ; CHECK-NEXT: - Index: 16 |
| 461 | ; CHECK-NEXT: Locals: | ||
| 443 | ; CHECK-NEXT: Body: 4100280284808080000B | 462 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 444 | ; CHECK-NEXT: - Locals: | 463 | ; CHECK-NEXT: - Index: 17 |
| 464 | ; CHECK-NEXT: Locals: | ||
| 445 | ; CHECK-NEXT: Body: 4100280284808080000B | 465 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 446 | ; CHECK-NEXT: - Locals: | 466 | ; CHECK-NEXT: - Index: 18 |
| 467 | ; CHECK-NEXT: Locals: | ||
| 447 | ; CHECK-NEXT: Body: 4100280284808080000B | 468 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 448 | ; CHECK-NEXT: - Locals: | 469 | ; CHECK-NEXT: - Index: 19 |
| 470 | ; CHECK-NEXT: Locals: | ||
| 449 | ; CHECK-NEXT: Body: 4100280284808080000B | 471 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 450 | ; CHECK-NEXT: - Locals: | 472 | ; CHECK-NEXT: - Index: 20 |
| 473 | ; CHECK-NEXT: Locals: | ||
| 451 | ; CHECK-NEXT: Body: 4100280284808080000B | 474 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 452 | ; CHECK-NEXT: - Locals: | 475 | ; CHECK-NEXT: - Index: 21 |
| 476 | ; CHECK-NEXT: Locals: | ||
| 453 | ; CHECK-NEXT: Body: 4100280284808080000B | 477 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 454 | ; CHECK-NEXT: - Locals: | 478 | ; CHECK-NEXT: - Index: 22 |
| 479 | ; CHECK-NEXT: Locals: | ||
| 455 | ; CHECK-NEXT: Body: 4100280284808080000B | 480 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 456 | ; CHECK-NEXT: - Locals: | 481 | ; CHECK-NEXT: - Index: 23 |
| 482 | ; CHECK-NEXT: Locals: | ||
| 457 | ; CHECK-NEXT: Body: 4100280284808080000B | 483 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 458 | ; CHECK-NEXT: - Locals: | 484 | ; CHECK-NEXT: - Index: 24 |
| 485 | ; CHECK-NEXT: Locals: | ||
| 459 | ; CHECK-NEXT: Body: 4100280284808080000B | 486 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 460 | ; CHECK-NEXT: - Locals: | 487 | ; CHECK-NEXT: - Index: 25 |
| 488 | ; CHECK-NEXT: Locals: | ||
| 461 | ; CHECK-NEXT: Body: 4100280284808080000B | 489 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 462 | ; CHECK-NEXT: - Locals: | 490 | ; CHECK-NEXT: - Index: 26 |
| 491 | ; CHECK-NEXT: Locals: | ||
| 463 | ; CHECK-NEXT: Body: 4100280284808080000B | 492 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 464 | ; CHECK-NEXT: - Locals: | 493 | ; CHECK-NEXT: - Index: 27 |
| 494 | ; CHECK-NEXT: Locals: | ||
| 465 | ; CHECK-NEXT: Body: 4100280284808080000B | 495 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 466 | ; CHECK-NEXT: - Locals: | 496 | ; CHECK-NEXT: - Index: 28 |
| 497 | ; CHECK-NEXT: Locals: | ||
| 467 | ; CHECK-NEXT: Body: 4100280284808080000B | 498 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 468 | ; CHECK-NEXT: - Locals: | 499 | ; CHECK-NEXT: - Index: 29 |
| 500 | ; CHECK-NEXT: Locals: | ||
| 469 | ; CHECK-NEXT: Body: 4100280284808080000B | 501 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 470 | ; CHECK-NEXT: - Locals: | 502 | ; CHECK-NEXT: - Index: 30 |
| 503 | ; CHECK-NEXT: Locals: | ||
| 471 | ; CHECK-NEXT: Body: 4100280284808080000B | 504 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 472 | ; CHECK-NEXT: - Locals: | 505 | ; CHECK-NEXT: - Index: 31 |
| 506 | ; CHECK-NEXT: Locals: | ||
| 473 | ; CHECK-NEXT: Body: 4100280284808080000B | 507 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 474 | ; CHECK-NEXT: - Locals: | 508 | ; CHECK-NEXT: - Index: 32 |
| 509 | ; CHECK-NEXT: Locals: | ||
| 475 | ; CHECK-NEXT: Body: 4100280284808080000B | 510 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 476 | ; CHECK-NEXT: - Locals: | 511 | ; CHECK-NEXT: - Index: 33 |
| 512 | ; CHECK-NEXT: Locals: | ||
| 477 | ; CHECK-NEXT: Body: 4100280284808080000B | 513 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 478 | ; CHECK-NEXT: - Locals: | 514 | ; CHECK-NEXT: - Index: 34 |
| 515 | ; CHECK-NEXT: Locals: | ||
| 479 | ; CHECK-NEXT: Body: 4100280284808080000B | 516 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 480 | ; CHECK-NEXT: - Locals: | 517 | ; CHECK-NEXT: - Index: 35 |
| 518 | ; CHECK-NEXT: Locals: | ||
| 481 | ; CHECK-NEXT: Body: 4100280284808080000B | 519 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 482 | ; CHECK-NEXT: - Locals: | 520 | ; CHECK-NEXT: - Index: 36 |
| 521 | ; CHECK-NEXT: Locals: | ||
| 483 | ; CHECK-NEXT: Body: 4100280284808080000B | 522 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 484 | ; CHECK-NEXT: - Locals: | 523 | ; CHECK-NEXT: - Index: 37 |
| 524 | ; CHECK-NEXT: Locals: | ||
| 485 | ; CHECK-NEXT: Body: 4100280284808080000B | 525 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 486 | ; CHECK-NEXT: - Locals: | 526 | ; CHECK-NEXT: - Index: 38 |
| 527 | ; CHECK-NEXT: Locals: | ||
| 487 | ; CHECK-NEXT: Body: 4100280284808080000B | 528 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 488 | ; CHECK-NEXT: - Locals: | 529 | ; CHECK-NEXT: - Index: 39 |
| 530 | ; CHECK-NEXT: Locals: | ||
| 489 | ; CHECK-NEXT: Body: 4100280284808080000B | 531 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 490 | ; CHECK-NEXT: - Locals: | 532 | ; CHECK-NEXT: - Index: 40 |
| 533 | ; CHECK-NEXT: Locals: | ||
| 491 | ; CHECK-NEXT: Body: 4100280284808080000B | 534 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 492 | ; CHECK-NEXT: - Locals: | 535 | ; CHECK-NEXT: - Index: 41 |
| 536 | ; CHECK-NEXT: Locals: | ||
| 493 | ; CHECK-NEXT: Body: 4100280284808080000B | 537 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 494 | ; CHECK-NEXT: - Locals: | 538 | ; CHECK-NEXT: - Index: 42 |
| 539 | ; CHECK-NEXT: Locals: | ||
| 495 | ; CHECK-NEXT: Body: 4100280284808080000B | 540 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 496 | ; CHECK-NEXT: - Locals: | 541 | ; CHECK-NEXT: - Index: 43 |
| 542 | ; CHECK-NEXT: Locals: | ||
| 497 | ; CHECK-NEXT: Body: 4100280284808080000B | 543 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 498 | ; CHECK-NEXT: - Locals: | 544 | ; CHECK-NEXT: - Index: 44 |
| 545 | ; CHECK-NEXT: Locals: | ||
| 499 | ; CHECK-NEXT: Body: 4100280284808080000B | 546 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 500 | ; CHECK-NEXT: - Locals: | 547 | ; CHECK-NEXT: - Index: 45 |
| 548 | ; CHECK-NEXT: Locals: | ||
| 501 | ; CHECK-NEXT: Body: 4100280284808080000B | 549 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 502 | ; CHECK-NEXT: - Locals: | 550 | ; CHECK-NEXT: - Index: 46 |
| 551 | ; CHECK-NEXT: Locals: | ||
| 503 | ; CHECK-NEXT: Body: 4100280284808080000B | 552 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 504 | ; CHECK-NEXT: - Locals: | 553 | ; CHECK-NEXT: - Index: 47 |
| 554 | ; CHECK-NEXT: Locals: | ||
| 505 | ; CHECK-NEXT: Body: 4100280284808080000B | 555 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 506 | ; CHECK-NEXT: - Locals: | 556 | ; CHECK-NEXT: - Index: 48 |
| 557 | ; CHECK-NEXT: Locals: | ||
| 507 | ; CHECK-NEXT: Body: 4100280284808080000B | 558 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 508 | ; CHECK-NEXT: - Locals: | 559 | ; CHECK-NEXT: - Index: 49 |
| 560 | ; CHECK-NEXT: Locals: | ||
| 509 | ; CHECK-NEXT: Body: 4100280284808080000B | 561 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 510 | ; CHECK-NEXT: - Locals: | 562 | ; CHECK-NEXT: - Index: 50 |
| 563 | ; CHECK-NEXT: Locals: | ||
| 511 | ; CHECK-NEXT: Body: 4100280284808080000B | 564 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 512 | ; CHECK-NEXT: - Locals: | 565 | ; CHECK-NEXT: - Index: 51 |
| 566 | ; CHECK-NEXT: Locals: | ||
| 513 | ; CHECK-NEXT: Body: 4100280284808080000B | 567 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 514 | ; CHECK-NEXT: - Locals: | 568 | ; CHECK-NEXT: - Index: 52 |
| 569 | ; CHECK-NEXT: Locals: | ||
| 515 | ; CHECK-NEXT: Body: 4100280284808080000B | 570 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 516 | ; CHECK-NEXT: - Locals: | 571 | ; CHECK-NEXT: - Index: 53 |
| 572 | ; CHECK-NEXT: Locals: | ||
| 517 | ; CHECK-NEXT: Body: 4100280284808080000B | 573 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 518 | ; CHECK-NEXT: - Locals: | 574 | ; CHECK-NEXT: - Index: 54 |
| 575 | ; CHECK-NEXT: Locals: | ||
| 519 | ; CHECK-NEXT: Body: 4100280284808080000B | 576 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 520 | ; CHECK-NEXT: - Locals: | 577 | ; CHECK-NEXT: - Index: 55 |
| 578 | ; CHECK-NEXT: Locals: | ||
| 521 | ; CHECK-NEXT: Body: 4100280284808080000B | 579 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 522 | ; CHECK-NEXT: - Locals: | 580 | ; CHECK-NEXT: - Index: 56 |
| 581 | ; CHECK-NEXT: Locals: | ||
| 523 | ; CHECK-NEXT: Body: 4100280284808080000B | 582 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 524 | ; CHECK-NEXT: - Locals: | 583 | ; CHECK-NEXT: - Index: 57 |
| 584 | ; CHECK-NEXT: Locals: | ||
| 525 | ; CHECK-NEXT: Body: 4100280284808080000B | 585 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 526 | ; CHECK-NEXT: - Locals: | 586 | ; CHECK-NEXT: - Index: 58 |
| 587 | ; CHECK-NEXT: Locals: | ||
| 527 | ; CHECK-NEXT: Body: 4100280284808080000B | 588 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 528 | ; CHECK-NEXT: - Locals: | 589 | ; CHECK-NEXT: - Index: 59 |
| 590 | ; CHECK-NEXT: Locals: | ||
| 529 | ; CHECK-NEXT: Body: 4100280284808080000B | 591 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 530 | ; CHECK-NEXT: - Locals: | 592 | ; CHECK-NEXT: - Index: 60 |
| 593 | ; CHECK-NEXT: Locals: | ||
| 531 | ; CHECK-NEXT: Body: 4100280284808080000B | 594 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 532 | ; CHECK-NEXT: - Locals: | 595 | ; CHECK-NEXT: - Index: 61 |
| 596 | ; CHECK-NEXT: Locals: | ||
| 533 | ; CHECK-NEXT: Body: 4100280284808080000B | 597 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 534 | ; CHECK-NEXT: - Locals: | 598 | ; CHECK-NEXT: - Index: 62 |
| 599 | ; CHECK-NEXT: Locals: | ||
| 535 | ; CHECK-NEXT: Body: 4100280284808080000B | 600 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 536 | ; CHECK-NEXT: - Locals: | 601 | ; CHECK-NEXT: - Index: 63 |
| 602 | ; CHECK-NEXT: Locals: | ||
| 537 | ; CHECK-NEXT: Body: 4100280284808080000B | 603 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 538 | ; CHECK-NEXT: - Locals: | 604 | ; CHECK-NEXT: - Index: 64 |
| 605 | ; CHECK-NEXT: Locals: | ||
| 539 | ; CHECK-NEXT: Body: 4100280284808080000B | 606 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 540 | ; CHECK-NEXT: - Locals: | 607 | ; CHECK-NEXT: - Index: 65 |
| 608 | ; CHECK-NEXT: Locals: | ||
| 541 | ; CHECK-NEXT: Body: 4100280284808080000B | 609 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 542 | ; CHECK-NEXT: - Locals: | 610 | ; CHECK-NEXT: - Index: 66 |
| 611 | ; CHECK-NEXT: Locals: | ||
| 543 | ; CHECK-NEXT: Body: 4100280284808080000B | 612 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 544 | ; CHECK-NEXT: - Locals: | 613 | ; CHECK-NEXT: - Index: 67 |
| 614 | ; CHECK-NEXT: Locals: | ||
| 545 | ; CHECK-NEXT: Body: 4100280284808080000B | 615 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 546 | ; CHECK-NEXT: - Locals: | 616 | ; CHECK-NEXT: - Index: 68 |
| 617 | ; CHECK-NEXT: Locals: | ||
| 547 | ; CHECK-NEXT: Body: 4100280284808080000B | 618 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 548 | ; CHECK-NEXT: - Locals: | 619 | ; CHECK-NEXT: - Index: 69 |
| 620 | ; CHECK-NEXT: Locals: | ||
| 549 | ; CHECK-NEXT: Body: 4100280284808080000B | 621 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 550 | ; CHECK-NEXT: - Locals: | 622 | ; CHECK-NEXT: - Index: 70 |
| 623 | ; CHECK-NEXT: Locals: | ||
| 551 | ; CHECK-NEXT: Body: 4100280284808080000B | 624 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 552 | ; CHECK-NEXT: - Locals: | 625 | ; CHECK-NEXT: - Index: 71 |
| 626 | ; CHECK-NEXT: Locals: | ||
| 553 | ; CHECK-NEXT: Body: 4100280284808080000B | 627 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 554 | ; CHECK-NEXT: - Locals: | 628 | ; CHECK-NEXT: - Index: 72 |
| 629 | ; CHECK-NEXT: Locals: | ||
| 555 | ; CHECK-NEXT: Body: 4100280284808080000B | 630 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 556 | ; CHECK-NEXT: - Locals: | 631 | ; CHECK-NEXT: - Index: 73 |
| 632 | ; CHECK-NEXT: Locals: | ||
| 557 | ; CHECK-NEXT: Body: 4100280284808080000B | 633 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 558 | ; CHECK-NEXT: - Locals: | 634 | ; CHECK-NEXT: - Index: 74 |
| 635 | ; CHECK-NEXT: Locals: | ||
| 559 | ; CHECK-NEXT: Body: 4100280284808080000B | 636 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 560 | ; CHECK-NEXT: - Locals: | 637 | ; CHECK-NEXT: - Index: 75 |
| 638 | ; CHECK-NEXT: Locals: | ||
| 561 | ; CHECK-NEXT: Body: 4100280284808080000B | 639 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 562 | ; CHECK-NEXT: - Locals: | 640 | ; CHECK-NEXT: - Index: 76 |
| 641 | ; CHECK-NEXT: Locals: | ||
| 563 | ; CHECK-NEXT: Body: 4100280284808080000B | 642 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 564 | ; CHECK-NEXT: - Locals: | 643 | ; CHECK-NEXT: - Index: 77 |
| 644 | ; CHECK-NEXT: Locals: | ||
| 565 | ; CHECK-NEXT: Body: 4100280284808080000B | 645 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 566 | ; CHECK-NEXT: - Locals: | 646 | ; CHECK-NEXT: - Index: 78 |
| 647 | ; CHECK-NEXT: Locals: | ||
| 567 | ; CHECK-NEXT: Body: 4100280284808080000B | 648 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 568 | ; CHECK-NEXT: - Locals: | 649 | ; CHECK-NEXT: - Index: 79 |
| 650 | ; CHECK-NEXT: Locals: | ||
| 569 | ; CHECK-NEXT: Body: 4100280284808080000B | 651 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 570 | ; CHECK-NEXT: - Locals: | 652 | ; CHECK-NEXT: - Index: 80 |
| 653 | ; CHECK-NEXT: Locals: | ||
| 571 | ; CHECK-NEXT: Body: 4100280284808080000B | 654 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 572 | ; CHECK-NEXT: - Locals: | 655 | ; CHECK-NEXT: - Index: 81 |
| 656 | ; CHECK-NEXT: Locals: | ||
| 573 | ; CHECK-NEXT: Body: 4100280284808080000B | 657 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 574 | ; CHECK-NEXT: - Locals: | 658 | ; CHECK-NEXT: - Index: 82 |
| 659 | ; CHECK-NEXT: Locals: | ||
| 575 | ; CHECK-NEXT: Body: 4100280284808080000B | 660 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 576 | ; CHECK-NEXT: - Locals: | 661 | ; CHECK-NEXT: - Index: 83 |
| 662 | ; CHECK-NEXT: Locals: | ||
| 577 | ; CHECK-NEXT: Body: 4100280284808080000B | 663 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 578 | ; CHECK-NEXT: - Locals: | 664 | ; CHECK-NEXT: - Index: 84 |
| 665 | ; CHECK-NEXT: Locals: | ||
| 579 | ; CHECK-NEXT: Body: 4100280284808080000B | 666 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 580 | ; CHECK-NEXT: - Locals: | 667 | ; CHECK-NEXT: - Index: 85 |
| 668 | ; CHECK-NEXT: Locals: | ||
| 581 | ; CHECK-NEXT: Body: 4100280284808080000B | 669 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 582 | ; CHECK-NEXT: - Locals: | 670 | ; CHECK-NEXT: - Index: 86 |
| 671 | ; CHECK-NEXT: Locals: | ||
| 583 | ; CHECK-NEXT: Body: 4100280284808080000B | 672 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 584 | ; CHECK-NEXT: - Locals: | 673 | ; CHECK-NEXT: - Index: 87 |
| 674 | ; CHECK-NEXT: Locals: | ||
| 585 | ; CHECK-NEXT: Body: 4100280284808080000B | 675 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 586 | ; CHECK-NEXT: - Locals: | 676 | ; CHECK-NEXT: - Index: 88 |
| 677 | ; CHECK-NEXT: Locals: | ||
| 587 | ; CHECK-NEXT: Body: 4100280284808080000B | 678 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 588 | ; CHECK-NEXT: - Locals: | 679 | ; CHECK-NEXT: - Index: 89 |
| 680 | ; CHECK-NEXT: Locals: | ||
| 589 | ; CHECK-NEXT: Body: 4100280284808080000B | 681 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 590 | ; CHECK-NEXT: - Locals: | 682 | ; CHECK-NEXT: - Index: 90 |
| 683 | ; CHECK-NEXT: Locals: | ||
| 591 | ; CHECK-NEXT: Body: 4100280284808080000B | 684 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 592 | ; CHECK-NEXT: - Locals: | 685 | ; CHECK-NEXT: - Index: 91 |
| 686 | ; CHECK-NEXT: Locals: | ||
| 593 | ; CHECK-NEXT: Body: 4100280284808080000B | 687 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 594 | ; CHECK-NEXT: - Locals: | 688 | ; CHECK-NEXT: - Index: 92 |
| 689 | ; CHECK-NEXT: Locals: | ||
| 595 | ; CHECK-NEXT: Body: 4100280284808080000B | 690 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 596 | ; CHECK-NEXT: - Locals: | 691 | ; CHECK-NEXT: - Index: 93 |
| 692 | ; CHECK-NEXT: Locals: | ||
| 597 | ; CHECK-NEXT: Body: 4100280284808080000B | 693 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 598 | ; CHECK-NEXT: - Locals: | 694 | ; CHECK-NEXT: - Index: 94 |
| 695 | ; CHECK-NEXT: Locals: | ||
| 599 | ; CHECK-NEXT: Body: 4100280284808080000B | 696 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 600 | ; CHECK-NEXT: - Locals: | 697 | ; CHECK-NEXT: - Index: 95 |
| 698 | ; CHECK-NEXT: Locals: | ||
| 601 | ; CHECK-NEXT: Body: 4100280284808080000B | 699 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 602 | ; CHECK-NEXT: - Locals: | 700 | ; CHECK-NEXT: - Index: 96 |
| 701 | ; CHECK-NEXT: Locals: | ||
| 603 | ; CHECK-NEXT: Body: 4100280284808080000B | 702 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 604 | ; CHECK-NEXT: - Locals: | 703 | ; CHECK-NEXT: - Index: 97 |
| 704 | ; CHECK-NEXT: Locals: | ||
| 605 | ; CHECK-NEXT: Body: 4100280284808080000B | 705 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 606 | ; CHECK-NEXT: - Locals: | 706 | ; CHECK-NEXT: - Index: 98 |
| 707 | ; CHECK-NEXT: Locals: | ||
| 607 | ; CHECK-NEXT: Body: 4100280284808080000B | 708 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 608 | ; CHECK-NEXT: - Locals: | 709 | ; CHECK-NEXT: - Index: 99 |
| 710 | ; CHECK-NEXT: Locals: | ||
| 609 | ; CHECK-NEXT: Body: 4100280284808080000B | 711 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 610 | ; CHECK-NEXT: - Locals: | 712 | ; CHECK-NEXT: - Index: 100 |
| 713 | ; CHECK-NEXT: Locals: | ||
| 611 | ; CHECK-NEXT: Body: 4100280284808080000B | 714 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 612 | ; CHECK-NEXT: - Locals: | 715 | ; CHECK-NEXT: - Index: 101 |
| 716 | ; CHECK-NEXT: Locals: | ||
| 613 | ; CHECK-NEXT: Body: 4100280284808080000B | 717 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 614 | ; CHECK-NEXT: - Locals: | 718 | ; CHECK-NEXT: - Index: 102 |
| 719 | ; CHECK-NEXT: Locals: | ||
| 615 | ; CHECK-NEXT: Body: 4100280284808080000B | 720 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 616 | ; CHECK-NEXT: - Locals: | 721 | ; CHECK-NEXT: - Index: 103 |
| 722 | ; CHECK-NEXT: Locals: | ||
| 617 | ; CHECK-NEXT: Body: 4100280284808080000B | 723 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 618 | ; CHECK-NEXT: - Locals: | 724 | ; CHECK-NEXT: - Index: 104 |
| 725 | ; CHECK-NEXT: Locals: | ||
| 619 | ; CHECK-NEXT: Body: 4100280284808080000B | 726 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 620 | ; CHECK-NEXT: - Locals: | 727 | ; CHECK-NEXT: - Index: 105 |
| 728 | ; CHECK-NEXT: Locals: | ||
| 621 | ; CHECK-NEXT: Body: 4100280284808080000B | 729 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 622 | ; CHECK-NEXT: - Locals: | 730 | ; CHECK-NEXT: - Index: 106 |
| 731 | ; CHECK-NEXT: Locals: | ||
| 623 | ; CHECK-NEXT: Body: 4100280284808080000B | 732 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 624 | ; CHECK-NEXT: - Locals: | 733 | ; CHECK-NEXT: - Index: 107 |
| 734 | ; CHECK-NEXT: Locals: | ||
| 625 | ; CHECK-NEXT: Body: 4100280284808080000B | 735 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 626 | ; CHECK-NEXT: - Locals: | 736 | ; CHECK-NEXT: - Index: 108 |
| 737 | ; CHECK-NEXT: Locals: | ||
| 627 | ; CHECK-NEXT: Body: 4100280284808080000B | 738 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 628 | ; CHECK-NEXT: - Locals: | 739 | ; CHECK-NEXT: - Index: 109 |
| 740 | ; CHECK-NEXT: Locals: | ||
| 629 | ; CHECK-NEXT: Body: 4100280284808080000B | 741 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 630 | ; CHECK-NEXT: - Locals: | 742 | ; CHECK-NEXT: - Index: 110 |
| 743 | ; CHECK-NEXT: Locals: | ||
| 631 | ; CHECK-NEXT: Body: 4100280284808080000B | 744 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 632 | ; CHECK-NEXT: - Locals: | 745 | ; CHECK-NEXT: - Index: 111 |
| 746 | ; CHECK-NEXT: Locals: | ||
| 633 | ; CHECK-NEXT: Body: 4100280284808080000B | 747 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 634 | ; CHECK-NEXT: - Locals: | 748 | ; CHECK-NEXT: - Index: 112 |
| 749 | ; CHECK-NEXT: Locals: | ||
| 635 | ; CHECK-NEXT: Body: 4100280284808080000B | 750 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 636 | ; CHECK-NEXT: - Locals: | 751 | ; CHECK-NEXT: - Index: 113 |
| 752 | ; CHECK-NEXT: Locals: | ||
| 637 | ; CHECK-NEXT: Body: 4100280284808080000B | 753 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 638 | ; CHECK-NEXT: - Locals: | 754 | ; CHECK-NEXT: - Index: 114 |
| 755 | ; CHECK-NEXT: Locals: | ||
| 639 | ; CHECK-NEXT: Body: 4100280284808080000B | 756 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 640 | ; CHECK-NEXT: - Locals: | 757 | ; CHECK-NEXT: - Index: 115 |
| 758 | ; CHECK-NEXT: Locals: | ||
| 641 | ; CHECK-NEXT: Body: 4100280284808080000B | 759 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 642 | ; CHECK-NEXT: - Locals: | 760 | ; CHECK-NEXT: - Index: 116 |
| 761 | ; CHECK-NEXT: Locals: | ||
| 643 | ; CHECK-NEXT: Body: 4100280284808080000B | 762 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 644 | ; CHECK-NEXT: - Locals: | 763 | ; CHECK-NEXT: - Index: 117 |
| 764 | ; CHECK-NEXT: Locals: | ||
| 645 | ; CHECK-NEXT: Body: 4100280284808080000B | 765 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 646 | ; CHECK-NEXT: - Locals: | 766 | ; CHECK-NEXT: - Index: 118 |
| 767 | ; CHECK-NEXT: Locals: | ||
| 647 | ; CHECK-NEXT: Body: 4100280284808080000B | 768 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 648 | ; CHECK-NEXT: - Locals: | 769 | ; CHECK-NEXT: - Index: 119 |
| 770 | ; CHECK-NEXT: Locals: | ||
| 649 | ; CHECK-NEXT: Body: 4100280284808080000B | 771 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 650 | ; CHECK-NEXT: - Locals: | 772 | ; CHECK-NEXT: - Index: 120 |
| 773 | ; CHECK-NEXT: Locals: | ||
| 651 | ; CHECK-NEXT: Body: 4100280284808080000B | 774 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 652 | ; CHECK-NEXT: - Locals: | 775 | ; CHECK-NEXT: - Index: 121 |
| 776 | ; CHECK-NEXT: Locals: | ||
| 653 | ; CHECK-NEXT: Body: 4100280284808080000B | 777 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 654 | ; CHECK-NEXT: - Locals: | 778 | ; CHECK-NEXT: - Index: 122 |
| 779 | ; CHECK-NEXT: Locals: | ||
| 655 | ; CHECK-NEXT: Body: 4100280284808080000B | 780 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 656 | ; CHECK-NEXT: - Locals: | 781 | ; CHECK-NEXT: - Index: 123 |
| 782 | ; CHECK-NEXT: Locals: | ||
| 657 | ; CHECK-NEXT: Body: 4100280284808080000B | 783 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 658 | ; CHECK-NEXT: - Locals: | 784 | ; CHECK-NEXT: - Index: 124 |
| 785 | ; CHECK-NEXT: Locals: | ||
| 659 | ; CHECK-NEXT: Body: 4100280284808080000B | 786 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 660 | ; CHECK-NEXT: - Locals: | 787 | ; CHECK-NEXT: - Index: 125 |
| 788 | ; CHECK-NEXT: Locals: | ||
| 661 | ; CHECK-NEXT: Body: 4100280284808080000B | 789 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 662 | ; CHECK-NEXT: - Locals: | 790 | ; CHECK-NEXT: - Index: 126 |
| 791 | ; CHECK-NEXT: Locals: | ||
| 663 | ; CHECK-NEXT: Body: 4100280284808080000B | 792 | ; CHECK-NEXT: Body: 4100280284808080000B |
| 664 | ; CHECK-NEXT: - Locals: | 793 | ; CHECK-NEXT: - Index: 127 |
| 794 | ; CHECK-NEXT: Locals: | ||
| 665 | ; CHECK-NEXT: Body: 4100280280808080000B | 795 | ; CHECK-NEXT: Body: 4100280280808080000B |
| 666 | ; CHECK-NEXT: - Locals: | 796 | ; CHECK-NEXT: - Index: 128 |
| 797 | ; CHECK-NEXT: Locals: | ||
| 667 | ; CHECK-NEXT: Body: 4100280280808080000B | 798 | ; CHECK-NEXT: Body: 4100280280808080000B |
| 668 | ; CHECK-NEXT: - Locals: | 799 | ; CHECK-NEXT: - Index: 129 |
| 800 | ; CHECK-NEXT: Locals: | ||
| 669 | ; CHECK-NEXT: Body: 1081818080000B | 801 | ; CHECK-NEXT: Body: 1081818080000B |
| 670 | ; CHECK-NEXT: - Type: DATA | 802 | ; CHECK-NEXT: - Type: DATA |
| 671 | ; CHECK-NEXT: Segments: | 803 | ; CHECK-NEXT: Segments: |
| ... | @@ -683,7 +815,670 @@ entry: | ... | @@ -683,7 +815,670 @@ entry: |
| 683 | ; CHECK-NEXT: Content: '01000000' | 815 | ; CHECK-NEXT: Content: '01000000' |
| 684 | ; CHECK-NEXT: - Type: CUSTOM | 816 | ; CHECK-NEXT: - Type: CUSTOM |
| 685 | ; CHECK-NEXT: Name: linking | 817 | ; CHECK-NEXT: Name: linking |
| 686 | ; CHECK-NEXT: DataSize: 8 | 818 | ; CHECK-NEXT: Version: 1 |
| 819 | ; CHECK-NEXT: SymbolTable: | ||
| 820 | ; CHECK-NEXT: - Index: 0 | ||
| 821 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 822 | ; CHECK-NEXT: Name: f1 | ||
| 823 | ; CHECK-NEXT: Flags: [ ] | ||
| 824 | ; CHECK-NEXT: Function: 0 | ||
| 825 | ; CHECK-NEXT: - Index: 1 | ||
| 826 | ; CHECK-NEXT: Kind: DATA | ||
| 827 | ; CHECK-NEXT: Name: foo | ||
| 828 | ; CHECK-NEXT: Flags: [ ] | ||
| 829 | ; CHECK-NEXT: Segment: 1 | ||
| 830 | ; CHECK-NEXT: Size: 4 | ||
| 831 | ; CHECK-NEXT: - Index: 2 | ||
| 832 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 833 | ; CHECK-NEXT: Name: f2 | ||
| 834 | ; CHECK-NEXT: Flags: [ ] | ||
| 835 | ; CHECK-NEXT: Function: 1 | ||
| 836 | ; CHECK-NEXT: - Index: 3 | ||
| 837 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 838 | ; CHECK-NEXT: Name: f3 | ||
| 839 | ; CHECK-NEXT: Flags: [ ] | ||
| 840 | ; CHECK-NEXT: Function: 2 | ||
| 841 | ; CHECK-NEXT: - Index: 4 | ||
| 842 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 843 | ; CHECK-NEXT: Name: f4 | ||
| 844 | ; CHECK-NEXT: Flags: [ ] | ||
| 845 | ; CHECK-NEXT: Function: 3 | ||
| 846 | ; CHECK-NEXT: - Index: 5 | ||
| 847 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 848 | ; CHECK-NEXT: Name: f5 | ||
| 849 | ; CHECK-NEXT: Flags: [ ] | ||
| 850 | ; CHECK-NEXT: Function: 4 | ||
| 851 | ; CHECK-NEXT: - Index: 6 | ||
| 852 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 853 | ; CHECK-NEXT: Name: f6 | ||
| 854 | ; CHECK-NEXT: Flags: [ ] | ||
| 855 | ; CHECK-NEXT: Function: 5 | ||
| 856 | ; CHECK-NEXT: - Index: 7 | ||
| 857 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 858 | ; CHECK-NEXT: Name: f7 | ||
| 859 | ; CHECK-NEXT: Flags: [ ] | ||
| 860 | ; CHECK-NEXT: Function: 6 | ||
| 861 | ; CHECK-NEXT: - Index: 8 | ||
| 862 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 863 | ; CHECK-NEXT: Name: f8 | ||
| 864 | ; CHECK-NEXT: Flags: [ ] | ||
| 865 | ; CHECK-NEXT: Function: 7 | ||
| 866 | ; CHECK-NEXT: - Index: 9 | ||
| 867 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 868 | ; CHECK-NEXT: Name: f9 | ||
| 869 | ; CHECK-NEXT: Flags: [ ] | ||
| 870 | ; CHECK-NEXT: Function: 8 | ||
| 871 | ; CHECK-NEXT: - Index: 10 | ||
| 872 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 873 | ; CHECK-NEXT: Name: f10 | ||
| 874 | ; CHECK-NEXT: Flags: [ ] | ||
| 875 | ; CHECK-NEXT: Function: 9 | ||
| 876 | ; CHECK-NEXT: - Index: 11 | ||
| 877 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 878 | ; CHECK-NEXT: Name: f11 | ||
| 879 | ; CHECK-NEXT: Flags: [ ] | ||
| 880 | ; CHECK-NEXT: Function: 10 | ||
| 881 | ; CHECK-NEXT: - Index: 12 | ||
| 882 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 883 | ; CHECK-NEXT: Name: f12 | ||
| 884 | ; CHECK-NEXT: Flags: [ ] | ||
| 885 | ; CHECK-NEXT: Function: 11 | ||
| 886 | ; CHECK-NEXT: - Index: 13 | ||
| 887 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 888 | ; CHECK-NEXT: Name: f13 | ||
| 889 | ; CHECK-NEXT: Flags: [ ] | ||
| 890 | ; CHECK-NEXT: Function: 12 | ||
| 891 | ; CHECK-NEXT: - Index: 14 | ||
| 892 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 893 | ; CHECK-NEXT: Name: f14 | ||
| 894 | ; CHECK-NEXT: Flags: [ ] | ||
| 895 | ; CHECK-NEXT: Function: 13 | ||
| 896 | ; CHECK-NEXT: - Index: 15 | ||
| 897 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 898 | ; CHECK-NEXT: Name: f15 | ||
| 899 | ; CHECK-NEXT: Flags: [ ] | ||
| 900 | ; CHECK-NEXT: Function: 14 | ||
| 901 | ; CHECK-NEXT: - Index: 16 | ||
| 902 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 903 | ; CHECK-NEXT: Name: f16 | ||
| 904 | ; CHECK-NEXT: Flags: [ ] | ||
| 905 | ; CHECK-NEXT: Function: 15 | ||
| 906 | ; CHECK-NEXT: - Index: 17 | ||
| 907 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 908 | ; CHECK-NEXT: Name: f17 | ||
| 909 | ; CHECK-NEXT: Flags: [ ] | ||
| 910 | ; CHECK-NEXT: Function: 16 | ||
| 911 | ; CHECK-NEXT: - Index: 18 | ||
| 912 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 913 | ; CHECK-NEXT: Name: f18 | ||
| 914 | ; CHECK-NEXT: Flags: [ ] | ||
| 915 | ; CHECK-NEXT: Function: 17 | ||
| 916 | ; CHECK-NEXT: - Index: 19 | ||
| 917 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 918 | ; CHECK-NEXT: Name: f19 | ||
| 919 | ; CHECK-NEXT: Flags: [ ] | ||
| 920 | ; CHECK-NEXT: Function: 18 | ||
| 921 | ; CHECK-NEXT: - Index: 20 | ||
| 922 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 923 | ; CHECK-NEXT: Name: f20 | ||
| 924 | ; CHECK-NEXT: Flags: [ ] | ||
| 925 | ; CHECK-NEXT: Function: 19 | ||
| 926 | ; CHECK-NEXT: - Index: 21 | ||
| 927 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 928 | ; CHECK-NEXT: Name: f21 | ||
| 929 | ; CHECK-NEXT: Flags: [ ] | ||
| 930 | ; CHECK-NEXT: Function: 20 | ||
| 931 | ; CHECK-NEXT: - Index: 22 | ||
| 932 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 933 | ; CHECK-NEXT: Name: f22 | ||
| 934 | ; CHECK-NEXT: Flags: [ ] | ||
| 935 | ; CHECK-NEXT: Function: 21 | ||
| 936 | ; CHECK-NEXT: - Index: 23 | ||
| 937 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 938 | ; CHECK-NEXT: Name: f23 | ||
| 939 | ; CHECK-NEXT: Flags: [ ] | ||
| 940 | ; CHECK-NEXT: Function: 22 | ||
| 941 | ; CHECK-NEXT: - Index: 24 | ||
| 942 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 943 | ; CHECK-NEXT: Name: f24 | ||
| 944 | ; CHECK-NEXT: Flags: [ ] | ||
| 945 | ; CHECK-NEXT: Function: 23 | ||
| 946 | ; CHECK-NEXT: - Index: 25 | ||
| 947 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 948 | ; CHECK-NEXT: Name: f25 | ||
| 949 | ; CHECK-NEXT: Flags: [ ] | ||
| 950 | ; CHECK-NEXT: Function: 24 | ||
| 951 | ; CHECK-NEXT: - Index: 26 | ||
| 952 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 953 | ; CHECK-NEXT: Name: f26 | ||
| 954 | ; CHECK-NEXT: Flags: [ ] | ||
| 955 | ; CHECK-NEXT: Function: 25 | ||
| 956 | ; CHECK-NEXT: - Index: 27 | ||
| 957 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 958 | ; CHECK-NEXT: Name: f27 | ||
| 959 | ; CHECK-NEXT: Flags: [ ] | ||
| 960 | ; CHECK-NEXT: Function: 26 | ||
| 961 | ; CHECK-NEXT: - Index: 28 | ||
| 962 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 963 | ; CHECK-NEXT: Name: f28 | ||
| 964 | ; CHECK-NEXT: Flags: [ ] | ||
| 965 | ; CHECK-NEXT: Function: 27 | ||
| 966 | ; CHECK-NEXT: - Index: 29 | ||
| 967 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 968 | ; CHECK-NEXT: Name: f29 | ||
| 969 | ; CHECK-NEXT: Flags: [ ] | ||
| 970 | ; CHECK-NEXT: Function: 28 | ||
| 971 | ; CHECK-NEXT: - Index: 30 | ||
| 972 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 973 | ; CHECK-NEXT: Name: f30 | ||
| 974 | ; CHECK-NEXT: Flags: [ ] | ||
| 975 | ; CHECK-NEXT: Function: 29 | ||
| 976 | ; CHECK-NEXT: - Index: 31 | ||
| 977 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 978 | ; CHECK-NEXT: Name: f31 | ||
| 979 | ; CHECK-NEXT: Flags: [ ] | ||
| 980 | ; CHECK-NEXT: Function: 30 | ||
| 981 | ; CHECK-NEXT: - Index: 32 | ||
| 982 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 983 | ; CHECK-NEXT: Name: f32 | ||
| 984 | ; CHECK-NEXT: Flags: [ ] | ||
| 985 | ; CHECK-NEXT: Function: 31 | ||
| 986 | ; CHECK-NEXT: - Index: 33 | ||
| 987 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 988 | ; CHECK-NEXT: Name: f33 | ||
| 989 | ; CHECK-NEXT: Flags: [ ] | ||
| 990 | ; CHECK-NEXT: Function: 32 | ||
| 991 | ; CHECK-NEXT: - Index: 34 | ||
| 992 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 993 | ; CHECK-NEXT: Name: f34 | ||
| 994 | ; CHECK-NEXT: Flags: [ ] | ||
| 995 | ; CHECK-NEXT: Function: 33 | ||
| 996 | ; CHECK-NEXT: - Index: 35 | ||
| 997 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 998 | ; CHECK-NEXT: Name: f35 | ||
| 999 | ; CHECK-NEXT: Flags: [ ] | ||
| 1000 | ; CHECK-NEXT: Function: 34 | ||
| 1001 | ; CHECK-NEXT: - Index: 36 | ||
| 1002 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1003 | ; CHECK-NEXT: Name: f36 | ||
| 1004 | ; CHECK-NEXT: Flags: [ ] | ||
| 1005 | ; CHECK-NEXT: Function: 35 | ||
| 1006 | ; CHECK-NEXT: - Index: 37 | ||
| 1007 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1008 | ; CHECK-NEXT: Name: f37 | ||
| 1009 | ; CHECK-NEXT: Flags: [ ] | ||
| 1010 | ; CHECK-NEXT: Function: 36 | ||
| 1011 | ; CHECK-NEXT: - Index: 38 | ||
| 1012 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1013 | ; CHECK-NEXT: Name: f38 | ||
| 1014 | ; CHECK-NEXT: Flags: [ ] | ||
| 1015 | ; CHECK-NEXT: Function: 37 | ||
| 1016 | ; CHECK-NEXT: - Index: 39 | ||
| 1017 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1018 | ; CHECK-NEXT: Name: f39 | ||
| 1019 | ; CHECK-NEXT: Flags: [ ] | ||
| 1020 | ; CHECK-NEXT: Function: 38 | ||
| 1021 | ; CHECK-NEXT: - Index: 40 | ||
| 1022 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1023 | ; CHECK-NEXT: Name: f40 | ||
| 1024 | ; CHECK-NEXT: Flags: [ ] | ||
| 1025 | ; CHECK-NEXT: Function: 39 | ||
| 1026 | ; CHECK-NEXT: - Index: 41 | ||
| 1027 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1028 | ; CHECK-NEXT: Name: f41 | ||
| 1029 | ; CHECK-NEXT: Flags: [ ] | ||
| 1030 | ; CHECK-NEXT: Function: 40 | ||
| 1031 | ; CHECK-NEXT: - Index: 42 | ||
| 1032 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1033 | ; CHECK-NEXT: Name: f42 | ||
| 1034 | ; CHECK-NEXT: Flags: [ ] | ||
| 1035 | ; CHECK-NEXT: Function: 41 | ||
| 1036 | ; CHECK-NEXT: - Index: 43 | ||
| 1037 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1038 | ; CHECK-NEXT: Name: f43 | ||
| 1039 | ; CHECK-NEXT: Flags: [ ] | ||
| 1040 | ; CHECK-NEXT: Function: 42 | ||
| 1041 | ; CHECK-NEXT: - Index: 44 | ||
| 1042 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1043 | ; CHECK-NEXT: Name: f44 | ||
| 1044 | ; CHECK-NEXT: Flags: [ ] | ||
| 1045 | ; CHECK-NEXT: Function: 43 | ||
| 1046 | ; CHECK-NEXT: - Index: 45 | ||
| 1047 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1048 | ; CHECK-NEXT: Name: f45 | ||
| 1049 | ; CHECK-NEXT: Flags: [ ] | ||
| 1050 | ; CHECK-NEXT: Function: 44 | ||
| 1051 | ; CHECK-NEXT: - Index: 46 | ||
| 1052 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1053 | ; CHECK-NEXT: Name: f46 | ||
| 1054 | ; CHECK-NEXT: Flags: [ ] | ||
| 1055 | ; CHECK-NEXT: Function: 45 | ||
| 1056 | ; CHECK-NEXT: - Index: 47 | ||
| 1057 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1058 | ; CHECK-NEXT: Name: f47 | ||
| 1059 | ; CHECK-NEXT: Flags: [ ] | ||
| 1060 | ; CHECK-NEXT: Function: 46 | ||
| 1061 | ; CHECK-NEXT: - Index: 48 | ||
| 1062 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1063 | ; CHECK-NEXT: Name: f48 | ||
| 1064 | ; CHECK-NEXT: Flags: [ ] | ||
| 1065 | ; CHECK-NEXT: Function: 47 | ||
| 1066 | ; CHECK-NEXT: - Index: 49 | ||
| 1067 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1068 | ; CHECK-NEXT: Name: f49 | ||
| 1069 | ; CHECK-NEXT: Flags: [ ] | ||
| 1070 | ; CHECK-NEXT: Function: 48 | ||
| 1071 | ; CHECK-NEXT: - Index: 50 | ||
| 1072 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1073 | ; CHECK-NEXT: Name: f50 | ||
| 1074 | ; CHECK-NEXT: Flags: [ ] | ||
| 1075 | ; CHECK-NEXT: Function: 49 | ||
| 1076 | ; CHECK-NEXT: - Index: 51 | ||
| 1077 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1078 | ; CHECK-NEXT: Name: f51 | ||
| 1079 | ; CHECK-NEXT: Flags: [ ] | ||
| 1080 | ; CHECK-NEXT: Function: 50 | ||
| 1081 | ; CHECK-NEXT: - Index: 52 | ||
| 1082 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1083 | ; CHECK-NEXT: Name: f52 | ||
| 1084 | ; CHECK-NEXT: Flags: [ ] | ||
| 1085 | ; CHECK-NEXT: Function: 51 | ||
| 1086 | ; CHECK-NEXT: - Index: 53 | ||
| 1087 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1088 | ; CHECK-NEXT: Name: f53 | ||
| 1089 | ; CHECK-NEXT: Flags: [ ] | ||
| 1090 | ; CHECK-NEXT: Function: 52 | ||
| 1091 | ; CHECK-NEXT: - Index: 54 | ||
| 1092 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1093 | ; CHECK-NEXT: Name: f54 | ||
| 1094 | ; CHECK-NEXT: Flags: [ ] | ||
| 1095 | ; CHECK-NEXT: Function: 53 | ||
| 1096 | ; CHECK-NEXT: - Index: 55 | ||
| 1097 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1098 | ; CHECK-NEXT: Name: f55 | ||
| 1099 | ; CHECK-NEXT: Flags: [ ] | ||
| 1100 | ; CHECK-NEXT: Function: 54 | ||
| 1101 | ; CHECK-NEXT: - Index: 56 | ||
| 1102 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1103 | ; CHECK-NEXT: Name: f56 | ||
| 1104 | ; CHECK-NEXT: Flags: [ ] | ||
| 1105 | ; CHECK-NEXT: Function: 55 | ||
| 1106 | ; CHECK-NEXT: - Index: 57 | ||
| 1107 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1108 | ; CHECK-NEXT: Name: f57 | ||
| 1109 | ; CHECK-NEXT: Flags: [ ] | ||
| 1110 | ; CHECK-NEXT: Function: 56 | ||
| 1111 | ; CHECK-NEXT: - Index: 58 | ||
| 1112 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1113 | ; CHECK-NEXT: Name: f58 | ||
| 1114 | ; CHECK-NEXT: Flags: [ ] | ||
| 1115 | ; CHECK-NEXT: Function: 57 | ||
| 1116 | ; CHECK-NEXT: - Index: 59 | ||
| 1117 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1118 | ; CHECK-NEXT: Name: f59 | ||
| 1119 | ; CHECK-NEXT: Flags: [ ] | ||
| 1120 | ; CHECK-NEXT: Function: 58 | ||
| 1121 | ; CHECK-NEXT: - Index: 60 | ||
| 1122 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1123 | ; CHECK-NEXT: Name: f60 | ||
| 1124 | ; CHECK-NEXT: Flags: [ ] | ||
| 1125 | ; CHECK-NEXT: Function: 59 | ||
| 1126 | ; CHECK-NEXT: - Index: 61 | ||
| 1127 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1128 | ; CHECK-NEXT: Name: f61 | ||
| 1129 | ; CHECK-NEXT: Flags: [ ] | ||
| 1130 | ; CHECK-NEXT: Function: 60 | ||
| 1131 | ; CHECK-NEXT: - Index: 62 | ||
| 1132 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1133 | ; CHECK-NEXT: Name: f62 | ||
| 1134 | ; CHECK-NEXT: Flags: [ ] | ||
| 1135 | ; CHECK-NEXT: Function: 61 | ||
| 1136 | ; CHECK-NEXT: - Index: 63 | ||
| 1137 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1138 | ; CHECK-NEXT: Name: f63 | ||
| 1139 | ; CHECK-NEXT: Flags: [ ] | ||
| 1140 | ; CHECK-NEXT: Function: 62 | ||
| 1141 | ; CHECK-NEXT: - Index: 64 | ||
| 1142 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1143 | ; CHECK-NEXT: Name: f64 | ||
| 1144 | ; CHECK-NEXT: Flags: [ ] | ||
| 1145 | ; CHECK-NEXT: Function: 63 | ||
| 1146 | ; CHECK-NEXT: - Index: 65 | ||
| 1147 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1148 | ; CHECK-NEXT: Name: f65 | ||
| 1149 | ; CHECK-NEXT: Flags: [ ] | ||
| 1150 | ; CHECK-NEXT: Function: 64 | ||
| 1151 | ; CHECK-NEXT: - Index: 66 | ||
| 1152 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1153 | ; CHECK-NEXT: Name: f66 | ||
| 1154 | ; CHECK-NEXT: Flags: [ ] | ||
| 1155 | ; CHECK-NEXT: Function: 65 | ||
| 1156 | ; CHECK-NEXT: - Index: 67 | ||
| 1157 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1158 | ; CHECK-NEXT: Name: f67 | ||
| 1159 | ; CHECK-NEXT: Flags: [ ] | ||
| 1160 | ; CHECK-NEXT: Function: 66 | ||
| 1161 | ; CHECK-NEXT: - Index: 68 | ||
| 1162 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1163 | ; CHECK-NEXT: Name: f68 | ||
| 1164 | ; CHECK-NEXT: Flags: [ ] | ||
| 1165 | ; CHECK-NEXT: Function: 67 | ||
| 1166 | ; CHECK-NEXT: - Index: 69 | ||
| 1167 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1168 | ; CHECK-NEXT: Name: f69 | ||
| 1169 | ; CHECK-NEXT: Flags: [ ] | ||
| 1170 | ; CHECK-NEXT: Function: 68 | ||
| 1171 | ; CHECK-NEXT: - Index: 70 | ||
| 1172 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1173 | ; CHECK-NEXT: Name: f70 | ||
| 1174 | ; CHECK-NEXT: Flags: [ ] | ||
| 1175 | ; CHECK-NEXT: Function: 69 | ||
| 1176 | ; CHECK-NEXT: - Index: 71 | ||
| 1177 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1178 | ; CHECK-NEXT: Name: f71 | ||
| 1179 | ; CHECK-NEXT: Flags: [ ] | ||
| 1180 | ; CHECK-NEXT: Function: 70 | ||
| 1181 | ; CHECK-NEXT: - Index: 72 | ||
| 1182 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1183 | ; CHECK-NEXT: Name: f72 | ||
| 1184 | ; CHECK-NEXT: Flags: [ ] | ||
| 1185 | ; CHECK-NEXT: Function: 71 | ||
| 1186 | ; CHECK-NEXT: - Index: 73 | ||
| 1187 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1188 | ; CHECK-NEXT: Name: f73 | ||
| 1189 | ; CHECK-NEXT: Flags: [ ] | ||
| 1190 | ; CHECK-NEXT: Function: 72 | ||
| 1191 | ; CHECK-NEXT: - Index: 74 | ||
| 1192 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1193 | ; CHECK-NEXT: Name: f74 | ||
| 1194 | ; CHECK-NEXT: Flags: [ ] | ||
| 1195 | ; CHECK-NEXT: Function: 73 | ||
| 1196 | ; CHECK-NEXT: - Index: 75 | ||
| 1197 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1198 | ; CHECK-NEXT: Name: f75 | ||
| 1199 | ; CHECK-NEXT: Flags: [ ] | ||
| 1200 | ; CHECK-NEXT: Function: 74 | ||
| 1201 | ; CHECK-NEXT: - Index: 76 | ||
| 1202 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1203 | ; CHECK-NEXT: Name: f76 | ||
| 1204 | ; CHECK-NEXT: Flags: [ ] | ||
| 1205 | ; CHECK-NEXT: Function: 75 | ||
| 1206 | ; CHECK-NEXT: - Index: 77 | ||
| 1207 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1208 | ; CHECK-NEXT: Name: f77 | ||
| 1209 | ; CHECK-NEXT: Flags: [ ] | ||
| 1210 | ; CHECK-NEXT: Function: 76 | ||
| 1211 | ; CHECK-NEXT: - Index: 78 | ||
| 1212 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1213 | ; CHECK-NEXT: Name: f78 | ||
| 1214 | ; CHECK-NEXT: Flags: [ ] | ||
| 1215 | ; CHECK-NEXT: Function: 77 | ||
| 1216 | ; CHECK-NEXT: - Index: 79 | ||
| 1217 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1218 | ; CHECK-NEXT: Name: f79 | ||
| 1219 | ; CHECK-NEXT: Flags: [ ] | ||
| 1220 | ; CHECK-NEXT: Function: 78 | ||
| 1221 | ; CHECK-NEXT: - Index: 80 | ||
| 1222 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1223 | ; CHECK-NEXT: Name: f80 | ||
| 1224 | ; CHECK-NEXT: Flags: [ ] | ||
| 1225 | ; CHECK-NEXT: Function: 79 | ||
| 1226 | ; CHECK-NEXT: - Index: 81 | ||
| 1227 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1228 | ; CHECK-NEXT: Name: f81 | ||
| 1229 | ; CHECK-NEXT: Flags: [ ] | ||
| 1230 | ; CHECK-NEXT: Function: 80 | ||
| 1231 | ; CHECK-NEXT: - Index: 82 | ||
| 1232 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1233 | ; CHECK-NEXT: Name: f82 | ||
| 1234 | ; CHECK-NEXT: Flags: [ ] | ||
| 1235 | ; CHECK-NEXT: Function: 81 | ||
| 1236 | ; CHECK-NEXT: - Index: 83 | ||
| 1237 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1238 | ; CHECK-NEXT: Name: f83 | ||
| 1239 | ; CHECK-NEXT: Flags: [ ] | ||
| 1240 | ; CHECK-NEXT: Function: 82 | ||
| 1241 | ; CHECK-NEXT: - Index: 84 | ||
| 1242 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1243 | ; CHECK-NEXT: Name: f84 | ||
| 1244 | ; CHECK-NEXT: Flags: [ ] | ||
| 1245 | ; CHECK-NEXT: Function: 83 | ||
| 1246 | ; CHECK-NEXT: - Index: 85 | ||
| 1247 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1248 | ; CHECK-NEXT: Name: f85 | ||
| 1249 | ; CHECK-NEXT: Flags: [ ] | ||
| 1250 | ; CHECK-NEXT: Function: 84 | ||
| 1251 | ; CHECK-NEXT: - Index: 86 | ||
| 1252 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1253 | ; CHECK-NEXT: Name: f86 | ||
| 1254 | ; CHECK-NEXT: Flags: [ ] | ||
| 1255 | ; CHECK-NEXT: Function: 85 | ||
| 1256 | ; CHECK-NEXT: - Index: 87 | ||
| 1257 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1258 | ; CHECK-NEXT: Name: f87 | ||
| 1259 | ; CHECK-NEXT: Flags: [ ] | ||
| 1260 | ; CHECK-NEXT: Function: 86 | ||
| 1261 | ; CHECK-NEXT: - Index: 88 | ||
| 1262 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1263 | ; CHECK-NEXT: Name: f88 | ||
| 1264 | ; CHECK-NEXT: Flags: [ ] | ||
| 1265 | ; CHECK-NEXT: Function: 87 | ||
| 1266 | ; CHECK-NEXT: - Index: 89 | ||
| 1267 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1268 | ; CHECK-NEXT: Name: f89 | ||
| 1269 | ; CHECK-NEXT: Flags: [ ] | ||
| 1270 | ; CHECK-NEXT: Function: 88 | ||
| 1271 | ; CHECK-NEXT: - Index: 90 | ||
| 1272 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1273 | ; CHECK-NEXT: Name: f90 | ||
| 1274 | ; CHECK-NEXT: Flags: [ ] | ||
| 1275 | ; CHECK-NEXT: Function: 89 | ||
| 1276 | ; CHECK-NEXT: - Index: 91 | ||
| 1277 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1278 | ; CHECK-NEXT: Name: f91 | ||
| 1279 | ; CHECK-NEXT: Flags: [ ] | ||
| 1280 | ; CHECK-NEXT: Function: 90 | ||
| 1281 | ; CHECK-NEXT: - Index: 92 | ||
| 1282 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1283 | ; CHECK-NEXT: Name: f92 | ||
| 1284 | ; CHECK-NEXT: Flags: [ ] | ||
| 1285 | ; CHECK-NEXT: Function: 91 | ||
| 1286 | ; CHECK-NEXT: - Index: 93 | ||
| 1287 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1288 | ; CHECK-NEXT: Name: f93 | ||
| 1289 | ; CHECK-NEXT: Flags: [ ] | ||
| 1290 | ; CHECK-NEXT: Function: 92 | ||
| 1291 | ; CHECK-NEXT: - Index: 94 | ||
| 1292 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1293 | ; CHECK-NEXT: Name: f94 | ||
| 1294 | ; CHECK-NEXT: Flags: [ ] | ||
| 1295 | ; CHECK-NEXT: Function: 93 | ||
| 1296 | ; CHECK-NEXT: - Index: 95 | ||
| 1297 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1298 | ; CHECK-NEXT: Name: f95 | ||
| 1299 | ; CHECK-NEXT: Flags: [ ] | ||
| 1300 | ; CHECK-NEXT: Function: 94 | ||
| 1301 | ; CHECK-NEXT: - Index: 96 | ||
| 1302 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1303 | ; CHECK-NEXT: Name: f96 | ||
| 1304 | ; CHECK-NEXT: Flags: [ ] | ||
| 1305 | ; CHECK-NEXT: Function: 95 | ||
| 1306 | ; CHECK-NEXT: - Index: 97 | ||
| 1307 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1308 | ; CHECK-NEXT: Name: f97 | ||
| 1309 | ; CHECK-NEXT: Flags: [ ] | ||
| 1310 | ; CHECK-NEXT: Function: 96 | ||
| 1311 | ; CHECK-NEXT: - Index: 98 | ||
| 1312 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1313 | ; CHECK-NEXT: Name: f98 | ||
| 1314 | ; CHECK-NEXT: Flags: [ ] | ||
| 1315 | ; CHECK-NEXT: Function: 97 | ||
| 1316 | ; CHECK-NEXT: - Index: 99 | ||
| 1317 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1318 | ; CHECK-NEXT: Name: f99 | ||
| 1319 | ; CHECK-NEXT: Flags: [ ] | ||
| 1320 | ; CHECK-NEXT: Function: 98 | ||
| 1321 | ; CHECK-NEXT: - Index: 100 | ||
| 1322 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1323 | ; CHECK-NEXT: Name: f100 | ||
| 1324 | ; CHECK-NEXT: Flags: [ ] | ||
| 1325 | ; CHECK-NEXT: Function: 99 | ||
| 1326 | ; CHECK-NEXT: - Index: 101 | ||
| 1327 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1328 | ; CHECK-NEXT: Name: f101 | ||
| 1329 | ; CHECK-NEXT: Flags: [ ] | ||
| 1330 | ; CHECK-NEXT: Function: 100 | ||
| 1331 | ; CHECK-NEXT: - Index: 102 | ||
| 1332 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1333 | ; CHECK-NEXT: Name: f102 | ||
| 1334 | ; CHECK-NEXT: Flags: [ ] | ||
| 1335 | ; CHECK-NEXT: Function: 101 | ||
| 1336 | ; CHECK-NEXT: - Index: 103 | ||
| 1337 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1338 | ; CHECK-NEXT: Name: f103 | ||
| 1339 | ; CHECK-NEXT: Flags: [ ] | ||
| 1340 | ; CHECK-NEXT: Function: 102 | ||
| 1341 | ; CHECK-NEXT: - Index: 104 | ||
| 1342 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1343 | ; CHECK-NEXT: Name: f104 | ||
| 1344 | ; CHECK-NEXT: Flags: [ ] | ||
| 1345 | ; CHECK-NEXT: Function: 103 | ||
| 1346 | ; CHECK-NEXT: - Index: 105 | ||
| 1347 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1348 | ; CHECK-NEXT: Name: f105 | ||
| 1349 | ; CHECK-NEXT: Flags: [ ] | ||
| 1350 | ; CHECK-NEXT: Function: 104 | ||
| 1351 | ; CHECK-NEXT: - Index: 106 | ||
| 1352 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1353 | ; CHECK-NEXT: Name: f106 | ||
| 1354 | ; CHECK-NEXT: Flags: [ ] | ||
| 1355 | ; CHECK-NEXT: Function: 105 | ||
| 1356 | ; CHECK-NEXT: - Index: 107 | ||
| 1357 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1358 | ; CHECK-NEXT: Name: f107 | ||
| 1359 | ; CHECK-NEXT: Flags: [ ] | ||
| 1360 | ; CHECK-NEXT: Function: 106 | ||
| 1361 | ; CHECK-NEXT: - Index: 108 | ||
| 1362 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1363 | ; CHECK-NEXT: Name: f108 | ||
| 1364 | ; CHECK-NEXT: Flags: [ ] | ||
| 1365 | ; CHECK-NEXT: Function: 107 | ||
| 1366 | ; CHECK-NEXT: - Index: 109 | ||
| 1367 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1368 | ; CHECK-NEXT: Name: f109 | ||
| 1369 | ; CHECK-NEXT: Flags: [ ] | ||
| 1370 | ; CHECK-NEXT: Function: 108 | ||
| 1371 | ; CHECK-NEXT: - Index: 110 | ||
| 1372 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1373 | ; CHECK-NEXT: Name: f110 | ||
| 1374 | ; CHECK-NEXT: Flags: [ ] | ||
| 1375 | ; CHECK-NEXT: Function: 109 | ||
| 1376 | ; CHECK-NEXT: - Index: 111 | ||
| 1377 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1378 | ; CHECK-NEXT: Name: f111 | ||
| 1379 | ; CHECK-NEXT: Flags: [ ] | ||
| 1380 | ; CHECK-NEXT: Function: 110 | ||
| 1381 | ; CHECK-NEXT: - Index: 112 | ||
| 1382 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1383 | ; CHECK-NEXT: Name: f112 | ||
| 1384 | ; CHECK-NEXT: Flags: [ ] | ||
| 1385 | ; CHECK-NEXT: Function: 111 | ||
| 1386 | ; CHECK-NEXT: - Index: 113 | ||
| 1387 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1388 | ; CHECK-NEXT: Name: f113 | ||
| 1389 | ; CHECK-NEXT: Flags: [ ] | ||
| 1390 | ; CHECK-NEXT: Function: 112 | ||
| 1391 | ; CHECK-NEXT: - Index: 114 | ||
| 1392 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1393 | ; CHECK-NEXT: Name: f114 | ||
| 1394 | ; CHECK-NEXT: Flags: [ ] | ||
| 1395 | ; CHECK-NEXT: Function: 113 | ||
| 1396 | ; CHECK-NEXT: - Index: 115 | ||
| 1397 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1398 | ; CHECK-NEXT: Name: f115 | ||
| 1399 | ; CHECK-NEXT: Flags: [ ] | ||
| 1400 | ; CHECK-NEXT: Function: 114 | ||
| 1401 | ; CHECK-NEXT: - Index: 116 | ||
| 1402 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1403 | ; CHECK-NEXT: Name: f116 | ||
| 1404 | ; CHECK-NEXT: Flags: [ ] | ||
| 1405 | ; CHECK-NEXT: Function: 115 | ||
| 1406 | ; CHECK-NEXT: - Index: 117 | ||
| 1407 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1408 | ; CHECK-NEXT: Name: f117 | ||
| 1409 | ; CHECK-NEXT: Flags: [ ] | ||
| 1410 | ; CHECK-NEXT: Function: 116 | ||
| 1411 | ; CHECK-NEXT: - Index: 118 | ||
| 1412 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1413 | ; CHECK-NEXT: Name: f118 | ||
| 1414 | ; CHECK-NEXT: Flags: [ ] | ||
| 1415 | ; CHECK-NEXT: Function: 117 | ||
| 1416 | ; CHECK-NEXT: - Index: 119 | ||
| 1417 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1418 | ; CHECK-NEXT: Name: f119 | ||
| 1419 | ; CHECK-NEXT: Flags: [ ] | ||
| 1420 | ; CHECK-NEXT: Function: 118 | ||
| 1421 | ; CHECK-NEXT: - Index: 120 | ||
| 1422 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1423 | ; CHECK-NEXT: Name: f120 | ||
| 1424 | ; CHECK-NEXT: Flags: [ ] | ||
| 1425 | ; CHECK-NEXT: Function: 119 | ||
| 1426 | ; CHECK-NEXT: - Index: 121 | ||
| 1427 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1428 | ; CHECK-NEXT: Name: f121 | ||
| 1429 | ; CHECK-NEXT: Flags: [ ] | ||
| 1430 | ; CHECK-NEXT: Function: 120 | ||
| 1431 | ; CHECK-NEXT: - Index: 122 | ||
| 1432 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1433 | ; CHECK-NEXT: Name: f122 | ||
| 1434 | ; CHECK-NEXT: Flags: [ ] | ||
| 1435 | ; CHECK-NEXT: Function: 121 | ||
| 1436 | ; CHECK-NEXT: - Index: 123 | ||
| 1437 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1438 | ; CHECK-NEXT: Name: f123 | ||
| 1439 | ; CHECK-NEXT: Flags: [ ] | ||
| 1440 | ; CHECK-NEXT: Function: 122 | ||
| 1441 | ; CHECK-NEXT: - Index: 124 | ||
| 1442 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1443 | ; CHECK-NEXT: Name: f124 | ||
| 1444 | ; CHECK-NEXT: Flags: [ ] | ||
| 1445 | ; CHECK-NEXT: Function: 123 | ||
| 1446 | ; CHECK-NEXT: - Index: 125 | ||
| 1447 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1448 | ; CHECK-NEXT: Name: f125 | ||
| 1449 | ; CHECK-NEXT: Flags: [ ] | ||
| 1450 | ; CHECK-NEXT: Function: 124 | ||
| 1451 | ; CHECK-NEXT: - Index: 126 | ||
| 1452 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1453 | ; CHECK-NEXT: Name: f126 | ||
| 1454 | ; CHECK-NEXT: Flags: [ ] | ||
| 1455 | ; CHECK-NEXT: Function: 125 | ||
| 1456 | ; CHECK-NEXT: - Index: 127 | ||
| 1457 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1458 | ; CHECK-NEXT: Name: f127 | ||
| 1459 | ; CHECK-NEXT: Flags: [ ] | ||
| 1460 | ; CHECK-NEXT: Function: 126 | ||
| 1461 | ; CHECK-NEXT: - Index: 128 | ||
| 1462 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1463 | ; CHECK-NEXT: Name: f128 | ||
| 1464 | ; CHECK-NEXT: Flags: [ ] | ||
| 1465 | ; CHECK-NEXT: Function: 127 | ||
| 1466 | ; CHECK-NEXT: - Index: 129 | ||
| 1467 | ; CHECK-NEXT: Kind: DATA | ||
| 1468 | ; CHECK-NEXT: Name: g0 | ||
| 1469 | ; CHECK-NEXT: Flags: [ ] | ||
| 1470 | ; CHECK-NEXT: Segment: 0 | ||
| 1471 | ; CHECK-NEXT: Size: 4 | ||
| 1472 | ; CHECK-NEXT: - Index: 130 | ||
| 1473 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1474 | ; CHECK-NEXT: Name: f129 | ||
| 1475 | ; CHECK-NEXT: Flags: [ ] | ||
| 1476 | ; CHECK-NEXT: Function: 128 | ||
| 1477 | ; CHECK-NEXT: - Index: 131 | ||
| 1478 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 1479 | ; CHECK-NEXT: Name: func | ||
| 1480 | ; CHECK-NEXT: Flags: [ ] | ||
| 1481 | ; CHECK-NEXT: Function: 129 | ||
| 687 | ; CHECK-NEXT: SegmentInfo: | 1482 | ; CHECK-NEXT: SegmentInfo: |
| 688 | ; CHECK-NEXT: - Index: 0 | 1483 | ; CHECK-NEXT: - Index: 0 |
| 689 | ; CHECK-NEXT: Name: .data.g0 | 1484 | ; CHECK-NEXT: Name: .data.g0 |
deps/lld/test/wasm/reloc-addend.ll created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 2 | ; RUN: wasm-ld -r -o %t.wasm %t.o | ||
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 4 | |||
| 5 | target triple = "wasm32-unknown-unknown" | ||
| 6 | |||
| 7 | @foo = hidden global [76 x i32] zeroinitializer, align 16 | ||
| 8 | |||
| 9 | ; bar points to the 16th element, which happens to be 64 bytes | ||
| 10 | ; This generates an addend of 64 which, is the value at which | ||
| 11 | ; signed and unsigned LEB encodes will differ. | ||
| 12 | @bar = hidden local_unnamed_addr global i32* getelementptr inbounds ([76 x i32], [76 x i32]* @foo, i32 0, i32 16), align 4 | ||
| 13 | |||
| 14 | ; CHECK: - Type: DATA | ||
| 15 | ; CHECK-NEXT: Relocations: | ||
| 16 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 | ||
| 17 | ; CHECK-NEXT: Index: 0 | ||
| 18 | ; CHECK-NEXT: Offset: 0x0000013D | ||
| 19 | ; CHECK-NEXT: Addend: 64 | ||
deps/lld/test/wasm/relocatable.ll+162-77| ... | @@ -1,22 +1,34 @@ | ... | @@ -1,22 +1,34 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/hello.ll -o %t.hello.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/hello.ll -o %t.hello.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 2 | ; RUN: llc -filetype=obj %s -o %t.o |
| 3 | ; RUN: lld -flavor wasm -r -o %t.wasm %t.hello.o %t.o | 3 | ; RUN: wasm-ld -r -o %t.wasm %t.hello.o %t.o |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 5 | 5 | ||
| 6 | target triple = "wasm32-unknown-unknown" | ||
| 7 | |||
| 6 | ; Function Attrs: nounwind | 8 | ; Function Attrs: nounwind |
| 7 | define hidden i32 @my_func() local_unnamed_addr { | 9 | define hidden i32 @my_func() local_unnamed_addr { |
| 8 | entry: | 10 | entry: |
| 9 | %call = tail call i32 @foo_import() | 11 | %call = tail call i32 @foo_import() |
| 12 | %call2 = tail call i32 @bar_import() | ||
| 10 | ret i32 1 | 13 | ret i32 1 |
| 11 | } | 14 | } |
| 12 | 15 | ||
| 13 | declare i32 @foo_import() local_unnamed_addr | 16 | declare i32 @foo_import() local_unnamed_addr |
| 17 | declare extern_weak i32 @bar_import() local_unnamed_addr | ||
| 14 | @data_import = external global i64 | 18 | @data_import = external global i64 |
| 15 | 19 | ||
| 16 | @func_addr1 = hidden global i32()* @my_func, align 4 | 20 | @func_addr1 = hidden global i32()* @my_func, align 4 |
| 17 | @func_addr2 = hidden global i32()* @foo_import, align 4 | 21 | @func_addr2 = hidden global i32()* @foo_import, align 4 |
| 22 | @func_addr3 = hidden global i32()* @bar_import, align 4 | ||
| 18 | @data_addr1 = hidden global i64* @data_import, align 8 | 23 | @data_addr1 = hidden global i64* @data_import, align 8 |
| 19 | 24 | ||
| 25 | $func_comdat = comdat any | ||
| 26 | @data_comdat = weak_odr constant [3 x i8] c"abc", comdat($func_comdat) | ||
| 27 | define linkonce_odr i32 @func_comdat() comdat { | ||
| 28 | entry: | ||
| 29 | ret i32 ptrtoint ([3 x i8]* @data_comdat to i32) | ||
| 30 | } | ||
| 31 | |||
| 20 | ; CHECK: --- !WASM | 32 | ; CHECK: --- !WASM |
| 21 | ; CHECK-NEXT: FileHeader: | 33 | ; CHECK-NEXT: FileHeader: |
| 22 | ; CHECK-NEXT: Version: 0x00000001 | 34 | ; CHECK-NEXT: Version: 0x00000001 |
| ... | @@ -26,115 +38,86 @@ declare i32 @foo_import() local_unnamed_addr | ... | @@ -26,115 +38,86 @@ declare i32 @foo_import() local_unnamed_addr |
| 26 | ; CHECK-NEXT: - Index: 0 | 38 | ; CHECK-NEXT: - Index: 0 |
| 27 | ; CHECK-NEXT: ReturnType: NORESULT | 39 | ; CHECK-NEXT: ReturnType: NORESULT |
| 28 | ; CHECK-NEXT: ParamTypes: | 40 | ; CHECK-NEXT: ParamTypes: |
| 41 | ; CHECK-NEXT: - I32 | ||
| 29 | ; CHECK-NEXT: - Index: 1 | 42 | ; CHECK-NEXT: - Index: 1 |
| 30 | ; CHECK-NEXT: ReturnType: NORESULT | 43 | ; CHECK-NEXT: ReturnType: I32 |
| 31 | ; CHECK-NEXT: ParamTypes: | 44 | ; CHECK-NEXT: ParamTypes: |
| 32 | ; CHECK-NEXT: - I32 | ||
| 33 | ; CHECK-NEXT: - Index: 2 | 45 | ; CHECK-NEXT: - Index: 2 |
| 34 | ; CHECK-NEXT: ReturnType: I32 | 46 | ; CHECK-NEXT: ReturnType: NORESULT |
| 35 | ; CHECK-NEXT: ParamTypes: | 47 | ; CHECK-NEXT: ParamTypes: |
| 36 | ; CHECK-NEXT: - Type: IMPORT | 48 | ; CHECK-NEXT: - Type: IMPORT |
| 37 | ; CHECK-NEXT: Imports: | 49 | ; CHECK-NEXT: Imports: |
| 38 | ; CHECK-NEXT: - Module: env | 50 | ; CHECK-NEXT: - Module: env |
| 39 | ; CHECK-NEXT: Field: puts | 51 | ; CHECK-NEXT: Field: puts |
| 40 | ; CHECK-NEXT: Kind: FUNCTION | 52 | ; CHECK-NEXT: Kind: FUNCTION |
| 41 | ; CHECK-NEXT: SigIndex: 1 | 53 | ; CHECK-NEXT: SigIndex: 0 |
| 42 | ; CHECK-NEXT: - Module: env | 54 | ; CHECK-NEXT: - Module: env |
| 43 | ; CHECK-NEXT: Field: foo_import | 55 | ; CHECK-NEXT: Field: foo_import |
| 44 | ; CHECK-NEXT: Kind: FUNCTION | 56 | ; CHECK-NEXT: Kind: FUNCTION |
| 45 | ; CHECK-NEXT: SigIndex: 2 | 57 | ; CHECK-NEXT: SigIndex: 1 |
| 46 | ; CHECK-NEXT: - Module: env | 58 | ; CHECK-NEXT: - Module: env |
| 47 | ; CHECK-NEXT: Field: data_import | 59 | ; CHECK-NEXT: Field: bar_import |
| 48 | ; CHECK-NEXT: Kind: GLOBAL | 60 | ; CHECK-NEXT: Kind: FUNCTION |
| 49 | ; CHECK-NEXT: GlobalType: I32 | 61 | ; CHECK-NEXT: SigIndex: 1 |
| 50 | ; CHECK-NEXT: GlobalMutable: false | ||
| 51 | ; CHECK-NEXT: - Type: FUNCTION | 62 | ; CHECK-NEXT: - Type: FUNCTION |
| 52 | ; CHECK-NEXT: FunctionTypes: [ 0, 2 ] | 63 | ; CHECK-NEXT: FunctionTypes: [ 2, 1, 1 ] |
| 53 | ; CHECK-NEXT: - Type: TABLE | 64 | ; CHECK-NEXT: - Type: TABLE |
| 54 | ; CHECK-NEXT: Tables: | 65 | ; CHECK-NEXT: Tables: |
| 55 | ; CHECK-NEXT: - ElemType: ANYFUNC | 66 | ; CHECK-NEXT: - ElemType: ANYFUNC |
| 56 | ; CHECK-NEXT: Limits: | 67 | ; CHECK-NEXT: Limits: |
| 57 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | 68 | ; CHECK-NEXT: Flags: [ HAS_MAX ] |
| 58 | ; CHECK-NEXT: Initial: 0x00000002 | 69 | ; CHECK-NEXT: Initial: 0x00000004 |
| 59 | ; CHECK-NEXT: Maximum: 0x00000002 | 70 | ; CHECK-NEXT: Maximum: 0x00000004 |
| 60 | ; CHECK-NEXT: - Type: MEMORY | 71 | ; CHECK-NEXT: - Type: MEMORY |
| 61 | ; CHECK-NEXT: Memories: | 72 | ; CHECK-NEXT: Memories: |
| 62 | ; CHECK-NEXT: - Initial: 0x00000001 | 73 | ; CHECK-NEXT: - Initial: 0x00000001 |
| 63 | ; CHECK-NEXT: - Type: GLOBAL | ||
| 64 | ; CHECK-NEXT: Globals: | ||
| 65 | ; CHECK-NEXT: - Type: I32 | ||
| 66 | ; CHECK-NEXT: Mutable: false | ||
| 67 | ; CHECK-NEXT: InitExpr: | ||
| 68 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 69 | ; CHECK-NEXT: Value: 0 | ||
| 70 | ; CHECK-NEXT: - Type: I32 | ||
| 71 | ; CHECK-NEXT: Mutable: false | ||
| 72 | ; CHECK-NEXT: InitExpr: | ||
| 73 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 74 | ; CHECK-NEXT: Value: 8 | ||
| 75 | ; CHECK-NEXT: - Type: I32 | ||
| 76 | ; CHECK-NEXT: Mutable: false | ||
| 77 | ; CHECK-NEXT: InitExpr: | ||
| 78 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 79 | ; CHECK-NEXT: Value: 12 | ||
| 80 | ; CHECK-NEXT: - Type: I32 | ||
| 81 | ; CHECK-NEXT: Mutable: false | ||
| 82 | ; CHECK-NEXT: InitExpr: | ||
| 83 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 84 | ; CHECK-NEXT: Value: 16 | ||
| 85 | ; CHECK-NEXT: - Type: EXPORT | ||
| 86 | ; CHECK-NEXT: Exports: | ||
| 87 | ; CHECK-NEXT: - Name: hello | ||
| 88 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 89 | ; CHECK-NEXT: Index: 2 | ||
| 90 | ; CHECK-NEXT: - Name: my_func | ||
| 91 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 92 | ; CHECK-NEXT: Index: 3 | ||
| 93 | ; CHECK-NEXT: - Name: hello_str | ||
| 94 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 95 | ; CHECK-NEXT: Index: 1 | ||
| 96 | ; CHECK-NEXT: - Name: func_addr1 | ||
| 97 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 98 | ; CHECK-NEXT: Index: 2 | ||
| 99 | ; CHECK-NEXT: - Name: func_addr2 | ||
| 100 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 101 | ; CHECK-NEXT: Index: 3 | ||
| 102 | ; CHECK-NEXT: - Name: data_addr1 | ||
| 103 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 104 | ; CHECK-NEXT: Index: 4 | ||
| 105 | ; CHECK-NEXT: - Type: ELEM | 74 | ; CHECK-NEXT: - Type: ELEM |
| 106 | ; CHECK-NEXT: Segments: | 75 | ; CHECK-NEXT: Segments: |
| 107 | ; CHECK-NEXT: - Offset: | 76 | ; CHECK-NEXT: - Offset: |
| 108 | ; CHECK-NEXT: Opcode: I32_CONST | 77 | ; CHECK-NEXT: Opcode: I32_CONST |
| 109 | ; CHECK-NEXT: Value: 0 | 78 | ; CHECK-NEXT: Value: 1 |
| 110 | ; CHECK-NEXT: Functions: [ 3, 1 ] | 79 | ; CHECK-NEXT: Functions: [ 4, 1, 2 ] |
| 111 | ; CHECK-NEXT: - Type: CODE | 80 | ; CHECK-NEXT: - Type: CODE |
| 112 | ; CHECK-NEXT: Relocations: | 81 | ; CHECK-NEXT: Relocations: |
| 113 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | 82 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB |
| 114 | ; CHECK-NEXT: Index: 1 | 83 | ; CHECK-NEXT: Index: 1 |
| 115 | ; CHECK-NEXT: Offset: 0x00000004 | 84 | ; CHECK-NEXT: Offset: 0x00000004 |
| 116 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | 85 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB |
| 117 | ; CHECK-NEXT: Index: 0 | 86 | ; CHECK-NEXT: Index: 2 |
| 118 | ; CHECK-NEXT: Offset: 0x0000000A | 87 | ; CHECK-NEXT: Offset: 0x0000000A |
| 119 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | 88 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB |
| 120 | ; CHECK-NEXT: Index: 1 | 89 | ; CHECK-NEXT: Index: 4 |
| 121 | ; CHECK-NEXT: Offset: 0x00000013 | 90 | ; CHECK-NEXT: Offset: 0x00000013 |
| 91 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | ||
| 92 | ; CHECK-NEXT: Index: 5 | ||
| 93 | ; CHECK-NEXT: Offset: 0x0000001A | ||
| 94 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB | ||
| 95 | ; CHECK-NEXT: Index: 7 | ||
| 96 | ; CHECK-NEXT: Offset: 0x00000026 | ||
| 122 | ; CHECK-NEXT: Functions: | 97 | ; CHECK-NEXT: Functions: |
| 123 | ; CHECK-NEXT: - Locals: | 98 | ; CHECK-NEXT: - Index: 3 |
| 99 | ; CHECK-NEXT: Locals: | ||
| 124 | ; CHECK-NEXT: Body: 4180808080001080808080000B | 100 | ; CHECK-NEXT: Body: 4180808080001080808080000B |
| 125 | ; CHECK-NEXT: - Locals: | 101 | ; CHECK-NEXT: - Index: 4 |
| 126 | ; CHECK-NEXT: Body: 1081808080001A41010B | 102 | ; CHECK-NEXT: Locals: |
| 103 | ; CHECK-NEXT: Body: 1081808080001A1082808080001A41010B | ||
| 104 | ; CHECK-NEXT: - Index: 5 | ||
| 105 | ; CHECK-NEXT: Locals: | ||
| 106 | ; CHECK-NEXT: Body: 419C808080000B | ||
| 127 | ; CHECK-NEXT: - Type: DATA | 107 | ; CHECK-NEXT: - Type: DATA |
| 128 | ; CHECK-NEXT: Relocations: | 108 | ; CHECK-NEXT: Relocations: |
| 129 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 | 109 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 |
| 130 | ; CHECK-NEXT: Index: 0 | 110 | ; CHECK-NEXT: Index: 3 |
| 131 | ; CHECK-NEXT: Offset: 0x00000012 | 111 | ; CHECK-NEXT: Offset: 0x00000012 |
| 132 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 | 112 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 |
| 133 | ; CHECK-NEXT: Index: 1 | 113 | ; CHECK-NEXT: Index: 4 |
| 134 | ; CHECK-NEXT: Offset: 0x0000001B | 114 | ; CHECK-NEXT: Offset: 0x0000001B |
| 135 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 | 115 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 |
| 136 | ; CHECK-NEXT: Index: 0 | 116 | ; CHECK-NEXT: Index: 5 |
| 137 | ; CHECK-NEXT: Offset: 0x00000024 | 117 | ; CHECK-NEXT: Offset: 0x00000024 |
| 118 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 | ||
| 119 | ; CHECK-NEXT: Index: 12 | ||
| 120 | ; CHECK-NEXT: Offset: 0x0000002D | ||
| 138 | ; CHECK-NEXT: Segments: | 121 | ; CHECK-NEXT: Segments: |
| 139 | ; CHECK-NEXT: - SectionOffset: 6 | 122 | ; CHECK-NEXT: - SectionOffset: 6 |
| 140 | ; CHECK-NEXT: MemoryIndex: 0 | 123 | ; CHECK-NEXT: MemoryIndex: 0 |
| ... | @@ -147,39 +130,137 @@ declare i32 @foo_import() local_unnamed_addr | ... | @@ -147,39 +130,137 @@ declare i32 @foo_import() local_unnamed_addr |
| 147 | ; CHECK-NEXT: Offset: | 130 | ; CHECK-NEXT: Offset: |
| 148 | ; CHECK-NEXT: Opcode: I32_CONST | 131 | ; CHECK-NEXT: Opcode: I32_CONST |
| 149 | ; CHECK-NEXT: Value: 8 | 132 | ; CHECK-NEXT: Value: 8 |
| 150 | ; CHECK-NEXT: Content: '00000000' | 133 | ; CHECK-NEXT: Content: '01000000' |
| 151 | ; CHECK-NEXT: - SectionOffset: 27 | 134 | ; CHECK-NEXT: - SectionOffset: 27 |
| 152 | ; CHECK-NEXT: MemoryIndex: 0 | 135 | ; CHECK-NEXT: MemoryIndex: 0 |
| 153 | ; CHECK-NEXT: Offset: | 136 | ; CHECK-NEXT: Offset: |
| 154 | ; CHECK-NEXT: Opcode: I32_CONST | 137 | ; CHECK-NEXT: Opcode: I32_CONST |
| 155 | ; CHECK-NEXT: Value: 12 | 138 | ; CHECK-NEXT: Value: 12 |
| 156 | ; CHECK-NEXT: Content: '01000000' | 139 | ; CHECK-NEXT: Content: '02000000' |
| 157 | ; CHECK-NEXT: - SectionOffset: 36 | 140 | ; CHECK-NEXT: - SectionOffset: 36 |
| 158 | ; CHECK-NEXT: MemoryIndex: 0 | 141 | ; CHECK-NEXT: MemoryIndex: 0 |
| 159 | ; CHECK-NEXT: Offset: | 142 | ; CHECK-NEXT: Offset: |
| 160 | ; CHECK-NEXT: Opcode: I32_CONST | 143 | ; CHECK-NEXT: Opcode: I32_CONST |
| 161 | ; CHECK-NEXT: Value: 16 | 144 | ; CHECK-NEXT: Value: 16 |
| 162 | ; CHECK-NEXT: Content: FFFFFFFF | 145 | ; CHECK-NEXT: Content: '03000000' |
| 146 | ; CHECK-NEXT: - SectionOffset: 45 | ||
| 147 | ; CHECK-NEXT: MemoryIndex: 0 | ||
| 148 | ; CHECK-NEXT: Offset: | ||
| 149 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 150 | ; CHECK-NEXT: Value: 24 | ||
| 151 | ; CHECK-NEXT: Content: '00000000' | ||
| 152 | ; CHECK-NEXT: - SectionOffset: 54 | ||
| 153 | ; CHECK-NEXT: MemoryIndex: 0 | ||
| 154 | ; CHECK-NEXT: Offset: | ||
| 155 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 156 | ; CHECK-NEXT: Value: 28 | ||
| 157 | ; CHECK-NEXT: Content: '616263' | ||
| 163 | ; CHECK-NEXT: - Type: CUSTOM | 158 | ; CHECK-NEXT: - Type: CUSTOM |
| 164 | ; CHECK-NEXT: Name: linking | 159 | ; CHECK-NEXT: Name: linking |
| 165 | ; CHECK-NEXT: DataSize: 20 | 160 | ; CHECK-NEXT: Version: 1 |
| 161 | ; CHECK-NEXT: SymbolTable: | ||
| 162 | ; CHECK-NEXT: - Index: 0 | ||
| 163 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 164 | ; CHECK-NEXT: Name: hello | ||
| 165 | ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 166 | ; CHECK-NEXT: Function: 3 | ||
| 167 | ; CHECK-NEXT: - Index: 1 | ||
| 168 | ; CHECK-NEXT: Kind: DATA | ||
| 169 | ; CHECK-NEXT: Name: hello_str | ||
| 170 | ; CHECK-NEXT: Flags: [ ] | ||
| 171 | ; CHECK-NEXT: Segment: 0 | ||
| 172 | ; CHECK-NEXT: Size: 7 | ||
| 173 | ; CHECK-NEXT: - Index: 2 | ||
| 174 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 175 | ; CHECK-NEXT: Name: puts | ||
| 176 | ; CHECK-NEXT: Flags: [ UNDEFINED ] | ||
| 177 | ; CHECK-NEXT: Function: 0 | ||
| 178 | ; CHECK-NEXT: - Index: 3 | ||
| 179 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 180 | ; CHECK-NEXT: Name: my_func | ||
| 181 | ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 182 | ; CHECK-NEXT: Function: 4 | ||
| 183 | ; CHECK-NEXT: - Index: 4 | ||
| 184 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 185 | ; CHECK-NEXT: Name: foo_import | ||
| 186 | ; CHECK-NEXT: Flags: [ UNDEFINED ] | ||
| 187 | ; CHECK-NEXT: Function: 1 | ||
| 188 | ; CHECK-NEXT: - Index: 5 | ||
| 189 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 190 | ; CHECK-NEXT: Name: bar_import | ||
| 191 | ; CHECK-NEXT: Flags: [ BINDING_WEAK, UNDEFINED ] | ||
| 192 | ; CHECK-NEXT: Function: 2 | ||
| 193 | ; CHECK-NEXT: - Index: 6 | ||
| 194 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 195 | ; CHECK-NEXT: Name: func_comdat | ||
| 196 | ; CHECK-NEXT: Flags: [ BINDING_WEAK ] | ||
| 197 | ; CHECK-NEXT: Function: 5 | ||
| 198 | ; CHECK-NEXT: - Index: 7 | ||
| 199 | ; CHECK-NEXT: Kind: DATA | ||
| 200 | ; CHECK-NEXT: Name: data_comdat | ||
| 201 | ; CHECK-NEXT: Flags: [ BINDING_WEAK ] | ||
| 202 | ; CHECK-NEXT: Segment: 5 | ||
| 203 | ; CHECK-NEXT: Size: 3 | ||
| 204 | ; CHECK-NEXT: - Index: 8 | ||
| 205 | ; CHECK-NEXT: Kind: DATA | ||
| 206 | ; CHECK-NEXT: Name: func_addr1 | ||
| 207 | ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 208 | ; CHECK-NEXT: Segment: 1 | ||
| 209 | ; CHECK-NEXT: Size: 4 | ||
| 210 | ; CHECK-NEXT: - Index: 9 | ||
| 211 | ; CHECK-NEXT: Kind: DATA | ||
| 212 | ; CHECK-NEXT: Name: func_addr2 | ||
| 213 | ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 214 | ; CHECK-NEXT: Segment: 2 | ||
| 215 | ; CHECK-NEXT: Size: 4 | ||
| 216 | ; CHECK-NEXT: - Index: 10 | ||
| 217 | ; CHECK-NEXT: Kind: DATA | ||
| 218 | ; CHECK-NEXT: Name: func_addr3 | ||
| 219 | ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 220 | ; CHECK-NEXT: Segment: 3 | ||
| 221 | ; CHECK-NEXT: Size: 4 | ||
| 222 | ; CHECK-NEXT: - Index: 11 | ||
| 223 | ; CHECK-NEXT: Kind: DATA | ||
| 224 | ; CHECK-NEXT: Name: data_addr1 | ||
| 225 | ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] | ||
| 226 | ; CHECK-NEXT: Segment: 4 | ||
| 227 | ; CHECK-NEXT: Size: 4 | ||
| 228 | ; CHECK-NEXT: - Index: 12 | ||
| 229 | ; CHECK-NEXT: Kind: DATA | ||
| 230 | ; CHECK-NEXT: Name: data_import | ||
| 231 | ; CHECK-NEXT: Flags: [ UNDEFINED ] | ||
| 166 | ; CHECK-NEXT: SegmentInfo: | 232 | ; CHECK-NEXT: SegmentInfo: |
| 167 | ; CHECK-NEXT: - Index: 0 | 233 | ; CHECK-NEXT: - Index: 0 |
| 168 | ; CHECK-NEXT: Name: .rodata.hello_str | 234 | ; CHECK-NEXT: Name: .rodata.hello_str |
| 169 | ; CHECK-NEXT: Alignment: 1 | 235 | ; CHECK-NEXT: Alignment: 1 |
| 170 | ; CHECK-NEXT: Flags: [ ] | 236 | ; CHECK-NEXT: Flags: [ ] |
| 171 | ; CHECK-NEXT: - Index: 1 | 237 | ; CHECK-NEXT: - Index: 1 |
| 172 | ; CHECK-NEXT: Name: .data.func_addr1 | 238 | ; CHECK-NEXT: Name: .data.func_addr1 |
| 173 | ; CHECK-NEXT: Alignment: 4 | 239 | ; CHECK-NEXT: Alignment: 4 |
| 174 | ; CHECK-NEXT: Flags: [ ] | 240 | ; CHECK-NEXT: Flags: [ ] |
| 175 | ; CHECK-NEXT: - Index: 2 | 241 | ; CHECK-NEXT: - Index: 2 |
| 176 | ; CHECK-NEXT: Name: .data.func_addr2 | 242 | ; CHECK-NEXT: Name: .data.func_addr2 |
| 177 | ; CHECK-NEXT: Alignment: 4 | 243 | ; CHECK-NEXT: Alignment: 4 |
| 178 | ; CHECK-NEXT: Flags: [ ] | 244 | ; CHECK-NEXT: Flags: [ ] |
| 179 | ; CHECK-NEXT: - Index: 3 | 245 | ; CHECK-NEXT: - Index: 3 |
| 246 | ; CHECK-NEXT: Name: .data.func_addr3 | ||
| 247 | ; CHECK-NEXT: Alignment: 4 | ||
| 248 | ; CHECK-NEXT: Flags: [ ] | ||
| 249 | ; CHECK-NEXT: - Index: 4 | ||
| 180 | ; CHECK-NEXT: Name: .data.data_addr1 | 250 | ; CHECK-NEXT: Name: .data.data_addr1 |
| 181 | ; CHECK-NEXT: Alignment: 8 | 251 | ; CHECK-NEXT: Alignment: 8 |
| 182 | ; CHECK-NEXT: Flags: [ ] | 252 | ; CHECK-NEXT: Flags: [ ] |
| 253 | ; CHECK-NEXT: - Index: 5 | ||
| 254 | ; CHECK-NEXT: Name: .rodata.data_comdat | ||
| 255 | ; CHECK-NEXT: Alignment: 1 | ||
| 256 | ; CHECK-NEXT: Flags: [ ] | ||
| 257 | ; CHECK-NEXT: Comdats: | ||
| 258 | ; CHECK-NEXT: - Name: func_comdat | ||
| 259 | ; CHECK-NEXT: Entries: | ||
| 260 | ; CHECK-NEXT: - Kind: FUNCTION | ||
| 261 | ; CHECK-NEXT: Index: 5 | ||
| 262 | ; CHECK-NEXT: - Kind: DATA | ||
| 263 | ; CHECK-NEXT: Index: 5 | ||
| 183 | ; CHECK-NEXT: - Type: CUSTOM | 264 | ; CHECK-NEXT: - Type: CUSTOM |
| 184 | ; CHECK-NEXT: Name: name | 265 | ; CHECK-NEXT: Name: name |
| 185 | ; CHECK-NEXT: FunctionNames: | 266 | ; CHECK-NEXT: FunctionNames: |
| ... | @@ -188,7 +269,11 @@ declare i32 @foo_import() local_unnamed_addr | ... | @@ -188,7 +269,11 @@ declare i32 @foo_import() local_unnamed_addr |
| 188 | ; CHECK-NEXT: - Index: 1 | 269 | ; CHECK-NEXT: - Index: 1 |
| 189 | ; CHECK-NEXT: Name: foo_import | 270 | ; CHECK-NEXT: Name: foo_import |
| 190 | ; CHECK-NEXT: - Index: 2 | 271 | ; CHECK-NEXT: - Index: 2 |
| 191 | ; CHECK-NEXT: Name: hello | 272 | ; CHECK-NEXT: Name: bar_import |
| 192 | ; CHECK-NEXT: - Index: 3 | 273 | ; CHECK-NEXT: - Index: 3 |
| 274 | ; CHECK-NEXT: Name: hello | ||
| 275 | ; CHECK-NEXT: - Index: 4 | ||
| 193 | ; CHECK-NEXT: Name: my_func | 276 | ; CHECK-NEXT: Name: my_func |
| 277 | ; CHECK-NEXT: - Index: 5 | ||
| 278 | ; CHECK-NEXT: Name: func_comdat | ||
| 194 | ; CHECK-NEXT: ... | 279 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/responsefile.test created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | RUN: llc -filetype=obj -o %t.o %p/Inputs/ret32.ll | ||
| 2 | |||
| 3 | RUN: echo "%/t.o -o %/t.wasm -e ret32" > %t.rsp | ||
| 4 | RUN: wasm-ld @%t.rsp --initial-memory=655360 | ||
| 5 | RUN: llvm-readobj --sections %t.wasm | FileCheck %s | ||
| 6 | CHECK: InitialPages: 10 | ||
| 7 | |||
| 8 | RUN: echo "blah\foo" > %t.rsp | ||
| 9 | RUN: not wasm-ld @%t.rsp 2>&1 | FileCheck --check-prefix=ESCAPE %s | ||
| 10 | ESCAPE: error: cannot open blahfoo: {{[Nn]}}o such file or directory | ||
deps/lld/test/wasm/signature-mismatch-weak.ll created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | ; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t.weak.o | ||
| 2 | ; RUN: llc -filetype=obj %p/Inputs/strong-symbol.ll -o %t.strong.o | ||
| 3 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 4 | ; RUN: wasm-ld -o %t.wasm %t.o %t.strong.o %t.weak.o 2>&1 | FileCheck %s | ||
| 5 | |||
| 6 | target triple = "wasm32-unknown-unknown" | ||
| 7 | |||
| 8 | declare i32 @weakFn() local_unnamed_addr | ||
| 9 | |||
| 10 | define void @_start() local_unnamed_addr { | ||
| 11 | entry: | ||
| 12 | %call = call i32 @weakFn() | ||
| 13 | ret void | ||
| 14 | } | ||
| 15 | |||
| 16 | ; CHECK: warning: function signature mismatch: weakFn | ||
| 17 | ; CHECK-NEXT: >>> defined as () -> I32 in {{.*}}signature-mismatch-weak.ll.tmp.o | ||
| 18 | ; CHECK-NEXT: >>> defined as () -> I64 in {{.*}}signature-mismatch-weak.ll.tmp.strong.o | ||
deps/lld/test/wasm/signature-mismatch.ll+13-3| ... | @@ -1,6 +1,12 @@ | ... | @@ -1,6 +1,12 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.main.o | 2 | ; RUN: llc -filetype=obj %s -o %t.main.o |
| 3 | ; RUN: not lld -flavor wasm --check-signatures -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s | 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 | ||
| 8 | |||
| 9 | target triple = "wasm32-unknown-unknown" | ||
| 4 | 10 | ||
| 5 | ; Function Attrs: nounwind | 11 | ; Function Attrs: nounwind |
| 6 | define hidden void @_start() local_unnamed_addr #0 { | 12 | define hidden void @_start() local_unnamed_addr #0 { |
| ... | @@ -14,3 +20,7 @@ declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1 | ... | @@ -14,3 +20,7 @@ declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1 |
| 14 | ; CHECK: error: function signature mismatch: ret32 | 20 | ; CHECK: error: function signature mismatch: ret32 |
| 15 | ; CHECK-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o | 21 | ; CHECK-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o |
| 16 | ; CHECK-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o | 22 | ; CHECK-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o |
| 23 | |||
| 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 created+42| ... | @@ -0,0 +1,42 @@ | ||
| 1 | ; Test that the --stack-first option places the stack at the start of linear | ||
| 2 | ; memory. In this case the --stack-first option is being passed along with a | ||
| 3 | ; stack size of 512. This means (since the stack grows down) the stack pointer | ||
| 4 | ; global should be initialized to 512. | ||
| 5 | |||
| 6 | RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o | ||
| 7 | |||
| 8 | RUN: wasm-ld -z stack-size=512 --stack-first --allow-undefined -o %t.wasm %t.o | ||
| 9 | RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 10 | |||
| 11 | CHECK: - Type: GLOBAL | ||
| 12 | CHECK-NEXT: Globals: | ||
| 13 | CHECK-NEXT: - Index: 0 | ||
| 14 | CHECK-NEXT: Type: I32 | ||
| 15 | CHECK-NEXT: Mutable: true | ||
| 16 | CHECK-NEXT: InitExpr: | ||
| 17 | CHECK-NEXT: Opcode: I32_CONST | ||
| 18 | CHECK-NEXT: Value: 512 | ||
| 19 | CHECK-NEXT: - Index: 1 | ||
| 20 | CHECK-NEXT: Type: I32 | ||
| 21 | CHECK-NEXT: Mutable: false | ||
| 22 | CHECK-NEXT: InitExpr: | ||
| 23 | CHECK-NEXT: Opcode: I32_CONST | ||
| 24 | CHECK-NEXT: Value: 512 | ||
| 25 | CHECK-NEXT: - Index: 2 | ||
| 26 | CHECK-NEXT: Type: I32 | ||
| 27 | CHECK-NEXT: Mutable: false | ||
| 28 | CHECK-NEXT: InitExpr: | ||
| 29 | CHECK-NEXT: Opcode: I32_CONST | ||
| 30 | CHECK-NEXT: Value: 512 | ||
| 31 | CHECK-NEXT: - Type: EXPORT | ||
| 32 | CHECK-NEXT: Exports: | ||
| 33 | CHECK-NEXT: - Name: memory | ||
| 34 | CHECK-NEXT: Kind: MEMORY | ||
| 35 | CHECK-NEXT: Index: 0 | ||
| 36 | CHECK-NEXT: - Name: __heap_base | ||
| 37 | CHECK-NEXT: Kind: GLOBAL | ||
| 38 | CHECK-NEXT: Index: 1 | ||
| 39 | CHECK-NEXT: - Name: __data_end | ||
| 40 | CHECK-NEXT: Kind: GLOBAL | ||
| 41 | CHECK-NEXT: Index: 2 | ||
| 42 | |||
deps/lld/test/wasm/stack-pointer.ll+28-22| ... | @@ -1,9 +1,11 @@ | ... | @@ -1,9 +1,11 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 1 | ; RUN: llc -filetype=obj %s -o %t.o |
| 2 | ; RUN: lld -flavor wasm --emit-relocs -o %t.wasm %t.o | 2 | ; RUN: wasm-ld --relocatable -o %t.wasm %t.o |
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 4 | 4 | ||
| 5 | target triple = "wasm32-unknown-unknown" | ||
| 6 | |||
| 5 | ; Function Attrs: nounwind | 7 | ; Function Attrs: nounwind |
| 6 | define hidden i32 @_start() local_unnamed_addr { | 8 | define i32 @_start() local_unnamed_addr { |
| 7 | entry: | 9 | entry: |
| 8 | %retval = alloca i32, align 4 | 10 | %retval = alloca i32, align 4 |
| 9 | ret i32 0 | 11 | ret i32 0 |
| ... | @@ -18,6 +20,13 @@ entry: | ... | @@ -18,6 +20,13 @@ entry: |
| 18 | ; CHECK-NEXT: - Index: 0 | 20 | ; CHECK-NEXT: - Index: 0 |
| 19 | ; CHECK-NEXT: ReturnType: I32 | 21 | ; CHECK-NEXT: ReturnType: I32 |
| 20 | ; CHECK-NEXT: ParamTypes: | 22 | ; CHECK-NEXT: ParamTypes: |
| 23 | ; CHECK-NEXT: - Type: IMPORT | ||
| 24 | ; CHECK-NEXT: Imports: | ||
| 25 | ; CHECK-NEXT: - Module: env | ||
| 26 | ; CHECK-NEXT: Field: __stack_pointer | ||
| 27 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 28 | ; CHECK-NEXT: GlobalType: I32 | ||
| 29 | ; CHECK-NEXT: GlobalMutable: true | ||
| 21 | ; CHECK-NEXT: - Type: FUNCTION | 30 | ; CHECK-NEXT: - Type: FUNCTION |
| 22 | ; CHECK-NEXT: FunctionTypes: [ 0 ] | 31 | ; CHECK-NEXT: FunctionTypes: [ 0 ] |
| 23 | ; CHECK-NEXT: - Type: TABLE | 32 | ; CHECK-NEXT: - Type: TABLE |
| ... | @@ -29,33 +38,30 @@ entry: | ... | @@ -29,33 +38,30 @@ entry: |
| 29 | ; CHECK-NEXT: Maximum: 0x00000001 | 38 | ; CHECK-NEXT: Maximum: 0x00000001 |
| 30 | ; CHECK-NEXT: - Type: MEMORY | 39 | ; CHECK-NEXT: - Type: MEMORY |
| 31 | ; CHECK-NEXT: Memories: | 40 | ; CHECK-NEXT: Memories: |
| 32 | ; CHECK-NEXT: - Initial: 0x00000002 | 41 | ; CHECK-NEXT: - Initial: 0x00000000 |
| 33 | ; CHECK-NEXT: - Type: GLOBAL | ||
| 34 | ; CHECK-NEXT: Globals: | ||
| 35 | ; CHECK-NEXT: - Type: I32 | ||
| 36 | ; CHECK-NEXT: Mutable: true | ||
| 37 | ; CHECK-NEXT: InitExpr: | ||
| 38 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 39 | ; CHECK-NEXT: Value: 66560 | ||
| 40 | ; CHECK-NEXT: - Type: EXPORT | ||
| 41 | ; CHECK-NEXT: Exports: | ||
| 42 | ; CHECK-NEXT: - Name: memory | ||
| 43 | ; CHECK-NEXT: Kind: MEMORY | ||
| 44 | ; CHECK-NEXT: Index: 0 | ||
| 45 | ; CHECK-NEXT: - Name: _start | ||
| 46 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 47 | ; CHECK-NEXT: Index: 0 | ||
| 48 | ; CHECK-NEXT: - Type: CODE | 42 | ; CHECK-NEXT: - Type: CODE |
| 49 | ; CHECK-NEXT: Relocations: | 43 | ; CHECK-NEXT: Relocations: |
| 50 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | 44 | ; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB |
| 51 | ; CHECK-NEXT: Index: 0 | 45 | ; CHECK-NEXT: Index: 1 |
| 52 | ; CHECK-NEXT: Offset: 0x00000004 | 46 | ; CHECK-NEXT: Offset: 0x00000004 |
| 53 | ; CHECK-NEXT: Functions: | 47 | ; CHECK-NEXT: Functions: |
| 54 | ; CHECK-NEXT: - Locals: | 48 | ; CHECK-NEXT: - Index: 0 |
| 49 | ; CHECK-NEXT: Locals: | ||
| 55 | ; CHECK-NEXT: Body: 23808080800041106B1A41000B | 50 | ; CHECK-NEXT: Body: 23808080800041106B1A41000B |
| 56 | ; CHECK-NEXT: - Type: CUSTOM | 51 | ; CHECK-NEXT: - Type: CUSTOM |
| 57 | ; CHECK-NEXT: Name: linking | 52 | ; CHECK-NEXT: Name: linking |
| 58 | ; CHECK-NEXT: DataSize: 0 | 53 | ; CHECK-NEXT: Version: 1 |
| 54 | ; CHECK-NEXT: SymbolTable: | ||
| 55 | ; CHECK-NEXT: - Index: 0 | ||
| 56 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 57 | ; CHECK-NEXT: Name: _start | ||
| 58 | ; CHECK-NEXT: Flags: [ ] | ||
| 59 | ; CHECK-NEXT: Function: 0 | ||
| 60 | ; CHECK-NEXT: - Index: 1 | ||
| 61 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 62 | ; CHECK-NEXT: Name: __stack_pointer | ||
| 63 | ; CHECK-NEXT: Flags: [ UNDEFINED ] | ||
| 64 | ; CHECK-NEXT: Global: 0 | ||
| 59 | ; CHECK-NEXT: - Type: CUSTOM | 65 | ; CHECK-NEXT: - Type: CUSTOM |
| 60 | ; CHECK-NEXT: Name: name | 66 | ; CHECK-NEXT: Name: name |
| 61 | ; CHECK-NEXT: FunctionNames: | 67 | ; CHECK-NEXT: FunctionNames: |
deps/lld/test/wasm/strip-debug.test+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 1 | RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.start.o |
| 2 | RUN: lld -flavor wasm --strip-debug --entry=ret32 -o %t.wasm %t.ret32.o | 2 | RUN: wasm-ld --strip-debug -o %t.wasm %t.start.o |
| 3 | RUN: obj2yaml %t.wasm | FileCheck %s | 3 | RUN: obj2yaml %t.wasm | FileCheck %s |
| 4 | 4 | ||
| 5 | # Check that there is no name section | 5 | # Check that there is no name section |
deps/lld/test/wasm/symbol-type-mismatch.ll+7-5| ... | @@ -1,9 +1,11 @@ | ... | @@ -1,9 +1,11 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 1 | ; RUN: llc -filetype=obj %s -o %t.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 2 | ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o |
| 3 | ; RUN: not lld -flavor wasm -o %t.wasm %t.o %t.ret32.o 2>&1 | FileCheck %s | 3 | ; RUN: not wasm-ld -o %t.wasm %t.o %t.ret32.o 2>&1 | FileCheck %s |
| 4 | |||
| 5 | target triple = "wasm32-unknown-unknown" | ||
| 4 | 6 | ||
| 5 | @ret32 = extern_weak global i32, align 4 | 7 | @ret32 = extern_weak global i32, align 4 |
| 6 | 8 | ||
| 7 | ; CHECK: error: symbol type mismatch: ret32 | 9 | ; CHECK: error: symbol type mismatch: ret32 |
| 8 | ; CHECK: >>> defined as Global in {{.*}}symbol-type-mismatch.ll.tmp.o | 10 | ; CHECK: >>> defined as WASM_SYMBOL_TYPE_DATA in {{.*}}symbol-type-mismatch.ll.tmp.o |
| 9 | ; CHECK: >>> defined as Function in {{.*}}.ret32.o | 11 | ; CHECK: >>> defined as WASM_SYMBOL_TYPE_FUNCTION in {{.*}}.ret32.o |
deps/lld/test/wasm/undefined-entry.test+9-2| ... | @@ -1,4 +1,11 @@ | ... | @@ -1,4 +1,11 @@ |
| 1 | RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/ret32.ll -o %t.ret32.o | 1 | RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o |
| 2 | RUN: not lld -flavor wasm -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s | 2 | RUN: not wasm-ld -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s |
| 3 | RUN: not wasm-ld -entry=foo -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-CUSTOM | ||
| 4 | RUN: not wasm-ld --allow-undefined -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-ALLOW | ||
| 3 | 5 | ||
| 4 | CHECK: error: undefined symbol: _start | 6 | CHECK: error: undefined symbol: _start |
| 7 | CHECK-CUSTOM: error: undefined symbol: foo | ||
| 8 | CHECK-ALLOW: error: entry symbol not defined (pass --no-entry to supress): | ||
| 9 | _start | ||
| 10 | |||
| 11 | RUN: wasm-ld --no-entry -o %t.wasm %t.ret32.o |
deps/lld/test/wasm/undefined-weak-call.ll created+120| ... | @@ -0,0 +1,120 @@ | ||
| 1 | ; RUN: llc -filetype=obj %s -o %t.o | ||
| 2 | ; RUN: wasm-ld --no-entry --print-gc-sections %t.o \ | ||
| 3 | ; RUN: -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-GC %s | ||
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 5 | |||
| 6 | ; Check that calling an undefined weak function generates an appropriate stub | ||
| 7 | ; that will fail at runtime with "unreachable". | ||
| 8 | |||
| 9 | target triple = "wasm32-unknown-unknown" | ||
| 10 | |||
| 11 | declare extern_weak void @weakFunc1() | ||
| 12 | declare extern_weak void @weakFunc2() ; same signature | ||
| 13 | declare extern_weak void @weakFunc3(i32 %arg) ; different | ||
| 14 | declare extern_weak void @weakFunc4() ; should be GC'd as not called | ||
| 15 | |||
| 16 | ; CHECK-GC: removing unused section {{.*}}:(weakFunc4) | ||
| 17 | |||
| 18 | define i32 @callWeakFuncs() { | ||
| 19 | call void @weakFunc1() | ||
| 20 | call void @weakFunc2() | ||
| 21 | call void @weakFunc3(i32 2) | ||
| 22 | %addr1 = ptrtoint void ()* @weakFunc1 to i32 | ||
| 23 | %addr4 = ptrtoint void ()* @weakFunc4 to i32 | ||
| 24 | %sum = add i32 %addr1, %addr4 | ||
| 25 | ret i32 %sum | ||
| 26 | } | ||
| 27 | |||
| 28 | ; CHECK: --- !WASM | ||
| 29 | ; CHECK-NEXT: FileHeader: | ||
| 30 | ; CHECK-NEXT: Version: 0x00000001 | ||
| 31 | ; CHECK-NEXT: Sections: | ||
| 32 | ; CHECK-NEXT: - Type: TYPE | ||
| 33 | ; CHECK-NEXT: Signatures: | ||
| 34 | ; CHECK-NEXT: - Index: 0 | ||
| 35 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 36 | ; CHECK-NEXT: ParamTypes: | ||
| 37 | ; CHECK-NEXT: - Index: 1 | ||
| 38 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 39 | ; CHECK-NEXT: ParamTypes: | ||
| 40 | ; CHECK-NEXT: - I32 | ||
| 41 | ; CHECK-NEXT: - Index: 2 | ||
| 42 | ; CHECK-NEXT: ReturnType: I32 | ||
| 43 | ; CHECK-NEXT: ParamTypes: | ||
| 44 | ; CHECK-NEXT: - Type: FUNCTION | ||
| 45 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 1, 2 ] | ||
| 46 | ; CHECK-NEXT: - Type: TABLE | ||
| 47 | ; CHECK-NEXT: Tables: | ||
| 48 | ; CHECK-NEXT: - ElemType: ANYFUNC | ||
| 49 | ; CHECK-NEXT: Limits: | ||
| 50 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | ||
| 51 | ; CHECK-NEXT: Initial: 0x00000001 | ||
| 52 | ; CHECK-NEXT: Maximum: 0x00000001 | ||
| 53 | ; CHECK-NEXT: - Type: MEMORY | ||
| 54 | ; CHECK-NEXT: Memories: | ||
| 55 | ; CHECK-NEXT: - Initial: 0x00000002 | ||
| 56 | ; CHECK-NEXT: - Type: GLOBAL | ||
| 57 | ; CHECK-NEXT: Globals: | ||
| 58 | ; CHECK-NEXT: - Index: 0 | ||
| 59 | ; CHECK-NEXT: Type: I32 | ||
| 60 | ; CHECK-NEXT: Mutable: true | ||
| 61 | ; CHECK-NEXT: InitExpr: | ||
| 62 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 63 | ; 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 | ||
| 76 | ; CHECK-NEXT: - Type: EXPORT | ||
| 77 | ; CHECK-NEXT: Exports: | ||
| 78 | ; CHECK-NEXT: - Name: memory | ||
| 79 | ; CHECK-NEXT: Kind: MEMORY | ||
| 80 | ; 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 | ||
| 87 | ; CHECK-NEXT: - Name: callWeakFuncs | ||
| 88 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 89 | ; CHECK-NEXT: Index: 4 | ||
| 90 | ; CHECK-NEXT: - Type: CODE | ||
| 91 | ; CHECK-NEXT: Functions: | ||
| 92 | ; CHECK-NEXT: - Index: 0 | ||
| 93 | ; CHECK-NEXT: Locals: | ||
| 94 | ; CHECK-NEXT: Body: 0B | ||
| 95 | ; CHECK-NEXT: - Index: 1 | ||
| 96 | ; CHECK-NEXT: Locals: | ||
| 97 | ; CHECK-NEXT: Body: 000B | ||
| 98 | ; CHECK-NEXT: - Index: 2 | ||
| 99 | ; CHECK-NEXT: Locals: | ||
| 100 | ; CHECK-NEXT: Body: 000B | ||
| 101 | ; CHECK-NEXT: - Index: 3 | ||
| 102 | ; CHECK-NEXT: Locals: | ||
| 103 | ; CHECK-NEXT: Body: 000B | ||
| 104 | ; CHECK-NEXT: - Index: 4 | ||
| 105 | ; CHECK-NEXT: Locals: | ||
| 106 | ; CHECK-NEXT: Body: 10818080800010828080800041021083808080004180808080004180808080006A0B | ||
| 107 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 108 | ; CHECK-NEXT: Name: name | ||
| 109 | ; CHECK-NEXT: FunctionNames: | ||
| 110 | ; CHECK-NEXT: - Index: 0 | ||
| 111 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 112 | ; CHECK-NEXT: - Index: 1 | ||
| 113 | ; CHECK-NEXT: Name: undefined function weakFunc1 | ||
| 114 | ; CHECK-NEXT: - Index: 2 | ||
| 115 | ; CHECK-NEXT: Name: undefined function weakFunc2 | ||
| 116 | ; CHECK-NEXT: - Index: 3 | ||
| 117 | ; CHECK-NEXT: Name: undefined function weakFunc3 | ||
| 118 | ; CHECK-NEXT: - Index: 4 | ||
| 119 | ; CHECK-NEXT: Name: callWeakFuncs | ||
| 120 | ; CHECK-NEXT: ... | ||
deps/lld/test/wasm/undefined.ll+12-6| ... | @@ -1,13 +1,19 @@ | ... | @@ -1,13 +1,19 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 1 | ; RUN: llc -filetype=obj %s -o %t.o |
| 2 | ; RUN: lld -flavor wasm --allow-undefined -o %t.wasm %t.o | 2 | ; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o |
| 3 | 3 | ||
| 4 | ; Fails due to undefined 'foo' | 4 | ; Fails due to undefined 'foo' and also 'baz' |
| 5 | ; RUN: not lld -flavor wasm -o %t.wasm %t.o 2>&1 | FileCheck %s | 5 | ; RUN: not wasm-ld --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s |
| 6 | ; CHECK: error: {{.*}}.o: undefined symbol: foo | 6 | ; CHECK: error: {{.*}}.o: undefined symbol: foo |
| 7 | ; CHECK: error: undefined symbol: baz | ||
| 7 | 8 | ||
| 8 | ; But succeeds if we pass a file containing 'foo' as --allow-undefined-file. | 9 | ; Succeeds if we pass a file containing 'foo' as --allow-undefined-file. |
| 9 | ; RUN: echo 'foo' > %t.txt | 10 | ; RUN: echo 'foo' > %t.txt |
| 10 | ; RUN: lld -flavor wasm --allow-undefined-file=%t.txt -o %t.wasm %t.o | 11 | ; RUN: wasm-ld --allow-undefined-file=%t.txt -o %t.wasm %t.o |
| 12 | |||
| 13 | ; Succeeds even if a missing symbol is added via --export | ||
| 14 | ; RUN: wasm-ld --allow-undefined --export=xxx -o %t.wasm %t.o | ||
| 15 | |||
| 16 | target triple = "wasm32-unknown-unknown" | ||
| 11 | 17 | ||
| 12 | ; Takes the address of the external foo() resulting in undefined external | 18 | ; Takes the address of the external foo() resulting in undefined external |
| 13 | @bar = hidden local_unnamed_addr global i8* bitcast (i32 ()* @foo to i8*), align 4 | 19 | @bar = hidden local_unnamed_addr global i8* bitcast (i32 ()* @foo to i8*), align 4 |
deps/lld/test/wasm/version.ll+4-2| ... | @@ -1,7 +1,9 @@ | ... | @@ -1,7 +1,9 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 1 | ; RUN: llc -filetype=obj %s -o %t.o |
| 2 | ; RUN: lld -flavor wasm -o %t.wasm %t.o | 2 | ; 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 |
| 4 | 4 | ||
| 5 | target triple = "wasm32-unknown-unknown" | ||
| 6 | |||
| 5 | define hidden void @_start() local_unnamed_addr #0 { | 7 | define hidden void @_start() local_unnamed_addr #0 { |
| 6 | entry: | 8 | entry: |
| 7 | ret void | 9 | ret void |
deps/lld/test/wasm/visibility-hidden.ll+17-9| ... | @@ -1,12 +1,14 @@ | ... | @@ -1,12 +1,14 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s | 1 | ; RUN: llc -filetype=obj -o %t.o %s |
| 2 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/hidden.ll -o %t2.o | 2 | ; RUN: llc -filetype=obj %S/Inputs/hidden.ll -o %t2.o |
| 3 | ; RUN: llvm-ar rcs %t2.a %t2.o | 3 | ; RUN: llvm-ar rcs %t2.a %t2.o |
| 4 | ; RUN: lld -flavor wasm %t.o %t2.a -o %t.wasm | 4 | ; RUN: wasm-ld %t.o %t2.a -o %t.wasm |
| 5 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 5 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 6 | 6 | ||
| 7 | ; Test that hidden symbols are not exported, whether pulled in from an archive | 7 | ; Test that hidden symbols are not exported, whether pulled in from an archive |
| 8 | ; or directly. | 8 | ; or directly. |
| 9 | 9 | ||
| 10 | target triple = "wasm32-unknown-unknown" | ||
| 11 | |||
| 10 | define hidden i32 @objectHidden() { | 12 | define hidden i32 @objectHidden() { |
| 11 | entry: | 13 | entry: |
| 12 | ret i32 0 | 14 | ret i32 0 |
| ... | @@ -20,13 +22,13 @@ entry: | ... | @@ -20,13 +22,13 @@ entry: |
| 20 | declare i32 @archiveHidden() | 22 | declare i32 @archiveHidden() |
| 21 | declare i32 @archiveDefault() | 23 | declare i32 @archiveDefault() |
| 22 | 24 | ||
| 23 | define i32 @_start() { | 25 | define void @_start() { |
| 24 | entry: | 26 | entry: |
| 25 | %call1 = call i32 @objectHidden() | 27 | %call1 = call i32 @objectHidden() |
| 26 | %call2 = call i32 @objectDefault() | 28 | %call2 = call i32 @objectDefault() |
| 27 | %call3 = call i32 @archiveHidden() | 29 | %call3 = call i32 @archiveHidden() |
| 28 | %call4 = call i32 @archiveDefault() | 30 | %call4 = call i32 @archiveDefault() |
| 29 | ret i32 0 | 31 | ret void |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | ; CHECK: - Type: EXPORT | 34 | ; CHECK: - Type: EXPORT |
| ... | @@ -34,13 +36,19 @@ entry: | ... | @@ -34,13 +36,19 @@ entry: |
| 34 | ; CHECK-NEXT: - Name: memory | 36 | ; CHECK-NEXT: - Name: memory |
| 35 | ; CHECK-NEXT: Kind: MEMORY | 37 | ; CHECK-NEXT: Kind: MEMORY |
| 36 | ; CHECK-NEXT: Index: 0 | 38 | ; CHECK-NEXT: Index: 0 |
| 39 | ; CHECK-NEXT: - Name: __heap_base | ||
| 40 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 41 | ; CHECK-NEXT: Index: 1 | ||
| 42 | ; CHECK-NEXT: - Name: __data_end | ||
| 43 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 44 | ; CHECK-NEXT: Index: 2 | ||
| 37 | ; CHECK-NEXT: - Name: _start | 45 | ; CHECK-NEXT: - Name: _start |
| 38 | ; CHECK-NEXT: Kind: FUNCTION | 46 | ; CHECK-NEXT: Kind: FUNCTION |
| 47 | ; CHECK-NEXT: Index: 3 | ||
| 48 | ; CHECK-NEXT: - Name: objectDefault | ||
| 49 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 39 | ; CHECK-NEXT: Index: 2 | 50 | ; CHECK-NEXT: Index: 2 |
| 40 | ; CHECK-NEXT: - Name: archiveDefault | 51 | ; CHECK-NEXT: - Name: archiveDefault |
| 41 | ; CHECK-NEXT: Kind: FUNCTION | 52 | ; CHECK-NEXT: Kind: FUNCTION |
| 42 | ; CHECK-NEXT: Index: 4 | 53 | ; CHECK-NEXT: Index: 5 |
| 43 | ; CHECK-NEXT: - Name: objectDefault | ||
| 44 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 45 | ; CHECK-NEXT: Index: 1 | ||
| 46 | ; CHECK-NEXT: - Type: | 54 | ; CHECK-NEXT: - Type: |
deps/lld/test/wasm/weak-alias-overide.ll+68-38| ... | @@ -1,11 +1,13 @@ | ... | @@ -1,11 +1,13 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s | 1 | ; RUN: llc -filetype=obj -o %t.o %s |
| 2 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o | 2 | ; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o |
| 3 | ; RUN: lld -flavor wasm %t.o %t2.o -o %t.wasm | 3 | ; RUN: wasm-ld %t.o %t2.o -o %t.wasm |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 5 | 5 | ||
| 6 | ; Test that the strongly defined alias_fn from this file is used both here | 6 | ; Test that the strongly defined alias_fn from this file is used both here |
| 7 | ; and in call_alias. | 7 | ; and in call_alias. |
| 8 | 8 | ||
| 9 | target triple = "wasm32-unknown-unknown" | ||
| 10 | |||
| 9 | define i32 @alias_fn() local_unnamed_addr #1 { | 11 | define i32 @alias_fn() local_unnamed_addr #1 { |
| 10 | ret i32 1 | 12 | ret i32 1 |
| 11 | } | 13 | } |
| ... | @@ -24,13 +26,13 @@ entry: | ... | @@ -24,13 +26,13 @@ entry: |
| 24 | ; CHECK-NEXT: - Type: TYPE | 26 | ; CHECK-NEXT: - Type: TYPE |
| 25 | ; CHECK-NEXT: Signatures: | 27 | ; CHECK-NEXT: Signatures: |
| 26 | ; CHECK-NEXT: - Index: 0 | 28 | ; CHECK-NEXT: - Index: 0 |
| 27 | ; CHECK-NEXT: ReturnType: I32 | 29 | ; CHECK-NEXT: ReturnType: NORESULT |
| 28 | ; CHECK-NEXT: ParamTypes: | 30 | ; CHECK-NEXT: ParamTypes: |
| 29 | ; CHECK-NEXT: - Index: 1 | 31 | ; CHECK-NEXT: - Index: 1 |
| 30 | ; CHECK-NEXT: ReturnType: NORESULT | 32 | ; CHECK-NEXT: ReturnType: I32 |
| 31 | ; CHECK-NEXT: ParamTypes: | 33 | ; CHECK-NEXT: ParamTypes: |
| 32 | ; CHECK-NEXT: - Type: FUNCTION | 34 | ; CHECK-NEXT: - Type: FUNCTION |
| 33 | ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0, 0, 0, 0 ] | 35 | ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1, 1, 1, 1, 1 ] |
| 34 | ; CHECK-NEXT: - Type: TABLE | 36 | ; CHECK-NEXT: - Type: TABLE |
| 35 | ; CHECK-NEXT: Tables: | 37 | ; CHECK-NEXT: Tables: |
| 36 | ; CHECK-NEXT: - ElemType: ANYFUNC | 38 | ; CHECK-NEXT: - ElemType: ANYFUNC |
| ... | @@ -43,81 +45,109 @@ entry: | ... | @@ -43,81 +45,109 @@ entry: |
| 43 | ; CHECK-NEXT: - Initial: 0x00000002 | 45 | ; CHECK-NEXT: - Initial: 0x00000002 |
| 44 | ; CHECK-NEXT: - Type: GLOBAL | 46 | ; CHECK-NEXT: - Type: GLOBAL |
| 45 | ; CHECK-NEXT: Globals: | 47 | ; CHECK-NEXT: Globals: |
| 46 | ; CHECK-NEXT: - Type: I32 | 48 | ; CHECK-NEXT: - Index: 0 |
| 49 | ; CHECK-NEXT: Type: I32 | ||
| 47 | ; CHECK-NEXT: Mutable: true | 50 | ; CHECK-NEXT: Mutable: true |
| 48 | ; CHECK-NEXT: InitExpr: | 51 | ; CHECK-NEXT: InitExpr: |
| 49 | ; CHECK-NEXT: Opcode: I32_CONST | 52 | ; CHECK-NEXT: Opcode: I32_CONST |
| 50 | ; CHECK-NEXT: Value: 66560 | 53 | ; 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 | ||
| 51 | ; CHECK-NEXT: - Type: EXPORT | 66 | ; CHECK-NEXT: - Type: EXPORT |
| 52 | ; CHECK-NEXT: Exports: | 67 | ; CHECK-NEXT: Exports: |
| 53 | ; CHECK-NEXT: - Name: memory | 68 | ; CHECK-NEXT: - Name: memory |
| 54 | ; CHECK-NEXT: Kind: MEMORY | 69 | ; CHECK-NEXT: Kind: MEMORY |
| 55 | ; CHECK-NEXT: Index: 0 | 70 | ; 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 | ||
| 56 | ; CHECK-NEXT: - Name: _start | 77 | ; CHECK-NEXT: - Name: _start |
| 57 | ; CHECK-NEXT: Kind: FUNCTION | 78 | ; CHECK-NEXT: Kind: FUNCTION |
| 58 | ; CHECK-NEXT: Index: 1 | 79 | ; CHECK-NEXT: Index: 2 |
| 59 | ; CHECK-NEXT: - Name: alias_fn | 80 | ; CHECK-NEXT: - Name: alias_fn |
| 60 | ; CHECK-NEXT: Kind: FUNCTION | 81 | ; CHECK-NEXT: Kind: FUNCTION |
| 61 | ; CHECK-NEXT: Index: 0 | 82 | ; CHECK-NEXT: Index: 1 |
| 62 | ; CHECK-NEXT: - Name: direct_fn | 83 | ; CHECK-NEXT: - Name: direct_fn |
| 63 | ; CHECK-NEXT: Kind: FUNCTION | 84 | ; CHECK-NEXT: Kind: FUNCTION |
| 64 | ; CHECK-NEXT: Index: 2 | 85 | ; CHECK-NEXT: Index: 3 |
| 65 | ; CHECK-NEXT: - Name: call_direct | 86 | ; CHECK-NEXT: - Name: call_direct |
| 66 | ; CHECK-NEXT: Kind: FUNCTION | 87 | ; CHECK-NEXT: Kind: FUNCTION |
| 67 | ; CHECK-NEXT: Index: 3 | 88 | ; CHECK-NEXT: Index: 4 |
| 68 | ; CHECK-NEXT: - Name: call_alias | 89 | ; CHECK-NEXT: - Name: call_alias |
| 69 | ; CHECK-NEXT: Kind: FUNCTION | 90 | ; CHECK-NEXT: Kind: FUNCTION |
| 70 | ; CHECK-NEXT: Index: 4 | 91 | ; CHECK-NEXT: Index: 5 |
| 71 | ; CHECK-NEXT: - Name: call_alias_ptr | 92 | ; CHECK-NEXT: - Name: call_alias_ptr |
| 72 | ; CHECK-NEXT: Kind: FUNCTION | 93 | ; CHECK-NEXT: Kind: FUNCTION |
| 73 | ; CHECK-NEXT: Index: 5 | 94 | ; CHECK-NEXT: Index: 6 |
| 74 | ; CHECK-NEXT: - Name: call_direct_ptr | 95 | ; CHECK-NEXT: - Name: call_direct_ptr |
| 75 | ; CHECK-NEXT: Kind: FUNCTION | 96 | ; CHECK-NEXT: Kind: FUNCTION |
| 76 | ; CHECK-NEXT: Index: 6 | 97 | ; CHECK-NEXT: Index: 7 |
| 77 | ; CHECK-NEXT: - Type: ELEM | 98 | ; CHECK-NEXT: - Type: ELEM |
| 78 | ; CHECK-NEXT: Segments: | 99 | ; CHECK-NEXT: Segments: |
| 79 | ; CHECK-NEXT: - Offset: | 100 | ; CHECK-NEXT: - Offset: |
| 80 | ; CHECK-NEXT: Opcode: I32_CONST | 101 | ; CHECK-NEXT: Opcode: I32_CONST |
| 81 | ; CHECK-NEXT: Value: 1 | 102 | ; CHECK-NEXT: Value: 1 |
| 82 | ; CHECK-NEXT: Functions: [ 0, 2 ] | 103 | ; CHECK-NEXT: Functions: [ 1, 3 ] |
| 83 | ; CHECK-NEXT: - Type: CODE | 104 | ; CHECK-NEXT: - Type: CODE |
| 84 | ; CHECK-NEXT: Functions: | 105 | ; CHECK-NEXT: Functions: |
| 85 | ; CHECK-NEXT: - Locals: | 106 | ; CHECK-NEXT: - Index: 0 |
| 107 | ; CHECK-NEXT: Locals: | ||
| 108 | ; CHECK-NEXT: Body: 0B | ||
| 109 | ; CHECK-NEXT: - Index: 1 | ||
| 110 | ; CHECK-NEXT: Locals: | ||
| 86 | ; CHECK-NEXT: Body: 41010B | 111 | ; CHECK-NEXT: Body: 41010B |
| 87 | ; CHECK-NEXT: - Locals: | 112 | ; CHECK-NEXT: - Index: 2 |
| 88 | ; CHECK-NEXT: Body: 1080808080001A0B | 113 | ; CHECK-NEXT: Locals: |
| 89 | ; CHECK-NEXT: - Locals: | 114 | ; CHECK-NEXT: Body: 1081808080001A0B |
| 115 | ; CHECK-NEXT: - Index: 3 | ||
| 116 | ; CHECK-NEXT: Locals: | ||
| 90 | ; CHECK-NEXT: Body: 41000B | 117 | ; CHECK-NEXT: Body: 41000B |
| 91 | ; CHECK-NEXT: - Locals: | 118 | ; CHECK-NEXT: - Index: 4 |
| 92 | ; CHECK-NEXT: Body: 1082808080000B | 119 | ; CHECK-NEXT: Locals: |
| 93 | ; CHECK-NEXT: - Locals: | 120 | ; CHECK-NEXT: Body: 1083808080000B |
| 94 | ; CHECK-NEXT: Body: 1080808080000B | 121 | ; CHECK-NEXT: - Index: 5 |
| 95 | ; CHECK-NEXT: - Locals: | 122 | ; CHECK-NEXT: Locals: |
| 123 | ; CHECK-NEXT: Body: 1081808080000B | ||
| 124 | ; CHECK-NEXT: - Index: 6 | ||
| 125 | ; CHECK-NEXT: Locals: | ||
| 96 | ; CHECK-NEXT: - Type: I32 | 126 | ; CHECK-NEXT: - Type: I32 |
| 97 | ; CHECK-NEXT: Count: 2 | 127 | ; CHECK-NEXT: Count: 2 |
| 98 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081080808080002101200041106A24808080800020010B | 128 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B |
| 99 | ; CHECK-NEXT: - Locals: | 129 | ; CHECK-NEXT: - Index: 7 |
| 130 | ; CHECK-NEXT: Locals: | ||
| 100 | ; CHECK-NEXT: - Type: I32 | 131 | ; CHECK-NEXT: - Type: I32 |
| 101 | ; CHECK-NEXT: Count: 2 | 132 | ; CHECK-NEXT: Count: 2 |
| 102 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081082808080002101200041106A24808080800020010B | 133 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081083808080002101200041106A24808080800020010B |
| 103 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 104 | ; CHECK-NEXT: Name: linking | ||
| 105 | ; CHECK-NEXT: DataSize: 0 | ||
| 106 | ; CHECK-NEXT: - Type: CUSTOM | 134 | ; CHECK-NEXT: - Type: CUSTOM |
| 107 | ; CHECK-NEXT: Name: name | 135 | ; CHECK-NEXT: Name: name |
| 108 | ; CHECK-NEXT: FunctionNames: | 136 | ; CHECK-NEXT: FunctionNames: |
| 109 | ; CHECK-NEXT: - Index: 0 | 137 | ; CHECK-NEXT: - Index: 0 |
| 110 | ; CHECK-NEXT: Name: alias_fn | 138 | ; CHECK-NEXT: Name: __wasm_call_ctors |
| 111 | ; CHECK-NEXT: - Index: 1 | 139 | ; CHECK-NEXT: - Index: 1 |
| 112 | ; CHECK-NEXT: Name: _start | 140 | ; CHECK-NEXT: Name: alias_fn |
| 113 | ; CHECK-NEXT: - Index: 2 | 141 | ; CHECK-NEXT: - Index: 2 |
| 114 | ; CHECK-NEXT: Name: direct_fn | 142 | ; CHECK-NEXT: Name: _start |
| 115 | ; CHECK-NEXT: - Index: 3 | 143 | ; CHECK-NEXT: - Index: 3 |
| 116 | ; CHECK-NEXT: Name: call_direct | 144 | ; CHECK-NEXT: Name: direct_fn |
| 117 | ; CHECK-NEXT: - Index: 4 | 145 | ; CHECK-NEXT: - Index: 4 |
| 118 | ; CHECK-NEXT: Name: call_alias | 146 | ; CHECK-NEXT: Name: call_direct |
| 119 | ; CHECK-NEXT: - Index: 5 | 147 | ; CHECK-NEXT: - Index: 5 |
| 120 | ; CHECK-NEXT: Name: call_alias_ptr | 148 | ; CHECK-NEXT: Name: call_alias |
| 121 | ; CHECK-NEXT: - Index: 6 | 149 | ; CHECK-NEXT: - Index: 6 |
| 150 | ; CHECK-NEXT: Name: call_alias_ptr | ||
| 151 | ; CHECK-NEXT: - Index: 7 | ||
| 122 | ; CHECK-NEXT: Name: call_direct_ptr | 152 | ; CHECK-NEXT: Name: call_direct_ptr |
| 123 | ; CHECK-NEXT: ... | 153 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/weak-alias.ll+235-38| ... | @@ -1,17 +1,19 @@ | ... | @@ -1,17 +1,19 @@ |
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s | 1 | ; RUN: llc -filetype=obj -o %t.o %s |
| 2 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o | 2 | ; RUN: llc -filetype=obj %S/Inputs/weak-alias.ll -o %t2.o |
| 3 | ; RUN: lld -flavor wasm %t.o %t2.o -o %t.wasm | 3 | ; RUN: wasm-ld %t.o %t2.o -o %t.wasm |
| 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 4 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 5 | 5 | ||
| 6 | ; Test that weak aliases (alias_fn is a weak alias of direct_fn) are linked correctly | 6 | ; Test that weak aliases (alias_fn is a weak alias of direct_fn) are linked correctly |
| 7 | 7 | ||
| 8 | target triple = "wasm32-unknown-unknown" | ||
| 9 | |||
| 8 | declare i32 @alias_fn() local_unnamed_addr #1 | 10 | declare i32 @alias_fn() local_unnamed_addr #1 |
| 9 | 11 | ||
| 10 | ; Function Attrs: nounwind uwtable | 12 | ; Function Attrs: nounwind uwtable |
| 11 | define i32 @_start() local_unnamed_addr #1 { | 13 | define void @_start() local_unnamed_addr #1 { |
| 12 | entry: | 14 | entry: |
| 13 | %call = tail call i32 @alias_fn() #2 | 15 | %call = tail call i32 @alias_fn() #2 |
| 14 | ret i32 %call | 16 | ret void |
| 15 | } | 17 | } |
| 16 | 18 | ||
| 17 | ; CHECK: --- !WASM | 19 | ; CHECK: --- !WASM |
| ... | @@ -21,93 +23,288 @@ entry: | ... | @@ -21,93 +23,288 @@ entry: |
| 21 | ; CHECK-NEXT: - Type: TYPE | 23 | ; CHECK-NEXT: - Type: TYPE |
| 22 | ; CHECK-NEXT: Signatures: | 24 | ; CHECK-NEXT: Signatures: |
| 23 | ; CHECK-NEXT: - Index: 0 | 25 | ; CHECK-NEXT: - Index: 0 |
| 26 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 27 | ; CHECK-NEXT: ParamTypes: | ||
| 28 | ; CHECK-NEXT: - Index: 1 | ||
| 24 | ; CHECK-NEXT: ReturnType: I32 | 29 | ; CHECK-NEXT: ReturnType: I32 |
| 25 | ; CHECK-NEXT: ParamTypes: | 30 | ; CHECK-NEXT: ParamTypes: |
| 26 | ; CHECK-NEXT: - Type: FUNCTION | 31 | ; CHECK-NEXT: - Type: FUNCTION |
| 27 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0 ] | 32 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1, 1, 1 ] |
| 28 | ; CHECK-NEXT: - Type: TABLE | 33 | ; CHECK-NEXT: - Type: TABLE |
| 29 | ; CHECK-NEXT: Tables: | 34 | ; CHECK-NEXT: Tables: |
| 30 | ; CHECK-NEXT: - ElemType: ANYFUNC | 35 | ; CHECK-NEXT: - ElemType: ANYFUNC |
| 31 | ; CHECK-NEXT: Limits: | 36 | ; CHECK-NEXT: Limits: |
| 32 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | 37 | ; CHECK-NEXT: Flags: [ HAS_MAX ] |
| 33 | ; CHECK-NEXT: Initial: 0x00000003 | 38 | ; CHECK-NEXT: Initial: 0x00000002 |
| 34 | ; CHECK-NEXT: Maximum: 0x00000003 | 39 | ; CHECK-NEXT: Maximum: 0x00000002 |
| 35 | ; CHECK-NEXT: - Type: MEMORY | 40 | ; CHECK-NEXT: - Type: MEMORY |
| 36 | ; CHECK-NEXT: Memories: | 41 | ; CHECK-NEXT: Memories: |
| 37 | ; CHECK-NEXT: - Initial: 0x00000002 | 42 | ; CHECK-NEXT: - Initial: 0x00000002 |
| 38 | ; CHECK-NEXT: - Type: GLOBAL | 43 | ; CHECK-NEXT: - Type: GLOBAL |
| 39 | ; CHECK-NEXT: Globals: | 44 | ; CHECK-NEXT: Globals: |
| 40 | ; CHECK-NEXT: - Type: I32 | 45 | ; CHECK-NEXT: - Index: 0 |
| 46 | ; CHECK-NEXT: Type: I32 | ||
| 41 | ; CHECK-NEXT: Mutable: true | 47 | ; CHECK-NEXT: Mutable: true |
| 42 | ; CHECK-NEXT: InitExpr: | 48 | ; CHECK-NEXT: InitExpr: |
| 43 | ; CHECK-NEXT: Opcode: I32_CONST | 49 | ; CHECK-NEXT: Opcode: I32_CONST |
| 44 | ; CHECK-NEXT: Value: 66560 | 50 | ; 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 | ||
| 45 | ; CHECK-NEXT: - Type: EXPORT | 63 | ; CHECK-NEXT: - Type: EXPORT |
| 46 | ; CHECK-NEXT: Exports: | 64 | ; CHECK-NEXT: Exports: |
| 47 | ; CHECK-NEXT: - Name: memory | 65 | ; CHECK-NEXT: - Name: memory |
| 48 | ; CHECK-NEXT: Kind: MEMORY | 66 | ; CHECK-NEXT: Kind: MEMORY |
| 49 | ; CHECK-NEXT: Index: 0 | 67 | ; 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 | ||
| 50 | ; CHECK-NEXT: - Name: _start | 74 | ; CHECK-NEXT: - Name: _start |
| 51 | ; CHECK-NEXT: Kind: FUNCTION | 75 | ; CHECK-NEXT: Kind: FUNCTION |
| 52 | ; CHECK-NEXT: Index: 0 | 76 | ; CHECK-NEXT: Index: 1 |
| 53 | ; CHECK-NEXT: - Name: alias_fn | 77 | ; CHECK-NEXT: - Name: alias_fn |
| 54 | ; CHECK-NEXT: Kind: FUNCTION | 78 | ; CHECK-NEXT: Kind: FUNCTION |
| 55 | ; CHECK-NEXT: Index: 1 | 79 | ; CHECK-NEXT: Index: 2 |
| 56 | ; CHECK-NEXT: - Name: direct_fn | 80 | ; CHECK-NEXT: - Name: direct_fn |
| 57 | ; CHECK-NEXT: Kind: FUNCTION | 81 | ; CHECK-NEXT: Kind: FUNCTION |
| 58 | ; CHECK-NEXT: Index: 1 | 82 | ; CHECK-NEXT: Index: 2 |
| 59 | ; CHECK-NEXT: - Name: call_direct | 83 | ; CHECK-NEXT: - Name: call_direct |
| 60 | ; CHECK-NEXT: Kind: FUNCTION | 84 | ; CHECK-NEXT: Kind: FUNCTION |
| 61 | ; CHECK-NEXT: Index: 2 | 85 | ; CHECK-NEXT: Index: 3 |
| 62 | ; CHECK-NEXT: - Name: call_alias | 86 | ; CHECK-NEXT: - Name: call_alias |
| 63 | ; CHECK-NEXT: Kind: FUNCTION | 87 | ; CHECK-NEXT: Kind: FUNCTION |
| 64 | ; CHECK-NEXT: Index: 3 | 88 | ; CHECK-NEXT: Index: 4 |
| 65 | ; CHECK-NEXT: - Name: call_alias_ptr | 89 | ; CHECK-NEXT: - Name: call_alias_ptr |
| 66 | ; CHECK-NEXT: Kind: FUNCTION | 90 | ; CHECK-NEXT: Kind: FUNCTION |
| 67 | ; CHECK-NEXT: Index: 4 | 91 | ; CHECK-NEXT: Index: 5 |
| 68 | ; CHECK-NEXT: - Name: call_direct_ptr | 92 | ; CHECK-NEXT: - Name: call_direct_ptr |
| 69 | ; CHECK-NEXT: Kind: FUNCTION | 93 | ; CHECK-NEXT: Kind: FUNCTION |
| 70 | ; CHECK-NEXT: Index: 5 | 94 | ; CHECK-NEXT: Index: 6 |
| 71 | ; CHECK-NEXT: - Type: ELEM | 95 | ; CHECK-NEXT: - Type: ELEM |
| 72 | ; CHECK-NEXT: Segments: | 96 | ; CHECK-NEXT: Segments: |
| 73 | ; CHECK-NEXT: - Offset: | 97 | ; CHECK-NEXT: - Offset: |
| 74 | ; CHECK-NEXT: Opcode: I32_CONST | 98 | ; CHECK-NEXT: Opcode: I32_CONST |
| 75 | ; CHECK-NEXT: Value: 1 | 99 | ; CHECK-NEXT: Value: 1 |
| 76 | ; CHECK-NEXT: Functions: [ 1, 1 ] | 100 | ; CHECK-NEXT: Functions: [ 2 ] |
| 77 | ; CHECK-NEXT: - Type: CODE | 101 | ; CHECK-NEXT: - Type: CODE |
| 78 | ; CHECK-NEXT: Functions: | 102 | ; CHECK-NEXT: Functions: |
| 79 | ; CHECK-NEXT: - Locals: | 103 | ; CHECK-NEXT: - Index: 0 |
| 80 | ; CHECK-NEXT: Body: 1081808080000B | 104 | ; CHECK-NEXT: Locals: |
| 81 | ; CHECK-NEXT: - Locals: | 105 | ; CHECK-NEXT: Body: 0B |
| 106 | ; CHECK-NEXT: - Index: 1 | ||
| 107 | ; CHECK-NEXT: Locals: | ||
| 108 | ; CHECK-NEXT: Body: 1082808080001A0B | ||
| 109 | ; CHECK-NEXT: - Index: 2 | ||
| 110 | ; CHECK-NEXT: Locals: | ||
| 82 | ; CHECK-NEXT: Body: 41000B | 111 | ; CHECK-NEXT: Body: 41000B |
| 83 | ; CHECK-NEXT: - Locals: | 112 | ; CHECK-NEXT: - Index: 3 |
| 84 | ; CHECK-NEXT: Body: 1081808080000B | 113 | ; CHECK-NEXT: Locals: |
| 85 | ; CHECK-NEXT: - Locals: | 114 | ; CHECK-NEXT: Body: 1082808080000B |
| 86 | ; CHECK-NEXT: Body: 1081808080000B | 115 | ; CHECK-NEXT: - Index: 4 |
| 87 | ; CHECK-NEXT: - Locals: | 116 | ; CHECK-NEXT: Locals: |
| 117 | ; CHECK-NEXT: Body: 1082808080000B | ||
| 118 | ; CHECK-NEXT: - Index: 5 | ||
| 119 | ; CHECK-NEXT: Locals: | ||
| 88 | ; CHECK-NEXT: - Type: I32 | 120 | ; CHECK-NEXT: - Type: I32 |
| 89 | ; CHECK-NEXT: Count: 2 | 121 | ; CHECK-NEXT: Count: 2 |
| 90 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B | 122 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081082808080002101200041106A24808080800020010B |
| 91 | ; CHECK-NEXT: - Locals: | 123 | ; CHECK-NEXT: - Index: 6 |
| 124 | ; CHECK-NEXT: Locals: | ||
| 92 | ; CHECK-NEXT: - Type: I32 | 125 | ; CHECK-NEXT: - Type: I32 |
| 93 | ; CHECK-NEXT: Count: 2 | 126 | ; CHECK-NEXT: Count: 2 |
| 94 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081081808080002101200041106A24808080800020010B | 127 | ; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081082808080002101200041106A24808080800020010B |
| 95 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 96 | ; CHECK-NEXT: Name: linking | ||
| 97 | ; CHECK-NEXT: DataSize: 0 | ||
| 98 | ; CHECK-NEXT: - Type: CUSTOM | 128 | ; CHECK-NEXT: - Type: CUSTOM |
| 99 | ; CHECK-NEXT: Name: name | 129 | ; CHECK-NEXT: Name: name |
| 100 | ; CHECK-NEXT: FunctionNames: | 130 | ; CHECK-NEXT: FunctionNames: |
| 101 | ; CHECK-NEXT: - Index: 0 | 131 | ; CHECK-NEXT: - Index: 0 |
| 102 | ; CHECK-NEXT: Name: _start | 132 | ; CHECK-NEXT: Name: __wasm_call_ctors |
| 103 | ; CHECK-NEXT: - Index: 1 | 133 | ; CHECK-NEXT: - Index: 1 |
| 104 | ; CHECK-NEXT: Name: direct_fn | 134 | ; CHECK-NEXT: Name: _start |
| 105 | ; CHECK-NEXT: - Index: 2 | 135 | ; CHECK-NEXT: - Index: 2 |
| 106 | ; CHECK-NEXT: Name: call_direct | 136 | ; CHECK-NEXT: Name: direct_fn |
| 107 | ; CHECK-NEXT: - Index: 3 | 137 | ; CHECK-NEXT: - Index: 3 |
| 108 | ; CHECK-NEXT: Name: call_alias | 138 | ; CHECK-NEXT: Name: call_direct |
| 109 | ; CHECK-NEXT: - Index: 4 | 139 | ; CHECK-NEXT: - Index: 4 |
| 110 | ; CHECK-NEXT: Name: call_alias_ptr | 140 | ; CHECK-NEXT: Name: call_alias |
| 111 | ; CHECK-NEXT: - Index: 5 | 141 | ; CHECK-NEXT: - Index: 5 |
| 142 | ; CHECK-NEXT: Name: call_alias_ptr | ||
| 143 | ; CHECK-NEXT: - Index: 6 | ||
| 112 | ; CHECK-NEXT: Name: call_direct_ptr | 144 | ; CHECK-NEXT: Name: call_direct_ptr |
| 113 | ; CHECK-NEXT: ... | 145 | ; CHECK-NEXT: ... |
| 146 | |||
| 147 | ; RUN: wasm-ld --relocatable %t.o %t2.o -o %t.reloc.o | ||
| 148 | ; RUN: obj2yaml %t.reloc.o | FileCheck %s -check-prefix=RELOC | ||
| 149 | |||
| 150 | ; RELOC: --- !WASM | ||
| 151 | ; RELOC-NEXT: FileHeader: | ||
| 152 | ; RELOC-NEXT: Version: 0x00000001 | ||
| 153 | ; RELOC-NEXT: Sections: | ||
| 154 | ; RELOC-NEXT: - Type: TYPE | ||
| 155 | ; RELOC-NEXT: Signatures: | ||
| 156 | ; RELOC-NEXT: - Index: 0 | ||
| 157 | ; RELOC-NEXT: ReturnType: NORESULT | ||
| 158 | ; RELOC-NEXT: ParamTypes: | ||
| 159 | ; RELOC-NEXT: - Index: 1 | ||
| 160 | ; RELOC-NEXT: ReturnType: I32 | ||
| 161 | ; RELOC-NEXT: ParamTypes: | ||
| 162 | ; RELOC-NEXT: - Type: IMPORT | ||
| 163 | ; RELOC-NEXT: Imports: | ||
| 164 | ; RELOC-NEXT: - Module: env | ||
| 165 | ; RELOC-NEXT: Field: __stack_pointer | ||
| 166 | ; RELOC-NEXT: Kind: GLOBAL | ||
| 167 | ; RELOC-NEXT: GlobalType: I32 | ||
| 168 | ; RELOC-NEXT: GlobalMutable: true | ||
| 169 | ; RELOC-NEXT: - Type: FUNCTION | ||
| 170 | ; RELOC-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1, 1 ] | ||
| 171 | ; RELOC-NEXT: - Type: TABLE | ||
| 172 | ; RELOC-NEXT: Tables: | ||
| 173 | ; RELOC-NEXT: - ElemType: ANYFUNC | ||
| 174 | ; RELOC-NEXT: Limits: | ||
| 175 | ; RELOC-NEXT: Flags: [ HAS_MAX ] | ||
| 176 | ; RELOC-NEXT: Initial: 0x00000002 | ||
| 177 | ; RELOC-NEXT: Maximum: 0x00000002 | ||
| 178 | ; RELOC-NEXT: - Type: MEMORY | ||
| 179 | ; RELOC-NEXT: Memories: | ||
| 180 | ; RELOC-NEXT: - Initial: 0x00000000 | ||
| 181 | ; RELOC-NEXT: - Type: ELEM | ||
| 182 | ; RELOC-NEXT: Segments: | ||
| 183 | ; RELOC-NEXT: - Offset: | ||
| 184 | ; RELOC-NEXT: Opcode: I32_CONST | ||
| 185 | ; RELOC-NEXT: Value: 1 | ||
| 186 | ; RELOC-NEXT: Functions: [ 1 ] | ||
| 187 | ; RELOC-NEXT: - Type: CODE | ||
| 188 | ; RELOC-NEXT: Relocations: | ||
| 189 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | ||
| 190 | ; RELOC-NEXT: Index: 4 | ||
| 191 | ; RELOC-NEXT: Offset: 0x00000004 | ||
| 192 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | ||
| 193 | ; RELOC-NEXT: Index: 1 | ||
| 194 | ; RELOC-NEXT: Offset: 0x00000013 | ||
| 195 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | ||
| 196 | ; RELOC-NEXT: Index: 4 | ||
| 197 | ; RELOC-NEXT: Offset: 0x0000001C | ||
| 198 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | ||
| 199 | ; RELOC-NEXT: Index: 6 | ||
| 200 | ; RELOC-NEXT: Offset: 0x00000027 | ||
| 201 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | ||
| 202 | ; RELOC-NEXT: Index: 6 | ||
| 203 | ; RELOC-NEXT: Offset: 0x00000032 | ||
| 204 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB | ||
| 205 | ; RELOC-NEXT: Index: 4 | ||
| 206 | ; RELOC-NEXT: Offset: 0x0000003A | ||
| 207 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | ||
| 208 | ; RELOC-NEXT: Index: 4 | ||
| 209 | ; RELOC-NEXT: Offset: 0x00000043 | ||
| 210 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | ||
| 211 | ; RELOC-NEXT: Index: 6 | ||
| 212 | ; RELOC-NEXT: Offset: 0x00000050 | ||
| 213 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | ||
| 214 | ; RELOC-NEXT: Index: 6 | ||
| 215 | ; RELOC-NEXT: Offset: 0x0000005D | ||
| 216 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | ||
| 217 | ; RELOC-NEXT: Index: 6 | ||
| 218 | ; RELOC-NEXT: Offset: 0x00000068 | ||
| 219 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB | ||
| 220 | ; RELOC-NEXT: Index: 1 | ||
| 221 | ; RELOC-NEXT: Offset: 0x00000070 | ||
| 222 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB | ||
| 223 | ; RELOC-NEXT: Index: 1 | ||
| 224 | ; RELOC-NEXT: Offset: 0x00000079 | ||
| 225 | ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB | ||
| 226 | ; RELOC-NEXT: Index: 6 | ||
| 227 | ; RELOC-NEXT: Offset: 0x00000086 | ||
| 228 | ; RELOC-NEXT: Functions: | ||
| 229 | ; RELOC-NEXT: - Index: 0 | ||
| 230 | ; RELOC-NEXT: Locals: | ||
| 231 | ; RELOC-NEXT: Body: 1081808080001A0B | ||
| 232 | ; RELOC-NEXT: - Index: 1 | ||
| 233 | ; RELOC-NEXT: Locals: | ||
| 234 | ; RELOC-NEXT: Body: 41000B | ||
| 235 | ; RELOC-NEXT: - Index: 2 | ||
| 236 | ; RELOC-NEXT: Locals: | ||
| 237 | ; RELOC-NEXT: Body: 1081808080000B | ||
| 238 | ; RELOC-NEXT: - Index: 3 | ||
| 239 | ; RELOC-NEXT: Locals: | ||
| 240 | ; RELOC-NEXT: Body: 1081808080000B | ||
| 241 | ; RELOC-NEXT: - Index: 4 | ||
| 242 | ; RELOC-NEXT: Locals: | ||
| 243 | ; RELOC-NEXT: - Type: I32 | ||
| 244 | ; RELOC-NEXT: Count: 2 | ||
| 245 | ; RELOC-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B | ||
| 246 | ; RELOC-NEXT: - Index: 5 | ||
| 247 | ; RELOC-NEXT: Locals: | ||
| 248 | ; RELOC-NEXT: - Type: I32 | ||
| 249 | ; RELOC-NEXT: Count: 2 | ||
| 250 | ; RELOC-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B | ||
| 251 | ; RELOC-NEXT: - Type: CUSTOM | ||
| 252 | ; RELOC-NEXT: Name: linking | ||
| 253 | ; RELOC-NEXT: Version: 1 | ||
| 254 | ; RELOC-NEXT: SymbolTable: | ||
| 255 | ; RELOC-NEXT: - Index: 0 | ||
| 256 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 257 | ; RELOC-NEXT: Name: _start | ||
| 258 | ; RELOC-NEXT: Flags: [ ] | ||
| 259 | ; RELOC-NEXT: Function: 0 | ||
| 260 | ; RELOC-NEXT: - Index: 1 | ||
| 261 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 262 | ; RELOC-NEXT: Name: direct_fn | ||
| 263 | ; RELOC-NEXT: Flags: [ ] | ||
| 264 | ; RELOC-NEXT: Function: 1 | ||
| 265 | ; RELOC-NEXT: - Index: 2 | ||
| 266 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 267 | ; RELOC-NEXT: Name: call_direct | ||
| 268 | ; RELOC-NEXT: Flags: [ ] | ||
| 269 | ; RELOC-NEXT: Function: 2 | ||
| 270 | ; RELOC-NEXT: - Index: 3 | ||
| 271 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 272 | ; RELOC-NEXT: Name: call_alias | ||
| 273 | ; RELOC-NEXT: Flags: [ ] | ||
| 274 | ; RELOC-NEXT: Function: 3 | ||
| 275 | ; RELOC-NEXT: - Index: 4 | ||
| 276 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 277 | ; RELOC-NEXT: Name: alias_fn | ||
| 278 | ; RELOC-NEXT: Flags: [ BINDING_WEAK ] | ||
| 279 | ; RELOC-NEXT: Function: 1 | ||
| 280 | ; RELOC-NEXT: - Index: 5 | ||
| 281 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 282 | ; RELOC-NEXT: Name: call_alias_ptr | ||
| 283 | ; RELOC-NEXT: Flags: [ ] | ||
| 284 | ; RELOC-NEXT: Function: 4 | ||
| 285 | ; RELOC-NEXT: - Index: 6 | ||
| 286 | ; RELOC-NEXT: Kind: GLOBAL | ||
| 287 | ; RELOC-NEXT: Name: __stack_pointer | ||
| 288 | ; RELOC-NEXT: Flags: [ UNDEFINED ] | ||
| 289 | ; RELOC-NEXT: Global: 0 | ||
| 290 | ; RELOC-NEXT: - Index: 7 | ||
| 291 | ; RELOC-NEXT: Kind: FUNCTION | ||
| 292 | ; RELOC-NEXT: Name: call_direct_ptr | ||
| 293 | ; RELOC-NEXT: Flags: [ ] | ||
| 294 | ; RELOC-NEXT: Function: 5 | ||
| 295 | ; RELOC-NEXT: - Type: CUSTOM | ||
| 296 | ; RELOC-NEXT: Name: name | ||
| 297 | ; RELOC-NEXT: FunctionNames: | ||
| 298 | ; RELOC-NEXT: - Index: 0 | ||
| 299 | ; RELOC-NEXT: Name: _start | ||
| 300 | ; RELOC-NEXT: - Index: 1 | ||
| 301 | ; RELOC-NEXT: Name: direct_fn | ||
| 302 | ; RELOC-NEXT: - Index: 2 | ||
| 303 | ; RELOC-NEXT: Name: call_direct | ||
| 304 | ; RELOC-NEXT: - Index: 3 | ||
| 305 | ; RELOC-NEXT: Name: call_alias | ||
| 306 | ; RELOC-NEXT: - Index: 4 | ||
| 307 | ; RELOC-NEXT: Name: call_alias_ptr | ||
| 308 | ; RELOC-NEXT: - Index: 5 | ||
| 309 | ; RELOC-NEXT: Name: call_direct_ptr | ||
| 310 | ; RELOC-NEXT: ... |
deps/lld/test/wasm/weak-external.ll deleted-86| ... | @@ -1,86 +0,0 @@ | ||
| 1 | ; RUN: llc -mtriple=wasm32-unknown-unknown-wasm -filetype=obj -o %t.o %s | ||
| 2 | ; RUN: lld -flavor wasm -strip-debug %t.o -o %t.wasm | ||
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 4 | |||
| 5 | ; Test that undefined weak externals (global_var) and (foo) don't cause | ||
| 6 | ; link failures and resolve to zero. | ||
| 7 | |||
| 8 | @global_var = extern_weak global i32, align 4 | ||
| 9 | |||
| 10 | declare extern_weak i32 @foo() | ||
| 11 | |||
| 12 | define i8* @get_address_of_foo() #0 { | ||
| 13 | entry: | ||
| 14 | ret i8* bitcast (i32 ()* @foo to i8*) | ||
| 15 | } | ||
| 16 | |||
| 17 | define i32* @get_address_of_global_var() #0 { | ||
| 18 | ret i32* @global_var | ||
| 19 | } | ||
| 20 | |||
| 21 | define i32 @_start() #0 { | ||
| 22 | entry: | ||
| 23 | %0 = load i32, i32* @global_var, align 4 | ||
| 24 | ret i32 %0 | ||
| 25 | } | ||
| 26 | |||
| 27 | ; CHECK: --- !WASM | ||
| 28 | ; CHECK-NEXT: FileHeader: | ||
| 29 | ; CHECK-NEXT: Version: 0x00000001 | ||
| 30 | ; CHECK-NEXT: Sections: | ||
| 31 | ; CHECK-NEXT: - Type: TYPE | ||
| 32 | ; CHECK-NEXT: Signatures: | ||
| 33 | ; CHECK-NEXT: - Index: 0 | ||
| 34 | ; CHECK-NEXT: ReturnType: I32 | ||
| 35 | ; CHECK-NEXT: ParamTypes: | ||
| 36 | ; CHECK-NEXT: - Type: FUNCTION | ||
| 37 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ] | ||
| 38 | ; CHECK-NEXT: - Type: TABLE | ||
| 39 | ; CHECK-NEXT: Tables: | ||
| 40 | ; CHECK-NEXT: - ElemType: ANYFUNC | ||
| 41 | ; CHECK-NEXT: Limits: | ||
| 42 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | ||
| 43 | ; CHECK-NEXT: Initial: 0x00000002 | ||
| 44 | ; CHECK-NEXT: Maximum: 0x00000002 | ||
| 45 | ; CHECK-NEXT: - Type: MEMORY | ||
| 46 | ; CHECK-NEXT: Memories: | ||
| 47 | ; CHECK-NEXT: - Initial: 0x00000002 | ||
| 48 | ; CHECK-NEXT: - Type: GLOBAL | ||
| 49 | ; CHECK-NEXT: Globals: | ||
| 50 | ; CHECK-NEXT: - Type: I32 | ||
| 51 | ; CHECK-NEXT: Mutable: true | ||
| 52 | ; CHECK-NEXT: InitExpr: | ||
| 53 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 54 | ; CHECK-NEXT: Value: 66560 | ||
| 55 | ; CHECK-NEXT: - Type: EXPORT | ||
| 56 | ; CHECK-NEXT: Exports: | ||
| 57 | ; CHECK-NEXT: - Name: memory | ||
| 58 | ; CHECK-NEXT: Kind: MEMORY | ||
| 59 | ; CHECK-NEXT: Index: 0 | ||
| 60 | ; CHECK-NEXT: - Name: _start | ||
| 61 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 62 | ; CHECK-NEXT: Index: 2 | ||
| 63 | ; CHECK-NEXT: - Name: get_address_of_foo | ||
| 64 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 65 | ; CHECK-NEXT: Index: 0 | ||
| 66 | ; CHECK-NEXT: - Name: get_address_of_global_var | ||
| 67 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 68 | ; CHECK-NEXT: Index: 1 | ||
| 69 | ; CHECK-NEXT: - Type: ELEM | ||
| 70 | ; CHECK-NEXT: Segments: | ||
| 71 | ; CHECK-NEXT: - Offset: | ||
| 72 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 73 | ; CHECK-NEXT: Value: 1 | ||
| 74 | ; CHECK-NEXT: Functions: [ 0 ] | ||
| 75 | ; CHECK-NEXT: - Type: CODE | ||
| 76 | ; CHECK-NEXT: Functions: | ||
| 77 | ; CHECK-NEXT: - Locals: | ||
| 78 | ; CHECK-NEXT: Body: 4181808080000B | ||
| 79 | ; CHECK-NEXT: - Locals: | ||
| 80 | ; CHECK-NEXT: Body: 41FFFFFFFF7F0B | ||
| 81 | ; CHECK-NEXT: - Locals: | ||
| 82 | ; CHECK-NEXT: Body: 41002802FFFFFFFF0F0B | ||
| 83 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 84 | ; CHECK-NEXT: Name: linking | ||
| 85 | ; CHECK-NEXT: DataSize: 0 | ||
| 86 | ; CHECK-NEXT: ... | ||
deps/lld/test/wasm/weak-symbols.ll+66-22| ... | @@ -1,17 +1,19 @@ | ... | @@ -1,17 +1,19 @@ |
| 1 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/weak-symbol1.ll -o %t1.o | 1 | ; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t1.o |
| 2 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %p/Inputs/weak-symbol2.ll -o %t2.o | 2 | ; RUN: llc -filetype=obj %p/Inputs/weak-symbol2.ll -o %t2.o |
| 3 | ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o | 3 | ; RUN: llc -filetype=obj %s -o %t.o |
| 4 | ; RUN: lld -flavor wasm -o %t.wasm %t.o %t1.o %t2.o | 4 | ; RUN: wasm-ld -no-gc-sections -o %t.wasm %t.o %t1.o %t2.o |
| 5 | ; RUN: obj2yaml %t.wasm | FileCheck %s | 5 | ; RUN: obj2yaml %t.wasm | FileCheck %s |
| 6 | 6 | ||
| 7 | target triple = "wasm32-unknown-unknown" | ||
| 8 | |||
| 7 | declare i32 @weakFn() local_unnamed_addr | 9 | declare i32 @weakFn() local_unnamed_addr |
| 8 | @weakGlobal = external global i32 | 10 | @weakGlobal = external global i32 |
| 9 | 11 | ||
| 10 | define i32 @_start() local_unnamed_addr { | 12 | define void @_start() local_unnamed_addr { |
| 11 | entry: | 13 | entry: |
| 12 | %call = call i32 @weakFn() | 14 | %call = call i32 @weakFn() |
| 13 | %val = load i32, i32* @weakGlobal, align 4 | 15 | %val = load i32, i32* @weakGlobal, align 4 |
| 14 | ret i32 %val | 16 | ret void |
| 15 | } | 17 | } |
| 16 | 18 | ||
| 17 | ; CHECK: --- !WASM | 19 | ; CHECK: --- !WASM |
| ... | @@ -21,10 +23,13 @@ entry: | ... | @@ -21,10 +23,13 @@ entry: |
| 21 | ; CHECK-NEXT: - Type: TYPE | 23 | ; CHECK-NEXT: - Type: TYPE |
| 22 | ; CHECK-NEXT: Signatures: | 24 | ; CHECK-NEXT: Signatures: |
| 23 | ; CHECK-NEXT: - Index: 0 | 25 | ; CHECK-NEXT: - Index: 0 |
| 26 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 27 | ; CHECK-NEXT: ParamTypes: | ||
| 28 | ; CHECK-NEXT: - Index: 1 | ||
| 24 | ; CHECK-NEXT: ReturnType: I32 | 29 | ; CHECK-NEXT: ReturnType: I32 |
| 25 | ; CHECK-NEXT: ParamTypes: | 30 | ; CHECK-NEXT: ParamTypes: |
| 26 | ; CHECK-NEXT: - Type: FUNCTION | 31 | ; CHECK-NEXT: - Type: FUNCTION |
| 27 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ] | 32 | ; CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 1, 1 ] |
| 28 | ; CHECK-NEXT: - Type: TABLE | 33 | ; CHECK-NEXT: - Type: TABLE |
| 29 | ; CHECK-NEXT: Tables: | 34 | ; CHECK-NEXT: Tables: |
| 30 | ; CHECK-NEXT: - ElemType: ANYFUNC | 35 | ; CHECK-NEXT: - ElemType: ANYFUNC |
| ... | @@ -37,45 +42,81 @@ entry: | ... | @@ -37,45 +42,81 @@ entry: |
| 37 | ; CHECK-NEXT: - Initial: 0x00000002 | 42 | ; CHECK-NEXT: - Initial: 0x00000002 |
| 38 | ; CHECK-NEXT: - Type: GLOBAL | 43 | ; CHECK-NEXT: - Type: GLOBAL |
| 39 | ; CHECK-NEXT: Globals: | 44 | ; CHECK-NEXT: Globals: |
| 40 | ; CHECK-NEXT: - Type: I32 | 45 | ; CHECK-NEXT: - Index: 0 |
| 46 | ; CHECK-NEXT: Type: I32 | ||
| 41 | ; CHECK-NEXT: Mutable: true | 47 | ; CHECK-NEXT: Mutable: true |
| 42 | ; CHECK-NEXT: InitExpr: | 48 | ; CHECK-NEXT: InitExpr: |
| 43 | ; CHECK-NEXT: Opcode: I32_CONST | 49 | ; CHECK-NEXT: Opcode: I32_CONST |
| 44 | ; CHECK-NEXT: Value: 66576 | 50 | ; CHECK-NEXT: Value: 66576 |
| 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: 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: 1032 | ||
| 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 | ||
| 68 | ; CHECK-NEXT: Value: 1024 | ||
| 45 | ; CHECK-NEXT: - Type: EXPORT | 69 | ; CHECK-NEXT: - Type: EXPORT |
| 46 | ; CHECK-NEXT: Exports: | 70 | ; CHECK-NEXT: Exports: |
| 47 | ; CHECK-NEXT: - Name: memory | 71 | ; CHECK-NEXT: - Name: memory |
| 48 | ; CHECK-NEXT: Kind: MEMORY | 72 | ; CHECK-NEXT: Kind: MEMORY |
| 49 | ; CHECK-NEXT: Index: 0 | 73 | ; 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 | ||
| 50 | ; CHECK-NEXT: - Name: _start | 80 | ; CHECK-NEXT: - Name: _start |
| 51 | ; CHECK-NEXT: Kind: FUNCTION | 81 | ; CHECK-NEXT: Kind: FUNCTION |
| 52 | ; CHECK-NEXT: Index: 0 | 82 | ; CHECK-NEXT: Index: 1 |
| 53 | ; CHECK-NEXT: - Name: weakFn | 83 | ; CHECK-NEXT: - Name: weakFn |
| 54 | ; CHECK-NEXT: Kind: FUNCTION | 84 | ; CHECK-NEXT: Kind: FUNCTION |
| 55 | ; CHECK-NEXT: Index: 1 | 85 | ; CHECK-NEXT: Index: 2 |
| 56 | ; CHECK-NEXT: - Name: exportWeak1 | 86 | ; CHECK-NEXT: - Name: exportWeak1 |
| 57 | ; CHECK-NEXT: Kind: FUNCTION | 87 | ; CHECK-NEXT: Kind: FUNCTION |
| 58 | ; CHECK-NEXT: Index: 2 | 88 | ; CHECK-NEXT: Index: 3 |
| 89 | ; CHECK-NEXT: - Name: weakGlobal | ||
| 90 | ; CHECK-NEXT: Kind: GLOBAL | ||
| 91 | ; CHECK-NEXT: Index: 3 | ||
| 59 | ; CHECK-NEXT: - Name: exportWeak2 | 92 | ; CHECK-NEXT: - Name: exportWeak2 |
| 60 | ; CHECK-NEXT: Kind: FUNCTION | 93 | ; CHECK-NEXT: Kind: FUNCTION |
| 61 | ; CHECK-NEXT: Index: 4 | 94 | ; CHECK-NEXT: Index: 5 |
| 62 | ; CHECK-NEXT: - Type: ELEM | 95 | ; CHECK-NEXT: - Type: ELEM |
| 63 | ; CHECK-NEXT: Segments: | 96 | ; CHECK-NEXT: Segments: |
| 64 | ; CHECK-NEXT: - Offset: | 97 | ; CHECK-NEXT: - Offset: |
| 65 | ; CHECK-NEXT: Opcode: I32_CONST | 98 | ; CHECK-NEXT: Opcode: I32_CONST |
| 66 | ; CHECK-NEXT: Value: 1 | 99 | ; CHECK-NEXT: Value: 1 |
| 67 | ; CHECK-NEXT: Functions: [ 1 ] | 100 | ; CHECK-NEXT: Functions: [ 2 ] |
| 68 | ; CHECK-NEXT: - Type: CODE | 101 | ; CHECK-NEXT: - Type: CODE |
| 69 | ; CHECK-NEXT: Functions: | 102 | ; CHECK-NEXT: Functions: |
| 70 | ; CHECK-NEXT: - Locals: | 103 | ; CHECK-NEXT: - Index: 0 |
| 71 | ; CHECK-NEXT: Body: 1081808080001A4100280280888080000B | 104 | ; CHECK-NEXT: Locals: |
| 72 | ; CHECK-NEXT: - Locals: | 105 | ; CHECK-NEXT: Body: 0B |
| 106 | ; CHECK-NEXT: - Index: 1 | ||
| 107 | ; CHECK-NEXT: Locals: | ||
| 108 | ; CHECK-NEXT: Body: 1082808080001A0B | ||
| 109 | ; CHECK-NEXT: - Index: 2 | ||
| 110 | ; CHECK-NEXT: Locals: | ||
| 73 | ; CHECK-NEXT: Body: 41010B | 111 | ; CHECK-NEXT: Body: 41010B |
| 74 | ; CHECK-NEXT: - Locals: | 112 | ; CHECK-NEXT: - Index: 3 |
| 113 | ; CHECK-NEXT: Locals: | ||
| 75 | ; CHECK-NEXT: Body: 4181808080000B | 114 | ; CHECK-NEXT: Body: 4181808080000B |
| 76 | ; CHECK-NEXT: - Locals: | 115 | ; CHECK-NEXT: - Index: 4 |
| 116 | ; CHECK-NEXT: Locals: | ||
| 77 | ; CHECK-NEXT: Body: 41020B | 117 | ; CHECK-NEXT: Body: 41020B |
| 78 | ; CHECK-NEXT: - Locals: | 118 | ; CHECK-NEXT: - Index: 5 |
| 119 | ; CHECK-NEXT: Locals: | ||
| 79 | ; CHECK-NEXT: Body: 4181808080000B | 120 | ; CHECK-NEXT: Body: 4181808080000B |
| 80 | ; CHECK-NEXT: - Type: DATA | 121 | ; CHECK-NEXT: - Type: DATA |
| 81 | ; CHECK-NEXT: Segments: | 122 | ; CHECK-NEXT: Segments: |
| ... | @@ -86,15 +127,18 @@ entry: | ... | @@ -86,15 +127,18 @@ entry: |
| 86 | ; CHECK-NEXT: Value: 1024 | 127 | ; CHECK-NEXT: Value: 1024 |
| 87 | ; CHECK-NEXT: Content: '0100000002000000' | 128 | ; CHECK-NEXT: Content: '0100000002000000' |
| 88 | ; CHECK-NEXT: - Type: CUSTOM | 129 | ; CHECK-NEXT: - Type: CUSTOM |
| 89 | ; CHECK-NEXT: Name: linking | ||
| 90 | ; CHECK-NEXT: DataSize: 8 | ||
| 91 | ; CHECK-NEXT: - Type: CUSTOM | ||
| 92 | ; CHECK-NEXT: Name: name | 130 | ; CHECK-NEXT: Name: name |
| 93 | ; CHECK-NEXT: FunctionNames: | 131 | ; CHECK-NEXT: FunctionNames: |
| 94 | ; CHECK-NEXT: - Index: 0 | 132 | ; CHECK-NEXT: - Index: 0 |
| 133 | ; CHECK-NEXT: Name: __wasm_call_ctors | ||
| 134 | ; CHECK-NEXT: - Index: 1 | ||
| 95 | ; CHECK-NEXT: Name: _start | 135 | ; CHECK-NEXT: Name: _start |
| 96 | ; CHECK-NEXT: - Index: 2 | 136 | ; CHECK-NEXT: - Index: 2 |
| 137 | ; CHECK-NEXT: Name: weakFn | ||
| 138 | ; CHECK-NEXT: - Index: 3 | ||
| 97 | ; CHECK-NEXT: Name: exportWeak1 | 139 | ; CHECK-NEXT: Name: exportWeak1 |
| 98 | ; CHECK-NEXT: - Index: 4 | 140 | ; CHECK-NEXT: - Index: 4 |
| 141 | ; CHECK-NEXT: Name: weakFn | ||
| 142 | ; CHECK-NEXT: - Index: 5 | ||
| 99 | ; CHECK-NEXT: Name: exportWeak2 | 143 | ; CHECK-NEXT: Name: exportWeak2 |
| 100 | ; CHECK-NEXT: ... | 144 | ; CHECK-NEXT: ... |
deps/lld/test/wasm/weak-undefined.ll created+107| ... | @@ -0,0 +1,107 @@ | ||
| 1 | ; RUN: llc -filetype=obj -o %t.o %s | ||
| 2 | ; RUN: wasm-ld -strip-debug %t.o -o %t.wasm | ||
| 3 | ; RUN: obj2yaml %t.wasm | FileCheck %s | ||
| 4 | |||
| 5 | ; Test that undefined weak externals (global_var) and (foo) don't cause | ||
| 6 | ; link failures and resolve to zero. | ||
| 7 | |||
| 8 | target triple = "wasm32-unknown-unknown" | ||
| 9 | |||
| 10 | @global_var = extern_weak global i32, align 4 | ||
| 11 | |||
| 12 | declare extern_weak i32 @foo() | ||
| 13 | |||
| 14 | define i8* @get_address_of_foo() #0 { | ||
| 15 | entry: | ||
| 16 | ret i8* bitcast (i32 ()* @foo to i8*) | ||
| 17 | } | ||
| 18 | |||
| 19 | define i32* @get_address_of_global_var() #0 { | ||
| 20 | ret i32* @global_var | ||
| 21 | } | ||
| 22 | |||
| 23 | define void @_start() #0 { | ||
| 24 | entry: | ||
| 25 | %call = call i32* @get_address_of_global_var() | ||
| 26 | ret void | ||
| 27 | } | ||
| 28 | |||
| 29 | ; CHECK: --- !WASM | ||
| 30 | ; CHECK-NEXT: FileHeader: | ||
| 31 | ; CHECK-NEXT: Version: 0x00000001 | ||
| 32 | ; CHECK-NEXT: Sections: | ||
| 33 | ; CHECK-NEXT: - Type: TYPE | ||
| 34 | ; CHECK-NEXT: Signatures: | ||
| 35 | ; CHECK-NEXT: - Index: 0 | ||
| 36 | ; CHECK-NEXT: ReturnType: NORESULT | ||
| 37 | ; CHECK-NEXT: ParamTypes: | ||
| 38 | ; CHECK-NEXT: - Index: 1 | ||
| 39 | ; CHECK-NEXT: ReturnType: I32 | ||
| 40 | ; CHECK-NEXT: ParamTypes: | ||
| 41 | ; CHECK-NEXT: - Type: FUNCTION | ||
| 42 | ; CHECK-NEXT: FunctionTypes: [ 0, 1, 1, 0 ] | ||
| 43 | ; CHECK-NEXT: - Type: TABLE | ||
| 44 | ; CHECK-NEXT: Tables: | ||
| 45 | ; CHECK-NEXT: - ElemType: ANYFUNC | ||
| 46 | ; CHECK-NEXT: Limits: | ||
| 47 | ; CHECK-NEXT: Flags: [ HAS_MAX ] | ||
| 48 | ; CHECK-NEXT: Initial: 0x00000001 | ||
| 49 | ; CHECK-NEXT: Maximum: 0x00000001 | ||
| 50 | ; CHECK-NEXT: - Type: MEMORY | ||
| 51 | ; CHECK-NEXT: Memories: | ||
| 52 | ; CHECK-NEXT: - Initial: 0x00000002 | ||
| 53 | ; CHECK-NEXT: - Type: GLOBAL | ||
| 54 | ; CHECK-NEXT: Globals: | ||
| 55 | ; CHECK-NEXT: - Index: 0 | ||
| 56 | ; CHECK-NEXT: Type: I32 | ||
| 57 | ; CHECK-NEXT: Mutable: true | ||
| 58 | ; CHECK-NEXT: InitExpr: | ||
| 59 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 60 | ; CHECK-NEXT: Value: 66560 | ||
| 61 | ; CHECK-NEXT: - Index: 1 | ||
| 62 | ; CHECK-NEXT: Type: I32 | ||
| 63 | ; CHECK-NEXT: Mutable: false | ||
| 64 | ; CHECK-NEXT: InitExpr: | ||
| 65 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 66 | ; CHECK-NEXT: Value: 66560 | ||
| 67 | ; CHECK-NEXT: - Index: 2 | ||
| 68 | ; CHECK-NEXT: Type: I32 | ||
| 69 | ; CHECK-NEXT: Mutable: false | ||
| 70 | ; CHECK-NEXT: InitExpr: | ||
| 71 | ; CHECK-NEXT: Opcode: I32_CONST | ||
| 72 | ; CHECK-NEXT: Value: 1024 | ||
| 73 | ; CHECK-NEXT: - Type: EXPORT | ||
| 74 | ; CHECK-NEXT: Exports: | ||
| 75 | ; CHECK-NEXT: - Name: memory | ||
| 76 | ; CHECK-NEXT: Kind: MEMORY | ||
| 77 | ; 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 | ||
| 84 | ; CHECK-NEXT: - Name: _start | ||
| 85 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 86 | ; CHECK-NEXT: Index: 3 | ||
| 87 | ; CHECK-NEXT: - Name: get_address_of_foo | ||
| 88 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 89 | ; CHECK-NEXT: Index: 1 | ||
| 90 | ; CHECK-NEXT: - Name: get_address_of_global_var | ||
| 91 | ; CHECK-NEXT: Kind: FUNCTION | ||
| 92 | ; CHECK-NEXT: Index: 2 | ||
| 93 | ; CHECK-NEXT: - Type: CODE | ||
| 94 | ; CHECK-NEXT: Functions: | ||
| 95 | ; CHECK-NEXT: - Index: 0 | ||
| 96 | ; CHECK-NEXT: Locals: | ||
| 97 | ; CHECK-NEXT: Body: 0B | ||
| 98 | ; CHECK-NEXT: - Index: 1 | ||
| 99 | ; CHECK-NEXT: Locals: | ||
| 100 | ; CHECK-NEXT: Body: 4180808080000B | ||
| 101 | ; CHECK-NEXT: - Index: 2 | ||
| 102 | ; CHECK-NEXT: Locals: | ||
| 103 | ; CHECK-NEXT: Body: 4180808080000B | ||
| 104 | ; CHECK-NEXT: - Index: 3 | ||
| 105 | ; CHECK-NEXT: Locals: | ||
| 106 | ; CHECK-NEXT: Body: 1082808080001A0B | ||
| 107 | ; CHECK-NEXT: ... | ||
deps/lld/test/wasm/whole-archive.test created+34| ... | @@ -0,0 +1,34 @@ | ||
| 1 | RUN: llc -filetype=obj %p/Inputs/start.ll -o %t.o | ||
| 2 | RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o | ||
| 3 | RUN: rm -f %t.a | ||
| 4 | RUN: llvm-ar rcs %t.a %t.ret32.o | ||
| 5 | |||
| 6 | Should not add symbols from the archive by default as they are not required | ||
| 7 | RUN: wasm-ld --no-gc-sections -o %t.wasm %t.o %t.a | ||
| 8 | RUN: obj2yaml %t.wasm | FileCheck --check-prefix=NOTADDED %s | ||
| 9 | NOTADDED: FunctionNames: | ||
| 10 | NOTADDED-NOT: Name: ret32 | ||
| 11 | NOTADDED: ... | ||
| 12 | |||
| 13 | Should add symbols from the archive if --whole-archive is used | ||
| 14 | RUN: wasm-ld --no-gc-sections -o %t.wasm %t.o --whole-archive %t.a | ||
| 15 | RUN: obj2yaml %t.wasm | FileCheck --check-prefix=ADDED %s | ||
| 16 | ADDED: FunctionNames: | ||
| 17 | ADDED: Name: ret32 | ||
| 18 | ADDED: ... | ||
| 19 | |||
| 20 | --no-whole-archive should restore default behaviour | ||
| 21 | RUN: wasm-ld --no-gc-sections -o %t.wasm %t.o --whole-archive --no-whole-archive %t.a | ||
| 22 | RUN: obj2yaml %t.wasm | FileCheck --check-prefix=NOTADDED %s | ||
| 23 | |||
| 24 | --whole-archive and --no-whole-archive should affect only archives which follow them | ||
| 25 | RUN: wasm-ld --no-gc-sections -o %t.wasm %t.o %t.a --whole-archive --no-whole-archive | ||
| 26 | RUN: obj2yaml %t.wasm | FileCheck --check-prefix=NOTADDED %s | ||
| 27 | RUN: wasm-ld --no-gc-sections -o %t.wasm %t.o --whole-archive %t.a --no-whole-archive | ||
| 28 | RUN: obj2yaml %t.wasm | FileCheck --check-prefix=ADDED %s | ||
| 29 | |||
| 30 | --whole-archive should also work with thin archives | ||
| 31 | RUN: rm -f %tthin.a | ||
| 32 | RUN: llvm-ar --format=gnu rcsT %tthin.a %t.ret32.o | ||
| 33 | RUN: wasm-ld --no-gc-sections -o %t.wasm %t.o --whole-archive %tthin.a | ||
| 34 | RUN: obj2yaml %t.wasm | FileCheck --check-prefix=ADDED %s | ||
deps/lld/tools/lld/lld.cpp+32-17| ... | @@ -7,12 +7,22 @@ | ... | @@ -7,12 +7,22 @@ |
| 7 | // | 7 | // |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | // | 9 | // |
| 10 | // This is the entry point to the lld driver. This is a thin wrapper which | 10 | // This file contains the main function of the lld executable. The main |
| 11 | // dispatches to the given platform specific driver. | 11 | // function is a thin wrapper which dispatches to the platform specific |
| 12 | // driver. | ||
| 12 | // | 13 | // |
| 13 | // If there is -flavor option, it is dispatched according to the arguments. | 14 | // lld is a single executable that contains four different linkers for ELF, |
| 14 | // If the flavor parameter is not present, then it is dispatched according | 15 | // COFF, WebAssembly and Mach-O. The main function dispatches according to |
| 15 | // to argv[0]. | 16 | // argv[0] (i.e. command name). The most common name for each target is shown |
| 17 | // below: | ||
| 18 | // | ||
| 19 | // - ld.lld: ELF (Unix) | ||
| 20 | // - ld64: Mach-O (macOS) | ||
| 21 | // - lld-link: COFF (Windows) | ||
| 22 | // - ld-wasm: WebAssembly | ||
| 23 | // | ||
| 24 | // lld can be invoked as "lld" along with "-flavor" option. This is for | ||
| 25 | // backward compatibility and not recommended. | ||
| 16 | // | 26 | // |
| 17 | //===----------------------------------------------------------------------===// | 27 | //===----------------------------------------------------------------------===// |
| 18 | 28 | ||
| ... | @@ -20,10 +30,9 @@ | ... | @@ -20,10 +30,9 @@ |
| 20 | #include "llvm/ADT/STLExtras.h" | 30 | #include "llvm/ADT/STLExtras.h" |
| 21 | #include "llvm/ADT/StringSwitch.h" | 31 | #include "llvm/ADT/StringSwitch.h" |
| 22 | #include "llvm/ADT/Twine.h" | 32 | #include "llvm/ADT/Twine.h" |
| 23 | #include "llvm/Support/ManagedStatic.h" | 33 | #include "llvm/Support/InitLLVM.h" |
| 24 | #include "llvm/Support/Path.h" | 34 | #include "llvm/Support/Path.h" |
| 25 | #include "llvm/Support/PrettyStackTrace.h" | 35 | #include <cstdlib> |
| 26 | #include "llvm/Support/Signals.h" | ||
| 27 | 36 | ||
| 28 | using namespace lld; | 37 | using namespace lld; |
| 29 | using namespace llvm; | 38 | using namespace llvm; |
| ... | @@ -102,28 +111,34 @@ static Flavor parseFlavor(std::vector<const char *> &V) { | ... | @@ -102,28 +111,34 @@ static Flavor parseFlavor(std::vector<const char *> &V) { |
| 102 | return parseProgname(Arg0); | 111 | return parseProgname(Arg0); |
| 103 | } | 112 | } |
| 104 | 113 | ||
| 114 | // If this function returns true, lld calls _exit() so that it quickly | ||
| 115 | // exits without invoking destructors of globally allocated objects. | ||
| 116 | // | ||
| 117 | // We don't want to do that if we are running tests though, because | ||
| 118 | // doing that breaks leak sanitizer. So, lit sets this environment variable, | ||
| 119 | // and we use it to detect whether we are running tests or not. | ||
| 120 | static bool canExitEarly() { return StringRef(getenv("LLD_IN_TEST")) != "1"; } | ||
| 121 | |||
| 105 | /// Universal linker main(). This linker emulates the gnu, darwin, or | 122 | /// Universal linker main(). This linker emulates the gnu, darwin, or |
| 106 | /// windows linker based on the argv[0] or -flavor option. | 123 | /// windows linker based on the argv[0] or -flavor option. |
| 107 | int main(int Argc, const char **Argv) { | 124 | int main(int Argc, const char **Argv) { |
| 108 | // Standard set up, so program fails gracefully. | 125 | InitLLVM X(Argc, Argv); |
| 109 | sys::PrintStackTraceOnErrorSignal(Argv[0]); | ||
| 110 | PrettyStackTraceProgram StackPrinter(Argc, Argv); | ||
| 111 | llvm_shutdown_obj Shutdown; | ||
| 112 | 126 | ||
| 113 | std::vector<const char *> Args(Argv, Argv + Argc); | 127 | std::vector<const char *> Args(Argv, Argv + Argc); |
| 114 | switch (parseFlavor(Args)) { | 128 | switch (parseFlavor(Args)) { |
| 115 | case Gnu: | 129 | case Gnu: |
| 116 | if (isPETarget(Args)) | 130 | if (isPETarget(Args)) |
| 117 | return !mingw::link(Args); | 131 | return !mingw::link(Args); |
| 118 | return !elf::link(Args, true); | 132 | return !elf::link(Args, canExitEarly()); |
| 119 | case WinLink: | 133 | case WinLink: |
| 120 | return !coff::link(Args, true); | 134 | return !coff::link(Args, canExitEarly()); |
| 121 | case Darwin: | 135 | case Darwin: |
| 122 | return !mach_o::link(Args); | 136 | return !mach_o::link(Args, canExitEarly()); |
| 123 | case Wasm: | 137 | case Wasm: |
| 124 | return !wasm::link(Args, true); | 138 | return !wasm::link(Args, canExitEarly()); |
| 125 | default: | 139 | default: |
| 126 | die("lld is a generic driver.\n" | 140 | die("lld is a generic driver.\n" |
| 127 | "Invoke ld.lld (Unix), ld (macOS) or lld-link (Windows) instead."); | 141 | "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-lld" |
| 142 | " (WebAssembly) instead"); | ||
| 128 | } | 143 | } |
| 129 | } | 144 | } |
deps/lld/unittests/DriverTests/DarwinLdDriverTest.cpp+3-6| ... | @@ -8,7 +8,7 @@ | ... | @@ -8,7 +8,7 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | /// | 9 | /// |
| 10 | /// \file | 10 | /// \file |
| 11 | /// \brief Darwin's ld driver tests. | 11 | /// Darwin's ld driver tests. |
| 12 | /// | 12 | /// |
| 13 | //===----------------------------------------------------------------------===// | 13 | //===----------------------------------------------------------------------===// |
| 14 | 14 | ||
| ... | @@ -23,8 +23,7 @@ using namespace lld; | ... | @@ -23,8 +23,7 @@ using namespace lld; |
| 23 | 23 | ||
| 24 | namespace lld { | 24 | namespace lld { |
| 25 | namespace mach_o { | 25 | namespace mach_o { |
| 26 | bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx, | 26 | bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx); |
| 27 | raw_ostream &diagnostics); | ||
| 28 | } | 27 | } |
| 29 | } | 28 | } |
| 30 | 29 | ||
| ... | @@ -42,9 +41,7 @@ protected: | ... | @@ -42,9 +41,7 @@ protected: |
| 42 | 41 | ||
| 43 | bool parse(std::vector<const char *> args) { | 42 | bool parse(std::vector<const char *> args) { |
| 44 | args.insert(args.begin(), "ld"); | 43 | args.insert(args.begin(), "ld"); |
| 45 | std::string errorMessage; | 44 | return mach_o::parse(args, _ctx); |
| 46 | raw_string_ostream os(errorMessage); | ||
| 47 | return mach_o::parse(args, _ctx, os); | ||
| 48 | } | 45 | } |
| 49 | 46 | ||
| 50 | MachOLinkingContext _ctx; | 47 | MachOLinkingContext _ctx; |
deps/lld/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp+10-5| ... | @@ -12,14 +12,17 @@ | ... | @@ -12,14 +12,17 @@ |
| 12 | #include "llvm/ADT/StringRef.h" | 12 | #include "llvm/ADT/StringRef.h" |
| 13 | #include "llvm/BinaryFormat/MachO.h" | 13 | #include "llvm/BinaryFormat/MachO.h" |
| 14 | #include "llvm/Support/Error.h" | 14 | #include "llvm/Support/Error.h" |
| 15 | #include "llvm/Support/FileSystem.h" | ||
| 15 | #include "llvm/Support/MemoryBuffer.h" | 16 | #include "llvm/Support/MemoryBuffer.h" |
| 16 | #include "llvm/Support/YAMLTraits.h" | 17 | #include "llvm/Support/YAMLTraits.h" |
| 17 | #include "gtest/gtest.h" | 18 | #include "gtest/gtest.h" |
| 18 | #include <cstdint> | 19 | #include <cstdint> |
| 19 | #include <memory> | 20 | #include <memory> |
| 20 | 21 | ||
| 22 | using llvm::SmallString; | ||
| 21 | using llvm::StringRef; | 23 | using llvm::StringRef; |
| 22 | using llvm::MemoryBuffer; | 24 | using llvm::MemoryBuffer; |
| 25 | using llvm::Twine; | ||
| 23 | 26 | ||
| 24 | using namespace lld::mach_o::normalized; | 27 | using namespace lld::mach_o::normalized; |
| 25 | using namespace llvm::MachO; | 28 | using namespace llvm::MachO; |
| ... | @@ -741,9 +744,11 @@ TEST(BinaryReaderTest, hello_obj_ppc) { | ... | @@ -741,9 +744,11 @@ TEST(BinaryReaderTest, hello_obj_ppc) { |
| 741 | EXPECT_EQ(printfLabel.type, N_UNDF); | 744 | EXPECT_EQ(printfLabel.type, N_UNDF); |
| 742 | EXPECT_EQ(printfLabel.scope, SymbolScope(N_EXT)); | 745 | EXPECT_EQ(printfLabel.scope, SymbolScope(N_EXT)); |
| 743 | 746 | ||
| 744 | auto ec = writeBinary(*f, "/tmp/foo.o"); | 747 | SmallString<128> tmpFl; |
| 745 | // FIXME: We want to do EXPECT_FALSE(ec) but that fails on some Windows bots, | 748 | std::error_code ec = |
| 746 | // probably due to /tmp not being available. | 749 | llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl); |
| 747 | // For now just consume the error without checking it. | 750 | EXPECT_FALSE(ec); |
| 748 | consumeError(std::move(ec)); | 751 | llvm::Error ec2 = writeBinary(*f, tmpFl); |
| 752 | EXPECT_FALSE(ec2); | ||
| 753 | llvm::sys::fs::remove(tmpFl); | ||
| 749 | } | 754 | } |
deps/lld/wasm/CMakeLists.txt+14-2| ... | @@ -2,10 +2,16 @@ set(LLVM_TARGET_DEFINITIONS Options.td) | ... | @@ -2,10 +2,16 @@ set(LLVM_TARGET_DEFINITIONS Options.td) |
| 2 | tablegen(LLVM Options.inc -gen-opt-parser-defs) | 2 | tablegen(LLVM Options.inc -gen-opt-parser-defs) |
| 3 | add_public_tablegen_target(WasmOptionsTableGen) | 3 | add_public_tablegen_target(WasmOptionsTableGen) |
| 4 | 4 | ||
| 5 | if(NOT LLD_BUILT_STANDALONE) | ||
| 6 | set(tablegen_deps intrinsics_gen) | ||
| 7 | endif() | ||
| 8 | |||
| 5 | add_lld_library(lldWasm | 9 | add_lld_library(lldWasm |
| 6 | Driver.cpp | 10 | Driver.cpp |
| 11 | InputChunks.cpp | ||
| 7 | InputFiles.cpp | 12 | InputFiles.cpp |
| 8 | InputSegment.cpp | 13 | LTO.cpp |
| 14 | MarkLive.cpp | ||
| 9 | OutputSections.cpp | 15 | OutputSections.cpp |
| 10 | SymbolTable.cpp | 16 | SymbolTable.cpp |
| 11 | Symbols.cpp | 17 | Symbols.cpp |
| ... | @@ -17,10 +23,16 @@ add_lld_library(lldWasm | ... | @@ -17,10 +23,16 @@ add_lld_library(lldWasm |
| 17 | BinaryFormat | 23 | BinaryFormat |
| 18 | Core | 24 | Core |
| 19 | Demangle | 25 | Demangle |
| 26 | LTO | ||
| 27 | MC | ||
| 20 | Object | 28 | Object |
| 21 | Option | 29 | Option |
| 22 | Support | 30 | Support |
| 23 | 31 | ||
| 24 | LINK_LIBS | 32 | LINK_LIBS |
| 25 | lldCommon | 33 | lldCommon |
| 26 | ) | 34 | |
| 35 | DEPENDS | ||
| 36 | WasmOptionsTableGen | ||
| 37 | ${tablegen_deps} | ||
| 38 | ) | ||
| \ No newline at end of file | |||
deps/lld/wasm/Config.h+17-7| ... | @@ -13,33 +13,43 @@ | ... | @@ -13,33 +13,43 @@ |
| 13 | #include "llvm/ADT/StringRef.h" | 13 | #include "llvm/ADT/StringRef.h" |
| 14 | #include "llvm/ADT/StringSet.h" | 14 | #include "llvm/ADT/StringSet.h" |
| 15 | #include "llvm/BinaryFormat/Wasm.h" | 15 | #include "llvm/BinaryFormat/Wasm.h" |
| 16 | 16 | #include "llvm/Support/CachePruning.h" | |
| 17 | #include "Symbols.h" | ||
| 18 | |||
| 19 | using llvm::wasm::WasmGlobal; | ||
| 20 | 17 | ||
| 21 | namespace lld { | 18 | namespace lld { |
| 22 | namespace wasm { | 19 | namespace wasm { |
| 23 | 20 | ||
| 24 | struct Configuration { | 21 | struct Configuration { |
| 25 | bool AllowUndefined; | 22 | bool AllowUndefined; |
| 26 | bool CheckSignatures; | 23 | bool CompressRelocTargets; |
| 27 | bool Demangle; | 24 | bool Demangle; |
| 28 | bool EmitRelocs; | 25 | bool DisableVerify; |
| 26 | bool ExportAll; | ||
| 27 | bool ExportTable; | ||
| 28 | bool GcSections; | ||
| 29 | bool ImportMemory; | 29 | bool ImportMemory; |
| 30 | bool ImportTable; | ||
| 31 | bool MergeDataSegments; | ||
| 32 | bool PrintGcSections; | ||
| 30 | bool Relocatable; | 33 | bool Relocatable; |
| 34 | bool SaveTemps; | ||
| 31 | bool StripAll; | 35 | bool StripAll; |
| 32 | bool StripDebug; | 36 | bool StripDebug; |
| 37 | bool StackFirst; | ||
| 33 | uint32_t GlobalBase; | 38 | uint32_t GlobalBase; |
| 34 | uint32_t InitialMemory; | 39 | uint32_t InitialMemory; |
| 35 | uint32_t MaxMemory; | 40 | uint32_t MaxMemory; |
| 36 | uint32_t ZStackSize; | 41 | uint32_t ZStackSize; |
| 42 | unsigned LTOPartitions; | ||
| 43 | unsigned LTOO; | ||
| 44 | unsigned Optimize; | ||
| 45 | unsigned ThinLTOJobs; | ||
| 37 | llvm::StringRef Entry; | 46 | llvm::StringRef Entry; |
| 38 | llvm::StringRef OutputFile; | 47 | llvm::StringRef OutputFile; |
| 48 | llvm::StringRef ThinLTOCacheDir; | ||
| 39 | 49 | ||
| 40 | llvm::StringSet<> AllowUndefinedSymbols; | 50 | llvm::StringSet<> AllowUndefinedSymbols; |
| 41 | std::vector<llvm::StringRef> SearchPaths; | 51 | std::vector<llvm::StringRef> SearchPaths; |
| 42 | Symbol *StackPointerSymbol = nullptr; | 52 | llvm::CachePruningPolicy ThinLTOCachePolicy; |
| 43 | }; | 53 | }; |
| 44 | 54 | ||
| 45 | // The only instance of Configuration struct. | 55 | // The only instance of Configuration struct. |
deps/lld/wasm/Driver.cpp+296-78| ... | @@ -9,11 +9,15 @@ | ... | @@ -9,11 +9,15 @@ |
| 9 | 9 | ||
| 10 | #include "lld/Common/Driver.h" | 10 | #include "lld/Common/Driver.h" |
| 11 | #include "Config.h" | 11 | #include "Config.h" |
| 12 | #include "InputChunks.h" | ||
| 13 | #include "InputGlobal.h" | ||
| 14 | #include "MarkLive.h" | ||
| 12 | #include "SymbolTable.h" | 15 | #include "SymbolTable.h" |
| 13 | #include "Writer.h" | 16 | #include "Writer.h" |
| 14 | #include "lld/Common/Args.h" | 17 | #include "lld/Common/Args.h" |
| 15 | #include "lld/Common/ErrorHandler.h" | 18 | #include "lld/Common/ErrorHandler.h" |
| 16 | #include "lld/Common/Memory.h" | 19 | #include "lld/Common/Memory.h" |
| 20 | #include "lld/Common/Strings.h" | ||
| 17 | #include "lld/Common/Threads.h" | 21 | #include "lld/Common/Threads.h" |
| 18 | #include "lld/Common/Version.h" | 22 | #include "lld/Common/Version.h" |
| 19 | #include "llvm/ADT/Twine.h" | 23 | #include "llvm/ADT/Twine.h" |
| ... | @@ -22,6 +26,9 @@ | ... | @@ -22,6 +26,9 @@ |
| 22 | #include "llvm/Support/CommandLine.h" | 26 | #include "llvm/Support/CommandLine.h" |
| 23 | #include "llvm/Support/Path.h" | 27 | #include "llvm/Support/Path.h" |
| 24 | #include "llvm/Support/Process.h" | 28 | #include "llvm/Support/Process.h" |
| 29 | #include "llvm/Support/TargetSelect.h" | ||
| 30 | |||
| 31 | #define DEBUG_TYPE "lld" | ||
| 25 | 32 | ||
| 26 | using namespace llvm; | 33 | using namespace llvm; |
| 27 | using namespace llvm::sys; | 34 | using namespace llvm::sys; |
| ... | @@ -30,14 +37,9 @@ using namespace llvm::wasm; | ... | @@ -30,14 +37,9 @@ using namespace llvm::wasm; |
| 30 | using namespace lld; | 37 | using namespace lld; |
| 31 | using namespace lld::wasm; | 38 | using namespace lld::wasm; |
| 32 | 39 | ||
| 33 | namespace { | 40 | Configuration *lld::wasm::Config; |
| 34 | 41 | ||
| 35 | // Parses command line options. | 42 | namespace { |
| 36 | class WasmOptTable : public llvm::opt::OptTable { | ||
| 37 | public: | ||
| 38 | WasmOptTable(); | ||
| 39 | llvm::opt::InputArgList parse(ArrayRef<const char *> Argv); | ||
| 40 | }; | ||
| 41 | 43 | ||
| 42 | // Create enum with OPT_xxx values for each option in Options.td | 44 | // Create enum with OPT_xxx values for each option in Options.td |
| 43 | enum { | 45 | enum { |
| ... | @@ -47,24 +49,36 @@ enum { | ... | @@ -47,24 +49,36 @@ enum { |
| 47 | #undef OPTION | 49 | #undef OPTION |
| 48 | }; | 50 | }; |
| 49 | 51 | ||
| 52 | // This function is called on startup. We need this for LTO since | ||
| 53 | // LTO calls LLVM functions to compile bitcode files to native code. | ||
| 54 | // Technically this can be delayed until we read bitcode files, but | ||
| 55 | // we don't bother to do lazily because the initialization is fast. | ||
| 56 | static void initLLVM() { | ||
| 57 | InitializeAllTargets(); | ||
| 58 | InitializeAllTargetMCs(); | ||
| 59 | InitializeAllAsmPrinters(); | ||
| 60 | InitializeAllAsmParsers(); | ||
| 61 | } | ||
| 62 | |||
| 50 | class LinkerDriver { | 63 | class LinkerDriver { |
| 51 | public: | 64 | public: |
| 52 | void link(ArrayRef<const char *> ArgsArr); | 65 | void link(ArrayRef<const char *> ArgsArr); |
| 53 | 66 | ||
| 54 | private: | 67 | private: |
| 55 | void createFiles(llvm::opt::InputArgList &Args); | 68 | void createFiles(opt::InputArgList &Args); |
| 56 | void addFile(StringRef Path); | 69 | void addFile(StringRef Path); |
| 57 | void addLibrary(StringRef Name); | 70 | void addLibrary(StringRef Name); |
| 71 | |||
| 72 | // True if we are in --whole-archive and --no-whole-archive. | ||
| 73 | bool InWholeArchive = false; | ||
| 74 | |||
| 58 | std::vector<InputFile *> Files; | 75 | std::vector<InputFile *> Files; |
| 59 | }; | 76 | }; |
| 60 | |||
| 61 | } // anonymous namespace | 77 | } // anonymous namespace |
| 62 | 78 | ||
| 63 | Configuration *lld::wasm::Config; | ||
| 64 | |||
| 65 | bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, | 79 | bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, |
| 66 | raw_ostream &Error) { | 80 | raw_ostream &Error) { |
| 67 | errorHandler().LogName = Args[0]; | 81 | errorHandler().LogName = sys::path::filename(Args[0]); |
| 68 | errorHandler().ErrorOS = &Error; | 82 | errorHandler().ErrorOS = &Error; |
| 69 | errorHandler().ColorDiagnostics = Error.has_colors(); | 83 | errorHandler().ColorDiagnostics = Error.has_colors(); |
| 70 | errorHandler().ErrorLimitExceededMsg = | 84 | errorHandler().ErrorLimitExceededMsg = |
| ... | @@ -74,6 +88,7 @@ bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, | ... | @@ -74,6 +88,7 @@ bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, |
| 74 | Config = make<Configuration>(); | 88 | Config = make<Configuration>(); |
| 75 | Symtab = make<SymbolTable>(); | 89 | Symtab = make<SymbolTable>(); |
| 76 | 90 | ||
| 91 | initLLVM(); | ||
| 77 | LinkerDriver().link(Args); | 92 | LinkerDriver().link(Args); |
| 78 | 93 | ||
| 79 | // Exit immediately if we don't need to return to the caller. | 94 | // Exit immediately if we don't need to return to the caller. |
| ... | @@ -86,8 +101,6 @@ bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, | ... | @@ -86,8 +101,6 @@ bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, |
| 86 | return !errorCount(); | 101 | return !errorCount(); |
| 87 | } | 102 | } |
| 88 | 103 | ||
| 89 | // Create OptTable | ||
| 90 | |||
| 91 | // Create prefix string literals used in Options.td | 104 | // Create prefix string literals used in Options.td |
| 92 | #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; | 105 | #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; |
| 93 | #include "Options.inc" | 106 | #include "Options.inc" |
| ... | @@ -102,6 +115,14 @@ static const opt::OptTable::Info OptInfo[] = { | ... | @@ -102,6 +115,14 @@ static const opt::OptTable::Info OptInfo[] = { |
| 102 | #undef OPTION | 115 | #undef OPTION |
| 103 | }; | 116 | }; |
| 104 | 117 | ||
| 118 | namespace { | ||
| 119 | class WasmOptTable : public llvm::opt::OptTable { | ||
| 120 | public: | ||
| 121 | WasmOptTable() : OptTable(OptInfo) {} | ||
| 122 | opt::InputArgList parse(ArrayRef<const char *> Argv); | ||
| 123 | }; | ||
| 124 | } // namespace | ||
| 125 | |||
| 105 | // Set color diagnostics according to -color-diagnostics={auto,always,never} | 126 | // Set color diagnostics according to -color-diagnostics={auto,always,never} |
| 106 | // or -no-color-diagnostics flags. | 127 | // or -no-color-diagnostics flags. |
| 107 | static void handleColorDiagnostics(opt::InputArgList &Args) { | 128 | static void handleColorDiagnostics(opt::InputArgList &Args) { |
| ... | @@ -109,19 +130,18 @@ static void handleColorDiagnostics(opt::InputArgList &Args) { | ... | @@ -109,19 +130,18 @@ static void handleColorDiagnostics(opt::InputArgList &Args) { |
| 109 | OPT_no_color_diagnostics); | 130 | OPT_no_color_diagnostics); |
| 110 | if (!Arg) | 131 | if (!Arg) |
| 111 | return; | 132 | return; |
| 112 | 133 | if (Arg->getOption().getID() == OPT_color_diagnostics) { | |
| 113 | if (Arg->getOption().getID() == OPT_color_diagnostics) | ||
| 114 | errorHandler().ColorDiagnostics = true; | 134 | errorHandler().ColorDiagnostics = true; |
| 115 | else if (Arg->getOption().getID() == OPT_no_color_diagnostics) | 135 | } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) { |
| 116 | errorHandler().ColorDiagnostics = false; | 136 | errorHandler().ColorDiagnostics = false; |
| 117 | else { | 137 | } else { |
| 118 | StringRef S = Arg->getValue(); | 138 | StringRef S = Arg->getValue(); |
| 119 | if (S == "always") | 139 | if (S == "always") |
| 120 | errorHandler().ColorDiagnostics = true; | 140 | errorHandler().ColorDiagnostics = true; |
| 121 | if (S == "never") | 141 | else if (S == "never") |
| 122 | errorHandler().ColorDiagnostics = false; | 142 | errorHandler().ColorDiagnostics = false; |
| 123 | if (S != "auto") | 143 | else if (S != "auto") |
| 124 | error("unknown option: -color-diagnostics=" + S); | 144 | error("unknown option: --color-diagnostics=" + S); |
| 125 | } | 145 | } |
| 126 | } | 146 | } |
| 127 | 147 | ||
| ... | @@ -134,25 +154,15 @@ static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) { | ... | @@ -134,25 +154,15 @@ static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) { |
| 134 | return None; | 154 | return None; |
| 135 | } | 155 | } |
| 136 | 156 | ||
| 137 | // Inject a new undefined symbol into the link. This will cause the link to | ||
| 138 | // fail unless this symbol can be found. | ||
| 139 | static void addSyntheticUndefinedFunction(StringRef Name, | ||
| 140 | const WasmSignature *Type) { | ||
| 141 | log("injecting undefined func: " + Name); | ||
| 142 | Symtab->addUndefinedFunction(Name, Type); | ||
| 143 | } | ||
| 144 | |||
| 145 | static void printHelp(const char *Argv0) { | ||
| 146 | WasmOptTable().PrintHelp(outs(), Argv0, "LLVM Linker", false); | ||
| 147 | } | ||
| 148 | |||
| 149 | WasmOptTable::WasmOptTable() : OptTable(OptInfo) {} | ||
| 150 | |||
| 151 | opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) { | 157 | opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) { |
| 152 | SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); | 158 | SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); |
| 153 | 159 | ||
| 154 | unsigned MissingIndex; | 160 | unsigned MissingIndex; |
| 155 | unsigned MissingCount; | 161 | unsigned MissingCount; |
| 162 | |||
| 163 | // Expand response files (arguments in the form of @<filename>) | ||
| 164 | cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Vec); | ||
| 165 | |||
| 156 | opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); | 166 | opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); |
| 157 | 167 | ||
| 158 | handleColorDiagnostics(Args); | 168 | handleColorDiagnostics(Args); |
| ... | @@ -161,16 +171,80 @@ opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) { | ... | @@ -161,16 +171,80 @@ opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) { |
| 161 | return Args; | 171 | return Args; |
| 162 | } | 172 | } |
| 163 | 173 | ||
| 174 | // Currently we allow a ".imports" to live alongside a library. This can | ||
| 175 | // be used to specify a list of symbols which can be undefined at link | ||
| 176 | // time (imported from the environment. For example libc.a include an | ||
| 177 | // import file that lists the syscall functions it relies on at runtime. | ||
| 178 | // In the long run this information would be better stored as a symbol | ||
| 179 | // attribute/flag in the object file itself. | ||
| 180 | // See: https://github.com/WebAssembly/tool-conventions/issues/35 | ||
| 181 | static void readImportFile(StringRef Filename) { | ||
| 182 | if (Optional<MemoryBufferRef> Buf = readFile(Filename)) | ||
| 183 | for (StringRef Sym : args::getLines(*Buf)) | ||
| 184 | Config->AllowUndefinedSymbols.insert(Sym); | ||
| 185 | } | ||
| 186 | |||
| 187 | // Returns slices of MB by parsing MB as an archive file. | ||
| 188 | // Each slice consists of a member file in the archive. | ||
| 189 | std::vector<MemoryBufferRef> static getArchiveMembers( | ||
| 190 | 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() + | ||
| 200 | ": could not get the child of the archive"); | ||
| 201 | MemoryBufferRef MBRef = | ||
| 202 | CHECK(C.getMemoryBufferRef(), | ||
| 203 | MB.getBufferIdentifier() + | ||
| 204 | ": could not get the buffer for a child of the archive"); | ||
| 205 | V.push_back(MBRef); | ||
| 206 | } | ||
| 207 | if (Err) | ||
| 208 | fatal(MB.getBufferIdentifier() + ": Archive::children failed: " + | ||
| 209 | toString(std::move(Err))); | ||
| 210 | |||
| 211 | // 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 | |||
| 215 | return V; | ||
| 216 | } | ||
| 217 | |||
| 164 | void LinkerDriver::addFile(StringRef Path) { | 218 | void LinkerDriver::addFile(StringRef Path) { |
| 165 | Optional<MemoryBufferRef> Buffer = readFile(Path); | 219 | Optional<MemoryBufferRef> Buffer = readFile(Path); |
| 166 | if (!Buffer.hasValue()) | 220 | if (!Buffer.hasValue()) |
| 167 | return; | 221 | return; |
| 168 | MemoryBufferRef MBRef = *Buffer; | 222 | MemoryBufferRef MBRef = *Buffer; |
| 169 | 223 | ||
| 170 | if (identify_magic(MBRef.getBuffer()) == file_magic::archive) | 224 | switch (identify_magic(MBRef.getBuffer())) { |
| 225 | case file_magic::archive: { | ||
| 226 | // Handle -whole-archive. | ||
| 227 | if (InWholeArchive) { | ||
| 228 | for (MemoryBufferRef &M : getArchiveMembers(MBRef)) | ||
| 229 | Files.push_back(createObjectFile(M)); | ||
| 230 | return; | ||
| 231 | } | ||
| 232 | |||
| 233 | SmallString<128> ImportFile = Path; | ||
| 234 | path::replace_extension(ImportFile, ".imports"); | ||
| 235 | if (fs::exists(ImportFile)) | ||
| 236 | readImportFile(ImportFile.str()); | ||
| 237 | |||
| 171 | Files.push_back(make<ArchiveFile>(MBRef)); | 238 | Files.push_back(make<ArchiveFile>(MBRef)); |
| 172 | else | 239 | return; |
| 173 | Files.push_back(make<ObjFile>(MBRef)); | 240 | } |
| 241 | case file_magic::bitcode: | ||
| 242 | case file_magic::wasm_object: | ||
| 243 | Files.push_back(createObjectFile(MBRef)); | ||
| 244 | break; | ||
| 245 | default: | ||
| 246 | error("unknown file type: " + MBRef.getBufferIdentifier()); | ||
| 247 | } | ||
| 174 | } | 248 | } |
| 175 | 249 | ||
| 176 | // Add a given library by searching it from input search paths. | 250 | // Add a given library by searching it from input search paths. |
| ... | @@ -194,11 +268,14 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) { | ... | @@ -194,11 +268,14 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) { |
| 194 | case OPT_INPUT: | 268 | case OPT_INPUT: |
| 195 | addFile(Arg->getValue()); | 269 | addFile(Arg->getValue()); |
| 196 | break; | 270 | break; |
| 271 | case OPT_whole_archive: | ||
| 272 | InWholeArchive = true; | ||
| 273 | break; | ||
| 274 | case OPT_no_whole_archive: | ||
| 275 | InWholeArchive = false; | ||
| 276 | break; | ||
| 197 | } | 277 | } |
| 198 | } | 278 | } |
| 199 | |||
| 200 | if (Files.empty()) | ||
| 201 | error("no input files"); | ||
| 202 | } | 279 | } |
| 203 | 280 | ||
| 204 | static StringRef getEntry(opt::InputArgList &Args, StringRef Default) { | 281 | static StringRef getEntry(opt::InputArgList &Args, StringRef Default) { |
| ... | @@ -210,13 +287,71 @@ static StringRef getEntry(opt::InputArgList &Args, StringRef Default) { | ... | @@ -210,13 +287,71 @@ static StringRef getEntry(opt::InputArgList &Args, StringRef Default) { |
| 210 | return Arg->getValue(); | 287 | return Arg->getValue(); |
| 211 | } | 288 | } |
| 212 | 289 | ||
| 290 | static 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. | ||
| 299 | static 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->FunctionType); | ||
| 310 | const WasmSignature &Sig = *FuncSym->FunctionType; | ||
| 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 | Optional<std::string> SymName = demangleItanium(Sym->getName()); | ||
| 315 | StringRef DebugName = | ||
| 316 | Saver.save("undefined function " + | ||
| 317 | (SymName ? StringRef(*SymName) : Sym->getName())); | ||
| 318 | SyntheticFunction *Func = | ||
| 319 | make<SyntheticFunction>(Sig, Sym->getName(), DebugName); | ||
| 320 | Func->setBody(UnreachableFn); | ||
| 321 | // Ensure it compares equal to the null pointer, and so that table relocs | ||
| 322 | // don't pull in the stub body (only call-operand relocs should do that). | ||
| 323 | Func->setTableIndex(0); | ||
| 324 | Symtab->SyntheticFunctions.emplace_back(Func); | ||
| 325 | // Hide our dummy to prevent export. | ||
| 326 | uint32_t Flags = WASM_SYMBOL_VISIBILITY_HIDDEN; | ||
| 327 | replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Flags, nullptr, Func); | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 331 | // Force Sym to be entered in the output. Used for -u or equivalent. | ||
| 332 | static Symbol *addUndefined(StringRef Name) { | ||
| 333 | Symbol *S = Symtab->addUndefinedFunction(Name, 0, nullptr, nullptr); | ||
| 334 | |||
| 335 | // Since symbol S may not be used inside the program, LTO may | ||
| 336 | // eliminate it. Mark the symbol as "used" to prevent it. | ||
| 337 | S->IsUsedInRegularObj = true; | ||
| 338 | |||
| 339 | return S; | ||
| 340 | } | ||
| 341 | |||
| 213 | void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | 342 | void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 214 | WasmOptTable Parser; | 343 | WasmOptTable Parser; |
| 215 | opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); | 344 | opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); |
| 216 | 345 | ||
| 217 | // Handle --help | 346 | // Handle --help |
| 218 | if (Args.hasArg(OPT_help)) { | 347 | if (Args.hasArg(OPT_help)) { |
| 219 | printHelp(ArgsArr[0]); | 348 | Parser.PrintHelp(outs(), ArgsArr[0], "LLVM Linker", false); |
| 349 | return; | ||
| 350 | } | ||
| 351 | |||
| 352 | // Handle --version | ||
| 353 | if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) { | ||
| 354 | outs() << getLLDVersion() << "\n"; | ||
| 220 | return; | 355 | return; |
| 221 | } | 356 | } |
| 222 | 357 | ||
| ... | @@ -229,26 +364,40 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -229,26 +364,40 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 229 | 364 | ||
| 230 | errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20); | 365 | errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20); |
| 231 | 366 | ||
| 232 | if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) { | ||
| 233 | outs() << getLLDVersion() << "\n"; | ||
| 234 | return; | ||
| 235 | } | ||
| 236 | |||
| 237 | Config->AllowUndefined = Args.hasArg(OPT_allow_undefined); | 367 | Config->AllowUndefined = Args.hasArg(OPT_allow_undefined); |
| 238 | Config->CheckSignatures = | 368 | Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true); |
| 239 | Args.hasFlag(OPT_check_signatures, OPT_no_check_signatures, false); | 369 | Config->DisableVerify = Args.hasArg(OPT_disable_verify); |
| 240 | Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); | ||
| 241 | Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start"); | 370 | Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start"); |
| 371 | Config->ExportAll = Args.hasArg(OPT_export_all); | ||
| 372 | Config->ExportTable = Args.hasArg(OPT_export_table); | ||
| 373 | errorHandler().FatalWarnings = | ||
| 374 | Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); | ||
| 242 | Config->ImportMemory = Args.hasArg(OPT_import_memory); | 375 | Config->ImportMemory = Args.hasArg(OPT_import_memory); |
| 376 | Config->ImportTable = Args.hasArg(OPT_import_table); | ||
| 377 | Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); | ||
| 378 | Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1); | ||
| 379 | Config->Optimize = args::getInteger(Args, OPT_O, 0); | ||
| 243 | Config->OutputFile = Args.getLastArgValue(OPT_o); | 380 | Config->OutputFile = Args.getLastArgValue(OPT_o); |
| 244 | Config->Relocatable = Args.hasArg(OPT_relocatable); | 381 | Config->Relocatable = Args.hasArg(OPT_relocatable); |
| 382 | Config->GcSections = | ||
| 383 | Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable); | ||
| 384 | Config->MergeDataSegments = | ||
| 385 | Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments, | ||
| 386 | !Config->Relocatable); | ||
| 387 | Config->PrintGcSections = | ||
| 388 | Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); | ||
| 389 | Config->SaveTemps = Args.hasArg(OPT_save_temps); | ||
| 245 | Config->SearchPaths = args::getStrings(Args, OPT_L); | 390 | Config->SearchPaths = args::getStrings(Args, OPT_L); |
| 246 | Config->StripAll = Args.hasArg(OPT_strip_all); | 391 | Config->StripAll = Args.hasArg(OPT_strip_all); |
| 247 | Config->StripDebug = Args.hasArg(OPT_strip_debug); | 392 | Config->StripDebug = Args.hasArg(OPT_strip_debug); |
| 393 | Config->StackFirst = Args.hasArg(OPT_stack_first); | ||
| 394 | Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir); | ||
| 395 | Config->ThinLTOCachePolicy = CHECK( | ||
| 396 | parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)), | ||
| 397 | "--thinlto-cache-policy: invalid cache policy"); | ||
| 398 | Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u); | ||
| 248 | errorHandler().Verbose = Args.hasArg(OPT_verbose); | 399 | errorHandler().Verbose = Args.hasArg(OPT_verbose); |
| 249 | ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); | 400 | ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); |
| 250 | if (Config->Relocatable) | ||
| 251 | Config->EmitRelocs = true; | ||
| 252 | 401 | ||
| 253 | Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0); | 402 | Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0); |
| 254 | Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024); | 403 | Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024); |
| ... | @@ -256,33 +405,72 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -256,33 +405,72 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 256 | Config->ZStackSize = | 405 | Config->ZStackSize = |
| 257 | args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize); | 406 | args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize); |
| 258 | 407 | ||
| 408 | Config->CompressRelocTargets = Config->Optimize > 0 && !Config->Relocatable; | ||
| 409 | |||
| 410 | if (Config->LTOO > 3) | ||
| 411 | error("invalid optimization level for LTO: " + Twine(Config->LTOO)); | ||
| 412 | if (Config->LTOPartitions == 0) | ||
| 413 | error("--lto-partitions: number of threads must be > 0"); | ||
| 414 | if (Config->ThinLTOJobs == 0) | ||
| 415 | error("--thinlto-jobs: number of threads must be > 0"); | ||
| 416 | |||
| 259 | if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file)) | 417 | if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file)) |
| 260 | if (Optional<MemoryBufferRef> Buf = readFile(Arg->getValue())) | 418 | readImportFile(Arg->getValue()); |
| 261 | for (StringRef Sym : args::getLines(*Buf)) | 419 | |
| 262 | Config->AllowUndefinedSymbols.insert(Sym); | 420 | if (!Args.hasArg(OPT_INPUT)) { |
| 421 | error("no input files"); | ||
| 422 | return; | ||
| 423 | } | ||
| 263 | 424 | ||
| 264 | if (Config->OutputFile.empty()) | 425 | if (Config->OutputFile.empty()) |
| 265 | error("no output file specified"); | 426 | error("no output file specified"); |
| 266 | 427 | ||
| 267 | if (!Args.hasArg(OPT_INPUT)) | 428 | if (Config->ImportTable && Config->ExportTable) |
| 268 | error("no input files"); | 429 | error("--import-table and --export-table may not be used together"); |
| 269 | 430 | ||
| 270 | if (Config->Relocatable && !Config->Entry.empty()) | 431 | if (Config->Relocatable) { |
| 271 | error("entry point specified for relocatable output file"); | 432 | if (!Config->Entry.empty()) |
| 272 | if (Config->Relocatable && Args.hasArg(OPT_undefined)) | 433 | error("entry point specified for relocatable output file"); |
| 273 | error("undefined symbols specified for relocatable output file"); | 434 | if (Config->GcSections) |
| 435 | error("-r and --gc-sections may not be used together"); | ||
| 436 | if (Args.hasArg(OPT_undefined)) | ||
| 437 | error("-r -and --undefined may not be used together"); | ||
| 438 | } | ||
| 274 | 439 | ||
| 440 | Symbol *EntrySym = nullptr; | ||
| 275 | if (!Config->Relocatable) { | 441 | if (!Config->Relocatable) { |
| 276 | if (!Config->Entry.empty()) { | 442 | llvm::wasm::WasmGlobal Global; |
| 277 | static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; | 443 | Global.Type = {WASM_TYPE_I32, true}; |
| 278 | addSyntheticUndefinedFunction(Config->Entry, &Signature); | 444 | Global.InitExpr.Value.Int32 = 0; |
| 279 | } | 445 | Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; |
| 446 | Global.SymbolName = "__stack_pointer"; | ||
| 447 | InputGlobal *StackPointer = make<InputGlobal>(Global, nullptr); | ||
| 448 | StackPointer->Live = true; | ||
| 449 | |||
| 450 | static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT}; | ||
| 451 | |||
| 452 | // Add synthetic symbols before any others | ||
| 453 | WasmSym::CallCtors = Symtab->addSyntheticFunction( | ||
| 454 | "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN, | ||
| 455 | make<SyntheticFunction>(NullSignature, "__wasm_call_ctors")); | ||
| 456 | // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global | ||
| 457 | // spec proposal is implemented in all major browsers. | ||
| 458 | // See: https://github.com/WebAssembly/mutable-global | ||
| 459 | WasmSym::StackPointer = Symtab->addSyntheticGlobal( | ||
| 460 | "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer); | ||
| 461 | WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0); | ||
| 462 | WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol( | ||
| 463 | "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN); | ||
| 464 | WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0); | ||
| 465 | |||
| 466 | // For now, since we don't actually use the start function as the | ||
| 467 | // wasm start symbol, we don't need to care about it signature. | ||
| 468 | if (!Config->Entry.empty()) | ||
| 469 | EntrySym = addUndefined(Config->Entry); | ||
| 280 | 470 | ||
| 281 | // Handle the `--undefined <sym>` options. | 471 | // Handle the `--undefined <sym>` options. |
| 282 | for (StringRef S : args::getStrings(Args, OPT_undefined)) | 472 | for (auto *Arg : Args.filtered(OPT_undefined)) |
| 283 | addSyntheticUndefinedFunction(S, nullptr); | 473 | addUndefined(Arg->getValue()); |
| 284 | |||
| 285 | Config->StackPointerSymbol = Symtab->addDefinedGlobal("__stack_pointer"); | ||
| 286 | } | 474 | } |
| 287 | 475 | ||
| 288 | createFiles(Args); | 476 | createFiles(Args); |
| ... | @@ -293,29 +481,59 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { | ... | @@ -293,29 +481,59 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { |
| 293 | // symbols that we need to the symbol table. | 481 | // symbols that we need to the symbol table. |
| 294 | for (InputFile *F : Files) | 482 | for (InputFile *F : Files) |
| 295 | Symtab->addFile(F); | 483 | Symtab->addFile(F); |
| 484 | if (errorCount()) | ||
| 485 | return; | ||
| 486 | |||
| 487 | // Add synthetic dummies for weak undefined functions. | ||
| 488 | if (!Config->Relocatable) | ||
| 489 | handleWeakUndefines(); | ||
| 490 | |||
| 491 | // Handle --export. | ||
| 492 | for (auto *Arg : Args.filtered(OPT_export)) { | ||
| 493 | StringRef Name = Arg->getValue(); | ||
| 494 | Symbol *Sym = Symtab->find(Name); | ||
| 495 | if (Sym && Sym->isDefined()) | ||
| 496 | Sym->ForceExport = true; | ||
| 497 | else if (!Config->AllowUndefined) | ||
| 498 | error("symbol exported via --export not found: " + Name); | ||
| 499 | } | ||
| 500 | |||
| 501 | // Do link-time optimization if given files are LLVM bitcode files. | ||
| 502 | // This compiles bitcode files into real object files. | ||
| 503 | Symtab->addCombinedLTOObject(); | ||
| 504 | if (errorCount()) | ||
| 505 | return; | ||
| 296 | 506 | ||
| 297 | // Make sure we have resolved all symbols. | 507 | // Make sure we have resolved all symbols. |
| 298 | if (!Config->Relocatable && !Config->AllowUndefined) { | 508 | if (!Config->Relocatable && !Config->AllowUndefined) { |
| 299 | Symtab->reportRemainingUndefines(); | 509 | Symtab->reportRemainingUndefines(); |
| 300 | } else { | 510 | } else { |
| 301 | // When we allow undefined symbols we cannot include those defined in | 511 | // Even when using --allow-undefined we still want to report the absence of |
| 302 | // -u/--undefined since these undefined symbols have only names and no | 512 | // our initial set of undefined symbols (i.e. the entry point and symbols |
| 303 | // function signature, which means they cannot be written to the final | 513 | // specified via --undefined). |
| 304 | // output. | 514 | // Part of the reason for this is that these function don't have signatures |
| 305 | for (StringRef S : args::getStrings(Args, OPT_undefined)) { | 515 | // so which means they cannot be written as wasm function imports. |
| 306 | Symbol *Sym = Symtab->find(S); | 516 | for (auto *Arg : Args.filtered(OPT_undefined)) { |
| 517 | Symbol *Sym = Symtab->find(Arg->getValue()); | ||
| 307 | if (!Sym->isDefined()) | 518 | if (!Sym->isDefined()) |
| 308 | error("function forced with --undefined not found: " + Sym->getName()); | 519 | error("symbol forced with --undefined not found: " + Sym->getName()); |
| 309 | } | 520 | } |
| 521 | if (EntrySym && !EntrySym->isDefined()) | ||
| 522 | error("entry symbol not defined (pass --no-entry to supress): " + | ||
| 523 | EntrySym->getName()); | ||
| 310 | } | 524 | } |
| 311 | if (errorCount()) | 525 | if (errorCount()) |
| 312 | return; | 526 | return; |
| 313 | 527 | ||
| 314 | if (!Config->Entry.empty() && !Symtab->find(Config->Entry)->isDefined()) | 528 | if (EntrySym) |
| 315 | error("entry point not found: " + Config->Entry); | 529 | EntrySym->setHidden(false); |
| 530 | |||
| 316 | if (errorCount()) | 531 | if (errorCount()) |
| 317 | return; | 532 | return; |
| 318 | 533 | ||
| 534 | // Do size optimizations: garbage collection | ||
| 535 | markLive(); | ||
| 536 | |||
| 319 | // Write the result to the file. | 537 | // Write the result to the file. |
| 320 | writeResult(); | 538 | writeResult(); |
| 321 | } | 539 | } |
deps/lld/wasm/InputChunks.cpp created+295| ... | @@ -0,0 +1,295 @@ | ||
| 1 | //===- InputChunks.cpp ----------------------------------------------------===// | ||
| 2 | // | ||
| 3 | // The LLVM Linker | ||
| 4 | // | ||
| 5 | // This file is distributed under the University of Illinois Open Source | ||
| 6 | // License. See LICENSE.TXT for details. | ||
| 7 | // | ||
| 8 | //===----------------------------------------------------------------------===// | ||
| 9 | |||
| 10 | #include "InputChunks.h" | ||
| 11 | #include "Config.h" | ||
| 12 | #include "OutputSegment.h" | ||
| 13 | #include "WriterUtils.h" | ||
| 14 | #include "lld/Common/ErrorHandler.h" | ||
| 15 | #include "lld/Common/LLVM.h" | ||
| 16 | #include "llvm/Support/LEB128.h" | ||
| 17 | |||
| 18 | #define DEBUG_TYPE "lld" | ||
| 19 | |||
| 20 | using namespace llvm; | ||
| 21 | using namespace llvm::wasm; | ||
| 22 | using namespace llvm::support::endian; | ||
| 23 | using namespace lld; | ||
| 24 | using namespace lld::wasm; | ||
| 25 | |||
| 26 | static StringRef ReloctTypeToString(uint8_t RelocType) { | ||
| 27 | switch (RelocType) { | ||
| 28 | #define WASM_RELOC(NAME, REL) case REL: return #NAME; | ||
| 29 | #include "llvm/BinaryFormat/WasmRelocs.def" | ||
| 30 | #undef WASM_RELOC | ||
| 31 | } | ||
| 32 | llvm_unreachable("unknown reloc type"); | ||
| 33 | } | ||
| 34 | |||
| 35 | std::string lld::toString(const InputChunk *C) { | ||
| 36 | return (toString(C->File) + ":(" + C->getName() + ")").str(); | ||
| 37 | } | ||
| 38 | |||
| 39 | StringRef InputChunk::getComdatName() const { | ||
| 40 | uint32_t Index = getComdat(); | ||
| 41 | if (Index == UINT32_MAX) | ||
| 42 | return StringRef(); | ||
| 43 | return File->getWasmObj()->linkingData().Comdats[Index]; | ||
| 44 | } | ||
| 45 | |||
| 46 | void InputChunk::copyRelocations(const WasmSection &Section) { | ||
| 47 | if (Section.Relocations.empty()) | ||
| 48 | return; | ||
| 49 | size_t Start = getInputSectionOffset(); | ||
| 50 | size_t Size = getInputSize(); | ||
| 51 | for (const WasmRelocation &R : Section.Relocations) | ||
| 52 | if (R.Offset >= Start && R.Offset < Start + Size) | ||
| 53 | Relocations.push_back(R); | ||
| 54 | } | ||
| 55 | |||
| 56 | void InputChunk::verifyRelocTargets() const { | ||
| 57 | for (const WasmRelocation &Rel : Relocations) { | ||
| 58 | uint32_t ExistingValue; | ||
| 59 | unsigned BytesRead = 0; | ||
| 60 | uint32_t Offset = Rel.Offset - getInputSectionOffset(); | ||
| 61 | const uint8_t *Loc = data().data() + Offset; | ||
| 62 | switch (Rel.Type) { | ||
| 63 | case R_WEBASSEMBLY_TYPE_INDEX_LEB: | ||
| 64 | case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: | ||
| 65 | case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: | ||
| 66 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 67 | ExistingValue = decodeULEB128(Loc, &BytesRead); | ||
| 68 | break; | ||
| 69 | case R_WEBASSEMBLY_TABLE_INDEX_SLEB: | ||
| 70 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 71 | ExistingValue = static_cast<uint32_t>(decodeSLEB128(Loc, &BytesRead)); | ||
| 72 | break; | ||
| 73 | case R_WEBASSEMBLY_TABLE_INDEX_I32: | ||
| 74 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 75 | case R_WEBASSEMBLY_FUNCTION_OFFSET_I32: | ||
| 76 | case R_WEBASSEMBLY_SECTION_OFFSET_I32: | ||
| 77 | ExistingValue = static_cast<uint32_t>(read32le(Loc)); | ||
| 78 | break; | ||
| 79 | default: | ||
| 80 | llvm_unreachable("unknown relocation type"); | ||
| 81 | } | ||
| 82 | |||
| 83 | if (BytesRead && BytesRead != 5) | ||
| 84 | warn("expected LEB at relocation site be 5-byte padded"); | ||
| 85 | uint32_t ExpectedValue = File->calcExpectedValue(Rel); | ||
| 86 | if (ExpectedValue != ExistingValue) | ||
| 87 | warn("unexpected existing value for " + ReloctTypeToString(Rel.Type) + | ||
| 88 | ": existing=" + Twine(ExistingValue) + | ||
| 89 | " expected=" + Twine(ExpectedValue)); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | // Copy this input chunk to an mmap'ed output file and apply relocations. | ||
| 94 | void InputChunk::writeTo(uint8_t *Buf) const { | ||
| 95 | // Copy contents | ||
| 96 | memcpy(Buf + OutputOffset, data().data(), data().size()); | ||
| 97 | |||
| 98 | // Apply relocations | ||
| 99 | if (Relocations.empty()) | ||
| 100 | return; | ||
| 101 | |||
| 102 | #ifndef NDEBUG | ||
| 103 | verifyRelocTargets(); | ||
| 104 | #endif | ||
| 105 | |||
| 106 | LLVM_DEBUG(dbgs() << "applying relocations: " << getName() | ||
| 107 | << " count=" << Relocations.size() << "\n"); | ||
| 108 | int32_t Off = OutputOffset - getInputSectionOffset(); | ||
| 109 | |||
| 110 | for (const WasmRelocation &Rel : Relocations) { | ||
| 111 | uint8_t *Loc = Buf + Rel.Offset + Off; | ||
| 112 | uint32_t Value = File->calcNewValue(Rel); | ||
| 113 | LLVM_DEBUG(dbgs() << "apply reloc: type=" << ReloctTypeToString(Rel.Type) | ||
| 114 | << " addend=" << Rel.Addend << " index=" << Rel.Index | ||
| 115 | << " value=" << Value << " offset=" << Rel.Offset | ||
| 116 | << "\n"); | ||
| 117 | |||
| 118 | switch (Rel.Type) { | ||
| 119 | case R_WEBASSEMBLY_TYPE_INDEX_LEB: | ||
| 120 | case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: | ||
| 121 | case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: | ||
| 122 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 123 | encodeULEB128(Value, Loc, 5); | ||
| 124 | break; | ||
| 125 | case R_WEBASSEMBLY_TABLE_INDEX_SLEB: | ||
| 126 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 127 | encodeSLEB128(static_cast<int32_t>(Value), Loc, 5); | ||
| 128 | break; | ||
| 129 | case R_WEBASSEMBLY_TABLE_INDEX_I32: | ||
| 130 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 131 | case R_WEBASSEMBLY_FUNCTION_OFFSET_I32: | ||
| 132 | case R_WEBASSEMBLY_SECTION_OFFSET_I32: | ||
| 133 | write32le(Loc, Value); | ||
| 134 | break; | ||
| 135 | default: | ||
| 136 | llvm_unreachable("unknown relocation type"); | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | // Copy relocation entries to a given output stream. | ||
| 142 | // This function is used only when a user passes "-r". For a regular link, | ||
| 143 | // we consume relocations instead of copying them to an output file. | ||
| 144 | void InputChunk::writeRelocations(raw_ostream &OS) const { | ||
| 145 | if (Relocations.empty()) | ||
| 146 | return; | ||
| 147 | |||
| 148 | int32_t Off = OutputOffset - getInputSectionOffset(); | ||
| 149 | LLVM_DEBUG(dbgs() << "writeRelocations: " << File->getName() | ||
| 150 | << " offset=" << Twine(Off) << "\n"); | ||
| 151 | |||
| 152 | for (const WasmRelocation &Rel : Relocations) { | ||
| 153 | writeUleb128(OS, Rel.Type, "reloc type"); | ||
| 154 | writeUleb128(OS, Rel.Offset + Off, "reloc offset"); | ||
| 155 | writeUleb128(OS, File->calcNewIndex(Rel), "reloc index"); | ||
| 156 | |||
| 157 | switch (Rel.Type) { | ||
| 158 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 159 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 160 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 161 | case R_WEBASSEMBLY_FUNCTION_OFFSET_I32: | ||
| 162 | case R_WEBASSEMBLY_SECTION_OFFSET_I32: | ||
| 163 | writeSleb128(OS, File->calcNewAddend(Rel), "reloc addend"); | ||
| 164 | break; | ||
| 165 | } | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | void InputFunction::setFunctionIndex(uint32_t Index) { | ||
| 170 | LLVM_DEBUG(dbgs() << "InputFunction::setFunctionIndex: " << getName() | ||
| 171 | << " -> " << Index << "\n"); | ||
| 172 | assert(!hasFunctionIndex()); | ||
| 173 | FunctionIndex = Index; | ||
| 174 | } | ||
| 175 | |||
| 176 | void InputFunction::setTableIndex(uint32_t Index) { | ||
| 177 | LLVM_DEBUG(dbgs() << "InputFunction::setTableIndex: " << getName() << " -> " | ||
| 178 | << Index << "\n"); | ||
| 179 | assert(!hasTableIndex()); | ||
| 180 | TableIndex = Index; | ||
| 181 | } | ||
| 182 | |||
| 183 | // Write a relocation value without padding and return the number of bytes | ||
| 184 | // witten. | ||
| 185 | static unsigned writeCompressedReloc(uint8_t *Buf, const WasmRelocation &Rel, | ||
| 186 | uint32_t Value) { | ||
| 187 | switch (Rel.Type) { | ||
| 188 | case R_WEBASSEMBLY_TYPE_INDEX_LEB: | ||
| 189 | case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: | ||
| 190 | case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: | ||
| 191 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 192 | return encodeULEB128(Value, Buf); | ||
| 193 | case R_WEBASSEMBLY_TABLE_INDEX_SLEB: | ||
| 194 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 195 | return encodeSLEB128(static_cast<int32_t>(Value), Buf); | ||
| 196 | default: | ||
| 197 | llvm_unreachable("unexpected relocation type"); | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | static unsigned getRelocWidthPadded(const WasmRelocation &Rel) { | ||
| 202 | switch (Rel.Type) { | ||
| 203 | case R_WEBASSEMBLY_TYPE_INDEX_LEB: | ||
| 204 | case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: | ||
| 205 | case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: | ||
| 206 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 207 | case R_WEBASSEMBLY_TABLE_INDEX_SLEB: | ||
| 208 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 209 | return 5; | ||
| 210 | default: | ||
| 211 | llvm_unreachable("unexpected relocation type"); | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | static unsigned getRelocWidth(const WasmRelocation &Rel, uint32_t Value) { | ||
| 216 | uint8_t Buf[5]; | ||
| 217 | return writeCompressedReloc(Buf, Rel, Value); | ||
| 218 | } | ||
| 219 | |||
| 220 | // Relocations of type LEB and SLEB in the code section are padded to 5 bytes | ||
| 221 | // so that a fast linker can blindly overwrite them without needing to worry | ||
| 222 | // about the number of bytes needed to encode the values. | ||
| 223 | // However, for optimal output the code section can be compressed to remove | ||
| 224 | // the padding then outputting non-relocatable files. | ||
| 225 | // In this case we need to perform a size calculation based on the value at each | ||
| 226 | // relocation. At best we end up saving 4 bytes for each relocation entry. | ||
| 227 | // | ||
| 228 | // This function only computes the final output size. It must be called | ||
| 229 | // before getSize() is used to calculate of layout of the code section. | ||
| 230 | void InputFunction::calculateSize() { | ||
| 231 | if (!File || !Config->CompressRelocTargets) | ||
| 232 | return; | ||
| 233 | |||
| 234 | LLVM_DEBUG(dbgs() << "calculateSize: " << getName() << "\n"); | ||
| 235 | |||
| 236 | const uint8_t *SecStart = File->CodeSection->Content.data(); | ||
| 237 | const uint8_t *FuncStart = SecStart + getInputSectionOffset(); | ||
| 238 | uint32_t FunctionSizeLength; | ||
| 239 | decodeULEB128(FuncStart, &FunctionSizeLength); | ||
| 240 | |||
| 241 | uint32_t Start = getInputSectionOffset(); | ||
| 242 | uint32_t End = Start + Function->Size; | ||
| 243 | |||
| 244 | uint32_t LastRelocEnd = Start + FunctionSizeLength; | ||
| 245 | for (WasmRelocation &Rel : Relocations) { | ||
| 246 | LLVM_DEBUG(dbgs() << " region: " << (Rel.Offset - LastRelocEnd) << "\n"); | ||
| 247 | CompressedFuncSize += Rel.Offset - LastRelocEnd; | ||
| 248 | CompressedFuncSize += getRelocWidth(Rel, File->calcNewValue(Rel)); | ||
| 249 | LastRelocEnd = Rel.Offset + getRelocWidthPadded(Rel); | ||
| 250 | } | ||
| 251 | LLVM_DEBUG(dbgs() << " final region: " << (End - LastRelocEnd) << "\n"); | ||
| 252 | CompressedFuncSize += End - LastRelocEnd; | ||
| 253 | |||
| 254 | // Now we know how long the resulting function is we can add the encoding | ||
| 255 | // of its length | ||
| 256 | uint8_t Buf[5]; | ||
| 257 | CompressedSize = CompressedFuncSize + encodeULEB128(CompressedFuncSize, Buf); | ||
| 258 | |||
| 259 | LLVM_DEBUG(dbgs() << " calculateSize orig: " << Function->Size << "\n"); | ||
| 260 | LLVM_DEBUG(dbgs() << " calculateSize new: " << CompressedSize << "\n"); | ||
| 261 | } | ||
| 262 | |||
| 263 | // Override the default writeTo method so that we can (optionally) write the | ||
| 264 | // compressed version of the function. | ||
| 265 | void InputFunction::writeTo(uint8_t *Buf) const { | ||
| 266 | if (!File || !Config->CompressRelocTargets) | ||
| 267 | return InputChunk::writeTo(Buf); | ||
| 268 | |||
| 269 | Buf += OutputOffset; | ||
| 270 | uint8_t *Orig = Buf; (void)Orig; | ||
| 271 | |||
| 272 | const uint8_t *SecStart = File->CodeSection->Content.data(); | ||
| 273 | const uint8_t *FuncStart = SecStart + getInputSectionOffset(); | ||
| 274 | const uint8_t *End = FuncStart + Function->Size; | ||
| 275 | uint32_t Count; | ||
| 276 | decodeULEB128(FuncStart, &Count); | ||
| 277 | FuncStart += Count; | ||
| 278 | |||
| 279 | LLVM_DEBUG(dbgs() << "write func: " << getName() << "\n"); | ||
| 280 | Buf += encodeULEB128(CompressedFuncSize, Buf); | ||
| 281 | const uint8_t *LastRelocEnd = FuncStart; | ||
| 282 | for (const WasmRelocation &Rel : Relocations) { | ||
| 283 | unsigned ChunkSize = (SecStart + Rel.Offset) - LastRelocEnd; | ||
| 284 | LLVM_DEBUG(dbgs() << " write chunk: " << ChunkSize << "\n"); | ||
| 285 | memcpy(Buf, LastRelocEnd, ChunkSize); | ||
| 286 | Buf += ChunkSize; | ||
| 287 | Buf += writeCompressedReloc(Buf, Rel, File->calcNewValue(Rel)); | ||
| 288 | LastRelocEnd = SecStart + Rel.Offset + getRelocWidthPadded(Rel); | ||
| 289 | } | ||
| 290 | |||
| 291 | unsigned ChunkSize = End - LastRelocEnd; | ||
| 292 | LLVM_DEBUG(dbgs() << " write final chunk: " << ChunkSize << "\n"); | ||
| 293 | memcpy(Buf, LastRelocEnd, ChunkSize); | ||
| 294 | LLVM_DEBUG(dbgs() << " total: " << (Buf + ChunkSize - Orig) << "\n"); | ||
| 295 | } | ||
deps/lld/wasm/InputChunks.h created+236| ... | @@ -0,0 +1,236 @@ | ||
| 1 | //===- InputChunks.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 | // An InputChunks represents an indivisible opaque region of a input wasm file. | ||
| 11 | // i.e. a single wasm data segment or a single wasm function. | ||
| 12 | // | ||
| 13 | // They are written directly to the mmap'd output file after which relocations | ||
| 14 | // are applied. Because each Chunk is independent they can be written in | ||
| 15 | // parallel. | ||
| 16 | // | ||
| 17 | // Chunks are also unit on which garbage collection (--gc-sections) operates. | ||
| 18 | // | ||
| 19 | //===----------------------------------------------------------------------===// | ||
| 20 | |||
| 21 | #ifndef LLD_WASM_INPUT_CHUNKS_H | ||
| 22 | #define LLD_WASM_INPUT_CHUNKS_H | ||
| 23 | |||
| 24 | #include "Config.h" | ||
| 25 | #include "InputFiles.h" | ||
| 26 | #include "lld/Common/ErrorHandler.h" | ||
| 27 | #include "llvm/Object/Wasm.h" | ||
| 28 | |||
| 29 | using llvm::object::WasmSection; | ||
| 30 | using llvm::object::WasmSegment; | ||
| 31 | using llvm::wasm::WasmFunction; | ||
| 32 | using llvm::wasm::WasmRelocation; | ||
| 33 | using llvm::wasm::WasmSignature; | ||
| 34 | |||
| 35 | namespace llvm { | ||
| 36 | class raw_ostream; | ||
| 37 | } | ||
| 38 | |||
| 39 | namespace lld { | ||
| 40 | namespace wasm { | ||
| 41 | |||
| 42 | class ObjFile; | ||
| 43 | class OutputSegment; | ||
| 44 | |||
| 45 | class InputChunk { | ||
| 46 | public: | ||
| 47 | enum Kind { DataSegment, Function, SyntheticFunction, Section }; | ||
| 48 | |||
| 49 | Kind kind() const { return SectionKind; } | ||
| 50 | |||
| 51 | virtual uint32_t getSize() const { return data().size(); } | ||
| 52 | |||
| 53 | void copyRelocations(const WasmSection &Section); | ||
| 54 | |||
| 55 | virtual void writeTo(uint8_t *SectionStart) const; | ||
| 56 | |||
| 57 | ArrayRef<WasmRelocation> getRelocations() const { return Relocations; } | ||
| 58 | |||
| 59 | virtual StringRef getName() const = 0; | ||
| 60 | virtual StringRef getDebugName() const = 0; | ||
| 61 | virtual uint32_t getComdat() const = 0; | ||
| 62 | StringRef getComdatName() const; | ||
| 63 | |||
| 64 | size_t NumRelocations() const { return Relocations.size(); } | ||
| 65 | void writeRelocations(llvm::raw_ostream &OS) const; | ||
| 66 | |||
| 67 | ObjFile *File; | ||
| 68 | int32_t OutputOffset = 0; | ||
| 69 | |||
| 70 | // Signals that the section is part of the output. The garbage collector, | ||
| 71 | // and COMDAT handling can set a sections' Live bit. | ||
| 72 | // If GC is disabled, all sections start out as live by default. | ||
| 73 | unsigned Live : 1; | ||
| 74 | |||
| 75 | protected: | ||
| 76 | InputChunk(ObjFile *F, Kind K) | ||
| 77 | : File(F), Live(!Config->GcSections), SectionKind(K) {} | ||
| 78 | virtual ~InputChunk() = default; | ||
| 79 | virtual ArrayRef<uint8_t> data() const = 0; | ||
| 80 | virtual uint32_t getInputSectionOffset() const = 0; | ||
| 81 | virtual uint32_t getInputSize() const { return getSize(); }; | ||
| 82 | |||
| 83 | // Verifies the existing data at relocation targets matches our expectations. | ||
| 84 | // This is performed only debug builds as an extra sanity check. | ||
| 85 | void verifyRelocTargets() const; | ||
| 86 | |||
| 87 | std::vector<WasmRelocation> Relocations; | ||
| 88 | Kind SectionKind; | ||
| 89 | }; | ||
| 90 | |||
| 91 | // Represents a WebAssembly data segment which can be included as part of | ||
| 92 | // an output data segments. Note that in WebAssembly, unlike ELF and other | ||
| 93 | // formats, used the term "data segment" to refer to the continous regions of | ||
| 94 | // memory that make on the data section. See: | ||
| 95 | // https://webassembly.github.io/spec/syntax/modules.html#syntax-data | ||
| 96 | // | ||
| 97 | // For example, by default, clang will produce a separate data section for | ||
| 98 | // each global variable. | ||
| 99 | class InputSegment : public InputChunk { | ||
| 100 | public: | ||
| 101 | InputSegment(const WasmSegment &Seg, ObjFile *F) | ||
| 102 | : InputChunk(F, InputChunk::DataSegment), Segment(Seg) {} | ||
| 103 | |||
| 104 | static bool classof(const InputChunk *C) { return C->kind() == DataSegment; } | ||
| 105 | |||
| 106 | uint32_t getAlignment() const { return Segment.Data.Alignment; } | ||
| 107 | StringRef getName() const override { return Segment.Data.Name; } | ||
| 108 | StringRef getDebugName() const override { return StringRef(); } | ||
| 109 | uint32_t getComdat() const override { return Segment.Data.Comdat; } | ||
| 110 | |||
| 111 | const OutputSegment *OutputSeg = nullptr; | ||
| 112 | int32_t OutputSegmentOffset = 0; | ||
| 113 | |||
| 114 | protected: | ||
| 115 | ArrayRef<uint8_t> data() const override { return Segment.Data.Content; } | ||
| 116 | uint32_t getInputSectionOffset() const override { | ||
| 117 | return Segment.SectionOffset; | ||
| 118 | } | ||
| 119 | |||
| 120 | const WasmSegment &Segment; | ||
| 121 | }; | ||
| 122 | |||
| 123 | // Represents a single wasm function within and input file. These are | ||
| 124 | // combined to create the final output CODE section. | ||
| 125 | class InputFunction : public InputChunk { | ||
| 126 | public: | ||
| 127 | InputFunction(const WasmSignature &S, const WasmFunction *Func, ObjFile *F) | ||
| 128 | : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {} | ||
| 129 | |||
| 130 | static bool classof(const InputChunk *C) { | ||
| 131 | return C->kind() == InputChunk::Function || | ||
| 132 | C->kind() == InputChunk::SyntheticFunction; | ||
| 133 | } | ||
| 134 | |||
| 135 | void writeTo(uint8_t *SectionStart) const override; | ||
| 136 | StringRef getName() const override { return Function->SymbolName; } | ||
| 137 | StringRef getDebugName() const override { return Function->DebugName; } | ||
| 138 | uint32_t getComdat() const override { return Function->Comdat; } | ||
| 139 | uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); } | ||
| 140 | uint32_t getFunctionCodeOffset() const { return Function->CodeOffset; } | ||
| 141 | uint32_t getSize() const override { | ||
| 142 | if (Config->CompressRelocTargets && File) { | ||
| 143 | assert(CompressedSize); | ||
| 144 | return CompressedSize; | ||
| 145 | } | ||
| 146 | return data().size(); | ||
| 147 | } | ||
| 148 | uint32_t getFunctionIndex() const { return FunctionIndex.getValue(); } | ||
| 149 | bool hasFunctionIndex() const { return FunctionIndex.hasValue(); } | ||
| 150 | void setFunctionIndex(uint32_t Index); | ||
| 151 | uint32_t getTableIndex() const { return TableIndex.getValue(); } | ||
| 152 | bool hasTableIndex() const { return TableIndex.hasValue(); } | ||
| 153 | void setTableIndex(uint32_t Index); | ||
| 154 | |||
| 155 | // The size of a given input function can depend on the values of the | ||
| 156 | // LEB relocations within it. This finalizeContents method is called after | ||
| 157 | // all the symbol values have be calcualted but before getSize() is ever | ||
| 158 | // called. | ||
| 159 | void calculateSize(); | ||
| 160 | |||
| 161 | const WasmSignature &Signature; | ||
| 162 | |||
| 163 | protected: | ||
| 164 | ArrayRef<uint8_t> data() const override { | ||
| 165 | assert(!Config->CompressRelocTargets); | ||
| 166 | return File->CodeSection->Content.slice(getInputSectionOffset(), | ||
| 167 | Function->Size); | ||
| 168 | } | ||
| 169 | |||
| 170 | uint32_t getInputSize() const override { return Function->Size; } | ||
| 171 | |||
| 172 | uint32_t getInputSectionOffset() const override { | ||
| 173 | return Function->CodeSectionOffset; | ||
| 174 | } | ||
| 175 | |||
| 176 | const WasmFunction *Function; | ||
| 177 | llvm::Optional<uint32_t> FunctionIndex; | ||
| 178 | llvm::Optional<uint32_t> TableIndex; | ||
| 179 | uint32_t CompressedFuncSize = 0; | ||
| 180 | uint32_t CompressedSize = 0; | ||
| 181 | }; | ||
| 182 | |||
| 183 | class SyntheticFunction : public InputFunction { | ||
| 184 | public: | ||
| 185 | SyntheticFunction(const WasmSignature &S, StringRef Name, | ||
| 186 | StringRef DebugName = {}) | ||
| 187 | : InputFunction(S, nullptr, nullptr), Name(Name), DebugName(DebugName) { | ||
| 188 | SectionKind = InputChunk::SyntheticFunction; | ||
| 189 | } | ||
| 190 | |||
| 191 | static bool classof(const InputChunk *C) { | ||
| 192 | return C->kind() == InputChunk::SyntheticFunction; | ||
| 193 | } | ||
| 194 | |||
| 195 | StringRef getName() const override { return Name; } | ||
| 196 | StringRef getDebugName() const override { return DebugName; } | ||
| 197 | uint32_t getComdat() const override { return UINT32_MAX; } | ||
| 198 | |||
| 199 | void setBody(ArrayRef<uint8_t> Body_) { Body = Body_; } | ||
| 200 | |||
| 201 | protected: | ||
| 202 | ArrayRef<uint8_t> data() const override { return Body; } | ||
| 203 | |||
| 204 | StringRef Name; | ||
| 205 | StringRef DebugName; | ||
| 206 | ArrayRef<uint8_t> Body; | ||
| 207 | }; | ||
| 208 | |||
| 209 | // Represents a single Wasm Section within an input file. | ||
| 210 | class InputSection : public InputChunk { | ||
| 211 | public: | ||
| 212 | InputSection(const WasmSection &S, ObjFile *F) | ||
| 213 | : InputChunk(F, InputChunk::Section), Section(S) { | ||
| 214 | assert(Section.Type == llvm::wasm::WASM_SEC_CUSTOM); | ||
| 215 | } | ||
| 216 | |||
| 217 | StringRef getName() const override { return Section.Name; } | ||
| 218 | StringRef getDebugName() const override { return StringRef(); } | ||
| 219 | uint32_t getComdat() const override { return UINT32_MAX; } | ||
| 220 | |||
| 221 | protected: | ||
| 222 | ArrayRef<uint8_t> data() const override { return Section.Content; } | ||
| 223 | |||
| 224 | // Offset within the input section. This is only zero since this chunk | ||
| 225 | // type represents an entire input section, not part of one. | ||
| 226 | uint32_t getInputSectionOffset() const override { return 0; } | ||
| 227 | |||
| 228 | const WasmSection &Section; | ||
| 229 | }; | ||
| 230 | |||
| 231 | } // namespace wasm | ||
| 232 | |||
| 233 | std::string toString(const wasm::InputChunk *); | ||
| 234 | } // namespace lld | ||
| 235 | |||
| 236 | #endif // LLD_WASM_INPUT_CHUNKS_H | ||
deps/lld/wasm/InputFiles.cpp+290-172| ... | @@ -8,9 +8,9 @@ | ... | @@ -8,9 +8,9 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | ||
| 10 | #include "InputFiles.h" | 10 | #include "InputFiles.h" |
| 11 | |||
| 12 | #include "Config.h" | 11 | #include "Config.h" |
| 13 | #include "InputSegment.h" | 12 | #include "InputChunks.h" |
| 13 | #include "InputGlobal.h" | ||
| 14 | #include "SymbolTable.h" | 14 | #include "SymbolTable.h" |
| 15 | #include "lld/Common/ErrorHandler.h" | 15 | #include "lld/Common/ErrorHandler.h" |
| 16 | #include "lld/Common/Memory.h" | 16 | #include "lld/Common/Memory.h" |
| ... | @@ -42,64 +42,126 @@ Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) { | ... | @@ -42,64 +42,126 @@ Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) { |
| 42 | return MBRef; | 42 | return MBRef; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | void ObjFile::dumpInfo() const { | 45 | InputFile *lld::wasm::createObjectFile(MemoryBufferRef MB) { |
| 46 | log("reloc info for: " + getName() + "\n" + | 46 | file_magic Magic = identify_magic(MB.getBuffer()); |
| 47 | " FunctionIndexOffset : " + Twine(FunctionIndexOffset) + "\n" + | 47 | if (Magic == file_magic::wasm_object) |
| 48 | " NumFunctionImports : " + Twine(NumFunctionImports()) + "\n" + | 48 | return make<ObjFile>(MB); |
| 49 | " NumGlobalImports : " + Twine(NumGlobalImports()) + "\n"); | ||
| 50 | } | ||
| 51 | 49 | ||
| 52 | bool ObjFile::isImportedFunction(uint32_t Index) const { | 50 | if (Magic == file_magic::bitcode) |
| 53 | return Index < NumFunctionImports(); | 51 | return make<BitcodeFile>(MB); |
| 54 | } | ||
| 55 | 52 | ||
| 56 | Symbol *ObjFile::getFunctionSymbol(uint32_t Index) const { | 53 | fatal("unknown file type: " + MB.getBufferIdentifier()); |
| 57 | return FunctionSymbols[Index]; | ||
| 58 | } | 54 | } |
| 59 | 55 | ||
| 60 | Symbol *ObjFile::getTableSymbol(uint32_t Index) const { | 56 | void ObjFile::dumpInfo() const { |
| 61 | return TableSymbols[Index]; | 57 | log("info for: " + getName() + |
| 62 | } | 58 | "\n Symbols : " + Twine(Symbols.size()) + |
| 63 | 59 | "\n Function Imports : " + Twine(WasmObj->getNumImportedFunctions()) + | |
| 64 | Symbol *ObjFile::getGlobalSymbol(uint32_t Index) const { | 60 | "\n Global Imports : " + Twine(WasmObj->getNumImportedGlobals())); |
| 65 | return GlobalSymbols[Index]; | ||
| 66 | } | ||
| 67 | |||
| 68 | uint32_t ObjFile::getRelocatedAddress(uint32_t Index) const { | ||
| 69 | return getGlobalSymbol(Index)->getVirtualAddress(); | ||
| 70 | } | 61 | } |
| 71 | 62 | ||
| 72 | uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const { | 63 | // Relocations contain either symbol or type indices. This function takes a |
| 73 | Symbol *Sym = getFunctionSymbol(Original); | 64 | // relocation and returns relocated index (i.e. translates from the input |
| 74 | uint32_t Index = Sym->getOutputIndex(); | 65 | // sybmol/type space to the output symbol/type space). |
| 75 | DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": " | 66 | uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const { |
| 76 | << Original << " -> " << Index << "\n"); | 67 | if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) { |
| 77 | return Index; | 68 | assert(TypeIsUsed[Reloc.Index]); |
| 69 | return TypeMap[Reloc.Index]; | ||
| 70 | } | ||
| 71 | return Symbols[Reloc.Index]->getOutputSymbolIndex(); | ||
| 78 | } | 72 | } |
| 79 | 73 | ||
| 80 | uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const { | 74 | // Relocations can contain addend for combined sections. This function takes a |
| 81 | return TypeMap[Original]; | 75 | // relocation and returns updated addend by offset in the output section. |
| 76 | uint32_t ObjFile::calcNewAddend(const WasmRelocation &Reloc) const { | ||
| 77 | switch (Reloc.Type) { | ||
| 78 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 79 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 80 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 81 | case R_WEBASSEMBLY_FUNCTION_OFFSET_I32: | ||
| 82 | return Reloc.Addend; | ||
| 83 | case R_WEBASSEMBLY_SECTION_OFFSET_I32: | ||
| 84 | return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend; | ||
| 85 | default: | ||
| 86 | llvm_unreachable("unexpected relocation type"); | ||
| 87 | } | ||
| 82 | } | 88 | } |
| 83 | 89 | ||
| 84 | uint32_t ObjFile::relocateTableIndex(uint32_t Original) const { | 90 | // Calculate the value we expect to find at the relocation location. |
| 85 | Symbol *Sym = getTableSymbol(Original); | 91 | // This is used as a sanity check before applying a relocation to a given |
| 86 | uint32_t Index = Sym->getTableIndex(); | 92 | // location. It is useful for catching bugs in the compiler and linker. |
| 87 | DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original | 93 | uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const { |
| 88 | << " -> " << Index << "\n"); | 94 | switch (Reloc.Type) { |
| 89 | return Index; | 95 | case R_WEBASSEMBLY_TABLE_INDEX_I32: |
| 96 | case R_WEBASSEMBLY_TABLE_INDEX_SLEB: { | ||
| 97 | const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index]; | ||
| 98 | return TableEntries[Sym.Info.ElementIndex]; | ||
| 99 | } | ||
| 100 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 101 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 102 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: { | ||
| 103 | const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index]; | ||
| 104 | if (Sym.isUndefined()) | ||
| 105 | return 0; | ||
| 106 | const WasmSegment& Segment = WasmObj->dataSegments()[Sym.Info.DataRef.Segment]; | ||
| 107 | return Segment.Data.Offset.Value.Int32 + Sym.Info.DataRef.Offset + | ||
| 108 | Reloc.Addend; | ||
| 109 | } | ||
| 110 | case R_WEBASSEMBLY_FUNCTION_OFFSET_I32: | ||
| 111 | if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) { | ||
| 112 | return Sym->Function->getFunctionInputOffset() + | ||
| 113 | Sym->Function->getFunctionCodeOffset() + Reloc.Addend; | ||
| 114 | } | ||
| 115 | return 0; | ||
| 116 | case R_WEBASSEMBLY_SECTION_OFFSET_I32: | ||
| 117 | return Reloc.Addend; | ||
| 118 | case R_WEBASSEMBLY_TYPE_INDEX_LEB: | ||
| 119 | return Reloc.Index; | ||
| 120 | case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: | ||
| 121 | case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: { | ||
| 122 | const WasmSymbol& Sym = WasmObj->syms()[Reloc.Index]; | ||
| 123 | return Sym.Info.ElementIndex; | ||
| 124 | } | ||
| 125 | default: | ||
| 126 | llvm_unreachable("unknown relocation type"); | ||
| 127 | } | ||
| 90 | } | 128 | } |
| 91 | 129 | ||
| 92 | uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const { | 130 | // Translate from the relocation's index into the final linked output value. |
| 93 | Symbol *Sym = getGlobalSymbol(Original); | 131 | uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const { |
| 94 | uint32_t Index = Sym->getOutputIndex(); | 132 | switch (Reloc.Type) { |
| 95 | DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original | 133 | case R_WEBASSEMBLY_TABLE_INDEX_I32: |
| 96 | << " -> " << Index << "\n"); | 134 | case R_WEBASSEMBLY_TABLE_INDEX_SLEB: |
| 97 | return Index; | 135 | return getFunctionSymbol(Reloc.Index)->getTableIndex(); |
| 136 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 137 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 138 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 139 | if (auto *Sym = dyn_cast<DefinedData>(getDataSymbol(Reloc.Index))) | ||
| 140 | if (Sym->isLive()) | ||
| 141 | return Sym->getVirtualAddress() + Reloc.Addend; | ||
| 142 | return 0; | ||
| 143 | case R_WEBASSEMBLY_TYPE_INDEX_LEB: | ||
| 144 | return TypeMap[Reloc.Index]; | ||
| 145 | case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: | ||
| 146 | return getFunctionSymbol(Reloc.Index)->getFunctionIndex(); | ||
| 147 | case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: | ||
| 148 | return getGlobalSymbol(Reloc.Index)->getGlobalIndex(); | ||
| 149 | case R_WEBASSEMBLY_FUNCTION_OFFSET_I32: | ||
| 150 | if (auto *Sym = dyn_cast<DefinedFunction>(getFunctionSymbol(Reloc.Index))) { | ||
| 151 | return Sym->Function->OutputOffset + | ||
| 152 | Sym->Function->getFunctionCodeOffset() + Reloc.Addend; | ||
| 153 | } | ||
| 154 | return 0; | ||
| 155 | case R_WEBASSEMBLY_SECTION_OFFSET_I32: | ||
| 156 | return getSectionSymbol(Reloc.Index)->Section->OutputOffset + Reloc.Addend; | ||
| 157 | default: | ||
| 158 | llvm_unreachable("unknown relocation type"); | ||
| 159 | } | ||
| 98 | } | 160 | } |
| 99 | 161 | ||
| 100 | void ObjFile::parse() { | 162 | void ObjFile::parse() { |
| 101 | // Parse a memory buffer as a wasm file. | 163 | // Parse a memory buffer as a wasm file. |
| 102 | DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n"); | 164 | LLVM_DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n"); |
| 103 | std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this)); | 165 | std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this)); |
| 104 | 166 | ||
| 105 | auto *Obj = dyn_cast<WasmObjectFile>(Bin.get()); | 167 | auto *Obj = dyn_cast<WasmObjectFile>(Bin.get()); |
| ... | @@ -111,156 +173,175 @@ void ObjFile::parse() { | ... | @@ -111,156 +173,175 @@ void ObjFile::parse() { |
| 111 | Bin.release(); | 173 | Bin.release(); |
| 112 | WasmObj.reset(Obj); | 174 | WasmObj.reset(Obj); |
| 113 | 175 | ||
| 176 | // Build up a map of function indices to table indices for use when | ||
| 177 | // verifying the existing table index relocations | ||
| 178 | uint32_t TotalFunctions = | ||
| 179 | WasmObj->getNumImportedFunctions() + WasmObj->functions().size(); | ||
| 180 | TableEntries.resize(TotalFunctions); | ||
| 181 | for (const WasmElemSegment &Seg : WasmObj->elements()) { | ||
| 182 | if (Seg.Offset.Opcode != WASM_OPCODE_I32_CONST) | ||
| 183 | fatal(toString(this) + ": invalid table elements"); | ||
| 184 | uint32_t Offset = Seg.Offset.Value.Int32; | ||
| 185 | for (uint32_t Index = 0; Index < Seg.Functions.size(); Index++) { | ||
| 186 | |||
| 187 | uint32_t FunctionIndex = Seg.Functions[Index]; | ||
| 188 | TableEntries[FunctionIndex] = Offset + Index; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 114 | // Find the code and data sections. Wasm objects can have at most one code | 192 | // Find the code and data sections. Wasm objects can have at most one code |
| 115 | // and one data section. | 193 | // and one data section. |
| 194 | uint32_t SectionIndex = 0; | ||
| 116 | for (const SectionRef &Sec : WasmObj->sections()) { | 195 | for (const SectionRef &Sec : WasmObj->sections()) { |
| 117 | const WasmSection &Section = WasmObj->getWasmSection(Sec); | 196 | const WasmSection &Section = WasmObj->getWasmSection(Sec); |
| 118 | if (Section.Type == WASM_SEC_CODE) | 197 | if (Section.Type == WASM_SEC_CODE) { |
| 119 | CodeSection = &Section; | 198 | CodeSection = &Section; |
| 120 | else if (Section.Type == WASM_SEC_DATA) | 199 | } else if (Section.Type == WASM_SEC_DATA) { |
| 121 | DataSection = &Section; | 200 | DataSection = &Section; |
| 201 | } else if (Section.Type == WASM_SEC_CUSTOM) { | ||
| 202 | CustomSections.emplace_back(make<InputSection>(Section, this)); | ||
| 203 | CustomSections.back()->copyRelocations(Section); | ||
| 204 | CustomSectionsByIndex[SectionIndex] = CustomSections.back(); | ||
| 205 | } | ||
| 206 | SectionIndex++; | ||
| 122 | } | 207 | } |
| 123 | 208 | ||
| 124 | initializeSymbols(); | 209 | TypeMap.resize(getWasmObj()->types().size()); |
| 125 | } | 210 | TypeIsUsed.resize(getWasmObj()->types().size(), false); |
| 126 | 211 | ||
| 127 | // Return the InputSegment in which a given symbol is defined. | 212 | ArrayRef<StringRef> Comdats = WasmObj->linkingData().Comdats; |
| 128 | InputSegment *ObjFile::getSegment(const WasmSymbol &WasmSym) { | 213 | UsedComdats.resize(Comdats.size()); |
| 129 | uint32_t Address = WasmObj->getWasmSymbolValue(WasmSym); | 214 | for (unsigned I = 0; I < Comdats.size(); ++I) |
| 130 | for (InputSegment *Segment : Segments) { | 215 | UsedComdats[I] = Symtab->addComdat(Comdats[I]); |
| 131 | if (Address >= Segment->startVA() && Address < Segment->endVA()) { | ||
| 132 | DEBUG(dbgs() << "Found symbol in segment: " << WasmSym.Name << " -> " | ||
| 133 | << Segment->getName() << "\n"); | ||
| 134 | 216 | ||
| 135 | return Segment; | 217 | // Populate `Segments`. |
| 136 | } | 218 | for (const WasmSegment &S : WasmObj->dataSegments()) { |
| 219 | InputSegment *Seg = make<InputSegment>(S, this); | ||
| 220 | Seg->copyRelocations(*DataSection); | ||
| 221 | Segments.emplace_back(Seg); | ||
| 222 | } | ||
| 223 | |||
| 224 | // Populate `Functions`. | ||
| 225 | ArrayRef<WasmFunction> Funcs = WasmObj->functions(); | ||
| 226 | ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes(); | ||
| 227 | ArrayRef<WasmSignature> Types = WasmObj->types(); | ||
| 228 | Functions.reserve(Funcs.size()); | ||
| 229 | |||
| 230 | for (size_t I = 0, E = Funcs.size(); I != E; ++I) { | ||
| 231 | InputFunction *F = | ||
| 232 | make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this); | ||
| 233 | F->copyRelocations(*CodeSection); | ||
| 234 | Functions.emplace_back(F); | ||
| 235 | } | ||
| 236 | |||
| 237 | // Populate `Globals`. | ||
| 238 | for (const WasmGlobal &G : WasmObj->globals()) | ||
| 239 | Globals.emplace_back(make<InputGlobal>(G, this)); | ||
| 240 | |||
| 241 | // Populate `Symbols` based on the WasmSymbols in the object. | ||
| 242 | Symbols.reserve(WasmObj->getNumberOfSymbols()); | ||
| 243 | for (const SymbolRef &Sym : WasmObj->symbols()) { | ||
| 244 | const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl()); | ||
| 245 | if (Symbol *Sym = createDefined(WasmSym)) | ||
| 246 | Symbols.push_back(Sym); | ||
| 247 | else | ||
| 248 | Symbols.push_back(createUndefined(WasmSym)); | ||
| 137 | } | 249 | } |
| 138 | error("symbol not found in any segment: " + WasmSym.Name); | ||
| 139 | return nullptr; | ||
| 140 | } | 250 | } |
| 141 | 251 | ||
| 142 | static void copyRelocationsRange(std::vector<WasmRelocation> &To, | 252 | bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const { |
| 143 | ArrayRef<WasmRelocation> From, size_t Start, | 253 | uint32_t C = Chunk->getComdat(); |
| 144 | size_t End) { | 254 | if (C == UINT32_MAX) |
| 145 | for (const WasmRelocation &R : From) | 255 | return false; |
| 146 | if (R.Offset >= Start && R.Offset < End) | 256 | return !UsedComdats[C]; |
| 147 | To.push_back(R); | ||
| 148 | } | 257 | } |
| 149 | 258 | ||
| 150 | void ObjFile::initializeSymbols() { | 259 | FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t Index) const { |
| 151 | Symbols.reserve(WasmObj->getNumberOfSymbols()); | 260 | return cast<FunctionSymbol>(Symbols[Index]); |
| 261 | } | ||
| 152 | 262 | ||
| 153 | for (const WasmImport &Import : WasmObj->imports()) { | 263 | GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const { |
| 154 | switch (Import.Kind) { | 264 | return cast<GlobalSymbol>(Symbols[Index]); |
| 155 | case WASM_EXTERNAL_FUNCTION: | 265 | } |
| 156 | ++FunctionImports; | ||
| 157 | break; | ||
| 158 | case WASM_EXTERNAL_GLOBAL: | ||
| 159 | ++GlobalImports; | ||
| 160 | break; | ||
| 161 | } | ||
| 162 | } | ||
| 163 | 266 | ||
| 164 | FunctionSymbols.resize(FunctionImports + WasmObj->functions().size()); | 267 | SectionSymbol *ObjFile::getSectionSymbol(uint32_t Index) const { |
| 165 | GlobalSymbols.resize(GlobalImports + WasmObj->globals().size()); | 268 | return cast<SectionSymbol>(Symbols[Index]); |
| 269 | } | ||
| 166 | 270 | ||
| 167 | for (const WasmSegment &S : WasmObj->dataSegments()) { | 271 | DataSymbol *ObjFile::getDataSymbol(uint32_t Index) const { |
| 168 | InputSegment *Seg = make<InputSegment>(&S, this); | 272 | return cast<DataSymbol>(Symbols[Index]); |
| 169 | copyRelocationsRange(Seg->Relocations, DataSection->Relocations, | 273 | } |
| 170 | Seg->getInputSectionOffset(), | ||
| 171 | Seg->getInputSectionOffset() + Seg->getSize()); | ||
| 172 | Segments.emplace_back(Seg); | ||
| 173 | } | ||
| 174 | 274 | ||
| 175 | // Populate `FunctionSymbols` and `GlobalSymbols` based on the WasmSymbols | 275 | Symbol *ObjFile::createDefined(const WasmSymbol &Sym) { |
| 176 | // in the object | 276 | if (!Sym.isDefined()) |
| 177 | for (const SymbolRef &Sym : WasmObj->symbols()) { | 277 | return nullptr; |
| 178 | const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl()); | ||
| 179 | Symbol *S; | ||
| 180 | switch (WasmSym.Type) { | ||
| 181 | case WasmSymbol::SymbolType::FUNCTION_IMPORT: | ||
| 182 | case WasmSymbol::SymbolType::GLOBAL_IMPORT: | ||
| 183 | S = createUndefined(WasmSym); | ||
| 184 | break; | ||
| 185 | case WasmSymbol::SymbolType::GLOBAL_EXPORT: | ||
| 186 | S = createDefined(WasmSym, getSegment(WasmSym)); | ||
| 187 | break; | ||
| 188 | case WasmSymbol::SymbolType::FUNCTION_EXPORT: | ||
| 189 | S = createDefined(WasmSym); | ||
| 190 | break; | ||
| 191 | case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME: | ||
| 192 | // These are for debugging only, no need to create linker symbols for them | ||
| 193 | continue; | ||
| 194 | } | ||
| 195 | 278 | ||
| 196 | Symbols.push_back(S); | 279 | StringRef Name = Sym.Info.Name; |
| 197 | if (WasmSym.isFunction()) { | 280 | uint32_t Flags = Sym.Info.Flags; |
| 198 | DEBUG(dbgs() << "Function: " << WasmSym.ElementIndex << " -> " | 281 | |
| 199 | << toString(*S) << "\n"); | 282 | switch (Sym.Info.Kind) { |
| 200 | FunctionSymbols[WasmSym.ElementIndex] = S; | 283 | case WASM_SYMBOL_TYPE_FUNCTION: { |
| 201 | if (WasmSym.HasAltIndex) | 284 | InputFunction *Func = |
| 202 | FunctionSymbols[WasmSym.AltIndex] = S; | 285 | Functions[Sym.Info.ElementIndex - WasmObj->getNumImportedFunctions()]; |
| 203 | } else { | 286 | if (isExcludedByComdat(Func)) { |
| 204 | DEBUG(dbgs() << "Global: " << WasmSym.ElementIndex << " -> " | 287 | Func->Live = false; |
| 205 | << toString(*S) << "\n"); | 288 | return nullptr; |
| 206 | GlobalSymbols[WasmSym.ElementIndex] = S; | ||
| 207 | if (WasmSym.HasAltIndex) | ||
| 208 | GlobalSymbols[WasmSym.AltIndex] = S; | ||
| 209 | } | 289 | } |
| 210 | } | ||
| 211 | 290 | ||
| 212 | DEBUG(for (size_t I = 0; I < FunctionSymbols.size(); ++I) | 291 | if (Sym.isBindingLocal()) |
| 213 | assert(FunctionSymbols[I] != nullptr); | 292 | return make<DefinedFunction>(Name, Flags, this, Func); |
| 214 | for (size_t I = 0; I < GlobalSymbols.size(); ++I) | 293 | return Symtab->addDefinedFunction(Name, Flags, this, Func); |
| 215 | assert(GlobalSymbols[I] != nullptr);); | ||
| 216 | |||
| 217 | // Populate `TableSymbols` with all symbols that are called indirectly | ||
| 218 | uint32_t SegmentCount = WasmObj->elements().size(); | ||
| 219 | if (SegmentCount) { | ||
| 220 | if (SegmentCount > 1) | ||
| 221 | fatal(getName() + ": contains more than one element segment"); | ||
| 222 | const WasmElemSegment &Segment = WasmObj->elements()[0]; | ||
| 223 | if (Segment.Offset.Opcode != WASM_OPCODE_I32_CONST) | ||
| 224 | fatal(getName() + ": unsupported element segment"); | ||
| 225 | if (Segment.TableIndex != 0) | ||
| 226 | fatal(getName() + ": unsupported table index in elem segment"); | ||
| 227 | if (Segment.Offset.Value.Int32 != 0) | ||
| 228 | fatal(getName() + ": unsupported element segment offset"); | ||
| 229 | TableSymbols.reserve(Segment.Functions.size()); | ||
| 230 | for (uint64_t FunctionIndex : Segment.Functions) | ||
| 231 | TableSymbols.push_back(getFunctionSymbol(FunctionIndex)); | ||
| 232 | } | 294 | } |
| 295 | case WASM_SYMBOL_TYPE_DATA: { | ||
| 296 | InputSegment *Seg = Segments[Sym.Info.DataRef.Segment]; | ||
| 297 | if (isExcludedByComdat(Seg)) { | ||
| 298 | Seg->Live = false; | ||
| 299 | return nullptr; | ||
| 300 | } | ||
| 233 | 301 | ||
| 234 | DEBUG(dbgs() << "TableSymbols: " << TableSymbols.size() << "\n"); | 302 | uint32_t Offset = Sym.Info.DataRef.Offset; |
| 235 | DEBUG(dbgs() << "Functions : " << FunctionSymbols.size() << "\n"); | 303 | uint32_t Size = Sym.Info.DataRef.Size; |
| 236 | DEBUG(dbgs() << "Globals : " << GlobalSymbols.size() << "\n"); | ||
| 237 | } | ||
| 238 | 304 | ||
| 239 | Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) { | 305 | if (Sym.isBindingLocal()) |
| 240 | return Symtab->addUndefined(this, &Sym); | 306 | return make<DefinedData>(Name, Flags, this, Seg, Offset, Size); |
| 307 | return Symtab->addDefinedData(Name, Flags, this, Seg, Offset, Size); | ||
| 308 | } | ||
| 309 | case WASM_SYMBOL_TYPE_GLOBAL: { | ||
| 310 | InputGlobal *Global = | ||
| 311 | Globals[Sym.Info.ElementIndex - WasmObj->getNumImportedGlobals()]; | ||
| 312 | if (Sym.isBindingLocal()) | ||
| 313 | return make<DefinedGlobal>(Name, Flags, this, Global); | ||
| 314 | return Symtab->addDefinedGlobal(Name, Flags, this, Global); | ||
| 315 | } | ||
| 316 | case WASM_SYMBOL_TYPE_SECTION: { | ||
| 317 | InputSection *Section = CustomSectionsByIndex[Sym.Info.ElementIndex]; | ||
| 318 | assert(Sym.isBindingLocal()); | ||
| 319 | return make<SectionSymbol>(Name, Flags, Section, this); | ||
| 320 | } | ||
| 321 | } | ||
| 322 | llvm_unreachable("unknown symbol kind"); | ||
| 241 | } | 323 | } |
| 242 | 324 | ||
| 243 | Symbol *ObjFile::createDefined(const WasmSymbol &Sym, | 325 | Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) { |
| 244 | const InputSegment *Segment) { | 326 | StringRef Name = Sym.Info.Name; |
| 245 | Symbol *S; | 327 | uint32_t Flags = Sym.Info.Flags; |
| 246 | if (Sym.isLocal()) { | 328 | |
| 247 | S = make<Symbol>(Sym.Name, true); | 329 | switch (Sym.Info.Kind) { |
| 248 | Symbol::Kind Kind; | 330 | case WASM_SYMBOL_TYPE_FUNCTION: |
| 249 | if (Sym.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT) | 331 | return Symtab->addUndefinedFunction(Name, Flags, this, Sym.FunctionType); |
| 250 | Kind = Symbol::Kind::DefinedFunctionKind; | 332 | case WASM_SYMBOL_TYPE_DATA: |
| 251 | else if (Sym.Type == WasmSymbol::SymbolType::GLOBAL_EXPORT) | 333 | return Symtab->addUndefinedData(Name, Flags, this); |
| 252 | Kind = Symbol::Kind::DefinedGlobalKind; | 334 | case WASM_SYMBOL_TYPE_GLOBAL: |
| 253 | else | 335 | return Symtab->addUndefinedGlobal(Name, Flags, this, Sym.GlobalType); |
| 254 | llvm_unreachable("invalid local symbol type"); | 336 | case WASM_SYMBOL_TYPE_SECTION: |
| 255 | S->update(Kind, this, &Sym, Segment); | 337 | llvm_unreachable("section symbols cannot be undefined"); |
| 256 | return S; | ||
| 257 | } | 338 | } |
| 258 | return Symtab->addDefined(this, &Sym, Segment); | 339 | llvm_unreachable("unknown symbol kind"); |
| 259 | } | 340 | } |
| 260 | 341 | ||
| 261 | void ArchiveFile::parse() { | 342 | void ArchiveFile::parse() { |
| 262 | // Parse a MemoryBufferRef as an archive file. | 343 | // Parse a MemoryBufferRef as an archive file. |
| 263 | DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n"); | 344 | LLVM_DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n"); |
| 264 | File = CHECK(Archive::create(MB), toString(this)); | 345 | File = CHECK(Archive::create(MB), toString(this)); |
| 265 | 346 | ||
| 266 | // Read the symbol table to construct Lazy symbols. | 347 | // Read the symbol table to construct Lazy symbols. |
| ... | @@ -269,7 +350,7 @@ void ArchiveFile::parse() { | ... | @@ -269,7 +350,7 @@ void ArchiveFile::parse() { |
| 269 | Symtab->addLazy(this, &Sym); | 350 | Symtab->addLazy(this, &Sym); |
| 270 | ++Count; | 351 | ++Count; |
| 271 | } | 352 | } |
| 272 | DEBUG(dbgs() << "Read " << Count << " symbols\n"); | 353 | LLVM_DEBUG(dbgs() << "Read " << Count << " symbols\n"); |
| 273 | } | 354 | } |
| 274 | 355 | ||
| 275 | void ArchiveFile::addMember(const Archive::Symbol *Sym) { | 356 | void ArchiveFile::addMember(const Archive::Symbol *Sym) { |
| ... | @@ -282,22 +363,59 @@ void ArchiveFile::addMember(const Archive::Symbol *Sym) { | ... | @@ -282,22 +363,59 @@ void ArchiveFile::addMember(const Archive::Symbol *Sym) { |
| 282 | if (!Seen.insert(C.getChildOffset()).second) | 363 | if (!Seen.insert(C.getChildOffset()).second) |
| 283 | return; | 364 | return; |
| 284 | 365 | ||
| 285 | DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n"); | 366 | LLVM_DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n"); |
| 286 | DEBUG(dbgs() << "from archive: " << toString(this) << "\n"); | 367 | LLVM_DEBUG(dbgs() << "from archive: " << toString(this) << "\n"); |
| 287 | 368 | ||
| 288 | MemoryBufferRef MB = | 369 | MemoryBufferRef MB = |
| 289 | CHECK(C.getMemoryBufferRef(), | 370 | CHECK(C.getMemoryBufferRef(), |
| 290 | "could not get the buffer for the member defining symbol " + | 371 | "could not get the buffer for the member defining symbol " + |
| 291 | Sym->getName()); | 372 | Sym->getName()); |
| 292 | 373 | ||
| 293 | if (identify_magic(MB.getBuffer()) != file_magic::wasm_object) { | 374 | InputFile *Obj = createObjectFile(MB); |
| 294 | error("unknown file type: " + MB.getBufferIdentifier()); | 375 | Obj->ArchiveName = getName(); |
| 376 | Symtab->addFile(Obj); | ||
| 377 | } | ||
| 378 | |||
| 379 | static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { | ||
| 380 | switch (GvVisibility) { | ||
| 381 | case GlobalValue::DefaultVisibility: | ||
| 382 | return WASM_SYMBOL_VISIBILITY_DEFAULT; | ||
| 383 | case GlobalValue::HiddenVisibility: | ||
| 384 | case GlobalValue::ProtectedVisibility: | ||
| 385 | return WASM_SYMBOL_VISIBILITY_HIDDEN; | ||
| 386 | } | ||
| 387 | llvm_unreachable("unknown visibility"); | ||
| 388 | } | ||
| 389 | |||
| 390 | static Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &ObjSym, | ||
| 391 | BitcodeFile &F) { | ||
| 392 | StringRef Name = Saver.save(ObjSym.getName()); | ||
| 393 | |||
| 394 | uint32_t Flags = ObjSym.isWeak() ? WASM_SYMBOL_BINDING_WEAK : 0; | ||
| 395 | Flags |= mapVisibility(ObjSym.getVisibility()); | ||
| 396 | |||
| 397 | if (ObjSym.isUndefined()) { | ||
| 398 | if (ObjSym.isExecutable()) | ||
| 399 | return Symtab->addUndefinedFunction(Name, Flags, &F, nullptr); | ||
| 400 | return Symtab->addUndefinedData(Name, Flags, &F); | ||
| 401 | } | ||
| 402 | |||
| 403 | if (ObjSym.isExecutable()) | ||
| 404 | return Symtab->addDefinedFunction(Name, Flags, &F, nullptr); | ||
| 405 | return Symtab->addDefinedData(Name, Flags, &F, nullptr, 0, 0); | ||
| 406 | } | ||
| 407 | |||
| 408 | void BitcodeFile::parse() { | ||
| 409 | Obj = check(lto::InputFile::create(MemoryBufferRef( | ||
| 410 | MB.getBuffer(), Saver.save(ArchiveName + MB.getBufferIdentifier())))); | ||
| 411 | Triple T(Obj->getTargetTriple()); | ||
| 412 | if (T.getArch() != Triple::wasm32) { | ||
| 413 | error(toString(MB.getBufferIdentifier()) + ": machine type must be wasm32"); | ||
| 295 | return; | 414 | return; |
| 296 | } | 415 | } |
| 297 | 416 | ||
| 298 | InputFile *Obj = make<ObjFile>(MB); | 417 | for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) |
| 299 | Obj->ParentName = ParentName; | 418 | Symbols.push_back(createBitcodeSymbol(ObjSym, *this)); |
| 300 | Symtab->addFile(Obj); | ||
| 301 | } | 419 | } |
| 302 | 420 | ||
| 303 | // Returns a string in the format of "foo.o" or "foo.a(bar.o)". | 421 | // Returns a string in the format of "foo.o" or "foo.a(bar.o)". |
| ... | @@ -305,8 +423,8 @@ std::string lld::toString(const wasm::InputFile *File) { | ... | @@ -305,8 +423,8 @@ std::string lld::toString(const wasm::InputFile *File) { |
| 305 | if (!File) | 423 | if (!File) |
| 306 | return "<internal>"; | 424 | return "<internal>"; |
| 307 | 425 | ||
| 308 | if (File->ParentName.empty()) | 426 | if (File->ArchiveName.empty()) |
| 309 | return File->getName(); | 427 | return File->getName(); |
| 310 | 428 | ||
| 311 | return (File->ParentName + "(" + File->getName() + ")").str(); | 429 | return (File->ArchiveName + "(" + File->getName() + ")").str(); |
| 312 | } | 430 | } |
deps/lld/wasm/InputFiles.h+54-41| ... | @@ -10,34 +10,46 @@ | ... | @@ -10,34 +10,46 @@ |
| 10 | #ifndef LLD_WASM_INPUT_FILES_H | 10 | #ifndef LLD_WASM_INPUT_FILES_H |
| 11 | #define LLD_WASM_INPUT_FILES_H | 11 | #define LLD_WASM_INPUT_FILES_H |
| 12 | 12 | ||
| 13 | #include "Symbols.h" | ||
| 13 | #include "lld/Common/LLVM.h" | 14 | #include "lld/Common/LLVM.h" |
| 14 | #include "llvm/ADT/DenseMap.h" | 15 | #include "llvm/ADT/DenseMap.h" |
| 15 | #include "llvm/ADT/DenseSet.h" | 16 | #include "llvm/ADT/DenseSet.h" |
| 17 | #include "llvm/LTO/LTO.h" | ||
| 16 | #include "llvm/Object/Archive.h" | 18 | #include "llvm/Object/Archive.h" |
| 17 | #include "llvm/Object/Wasm.h" | 19 | #include "llvm/Object/Wasm.h" |
| 18 | #include "llvm/Support/MemoryBuffer.h" | 20 | #include "llvm/Support/MemoryBuffer.h" |
| 19 | |||
| 20 | #include "WriterUtils.h" | ||
| 21 | |||
| 22 | #include <vector> | 21 | #include <vector> |
| 23 | 22 | ||
| 24 | using llvm::object::Archive; | 23 | using llvm::object::Archive; |
| 25 | using llvm::object::WasmObjectFile; | 24 | using llvm::object::WasmObjectFile; |
| 26 | using llvm::object::WasmSection; | 25 | using llvm::object::WasmSection; |
| 27 | using llvm::object::WasmSymbol; | 26 | using llvm::object::WasmSymbol; |
| 27 | using llvm::wasm::WasmGlobal; | ||
| 28 | using llvm::wasm::WasmImport; | 28 | using llvm::wasm::WasmImport; |
| 29 | using llvm::wasm::WasmRelocation; | ||
| 30 | using llvm::wasm::WasmSignature; | ||
| 31 | |||
| 32 | namespace llvm { | ||
| 33 | namespace lto { | ||
| 34 | class InputFile; | ||
| 35 | } | ||
| 36 | } // namespace llvm | ||
| 29 | 37 | ||
| 30 | namespace lld { | 38 | namespace lld { |
| 31 | namespace wasm { | 39 | namespace wasm { |
| 32 | 40 | ||
| 33 | class Symbol; | 41 | class InputChunk; |
| 42 | class InputFunction; | ||
| 34 | class InputSegment; | 43 | class InputSegment; |
| 44 | class InputGlobal; | ||
| 45 | class InputSection; | ||
| 35 | 46 | ||
| 36 | class InputFile { | 47 | class InputFile { |
| 37 | public: | 48 | public: |
| 38 | enum Kind { | 49 | enum Kind { |
| 39 | ObjectKind, | 50 | ObjectKind, |
| 40 | ArchiveKind, | 51 | ArchiveKind, |
| 52 | BitcodeKind, | ||
| 41 | }; | 53 | }; |
| 42 | 54 | ||
| 43 | virtual ~InputFile() {} | 55 | virtual ~InputFile() {} |
| ... | @@ -51,12 +63,17 @@ public: | ... | @@ -51,12 +63,17 @@ public: |
| 51 | Kind kind() const { return FileKind; } | 63 | Kind kind() const { return FileKind; } |
| 52 | 64 | ||
| 53 | // An archive file name if this file is created from an archive. | 65 | // An archive file name if this file is created from an archive. |
| 54 | StringRef ParentName; | 66 | StringRef ArchiveName; |
| 67 | |||
| 68 | ArrayRef<Symbol *> getSymbols() const { return Symbols; } | ||
| 55 | 69 | ||
| 56 | protected: | 70 | protected: |
| 57 | InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} | 71 | InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} |
| 58 | MemoryBufferRef MB; | 72 | MemoryBufferRef MB; |
| 59 | 73 | ||
| 74 | // List of all symbols referenced or defined by this file. | ||
| 75 | std::vector<Symbol *> Symbols; | ||
| 76 | |||
| 60 | private: | 77 | private: |
| 61 | const Kind FileKind; | 78 | const Kind FileKind; |
| 62 | }; | 79 | }; |
| ... | @@ -89,58 +106,54 @@ public: | ... | @@ -89,58 +106,54 @@ public: |
| 89 | 106 | ||
| 90 | void dumpInfo() const; | 107 | void dumpInfo() const; |
| 91 | 108 | ||
| 92 | uint32_t relocateTypeIndex(uint32_t Original) const; | 109 | uint32_t calcNewIndex(const WasmRelocation &Reloc) const; |
| 93 | uint32_t relocateFunctionIndex(uint32_t Original) const; | 110 | uint32_t calcNewValue(const WasmRelocation &Reloc) const; |
| 94 | uint32_t relocateGlobalIndex(uint32_t Original) const; | 111 | uint32_t calcNewAddend(const WasmRelocation &Reloc) const; |
| 95 | uint32_t relocateTableIndex(uint32_t Original) const; | 112 | uint32_t calcExpectedValue(const WasmRelocation &Reloc) const; |
| 96 | uint32_t getRelocatedAddress(uint32_t Index) const; | ||
| 97 | |||
| 98 | // Returns true if the given function index is an imported function, | ||
| 99 | // as opposed to the locally defined function. | ||
| 100 | bool isImportedFunction(uint32_t Index) const; | ||
| 101 | |||
| 102 | size_t NumFunctionImports() const { return FunctionImports; } | ||
| 103 | size_t NumGlobalImports() const { return GlobalImports; } | ||
| 104 | 113 | ||
| 105 | int32_t FunctionIndexOffset = 0; | ||
| 106 | const WasmSection *CodeSection = nullptr; | 114 | const WasmSection *CodeSection = nullptr; |
| 107 | std::vector<OutputRelocation> CodeRelocations; | ||
| 108 | int32_t CodeOffset = 0; | ||
| 109 | const WasmSection *DataSection = nullptr; | 115 | const WasmSection *DataSection = nullptr; |
| 110 | 116 | ||
| 117 | // Maps input type indices to output type indices | ||
| 111 | std::vector<uint32_t> TypeMap; | 118 | std::vector<uint32_t> TypeMap; |
| 119 | std::vector<bool> TypeIsUsed; | ||
| 120 | // Maps function indices to table indices | ||
| 121 | std::vector<uint32_t> TableEntries; | ||
| 122 | std::vector<bool> UsedComdats; | ||
| 112 | std::vector<InputSegment *> Segments; | 123 | std::vector<InputSegment *> Segments; |
| 124 | std::vector<InputFunction *> Functions; | ||
| 125 | std::vector<InputGlobal *> Globals; | ||
| 126 | std::vector<InputSection *> CustomSections; | ||
| 127 | llvm::DenseMap<uint32_t, InputSection *> CustomSectionsByIndex; | ||
| 113 | 128 | ||
| 114 | ArrayRef<Symbol *> getSymbols() { return Symbols; } | 129 | Symbol *getSymbol(uint32_t Index) const { return Symbols[Index]; } |
| 115 | ArrayRef<Symbol *> getTableSymbols() { return TableSymbols; } | 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; | ||
| 116 | 134 | ||
| 117 | private: | 135 | private: |
| 118 | Symbol *createDefined(const WasmSymbol &Sym, | 136 | Symbol *createDefined(const WasmSymbol &Sym); |
| 119 | const InputSegment *Segment = nullptr); | ||
| 120 | Symbol *createUndefined(const WasmSymbol &Sym); | 137 | Symbol *createUndefined(const WasmSymbol &Sym); |
| 121 | void initializeSymbols(); | ||
| 122 | InputSegment *getSegment(const WasmSymbol &WasmSym); | ||
| 123 | Symbol *getFunctionSymbol(uint32_t FunctionIndex) const; | ||
| 124 | Symbol *getTableSymbol(uint32_t TableIndex) const; | ||
| 125 | Symbol *getGlobalSymbol(uint32_t GlobalIndex) const; | ||
| 126 | 138 | ||
| 127 | // List of all symbols referenced or defined by this file. | 139 | bool isExcludedByComdat(InputChunk *Chunk) const; |
| 128 | std::vector<Symbol *> Symbols; | ||
| 129 | |||
| 130 | // List of all function symbols indexed by the function index space | ||
| 131 | std::vector<Symbol *> FunctionSymbols; | ||
| 132 | 140 | ||
| 133 | // List of all global symbols indexed by the global index space | 141 | std::unique_ptr<WasmObjectFile> WasmObj; |
| 134 | std::vector<Symbol *> GlobalSymbols; | 142 | }; |
| 135 | 143 | ||
| 136 | // List of all indirect symbols indexed by table index space. | 144 | class BitcodeFile : public InputFile { |
| 137 | std::vector<Symbol *> TableSymbols; | 145 | public: |
| 146 | explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {} | ||
| 147 | static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } | ||
| 138 | 148 | ||
| 139 | uint32_t GlobalImports = 0; | 149 | void parse() override; |
| 140 | uint32_t FunctionImports = 0; | 150 | std::unique_ptr<llvm::lto::InputFile> Obj; |
| 141 | std::unique_ptr<WasmObjectFile> WasmObj; | ||
| 142 | }; | 151 | }; |
| 143 | 152 | ||
| 153 | // Will report a fatal() error if the input buffer is not a valid bitcode | ||
| 154 | // or was object file. | ||
| 155 | InputFile *createObjectFile(MemoryBufferRef MB); | ||
| 156 | |||
| 144 | // Opens a given file. | 157 | // Opens a given file. |
| 145 | llvm::Optional<MemoryBufferRef> readFile(StringRef Path); | 158 | llvm::Optional<MemoryBufferRef> readFile(StringRef Path); |
| 146 | 159 |
deps/lld/wasm/InputGlobal.h created+59| ... | @@ -0,0 +1,59 @@ | ||
| 1 | //===- InputGlobal.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_WASM_INPUT_GLOBAL_H | ||
| 11 | #define LLD_WASM_INPUT_GLOBAL_H | ||
| 12 | |||
| 13 | #include "Config.h" | ||
| 14 | #include "InputFiles.h" | ||
| 15 | #include "WriterUtils.h" | ||
| 16 | #include "lld/Common/ErrorHandler.h" | ||
| 17 | #include "llvm/Object/Wasm.h" | ||
| 18 | |||
| 19 | using llvm::wasm::WasmGlobal; | ||
| 20 | using llvm::wasm::WasmInitExpr; | ||
| 21 | |||
| 22 | namespace lld { | ||
| 23 | namespace wasm { | ||
| 24 | |||
| 25 | // Represents a single Wasm Global Variable within an input file. These are | ||
| 26 | // combined to form the final GLOBALS section. | ||
| 27 | class InputGlobal { | ||
| 28 | public: | ||
| 29 | InputGlobal(const WasmGlobal &G, ObjFile *F) | ||
| 30 | : File(F), Global(G), Live(!Config->GcSections) {} | ||
| 31 | |||
| 32 | StringRef getName() const { return Global.SymbolName; } | ||
| 33 | const WasmGlobalType &getType() const { return Global.Type; } | ||
| 34 | |||
| 35 | uint32_t getGlobalIndex() const { return GlobalIndex.getValue(); } | ||
| 36 | bool hasGlobalIndex() const { return GlobalIndex.hasValue(); } | ||
| 37 | void setGlobalIndex(uint32_t Index) { | ||
| 38 | assert(!hasGlobalIndex()); | ||
| 39 | GlobalIndex = Index; | ||
| 40 | } | ||
| 41 | |||
| 42 | ObjFile *File; | ||
| 43 | WasmGlobal Global; | ||
| 44 | |||
| 45 | bool Live = false; | ||
| 46 | |||
| 47 | protected: | ||
| 48 | llvm::Optional<uint32_t> GlobalIndex; | ||
| 49 | }; | ||
| 50 | |||
| 51 | } // namespace wasm | ||
| 52 | |||
| 53 | inline std::string toString(const wasm::InputGlobal *G) { | ||
| 54 | return (toString(G->File) + ":(" + G->getName() + ")").str(); | ||
| 55 | } | ||
| 56 | |||
| 57 | } // namespace lld | ||
| 58 | |||
| 59 | #endif // LLD_WASM_INPUT_GLOBAL_H | ||
deps/lld/wasm/InputSegment.cpp deleted-25| ... | @@ -1,25 +0,0 @@ | ||
| 1 | //===- InputSegment.cpp ---------------------------------------------------===// | ||
| 2 | // | ||
| 3 | // The LLVM Linker | ||
| 4 | // | ||
| 5 | // This file is distributed under the University of Illinois Open Source | ||
| 6 | // License. See LICENSE.TXT for details. | ||
| 7 | // | ||
| 8 | //===----------------------------------------------------------------------===// | ||
| 9 | |||
| 10 | #include "InputSegment.h" | ||
| 11 | #include "OutputSegment.h" | ||
| 12 | #include "lld/Common/LLVM.h" | ||
| 13 | |||
| 14 | #define DEBUG_TYPE "lld" | ||
| 15 | |||
| 16 | using namespace llvm; | ||
| 17 | using namespace lld::wasm; | ||
| 18 | |||
| 19 | uint32_t InputSegment::translateVA(uint32_t Address) const { | ||
| 20 | assert(Address >= startVA() && Address < endVA()); | ||
| 21 | int32_t Delta = OutputSeg->StartVA + OutputSegmentOffset - startVA(); | ||
| 22 | DEBUG(dbgs() << "translateVA: " << getName() << " Delta=" << Delta | ||
| 23 | << " Address=" << Address << "\n"); | ||
| 24 | return Address + Delta; | ||
| 25 | } | ||
deps/lld/wasm/InputSegment.h deleted-76| ... | @@ -1,76 +0,0 @@ | ||
| 1 | //===- InputSegment.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 | // Represents a WebAssembly data segment which can be included as part of | ||
| 11 | // an output data segments. Note that in WebAssembly, unlike ELF and other | ||
| 12 | // formats, used the term "data segment" to refer to the continous regions of | ||
| 13 | // memory that make on the data section. See: | ||
| 14 | // https://webassembly.github.io/spec/syntax/modules.html#syntax-data | ||
| 15 | // | ||
| 16 | // For example, by default, clang will produce a separate data section for | ||
| 17 | // each global variable. | ||
| 18 | // | ||
| 19 | //===----------------------------------------------------------------------===// | ||
| 20 | |||
| 21 | #ifndef LLD_WASM_INPUT_SEGMENT_H | ||
| 22 | #define LLD_WASM_INPUT_SEGMENT_H | ||
| 23 | |||
| 24 | #include "WriterUtils.h" | ||
| 25 | #include "lld/Common/ErrorHandler.h" | ||
| 26 | #include "llvm/Object/Wasm.h" | ||
| 27 | |||
| 28 | using llvm::object::WasmSegment; | ||
| 29 | using llvm::wasm::WasmRelocation; | ||
| 30 | |||
| 31 | namespace lld { | ||
| 32 | namespace wasm { | ||
| 33 | |||
| 34 | class ObjFile; | ||
| 35 | class OutputSegment; | ||
| 36 | |||
| 37 | class InputSegment { | ||
| 38 | public: | ||
| 39 | InputSegment(const WasmSegment *Seg, const ObjFile *F) | ||
| 40 | : Segment(Seg), File(F) {} | ||
| 41 | |||
| 42 | // Translate an offset in the input segment to an offset in the output | ||
| 43 | // segment. | ||
| 44 | uint32_t translateVA(uint32_t Address) const; | ||
| 45 | |||
| 46 | const OutputSegment *getOutputSegment() const { return OutputSeg; } | ||
| 47 | |||
| 48 | uint32_t getOutputSegmentOffset() const { return OutputSegmentOffset; } | ||
| 49 | |||
| 50 | uint32_t getInputSectionOffset() const { return Segment->SectionOffset; } | ||
| 51 | |||
| 52 | void setOutputSegment(const OutputSegment *Segment, uint32_t Offset) { | ||
| 53 | OutputSeg = Segment; | ||
| 54 | OutputSegmentOffset = Offset; | ||
| 55 | } | ||
| 56 | |||
| 57 | uint32_t getSize() const { return Segment->Data.Content.size(); } | ||
| 58 | uint32_t getAlignment() const { return Segment->Data.Alignment; } | ||
| 59 | uint32_t startVA() const { return Segment->Data.Offset.Value.Int32; } | ||
| 60 | uint32_t endVA() const { return startVA() + getSize(); } | ||
| 61 | StringRef getName() const { return Segment->Data.Name; } | ||
| 62 | |||
| 63 | const WasmSegment *Segment; | ||
| 64 | const ObjFile *File; | ||
| 65 | std::vector<WasmRelocation> Relocations; | ||
| 66 | std::vector<OutputRelocation> OutRelocations; | ||
| 67 | |||
| 68 | protected: | ||
| 69 | const OutputSegment *OutputSeg = nullptr; | ||
| 70 | uint32_t OutputSegmentOffset = 0; | ||
| 71 | }; | ||
| 72 | |||
| 73 | } // namespace wasm | ||
| 74 | } // namespace lld | ||
| 75 | |||
| 76 | #endif // LLD_WASM_INPUT_SEGMENT_H | ||
deps/lld/wasm/LTO.cpp created+155| ... | @@ -0,0 +1,155 @@ | ||
| 1 | //===- LTO.cpp ------------------------------------------------------------===// | ||
| 2 | // | ||
| 3 | // The LLVM Linker | ||
| 4 | // | ||
| 5 | // This file is distributed under the University of Illinois Open Source | ||
| 6 | // License. See LICENSE.TXT for details. | ||
| 7 | // | ||
| 8 | //===----------------------------------------------------------------------===// | ||
| 9 | |||
| 10 | #include "LTO.h" | ||
| 11 | #include "Config.h" | ||
| 12 | #include "InputFiles.h" | ||
| 13 | #include "Symbols.h" | ||
| 14 | #include "lld/Common/ErrorHandler.h" | ||
| 15 | #include "lld/Common/Strings.h" | ||
| 16 | #include "lld/Common/TargetOptionsCommandFlags.h" | ||
| 17 | #include "llvm/ADT/STLExtras.h" | ||
| 18 | #include "llvm/ADT/SmallString.h" | ||
| 19 | #include "llvm/ADT/StringRef.h" | ||
| 20 | #include "llvm/ADT/Twine.h" | ||
| 21 | #include "llvm/IR/DiagnosticPrinter.h" | ||
| 22 | #include "llvm/LTO/Caching.h" | ||
| 23 | #include "llvm/LTO/Config.h" | ||
| 24 | #include "llvm/LTO/LTO.h" | ||
| 25 | #include "llvm/Object/SymbolicFile.h" | ||
| 26 | #include "llvm/Support/CodeGen.h" | ||
| 27 | #include "llvm/Support/Error.h" | ||
| 28 | #include "llvm/Support/FileSystem.h" | ||
| 29 | #include "llvm/Support/MemoryBuffer.h" | ||
| 30 | #include "llvm/Support/raw_ostream.h" | ||
| 31 | #include <algorithm> | ||
| 32 | #include <cstddef> | ||
| 33 | #include <memory> | ||
| 34 | #include <string> | ||
| 35 | #include <system_error> | ||
| 36 | #include <vector> | ||
| 37 | |||
| 38 | using namespace llvm; | ||
| 39 | using namespace llvm::object; | ||
| 40 | |||
| 41 | using namespace lld; | ||
| 42 | using namespace lld::wasm; | ||
| 43 | |||
| 44 | static std::unique_ptr<lto::LTO> createLTO() { | ||
| 45 | lto::Config C; | ||
| 46 | C.Options = InitTargetOptionsFromCodeGenFlags(); | ||
| 47 | |||
| 48 | // Always emit a section per function/data with LTO. | ||
| 49 | C.Options.FunctionSections = true; | ||
| 50 | C.Options.DataSections = true; | ||
| 51 | |||
| 52 | // Wasm currently only supports ThreadModel::Single | ||
| 53 | C.Options.ThreadModel = ThreadModel::Single; | ||
| 54 | |||
| 55 | C.DisableVerify = Config->DisableVerify; | ||
| 56 | C.DiagHandler = diagnosticHandler; | ||
| 57 | C.OptLevel = Config->LTOO; | ||
| 58 | |||
| 59 | if (Config->SaveTemps) | ||
| 60 | checkError(C.addSaveTemps(Config->OutputFile.str() + ".", | ||
| 61 | /*UseInputModulePath*/ true)); | ||
| 62 | |||
| 63 | lto::ThinBackend Backend; | ||
| 64 | if (Config->ThinLTOJobs != -1U) | ||
| 65 | Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs); | ||
| 66 | return llvm::make_unique<lto::LTO>(std::move(C), Backend, | ||
| 67 | Config->LTOPartitions); | ||
| 68 | } | ||
| 69 | |||
| 70 | BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {} | ||
| 71 | |||
| 72 | BitcodeCompiler::~BitcodeCompiler() = default; | ||
| 73 | |||
| 74 | static void undefine(Symbol *S) { | ||
| 75 | if (isa<DefinedFunction>(S)) | ||
| 76 | replaceSymbol<UndefinedFunction>(S, S->getName(), 0); | ||
| 77 | else if (isa<DefinedData>(S)) | ||
| 78 | replaceSymbol<UndefinedData>(S, S->getName(), 0); | ||
| 79 | else | ||
| 80 | llvm_unreachable("unexpected symbol kind"); | ||
| 81 | } | ||
| 82 | |||
| 83 | void BitcodeCompiler::add(BitcodeFile &F) { | ||
| 84 | lto::InputFile &Obj = *F.Obj; | ||
| 85 | unsigned SymNum = 0; | ||
| 86 | ArrayRef<Symbol *> Syms = F.getSymbols(); | ||
| 87 | std::vector<lto::SymbolResolution> Resols(Syms.size()); | ||
| 88 | |||
| 89 | // Provide a resolution to the LTO API for each symbol. | ||
| 90 | for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { | ||
| 91 | Symbol *Sym = Syms[SymNum]; | ||
| 92 | lto::SymbolResolution &R = Resols[SymNum]; | ||
| 93 | ++SymNum; | ||
| 94 | |||
| 95 | // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile | ||
| 96 | // reports two symbols for module ASM defined. Without this check, lld | ||
| 97 | // flags an undefined in IR with a definition in ASM as prevailing. | ||
| 98 | // Once IRObjectFile is fixed to report only one symbol this hack can | ||
| 99 | // be removed. | ||
| 100 | R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F; | ||
| 101 | R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj || | ||
| 102 | (R.Prevailing && Sym->isExported()); | ||
| 103 | if (R.Prevailing) | ||
| 104 | undefine(Sym); | ||
| 105 | } | ||
| 106 | checkError(LTOObj->add(std::move(F.Obj), Resols)); | ||
| 107 | } | ||
| 108 | |||
| 109 | // Merge all the bitcode files we have seen, codegen the result | ||
| 110 | // and return the resulting objects. | ||
| 111 | std::vector<StringRef> BitcodeCompiler::compile() { | ||
| 112 | unsigned MaxTasks = LTOObj->getMaxTasks(); | ||
| 113 | Buf.resize(MaxTasks); | ||
| 114 | Files.resize(MaxTasks); | ||
| 115 | |||
| 116 | // The --thinlto-cache-dir option specifies the path to a directory in which | ||
| 117 | // to cache native object files for ThinLTO incremental builds. If a path was | ||
| 118 | // specified, configure LTO to use it as the cache directory. | ||
| 119 | lto::NativeObjectCache Cache; | ||
| 120 | if (!Config->ThinLTOCacheDir.empty()) | ||
| 121 | Cache = check( | ||
| 122 | lto::localCache(Config->ThinLTOCacheDir, | ||
| 123 | [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) { | ||
| 124 | Files[Task] = std::move(MB); | ||
| 125 | })); | ||
| 126 | |||
| 127 | checkError(LTOObj->run( | ||
| 128 | [&](size_t Task) { | ||
| 129 | return llvm::make_unique<lto::NativeObjectStream>( | ||
| 130 | llvm::make_unique<raw_svector_ostream>(Buf[Task])); | ||
| 131 | }, | ||
| 132 | Cache)); | ||
| 133 | |||
| 134 | if (!Config->ThinLTOCacheDir.empty()) | ||
| 135 | pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy); | ||
| 136 | |||
| 137 | std::vector<StringRef> Ret; | ||
| 138 | for (unsigned I = 0; I != MaxTasks; ++I) { | ||
| 139 | if (Buf[I].empty()) | ||
| 140 | continue; | ||
| 141 | if (Config->SaveTemps) { | ||
| 142 | if (I == 0) | ||
| 143 | saveBuffer(Buf[I], Config->OutputFile + ".lto.o"); | ||
| 144 | else | ||
| 145 | saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o"); | ||
| 146 | } | ||
| 147 | Ret.emplace_back(Buf[I].data(), Buf[I].size()); | ||
| 148 | } | ||
| 149 | |||
| 150 | for (std::unique_ptr<MemoryBuffer> &File : Files) | ||
| 151 | if (File) | ||
| 152 | Ret.push_back(File->getBuffer()); | ||
| 153 | |||
| 154 | return Ret; | ||
| 155 | } | ||
deps/lld/wasm/LTO.h created+57| ... | @@ -0,0 +1,57 @@ | ||
| 1 | //===- LTO.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 | // This file provides a way to combine bitcode files into one wasm | ||
| 11 | // file by compiling them using LLVM. | ||
| 12 | // | ||
| 13 | // If LTO is in use, your input files are not in regular wasm files | ||
| 14 | // but instead LLVM bitcode files. In that case, the linker has to | ||
| 15 | // convert bitcode files into the native format so that we can create | ||
| 16 | // a wasm file that contains native code. This file provides that | ||
| 17 | // functionality. | ||
| 18 | // | ||
| 19 | //===----------------------------------------------------------------------===// | ||
| 20 | |||
| 21 | #ifndef LLD_WASM_LTO_H | ||
| 22 | #define LLD_WASM_LTO_H | ||
| 23 | |||
| 24 | #include "lld/Common/LLVM.h" | ||
| 25 | #include "llvm/ADT/SmallString.h" | ||
| 26 | #include <memory> | ||
| 27 | #include <vector> | ||
| 28 | |||
| 29 | namespace llvm { | ||
| 30 | namespace lto { | ||
| 31 | class LTO; | ||
| 32 | } | ||
| 33 | } // namespace llvm | ||
| 34 | |||
| 35 | namespace lld { | ||
| 36 | namespace wasm { | ||
| 37 | |||
| 38 | class BitcodeFile; | ||
| 39 | class InputFile; | ||
| 40 | |||
| 41 | class BitcodeCompiler { | ||
| 42 | public: | ||
| 43 | BitcodeCompiler(); | ||
| 44 | ~BitcodeCompiler(); | ||
| 45 | |||
| 46 | void add(BitcodeFile &F); | ||
| 47 | std::vector<StringRef> compile(); | ||
| 48 | |||
| 49 | private: | ||
| 50 | std::unique_ptr<llvm::lto::LTO> LTOObj; | ||
| 51 | std::vector<SmallString<0>> Buf; | ||
| 52 | std::vector<std::unique_ptr<MemoryBuffer>> Files; | ||
| 53 | }; | ||
| 54 | } // namespace wasm | ||
| 55 | } // namespace lld | ||
| 56 | |||
| 57 | #endif | ||
deps/lld/wasm/MarkLive.cpp created+118| ... | @@ -0,0 +1,118 @@ | ||
| 1 | //===- MarkLive.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 implements --gc-sections, which is a feature to remove unused | ||
| 11 | // chunks from the output. Unused chunks are those that are not reachable from | ||
| 12 | // known root symbols or chunks. This feature is implemented as a mark-sweep | ||
| 13 | // garbage collector. | ||
| 14 | // | ||
| 15 | // Here's how it works. Each InputChunk has a "Live" bit. The bit is off by | ||
| 16 | // default. Starting with the GC-roots, visit all reachable chunks and set their | ||
| 17 | // Live bits. The Writer will then ignore chunks whose Live bits are off, so | ||
| 18 | // that such chunk are not appear in the output. | ||
| 19 | // | ||
| 20 | //===----------------------------------------------------------------------===// | ||
| 21 | |||
| 22 | #include "MarkLive.h" | ||
| 23 | #include "Config.h" | ||
| 24 | #include "InputChunks.h" | ||
| 25 | #include "InputGlobal.h" | ||
| 26 | #include "SymbolTable.h" | ||
| 27 | #include "Symbols.h" | ||
| 28 | |||
| 29 | #define DEBUG_TYPE "lld" | ||
| 30 | |||
| 31 | using namespace llvm; | ||
| 32 | using namespace llvm::wasm; | ||
| 33 | using namespace lld; | ||
| 34 | using namespace lld::wasm; | ||
| 35 | |||
| 36 | void lld::wasm::markLive() { | ||
| 37 | if (!Config->GcSections) | ||
| 38 | return; | ||
| 39 | |||
| 40 | LLVM_DEBUG(dbgs() << "markLive\n"); | ||
| 41 | SmallVector<InputChunk *, 256> Q; | ||
| 42 | |||
| 43 | auto Enqueue = [&](Symbol *Sym) { | ||
| 44 | if (!Sym || Sym->isLive()) | ||
| 45 | return; | ||
| 46 | LLVM_DEBUG(dbgs() << "markLive: " << Sym->getName() << "\n"); | ||
| 47 | Sym->markLive(); | ||
| 48 | if (InputChunk *Chunk = Sym->getChunk()) | ||
| 49 | Q.push_back(Chunk); | ||
| 50 | }; | ||
| 51 | |||
| 52 | // Add GC root symbols. | ||
| 53 | if (!Config->Entry.empty()) | ||
| 54 | Enqueue(Symtab->find(Config->Entry)); | ||
| 55 | Enqueue(WasmSym::CallCtors); | ||
| 56 | |||
| 57 | // We need to preserve any exported symbol | ||
| 58 | for (Symbol *Sym : Symtab->getSymbols()) | ||
| 59 | if (Sym->isExported()) | ||
| 60 | Enqueue(Sym); | ||
| 61 | |||
| 62 | // The ctor functions are all used in the synthetic __wasm_call_ctors | ||
| 63 | // function, but since this function is created in-place it doesn't contain | ||
| 64 | // relocations which mean we have to manually mark the ctors. | ||
| 65 | for (const ObjFile *Obj : Symtab->ObjectFiles) { | ||
| 66 | const WasmLinkingData &L = Obj->getWasmObj()->linkingData(); | ||
| 67 | for (const WasmInitFunc &F : L.InitFunctions) | ||
| 68 | Enqueue(Obj->getFunctionSymbol(F.Symbol)); | ||
| 69 | } | ||
| 70 | |||
| 71 | // Follow relocations to mark all reachable chunks. | ||
| 72 | while (!Q.empty()) { | ||
| 73 | InputChunk *C = Q.pop_back_val(); | ||
| 74 | |||
| 75 | for (const WasmRelocation Reloc : C->getRelocations()) { | ||
| 76 | if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) | ||
| 77 | continue; | ||
| 78 | Symbol *Sym = C->File->getSymbol(Reloc.Index); | ||
| 79 | |||
| 80 | // If the function has been assigned the special index zero in the table, | ||
| 81 | // the relocation doesn't pull in the function body, since the function | ||
| 82 | // won't actually go in the table (the runtime will trap attempts to call | ||
| 83 | // that index, since we don't use it). A function with a table index of | ||
| 84 | // zero is only reachable via "call", not via "call_indirect". The stub | ||
| 85 | // functions used for weak-undefined symbols have this behaviour (compare | ||
| 86 | // equal to null pointer, only reachable via direct call). | ||
| 87 | if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB || | ||
| 88 | Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32) { | ||
| 89 | FunctionSymbol *FuncSym = cast<FunctionSymbol>(Sym); | ||
| 90 | if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0) | ||
| 91 | continue; | ||
| 92 | } | ||
| 93 | |||
| 94 | Enqueue(Sym); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | // Report garbage-collected sections. | ||
| 99 | if (Config->PrintGcSections) { | ||
| 100 | for (const ObjFile *Obj : Symtab->ObjectFiles) { | ||
| 101 | for (InputChunk *C : Obj->Functions) | ||
| 102 | if (!C->Live) | ||
| 103 | message("removing unused section " + toString(C)); | ||
| 104 | for (InputChunk *C : Obj->Segments) | ||
| 105 | if (!C->Live) | ||
| 106 | message("removing unused section " + toString(C)); | ||
| 107 | for (InputGlobal *G : Obj->Globals) | ||
| 108 | if (!G->Live) | ||
| 109 | message("removing unused section " + toString(G)); | ||
| 110 | } | ||
| 111 | for (InputChunk *C : Symtab->SyntheticFunctions) | ||
| 112 | if (!C->Live) | ||
| 113 | message("removing unused section " + toString(C)); | ||
| 114 | for (InputGlobal *G : Symtab->SyntheticGlobals) | ||
| 115 | if (!G->Live) | ||
| 116 | message("removing unused section " + toString(G)); | ||
| 117 | } | ||
| 118 | } | ||
deps/lld/wasm/MarkLive.h created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | //===- MarkLive.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_WASM_MARKLIVE_H | ||
| 11 | #define LLD_WASM_MARKLIVE_H | ||
| 12 | |||
| 13 | namespace lld { | ||
| 14 | namespace wasm { | ||
| 15 | |||
| 16 | void markLive(); | ||
| 17 | |||
| 18 | } // namespace wasm | ||
| 19 | } // namespace lld | ||
| 20 | |||
| 21 | #endif // LLD_WASM_MARKLIVE_H | ||
deps/lld/wasm/Options.td+87-32| ... | @@ -11,21 +11,47 @@ multiclass Eq<string name> { | ... | @@ -11,21 +11,47 @@ multiclass Eq<string name> { |
| 11 | def _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>; | 11 | def _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>; |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">, | 14 | multiclass B<string name, string help1, string help2> { |
| 15 | HelpText<"Add a directory to the library search path">; | 15 | def NAME: Flag<["--", "-"], name>, HelpText<help1>; |
| 16 | def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>; | ||
| 17 | } | ||
| 16 | 18 | ||
| 19 | // The follow flags are shared with the ELF linker | ||
| 17 | def color_diagnostics: F<"color-diagnostics">, | 20 | def color_diagnostics: F<"color-diagnostics">, |
| 18 | HelpText<"Use colors in diagnostics">; | 21 | HelpText<"Use colors in diagnostics">; |
| 19 | 22 | ||
| 20 | def color_diagnostics_eq: J<"color-diagnostics=">, | 23 | def color_diagnostics_eq: J<"color-diagnostics=">, |
| 21 | HelpText<"Use colors in diagnostics">; | 24 | HelpText<"Use colors in diagnostics; one of 'always', 'never', 'auto'">; |
| 25 | |||
| 26 | defm demangle: B<"demangle", | ||
| 27 | "Demangle symbol names", | ||
| 28 | "Do not demangle symbol names">; | ||
| 29 | |||
| 30 | def entry: S<"entry">, MetaVarName<"<entry>">, | ||
| 31 | HelpText<"Name of entry point symbol">; | ||
| 32 | |||
| 33 | def error_limit: J<"error-limit=">, | ||
| 34 | HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">; | ||
| 35 | |||
| 36 | def fatal_warnings: F<"fatal-warnings">, | ||
| 37 | HelpText<"Treat warnings as errors">; | ||
| 38 | |||
| 39 | defm gc_sections: B<"gc-sections", | ||
| 40 | "Enable garbage collection of unused sections", | ||
| 41 | "Disable garbage collection of unused sections">; | ||
| 42 | |||
| 43 | defm merge_data_segments: B<"merge-data-segments", | ||
| 44 | "Enable merging data segments", | ||
| 45 | "Disable merging data segments">; | ||
| 22 | 46 | ||
| 23 | // The follow flags are shared with the ELF linker | ||
| 24 | def help: F<"help">, HelpText<"Print option help">; | 47 | def help: F<"help">, HelpText<"Print option help">; |
| 25 | 48 | ||
| 26 | def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">, | 49 | def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">, |
| 27 | HelpText<"Root name of library to use">; | 50 | HelpText<"Root name of library to use">; |
| 28 | 51 | ||
| 52 | def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">, | ||
| 53 | HelpText<"Add a directory to the library search path">; | ||
| 54 | |||
| 29 | def mllvm: S<"mllvm">, HelpText<"Options to pass to LLVM">; | 55 | def mllvm: S<"mllvm">, HelpText<"Options to pass to LLVM">; |
| 30 | 56 | ||
| 31 | def no_threads: F<"no-threads">, | 57 | def no_threads: F<"no-threads">, |
| ... | @@ -34,70 +60,99 @@ def no_threads: F<"no-threads">, | ... | @@ -34,70 +60,99 @@ def no_threads: F<"no-threads">, |
| 34 | def no_color_diagnostics: F<"no-color-diagnostics">, | 60 | def no_color_diagnostics: F<"no-color-diagnostics">, |
| 35 | HelpText<"Do not use colors in diagnostics">; | 61 | HelpText<"Do not use colors in diagnostics">; |
| 36 | 62 | ||
| 37 | def no_check_signatures: F<"no-check-signatures">, HelpText<"Don't check function signatures">; | 63 | def no_fatal_warnings: F<"no-fatal-warnings">; |
| 38 | 64 | ||
| 39 | def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">, | 65 | def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">, |
| 40 | HelpText<"Path to file to write output">; | 66 | HelpText<"Path to file to write output">; |
| 41 | 67 | ||
| 42 | def threads: F<"threads">, HelpText<"Run the linker multi-threaded">; | 68 | def O: JoinedOrSeparate<["-"], "O">, HelpText<"Optimize output file size">; |
| 43 | 69 | ||
| 44 | def check_signatures: F<"check-signatures">, HelpText<"Check function signatures">; | 70 | defm print_gc_sections: B<"print-gc-sections", |
| 45 | 71 | "List removed unused sections", | |
| 46 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; | 72 | "Do not list removed unused sections">; |
| 47 | |||
| 48 | def version: F<"version">, HelpText<"Display the version number and exit">; | ||
| 49 | |||
| 50 | def verbose: F<"verbose">, HelpText<"Verbose mode">; | ||
| 51 | 73 | ||
| 52 | def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">; | 74 | def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">; |
| 53 | 75 | ||
| 54 | def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">; | ||
| 55 | |||
| 56 | def strip_all: F<"strip-all">, HelpText<"Strip all symbols">; | 76 | def strip_all: F<"strip-all">, HelpText<"Strip all symbols">; |
| 57 | 77 | ||
| 58 | def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">; | 78 | def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">; |
| 59 | 79 | ||
| 80 | def threads: F<"threads">, HelpText<"Run the linker multi-threaded">; | ||
| 81 | |||
| 60 | defm undefined: Eq<"undefined">, | 82 | defm undefined: Eq<"undefined">, |
| 61 | HelpText<"Force undefined symbol during linking">; | 83 | HelpText<"Force undefined symbol during linking">; |
| 62 | 84 | ||
| 85 | def v: Flag<["-"], "v">, HelpText<"Display the version number">; | ||
| 86 | |||
| 87 | def verbose: F<"verbose">, HelpText<"Verbose mode">; | ||
| 88 | |||
| 89 | def version: F<"version">, HelpText<"Display the version number and exit">; | ||
| 90 | |||
| 63 | def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, | 91 | def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, |
| 64 | HelpText<"Linker option extensions">; | 92 | HelpText<"Linker option extensions">; |
| 65 | 93 | ||
| 66 | def entry: S<"entry">, MetaVarName<"<entry>">, | 94 | // The follow flags are unique to wasm |
| 67 | HelpText<"Name of entry point symbol">; | ||
| 68 | 95 | ||
| 69 | def no_entry: F<"no-entry">, | 96 | def allow_undefined: F<"allow-undefined">, |
| 70 | HelpText<"Do not output any entry point">; | 97 | HelpText<"Allow undefined symbols in linked binary">; |
| 71 | 98 | ||
| 72 | def error_limit: J<"error-limit=">, | 99 | def allow_undefined_file: J<"allow-undefined-file=">, |
| 73 | HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">; | 100 | HelpText<"Allow symbols listed in <file> to be undefined in linked binary">; |
| 74 | 101 | ||
| 75 | // The follow flags are unique to wasm | 102 | def allow_undefined_file_s: Separate<["-"], "allow-undefined-file">, |
| 103 | Alias<allow_undefined_file>; | ||
| 104 | |||
| 105 | defm export: Eq<"export">, | ||
| 106 | HelpText<"Force a symbol to be exported">; | ||
| 107 | |||
| 108 | def export_all: F<"export-all">, | ||
| 109 | HelpText<"Export all symbols (normally combined with --no-gc-sections)">; | ||
| 110 | |||
| 111 | def export_table: F<"export-table">, | ||
| 112 | HelpText<"Export function table to the environment">; | ||
| 76 | 113 | ||
| 77 | def global_base: J<"global-base=">, | 114 | def global_base: J<"global-base=">, |
| 78 | HelpText<"Where to start to place global data">; | 115 | HelpText<"Where to start to place global data">; |
| 79 | 116 | ||
| 117 | def import_memory: F<"import-memory">, | ||
| 118 | HelpText<"Import memory from the environment">; | ||
| 119 | |||
| 120 | def import_table: F<"import-table">, | ||
| 121 | HelpText<"Import function table from the environment">; | ||
| 122 | |||
| 80 | def initial_memory: J<"initial-memory=">, | 123 | def initial_memory: J<"initial-memory=">, |
| 81 | HelpText<"Initial size of the linear memory">; | 124 | HelpText<"Initial size of the linear memory">; |
| 82 | 125 | ||
| 83 | def max_memory: J<"max-memory=">, | 126 | def max_memory: J<"max-memory=">, |
| 84 | HelpText<"Maximum size of the linear memory">; | 127 | HelpText<"Maximum size of the linear memory">; |
| 85 | 128 | ||
| 86 | def import_memory: F<"import-memory">, | 129 | def no_entry: F<"no-entry">, |
| 87 | HelpText<"Import memory from the environment">; | 130 | HelpText<"Do not output any entry point">; |
| 88 | |||
| 89 | def allow_undefined: F<"allow-undefined">, | ||
| 90 | HelpText<"Allow undefined symbols in linked binary">; | ||
| 91 | 131 | ||
| 92 | def allow_undefined_file: J<"allow-undefined-file=">, | 132 | def stack_first: F<"stack-first">, |
| 93 | HelpText<"Allow symbols listed in <file> to be undefined in linked binary">; | 133 | HelpText<"Place stack at start of linear memory rather than after data">; |
| 94 | 134 | ||
| 95 | def allow_undefined_file_s: Separate<["-"], "allow-undefined-file">, Alias<allow_undefined_file>; | 135 | defm whole_archive: B<"whole-archive", |
| 136 | "Force load of all members in a static library", | ||
| 137 | "Do not force load of all members in a static library (default)">; | ||
| 96 | 138 | ||
| 97 | // Aliases | 139 | // Aliases |
| 140 | def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>; | ||
| 141 | def alias_entry_entry: J<"entry=">, Alias<entry>; | ||
| 98 | def alias_initial_memory_i: Flag<["-"], "i">, Alias<initial_memory>; | 142 | def alias_initial_memory_i: Flag<["-"], "i">, Alias<initial_memory>; |
| 99 | def alias_max_memory_m: Flag<["-"], "m">, Alias<max_memory>; | 143 | def alias_max_memory_m: Flag<["-"], "m">, Alias<max_memory>; |
| 100 | def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>; | 144 | def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>; |
| 101 | def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>; | ||
| 102 | def alias_entry_entry: J<"entry=">, Alias<entry>; | ||
| 103 | def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>; | 145 | def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>; |
| 146 | |||
| 147 | // LTO-related options. | ||
| 148 | def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">, | ||
| 149 | HelpText<"Optimization level for LTO">; | ||
| 150 | def lto_partitions: J<"lto-partitions=">, | ||
| 151 | HelpText<"Number of LTO codegen partitions">; | ||
| 152 | def disable_verify: F<"disable-verify">; | ||
| 153 | def save_temps: F<"save-temps">; | ||
| 154 | def thinlto_cache_dir: J<"thinlto-cache-dir=">, | ||
| 155 | HelpText<"Path to ThinLTO cached object file directory">; | ||
| 156 | defm thinlto_cache_policy: Eq<"thinlto-cache-policy">, | ||
| 157 | HelpText<"Pruning policy for the ThinLTO cache">; | ||
| 158 | def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">; |
deps/lld/wasm/OutputSections.cpp+89-198| ... | @@ -8,13 +8,11 @@ | ... | @@ -8,13 +8,11 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | ||
| 10 | #include "OutputSections.h" | 10 | #include "OutputSections.h" |
| 11 | 11 | #include "InputChunks.h" | |
| 12 | #include "Config.h" | ||
| 13 | #include "InputFiles.h" | 12 | #include "InputFiles.h" |
| 14 | #include "OutputSegment.h" | 13 | #include "OutputSegment.h" |
| 15 | #include "SymbolTable.h" | 14 | #include "WriterUtils.h" |
| 16 | #include "lld/Common/ErrorHandler.h" | 15 | #include "lld/Common/ErrorHandler.h" |
| 17 | #include "lld/Common/Memory.h" | ||
| 18 | #include "lld/Common/Threads.h" | 16 | #include "lld/Common/Threads.h" |
| 19 | #include "llvm/ADT/Twine.h" | 17 | #include "llvm/ADT/Twine.h" |
| 20 | #include "llvm/Support/LEB128.h" | 18 | #include "llvm/Support/LEB128.h" |
| ... | @@ -26,12 +24,6 @@ using namespace llvm::wasm; | ... | @@ -26,12 +24,6 @@ using namespace llvm::wasm; |
| 26 | using namespace lld; | 24 | using namespace lld; |
| 27 | using namespace lld::wasm; | 25 | using namespace lld::wasm; |
| 28 | 26 | ||
| 29 | enum class RelocEncoding { | ||
| 30 | Uleb128, | ||
| 31 | Sleb128, | ||
| 32 | I32, | ||
| 33 | }; | ||
| 34 | |||
| 35 | static StringRef sectionTypeToString(uint32_t SectionType) { | 27 | static StringRef sectionTypeToString(uint32_t SectionType) { |
| 36 | switch (SectionType) { | 28 | switch (SectionType) { |
| 37 | case WASM_SEC_CUSTOM: | 29 | case WASM_SEC_CUSTOM: |
| ... | @@ -63,159 +55,40 @@ static StringRef sectionTypeToString(uint32_t SectionType) { | ... | @@ -63,159 +55,40 @@ static StringRef sectionTypeToString(uint32_t SectionType) { |
| 63 | } | 55 | } |
| 64 | } | 56 | } |
| 65 | 57 | ||
| 66 | std::string lld::toString(const OutputSection &Section) { | 58 | // Returns a string, e.g. "FUNCTION(.text)". |
| 67 | std::string rtn = Section.getSectionName(); | 59 | std::string lld::toString(const OutputSection &Sec) { |
| 68 | if (!Section.Name.empty()) | 60 | if (!Sec.Name.empty()) |
| 69 | rtn += "(" + Section.Name + ")"; | 61 | return (Sec.getSectionName() + "(" + Sec.Name + ")").str(); |
| 70 | return rtn; | 62 | return Sec.getSectionName(); |
| 71 | } | ||
| 72 | |||
| 73 | static void applyRelocation(uint8_t *Buf, const OutputRelocation &Reloc) { | ||
| 74 | DEBUG(dbgs() << "write reloc: type=" << Reloc.Reloc.Type | ||
| 75 | << " index=" << Reloc.Reloc.Index << " value=" << Reloc.Value | ||
| 76 | << " offset=" << Reloc.Reloc.Offset << "\n"); | ||
| 77 | Buf += Reloc.Reloc.Offset; | ||
| 78 | int64_t ExistingValue; | ||
| 79 | switch (Reloc.Reloc.Type) { | ||
| 80 | case R_WEBASSEMBLY_TYPE_INDEX_LEB: | ||
| 81 | case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: | ||
| 82 | ExistingValue = decodeULEB128(Buf); | ||
| 83 | if (ExistingValue != Reloc.Reloc.Index) { | ||
| 84 | DEBUG(dbgs() << "existing value: " << decodeULEB128(Buf) << "\n"); | ||
| 85 | assert(decodeULEB128(Buf) == Reloc.Reloc.Index); | ||
| 86 | } | ||
| 87 | LLVM_FALLTHROUGH; | ||
| 88 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 89 | case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: | ||
| 90 | encodeULEB128(Reloc.Value, Buf, 5); | ||
| 91 | break; | ||
| 92 | case R_WEBASSEMBLY_TABLE_INDEX_SLEB: | ||
| 93 | ExistingValue = decodeSLEB128(Buf); | ||
| 94 | if (ExistingValue != Reloc.Reloc.Index) { | ||
| 95 | DEBUG(dbgs() << "existing value: " << decodeSLEB128(Buf) << "\n"); | ||
| 96 | assert(decodeSLEB128(Buf) == Reloc.Reloc.Index); | ||
| 97 | } | ||
| 98 | LLVM_FALLTHROUGH; | ||
| 99 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 100 | encodeSLEB128(static_cast<int32_t>(Reloc.Value), Buf, 5); | ||
| 101 | break; | ||
| 102 | case R_WEBASSEMBLY_TABLE_INDEX_I32: | ||
| 103 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 104 | support::endian::write32<support::little>(Buf, Reloc.Value); | ||
| 105 | break; | ||
| 106 | default: | ||
| 107 | llvm_unreachable("unknown relocation type"); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | static void applyRelocations(uint8_t *Buf, ArrayRef<OutputRelocation> Relocs) { | ||
| 112 | if (!Relocs.size()) | ||
| 113 | return; | ||
| 114 | log("applyRelocations: count=" + Twine(Relocs.size())); | ||
| 115 | for (const OutputRelocation &Reloc : Relocs) | ||
| 116 | applyRelocation(Buf, Reloc); | ||
| 117 | } | ||
| 118 | |||
| 119 | // Relocations contain an index into the function, global or table index | ||
| 120 | // space of the input file. This function takes a relocation and returns the | ||
| 121 | // relocated index (i.e. translates from the input index space to the output | ||
| 122 | // index space). | ||
| 123 | static uint32_t calcNewIndex(const ObjFile &File, const WasmRelocation &Reloc) { | ||
| 124 | switch (Reloc.Type) { | ||
| 125 | case R_WEBASSEMBLY_TYPE_INDEX_LEB: | ||
| 126 | return File.relocateTypeIndex(Reloc.Index); | ||
| 127 | case R_WEBASSEMBLY_FUNCTION_INDEX_LEB: | ||
| 128 | return File.relocateFunctionIndex(Reloc.Index); | ||
| 129 | case R_WEBASSEMBLY_TABLE_INDEX_I32: | ||
| 130 | case R_WEBASSEMBLY_TABLE_INDEX_SLEB: | ||
| 131 | return File.relocateTableIndex(Reloc.Index); | ||
| 132 | case R_WEBASSEMBLY_GLOBAL_INDEX_LEB: | ||
| 133 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 134 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 135 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 136 | return File.relocateGlobalIndex(Reloc.Index); | ||
| 137 | default: | ||
| 138 | llvm_unreachable("unknown relocation type"); | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | // Take a vector of relocations from an input file and create output | ||
| 143 | // relocations based on them. Calculates the updated index and offset for | ||
| 144 | // each relocation as well as the value to write out in the final binary. | ||
| 145 | static void calcRelocations(const ObjFile &File, | ||
| 146 | ArrayRef<WasmRelocation> Relocs, | ||
| 147 | std::vector<OutputRelocation> &OutputRelocs, | ||
| 148 | int32_t OutputOffset) { | ||
| 149 | log("calcRelocations: " + File.getName() + " offset=" + Twine(OutputOffset)); | ||
| 150 | for (const WasmRelocation &Reloc : Relocs) { | ||
| 151 | OutputRelocation NewReloc; | ||
| 152 | NewReloc.Reloc = Reloc; | ||
| 153 | NewReloc.Reloc.Offset += OutputOffset; | ||
| 154 | DEBUG(dbgs() << "reloc: type=" << Reloc.Type << " index=" << Reloc.Index | ||
| 155 | << " offset=" << Reloc.Offset | ||
| 156 | << " newOffset=" << NewReloc.Reloc.Offset << "\n"); | ||
| 157 | |||
| 158 | if (Config->EmitRelocs) | ||
| 159 | NewReloc.NewIndex = calcNewIndex(File, Reloc); | ||
| 160 | else | ||
| 161 | NewReloc.NewIndex = UINT32_MAX; | ||
| 162 | |||
| 163 | switch (Reloc.Type) { | ||
| 164 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 165 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 166 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 167 | NewReloc.Value = File.getRelocatedAddress(Reloc.Index); | ||
| 168 | if (NewReloc.Value != UINT32_MAX) | ||
| 169 | NewReloc.Value += Reloc.Addend; | ||
| 170 | break; | ||
| 171 | default: | ||
| 172 | NewReloc.Value = calcNewIndex(File, Reloc); | ||
| 173 | break; | ||
| 174 | } | ||
| 175 | |||
| 176 | OutputRelocs.emplace_back(NewReloc); | ||
| 177 | } | ||
| 178 | } | 63 | } |
| 179 | 64 | ||
| 180 | std::string OutputSection::getSectionName() const { | 65 | StringRef OutputSection::getSectionName() const { |
| 181 | return sectionTypeToString(Type); | 66 | return sectionTypeToString(Type); |
| 182 | } | 67 | } |
| 183 | 68 | ||
| 184 | std::string SubSection::getSectionName() const { | ||
| 185 | return std::string("subsection <type=") + std::to_string(Type) + ">"; | ||
| 186 | } | ||
| 187 | |||
| 188 | void OutputSection::createHeader(size_t BodySize) { | 69 | void OutputSection::createHeader(size_t BodySize) { |
| 189 | raw_string_ostream OS(Header); | 70 | raw_string_ostream OS(Header); |
| 190 | debugWrite(OS.tell(), "section type [" + Twine(getSectionName()) + "]"); | 71 | debugWrite(OS.tell(), "section type [" + getSectionName() + "]"); |
| 191 | writeUleb128(OS, Type, nullptr); | 72 | encodeULEB128(Type, OS); |
| 192 | writeUleb128(OS, BodySize, "section size"); | 73 | writeUleb128(OS, BodySize, "section size"); |
| 193 | OS.flush(); | 74 | OS.flush(); |
| 194 | log("createHeader: " + toString(*this) + " body=" + Twine(BodySize) + | 75 | log("createHeader: " + toString(*this) + " body=" + Twine(BodySize) + |
| 195 | " total=" + Twine(getSize())); | 76 | " total=" + Twine(getSize())); |
| 196 | } | 77 | } |
| 197 | 78 | ||
| 198 | CodeSection::CodeSection(uint32_t NumFunctions, ArrayRef<ObjFile *> Objs) | 79 | CodeSection::CodeSection(ArrayRef<InputFunction *> Functions) |
| 199 | : OutputSection(WASM_SEC_CODE), InputObjects(Objs) { | 80 | : OutputSection(WASM_SEC_CODE), Functions(Functions) { |
| 81 | assert(Functions.size() > 0); | ||
| 82 | |||
| 200 | raw_string_ostream OS(CodeSectionHeader); | 83 | raw_string_ostream OS(CodeSectionHeader); |
| 201 | writeUleb128(OS, NumFunctions, "function count"); | 84 | writeUleb128(OS, Functions.size(), "function count"); |
| 202 | OS.flush(); | 85 | OS.flush(); |
| 203 | BodySize = CodeSectionHeader.size(); | 86 | BodySize = CodeSectionHeader.size(); |
| 204 | 87 | ||
| 205 | for (ObjFile *File : InputObjects) { | 88 | for (InputFunction *Func : Functions) { |
| 206 | if (!File->CodeSection) | 89 | Func->OutputOffset = BodySize; |
| 207 | continue; | 90 | Func->calculateSize(); |
| 208 | 91 | BodySize += Func->getSize(); | |
| 209 | File->CodeOffset = BodySize; | ||
| 210 | ArrayRef<uint8_t> Content = File->CodeSection->Content; | ||
| 211 | unsigned HeaderSize = 0; | ||
| 212 | decodeULEB128(Content.data(), &HeaderSize); | ||
| 213 | |||
| 214 | calcRelocations(*File, File->CodeSection->Relocations, | ||
| 215 | File->CodeRelocations, BodySize - HeaderSize); | ||
| 216 | |||
| 217 | size_t PayloadSize = Content.size() - HeaderSize; | ||
| 218 | BodySize += PayloadSize; | ||
| 219 | } | 92 | } |
| 220 | 93 | ||
| 221 | createHeader(BodySize); | 94 | createHeader(BodySize); |
| ... | @@ -224,49 +97,32 @@ CodeSection::CodeSection(uint32_t NumFunctions, ArrayRef<ObjFile *> Objs) | ... | @@ -224,49 +97,32 @@ CodeSection::CodeSection(uint32_t NumFunctions, ArrayRef<ObjFile *> Objs) |
| 224 | void CodeSection::writeTo(uint8_t *Buf) { | 97 | void CodeSection::writeTo(uint8_t *Buf) { |
| 225 | log("writing " + toString(*this)); | 98 | log("writing " + toString(*this)); |
| 226 | log(" size=" + Twine(getSize())); | 99 | log(" size=" + Twine(getSize())); |
| 100 | log(" headersize=" + Twine(Header.size())); | ||
| 101 | log(" codeheadersize=" + Twine(CodeSectionHeader.size())); | ||
| 227 | Buf += Offset; | 102 | Buf += Offset; |
| 228 | 103 | ||
| 229 | // Write section header | 104 | // Write section header |
| 230 | memcpy(Buf, Header.data(), Header.size()); | 105 | memcpy(Buf, Header.data(), Header.size()); |
| 231 | Buf += Header.size(); | 106 | Buf += Header.size(); |
| 232 | 107 | ||
| 233 | uint8_t *ContentsStart = Buf; | ||
| 234 | |||
| 235 | // Write code section headers | 108 | // Write code section headers |
| 236 | memcpy(Buf, CodeSectionHeader.data(), CodeSectionHeader.size()); | 109 | memcpy(Buf, CodeSectionHeader.data(), CodeSectionHeader.size()); |
| 237 | Buf += CodeSectionHeader.size(); | ||
| 238 | 110 | ||
| 239 | // Write code section bodies | 111 | // Write code section bodies |
| 240 | parallelForEach(InputObjects, [ContentsStart](ObjFile *File) { | 112 | parallelForEach(Functions, |
| 241 | if (!File->CodeSection) | 113 | [&](const InputChunk *Chunk) { Chunk->writeTo(Buf); }); |
| 242 | return; | ||
| 243 | |||
| 244 | ArrayRef<uint8_t> Content(File->CodeSection->Content); | ||
| 245 | |||
| 246 | // Payload doesn't include the initial header (function count) | ||
| 247 | unsigned HeaderSize = 0; | ||
| 248 | decodeULEB128(Content.data(), &HeaderSize); | ||
| 249 | |||
| 250 | size_t PayloadSize = Content.size() - HeaderSize; | ||
| 251 | memcpy(ContentsStart + File->CodeOffset, Content.data() + HeaderSize, | ||
| 252 | PayloadSize); | ||
| 253 | |||
| 254 | log("applying relocations for: " + File->getName()); | ||
| 255 | applyRelocations(ContentsStart, File->CodeRelocations); | ||
| 256 | }); | ||
| 257 | } | 114 | } |
| 258 | 115 | ||
| 259 | uint32_t CodeSection::numRelocations() const { | 116 | uint32_t CodeSection::numRelocations() const { |
| 260 | uint32_t Count = 0; | 117 | uint32_t Count = 0; |
| 261 | for (ObjFile *File : InputObjects) | 118 | for (const InputChunk *Func : Functions) |
| 262 | Count += File->CodeRelocations.size(); | 119 | Count += Func->NumRelocations(); |
| 263 | return Count; | 120 | return Count; |
| 264 | } | 121 | } |
| 265 | 122 | ||
| 266 | void CodeSection::writeRelocations(raw_ostream &OS) const { | 123 | void CodeSection::writeRelocations(raw_ostream &OS) const { |
| 267 | for (ObjFile *File : InputObjects) | 124 | for (const InputChunk *C : Functions) |
| 268 | for (const OutputRelocation &Reloc : File->CodeRelocations) | 125 | C->writeRelocations(OS); |
| 269 | writeReloc(OS, Reloc); | ||
| 270 | } | 126 | } |
| 271 | 127 | ||
| 272 | DataSection::DataSection(ArrayRef<OutputSegment *> Segments) | 128 | DataSection::DataSection(ArrayRef<OutputSegment *> Segments) |
| ... | @@ -285,18 +141,14 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments) | ... | @@ -285,18 +141,14 @@ DataSection::DataSection(ArrayRef<OutputSegment *> Segments) |
| 285 | writeUleb128(OS, WASM_OPCODE_END, "opcode:end"); | 141 | writeUleb128(OS, WASM_OPCODE_END, "opcode:end"); |
| 286 | writeUleb128(OS, Segment->Size, "segment size"); | 142 | writeUleb128(OS, Segment->Size, "segment size"); |
| 287 | OS.flush(); | 143 | OS.flush(); |
| 288 | Segment->setSectionOffset(BodySize); | 144 | |
| 289 | BodySize += Segment->Header.size(); | 145 | Segment->SectionOffset = BodySize; |
| 146 | BodySize += Segment->Header.size() + Segment->Size; | ||
| 290 | log("Data segment: size=" + Twine(Segment->Size)); | 147 | log("Data segment: size=" + Twine(Segment->Size)); |
| 291 | for (InputSegment *InputSeg : Segment->InputSegments) { | 148 | |
| 292 | uint32_t InputOffset = InputSeg->getInputSectionOffset(); | 149 | for (InputSegment *InputSeg : Segment->InputSegments) |
| 293 | uint32_t OutputOffset = Segment->getSectionOffset() + | 150 | InputSeg->OutputOffset = Segment->SectionOffset + Segment->Header.size() + |
| 294 | Segment->Header.size() + | 151 | InputSeg->OutputSegmentOffset; |
| 295 | InputSeg->getOutputSegmentOffset(); | ||
| 296 | calcRelocations(*InputSeg->File, InputSeg->Relocations, | ||
| 297 | InputSeg->OutRelocations, OutputOffset - InputOffset); | ||
| 298 | } | ||
| 299 | BodySize += Segment->Size; | ||
| 300 | } | 152 | } |
| 301 | 153 | ||
| 302 | createHeader(BodySize); | 154 | createHeader(BodySize); |
| ... | @@ -311,38 +163,77 @@ void DataSection::writeTo(uint8_t *Buf) { | ... | @@ -311,38 +163,77 @@ void DataSection::writeTo(uint8_t *Buf) { |
| 311 | memcpy(Buf, Header.data(), Header.size()); | 163 | memcpy(Buf, Header.data(), Header.size()); |
| 312 | Buf += Header.size(); | 164 | Buf += Header.size(); |
| 313 | 165 | ||
| 314 | uint8_t *ContentsStart = Buf; | ||
| 315 | |||
| 316 | // Write data section headers | 166 | // Write data section headers |
| 317 | memcpy(Buf, DataSectionHeader.data(), DataSectionHeader.size()); | 167 | memcpy(Buf, DataSectionHeader.data(), DataSectionHeader.size()); |
| 318 | 168 | ||
| 319 | parallelForEach(Segments, [ContentsStart](const OutputSegment *Segment) { | 169 | parallelForEach(Segments, [&](const OutputSegment *Segment) { |
| 320 | // Write data segment header | 170 | // Write data segment header |
| 321 | uint8_t *SegStart = ContentsStart + Segment->getSectionOffset(); | 171 | uint8_t *SegStart = Buf + Segment->SectionOffset; |
| 322 | memcpy(SegStart, Segment->Header.data(), Segment->Header.size()); | 172 | memcpy(SegStart, Segment->Header.data(), Segment->Header.size()); |
| 323 | 173 | ||
| 324 | // Write segment data payload | 174 | // Write segment data payload |
| 325 | for (const InputSegment *Input : Segment->InputSegments) { | 175 | for (const InputChunk *Chunk : Segment->InputSegments) |
| 326 | ArrayRef<uint8_t> Content(Input->Segment->Data.Content); | 176 | Chunk->writeTo(Buf); |
| 327 | memcpy(SegStart + Segment->Header.size() + | ||
| 328 | Input->getOutputSegmentOffset(), | ||
| 329 | Content.data(), Content.size()); | ||
| 330 | applyRelocations(ContentsStart, Input->OutRelocations); | ||
| 331 | } | ||
| 332 | }); | 177 | }); |
| 333 | } | 178 | } |
| 334 | 179 | ||
| 335 | uint32_t DataSection::numRelocations() const { | 180 | uint32_t DataSection::numRelocations() const { |
| 336 | uint32_t Count = 0; | 181 | uint32_t Count = 0; |
| 337 | for (const OutputSegment *Seg : Segments) | 182 | for (const OutputSegment *Seg : Segments) |
| 338 | for (const InputSegment *InputSeg : Seg->InputSegments) | 183 | for (const InputChunk *InputSeg : Seg->InputSegments) |
| 339 | Count += InputSeg->OutRelocations.size(); | 184 | Count += InputSeg->NumRelocations(); |
| 340 | return Count; | 185 | return Count; |
| 341 | } | 186 | } |
| 342 | 187 | ||
| 343 | void DataSection::writeRelocations(raw_ostream &OS) const { | 188 | void DataSection::writeRelocations(raw_ostream &OS) const { |
| 344 | for (const OutputSegment *Seg : Segments) | 189 | for (const OutputSegment *Seg : Segments) |
| 345 | for (const InputSegment *InputSeg : Seg->InputSegments) | 190 | for (const InputChunk *C : Seg->InputSegments) |
| 346 | for (const OutputRelocation &Reloc : InputSeg->OutRelocations) | 191 | C->writeRelocations(OS); |
| 347 | writeReloc(OS, Reloc); | 192 | } |
| 193 | |||
| 194 | CustomSection::CustomSection(std::string Name, | ||
| 195 | ArrayRef<InputSection *> InputSections) | ||
| 196 | : OutputSection(WASM_SEC_CUSTOM, Name), PayloadSize(0), | ||
| 197 | InputSections(InputSections) { | ||
| 198 | raw_string_ostream OS(NameData); | ||
| 199 | encodeULEB128(Name.size(), OS); | ||
| 200 | OS << Name; | ||
| 201 | OS.flush(); | ||
| 202 | |||
| 203 | for (InputSection *Section : InputSections) { | ||
| 204 | Section->OutputOffset = PayloadSize; | ||
| 205 | PayloadSize += Section->getSize(); | ||
| 206 | } | ||
| 207 | |||
| 208 | createHeader(PayloadSize + NameData.size()); | ||
| 209 | } | ||
| 210 | |||
| 211 | void CustomSection::writeTo(uint8_t *Buf) { | ||
| 212 | log("writing " + toString(*this) + " size=" + Twine(getSize()) + | ||
| 213 | " chunks=" + Twine(InputSections.size())); | ||
| 214 | |||
| 215 | assert(Offset); | ||
| 216 | Buf += Offset; | ||
| 217 | |||
| 218 | // Write section header | ||
| 219 | memcpy(Buf, Header.data(), Header.size()); | ||
| 220 | Buf += Header.size(); | ||
| 221 | memcpy(Buf, NameData.data(), NameData.size()); | ||
| 222 | Buf += NameData.size(); | ||
| 223 | |||
| 224 | // Write custom sections payload | ||
| 225 | parallelForEach(InputSections, | ||
| 226 | [&](const InputSection *Section) { Section->writeTo(Buf); }); | ||
| 227 | } | ||
| 228 | |||
| 229 | uint32_t CustomSection::numRelocations() const { | ||
| 230 | uint32_t Count = 0; | ||
| 231 | for (const InputSection *InputSect : InputSections) | ||
| 232 | Count += InputSect->NumRelocations(); | ||
| 233 | return Count; | ||
| 234 | } | ||
| 235 | |||
| 236 | void CustomSection::writeRelocations(raw_ostream &OS) const { | ||
| 237 | for (const InputSection *S : InputSections) | ||
| 238 | S->writeRelocations(OS); | ||
| 348 | } | 239 | } |
deps/lld/wasm/OutputSections.h+28-22| ... | @@ -10,7 +10,7 @@ | ... | @@ -10,7 +10,7 @@ |
| 10 | #ifndef LLD_WASM_OUTPUT_SECTIONS_H | 10 | #ifndef LLD_WASM_OUTPUT_SECTIONS_H |
| 11 | #define LLD_WASM_OUTPUT_SECTIONS_H | 11 | #define LLD_WASM_OUTPUT_SECTIONS_H |
| 12 | 12 | ||
| 13 | #include "InputSegment.h" | 13 | #include "InputChunks.h" |
| 14 | #include "WriterUtils.h" | 14 | #include "WriterUtils.h" |
| 15 | #include "lld/Common/ErrorHandler.h" | 15 | #include "lld/Common/ErrorHandler.h" |
| 16 | #include "llvm/ADT/DenseMap.h" | 16 | #include "llvm/ADT/DenseMap.h" |
| ... | @@ -28,7 +28,6 @@ std::string toString(const wasm::OutputSection &Section); | ... | @@ -28,7 +28,6 @@ std::string toString(const wasm::OutputSection &Section); |
| 28 | namespace wasm { | 28 | namespace wasm { |
| 29 | 29 | ||
| 30 | class OutputSegment; | 30 | class OutputSegment; |
| 31 | class ObjFile; | ||
| 32 | 31 | ||
| 33 | class OutputSection { | 32 | class OutputSection { |
| 34 | public: | 33 | public: |
| ... | @@ -36,7 +35,7 @@ public: | ... | @@ -36,7 +35,7 @@ public: |
| 36 | : Type(Type), Name(Name) {} | 35 | : Type(Type), Name(Name) {} |
| 37 | virtual ~OutputSection() = default; | 36 | virtual ~OutputSection() = default; |
| 38 | 37 | ||
| 39 | std::string getSectionName() const; | 38 | StringRef getSectionName() const; |
| 40 | void setOffset(size_t NewOffset) { | 39 | void setOffset(size_t NewOffset) { |
| 41 | log("setOffset: " + toString(*this) + ": " + Twine(NewOffset)); | 40 | log("setOffset: " + toString(*this) + ": " + Twine(NewOffset)); |
| 42 | Offset = NewOffset; | 41 | Offset = NewOffset; |
| ... | @@ -61,7 +60,7 @@ public: | ... | @@ -61,7 +60,7 @@ public: |
| 61 | SyntheticSection(uint32_t Type, std::string Name = "") | 60 | SyntheticSection(uint32_t Type, std::string Name = "") |
| 62 | : OutputSection(Type, Name), BodyOutputStream(Body) { | 61 | : OutputSection(Type, Name), BodyOutputStream(Body) { |
| 63 | if (!Name.empty()) | 62 | if (!Name.empty()) |
| 64 | writeStr(BodyOutputStream, Name); | 63 | writeStr(BodyOutputStream, Name, "section name"); |
| 65 | } | 64 | } |
| 66 | 65 | ||
| 67 | void writeTo(uint8_t *Buf) override { | 66 | void writeTo(uint8_t *Buf) override { |
| ... | @@ -86,32 +85,16 @@ protected: | ... | @@ -86,32 +85,16 @@ protected: |
| 86 | raw_string_ostream BodyOutputStream; | 85 | raw_string_ostream BodyOutputStream; |
| 87 | }; | 86 | }; |
| 88 | 87 | ||
| 89 | // Some synthetic sections (e.g. "name" and "linking") have subsections. | ||
| 90 | // Just like the synthetic sections themselves these need to be created before | ||
| 91 | // they can be written out (since they are preceded by their length). This | ||
| 92 | // class is used to create subsections and then write them into the stream | ||
| 93 | // of the parent section. | ||
| 94 | class SubSection : public SyntheticSection { | ||
| 95 | public: | ||
| 96 | explicit SubSection(uint32_t Type) : SyntheticSection(Type) {} | ||
| 97 | |||
| 98 | std::string getSectionName() const; | ||
| 99 | void writeToStream(raw_ostream &OS) { | ||
| 100 | writeBytes(OS, Header.data(), Header.size()); | ||
| 101 | writeBytes(OS, Body.data(), Body.size()); | ||
| 102 | } | ||
| 103 | }; | ||
| 104 | |||
| 105 | class CodeSection : public OutputSection { | 88 | class CodeSection : public OutputSection { |
| 106 | public: | 89 | public: |
| 107 | explicit CodeSection(uint32_t NumFunctions, ArrayRef<ObjFile *> Objs); | 90 | explicit CodeSection(ArrayRef<InputFunction *> Functions); |
| 108 | size_t getSize() const override { return Header.size() + BodySize; } | 91 | size_t getSize() const override { return Header.size() + BodySize; } |
| 109 | void writeTo(uint8_t *Buf) override; | 92 | void writeTo(uint8_t *Buf) override; |
| 110 | uint32_t numRelocations() const override; | 93 | uint32_t numRelocations() const override; |
| 111 | void writeRelocations(raw_ostream &OS) const override; | 94 | void writeRelocations(raw_ostream &OS) const override; |
| 112 | 95 | ||
| 113 | protected: | 96 | protected: |
| 114 | ArrayRef<ObjFile *> InputObjects; | 97 | ArrayRef<InputFunction *> Functions; |
| 115 | std::string CodeSectionHeader; | 98 | std::string CodeSectionHeader; |
| 116 | size_t BodySize = 0; | 99 | size_t BodySize = 0; |
| 117 | }; | 100 | }; |
| ... | @@ -130,6 +113,29 @@ protected: | ... | @@ -130,6 +113,29 @@ protected: |
| 130 | size_t BodySize = 0; | 113 | size_t BodySize = 0; |
| 131 | }; | 114 | }; |
| 132 | 115 | ||
| 116 | // Represents a custom section in the output file. Wasm custom sections are | ||
| 117 | // used for storing user-defined metadata. Unlike the core sections types | ||
| 118 | // they are identified by their string name. | ||
| 119 | // The linker combines custom sections that have the same name by simply | ||
| 120 | // concatenating them. | ||
| 121 | // Note that some custom sections such as "name" and "linking" are handled | ||
| 122 | // separately and are instead synthesized by the linker. | ||
| 123 | class CustomSection : public OutputSection { | ||
| 124 | public: | ||
| 125 | CustomSection(std::string Name, ArrayRef<InputSection *> InputSections); | ||
| 126 | size_t getSize() const override { | ||
| 127 | return Header.size() + NameData.size() + PayloadSize; | ||
| 128 | } | ||
| 129 | void writeTo(uint8_t *Buf) override; | ||
| 130 | uint32_t numRelocations() const override; | ||
| 131 | void writeRelocations(raw_ostream &OS) const override; | ||
| 132 | |||
| 133 | protected: | ||
| 134 | size_t PayloadSize; | ||
| 135 | ArrayRef<InputSection *> InputSections; | ||
| 136 | std::string NameData; | ||
| 137 | }; | ||
| 138 | |||
| 133 | } // namespace wasm | 139 | } // namespace wasm |
| 134 | } // namespace lld | 140 | } // namespace lld |
| 135 | 141 |
deps/lld/wasm/OutputSegment.h+12-16| ... | @@ -10,7 +10,7 @@ | ... | @@ -10,7 +10,7 @@ |
| 10 | #ifndef LLD_WASM_OUTPUT_SEGMENT_H | 10 | #ifndef LLD_WASM_OUTPUT_SEGMENT_H |
| 11 | #define LLD_WASM_OUTPUT_SEGMENT_H | 11 | #define LLD_WASM_OUTPUT_SEGMENT_H |
| 12 | 12 | ||
| 13 | #include "InputSegment.h" | 13 | #include "InputChunks.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | 14 | #include "lld/Common/ErrorHandler.h" |
| 15 | #include "llvm/Object/Wasm.h" | 15 | #include "llvm/Object/Wasm.h" |
| 16 | 16 | ||
| ... | @@ -21,21 +21,20 @@ class InputSegment; | ... | @@ -21,21 +21,20 @@ class InputSegment; |
| 21 | 21 | ||
| 22 | class OutputSegment { | 22 | class OutputSegment { |
| 23 | public: | 23 | public: |
| 24 | OutputSegment(StringRef N) : Name(N) {} | 24 | OutputSegment(StringRef N, uint32_t Index) : Name(N), Index(Index) {} |
| 25 | 25 | ||
| 26 | void addInputSegment(InputSegment *Segment) { | 26 | void addInputSegment(InputSegment *InSeg) { |
| 27 | Alignment = std::max(Alignment, Segment->getAlignment()); | 27 | Alignment = std::max(Alignment, InSeg->getAlignment()); |
| 28 | InputSegments.push_back(Segment); | 28 | InputSegments.push_back(InSeg); |
| 29 | Size = llvm::alignTo(Size, Segment->getAlignment()); | 29 | Size = llvm::alignTo(Size, InSeg->getAlignment()); |
| 30 | Segment->setOutputSegment(this, Size); | 30 | InSeg->OutputSeg = this; |
| 31 | Size += Segment->getSize(); | 31 | InSeg->OutputSegmentOffset = Size; |
| 32 | Size += InSeg->getSize(); | ||
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | uint32_t getSectionOffset() const { return SectionOffset; } | ||
| 35 | |||
| 36 | void setSectionOffset(uint32_t Offset) { SectionOffset = Offset; } | ||
| 37 | |||
| 38 | StringRef Name; | 35 | StringRef Name; |
| 36 | const uint32_t Index; | ||
| 37 | uint32_t SectionOffset = 0; | ||
| 39 | uint32_t Alignment = 0; | 38 | uint32_t Alignment = 0; |
| 40 | uint32_t StartVA = 0; | 39 | uint32_t StartVA = 0; |
| 41 | std::vector<InputSegment *> InputSegments; | 40 | std::vector<InputSegment *> InputSegments; |
| ... | @@ -45,9 +44,6 @@ public: | ... | @@ -45,9 +44,6 @@ public: |
| 45 | 44 | ||
| 46 | // Segment header | 45 | // Segment header |
| 47 | std::string Header; | 46 | std::string Header; |
| 48 | |||
| 49 | private: | ||
| 50 | uint32_t SectionOffset = 0; | ||
| 51 | }; | 47 | }; |
| 52 | 48 | ||
| 53 | } // namespace wasm | 49 | } // namespace wasm |
deps/lld/wasm/SymbolTable.cpp+259-131| ... | @@ -8,17 +8,18 @@ | ... | @@ -8,17 +8,18 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | ||
| 10 | #include "SymbolTable.h" | 10 | #include "SymbolTable.h" |
| 11 | |||
| 12 | #include "Config.h" | 11 | #include "Config.h" |
| 12 | #include "InputChunks.h" | ||
| 13 | #include "InputGlobal.h" | ||
| 13 | #include "WriterUtils.h" | 14 | #include "WriterUtils.h" |
| 14 | #include "lld/Common/ErrorHandler.h" | 15 | #include "lld/Common/ErrorHandler.h" |
| 15 | #include "lld/Common/Memory.h" | 16 | #include "lld/Common/Memory.h" |
| 16 | 17 | #include "llvm/ADT/SetVector.h" | |
| 17 | #include <unordered_set> | ||
| 18 | 18 | ||
| 19 | #define DEBUG_TYPE "lld" | 19 | #define DEBUG_TYPE "lld" |
| 20 | 20 | ||
| 21 | using namespace llvm; | 21 | using namespace llvm; |
| 22 | using namespace llvm::wasm; | ||
| 22 | using namespace lld; | 23 | using namespace lld; |
| 23 | using namespace lld::wasm; | 24 | using namespace lld::wasm; |
| 24 | 25 | ||
| ... | @@ -28,17 +29,46 @@ void SymbolTable::addFile(InputFile *File) { | ... | @@ -28,17 +29,46 @@ void SymbolTable::addFile(InputFile *File) { |
| 28 | log("Processing: " + toString(File)); | 29 | log("Processing: " + toString(File)); |
| 29 | File->parse(); | 30 | File->parse(); |
| 30 | 31 | ||
| 31 | if (auto *F = dyn_cast<ObjFile>(File)) | 32 | // LLVM bitcode file |
| 33 | if (auto *F = dyn_cast<BitcodeFile>(File)) | ||
| 34 | BitcodeFiles.push_back(F); | ||
| 35 | else if (auto *F = dyn_cast<ObjFile>(File)) | ||
| 32 | ObjectFiles.push_back(F); | 36 | ObjectFiles.push_back(F); |
| 33 | } | 37 | } |
| 34 | 38 | ||
| 39 | // This function is where all the optimizations of link-time | ||
| 40 | // optimization happens. When LTO is in use, some input files are | ||
| 41 | // not in native object file format but in the LLVM bitcode format. | ||
| 42 | // This function compiles bitcode files into a few big native files | ||
| 43 | // using LLVM functions and replaces bitcode symbols with the results. | ||
| 44 | // Because all bitcode files that the program consists of are passed | ||
| 45 | // to the compiler at once, it can do whole-program optimization. | ||
| 46 | void SymbolTable::addCombinedLTOObject() { | ||
| 47 | if (BitcodeFiles.empty()) | ||
| 48 | return; | ||
| 49 | |||
| 50 | // Compile bitcode files and replace bitcode symbols. | ||
| 51 | LTO.reset(new BitcodeCompiler); | ||
| 52 | for (BitcodeFile *F : BitcodeFiles) | ||
| 53 | LTO->add(*F); | ||
| 54 | |||
| 55 | for (StringRef Filename : LTO->compile()) { | ||
| 56 | auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp")); | ||
| 57 | Obj->parse(); | ||
| 58 | ObjectFiles.push_back(Obj); | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 35 | void SymbolTable::reportRemainingUndefines() { | 62 | void SymbolTable::reportRemainingUndefines() { |
| 36 | std::unordered_set<Symbol *> Undefs; | 63 | SetVector<Symbol *> Undefs; |
| 37 | for (Symbol *Sym : SymVector) { | 64 | for (Symbol *Sym : SymVector) { |
| 38 | if (Sym->isUndefined() && !Sym->isWeak() && | 65 | if (!Sym->isUndefined() || Sym->isWeak()) |
| 39 | Config->AllowUndefinedSymbols.count(Sym->getName()) == 0) { | 66 | continue; |
| 40 | Undefs.insert(Sym); | 67 | if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0) |
| 41 | } | 68 | continue; |
| 69 | if (!Sym->IsUsedInRegularObj) | ||
| 70 | continue; | ||
| 71 | Undefs.insert(Sym); | ||
| 42 | } | 72 | } |
| 43 | 73 | ||
| 44 | if (Undefs.empty()) | 74 | if (Undefs.empty()) |
| ... | @@ -55,183 +85,281 @@ void SymbolTable::reportRemainingUndefines() { | ... | @@ -55,183 +85,281 @@ void SymbolTable::reportRemainingUndefines() { |
| 55 | } | 85 | } |
| 56 | 86 | ||
| 57 | Symbol *SymbolTable::find(StringRef Name) { | 87 | Symbol *SymbolTable::find(StringRef Name) { |
| 58 | auto It = SymMap.find(CachedHashStringRef(Name)); | 88 | return SymMap.lookup(CachedHashStringRef(Name)); |
| 59 | if (It == SymMap.end()) | ||
| 60 | return nullptr; | ||
| 61 | return It->second; | ||
| 62 | } | 89 | } |
| 63 | 90 | ||
| 64 | std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { | 91 | std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { |
| 65 | Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; | 92 | Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; |
| 66 | if (Sym) | 93 | if (Sym) |
| 67 | return {Sym, false}; | 94 | return {Sym, false}; |
| 68 | Sym = make<Symbol>(Name, false); | 95 | Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); |
| 96 | Sym->IsUsedInRegularObj = false; | ||
| 69 | SymVector.emplace_back(Sym); | 97 | SymVector.emplace_back(Sym); |
| 70 | return {Sym, true}; | 98 | return {Sym, true}; |
| 71 | } | 99 | } |
| 72 | 100 | ||
| 73 | void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { | 101 | static void reportTypeError(const Symbol *Existing, const InputFile *File, |
| 74 | error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " + | 102 | llvm::wasm::WasmSymbolType Type) { |
| 75 | toString(Existing->getFile()) + "\n>>> defined in " + | 103 | error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " + |
| 76 | toString(NewFile)); | 104 | toString(Existing->getWasmType()) + " in " + |
| 105 | toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) + | ||
| 106 | " in " + toString(File)); | ||
| 77 | } | 107 | } |
| 78 | 108 | ||
| 79 | // Get the signature for a given function symbol, either by looking | 109 | static void checkFunctionType(Symbol *Existing, const InputFile *File, |
| 80 | // it up in function sections (for defined functions), of the imports section | 110 | const WasmSignature *NewSig) { |
| 81 | // (for imported functions). | 111 | auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing); |
| 82 | static const WasmSignature *getFunctionSig(const ObjFile &Obj, | 112 | if (!ExistingFunction) { |
| 83 | const WasmSymbol &Sym) { | 113 | reportTypeError(Existing, File, WASM_SYMBOL_TYPE_FUNCTION); |
| 84 | DEBUG(dbgs() << "getFunctionSig: " << Sym.Name << "\n"); | 114 | return; |
| 85 | const WasmObjectFile *WasmObj = Obj.getWasmObj(); | 115 | } |
| 86 | return &WasmObj->types()[Sym.FunctionType]; | 116 | |
| 117 | if (!NewSig) | ||
| 118 | return; | ||
| 119 | |||
| 120 | const WasmSignature *OldSig = ExistingFunction->FunctionType; | ||
| 121 | if (!OldSig) { | ||
| 122 | ExistingFunction->FunctionType = NewSig; | ||
| 123 | return; | ||
| 124 | } | ||
| 125 | |||
| 126 | if (*NewSig != *OldSig) | ||
| 127 | warn("function signature mismatch: " + Existing->getName() + | ||
| 128 | "\n>>> defined as " + toString(*OldSig) + " in " + | ||
| 129 | toString(Existing->getFile()) + "\n>>> defined as " + | ||
| 130 | toString(*NewSig) + " in " + toString(File)); | ||
| 87 | } | 131 | } |
| 88 | 132 | ||
| 89 | // Check the type of new symbol matches that of the symbol is replacing. | 133 | // Check the type of new symbol matches that of the symbol is replacing. |
| 90 | // For functions this can also involve verifying that the signatures match. | 134 | // For functions this can also involve verifying that the signatures match. |
| 91 | static void checkSymbolTypes(const Symbol &Existing, const InputFile &F, | 135 | static void checkGlobalType(const Symbol *Existing, const InputFile *File, |
| 92 | const WasmSymbol &New, | 136 | const WasmGlobalType *NewType) { |
| 93 | const WasmSignature *NewSig) { | 137 | if (!isa<GlobalSymbol>(Existing)) { |
| 94 | if (Existing.isLazy()) | 138 | reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL); |
| 95 | return; | 139 | return; |
| 140 | } | ||
| 96 | 141 | ||
| 97 | bool NewIsFunction = New.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT || | 142 | const WasmGlobalType *OldType = cast<GlobalSymbol>(Existing)->getGlobalType(); |
| 98 | New.Type == WasmSymbol::SymbolType::FUNCTION_IMPORT; | 143 | if (*NewType != *OldType) { |
| 99 | 144 | error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " + | |
| 100 | // First check the symbol types match (i.e. either both are function | 145 | toString(*OldType) + " in " + toString(Existing->getFile()) + |
| 101 | // symbols or both are data symbols). | 146 | "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); |
| 102 | if (Existing.isFunction() != NewIsFunction) { | ||
| 103 | error("symbol type mismatch: " + New.Name + "\n>>> defined as " + | ||
| 104 | (Existing.isFunction() ? "Function" : "Global") + " in " + | ||
| 105 | toString(Existing.getFile()) + "\n>>> defined as " + | ||
| 106 | (NewIsFunction ? "Function" : "Global") + " in " + F.getName()); | ||
| 107 | return; | ||
| 108 | } | 147 | } |
| 148 | } | ||
| 109 | 149 | ||
| 110 | // For function symbols, optionally check the function signature matches too. | 150 | static void checkDataType(const Symbol *Existing, const InputFile *File) { |
| 111 | if (!NewIsFunction || !Config->CheckSignatures) | 151 | if (!isa<DataSymbol>(Existing)) |
| 112 | return; | 152 | reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA); |
| 113 | // Skip the signature check if the existing function has no signature (e.g. | 153 | } |
| 114 | // if it is an undefined symbol generated by --undefined command line flag). | ||
| 115 | if (!Existing.hasFunctionType()) | ||
| 116 | return; | ||
| 117 | 154 | ||
| 118 | DEBUG(dbgs() << "checkSymbolTypes: " << New.Name << "\n"); | 155 | DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, |
| 119 | assert(NewSig); | 156 | uint32_t Flags, |
| 157 | InputFunction *Function) { | ||
| 158 | LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); | ||
| 159 | assert(!find(Name)); | ||
| 160 | SyntheticFunctions.emplace_back(Function); | ||
| 161 | return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags, | ||
| 162 | nullptr, Function); | ||
| 163 | } | ||
| 120 | 164 | ||
| 121 | const WasmSignature &OldSig = Existing.getFunctionType(); | 165 | DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, |
| 122 | if (*NewSig == OldSig) | 166 | uint32_t Flags) { |
| 123 | return; | 167 | LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n"); |
| 168 | assert(!find(Name)); | ||
| 169 | return replaceSymbol<DefinedData>(insert(Name).first, Name, Flags); | ||
| 170 | } | ||
| 124 | 171 | ||
| 125 | error("function signature mismatch: " + New.Name + "\n>>> defined as " + | 172 | DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, |
| 126 | toString(OldSig) + " in " + toString(Existing.getFile()) + | 173 | InputGlobal *Global) { |
| 127 | "\n>>> defined as " + toString(*NewSig) + " in " + F.getName()); | 174 | LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global |
| 175 | << "\n"); | ||
| 176 | assert(!find(Name)); | ||
| 177 | SyntheticGlobals.emplace_back(Global); | ||
| 178 | return replaceSymbol<DefinedGlobal>(insert(Name).first, Name, Flags, nullptr, | ||
| 179 | Global); | ||
| 128 | } | 180 | } |
| 129 | 181 | ||
| 130 | Symbol *SymbolTable::addDefinedGlobal(StringRef Name) { | 182 | static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, |
| 131 | DEBUG(dbgs() << "addDefinedGlobal: " << Name << "\n"); | 183 | uint32_t NewFlags) { |
| 184 | // If existing symbol is undefined, replace it. | ||
| 185 | if (!Existing->isDefined()) { | ||
| 186 | LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: " | ||
| 187 | << Existing->getName() << "\n"); | ||
| 188 | return true; | ||
| 189 | } | ||
| 190 | |||
| 191 | // Now we have two defined symbols. If the new one is weak, we can ignore it. | ||
| 192 | if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { | ||
| 193 | LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n"); | ||
| 194 | return false; | ||
| 195 | } | ||
| 196 | |||
| 197 | // If the existing symbol is weak, we should replace it. | ||
| 198 | if (Existing->isWeak()) { | ||
| 199 | LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n"); | ||
| 200 | return true; | ||
| 201 | } | ||
| 202 | |||
| 203 | // Neither symbol is week. They conflict. | ||
| 204 | error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " + | ||
| 205 | toString(Existing->getFile()) + "\n>>> defined in " + | ||
| 206 | toString(NewFile)); | ||
| 207 | return true; | ||
| 208 | } | ||
| 209 | |||
| 210 | Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, | ||
| 211 | InputFile *File, | ||
| 212 | InputFunction *Function) { | ||
| 213 | LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n"); | ||
| 132 | Symbol *S; | 214 | Symbol *S; |
| 133 | bool WasInserted; | 215 | bool WasInserted; |
| 134 | std::tie(S, WasInserted) = insert(Name); | 216 | std::tie(S, WasInserted) = insert(Name); |
| 135 | if (WasInserted) | 217 | |
| 136 | S->update(Symbol::DefinedGlobalKind); | 218 | if (!File || File->kind() == InputFile::ObjectKind) |
| 137 | else if (!S->isGlobal()) | 219 | S->IsUsedInRegularObj = true; |
| 138 | error("symbol type mismatch: " + Name); | 220 | |
| 221 | if (WasInserted || S->isLazy()) { | ||
| 222 | replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); | ||
| 223 | return S; | ||
| 224 | } | ||
| 225 | |||
| 226 | if (Function) | ||
| 227 | checkFunctionType(S, File, &Function->Signature); | ||
| 228 | |||
| 229 | if (shouldReplace(S, File, Flags)) | ||
| 230 | replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); | ||
| 139 | return S; | 231 | return S; |
| 140 | } | 232 | } |
| 141 | 233 | ||
| 142 | Symbol *SymbolTable::addDefined(InputFile *F, const WasmSymbol *Sym, | 234 | Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags, |
| 143 | const InputSegment *Segment) { | 235 | InputFile *File, InputSegment *Segment, |
| 144 | DEBUG(dbgs() << "addDefined: " << Sym->Name << "\n"); | 236 | uint32_t Address, uint32_t Size) { |
| 237 | LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address | ||
| 238 | << "\n"); | ||
| 145 | Symbol *S; | 239 | Symbol *S; |
| 146 | bool WasInserted; | 240 | bool WasInserted; |
| 147 | Symbol::Kind Kind = Symbol::DefinedFunctionKind; | 241 | std::tie(S, WasInserted) = insert(Name); |
| 148 | const WasmSignature *NewSig = nullptr; | ||
| 149 | if (Sym->Type == WasmSymbol::SymbolType::GLOBAL_EXPORT) | ||
| 150 | Kind = Symbol::DefinedGlobalKind; | ||
| 151 | else | ||
| 152 | NewSig = getFunctionSig(*cast<ObjFile>(F), *Sym); | ||
| 153 | 242 | ||
| 154 | std::tie(S, WasInserted) = insert(Sym->Name); | 243 | if (!File || File->kind() == InputFile::ObjectKind) |
| 155 | if (WasInserted) { | 244 | S->IsUsedInRegularObj = true; |
| 156 | S->update(Kind, F, Sym, Segment, NewSig); | 245 | |
| 157 | } else if (S->isLazy()) { | 246 | if (WasInserted || S->isLazy()) { |
| 158 | // The existing symbol is lazy. Replace it without checking types since | 247 | replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); |
| 159 | // lazy symbols don't have any type information. | 248 | return S; |
| 160 | DEBUG(dbgs() << "replacing existing lazy symbol: " << Sym->Name << "\n"); | ||
| 161 | S->update(Kind, F, Sym, Segment, NewSig); | ||
| 162 | } else if (!S->isDefined()) { | ||
| 163 | // The existing symbol table entry is undefined. The new symbol replaces | ||
| 164 | // it, after checking the type matches | ||
| 165 | DEBUG(dbgs() << "resolving existing undefined symbol: " << Sym->Name | ||
| 166 | << "\n"); | ||
| 167 | checkSymbolTypes(*S, *F, *Sym, NewSig); | ||
| 168 | S->update(Kind, F, Sym, Segment, NewSig); | ||
| 169 | } else if (Sym->isWeak()) { | ||
| 170 | // the new symbol is weak we can ignore it | ||
| 171 | DEBUG(dbgs() << "existing symbol takes precedence\n"); | ||
| 172 | } else if (S->isWeak()) { | ||
| 173 | // the new symbol is not weak and the existing symbol is, so we replace | ||
| 174 | // it | ||
| 175 | DEBUG(dbgs() << "replacing existing weak symbol\n"); | ||
| 176 | checkSymbolTypes(*S, *F, *Sym, NewSig); | ||
| 177 | S->update(Kind, F, Sym, Segment, NewSig); | ||
| 178 | } else { | ||
| 179 | // neither symbol is week. They conflict. | ||
| 180 | reportDuplicate(S, F); | ||
| 181 | } | 249 | } |
| 250 | |||
| 251 | checkDataType(S, File); | ||
| 252 | |||
| 253 | if (shouldReplace(S, File, Flags)) | ||
| 254 | replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); | ||
| 182 | return S; | 255 | return S; |
| 183 | } | 256 | } |
| 184 | 257 | ||
| 185 | Symbol *SymbolTable::addUndefinedFunction(StringRef Name, | 258 | Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, |
| 186 | const WasmSignature *Type) { | 259 | InputFile *File, InputGlobal *Global) { |
| 260 | LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n"); | ||
| 187 | Symbol *S; | 261 | Symbol *S; |
| 188 | bool WasInserted; | 262 | bool WasInserted; |
| 189 | std::tie(S, WasInserted) = insert(Name); | 263 | std::tie(S, WasInserted) = insert(Name); |
| 190 | if (WasInserted) { | 264 | |
| 191 | S->update(Symbol::UndefinedFunctionKind, nullptr, nullptr, nullptr, Type); | 265 | if (!File || File->kind() == InputFile::ObjectKind) |
| 192 | } else if (!S->isFunction()) { | 266 | S->IsUsedInRegularObj = true; |
| 193 | error("symbol type mismatch: " + Name); | 267 | |
| 268 | if (WasInserted || S->isLazy()) { | ||
| 269 | replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); | ||
| 270 | return S; | ||
| 194 | } | 271 | } |
| 272 | |||
| 273 | checkGlobalType(S, File, &Global->getType()); | ||
| 274 | |||
| 275 | if (shouldReplace(S, File, Flags)) | ||
| 276 | replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); | ||
| 195 | return S; | 277 | return S; |
| 196 | } | 278 | } |
| 197 | 279 | ||
| 198 | Symbol *SymbolTable::addUndefined(InputFile *F, const WasmSymbol *Sym) { | 280 | Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, |
| 199 | DEBUG(dbgs() << "addUndefined: " << Sym->Name << "\n"); | 281 | InputFile *File, |
| 282 | const WasmSignature *Sig) { | ||
| 283 | LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n"); | ||
| 284 | |||
| 200 | Symbol *S; | 285 | Symbol *S; |
| 201 | bool WasInserted; | 286 | bool WasInserted; |
| 202 | Symbol::Kind Kind = Symbol::UndefinedFunctionKind; | 287 | std::tie(S, WasInserted) = insert(Name); |
| 203 | const WasmSignature *NewSig = nullptr; | 288 | |
| 204 | if (Sym->Type == WasmSymbol::SymbolType::GLOBAL_IMPORT) | 289 | if (!File || File->kind() == InputFile::ObjectKind) |
| 205 | Kind = Symbol::UndefinedGlobalKind; | 290 | S->IsUsedInRegularObj = true; |
| 291 | |||
| 292 | if (WasInserted) | ||
| 293 | replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig); | ||
| 294 | else if (auto *Lazy = dyn_cast<LazySymbol>(S)) | ||
| 295 | Lazy->fetch(); | ||
| 206 | else | 296 | else |
| 207 | NewSig = getFunctionSig(*cast<ObjFile>(F), *Sym); | 297 | checkFunctionType(S, File, Sig); |
| 208 | std::tie(S, WasInserted) = insert(Sym->Name); | 298 | |
| 209 | if (WasInserted) { | 299 | return S; |
| 210 | S->update(Kind, F, Sym, nullptr, NewSig); | 300 | } |
| 211 | } else if (S->isLazy()) { | 301 | |
| 212 | DEBUG(dbgs() << "resolved by existing lazy\n"); | 302 | Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, |
| 213 | auto *AF = cast<ArchiveFile>(S->getFile()); | 303 | InputFile *File) { |
| 214 | AF->addMember(&S->getArchiveSymbol()); | 304 | LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n"); |
| 215 | } else if (S->isDefined()) { | 305 | |
| 216 | DEBUG(dbgs() << "resolved by existing\n"); | 306 | Symbol *S; |
| 217 | checkSymbolTypes(*S, *F, *Sym, NewSig); | 307 | bool WasInserted; |
| 218 | } | 308 | std::tie(S, WasInserted) = insert(Name); |
| 309 | |||
| 310 | if (!File || File->kind() == InputFile::ObjectKind) | ||
| 311 | S->IsUsedInRegularObj = true; | ||
| 312 | |||
| 313 | if (WasInserted) | ||
| 314 | replaceSymbol<UndefinedData>(S, Name, Flags, File); | ||
| 315 | else if (auto *Lazy = dyn_cast<LazySymbol>(S)) | ||
| 316 | Lazy->fetch(); | ||
| 317 | else if (S->isDefined()) | ||
| 318 | checkDataType(S, File); | ||
| 219 | return S; | 319 | return S; |
| 220 | } | 320 | } |
| 221 | 321 | ||
| 222 | void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol *Sym) { | 322 | Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, |
| 223 | DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n"); | 323 | InputFile *File, |
| 324 | const WasmGlobalType *Type) { | ||
| 325 | LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n"); | ||
| 326 | |||
| 327 | Symbol *S; | ||
| 328 | bool WasInserted; | ||
| 329 | std::tie(S, WasInserted) = insert(Name); | ||
| 330 | |||
| 331 | if (!File || File->kind() == InputFile::ObjectKind) | ||
| 332 | S->IsUsedInRegularObj = true; | ||
| 333 | |||
| 334 | if (WasInserted) | ||
| 335 | replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type); | ||
| 336 | else if (auto *Lazy = dyn_cast<LazySymbol>(S)) | ||
| 337 | Lazy->fetch(); | ||
| 338 | else if (S->isDefined()) | ||
| 339 | checkGlobalType(S, File, Type); | ||
| 340 | return S; | ||
| 341 | } | ||
| 342 | |||
| 343 | void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) { | ||
| 344 | LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n"); | ||
| 224 | StringRef Name = Sym->getName(); | 345 | StringRef Name = Sym->getName(); |
| 346 | |||
| 225 | Symbol *S; | 347 | Symbol *S; |
| 226 | bool WasInserted; | 348 | bool WasInserted; |
| 227 | std::tie(S, WasInserted) = insert(Name); | 349 | std::tie(S, WasInserted) = insert(Name); |
| 350 | |||
| 228 | if (WasInserted) { | 351 | if (WasInserted) { |
| 229 | S->update(Symbol::LazyKind, F); | 352 | replaceSymbol<LazySymbol>(S, Name, File, *Sym); |
| 230 | S->setArchiveSymbol(*Sym); | 353 | return; |
| 231 | } else if (S->isUndefined()) { | 354 | } |
| 232 | // There is an existing undefined symbol. The can load from the | 355 | |
| 233 | // archive. | 356 | // If there is an existing undefined symbol, load a new one from the archive. |
| 234 | DEBUG(dbgs() << "replacing existing undefined\n"); | 357 | if (S->isUndefined()) { |
| 235 | F->addMember(Sym); | 358 | LLVM_DEBUG(dbgs() << "replacing existing undefined\n"); |
| 359 | File->addMember(Sym); | ||
| 236 | } | 360 | } |
| 237 | } | 361 | } |
| 362 | |||
| 363 | bool SymbolTable::addComdat(StringRef Name) { | ||
| 364 | return Comdats.insert(CachedHashStringRef(Name)).second; | ||
| 365 | } |
deps/lld/wasm/SymbolTable.h+34-9| ... | @@ -11,13 +11,13 @@ | ... | @@ -11,13 +11,13 @@ |
| 11 | #define LLD_WASM_SYMBOL_TABLE_H | 11 | #define LLD_WASM_SYMBOL_TABLE_H |
| 12 | 12 | ||
| 13 | #include "InputFiles.h" | 13 | #include "InputFiles.h" |
| 14 | #include "LTO.h" | ||
| 14 | #include "Symbols.h" | 15 | #include "Symbols.h" |
| 15 | |||
| 16 | #include "llvm/ADT/CachedHashString.h" | 16 | #include "llvm/ADT/CachedHashString.h" |
| 17 | #include "llvm/ADT/DenseMap.h" | 17 | #include "llvm/ADT/DenseSet.h" |
| 18 | #include "llvm/Support/raw_ostream.h" | 18 | #include "llvm/Support/raw_ostream.h" |
| 19 | 19 | ||
| 20 | using llvm::object::WasmSymbol; | 20 | using llvm::wasm::WasmGlobalType; |
| 21 | using llvm::wasm::WasmSignature; | 21 | using llvm::wasm::WasmSignature; |
| 22 | 22 | ||
| 23 | namespace lld { | 23 | namespace lld { |
| ... | @@ -40,27 +40,52 @@ class InputSegment; | ... | @@ -40,27 +40,52 @@ class InputSegment; |
| 40 | class SymbolTable { | 40 | class SymbolTable { |
| 41 | public: | 41 | public: |
| 42 | void addFile(InputFile *File); | 42 | void addFile(InputFile *File); |
| 43 | void addCombinedLTOObject(); | ||
| 43 | 44 | ||
| 44 | std::vector<ObjFile *> ObjectFiles; | 45 | std::vector<ObjFile *> ObjectFiles; |
| 46 | std::vector<BitcodeFile *> BitcodeFiles; | ||
| 47 | std::vector<InputFunction *> SyntheticFunctions; | ||
| 48 | std::vector<InputGlobal *> SyntheticGlobals; | ||
| 45 | 49 | ||
| 46 | void reportDuplicate(Symbol *Existing, InputFile *NewFile); | ||
| 47 | void reportRemainingUndefines(); | 50 | void reportRemainingUndefines(); |
| 48 | 51 | ||
| 49 | ArrayRef<Symbol *> getSymbols() const { return SymVector; } | 52 | ArrayRef<Symbol *> getSymbols() const { return SymVector; } |
| 50 | Symbol *find(StringRef Name); | 53 | Symbol *find(StringRef Name); |
| 51 | 54 | ||
| 52 | Symbol *addDefined(InputFile *F, const WasmSymbol *Sym, | 55 | Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, |
| 53 | const InputSegment *Segment = nullptr); | 56 | InputFunction *Function); |
| 54 | Symbol *addUndefined(InputFile *F, const WasmSymbol *Sym); | 57 | Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *File, |
| 55 | Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type); | 58 | InputSegment *Segment, uint32_t Address, |
| 56 | Symbol *addDefinedGlobal(StringRef Name); | 59 | uint32_t Size); |
| 60 | Symbol *addDefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, | ||
| 61 | InputGlobal *G); | ||
| 62 | |||
| 63 | Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, | ||
| 64 | const WasmSignature *Signature); | ||
| 65 | Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File); | ||
| 66 | Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, | ||
| 67 | const WasmGlobalType *Type); | ||
| 68 | |||
| 57 | void addLazy(ArchiveFile *F, const Archive::Symbol *Sym); | 69 | void addLazy(ArchiveFile *F, const Archive::Symbol *Sym); |
| 58 | 70 | ||
| 71 | bool addComdat(StringRef Name); | ||
| 72 | |||
| 73 | DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags); | ||
| 74 | DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags, | ||
| 75 | InputGlobal *Global); | ||
| 76 | DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags, | ||
| 77 | InputFunction *Function); | ||
| 78 | |||
| 59 | private: | 79 | private: |
| 60 | std::pair<Symbol *, bool> insert(StringRef Name); | 80 | std::pair<Symbol *, bool> insert(StringRef Name); |
| 61 | 81 | ||
| 62 | llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap; | 82 | llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> SymMap; |
| 63 | std::vector<Symbol *> SymVector; | 83 | std::vector<Symbol *> SymVector; |
| 84 | |||
| 85 | llvm::DenseSet<llvm::CachedHashStringRef> Comdats; | ||
| 86 | |||
| 87 | // For LTO. | ||
| 88 | std::unique_ptr<BitcodeCompiler> LTO; | ||
| 64 | }; | 89 | }; |
| 65 | 90 | ||
| 66 | extern SymbolTable *Symtab; | 91 | extern SymbolTable *Symtab; |
deps/lld/wasm/Symbols.cpp+189-51| ... | @@ -8,92 +8,224 @@ | ... | @@ -8,92 +8,224 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | ||
| 10 | #include "Symbols.h" | 10 | #include "Symbols.h" |
| 11 | |||
| 12 | #include "Config.h" | 11 | #include "Config.h" |
| 12 | #include "InputChunks.h" | ||
| 13 | #include "InputFiles.h" | 13 | #include "InputFiles.h" |
| 14 | #include "InputSegment.h" | 14 | #include "InputGlobal.h" |
| 15 | #include "OutputSegment.h" | ||
| 15 | #include "lld/Common/ErrorHandler.h" | 16 | #include "lld/Common/ErrorHandler.h" |
| 16 | #include "lld/Common/Strings.h" | 17 | #include "lld/Common/Strings.h" |
| 17 | 18 | ||
| 18 | #define DEBUG_TYPE "lld" | 19 | #define DEBUG_TYPE "lld" |
| 19 | 20 | ||
| 20 | using namespace llvm; | 21 | using namespace llvm; |
| 22 | using namespace llvm::wasm; | ||
| 21 | using namespace lld; | 23 | using namespace lld; |
| 22 | using namespace lld::wasm; | 24 | using namespace lld::wasm; |
| 23 | 25 | ||
| 24 | uint32_t Symbol::getGlobalIndex() const { | 26 | DefinedFunction *WasmSym::CallCtors; |
| 25 | assert(!Sym->isFunction()); | 27 | DefinedData *WasmSym::DsoHandle; |
| 26 | return Sym->ElementIndex; | 28 | DefinedData *WasmSym::DataEnd; |
| 29 | DefinedData *WasmSym::HeapBase; | ||
| 30 | DefinedGlobal *WasmSym::StackPointer; | ||
| 31 | |||
| 32 | WasmSymbolType Symbol::getWasmType() const { | ||
| 33 | if (isa<FunctionSymbol>(this)) | ||
| 34 | return WASM_SYMBOL_TYPE_FUNCTION; | ||
| 35 | if (isa<DataSymbol>(this)) | ||
| 36 | return WASM_SYMBOL_TYPE_DATA; | ||
| 37 | if (isa<GlobalSymbol>(this)) | ||
| 38 | return WASM_SYMBOL_TYPE_GLOBAL; | ||
| 39 | if (isa<SectionSymbol>(this)) | ||
| 40 | return WASM_SYMBOL_TYPE_SECTION; | ||
| 41 | llvm_unreachable("invalid symbol kind"); | ||
| 42 | } | ||
| 43 | |||
| 44 | InputChunk *Symbol::getChunk() const { | ||
| 45 | if (auto *F = dyn_cast<DefinedFunction>(this)) | ||
| 46 | return F->Function; | ||
| 47 | if (auto *D = dyn_cast<DefinedData>(this)) | ||
| 48 | return D->Segment; | ||
| 49 | return nullptr; | ||
| 50 | } | ||
| 51 | |||
| 52 | bool Symbol::isLive() const { | ||
| 53 | if (auto *G = dyn_cast<DefinedGlobal>(this)) | ||
| 54 | return G->Global->Live; | ||
| 55 | if (InputChunk *C = getChunk()) | ||
| 56 | return C->Live; | ||
| 57 | return Referenced; | ||
| 27 | } | 58 | } |
| 28 | 59 | ||
| 29 | uint32_t Symbol::getFunctionIndex() const { | 60 | void Symbol::markLive() { |
| 30 | assert(Sym->isFunction()); | 61 | if (auto *G = dyn_cast<DefinedGlobal>(this)) |
| 31 | return Sym->ElementIndex; | 62 | G->Global->Live = true; |
| 63 | if (InputChunk *C = getChunk()) | ||
| 64 | C->Live = true; | ||
| 65 | Referenced = true; | ||
| 32 | } | 66 | } |
| 33 | 67 | ||
| 34 | const WasmSignature &Symbol::getFunctionType() const { | 68 | uint32_t Symbol::getOutputSymbolIndex() const { |
| 35 | assert(FunctionType != nullptr); | 69 | assert(OutputSymbolIndex != INVALID_INDEX); |
| 36 | return *FunctionType; | 70 | return OutputSymbolIndex; |
| 37 | } | 71 | } |
| 38 | 72 | ||
| 39 | uint32_t Symbol::getVirtualAddress() const { | 73 | void Symbol::setOutputSymbolIndex(uint32_t Index) { |
| 40 | assert(isGlobal()); | 74 | LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index |
| 41 | DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); | 75 | << "\n"); |
| 42 | if (isUndefined()) | 76 | assert(OutputSymbolIndex == INVALID_INDEX); |
| 43 | return UINT32_MAX; | 77 | OutputSymbolIndex = Index; |
| 44 | if (VirtualAddress.hasValue()) | 78 | } |
| 45 | return VirtualAddress.getValue(); | 79 | |
| 80 | bool Symbol::isWeak() const { | ||
| 81 | return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK; | ||
| 82 | } | ||
| 46 | 83 | ||
| 47 | assert(Sym != nullptr); | 84 | bool Symbol::isLocal() const { |
| 48 | ObjFile *Obj = cast<ObjFile>(File); | 85 | return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL; |
| 49 | const WasmGlobal &Global = | ||
| 50 | Obj->getWasmObj()->globals()[getGlobalIndex() - Obj->NumGlobalImports()]; | ||
| 51 | assert(Global.Type == llvm::wasm::WASM_TYPE_I32); | ||
| 52 | assert(Segment); | ||
| 53 | return Segment->translateVA(Global.InitExpr.Value.Int32); | ||
| 54 | } | 86 | } |
| 55 | 87 | ||
| 56 | uint32_t Symbol::getOutputIndex() const { | 88 | bool Symbol::isHidden() const { |
| 57 | if (isUndefined() && isWeak()) | 89 | return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN; |
| 58 | return 0; | ||
| 59 | return OutputIndex.getValue(); | ||
| 60 | } | 90 | } |
| 61 | 91 | ||
| 62 | void Symbol::setVirtualAddress(uint32_t Value) { | 92 | void Symbol::setHidden(bool IsHidden) { |
| 63 | DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); | 93 | LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n"); |
| 64 | assert(!VirtualAddress.hasValue()); | 94 | Flags &= ~WASM_SYMBOL_VISIBILITY_MASK; |
| 65 | VirtualAddress = Value; | 95 | if (IsHidden) |
| 96 | Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; | ||
| 97 | else | ||
| 98 | Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT; | ||
| 66 | } | 99 | } |
| 67 | 100 | ||
| 68 | void Symbol::setOutputIndex(uint32_t Index) { | 101 | bool Symbol::isExported() const { |
| 69 | DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n"); | 102 | if (!isDefined() || isLocal()) |
| 70 | assert(!OutputIndex.hasValue()); | 103 | return false; |
| 71 | OutputIndex = Index; | 104 | |
| 105 | if (ForceExport || Config->ExportAll) | ||
| 106 | return true; | ||
| 107 | |||
| 108 | return !isHidden(); | ||
| 72 | } | 109 | } |
| 73 | 110 | ||
| 74 | void Symbol::setTableIndex(uint32_t Index) { | 111 | uint32_t FunctionSymbol::getFunctionIndex() const { |
| 75 | DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n"); | 112 | if (auto *F = dyn_cast<DefinedFunction>(this)) |
| 76 | assert(!TableIndex.hasValue()); | 113 | return F->Function->getFunctionIndex(); |
| 114 | assert(FunctionIndex != INVALID_INDEX); | ||
| 115 | return FunctionIndex; | ||
| 116 | } | ||
| 117 | |||
| 118 | void FunctionSymbol::setFunctionIndex(uint32_t Index) { | ||
| 119 | LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n"); | ||
| 120 | assert(FunctionIndex == INVALID_INDEX); | ||
| 121 | FunctionIndex = Index; | ||
| 122 | } | ||
| 123 | |||
| 124 | bool FunctionSymbol::hasFunctionIndex() const { | ||
| 125 | if (auto *F = dyn_cast<DefinedFunction>(this)) | ||
| 126 | return F->Function->hasFunctionIndex(); | ||
| 127 | return FunctionIndex != INVALID_INDEX; | ||
| 128 | } | ||
| 129 | |||
| 130 | uint32_t FunctionSymbol::getTableIndex() const { | ||
| 131 | if (auto *F = dyn_cast<DefinedFunction>(this)) | ||
| 132 | return F->Function->getTableIndex(); | ||
| 133 | assert(TableIndex != INVALID_INDEX); | ||
| 134 | return TableIndex; | ||
| 135 | } | ||
| 136 | |||
| 137 | bool FunctionSymbol::hasTableIndex() const { | ||
| 138 | if (auto *F = dyn_cast<DefinedFunction>(this)) | ||
| 139 | return F->Function->hasTableIndex(); | ||
| 140 | return TableIndex != INVALID_INDEX; | ||
| 141 | } | ||
| 142 | |||
| 143 | void FunctionSymbol::setTableIndex(uint32_t Index) { | ||
| 144 | // For imports, we set the table index here on the Symbol; for defined | ||
| 145 | // functions we set the index on the InputFunction so that we don't export | ||
| 146 | // the same thing twice (keeps the table size down). | ||
| 147 | if (auto *F = dyn_cast<DefinedFunction>(this)) { | ||
| 148 | F->Function->setTableIndex(Index); | ||
| 149 | return; | ||
| 150 | } | ||
| 151 | LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n"); | ||
| 152 | assert(TableIndex == INVALID_INDEX); | ||
| 77 | TableIndex = Index; | 153 | TableIndex = Index; |
| 78 | } | 154 | } |
| 79 | 155 | ||
| 80 | void Symbol::update(Kind K, InputFile *F, const WasmSymbol *WasmSym, | 156 | DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, |
| 81 | const InputSegment *Seg, const WasmSignature *Sig) { | 157 | InputFunction *Function) |
| 82 | SymbolKind = K; | 158 | : FunctionSymbol(Name, DefinedFunctionKind, Flags, F, |
| 83 | File = F; | 159 | Function ? &Function->Signature : nullptr), |
| 84 | Sym = WasmSym; | 160 | Function(Function) {} |
| 85 | Segment = Seg; | 161 | |
| 86 | FunctionType = Sig; | 162 | uint32_t DefinedData::getVirtualAddress() const { |
| 163 | LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); | ||
| 164 | if (Segment) | ||
| 165 | return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset; | ||
| 166 | return Offset; | ||
| 167 | } | ||
| 168 | |||
| 169 | void DefinedData::setVirtualAddress(uint32_t Value) { | ||
| 170 | LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n"); | ||
| 171 | assert(!Segment); | ||
| 172 | Offset = Value; | ||
| 173 | } | ||
| 174 | |||
| 175 | uint32_t DefinedData::getOutputSegmentOffset() const { | ||
| 176 | LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n"); | ||
| 177 | return Segment->OutputSegmentOffset + Offset; | ||
| 178 | } | ||
| 179 | |||
| 180 | uint32_t DefinedData::getOutputSegmentIndex() const { | ||
| 181 | LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n"); | ||
| 182 | return Segment->OutputSeg->Index; | ||
| 183 | } | ||
| 184 | |||
| 185 | uint32_t GlobalSymbol::getGlobalIndex() const { | ||
| 186 | if (auto *F = dyn_cast<DefinedGlobal>(this)) | ||
| 187 | return F->Global->getGlobalIndex(); | ||
| 188 | assert(GlobalIndex != INVALID_INDEX); | ||
| 189 | return GlobalIndex; | ||
| 190 | } | ||
| 191 | |||
| 192 | void GlobalSymbol::setGlobalIndex(uint32_t Index) { | ||
| 193 | LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n"); | ||
| 194 | assert(GlobalIndex == INVALID_INDEX); | ||
| 195 | GlobalIndex = Index; | ||
| 196 | } | ||
| 197 | |||
| 198 | bool GlobalSymbol::hasGlobalIndex() const { | ||
| 199 | if (auto *F = dyn_cast<DefinedGlobal>(this)) | ||
| 200 | return F->Global->hasGlobalIndex(); | ||
| 201 | return GlobalIndex != INVALID_INDEX; | ||
| 87 | } | 202 | } |
| 88 | 203 | ||
| 89 | bool Symbol::isWeak() const { return Sym && Sym->isWeak(); } | 204 | DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, |
| 205 | InputGlobal *Global) | ||
| 206 | : GlobalSymbol(Name, DefinedGlobalKind, Flags, File, | ||
| 207 | Global ? &Global->getType() : nullptr), | ||
| 208 | Global(Global) {} | ||
| 209 | |||
| 210 | uint32_t SectionSymbol::getOutputSectionIndex() const { | ||
| 211 | LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n"); | ||
| 212 | assert(OutputSectionIndex != INVALID_INDEX); | ||
| 213 | return OutputSectionIndex; | ||
| 214 | } | ||
| 215 | |||
| 216 | void SectionSymbol::setOutputSectionIndex(uint32_t Index) { | ||
| 217 | LLVM_DEBUG(dbgs() << "setOutputSectionIndex: " << getName() << " -> " << Index | ||
| 218 | << "\n"); | ||
| 219 | assert(Index != INVALID_INDEX); | ||
| 220 | OutputSectionIndex = Index; | ||
| 221 | } | ||
| 90 | 222 | ||
| 91 | bool Symbol::isHidden() const { return Sym && Sym->isHidden(); } | 223 | void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); } |
| 92 | 224 | ||
| 93 | std::string lld::toString(const wasm::Symbol &Sym) { | 225 | std::string lld::toString(const wasm::Symbol &Sym) { |
| 94 | if (Config->Demangle) | 226 | if (Config->Demangle) |
| 95 | if (Optional<std::string> S = demangleItanium(Sym.getName())) | 227 | if (Optional<std::string> S = demangleItanium(Sym.getName())) |
| 96 | return "`" + *S + "'"; | 228 | return *S; |
| 97 | return Sym.getName(); | 229 | return Sym.getName(); |
| 98 | } | 230 | } |
| 99 | 231 | ||
| ... | @@ -101,14 +233,20 @@ std::string lld::toString(wasm::Symbol::Kind Kind) { | ... | @@ -101,14 +233,20 @@ std::string lld::toString(wasm::Symbol::Kind Kind) { |
| 101 | switch (Kind) { | 233 | switch (Kind) { |
| 102 | case wasm::Symbol::DefinedFunctionKind: | 234 | case wasm::Symbol::DefinedFunctionKind: |
| 103 | return "DefinedFunction"; | 235 | return "DefinedFunction"; |
| 236 | case wasm::Symbol::DefinedDataKind: | ||
| 237 | return "DefinedData"; | ||
| 104 | case wasm::Symbol::DefinedGlobalKind: | 238 | case wasm::Symbol::DefinedGlobalKind: |
| 105 | return "DefinedGlobal"; | 239 | return "DefinedGlobal"; |
| 106 | case wasm::Symbol::UndefinedFunctionKind: | 240 | case wasm::Symbol::UndefinedFunctionKind: |
| 107 | return "UndefinedFunction"; | 241 | return "UndefinedFunction"; |
| 242 | case wasm::Symbol::UndefinedDataKind: | ||
| 243 | return "UndefinedData"; | ||
| 108 | case wasm::Symbol::UndefinedGlobalKind: | 244 | case wasm::Symbol::UndefinedGlobalKind: |
| 109 | return "UndefinedGlobal"; | 245 | return "UndefinedGlobal"; |
| 110 | case wasm::Symbol::LazyKind: | 246 | case wasm::Symbol::LazyKind: |
| 111 | return "LazyKind"; | 247 | return "LazyKind"; |
| 248 | case wasm::Symbol::SectionKind: | ||
| 249 | return "SectionKind"; | ||
| 112 | } | 250 | } |
| 113 | llvm_unreachable("Invalid symbol kind!"); | 251 | llvm_unreachable("invalid symbol kind"); |
| 114 | } | 252 | } |
deps/lld/wasm/Symbols.h+282-55| ... | @@ -10,53 +10,59 @@ | ... | @@ -10,53 +10,59 @@ |
| 10 | #ifndef LLD_WASM_SYMBOLS_H | 10 | #ifndef LLD_WASM_SYMBOLS_H |
| 11 | #define LLD_WASM_SYMBOLS_H | 11 | #define LLD_WASM_SYMBOLS_H |
| 12 | 12 | ||
| 13 | #include "Config.h" | ||
| 13 | #include "lld/Common/LLVM.h" | 14 | #include "lld/Common/LLVM.h" |
| 14 | #include "llvm/Object/Archive.h" | 15 | #include "llvm/Object/Archive.h" |
| 15 | #include "llvm/Object/Wasm.h" | 16 | #include "llvm/Object/Wasm.h" |
| 16 | 17 | ||
| 17 | using llvm::object::Archive; | 18 | using llvm::object::Archive; |
| 18 | using llvm::object::WasmSymbol; | 19 | using llvm::object::WasmSymbol; |
| 19 | using llvm::wasm::WasmExport; | 20 | using llvm::wasm::WasmGlobal; |
| 20 | using llvm::wasm::WasmImport; | 21 | using llvm::wasm::WasmGlobalType; |
| 21 | using llvm::wasm::WasmSignature; | 22 | using llvm::wasm::WasmSignature; |
| 23 | using llvm::wasm::WasmSymbolType; | ||
| 22 | 24 | ||
| 23 | namespace lld { | 25 | namespace lld { |
| 24 | namespace wasm { | 26 | namespace wasm { |
| 25 | 27 | ||
| 26 | class InputFile; | 28 | class InputFile; |
| 29 | class InputChunk; | ||
| 27 | class InputSegment; | 30 | class InputSegment; |
| 31 | class InputFunction; | ||
| 32 | class InputGlobal; | ||
| 33 | class InputSection; | ||
| 28 | 34 | ||
| 35 | #define INVALID_INDEX UINT32_MAX | ||
| 36 | |||
| 37 | // The base class for real symbol classes. | ||
| 29 | class Symbol { | 38 | class Symbol { |
| 30 | public: | 39 | public: |
| 31 | enum Kind { | 40 | enum Kind { |
| 32 | DefinedFunctionKind, | 41 | DefinedFunctionKind, |
| 42 | DefinedDataKind, | ||
| 33 | DefinedGlobalKind, | 43 | DefinedGlobalKind, |
| 34 | 44 | SectionKind, | |
| 35 | LazyKind, | ||
| 36 | UndefinedFunctionKind, | 45 | UndefinedFunctionKind, |
| 46 | UndefinedDataKind, | ||
| 37 | UndefinedGlobalKind, | 47 | UndefinedGlobalKind, |
| 38 | 48 | LazyKind, | |
| 39 | LastDefinedKind = DefinedGlobalKind, | ||
| 40 | InvalidKind, | ||
| 41 | }; | 49 | }; |
| 42 | 50 | ||
| 43 | Symbol(StringRef Name, bool IsLocal) | 51 | Kind kind() const { return SymbolKind; } |
| 44 | : WrittenToSymtab(0), WrittenToNameSec(0), IsLocal(IsLocal), Name(Name) {} | ||
| 45 | 52 | ||
| 46 | Kind getKind() const { return SymbolKind; } | 53 | bool isDefined() const { |
| 54 | return SymbolKind == DefinedFunctionKind || SymbolKind == DefinedDataKind || | ||
| 55 | SymbolKind == DefinedGlobalKind || SymbolKind == SectionKind; | ||
| 56 | } | ||
| 47 | 57 | ||
| 48 | bool isLazy() const { return SymbolKind == LazyKind; } | ||
| 49 | bool isDefined() const { return SymbolKind <= LastDefinedKind; } | ||
| 50 | bool isUndefined() const { | 58 | bool isUndefined() const { |
| 51 | return SymbolKind == UndefinedGlobalKind || | 59 | return SymbolKind == UndefinedFunctionKind || |
| 52 | SymbolKind == UndefinedFunctionKind; | 60 | SymbolKind == UndefinedDataKind || SymbolKind == UndefinedGlobalKind; |
| 53 | } | 61 | } |
| 54 | bool isFunction() const { | 62 | |
| 55 | return SymbolKind == DefinedFunctionKind || | 63 | bool isLazy() const { return SymbolKind == LazyKind; } |
| 56 | SymbolKind == UndefinedFunctionKind; | 64 | |
| 57 | } | 65 | bool isLocal() const; |
| 58 | bool isGlobal() const { return !isFunction(); } | ||
| 59 | bool isLocal() const { return IsLocal; } | ||
| 60 | bool isWeak() const; | 66 | bool isWeak() const; |
| 61 | bool isHidden() const; | 67 | bool isHidden() const; |
| 62 | 68 | ||
| ... | @@ -66,57 +72,278 @@ public: | ... | @@ -66,57 +72,278 @@ public: |
| 66 | // Returns the file from which this symbol was created. | 72 | // Returns the file from which this symbol was created. |
| 67 | InputFile *getFile() const { return File; } | 73 | InputFile *getFile() const { return File; } |
| 68 | 74 | ||
| 69 | uint32_t getGlobalIndex() const; | 75 | InputChunk *getChunk() const; |
| 70 | uint32_t getFunctionIndex() const; | ||
| 71 | 76 | ||
| 72 | bool hasFunctionType() const { return FunctionType != nullptr; } | 77 | // Indicates that the section or import for this symbol will be included in |
| 73 | const WasmSignature &getFunctionType() const; | 78 | // the final image. |
| 74 | uint32_t getOutputIndex() const; | 79 | bool isLive() const; |
| 75 | uint32_t getTableIndex() const { return TableIndex.getValue(); } | ||
| 76 | 80 | ||
| 77 | // Returns the virtual address of a defined global. | 81 | // Marks the symbol's InputChunk as Live, so that it will be included in the |
| 78 | // Only works for globals, not functions. | 82 | // final image. |
| 79 | uint32_t getVirtualAddress() const; | 83 | void markLive(); |
| 84 | |||
| 85 | void setHidden(bool IsHidden); | ||
| 80 | 86 | ||
| 81 | // Set the output index of the symbol (in the function or global index | 87 | // Get/set the index in the output symbol table. This is only used for |
| 82 | // space of the output object. | 88 | // relocatable output. |
| 83 | void setOutputIndex(uint32_t Index); | 89 | uint32_t getOutputSymbolIndex() const; |
| 90 | void setOutputSymbolIndex(uint32_t Index); | ||
| 84 | 91 | ||
| 85 | // Returns true if a table index has been set for this symbol | 92 | WasmSymbolType getWasmType() const; |
| 86 | bool hasTableIndex() const { return TableIndex.hasValue(); } | 93 | bool isExported() const; |
| 87 | 94 | ||
| 88 | // Set the table index of the symbol | 95 | // True if this symbol was referenced by a regular (non-bitcode) object. |
| 96 | unsigned IsUsedInRegularObj : 1; | ||
| 97 | unsigned ForceExport : 1; | ||
| 98 | |||
| 99 | protected: | ||
| 100 | Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F) | ||
| 101 | : IsUsedInRegularObj(false), ForceExport(false), Name(Name), | ||
| 102 | SymbolKind(K), Flags(Flags), File(F), Referenced(!Config->GcSections) {} | ||
| 103 | |||
| 104 | StringRef Name; | ||
| 105 | Kind SymbolKind; | ||
| 106 | uint32_t Flags; | ||
| 107 | InputFile *File; | ||
| 108 | uint32_t OutputSymbolIndex = INVALID_INDEX; | ||
| 109 | bool Referenced; | ||
| 110 | }; | ||
| 111 | |||
| 112 | class FunctionSymbol : public Symbol { | ||
| 113 | public: | ||
| 114 | static bool classof(const Symbol *S) { | ||
| 115 | return S->kind() == DefinedFunctionKind || | ||
| 116 | S->kind() == UndefinedFunctionKind; | ||
| 117 | } | ||
| 118 | |||
| 119 | // Get/set the table index | ||
| 89 | void setTableIndex(uint32_t Index); | 120 | void setTableIndex(uint32_t Index); |
| 121 | uint32_t getTableIndex() const; | ||
| 122 | bool hasTableIndex() const; | ||
| 123 | |||
| 124 | // Get/set the function index | ||
| 125 | uint32_t getFunctionIndex() const; | ||
| 126 | void setFunctionIndex(uint32_t Index); | ||
| 127 | bool hasFunctionIndex() const; | ||
| 90 | 128 | ||
| 129 | const WasmSignature *FunctionType; | ||
| 130 | |||
| 131 | protected: | ||
| 132 | FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, | ||
| 133 | const WasmSignature *Type) | ||
| 134 | : Symbol(Name, K, Flags, F), FunctionType(Type) {} | ||
| 135 | |||
| 136 | uint32_t TableIndex = INVALID_INDEX; | ||
| 137 | uint32_t FunctionIndex = INVALID_INDEX; | ||
| 138 | }; | ||
| 139 | |||
| 140 | class DefinedFunction : public FunctionSymbol { | ||
| 141 | public: | ||
| 142 | DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, | ||
| 143 | InputFunction *Function); | ||
| 144 | |||
| 145 | static bool classof(const Symbol *S) { | ||
| 146 | return S->kind() == DefinedFunctionKind; | ||
| 147 | } | ||
| 148 | |||
| 149 | InputFunction *Function; | ||
| 150 | }; | ||
| 151 | |||
| 152 | class UndefinedFunction : public FunctionSymbol { | ||
| 153 | public: | ||
| 154 | UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr, | ||
| 155 | const WasmSignature *Type = nullptr) | ||
| 156 | : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {} | ||
| 157 | |||
| 158 | static bool classof(const Symbol *S) { | ||
| 159 | return S->kind() == UndefinedFunctionKind; | ||
| 160 | } | ||
| 161 | }; | ||
| 162 | |||
| 163 | class SectionSymbol : public Symbol { | ||
| 164 | public: | ||
| 165 | static bool classof(const Symbol *S) { return S->kind() == SectionKind; } | ||
| 166 | |||
| 167 | SectionSymbol(StringRef Name, uint32_t Flags, const InputSection *S, | ||
| 168 | InputFile *F = nullptr) | ||
| 169 | : Symbol(Name, SectionKind, Flags, F), Section(S) {} | ||
| 170 | |||
| 171 | const InputSection *Section; | ||
| 172 | |||
| 173 | uint32_t getOutputSectionIndex() const; | ||
| 174 | void setOutputSectionIndex(uint32_t Index); | ||
| 175 | |||
| 176 | protected: | ||
| 177 | uint32_t OutputSectionIndex = INVALID_INDEX; | ||
| 178 | }; | ||
| 179 | |||
| 180 | class DataSymbol : public Symbol { | ||
| 181 | public: | ||
| 182 | static bool classof(const Symbol *S) { | ||
| 183 | return S->kind() == DefinedDataKind || S->kind() == UndefinedDataKind; | ||
| 184 | } | ||
| 185 | |||
| 186 | protected: | ||
| 187 | DataSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F) | ||
| 188 | : Symbol(Name, K, Flags, F) {} | ||
| 189 | }; | ||
| 190 | |||
| 191 | class DefinedData : public DataSymbol { | ||
| 192 | public: | ||
| 193 | // Constructor for regular data symbols originating from input files. | ||
| 194 | DefinedData(StringRef Name, uint32_t Flags, InputFile *F, | ||
| 195 | InputSegment *Segment, uint32_t Offset, uint32_t Size) | ||
| 196 | : DataSymbol(Name, DefinedDataKind, Flags, F), Segment(Segment), | ||
| 197 | Offset(Offset), Size(Size) {} | ||
| 198 | |||
| 199 | // Constructor for linker synthetic data symbols. | ||
| 200 | DefinedData(StringRef Name, uint32_t Flags) | ||
| 201 | : DataSymbol(Name, DefinedDataKind, Flags, nullptr) {} | ||
| 202 | |||
| 203 | static bool classof(const Symbol *S) { return S->kind() == DefinedDataKind; } | ||
| 204 | |||
| 205 | // Returns the output virtual address of a defined data symbol. | ||
| 206 | uint32_t getVirtualAddress() const; | ||
| 91 | void setVirtualAddress(uint32_t VA); | 207 | void setVirtualAddress(uint32_t VA); |
| 92 | 208 | ||
| 93 | void update(Kind K, InputFile *F = nullptr, const WasmSymbol *Sym = nullptr, | 209 | // Returns the offset of a defined data symbol within its OutputSegment. |
| 94 | const InputSegment *Segment = nullptr, | 210 | uint32_t getOutputSegmentOffset() const; |
| 95 | const WasmSignature *Sig = nullptr); | 211 | uint32_t getOutputSegmentIndex() const; |
| 212 | uint32_t getSize() const { return Size; } | ||
| 213 | |||
| 214 | InputSegment *Segment = nullptr; | ||
| 215 | |||
| 216 | protected: | ||
| 217 | uint32_t Offset = 0; | ||
| 218 | uint32_t Size = 0; | ||
| 219 | }; | ||
| 220 | |||
| 221 | class UndefinedData : public DataSymbol { | ||
| 222 | public: | ||
| 223 | UndefinedData(StringRef Name, uint32_t Flags, InputFile *File = nullptr) | ||
| 224 | : DataSymbol(Name, UndefinedDataKind, Flags, File) {} | ||
| 225 | static bool classof(const Symbol *S) { | ||
| 226 | return S->kind() == UndefinedDataKind; | ||
| 227 | } | ||
| 228 | }; | ||
| 96 | 229 | ||
| 97 | void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol = Sym; } | 230 | class GlobalSymbol : public Symbol { |
| 98 | const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; } | 231 | public: |
| 232 | static bool classof(const Symbol *S) { | ||
| 233 | return S->kind() == DefinedGlobalKind || S->kind() == UndefinedGlobalKind; | ||
| 234 | } | ||
| 99 | 235 | ||
| 100 | // This bit is used by Writer::writeNameSection() to prevent | 236 | const WasmGlobalType *getGlobalType() const { return GlobalType; } |
| 101 | // symbols from being written to the symbol table more than once. | 237 | |
| 102 | unsigned WrittenToSymtab : 1; | 238 | // Get/set the global index |
| 103 | unsigned WrittenToNameSec : 1; | 239 | uint32_t getGlobalIndex() const; |
| 240 | void setGlobalIndex(uint32_t Index); | ||
| 241 | bool hasGlobalIndex() const; | ||
| 104 | 242 | ||
| 105 | protected: | 243 | protected: |
| 106 | unsigned IsLocal : 1; | 244 | GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, |
| 245 | const WasmGlobalType *GlobalType) | ||
| 246 | : Symbol(Name, K, Flags, F), GlobalType(GlobalType) {} | ||
| 107 | 247 | ||
| 108 | StringRef Name; | 248 | // Explicit function type, needed for undefined or synthetic functions only. |
| 109 | Archive::Symbol ArchiveSymbol = {nullptr, 0, 0}; | 249 | // For regular defined globals this information comes from the InputChunk. |
| 110 | Kind SymbolKind = InvalidKind; | 250 | const WasmGlobalType *GlobalType; |
| 111 | InputFile *File = nullptr; | 251 | uint32_t GlobalIndex = INVALID_INDEX; |
| 112 | const WasmSymbol *Sym = nullptr; | ||
| 113 | const InputSegment *Segment = nullptr; | ||
| 114 | llvm::Optional<uint32_t> OutputIndex; | ||
| 115 | llvm::Optional<uint32_t> TableIndex; | ||
| 116 | llvm::Optional<uint32_t> VirtualAddress; | ||
| 117 | const WasmSignature *FunctionType; | ||
| 118 | }; | 252 | }; |
| 119 | 253 | ||
| 254 | class DefinedGlobal : public GlobalSymbol { | ||
| 255 | public: | ||
| 256 | DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, | ||
| 257 | InputGlobal *Global); | ||
| 258 | |||
| 259 | static bool classof(const Symbol *S) { | ||
| 260 | return S->kind() == DefinedGlobalKind; | ||
| 261 | } | ||
| 262 | |||
| 263 | InputGlobal *Global; | ||
| 264 | }; | ||
| 265 | |||
| 266 | class UndefinedGlobal : public GlobalSymbol { | ||
| 267 | public: | ||
| 268 | UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr, | ||
| 269 | const WasmGlobalType *Type = nullptr) | ||
| 270 | : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type) {} | ||
| 271 | |||
| 272 | static bool classof(const Symbol *S) { | ||
| 273 | return S->kind() == UndefinedGlobalKind; | ||
| 274 | } | ||
| 275 | }; | ||
| 276 | |||
| 277 | class LazySymbol : public Symbol { | ||
| 278 | public: | ||
| 279 | LazySymbol(StringRef Name, InputFile *File, const Archive::Symbol &Sym) | ||
| 280 | : Symbol(Name, LazyKind, 0, File), ArchiveSymbol(Sym) {} | ||
| 281 | |||
| 282 | static bool classof(const Symbol *S) { return S->kind() == LazyKind; } | ||
| 283 | void fetch(); | ||
| 284 | |||
| 285 | private: | ||
| 286 | Archive::Symbol ArchiveSymbol; | ||
| 287 | }; | ||
| 288 | |||
| 289 | // linker-generated symbols | ||
| 290 | struct WasmSym { | ||
| 291 | // __stack_pointer | ||
| 292 | // Global that holds the address of the top of the explicit value stack in | ||
| 293 | // linear memory. | ||
| 294 | static DefinedGlobal *StackPointer; | ||
| 295 | |||
| 296 | // __data_end | ||
| 297 | // Symbol marking the end of the data and bss. | ||
| 298 | static DefinedData *DataEnd; | ||
| 299 | |||
| 300 | // __heap_base | ||
| 301 | // Symbol marking the end of the data, bss and explicit stack. Any linear | ||
| 302 | // memory following this address is not used by the linked code and can | ||
| 303 | // therefore be used as a backing store for brk()/malloc() implementations. | ||
| 304 | static DefinedData *HeapBase; | ||
| 305 | |||
| 306 | // __wasm_call_ctors | ||
| 307 | // Function that directly calls all ctors in priority order. | ||
| 308 | static DefinedFunction *CallCtors; | ||
| 309 | |||
| 310 | // __dso_handle | ||
| 311 | // Symbol used in calls to __cxa_atexit to determine current DLL | ||
| 312 | static DefinedData *DsoHandle; | ||
| 313 | }; | ||
| 314 | |||
| 315 | // A buffer class that is large enough to hold any Symbol-derived | ||
| 316 | // object. We allocate memory using this class and instantiate a symbol | ||
| 317 | // using the placement new. | ||
| 318 | union SymbolUnion { | ||
| 319 | alignas(DefinedFunction) char A[sizeof(DefinedFunction)]; | ||
| 320 | alignas(DefinedData) char B[sizeof(DefinedData)]; | ||
| 321 | alignas(DefinedGlobal) char C[sizeof(DefinedGlobal)]; | ||
| 322 | alignas(LazySymbol) char D[sizeof(LazySymbol)]; | ||
| 323 | alignas(UndefinedFunction) char E[sizeof(UndefinedFunction)]; | ||
| 324 | alignas(UndefinedData) char F[sizeof(UndefinedData)]; | ||
| 325 | alignas(UndefinedGlobal) char G[sizeof(UndefinedGlobal)]; | ||
| 326 | alignas(SectionSymbol) char I[sizeof(SectionSymbol)]; | ||
| 327 | }; | ||
| 328 | |||
| 329 | template <typename T, typename... ArgT> | ||
| 330 | T *replaceSymbol(Symbol *S, ArgT &&... Arg) { | ||
| 331 | static_assert(std::is_trivially_destructible<T>(), | ||
| 332 | "Symbol types must be trivially destructible"); | ||
| 333 | static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small"); | ||
| 334 | static_assert(alignof(T) <= alignof(SymbolUnion), | ||
| 335 | "SymbolUnion not aligned enough"); | ||
| 336 | assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr && | ||
| 337 | "Not a Symbol"); | ||
| 338 | |||
| 339 | Symbol SymCopy = *S; | ||
| 340 | |||
| 341 | T *S2 = new (S) T(std::forward<ArgT>(Arg)...); | ||
| 342 | S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj; | ||
| 343 | S2->ForceExport = SymCopy.ForceExport; | ||
| 344 | return S2; | ||
| 345 | } | ||
| 346 | |||
| 120 | } // namespace wasm | 347 | } // namespace wasm |
| 121 | 348 | ||
| 122 | // Returns a symbol name for an error message. | 349 | // Returns a symbol name for an error message. |
deps/lld/wasm/Writer.cpp+645-309| ... | @@ -8,21 +8,28 @@ | ... | @@ -8,21 +8,28 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | ||
| 10 | #include "Writer.h" | 10 | #include "Writer.h" |
| 11 | |||
| 12 | #include "Config.h" | 11 | #include "Config.h" |
| 12 | #include "InputChunks.h" | ||
| 13 | #include "InputGlobal.h" | ||
| 13 | #include "OutputSections.h" | 14 | #include "OutputSections.h" |
| 14 | #include "OutputSegment.h" | 15 | #include "OutputSegment.h" |
| 15 | #include "SymbolTable.h" | 16 | #include "SymbolTable.h" |
| 16 | #include "WriterUtils.h" | 17 | #include "WriterUtils.h" |
| 17 | #include "lld/Common/ErrorHandler.h" | 18 | #include "lld/Common/ErrorHandler.h" |
| 18 | #include "lld/Common/Memory.h" | 19 | #include "lld/Common/Memory.h" |
| 20 | #include "lld/Common/Strings.h" | ||
| 19 | #include "lld/Common/Threads.h" | 21 | #include "lld/Common/Threads.h" |
| 22 | #include "llvm/ADT/DenseSet.h" | ||
| 23 | #include "llvm/ADT/StringMap.h" | ||
| 24 | #include "llvm/BinaryFormat/Wasm.h" | ||
| 25 | #include "llvm/Object/WasmTraits.h" | ||
| 20 | #include "llvm/Support/FileOutputBuffer.h" | 26 | #include "llvm/Support/FileOutputBuffer.h" |
| 21 | #include "llvm/Support/Format.h" | 27 | #include "llvm/Support/Format.h" |
| 22 | #include "llvm/Support/FormatVariadic.h" | 28 | #include "llvm/Support/FormatVariadic.h" |
| 23 | #include "llvm/Support/LEB128.h" | 29 | #include "llvm/Support/LEB128.h" |
| 24 | 30 | ||
| 25 | #include <cstdarg> | 31 | #include <cstdarg> |
| 32 | #include <map> | ||
| 26 | 33 | ||
| 27 | #define DEBUG_TYPE "lld" | 34 | #define DEBUG_TYPE "lld" |
| 28 | 35 | ||
| ... | @@ -32,31 +39,16 @@ using namespace lld; | ... | @@ -32,31 +39,16 @@ using namespace lld; |
| 32 | using namespace lld::wasm; | 39 | using namespace lld::wasm; |
| 33 | 40 | ||
| 34 | static constexpr int kStackAlignment = 16; | 41 | static constexpr int kStackAlignment = 16; |
| 42 | static constexpr int kInitialTableOffset = 1; | ||
| 43 | static constexpr const char *kFunctionTableName = "__indirect_function_table"; | ||
| 35 | 44 | ||
| 36 | namespace { | 45 | namespace { |
| 37 | 46 | ||
| 38 | // Traits for using WasmSignature in a DenseMap. | 47 | // An init entry to be written to either the synthetic init func or the |
| 39 | struct WasmSignatureDenseMapInfo { | 48 | // linking metadata. |
| 40 | static WasmSignature getEmptyKey() { | 49 | struct WasmInitEntry { |
| 41 | WasmSignature Sig; | 50 | const FunctionSymbol *Sym; |
| 42 | Sig.ReturnType = 1; | 51 | uint32_t Priority; |
| 43 | return Sig; | ||
| 44 | } | ||
| 45 | static WasmSignature getTombstoneKey() { | ||
| 46 | WasmSignature Sig; | ||
| 47 | Sig.ReturnType = 2; | ||
| 48 | return Sig; | ||
| 49 | } | ||
| 50 | static unsigned getHashValue(const WasmSignature &Sig) { | ||
| 51 | uintptr_t Value = 0; | ||
| 52 | Value += DenseMapInfo<int32_t>::getHashValue(Sig.ReturnType); | ||
| 53 | for (int32_t Param : Sig.ParamTypes) | ||
| 54 | Value += DenseMapInfo<int32_t>::getHashValue(Param); | ||
| 55 | return Value; | ||
| 56 | } | ||
| 57 | static bool isEqual(const WasmSignature &LHS, const WasmSignature &RHS) { | ||
| 58 | return LHS == RHS; | ||
| 59 | } | ||
| 60 | }; | 52 | }; |
| 61 | 53 | ||
| 62 | // The writer writes a SymbolTable result to a file. | 54 | // The writer writes a SymbolTable result to a file. |
| ... | @@ -67,17 +59,22 @@ public: | ... | @@ -67,17 +59,22 @@ public: |
| 67 | private: | 59 | private: |
| 68 | void openFile(); | 60 | void openFile(); |
| 69 | 61 | ||
| 70 | uint32_t getTypeIndex(const WasmSignature &Sig); | 62 | uint32_t lookupType(const WasmSignature &Sig); |
| 71 | void assignSymbolIndexes(); | 63 | uint32_t registerType(const WasmSignature &Sig); |
| 64 | |||
| 65 | void createCtorFunction(); | ||
| 66 | void calculateInitFunctions(); | ||
| 67 | void assignIndexes(); | ||
| 72 | void calculateImports(); | 68 | void calculateImports(); |
| 73 | void calculateOffsets(); | 69 | void calculateExports(); |
| 70 | void calculateCustomSections(); | ||
| 71 | void assignSymtab(); | ||
| 74 | void calculateTypes(); | 72 | void calculateTypes(); |
| 75 | void createOutputSegments(); | 73 | void createOutputSegments(); |
| 76 | void layoutMemory(); | 74 | void layoutMemory(); |
| 77 | void createHeader(); | 75 | void createHeader(); |
| 78 | void createSections(); | 76 | void createSections(); |
| 79 | SyntheticSection *createSyntheticSection(uint32_t Type, | 77 | SyntheticSection *createSyntheticSection(uint32_t Type, StringRef Name = ""); |
| 80 | std::string Name = ""); | ||
| 81 | 78 | ||
| 82 | // Builtin sections | 79 | // Builtin sections |
| 83 | void createTypeSection(); | 80 | void createTypeSection(); |
| ... | @@ -88,9 +85,9 @@ private: | ... | @@ -88,9 +85,9 @@ private: |
| 88 | void createImportSection(); | 85 | void createImportSection(); |
| 89 | void createMemorySection(); | 86 | void createMemorySection(); |
| 90 | void createElemSection(); | 87 | void createElemSection(); |
| 91 | void createStartSection(); | ||
| 92 | void createCodeSection(); | 88 | void createCodeSection(); |
| 93 | void createDataSection(); | 89 | void createDataSection(); |
| 90 | void createCustomSections(); | ||
| 94 | 91 | ||
| 95 | // Custom sections | 92 | // Custom sections |
| 96 | void createRelocSections(); | 93 | void createRelocSections(); |
| ... | @@ -101,17 +98,24 @@ private: | ... | @@ -101,17 +98,24 @@ private: |
| 101 | void writeSections(); | 98 | void writeSections(); |
| 102 | 99 | ||
| 103 | uint64_t FileSize = 0; | 100 | uint64_t FileSize = 0; |
| 104 | uint32_t DataSize = 0; | ||
| 105 | uint32_t NumFunctions = 0; | ||
| 106 | uint32_t NumMemoryPages = 0; | 101 | uint32_t NumMemoryPages = 0; |
| 107 | uint32_t InitialTableOffset = 0; | 102 | uint32_t MaxMemoryPages = 0; |
| 108 | 103 | ||
| 109 | std::vector<const WasmSignature *> Types; | 104 | std::vector<const WasmSignature *> Types; |
| 110 | DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices; | 105 | DenseMap<WasmSignature, int32_t> TypeIndices; |
| 111 | std::vector<const Symbol *> FunctionImports; | 106 | std::vector<const Symbol *> ImportedSymbols; |
| 112 | std::vector<const Symbol *> GlobalImports; | 107 | unsigned NumImportedFunctions = 0; |
| 113 | std::vector<const Symbol *> DefinedGlobals; | 108 | unsigned NumImportedGlobals = 0; |
| 114 | std::vector<const Symbol *> IndirectFunctions; | 109 | std::vector<WasmExport> Exports; |
| 110 | std::vector<const DefinedData *> DefinedFakeGlobals; | ||
| 111 | std::vector<InputGlobal *> InputGlobals; | ||
| 112 | std::vector<InputFunction *> InputFunctions; | ||
| 113 | std::vector<const FunctionSymbol *> IndirectFunctions; | ||
| 114 | std::vector<const Symbol *> SymtabEntries; | ||
| 115 | std::vector<WasmInitEntry> InitFunctions; | ||
| 116 | |||
| 117 | llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping; | ||
| 118 | llvm::StringMap<SectionSymbol *> CustomSectionSymbols; | ||
| 115 | 119 | ||
| 116 | // Elements that are used to construct the final output | 120 | // Elements that are used to construct the final output |
| 117 | std::string Header; | 121 | std::string Header; |
| ... | @@ -125,20 +129,12 @@ private: | ... | @@ -125,20 +129,12 @@ private: |
| 125 | 129 | ||
| 126 | } // anonymous namespace | 130 | } // anonymous namespace |
| 127 | 131 | ||
| 128 | static void debugPrint(const char *fmt, ...) { | ||
| 129 | if (!errorHandler().Verbose) | ||
| 130 | return; | ||
| 131 | fprintf(stderr, "lld: "); | ||
| 132 | va_list ap; | ||
| 133 | va_start(ap, fmt); | ||
| 134 | vfprintf(stderr, fmt, ap); | ||
| 135 | va_end(ap); | ||
| 136 | } | ||
| 137 | |||
| 138 | void Writer::createImportSection() { | 132 | void Writer::createImportSection() { |
| 139 | uint32_t NumImports = FunctionImports.size() + GlobalImports.size(); | 133 | uint32_t NumImports = ImportedSymbols.size(); |
| 140 | if (Config->ImportMemory) | 134 | if (Config->ImportMemory) |
| 141 | ++NumImports; | 135 | ++NumImports; |
| 136 | if (Config->ImportTable) | ||
| 137 | ++NumImports; | ||
| 142 | 138 | ||
| 143 | if (NumImports == 0) | 139 | if (NumImports == 0) |
| 144 | return; | 140 | return; |
| ... | @@ -148,16 +144,6 @@ void Writer::createImportSection() { | ... | @@ -148,16 +144,6 @@ void Writer::createImportSection() { |
| 148 | 144 | ||
| 149 | writeUleb128(OS, NumImports, "import count"); | 145 | writeUleb128(OS, NumImports, "import count"); |
| 150 | 146 | ||
| 151 | for (const Symbol *Sym : FunctionImports) { | ||
| 152 | WasmImport Import; | ||
| 153 | Import.Module = "env"; | ||
| 154 | Import.Field = Sym->getName(); | ||
| 155 | Import.Kind = WASM_EXTERNAL_FUNCTION; | ||
| 156 | assert(TypeIndices.count(Sym->getFunctionType()) > 0); | ||
| 157 | Import.SigIndex = TypeIndices.lookup(Sym->getFunctionType()); | ||
| 158 | writeImport(OS, Import); | ||
| 159 | } | ||
| 160 | |||
| 161 | if (Config->ImportMemory) { | 147 | if (Config->ImportMemory) { |
| 162 | WasmImport Import; | 148 | WasmImport Import; |
| 163 | Import.Module = "env"; | 149 | Import.Module = "env"; |
| ... | @@ -165,16 +151,36 @@ void Writer::createImportSection() { | ... | @@ -165,16 +151,36 @@ void Writer::createImportSection() { |
| 165 | Import.Kind = WASM_EXTERNAL_MEMORY; | 151 | Import.Kind = WASM_EXTERNAL_MEMORY; |
| 166 | Import.Memory.Flags = 0; | 152 | Import.Memory.Flags = 0; |
| 167 | Import.Memory.Initial = NumMemoryPages; | 153 | Import.Memory.Initial = NumMemoryPages; |
| 154 | if (MaxMemoryPages != 0) { | ||
| 155 | Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; | ||
| 156 | Import.Memory.Maximum = MaxMemoryPages; | ||
| 157 | } | ||
| 168 | writeImport(OS, Import); | 158 | writeImport(OS, Import); |
| 169 | } | 159 | } |
| 170 | 160 | ||
| 171 | for (const Symbol *Sym : GlobalImports) { | 161 | if (Config->ImportTable) { |
| 162 | uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size(); | ||
| 163 | WasmImport Import; | ||
| 164 | Import.Module = "env"; | ||
| 165 | Import.Field = kFunctionTableName; | ||
| 166 | Import.Kind = WASM_EXTERNAL_TABLE; | ||
| 167 | Import.Table.ElemType = WASM_TYPE_ANYFUNC; | ||
| 168 | Import.Table.Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize}; | ||
| 169 | writeImport(OS, Import); | ||
| 170 | } | ||
| 171 | |||
| 172 | for (const Symbol *Sym : ImportedSymbols) { | ||
| 172 | WasmImport Import; | 173 | WasmImport Import; |
| 173 | Import.Module = "env"; | 174 | Import.Module = "env"; |
| 174 | Import.Field = Sym->getName(); | 175 | Import.Field = Sym->getName(); |
| 175 | Import.Kind = WASM_EXTERNAL_GLOBAL; | 176 | if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) { |
| 176 | Import.Global.Mutable = false; | 177 | Import.Kind = WASM_EXTERNAL_FUNCTION; |
| 177 | Import.Global.Type = WASM_TYPE_I32; | 178 | Import.SigIndex = lookupType(*FunctionSym->FunctionType); |
| 179 | } else { | ||
| 180 | auto *GlobalSym = cast<GlobalSymbol>(Sym); | ||
| 181 | Import.Kind = WASM_EXTERNAL_GLOBAL; | ||
| 182 | Import.Global = *GlobalSym->getGlobalType(); | ||
| 183 | } | ||
| 178 | writeImport(OS, Import); | 184 | writeImport(OS, Import); |
| 179 | } | 185 | } |
| 180 | } | 186 | } |
| ... | @@ -188,16 +194,15 @@ void Writer::createTypeSection() { | ... | @@ -188,16 +194,15 @@ void Writer::createTypeSection() { |
| 188 | } | 194 | } |
| 189 | 195 | ||
| 190 | void Writer::createFunctionSection() { | 196 | void Writer::createFunctionSection() { |
| 191 | if (!NumFunctions) | 197 | if (InputFunctions.empty()) |
| 192 | return; | 198 | return; |
| 193 | 199 | ||
| 194 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION); | 200 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION); |
| 195 | raw_ostream &OS = Section->getStream(); | 201 | raw_ostream &OS = Section->getStream(); |
| 196 | 202 | ||
| 197 | writeUleb128(OS, NumFunctions, "function count"); | 203 | writeUleb128(OS, InputFunctions.size(), "function count"); |
| 198 | for (ObjFile *File : Symtab->ObjectFiles) | 204 | for (const InputFunction *Func : InputFunctions) |
| 199 | for (uint32_t Sig : File->getWasmObj()->functionTypes()) | 205 | writeUleb128(OS, lookupType(Func->Signature), "sig index"); |
| 200 | writeUleb128(OS, File->relocateTypeIndex(Sig), "sig index"); | ||
| 201 | } | 206 | } |
| 202 | 207 | ||
| 203 | void Writer::createMemorySection() { | 208 | void Writer::createMemorySection() { |
| ... | @@ -207,23 +212,29 @@ void Writer::createMemorySection() { | ... | @@ -207,23 +212,29 @@ void Writer::createMemorySection() { |
| 207 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY); | 212 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY); |
| 208 | raw_ostream &OS = Section->getStream(); | 213 | raw_ostream &OS = Section->getStream(); |
| 209 | 214 | ||
| 215 | bool HasMax = MaxMemoryPages != 0; | ||
| 210 | writeUleb128(OS, 1, "memory count"); | 216 | writeUleb128(OS, 1, "memory count"); |
| 211 | writeUleb128(OS, 0, "memory limits flags"); | 217 | writeUleb128(OS, HasMax ? static_cast<unsigned>(WASM_LIMITS_FLAG_HAS_MAX) : 0, |
| 218 | "memory limits flags"); | ||
| 212 | writeUleb128(OS, NumMemoryPages, "initial pages"); | 219 | writeUleb128(OS, NumMemoryPages, "initial pages"); |
| 220 | if (HasMax) | ||
| 221 | writeUleb128(OS, MaxMemoryPages, "max pages"); | ||
| 213 | } | 222 | } |
| 214 | 223 | ||
| 215 | void Writer::createGlobalSection() { | 224 | void Writer::createGlobalSection() { |
| 216 | if (DefinedGlobals.empty()) | 225 | unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size(); |
| 226 | if (NumGlobals == 0) | ||
| 217 | return; | 227 | return; |
| 218 | 228 | ||
| 219 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL); | 229 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL); |
| 220 | raw_ostream &OS = Section->getStream(); | 230 | raw_ostream &OS = Section->getStream(); |
| 221 | 231 | ||
| 222 | writeUleb128(OS, DefinedGlobals.size(), "global count"); | 232 | writeUleb128(OS, NumGlobals, "global count"); |
| 223 | for (const Symbol *Sym : DefinedGlobals) { | 233 | for (const InputGlobal *G : InputGlobals) |
| 234 | writeGlobal(OS, G->Global); | ||
| 235 | for (const DefinedData *Sym : DefinedFakeGlobals) { | ||
| 224 | WasmGlobal Global; | 236 | WasmGlobal Global; |
| 225 | Global.Type = WASM_TYPE_I32; | 237 | Global.Type = {WASM_TYPE_I32, false}; |
| 226 | Global.Mutable = Sym == Config->StackPointerSymbol; | ||
| 227 | Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; | 238 | Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; |
| 228 | Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); | 239 | Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); |
| 229 | writeGlobal(OS, Global); | 240 | writeGlobal(OS, Global); |
| ... | @@ -231,88 +242,73 @@ void Writer::createGlobalSection() { | ... | @@ -231,88 +242,73 @@ void Writer::createGlobalSection() { |
| 231 | } | 242 | } |
| 232 | 243 | ||
| 233 | void Writer::createTableSection() { | 244 | void Writer::createTableSection() { |
| 234 | // Always output a table section, even if there are no indirect calls. | 245 | if (Config->ImportTable) |
| 235 | // There are two reasons for this: | 246 | return; |
| 247 | |||
| 248 | // Always output a table section (or table import), even if there are no | ||
| 249 | // indirect calls. There are two reasons for this: | ||
| 236 | // 1. For executables it is useful to have an empty table slot at 0 | 250 | // 1. For executables it is useful to have an empty table slot at 0 |
| 237 | // which can be filled with a null function call handler. | 251 | // which can be filled with a null function call handler. |
| 238 | // 2. If we don't do this, any program that contains a call_indirect but | 252 | // 2. If we don't do this, any program that contains a call_indirect but |
| 239 | // no address-taken function will fail at validation time since it is | 253 | // no address-taken function will fail at validation time since it is |
| 240 | // a validation error to include a call_indirect instruction if there | 254 | // a validation error to include a call_indirect instruction if there |
| 241 | // is not table. | 255 | // is not table. |
| 242 | uint32_t TableSize = InitialTableOffset + IndirectFunctions.size(); | 256 | uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size(); |
| 243 | 257 | ||
| 244 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE); | 258 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE); |
| 245 | raw_ostream &OS = Section->getStream(); | 259 | raw_ostream &OS = Section->getStream(); |
| 246 | 260 | ||
| 247 | writeUleb128(OS, 1, "table count"); | 261 | writeUleb128(OS, 1, "table count"); |
| 248 | writeSleb128(OS, WASM_TYPE_ANYFUNC, "table type"); | 262 | WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize}; |
| 249 | writeUleb128(OS, WASM_LIMITS_FLAG_HAS_MAX, "table flags"); | 263 | writeTableType(OS, WasmTable{WASM_TYPE_ANYFUNC, Limits}); |
| 250 | writeUleb128(OS, TableSize, "table initial size"); | ||
| 251 | writeUleb128(OS, TableSize, "table max size"); | ||
| 252 | } | 264 | } |
| 253 | 265 | ||
| 254 | void Writer::createExportSection() { | 266 | void Writer::createExportSection() { |
| 255 | bool ExportMemory = !Config->Relocatable && !Config->ImportMemory; | 267 | if (!Exports.size()) |
| 256 | Symbol *EntrySym = Symtab->find(Config->Entry); | ||
| 257 | bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined(); | ||
| 258 | bool ExportHidden = Config->EmitRelocs; | ||
| 259 | |||
| 260 | uint32_t NumExports = ExportMemory ? 1 : 0; | ||
| 261 | |||
| 262 | std::vector<const Symbol *> SymbolExports; | ||
| 263 | if (ExportEntry) | ||
| 264 | SymbolExports.emplace_back(EntrySym); | ||
| 265 | |||
| 266 | for (const Symbol *Sym : Symtab->getSymbols()) { | ||
| 267 | if (Sym->isUndefined() || Sym->isGlobal()) | ||
| 268 | continue; | ||
| 269 | if (Sym->isHidden() && !ExportHidden) | ||
| 270 | continue; | ||
| 271 | if (ExportEntry && Sym == EntrySym) | ||
| 272 | continue; | ||
| 273 | SymbolExports.emplace_back(Sym); | ||
| 274 | } | ||
| 275 | |||
| 276 | for (const Symbol *Sym : DefinedGlobals) { | ||
| 277 | // Can't export the SP right now because it mutable and mutable globals | ||
| 278 | // connot be exported. | ||
| 279 | if (Sym == Config->StackPointerSymbol) | ||
| 280 | continue; | ||
| 281 | SymbolExports.emplace_back(Sym); | ||
| 282 | } | ||
| 283 | |||
| 284 | NumExports += SymbolExports.size(); | ||
| 285 | if (!NumExports) | ||
| 286 | return; | 268 | return; |
| 287 | 269 | ||
| 288 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT); | 270 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT); |
| 289 | raw_ostream &OS = Section->getStream(); | 271 | raw_ostream &OS = Section->getStream(); |
| 290 | 272 | ||
| 291 | writeUleb128(OS, NumExports, "export count"); | 273 | writeUleb128(OS, Exports.size(), "export count"); |
| 274 | for (const WasmExport &Export : Exports) | ||
| 275 | writeExport(OS, Export); | ||
| 276 | } | ||
| 292 | 277 | ||
| 293 | if (ExportMemory) { | 278 | void Writer::calculateCustomSections() { |
| 294 | WasmExport MemoryExport; | 279 | log("calculateCustomSections"); |
| 295 | MemoryExport.Name = "memory"; | 280 | bool StripDebug = Config->StripDebug || Config->StripAll; |
| 296 | MemoryExport.Kind = WASM_EXTERNAL_MEMORY; | 281 | for (ObjFile *File : Symtab->ObjectFiles) { |
| 297 | MemoryExport.Index = 0; | 282 | for (InputSection *Section : File->CustomSections) { |
| 298 | writeExport(OS, MemoryExport); | 283 | StringRef Name = Section->getName(); |
| 284 | // These custom sections are known the linker and synthesized rather than | ||
| 285 | // blindly copied | ||
| 286 | if (Name == "linking" || Name == "name" || Name.startswith("reloc.")) | ||
| 287 | continue; | ||
| 288 | // .. or it is a debug section | ||
| 289 | if (StripDebug && Name.startswith(".debug_")) | ||
| 290 | continue; | ||
| 291 | CustomSectionMapping[Name].push_back(Section); | ||
| 292 | } | ||
| 299 | } | 293 | } |
| 294 | } | ||
| 300 | 295 | ||
| 301 | for (const Symbol *Sym : SymbolExports) { | 296 | void Writer::createCustomSections() { |
| 302 | log("Export: " + Sym->getName()); | 297 | log("createCustomSections"); |
| 303 | WasmExport Export; | 298 | for (auto &Pair : CustomSectionMapping) { |
| 304 | Export.Name = Sym->getName(); | 299 | StringRef Name = Pair.first(); |
| 305 | Export.Index = Sym->getOutputIndex(); | 300 | |
| 306 | if (Sym->isFunction()) | 301 | auto P = CustomSectionSymbols.find(Name); |
| 307 | Export.Kind = WASM_EXTERNAL_FUNCTION; | 302 | if (P != CustomSectionSymbols.end()) { |
| 308 | else | 303 | uint32_t SectionIndex = OutputSections.size(); |
| 309 | Export.Kind = WASM_EXTERNAL_GLOBAL; | 304 | P->second->setOutputSectionIndex(SectionIndex); |
| 310 | writeExport(OS, Export); | 305 | } |
| 306 | |||
| 307 | LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n"); | ||
| 308 | OutputSections.push_back(make<CustomSection>(Name, Pair.second)); | ||
| 311 | } | 309 | } |
| 312 | } | 310 | } |
| 313 | 311 | ||
| 314 | void Writer::createStartSection() {} | ||
| 315 | |||
| 316 | void Writer::createElemSection() { | 312 | void Writer::createElemSection() { |
| 317 | if (IndirectFunctions.empty()) | 313 | if (IndirectFunctions.empty()) |
| 318 | return; | 314 | return; |
| ... | @@ -324,25 +320,25 @@ void Writer::createElemSection() { | ... | @@ -324,25 +320,25 @@ void Writer::createElemSection() { |
| 324 | writeUleb128(OS, 0, "table index"); | 320 | writeUleb128(OS, 0, "table index"); |
| 325 | WasmInitExpr InitExpr; | 321 | WasmInitExpr InitExpr; |
| 326 | InitExpr.Opcode = WASM_OPCODE_I32_CONST; | 322 | InitExpr.Opcode = WASM_OPCODE_I32_CONST; |
| 327 | InitExpr.Value.Int32 = InitialTableOffset; | 323 | InitExpr.Value.Int32 = kInitialTableOffset; |
| 328 | writeInitExpr(OS, InitExpr); | 324 | writeInitExpr(OS, InitExpr); |
| 329 | writeUleb128(OS, IndirectFunctions.size(), "elem count"); | 325 | writeUleb128(OS, IndirectFunctions.size(), "elem count"); |
| 330 | 326 | ||
| 331 | uint32_t TableIndex = InitialTableOffset; | 327 | uint32_t TableIndex = kInitialTableOffset; |
| 332 | for (const Symbol *Sym : IndirectFunctions) { | 328 | for (const FunctionSymbol *Sym : IndirectFunctions) { |
| 333 | assert(Sym->getTableIndex() == TableIndex); | 329 | assert(Sym->getTableIndex() == TableIndex); |
| 334 | writeUleb128(OS, Sym->getOutputIndex(), "function index"); | 330 | writeUleb128(OS, Sym->getFunctionIndex(), "function index"); |
| 335 | ++TableIndex; | 331 | ++TableIndex; |
| 336 | } | 332 | } |
| 337 | } | 333 | } |
| 338 | 334 | ||
| 339 | void Writer::createCodeSection() { | 335 | void Writer::createCodeSection() { |
| 340 | if (!NumFunctions) | 336 | if (InputFunctions.empty()) |
| 341 | return; | 337 | return; |
| 342 | 338 | ||
| 343 | log("createCodeSection"); | 339 | log("createCodeSection"); |
| 344 | 340 | ||
| 345 | auto Section = make<CodeSection>(NumFunctions, Symtab->ObjectFiles); | 341 | auto Section = make<CodeSection>(InputFunctions); |
| 346 | OutputSections.push_back(Section); | 342 | OutputSections.push_back(Section); |
| 347 | } | 343 | } |
| 348 | 344 | ||
| ... | @@ -361,28 +357,68 @@ void Writer::createRelocSections() { | ... | @@ -361,28 +357,68 @@ void Writer::createRelocSections() { |
| 361 | log("createRelocSections"); | 357 | log("createRelocSections"); |
| 362 | // Don't use iterator here since we are adding to OutputSection | 358 | // Don't use iterator here since we are adding to OutputSection |
| 363 | size_t OrigSize = OutputSections.size(); | 359 | size_t OrigSize = OutputSections.size(); |
| 364 | for (size_t i = 0; i < OrigSize; i++) { | 360 | for (size_t I = 0; I < OrigSize; I++) { |
| 365 | OutputSection *S = OutputSections[i]; | 361 | OutputSection *OSec = OutputSections[I]; |
| 366 | const char *name; | 362 | uint32_t Count = OSec->numRelocations(); |
| 367 | uint32_t Count = S->numRelocations(); | ||
| 368 | if (!Count) | 363 | if (!Count) |
| 369 | continue; | 364 | continue; |
| 370 | 365 | ||
| 371 | if (S->Type == WASM_SEC_DATA) | 366 | StringRef Name; |
| 372 | name = "reloc.DATA"; | 367 | if (OSec->Type == WASM_SEC_DATA) |
| 373 | else if (S->Type == WASM_SEC_CODE) | 368 | Name = "reloc.DATA"; |
| 374 | name = "reloc.CODE"; | 369 | else if (OSec->Type == WASM_SEC_CODE) |
| 370 | Name = "reloc.CODE"; | ||
| 371 | else if (OSec->Type == WASM_SEC_CUSTOM) | ||
| 372 | Name = Saver.save("reloc." + OSec->Name); | ||
| 375 | else | 373 | else |
| 376 | llvm_unreachable("relocations only supported for code and data"); | 374 | llvm_unreachable( |
| 375 | "relocations only supported for code, data, or custom sections"); | ||
| 377 | 376 | ||
| 378 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, name); | 377 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name); |
| 379 | raw_ostream &OS = Section->getStream(); | 378 | raw_ostream &OS = Section->getStream(); |
| 380 | writeUleb128(OS, S->Type, "reloc section"); | 379 | writeUleb128(OS, I, "reloc section"); |
| 381 | writeUleb128(OS, Count, "reloc count"); | 380 | writeUleb128(OS, Count, "reloc count"); |
| 382 | S->writeRelocations(OS); | 381 | OSec->writeRelocations(OS); |
| 383 | } | 382 | } |
| 384 | } | 383 | } |
| 385 | 384 | ||
| 385 | static uint32_t getWasmFlags(const Symbol *Sym) { | ||
| 386 | uint32_t Flags = 0; | ||
| 387 | if (Sym->isLocal()) | ||
| 388 | Flags |= WASM_SYMBOL_BINDING_LOCAL; | ||
| 389 | if (Sym->isWeak()) | ||
| 390 | Flags |= WASM_SYMBOL_BINDING_WEAK; | ||
| 391 | if (Sym->isHidden()) | ||
| 392 | Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; | ||
| 393 | if (Sym->isUndefined()) | ||
| 394 | Flags |= WASM_SYMBOL_UNDEFINED; | ||
| 395 | return Flags; | ||
| 396 | } | ||
| 397 | |||
| 398 | // Some synthetic sections (e.g. "name" and "linking") have subsections. | ||
| 399 | // Just like the synthetic sections themselves these need to be created before | ||
| 400 | // they can be written out (since they are preceded by their length). This | ||
| 401 | // class is used to create subsections and then write them into the stream | ||
| 402 | // of the parent section. | ||
| 403 | class SubSection { | ||
| 404 | public: | ||
| 405 | explicit SubSection(uint32_t Type) : Type(Type) {} | ||
| 406 | |||
| 407 | void writeTo(raw_ostream &To) { | ||
| 408 | OS.flush(); | ||
| 409 | writeUleb128(To, Type, "subsection type"); | ||
| 410 | writeUleb128(To, Body.size(), "subsection size"); | ||
| 411 | To.write(Body.data(), Body.size()); | ||
| 412 | } | ||
| 413 | |||
| 414 | private: | ||
| 415 | uint32_t Type; | ||
| 416 | std::string Body; | ||
| 417 | |||
| 418 | public: | ||
| 419 | raw_string_ostream OS{Body}; | ||
| 420 | }; | ||
| 421 | |||
| 386 | // Create the custom "linking" section containing linker metadata. | 422 | // Create the custom "linking" section containing linker metadata. |
| 387 | // This is only created when relocatable output is requested. | 423 | // This is only created when relocatable output is requested. |
| 388 | void Writer::createLinkingSection() { | 424 | void Writer::createLinkingSection() { |
| ... | @@ -390,82 +426,145 @@ void Writer::createLinkingSection() { | ... | @@ -390,82 +426,145 @@ void Writer::createLinkingSection() { |
| 390 | createSyntheticSection(WASM_SEC_CUSTOM, "linking"); | 426 | createSyntheticSection(WASM_SEC_CUSTOM, "linking"); |
| 391 | raw_ostream &OS = Section->getStream(); | 427 | raw_ostream &OS = Section->getStream(); |
| 392 | 428 | ||
| 393 | SubSection DataSizeSubSection(WASM_DATA_SIZE); | 429 | writeUleb128(OS, WasmMetadataVersion, "Version"); |
| 394 | writeUleb128(DataSizeSubSection.getStream(), DataSize, "data size"); | 430 | |
| 395 | DataSizeSubSection.finalizeContents(); | 431 | if (!SymtabEntries.empty()) { |
| 396 | DataSizeSubSection.writeToStream(OS); | 432 | SubSection Sub(WASM_SYMBOL_TABLE); |
| 433 | writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols"); | ||
| 434 | |||
| 435 | for (const Symbol *Sym : SymtabEntries) { | ||
| 436 | assert(Sym->isDefined() || Sym->isUndefined()); | ||
| 437 | WasmSymbolType Kind = Sym->getWasmType(); | ||
| 438 | uint32_t Flags = getWasmFlags(Sym); | ||
| 439 | |||
| 440 | writeU8(Sub.OS, Kind, "sym kind"); | ||
| 441 | writeUleb128(Sub.OS, Flags, "sym flags"); | ||
| 442 | |||
| 443 | if (auto *F = dyn_cast<FunctionSymbol>(Sym)) { | ||
| 444 | writeUleb128(Sub.OS, F->getFunctionIndex(), "index"); | ||
| 445 | if (Sym->isDefined()) | ||
| 446 | writeStr(Sub.OS, Sym->getName(), "sym name"); | ||
| 447 | } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) { | ||
| 448 | writeUleb128(Sub.OS, G->getGlobalIndex(), "index"); | ||
| 449 | if (Sym->isDefined()) | ||
| 450 | writeStr(Sub.OS, Sym->getName(), "sym name"); | ||
| 451 | } else if (isa<DataSymbol>(Sym)) { | ||
| 452 | writeStr(Sub.OS, Sym->getName(), "sym name"); | ||
| 453 | if (auto *DataSym = dyn_cast<DefinedData>(Sym)) { | ||
| 454 | writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index"); | ||
| 455 | writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(), | ||
| 456 | "data offset"); | ||
| 457 | writeUleb128(Sub.OS, DataSym->getSize(), "data size"); | ||
| 458 | } | ||
| 459 | } else { | ||
| 460 | auto *S = cast<SectionSymbol>(Sym); | ||
| 461 | writeUleb128(Sub.OS, S->getOutputSectionIndex(), "sym section index"); | ||
| 462 | } | ||
| 463 | } | ||
| 397 | 464 | ||
| 398 | if (!Config->Relocatable) | 465 | Sub.writeTo(OS); |
| 399 | return; | 466 | } |
| 400 | 467 | ||
| 401 | if (Segments.size()) { | 468 | if (Segments.size()) { |
| 402 | SubSection SubSection(WASM_SEGMENT_INFO); | 469 | SubSection Sub(WASM_SEGMENT_INFO); |
| 403 | writeUleb128(SubSection.getStream(), Segments.size(), "num data segments"); | 470 | writeUleb128(Sub.OS, Segments.size(), "num data segments"); |
| 404 | for (const OutputSegment *S : Segments) { | 471 | for (const OutputSegment *S : Segments) { |
| 405 | writeStr(SubSection.getStream(), S->Name, "segment name"); | 472 | writeStr(Sub.OS, S->Name, "segment name"); |
| 406 | writeUleb128(SubSection.getStream(), S->Alignment, "alignment"); | 473 | writeUleb128(Sub.OS, S->Alignment, "alignment"); |
| 407 | writeUleb128(SubSection.getStream(), 0, "flags"); | 474 | writeUleb128(Sub.OS, 0, "flags"); |
| 408 | } | 475 | } |
| 409 | SubSection.finalizeContents(); | 476 | Sub.writeTo(OS); |
| 410 | SubSection.writeToStream(OS); | ||
| 411 | } | 477 | } |
| 412 | 478 | ||
| 413 | std::vector<WasmInitFunc> InitFunctions; | 479 | if (!InitFunctions.empty()) { |
| 414 | for (ObjFile *File : Symtab->ObjectFiles) { | 480 | SubSection Sub(WASM_INIT_FUNCS); |
| 415 | const WasmLinkingData &L = File->getWasmObj()->linkingData(); | 481 | writeUleb128(Sub.OS, InitFunctions.size(), "num init functions"); |
| 416 | InitFunctions.reserve(InitFunctions.size() + L.InitFunctions.size()); | 482 | for (const WasmInitEntry &F : InitFunctions) { |
| 417 | for (const WasmInitFunc &F : L.InitFunctions) | 483 | writeUleb128(Sub.OS, F.Priority, "priority"); |
| 418 | InitFunctions.emplace_back(WasmInitFunc{ | 484 | writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index"); |
| 419 | F.Priority, File->relocateFunctionIndex(F.FunctionIndex)}); | 485 | } |
| 486 | Sub.writeTo(OS); | ||
| 420 | } | 487 | } |
| 421 | 488 | ||
| 422 | if (!InitFunctions.empty()) { | 489 | struct ComdatEntry { |
| 423 | SubSection SubSection(WASM_INIT_FUNCS); | 490 | unsigned Kind; |
| 424 | writeUleb128(SubSection.getStream(), InitFunctions.size(), | 491 | uint32_t Index; |
| 425 | "num init functionsw"); | 492 | }; |
| 426 | for (const WasmInitFunc &F : InitFunctions) { | 493 | std::map<StringRef, std::vector<ComdatEntry>> Comdats; |
| 427 | writeUleb128(SubSection.getStream(), F.Priority, "priority"); | 494 | |
| 428 | writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index"); | 495 | for (const InputFunction *F : InputFunctions) { |
| 496 | StringRef Comdat = F->getComdatName(); | ||
| 497 | if (!Comdat.empty()) | ||
| 498 | Comdats[Comdat].emplace_back( | ||
| 499 | ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()}); | ||
| 500 | } | ||
| 501 | for (uint32_t I = 0; I < Segments.size(); ++I) { | ||
| 502 | const auto &InputSegments = Segments[I]->InputSegments; | ||
| 503 | if (InputSegments.empty()) | ||
| 504 | continue; | ||
| 505 | StringRef Comdat = InputSegments[0]->getComdatName(); | ||
| 506 | #ifndef NDEBUG | ||
| 507 | for (const InputSegment *IS : InputSegments) | ||
| 508 | assert(IS->getComdatName() == Comdat); | ||
| 509 | #endif | ||
| 510 | if (!Comdat.empty()) | ||
| 511 | Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I}); | ||
| 512 | } | ||
| 513 | |||
| 514 | if (!Comdats.empty()) { | ||
| 515 | SubSection Sub(WASM_COMDAT_INFO); | ||
| 516 | writeUleb128(Sub.OS, Comdats.size(), "num comdats"); | ||
| 517 | for (const auto &C : Comdats) { | ||
| 518 | writeStr(Sub.OS, C.first, "comdat name"); | ||
| 519 | writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use | ||
| 520 | writeUleb128(Sub.OS, C.second.size(), "num entries"); | ||
| 521 | for (const ComdatEntry &Entry : C.second) { | ||
| 522 | writeU8(Sub.OS, Entry.Kind, "entry kind"); | ||
| 523 | writeUleb128(Sub.OS, Entry.Index, "entry index"); | ||
| 524 | } | ||
| 429 | } | 525 | } |
| 430 | SubSection.finalizeContents(); | 526 | Sub.writeTo(OS); |
| 431 | SubSection.writeToStream(OS); | ||
| 432 | } | 527 | } |
| 433 | } | 528 | } |
| 434 | 529 | ||
| 435 | // Create the custom "name" section containing debug symbol names. | 530 | // Create the custom "name" section containing debug symbol names. |
| 436 | void Writer::createNameSection() { | 531 | void Writer::createNameSection() { |
| 437 | // Create an array of all function sorted by function index space | 532 | unsigned NumNames = NumImportedFunctions; |
| 438 | std::vector<const Symbol *> Names; | 533 | for (const InputFunction *F : InputFunctions) |
| 534 | if (!F->getName().empty() || !F->getDebugName().empty()) | ||
| 535 | ++NumNames; | ||
| 439 | 536 | ||
| 440 | for (ObjFile *File : Symtab->ObjectFiles) { | 537 | if (NumNames == 0) |
| 441 | Names.reserve(Names.size() + File->getSymbols().size()); | 538 | return; |
| 442 | for (Symbol *S : File->getSymbols()) { | ||
| 443 | if (!S->isFunction() || S->isWeak() || S->WrittenToNameSec) | ||
| 444 | continue; | ||
| 445 | S->WrittenToNameSec = true; | ||
| 446 | Names.emplace_back(S); | ||
| 447 | } | ||
| 448 | } | ||
| 449 | 539 | ||
| 450 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name"); | 540 | SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name"); |
| 451 | 541 | ||
| 452 | std::sort(Names.begin(), Names.end(), [](const Symbol *A, const Symbol *B) { | 542 | SubSection Sub(WASM_NAMES_FUNCTION); |
| 453 | return A->getOutputIndex() < B->getOutputIndex(); | 543 | writeUleb128(Sub.OS, NumNames, "name count"); |
| 454 | }); | 544 | |
| 455 | 545 | // Names must appear in function index order. As it happens ImportedSymbols | |
| 456 | SubSection FunctionSubsection(WASM_NAMES_FUNCTION); | 546 | // and InputFunctions are numbered in order with imported functions coming |
| 457 | raw_ostream &OS = FunctionSubsection.getStream(); | 547 | // first. |
| 458 | writeUleb128(OS, Names.size(), "name count"); | 548 | for (const Symbol *S : ImportedSymbols) { |
| 459 | 549 | if (auto *F = dyn_cast<FunctionSymbol>(S)) { | |
| 460 | // We have to iterate through the inputs twice so that all the imports | 550 | writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); |
| 461 | // appear first before any of the local function names. | 551 | Optional<std::string> Name = demangleItanium(F->getName()); |
| 462 | for (const Symbol *S : Names) { | 552 | writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name"); |
| 463 | writeUleb128(OS, S->getOutputIndex(), "func index"); | 553 | } |
| 464 | writeStr(OS, S->getName(), "symbol name"); | 554 | } |
| 555 | for (const InputFunction *F : InputFunctions) { | ||
| 556 | if (!F->getName().empty()) { | ||
| 557 | writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); | ||
| 558 | if (!F->getDebugName().empty()) { | ||
| 559 | writeStr(Sub.OS, F->getDebugName(), "symbol name"); | ||
| 560 | } else { | ||
| 561 | Optional<std::string> Name = demangleItanium(F->getName()); | ||
| 562 | writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name"); | ||
| 563 | } | ||
| 564 | } | ||
| 465 | } | 565 | } |
| 466 | 566 | ||
| 467 | FunctionSubsection.finalizeContents(); | 567 | Sub.writeTo(Section->getStream()); |
| 468 | FunctionSubsection.writeToStream(Section->getStream()); | ||
| 469 | } | 568 | } |
| 470 | 569 | ||
| 471 | void Writer::writeHeader() { | 570 | void Writer::writeHeader() { |
| ... | @@ -479,48 +578,98 @@ void Writer::writeSections() { | ... | @@ -479,48 +578,98 @@ void Writer::writeSections() { |
| 479 | 578 | ||
| 480 | // Fix the memory layout of the output binary. This assigns memory offsets | 579 | // Fix the memory layout of the output binary. This assigns memory offsets |
| 481 | // to each of the input data sections as well as the explicit stack region. | 580 | // to each of the input data sections as well as the explicit stack region. |
| 581 | // The default memory layout is as follows, from low to high. | ||
| 582 | // | ||
| 583 | // - initialized data (starting at Config->GlobalBase) | ||
| 584 | // - BSS data (not currently implemented in llvm) | ||
| 585 | // - explicit stack (Config->ZStackSize) | ||
| 586 | // - heap start / unallocated | ||
| 587 | // | ||
| 588 | // The --stack-first option means that stack is placed before any static data. | ||
| 589 | // This can be useful since it means that stack overflow traps immediately rather | ||
| 590 | // than overwriting global data, but also increases code size since all static | ||
| 591 | // data loads and stores requires larger offsets. | ||
| 482 | void Writer::layoutMemory() { | 592 | void Writer::layoutMemory() { |
| 593 | createOutputSegments(); | ||
| 594 | |||
| 483 | uint32_t MemoryPtr = 0; | 595 | uint32_t MemoryPtr = 0; |
| 484 | if (!Config->Relocatable) { | 596 | |
| 597 | auto PlaceStack = [&]() { | ||
| 598 | if (Config->Relocatable) | ||
| 599 | return; | ||
| 600 | MemoryPtr = alignTo(MemoryPtr, kStackAlignment); | ||
| 601 | if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment)) | ||
| 602 | error("stack size must be " + Twine(kStackAlignment) + "-byte aligned"); | ||
| 603 | log("mem: stack size = " + Twine(Config->ZStackSize)); | ||
| 604 | log("mem: stack base = " + Twine(MemoryPtr)); | ||
| 605 | MemoryPtr += Config->ZStackSize; | ||
| 606 | WasmSym::StackPointer->Global->Global.InitExpr.Value.Int32 = MemoryPtr; | ||
| 607 | log("mem: stack top = " + Twine(MemoryPtr)); | ||
| 608 | }; | ||
| 609 | |||
| 610 | if (Config->StackFirst) { | ||
| 611 | PlaceStack(); | ||
| 612 | } else { | ||
| 485 | MemoryPtr = Config->GlobalBase; | 613 | MemoryPtr = Config->GlobalBase; |
| 486 | debugPrint("mem: global base = %d\n", Config->GlobalBase); | 614 | log("mem: global base = " + Twine(Config->GlobalBase)); |
| 487 | } | 615 | } |
| 488 | 616 | ||
| 489 | createOutputSegments(); | 617 | uint32_t DataStart = MemoryPtr; |
| 618 | |||
| 619 | // Arbitrarily set __dso_handle handle to point to the start of the data | ||
| 620 | // segments. | ||
| 621 | if (WasmSym::DsoHandle) | ||
| 622 | WasmSym::DsoHandle->setVirtualAddress(DataStart); | ||
| 490 | 623 | ||
| 491 | // Static data comes first | ||
| 492 | for (OutputSegment *Seg : Segments) { | 624 | for (OutputSegment *Seg : Segments) { |
| 493 | MemoryPtr = alignTo(MemoryPtr, Seg->Alignment); | 625 | MemoryPtr = alignTo(MemoryPtr, Seg->Alignment); |
| 494 | Seg->StartVA = MemoryPtr; | 626 | Seg->StartVA = MemoryPtr; |
| 495 | debugPrint("mem: %-10s offset=%-8d size=%-4d align=%d\n", | 627 | log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name, |
| 496 | Seg->Name.str().c_str(), MemoryPtr, Seg->Size, Seg->Alignment); | 628 | MemoryPtr, Seg->Size, Seg->Alignment)); |
| 497 | MemoryPtr += Seg->Size; | 629 | MemoryPtr += Seg->Size; |
| 498 | } | 630 | } |
| 499 | 631 | ||
| 500 | DataSize = MemoryPtr; | 632 | // TODO: Add .bss space here. |
| 501 | if (!Config->Relocatable) | 633 | if (WasmSym::DataEnd) |
| 502 | DataSize -= Config->GlobalBase; | 634 | WasmSym::DataEnd->setVirtualAddress(MemoryPtr); |
| 503 | debugPrint("mem: static data = %d\n", DataSize); | 635 | |
| 636 | log("mem: static data = " + Twine(MemoryPtr - DataStart)); | ||
| 504 | 637 | ||
| 505 | // Stack comes after static data | 638 | if (!Config->StackFirst) |
| 639 | PlaceStack(); | ||
| 640 | |||
| 641 | // Set `__heap_base` to directly follow the end of the stack or global data. | ||
| 642 | // The fact that this comes last means that a malloc/brk implementation | ||
| 643 | // can grow the heap at runtime. | ||
| 506 | if (!Config->Relocatable) { | 644 | if (!Config->Relocatable) { |
| 507 | MemoryPtr = alignTo(MemoryPtr, kStackAlignment); | 645 | WasmSym::HeapBase->setVirtualAddress(MemoryPtr); |
| 508 | if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment)) | 646 | log("mem: heap base = " + Twine(MemoryPtr)); |
| 509 | error("stack size must be " + Twine(kStackAlignment) + "-byte aligned"); | ||
| 510 | debugPrint("mem: stack size = %d\n", Config->ZStackSize); | ||
| 511 | debugPrint("mem: stack base = %d\n", MemoryPtr); | ||
| 512 | MemoryPtr += Config->ZStackSize; | ||
| 513 | Config->StackPointerSymbol->setVirtualAddress(MemoryPtr); | ||
| 514 | debugPrint("mem: stack top = %d\n", MemoryPtr); | ||
| 515 | } | 647 | } |
| 516 | 648 | ||
| 649 | if (Config->InitialMemory != 0) { | ||
| 650 | if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize)) | ||
| 651 | error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); | ||
| 652 | if (MemoryPtr > Config->InitialMemory) | ||
| 653 | error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed"); | ||
| 654 | else | ||
| 655 | MemoryPtr = Config->InitialMemory; | ||
| 656 | } | ||
| 517 | uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize); | 657 | uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize); |
| 518 | NumMemoryPages = MemSize / WasmPageSize; | 658 | NumMemoryPages = MemSize / WasmPageSize; |
| 519 | debugPrint("mem: total pages = %d\n", NumMemoryPages); | 659 | log("mem: total pages = " + Twine(NumMemoryPages)); |
| 660 | |||
| 661 | if (Config->MaxMemory != 0) { | ||
| 662 | if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) | ||
| 663 | error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); | ||
| 664 | if (MemoryPtr > Config->MaxMemory) | ||
| 665 | error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed"); | ||
| 666 | MaxMemoryPages = Config->MaxMemory / WasmPageSize; | ||
| 667 | log("mem: max pages = " + Twine(MaxMemoryPages)); | ||
| 668 | } | ||
| 520 | } | 669 | } |
| 521 | 670 | ||
| 522 | SyntheticSection *Writer::createSyntheticSection(uint32_t Type, | 671 | SyntheticSection *Writer::createSyntheticSection(uint32_t Type, |
| 523 | std::string Name) { | 672 | StringRef Name) { |
| 524 | auto Sec = make<SyntheticSection>(Type, Name); | 673 | auto Sec = make<SyntheticSection>(Type, Name); |
| 525 | log("createSection: " + toString(*Sec)); | 674 | log("createSection: " + toString(*Sec)); |
| 526 | OutputSections.push_back(Sec); | 675 | OutputSections.push_back(Sec); |
| ... | @@ -536,15 +685,16 @@ void Writer::createSections() { | ... | @@ -536,15 +685,16 @@ void Writer::createSections() { |
| 536 | createMemorySection(); | 685 | createMemorySection(); |
| 537 | createGlobalSection(); | 686 | createGlobalSection(); |
| 538 | createExportSection(); | 687 | createExportSection(); |
| 539 | createStartSection(); | ||
| 540 | createElemSection(); | 688 | createElemSection(); |
| 541 | createCodeSection(); | 689 | createCodeSection(); |
| 542 | createDataSection(); | 690 | createDataSection(); |
| 691 | createCustomSections(); | ||
| 543 | 692 | ||
| 544 | // Custom sections | 693 | // Custom sections |
| 545 | if (Config->EmitRelocs) | 694 | if (Config->Relocatable) { |
| 695 | createLinkingSection(); | ||
| 546 | createRelocSections(); | 696 | createRelocSections(); |
| 547 | createLinkingSection(); | 697 | } |
| 548 | if (!Config->StripDebug && !Config->StripAll) | 698 | if (!Config->StripDebug && !Config->StripAll) |
| 549 | createNameSection(); | 699 | createNameSection(); |
| 550 | 700 | ||
| ... | @@ -555,149 +705,336 @@ void Writer::createSections() { | ... | @@ -555,149 +705,336 @@ void Writer::createSections() { |
| 555 | } | 705 | } |
| 556 | } | 706 | } |
| 557 | 707 | ||
| 558 | void Writer::calculateOffsets() { | 708 | void Writer::calculateImports() { |
| 559 | for (ObjFile *File : Symtab->ObjectFiles) { | 709 | for (Symbol *Sym : Symtab->getSymbols()) { |
| 560 | const WasmObjectFile *WasmFile = File->getWasmObj(); | 710 | if (!Sym->isUndefined()) |
| 561 | 711 | continue; | |
| 562 | // Function Index | 712 | if (isa<DataSymbol>(Sym)) |
| 563 | File->FunctionIndexOffset = | 713 | continue; |
| 564 | FunctionImports.size() - File->NumFunctionImports() + NumFunctions; | 714 | if (Sym->isWeak() && !Config->Relocatable) |
| 565 | NumFunctions += WasmFile->functions().size(); | 715 | continue; |
| 716 | if (!Sym->isLive()) | ||
| 717 | continue; | ||
| 718 | if (!Sym->IsUsedInRegularObj) | ||
| 719 | continue; | ||
| 566 | 720 | ||
| 567 | // Memory | 721 | LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); |
| 568 | if (WasmFile->memories().size() > 1) | 722 | ImportedSymbols.emplace_back(Sym); |
| 569 | fatal(File->getName() + ": contains more than one memory"); | 723 | if (auto *F = dyn_cast<FunctionSymbol>(Sym)) |
| 724 | F->setFunctionIndex(NumImportedFunctions++); | ||
| 725 | else | ||
| 726 | cast<GlobalSymbol>(Sym)->setGlobalIndex(NumImportedGlobals++); | ||
| 570 | } | 727 | } |
| 571 | } | 728 | } |
| 572 | 729 | ||
| 573 | void Writer::calculateImports() { | 730 | void Writer::calculateExports() { |
| 731 | if (Config->Relocatable) | ||
| 732 | return; | ||
| 733 | |||
| 734 | if (!Config->Relocatable && !Config->ImportMemory) | ||
| 735 | Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); | ||
| 736 | |||
| 737 | if (!Config->Relocatable && Config->ExportTable) | ||
| 738 | Exports.push_back(WasmExport{kFunctionTableName, WASM_EXTERNAL_TABLE, 0}); | ||
| 739 | |||
| 740 | unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size(); | ||
| 741 | |||
| 574 | for (Symbol *Sym : Symtab->getSymbols()) { | 742 | for (Symbol *Sym : Symtab->getSymbols()) { |
| 575 | if (!Sym->isUndefined() || Sym->isWeak()) | 743 | if (!Sym->isExported()) |
| 744 | continue; | ||
| 745 | if (!Sym->isLive()) | ||
| 576 | continue; | 746 | continue; |
| 577 | 747 | ||
| 578 | if (Sym->isFunction()) { | 748 | StringRef Name = Sym->getName(); |
| 579 | Sym->setOutputIndex(FunctionImports.size()); | 749 | WasmExport Export; |
| 580 | FunctionImports.push_back(Sym); | 750 | if (auto *F = dyn_cast<DefinedFunction>(Sym)) { |
| 751 | Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()}; | ||
| 752 | } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) { | ||
| 753 | // TODO(sbc): Remove this check once to mutable global proposal is | ||
| 754 | // implement in all major browsers. | ||
| 755 | // See: https://github.com/WebAssembly/mutable-global | ||
| 756 | if (G->getGlobalType()->Mutable) { | ||
| 757 | // Only the __stack_pointer should ever be create as mutable. | ||
| 758 | assert(G == WasmSym::StackPointer); | ||
| 759 | continue; | ||
| 760 | } | ||
| 761 | Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()}; | ||
| 581 | } else { | 762 | } else { |
| 582 | Sym->setOutputIndex(GlobalImports.size()); | 763 | auto *D = cast<DefinedData>(Sym); |
| 583 | GlobalImports.push_back(Sym); | 764 | DefinedFakeGlobals.emplace_back(D); |
| 765 | Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++}; | ||
| 584 | } | 766 | } |
| 767 | |||
| 768 | LLVM_DEBUG(dbgs() << "Export: " << Name << "\n"); | ||
| 769 | Exports.push_back(Export); | ||
| 770 | } | ||
| 771 | } | ||
| 772 | |||
| 773 | void Writer::assignSymtab() { | ||
| 774 | if (!Config->Relocatable) | ||
| 775 | return; | ||
| 776 | |||
| 777 | StringMap<uint32_t> SectionSymbolIndices; | ||
| 778 | |||
| 779 | unsigned SymbolIndex = SymtabEntries.size(); | ||
| 780 | for (ObjFile *File : Symtab->ObjectFiles) { | ||
| 781 | LLVM_DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n"); | ||
| 782 | for (Symbol *Sym : File->getSymbols()) { | ||
| 783 | if (Sym->getFile() != File) | ||
| 784 | continue; | ||
| 785 | |||
| 786 | if (auto *S = dyn_cast<SectionSymbol>(Sym)) { | ||
| 787 | StringRef Name = S->getName(); | ||
| 788 | if (CustomSectionMapping.count(Name) == 0) | ||
| 789 | continue; | ||
| 790 | |||
| 791 | auto SSI = SectionSymbolIndices.find(Name); | ||
| 792 | if (SSI != SectionSymbolIndices.end()) { | ||
| 793 | Sym->setOutputSymbolIndex(SSI->second); | ||
| 794 | continue; | ||
| 795 | } | ||
| 796 | |||
| 797 | SectionSymbolIndices[Name] = SymbolIndex; | ||
| 798 | CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym); | ||
| 799 | |||
| 800 | Sym->markLive(); | ||
| 801 | } | ||
| 802 | |||
| 803 | // (Since this is relocatable output, GC is not performed so symbols must | ||
| 804 | // be live.) | ||
| 805 | assert(Sym->isLive()); | ||
| 806 | Sym->setOutputSymbolIndex(SymbolIndex++); | ||
| 807 | SymtabEntries.emplace_back(Sym); | ||
| 808 | } | ||
| 809 | } | ||
| 810 | |||
| 811 | // For the moment, relocatable output doesn't contain any synthetic functions, | ||
| 812 | // so no need to look through the Symtab for symbols not referenced by | ||
| 813 | // Symtab->ObjectFiles. | ||
| 814 | } | ||
| 815 | |||
| 816 | uint32_t Writer::lookupType(const WasmSignature &Sig) { | ||
| 817 | auto It = TypeIndices.find(Sig); | ||
| 818 | if (It == TypeIndices.end()) { | ||
| 819 | error("type not found: " + toString(Sig)); | ||
| 820 | return 0; | ||
| 585 | } | 821 | } |
| 822 | return It->second; | ||
| 586 | } | 823 | } |
| 587 | 824 | ||
| 588 | uint32_t Writer::getTypeIndex(const WasmSignature &Sig) { | 825 | uint32_t Writer::registerType(const WasmSignature &Sig) { |
| 589 | auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size())); | 826 | auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size())); |
| 590 | if (Pair.second) | 827 | if (Pair.second) { |
| 828 | LLVM_DEBUG(dbgs() << "type " << toString(Sig) << "\n"); | ||
| 591 | Types.push_back(&Sig); | 829 | Types.push_back(&Sig); |
| 830 | } | ||
| 592 | return Pair.first->second; | 831 | return Pair.first->second; |
| 593 | } | 832 | } |
| 594 | 833 | ||
| 595 | void Writer::calculateTypes() { | 834 | void Writer::calculateTypes() { |
| 835 | // The output type section is the union of the following sets: | ||
| 836 | // 1. Any signature used in the TYPE relocation | ||
| 837 | // 2. The signatures of all imported functions | ||
| 838 | // 3. The signatures of all defined functions | ||
| 839 | |||
| 596 | for (ObjFile *File : Symtab->ObjectFiles) { | 840 | for (ObjFile *File : Symtab->ObjectFiles) { |
| 597 | File->TypeMap.reserve(File->getWasmObj()->types().size()); | 841 | ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); |
| 598 | for (const WasmSignature &Sig : File->getWasmObj()->types()) | 842 | for (uint32_t I = 0; I < Types.size(); I++) |
| 599 | File->TypeMap.push_back(getTypeIndex(Sig)); | 843 | if (File->TypeIsUsed[I]) |
| 844 | File->TypeMap[I] = registerType(Types[I]); | ||
| 600 | } | 845 | } |
| 601 | } | ||
| 602 | 846 | ||
| 603 | void Writer::assignSymbolIndexes() { | 847 | for (const Symbol *Sym : ImportedSymbols) |
| 604 | uint32_t GlobalIndex = GlobalImports.size(); | 848 | if (auto *F = dyn_cast<FunctionSymbol>(Sym)) |
| 849 | registerType(*F->FunctionType); | ||
| 605 | 850 | ||
| 606 | if (Config->StackPointerSymbol) { | 851 | for (const InputFunction *F : InputFunctions) |
| 607 | DefinedGlobals.emplace_back(Config->StackPointerSymbol); | 852 | registerType(F->Signature); |
| 608 | Config->StackPointerSymbol->setOutputIndex(GlobalIndex++); | 853 | } |
| 609 | } | ||
| 610 | 854 | ||
| 611 | if (Config->EmitRelocs) | 855 | void Writer::assignIndexes() { |
| 612 | DefinedGlobals.reserve(Symtab->getSymbols().size()); | 856 | uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size(); |
| 857 | auto AddDefinedFunction = [&](InputFunction *Func) { | ||
| 858 | if (!Func->Live) | ||
| 859 | return; | ||
| 860 | InputFunctions.emplace_back(Func); | ||
| 861 | Func->setFunctionIndex(FunctionIndex++); | ||
| 862 | }; | ||
| 613 | 863 | ||
| 614 | uint32_t TableIndex = InitialTableOffset; | 864 | for (InputFunction *Func : Symtab->SyntheticFunctions) |
| 865 | AddDefinedFunction(Func); | ||
| 615 | 866 | ||
| 616 | for (ObjFile *File : Symtab->ObjectFiles) { | 867 | for (ObjFile *File : Symtab->ObjectFiles) { |
| 617 | DEBUG(dbgs() << "assignSymbolIndexes: " << File->getName() << "\n"); | 868 | LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); |
| 618 | 869 | for (InputFunction *Func : File->Functions) | |
| 619 | for (Symbol *Sym : File->getSymbols()) { | 870 | AddDefinedFunction(Func); |
| 620 | // Assign indexes for symbols defined with this file. | 871 | } |
| 621 | if (!Sym->isDefined() || File != Sym->getFile()) | ||
| 622 | continue; | ||
| 623 | if (Sym->isFunction()) { | ||
| 624 | auto *Obj = cast<ObjFile>(Sym->getFile()); | ||
| 625 | Sym->setOutputIndex(Obj->FunctionIndexOffset + | ||
| 626 | Sym->getFunctionIndex()); | ||
| 627 | } else if (Config->EmitRelocs) { | ||
| 628 | DefinedGlobals.emplace_back(Sym); | ||
| 629 | Sym->setOutputIndex(GlobalIndex++); | ||
| 630 | } | ||
| 631 | } | ||
| 632 | 872 | ||
| 633 | for (Symbol *Sym : File->getTableSymbols()) { | 873 | uint32_t TableIndex = kInitialTableOffset; |
| 634 | if (!Sym->hasTableIndex()) { | 874 | auto HandleRelocs = [&](InputChunk *Chunk) { |
| 875 | if (!Chunk->Live) | ||
| 876 | return; | ||
| 877 | ObjFile *File = Chunk->File; | ||
| 878 | ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); | ||
| 879 | for (const WasmRelocation &Reloc : Chunk->getRelocations()) { | ||
| 880 | if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 || | ||
| 881 | Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) { | ||
| 882 | FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index); | ||
| 883 | if (Sym->hasTableIndex() || !Sym->hasFunctionIndex()) | ||
| 884 | continue; | ||
| 635 | Sym->setTableIndex(TableIndex++); | 885 | Sym->setTableIndex(TableIndex++); |
| 636 | IndirectFunctions.emplace_back(Sym); | 886 | IndirectFunctions.emplace_back(Sym); |
| 887 | } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) { | ||
| 888 | // Mark target type as live | ||
| 889 | File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]); | ||
| 890 | File->TypeIsUsed[Reloc.Index] = true; | ||
| 637 | } | 891 | } |
| 638 | } | 892 | } |
| 893 | }; | ||
| 894 | |||
| 895 | for (ObjFile *File : Symtab->ObjectFiles) { | ||
| 896 | LLVM_DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n"); | ||
| 897 | for (InputChunk *Chunk : File->Functions) | ||
| 898 | HandleRelocs(Chunk); | ||
| 899 | for (InputChunk *Chunk : File->Segments) | ||
| 900 | HandleRelocs(Chunk); | ||
| 901 | for (auto &P : File->CustomSections) | ||
| 902 | HandleRelocs(P); | ||
| 903 | } | ||
| 904 | |||
| 905 | uint32_t GlobalIndex = NumImportedGlobals + InputGlobals.size(); | ||
| 906 | auto AddDefinedGlobal = [&](InputGlobal *Global) { | ||
| 907 | if (Global->Live) { | ||
| 908 | LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n"); | ||
| 909 | Global->setGlobalIndex(GlobalIndex++); | ||
| 910 | InputGlobals.push_back(Global); | ||
| 911 | } | ||
| 912 | }; | ||
| 913 | |||
| 914 | for (InputGlobal *Global : Symtab->SyntheticGlobals) | ||
| 915 | AddDefinedGlobal(Global); | ||
| 916 | |||
| 917 | for (ObjFile *File : Symtab->ObjectFiles) { | ||
| 918 | LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); | ||
| 919 | for (InputGlobal *Global : File->Globals) | ||
| 920 | AddDefinedGlobal(Global); | ||
| 639 | } | 921 | } |
| 640 | } | 922 | } |
| 641 | 923 | ||
| 642 | static StringRef getOutputDataSegmentName(StringRef Name) { | 924 | static StringRef getOutputDataSegmentName(StringRef Name) { |
| 643 | if (Config->Relocatable) | 925 | if (!Config->MergeDataSegments) |
| 644 | return Name; | 926 | return Name; |
| 645 | 927 | if (Name.startswith(".text.")) | |
| 646 | for (StringRef V : | 928 | return ".text"; |
| 647 | {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.", | 929 | if (Name.startswith(".data.")) |
| 648 | ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", | 930 | return ".data"; |
| 649 | ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) { | 931 | if (Name.startswith(".bss.")) |
| 650 | StringRef Prefix = V.drop_back(); | 932 | return ".bss"; |
| 651 | if (Name.startswith(V) || Name == Prefix) | ||
| 652 | return Prefix; | ||
| 653 | } | ||
| 654 | |||
| 655 | return Name; | 933 | return Name; |
| 656 | } | 934 | } |
| 657 | 935 | ||
| 658 | void Writer::createOutputSegments() { | 936 | void Writer::createOutputSegments() { |
| 659 | for (ObjFile *File : Symtab->ObjectFiles) { | 937 | for (ObjFile *File : Symtab->ObjectFiles) { |
| 660 | for (InputSegment *Segment : File->Segments) { | 938 | for (InputSegment *Segment : File->Segments) { |
| 939 | if (!Segment->Live) | ||
| 940 | continue; | ||
| 661 | StringRef Name = getOutputDataSegmentName(Segment->getName()); | 941 | StringRef Name = getOutputDataSegmentName(Segment->getName()); |
| 662 | OutputSegment *&S = SegmentMap[Name]; | 942 | OutputSegment *&S = SegmentMap[Name]; |
| 663 | if (S == nullptr) { | 943 | if (S == nullptr) { |
| 664 | DEBUG(dbgs() << "new segment: " << Name << "\n"); | 944 | LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n"); |
| 665 | S = make<OutputSegment>(Name); | 945 | S = make<OutputSegment>(Name, Segments.size()); |
| 666 | Segments.push_back(S); | 946 | Segments.push_back(S); |
| 667 | } | 947 | } |
| 668 | S->addInputSegment(Segment); | 948 | S->addInputSegment(Segment); |
| 669 | DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); | 949 | LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); |
| 670 | } | 950 | } |
| 671 | } | 951 | } |
| 672 | } | 952 | } |
| 673 | 953 | ||
| 954 | static const int OPCODE_CALL = 0x10; | ||
| 955 | static const int OPCODE_END = 0xb; | ||
| 956 | |||
| 957 | // Create synthetic "__wasm_call_ctors" function based on ctor functions | ||
| 958 | // in input object. | ||
| 959 | void Writer::createCtorFunction() { | ||
| 960 | // First write the body's contents to a string. | ||
| 961 | std::string BodyContent; | ||
| 962 | { | ||
| 963 | raw_string_ostream OS(BodyContent); | ||
| 964 | writeUleb128(OS, 0, "num locals"); | ||
| 965 | for (const WasmInitEntry &F : InitFunctions) { | ||
| 966 | writeU8(OS, OPCODE_CALL, "CALL"); | ||
| 967 | writeUleb128(OS, F.Sym->getFunctionIndex(), "function index"); | ||
| 968 | } | ||
| 969 | writeU8(OS, OPCODE_END, "END"); | ||
| 970 | } | ||
| 971 | |||
| 972 | // Once we know the size of the body we can create the final function body | ||
| 973 | std::string FunctionBody; | ||
| 974 | { | ||
| 975 | raw_string_ostream OS(FunctionBody); | ||
| 976 | writeUleb128(OS, BodyContent.size(), "function size"); | ||
| 977 | OS << BodyContent; | ||
| 978 | } | ||
| 979 | |||
| 980 | ArrayRef<uint8_t> Body = toArrayRef(Saver.save(FunctionBody)); | ||
| 981 | cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body); | ||
| 982 | } | ||
| 983 | |||
| 984 | // Populate InitFunctions vector with init functions from all input objects. | ||
| 985 | // This is then used either when creating the output linking section or to | ||
| 986 | // synthesize the "__wasm_call_ctors" function. | ||
| 987 | void Writer::calculateInitFunctions() { | ||
| 988 | for (ObjFile *File : Symtab->ObjectFiles) { | ||
| 989 | const WasmLinkingData &L = File->getWasmObj()->linkingData(); | ||
| 990 | for (const WasmInitFunc &F : L.InitFunctions) { | ||
| 991 | FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol); | ||
| 992 | if (*Sym->FunctionType != WasmSignature{{}, WASM_TYPE_NORESULT}) | ||
| 993 | error("invalid signature for init func: " + toString(*Sym)); | ||
| 994 | InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority}); | ||
| 995 | } | ||
| 996 | } | ||
| 997 | |||
| 998 | // Sort in order of priority (lowest first) so that they are called | ||
| 999 | // in the correct order. | ||
| 1000 | std::stable_sort(InitFunctions.begin(), InitFunctions.end(), | ||
| 1001 | [](const WasmInitEntry &L, const WasmInitEntry &R) { | ||
| 1002 | return L.Priority < R.Priority; | ||
| 1003 | }); | ||
| 1004 | } | ||
| 1005 | |||
| 674 | void Writer::run() { | 1006 | void Writer::run() { |
| 675 | if (!Config->Relocatable) | 1007 | if (Config->Relocatable) |
| 676 | InitialTableOffset = 1; | 1008 | Config->GlobalBase = 0; |
| 677 | 1009 | ||
| 678 | log("-- calculateTypes"); | ||
| 679 | calculateTypes(); | ||
| 680 | log("-- calculateImports"); | 1010 | log("-- calculateImports"); |
| 681 | calculateImports(); | 1011 | calculateImports(); |
| 682 | log("-- calculateOffsets"); | 1012 | log("-- assignIndexes"); |
| 683 | calculateOffsets(); | 1013 | assignIndexes(); |
| 1014 | log("-- calculateInitFunctions"); | ||
| 1015 | calculateInitFunctions(); | ||
| 1016 | if (!Config->Relocatable) | ||
| 1017 | createCtorFunction(); | ||
| 1018 | log("-- calculateTypes"); | ||
| 1019 | calculateTypes(); | ||
| 1020 | log("-- layoutMemory"); | ||
| 1021 | layoutMemory(); | ||
| 1022 | log("-- calculateExports"); | ||
| 1023 | calculateExports(); | ||
| 1024 | log("-- calculateCustomSections"); | ||
| 1025 | calculateCustomSections(); | ||
| 1026 | log("-- assignSymtab"); | ||
| 1027 | assignSymtab(); | ||
| 684 | 1028 | ||
| 685 | if (errorHandler().Verbose) { | 1029 | if (errorHandler().Verbose) { |
| 686 | log("Defined Functions: " + Twine(NumFunctions)); | 1030 | log("Defined Functions: " + Twine(InputFunctions.size())); |
| 687 | log("Defined Globals : " + Twine(DefinedGlobals.size())); | 1031 | log("Defined Globals : " + Twine(InputGlobals.size())); |
| 688 | log("Function Imports : " + Twine(FunctionImports.size())); | 1032 | log("Function Imports : " + Twine(NumImportedFunctions)); |
| 689 | log("Global Imports : " + Twine(GlobalImports.size())); | 1033 | log("Global Imports : " + Twine(NumImportedGlobals)); |
| 690 | log("Total Imports : " + | ||
| 691 | Twine(FunctionImports.size() + GlobalImports.size())); | ||
| 692 | for (ObjFile *File : Symtab->ObjectFiles) | 1034 | for (ObjFile *File : Symtab->ObjectFiles) |
| 693 | File->dumpInfo(); | 1035 | File->dumpInfo(); |
| 694 | } | 1036 | } |
| 695 | 1037 | ||
| 696 | log("-- assignSymbolIndexes"); | ||
| 697 | assignSymbolIndexes(); | ||
| 698 | log("-- layoutMemory"); | ||
| 699 | layoutMemory(); | ||
| 700 | |||
| 701 | createHeader(); | 1038 | createHeader(); |
| 702 | log("-- createSections"); | 1039 | log("-- createSections"); |
| 703 | createSections(); | 1040 | createSections(); |
| ... | @@ -721,7 +1058,6 @@ void Writer::run() { | ... | @@ -721,7 +1058,6 @@ void Writer::run() { |
| 721 | // Open a result file. | 1058 | // Open a result file. |
| 722 | void Writer::openFile() { | 1059 | void Writer::openFile() { |
| 723 | log("writing: " + Config->OutputFile); | 1060 | log("writing: " + Config->OutputFile); |
| 724 | ::remove(Config->OutputFile.str().c_str()); | ||
| 725 | 1061 | ||
| 726 | Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = | 1062 | Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = |
| 727 | FileOutputBuffer::create(Config->OutputFile, FileSize, | 1063 | FileOutputBuffer::create(Config->OutputFile, FileSize, |
deps/lld/wasm/WriterUtils.cpp+55-58| ... | @@ -8,12 +8,9 @@ | ... | @@ -8,12 +8,9 @@ |
| 8 | //===----------------------------------------------------------------------===// | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | ||
| 10 | #include "WriterUtils.h" | 10 | #include "WriterUtils.h" |
| 11 | |||
| 12 | #include "lld/Common/ErrorHandler.h" | 11 | #include "lld/Common/ErrorHandler.h" |
| 13 | |||
| 14 | #include "llvm/Support/Debug.h" | 12 | #include "llvm/Support/Debug.h" |
| 15 | #include "llvm/Support/EndianStream.h" | 13 | #include "llvm/Support/EndianStream.h" |
| 16 | #include "llvm/Support/FormatVariadic.h" | ||
| 17 | #include "llvm/Support/LEB128.h" | 14 | #include "llvm/Support/LEB128.h" |
| 18 | 15 | ||
| 19 | #define DEBUG_TYPE "lld" | 16 | #define DEBUG_TYPE "lld" |
| ... | @@ -22,7 +19,7 @@ using namespace llvm; | ... | @@ -22,7 +19,7 @@ using namespace llvm; |
| 22 | using namespace llvm::wasm; | 19 | using namespace llvm::wasm; |
| 23 | using namespace lld::wasm; | 20 | using namespace lld::wasm; |
| 24 | 21 | ||
| 25 | static const char *valueTypeToString(int32_t Type) { | 22 | static const char *valueTypeToString(uint8_t Type) { |
| 26 | switch (Type) { | 23 | switch (Type) { |
| 27 | case WASM_TYPE_I32: | 24 | case WASM_TYPE_I32: |
| 28 | return "i32"; | 25 | return "i32"; |
| ... | @@ -39,61 +36,57 @@ static const char *valueTypeToString(int32_t Type) { | ... | @@ -39,61 +36,57 @@ static const char *valueTypeToString(int32_t Type) { |
| 39 | 36 | ||
| 40 | namespace lld { | 37 | namespace lld { |
| 41 | 38 | ||
| 42 | void wasm::debugWrite(uint64_t offset, Twine msg) { | 39 | void wasm::debugWrite(uint64_t Offset, const Twine &Msg) { |
| 43 | DEBUG(dbgs() << format(" | %08" PRIx64 ": ", offset) << msg << "\n"); | 40 | LLVM_DEBUG(dbgs() << format(" | %08lld: ", Offset) << Msg << "\n"); |
| 44 | } | 41 | } |
| 45 | 42 | ||
| 46 | void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const char *msg) { | 43 | void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg) { |
| 47 | if (msg) | 44 | debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]"); |
| 48 | debugWrite(OS.tell(), msg + formatv(" [{0:x}]", Number)); | ||
| 49 | encodeULEB128(Number, OS); | 45 | encodeULEB128(Number, OS); |
| 50 | } | 46 | } |
| 51 | 47 | ||
| 52 | void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const char *msg) { | 48 | void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg) { |
| 53 | if (msg) | 49 | debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]"); |
| 54 | debugWrite(OS.tell(), msg + formatv(" [{0:x}]", Number)); | ||
| 55 | encodeSLEB128(Number, OS); | 50 | encodeSLEB128(Number, OS); |
| 56 | } | 51 | } |
| 57 | 52 | ||
| 58 | void wasm::writeBytes(raw_ostream &OS, const char *bytes, size_t count, | 53 | void wasm::writeBytes(raw_ostream &OS, const char *Bytes, size_t Count, |
| 59 | const char *msg) { | 54 | const Twine &Msg) { |
| 60 | if (msg) | 55 | debugWrite(OS.tell(), Msg + " [data[" + Twine(Count) + "]]"); |
| 61 | debugWrite(OS.tell(), msg + formatv(" [data[{0}]]", count)); | 56 | OS.write(Bytes, Count); |
| 62 | OS.write(bytes, count); | ||
| 63 | } | 57 | } |
| 64 | 58 | ||
| 65 | void wasm::writeStr(raw_ostream &OS, const StringRef String, const char *msg) { | 59 | void wasm::writeStr(raw_ostream &OS, StringRef String, const Twine &Msg) { |
| 66 | if (msg) | 60 | debugWrite(OS.tell(), |
| 67 | debugWrite(OS.tell(), | 61 | Msg + " [str[" + Twine(String.size()) + "]: " + String + "]"); |
| 68 | msg + formatv(" [str[{0}]: {1}]", String.size(), String)); | 62 | encodeULEB128(String.size(), OS); |
| 69 | writeUleb128(OS, String.size(), nullptr); | 63 | OS.write(String.data(), String.size()); |
| 70 | writeBytes(OS, String.data(), String.size()); | ||
| 71 | } | 64 | } |
| 72 | 65 | ||
| 73 | void wasm::writeU8(raw_ostream &OS, uint8_t byte, const char *msg) { | 66 | void wasm::writeU8(raw_ostream &OS, uint8_t Byte, const Twine &Msg) { |
| 74 | OS << byte; | 67 | debugWrite(OS.tell(), Msg + " [0x" + utohexstr(Byte) + "]"); |
| 68 | OS << Byte; | ||
| 75 | } | 69 | } |
| 76 | 70 | ||
| 77 | void wasm::writeU32(raw_ostream &OS, uint32_t Number, const char *msg) { | 71 | void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) { |
| 78 | debugWrite(OS.tell(), msg + formatv("[{0:x}]", Number)); | 72 | debugWrite(OS.tell(), Msg + "[0x" + utohexstr(Number) + "]"); |
| 79 | support::endian::Writer<support::little>(OS).write(Number); | 73 | support::endian::write(OS, Number, support::little); |
| 80 | } | 74 | } |
| 81 | 75 | ||
| 82 | void wasm::writeValueType(raw_ostream &OS, int32_t Type, const char *msg) { | 76 | void wasm::writeValueType(raw_ostream &OS, uint8_t Type, const Twine &Msg) { |
| 83 | debugWrite(OS.tell(), msg + formatv("[type: {0}]", valueTypeToString(Type))); | 77 | writeU8(OS, Type, Msg + "[type: " + valueTypeToString(Type) + "]"); |
| 84 | writeSleb128(OS, Type, nullptr); | ||
| 85 | } | 78 | } |
| 86 | 79 | ||
| 87 | void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) { | 80 | void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) { |
| 88 | writeSleb128(OS, WASM_TYPE_FUNC, "signature type"); | 81 | writeU8(OS, WASM_TYPE_FUNC, "signature type"); |
| 89 | writeUleb128(OS, Sig.ParamTypes.size(), "param count"); | 82 | writeUleb128(OS, Sig.ParamTypes.size(), "param Count"); |
| 90 | for (int32_t ParamType : Sig.ParamTypes) { | 83 | for (uint8_t ParamType : Sig.ParamTypes) { |
| 91 | writeValueType(OS, ParamType, "param type"); | 84 | writeValueType(OS, ParamType, "param type"); |
| 92 | } | 85 | } |
| 93 | if (Sig.ReturnType == WASM_TYPE_NORESULT) { | 86 | if (Sig.ReturnType == WASM_TYPE_NORESULT) { |
| 94 | writeUleb128(OS, 0, "result count"); | 87 | writeUleb128(OS, 0, "result Count"); |
| 95 | } else { | 88 | } else { |
| 96 | writeUleb128(OS, 1, "result count"); | 89 | writeUleb128(OS, 1, "result Count"); |
| 97 | writeValueType(OS, Sig.ReturnType, "result type"); | 90 | writeValueType(OS, Sig.ReturnType, "result type"); |
| 98 | } | 91 | } |
| 99 | } | 92 | } |
| ... | @@ -117,18 +110,27 @@ void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) { | ... | @@ -117,18 +110,27 @@ void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) { |
| 117 | } | 110 | } |
| 118 | 111 | ||
| 119 | void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) { | 112 | void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) { |
| 120 | writeUleb128(OS, Limits.Flags, "limits flags"); | 113 | writeU8(OS, Limits.Flags, "limits flags"); |
| 121 | writeUleb128(OS, Limits.Initial, "limits initial"); | 114 | writeUleb128(OS, Limits.Initial, "limits initial"); |
| 122 | if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX) | 115 | if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX) |
| 123 | writeUleb128(OS, Limits.Maximum, "limits max"); | 116 | writeUleb128(OS, Limits.Maximum, "limits max"); |
| 124 | } | 117 | } |
| 125 | 118 | ||
| 119 | void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) { | ||
| 120 | writeValueType(OS, Type.Type, "global type"); | ||
| 121 | writeU8(OS, Type.Mutable, "global mutable"); | ||
| 122 | } | ||
| 123 | |||
| 126 | void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) { | 124 | void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) { |
| 127 | writeValueType(OS, Global.Type, "global type"); | 125 | writeGlobalType(OS, Global.Type); |
| 128 | writeUleb128(OS, Global.Mutable, "global mutable"); | ||
| 129 | writeInitExpr(OS, Global.InitExpr); | 126 | writeInitExpr(OS, Global.InitExpr); |
| 130 | } | 127 | } |
| 131 | 128 | ||
| 129 | void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) { | ||
| 130 | writeU8(OS, WASM_TYPE_ANYFUNC, "table type"); | ||
| 131 | writeLimits(OS, Type.Limits); | ||
| 132 | } | ||
| 133 | |||
| 132 | void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) { | 134 | void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) { |
| 133 | writeStr(OS, Import.Module, "import module name"); | 135 | writeStr(OS, Import.Module, "import module name"); |
| 134 | writeStr(OS, Import.Field, "import field name"); | 136 | writeStr(OS, Import.Field, "import field name"); |
| ... | @@ -138,12 +140,14 @@ void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) { | ... | @@ -138,12 +140,14 @@ void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) { |
| 138 | writeUleb128(OS, Import.SigIndex, "import sig index"); | 140 | writeUleb128(OS, Import.SigIndex, "import sig index"); |
| 139 | break; | 141 | break; |
| 140 | case WASM_EXTERNAL_GLOBAL: | 142 | case WASM_EXTERNAL_GLOBAL: |
| 141 | writeValueType(OS, Import.Global.Type, "import global type"); | 143 | writeGlobalType(OS, Import.Global); |
| 142 | writeUleb128(OS, Import.Global.Mutable, "import global mutable"); | ||
| 143 | break; | 144 | break; |
| 144 | case WASM_EXTERNAL_MEMORY: | 145 | case WASM_EXTERNAL_MEMORY: |
| 145 | writeLimits(OS, Import.Memory); | 146 | writeLimits(OS, Import.Memory); |
| 146 | break; | 147 | break; |
| 148 | case WASM_EXTERNAL_TABLE: | ||
| 149 | writeTableType(OS, Import.Table); | ||
| 150 | break; | ||
| 147 | default: | 151 | default: |
| 148 | fatal("unsupported import type: " + Twine(Import.Kind)); | 152 | fatal("unsupported import type: " + Twine(Import.Kind)); |
| 149 | } | 153 | } |
| ... | @@ -162,27 +166,13 @@ void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) { | ... | @@ -162,27 +166,13 @@ void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) { |
| 162 | case WASM_EXTERNAL_MEMORY: | 166 | case WASM_EXTERNAL_MEMORY: |
| 163 | writeUleb128(OS, Export.Index, "memory index"); | 167 | writeUleb128(OS, Export.Index, "memory index"); |
| 164 | break; | 168 | break; |
| 165 | default: | 169 | case WASM_EXTERNAL_TABLE: |
| 166 | fatal("unsupported export type: " + Twine(Export.Kind)); | 170 | writeUleb128(OS, Export.Index, "table index"); |
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | void wasm::writeReloc(raw_ostream &OS, const OutputRelocation &Reloc) { | ||
| 171 | writeUleb128(OS, Reloc.Reloc.Type, "reloc type"); | ||
| 172 | writeUleb128(OS, Reloc.Reloc.Offset, "reloc offset"); | ||
| 173 | writeUleb128(OS, Reloc.NewIndex, "reloc index"); | ||
| 174 | |||
| 175 | switch (Reloc.Reloc.Type) { | ||
| 176 | case R_WEBASSEMBLY_MEMORY_ADDR_LEB: | ||
| 177 | case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: | ||
| 178 | case R_WEBASSEMBLY_MEMORY_ADDR_I32: | ||
| 179 | writeUleb128(OS, Reloc.Reloc.Addend, "reloc addend"); | ||
| 180 | break; | 171 | break; |
| 181 | default: | 172 | default: |
| 182 | break; | 173 | fatal("unsupported export type: " + Twine(Export.Kind)); |
| 183 | } | 174 | } |
| 184 | } | 175 | } |
| 185 | |||
| 186 | } // namespace lld | 176 | } // namespace lld |
| 187 | 177 | ||
| 188 | std::string lld::toString(ValType Type) { | 178 | std::string lld::toString(ValType Type) { |
| ... | @@ -195,6 +185,8 @@ std::string lld::toString(ValType Type) { | ... | @@ -195,6 +185,8 @@ std::string lld::toString(ValType Type) { |
| 195 | return "F32"; | 185 | return "F32"; |
| 196 | case ValType::F64: | 186 | case ValType::F64: |
| 197 | return "F64"; | 187 | return "F64"; |
| 188 | case ValType::EXCEPT_REF: | ||
| 189 | return "except_ref"; | ||
| 198 | } | 190 | } |
| 199 | llvm_unreachable("Invalid wasm::ValType"); | 191 | llvm_unreachable("Invalid wasm::ValType"); |
| 200 | } | 192 | } |
| ... | @@ -213,3 +205,8 @@ std::string lld::toString(const WasmSignature &Sig) { | ... | @@ -213,3 +205,8 @@ std::string lld::toString(const WasmSignature &Sig) { |
| 213 | S += toString(static_cast<ValType>(Sig.ReturnType)); | 205 | S += toString(static_cast<ValType>(Sig.ReturnType)); |
| 214 | return S.str(); | 206 | return S.str(); |
| 215 | } | 207 | } |
| 208 | |||
| 209 | std::string lld::toString(const WasmGlobalType &Sig) { | ||
| 210 | return (Sig.Mutable ? "var " : "const ") + | ||
| 211 | toString(static_cast<ValType>(Sig.Type)); | ||
| 212 | } |
deps/lld/wasm/WriterUtils.h+16-30| ... | @@ -10,49 +10,32 @@ | ... | @@ -10,49 +10,32 @@ |
| 10 | #ifndef LLD_WASM_WRITERUTILS_H | 10 | #ifndef LLD_WASM_WRITERUTILS_H |
| 11 | #define LLD_WASM_WRITERUTILS_H | 11 | #define LLD_WASM_WRITERUTILS_H |
| 12 | 12 | ||
| 13 | #include "lld/Common/LLVM.h" | ||
| 13 | #include "llvm/ADT/Twine.h" | 14 | #include "llvm/ADT/Twine.h" |
| 14 | #include "llvm/Object/Wasm.h" | 15 | #include "llvm/Object/Wasm.h" |
| 15 | #include "llvm/Support/raw_ostream.h" | 16 | #include "llvm/Support/raw_ostream.h" |
| 16 | 17 | ||
| 17 | using llvm::raw_ostream; | 18 | using llvm::raw_ostream; |
| 18 | 19 | ||
| 19 | // Needed for WasmSignatureDenseMapInfo | ||
| 20 | inline bool operator==(const llvm::wasm::WasmSignature &LHS, | ||
| 21 | const llvm::wasm::WasmSignature &RHS) { | ||
| 22 | return LHS.ReturnType == RHS.ReturnType && LHS.ParamTypes == RHS.ParamTypes; | ||
| 23 | } | ||
| 24 | |||
| 25 | inline bool operator!=(const llvm::wasm::WasmSignature &LHS, | ||
| 26 | const llvm::wasm::WasmSignature &RHS) { | ||
| 27 | return !(LHS == RHS); | ||
| 28 | } | ||
| 29 | |||
| 30 | namespace lld { | 20 | namespace lld { |
| 31 | namespace wasm { | 21 | namespace wasm { |
| 32 | 22 | ||
| 33 | struct OutputRelocation { | 23 | void debugWrite(uint64_t Offset, const Twine &Msg); |
| 34 | llvm::wasm::WasmRelocation Reloc; | ||
| 35 | uint32_t NewIndex; | ||
| 36 | uint32_t Value; | ||
| 37 | }; | ||
| 38 | |||
| 39 | void debugWrite(uint64_t offset, llvm::Twine msg); | ||
| 40 | 24 | ||
| 41 | void writeUleb128(raw_ostream &OS, uint32_t Number, const char *msg); | 25 | void writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg); |
| 42 | 26 | ||
| 43 | void writeSleb128(raw_ostream &OS, int32_t Number, const char *msg); | 27 | void writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg); |
| 44 | 28 | ||
| 45 | void writeBytes(raw_ostream &OS, const char *bytes, size_t count, | 29 | void writeBytes(raw_ostream &OS, const char *Bytes, size_t count, |
| 46 | const char *msg = nullptr); | 30 | const Twine &Msg); |
| 47 | 31 | ||
| 48 | void writeStr(raw_ostream &OS, const llvm::StringRef String, | 32 | void writeStr(raw_ostream &OS, StringRef String, const Twine &Msg); |
| 49 | const char *msg = nullptr); | ||
| 50 | 33 | ||
| 51 | void writeU8(raw_ostream &OS, uint8_t byte, const char *msg); | 34 | void writeU8(raw_ostream &OS, uint8_t byte, const Twine &Msg); |
| 52 | 35 | ||
| 53 | void writeU32(raw_ostream &OS, uint32_t Number, const char *msg); | 36 | void writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg); |
| 54 | 37 | ||
| 55 | void writeValueType(raw_ostream &OS, int32_t Type, const char *msg); | 38 | void writeValueType(raw_ostream &OS, uint8_t Type, const Twine &Msg); |
| 56 | 39 | ||
| 57 | void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig); | 40 | void writeSig(raw_ostream &OS, const llvm::wasm::WasmSignature &Sig); |
| 58 | 41 | ||
| ... | @@ -60,18 +43,21 @@ void writeInitExpr(raw_ostream &OS, const llvm::wasm::WasmInitExpr &InitExpr); | ... | @@ -60,18 +43,21 @@ void writeInitExpr(raw_ostream &OS, const llvm::wasm::WasmInitExpr &InitExpr); |
| 60 | 43 | ||
| 61 | void writeLimits(raw_ostream &OS, const llvm::wasm::WasmLimits &Limits); | 44 | void writeLimits(raw_ostream &OS, const llvm::wasm::WasmLimits &Limits); |
| 62 | 45 | ||
| 46 | void writeGlobalType(raw_ostream &OS, const llvm::wasm::WasmGlobalType &Type); | ||
| 47 | |||
| 63 | void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global); | 48 | void writeGlobal(raw_ostream &OS, const llvm::wasm::WasmGlobal &Global); |
| 64 | 49 | ||
| 50 | void writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type); | ||
| 51 | |||
| 65 | void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import); | 52 | void writeImport(raw_ostream &OS, const llvm::wasm::WasmImport &Import); |
| 66 | 53 | ||
| 67 | void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export); | 54 | void writeExport(raw_ostream &OS, const llvm::wasm::WasmExport &Export); |
| 68 | 55 | ||
| 69 | void writeReloc(raw_ostream &OS, const OutputRelocation &Reloc); | ||
| 70 | |||
| 71 | } // namespace wasm | 56 | } // namespace wasm |
| 72 | 57 | ||
| 73 | std::string toString(const llvm::wasm::ValType Type); | 58 | std::string toString(llvm::wasm::ValType Type); |
| 74 | std::string toString(const llvm::wasm::WasmSignature &Sig); | 59 | std::string toString(const llvm::wasm::WasmSignature &Sig); |
| 60 | std::string toString(const llvm::wasm::WasmGlobalType &Sig); | ||
| 75 | 61 | ||
| 76 | } // namespace lld | 62 | } // namespace lld |
| 77 | 63 |